UNPKG

homebridge-homeconnect

Version:
6,918 lines 663 kB
(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.APIStatus = void 0;
var _utils = require("../../utils.js");
var _utilsDom = require("./utils-dom.js");
// Homebridge plugin for Home Connect home appliances
// Copyright © 2024 Alexander Thoukydides

// URL for the server status image
const STATUS_URL = 'https://homeconnect.thouky.co.uk/api/images/plugin-status.svg';
// Warn for errors more recent than this
const STATUS_SINCE = 24 * 60 * 60 * _utils.MS;
// Interval to poll for updates (if there are issues)
const POLL_INTERVAL = 2.5 * 60 * _utils.MS;
// Home Connect API server status
class APIStatus {
  log;
  // When was the status last updated
  lastUpdated;
  // Create a new API server status checker
  constructor(log) {
    this.log = log;
    this.pollStatus();
  }
  // Check the status of the Home Connect API servers
  async pollStatus() {
    // Attempt to fetch the status image
    const response = await fetch(STATUS_URL);
    if (!response.ok) {
      this.log.warn('checkStatus fetch', response.statusText);
      return;
    }
    const svg = await response.text();
    // Attempt to parse the status header
    let status;
    try {
      status = JSON.parse(response.headers.get('X-Server-Status') ?? '');
      (0, _utils.assertIsBoolean)(status.up);
      (0, _utils.assertIsNumber)(status.since);
      (0, _utils.assertIsNumber)(status.updated);
    } catch (err) {
      this.log.warn('checkStatus X-Server-Status', err);
      return;
    }
    // Update the displayed status, if it has changed
    let pollAgain = true;
    if (this.lastUpdated !== status.updated) {
      this.lastUpdated = status.updated;
      pollAgain = this.showStatus(svg, status);
    }
    // Periodically poll the status if there are server issues
    if (pollAgain) setTimeout(() => this.pollStatus(), POLL_INTERVAL);
  }
  // Display the latest status of the Home Connect API servers
  showStatus(svg, status) {
    // Display the appropriate summary
    (0, _utilsDom.getElementById)('hc-api-up').hidden = !status.up;
    (0, _utilsDom.getElementById)('hc-api-up2').hidden = !status.up;
    (0, _utilsDom.getElementById)('hc-api-down').hidden = status.up;
    (0, _utilsDom.getElementById)('hc-api-down2').hidden = status.up;
    // Add the detailed status
    (0, _utilsDom.getElementById)('hc-api-since').innerText = this.formatDateTime(status.since);
    // Add the retrieved status image
    (0, _utilsDom.getElementById)('hc-api-svg').innerHTML = svg;
    // Show or hide the status as appropriate
    const showStatus = !status.up || Date.now() < status.since + STATUS_SINCE;
    (0, _utilsDom.getElementById)('hc-api-status').hidden = !showStatus;
    return showStatus;
  }
  // Format a date/time
  formatDateTime(date) {
    return new Date(date).toLocaleString(undefined, {
      weekday: 'long',
      month: 'long',
      day: 'numeric',
      hour: 'numeric',
      minute: '2-digit',
      timeZoneName: 'short'
    });
  }
}
exports.APIStatus = APIStatus;

},{"../../utils.js":12,"./utils-dom.js":9}],2:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.Cards = void 0;
var _utils = require("../../utils.js");
var _utilsDom = require("./utils-dom.js");
// Homebridge plugin for Home Connect home appliances
// Copyright © 2023 Alexander Thoukydides

// Cards to select global or per-appliance configuration
class Cards {
  log;
  // HTML element that has the cards as children
  parentElement;
  // Current cards
  nonApplianceCards = [];
  applianceCards = [];
  // The currently selected card
  selectedCardId;
  onSelect;
  // Construct a new cards handler
  constructor(log) {
    this.log = log;
    this.parentElement = (0, _utilsDom.getElementById)('hc-appliance-cards');
  }
  // Update the list of non-appliance cards
  setNonAppliances(cards) {
    this.nonApplianceCards = cards;
    this.updateCards();
  }
  // Update the list of appliances
  setAppliances(appliances) {
    // Convert the appliances to card descriptions
    const applianceCards = appliances.map(appliance => ({
      id: appliance.haId,
      icon: appliance.type.toLocaleLowerCase(),
      name: appliance.name,
      detail: `${appliance.brand} ${appliance.enumber}`
    }));
    applianceCards.sort((a, b) => a.name.localeCompare(b.name));
    // Check whether the list of appliances has changed
    if (JSON.stringify(applianceCards) !== JSON.stringify(this.applianceCards)) {
      this.applianceCards = applianceCards;
      this.updateCards();
    }
  }
  // Update the list of cards and restore the selection, if still valid
  updateCards() {
    // Replace the existing cards with new ones
    const allCards = [...this.nonApplianceCards, ...this.applianceCards];
    this.parentElement.replaceChildren(...allCards.map(card => this.makeCard(card)));
    this.parentElement.hidden = !allCards.length;
    // Restore any previous selection
    this.selectCard(this.selectedCardId);
  }
  // Create a new card
  makeCard({
    id,
    icon,
    name,
    detail
  }) {
    // Create a new card from the template
    if (detail === undefined) detail = ' '; // (non-breaking space)
    const card = (0, _utilsDom.cloneTemplate)('hc-appliance-card', {
      name,
      detail
    });
    this.loadCardIcon((0, _utilsDom.getSlot)(card, 'icon'), `./images/icon-${icon}.svg`, id);
    // Handle card selection
    const element = card.children[0];
    (0, _utils.assertIsInstanceOf)(element, HTMLElement);
    element.dataset.id = id;
    element.onclick = () => {
      this.selectCard(id);
    };
    return card;
  }
  // Load the icon image for a card
  async loadCardIcon(element, url, id) {
    try {
      // Load the icon and add it to the card
      const response = await fetch(url);
      if (!response.ok) throw new Error(`Failed to fetch icon ${response.url}: ${response.statusText}`);
      element.innerHTML = await response.text();
      // Change the group (layer) IDs to classes
      element.querySelectorAll('g[id]').forEach(group => {
        const id = group.getAttribute('id');
        (0, _utils.assertIsDefined)(id);
        group.removeAttribute('id');
        group.classList.add(id);
      });
      // Assign unique IDs to gradient fills
      element.querySelectorAll('defs [id]').forEach(def => {
        const oldId = def.getAttribute('id');
        const newId = `${id}-${oldId}`;
        def.setAttribute('id', newId);
        element.querySelectorAll(`[fill='url(#${oldId})']`).forEach(ref => {
          ref.setAttribute('fill', `url(#${newId})`);
        });
      });
    } catch (err) {
      this.log.error(`loadCardIcon(${id}) =>`, err);
    }
  }
  // A card has been selected
  selectCard(id) {
    // Select this card and deselect all others
    let selectedCard;
    for (const card of Array.from(this.parentElement.children)) {
      (0, _utils.assertIsInstanceOf)(card, HTMLElement);
      if (card.dataset.id === id) selectedCard = card;
      card.classList.toggle('hc-selected', card.dataset.id === id);
    }
    if (!selectedCard) id = undefined;
    // Notify the client of selection changes
    if (this.selectedCardId !== id) {
      this.log.debug(`onSelect(${id}) (was ${this.selectedCardId})`);
      this.selectedCardId = id;
      this.onSelect?.(id);
    }
  }
}
exports.Cards = Cards;

},{"../../utils.js":12,"./utils-dom.js":9}],3:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.ClientClientID = void 0;
var _utils = require("../../utils.js");
var _utilsDom = require("./utils-dom.js");
// Homebridge plugin for Home Connect home appliances
// Copyright © 2023 Alexander Thoukydides

// Minimum time between duplicate toast notifications
const TOAST_DEDUP_TIME = 5 * _utils.MS;
// The current Home Connect client
class ClientClientID {
  log;
  ipc;
  // The configuration of the client being monitored
  clientConfig;
  // The most recent toast displayed (to avoid duplicates)
  lastToast;
  // Triggers to modify the configuration
  onFail;
  onAppliances;
  // Create a new Home Connect client
  constructor(log, ipc) {
    this.log = log;
    this.ipc = ipc;
    this.ipc.onEvent('status', status => {
      this.onClientStatus(status);
    });
  }
  // The Home Connect client configuration has changed
  async setClient(config) {
    const clientConfig = this.prepareClientConfig(config);
    if (clientConfig) {
      // Test the client configuration
      this.clientConfig = clientConfig;
      try {
        const status = await this.ipc.request('/clientid', clientConfig);
        this.onClientStatus(status);
      } catch (err) {
        const message = err instanceof Error ? err.message : String(err);
        this.showToast('error', `Unable to attempt authorisation ${message}`);
      }
    } else {
      // Ignore the client configuration until it is valid
      this.clientConfig = undefined;
      this.showPanel();
      this.onAppliances?.();
    }
  }
  // Test whether the client configuration is likely to be valid
  prepareClientConfig(config) {
    if (config.debug?.includes('Mock Appliances')) {
      // Mock appliances; use an empty clientid to match the status
      return {
        ...config,
        clientid: ''
      };
    } else if (config.clientid !== undefined && /^[0-9A-F]{64}$/i.test(config.clientid)) {
      // Viable clientid
      return config;
    }
  }
  // Handle events from the Home Connect client
  onClientStatus(status) {
    // Ignore the status if no longer monitoring the client
    if (this.clientConfig?.clientid !== status.clientid) return;
    // Update the list of appliances
    this.onAppliances?.(status.appliances);
    // Display an appropriate toast notification
    switch (status.authorisation?.state) {
      case 'success':
        this.showToast('success', 'Successfully authorised');
        this.showPanel();
        break;
      case 'user':
        this.showToast('info', 'User authorisation required');
        this.showUserAuthorisation(status.authorisation);
        break;
      case 'fail':
        this.showToast('error', 'Authorisation failed');
        this.showFail(status.authorisation);
        this.onFail?.();
        break;
      case 'busy':
      default:
        this.showPanel();
    }
  }
  // Prompt the user to authorise the client
  showUserAuthorisation(authorisation) {
    // Set the link/code
    const link = (0, _utilsDom.getElementById)('hc-client-user-link');
    link.setAttribute('href', authorisation.uri);
    (0, _utilsDom.setSlotText)(document, {
      'hc-client-user-code': authorisation.code
    });
    // Enable generation of a new authorisation code
    (0, _utilsDom.getElementById)('hc-client-user-retry').onclick = () => {
      this.retryAuthorisation();
    };
    // Make the authorisation link visible (before triggering transition)
    this.showPanel('hc-client-user');
    // Start animating the progress bar for the time until the link expires
    const progress = (0, _utilsDom.getElementById)('hc-client-user-progress');
    progress.classList.remove('hc-progress-zero');
    if (authorisation.expires !== null) {
      progress.style.transitionDuration = `${authorisation.expires - Date.now()}ms`;
      void progress.offsetHeight; // (force a reflow)
      progress.classList.add('hc-progress-zero');
    }
  }
  // Display the result of a failed authorisation
  showFail(authorisation) {
    // Display the error message
    (0, _utilsDom.getElementById)('hc-client-fail-message').textContent = authorisation.message;
    // Indicate whether the authorisation can be retried
    (0, _utilsDom.getElementById)('hc-client-fail-retryable').hidden = !authorisation.retryable;
    (0, _utilsDom.getElementById)('hc-client-fail-retry').hidden = !authorisation.retryable;
    (0, _utilsDom.getElementById)('hc-client-fail-retry').onclick = () => {
      this.retryAuthorisation();
    };
    // Add any help that has been provided
    if (authorisation.help) {
      // Set text blocks
      const setText = (id, text) => {
        (0, _utilsDom.getElementById)(id).replaceChildren(...text.map(paragraph => (0, _utilsDom.cloneTemplate)('hc-client-fail-paragraph', {
          paragraph
        })));
      };
      setText('hc-client-fail-prescript', authorisation.help.prescript);
      setText('hc-client-fail-postscript', authorisation.help.postscript);
      // Provide additional help for creating or modifying the application
      const {
        client
      } = authorisation.help;
      const link = (0, _utilsDom.getElementById)('hc-client-fail-uri');
      if (client) {
        (0, _utilsDom.getElementById)('hc-client-fail-client-settings').replaceChildren(...Object.entries(client.settings).map(([key, value]) => (0, _utilsDom.cloneTemplate)('hc-client-fail-client-setting', {
          key,
          value
        })));
        link.setAttribute('href', client.uri);
        link.textContent = client.action === 'create' ? 'Create application' : 'Modify application';
        link.hidden = false;
        (0, _utilsDom.getElementById)('hc-client-fail-client').hidden = false;
      } else {
        link.hidden = true;
        (0, _utilsDom.getElementById)('hc-client-fail-client').hidden = true;
      }
      // Make the details visible
      (0, _utilsDom.getElementById)('hc-client-fail-detail').hidden = false;
    } else {
      // Otherwise hide the details
      (0, _utilsDom.getElementById)('hc-client-fail-uri').hidden = true;
      (0, _utilsDom.getElementById)('hc-client-fail-detail').hidden = true;
    }
    // Make the failure message visible
    this.showPanel('hc-client-fail');
  }
  // Trigger authorisation retry
  async retryAuthorisation() {
    try {
      await this.ipc.request('/clientid/retry', null);
      this.showToast('info', 'Requesting new authorisation code');
    } catch (err) {
      const message = err instanceof Error ? err.message : String(err);
      this.showToast('error', `Unable to retry authorisation: ${message}`);
    }
  }
  // Show the specified element and hide all others
  showPanel(idShow) {
    for (const id of ['hc-client-fail', 'hc-client-user']) {
      (0, _utilsDom.getElementById)(id).hidden = id !== idShow;
    }
  }
  // Display a toast notification
  showToast(level, message) {
    // Avoid duplicate toast notifications
    const key = `${level} - ${message}`;
    if (this.lastToast === key) return;
    this.lastToast = key;
    setTimeout(() => {
      if (this.lastToast === key) this.lastToast = undefined;
    }, TOAST_DEDUP_TIME);
    // Display the toast notification
    window.homebridge.toast[level](message, 'Home Connect Client');
  }
}
exports.ClientClientID = ClientClientID;

},{"../../utils.js":12,"./utils-dom.js":9}],4:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.ClientIPC = void 0;
// Homebridge plugin for Home Connect home appliances
// Copyright © 2023 Alexander Thoukydides
// Client-side IPC implementation
class ClientIPC {
  log;
  // Create a new client IPC instance
  constructor(log) {
    this.log = log;
  }
  // Issue a request to the server
  async request(path, data) {
    try {
      this.log.debug(`request("${path}", %O)`, data);
      const result = await window.homebridge.request(path, data);
      this.log.debug(`request("${path}", %O) =>`, data, result);
      return result;
    } catch (err) {
      this.log.error(`request("${path}", %O) =>`, data, err);
      throw err;
    }
  }
  // Add an event listener
  onEvent(event, callback) {
    window.homebridge.addEventListener(event, async evt => {
      try {
        const data = evt.data;
        if (event !== 'log') this.log.debug(`onEvent("${event}") => callback`, data);
        await callback(data);
      } catch (err) {
        this.log.error(`onEvent("${event}") =>`, err);
      }
    });
  }
}
exports.ClientIPC = ClientIPC;

},{}],5:[function(require,module,exports){
"use strict";

require("@homebridge/plugin-ui-utils/dist/ui.interface.js");
var _logger = require("./logger.js");
var _config = require("./config.js");
var _cards = require("./cards.js");
var _clientClientid = require("./client-clientid.js");
var _forms = require("./forms.js");
var _clientIpc = require("./client-ipc.js");
var _apiStatus = require("./api-status.js");
// Homebridge plugin for Home Connect home appliances
// Copyright © 2023-2024 Alexander Thoukydides

// A Homebridge HomeConnect custom UI client
class Client {
  // Custom loggers
  log;
  serverLog;
  // Local resources
  ipc;
  // Create a new custom UI client
  constructor() {
    // Create a local logger and IPC client
    this.log = new _logger.ClientLogger();
    this.log.debug('homebridge.plugin', window.homebridge.plugin);
    this.ipc = new _clientIpc.ClientIPC(this.log);
    // Wait for the server before continuing initialisation
    this.ipc.onEvent('ready', () => {
      this.serverReady();
    });
  }
  // The server is ready so finish initialising the client
  serverReady() {
    // Start receiving (important) log messages from the server
    this.serverLog = new _logger.ServerLogger(this.ipc, "warn" /* LogLevel.WARN */);
    // Create all of the required resources
    const config = new _config.Config(this.log, this.ipc);
    const forms = new _forms.Forms(this.log, this.ipc, config);
    const cards = new _cards.Cards(this.log);
    const client = new _clientClientid.ClientClientID(this.log, this.ipc);
    new _apiStatus.APIStatus(this.log);
    // Create cards for the global settings and each available appliance
    cards.setNonAppliances([{
      id: _forms.FormId.Global,
      icon: 'global',
      name: 'General Settings'
    }]);
    client.onAppliances = appliances => {
      cards.setAppliances(appliances ?? []);
    };
    cards.onSelect = id => {
      forms.showForm(id);
    };
    // Attempt to authorise a client when the configuration changes
    config.onGlobal = config => {
      client.setClient(config);
    };
    client.onFail = () => {
      forms.showForm(_forms.FormId.Global);
    };
  }
}
// Create a custom UI client instance
new Client();

},{"./api-status.js":1,"./cards.js":2,"./client-clientid.js":3,"./client-ipc.js":4,"./config.js":6,"./forms.js":7,"./logger.js":8,"@homebridge/plugin-ui-utils/dist/ui.interface.js":13}],6:[function(require,module,exports){
(function (global){(function (){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.Config = void 0;
require("@homebridge/plugin-ui-utils/dist/ui.interface.js");
var _utils = require("../../utils.js");
var _utilsDom = require("./utils-dom.js");
var _configTypes = require("../../ti/config-types.js");
// Homebridge plugin for Home Connect home appliances
// Copyright © 2023 Alexander Thoukydides

// The current plugin configuration
class Config {
  log;
  ipc;
  // The saved configuration
  savedConfig;
  // The configuration being edited
  global = {};
  appliances = {};
  onGlobal;
  // Promises for retrieving the current configurations
  readyPromise;
  activePromise;
  // Create a new configuration object
  constructor(log, ipc) {
    this.log = log;
    this.ipc = ipc;
    this.readyPromise = this.getConfig();
    this.activePromise = this.getActiveConfig();
  }
  // Retrieve and parse the configuration to be edited
  async getConfig() {
    // Retrieve the current plugin configuration (if any)
    const configArray = await window.homebridge.getPluginConfig();
    if (configArray[0] === undefined) {
      this.log.warn('No plugin configuration found; creating a new one');
      this.savedConfig = {
        platform: window.homebridge.plugin.displayName
      };
    } else {
      if (1 < configArray.length) {
        this.log.error(`Using the first of ${configArray.length} plugin configurations`, configArray);
        window.homebridge.toast.error('Only a single platform instance is supported; using the first', 'Multiple Configuration Blocks');
      }
      this.savedConfig = configArray[0];
      this.checkIfModified(this.savedConfig);
    }
    // Treat all unexpected properties as appliance configurations
    const keyofConfigPlugin = (0, _utils.keyofChecker)(_configTypes.typeSuite, _configTypes.typeSuite.ConfigPlugin);
    const select = predicate => Object.fromEntries(Object.entries(this.savedConfig ?? {}).filter(predicate));
    this.global = select(([key]) => keyofConfigPlugin.includes(key));
    this.appliances = select(([key]) => !keyofConfigPlugin.includes(key));
    this.log.debug('getConfig() global %O appliances %O', this.global, this.appliances);
    this.onGlobal?.(this.global);
  }
  // Retrieve the most recently used configuration
  async getActiveConfig() {
    try {
      return await this.ipc.request('/config', null);
    } catch {
      return {};
    }
  }
  // Update the homebridge-ui-x copy of the configuration
  async putConfig(save = false) {
    // Construct the full configuration
    const config = {
      ...this.global,
      ...this.appliances
    };
    this.log.debug(`putConfig(${save})'}`, config);
    // Inform homebridge-ui-x of the new configuration
    await window.homebridge.updatePluginConfig([config]);
    if (save) {
      await window.homebridge.savePluginConfig();
      this.savedConfig = config;
      this.log.info('Plugin configuration saved');
    }
    // Check whether the configuration matches the active plugin
    this.checkIfModified(config);
  }
  // Compare two configuration objects
  diffObject(to, from, keyPrefix = '') {
    const keys = [...Object.keys(to), ...Object.keys(from)].filter((key, index, self) => index === self.indexOf(key));
    const diff = [];
    for (const key of keys) {
      const valueTo = to[key];
      const valueFrom = from[key];
      const keyName = `${keyPrefix}.${key}`;
      const isObject = value => value !== undefined && typeof value === 'object';
      if (Array.isArray(valueTo) && Array.isArray(valueFrom)) diff.push(...this.diffArray(valueTo, valueFrom, keyName));else if (isObject(valueTo) && isObject(valueFrom)) diff.push(...this.diffObject(valueTo, valueFrom, keyName));else if (valueTo !== valueFrom) diff.push({
        key: keyName,
        from: valueFrom,
        to: valueTo
      });
    }
    return diff;
  }
  // Compare two configuration arrays
  diffArray(to, from, keyPrefix = '') {
    const isSimple = array => array.length !== 0 && typeof array[0] !== 'object';
    if (isSimple(to) || isSimple(from)) {
      if (to.length === from.length && to.every((value, index) => value === from[index])) return [];else return [{
        key: keyPrefix,
        from,
        to
      }];
    } else {
      return this.diffObject(to, from, keyPrefix);
    }
  }
  // Check whether the configuration has been modified
  async checkIfModified(config) {
    // Ignore completely new/empty configuration
    if (!Object.keys(config).length) return;
    // Compare the configuration to the active plugin and saved versions
    const activeConfig = await this.activePromise;
    const activeDiff = this.diffObject(config, activeConfig);
    const savedDiff = this.diffObject(config, this.savedConfig ?? {});
    if (activeDiff.length || savedDiff.length) {
      this.log.debug('checkIfModified(%O) active %O saved %O', config, activeDiff, savedDiff);
    }
    // Hide or show the restart required message
    this.showRestartRequired(activeDiff, 0 < savedDiff.length);
  }
  // Show or hide the restart required message
  showRestartRequired(changes, isUnsaved) {
    // Show the message if there are any differences
    (0, _utilsDom.getElementById)('hc-modified').hidden = changes.length === 0 && !isUnsaved;
    (0, _utilsDom.getElementById)('hc-modified-saved').hidden = isUnsaved;
    (0, _utilsDom.getElementById)('hc-modified-unsaved').hidden = !isUnsaved;
    // Display the diff
    const formatValue = value => JSON.stringify(value, null, 4);
    (0, _utilsDom.getElementById)('hc-modified-diff').replaceChildren(...changes.map(change => (0, _utilsDom.cloneTemplate)('hc-modified-diff-delta', {
      key: change.key,
      from: formatValue(change.from),
      to: formatValue(change.to)
    })));
  }
  // Get the current global configuration
  async getGlobal() {
    await this.readyPromise;
    return this.global;
  }
  // Set updated global configuration
  async setGlobal(config) {
    if (this.diffObject(config, await this.getGlobal()).length) {
      this.log.debug('setGlobal(%O)', config);
      this.global = config;
      this.onGlobal?.(config);
      await this.putConfig();
    }
  }
  // Get the current configuration for a specific appliance
  async getAppliance(haid) {
    await this.readyPromise;
    return this.appliances[haid] ?? {};
  }
  // Set updated global configuration
  async setAppliance(haid, config) {
    if (this.diffObject(config, await this.getAppliance(haid)).length) {
      this.log.debug(`setAppliance("${haid}", %O)`, config);
      this.appliances[haid] = config;
      await this.putConfig();
    }
  }
}
exports.Config = Config;

}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})

},{"../../ti/config-types.js":11,"../../utils.js":12,"./utils-dom.js":9,"@homebridge/plugin-ui-utils/dist/ui.interface.js":13}],7:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.TemplateForm = exports.GlobalForm = exports.Forms = exports.FormId = exports.Form = exports.ApplianceForm = void 0;
var _utilsDom = require("./utils-dom.js");
// Homebridge plugin for Home Connect home appliances
// Copyright © 2023 Alexander Thoukydides

// A configuration form handler
class Form {
  log;
  // The form
  form;
  // Create a configuration form
  constructor(log) {
    this.log = log;
  }
  // Retrieve and display the form
  async createForm() {
    // Retrieve the form schema and data
    const schema = await this.getSchema();
    const data = await this.getData();
    // Create the form (adding header and footer)
    const patchedSchema = this.patchSchema(schema);
    this.log.debug('createForm', patchedSchema, data);
    this.form = window.homebridge.createForm(patchedSchema, data);
    // Return any changes to the configuration
    this.form.onChange(config => this.putData(config));
  }
  // Hide the form (implicitly called if a different form is created)
  destroyForm() {
    this.form?.end();
    this.form = undefined;
  }
  // Add a header and footer to the schema form
  patchSchema(schema) {
    const form = [...(schema.form ?? []), ...this.formFromTemplate('hc-form-footer')];
    return {
      ...schema,
      form
    };
  }
  // Create a form item from a template
  formFromTemplate(...args) {
    const template = (0, _utilsDom.cloneTemplate)(...args);
    const absTemplate = (0, _utilsDom.elementWithAbsolutePaths)(template);
    return this.formFromHTML(absTemplate);
  }
  // Create a form item from an HTML element
  formFromHTML(element) {
    return [{
      type: 'help',
      helpvalue: (0, _utilsDom.getHTML)(element)
    }];
  }
}
// A global configuration form handler
exports.Form = Form;
class GlobalForm extends Form {
  ipc;
  config;
  constructor(log, ipc, config) {
    super(log);
    this.ipc = ipc;
    this.config = config;
  }
  getSchema() {
    return this.ipc.request('/schema/global', null);
  }
  getData() {
    return this.config.getGlobal();
  }
  putData(data) {
    return this.config.setGlobal(data);
  }
}
// An configuration form handler for a specific appliance
exports.GlobalForm = GlobalForm;
class ApplianceForm extends Form {
  ipc;
  config;
  haid;
  constructor(log, ipc, config, haid) {
    super(log);
    this.ipc = ipc;
    this.config = config;
    this.haid = haid;
  }
  getSchema() {
    return this.ipc.request('/schema/appliance', this.haid);
  }
  getData() {
    return this.config.getAppliance(this.haid);
  }
  putData(data) {
    return this.config.setAppliance(this.haid, data);
  }
}
// A placeholder form handler
exports.ApplianceForm = ApplianceForm;
class TemplateForm extends Form {
  elementAsForm;
  constructor(log, ...args) {
    super(log);
    this.elementAsForm = this.formFromTemplate(...args);
  }
  // Create a placeholder schema using the specified HTML element
  async getSchema() {
    return Promise.resolve({
      schema: {
        type: 'object',
        properties: {}
      },
      form: this.elementAsForm
    });
  }
  async getData() {
    return Promise.resolve({});
  }
  async putData() {}
}
// Identifiers for special forms
exports.TemplateForm = TemplateForm;
var FormId;
(function (FormId) {
  FormId["Global"] = "global";
  FormId["Placeholder"] = "placeholder";
  FormId["Unavailable"] = "unavailable";
})(FormId || (exports.FormId = FormId = {}));
// Type guard to check whether a string is a special form identifier
function isFormId(value) {
  return Object.values(FormId).includes(value);
}
// Manage the configuration forms
class Forms {
  log;
  ipc;
  config;
  // The form currently being displayed
  currentForm;
  // Create a new form manager
  constructor(log, ipc, config) {
    this.log = log;
    this.ipc = ipc;
    this.config = config;
    this.showForm();
  }
  // Display the specified form (defaulting to the placeholder)
  async showForm(formId) {
    try {
      // The forms are retrieved from the server, so display a spinner
      window.homebridge.showSpinner();
      // Display the requested form, with fallback to the error form
      try {
        await this.constructAndShowForm(formId ?? FormId.Placeholder);
      } catch (err) {
        this.log.warn('Failed to display form', formId, err);
        await this.constructAndShowForm(FormId.Unavailable);
      }
    } finally {
      // Ensure that the spinner is always hidden
      window.homebridge.hideSpinner();
    }
  }
  // Try to create the requested form, with fallback to the placeholder
  async constructAndShowForm(formId) {
    const form = this.constructForm(formId);
    await form.createForm();
    this.currentForm = form;
  }
  // Create a specific form
  constructForm(formId) {
    if (isFormId(formId)) {
      switch (formId) {
        case FormId.Placeholder:
          return new TemplateForm(this.log, 'hc-form-placeholder');
        case FormId.Unavailable:
          return new TemplateForm(this.log, 'hc-form-unavailable');
        case FormId.Global:
          return new GlobalForm(this.log, this.ipc, this.config);
      }
    } else {
      return new ApplianceForm(this.log, this.ipc, this.config, formId);
    }
  }
}
exports.Forms = Forms;

},{"./utils-dom.js":9}],8:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.ServerLogger = exports.ConsoleLogger = exports.ClientLogger = void 0;
// Homebridge plugin for Home Connect home appliances
// Copyright © 2023 Alexander Thoukydides
// Prefix for client and server log messages
const PLUGIN_PREFIX = window.homebridge.plugin.displayName ?? window.homebridge.plugin.name;
// A logger that sends messages to the debugging console
class ConsoleLogger {
  prefix;
  // Create a new console logger
  constructor(prefix = '') {
    this.prefix = prefix;
  }
  // Simple wrappers to log a message
  error(message, ...params) {
    this.log("error" /* LogLevel.ERROR */, message, ...params);
  }
  warn(message, ...params) {
    this.log("warn" /* LogLevel.WARN */, message, ...params);
  }
  success(message, ...params) {
    this.log("success" /* LogLevel.SUCCESS */, message, ...params);
  }
  info(message, ...params) {
    this.log("info" /* LogLevel.INFO */, message, ...params);
  }
  debug(message, ...params) {
    this.log("debug" /* LogLevel.DEBUG */, message, ...params);
  }
  // Log a message at the specified level
  log(level, message, ...params) {
    // Add the prefix to the message
    if (this.prefix.length) message = `[${this.prefix}] ${message}`;
    // Log the message
    switch (level) {
      case "error" /* LogLevel.ERROR */:
        console.error(message, ...params);
        break;
      case "warn" /* LogLevel.WARN */:
        console.warn(message, ...params);
        break;
      case "success" /* LogLevel.SUCCESS */:
        console.info(message, ...params);
        break;
      case "info" /* LogLevel.INFO */:
        console.info(message, ...params);
        break;
      case "debug" /* LogLevel.DEBUG */:
        console.debug(message, ...params);
        break;
    }
  }
}
// Logger for locally generated messages
exports.ConsoleLogger = ConsoleLogger;
class ClientLogger extends ConsoleLogger {
  // Create a new client logger
  constructor() {
    super(`${PLUGIN_PREFIX} client`);
  }
}
// Logger that receives messages events from the server
exports.ClientLogger = ClientLogger;
class ServerLogger extends ConsoleLogger {
  ipc;
  // Create a new server logger
  constructor(ipc, minLevel) {
    super(`${PLUGIN_PREFIX} server`);
    this.ipc = ipc;
    // Start receiving log events
    ipc.onEvent('log', messages => {
      this.logMessages(messages);
    });
    try {
      ipc.request('/log', minLevel);
    } catch {/* empty */}
  }
  // Log messages received from the server
  logMessages(messages) {
    for (const {
      level,
      message,
      params
    } of messages) this.log(level, message, ...params);
  }
}
exports.ServerLogger = ServerLogger;

},{}],9:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.cloneTemplate = cloneTemplate;
exports.elementWithAbsolutePaths = elementWithAbsolutePaths;
exports.getElementById = getElementById;
exports.getHTML = getHTML;
exports.getSlot = getSlot;
exports.setSlotText = setSlotText;
var _assert = _interopRequireDefault(require("assert"));
var _utils = require("../../utils.js");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
// Homebridge plugin for Home Connect home appliances
// Copyright © 2023 Alexander Thoukydides

// Get an HTML element by its "id" attribute
function getElementById(elementId) {
  const element = document.getElementById(elementId);
  (0, _utils.assertIsInstanceOf)(element, HTMLElement);
  return element;
}
// Get an HTML element using a slot name
function getSlot(within, slotName) {
  const slots = within.querySelectorAll(`[slot="${slotName}"]`);
  _assert.default.equal(slots.length, 1, `Expected exactly one slot with name "${slotName}"`);
  (0, _utils.assertIsInstanceOf)(slots[0], HTMLElement);
  return slots[0];
}
// Set the text content of multiple slot elements
function setSlotText(within, slotText) {
  for (const [slotName, text] of Object.entries(slotText)) getSlot(within, slotName).textContent = text;
}
// Create a copy of a template element
function cloneTemplate(elementId, slotText) {
  // Find the template element
  const template = document.getElementById(elementId);
  (0, _utils.assertIsInstanceOf)(template, HTMLTemplateElement);
  // Clone the template's document-fragment and set slot values
  const documentFragment = template.content.cloneNode(true);
  (0, _utils.assertIsInstanceOf)(documentFragment, DocumentFragment);
  if (slotText) setSlotText(documentFragment, slotText);
  return documentFragment;
}
// Make URI paths absolute
function elementWithAbsolutePaths(fragment) {
  for (const attribute of ['href', 'src']) {
    const elements = fragment.querySelectorAll(`[${attribute}]`);
    for (const element of Array.from(elements)) {
      const path = element.getAttribute(attribute);
      (0, _utils.assertIsDefined)(path);
      element.setAttribute(attribute, new URL(path, location.href).href);
    }
  }
  return fragment;
}
// Obtain the HTML serialization of a template element
function getHTML(fragment) {
  const serializer = new XMLSerializer();
  return serializer.serializeToString(fragment);
}

},{"../../utils.js":12,"assert":14}],10:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = exports.DebugFeatures = exports.ConfigPlugin = exports.ConfigAppliances = exports.ApplianceProgramOptions = exports.ApplianceProgramConfig = exports.ApplianceNamesPrefix = exports.ApplianceFeatures = exports.ApplianceConfig = exports.AddProgramsConfig = void 0;
var t = _interopRequireWildcard(require("ts-interface-checker"));
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
/**
 * This module was automatically generated by `ts-interface-builder`
 */

// tslint:disable:object-literal-key-quotes
const ConfigPlugin = exports.ConfigPlugin = t.iface([], {
  "platform": "string",
  "name": t.opt("string"),
  "clientid": "string",
  "clientsecret": t.opt("string"),
  "simulator": t.opt("boolean"),
  "china": t.opt("boolean"),
  "language": t.iface([], {
    "api": "string"
  }),
  "debug": t.opt(t.array("DebugFeatures"))
});
const DebugFeatures = exports.DebugFeatures = t.union(t.lit('Log API Headers'), t.lit('Log API Bodies'), t.lit('Log Appliance IDs'), t.lit('Log Debug as Info'), t.lit('Mock Appliances'));
const ConfigAppliances = exports.ConfigAppliances = t.iface([], {
  [t.indexKey]: "ApplianceConfig"
});
const AddProgramsConfig = exports.AddProgramsConfig = t.union(t.lit('none'), t.lit('auto'), t.lit('custom'));
const ApplianceConfig = exports.ApplianceConfig = t.iface([], {
  "enabled": t.opt("boolean"),
  "names": t.opt(t.iface([], {
    "prefix": "ApplianceNamesPrefix"
  })),
  "features": t.opt("ApplianceFeatures"),
  "addprograms": t.opt("AddProgramsConfig"),
  "programs": t.opt(t.array("ApplianceProgramConfig"))
});
const ApplianceNamesPrefix = exports.ApplianceNamesPrefix = t.iface([], {
  "programs": t.opt("boolean"),
  "other": t.opt("boolean")
});
const ApplianceFeatures = exports.ApplianceFeatures = t.iface([], {
  [t.indexKey]: "boolean"
});
const ApplianceProgramConfig = exports.ApplianceProgramConfig = t.iface([], {
  "name": "string",
  "key": "string",
  "selectonly": t.opt("boolean"),
  "options": t.opt("ApplianceProgramOptions")
});
const ApplianceProgramOptions = exports.ApplianceProgramOptions = t.iface([], {
  [t.indexKey]: t.union("string", "number", "boolean")
});
const exportedTypeSuite = {
  ConfigPlugin,
  DebugFeatures,
  ConfigAppliances,
  AddProgramsConfig,
  ApplianceConfig,
  ApplianceNamesPrefix,
  ApplianceFeatures,
  ApplianceProgramConfig,
  ApplianceProgramOptions
};
var _default = exports.default = exportedTypeSuite;

},{"ts-interface-checker":62}],11:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.typeSuite = exports.default = exports.checkers = void 0;
var _tsInterfaceChecker = require("ts-interface-checker");
var _configTypesTi = _interopRequireDefault(require("./config-types-ti.js"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
// This module was automatically generated by node ts-interface-post.ts
// 2025-01-08T16:11:31.518Z

// Type definitions
const typeSuite = exports.typeSuite = _configTypesTi.default;
// Checkers
const checkers = exports.checkers = (0, _tsInterfaceChecker.createCheckers)(_configTypesTi.default);
// Export the checkers by default
var _default = exports.default = checkers;

},{"./config-types-ti.js":10,"ts-interface-checker":62}],12:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.MS = void 0;
exports.assertIsBoolean = assertIsBoolean;
exports.assertIsDefined = assertIsDefined;
exports.assertIsInstanceOf = assertIsInstanceOf;
exports.assertIsNumber = assertIsNumber;
exports.assertIsString = assertIsString;
exports.assertIsUndefined = assertIsUndefined;
exports.columns = columns;
exports.deepMerge = deepMerge;
exports.formatList = formatList;
exports.formatMilliseconds = formatMilliseconds;
exports.formatSeconds = formatSeconds;
exports.getValidationTree = getValidationTree;
exports.keyofChecker = keyofChecker;
exports.plural = plural;
var _assert = _interopRequireDefault(require("assert"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
// Homebridge plugin for Home Connect home appliances
// Copyright © 2023 Alexander Thoukydides

// Milliseconds in a second
const MS = exports.MS = 1000;
// Type assertions
function assertIsDefined(value) {
  _assert.default.notStrictEqual(value, undefined);
  _assert.default.notStrictEqual(value, null);
}
function assertIsUndefined(value) {
  _assert.default.strictEqual(value, undefined);
}
function assertIsString(value) {
  _assert.default.strictEqual(typeof value, 'string');
}
function assertIsNumber(value) {
  _assert.default.strictEqual(typeof value, 'number');
}
function assertIsBoolean(value) {
  _assert.default.strictEqual(typeof value, 'boolean');
}
function assertIsInstanceOf(value, type) {
  (0, _assert.default)(value instanceof type, `Not an instance of ${type.name}`);
}
// Format a milliseconds duration
function formatMilliseconds(ms, maxParts = 2) {
  if (ms < 1) return 'n/a';
  // Split the duration into components
  const duration = [['day', Math.floor(ms / (24 * 60 * 60 * MS))], ['hour', Math.floor(ms / (60 * 60 * MS)) % 24], ['minute', Math.floor(ms / (60 * MS)) % 60], ['second', Math.floor(ms / MS) % 60], ['millisecond', Math.floor(ms) % MS]];
  // Remove any leading zero components
  while (duration[0]?.[1] === 0) duration.shift();
  // Combine the required number of remaining components
  return duration.slice(0, maxParts).filter(([_key, value]) => value !== 0).map(([key, value]) => plural(value, key)).join(' ');
}
// Format a seconds duration
function formatSeconds(seconds, maxParts = 2) {
  return formatMilliseconds(seconds * 1000, maxParts);
}
// Format a list (with Oxford comma)
function formatList(items) {
  switch (items.length) {
    case 0:
      return 'n/a';
    case 1:
      return items[0] ?? '';
    case 2:
      return `${items[0]} and ${items[1]}`;
    default:
      return [...items.slice(0, -1), `and ${items[items.length - 1]}`].join(', ');
  }
}
// Format a counted noun (handling most regular cases automatically)
function plural(count, noun, showCount = true) {
  const [singular, plural] = Array.isArray(noun) ? noun : [noun, ''];
  noun = count === 1 ? singular : plural;
  if (!noun) {
    // Apply regular rules
    const rules = [['on$', 'a', 2],
    // phenomenon/phenomena criterion/criteria
    ['us$', 'i', 1],
    //     cactus/cacti         focus/foci
    ['[^aeiou]y$', 'ies', 1],
    //        cty/cites         puppy/puppies
    ['(ch|is|o|s|sh|x|z)$', 'es', 0],
    //       iris/irises        truss/trusses
    ['', 's', 0] //        cat/cats          house/houses
    ];
    const rule = rules.find(([ending]) => new RegExp(ending, 'i').test(singular));
    assertIsDefined(rule);
    const matchCase = s => singular === singular.toUpperCase() ? s.toUpperCase() : s;
    noun = singular.substring(0, singular.length - rule[2]).concat(matchCase(rule[1]));
  }
  return showCount ? `${count} ${noun}` : noun;
}
// Format strings in columns
function columns(rows, separator = '  ') {
  // Determine the required column widths
  const width = [];
  rows.forEach(row => {
    row.forEach((value, index) => {
      width[index] = Math.max(width[index] ?? 0, value.length);
    });
  });
  width.splice(-1, 1, 0);
  // Format the rows
  return rows.map(row => row.map((value, index) => value.padEnd(width[index] ?? 0)).join(separator));
}
// Recursive object assignment, skipping undefined values
function deepMerge(...objects) {
  const isObject = value => value !== undefined && typeof value === 'object' && !Array.isArray(value);
  return objects.reduce((acc, object) => {
    Object.entries(object).forEach(([key, value]) => {
      const accValue = acc[key];
      if (value === undefined) return;
      if (isObject(accValue) && isObject(value)) acc[key] = deepMerge(accValue, value);else acc[key] = value;
    });
    return acc;
  }, {});
}
// Convert checker validation error into lines of text
function getValidationTree(errors) {
  const lines = [];
  errors.forEach((error, index) => {
    const prefix = (a, b) => index < errors.length - 1 ? a : b;
    lines.push(`${prefix('├─ ', '└─ ')}${error.path} ${error.message}`);
    if (error.nested) {
      const nested = getValidationTree(error.nested);
      lines.push(...nested.map(line => `${prefix('│  ', '   ')} ${line}`));
    }
  });
  return lines;
}
// Extract property keys or union literal from a ti-interface-checker type
function keyofChecker(typeSuite, type) {
  const checker = type;
  // TIface
  const props = [];
  if (checker.propSet instanceof Set) {
    props.push(...checker.propSet);
  }
  if (Array.isArray(checker.bases)) {
    for (const base of checker.bases) {
      const baseType = typeSuite[base];
      assertIsDefined(baseType);
      props.push(...keyofChecker(typeSuite, baseType));
    }
  }
  // TUnion or TIntersection
  if (Array.isArray(checker.ttypes)) {
    for (const ttype of checker.ttypes) props.push(...keyofChecker(typeSuite, ttype));
  }
  // TEnum
  if (checker.validValues instanceof Set) {
    props.push(...checker.validValues);
  }
  if (typeof checker.value === 'string') {
    // TLiteral
    props.push(checker.value);
  } else if (typeof checker.name === 'string') {
    // TName
    const nameType = typeSuite[checker.name];
    assertIsDefined(nameType);
    props.push(...keyofChecker(typeSuite, nameType));
  }
  return props;
}

},{"assert":14}],13:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

},{}],14:[function(require,module,exports){
(function (global){(function (){
'use strict';

var objectAssign = require('object.assign/polyfill')();

// compare and isBuffer taken from https://github.com/feross/buffer/blob/680e9e5e488f22aac27599a57dc844a6315928dd/index.js
// original notice:

/*!
 * The buffer module from node.js, for the browser.
 *
 * @author   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
 * @license  MIT
 */
function compare(a, b) {
  if (a === b) {
    return 0;
  }

  var x = a.length;
  var y = b.length;

  for (var i = 0, len = Math.min(x, y); i < len; ++i) {
    if (a[i] !== b[i]) {
      x = a[i];
      y = b[i];
      break;
    }
  }

  if (x < y) {
    return -1;
  }
  if (y < x) {
    return 1;
  }
  return 0;
}
function isBuffer(b) {
  if (global.Buffer && typeof global.Buffer.isBuffer === 'function') {
    return global.Buffer.isBuffer(b);
  }
  return !!(b != null && b._isBuffer);
}

// based on node assert, original notice:
// NB: The URL to the CommonJS spec is kept just for tradition.
//     node-assert has evolved a lot since then, both in API and behavior.

// http://wiki.commonjs.org/wiki/Unit_Testing/1.0
//
// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8!
//
// Originally from narwhal.js (http://narwhaljs.org)
// Copyright (c) 2009 Thomas Robinson <280north.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the 'Software'), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

var util = require('util/');
var hasOwn = Object.prototype.hasOwnProperty;
var pSlice = Array.prototype.slice;
var functionsHaveNames = (function () {
  return function foo() {}.name === 'foo';
}());
function pToString (obj) {
  return Object.prototype.toString.call(obj);
}
function isView(arrbuf) {
  if (isBuffer(arrbuf)) {
    return false;
  }
  if (typeof global.ArrayBuffer !== 'function') {
    return false;
  }
  if (typeof ArrayBuffer.isView === 'function') {
    return ArrayBuffer.isView(arrbuf);
  }
  if (!arrbuf) {
    return false;
  }
  if (arrbuf instanceof DataView) {
    return true;
  }
  if (arrbuf.buffer && arrbuf.buffer instanceof ArrayBuffer) {
    return true;
  }
  return false;
}
// 1. The assert module provides functions that throw
// AssertionError's when particular conditions are not met. The
// assert module must conform to the following interface.

var assert = module.exports = ok;

// 2. The AssertionError is defined in assert.
// new assert.AssertionError({ message: message,
//                             actual: actual,
//                             expected: expected })

var regex = /\s*function\s+([^\(\s]*)\s*/;
// based on https://github.com/ljharb/function.prototype.name/blob/adeeeec8bfcc6068b187d7d9fb3d5bb1d3a30899/implementation.js
function getName(func) {
  if (!util.isFunction(func)) {
    return;
  }
  if (functionsHaveNames) {
    return func.name;
  }
  var str = func.toString();
  var match = str.match(regex);
  return match && match[1];
}
assert.AssertionError = function AssertionError(options) {
  this.name = 'AssertionError';
  this.actual = options.actual;
  this.expected = options.expected;
  this.operator = options.operator;
  if (options.message) {
    this.message = options.message;
    this.generatedMessage = false;
  } else {
    this.message = getMessage(this);
    this.generatedMessage = true;
  }
  var stackStartFunction = options.stackStartFunction || fail;
  if (Error.captureStackTrace) {
    Error.captureStackTrace(this, stackStartFunction);
  } else {
    // non v8 browsers so we can have a stacktrace
    var err = new Error();
    if (err.stack) {
      var out = err.stack;

      // try to strip useless frames
      var fn_name = getName(stackStartFunction);
      var idx = out.indexOf('\n' + fn_name);
      if (idx >= 0) {
        // once we have located the function frame
        // we need to strip out everything before it (and its line)
        var next_line = out.indexOf('\n', idx + 1);
        out = out.substring(next_line + 1);
      }

      this.stack = out;
    }
  }
};

// assert.AssertionError instanceof Error
util.inherits(assert.AssertionError, Error);

function truncate(s, n) {
  if (typeof s === 'string') {
    return s.length < n ? s : s.slice(0, n);
  } else {
    return s;
  }
}
function inspect(something) {
  if (functionsHaveNames || !util.isFunction(something)) {
    return util.inspect(something);
  }
  var rawname = getName(something);
  var name = rawname ? ': ' + rawname : '';
  return '[Function' +  name + ']';
}
function getMessage(self) {
  return truncate(inspect(self.actual), 128) + ' ' +
         self.operator + ' ' +
         truncate(inspect(self.expected), 128);
}

// At present only the three keys mentioned above are used and
// understood by the spec. Implementations or sub modules can pass
// other keys to the AssertionError's constructor - they will be
// ignored.

// 3. All of the following functions must throw an AssertionError
// when a corresponding condition is not met, with a message that
// may be undefined if not provided.  All assertion methods provide
// both the actual and expected values to the assertion error for
// display purposes.

function fail(actual, expected, message, operator, stackStartFunction) {
  throw new assert.AssertionError({
    message: message,
    actual: actual,
    expected: expected,
    operator: operator,
    stackStartFunction: stackStartFunction
  });
}

// EXTENSION! allows for well behaved errors defined elsewhere.
assert.fail = fail;

// 4. Pure assertion tests whether a value is truthy, as determined
// by !!guard.
// assert.ok(guard, message_opt);
// This statement is equivalent to assert.equal(true, !!guard,
// message_opt);. To test strictly for the value true, use
// assert.strictEqual(true, guard, message_opt);.

function ok(value, message) {
  if (!value) fail(value, true, message, '==', assert.ok);
}
assert.ok = ok;

// 5. The equality assertion tests shallow, coercive equality with
// ==.
// assert.equal(actual, expected, message_opt);

assert.equal = function equal(actual, expected, message) {
  if (actual != expected) fail(actual, expected, message, '==', assert.equal);
};

// 6. The non-equality assertion tests for whether two objects are not equal
// with != assert.notEqual(actual, expected, message_opt);

assert.notEqual = function notEqual(actual, expected, message) {
  if (actual == expected) {
    fail(actual, expected, message, '!=', assert.notEqual);
  }
};

// 7. The equivalence assertion tests a deep equality relation.
// assert.deepEqual(actual, expected, message_opt);

assert.deepEqual = function deepEqual(actual, expected, message) {
  if (!_deepEqual(actual, expected, false)) {
    fail(actual, expected, message, 'deepEqual', assert.deepEqual);
  }
};

assert.deepStrictEqual = function deepStrictEqual(actual, expected, message) {
  if (!_deepEqual(actual, expected, true)) {
    fail(actual, expected, message, 'deepStrictEqual', assert.deepStrictEqual);
  }
};

function _deepEqual(actual, expected, strict, memos) {
  // 7.1. All identical values are equivalent, as determined by ===.
  if (actual === expected) {
    return true;
  } else if (isBuffer(actual) && isBuffer(expected)) {
    return compare(actual, expected) === 0;

  // 7.2. If the expected value is a Date object, the actual value is
  // equivalent if it is also a Date object that refers to the same time.
  } else if (util.isDate(actual) && util.isDate(expected)) {
    return actual.getTime() === expected.getTime();

  // 7.3 If the expected value is a RegExp object, the actual value is
  // equivalent if it is also a RegExp object with the same source and
  // properties (`global`, `multiline`, `lastIndex`, `ignoreCase`).
  } else if (util.isRegExp(actual) && util.isRegExp(expected)) {
    return actual.source === expected.source &&
           actual.global === expected.global &&
           actual.multiline === expected.multiline &&
           actual.lastIndex === expected.lastIndex &&
           actual.ignoreCase === expected.ignoreCase;

  // 7.4. Other pairs that do not both pass typeof value == 'object',
  // equivalence is determined by ==.
  } else if ((actual === null || typeof actual !== 'object') &&
             (expected === null || typeof expected !== 'object')) {
    return strict ? actual === expected : actual == expected;

  // If both values are instances of typed arrays, wrap their underlying
  // ArrayBuffers in a Buffer each to increase performance
  // This optimization requires the arrays to have the same type as checked by
  // Object.prototype.toString (aka pToString). Never perform binary
  // comparisons for Float*Arrays, though, since e.g. +0 === -0 but their
  // bit patterns are not identical.
  } else if (isView(actual) && isView(expected) &&
             pToString(actual) === pToString(expected) &&
             !(actual instanceof Float32Array ||
               actual instanceof Float64Array)) {
    return compare(new Uint8Array(actual.buffer),
                   new Uint8Array(expected.buffer)) === 0;

  // 7.5 For all other Object pairs, including Array objects, equivalence is
  // determined by having the same number of owned properties (as verified
  // with Object.prototype.hasOwnProperty.call), the same set of keys
  // (although not necessarily the same order), equivalent values for every
  // corresponding key, and an identical 'prototype' property. Note: this
  // accounts for both named and indexed properties on Arrays.
  } else if (isBuffer(actual) !== isBuffer(expected)) {
    return false;
  } else {
    memos = memos || {actual: [], expected: []};

    var actualIndex = memos.actual.indexOf(actual);
    if (actualIndex !== -1) {
      if (actualIndex === memos.expected.indexOf(expected)) {
        return true;
      }
    }

    memos.actual.push(actual);
    memos.expected.push(expected);

    return objEquiv(actual, expected, strict, memos);
  }
}

function isArguments(object) {
  return Object.prototype.toString.call(object) == '[object Arguments]';
}

function objEquiv(a, b, strict, actualVisitedObjects) {
  if (a === null || a === undefined || b === null || b === undefined)
    return false;
  // if one is a primitive, the other must be same
  if (util.isPrimitive(a) || util.isPrimitive(b))
    return a === b;
  if (strict && Object.getPrototypeOf(a) !== Object.getPrototypeOf(b))
    return false;
  var aIsArgs = isArguments(a);
  var bIsArgs = isArguments(b);
  if ((aIsArgs && !bIsArgs) || (!aIsArgs && bIsArgs))
    return false;
  if (aIsArgs) {
    a = pSlice.call(a);
    b = pSlice.call(b);
    return _deepEqual(a, b, strict);
  }
  var ka = objectKeys(a);
  var kb = objectKeys(b);
  var key, i;
  // having the same number of owned properties (keys incorporates
  // hasOwnProperty)
  if (ka.length !== kb.length)
    return false;
  //the same set of keys (although not necessarily the same order),
  ka.sort();
  kb.sort();
  //~~~cheap key test
  for (i = ka.length - 1; i >= 0; i--) {
    if (ka[i] !== kb[i])
      return false;
  }
  //equivalent values for every corresponding key, and
  //~~~possibly expensive deep test
  for (i = ka.length - 1; i >= 0; i--) {
    key = ka[i];
    if (!_deepEqual(a[key], b[key], strict, actualVisitedObjects))
      return false;
  }
  return true;
}

// 8. The non-equivalence assertion tests for any deep inequality.
// assert.notDeepEqual(actual, expected, message_opt);

assert.notDeepEqual = function notDeepEqual(actual, expected, message) {
  if (_deepEqual(actual, expected, false)) {
    fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual);
  }
};

assert.notDeepStrictEqual = notDeepStrictEqual;
function notDeepStrictEqual(actual, expected, message) {
  if (_deepEqual(actual, expected, true)) {
    fail(actual, expected, message, 'notDeepStrictEqual', notDeepStrictEqual);
  }
}


// 9. The strict equality assertion tests strict equality, as determined by ===.
// assert.strictEqual(actual, expected, message_opt);

assert.strictEqual = function strictEqual(actual, expected, message) {
  if (actual !== expected) {
    fail(actual, expected, message, '===', assert.strictEqual);
  }
};

// 10. The strict non-equality assertion tests for strict inequality, as
// determined by !==.  assert.notStrictEqual(actual, expected, message_opt);

assert.notStrictEqual = function notStrictEqual(actual, expected, message) {
  if (actual === expected) {
    fail(actual, expected, message, '!==', assert.notStrictEqual);
  }
};

function expectedException(actual, expected) {
  if (!actual || !expected) {
    return false;
  }

  if (Object.prototype.toString.call(expected) == '[object RegExp]') {
    return expected.test(actual);
  }

  try {
    if (actual instanceof expected) {
      return true;
    }
  } catch (e) {
    // Ignore.  The instanceof check doesn't work for arrow functions.
  }

  if (Error.isPrototypeOf(expected)) {
    return false;
  }

  return expected.call({}, actual) === true;
}

function _tryBlock(block) {
  var error;
  try {
    block();
  } catch (e) {
    error = e;
  }
  return error;
}

function _throws(shouldThrow, block, expected, message) {
  var actual;

  if (typeof block !== 'function') {
    throw new TypeError('"block" argument must be a function');
  }

  if (typeof expected === 'string') {
    message = expected;
    expected = null;
  }

  actual = _tryBlock(block);

  message = (expected && expected.name ? ' (' + expected.name + ').' : '.') +
            (message ? ' ' + message : '.');

  if (shouldThrow && !actual) {
    fail(actual, expected, 'Missing expected exception' + message);
  }

  var userProvidedMessage = typeof message === 'string';
  var isUnwantedException = !shouldThrow && util.isError(actual);
  var isUnexpectedException = !shouldThrow && actual && !expected;

  if ((isUnwantedException &&
      userProvidedMessage &&
      expectedException(actual, expected)) ||
      isUnexpectedException) {
    fail(actual, expected, 'Got unwanted exception' + message);
  }

  if ((shouldThrow && actual && expected &&
      !expectedException(actual, expected)) || (!shouldThrow && actual)) {
    throw actual;
  }
}

// 11. Expected to throw an error:
// assert.throws(block, Error_opt, message_opt);

assert.throws = function(block, /*optional*/error, /*optional*/message) {
  _throws(true, block, error, message);
};

// EXTENSION! This is annoying to write outside this module.
assert.doesNotThrow = function(block, /*optional*/error, /*optional*/message) {
  _throws(false, block, error, message);
};

assert.ifError = function(err) { if (err) throw err; };

// Expose a strict only variant of assert
function strict(value, message) {
  if (!value) fail(value, true, message, '==', strict);
}
assert.strict = objectAssign(strict, assert, {
  equal: assert.strictEqual,
  deepEqual: assert.deepStrictEqual,
  notEqual: assert.notStrictEqual,
  notDeepEqual: assert.notDeepStrictEqual
});
assert.strict.strict = assert.strict;

var objectKeys = Object.keys || function (obj) {
  var keys = [];
  for (var key in obj) {
    if (hasOwn.call(obj, key)) keys.push(key);
  }
  return keys;
};

}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})

},{"object.assign/polyfill":60,"util/":17}],15:[function(require,module,exports){
if (typeof Object.create === 'function') {
  // implementation from standard node.js 'util' module
  module.exports = function inherits(ctor, superCtor) {
    ctor.super_ = superCtor
    ctor.prototype = Object.create(superCtor.prototype, {
      constructor: {
        value: ctor,
        enumerable: false,
        writable: true,
        configurable: true
      }
    });
  };
} else {
  // old school shim for old browsers
  module.exports = function inherits(ctor, superCtor) {
    ctor.super_ = superCtor
    var TempCtor = function () {}
    TempCtor.prototype = superCtor.prototype
    ctor.prototype = new TempCtor()
    ctor.prototype.constructor = ctor
  }
}

},{}],16:[function(require,module,exports){
module.exports = function isBuffer(arg) {
  return arg && typeof arg === 'object'
    && typeof arg.copy === 'function'
    && typeof arg.fill === 'function'
    && typeof arg.readUInt8 === 'function';
}
},{}],17:[function(require,module,exports){
(function (process,global){(function (){
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

var formatRegExp = /%[sdj%]/g;
exports.format = function(f) {
  if (!isString(f)) {
    var objects = [];
    for (var i = 0; i < arguments.length; i++) {
      objects.push(inspect(arguments[i]));
    }
    return objects.join(' ');
  }

  var i = 1;
  var args = arguments;
  var len = args.length;
  var str = String(f).replace(formatRegExp, function(x) {
    if (x === '%%') return '%';
    if (i >= len) return x;
    switch (x) {
      case '%s': return String(args[i++]);
      case '%d': return Number(args[i++]);
      case '%j':
        try {
          return JSON.stringify(args[i++]);
        } catch (_) {
          return '[Circular]';
        }
      default:
        return x;
    }
  });
  for (var x = args[i]; i < len; x = args[++i]) {
    if (isNull(x) || !isObject(x)) {
      str += ' ' + x;
    } else {
      str += ' ' + inspect(x);
    }
  }
  return str;
};


// Mark that a method should not be used.
// Returns a modified function which warns once by default.
// If --no-deprecation is set, then it is a no-op.
exports.deprecate = function(fn, msg) {
  // Allow for deprecating things in the process of starting up.
  if (isUndefined(global.process)) {
    return function() {
      return exports.deprecate(fn, msg).apply(this, arguments);
    };
  }

  if (process.noDeprecation === true) {
    return fn;
  }

  var warned = false;
  function deprecated() {
    if (!warned) {
      if (process.throwDeprecation) {
        throw new Error(msg);
      } else if (process.traceDeprecation) {
        console.trace(msg);
      } else {
        console.error(msg);
      }
      warned = true;
    }
    return fn.apply(this, arguments);
  }

  return deprecated;
};


var debugs = {};
var debugEnviron;
exports.debuglog = function(set) {
  if (isUndefined(debugEnviron))
    debugEnviron = process.env.NODE_DEBUG || '';
  set = set.toUpperCase();
  if (!debugs[set]) {
    if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) {
      var pid = process.pid;
      debugs[set] = function() {
        var msg = exports.format.apply(exports, arguments);
        console.error('%s %d: %s', set, pid, msg);
      };
    } else {
      debugs[set] = function() {};
    }
  }
  return debugs[set];
};


/**
 * Echos the value of a value. Trys to print the value out
 * in the best way possible given the different types.
 *
 * @param {Object} obj The object to print out.
 * @param {Object} opts Optional options object that alters the output.
 */
/* legacy: obj, showHidden, depth, colors*/
function inspect(obj, opts) {
  // default options
  var ctx = {
    seen: [],
    stylize: stylizeNoColor
  };
  // legacy...
  if (arguments.length >= 3) ctx.depth = arguments[2];
  if (arguments.length >= 4) ctx.colors = arguments[3];
  if (isBoolean(opts)) {
    // legacy...
    ctx.showHidden = opts;
  } else if (opts) {
    // got an "options" object
    exports._extend(ctx, opts);
  }
  // set default options
  if (isUndefined(ctx.showHidden)) ctx.showHidden = false;
  if (isUndefined(ctx.depth)) ctx.depth = 2;
  if (isUndefined(ctx.colors)) ctx.colors = false;
  if (isUndefined(ctx.customInspect)) ctx.customInspect = true;
  if (ctx.colors) ctx.stylize = stylizeWithColor;
  return formatValue(ctx, obj, ctx.depth);
}
exports.inspect = inspect;


// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
inspect.colors = {
  'bold' : [1, 22],
  'italic' : [3, 23],
  'underline' : [4, 24],
  'inverse' : [7, 27],
  'white' : [37, 39],
  'grey' : [90, 39],
  'black' : [30, 39],
  'blue' : [34, 39],
  'cyan' : [36, 39],
  'green' : [32, 39],
  'magenta' : [35, 39],
  'red' : [31, 39],
  'yellow' : [33, 39]
};

// Don't use 'blue' not visible on cmd.exe
inspect.styles = {
  'special': 'cyan',
  'number': 'yellow',
  'boolean': 'yellow',
  'undefined': 'grey',
  'null': 'bold',
  'string': 'green',
  'date': 'magenta',
  // "name": intentionally not styling
  'regexp': 'red'
};


function stylizeWithColor(str, styleType) {
  var style = inspect.styles[styleType];

  if (style) {
    return '\u001b[' + inspect.colors[style][0] + 'm' + str +
           '\u001b[' + inspect.colors[style][1] + 'm';
  } else {
    return str;
  }
}


function stylizeNoColor(str, styleType) {
  return str;
}


function arrayToHash(array) {
  var hash = {};

  array.forEach(function(val, idx) {
    hash[val] = true;
  });

  return hash;
}


function formatValue(ctx, value, recurseTimes) {
  // Provide a hook for user-specified inspect functions.
  // Check that value is an object with an inspect function on it
  if (ctx.customInspect &&
      value &&
      isFunction(value.inspect) &&
      // Filter out the util module, it's inspect function is special
      value.inspect !== exports.inspect &&
      // Also filter out any prototype objects using the circular check.
      !(value.constructor && value.constructor.prototype === value)) {
    var ret = value.inspect(recurseTimes, ctx);
    if (!isString(ret)) {
      ret = formatValue(ctx, ret, recurseTimes);
    }
    return ret;
  }

  // Primitive types cannot have properties
  var primitive = formatPrimitive(ctx, value);
  if (primitive) {
    return primitive;
  }

  // Look up the keys of the object.
  var keys = Object.keys(value);
  var visibleKeys = arrayToHash(keys);

  if (ctx.showHidden) {
    keys = Object.getOwnPropertyNames(value);
  }

  // IE doesn't make error fields non-enumerable
  // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx
  if (isError(value)
      && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {
    return formatError(value);
  }

  // Some type of object without properties can be shortcutted.
  if (keys.length === 0) {
    if (isFunction(value)) {
      var name = value.name ? ': ' + value.name : '';
      return ctx.stylize('[Function' + name + ']', 'special');
    }
    if (isRegExp(value)) {
      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
    }
    if (isDate(value)) {
      return ctx.stylize(Date.prototype.toString.call(value), 'date');
    }
    if (isError(value)) {
      return formatError(value);
    }
  }

  var base = '', array = false, braces = ['{', '}'];

  // Make Array say that they are Array
  if (isArray(value)) {
    array = true;
    braces = ['[', ']'];
  }

  // Make functions say that they are functions
  if (isFunction(value)) {
    var n = value.name ? ': ' + value.name : '';
    base = ' [Function' + n + ']';
  }

  // Make RegExps say that they are RegExps
  if (isRegExp(value)) {
    base = ' ' + RegExp.prototype.toString.call(value);
  }

  // Make dates with properties first say the date
  if (isDate(value)) {
    base = ' ' + Date.prototype.toUTCString.call(value);
  }

  // Make error with message first say the error
  if (isError(value)) {
    base = ' ' + formatError(value);
  }

  if (keys.length === 0 && (!array || value.length == 0)) {
    return braces[0] + base + braces[1];
  }

  if (recurseTimes < 0) {
    if (isRegExp(value)) {
      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
    } else {
      return ctx.stylize('[Object]', 'special');
    }
  }

  ctx.seen.push(value);

  var output;
  if (array) {
    output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
  } else {
    output = keys.map(function(key) {
      return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
    });
  }

  ctx.seen.pop();

  return reduceToSingleString(output, base, braces);
}


function formatPrimitive(ctx, value) {
  if (isUndefined(value))
    return ctx.stylize('undefined', 'undefined');
  if (isString(value)) {
    var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
                                             .replace(/'/g, "\\'")
                                             .replace(/\\"/g, '"') + '\'';
    return ctx.stylize(simple, 'string');
  }
  if (isNumber(value))
    return ctx.stylize('' + value, 'number');
  if (isBoolean(value))
    return ctx.stylize('' + value, 'boolean');
  // For some reason typeof null is "object", so special case here.
  if (isNull(value))
    return ctx.stylize('null', 'null');
}


function formatError(value) {
  return '[' + Error.prototype.toString.call(value) + ']';
}


function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
  var output = [];
  for (var i = 0, l = value.length; i < l; ++i) {
    if (hasOwnProperty(value, String(i))) {
      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
          String(i), true));
    } else {
      output.push('');
    }
  }
  keys.forEach(function(key) {
    if (!key.match(/^\d+$/)) {
      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
          key, true));
    }
  });
  return output;
}


function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
  var name, str, desc;
  desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };
  if (desc.get) {
    if (desc.set) {
      str = ctx.stylize('[Getter/Setter]', 'special');
    } else {
      str = ctx.stylize('[Getter]', 'special');
    }
  } else {
    if (desc.set) {
      str = ctx.stylize('[Setter]', 'special');
    }
  }
  if (!hasOwnProperty(visibleKeys, key)) {
    name = '[' + key + ']';
  }
  if (!str) {
    if (ctx.seen.indexOf(desc.value) < 0) {
      if (isNull(recurseTimes)) {
        str = formatValue(ctx, desc.value, null);
      } else {
        str = formatValue(ctx, desc.value, recurseTimes - 1);
      }
      if (str.indexOf('\n') > -1) {
        if (array) {
          str = str.split('\n').map(function(line) {
            return '  ' + line;
          }).join('\n').substr(2);
        } else {
          str = '\n' + str.split('\n').map(function(line) {
            return '   ' + line;
          }).join('\n');
        }
      }
    } else {
      str = ctx.stylize('[Circular]', 'special');
    }
  }
  if (isUndefined(name)) {
    if (array && key.match(/^\d+$/)) {
      return str;
    }
    name = JSON.stringify('' + key);
    if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
      name = name.substr(1, name.length - 2);
      name = ctx.stylize(name, 'name');
    } else {
      name = name.replace(/'/g, "\\'")
                 .replace(/\\"/g, '"')
                 .replace(/(^"|"$)/g, "'");
      name = ctx.stylize(name, 'string');
    }
  }

  return name + ': ' + str;
}


function reduceToSingleString(output, base, braces) {
  var numLinesEst = 0;
  var length = output.reduce(function(prev, cur) {
    numLinesEst++;
    if (cur.indexOf('\n') >= 0) numLinesEst++;
    return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1;
  }, 0);

  if (length > 60) {
    return braces[0] +
           (base === '' ? '' : base + '\n ') +
           ' ' +
           output.join(',\n  ') +
           ' ' +
           braces[1];
  }

  return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
}


// NOTE: These type checking functions intentionally don't use `instanceof`
// because it is fragile and can be easily faked with `Object.create()`.
function isArray(ar) {
  return Array.isArray(ar);
}
exports.isArray = isArray;

function isBoolean(arg) {
  return typeof arg === 'boolean';
}
exports.isBoolean = isBoolean;

function isNull(arg) {
  return arg === null;
}
exports.isNull = isNull;

function isNullOrUndefined(arg) {
  return arg == null;
}
exports.isNullOrUndefined = isNullOrUndefined;

function isNumber(arg) {
  return typeof arg === 'number';
}
exports.isNumber = isNumber;

function isString(arg) {
  return typeof arg === 'string';
}
exports.isString = isString;

function isSymbol(arg) {
  return typeof arg === 'symbol';
}
exports.isSymbol = isSymbol;

function isUndefined(arg) {
  return arg === void 0;
}
exports.isUndefined = isUndefined;

function isRegExp(re) {
  return isObject(re) && objectToString(re) === '[object RegExp]';
}
exports.isRegExp = isRegExp;

function isObject(arg) {
  return typeof arg === 'object' && arg !== null;
}
exports.isObject = isObject;

function isDate(d) {
  return isObject(d) && objectToString(d) === '[object Date]';
}
exports.isDate = isDate;

function isError(e) {
  return isObject(e) &&
      (objectToString(e) === '[object Error]' || e instanceof Error);
}
exports.isError = isError;

function isFunction(arg) {
  return typeof arg === 'function';
}
exports.isFunction = isFunction;

function isPrimitive(arg) {
  return arg === null ||
         typeof arg === 'boolean' ||
         typeof arg === 'number' ||
         typeof arg === 'string' ||
         typeof arg === 'symbol' ||  // ES6 symbol
         typeof arg === 'undefined';
}
exports.isPrimitive = isPrimitive;

exports.isBuffer = require('./support/isBuffer');

function objectToString(o) {
  return Object.prototype.toString.call(o);
}


function pad(n) {
  return n < 10 ? '0' + n.toString(10) : n.toString(10);
}


var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
              'Oct', 'Nov', 'Dec'];

// 26 Feb 16:19:34
function timestamp() {
  var d = new Date();
  var time = [pad(d.getHours()),
              pad(d.getMinutes()),
              pad(d.getSeconds())].join(':');
  return [d.getDate(), months[d.getMonth()], time].join(' ');
}


// log is just a thin wrapper to console.log that prepends a timestamp
exports.log = function() {
  console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));
};


/**
 * Inherit the prototype methods from one constructor into another.
 *
 * The Function.prototype.inherits from lang.js rewritten as a standalone
 * function (not on Function.prototype). NOTE: If this file is to be loaded
 * during bootstrapping this function needs to be rewritten using some native
 * functions as prototype setup using normal JavaScript does not work as
 * expected during bootstrapping (see mirror.js in r114903).
 *
 * @param {function} ctor Constructor function which needs to inherit the
 *     prototype.
 * @param {function} superCtor Constructor function to inherit prototype from.
 */
exports.inherits = require('inherits');

exports._extend = function(origin, add) {
  // Don't do anything if add isn't an object
  if (!add || !isObject(add)) return origin;

  var keys = Object.keys(add);
  var i = keys.length;
  while (i--) {
    origin[keys[i]] = add[keys[i]];
  }
  return origin;
};

function hasOwnProperty(obj, prop) {
  return Object.prototype.hasOwnProperty.call(obj, prop);
}

}).call(this)}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})

},{"./support/isBuffer":16,"_process":61,"inherits":15}],18:[function(require,module,exports){
'use strict'

exports.byteLength = byteLength
exports.toByteArray = toByteArray
exports.fromByteArray = fromByteArray

var lookup = []
var revLookup = []
var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array

var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
for (var i = 0, len = code.length; i < len; ++i) {
  lookup[i] = code[i]
  revLookup[code.charCodeAt(i)] = i
}

// Support decoding URL-safe base64 strings, as Node.js does.
// See: https://en.wikipedia.org/wiki/Base64#URL_applications
revLookup['-'.charCodeAt(0)] = 62
revLookup['_'.charCodeAt(0)] = 63

function getLens (b64) {
  var len = b64.length

  if (len % 4 > 0) {
    throw new Error('Invalid string. Length must be a multiple of 4')
  }

  // Trim off extra bytes after placeholder bytes are found
  // See: https://github.com/beatgammit/base64-js/issues/42
  var validLen = b64.indexOf('=')
  if (validLen === -1) validLen = len

  var placeHoldersLen = validLen === len
    ? 0
    : 4 - (validLen % 4)

  return [validLen, placeHoldersLen]
}

// base64 is 4/3 + up to two characters of the original data
function byteLength (b64) {
  var lens = getLens(b64)
  var validLen = lens[0]
  var placeHoldersLen = lens[1]
  return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen
}

function _byteLength (b64, validLen, placeHoldersLen) {
  return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen
}

function toByteArray (b64) {
  var tmp
  var lens = getLens(b64)
  var validLen = lens[0]
  var placeHoldersLen = lens[1]

  var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen))

  var curByte = 0

  // if there are placeholders, only get up to the last complete 4 chars
  var len = placeHoldersLen > 0
    ? validLen - 4
    : validLen

  var i
  for (i = 0; i < len; i += 4) {
    tmp =
      (revLookup[b64.charCodeAt(i)] << 18) |
      (revLookup[b64.charCodeAt(i + 1)] << 12) |
      (revLookup[b64.charCodeAt(i + 2)] << 6) |
      revLookup[b64.charCodeAt(i + 3)]
    arr[curByte++] = (tmp >> 16) & 0xFF
    arr[curByte++] = (tmp >> 8) & 0xFF
    arr[curByte++] = tmp & 0xFF
  }

  if (placeHoldersLen === 2) {
    tmp =
      (revLookup[b64.charCodeAt(i)] << 2) |
      (revLookup[b64.charCodeAt(i + 1)] >> 4)
    arr[curByte++] = tmp & 0xFF
  }

  if (placeHoldersLen === 1) {
    tmp =
      (revLookup[b64.charCodeAt(i)] << 10) |
      (revLookup[b64.charCodeAt(i + 1)] << 4) |
      (revLookup[b64.charCodeAt(i + 2)] >> 2)
    arr[curByte++] = (tmp >> 8) & 0xFF
    arr[curByte++] = tmp & 0xFF
  }

  return arr
}

function tripletToBase64 (num) {
  return lookup[num >> 18 & 0x3F] +
    lookup[num >> 12 & 0x3F] +
    lookup[num >> 6 & 0x3F] +
    lookup[num & 0x3F]
}

function encodeChunk (uint8, start, end) {
  var tmp
  var output = []
  for (var i = start; i < end; i += 3) {
    tmp =
      ((uint8[i] << 16) & 0xFF0000) +
      ((uint8[i + 1] << 8) & 0xFF00) +
      (uint8[i + 2] & 0xFF)
    output.push(tripletToBase64(tmp))
  }
  return output.join('')
}

function fromByteArray (uint8) {
  var tmp
  var len = uint8.length
  var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes
  var parts = []
  var maxChunkLength = 16383 // must be multiple of 3

  // go through the array every three bytes, we'll deal with trailing stuff later
  for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {
    parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)))
  }

  // pad the end with zeros, but make sure to not forget the extra bytes
  if (extraBytes === 1) {
    tmp = uint8[len - 1]
    parts.push(
      lookup[tmp >> 2] +
      lookup[(tmp << 4) & 0x3F] +
      '=='
    )
  } else if (extraBytes === 2) {
    tmp = (uint8[len - 2] << 8) + uint8[len - 1]
    parts.push(
      lookup[tmp >> 10] +
      lookup[(tmp >> 4) & 0x3F] +
      lookup[(tmp << 2) & 0x3F] +
      '='
    )
  }

  return parts.join('')
}

},{}],19:[function(require,module,exports){
(function (Buffer){(function (){
/*!
 * The buffer module from node.js, for the browser.
 *
 * @author   Feross Aboukhadijeh <https://feross.org>
 * @license  MIT
 */
/* eslint-disable no-proto */

'use strict'

var base64 = require('base64-js')
var ieee754 = require('ieee754')

exports.Buffer = Buffer
exports.SlowBuffer = SlowBuffer
exports.INSPECT_MAX_BYTES = 50

var K_MAX_LENGTH = 0x7fffffff
exports.kMaxLength = K_MAX_LENGTH

/**
 * If `Buffer.TYPED_ARRAY_SUPPORT`:
 *   === true    Use Uint8Array implementation (fastest)
 *   === false   Print warning and recommend using `buffer` v4.x which has an Object
 *               implementation (most compatible, even IE6)
 *
 * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,
 * Opera 11.6+, iOS 4.2+.
 *
 * We report that the browser does not support typed arrays if the are not subclassable
 * using __proto__. Firefox 4-29 lacks support for adding new properties to `Uint8Array`
 * (See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438). IE 10 lacks support
 * for __proto__ and has a buggy typed array implementation.
 */
Buffer.TYPED_ARRAY_SUPPORT = typedArraySupport()

if (!Buffer.TYPED_ARRAY_SUPPORT && typeof console !== 'undefined' &&
    typeof console.error === 'function') {
  console.error(
    'This browser lacks typed array (Uint8Array) support which is required by ' +
    '`buffer` v5.x. Use `buffer` v4.x if you require old browser support.'
  )
}

function typedArraySupport () {
  // Can typed array instances can be augmented?
  try {
    var arr = new Uint8Array(1)
    arr.__proto__ = { __proto__: Uint8Array.prototype, foo: function () { return 42 } }
    return arr.foo() === 42
  } catch (e) {
    return false
  }
}

Object.defineProperty(Buffer.prototype, 'parent', {
  enumerable: true,
  get: function () {
    if (!Buffer.isBuffer(this)) return undefined
    return this.buffer
  }
})

Object.defineProperty(Buffer.prototype, 'offset', {
  enumerable: true,
  get: function () {
    if (!Buffer.isBuffer(this)) return undefined
    return this.byteOffset
  }
})

function createBuffer (length) {
  if (length > K_MAX_LENGTH) {
    throw new RangeError('The value "' + length + '" is invalid for option "size"')
  }
  // Return an augmented `Uint8Array` instance
  var buf = new Uint8Array(length)
  buf.__proto__ = Buffer.prototype
  return buf
}

/**
 * The Buffer constructor returns instances of `Uint8Array` that have their
 * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of
 * `Uint8Array`, so the returned instances will have all the node `Buffer` methods
 * and the `Uint8Array` methods. Square bracket notation works as expected -- it
 * returns a single octet.
 *
 * The `Uint8Array` prototype remains unmodified.
 */

function Buffer (arg, encodingOrOffset, length) {
  // Common case.
  if (typeof arg === 'number') {
    if (typeof encodingOrOffset === 'string') {
      throw new TypeError(
        'The "string" argument must be of type string. Received type number'
      )
    }
    return allocUnsafe(arg)
  }
  return from(arg, encodingOrOffset, length)
}

// Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97
if (typeof Symbol !== 'undefined' && Symbol.species != null &&
    Buffer[Symbol.species] === Buffer) {
  Object.defineProperty(Buffer, Symbol.species, {
    value: null,
    configurable: true,
    enumerable: false,
    writable: false
  })
}

Buffer.poolSize = 8192 // not used by this implementation

function from (value, encodingOrOffset, length) {
  if (typeof value === 'string') {
    return fromString(value, encodingOrOffset)
  }

  if (ArrayBuffer.isView(value)) {
    return fromArrayLike(value)
  }

  if (value == null) {
    throw TypeError(
      'The first argument must be one of type string, Buffer, ArrayBuffer, Array, ' +
      'or Array-like Object. Received type ' + (typeof value)
    )
  }

  if (isInstance(value, ArrayBuffer) ||
      (value && isInstance(value.buffer, ArrayBuffer))) {
    return fromArrayBuffer(value, encodingOrOffset, length)
  }

  if (typeof value === 'number') {
    throw new TypeError(
      'The "value" argument must not be of type number. Received type number'
    )
  }

  var valueOf = value.valueOf && value.valueOf()
  if (valueOf != null && valueOf !== value) {
    return Buffer.from(valueOf, encodingOrOffset, length)
  }

  var b = fromObject(value)
  if (b) return b

  if (typeof Symbol !== 'undefined' && Symbol.toPrimitive != null &&
      typeof value[Symbol.toPrimitive] === 'function') {
    return Buffer.from(
      value[Symbol.toPrimitive]('string'), encodingOrOffset, length
    )
  }

  throw new TypeError(
    'The first argument must be one of type string, Buffer, ArrayBuffer, Array, ' +
    'or Array-like Object. Received type ' + (typeof value)
  )
}

/**
 * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError
 * if value is a number.
 * Buffer.from(str[, encoding])
 * Buffer.from(array)
 * Buffer.from(buffer)
 * Buffer.from(arrayBuffer[, byteOffset[, length]])
 **/
Buffer.from = function (value, encodingOrOffset, length) {
  return from(value, encodingOrOffset, length)
}

// Note: Change prototype *after* Buffer.from is defined to workaround Chrome bug:
// https://github.com/feross/buffer/pull/148
Buffer.prototype.__proto__ = Uint8Array.prototype
Buffer.__proto__ = Uint8Array

function assertSize (size) {
  if (typeof size !== 'number') {
    throw new TypeError('"size" argument must be of type number')
  } else if (size < 0) {
    throw new RangeError('The value "' + size + '" is invalid for option "size"')
  }
}

function alloc (size, fill, encoding) {
  assertSize(size)
  if (size <= 0) {
    return createBuffer(size)
  }
  if (fill !== undefined) {
    // Only pay attention to encoding if it's a string. This
    // prevents accidentally sending in a number that would
    // be interpretted as a start offset.
    return typeof encoding === 'string'
      ? createBuffer(size).fill(fill, encoding)
      : createBuffer(size).fill(fill)
  }
  return createBuffer(size)
}

/**
 * Creates a new filled Buffer instance.
 * alloc(size[, fill[, encoding]])
 **/
Buffer.alloc = function (size, fill, encoding) {
  return alloc(size, fill, encoding)
}

function allocUnsafe (size) {
  assertSize(size)
  return createBuffer(size < 0 ? 0 : checked(size) | 0)
}

/**
 * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.
 * */
Buffer.allocUnsafe = function (size) {
  return allocUnsafe(size)
}
/**
 * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.
 */
Buffer.allocUnsafeSlow = function (size) {
  return allocUnsafe(size)
}

function fromString (string, encoding) {
  if (typeof encoding !== 'string' || encoding === '') {
    encoding = 'utf8'
  }

  if (!Buffer.isEncoding(encoding)) {
    throw new TypeError('Unknown encoding: ' + encoding)
  }

  var length = byteLength(string, encoding) | 0
  var buf = createBuffer(length)

  var actual = buf.write(string, encoding)

  if (actual !== length) {
    // Writing a hex string, for example, that contains invalid characters will
    // cause everything after the first invalid character to be ignored. (e.g.
    // 'abxxcd' will be treated as 'ab')
    buf = buf.slice(0, actual)
  }

  return buf
}

function fromArrayLike (array) {
  var length = array.length < 0 ? 0 : checked(array.length) | 0
  var buf = createBuffer(length)
  for (var i = 0; i < length; i += 1) {
    buf[i] = array[i] & 255
  }
  return buf
}

function fromArrayBuffer (array, byteOffset, length) {
  if (byteOffset < 0 || array.byteLength < byteOffset) {
    throw new RangeError('"offset" is outside of buffer bounds')
  }

  if (array.byteLength < byteOffset + (length || 0)) {
    throw new RangeError('"length" is outside of buffer bounds')
  }

  var buf
  if (byteOffset === undefined && length === undefined) {
    buf = new Uint8Array(array)
  } else if (length === undefined) {
    buf = new Uint8Array(array, byteOffset)
  } else {
    buf = new Uint8Array(array, byteOffset, length)
  }

  // Return an augmented `Uint8Array` instance
  buf.__proto__ = Buffer.prototype
  return buf
}

function fromObject (obj) {
  if (Buffer.isBuffer(obj)) {
    var len = checked(obj.length) | 0
    var buf = createBuffer(len)

    if (buf.length === 0) {
      return buf
    }

    obj.copy(buf, 0, 0, len)
    return buf
  }

  if (obj.length !== undefined) {
    if (typeof obj.length !== 'number' || numberIsNaN(obj.length)) {
      return createBuffer(0)
    }
    return fromArrayLike(obj)
  }

  if (obj.type === 'Buffer' && Array.isArray(obj.data)) {
    return fromArrayLike(obj.data)
  }
}

function checked (length) {
  // Note: cannot use `length < K_MAX_LENGTH` here because that fails when
  // length is NaN (which is otherwise coerced to zero.)
  if (length >= K_MAX_LENGTH) {
    throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
                         'size: 0x' + K_MAX_LENGTH.toString(16) + ' bytes')
  }
  return length | 0
}

function SlowBuffer (length) {
  if (+length != length) { // eslint-disable-line eqeqeq
    length = 0
  }
  return Buffer.alloc(+length)
}

Buffer.isBuffer = function isBuffer (b) {
  return b != null && b._isBuffer === true &&
    b !== Buffer.prototype // so Buffer.isBuffer(Buffer.prototype) will be false
}

Buffer.compare = function compare (a, b) {
  if (isInstance(a, Uint8Array)) a = Buffer.from(a, a.offset, a.byteLength)
  if (isInstance(b, Uint8Array)) b = Buffer.from(b, b.offset, b.byteLength)
  if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {
    throw new TypeError(
      'The "buf1", "buf2" arguments must be one of type Buffer or Uint8Array'
    )
  }

  if (a === b) return 0

  var x = a.length
  var y = b.length

  for (var i = 0, len = Math.min(x, y); i < len; ++i) {
    if (a[i] !== b[i]) {
      x = a[i]
      y = b[i]
      break
    }
  }

  if (x < y) return -1
  if (y < x) return 1
  return 0
}

Buffer.isEncoding = function isEncoding (encoding) {
  switch (String(encoding).toLowerCase()) {
    case 'hex':
    case 'utf8':
    case 'utf-8':
    case 'ascii':
    case 'latin1':
    case 'binary':
    case 'base64':
    case 'ucs2':
    case 'ucs-2':
    case 'utf16le':
    case 'utf-16le':
      return true
    default:
      return false
  }
}

Buffer.concat = function concat (list, length) {
  if (!Array.isArray(list)) {
    throw new TypeError('"list" argument must be an Array of Buffers')
  }

  if (list.length === 0) {
    return Buffer.alloc(0)
  }

  var i
  if (length === undefined) {
    length = 0
    for (i = 0; i < list.length; ++i) {
      length += list[i].length
    }
  }

  var buffer = Buffer.allocUnsafe(length)
  var pos = 0
  for (i = 0; i < list.length; ++i) {
    var buf = list[i]
    if (isInstance(buf, Uint8Array)) {
      buf = Buffer.from(buf)
    }
    if (!Buffer.isBuffer(buf)) {
      throw new TypeError('"list" argument must be an Array of Buffers')
    }
    buf.copy(buffer, pos)
    pos += buf.length
  }
  return buffer
}

function byteLength (string, encoding) {
  if (Buffer.isBuffer(string)) {
    return string.length
  }
  if (ArrayBuffer.isView(string) || isInstance(string, ArrayBuffer)) {
    return string.byteLength
  }
  if (typeof string !== 'string') {
    throw new TypeError(
      'The "string" argument must be one of type string, Buffer, or ArrayBuffer. ' +
      'Received type ' + typeof string
    )
  }

  var len = string.length
  var mustMatch = (arguments.length > 2 && arguments[2] === true)
  if (!mustMatch && len === 0) return 0

  // Use a for loop to avoid recursion
  var loweredCase = false
  for (;;) {
    switch (encoding) {
      case 'ascii':
      case 'latin1':
      case 'binary':
        return len
      case 'utf8':
      case 'utf-8':
        return utf8ToBytes(string).length
      case 'ucs2':
      case 'ucs-2':
      case 'utf16le':
      case 'utf-16le':
        return len * 2
      case 'hex':
        return len >>> 1
      case 'base64':
        return base64ToBytes(string).length
      default:
        if (loweredCase) {
          return mustMatch ? -1 : utf8ToBytes(string).length // assume utf8
        }
        encoding = ('' + encoding).toLowerCase()
        loweredCase = true
    }
  }
}
Buffer.byteLength = byteLength

function slowToString (encoding, start, end) {
  var loweredCase = false

  // No need to verify that "this.length <= MAX_UINT32" since it's a read-only
  // property of a typed array.

  // This behaves neither like String nor Uint8Array in that we set start/end
  // to their upper/lower bounds if the value passed is out of range.
  // undefined is handled specially as per ECMA-262 6th Edition,
  // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.
  if (start === undefined || start < 0) {
    start = 0
  }
  // Return early if start > this.length. Done here to prevent potential uint32
  // coercion fail below.
  if (start > this.length) {
    return ''
  }

  if (end === undefined || end > this.length) {
    end = this.length
  }

  if (end <= 0) {
    return ''
  }

  // Force coersion to uint32. This will also coerce falsey/NaN values to 0.
  end >>>= 0
  start >>>= 0

  if (end <= start) {
    return ''
  }

  if (!encoding) encoding = 'utf8'

  while (true) {
    switch (encoding) {
      case 'hex':
        return hexSlice(this, start, end)

      case 'utf8':
      case 'utf-8':
        return utf8Slice(this, start, end)

      case 'ascii':
        return asciiSlice(this, start, end)

      case 'latin1':
      case 'binary':
        return latin1Slice(this, start, end)

      case 'base64':
        return base64Slice(this, start, end)

      case 'ucs2':
      case 'ucs-2':
      case 'utf16le':
      case 'utf-16le':
        return utf16leSlice(this, start, end)

      default:
        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
        encoding = (encoding + '').toLowerCase()
        loweredCase = true
    }
  }
}

// This property is used by `Buffer.isBuffer` (and the `is-buffer` npm package)
// to detect a Buffer instance. It's not possible to use `instanceof Buffer`
// reliably in a browserify context because there could be multiple different
// copies of the 'buffer' package in use. This method works even for Buffer
// instances that were created from another copy of the `buffer` package.
// See: https://github.com/feross/buffer/issues/154
Buffer.prototype._isBuffer = true

function swap (b, n, m) {
  var i = b[n]
  b[n] = b[m]
  b[m] = i
}

Buffer.prototype.swap16 = function swap16 () {
  var len = this.length
  if (len % 2 !== 0) {
    throw new RangeError('Buffer size must be a multiple of 16-bits')
  }
  for (var i = 0; i < len; i += 2) {
    swap(this, i, i + 1)
  }
  return this
}

Buffer.prototype.swap32 = function swap32 () {
  var len = this.length
  if (len % 4 !== 0) {
    throw new RangeError('Buffer size must be a multiple of 32-bits')
  }
  for (var i = 0; i < len; i += 4) {
    swap(this, i, i + 3)
    swap(this, i + 1, i + 2)
  }
  return this
}

Buffer.prototype.swap64 = function swap64 () {
  var len = this.length
  if (len % 8 !== 0) {
    throw new RangeError('Buffer size must be a multiple of 64-bits')
  }
  for (var i = 0; i < len; i += 8) {
    swap(this, i, i + 7)
    swap(this, i + 1, i + 6)
    swap(this, i + 2, i + 5)
    swap(this, i + 3, i + 4)
  }
  return this
}

Buffer.prototype.toString = function toString () {
  var length = this.length
  if (length === 0) return ''
  if (arguments.length === 0) return utf8Slice(this, 0, length)
  return slowToString.apply(this, arguments)
}

Buffer.prototype.toLocaleString = Buffer.prototype.toString

Buffer.prototype.equals = function equals (b) {
  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
  if (this === b) return true
  return Buffer.compare(this, b) === 0
}

Buffer.prototype.inspect = function inspect () {
  var str = ''
  var max = exports.INSPECT_MAX_BYTES
  str = this.toString('hex', 0, max).replace(/(.{2})/g, '$1 ').trim()
  if (this.length > max) str += ' ... '
  return '<Buffer ' + str + '>'
}

Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) {
  if (isInstance(target, Uint8Array)) {
    target = Buffer.from(target, target.offset, target.byteLength)
  }
  if (!Buffer.isBuffer(target)) {
    throw new TypeError(
      'The "target" argument must be one of type Buffer or Uint8Array. ' +
      'Received type ' + (typeof target)
    )
  }

  if (start === undefined) {
    start = 0
  }
  if (end === undefined) {
    end = target ? target.length : 0
  }
  if (thisStart === undefined) {
    thisStart = 0
  }
  if (thisEnd === undefined) {
    thisEnd = this.length
  }

  if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {
    throw new RangeError('out of range index')
  }

  if (thisStart >= thisEnd && start >= end) {
    return 0
  }
  if (thisStart >= thisEnd) {
    return -1
  }
  if (start >= end) {
    return 1
  }

  start >>>= 0
  end >>>= 0
  thisStart >>>= 0
  thisEnd >>>= 0

  if (this === target) return 0

  var x = thisEnd - thisStart
  var y = end - start
  var len = Math.min(x, y)

  var thisCopy = this.slice(thisStart, thisEnd)
  var targetCopy = target.slice(start, end)

  for (var i = 0; i < len; ++i) {
    if (thisCopy[i] !== targetCopy[i]) {
      x = thisCopy[i]
      y = targetCopy[i]
      break
    }
  }

  if (x < y) return -1
  if (y < x) return 1
  return 0
}

// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,
// OR the last index of `val` in `buffer` at offset <= `byteOffset`.
//
// Arguments:
// - buffer - a Buffer to search
// - val - a string, Buffer, or number
// - byteOffset - an index into `buffer`; will be clamped to an int32
// - encoding - an optional encoding, relevant is val is a string
// - dir - true for indexOf, false for lastIndexOf
function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {
  // Empty buffer means no match
  if (buffer.length === 0) return -1

  // Normalize byteOffset
  if (typeof byteOffset === 'string') {
    encoding = byteOffset
    byteOffset = 0
  } else if (byteOffset > 0x7fffffff) {
    byteOffset = 0x7fffffff
  } else if (byteOffset < -0x80000000) {
    byteOffset = -0x80000000
  }
  byteOffset = +byteOffset // Coerce to Number.
  if (numberIsNaN(byteOffset)) {
    // byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer
    byteOffset = dir ? 0 : (buffer.length - 1)
  }

  // Normalize byteOffset: negative offsets start from the end of the buffer
  if (byteOffset < 0) byteOffset = buffer.length + byteOffset
  if (byteOffset >= buffer.length) {
    if (dir) return -1
    else byteOffset = buffer.length - 1
  } else if (byteOffset < 0) {
    if (dir) byteOffset = 0
    else return -1
  }

  // Normalize val
  if (typeof val === 'string') {
    val = Buffer.from(val, encoding)
  }

  // Finally, search either indexOf (if dir is true) or lastIndexOf
  if (Buffer.isBuffer(val)) {
    // Special case: looking for empty string/buffer always fails
    if (val.length === 0) {
      return -1
    }
    return arrayIndexOf(buffer, val, byteOffset, encoding, dir)
  } else if (typeof val === 'number') {
    val = val & 0xFF // Search for a byte value [0-255]
    if (typeof Uint8Array.prototype.indexOf === 'function') {
      if (dir) {
        return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)
      } else {
        return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset)
      }
    }
    return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir)
  }

  throw new TypeError('val must be string, number or Buffer')
}

function arrayIndexOf (arr, val, byteOffset, encoding, dir) {
  var indexSize = 1
  var arrLength = arr.length
  var valLength = val.length

  if (encoding !== undefined) {
    encoding = String(encoding).toLowerCase()
    if (encoding === 'ucs2' || encoding === 'ucs-2' ||
        encoding === 'utf16le' || encoding === 'utf-16le') {
      if (arr.length < 2 || val.length < 2) {
        return -1
      }
      indexSize = 2
      arrLength /= 2
      valLength /= 2
      byteOffset /= 2
    }
  }

  function read (buf, i) {
    if (indexSize === 1) {
      return buf[i]
    } else {
      return buf.readUInt16BE(i * indexSize)
    }
  }

  var i
  if (dir) {
    var foundIndex = -1
    for (i = byteOffset; i < arrLength; i++) {
      if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {
        if (foundIndex === -1) foundIndex = i
        if (i - foundIndex + 1 === valLength) return foundIndex * indexSize
      } else {
        if (foundIndex !== -1) i -= i - foundIndex
        foundIndex = -1
      }
    }
  } else {
    if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength
    for (i = byteOffset; i >= 0; i--) {
      var found = true
      for (var j = 0; j < valLength; j++) {
        if (read(arr, i + j) !== read(val, j)) {
          found = false
          break
        }
      }
      if (found) return i
    }
  }

  return -1
}

Buffer.prototype.includes = function includes (val, byteOffset, encoding) {
  return this.indexOf(val, byteOffset, encoding) !== -1
}

Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {
  return bidirectionalIndexOf(this, val, byteOffset, encoding, true)
}

Buffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) {
  return bidirectionalIndexOf(this, val, byteOffset, encoding, false)
}

function hexWrite (buf, string, offset, length) {
  offset = Number(offset) || 0
  var remaining = buf.length - offset
  if (!length) {
    length = remaining
  } else {
    length = Number(length)
    if (length > remaining) {
      length = remaining
    }
  }

  var strLen = string.length

  if (length > strLen / 2) {
    length = strLen / 2
  }
  for (var i = 0; i < length; ++i) {
    var parsed = parseInt(string.substr(i * 2, 2), 16)
    if (numberIsNaN(parsed)) return i
    buf[offset + i] = parsed
  }
  return i
}

function utf8Write (buf, string, offset, length) {
  return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)
}

function asciiWrite (buf, string, offset, length) {
  return blitBuffer(asciiToBytes(string), buf, offset, length)
}

function latin1Write (buf, string, offset, length) {
  return asciiWrite(buf, string, offset, length)
}

function base64Write (buf, string, offset, length) {
  return blitBuffer(base64ToBytes(string), buf, offset, length)
}

function ucs2Write (buf, string, offset, length) {
  return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)
}

Buffer.prototype.write = function write (string, offset, length, encoding) {
  // Buffer#write(string)
  if (offset === undefined) {
    encoding = 'utf8'
    length = this.length
    offset = 0
  // Buffer#write(string, encoding)
  } else if (length === undefined && typeof offset === 'string') {
    encoding = offset
    length = this.length
    offset = 0
  // Buffer#write(string, offset[, length][, encoding])
  } else if (isFinite(offset)) {
    offset = offset >>> 0
    if (isFinite(length)) {
      length = length >>> 0
      if (encoding === undefined) encoding = 'utf8'
    } else {
      encoding = length
      length = undefined
    }
  } else {
    throw new Error(
      'Buffer.write(string, encoding, offset[, length]) is no longer supported'
    )
  }

  var remaining = this.length - offset
  if (length === undefined || length > remaining) length = remaining

  if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {
    throw new RangeError('Attempt to write outside buffer bounds')
  }

  if (!encoding) encoding = 'utf8'

  var loweredCase = false
  for (;;) {
    switch (encoding) {
      case 'hex':
        return hexWrite(this, string, offset, length)

      case 'utf8':
      case 'utf-8':
        return utf8Write(this, string, offset, length)

      case 'ascii':
        return asciiWrite(this, string, offset, length)

      case 'latin1':
      case 'binary':
        return latin1Write(this, string, offset, length)

      case 'base64':
        // Warning: maxLength not taken into account in base64Write
        return base64Write(this, string, offset, length)

      case 'ucs2':
      case 'ucs-2':
      case 'utf16le':
      case 'utf-16le':
        return ucs2Write(this, string, offset, length)

      default:
        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
        encoding = ('' + encoding).toLowerCase()
        loweredCase = true
    }
  }
}

Buffer.prototype.toJSON = function toJSON () {
  return {
    type: 'Buffer',
    data: Array.prototype.slice.call(this._arr || this, 0)
  }
}

function base64Slice (buf, start, end) {
  if (start === 0 && end === buf.length) {
    return base64.fromByteArray(buf)
  } else {
    return base64.fromByteArray(buf.slice(start, end))
  }
}

function utf8Slice (buf, start, end) {
  end = Math.min(buf.length, end)
  var res = []

  var i = start
  while (i < end) {
    var firstByte = buf[i]
    var codePoint = null
    var bytesPerSequence = (firstByte > 0xEF) ? 4
      : (firstByte > 0xDF) ? 3
        : (firstByte > 0xBF) ? 2
          : 1

    if (i + bytesPerSequence <= end) {
      var secondByte, thirdByte, fourthByte, tempCodePoint

      switch (bytesPerSequence) {
        case 1:
          if (firstByte < 0x80) {
            codePoint = firstByte
          }
          break
        case 2:
          secondByte = buf[i + 1]
          if ((secondByte & 0xC0) === 0x80) {
            tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)
            if (tempCodePoint > 0x7F) {
              codePoint = tempCodePoint
            }
          }
          break
        case 3:
          secondByte = buf[i + 1]
          thirdByte = buf[i + 2]
          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {
            tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)
            if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {
              codePoint = tempCodePoint
            }
          }
          break
        case 4:
          secondByte = buf[i + 1]
          thirdByte = buf[i + 2]
          fourthByte = buf[i + 3]
          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {
            tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)
            if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {
              codePoint = tempCodePoint
            }
          }
      }
    }

    if (codePoint === null) {
      // we did not generate a valid codePoint so insert a
      // replacement char (U+FFFD) and advance only 1 byte
      codePoint = 0xFFFD
      bytesPerSequence = 1
    } else if (codePoint > 0xFFFF) {
      // encode to utf16 (surrogate pair dance)
      codePoint -= 0x10000
      res.push(codePoint >>> 10 & 0x3FF | 0xD800)
      codePoint = 0xDC00 | codePoint & 0x3FF
    }

    res.push(codePoint)
    i += bytesPerSequence
  }

  return decodeCodePointsArray(res)
}

// Based on http://stackoverflow.com/a/22747272/680742, the browser with
// the lowest limit is Chrome, with 0x10000 args.
// We go 1 magnitude less, for safety
var MAX_ARGUMENTS_LENGTH = 0x1000

function decodeCodePointsArray (codePoints) {
  var len = codePoints.length
  if (len <= MAX_ARGUMENTS_LENGTH) {
    return String.fromCharCode.apply(String, codePoints) // avoid extra slice()
  }

  // Decode in chunks to avoid "call stack size exceeded".
  var res = ''
  var i = 0
  while (i < len) {
    res += String.fromCharCode.apply(
      String,
      codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)
    )
  }
  return res
}

function asciiSlice (buf, start, end) {
  var ret = ''
  end = Math.min(buf.length, end)

  for (var i = start; i < end; ++i) {
    ret += String.fromCharCode(buf[i] & 0x7F)
  }
  return ret
}

function latin1Slice (buf, start, end) {
  var ret = ''
  end = Math.min(buf.length, end)

  for (var i = start; i < end; ++i) {
    ret += String.fromCharCode(buf[i])
  }
  return ret
}

function hexSlice (buf, start, end) {
  var len = buf.length

  if (!start || start < 0) start = 0
  if (!end || end < 0 || end > len) end = len

  var out = ''
  for (var i = start; i < end; ++i) {
    out += toHex(buf[i])
  }
  return out
}

function utf16leSlice (buf, start, end) {
  var bytes = buf.slice(start, end)
  var res = ''
  for (var i = 0; i < bytes.length; i += 2) {
    res += String.fromCharCode(bytes[i] + (bytes[i + 1] * 256))
  }
  return res
}

Buffer.prototype.slice = function slice (start, end) {
  var len = this.length
  start = ~~start
  end = end === undefined ? len : ~~end

  if (start < 0) {
    start += len
    if (start < 0) start = 0
  } else if (start > len) {
    start = len
  }

  if (end < 0) {
    end += len
    if (end < 0) end = 0
  } else if (end > len) {
    end = len
  }

  if (end < start) end = start

  var newBuf = this.subarray(start, end)
  // Return an augmented `Uint8Array` instance
  newBuf.__proto__ = Buffer.prototype
  return newBuf
}

/*
 * Need to make sure that buffer isn't trying to write out of bounds.
 */
function checkOffset (offset, ext, length) {
  if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')
  if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')
}

Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {
  offset = offset >>> 0
  byteLength = byteLength >>> 0
  if (!noAssert) checkOffset(offset, byteLength, this.length)

  var val = this[offset]
  var mul = 1
  var i = 0
  while (++i < byteLength && (mul *= 0x100)) {
    val += this[offset + i] * mul
  }

  return val
}

Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {
  offset = offset >>> 0
  byteLength = byteLength >>> 0
  if (!noAssert) {
    checkOffset(offset, byteLength, this.length)
  }

  var val = this[offset + --byteLength]
  var mul = 1
  while (byteLength > 0 && (mul *= 0x100)) {
    val += this[offset + --byteLength] * mul
  }

  return val
}

Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {
  offset = offset >>> 0
  if (!noAssert) checkOffset(offset, 1, this.length)
  return this[offset]
}

Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {
  offset = offset >>> 0
  if (!noAssert) checkOffset(offset, 2, this.length)
  return this[offset] | (this[offset + 1] << 8)
}

Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {
  offset = offset >>> 0
  if (!noAssert) checkOffset(offset, 2, this.length)
  return (this[offset] << 8) | this[offset + 1]
}

Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {
  offset = offset >>> 0
  if (!noAssert) checkOffset(offset, 4, this.length)

  return ((this[offset]) |
      (this[offset + 1] << 8) |
      (this[offset + 2] << 16)) +
      (this[offset + 3] * 0x1000000)
}

Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {
  offset = offset >>> 0
  if (!noAssert) checkOffset(offset, 4, this.length)

  return (this[offset] * 0x1000000) +
    ((this[offset + 1] << 16) |
    (this[offset + 2] << 8) |
    this[offset + 3])
}

Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {
  offset = offset >>> 0
  byteLength = byteLength >>> 0
  if (!noAssert) checkOffset(offset, byteLength, this.length)

  var val = this[offset]
  var mul = 1
  var i = 0
  while (++i < byteLength && (mul *= 0x100)) {
    val += this[offset + i] * mul
  }
  mul *= 0x80

  if (val >= mul) val -= Math.pow(2, 8 * byteLength)

  return val
}

Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {
  offset = offset >>> 0
  byteLength = byteLength >>> 0
  if (!noAssert) checkOffset(offset, byteLength, this.length)

  var i = byteLength
  var mul = 1
  var val = this[offset + --i]
  while (i > 0 && (mul *= 0x100)) {
    val += this[offset + --i] * mul
  }
  mul *= 0x80

  if (val >= mul) val -= Math.pow(2, 8 * byteLength)

  return val
}

Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) {
  offset = offset >>> 0
  if (!noAssert) checkOffset(offset, 1, this.length)
  if (!(this[offset] & 0x80)) return (this[offset])
  return ((0xff - this[offset] + 1) * -1)
}

Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {
  offset = offset >>> 0
  if (!noAssert) checkOffset(offset, 2, this.length)
  var val = this[offset] | (this[offset + 1] << 8)
  return (val & 0x8000) ? val | 0xFFFF0000 : val
}

Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {
  offset = offset >>> 0
  if (!noAssert) checkOffset(offset, 2, this.length)
  var val = this[offset + 1] | (this[offset] << 8)
  return (val & 0x8000) ? val | 0xFFFF0000 : val
}

Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {
  offset = offset >>> 0
  if (!noAssert) checkOffset(offset, 4, this.length)

  return (this[offset]) |
    (this[offset + 1] << 8) |
    (this[offset + 2] << 16) |
    (this[offset + 3] << 24)
}

Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {
  offset = offset >>> 0
  if (!noAssert) checkOffset(offset, 4, this.length)

  return (this[offset] << 24) |
    (this[offset + 1] << 16) |
    (this[offset + 2] << 8) |
    (this[offset + 3])
}

Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {
  offset = offset >>> 0
  if (!noAssert) checkOffset(offset, 4, this.length)
  return ieee754.read(this, offset, true, 23, 4)
}

Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {
  offset = offset >>> 0
  if (!noAssert) checkOffset(offset, 4, this.length)
  return ieee754.read(this, offset, false, 23, 4)
}

Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {
  offset = offset >>> 0
  if (!noAssert) checkOffset(offset, 8, this.length)
  return ieee754.read(this, offset, true, 52, 8)
}

Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {
  offset = offset >>> 0
  if (!noAssert) checkOffset(offset, 8, this.length)
  return ieee754.read(this, offset, false, 52, 8)
}

function checkInt (buf, value, offset, ext, max, min) {
  if (!Buffer.isBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance')
  if (value > max || value < min) throw new RangeError('"value" argument is out of bounds')
  if (offset + ext > buf.length) throw new RangeError('Index out of range')
}

Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {
  value = +value
  offset = offset >>> 0
  byteLength = byteLength >>> 0
  if (!noAssert) {
    var maxBytes = Math.pow(2, 8 * byteLength) - 1
    checkInt(this, value, offset, byteLength, maxBytes, 0)
  }

  var mul = 1
  var i = 0
  this[offset] = value & 0xFF
  while (++i < byteLength && (mul *= 0x100)) {
    this[offset + i] = (value / mul) & 0xFF
  }

  return offset + byteLength
}

Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {
  value = +value
  offset = offset >>> 0
  byteLength = byteLength >>> 0
  if (!noAssert) {
    var maxBytes = Math.pow(2, 8 * byteLength) - 1
    checkInt(this, value, offset, byteLength, maxBytes, 0)
  }

  var i = byteLength - 1
  var mul = 1
  this[offset + i] = value & 0xFF
  while (--i >= 0 && (mul *= 0x100)) {
    this[offset + i] = (value / mul) & 0xFF
  }

  return offset + byteLength
}

Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {
  value = +value
  offset = offset >>> 0
  if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)
  this[offset] = (value & 0xff)
  return offset + 1
}

Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {
  value = +value
  offset = offset >>> 0
  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
  this[offset] = (value & 0xff)
  this[offset + 1] = (value >>> 8)
  return offset + 2
}

Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {
  value = +value
  offset = offset >>> 0
  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
  this[offset] = (value >>> 8)
  this[offset + 1] = (value & 0xff)
  return offset + 2
}

Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {
  value = +value
  offset = offset >>> 0
  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
  this[offset + 3] = (value >>> 24)
  this[offset + 2] = (value >>> 16)
  this[offset + 1] = (value >>> 8)
  this[offset] = (value & 0xff)
  return offset + 4
}

Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {
  value = +value
  offset = offset >>> 0
  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
  this[offset] = (value >>> 24)
  this[offset + 1] = (value >>> 16)
  this[offset + 2] = (value >>> 8)
  this[offset + 3] = (value & 0xff)
  return offset + 4
}

Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {
  value = +value
  offset = offset >>> 0
  if (!noAssert) {
    var limit = Math.pow(2, (8 * byteLength) - 1)

    checkInt(this, value, offset, byteLength, limit - 1, -limit)
  }

  var i = 0
  var mul = 1
  var sub = 0
  this[offset] = value & 0xFF
  while (++i < byteLength && (mul *= 0x100)) {
    if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {
      sub = 1
    }
    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
  }

  return offset + byteLength
}

Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {
  value = +value
  offset = offset >>> 0
  if (!noAssert) {
    var limit = Math.pow(2, (8 * byteLength) - 1)

    checkInt(this, value, offset, byteLength, limit - 1, -limit)
  }

  var i = byteLength - 1
  var mul = 1
  var sub = 0
  this[offset + i] = value & 0xFF
  while (--i >= 0 && (mul *= 0x100)) {
    if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {
      sub = 1
    }
    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
  }

  return offset + byteLength
}

Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {
  value = +value
  offset = offset >>> 0
  if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)
  if (value < 0) value = 0xff + value + 1
  this[offset] = (value & 0xff)
  return offset + 1
}

Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {
  value = +value
  offset = offset >>> 0
  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
  this[offset] = (value & 0xff)
  this[offset + 1] = (value >>> 8)
  return offset + 2
}

Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {
  value = +value
  offset = offset >>> 0
  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
  this[offset] = (value >>> 8)
  this[offset + 1] = (value & 0xff)
  return offset + 2
}

Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {
  value = +value
  offset = offset >>> 0
  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
  this[offset] = (value & 0xff)
  this[offset + 1] = (value >>> 8)
  this[offset + 2] = (value >>> 16)
  this[offset + 3] = (value >>> 24)
  return offset + 4
}

Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {
  value = +value
  offset = offset >>> 0
  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
  if (value < 0) value = 0xffffffff + value + 1
  this[offset] = (value >>> 24)
  this[offset + 1] = (value >>> 16)
  this[offset + 2] = (value >>> 8)
  this[offset + 3] = (value & 0xff)
  return offset + 4
}

function checkIEEE754 (buf, value, offset, ext, max, min) {
  if (offset + ext > buf.length) throw new RangeError('Index out of range')
  if (offset < 0) throw new RangeError('Index out of range')
}

function writeFloat (buf, value, offset, littleEndian, noAssert) {
  value = +value
  offset = offset >>> 0
  if (!noAssert) {
    checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)
  }
  ieee754.write(buf, value, offset, littleEndian, 23, 4)
  return offset + 4
}

Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {
  return writeFloat(this, value, offset, true, noAssert)
}

Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {
  return writeFloat(this, value, offset, false, noAssert)
}

function writeDouble (buf, value, offset, littleEndian, noAssert) {
  value = +value
  offset = offset >>> 0
  if (!noAssert) {
    checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)
  }
  ieee754.write(buf, value, offset, littleEndian, 52, 8)
  return offset + 8
}

Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {
  return writeDouble(this, value, offset, true, noAssert)
}

Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {
  return writeDouble(this, value, offset, false, noAssert)
}

// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
Buffer.prototype.copy = function copy (target, targetStart, start, end) {
  if (!Buffer.isBuffer(target)) throw new TypeError('argument should be a Buffer')
  if (!start) start = 0
  if (!end && end !== 0) end = this.length
  if (targetStart >= target.length) targetStart = target.length
  if (!targetStart) targetStart = 0
  if (end > 0 && end < start) end = start

  // Copy 0 bytes; we're done
  if (end === start) return 0
  if (target.length === 0 || this.length === 0) return 0

  // Fatal error conditions
  if (targetStart < 0) {
    throw new RangeError('targetStart out of bounds')
  }
  if (start < 0 || start >= this.length) throw new RangeError('Index out of range')
  if (end < 0) throw new RangeError('sourceEnd out of bounds')

  // Are we oob?
  if (end > this.length) end = this.length
  if (target.length - targetStart < end - start) {
    end = target.length - targetStart + start
  }

  var len = end - start

  if (this === target && typeof Uint8Array.prototype.copyWithin === 'function') {
    // Use built-in when available, missing from IE11
    this.copyWithin(targetStart, start, end)
  } else if (this === target && start < targetStart && targetStart < end) {
    // descending copy from end
    for (var i = len - 1; i >= 0; --i) {
      target[i + targetStart] = this[i + start]
    }
  } else {
    Uint8Array.prototype.set.call(
      target,
      this.subarray(start, end),
      targetStart
    )
  }

  return len
}

// Usage:
//    buffer.fill(number[, offset[, end]])
//    buffer.fill(buffer[, offset[, end]])
//    buffer.fill(string[, offset[, end]][, encoding])
Buffer.prototype.fill = function fill (val, start, end, encoding) {
  // Handle string cases:
  if (typeof val === 'string') {
    if (typeof start === 'string') {
      encoding = start
      start = 0
      end = this.length
    } else if (typeof end === 'string') {
      encoding = end
      end = this.length
    }
    if (encoding !== undefined && typeof encoding !== 'string') {
      throw new TypeError('encoding must be a string')
    }
    if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {
      throw new TypeError('Unknown encoding: ' + encoding)
    }
    if (val.length === 1) {
      var code = val.charCodeAt(0)
      if ((encoding === 'utf8' && code < 128) ||
          encoding === 'latin1') {
        // Fast path: If `val` fits into a single byte, use that numeric value.
        val = code
      }
    }
  } else if (typeof val === 'number') {
    val = val & 255
  }

  // Invalid ranges are not set to a default, so can range check early.
  if (start < 0 || this.length < start || this.length < end) {
    throw new RangeError('Out of range index')
  }

  if (end <= start) {
    return this
  }

  start = start >>> 0
  end = end === undefined ? this.length : end >>> 0

  if (!val) val = 0

  var i
  if (typeof val === 'number') {
    for (i = start; i < end; ++i) {
      this[i] = val
    }
  } else {
    var bytes = Buffer.isBuffer(val)
      ? val
      : Buffer.from(val, encoding)
    var len = bytes.length
    if (len === 0) {
      throw new TypeError('The value "' + val +
        '" is invalid for argument "value"')
    }
    for (i = 0; i < end - start; ++i) {
      this[i + start] = bytes[i % len]
    }
  }

  return this
}

// HELPER FUNCTIONS
// ================

var INVALID_BASE64_RE = /[^+/0-9A-Za-z-_]/g

function base64clean (str) {
  // Node takes equal signs as end of the Base64 encoding
  str = str.split('=')[0]
  // Node strips out invalid characters like \n and \t from the string, base64-js does not
  str = str.trim().replace(INVALID_BASE64_RE, '')
  // Node converts strings with length < 2 to ''
  if (str.length < 2) return ''
  // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not
  while (str.length % 4 !== 0) {
    str = str + '='
  }
  return str
}

function toHex (n) {
  if (n < 16) return '0' + n.toString(16)
  return n.toString(16)
}

function utf8ToBytes (string, units) {
  units = units || Infinity
  var codePoint
  var length = string.length
  var leadSurrogate = null
  var bytes = []

  for (var i = 0; i < length; ++i) {
    codePoint = string.charCodeAt(i)

    // is surrogate component
    if (codePoint > 0xD7FF && codePoint < 0xE000) {
      // last char was a lead
      if (!leadSurrogate) {
        // no lead yet
        if (codePoint > 0xDBFF) {
          // unexpected trail
          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
          continue
        } else if (i + 1 === length) {
          // unpaired lead
          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
          continue
        }

        // valid lead
        leadSurrogate = codePoint

        continue
      }

      // 2 leads in a row
      if (codePoint < 0xDC00) {
        if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
        leadSurrogate = codePoint
        continue
      }

      // valid surrogate pair
      codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000
    } else if (leadSurrogate) {
      // valid bmp char, but last char was a lead
      if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
    }

    leadSurrogate = null

    // encode utf8
    if (codePoint < 0x80) {
      if ((units -= 1) < 0) break
      bytes.push(codePoint)
    } else if (codePoint < 0x800) {
      if ((units -= 2) < 0) break
      bytes.push(
        codePoint >> 0x6 | 0xC0,
        codePoint & 0x3F | 0x80
      )
    } else if (codePoint < 0x10000) {
      if ((units -= 3) < 0) break
      bytes.push(
        codePoint >> 0xC | 0xE0,
        codePoint >> 0x6 & 0x3F | 0x80,
        codePoint & 0x3F | 0x80
      )
    } else if (codePoint < 0x110000) {
      if ((units -= 4) < 0) break
      bytes.push(
        codePoint >> 0x12 | 0xF0,
        codePoint >> 0xC & 0x3F | 0x80,
        codePoint >> 0x6 & 0x3F | 0x80,
        codePoint & 0x3F | 0x80
      )
    } else {
      throw new Error('Invalid code point')
    }
  }

  return bytes
}

function asciiToBytes (str) {
  var byteArray = []
  for (var i = 0; i < str.length; ++i) {
    // Node's code seems to be doing this and not & 0x7F..
    byteArray.push(str.charCodeAt(i) & 0xFF)
  }
  return byteArray
}

function utf16leToBytes (str, units) {
  var c, hi, lo
  var byteArray = []
  for (var i = 0; i < str.length; ++i) {
    if ((units -= 2) < 0) break

    c = str.charCodeAt(i)
    hi = c >> 8
    lo = c % 256
    byteArray.push(lo)
    byteArray.push(hi)
  }

  return byteArray
}

function base64ToBytes (str) {
  return base64.toByteArray(base64clean(str))
}

function blitBuffer (src, dst, offset, length) {
  for (var i = 0; i < length; ++i) {
    if ((i + offset >= dst.length) || (i >= src.length)) break
    dst[i + offset] = src[i]
  }
  return i
}

// ArrayBuffer or Uint8Array objects from other contexts (i.e. iframes) do not pass
// the `instanceof` check but they should be treated as of that type.
// See: https://github.com/feross/buffer/issues/166
function isInstance (obj, type) {
  return obj instanceof type ||
    (obj != null && obj.constructor != null && obj.constructor.name != null &&
      obj.constructor.name === type.name)
}
function numberIsNaN (obj) {
  // For IE11 support
  return obj !== obj // eslint-disable-line no-self-compare
}

}).call(this)}).call(this,require("buffer").Buffer)

},{"base64-js":18,"buffer":19,"ieee754":47}],20:[function(require,module,exports){
'use strict';

var bind = require('function-bind');
var $apply = require('./functionApply');
var $call = require('./functionCall');
var $reflectApply = require('./reflectApply');

/** @type {import('./actualApply')} */
module.exports = $reflectApply || bind.call($call, $apply);

},{"./functionApply":21,"./functionCall":22,"./reflectApply":24,"function-bind":37}],21:[function(require,module,exports){
'use strict';

/** @type {import('./functionApply')} */
module.exports = Function.prototype.apply;

},{}],22:[function(require,module,exports){
'use strict';

/** @type {import('./functionCall')} */
module.exports = Function.prototype.call;

},{}],23:[function(require,module,exports){
'use strict';

var bind = require('function-bind');
var $TypeError = require('es-errors/type');
var $call = require('./functionCall');
var $actualApply = require('./actualApply');

/** @type {import('.')} */
module.exports = function callBindBasic(args) {
  if (args.length < 1 || typeof args[0] !== 'function') {
    throw new $TypeError('a function is required');
  }
  return $actualApply(bind, $call, args);
};

},{"./actualApply":20,"./functionCall":22,"es-errors/type":33,"function-bind":37}],24:[function(require,module,exports){
'use strict';

/** @type {import('./reflectApply')} */
module.exports = typeof Reflect !== 'undefined' && Reflect && Reflect.apply;

},{}],25:[function(require,module,exports){
'use strict';

var GetIntrinsic = require('get-intrinsic');
var callBindBasic = require('call-bind-apply-helpers');

/** @type {(thisArg: string, searchString: string, position?: number) => number} */
var $indexOf = callBindBasic([GetIntrinsic('%String.prototype.indexOf%')]);

/** @type {import('.')} */
module.exports = function callBoundIntrinsic(name, allowMissing) {
  // eslint-disable-next-line no-extra-parens
  var intrinsic = /** @type {Parameters<typeof callBindBasic>[0][0]} */GetIntrinsic(name, !!allowMissing);
  if (typeof intrinsic === 'function' && $indexOf(name, '.prototype.') > -1) {
    return callBindBasic([intrinsic]);
  }
  return intrinsic;
};

},{"call-bind-apply-helpers":23,"get-intrinsic":38}],26:[function(require,module,exports){
'use strict';

var callBind = require('call-bind-apply-helpers');
var gOPD = require('gopd');
var hasProtoAccessor;
try {
  // eslint-disable-next-line no-extra-parens, no-proto
  hasProtoAccessor = /** @type {{ __proto__?: typeof Array.prototype }} */[].__proto__ === Array.prototype;
} catch (e) {
  if (!e || typeof e !== 'object' || !('code' in e) || e.code !== 'ERR_PROTO_ACCESS') {
    throw e;
  }
}

// eslint-disable-next-line no-extra-parens
var desc = !!hasProtoAccessor && gOPD && gOPD(Object.prototype, /** @type {keyof typeof Object.prototype} */'__proto__');
var $Object = Object;
var $getPrototypeOf = $Object.getPrototypeOf;

/** @type {import('./get')} */
module.exports = desc && typeof desc.get === 'function' ? callBind([desc.get]) : typeof $getPrototypeOf === 'function' ? /** @type {import('./get')} */function getDunder(value) {
  // eslint-disable-next-line eqeqeq
  return $getPrototypeOf(value == null ? value : $Object(value));
} : false;

},{"call-bind-apply-helpers":23,"gopd":43}],27:[function(require,module,exports){
'use strict';

/** @type {import('.')} */
var $defineProperty = Object.defineProperty || false;
if ($defineProperty) {
  try {
    $defineProperty({}, 'a', {
      value: 1
    });
  } catch (e) {
    // IE 8 has a broken defineProperty
    $defineProperty = false;
  }
}
module.exports = $defineProperty;

},{}],28:[function(require,module,exports){
'use strict';

/** @type {import('./eval')} */
module.exports = EvalError;

},{}],29:[function(require,module,exports){
'use strict';

/** @type {import('.')} */
module.exports = Error;

},{}],30:[function(require,module,exports){
'use strict';

/** @type {import('./range')} */
module.exports = RangeError;

},{}],31:[function(require,module,exports){
'use strict';

/** @type {import('./ref')} */
module.exports = ReferenceError;

},{}],32:[function(require,module,exports){
'use strict';

/** @type {import('./syntax')} */
module.exports = SyntaxError;

},{}],33:[function(require,module,exports){
'use strict';

/** @type {import('./type')} */
module.exports = TypeError;

},{}],34:[function(require,module,exports){
'use strict';

/** @type {import('./uri')} */
module.exports = URIError;

},{}],35:[function(require,module,exports){
'use strict';

/** @type {import('.')} */
module.exports = Object;

},{}],36:[function(require,module,exports){
'use strict';

/* eslint no-invalid-this: 1 */

var ERROR_MESSAGE = 'Function.prototype.bind called on incompatible ';
var toStr = Object.prototype.toString;
var max = Math.max;
var funcType = '[object Function]';

var concatty = function concatty(a, b) {
    var arr = [];

    for (var i = 0; i < a.length; i += 1) {
        arr[i] = a[i];
    }
    for (var j = 0; j < b.length; j += 1) {
        arr[j + a.length] = b[j];
    }

    return arr;
};

var slicy = function slicy(arrLike, offset) {
    var arr = [];
    for (var i = offset || 0, j = 0; i < arrLike.length; i += 1, j += 1) {
        arr[j] = arrLike[i];
    }
    return arr;
};

var joiny = function (arr, joiner) {
    var str = '';
    for (var i = 0; i < arr.length; i += 1) {
        str += arr[i];
        if (i + 1 < arr.length) {
            str += joiner;
        }
    }
    return str;
};

module.exports = function bind(that) {
    var target = this;
    if (typeof target !== 'function' || toStr.apply(target) !== funcType) {
        throw new TypeError(ERROR_MESSAGE + target);
    }
    var args = slicy(arguments, 1);

    var bound;
    var binder = function () {
        if (this instanceof bound) {
            var result = target.apply(
                this,
                concatty(args, arguments)
            );
            if (Object(result) === result) {
                return result;
            }
            return this;
        }
        return target.apply(
            that,
            concatty(args, arguments)
        );

    };

    var boundLength = max(0, target.length - args.length);
    var boundArgs = [];
    for (var i = 0; i < boundLength; i++) {
        boundArgs[i] = '$' + i;
    }

    bound = Function('binder', 'return function (' + joiny(boundArgs, ',') + '){ return binder.apply(this,arguments); }')(binder);

    if (target.prototype) {
        var Empty = function Empty() {};
        Empty.prototype = target.prototype;
        bound.prototype = new Empty();
        Empty.prototype = null;
    }

    return bound;
};

},{}],37:[function(require,module,exports){
'use strict';

var implementation = require('./implementation');

module.exports = Function.prototype.bind || implementation;

},{"./implementation":36}],38:[function(require,module,exports){
'use strict';

var undefined;

var $Object = require('es-object-atoms');

var $Error = require('es-errors');
var $EvalError = require('es-errors/eval');
var $RangeError = require('es-errors/range');
var $ReferenceError = require('es-errors/ref');
var $SyntaxError = require('es-errors/syntax');
var $TypeError = require('es-errors/type');
var $URIError = require('es-errors/uri');

var abs = require('math-intrinsics/abs');
var floor = require('math-intrinsics/floor');
var max = require('math-intrinsics/max');
var min = require('math-intrinsics/min');
var pow = require('math-intrinsics/pow');
var round = require('math-intrinsics/round');
var sign = require('math-intrinsics/sign');

var $Function = Function;

// eslint-disable-next-line consistent-return
var getEvalledConstructor = function (expressionSyntax) {
	try {
		return $Function('"use strict"; return (' + expressionSyntax + ').constructor;')();
	} catch (e) {}
};

var $gOPD = require('gopd');
var $defineProperty = require('es-define-property');

var throwTypeError = function () {
	throw new $TypeError();
};
var ThrowTypeError = $gOPD
	? (function () {
		try {
			// eslint-disable-next-line no-unused-expressions, no-caller, no-restricted-properties
			arguments.callee; // IE 8 does not throw here
			return throwTypeError;
		} catch (calleeThrows) {
			try {
				// IE 8 throws on Object.getOwnPropertyDescriptor(arguments, '')
				return $gOPD(arguments, 'callee').get;
			} catch (gOPDthrows) {
				return throwTypeError;
			}
		}
	}())
	: throwTypeError;

var hasSymbols = require('has-symbols')();

var getProto = require('get-proto');
var $ObjectGPO = require('get-proto/Object.getPrototypeOf');
var $ReflectGPO = require('get-proto/Reflect.getPrototypeOf');

var $apply = require('call-bind-apply-helpers/functionApply');
var $call = require('call-bind-apply-helpers/functionCall');

var needsEval = {};

var TypedArray = typeof Uint8Array === 'undefined' || !getProto ? undefined : getProto(Uint8Array);

var INTRINSICS = {
	__proto__: null,
	'%AggregateError%': typeof AggregateError === 'undefined' ? undefined : AggregateError,
	'%Array%': Array,
	'%ArrayBuffer%': typeof ArrayBuffer === 'undefined' ? undefined : ArrayBuffer,
	'%ArrayIteratorPrototype%': hasSymbols && getProto ? getProto([][Symbol.iterator]()) : undefined,
	'%AsyncFromSyncIteratorPrototype%': undefined,
	'%AsyncFunction%': needsEval,
	'%AsyncGenerator%': needsEval,
	'%AsyncGeneratorFunction%': needsEval,
	'%AsyncIteratorPrototype%': needsEval,
	'%Atomics%': typeof Atomics === 'undefined' ? undefined : Atomics,
	'%BigInt%': typeof BigInt === 'undefined' ? undefined : BigInt,
	'%BigInt64Array%': typeof BigInt64Array === 'undefined' ? undefined : BigInt64Array,
	'%BigUint64Array%': typeof BigUint64Array === 'undefined' ? undefined : BigUint64Array,
	'%Boolean%': Boolean,
	'%DataView%': typeof DataView === 'undefined' ? undefined : DataView,
	'%Date%': Date,
	'%decodeURI%': decodeURI,
	'%decodeURIComponent%': decodeURIComponent,
	'%encodeURI%': encodeURI,
	'%encodeURIComponent%': encodeURIComponent,
	'%Error%': $Error,
	'%eval%': eval, // eslint-disable-line no-eval
	'%EvalError%': $EvalError,
	'%Float32Array%': typeof Float32Array === 'undefined' ? undefined : Float32Array,
	'%Float64Array%': typeof Float64Array === 'undefined' ? undefined : Float64Array,
	'%FinalizationRegistry%': typeof FinalizationRegistry === 'undefined' ? undefined : FinalizationRegistry,
	'%Function%': $Function,
	'%GeneratorFunction%': needsEval,
	'%Int8Array%': typeof Int8Array === 'undefined' ? undefined : Int8Array,
	'%Int16Array%': typeof Int16Array === 'undefined' ? undefined : Int16Array,
	'%Int32Array%': typeof Int32Array === 'undefined' ? undefined : Int32Array,
	'%isFinite%': isFinite,
	'%isNaN%': isNaN,
	'%IteratorPrototype%': hasSymbols && getProto ? getProto(getProto([][Symbol.iterator]())) : undefined,
	'%JSON%': typeof JSON === 'object' ? JSON : undefined,
	'%Map%': typeof Map === 'undefined' ? undefined : Map,
	'%MapIteratorPrototype%': typeof Map === 'undefined' || !hasSymbols || !getProto ? undefined : getProto(new Map()[Symbol.iterator]()),
	'%Math%': Math,
	'%Number%': Number,
	'%Object%': $Object,
	'%Object.getOwnPropertyDescriptor%': $gOPD,
	'%parseFloat%': parseFloat,
	'%parseInt%': parseInt,
	'%Promise%': typeof Promise === 'undefined' ? undefined : Promise,
	'%Proxy%': typeof Proxy === 'undefined' ? undefined : Proxy,
	'%RangeError%': $RangeError,
	'%ReferenceError%': $ReferenceError,
	'%Reflect%': typeof Reflect === 'undefined' ? undefined : Reflect,
	'%RegExp%': RegExp,
	'%Set%': typeof Set === 'undefined' ? undefined : Set,
	'%SetIteratorPrototype%': typeof Set === 'undefined' || !hasSymbols || !getProto ? undefined : getProto(new Set()[Symbol.iterator]()),
	'%SharedArrayBuffer%': typeof SharedArrayBuffer === 'undefined' ? undefined : SharedArrayBuffer,
	'%String%': String,
	'%StringIteratorPrototype%': hasSymbols && getProto ? getProto(''[Symbol.iterator]()) : undefined,
	'%Symbol%': hasSymbols ? Symbol : undefined,
	'%SyntaxError%': $SyntaxError,
	'%ThrowTypeError%': ThrowTypeError,
	'%TypedArray%': TypedArray,
	'%TypeError%': $TypeError,
	'%Uint8Array%': typeof Uint8Array === 'undefined' ? undefined : Uint8Array,
	'%Uint8ClampedArray%': typeof Uint8ClampedArray === 'undefined' ? undefined : Uint8ClampedArray,
	'%Uint16Array%': typeof Uint16Array === 'undefined' ? undefined : Uint16Array,
	'%Uint32Array%': typeof Uint32Array === 'undefined' ? undefined : Uint32Array,
	'%URIError%': $URIError,
	'%WeakMap%': typeof WeakMap === 'undefined' ? undefined : WeakMap,
	'%WeakRef%': typeof WeakRef === 'undefined' ? undefined : WeakRef,
	'%WeakSet%': typeof WeakSet === 'undefined' ? undefined : WeakSet,

	'%Function.prototype.call%': $call,
	'%Function.prototype.apply%': $apply,
	'%Object.defineProperty%': $defineProperty,
	'%Object.getPrototypeOf%': $ObjectGPO,
	'%Math.abs%': abs,
	'%Math.floor%': floor,
	'%Math.max%': max,
	'%Math.min%': min,
	'%Math.pow%': pow,
	'%Math.round%': round,
	'%Math.sign%': sign,
	'%Reflect.getPrototypeOf%': $ReflectGPO
};

if (getProto) {
	try {
		null.error; // eslint-disable-line no-unused-expressions
	} catch (e) {
		// https://github.com/tc39/proposal-shadowrealm/pull/384#issuecomment-1364264229
		var errorProto = getProto(getProto(e));
		INTRINSICS['%Error.prototype%'] = errorProto;
	}
}

var doEval = function doEval(name) {
	var value;
	if (name === '%AsyncFunction%') {
		value = getEvalledConstructor('async function () {}');
	} else if (name === '%GeneratorFunction%') {
		value = getEvalledConstructor('function* () {}');
	} else if (name === '%AsyncGeneratorFunction%') {
		value = getEvalledConstructor('async function* () {}');
	} else if (name === '%AsyncGenerator%') {
		var fn = doEval('%AsyncGeneratorFunction%');
		if (fn) {
			value = fn.prototype;
		}
	} else if (name === '%AsyncIteratorPrototype%') {
		var gen = doEval('%AsyncGenerator%');
		if (gen && getProto) {
			value = getProto(gen.prototype);
		}
	}

	INTRINSICS[name] = value;

	return value;
};

var LEGACY_ALIASES = {
	__proto__: null,
	'%ArrayBufferPrototype%': ['ArrayBuffer', 'prototype'],
	'%ArrayPrototype%': ['Array', 'prototype'],
	'%ArrayProto_entries%': ['Array', 'prototype', 'entries'],
	'%ArrayProto_forEach%': ['Array', 'prototype', 'forEach'],
	'%ArrayProto_keys%': ['Array', 'prototype', 'keys'],
	'%ArrayProto_values%': ['Array', 'prototype', 'values'],
	'%AsyncFunctionPrototype%': ['AsyncFunction', 'prototype'],
	'%AsyncGenerator%': ['AsyncGeneratorFunction', 'prototype'],
	'%AsyncGeneratorPrototype%': ['AsyncGeneratorFunction', 'prototype', 'prototype'],
	'%BooleanPrototype%': ['Boolean', 'prototype'],
	'%DataViewPrototype%': ['DataView', 'prototype'],
	'%DatePrototype%': ['Date', 'prototype'],
	'%ErrorPrototype%': ['Error', 'prototype'],
	'%EvalErrorPrototype%': ['EvalError', 'prototype'],
	'%Float32ArrayPrototype%': ['Float32Array', 'prototype'],
	'%Float64ArrayPrototype%': ['Float64Array', 'prototype'],
	'%FunctionPrototype%': ['Function', 'prototype'],
	'%Generator%': ['GeneratorFunction', 'prototype'],
	'%GeneratorPrototype%': ['GeneratorFunction', 'prototype', 'prototype'],
	'%Int8ArrayPrototype%': ['Int8Array', 'prototype'],
	'%Int16ArrayPrototype%': ['Int16Array', 'prototype'],
	'%Int32ArrayPrototype%': ['Int32Array', 'prototype'],
	'%JSONParse%': ['JSON', 'parse'],
	'%JSONStringify%': ['JSON', 'stringify'],
	'%MapPrototype%': ['Map', 'prototype'],
	'%NumberPrototype%': ['Number', 'prototype'],
	'%ObjectPrototype%': ['Object', 'prototype'],
	'%ObjProto_toString%': ['Object', 'prototype', 'toString'],
	'%ObjProto_valueOf%': ['Object', 'prototype', 'valueOf'],
	'%PromisePrototype%': ['Promise', 'prototype'],
	'%PromiseProto_then%': ['Promise', 'prototype', 'then'],
	'%Promise_all%': ['Promise', 'all'],
	'%Promise_reject%': ['Promise', 'reject'],
	'%Promise_resolve%': ['Promise', 'resolve'],
	'%RangeErrorPrototype%': ['RangeError', 'prototype'],
	'%ReferenceErrorPrototype%': ['ReferenceError', 'prototype'],
	'%RegExpPrototype%': ['RegExp', 'prototype'],
	'%SetPrototype%': ['Set', 'prototype'],
	'%SharedArrayBufferPrototype%': ['SharedArrayBuffer', 'prototype'],
	'%StringPrototype%': ['String', 'prototype'],
	'%SymbolPrototype%': ['Symbol', 'prototype'],
	'%SyntaxErrorPrototype%': ['SyntaxError', 'prototype'],
	'%TypedArrayPrototype%': ['TypedArray', 'prototype'],
	'%TypeErrorPrototype%': ['TypeError', 'prototype'],
	'%Uint8ArrayPrototype%': ['Uint8Array', 'prototype'],
	'%Uint8ClampedArrayPrototype%': ['Uint8ClampedArray', 'prototype'],
	'%Uint16ArrayPrototype%': ['Uint16Array', 'prototype'],
	'%Uint32ArrayPrototype%': ['Uint32Array', 'prototype'],
	'%URIErrorPrototype%': ['URIError', 'prototype'],
	'%WeakMapPrototype%': ['WeakMap', 'prototype'],
	'%WeakSetPrototype%': ['WeakSet', 'prototype']
};

var bind = require('function-bind');
var hasOwn = require('hasown');
var $concat = bind.call($call, Array.prototype.concat);
var $spliceApply = bind.call($apply, Array.prototype.splice);
var $replace = bind.call($call, String.prototype.replace);
var $strSlice = bind.call($call, String.prototype.slice);
var $exec = bind.call($call, RegExp.prototype.exec);

/* adapted from https://github.com/lodash/lodash/blob/4.17.15/dist/lodash.js#L6735-L6744 */
var rePropName = /[^%.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|%$))/g;
var reEscapeChar = /\\(\\)?/g; /** Used to match backslashes in property paths. */
var stringToPath = function stringToPath(string) {
	var first = $strSlice(string, 0, 1);
	var last = $strSlice(string, -1);
	if (first === '%' && last !== '%') {
		throw new $SyntaxError('invalid intrinsic syntax, expected closing `%`');
	} else if (last === '%' && first !== '%') {
		throw new $SyntaxError('invalid intrinsic syntax, expected opening `%`');
	}
	var result = [];
	$replace(string, rePropName, function (match, number, quote, subString) {
		result[result.length] = quote ? $replace(subString, reEscapeChar, '$1') : number || match;
	});
	return result;
};
/* end adaptation */

var getBaseIntrinsic = function getBaseIntrinsic(name, allowMissing) {
	var intrinsicName = name;
	var alias;
	if (hasOwn(LEGACY_ALIASES, intrinsicName)) {
		alias = LEGACY_ALIASES[intrinsicName];
		intrinsicName = '%' + alias[0] + '%';
	}

	if (hasOwn(INTRINSICS, intrinsicName)) {
		var value = INTRINSICS[intrinsicName];
		if (value === needsEval) {
			value = doEval(intrinsicName);
		}
		if (typeof value === 'undefined' && !allowMissing) {
			throw new $TypeError('intrinsic ' + name + ' exists, but is not available. Please file an issue!');
		}

		return {
			alias: alias,
			name: intrinsicName,
			value: value
		};
	}

	throw new $SyntaxError('intrinsic ' + name + ' does not exist!');
};

module.exports = function GetIntrinsic(name, allowMissing) {
	if (typeof name !== 'string' || name.length === 0) {
		throw new $TypeError('intrinsic name must be a non-empty string');
	}
	if (arguments.length > 1 && typeof allowMissing !== 'boolean') {
		throw new $TypeError('"allowMissing" argument must be a boolean');
	}

	if ($exec(/^%?[^%]*%?$/, name) === null) {
		throw new $SyntaxError('`%` may not be present anywhere but at the beginning and end of the intrinsic name');
	}
	var parts = stringToPath(name);
	var intrinsicBaseName = parts.length > 0 ? parts[0] : '';

	var intrinsic = getBaseIntrinsic('%' + intrinsicBaseName + '%', allowMissing);
	var intrinsicRealName = intrinsic.name;
	var value = intrinsic.value;
	var skipFurtherCaching = false;

	var alias = intrinsic.alias;
	if (alias) {
		intrinsicBaseName = alias[0];
		$spliceApply(parts, $concat([0, 1], alias));
	}

	for (var i = 1, isOwn = true; i < parts.length; i += 1) {
		var part = parts[i];
		var first = $strSlice(part, 0, 1);
		var last = $strSlice(part, -1);
		if (
			(
				(first === '"' || first === "'" || first === '`')
				|| (last === '"' || last === "'" || last === '`')
			)
			&& first !== last
		) {
			throw new $SyntaxError('property names with quotes must have matching quotes');
		}
		if (part === 'constructor' || !isOwn) {
			skipFurtherCaching = true;
		}

		intrinsicBaseName += '.' + part;
		intrinsicRealName = '%' + intrinsicBaseName + '%';

		if (hasOwn(INTRINSICS, intrinsicRealName)) {
			value = INTRINSICS[intrinsicRealName];
		} else if (value != null) {
			if (!(part in value)) {
				if (!allowMissing) {
					throw new $TypeError('base intrinsic for ' + name + ' exists, but the property is not available.');
				}
				return void undefined;
			}
			if ($gOPD && (i + 1) >= parts.length) {
				var desc = $gOPD(value, part);
				isOwn = !!desc;

				// By convention, when a data property is converted to an accessor
				// property to emulate a data property that does not suffer from
				// the override mistake, that accessor's getter is marked with
				// an `originalValue` property. Here, when we detect this, we
				// uphold the illusion by pretending to see that original data
				// property, i.e., returning the value rather than the getter
				// itself.
				if (isOwn && 'get' in desc && !('originalValue' in desc.get)) {
					value = desc.get;
				} else {
					value = value[part];
				}
			} else {
				isOwn = hasOwn(value, part);
				value = value[part];
			}

			if (isOwn && !skipFurtherCaching) {
				INTRINSICS[intrinsicRealName] = value;
			}
		}
	}
	return value;
};

},{"call-bind-apply-helpers/functionApply":21,"call-bind-apply-helpers/functionCall":22,"es-define-property":27,"es-errors":29,"es-errors/eval":28,"es-errors/range":30,"es-errors/ref":31,"es-errors/syntax":32,"es-errors/type":33,"es-errors/uri":34,"es-object-atoms":35,"function-bind":37,"get-proto":41,"get-proto/Object.getPrototypeOf":39,"get-proto/Reflect.getPrototypeOf":40,"gopd":43,"has-symbols":44,"hasown":46,"math-intrinsics/abs":48,"math-intrinsics/floor":49,"math-intrinsics/max":51,"math-intrinsics/min":52,"math-intrinsics/pow":53,"math-intrinsics/round":54,"math-intrinsics/sign":55}],39:[function(require,module,exports){
'use strict';

var $Object = require('es-object-atoms');

/** @type {import('./Object.getPrototypeOf')} */
module.exports = $Object.getPrototypeOf || null;

},{"es-object-atoms":35}],40:[function(require,module,exports){
'use strict';

/** @type {import('./Reflect.getPrototypeOf')} */
module.exports = typeof Reflect !== 'undefined' && Reflect.getPrototypeOf || null;

},{}],41:[function(require,module,exports){
'use strict';

var reflectGetProto = require('./Reflect.getPrototypeOf');
var originalGetProto = require('./Object.getPrototypeOf');
var getDunderProto = require('dunder-proto/get');

/** @type {import('.')} */
module.exports = reflectGetProto ? function getProto(O) {
  // @ts-expect-error TS can't narrow inside a closure, for some reason
  return reflectGetProto(O);
} : originalGetProto ? function getProto(O) {
  if (!O || typeof O !== 'object' && typeof O !== 'function') {
    throw new TypeError('getProto: not an object');
  }
  // @ts-expect-error TS can't narrow inside a closure, for some reason
  return originalGetProto(O);
} : getDunderProto ? function getProto(O) {
  // @ts-expect-error TS can't narrow inside a closure, for some reason
  return getDunderProto(O);
} : null;

},{"./Object.getPrototypeOf":39,"./Reflect.getPrototypeOf":40,"dunder-proto/get":26}],42:[function(require,module,exports){
'use strict';

/** @type {import('./gOPD')} */
module.exports = Object.getOwnPropertyDescriptor;

},{}],43:[function(require,module,exports){
'use strict';

/** @type {import('.')} */
var $gOPD = require('./gOPD');
if ($gOPD) {
  try {
    $gOPD([], 'length');
  } catch (e) {
    // IE 8 has a broken gOPD
    $gOPD = null;
  }
}
module.exports = $gOPD;

},{"./gOPD":42}],44:[function(require,module,exports){
'use strict';

var origSymbol = typeof Symbol !== 'undefined' && Symbol;
var hasSymbolSham = require('./shams');

/** @type {import('.')} */
module.exports = function hasNativeSymbols() {
  if (typeof origSymbol !== 'function') {
    return false;
  }
  if (typeof Symbol !== 'function') {
    return false;
  }
  if (typeof origSymbol('foo') !== 'symbol') {
    return false;
  }
  if (typeof Symbol('bar') !== 'symbol') {
    return false;
  }
  return hasSymbolSham();
};

},{"./shams":45}],45:[function(require,module,exports){
'use strict';

/** @type {import('./shams')} */
/* eslint complexity: [2, 18], max-statements: [2, 33] */
module.exports = function hasSymbols() {
  if (typeof Symbol !== 'function' || typeof Object.getOwnPropertySymbols !== 'function') {
    return false;
  }
  if (typeof Symbol.iterator === 'symbol') {
    return true;
  }

  /** @type {{ [k in symbol]?: unknown }} */
  var obj = {};
  var sym = Symbol('test');
  var symObj = Object(sym);
  if (typeof sym === 'string') {
    return false;
  }
  if (Object.prototype.toString.call(sym) !== '[object Symbol]') {
    return false;
  }
  if (Object.prototype.toString.call(symObj) !== '[object Symbol]') {
    return false;
  }

  // temp disabled per https://github.com/ljharb/object.assign/issues/17
  // if (sym instanceof Symbol) { return false; }
  // temp disabled per https://github.com/WebReflection/get-own-property-symbols/issues/4
  // if (!(symObj instanceof Symbol)) { return false; }

  // if (typeof Symbol.prototype.toString !== 'function') { return false; }
  // if (String(sym) !== Symbol.prototype.toString.call(sym)) { return false; }

  var symVal = 42;
  obj[sym] = symVal;
  for (var _ in obj) {
    return false;
  } // eslint-disable-line no-restricted-syntax, no-unreachable-loop
  if (typeof Object.keys === 'function' && Object.keys(obj).length !== 0) {
    return false;
  }
  if (typeof Object.getOwnPropertyNames === 'function' && Object.getOwnPropertyNames(obj).length !== 0) {
    return false;
  }
  var syms = Object.getOwnPropertySymbols(obj);
  if (syms.length !== 1 || syms[0] !== sym) {
    return false;
  }
  if (!Object.prototype.propertyIsEnumerable.call(obj, sym)) {
    return false;
  }
  if (typeof Object.getOwnPropertyDescriptor === 'function') {
    // eslint-disable-next-line no-extra-parens
    var descriptor = /** @type {PropertyDescriptor} */Object.getOwnPropertyDescriptor(obj, sym);
    if (descriptor.value !== symVal || descriptor.enumerable !== true) {
      return false;
    }
  }
  return true;
};

},{}],46:[function(require,module,exports){
'use strict';

var call = Function.prototype.call;
var $hasOwn = Object.prototype.hasOwnProperty;
var bind = require('function-bind');

/** @type {import('.')} */
module.exports = bind.call(call, $hasOwn);

},{"function-bind":37}],47:[function(require,module,exports){
/*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh <https://feross.org/opensource> */
exports.read = function (buffer, offset, isLE, mLen, nBytes) {
  var e, m
  var eLen = (nBytes * 8) - mLen - 1
  var eMax = (1 << eLen) - 1
  var eBias = eMax >> 1
  var nBits = -7
  var i = isLE ? (nBytes - 1) : 0
  var d = isLE ? -1 : 1
  var s = buffer[offset + i]

  i += d

  e = s & ((1 << (-nBits)) - 1)
  s >>= (-nBits)
  nBits += eLen
  for (; nBits > 0; e = (e * 256) + buffer[offset + i], i += d, nBits -= 8) {}

  m = e & ((1 << (-nBits)) - 1)
  e >>= (-nBits)
  nBits += mLen
  for (; nBits > 0; m = (m * 256) + buffer[offset + i], i += d, nBits -= 8) {}

  if (e === 0) {
    e = 1 - eBias
  } else if (e === eMax) {
    return m ? NaN : ((s ? -1 : 1) * Infinity)
  } else {
    m = m + Math.pow(2, mLen)
    e = e - eBias
  }
  return (s ? -1 : 1) * m * Math.pow(2, e - mLen)
}

exports.write = function (buffer, value, offset, isLE, mLen, nBytes) {
  var e, m, c
  var eLen = (nBytes * 8) - mLen - 1
  var eMax = (1 << eLen) - 1
  var eBias = eMax >> 1
  var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)
  var i = isLE ? 0 : (nBytes - 1)
  var d = isLE ? 1 : -1
  var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0

  value = Math.abs(value)

  if (isNaN(value) || value === Infinity) {
    m = isNaN(value) ? 1 : 0
    e = eMax
  } else {
    e = Math.floor(Math.log(value) / Math.LN2)
    if (value * (c = Math.pow(2, -e)) < 1) {
      e--
      c *= 2
    }
    if (e + eBias >= 1) {
      value += rt / c
    } else {
      value += rt * Math.pow(2, 1 - eBias)
    }
    if (value * c >= 2) {
      e++
      c /= 2
    }

    if (e + eBias >= eMax) {
      m = 0
      e = eMax
    } else if (e + eBias >= 1) {
      m = ((value * c) - 1) * Math.pow(2, mLen)
      e = e + eBias
    } else {
      m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)
      e = 0
    }
  }

  for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}

  e = (e << mLen) | m
  eLen += mLen
  for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}

  buffer[offset + i - d] |= s * 128
}

},{}],48:[function(require,module,exports){
'use strict';

/** @type {import('./abs')} */
module.exports = Math.abs;

},{}],49:[function(require,module,exports){
'use strict';

/** @type {import('./floor')} */
module.exports = Math.floor;

},{}],50:[function(require,module,exports){
'use strict';

/** @type {import('./isNaN')} */
module.exports = Number.isNaN || function isNaN(a) {
  return a !== a;
};

},{}],51:[function(require,module,exports){
'use strict';

/** @type {import('./max')} */
module.exports = Math.max;

},{}],52:[function(require,module,exports){
'use strict';

/** @type {import('./min')} */
module.exports = Math.min;

},{}],53:[function(require,module,exports){
'use strict';

/** @type {import('./pow')} */
module.exports = Math.pow;

},{}],54:[function(require,module,exports){
'use strict';

/** @type {import('./round')} */
module.exports = Math.round;

},{}],55:[function(require,module,exports){
'use strict';

var $isNaN = require('./isNaN');

/** @type {import('./sign')} */
module.exports = function sign(number) {
  if ($isNaN(number) || number === 0) {
    return number;
  }
  return number < 0 ? -1 : +1;
};

},{"./isNaN":50}],56:[function(require,module,exports){
'use strict';

var keysShim;
if (!Object.keys) {
	// modified from https://github.com/es-shims/es5-shim
	var has = Object.prototype.hasOwnProperty;
	var toStr = Object.prototype.toString;
	var isArgs = require('./isArguments'); // eslint-disable-line global-require
	var isEnumerable = Object.prototype.propertyIsEnumerable;
	var hasDontEnumBug = !isEnumerable.call({ toString: null }, 'toString');
	var hasProtoEnumBug = isEnumerable.call(function () {}, 'prototype');
	var dontEnums = [
		'toString',
		'toLocaleString',
		'valueOf',
		'hasOwnProperty',
		'isPrototypeOf',
		'propertyIsEnumerable',
		'constructor'
	];
	var equalsConstructorPrototype = function (o) {
		var ctor = o.constructor;
		return ctor && ctor.prototype === o;
	};
	var excludedKeys = {
		$applicationCache: true,
		$console: true,
		$external: true,
		$frame: true,
		$frameElement: true,
		$frames: true,
		$innerHeight: true,
		$innerWidth: true,
		$onmozfullscreenchange: true,
		$onmozfullscreenerror: true,
		$outerHeight: true,
		$outerWidth: true,
		$pageXOffset: true,
		$pageYOffset: true,
		$parent: true,
		$scrollLeft: true,
		$scrollTop: true,
		$scrollX: true,
		$scrollY: true,
		$self: true,
		$webkitIndexedDB: true,
		$webkitStorageInfo: true,
		$window: true
	};
	var hasAutomationEqualityBug = (function () {
		/* global window */
		if (typeof window === 'undefined') { return false; }
		for (var k in window) {
			try {
				if (!excludedKeys['$' + k] && has.call(window, k) && window[k] !== null && typeof window[k] === 'object') {
					try {
						equalsConstructorPrototype(window[k]);
					} catch (e) {
						return true;
					}
				}
			} catch (e) {
				return true;
			}
		}
		return false;
	}());
	var equalsConstructorPrototypeIfNotBuggy = function (o) {
		/* global window */
		if (typeof window === 'undefined' || !hasAutomationEqualityBug) {
			return equalsConstructorPrototype(o);
		}
		try {
			return equalsConstructorPrototype(o);
		} catch (e) {
			return false;
		}
	};

	keysShim = function keys(object) {
		var isObject = object !== null && typeof object === 'object';
		var isFunction = toStr.call(object) === '[object Function]';
		var isArguments = isArgs(object);
		var isString = isObject && toStr.call(object) === '[object String]';
		var theKeys = [];

		if (!isObject && !isFunction && !isArguments) {
			throw new TypeError('Object.keys called on a non-object');
		}

		var skipProto = hasProtoEnumBug && isFunction;
		if (isString && object.length > 0 && !has.call(object, 0)) {
			for (var i = 0; i < object.length; ++i) {
				theKeys.push(String(i));
			}
		}

		if (isArguments && object.length > 0) {
			for (var j = 0; j < object.length; ++j) {
				theKeys.push(String(j));
			}
		} else {
			for (var name in object) {
				if (!(skipProto && name === 'prototype') && has.call(object, name)) {
					theKeys.push(String(name));
				}
			}
		}

		if (hasDontEnumBug) {
			var skipConstructor = equalsConstructorPrototypeIfNotBuggy(object);

			for (var k = 0; k < dontEnums.length; ++k) {
				if (!(skipConstructor && dontEnums[k] === 'constructor') && has.call(object, dontEnums[k])) {
					theKeys.push(dontEnums[k]);
				}
			}
		}
		return theKeys;
	};
}
module.exports = keysShim;

},{"./isArguments":58}],57:[function(require,module,exports){
'use strict';

var slice = Array.prototype.slice;
var isArgs = require('./isArguments');

var origKeys = Object.keys;
var keysShim = origKeys ? function keys(o) { return origKeys(o); } : require('./implementation');

var originalKeys = Object.keys;

keysShim.shim = function shimObjectKeys() {
	if (Object.keys) {
		var keysWorksWithArguments = (function () {
			// Safari 5.0 bug
			var args = Object.keys(arguments);
			return args && args.length === arguments.length;
		}(1, 2));
		if (!keysWorksWithArguments) {
			Object.keys = function keys(object) { // eslint-disable-line func-name-matching
				if (isArgs(object)) {
					return originalKeys(slice.call(object));
				}
				return originalKeys(object);
			};
		}
	} else {
		Object.keys = keysShim;
	}
	return Object.keys || keysShim;
};

module.exports = keysShim;

},{"./implementation":56,"./isArguments":58}],58:[function(require,module,exports){
'use strict';

var toStr = Object.prototype.toString;

module.exports = function isArguments(value) {
	var str = toStr.call(value);
	var isArgs = str === '[object Arguments]';
	if (!isArgs) {
		isArgs = str !== '[object Array]' &&
			value !== null &&
			typeof value === 'object' &&
			typeof value.length === 'number' &&
			value.length >= 0 &&
			toStr.call(value.callee) === '[object Function]';
	}
	return isArgs;
};

},{}],59:[function(require,module,exports){
'use strict';

// modified from https://github.com/es-shims/es6-shim
var objectKeys = require('object-keys');
var hasSymbols = require('has-symbols/shams')();
var callBound = require('call-bound');
var $Object = require('es-object-atoms');
var $push = callBound('Array.prototype.push');
var $propIsEnumerable = callBound('Object.prototype.propertyIsEnumerable');
var originalGetSymbols = hasSymbols ? $Object.getOwnPropertySymbols : null;

// eslint-disable-next-line no-unused-vars
module.exports = function assign(target, source1) {
	if (target == null) { throw new TypeError('target must be an object'); }
	var to = $Object(target); // step 1
	if (arguments.length === 1) {
		return to; // step 2
	}
	for (var s = 1; s < arguments.length; ++s) {
		var from = $Object(arguments[s]); // step 3.a.i

		// step 3.a.ii:
		var keys = objectKeys(from);
		var getSymbols = hasSymbols && ($Object.getOwnPropertySymbols || originalGetSymbols);
		if (getSymbols) {
			var syms = getSymbols(from);
			for (var j = 0; j < syms.length; ++j) {
				var key = syms[j];
				if ($propIsEnumerable(from, key)) {
					$push(keys, key);
				}
			}
		}

		// step 3.a.iii:
		for (var i = 0; i < keys.length; ++i) {
			var nextKey = keys[i];
			if ($propIsEnumerable(from, nextKey)) { // step 3.a.iii.2
				var propValue = from[nextKey]; // step 3.a.iii.2.a
				to[nextKey] = propValue; // step 3.a.iii.2.b
			}
		}
	}

	return to; // step 4
};

},{"call-bound":25,"es-object-atoms":35,"has-symbols/shams":45,"object-keys":57}],60:[function(require,module,exports){
'use strict';

var implementation = require('./implementation');

var lacksProperEnumerationOrder = function () {
	if (!Object.assign) {
		return false;
	}
	/*
	 * v8, specifically in node 4.x, has a bug with incorrect property enumeration order
	 * note: this does not detect the bug unless there's 20 characters
	 */
	var str = 'abcdefghijklmnopqrst';
	var letters = str.split('');
	var map = {};
	for (var i = 0; i < letters.length; ++i) {
		map[letters[i]] = letters[i];
	}
	var obj = Object.assign({}, map);
	var actual = '';
	for (var k in obj) {
		actual += k;
	}
	return str !== actual;
};

var assignHasPendingExceptions = function () {
	if (!Object.assign || !Object.preventExtensions) {
		return false;
	}
	/*
	 * Firefox 37 still has "pending exception" logic in its Object.assign implementation,
	 * which is 72% slower than our shim, and Firefox 40's native implementation.
	 */
	var thrower = Object.preventExtensions({ 1: 2 });
	try {
		Object.assign(thrower, 'xy');
	} catch (e) {
		return thrower[1] === 'y';
	}
	return false;
};

module.exports = function getPolyfill() {
	if (!Object.assign) {
		return implementation;
	}
	if (lacksProperEnumerationOrder()) {
		return implementation;
	}
	if (assignHasPendingExceptions()) {
		return implementation;
	}
	return Object.assign;
};

},{"./implementation":59}],61:[function(require,module,exports){
// shim for using process in browser
var process = module.exports = {};

// cached from whatever global is present so that test runners that stub it
// don't break things.  But we need to wrap it in a try catch in case it is
// wrapped in strict mode code which doesn't define any globals.  It's inside a
// function because try/catches deoptimize in certain engines.

var cachedSetTimeout;
var cachedClearTimeout;

function defaultSetTimout() {
    throw new Error('setTimeout has not been defined');
}
function defaultClearTimeout () {
    throw new Error('clearTimeout has not been defined');
}
(function () {
    try {
        if (typeof setTimeout === 'function') {
            cachedSetTimeout = setTimeout;
        } else {
            cachedSetTimeout = defaultSetTimout;
        }
    } catch (e) {
        cachedSetTimeout = defaultSetTimout;
    }
    try {
        if (typeof clearTimeout === 'function') {
            cachedClearTimeout = clearTimeout;
        } else {
            cachedClearTimeout = defaultClearTimeout;
        }
    } catch (e) {
        cachedClearTimeout = defaultClearTimeout;
    }
} ())
function runTimeout(fun) {
    if (cachedSetTimeout === setTimeout) {
        //normal enviroments in sane situations
        return setTimeout(fun, 0);
    }
    // if setTimeout wasn't available but was latter defined
    if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
        cachedSetTimeout = setTimeout;
        return setTimeout(fun, 0);
    }
    try {
        // when when somebody has screwed with setTimeout but no I.E. maddness
        return cachedSetTimeout(fun, 0);
    } catch(e){
        try {
            // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
            return cachedSetTimeout.call(null, fun, 0);
        } catch(e){
            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
            return cachedSetTimeout.call(this, fun, 0);
        }
    }


}
function runClearTimeout(marker) {
    if (cachedClearTimeout === clearTimeout) {
        //normal enviroments in sane situations
        return clearTimeout(marker);
    }
    // if clearTimeout wasn't available but was latter defined
    if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
        cachedClearTimeout = clearTimeout;
        return clearTimeout(marker);
    }
    try {
        // when when somebody has screwed with setTimeout but no I.E. maddness
        return cachedClearTimeout(marker);
    } catch (e){
        try {
            // When we are in I.E. but the script has been evaled so I.E. doesn't  trust the global object when called normally
            return cachedClearTimeout.call(null, marker);
        } catch (e){
            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
            // Some versions of I.E. have different rules for clearTimeout vs setTimeout
            return cachedClearTimeout.call(this, marker);
        }
    }



}
var queue = [];
var draining = false;
var currentQueue;
var queueIndex = -1;

function cleanUpNextTick() {
    if (!draining || !currentQueue) {
        return;
    }
    draining = false;
    if (currentQueue.length) {
        queue = currentQueue.concat(queue);
    } else {
        queueIndex = -1;
    }
    if (queue.length) {
        drainQueue();
    }
}

function drainQueue() {
    if (draining) {
        return;
    }
    var timeout = runTimeout(cleanUpNextTick);
    draining = true;

    var len = queue.length;
    while(len) {
        currentQueue = queue;
        queue = [];
        while (++queueIndex < len) {
            if (currentQueue) {
                currentQueue[queueIndex].run();
            }
        }
        queueIndex = -1;
        len = queue.length;
    }
    currentQueue = null;
    draining = false;
    runClearTimeout(timeout);
}

process.nextTick = function (fun) {
    var args = new Array(arguments.length - 1);
    if (arguments.length > 1) {
        for (var i = 1; i < arguments.length; i++) {
            args[i - 1] = arguments[i];
        }
    }
    queue.push(new Item(fun, args));
    if (queue.length === 1 && !draining) {
        runTimeout(drainQueue);
    }
};

// v8 likes predictible objects
function Item(fun, array) {
    this.fun = fun;
    this.array = array;
}
Item.prototype.run = function () {
    this.fun.apply(null, this.array);
};
process.title = 'browser';
process.browser = true;
process.env = {};
process.argv = [];
process.version = ''; // empty string to avoid regexp issues
process.versions = {};

function noop() {}

process.on = noop;
process.addListener = noop;
process.once = noop;
process.off = noop;
process.removeListener = noop;
process.removeAllListeners = noop;
process.emit = noop;
process.prependListener = noop;
process.prependOnceListener = noop;

process.listeners = function (name) { return [] }

process.binding = function (name) {
    throw new Error('process.binding is not supported');
};

process.cwd = function () { return '/' };
process.chdir = function (dir) {
    throw new Error('process.chdir is not supported');
};
process.umask = function() { return 0; };

},{}],62:[function(require,module,exports){
"use strict";
var __spreadArrays = (this && this.__spreadArrays) || function () {
    for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
    for (var r = Array(s), k = 0, i = 0; i < il; i++)
        for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
            r[k] = a[j];
    return r;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Checker = exports.createCheckers = void 0;
var types_1 = require("./types");
var util_1 = require("./util");
/**
 * Export functions used to define interfaces.
 */
var types_2 = require("./types");
Object.defineProperty(exports, "TArray", { enumerable: true, get: function () { return types_2.TArray; } });
Object.defineProperty(exports, "TEnumType", { enumerable: true, get: function () { return types_2.TEnumType; } });
Object.defineProperty(exports, "TEnumLiteral", { enumerable: true, get: function () { return types_2.TEnumLiteral; } });
Object.defineProperty(exports, "TFunc", { enumerable: true, get: function () { return types_2.TFunc; } });
Object.defineProperty(exports, "TIface", { enumerable: true, get: function () { return types_2.TIface; } });
Object.defineProperty(exports, "TLiteral", { enumerable: true, get: function () { return types_2.TLiteral; } });
Object.defineProperty(exports, "TName", { enumerable: true, get: function () { return types_2.TName; } });
Object.defineProperty(exports, "TOptional", { enumerable: true, get: function () { return types_2.TOptional; } });
Object.defineProperty(exports, "TParam", { enumerable: true, get: function () { return types_2.TParam; } });
Object.defineProperty(exports, "TParamList", { enumerable: true, get: function () { return types_2.TParamList; } });
Object.defineProperty(exports, "TProp", { enumerable: true, get: function () { return types_2.TProp; } });
Object.defineProperty(exports, "TTuple", { enumerable: true, get: function () { return types_2.TTuple; } });
Object.defineProperty(exports, "TType", { enumerable: true, get: function () { return types_2.TType; } });
Object.defineProperty(exports, "TUnion", { enumerable: true, get: function () { return types_2.TUnion; } });
Object.defineProperty(exports, "TIntersection", { enumerable: true, get: function () { return types_2.TIntersection; } });
Object.defineProperty(exports, "array", { enumerable: true, get: function () { return types_2.array; } });
Object.defineProperty(exports, "enumlit", { enumerable: true, get: function () { return types_2.enumlit; } });
Object.defineProperty(exports, "enumtype", { enumerable: true, get: function () { return types_2.enumtype; } });
Object.defineProperty(exports, "func", { enumerable: true, get: function () { return types_2.func; } });
Object.defineProperty(exports, "iface", { enumerable: true, get: function () { return types_2.iface; } });
Object.defineProperty(exports, "lit", { enumerable: true, get: function () { return types_2.lit; } });
Object.defineProperty(exports, "name", { enumerable: true, get: function () { return types_2.name; } });
Object.defineProperty(exports, "opt", { enumerable: true, get: function () { return types_2.opt; } });
Object.defineProperty(exports, "param", { enumerable: true, get: function () { return types_2.param; } });
Object.defineProperty(exports, "tuple", { enumerable: true, get: function () { return types_2.tuple; } });
Object.defineProperty(exports, "union", { enumerable: true, get: function () { return types_2.union; } });
Object.defineProperty(exports, "intersection", { enumerable: true, get: function () { return types_2.intersection; } });
Object.defineProperty(exports, "rest", { enumerable: true, get: function () { return types_2.rest; } });
Object.defineProperty(exports, "indexKey", { enumerable: true, get: function () { return types_2.indexKey; } });
Object.defineProperty(exports, "BasicType", { enumerable: true, get: function () { return types_2.BasicType; } });
var util_2 = require("./util");
Object.defineProperty(exports, "VError", { enumerable: true, get: function () { return util_2.VError; } });
/**
 * Takes one of more type suites (e.g. a module generated by `ts-interface-builder`), and combines
 * them into a suite of interface checkers. If a type is used by name, that name should be present
 * among the passed-in type suites.
 *
 * The returned object maps type names to Checker objects.
 */
function createCheckers() {
    var typeSuite = [];
    for (var _i = 0; _i < arguments.length; _i++) {
        typeSuite[_i] = arguments[_i];
    }
    var fullSuite = Object.assign.apply(Object, __spreadArrays([{}, types_1.basicTypes], typeSuite));
    var checkers = {};
    for (var _a = 0, typeSuite_1 = typeSuite; _a < typeSuite_1.length; _a++) {
        var suite_1 = typeSuite_1[_a];
        for (var _b = 0, _c = Object.keys(suite_1); _b < _c.length; _b++) {
            var name = _c[_b];
            checkers[name] = new Checker(fullSuite, suite_1[name]);
        }
    }
    return checkers;
}
exports.createCheckers = createCheckers;
/**
 * Checker implements validation of objects, and also includes accessors to validate method calls.
 * Checkers should be created using `createCheckers()`.
 */
var Checker = /** @class */ (function () {
    // Create checkers by using `createCheckers()` function.
    function Checker(suite, ttype, _path) {
        if (_path === void 0) { _path = 'value'; }
        this.suite = suite;
        this.ttype = ttype;
        this._path = _path;
        this.props = new Map();
        if (ttype instanceof types_1.TIface) {
            for (var _i = 0, _a = ttype.props; _i < _a.length; _i++) {
                var p = _a[_i];
                this.props.set(p.name, p.ttype);
            }
        }
        this.checkerPlain = this.ttype.getChecker(suite, false);
        this.checkerStrict = this.ttype.getChecker(suite, true);
    }
    /**
     * Set the path to report in errors, instead of the default "value". (E.g. if the Checker is for
     * a "person" interface, set path to "person" to report e.g. "person.name is not a string".)
     */
    Checker.prototype.setReportedPath = function (path) {
        this._path = path;
    };
    /**
     * Check that the given value satisfies this checker's type, or throw Error.
     */
    Checker.prototype.check = function (value) { return this._doCheck(this.checkerPlain, value); };
    /**
     * A fast check for whether or not the given value satisfies this Checker's type. This returns
     * true or false, does not produce an error message, and is fast both on success and on failure.
     */
    Checker.prototype.test = function (value) {
        return this.checkerPlain(value, new util_1.NoopContext());
    };
    /**
     * Returns a non-empty array of error objects describing the errors if the given value does not satisfy this
     * Checker's type, or null if it does.
     */
    Checker.prototype.validate = function (value) {
        return this._doValidate(this.checkerPlain, value);
    };
    /**
     * Check that the given value satisfies this checker's type strictly. This checks that objects
     * and tuples have no extra members. Note that this prevents backward compatibility, so usually
     * a plain check() is more appropriate.
     */
    Checker.prototype.strictCheck = function (value) { return this._doCheck(this.checkerStrict, value); };
    /**
     * A fast strict check for whether or not the given value satisfies this Checker's type. Returns
     * true or false, does not produce an error message, and is fast both on success and on failure.
     */
    Checker.prototype.strictTest = function (value) {
        return this.checkerStrict(value, new util_1.NoopContext());
    };
    /**
     * Returns a non-empty array of error objects describing the errors if the given value does not satisfy this
     * Checker's type strictly, or null if it does.
     */
    Checker.prototype.strictValidate = function (value) {
        return this._doValidate(this.checkerStrict, value);
    };
    /**
     * If this checker is for an interface, returns a Checker for the type required for the given
     * property of this interface.
     */
    Checker.prototype.getProp = function (prop) {
        var ttype = this.props.get(prop);
        if (!ttype) {
            throw new Error("Type has no property " + prop);
        }
        return new Checker(this.suite, ttype, this._path + "." + prop);
    };
    /**
     * If this checker is for an interface, returns a Checker for the argument-list required to call
     * the given method of this interface. E.g. if this Checker is for the interface:
     *    interface Foo {
     *      find(s: string, pos?: number): number;
     *    }
     * Then methodArgs("find").check(...) will succeed for ["foo"] and ["foo", 3], but not for [17].
     */
    Checker.prototype.methodArgs = function (methodName) {
        var tfunc = this._getMethod(methodName);
        return new Checker(this.suite, tfunc.paramList);
    };
    /**
     * If this checker is for an interface, returns a Checker for the return value of the given
     * method of this interface.
     */
    Checker.prototype.methodResult = function (methodName) {
        var tfunc = this._getMethod(methodName);
        return new Checker(this.suite, tfunc.result);
    };
    /**
     * If this checker is for a function, returns a Checker for its argument-list.
     */
    Checker.prototype.getArgs = function () {
        if (!(this.ttype instanceof types_1.TFunc)) {
            throw new Error("getArgs() applied to non-function");
        }
        return new Checker(this.suite, this.ttype.paramList);
    };
    /**
     * If this checker is for a function, returns a Checker for its result.
     */
    Checker.prototype.getResult = function () {
        if (!(this.ttype instanceof types_1.TFunc)) {
            throw new Error("getResult() applied to non-function");
        }
        return new Checker(this.suite, this.ttype.result);
    };
    /**
     * Return the type for which this is a checker.
     */
    Checker.prototype.getType = function () {
        return this.ttype;
    };
    /**
     * Actual implementation of check() and strictCheck().
     */
    Checker.prototype._doCheck = function (checkerFunc, value) {
        var noopCtx = new util_1.NoopContext();
        if (!checkerFunc(value, noopCtx)) {
            var detailCtx = new util_1.DetailContext();
            checkerFunc(value, detailCtx);
            throw detailCtx.getError(this._path);
        }
    };
    Checker.prototype._doValidate = function (checkerFunc, value) {
        var noopCtx = new util_1.NoopContext();
        if (checkerFunc(value, noopCtx)) {
            return null;
        }
        var detailCtx = new util_1.DetailContext();
        checkerFunc(value, detailCtx);
        return detailCtx.getErrorDetails(this._path);
    };
    Checker.prototype._getMethod = function (methodName) {
        var ttype = this.props.get(methodName);
        if (!ttype) {
            throw new Error("Type has no property " + methodName);
        }
        if (!(ttype instanceof types_1.TFunc)) {
            throw new Error("Property " + methodName + " is not a method");
        }
        return ttype;
    };
    return Checker;
}());
exports.Checker = Checker;

},{"./types":63,"./util":64}],63:[function(require,module,exports){
(function (Buffer){(function (){
"use strict";
/**
 * This module defines nodes used to define types and validations for objects and interfaces.
 */
// tslint:disable:no-shadowed-variable prefer-for-of
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.basicTypes = exports.BasicType = exports.TParamList = exports.TParam = exports.param = exports.TFunc = exports.func = exports.TProp = exports.TOptional = exports.opt = exports.TIface = exports.iface = exports.indexKey = exports.TEnumLiteral = exports.enumlit = exports.TEnumType = exports.enumtype = exports.TIntersection = exports.intersection = exports.TUnion = exports.union = exports.TTuple = exports.tuple = exports.RestType = exports.rest = exports.TArray = exports.array = exports.TLiteral = exports.lit = exports.TName = exports.name = exports.TType = void 0;
var util_1 = require("./util");
/** Node that represents a type. */
var TType = /** @class */ (function () {
    function TType() {
    }
    return TType;
}());
exports.TType = TType;
/** Parses a type spec into a TType node. */
function parseSpec(typeSpec) {
    return typeof typeSpec === "string" ? name(typeSpec) : typeSpec;
}
function getNamedType(suite, name) {
    var ttype = suite[name];
    if (!ttype) {
        throw new Error("Unknown type " + name);
    }
    return ttype;
}
/**
 * Defines a type name, either built-in, or defined in this suite. It can typically be included in
 * the specs as just a plain string.
 */
function name(value) { return new TName(value); }
exports.name = name;
var TName = /** @class */ (function (_super) {
    __extends(TName, _super);
    function TName(name) {
        var _this = _super.call(this) || this;
        _this.name = name;
        _this._failMsg = "is not a " + name;
        return _this;
    }
    TName.prototype.getChecker = function (suite, strict, allowedProps) {
        // Using names, we can reference a type recursively in its own definition. To avoid an
        // infinite recursion in getChecker() calls, we cache and reuse the checker that's being built
        // when it references its own TName node. Note that it's important to reuse the result only
        // when getChecker() is called with the same arguments, but that's already guaranteed because
        // we are caching only for the current call and only for the same TName object (not another
        // instance of name() call for the same name).
        //
        // Note also that this is about handling recursive types; it does NOT help validating data
        // with circular references.
        var checkerFunc = this._checkerBeingBuilt;
        if (!checkerFunc) {
            this._checkerBeingBuilt = function (value, ctx) { return checkerFunc(value, ctx); };
            try {
                checkerFunc = this._getChecker(suite, strict, allowedProps);
            }
            finally {
                this._checkerBeingBuilt = undefined;
            }
        }
        return checkerFunc;
    };
    TName.prototype._getChecker = function (suite, strict, allowedProps) {
        var _this = this;
        var ttype = getNamedType(suite, this.name);
        var checker = ttype.getChecker(suite, strict, allowedProps);
        if (ttype instanceof BasicType || ttype instanceof TName) {
            return checker;
        }
        // For complex types, add an additional "is not a <Type>" message on failure.
        return function (value, ctx) { return checker(value, ctx) ? true : ctx.fail(null, _this._failMsg, 0); };
    };
    return TName;
}(TType));
exports.TName = TName;
/**
 * Defines a literal value, e.g. lit('hello') or lit(123).
 */
function lit(value) { return new TLiteral(value); }
exports.lit = lit;
var TLiteral = /** @class */ (function (_super) {
    __extends(TLiteral, _super);
    function TLiteral(value) {
        var _this = _super.call(this) || this;
        _this.value = value;
        _this.name = JSON.stringify(value);
        _this._failMsg = "is not " + _this.name;
        return _this;
    }
    TLiteral.prototype.getChecker = function (suite, strict) {
        var _this = this;
        return function (value, ctx) { return (value === _this.value) ? true : ctx.fail(null, _this._failMsg, -1); };
    };
    return TLiteral;
}(TType));
exports.TLiteral = TLiteral;
/**
 * Defines an array type, e.g. array('number').
 */
function array(typeSpec) { return new TArray(parseSpec(typeSpec)); }
exports.array = array;
var TArray = /** @class */ (function (_super) {
    __extends(TArray, _super);
    function TArray(ttype) {
        var _this = _super.call(this) || this;
        _this.ttype = ttype;
        var elementTypeName = getTypeName(ttype);
        if (elementTypeName) {
            _this.name = elementTypeName + "[]";
        }
        return _this;
    }
    TArray.prototype.getChecker = function (suite, strict) {
        var itemChecker = this.ttype.getChecker(suite, strict);
        return function (value, ctx) {
            if (!Array.isArray(value)) {
                return ctx.fail(null, "is not an array", 0);
            }
            for (var i = 0; i < value.length; i++) {
                var ok = itemChecker(value[i], ctx);
                if (!ok) {
                    return ctx.fail(i, null, 1);
                }
            }
            return true;
        };
    };
    return TArray;
}(TType));
exports.TArray = TArray;
/**
 * Defines a rest type, e.g. tuple('string', rest(array('number'))).
 */
function rest(typeSpec) {
    return new RestType(typeSpec);
}
exports.rest = rest;
var RestType = /** @class */ (function (_super) {
    __extends(RestType, _super);
    function RestType(typeSpec) {
        var _this = _super.call(this) || this;
        _this.typeSpec = typeSpec;
        return _this;
    }
    RestType.prototype.setStart = function (start) {
        this._start = start;
    };
    RestType.prototype.getChecker = function (suite, strict) {
        var arrType = typeof this.typeSpec === "string" ? getNamedType(suite, this.typeSpec) : this.typeSpec;
        if (!(arrType instanceof TArray)) {
            throw new Error("Rest type must be an array");
        }
        var itemChecker = arrType.ttype.getChecker(suite, strict);
        var start = this._start;
        return function (value, ctx) {
            for (var i = start; i < value.length; i++) {
                if (!itemChecker(value[i], ctx)) {
                    return ctx.fail(i, null, 1);
                }
            }
            return true;
        };
    };
    return RestType;
}(TType));
exports.RestType = RestType;
/**
 * Defines a tuple type, e.g. tuple('string', 'number').
 */
function tuple() {
    var typeSpec = [];
    for (var _i = 0; _i < arguments.length; _i++) {
        typeSpec[_i] = arguments[_i];
    }
    return new TTuple(typeSpec.map(function (t) { return parseSpec(t); }));
}
exports.tuple = tuple;
var TTuple = /** @class */ (function (_super) {
    __extends(TTuple, _super);
    function TTuple(ttypes) {
        var _this = _super.call(this) || this;
        _this.ttypes = ttypes;
        var last = ttypes[ttypes.length - 1];
        if (last instanceof RestType) {
            ttypes.pop();
            _this._restType = last;
            _this._restType.setStart(ttypes.length);
        }
        return _this;
    }
    TTuple.prototype.getChecker = function (suite, strict) {
        var itemCheckers = this.ttypes.map(function (t) { return t.getChecker(suite, strict); });
        var checker = function (value, ctx) {
            if (!Array.isArray(value)) {
                return ctx.fail(null, "is not an array", 0);
            }
            for (var i = 0; i < itemCheckers.length; i++) {
                var ok = itemCheckers[i](value[i], ctx);
                if (!ok) {
                    return ctx.fail(i, null, 1);
                }
            }
            return true;
        };
        if (this._restType) {
            var restChecker_1 = this._restType.getChecker(suite, strict);
            return function (value, ctx) {
                return checker(value, ctx) && restChecker_1(value, ctx);
            };
        }
        if (!strict) {
            return checker;
        }
        return function (value, ctx) {
            if (!checker(value, ctx)) {
                return false;
            }
            return value.length <= itemCheckers.length ? true :
                ctx.fail(itemCheckers.length, "is extraneous", 2);
        };
    };
    return TTuple;
}(TType));
exports.TTuple = TTuple;
/**
 * Defines a union type, e.g. union('number', 'null').
 */
function union() {
    var typeSpec = [];
    for (var _i = 0; _i < arguments.length; _i++) {
        typeSpec[_i] = arguments[_i];
    }
    return new TUnion(typeSpec.map(function (t) { return parseSpec(t); }));
}
exports.union = union;
var TUnion = /** @class */ (function (_super) {
    __extends(TUnion, _super);
    function TUnion(ttypes) {
        var _this = _super.call(this) || this;
        _this.ttypes = ttypes;
        var names = ttypes.map(getTypeName)
            .filter(function (n) { return n; });
        var otherTypes = ttypes.length - names.length;
        if (names.length) {
            if (otherTypes > 0) {
                names.push(otherTypes + " more");
            }
            _this._failMsg = "is none of " + names.join(", ");
        }
        else {
            _this._failMsg = "is none of " + otherTypes + " types";
        }
        return _this;
    }
    TUnion.prototype.getChecker = function (suite, strict, allowedProps) {
        var _this = this;
        var itemCheckers = this.ttypes.map(function (t) { return t.getChecker(suite, strict, allowedProps); });
        return function (value, ctx) {
            var ur = ctx.unionResolver();
            for (var i = 0; i < itemCheckers.length; i++) {
                var ok = itemCheckers[i](value, ur.createContext());
                if (ok) {
                    return true;
                }
            }
            ctx.resolveUnion(ur);
            return ctx.fail(null, _this._failMsg, 0);
        };
    };
    return TUnion;
}(TType));
exports.TUnion = TUnion;
/**
 * Defines an intersection type, e.g. intersection('number', 'null').
 */
function intersection() {
    var typeSpec = [];
    for (var _i = 0; _i < arguments.length; _i++) {
        typeSpec[_i] = arguments[_i];
    }
    return new TIntersection(typeSpec.map(function (t) { return parseSpec(t); }));
}
exports.intersection = intersection;
var TIntersection = /** @class */ (function (_super) {
    __extends(TIntersection, _super);
    function TIntersection(ttypes) {
        var _this = _super.call(this) || this;
        _this.ttypes = ttypes;
        return _this;
    }
    TIntersection.prototype.getChecker = function (suite, strict, allowedProps) {
        if (allowedProps === void 0) { allowedProps = new Set(); }
        var itemCheckers = this.ttypes.map(function (t) { return t.getChecker(suite, strict, allowedProps); });
        return function (value, ctx) {
            return itemCheckers.every(function (checker) {
                checker(value, ctx.fork());
                return ctx.completeFork();
            }) && !ctx.failed();
        };
    };
    return TIntersection;
}(TType));
exports.TIntersection = TIntersection;
/**
 * Defines an enum type, e.g. enum({'A': 1, 'B': 2}).
 */
function enumtype(values) {
    return new TEnumType(values);
}
exports.enumtype = enumtype;
var TEnumType = /** @class */ (function (_super) {
    __extends(TEnumType, _super);
    function TEnumType(members) {
        var _this = _super.call(this) || this;
        _this.members = members;
        _this.validValues = new Set();
        _this._failMsg = "is not a valid enum value";
        _this.validValues = new Set(Object.keys(members).map(function (name) { return members[name]; }));
        return _this;
    }
    TEnumType.prototype.getChecker = function (suite, strict) {
        var _this = this;
        return function (value, ctx) {
            return (_this.validValues.has(value) ? true : ctx.fail(null, _this._failMsg, 0));
        };
    };
    return TEnumType;
}(TType));
exports.TEnumType = TEnumType;
/**
 * Defines a literal enum value, such as Direction.Up, specified as enumlit("Direction", "Up").
 */
function enumlit(name, prop) {
    return new TEnumLiteral(name, prop);
}
exports.enumlit = enumlit;
var TEnumLiteral = /** @class */ (function (_super) {
    __extends(TEnumLiteral, _super);
    function TEnumLiteral(enumName, prop) {
        var _this = _super.call(this) || this;
        _this.enumName = enumName;
        _this.prop = prop;
        _this._failMsg = "is not " + enumName + "." + prop;
        return _this;
    }
    TEnumLiteral.prototype.getChecker = function (suite, strict) {
        var _this = this;
        var ttype = getNamedType(suite, this.enumName);
        if (!(ttype instanceof TEnumType)) {
            throw new Error("Type " + this.enumName + " used in enumlit is not an enum type");
        }
        var val = ttype.members[this.prop];
        if (!ttype.members.hasOwnProperty(this.prop)) {
            throw new Error("Unknown value " + this.enumName + "." + this.prop + " used in enumlit");
        }
        return function (value, ctx) { return (value === val) ? true : ctx.fail(null, _this._failMsg, -1); };
    };
    return TEnumLiteral;
}(TType));
exports.TEnumLiteral = TEnumLiteral;
function makeIfaceProps(props) {
    return Object.keys(props)
        .filter(function (name) { return (name !== exports.indexKey); })
        .map(function (name) { return makeIfaceProp(name, props[name]); });
}
function makeIfaceProp(name, prop) {
    return prop instanceof TOptional ?
        new TProp(name, prop.ttype, true) :
        new TProp(name, parseSpec(prop), false);
}
/**
 * indexKey is a special key that indicates an index signature when used as a key in an interface.
 * E.g. {[key: string]: number} becomes t.iface([], {[t.indexKey]: "number"}).
 *
 * We don't distinguish between string- and number-type index signatures, and don't support
 * multiple index signatures.
 */
exports.indexKey = Symbol();
/**
 * Defines an interface. The first argument is an array of interfaces that it extends, and the
 * second is an array of properties.
 */
function iface(bases, props) {
    return new TIface(bases, makeIfaceProps(props), props[exports.indexKey]);
}
exports.iface = iface;
var TIface = /** @class */ (function (_super) {
    __extends(TIface, _super);
    function TIface(bases, props, indexType) {
        var _this = _super.call(this) || this;
        _this.bases = bases;
        _this.props = props;
        _this.indexType = indexType ? parseSpec(indexType) : undefined;
        _this.propSet = new Set(props.map(function (p) { return p.name; }));
        return _this;
    }
    TIface.prototype.getChecker = function (suite, strict, allowedProps) {
        var _this = this;
        var _a;
        if (allowedProps === void 0) { allowedProps = new Set(); }
        this.propSet.forEach(function (prop) { return allowedProps.add(prop); });
        var baseCheckers = this.bases.map(function (b) { return getNamedType(suite, b).getChecker(suite, strict, allowedProps); });
        var propCheckers = this.props.map(function (prop) { return prop.ttype.getChecker(suite, strict); });
        var indexTypeChecker = (_a = this.indexType) === null || _a === void 0 ? void 0 : _a.getChecker(suite, strict);
        var testCtx = new util_1.NoopContext();
        // Consider a prop required if it's not optional AND does not allow for undefined as a value.
        var isPropRequired = this.props.map(function (prop, i) {
            return !prop.isOpt && !propCheckers[i](undefined, testCtx);
        });
        return function (value, ctx) {
            if (typeof value !== "object" || value === null) {
                return ctx.fail(null, "is not an object", 0);
            }
            for (var i = 0; i < baseCheckers.length; i++) {
                baseCheckers[i](value, ctx.fork());
                if (!ctx.completeFork()) {
                    return false;
                }
            }
            for (var i = 0; i < propCheckers.length; i++) {
                var name_1 = _this.props[i].name;
                var v = value[name_1];
                if (v === undefined) {
                    if (isPropRequired[i]) {
                        ctx.fork().fail(name_1, "is missing", 1);
                        if (!ctx.completeFork()) {
                            return false;
                        }
                    }
                }
                else {
                    var fork = ctx.fork();
                    var ok = propCheckers[i](v, fork);
                    if (!ok) {
                        fork.fail(name_1, null, 1);
                    }
                    if (!ctx.completeFork()) {
                        return false;
                    }
                }
            }
            if (indexTypeChecker) {
                for (var prop in value) {
                    var fork = ctx.fork();
                    if (!indexTypeChecker(value[prop], fork)) {
                        fork.fail(prop, null, 1);
                    }
                    if (!ctx.completeFork()) {
                        return false;
                    }
                }
            }
            else if (strict) {
                // In strict mode, check also for unknown enumerable properties.
                for (var prop in value) {
                    if (!allowedProps.has(prop)) {
                        ctx.fork().fail(prop, "is extraneous", 2);
                        if (!ctx.completeFork()) {
                            return false;
                        }
                    }
                }
            }
            return !ctx.failed();
        };
    };
    return TIface;
}(TType));
exports.TIface = TIface;
/**
 * Defines an optional property on an interface.
 */
function opt(typeSpec) { return new TOptional(parseSpec(typeSpec)); }
exports.opt = opt;
var TOptional = /** @class */ (function (_super) {
    __extends(TOptional, _super);
    function TOptional(ttype) {
        var _this = _super.call(this) || this;
        _this.ttype = ttype;
        return _this;
    }
    TOptional.prototype.getChecker = function (suite, strict) {
        var itemChecker = this.ttype.getChecker(suite, strict);
        return function (value, ctx) {
            return value === undefined || itemChecker(value, ctx);
        };
    };
    return TOptional;
}(TType));
exports.TOptional = TOptional;
/**
 * Defines a property in an interface.
 */
var TProp = /** @class */ (function () {
    function TProp(name, ttype, isOpt) {
        this.name = name;
        this.ttype = ttype;
        this.isOpt = isOpt;
    }
    return TProp;
}());
exports.TProp = TProp;
/**
 * Defines a function. The first argument declares the function's return type, the rest declare
 * its parameters.
 */
function func(resultSpec) {
    var params = [];
    for (var _i = 1; _i < arguments.length; _i++) {
        params[_i - 1] = arguments[_i];
    }
    return new TFunc(new TParamList(params), parseSpec(resultSpec));
}
exports.func = func;
var TFunc = /** @class */ (function (_super) {
    __extends(TFunc, _super);
    function TFunc(paramList, result) {
        var _this = _super.call(this) || this;
        _this.paramList = paramList;
        _this.result = result;
        return _this;
    }
    TFunc.prototype.getChecker = function (suite, strict) {
        return function (value, ctx) {
            return typeof value === "function" ? true : ctx.fail(null, "is not a function", 0);
        };
    };
    return TFunc;
}(TType));
exports.TFunc = TFunc;
/**
 * Defines a function parameter.
 */
function param(name, typeSpec, isOpt) {
    return new TParam(name, parseSpec(typeSpec), Boolean(isOpt));
}
exports.param = param;
var TParam = /** @class */ (function () {
    function TParam(name, ttype, isOpt) {
        this.name = name;
        this.ttype = ttype;
        this.isOpt = isOpt;
    }
    return TParam;
}());
exports.TParam = TParam;
/**
 * Defines a function parameter list.
 */
var TParamList = /** @class */ (function (_super) {
    __extends(TParamList, _super);
    function TParamList(params) {
        var _this = _super.call(this) || this;
        _this.params = params;
        return _this;
    }
    TParamList.prototype.getChecker = function (suite, strict) {
        var _this = this;
        var itemCheckers = this.params.map(function (t) { return t.ttype.getChecker(suite, strict); });
        var testCtx = new util_1.NoopContext();
        var isParamRequired = this.params.map(function (param, i) {
            return !param.isOpt && !itemCheckers[i](undefined, testCtx);
        });
        var checker = function (value, ctx) {
            if (!Array.isArray(value)) {
                return ctx.fail(null, "is not an array", 0);
            }
            for (var i = 0; i < itemCheckers.length; i++) {
                var p = _this.params[i];
                if (value[i] === undefined) {
                    if (isParamRequired[i]) {
                        return ctx.fail(p.name, "is missing", 1);
                    }
                }
                else {
                    var ok = itemCheckers[i](value[i], ctx);
                    if (!ok) {
                        return ctx.fail(p.name, null, 1);
                    }
                }
            }
            return true;
        };
        if (!strict) {
            return checker;
        }
        return function (value, ctx) {
            if (!checker(value, ctx)) {
                return false;
            }
            return value.length <= itemCheckers.length ? true :
                ctx.fail(itemCheckers.length, "is extraneous", 2);
        };
    };
    return TParamList;
}(TType));
exports.TParamList = TParamList;
/**
 * Single TType implementation for all basic built-in types.
 */
var BasicType = /** @class */ (function (_super) {
    __extends(BasicType, _super);
    function BasicType(validator, message) {
        var _this = _super.call(this) || this;
        _this.validator = validator;
        _this.message = message;
        return _this;
    }
    BasicType.prototype.getChecker = function (suite, strict) {
        var _this = this;
        return function (value, ctx) { return _this.validator(value) ? true : ctx.fail(null, _this.message, 0); };
    };
    return BasicType;
}(TType));
exports.BasicType = BasicType;
/**
 * Defines the suite of basic types.
 */
exports.basicTypes = {
    any: new BasicType(function (v) { return true; }, "is invalid"),
    unknown: new BasicType(function (v) { return true; }, "is invalid"),
    number: new BasicType(function (v) { return (typeof v === "number"); }, "is not a number"),
    object: new BasicType(function (v) { return (typeof v === "object" && v); }, "is not an object"),
    boolean: new BasicType(function (v) { return (typeof v === "boolean"); }, "is not a boolean"),
    string: new BasicType(function (v) { return (typeof v === "string"); }, "is not a string"),
    symbol: new BasicType(function (v) { return (typeof v === "symbol"); }, "is not a symbol"),
    void: new BasicType(function (v) { return (v == null); }, "is not void"),
    undefined: new BasicType(function (v) { return (v === undefined); }, "is not undefined"),
    null: new BasicType(function (v) { return (v === null); }, "is not null"),
    never: new BasicType(function (v) { return false; }, "is unexpected"),
    Date: new BasicType(getIsNativeChecker("[object Date]"), "is not a Date"),
    RegExp: new BasicType(getIsNativeChecker("[object RegExp]"), "is not a RegExp"),
};
// This approach for checking native object types mirrors that of lodash. Its advantage over
// `isinstance` is that it can still return true for native objects created in different JS
// execution environments.
var nativeToString = Object.prototype.toString;
function getIsNativeChecker(tag) {
    return function (v) { return typeof v === "object" && v && nativeToString.call(v) === tag; };
}
if (typeof Buffer !== "undefined") {
    exports.basicTypes.Buffer = new BasicType(function (v) { return Buffer.isBuffer(v); }, "is not a Buffer");
}
var _loop_1 = function (array_1) {
    exports.basicTypes[array_1.name] = new BasicType(function (v) { return (v instanceof array_1); }, "is not a " + array_1.name);
};
// Support typed arrays of various flavors
for (var _i = 0, _a = [Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array,
    Int32Array, Uint32Array, Float32Array, Float64Array, ArrayBuffer]; _i < _a.length; _i++) {
    var array_1 = _a[_i];
    _loop_1(array_1);
}
function getTypeName(t) {
    if (t instanceof TName || t instanceof TLiteral || t instanceof TArray) {
        return t.name;
    }
}

}).call(this)}).call(this,require("buffer").Buffer)

},{"./util":64,"buffer":19}],64:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var __spreadArrays = (this && this.__spreadArrays) || function () {
    for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
    for (var r = Array(s), k = 0, i = 0; i < il; i++)
        for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
            r[k] = a[j];
    return r;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.DetailContext = exports.NoopContext = exports.VError = void 0;
/**
 * Error thrown by validation. Besides an informative message, it includes the path to the
 * property which triggered the failure.
 */
var VError = /** @class */ (function (_super) {
    __extends(VError, _super);
    function VError(path, message) {
        var _this = _super.call(this, message) || this;
        _this.path = path;
        // See https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work for info about this workaround.
        Object.setPrototypeOf(_this, VError.prototype);
        return _this;
    }
    return VError;
}(Error));
exports.VError = VError;
/**
 * Fast implementation of IContext used for first-pass validation. If that fails, we can validate
 * using DetailContext to collect error messages. That's faster for the common case when messages
 * normally pass validation.
 */
var NoopContext = /** @class */ (function () {
    function NoopContext() {
        this._failed = false;
    }
    NoopContext.prototype.fail = function (relPath, message, score) {
        this._failed = true;
        return false;
    };
    NoopContext.prototype.fork = function () {
        return this;
    };
    NoopContext.prototype.completeFork = function () {
        return !this._failed;
    };
    NoopContext.prototype.failed = function () {
        return this._failed;
    };
    NoopContext.prototype.unionResolver = function () { return this; };
    NoopContext.prototype.createContext = function () {
        this._failed = false;
        return this;
    };
    NoopContext.prototype.resolveUnion = function (ur) { };
    return NoopContext;
}());
exports.NoopContext = NoopContext;
/**
 * Complete implementation of IContext that collects meaningfull errors.
 */
var DetailContext = /** @class */ (function () {
    function DetailContext() {
        // Stack of property names and associated messages for reporting helpful error messages.
        this._propNames = [];
        this._messages = [];
        /** Contexts created by fork() which have completed and contain failures */
        this._failedForks = [];
        /**
         * Contains the context returned by fork() which should be checked until
         * completeFork() is called.
         * Will be reused for the next fork() if there are no failures.
         */
        this._currentFork = null;
        // Score is used to choose the best union member whose DetailContext to use for reporting.
        // Higher score means better match (or rather less severe mismatch).
        this._score = 0;
    }
    DetailContext.prototype.fail = function (relPath, message, score) {
        this._propNames.push(relPath);
        this._messages.push(message);
        this._score += score;
        return false;
    };
    DetailContext.prototype.unionResolver = function () {
        return new DetailUnionResolver();
    };
    DetailContext.prototype.resolveUnion = function (unionResolver) {
        var _a, _b, _c;
        var u = unionResolver;
        var best = null;
        for (var _i = 0, _d = u.contexts; _i < _d.length; _i++) {
            var ctx = _d[_i];
            if (!best || ctx._score >= best._score) {
                best = ctx;
            }
        }
        if (best && best._score > 0) {
            (_a = this._propNames).push.apply(_a, best._propNames);
            (_b = this._messages).push.apply(_b, best._messages);
            (_c = this._failedForks).push.apply(_c, best._failedForks);
        }
    };
    DetailContext.prototype.getError = function (path) {
        var fullMessage = flatten(this.getErrorDetails(path).map(errorLines))
            .join("\n");
        return new VError(path, fullMessage);
    };
    DetailContext.prototype.getErrorDetails = function (path) {
        var detail = null;
        var nested;
        var details = [];
        // As checkers call fail() and return to their parent checkers,
        // the deepest failures are recorded first.
        // Go through failures in reverse to start from the root type
        for (var i = this._propNames.length - 1; i >= 0; i--) {
            var p = this._propNames[i];
            path += (typeof p === "number") ? "[" + p + "]" : (p ? "." + p : "");
            var message = this._messages[i];
            if (!message) {
                continue;
            }
            nested = { path: path, message: message };
            if (detail) {
                detail.nested = [nested];
            }
            else {
                // This is the root failure, so it will be returned
                details.push(nested);
            }
            // Move into the deeper error
            detail = nested;
        }
        var forkErrors = flatten(this._failedForks.map(function (fork) { return fork.getErrorDetails(path); }));
        if (detail) {
            // don't put an empty array in detail.nested
            if (forkErrors.length) {
                // detail is the deepest nested error, so detail.nested is null at this point
                detail.nested = forkErrors;
            }
        }
        else {
            // There were no 'plain' failures, only fork failures
            details = forkErrors;
        }
        return details;
    };
    DetailContext.prototype.fork = function () {
        if (this._currentFork == null) {
            this._currentFork = new DetailContext();
        }
        return this._currentFork;
    };
    DetailContext.prototype.completeFork = function () {
        var fork = this._currentFork;
        if (fork._failed()) {
            this._failedForks.push(fork);
            this._currentFork = null;
            // To preserve old behaviour, use the score of the first failure
            // Might want to revise this
            if (this._failedForks.length === 1) {
                this._score = fork._score;
            }
        }
        return this._failedForks.length < DetailContext.maxForks;
    };
    // failed() is the public interface,
    // it gets monkeypatched to ensure correct usage in checkers.
    // _failed() may be called internally
    // in ways which would fail the monkeypatched assertions.
    DetailContext.prototype.failed = function () {
        return this._failed();
    };
    DetailContext.prototype._failed = function () {
        return this._propNames.length + this._failedForks.length > 0;
    };
    /**
     * Maximum number of errors recorded at one level for an object,
     * i.e. the maximum length of Checker.validate() or IErrorDetail.nested.
     */
    // If _failedForks has this length then completeFork() should return false
    // so that the checker stops making more forks.
    DetailContext.maxForks = 3;
    return DetailContext;
}());
exports.DetailContext = DetailContext;
var DetailUnionResolver = /** @class */ (function () {
    function DetailUnionResolver() {
        this.contexts = [];
    }
    DetailUnionResolver.prototype.createContext = function () {
        var ctx = new DetailContext();
        this.contexts.push(ctx);
        return ctx;
    };
    return DetailUnionResolver;
}());
/**
 * Returns lines of a message describing `error`.
 * The lines should be newline separated in the final message.
 * Only returns multiple lines if `error` or a descendant
 * has multiple errors in its `.nested` array.
 * Simple paths of nested errors anywhere in the tree
 * are collapsed into a single line until a branch is reached.
 */
var errorLines = function (error) {
    var rootMessage = error.path + " " + error.message;
    var nestedErrors = error.nested || [];
    var nestedLines = flatten(nestedErrors.map(errorLines));
    if (nestedErrors.length == 1) {
        // Single nested errors are collapsed into the first line,
        // but they may have branches deeper down leading to more lines
        // which are already indented
        var first = nestedLines[0], rest = nestedLines.slice(1);
        return __spreadArrays([
            rootMessage + "; " + first
        ], rest);
    }
    else {
        // Indent messages from nested errors
        // or just return [rootMessage] if there are no nested errors
        return __spreadArrays([
            rootMessage
        ], nestedLines.map(function (line) { return "    " + line; }));
    }
};
/** Shallow flatten a 2D array into a 1D array */
function flatten(arr) {
    var _a;
    return (_a = []).concat.apply(_a, arr);
}

},{}]},{},[5])
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJkaXN0L2hvbWVicmlkZ2UtdWkvcHVibGljL2FwaS1zdGF0dXMuanMiLCJkaXN0L2hvbWVicmlkZ2UtdWkvcHVibGljL2NhcmRzLmpzIiwiZGlzdC9ob21lYnJpZGdlLXVpL3B1YmxpYy9jbGllbnQtY2xpZW50aWQuanMiLCJkaXN0L2hvbWVicmlkZ2UtdWkvcHVibGljL2NsaWVudC1pcGMuanMiLCJkaXN0L2hvbWVicmlkZ2UtdWkvcHVibGljL2NsaWVudC5qcyIsImRpc3QvaG9tZWJyaWRnZS11aS9wdWJsaWMvY29uZmlnLmpzIiwiZGlzdC9ob21lYnJpZGdlLXVpL3B1YmxpYy9mb3Jtcy5qcyIsImRpc3QvaG9tZWJyaWRnZS11aS9wdWJsaWMvbG9nZ2VyLmpzIiwiZGlzdC9ob21lYnJpZGdlLXVpL3B1YmxpYy91dGlscy1kb20uanMiLCJkaXN0L3RpL2NvbmZpZy10eXBlcy10aS5qcyIsImRpc3QvdGkvY29uZmlnLXR5cGVzLmpzIiwiZGlzdC91dGlscy5qcyIsIm5vZGVfbW9kdWxlcy9AaG9tZWJyaWRnZS9wbHVnaW4tdWktdXRpbHMvZGlzdC91aS5pbnRlcmZhY2UuanMiLCJub2RlX21vZHVsZXMvYXNzZXJ0L2Fzc2VydC5qcyIsIm5vZGVfbW9kdWxlcy9hc3NlcnQvbm9kZV9tb2R1bGVzL2luaGVyaXRzL2luaGVyaXRzX2Jyb3dzZXIuanMiLCJub2RlX21vZHVsZXMvYXNzZXJ0L25vZGVfbW9kdWxlcy91dGlsL3N1cHBvcnQvaXNCdWZmZXJCcm93c2VyLmpzIiwibm9kZV9tb2R1bGVzL2Fzc2VydC9ub2RlX21vZHVsZXMvdXRpbC91dGlsLmpzIiwibm9kZV9tb2R1bGVzL2Jhc2U2NC1qcy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9idWZmZXIvaW5kZXguanMiLCJub2RlX21vZHVsZXMvY2FsbC1iaW5kLWFwcGx5LWhlbHBlcnMvYWN0dWFsQXBwbHkuanMiLCJub2RlX21vZHVsZXMvY2FsbC1iaW5kLWFwcGx5LWhlbHBlcnMvZnVuY3Rpb25BcHBseS5qcyIsIm5vZGVfbW9kdWxlcy9jYWxsLWJpbmQtYXBwbHktaGVscGVycy9mdW5jdGlvbkNhbGwuanMiLCJub2RlX21vZHVsZXMvY2FsbC1iaW5kLWFwcGx5LWhlbHBlcnMvaW5kZXguanMiLCJub2RlX21vZHVsZXMvY2FsbC1iaW5kLWFwcGx5LWhlbHBlcnMvcmVmbGVjdEFwcGx5LmpzIiwibm9kZV9tb2R1bGVzL2NhbGwtYm91bmQvaW5kZXguanMiLCJub2RlX21vZHVsZXMvZHVuZGVyLXByb3RvL2dldC5qcyIsIm5vZGVfbW9kdWxlcy9lcy1kZWZpbmUtcHJvcGVydHkvaW5kZXguanMiLCJub2RlX21vZHVsZXMvZXMtZXJyb3JzL2V2YWwuanMiLCJub2RlX21vZHVsZXMvZXMtZXJyb3JzL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2VzLWVycm9ycy9yYW5nZS5qcyIsIm5vZGVfbW9kdWxlcy9lcy1lcnJvcnMvcmVmLmpzIiwibm9kZV9tb2R1bGVzL2VzLWVycm9ycy9zeW50YXguanMiLCJub2RlX21vZHVsZXMvZXMtZXJyb3JzL3R5cGUuanMiLCJub2RlX21vZHVsZXMvZXMtZXJyb3JzL3VyaS5qcyIsIm5vZGVfbW9kdWxlcy9lcy1vYmplY3QtYXRvbXMvaW5kZXguanMiLCJub2RlX21vZHVsZXMvZnVuY3Rpb24tYmluZC9pbXBsZW1lbnRhdGlvbi5qcyIsIm5vZGVfbW9kdWxlcy9mdW5jdGlvbi1iaW5kL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2dldC1pbnRyaW5zaWMvaW5kZXguanMiLCJub2RlX21vZHVsZXMvZ2V0LXByb3RvL09iamVjdC5nZXRQcm90b3R5cGVPZi5qcyIsIm5vZGVfbW9kdWxlcy9nZXQtcHJvdG8vUmVmbGVjdC5nZXRQcm90b3R5cGVPZi5qcyIsIm5vZGVfbW9kdWxlcy9nZXQtcHJvdG8vaW5kZXguanMiLCJub2RlX21vZHVsZXMvZ29wZC9nT1BELmpzIiwibm9kZV9tb2R1bGVzL2dvcGQvaW5kZXguanMiLCJub2RlX21vZHVsZXMvaGFzLXN5bWJvbHMvaW5kZXguanMiLCJub2RlX21vZHVsZXMvaGFzLXN5bWJvbHMvc2hhbXMuanMiLCJub2RlX21vZHVsZXMvaGFzb3duL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2llZWU3NTQvaW5kZXguanMiLCJub2RlX21vZHVsZXMvbWF0aC1pbnRyaW5zaWNzL2Ficy5qcyIsIm5vZGVfbW9kdWxlcy9tYXRoLWludHJpbnNpY3MvZmxvb3IuanMiLCJub2RlX21vZHVsZXMvbWF0aC1pbnRyaW5zaWNzL2lzTmFOLmpzIiwibm9kZV9tb2R1bGVzL21hdGgtaW50cmluc2ljcy9tYXguanMiLCJub2RlX21vZHVsZXMvbWF0aC1pbnRyaW5zaWNzL21pbi5qcyIsIm5vZGVfbW9kdWxlcy9tYXRoLWludHJpbnNpY3MvcG93LmpzIiwibm9kZV9tb2R1bGVzL21hdGgtaW50cmluc2ljcy9yb3VuZC5qcyIsIm5vZGVfbW9kdWxlcy9tYXRoLWludHJpbnNpY3Mvc2lnbi5qcyIsIm5vZGVfbW9kdWxlcy9vYmplY3Qta2V5cy9pbXBsZW1lbnRhdGlvbi5qcyIsIm5vZGVfbW9kdWxlcy9vYmplY3Qta2V5cy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9vYmplY3Qta2V5cy9pc0FyZ3VtZW50cy5qcyIsIm5vZGVfbW9kdWxlcy9vYmplY3QuYXNzaWduL2ltcGxlbWVudGF0aW9uLmpzIiwibm9kZV9tb2R1bGVzL29iamVjdC5hc3NpZ24vcG9seWZpbGwuanMiLCJub2RlX21vZHVsZXMvcHJvY2Vzcy9icm93c2VyLmpzIiwibm9kZV9tb2R1bGVzL3RzLWludGVyZmFjZS1jaGVja2VyL2Rpc3QvaW5kZXguanMiLCJub2RlX21vZHVsZXMvdHMtaW50ZXJmYWNlLWNoZWNrZXIvZGlzdC90eXBlcy5qcyIsIm5vZGVfbW9kdWxlcy90cy1pbnRlcmZhY2UtY2hlY2tlci9kaXN0L3V0aWwuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5SEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaE1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDaEVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDM0tBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDektBO0FBQ0E7QUFDQTs7O0FDRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDMWZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUNMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDMWtCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDdEpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUNqdkRBLFlBQVk7O0FBRVosSUFBSSxJQUFJLEdBQUcsT0FBTyxDQUFDLGVBQWUsQ0FBQztBQUVuQyxJQUFJLE1BQU0sR0FBRyxPQUFPLENBQUMsaUJBQWlCLENBQUM7QUFDdkMsSUFBSSxLQUFLLEdBQUcsT0FBTyxDQUFDLGdCQUFnQixDQUFDO0FBQ3JDLElBQUksYUFBYSxHQUFHLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQzs7QUFFN0M7QUFDQSxNQUFNLENBQUMsT0FBTyxHQUFHLGFBQWEsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUM7OztBQ1QxRCxZQUFZOztBQUVaO0FBQ0EsTUFBTSxDQUFDLE9BQU8sR0FBRyxRQUFRLENBQUMsU0FBUyxDQUFDLEtBQUs7OztBQ0h6QyxZQUFZOztBQUVaO0FBQ0EsTUFBTSxDQUFDLE9BQU8sR0FBRyxRQUFRLENBQUMsU0FBUyxDQUFDLElBQUk7OztBQ0h4QyxZQUFZOztBQUVaLElBQUksSUFBSSxHQUFHLE9BQU8sQ0FBQyxlQUFlLENBQUM7QUFDbkMsSUFBSSxVQUFVLEdBQUcsT0FBTyxDQUFDLGdCQUFnQixDQUFDO0FBRTFDLElBQUksS0FBSyxHQUFHLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQztBQUNyQyxJQUFJLFlBQVksR0FBRyxPQUFPLENBQUMsZUFBZSxDQUFDOztBQUUzQztBQUNBLE1BQU0sQ0FBQyxPQUFPLEdBQUcsU0FBUyxhQUFhLENBQUMsSUFBSSxFQUFFO0VBQzdDLElBQUksSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLElBQUksT0FBTyxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssVUFBVSxFQUFFO0lBQ3JELE1BQU0sSUFBSSxVQUFVLENBQUMsd0JBQXdCLENBQUM7RUFDL0M7RUFDQSxPQUFPLFlBQVksQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQztBQUN2QyxDQUFDOzs7QUNkRCxZQUFZOztBQUVaO0FBQ0EsTUFBTSxDQUFDLE9BQU8sR0FBRyxPQUFPLE9BQU8sS0FBSyxXQUFXLElBQUksT0FBTyxJQUFJLE9BQU8sQ0FBQyxLQUFLOzs7QUNIM0UsWUFBWTs7QUFFWixJQUFJLFlBQVksR0FBRyxPQUFPLENBQUMsZUFBZSxDQUFDO0FBRTNDLElBQUksYUFBYSxHQUFHLE9BQU8sQ0FBQyx5QkFBeUIsQ0FBQzs7QUFFdEQ7QUFDQSxJQUFJLFFBQVEsR0FBRyxhQUFhLENBQUMsQ0FBQyxZQUFZLENBQUMsNEJBQTRCLENBQUMsQ0FBQyxDQUFDOztBQUUxRTtBQUNBLE1BQU0sQ0FBQyxPQUFPLEdBQUcsU0FBUyxrQkFBa0IsQ0FBQyxJQUFJLEVBQUUsWUFBWSxFQUFFO0VBQ2hFO0VBQ0EsSUFBSSxTQUFTLEdBQUcscURBQXVELFlBQVksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLFlBQVksQ0FBRTtFQUMxRyxJQUFJLE9BQU8sU0FBUyxLQUFLLFVBQVUsSUFBSSxRQUFRLENBQUMsSUFBSSxFQUFFLGFBQWEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFO0lBQzFFLE9BQU8sYUFBYSxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUM7RUFDbEM7RUFDQSxPQUFPLFNBQVM7QUFDakIsQ0FBQzs7O0FDakJELFlBQVk7O0FBRVosSUFBSSxRQUFRLEdBQUcsT0FBTyxDQUFDLHlCQUF5QixDQUFDO0FBQ2pELElBQUksSUFBSSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUM7QUFFMUIsSUFBSSxnQkFBZ0I7QUFDcEIsSUFBSTtFQUNIO0VBQ0EsZ0JBQWdCLEdBQUcscURBQXVELEVBQUUsQ0FBRSxTQUFTLEtBQUssS0FBSyxDQUFDLFNBQVM7QUFDNUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxFQUFFO0VBQ1gsSUFBSSxDQUFDLENBQUMsSUFBSSxPQUFPLENBQUMsS0FBSyxRQUFRLElBQUksRUFBRSxNQUFNLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksS0FBSyxrQkFBa0IsRUFBRTtJQUNuRixNQUFNLENBQUM7RUFDUjtBQUNEOztBQUVBO0FBQ0EsSUFBSSxJQUFJLEdBQUcsQ0FBQyxDQUFDLGdCQUFnQixJQUFJLElBQUksSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsRUFBRSw0Q0FBOEMsV0FBWSxDQUFDO0FBRTNILElBQUksT0FBTyxHQUFHLE1BQU07QUFDcEIsSUFBSSxlQUFlLEdBQUcsT0FBTyxDQUFDLGNBQWM7O0FBRTVDO0FBQ0EsTUFBTSxDQUFDLE9BQU8sR0FBRyxJQUFJLElBQUksT0FBTyxJQUFJLENBQUMsR0FBRyxLQUFLLFVBQVUsR0FDcEQsUUFBUSxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQ3BCLE9BQU8sZUFBZSxLQUFLLFVBQVUsR0FDcEMsOEJBQStCLFNBQVMsU0FBUyxDQUFDLEtBQUssRUFBRTtFQUMxRDtFQUNBLE9BQU8sZUFBZSxDQUFDLEtBQUssSUFBSSxJQUFJLEdBQUcsS0FBSyxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUMvRCxDQUFDLEdBQ0MsS0FBSzs7O0FDN0JULFlBQVk7O0FBRVo7QUFDQSxJQUFJLGVBQWUsR0FBRyxNQUFNLENBQUMsY0FBYyxJQUFJLEtBQUs7QUFDcEQsSUFBSSxlQUFlLEVBQUU7RUFDcEIsSUFBSTtJQUNILGVBQWUsQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLEVBQUU7TUFBRSxLQUFLLEVBQUU7SUFBRSxDQUFDLENBQUM7RUFDdkMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxFQUFFO0lBQ1g7SUFDQSxlQUFlLEdBQUcsS0FBSztFQUN4QjtBQUNEO0FBRUEsTUFBTSxDQUFDLE9BQU8sR0FBRyxlQUFlOzs7QUNiaEMsWUFBWTs7QUFFWjtBQUNBLE1BQU0sQ0FBQyxPQUFPLEdBQUcsU0FBUzs7O0FDSDFCLFlBQVk7O0FBRVo7QUFDQSxNQUFNLENBQUMsT0FBTyxHQUFHLEtBQUs7OztBQ0h0QixZQUFZOztBQUVaO0FBQ0EsTUFBTSxDQUFDLE9BQU8sR0FBRyxVQUFVOzs7QUNIM0IsWUFBWTs7QUFFWjtBQUNBLE1BQU0sQ0FBQyxPQUFPLEdBQUcsY0FBYzs7O0FDSC9CLFlBQVk7O0FBRVo7QUFDQSxNQUFNLENBQUMsT0FBTyxHQUFHLFdBQVc7OztBQ0g1QixZQUFZOztBQUVaO0FBQ0EsTUFBTSxDQUFDLE9BQU8sR0FBRyxTQUFTOzs7QUNIMUIsWUFBWTs7QUFFWjtBQUNBLE1BQU0sQ0FBQyxPQUFPLEdBQUcsUUFBUTs7O0FDSHpCLFlBQVk7O0FBRVo7QUFDQSxNQUFNLENBQUMsT0FBTyxHQUFHLE1BQU07OztBQ0h2QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6WEEsWUFBWTs7QUFFWixJQUFJLE9BQU8sR0FBRyxPQUFPLENBQUMsaUJBQWlCLENBQUM7O0FBRXhDO0FBQ0EsTUFBTSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUMsY0FBYyxJQUFJLElBQUk7OztBQ0wvQyxZQUFZOztBQUVaO0FBQ0EsTUFBTSxDQUFDLE9BQU8sR0FBSSxPQUFPLE9BQU8sS0FBSyxXQUFXLElBQUksT0FBTyxDQUFDLGNBQWMsSUFBSyxJQUFJOzs7QUNIbkYsWUFBWTs7QUFFWixJQUFJLGVBQWUsR0FBRyxPQUFPLENBQUMsMEJBQTBCLENBQUM7QUFDekQsSUFBSSxnQkFBZ0IsR0FBRyxPQUFPLENBQUMseUJBQXlCLENBQUM7QUFFekQsSUFBSSxjQUFjLEdBQUcsT0FBTyxDQUFDLGtCQUFrQixDQUFDOztBQUVoRDtBQUNBLE1BQU0sQ0FBQyxPQUFPLEdBQUcsZUFBZSxHQUM3QixTQUFTLFFBQVEsQ0FBQyxDQUFDLEVBQUU7RUFDdEI7RUFDQSxPQUFPLGVBQWUsQ0FBQyxDQUFDLENBQUM7QUFDMUIsQ0FBQyxHQUNDLGdCQUFnQixHQUNmLFNBQVMsUUFBUSxDQUFDLENBQUMsRUFBRTtFQUN0QixJQUFJLENBQUMsQ0FBQyxJQUFLLE9BQU8sQ0FBQyxLQUFLLFFBQVEsSUFBSSxPQUFPLENBQUMsS0FBSyxVQUFXLEVBQUU7SUFDN0QsTUFBTSxJQUFJLFNBQVMsQ0FBQyx5QkFBeUIsQ0FBQztFQUMvQztFQUNBO0VBQ0EsT0FBTyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUM7QUFDM0IsQ0FBQyxHQUNDLGNBQWMsR0FDYixTQUFTLFFBQVEsQ0FBQyxDQUFDLEVBQUU7RUFDdEI7RUFDQSxPQUFPLGNBQWMsQ0FBQyxDQUFDLENBQUM7QUFDekIsQ0FBQyxHQUNDLElBQUk7OztBQzFCVCxZQUFZOztBQUVaO0FBQ0EsTUFBTSxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUMsd0JBQXdCOzs7QUNIaEQsWUFBWTs7QUFFWjtBQUNBLElBQUksS0FBSyxHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUM7QUFFN0IsSUFBSSxLQUFLLEVBQUU7RUFDVixJQUFJO0lBQ0gsS0FBSyxDQUFDLEVBQUUsRUFBRSxRQUFRLENBQUM7RUFDcEIsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxFQUFFO0lBQ1g7SUFDQSxLQUFLLEdBQUcsSUFBSTtFQUNiO0FBQ0Q7QUFFQSxNQUFNLENBQUMsT0FBTyxHQUFHLEtBQUs7OztBQ2R0QixZQUFZOztBQUVaLElBQUksVUFBVSxHQUFHLE9BQU8sTUFBTSxLQUFLLFdBQVcsSUFBSSxNQUFNO0FBQ3hELElBQUksYUFBYSxHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUM7O0FBRXRDO0FBQ0EsTUFBTSxDQUFDLE9BQU8sR0FBRyxTQUFTLGdCQUFnQixDQUFBLEVBQUc7RUFDNUMsSUFBSSxPQUFPLFVBQVUsS0FBSyxVQUFVLEVBQUU7SUFBRSxPQUFPLEtBQUs7RUFBRTtFQUN0RCxJQUFJLE9BQU8sTUFBTSxLQUFLLFVBQVUsRUFBRTtJQUFFLE9BQU8sS0FBSztFQUFFO0VBQ2xELElBQUksT0FBTyxVQUFVLENBQUMsS0FBSyxDQUFDLEtBQUssUUFBUSxFQUFFO0lBQUUsT0FBTyxLQUFLO0VBQUU7RUFDM0QsSUFBSSxPQUFPLE1BQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxRQUFRLEVBQUU7SUFBRSxPQUFPLEtBQUs7RUFBRTtFQUV2RCxPQUFPLGFBQWEsQ0FBQyxDQUFDO0FBQ3ZCLENBQUM7OztBQ2JELFlBQVk7O0FBRVo7QUFDQTtBQUNBLE1BQU0sQ0FBQyxPQUFPLEdBQUcsU0FBUyxVQUFVLENBQUEsRUFBRztFQUN0QyxJQUFJLE9BQU8sTUFBTSxLQUFLLFVBQVUsSUFBSSxPQUFPLE1BQU0sQ0FBQyxxQkFBcUIsS0FBSyxVQUFVLEVBQUU7SUFBRSxPQUFPLEtBQUs7RUFBRTtFQUN4RyxJQUFJLE9BQU8sTUFBTSxDQUFDLFFBQVEsS0FBSyxRQUFRLEVBQUU7SUFBRSxPQUFPLElBQUk7RUFBRTs7RUFFeEQ7RUFDQSxJQUFJLEdBQUcsR0FBRyxDQUFDLENBQUM7RUFDWixJQUFJLEdBQUcsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDO0VBQ3hCLElBQUksTUFBTSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUM7RUFDeEIsSUFBSSxPQUFPLEdBQUcsS0FBSyxRQUFRLEVBQUU7SUFBRSxPQUFPLEtBQUs7RUFBRTtFQUU3QyxJQUFJLE1BQU0sQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxpQkFBaUIsRUFBRTtJQUFFLE9BQU8sS0FBSztFQUFFO0VBQy9FLElBQUksTUFBTSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLGlCQUFpQixFQUFFO0lBQUUsT0FBTyxLQUFLO0VBQUU7O0VBRWxGO0VBQ0E7RUFDQTtFQUNBOztFQUVBO0VBQ0E7O0VBRUEsSUFBSSxNQUFNLEdBQUcsRUFBRTtFQUNmLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxNQUFNO0VBQ2pCLEtBQUssSUFBSSxDQUFDLElBQUksR0FBRyxFQUFFO0lBQUUsT0FBTyxLQUFLO0VBQUUsQ0FBQyxDQUFDO0VBQ3JDLElBQUksT0FBTyxNQUFNLENBQUMsSUFBSSxLQUFLLFVBQVUsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUU7SUFBRSxPQUFPLEtBQUs7RUFBRTtFQUV4RixJQUFJLE9BQU8sTUFBTSxDQUFDLG1CQUFtQixLQUFLLFVBQVUsSUFBSSxNQUFNLENBQUMsbUJBQW1CLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtJQUFFLE9BQU8sS0FBSztFQUFFO0VBRXRILElBQUksSUFBSSxHQUFHLE1BQU0sQ0FBQyxxQkFBcUIsQ0FBQyxHQUFHLENBQUM7RUFDNUMsSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLENBQUMsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssR0FBRyxFQUFFO0lBQUUsT0FBTyxLQUFLO0VBQUU7RUFFMUQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsb0JBQW9CLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsRUFBRTtJQUFFLE9BQU8sS0FBSztFQUFFO0VBRTNFLElBQUksT0FBTyxNQUFNLENBQUMsd0JBQXdCLEtBQUssVUFBVSxFQUFFO0lBQzFEO0lBQ0EsSUFBSSxVQUFVLEdBQUcsaUNBQW1DLE1BQU0sQ0FBQyx3QkFBd0IsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFFO0lBQzlGLElBQUksVUFBVSxDQUFDLEtBQUssS0FBSyxNQUFNLElBQUksVUFBVSxDQUFDLFVBQVUsS0FBSyxJQUFJLEVBQUU7TUFBRSxPQUFPLEtBQUs7SUFBRTtFQUNwRjtFQUVBLE9BQU8sSUFBSTtBQUNaLENBQUM7OztBQzVDRCxZQUFZOztBQUVaLElBQUksSUFBSSxHQUFHLFFBQVEsQ0FBQyxTQUFTLENBQUMsSUFBSTtBQUNsQyxJQUFJLE9BQU8sR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDLGNBQWM7QUFDN0MsSUFBSSxJQUFJLEdBQUcsT0FBTyxDQUFDLGVBQWUsQ0FBQzs7QUFFbkM7QUFDQSxNQUFNLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQzs7O0FDUHpDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckZBLFlBQVk7O0FBRVo7QUFDQSxNQUFNLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxHQUFHOzs7QUNIekIsWUFBWTs7QUFFWjtBQUNBLE1BQU0sQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLEtBQUs7OztBQ0gzQixZQUFZOztBQUVaO0FBQ0EsTUFBTSxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUMsS0FBSyxJQUFJLFNBQVMsS0FBSyxDQUFDLENBQUMsRUFBRTtFQUNsRCxPQUFPLENBQUMsS0FBSyxDQUFDO0FBQ2YsQ0FBQzs7O0FDTEQsWUFBWTs7QUFFWjtBQUNBLE1BQU0sQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLEdBQUc7OztBQ0h6QixZQUFZOztBQUVaO0FBQ0EsTUFBTSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsR0FBRzs7O0FDSHpCLFlBQVk7O0FBRVo7QUFDQSxNQUFNLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxHQUFHOzs7QUNIekIsWUFBWTs7QUFFWjtBQUNBLE1BQU0sQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLEtBQUs7OztBQ0gzQixZQUFZOztBQUVaLElBQUksTUFBTSxHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUM7O0FBRS9CO0FBQ0EsTUFBTSxDQUFDLE9BQU8sR0FBRyxTQUFTLElBQUksQ0FBQyxNQUFNLEVBQUU7RUFDdEMsSUFBSSxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksTUFBTSxLQUFLLENBQUMsRUFBRTtJQUNuQyxPQUFPLE1BQU07RUFDZDtFQUNBLE9BQU8sTUFBTSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDNUIsQ0FBQzs7O0FDVkQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4TEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDbE9BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUM5cEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24oKXtmdW5jdGlvbiByKGUsbix0KXtmdW5jdGlvbiBvKGksZil7aWYoIW5baV0pe2lmKCFlW2ldKXt2YXIgYz1cImZ1bmN0aW9uXCI9PXR5cGVvZiByZXF1aXJlJiZyZXF1aXJlO2lmKCFmJiZjKXJldHVybiBjKGksITApO2lmKHUpcmV0dXJuIHUoaSwhMCk7dmFyIGE9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitpK1wiJ1wiKTt0aHJvdyBhLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsYX12YXIgcD1uW2ldPXtleHBvcnRzOnt9fTtlW2ldWzBdLmNhbGwocC5leHBvcnRzLGZ1bmN0aW9uKHIpe3ZhciBuPWVbaV1bMV1bcl07cmV0dXJuIG8obnx8cil9LHAscC5leHBvcnRzLHIsZSxuLHQpfXJldHVybiBuW2ldLmV4cG9ydHN9Zm9yKHZhciB1PVwiZnVuY3Rpb25cIj09dHlwZW9mIHJlcXVpcmUmJnJlcXVpcmUsaT0wO2k8dC5sZW5ndGg7aSsrKW8odFtpXSk7cmV0dXJuIG99cmV0dXJuIHJ9KSgpIiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLkFQSVN0YXR1cyA9IHZvaWQgMDtcbnZhciBfdXRpbHMgPSByZXF1aXJlKFwiLi4vLi4vdXRpbHMuanNcIik7XG52YXIgX3V0aWxzRG9tID0gcmVxdWlyZShcIi4vdXRpbHMtZG9tLmpzXCIpO1xuLy8gSG9tZWJyaWRnZSBwbHVnaW4gZm9yIEhvbWUgQ29ubmVjdCBob21lIGFwcGxpYW5jZXNcbi8vIENvcHlyaWdodCDCqSAyMDI0IEFsZXhhbmRlciBUaG91a3lkaWRlc1xuXG4vLyBVUkwgZm9yIHRoZSBzZXJ2ZXIgc3RhdHVzIGltYWdlXG5jb25zdCBTVEFUVVNfVVJMID0gJ2h0dHBzOi8vaG9tZWNvbm5lY3QudGhvdWt5LmNvLnVrL2FwaS9pbWFnZXMvcGx1Z2luLXN0YXR1cy5zdmcnO1xuLy8gV2FybiBmb3IgZXJyb3JzIG1vcmUgcmVjZW50IHRoYW4gdGhpc1xuY29uc3QgU1RBVFVTX1NJTkNFID0gMjQgKiA2MCAqIDYwICogX3V0aWxzLk1TO1xuLy8gSW50ZXJ2YWwgdG8gcG9sbCBmb3IgdXBkYXRlcyAoaWYgdGhlcmUgYXJlIGlzc3VlcylcbmNvbnN0IFBPTExfSU5URVJWQUwgPSAyLjUgKiA2MCAqIF91dGlscy5NUztcbi8vIEhvbWUgQ29ubmVjdCBBUEkgc2VydmVyIHN0YXR1c1xuY2xhc3MgQVBJU3RhdHVzIHtcbiAgbG9nO1xuICAvLyBXaGVuIHdhcyB0aGUgc3RhdHVzIGxhc3QgdXBkYXRlZFxuICBsYXN0VXBkYXRlZDtcbiAgLy8gQ3JlYXRlIGEgbmV3IEFQSSBzZXJ2ZXIgc3RhdHVzIGNoZWNrZXJcbiAgY29uc3RydWN0b3IobG9nKSB7XG4gICAgdGhpcy5sb2cgPSBsb2c7XG4gICAgdGhpcy5wb2xsU3RhdHVzKCk7XG4gIH1cbiAgLy8gQ2hlY2sgdGhlIHN0YXR1cyBvZiB0aGUgSG9tZSBDb25uZWN0IEFQSSBzZXJ2ZXJzXG4gIGFzeW5jIHBvbGxTdGF0dXMoKSB7XG4gICAgLy8gQXR0ZW1wdCB0byBmZXRjaCB0aGUgc3RhdHVzIGltYWdlXG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaChTVEFUVVNfVVJMKTtcbiAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgICB0aGlzLmxvZy53YXJuKCdjaGVja1N0YXR1cyBmZXRjaCcsIHJlc3BvbnNlLnN0YXR1c1RleHQpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBzdmcgPSBhd2FpdCByZXNwb25zZS50ZXh0KCk7XG4gICAgLy8gQXR0ZW1wdCB0byBwYXJzZSB0aGUgc3RhdHVzIGhlYWRlclxuICAgIGxldCBzdGF0dXM7XG4gICAgdHJ5IHtcbiAgICAgIHN0YXR1cyA9IEpTT04ucGFyc2UocmVzcG9uc2UuaGVhZGVycy5nZXQoJ1gtU2VydmVyLVN0YXR1cycpID8/ICcnKTtcbiAgICAgICgwLCBfdXRpbHMuYXNzZXJ0SXNCb29sZWFuKShzdGF0dXMudXApO1xuICAgICAgKDAsIF91dGlscy5hc3NlcnRJc051bWJlcikoc3RhdHVzLnNpbmNlKTtcbiAgICAgICgwLCBfdXRpbHMuYXNzZXJ0SXNOdW1iZXIpKHN0YXR1cy51cGRhdGVkKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHRoaXMubG9nLndhcm4oJ2NoZWNrU3RhdHVzIFgtU2VydmVyLVN0YXR1cycsIGVycik7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIFVwZGF0ZSB0aGUgZGlzcGxheWVkIHN0YXR1cywgaWYgaXQgaGFzIGNoYW5nZWRcbiAgICBsZXQgcG9sbEFnYWluID0gdHJ1ZTtcbiAgICBpZiAodGhpcy5sYXN0VXBkYXRlZCAhPT0gc3RhdHVzLnVwZGF0ZWQpIHtcbiAgICAgIHRoaXMubGFzdFVwZGF0ZWQgPSBzdGF0dXMudXBkYXRlZDtcbiAgICAgIHBvbGxBZ2FpbiA9IHRoaXMuc2hvd1N0YXR1cyhzdmcsIHN0YXR1cyk7XG4gICAgfVxuICAgIC8vIFBlcmlvZGljYWxseSBwb2xsIHRoZSBzdGF0dXMgaWYgdGhlcmUgYXJlIHNlcnZlciBpc3N1ZXNcbiAgICBpZiAocG9sbEFnYWluKSBzZXRUaW1lb3V0KCgpID0+IHRoaXMucG9sbFN0YXR1cygpLCBQT0xMX0lOVEVSVkFMKTtcbiAgfVxuICAvLyBEaXNwbGF5IHRoZSBsYXRlc3Qgc3RhdHVzIG9mIHRoZSBIb21lIENvbm5lY3QgQVBJIHNlcnZlcnNcbiAgc2hvd1N0YXR1cyhzdmcsIHN0YXR1cykge1xuICAgIC8vIERpc3BsYXkgdGhlIGFwcHJvcHJpYXRlIHN1bW1hcnlcbiAgICAoMCwgX3V0aWxzRG9tLmdldEVsZW1lbnRCeUlkKSgnaGMtYXBpLXVwJykuaGlkZGVuID0gIXN0YXR1cy51cDtcbiAgICAoMCwgX3V0aWxzRG9tLmdldEVsZW1lbnRCeUlkKSgnaGMtYXBpLXVwMicpLmhpZGRlbiA9ICFzdGF0dXMudXA7XG4gICAgKDAsIF91dGlsc0RvbS5nZXRFbGVtZW50QnlJZCkoJ2hjLWFwaS1kb3duJykuaGlkZGVuID0gc3RhdHVzLnVwO1xuICAgICgwLCBfdXRpbHNEb20uZ2V0RWxlbWVudEJ5SWQpKCdoYy1hcGktZG93bjInKS5oaWRkZW4gPSBzdGF0dXMudXA7XG4gICAgLy8gQWRkIHRoZSBkZXRhaWxlZCBzdGF0dXNcbiAgICAoMCwgX3V0aWxzRG9tLmdldEVsZW1lbnRCeUlkKSgnaGMtYXBpLXNpbmNlJykuaW5uZXJUZXh0ID0gdGhpcy5mb3JtYXREYXRlVGltZShzdGF0dXMuc2luY2UpO1xuICAgIC8vIEFkZCB0aGUgcmV0cmlldmVkIHN0YXR1cyBpbWFnZVxuICAgICgwLCBfdXRpbHNEb20uZ2V0RWxlbWVudEJ5SWQpKCdoYy1hcGktc3ZnJykuaW5uZXJIVE1MID0gc3ZnO1xuICAgIC8vIFNob3cgb3IgaGlkZSB0aGUgc3RhdHVzIGFzIGFwcHJvcHJpYXRlXG4gICAgY29uc3Qgc2hvd1N0YXR1cyA9ICFzdGF0dXMudXAgfHwgRGF0ZS5ub3coKSA8IHN0YXR1cy5zaW5jZSArIFNUQVRVU19TSU5DRTtcbiAgICAoMCwgX3V0aWxzRG9tLmdldEVsZW1lbnRCeUlkKSgnaGMtYXBpLXN0YXR1cycpLmhpZGRlbiA9ICFzaG93U3RhdHVzO1xuICAgIHJldHVybiBzaG93U3RhdHVzO1xuICB9XG4gIC8vIEZvcm1hdCBhIGRhdGUvdGltZVxuICBmb3JtYXREYXRlVGltZShkYXRlKSB7XG4gICAgcmV0dXJuIG5ldyBEYXRlKGRhdGUpLnRvTG9jYWxlU3RyaW5nKHVuZGVmaW5lZCwge1xuICAgICAgd2Vla2RheTogJ2xvbmcnLFxuICAgICAgbW9udGg6ICdsb25nJyxcbiAgICAgIGRheTogJ251bWVyaWMnLFxuICAgICAgaG91cjogJ251bWVyaWMnLFxuICAgICAgbWludXRlOiAnMi1kaWdpdCcsXG4gICAgICB0aW1lWm9uZU5hbWU6ICdzaG9ydCdcbiAgICB9KTtcbiAgfVxufVxuZXhwb3J0cy5BUElTdGF0dXMgPSBBUElTdGF0dXM7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldD11dGYtODtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnVZVzFsY3lJNld5SmZkWFJwYkhNaUxDSnlaWEYxYVhKbElpd2lYM1YwYVd4elJHOXRJaXdpVTFSQlZGVlRYMVZTVENJc0lsTlVRVlJWVTE5VFNVNURSU0lzSWsxVElpd2lVRTlNVEY5SlRsUkZVbFpCVENJc0lrRlFTVk4wWVhSMWN5SXNJbXh2WnlJc0lteGhjM1JWY0dSaGRHVmtJaXdpWTI5dWMzUnlkV04wYjNJaUxDSndiMnhzVTNSaGRIVnpJaXdpY21WemNHOXVjMlVpTENKbVpYUmphQ0lzSW05cklpd2lkMkZ5YmlJc0luTjBZWFIxYzFSbGVIUWlMQ0p6ZG1jaUxDSjBaWGgwSWl3aWMzUmhkSFZ6SWl3aVNsTlBUaUlzSW5CaGNuTmxJaXdpYUdWaFpHVnljeUlzSW1kbGRDSXNJbUZ6YzJWeWRFbHpRbTl2YkdWaGJpSXNJblZ3SWl3aVlYTnpaWEowU1hOT2RXMWlaWElpTENKemFXNWpaU0lzSW5Wd1pHRjBaV1FpTENKbGNuSWlMQ0p3YjJ4c1FXZGhhVzRpTENKemFHOTNVM1JoZEhWeklpd2ljMlYwVkdsdFpXOTFkQ0lzSW1kbGRFVnNaVzFsYm5SQ2VVbGtJaXdpYUdsa1pHVnVJaXdpYVc1dVpYSlVaWGgwSWl3aVptOXliV0YwUkdGMFpWUnBiV1VpTENKcGJtNWxja2hVVFV3aUxDSkVZWFJsSWl3aWJtOTNJaXdpWkdGMFpTSXNJblJ2VEc5allXeGxVM1J5YVc1bklpd2lkVzVrWldacGJtVmtJaXdpZDJWbGEyUmhlU0lzSW0xdmJuUm9JaXdpWkdGNUlpd2lhRzkxY2lJc0ltMXBiblYwWlNJc0luUnBiV1ZhYjI1bFRtRnRaU0lzSW1WNGNHOXlkSE1pWFN3aWMyOTFjbU5sY3lJNld5SXVMaTh1TGk4dUxpOXpjbU12YUc5dFpXSnlhV1JuWlMxMWFTOXdkV0pzYVdNdllYQnBMWE4wWVhSMWN5NTBjeUpkTENKemIzVnlZMlZ6UTI5dWRHVnVkQ0k2VzI1MWJHeGRMQ0p0WVhCd2FXNW5jeUk2SWpzN096czdPMEZCU1VFc1NVRkJRVUVzVFVGQlFTeEhRVUZCUXl4UFFVRkJPMEZCUTBFc1NVRkJRVU1zVTBGQlFTeEhRVUZCUkN4UFFVRkJPMEZCVEVFN1FVRkRRVHM3UVVGTlFUdEJRVU5CTEUxQlFVMUZMRlZCUVZVc1IwRkJSeXdyUkVGQkswUTdRVUZGYkVZN1FVRkRRU3hOUVVGTlF5eFpRVUZaTEVkQlFVY3NSVUZCUlN4SFFVRkhMRVZCUVVVc1IwRkJSeXhGUVVGRkxFZEJRVWRETEZOQlFVVTdRVUZGZEVNN1FVRkRRU3hOUVVGTlF5eGhRVUZoTEVkQlFVY3NSMEZCUnl4SFFVRkhMRVZCUVVVc1IwRkJSMFFzVTBGQlJUdEJRVk51UXp0QlFVTk5MRTFCUVU5RkxGTkJRVk03UlVGTlIwTXNSMEZCUVR0RlFVcHlRanRGUVVOQlF5eFhRVUZYTzBWQlJWZzdSVUZEUVVNc1dVRkJjVUpHTEVkQlFWYzdTVUZCV0N4TFFVRkJRU3hIUVVGSExFZEJRVWhCTEVkQlFVYzdTVUZEY0VJc1NVRkJTU3hEUVVGRFJ5eFZRVUZWTEVWQlFVVTdSVUZEY2tJN1JVRkZRVHRGUVVOQkxFMUJRVTFCTEZWQlFWVkJMRU5CUVVFN1NVRkRXanRKUVVOQkxFMUJRVTFETEZGQlFWRXNSMEZCUnl4TlFVRk5ReXhMUVVGTExFTkJRVU5XTEZWQlFWVXNRMEZCUXp0SlFVTjRReXhKUVVGSkxFTkJRVU5UTEZGQlFWRXNRMEZCUTBVc1JVRkJSU3hGUVVGRk8wMUJRMlFzU1VGQlNTeERRVUZEVGl4SFFVRkhMRU5CUVVOUExFbEJRVWtzUTBGQlF5eHRRa0ZCYlVJc1JVRkJSVWdzVVVGQlVTeERRVUZEU1N4VlFVRlZMRU5CUVVNN1RVRkRka1E3U1VGRFNqdEpRVU5CTEUxQlFVMURMRWRCUVVjc1IwRkJSeXhOUVVGTlRDeFJRVUZSTEVOQlFVTk5MRWxCUVVrc1JVRkJSVHRKUVVWcVF6dEpRVU5CTEVsQlFVbERMRTFCUVUwN1NVRkRWaXhKUVVGSk8wMUJRMEZCTEUxQlFVMHNSMEZCUjBNc1NVRkJTU3hEUVVGRFF5eExRVUZMTEVOQlFVTlVMRkZCUVZFc1EwRkJRMVVzVDBGQlR5eERRVUZEUXl4SFFVRkhMRU5CUVVNc2FVSkJRV2xDTEVOQlFVTXNTVUZCU1N4RlFVRkZMRU5CUVdsQ08wMUJRMnhHTEVsQlFVRkRMSE5DUVVGbExFVkJRVU5NTEUxQlFVMHNRMEZCUTAwc1JVRkJSU3hEUVVGRE8wMUJRekZDTEVsQlFVRkRMSEZDUVVGakxFVkJRVU5RTEUxQlFVMHNRMEZCUTFFc1MwRkJTeXhEUVVGRE8wMUJRelZDTEVsQlFVRkVMSEZDUVVGakxFVkJRVU5RTEUxQlFVMHNRMEZCUTFNc1QwRkJUeXhEUVVGRE8wbEJRMnhETEVOQlFVTXNRMEZCUXl4UFFVRlBReXhIUVVGSExFVkJRVVU3VFVGRFZpeEpRVUZKTEVOQlFVTnlRaXhIUVVGSExFTkJRVU5QTEVsQlFVa3NRMEZCUXl3MlFrRkJOa0lzUlVGQlJXTXNSMEZCUnl4RFFVRkRPMDFCUTJwRU8wbEJRMG83U1VGRlFUdEpRVU5CTEVsQlFVbERMRk5CUVZNc1IwRkJSeXhKUVVGSk8wbEJRM0JDTEVsQlFVa3NTVUZCU1N4RFFVRkRja0lzVjBGQlZ5eExRVUZMVlN4TlFVRk5MRU5CUVVOVExFOUJRVThzUlVGQlJUdE5RVU55UXl4SlFVRkpMRU5CUVVOdVFpeFhRVUZYTEVkQlFVZFZMRTFCUVUwc1EwRkJRMU1zVDBGQlR6dE5RVU5xUTBVc1UwRkJVeXhIUVVGSExFbEJRVWtzUTBGQlEwTXNWVUZCVlN4RFFVRkRaQ3hIUVVGSExFVkJRVVZGTEUxQlFVMHNRMEZCUXp0SlFVTTFRenRKUVVWQk8wbEJRMEVzU1VGQlNWY3NVMEZCVXl4RlFVRkZSU3hWUVVGVkxFTkJRVU1zVFVGQlRTeEpRVUZKTEVOQlFVTnlRaXhWUVVGVkxFVkJRVVVzUlVGQlJVd3NZVUZCWVN4RFFVRkRPMFZCUTNKRk8wVkJSVUU3UlVGRFFYbENMRlZCUVZWQkxFTkJRVU5rTEVkQlFWY3NSVUZCUlVVc1RVRkJiMEk3U1VGRGVFTTdTVUZEUVN4SlFVRkJZeXgzUWtGQll5eEZRVUZETEZkQlFWY3NRMEZCUXl4RFFVRkRReXhOUVVGTkxFZEJRVWNzUTBGQlEyWXNUVUZCVFN4RFFVRkRUU3hGUVVGRk8wbEJReTlETEVsQlFVRlJMSGRDUVVGakxFVkJRVU1zV1VGQldTeERRVUZETEVOQlFVTkRMRTFCUVUwc1IwRkJSeXhEUVVGRFppeE5RVUZOTEVOQlFVTk5MRVZCUVVVN1NVRkRhRVFzU1VGQlFWRXNkMEpCUVdNc1JVRkJReXhoUVVGaExFTkJRVU1zUTBGQlEwTXNUVUZCVFN4SFFVRkhaaXhOUVVGTkxFTkJRVU5OTEVWQlFVVTdTVUZEYUVRc1NVRkJRVkVzZDBKQlFXTXNSVUZCUXl4alFVRmpMRU5CUVVNc1EwRkJRME1zVFVGQlRTeEhRVUZIWml4TlFVRk5MRU5CUVVOTkxFVkJRVVU3U1VGRmFrUTdTVUZEUVN4SlFVRkJVU3gzUWtGQll5eEZRVUZETEdOQlFXTXNRMEZCUXl4RFFVRkRSU3hUUVVGVExFZEJRVWNzU1VGQlNTeERRVUZEUXl4alFVRmpMRU5CUVVOcVFpeE5RVUZOTEVOQlFVTlJMRXRCUVVzc1EwRkJRenRKUVVVMVJUdEpRVU5CTEVsQlFVRk5MSGRDUVVGakxFVkJRVU1zV1VGQldTeERRVUZETEVOQlFVTkpMRk5CUVZNc1IwRkJSM0JDTEVkQlFVYzdTVUZGTlVNN1NVRkRRU3hOUVVGTll5eFZRVUZWTEVkQlFVY3NRMEZCUTFvc1RVRkJUU3hEUVVGRFRTeEZRVUZGTEVsQlFVbGhMRWxCUVVrc1EwRkJRME1zUjBGQlJ5eEZRVUZGTEVkQlFVZHdRaXhOUVVGTkxFTkJRVU5STEV0QlFVc3NSMEZCUjNaQ0xGbEJRVms3U1VGRGVrVXNTVUZCUVRaQ0xIZENRVUZqTEVWQlFVTXNaVUZCWlN4RFFVRkRMRU5CUVVORExFMUJRVTBzUjBGQlJ5eERRVUZEU0N4VlFVRlZPMGxCUTNCRUxFOUJRVTlCTEZWQlFWVTdSVUZEY2tJN1JVRkZRVHRGUVVOQlN5eGpRVUZqUVN4RFFVRkRTU3hKUVVGWk8wbEJRM1pDTEU5QlFVOHNTVUZCU1VZc1NVRkJTU3hEUVVGRFJTeEpRVUZKTEVOQlFVTXNRMEZCUTBNc1kwRkJZeXhEUVVGRFF5eFRRVUZUTEVWQlFVVTdUVUZETlVORExFOUJRVThzUlVGQlV5eE5RVUZOTzAxQlEzUkNReXhMUVVGTExFVkJRVmNzVFVGQlRUdE5RVU4wUWtNc1IwRkJSeXhGUVVGaExGTkJRVk03VFVGRGVrSkRMRWxCUVVrc1JVRkJXU3hUUVVGVE8wMUJRM3BDUXl4TlFVRk5MRVZCUVZVc1UwRkJVenROUVVONlFrTXNXVUZCV1N4RlFVRkpPMHRCUTI1Q0xFTkJRVU03UlVGRFRqczdRVUZEU0VNc1QwRkJRU3hEUVVGQk1VTXNVMEZCUVN4SFFVRkJRU3hUUVVGQklpd2lhV2R1YjNKbFRHbHpkQ0k2VzExOSIsIlwidXNlIHN0cmljdFwiO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5DYXJkcyA9IHZvaWQgMDtcbnZhciBfdXRpbHMgPSByZXF1aXJlKFwiLi4vLi4vdXRpbHMuanNcIik7XG52YXIgX3V0aWxzRG9tID0gcmVxdWlyZShcIi4vdXRpbHMtZG9tLmpzXCIpO1xuLy8gSG9tZWJyaWRnZSBwbHVnaW4gZm9yIEhvbWUgQ29ubmVjdCBob21lIGFwcGxpYW5jZXNcbi8vIENvcHlyaWdodCDCqSAyMDIzIEFsZXhhbmRlciBUaG91a3lkaWRlc1xuXG4vLyBDYXJkcyB0byBzZWxlY3QgZ2xvYmFsIG9yIHBlci1hcHBsaWFuY2UgY29uZmlndXJhdGlvblxuY2xhc3MgQ2FyZHMge1xuICBsb2c7XG4gIC8vIEhUTUwgZWxlbWVudCB0aGF0IGhhcyB0aGUgY2FyZHMgYXMgY2hpbGRyZW5cbiAgcGFyZW50RWxlbWVudDtcbiAgLy8gQ3VycmVudCBjYXJkc1xuICBub25BcHBsaWFuY2VDYXJkcyA9IFtdO1xuICBhcHBsaWFuY2VDYXJkcyA9IFtdO1xuICAvLyBUaGUgY3VycmVudGx5IHNlbGVjdGVkIGNhcmRcbiAgc2VsZWN0ZWRDYXJkSWQ7XG4gIG9uU2VsZWN0O1xuICAvLyBDb25zdHJ1Y3QgYSBuZXcgY2FyZHMgaGFuZGxlclxuICBjb25zdHJ1Y3Rvcihsb2cpIHtcbiAgICB0aGlzLmxvZyA9IGxvZztcbiAgICB0aGlzLnBhcmVudEVsZW1lbnQgPSAoMCwgX3V0aWxzRG9tLmdldEVsZW1lbnRCeUlkKSgnaGMtYXBwbGlhbmNlLWNhcmRzJyk7XG4gIH1cbiAgLy8gVXBkYXRlIHRoZSBsaXN0IG9mIG5vbi1hcHBsaWFuY2UgY2FyZHNcbiAgc2V0Tm9uQXBwbGlhbmNlcyhjYXJkcykge1xuICAgIHRoaXMubm9uQXBwbGlhbmNlQ2FyZHMgPSBjYXJkcztcbiAgICB0aGlzLnVwZGF0ZUNhcmRzKCk7XG4gIH1cbiAgLy8gVXBkYXRlIHRoZSBsaXN0IG9mIGFwcGxpYW5jZXNcbiAgc2V0QXBwbGlhbmNlcyhhcHBsaWFuY2VzKSB7XG4gICAgLy8gQ29udmVydCB0aGUgYXBwbGlhbmNlcyB0byBjYXJkIGRlc2NyaXB0aW9uc1xuICAgIGNvbnN0IGFwcGxpYW5jZUNhcmRzID0gYXBwbGlhbmNlcy5tYXAoYXBwbGlhbmNlID0+ICh7XG4gICAgICBpZDogYXBwbGlhbmNlLmhhSWQsXG4gICAgICBpY29uOiBhcHBsaWFuY2UudHlwZS50b0xvY2FsZUxvd2VyQ2FzZSgpLFxuICAgICAgbmFtZTogYXBwbGlhbmNlLm5hbWUsXG4gICAgICBkZXRhaWw6IGAke2FwcGxpYW5jZS5icmFuZH0gJHthcHBsaWFuY2UuZW51bWJlcn1gXG4gICAgfSkpO1xuICAgIGFwcGxpYW5jZUNhcmRzLnNvcnQoKGEsIGIpID0+IGEubmFtZS5sb2NhbGVDb21wYXJlKGIubmFtZSkpO1xuICAgIC8vIENoZWNrIHdoZXRoZXIgdGhlIGxpc3Qgb2YgYXBwbGlhbmNlcyBoYXMgY2hhbmdlZFxuICAgIGlmIChKU09OLnN0cmluZ2lmeShhcHBsaWFuY2VDYXJkcykgIT09IEpTT04uc3RyaW5naWZ5KHRoaXMuYXBwbGlhbmNlQ2FyZHMpKSB7XG4gICAgICB0aGlzLmFwcGxpYW5jZUNhcmRzID0gYXBwbGlhbmNlQ2FyZHM7XG4gICAgICB0aGlzLnVwZGF0ZUNhcmRzKCk7XG4gICAgfVxuICB9XG4gIC8vIFVwZGF0ZSB0aGUgbGlzdCBvZiBjYXJkcyBhbmQgcmVzdG9yZSB0aGUgc2VsZWN0aW9uLCBpZiBzdGlsbCB2YWxpZFxuICB1cGRhdGVDYXJkcygpIHtcbiAgICAvLyBSZXBsYWNlIHRoZSBleGlzdGluZyBjYXJkcyB3aXRoIG5ldyBvbmVzXG4gICAgY29uc3QgYWxsQ2FyZHMgPSBbLi4udGhpcy5ub25BcHBsaWFuY2VDYXJkcywgLi4udGhpcy5hcHBsaWFuY2VDYXJkc107XG4gICAgdGhpcy5wYXJlbnRFbGVtZW50LnJlcGxhY2VDaGlsZHJlbiguLi5hbGxDYXJkcy5tYXAoY2FyZCA9PiB0aGlzLm1ha2VDYXJkKGNhcmQpKSk7XG4gICAgdGhpcy5wYXJlbnRFbGVtZW50LmhpZGRlbiA9ICFhbGxDYXJkcy5sZW5ndGg7XG4gICAgLy8gUmVzdG9yZSBhbnkgcHJldmlvdXMgc2VsZWN0aW9uXG4gICAgdGhpcy5zZWxlY3RDYXJkKHRoaXMuc2VsZWN0ZWRDYXJkSWQpO1xuICB9XG4gIC8vIENyZWF0ZSBhIG5ldyBjYXJkXG4gIG1ha2VDYXJkKHtcbiAgICBpZCxcbiAgICBpY29uLFxuICAgIG5hbWUsXG4gICAgZGV0YWlsXG4gIH0pIHtcbiAgICAvLyBDcmVhdGUgYSBuZXcgY2FyZCBmcm9tIHRoZSB0ZW1wbGF0ZVxuICAgIGlmIChkZXRhaWwgPT09IHVuZGVmaW5lZCkgZGV0YWlsID0gJ8KgJzsgLy8gKG5vbi1icmVha2luZyBzcGFjZSlcbiAgICBjb25zdCBjYXJkID0gKDAsIF91dGlsc0RvbS5jbG9uZVRlbXBsYXRlKSgnaGMtYXBwbGlhbmNlLWNhcmQnLCB7XG4gICAgICBuYW1lLFxuICAgICAgZGV0YWlsXG4gICAgfSk7XG4gICAgdGhpcy5sb2FkQ2FyZEljb24oKDAsIF91dGlsc0RvbS5nZXRTbG90KShjYXJkLCAnaWNvbicpLCBgLi9pbWFnZXMvaWNvbi0ke2ljb259LnN2Z2AsIGlkKTtcbiAgICAvLyBIYW5kbGUgY2FyZCBzZWxlY3Rpb25cbiAgICBjb25zdCBlbGVtZW50ID0gY2FyZC5jaGlsZHJlblswXTtcbiAgICAoMCwgX3V0aWxzLmFzc2VydElzSW5zdGFuY2VPZikoZWxlbWVudCwgSFRNTEVsZW1lbnQpO1xuICAgIGVsZW1lbnQuZGF0YXNldC5pZCA9IGlkO1xuICAgIGVsZW1lbnQub25jbGljayA9ICgpID0+IHtcbiAgICAgIHRoaXMuc2VsZWN0Q2FyZChpZCk7XG4gICAgfTtcbiAgICByZXR1cm4gY2FyZDtcbiAgfVxuICAvLyBMb2FkIHRoZSBpY29uIGltYWdlIGZvciBhIGNhcmRcbiAgYXN5bmMgbG9hZENhcmRJY29uKGVsZW1lbnQsIHVybCwgaWQpIHtcbiAgICB0cnkge1xuICAgICAgLy8gTG9hZCB0aGUgaWNvbiBhbmQgYWRkIGl0IHRvIHRoZSBjYXJkXG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKHVybCk7XG4gICAgICBpZiAoIXJlc3BvbnNlLm9rKSB0aHJvdyBuZXcgRXJyb3IoYEZhaWxlZCB0byBmZXRjaCBpY29uICR7cmVzcG9uc2UudXJsfTogJHtyZXNwb25zZS5zdGF0dXNUZXh0fWApO1xuICAgICAgZWxlbWVudC5pbm5lckhUTUwgPSBhd2FpdCByZXNwb25zZS50ZXh0KCk7XG4gICAgICAvLyBDaGFuZ2UgdGhlIGdyb3VwIChsYXllcikgSURzIHRvIGNsYXNzZXNcbiAgICAgIGVsZW1lbnQucXVlcnlTZWxlY3RvckFsbCgnZ1tpZF0nKS5mb3JFYWNoKGdyb3VwID0+IHtcbiAgICAgICAgY29uc3QgaWQgPSBncm91cC5nZXRBdHRyaWJ1dGUoJ2lkJyk7XG4gICAgICAgICgwLCBfdXRpbHMuYXNzZXJ0SXNEZWZpbmVkKShpZCk7XG4gICAgICAgIGdyb3VwLnJlbW92ZUF0dHJpYnV0ZSgnaWQnKTtcbiAgICAgICAgZ3JvdXAuY2xhc3NMaXN0LmFkZChpZCk7XG4gICAgICB9KTtcbiAgICAgIC8vIEFzc2lnbiB1bmlxdWUgSURzIHRvIGdyYWRpZW50IGZpbGxzXG4gICAgICBlbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ2RlZnMgW2lkXScpLmZvckVhY2goZGVmID0+IHtcbiAgICAgICAgY29uc3Qgb2xkSWQgPSBkZWYuZ2V0QXR0cmlidXRlKCdpZCcpO1xuICAgICAgICBjb25zdCBuZXdJZCA9IGAke2lkfS0ke29sZElkfWA7XG4gICAgICAgIGRlZi5zZXRBdHRyaWJ1dGUoJ2lkJywgbmV3SWQpO1xuICAgICAgICBlbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoYFtmaWxsPSd1cmwoIyR7b2xkSWR9KSddYCkuZm9yRWFjaChyZWYgPT4ge1xuICAgICAgICAgIHJlZi5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCBgdXJsKCMke25ld0lkfSlgKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHRoaXMubG9nLmVycm9yKGBsb2FkQ2FyZEljb24oJHtpZH0pID0+YCwgZXJyKTtcbiAgICB9XG4gIH1cbiAgLy8gQSBjYXJkIGhhcyBiZWVuIHNlbGVjdGVkXG4gIHNlbGVjdENhcmQoaWQpIHtcbiAgICAvLyBTZWxlY3QgdGhpcyBjYXJkIGFuZCBkZXNlbGVjdCBhbGwgb3RoZXJzXG4gICAgbGV0IHNlbGVjdGVkQ2FyZDtcbiAgICBmb3IgKGNvbnN0IGNhcmQgb2YgQXJyYXkuZnJvbSh0aGlzLnBhcmVudEVsZW1lbnQuY2hpbGRyZW4pKSB7XG4gICAgICAoMCwgX3V0aWxzLmFzc2VydElzSW5zdGFuY2VPZikoY2FyZCwgSFRNTEVsZW1lbnQpO1xuICAgICAgaWYgKGNhcmQuZGF0YXNldC5pZCA9PT0gaWQpIHNlbGVjdGVkQ2FyZCA9IGNhcmQ7XG4gICAgICBjYXJkLmNsYXNzTGlzdC50b2dnbGUoJ2hjLXNlbGVjdGVkJywgY2FyZC5kYXRhc2V0LmlkID09PSBpZCk7XG4gICAgfVxuICAgIGlmICghc2VsZWN0ZWRDYXJkKSBpZCA9IHVuZGVmaW5lZDtcbiAgICAvLyBOb3RpZnkgdGhlIGNsaWVudCBvZiBzZWxlY3Rpb24gY2hhbmdlc1xuICAgIGlmICh0aGlzLnNlbGVjdGVkQ2FyZElkICE9PSBpZCkge1xuICAgICAgdGhpcy5sb2cuZGVidWcoYG9uU2VsZWN0KCR7aWR9KSAod2FzICR7dGhpcy5zZWxlY3RlZENhcmRJZH0pYCk7XG4gICAgICB0aGlzLnNlbGVjdGVkQ2FyZElkID0gaWQ7XG4gICAgICB0aGlzLm9uU2VsZWN0Py4oaWQpO1xuICAgIH1cbiAgfVxufVxuZXhwb3J0cy5DYXJkcyA9IENhcmRzO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ9dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p1WVcxbGN5STZXeUpmZFhScGJITWlMQ0p5WlhGMWFYSmxJaXdpWDNWMGFXeHpSRzl0SWl3aVEyRnlaSE1pTENKc2IyY2lMQ0p3WVhKbGJuUkZiR1Z0Wlc1MElpd2libTl1UVhCd2JHbGhibU5sUTJGeVpITWlMQ0poY0hCc2FXRnVZMlZEWVhKa2N5SXNJbk5sYkdWamRHVmtRMkZ5WkVsa0lpd2liMjVUWld4bFkzUWlMQ0pqYjI1emRISjFZM1J2Y2lJc0ltZGxkRVZzWlcxbGJuUkNlVWxrSWl3aWMyVjBUbTl1UVhCd2JHbGhibU5sY3lJc0ltTmhjbVJ6SWl3aWRYQmtZWFJsUTJGeVpITWlMQ0p6WlhSQmNIQnNhV0Z1WTJWeklpd2lZWEJ3YkdsaGJtTmxjeUlzSW0xaGNDSXNJbUZ3Y0d4cFlXNWpaU0lzSW1sa0lpd2lhR0ZKWkNJc0ltbGpiMjRpTENKMGVYQmxJaXdpZEc5TWIyTmhiR1ZNYjNkbGNrTmhjMlVpTENKdVlXMWxJaXdpWkdWMFlXbHNJaXdpWW5KaGJtUWlMQ0psYm5WdFltVnlJaXdpYzI5eWRDSXNJbUVpTENKaUlpd2liRzlqWVd4bFEyOXRjR0Z5WlNJc0lrcFRUMDRpTENKemRISnBibWRwWm5raUxDSmhiR3hEWVhKa2N5SXNJbkpsY0d4aFkyVkRhR2xzWkhKbGJpSXNJbU5oY21RaUxDSnRZV3RsUTJGeVpDSXNJbWhwWkdSbGJpSXNJbXhsYm1kMGFDSXNJbk5sYkdWamRFTmhjbVFpTENKMWJtUmxabWx1WldRaUxDSmpiRzl1WlZSbGJYQnNZWFJsSWl3aWJHOWhaRU5oY21SSlkyOXVJaXdpWjJWMFUyeHZkQ0lzSW1Wc1pXMWxiblFpTENKamFHbHNaSEpsYmlJc0ltRnpjMlZ5ZEVselNXNXpkR0Z1WTJWUFppSXNJa2hVVFV4RmJHVnRaVzUwSWl3aVpHRjBZWE5sZENJc0ltOXVZMnhwWTJzaUxDSjFjbXdpTENKeVpYTndiMjV6WlNJc0ltWmxkR05vSWl3aWIyc2lMQ0pGY25KdmNpSXNJbk4wWVhSMWMxUmxlSFFpTENKcGJtNWxja2hVVFV3aUxDSjBaWGgwSWl3aWNYVmxjbmxUWld4bFkzUnZja0ZzYkNJc0ltWnZja1ZoWTJnaUxDSm5jbTkxY0NJc0ltZGxkRUYwZEhKcFluVjBaU0lzSW1GemMyVnlkRWx6UkdWbWFXNWxaQ0lzSW5KbGJXOTJaVUYwZEhKcFluVjBaU0lzSW1Oc1lYTnpUR2x6ZENJc0ltRmtaQ0lzSW1SbFppSXNJbTlzWkVsa0lpd2libVYzU1dRaUxDSnpaWFJCZEhSeWFXSjFkR1VpTENKeVpXWWlMQ0psY25JaUxDSmxjbkp2Y2lJc0luTmxiR1ZqZEdWa1EyRnlaQ0lzSWtGeWNtRjVJaXdpWm5KdmJTSXNJblJ2WjJkc1pTSXNJbVJsWW5Wbklpd2laWGh3YjNKMGN5SmRMQ0p6YjNWeVkyVnpJanBiSWk0dUx5NHVMeTR1TDNOeVl5OW9iMjFsWW5KcFpHZGxMWFZwTDNCMVlteHBZeTlqWVhKa2N5NTBjeUpkTENKemIzVnlZMlZ6UTI5dWRHVnVkQ0k2VzI1MWJHeGRMQ0p0WVhCd2FXNW5jeUk2SWpzN096czdPMEZCVFVFc1NVRkJRVUVzVFVGQlFTeEhRVUZCUXl4UFFVRkJPMEZCUTBFc1NVRkJRVU1zVTBGQlFTeEhRVUZCUkN4UFFVRkJPMEZCVUVFN1FVRkRRVHM3UVVGcFFrRTdRVUZEVFN4TlFVRlBSU3hMUVVGTE8wVkJZMDlETEVkQlFVRTdSVUZhY2tJN1JVRkRVME1zWVVGQllUdEZRVVYwUWp0RlFVTkJReXhwUWtGQmFVSXNSMEZCZFVJc1JVRkJSVHRGUVVNeFEwTXNZMEZCWXl4SFFVRXdRaXhGUVVGRk8wVkJSVEZETzBWQlEwRkRMR05CUVdNN1JVRkRaRU1zVVVGQlVUdEZRVVZTTzBWQlEwRkRMRmxCUVhGQ1RpeEhRVUZYTzBsQlFWZ3NTMEZCUVVFc1IwRkJSeXhIUVVGSVFTeEhRVUZITzBsQlEzQkNMRWxCUVVrc1EwRkJRME1zWVVGQllTeEhRVUZITEVsQlFVRk5MSGRDUVVGakxFVkJRVU1zYjBKQlFXOUNMRU5CUVVNN1JVRkROMFE3UlVGRlFUdEZRVU5CUXl4blFrRkJaMEpCTEVOQlFVTkRMRXRCUVhkQ08wbEJRM0pETEVsQlFVa3NRMEZCUTFBc2FVSkJRV2xDTEVkQlFVZFBMRXRCUVVzN1NVRkRPVUlzU1VGQlNTeERRVUZEUXl4WFFVRlhMRVZCUVVVN1JVRkRkRUk3UlVGRlFUdEZRVU5CUXl4aFFVRmhRU3hEUVVGRFF5eFZRVUV5UWp0SlFVTnlRenRKUVVOQkxFMUJRVTFVTEdOQlFXTXNSMEZCUjFNc1ZVRkJWU3hEUVVGRFF5eEhRVUZITEVOQlFVTkRMRk5CUVZNc1MwRkJTenROUVVOb1JFTXNSVUZCUlN4RlFVRk5SQ3hUUVVGVExFTkJRVU5GTEVsQlFVazdUVUZEZEVKRExFbEJRVWtzUlVGQlNVZ3NVMEZCVXl4RFFVRkRTU3hKUVVGSkxFTkJRVU5ETEdsQ1FVRnBRaXhGUVVGRk8wMUJRekZEUXl4SlFVRkpMRVZCUVVsT0xGTkJRVk1zUTBGQlEwMHNTVUZCU1R0TlFVTjBRa01zVFVGQlRTeEZRVUZGTEVkQlFVZFFMRk5CUVZNc1EwRkJRMUVzUzBGQlN5eEpRVUZKVWl4VFFVRlRMRU5CUVVOVExFOUJRVTg3UzBGRGJFUXNRMEZCUXl4RFFVRkRPMGxCUTBod1FpeGpRVUZqTEVOQlFVTnhRaXhKUVVGSkxFTkJRVU1zUTBGQlEwTXNRMEZCUXl4RlFVRkZReXhEUVVGRExFdEJRVXRFTEVOQlFVTXNRMEZCUTB3c1NVRkJTU3hEUVVGRFR5eGhRVUZoTEVOQlFVTkVMRU5CUVVNc1EwRkJRMDRzU1VGQlNTeERRVUZETEVOQlFVTTdTVUZGTTBRN1NVRkRRU3hKUVVGSlVTeEpRVUZKTEVOQlFVTkRMRk5CUVZNc1EwRkJRekZDTEdOQlFXTXNRMEZCUXl4TFFVRkxlVUlzU1VGQlNTeERRVUZEUXl4VFFVRlRMRU5CUVVNc1NVRkJTU3hEUVVGRE1VSXNZMEZCWXl4RFFVRkRMRVZCUVVVN1RVRkRlRVVzU1VGQlNTeERRVUZEUVN4alFVRmpMRWRCUVVkQkxHTkJRV003VFVGRGNFTXNTVUZCU1N4RFFVRkRUeXhYUVVGWExFVkJRVVU3U1VGRGRFSTdSVUZEU2p0RlFVVkJPMFZCUTBGQkxGZEJRVmRCTEVOQlFVRTdTVUZEVUR0SlFVTkJMRTFCUVUxdlFpeFJRVUZSTEVkQlFVY3NRMEZCUXl4SFFVRkhMRWxCUVVrc1EwRkJRelZDTEdsQ1FVRnBRaXhGUVVGRkxFZEJRVWNzU1VGQlNTeERRVUZEUXl4alFVRmpMRU5CUVVNN1NVRkRjRVVzU1VGQlNTeERRVUZEUml4aFFVRmhMRU5CUVVNNFFpeGxRVUZsTEVOQlFVTXNSMEZCUjBRc1VVRkJVU3hEUVVGRGFrSXNSMEZCUnl4RFFVRkRiVUlzU1VGQlNTeEpRVUZKTEVsQlFVa3NRMEZCUTBNc1VVRkJVU3hEUVVGRFJDeEpRVUZKTEVOQlFVTXNRMEZCUXl4RFFVRkRPMGxCUTJoR0xFbEJRVWtzUTBGQlF5OUNMR0ZCUVdFc1EwRkJRMmxETEUxQlFVMHNSMEZCUnl4RFFVRkRTaXhSUVVGUkxFTkJRVU5MTEUxQlFVMDdTVUZGTlVNN1NVRkRRU3hKUVVGSkxFTkJRVU5ETEZWQlFWVXNRMEZCUXl4SlFVRkpMRU5CUVVOb1F5eGpRVUZqTEVOQlFVTTdSVUZEZUVNN1JVRkhRVHRGUVVOQk5rSXNVVUZCVVVFc1EwRkJRenRKUVVGRmJFSXNSVUZCUlR0SlFVRkZSU3hKUVVGSk8wbEJRVVZITEVsQlFVazdTVUZCUlVNN1JVRkJUU3hEUVVGdFFqdEpRVU5vUkR0SlFVTkJMRWxCUVVsQkxFMUJRVTBzUzBGQlMyZENMRk5CUVZNc1JVRkJSV2hDTEUxQlFVMHNSMEZCUnl4SFFVRkhMRU5CUVVNc1EwRkJRenRKUVVONFF5eE5RVUZOVnl4SlFVRkpMRWRCUVVjc1NVRkJRVTBzZFVKQlFXRXNSVUZCUXl4dFFrRkJiVUlzUlVGQlJUdE5RVUZGYkVJc1NVRkJTVHROUVVGRlF6dEpRVUZOTEVOQlFVVXNRMEZCUXp0SlFVTnFSU3hKUVVGSkxFTkJRVU5yUWl4WlFVRlpMRU5CUVVNc1NVRkJRVU1zYVVKQlFVOHNSVUZCUTFJc1NVRkJTU3hGUVVGRkxFMUJRVTBzUTBGQlF5eEZRVUZGTEdsQ1FVRnBRbVlzU1VGQlNTeE5RVUZOTEVWQlFVVkdMRVZCUVVVc1EwRkJRenRKUVVWNlJUdEpRVU5CTEUxQlFVMHdRaXhQUVVGUExFZEJRVWRVTEVsQlFVa3NRMEZCUTFVc1VVRkJVU3hEUVVGRExFTkJRVU1zUTBGQlF6dEpRVU5vUXl4SlFVRkJReXg1UWtGQmEwSXNSVUZCUTBZc1QwRkJUeXhGUVVGRlJ5eFhRVUZYTEVOQlFVTTdTVUZEZUVOSUxFOUJRVThzUTBGQlEwa3NUMEZCVHl4RFFVRkRPVUlzUlVGQlJTeEhRVUZIUVN4RlFVRkZPMGxCUTNaQ01FSXNUMEZCVHl4RFFVRkRTeXhQUVVGUExFZEJRVWNzVFVGQlZ6dE5RVUZITEVsQlFVa3NRMEZCUTFZc1ZVRkJWU3hEUVVGRGNrSXNSVUZCUlN4RFFVRkRPMGxCUVVVc1EwRkJRenRKUVVOMFJDeFBRVUZQYVVJc1NVRkJTVHRGUVVObU8wVkJSVUU3UlVGRFFTeE5RVUZOVHl4WlFVRlpRU3hEUVVGRFJTeFBRVUZ2UWl4RlFVRkZUU3hIUVVGWExFVkJRVVZvUXl4RlFVRlZPMGxCUXpWRUxFbEJRVWs3VFVGRFFUdE5RVU5CTEUxQlFVMXBReXhSUVVGUkxFZEJRVWNzVFVGQlRVTXNTMEZCU3l4RFFVRkRSaXhIUVVGSExFTkJRVU03VFVGRGFrTXNTVUZCU1N4RFFVRkRReXhSUVVGUkxFTkJRVU5GTEVWQlFVVXNSVUZCUlN4TlFVRk5MRWxCUVVsRExFdEJRVXNzUTBGQlF5eDNRa0ZCZDBKSUxGRkJRVkVzUTBGQlEwUXNSMEZCUnl4TFFVRkxReXhSUVVGUkxFTkJRVU5KTEZWQlFWVXNSVUZCUlN4RFFVRkRPMDFCUTJwSFdDeFBRVUZQTEVOQlFVTlpMRk5CUVZNc1IwRkJSeXhOUVVGTlRDeFJRVUZSTEVOQlFVTk5MRWxCUVVrc1JVRkJSVHROUVVWNlF6dE5RVU5CWWl4UFFVRlBMRU5CUVVOakxHZENRVUZuUWl4RFFVRkRMRTlCUVU4c1EwRkJReXhEUVVGRFF5eFBRVUZQTEVOQlFVTkRMRXRCUVVzc1NVRkJSenRSUVVNNVF5eE5RVUZOTVVNc1JVRkJSU3hIUVVGSE1FTXNTMEZCU3l4RFFVRkRReXhaUVVGWkxFTkJRVU1zU1VGQlNTeERRVUZETzFGQlEyNURMRWxCUVVGRExITkNRVUZsTEVWQlFVTTFReXhGUVVGRkxFTkJRVU03VVVGRGJrSXdReXhMUVVGTExFTkJRVU5ITEdWQlFXVXNRMEZCUXl4SlFVRkpMRU5CUVVNN1VVRkRNMEpJTEV0QlFVc3NRMEZCUTBrc1UwRkJVeXhEUVVGRFF5eEhRVUZITEVOQlFVTXZReXhGUVVGRkxFTkJRVU03VFVGRE0wSXNRMEZCUXl4RFFVRkRPMDFCUlVZN1RVRkRRVEJDTEU5QlFVOHNRMEZCUTJNc1owSkJRV2RDTEVOQlFVTXNWMEZCVnl4RFFVRkRMRU5CUVVORExFOUJRVThzUTBGQlEwOHNSMEZCUnl4SlFVRkhPMUZCUTJoRUxFMUJRVTFETEV0QlFVc3NSMEZCUjBRc1IwRkJSeXhEUVVGRFRDeFpRVUZaTEVOQlFVTXNTVUZCU1N4RFFVRkRPMUZCUTNCRExFMUJRVTFQTEV0QlFVc3NSMEZCUnl4SFFVRkhiRVFzUlVGQlJTeEpRVUZKYVVRc1MwRkJTeXhGUVVGRk8xRkJRemxDUkN4SFFVRkhMRU5CUVVOSExGbEJRVmtzUTBGQlF5eEpRVUZKTEVWQlFVVkVMRXRCUVVzc1EwRkJRenRSUVVNM1FuaENMRTlCUVU4c1EwRkJRMk1zWjBKQlFXZENMRU5CUVVNc1pVRkJaVk1zUzBGQlN5eExRVUZMTEVOQlFVTXNRMEZCUTFJc1QwRkJUeXhEUVVGRFZ5eEhRVUZITEVsQlFVYzdWVUZCUjBFc1IwRkJSeXhEUVVGRFJDeFpRVUZaTEVOQlFVTXNUVUZCVFN4RlFVRkZMRkZCUVZGRUxFdEJRVXNzUjBGQlJ5eERRVUZETzFGQlFVVXNRMEZCUXl4RFFVRkRPMDFCUTNaSUxFTkJRVU1zUTBGQlF6dEpRVU5PTEVOQlFVTXNRMEZCUXl4UFFVRlBSeXhIUVVGSExFVkJRVVU3VFVGRFZpeEpRVUZKTEVOQlFVTndSU3hIUVVGSExFTkJRVU54UlN4TFFVRkxMRU5CUVVNc1owSkJRV2RDZEVRc1JVRkJSU3hOUVVGTkxFVkJRVVZ4UkN4SFFVRkhMRU5CUVVNN1NVRkRha1E3UlVGRFNqdEZRVVZCTzBWQlEwRm9ReXhWUVVGVlFTeERRVUZEY2tJc1JVRkJWenRKUVVOc1FqdEpRVU5CTEVsQlFVbDFSQ3haUVVGeFF6dEpRVU42UXl4TFFVRkxMRTFCUVUxMFF5eEpRVUZKTEVsQlFVbDFReXhMUVVGTExFTkJRVU5ETEVsQlFVa3NRMEZCUXl4SlFVRkpMRU5CUVVOMlJTeGhRVUZoTEVOQlFVTjVReXhSUVVGUkxFTkJRVU1zUlVGQlJUdE5RVU40UkN4SlFVRkJReXg1UWtGQmEwSXNSVUZCUTFnc1NVRkJTU3hGUVVGRldTeFhRVUZYTEVOQlFVTTdUVUZEY2tNc1NVRkJTVm9zU1VGQlNTeERRVUZEWVN4UFFVRlBMRU5CUVVNNVFpeEZRVUZGTEV0QlFVdEJMRVZCUVVVc1JVRkJSWFZFTEZsQlFWa3NSMEZCUjNSRExFbEJRVWs3VFVGREwwTkJMRWxCUVVrc1EwRkJRelpDTEZOQlFWTXNRMEZCUTFrc1RVRkJUU3hEUVVGRExHRkJRV0VzUlVGQlJYcERMRWxCUVVrc1EwRkJRMkVzVDBGQlR5eERRVUZET1VJc1JVRkJSU3hMUVVGTFFTeEZRVUZGTEVOQlFVTTdTVUZEYUVVN1NVRkRRU3hKUVVGSkxFTkJRVU4xUkN4WlFVRlpMRVZCUVVWMlJDeEZRVUZGTEVkQlFVZHpRaXhUUVVGVE8wbEJSV3BETzBsQlEwRXNTVUZCU1N4SlFVRkpMRU5CUVVOcVF5eGpRVUZqTEV0QlFVdFhMRVZCUVVVc1JVRkJSVHROUVVNMVFpeEpRVUZKTEVOQlFVTm1MRWRCUVVjc1EwRkJRekJGTEV0QlFVc3NRMEZCUXl4WlFVRlpNMFFzUlVGQlJTeFZRVUZWTEVsQlFVa3NRMEZCUTFnc1kwRkJZeXhIUVVGSExFTkJRVU03VFVGRE9VUXNTVUZCU1N4RFFVRkRRU3hqUVVGakxFZEJRVWRYTEVWQlFVVTdUVUZEZUVJc1NVRkJTU3hEUVVGRFZpeFJRVUZSTEVkQlFVZFZMRVZCUVVVc1EwRkJRenRKUVVOMlFqdEZRVU5LT3p0QlFVTklORVFzVDBGQlFTeERRVUZCTlVVc1MwRkJRU3hIUVVGQlFTeExRVUZCSWl3aWFXZHViM0psVEdsemRDSTZXMTE5IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLkNsaWVudENsaWVudElEID0gdm9pZCAwO1xudmFyIF91dGlscyA9IHJlcXVpcmUoXCIuLi8uLi91dGlscy5qc1wiKTtcbnZhciBfdXRpbHNEb20gPSByZXF1aXJlKFwiLi91dGlscy1kb20uanNcIik7XG4vLyBIb21lYnJpZGdlIHBsdWdpbiBmb3IgSG9tZSBDb25uZWN0IGhvbWUgYXBwbGlhbmNlc1xuLy8gQ29weXJpZ2h0IMKpIDIwMjMgQWxleGFuZGVyIFRob3VreWRpZGVzXG5cbi8vIE1pbmltdW0gdGltZSBiZXR3ZWVuIGR1cGxpY2F0ZSB0b2FzdCBub3RpZmljYXRpb25zXG5jb25zdCBUT0FTVF9ERURVUF9USU1FID0gNSAqIF91dGlscy5NUztcbi8vIFRoZSBjdXJyZW50IEhvbWUgQ29ubmVjdCBjbGllbnRcbmNsYXNzIENsaWVudENsaWVudElEIHtcbiAgbG9nO1xuICBpcGM7XG4gIC8vIFRoZSBjb25maWd1cmF0aW9uIG9mIHRoZSBjbGllbnQgYmVpbmcgbW9uaXRvcmVkXG4gIGNsaWVudENvbmZpZztcbiAgLy8gVGhlIG1vc3QgcmVjZW50IHRvYXN0IGRpc3BsYXllZCAodG8gYXZvaWQgZHVwbGljYXRlcylcbiAgbGFzdFRvYXN0O1xuICAvLyBUcmlnZ2VycyB0byBtb2RpZnkgdGhlIGNvbmZpZ3VyYXRpb25cbiAgb25GYWlsO1xuICBvbkFwcGxpYW5jZXM7XG4gIC8vIENyZWF0ZSBhIG5ldyBIb21lIENvbm5lY3QgY2xpZW50XG4gIGNvbnN0cnVjdG9yKGxvZywgaXBjKSB7XG4gICAgdGhpcy5sb2cgPSBsb2c7XG4gICAgdGhpcy5pcGMgPSBpcGM7XG4gICAgdGhpcy5pcGMub25FdmVudCgnc3RhdHVzJywgc3RhdHVzID0+IHtcbiAgICAgIHRoaXMub25DbGllbnRTdGF0dXMoc3RhdHVzKTtcbiAgICB9KTtcbiAgfVxuICAvLyBUaGUgSG9tZSBDb25uZWN0IGNsaWVudCBjb25maWd1cmF0aW9uIGhhcyBjaGFuZ2VkXG4gIGFzeW5jIHNldENsaWVudChjb25maWcpIHtcbiAgICBjb25zdCBjbGllbnRDb25maWcgPSB0aGlzLnByZXBhcmVDbGllbnRDb25maWcoY29uZmlnKTtcbiAgICBpZiAoY2xpZW50Q29uZmlnKSB7XG4gICAgICAvLyBUZXN0IHRoZSBjbGllbnQgY29uZmlndXJhdGlvblxuICAgICAgdGhpcy5jbGllbnRDb25maWcgPSBjbGllbnRDb25maWc7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBzdGF0dXMgPSBhd2FpdCB0aGlzLmlwYy5yZXF1ZXN0KCcvY2xpZW50aWQnLCBjbGllbnRDb25maWcpO1xuICAgICAgICB0aGlzLm9uQ2xpZW50U3RhdHVzKHN0YXR1cyk7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgY29uc3QgbWVzc2FnZSA9IGVyciBpbnN0YW5jZW9mIEVycm9yID8gZXJyLm1lc3NhZ2UgOiBTdHJpbmcoZXJyKTtcbiAgICAgICAgdGhpcy5zaG93VG9hc3QoJ2Vycm9yJywgYFVuYWJsZSB0byBhdHRlbXB0IGF1dGhvcmlzYXRpb24gJHttZXNzYWdlfWApO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBJZ25vcmUgdGhlIGNsaWVudCBjb25maWd1cmF0aW9uIHVudGlsIGl0IGlzIHZhbGlkXG4gICAgICB0aGlzLmNsaWVudENvbmZpZyA9IHVuZGVmaW5lZDtcbiAgICAgIHRoaXMuc2hvd1BhbmVsKCk7XG4gICAgICB0aGlzLm9uQXBwbGlhbmNlcz8uKCk7XG4gICAgfVxuICB9XG4gIC8vIFRlc3Qgd2hldGhlciB0aGUgY2xpZW50IGNvbmZpZ3VyYXRpb24gaXMgbGlrZWx5IHRvIGJlIHZhbGlkXG4gIHByZXBhcmVDbGllbnRDb25maWcoY29uZmlnKSB7XG4gICAgaWYgKGNvbmZpZy5kZWJ1Zz8uaW5jbHVkZXMoJ01vY2sgQXBwbGlhbmNlcycpKSB7XG4gICAgICAvLyBNb2NrIGFwcGxpYW5jZXM7IHVzZSBhbiBlbXB0eSBjbGllbnRpZCB0byBtYXRjaCB0aGUgc3RhdHVzXG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi5jb25maWcsXG4gICAgICAgIGNsaWVudGlkOiAnJ1xuICAgICAgfTtcbiAgICB9IGVsc2UgaWYgKGNvbmZpZy5jbGllbnRpZCAhPT0gdW5kZWZpbmVkICYmIC9eWzAtOUEtRl17NjR9JC9pLnRlc3QoY29uZmlnLmNsaWVudGlkKSkge1xuICAgICAgLy8gVmlhYmxlIGNsaWVudGlkXG4gICAgICByZXR1cm4gY29uZmlnO1xuICAgIH1cbiAgfVxuICAvLyBIYW5kbGUgZXZlbnRzIGZyb20gdGhlIEhvbWUgQ29ubmVjdCBjbGllbnRcbiAgb25DbGllbnRTdGF0dXMoc3RhdHVzKSB7XG4gICAgLy8gSWdub3JlIHRoZSBzdGF0dXMgaWYgbm8gbG9uZ2VyIG1vbml0b3JpbmcgdGhlIGNsaWVudFxuICAgIGlmICh0aGlzLmNsaWVudENvbmZpZz8uY2xpZW50aWQgIT09IHN0YXR1cy5jbGllbnRpZCkgcmV0dXJuO1xuICAgIC8vIFVwZGF0ZSB0aGUgbGlzdCBvZiBhcHBsaWFuY2VzXG4gICAgdGhpcy5vbkFwcGxpYW5jZXM/LihzdGF0dXMuYXBwbGlhbmNlcyk7XG4gICAgLy8gRGlzcGxheSBhbiBhcHByb3ByaWF0ZSB0b2FzdCBub3RpZmljYXRpb25cbiAgICBzd2l0Y2ggKHN0YXR1cy5hdXRob3Jpc2F0aW9uPy5zdGF0ZSkge1xuICAgICAgY2FzZSAnc3VjY2Vzcyc6XG4gICAgICAgIHRoaXMuc2hvd1RvYXN0KCdzdWNjZXNzJywgJ1N1Y2Nlc3NmdWxseSBhdXRob3Jpc2VkJyk7XG4gICAgICAgIHRoaXMuc2hvd1BhbmVsKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAndXNlcic6XG4gICAgICAgIHRoaXMuc2hvd1RvYXN0KCdpbmZvJywgJ1VzZXIgYXV0aG9yaXNhdGlvbiByZXF1aXJlZCcpO1xuICAgICAgICB0aGlzLnNob3dVc2VyQXV0aG9yaXNhdGlvbihzdGF0dXMuYXV0aG9yaXNhdGlvbik7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnZmFpbCc6XG4gICAgICAgIHRoaXMuc2hvd1RvYXN0KCdlcnJvcicsICdBdXRob3Jpc2F0aW9uIGZhaWxlZCcpO1xuICAgICAgICB0aGlzLnNob3dGYWlsKHN0YXR1cy5hdXRob3Jpc2F0aW9uKTtcbiAgICAgICAgdGhpcy5vbkZhaWw/LigpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2J1c3knOlxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhpcy5zaG93UGFuZWwoKTtcbiAgICB9XG4gIH1cbiAgLy8gUHJvbXB0IHRoZSB1c2VyIHRvIGF1dGhvcmlzZSB0aGUgY2xpZW50XG4gIHNob3dVc2VyQXV0aG9yaXNhdGlvbihhdXRob3Jpc2F0aW9uKSB7XG4gICAgLy8gU2V0IHRoZSBsaW5rL2NvZGVcbiAgICBjb25zdCBsaW5rID0gKDAsIF91dGlsc0RvbS5nZXRFbGVtZW50QnlJZCkoJ2hjLWNsaWVudC11c2VyLWxpbmsnKTtcbiAgICBsaW5rLnNldEF0dHJpYnV0ZSgnaHJlZicsIGF1dGhvcmlzYXRpb24udXJpKTtcbiAgICAoMCwgX3V0aWxzRG9tLnNldFNsb3RUZXh0KShkb2N1bWVudCwge1xuICAgICAgJ2hjLWNsaWVudC11c2VyLWNvZGUnOiBhdXRob3Jpc2F0aW9uLmNvZGVcbiAgICB9KTtcbiAgICAvLyBFbmFibGUgZ2VuZXJhdGlvbiBvZiBhIG5ldyBhdXRob3Jpc2F0aW9uIGNvZGVcbiAgICAoMCwgX3V0aWxzRG9tLmdldEVsZW1lbnRCeUlkKSgnaGMtY2xpZW50LXVzZXItcmV0cnknKS5vbmNsaWNrID0gKCkgPT4ge1xuICAgICAgdGhpcy5yZXRyeUF1dGhvcmlzYXRpb24oKTtcbiAgICB9O1xuICAgIC8vIE1ha2UgdGhlIGF1dGhvcmlzYXRpb24gbGluayB2aXNpYmxlIChiZWZvcmUgdHJpZ2dlcmluZyB0cmFuc2l0aW9uKVxuICAgIHRoaXMuc2hvd1BhbmVsKCdoYy1jbGllbnQtdXNlcicpO1xuICAgIC8vIFN0YXJ0IGFuaW1hdGluZyB0aGUgcHJvZ3Jlc3MgYmFyIGZvciB0aGUgdGltZSB1bnRpbCB0aGUgbGluayBleHBpcmVzXG4gICAgY29uc3QgcHJvZ3Jlc3MgPSAoMCwgX3V0aWxzRG9tLmdldEVsZW1lbnRCeUlkKSgnaGMtY2xpZW50LXVzZXItcHJvZ3Jlc3MnKTtcbiAgICBwcm9ncmVzcy5jbGFzc0xpc3QucmVtb3ZlKCdoYy1wcm9ncmVzcy16ZXJvJyk7XG4gICAgaWYgKGF1dGhvcmlzYXRpb24uZXhwaXJlcyAhPT0gbnVsbCkge1xuICAgICAgcHJvZ3Jlc3Muc3R5bGUudHJhbnNpdGlvbkR1cmF0aW9uID0gYCR7YXV0aG9yaXNhdGlvbi5leHBpcmVzIC0gRGF0ZS5ub3coKX1tc2A7XG4gICAgICB2b2lkIHByb2dyZXNzLm9mZnNldEhlaWdodDsgLy8gKGZvcmNlIGEgcmVmbG93KVxuICAgICAgcHJvZ3Jlc3MuY2xhc3NMaXN0LmFkZCgnaGMtcHJvZ3Jlc3MtemVybycpO1xuICAgIH1cbiAgfVxuICAvLyBEaXNwbGF5IHRoZSByZXN1bHQgb2YgYSBmYWlsZWQgYXV0aG9yaXNhdGlvblxuICBzaG93RmFpbChhdXRob3Jpc2F0aW9uKSB7XG4gICAgLy8gRGlzcGxheSB0aGUgZXJyb3IgbWVzc2FnZVxuICAgICgwLCBfdXRpbHNEb20uZ2V0RWxlbWVudEJ5SWQpKCdoYy1jbGllbnQtZmFpbC1tZXNzYWdlJykudGV4dENvbnRlbnQgPSBhdXRob3Jpc2F0aW9uLm1lc3NhZ2U7XG4gICAgLy8gSW5kaWNhdGUgd2hldGhlciB0aGUgYXV0aG9yaXNhdGlvbiBjYW4gYmUgcmV0cmllZFxuICAgICgwLCBfdXRpbHNEb20uZ2V0RWxlbWVudEJ5SWQpKCdoYy1jbGllbnQtZmFpbC1yZXRyeWFibGUnKS5oaWRkZW4gPSAhYXV0aG9yaXNhdGlvbi5yZXRyeWFibGU7XG4gICAgKDAsIF91dGlsc0RvbS5nZXRFbGVtZW50QnlJZCkoJ2hjLWNsaWVudC1mYWlsLXJldHJ5JykuaGlkZGVuID0gIWF1dGhvcmlzYXRpb24ucmV0cnlhYmxlO1xuICAgICgwLCBfdXRpbHNEb20uZ2V0RWxlbWVudEJ5SWQpKCdoYy1jbGllbnQtZmFpbC1yZXRyeScpLm9uY2xpY2sgPSAoKSA9PiB7XG4gICAgICB0aGlzLnJldHJ5QXV0aG9yaXNhdGlvbigpO1xuICAgIH07XG4gICAgLy8gQWRkIGFueSBoZWxwIHRoYXQgaGFzIGJlZW4gcHJvdmlkZWRcbiAgICBpZiAoYXV0aG9yaXNhdGlvbi5oZWxwKSB7XG4gICAgICAvLyBTZXQgdGV4dCBibG9ja3NcbiAgICAgIGNvbnN0IHNldFRleHQgPSAoaWQsIHRleHQpID0+IHtcbiAgICAgICAgKDAsIF91dGlsc0RvbS5nZXRFbGVtZW50QnlJZCkoaWQpLnJlcGxhY2VDaGlsZHJlbiguLi50ZXh0Lm1hcChwYXJhZ3JhcGggPT4gKDAsIF91dGlsc0RvbS5jbG9uZVRlbXBsYXRlKSgnaGMtY2xpZW50LWZhaWwtcGFyYWdyYXBoJywge1xuICAgICAgICAgIHBhcmFncmFwaFxuICAgICAgICB9KSkpO1xuICAgICAgfTtcbiAgICAgIHNldFRleHQoJ2hjLWNsaWVudC1mYWlsLXByZXNjcmlwdCcsIGF1dGhvcmlzYXRpb24uaGVscC5wcmVzY3JpcHQpO1xuICAgICAgc2V0VGV4dCgnaGMtY2xpZW50LWZhaWwtcG9zdHNjcmlwdCcsIGF1dGhvcmlzYXRpb24uaGVscC5wb3N0c2NyaXB0KTtcbiAgICAgIC8vIFByb3ZpZGUgYWRkaXRpb25hbCBoZWxwIGZvciBjcmVhdGluZyBvciBtb2RpZnlpbmcgdGhlIGFwcGxpY2F0aW9uXG4gICAgICBjb25zdCB7XG4gICAgICAgIGNsaWVudFxuICAgICAgfSA9IGF1dGhvcmlzYXRpb24uaGVscDtcbiAgICAgIGNvbnN0IGxpbmsgPSAoMCwgX3V0aWxzRG9tLmdldEVsZW1lbnRCeUlkKSgnaGMtY2xpZW50LWZhaWwtdXJpJyk7XG4gICAgICBpZiAoY2xpZW50KSB7XG4gICAgICAgICgwLCBfdXRpbHNEb20uZ2V0RWxlbWVudEJ5SWQpKCdoYy1jbGllbnQtZmFpbC1jbGllbnQtc2V0dGluZ3MnKS5yZXBsYWNlQ2hpbGRyZW4oLi4uT2JqZWN0LmVudHJpZXMoY2xpZW50LnNldHRpbmdzKS5tYXAoKFtrZXksIHZhbHVlXSkgPT4gKDAsIF91dGlsc0RvbS5jbG9uZVRlbXBsYXRlKSgnaGMtY2xpZW50LWZhaWwtY2xpZW50LXNldHRpbmcnLCB7XG4gICAgICAgICAga2V5LFxuICAgICAgICAgIHZhbHVlXG4gICAgICAgIH0pKSk7XG4gICAgICAgIGxpbmsuc2V0QXR0cmlidXRlKCdocmVmJywgY2xpZW50LnVyaSk7XG4gICAgICAgIGxpbmsudGV4dENvbnRlbnQgPSBjbGllbnQuYWN0aW9uID09PSAnY3JlYXRlJyA/ICdDcmVhdGUgYXBwbGljYXRpb24nIDogJ01vZGlmeSBhcHBsaWNhdGlvbic7XG4gICAgICAgIGxpbmsuaGlkZGVuID0gZmFsc2U7XG4gICAgICAgICgwLCBfdXRpbHNEb20uZ2V0RWxlbWVudEJ5SWQpKCdoYy1jbGllbnQtZmFpbC1jbGllbnQnKS5oaWRkZW4gPSBmYWxzZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxpbmsuaGlkZGVuID0gdHJ1ZTtcbiAgICAgICAgKDAsIF91dGlsc0RvbS5nZXRFbGVtZW50QnlJZCkoJ2hjLWNsaWVudC1mYWlsLWNsaWVudCcpLmhpZGRlbiA9IHRydWU7XG4gICAgICB9XG4gICAgICAvLyBNYWtlIHRoZSBkZXRhaWxzIHZpc2libGVcbiAgICAgICgwLCBfdXRpbHNEb20uZ2V0RWxlbWVudEJ5SWQpKCdoYy1jbGllbnQtZmFpbC1kZXRhaWwnKS5oaWRkZW4gPSBmYWxzZTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gT3RoZXJ3aXNlIGhpZGUgdGhlIGRldGFpbHNcbiAgICAgICgwLCBfdXRpbHNEb20uZ2V0RWxlbWVudEJ5SWQpKCdoYy1jbGllbnQtZmFpbC11cmknKS5oaWRkZW4gPSB0cnVlO1xuICAgICAgKDAsIF91dGlsc0RvbS5nZXRFbGVtZW50QnlJZCkoJ2hjLWNsaWVudC1mYWlsLWRldGFpbCcpLmhpZGRlbiA9IHRydWU7XG4gICAgfVxuICAgIC8vIE1ha2UgdGhlIGZhaWx1cmUgbWVzc2FnZSB2aXNpYmxlXG4gICAgdGhpcy5zaG93UGFuZWwoJ2hjLWNsaWVudC1mYWlsJyk7XG4gIH1cbiAgLy8gVHJpZ2dlciBhdXRob3Jpc2F0aW9uIHJldHJ5XG4gIGFzeW5jIHJldHJ5QXV0aG9yaXNhdGlvbigpIHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5pcGMucmVxdWVzdCgnL2NsaWVudGlkL3JldHJ5JywgbnVsbCk7XG4gICAgICB0aGlzLnNob3dUb2FzdCgnaW5mbycsICdSZXF1ZXN0aW5nIG5ldyBhdXRob3Jpc2F0aW9uIGNvZGUnKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGNvbnN0IG1lc3NhZ2UgPSBlcnIgaW5zdGFuY2VvZiBFcnJvciA/IGVyci5tZXNzYWdlIDogU3RyaW5nKGVycik7XG4gICAgICB0aGlzLnNob3dUb2FzdCgnZXJyb3InLCBgVW5hYmxlIHRvIHJldHJ5IGF1dGhvcmlzYXRpb246ICR7bWVzc2FnZX1gKTtcbiAgICB9XG4gIH1cbiAgLy8gU2hvdyB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgYW5kIGhpZGUgYWxsIG90aGVyc1xuICBzaG93UGFuZWwoaWRTaG93KSB7XG4gICAgZm9yIChjb25zdCBpZCBvZiBbJ2hjLWNsaWVudC1mYWlsJywgJ2hjLWNsaWVudC11c2VyJ10pIHtcbiAgICAgICgwLCBfdXRpbHNEb20uZ2V0RWxlbWVudEJ5SWQpKGlkKS5oaWRkZW4gPSBpZCAhPT0gaWRTaG93O1xuICAgIH1cbiAgfVxuICAvLyBEaXNwbGF5IGEgdG9hc3Qgbm90aWZpY2F0aW9uXG4gIHNob3dUb2FzdChsZXZlbCwgbWVzc2FnZSkge1xuICAgIC8vIEF2b2lkIGR1cGxpY2F0ZSB0b2FzdCBub3RpZmljYXRpb25zXG4gICAgY29uc3Qga2V5ID0gYCR7bGV2ZWx9IC0gJHttZXNzYWdlfWA7XG4gICAgaWYgKHRoaXMubGFzdFRvYXN0ID09PSBrZXkpIHJldHVybjtcbiAgICB0aGlzLmxhc3RUb2FzdCA9IGtleTtcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGlmICh0aGlzLmxhc3RUb2FzdCA9PT0ga2V5KSB0aGlzLmxhc3RUb2FzdCA9IHVuZGVmaW5lZDtcbiAgICB9LCBUT0FTVF9ERURVUF9USU1FKTtcbiAgICAvLyBEaXNwbGF5IHRoZSB0b2FzdCBub3RpZmljYXRpb25cbiAgICB3aW5kb3cuaG9tZWJyaWRnZS50b2FzdFtsZXZlbF0obWVzc2FnZSwgJ0hvbWUgQ29ubmVjdCBDbGllbnQnKTtcbiAgfVxufVxuZXhwb3J0cy5DbGllbnRDbGllbnRJRCA9IENsaWVudENsaWVudElEO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ9dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p1WVcxbGN5STZXeUpmZFhScGJITWlMQ0p5WlhGMWFYSmxJaXdpWDNWMGFXeHpSRzl0SWl3aVZFOUJVMVJmUkVWRVZWQmZWRWxOUlNJc0lrMVRJaXdpUTJ4cFpXNTBRMnhwWlc1MFNVUWlMQ0pzYjJjaUxDSnBjR01pTENKamJHbGxiblJEYjI1bWFXY2lMQ0pzWVhOMFZHOWhjM1FpTENKdmJrWmhhV3dpTENKdmJrRndjR3hwWVc1alpYTWlMQ0pqYjI1emRISjFZM1J2Y2lJc0ltOXVSWFpsYm5RaUxDSnpkR0YwZFhNaUxDSnZia05zYVdWdWRGTjBZWFIxY3lJc0luTmxkRU5zYVdWdWRDSXNJbU52Ym1acFp5SXNJbkJ5WlhCaGNtVkRiR2xsYm5SRGIyNW1hV2NpTENKeVpYRjFaWE4wSWl3aVpYSnlJaXdpYldWemMyRm5aU0lzSWtWeWNtOXlJaXdpVTNSeWFXNW5JaXdpYzJodmQxUnZZWE4wSWl3aWRXNWtaV1pwYm1Wa0lpd2ljMmh2ZDFCaGJtVnNJaXdpWkdWaWRXY2lMQ0pwYm1Oc2RXUmxjeUlzSW1Oc2FXVnVkR2xrSWl3aWRHVnpkQ0lzSW1Gd2NHeHBZVzVqWlhNaUxDSmhkWFJvYjNKcGMyRjBhVzl1SWl3aWMzUmhkR1VpTENKemFHOTNWWE5sY2tGMWRHaHZjbWx6WVhScGIyNGlMQ0p6YUc5M1JtRnBiQ0lzSW14cGJtc2lMQ0puWlhSRmJHVnRaVzUwUW5sSlpDSXNJbk5sZEVGMGRISnBZblYwWlNJc0luVnlhU0lzSW5ObGRGTnNiM1JVWlhoMElpd2laRzlqZFcxbGJuUWlMQ0pqYjJSbElpd2liMjVqYkdsamF5SXNJbkpsZEhKNVFYVjBhRzl5YVhOaGRHbHZiaUlzSW5CeWIyZHlaWE56SWl3aVkyeGhjM05NYVhOMElpd2ljbVZ0YjNabElpd2laWGh3YVhKbGN5SXNJbk4wZVd4bElpd2lkSEpoYm5OcGRHbHZia1IxY21GMGFXOXVJaXdpUkdGMFpTSXNJbTV2ZHlJc0ltOW1abk5sZEVobGFXZG9kQ0lzSW1Ga1pDSXNJblJsZUhSRGIyNTBaVzUwSWl3aWFHbGtaR1Z1SWl3aWNtVjBjbmxoWW14bElpd2lhR1ZzY0NJc0luTmxkRlJsZUhRaUxDSnBaQ0lzSW5SbGVIUWlMQ0p5WlhCc1lXTmxRMmhwYkdSeVpXNGlMQ0p0WVhBaUxDSndZWEpoWjNKaGNHZ2lMQ0pqYkc5dVpWUmxiWEJzWVhSbElpd2ljSEpsYzJOeWFYQjBJaXdpY0c5emRITmpjbWx3ZENJc0ltTnNhV1Z1ZENJc0lrOWlhbVZqZENJc0ltVnVkSEpwWlhNaUxDSnpaWFIwYVc1bmN5SXNJbXRsZVNJc0luWmhiSFZsSWl3aVlXTjBhVzl1SWl3aWFXUlRhRzkzSWl3aWJHVjJaV3dpTENKelpYUlVhVzFsYjNWMElpd2lkMmx1Wkc5M0lpd2lhRzl0WldKeWFXUm5aU0lzSW5SdllYTjBJaXdpWlhod2IzSjBjeUpkTENKemIzVnlZMlZ6SWpwYklpNHVMeTR1THk0dUwzTnlZeTlvYjIxbFluSnBaR2RsTFhWcEwzQjFZbXhwWXk5amJHbGxiblF0WTJ4cFpXNTBhV1F1ZEhNaVhTd2ljMjkxY21ObGMwTnZiblJsYm5RaU9sdHVkV3hzWFN3aWJXRndjR2x1WjNNaU9pSTdPenM3T3p0QlFWTkJMRWxCUVVGQkxFMUJRVUVzUjBGQlFVTXNUMEZCUVR0QlFVVkJMRWxCUVVGRExGTkJRVUVzUjBGQlFVUXNUMEZCUVR0QlFWaEJPMEZCUTBFN08wRkJZVUU3UVVGRFFTeE5RVUZOUlN4blFrRkJaMElzUjBGQlJ5eERRVUZETEVkQlFVZERMRk5CUVVVN1FVRkZMMEk3UVVGRFRTeE5RVUZQUXl4alFVRmpPMFZCWVVaRExFZEJRVUU3UlVGQmMwSkRMRWRCUVVFN1JVRllNME03UlVGRFFVTXNXVUZCV1R0RlFVVmFPMFZCUTBGRExGTkJRVk03UlVGRlZEdEZRVU5CUXl4TlFVRk5PMFZCUTA1RExGbEJRVms3UlVGRldqdEZRVU5CUXl4WlFVRnhRazRzUjBGQlZ5eEZRVUZYUXl4SFFVRmpPMGxCUVhCRExFdEJRVUZFTEVkQlFVY3NSMEZCU0VFc1IwRkJSenRKUVVGdFFpeExRVUZCUXl4SFFVRkhMRWRCUVVoQkxFZEJRVWM3U1VGRE1VTXNTVUZCU1N4RFFVRkRRU3hIUVVGSExFTkJRVU5OTEU5QlFVOHNRMEZCUXl4UlFVRlJMRVZCUVVWRExFMUJRVTBzU1VGQlJ6dE5RVUZITEVsQlFVa3NRMEZCUTBNc1kwRkJZeXhEUVVGRFJDeE5RVUZOTEVOQlFVTTdTVUZCUlN4RFFVRkRMRU5CUVVNN1JVRkRNVVU3UlVGRlFUdEZRVU5CTEUxQlFVMUZMRk5CUVZOQkxFTkJRVU5ETEUxQlFUWkNPMGxCUTNwRExFMUJRVTFVTEZsQlFWa3NSMEZCUnl4SlFVRkpMRU5CUVVOVkxHMUNRVUZ0UWl4RFFVRkRSQ3hOUVVGTkxFTkJRVU03U1VGRGNrUXNTVUZCU1ZRc1dVRkJXU3hGUVVGRk8wMUJRMlE3VFVGRFFTeEpRVUZKTEVOQlFVTkJMRmxCUVZrc1IwRkJSMEVzV1VGQldUdE5RVU5vUXl4SlFVRkpPMUZCUTBFc1RVRkJUVTBzVFVGQlRTeEhRVUZITEUxQlFVMHNTVUZCU1N4RFFVRkRVQ3hIUVVGSExFTkJRVU5aTEU5QlFVOHNRMEZCUXl4WFFVRlhMRVZCUVVWWUxGbEJRVmtzUTBGQlF6dFJRVU5vUlN4SlFVRkpMRU5CUVVOUExHTkJRV01zUTBGQlEwUXNUVUZCVFN4RFFVRkRPMDFCUXk5Q0xFTkJRVU1zUTBGQlF5eFBRVUZQVFN4SFFVRkhMRVZCUVVVN1VVRkRWaXhOUVVGTlF5eFBRVUZQTEVkQlFVZEVMRWRCUVVjc1dVRkJXVVVzUzBGQlN5eEhRVUZIUml4SFFVRkhMRU5CUVVORExFOUJRVThzUjBGQlIwVXNUVUZCVFN4RFFVRkRTQ3hIUVVGSExFTkJRVU03VVVGRGFFVXNTVUZCU1N4RFFVRkRTU3hUUVVGVExFTkJRVU1zVDBGQlR5eEZRVUZGTEcxRFFVRnRRMGdzVDBGQlR5eEZRVUZGTEVOQlFVTTdUVUZEZWtVN1NVRkRTaXhEUVVGRExFMUJRVTA3VFVGRFNEdE5RVU5CTEVsQlFVa3NRMEZCUTJJc1dVRkJXU3hIUVVGSGFVSXNVMEZCVXp0TlFVTTNRaXhKUVVGSkxFTkJRVU5ETEZOQlFWTXNSVUZCUlR0TlFVTm9RaXhKUVVGSkxFTkJRVU5tTEZsQlFWa3NSMEZCUlN4RFFVRkZPMGxCUTNwQ08wVkJRMG83UlVGRlFUdEZRVU5CVHl4dFFrRkJiVUpCTEVOQlFVTkVMRTFCUVRaQ08wbEJRemRETEVsQlFVbEJMRTFCUVUwc1EwRkJRMVVzUzBGQlN5eEZRVUZGUXl4UlFVRlJMRU5CUVVNc2FVSkJRV2xDTEVOQlFVTXNSVUZCUlR0TlFVTXpRenROUVVOQkxFOUJRVTg3VVVGQlJTeEhRVUZIV0N4TlFVRk5PMUZCUVVWWkxGRkJRVkVzUlVGQlJUdE5RVUZGTEVOQlFXdENPMGxCUTNSRUxFTkJRVU1zVFVGQlRTeEpRVUZKV2l4TlFVRk5MRU5CUVVOWkxGRkJRVkVzUzBGQlMwb3NVMEZCVXl4SlFVRkpMR2xDUVVGcFFpeERRVUZEU3l4SlFVRkpMRU5CUVVOaUxFMUJRVTBzUTBGQlExa3NVVUZCVVN4RFFVRkRMRVZCUVVVN1RVRkRha1k3VFVGRFFTeFBRVUZQV2l4TlFVRnpRanRKUVVOcVF6dEZRVU5LTzBWQlJVRTdSVUZEUVVZc1kwRkJZMEVzUTBGQlEwUXNUVUZCYzBJN1NVRkRha003U1VGRFFTeEpRVUZKTEVsQlFVa3NRMEZCUTA0c1dVRkJXU3hGUVVGRmNVSXNVVUZCVVN4TFFVRkxaaXhOUVVGTkxFTkJRVU5sTEZGQlFWRXNSVUZCUlR0SlFVVnlSRHRKUVVOQkxFbEJRVWtzUTBGQlEyeENMRmxCUVZrc1IwRkJSMGNzVFVGQlRTeERRVUZEYVVJc1ZVRkJWU3hEUVVGRE8wbEJSWFJETzBsQlEwRXNVVUZCVVdwQ0xFMUJRVTBzUTBGQlEydENMR0ZCUVdFc1JVRkJSVU1zUzBGQlN6dE5RVU51UXl4TFFVRkxMRk5CUVZNN1VVRkRWaXhKUVVGSkxFTkJRVU5VTEZOQlFWTXNRMEZCUXl4VFFVRlRMRVZCUVVVc2VVSkJRWGxDTEVOQlFVTTdVVUZEY0VRc1NVRkJTU3hEUVVGRFJTeFRRVUZUTEVWQlFVVTdVVUZEYUVJN1RVRkRTaXhMUVVGTExFMUJRVTA3VVVGRFVDeEpRVUZKTEVOQlFVTkdMRk5CUVZNc1EwRkJReXhOUVVGTkxFVkJRVVVzTmtKQlFUWkNMRU5CUVVNN1VVRkRja1FzU1VGQlNTeERRVUZEVlN4eFFrRkJjVUlzUTBGQlEzQkNMRTFCUVUwc1EwRkJRMnRDTEdGQlFXRXNRMEZCUXp0UlFVTm9SRHROUVVOS0xFdEJRVXNzVFVGQlRUdFJRVU5RTEVsQlFVa3NRMEZCUTFJc1UwRkJVeXhEUVVGRExFOUJRVThzUlVGQlJTeHpRa0ZCYzBJc1EwRkJRenRSUVVNdlF5eEpRVUZKTEVOQlFVTlhMRkZCUVZFc1EwRkJRM0pDTEUxQlFVMHNRMEZCUTJ0Q0xHRkJRV0VzUTBGQlF6dFJRVU51UXl4SlFVRkpMRU5CUVVOMFFpeE5RVUZOTEVkQlFVVXNRMEZCUlR0UlFVTm1PMDFCUTBvc1MwRkJTeXhOUVVGTk8wMUJRMWc3VVVGRFNTeEpRVUZKTEVOQlFVTm5RaXhUUVVGVExFVkJRVVU3U1VGRGNFSTdSVUZEU2p0RlFVVkJPMFZCUTBGUkxIRkNRVUZ4UWtFc1EwRkJRMFlzWVVGQmMwTTdTVUZEZUVRN1NVRkRRU3hOUVVGTlNTeEpRVUZKTEVkQlFVY3NTVUZCUVVNc2QwSkJRV01zUlVGQlF5eHhRa0ZCY1VJc1EwRkJRenRKUVVOc1JFUXNTVUZCU1N4RFFVRkRSU3haUVVGWkxFTkJRVU1zVFVGQlRTeEZRVUZGVGl4aFFVRmhMRU5CUVVOUExFZEJRVWNzUTBGQlF6dEpRVU0xUXl4SlFVRkJReXh4UWtGQlZ5eEZRVUZEUXl4UlFVRlJMRVZCUVVVN1RVRkJSU3h4UWtGQmNVSXNSVUZCUlZRc1lVRkJZU3hEUVVGRFZUdEpRVUZKTEVOQlFVVXNRMEZCUXp0SlFVVndSVHRKUVVOQkxFbEJRVUZNTEhkQ1FVRmpMRVZCUVVNc2MwSkJRWE5DTEVOQlFVTXNRMEZCUTAwc1QwRkJUeXhIUVVGSExFMUJRVmM3VFVGQlJ5eEpRVUZKTEVOQlFVTkRMR3RDUVVGclFpeEZRVUZGTzBsQlFVVXNRMEZCUXp0SlFVVXpSanRKUVVOQkxFbEJRVWtzUTBGQlEyeENMRk5CUVZNc1EwRkJReXhuUWtGQlowSXNRMEZCUXp0SlFVVm9RenRKUVVOQkxFMUJRVTF0UWl4UlFVRlJMRWRCUVVjc1NVRkJRVklzZDBKQlFXTXNSVUZCUXl4NVFrRkJlVUlzUTBGQlF6dEpRVU14UkZFc1VVRkJVU3hEUVVGRFF5eFRRVUZUTEVOQlFVTkRMRTFCUVUwc1EwRkJReXhyUWtGQmEwSXNRMEZCUXp0SlFVTTNReXhKUVVGSlppeGhRVUZoTEVOQlFVTm5RaXhQUVVGUExFdEJRVXNzU1VGQlNTeEZRVUZGTzAxQlEyaERTQ3hSUVVGUkxFTkJRVU5KTEV0QlFVc3NRMEZCUTBNc2EwSkJRV3RDTEVkQlFVY3NSMEZCUjJ4Q0xHRkJRV0VzUTBGQlEyZENMRTlCUVU4c1IwRkJSMGNzU1VGQlNTeERRVUZEUXl4SFFVRkhMRVZCUVVVc1NVRkJTVHROUVVNM1JTeExRVUZMVUN4UlFVRlJMRU5CUVVOUkxGbEJRV0VzUTBGQlF5eERRVUZETzAxQlF6ZENVaXhSUVVGUkxFTkJRVU5ETEZOQlFWTXNRMEZCUTFFc1IwRkJSeXhEUVVGRExHdENRVUZyUWl4RFFVRkRPMGxCUXpsRE8wVkJRMG83UlVGRlFUdEZRVU5CYmtJc1VVRkJVVUVzUTBGQlEwZ3NZVUZCZDBNN1NVRkROME03U1VGRFFTeEpRVUZCU3l4M1FrRkJZeXhGUVVGRExIZENRVUYzUWl4RFFVRkRMRU5CUVVOclFpeFhRVUZYTEVkQlFVZDJRaXhoUVVGaExFTkJRVU5ZTEU5QlFVODdTVUZGTlVVN1NVRkRRU3hKUVVGQlowSXNkMEpCUVdNc1JVRkJReXd3UWtGQk1FSXNRMEZCUXl4RFFVRkRiVUlzVFVGQlRTeEhRVUZITEVOQlFVTjRRaXhoUVVGaExFTkJRVU41UWl4VFFVRlRPMGxCUXpWRkxFbEJRVUZ3UWl4M1FrRkJZeXhGUVVGRExITkNRVUZ6UWl4RFFVRkRMRU5CUVV0dFFpeE5RVUZOTEVkQlFVY3NRMEZCUTNoQ0xHRkJRV0VzUTBGQlEzbENMRk5CUVZNN1NVRkROVVVzU1VGQlFYQkNMSGRDUVVGakxFVkJRVU1zYzBKQlFYTkNMRU5CUVVNc1EwRkJRMDBzVDBGQlR5eEhRVUZITEUxQlFWYzdUVUZCUnl4SlFVRkpMRU5CUVVORExHdENRVUZyUWl4RlFVRkZPMGxCUVVVc1EwRkJRenRKUVVVelJqdEpRVU5CTEVsQlFVbGFMR0ZCUVdFc1EwRkJRekJDTEVsQlFVa3NSVUZCUlR0TlFVTndRanROUVVOQkxFMUJRVTFETEU5QlFVOHNSMEZCUjBFc1EwRkJRME1zUlVGQlZTeEZRVUZGUXl4SlFVRmpMRXRCUVZVN1VVRkRha1FzU1VGQlFYaENMSGRDUVVGakxFVkJRVU4xUWl4RlFVRkZMRU5CUVVNc1EwRkJRMFVzWlVGQlpTeERRVUZETEVkQlFVZEVMRWxCUVVrc1EwRkJRMFVzUjBGQlJ5eERRVUZEUXl4VFFVRlRMRWxCUTNCRUxFbEJRVUZETEhWQ1FVRmhMRVZCUVVNc01FSkJRVEJDTEVWQlFVVTdWVUZCUlVRN1VVRkJVeXhEUVVGRkxFTkJRVVVzUTBGQlF5eERRVUZETzAxQlEyNUZMRU5CUVVNN1RVRkRSRXdzVDBGQlR5eERRVUZETERCQ1FVRXdRaXhGUVVGSE0wSXNZVUZCWVN4RFFVRkRNRUlzU1VGQlNTeERRVUZEVVN4VFFVRlRMRU5CUVVNN1RVRkRiRVZRTEU5QlFVOHNRMEZCUXl3eVFrRkJNa0lzUlVGQlJUTkNMR0ZCUVdFc1EwRkJRekJDTEVsQlFVa3NRMEZCUTFNc1ZVRkJWU3hEUVVGRE8wMUJSVzVGTzAxQlEwRXNUVUZCVFR0UlFVRkZRenROUVVGTkxFTkJRVVVzUjBGQlIzQkRMR0ZCUVdFc1EwRkJRekJDTEVsQlFVazdUVUZEY2tNc1RVRkJUWFJDTEVsQlFVa3NSMEZCUnl4SlFVRkJReXgzUWtGQll5eEZRVUZETEc5Q1FVRnZRaXhEUVVGRE8wMUJRMnBFTEVsQlFVa3JRaXhOUVVGTkxFVkJRVVU3VVVGRFVpeEpRVUZCTDBJc2QwSkJRV01zUlVGQlF5eG5RMEZCWjBNc1EwRkJReXhEUVVGRGVVSXNaVUZCWlN4RFFVTTFSQ3hIUVVGSFR5eE5RVUZOTEVOQlFVTkRMRTlCUVU4c1EwRkJRMFlzVFVGQlRTeERRVUZEUnl4UlFVRlJMRU5CUVVNc1EwRkJRMUlzUjBGQlJ5eERRVUZETEVOQlFVTXNRMEZCUTFNc1IwRkJSeXhGUVVGRlF5eExRVUZMTEVOQlFVTXNTMEZEYUVRc1NVRkJRVklzZFVKQlFXRXNSVUZCUXl3clFrRkJLMElzUlVGQlJUdFZRVUZGVHl4SFFVRkhPMVZCUVVWRE8xRkJRVXNzUTBGQlJTeERRVUZETEVOQlFVTXNRMEZCUXp0UlFVTjRSWEpETEVsQlFVa3NRMEZCUTBVc1dVRkJXU3hEUVVGRExFMUJRVTBzUlVGQlJUaENMRTFCUVUwc1EwRkJRemRDTEVkQlFVY3NRMEZCUXp0UlFVTnlRMGdzU1VGQlNTeERRVUZEYlVJc1YwRkJWeXhIUVVGSFlTeE5RVUZOTEVOQlFVTk5MRTFCUVUwc1MwRkJTeXhSUVVGUkxFZEJRVWNzYjBKQlFXOUNMRWRCUVVjc2IwSkJRVzlDTzFGQlF6TkdkRU1zU1VGQlNTeERRVUZEYjBJc1RVRkJUU3hIUVVGSExFdEJRVXM3VVVGRGJrSXNTVUZCUVc1Q0xIZENRVUZqTEVWQlFVTXNkVUpCUVhWQ0xFTkJRVU1zUTBGQlEyMUNMRTFCUVUwc1IwRkJSeXhMUVVGTE8wMUJRekZFTEVOQlFVTXNUVUZCVFR0UlFVTkljRUlzU1VGQlNTeERRVUZEYjBJc1RVRkJUU3hIUVVGSExFbEJRVWs3VVVGRGJFSXNTVUZCUVc1Q0xIZENRVUZqTEVWQlFVTXNkVUpCUVhWQ0xFTkJRVU1zUTBGQlEyMUNMRTFCUVUwc1IwRkJSeXhKUVVGSk8wMUJRM3BFTzAxQlJVRTdUVUZEUVN4SlFVRkJia0lzZDBKQlFXTXNSVUZCUXl4MVFrRkJkVUlzUTBGQlF5eERRVUZEYlVJc1RVRkJUU3hIUVVGSExFdEJRVXM3U1VGRE1VUXNRMEZCUXl4TlFVRk5PMDFCUTBnN1RVRkRRU3hKUVVGQmJrSXNkMEpCUVdNc1JVRkJReXh2UWtGQmIwSXNRMEZCUXl4RFFVRkpiVUlzVFVGQlRTeEhRVUZITEVsQlFVazdUVUZEY2tRc1NVRkJRVzVDTEhkQ1FVRmpMRVZCUVVNc2RVSkJRWFZDTEVOQlFVTXNRMEZCUTIxQ0xFMUJRVTBzUjBGQlJ5eEpRVUZKTzBsQlEzcEVPMGxCUlVFN1NVRkRRU3hKUVVGSkxFTkJRVU01UWl4VFFVRlRMRU5CUVVNc1owSkJRV2RDTEVOQlFVTTdSVUZEY0VNN1JVRkZRVHRGUVVOQkxFMUJRVTFyUWl4clFrRkJhMEpCTEVOQlFVRTdTVUZEY0VJc1NVRkJTVHROUVVOQkxFMUJRVTBzU1VGQlNTeERRVUZEY2tNc1IwRkJSeXhEUVVGRFdTeFBRVUZQTEVOQlFVTXNhVUpCUVdsQ0xFVkJRVVVzU1VGQlNTeERRVUZETzAxQlF5OURMRWxCUVVrc1EwRkJRMHNzVTBGQlV5eERRVUZETEUxQlFVMHNSVUZCUlN4dFEwRkJiVU1zUTBGQlF6dEpRVU12UkN4RFFVRkRMRU5CUVVNc1QwRkJUMG9zUjBGQlJ5eEZRVUZGTzAxQlExWXNUVUZCVFVNc1QwRkJUeXhIUVVGSFJDeEhRVUZITEZsQlFWbEZMRXRCUVVzc1IwRkJSMFlzUjBGQlJ5eERRVUZEUXl4UFFVRlBMRWRCUVVkRkxFMUJRVTBzUTBGQlEwZ3NSMEZCUnl4RFFVRkRPMDFCUTJoRkxFbEJRVWtzUTBGQlEwa3NVMEZCVXl4RFFVRkRMRTlCUVU4c1JVRkJSU3hyUTBGQmEwTklMRTlCUVU4c1JVRkJSU3hEUVVGRE8wbEJRM2hGTzBWQlEwbzdSVUZGUVR0RlFVTkJTeXhUUVVGVFFTeERRVUZEYVVRc1RVRkJaVHRKUVVOeVFpeExRVUZMTEUxQlFVMW1MRVZCUVVVc1NVRkJTU3hEUVVGRExHZENRVUZuUWl4RlFVRkZMR2RDUVVGblFpeERRVUZETEVWQlFVVTdUVUZEYmtRc1NVRkJRWFpDTEhkQ1FVRmpMRVZCUVVOMVFpeEZRVUZGTEVOQlFVTXNRMEZCUTBvc1RVRkJUU3hIUVVGSFNTeEZRVUZGTEV0QlFVdGxMRTFCUVUwN1NVRkROME03UlVGRFNqdEZRVVZCTzBWQlEwRnVSQ3hUUVVGVFFTeERRVUZEYjBRc1MwRkJjVU1zUlVGQlJYWkVMRTlCUVdVN1NVRkROVVE3U1VGRFFTeE5RVUZOYlVRc1IwRkJSeXhIUVVGSExFZEJRVWRKTEV0QlFVc3NUVUZCVFhaRUxFOUJRVThzUlVGQlJUdEpRVU51UXl4SlFVRkpMRWxCUVVrc1EwRkJRMW9zVTBGQlV5eExRVUZMSzBRc1IwRkJSeXhGUVVGRk8wbEJRelZDTEVsQlFVa3NRMEZCUXk5RUxGTkJRVk1zUjBGQlJ5dEVMRWRCUVVjN1NVRkRjRUpMTEZWQlFWVXNRMEZCUXl4TlFVRkxPMDFCUTFvc1NVRkJTU3hKUVVGSkxFTkJRVU53UlN4VFFVRlRMRXRCUVVzclJDeEhRVUZITEVWQlFVVXNTVUZCU1N4RFFVRkRMMFFzVTBGQlV5eEhRVUZIWjBJc1UwRkJVenRKUVVNeFJDeERRVUZETEVWQlFVVjBRaXhuUWtGQlowSXNRMEZCUXp0SlFVVndRanRKUVVOQk1rVXNUVUZCVFN4RFFVRkRReXhWUVVGVkxFTkJRVU5ETEV0QlFVc3NRMEZCUTBvc1MwRkJTeXhEUVVGRExFTkJRVU4yUkN4UFFVRlBMRVZCUVVVc2NVSkJRWEZDTEVOQlFVTTdSVUZEYkVVN08wRkJRMGcwUkN4UFFVRkJMRU5CUVVFMVJTeGpRVUZCTEVkQlFVRkJMR05CUVVFaUxDSnBaMjV2Y21WTWFYTjBJanBiWFgwPSIsIlwidXNlIHN0cmljdFwiO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5DbGllbnRJUEMgPSB2b2lkIDA7XG4vLyBIb21lYnJpZGdlIHBsdWdpbiBmb3IgSG9tZSBDb25uZWN0IGhvbWUgYXBwbGlhbmNlc1xuLy8gQ29weXJpZ2h0IMKpIDIwMjMgQWxleGFuZGVyIFRob3VreWRpZGVzXG4vLyBDbGllbnQtc2lkZSBJUEMgaW1wbGVtZW50YXRpb25cbmNsYXNzIENsaWVudElQQyB7XG4gIGxvZztcbiAgLy8gQ3JlYXRlIGEgbmV3IGNsaWVudCBJUEMgaW5zdGFuY2VcbiAgY29uc3RydWN0b3IobG9nKSB7XG4gICAgdGhpcy5sb2cgPSBsb2c7XG4gIH1cbiAgLy8gSXNzdWUgYSByZXF1ZXN0IHRvIHRoZSBzZXJ2ZXJcbiAgYXN5bmMgcmVxdWVzdChwYXRoLCBkYXRhKSB7XG4gICAgdHJ5IHtcbiAgICAgIHRoaXMubG9nLmRlYnVnKGByZXF1ZXN0KFwiJHtwYXRofVwiLCAlTylgLCBkYXRhKTtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHdpbmRvdy5ob21lYnJpZGdlLnJlcXVlc3QocGF0aCwgZGF0YSk7XG4gICAgICB0aGlzLmxvZy5kZWJ1ZyhgcmVxdWVzdChcIiR7cGF0aH1cIiwgJU8pID0+YCwgZGF0YSwgcmVzdWx0KTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICB0aGlzLmxvZy5lcnJvcihgcmVxdWVzdChcIiR7cGF0aH1cIiwgJU8pID0+YCwgZGF0YSwgZXJyKTtcbiAgICAgIHRocm93IGVycjtcbiAgICB9XG4gIH1cbiAgLy8gQWRkIGFuIGV2ZW50IGxpc3RlbmVyXG4gIG9uRXZlbnQoZXZlbnQsIGNhbGxiYWNrKSB7XG4gICAgd2luZG93LmhvbWVicmlkZ2UuYWRkRXZlbnRMaXN0ZW5lcihldmVudCwgYXN5bmMgZXZ0ID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IGRhdGEgPSBldnQuZGF0YTtcbiAgICAgICAgaWYgKGV2ZW50ICE9PSAnbG9nJykgdGhpcy5sb2cuZGVidWcoYG9uRXZlbnQoXCIke2V2ZW50fVwiKSA9PiBjYWxsYmFja2AsIGRhdGEpO1xuICAgICAgICBhd2FpdCBjYWxsYmFjayhkYXRhKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICB0aGlzLmxvZy5lcnJvcihgb25FdmVudChcIiR7ZXZlbnR9XCIpID0+YCwgZXJyKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufVxuZXhwb3J0cy5DbGllbnRJUEMgPSBDbGllbnRJUEM7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldD11dGYtODtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnVZVzFsY3lJNld5SkRiR2xsYm5SSlVFTWlMQ0pzYjJjaUxDSmpiMjV6ZEhKMVkzUnZjaUlzSW5KbGNYVmxjM1FpTENKd1lYUm9JaXdpWkdGMFlTSXNJbVJsWW5Wbklpd2ljbVZ6ZFd4MElpd2lkMmx1Wkc5M0lpd2lhRzl0WldKeWFXUm5aU0lzSW1WeWNpSXNJbVZ5Y205eUlpd2liMjVGZG1WdWRDSXNJbVYyWlc1MElpd2lZMkZzYkdKaFkyc2lMQ0poWkdSRmRtVnVkRXhwYzNSbGJtVnlJaXdpWlhaMElpd2laWGh3YjNKMGN5SmRMQ0p6YjNWeVkyVnpJanBiSWk0dUx5NHVMeTR1TDNOeVl5OW9iMjFsWW5KcFpHZGxMWFZwTDNCMVlteHBZeTlqYkdsbGJuUXRhWEJqTG5SeklsMHNJbk52ZFhKalpYTkRiMjUwWlc1MElqcGJiblZzYkYwc0ltMWhjSEJwYm1keklqb2lPenM3T3pzN1FVRkJRVHRCUVVOQk8wRkJUVUU3UVVGRFRTeE5RVUZQUVN4VFFVRlRPMFZCUjBkRExFZEJRVUU3UlVGRWNrSTdSVUZEUVVNc1dVRkJjVUpFTEVkQlFWYzdTVUZCV0N4TFFVRkJRU3hIUVVGSExFZEJRVWhCTEVkQlFVYzdSVUZCVnp0RlFVVnVRenRGUVVOQkxFMUJRVTFGTEU5QlFVOUJMRU5CUVRCQ1F5eEpRVUZWTEVWQlFVVkRMRWxCUVhsQ08wbEJRM2hGTEVsQlFVazdUVUZEUVN4SlFVRkpMRU5CUVVOS0xFZEJRVWNzUTBGQlEwc3NTMEZCU3l4RFFVRkRMRmxCUVZsR0xFbEJRVWtzVVVGQlVTeEZRVUZGUXl4SlFVRkpMRU5CUVVNN1RVRkRPVU1zVFVGQlRVVXNUVUZCVFN4SFFVRlpMRTFCUVUxRExFMUJRVTBzUTBGQlEwTXNWVUZCVlN4RFFVRkRUaXhQUVVGUExFTkJRVU5ETEVsQlFVa3NSVUZCUlVNc1NVRkJTU3hEUVVGRE8wMUJRMjVGTEVsQlFVa3NRMEZCUTBvc1IwRkJSeXhEUVVGRFN5eExRVUZMTEVOQlFVTXNXVUZCV1VZc1NVRkJTU3hYUVVGWExFVkJRVVZETEVsQlFVa3NSVUZCUlVVc1RVRkJUU3hEUVVGRE8wMUJRM3BFTEU5QlFVOUJMRTFCUVRoQ08wbEJRM3BETEVOQlFVTXNRMEZCUXl4UFFVRlBSeXhIUVVGSExFVkJRVVU3VFVGRFZpeEpRVUZKTEVOQlFVTlVMRWRCUVVjc1EwRkJRMVVzUzBGQlN5eERRVUZETEZsQlFWbFFMRWxCUVVrc1YwRkJWeXhGUVVGRlF5eEpRVUZKTEVWQlFVVkxMRWRCUVVjc1EwRkJRenROUVVOMFJDeE5RVUZOUVN4SFFVRkhPMGxCUTJJN1JVRkRTanRGUVVWQk8wVkJRMEZGTEU5QlFVOUJMRU5CUVRSQ1F5eExRVUZaTEVWQlFVVkRMRkZCUVN0RU8wbEJRelZIVGl4TlFVRk5MRU5CUVVORExGVkJRVlVzUTBGQlEwMHNaMEpCUVdkQ0xFTkJRVU5HTEV0QlFVc3NSVUZCUlN4TlFVRlBSeXhIUVVGSExFbEJRVWs3VFVGRGNFUXNTVUZCU1R0UlFVTkJMRTFCUVUxWUxFbEJRVWtzUjBGQlNWY3NSMEZCYlVRc1EwRkJRMWdzU1VGQlNUdFJRVU4wUlN4SlFVRkpVU3hMUVVGTExFdEJRVXNzUzBGQlN5eEZRVUZGTEVsQlFVa3NRMEZCUTFvc1IwRkJSeXhEUVVGRFN5eExRVUZMTEVOQlFVTXNXVUZCV1U4c1MwRkJTeXhuUWtGQlowSXNSVUZCUlZJc1NVRkJTU3hEUVVGRE8xRkJRelZGTEUxQlFVMVRMRkZCUVZFc1EwRkJRMVFzU1VGQlNTeERRVUZETzAxQlEzaENMRU5CUVVNc1EwRkJReXhQUVVGUFN5eEhRVUZITEVWQlFVVTdVVUZEVml4SlFVRkpMRU5CUVVOVUxFZEJRVWNzUTBGQlExVXNTMEZCU3l4RFFVRkRMRmxCUVZsRkxFdEJRVXNzVDBGQlR5eEZRVUZGU0N4SFFVRkhMRU5CUVVNN1RVRkRha1E3U1VGRFNpeERRVUZETEVOQlFVTTdSVUZEVGpzN1FVRkRTRThzVDBGQlFTeERRVUZCYWtJc1UwRkJRU3hIUVVGQlFTeFRRVUZCSWl3aWFXZHViM0psVEdsemRDSTZXMTE5IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbnJlcXVpcmUoXCJAaG9tZWJyaWRnZS9wbHVnaW4tdWktdXRpbHMvZGlzdC91aS5pbnRlcmZhY2UuanNcIik7XG52YXIgX2xvZ2dlciA9IHJlcXVpcmUoXCIuL2xvZ2dlci5qc1wiKTtcbnZhciBfY29uZmlnID0gcmVxdWlyZShcIi4vY29uZmlnLmpzXCIpO1xudmFyIF9jYXJkcyA9IHJlcXVpcmUoXCIuL2NhcmRzLmpzXCIpO1xudmFyIF9jbGllbnRDbGllbnRpZCA9IHJlcXVpcmUoXCIuL2NsaWVudC1jbGllbnRpZC5qc1wiKTtcbnZhciBfZm9ybXMgPSByZXF1aXJlKFwiLi9mb3Jtcy5qc1wiKTtcbnZhciBfY2xpZW50SXBjID0gcmVxdWlyZShcIi4vY2xpZW50LWlwYy5qc1wiKTtcbnZhciBfYXBpU3RhdHVzID0gcmVxdWlyZShcIi4vYXBpLXN0YXR1cy5qc1wiKTtcbi8vIEhvbWVicmlkZ2UgcGx1Z2luIGZvciBIb21lIENvbm5lY3QgaG9tZSBhcHBsaWFuY2VzXG4vLyBDb3B5cmlnaHQgwqkgMjAyMy0yMDI0IEFsZXhhbmRlciBUaG91a3lkaWRlc1xuXG4vLyBBIEhvbWVicmlkZ2UgSG9tZUNvbm5lY3QgY3VzdG9tIFVJIGNsaWVudFxuY2xhc3MgQ2xpZW50IHtcbiAgLy8gQ3VzdG9tIGxvZ2dlcnNcbiAgbG9nO1xuICBzZXJ2ZXJMb2c7XG4gIC8vIExvY2FsIHJlc291cmNlc1xuICBpcGM7XG4gIC8vIENyZWF0ZSBhIG5ldyBjdXN0b20gVUkgY2xpZW50XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIC8vIENyZWF0ZSBhIGxvY2FsIGxvZ2dlciBhbmQgSVBDIGNsaWVudFxuICAgIHRoaXMubG9nID0gbmV3IF9sb2dnZXIuQ2xpZW50TG9nZ2VyKCk7XG4gICAgdGhpcy5sb2cuZGVidWcoJ2hvbWVicmlkZ2UucGx1Z2luJywgd2luZG93LmhvbWVicmlkZ2UucGx1Z2luKTtcbiAgICB0aGlzLmlwYyA9IG5ldyBfY2xpZW50SXBjLkNsaWVudElQQyh0aGlzLmxvZyk7XG4gICAgLy8gV2FpdCBmb3IgdGhlIHNlcnZlciBiZWZvcmUgY29udGludWluZyBpbml0aWFsaXNhdGlvblxuICAgIHRoaXMuaXBjLm9uRXZlbnQoJ3JlYWR5JywgKCkgPT4ge1xuICAgICAgdGhpcy5zZXJ2ZXJSZWFkeSgpO1xuICAgIH0pO1xuICB9XG4gIC8vIFRoZSBzZXJ2ZXIgaXMgcmVhZHkgc28gZmluaXNoIGluaXRpYWxpc2luZyB0aGUgY2xpZW50XG4gIHNlcnZlclJlYWR5KCkge1xuICAgIC8vIFN0YXJ0IHJlY2VpdmluZyAoaW1wb3J0YW50KSBsb2cgbWVzc2FnZXMgZnJvbSB0aGUgc2VydmVyXG4gICAgdGhpcy5zZXJ2ZXJMb2cgPSBuZXcgX2xvZ2dlci5TZXJ2ZXJMb2dnZXIodGhpcy5pcGMsIFwid2FyblwiIC8qIExvZ0xldmVsLldBUk4gKi8pO1xuICAgIC8vIENyZWF0ZSBhbGwgb2YgdGhlIHJlcXVpcmVkIHJlc291cmNlc1xuICAgIGNvbnN0IGNvbmZpZyA9IG5ldyBfY29uZmlnLkNvbmZpZyh0aGlzLmxvZywgdGhpcy5pcGMpO1xuICAgIGNvbnN0IGZvcm1zID0gbmV3IF9mb3Jtcy5Gb3Jtcyh0aGlzLmxvZywgdGhpcy5pcGMsIGNvbmZpZyk7XG4gICAgY29uc3QgY2FyZHMgPSBuZXcgX2NhcmRzLkNhcmRzKHRoaXMubG9nKTtcbiAgICBjb25zdCBjbGllbnQgPSBuZXcgX2NsaWVudENsaWVudGlkLkNsaWVudENsaWVudElEKHRoaXMubG9nLCB0aGlzLmlwYyk7XG4gICAgbmV3IF9hcGlTdGF0dXMuQVBJU3RhdHVzKHRoaXMubG9nKTtcbiAgICAvLyBDcmVhdGUgY2FyZHMgZm9yIHRoZSBnbG9iYWwgc2V0dGluZ3MgYW5kIGVhY2ggYXZhaWxhYmxlIGFwcGxpYW5jZVxuICAgIGNhcmRzLnNldE5vbkFwcGxpYW5jZXMoW3tcbiAgICAgIGlkOiBfZm9ybXMuRm9ybUlkLkdsb2JhbCxcbiAgICAgIGljb246ICdnbG9iYWwnLFxuICAgICAgbmFtZTogJ0dlbmVyYWwgU2V0dGluZ3MnXG4gICAgfV0pO1xuICAgIGNsaWVudC5vbkFwcGxpYW5jZXMgPSBhcHBsaWFuY2VzID0+IHtcbiAgICAgIGNhcmRzLnNldEFwcGxpYW5jZXMoYXBwbGlhbmNlcyA/PyBbXSk7XG4gICAgfTtcbiAgICBjYXJkcy5vblNlbGVjdCA9IGlkID0+IHtcbiAgICAgIGZvcm1zLnNob3dGb3JtKGlkKTtcbiAgICB9O1xuICAgIC8vIEF0dGVtcHQgdG8gYXV0aG9yaXNlIGEgY2xpZW50IHdoZW4gdGhlIGNvbmZpZ3VyYXRpb24gY2hhbmdlc1xuICAgIGNvbmZpZy5vbkdsb2JhbCA9IGNvbmZpZyA9PiB7XG4gICAgICBjbGllbnQuc2V0Q2xpZW50KGNvbmZpZyk7XG4gICAgfTtcbiAgICBjbGllbnQub25GYWlsID0gKCkgPT4ge1xuICAgICAgZm9ybXMuc2hvd0Zvcm0oX2Zvcm1zLkZvcm1JZC5HbG9iYWwpO1xuICAgIH07XG4gIH1cbn1cbi8vIENyZWF0ZSBhIGN1c3RvbSBVSSBjbGllbnQgaW5zdGFuY2Vcbm5ldyBDbGllbnQoKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRhdGE6YXBwbGljYXRpb24vanNvbjtjaGFyc2V0PXV0Zi04O2Jhc2U2NCxleUoyWlhKemFXOXVJam96TENKdVlXMWxjeUk2V3lKeVpYRjFhWEpsSWl3aVgyeHZaMmRsY2lJc0lsOWpiMjVtYVdjaUxDSmZZMkZ5WkhNaUxDSmZZMnhwWlc1MFEyeHBaVzUwYVdRaUxDSmZabTl5YlhNaUxDSmZZMnhwWlc1MFNYQmpJaXdpWDJGd2FWTjBZWFIxY3lJc0lrTnNhV1Z1ZENJc0lteHZaeUlzSW5ObGNuWmxja3h2WnlJc0ltbHdZeUlzSW1OdmJuTjBjblZqZEc5eUlpd2lRMnhwWlc1MFRHOW5aMlZ5SWl3aVpHVmlkV2NpTENKM2FXNWtiM2NpTENKb2IyMWxZbkpwWkdkbElpd2ljR3gxWjJsdUlpd2lRMnhwWlc1MFNWQkRJaXdpYjI1RmRtVnVkQ0lzSW5ObGNuWmxjbEpsWVdSNUlpd2lVMlZ5ZG1WeVRHOW5aMlZ5SWl3aVkyOXVabWxuSWl3aVEyOXVabWxuSWl3aVptOXliWE1pTENKR2IzSnRjeUlzSW1OaGNtUnpJaXdpUTJGeVpITWlMQ0pqYkdsbGJuUWlMQ0pEYkdsbGJuUkRiR2xsYm5SSlJDSXNJa0ZRU1ZOMFlYUjFjeUlzSW5ObGRFNXZia0Z3Y0d4cFlXNWpaWE1pTENKcFpDSXNJa1p2Y20xSlpDSXNJa2RzYjJKaGJDSXNJbWxqYjI0aUxDSnVZVzFsSWl3aWIyNUJjSEJzYVdGdVkyVnpJaXdpWVhCd2JHbGhibU5sY3lJc0luTmxkRUZ3Y0d4cFlXNWpaWE1pTENKdmJsTmxiR1ZqZENJc0luTm9iM2RHYjNKdElpd2liMjVIYkc5aVlXd2lMQ0p6WlhSRGJHbGxiblFpTENKdmJrWmhhV3dpWFN3aWMyOTFjbU5sY3lJNld5SXVMaTh1TGk4dUxpOXpjbU12YUc5dFpXSnlhV1JuWlMxMWFTOXdkV0pzYVdNdlkyeHBaVzUwTG5SeklsMHNJbk52ZFhKalpYTkRiMjUwWlc1MElqcGJiblZzYkYwc0ltMWhjSEJwYm1keklqb2lPenRCUVVkQlFTeFBRVUZCTzBGQlIwRXNTVUZCUVVNc1QwRkJRU3hIUVVGQlJDeFBRVUZCTzBGQlEwRXNTVUZCUVVVc1QwRkJRU3hIUVVGQlJpeFBRVUZCTzBGQlEwRXNTVUZCUVVjc1RVRkJRU3hIUVVGQlNDeFBRVUZCTzBGQlEwRXNTVUZCUVVrc1pVRkJRU3hIUVVGQlNpeFBRVUZCTzBGQlEwRXNTVUZCUVVzc1RVRkJRU3hIUVVGQlRDeFBRVUZCTzBGQlEwRXNTVUZCUVUwc1ZVRkJRU3hIUVVGQlRpeFBRVUZCTzBGQlEwRXNTVUZCUVU4c1ZVRkJRU3hIUVVGQlVDeFBRVUZCTzBGQldrRTdRVUZEUVRzN1FVRmhRVHRCUVVOQkxFMUJRVTFSTEUxQlFVMDdSVUZGVWp0RlFVTlRReXhIUVVGSE8wVkJRMXBETEZOQlFWTTdSVUZGVkR0RlFVTlRReXhIUVVGSE8wVkJSVm83UlVGRFFVTXNXVUZCUVR0SlFVTkpPMGxCUTBFc1NVRkJTU3hEUVVGRFNDeEhRVUZITEVkQlFVY3NTVUZCU1Vrc2IwSkJRVmtzUlVGQlJUdEpRVU0zUWl4SlFVRkpMRU5CUVVOS0xFZEJRVWNzUTBGQlEwc3NTMEZCU3l4RFFVRkRMRzFDUVVGdFFpeEZRVUZGUXl4TlFVRk5MRU5CUVVORExGVkJRVlVzUTBGQlEwTXNUVUZCVFN4RFFVRkRPMGxCUXpkRUxFbEJRVWtzUTBGQlEwNHNSMEZCUnl4SFFVRkhMRWxCUVVsUExHOUNRVUZUTEVOQlFVTXNTVUZCU1N4RFFVRkRWQ3hIUVVGSExFTkJRVU03U1VGRmJFTTdTVUZEUVN4SlFVRkpMRU5CUVVORkxFZEJRVWNzUTBGQlExRXNUMEZCVHl4RFFVRkRMRTlCUVU4c1JVRkJSU3hOUVVGTE8wMUJRVWNzU1VGQlNTeERRVUZEUXl4WFFVRlhMRVZCUVVVN1NVRkJSU3hEUVVGRExFTkJRVU03UlVGRE5VUTdSVUZGUVR0RlFVTkJRU3hYUVVGWFFTeERRVUZCTzBsQlExQTdTVUZEUVN4SlFVRkpMRU5CUVVOV0xGTkJRVk1zUjBGQlJ5eEpRVUZKVnl4dlFrRkJXU3hEUVVGRExFbEJRVWtzUTBGQlExWXNSMEZCUnl3MlFrRkJaMEk3U1VGRk1VUTdTVUZEUVN4TlFVRk5WeXhOUVVGTkxFZEJRVWNzU1VGQlNVTXNZMEZCVFN4RFFVRkRMRWxCUVVrc1EwRkJRMlFzUjBGQlJ5eEZRVUZGTEVsQlFVa3NRMEZCUTBVc1IwRkJSeXhEUVVGRE8wbEJRemRETEUxQlFVMWhMRXRCUVVzc1IwRkJTU3hKUVVGSlF5eFpRVUZMTEVOQlFVTXNTVUZCU1N4RFFVRkRhRUlzUjBGQlJ5eEZRVUZGTEVsQlFVa3NRMEZCUTBVc1IwRkJSeXhGUVVGRlZ5eE5RVUZOTEVOQlFVTTdTVUZEY0VRc1RVRkJUVWtzUzBGQlN5eEhRVUZKTEVsQlFVbERMRmxCUVVzc1EwRkJReXhKUVVGSkxFTkJRVU5zUWl4SFFVRkhMRU5CUVVNN1NVRkRiRU1zVFVGQlRXMUNMRTFCUVUwc1IwRkJSeXhKUVVGSlF5dzRRa0ZCWXl4RFFVRkRMRWxCUVVrc1EwRkJRM0JDTEVkQlFVY3NSVUZCUlN4SlFVRkpMRU5CUVVORkxFZEJRVWNzUTBGQlF6dEpRVU55UkN4SlFVRkpiVUlzYjBKQlFWTXNRMEZCUXl4SlFVRkpMRU5CUVVOeVFpeEhRVUZITEVOQlFVTTdTVUZGZGtJN1NVRkRRV2xDTEV0QlFVc3NRMEZCUTBzc1owSkJRV2RDTEVOQlFVTXNRMEZCUXp0TlFVRkZReXhGUVVGRkxFVkJRVVZETEdGQlFVMHNRMEZCUTBNc1RVRkJUVHROUVVGRlF5eEpRVUZKTEVWQlFVVXNVVUZCVVR0TlFVRkZReXhKUVVGSkxFVkJRVVU3U1VGQmEwSXNRMEZCUlN4RFFVRkRMRU5CUVVNN1NVRkRla1pTTEUxQlFVMHNRMEZCUTFNc1dVRkJXU3hIUVVGSlF5eFZRVUZWTEVsQlFWYzdUVUZCUjFvc1MwRkJTeXhEUVVGRFlTeGhRVUZoTEVOQlFVTkVMRlZCUVZVc1NVRkJTU3hGUVVGRkxFTkJRVU03U1VGQlJTeERRVUZETzBsQlEzWkdXaXhMUVVGTExFTkJRVU5qTEZGQlFWRXNSMEZCVTFJc1JVRkJWeXhKUVVGVk8wMUJRVWRTTEV0QlFVc3NRMEZCUTJsQ0xGRkJRVkVzUTBGQlExUXNSVUZCUlN4RFFVRkRPMGxCUVVVc1EwRkJRenRKUVVWd1JUdEpRVU5CVml4TlFVRk5MRU5CUVVOdlFpeFJRVUZSTEVkQlFVbHdRaXhOUVVGTkxFbEJRVlU3VFVGQlIwMHNUVUZCVFN4RFFVRkRaU3hUUVVGVExFTkJRVU55UWl4TlFVRk5MRU5CUVVNN1NVRkJSU3hEUVVGRE8wbEJRMnBGVFN4TlFVRk5MRU5CUVVOblFpeE5RVUZOTEVkQlFVc3NUVUZCYVVJN1RVRkJSM0JDTEV0QlFVc3NRMEZCUTJsQ0xGRkJRVkVzUTBGQlExSXNZVUZCVFN4RFFVRkRReXhOUVVGTkxFTkJRVU03U1VGQlJTeERRVUZETzBWQlF6RkZPenRCUVVkS08wRkJRMEVzU1VGQlNURkNMRTFCUVUwc1JVRkJSU0lzSW1sbmJtOXlaVXhwYzNRaU9sdGRmUT09IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLkNvbmZpZyA9IHZvaWQgMDtcbnJlcXVpcmUoXCJAaG9tZWJyaWRnZS9wbHVnaW4tdWktdXRpbHMvZGlzdC91aS5pbnRlcmZhY2UuanNcIik7XG52YXIgX3V0aWxzID0gcmVxdWlyZShcIi4uLy4uL3V0aWxzLmpzXCIpO1xudmFyIF91dGlsc0RvbSA9IHJlcXVpcmUoXCIuL3V0aWxzLWRvbS5qc1wiKTtcbnZhciBfY29uZmlnVHlwZXMgPSByZXF1aXJlKFwiLi4vLi4vdGkvY29uZmlnLXR5cGVzLmpzXCIpO1xuLy8gSG9tZWJyaWRnZSBwbHVnaW4gZm9yIEhvbWUgQ29ubmVjdCBob21lIGFwcGxpYW5jZXNcbi8vIENvcHlyaWdodCDCqSAyMDIzIEFsZXhhbmRlciBUaG91a3lkaWRlc1xuXG4vLyBUaGUgY3VycmVudCBwbHVnaW4gY29uZmlndXJhdGlvblxuY2xhc3MgQ29uZmlnIHtcbiAgbG9nO1xuICBpcGM7XG4gIC8vIFRoZSBzYXZlZCBjb25maWd1cmF0aW9uXG4gIHNhdmVkQ29uZmlnO1xuICAvLyBUaGUgY29uZmlndXJhdGlvbiBiZWluZyBlZGl0ZWRcbiAgZ2xvYmFsID0ge307XG4gIGFwcGxpYW5jZXMgPSB7fTtcbiAgb25HbG9iYWw7XG4gIC8vIFByb21pc2VzIGZvciByZXRyaWV2aW5nIHRoZSBjdXJyZW50IGNvbmZpZ3VyYXRpb25zXG4gIHJlYWR5UHJvbWlzZTtcbiAgYWN0aXZlUHJvbWlzZTtcbiAgLy8gQ3JlYXRlIGEgbmV3IGNvbmZpZ3VyYXRpb24gb2JqZWN0XG4gIGNvbnN0cnVjdG9yKGxvZywgaXBjKSB7XG4gICAgdGhpcy5sb2cgPSBsb2c7XG4gICAgdGhpcy5pcGMgPSBpcGM7XG4gICAgdGhpcy5yZWFkeVByb21pc2UgPSB0aGlzLmdldENvbmZpZygpO1xuICAgIHRoaXMuYWN0aXZlUHJvbWlzZSA9IHRoaXMuZ2V0QWN0aXZlQ29uZmlnKCk7XG4gIH1cbiAgLy8gUmV0cmlldmUgYW5kIHBhcnNlIHRoZSBjb25maWd1cmF0aW9uIHRvIGJlIGVkaXRlZFxuICBhc3luYyBnZXRDb25maWcoKSB7XG4gICAgLy8gUmV0cmlldmUgdGhlIGN1cnJlbnQgcGx1Z2luIGNvbmZpZ3VyYXRpb24gKGlmIGFueSlcbiAgICBjb25zdCBjb25maWdBcnJheSA9IGF3YWl0IHdpbmRvdy5ob21lYnJpZGdlLmdldFBsdWdpbkNvbmZpZygpO1xuICAgIGlmIChjb25maWdBcnJheVswXSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLmxvZy53YXJuKCdObyBwbHVnaW4gY29uZmlndXJhdGlvbiBmb3VuZDsgY3JlYXRpbmcgYSBuZXcgb25lJyk7XG4gICAgICB0aGlzLnNhdmVkQ29uZmlnID0ge1xuICAgICAgICBwbGF0Zm9ybTogd2luZG93LmhvbWVicmlkZ2UucGx1Z2luLmRpc3BsYXlOYW1lXG4gICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoMSA8IGNvbmZpZ0FycmF5Lmxlbmd0aCkge1xuICAgICAgICB0aGlzLmxvZy5lcnJvcihgVXNpbmcgdGhlIGZpcnN0IG9mICR7Y29uZmlnQXJyYXkubGVuZ3RofSBwbHVnaW4gY29uZmlndXJhdGlvbnNgLCBjb25maWdBcnJheSk7XG4gICAgICAgIHdpbmRvdy5ob21lYnJpZGdlLnRvYXN0LmVycm9yKCdPbmx5IGEgc2luZ2xlIHBsYXRmb3JtIGluc3RhbmNlIGlzIHN1cHBvcnRlZDsgdXNpbmcgdGhlIGZpcnN0JywgJ011bHRpcGxlIENvbmZpZ3VyYXRpb24gQmxvY2tzJyk7XG4gICAgICB9XG4gICAgICB0aGlzLnNhdmVkQ29uZmlnID0gY29uZmlnQXJyYXlbMF07XG4gICAgICB0aGlzLmNoZWNrSWZNb2RpZmllZCh0aGlzLnNhdmVkQ29uZmlnKTtcbiAgICB9XG4gICAgLy8gVHJlYXQgYWxsIHVuZXhwZWN0ZWQgcHJvcGVydGllcyBhcyBhcHBsaWFuY2UgY29uZmlndXJhdGlvbnNcbiAgICBjb25zdCBrZXlvZkNvbmZpZ1BsdWdpbiA9ICgwLCBfdXRpbHMua2V5b2ZDaGVja2VyKShfY29uZmlnVHlwZXMudHlwZVN1aXRlLCBfY29uZmlnVHlwZXMudHlwZVN1aXRlLkNvbmZpZ1BsdWdpbik7XG4gICAgY29uc3Qgc2VsZWN0ID0gcHJlZGljYXRlID0+IE9iamVjdC5mcm9tRW50cmllcyhPYmplY3QuZW50cmllcyh0aGlzLnNhdmVkQ29uZmlnID8/IHt9KS5maWx0ZXIocHJlZGljYXRlKSk7XG4gICAgdGhpcy5nbG9iYWwgPSBzZWxlY3QoKFtrZXldKSA9PiBrZXlvZkNvbmZpZ1BsdWdpbi5pbmNsdWRlcyhrZXkpKTtcbiAgICB0aGlzLmFwcGxpYW5jZXMgPSBzZWxlY3QoKFtrZXldKSA9PiAha2V5b2ZDb25maWdQbHVnaW4uaW5jbHVkZXMoa2V5KSk7XG4gICAgdGhpcy5sb2cuZGVidWcoJ2dldENvbmZpZygpIGdsb2JhbCAlTyBhcHBsaWFuY2VzICVPJywgdGhpcy5nbG9iYWwsIHRoaXMuYXBwbGlhbmNlcyk7XG4gICAgdGhpcy5vbkdsb2JhbD8uKHRoaXMuZ2xvYmFsKTtcbiAgfVxuICAvLyBSZXRyaWV2ZSB0aGUgbW9zdCByZWNlbnRseSB1c2VkIGNvbmZpZ3VyYXRpb25cbiAgYXN5bmMgZ2V0QWN0aXZlQ29uZmlnKCkge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5pcGMucmVxdWVzdCgnL2NvbmZpZycsIG51bGwpO1xuICAgIH0gY2F0Y2gge1xuICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgfVxuICAvLyBVcGRhdGUgdGhlIGhvbWVicmlkZ2UtdWkteCBjb3B5IG9mIHRoZSBjb25maWd1cmF0aW9uXG4gIGFzeW5jIHB1dENvbmZpZyhzYXZlID0gZmFsc2UpIHtcbiAgICAvLyBDb25zdHJ1Y3QgdGhlIGZ1bGwgY29uZmlndXJhdGlvblxuICAgIGNvbnN0IGNvbmZpZyA9IHtcbiAgICAgIC4uLnRoaXMuZ2xvYmFsLFxuICAgICAgLi4udGhpcy5hcHBsaWFuY2VzXG4gICAgfTtcbiAgICB0aGlzLmxvZy5kZWJ1ZyhgcHV0Q29uZmlnKCR7c2F2ZX0pJ31gLCBjb25maWcpO1xuICAgIC8vIEluZm9ybSBob21lYnJpZGdlLXVpLXggb2YgdGhlIG5ldyBjb25maWd1cmF0aW9uXG4gICAgYXdhaXQgd2luZG93LmhvbWVicmlkZ2UudXBkYXRlUGx1Z2luQ29uZmlnKFtjb25maWddKTtcbiAgICBpZiAoc2F2ZSkge1xuICAgICAgYXdhaXQgd2luZG93LmhvbWVicmlkZ2Uuc2F2ZVBsdWdpbkNvbmZpZygpO1xuICAgICAgdGhpcy5zYXZlZENvbmZpZyA9IGNvbmZpZztcbiAgICAgIHRoaXMubG9nLmluZm8oJ1BsdWdpbiBjb25maWd1cmF0aW9uIHNhdmVkJyk7XG4gICAgfVxuICAgIC8vIENoZWNrIHdoZXRoZXIgdGhlIGNvbmZpZ3VyYXRpb24gbWF0Y2hlcyB0aGUgYWN0aXZlIHBsdWdpblxuICAgIHRoaXMuY2hlY2tJZk1vZGlmaWVkKGNvbmZpZyk7XG4gIH1cbiAgLy8gQ29tcGFyZSB0d28gY29uZmlndXJhdGlvbiBvYmplY3RzXG4gIGRpZmZPYmplY3QodG8sIGZyb20sIGtleVByZWZpeCA9ICcnKSB7XG4gICAgY29uc3Qga2V5cyA9IFsuLi5PYmplY3Qua2V5cyh0byksIC4uLk9iamVjdC5rZXlzKGZyb20pXS5maWx0ZXIoKGtleSwgaW5kZXgsIHNlbGYpID0+IGluZGV4ID09PSBzZWxmLmluZGV4T2Yoa2V5KSk7XG4gICAgY29uc3QgZGlmZiA9IFtdO1xuICAgIGZvciAoY29uc3Qga2V5IG9mIGtleXMpIHtcbiAgICAgIGNvbnN0IHZhbHVlVG8gPSB0b1trZXldO1xuICAgICAgY29uc3QgdmFsdWVGcm9tID0gZnJvbVtrZXldO1xuICAgICAgY29uc3Qga2V5TmFtZSA9IGAke2tleVByZWZpeH0uJHtrZXl9YDtcbiAgICAgIGNvbnN0IGlzT2JqZWN0ID0gdmFsdWUgPT4gdmFsdWUgIT09IHVuZGVmaW5lZCAmJiB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnO1xuICAgICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWVUbykgJiYgQXJyYXkuaXNBcnJheSh2YWx1ZUZyb20pKSBkaWZmLnB1c2goLi4udGhpcy5kaWZmQXJyYXkodmFsdWVUbywgdmFsdWVGcm9tLCBrZXlOYW1lKSk7ZWxzZSBpZiAoaXNPYmplY3QodmFsdWVUbykgJiYgaXNPYmplY3QodmFsdWVGcm9tKSkgZGlmZi5wdXNoKC4uLnRoaXMuZGlmZk9iamVjdCh2YWx1ZVRvLCB2YWx1ZUZyb20sIGtleU5hbWUpKTtlbHNlIGlmICh2YWx1ZVRvICE9PSB2YWx1ZUZyb20pIGRpZmYucHVzaCh7XG4gICAgICAgIGtleToga2V5TmFtZSxcbiAgICAgICAgZnJvbTogdmFsdWVGcm9tLFxuICAgICAgICB0bzogdmFsdWVUb1xuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBkaWZmO1xuICB9XG4gIC8vIENvbXBhcmUgdHdvIGNvbmZpZ3VyYXRpb24gYXJyYXlzXG4gIGRpZmZBcnJheSh0bywgZnJvbSwga2V5UHJlZml4ID0gJycpIHtcbiAgICBjb25zdCBpc1NpbXBsZSA9IGFycmF5ID0+IGFycmF5Lmxlbmd0aCAhPT0gMCAmJiB0eXBlb2YgYXJyYXlbMF0gIT09ICdvYmplY3QnO1xuICAgIGlmIChpc1NpbXBsZSh0bykgfHwgaXNTaW1wbGUoZnJvbSkpIHtcbiAgICAgIGlmICh0by5sZW5ndGggPT09IGZyb20ubGVuZ3RoICYmIHRvLmV2ZXJ5KCh2YWx1ZSwgaW5kZXgpID0+IHZhbHVlID09PSBmcm9tW2luZGV4XSkpIHJldHVybiBbXTtlbHNlIHJldHVybiBbe1xuICAgICAgICBrZXk6IGtleVByZWZpeCxcbiAgICAgICAgZnJvbSxcbiAgICAgICAgdG9cbiAgICAgIH1dO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5kaWZmT2JqZWN0KHRvLCBmcm9tLCBrZXlQcmVmaXgpO1xuICAgIH1cbiAgfVxuICAvLyBDaGVjayB3aGV0aGVyIHRoZSBjb25maWd1cmF0aW9uIGhhcyBiZWVuIG1vZGlmaWVkXG4gIGFzeW5jIGNoZWNrSWZNb2RpZmllZChjb25maWcpIHtcbiAgICAvLyBJZ25vcmUgY29tcGxldGVseSBuZXcvZW1wdHkgY29uZmlndXJhdGlvblxuICAgIGlmICghT2JqZWN0LmtleXMoY29uZmlnKS5sZW5ndGgpIHJldHVybjtcbiAgICAvLyBDb21wYXJlIHRoZSBjb25maWd1cmF0aW9uIHRvIHRoZSBhY3RpdmUgcGx1Z2luIGFuZCBzYXZlZCB2ZXJzaW9uc1xuICAgIGNvbnN0IGFjdGl2ZUNvbmZpZyA9IGF3YWl0IHRoaXMuYWN0aXZlUHJvbWlzZTtcbiAgICBjb25zdCBhY3RpdmVEaWZmID0gdGhpcy5kaWZmT2JqZWN0KGNvbmZpZywgYWN0aXZlQ29uZmlnKTtcbiAgICBjb25zdCBzYXZlZERpZmYgPSB0aGlzLmRpZmZPYmplY3QoY29uZmlnLCB0aGlzLnNhdmVkQ29uZmlnID8/IHt9KTtcbiAgICBpZiAoYWN0aXZlRGlmZi5sZW5ndGggfHwgc2F2ZWREaWZmLmxlbmd0aCkge1xuICAgICAgdGhpcy5sb2cuZGVidWcoJ2NoZWNrSWZNb2RpZmllZCglTykgYWN0aXZlICVPIHNhdmVkICVPJywgY29uZmlnLCBhY3RpdmVEaWZmLCBzYXZlZERpZmYpO1xuICAgIH1cbiAgICAvLyBIaWRlIG9yIHNob3cgdGhlIHJlc3RhcnQgcmVxdWlyZWQgbWVzc2FnZVxuICAgIHRoaXMuc2hvd1Jlc3RhcnRSZXF1aXJlZChhY3RpdmVEaWZmLCAwIDwgc2F2ZWREaWZmLmxlbmd0aCk7XG4gIH1cbiAgLy8gU2hvdyBvciBoaWRlIHRoZSByZXN0YXJ0IHJlcXVpcmVkIG1lc3NhZ2VcbiAgc2hvd1Jlc3RhcnRSZXF1aXJlZChjaGFuZ2VzLCBpc1Vuc2F2ZWQpIHtcbiAgICAvLyBTaG93IHRoZSBtZXNzYWdlIGlmIHRoZXJlIGFyZSBhbnkgZGlmZmVyZW5jZXNcbiAgICAoMCwgX3V0aWxzRG9tLmdldEVsZW1lbnRCeUlkKSgnaGMtbW9kaWZpZWQnKS5oaWRkZW4gPSBjaGFuZ2VzLmxlbmd0aCA9PT0gMCAmJiAhaXNVbnNhdmVkO1xuICAgICgwLCBfdXRpbHNEb20uZ2V0RWxlbWVudEJ5SWQpKCdoYy1tb2RpZmllZC1zYXZlZCcpLmhpZGRlbiA9IGlzVW5zYXZlZDtcbiAgICAoMCwgX3V0aWxzRG9tLmdldEVsZW1lbnRCeUlkKSgnaGMtbW9kaWZpZWQtdW5zYXZlZCcpLmhpZGRlbiA9ICFpc1Vuc2F2ZWQ7XG4gICAgLy8gRGlzcGxheSB0aGUgZGlmZlxuICAgIGNvbnN0IGZvcm1hdFZhbHVlID0gdmFsdWUgPT4gSlNPTi5zdHJpbmdpZnkodmFsdWUsIG51bGwsIDQpO1xuICAgICgwLCBfdXRpbHNEb20uZ2V0RWxlbWVudEJ5SWQpKCdoYy1tb2RpZmllZC1kaWZmJykucmVwbGFjZUNoaWxkcmVuKC4uLmNoYW5nZXMubWFwKGNoYW5nZSA9PiAoMCwgX3V0aWxzRG9tLmNsb25lVGVtcGxhdGUpKCdoYy1tb2RpZmllZC1kaWZmLWRlbHRhJywge1xuICAgICAga2V5OiBjaGFuZ2Uua2V5LFxuICAgICAgZnJvbTogZm9ybWF0VmFsdWUoY2hhbmdlLmZyb20pLFxuICAgICAgdG86IGZvcm1hdFZhbHVlKGNoYW5nZS50bylcbiAgICB9KSkpO1xuICB9XG4gIC8vIEdldCB0aGUgY3VycmVudCBnbG9iYWwgY29uZmlndXJhdGlvblxuICBhc3luYyBnZXRHbG9iYWwoKSB7XG4gICAgYXdhaXQgdGhpcy5yZWFkeVByb21pc2U7XG4gICAgcmV0dXJuIHRoaXMuZ2xvYmFsO1xuICB9XG4gIC8vIFNldCB1cGRhdGVkIGdsb2JhbCBjb25maWd1cmF0aW9uXG4gIGFzeW5jIHNldEdsb2JhbChjb25maWcpIHtcbiAgICBpZiAodGhpcy5kaWZmT2JqZWN0KGNvbmZpZywgYXdhaXQgdGhpcy5nZXRHbG9iYWwoKSkubGVuZ3RoKSB7XG4gICAgICB0aGlzLmxvZy5kZWJ1Zygnc2V0R2xvYmFsKCVPKScsIGNvbmZpZyk7XG4gICAgICB0aGlzLmdsb2JhbCA9IGNvbmZpZztcbiAgICAgIHRoaXMub25HbG9iYWw/Lihjb25maWcpO1xuICAgICAgYXdhaXQgdGhpcy5wdXRDb25maWcoKTtcbiAgICB9XG4gIH1cbiAgLy8gR2V0IHRoZSBjdXJyZW50IGNvbmZpZ3VyYXRpb24gZm9yIGEgc3BlY2lmaWMgYXBwbGlhbmNlXG4gIGFzeW5jIGdldEFwcGxpYW5jZShoYWlkKSB7XG4gICAgYXdhaXQgdGhpcy5yZWFkeVByb21pc2U7XG4gICAgcmV0dXJuIHRoaXMuYXBwbGlhbmNlc1toYWlkXSA/PyB7fTtcbiAgfVxuICAvLyBTZXQgdXBkYXRlZCBnbG9iYWwgY29uZmlndXJhdGlvblxuICBhc3luYyBzZXRBcHBsaWFuY2UoaGFpZCwgY29uZmlnKSB7XG4gICAgaWYgKHRoaXMuZGlmZk9iamVjdChjb25maWcsIGF3YWl0IHRoaXMuZ2V0QXBwbGlhbmNlKGhhaWQpKS5sZW5ndGgpIHtcbiAgICAgIHRoaXMubG9nLmRlYnVnKGBzZXRBcHBsaWFuY2UoXCIke2hhaWR9XCIsICVPKWAsIGNvbmZpZyk7XG4gICAgICB0aGlzLmFwcGxpYW5jZXNbaGFpZF0gPSBjb25maWc7XG4gICAgICBhd2FpdCB0aGlzLnB1dENvbmZpZygpO1xuICAgIH1cbiAgfVxufVxuZXhwb3J0cy5Db25maWcgPSBDb25maWc7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldD11dGYtODtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnVZVzFsY3lJNld5SnlaWEYxYVhKbElpd2lYM1YwYVd4eklpd2lYM1YwYVd4elJHOXRJaXdpWDJOdmJtWnBaMVI1Y0dWeklpd2lRMjl1Wm1sbklpd2liRzluSWl3aWFYQmpJaXdpYzJGMlpXUkRiMjVtYVdjaUxDSm5iRzlpWVd3aUxDSmhjSEJzYVdGdVkyVnpJaXdpYjI1SGJHOWlZV3dpTENKeVpXRmtlVkJ5YjIxcGMyVWlMQ0poWTNScGRtVlFjbTl0YVhObElpd2lZMjl1YzNSeWRXTjBiM0lpTENKblpYUkRiMjVtYVdjaUxDSm5aWFJCWTNScGRtVkRiMjVtYVdjaUxDSmpiMjVtYVdkQmNuSmhlU0lzSW5kcGJtUnZkeUlzSW1odmJXVmljbWxrWjJVaUxDSm5aWFJRYkhWbmFXNURiMjVtYVdjaUxDSjFibVJsWm1sdVpXUWlMQ0ozWVhKdUlpd2ljR3hoZEdadmNtMGlMQ0p3YkhWbmFXNGlMQ0prYVhOd2JHRjVUbUZ0WlNJc0lteGxibWQwYUNJc0ltVnljbTl5SWl3aWRHOWhjM1FpTENKamFHVmphMGxtVFc5a2FXWnBaV1FpTENKclpYbHZaa052Ym1acFoxQnNkV2RwYmlJc0ltdGxlVzltUTJobFkydGxjaUlzSW5SNWNHVlRkV2wwWlNJc0lrTnZibVpwWjFCc2RXZHBiaUlzSW5ObGJHVmpkQ0lzSW5CeVpXUnBZMkYwWlNJc0lrOWlhbVZqZENJc0ltWnliMjFGYm5SeWFXVnpJaXdpWlc1MGNtbGxjeUlzSW1acGJIUmxjaUlzSW10bGVTSXNJbWx1WTJ4MVpHVnpJaXdpWkdWaWRXY2lMQ0p5WlhGMVpYTjBJaXdpY0hWMFEyOXVabWxuSWl3aWMyRjJaU0lzSW1OdmJtWnBaeUlzSW5Wd1pHRjBaVkJzZFdkcGJrTnZibVpwWnlJc0luTmhkbVZRYkhWbmFXNURiMjVtYVdjaUxDSnBibVp2SWl3aVpHbG1aazlpYW1WamRDSXNJblJ2SWl3aVpuSnZiU0lzSW10bGVWQnlaV1pwZUNJc0ltdGxlWE1pTENKcGJtUmxlQ0lzSW5ObGJHWWlMQ0pwYm1SbGVFOW1JaXdpWkdsbVppSXNJblpoYkhWbFZHOGlMQ0oyWVd4MVpVWnliMjBpTENKclpYbE9ZVzFsSWl3aWFYTlBZbXBsWTNRaUxDSjJZV3gxWlNJc0lrRnljbUY1SWl3aWFYTkJjbkpoZVNJc0luQjFjMmdpTENKa2FXWm1RWEp5WVhraUxDSnBjMU5wYlhCc1pTSXNJbUZ5Y21GNUlpd2laWFpsY25raUxDSmhZM1JwZG1WRGIyNW1hV2NpTENKaFkzUnBkbVZFYVdabUlpd2ljMkYyWldSRWFXWm1JaXdpYzJodmQxSmxjM1JoY25SU1pYRjFhWEpsWkNJc0ltTm9ZVzVuWlhNaUxDSnBjMVZ1YzJGMlpXUWlMQ0puWlhSRmJHVnRaVzUwUW5sSlpDSXNJbWhwWkdSbGJpSXNJbVp2Y20xaGRGWmhiSFZsSWl3aVNsTlBUaUlzSW5OMGNtbHVaMmxtZVNJc0luSmxjR3hoWTJWRGFHbHNaSEpsYmlJc0ltMWhjQ0lzSW1Ob1lXNW5aU0lzSW1Oc2IyNWxWR1Z0Y0d4aGRHVWlMQ0puWlhSSGJHOWlZV3dpTENKelpYUkhiRzlpWVd3aUxDSm5aWFJCY0hCc2FXRnVZMlVpTENKb1lXbGtJaXdpYzJWMFFYQndiR2xoYm1ObElpd2laWGh3YjNKMGN5SmRMQ0p6YjNWeVkyVnpJanBiSWk0dUx5NHVMeTR1TDNOeVl5OW9iMjFsWW5KcFpHZGxMWFZwTDNCMVlteHBZeTlqYjI1bWFXY3VkSE1pWFN3aWMyOTFjbU5sYzBOdmJuUmxiblFpT2x0dWRXeHNYU3dpYldGd2NHbHVaM01pT2lJN096czdPenRCUVVkQlFTeFBRVUZCTzBGQlMwRXNTVUZCUVVNc1RVRkJRU3hIUVVGQlJDeFBRVUZCTzBGQlJVRXNTVUZCUVVVc1UwRkJRU3hIUVVGQlJpeFBRVUZCTzBGQlEwRXNTVUZCUVVjc1dVRkJRU3hIUVVGQlNDeFBRVUZCTzBGQldFRTdRVUZEUVRzN1FVRnRRa0U3UVVGRFRTeE5RVUZQU1N4TlFVRk5PMFZCWlUxRExFZEJRVUU3UlVGRFFVTXNSMEZCUVR0RlFXUnlRanRGUVVOQlF5eFhRVUZYTzBWQlJWZzdSVUZEUVVNc1RVRkJUU3hIUVVGclF5eEZRVUZGTzBWQlF6RkRReXhWUVVGVkxFZEJRWGxDTEVWQlFVVTdSVUZEY2tORExGRkJRVkU3UlVGRlVqdEZRVU5CUXl4WlFVRlpPMFZCUTFwRExHRkJRV0U3UlVGRllqdEZRVU5CUXl4WlFVRnhRbElzUjBGQlZ5eEZRVU5ZUXl4SFFVRmpPMGxCUkdRc1MwRkJRVVFzUjBGQlJ5eEhRVUZJUVN4SFFVRkhPMGxCUTBnc1MwRkJRVU1zUjBGQlJ5eEhRVUZJUVN4SFFVRkhPMGxCUTNCQ0xFbEJRVWtzUTBGQlEwc3NXVUZCV1N4SFFVRkpMRWxCUVVrc1EwRkJRMGNzVTBGQlV5eEZRVUZGTzBsQlEzSkRMRWxCUVVrc1EwRkJRMFlzWVVGQllTeEhRVUZITEVsQlFVa3NRMEZCUTBjc1pVRkJaU3hGUVVGRk8wVkJReTlETzBWQlJVRTdSVUZEUVN4TlFVRk5SQ3hUUVVGVFFTeERRVUZCTzBsQlExZzdTVUZEUVN4TlFVRk5SU3hYUVVGWExFZEJRVWNzVFVGQlRVTXNUVUZCVFN4RFFVRkRReXhWUVVGVkxFTkJRVU5ETEdWQlFXVXNSVUZCUlR0SlFVTTNSQ3hKUVVGSlNDeFhRVUZYTEVOQlFVTXNRMEZCUXl4RFFVRkRMRXRCUVV0SkxGTkJRVk1zUlVGQlJUdE5RVU01UWl4SlFVRkpMRU5CUVVObUxFZEJRVWNzUTBGQlEyZENMRWxCUVVrc1EwRkJReXh0UkVGQmJVUXNRMEZCUXp0TlFVTnNSU3hKUVVGSkxFTkJRVU5rTEZkQlFWY3NSMEZCUnp0UlFVRkZaU3hSUVVGUkxFVkJRVVZNTEUxQlFVMHNRMEZCUTBNc1ZVRkJWU3hEUVVGRFN5eE5RVUZOTEVOQlFVTkRPMDFCUVZjc1EwRkJSVHRKUVVONlJTeERRVUZETEUxQlFVMDdUVUZEU0N4SlFVRkpMRU5CUVVNc1IwRkJSMUlzVjBGQlZ5eERRVUZEVXl4TlFVRk5MRVZCUVVVN1VVRkRlRUlzU1VGQlNTeERRVUZEY0VJc1IwRkJSeXhEUVVGRGNVSXNTMEZCU3l4RFFVRkRMSE5DUVVGelFsWXNWMEZCVnl4RFFVRkRVeXhOUVVGTkxIZENRVUYzUWl4RlFVRkZWQ3hYUVVGWExFTkJRVU03VVVGRE4wWkRMRTFCUVUwc1EwRkJRME1zVlVGQlZTeERRVUZEVXl4TFFVRkxMRU5CUVVORUxFdEJRVXNzUTBGQlF5d3JSRUZCSzBRc1JVRkRMMFFzSzBKQlFTdENMRU5CUVVNN1RVRkRiRVU3VFVGRFFTeEpRVUZKTEVOQlFVTnVRaXhYUVVGWExFZEJRVWRUTEZkQlFWY3NRMEZCUXl4RFFVRkRMRU5CUVVNN1RVRkRha01zU1VGQlNTeERRVUZEV1N4bFFVRmxMRU5CUVVNc1NVRkJTU3hEUVVGRGNrSXNWMEZCVnl4RFFVRkRPMGxCUXpGRE8wbEJSVUU3U1VGRFFTeE5RVUZOYzBJc2FVSkJRV2xDTEVkQlFVY3NTVUZCUVVNc2JVSkJRVmtzUlVGQlEwTXNjMEpCUVZNc1JVRkJSVUVzYzBKQlFWTXNRMEZCUTBNc1dVRkJXU3hEUVVGRE8wbEJRM3BGTEUxQlFVMURMRTFCUVUwc1IwRkJTVU1zVTBGQmRVUXNTVUZEYmtWRExFMUJRVTBzUTBGQlEwTXNWMEZCVnl4RFFVRkRSQ3hOUVVGTkxFTkJRVU5GTEU5QlFVOHNRMEZCUXl4SlFVRkpMRU5CUVVNNVFpeFhRVUZYTEVsQlFVa3NSVUZCUlN4RFFVRkRMRU5CUVVNclFpeE5RVUZOTEVOQlFVTktMRk5CUVZNc1EwRkJReXhEUVVGRE8wbEJRMmhHTEVsQlFVa3NRMEZCUXpGQ0xFMUJRVTBzUjBGQlQzbENMRTFCUVUwc1EwRkJReXhEUVVGRExFTkJRVU5OTEVkQlFVY3NRMEZCUXl4TFFVRk5WaXhwUWtGQmFVSXNRMEZCUTFjc1VVRkJVU3hEUVVGRFJDeEhRVUZITEVOQlFVTXNRMEZCTUVJN1NVRkRPVVlzU1VGQlNTeERRVUZET1VJc1ZVRkJWU3hIUVVGSGQwSXNUVUZCVFN4RFFVRkRMRU5CUVVNc1EwRkJRMDBzUjBGQlJ5eERRVUZETEV0QlFVc3NRMEZCUTFZc2FVSkJRV2xDTEVOQlFVTlhMRkZCUVZFc1EwRkJRMFFzUjBGQlJ5eERRVUZETEVOQlFYRkNPMGxCUTNwR0xFbEJRVWtzUTBGQlEyeERMRWRCUVVjc1EwRkJRMjlETEV0QlFVc3NRMEZCUXl4eFEwRkJjVU1zUlVGQlJTeEpRVUZKTEVOQlFVTnFReXhOUVVGTkxFVkJRVVVzU1VGQlNTeERRVUZEUXl4VlFVRlZMRU5CUVVNN1NVRkRia1lzU1VGQlNTeERRVUZEUXl4UlFVRlJMRWRCUVVjc1NVRkJTU3hEUVVGRFJpeE5RVUZOTEVOQlFVTTdSVUZEYUVNN1JVRkZRVHRGUVVOQkxFMUJRVTFQTEdWQlFXVkJMRU5CUVVFN1NVRkRha0lzU1VGQlNUdE5RVU5CTEU5QlFVOHNUVUZCVFN4SlFVRkpMRU5CUVVOVUxFZEJRVWNzUTBGQlEyOURMRTlCUVU4c1EwRkJReXhUUVVGVExFVkJRVVVzU1VGQlNTeERRVUZETzBsQlEyeEVMRU5CUVVNc1EwRkJReXhOUVVGTk8wMUJRMG9zVDBGQlR5eEZRVUZ2UWp0SlFVTXZRanRGUVVOS08wVkJSVUU3UlVGRFFTeE5RVUZOUXl4VFFVRlRRU3hEUVVGRFF5eEpRVUZKTEVkQlFVY3NTMEZCU3p0SlFVTjRRanRKUVVOQkxFMUJRVTFETEUxQlFVMHNSMEZCUnp0TlFVRkZMRWRCUVVjc1NVRkJTU3hEUVVGRGNrTXNUVUZCVFR0TlFVRkZMRWRCUVVjc1NVRkJTU3hEUVVGRFF6dEpRVUZWTEVOQlFVVTdTVUZEY2tRc1NVRkJTU3hEUVVGRFNpeEhRVUZITEVOQlFVTnZReXhMUVVGTExFTkJRVU1zWVVGQllVY3NTVUZCU1N4TFFVRkxMRVZCUVVWRExFMUJRVTBzUTBGQlF6dEpRVVU1UXp0SlFVTkJMRTFCUVUwMVFpeE5RVUZOTEVOQlFVTkRMRlZCUVZVc1EwRkJRelJDTEd0Q1FVRnJRaXhEUVVGRExFTkJRVU5FTEUxQlFVMHNRMEZCUXl4RFFVRkRPMGxCUTNCRUxFbEJRVWxFTEVsQlFVa3NSVUZCUlR0TlFVTk9MRTFCUVUwelFpeE5RVUZOTEVOQlFVTkRMRlZCUVZVc1EwRkJRelpDTEdkQ1FVRm5RaXhGUVVGRk8wMUJRekZETEVsQlFVa3NRMEZCUTNoRExGZEJRVmNzUjBGQlIzTkRMRTFCUVUwN1RVRkRla0lzU1VGQlNTeERRVUZEZUVNc1IwRkJSeXhEUVVGRE1rTXNTVUZCU1N4RFFVRkRMRFJDUVVFMFFpeERRVUZETzBsQlF5OURPMGxCUlVFN1NVRkRRU3hKUVVGSkxFTkJRVU53UWl4bFFVRmxMRU5CUVVOcFFpeE5RVUZOTEVOQlFVTTdSVUZEYUVNN1JVRkZRVHRGUVVOQlNTeFZRVUZWUVN4RFFVRkRReXhGUVVGVkxFVkJRVVZETEVsQlFWa3NSVUZCUlVNc1UwRkJVeXhIUVVGSExFVkJRVVU3U1VGREwwTXNUVUZCVFVNc1NVRkJTU3hIUVVGSExFTkJRVU1zUjBGQlIyeENMRTFCUVUwc1EwRkJRMnRDTEVsQlFVa3NRMEZCUTBnc1JVRkJSU3hEUVVGRExFVkJRVVVzUjBGQlIyWXNUVUZCVFN4RFFVRkRhMElzU1VGQlNTeERRVUZEUml4SlFVRkpMRU5CUVVNc1EwRkJReXhEUVVOc1JHSXNUVUZCVFN4RFFVRkRMRU5CUVVORExFZEJRVWNzUlVGQlJXVXNTMEZCU3l4RlFVRkZReXhKUVVGSkxFdEJRVXRFTEV0QlFVc3NTMEZCUzBNc1NVRkJTU3hEUVVGRFF5eFBRVUZQTEVOQlFVTnFRaXhIUVVGSExFTkJRVU1zUTBGQlF6dEpRVU01UkN4TlFVRk5hMElzU1VGQlNTeEhRVUZyUWl4RlFVRkZPMGxCUXpsQ0xFdEJRVXNzVFVGQlRXeENMRWRCUVVjc1NVRkJTV01zU1VGQlNTeEZRVUZGTzAxQlEzQkNMRTFCUVUxTExFOUJRVThzUjBGQlMxSXNSVUZCUlN4RFFVRkhXQ3hIUVVGWkxFTkJRVU03VFVGRGNFTXNUVUZCVFc5Q0xGTkJRVk1zUjBGQlIxSXNTVUZCU1N4RFFVRkRXaXhIUVVGWkxFTkJRVU03VFVGRGNFTXNUVUZCVFhGQ0xFOUJRVThzUjBGQlJ5eEhRVUZIVWl4VFFVRlRMRWxCUVVsaUxFZEJRVWNzUlVGQlJUdE5RVU55UXl4TlFVRk5jMElzVVVGQlVTeEhRVUZKUXl4TFFVRmpMRWxCUVdOQkxFdEJRVXNzUzBGQlN6RkRMRk5CUVZNc1NVRkJTU3hQUVVGUE1FTXNTMEZCU3l4TFFVRkxMRkZCUVZFN1RVRkRPVVlzU1VGQlNVTXNTMEZCU3l4RFFVRkRReXhQUVVGUExFTkJRVU5PTEU5QlFVOHNRMEZCUXl4SlFVRkpTeXhMUVVGTExFTkJRVU5ETEU5QlFVOHNRMEZCUTB3c1UwRkJVeXhEUVVGRExFVkJRVVZHTEVsQlFVa3NRMEZCUTFFc1NVRkJTU3hEUVVGRExFZEJRVWNzU1VGQlNTeERRVUZEUXl4VFFVRlRMRU5CUVVWU0xFOUJRVThzUlVGQlJVTXNVMEZCVXl4RlFVRkZReXhQUVVGUExFTkJRVU1zUTBGQlF5eERRVUZETEV0QlF6bEhMRWxCUVVsRExGRkJRVkVzUTBGQlEwZ3NUMEZCVHl4RFFVRkRMRWxCUVVsSExGRkJRVkVzUTBGQlEwWXNVMEZCVXl4RFFVRkRMRVZCUVU5R0xFbEJRVWtzUTBGQlExRXNTVUZCU1N4RFFVRkRMRWRCUVVjc1NVRkJTU3hEUVVGRGFFSXNWVUZCVlN4RFFVRkRVeXhQUVVGUExFVkJRVVZETEZOQlFWTXNSVUZCUlVNc1QwRkJUeXhEUVVGRExFTkJRVU1zUTBGQlF5eExRVU01Unl4SlFVRkpSaXhQUVVGUExFdEJRVXRETEZOQlFWTXNSVUZCUlVZc1NVRkJTU3hEUVVGRFVTeEpRVUZKTEVOQlFVTTdVVUZCUlRGQ0xFZEJRVWNzUlVGQlJYRkNMRTlCUVU4N1VVRkJSVlFzU1VGQlNTeEZRVUZGVVN4VFFVRlRPMUZCUVVWVUxFVkJRVVVzUlVGQlJWRTdUVUZCVHl4RFFVRkZMRU5CUVVNN1NVRkROMFk3U1VGRFFTeFBRVUZQUkN4SlFVRkpPMFZCUTJZN1JVRkZRVHRGUVVOQlV5eFRRVUZUUVN4RFFVRkRhRUlzUlVGQllTeEZRVUZGUXl4SlFVRmxMRVZCUVVWRExGTkJRVk1zUjBGQlJ5eEZRVUZGTzBsQlEzQkVMRTFCUVUxbExGRkJRVkVzUjBGQlNVTXNTMEZCWjBJc1NVRkJZMEVzUzBGQlN5eERRVUZETTBNc1RVRkJUU3hMUVVGTExFTkJRVU1zU1VGQlNTeFBRVUZQTWtNc1MwRkJTeXhEUVVGRExFTkJRVU1zUTBGQlF5eExRVUZMTEZGQlFWRTdTVUZEYkVjc1NVRkJTVVFzVVVGQlVTeERRVUZEYWtJc1JVRkJSU3hEUVVGRExFbEJRVWxwUWl4UlFVRlJMRU5CUVVOb1FpeEpRVUZKTEVOQlFVTXNSVUZCUlR0TlFVTm9ReXhKUVVGSlJDeEZRVUZGTEVOQlFVTjZRaXhOUVVGTkxFdEJRVXN3UWl4SlFVRkpMRU5CUVVNeFFpeE5RVUZOTEVsQlFVbDVRaXhGUVVGRkxFTkJRVU50UWl4TFFVRkxMRU5CUVVNc1EwRkJRMUFzUzBGQlN5eEZRVUZGVWl4TFFVRkxMRXRCUVV0UkxFdEJRVXNzUzBGQlMxZ3NTVUZCU1N4RFFVRkRSeXhMUVVGTExFTkJRVU1zUTBGQlF5eEZRVUZGTEU5QlFVOHNSVUZCUlN4RFFVRkRMRXRCUTNwR0xFOUJRVThzUTBGQlF6dFJRVUZGWml4SFFVRkhMRVZCUVVWaExGTkJRVk03VVVGQlJVUXNTVUZCU1R0UlFVRkZSRHROUVVGRkxFTkJRVVVzUTBGQlF6dEpRVU01UXl4RFFVRkRMRTFCUVUwN1RVRkRTQ3hQUVVGUExFbEJRVWtzUTBGQlEwUXNWVUZCVlN4RFFVRkRReXhGUVVGRkxFVkJRVVZETEVsQlFVa3NSVUZCUlVNc1UwRkJVeXhEUVVGRE8wbEJReTlETzBWQlEwbzdSVUZGUVR0RlFVTkJMRTFCUVUxNFFpeGxRVUZsUVN4RFFVRkRhVUlzVFVGQmIwSTdTVUZEZEVNN1NVRkRRU3hKUVVGSkxFTkJRVU5XTEUxQlFVMHNRMEZCUTJ0Q0xFbEJRVWtzUTBGQlExSXNUVUZCVFN4RFFVRkRMRU5CUVVOd1FpeE5RVUZOTEVWQlFVVTdTVUZGYWtNN1NVRkRRU3hOUVVGTk5rTXNXVUZCV1N4SFFVRkhMRTFCUVUwc1NVRkJTU3hEUVVGRE1VUXNZVUZCWVR0SlFVTTNReXhOUVVGTk1rUXNWVUZCVlN4SFFVRkhMRWxCUVVrc1EwRkJRM1JDTEZWQlFWVXNRMEZCUTBvc1RVRkJUU3hGUVVGRmVVSXNXVUZCV1N4RFFVRkRPMGxCUTNoRUxFMUJRVTFGTEZOQlFWTXNSMEZCUnl4SlFVRkpMRU5CUVVOMlFpeFZRVUZWTEVOQlFVTktMRTFCUVUwc1JVRkJSU3hKUVVGSkxFTkJRVU4wUXl4WFFVRlhMRWxCUVVrc1JVRkJSU3hEUVVGRE8wbEJRMnBGTEVsQlFVbG5SU3hWUVVGVkxFTkJRVU01UXl4TlFVRk5MRWxCUVVrclF5eFRRVUZUTEVOQlFVTXZReXhOUVVGTkxFVkJRVVU3VFVGRGRrTXNTVUZCU1N4RFFVRkRjRUlzUjBGQlJ5eERRVUZEYjBNc1MwRkJTeXhEUVVGRExIZERRVUYzUXl4RlFVRkZTU3hOUVVGTkxFVkJRVVV3UWl4VlFVRlZMRVZCUVVWRExGTkJRVk1zUTBGQlF6dEpRVU16Ump0SlFVVkJPMGxCUTBFc1NVRkJTU3hEUVVGRFF5eHRRa0ZCYlVJc1EwRkJRMFlzVlVGQlZTeEZRVUZGTEVOQlFVTXNSMEZCUjBNc1UwRkJVeXhEUVVGREwwTXNUVUZCVFN4RFFVRkRPMFZCUXpsRU8wVkJSVUU3UlVGRFFXZEVMRzFDUVVGdFFrRXNRMEZCUTBNc1QwRkJjVUlzUlVGQlJVTXNVMEZCYTBJN1NVRkRla1E3U1VGRFFTeEpRVUZCUXl4M1FrRkJZeXhGUVVGRExHRkJRV0VzUTBGQlF5eERRVUZEUXl4TlFVRk5MRWRCUVVkSUxFOUJRVThzUTBGQlEycEVMRTFCUVUwc1MwRkJTeXhEUVVGRExFbEJRVWtzUTBGQlEydEVMRk5CUVZNN1NVRkRla1VzU1VGQlFVTXNkMEpCUVdNc1JVRkJReXh0UWtGQmJVSXNRMEZCUXl4RFFVRkhReXhOUVVGTkxFZEJRVWRHTEZOQlFWTTdTVUZEZUVRc1NVRkJRVU1zZDBKQlFXTXNSVUZCUXl4eFFrRkJjVUlzUTBGQlF5eERRVUZEUXl4TlFVRk5MRWRCUVVjc1EwRkJRMFlzVTBGQlV6dEpRVVY2UkR0SlFVTkJMRTFCUVUxSExGZEJRVmNzUjBGQlNXaENMRXRCUVdNc1NVRkJZV2xDTEVsQlFVa3NRMEZCUTBNc1UwRkJVeXhEUVVGRGJFSXNTMEZCU3l4RlFVRkZMRWxCUVVrc1JVRkJSU3hEUVVGRExFTkJRVU03U1VGRE9VVXNTVUZCUVdNc2QwSkJRV01zUlVGQlF5eHJRa0ZCYTBJc1EwRkJReXhEUVVGRFN5eGxRVUZsTEVOQlFVTXNSMEZCUjFBc1QwRkJUeXhEUVVGRFVTeEhRVUZITEVOQlFVTkRMRTFCUVUwc1NVRkRjRVVzU1VGQlFVTXNkVUpCUVdFc1JVRkJReXgzUWtGQmQwSXNSVUZCUlR0TlFVTndRemRETEVkQlFVY3NSVUZCU3pSRExFMUJRVTBzUTBGQlF6VkRMRWRCUVVjN1RVRkRiRUpaTEVsQlFVa3NSVUZCU1RKQ0xGZEJRVmNzUTBGQlEwc3NUVUZCVFN4RFFVRkRhRU1zU1VGQlNTeERRVUZETzAxQlEyaERSQ3hGUVVGRkxFVkJRVTAwUWl4WFFVRlhMRU5CUVVOTExFMUJRVTBzUTBGQlEycERMRVZCUVVVN1MwRkRhRU1zUTBGQlF5eERRVUZETEVOQlFVTTdSVUZEV2p0RlFVVkJPMFZCUTBFc1RVRkJUVzFETEZOQlFWTkJMRU5CUVVFN1NVRkRXQ3hOUVVGTkxFbEJRVWtzUTBGQlF6RkZMRmxCUVZrN1NVRkRka0lzVDBGQlR5eEpRVUZKTEVOQlFVTklMRTFCUVUwN1JVRkRkRUk3UlVGRlFUdEZRVU5CTEUxQlFVMDRSU3hUUVVGVFFTeERRVUZEZWtNc1RVRkJiMEk3U1VGRGFFTXNTVUZCU1N4SlFVRkpMRU5CUVVOSkxGVkJRVlVzUTBGQlEwb3NUVUZCVFN4RlFVRkZMRTFCUVUwc1NVRkJTU3hEUVVGRGQwTXNVMEZCVXl4RlFVRkZMRU5CUVVNc1EwRkJRelZFTEUxQlFVMHNSVUZCUlR0TlFVTjRSQ3hKUVVGSkxFTkJRVU53UWl4SFFVRkhMRU5CUVVOdlF5eExRVUZMTEVOQlFVTXNaVUZCWlN4RlFVRkZTU3hOUVVGTkxFTkJRVU03VFVGRGRrTXNTVUZCU1N4RFFVRkRja01zVFVGQlRTeEhRVUZIY1VNc1RVRkJUVHROUVVOd1FpeEpRVUZKTEVOQlFVTnVReXhSUVVGUkxFZEJRVWR0UXl4TlFVRk5MRU5CUVVNN1RVRkRka0lzVFVGQlRTeEpRVUZKTEVOQlFVTkdMRk5CUVZNc1JVRkJSVHRKUVVNeFFqdEZRVU5LTzBWQlJVRTdSVUZEUVN4TlFVRk5ORU1zV1VGQldVRXNRMEZCUTBNc1NVRkJXVHRKUVVNelFpeE5RVUZOTEVsQlFVa3NRMEZCUXpkRkxGbEJRVms3U1VGRGRrSXNUMEZCVHl4SlFVRkpMRU5CUVVOR0xGVkJRVlVzUTBGQlF5dEZMRWxCUVVrc1EwRkJReXhKUVVGSkxFVkJRVVU3UlVGRGRFTTdSVUZGUVR0RlFVTkJMRTFCUVUxRExGbEJRVmxCTEVOQlFVTkVMRWxCUVZrc1JVRkJSVE5ETEUxQlFYVkNPMGxCUTNCRUxFbEJRVWtzU1VGQlNTeERRVUZEU1N4VlFVRlZMRU5CUVVOS0xFMUJRVTBzUlVGQlJTeE5RVUZOTEVsQlFVa3NRMEZCUXpCRExGbEJRVmtzUTBGQlEwTXNTVUZCU1N4RFFVRkRMRU5CUVVNc1EwRkJReTlFTEUxQlFVMHNSVUZCUlR0TlFVTXZSQ3hKUVVGSkxFTkJRVU53UWl4SFFVRkhMRU5CUVVOdlF5eExRVUZMTEVOQlFVTXNhVUpCUVdsQ0swTXNTVUZCU1N4UlFVRlJMRVZCUVVVelF5eE5RVUZOTEVOQlFVTTdUVUZEY2tRc1NVRkJTU3hEUVVGRGNFTXNWVUZCVlN4RFFVRkRLMFVzU1VGQlNTeERRVUZETEVkQlFVY3pReXhOUVVGTk8wMUJRemxDTEUxQlFVMHNTVUZCU1N4RFFVRkRSaXhUUVVGVExFVkJRVVU3U1VGRE1VSTdSVUZEU2pzN1FVRkRTQ3RETEU5QlFVRXNRMEZCUVhSR0xFMUJRVUVzUjBGQlFVRXNUVUZCUVNJc0ltbG5ibTl5WlV4cGMzUWlPbHRkZlE9PSIsIlwidXNlIHN0cmljdFwiO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5UZW1wbGF0ZUZvcm0gPSBleHBvcnRzLkdsb2JhbEZvcm0gPSBleHBvcnRzLkZvcm1zID0gZXhwb3J0cy5Gb3JtSWQgPSBleHBvcnRzLkZvcm0gPSBleHBvcnRzLkFwcGxpYW5jZUZvcm0gPSB2b2lkIDA7XG52YXIgX3V0aWxzRG9tID0gcmVxdWlyZShcIi4vdXRpbHMtZG9tLmpzXCIpO1xuLy8gSG9tZWJyaWRnZSBwbHVnaW4gZm9yIEhvbWUgQ29ubmVjdCBob21lIGFwcGxpYW5jZXNcbi8vIENvcHlyaWdodCDCqSAyMDIzIEFsZXhhbmRlciBUaG91a3lkaWRlc1xuXG4vLyBBIGNvbmZpZ3VyYXRpb24gZm9ybSBoYW5kbGVyXG5jbGFzcyBGb3JtIHtcbiAgbG9nO1xuICAvLyBUaGUgZm9ybVxuICBmb3JtO1xuICAvLyBDcmVhdGUgYSBjb25maWd1cmF0aW9uIGZvcm1cbiAgY29uc3RydWN0b3IobG9nKSB7XG4gICAgdGhpcy5sb2cgPSBsb2c7XG4gIH1cbiAgLy8gUmV0cmlldmUgYW5kIGRpc3BsYXkgdGhlIGZvcm1cbiAgYXN5bmMgY3JlYXRlRm9ybSgpIHtcbiAgICAvLyBSZXRyaWV2ZSB0aGUgZm9ybSBzY2hlbWEgYW5kIGRhdGFcbiAgICBjb25zdCBzY2hlbWEgPSBhd2FpdCB0aGlzLmdldFNjaGVtYSgpO1xuICAgIGNvbnN0IGRhdGEgPSBhd2FpdCB0aGlzLmdldERhdGEoKTtcbiAgICAvLyBDcmVhdGUgdGhlIGZvcm0gKGFkZGluZyBoZWFkZXIgYW5kIGZvb3RlcilcbiAgICBjb25zdCBwYXRjaGVkU2NoZW1hID0gdGhpcy5wYXRjaFNjaGVtYShzY2hlbWEpO1xuICAgIHRoaXMubG9nLmRlYnVnKCdjcmVhdGVGb3JtJywgcGF0Y2hlZFNjaGVtYSwgZGF0YSk7XG4gICAgdGhpcy5mb3JtID0gd2luZG93LmhvbWVicmlkZ2UuY3JlYXRlRm9ybShwYXRjaGVkU2NoZW1hLCBkYXRhKTtcbiAgICAvLyBSZXR1cm4gYW55IGNoYW5nZXMgdG8gdGhlIGNvbmZpZ3VyYXRpb25cbiAgICB0aGlzLmZvcm0ub25DaGFuZ2UoY29uZmlnID0+IHRoaXMucHV0RGF0YShjb25maWcpKTtcbiAgfVxuICAvLyBIaWRlIHRoZSBmb3JtIChpbXBsaWNpdGx5IGNhbGxlZCBpZiBhIGRpZmZlcmVudCBmb3JtIGlzIGNyZWF0ZWQpXG4gIGRlc3Ryb3lGb3JtKCkge1xuICAgIHRoaXMuZm9ybT8uZW5kKCk7XG4gICAgdGhpcy5mb3JtID0gdW5kZWZpbmVkO1xuICB9XG4gIC8vIEFkZCBhIGhlYWRlciBhbmQgZm9vdGVyIHRvIHRoZSBzY2hlbWEgZm9ybVxuICBwYXRjaFNjaGVtYShzY2hlbWEpIHtcbiAgICBjb25zdCBmb3JtID0gWy4uLihzY2hlbWEuZm9ybSA/PyBbXSksIC4uLnRoaXMuZm9ybUZyb21UZW1wbGF0ZSgnaGMtZm9ybS1mb290ZXInKV07XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLnNjaGVtYSxcbiAgICAgIGZvcm1cbiAgICB9O1xuICB9XG4gIC8vIENyZWF0ZSBhIGZvcm0gaXRlbSBmcm9tIGEgdGVtcGxhdGVcbiAgZm9ybUZyb21UZW1wbGF0ZSguLi5hcmdzKSB7XG4gICAgY29uc3QgdGVtcGxhdGUgPSAoMCwgX3V0aWxzRG9tLmNsb25lVGVtcGxhdGUpKC4uLmFyZ3MpO1xuICAgIGNvbnN0IGFic1RlbXBsYXRlID0gKDAsIF91dGlsc0RvbS5lbGVtZW50V2l0aEFic29sdXRlUGF0aHMpKHRlbXBsYXRlKTtcbiAgICByZXR1cm4gdGhpcy5mb3JtRnJvbUhUTUwoYWJzVGVtcGxhdGUpO1xuICB9XG4gIC8vIENyZWF0ZSBhIGZvcm0gaXRlbSBmcm9tIGFuIEhUTUwgZWxlbWVudFxuICBmb3JtRnJvbUhUTUwoZWxlbWVudCkge1xuICAgIHJldHVybiBbe1xuICAgICAgdHlwZTogJ2hlbHAnLFxuICAgICAgaGVscHZhbHVlOiAoMCwgX3V0aWxzRG9tLmdldEhUTUwpKGVsZW1lbnQpXG4gICAgfV07XG4gIH1cbn1cbi8vIEEgZ2xvYmFsIGNvbmZpZ3VyYXRpb24gZm9ybSBoYW5kbGVyXG5leHBvcnRzLkZvcm0gPSBGb3JtO1xuY2xhc3MgR2xvYmFsRm9ybSBleHRlbmRzIEZvcm0ge1xuICBpcGM7XG4gIGNvbmZpZztcbiAgY29uc3RydWN0b3IobG9nLCBpcGMsIGNvbmZpZykge1xuICAgIHN1cGVyKGxvZyk7XG4gICAgdGhpcy5pcGMgPSBpcGM7XG4gICAgdGhpcy5jb25maWcgPSBjb25maWc7XG4gIH1cbiAgZ2V0U2NoZW1hKCkge1xuICAgIHJldHVybiB0aGlzLmlwYy5yZXF1ZXN0KCcvc2NoZW1hL2dsb2JhbCcsIG51bGwpO1xuICB9XG4gIGdldERhdGEoKSB7XG4gICAgcmV0dXJuIHRoaXMuY29uZmlnLmdldEdsb2JhbCgpO1xuICB9XG4gIHB1dERhdGEoZGF0YSkge1xuICAgIHJldHVybiB0aGlzLmNvbmZpZy5zZXRHbG9iYWwoZGF0YSk7XG4gIH1cbn1cbi8vIEFuIGNvbmZpZ3VyYXRpb24gZm9ybSBoYW5kbGVyIGZvciBhIHNwZWNpZmljIGFwcGxpYW5jZVxuZXhwb3J0cy5HbG9iYWxGb3JtID0gR2xvYmFsRm9ybTtcbmNsYXNzIEFwcGxpYW5jZUZvcm0gZXh0ZW5kcyBGb3JtIHtcbiAgaXBjO1xuICBjb25maWc7XG4gIGhhaWQ7XG4gIGNvbnN0cnVjdG9yKGxvZywgaXBjLCBjb25maWcsIGhhaWQpIHtcbiAgICBzdXBlcihsb2cpO1xuICAgIHRoaXMuaXBjID0gaXBjO1xuICAgIHRoaXMuY29uZmlnID0gY29uZmlnO1xuICAgIHRoaXMuaGFpZCA9IGhhaWQ7XG4gIH1cbiAgZ2V0U2NoZW1hKCkge1xuICAgIHJldHVybiB0aGlzLmlwYy5yZXF1ZXN0KCcvc2NoZW1hL2FwcGxpYW5jZScsIHRoaXMuaGFpZCk7XG4gIH1cbiAgZ2V0RGF0YSgpIHtcbiAgICByZXR1cm4gdGhpcy5jb25maWcuZ2V0QXBwbGlhbmNlKHRoaXMuaGFpZCk7XG4gIH1cbiAgcHV0RGF0YShkYXRhKSB7XG4gICAgcmV0dXJuIHRoaXMuY29uZmlnLnNldEFwcGxpYW5jZSh0aGlzLmhhaWQsIGRhdGEpO1xuICB9XG59XG4vLyBBIHBsYWNlaG9sZGVyIGZvcm0gaGFuZGxlclxuZXhwb3J0cy5BcHBsaWFuY2VGb3JtID0gQXBwbGlhbmNlRm9ybTtcbmNsYXNzIFRlbXBsYXRlRm9ybSBleHRlbmRzIEZvcm0ge1xuICBlbGVtZW50QXNGb3JtO1xuICBjb25zdHJ1Y3Rvcihsb2csIC4uLmFyZ3MpIHtcbiAgICBzdXBlcihsb2cpO1xuICAgIHRoaXMuZWxlbWVudEFzRm9ybSA9IHRoaXMuZm9ybUZyb21UZW1wbGF0ZSguLi5hcmdzKTtcbiAgfVxuICAvLyBDcmVhdGUgYSBwbGFjZWhvbGRlciBzY2hlbWEgdXNpbmcgdGhlIHNwZWNpZmllZCBIVE1MIGVsZW1lbnRcbiAgYXN5bmMgZ2V0U2NoZW1hKCkge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoe1xuICAgICAgc2NoZW1hOiB7XG4gICAgICAgIHR5cGU6ICdvYmplY3QnLFxuICAgICAgICBwcm9wZXJ0aWVzOiB7fVxuICAgICAgfSxcbiAgICAgIGZvcm06IHRoaXMuZWxlbWVudEFzRm9ybVxuICAgIH0pO1xuICB9XG4gIGFzeW5jIGdldERhdGEoKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7fSk7XG4gIH1cbiAgYXN5bmMgcHV0RGF0YSgpIHt9XG59XG4vLyBJZGVudGlmaWVycyBmb3Igc3BlY2lhbCBmb3Jtc1xuZXhwb3J0cy5UZW1wbGF0ZUZvcm0gPSBUZW1wbGF0ZUZvcm07XG52YXIgRm9ybUlkO1xuKGZ1bmN0aW9uIChGb3JtSWQpIHtcbiAgRm9ybUlkW1wiR2xvYmFsXCJdID0gXCJnbG9iYWxcIjtcbiAgRm9ybUlkW1wiUGxhY2Vob2xkZXJcIl0gPSBcInBsYWNlaG9sZGVyXCI7XG4gIEZvcm1JZFtcIlVuYXZhaWxhYmxlXCJdID0gXCJ1bmF2YWlsYWJsZVwiO1xufSkoRm9ybUlkIHx8IChleHBvcnRzLkZvcm1JZCA9IEZvcm1JZCA9IHt9KSk7XG4vLyBUeXBlIGd1YXJkIHRvIGNoZWNrIHdoZXRoZXIgYSBzdHJpbmcgaXMgYSBzcGVjaWFsIGZvcm0gaWRlbnRpZmllclxuZnVuY3Rpb24gaXNGb3JtSWQodmFsdWUpIHtcbiAgcmV0dXJuIE9iamVjdC52YWx1ZXMoRm9ybUlkKS5pbmNsdWRlcyh2YWx1ZSk7XG59XG4vLyBNYW5hZ2UgdGhlIGNvbmZpZ3VyYXRpb24gZm9ybXNcbmNsYXNzIEZvcm1zIHtcbiAgbG9nO1xuICBpcGM7XG4gIGNvbmZpZztcbiAgLy8gVGhlIGZvcm0gY3VycmVudGx5IGJlaW5nIGRpc3BsYXllZFxuICBjdXJyZW50Rm9ybTtcbiAgLy8gQ3JlYXRlIGEgbmV3IGZvcm0gbWFuYWdlclxuICBjb25zdHJ1Y3Rvcihsb2csIGlwYywgY29uZmlnKSB7XG4gICAgdGhpcy5sb2cgPSBsb2c7XG4gICAgdGhpcy5pcGMgPSBpcGM7XG4gICAgdGhpcy5jb25maWcgPSBjb25maWc7XG4gICAgdGhpcy5zaG93Rm9ybSgpO1xuICB9XG4gIC8vIERpc3BsYXkgdGhlIHNwZWNpZmllZCBmb3JtIChkZWZhdWx0aW5nIHRvIHRoZSBwbGFjZWhvbGRlcilcbiAgYXN5bmMgc2hvd0Zvcm0oZm9ybUlkKSB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIFRoZSBmb3JtcyBhcmUgcmV0cmlldmVkIGZyb20gdGhlIHNlcnZlciwgc28gZGlzcGxheSBhIHNwaW5uZXJcbiAgICAgIHdpbmRvdy5ob21lYnJpZGdlLnNob3dTcGlubmVyKCk7XG4gICAgICAvLyBEaXNwbGF5IHRoZSByZXF1ZXN0ZWQgZm9ybSwgd2l0aCBmYWxsYmFjayB0byB0aGUgZXJyb3IgZm9ybVxuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdGhpcy5jb25zdHJ1Y3RBbmRTaG93Rm9ybShmb3JtSWQgPz8gRm9ybUlkLlBsYWNlaG9sZGVyKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICB0aGlzLmxvZy53YXJuKCdGYWlsZWQgdG8gZGlzcGxheSBmb3JtJywgZm9ybUlkLCBlcnIpO1xuICAgICAgICBhd2FpdCB0aGlzLmNvbnN0cnVjdEFuZFNob3dGb3JtKEZvcm1JZC5VbmF2YWlsYWJsZSk7XG4gICAgICB9XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIC8vIEVuc3VyZSB0aGF0IHRoZSBzcGlubmVyIGlzIGFsd2F5cyBoaWRkZW5cbiAgICAgIHdpbmRvdy5ob21lYnJpZGdlLmhpZGVTcGlubmVyKCk7XG4gICAgfVxuICB9XG4gIC8vIFRyeSB0byBjcmVhdGUgdGhlIHJlcXVlc3RlZCBmb3JtLCB3aXRoIGZhbGxiYWNrIHRvIHRoZSBwbGFjZWhvbGRlclxuICBhc3luYyBjb25zdHJ1Y3RBbmRTaG93Rm9ybShmb3JtSWQpIHtcbiAgICBjb25zdCBmb3JtID0gdGhpcy5jb25zdHJ1Y3RGb3JtKGZvcm1JZCk7XG4gICAgYXdhaXQgZm9ybS5jcmVhdGVGb3JtKCk7XG4gICAgdGhpcy5jdXJyZW50Rm9ybSA9IGZvcm07XG4gIH1cbiAgLy8gQ3JlYXRlIGEgc3BlY2lmaWMgZm9ybVxuICBjb25zdHJ1Y3RGb3JtKGZvcm1JZCkge1xuICAgIGlmIChpc0Zvcm1JZChmb3JtSWQpKSB7XG4gICAgICBzd2l0Y2ggKGZvcm1JZCkge1xuICAgICAgICBjYXNlIEZvcm1JZC5QbGFjZWhvbGRlcjpcbiAgICAgICAgICByZXR1cm4gbmV3IFRlbXBsYXRlRm9ybSh0aGlzLmxvZywgJ2hjLWZvcm0tcGxhY2Vob2xkZXInKTtcbiAgICAgICAgY2FzZSBGb3JtSWQuVW5hdmFpbGFibGU6XG4gICAgICAgICAgcmV0dXJuIG5ldyBUZW1wbGF0ZUZvcm0odGhpcy5sb2csICdoYy1mb3JtLXVuYXZhaWxhYmxlJyk7XG4gICAgICAgIGNhc2UgRm9ybUlkLkdsb2JhbDpcbiAgICAgICAgICByZXR1cm4gbmV3IEdsb2JhbEZvcm0odGhpcy5sb2csIHRoaXMuaXBjLCB0aGlzLmNvbmZpZyk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBuZXcgQXBwbGlhbmNlRm9ybSh0aGlzLmxvZywgdGhpcy5pcGMsIHRoaXMuY29uZmlnLCBmb3JtSWQpO1xuICAgIH1cbiAgfVxufVxuZXhwb3J0cy5Gb3JtcyA9IEZvcm1zO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ9dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p1WVcxbGN5STZXeUpmZFhScGJITkViMjBpTENKeVpYRjFhWEpsSWl3aVJtOXliU0lzSW14dlp5SXNJbVp2Y20waUxDSmpiMjV6ZEhKMVkzUnZjaUlzSW1OeVpXRjBaVVp2Y20waUxDSnpZMmhsYldFaUxDSm5aWFJUWTJobGJXRWlMQ0prWVhSaElpd2laMlYwUkdGMFlTSXNJbkJoZEdOb1pXUlRZMmhsYldFaUxDSndZWFJqYUZOamFHVnRZU0lzSW1SbFluVm5JaXdpZDJsdVpHOTNJaXdpYUc5dFpXSnlhV1JuWlNJc0ltOXVRMmhoYm1kbElpd2lZMjl1Wm1sbklpd2ljSFYwUkdGMFlTSXNJbVJsYzNSeWIzbEdiM0p0SWl3aVpXNWtJaXdpZFc1a1pXWnBibVZrSWl3aVptOXliVVp5YjIxVVpXMXdiR0YwWlNJc0ltRnlaM01pTENKMFpXMXdiR0YwWlNJc0ltTnNiMjVsVkdWdGNHeGhkR1VpTENKaFluTlVaVzF3YkdGMFpTSXNJbVZzWlcxbGJuUlhhWFJvUVdKemIyeDFkR1ZRWVhSb2N5SXNJbVp2Y20xR2NtOXRTRlJOVENJc0ltVnNaVzFsYm5RaUxDSjBlWEJsSWl3aWFHVnNjSFpoYkhWbElpd2laMlYwU0ZSTlRDSXNJbVY0Y0c5eWRITWlMQ0pIYkc5aVlXeEdiM0p0SWl3aWFYQmpJaXdpY21WeGRXVnpkQ0lzSW1kbGRFZHNiMkpoYkNJc0luTmxkRWRzYjJKaGJDSXNJa0Z3Y0d4cFlXNWpaVVp2Y20waUxDSm9ZV2xrSWl3aVoyVjBRWEJ3YkdsaGJtTmxJaXdpYzJWMFFYQndiR2xoYm1ObElpd2lWR1Z0Y0d4aGRHVkdiM0p0SWl3aVpXeGxiV1Z1ZEVGelJtOXliU0lzSWxCeWIyMXBjMlVpTENKeVpYTnZiSFpsSWl3aWNISnZjR1Z5ZEdsbGN5SXNJa1p2Y20xSlpDSXNJbWx6Um05eWJVbGtJaXdpZG1Gc2RXVWlMQ0pQWW1wbFkzUWlMQ0oyWVd4MVpYTWlMQ0pwYm1Oc2RXUmxjeUlzSWtadmNtMXpJaXdpWTNWeWNtVnVkRVp2Y20waUxDSnphRzkzUm05eWJTSXNJbVp2Y20xSlpDSXNJbk5vYjNkVGNHbHVibVZ5SWl3aVkyOXVjM1J5ZFdOMFFXNWtVMmh2ZDBadmNtMGlMQ0pRYkdGalpXaHZiR1JsY2lJc0ltVnljaUlzSW5kaGNtNGlMQ0pWYm1GMllXbHNZV0pzWlNJc0ltaHBaR1ZUY0dsdWJtVnlJaXdpWTI5dWMzUnlkV04wUm05eWJTSXNJa2RzYjJKaGJDSmRMQ0p6YjNWeVkyVnpJanBiSWk0dUx5NHVMeTR1TDNOeVl5OW9iMjFsWW5KcFpHZGxMWFZwTDNCMVlteHBZeTltYjNKdGN5NTBjeUpkTENKemIzVnlZMlZ6UTI5dWRHVnVkQ0k2VzI1MWJHeGRMQ0p0WVhCd2FXNW5jeUk2SWpzN096czdPMEZCVTBFc1NVRkJRVUVzVTBGQlFTeEhRVUZCUXl4UFFVRkJPMEZCVkVFN1FVRkRRVHM3UVVGVlFUdEJRVU5OTEUxQlFXZENReXhKUVVGSk8wVkJUVVJETEVkQlFVRTdSVUZLY2tJN1JVRkRRVU1zU1VGQlNUdEZRVVZLTzBWQlEwRkRMRmxCUVhGQ1JpeEhRVUZYTzBsQlFWZ3NTMEZCUVVFc1IwRkJSeXhIUVVGSVFTeEhRVUZITzBWQlFWYzdSVUZYYmtNN1JVRkRRU3hOUVVGTlJ5eFZRVUZWUVN4RFFVRkJPMGxCUTFvN1NVRkRRU3hOUVVGTlF5eE5RVUZOTEVkQlFVY3NUVUZCVFN4SlFVRkpMRU5CUVVORExGTkJRVk1zUlVGQlJUdEpRVU55UXl4TlFVRk5ReXhKUVVGSkxFZEJRVXNzVFVGQlRTeEpRVUZKTEVOQlFVTkRMRTlCUVU4c1JVRkJSVHRKUVVWdVF6dEpRVU5CTEUxQlFVMURMR0ZCUVdFc1IwRkJSeXhKUVVGSkxFTkJRVU5ETEZkQlFWY3NRMEZCUTB3c1RVRkJUU3hEUVVGRE8wbEJRemxETEVsQlFVa3NRMEZCUTBvc1IwRkJSeXhEUVVGRFZTeExRVUZMTEVOQlFVTXNXVUZCV1N4RlFVRkZSaXhoUVVGaExFVkJRVVZHTEVsQlFVa3NRMEZCUXp0SlFVTnFSQ3hKUVVGSkxFTkJRVU5NTEVsQlFVa3NSMEZCUjFVc1RVRkJUU3hEUVVGRFF5eFZRVUZWTEVOQlFVTlVMRlZCUVZVc1EwRkJRMHNzWVVGQllTeEZRVUZGUml4SlFVRkpMRU5CUVVNN1NVRkZOMFE3U1VGRFFTeEpRVUZKTEVOQlFVTk1MRWxCUVVrc1EwRkJRMWtzVVVGQlVTeERRVUZEUXl4TlFVRk5MRWxCUVVrc1NVRkJTU3hEUVVGRFF5eFBRVUZQTEVOQlFVTkVMRTFCUVUwc1EwRkJReXhEUVVGRE8wVkJRM1JFTzBWQlJVRTdSVUZEUVVVc1YwRkJWMEVzUTBGQlFUdEpRVU5RTEVsQlFVa3NRMEZCUTJZc1NVRkJTU3hGUVVGRlowSXNSMEZCUnl4RlFVRkZPMGxCUTJoQ0xFbEJRVWtzUTBGQlEyaENMRWxCUVVrc1IwRkJSMmxDTEZOQlFWTTdSVUZEZWtJN1JVRkZRVHRGUVVOQlZDeFhRVUZYUVN4RFFVRkRUQ3hOUVVGM1FqdEpRVU5vUXl4TlFVRk5TQ3hKUVVGSkxFZEJRVWNzUTBGRFZDeEpRVUZKUnl4TlFVRk5MRU5CUVVOSUxFbEJRVWtzU1VGQlNTeEZRVUZGTEVOQlFVTXNSVUZEZEVJc1IwRkJSeXhKUVVGSkxFTkJRVU5yUWl4blFrRkJaMElzUTBGQlF5eG5Ra0ZCWjBJc1EwRkJReXhEUVVNM1F6dEpRVU5FTEU5QlFVODdUVUZCUlN4SFFVRkhaaXhOUVVGTk8wMUJRVVZJTzBsQlFVa3NRMEZCUlR0RlFVTTVRanRGUVVWQk8wVkJRMEZyUWl4blFrRkJaMEpCTEVOQlFVTXNSMEZCUjBNc1NVRkJjME03U1VGRGRFUXNUVUZCVFVNc1VVRkJVU3hIUVVGSExFbEJRVUZETEhWQ1FVRmhMRVZCUVVNc1IwRkJSMFlzU1VGQlNTeERRVUZETzBsQlEzWkRMRTFCUVUxSExGZEJRVmNzUjBGQlJ5eEpRVUZCUXl4clEwRkJkMElzUlVGQlEwZ3NVVUZCVVN4RFFVRkRPMGxCUTNSRUxFOUJRVThzU1VGQlNTeERRVUZEU1N4WlFVRlpMRU5CUVVOR0xGZEJRVmNzUTBGQlF6dEZRVU42UXp0RlFVVkJPMFZCUTBGRkxGbEJRVmxCTEVOQlFVTkRMRTlCUVdFN1NVRkRkRUlzVDBGQlR5eERRVUZETzAxQlEwcERMRWxCUVVrc1JVRkJVU3hOUVVGTk8wMUJRMnhDUXl4VFFVRlRMRVZCUVVjc1NVRkJRVU1zYVVKQlFVOHNSVUZCUTBnc1QwRkJUenRMUVVNNVFpeERRVUZETzBWQlEwNDdPMEZCUjBvN1FVRkJRVWtzVDBGQlFTeERRVUZCTDBJc1NVRkJRU3hIUVVGQlFTeEpRVUZCTzBGQlEwMHNUVUZCVDJkRExGVkJRVmNzVTBGQlVXaERMRWxCUVVrN1JVRkZXR2xETEVkQlFVRTdSVUZEUVd4Q0xFMUJRVUU3UlVGR2NrSmFMRmxCUVZsR0xFZEJRVEJDTEVWQlEycENaME1zUjBGQmIwSXNSVUZEY0VKc1FpeE5RVUZwUWp0SlFVTnNReXhMUVVGTExFTkJRVU5rTEVkQlFVY3NRMEZCUXp0SlFVWlBMRXRCUVVGblF5eEhRVUZITEVkQlFVaEJMRWRCUVVjN1NVRkRTQ3hMUVVGQmJFSXNUVUZCVFN4SFFVRk9RU3hOUVVGTk8wVkJSVE5DTzBWQlJVRlVMRk5CUVZOQkxFTkJRVUU3U1VGQmNVTXNUMEZCVHl4SlFVRkpMRU5CUVVNeVFpeEhRVUZITEVOQlFVTkRMRTlCUVU4c1EwRkJReXhuUWtGQlowSXNSVUZCUlN4SlFVRkpMRU5CUVVNN1JVRkJSVHRGUVVNdlJqRkNMRTlCUVU5QkxFTkJRVUU3U1VGQmRVTXNUMEZCVHl4SlFVRkpMRU5CUVVOUExFMUJRVTBzUTBGQlEyOUNMRk5CUVZNc1JVRkJSVHRGUVVGRk8wVkJRemxGYmtJc1QwRkJUMEVzUTBGQlExUXNTVUZCYTBJN1NVRkJiMElzVDBGQlR5eEpRVUZKTEVOQlFVTlJMRTFCUVUwc1EwRkJRM0ZDTEZOQlFWTXNRMEZCUXpkQ0xFbEJRVzlDTEVOQlFVTTdSVUZCUlRzN1FVRkhkRWM3UVVGQlFYZENMRTlCUVVFc1EwRkJRVU1zVlVGQlFTeEhRVUZCUVN4VlFVRkJPMEZCUTAwc1RVRkJUMHNzWVVGQll5eFRRVUZSY2tNc1NVRkJTVHRGUVVWa2FVTXNSMEZCUVR0RlFVTkJiRUlzVFVGQlFUdEZRVU5CZFVJc1NVRkJRVHRGUVVoeVFtNURMRmxCUVZsR0xFZEJRVEJDTEVWQlEycENaME1zUjBGQmIwSXNSVUZEY0VKc1FpeE5RVUZwUWl4RlFVTnFRblZDTEVsQlFXbENPMGxCUTJ4RExFdEJRVXNzUTBGQlEzSkRMRWRCUVVjc1EwRkJRenRKUVVoUExFdEJRVUZuUXl4SFFVRkhMRWRCUVVoQkxFZEJRVWM3U1VGRFNDeExRVUZCYkVJc1RVRkJUU3hIUVVGT1FTeE5RVUZOTzBsQlEwNHNTMEZCUVhWQ0xFbEJRVWtzUjBGQlNrRXNTVUZCU1R0RlFVVjZRanRGUVVWQmFFTXNVMEZCVTBFc1EwRkJRVHRKUVVGeFF5eFBRVUZQTEVsQlFVa3NRMEZCUXpKQ0xFZEJRVWNzUTBGQlEwTXNUMEZCVHl4RFFVRkRMRzFDUVVGdFFpeEZRVUZGTEVsQlFVa3NRMEZCUTBrc1NVRkJTU3hEUVVGRE8wVkJRVVU3UlVGRGRrYzVRaXhQUVVGUFFTeERRVUZCTzBsQlFYVkRMRTlCUVU4c1NVRkJTU3hEUVVGRFR5eE5RVUZOTEVOQlFVTjNRaXhaUVVGWkxFTkJRVU1zU1VGQlNTeERRVUZEUkN4SlFVRkpMRU5CUVVNN1JVRkJSVHRGUVVNeFJuUkNMRTlCUVU5QkxFTkJRVU5VTEVsQlFXdENPMGxCUVc5Q0xFOUJRVThzU1VGQlNTeERRVUZEVVN4TlFVRk5MRU5CUVVONVFpeFpRVUZaTEVOQlFVTXNTVUZCU1N4RFFVRkRSaXhKUVVGSkxFVkJRVVV2UWl4SlFVRkpMRU5CUVVNN1JVRkJSVHM3UVVGSGNFYzdRVUZCUVhkQ0xFOUJRVUVzUTBGQlFVMHNZVUZCUVN4SFFVRkJRU3hoUVVGQk8wRkJRMDBzVFVGQlQwa3NXVUZCWVN4VFFVRlJla01zU1VGQlNUdEZRVVY2UWpCRExHRkJRV0U3UlVGRmRFSjJReXhaUVVGWlJpeEhRVUZyUWl4RlFVTnNRaXhIUVVGSGIwSXNTVUZCZVVNN1NVRkRjRVFzUzBGQlN5eERRVUZEY0VJc1IwRkJSeXhEUVVGRE8wbEJRMVlzU1VGQlNTeERRVUZEZVVNc1lVRkJZU3hIUVVGSExFbEJRVWtzUTBGQlEzUkNMR2RDUVVGblFpeERRVUZETEVkQlFVZERMRWxCUVVrc1EwRkJRenRGUVVOMlJEdEZRVVZCTzBWQlEwRXNUVUZCVFdZc1UwRkJVMEVzUTBGQlFUdEpRVU5ZTEU5QlFVOXhReXhQUVVGUExFTkJRVU5ETEU5QlFVOHNRMEZCUXp0TlFVTnVRblpETEUxQlFVMHNSVUZCUlR0UlFVTktkVUlzU1VGQlNTeEZRVUZGTEZGQlFWRTdVVUZEWkdsQ0xGVkJRVlVzUlVGQlJUdFBRVU5tTzAxQlEwUXpReXhKUVVGSkxFVkJRVWtzU1VGQlNTeERRVUZEZDBNN1MwRkRhRUlzUTBGQlF6dEZRVU5PTzBWQlJVRXNUVUZCVFd4RExFOUJRVTlCTEVOQlFVRTdTVUZCTmtJc1QwRkJUMjFETEU5QlFVOHNRMEZCUTBNc1QwRkJUeXhEUVVGRExFVkJRVVVzUTBGQlF6dEZRVUZGTzBWQlEzUkZMRTFCUVUwMVFpeFBRVUZQUVN4RFFVRkJMRWRCUVhsRE96dEJRVWN4UkR0QlFVRkJaU3hQUVVGQkxFTkJRVUZWTEZsQlFVRXNSMEZCUVVFc1dVRkJRVHRCUVVOQkxFbEJRVmxMTEUxQlNWZzdRVUZLUkN4WFFVRlpRU3hOUVVGTk8wVkJRMlJCTEUxQlFVRXNjVUpCUVhOQ08wVkJRM1JDUVN4TlFVRkJMQ3RDUVVFeVFqdEZRVU16UWtFc1RVRkJRU3dyUWtGQk1rSTdRVUZETDBJc1EwRkJReXhGUVVwWFFTeE5RVUZOTEV0QlFVRm1MRTlCUVVFc1EwRkJRV1VzVFVGQlFTeEhRVUZPUVN4TlFVRk5PMEZCVFd4Q08wRkJRMEVzVTBGQlUwTXNVVUZCVVVFc1EwRkJRME1zUzBGQllUdEZRVU16UWl4UFFVRlBReXhOUVVGTkxFTkJRVU5ETEUxQlFVMHNRMEZCUTBvc1RVRkJUU3hEUVVGRExFTkJRVU5MTEZGQlFWRXNRMEZCUTBnc1MwRkJaU3hEUVVGRE8wRkJRekZFTzBGQlJVRTdRVUZEVFN4TlFVRlBTU3hMUVVGTE8wVkJUVTl1UkN4SFFVRkJPMFZCUTBGblF5eEhRVUZCTzBWQlEwRnNRaXhOUVVGQk8wVkJUbkpDTzBWQlEwRnpReXhYUVVGWE8wVkJSVmc3UlVGRFFXeEVMRmxCUVhGQ1JpeEhRVUZwUWl4RlFVTnFRbWRETEVkQlFXOUNMRVZCUTNCQ2JFSXNUVUZCYVVJN1NVRkdha0lzUzBGQlFXUXNSMEZCUnl4SFFVRklRU3hIUVVGSE8wbEJRMGdzUzBGQlFXZERMRWRCUVVjc1IwRkJTRUVzUjBGQlJ6dEpRVU5JTEV0QlFVRnNRaXhOUVVGTkxFZEJRVTVCTEUxQlFVMDdTVUZEZGtJc1NVRkJTU3hEUVVGRGRVTXNVVUZCVVN4RlFVRkZPMFZCUTI1Q08wVkJSVUU3UlVGRFFTeE5RVUZOUVN4UlFVRlJRU3hEUVVGRFF5eE5RVUZsTzBsQlF6RkNMRWxCUVVrN1RVRkRRVHROUVVOQk0wTXNUVUZCVFN4RFFVRkRReXhWUVVGVkxFTkJRVU15UXl4WFFVRlhMRVZCUVVVN1RVRkZMMEk3VFVGRFFTeEpRVUZKTzFGQlEwRXNUVUZCVFN4SlFVRkpMRU5CUVVORExHOUNRVUZ2UWl4RFFVRkRSaXhOUVVGTkxFbEJRVWxVTEUxQlFVMHNRMEZCUTFrc1YwRkJWeXhEUVVGRE8wMUJRMnBGTEVOQlFVTXNRMEZCUXl4UFFVRlBReXhIUVVGSExFVkJRVVU3VVVGRFZpeEpRVUZKTEVOQlFVTXhSQ3hIUVVGSExFTkJRVU15UkN4SlFVRkpMRU5CUVVNc2QwSkJRWGRDTEVWQlFVVk1MRTFCUVUwc1JVRkJSVWtzUjBGQlJ5eERRVUZETzFGQlEzQkVMRTFCUVUwc1NVRkJTU3hEUVVGRFJpeHZRa0ZCYjBJc1EwRkJRMWdzVFVGQlRTeERRVUZEWlN4WFFVRlhMRU5CUVVNN1RVRkRka1E3U1VGRFNpeERRVUZETEZOQlFWRTdUVUZEVER0TlFVTkJha1FzVFVGQlRTeERRVUZEUXl4VlFVRlZMRU5CUVVOcFJDeFhRVUZYTEVWQlFVVTdTVUZEYmtNN1JVRkRTanRGUVVWQk8wVkJRMEVzVFVGQlRVd3NiMEpCUVc5Q1FTeERRVUZEUml4TlFVRmpPMGxCUTNKRExFMUJRVTF5UkN4SlFVRkpMRWRCUVVjc1NVRkJTU3hEUVVGRE5rUXNZVUZCWVN4RFFVRkRVaXhOUVVGTkxFTkJRVU03U1VGRGRrTXNUVUZCVFhKRUxFbEJRVWtzUTBGQlEwVXNWVUZCVlN4RlFVRkZPMGxCUTNaQ0xFbEJRVWtzUTBGQlEybEVMRmRCUVZjc1IwRkJSMjVFTEVsQlFVazdSVUZETTBJN1JVRkZRVHRGUVVOQk5rUXNZVUZCWVVFc1EwRkJRMUlzVFVGQll6dEpRVU40UWl4SlFVRkpVaXhSUVVGUkxFTkJRVU5STEUxQlFVMHNRMEZCUXl4RlFVRkZPMDFCUTJ4Q0xGRkJRVkZCTEUxQlFVMDdVVUZEWkN4TFFVRkxWQ3hOUVVGTkxFTkJRVU5aTEZkQlFWYzdWVUZCUlN4UFFVRlBMRWxCUVVscVFpeFpRVUZaTEVOQlFVVXNTVUZCU1N4RFFVRkRlRU1zUjBGQlJ5eEZRVUZGTEhGQ1FVRnhRaXhEUVVGRE8xRkJRMnhHTEV0QlFVczJReXhOUVVGTkxFTkJRVU5sTEZkQlFWYzdWVUZCUlN4UFFVRlBMRWxCUVVsd1FpeFpRVUZaTEVOQlFVVXNTVUZCU1N4RFFVRkRlRU1zUjBGQlJ5eEZRVUZGTEhGQ1FVRnhRaXhEUVVGRE8xRkJRMnhHTEV0QlFVczJReXhOUVVGTkxFTkJRVU5yUWl4TlFVRk5PMVZCUVU4c1QwRkJUeXhKUVVGSmFFTXNWVUZCVlN4RFFVRkpMRWxCUVVrc1EwRkJReTlDTEVkQlFVY3NSVUZCUlN4SlFVRkpMRU5CUVVOblF5eEhRVUZITEVWQlFVVXNTVUZCU1N4RFFVRkRiRUlzVFVGQlRTeERRVUZETzAxQlEyeEdPMGxCUTBvc1EwRkJReXhOUVVGTk8wMUJRMGdzVDBGQlR5eEpRVUZKYzBJc1lVRkJZU3hEUVVGRExFbEJRVWtzUTBGQlEzQkRMRWRCUVVjc1JVRkJSU3hKUVVGSkxFTkJRVU5uUXl4SFFVRkhMRVZCUVVVc1NVRkJTU3hEUVVGRGJFSXNUVUZCVFN4RlFVRkZkME1zVFVGQlRTeERRVUZETzBsQlEzSkZPMFZCUTBvN08wRkJRMGg0UWl4UFFVRkJMRU5CUVVGeFFpeExRVUZCTEVkQlFVRkJMRXRCUVVFaUxDSnBaMjV2Y21WTWFYTjBJanBiWFgwPSIsIlwidXNlIHN0cmljdFwiO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5TZXJ2ZXJMb2dnZXIgPSBleHBvcnRzLkNvbnNvbGVMb2dnZXIgPSBleHBvcnRzLkNsaWVudExvZ2dlciA9IHZvaWQgMDtcbi8vIEhvbWVicmlkZ2UgcGx1Z2luIGZvciBIb21lIENvbm5lY3QgaG9tZSBhcHBsaWFuY2VzXG4vLyBDb3B5cmlnaHQgwqkgMjAyMyBBbGV4YW5kZXIgVGhvdWt5ZGlkZXNcbi8vIFByZWZpeCBmb3IgY2xpZW50IGFuZCBzZXJ2ZXIgbG9nIG1lc3NhZ2VzXG5jb25zdCBQTFVHSU5fUFJFRklYID0gd2luZG93LmhvbWVicmlkZ2UucGx1Z2luLmRpc3BsYXlOYW1lID8/IHdpbmRvdy5ob21lYnJpZGdlLnBsdWdpbi5uYW1lO1xuLy8gQSBsb2dnZXIgdGhhdCBzZW5kcyBtZXNzYWdlcyB0byB0aGUgZGVidWdnaW5nIGNvbnNvbGVcbmNsYXNzIENvbnNvbGVMb2dnZXIge1xuICBwcmVmaXg7XG4gIC8vIENyZWF0ZSBhIG5ldyBjb25zb2xlIGxvZ2dlclxuICBjb25zdHJ1Y3RvcihwcmVmaXggPSAnJykge1xuICAgIHRoaXMucHJlZml4ID0gcHJlZml4O1xuICB9XG4gIC8vIFNpbXBsZSB3cmFwcGVycyB0byBsb2cgYSBtZXNzYWdlXG4gIGVycm9yKG1lc3NhZ2UsIC4uLnBhcmFtcykge1xuICAgIHRoaXMubG9nKFwiZXJyb3JcIiAvKiBMb2dMZXZlbC5FUlJPUiAqLywgbWVzc2FnZSwgLi4ucGFyYW1zKTtcbiAgfVxuICB3YXJuKG1lc3NhZ2UsIC4uLnBhcmFtcykge1xuICAgIHRoaXMubG9nKFwid2FyblwiIC8qIExvZ0xldmVsLldBUk4gKi8sIG1lc3NhZ2UsIC4uLnBhcmFtcyk7XG4gIH1cbiAgc3VjY2VzcyhtZXNzYWdlLCAuLi5wYXJhbXMpIHtcbiAgICB0aGlzLmxvZyhcInN1Y2Nlc3NcIiAvKiBMb2dMZXZlbC5TVUNDRVNTICovLCBtZXNzYWdlLCAuLi5wYXJhbXMpO1xuICB9XG4gIGluZm8obWVzc2FnZSwgLi4ucGFyYW1zKSB7XG4gICAgdGhpcy5sb2coXCJpbmZvXCIgLyogTG9nTGV2ZWwuSU5GTyAqLywgbWVzc2FnZSwgLi4ucGFyYW1zKTtcbiAgfVxuICBkZWJ1ZyhtZXNzYWdlLCAuLi5wYXJhbXMpIHtcbiAgICB0aGlzLmxvZyhcImRlYnVnXCIgLyogTG9nTGV2ZWwuREVCVUcgKi8sIG1lc3NhZ2UsIC4uLnBhcmFtcyk7XG4gIH1cbiAgLy8gTG9nIGEgbWVzc2FnZSBhdCB0aGUgc3BlY2lmaWVkIGxldmVsXG4gIGxvZyhsZXZlbCwgbWVzc2FnZSwgLi4ucGFyYW1zKSB7XG4gICAgLy8gQWRkIHRoZSBwcmVmaXggdG8gdGhlIG1lc3NhZ2VcbiAgICBpZiAodGhpcy5wcmVmaXgubGVuZ3RoKSBtZXNzYWdlID0gYFske3RoaXMucHJlZml4fV0gJHttZXNzYWdlfWA7XG4gICAgLy8gTG9nIHRoZSBtZXNzYWdlXG4gICAgc3dpdGNoIChsZXZlbCkge1xuICAgICAgY2FzZSBcImVycm9yXCIgLyogTG9nTGV2ZWwuRVJST1IgKi86XG4gICAgICAgIGNvbnNvbGUuZXJyb3IobWVzc2FnZSwgLi4ucGFyYW1zKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFwid2FyblwiIC8qIExvZ0xldmVsLldBUk4gKi86XG4gICAgICAgIGNvbnNvbGUud2FybihtZXNzYWdlLCAuLi5wYXJhbXMpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgXCJzdWNjZXNzXCIgLyogTG9nTGV2ZWwuU1VDQ0VTUyAqLzpcbiAgICAgICAgY29uc29sZS5pbmZvKG1lc3NhZ2UsIC4uLnBhcmFtcyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBcImluZm9cIiAvKiBMb2dMZXZlbC5JTkZPICovOlxuICAgICAgICBjb25zb2xlLmluZm8obWVzc2FnZSwgLi4ucGFyYW1zKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFwiZGVidWdcIiAvKiBMb2dMZXZlbC5ERUJVRyAqLzpcbiAgICAgICAgY29uc29sZS5kZWJ1ZyhtZXNzYWdlLCAuLi5wYXJhbXMpO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gIH1cbn1cbi8vIExvZ2dlciBmb3IgbG9jYWxseSBnZW5lcmF0ZWQgbWVzc2FnZXNcbmV4cG9ydHMuQ29uc29sZUxvZ2dlciA9IENvbnNvbGVMb2dnZXI7XG5jbGFzcyBDbGllbnRMb2dnZXIgZXh0ZW5kcyBDb25zb2xlTG9nZ2VyIHtcbiAgLy8gQ3JlYXRlIGEgbmV3IGNsaWVudCBsb2dnZXJcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoYCR7UExVR0lOX1BSRUZJWH0gY2xpZW50YCk7XG4gIH1cbn1cbi8vIExvZ2dlciB0aGF0IHJlY2VpdmVzIG1lc3NhZ2VzIGV2ZW50cyBmcm9tIHRoZSBzZXJ2ZXJcbmV4cG9ydHMuQ2xpZW50TG9nZ2VyID0gQ2xpZW50TG9nZ2VyO1xuY2xhc3MgU2VydmVyTG9nZ2VyIGV4dGVuZHMgQ29uc29sZUxvZ2dlciB7XG4gIGlwYztcbiAgLy8gQ3JlYXRlIGEgbmV3IHNlcnZlciBsb2dnZXJcbiAgY29uc3RydWN0b3IoaXBjLCBtaW5MZXZlbCkge1xuICAgIHN1cGVyKGAke1BMVUdJTl9QUkVGSVh9IHNlcnZlcmApO1xuICAgIHRoaXMuaXBjID0gaXBjO1xuICAgIC8vIFN0YXJ0IHJlY2VpdmluZyBsb2cgZXZlbnRzXG4gICAgaXBjLm9uRXZlbnQoJ2xvZycsIG1lc3NhZ2VzID0+IHtcbiAgICAgIHRoaXMubG9nTWVzc2FnZXMobWVzc2FnZXMpO1xuICAgIH0pO1xuICAgIHRyeSB7XG4gICAgICBpcGMucmVxdWVzdCgnL2xvZycsIG1pbkxldmVsKTtcbiAgICB9IGNhdGNoIHsvKiBlbXB0eSAqL31cbiAgfVxuICAvLyBMb2cgbWVzc2FnZXMgcmVjZWl2ZWQgZnJvbSB0aGUgc2VydmVyXG4gIGxvZ01lc3NhZ2VzKG1lc3NhZ2VzKSB7XG4gICAgZm9yIChjb25zdCB7XG4gICAgICBsZXZlbCxcbiAgICAgIG1lc3NhZ2UsXG4gICAgICBwYXJhbXNcbiAgICB9IG9mIG1lc3NhZ2VzKSB0aGlzLmxvZyhsZXZlbCwgbWVzc2FnZSwgLi4ucGFyYW1zKTtcbiAgfVxufVxuZXhwb3J0cy5TZXJ2ZXJMb2dnZXIgPSBTZXJ2ZXJMb2dnZXI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldD11dGYtODtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnVZVzFsY3lJNld5SlFURlZIU1U1ZlVGSkZSa2xZSWl3aWQybHVaRzkzSWl3aWFHOXRaV0p5YVdSblpTSXNJbkJzZFdkcGJpSXNJbVJwYzNCc1lYbE9ZVzFsSWl3aWJtRnRaU0lzSWtOdmJuTnZiR1ZNYjJkblpYSWlMQ0p3Y21WbWFYZ2lMQ0pqYjI1emRISjFZM1J2Y2lJc0ltVnljbTl5SWl3aWJXVnpjMkZuWlNJc0luQmhjbUZ0Y3lJc0lteHZaeUlzSW5kaGNtNGlMQ0p6ZFdOalpYTnpJaXdpYVc1bWJ5SXNJbVJsWW5Wbklpd2liR1YyWld3aUxDSnNaVzVuZEdnaUxDSmpiMjV6YjJ4bElpd2laWGh3YjNKMGN5SXNJa05zYVdWdWRFeHZaMmRsY2lJc0lsTmxjblpsY2t4dloyZGxjaUlzSW1sd1l5SXNJbTFwYmt4bGRtVnNJaXdpYjI1RmRtVnVkQ0lzSW0xbGMzTmhaMlZ6SWl3aWJHOW5UV1Z6YzJGblpYTWlMQ0p5WlhGMVpYTjBJbDBzSW5OdmRYSmpaWE1pT2xzaUxpNHZMaTR2TGk0dmMzSmpMMmh2YldWaWNtbGtaMlV0ZFdrdmNIVmliR2xqTDJ4dloyZGxjaTUwY3lKZExDSnpiM1Z5WTJWelEyOXVkR1Z1ZENJNlcyNTFiR3hkTENKdFlYQndhVzVuY3lJNklqczdPenM3TzBGQlFVRTdRVUZEUVR0QlFVOUJPMEZCUTBFc1RVRkJUVUVzWVVGQllTeEhRVUZIUXl4TlFVRk5MRU5CUVVORExGVkJRVlVzUTBGQlEwTXNUVUZCVFN4RFFVRkRReXhYUVVGWExFbEJRVWxJTEUxQlFVMHNRMEZCUTBNc1ZVRkJWU3hEUVVGRFF5eE5RVUZOTEVOQlFVTkZMRWxCUVVrN1FVRkZNMFk3UVVGRFRTeE5RVUZQUXl4aFFVRmhPMFZCUjBSRExFMUJRVUU3UlVGRWNrSTdSVUZEUVVNc1dVRkJjVUpFTEUxQlFVRXNSMEZCVXl4RlFVRkZPMGxCUVZnc1MwRkJRVUVzVFVGQlRTeEhRVUZPUVN4TlFVRk5PMFZCUVZFN1JVRkZia003UlVGRFFVVXNTMEZCUzBFc1EwRkJSME1zVDBGQlpTeEZRVUZGTEVkQlFVZERMRTFCUVdsQ08wbEJRVlVzU1VGQlNTeERRVUZEUXl4SFFVRkhMQ3RDUVVGdFFrWXNUMEZCVHl4RlFVRkZMRWRCUVVkRExFMUJRVTBzUTBGQlF6dEZRVUZGTzBWQlEzWkhSU3hKUVVGSlFTeERRVUZKU0N4UFFVRmxMRVZCUVVVc1IwRkJSME1zVFVGQmFVSTdTVUZCVlN4SlFVRkpMRU5CUVVORExFZEJRVWNzTmtKQlFXMUNSaXhQUVVGUExFVkJRVVVzUjBGQlIwTXNUVUZCVFN4RFFVRkRPMFZCUVVVN1JVRkRka2RITEU5QlFVOUJMRU5CUVVOS0xFOUJRV1VzUlVGQlJTeEhRVUZIUXl4TlFVRnBRanRKUVVGVkxFbEJRVWtzUTBGQlEwTXNSMEZCUnl4dFEwRkJiVUpHTEU5QlFVOHNSVUZCUlN4SFFVRkhReXhOUVVGTkxFTkJRVU03UlVGQlJUdEZRVU4yUjBrc1NVRkJTVUVzUTBGQlNVd3NUMEZCWlN4RlFVRkZMRWRCUVVkRExFMUJRV2xDTzBsQlFWVXNTVUZCU1N4RFFVRkRReXhIUVVGSExEWkNRVUZ0UWtZc1QwRkJUeXhGUVVGRkxFZEJRVWRETEUxQlFVMHNRMEZCUXp0RlFVRkZPMFZCUTNaSFN5eExRVUZMUVN4RFFVRkhUaXhQUVVGbExFVkJRVVVzUjBGQlIwTXNUVUZCYVVJN1NVRkJWU3hKUVVGSkxFTkJRVU5ETEVkQlFVY3NLMEpCUVcxQ1JpeFBRVUZQTEVWQlFVVXNSMEZCUjBNc1RVRkJUU3hEUVVGRE8wVkJRVVU3UlVGSGRrYzdSVUZEUVVNc1IwRkJSMEVzUTBGQlEwc3NTMEZCWlN4RlFVRkZVQ3hQUVVGbExFVkJRVVVzUjBGQlIwTXNUVUZCYVVJN1NVRkRkRVE3U1VGRFFTeEpRVUZKTEVsQlFVa3NRMEZCUTBvc1RVRkJUU3hEUVVGRFZ5eE5RVUZOTEVWQlFVVlNMRTlCUVU4c1IwRkJSeXhKUVVGSkxFbEJRVWtzUTBGQlEwZ3NUVUZCVFN4TFFVRkxSeXhQUVVGUExFVkJRVVU3U1VGRkwwUTdTVUZEUVN4UlFVRlJUeXhMUVVGTE8wMUJRMkk3VVVGQmRVSkZMRTlCUVU4c1EwRkJRMVlzUzBGQlN5eERRVUZIUXl4UFFVRlBMRVZCUVVVc1IwRkJSME1zVFVGQlRTeERRVUZETzFGQlFVVTdUVUZETlVRN1VVRkJkVUpSTEU5QlFVOHNRMEZCUTA0c1NVRkJTU3hEUVVGSlNDeFBRVUZQTEVWQlFVVXNSMEZCUjBNc1RVRkJUU3hEUVVGRE8xRkJRVVU3VFVGRE5VUTdVVUZCZFVKUkxFOUJRVThzUTBGQlEwb3NTVUZCU1N4RFFVRkpUQ3hQUVVGUExFVkJRVVVzUjBGQlIwTXNUVUZCVFN4RFFVRkRPMUZCUVVVN1RVRkROVVE3VVVGQmRVSlJMRTlCUVU4c1EwRkJRMG9zU1VGQlNTeERRVUZKVEN4UFFVRlBMRVZCUVVVc1IwRkJSME1zVFVGQlRTeERRVUZETzFGQlFVVTdUVUZETlVRN1VVRkJkVUpSTEU5QlFVOHNRMEZCUTBnc1MwRkJTeXhEUVVGSFRpeFBRVUZQTEVWQlFVVXNSMEZCUjBNc1RVRkJUU3hEUVVGRE8xRkJRVVU3U1VGRE5VUTdSVUZEU2pzN1FVRkpTanRCUVVGQlV5eFBRVUZCTEVOQlFVRmtMR0ZCUVVFc1IwRkJRVUVzWVVGQlFUdEJRVU5OTEUxQlFVOWxMRmxCUVdFc1UwRkJVV1lzWVVGQllUdEZRVVV6UXp0RlFVTkJSU3haUVVGQk8wbEJRMGtzUzBGQlN5eERRVUZETEVkQlFVZFNMR0ZCUVdFc1UwRkJVeXhEUVVGRE8wVkJRM0JET3p0QlFVZEtPMEZCUVVGdlFpeFBRVUZCTEVOQlFVRkRMRmxCUVVFc1IwRkJRVUVzV1VGQlFUdEJRVU5OTEUxQlFVOURMRmxCUVdFc1UwRkJVV2hDTEdGQlFXRTdSVUZIZEVKcFFpeEhRVUZCTzBWQlJISkNPMFZCUTBGbUxGbEJRWEZDWlN4SFFVRmpMRVZCUVVWRExGRkJRV3RDTzBsQlEyNUVMRXRCUVVzc1EwRkJReXhIUVVGSGVFSXNZVUZCWVN4VFFVRlRMRU5CUVVNN1NVRkVaaXhMUVVGQmRVSXNSMEZCUnl4SFFVRklRU3hIUVVGSE8wbEJSM0JDTzBsQlEwRkJMRWRCUVVjc1EwRkJRMFVzVDBGQlR5eERRVUZETEV0QlFVc3NSVUZCUlVNc1VVRkJVU3hKUVVGSE8wMUJRVWNzU1VGQlNTeERRVUZEUXl4WFFVRlhMRU5CUVVORUxGRkJRVkVzUTBGQlF6dEpRVUZGTEVOQlFVTXNRMEZCUXp0SlFVTXZSQ3hKUVVGSk8wMUJRVVZJTEVkQlFVY3NRMEZCUTBzc1QwRkJUeXhEUVVGRExFMUJRVTBzUlVGQlJVb3NVVUZCVVN4RFFVRkRPMGxCUVVVc1EwRkJReXhEUVVGRExFMUJRVTBzUTBGQlJUdEZRVU51UkR0RlFVVkJPMFZCUTBGSExGZEJRVmRCTEVOQlFVTkVMRkZCUVRSQ08wbEJRM0JETEV0QlFVc3NUVUZCVFR0TlFVRkZWQ3hMUVVGTE8wMUJRVVZRTEU5QlFVODdUVUZCUlVNN1NVRkJUU3hEUVVGRkxFbEJRVWxsTEZGQlFWRXNSVUZETjBNc1NVRkJTU3hEUVVGRFpDeEhRVUZITEVOQlFVTkxMRXRCUVVzc1JVRkJSVkFzVDBGQlR5eEZRVUZGTEVkQlFVZERMRTFCUVUwc1EwRkJRenRGUVVNelF6czdRVUZEU0ZNc1QwRkJRU3hEUVVGQlJTeFpRVUZCTEVkQlFVRkJMRmxCUVVFaUxDSnBaMjV2Y21WTWFYTjBJanBiWFgwPSIsIlwidXNlIHN0cmljdFwiO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5jbG9uZVRlbXBsYXRlID0gY2xvbmVUZW1wbGF0ZTtcbmV4cG9ydHMuZWxlbWVudFdpdGhBYnNvbHV0ZVBhdGhzID0gZWxlbWVudFdpdGhBYnNvbHV0ZVBhdGhzO1xuZXhwb3J0cy5nZXRFbGVtZW50QnlJZCA9IGdldEVsZW1lbnRCeUlkO1xuZXhwb3J0cy5nZXRIVE1MID0gZ2V0SFRNTDtcbmV4cG9ydHMuZ2V0U2xvdCA9IGdldFNsb3Q7XG5leHBvcnRzLnNldFNsb3RUZXh0ID0gc2V0U2xvdFRleHQ7XG52YXIgX2Fzc2VydCA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcImFzc2VydFwiKSk7XG52YXIgX3V0aWxzID0gcmVxdWlyZShcIi4uLy4uL3V0aWxzLmpzXCIpO1xuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChlKSB7IHJldHVybiBlICYmIGUuX19lc01vZHVsZSA/IGUgOiB7IGRlZmF1bHQ6IGUgfTsgfVxuLy8gSG9tZWJyaWRnZSBwbHVnaW4gZm9yIEhvbWUgQ29ubmVjdCBob21lIGFwcGxpYW5jZXNcbi8vIENvcHlyaWdodCDCqSAyMDIzIEFsZXhhbmRlciBUaG91a3lkaWRlc1xuXG4vLyBHZXQgYW4gSFRNTCBlbGVtZW50IGJ5IGl0cyBcImlkXCIgYXR0cmlidXRlXG5mdW5jdGlvbiBnZXRFbGVtZW50QnlJZChlbGVtZW50SWQpIHtcbiAgY29uc3QgZWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGVsZW1lbnRJZCk7XG4gICgwLCBfdXRpbHMuYXNzZXJ0SXNJbnN0YW5jZU9mKShlbGVtZW50LCBIVE1MRWxlbWVudCk7XG4gIHJldHVybiBlbGVtZW50O1xufVxuLy8gR2V0IGFuIEhUTUwgZWxlbWVudCB1c2luZyBhIHNsb3QgbmFtZVxuZnVuY3Rpb24gZ2V0U2xvdCh3aXRoaW4sIHNsb3ROYW1lKSB7XG4gIGNvbnN0IHNsb3RzID0gd2l0aGluLnF1ZXJ5U2VsZWN0b3JBbGwoYFtzbG90PVwiJHtzbG90TmFtZX1cIl1gKTtcbiAgX2Fzc2VydC5kZWZhdWx0LmVxdWFsKHNsb3RzLmxlbmd0aCwgMSwgYEV4cGVjdGVkIGV4YWN0bHkgb25lIHNsb3Qgd2l0aCBuYW1lIFwiJHtzbG90TmFtZX1cImApO1xuICAoMCwgX3V0aWxzLmFzc2VydElzSW5zdGFuY2VPZikoc2xvdHNbMF0sIEhUTUxFbGVtZW50KTtcbiAgcmV0dXJuIHNsb3RzWzBdO1xufVxuLy8gU2V0IHRoZSB0ZXh0IGNvbnRlbnQgb2YgbXVsdGlwbGUgc2xvdCBlbGVtZW50c1xuZnVuY3Rpb24gc2V0U2xvdFRleHQod2l0aGluLCBzbG90VGV4dCkge1xuICBmb3IgKGNvbnN0IFtzbG90TmFtZSwgdGV4dF0gb2YgT2JqZWN0LmVudHJpZXMoc2xvdFRleHQpKSBnZXRTbG90KHdpdGhpbiwgc2xvdE5hbWUpLnRleHRDb250ZW50ID0gdGV4dDtcbn1cbi8vIENyZWF0ZSBhIGNvcHkgb2YgYSB0ZW1wbGF0ZSBlbGVtZW50XG5mdW5jdGlvbiBjbG9uZVRlbXBsYXRlKGVsZW1lbnRJZCwgc2xvdFRleHQpIHtcbiAgLy8gRmluZCB0aGUgdGVtcGxhdGUgZWxlbWVudFxuICBjb25zdCB0ZW1wbGF0ZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGVsZW1lbnRJZCk7XG4gICgwLCBfdXRpbHMuYXNzZXJ0SXNJbnN0YW5jZU9mKSh0ZW1wbGF0ZSwgSFRNTFRlbXBsYXRlRWxlbWVudCk7XG4gIC8vIENsb25lIHRoZSB0ZW1wbGF0ZSdzIGRvY3VtZW50LWZyYWdtZW50IGFuZCBzZXQgc2xvdCB2YWx1ZXNcbiAgY29uc3QgZG9jdW1lbnRGcmFnbWVudCA9IHRlbXBsYXRlLmNvbnRlbnQuY2xvbmVOb2RlKHRydWUpO1xuICAoMCwgX3V0aWxzLmFzc2VydElzSW5zdGFuY2VPZikoZG9jdW1lbnRGcmFnbWVudCwgRG9jdW1lbnRGcmFnbWVudCk7XG4gIGlmIChzbG90VGV4dCkgc2V0U2xvdFRleHQoZG9jdW1lbnRGcmFnbWVudCwgc2xvdFRleHQpO1xuICByZXR1cm4gZG9jdW1lbnRGcmFnbWVudDtcbn1cbi8vIE1ha2UgVVJJIHBhdGhzIGFic29sdXRlXG5mdW5jdGlvbiBlbGVtZW50V2l0aEFic29sdXRlUGF0aHMoZnJhZ21lbnQpIHtcbiAgZm9yIChjb25zdCBhdHRyaWJ1dGUgb2YgWydocmVmJywgJ3NyYyddKSB7XG4gICAgY29uc3QgZWxlbWVudHMgPSBmcmFnbWVudC5xdWVyeVNlbGVjdG9yQWxsKGBbJHthdHRyaWJ1dGV9XWApO1xuICAgIGZvciAoY29uc3QgZWxlbWVudCBvZiBBcnJheS5mcm9tKGVsZW1lbnRzKSkge1xuICAgICAgY29uc3QgcGF0aCA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKGF0dHJpYnV0ZSk7XG4gICAgICAoMCwgX3V0aWxzLmFzc2VydElzRGVmaW5lZCkocGF0aCk7XG4gICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZShhdHRyaWJ1dGUsIG5ldyBVUkwocGF0aCwgbG9jYXRpb24uaHJlZikuaHJlZik7XG4gICAgfVxuICB9XG4gIHJldHVybiBmcmFnbWVudDtcbn1cbi8vIE9idGFpbiB0aGUgSFRNTCBzZXJpYWxpemF0aW9uIG9mIGEgdGVtcGxhdGUgZWxlbWVudFxuZnVuY3Rpb24gZ2V0SFRNTChmcmFnbWVudCkge1xuICBjb25zdCBzZXJpYWxpemVyID0gbmV3IFhNTFNlcmlhbGl6ZXIoKTtcbiAgcmV0dXJuIHNlcmlhbGl6ZXIuc2VyaWFsaXplVG9TdHJpbmcoZnJhZ21lbnQpO1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ9dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p1WVcxbGN5STZXeUpmWVhOelpYSjBJaXdpWDJsdWRHVnliM0JTWlhGMWFYSmxSR1ZtWVhWc2RDSXNJbkpsY1hWcGNtVWlMQ0pmZFhScGJITWlMQ0psSWl3aVgxOWxjMDF2WkhWc1pTSXNJbVJsWm1GMWJIUWlMQ0puWlhSRmJHVnRaVzUwUW5sSlpDSXNJbVZzWlcxbGJuUkpaQ0lzSW1Wc1pXMWxiblFpTENKa2IyTjFiV1Z1ZENJc0ltRnpjMlZ5ZEVselNXNXpkR0Z1WTJWUFppSXNJa2hVVFV4RmJHVnRaVzUwSWl3aVoyVjBVMnh2ZENJc0luZHBkR2hwYmlJc0luTnNiM1JPWVcxbElpd2ljMnh2ZEhNaUxDSnhkV1Z5ZVZObGJHVmpkRzl5UVd4c0lpd2lZWE56WlhKMElpd2laWEYxWVd3aUxDSnNaVzVuZEdnaUxDSnpaWFJUYkc5MFZHVjRkQ0lzSW5Oc2IzUlVaWGgwSWl3aWRHVjRkQ0lzSWs5aWFtVmpkQ0lzSW1WdWRISnBaWE1pTENKMFpYaDBRMjl1ZEdWdWRDSXNJbU5zYjI1bFZHVnRjR3hoZEdVaUxDSjBaVzF3YkdGMFpTSXNJa2hVVFV4VVpXMXdiR0YwWlVWc1pXMWxiblFpTENKa2IyTjFiV1Z1ZEVaeVlXZHRaVzUwSWl3aVkyOXVkR1Z1ZENJc0ltTnNiMjVsVG05a1pTSXNJa1J2WTNWdFpXNTBSbkpoWjIxbGJuUWlMQ0psYkdWdFpXNTBWMmwwYUVGaWMyOXNkWFJsVUdGMGFITWlMQ0ptY21GbmJXVnVkQ0lzSW1GMGRISnBZblYwWlNJc0ltVnNaVzFsYm5Seklpd2lRWEp5WVhraUxDSm1jbTl0SWl3aWNHRjBhQ0lzSW1kbGRFRjBkSEpwWW5WMFpTSXNJbUZ6YzJWeWRFbHpSR1ZtYVc1bFpDSXNJbk5sZEVGMGRISnBZblYwWlNJc0lsVlNUQ0lzSW14dlkyRjBhVzl1SWl3aWFISmxaaUlzSW1kbGRFaFVUVXdpTENKelpYSnBZV3hwZW1WeUlpd2lXRTFNVTJWeWFXRnNhWHBsY2lJc0luTmxjbWxoYkdsNlpWUnZVM1J5YVc1bklsMHNJbk52ZFhKalpYTWlPbHNpTGk0dkxpNHZMaTR2YzNKakwyaHZiV1ZpY21sa1oyVXRkV2t2Y0hWaWJHbGpMM1YwYVd4ekxXUnZiUzUwY3lKZExDSnpiM1Z5WTJWelEyOXVkR1Z1ZENJNlcyNTFiR3hkTENKdFlYQndhVzVuY3lJNklqczdPenM3T3pzN096czdRVUZIUVN4SlFVRkJRU3hQUVVGQkxFZEJRVUZETEhOQ1FVRkJMRU5CUVVGRExFOUJRVUU3UVVGRlFTeEpRVUZCUXl4TlFVRkJMRWRCUVVGRUxFOUJRVUU3UVVGQmNVVXNVMEZCUVVRc2RVSkJRVUZITEVOQlFVRXNWMEZCUVVFc1EwRkJRU3hKUVVGQlFTeERRVUZCTEVOQlFVRkRMRlZCUVVFc1IwRkJRVVFzUTBGQlFTeExRVUZCUlN4UFFVRkJMRVZCUVVGR0xFTkJRVUU3UVVGTWNrVTdRVUZEUVRzN1FVRlhRVHRCUVVOTkxGTkJRVlZITEdOQlFXTkJMRU5CUVVORExGTkJRV2xDTzBWQlF6VkRMRTFCUVUxRExFOUJRVThzUjBGQlIwTXNVVUZCVVN4RFFVRkRTQ3hqUVVGakxFTkJRVU5ETEZOQlFWTXNRMEZCUXp0RlFVTnNSQ3hKUVVGQlJ5eDVRa0ZCYTBJc1JVRkJRMFlzVDBGQlR5eEZRVUZGUnl4WFFVRlhMRU5CUVVNN1JVRkRlRU1zVDBGQlQwZ3NUMEZCVHp0QlFVTnNRanRCUVVWQk8wRkJRMDBzVTBGQlZVa3NUMEZCVDBFc1EwRkJRME1zVFVGQmQwSXNSVUZCUlVNc1VVRkJaMEk3UlVGRE9VUXNUVUZCVFVNc1MwRkJTeXhIUVVGSFJpeE5RVUZOTEVOQlFVTkhMR2RDUVVGblFpeERRVUZETEZWQlFWVkdMRkZCUVZFc1NVRkJTU3hEUVVGRE8wVkJRemRFUnl4bFFVRk5MRU5CUVVORExFdEJRVXNzUTBGQlEwZ3NTMEZCU3l4RFFVRkRTU3hOUVVGTkxFVkJRVVVzUTBGQlF5eEZRVUZGTEhkRFFVRjNRMHdzVVVGQlVTeEhRVUZITEVOQlFVTTdSVUZEYkVZc1NVRkJRVW9zZVVKQlFXdENMRVZCUVVOTExFdEJRVXNzUTBGQlF5eERRVUZETEVOQlFVTXNSVUZCUlVvc1YwRkJWeXhEUVVGRE8wVkJRM3BETEU5QlFVOUpMRXRCUVVzc1EwRkJReXhEUVVGRExFTkJRVU03UVVGRGJrSTdRVUZGUVR0QlFVTk5MRk5CUVZWTExGZEJRVmRCTEVOQlFVTlFMRTFCUVhkQ0xFVkJRVVZSTEZGQlFXZERPMFZCUTJ4R0xFdEJRVXNzVFVGQlRTeERRVUZEVUN4UlFVRlJMRVZCUVVWUkxFbEJRVWtzUTBGQlF5eEpRVUZKUXl4TlFVRk5MRU5CUVVORExFOUJRVThzUTBGQlEwZ3NVVUZCVVN4RFFVRkRMRVZCUTI1RVZDeFBRVUZQTEVOQlFVTkRMRTFCUVUwc1JVRkJSVU1zVVVGQlVTeERRVUZETEVOQlFVTlhMRmRCUVZjc1IwRkJSMGdzU1VGQlNUdEJRVU53UkR0QlFVVkJPMEZCUTAwc1UwRkJWVWtzWVVGQllVRXNRMEZCUTI1Q0xGTkJRV2xDTEVWQlFVVmpMRkZCUVdsRE8wVkJRemxGTzBWQlEwRXNUVUZCVFUwc1VVRkJVU3hIUVVGSGJFSXNVVUZCVVN4RFFVRkRTQ3hqUVVGakxFTkJRVU5ETEZOQlFWTXNRMEZCUXp0RlFVTnVSQ3hKUVVGQlJ5eDVRa0ZCYTBJc1JVRkJRMmxDTEZGQlFWRXNSVUZCUlVNc2JVSkJRVzFDTEVOQlFVTTdSVUZGYWtRN1JVRkRRU3hOUVVGTlF5eG5Ra0ZCWjBJc1IwRkJSMFlzVVVGQlVTeERRVUZEUnl4UFFVRlBMRU5CUVVORExGTkJRVk1zUTBGQlF5eEpRVUZKTEVOQlFVTTdSVUZEZWtRc1NVRkJRWEpDTEhsQ1FVRnJRaXhGUVVGRGJVSXNaMEpCUVdkQ0xFVkJRVVZITEdkQ1FVRm5RaXhEUVVGRE8wVkJRM1JFTEVsQlFVbFlMRkZCUVZFc1JVRkJSVVFzVjBGQlZ5eERRVUZEVXl4blFrRkJaMElzUlVGQlJWSXNVVUZCVVN4RFFVRkRPMFZCUTNKRUxFOUJRVTlSTEdkQ1FVRm5RanRCUVVNelFqdEJRVVZCTzBGQlEwMHNVMEZCVlVrc2QwSkJRWGRDUVN4RFFVRm5RME1zVVVGQll6dEZRVU5zUml4TFFVRkxMRTFCUVUxRExGTkJRVk1zU1VGQlNTeERRVUZETEUxQlFVMHNSVUZCUlN4TFFVRkxMRU5CUVVNc1JVRkJSVHRKUVVOeVF5eE5RVUZOUXl4UlFVRlJMRWRCUVVkR0xGRkJRVkVzUTBGQlEyeENMR2RDUVVGblFpeERRVUZETEVsQlFVbHRRaXhUUVVGVExFZEJRVWNzUTBGQlF6dEpRVU0xUkN4TFFVRkxMRTFCUVUwelFpeFBRVUZQTEVsQlFVazJRaXhMUVVGTExFTkJRVU5ETEVsQlFVa3NRMEZCUTBZc1VVRkJVU3hEUVVGRExFVkJRVVU3VFVGRGVFTXNUVUZCVFVjc1NVRkJTU3hIUVVGSEwwSXNUMEZCVHl4RFFVRkRaME1zV1VGQldTeERRVUZEVEN4VFFVRlRMRU5CUVVNN1RVRkROVU1zU1VGQlFVMHNjMEpCUVdVc1JVRkJRMFlzU1VGQlNTeERRVUZETzAxQlEzSkNMMElzVDBGQlR5eERRVUZEYTBNc1dVRkJXU3hEUVVGRFVDeFRRVUZUTEVWQlFVVXNTVUZCU1ZFc1IwRkJSeXhEUVVGRFNpeEpRVUZKTEVWQlFVVkxMRkZCUVZFc1EwRkJRME1zU1VGQlNTeERRVUZETEVOQlFVTkJMRWxCUVVrc1EwRkJRenRKUVVOMFJUdEZRVU5LTzBWQlEwRXNUMEZCVDFnc1VVRkJVVHRCUVVOdVFqdEJRVVZCTzBGQlEwMHNVMEZCVlZrc1QwRkJUMEVzUTBGQlExb3NVVUZCWXp0RlFVTnNReXhOUVVGTllTeFZRVUZWTEVkQlFVY3NTVUZCU1VNc1lVRkJZU3hGUVVGRk8wVkJRM1JETEU5QlFVOUVMRlZCUVZVc1EwRkJRMFVzYVVKQlFXbENMRU5CUVVObUxGRkJRVkVzUTBGQlF6dEJRVU5xUkNJc0ltbG5ibTl5WlV4cGMzUWlPbHRkZlE9PSIsIlwidXNlIHN0cmljdFwiO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gZXhwb3J0cy5EZWJ1Z0ZlYXR1cmVzID0gZXhwb3J0cy5Db25maWdQbHVnaW4gPSBleHBvcnRzLkNvbmZpZ0FwcGxpYW5jZXMgPSBleHBvcnRzLkFwcGxpYW5jZVByb2dyYW1PcHRpb25zID0gZXhwb3J0cy5BcHBsaWFuY2VQcm9ncmFtQ29uZmlnID0gZXhwb3J0cy5BcHBsaWFuY2VOYW1lc1ByZWZpeCA9IGV4cG9ydHMuQXBwbGlhbmNlRmVhdHVyZXMgPSBleHBvcnRzLkFwcGxpYW5jZUNvbmZpZyA9IGV4cG9ydHMuQWRkUHJvZ3JhbXNDb25maWcgPSB2b2lkIDA7XG52YXIgdCA9IF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkKHJlcXVpcmUoXCJ0cy1pbnRlcmZhY2UtY2hlY2tlclwiKSk7XG5mdW5jdGlvbiBfZ2V0UmVxdWlyZVdpbGRjYXJkQ2FjaGUoZSkgeyBpZiAoXCJmdW5jdGlvblwiICE9IHR5cGVvZiBXZWFrTWFwKSByZXR1cm4gbnVsbDsgdmFyIHIgPSBuZXcgV2Vha01hcCgpLCB0ID0gbmV3IFdlYWtNYXAoKTsgcmV0dXJuIChfZ2V0UmVxdWlyZVdpbGRjYXJkQ2FjaGUgPSBmdW5jdGlvbiAoZSkgeyByZXR1cm4gZSA/IHQgOiByOyB9KShlKTsgfVxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQoZSwgcikgeyBpZiAoIXIgJiYgZSAmJiBlLl9fZXNNb2R1bGUpIHJldHVybiBlOyBpZiAobnVsbCA9PT0gZSB8fCBcIm9iamVjdFwiICE9IHR5cGVvZiBlICYmIFwiZnVuY3Rpb25cIiAhPSB0eXBlb2YgZSkgcmV0dXJuIHsgZGVmYXVsdDogZSB9OyB2YXIgdCA9IF9nZXRSZXF1aXJlV2lsZGNhcmRDYWNoZShyKTsgaWYgKHQgJiYgdC5oYXMoZSkpIHJldHVybiB0LmdldChlKTsgdmFyIG4gPSB7IF9fcHJvdG9fXzogbnVsbCB9LCBhID0gT2JqZWN0LmRlZmluZVByb3BlcnR5ICYmIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I7IGZvciAodmFyIHUgaW4gZSkgaWYgKFwiZGVmYXVsdFwiICE9PSB1ICYmIHt9Lmhhc093blByb3BlcnR5LmNhbGwoZSwgdSkpIHsgdmFyIGkgPSBhID8gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihlLCB1KSA6IG51bGw7IGkgJiYgKGkuZ2V0IHx8IGkuc2V0KSA/IE9iamVjdC5kZWZpbmVQcm9wZXJ0eShuLCB1LCBpKSA6IG5bdV0gPSBlW3VdOyB9IHJldHVybiBuLmRlZmF1bHQgPSBlLCB0ICYmIHQuc2V0KGUsIG4pLCBuOyB9XG4vKipcbiAqIFRoaXMgbW9kdWxlIHdhcyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBieSBgdHMtaW50ZXJmYWNlLWJ1aWxkZXJgXG4gKi9cblxuLy8gdHNsaW50OmRpc2FibGU6b2JqZWN0LWxpdGVyYWwta2V5LXF1b3Rlc1xuY29uc3QgQ29uZmlnUGx1Z2luID0gZXhwb3J0cy5Db25maWdQbHVnaW4gPSB0LmlmYWNlKFtdLCB7XG4gIFwicGxhdGZvcm1cIjogXCJzdHJpbmdcIixcbiAgXCJuYW1lXCI6IHQub3B0KFwic3RyaW5nXCIpLFxuICBcImNsaWVudGlkXCI6IFwic3RyaW5nXCIsXG4gIFwiY2xpZW50c2VjcmV0XCI6IHQub3B0KFwic3RyaW5nXCIpLFxuICBcInNpbXVsYXRvclwiOiB0Lm9wdChcImJvb2xlYW5cIiksXG4gIFwiY2hpbmFcIjogdC5vcHQoXCJib29sZWFuXCIpLFxuICBcImxhbmd1YWdlXCI6IHQuaWZhY2UoW10sIHtcbiAgICBcImFwaVwiOiBcInN0cmluZ1wiXG4gIH0pLFxuICBcImRlYnVnXCI6IHQub3B0KHQuYXJyYXkoXCJEZWJ1Z0ZlYXR1cmVzXCIpKVxufSk7XG5jb25zdCBEZWJ1Z0ZlYXR1cmVzID0gZXhwb3J0cy5EZWJ1Z0ZlYXR1cmVzID0gdC51bmlvbih0LmxpdCgnTG9nIEFQSSBIZWFkZXJzJyksIHQubGl0KCdMb2cgQVBJIEJvZGllcycpLCB0LmxpdCgnTG9nIEFwcGxpYW5jZSBJRHMnKSwgdC5saXQoJ0xvZyBEZWJ1ZyBhcyBJbmZvJyksIHQubGl0KCdNb2NrIEFwcGxpYW5jZXMnKSk7XG5jb25zdCBDb25maWdBcHBsaWFuY2VzID0gZXhwb3J0cy5Db25maWdBcHBsaWFuY2VzID0gdC5pZmFjZShbXSwge1xuICBbdC5pbmRleEtleV06IFwiQXBwbGlhbmNlQ29uZmlnXCJcbn0pO1xuY29uc3QgQWRkUHJvZ3JhbXNDb25maWcgPSBleHBvcnRzLkFkZFByb2dyYW1zQ29uZmlnID0gdC51bmlvbih0LmxpdCgnbm9uZScpLCB0LmxpdCgnYXV0bycpLCB0LmxpdCgnY3VzdG9tJykpO1xuY29uc3QgQXBwbGlhbmNlQ29uZmlnID0gZXhwb3J0cy5BcHBsaWFuY2VDb25maWcgPSB0LmlmYWNlKFtdLCB7XG4gIFwiZW5hYmxlZFwiOiB0Lm9wdChcImJvb2xlYW5cIiksXG4gIFwibmFtZXNcIjogdC5vcHQodC5pZmFjZShbXSwge1xuICAgIFwicHJlZml4XCI6IFwiQXBwbGlhbmNlTmFtZXNQcmVmaXhcIlxuICB9KSksXG4gIFwiZmVhdHVyZXNcIjogdC5vcHQoXCJBcHBsaWFuY2VGZWF0dXJlc1wiKSxcbiAgXCJhZGRwcm9ncmFtc1wiOiB0Lm9wdChcIkFkZFByb2dyYW1zQ29uZmlnXCIpLFxuICBcInByb2dyYW1zXCI6IHQub3B0KHQuYXJyYXkoXCJBcHBsaWFuY2VQcm9ncmFtQ29uZmlnXCIpKVxufSk7XG5jb25zdCBBcHBsaWFuY2VOYW1lc1ByZWZpeCA9IGV4cG9ydHMuQXBwbGlhbmNlTmFtZXNQcmVmaXggPSB0LmlmYWNlKFtdLCB7XG4gIFwicHJvZ3JhbXNcIjogdC5vcHQoXCJib29sZWFuXCIpLFxuICBcIm90aGVyXCI6IHQub3B0KFwiYm9vbGVhblwiKVxufSk7XG5jb25zdCBBcHBsaWFuY2VGZWF0dXJlcyA9IGV4cG9ydHMuQXBwbGlhbmNlRmVhdHVyZXMgPSB0LmlmYWNlKFtdLCB7XG4gIFt0LmluZGV4S2V5XTogXCJib29sZWFuXCJcbn0pO1xuY29uc3QgQXBwbGlhbmNlUHJvZ3JhbUNvbmZpZyA9IGV4cG9ydHMuQXBwbGlhbmNlUHJvZ3JhbUNvbmZpZyA9IHQuaWZhY2UoW10sIHtcbiAgXCJuYW1lXCI6IFwic3RyaW5nXCIsXG4gIFwia2V5XCI6IFwic3RyaW5nXCIsXG4gIFwic2VsZWN0b25seVwiOiB0Lm9wdChcImJvb2xlYW5cIiksXG4gIFwib3B0aW9uc1wiOiB0Lm9wdChcIkFwcGxpYW5jZVByb2dyYW1PcHRpb25zXCIpXG59KTtcbmNvbnN0IEFwcGxpYW5jZVByb2dyYW1PcHRpb25zID0gZXhwb3J0cy5BcHBsaWFuY2VQcm9ncmFtT3B0aW9ucyA9IHQuaWZhY2UoW10sIHtcbiAgW3QuaW5kZXhLZXldOiB0LnVuaW9uKFwic3RyaW5nXCIsIFwibnVtYmVyXCIsIFwiYm9vbGVhblwiKVxufSk7XG5jb25zdCBleHBvcnRlZFR5cGVTdWl0ZSA9IHtcbiAgQ29uZmlnUGx1Z2luLFxuICBEZWJ1Z0ZlYXR1cmVzLFxuICBDb25maWdBcHBsaWFuY2VzLFxuICBBZGRQcm9ncmFtc0NvbmZpZyxcbiAgQXBwbGlhbmNlQ29uZmlnLFxuICBBcHBsaWFuY2VOYW1lc1ByZWZpeCxcbiAgQXBwbGlhbmNlRmVhdHVyZXMsXG4gIEFwcGxpYW5jZVByb2dyYW1Db25maWcsXG4gIEFwcGxpYW5jZVByb2dyYW1PcHRpb25zXG59O1xudmFyIF9kZWZhdWx0ID0gZXhwb3J0cy5kZWZhdWx0ID0gZXhwb3J0ZWRUeXBlU3VpdGU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldD11dGYtODtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnVZVzFsY3lJNld5SjBJaXdpWDJsdWRHVnliM0JTWlhGMWFYSmxWMmxzWkdOaGNtUWlMQ0p5WlhGMWFYSmxJaXdpWDJkbGRGSmxjWFZwY21WWGFXeGtZMkZ5WkVOaFkyaGxJaXdpWlNJc0lsZGxZV3ROWVhBaUxDSnlJaXdpWDE5bGMwMXZaSFZzWlNJc0ltUmxabUYxYkhRaUxDSm9ZWE1pTENKblpYUWlMQ0p1SWl3aVgxOXdjbTkwYjE5Zklpd2lZU0lzSWs5aWFtVmpkQ0lzSW1SbFptbHVaVkJ5YjNCbGNuUjVJaXdpWjJWMFQzZHVVSEp2Y0dWeWRIbEVaWE5qY21sd2RHOXlJaXdpZFNJc0ltaGhjMDkzYmxCeWIzQmxjblI1SWl3aVkyRnNiQ0lzSW1raUxDSnpaWFFpTENKRGIyNW1hV2RRYkhWbmFXNGlMQ0psZUhCdmNuUnpJaXdpYVdaaFkyVWlMQ0p2Y0hRaUxDSmhjbkpoZVNJc0lrUmxZblZuUm1WaGRIVnlaWE1pTENKMWJtbHZiaUlzSW14cGRDSXNJa052Ym1acFowRndjR3hwWVc1alpYTWlMQ0pwYm1SbGVFdGxlU0lzSWtGa1pGQnliMmR5WVcxelEyOXVabWxuSWl3aVFYQndiR2xoYm1ObFEyOXVabWxuSWl3aVFYQndiR2xoYm1ObFRtRnRaWE5RY21WbWFYZ2lMQ0pCY0hCc2FXRnVZMlZHWldGMGRYSmxjeUlzSWtGd2NHeHBZVzVqWlZCeWIyZHlZVzFEYjI1bWFXY2lMQ0pCY0hCc2FXRnVZMlZRY205bmNtRnRUM0IwYVc5dWN5SXNJbVY0Y0c5eWRHVmtWSGx3WlZOMWFYUmxJaXdpWDJSbFptRjFiSFFpWFN3aWMyOTFjbU5sY3lJNld5SXVMaTh1TGk5emNtTXZkR2t2WTI5dVptbG5MWFI1Y0dWekxYUnBMblJ6SWwwc0luTnZkWEpqWlhORGIyNTBaVzUwSWpwYmJuVnNiRjBzSW0xaGNIQnBibWR6SWpvaU96czdPenM3UVVGSFFTeEpRVUZCUVN4RFFVRkJMRWRCUVVGRExIVkNRVUZCTEVOQlFVRkRMRTlCUVVFN1FVRkJNRU1zVTBGQlFVTXNlVUpCUVVGRExFTkJRVUVzTmtKQlFVRkRMRTlCUVVFc2JVSkJRVUZETEVOQlFVRXNUMEZCUVVRc1QwRkJRU3hKUVVGQlRDeERRVUZCTEU5QlFVRkxMRTlCUVVFc1dVRkJRVVlzZDBKQlFVRXNXVUZCUVVFc1EwRkJRVU1zUTBGQlFTeFhRVUZCUVN4RFFVRkJMRWRCUVVGS0xFTkJRVUVzUjBGQlFVMHNRMEZCUVN4TFFVRkJSaXhEUVVGQk8wRkJRVUVzVTBGQlFVZ3NkMEpCUVVGSExFTkJRVUVzUlVGQlFVVXNRMEZCUVN4VFFVRkJRU3hEUVVGQkxFbEJRVUZHTEVOQlFVRXNTVUZCUVVFc1EwRkJRU3hEUVVGQlJ5eFZRVUZCTEZOQlFVRklMRU5CUVVFc1pVRkJRVUVzUTBGQlFTeDFRa0ZCUVVFc1EwRkJRU3g1UWtGQlFVRXNRMEZCUVN4WFFVRkJTU3hQUVVGQkxFVkJRVUZLTEVOQlFVRXNVVUZCUVVvc1EwRkJRU3hIUVVGQlJ5eDNRa0ZCUVN4RFFVRkJSeXhEUVVGQkxFOUJRVUZPTEVOQlFVRXNTVUZCUVVFc1EwRkJRU3hEUVVGQlV5eEhRVUZCTEVOQlFVRk1MRU5CUVVFc1ZVRkJRVW9zUTBGQlFTeERRVUZCVlN4SFFVRkJMRU5CUVVGT0xFTkJRVUVzVDBGQlFVOHNRMEZCUVN4TFFVRkJReXhUUVVGQkxGVkJRVUZETEVOQlFVRXNSMEZCUVVNc1RVRkJRU3hEUVVGQlF5eGpRVUZCTEVsQlFVRkVMRTFCUVVFc1EwRkJRVVVzZDBKQlFVRXNWMEZCUVVNc1EwRkJRU3hKUVVGQllpeERRVUZCTEc5Q1FVRkJZU3hEUVVGQkxFOUJRVUZETEdOQlFVRXNRMEZCUVVNc1NVRkJRU3hEUVVGQlppeERRVUZCTEVWQlFVRmhMRU5CUVVFc1UwRkJRVWNzUTBGQlFTeEhRVUZCVUN4RFFVRkJMRWRCUVVGRExFMUJRVUVzUTBGQlFVVXNkMEpCUVVFc1EwRkJRVm9zUTBGQlFTeEZRVUZCWVN4RFFVRkJMRlZCUVVGSExFTkJRVUVzUzBGQlFVRXNRMEZCUVN4RFFVRkJWaXhIUVVGQkxFbEJRVUZWTEVOQlFVRXNRMEZCUVVNc1IwRkJRU3hKUVVGQlVDeE5RVUZCTEVOQlFVRkRMR05CUVVFc1EwRkJRVW9zUTBGQlFTeEZRVUZCVFN4RFFVRkJMRVZCUVVGSExFTkJRVUVzU1VGQlFWUXNRMEZCUVN4RFFVRkJUU3hEUVVGQkxFbEJRVUZpTEVOQlFVRXNRMEZCUVdFc1EwRkJRU3haUVVGQlRpeERRVUZCTEVOQlFVRklMRTlCUVVFc1IwRkJRVW9zUTBGQlFTeEZRVUZCU2l4RFFVRkJMRWxCUVVGQkxFTkJRVUVzUTBGQlFYRkNMRWRCUVVFc1EwRkJRV3BDTEVOQlFVRXNSVUZCUVU4c1EwRkJRU3hIUVVGQlFTeERRVUZCTzBGQlNERkRPenM3TzBGQlNVRTdRVUZGVHl4TlFVRk5WeXhaUVVGWkxFZEJRVUZETEU5QlFVRXNRMEZCUVVRc1dVRkJRU3hIUVVGSGRFSXNRMEZCUXl4RFFVRkRkMElzUzBGQlN5eERRVUZETEVWQlFVVXNSVUZCUlR0RlFVTjBReXhWUVVGVkxFVkJRVVVzVVVGQlVUdEZRVU53UWl4TlFVRk5MRVZCUVVWNFFpeERRVUZETEVOQlFVTjVRaXhIUVVGSExFTkJRVU1zVVVGQlVTeERRVUZETzBWQlEzWkNMRlZCUVZVc1JVRkJSU3hSUVVGUk8wVkJRM0JDTEdOQlFXTXNSVUZCUlhwQ0xFTkJRVU1zUTBGQlEzbENMRWRCUVVjc1EwRkJReXhSUVVGUkxFTkJRVU03UlVGREwwSXNWMEZCVnl4RlFVRkZla0lzUTBGQlF5eERRVUZEZVVJc1IwRkJSeXhEUVVGRExGTkJRVk1zUTBGQlF6dEZRVU0zUWl4UFFVRlBMRVZCUVVWNlFpeERRVUZETEVOQlFVTjVRaXhIUVVGSExFTkJRVU1zVTBGQlV5eERRVUZETzBWQlEzcENMRlZCUVZVc1JVRkJSWHBDTEVOQlFVTXNRMEZCUTNkQ0xFdEJRVXNzUTBGQlF5eEZRVUZGTEVWQlFVVTdTVUZEZEVJc1MwRkJTeXhGUVVGRk8wZEJRMUlzUTBGQlF6dEZRVU5HTEU5QlFVOHNSVUZCUlhoQ0xFTkJRVU1zUTBGQlEzbENMRWRCUVVjc1EwRkJRM3BDTEVOQlFVTXNRMEZCUXpCQ0xFdEJRVXNzUTBGQlF5eGxRVUZsTEVOQlFVTTdRMEZEZUVNc1EwRkJRenRCUVVWTExFMUJRVTFETEdGQlFXRXNSMEZCUVVvc1QwRkJRU3hEUVVGQlNTeGhRVUZCTEVkQlFVY3pRaXhEUVVGRExFTkJRVU0wUWl4TFFVRkxMRU5CUVVNMVFpeERRVUZETEVOQlFVTTJRaXhIUVVGSExFTkJRVU1zYVVKQlFXbENMRU5CUVVNc1JVRkJSVGRDTEVOQlFVTXNRMEZCUXpaQ0xFZEJRVWNzUTBGQlF5eG5Ra0ZCWjBJc1EwRkJReXhGUVVGRk4wSXNRMEZCUXl4RFFVRkROa0lzUjBGQlJ5eERRVUZETEcxQ1FVRnRRaXhEUVVGRExFVkJRVVUzUWl4RFFVRkRMRU5CUVVNMlFpeEhRVUZITEVOQlFVTXNiVUpCUVcxQ0xFTkJRVU1zUlVGQlJUZENMRU5CUVVNc1EwRkJRelpDTEVkQlFVY3NRMEZCUXl4cFFrRkJhVUlzUTBGQlF5eERRVUZETzBGQlJXeExMRTFCUVUxRExHZENRVUZuUWl4SFFVRkJVQ3hQUVVGQkxFTkJRVUZQTEdkQ1FVRkJMRWRCUVVjNVFpeERRVUZETEVOQlFVTjNRaXhMUVVGTExFTkJRVU1zUlVGQlJTeEZRVUZGTzBWQlF6RkRMRU5CUVVONFFpeERRVUZETEVOQlFVTXJRaXhSUVVGUkxFZEJRVWM3UTBGRFppeERRVUZETzBGQlJVc3NUVUZCVFVNc2FVSkJRV2xDTEVkQlFVRlVMRTlCUVVFc1EwRkJRVk1zYVVKQlFVRXNSMEZCUjJoRExFTkJRVU1zUTBGQlF6UkNMRXRCUVVzc1EwRkJRelZDTEVOQlFVTXNRMEZCUXpaQ0xFZEJRVWNzUTBGQlF5eE5RVUZOTEVOQlFVTXNSVUZCUlRkQ0xFTkJRVU1zUTBGQlF6WkNMRWRCUVVjc1EwRkJReXhOUVVGTkxFTkJRVU1zUlVGQlJUZENMRU5CUVVNc1EwRkJRelpDTEVkQlFVY3NRMEZCUXl4UlFVRlJMRU5CUVVNc1EwRkJRenRCUVVWb1JpeE5RVUZOU1N4bFFVRmxMRWRCUVVGV0xFOUJRVUVzUTBGQlFWVXNaVUZCUVN4SFFVRkhha01zUTBGQlF5eERRVUZEZDBJc1MwRkJTeXhEUVVGRExFVkJRVVVzUlVGQlJUdEZRVU42UXl4VFFVRlRMRVZCUVVWNFFpeERRVUZETEVOQlFVTjVRaXhIUVVGSExFTkJRVU1zVTBGQlV5eERRVUZETzBWQlF6TkNMRTlCUVU4c1JVRkJSWHBDTEVOQlFVTXNRMEZCUTNsQ0xFZEJRVWNzUTBGQlEzcENMRU5CUVVNc1EwRkJRM2RDTEV0QlFVc3NRMEZCUXl4RlFVRkZMRVZCUVVVN1NVRkRla0lzVVVGQlVTeEZRVUZGTzBkQlExZ3NRMEZCUXl4RFFVRkRPMFZCUTBnc1ZVRkJWU3hGUVVGRmVFSXNRMEZCUXl4RFFVRkRlVUlzUjBGQlJ5eERRVUZETEcxQ1FVRnRRaXhEUVVGRE8wVkJRM1JETEdGQlFXRXNSVUZCUlhwQ0xFTkJRVU1zUTBGQlEzbENMRWRCUVVjc1EwRkJReXh0UWtGQmJVSXNRMEZCUXp0RlFVTjZReXhWUVVGVkxFVkJRVVY2UWl4RFFVRkRMRU5CUVVONVFpeEhRVUZITEVOQlFVTjZRaXhEUVVGRExFTkJRVU13UWl4TFFVRkxMRU5CUVVNc2QwSkJRWGRDTEVOQlFVTTdRMEZEY0VRc1EwRkJRenRCUVVWTExFMUJRVTFSTEc5Q1FVRnZRaXhIUVVGQldDeFBRVUZCTEVOQlFVRlhMRzlDUVVGQkxFZEJRVWRzUXl4RFFVRkRMRU5CUVVOM1FpeExRVUZMTEVOQlFVTXNSVUZCUlN4RlFVRkZPMFZCUXpsRExGVkJRVlVzUlVGQlJYaENMRU5CUVVNc1EwRkJRM2xDTEVkQlFVY3NRMEZCUXl4VFFVRlRMRU5CUVVNN1JVRkROVUlzVDBGQlR5eEZRVUZGZWtJc1EwRkJReXhEUVVGRGVVSXNSMEZCUnl4RFFVRkRMRk5CUVZNN1EwRkRla0lzUTBGQlF6dEJRVVZMTEUxQlFVMVZMR2xDUVVGcFFpeEhRVUZCV2l4UFFVRkJMRU5CUVVGWkxHbENRVUZCTEVkQlFVZHVReXhEUVVGRExFTkJRVU4zUWl4TFFVRkxMRU5CUVVNc1JVRkJSU3hGUVVGRk8wVkJRek5ETEVOQlFVTjRRaXhEUVVGRExFTkJRVU1yUWl4UlFVRlJMRWRCUVVjN1EwRkRaaXhEUVVGRE8wRkJSVXNzVFVGQlRVc3NjMEpCUVhOQ0xFZEJRVUZpTEU5QlFVRXNRMEZCUVdFc2MwSkJRVUVzUjBGQlIzQkRMRU5CUVVNc1EwRkJRM2RDTEV0QlFVc3NRMEZCUXl4RlFVRkZMRVZCUVVVN1JVRkRhRVFzVFVGQlRTeEZRVUZGTEZGQlFWRTdSVUZEYUVJc1MwRkJTeXhGUVVGRkxGRkJRVkU3UlVGRFppeFpRVUZaTEVWQlFVVjRRaXhEUVVGRExFTkJRVU41UWl4SFFVRkhMRU5CUVVNc1UwRkJVeXhEUVVGRE8wVkJRemxDTEZOQlFWTXNSVUZCUlhwQ0xFTkJRVU1zUTBGQlEzbENMRWRCUVVjc1EwRkJReXg1UWtGQmVVSTdRMEZETTBNc1EwRkJRenRCUVVWTExFMUJRVTFaTEhWQ1FVRjFRaXhIUVVGQlpDeFBRVUZCTEVOQlFVRmpMSFZDUVVGQkxFZEJRVWR5UXl4RFFVRkRMRU5CUVVOM1FpeExRVUZMTEVOQlFVTXNSVUZCUlN4RlFVRkZPMFZCUTJwRUxFTkJRVU40UWl4RFFVRkRMRU5CUVVNclFpeFJRVUZSTEVkQlFVY3ZRaXhEUVVGRExFTkJRVU0wUWl4TFFVRkxMRU5CUVVNc1VVRkJVU3hGUVVGRkxGRkJRVkVzUlVGQlJTeFRRVUZUTzBOQlEzQkVMRU5CUVVNN1FVRkZSaXhOUVVGTlZTeHBRa0ZCYVVJc1IwRkJhVUk3UlVGRGRFTm9RaXhaUVVGWk8wVkJRMXBMTEdGQlFXRTdSVUZEWWtjc1owSkJRV2RDTzBWQlEyaENSU3hwUWtGQmFVSTdSVUZEYWtKRExHVkJRV1U3UlVGRFprTXNiMEpCUVc5Q08wVkJRM0JDUXl4cFFrRkJhVUk3UlVGRGFrSkRMSE5DUVVGelFqdEZRVU4wUWtNN1EwRkRSRHRCUVVGRExFbEJRVUZGTEZGQlFVRXNSMEZCUVdoQ0xFOUJRVUVzUTBGQlFXWXNUMEZCUVN4SFFVTmhPRUlzYVVKQlFXbENJaXdpYVdkdWIzSmxUR2x6ZENJNlcxMTkiLCJcInVzZSBzdHJpY3RcIjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMudHlwZVN1aXRlID0gZXhwb3J0cy5kZWZhdWx0ID0gZXhwb3J0cy5jaGVja2VycyA9IHZvaWQgMDtcbnZhciBfdHNJbnRlcmZhY2VDaGVja2VyID0gcmVxdWlyZShcInRzLWludGVyZmFjZS1jaGVja2VyXCIpO1xudmFyIF9jb25maWdUeXBlc1RpID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiLi9jb25maWctdHlwZXMtdGkuanNcIikpO1xuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChlKSB7IHJldHVybiBlICYmIGUuX19lc01vZHVsZSA/IGUgOiB7IGRlZmF1bHQ6IGUgfTsgfVxuLy8gVGhpcyBtb2R1bGUgd2FzIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IG5vZGUgdHMtaW50ZXJmYWNlLXBvc3QudHNcbi8vIDIwMjUtMDEtMDhUMTY6MTE6MzEuNTE4WlxuXG4vLyBUeXBlIGRlZmluaXRpb25zXG5jb25zdCB0eXBlU3VpdGUgPSBleHBvcnRzLnR5cGVTdWl0ZSA9IF9jb25maWdUeXBlc1RpLmRlZmF1bHQ7XG4vLyBDaGVja2Vyc1xuY29uc3QgY2hlY2tlcnMgPSBleHBvcnRzLmNoZWNrZXJzID0gKDAsIF90c0ludGVyZmFjZUNoZWNrZXIuY3JlYXRlQ2hlY2tlcnMpKF9jb25maWdUeXBlc1RpLmRlZmF1bHQpO1xuLy8gRXhwb3J0IHRoZSBjaGVja2VycyBieSBkZWZhdWx0XG52YXIgX2RlZmF1bHQgPSBleHBvcnRzLmRlZmF1bHQgPSBjaGVja2Vycztcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRhdGE6YXBwbGljYXRpb24vanNvbjtjaGFyc2V0PXV0Zi04O2Jhc2U2NCxleUoyWlhKemFXOXVJam96TENKdVlXMWxjeUk2V3lKZmRITkpiblJsY21aaFkyVkRhR1ZqYTJWeUlpd2ljbVZ4ZFdseVpTSXNJbDlqYjI1bWFXZFVlWEJsYzFScElpd2lYMmx1ZEdWeWIzQlNaWEYxYVhKbFJHVm1ZWFZzZENJc0ltVWlMQ0pmWDJWelRXOWtkV3hsSWl3aVpHVm1ZWFZzZENJc0luUjVjR1ZUZFdsMFpTSXNJbVY0Y0c5eWRITWlMQ0psZUhCdmNuUmxaRlI1Y0dWVGRXbDBaU0lzSW1Ob1pXTnJaWEp6SWl3aVkzSmxZWFJsUTJobFkydGxjbk1pTENKZlpHVm1ZWFZzZENKZExDSnpiM1Z5WTJWeklqcGJJaTR1THk0dUwzTnlZeTkwYVM5amIyNW1hV2N0ZEhsd1pYTXVkSE1pWFN3aWMyOTFjbU5sYzBOdmJuUmxiblFpT2x0dWRXeHNYU3dpYldGd2NHbHVaM01pT2lJN096czdPenRCUVVkQkxFbEJRVUZCTEcxQ1FVRkJMRWRCUVVGRExFOUJRVUU3UVVGRlFTeEpRVUZCUXl4alFVRkJMRWRCUVVGRExITkNRVUZCTEVOQlFVRkdMRTlCUVVFN1FVRkJjVVFzVTBGQlFVVXNkVUpCUVVGRExFTkJRVUVzVjBGQlFVRXNRMEZCUVN4SlFVRkJRU3hEUVVGQkxFTkJRVUZETEZWQlFVRXNSMEZCUVVRc1EwRkJRU3hMUVVGQlJTeFBRVUZCTEVWQlFVRkdMRU5CUVVFN1FVRk1ja1E3UVVGRFFUczdRVUZ0UWtFN1FVRkRUeXhOUVVGTlJ5eFRRVUZUTEVkQlFVRkRMRTlCUVVFc1EwRkJRVVFzVTBGQlFTeEhRVUZIUlN4elFrRlZlRUk3UVVGRlJEdEJRVU5QTEUxQlFVMURMRkZCUVZFc1IwRkJRVVlzVDBGQlFTeERRVUZCUlN4UlFVRkJMRWRCUVVjc1NVRkJRVU1zYTBOQlFXTXNSVUZCUTBZc2MwSkJRV2xDTEVOQlZYWkVPMEZCUlVRN1FVRkJRU3hKUVVGQlJ5eFJRVUZCTEVkQlFVRktMRTlCUVVFc1EwRkJRVVlzVDBGQlFTeEhRVU5sU1N4UlFVRlJJaXdpYVdkdWIzSmxUR2x6ZENJNlcxMTkiLCJcInVzZSBzdHJpY3RcIjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuTVMgPSB2b2lkIDA7XG5leHBvcnRzLmFzc2VydElzQm9vbGVhbiA9IGFzc2VydElzQm9vbGVhbjtcbmV4cG9ydHMuYXNzZXJ0SXNEZWZpbmVkID0gYXNzZXJ0SXNEZWZpbmVkO1xuZXhwb3J0cy5hc3NlcnRJc0luc3RhbmNlT2YgPSBhc3NlcnRJc0luc3RhbmNlT2Y7XG5leHBvcnRzLmFzc2VydElzTnVtYmVyID0gYXNzZXJ0SXNOdW1iZXI7XG5leHBvcnRzLmFzc2VydElzU3RyaW5nID0gYXNzZXJ0SXNTdHJpbmc7XG5leHBvcnRzLmFzc2VydElzVW5kZWZpbmVkID0gYXNzZXJ0SXNVbmRlZmluZWQ7XG5leHBvcnRzLmNvbHVtbnMgPSBjb2x1bW5zO1xuZXhwb3J0cy5kZWVwTWVyZ2UgPSBkZWVwTWVyZ2U7XG5leHBvcnRzLmZvcm1hdExpc3QgPSBmb3JtYXRMaXN0O1xuZXhwb3J0cy5mb3JtYXRNaWxsaXNlY29uZHMgPSBmb3JtYXRNaWxsaXNlY29uZHM7XG5leHBvcnRzLmZvcm1hdFNlY29uZHMgPSBmb3JtYXRTZWNvbmRzO1xuZXhwb3J0cy5nZXRWYWxpZGF0aW9uVHJlZSA9IGdldFZhbGlkYXRpb25UcmVlO1xuZXhwb3J0cy5rZXlvZkNoZWNrZXIgPSBrZXlvZkNoZWNrZXI7XG5leHBvcnRzLnBsdXJhbCA9IHBsdXJhbDtcbnZhciBfYXNzZXJ0ID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiYXNzZXJ0XCIpKTtcbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoZSkgeyByZXR1cm4gZSAmJiBlLl9fZXNNb2R1bGUgPyBlIDogeyBkZWZhdWx0OiBlIH07IH1cbi8vIEhvbWVicmlkZ2UgcGx1Z2luIGZvciBIb21lIENvbm5lY3QgaG9tZSBhcHBsaWFuY2VzXG4vLyBDb3B5cmlnaHQgwqkgMjAyMyBBbGV4YW5kZXIgVGhvdWt5ZGlkZXNcblxuLy8gTWlsbGlzZWNvbmRzIGluIGEgc2Vjb25kXG5jb25zdCBNUyA9IGV4cG9ydHMuTVMgPSAxMDAwO1xuLy8gVHlwZSBhc3NlcnRpb25zXG5mdW5jdGlvbiBhc3NlcnRJc0RlZmluZWQodmFsdWUpIHtcbiAgX2Fzc2VydC5kZWZhdWx0Lm5vdFN0cmljdEVxdWFsKHZhbHVlLCB1bmRlZmluZWQpO1xuICBfYXNzZXJ0LmRlZmF1bHQubm90U3RyaWN0RXF1YWwodmFsdWUsIG51bGwpO1xufVxuZnVuY3Rpb24gYXNzZXJ0SXNVbmRlZmluZWQodmFsdWUpIHtcbiAgX2Fzc2VydC5kZWZhdWx0LnN0cmljdEVxdWFsKHZhbHVlLCB1bmRlZmluZWQpO1xufVxuZnVuY3Rpb24gYXNzZXJ0SXNTdHJpbmcodmFsdWUpIHtcbiAgX2Fzc2VydC5kZWZhdWx0LnN0cmljdEVxdWFsKHR5cGVvZiB2YWx1ZSwgJ3N0cmluZycpO1xufVxuZnVuY3Rpb24gYXNzZXJ0SXNOdW1iZXIodmFsdWUpIHtcbiAgX2Fzc2VydC5kZWZhdWx0LnN0cmljdEVxdWFsKHR5cGVvZiB2YWx1ZSwgJ251bWJlcicpO1xufVxuZnVuY3Rpb24gYXNzZXJ0SXNCb29sZWFuKHZhbHVlKSB7XG4gIF9hc3NlcnQuZGVmYXVsdC5zdHJpY3RFcXVhbCh0eXBlb2YgdmFsdWUsICdib29sZWFuJyk7XG59XG5mdW5jdGlvbiBhc3NlcnRJc0luc3RhbmNlT2YodmFsdWUsIHR5cGUpIHtcbiAgKDAsIF9hc3NlcnQuZGVmYXVsdCkodmFsdWUgaW5zdGFuY2VvZiB0eXBlLCBgTm90IGFuIGluc3RhbmNlIG9mICR7dHlwZS5uYW1lfWApO1xufVxuLy8gRm9ybWF0IGEgbWlsbGlzZWNvbmRzIGR1cmF0aW9uXG5mdW5jdGlvbiBmb3JtYXRNaWxsaXNlY29uZHMobXMsIG1heFBhcnRzID0gMikge1xuICBpZiAobXMgPCAxKSByZXR1cm4gJ24vYSc7XG4gIC8vIFNwbGl0IHRoZSBkdXJhdGlvbiBpbnRvIGNvbXBvbmVudHNcbiAgY29uc3QgZHVyYXRpb24gPSBbWydkYXknLCBNYXRoLmZsb29yKG1zIC8gKDI0ICogNjAgKiA2MCAqIE1TKSldLCBbJ2hvdXInLCBNYXRoLmZsb29yKG1zIC8gKDYwICogNjAgKiBNUykpICUgMjRdLCBbJ21pbnV0ZScsIE1hdGguZmxvb3IobXMgLyAoNjAgKiBNUykpICUgNjBdLCBbJ3NlY29uZCcsIE1hdGguZmxvb3IobXMgLyBNUykgJSA2MF0sIFsnbWlsbGlzZWNvbmQnLCBNYXRoLmZsb29yKG1zKSAlIE1TXV07XG4gIC8vIFJlbW92ZSBhbnkgbGVhZGluZyB6ZXJvIGNvbXBvbmVudHNcbiAgd2hpbGUgKGR1cmF0aW9uWzBdPy5bMV0gPT09IDApIGR1cmF0aW9uLnNoaWZ0KCk7XG4gIC8vIENvbWJpbmUgdGhlIHJlcXVpcmVkIG51bWJlciBvZiByZW1haW5pbmcgY29tcG9uZW50c1xuICByZXR1cm4gZHVyYXRpb24uc2xpY2UoMCwgbWF4UGFydHMpLmZpbHRlcigoW19rZXksIHZhbHVlXSkgPT4gdmFsdWUgIT09IDApLm1hcCgoW2tleSwgdmFsdWVdKSA9PiBwbHVyYWwodmFsdWUsIGtleSkpLmpvaW4oJyAnKTtcbn1cbi8vIEZvcm1hdCBhIHNlY29uZHMgZHVyYXRpb25cbmZ1bmN0aW9uIGZvcm1hdFNlY29uZHMoc2Vjb25kcywgbWF4UGFydHMgPSAyKSB7XG4gIHJldHVybiBmb3JtYXRNaWxsaXNlY29uZHMoc2Vjb25kcyAqIDEwMDAsIG1heFBhcnRzKTtcbn1cbi8vIEZvcm1hdCBhIGxpc3QgKHdpdGggT3hmb3JkIGNvbW1hKVxuZnVuY3Rpb24gZm9ybWF0TGlzdChpdGVtcykge1xuICBzd2l0Y2ggKGl0ZW1zLmxlbmd0aCkge1xuICAgIGNhc2UgMDpcbiAgICAgIHJldHVybiAnbi9hJztcbiAgICBjYXNlIDE6XG4gICAgICByZXR1cm4gaXRlbXNbMF0gPz8gJyc7XG4gICAgY2FzZSAyOlxuICAgICAgcmV0dXJuIGAke2l0ZW1zWzBdfSBhbmQgJHtpdGVtc1sxXX1gO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gWy4uLml0ZW1zLnNsaWNlKDAsIC0xKSwgYGFuZCAke2l0ZW1zW2l0ZW1zLmxlbmd0aCAtIDFdfWBdLmpvaW4oJywgJyk7XG4gIH1cbn1cbi8vIEZvcm1hdCBhIGNvdW50ZWQgbm91biAoaGFuZGxpbmcgbW9zdCByZWd1bGFyIGNhc2VzIGF1dG9tYXRpY2FsbHkpXG5mdW5jdGlvbiBwbHVyYWwoY291bnQsIG5vdW4sIHNob3dDb3VudCA9IHRydWUpIHtcbiAgY29uc3QgW3Npbmd1bGFyLCBwbHVyYWxdID0gQXJyYXkuaXNBcnJheShub3VuKSA/IG5vdW4gOiBbbm91biwgJyddO1xuICBub3VuID0gY291bnQgPT09IDEgPyBzaW5ndWxhciA6IHBsdXJhbDtcbiAgaWYgKCFub3VuKSB7XG4gICAgLy8gQXBwbHkgcmVndWxhciBydWxlc1xuICAgIGNvbnN0IHJ1bGVzID0gW1snb24kJywgJ2EnLCAyXSxcbiAgICAvLyBwaGVub21lbm9uL3BoZW5vbWVuYSBjcml0ZXJpb24vY3JpdGVyaWFcbiAgICBbJ3VzJCcsICdpJywgMV0sXG4gICAgLy8gICAgIGNhY3R1cy9jYWN0aSAgICAgICAgIGZvY3VzL2ZvY2lcbiAgICBbJ1teYWVpb3VdeSQnLCAnaWVzJywgMV0sXG4gICAgLy8gICAgICAgIGN0eS9jaXRlcyAgICAgICAgIHB1cHB5L3B1cHBpZXNcbiAgICBbJyhjaHxpc3xvfHN8c2h8eHx6KSQnLCAnZXMnLCAwXSxcbiAgICAvLyAgICAgICBpcmlzL2lyaXNlcyAgICAgICAgdHJ1c3MvdHJ1c3Nlc1xuICAgIFsnJywgJ3MnLCAwXSAvLyAgICAgICAgY2F0L2NhdHMgICAgICAgICAgaG91c2UvaG91c2VzXG4gICAgXTtcbiAgICBjb25zdCBydWxlID0gcnVsZXMuZmluZCgoW2VuZGluZ10pID0+IG5ldyBSZWdFeHAoZW5kaW5nLCAnaScpLnRlc3Qoc2luZ3VsYXIpKTtcbiAgICBhc3NlcnRJc0RlZmluZWQocnVsZSk7XG4gICAgY29uc3QgbWF0Y2hDYXNlID0gcyA9PiBzaW5ndWxhciA9PT0gc2luZ3VsYXIudG9VcHBlckNhc2UoKSA/IHMudG9VcHBlckNhc2UoKSA6IHM7XG4gICAgbm91biA9IHNpbmd1bGFyLnN1YnN0cmluZygwLCBzaW5ndWxhci5sZW5ndGggLSBydWxlWzJdKS5jb25jYXQobWF0Y2hDYXNlKHJ1bGVbMV0pKTtcbiAgfVxuICByZXR1cm4gc2hvd0NvdW50ID8gYCR7Y291bnR9ICR7bm91bn1gIDogbm91bjtcbn1cbi8vIEZvcm1hdCBzdHJpbmdzIGluIGNvbHVtbnNcbmZ1bmN0aW9uIGNvbHVtbnMocm93cywgc2VwYXJhdG9yID0gJyAgJykge1xuICAvLyBEZXRlcm1pbmUgdGhlIHJlcXVpcmVkIGNvbHVtbiB3aWR0aHNcbiAgY29uc3Qgd2lkdGggPSBbXTtcbiAgcm93cy5mb3JFYWNoKHJvdyA9PiB7XG4gICAgcm93LmZvckVhY2goKHZhbHVlLCBpbmRleCkgPT4ge1xuICAgICAgd2lkdGhbaW5kZXhdID0gTWF0aC5tYXgod2lkdGhbaW5kZXhdID8/IDAsIHZhbHVlLmxlbmd0aCk7XG4gICAgfSk7XG4gIH0pO1xuICB3aWR0aC5zcGxpY2UoLTEsIDEsIDApO1xuICAvLyBGb3JtYXQgdGhlIHJvd3NcbiAgcmV0dXJuIHJvd3MubWFwKHJvdyA9PiByb3cubWFwKCh2YWx1ZSwgaW5kZXgpID0+IHZhbHVlLnBhZEVuZCh3aWR0aFtpbmRleF0gPz8gMCkpLmpvaW4oc2VwYXJhdG9yKSk7XG59XG4vLyBSZWN1cnNpdmUgb2JqZWN0IGFzc2lnbm1lbnQsIHNraXBwaW5nIHVuZGVmaW5lZCB2YWx1ZXNcbmZ1bmN0aW9uIGRlZXBNZXJnZSguLi5vYmplY3RzKSB7XG4gIGNvbnN0IGlzT2JqZWN0ID0gdmFsdWUgPT4gdmFsdWUgIT09IHVuZGVmaW5lZCAmJiB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmICFBcnJheS5pc0FycmF5KHZhbHVlKTtcbiAgcmV0dXJuIG9iamVjdHMucmVkdWNlKChhY2MsIG9iamVjdCkgPT4ge1xuICAgIE9iamVjdC5lbnRyaWVzKG9iamVjdCkuZm9yRWFjaCgoW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgICBjb25zdCBhY2NWYWx1ZSA9IGFjY1trZXldO1xuICAgICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHJldHVybjtcbiAgICAgIGlmIChpc09iamVjdChhY2NWYWx1ZSkgJiYgaXNPYmplY3QodmFsdWUpKSBhY2Nba2V5XSA9IGRlZXBNZXJnZShhY2NWYWx1ZSwgdmFsdWUpO2Vsc2UgYWNjW2tleV0gPSB2YWx1ZTtcbiAgICB9KTtcbiAgICByZXR1cm4gYWNjO1xuICB9LCB7fSk7XG59XG4vLyBDb252ZXJ0IGNoZWNrZXIgdmFsaWRhdGlvbiBlcnJvciBpbnRvIGxpbmVzIG9mIHRleHRcbmZ1bmN0aW9uIGdldFZhbGlkYXRpb25UcmVlKGVycm9ycykge1xuICBjb25zdCBsaW5lcyA9IFtdO1xuICBlcnJvcnMuZm9yRWFjaCgoZXJyb3IsIGluZGV4KSA9PiB7XG4gICAgY29uc3QgcHJlZml4ID0gKGEsIGIpID0+IGluZGV4IDwgZXJyb3JzLmxlbmd0aCAtIDEgPyBhIDogYjtcbiAgICBsaW5lcy5wdXNoKGAke3ByZWZpeCgn4pSc4pSAICcsICfilJTilIAgJyl9JHtlcnJvci5wYXRofSAke2Vycm9yLm1lc3NhZ2V9YCk7XG4gICAgaWYgKGVycm9yLm5lc3RlZCkge1xuICAgICAgY29uc3QgbmVzdGVkID0gZ2V0VmFsaWRhdGlvblRyZWUoZXJyb3IubmVzdGVkKTtcbiAgICAgIGxpbmVzLnB1c2goLi4ubmVzdGVkLm1hcChsaW5lID0+IGAke3ByZWZpeCgn4pSCICAnLCAnICAgJyl9ICR7bGluZX1gKSk7XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIGxpbmVzO1xufVxuLy8gRXh0cmFjdCBwcm9wZXJ0eSBrZXlzIG9yIHVuaW9uIGxpdGVyYWwgZnJvbSBhIHRpLWludGVyZmFjZS1jaGVja2VyIHR5cGVcbmZ1bmN0aW9uIGtleW9mQ2hlY2tlcih0eXBlU3VpdGUsIHR5cGUpIHtcbiAgY29uc3QgY2hlY2tlciA9IHR5cGU7XG4gIC8vIFRJZmFjZVxuICBjb25zdCBwcm9wcyA9IFtdO1xuICBpZiAoY2hlY2tlci5wcm9wU2V0IGluc3RhbmNlb2YgU2V0KSB7XG4gICAgcHJvcHMucHVzaCguLi5jaGVja2VyLnByb3BTZXQpO1xuICB9XG4gIGlmIChBcnJheS5pc0FycmF5KGNoZWNrZXIuYmFzZXMpKSB7XG4gICAgZm9yIChjb25zdCBiYXNlIG9mIGNoZWNrZXIuYmFzZXMpIHtcbiAgICAgIGNvbnN0IGJhc2VUeXBlID0gdHlwZVN1aXRlW2Jhc2VdO1xuICAgICAgYXNzZXJ0SXNEZWZpbmVkKGJhc2VUeXBlKTtcbiAgICAgIHByb3BzLnB1c2goLi4ua2V5b2ZDaGVja2VyKHR5cGVTdWl0ZSwgYmFzZVR5cGUpKTtcbiAgICB9XG4gIH1cbiAgLy8gVFVuaW9uIG9yIFRJbnRlcnNlY3Rpb25cbiAgaWYgKEFycmF5LmlzQXJyYXkoY2hlY2tlci50dHlwZXMpKSB7XG4gICAgZm9yIChjb25zdCB0dHlwZSBvZiBjaGVja2VyLnR0eXBlcykgcHJvcHMucHVzaCguLi5rZXlvZkNoZWNrZXIodHlwZVN1aXRlLCB0dHlwZSkpO1xuICB9XG4gIC8vIFRFbnVtXG4gIGlmIChjaGVja2VyLnZhbGlkVmFsdWVzIGluc3RhbmNlb2YgU2V0KSB7XG4gICAgcHJvcHMucHVzaCguLi5jaGVja2VyLnZhbGlkVmFsdWVzKTtcbiAgfVxuICBpZiAodHlwZW9mIGNoZWNrZXIudmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgLy8gVExpdGVyYWxcbiAgICBwcm9wcy5wdXNoKGNoZWNrZXIudmFsdWUpO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBjaGVja2VyLm5hbWUgPT09ICdzdHJpbmcnKSB7XG4gICAgLy8gVE5hbWVcbiAgICBjb25zdCBuYW1lVHlwZSA9IHR5cGVTdWl0ZVtjaGVja2VyLm5hbWVdO1xuICAgIGFzc2VydElzRGVmaW5lZChuYW1lVHlwZSk7XG4gICAgcHJvcHMucHVzaCguLi5rZXlvZkNoZWNrZXIodHlwZVN1aXRlLCBuYW1lVHlwZSkpO1xuICB9XG4gIHJldHVybiBwcm9wcztcbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRhdGE6YXBwbGljYXRpb24vanNvbjtjaGFyc2V0PXV0Zi04O2Jhc2U2NCxleUoyWlhKemFXOXVJam96TENKdVlXMWxjeUk2V3lKZllYTnpaWEowSWl3aVgybHVkR1Z5YjNCU1pYRjFhWEpsUkdWbVlYVnNkQ0lzSW5KbGNYVnBjbVVpTENKbElpd2lYMTlsYzAxdlpIVnNaU0lzSW1SbFptRjFiSFFpTENKTlV5SXNJbVY0Y0c5eWRITWlMQ0poYzNObGNuUkpjMFJsWm1sdVpXUWlMQ0oyWVd4MVpTSXNJbUZ6YzJWeWRDSXNJbTV2ZEZOMGNtbGpkRVZ4ZFdGc0lpd2lkVzVrWldacGJtVmtJaXdpWVhOelpYSjBTWE5WYm1SbFptbHVaV1FpTENKemRISnBZM1JGY1hWaGJDSXNJbUZ6YzJWeWRFbHpVM1J5YVc1bklpd2lZWE56WlhKMFNYTk9kVzFpWlhJaUxDSmhjM05sY25SSmMwSnZiMnhsWVc0aUxDSmhjM05sY25SSmMwbHVjM1JoYm1ObFQyWWlMQ0owZVhCbElpd2libUZ0WlNJc0ltWnZjbTFoZEUxcGJHeHBjMlZqYjI1a2N5SXNJbTF6SWl3aWJXRjRVR0Z5ZEhNaUxDSmtkWEpoZEdsdmJpSXNJazFoZEdnaUxDSm1iRzl2Y2lJc0luTm9hV1owSWl3aWMyeHBZMlVpTENKbWFXeDBaWElpTENKZmEyVjVJaXdpYldGd0lpd2lhMlY1SWl3aWNHeDFjbUZzSWl3aWFtOXBiaUlzSW1admNtMWhkRk5sWTI5dVpITWlMQ0p6WldOdmJtUnpJaXdpWm05eWJXRjBUR2x6ZENJc0ltbDBaVzF6SWl3aWJHVnVaM1JvSWl3aVkyOTFiblFpTENKdWIzVnVJaXdpYzJodmQwTnZkVzUwSWl3aWMybHVaM1ZzWVhJaUxDSkJjbkpoZVNJc0ltbHpRWEp5WVhraUxDSnlkV3hsY3lJc0luSjFiR1VpTENKbWFXNWtJaXdpWlc1a2FXNW5JaXdpVW1WblJYaHdJaXdpZEdWemRDSXNJbTFoZEdOb1EyRnpaU0lzSW5NaUxDSjBiMVZ3Y0dWeVEyRnpaU0lzSW5OMVluTjBjbWx1WnlJc0ltTnZibU5oZENJc0ltTnZiSFZ0Ym5NaUxDSnliM2R6SWl3aWMyVndZWEpoZEc5eUlpd2lkMmxrZEdnaUxDSm1iM0pGWVdOb0lpd2ljbTkzSWl3aWFXNWtaWGdpTENKdFlYZ2lMQ0p6Y0d4cFkyVWlMQ0p3WVdSRmJtUWlMQ0prWldWd1RXVnlaMlVpTENKdlltcGxZM1J6SWl3aWFYTlBZbXBsWTNRaUxDSnlaV1IxWTJVaUxDSmhZMk1pTENKdlltcGxZM1FpTENKUFltcGxZM1FpTENKbGJuUnlhV1Z6SWl3aVlXTmpWbUZzZFdVaUxDSm5aWFJXWVd4cFpHRjBhVzl1VkhKbFpTSXNJbVZ5Y205eWN5SXNJbXhwYm1Weklpd2laWEp5YjNJaUxDSndjbVZtYVhnaUxDSmhJaXdpWWlJc0luQjFjMmdpTENKd1lYUm9JaXdpYldWemMyRm5aU0lzSW01bGMzUmxaQ0lzSW14cGJtVWlMQ0pyWlhsdlprTm9aV05yWlhJaUxDSjBlWEJsVTNWcGRHVWlMQ0pqYUdWamEyVnlJaXdpY0hKdmNITWlMQ0p3Y205d1UyVjBJaXdpVTJWMElpd2lZbUZ6WlhNaUxDSmlZWE5sSWl3aVltRnpaVlI1Y0dVaUxDSjBkSGx3WlhNaUxDSjBkSGx3WlNJc0luWmhiR2xrVm1Gc2RXVnpJaXdpYm1GdFpWUjVjR1VpWFN3aWMyOTFjbU5sY3lJNld5SXVMaTl6Y21NdmRYUnBiSE11ZEhNaVhTd2ljMjkxY21ObGMwTnZiblJsYm5RaU9sdHVkV3hzWFN3aWJXRndjR2x1WjNNaU9pSTdPenM3T3pzN096czdPenM3T3pzN096czdPMEZCUjBFc1NVRkJRVUVzVDBGQlFTeEhRVUZCUXl4elFrRkJRU3hEUVVGQlF5eFBRVUZCTzBGQlFUUkNMRk5CUVVGRUxIVkNRVUZCUlN4RFFVRkJMRmRCUVVGQkxFTkJRVUVzU1VGQlFVRXNRMEZCUVN4RFFVRkJReXhWUVVGQkxFZEJRVUZFTEVOQlFVRXNTMEZCUVVVc1QwRkJRU3hGUVVGQlJpeERRVUZCTzBGQlNEVkNPMEZCUTBFN08wRkJTMEU3UVVGRFR5eE5RVUZOUnl4RlFVRkZMRWRCUVVGRExFOUJRVUVzUTBGQlFVUXNSVUZCUVN4SFFVRkhMRWxCUVVrN1FVRlhkRUk3UVVGRFRTeFRRVUZWUlN4bFFVRmxRU3hEUVVGUFF5eExRVUZYTzBWQlF6ZERReXhsUVVGTkxFTkJRVU5ETEdOQlFXTXNRMEZCUTBZc1MwRkJTeXhGUVVGRlJ5eFRRVUZUTEVOQlFVTTdSVUZEZGtOR0xHVkJRVTBzUTBGQlEwTXNZMEZCWXl4RFFVRkRSaXhMUVVGTExFVkJRVVVzU1VGQlNTeERRVUZETzBGQlEzUkRPMEZCUTAwc1UwRkJWVWtzYVVKQlFXbENRU3hEUVVGRFNpeExRVUZqTzBWQlF6VkRReXhsUVVGTkxFTkJRVU5KTEZkQlFWY3NRMEZCUTB3c1MwRkJTeXhGUVVGRlJ5eFRRVUZUTEVOQlFVTTdRVUZEZUVNN1FVRkRUU3hUUVVGVlJ5eGpRVUZqUVN4RFFVRkRUaXhMUVVGak8wVkJRM3BEUXl4bFFVRk5MRU5CUVVOSkxGZEJRVmNzUTBGQlF5eFBRVUZQVEN4TFFVRkxMRVZCUVVVc1VVRkJVU3hEUVVGRE8wRkJRemxETzBGQlEwMHNVMEZCVlU4c1kwRkJZMEVzUTBGQlExQXNTMEZCWXp0RlFVTjZRME1zWlVGQlRTeERRVUZEU1N4WFFVRlhMRU5CUVVNc1QwRkJUMHdzUzBGQlN5eEZRVUZGTEZGQlFWRXNRMEZCUXp0QlFVTTVRenRCUVVOTkxGTkJRVlZSTEdWQlFXVkJMRU5CUVVOU0xFdEJRV003UlVGRE1VTkRMR1ZCUVUwc1EwRkJRMGtzVjBGQlZ5eERRVUZETEU5QlFVOU1MRXRCUVVzc1JVRkJSU3hUUVVGVExFTkJRVU03UVVGREwwTTdRVUZEVFN4VFFVRlZVeXhyUWtGQmEwSkJMRU5CUVhOQ1ZDeExRVUZqTEVWQlFVVlZMRWxCUVhWQ08wVkJRek5HTEVsQlFVRlVMR1ZCUVUwc1JVRkJRMFFzUzBGQlN5eFpRVUZaVlN4SlFVRkpMRVZCUVVVc2MwSkJRWE5DUVN4SlFVRkpMRU5CUVVORExFbEJRVWtzUlVGQlJTeERRVUZETzBGQlEzQkZPMEZCUlVFN1FVRkRUU3hUUVVGVlF5eHJRa0ZCYTBKQkxFTkJRVU5ETEVWQlFWVXNSVUZCUlVNc1VVRkJVU3hIUVVGSExFTkJRVU03UlVGRGRrUXNTVUZCU1VRc1JVRkJSU3hIUVVGSExFTkJRVU1zUlVGQlJTeFBRVUZQTEV0QlFVczdSVUZGZUVJN1JVRkRRU3hOUVVGTlJTeFJRVUZSTEVkQlFYVkNMRU5CUTJwRExFTkJRVU1zUzBGQlN5eEZRVUZWUXl4SlFVRkpMRU5CUVVORExFdEJRVXNzUTBGQlEwb3NSVUZCUlN4SlFVRkpMRVZCUVVVc1IwRkJSeXhGUVVGRkxFZEJRVWNzUlVGQlJTeEhRVUZIYUVJc1JVRkJSU3hEUVVGRExFTkJRVU1zUTBGQlRTeEZRVU14UkN4RFFVRkRMRTFCUVUwc1JVRkJVMjFDTEVsQlFVa3NRMEZCUTBNc1MwRkJTeXhEUVVGRFNpeEZRVUZGTEVsQlFWTXNSVUZCUlN4SFFVRkhMRVZCUVVVc1IwRkJSMmhDTEVWQlFVVXNRMEZCUXl4RFFVRkRMRWRCUVVjc1JVRkJSU3hEUVVGRExFVkJRekZFTEVOQlFVTXNVVUZCVVN4RlFVRlBiVUlzU1VGQlNTeERRVUZEUXl4TFFVRkxMRU5CUVVOS0xFVkJRVVVzU1VGQll5eEZRVUZGTEVkQlFVZG9RaXhGUVVGRkxFTkJRVU1zUTBGQlF5eEhRVUZITEVWQlFVVXNRMEZCUXl4RlFVTXhSQ3hEUVVGRExGRkJRVkVzUlVGQlQyMUNMRWxCUVVrc1EwRkJRME1zUzBGQlN5eERRVUZEU2l4RlFVRkZMRWRCUVcxQ2FFSXNSVUZCUlN4RFFVRkZMRWRCUVVjc1JVRkJSU3hEUVVGRExFVkJRekZFTEVOQlFVTXNZVUZCWVN4RlFVRkZiVUlzU1VGQlNTeERRVUZEUXl4TFFVRkxMRU5CUVVOS0xFVkJRVVVzUTBGQmRVSXNSMEZCUjJoQ0xFVkJRVVVzUTBGQlF5eERRVU0zUkR0RlFVVkVPMFZCUTBFc1QwRkJUMnRDTEZGQlFWRXNRMEZCUXl4RFFVRkRMRU5CUVVNc1IwRkJSeXhEUVVGRExFTkJRVU1zUzBGQlN5eERRVUZETEVWQlFVVkJMRkZCUVZFc1EwRkJRMGNzUzBGQlN5eEZRVUZGTzBWQlJTOURPMFZCUTBFc1QwRkJUMGdzVVVGQlVTeERRVUZEU1N4TFFVRkxMRU5CUVVNc1EwRkJReXhGUVVGRlRDeFJRVUZSTEVOQlFVTXNRMEZETjBKTkxFMUJRVTBzUTBGQlF5eERRVUZETEVOQlFVTkRMRWxCUVVrc1JVRkJSWEpDTEV0QlFVc3NRMEZCUXl4TFFVRkxRU3hMUVVGTExFdEJRVXNzUTBGQlF5eERRVUZETEVOQlEzUkRjMElzUjBGQlJ5eERRVUZETEVOQlFVTXNRMEZCUTBNc1IwRkJSeXhGUVVGRmRrSXNTMEZCU3l4RFFVRkRMRXRCUVV0M1FpeE5RVUZOTEVOQlFVTjRRaXhMUVVGTExFVkJRVVYxUWl4SFFVRkhMRU5CUVVNc1EwRkJReXhEUVVONlEwVXNTVUZCU1N4RFFVRkRMRWRCUVVjc1EwRkJRenRCUVVOc1FqdEJRVVZCTzBGQlEwMHNVMEZCVlVNc1lVRkJZVUVzUTBGQlEwTXNUMEZCWlN4RlFVRkZZaXhSUVVGUkxFZEJRVWNzUTBGQlF6dEZRVU4yUkN4UFFVRlBSaXhyUWtGQmEwSXNRMEZCUTJVc1QwRkJUeXhIUVVGSExFbEJRVWtzUlVGQlJXSXNVVUZCVVN4RFFVRkRPMEZCUTNaRU8wRkJSVUU3UVVGRFRTeFRRVUZWWXl4VlFVRlZRU3hEUVVGRFF5eExRVUZsTzBWQlEzUkRMRkZCUVZGQkxFdEJRVXNzUTBGQlEwTXNUVUZCVFR0SlFVTndRaXhMUVVGTExFTkJRVU03VFVGQlRTeFBRVUZQTEV0QlFVczdTVUZEZUVJc1MwRkJTeXhEUVVGRE8wMUJRVTBzVDBGQlQwUXNTMEZCU3l4RFFVRkRMRU5CUVVNc1EwRkJReXhKUVVGSkxFVkJRVVU3U1VGRGFrTXNTMEZCU3l4RFFVRkRPMDFCUVUwc1QwRkJUeXhIUVVGSFFTeExRVUZMTEVOQlFVTXNRMEZCUXl4RFFVRkRMRkZCUVZGQkxFdEJRVXNzUTBGQlF5eERRVUZETEVOQlFVTXNSVUZCUlR0SlFVTm9SRHROUVVGWkxFOUJRVThzUTBGQlF5eEhRVUZIUVN4TFFVRkxMRU5CUVVOV0xFdEJRVXNzUTBGQlF5eERRVUZETEVWQlFVVXNRMEZCUXl4RFFVRkRMRU5CUVVNc1JVRkJSU3hQUVVGUFZTeExRVUZMTEVOQlFVTkJMRXRCUVVzc1EwRkJRME1zVFVGQlRTeEhRVUZITEVOQlFVTXNRMEZCUXl4RlFVRkZMRU5CUVVNc1EwRkJRMHdzU1VGQlNTeERRVUZETEVsQlFVa3NRMEZCUXp0RlFVTjJSanRCUVVOS08wRkJSVUU3UVVGRFRTeFRRVUZWUkN4TlFVRk5RU3hEUVVGRFR5eExRVUZoTEVWQlFVVkRMRWxCUVN0Q0xFVkJRVVZETEZOQlFWTXNSMEZCUnl4SlFVRkpPMFZCUTI1R0xFMUJRVTBzUTBGQlEwTXNVVUZCVVN4RlFVRkZWaXhOUVVGTkxFTkJRVU1zUjBGQlIxY3NTMEZCU3l4RFFVRkRReXhQUVVGUExFTkJRVU5LTEVsQlFVa3NRMEZCUXl4SFFVRkhRU3hKUVVGSkxFZEJRVWNzUTBGQlEwRXNTVUZCU1N4RlFVRkZMRVZCUVVVc1EwRkJRenRGUVVOc1JVRXNTVUZCU1N4SFFVRkhSQ3hMUVVGTExFdEJRVXNzUTBGQlF5eEhRVUZIUnl4UlFVRlJMRWRCUVVkV0xFMUJRVTA3UlVGRGRFTXNTVUZCU1N4RFFVRkRVU3hKUVVGSkxFVkJRVVU3U1VGRFVEdEpRVU5CTEUxQlFVMUxMRXRCUVVzc1IwRkJLMElzUTBGRGRFTXNRMEZCUXl4TFFVRkxMRVZCUVd0Q0xFZEJRVWNzUlVGQlNTeERRVUZETEVOQlFVTTdTVUZCUlR0SlFVTnVReXhEUVVGRExFdEJRVXNzUlVGQmEwSXNSMEZCUnl4RlFVRkpMRU5CUVVNc1EwRkJRenRKUVVGRk8wbEJRMjVETEVOQlFVTXNXVUZCV1N4RlFVRlhMRXRCUVVzc1JVRkJSU3hEUVVGRExFTkJRVU03U1VGQlJUdEpRVU51UXl4RFFVRkRMSEZDUVVGeFFpeEZRVUZGTEVsQlFVa3NSVUZCUnl4RFFVRkRMRU5CUVVNN1NVRkJSVHRKUVVOdVF5eERRVUZETEVWQlFVVXNSVUZCY1VJc1IwRkJSeXhGUVVGSkxFTkJRVU1zUTBGQlF5eERRVUZGTzBsQlFVRXNRMEZEZEVNN1NVRkRSQ3hOUVVGTlF5eEpRVUZKTEVkQlFVZEVMRXRCUVVzc1EwRkJRMFVzU1VGQlNTeERRVUZETEVOQlFVTXNRMEZCUTBNc1RVRkJUU3hEUVVGRExFdEJRVXNzU1VGQlNVTXNUVUZCVFN4RFFVRkRSQ3hOUVVGTkxFVkJRVVVzUjBGQlJ5eERRVUZETEVOQlFVTkZMRWxCUVVrc1EwRkJRMUlzVVVGQlVTeERRVUZETEVOQlFVTTdTVUZETjBWdVF5eGxRVUZsTEVOQlFVTjFReXhKUVVGSkxFTkJRVU03U1VGRGNrSXNUVUZCVFVzc1UwRkJVeXhIUVVGSlF5eERRVUZUTEVsQlFXRldMRkZCUVZFc1MwRkJTMEVzVVVGQlVTeERRVUZEVnl4WFFVRlhMRVZCUVVVc1IwRkJSMFFzUTBGQlF5eERRVUZEUXl4WFFVRlhMRVZCUVVVc1IwRkJSMFFzUTBGQlF6dEpRVU5zUjFvc1NVRkJTU3hIUVVGSFJTeFJRVUZSTEVOQlFVTlpMRk5CUVZNc1EwRkJReXhEUVVGRExFVkJRVVZhTEZGQlFWRXNRMEZCUTBvc1RVRkJUU3hIUVVGSFVTeEpRVUZKTEVOQlFVTXNRMEZCUXl4RFFVRkRMRU5CUVVNc1EwRkJRMU1zVFVGQlRTeERRVUZEU2l4VFFVRlRMRU5CUVVOTUxFbEJRVWtzUTBGQlF5eERRVUZETEVOQlFVTXNRMEZCUXl4RFFVRkRPMFZCUTNSR08wVkJRMEVzVDBGQlQwd3NVMEZCVXl4SFFVRkhMRWRCUVVkR0xFdEJRVXNzU1VGQlNVTXNTVUZCU1N4RlFVRkZMRWRCUVVkQkxFbEJRVWs3UVVGRGFFUTdRVUZGUVR0QlFVTk5MRk5CUVZWblFpeFBRVUZQUVN4RFFVRkRReXhKUVVGblFpeEZRVUZGUXl4VFFVRlRMRWRCUVVjc1NVRkJTVHRGUVVOMFJEdEZRVU5CTEUxQlFVMURMRXRCUVVzc1IwRkJZU3hGUVVGRk8wVkJRekZDUml4SlFVRkpMRU5CUVVOSExFOUJRVThzUTBGQlEwTXNSMEZCUnl4SlFVRkhPMGxCUTJaQkxFZEJRVWNzUTBGQlEwUXNUMEZCVHl4RFFVRkRMRU5CUVVOd1JDeExRVUZMTEVWQlFVVnpSQ3hMUVVGTExFdEJRVWs3VFVGRGVrSklMRXRCUVVzc1EwRkJRMGNzUzBGQlN5eERRVUZETEVkQlFVZDBReXhKUVVGSkxFTkJRVU4xUXl4SFFVRkhMRU5CUVVOS0xFdEJRVXNzUTBGQlEwY3NTMEZCU3l4RFFVRkRMRWxCUVVrc1EwRkJReXhGUVVGRmRFUXNTMEZCU3l4RFFVRkRPRUlzVFVGQlRTeERRVUZETzBsQlF6VkVMRU5CUVVNc1EwRkJRenRGUVVOT0xFTkJRVU1zUTBGQlF6dEZRVU5HY1VJc1MwRkJTeXhEUVVGRFN5eE5RVUZOTEVOQlFVTXNRMEZCUXl4RFFVRkRMRVZCUVVVc1EwRkJReXhGUVVGRkxFTkJRVU1zUTBGQlF6dEZRVVYwUWp0RlFVTkJMRTlCUVU5UUxFbEJRVWtzUTBGQlF6TkNMRWRCUVVjc1EwRkJReXRDTEVkQlFVY3NTVUZCU1VFc1IwRkJSeXhEUVVGREwwSXNSMEZCUnl4RFFVRkRMRU5CUVVOMFFpeExRVUZMTEVWQlFVVnpSQ3hMUVVGTExFdEJRVXQwUkN4TFFVRkxMRU5CUVVONVJDeE5RVUZOTEVOQlFVTk9MRXRCUVVzc1EwRkJRMGNzUzBGQlN5eERRVUZETEVsQlFVa3NRMEZCUXl4RFFVRkRMRU5CUVVNc1EwRkJRemRDTEVsQlFVa3NRMEZCUTNsQ0xGTkJRVk1zUTBGQlF5eERRVUZETzBGQlEzUkhPMEZCUlVFN1FVRkRUU3hUUVVGVlVTeFRRVUZUUVN4RFFVRnpRaXhIUVVGSFF5eFBRVUZ0UXp0RlFVTnFSaXhOUVVGTlF5eFJRVUZSTEVkQlFVazFSQ3hMUVVGakxFbEJRelZDUVN4TFFVRkxMRXRCUVV0SExGTkJRVk1zU1VGQlNTeFBRVUZQU0N4TFFVRkxMRXRCUVVzc1VVRkJVU3hKUVVGSkxFTkJRVU50UXl4TFFVRkxMRU5CUVVORExFOUJRVThzUTBGQlEzQkRMRXRCUVVzc1EwRkJRenRGUVVNM1JTeFBRVUZQTWtRc1QwRkJUeXhEUVVGRFJTeE5RVUZOTEVOQlFVTXNRMEZCUTBNc1IwRkJORUlzUlVGQlJVTXNUVUZCWXl4TFFVRkpPMGxCUTI1RlF5eE5RVUZOTEVOQlFVTkRMRTlCUVU4c1EwRkJRMFlzVFVGQlRTeERRVUZETEVOQlFVTllMRTlCUVU4c1EwRkJReXhEUVVGRExFTkJRVU0zUWl4SFFVRkhMRVZCUVVWMlFpeExRVUZMTEVOQlFVTXNTMEZCU1R0TlFVTTFReXhOUVVGTmEwVXNVVUZCVVN4SFFVRkhTaXhIUVVGSExFTkJRVU4yUXl4SFFVRkhMRU5CUVVNN1RVRkRla0lzU1VGQlNYWkNMRXRCUVVzc1MwRkJTMGNzVTBGQlV5eEZRVUZGTzAxQlEzcENMRWxCUVVsNVJDeFJRVUZSTEVOQlFVTk5MRkZCUVZFc1EwRkJReXhKUVVGSlRpeFJRVUZSTEVOQlFVTTFSQ3hMUVVGTExFTkJRVU1zUlVGQlJUaEVMRWRCUVVjc1EwRkJRM1pETEVkQlFVY3NRMEZCUXl4SFFVRkhiVU1zVTBGQlV5eERRVUZEVVN4UlFVRlJMRVZCUVVWc1JTeExRVUZMTEVOQlFVTXNRMEZCUXl4TFFVTTFSVGhFTEVkQlFVY3NRMEZCUTNaRExFZEJRVWNzUTBGQlF5eEhRVUZIZGtJc1MwRkJTenRKUVVONlFpeERRVUZETEVOQlFVTTdTVUZEUml4UFFVRlBPRVFzUjBGQlJ6dEZRVU5rTEVOQlFVTXNSVUZCUlN4RlFVRkZMRU5CUVZNN1FVRkRiRUk3UVVGUlFUdEJRVU5OTEZOQlFWVkxMR2xDUVVGcFFrRXNRMEZCUTBNc1RVRkJjMEk3UlVGRGNFUXNUVUZCVFVNc1MwRkJTeXhIUVVGaExFVkJRVVU3UlVGRE1VSkVMRTFCUVUwc1EwRkJRMmhDTEU5QlFVOHNRMEZCUXl4RFFVRkRhMElzUzBGQlN5eEZRVUZGYUVJc1MwRkJTeXhMUVVGSk8wbEJRelZDTEUxQlFVMXBRaXhOUVVGTkxFZEJRVWRCTEVOQlFVTkRMRU5CUVZNc1JVRkJSVU1zUTBGQlV5eExRVUZoYmtJc1MwRkJTeXhIUVVGSFl5eE5RVUZOTEVOQlFVTjBReXhOUVVGTkxFZEJRVWNzUTBGQlF5eEhRVUZITUVNc1EwRkJReXhIUVVGSFF5eERRVUZETzBsQlEyeEdTaXhMUVVGTExFTkJRVU5MTEVsQlFVa3NRMEZCUXl4SFFVRkhTQ3hOUVVGTkxFTkJRVU1zUzBGQlN5eEZRVUZGTEV0QlFVc3NRMEZCUXl4SFFVRkhSQ3hMUVVGTExFTkJRVU5MTEVsQlFVa3NTVUZCU1V3c1MwRkJTeXhEUVVGRFRTeFBRVUZQTEVWQlFVVXNRMEZCUXp0SlFVTnVSU3hKUVVGSlRpeExRVUZMTEVOQlFVTlBMRTFCUVUwc1JVRkJSVHROUVVOa0xFMUJRVTFCTEUxQlFVMHNSMEZCUjFZc2FVSkJRV2xDTEVOQlFVTkhMRXRCUVVzc1EwRkJRMDhzVFVGQlRTeERRVUZETzAxQlF6bERVaXhMUVVGTExFTkJRVU5MTEVsQlFVa3NRMEZCUXl4SFFVRkhSeXhOUVVGTkxFTkJRVU4yUkN4SFFVRkhMRU5CUVVOM1JDeEpRVUZKTEVsQlFVa3NSMEZCUjFBc1RVRkJUU3hEUVVGRExFdEJRVXNzUlVGQlJTeExRVUZMTEVOQlFVTXNTVUZCU1U4c1NVRkJTU3hGUVVGRkxFTkJRVU1zUTBGQlF6dEpRVU40UlR0RlFVTktMRU5CUVVNc1EwRkJRenRGUVVOR0xFOUJRVTlVTEV0QlFVczdRVUZEYUVJN1FVRkZRVHRCUVVOTkxGTkJRVlZWTEZsQlFWbEJMRU5CUVVORExGTkJRWEZDTEVWQlFVVjBSU3hKUVVGWE8wVkJRek5FTEUxQlFVMTFSU3hQUVVGUExFZEJRVWQyUlN4SlFVOW1PMFZCUlVRN1JVRkRRU3hOUVVGTmQwVXNTMEZCU3l4SFFVRkhMRVZCUVVVN1JVRkRhRUlzU1VGQlNVUXNUMEZCVHl4RFFVRkRSU3hQUVVGUExGbEJRVmxETEVkQlFVY3NSVUZCUlR0SlFVTm9RMFlzUzBGQlN5eERRVUZEVWl4SlFVRkpMRU5CUVVNc1IwRkJSMDhzVDBGQlR5eERRVUZEUlN4UFFVRlBMRU5CUVVNN1JVRkRiRU03UlVGRFFTeEpRVUZKYUVRc1MwRkJTeXhEUVVGRFF5eFBRVUZQTEVOQlFVTTJReXhQUVVGUExFTkJRVU5KTEV0QlFVc3NRMEZCUXl4RlFVRkZPMGxCUXpsQ0xFdEJRVXNzVFVGQlRVTXNTVUZCU1N4SlFVRkpUQ3hQUVVGUExFTkJRVU5KTEV0QlFVc3NSVUZCUlR0TlFVTTVRaXhOUVVGTlJTeFJRVUZSTEVkQlFVZFFMRk5CUVZNc1EwRkJRMDBzU1VGQlNTeERRVUZETzAxQlEyaERka1lzWlVGQlpTeERRVUZEZDBZc1VVRkJVU3hEUVVGRE8wMUJRM3BDVEN4TFFVRkxMRU5CUVVOU0xFbEJRVWtzUTBGQlF5eEhRVUZIU3l4WlFVRlpMRU5CUVVORExGTkJRVk1zUlVGQlJVOHNVVUZCVVN4RFFVRkRMRU5CUVVNN1NVRkRjRVE3UlVGRFNqdEZRVVZCTzBWQlEwRXNTVUZCU1hCRUxFdEJRVXNzUTBGQlEwTXNUMEZCVHl4RFFVRkROa01zVDBGQlR5eERRVUZEVHl4TlFVRk5MRU5CUVVNc1JVRkJSVHRKUVVNdlFpeExRVUZMTEUxQlFVMURMRXRCUVVzc1NVRkJTVklzVDBGQlR5eERRVUZEVHl4TlFVRk5MRVZCUXpsQ1RpeExRVUZMTEVOQlFVTlNMRWxCUVVrc1EwRkJReXhIUVVGSFN5eFpRVUZaTEVOQlFVTkRMRk5CUVZNc1JVRkJSVk1zUzBGQlN5eERRVUZETEVOQlFVTTdSVUZEY2tRN1JVRkZRVHRGUVVOQkxFbEJRVWxTTEU5QlFVOHNRMEZCUTFNc1YwRkJWeXhaUVVGWlRpeEhRVUZITEVWQlFVVTdTVUZEY0VOR0xFdEJRVXNzUTBGQlExSXNTVUZCU1N4RFFVRkRMRWRCUVVkUExFOUJRVThzUTBGQlExTXNWMEZCVnl4RFFVRkRPMFZCUTNSRE8wVkJSVUVzU1VGQlNTeFBRVUZQVkN4UFFVRlBMRU5CUVVOcVJpeExRVUZMTEV0QlFVc3NVVUZCVVN4RlFVRkZPMGxCUTI1RE8wbEJRMEZyUml4TFFVRkxMRU5CUVVOU0xFbEJRVWtzUTBGQlEwOHNUMEZCVHl4RFFVRkRha1lzUzBGQlN5eERRVUZETzBWQlF6ZENMRU5CUVVNc1RVRkJUU3hKUVVGSkxFOUJRVTlwUml4UFFVRlBMRU5CUVVOMFJTeEpRVUZKTEV0QlFVc3NVVUZCVVN4RlFVRkZPMGxCUTNwRE8wbEJRMEVzVFVGQlRXZEdMRkZCUVZFc1IwRkJSMWdzVTBGQlV5eERRVUZEUXl4UFFVRlBMRU5CUVVOMFJTeEpRVUZKTEVOQlFVTTdTVUZEZUVOYUxHVkJRV1VzUTBGQlF6UkdMRkZCUVZFc1EwRkJRenRKUVVONlFsUXNTMEZCU3l4RFFVRkRVaXhKUVVGSkxFTkJRVU1zUjBGQlIwc3NXVUZCV1N4RFFVRkRReXhUUVVGVExFVkJRVVZYTEZGQlFWRXNRMEZCUXl4RFFVRkRPMFZCUTNCRU8wVkJSVUVzVDBGQlQxUXNTMEZCU3p0QlFVTm9RaUlzSW1sbmJtOXlaVXhwYzNRaU9sdGRmUT09IiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD11aS5pbnRlcmZhY2UuanMubWFwIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgb2JqZWN0QXNzaWduID0gcmVxdWlyZSgnb2JqZWN0LmFzc2lnbi9wb2x5ZmlsbCcpKCk7XG5cbi8vIGNvbXBhcmUgYW5kIGlzQnVmZmVyIHRha2VuIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL2Zlcm9zcy9idWZmZXIvYmxvYi82ODBlOWU1ZTQ4OGYyMmFhYzI3NTk5YTU3ZGM4NDRhNjMxNTkyOGRkL2luZGV4LmpzXG4vLyBvcmlnaW5hbCBub3RpY2U6XG5cbi8qIVxuICogVGhlIGJ1ZmZlciBtb2R1bGUgZnJvbSBub2RlLmpzLCBmb3IgdGhlIGJyb3dzZXIuXG4gKlxuICogQGF1dGhvciAgIEZlcm9zcyBBYm91a2hhZGlqZWggPGZlcm9zc0BmZXJvc3Mub3JnPiA8aHR0cDovL2Zlcm9zcy5vcmc+XG4gKiBAbGljZW5zZSAgTUlUXG4gKi9cbmZ1bmN0aW9uIGNvbXBhcmUoYSwgYikge1xuICBpZiAoYSA9PT0gYikge1xuICAgIHJldHVybiAwO1xuICB9XG5cbiAgdmFyIHggPSBhLmxlbmd0aDtcbiAgdmFyIHkgPSBiLmxlbmd0aDtcblxuICBmb3IgKHZhciBpID0gMCwgbGVuID0gTWF0aC5taW4oeCwgeSk7IGkgPCBsZW47ICsraSkge1xuICAgIGlmIChhW2ldICE9PSBiW2ldKSB7XG4gICAgICB4ID0gYVtpXTtcbiAgICAgIHkgPSBiW2ldO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgaWYgKHggPCB5KSB7XG4gICAgcmV0dXJuIC0xO1xuICB9XG4gIGlmICh5IDwgeCkge1xuICAgIHJldHVybiAxO1xuICB9XG4gIHJldHVybiAwO1xufVxuZnVuY3Rpb24gaXNCdWZmZXIoYikge1xuICBpZiAoZ2xvYmFsLkJ1ZmZlciAmJiB0eXBlb2YgZ2xvYmFsLkJ1ZmZlci5pc0J1ZmZlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBnbG9iYWwuQnVmZmVyLmlzQnVmZmVyKGIpO1xuICB9XG4gIHJldHVybiAhIShiICE9IG51bGwgJiYgYi5faXNCdWZmZXIpO1xufVxuXG4vLyBiYXNlZCBvbiBub2RlIGFzc2VydCwgb3JpZ2luYWwgbm90aWNlOlxuLy8gTkI6IFRoZSBVUkwgdG8gdGhlIENvbW1vbkpTIHNwZWMgaXMga2VwdCBqdXN0IGZvciB0cmFkaXRpb24uXG4vLyAgICAgbm9kZS1hc3NlcnQgaGFzIGV2b2x2ZWQgYSBsb3Qgc2luY2UgdGhlbiwgYm90aCBpbiBBUEkgYW5kIGJlaGF2aW9yLlxuXG4vLyBodHRwOi8vd2lraS5jb21tb25qcy5vcmcvd2lraS9Vbml0X1Rlc3RpbmcvMS4wXG4vL1xuLy8gVEhJUyBJUyBOT1QgVEVTVEVEIE5PUiBMSUtFTFkgVE8gV09SSyBPVVRTSURFIFY4IVxuLy9cbi8vIE9yaWdpbmFsbHkgZnJvbSBuYXJ3aGFsLmpzIChodHRwOi8vbmFyd2hhbGpzLm9yZylcbi8vIENvcHlyaWdodCAoYykgMjAwOSBUaG9tYXMgUm9iaW5zb24gPDI4MG5vcnRoLmNvbT5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG4vLyBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSAnU29mdHdhcmUnKSwgdG9cbi8vIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlXG4vLyByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Jcbi8vIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzXG4vLyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4vLyBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgJ0FTIElTJywgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuLy8gSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4vLyBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcbi8vIEFVVEhPUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOXG4vLyBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OXG4vLyBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxudmFyIHV0aWwgPSByZXF1aXJlKCd1dGlsLycpO1xudmFyIGhhc093biA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG52YXIgcFNsaWNlID0gQXJyYXkucHJvdG90eXBlLnNsaWNlO1xudmFyIGZ1bmN0aW9uc0hhdmVOYW1lcyA9IChmdW5jdGlvbiAoKSB7XG4gIHJldHVybiBmdW5jdGlvbiBmb28oKSB7fS5uYW1lID09PSAnZm9vJztcbn0oKSk7XG5mdW5jdGlvbiBwVG9TdHJpbmcgKG9iaikge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG9iaik7XG59XG5mdW5jdGlvbiBpc1ZpZXcoYXJyYnVmKSB7XG4gIGlmIChpc0J1ZmZlcihhcnJidWYpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmICh0eXBlb2YgZ2xvYmFsLkFycmF5QnVmZmVyICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmICh0eXBlb2YgQXJyYXlCdWZmZXIuaXNWaWV3ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuIEFycmF5QnVmZmVyLmlzVmlldyhhcnJidWYpO1xuICB9XG4gIGlmICghYXJyYnVmKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmIChhcnJidWYgaW5zdGFuY2VvZiBEYXRhVmlldykge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIGlmIChhcnJidWYuYnVmZmVyICYmIGFycmJ1Zi5idWZmZXIgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cbi8vIDEuIFRoZSBhc3NlcnQgbW9kdWxlIHByb3ZpZGVzIGZ1bmN0aW9ucyB0aGF0IHRocm93XG4vLyBBc3NlcnRpb25FcnJvcidzIHdoZW4gcGFydGljdWxhciBjb25kaXRpb25zIGFyZSBub3QgbWV0LiBUaGVcbi8vIGFzc2VydCBtb2R1bGUgbXVzdCBjb25mb3JtIHRvIHRoZSBmb2xsb3dpbmcgaW50ZXJmYWNlLlxuXG52YXIgYXNzZXJ0ID0gbW9kdWxlLmV4cG9ydHMgPSBvaztcblxuLy8gMi4gVGhlIEFzc2VydGlvbkVycm9yIGlzIGRlZmluZWQgaW4gYXNzZXJ0LlxuLy8gbmV3IGFzc2VydC5Bc3NlcnRpb25FcnJvcih7IG1lc3NhZ2U6IG1lc3NhZ2UsXG4vLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWN0dWFsOiBhY3R1YWwsXG4vLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwZWN0ZWQ6IGV4cGVjdGVkIH0pXG5cbnZhciByZWdleCA9IC9cXHMqZnVuY3Rpb25cXHMrKFteXFwoXFxzXSopXFxzKi87XG4vLyBiYXNlZCBvbiBodHRwczovL2dpdGh1Yi5jb20vbGpoYXJiL2Z1bmN0aW9uLnByb3RvdHlwZS5uYW1lL2Jsb2IvYWRlZWVlYzhiZmNjNjA2OGIxODdkN2Q5ZmIzZDViYjFkM2EzMDg5OS9pbXBsZW1lbnRhdGlvbi5qc1xuZnVuY3Rpb24gZ2V0TmFtZShmdW5jKSB7XG4gIGlmICghdXRpbC5pc0Z1bmN0aW9uKGZ1bmMpKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGlmIChmdW5jdGlvbnNIYXZlTmFtZXMpIHtcbiAgICByZXR1cm4gZnVuYy5uYW1lO1xuICB9XG4gIHZhciBzdHIgPSBmdW5jLnRvU3RyaW5nKCk7XG4gIHZhciBtYXRjaCA9IHN0ci5tYXRjaChyZWdleCk7XG4gIHJldHVybiBtYXRjaCAmJiBtYXRjaFsxXTtcbn1cbmFzc2VydC5Bc3NlcnRpb25FcnJvciA9IGZ1bmN0aW9uIEFzc2VydGlvbkVycm9yKG9wdGlvbnMpIHtcbiAgdGhpcy5uYW1lID0gJ0Fzc2VydGlvbkVycm9yJztcbiAgdGhpcy5hY3R1YWwgPSBvcHRpb25zLmFjdHVhbDtcbiAgdGhpcy5leHBlY3RlZCA9IG9wdGlvbnMuZXhwZWN0ZWQ7XG4gIHRoaXMub3BlcmF0b3IgPSBvcHRpb25zLm9wZXJhdG9yO1xuICBpZiAob3B0aW9ucy5tZXNzYWdlKSB7XG4gICAgdGhpcy5tZXNzYWdlID0gb3B0aW9ucy5tZXNzYWdlO1xuICAgIHRoaXMuZ2VuZXJhdGVkTWVzc2FnZSA9IGZhbHNlO1xuICB9IGVsc2Uge1xuICAgIHRoaXMubWVzc2FnZSA9IGdldE1lc3NhZ2UodGhpcyk7XG4gICAgdGhpcy5nZW5lcmF0ZWRNZXNzYWdlID0gdHJ1ZTtcbiAgfVxuICB2YXIgc3RhY2tTdGFydEZ1bmN0aW9uID0gb3B0aW9ucy5zdGFja1N0YXJ0RnVuY3Rpb24gfHwgZmFpbDtcbiAgaWYgKEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKSB7XG4gICAgRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UodGhpcywgc3RhY2tTdGFydEZ1bmN0aW9uKTtcbiAgfSBlbHNlIHtcbiAgICAvLyBub24gdjggYnJvd3NlcnMgc28gd2UgY2FuIGhhdmUgYSBzdGFja3RyYWNlXG4gICAgdmFyIGVyciA9IG5ldyBFcnJvcigpO1xuICAgIGlmIChlcnIuc3RhY2spIHtcbiAgICAgIHZhciBvdXQgPSBlcnIuc3RhY2s7XG5cbiAgICAgIC8vIHRyeSB0byBzdHJpcCB1c2VsZXNzIGZyYW1lc1xuICAgICAgdmFyIGZuX25hbWUgPSBnZXROYW1lKHN0YWNrU3RhcnRGdW5jdGlvbik7XG4gICAgICB2YXIgaWR4ID0gb3V0LmluZGV4T2YoJ1xcbicgKyBmbl9uYW1lKTtcbiAgICAgIGlmIChpZHggPj0gMCkge1xuICAgICAgICAvLyBvbmNlIHdlIGhhdmUgbG9jYXRlZCB0aGUgZnVuY3Rpb24gZnJhbWVcbiAgICAgICAgLy8gd2UgbmVlZCB0byBzdHJpcCBvdXQgZXZlcnl0aGluZyBiZWZvcmUgaXQgKGFuZCBpdHMgbGluZSlcbiAgICAgICAgdmFyIG5leHRfbGluZSA9IG91dC5pbmRleE9mKCdcXG4nLCBpZHggKyAxKTtcbiAgICAgICAgb3V0ID0gb3V0LnN1YnN0cmluZyhuZXh0X2xpbmUgKyAxKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5zdGFjayA9IG91dDtcbiAgICB9XG4gIH1cbn07XG5cbi8vIGFzc2VydC5Bc3NlcnRpb25FcnJvciBpbnN0YW5jZW9mIEVycm9yXG51dGlsLmluaGVyaXRzKGFzc2VydC5Bc3NlcnRpb25FcnJvciwgRXJyb3IpO1xuXG5mdW5jdGlvbiB0cnVuY2F0ZShzLCBuKSB7XG4gIGlmICh0eXBlb2YgcyA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gcy5sZW5ndGggPCBuID8gcyA6IHMuc2xpY2UoMCwgbik7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHM7XG4gIH1cbn1cbmZ1bmN0aW9uIGluc3BlY3Qoc29tZXRoaW5nKSB7XG4gIGlmIChmdW5jdGlvbnNIYXZlTmFtZXMgfHwgIXV0aWwuaXNGdW5jdGlvbihzb21ldGhpbmcpKSB7XG4gICAgcmV0dXJuIHV0aWwuaW5zcGVjdChzb21ldGhpbmcpO1xuICB9XG4gIHZhciByYXduYW1lID0gZ2V0TmFtZShzb21ldGhpbmcpO1xuICB2YXIgbmFtZSA9IHJhd25hbWUgPyAnOiAnICsgcmF3bmFtZSA6ICcnO1xuICByZXR1cm4gJ1tGdW5jdGlvbicgKyAgbmFtZSArICddJztcbn1cbmZ1bmN0aW9uIGdldE1lc3NhZ2Uoc2VsZikge1xuICByZXR1cm4gdHJ1bmNhdGUoaW5zcGVjdChzZWxmLmFjdHVhbCksIDEyOCkgKyAnICcgK1xuICAgICAgICAgc2VsZi5vcGVyYXRvciArICcgJyArXG4gICAgICAgICB0cnVuY2F0ZShpbnNwZWN0KHNlbGYuZXhwZWN0ZWQpLCAxMjgpO1xufVxuXG4vLyBBdCBwcmVzZW50IG9ubHkgdGhlIHRocmVlIGtleXMgbWVudGlvbmVkIGFib3ZlIGFyZSB1c2VkIGFuZFxuLy8gdW5kZXJzdG9vZCBieSB0aGUgc3BlYy4gSW1wbGVtZW50YXRpb25zIG9yIHN1YiBtb2R1bGVzIGNhbiBwYXNzXG4vLyBvdGhlciBrZXlzIHRvIHRoZSBBc3NlcnRpb25FcnJvcidzIGNvbnN0cnVjdG9yIC0gdGhleSB3aWxsIGJlXG4vLyBpZ25vcmVkLlxuXG4vLyAzLiBBbGwgb2YgdGhlIGZvbGxvd2luZyBmdW5jdGlvbnMgbXVzdCB0aHJvdyBhbiBBc3NlcnRpb25FcnJvclxuLy8gd2hlbiBhIGNvcnJlc3BvbmRpbmcgY29uZGl0aW9uIGlzIG5vdCBtZXQsIHdpdGggYSBtZXNzYWdlIHRoYXRcbi8vIG1heSBiZSB1bmRlZmluZWQgaWYgbm90IHByb3ZpZGVkLiAgQWxsIGFzc2VydGlvbiBtZXRob2RzIHByb3ZpZGVcbi8vIGJvdGggdGhlIGFjdHVhbCBhbmQgZXhwZWN0ZWQgdmFsdWVzIHRvIHRoZSBhc3NlcnRpb24gZXJyb3IgZm9yXG4vLyBkaXNwbGF5IHB1cnBvc2VzLlxuXG5mdW5jdGlvbiBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UsIG9wZXJhdG9yLCBzdGFja1N0YXJ0RnVuY3Rpb24pIHtcbiAgdGhyb3cgbmV3IGFzc2VydC5Bc3NlcnRpb25FcnJvcih7XG4gICAgbWVzc2FnZTogbWVzc2FnZSxcbiAgICBhY3R1YWw6IGFjdHVhbCxcbiAgICBleHBlY3RlZDogZXhwZWN0ZWQsXG4gICAgb3BlcmF0b3I6IG9wZXJhdG9yLFxuICAgIHN0YWNrU3RhcnRGdW5jdGlvbjogc3RhY2tTdGFydEZ1bmN0aW9uXG4gIH0pO1xufVxuXG4vLyBFWFRFTlNJT04hIGFsbG93cyBmb3Igd2VsbCBiZWhhdmVkIGVycm9ycyBkZWZpbmVkIGVsc2V3aGVyZS5cbmFzc2VydC5mYWlsID0gZmFpbDtcblxuLy8gNC4gUHVyZSBhc3NlcnRpb24gdGVzdHMgd2hldGhlciBhIHZhbHVlIGlzIHRydXRoeSwgYXMgZGV0ZXJtaW5lZFxuLy8gYnkgISFndWFyZC5cbi8vIGFzc2VydC5vayhndWFyZCwgbWVzc2FnZV9vcHQpO1xuLy8gVGhpcyBzdGF0ZW1lbnQgaXMgZXF1aXZhbGVudCB0byBhc3NlcnQuZXF1YWwodHJ1ZSwgISFndWFyZCxcbi8vIG1lc3NhZ2Vfb3B0KTsuIFRvIHRlc3Qgc3RyaWN0bHkgZm9yIHRoZSB2YWx1ZSB0cnVlLCB1c2Vcbi8vIGFzc2VydC5zdHJpY3RFcXVhbCh0cnVlLCBndWFyZCwgbWVzc2FnZV9vcHQpOy5cblxuZnVuY3Rpb24gb2sodmFsdWUsIG1lc3NhZ2UpIHtcbiAgaWYgKCF2YWx1ZSkgZmFpbCh2YWx1ZSwgdHJ1ZSwgbWVzc2FnZSwgJz09JywgYXNzZXJ0Lm9rKTtcbn1cbmFzc2VydC5vayA9IG9rO1xuXG4vLyA1LiBUaGUgZXF1YWxpdHkgYXNzZXJ0aW9uIHRlc3RzIHNoYWxsb3csIGNvZXJjaXZlIGVxdWFsaXR5IHdpdGhcbi8vID09LlxuLy8gYXNzZXJ0LmVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2Vfb3B0KTtcblxuYXNzZXJ0LmVxdWFsID0gZnVuY3Rpb24gZXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuICBpZiAoYWN0dWFsICE9IGV4cGVjdGVkKSBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UsICc9PScsIGFzc2VydC5lcXVhbCk7XG59O1xuXG4vLyA2LiBUaGUgbm9uLWVxdWFsaXR5IGFzc2VydGlvbiB0ZXN0cyBmb3Igd2hldGhlciB0d28gb2JqZWN0cyBhcmUgbm90IGVxdWFsXG4vLyB3aXRoICE9IGFzc2VydC5ub3RFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlX29wdCk7XG5cbmFzc2VydC5ub3RFcXVhbCA9IGZ1bmN0aW9uIG5vdEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UpIHtcbiAgaWYgKGFjdHVhbCA9PSBleHBlY3RlZCkge1xuICAgIGZhaWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSwgJyE9JywgYXNzZXJ0Lm5vdEVxdWFsKTtcbiAgfVxufTtcblxuLy8gNy4gVGhlIGVxdWl2YWxlbmNlIGFzc2VydGlvbiB0ZXN0cyBhIGRlZXAgZXF1YWxpdHkgcmVsYXRpb24uXG4vLyBhc3NlcnQuZGVlcEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2Vfb3B0KTtcblxuYXNzZXJ0LmRlZXBFcXVhbCA9IGZ1bmN0aW9uIGRlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlKSB7XG4gIGlmICghX2RlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBmYWxzZSkpIHtcbiAgICBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UsICdkZWVwRXF1YWwnLCBhc3NlcnQuZGVlcEVxdWFsKTtcbiAgfVxufTtcblxuYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbCA9IGZ1bmN0aW9uIGRlZXBTdHJpY3RFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlKSB7XG4gIGlmICghX2RlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCB0cnVlKSkge1xuICAgIGZhaWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSwgJ2RlZXBTdHJpY3RFcXVhbCcsIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwpO1xuICB9XG59O1xuXG5mdW5jdGlvbiBfZGVlcEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIHN0cmljdCwgbWVtb3MpIHtcbiAgLy8gNy4xLiBBbGwgaWRlbnRpY2FsIHZhbHVlcyBhcmUgZXF1aXZhbGVudCwgYXMgZGV0ZXJtaW5lZCBieSA9PT0uXG4gIGlmIChhY3R1YWwgPT09IGV4cGVjdGVkKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH0gZWxzZSBpZiAoaXNCdWZmZXIoYWN0dWFsKSAmJiBpc0J1ZmZlcihleHBlY3RlZCkpIHtcbiAgICByZXR1cm4gY29tcGFyZShhY3R1YWwsIGV4cGVjdGVkKSA9PT0gMDtcblxuICAvLyA3LjIuIElmIHRoZSBleHBlY3RlZCB2YWx1ZSBpcyBhIERhdGUgb2JqZWN0LCB0aGUgYWN0dWFsIHZhbHVlIGlzXG4gIC8vIGVxdWl2YWxlbnQgaWYgaXQgaXMgYWxzbyBhIERhdGUgb2JqZWN0IHRoYXQgcmVmZXJzIHRvIHRoZSBzYW1lIHRpbWUuXG4gIH0gZWxzZSBpZiAodXRpbC5pc0RhdGUoYWN0dWFsKSAmJiB1dGlsLmlzRGF0ZShleHBlY3RlZCkpIHtcbiAgICByZXR1cm4gYWN0dWFsLmdldFRpbWUoKSA9PT0gZXhwZWN0ZWQuZ2V0VGltZSgpO1xuXG4gIC8vIDcuMyBJZiB0aGUgZXhwZWN0ZWQgdmFsdWUgaXMgYSBSZWdFeHAgb2JqZWN0LCB0aGUgYWN0dWFsIHZhbHVlIGlzXG4gIC8vIGVxdWl2YWxlbnQgaWYgaXQgaXMgYWxzbyBhIFJlZ0V4cCBvYmplY3Qgd2l0aCB0aGUgc2FtZSBzb3VyY2UgYW5kXG4gIC8vIHByb3BlcnRpZXMgKGBnbG9iYWxgLCBgbXVsdGlsaW5lYCwgYGxhc3RJbmRleGAsIGBpZ25vcmVDYXNlYCkuXG4gIH0gZWxzZSBpZiAodXRpbC5pc1JlZ0V4cChhY3R1YWwpICYmIHV0aWwuaXNSZWdFeHAoZXhwZWN0ZWQpKSB7XG4gICAgcmV0dXJuIGFjdHVhbC5zb3VyY2UgPT09IGV4cGVjdGVkLnNvdXJjZSAmJlxuICAgICAgICAgICBhY3R1YWwuZ2xvYmFsID09PSBleHBlY3RlZC5nbG9iYWwgJiZcbiAgICAgICAgICAgYWN0dWFsLm11bHRpbGluZSA9PT0gZXhwZWN0ZWQubXVsdGlsaW5lICYmXG4gICAgICAgICAgIGFjdHVhbC5sYXN0SW5kZXggPT09IGV4cGVjdGVkLmxhc3RJbmRleCAmJlxuICAgICAgICAgICBhY3R1YWwuaWdub3JlQ2FzZSA9PT0gZXhwZWN0ZWQuaWdub3JlQ2FzZTtcblxuICAvLyA3LjQuIE90aGVyIHBhaXJzIHRoYXQgZG8gbm90IGJvdGggcGFzcyB0eXBlb2YgdmFsdWUgPT0gJ29iamVjdCcsXG4gIC8vIGVxdWl2YWxlbmNlIGlzIGRldGVybWluZWQgYnkgPT0uXG4gIH0gZWxzZSBpZiAoKGFjdHVhbCA9PT0gbnVsbCB8fCB0eXBlb2YgYWN0dWFsICE9PSAnb2JqZWN0JykgJiZcbiAgICAgICAgICAgICAoZXhwZWN0ZWQgPT09IG51bGwgfHwgdHlwZW9mIGV4cGVjdGVkICE9PSAnb2JqZWN0JykpIHtcbiAgICByZXR1cm4gc3RyaWN0ID8gYWN0dWFsID09PSBleHBlY3RlZCA6IGFjdHVhbCA9PSBleHBlY3RlZDtcblxuICAvLyBJZiBib3RoIHZhbHVlcyBhcmUgaW5zdGFuY2VzIG9mIHR5cGVkIGFycmF5cywgd3JhcCB0aGVpciB1bmRlcmx5aW5nXG4gIC8vIEFycmF5QnVmZmVycyBpbiBhIEJ1ZmZlciBlYWNoIHRvIGluY3JlYXNlIHBlcmZvcm1hbmNlXG4gIC8vIFRoaXMgb3B0aW1pemF0aW9uIHJlcXVpcmVzIHRoZSBhcnJheXMgdG8gaGF2ZSB0aGUgc2FtZSB0eXBlIGFzIGNoZWNrZWQgYnlcbiAgLy8gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZyAoYWthIHBUb1N0cmluZykuIE5ldmVyIHBlcmZvcm0gYmluYXJ5XG4gIC8vIGNvbXBhcmlzb25zIGZvciBGbG9hdCpBcnJheXMsIHRob3VnaCwgc2luY2UgZS5nLiArMCA9PT0gLTAgYnV0IHRoZWlyXG4gIC8vIGJpdCBwYXR0ZXJucyBhcmUgbm90IGlkZW50aWNhbC5cbiAgfSBlbHNlIGlmIChpc1ZpZXcoYWN0dWFsKSAmJiBpc1ZpZXcoZXhwZWN0ZWQpICYmXG4gICAgICAgICAgICAgcFRvU3RyaW5nKGFjdHVhbCkgPT09IHBUb1N0cmluZyhleHBlY3RlZCkgJiZcbiAgICAgICAgICAgICAhKGFjdHVhbCBpbnN0YW5jZW9mIEZsb2F0MzJBcnJheSB8fFxuICAgICAgICAgICAgICAgYWN0dWFsIGluc3RhbmNlb2YgRmxvYXQ2NEFycmF5KSkge1xuICAgIHJldHVybiBjb21wYXJlKG5ldyBVaW50OEFycmF5KGFjdHVhbC5idWZmZXIpLFxuICAgICAgICAgICAgICAgICAgIG5ldyBVaW50OEFycmF5KGV4cGVjdGVkLmJ1ZmZlcikpID09PSAwO1xuXG4gIC8vIDcuNSBGb3IgYWxsIG90aGVyIE9iamVjdCBwYWlycywgaW5jbHVkaW5nIEFycmF5IG9iamVjdHMsIGVxdWl2YWxlbmNlIGlzXG4gIC8vIGRldGVybWluZWQgYnkgaGF2aW5nIHRoZSBzYW1lIG51bWJlciBvZiBvd25lZCBwcm9wZXJ0aWVzIChhcyB2ZXJpZmllZFxuICAvLyB3aXRoIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCksIHRoZSBzYW1lIHNldCBvZiBrZXlzXG4gIC8vIChhbHRob3VnaCBub3QgbmVjZXNzYXJpbHkgdGhlIHNhbWUgb3JkZXIpLCBlcXVpdmFsZW50IHZhbHVlcyBmb3IgZXZlcnlcbiAgLy8gY29ycmVzcG9uZGluZyBrZXksIGFuZCBhbiBpZGVudGljYWwgJ3Byb3RvdHlwZScgcHJvcGVydHkuIE5vdGU6IHRoaXNcbiAgLy8gYWNjb3VudHMgZm9yIGJvdGggbmFtZWQgYW5kIGluZGV4ZWQgcHJvcGVydGllcyBvbiBBcnJheXMuXG4gIH0gZWxzZSBpZiAoaXNCdWZmZXIoYWN0dWFsKSAhPT0gaXNCdWZmZXIoZXhwZWN0ZWQpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9IGVsc2Uge1xuICAgIG1lbW9zID0gbWVtb3MgfHwge2FjdHVhbDogW10sIGV4cGVjdGVkOiBbXX07XG5cbiAgICB2YXIgYWN0dWFsSW5kZXggPSBtZW1vcy5hY3R1YWwuaW5kZXhPZihhY3R1YWwpO1xuICAgIGlmIChhY3R1YWxJbmRleCAhPT0gLTEpIHtcbiAgICAgIGlmIChhY3R1YWxJbmRleCA9PT0gbWVtb3MuZXhwZWN0ZWQuaW5kZXhPZihleHBlY3RlZCkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgbWVtb3MuYWN0dWFsLnB1c2goYWN0dWFsKTtcbiAgICBtZW1vcy5leHBlY3RlZC5wdXNoKGV4cGVjdGVkKTtcblxuICAgIHJldHVybiBvYmpFcXVpdihhY3R1YWwsIGV4cGVjdGVkLCBzdHJpY3QsIG1lbW9zKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBpc0FyZ3VtZW50cyhvYmplY3QpIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvYmplY3QpID09ICdbb2JqZWN0IEFyZ3VtZW50c10nO1xufVxuXG5mdW5jdGlvbiBvYmpFcXVpdihhLCBiLCBzdHJpY3QsIGFjdHVhbFZpc2l0ZWRPYmplY3RzKSB7XG4gIGlmIChhID09PSBudWxsIHx8IGEgPT09IHVuZGVmaW5lZCB8fCBiID09PSBudWxsIHx8IGIgPT09IHVuZGVmaW5lZClcbiAgICByZXR1cm4gZmFsc2U7XG4gIC8vIGlmIG9uZSBpcyBhIHByaW1pdGl2ZSwgdGhlIG90aGVyIG11c3QgYmUgc2FtZVxuICBpZiAodXRpbC5pc1ByaW1pdGl2ZShhKSB8fCB1dGlsLmlzUHJpbWl0aXZlKGIpKVxuICAgIHJldHVybiBhID09PSBiO1xuICBpZiAoc3RyaWN0ICYmIE9iamVjdC5nZXRQcm90b3R5cGVPZihhKSAhPT0gT2JqZWN0LmdldFByb3RvdHlwZU9mKGIpKVxuICAgIHJldHVybiBmYWxzZTtcbiAgdmFyIGFJc0FyZ3MgPSBpc0FyZ3VtZW50cyhhKTtcbiAgdmFyIGJJc0FyZ3MgPSBpc0FyZ3VtZW50cyhiKTtcbiAgaWYgKChhSXNBcmdzICYmICFiSXNBcmdzKSB8fCAoIWFJc0FyZ3MgJiYgYklzQXJncykpXG4gICAgcmV0dXJuIGZhbHNlO1xuICBpZiAoYUlzQXJncykge1xuICAgIGEgPSBwU2xpY2UuY2FsbChhKTtcbiAgICBiID0gcFNsaWNlLmNhbGwoYik7XG4gICAgcmV0dXJuIF9kZWVwRXF1YWwoYSwgYiwgc3RyaWN0KTtcbiAgfVxuICB2YXIga2EgPSBvYmplY3RLZXlzKGEpO1xuICB2YXIga2IgPSBvYmplY3RLZXlzKGIpO1xuICB2YXIga2V5LCBpO1xuICAvLyBoYXZpbmcgdGhlIHNhbWUgbnVtYmVyIG9mIG93bmVkIHByb3BlcnRpZXMgKGtleXMgaW5jb3Jwb3JhdGVzXG4gIC8vIGhhc093blByb3BlcnR5KVxuICBpZiAoa2EubGVuZ3RoICE9PSBrYi5sZW5ndGgpXG4gICAgcmV0dXJuIGZhbHNlO1xuICAvL3RoZSBzYW1lIHNldCBvZiBrZXlzIChhbHRob3VnaCBub3QgbmVjZXNzYXJpbHkgdGhlIHNhbWUgb3JkZXIpLFxuICBrYS5zb3J0KCk7XG4gIGtiLnNvcnQoKTtcbiAgLy9+fn5jaGVhcCBrZXkgdGVzdFxuICBmb3IgKGkgPSBrYS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgIGlmIChrYVtpXSAhPT0ga2JbaV0pXG4gICAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgLy9lcXVpdmFsZW50IHZhbHVlcyBmb3IgZXZlcnkgY29ycmVzcG9uZGluZyBrZXksIGFuZFxuICAvL35+fnBvc3NpYmx5IGV4cGVuc2l2ZSBkZWVwIHRlc3RcbiAgZm9yIChpID0ga2EubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICBrZXkgPSBrYVtpXTtcbiAgICBpZiAoIV9kZWVwRXF1YWwoYVtrZXldLCBiW2tleV0sIHN0cmljdCwgYWN0dWFsVmlzaXRlZE9iamVjdHMpKVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiB0cnVlO1xufVxuXG4vLyA4LiBUaGUgbm9uLWVxdWl2YWxlbmNlIGFzc2VydGlvbiB0ZXN0cyBmb3IgYW55IGRlZXAgaW5lcXVhbGl0eS5cbi8vIGFzc2VydC5ub3REZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZV9vcHQpO1xuXG5hc3NlcnQubm90RGVlcEVxdWFsID0gZnVuY3Rpb24gbm90RGVlcEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UpIHtcbiAgaWYgKF9kZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgZmFsc2UpKSB7XG4gICAgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCAnbm90RGVlcEVxdWFsJywgYXNzZXJ0Lm5vdERlZXBFcXVhbCk7XG4gIH1cbn07XG5cbmFzc2VydC5ub3REZWVwU3RyaWN0RXF1YWwgPSBub3REZWVwU3RyaWN0RXF1YWw7XG5mdW5jdGlvbiBub3REZWVwU3RyaWN0RXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuICBpZiAoX2RlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCB0cnVlKSkge1xuICAgIGZhaWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSwgJ25vdERlZXBTdHJpY3RFcXVhbCcsIG5vdERlZXBTdHJpY3RFcXVhbCk7XG4gIH1cbn1cblxuXG4vLyA5LiBUaGUgc3RyaWN0IGVxdWFsaXR5IGFzc2VydGlvbiB0ZXN0cyBzdHJpY3QgZXF1YWxpdHksIGFzIGRldGVybWluZWQgYnkgPT09LlxuLy8gYXNzZXJ0LnN0cmljdEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2Vfb3B0KTtcblxuYXNzZXJ0LnN0cmljdEVxdWFsID0gZnVuY3Rpb24gc3RyaWN0RXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuICBpZiAoYWN0dWFsICE9PSBleHBlY3RlZCkge1xuICAgIGZhaWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSwgJz09PScsIGFzc2VydC5zdHJpY3RFcXVhbCk7XG4gIH1cbn07XG5cbi8vIDEwLiBUaGUgc3RyaWN0IG5vbi1lcXVhbGl0eSBhc3NlcnRpb24gdGVzdHMgZm9yIHN0cmljdCBpbmVxdWFsaXR5LCBhc1xuLy8gZGV0ZXJtaW5lZCBieSAhPT0uICBhc3NlcnQubm90U3RyaWN0RXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZV9vcHQpO1xuXG5hc3NlcnQubm90U3RyaWN0RXF1YWwgPSBmdW5jdGlvbiBub3RTdHJpY3RFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlKSB7XG4gIGlmIChhY3R1YWwgPT09IGV4cGVjdGVkKSB7XG4gICAgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCAnIT09JywgYXNzZXJ0Lm5vdFN0cmljdEVxdWFsKTtcbiAgfVxufTtcblxuZnVuY3Rpb24gZXhwZWN0ZWRFeGNlcHRpb24oYWN0dWFsLCBleHBlY3RlZCkge1xuICBpZiAoIWFjdHVhbCB8fCAhZXhwZWN0ZWQpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBpZiAoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGV4cGVjdGVkKSA9PSAnW29iamVjdCBSZWdFeHBdJykge1xuICAgIHJldHVybiBleHBlY3RlZC50ZXN0KGFjdHVhbCk7XG4gIH1cblxuICB0cnkge1xuICAgIGlmIChhY3R1YWwgaW5zdGFuY2VvZiBleHBlY3RlZCkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9IGNhdGNoIChlKSB7XG4gICAgLy8gSWdub3JlLiAgVGhlIGluc3RhbmNlb2YgY2hlY2sgZG9lc24ndCB3b3JrIGZvciBhcnJvdyBmdW5jdGlvbnMuXG4gIH1cblxuICBpZiAoRXJyb3IuaXNQcm90b3R5cGVPZihleHBlY3RlZCkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gZXhwZWN0ZWQuY2FsbCh7fSwgYWN0dWFsKSA9PT0gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gX3RyeUJsb2NrKGJsb2NrKSB7XG4gIHZhciBlcnJvcjtcbiAgdHJ5IHtcbiAgICBibG9jaygpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgZXJyb3IgPSBlO1xuICB9XG4gIHJldHVybiBlcnJvcjtcbn1cblxuZnVuY3Rpb24gX3Rocm93cyhzaG91bGRUaHJvdywgYmxvY2ssIGV4cGVjdGVkLCBtZXNzYWdlKSB7XG4gIHZhciBhY3R1YWw7XG5cbiAgaWYgKHR5cGVvZiBibG9jayAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wiYmxvY2tcIiBhcmd1bWVudCBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcbiAgfVxuXG4gIGlmICh0eXBlb2YgZXhwZWN0ZWQgPT09ICdzdHJpbmcnKSB7XG4gICAgbWVzc2FnZSA9IGV4cGVjdGVkO1xuICAgIGV4cGVjdGVkID0gbnVsbDtcbiAgfVxuXG4gIGFjdHVhbCA9IF90cnlCbG9jayhibG9jayk7XG5cbiAgbWVzc2FnZSA9IChleHBlY3RlZCAmJiBleHBlY3RlZC5uYW1lID8gJyAoJyArIGV4cGVjdGVkLm5hbWUgKyAnKS4nIDogJy4nKSArXG4gICAgICAgICAgICAobWVzc2FnZSA/ICcgJyArIG1lc3NhZ2UgOiAnLicpO1xuXG4gIGlmIChzaG91bGRUaHJvdyAmJiAhYWN0dWFsKSB7XG4gICAgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCAnTWlzc2luZyBleHBlY3RlZCBleGNlcHRpb24nICsgbWVzc2FnZSk7XG4gIH1cblxuICB2YXIgdXNlclByb3ZpZGVkTWVzc2FnZSA9IHR5cGVvZiBtZXNzYWdlID09PSAnc3RyaW5nJztcbiAgdmFyIGlzVW53YW50ZWRFeGNlcHRpb24gPSAhc2hvdWxkVGhyb3cgJiYgdXRpbC5pc0Vycm9yKGFjdHVhbCk7XG4gIHZhciBpc1VuZXhwZWN0ZWRFeGNlcHRpb24gPSAhc2hvdWxkVGhyb3cgJiYgYWN0dWFsICYmICFleHBlY3RlZDtcblxuICBpZiAoKGlzVW53YW50ZWRFeGNlcHRpb24gJiZcbiAgICAgIHVzZXJQcm92aWRlZE1lc3NhZ2UgJiZcbiAgICAgIGV4cGVjdGVkRXhjZXB0aW9uKGFjdHVhbCwgZXhwZWN0ZWQpKSB8fFxuICAgICAgaXNVbmV4cGVjdGVkRXhjZXB0aW9uKSB7XG4gICAgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCAnR290IHVud2FudGVkIGV4Y2VwdGlvbicgKyBtZXNzYWdlKTtcbiAgfVxuXG4gIGlmICgoc2hvdWxkVGhyb3cgJiYgYWN0dWFsICYmIGV4cGVjdGVkICYmXG4gICAgICAhZXhwZWN0ZWRFeGNlcHRpb24oYWN0dWFsLCBleHBlY3RlZCkpIHx8ICghc2hvdWxkVGhyb3cgJiYgYWN0dWFsKSkge1xuICAgIHRocm93IGFjdHVhbDtcbiAgfVxufVxuXG4vLyAxMS4gRXhwZWN0ZWQgdG8gdGhyb3cgYW4gZXJyb3I6XG4vLyBhc3NlcnQudGhyb3dzKGJsb2NrLCBFcnJvcl9vcHQsIG1lc3NhZ2Vfb3B0KTtcblxuYXNzZXJ0LnRocm93cyA9IGZ1bmN0aW9uKGJsb2NrLCAvKm9wdGlvbmFsKi9lcnJvciwgLypvcHRpb25hbCovbWVzc2FnZSkge1xuICBfdGhyb3dzKHRydWUsIGJsb2NrLCBlcnJvciwgbWVzc2FnZSk7XG59O1xuXG4vLyBFWFRFTlNJT04hIFRoaXMgaXMgYW5ub3lpbmcgdG8gd3JpdGUgb3V0c2lkZSB0aGlzIG1vZHVsZS5cbmFzc2VydC5kb2VzTm90VGhyb3cgPSBmdW5jdGlvbihibG9jaywgLypvcHRpb25hbCovZXJyb3IsIC8qb3B0aW9uYWwqL21lc3NhZ2UpIHtcbiAgX3Rocm93cyhmYWxzZSwgYmxvY2ssIGVycm9yLCBtZXNzYWdlKTtcbn07XG5cbmFzc2VydC5pZkVycm9yID0gZnVuY3Rpb24oZXJyKSB7IGlmIChlcnIpIHRocm93IGVycjsgfTtcblxuLy8gRXhwb3NlIGEgc3RyaWN0IG9ubHkgdmFyaWFudCBvZiBhc3NlcnRcbmZ1bmN0aW9uIHN0cmljdCh2YWx1ZSwgbWVzc2FnZSkge1xuICBpZiAoIXZhbHVlKSBmYWlsKHZhbHVlLCB0cnVlLCBtZXNzYWdlLCAnPT0nLCBzdHJpY3QpO1xufVxuYXNzZXJ0LnN0cmljdCA9IG9iamVjdEFzc2lnbihzdHJpY3QsIGFzc2VydCwge1xuICBlcXVhbDogYXNzZXJ0LnN0cmljdEVxdWFsLFxuICBkZWVwRXF1YWw6IGFzc2VydC5kZWVwU3RyaWN0RXF1YWwsXG4gIG5vdEVxdWFsOiBhc3NlcnQubm90U3RyaWN0RXF1YWwsXG4gIG5vdERlZXBFcXVhbDogYXNzZXJ0Lm5vdERlZXBTdHJpY3RFcXVhbFxufSk7XG5hc3NlcnQuc3RyaWN0LnN0cmljdCA9IGFzc2VydC5zdHJpY3Q7XG5cbnZhciBvYmplY3RLZXlzID0gT2JqZWN0LmtleXMgfHwgZnVuY3Rpb24gKG9iaikge1xuICB2YXIga2V5cyA9IFtdO1xuICBmb3IgKHZhciBrZXkgaW4gb2JqKSB7XG4gICAgaWYgKGhhc093bi5jYWxsKG9iaiwga2V5KSkga2V5cy5wdXNoKGtleSk7XG4gIH1cbiAgcmV0dXJuIGtleXM7XG59O1xuIiwiaWYgKHR5cGVvZiBPYmplY3QuY3JlYXRlID09PSAnZnVuY3Rpb24nKSB7XG4gIC8vIGltcGxlbWVudGF0aW9uIGZyb20gc3RhbmRhcmQgbm9kZS5qcyAndXRpbCcgbW9kdWxlXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICBjdG9yLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDdG9yLnByb3RvdHlwZSwge1xuICAgICAgY29uc3RydWN0b3I6IHtcbiAgICAgICAgdmFsdWU6IGN0b3IsXG4gICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgICB9XG4gICAgfSk7XG4gIH07XG59IGVsc2Uge1xuICAvLyBvbGQgc2Nob29sIHNoaW0gZm9yIG9sZCBicm93c2Vyc1xuICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGluaGVyaXRzKGN0b3IsIHN1cGVyQ3Rvcikge1xuICAgIGN0b3Iuc3VwZXJfID0gc3VwZXJDdG9yXG4gICAgdmFyIFRlbXBDdG9yID0gZnVuY3Rpb24gKCkge31cbiAgICBUZW1wQ3Rvci5wcm90b3R5cGUgPSBzdXBlckN0b3IucHJvdG90eXBlXG4gICAgY3Rvci5wcm90b3R5cGUgPSBuZXcgVGVtcEN0b3IoKVxuICAgIGN0b3IucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gY3RvclxuICB9XG59XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGlzQnVmZmVyKGFyZykge1xuICByZXR1cm4gYXJnICYmIHR5cGVvZiBhcmcgPT09ICdvYmplY3QnXG4gICAgJiYgdHlwZW9mIGFyZy5jb3B5ID09PSAnZnVuY3Rpb24nXG4gICAgJiYgdHlwZW9mIGFyZy5maWxsID09PSAnZnVuY3Rpb24nXG4gICAgJiYgdHlwZW9mIGFyZy5yZWFkVUludDggPT09ICdmdW5jdGlvbic7XG59IiwiLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbnZhciBmb3JtYXRSZWdFeHAgPSAvJVtzZGolXS9nO1xuZXhwb3J0cy5mb3JtYXQgPSBmdW5jdGlvbihmKSB7XG4gIGlmICghaXNTdHJpbmcoZikpIHtcbiAgICB2YXIgb2JqZWN0cyA9IFtdO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBvYmplY3RzLnB1c2goaW5zcGVjdChhcmd1bWVudHNbaV0pKTtcbiAgICB9XG4gICAgcmV0dXJuIG9iamVjdHMuam9pbignICcpO1xuICB9XG5cbiAgdmFyIGkgPSAxO1xuICB2YXIgYXJncyA9IGFyZ3VtZW50cztcbiAgdmFyIGxlbiA9IGFyZ3MubGVuZ3RoO1xuICB2YXIgc3RyID0gU3RyaW5nKGYpLnJlcGxhY2UoZm9ybWF0UmVnRXhwLCBmdW5jdGlvbih4KSB7XG4gICAgaWYgKHggPT09ICclJScpIHJldHVybiAnJSc7XG4gICAgaWYgKGkgPj0gbGVuKSByZXR1cm4geDtcbiAgICBzd2l0Y2ggKHgpIHtcbiAgICAgIGNhc2UgJyVzJzogcmV0dXJuIFN0cmluZyhhcmdzW2krK10pO1xuICAgICAgY2FzZSAnJWQnOiByZXR1cm4gTnVtYmVyKGFyZ3NbaSsrXSk7XG4gICAgICBjYXNlICclaic6XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KGFyZ3NbaSsrXSk7XG4gICAgICAgIH0gY2F0Y2ggKF8pIHtcbiAgICAgICAgICByZXR1cm4gJ1tDaXJjdWxhcl0nO1xuICAgICAgICB9XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4geDtcbiAgICB9XG4gIH0pO1xuICBmb3IgKHZhciB4ID0gYXJnc1tpXTsgaSA8IGxlbjsgeCA9IGFyZ3NbKytpXSkge1xuICAgIGlmIChpc051bGwoeCkgfHwgIWlzT2JqZWN0KHgpKSB7XG4gICAgICBzdHIgKz0gJyAnICsgeDtcbiAgICB9IGVsc2Uge1xuICAgICAgc3RyICs9ICcgJyArIGluc3BlY3QoeCk7XG4gICAgfVxuICB9XG4gIHJldHVybiBzdHI7XG59O1xuXG5cbi8vIE1hcmsgdGhhdCBhIG1ldGhvZCBzaG91bGQgbm90IGJlIHVzZWQuXG4vLyBSZXR1cm5zIGEgbW9kaWZpZWQgZnVuY3Rpb24gd2hpY2ggd2FybnMgb25jZSBieSBkZWZhdWx0LlxuLy8gSWYgLS1uby1kZXByZWNhdGlvbiBpcyBzZXQsIHRoZW4gaXQgaXMgYSBuby1vcC5cbmV4cG9ydHMuZGVwcmVjYXRlID0gZnVuY3Rpb24oZm4sIG1zZykge1xuICAvLyBBbGxvdyBmb3IgZGVwcmVjYXRpbmcgdGhpbmdzIGluIHRoZSBwcm9jZXNzIG9mIHN0YXJ0aW5nIHVwLlxuICBpZiAoaXNVbmRlZmluZWQoZ2xvYmFsLnByb2Nlc3MpKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIGV4cG9ydHMuZGVwcmVjYXRlKGZuLCBtc2cpLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfTtcbiAgfVxuXG4gIGlmIChwcm9jZXNzLm5vRGVwcmVjYXRpb24gPT09IHRydWUpIHtcbiAgICByZXR1cm4gZm47XG4gIH1cblxuICB2YXIgd2FybmVkID0gZmFsc2U7XG4gIGZ1bmN0aW9uIGRlcHJlY2F0ZWQoKSB7XG4gICAgaWYgKCF3YXJuZWQpIHtcbiAgICAgIGlmIChwcm9jZXNzLnRocm93RGVwcmVjYXRpb24pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1zZyk7XG4gICAgICB9IGVsc2UgaWYgKHByb2Nlc3MudHJhY2VEZXByZWNhdGlvbikge1xuICAgICAgICBjb25zb2xlLnRyYWNlKG1zZyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zb2xlLmVycm9yKG1zZyk7XG4gICAgICB9XG4gICAgICB3YXJuZWQgPSB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgfVxuXG4gIHJldHVybiBkZXByZWNhdGVkO1xufTtcblxuXG52YXIgZGVidWdzID0ge307XG52YXIgZGVidWdFbnZpcm9uO1xuZXhwb3J0cy5kZWJ1Z2xvZyA9IGZ1bmN0aW9uKHNldCkge1xuICBpZiAoaXNVbmRlZmluZWQoZGVidWdFbnZpcm9uKSlcbiAgICBkZWJ1Z0Vudmlyb24gPSBwcm9jZXNzLmVudi5OT0RFX0RFQlVHIHx8ICcnO1xuICBzZXQgPSBzZXQudG9VcHBlckNhc2UoKTtcbiAgaWYgKCFkZWJ1Z3Nbc2V0XSkge1xuICAgIGlmIChuZXcgUmVnRXhwKCdcXFxcYicgKyBzZXQgKyAnXFxcXGInLCAnaScpLnRlc3QoZGVidWdFbnZpcm9uKSkge1xuICAgICAgdmFyIHBpZCA9IHByb2Nlc3MucGlkO1xuICAgICAgZGVidWdzW3NldF0gPSBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIG1zZyA9IGV4cG9ydHMuZm9ybWF0LmFwcGx5KGV4cG9ydHMsIGFyZ3VtZW50cyk7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJyVzICVkOiAlcycsIHNldCwgcGlkLCBtc2cpO1xuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgZGVidWdzW3NldF0gPSBmdW5jdGlvbigpIHt9O1xuICAgIH1cbiAgfVxuICByZXR1cm4gZGVidWdzW3NldF07XG59O1xuXG5cbi8qKlxuICogRWNob3MgdGhlIHZhbHVlIG9mIGEgdmFsdWUuIFRyeXMgdG8gcHJpbnQgdGhlIHZhbHVlIG91dFxuICogaW4gdGhlIGJlc3Qgd2F5IHBvc3NpYmxlIGdpdmVuIHRoZSBkaWZmZXJlbnQgdHlwZXMuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9iaiBUaGUgb2JqZWN0IHRvIHByaW50IG91dC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRzIE9wdGlvbmFsIG9wdGlvbnMgb2JqZWN0IHRoYXQgYWx0ZXJzIHRoZSBvdXRwdXQuXG4gKi9cbi8qIGxlZ2FjeTogb2JqLCBzaG93SGlkZGVuLCBkZXB0aCwgY29sb3JzKi9cbmZ1bmN0aW9uIGluc3BlY3Qob2JqLCBvcHRzKSB7XG4gIC8vIGRlZmF1bHQgb3B0aW9uc1xuICB2YXIgY3R4ID0ge1xuICAgIHNlZW46IFtdLFxuICAgIHN0eWxpemU6IHN0eWxpemVOb0NvbG9yXG4gIH07XG4gIC8vIGxlZ2FjeS4uLlxuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+PSAzKSBjdHguZGVwdGggPSBhcmd1bWVudHNbMl07XG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID49IDQpIGN0eC5jb2xvcnMgPSBhcmd1bWVudHNbM107XG4gIGlmIChpc0Jvb2xlYW4ob3B0cykpIHtcbiAgICAvLyBsZWdhY3kuLi5cbiAgICBjdHguc2hvd0hpZGRlbiA9IG9wdHM7XG4gIH0gZWxzZSBpZiAob3B0cykge1xuICAgIC8vIGdvdCBhbiBcIm9wdGlvbnNcIiBvYmplY3RcbiAgICBleHBvcnRzLl9leHRlbmQoY3R4LCBvcHRzKTtcbiAgfVxuICAvLyBzZXQgZGVmYXVsdCBvcHRpb25zXG4gIGlmIChpc1VuZGVmaW5lZChjdHguc2hvd0hpZGRlbikpIGN0eC5zaG93SGlkZGVuID0gZmFsc2U7XG4gIGlmIChpc1VuZGVmaW5lZChjdHguZGVwdGgpKSBjdHguZGVwdGggPSAyO1xuICBpZiAoaXNVbmRlZmluZWQoY3R4LmNvbG9ycykpIGN0eC5jb2xvcnMgPSBmYWxzZTtcbiAgaWYgKGlzVW5kZWZpbmVkKGN0eC5jdXN0b21JbnNwZWN0KSkgY3R4LmN1c3RvbUluc3BlY3QgPSB0cnVlO1xuICBpZiAoY3R4LmNvbG9ycykgY3R4LnN0eWxpemUgPSBzdHlsaXplV2l0aENvbG9yO1xuICByZXR1cm4gZm9ybWF0VmFsdWUoY3R4LCBvYmosIGN0eC5kZXB0aCk7XG59XG5leHBvcnRzLmluc3BlY3QgPSBpbnNwZWN0O1xuXG5cbi8vIGh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQU5TSV9lc2NhcGVfY29kZSNncmFwaGljc1xuaW5zcGVjdC5jb2xvcnMgPSB7XG4gICdib2xkJyA6IFsxLCAyMl0sXG4gICdpdGFsaWMnIDogWzMsIDIzXSxcbiAgJ3VuZGVybGluZScgOiBbNCwgMjRdLFxuICAnaW52ZXJzZScgOiBbNywgMjddLFxuICAnd2hpdGUnIDogWzM3LCAzOV0sXG4gICdncmV5JyA6IFs5MCwgMzldLFxuICAnYmxhY2snIDogWzMwLCAzOV0sXG4gICdibHVlJyA6IFszNCwgMzldLFxuICAnY3lhbicgOiBbMzYsIDM5XSxcbiAgJ2dyZWVuJyA6IFszMiwgMzldLFxuICAnbWFnZW50YScgOiBbMzUsIDM5XSxcbiAgJ3JlZCcgOiBbMzEsIDM5XSxcbiAgJ3llbGxvdycgOiBbMzMsIDM5XVxufTtcblxuLy8gRG9uJ3QgdXNlICdibHVlJyBub3QgdmlzaWJsZSBvbiBjbWQuZXhlXG5pbnNwZWN0LnN0eWxlcyA9IHtcbiAgJ3NwZWNpYWwnOiAnY3lhbicsXG4gICdudW1iZXInOiAneWVsbG93JyxcbiAgJ2Jvb2xlYW4nOiAneWVsbG93JyxcbiAgJ3VuZGVmaW5lZCc6ICdncmV5JyxcbiAgJ251bGwnOiAnYm9sZCcsXG4gICdzdHJpbmcnOiAnZ3JlZW4nLFxuICAnZGF0ZSc6ICdtYWdlbnRhJyxcbiAgLy8gXCJuYW1lXCI6IGludGVudGlvbmFsbHkgbm90IHN0eWxpbmdcbiAgJ3JlZ2V4cCc6ICdyZWQnXG59O1xuXG5cbmZ1bmN0aW9uIHN0eWxpemVXaXRoQ29sb3Ioc3RyLCBzdHlsZVR5cGUpIHtcbiAgdmFyIHN0eWxlID0gaW5zcGVjdC5zdHlsZXNbc3R5bGVUeXBlXTtcblxuICBpZiAoc3R5bGUpIHtcbiAgICByZXR1cm4gJ1xcdTAwMWJbJyArIGluc3BlY3QuY29sb3JzW3N0eWxlXVswXSArICdtJyArIHN0ciArXG4gICAgICAgICAgICdcXHUwMDFiWycgKyBpbnNwZWN0LmNvbG9yc1tzdHlsZV1bMV0gKyAnbSc7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHN0cjtcbiAgfVxufVxuXG5cbmZ1bmN0aW9uIHN0eWxpemVOb0NvbG9yKHN0ciwgc3R5bGVUeXBlKSB7XG4gIHJldHVybiBzdHI7XG59XG5cblxuZnVuY3Rpb24gYXJyYXlUb0hhc2goYXJyYXkpIHtcbiAgdmFyIGhhc2ggPSB7fTtcblxuICBhcnJheS5mb3JFYWNoKGZ1bmN0aW9uKHZhbCwgaWR4KSB7XG4gICAgaGFzaFt2YWxdID0gdHJ1ZTtcbiAgfSk7XG5cbiAgcmV0dXJuIGhhc2g7XG59XG5cblxuZnVuY3Rpb24gZm9ybWF0VmFsdWUoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzKSB7XG4gIC8vIFByb3ZpZGUgYSBob29rIGZvciB1c2VyLXNwZWNpZmllZCBpbnNwZWN0IGZ1bmN0aW9ucy5cbiAgLy8gQ2hlY2sgdGhhdCB2YWx1ZSBpcyBhbiBvYmplY3Qgd2l0aCBhbiBpbnNwZWN0IGZ1bmN0aW9uIG9uIGl0XG4gIGlmIChjdHguY3VzdG9tSW5zcGVjdCAmJlxuICAgICAgdmFsdWUgJiZcbiAgICAgIGlzRnVuY3Rpb24odmFsdWUuaW5zcGVjdCkgJiZcbiAgICAgIC8vIEZpbHRlciBvdXQgdGhlIHV0aWwgbW9kdWxlLCBpdCdzIGluc3BlY3QgZnVuY3Rpb24gaXMgc3BlY2lhbFxuICAgICAgdmFsdWUuaW5zcGVjdCAhPT0gZXhwb3J0cy5pbnNwZWN0ICYmXG4gICAgICAvLyBBbHNvIGZpbHRlciBvdXQgYW55IHByb3RvdHlwZSBvYmplY3RzIHVzaW5nIHRoZSBjaXJjdWxhciBjaGVjay5cbiAgICAgICEodmFsdWUuY29uc3RydWN0b3IgJiYgdmFsdWUuY29uc3RydWN0b3IucHJvdG90eXBlID09PSB2YWx1ZSkpIHtcbiAgICB2YXIgcmV0ID0gdmFsdWUuaW5zcGVjdChyZWN1cnNlVGltZXMsIGN0eCk7XG4gICAgaWYgKCFpc1N0cmluZyhyZXQpKSB7XG4gICAgICByZXQgPSBmb3JtYXRWYWx1ZShjdHgsIHJldCwgcmVjdXJzZVRpbWVzKTtcbiAgICB9XG4gICAgcmV0dXJuIHJldDtcbiAgfVxuXG4gIC8vIFByaW1pdGl2ZSB0eXBlcyBjYW5ub3QgaGF2ZSBwcm9wZXJ0aWVzXG4gIHZhciBwcmltaXRpdmUgPSBmb3JtYXRQcmltaXRpdmUoY3R4LCB2YWx1ZSk7XG4gIGlmIChwcmltaXRpdmUpIHtcbiAgICByZXR1cm4gcHJpbWl0aXZlO1xuICB9XG5cbiAgLy8gTG9vayB1cCB0aGUga2V5cyBvZiB0aGUgb2JqZWN0LlxuICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKHZhbHVlKTtcbiAgdmFyIHZpc2libGVLZXlzID0gYXJyYXlUb0hhc2goa2V5cyk7XG5cbiAgaWYgKGN0eC5zaG93SGlkZGVuKSB7XG4gICAga2V5cyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHZhbHVlKTtcbiAgfVxuXG4gIC8vIElFIGRvZXNuJ3QgbWFrZSBlcnJvciBmaWVsZHMgbm9uLWVudW1lcmFibGVcbiAgLy8gaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbS9lbi11cy9saWJyYXJ5L2llL2R3dzUyc2J0KHY9dnMuOTQpLmFzcHhcbiAgaWYgKGlzRXJyb3IodmFsdWUpXG4gICAgICAmJiAoa2V5cy5pbmRleE9mKCdtZXNzYWdlJykgPj0gMCB8fCBrZXlzLmluZGV4T2YoJ2Rlc2NyaXB0aW9uJykgPj0gMCkpIHtcbiAgICByZXR1cm4gZm9ybWF0RXJyb3IodmFsdWUpO1xuICB9XG5cbiAgLy8gU29tZSB0eXBlIG9mIG9iamVjdCB3aXRob3V0IHByb3BlcnRpZXMgY2FuIGJlIHNob3J0Y3V0dGVkLlxuICBpZiAoa2V5cy5sZW5ndGggPT09IDApIHtcbiAgICBpZiAoaXNGdW5jdGlvbih2YWx1ZSkpIHtcbiAgICAgIHZhciBuYW1lID0gdmFsdWUubmFtZSA/ICc6ICcgKyB2YWx1ZS5uYW1lIDogJyc7XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoJ1tGdW5jdGlvbicgKyBuYW1lICsgJ10nLCAnc3BlY2lhbCcpO1xuICAgIH1cbiAgICBpZiAoaXNSZWdFeHAodmFsdWUpKSB7XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoUmVnRXhwLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKSwgJ3JlZ2V4cCcpO1xuICAgIH1cbiAgICBpZiAoaXNEYXRlKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKERhdGUucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpLCAnZGF0ZScpO1xuICAgIH1cbiAgICBpZiAoaXNFcnJvcih2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBmb3JtYXRFcnJvcih2YWx1ZSk7XG4gICAgfVxuICB9XG5cbiAgdmFyIGJhc2UgPSAnJywgYXJyYXkgPSBmYWxzZSwgYnJhY2VzID0gWyd7JywgJ30nXTtcblxuICAvLyBNYWtlIEFycmF5IHNheSB0aGF0IHRoZXkgYXJlIEFycmF5XG4gIGlmIChpc0FycmF5KHZhbHVlKSkge1xuICAgIGFycmF5ID0gdHJ1ZTtcbiAgICBicmFjZXMgPSBbJ1snLCAnXSddO1xuICB9XG5cbiAgLy8gTWFrZSBmdW5jdGlvbnMgc2F5IHRoYXQgdGhleSBhcmUgZnVuY3Rpb25zXG4gIGlmIChpc0Z1bmN0aW9uKHZhbHVlKSkge1xuICAgIHZhciBuID0gdmFsdWUubmFtZSA/ICc6ICcgKyB2YWx1ZS5uYW1lIDogJyc7XG4gICAgYmFzZSA9ICcgW0Z1bmN0aW9uJyArIG4gKyAnXSc7XG4gIH1cblxuICAvLyBNYWtlIFJlZ0V4cHMgc2F5IHRoYXQgdGhleSBhcmUgUmVnRXhwc1xuICBpZiAoaXNSZWdFeHAodmFsdWUpKSB7XG4gICAgYmFzZSA9ICcgJyArIFJlZ0V4cC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSk7XG4gIH1cblxuICAvLyBNYWtlIGRhdGVzIHdpdGggcHJvcGVydGllcyBmaXJzdCBzYXkgdGhlIGRhdGVcbiAgaWYgKGlzRGF0ZSh2YWx1ZSkpIHtcbiAgICBiYXNlID0gJyAnICsgRGF0ZS5wcm90b3R5cGUudG9VVENTdHJpbmcuY2FsbCh2YWx1ZSk7XG4gIH1cblxuICAvLyBNYWtlIGVycm9yIHdpdGggbWVzc2FnZSBmaXJzdCBzYXkgdGhlIGVycm9yXG4gIGlmIChpc0Vycm9yKHZhbHVlKSkge1xuICAgIGJhc2UgPSAnICcgKyBmb3JtYXRFcnJvcih2YWx1ZSk7XG4gIH1cblxuICBpZiAoa2V5cy5sZW5ndGggPT09IDAgJiYgKCFhcnJheSB8fCB2YWx1ZS5sZW5ndGggPT0gMCkpIHtcbiAgICByZXR1cm4gYnJhY2VzWzBdICsgYmFzZSArIGJyYWNlc1sxXTtcbiAgfVxuXG4gIGlmIChyZWN1cnNlVGltZXMgPCAwKSB7XG4gICAgaWYgKGlzUmVnRXhwKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKFJlZ0V4cC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSksICdyZWdleHAnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKCdbT2JqZWN0XScsICdzcGVjaWFsJyk7XG4gICAgfVxuICB9XG5cbiAgY3R4LnNlZW4ucHVzaCh2YWx1ZSk7XG5cbiAgdmFyIG91dHB1dDtcbiAgaWYgKGFycmF5KSB7XG4gICAgb3V0cHV0ID0gZm9ybWF0QXJyYXkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cywga2V5cyk7XG4gIH0gZWxzZSB7XG4gICAgb3V0cHV0ID0ga2V5cy5tYXAoZnVuY3Rpb24oa2V5KSB7XG4gICAgICByZXR1cm4gZm9ybWF0UHJvcGVydHkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cywga2V5LCBhcnJheSk7XG4gICAgfSk7XG4gIH1cblxuICBjdHguc2Vlbi5wb3AoKTtcblxuICByZXR1cm4gcmVkdWNlVG9TaW5nbGVTdHJpbmcob3V0cHV0LCBiYXNlLCBicmFjZXMpO1xufVxuXG5cbmZ1bmN0aW9uIGZvcm1hdFByaW1pdGl2ZShjdHgsIHZhbHVlKSB7XG4gIGlmIChpc1VuZGVmaW5lZCh2YWx1ZSkpXG4gICAgcmV0dXJuIGN0eC5zdHlsaXplKCd1bmRlZmluZWQnLCAndW5kZWZpbmVkJyk7XG4gIGlmIChpc1N0cmluZyh2YWx1ZSkpIHtcbiAgICB2YXIgc2ltcGxlID0gJ1xcJycgKyBKU09OLnN0cmluZ2lmeSh2YWx1ZSkucmVwbGFjZSgvXlwifFwiJC9nLCAnJylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5yZXBsYWNlKC8nL2csIFwiXFxcXCdcIilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5yZXBsYWNlKC9cXFxcXCIvZywgJ1wiJykgKyAnXFwnJztcbiAgICByZXR1cm4gY3R4LnN0eWxpemUoc2ltcGxlLCAnc3RyaW5nJyk7XG4gIH1cbiAgaWYgKGlzTnVtYmVyKHZhbHVlKSlcbiAgICByZXR1cm4gY3R4LnN0eWxpemUoJycgKyB2YWx1ZSwgJ251bWJlcicpO1xuICBpZiAoaXNCb29sZWFuKHZhbHVlKSlcbiAgICByZXR1cm4gY3R4LnN0eWxpemUoJycgKyB2YWx1ZSwgJ2Jvb2xlYW4nKTtcbiAgLy8gRm9yIHNvbWUgcmVhc29uIHR5cGVvZiBudWxsIGlzIFwib2JqZWN0XCIsIHNvIHNwZWNpYWwgY2FzZSBoZXJlLlxuICBpZiAoaXNOdWxsKHZhbHVlKSlcbiAgICByZXR1cm4gY3R4LnN0eWxpemUoJ251bGwnLCAnbnVsbCcpO1xufVxuXG5cbmZ1bmN0aW9uIGZvcm1hdEVycm9yKHZhbHVlKSB7XG4gIHJldHVybiAnWycgKyBFcnJvci5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSkgKyAnXSc7XG59XG5cblxuZnVuY3Rpb24gZm9ybWF0QXJyYXkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cywga2V5cykge1xuICB2YXIgb3V0cHV0ID0gW107XG4gIGZvciAodmFyIGkgPSAwLCBsID0gdmFsdWUubGVuZ3RoOyBpIDwgbDsgKytpKSB7XG4gICAgaWYgKGhhc093blByb3BlcnR5KHZhbHVlLCBTdHJpbmcoaSkpKSB7XG4gICAgICBvdXRwdXQucHVzaChmb3JtYXRQcm9wZXJ0eShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLFxuICAgICAgICAgIFN0cmluZyhpKSwgdHJ1ZSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBvdXRwdXQucHVzaCgnJyk7XG4gICAgfVxuICB9XG4gIGtleXMuZm9yRWFjaChmdW5jdGlvbihrZXkpIHtcbiAgICBpZiAoIWtleS5tYXRjaCgvXlxcZCskLykpIHtcbiAgICAgIG91dHB1dC5wdXNoKGZvcm1hdFByb3BlcnR5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsXG4gICAgICAgICAga2V5LCB0cnVlKSk7XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIG91dHB1dDtcbn1cblxuXG5mdW5jdGlvbiBmb3JtYXRQcm9wZXJ0eShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLCBrZXksIGFycmF5KSB7XG4gIHZhciBuYW1lLCBzdHIsIGRlc2M7XG4gIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHZhbHVlLCBrZXkpIHx8IHsgdmFsdWU6IHZhbHVlW2tleV0gfTtcbiAgaWYgKGRlc2MuZ2V0KSB7XG4gICAgaWYgKGRlc2Muc2V0KSB7XG4gICAgICBzdHIgPSBjdHguc3R5bGl6ZSgnW0dldHRlci9TZXR0ZXJdJywgJ3NwZWNpYWwnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc3RyID0gY3R4LnN0eWxpemUoJ1tHZXR0ZXJdJywgJ3NwZWNpYWwnKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaWYgKGRlc2Muc2V0KSB7XG4gICAgICBzdHIgPSBjdHguc3R5bGl6ZSgnW1NldHRlcl0nLCAnc3BlY2lhbCcpO1xuICAgIH1cbiAgfVxuICBpZiAoIWhhc093blByb3BlcnR5KHZpc2libGVLZXlzLCBrZXkpKSB7XG4gICAgbmFtZSA9ICdbJyArIGtleSArICddJztcbiAgfVxuICBpZiAoIXN0cikge1xuICAgIGlmIChjdHguc2Vlbi5pbmRleE9mKGRlc2MudmFsdWUpIDwgMCkge1xuICAgICAgaWYgKGlzTnVsbChyZWN1cnNlVGltZXMpKSB7XG4gICAgICAgIHN0ciA9IGZvcm1hdFZhbHVlKGN0eCwgZGVzYy52YWx1ZSwgbnVsbCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdHIgPSBmb3JtYXRWYWx1ZShjdHgsIGRlc2MudmFsdWUsIHJlY3Vyc2VUaW1lcyAtIDEpO1xuICAgICAgfVxuICAgICAgaWYgKHN0ci5pbmRleE9mKCdcXG4nKSA+IC0xKSB7XG4gICAgICAgIGlmIChhcnJheSkge1xuICAgICAgICAgIHN0ciA9IHN0ci5zcGxpdCgnXFxuJykubWFwKGZ1bmN0aW9uKGxpbmUpIHtcbiAgICAgICAgICAgIHJldHVybiAnICAnICsgbGluZTtcbiAgICAgICAgICB9KS5qb2luKCdcXG4nKS5zdWJzdHIoMik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc3RyID0gJ1xcbicgKyBzdHIuc3BsaXQoJ1xcbicpLm1hcChmdW5jdGlvbihsaW5lKSB7XG4gICAgICAgICAgICByZXR1cm4gJyAgICcgKyBsaW5lO1xuICAgICAgICAgIH0pLmpvaW4oJ1xcbicpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0ciA9IGN0eC5zdHlsaXplKCdbQ2lyY3VsYXJdJywgJ3NwZWNpYWwnKTtcbiAgICB9XG4gIH1cbiAgaWYgKGlzVW5kZWZpbmVkKG5hbWUpKSB7XG4gICAgaWYgKGFycmF5ICYmIGtleS5tYXRjaCgvXlxcZCskLykpIHtcbiAgICAgIHJldHVybiBzdHI7XG4gICAgfVxuICAgIG5hbWUgPSBKU09OLnN0cmluZ2lmeSgnJyArIGtleSk7XG4gICAgaWYgKG5hbWUubWF0Y2goL15cIihbYS16QS1aX11bYS16QS1aXzAtOV0qKVwiJC8pKSB7XG4gICAgICBuYW1lID0gbmFtZS5zdWJzdHIoMSwgbmFtZS5sZW5ndGggLSAyKTtcbiAgICAgIG5hbWUgPSBjdHguc3R5bGl6ZShuYW1lLCAnbmFtZScpO1xuICAgIH0gZWxzZSB7XG4gICAgICBuYW1lID0gbmFtZS5yZXBsYWNlKC8nL2csIFwiXFxcXCdcIilcbiAgICAgICAgICAgICAgICAgLnJlcGxhY2UoL1xcXFxcIi9nLCAnXCInKVxuICAgICAgICAgICAgICAgICAucmVwbGFjZSgvKF5cInxcIiQpL2csIFwiJ1wiKTtcbiAgICAgIG5hbWUgPSBjdHguc3R5bGl6ZShuYW1lLCAnc3RyaW5nJyk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG5hbWUgKyAnOiAnICsgc3RyO1xufVxuXG5cbmZ1bmN0aW9uIHJlZHVjZVRvU2luZ2xlU3RyaW5nKG91dHB1dCwgYmFzZSwgYnJhY2VzKSB7XG4gIHZhciBudW1MaW5lc0VzdCA9IDA7XG4gIHZhciBsZW5ndGggPSBvdXRwdXQucmVkdWNlKGZ1bmN0aW9uKHByZXYsIGN1cikge1xuICAgIG51bUxpbmVzRXN0Kys7XG4gICAgaWYgKGN1ci5pbmRleE9mKCdcXG4nKSA+PSAwKSBudW1MaW5lc0VzdCsrO1xuICAgIHJldHVybiBwcmV2ICsgY3VyLnJlcGxhY2UoL1xcdTAwMWJcXFtcXGRcXGQ/bS9nLCAnJykubGVuZ3RoICsgMTtcbiAgfSwgMCk7XG5cbiAgaWYgKGxlbmd0aCA+IDYwKSB7XG4gICAgcmV0dXJuIGJyYWNlc1swXSArXG4gICAgICAgICAgIChiYXNlID09PSAnJyA/ICcnIDogYmFzZSArICdcXG4gJykgK1xuICAgICAgICAgICAnICcgK1xuICAgICAgICAgICBvdXRwdXQuam9pbignLFxcbiAgJykgK1xuICAgICAgICAgICAnICcgK1xuICAgICAgICAgICBicmFjZXNbMV07XG4gIH1cblxuICByZXR1cm4gYnJhY2VzWzBdICsgYmFzZSArICcgJyArIG91dHB1dC5qb2luKCcsICcpICsgJyAnICsgYnJhY2VzWzFdO1xufVxuXG5cbi8vIE5PVEU6IFRoZXNlIHR5cGUgY2hlY2tpbmcgZnVuY3Rpb25zIGludGVudGlvbmFsbHkgZG9uJ3QgdXNlIGBpbnN0YW5jZW9mYFxuLy8gYmVjYXVzZSBpdCBpcyBmcmFnaWxlIGFuZCBjYW4gYmUgZWFzaWx5IGZha2VkIHdpdGggYE9iamVjdC5jcmVhdGUoKWAuXG5mdW5jdGlvbiBpc0FycmF5KGFyKSB7XG4gIHJldHVybiBBcnJheS5pc0FycmF5KGFyKTtcbn1cbmV4cG9ydHMuaXNBcnJheSA9IGlzQXJyYXk7XG5cbmZ1bmN0aW9uIGlzQm9vbGVhbihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdib29sZWFuJztcbn1cbmV4cG9ydHMuaXNCb29sZWFuID0gaXNCb29sZWFuO1xuXG5mdW5jdGlvbiBpc051bGwoYXJnKSB7XG4gIHJldHVybiBhcmcgPT09IG51bGw7XG59XG5leHBvcnRzLmlzTnVsbCA9IGlzTnVsbDtcblxuZnVuY3Rpb24gaXNOdWxsT3JVbmRlZmluZWQoYXJnKSB7XG4gIHJldHVybiBhcmcgPT0gbnVsbDtcbn1cbmV4cG9ydHMuaXNOdWxsT3JVbmRlZmluZWQgPSBpc051bGxPclVuZGVmaW5lZDtcblxuZnVuY3Rpb24gaXNOdW1iZXIoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnbnVtYmVyJztcbn1cbmV4cG9ydHMuaXNOdW1iZXIgPSBpc051bWJlcjtcblxuZnVuY3Rpb24gaXNTdHJpbmcoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnc3RyaW5nJztcbn1cbmV4cG9ydHMuaXNTdHJpbmcgPSBpc1N0cmluZztcblxuZnVuY3Rpb24gaXNTeW1ib2woYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnc3ltYm9sJztcbn1cbmV4cG9ydHMuaXNTeW1ib2wgPSBpc1N5bWJvbDtcblxuZnVuY3Rpb24gaXNVbmRlZmluZWQoYXJnKSB7XG4gIHJldHVybiBhcmcgPT09IHZvaWQgMDtcbn1cbmV4cG9ydHMuaXNVbmRlZmluZWQgPSBpc1VuZGVmaW5lZDtcblxuZnVuY3Rpb24gaXNSZWdFeHAocmUpIHtcbiAgcmV0dXJuIGlzT2JqZWN0KHJlKSAmJiBvYmplY3RUb1N0cmluZyhyZSkgPT09ICdbb2JqZWN0IFJlZ0V4cF0nO1xufVxuZXhwb3J0cy5pc1JlZ0V4cCA9IGlzUmVnRXhwO1xuXG5mdW5jdGlvbiBpc09iamVjdChhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdvYmplY3QnICYmIGFyZyAhPT0gbnVsbDtcbn1cbmV4cG9ydHMuaXNPYmplY3QgPSBpc09iamVjdDtcblxuZnVuY3Rpb24gaXNEYXRlKGQpIHtcbiAgcmV0dXJuIGlzT2JqZWN0KGQpICYmIG9iamVjdFRvU3RyaW5nKGQpID09PSAnW29iamVjdCBEYXRlXSc7XG59XG5leHBvcnRzLmlzRGF0ZSA9IGlzRGF0ZTtcblxuZnVuY3Rpb24gaXNFcnJvcihlKSB7XG4gIHJldHVybiBpc09iamVjdChlKSAmJlxuICAgICAgKG9iamVjdFRvU3RyaW5nKGUpID09PSAnW29iamVjdCBFcnJvcl0nIHx8IGUgaW5zdGFuY2VvZiBFcnJvcik7XG59XG5leHBvcnRzLmlzRXJyb3IgPSBpc0Vycm9yO1xuXG5mdW5jdGlvbiBpc0Z1bmN0aW9uKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ2Z1bmN0aW9uJztcbn1cbmV4cG9ydHMuaXNGdW5jdGlvbiA9IGlzRnVuY3Rpb247XG5cbmZ1bmN0aW9uIGlzUHJpbWl0aXZlKGFyZykge1xuICByZXR1cm4gYXJnID09PSBudWxsIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnYm9vbGVhbicgfHxcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICdudW1iZXInIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnc3RyaW5nJyB8fFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ3N5bWJvbCcgfHwgIC8vIEVTNiBzeW1ib2xcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICd1bmRlZmluZWQnO1xufVxuZXhwb3J0cy5pc1ByaW1pdGl2ZSA9IGlzUHJpbWl0aXZlO1xuXG5leHBvcnRzLmlzQnVmZmVyID0gcmVxdWlyZSgnLi9zdXBwb3J0L2lzQnVmZmVyJyk7XG5cbmZ1bmN0aW9uIG9iamVjdFRvU3RyaW5nKG8pIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvKTtcbn1cblxuXG5mdW5jdGlvbiBwYWQobikge1xuICByZXR1cm4gbiA8IDEwID8gJzAnICsgbi50b1N0cmluZygxMCkgOiBuLnRvU3RyaW5nKDEwKTtcbn1cblxuXG52YXIgbW9udGhzID0gWydKYW4nLCAnRmViJywgJ01hcicsICdBcHInLCAnTWF5JywgJ0p1bicsICdKdWwnLCAnQXVnJywgJ1NlcCcsXG4gICAgICAgICAgICAgICdPY3QnLCAnTm92JywgJ0RlYyddO1xuXG4vLyAyNiBGZWIgMTY6MTk6MzRcbmZ1bmN0aW9uIHRpbWVzdGFtcCgpIHtcbiAgdmFyIGQgPSBuZXcgRGF0ZSgpO1xuICB2YXIgdGltZSA9IFtwYWQoZC5nZXRIb3VycygpKSxcbiAgICAgICAgICAgICAgcGFkKGQuZ2V0TWludXRlcygpKSxcbiAgICAgICAgICAgICAgcGFkKGQuZ2V0U2Vjb25kcygpKV0uam9pbignOicpO1xuICByZXR1cm4gW2QuZ2V0RGF0ZSgpLCBtb250aHNbZC5nZXRNb250aCgpXSwgdGltZV0uam9pbignICcpO1xufVxuXG5cbi8vIGxvZyBpcyBqdXN0IGEgdGhpbiB3cmFwcGVyIHRvIGNvbnNvbGUubG9nIHRoYXQgcHJlcGVuZHMgYSB0aW1lc3RhbXBcbmV4cG9ydHMubG9nID0gZnVuY3Rpb24oKSB7XG4gIGNvbnNvbGUubG9nKCclcyAtICVzJywgdGltZXN0YW1wKCksIGV4cG9ydHMuZm9ybWF0LmFwcGx5KGV4cG9ydHMsIGFyZ3VtZW50cykpO1xufTtcblxuXG4vKipcbiAqIEluaGVyaXQgdGhlIHByb3RvdHlwZSBtZXRob2RzIGZyb20gb25lIGNvbnN0cnVjdG9yIGludG8gYW5vdGhlci5cbiAqXG4gKiBUaGUgRnVuY3Rpb24ucHJvdG90eXBlLmluaGVyaXRzIGZyb20gbGFuZy5qcyByZXdyaXR0ZW4gYXMgYSBzdGFuZGFsb25lXG4gKiBmdW5jdGlvbiAobm90IG9uIEZ1bmN0aW9uLnByb3RvdHlwZSkuIE5PVEU6IElmIHRoaXMgZmlsZSBpcyB0byBiZSBsb2FkZWRcbiAqIGR1cmluZyBib290c3RyYXBwaW5nIHRoaXMgZnVuY3Rpb24gbmVlZHMgdG8gYmUgcmV3cml0dGVuIHVzaW5nIHNvbWUgbmF0aXZlXG4gKiBmdW5jdGlvbnMgYXMgcHJvdG90eXBlIHNldHVwIHVzaW5nIG5vcm1hbCBKYXZhU2NyaXB0IGRvZXMgbm90IHdvcmsgYXNcbiAqIGV4cGVjdGVkIGR1cmluZyBib290c3RyYXBwaW5nIChzZWUgbWlycm9yLmpzIGluIHIxMTQ5MDMpLlxuICpcbiAqIEBwYXJhbSB7ZnVuY3Rpb259IGN0b3IgQ29uc3RydWN0b3IgZnVuY3Rpb24gd2hpY2ggbmVlZHMgdG8gaW5oZXJpdCB0aGVcbiAqICAgICBwcm90b3R5cGUuXG4gKiBAcGFyYW0ge2Z1bmN0aW9ufSBzdXBlckN0b3IgQ29uc3RydWN0b3IgZnVuY3Rpb24gdG8gaW5oZXJpdCBwcm90b3R5cGUgZnJvbS5cbiAqL1xuZXhwb3J0cy5pbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG5cbmV4cG9ydHMuX2V4dGVuZCA9IGZ1bmN0aW9uKG9yaWdpbiwgYWRkKSB7XG4gIC8vIERvbid0IGRvIGFueXRoaW5nIGlmIGFkZCBpc24ndCBhbiBvYmplY3RcbiAgaWYgKCFhZGQgfHwgIWlzT2JqZWN0KGFkZCkpIHJldHVybiBvcmlnaW47XG5cbiAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhhZGQpO1xuICB2YXIgaSA9IGtleXMubGVuZ3RoO1xuICB3aGlsZSAoaS0tKSB7XG4gICAgb3JpZ2luW2tleXNbaV1dID0gYWRkW2tleXNbaV1dO1xuICB9XG4gIHJldHVybiBvcmlnaW47XG59O1xuXG5mdW5jdGlvbiBoYXNPd25Qcm9wZXJ0eShvYmosIHByb3ApIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIHByb3ApO1xufVxuIiwiJ3VzZSBzdHJpY3QnXG5cbmV4cG9ydHMuYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGhcbmV4cG9ydHMudG9CeXRlQXJyYXkgPSB0b0J5dGVBcnJheVxuZXhwb3J0cy5mcm9tQnl0ZUFycmF5ID0gZnJvbUJ5dGVBcnJheVxuXG52YXIgbG9va3VwID0gW11cbnZhciByZXZMb29rdXAgPSBbXVxudmFyIEFyciA9IHR5cGVvZiBVaW50OEFycmF5ICE9PSAndW5kZWZpbmVkJyA/IFVpbnQ4QXJyYXkgOiBBcnJheVxuXG52YXIgY29kZSA9ICdBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvJ1xuZm9yICh2YXIgaSA9IDAsIGxlbiA9IGNvZGUubGVuZ3RoOyBpIDwgbGVuOyArK2kpIHtcbiAgbG9va3VwW2ldID0gY29kZVtpXVxuICByZXZMb29rdXBbY29kZS5jaGFyQ29kZUF0KGkpXSA9IGlcbn1cblxuLy8gU3VwcG9ydCBkZWNvZGluZyBVUkwtc2FmZSBiYXNlNjQgc3RyaW5ncywgYXMgTm9kZS5qcyBkb2VzLlxuLy8gU2VlOiBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9CYXNlNjQjVVJMX2FwcGxpY2F0aW9uc1xucmV2TG9va3VwWyctJy5jaGFyQ29kZUF0KDApXSA9IDYyXG5yZXZMb29rdXBbJ18nLmNoYXJDb2RlQXQoMCldID0gNjNcblxuZnVuY3Rpb24gZ2V0TGVucyAoYjY0KSB7XG4gIHZhciBsZW4gPSBiNjQubGVuZ3RoXG5cbiAgaWYgKGxlbiAlIDQgPiAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHN0cmluZy4gTGVuZ3RoIG11c3QgYmUgYSBtdWx0aXBsZSBvZiA0JylcbiAgfVxuXG4gIC8vIFRyaW0gb2ZmIGV4dHJhIGJ5dGVzIGFmdGVyIHBsYWNlaG9sZGVyIGJ5dGVzIGFyZSBmb3VuZFxuICAvLyBTZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9iZWF0Z2FtbWl0L2Jhc2U2NC1qcy9pc3N1ZXMvNDJcbiAgdmFyIHZhbGlkTGVuID0gYjY0LmluZGV4T2YoJz0nKVxuICBpZiAodmFsaWRMZW4gPT09IC0xKSB2YWxpZExlbiA9IGxlblxuXG4gIHZhciBwbGFjZUhvbGRlcnNMZW4gPSB2YWxpZExlbiA9PT0gbGVuXG4gICAgPyAwXG4gICAgOiA0IC0gKHZhbGlkTGVuICUgNClcblxuICByZXR1cm4gW3ZhbGlkTGVuLCBwbGFjZUhvbGRlcnNMZW5dXG59XG5cbi8vIGJhc2U2NCBpcyA0LzMgKyB1cCB0byB0d28gY2hhcmFjdGVycyBvZiB0aGUgb3JpZ2luYWwgZGF0YVxuZnVuY3Rpb24gYnl0ZUxlbmd0aCAoYjY0KSB7XG4gIHZhciBsZW5zID0gZ2V0TGVucyhiNjQpXG4gIHZhciB2YWxpZExlbiA9IGxlbnNbMF1cbiAgdmFyIHBsYWNlSG9sZGVyc0xlbiA9IGxlbnNbMV1cbiAgcmV0dXJuICgodmFsaWRMZW4gKyBwbGFjZUhvbGRlcnNMZW4pICogMyAvIDQpIC0gcGxhY2VIb2xkZXJzTGVuXG59XG5cbmZ1bmN0aW9uIF9ieXRlTGVuZ3RoIChiNjQsIHZhbGlkTGVuLCBwbGFjZUhvbGRlcnNMZW4pIHtcbiAgcmV0dXJuICgodmFsaWRMZW4gKyBwbGFjZUhvbGRlcnNMZW4pICogMyAvIDQpIC0gcGxhY2VIb2xkZXJzTGVuXG59XG5cbmZ1bmN0aW9uIHRvQnl0ZUFycmF5IChiNjQpIHtcbiAgdmFyIHRtcFxuICB2YXIgbGVucyA9IGdldExlbnMoYjY0KVxuICB2YXIgdmFsaWRMZW4gPSBsZW5zWzBdXG4gIHZhciBwbGFjZUhvbGRlcnNMZW4gPSBsZW5zWzFdXG5cbiAgdmFyIGFyciA9IG5ldyBBcnIoX2J5dGVMZW5ndGgoYjY0LCB2YWxpZExlbiwgcGxhY2VIb2xkZXJzTGVuKSlcblxuICB2YXIgY3VyQnl0ZSA9IDBcblxuICAvLyBpZiB0aGVyZSBhcmUgcGxhY2Vob2xkZXJzLCBvbmx5IGdldCB1cCB0byB0aGUgbGFzdCBjb21wbGV0ZSA0IGNoYXJzXG4gIHZhciBsZW4gPSBwbGFjZUhvbGRlcnNMZW4gPiAwXG4gICAgPyB2YWxpZExlbiAtIDRcbiAgICA6IHZhbGlkTGVuXG5cbiAgdmFyIGlcbiAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSArPSA0KSB7XG4gICAgdG1wID1cbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSldIDw8IDE4KSB8XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkgKyAxKV0gPDwgMTIpIHxcbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDIpXSA8PCA2KSB8XG4gICAgICByZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDMpXVxuICAgIGFycltjdXJCeXRlKytdID0gKHRtcCA+PiAxNikgJiAweEZGXG4gICAgYXJyW2N1ckJ5dGUrK10gPSAodG1wID4+IDgpICYgMHhGRlxuICAgIGFycltjdXJCeXRlKytdID0gdG1wICYgMHhGRlxuICB9XG5cbiAgaWYgKHBsYWNlSG9sZGVyc0xlbiA9PT0gMikge1xuICAgIHRtcCA9XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkpXSA8PCAyKSB8XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkgKyAxKV0gPj4gNClcbiAgICBhcnJbY3VyQnl0ZSsrXSA9IHRtcCAmIDB4RkZcbiAgfVxuXG4gIGlmIChwbGFjZUhvbGRlcnNMZW4gPT09IDEpIHtcbiAgICB0bXAgPVxuICAgICAgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpKV0gPDwgMTApIHxcbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDEpXSA8PCA0KSB8XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkgKyAyKV0gPj4gMilcbiAgICBhcnJbY3VyQnl0ZSsrXSA9ICh0bXAgPj4gOCkgJiAweEZGXG4gICAgYXJyW2N1ckJ5dGUrK10gPSB0bXAgJiAweEZGXG4gIH1cblxuICByZXR1cm4gYXJyXG59XG5cbmZ1bmN0aW9uIHRyaXBsZXRUb0Jhc2U2NCAobnVtKSB7XG4gIHJldHVybiBsb29rdXBbbnVtID4+IDE4ICYgMHgzRl0gK1xuICAgIGxvb2t1cFtudW0gPj4gMTIgJiAweDNGXSArXG4gICAgbG9va3VwW251bSA+PiA2ICYgMHgzRl0gK1xuICAgIGxvb2t1cFtudW0gJiAweDNGXVxufVxuXG5mdW5jdGlvbiBlbmNvZGVDaHVuayAodWludDgsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIHRtcFxuICB2YXIgb3V0cHV0ID0gW11cbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpICs9IDMpIHtcbiAgICB0bXAgPVxuICAgICAgKCh1aW50OFtpXSA8PCAxNikgJiAweEZGMDAwMCkgK1xuICAgICAgKCh1aW50OFtpICsgMV0gPDwgOCkgJiAweEZGMDApICtcbiAgICAgICh1aW50OFtpICsgMl0gJiAweEZGKVxuICAgIG91dHB1dC5wdXNoKHRyaXBsZXRUb0Jhc2U2NCh0bXApKVxuICB9XG4gIHJldHVybiBvdXRwdXQuam9pbignJylcbn1cblxuZnVuY3Rpb24gZnJvbUJ5dGVBcnJheSAodWludDgpIHtcbiAgdmFyIHRtcFxuICB2YXIgbGVuID0gdWludDgubGVuZ3RoXG4gIHZhciBleHRyYUJ5dGVzID0gbGVuICUgMyAvLyBpZiB3ZSBoYXZlIDEgYnl0ZSBsZWZ0LCBwYWQgMiBieXRlc1xuICB2YXIgcGFydHMgPSBbXVxuICB2YXIgbWF4Q2h1bmtMZW5ndGggPSAxNjM4MyAvLyBtdXN0IGJlIG11bHRpcGxlIG9mIDNcblxuICAvLyBnbyB0aHJvdWdoIHRoZSBhcnJheSBldmVyeSB0aHJlZSBieXRlcywgd2UnbGwgZGVhbCB3aXRoIHRyYWlsaW5nIHN0dWZmIGxhdGVyXG4gIGZvciAodmFyIGkgPSAwLCBsZW4yID0gbGVuIC0gZXh0cmFCeXRlczsgaSA8IGxlbjI7IGkgKz0gbWF4Q2h1bmtMZW5ndGgpIHtcbiAgICBwYXJ0cy5wdXNoKGVuY29kZUNodW5rKHVpbnQ4LCBpLCAoaSArIG1heENodW5rTGVuZ3RoKSA+IGxlbjIgPyBsZW4yIDogKGkgKyBtYXhDaHVua0xlbmd0aCkpKVxuICB9XG5cbiAgLy8gcGFkIHRoZSBlbmQgd2l0aCB6ZXJvcywgYnV0IG1ha2Ugc3VyZSB0byBub3QgZm9yZ2V0IHRoZSBleHRyYSBieXRlc1xuICBpZiAoZXh0cmFCeXRlcyA9PT0gMSkge1xuICAgIHRtcCA9IHVpbnQ4W2xlbiAtIDFdXG4gICAgcGFydHMucHVzaChcbiAgICAgIGxvb2t1cFt0bXAgPj4gMl0gK1xuICAgICAgbG9va3VwWyh0bXAgPDwgNCkgJiAweDNGXSArXG4gICAgICAnPT0nXG4gICAgKVxuICB9IGVsc2UgaWYgKGV4dHJhQnl0ZXMgPT09IDIpIHtcbiAgICB0bXAgPSAodWludDhbbGVuIC0gMl0gPDwgOCkgKyB1aW50OFtsZW4gLSAxXVxuICAgIHBhcnRzLnB1c2goXG4gICAgICBsb29rdXBbdG1wID4+IDEwXSArXG4gICAgICBsb29rdXBbKHRtcCA+PiA0KSAmIDB4M0ZdICtcbiAgICAgIGxvb2t1cFsodG1wIDw8IDIpICYgMHgzRl0gK1xuICAgICAgJz0nXG4gICAgKVxuICB9XG5cbiAgcmV0dXJuIHBhcnRzLmpvaW4oJycpXG59XG4iLCIvKiFcbiAqIFRoZSBidWZmZXIgbW9kdWxlIGZyb20gbm9kZS5qcywgZm9yIHRoZSBicm93c2VyLlxuICpcbiAqIEBhdXRob3IgICBGZXJvc3MgQWJvdWtoYWRpamVoIDxodHRwczovL2Zlcm9zcy5vcmc+XG4gKiBAbGljZW5zZSAgTUlUXG4gKi9cbi8qIGVzbGludC1kaXNhYmxlIG5vLXByb3RvICovXG5cbid1c2Ugc3RyaWN0J1xuXG52YXIgYmFzZTY0ID0gcmVxdWlyZSgnYmFzZTY0LWpzJylcbnZhciBpZWVlNzU0ID0gcmVxdWlyZSgnaWVlZTc1NCcpXG5cbmV4cG9ydHMuQnVmZmVyID0gQnVmZmVyXG5leHBvcnRzLlNsb3dCdWZmZXIgPSBTbG93QnVmZmVyXG5leHBvcnRzLklOU1BFQ1RfTUFYX0JZVEVTID0gNTBcblxudmFyIEtfTUFYX0xFTkdUSCA9IDB4N2ZmZmZmZmZcbmV4cG9ydHMua01heExlbmd0aCA9IEtfTUFYX0xFTkdUSFxuXG4vKipcbiAqIElmIGBCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVGA6XG4gKiAgID09PSB0cnVlICAgIFVzZSBVaW50OEFycmF5IGltcGxlbWVudGF0aW9uIChmYXN0ZXN0KVxuICogICA9PT0gZmFsc2UgICBQcmludCB3YXJuaW5nIGFuZCByZWNvbW1lbmQgdXNpbmcgYGJ1ZmZlcmAgdjQueCB3aGljaCBoYXMgYW4gT2JqZWN0XG4gKiAgICAgICAgICAgICAgIGltcGxlbWVudGF0aW9uIChtb3N0IGNvbXBhdGlibGUsIGV2ZW4gSUU2KVxuICpcbiAqIEJyb3dzZXJzIHRoYXQgc3VwcG9ydCB0eXBlZCBhcnJheXMgYXJlIElFIDEwKywgRmlyZWZveCA0KywgQ2hyb21lIDcrLCBTYWZhcmkgNS4xKyxcbiAqIE9wZXJhIDExLjYrLCBpT1MgNC4yKy5cbiAqXG4gKiBXZSByZXBvcnQgdGhhdCB0aGUgYnJvd3NlciBkb2VzIG5vdCBzdXBwb3J0IHR5cGVkIGFycmF5cyBpZiB0aGUgYXJlIG5vdCBzdWJjbGFzc2FibGVcbiAqIHVzaW5nIF9fcHJvdG9fXy4gRmlyZWZveCA0LTI5IGxhY2tzIHN1cHBvcnQgZm9yIGFkZGluZyBuZXcgcHJvcGVydGllcyB0byBgVWludDhBcnJheWBcbiAqIChTZWU6IGh0dHBzOi8vYnVnemlsbGEubW96aWxsYS5vcmcvc2hvd19idWcuY2dpP2lkPTY5NTQzOCkuIElFIDEwIGxhY2tzIHN1cHBvcnRcbiAqIGZvciBfX3Byb3RvX18gYW5kIGhhcyBhIGJ1Z2d5IHR5cGVkIGFycmF5IGltcGxlbWVudGF0aW9uLlxuICovXG5CdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCA9IHR5cGVkQXJyYXlTdXBwb3J0KClcblxuaWYgKCFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCAmJiB0eXBlb2YgY29uc29sZSAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgICB0eXBlb2YgY29uc29sZS5lcnJvciA9PT0gJ2Z1bmN0aW9uJykge1xuICBjb25zb2xlLmVycm9yKFxuICAgICdUaGlzIGJyb3dzZXIgbGFja3MgdHlwZWQgYXJyYXkgKFVpbnQ4QXJyYXkpIHN1cHBvcnQgd2hpY2ggaXMgcmVxdWlyZWQgYnkgJyArXG4gICAgJ2BidWZmZXJgIHY1LnguIFVzZSBgYnVmZmVyYCB2NC54IGlmIHlvdSByZXF1aXJlIG9sZCBicm93c2VyIHN1cHBvcnQuJ1xuICApXG59XG5cbmZ1bmN0aW9uIHR5cGVkQXJyYXlTdXBwb3J0ICgpIHtcbiAgLy8gQ2FuIHR5cGVkIGFycmF5IGluc3RhbmNlcyBjYW4gYmUgYXVnbWVudGVkP1xuICB0cnkge1xuICAgIHZhciBhcnIgPSBuZXcgVWludDhBcnJheSgxKVxuICAgIGFyci5fX3Byb3RvX18gPSB7IF9fcHJvdG9fXzogVWludDhBcnJheS5wcm90b3R5cGUsIGZvbzogZnVuY3Rpb24gKCkgeyByZXR1cm4gNDIgfSB9XG4gICAgcmV0dXJuIGFyci5mb28oKSA9PT0gNDJcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG59XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShCdWZmZXIucHJvdG90eXBlLCAncGFyZW50Jywge1xuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcih0aGlzKSkgcmV0dXJuIHVuZGVmaW5lZFxuICAgIHJldHVybiB0aGlzLmJ1ZmZlclxuICB9XG59KVxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoQnVmZmVyLnByb3RvdHlwZSwgJ29mZnNldCcsIHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKCFCdWZmZXIuaXNCdWZmZXIodGhpcykpIHJldHVybiB1bmRlZmluZWRcbiAgICByZXR1cm4gdGhpcy5ieXRlT2Zmc2V0XG4gIH1cbn0pXG5cbmZ1bmN0aW9uIGNyZWF0ZUJ1ZmZlciAobGVuZ3RoKSB7XG4gIGlmIChsZW5ndGggPiBLX01BWF9MRU5HVEgpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignVGhlIHZhbHVlIFwiJyArIGxlbmd0aCArICdcIiBpcyBpbnZhbGlkIGZvciBvcHRpb24gXCJzaXplXCInKVxuICB9XG4gIC8vIFJldHVybiBhbiBhdWdtZW50ZWQgYFVpbnQ4QXJyYXlgIGluc3RhbmNlXG4gIHZhciBidWYgPSBuZXcgVWludDhBcnJheShsZW5ndGgpXG4gIGJ1Zi5fX3Byb3RvX18gPSBCdWZmZXIucHJvdG90eXBlXG4gIHJldHVybiBidWZcbn1cblxuLyoqXG4gKiBUaGUgQnVmZmVyIGNvbnN0cnVjdG9yIHJldHVybnMgaW5zdGFuY2VzIG9mIGBVaW50OEFycmF5YCB0aGF0IGhhdmUgdGhlaXJcbiAqIHByb3RvdHlwZSBjaGFuZ2VkIHRvIGBCdWZmZXIucHJvdG90eXBlYC4gRnVydGhlcm1vcmUsIGBCdWZmZXJgIGlzIGEgc3ViY2xhc3Mgb2ZcbiAqIGBVaW50OEFycmF5YCwgc28gdGhlIHJldHVybmVkIGluc3RhbmNlcyB3aWxsIGhhdmUgYWxsIHRoZSBub2RlIGBCdWZmZXJgIG1ldGhvZHNcbiAqIGFuZCB0aGUgYFVpbnQ4QXJyYXlgIG1ldGhvZHMuIFNxdWFyZSBicmFja2V0IG5vdGF0aW9uIHdvcmtzIGFzIGV4cGVjdGVkIC0tIGl0XG4gKiByZXR1cm5zIGEgc2luZ2xlIG9jdGV0LlxuICpcbiAqIFRoZSBgVWludDhBcnJheWAgcHJvdG90eXBlIHJlbWFpbnMgdW5tb2RpZmllZC5cbiAqL1xuXG5mdW5jdGlvbiBCdWZmZXIgKGFyZywgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKSB7XG4gIC8vIENvbW1vbiBjYXNlLlxuICBpZiAodHlwZW9mIGFyZyA9PT0gJ251bWJlcicpIHtcbiAgICBpZiAodHlwZW9mIGVuY29kaW5nT3JPZmZzZXQgPT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgICAnVGhlIFwic3RyaW5nXCIgYXJndW1lbnQgbXVzdCBiZSBvZiB0eXBlIHN0cmluZy4gUmVjZWl2ZWQgdHlwZSBudW1iZXInXG4gICAgICApXG4gICAgfVxuICAgIHJldHVybiBhbGxvY1Vuc2FmZShhcmcpXG4gIH1cbiAgcmV0dXJuIGZyb20oYXJnLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpXG59XG5cbi8vIEZpeCBzdWJhcnJheSgpIGluIEVTMjAxNi4gU2VlOiBodHRwczovL2dpdGh1Yi5jb20vZmVyb3NzL2J1ZmZlci9wdWxsLzk3XG5pZiAodHlwZW9mIFN5bWJvbCAhPT0gJ3VuZGVmaW5lZCcgJiYgU3ltYm9sLnNwZWNpZXMgIT0gbnVsbCAmJlxuICAgIEJ1ZmZlcltTeW1ib2wuc3BlY2llc10gPT09IEJ1ZmZlcikge1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoQnVmZmVyLCBTeW1ib2wuc3BlY2llcywge1xuICAgIHZhbHVlOiBudWxsLFxuICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICB3cml0YWJsZTogZmFsc2VcbiAgfSlcbn1cblxuQnVmZmVyLnBvb2xTaXplID0gODE5MiAvLyBub3QgdXNlZCBieSB0aGlzIGltcGxlbWVudGF0aW9uXG5cbmZ1bmN0aW9uIGZyb20gKHZhbHVlLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpIHtcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gZnJvbVN0cmluZyh2YWx1ZSwgZW5jb2RpbmdPck9mZnNldClcbiAgfVxuXG4gIGlmIChBcnJheUJ1ZmZlci5pc1ZpZXcodmFsdWUpKSB7XG4gICAgcmV0dXJuIGZyb21BcnJheUxpa2UodmFsdWUpXG4gIH1cblxuICBpZiAodmFsdWUgPT0gbnVsbCkge1xuICAgIHRocm93IFR5cGVFcnJvcihcbiAgICAgICdUaGUgZmlyc3QgYXJndW1lbnQgbXVzdCBiZSBvbmUgb2YgdHlwZSBzdHJpbmcsIEJ1ZmZlciwgQXJyYXlCdWZmZXIsIEFycmF5LCAnICtcbiAgICAgICdvciBBcnJheS1saWtlIE9iamVjdC4gUmVjZWl2ZWQgdHlwZSAnICsgKHR5cGVvZiB2YWx1ZSlcbiAgICApXG4gIH1cblxuICBpZiAoaXNJbnN0YW5jZSh2YWx1ZSwgQXJyYXlCdWZmZXIpIHx8XG4gICAgICAodmFsdWUgJiYgaXNJbnN0YW5jZSh2YWx1ZS5idWZmZXIsIEFycmF5QnVmZmVyKSkpIHtcbiAgICByZXR1cm4gZnJvbUFycmF5QnVmZmVyKHZhbHVlLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpXG4gIH1cblxuICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICAnVGhlIFwidmFsdWVcIiBhcmd1bWVudCBtdXN0IG5vdCBiZSBvZiB0eXBlIG51bWJlci4gUmVjZWl2ZWQgdHlwZSBudW1iZXInXG4gICAgKVxuICB9XG5cbiAgdmFyIHZhbHVlT2YgPSB2YWx1ZS52YWx1ZU9mICYmIHZhbHVlLnZhbHVlT2YoKVxuICBpZiAodmFsdWVPZiAhPSBudWxsICYmIHZhbHVlT2YgIT09IHZhbHVlKSB7XG4gICAgcmV0dXJuIEJ1ZmZlci5mcm9tKHZhbHVlT2YsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aClcbiAgfVxuXG4gIHZhciBiID0gZnJvbU9iamVjdCh2YWx1ZSlcbiAgaWYgKGIpIHJldHVybiBiXG5cbiAgaWYgKHR5cGVvZiBTeW1ib2wgIT09ICd1bmRlZmluZWQnICYmIFN5bWJvbC50b1ByaW1pdGl2ZSAhPSBudWxsICYmXG4gICAgICB0eXBlb2YgdmFsdWVbU3ltYm9sLnRvUHJpbWl0aXZlXSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBCdWZmZXIuZnJvbShcbiAgICAgIHZhbHVlW1N5bWJvbC50b1ByaW1pdGl2ZV0oJ3N0cmluZycpLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGhcbiAgICApXG4gIH1cblxuICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICdUaGUgZmlyc3QgYXJndW1lbnQgbXVzdCBiZSBvbmUgb2YgdHlwZSBzdHJpbmcsIEJ1ZmZlciwgQXJyYXlCdWZmZXIsIEFycmF5LCAnICtcbiAgICAnb3IgQXJyYXktbGlrZSBPYmplY3QuIFJlY2VpdmVkIHR5cGUgJyArICh0eXBlb2YgdmFsdWUpXG4gIClcbn1cblxuLyoqXG4gKiBGdW5jdGlvbmFsbHkgZXF1aXZhbGVudCB0byBCdWZmZXIoYXJnLCBlbmNvZGluZykgYnV0IHRocm93cyBhIFR5cGVFcnJvclxuICogaWYgdmFsdWUgaXMgYSBudW1iZXIuXG4gKiBCdWZmZXIuZnJvbShzdHJbLCBlbmNvZGluZ10pXG4gKiBCdWZmZXIuZnJvbShhcnJheSlcbiAqIEJ1ZmZlci5mcm9tKGJ1ZmZlcilcbiAqIEJ1ZmZlci5mcm9tKGFycmF5QnVmZmVyWywgYnl0ZU9mZnNldFssIGxlbmd0aF1dKVxuICoqL1xuQnVmZmVyLmZyb20gPSBmdW5jdGlvbiAodmFsdWUsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gZnJvbSh2YWx1ZSwgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKVxufVxuXG4vLyBOb3RlOiBDaGFuZ2UgcHJvdG90eXBlICphZnRlciogQnVmZmVyLmZyb20gaXMgZGVmaW5lZCB0byB3b3JrYXJvdW5kIENocm9tZSBidWc6XG4vLyBodHRwczovL2dpdGh1Yi5jb20vZmVyb3NzL2J1ZmZlci9wdWxsLzE0OFxuQnVmZmVyLnByb3RvdHlwZS5fX3Byb3RvX18gPSBVaW50OEFycmF5LnByb3RvdHlwZVxuQnVmZmVyLl9fcHJvdG9fXyA9IFVpbnQ4QXJyYXlcblxuZnVuY3Rpb24gYXNzZXJ0U2l6ZSAoc2l6ZSkge1xuICBpZiAodHlwZW9mIHNpemUgIT09ICdudW1iZXInKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJzaXplXCIgYXJndW1lbnQgbXVzdCBiZSBvZiB0eXBlIG51bWJlcicpXG4gIH0gZWxzZSBpZiAoc2l6ZSA8IDApIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignVGhlIHZhbHVlIFwiJyArIHNpemUgKyAnXCIgaXMgaW52YWxpZCBmb3Igb3B0aW9uIFwic2l6ZVwiJylcbiAgfVxufVxuXG5mdW5jdGlvbiBhbGxvYyAoc2l6ZSwgZmlsbCwgZW5jb2RpbmcpIHtcbiAgYXNzZXJ0U2l6ZShzaXplKVxuICBpZiAoc2l6ZSA8PSAwKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUJ1ZmZlcihzaXplKVxuICB9XG4gIGlmIChmaWxsICE9PSB1bmRlZmluZWQpIHtcbiAgICAvLyBPbmx5IHBheSBhdHRlbnRpb24gdG8gZW5jb2RpbmcgaWYgaXQncyBhIHN0cmluZy4gVGhpc1xuICAgIC8vIHByZXZlbnRzIGFjY2lkZW50YWxseSBzZW5kaW5nIGluIGEgbnVtYmVyIHRoYXQgd291bGRcbiAgICAvLyBiZSBpbnRlcnByZXR0ZWQgYXMgYSBzdGFydCBvZmZzZXQuXG4gICAgcmV0dXJuIHR5cGVvZiBlbmNvZGluZyA9PT0gJ3N0cmluZydcbiAgICAgID8gY3JlYXRlQnVmZmVyKHNpemUpLmZpbGwoZmlsbCwgZW5jb2RpbmcpXG4gICAgICA6IGNyZWF0ZUJ1ZmZlcihzaXplKS5maWxsKGZpbGwpXG4gIH1cbiAgcmV0dXJuIGNyZWF0ZUJ1ZmZlcihzaXplKVxufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgZmlsbGVkIEJ1ZmZlciBpbnN0YW5jZS5cbiAqIGFsbG9jKHNpemVbLCBmaWxsWywgZW5jb2RpbmddXSlcbiAqKi9cbkJ1ZmZlci5hbGxvYyA9IGZ1bmN0aW9uIChzaXplLCBmaWxsLCBlbmNvZGluZykge1xuICByZXR1cm4gYWxsb2Moc2l6ZSwgZmlsbCwgZW5jb2RpbmcpXG59XG5cbmZ1bmN0aW9uIGFsbG9jVW5zYWZlIChzaXplKSB7XG4gIGFzc2VydFNpemUoc2l6ZSlcbiAgcmV0dXJuIGNyZWF0ZUJ1ZmZlcihzaXplIDwgMCA/IDAgOiBjaGVja2VkKHNpemUpIHwgMClcbn1cblxuLyoqXG4gKiBFcXVpdmFsZW50IHRvIEJ1ZmZlcihudW0pLCBieSBkZWZhdWx0IGNyZWF0ZXMgYSBub24temVyby1maWxsZWQgQnVmZmVyIGluc3RhbmNlLlxuICogKi9cbkJ1ZmZlci5hbGxvY1Vuc2FmZSA9IGZ1bmN0aW9uIChzaXplKSB7XG4gIHJldHVybiBhbGxvY1Vuc2FmZShzaXplKVxufVxuLyoqXG4gKiBFcXVpdmFsZW50IHRvIFNsb3dCdWZmZXIobnVtKSwgYnkgZGVmYXVsdCBjcmVhdGVzIGEgbm9uLXplcm8tZmlsbGVkIEJ1ZmZlciBpbnN0YW5jZS5cbiAqL1xuQnVmZmVyLmFsbG9jVW5zYWZlU2xvdyA9IGZ1bmN0aW9uIChzaXplKSB7XG4gIHJldHVybiBhbGxvY1Vuc2FmZShzaXplKVxufVxuXG5mdW5jdGlvbiBmcm9tU3RyaW5nIChzdHJpbmcsIGVuY29kaW5nKSB7XG4gIGlmICh0eXBlb2YgZW5jb2RpbmcgIT09ICdzdHJpbmcnIHx8IGVuY29kaW5nID09PSAnJykge1xuICAgIGVuY29kaW5nID0gJ3V0ZjgnXG4gIH1cblxuICBpZiAoIUJ1ZmZlci5pc0VuY29kaW5nKGVuY29kaW5nKSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmNvZGluZylcbiAgfVxuXG4gIHZhciBsZW5ndGggPSBieXRlTGVuZ3RoKHN0cmluZywgZW5jb2RpbmcpIHwgMFxuICB2YXIgYnVmID0gY3JlYXRlQnVmZmVyKGxlbmd0aClcblxuICB2YXIgYWN0dWFsID0gYnVmLndyaXRlKHN0cmluZywgZW5jb2RpbmcpXG5cbiAgaWYgKGFjdHVhbCAhPT0gbGVuZ3RoKSB7XG4gICAgLy8gV3JpdGluZyBhIGhleCBzdHJpbmcsIGZvciBleGFtcGxlLCB0aGF0IGNvbnRhaW5zIGludmFsaWQgY2hhcmFjdGVycyB3aWxsXG4gICAgLy8gY2F1c2UgZXZlcnl0aGluZyBhZnRlciB0aGUgZmlyc3QgaW52YWxpZCBjaGFyYWN0ZXIgdG8gYmUgaWdub3JlZC4gKGUuZy5cbiAgICAvLyAnYWJ4eGNkJyB3aWxsIGJlIHRyZWF0ZWQgYXMgJ2FiJylcbiAgICBidWYgPSBidWYuc2xpY2UoMCwgYWN0dWFsKVxuICB9XG5cbiAgcmV0dXJuIGJ1ZlxufVxuXG5mdW5jdGlvbiBmcm9tQXJyYXlMaWtlIChhcnJheSkge1xuICB2YXIgbGVuZ3RoID0gYXJyYXkubGVuZ3RoIDwgMCA/IDAgOiBjaGVja2VkKGFycmF5Lmxlbmd0aCkgfCAwXG4gIHZhciBidWYgPSBjcmVhdGVCdWZmZXIobGVuZ3RoKVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSArPSAxKSB7XG4gICAgYnVmW2ldID0gYXJyYXlbaV0gJiAyNTVcbiAgfVxuICByZXR1cm4gYnVmXG59XG5cbmZ1bmN0aW9uIGZyb21BcnJheUJ1ZmZlciAoYXJyYXksIGJ5dGVPZmZzZXQsIGxlbmd0aCkge1xuICBpZiAoYnl0ZU9mZnNldCA8IDAgfHwgYXJyYXkuYnl0ZUxlbmd0aCA8IGJ5dGVPZmZzZXQpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignXCJvZmZzZXRcIiBpcyBvdXRzaWRlIG9mIGJ1ZmZlciBib3VuZHMnKVxuICB9XG5cbiAgaWYgKGFycmF5LmJ5dGVMZW5ndGggPCBieXRlT2Zmc2V0ICsgKGxlbmd0aCB8fCAwKSkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdcImxlbmd0aFwiIGlzIG91dHNpZGUgb2YgYnVmZmVyIGJvdW5kcycpXG4gIH1cblxuICB2YXIgYnVmXG4gIGlmIChieXRlT2Zmc2V0ID09PSB1bmRlZmluZWQgJiYgbGVuZ3RoID09PSB1bmRlZmluZWQpIHtcbiAgICBidWYgPSBuZXcgVWludDhBcnJheShhcnJheSlcbiAgfSBlbHNlIGlmIChsZW5ndGggPT09IHVuZGVmaW5lZCkge1xuICAgIGJ1ZiA9IG5ldyBVaW50OEFycmF5KGFycmF5LCBieXRlT2Zmc2V0KVxuICB9IGVsc2Uge1xuICAgIGJ1ZiA9IG5ldyBVaW50OEFycmF5KGFycmF5LCBieXRlT2Zmc2V0LCBsZW5ndGgpXG4gIH1cblxuICAvLyBSZXR1cm4gYW4gYXVnbWVudGVkIGBVaW50OEFycmF5YCBpbnN0YW5jZVxuICBidWYuX19wcm90b19fID0gQnVmZmVyLnByb3RvdHlwZVxuICByZXR1cm4gYnVmXG59XG5cbmZ1bmN0aW9uIGZyb21PYmplY3QgKG9iaikge1xuICBpZiAoQnVmZmVyLmlzQnVmZmVyKG9iaikpIHtcbiAgICB2YXIgbGVuID0gY2hlY2tlZChvYmoubGVuZ3RoKSB8IDBcbiAgICB2YXIgYnVmID0gY3JlYXRlQnVmZmVyKGxlbilcblxuICAgIGlmIChidWYubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gYnVmXG4gICAgfVxuXG4gICAgb2JqLmNvcHkoYnVmLCAwLCAwLCBsZW4pXG4gICAgcmV0dXJuIGJ1ZlxuICB9XG5cbiAgaWYgKG9iai5sZW5ndGggIT09IHVuZGVmaW5lZCkge1xuICAgIGlmICh0eXBlb2Ygb2JqLmxlbmd0aCAhPT0gJ251bWJlcicgfHwgbnVtYmVySXNOYU4ob2JqLmxlbmd0aCkpIHtcbiAgICAgIHJldHVybiBjcmVhdGVCdWZmZXIoMClcbiAgICB9XG4gICAgcmV0dXJuIGZyb21BcnJheUxpa2Uob2JqKVxuICB9XG5cbiAgaWYgKG9iai50eXBlID09PSAnQnVmZmVyJyAmJiBBcnJheS5pc0FycmF5KG9iai5kYXRhKSkge1xuICAgIHJldHVybiBmcm9tQXJyYXlMaWtlKG9iai5kYXRhKVxuICB9XG59XG5cbmZ1bmN0aW9uIGNoZWNrZWQgKGxlbmd0aCkge1xuICAvLyBOb3RlOiBjYW5ub3QgdXNlIGBsZW5ndGggPCBLX01BWF9MRU5HVEhgIGhlcmUgYmVjYXVzZSB0aGF0IGZhaWxzIHdoZW5cbiAgLy8gbGVuZ3RoIGlzIE5hTiAod2hpY2ggaXMgb3RoZXJ3aXNlIGNvZXJjZWQgdG8gemVyby4pXG4gIGlmIChsZW5ndGggPj0gS19NQVhfTEVOR1RIKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0F0dGVtcHQgdG8gYWxsb2NhdGUgQnVmZmVyIGxhcmdlciB0aGFuIG1heGltdW0gJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgJ3NpemU6IDB4JyArIEtfTUFYX0xFTkdUSC50b1N0cmluZygxNikgKyAnIGJ5dGVzJylcbiAgfVxuICByZXR1cm4gbGVuZ3RoIHwgMFxufVxuXG5mdW5jdGlvbiBTbG93QnVmZmVyIChsZW5ndGgpIHtcbiAgaWYgKCtsZW5ndGggIT0gbGVuZ3RoKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgZXFlcWVxXG4gICAgbGVuZ3RoID0gMFxuICB9XG4gIHJldHVybiBCdWZmZXIuYWxsb2MoK2xlbmd0aClcbn1cblxuQnVmZmVyLmlzQnVmZmVyID0gZnVuY3Rpb24gaXNCdWZmZXIgKGIpIHtcbiAgcmV0dXJuIGIgIT0gbnVsbCAmJiBiLl9pc0J1ZmZlciA9PT0gdHJ1ZSAmJlxuICAgIGIgIT09IEJ1ZmZlci5wcm90b3R5cGUgLy8gc28gQnVmZmVyLmlzQnVmZmVyKEJ1ZmZlci5wcm90b3R5cGUpIHdpbGwgYmUgZmFsc2Vcbn1cblxuQnVmZmVyLmNvbXBhcmUgPSBmdW5jdGlvbiBjb21wYXJlIChhLCBiKSB7XG4gIGlmIChpc0luc3RhbmNlKGEsIFVpbnQ4QXJyYXkpKSBhID0gQnVmZmVyLmZyb20oYSwgYS5vZmZzZXQsIGEuYnl0ZUxlbmd0aClcbiAgaWYgKGlzSW5zdGFuY2UoYiwgVWludDhBcnJheSkpIGIgPSBCdWZmZXIuZnJvbShiLCBiLm9mZnNldCwgYi5ieXRlTGVuZ3RoKVxuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihhKSB8fCAhQnVmZmVyLmlzQnVmZmVyKGIpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgICdUaGUgXCJidWYxXCIsIFwiYnVmMlwiIGFyZ3VtZW50cyBtdXN0IGJlIG9uZSBvZiB0eXBlIEJ1ZmZlciBvciBVaW50OEFycmF5J1xuICAgIClcbiAgfVxuXG4gIGlmIChhID09PSBiKSByZXR1cm4gMFxuXG4gIHZhciB4ID0gYS5sZW5ndGhcbiAgdmFyIHkgPSBiLmxlbmd0aFxuXG4gIGZvciAodmFyIGkgPSAwLCBsZW4gPSBNYXRoLm1pbih4LCB5KTsgaSA8IGxlbjsgKytpKSB7XG4gICAgaWYgKGFbaV0gIT09IGJbaV0pIHtcbiAgICAgIHggPSBhW2ldXG4gICAgICB5ID0gYltpXVxuICAgICAgYnJlYWtcbiAgICB9XG4gIH1cblxuICBpZiAoeCA8IHkpIHJldHVybiAtMVxuICBpZiAoeSA8IHgpIHJldHVybiAxXG4gIHJldHVybiAwXG59XG5cbkJ1ZmZlci5pc0VuY29kaW5nID0gZnVuY3Rpb24gaXNFbmNvZGluZyAoZW5jb2RpbmcpIHtcbiAgc3dpdGNoIChTdHJpbmcoZW5jb2RpbmcpLnRvTG93ZXJDYXNlKCkpIHtcbiAgICBjYXNlICdoZXgnOlxuICAgIGNhc2UgJ3V0ZjgnOlxuICAgIGNhc2UgJ3V0Zi04JzpcbiAgICBjYXNlICdhc2NpaSc6XG4gICAgY2FzZSAnbGF0aW4xJzpcbiAgICBjYXNlICdiaW5hcnknOlxuICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgY2FzZSAndWNzMic6XG4gICAgY2FzZSAndWNzLTInOlxuICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgIHJldHVybiB0cnVlXG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBmYWxzZVxuICB9XG59XG5cbkJ1ZmZlci5jb25jYXQgPSBmdW5jdGlvbiBjb25jYXQgKGxpc3QsIGxlbmd0aCkge1xuICBpZiAoIUFycmF5LmlzQXJyYXkobGlzdCkpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RcIiBhcmd1bWVudCBtdXN0IGJlIGFuIEFycmF5IG9mIEJ1ZmZlcnMnKVxuICB9XG5cbiAgaWYgKGxpc3QubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIEJ1ZmZlci5hbGxvYygwKVxuICB9XG5cbiAgdmFyIGlcbiAgaWYgKGxlbmd0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgbGVuZ3RoID0gMFxuICAgIGZvciAoaSA9IDA7IGkgPCBsaXN0Lmxlbmd0aDsgKytpKSB7XG4gICAgICBsZW5ndGggKz0gbGlzdFtpXS5sZW5ndGhcbiAgICB9XG4gIH1cblxuICB2YXIgYnVmZmVyID0gQnVmZmVyLmFsbG9jVW5zYWZlKGxlbmd0aClcbiAgdmFyIHBvcyA9IDBcbiAgZm9yIChpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyArK2kpIHtcbiAgICB2YXIgYnVmID0gbGlzdFtpXVxuICAgIGlmIChpc0luc3RhbmNlKGJ1ZiwgVWludDhBcnJheSkpIHtcbiAgICAgIGJ1ZiA9IEJ1ZmZlci5mcm9tKGJ1ZilcbiAgICB9XG4gICAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYnVmKSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJsaXN0XCIgYXJndW1lbnQgbXVzdCBiZSBhbiBBcnJheSBvZiBCdWZmZXJzJylcbiAgICB9XG4gICAgYnVmLmNvcHkoYnVmZmVyLCBwb3MpXG4gICAgcG9zICs9IGJ1Zi5sZW5ndGhcbiAgfVxuICByZXR1cm4gYnVmZmVyXG59XG5cbmZ1bmN0aW9uIGJ5dGVMZW5ndGggKHN0cmluZywgZW5jb2RpbmcpIHtcbiAgaWYgKEJ1ZmZlci5pc0J1ZmZlcihzdHJpbmcpKSB7XG4gICAgcmV0dXJuIHN0cmluZy5sZW5ndGhcbiAgfVxuICBpZiAoQXJyYXlCdWZmZXIuaXNWaWV3KHN0cmluZykgfHwgaXNJbnN0YW5jZShzdHJpbmcsIEFycmF5QnVmZmVyKSkge1xuICAgIHJldHVybiBzdHJpbmcuYnl0ZUxlbmd0aFxuICB9XG4gIGlmICh0eXBlb2Ygc3RyaW5nICE9PSAnc3RyaW5nJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICAnVGhlIFwic3RyaW5nXCIgYXJndW1lbnQgbXVzdCBiZSBvbmUgb2YgdHlwZSBzdHJpbmcsIEJ1ZmZlciwgb3IgQXJyYXlCdWZmZXIuICcgK1xuICAgICAgJ1JlY2VpdmVkIHR5cGUgJyArIHR5cGVvZiBzdHJpbmdcbiAgICApXG4gIH1cblxuICB2YXIgbGVuID0gc3RyaW5nLmxlbmd0aFxuICB2YXIgbXVzdE1hdGNoID0gKGFyZ3VtZW50cy5sZW5ndGggPiAyICYmIGFyZ3VtZW50c1syXSA9PT0gdHJ1ZSlcbiAgaWYgKCFtdXN0TWF0Y2ggJiYgbGVuID09PSAwKSByZXR1cm4gMFxuXG4gIC8vIFVzZSBhIGZvciBsb29wIHRvIGF2b2lkIHJlY3Vyc2lvblxuICB2YXIgbG93ZXJlZENhc2UgPSBmYWxzZVxuICBmb3IgKDs7KSB7XG4gICAgc3dpdGNoIChlbmNvZGluZykge1xuICAgICAgY2FzZSAnYXNjaWknOlxuICAgICAgY2FzZSAnbGF0aW4xJzpcbiAgICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICAgIHJldHVybiBsZW5cbiAgICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgY2FzZSAndXRmLTgnOlxuICAgICAgICByZXR1cm4gdXRmOFRvQnl0ZXMoc3RyaW5nKS5sZW5ndGhcbiAgICAgIGNhc2UgJ3VjczInOlxuICAgICAgY2FzZSAndWNzLTInOlxuICAgICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICAgIHJldHVybiBsZW4gKiAyXG4gICAgICBjYXNlICdoZXgnOlxuICAgICAgICByZXR1cm4gbGVuID4+PiAxXG4gICAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgICByZXR1cm4gYmFzZTY0VG9CeXRlcyhzdHJpbmcpLmxlbmd0aFxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKGxvd2VyZWRDYXNlKSB7XG4gICAgICAgICAgcmV0dXJuIG11c3RNYXRjaCA/IC0xIDogdXRmOFRvQnl0ZXMoc3RyaW5nKS5sZW5ndGggLy8gYXNzdW1lIHV0ZjhcbiAgICAgICAgfVxuICAgICAgICBlbmNvZGluZyA9ICgnJyArIGVuY29kaW5nKS50b0xvd2VyQ2FzZSgpXG4gICAgICAgIGxvd2VyZWRDYXNlID0gdHJ1ZVxuICAgIH1cbiAgfVxufVxuQnVmZmVyLmJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoXG5cbmZ1bmN0aW9uIHNsb3dUb1N0cmluZyAoZW5jb2RpbmcsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGxvd2VyZWRDYXNlID0gZmFsc2VcblxuICAvLyBObyBuZWVkIHRvIHZlcmlmeSB0aGF0IFwidGhpcy5sZW5ndGggPD0gTUFYX1VJTlQzMlwiIHNpbmNlIGl0J3MgYSByZWFkLW9ubHlcbiAgLy8gcHJvcGVydHkgb2YgYSB0eXBlZCBhcnJheS5cblxuICAvLyBUaGlzIGJlaGF2ZXMgbmVpdGhlciBsaWtlIFN0cmluZyBub3IgVWludDhBcnJheSBpbiB0aGF0IHdlIHNldCBzdGFydC9lbmRcbiAgLy8gdG8gdGhlaXIgdXBwZXIvbG93ZXIgYm91bmRzIGlmIHRoZSB2YWx1ZSBwYXNzZWQgaXMgb3V0IG9mIHJhbmdlLlxuICAvLyB1bmRlZmluZWQgaXMgaGFuZGxlZCBzcGVjaWFsbHkgYXMgcGVyIEVDTUEtMjYyIDZ0aCBFZGl0aW9uLFxuICAvLyBTZWN0aW9uIDEzLjMuMy43IFJ1bnRpbWUgU2VtYW50aWNzOiBLZXllZEJpbmRpbmdJbml0aWFsaXphdGlvbi5cbiAgaWYgKHN0YXJ0ID09PSB1bmRlZmluZWQgfHwgc3RhcnQgPCAwKSB7XG4gICAgc3RhcnQgPSAwXG4gIH1cbiAgLy8gUmV0dXJuIGVhcmx5IGlmIHN0YXJ0ID4gdGhpcy5sZW5ndGguIERvbmUgaGVyZSB0byBwcmV2ZW50IHBvdGVudGlhbCB1aW50MzJcbiAgLy8gY29lcmNpb24gZmFpbCBiZWxvdy5cbiAgaWYgKHN0YXJ0ID4gdGhpcy5sZW5ndGgpIHtcbiAgICByZXR1cm4gJydcbiAgfVxuXG4gIGlmIChlbmQgPT09IHVuZGVmaW5lZCB8fCBlbmQgPiB0aGlzLmxlbmd0aCkge1xuICAgIGVuZCA9IHRoaXMubGVuZ3RoXG4gIH1cblxuICBpZiAoZW5kIDw9IDApIHtcbiAgICByZXR1cm4gJydcbiAgfVxuXG4gIC8vIEZvcmNlIGNvZXJzaW9uIHRvIHVpbnQzMi4gVGhpcyB3aWxsIGFsc28gY29lcmNlIGZhbHNleS9OYU4gdmFsdWVzIHRvIDAuXG4gIGVuZCA+Pj49IDBcbiAgc3RhcnQgPj4+PSAwXG5cbiAgaWYgKGVuZCA8PSBzdGFydCkge1xuICAgIHJldHVybiAnJ1xuICB9XG5cbiAgaWYgKCFlbmNvZGluZykgZW5jb2RpbmcgPSAndXRmOCdcblxuICB3aGlsZSAodHJ1ZSkge1xuICAgIHN3aXRjaCAoZW5jb2RpbmcpIHtcbiAgICAgIGNhc2UgJ2hleCc6XG4gICAgICAgIHJldHVybiBoZXhTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICd1dGY4JzpcbiAgICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgICAgcmV0dXJuIHV0ZjhTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICdhc2NpaSc6XG4gICAgICAgIHJldHVybiBhc2NpaVNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ2xhdGluMSc6XG4gICAgICBjYXNlICdiaW5hcnknOlxuICAgICAgICByZXR1cm4gbGF0aW4xU2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgICAgcmV0dXJuIGJhc2U2NFNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ3VjczInOlxuICAgICAgY2FzZSAndWNzLTInOlxuICAgICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICAgIHJldHVybiB1dGYxNmxlU2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKGxvd2VyZWRDYXNlKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpXG4gICAgICAgIGVuY29kaW5nID0gKGVuY29kaW5nICsgJycpLnRvTG93ZXJDYXNlKClcbiAgICAgICAgbG93ZXJlZENhc2UgPSB0cnVlXG4gICAgfVxuICB9XG59XG5cbi8vIFRoaXMgcHJvcGVydHkgaXMgdXNlZCBieSBgQnVmZmVyLmlzQnVmZmVyYCAoYW5kIHRoZSBgaXMtYnVmZmVyYCBucG0gcGFja2FnZSlcbi8vIHRvIGRldGVjdCBhIEJ1ZmZlciBpbnN0YW5jZS4gSXQncyBub3QgcG9zc2libGUgdG8gdXNlIGBpbnN0YW5jZW9mIEJ1ZmZlcmBcbi8vIHJlbGlhYmx5IGluIGEgYnJvd3NlcmlmeSBjb250ZXh0IGJlY2F1c2UgdGhlcmUgY291bGQgYmUgbXVsdGlwbGUgZGlmZmVyZW50XG4vLyBjb3BpZXMgb2YgdGhlICdidWZmZXInIHBhY2thZ2UgaW4gdXNlLiBUaGlzIG1ldGhvZCB3b3JrcyBldmVuIGZvciBCdWZmZXJcbi8vIGluc3RhbmNlcyB0aGF0IHdlcmUgY3JlYXRlZCBmcm9tIGFub3RoZXIgY29weSBvZiB0aGUgYGJ1ZmZlcmAgcGFja2FnZS5cbi8vIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL2Zlcm9zcy9idWZmZXIvaXNzdWVzLzE1NFxuQnVmZmVyLnByb3RvdHlwZS5faXNCdWZmZXIgPSB0cnVlXG5cbmZ1bmN0aW9uIHN3YXAgKGIsIG4sIG0pIHtcbiAgdmFyIGkgPSBiW25dXG4gIGJbbl0gPSBiW21dXG4gIGJbbV0gPSBpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuc3dhcDE2ID0gZnVuY3Rpb24gc3dhcDE2ICgpIHtcbiAgdmFyIGxlbiA9IHRoaXMubGVuZ3RoXG4gIGlmIChsZW4gJSAyICE9PSAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0J1ZmZlciBzaXplIG11c3QgYmUgYSBtdWx0aXBsZSBvZiAxNi1iaXRzJylcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSArPSAyKSB7XG4gICAgc3dhcCh0aGlzLCBpLCBpICsgMSlcbiAgfVxuICByZXR1cm4gdGhpc1xufVxuXG5CdWZmZXIucHJvdG90eXBlLnN3YXAzMiA9IGZ1bmN0aW9uIHN3YXAzMiAoKSB7XG4gIHZhciBsZW4gPSB0aGlzLmxlbmd0aFxuICBpZiAobGVuICUgNCAhPT0gMCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdCdWZmZXIgc2l6ZSBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgMzItYml0cycpXG4gIH1cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkgKz0gNCkge1xuICAgIHN3YXAodGhpcywgaSwgaSArIDMpXG4gICAgc3dhcCh0aGlzLCBpICsgMSwgaSArIDIpXG4gIH1cbiAgcmV0dXJuIHRoaXNcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5zd2FwNjQgPSBmdW5jdGlvbiBzd2FwNjQgKCkge1xuICB2YXIgbGVuID0gdGhpcy5sZW5ndGhcbiAgaWYgKGxlbiAlIDggIT09IDApIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignQnVmZmVyIHNpemUgbXVzdCBiZSBhIG11bHRpcGxlIG9mIDY0LWJpdHMnKVxuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpICs9IDgpIHtcbiAgICBzd2FwKHRoaXMsIGksIGkgKyA3KVxuICAgIHN3YXAodGhpcywgaSArIDEsIGkgKyA2KVxuICAgIHN3YXAodGhpcywgaSArIDIsIGkgKyA1KVxuICAgIHN3YXAodGhpcywgaSArIDMsIGkgKyA0KVxuICB9XG4gIHJldHVybiB0aGlzXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiB0b1N0cmluZyAoKSB7XG4gIHZhciBsZW5ndGggPSB0aGlzLmxlbmd0aFxuICBpZiAobGVuZ3RoID09PSAwKSByZXR1cm4gJydcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHJldHVybiB1dGY4U2xpY2UodGhpcywgMCwgbGVuZ3RoKVxuICByZXR1cm4gc2xvd1RvU3RyaW5nLmFwcGx5KHRoaXMsIGFyZ3VtZW50cylcbn1cblxuQnVmZmVyLnByb3RvdHlwZS50b0xvY2FsZVN0cmluZyA9IEJ1ZmZlci5wcm90b3R5cGUudG9TdHJpbmdcblxuQnVmZmVyLnByb3RvdHlwZS5lcXVhbHMgPSBmdW5jdGlvbiBlcXVhbHMgKGIpIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYikpIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50IG11c3QgYmUgYSBCdWZmZXInKVxuICBpZiAodGhpcyA9PT0gYikgcmV0dXJuIHRydWVcbiAgcmV0dXJuIEJ1ZmZlci5jb21wYXJlKHRoaXMsIGIpID09PSAwXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuaW5zcGVjdCA9IGZ1bmN0aW9uIGluc3BlY3QgKCkge1xuICB2YXIgc3RyID0gJydcbiAgdmFyIG1heCA9IGV4cG9ydHMuSU5TUEVDVF9NQVhfQllURVNcbiAgc3RyID0gdGhpcy50b1N0cmluZygnaGV4JywgMCwgbWF4KS5yZXBsYWNlKC8oLnsyfSkvZywgJyQxICcpLnRyaW0oKVxuICBpZiAodGhpcy5sZW5ndGggPiBtYXgpIHN0ciArPSAnIC4uLiAnXG4gIHJldHVybiAnPEJ1ZmZlciAnICsgc3RyICsgJz4nXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuY29tcGFyZSA9IGZ1bmN0aW9uIGNvbXBhcmUgKHRhcmdldCwgc3RhcnQsIGVuZCwgdGhpc1N0YXJ0LCB0aGlzRW5kKSB7XG4gIGlmIChpc0luc3RhbmNlKHRhcmdldCwgVWludDhBcnJheSkpIHtcbiAgICB0YXJnZXQgPSBCdWZmZXIuZnJvbSh0YXJnZXQsIHRhcmdldC5vZmZzZXQsIHRhcmdldC5ieXRlTGVuZ3RoKVxuICB9XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKHRhcmdldCkpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgJ1RoZSBcInRhcmdldFwiIGFyZ3VtZW50IG11c3QgYmUgb25lIG9mIHR5cGUgQnVmZmVyIG9yIFVpbnQ4QXJyYXkuICcgK1xuICAgICAgJ1JlY2VpdmVkIHR5cGUgJyArICh0eXBlb2YgdGFyZ2V0KVxuICAgIClcbiAgfVxuXG4gIGlmIChzdGFydCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgc3RhcnQgPSAwXG4gIH1cbiAgaWYgKGVuZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgZW5kID0gdGFyZ2V0ID8gdGFyZ2V0Lmxlbmd0aCA6IDBcbiAgfVxuICBpZiAodGhpc1N0YXJ0ID09PSB1bmRlZmluZWQpIHtcbiAgICB0aGlzU3RhcnQgPSAwXG4gIH1cbiAgaWYgKHRoaXNFbmQgPT09IHVuZGVmaW5lZCkge1xuICAgIHRoaXNFbmQgPSB0aGlzLmxlbmd0aFxuICB9XG5cbiAgaWYgKHN0YXJ0IDwgMCB8fCBlbmQgPiB0YXJnZXQubGVuZ3RoIHx8IHRoaXNTdGFydCA8IDAgfHwgdGhpc0VuZCA+IHRoaXMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ291dCBvZiByYW5nZSBpbmRleCcpXG4gIH1cblxuICBpZiAodGhpc1N0YXJ0ID49IHRoaXNFbmQgJiYgc3RhcnQgPj0gZW5kKSB7XG4gICAgcmV0dXJuIDBcbiAgfVxuICBpZiAodGhpc1N0YXJ0ID49IHRoaXNFbmQpIHtcbiAgICByZXR1cm4gLTFcbiAgfVxuICBpZiAoc3RhcnQgPj0gZW5kKSB7XG4gICAgcmV0dXJuIDFcbiAgfVxuXG4gIHN0YXJ0ID4+Pj0gMFxuICBlbmQgPj4+PSAwXG4gIHRoaXNTdGFydCA+Pj49IDBcbiAgdGhpc0VuZCA+Pj49IDBcblxuICBpZiAodGhpcyA9PT0gdGFyZ2V0KSByZXR1cm4gMFxuXG4gIHZhciB4ID0gdGhpc0VuZCAtIHRoaXNTdGFydFxuICB2YXIgeSA9IGVuZCAtIHN0YXJ0XG4gIHZhciBsZW4gPSBNYXRoLm1pbih4LCB5KVxuXG4gIHZhciB0aGlzQ29weSA9IHRoaXMuc2xpY2UodGhpc1N0YXJ0LCB0aGlzRW5kKVxuICB2YXIgdGFyZ2V0Q29weSA9IHRhcmdldC5zbGljZShzdGFydCwgZW5kKVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpIHtcbiAgICBpZiAodGhpc0NvcHlbaV0gIT09IHRhcmdldENvcHlbaV0pIHtcbiAgICAgIHggPSB0aGlzQ29weVtpXVxuICAgICAgeSA9IHRhcmdldENvcHlbaV1cbiAgICAgIGJyZWFrXG4gICAgfVxuICB9XG5cbiAgaWYgKHggPCB5KSByZXR1cm4gLTFcbiAgaWYgKHkgPCB4KSByZXR1cm4gMVxuICByZXR1cm4gMFxufVxuXG4vLyBGaW5kcyBlaXRoZXIgdGhlIGZpcnN0IGluZGV4IG9mIGB2YWxgIGluIGBidWZmZXJgIGF0IG9mZnNldCA+PSBgYnl0ZU9mZnNldGAsXG4vLyBPUiB0aGUgbGFzdCBpbmRleCBvZiBgdmFsYCBpbiBgYnVmZmVyYCBhdCBvZmZzZXQgPD0gYGJ5dGVPZmZzZXRgLlxuLy9cbi8vIEFyZ3VtZW50czpcbi8vIC0gYnVmZmVyIC0gYSBCdWZmZXIgdG8gc2VhcmNoXG4vLyAtIHZhbCAtIGEgc3RyaW5nLCBCdWZmZXIsIG9yIG51bWJlclxuLy8gLSBieXRlT2Zmc2V0IC0gYW4gaW5kZXggaW50byBgYnVmZmVyYDsgd2lsbCBiZSBjbGFtcGVkIHRvIGFuIGludDMyXG4vLyAtIGVuY29kaW5nIC0gYW4gb3B0aW9uYWwgZW5jb2RpbmcsIHJlbGV2YW50IGlzIHZhbCBpcyBhIHN0cmluZ1xuLy8gLSBkaXIgLSB0cnVlIGZvciBpbmRleE9mLCBmYWxzZSBmb3IgbGFzdEluZGV4T2ZcbmZ1bmN0aW9uIGJpZGlyZWN0aW9uYWxJbmRleE9mIChidWZmZXIsIHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcsIGRpcikge1xuICAvLyBFbXB0eSBidWZmZXIgbWVhbnMgbm8gbWF0Y2hcbiAgaWYgKGJ1ZmZlci5sZW5ndGggPT09IDApIHJldHVybiAtMVxuXG4gIC8vIE5vcm1hbGl6ZSBieXRlT2Zmc2V0XG4gIGlmICh0eXBlb2YgYnl0ZU9mZnNldCA9PT0gJ3N0cmluZycpIHtcbiAgICBlbmNvZGluZyA9IGJ5dGVPZmZzZXRcbiAgICBieXRlT2Zmc2V0ID0gMFxuICB9IGVsc2UgaWYgKGJ5dGVPZmZzZXQgPiAweDdmZmZmZmZmKSB7XG4gICAgYnl0ZU9mZnNldCA9IDB4N2ZmZmZmZmZcbiAgfSBlbHNlIGlmIChieXRlT2Zmc2V0IDwgLTB4ODAwMDAwMDApIHtcbiAgICBieXRlT2Zmc2V0ID0gLTB4ODAwMDAwMDBcbiAgfVxuICBieXRlT2Zmc2V0ID0gK2J5dGVPZmZzZXQgLy8gQ29lcmNlIHRvIE51bWJlci5cbiAgaWYgKG51bWJlcklzTmFOKGJ5dGVPZmZzZXQpKSB7XG4gICAgLy8gYnl0ZU9mZnNldDogaXQgaXQncyB1bmRlZmluZWQsIG51bGwsIE5hTiwgXCJmb29cIiwgZXRjLCBzZWFyY2ggd2hvbGUgYnVmZmVyXG4gICAgYnl0ZU9mZnNldCA9IGRpciA/IDAgOiAoYnVmZmVyLmxlbmd0aCAtIDEpXG4gIH1cblxuICAvLyBOb3JtYWxpemUgYnl0ZU9mZnNldDogbmVnYXRpdmUgb2Zmc2V0cyBzdGFydCBmcm9tIHRoZSBlbmQgb2YgdGhlIGJ1ZmZlclxuICBpZiAoYnl0ZU9mZnNldCA8IDApIGJ5dGVPZmZzZXQgPSBidWZmZXIubGVuZ3RoICsgYnl0ZU9mZnNldFxuICBpZiAoYnl0ZU9mZnNldCA+PSBidWZmZXIubGVuZ3RoKSB7XG4gICAgaWYgKGRpcikgcmV0dXJuIC0xXG4gICAgZWxzZSBieXRlT2Zmc2V0ID0gYnVmZmVyLmxlbmd0aCAtIDFcbiAgfSBlbHNlIGlmIChieXRlT2Zmc2V0IDwgMCkge1xuICAgIGlmIChkaXIpIGJ5dGVPZmZzZXQgPSAwXG4gICAgZWxzZSByZXR1cm4gLTFcbiAgfVxuXG4gIC8vIE5vcm1hbGl6ZSB2YWxcbiAgaWYgKHR5cGVvZiB2YWwgPT09ICdzdHJpbmcnKSB7XG4gICAgdmFsID0gQnVmZmVyLmZyb20odmFsLCBlbmNvZGluZylcbiAgfVxuXG4gIC8vIEZpbmFsbHksIHNlYXJjaCBlaXRoZXIgaW5kZXhPZiAoaWYgZGlyIGlzIHRydWUpIG9yIGxhc3RJbmRleE9mXG4gIGlmIChCdWZmZXIuaXNCdWZmZXIodmFsKSkge1xuICAgIC8vIFNwZWNpYWwgY2FzZTogbG9va2luZyBmb3IgZW1wdHkgc3RyaW5nL2J1ZmZlciBhbHdheXMgZmFpbHNcbiAgICBpZiAodmFsLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIC0xXG4gICAgfVxuICAgIHJldHVybiBhcnJheUluZGV4T2YoYnVmZmVyLCB2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nLCBkaXIpXG4gIH0gZWxzZSBpZiAodHlwZW9mIHZhbCA9PT0gJ251bWJlcicpIHtcbiAgICB2YWwgPSB2YWwgJiAweEZGIC8vIFNlYXJjaCBmb3IgYSBieXRlIHZhbHVlIFswLTI1NV1cbiAgICBpZiAodHlwZW9mIFVpbnQ4QXJyYXkucHJvdG90eXBlLmluZGV4T2YgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGlmIChkaXIpIHtcbiAgICAgICAgcmV0dXJuIFVpbnQ4QXJyYXkucHJvdG90eXBlLmluZGV4T2YuY2FsbChidWZmZXIsIHZhbCwgYnl0ZU9mZnNldClcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBVaW50OEFycmF5LnByb3RvdHlwZS5sYXN0SW5kZXhPZi5jYWxsKGJ1ZmZlciwgdmFsLCBieXRlT2Zmc2V0KVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gYXJyYXlJbmRleE9mKGJ1ZmZlciwgWyB2YWwgXSwgYnl0ZU9mZnNldCwgZW5jb2RpbmcsIGRpcilcbiAgfVxuXG4gIHRocm93IG5ldyBUeXBlRXJyb3IoJ3ZhbCBtdXN0IGJlIHN0cmluZywgbnVtYmVyIG9yIEJ1ZmZlcicpXG59XG5cbmZ1bmN0aW9uIGFycmF5SW5kZXhPZiAoYXJyLCB2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nLCBkaXIpIHtcbiAgdmFyIGluZGV4U2l6ZSA9IDFcbiAgdmFyIGFyckxlbmd0aCA9IGFyci5sZW5ndGhcbiAgdmFyIHZhbExlbmd0aCA9IHZhbC5sZW5ndGhcblxuICBpZiAoZW5jb2RpbmcgIT09IHVuZGVmaW5lZCkge1xuICAgIGVuY29kaW5nID0gU3RyaW5nKGVuY29kaW5nKS50b0xvd2VyQ2FzZSgpXG4gICAgaWYgKGVuY29kaW5nID09PSAndWNzMicgfHwgZW5jb2RpbmcgPT09ICd1Y3MtMicgfHxcbiAgICAgICAgZW5jb2RpbmcgPT09ICd1dGYxNmxlJyB8fCBlbmNvZGluZyA9PT0gJ3V0Zi0xNmxlJykge1xuICAgICAgaWYgKGFyci5sZW5ndGggPCAyIHx8IHZhbC5sZW5ndGggPCAyKSB7XG4gICAgICAgIHJldHVybiAtMVxuICAgICAgfVxuICAgICAgaW5kZXhTaXplID0gMlxuICAgICAgYXJyTGVuZ3RoIC89IDJcbiAgICAgIHZhbExlbmd0aCAvPSAyXG4gICAgICBieXRlT2Zmc2V0IC89IDJcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiByZWFkIChidWYsIGkpIHtcbiAgICBpZiAoaW5kZXhTaXplID09PSAxKSB7XG4gICAgICByZXR1cm4gYnVmW2ldXG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBidWYucmVhZFVJbnQxNkJFKGkgKiBpbmRleFNpemUpXG4gICAgfVxuICB9XG5cbiAgdmFyIGlcbiAgaWYgKGRpcikge1xuICAgIHZhciBmb3VuZEluZGV4ID0gLTFcbiAgICBmb3IgKGkgPSBieXRlT2Zmc2V0OyBpIDwgYXJyTGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChyZWFkKGFyciwgaSkgPT09IHJlYWQodmFsLCBmb3VuZEluZGV4ID09PSAtMSA/IDAgOiBpIC0gZm91bmRJbmRleCkpIHtcbiAgICAgICAgaWYgKGZvdW5kSW5kZXggPT09IC0xKSBmb3VuZEluZGV4ID0gaVxuICAgICAgICBpZiAoaSAtIGZvdW5kSW5kZXggKyAxID09PSB2YWxMZW5ndGgpIHJldHVybiBmb3VuZEluZGV4ICogaW5kZXhTaXplXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoZm91bmRJbmRleCAhPT0gLTEpIGkgLT0gaSAtIGZvdW5kSW5kZXhcbiAgICAgICAgZm91bmRJbmRleCA9IC0xXG4gICAgICB9XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGlmIChieXRlT2Zmc2V0ICsgdmFsTGVuZ3RoID4gYXJyTGVuZ3RoKSBieXRlT2Zmc2V0ID0gYXJyTGVuZ3RoIC0gdmFsTGVuZ3RoXG4gICAgZm9yIChpID0gYnl0ZU9mZnNldDsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIHZhciBmb3VuZCA9IHRydWVcbiAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgdmFsTGVuZ3RoOyBqKyspIHtcbiAgICAgICAgaWYgKHJlYWQoYXJyLCBpICsgaikgIT09IHJlYWQodmFsLCBqKSkge1xuICAgICAgICAgIGZvdW5kID0gZmFsc2VcbiAgICAgICAgICBicmVha1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoZm91bmQpIHJldHVybiBpXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIC0xXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuaW5jbHVkZXMgPSBmdW5jdGlvbiBpbmNsdWRlcyAodmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZykge1xuICByZXR1cm4gdGhpcy5pbmRleE9mKHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcpICE9PSAtMVxufVxuXG5CdWZmZXIucHJvdG90eXBlLmluZGV4T2YgPSBmdW5jdGlvbiBpbmRleE9mICh2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nKSB7XG4gIHJldHVybiBiaWRpcmVjdGlvbmFsSW5kZXhPZih0aGlzLCB2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nLCB0cnVlKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLmxhc3RJbmRleE9mID0gZnVuY3Rpb24gbGFzdEluZGV4T2YgKHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcpIHtcbiAgcmV0dXJuIGJpZGlyZWN0aW9uYWxJbmRleE9mKHRoaXMsIHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcsIGZhbHNlKVxufVxuXG5mdW5jdGlvbiBoZXhXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIG9mZnNldCA9IE51bWJlcihvZmZzZXQpIHx8IDBcbiAgdmFyIHJlbWFpbmluZyA9IGJ1Zi5sZW5ndGggLSBvZmZzZXRcbiAgaWYgKCFsZW5ndGgpIHtcbiAgICBsZW5ndGggPSByZW1haW5pbmdcbiAgfSBlbHNlIHtcbiAgICBsZW5ndGggPSBOdW1iZXIobGVuZ3RoKVxuICAgIGlmIChsZW5ndGggPiByZW1haW5pbmcpIHtcbiAgICAgIGxlbmd0aCA9IHJlbWFpbmluZ1xuICAgIH1cbiAgfVxuXG4gIHZhciBzdHJMZW4gPSBzdHJpbmcubGVuZ3RoXG5cbiAgaWYgKGxlbmd0aCA+IHN0ckxlbiAvIDIpIHtcbiAgICBsZW5ndGggPSBzdHJMZW4gLyAyXG4gIH1cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkge1xuICAgIHZhciBwYXJzZWQgPSBwYXJzZUludChzdHJpbmcuc3Vic3RyKGkgKiAyLCAyKSwgMTYpXG4gICAgaWYgKG51bWJlcklzTmFOKHBhcnNlZCkpIHJldHVybiBpXG4gICAgYnVmW29mZnNldCArIGldID0gcGFyc2VkXG4gIH1cbiAgcmV0dXJuIGlcbn1cblxuZnVuY3Rpb24gdXRmOFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGJsaXRCdWZmZXIodXRmOFRvQnl0ZXMoc3RyaW5nLCBidWYubGVuZ3RoIC0gb2Zmc2V0KSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gYXNjaWlXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBibGl0QnVmZmVyKGFzY2lpVG9CeXRlcyhzdHJpbmcpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5mdW5jdGlvbiBsYXRpbjFXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBhc2NpaVdyaXRlKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gYmFzZTY0V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYmxpdEJ1ZmZlcihiYXNlNjRUb0J5dGVzKHN0cmluZyksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIHVjczJXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBibGl0QnVmZmVyKHV0ZjE2bGVUb0J5dGVzKHN0cmluZywgYnVmLmxlbmd0aCAtIG9mZnNldCksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbiB3cml0ZSAoc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCwgZW5jb2RpbmcpIHtcbiAgLy8gQnVmZmVyI3dyaXRlKHN0cmluZylcbiAgaWYgKG9mZnNldCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgZW5jb2RpbmcgPSAndXRmOCdcbiAgICBsZW5ndGggPSB0aGlzLmxlbmd0aFxuICAgIG9mZnNldCA9IDBcbiAgLy8gQnVmZmVyI3dyaXRlKHN0cmluZywgZW5jb2RpbmcpXG4gIH0gZWxzZSBpZiAobGVuZ3RoID09PSB1bmRlZmluZWQgJiYgdHlwZW9mIG9mZnNldCA9PT0gJ3N0cmluZycpIHtcbiAgICBlbmNvZGluZyA9IG9mZnNldFxuICAgIGxlbmd0aCA9IHRoaXMubGVuZ3RoXG4gICAgb2Zmc2V0ID0gMFxuICAvLyBCdWZmZXIjd3JpdGUoc3RyaW5nLCBvZmZzZXRbLCBsZW5ndGhdWywgZW5jb2RpbmddKVxuICB9IGVsc2UgaWYgKGlzRmluaXRlKG9mZnNldCkpIHtcbiAgICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgICBpZiAoaXNGaW5pdGUobGVuZ3RoKSkge1xuICAgICAgbGVuZ3RoID0gbGVuZ3RoID4+PiAwXG4gICAgICBpZiAoZW5jb2RpbmcgPT09IHVuZGVmaW5lZCkgZW5jb2RpbmcgPSAndXRmOCdcbiAgICB9IGVsc2Uge1xuICAgICAgZW5jb2RpbmcgPSBsZW5ndGhcbiAgICAgIGxlbmd0aCA9IHVuZGVmaW5lZFxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAnQnVmZmVyLndyaXRlKHN0cmluZywgZW5jb2RpbmcsIG9mZnNldFssIGxlbmd0aF0pIGlzIG5vIGxvbmdlciBzdXBwb3J0ZWQnXG4gICAgKVxuICB9XG5cbiAgdmFyIHJlbWFpbmluZyA9IHRoaXMubGVuZ3RoIC0gb2Zmc2V0XG4gIGlmIChsZW5ndGggPT09IHVuZGVmaW5lZCB8fCBsZW5ndGggPiByZW1haW5pbmcpIGxlbmd0aCA9IHJlbWFpbmluZ1xuXG4gIGlmICgoc3RyaW5nLmxlbmd0aCA+IDAgJiYgKGxlbmd0aCA8IDAgfHwgb2Zmc2V0IDwgMCkpIHx8IG9mZnNldCA+IHRoaXMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0F0dGVtcHQgdG8gd3JpdGUgb3V0c2lkZSBidWZmZXIgYm91bmRzJylcbiAgfVxuXG4gIGlmICghZW5jb2RpbmcpIGVuY29kaW5nID0gJ3V0ZjgnXG5cbiAgdmFyIGxvd2VyZWRDYXNlID0gZmFsc2VcbiAgZm9yICg7Oykge1xuICAgIHN3aXRjaCAoZW5jb2RpbmcpIHtcbiAgICAgIGNhc2UgJ2hleCc6XG4gICAgICAgIHJldHVybiBoZXhXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICd1dGY4JzpcbiAgICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgICAgcmV0dXJuIHV0ZjhXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICdhc2NpaSc6XG4gICAgICAgIHJldHVybiBhc2NpaVdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ2xhdGluMSc6XG4gICAgICBjYXNlICdiaW5hcnknOlxuICAgICAgICByZXR1cm4gbGF0aW4xV3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgICAgLy8gV2FybmluZzogbWF4TGVuZ3RoIG5vdCB0YWtlbiBpbnRvIGFjY291bnQgaW4gYmFzZTY0V3JpdGVcbiAgICAgICAgcmV0dXJuIGJhc2U2NFdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ3VjczInOlxuICAgICAgY2FzZSAndWNzLTInOlxuICAgICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICAgIHJldHVybiB1Y3MyV3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKGxvd2VyZWRDYXNlKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpXG4gICAgICAgIGVuY29kaW5nID0gKCcnICsgZW5jb2RpbmcpLnRvTG93ZXJDYXNlKClcbiAgICAgICAgbG93ZXJlZENhc2UgPSB0cnVlXG4gICAgfVxuICB9XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OICgpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiAnQnVmZmVyJyxcbiAgICBkYXRhOiBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbCh0aGlzLl9hcnIgfHwgdGhpcywgMClcbiAgfVxufVxuXG5mdW5jdGlvbiBiYXNlNjRTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIGlmIChzdGFydCA9PT0gMCAmJiBlbmQgPT09IGJ1Zi5sZW5ndGgpIHtcbiAgICByZXR1cm4gYmFzZTY0LmZyb21CeXRlQXJyYXkoYnVmKVxuICB9IGVsc2Uge1xuICAgIHJldHVybiBiYXNlNjQuZnJvbUJ5dGVBcnJheShidWYuc2xpY2Uoc3RhcnQsIGVuZCkpXG4gIH1cbn1cblxuZnVuY3Rpb24gdXRmOFNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgZW5kID0gTWF0aC5taW4oYnVmLmxlbmd0aCwgZW5kKVxuICB2YXIgcmVzID0gW11cblxuICB2YXIgaSA9IHN0YXJ0XG4gIHdoaWxlIChpIDwgZW5kKSB7XG4gICAgdmFyIGZpcnN0Qnl0ZSA9IGJ1ZltpXVxuICAgIHZhciBjb2RlUG9pbnQgPSBudWxsXG4gICAgdmFyIGJ5dGVzUGVyU2VxdWVuY2UgPSAoZmlyc3RCeXRlID4gMHhFRikgPyA0XG4gICAgICA6IChmaXJzdEJ5dGUgPiAweERGKSA/IDNcbiAgICAgICAgOiAoZmlyc3RCeXRlID4gMHhCRikgPyAyXG4gICAgICAgICAgOiAxXG5cbiAgICBpZiAoaSArIGJ5dGVzUGVyU2VxdWVuY2UgPD0gZW5kKSB7XG4gICAgICB2YXIgc2Vjb25kQnl0ZSwgdGhpcmRCeXRlLCBmb3VydGhCeXRlLCB0ZW1wQ29kZVBvaW50XG5cbiAgICAgIHN3aXRjaCAoYnl0ZXNQZXJTZXF1ZW5jZSkge1xuICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgaWYgKGZpcnN0Qnl0ZSA8IDB4ODApIHtcbiAgICAgICAgICAgIGNvZGVQb2ludCA9IGZpcnN0Qnl0ZVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgc2Vjb25kQnl0ZSA9IGJ1ZltpICsgMV1cbiAgICAgICAgICBpZiAoKHNlY29uZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCkge1xuICAgICAgICAgICAgdGVtcENvZGVQb2ludCA9IChmaXJzdEJ5dGUgJiAweDFGKSA8PCAweDYgfCAoc2Vjb25kQnl0ZSAmIDB4M0YpXG4gICAgICAgICAgICBpZiAodGVtcENvZGVQb2ludCA+IDB4N0YpIHtcbiAgICAgICAgICAgICAgY29kZVBvaW50ID0gdGVtcENvZGVQb2ludFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgc2Vjb25kQnl0ZSA9IGJ1ZltpICsgMV1cbiAgICAgICAgICB0aGlyZEJ5dGUgPSBidWZbaSArIDJdXG4gICAgICAgICAgaWYgKChzZWNvbmRCeXRlICYgMHhDMCkgPT09IDB4ODAgJiYgKHRoaXJkQnl0ZSAmIDB4QzApID09PSAweDgwKSB7XG4gICAgICAgICAgICB0ZW1wQ29kZVBvaW50ID0gKGZpcnN0Qnl0ZSAmIDB4RikgPDwgMHhDIHwgKHNlY29uZEJ5dGUgJiAweDNGKSA8PCAweDYgfCAodGhpcmRCeXRlICYgMHgzRilcbiAgICAgICAgICAgIGlmICh0ZW1wQ29kZVBvaW50ID4gMHg3RkYgJiYgKHRlbXBDb2RlUG9pbnQgPCAweEQ4MDAgfHwgdGVtcENvZGVQb2ludCA+IDB4REZGRikpIHtcbiAgICAgICAgICAgICAgY29kZVBvaW50ID0gdGVtcENvZGVQb2ludFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlIDQ6XG4gICAgICAgICAgc2Vjb25kQnl0ZSA9IGJ1ZltpICsgMV1cbiAgICAgICAgICB0aGlyZEJ5dGUgPSBidWZbaSArIDJdXG4gICAgICAgICAgZm91cnRoQnl0ZSA9IGJ1ZltpICsgM11cbiAgICAgICAgICBpZiAoKHNlY29uZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCAmJiAodGhpcmRCeXRlICYgMHhDMCkgPT09IDB4ODAgJiYgKGZvdXJ0aEJ5dGUgJiAweEMwKSA9PT0gMHg4MCkge1xuICAgICAgICAgICAgdGVtcENvZGVQb2ludCA9IChmaXJzdEJ5dGUgJiAweEYpIDw8IDB4MTIgfCAoc2Vjb25kQnl0ZSAmIDB4M0YpIDw8IDB4QyB8ICh0aGlyZEJ5dGUgJiAweDNGKSA8PCAweDYgfCAoZm91cnRoQnl0ZSAmIDB4M0YpXG4gICAgICAgICAgICBpZiAodGVtcENvZGVQb2ludCA+IDB4RkZGRiAmJiB0ZW1wQ29kZVBvaW50IDwgMHgxMTAwMDApIHtcbiAgICAgICAgICAgICAgY29kZVBvaW50ID0gdGVtcENvZGVQb2ludFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoY29kZVBvaW50ID09PSBudWxsKSB7XG4gICAgICAvLyB3ZSBkaWQgbm90IGdlbmVyYXRlIGEgdmFsaWQgY29kZVBvaW50IHNvIGluc2VydCBhXG4gICAgICAvLyByZXBsYWNlbWVudCBjaGFyIChVK0ZGRkQpIGFuZCBhZHZhbmNlIG9ubHkgMSBieXRlXG4gICAgICBjb2RlUG9pbnQgPSAweEZGRkRcbiAgICAgIGJ5dGVzUGVyU2VxdWVuY2UgPSAxXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPiAweEZGRkYpIHtcbiAgICAgIC8vIGVuY29kZSB0byB1dGYxNiAoc3Vycm9nYXRlIHBhaXIgZGFuY2UpXG4gICAgICBjb2RlUG9pbnQgLT0gMHgxMDAwMFxuICAgICAgcmVzLnB1c2goY29kZVBvaW50ID4+PiAxMCAmIDB4M0ZGIHwgMHhEODAwKVxuICAgICAgY29kZVBvaW50ID0gMHhEQzAwIHwgY29kZVBvaW50ICYgMHgzRkZcbiAgICB9XG5cbiAgICByZXMucHVzaChjb2RlUG9pbnQpXG4gICAgaSArPSBieXRlc1BlclNlcXVlbmNlXG4gIH1cblxuICByZXR1cm4gZGVjb2RlQ29kZVBvaW50c0FycmF5KHJlcylcbn1cblxuLy8gQmFzZWQgb24gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMjI3NDcyNzIvNjgwNzQyLCB0aGUgYnJvd3NlciB3aXRoXG4vLyB0aGUgbG93ZXN0IGxpbWl0IGlzIENocm9tZSwgd2l0aCAweDEwMDAwIGFyZ3MuXG4vLyBXZSBnbyAxIG1hZ25pdHVkZSBsZXNzLCBmb3Igc2FmZXR5XG52YXIgTUFYX0FSR1VNRU5UU19MRU5HVEggPSAweDEwMDBcblxuZnVuY3Rpb24gZGVjb2RlQ29kZVBvaW50c0FycmF5IChjb2RlUG9pbnRzKSB7XG4gIHZhciBsZW4gPSBjb2RlUG9pbnRzLmxlbmd0aFxuICBpZiAobGVuIDw9IE1BWF9BUkdVTUVOVFNfTEVOR1RIKSB7XG4gICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoU3RyaW5nLCBjb2RlUG9pbnRzKSAvLyBhdm9pZCBleHRyYSBzbGljZSgpXG4gIH1cblxuICAvLyBEZWNvZGUgaW4gY2h1bmtzIHRvIGF2b2lkIFwiY2FsbCBzdGFjayBzaXplIGV4Y2VlZGVkXCIuXG4gIHZhciByZXMgPSAnJ1xuICB2YXIgaSA9IDBcbiAgd2hpbGUgKGkgPCBsZW4pIHtcbiAgICByZXMgKz0gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShcbiAgICAgIFN0cmluZyxcbiAgICAgIGNvZGVQb2ludHMuc2xpY2UoaSwgaSArPSBNQVhfQVJHVU1FTlRTX0xFTkdUSClcbiAgICApXG4gIH1cbiAgcmV0dXJuIHJlc1xufVxuXG5mdW5jdGlvbiBhc2NpaVNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIHJldCA9ICcnXG4gIGVuZCA9IE1hdGgubWluKGJ1Zi5sZW5ndGgsIGVuZClcblxuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7ICsraSkge1xuICAgIHJldCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ1ZltpXSAmIDB4N0YpXG4gIH1cbiAgcmV0dXJuIHJldFxufVxuXG5mdW5jdGlvbiBsYXRpbjFTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciByZXQgPSAnJ1xuICBlbmQgPSBNYXRoLm1pbihidWYubGVuZ3RoLCBlbmQpXG5cbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyArK2kpIHtcbiAgICByZXQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShidWZbaV0pXG4gIH1cbiAgcmV0dXJuIHJldFxufVxuXG5mdW5jdGlvbiBoZXhTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciBsZW4gPSBidWYubGVuZ3RoXG5cbiAgaWYgKCFzdGFydCB8fCBzdGFydCA8IDApIHN0YXJ0ID0gMFxuICBpZiAoIWVuZCB8fCBlbmQgPCAwIHx8IGVuZCA+IGxlbikgZW5kID0gbGVuXG5cbiAgdmFyIG91dCA9ICcnXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgKytpKSB7XG4gICAgb3V0ICs9IHRvSGV4KGJ1ZltpXSlcbiAgfVxuICByZXR1cm4gb3V0XG59XG5cbmZ1bmN0aW9uIHV0ZjE2bGVTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciBieXRlcyA9IGJ1Zi5zbGljZShzdGFydCwgZW5kKVxuICB2YXIgcmVzID0gJydcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBieXRlcy5sZW5ndGg7IGkgKz0gMikge1xuICAgIHJlcyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ5dGVzW2ldICsgKGJ5dGVzW2kgKyAxXSAqIDI1NikpXG4gIH1cbiAgcmV0dXJuIHJlc1xufVxuXG5CdWZmZXIucHJvdG90eXBlLnNsaWNlID0gZnVuY3Rpb24gc2xpY2UgKHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGxlbiA9IHRoaXMubGVuZ3RoXG4gIHN0YXJ0ID0gfn5zdGFydFxuICBlbmQgPSBlbmQgPT09IHVuZGVmaW5lZCA/IGxlbiA6IH5+ZW5kXG5cbiAgaWYgKHN0YXJ0IDwgMCkge1xuICAgIHN0YXJ0ICs9IGxlblxuICAgIGlmIChzdGFydCA8IDApIHN0YXJ0ID0gMFxuICB9IGVsc2UgaWYgKHN0YXJ0ID4gbGVuKSB7XG4gICAgc3RhcnQgPSBsZW5cbiAgfVxuXG4gIGlmIChlbmQgPCAwKSB7XG4gICAgZW5kICs9IGxlblxuICAgIGlmIChlbmQgPCAwKSBlbmQgPSAwXG4gIH0gZWxzZSBpZiAoZW5kID4gbGVuKSB7XG4gICAgZW5kID0gbGVuXG4gIH1cblxuICBpZiAoZW5kIDwgc3RhcnQpIGVuZCA9IHN0YXJ0XG5cbiAgdmFyIG5ld0J1ZiA9IHRoaXMuc3ViYXJyYXkoc3RhcnQsIGVuZClcbiAgLy8gUmV0dXJuIGFuIGF1Z21lbnRlZCBgVWludDhBcnJheWAgaW5zdGFuY2VcbiAgbmV3QnVmLl9fcHJvdG9fXyA9IEJ1ZmZlci5wcm90b3R5cGVcbiAgcmV0dXJuIG5ld0J1ZlxufVxuXG4vKlxuICogTmVlZCB0byBtYWtlIHN1cmUgdGhhdCBidWZmZXIgaXNuJ3QgdHJ5aW5nIHRvIHdyaXRlIG91dCBvZiBib3VuZHMuXG4gKi9cbmZ1bmN0aW9uIGNoZWNrT2Zmc2V0IChvZmZzZXQsIGV4dCwgbGVuZ3RoKSB7XG4gIGlmICgob2Zmc2V0ICUgMSkgIT09IDAgfHwgb2Zmc2V0IDwgMCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ29mZnNldCBpcyBub3QgdWludCcpXG4gIGlmIChvZmZzZXQgKyBleHQgPiBsZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdUcnlpbmcgdG8gYWNjZXNzIGJleW9uZCBidWZmZXIgbGVuZ3RoJylcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludExFID0gZnVuY3Rpb24gcmVhZFVJbnRMRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcblxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXRdXG4gIHZhciBtdWwgPSAxXG4gIHZhciBpID0gMFxuICB3aGlsZSAoKytpIDwgYnl0ZUxlbmd0aCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHZhbCArPSB0aGlzW29mZnNldCArIGldICogbXVsXG4gIH1cblxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnRCRSA9IGZ1bmN0aW9uIHJlYWRVSW50QkUgKG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuICB9XG5cbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0ICsgLS1ieXRlTGVuZ3RoXVxuICB2YXIgbXVsID0gMVxuICB3aGlsZSAoYnl0ZUxlbmd0aCA+IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyAtLWJ5dGVMZW5ndGhdICogbXVsXG4gIH1cblxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQ4ID0gZnVuY3Rpb24gcmVhZFVJbnQ4IChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDEsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gdGhpc1tvZmZzZXRdXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQxNkxFID0gZnVuY3Rpb24gcmVhZFVJbnQxNkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gdGhpc1tvZmZzZXRdIHwgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgOClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDE2QkUgPSBmdW5jdGlvbiByZWFkVUludDE2QkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiAodGhpc1tvZmZzZXRdIDw8IDgpIHwgdGhpc1tvZmZzZXQgKyAxXVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MzJMRSA9IGZ1bmN0aW9uIHJlYWRVSW50MzJMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKCh0aGlzW29mZnNldF0pIHxcbiAgICAgICh0aGlzW29mZnNldCArIDFdIDw8IDgpIHxcbiAgICAgICh0aGlzW29mZnNldCArIDJdIDw8IDE2KSkgK1xuICAgICAgKHRoaXNbb2Zmc2V0ICsgM10gKiAweDEwMDAwMDApXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQzMkJFID0gZnVuY3Rpb24gcmVhZFVJbnQzMkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuXG4gIHJldHVybiAodGhpc1tvZmZzZXRdICogMHgxMDAwMDAwKSArXG4gICAgKCh0aGlzW29mZnNldCArIDFdIDw8IDE2KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgOCkgfFxuICAgIHRoaXNbb2Zmc2V0ICsgM10pXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludExFID0gZnVuY3Rpb24gcmVhZEludExFIChvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldF1cbiAgdmFyIG11bCA9IDFcbiAgdmFyIGkgPSAwXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgaV0gKiBtdWxcbiAgfVxuICBtdWwgKj0gMHg4MFxuXG4gIGlmICh2YWwgPj0gbXVsKSB2YWwgLT0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpXG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnRCRSA9IGZ1bmN0aW9uIHJlYWRJbnRCRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcblxuICB2YXIgaSA9IGJ5dGVMZW5ndGhcbiAgdmFyIG11bCA9IDFcbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0ICsgLS1pXVxuICB3aGlsZSAoaSA+IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyAtLWldICogbXVsXG4gIH1cbiAgbXVsICo9IDB4ODBcblxuICBpZiAodmFsID49IG11bCkgdmFsIC09IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50OCA9IGZ1bmN0aW9uIHJlYWRJbnQ4IChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDEsIHRoaXMubGVuZ3RoKVxuICBpZiAoISh0aGlzW29mZnNldF0gJiAweDgwKSkgcmV0dXJuICh0aGlzW29mZnNldF0pXG4gIHJldHVybiAoKDB4ZmYgLSB0aGlzW29mZnNldF0gKyAxKSAqIC0xKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQxNkxFID0gZnVuY3Rpb24gcmVhZEludDE2TEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldF0gfCAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KVxuICByZXR1cm4gKHZhbCAmIDB4ODAwMCkgPyB2YWwgfCAweEZGRkYwMDAwIDogdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDE2QkUgPSBmdW5jdGlvbiByZWFkSW50MTZCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAyLCB0aGlzLmxlbmd0aClcbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0ICsgMV0gfCAodGhpc1tvZmZzZXRdIDw8IDgpXG4gIHJldHVybiAodmFsICYgMHg4MDAwKSA/IHZhbCB8IDB4RkZGRjAwMDAgOiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MzJMRSA9IGZ1bmN0aW9uIHJlYWRJbnQzMkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuXG4gIHJldHVybiAodGhpc1tvZmZzZXRdKSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgOCkgfFxuICAgICh0aGlzW29mZnNldCArIDJdIDw8IDE2KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgM10gPDwgMjQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDMyQkUgPSBmdW5jdGlvbiByZWFkSW50MzJCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSA8PCAyNCkgfFxuICAgICh0aGlzW29mZnNldCArIDFdIDw8IDE2KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgOCkgfFxuICAgICh0aGlzW29mZnNldCArIDNdKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRGbG9hdExFID0gZnVuY3Rpb24gcmVhZEZsb2F0TEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCB0cnVlLCAyMywgNClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRmxvYXRCRSA9IGZ1bmN0aW9uIHJlYWRGbG9hdEJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gaWVlZTc1NC5yZWFkKHRoaXMsIG9mZnNldCwgZmFsc2UsIDIzLCA0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWREb3VibGVMRSA9IGZ1bmN0aW9uIHJlYWREb3VibGVMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA4LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIHRydWUsIDUyLCA4KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWREb3VibGVCRSA9IGZ1bmN0aW9uIHJlYWREb3VibGVCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA4LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIGZhbHNlLCA1MiwgOClcbn1cblxuZnVuY3Rpb24gY2hlY2tJbnQgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgZXh0LCBtYXgsIG1pbikge1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihidWYpKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImJ1ZmZlclwiIGFyZ3VtZW50IG11c3QgYmUgYSBCdWZmZXIgaW5zdGFuY2UnKVxuICBpZiAodmFsdWUgPiBtYXggfHwgdmFsdWUgPCBtaW4pIHRocm93IG5ldyBSYW5nZUVycm9yKCdcInZhbHVlXCIgYXJndW1lbnQgaXMgb3V0IG9mIGJvdW5kcycpXG4gIGlmIChvZmZzZXQgKyBleHQgPiBidWYubGVuZ3RoKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignSW5kZXggb3V0IG9mIHJhbmdlJylcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnRMRSA9IGZ1bmN0aW9uIHdyaXRlVUludExFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIHZhciBtYXhCeXRlcyA9IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKSAtIDFcbiAgICBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBtYXhCeXRlcywgMClcbiAgfVxuXG4gIHZhciBtdWwgPSAxXG4gIHZhciBpID0gMFxuICB0aGlzW29mZnNldF0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB0aGlzW29mZnNldCArIGldID0gKHZhbHVlIC8gbXVsKSAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50QkUgPSBmdW5jdGlvbiB3cml0ZVVJbnRCRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICB2YXIgbWF4Qnl0ZXMgPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aCkgLSAxXG4gICAgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbWF4Qnl0ZXMsIDApXG4gIH1cblxuICB2YXIgaSA9IGJ5dGVMZW5ndGggLSAxXG4gIHZhciBtdWwgPSAxXG4gIHRoaXNbb2Zmc2V0ICsgaV0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKC0taSA+PSAwICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdGhpc1tvZmZzZXQgKyBpXSA9ICh2YWx1ZSAvIG11bCkgJiAweEZGXG4gIH1cblxuICByZXR1cm4gb2Zmc2V0ICsgYnl0ZUxlbmd0aFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDggPSBmdW5jdGlvbiB3cml0ZVVJbnQ4ICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMSwgMHhmZiwgMClcbiAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgcmV0dXJuIG9mZnNldCArIDFcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQxNkxFID0gZnVuY3Rpb24gd3JpdGVVSW50MTZMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4ZmZmZiwgMClcbiAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gOClcbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQxNkJFID0gZnVuY3Rpb24gd3JpdGVVSW50MTZCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4ZmZmZiwgMClcbiAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiA4KVxuICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlICYgMHhmZilcbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQzMkxFID0gZnVuY3Rpb24gd3JpdGVVSW50MzJMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4ZmZmZmZmZmYsIDApXG4gIHRoaXNbb2Zmc2V0ICsgM10gPSAodmFsdWUgPj4+IDI0KVxuICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiAxNilcbiAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gOClcbiAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQzMkJFID0gZnVuY3Rpb24gd3JpdGVVSW50MzJCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4ZmZmZmZmZmYsIDApXG4gIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gMjQpXG4gIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDE2KVxuICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiA4KVxuICB0aGlzW29mZnNldCArIDNdID0gKHZhbHVlICYgMHhmZilcbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludExFID0gZnVuY3Rpb24gd3JpdGVJbnRMRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICB2YXIgbGltaXQgPSBNYXRoLnBvdygyLCAoOCAqIGJ5dGVMZW5ndGgpIC0gMSlcblxuICAgIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIGxpbWl0IC0gMSwgLWxpbWl0KVxuICB9XG5cbiAgdmFyIGkgPSAwXG4gIHZhciBtdWwgPSAxXG4gIHZhciBzdWIgPSAwXG4gIHRoaXNbb2Zmc2V0XSA9IHZhbHVlICYgMHhGRlxuICB3aGlsZSAoKytpIDwgYnl0ZUxlbmd0aCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIGlmICh2YWx1ZSA8IDAgJiYgc3ViID09PSAwICYmIHRoaXNbb2Zmc2V0ICsgaSAtIDFdICE9PSAwKSB7XG4gICAgICBzdWIgPSAxXG4gICAgfVxuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAoKHZhbHVlIC8gbXVsKSA+PiAwKSAtIHN1YiAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnRCRSA9IGZ1bmN0aW9uIHdyaXRlSW50QkUgKHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgdmFyIGxpbWl0ID0gTWF0aC5wb3coMiwgKDggKiBieXRlTGVuZ3RoKSAtIDEpXG5cbiAgICBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBsaW1pdCAtIDEsIC1saW1pdClcbiAgfVxuXG4gIHZhciBpID0gYnl0ZUxlbmd0aCAtIDFcbiAgdmFyIG11bCA9IDFcbiAgdmFyIHN1YiA9IDBcbiAgdGhpc1tvZmZzZXQgKyBpXSA9IHZhbHVlICYgMHhGRlxuICB3aGlsZSAoLS1pID49IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICBpZiAodmFsdWUgPCAwICYmIHN1YiA9PT0gMCAmJiB0aGlzW29mZnNldCArIGkgKyAxXSAhPT0gMCkge1xuICAgICAgc3ViID0gMVxuICAgIH1cbiAgICB0aGlzW29mZnNldCArIGldID0gKCh2YWx1ZSAvIG11bCkgPj4gMCkgLSBzdWIgJiAweEZGXG4gIH1cblxuICByZXR1cm4gb2Zmc2V0ICsgYnl0ZUxlbmd0aFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50OCA9IGZ1bmN0aW9uIHdyaXRlSW50OCAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDEsIDB4N2YsIC0weDgwKVxuICBpZiAodmFsdWUgPCAwKSB2YWx1ZSA9IDB4ZmYgKyB2YWx1ZSArIDFcbiAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgcmV0dXJuIG9mZnNldCArIDFcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDE2TEUgPSBmdW5jdGlvbiB3cml0ZUludDE2TEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAyLCAweDdmZmYsIC0weDgwMDApXG4gIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQxNkJFID0gZnVuY3Rpb24gd3JpdGVJbnQxNkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMiwgMHg3ZmZmLCAtMHg4MDAwKVxuICB0aGlzW29mZnNldF0gPSAodmFsdWUgPj4+IDgpXG4gIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgJiAweGZmKVxuICByZXR1cm4gb2Zmc2V0ICsgMlxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MzJMRSA9IGZ1bmN0aW9uIHdyaXRlSW50MzJMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4N2ZmZmZmZmYsIC0weDgwMDAwMDAwKVxuICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiAxNilcbiAgdGhpc1tvZmZzZXQgKyAzXSA9ICh2YWx1ZSA+Pj4gMjQpXG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQzMkJFID0gZnVuY3Rpb24gd3JpdGVJbnQzMkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgNCwgMHg3ZmZmZmZmZiwgLTB4ODAwMDAwMDApXG4gIGlmICh2YWx1ZSA8IDApIHZhbHVlID0gMHhmZmZmZmZmZiArIHZhbHVlICsgMVxuICB0aGlzW29mZnNldF0gPSAodmFsdWUgPj4+IDI0KVxuICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiAxNilcbiAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gOClcbiAgdGhpc1tvZmZzZXQgKyAzXSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbmZ1bmN0aW9uIGNoZWNrSUVFRTc1NCAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBleHQsIG1heCwgbWluKSB7XG4gIGlmIChvZmZzZXQgKyBleHQgPiBidWYubGVuZ3RoKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignSW5kZXggb3V0IG9mIHJhbmdlJylcbiAgaWYgKG9mZnNldCA8IDApIHRocm93IG5ldyBSYW5nZUVycm9yKCdJbmRleCBvdXQgb2YgcmFuZ2UnKVxufVxuXG5mdW5jdGlvbiB3cml0ZUZsb2F0IChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBjaGVja0lFRUU3NTQoYnVmLCB2YWx1ZSwgb2Zmc2V0LCA0LCAzLjQwMjgyMzQ2NjM4NTI4ODZlKzM4LCAtMy40MDI4MjM0NjYzODUyODg2ZSszOClcbiAgfVxuICBpZWVlNzU0LndyaXRlKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCAyMywgNClcbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUZsb2F0TEUgPSBmdW5jdGlvbiB3cml0ZUZsb2F0TEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiB3cml0ZUZsb2F0KHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRmxvYXRCRSA9IGZ1bmN0aW9uIHdyaXRlRmxvYXRCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHdyaXRlRmxvYXQodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG5mdW5jdGlvbiB3cml0ZURvdWJsZSAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgY2hlY2tJRUVFNzU0KGJ1ZiwgdmFsdWUsIG9mZnNldCwgOCwgMS43OTc2OTMxMzQ4NjIzMTU3RSszMDgsIC0xLjc5NzY5MzEzNDg2MjMxNTdFKzMwOClcbiAgfVxuICBpZWVlNzU0LndyaXRlKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCA1MiwgOClcbiAgcmV0dXJuIG9mZnNldCArIDhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZURvdWJsZUxFID0gZnVuY3Rpb24gd3JpdGVEb3VibGVMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHdyaXRlRG91YmxlKHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRG91YmxlQkUgPSBmdW5jdGlvbiB3cml0ZURvdWJsZUJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVEb3VibGUodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG4vLyBjb3B5KHRhcmdldEJ1ZmZlciwgdGFyZ2V0U3RhcnQ9MCwgc291cmNlU3RhcnQ9MCwgc291cmNlRW5kPWJ1ZmZlci5sZW5ndGgpXG5CdWZmZXIucHJvdG90eXBlLmNvcHkgPSBmdW5jdGlvbiBjb3B5ICh0YXJnZXQsIHRhcmdldFN0YXJ0LCBzdGFydCwgZW5kKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKHRhcmdldCkpIHRocm93IG5ldyBUeXBlRXJyb3IoJ2FyZ3VtZW50IHNob3VsZCBiZSBhIEJ1ZmZlcicpXG4gIGlmICghc3RhcnQpIHN0YXJ0ID0gMFxuICBpZiAoIWVuZCAmJiBlbmQgIT09IDApIGVuZCA9IHRoaXMubGVuZ3RoXG4gIGlmICh0YXJnZXRTdGFydCA+PSB0YXJnZXQubGVuZ3RoKSB0YXJnZXRTdGFydCA9IHRhcmdldC5sZW5ndGhcbiAgaWYgKCF0YXJnZXRTdGFydCkgdGFyZ2V0U3RhcnQgPSAwXG4gIGlmIChlbmQgPiAwICYmIGVuZCA8IHN0YXJ0KSBlbmQgPSBzdGFydFxuXG4gIC8vIENvcHkgMCBieXRlczsgd2UncmUgZG9uZVxuICBpZiAoZW5kID09PSBzdGFydCkgcmV0dXJuIDBcbiAgaWYgKHRhcmdldC5sZW5ndGggPT09IDAgfHwgdGhpcy5sZW5ndGggPT09IDApIHJldHVybiAwXG5cbiAgLy8gRmF0YWwgZXJyb3IgY29uZGl0aW9uc1xuICBpZiAodGFyZ2V0U3RhcnQgPCAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3RhcmdldFN0YXJ0IG91dCBvZiBib3VuZHMnKVxuICB9XG4gIGlmIChzdGFydCA8IDAgfHwgc3RhcnQgPj0gdGhpcy5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdJbmRleCBvdXQgb2YgcmFuZ2UnKVxuICBpZiAoZW5kIDwgMCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3NvdXJjZUVuZCBvdXQgb2YgYm91bmRzJylcblxuICAvLyBBcmUgd2Ugb29iP1xuICBpZiAoZW5kID4gdGhpcy5sZW5ndGgpIGVuZCA9IHRoaXMubGVuZ3RoXG4gIGlmICh0YXJnZXQubGVuZ3RoIC0gdGFyZ2V0U3RhcnQgPCBlbmQgLSBzdGFydCkge1xuICAgIGVuZCA9IHRhcmdldC5sZW5ndGggLSB0YXJnZXRTdGFydCArIHN0YXJ0XG4gIH1cblxuICB2YXIgbGVuID0gZW5kIC0gc3RhcnRcblxuICBpZiAodGhpcyA9PT0gdGFyZ2V0ICYmIHR5cGVvZiBVaW50OEFycmF5LnByb3RvdHlwZS5jb3B5V2l0aGluID09PSAnZnVuY3Rpb24nKSB7XG4gICAgLy8gVXNlIGJ1aWx0LWluIHdoZW4gYXZhaWxhYmxlLCBtaXNzaW5nIGZyb20gSUUxMVxuICAgIHRoaXMuY29weVdpdGhpbih0YXJnZXRTdGFydCwgc3RhcnQsIGVuZClcbiAgfSBlbHNlIGlmICh0aGlzID09PSB0YXJnZXQgJiYgc3RhcnQgPCB0YXJnZXRTdGFydCAmJiB0YXJnZXRTdGFydCA8IGVuZCkge1xuICAgIC8vIGRlc2NlbmRpbmcgY29weSBmcm9tIGVuZFxuICAgIGZvciAodmFyIGkgPSBsZW4gLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgdGFyZ2V0W2kgKyB0YXJnZXRTdGFydF0gPSB0aGlzW2kgKyBzdGFydF1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgVWludDhBcnJheS5wcm90b3R5cGUuc2V0LmNhbGwoXG4gICAgICB0YXJnZXQsXG4gICAgICB0aGlzLnN1YmFycmF5KHN0YXJ0LCBlbmQpLFxuICAgICAgdGFyZ2V0U3RhcnRcbiAgICApXG4gIH1cblxuICByZXR1cm4gbGVuXG59XG5cbi8vIFVzYWdlOlxuLy8gICAgYnVmZmVyLmZpbGwobnVtYmVyWywgb2Zmc2V0WywgZW5kXV0pXG4vLyAgICBidWZmZXIuZmlsbChidWZmZXJbLCBvZmZzZXRbLCBlbmRdXSlcbi8vICAgIGJ1ZmZlci5maWxsKHN0cmluZ1ssIG9mZnNldFssIGVuZF1dWywgZW5jb2RpbmddKVxuQnVmZmVyLnByb3RvdHlwZS5maWxsID0gZnVuY3Rpb24gZmlsbCAodmFsLCBzdGFydCwgZW5kLCBlbmNvZGluZykge1xuICAvLyBIYW5kbGUgc3RyaW5nIGNhc2VzOlxuICBpZiAodHlwZW9mIHZhbCA9PT0gJ3N0cmluZycpIHtcbiAgICBpZiAodHlwZW9mIHN0YXJ0ID09PSAnc3RyaW5nJykge1xuICAgICAgZW5jb2RpbmcgPSBzdGFydFxuICAgICAgc3RhcnQgPSAwXG4gICAgICBlbmQgPSB0aGlzLmxlbmd0aFxuICAgIH0gZWxzZSBpZiAodHlwZW9mIGVuZCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGVuY29kaW5nID0gZW5kXG4gICAgICBlbmQgPSB0aGlzLmxlbmd0aFxuICAgIH1cbiAgICBpZiAoZW5jb2RpbmcgIT09IHVuZGVmaW5lZCAmJiB0eXBlb2YgZW5jb2RpbmcgIT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdlbmNvZGluZyBtdXN0IGJlIGEgc3RyaW5nJylcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBlbmNvZGluZyA9PT0gJ3N0cmluZycgJiYgIUJ1ZmZlci5pc0VuY29kaW5nKGVuY29kaW5nKSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVW5rbm93biBlbmNvZGluZzogJyArIGVuY29kaW5nKVxuICAgIH1cbiAgICBpZiAodmFsLmxlbmd0aCA9PT0gMSkge1xuICAgICAgdmFyIGNvZGUgPSB2YWwuY2hhckNvZGVBdCgwKVxuICAgICAgaWYgKChlbmNvZGluZyA9PT0gJ3V0ZjgnICYmIGNvZGUgPCAxMjgpIHx8XG4gICAgICAgICAgZW5jb2RpbmcgPT09ICdsYXRpbjEnKSB7XG4gICAgICAgIC8vIEZhc3QgcGF0aDogSWYgYHZhbGAgZml0cyBpbnRvIGEgc2luZ2xlIGJ5dGUsIHVzZSB0aGF0IG51bWVyaWMgdmFsdWUuXG4gICAgICAgIHZhbCA9IGNvZGVcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSBpZiAodHlwZW9mIHZhbCA9PT0gJ251bWJlcicpIHtcbiAgICB2YWwgPSB2YWwgJiAyNTVcbiAgfVxuXG4gIC8vIEludmFsaWQgcmFuZ2VzIGFyZSBub3Qgc2V0IHRvIGEgZGVmYXVsdCwgc28gY2FuIHJhbmdlIGNoZWNrIGVhcmx5LlxuICBpZiAoc3RhcnQgPCAwIHx8IHRoaXMubGVuZ3RoIDwgc3RhcnQgfHwgdGhpcy5sZW5ndGggPCBlbmQpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignT3V0IG9mIHJhbmdlIGluZGV4JylcbiAgfVxuXG4gIGlmIChlbmQgPD0gc3RhcnQpIHtcbiAgICByZXR1cm4gdGhpc1xuICB9XG5cbiAgc3RhcnQgPSBzdGFydCA+Pj4gMFxuICBlbmQgPSBlbmQgPT09IHVuZGVmaW5lZCA/IHRoaXMubGVuZ3RoIDogZW5kID4+PiAwXG5cbiAgaWYgKCF2YWwpIHZhbCA9IDBcblxuICB2YXIgaVxuICBpZiAodHlwZW9mIHZhbCA9PT0gJ251bWJlcicpIHtcbiAgICBmb3IgKGkgPSBzdGFydDsgaSA8IGVuZDsgKytpKSB7XG4gICAgICB0aGlzW2ldID0gdmFsXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHZhciBieXRlcyA9IEJ1ZmZlci5pc0J1ZmZlcih2YWwpXG4gICAgICA/IHZhbFxuICAgICAgOiBCdWZmZXIuZnJvbSh2YWwsIGVuY29kaW5nKVxuICAgIHZhciBsZW4gPSBieXRlcy5sZW5ndGhcbiAgICBpZiAobGVuID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgdmFsdWUgXCInICsgdmFsICtcbiAgICAgICAgJ1wiIGlzIGludmFsaWQgZm9yIGFyZ3VtZW50IFwidmFsdWVcIicpXG4gICAgfVxuICAgIGZvciAoaSA9IDA7IGkgPCBlbmQgLSBzdGFydDsgKytpKSB7XG4gICAgICB0aGlzW2kgKyBzdGFydF0gPSBieXRlc1tpICUgbGVuXVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0aGlzXG59XG5cbi8vIEhFTFBFUiBGVU5DVElPTlNcbi8vID09PT09PT09PT09PT09PT1cblxudmFyIElOVkFMSURfQkFTRTY0X1JFID0gL1teKy8wLTlBLVphLXotX10vZ1xuXG5mdW5jdGlvbiBiYXNlNjRjbGVhbiAoc3RyKSB7XG4gIC8vIE5vZGUgdGFrZXMgZXF1YWwgc2lnbnMgYXMgZW5kIG9mIHRoZSBCYXNlNjQgZW5jb2RpbmdcbiAgc3RyID0gc3RyLnNwbGl0KCc9JylbMF1cbiAgLy8gTm9kZSBzdHJpcHMgb3V0IGludmFsaWQgY2hhcmFjdGVycyBsaWtlIFxcbiBhbmQgXFx0IGZyb20gdGhlIHN0cmluZywgYmFzZTY0LWpzIGRvZXMgbm90XG4gIHN0ciA9IHN0ci50cmltKCkucmVwbGFjZShJTlZBTElEX0JBU0U2NF9SRSwgJycpXG4gIC8vIE5vZGUgY29udmVydHMgc3RyaW5ncyB3aXRoIGxlbmd0aCA8IDIgdG8gJydcbiAgaWYgKHN0ci5sZW5ndGggPCAyKSByZXR1cm4gJydcbiAgLy8gTm9kZSBhbGxvd3MgZm9yIG5vbi1wYWRkZWQgYmFzZTY0IHN0cmluZ3MgKG1pc3NpbmcgdHJhaWxpbmcgPT09KSwgYmFzZTY0LWpzIGRvZXMgbm90XG4gIHdoaWxlIChzdHIubGVuZ3RoICUgNCAhPT0gMCkge1xuICAgIHN0ciA9IHN0ciArICc9J1xuICB9XG4gIHJldHVybiBzdHJcbn1cblxuZnVuY3Rpb24gdG9IZXggKG4pIHtcbiAgaWYgKG4gPCAxNikgcmV0dXJuICcwJyArIG4udG9TdHJpbmcoMTYpXG4gIHJldHVybiBuLnRvU3RyaW5nKDE2KVxufVxuXG5mdW5jdGlvbiB1dGY4VG9CeXRlcyAoc3RyaW5nLCB1bml0cykge1xuICB1bml0cyA9IHVuaXRzIHx8IEluZmluaXR5XG4gIHZhciBjb2RlUG9pbnRcbiAgdmFyIGxlbmd0aCA9IHN0cmluZy5sZW5ndGhcbiAgdmFyIGxlYWRTdXJyb2dhdGUgPSBudWxsXG4gIHZhciBieXRlcyA9IFtdXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkge1xuICAgIGNvZGVQb2ludCA9IHN0cmluZy5jaGFyQ29kZUF0KGkpXG5cbiAgICAvLyBpcyBzdXJyb2dhdGUgY29tcG9uZW50XG4gICAgaWYgKGNvZGVQb2ludCA+IDB4RDdGRiAmJiBjb2RlUG9pbnQgPCAweEUwMDApIHtcbiAgICAgIC8vIGxhc3QgY2hhciB3YXMgYSBsZWFkXG4gICAgICBpZiAoIWxlYWRTdXJyb2dhdGUpIHtcbiAgICAgICAgLy8gbm8gbGVhZCB5ZXRcbiAgICAgICAgaWYgKGNvZGVQb2ludCA+IDB4REJGRikge1xuICAgICAgICAgIC8vIHVuZXhwZWN0ZWQgdHJhaWxcbiAgICAgICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9IGVsc2UgaWYgKGkgKyAxID09PSBsZW5ndGgpIHtcbiAgICAgICAgICAvLyB1bnBhaXJlZCBsZWFkXG4gICAgICAgICAgaWYgKCh1bml0cyAtPSAzKSA+IC0xKSBieXRlcy5wdXNoKDB4RUYsIDB4QkYsIDB4QkQpXG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHZhbGlkIGxlYWRcbiAgICAgICAgbGVhZFN1cnJvZ2F0ZSA9IGNvZGVQb2ludFxuXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIC8vIDIgbGVhZHMgaW4gYSByb3dcbiAgICAgIGlmIChjb2RlUG9pbnQgPCAweERDMDApIHtcbiAgICAgICAgaWYgKCh1bml0cyAtPSAzKSA+IC0xKSBieXRlcy5wdXNoKDB4RUYsIDB4QkYsIDB4QkQpXG4gICAgICAgIGxlYWRTdXJyb2dhdGUgPSBjb2RlUG9pbnRcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgLy8gdmFsaWQgc3Vycm9nYXRlIHBhaXJcbiAgICAgIGNvZGVQb2ludCA9IChsZWFkU3Vycm9nYXRlIC0gMHhEODAwIDw8IDEwIHwgY29kZVBvaW50IC0gMHhEQzAwKSArIDB4MTAwMDBcbiAgICB9IGVsc2UgaWYgKGxlYWRTdXJyb2dhdGUpIHtcbiAgICAgIC8vIHZhbGlkIGJtcCBjaGFyLCBidXQgbGFzdCBjaGFyIHdhcyBhIGxlYWRcbiAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgIH1cblxuICAgIGxlYWRTdXJyb2dhdGUgPSBudWxsXG5cbiAgICAvLyBlbmNvZGUgdXRmOFxuICAgIGlmIChjb2RlUG9pbnQgPCAweDgwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDEpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goY29kZVBvaW50KVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50IDwgMHg4MDApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gMikgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChcbiAgICAgICAgY29kZVBvaW50ID4+IDB4NiB8IDB4QzAsXG4gICAgICAgIGNvZGVQb2ludCAmIDB4M0YgfCAweDgwXG4gICAgICApXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPCAweDEwMDAwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDMpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goXG4gICAgICAgIGNvZGVQb2ludCA+PiAweEMgfCAweEUwLFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHg2ICYgMHgzRiB8IDB4ODAsXG4gICAgICAgIGNvZGVQb2ludCAmIDB4M0YgfCAweDgwXG4gICAgICApXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPCAweDExMDAwMCkge1xuICAgICAgaWYgKCh1bml0cyAtPSA0KSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHgxMiB8IDB4RjAsXG4gICAgICAgIGNvZGVQb2ludCA+PiAweEMgJiAweDNGIHwgMHg4MCxcbiAgICAgICAgY29kZVBvaW50ID4+IDB4NiAmIDB4M0YgfCAweDgwLFxuICAgICAgICBjb2RlUG9pbnQgJiAweDNGIHwgMHg4MFxuICAgICAgKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgY29kZSBwb2ludCcpXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGJ5dGVzXG59XG5cbmZ1bmN0aW9uIGFzY2lpVG9CeXRlcyAoc3RyKSB7XG4gIHZhciBieXRlQXJyYXkgPSBbXVxuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0ci5sZW5ndGg7ICsraSkge1xuICAgIC8vIE5vZGUncyBjb2RlIHNlZW1zIHRvIGJlIGRvaW5nIHRoaXMgYW5kIG5vdCAmIDB4N0YuLlxuICAgIGJ5dGVBcnJheS5wdXNoKHN0ci5jaGFyQ29kZUF0KGkpICYgMHhGRilcbiAgfVxuICByZXR1cm4gYnl0ZUFycmF5XG59XG5cbmZ1bmN0aW9uIHV0ZjE2bGVUb0J5dGVzIChzdHIsIHVuaXRzKSB7XG4gIHZhciBjLCBoaSwgbG9cbiAgdmFyIGJ5dGVBcnJheSA9IFtdXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgKytpKSB7XG4gICAgaWYgKCh1bml0cyAtPSAyKSA8IDApIGJyZWFrXG5cbiAgICBjID0gc3RyLmNoYXJDb2RlQXQoaSlcbiAgICBoaSA9IGMgPj4gOFxuICAgIGxvID0gYyAlIDI1NlxuICAgIGJ5dGVBcnJheS5wdXNoKGxvKVxuICAgIGJ5dGVBcnJheS5wdXNoKGhpKVxuICB9XG5cbiAgcmV0dXJuIGJ5dGVBcnJheVxufVxuXG5mdW5jdGlvbiBiYXNlNjRUb0J5dGVzIChzdHIpIHtcbiAgcmV0dXJuIGJhc2U2NC50b0J5dGVBcnJheShiYXNlNjRjbGVhbihzdHIpKVxufVxuXG5mdW5jdGlvbiBibGl0QnVmZmVyIChzcmMsIGRzdCwgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkge1xuICAgIGlmICgoaSArIG9mZnNldCA+PSBkc3QubGVuZ3RoKSB8fCAoaSA+PSBzcmMubGVuZ3RoKSkgYnJlYWtcbiAgICBkc3RbaSArIG9mZnNldF0gPSBzcmNbaV1cbiAgfVxuICByZXR1cm4gaVxufVxuXG4vLyBBcnJheUJ1ZmZlciBvciBVaW50OEFycmF5IG9iamVjdHMgZnJvbSBvdGhlciBjb250ZXh0cyAoaS5lLiBpZnJhbWVzKSBkbyBub3QgcGFzc1xuLy8gdGhlIGBpbnN0YW5jZW9mYCBjaGVjayBidXQgdGhleSBzaG91bGQgYmUgdHJlYXRlZCBhcyBvZiB0aGF0IHR5cGUuXG4vLyBTZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9mZXJvc3MvYnVmZmVyL2lzc3Vlcy8xNjZcbmZ1bmN0aW9uIGlzSW5zdGFuY2UgKG9iaiwgdHlwZSkge1xuICByZXR1cm4gb2JqIGluc3RhbmNlb2YgdHlwZSB8fFxuICAgIChvYmogIT0gbnVsbCAmJiBvYmouY29uc3RydWN0b3IgIT0gbnVsbCAmJiBvYmouY29uc3RydWN0b3IubmFtZSAhPSBudWxsICYmXG4gICAgICBvYmouY29uc3RydWN0b3IubmFtZSA9PT0gdHlwZS5uYW1lKVxufVxuZnVuY3Rpb24gbnVtYmVySXNOYU4gKG9iaikge1xuICAvLyBGb3IgSUUxMSBzdXBwb3J0XG4gIHJldHVybiBvYmogIT09IG9iaiAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXNlbGYtY29tcGFyZVxufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYmluZCA9IHJlcXVpcmUoJ2Z1bmN0aW9uLWJpbmQnKTtcblxudmFyICRhcHBseSA9IHJlcXVpcmUoJy4vZnVuY3Rpb25BcHBseScpO1xudmFyICRjYWxsID0gcmVxdWlyZSgnLi9mdW5jdGlvbkNhbGwnKTtcbnZhciAkcmVmbGVjdEFwcGx5ID0gcmVxdWlyZSgnLi9yZWZsZWN0QXBwbHknKTtcblxuLyoqIEB0eXBlIHtpbXBvcnQoJy4vYWN0dWFsQXBwbHknKX0gKi9cbm1vZHVsZS5leHBvcnRzID0gJHJlZmxlY3RBcHBseSB8fCBiaW5kLmNhbGwoJGNhbGwsICRhcHBseSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKiBAdHlwZSB7aW1wb3J0KCcuL2Z1bmN0aW9uQXBwbHknKX0gKi9cbm1vZHVsZS5leHBvcnRzID0gRnVuY3Rpb24ucHJvdG90eXBlLmFwcGx5O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKiogQHR5cGUge2ltcG9ydCgnLi9mdW5jdGlvbkNhbGwnKX0gKi9cbm1vZHVsZS5leHBvcnRzID0gRnVuY3Rpb24ucHJvdG90eXBlLmNhbGw7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBiaW5kID0gcmVxdWlyZSgnZnVuY3Rpb24tYmluZCcpO1xudmFyICRUeXBlRXJyb3IgPSByZXF1aXJlKCdlcy1lcnJvcnMvdHlwZScpO1xuXG52YXIgJGNhbGwgPSByZXF1aXJlKCcuL2Z1bmN0aW9uQ2FsbCcpO1xudmFyICRhY3R1YWxBcHBseSA9IHJlcXVpcmUoJy4vYWN0dWFsQXBwbHknKTtcblxuLyoqIEB0eXBlIHtpbXBvcnQoJy4nKX0gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gY2FsbEJpbmRCYXNpYyhhcmdzKSB7XG5cdGlmIChhcmdzLmxlbmd0aCA8IDEgfHwgdHlwZW9mIGFyZ3NbMF0gIT09ICdmdW5jdGlvbicpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignYSBmdW5jdGlvbiBpcyByZXF1aXJlZCcpO1xuXHR9XG5cdHJldHVybiAkYWN0dWFsQXBwbHkoYmluZCwgJGNhbGwsIGFyZ3MpO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqIEB0eXBlIHtpbXBvcnQoJy4vcmVmbGVjdEFwcGx5Jyl9ICovXG5tb2R1bGUuZXhwb3J0cyA9IHR5cGVvZiBSZWZsZWN0ICE9PSAndW5kZWZpbmVkJyAmJiBSZWZsZWN0ICYmIFJlZmxlY3QuYXBwbHk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG5cbnZhciBjYWxsQmluZEJhc2ljID0gcmVxdWlyZSgnY2FsbC1iaW5kLWFwcGx5LWhlbHBlcnMnKTtcblxuLyoqIEB0eXBlIHsodGhpc0FyZzogc3RyaW5nLCBzZWFyY2hTdHJpbmc6IHN0cmluZywgcG9zaXRpb24/OiBudW1iZXIpID0+IG51bWJlcn0gKi9cbnZhciAkaW5kZXhPZiA9IGNhbGxCaW5kQmFzaWMoW0dldEludHJpbnNpYygnJVN0cmluZy5wcm90b3R5cGUuaW5kZXhPZiUnKV0pO1xuXG4vKiogQHR5cGUge2ltcG9ydCgnLicpfSAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBjYWxsQm91bmRJbnRyaW5zaWMobmFtZSwgYWxsb3dNaXNzaW5nKSB7XG5cdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1leHRyYS1wYXJlbnNcblx0dmFyIGludHJpbnNpYyA9IC8qKiBAdHlwZSB7UGFyYW1ldGVyczx0eXBlb2YgY2FsbEJpbmRCYXNpYz5bMF1bMF19ICovIChHZXRJbnRyaW5zaWMobmFtZSwgISFhbGxvd01pc3NpbmcpKTtcblx0aWYgKHR5cGVvZiBpbnRyaW5zaWMgPT09ICdmdW5jdGlvbicgJiYgJGluZGV4T2YobmFtZSwgJy5wcm90b3R5cGUuJykgPiAtMSkge1xuXHRcdHJldHVybiBjYWxsQmluZEJhc2ljKFtpbnRyaW5zaWNdKTtcblx0fVxuXHRyZXR1cm4gaW50cmluc2ljO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGNhbGxCaW5kID0gcmVxdWlyZSgnY2FsbC1iaW5kLWFwcGx5LWhlbHBlcnMnKTtcbnZhciBnT1BEID0gcmVxdWlyZSgnZ29wZCcpO1xuXG52YXIgaGFzUHJvdG9BY2Nlc3NvcjtcbnRyeSB7XG5cdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1leHRyYS1wYXJlbnMsIG5vLXByb3RvXG5cdGhhc1Byb3RvQWNjZXNzb3IgPSAvKiogQHR5cGUge3sgX19wcm90b19fPzogdHlwZW9mIEFycmF5LnByb3RvdHlwZSB9fSAqLyAoW10pLl9fcHJvdG9fXyA9PT0gQXJyYXkucHJvdG90eXBlO1xufSBjYXRjaCAoZSkge1xuXHRpZiAoIWUgfHwgdHlwZW9mIGUgIT09ICdvYmplY3QnIHx8ICEoJ2NvZGUnIGluIGUpIHx8IGUuY29kZSAhPT0gJ0VSUl9QUk9UT19BQ0NFU1MnKSB7XG5cdFx0dGhyb3cgZTtcblx0fVxufVxuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tZXh0cmEtcGFyZW5zXG52YXIgZGVzYyA9ICEhaGFzUHJvdG9BY2Nlc3NvciAmJiBnT1BEICYmIGdPUEQoT2JqZWN0LnByb3RvdHlwZSwgLyoqIEB0eXBlIHtrZXlvZiB0eXBlb2YgT2JqZWN0LnByb3RvdHlwZX0gKi8gKCdfX3Byb3RvX18nKSk7XG5cbnZhciAkT2JqZWN0ID0gT2JqZWN0O1xudmFyICRnZXRQcm90b3R5cGVPZiA9ICRPYmplY3QuZ2V0UHJvdG90eXBlT2Y7XG5cbi8qKiBAdHlwZSB7aW1wb3J0KCcuL2dldCcpfSAqL1xubW9kdWxlLmV4cG9ydHMgPSBkZXNjICYmIHR5cGVvZiBkZXNjLmdldCA9PT0gJ2Z1bmN0aW9uJ1xuXHQ/IGNhbGxCaW5kKFtkZXNjLmdldF0pXG5cdDogdHlwZW9mICRnZXRQcm90b3R5cGVPZiA9PT0gJ2Z1bmN0aW9uJ1xuXHRcdD8gLyoqIEB0eXBlIHtpbXBvcnQoJy4vZ2V0Jyl9ICovIGZ1bmN0aW9uIGdldER1bmRlcih2YWx1ZSkge1xuXHRcdFx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGVxZXFlcVxuXHRcdFx0cmV0dXJuICRnZXRQcm90b3R5cGVPZih2YWx1ZSA9PSBudWxsID8gdmFsdWUgOiAkT2JqZWN0KHZhbHVlKSk7XG5cdFx0fVxuXHRcdDogZmFsc2U7XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKiBAdHlwZSB7aW1wb3J0KCcuJyl9ICovXG52YXIgJGRlZmluZVByb3BlcnR5ID0gT2JqZWN0LmRlZmluZVByb3BlcnR5IHx8IGZhbHNlO1xuaWYgKCRkZWZpbmVQcm9wZXJ0eSkge1xuXHR0cnkge1xuXHRcdCRkZWZpbmVQcm9wZXJ0eSh7fSwgJ2EnLCB7IHZhbHVlOiAxIH0pO1xuXHR9IGNhdGNoIChlKSB7XG5cdFx0Ly8gSUUgOCBoYXMgYSBicm9rZW4gZGVmaW5lUHJvcGVydHlcblx0XHQkZGVmaW5lUHJvcGVydHkgPSBmYWxzZTtcblx0fVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9ICRkZWZpbmVQcm9wZXJ0eTtcbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqIEB0eXBlIHtpbXBvcnQoJy4vZXZhbCcpfSAqL1xubW9kdWxlLmV4cG9ydHMgPSBFdmFsRXJyb3I7XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKiBAdHlwZSB7aW1wb3J0KCcuJyl9ICovXG5tb2R1bGUuZXhwb3J0cyA9IEVycm9yO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKiogQHR5cGUge2ltcG9ydCgnLi9yYW5nZScpfSAqL1xubW9kdWxlLmV4cG9ydHMgPSBSYW5nZUVycm9yO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKiogQHR5cGUge2ltcG9ydCgnLi9yZWYnKX0gKi9cbm1vZHVsZS5leHBvcnRzID0gUmVmZXJlbmNlRXJyb3I7XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKiBAdHlwZSB7aW1wb3J0KCcuL3N5bnRheCcpfSAqL1xubW9kdWxlLmV4cG9ydHMgPSBTeW50YXhFcnJvcjtcbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqIEB0eXBlIHtpbXBvcnQoJy4vdHlwZScpfSAqL1xubW9kdWxlLmV4cG9ydHMgPSBUeXBlRXJyb3I7XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKiBAdHlwZSB7aW1wb3J0KCcuL3VyaScpfSAqL1xubW9kdWxlLmV4cG9ydHMgPSBVUklFcnJvcjtcbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqIEB0eXBlIHtpbXBvcnQoJy4nKX0gKi9cbm1vZHVsZS5leHBvcnRzID0gT2JqZWN0O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKiBlc2xpbnQgbm8taW52YWxpZC10aGlzOiAxICovXG5cbnZhciBFUlJPUl9NRVNTQUdFID0gJ0Z1bmN0aW9uLnByb3RvdHlwZS5iaW5kIGNhbGxlZCBvbiBpbmNvbXBhdGlibGUgJztcbnZhciB0b1N0ciA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG52YXIgbWF4ID0gTWF0aC5tYXg7XG52YXIgZnVuY1R5cGUgPSAnW29iamVjdCBGdW5jdGlvbl0nO1xuXG52YXIgY29uY2F0dHkgPSBmdW5jdGlvbiBjb25jYXR0eShhLCBiKSB7XG4gICAgdmFyIGFyciA9IFtdO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgIGFycltpXSA9IGFbaV07XG4gICAgfVxuICAgIGZvciAodmFyIGogPSAwOyBqIDwgYi5sZW5ndGg7IGogKz0gMSkge1xuICAgICAgICBhcnJbaiArIGEubGVuZ3RoXSA9IGJbal07XG4gICAgfVxuXG4gICAgcmV0dXJuIGFycjtcbn07XG5cbnZhciBzbGljeSA9IGZ1bmN0aW9uIHNsaWN5KGFyckxpa2UsIG9mZnNldCkge1xuICAgIHZhciBhcnIgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gb2Zmc2V0IHx8IDAsIGogPSAwOyBpIDwgYXJyTGlrZS5sZW5ndGg7IGkgKz0gMSwgaiArPSAxKSB7XG4gICAgICAgIGFycltqXSA9IGFyckxpa2VbaV07XG4gICAgfVxuICAgIHJldHVybiBhcnI7XG59O1xuXG52YXIgam9pbnkgPSBmdW5jdGlvbiAoYXJyLCBqb2luZXIpIHtcbiAgICB2YXIgc3RyID0gJyc7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgc3RyICs9IGFycltpXTtcbiAgICAgICAgaWYgKGkgKyAxIDwgYXJyLmxlbmd0aCkge1xuICAgICAgICAgICAgc3RyICs9IGpvaW5lcjtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gc3RyO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBiaW5kKHRoYXQpIHtcbiAgICB2YXIgdGFyZ2V0ID0gdGhpcztcbiAgICBpZiAodHlwZW9mIHRhcmdldCAhPT0gJ2Z1bmN0aW9uJyB8fCB0b1N0ci5hcHBseSh0YXJnZXQpICE9PSBmdW5jVHlwZSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKEVSUk9SX01FU1NBR0UgKyB0YXJnZXQpO1xuICAgIH1cbiAgICB2YXIgYXJncyA9IHNsaWN5KGFyZ3VtZW50cywgMSk7XG5cbiAgICB2YXIgYm91bmQ7XG4gICAgdmFyIGJpbmRlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMgaW5zdGFuY2VvZiBib3VuZCkge1xuICAgICAgICAgICAgdmFyIHJlc3VsdCA9IHRhcmdldC5hcHBseShcbiAgICAgICAgICAgICAgICB0aGlzLFxuICAgICAgICAgICAgICAgIGNvbmNhdHR5KGFyZ3MsIGFyZ3VtZW50cylcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBpZiAoT2JqZWN0KHJlc3VsdCkgPT09IHJlc3VsdCkge1xuICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGFyZ2V0LmFwcGx5KFxuICAgICAgICAgICAgdGhhdCxcbiAgICAgICAgICAgIGNvbmNhdHR5KGFyZ3MsIGFyZ3VtZW50cylcbiAgICAgICAgKTtcblxuICAgIH07XG5cbiAgICB2YXIgYm91bmRMZW5ndGggPSBtYXgoMCwgdGFyZ2V0Lmxlbmd0aCAtIGFyZ3MubGVuZ3RoKTtcbiAgICB2YXIgYm91bmRBcmdzID0gW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBib3VuZExlbmd0aDsgaSsrKSB7XG4gICAgICAgIGJvdW5kQXJnc1tpXSA9ICckJyArIGk7XG4gICAgfVxuXG4gICAgYm91bmQgPSBGdW5jdGlvbignYmluZGVyJywgJ3JldHVybiBmdW5jdGlvbiAoJyArIGpvaW55KGJvdW5kQXJncywgJywnKSArICcpeyByZXR1cm4gYmluZGVyLmFwcGx5KHRoaXMsYXJndW1lbnRzKTsgfScpKGJpbmRlcik7XG5cbiAgICBpZiAodGFyZ2V0LnByb3RvdHlwZSkge1xuICAgICAgICB2YXIgRW1wdHkgPSBmdW5jdGlvbiBFbXB0eSgpIHt9O1xuICAgICAgICBFbXB0eS5wcm90b3R5cGUgPSB0YXJnZXQucHJvdG90eXBlO1xuICAgICAgICBib3VuZC5wcm90b3R5cGUgPSBuZXcgRW1wdHkoKTtcbiAgICAgICAgRW1wdHkucHJvdG90eXBlID0gbnVsbDtcbiAgICB9XG5cbiAgICByZXR1cm4gYm91bmQ7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgaW1wbGVtZW50YXRpb24gPSByZXF1aXJlKCcuL2ltcGxlbWVudGF0aW9uJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQgfHwgaW1wbGVtZW50YXRpb247XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciB1bmRlZmluZWQ7XG5cbnZhciAkT2JqZWN0ID0gcmVxdWlyZSgnZXMtb2JqZWN0LWF0b21zJyk7XG5cbnZhciAkRXJyb3IgPSByZXF1aXJlKCdlcy1lcnJvcnMnKTtcbnZhciAkRXZhbEVycm9yID0gcmVxdWlyZSgnZXMtZXJyb3JzL2V2YWwnKTtcbnZhciAkUmFuZ2VFcnJvciA9IHJlcXVpcmUoJ2VzLWVycm9ycy9yYW5nZScpO1xudmFyICRSZWZlcmVuY2VFcnJvciA9IHJlcXVpcmUoJ2VzLWVycm9ycy9yZWYnKTtcbnZhciAkU3ludGF4RXJyb3IgPSByZXF1aXJlKCdlcy1lcnJvcnMvc3ludGF4Jyk7XG52YXIgJFR5cGVFcnJvciA9IHJlcXVpcmUoJ2VzLWVycm9ycy90eXBlJyk7XG52YXIgJFVSSUVycm9yID0gcmVxdWlyZSgnZXMtZXJyb3JzL3VyaScpO1xuXG52YXIgYWJzID0gcmVxdWlyZSgnbWF0aC1pbnRyaW5zaWNzL2FicycpO1xudmFyIGZsb29yID0gcmVxdWlyZSgnbWF0aC1pbnRyaW5zaWNzL2Zsb29yJyk7XG52YXIgbWF4ID0gcmVxdWlyZSgnbWF0aC1pbnRyaW5zaWNzL21heCcpO1xudmFyIG1pbiA9IHJlcXVpcmUoJ21hdGgtaW50cmluc2ljcy9taW4nKTtcbnZhciBwb3cgPSByZXF1aXJlKCdtYXRoLWludHJpbnNpY3MvcG93Jyk7XG52YXIgcm91bmQgPSByZXF1aXJlKCdtYXRoLWludHJpbnNpY3Mvcm91bmQnKTtcbnZhciBzaWduID0gcmVxdWlyZSgnbWF0aC1pbnRyaW5zaWNzL3NpZ24nKTtcblxudmFyICRGdW5jdGlvbiA9IEZ1bmN0aW9uO1xuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY29uc2lzdGVudC1yZXR1cm5cbnZhciBnZXRFdmFsbGVkQ29uc3RydWN0b3IgPSBmdW5jdGlvbiAoZXhwcmVzc2lvblN5bnRheCkge1xuXHR0cnkge1xuXHRcdHJldHVybiAkRnVuY3Rpb24oJ1widXNlIHN0cmljdFwiOyByZXR1cm4gKCcgKyBleHByZXNzaW9uU3ludGF4ICsgJykuY29uc3RydWN0b3I7JykoKTtcblx0fSBjYXRjaCAoZSkge31cbn07XG5cbnZhciAkZ09QRCA9IHJlcXVpcmUoJ2dvcGQnKTtcbnZhciAkZGVmaW5lUHJvcGVydHkgPSByZXF1aXJlKCdlcy1kZWZpbmUtcHJvcGVydHknKTtcblxudmFyIHRocm93VHlwZUVycm9yID0gZnVuY3Rpb24gKCkge1xuXHR0aHJvdyBuZXcgJFR5cGVFcnJvcigpO1xufTtcbnZhciBUaHJvd1R5cGVFcnJvciA9ICRnT1BEXG5cdD8gKGZ1bmN0aW9uICgpIHtcblx0XHR0cnkge1xuXHRcdFx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVudXNlZC1leHByZXNzaW9ucywgbm8tY2FsbGVyLCBuby1yZXN0cmljdGVkLXByb3BlcnRpZXNcblx0XHRcdGFyZ3VtZW50cy5jYWxsZWU7IC8vIElFIDggZG9lcyBub3QgdGhyb3cgaGVyZVxuXHRcdFx0cmV0dXJuIHRocm93VHlwZUVycm9yO1xuXHRcdH0gY2F0Y2ggKGNhbGxlZVRocm93cykge1xuXHRcdFx0dHJ5IHtcblx0XHRcdFx0Ly8gSUUgOCB0aHJvd3Mgb24gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihhcmd1bWVudHMsICcnKVxuXHRcdFx0XHRyZXR1cm4gJGdPUEQoYXJndW1lbnRzLCAnY2FsbGVlJykuZ2V0O1xuXHRcdFx0fSBjYXRjaCAoZ09QRHRocm93cykge1xuXHRcdFx0XHRyZXR1cm4gdGhyb3dUeXBlRXJyb3I7XG5cdFx0XHR9XG5cdFx0fVxuXHR9KCkpXG5cdDogdGhyb3dUeXBlRXJyb3I7XG5cbnZhciBoYXNTeW1ib2xzID0gcmVxdWlyZSgnaGFzLXN5bWJvbHMnKSgpO1xuXG52YXIgZ2V0UHJvdG8gPSByZXF1aXJlKCdnZXQtcHJvdG8nKTtcbnZhciAkT2JqZWN0R1BPID0gcmVxdWlyZSgnZ2V0LXByb3RvL09iamVjdC5nZXRQcm90b3R5cGVPZicpO1xudmFyICRSZWZsZWN0R1BPID0gcmVxdWlyZSgnZ2V0LXByb3RvL1JlZmxlY3QuZ2V0UHJvdG90eXBlT2YnKTtcblxudmFyICRhcHBseSA9IHJlcXVpcmUoJ2NhbGwtYmluZC1hcHBseS1oZWxwZXJzL2Z1bmN0aW9uQXBwbHknKTtcbnZhciAkY2FsbCA9IHJlcXVpcmUoJ2NhbGwtYmluZC1hcHBseS1oZWxwZXJzL2Z1bmN0aW9uQ2FsbCcpO1xuXG52YXIgbmVlZHNFdmFsID0ge307XG5cbnZhciBUeXBlZEFycmF5ID0gdHlwZW9mIFVpbnQ4QXJyYXkgPT09ICd1bmRlZmluZWQnIHx8ICFnZXRQcm90byA/IHVuZGVmaW5lZCA6IGdldFByb3RvKFVpbnQ4QXJyYXkpO1xuXG52YXIgSU5UUklOU0lDUyA9IHtcblx0X19wcm90b19fOiBudWxsLFxuXHQnJUFnZ3JlZ2F0ZUVycm9yJSc6IHR5cGVvZiBBZ2dyZWdhdGVFcnJvciA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBBZ2dyZWdhdGVFcnJvcixcblx0JyVBcnJheSUnOiBBcnJheSxcblx0JyVBcnJheUJ1ZmZlciUnOiB0eXBlb2YgQXJyYXlCdWZmZXIgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogQXJyYXlCdWZmZXIsXG5cdCclQXJyYXlJdGVyYXRvclByb3RvdHlwZSUnOiBoYXNTeW1ib2xzICYmIGdldFByb3RvID8gZ2V0UHJvdG8oW11bU3ltYm9sLml0ZXJhdG9yXSgpKSA6IHVuZGVmaW5lZCxcblx0JyVBc3luY0Zyb21TeW5jSXRlcmF0b3JQcm90b3R5cGUlJzogdW5kZWZpbmVkLFxuXHQnJUFzeW5jRnVuY3Rpb24lJzogbmVlZHNFdmFsLFxuXHQnJUFzeW5jR2VuZXJhdG9yJSc6IG5lZWRzRXZhbCxcblx0JyVBc3luY0dlbmVyYXRvckZ1bmN0aW9uJSc6IG5lZWRzRXZhbCxcblx0JyVBc3luY0l0ZXJhdG9yUHJvdG90eXBlJSc6IG5lZWRzRXZhbCxcblx0JyVBdG9taWNzJSc6IHR5cGVvZiBBdG9taWNzID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IEF0b21pY3MsXG5cdCclQmlnSW50JSc6IHR5cGVvZiBCaWdJbnQgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogQmlnSW50LFxuXHQnJUJpZ0ludDY0QXJyYXklJzogdHlwZW9mIEJpZ0ludDY0QXJyYXkgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogQmlnSW50NjRBcnJheSxcblx0JyVCaWdVaW50NjRBcnJheSUnOiB0eXBlb2YgQmlnVWludDY0QXJyYXkgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogQmlnVWludDY0QXJyYXksXG5cdCclQm9vbGVhbiUnOiBCb29sZWFuLFxuXHQnJURhdGFWaWV3JSc6IHR5cGVvZiBEYXRhVmlldyA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBEYXRhVmlldyxcblx0JyVEYXRlJSc6IERhdGUsXG5cdCclZGVjb2RlVVJJJSc6IGRlY29kZVVSSSxcblx0JyVkZWNvZGVVUklDb21wb25lbnQlJzogZGVjb2RlVVJJQ29tcG9uZW50LFxuXHQnJWVuY29kZVVSSSUnOiBlbmNvZGVVUkksXG5cdCclZW5jb2RlVVJJQ29tcG9uZW50JSc6IGVuY29kZVVSSUNvbXBvbmVudCxcblx0JyVFcnJvciUnOiAkRXJyb3IsXG5cdCclZXZhbCUnOiBldmFsLCAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLWV2YWxcblx0JyVFdmFsRXJyb3IlJzogJEV2YWxFcnJvcixcblx0JyVGbG9hdDMyQXJyYXklJzogdHlwZW9mIEZsb2F0MzJBcnJheSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBGbG9hdDMyQXJyYXksXG5cdCclRmxvYXQ2NEFycmF5JSc6IHR5cGVvZiBGbG9hdDY0QXJyYXkgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogRmxvYXQ2NEFycmF5LFxuXHQnJUZpbmFsaXphdGlvblJlZ2lzdHJ5JSc6IHR5cGVvZiBGaW5hbGl6YXRpb25SZWdpc3RyeSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBGaW5hbGl6YXRpb25SZWdpc3RyeSxcblx0JyVGdW5jdGlvbiUnOiAkRnVuY3Rpb24sXG5cdCclR2VuZXJhdG9yRnVuY3Rpb24lJzogbmVlZHNFdmFsLFxuXHQnJUludDhBcnJheSUnOiB0eXBlb2YgSW50OEFycmF5ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IEludDhBcnJheSxcblx0JyVJbnQxNkFycmF5JSc6IHR5cGVvZiBJbnQxNkFycmF5ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IEludDE2QXJyYXksXG5cdCclSW50MzJBcnJheSUnOiB0eXBlb2YgSW50MzJBcnJheSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBJbnQzMkFycmF5LFxuXHQnJWlzRmluaXRlJSc6IGlzRmluaXRlLFxuXHQnJWlzTmFOJSc6IGlzTmFOLFxuXHQnJUl0ZXJhdG9yUHJvdG90eXBlJSc6IGhhc1N5bWJvbHMgJiYgZ2V0UHJvdG8gPyBnZXRQcm90byhnZXRQcm90byhbXVtTeW1ib2wuaXRlcmF0b3JdKCkpKSA6IHVuZGVmaW5lZCxcblx0JyVKU09OJSc6IHR5cGVvZiBKU09OID09PSAnb2JqZWN0JyA/IEpTT04gOiB1bmRlZmluZWQsXG5cdCclTWFwJSc6IHR5cGVvZiBNYXAgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogTWFwLFxuXHQnJU1hcEl0ZXJhdG9yUHJvdG90eXBlJSc6IHR5cGVvZiBNYXAgPT09ICd1bmRlZmluZWQnIHx8ICFoYXNTeW1ib2xzIHx8ICFnZXRQcm90byA/IHVuZGVmaW5lZCA6IGdldFByb3RvKG5ldyBNYXAoKVtTeW1ib2wuaXRlcmF0b3JdKCkpLFxuXHQnJU1hdGglJzogTWF0aCxcblx0JyVOdW1iZXIlJzogTnVtYmVyLFxuXHQnJU9iamVjdCUnOiAkT2JqZWN0LFxuXHQnJU9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IlJzogJGdPUEQsXG5cdCclcGFyc2VGbG9hdCUnOiBwYXJzZUZsb2F0LFxuXHQnJXBhcnNlSW50JSc6IHBhcnNlSW50LFxuXHQnJVByb21pc2UlJzogdHlwZW9mIFByb21pc2UgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogUHJvbWlzZSxcblx0JyVQcm94eSUnOiB0eXBlb2YgUHJveHkgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogUHJveHksXG5cdCclUmFuZ2VFcnJvciUnOiAkUmFuZ2VFcnJvcixcblx0JyVSZWZlcmVuY2VFcnJvciUnOiAkUmVmZXJlbmNlRXJyb3IsXG5cdCclUmVmbGVjdCUnOiB0eXBlb2YgUmVmbGVjdCA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBSZWZsZWN0LFxuXHQnJVJlZ0V4cCUnOiBSZWdFeHAsXG5cdCclU2V0JSc6IHR5cGVvZiBTZXQgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogU2V0LFxuXHQnJVNldEl0ZXJhdG9yUHJvdG90eXBlJSc6IHR5cGVvZiBTZXQgPT09ICd1bmRlZmluZWQnIHx8ICFoYXNTeW1ib2xzIHx8ICFnZXRQcm90byA/IHVuZGVmaW5lZCA6IGdldFByb3RvKG5ldyBTZXQoKVtTeW1ib2wuaXRlcmF0b3JdKCkpLFxuXHQnJVNoYXJlZEFycmF5QnVmZmVyJSc6IHR5cGVvZiBTaGFyZWRBcnJheUJ1ZmZlciA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBTaGFyZWRBcnJheUJ1ZmZlcixcblx0JyVTdHJpbmclJzogU3RyaW5nLFxuXHQnJVN0cmluZ0l0ZXJhdG9yUHJvdG90eXBlJSc6IGhhc1N5bWJvbHMgJiYgZ2V0UHJvdG8gPyBnZXRQcm90bygnJ1tTeW1ib2wuaXRlcmF0b3JdKCkpIDogdW5kZWZpbmVkLFxuXHQnJVN5bWJvbCUnOiBoYXNTeW1ib2xzID8gU3ltYm9sIDogdW5kZWZpbmVkLFxuXHQnJVN5bnRheEVycm9yJSc6ICRTeW50YXhFcnJvcixcblx0JyVUaHJvd1R5cGVFcnJvciUnOiBUaHJvd1R5cGVFcnJvcixcblx0JyVUeXBlZEFycmF5JSc6IFR5cGVkQXJyYXksXG5cdCclVHlwZUVycm9yJSc6ICRUeXBlRXJyb3IsXG5cdCclVWludDhBcnJheSUnOiB0eXBlb2YgVWludDhBcnJheSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBVaW50OEFycmF5LFxuXHQnJVVpbnQ4Q2xhbXBlZEFycmF5JSc6IHR5cGVvZiBVaW50OENsYW1wZWRBcnJheSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBVaW50OENsYW1wZWRBcnJheSxcblx0JyVVaW50MTZBcnJheSUnOiB0eXBlb2YgVWludDE2QXJyYXkgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogVWludDE2QXJyYXksXG5cdCclVWludDMyQXJyYXklJzogdHlwZW9mIFVpbnQzMkFycmF5ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IFVpbnQzMkFycmF5LFxuXHQnJVVSSUVycm9yJSc6ICRVUklFcnJvcixcblx0JyVXZWFrTWFwJSc6IHR5cGVvZiBXZWFrTWFwID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IFdlYWtNYXAsXG5cdCclV2Vha1JlZiUnOiB0eXBlb2YgV2Vha1JlZiA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBXZWFrUmVmLFxuXHQnJVdlYWtTZXQlJzogdHlwZW9mIFdlYWtTZXQgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogV2Vha1NldCxcblxuXHQnJUZ1bmN0aW9uLnByb3RvdHlwZS5jYWxsJSc6ICRjYWxsLFxuXHQnJUZ1bmN0aW9uLnByb3RvdHlwZS5hcHBseSUnOiAkYXBwbHksXG5cdCclT2JqZWN0LmRlZmluZVByb3BlcnR5JSc6ICRkZWZpbmVQcm9wZXJ0eSxcblx0JyVPYmplY3QuZ2V0UHJvdG90eXBlT2YlJzogJE9iamVjdEdQTyxcblx0JyVNYXRoLmFicyUnOiBhYnMsXG5cdCclTWF0aC5mbG9vciUnOiBmbG9vcixcblx0JyVNYXRoLm1heCUnOiBtYXgsXG5cdCclTWF0aC5taW4lJzogbWluLFxuXHQnJU1hdGgucG93JSc6IHBvdyxcblx0JyVNYXRoLnJvdW5kJSc6IHJvdW5kLFxuXHQnJU1hdGguc2lnbiUnOiBzaWduLFxuXHQnJVJlZmxlY3QuZ2V0UHJvdG90eXBlT2YlJzogJFJlZmxlY3RHUE9cbn07XG5cbmlmIChnZXRQcm90bykge1xuXHR0cnkge1xuXHRcdG51bGwuZXJyb3I7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW51c2VkLWV4cHJlc3Npb25zXG5cdH0gY2F0Y2ggKGUpIHtcblx0XHQvLyBodHRwczovL2dpdGh1Yi5jb20vdGMzOS9wcm9wb3NhbC1zaGFkb3dyZWFsbS9wdWxsLzM4NCNpc3N1ZWNvbW1lbnQtMTM2NDI2NDIyOVxuXHRcdHZhciBlcnJvclByb3RvID0gZ2V0UHJvdG8oZ2V0UHJvdG8oZSkpO1xuXHRcdElOVFJJTlNJQ1NbJyVFcnJvci5wcm90b3R5cGUlJ10gPSBlcnJvclByb3RvO1xuXHR9XG59XG5cbnZhciBkb0V2YWwgPSBmdW5jdGlvbiBkb0V2YWwobmFtZSkge1xuXHR2YXIgdmFsdWU7XG5cdGlmIChuYW1lID09PSAnJUFzeW5jRnVuY3Rpb24lJykge1xuXHRcdHZhbHVlID0gZ2V0RXZhbGxlZENvbnN0cnVjdG9yKCdhc3luYyBmdW5jdGlvbiAoKSB7fScpO1xuXHR9IGVsc2UgaWYgKG5hbWUgPT09ICclR2VuZXJhdG9yRnVuY3Rpb24lJykge1xuXHRcdHZhbHVlID0gZ2V0RXZhbGxlZENvbnN0cnVjdG9yKCdmdW5jdGlvbiogKCkge30nKTtcblx0fSBlbHNlIGlmIChuYW1lID09PSAnJUFzeW5jR2VuZXJhdG9yRnVuY3Rpb24lJykge1xuXHRcdHZhbHVlID0gZ2V0RXZhbGxlZENvbnN0cnVjdG9yKCdhc3luYyBmdW5jdGlvbiogKCkge30nKTtcblx0fSBlbHNlIGlmIChuYW1lID09PSAnJUFzeW5jR2VuZXJhdG9yJScpIHtcblx0XHR2YXIgZm4gPSBkb0V2YWwoJyVBc3luY0dlbmVyYXRvckZ1bmN0aW9uJScpO1xuXHRcdGlmIChmbikge1xuXHRcdFx0dmFsdWUgPSBmbi5wcm90b3R5cGU7XG5cdFx0fVxuXHR9IGVsc2UgaWYgKG5hbWUgPT09ICclQXN5bmNJdGVyYXRvclByb3RvdHlwZSUnKSB7XG5cdFx0dmFyIGdlbiA9IGRvRXZhbCgnJUFzeW5jR2VuZXJhdG9yJScpO1xuXHRcdGlmIChnZW4gJiYgZ2V0UHJvdG8pIHtcblx0XHRcdHZhbHVlID0gZ2V0UHJvdG8oZ2VuLnByb3RvdHlwZSk7XG5cdFx0fVxuXHR9XG5cblx0SU5UUklOU0lDU1tuYW1lXSA9IHZhbHVlO1xuXG5cdHJldHVybiB2YWx1ZTtcbn07XG5cbnZhciBMRUdBQ1lfQUxJQVNFUyA9IHtcblx0X19wcm90b19fOiBudWxsLFxuXHQnJUFycmF5QnVmZmVyUHJvdG90eXBlJSc6IFsnQXJyYXlCdWZmZXInLCAncHJvdG90eXBlJ10sXG5cdCclQXJyYXlQcm90b3R5cGUlJzogWydBcnJheScsICdwcm90b3R5cGUnXSxcblx0JyVBcnJheVByb3RvX2VudHJpZXMlJzogWydBcnJheScsICdwcm90b3R5cGUnLCAnZW50cmllcyddLFxuXHQnJUFycmF5UHJvdG9fZm9yRWFjaCUnOiBbJ0FycmF5JywgJ3Byb3RvdHlwZScsICdmb3JFYWNoJ10sXG5cdCclQXJyYXlQcm90b19rZXlzJSc6IFsnQXJyYXknLCAncHJvdG90eXBlJywgJ2tleXMnXSxcblx0JyVBcnJheVByb3RvX3ZhbHVlcyUnOiBbJ0FycmF5JywgJ3Byb3RvdHlwZScsICd2YWx1ZXMnXSxcblx0JyVBc3luY0Z1bmN0aW9uUHJvdG90eXBlJSc6IFsnQXN5bmNGdW5jdGlvbicsICdwcm90b3R5cGUnXSxcblx0JyVBc3luY0dlbmVyYXRvciUnOiBbJ0FzeW5jR2VuZXJhdG9yRnVuY3Rpb24nLCAncHJvdG90eXBlJ10sXG5cdCclQXN5bmNHZW5lcmF0b3JQcm90b3R5cGUlJzogWydBc3luY0dlbmVyYXRvckZ1bmN0aW9uJywgJ3Byb3RvdHlwZScsICdwcm90b3R5cGUnXSxcblx0JyVCb29sZWFuUHJvdG90eXBlJSc6IFsnQm9vbGVhbicsICdwcm90b3R5cGUnXSxcblx0JyVEYXRhVmlld1Byb3RvdHlwZSUnOiBbJ0RhdGFWaWV3JywgJ3Byb3RvdHlwZSddLFxuXHQnJURhdGVQcm90b3R5cGUlJzogWydEYXRlJywgJ3Byb3RvdHlwZSddLFxuXHQnJUVycm9yUHJvdG90eXBlJSc6IFsnRXJyb3InLCAncHJvdG90eXBlJ10sXG5cdCclRXZhbEVycm9yUHJvdG90eXBlJSc6IFsnRXZhbEVycm9yJywgJ3Byb3RvdHlwZSddLFxuXHQnJUZsb2F0MzJBcnJheVByb3RvdHlwZSUnOiBbJ0Zsb2F0MzJBcnJheScsICdwcm90b3R5cGUnXSxcblx0JyVGbG9hdDY0QXJyYXlQcm90b3R5cGUlJzogWydGbG9hdDY0QXJyYXknLCAncHJvdG90eXBlJ10sXG5cdCclRnVuY3Rpb25Qcm90b3R5cGUlJzogWydGdW5jdGlvbicsICdwcm90b3R5cGUnXSxcblx0JyVHZW5lcmF0b3IlJzogWydHZW5lcmF0b3JGdW5jdGlvbicsICdwcm90b3R5cGUnXSxcblx0JyVHZW5lcmF0b3JQcm90b3R5cGUlJzogWydHZW5lcmF0b3JGdW5jdGlvbicsICdwcm90b3R5cGUnLCAncHJvdG90eXBlJ10sXG5cdCclSW50OEFycmF5UHJvdG90eXBlJSc6IFsnSW50OEFycmF5JywgJ3Byb3RvdHlwZSddLFxuXHQnJUludDE2QXJyYXlQcm90b3R5cGUlJzogWydJbnQxNkFycmF5JywgJ3Byb3RvdHlwZSddLFxuXHQnJUludDMyQXJyYXlQcm90b3R5cGUlJzogWydJbnQzMkFycmF5JywgJ3Byb3RvdHlwZSddLFxuXHQnJUpTT05QYXJzZSUnOiBbJ0pTT04nLCAncGFyc2UnXSxcblx0JyVKU09OU3RyaW5naWZ5JSc6IFsnSlNPTicsICdzdHJpbmdpZnknXSxcblx0JyVNYXBQcm90b3R5cGUlJzogWydNYXAnLCAncHJvdG90eXBlJ10sXG5cdCclTnVtYmVyUHJvdG90eXBlJSc6IFsnTnVtYmVyJywgJ3Byb3RvdHlwZSddLFxuXHQnJU9iamVjdFByb3RvdHlwZSUnOiBbJ09iamVjdCcsICdwcm90b3R5cGUnXSxcblx0JyVPYmpQcm90b190b1N0cmluZyUnOiBbJ09iamVjdCcsICdwcm90b3R5cGUnLCAndG9TdHJpbmcnXSxcblx0JyVPYmpQcm90b192YWx1ZU9mJSc6IFsnT2JqZWN0JywgJ3Byb3RvdHlwZScsICd2YWx1ZU9mJ10sXG5cdCclUHJvbWlzZVByb3RvdHlwZSUnOiBbJ1Byb21pc2UnLCAncHJvdG90eXBlJ10sXG5cdCclUHJvbWlzZVByb3RvX3RoZW4lJzogWydQcm9taXNlJywgJ3Byb3RvdHlwZScsICd0aGVuJ10sXG5cdCclUHJvbWlzZV9hbGwlJzogWydQcm9taXNlJywgJ2FsbCddLFxuXHQnJVByb21pc2VfcmVqZWN0JSc6IFsnUHJvbWlzZScsICdyZWplY3QnXSxcblx0JyVQcm9taXNlX3Jlc29sdmUlJzogWydQcm9taXNlJywgJ3Jlc29sdmUnXSxcblx0JyVSYW5nZUVycm9yUHJvdG90eXBlJSc6IFsnUmFuZ2VFcnJvcicsICdwcm90b3R5cGUnXSxcblx0JyVSZWZlcmVuY2VFcnJvclByb3RvdHlwZSUnOiBbJ1JlZmVyZW5jZUVycm9yJywgJ3Byb3RvdHlwZSddLFxuXHQnJVJlZ0V4cFByb3RvdHlwZSUnOiBbJ1JlZ0V4cCcsICdwcm90b3R5cGUnXSxcblx0JyVTZXRQcm90b3R5cGUlJzogWydTZXQnLCAncHJvdG90eXBlJ10sXG5cdCclU2hhcmVkQXJyYXlCdWZmZXJQcm90b3R5cGUlJzogWydTaGFyZWRBcnJheUJ1ZmZlcicsICdwcm90b3R5cGUnXSxcblx0JyVTdHJpbmdQcm90b3R5cGUlJzogWydTdHJpbmcnLCAncHJvdG90eXBlJ10sXG5cdCclU3ltYm9sUHJvdG90eXBlJSc6IFsnU3ltYm9sJywgJ3Byb3RvdHlwZSddLFxuXHQnJVN5bnRheEVycm9yUHJvdG90eXBlJSc6IFsnU3ludGF4RXJyb3InLCAncHJvdG90eXBlJ10sXG5cdCclVHlwZWRBcnJheVByb3RvdHlwZSUnOiBbJ1R5cGVkQXJyYXknLCAncHJvdG90eXBlJ10sXG5cdCclVHlwZUVycm9yUHJvdG90eXBlJSc6IFsnVHlwZUVycm9yJywgJ3Byb3RvdHlwZSddLFxuXHQnJVVpbnQ4QXJyYXlQcm90b3R5cGUlJzogWydVaW50OEFycmF5JywgJ3Byb3RvdHlwZSddLFxuXHQnJVVpbnQ4Q2xhbXBlZEFycmF5UHJvdG90eXBlJSc6IFsnVWludDhDbGFtcGVkQXJyYXknLCAncHJvdG90eXBlJ10sXG5cdCclVWludDE2QXJyYXlQcm90b3R5cGUlJzogWydVaW50MTZBcnJheScsICdwcm90b3R5cGUnXSxcblx0JyVVaW50MzJBcnJheVByb3RvdHlwZSUnOiBbJ1VpbnQzMkFycmF5JywgJ3Byb3RvdHlwZSddLFxuXHQnJVVSSUVycm9yUHJvdG90eXBlJSc6IFsnVVJJRXJyb3InLCAncHJvdG90eXBlJ10sXG5cdCclV2Vha01hcFByb3RvdHlwZSUnOiBbJ1dlYWtNYXAnLCAncHJvdG90eXBlJ10sXG5cdCclV2Vha1NldFByb3RvdHlwZSUnOiBbJ1dlYWtTZXQnLCAncHJvdG90eXBlJ11cbn07XG5cbnZhciBiaW5kID0gcmVxdWlyZSgnZnVuY3Rpb24tYmluZCcpO1xudmFyIGhhc093biA9IHJlcXVpcmUoJ2hhc293bicpO1xudmFyICRjb25jYXQgPSBiaW5kLmNhbGwoJGNhbGwsIEFycmF5LnByb3RvdHlwZS5jb25jYXQpO1xudmFyICRzcGxpY2VBcHBseSA9IGJpbmQuY2FsbCgkYXBwbHksIEFycmF5LnByb3RvdHlwZS5zcGxpY2UpO1xudmFyICRyZXBsYWNlID0gYmluZC5jYWxsKCRjYWxsLCBTdHJpbmcucHJvdG90eXBlLnJlcGxhY2UpO1xudmFyICRzdHJTbGljZSA9IGJpbmQuY2FsbCgkY2FsbCwgU3RyaW5nLnByb3RvdHlwZS5zbGljZSk7XG52YXIgJGV4ZWMgPSBiaW5kLmNhbGwoJGNhbGwsIFJlZ0V4cC5wcm90b3R5cGUuZXhlYyk7XG5cbi8qIGFkYXB0ZWQgZnJvbSBodHRwczovL2dpdGh1Yi5jb20vbG9kYXNoL2xvZGFzaC9ibG9iLzQuMTcuMTUvZGlzdC9sb2Rhc2guanMjTDY3MzUtTDY3NDQgKi9cbnZhciByZVByb3BOYW1lID0gL1teJS5bXFxdXSt8XFxbKD86KC0/XFxkKyg/OlxcLlxcZCspPyl8KFtcIiddKSgoPzooPyFcXDIpW15cXFxcXXxcXFxcLikqPylcXDIpXFxdfCg/PSg/OlxcLnxcXFtcXF0pKD86XFwufFxcW1xcXXwlJCkpL2c7XG52YXIgcmVFc2NhcGVDaGFyID0gL1xcXFwoXFxcXCk/L2c7IC8qKiBVc2VkIHRvIG1hdGNoIGJhY2tzbGFzaGVzIGluIHByb3BlcnR5IHBhdGhzLiAqL1xudmFyIHN0cmluZ1RvUGF0aCA9IGZ1bmN0aW9uIHN0cmluZ1RvUGF0aChzdHJpbmcpIHtcblx0dmFyIGZpcnN0ID0gJHN0clNsaWNlKHN0cmluZywgMCwgMSk7XG5cdHZhciBsYXN0ID0gJHN0clNsaWNlKHN0cmluZywgLTEpO1xuXHRpZiAoZmlyc3QgPT09ICclJyAmJiBsYXN0ICE9PSAnJScpIHtcblx0XHR0aHJvdyBuZXcgJFN5bnRheEVycm9yKCdpbnZhbGlkIGludHJpbnNpYyBzeW50YXgsIGV4cGVjdGVkIGNsb3NpbmcgYCVgJyk7XG5cdH0gZWxzZSBpZiAobGFzdCA9PT0gJyUnICYmIGZpcnN0ICE9PSAnJScpIHtcblx0XHR0aHJvdyBuZXcgJFN5bnRheEVycm9yKCdpbnZhbGlkIGludHJpbnNpYyBzeW50YXgsIGV4cGVjdGVkIG9wZW5pbmcgYCVgJyk7XG5cdH1cblx0dmFyIHJlc3VsdCA9IFtdO1xuXHQkcmVwbGFjZShzdHJpbmcsIHJlUHJvcE5hbWUsIGZ1bmN0aW9uIChtYXRjaCwgbnVtYmVyLCBxdW90ZSwgc3ViU3RyaW5nKSB7XG5cdFx0cmVzdWx0W3Jlc3VsdC5sZW5ndGhdID0gcXVvdGUgPyAkcmVwbGFjZShzdWJTdHJpbmcsIHJlRXNjYXBlQ2hhciwgJyQxJykgOiBudW1iZXIgfHwgbWF0Y2g7XG5cdH0pO1xuXHRyZXR1cm4gcmVzdWx0O1xufTtcbi8qIGVuZCBhZGFwdGF0aW9uICovXG5cbnZhciBnZXRCYXNlSW50cmluc2ljID0gZnVuY3Rpb24gZ2V0QmFzZUludHJpbnNpYyhuYW1lLCBhbGxvd01pc3NpbmcpIHtcblx0dmFyIGludHJpbnNpY05hbWUgPSBuYW1lO1xuXHR2YXIgYWxpYXM7XG5cdGlmIChoYXNPd24oTEVHQUNZX0FMSUFTRVMsIGludHJpbnNpY05hbWUpKSB7XG5cdFx0YWxpYXMgPSBMRUdBQ1lfQUxJQVNFU1tpbnRyaW5zaWNOYW1lXTtcblx0XHRpbnRyaW5zaWNOYW1lID0gJyUnICsgYWxpYXNbMF0gKyAnJSc7XG5cdH1cblxuXHRpZiAoaGFzT3duKElOVFJJTlNJQ1MsIGludHJpbnNpY05hbWUpKSB7XG5cdFx0dmFyIHZhbHVlID0gSU5UUklOU0lDU1tpbnRyaW5zaWNOYW1lXTtcblx0XHRpZiAodmFsdWUgPT09IG5lZWRzRXZhbCkge1xuXHRcdFx0dmFsdWUgPSBkb0V2YWwoaW50cmluc2ljTmFtZSk7XG5cdFx0fVxuXHRcdGlmICh0eXBlb2YgdmFsdWUgPT09ICd1bmRlZmluZWQnICYmICFhbGxvd01pc3NpbmcpIHtcblx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdpbnRyaW5zaWMgJyArIG5hbWUgKyAnIGV4aXN0cywgYnV0IGlzIG5vdCBhdmFpbGFibGUuIFBsZWFzZSBmaWxlIGFuIGlzc3VlIScpO1xuXHRcdH1cblxuXHRcdHJldHVybiB7XG5cdFx0XHRhbGlhczogYWxpYXMsXG5cdFx0XHRuYW1lOiBpbnRyaW5zaWNOYW1lLFxuXHRcdFx0dmFsdWU6IHZhbHVlXG5cdFx0fTtcblx0fVxuXG5cdHRocm93IG5ldyAkU3ludGF4RXJyb3IoJ2ludHJpbnNpYyAnICsgbmFtZSArICcgZG9lcyBub3QgZXhpc3QhJyk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIEdldEludHJpbnNpYyhuYW1lLCBhbGxvd01pc3NpbmcpIHtcblx0aWYgKHR5cGVvZiBuYW1lICE9PSAnc3RyaW5nJyB8fCBuYW1lLmxlbmd0aCA9PT0gMCkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdpbnRyaW5zaWMgbmFtZSBtdXN0IGJlIGEgbm9uLWVtcHR5IHN0cmluZycpO1xuXHR9XG5cdGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSAmJiB0eXBlb2YgYWxsb3dNaXNzaW5nICE9PSAnYm9vbGVhbicpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignXCJhbGxvd01pc3NpbmdcIiBhcmd1bWVudCBtdXN0IGJlIGEgYm9vbGVhbicpO1xuXHR9XG5cblx0aWYgKCRleGVjKC9eJT9bXiVdKiU/JC8sIG5hbWUpID09PSBudWxsKSB7XG5cdFx0dGhyb3cgbmV3ICRTeW50YXhFcnJvcignYCVgIG1heSBub3QgYmUgcHJlc2VudCBhbnl3aGVyZSBidXQgYXQgdGhlIGJlZ2lubmluZyBhbmQgZW5kIG9mIHRoZSBpbnRyaW5zaWMgbmFtZScpO1xuXHR9XG5cdHZhciBwYXJ0cyA9IHN0cmluZ1RvUGF0aChuYW1lKTtcblx0dmFyIGludHJpbnNpY0Jhc2VOYW1lID0gcGFydHMubGVuZ3RoID4gMCA/IHBhcnRzWzBdIDogJyc7XG5cblx0dmFyIGludHJpbnNpYyA9IGdldEJhc2VJbnRyaW5zaWMoJyUnICsgaW50cmluc2ljQmFzZU5hbWUgKyAnJScsIGFsbG93TWlzc2luZyk7XG5cdHZhciBpbnRyaW5zaWNSZWFsTmFtZSA9IGludHJpbnNpYy5uYW1lO1xuXHR2YXIgdmFsdWUgPSBpbnRyaW5zaWMudmFsdWU7XG5cdHZhciBza2lwRnVydGhlckNhY2hpbmcgPSBmYWxzZTtcblxuXHR2YXIgYWxpYXMgPSBpbnRyaW5zaWMuYWxpYXM7XG5cdGlmIChhbGlhcykge1xuXHRcdGludHJpbnNpY0Jhc2VOYW1lID0gYWxpYXNbMF07XG5cdFx0JHNwbGljZUFwcGx5KHBhcnRzLCAkY29uY2F0KFswLCAxXSwgYWxpYXMpKTtcblx0fVxuXG5cdGZvciAodmFyIGkgPSAxLCBpc093biA9IHRydWU7IGkgPCBwYXJ0cy5sZW5ndGg7IGkgKz0gMSkge1xuXHRcdHZhciBwYXJ0ID0gcGFydHNbaV07XG5cdFx0dmFyIGZpcnN0ID0gJHN0clNsaWNlKHBhcnQsIDAsIDEpO1xuXHRcdHZhciBsYXN0ID0gJHN0clNsaWNlKHBhcnQsIC0xKTtcblx0XHRpZiAoXG5cdFx0XHQoXG5cdFx0XHRcdChmaXJzdCA9PT0gJ1wiJyB8fCBmaXJzdCA9PT0gXCInXCIgfHwgZmlyc3QgPT09ICdgJylcblx0XHRcdFx0fHwgKGxhc3QgPT09ICdcIicgfHwgbGFzdCA9PT0gXCInXCIgfHwgbGFzdCA9PT0gJ2AnKVxuXHRcdFx0KVxuXHRcdFx0JiYgZmlyc3QgIT09IGxhc3Rcblx0XHQpIHtcblx0XHRcdHRocm93IG5ldyAkU3ludGF4RXJyb3IoJ3Byb3BlcnR5IG5hbWVzIHdpdGggcXVvdGVzIG11c3QgaGF2ZSBtYXRjaGluZyBxdW90ZXMnKTtcblx0XHR9XG5cdFx0aWYgKHBhcnQgPT09ICdjb25zdHJ1Y3RvcicgfHwgIWlzT3duKSB7XG5cdFx0XHRza2lwRnVydGhlckNhY2hpbmcgPSB0cnVlO1xuXHRcdH1cblxuXHRcdGludHJpbnNpY0Jhc2VOYW1lICs9ICcuJyArIHBhcnQ7XG5cdFx0aW50cmluc2ljUmVhbE5hbWUgPSAnJScgKyBpbnRyaW5zaWNCYXNlTmFtZSArICclJztcblxuXHRcdGlmIChoYXNPd24oSU5UUklOU0lDUywgaW50cmluc2ljUmVhbE5hbWUpKSB7XG5cdFx0XHR2YWx1ZSA9IElOVFJJTlNJQ1NbaW50cmluc2ljUmVhbE5hbWVdO1xuXHRcdH0gZWxzZSBpZiAodmFsdWUgIT0gbnVsbCkge1xuXHRcdFx0aWYgKCEocGFydCBpbiB2YWx1ZSkpIHtcblx0XHRcdFx0aWYgKCFhbGxvd01pc3NpbmcpIHtcblx0XHRcdFx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignYmFzZSBpbnRyaW5zaWMgZm9yICcgKyBuYW1lICsgJyBleGlzdHMsIGJ1dCB0aGUgcHJvcGVydHkgaXMgbm90IGF2YWlsYWJsZS4nKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gdm9pZCB1bmRlZmluZWQ7XG5cdFx0XHR9XG5cdFx0XHRpZiAoJGdPUEQgJiYgKGkgKyAxKSA+PSBwYXJ0cy5sZW5ndGgpIHtcblx0XHRcdFx0dmFyIGRlc2MgPSAkZ09QRCh2YWx1ZSwgcGFydCk7XG5cdFx0XHRcdGlzT3duID0gISFkZXNjO1xuXG5cdFx0XHRcdC8vIEJ5IGNvbnZlbnRpb24sIHdoZW4gYSBkYXRhIHByb3BlcnR5IGlzIGNvbnZlcnRlZCB0byBhbiBhY2Nlc3NvclxuXHRcdFx0XHQvLyBwcm9wZXJ0eSB0byBlbXVsYXRlIGEgZGF0YSBwcm9wZXJ0eSB0aGF0IGRvZXMgbm90IHN1ZmZlciBmcm9tXG5cdFx0XHRcdC8vIHRoZSBvdmVycmlkZSBtaXN0YWtlLCB0aGF0IGFjY2Vzc29yJ3MgZ2V0dGVyIGlzIG1hcmtlZCB3aXRoXG5cdFx0XHRcdC8vIGFuIGBvcmlnaW5hbFZhbHVlYCBwcm9wZXJ0eS4gSGVyZSwgd2hlbiB3ZSBkZXRlY3QgdGhpcywgd2Vcblx0XHRcdFx0Ly8gdXBob2xkIHRoZSBpbGx1c2lvbiBieSBwcmV0ZW5kaW5nIHRvIHNlZSB0aGF0IG9yaWdpbmFsIGRhdGFcblx0XHRcdFx0Ly8gcHJvcGVydHksIGkuZS4sIHJldHVybmluZyB0aGUgdmFsdWUgcmF0aGVyIHRoYW4gdGhlIGdldHRlclxuXHRcdFx0XHQvLyBpdHNlbGYuXG5cdFx0XHRcdGlmIChpc093biAmJiAnZ2V0JyBpbiBkZXNjICYmICEoJ29yaWdpbmFsVmFsdWUnIGluIGRlc2MuZ2V0KSkge1xuXHRcdFx0XHRcdHZhbHVlID0gZGVzYy5nZXQ7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0dmFsdWUgPSB2YWx1ZVtwYXJ0XTtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0aXNPd24gPSBoYXNPd24odmFsdWUsIHBhcnQpO1xuXHRcdFx0XHR2YWx1ZSA9IHZhbHVlW3BhcnRdO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoaXNPd24gJiYgIXNraXBGdXJ0aGVyQ2FjaGluZykge1xuXHRcdFx0XHRJTlRSSU5TSUNTW2ludHJpbnNpY1JlYWxOYW1lXSA9IHZhbHVlO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXHRyZXR1cm4gdmFsdWU7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgJE9iamVjdCA9IHJlcXVpcmUoJ2VzLW9iamVjdC1hdG9tcycpO1xuXG4vKiogQHR5cGUge2ltcG9ydCgnLi9PYmplY3QuZ2V0UHJvdG90eXBlT2YnKX0gKi9cbm1vZHVsZS5leHBvcnRzID0gJE9iamVjdC5nZXRQcm90b3R5cGVPZiB8fCBudWxsO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKiogQHR5cGUge2ltcG9ydCgnLi9SZWZsZWN0LmdldFByb3RvdHlwZU9mJyl9ICovXG5tb2R1bGUuZXhwb3J0cyA9ICh0eXBlb2YgUmVmbGVjdCAhPT0gJ3VuZGVmaW5lZCcgJiYgUmVmbGVjdC5nZXRQcm90b3R5cGVPZikgfHwgbnVsbDtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHJlZmxlY3RHZXRQcm90byA9IHJlcXVpcmUoJy4vUmVmbGVjdC5nZXRQcm90b3R5cGVPZicpO1xudmFyIG9yaWdpbmFsR2V0UHJvdG8gPSByZXF1aXJlKCcuL09iamVjdC5nZXRQcm90b3R5cGVPZicpO1xuXG52YXIgZ2V0RHVuZGVyUHJvdG8gPSByZXF1aXJlKCdkdW5kZXItcHJvdG8vZ2V0Jyk7XG5cbi8qKiBAdHlwZSB7aW1wb3J0KCcuJyl9ICovXG5tb2R1bGUuZXhwb3J0cyA9IHJlZmxlY3RHZXRQcm90b1xuXHQ/IGZ1bmN0aW9uIGdldFByb3RvKE8pIHtcblx0XHQvLyBAdHMtZXhwZWN0LWVycm9yIFRTIGNhbid0IG5hcnJvdyBpbnNpZGUgYSBjbG9zdXJlLCBmb3Igc29tZSByZWFzb25cblx0XHRyZXR1cm4gcmVmbGVjdEdldFByb3RvKE8pO1xuXHR9XG5cdDogb3JpZ2luYWxHZXRQcm90b1xuXHRcdD8gZnVuY3Rpb24gZ2V0UHJvdG8oTykge1xuXHRcdFx0aWYgKCFPIHx8ICh0eXBlb2YgTyAhPT0gJ29iamVjdCcgJiYgdHlwZW9mIE8gIT09ICdmdW5jdGlvbicpKSB7XG5cdFx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ2dldFByb3RvOiBub3QgYW4gb2JqZWN0Jyk7XG5cdFx0XHR9XG5cdFx0XHQvLyBAdHMtZXhwZWN0LWVycm9yIFRTIGNhbid0IG5hcnJvdyBpbnNpZGUgYSBjbG9zdXJlLCBmb3Igc29tZSByZWFzb25cblx0XHRcdHJldHVybiBvcmlnaW5hbEdldFByb3RvKE8pO1xuXHRcdH1cblx0XHQ6IGdldER1bmRlclByb3RvXG5cdFx0XHQ/IGZ1bmN0aW9uIGdldFByb3RvKE8pIHtcblx0XHRcdFx0Ly8gQHRzLWV4cGVjdC1lcnJvciBUUyBjYW4ndCBuYXJyb3cgaW5zaWRlIGEgY2xvc3VyZSwgZm9yIHNvbWUgcmVhc29uXG5cdFx0XHRcdHJldHVybiBnZXREdW5kZXJQcm90byhPKTtcblx0XHRcdH1cblx0XHRcdDogbnVsbDtcbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqIEB0eXBlIHtpbXBvcnQoJy4vZ09QRCcpfSAqL1xubW9kdWxlLmV4cG9ydHMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKiogQHR5cGUge2ltcG9ydCgnLicpfSAqL1xudmFyICRnT1BEID0gcmVxdWlyZSgnLi9nT1BEJyk7XG5cbmlmICgkZ09QRCkge1xuXHR0cnkge1xuXHRcdCRnT1BEKFtdLCAnbGVuZ3RoJyk7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHQvLyBJRSA4IGhhcyBhIGJyb2tlbiBnT1BEXG5cdFx0JGdPUEQgPSBudWxsO1xuXHR9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gJGdPUEQ7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBvcmlnU3ltYm9sID0gdHlwZW9mIFN5bWJvbCAhPT0gJ3VuZGVmaW5lZCcgJiYgU3ltYm9sO1xudmFyIGhhc1N5bWJvbFNoYW0gPSByZXF1aXJlKCcuL3NoYW1zJyk7XG5cbi8qKiBAdHlwZSB7aW1wb3J0KCcuJyl9ICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGhhc05hdGl2ZVN5bWJvbHMoKSB7XG5cdGlmICh0eXBlb2Ygb3JpZ1N5bWJvbCAhPT0gJ2Z1bmN0aW9uJykgeyByZXR1cm4gZmFsc2U7IH1cblx0aWYgKHR5cGVvZiBTeW1ib2wgIT09ICdmdW5jdGlvbicpIHsgcmV0dXJuIGZhbHNlOyB9XG5cdGlmICh0eXBlb2Ygb3JpZ1N5bWJvbCgnZm9vJykgIT09ICdzeW1ib2wnKSB7IHJldHVybiBmYWxzZTsgfVxuXHRpZiAodHlwZW9mIFN5bWJvbCgnYmFyJykgIT09ICdzeW1ib2wnKSB7IHJldHVybiBmYWxzZTsgfVxuXG5cdHJldHVybiBoYXNTeW1ib2xTaGFtKCk7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKiogQHR5cGUge2ltcG9ydCgnLi9zaGFtcycpfSAqL1xuLyogZXNsaW50IGNvbXBsZXhpdHk6IFsyLCAxOF0sIG1heC1zdGF0ZW1lbnRzOiBbMiwgMzNdICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGhhc1N5bWJvbHMoKSB7XG5cdGlmICh0eXBlb2YgU3ltYm9sICE9PSAnZnVuY3Rpb24nIHx8IHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzICE9PSAnZnVuY3Rpb24nKSB7IHJldHVybiBmYWxzZTsgfVxuXHRpZiAodHlwZW9mIFN5bWJvbC5pdGVyYXRvciA9PT0gJ3N5bWJvbCcpIHsgcmV0dXJuIHRydWU7IH1cblxuXHQvKiogQHR5cGUge3sgW2sgaW4gc3ltYm9sXT86IHVua25vd24gfX0gKi9cblx0dmFyIG9iaiA9IHt9O1xuXHR2YXIgc3ltID0gU3ltYm9sKCd0ZXN0Jyk7XG5cdHZhciBzeW1PYmogPSBPYmplY3Qoc3ltKTtcblx0aWYgKHR5cGVvZiBzeW0gPT09ICdzdHJpbmcnKSB7IHJldHVybiBmYWxzZTsgfVxuXG5cdGlmIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoc3ltKSAhPT0gJ1tvYmplY3QgU3ltYm9sXScpIHsgcmV0dXJuIGZhbHNlOyB9XG5cdGlmIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoc3ltT2JqKSAhPT0gJ1tvYmplY3QgU3ltYm9sXScpIHsgcmV0dXJuIGZhbHNlOyB9XG5cblx0Ly8gdGVtcCBkaXNhYmxlZCBwZXIgaHR0cHM6Ly9naXRodWIuY29tL2xqaGFyYi9vYmplY3QuYXNzaWduL2lzc3Vlcy8xN1xuXHQvLyBpZiAoc3ltIGluc3RhbmNlb2YgU3ltYm9sKSB7IHJldHVybiBmYWxzZTsgfVxuXHQvLyB0ZW1wIGRpc2FibGVkIHBlciBodHRwczovL2dpdGh1Yi5jb20vV2ViUmVmbGVjdGlvbi9nZXQtb3duLXByb3BlcnR5LXN5bWJvbHMvaXNzdWVzLzRcblx0Ly8gaWYgKCEoc3ltT2JqIGluc3RhbmNlb2YgU3ltYm9sKSkgeyByZXR1cm4gZmFsc2U7IH1cblxuXHQvLyBpZiAodHlwZW9mIFN5bWJvbC5wcm90b3R5cGUudG9TdHJpbmcgIT09ICdmdW5jdGlvbicpIHsgcmV0dXJuIGZhbHNlOyB9XG5cdC8vIGlmIChTdHJpbmcoc3ltKSAhPT0gU3ltYm9sLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHN5bSkpIHsgcmV0dXJuIGZhbHNlOyB9XG5cblx0dmFyIHN5bVZhbCA9IDQyO1xuXHRvYmpbc3ltXSA9IHN5bVZhbDtcblx0Zm9yICh2YXIgXyBpbiBvYmopIHsgcmV0dXJuIGZhbHNlOyB9IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tcmVzdHJpY3RlZC1zeW50YXgsIG5vLXVucmVhY2hhYmxlLWxvb3Bcblx0aWYgKHR5cGVvZiBPYmplY3Qua2V5cyA9PT0gJ2Z1bmN0aW9uJyAmJiBPYmplY3Qua2V5cyhvYmopLmxlbmd0aCAhPT0gMCkgeyByZXR1cm4gZmFsc2U7IH1cblxuXHRpZiAodHlwZW9mIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzID09PSAnZnVuY3Rpb24nICYmIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKG9iaikubGVuZ3RoICE9PSAwKSB7IHJldHVybiBmYWxzZTsgfVxuXG5cdHZhciBzeW1zID0gT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhvYmopO1xuXHRpZiAoc3ltcy5sZW5ndGggIT09IDEgfHwgc3ltc1swXSAhPT0gc3ltKSB7IHJldHVybiBmYWxzZTsgfVxuXG5cdGlmICghT2JqZWN0LnByb3RvdHlwZS5wcm9wZXJ0eUlzRW51bWVyYWJsZS5jYWxsKG9iaiwgc3ltKSkgeyByZXR1cm4gZmFsc2U7IH1cblxuXHRpZiAodHlwZW9mIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IgPT09ICdmdW5jdGlvbicpIHtcblx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tZXh0cmEtcGFyZW5zXG5cdFx0dmFyIGRlc2NyaXB0b3IgPSAvKiogQHR5cGUge1Byb3BlcnR5RGVzY3JpcHRvcn0gKi8gKE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Iob2JqLCBzeW0pKTtcblx0XHRpZiAoZGVzY3JpcHRvci52YWx1ZSAhPT0gc3ltVmFsIHx8IGRlc2NyaXB0b3IuZW51bWVyYWJsZSAhPT0gdHJ1ZSkgeyByZXR1cm4gZmFsc2U7IH1cblx0fVxuXG5cdHJldHVybiB0cnVlO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGNhbGwgPSBGdW5jdGlvbi5wcm90b3R5cGUuY2FsbDtcbnZhciAkaGFzT3duID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcbnZhciBiaW5kID0gcmVxdWlyZSgnZnVuY3Rpb24tYmluZCcpO1xuXG4vKiogQHR5cGUge2ltcG9ydCgnLicpfSAqL1xubW9kdWxlLmV4cG9ydHMgPSBiaW5kLmNhbGwoY2FsbCwgJGhhc093bik7XG4iLCIvKiEgaWVlZTc1NC4gQlNELTMtQ2xhdXNlIExpY2Vuc2UuIEZlcm9zcyBBYm91a2hhZGlqZWggPGh0dHBzOi8vZmVyb3NzLm9yZy9vcGVuc291cmNlPiAqL1xuZXhwb3J0cy5yZWFkID0gZnVuY3Rpb24gKGJ1ZmZlciwgb2Zmc2V0LCBpc0xFLCBtTGVuLCBuQnl0ZXMpIHtcbiAgdmFyIGUsIG1cbiAgdmFyIGVMZW4gPSAobkJ5dGVzICogOCkgLSBtTGVuIC0gMVxuICB2YXIgZU1heCA9ICgxIDw8IGVMZW4pIC0gMVxuICB2YXIgZUJpYXMgPSBlTWF4ID4+IDFcbiAgdmFyIG5CaXRzID0gLTdcbiAgdmFyIGkgPSBpc0xFID8gKG5CeXRlcyAtIDEpIDogMFxuICB2YXIgZCA9IGlzTEUgPyAtMSA6IDFcbiAgdmFyIHMgPSBidWZmZXJbb2Zmc2V0ICsgaV1cblxuICBpICs9IGRcblxuICBlID0gcyAmICgoMSA8PCAoLW5CaXRzKSkgLSAxKVxuICBzID4+PSAoLW5CaXRzKVxuICBuQml0cyArPSBlTGVuXG4gIGZvciAoOyBuQml0cyA+IDA7IGUgPSAoZSAqIDI1NikgKyBidWZmZXJbb2Zmc2V0ICsgaV0sIGkgKz0gZCwgbkJpdHMgLT0gOCkge31cblxuICBtID0gZSAmICgoMSA8PCAoLW5CaXRzKSkgLSAxKVxuICBlID4+PSAoLW5CaXRzKVxuICBuQml0cyArPSBtTGVuXG4gIGZvciAoOyBuQml0cyA+IDA7IG0gPSAobSAqIDI1NikgKyBidWZmZXJbb2Zmc2V0ICsgaV0sIGkgKz0gZCwgbkJpdHMgLT0gOCkge31cblxuICBpZiAoZSA9PT0gMCkge1xuICAgIGUgPSAxIC0gZUJpYXNcbiAgfSBlbHNlIGlmIChlID09PSBlTWF4KSB7XG4gICAgcmV0dXJuIG0gPyBOYU4gOiAoKHMgPyAtMSA6IDEpICogSW5maW5pdHkpXG4gIH0gZWxzZSB7XG4gICAgbSA9IG0gKyBNYXRoLnBvdygyLCBtTGVuKVxuICAgIGUgPSBlIC0gZUJpYXNcbiAgfVxuICByZXR1cm4gKHMgPyAtMSA6IDEpICogbSAqIE1hdGgucG93KDIsIGUgLSBtTGVuKVxufVxuXG5leHBvcnRzLndyaXRlID0gZnVuY3Rpb24gKGJ1ZmZlciwgdmFsdWUsIG9mZnNldCwgaXNMRSwgbUxlbiwgbkJ5dGVzKSB7XG4gIHZhciBlLCBtLCBjXG4gIHZhciBlTGVuID0gKG5CeXRlcyAqIDgpIC0gbUxlbiAtIDFcbiAgdmFyIGVNYXggPSAoMSA8PCBlTGVuKSAtIDFcbiAgdmFyIGVCaWFzID0gZU1heCA+PiAxXG4gIHZhciBydCA9IChtTGVuID09PSAyMyA/IE1hdGgucG93KDIsIC0yNCkgLSBNYXRoLnBvdygyLCAtNzcpIDogMClcbiAgdmFyIGkgPSBpc0xFID8gMCA6IChuQnl0ZXMgLSAxKVxuICB2YXIgZCA9IGlzTEUgPyAxIDogLTFcbiAgdmFyIHMgPSB2YWx1ZSA8IDAgfHwgKHZhbHVlID09PSAwICYmIDEgLyB2YWx1ZSA8IDApID8gMSA6IDBcblxuICB2YWx1ZSA9IE1hdGguYWJzKHZhbHVlKVxuXG4gIGlmIChpc05hTih2YWx1ZSkgfHwgdmFsdWUgPT09IEluZmluaXR5KSB7XG4gICAgbSA9IGlzTmFOKHZhbHVlKSA/IDEgOiAwXG4gICAgZSA9IGVNYXhcbiAgfSBlbHNlIHtcbiAgICBlID0gTWF0aC5mbG9vcihNYXRoLmxvZyh2YWx1ZSkgLyBNYXRoLkxOMilcbiAgICBpZiAodmFsdWUgKiAoYyA9IE1hdGgucG93KDIsIC1lKSkgPCAxKSB7XG4gICAgICBlLS1cbiAgICAgIGMgKj0gMlxuICAgIH1cbiAgICBpZiAoZSArIGVCaWFzID49IDEpIHtcbiAgICAgIHZhbHVlICs9IHJ0IC8gY1xuICAgIH0gZWxzZSB7XG4gICAgICB2YWx1ZSArPSBydCAqIE1hdGgucG93KDIsIDEgLSBlQmlhcylcbiAgICB9XG4gICAgaWYgKHZhbHVlICogYyA+PSAyKSB7XG4gICAgICBlKytcbiAgICAgIGMgLz0gMlxuICAgIH1cblxuICAgIGlmIChlICsgZUJpYXMgPj0gZU1heCkge1xuICAgICAgbSA9IDBcbiAgICAgIGUgPSBlTWF4XG4gICAgfSBlbHNlIGlmIChlICsgZUJpYXMgPj0gMSkge1xuICAgICAgbSA9ICgodmFsdWUgKiBjKSAtIDEpICogTWF0aC5wb3coMiwgbUxlbilcbiAgICAgIGUgPSBlICsgZUJpYXNcbiAgICB9IGVsc2Uge1xuICAgICAgbSA9IHZhbHVlICogTWF0aC5wb3coMiwgZUJpYXMgLSAxKSAqIE1hdGgucG93KDIsIG1MZW4pXG4gICAgICBlID0gMFxuICAgIH1cbiAgfVxuXG4gIGZvciAoOyBtTGVuID49IDg7IGJ1ZmZlcltvZmZzZXQgKyBpXSA9IG0gJiAweGZmLCBpICs9IGQsIG0gLz0gMjU2LCBtTGVuIC09IDgpIHt9XG5cbiAgZSA9IChlIDw8IG1MZW4pIHwgbVxuICBlTGVuICs9IG1MZW5cbiAgZm9yICg7IGVMZW4gPiAwOyBidWZmZXJbb2Zmc2V0ICsgaV0gPSBlICYgMHhmZiwgaSArPSBkLCBlIC89IDI1NiwgZUxlbiAtPSA4KSB7fVxuXG4gIGJ1ZmZlcltvZmZzZXQgKyBpIC0gZF0gfD0gcyAqIDEyOFxufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKiogQHR5cGUge2ltcG9ydCgnLi9hYnMnKX0gKi9cbm1vZHVsZS5leHBvcnRzID0gTWF0aC5hYnM7XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKiBAdHlwZSB7aW1wb3J0KCcuL2Zsb29yJyl9ICovXG5tb2R1bGUuZXhwb3J0cyA9IE1hdGguZmxvb3I7XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKiBAdHlwZSB7aW1wb3J0KCcuL2lzTmFOJyl9ICovXG5tb2R1bGUuZXhwb3J0cyA9IE51bWJlci5pc05hTiB8fCBmdW5jdGlvbiBpc05hTihhKSB7XG5cdHJldHVybiBhICE9PSBhO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqIEB0eXBlIHtpbXBvcnQoJy4vbWF4Jyl9ICovXG5tb2R1bGUuZXhwb3J0cyA9IE1hdGgubWF4O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKiogQHR5cGUge2ltcG9ydCgnLi9taW4nKX0gKi9cbm1vZHVsZS5leHBvcnRzID0gTWF0aC5taW47XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKiBAdHlwZSB7aW1wb3J0KCcuL3BvdycpfSAqL1xubW9kdWxlLmV4cG9ydHMgPSBNYXRoLnBvdztcbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqIEB0eXBlIHtpbXBvcnQoJy4vcm91bmQnKX0gKi9cbm1vZHVsZS5leHBvcnRzID0gTWF0aC5yb3VuZDtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyICRpc05hTiA9IHJlcXVpcmUoJy4vaXNOYU4nKTtcblxuLyoqIEB0eXBlIHtpbXBvcnQoJy4vc2lnbicpfSAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBzaWduKG51bWJlcikge1xuXHRpZiAoJGlzTmFOKG51bWJlcikgfHwgbnVtYmVyID09PSAwKSB7XG5cdFx0cmV0dXJuIG51bWJlcjtcblx0fVxuXHRyZXR1cm4gbnVtYmVyIDwgMCA/IC0xIDogKzE7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIga2V5c1NoaW07XG5pZiAoIU9iamVjdC5rZXlzKSB7XG5cdC8vIG1vZGlmaWVkIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL2VzLXNoaW1zL2VzNS1zaGltXG5cdHZhciBoYXMgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuXHR2YXIgdG9TdHIgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xuXHR2YXIgaXNBcmdzID0gcmVxdWlyZSgnLi9pc0FyZ3VtZW50cycpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIGdsb2JhbC1yZXF1aXJlXG5cdHZhciBpc0VudW1lcmFibGUgPSBPYmplY3QucHJvdG90eXBlLnByb3BlcnR5SXNFbnVtZXJhYmxlO1xuXHR2YXIgaGFzRG9udEVudW1CdWcgPSAhaXNFbnVtZXJhYmxlLmNhbGwoeyB0b1N0cmluZzogbnVsbCB9LCAndG9TdHJpbmcnKTtcblx0dmFyIGhhc1Byb3RvRW51bUJ1ZyA9IGlzRW51bWVyYWJsZS5jYWxsKGZ1bmN0aW9uICgpIHt9LCAncHJvdG90eXBlJyk7XG5cdHZhciBkb250RW51bXMgPSBbXG5cdFx0J3RvU3RyaW5nJyxcblx0XHQndG9Mb2NhbGVTdHJpbmcnLFxuXHRcdCd2YWx1ZU9mJyxcblx0XHQnaGFzT3duUHJvcGVydHknLFxuXHRcdCdpc1Byb3RvdHlwZU9mJyxcblx0XHQncHJvcGVydHlJc0VudW1lcmFibGUnLFxuXHRcdCdjb25zdHJ1Y3Rvcidcblx0XTtcblx0dmFyIGVxdWFsc0NvbnN0cnVjdG9yUHJvdG90eXBlID0gZnVuY3Rpb24gKG8pIHtcblx0XHR2YXIgY3RvciA9IG8uY29uc3RydWN0b3I7XG5cdFx0cmV0dXJuIGN0b3IgJiYgY3Rvci5wcm90b3R5cGUgPT09IG87XG5cdH07XG5cdHZhciBleGNsdWRlZEtleXMgPSB7XG5cdFx0JGFwcGxpY2F0aW9uQ2FjaGU6IHRydWUsXG5cdFx0JGNvbnNvbGU6IHRydWUsXG5cdFx0JGV4dGVybmFsOiB0cnVlLFxuXHRcdCRmcmFtZTogdHJ1ZSxcblx0XHQkZnJhbWVFbGVtZW50OiB0cnVlLFxuXHRcdCRmcmFtZXM6IHRydWUsXG5cdFx0JGlubmVySGVpZ2h0OiB0cnVlLFxuXHRcdCRpbm5lcldpZHRoOiB0cnVlLFxuXHRcdCRvbm1vemZ1bGxzY3JlZW5jaGFuZ2U6IHRydWUsXG5cdFx0JG9ubW96ZnVsbHNjcmVlbmVycm9yOiB0cnVlLFxuXHRcdCRvdXRlckhlaWdodDogdHJ1ZSxcblx0XHQkb3V0ZXJXaWR0aDogdHJ1ZSxcblx0XHQkcGFnZVhPZmZzZXQ6IHRydWUsXG5cdFx0JHBhZ2VZT2Zmc2V0OiB0cnVlLFxuXHRcdCRwYXJlbnQ6IHRydWUsXG5cdFx0JHNjcm9sbExlZnQ6IHRydWUsXG5cdFx0JHNjcm9sbFRvcDogdHJ1ZSxcblx0XHQkc2Nyb2xsWDogdHJ1ZSxcblx0XHQkc2Nyb2xsWTogdHJ1ZSxcblx0XHQkc2VsZjogdHJ1ZSxcblx0XHQkd2Via2l0SW5kZXhlZERCOiB0cnVlLFxuXHRcdCR3ZWJraXRTdG9yYWdlSW5mbzogdHJ1ZSxcblx0XHQkd2luZG93OiB0cnVlXG5cdH07XG5cdHZhciBoYXNBdXRvbWF0aW9uRXF1YWxpdHlCdWcgPSAoZnVuY3Rpb24gKCkge1xuXHRcdC8qIGdsb2JhbCB3aW5kb3cgKi9cblx0XHRpZiAodHlwZW9mIHdpbmRvdyA9PT0gJ3VuZGVmaW5lZCcpIHsgcmV0dXJuIGZhbHNlOyB9XG5cdFx0Zm9yICh2YXIgayBpbiB3aW5kb3cpIHtcblx0XHRcdHRyeSB7XG5cdFx0XHRcdGlmICghZXhjbHVkZWRLZXlzWyckJyArIGtdICYmIGhhcy5jYWxsKHdpbmRvdywgaykgJiYgd2luZG93W2tdICE9PSBudWxsICYmIHR5cGVvZiB3aW5kb3dba10gPT09ICdvYmplY3QnKSB7XG5cdFx0XHRcdFx0dHJ5IHtcblx0XHRcdFx0XHRcdGVxdWFsc0NvbnN0cnVjdG9yUHJvdG90eXBlKHdpbmRvd1trXSk7XG5cdFx0XHRcdFx0fSBjYXRjaCAoZSkge1xuXHRcdFx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9IGNhdGNoIChlKSB7XG5cdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gZmFsc2U7XG5cdH0oKSk7XG5cdHZhciBlcXVhbHNDb25zdHJ1Y3RvclByb3RvdHlwZUlmTm90QnVnZ3kgPSBmdW5jdGlvbiAobykge1xuXHRcdC8qIGdsb2JhbCB3aW5kb3cgKi9cblx0XHRpZiAodHlwZW9mIHdpbmRvdyA9PT0gJ3VuZGVmaW5lZCcgfHwgIWhhc0F1dG9tYXRpb25FcXVhbGl0eUJ1Zykge1xuXHRcdFx0cmV0dXJuIGVxdWFsc0NvbnN0cnVjdG9yUHJvdG90eXBlKG8pO1xuXHRcdH1cblx0XHR0cnkge1xuXHRcdFx0cmV0dXJuIGVxdWFsc0NvbnN0cnVjdG9yUHJvdG90eXBlKG8pO1xuXHRcdH0gY2F0Y2ggKGUpIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdH07XG5cblx0a2V5c1NoaW0gPSBmdW5jdGlvbiBrZXlzKG9iamVjdCkge1xuXHRcdHZhciBpc09iamVjdCA9IG9iamVjdCAhPT0gbnVsbCAmJiB0eXBlb2Ygb2JqZWN0ID09PSAnb2JqZWN0Jztcblx0XHR2YXIgaXNGdW5jdGlvbiA9IHRvU3RyLmNhbGwob2JqZWN0KSA9PT0gJ1tvYmplY3QgRnVuY3Rpb25dJztcblx0XHR2YXIgaXNBcmd1bWVudHMgPSBpc0FyZ3Mob2JqZWN0KTtcblx0XHR2YXIgaXNTdHJpbmcgPSBpc09iamVjdCAmJiB0b1N0ci5jYWxsKG9iamVjdCkgPT09ICdbb2JqZWN0IFN0cmluZ10nO1xuXHRcdHZhciB0aGVLZXlzID0gW107XG5cblx0XHRpZiAoIWlzT2JqZWN0ICYmICFpc0Z1bmN0aW9uICYmICFpc0FyZ3VtZW50cykge1xuXHRcdFx0dGhyb3cgbmV3IFR5cGVFcnJvcignT2JqZWN0LmtleXMgY2FsbGVkIG9uIGEgbm9uLW9iamVjdCcpO1xuXHRcdH1cblxuXHRcdHZhciBza2lwUHJvdG8gPSBoYXNQcm90b0VudW1CdWcgJiYgaXNGdW5jdGlvbjtcblx0XHRpZiAoaXNTdHJpbmcgJiYgb2JqZWN0Lmxlbmd0aCA+IDAgJiYgIWhhcy5jYWxsKG9iamVjdCwgMCkpIHtcblx0XHRcdGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0Lmxlbmd0aDsgKytpKSB7XG5cdFx0XHRcdHRoZUtleXMucHVzaChTdHJpbmcoaSkpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGlmIChpc0FyZ3VtZW50cyAmJiBvYmplY3QubGVuZ3RoID4gMCkge1xuXHRcdFx0Zm9yICh2YXIgaiA9IDA7IGogPCBvYmplY3QubGVuZ3RoOyArK2opIHtcblx0XHRcdFx0dGhlS2V5cy5wdXNoKFN0cmluZyhqKSk7XG5cdFx0XHR9XG5cdFx0fSBlbHNlIHtcblx0XHRcdGZvciAodmFyIG5hbWUgaW4gb2JqZWN0KSB7XG5cdFx0XHRcdGlmICghKHNraXBQcm90byAmJiBuYW1lID09PSAncHJvdG90eXBlJykgJiYgaGFzLmNhbGwob2JqZWN0LCBuYW1lKSkge1xuXHRcdFx0XHRcdHRoZUtleXMucHVzaChTdHJpbmcobmFtZSkpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0aWYgKGhhc0RvbnRFbnVtQnVnKSB7XG5cdFx0XHR2YXIgc2tpcENvbnN0cnVjdG9yID0gZXF1YWxzQ29uc3RydWN0b3JQcm90b3R5cGVJZk5vdEJ1Z2d5KG9iamVjdCk7XG5cblx0XHRcdGZvciAodmFyIGsgPSAwOyBrIDwgZG9udEVudW1zLmxlbmd0aDsgKytrKSB7XG5cdFx0XHRcdGlmICghKHNraXBDb25zdHJ1Y3RvciAmJiBkb250RW51bXNba10gPT09ICdjb25zdHJ1Y3RvcicpICYmIGhhcy5jYWxsKG9iamVjdCwgZG9udEVudW1zW2tdKSkge1xuXHRcdFx0XHRcdHRoZUtleXMucHVzaChkb250RW51bXNba10pO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiB0aGVLZXlzO1xuXHR9O1xufVxubW9kdWxlLmV4cG9ydHMgPSBrZXlzU2hpbTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHNsaWNlID0gQXJyYXkucHJvdG90eXBlLnNsaWNlO1xudmFyIGlzQXJncyA9IHJlcXVpcmUoJy4vaXNBcmd1bWVudHMnKTtcblxudmFyIG9yaWdLZXlzID0gT2JqZWN0LmtleXM7XG52YXIga2V5c1NoaW0gPSBvcmlnS2V5cyA/IGZ1bmN0aW9uIGtleXMobykgeyByZXR1cm4gb3JpZ0tleXMobyk7IH0gOiByZXF1aXJlKCcuL2ltcGxlbWVudGF0aW9uJyk7XG5cbnZhciBvcmlnaW5hbEtleXMgPSBPYmplY3Qua2V5cztcblxua2V5c1NoaW0uc2hpbSA9IGZ1bmN0aW9uIHNoaW1PYmplY3RLZXlzKCkge1xuXHRpZiAoT2JqZWN0LmtleXMpIHtcblx0XHR2YXIga2V5c1dvcmtzV2l0aEFyZ3VtZW50cyA9IChmdW5jdGlvbiAoKSB7XG5cdFx0XHQvLyBTYWZhcmkgNS4wIGJ1Z1xuXHRcdFx0dmFyIGFyZ3MgPSBPYmplY3Qua2V5cyhhcmd1bWVudHMpO1xuXHRcdFx0cmV0dXJuIGFyZ3MgJiYgYXJncy5sZW5ndGggPT09IGFyZ3VtZW50cy5sZW5ndGg7XG5cdFx0fSgxLCAyKSk7XG5cdFx0aWYgKCFrZXlzV29ya3NXaXRoQXJndW1lbnRzKSB7XG5cdFx0XHRPYmplY3Qua2V5cyA9IGZ1bmN0aW9uIGtleXMob2JqZWN0KSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgZnVuYy1uYW1lLW1hdGNoaW5nXG5cdFx0XHRcdGlmIChpc0FyZ3Mob2JqZWN0KSkge1xuXHRcdFx0XHRcdHJldHVybiBvcmlnaW5hbEtleXMoc2xpY2UuY2FsbChvYmplY3QpKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gb3JpZ2luYWxLZXlzKG9iamVjdCk7XG5cdFx0XHR9O1xuXHRcdH1cblx0fSBlbHNlIHtcblx0XHRPYmplY3Qua2V5cyA9IGtleXNTaGltO1xuXHR9XG5cdHJldHVybiBPYmplY3Qua2V5cyB8fCBrZXlzU2hpbTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0ga2V5c1NoaW07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciB0b1N0ciA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaXNBcmd1bWVudHModmFsdWUpIHtcblx0dmFyIHN0ciA9IHRvU3RyLmNhbGwodmFsdWUpO1xuXHR2YXIgaXNBcmdzID0gc3RyID09PSAnW29iamVjdCBBcmd1bWVudHNdJztcblx0aWYgKCFpc0FyZ3MpIHtcblx0XHRpc0FyZ3MgPSBzdHIgIT09ICdbb2JqZWN0IEFycmF5XScgJiZcblx0XHRcdHZhbHVlICE9PSBudWxsICYmXG5cdFx0XHR0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmXG5cdFx0XHR0eXBlb2YgdmFsdWUubGVuZ3RoID09PSAnbnVtYmVyJyAmJlxuXHRcdFx0dmFsdWUubGVuZ3RoID49IDAgJiZcblx0XHRcdHRvU3RyLmNhbGwodmFsdWUuY2FsbGVlKSA9PT0gJ1tvYmplY3QgRnVuY3Rpb25dJztcblx0fVxuXHRyZXR1cm4gaXNBcmdzO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxuLy8gbW9kaWZpZWQgZnJvbSBodHRwczovL2dpdGh1Yi5jb20vZXMtc2hpbXMvZXM2LXNoaW1cbnZhciBvYmplY3RLZXlzID0gcmVxdWlyZSgnb2JqZWN0LWtleXMnKTtcbnZhciBoYXNTeW1ib2xzID0gcmVxdWlyZSgnaGFzLXN5bWJvbHMvc2hhbXMnKSgpO1xudmFyIGNhbGxCb3VuZCA9IHJlcXVpcmUoJ2NhbGwtYm91bmQnKTtcbnZhciAkT2JqZWN0ID0gcmVxdWlyZSgnZXMtb2JqZWN0LWF0b21zJyk7XG52YXIgJHB1c2ggPSBjYWxsQm91bmQoJ0FycmF5LnByb3RvdHlwZS5wdXNoJyk7XG52YXIgJHByb3BJc0VudW1lcmFibGUgPSBjYWxsQm91bmQoJ09iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUnKTtcbnZhciBvcmlnaW5hbEdldFN5bWJvbHMgPSBoYXNTeW1ib2xzID8gJE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMgOiBudWxsO1xuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLXZhcnNcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gYXNzaWduKHRhcmdldCwgc291cmNlMSkge1xuXHRpZiAodGFyZ2V0ID09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigndGFyZ2V0IG11c3QgYmUgYW4gb2JqZWN0Jyk7IH1cblx0dmFyIHRvID0gJE9iamVjdCh0YXJnZXQpOyAvLyBzdGVwIDFcblx0aWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDEpIHtcblx0XHRyZXR1cm4gdG87IC8vIHN0ZXAgMlxuXHR9XG5cdGZvciAodmFyIHMgPSAxOyBzIDwgYXJndW1lbnRzLmxlbmd0aDsgKytzKSB7XG5cdFx0dmFyIGZyb20gPSAkT2JqZWN0KGFyZ3VtZW50c1tzXSk7IC8vIHN0ZXAgMy5hLmlcblxuXHRcdC8vIHN0ZXAgMy5hLmlpOlxuXHRcdHZhciBrZXlzID0gb2JqZWN0S2V5cyhmcm9tKTtcblx0XHR2YXIgZ2V0U3ltYm9scyA9IGhhc1N5bWJvbHMgJiYgKCRPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzIHx8IG9yaWdpbmFsR2V0U3ltYm9scyk7XG5cdFx0aWYgKGdldFN5bWJvbHMpIHtcblx0XHRcdHZhciBzeW1zID0gZ2V0U3ltYm9scyhmcm9tKTtcblx0XHRcdGZvciAodmFyIGogPSAwOyBqIDwgc3ltcy5sZW5ndGg7ICsraikge1xuXHRcdFx0XHR2YXIga2V5ID0gc3ltc1tqXTtcblx0XHRcdFx0aWYgKCRwcm9wSXNFbnVtZXJhYmxlKGZyb20sIGtleSkpIHtcblx0XHRcdFx0XHQkcHVzaChrZXlzLCBrZXkpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gc3RlcCAzLmEuaWlpOlxuXHRcdGZvciAodmFyIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSkge1xuXHRcdFx0dmFyIG5leHRLZXkgPSBrZXlzW2ldO1xuXHRcdFx0aWYgKCRwcm9wSXNFbnVtZXJhYmxlKGZyb20sIG5leHRLZXkpKSB7IC8vIHN0ZXAgMy5hLmlpaS4yXG5cdFx0XHRcdHZhciBwcm9wVmFsdWUgPSBmcm9tW25leHRLZXldOyAvLyBzdGVwIDMuYS5paWkuMi5hXG5cdFx0XHRcdHRvW25leHRLZXldID0gcHJvcFZhbHVlOyAvLyBzdGVwIDMuYS5paWkuMi5iXG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIHRvOyAvLyBzdGVwIDRcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBpbXBsZW1lbnRhdGlvbiA9IHJlcXVpcmUoJy4vaW1wbGVtZW50YXRpb24nKTtcblxudmFyIGxhY2tzUHJvcGVyRW51bWVyYXRpb25PcmRlciA9IGZ1bmN0aW9uICgpIHtcblx0aWYgKCFPYmplY3QuYXNzaWduKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cdC8qXG5cdCAqIHY4LCBzcGVjaWZpY2FsbHkgaW4gbm9kZSA0LngsIGhhcyBhIGJ1ZyB3aXRoIGluY29ycmVjdCBwcm9wZXJ0eSBlbnVtZXJhdGlvbiBvcmRlclxuXHQgKiBub3RlOiB0aGlzIGRvZXMgbm90IGRldGVjdCB0aGUgYnVnIHVubGVzcyB0aGVyZSdzIDIwIGNoYXJhY3RlcnNcblx0ICovXG5cdHZhciBzdHIgPSAnYWJjZGVmZ2hpamtsbW5vcHFyc3QnO1xuXHR2YXIgbGV0dGVycyA9IHN0ci5zcGxpdCgnJyk7XG5cdHZhciBtYXAgPSB7fTtcblx0Zm9yICh2YXIgaSA9IDA7IGkgPCBsZXR0ZXJzLmxlbmd0aDsgKytpKSB7XG5cdFx0bWFwW2xldHRlcnNbaV1dID0gbGV0dGVyc1tpXTtcblx0fVxuXHR2YXIgb2JqID0gT2JqZWN0LmFzc2lnbih7fSwgbWFwKTtcblx0dmFyIGFjdHVhbCA9ICcnO1xuXHRmb3IgKHZhciBrIGluIG9iaikge1xuXHRcdGFjdHVhbCArPSBrO1xuXHR9XG5cdHJldHVybiBzdHIgIT09IGFjdHVhbDtcbn07XG5cbnZhciBhc3NpZ25IYXNQZW5kaW5nRXhjZXB0aW9ucyA9IGZ1bmN0aW9uICgpIHtcblx0aWYgKCFPYmplY3QuYXNzaWduIHx8ICFPYmplY3QucHJldmVudEV4dGVuc2lvbnMpIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblx0Lypcblx0ICogRmlyZWZveCAzNyBzdGlsbCBoYXMgXCJwZW5kaW5nIGV4Y2VwdGlvblwiIGxvZ2ljIGluIGl0cyBPYmplY3QuYXNzaWduIGltcGxlbWVudGF0aW9uLFxuXHQgKiB3aGljaCBpcyA3MiUgc2xvd2VyIHRoYW4gb3VyIHNoaW0sIGFuZCBGaXJlZm94IDQwJ3MgbmF0aXZlIGltcGxlbWVudGF0aW9uLlxuXHQgKi9cblx0dmFyIHRocm93ZXIgPSBPYmplY3QucHJldmVudEV4dGVuc2lvbnMoeyAxOiAyIH0pO1xuXHR0cnkge1xuXHRcdE9iamVjdC5hc3NpZ24odGhyb3dlciwgJ3h5Jyk7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHRyZXR1cm4gdGhyb3dlclsxXSA9PT0gJ3knO1xuXHR9XG5cdHJldHVybiBmYWxzZTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gZ2V0UG9seWZpbGwoKSB7XG5cdGlmICghT2JqZWN0LmFzc2lnbikge1xuXHRcdHJldHVybiBpbXBsZW1lbnRhdGlvbjtcblx0fVxuXHRpZiAobGFja3NQcm9wZXJFbnVtZXJhdGlvbk9yZGVyKCkpIHtcblx0XHRyZXR1cm4gaW1wbGVtZW50YXRpb247XG5cdH1cblx0aWYgKGFzc2lnbkhhc1BlbmRpbmdFeGNlcHRpb25zKCkpIHtcblx0XHRyZXR1cm4gaW1wbGVtZW50YXRpb247XG5cdH1cblx0cmV0dXJuIE9iamVjdC5hc3NpZ247XG59O1xuIiwiLy8gc2hpbSBmb3IgdXNpbmcgcHJvY2VzcyBpbiBicm93c2VyXG52YXIgcHJvY2VzcyA9IG1vZHVsZS5leHBvcnRzID0ge307XG5cbi8vIGNhY2hlZCBmcm9tIHdoYXRldmVyIGdsb2JhbCBpcyBwcmVzZW50IHNvIHRoYXQgdGVzdCBydW5uZXJzIHRoYXQgc3R1YiBpdFxuLy8gZG9uJ3QgYnJlYWsgdGhpbmdzLiAgQnV0IHdlIG5lZWQgdG8gd3JhcCBpdCBpbiBhIHRyeSBjYXRjaCBpbiBjYXNlIGl0IGlzXG4vLyB3cmFwcGVkIGluIHN0cmljdCBtb2RlIGNvZGUgd2hpY2ggZG9lc24ndCBkZWZpbmUgYW55IGdsb2JhbHMuICBJdCdzIGluc2lkZSBhXG4vLyBmdW5jdGlvbiBiZWNhdXNlIHRyeS9jYXRjaGVzIGRlb3B0aW1pemUgaW4gY2VydGFpbiBlbmdpbmVzLlxuXG52YXIgY2FjaGVkU2V0VGltZW91dDtcbnZhciBjYWNoZWRDbGVhclRpbWVvdXQ7XG5cbmZ1bmN0aW9uIGRlZmF1bHRTZXRUaW1vdXQoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdzZXRUaW1lb3V0IGhhcyBub3QgYmVlbiBkZWZpbmVkJyk7XG59XG5mdW5jdGlvbiBkZWZhdWx0Q2xlYXJUaW1lb3V0ICgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2NsZWFyVGltZW91dCBoYXMgbm90IGJlZW4gZGVmaW5lZCcpO1xufVxuKGZ1bmN0aW9uICgpIHtcbiAgICB0cnkge1xuICAgICAgICBpZiAodHlwZW9mIHNldFRpbWVvdXQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIGNhY2hlZFNldFRpbWVvdXQgPSBzZXRUaW1lb3V0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IGRlZmF1bHRTZXRUaW1vdXQ7XG4gICAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGNhY2hlZFNldFRpbWVvdXQgPSBkZWZhdWx0U2V0VGltb3V0O1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICBpZiAodHlwZW9mIGNsZWFyVGltZW91dCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgY2FjaGVkQ2xlYXJUaW1lb3V0ID0gY2xlYXJUaW1lb3V0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY2FjaGVkQ2xlYXJUaW1lb3V0ID0gZGVmYXVsdENsZWFyVGltZW91dDtcbiAgICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgY2FjaGVkQ2xlYXJUaW1lb3V0ID0gZGVmYXVsdENsZWFyVGltZW91dDtcbiAgICB9XG59ICgpKVxuZnVuY3Rpb24gcnVuVGltZW91dChmdW4pIHtcbiAgICBpZiAoY2FjaGVkU2V0VGltZW91dCA9PT0gc2V0VGltZW91dCkge1xuICAgICAgICAvL25vcm1hbCBlbnZpcm9tZW50cyBpbiBzYW5lIHNpdHVhdGlvbnNcbiAgICAgICAgcmV0dXJuIHNldFRpbWVvdXQoZnVuLCAwKTtcbiAgICB9XG4gICAgLy8gaWYgc2V0VGltZW91dCB3YXNuJ3QgYXZhaWxhYmxlIGJ1dCB3YXMgbGF0dGVyIGRlZmluZWRcbiAgICBpZiAoKGNhY2hlZFNldFRpbWVvdXQgPT09IGRlZmF1bHRTZXRUaW1vdXQgfHwgIWNhY2hlZFNldFRpbWVvdXQpICYmIHNldFRpbWVvdXQpIHtcbiAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IHNldFRpbWVvdXQ7XG4gICAgICAgIHJldHVybiBzZXRUaW1lb3V0KGZ1biwgMCk7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIC8vIHdoZW4gd2hlbiBzb21lYm9keSBoYXMgc2NyZXdlZCB3aXRoIHNldFRpbWVvdXQgYnV0IG5vIEkuRS4gbWFkZG5lc3NcbiAgICAgICAgcmV0dXJuIGNhY2hlZFNldFRpbWVvdXQoZnVuLCAwKTtcbiAgICB9IGNhdGNoKGUpe1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gV2hlbiB3ZSBhcmUgaW4gSS5FLiBidXQgdGhlIHNjcmlwdCBoYXMgYmVlbiBldmFsZWQgc28gSS5FLiBkb2Vzbid0IHRydXN0IHRoZSBnbG9iYWwgb2JqZWN0IHdoZW4gY2FsbGVkIG5vcm1hbGx5XG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkU2V0VGltZW91dC5jYWxsKG51bGwsIGZ1biwgMCk7XG4gICAgICAgIH0gY2F0Y2goZSl7XG4gICAgICAgICAgICAvLyBzYW1lIGFzIGFib3ZlIGJ1dCB3aGVuIGl0J3MgYSB2ZXJzaW9uIG9mIEkuRS4gdGhhdCBtdXN0IGhhdmUgdGhlIGdsb2JhbCBvYmplY3QgZm9yICd0aGlzJywgaG9wZnVsbHkgb3VyIGNvbnRleHQgY29ycmVjdCBvdGhlcndpc2UgaXQgd2lsbCB0aHJvdyBhIGdsb2JhbCBlcnJvclxuICAgICAgICAgICAgcmV0dXJuIGNhY2hlZFNldFRpbWVvdXQuY2FsbCh0aGlzLCBmdW4sIDApO1xuICAgICAgICB9XG4gICAgfVxuXG5cbn1cbmZ1bmN0aW9uIHJ1bkNsZWFyVGltZW91dChtYXJrZXIpIHtcbiAgICBpZiAoY2FjaGVkQ2xlYXJUaW1lb3V0ID09PSBjbGVhclRpbWVvdXQpIHtcbiAgICAgICAgLy9ub3JtYWwgZW52aXJvbWVudHMgaW4gc2FuZSBzaXR1YXRpb25zXG4gICAgICAgIHJldHVybiBjbGVhclRpbWVvdXQobWFya2VyKTtcbiAgICB9XG4gICAgLy8gaWYgY2xlYXJUaW1lb3V0IHdhc24ndCBhdmFpbGFibGUgYnV0IHdhcyBsYXR0ZXIgZGVmaW5lZFxuICAgIGlmICgoY2FjaGVkQ2xlYXJUaW1lb3V0ID09PSBkZWZhdWx0Q2xlYXJUaW1lb3V0IHx8ICFjYWNoZWRDbGVhclRpbWVvdXQpICYmIGNsZWFyVGltZW91dCkge1xuICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBjbGVhclRpbWVvdXQ7XG4gICAgICAgIHJldHVybiBjbGVhclRpbWVvdXQobWFya2VyKTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgLy8gd2hlbiB3aGVuIHNvbWVib2R5IGhhcyBzY3Jld2VkIHdpdGggc2V0VGltZW91dCBidXQgbm8gSS5FLiBtYWRkbmVzc1xuICAgICAgICByZXR1cm4gY2FjaGVkQ2xlYXJUaW1lb3V0KG1hcmtlcik7XG4gICAgfSBjYXRjaCAoZSl7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBXaGVuIHdlIGFyZSBpbiBJLkUuIGJ1dCB0aGUgc2NyaXB0IGhhcyBiZWVuIGV2YWxlZCBzbyBJLkUuIGRvZXNuJ3QgIHRydXN0IHRoZSBnbG9iYWwgb2JqZWN0IHdoZW4gY2FsbGVkIG5vcm1hbGx5XG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkQ2xlYXJUaW1lb3V0LmNhbGwobnVsbCwgbWFya2VyKTtcbiAgICAgICAgfSBjYXRjaCAoZSl7XG4gICAgICAgICAgICAvLyBzYW1lIGFzIGFib3ZlIGJ1dCB3aGVuIGl0J3MgYSB2ZXJzaW9uIG9mIEkuRS4gdGhhdCBtdXN0IGhhdmUgdGhlIGdsb2JhbCBvYmplY3QgZm9yICd0aGlzJywgaG9wZnVsbHkgb3VyIGNvbnRleHQgY29ycmVjdCBvdGhlcndpc2UgaXQgd2lsbCB0aHJvdyBhIGdsb2JhbCBlcnJvci5cbiAgICAgICAgICAgIC8vIFNvbWUgdmVyc2lvbnMgb2YgSS5FLiBoYXZlIGRpZmZlcmVudCBydWxlcyBmb3IgY2xlYXJUaW1lb3V0IHZzIHNldFRpbWVvdXRcbiAgICAgICAgICAgIHJldHVybiBjYWNoZWRDbGVhclRpbWVvdXQuY2FsbCh0aGlzLCBtYXJrZXIpO1xuICAgICAgICB9XG4gICAgfVxuXG5cblxufVxudmFyIHF1ZXVlID0gW107XG52YXIgZHJhaW5pbmcgPSBmYWxzZTtcbnZhciBjdXJyZW50UXVldWU7XG52YXIgcXVldWVJbmRleCA9IC0xO1xuXG5mdW5jdGlvbiBjbGVhblVwTmV4dFRpY2soKSB7XG4gICAgaWYgKCFkcmFpbmluZyB8fCAhY3VycmVudFF1ZXVlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZHJhaW5pbmcgPSBmYWxzZTtcbiAgICBpZiAoY3VycmVudFF1ZXVlLmxlbmd0aCkge1xuICAgICAgICBxdWV1ZSA9IGN1cnJlbnRRdWV1ZS5jb25jYXQocXVldWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHF1ZXVlSW5kZXggPSAtMTtcbiAgICB9XG4gICAgaWYgKHF1ZXVlLmxlbmd0aCkge1xuICAgICAgICBkcmFpblF1ZXVlKCk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBkcmFpblF1ZXVlKCkge1xuICAgIGlmIChkcmFpbmluZykge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIHZhciB0aW1lb3V0ID0gcnVuVGltZW91dChjbGVhblVwTmV4dFRpY2spO1xuICAgIGRyYWluaW5nID0gdHJ1ZTtcblxuICAgIHZhciBsZW4gPSBxdWV1ZS5sZW5ndGg7XG4gICAgd2hpbGUobGVuKSB7XG4gICAgICAgIGN1cnJlbnRRdWV1ZSA9IHF1ZXVlO1xuICAgICAgICBxdWV1ZSA9IFtdO1xuICAgICAgICB3aGlsZSAoKytxdWV1ZUluZGV4IDwgbGVuKSB7XG4gICAgICAgICAgICBpZiAoY3VycmVudFF1ZXVlKSB7XG4gICAgICAgICAgICAgICAgY3VycmVudFF1ZXVlW3F1ZXVlSW5kZXhdLnJ1bigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHF1ZXVlSW5kZXggPSAtMTtcbiAgICAgICAgbGVuID0gcXVldWUubGVuZ3RoO1xuICAgIH1cbiAgICBjdXJyZW50UXVldWUgPSBudWxsO1xuICAgIGRyYWluaW5nID0gZmFsc2U7XG4gICAgcnVuQ2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xufVxuXG5wcm9jZXNzLm5leHRUaWNrID0gZnVuY3Rpb24gKGZ1bikge1xuICAgIHZhciBhcmdzID0gbmV3IEFycmF5KGFyZ3VtZW50cy5sZW5ndGggLSAxKTtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGFyZ3NbaSAtIDFdID0gYXJndW1lbnRzW2ldO1xuICAgICAgICB9XG4gICAgfVxuICAgIHF1ZXVlLnB1c2gobmV3IEl0ZW0oZnVuLCBhcmdzKSk7XG4gICAgaWYgKHF1ZXVlLmxlbmd0aCA9PT0gMSAmJiAhZHJhaW5pbmcpIHtcbiAgICAgICAgcnVuVGltZW91dChkcmFpblF1ZXVlKTtcbiAgICB9XG59O1xuXG4vLyB2OCBsaWtlcyBwcmVkaWN0aWJsZSBvYmplY3RzXG5mdW5jdGlvbiBJdGVtKGZ1biwgYXJyYXkpIHtcbiAgICB0aGlzLmZ1biA9IGZ1bjtcbiAgICB0aGlzLmFycmF5ID0gYXJyYXk7XG59XG5JdGVtLnByb3RvdHlwZS5ydW4gPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5mdW4uYXBwbHkobnVsbCwgdGhpcy5hcnJheSk7XG59O1xucHJvY2Vzcy50aXRsZSA9ICdicm93c2VyJztcbnByb2Nlc3MuYnJvd3NlciA9IHRydWU7XG5wcm9jZXNzLmVudiA9IHt9O1xucHJvY2Vzcy5hcmd2ID0gW107XG5wcm9jZXNzLnZlcnNpb24gPSAnJzsgLy8gZW1wdHkgc3RyaW5nIHRvIGF2b2lkIHJlZ2V4cCBpc3N1ZXNcbnByb2Nlc3MudmVyc2lvbnMgPSB7fTtcblxuZnVuY3Rpb24gbm9vcCgpIHt9XG5cbnByb2Nlc3Mub24gPSBub29wO1xucHJvY2Vzcy5hZGRMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLm9uY2UgPSBub29wO1xucHJvY2Vzcy5vZmYgPSBub29wO1xucHJvY2Vzcy5yZW1vdmVMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLnJlbW92ZUFsbExpc3RlbmVycyA9IG5vb3A7XG5wcm9jZXNzLmVtaXQgPSBub29wO1xucHJvY2Vzcy5wcmVwZW5kTGlzdGVuZXIgPSBub29wO1xucHJvY2Vzcy5wcmVwZW5kT25jZUxpc3RlbmVyID0gbm9vcDtcblxucHJvY2Vzcy5saXN0ZW5lcnMgPSBmdW5jdGlvbiAobmFtZSkgeyByZXR1cm4gW10gfVxuXG5wcm9jZXNzLmJpbmRpbmcgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5iaW5kaW5nIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn07XG5cbnByb2Nlc3MuY3dkID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gJy8nIH07XG5wcm9jZXNzLmNoZGlyID0gZnVuY3Rpb24gKGRpcikge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5jaGRpciBpcyBub3Qgc3VwcG9ydGVkJyk7XG59O1xucHJvY2Vzcy51bWFzayA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gMDsgfTtcbiIsIlwidXNlIHN0cmljdFwiO1xudmFyIF9fc3ByZWFkQXJyYXlzID0gKHRoaXMgJiYgdGhpcy5fX3NwcmVhZEFycmF5cykgfHwgZnVuY3Rpb24gKCkge1xuICAgIGZvciAodmFyIHMgPSAwLCBpID0gMCwgaWwgPSBhcmd1bWVudHMubGVuZ3RoOyBpIDwgaWw7IGkrKykgcyArPSBhcmd1bWVudHNbaV0ubGVuZ3RoO1xuICAgIGZvciAodmFyIHIgPSBBcnJheShzKSwgayA9IDAsIGkgPSAwOyBpIDwgaWw7IGkrKylcbiAgICAgICAgZm9yICh2YXIgYSA9IGFyZ3VtZW50c1tpXSwgaiA9IDAsIGpsID0gYS5sZW5ndGg7IGogPCBqbDsgaisrLCBrKyspXG4gICAgICAgICAgICByW2tdID0gYVtqXTtcbiAgICByZXR1cm4gcjtcbn07XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLkNoZWNrZXIgPSBleHBvcnRzLmNyZWF0ZUNoZWNrZXJzID0gdm9pZCAwO1xudmFyIHR5cGVzXzEgPSByZXF1aXJlKFwiLi90eXBlc1wiKTtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiLi91dGlsXCIpO1xuLyoqXG4gKiBFeHBvcnQgZnVuY3Rpb25zIHVzZWQgdG8gZGVmaW5lIGludGVyZmFjZXMuXG4gKi9cbnZhciB0eXBlc18yID0gcmVxdWlyZShcIi4vdHlwZXNcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJUQXJyYXlcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHR5cGVzXzIuVEFycmF5OyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiVEVudW1UeXBlXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiB0eXBlc18yLlRFbnVtVHlwZTsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlRFbnVtTGl0ZXJhbFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdHlwZXNfMi5URW51bUxpdGVyYWw7IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJURnVuY1wiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdHlwZXNfMi5URnVuYzsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlRJZmFjZVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdHlwZXNfMi5USWZhY2U7IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJUTGl0ZXJhbFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdHlwZXNfMi5UTGl0ZXJhbDsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlROYW1lXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiB0eXBlc18yLlROYW1lOyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiVE9wdGlvbmFsXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiB0eXBlc18yLlRPcHRpb25hbDsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlRQYXJhbVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdHlwZXNfMi5UUGFyYW07IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJUUGFyYW1MaXN0XCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiB0eXBlc18yLlRQYXJhbUxpc3Q7IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJUUHJvcFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdHlwZXNfMi5UUHJvcDsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlRUdXBsZVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdHlwZXNfMi5UVHVwbGU7IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJUVHlwZVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdHlwZXNfMi5UVHlwZTsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlRVbmlvblwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdHlwZXNfMi5UVW5pb247IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJUSW50ZXJzZWN0aW9uXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiB0eXBlc18yLlRJbnRlcnNlY3Rpb247IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJhcnJheVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdHlwZXNfMi5hcnJheTsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcImVudW1saXRcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHR5cGVzXzIuZW51bWxpdDsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcImVudW10eXBlXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiB0eXBlc18yLmVudW10eXBlOyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiZnVuY1wiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdHlwZXNfMi5mdW5jOyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiaWZhY2VcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHR5cGVzXzIuaWZhY2U7IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJsaXRcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHR5cGVzXzIubGl0OyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwibmFtZVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdHlwZXNfMi5uYW1lOyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwib3B0XCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiB0eXBlc18yLm9wdDsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcInBhcmFtXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiB0eXBlc18yLnBhcmFtOyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwidHVwbGVcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHR5cGVzXzIudHVwbGU7IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJ1bmlvblwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdHlwZXNfMi51bmlvbjsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcImludGVyc2VjdGlvblwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdHlwZXNfMi5pbnRlcnNlY3Rpb247IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJyZXN0XCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiB0eXBlc18yLnJlc3Q7IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJpbmRleEtleVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdHlwZXNfMi5pbmRleEtleTsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkJhc2ljVHlwZVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdHlwZXNfMi5CYXNpY1R5cGU7IH0gfSk7XG52YXIgdXRpbF8yID0gcmVxdWlyZShcIi4vdXRpbFwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlZFcnJvclwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdXRpbF8yLlZFcnJvcjsgfSB9KTtcbi8qKlxuICogVGFrZXMgb25lIG9mIG1vcmUgdHlwZSBzdWl0ZXMgKGUuZy4gYSBtb2R1bGUgZ2VuZXJhdGVkIGJ5IGB0cy1pbnRlcmZhY2UtYnVpbGRlcmApLCBhbmQgY29tYmluZXNcbiAqIHRoZW0gaW50byBhIHN1aXRlIG9mIGludGVyZmFjZSBjaGVja2Vycy4gSWYgYSB0eXBlIGlzIHVzZWQgYnkgbmFtZSwgdGhhdCBuYW1lIHNob3VsZCBiZSBwcmVzZW50XG4gKiBhbW9uZyB0aGUgcGFzc2VkLWluIHR5cGUgc3VpdGVzLlxuICpcbiAqIFRoZSByZXR1cm5lZCBvYmplY3QgbWFwcyB0eXBlIG5hbWVzIHRvIENoZWNrZXIgb2JqZWN0cy5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlQ2hlY2tlcnMoKSB7XG4gICAgdmFyIHR5cGVTdWl0ZSA9IFtdO1xuICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCBhcmd1bWVudHMubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgIHR5cGVTdWl0ZVtfaV0gPSBhcmd1bWVudHNbX2ldO1xuICAgIH1cbiAgICB2YXIgZnVsbFN1aXRlID0gT2JqZWN0LmFzc2lnbi5hcHBseShPYmplY3QsIF9fc3ByZWFkQXJyYXlzKFt7fSwgdHlwZXNfMS5iYXNpY1R5cGVzXSwgdHlwZVN1aXRlKSk7XG4gICAgdmFyIGNoZWNrZXJzID0ge307XG4gICAgZm9yICh2YXIgX2EgPSAwLCB0eXBlU3VpdGVfMSA9IHR5cGVTdWl0ZTsgX2EgPCB0eXBlU3VpdGVfMS5sZW5ndGg7IF9hKyspIHtcbiAgICAgICAgdmFyIHN1aXRlXzEgPSB0eXBlU3VpdGVfMVtfYV07XG4gICAgICAgIGZvciAodmFyIF9iID0gMCwgX2MgPSBPYmplY3Qua2V5cyhzdWl0ZV8xKTsgX2IgPCBfYy5sZW5ndGg7IF9iKyspIHtcbiAgICAgICAgICAgIHZhciBuYW1lID0gX2NbX2JdO1xuICAgICAgICAgICAgY2hlY2tlcnNbbmFtZV0gPSBuZXcgQ2hlY2tlcihmdWxsU3VpdGUsIHN1aXRlXzFbbmFtZV0pO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBjaGVja2Vycztcbn1cbmV4cG9ydHMuY3JlYXRlQ2hlY2tlcnMgPSBjcmVhdGVDaGVja2Vycztcbi8qKlxuICogQ2hlY2tlciBpbXBsZW1lbnRzIHZhbGlkYXRpb24gb2Ygb2JqZWN0cywgYW5kIGFsc28gaW5jbHVkZXMgYWNjZXNzb3JzIHRvIHZhbGlkYXRlIG1ldGhvZCBjYWxscy5cbiAqIENoZWNrZXJzIHNob3VsZCBiZSBjcmVhdGVkIHVzaW5nIGBjcmVhdGVDaGVja2VycygpYC5cbiAqL1xudmFyIENoZWNrZXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XG4gICAgLy8gQ3JlYXRlIGNoZWNrZXJzIGJ5IHVzaW5nIGBjcmVhdGVDaGVja2VycygpYCBmdW5jdGlvbi5cbiAgICBmdW5jdGlvbiBDaGVja2VyKHN1aXRlLCB0dHlwZSwgX3BhdGgpIHtcbiAgICAgICAgaWYgKF9wYXRoID09PSB2b2lkIDApIHsgX3BhdGggPSAndmFsdWUnOyB9XG4gICAgICAgIHRoaXMuc3VpdGUgPSBzdWl0ZTtcbiAgICAgICAgdGhpcy50dHlwZSA9IHR0eXBlO1xuICAgICAgICB0aGlzLl9wYXRoID0gX3BhdGg7XG4gICAgICAgIHRoaXMucHJvcHMgPSBuZXcgTWFwKCk7XG4gICAgICAgIGlmICh0dHlwZSBpbnN0YW5jZW9mIHR5cGVzXzEuVElmYWNlKSB7XG4gICAgICAgICAgICBmb3IgKHZhciBfaSA9IDAsIF9hID0gdHR5cGUucHJvcHM7IF9pIDwgX2EubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgICAgICAgICAgdmFyIHAgPSBfYVtfaV07XG4gICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5zZXQocC5uYW1lLCBwLnR0eXBlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLmNoZWNrZXJQbGFpbiA9IHRoaXMudHR5cGUuZ2V0Q2hlY2tlcihzdWl0ZSwgZmFsc2UpO1xuICAgICAgICB0aGlzLmNoZWNrZXJTdHJpY3QgPSB0aGlzLnR0eXBlLmdldENoZWNrZXIoc3VpdGUsIHRydWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIHBhdGggdG8gcmVwb3J0IGluIGVycm9ycywgaW5zdGVhZCBvZiB0aGUgZGVmYXVsdCBcInZhbHVlXCIuIChFLmcuIGlmIHRoZSBDaGVja2VyIGlzIGZvclxuICAgICAqIGEgXCJwZXJzb25cIiBpbnRlcmZhY2UsIHNldCBwYXRoIHRvIFwicGVyc29uXCIgdG8gcmVwb3J0IGUuZy4gXCJwZXJzb24ubmFtZSBpcyBub3QgYSBzdHJpbmdcIi4pXG4gICAgICovXG4gICAgQ2hlY2tlci5wcm90b3R5cGUuc2V0UmVwb3J0ZWRQYXRoID0gZnVuY3Rpb24gKHBhdGgpIHtcbiAgICAgICAgdGhpcy5fcGF0aCA9IHBhdGg7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBDaGVjayB0aGF0IHRoZSBnaXZlbiB2YWx1ZSBzYXRpc2ZpZXMgdGhpcyBjaGVja2VyJ3MgdHlwZSwgb3IgdGhyb3cgRXJyb3IuXG4gICAgICovXG4gICAgQ2hlY2tlci5wcm90b3R5cGUuY2hlY2sgPSBmdW5jdGlvbiAodmFsdWUpIHsgcmV0dXJuIHRoaXMuX2RvQ2hlY2sodGhpcy5jaGVja2VyUGxhaW4sIHZhbHVlKTsgfTtcbiAgICAvKipcbiAgICAgKiBBIGZhc3QgY2hlY2sgZm9yIHdoZXRoZXIgb3Igbm90IHRoZSBnaXZlbiB2YWx1ZSBzYXRpc2ZpZXMgdGhpcyBDaGVja2VyJ3MgdHlwZS4gVGhpcyByZXR1cm5zXG4gICAgICogdHJ1ZSBvciBmYWxzZSwgZG9lcyBub3QgcHJvZHVjZSBhbiBlcnJvciBtZXNzYWdlLCBhbmQgaXMgZmFzdCBib3RoIG9uIHN1Y2Nlc3MgYW5kIG9uIGZhaWx1cmUuXG4gICAgICovXG4gICAgQ2hlY2tlci5wcm90b3R5cGUudGVzdCA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5jaGVja2VyUGxhaW4odmFsdWUsIG5ldyB1dGlsXzEuTm9vcENvbnRleHQoKSk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGEgbm9uLWVtcHR5IGFycmF5IG9mIGVycm9yIG9iamVjdHMgZGVzY3JpYmluZyB0aGUgZXJyb3JzIGlmIHRoZSBnaXZlbiB2YWx1ZSBkb2VzIG5vdCBzYXRpc2Z5IHRoaXNcbiAgICAgKiBDaGVja2VyJ3MgdHlwZSwgb3IgbnVsbCBpZiBpdCBkb2VzLlxuICAgICAqL1xuICAgIENoZWNrZXIucHJvdG90eXBlLnZhbGlkYXRlID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kb1ZhbGlkYXRlKHRoaXMuY2hlY2tlclBsYWluLCB2YWx1ZSk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBDaGVjayB0aGF0IHRoZSBnaXZlbiB2YWx1ZSBzYXRpc2ZpZXMgdGhpcyBjaGVja2VyJ3MgdHlwZSBzdHJpY3RseS4gVGhpcyBjaGVja3MgdGhhdCBvYmplY3RzXG4gICAgICogYW5kIHR1cGxlcyBoYXZlIG5vIGV4dHJhIG1lbWJlcnMuIE5vdGUgdGhhdCB0aGlzIHByZXZlbnRzIGJhY2t3YXJkIGNvbXBhdGliaWxpdHksIHNvIHVzdWFsbHlcbiAgICAgKiBhIHBsYWluIGNoZWNrKCkgaXMgbW9yZSBhcHByb3ByaWF0ZS5cbiAgICAgKi9cbiAgICBDaGVja2VyLnByb3RvdHlwZS5zdHJpY3RDaGVjayA9IGZ1bmN0aW9uICh2YWx1ZSkgeyByZXR1cm4gdGhpcy5fZG9DaGVjayh0aGlzLmNoZWNrZXJTdHJpY3QsIHZhbHVlKTsgfTtcbiAgICAvKipcbiAgICAgKiBBIGZhc3Qgc3RyaWN0IGNoZWNrIGZvciB3aGV0aGVyIG9yIG5vdCB0aGUgZ2l2ZW4gdmFsdWUgc2F0aXNmaWVzIHRoaXMgQ2hlY2tlcidzIHR5cGUuIFJldHVybnNcbiAgICAgKiB0cnVlIG9yIGZhbHNlLCBkb2VzIG5vdCBwcm9kdWNlIGFuIGVycm9yIG1lc3NhZ2UsIGFuZCBpcyBmYXN0IGJvdGggb24gc3VjY2VzcyBhbmQgb24gZmFpbHVyZS5cbiAgICAgKi9cbiAgICBDaGVja2VyLnByb3RvdHlwZS5zdHJpY3RUZXN0ID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNoZWNrZXJTdHJpY3QodmFsdWUsIG5ldyB1dGlsXzEuTm9vcENvbnRleHQoKSk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGEgbm9uLWVtcHR5IGFycmF5IG9mIGVycm9yIG9iamVjdHMgZGVzY3JpYmluZyB0aGUgZXJyb3JzIGlmIHRoZSBnaXZlbiB2YWx1ZSBkb2VzIG5vdCBzYXRpc2Z5IHRoaXNcbiAgICAgKiBDaGVja2VyJ3MgdHlwZSBzdHJpY3RseSwgb3IgbnVsbCBpZiBpdCBkb2VzLlxuICAgICAqL1xuICAgIENoZWNrZXIucHJvdG90eXBlLnN0cmljdFZhbGlkYXRlID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kb1ZhbGlkYXRlKHRoaXMuY2hlY2tlclN0cmljdCwgdmFsdWUpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogSWYgdGhpcyBjaGVja2VyIGlzIGZvciBhbiBpbnRlcmZhY2UsIHJldHVybnMgYSBDaGVja2VyIGZvciB0aGUgdHlwZSByZXF1aXJlZCBmb3IgdGhlIGdpdmVuXG4gICAgICogcHJvcGVydHkgb2YgdGhpcyBpbnRlcmZhY2UuXG4gICAgICovXG4gICAgQ2hlY2tlci5wcm90b3R5cGUuZ2V0UHJvcCA9IGZ1bmN0aW9uIChwcm9wKSB7XG4gICAgICAgIHZhciB0dHlwZSA9IHRoaXMucHJvcHMuZ2V0KHByb3ApO1xuICAgICAgICBpZiAoIXR0eXBlKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUeXBlIGhhcyBubyBwcm9wZXJ0eSBcIiArIHByb3ApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgQ2hlY2tlcih0aGlzLnN1aXRlLCB0dHlwZSwgdGhpcy5fcGF0aCArIFwiLlwiICsgcHJvcCk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBJZiB0aGlzIGNoZWNrZXIgaXMgZm9yIGFuIGludGVyZmFjZSwgcmV0dXJucyBhIENoZWNrZXIgZm9yIHRoZSBhcmd1bWVudC1saXN0IHJlcXVpcmVkIHRvIGNhbGxcbiAgICAgKiB0aGUgZ2l2ZW4gbWV0aG9kIG9mIHRoaXMgaW50ZXJmYWNlLiBFLmcuIGlmIHRoaXMgQ2hlY2tlciBpcyBmb3IgdGhlIGludGVyZmFjZTpcbiAgICAgKiAgICBpbnRlcmZhY2UgRm9vIHtcbiAgICAgKiAgICAgIGZpbmQoczogc3RyaW5nLCBwb3M/OiBudW1iZXIpOiBudW1iZXI7XG4gICAgICogICAgfVxuICAgICAqIFRoZW4gbWV0aG9kQXJncyhcImZpbmRcIikuY2hlY2soLi4uKSB3aWxsIHN1Y2NlZWQgZm9yIFtcImZvb1wiXSBhbmQgW1wiZm9vXCIsIDNdLCBidXQgbm90IGZvciBbMTddLlxuICAgICAqL1xuICAgIENoZWNrZXIucHJvdG90eXBlLm1ldGhvZEFyZ3MgPSBmdW5jdGlvbiAobWV0aG9kTmFtZSkge1xuICAgICAgICB2YXIgdGZ1bmMgPSB0aGlzLl9nZXRNZXRob2QobWV0aG9kTmFtZSk7XG4gICAgICAgIHJldHVybiBuZXcgQ2hlY2tlcih0aGlzLnN1aXRlLCB0ZnVuYy5wYXJhbUxpc3QpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogSWYgdGhpcyBjaGVja2VyIGlzIGZvciBhbiBpbnRlcmZhY2UsIHJldHVybnMgYSBDaGVja2VyIGZvciB0aGUgcmV0dXJuIHZhbHVlIG9mIHRoZSBnaXZlblxuICAgICAqIG1ldGhvZCBvZiB0aGlzIGludGVyZmFjZS5cbiAgICAgKi9cbiAgICBDaGVja2VyLnByb3RvdHlwZS5tZXRob2RSZXN1bHQgPSBmdW5jdGlvbiAobWV0aG9kTmFtZSkge1xuICAgICAgICB2YXIgdGZ1bmMgPSB0aGlzLl9nZXRNZXRob2QobWV0aG9kTmFtZSk7XG4gICAgICAgIHJldHVybiBuZXcgQ2hlY2tlcih0aGlzLnN1aXRlLCB0ZnVuYy5yZXN1bHQpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogSWYgdGhpcyBjaGVja2VyIGlzIGZvciBhIGZ1bmN0aW9uLCByZXR1cm5zIGEgQ2hlY2tlciBmb3IgaXRzIGFyZ3VtZW50LWxpc3QuXG4gICAgICovXG4gICAgQ2hlY2tlci5wcm90b3R5cGUuZ2V0QXJncyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKCEodGhpcy50dHlwZSBpbnN0YW5jZW9mIHR5cGVzXzEuVEZ1bmMpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJnZXRBcmdzKCkgYXBwbGllZCB0byBub24tZnVuY3Rpb25cIik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBDaGVja2VyKHRoaXMuc3VpdGUsIHRoaXMudHR5cGUucGFyYW1MaXN0KTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIElmIHRoaXMgY2hlY2tlciBpcyBmb3IgYSBmdW5jdGlvbiwgcmV0dXJucyBhIENoZWNrZXIgZm9yIGl0cyByZXN1bHQuXG4gICAgICovXG4gICAgQ2hlY2tlci5wcm90b3R5cGUuZ2V0UmVzdWx0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoISh0aGlzLnR0eXBlIGluc3RhbmNlb2YgdHlwZXNfMS5URnVuYykpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImdldFJlc3VsdCgpIGFwcGxpZWQgdG8gbm9uLWZ1bmN0aW9uXCIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgQ2hlY2tlcih0aGlzLnN1aXRlLCB0aGlzLnR0eXBlLnJlc3VsdCk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIHR5cGUgZm9yIHdoaWNoIHRoaXMgaXMgYSBjaGVja2VyLlxuICAgICAqL1xuICAgIENoZWNrZXIucHJvdG90eXBlLmdldFR5cGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnR0eXBlO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogQWN0dWFsIGltcGxlbWVudGF0aW9uIG9mIGNoZWNrKCkgYW5kIHN0cmljdENoZWNrKCkuXG4gICAgICovXG4gICAgQ2hlY2tlci5wcm90b3R5cGUuX2RvQ2hlY2sgPSBmdW5jdGlvbiAoY2hlY2tlckZ1bmMsIHZhbHVlKSB7XG4gICAgICAgIHZhciBub29wQ3R4ID0gbmV3IHV0aWxfMS5Ob29wQ29udGV4dCgpO1xuICAgICAgICBpZiAoIWNoZWNrZXJGdW5jKHZhbHVlLCBub29wQ3R4KSkge1xuICAgICAgICAgICAgdmFyIGRldGFpbEN0eCA9IG5ldyB1dGlsXzEuRGV0YWlsQ29udGV4dCgpO1xuICAgICAgICAgICAgY2hlY2tlckZ1bmModmFsdWUsIGRldGFpbEN0eCk7XG4gICAgICAgICAgICB0aHJvdyBkZXRhaWxDdHguZ2V0RXJyb3IodGhpcy5fcGF0aCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIENoZWNrZXIucHJvdG90eXBlLl9kb1ZhbGlkYXRlID0gZnVuY3Rpb24gKGNoZWNrZXJGdW5jLCB2YWx1ZSkge1xuICAgICAgICB2YXIgbm9vcEN0eCA9IG5ldyB1dGlsXzEuTm9vcENvbnRleHQoKTtcbiAgICAgICAgaWYgKGNoZWNrZXJGdW5jKHZhbHVlLCBub29wQ3R4KSkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGRldGFpbEN0eCA9IG5ldyB1dGlsXzEuRGV0YWlsQ29udGV4dCgpO1xuICAgICAgICBjaGVja2VyRnVuYyh2YWx1ZSwgZGV0YWlsQ3R4KTtcbiAgICAgICAgcmV0dXJuIGRldGFpbEN0eC5nZXRFcnJvckRldGFpbHModGhpcy5fcGF0aCk7XG4gICAgfTtcbiAgICBDaGVja2VyLnByb3RvdHlwZS5fZ2V0TWV0aG9kID0gZnVuY3Rpb24gKG1ldGhvZE5hbWUpIHtcbiAgICAgICAgdmFyIHR0eXBlID0gdGhpcy5wcm9wcy5nZXQobWV0aG9kTmFtZSk7XG4gICAgICAgIGlmICghdHR5cGUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlR5cGUgaGFzIG5vIHByb3BlcnR5IFwiICsgbWV0aG9kTmFtZSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCEodHR5cGUgaW5zdGFuY2VvZiB0eXBlc18xLlRGdW5jKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiUHJvcGVydHkgXCIgKyBtZXRob2ROYW1lICsgXCIgaXMgbm90IGEgbWV0aG9kXCIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0dHlwZTtcbiAgICB9O1xuICAgIHJldHVybiBDaGVja2VyO1xufSgpKTtcbmV4cG9ydHMuQ2hlY2tlciA9IENoZWNrZXI7XG4iLCJcInVzZSBzdHJpY3RcIjtcbi8qKlxuICogVGhpcyBtb2R1bGUgZGVmaW5lcyBub2RlcyB1c2VkIHRvIGRlZmluZSB0eXBlcyBhbmQgdmFsaWRhdGlvbnMgZm9yIG9iamVjdHMgYW5kIGludGVyZmFjZXMuXG4gKi9cbi8vIHRzbGludDpkaXNhYmxlOm5vLXNoYWRvd2VkLXZhcmlhYmxlIHByZWZlci1mb3Itb2ZcbnZhciBfX2V4dGVuZHMgPSAodGhpcyAmJiB0aGlzLl9fZXh0ZW5kcykgfHwgKGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICAgIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHxcbiAgICAgICAgICAgICh7IF9fcHJvdG9fXzogW10gfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7IGQuX19wcm90b19fID0gYjsgfSkgfHxcbiAgICAgICAgICAgIGZ1bmN0aW9uIChkLCBiKSB7IGZvciAodmFyIHAgaW4gYikgaWYgKGIuaGFzT3duUHJvcGVydHkocCkpIGRbcF0gPSBiW3BdOyB9O1xuICAgICAgICByZXR1cm4gZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgICB9O1xuICAgIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgICBleHRlbmRTdGF0aWNzKGQsIGIpO1xuICAgICAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cbiAgICAgICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICAgIH07XG59KSgpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5iYXNpY1R5cGVzID0gZXhwb3J0cy5CYXNpY1R5cGUgPSBleHBvcnRzLlRQYXJhbUxpc3QgPSBleHBvcnRzLlRQYXJhbSA9IGV4cG9ydHMucGFyYW0gPSBleHBvcnRzLlRGdW5jID0gZXhwb3J0cy5mdW5jID0gZXhwb3J0cy5UUHJvcCA9IGV4cG9ydHMuVE9wdGlvbmFsID0gZXhwb3J0cy5vcHQgPSBleHBvcnRzLlRJZmFjZSA9IGV4cG9ydHMuaWZhY2UgPSBleHBvcnRzLmluZGV4S2V5ID0gZXhwb3J0cy5URW51bUxpdGVyYWwgPSBleHBvcnRzLmVudW1saXQgPSBleHBvcnRzLlRFbnVtVHlwZSA9IGV4cG9ydHMuZW51bXR5cGUgPSBleHBvcnRzLlRJbnRlcnNlY3Rpb24gPSBleHBvcnRzLmludGVyc2VjdGlvbiA9IGV4cG9ydHMuVFVuaW9uID0gZXhwb3J0cy51bmlvbiA9IGV4cG9ydHMuVFR1cGxlID0gZXhwb3J0cy50dXBsZSA9IGV4cG9ydHMuUmVzdFR5cGUgPSBleHBvcnRzLnJlc3QgPSBleHBvcnRzLlRBcnJheSA9IGV4cG9ydHMuYXJyYXkgPSBleHBvcnRzLlRMaXRlcmFsID0gZXhwb3J0cy5saXQgPSBleHBvcnRzLlROYW1lID0gZXhwb3J0cy5uYW1lID0gZXhwb3J0cy5UVHlwZSA9IHZvaWQgMDtcbnZhciB1dGlsXzEgPSByZXF1aXJlKFwiLi91dGlsXCIpO1xuLyoqIE5vZGUgdGhhdCByZXByZXNlbnRzIGEgdHlwZS4gKi9cbnZhciBUVHlwZSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBUVHlwZSgpIHtcbiAgICB9XG4gICAgcmV0dXJuIFRUeXBlO1xufSgpKTtcbmV4cG9ydHMuVFR5cGUgPSBUVHlwZTtcbi8qKiBQYXJzZXMgYSB0eXBlIHNwZWMgaW50byBhIFRUeXBlIG5vZGUuICovXG5mdW5jdGlvbiBwYXJzZVNwZWModHlwZVNwZWMpIHtcbiAgICByZXR1cm4gdHlwZW9mIHR5cGVTcGVjID09PSBcInN0cmluZ1wiID8gbmFtZSh0eXBlU3BlYykgOiB0eXBlU3BlYztcbn1cbmZ1bmN0aW9uIGdldE5hbWVkVHlwZShzdWl0ZSwgbmFtZSkge1xuICAgIHZhciB0dHlwZSA9IHN1aXRlW25hbWVdO1xuICAgIGlmICghdHR5cGUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biB0eXBlIFwiICsgbmFtZSk7XG4gICAgfVxuICAgIHJldHVybiB0dHlwZTtcbn1cbi8qKlxuICogRGVmaW5lcyBhIHR5cGUgbmFtZSwgZWl0aGVyIGJ1aWx0LWluLCBvciBkZWZpbmVkIGluIHRoaXMgc3VpdGUuIEl0IGNhbiB0eXBpY2FsbHkgYmUgaW5jbHVkZWQgaW5cbiAqIHRoZSBzcGVjcyBhcyBqdXN0IGEgcGxhaW4gc3RyaW5nLlxuICovXG5mdW5jdGlvbiBuYW1lKHZhbHVlKSB7IHJldHVybiBuZXcgVE5hbWUodmFsdWUpOyB9XG5leHBvcnRzLm5hbWUgPSBuYW1lO1xudmFyIFROYW1lID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIF9fZXh0ZW5kcyhUTmFtZSwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBUTmFtZShuYW1lKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLm5hbWUgPSBuYW1lO1xuICAgICAgICBfdGhpcy5fZmFpbE1zZyA9IFwiaXMgbm90IGEgXCIgKyBuYW1lO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIFROYW1lLnByb3RvdHlwZS5nZXRDaGVja2VyID0gZnVuY3Rpb24gKHN1aXRlLCBzdHJpY3QsIGFsbG93ZWRQcm9wcykge1xuICAgICAgICAvLyBVc2luZyBuYW1lcywgd2UgY2FuIHJlZmVyZW5jZSBhIHR5cGUgcmVjdXJzaXZlbHkgaW4gaXRzIG93biBkZWZpbml0aW9uLiBUbyBhdm9pZCBhblxuICAgICAgICAvLyBpbmZpbml0ZSByZWN1cnNpb24gaW4gZ2V0Q2hlY2tlcigpIGNhbGxzLCB3ZSBjYWNoZSBhbmQgcmV1c2UgdGhlIGNoZWNrZXIgdGhhdCdzIGJlaW5nIGJ1aWx0XG4gICAgICAgIC8vIHdoZW4gaXQgcmVmZXJlbmNlcyBpdHMgb3duIFROYW1lIG5vZGUuIE5vdGUgdGhhdCBpdCdzIGltcG9ydGFudCB0byByZXVzZSB0aGUgcmVzdWx0IG9ubHlcbiAgICAgICAgLy8gd2hlbiBnZXRDaGVja2VyKCkgaXMgY2FsbGVkIHdpdGggdGhlIHNhbWUgYXJndW1lbnRzLCBidXQgdGhhdCdzIGFscmVhZHkgZ3VhcmFudGVlZCBiZWNhdXNlXG4gICAgICAgIC8vIHdlIGFyZSBjYWNoaW5nIG9ubHkgZm9yIHRoZSBjdXJyZW50IGNhbGwgYW5kIG9ubHkgZm9yIHRoZSBzYW1lIFROYW1lIG9iamVjdCAobm90IGFub3RoZXJcbiAgICAgICAgLy8gaW5zdGFuY2Ugb2YgbmFtZSgpIGNhbGwgZm9yIHRoZSBzYW1lIG5hbWUpLlxuICAgICAgICAvL1xuICAgICAgICAvLyBOb3RlIGFsc28gdGhhdCB0aGlzIGlzIGFib3V0IGhhbmRsaW5nIHJlY3Vyc2l2ZSB0eXBlczsgaXQgZG9lcyBOT1QgaGVscCB2YWxpZGF0aW5nIGRhdGFcbiAgICAgICAgLy8gd2l0aCBjaXJjdWxhciByZWZlcmVuY2VzLlxuICAgICAgICB2YXIgY2hlY2tlckZ1bmMgPSB0aGlzLl9jaGVja2VyQmVpbmdCdWlsdDtcbiAgICAgICAgaWYgKCFjaGVja2VyRnVuYykge1xuICAgICAgICAgICAgdGhpcy5fY2hlY2tlckJlaW5nQnVpbHQgPSBmdW5jdGlvbiAodmFsdWUsIGN0eCkgeyByZXR1cm4gY2hlY2tlckZ1bmModmFsdWUsIGN0eCk7IH07XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGNoZWNrZXJGdW5jID0gdGhpcy5fZ2V0Q2hlY2tlcihzdWl0ZSwgc3RyaWN0LCBhbGxvd2VkUHJvcHMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZmluYWxseSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fY2hlY2tlckJlaW5nQnVpbHQgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNoZWNrZXJGdW5jO1xuICAgIH07XG4gICAgVE5hbWUucHJvdG90eXBlLl9nZXRDaGVja2VyID0gZnVuY3Rpb24gKHN1aXRlLCBzdHJpY3QsIGFsbG93ZWRQcm9wcykge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgdHR5cGUgPSBnZXROYW1lZFR5cGUoc3VpdGUsIHRoaXMubmFtZSk7XG4gICAgICAgIHZhciBjaGVja2VyID0gdHR5cGUuZ2V0Q2hlY2tlcihzdWl0ZSwgc3RyaWN0LCBhbGxvd2VkUHJvcHMpO1xuICAgICAgICBpZiAodHR5cGUgaW5zdGFuY2VvZiBCYXNpY1R5cGUgfHwgdHR5cGUgaW5zdGFuY2VvZiBUTmFtZSkge1xuICAgICAgICAgICAgcmV0dXJuIGNoZWNrZXI7XG4gICAgICAgIH1cbiAgICAgICAgLy8gRm9yIGNvbXBsZXggdHlwZXMsIGFkZCBhbiBhZGRpdGlvbmFsIFwiaXMgbm90IGEgPFR5cGU+XCIgbWVzc2FnZSBvbiBmYWlsdXJlLlxuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKHZhbHVlLCBjdHgpIHsgcmV0dXJuIGNoZWNrZXIodmFsdWUsIGN0eCkgPyB0cnVlIDogY3R4LmZhaWwobnVsbCwgX3RoaXMuX2ZhaWxNc2csIDApOyB9O1xuICAgIH07XG4gICAgcmV0dXJuIFROYW1lO1xufShUVHlwZSkpO1xuZXhwb3J0cy5UTmFtZSA9IFROYW1lO1xuLyoqXG4gKiBEZWZpbmVzIGEgbGl0ZXJhbCB2YWx1ZSwgZS5nLiBsaXQoJ2hlbGxvJykgb3IgbGl0KDEyMykuXG4gKi9cbmZ1bmN0aW9uIGxpdCh2YWx1ZSkgeyByZXR1cm4gbmV3IFRMaXRlcmFsKHZhbHVlKTsgfVxuZXhwb3J0cy5saXQgPSBsaXQ7XG52YXIgVExpdGVyYWwgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgX19leHRlbmRzKFRMaXRlcmFsLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFRMaXRlcmFsKHZhbHVlKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLnZhbHVlID0gdmFsdWU7XG4gICAgICAgIF90aGlzLm5hbWUgPSBKU09OLnN0cmluZ2lmeSh2YWx1ZSk7XG4gICAgICAgIF90aGlzLl9mYWlsTXNnID0gXCJpcyBub3QgXCIgKyBfdGhpcy5uYW1lO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIFRMaXRlcmFsLnByb3RvdHlwZS5nZXRDaGVja2VyID0gZnVuY3Rpb24gKHN1aXRlLCBzdHJpY3QpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICh2YWx1ZSwgY3R4KSB7IHJldHVybiAodmFsdWUgPT09IF90aGlzLnZhbHVlKSA/IHRydWUgOiBjdHguZmFpbChudWxsLCBfdGhpcy5fZmFpbE1zZywgLTEpOyB9O1xuICAgIH07XG4gICAgcmV0dXJuIFRMaXRlcmFsO1xufShUVHlwZSkpO1xuZXhwb3J0cy5UTGl0ZXJhbCA9IFRMaXRlcmFsO1xuLyoqXG4gKiBEZWZpbmVzIGFuIGFycmF5IHR5cGUsIGUuZy4gYXJyYXkoJ251bWJlcicpLlxuICovXG5mdW5jdGlvbiBhcnJheSh0eXBlU3BlYykgeyByZXR1cm4gbmV3IFRBcnJheShwYXJzZVNwZWModHlwZVNwZWMpKTsgfVxuZXhwb3J0cy5hcnJheSA9IGFycmF5O1xudmFyIFRBcnJheSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICBfX2V4dGVuZHMoVEFycmF5LCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFRBcnJheSh0dHlwZSkge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy50dHlwZSA9IHR0eXBlO1xuICAgICAgICB2YXIgZWxlbWVudFR5cGVOYW1lID0gZ2V0VHlwZU5hbWUodHR5cGUpO1xuICAgICAgICBpZiAoZWxlbWVudFR5cGVOYW1lKSB7XG4gICAgICAgICAgICBfdGhpcy5uYW1lID0gZWxlbWVudFR5cGVOYW1lICsgXCJbXVwiO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgVEFycmF5LnByb3RvdHlwZS5nZXRDaGVja2VyID0gZnVuY3Rpb24gKHN1aXRlLCBzdHJpY3QpIHtcbiAgICAgICAgdmFyIGl0ZW1DaGVja2VyID0gdGhpcy50dHlwZS5nZXRDaGVja2VyKHN1aXRlLCBzdHJpY3QpO1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKHZhbHVlLCBjdHgpIHtcbiAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gY3R4LmZhaWwobnVsbCwgXCJpcyBub3QgYW4gYXJyYXlcIiwgMCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHZhbHVlLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgdmFyIG9rID0gaXRlbUNoZWNrZXIodmFsdWVbaV0sIGN0eCk7XG4gICAgICAgICAgICAgICAgaWYgKCFvaykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY3R4LmZhaWwoaSwgbnVsbCwgMSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH07XG4gICAgfTtcbiAgICByZXR1cm4gVEFycmF5O1xufShUVHlwZSkpO1xuZXhwb3J0cy5UQXJyYXkgPSBUQXJyYXk7XG4vKipcbiAqIERlZmluZXMgYSByZXN0IHR5cGUsIGUuZy4gdHVwbGUoJ3N0cmluZycsIHJlc3QoYXJyYXkoJ251bWJlcicpKSkuXG4gKi9cbmZ1bmN0aW9uIHJlc3QodHlwZVNwZWMpIHtcbiAgICByZXR1cm4gbmV3IFJlc3RUeXBlKHR5cGVTcGVjKTtcbn1cbmV4cG9ydHMucmVzdCA9IHJlc3Q7XG52YXIgUmVzdFR5cGUgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgX19leHRlbmRzKFJlc3RUeXBlLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFJlc3RUeXBlKHR5cGVTcGVjKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLnR5cGVTcGVjID0gdHlwZVNwZWM7XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgUmVzdFR5cGUucHJvdG90eXBlLnNldFN0YXJ0ID0gZnVuY3Rpb24gKHN0YXJ0KSB7XG4gICAgICAgIHRoaXMuX3N0YXJ0ID0gc3RhcnQ7XG4gICAgfTtcbiAgICBSZXN0VHlwZS5wcm90b3R5cGUuZ2V0Q2hlY2tlciA9IGZ1bmN0aW9uIChzdWl0ZSwgc3RyaWN0KSB7XG4gICAgICAgIHZhciBhcnJUeXBlID0gdHlwZW9mIHRoaXMudHlwZVNwZWMgPT09IFwic3RyaW5nXCIgPyBnZXROYW1lZFR5cGUoc3VpdGUsIHRoaXMudHlwZVNwZWMpIDogdGhpcy50eXBlU3BlYztcbiAgICAgICAgaWYgKCEoYXJyVHlwZSBpbnN0YW5jZW9mIFRBcnJheSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlJlc3QgdHlwZSBtdXN0IGJlIGFuIGFycmF5XCIpO1xuICAgICAgICB9XG4gICAgICAgIHZhciBpdGVtQ2hlY2tlciA9IGFyclR5cGUudHR5cGUuZ2V0Q2hlY2tlcihzdWl0ZSwgc3RyaWN0KTtcbiAgICAgICAgdmFyIHN0YXJ0ID0gdGhpcy5fc3RhcnQ7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAodmFsdWUsIGN0eCkge1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgdmFsdWUubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBpZiAoIWl0ZW1DaGVja2VyKHZhbHVlW2ldLCBjdHgpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjdHguZmFpbChpLCBudWxsLCAxKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfTtcbiAgICB9O1xuICAgIHJldHVybiBSZXN0VHlwZTtcbn0oVFR5cGUpKTtcbmV4cG9ydHMuUmVzdFR5cGUgPSBSZXN0VHlwZTtcbi8qKlxuICogRGVmaW5lcyBhIHR1cGxlIHR5cGUsIGUuZy4gdHVwbGUoJ3N0cmluZycsICdudW1iZXInKS5cbiAqL1xuZnVuY3Rpb24gdHVwbGUoKSB7XG4gICAgdmFyIHR5cGVTcGVjID0gW107XG4gICAgZm9yICh2YXIgX2kgPSAwOyBfaSA8IGFyZ3VtZW50cy5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgdHlwZVNwZWNbX2ldID0gYXJndW1lbnRzW19pXTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBUVHVwbGUodHlwZVNwZWMubWFwKGZ1bmN0aW9uICh0KSB7IHJldHVybiBwYXJzZVNwZWModCk7IH0pKTtcbn1cbmV4cG9ydHMudHVwbGUgPSB0dXBsZTtcbnZhciBUVHVwbGUgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgX19leHRlbmRzKFRUdXBsZSwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBUVHVwbGUodHR5cGVzKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLnR0eXBlcyA9IHR0eXBlcztcbiAgICAgICAgdmFyIGxhc3QgPSB0dHlwZXNbdHR5cGVzLmxlbmd0aCAtIDFdO1xuICAgICAgICBpZiAobGFzdCBpbnN0YW5jZW9mIFJlc3RUeXBlKSB7XG4gICAgICAgICAgICB0dHlwZXMucG9wKCk7XG4gICAgICAgICAgICBfdGhpcy5fcmVzdFR5cGUgPSBsYXN0O1xuICAgICAgICAgICAgX3RoaXMuX3Jlc3RUeXBlLnNldFN0YXJ0KHR0eXBlcy5sZW5ndGgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgVFR1cGxlLnByb3RvdHlwZS5nZXRDaGVja2VyID0gZnVuY3Rpb24gKHN1aXRlLCBzdHJpY3QpIHtcbiAgICAgICAgdmFyIGl0ZW1DaGVja2VycyA9IHRoaXMudHR5cGVzLm1hcChmdW5jdGlvbiAodCkgeyByZXR1cm4gdC5nZXRDaGVja2VyKHN1aXRlLCBzdHJpY3QpOyB9KTtcbiAgICAgICAgdmFyIGNoZWNrZXIgPSBmdW5jdGlvbiAodmFsdWUsIGN0eCkge1xuICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBjdHguZmFpbChudWxsLCBcImlzIG5vdCBhbiBhcnJheVwiLCAwKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaXRlbUNoZWNrZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgdmFyIG9rID0gaXRlbUNoZWNrZXJzW2ldKHZhbHVlW2ldLCBjdHgpO1xuICAgICAgICAgICAgICAgIGlmICghb2spIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGN0eC5mYWlsKGksIG51bGwsIDEpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9O1xuICAgICAgICBpZiAodGhpcy5fcmVzdFR5cGUpIHtcbiAgICAgICAgICAgIHZhciByZXN0Q2hlY2tlcl8xID0gdGhpcy5fcmVzdFR5cGUuZ2V0Q2hlY2tlcihzdWl0ZSwgc3RyaWN0KTtcbiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAodmFsdWUsIGN0eCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBjaGVja2VyKHZhbHVlLCBjdHgpICYmIHJlc3RDaGVja2VyXzEodmFsdWUsIGN0eCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGlmICghc3RyaWN0KSB7XG4gICAgICAgICAgICByZXR1cm4gY2hlY2tlcjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKHZhbHVlLCBjdHgpIHtcbiAgICAgICAgICAgIGlmICghY2hlY2tlcih2YWx1ZSwgY3R4KSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB2YWx1ZS5sZW5ndGggPD0gaXRlbUNoZWNrZXJzLmxlbmd0aCA/IHRydWUgOlxuICAgICAgICAgICAgICAgIGN0eC5mYWlsKGl0ZW1DaGVja2Vycy5sZW5ndGgsIFwiaXMgZXh0cmFuZW91c1wiLCAyKTtcbiAgICAgICAgfTtcbiAgICB9O1xuICAgIHJldHVybiBUVHVwbGU7XG59KFRUeXBlKSk7XG5leHBvcnRzLlRUdXBsZSA9IFRUdXBsZTtcbi8qKlxuICogRGVmaW5lcyBhIHVuaW9uIHR5cGUsIGUuZy4gdW5pb24oJ251bWJlcicsICdudWxsJykuXG4gKi9cbmZ1bmN0aW9uIHVuaW9uKCkge1xuICAgIHZhciB0eXBlU3BlYyA9IFtdO1xuICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCBhcmd1bWVudHMubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgIHR5cGVTcGVjW19pXSA9IGFyZ3VtZW50c1tfaV07XG4gICAgfVxuICAgIHJldHVybiBuZXcgVFVuaW9uKHR5cGVTcGVjLm1hcChmdW5jdGlvbiAodCkgeyByZXR1cm4gcGFyc2VTcGVjKHQpOyB9KSk7XG59XG5leHBvcnRzLnVuaW9uID0gdW5pb247XG52YXIgVFVuaW9uID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIF9fZXh0ZW5kcyhUVW5pb24sIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gVFVuaW9uKHR0eXBlcykge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy50dHlwZXMgPSB0dHlwZXM7XG4gICAgICAgIHZhciBuYW1lcyA9IHR0eXBlcy5tYXAoZ2V0VHlwZU5hbWUpXG4gICAgICAgICAgICAuZmlsdGVyKGZ1bmN0aW9uIChuKSB7IHJldHVybiBuOyB9KTtcbiAgICAgICAgdmFyIG90aGVyVHlwZXMgPSB0dHlwZXMubGVuZ3RoIC0gbmFtZXMubGVuZ3RoO1xuICAgICAgICBpZiAobmFtZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICBpZiAob3RoZXJUeXBlcyA+IDApIHtcbiAgICAgICAgICAgICAgICBuYW1lcy5wdXNoKG90aGVyVHlwZXMgKyBcIiBtb3JlXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgX3RoaXMuX2ZhaWxNc2cgPSBcImlzIG5vbmUgb2YgXCIgKyBuYW1lcy5qb2luKFwiLCBcIik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBfdGhpcy5fZmFpbE1zZyA9IFwiaXMgbm9uZSBvZiBcIiArIG90aGVyVHlwZXMgKyBcIiB0eXBlc1wiO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgVFVuaW9uLnByb3RvdHlwZS5nZXRDaGVja2VyID0gZnVuY3Rpb24gKHN1aXRlLCBzdHJpY3QsIGFsbG93ZWRQcm9wcykge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgaXRlbUNoZWNrZXJzID0gdGhpcy50dHlwZXMubWFwKGZ1bmN0aW9uICh0KSB7IHJldHVybiB0LmdldENoZWNrZXIoc3VpdGUsIHN0cmljdCwgYWxsb3dlZFByb3BzKTsgfSk7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAodmFsdWUsIGN0eCkge1xuICAgICAgICAgICAgdmFyIHVyID0gY3R4LnVuaW9uUmVzb2x2ZXIoKTtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaXRlbUNoZWNrZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgdmFyIG9rID0gaXRlbUNoZWNrZXJzW2ldKHZhbHVlLCB1ci5jcmVhdGVDb250ZXh0KCkpO1xuICAgICAgICAgICAgICAgIGlmIChvaykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjdHgucmVzb2x2ZVVuaW9uKHVyKTtcbiAgICAgICAgICAgIHJldHVybiBjdHguZmFpbChudWxsLCBfdGhpcy5fZmFpbE1zZywgMCk7XG4gICAgICAgIH07XG4gICAgfTtcbiAgICByZXR1cm4gVFVuaW9uO1xufShUVHlwZSkpO1xuZXhwb3J0cy5UVW5pb24gPSBUVW5pb247XG4vKipcbiAqIERlZmluZXMgYW4gaW50ZXJzZWN0aW9uIHR5cGUsIGUuZy4gaW50ZXJzZWN0aW9uKCdudW1iZXInLCAnbnVsbCcpLlxuICovXG5mdW5jdGlvbiBpbnRlcnNlY3Rpb24oKSB7XG4gICAgdmFyIHR5cGVTcGVjID0gW107XG4gICAgZm9yICh2YXIgX2kgPSAwOyBfaSA8IGFyZ3VtZW50cy5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgdHlwZVNwZWNbX2ldID0gYXJndW1lbnRzW19pXTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBUSW50ZXJzZWN0aW9uKHR5cGVTcGVjLm1hcChmdW5jdGlvbiAodCkgeyByZXR1cm4gcGFyc2VTcGVjKHQpOyB9KSk7XG59XG5leHBvcnRzLmludGVyc2VjdGlvbiA9IGludGVyc2VjdGlvbjtcbnZhciBUSW50ZXJzZWN0aW9uID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIF9fZXh0ZW5kcyhUSW50ZXJzZWN0aW9uLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFRJbnRlcnNlY3Rpb24odHR5cGVzKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLnR0eXBlcyA9IHR0eXBlcztcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICBUSW50ZXJzZWN0aW9uLnByb3RvdHlwZS5nZXRDaGVja2VyID0gZnVuY3Rpb24gKHN1aXRlLCBzdHJpY3QsIGFsbG93ZWRQcm9wcykge1xuICAgICAgICBpZiAoYWxsb3dlZFByb3BzID09PSB2b2lkIDApIHsgYWxsb3dlZFByb3BzID0gbmV3IFNldCgpOyB9XG4gICAgICAgIHZhciBpdGVtQ2hlY2tlcnMgPSB0aGlzLnR0eXBlcy5tYXAoZnVuY3Rpb24gKHQpIHsgcmV0dXJuIHQuZ2V0Q2hlY2tlcihzdWl0ZSwgc3RyaWN0LCBhbGxvd2VkUHJvcHMpOyB9KTtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICh2YWx1ZSwgY3R4KSB7XG4gICAgICAgICAgICByZXR1cm4gaXRlbUNoZWNrZXJzLmV2ZXJ5KGZ1bmN0aW9uIChjaGVja2VyKSB7XG4gICAgICAgICAgICAgICAgY2hlY2tlcih2YWx1ZSwgY3R4LmZvcmsoKSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGN0eC5jb21wbGV0ZUZvcmsoKTtcbiAgICAgICAgICAgIH0pICYmICFjdHguZmFpbGVkKCk7XG4gICAgICAgIH07XG4gICAgfTtcbiAgICByZXR1cm4gVEludGVyc2VjdGlvbjtcbn0oVFR5cGUpKTtcbmV4cG9ydHMuVEludGVyc2VjdGlvbiA9IFRJbnRlcnNlY3Rpb247XG4vKipcbiAqIERlZmluZXMgYW4gZW51bSB0eXBlLCBlLmcuIGVudW0oeydBJzogMSwgJ0InOiAyfSkuXG4gKi9cbmZ1bmN0aW9uIGVudW10eXBlKHZhbHVlcykge1xuICAgIHJldHVybiBuZXcgVEVudW1UeXBlKHZhbHVlcyk7XG59XG5leHBvcnRzLmVudW10eXBlID0gZW51bXR5cGU7XG52YXIgVEVudW1UeXBlID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIF9fZXh0ZW5kcyhURW51bVR5cGUsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gVEVudW1UeXBlKG1lbWJlcnMpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMubWVtYmVycyA9IG1lbWJlcnM7XG4gICAgICAgIF90aGlzLnZhbGlkVmFsdWVzID0gbmV3IFNldCgpO1xuICAgICAgICBfdGhpcy5fZmFpbE1zZyA9IFwiaXMgbm90IGEgdmFsaWQgZW51bSB2YWx1ZVwiO1xuICAgICAgICBfdGhpcy52YWxpZFZhbHVlcyA9IG5ldyBTZXQoT2JqZWN0LmtleXMobWVtYmVycykubWFwKGZ1bmN0aW9uIChuYW1lKSB7IHJldHVybiBtZW1iZXJzW25hbWVdOyB9KSk7XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgVEVudW1UeXBlLnByb3RvdHlwZS5nZXRDaGVja2VyID0gZnVuY3Rpb24gKHN1aXRlLCBzdHJpY3QpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICh2YWx1ZSwgY3R4KSB7XG4gICAgICAgICAgICByZXR1cm4gKF90aGlzLnZhbGlkVmFsdWVzLmhhcyh2YWx1ZSkgPyB0cnVlIDogY3R4LmZhaWwobnVsbCwgX3RoaXMuX2ZhaWxNc2csIDApKTtcbiAgICAgICAgfTtcbiAgICB9O1xuICAgIHJldHVybiBURW51bVR5cGU7XG59KFRUeXBlKSk7XG5leHBvcnRzLlRFbnVtVHlwZSA9IFRFbnVtVHlwZTtcbi8qKlxuICogRGVmaW5lcyBhIGxpdGVyYWwgZW51bSB2YWx1ZSwgc3VjaCBhcyBEaXJlY3Rpb24uVXAsIHNwZWNpZmllZCBhcyBlbnVtbGl0KFwiRGlyZWN0aW9uXCIsIFwiVXBcIikuXG4gKi9cbmZ1bmN0aW9uIGVudW1saXQobmFtZSwgcHJvcCkge1xuICAgIHJldHVybiBuZXcgVEVudW1MaXRlcmFsKG5hbWUsIHByb3ApO1xufVxuZXhwb3J0cy5lbnVtbGl0ID0gZW51bWxpdDtcbnZhciBURW51bUxpdGVyYWwgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgX19leHRlbmRzKFRFbnVtTGl0ZXJhbCwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBURW51bUxpdGVyYWwoZW51bU5hbWUsIHByb3ApIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMuZW51bU5hbWUgPSBlbnVtTmFtZTtcbiAgICAgICAgX3RoaXMucHJvcCA9IHByb3A7XG4gICAgICAgIF90aGlzLl9mYWlsTXNnID0gXCJpcyBub3QgXCIgKyBlbnVtTmFtZSArIFwiLlwiICsgcHJvcDtcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICBURW51bUxpdGVyYWwucHJvdG90eXBlLmdldENoZWNrZXIgPSBmdW5jdGlvbiAoc3VpdGUsIHN0cmljdCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgdHR5cGUgPSBnZXROYW1lZFR5cGUoc3VpdGUsIHRoaXMuZW51bU5hbWUpO1xuICAgICAgICBpZiAoISh0dHlwZSBpbnN0YW5jZW9mIFRFbnVtVHlwZSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlR5cGUgXCIgKyB0aGlzLmVudW1OYW1lICsgXCIgdXNlZCBpbiBlbnVtbGl0IGlzIG5vdCBhbiBlbnVtIHR5cGVcIik7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHZhbCA9IHR0eXBlLm1lbWJlcnNbdGhpcy5wcm9wXTtcbiAgICAgICAgaWYgKCF0dHlwZS5tZW1iZXJzLmhhc093blByb3BlcnR5KHRoaXMucHJvcCkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gdmFsdWUgXCIgKyB0aGlzLmVudW1OYW1lICsgXCIuXCIgKyB0aGlzLnByb3AgKyBcIiB1c2VkIGluIGVudW1saXRcIik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICh2YWx1ZSwgY3R4KSB7IHJldHVybiAodmFsdWUgPT09IHZhbCkgPyB0cnVlIDogY3R4LmZhaWwobnVsbCwgX3RoaXMuX2ZhaWxNc2csIC0xKTsgfTtcbiAgICB9O1xuICAgIHJldHVybiBURW51bUxpdGVyYWw7XG59KFRUeXBlKSk7XG5leHBvcnRzLlRFbnVtTGl0ZXJhbCA9IFRFbnVtTGl0ZXJhbDtcbmZ1bmN0aW9uIG1ha2VJZmFjZVByb3BzKHByb3BzKSB7XG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKHByb3BzKVxuICAgICAgICAuZmlsdGVyKGZ1bmN0aW9uIChuYW1lKSB7IHJldHVybiAobmFtZSAhPT0gZXhwb3J0cy5pbmRleEtleSk7IH0pXG4gICAgICAgIC5tYXAoZnVuY3Rpb24gKG5hbWUpIHsgcmV0dXJuIG1ha2VJZmFjZVByb3AobmFtZSwgcHJvcHNbbmFtZV0pOyB9KTtcbn1cbmZ1bmN0aW9uIG1ha2VJZmFjZVByb3AobmFtZSwgcHJvcCkge1xuICAgIHJldHVybiBwcm9wIGluc3RhbmNlb2YgVE9wdGlvbmFsID9cbiAgICAgICAgbmV3IFRQcm9wKG5hbWUsIHByb3AudHR5cGUsIHRydWUpIDpcbiAgICAgICAgbmV3IFRQcm9wKG5hbWUsIHBhcnNlU3BlYyhwcm9wKSwgZmFsc2UpO1xufVxuLyoqXG4gKiBpbmRleEtleSBpcyBhIHNwZWNpYWwga2V5IHRoYXQgaW5kaWNhdGVzIGFuIGluZGV4IHNpZ25hdHVyZSB3aGVuIHVzZWQgYXMgYSBrZXkgaW4gYW4gaW50ZXJmYWNlLlxuICogRS5nLiB7W2tleTogc3RyaW5nXTogbnVtYmVyfSBiZWNvbWVzIHQuaWZhY2UoW10sIHtbdC5pbmRleEtleV06IFwibnVtYmVyXCJ9KS5cbiAqXG4gKiBXZSBkb24ndCBkaXN0aW5ndWlzaCBiZXR3ZWVuIHN0cmluZy0gYW5kIG51bWJlci10eXBlIGluZGV4IHNpZ25hdHVyZXMsIGFuZCBkb24ndCBzdXBwb3J0XG4gKiBtdWx0aXBsZSBpbmRleCBzaWduYXR1cmVzLlxuICovXG5leHBvcnRzLmluZGV4S2V5ID0gU3ltYm9sKCk7XG4vKipcbiAqIERlZmluZXMgYW4gaW50ZXJmYWNlLiBUaGUgZmlyc3QgYXJndW1lbnQgaXMgYW4gYXJyYXkgb2YgaW50ZXJmYWNlcyB0aGF0IGl0IGV4dGVuZHMsIGFuZCB0aGVcbiAqIHNlY29uZCBpcyBhbiBhcnJheSBvZiBwcm9wZXJ0aWVzLlxuICovXG5mdW5jdGlvbiBpZmFjZShiYXNlcywgcHJvcHMpIHtcbiAgICByZXR1cm4gbmV3IFRJZmFjZShiYXNlcywgbWFrZUlmYWNlUHJvcHMocHJvcHMpLCBwcm9wc1tleHBvcnRzLmluZGV4S2V5XSk7XG59XG5leHBvcnRzLmlmYWNlID0gaWZhY2U7XG52YXIgVElmYWNlID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIF9fZXh0ZW5kcyhUSWZhY2UsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gVElmYWNlKGJhc2VzLCBwcm9wcywgaW5kZXhUeXBlKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLmJhc2VzID0gYmFzZXM7XG4gICAgICAgIF90aGlzLnByb3BzID0gcHJvcHM7XG4gICAgICAgIF90aGlzLmluZGV4VHlwZSA9IGluZGV4VHlwZSA/IHBhcnNlU3BlYyhpbmRleFR5cGUpIDogdW5kZWZpbmVkO1xuICAgICAgICBfdGhpcy5wcm9wU2V0ID0gbmV3IFNldChwcm9wcy5tYXAoZnVuY3Rpb24gKHApIHsgcmV0dXJuIHAubmFtZTsgfSkpO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIFRJZmFjZS5wcm90b3R5cGUuZ2V0Q2hlY2tlciA9IGZ1bmN0aW9uIChzdWl0ZSwgc3RyaWN0LCBhbGxvd2VkUHJvcHMpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIF9hO1xuICAgICAgICBpZiAoYWxsb3dlZFByb3BzID09PSB2b2lkIDApIHsgYWxsb3dlZFByb3BzID0gbmV3IFNldCgpOyB9XG4gICAgICAgIHRoaXMucHJvcFNldC5mb3JFYWNoKGZ1bmN0aW9uIChwcm9wKSB7IHJldHVybiBhbGxvd2VkUHJvcHMuYWRkKHByb3ApOyB9KTtcbiAgICAgICAgdmFyIGJhc2VDaGVja2VycyA9IHRoaXMuYmFzZXMubWFwKGZ1bmN0aW9uIChiKSB7IHJldHVybiBnZXROYW1lZFR5cGUoc3VpdGUsIGIpLmdldENoZWNrZXIoc3VpdGUsIHN0cmljdCwgYWxsb3dlZFByb3BzKTsgfSk7XG4gICAgICAgIHZhciBwcm9wQ2hlY2tlcnMgPSB0aGlzLnByb3BzLm1hcChmdW5jdGlvbiAocHJvcCkgeyByZXR1cm4gcHJvcC50dHlwZS5nZXRDaGVja2VyKHN1aXRlLCBzdHJpY3QpOyB9KTtcbiAgICAgICAgdmFyIGluZGV4VHlwZUNoZWNrZXIgPSAoX2EgPSB0aGlzLmluZGV4VHlwZSkgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hLmdldENoZWNrZXIoc3VpdGUsIHN0cmljdCk7XG4gICAgICAgIHZhciB0ZXN0Q3R4ID0gbmV3IHV0aWxfMS5Ob29wQ29udGV4dCgpO1xuICAgICAgICAvLyBDb25zaWRlciBhIHByb3AgcmVxdWlyZWQgaWYgaXQncyBub3Qgb3B0aW9uYWwgQU5EIGRvZXMgbm90IGFsbG93IGZvciB1bmRlZmluZWQgYXMgYSB2YWx1ZS5cbiAgICAgICAgdmFyIGlzUHJvcFJlcXVpcmVkID0gdGhpcy5wcm9wcy5tYXAoZnVuY3Rpb24gKHByb3AsIGkpIHtcbiAgICAgICAgICAgIHJldHVybiAhcHJvcC5pc09wdCAmJiAhcHJvcENoZWNrZXJzW2ldKHVuZGVmaW5lZCwgdGVzdEN0eCk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKHZhbHVlLCBjdHgpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgIT09IFwib2JqZWN0XCIgfHwgdmFsdWUgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gY3R4LmZhaWwobnVsbCwgXCJpcyBub3QgYW4gb2JqZWN0XCIsIDApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBiYXNlQ2hlY2tlcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBiYXNlQ2hlY2tlcnNbaV0odmFsdWUsIGN0eC5mb3JrKCkpO1xuICAgICAgICAgICAgICAgIGlmICghY3R4LmNvbXBsZXRlRm9yaygpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BDaGVja2Vycy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIHZhciBuYW1lXzEgPSBfdGhpcy5wcm9wc1tpXS5uYW1lO1xuICAgICAgICAgICAgICAgIHZhciB2ID0gdmFsdWVbbmFtZV8xXTtcbiAgICAgICAgICAgICAgICBpZiAodiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc1Byb3BSZXF1aXJlZFtpXSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY3R4LmZvcmsoKS5mYWlsKG5hbWVfMSwgXCJpcyBtaXNzaW5nXCIsIDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFjdHguY29tcGxldGVGb3JrKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBmb3JrID0gY3R4LmZvcmsoKTtcbiAgICAgICAgICAgICAgICAgICAgdmFyIG9rID0gcHJvcENoZWNrZXJzW2ldKHYsIGZvcmspO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIW9rKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3JrLmZhaWwobmFtZV8xLCBudWxsLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoIWN0eC5jb21wbGV0ZUZvcmsoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGluZGV4VHlwZUNoZWNrZXIpIHtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBwcm9wIGluIHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBmb3JrID0gY3R4LmZvcmsoKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFpbmRleFR5cGVDaGVja2VyKHZhbHVlW3Byb3BdLCBmb3JrKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9yay5mYWlsKHByb3AsIG51bGwsIDEpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmICghY3R4LmNvbXBsZXRlRm9yaygpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChzdHJpY3QpIHtcbiAgICAgICAgICAgICAgICAvLyBJbiBzdHJpY3QgbW9kZSwgY2hlY2sgYWxzbyBmb3IgdW5rbm93biBlbnVtZXJhYmxlIHByb3BlcnRpZXMuXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgcHJvcCBpbiB2YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIWFsbG93ZWRQcm9wcy5oYXMocHJvcCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGN0eC5mb3JrKCkuZmFpbChwcm9wLCBcImlzIGV4dHJhbmVvdXNcIiwgMik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWN0eC5jb21wbGV0ZUZvcmsoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiAhY3R4LmZhaWxlZCgpO1xuICAgICAgICB9O1xuICAgIH07XG4gICAgcmV0dXJuIFRJZmFjZTtcbn0oVFR5cGUpKTtcbmV4cG9ydHMuVElmYWNlID0gVElmYWNlO1xuLyoqXG4gKiBEZWZpbmVzIGFuIG9wdGlvbmFsIHByb3BlcnR5IG9uIGFuIGludGVyZmFjZS5cbiAqL1xuZnVuY3Rpb24gb3B0KHR5cGVTcGVjKSB7IHJldHVybiBuZXcgVE9wdGlvbmFsKHBhcnNlU3BlYyh0eXBlU3BlYykpOyB9XG5leHBvcnRzLm9wdCA9IG9wdDtcbnZhciBUT3B0aW9uYWwgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgX19leHRlbmRzKFRPcHRpb25hbCwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBUT3B0aW9uYWwodHR5cGUpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMudHR5cGUgPSB0dHlwZTtcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICBUT3B0aW9uYWwucHJvdG90eXBlLmdldENoZWNrZXIgPSBmdW5jdGlvbiAoc3VpdGUsIHN0cmljdCkge1xuICAgICAgICB2YXIgaXRlbUNoZWNrZXIgPSB0aGlzLnR0eXBlLmdldENoZWNrZXIoc3VpdGUsIHN0cmljdCk7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAodmFsdWUsIGN0eCkge1xuICAgICAgICAgICAgcmV0dXJuIHZhbHVlID09PSB1bmRlZmluZWQgfHwgaXRlbUNoZWNrZXIodmFsdWUsIGN0eCk7XG4gICAgICAgIH07XG4gICAgfTtcbiAgICByZXR1cm4gVE9wdGlvbmFsO1xufShUVHlwZSkpO1xuZXhwb3J0cy5UT3B0aW9uYWwgPSBUT3B0aW9uYWw7XG4vKipcbiAqIERlZmluZXMgYSBwcm9wZXJ0eSBpbiBhbiBpbnRlcmZhY2UuXG4gKi9cbnZhciBUUHJvcCA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBUUHJvcChuYW1lLCB0dHlwZSwgaXNPcHQpIHtcbiAgICAgICAgdGhpcy5uYW1lID0gbmFtZTtcbiAgICAgICAgdGhpcy50dHlwZSA9IHR0eXBlO1xuICAgICAgICB0aGlzLmlzT3B0ID0gaXNPcHQ7XG4gICAgfVxuICAgIHJldHVybiBUUHJvcDtcbn0oKSk7XG5leHBvcnRzLlRQcm9wID0gVFByb3A7XG4vKipcbiAqIERlZmluZXMgYSBmdW5jdGlvbi4gVGhlIGZpcnN0IGFyZ3VtZW50IGRlY2xhcmVzIHRoZSBmdW5jdGlvbidzIHJldHVybiB0eXBlLCB0aGUgcmVzdCBkZWNsYXJlXG4gKiBpdHMgcGFyYW1ldGVycy5cbiAqL1xuZnVuY3Rpb24gZnVuYyhyZXN1bHRTcGVjKSB7XG4gICAgdmFyIHBhcmFtcyA9IFtdO1xuICAgIGZvciAodmFyIF9pID0gMTsgX2kgPCBhcmd1bWVudHMubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgIHBhcmFtc1tfaSAtIDFdID0gYXJndW1lbnRzW19pXTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBURnVuYyhuZXcgVFBhcmFtTGlzdChwYXJhbXMpLCBwYXJzZVNwZWMocmVzdWx0U3BlYykpO1xufVxuZXhwb3J0cy5mdW5jID0gZnVuYztcbnZhciBURnVuYyA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICBfX2V4dGVuZHMoVEZ1bmMsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gVEZ1bmMocGFyYW1MaXN0LCByZXN1bHQpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMucGFyYW1MaXN0ID0gcGFyYW1MaXN0O1xuICAgICAgICBfdGhpcy5yZXN1bHQgPSByZXN1bHQ7XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgVEZ1bmMucHJvdG90eXBlLmdldENoZWNrZXIgPSBmdW5jdGlvbiAoc3VpdGUsIHN0cmljdCkge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKHZhbHVlLCBjdHgpIHtcbiAgICAgICAgICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT09IFwiZnVuY3Rpb25cIiA/IHRydWUgOiBjdHguZmFpbChudWxsLCBcImlzIG5vdCBhIGZ1bmN0aW9uXCIsIDApO1xuICAgICAgICB9O1xuICAgIH07XG4gICAgcmV0dXJuIFRGdW5jO1xufShUVHlwZSkpO1xuZXhwb3J0cy5URnVuYyA9IFRGdW5jO1xuLyoqXG4gKiBEZWZpbmVzIGEgZnVuY3Rpb24gcGFyYW1ldGVyLlxuICovXG5mdW5jdGlvbiBwYXJhbShuYW1lLCB0eXBlU3BlYywgaXNPcHQpIHtcbiAgICByZXR1cm4gbmV3IFRQYXJhbShuYW1lLCBwYXJzZVNwZWModHlwZVNwZWMpLCBCb29sZWFuKGlzT3B0KSk7XG59XG5leHBvcnRzLnBhcmFtID0gcGFyYW07XG52YXIgVFBhcmFtID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIFRQYXJhbShuYW1lLCB0dHlwZSwgaXNPcHQpIHtcbiAgICAgICAgdGhpcy5uYW1lID0gbmFtZTtcbiAgICAgICAgdGhpcy50dHlwZSA9IHR0eXBlO1xuICAgICAgICB0aGlzLmlzT3B0ID0gaXNPcHQ7XG4gICAgfVxuICAgIHJldHVybiBUUGFyYW07XG59KCkpO1xuZXhwb3J0cy5UUGFyYW0gPSBUUGFyYW07XG4vKipcbiAqIERlZmluZXMgYSBmdW5jdGlvbiBwYXJhbWV0ZXIgbGlzdC5cbiAqL1xudmFyIFRQYXJhbUxpc3QgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgX19leHRlbmRzKFRQYXJhbUxpc3QsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gVFBhcmFtTGlzdChwYXJhbXMpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMucGFyYW1zID0gcGFyYW1zO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIFRQYXJhbUxpc3QucHJvdG90eXBlLmdldENoZWNrZXIgPSBmdW5jdGlvbiAoc3VpdGUsIHN0cmljdCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgaXRlbUNoZWNrZXJzID0gdGhpcy5wYXJhbXMubWFwKGZ1bmN0aW9uICh0KSB7IHJldHVybiB0LnR0eXBlLmdldENoZWNrZXIoc3VpdGUsIHN0cmljdCk7IH0pO1xuICAgICAgICB2YXIgdGVzdEN0eCA9IG5ldyB1dGlsXzEuTm9vcENvbnRleHQoKTtcbiAgICAgICAgdmFyIGlzUGFyYW1SZXF1aXJlZCA9IHRoaXMucGFyYW1zLm1hcChmdW5jdGlvbiAocGFyYW0sIGkpIHtcbiAgICAgICAgICAgIHJldHVybiAhcGFyYW0uaXNPcHQgJiYgIWl0ZW1DaGVja2Vyc1tpXSh1bmRlZmluZWQsIHRlc3RDdHgpO1xuICAgICAgICB9KTtcbiAgICAgICAgdmFyIGNoZWNrZXIgPSBmdW5jdGlvbiAodmFsdWUsIGN0eCkge1xuICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBjdHguZmFpbChudWxsLCBcImlzIG5vdCBhbiBhcnJheVwiLCAwKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaXRlbUNoZWNrZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgdmFyIHAgPSBfdGhpcy5wYXJhbXNbaV07XG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlW2ldID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzUGFyYW1SZXF1aXJlZFtpXSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGN0eC5mYWlsKHAubmFtZSwgXCJpcyBtaXNzaW5nXCIsIDEpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB2YXIgb2sgPSBpdGVtQ2hlY2tlcnNbaV0odmFsdWVbaV0sIGN0eCk7XG4gICAgICAgICAgICAgICAgICAgIGlmICghb2spIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjdHguZmFpbChwLm5hbWUsIG51bGwsIDEpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH07XG4gICAgICAgIGlmICghc3RyaWN0KSB7XG4gICAgICAgICAgICByZXR1cm4gY2hlY2tlcjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKHZhbHVlLCBjdHgpIHtcbiAgICAgICAgICAgIGlmICghY2hlY2tlcih2YWx1ZSwgY3R4KSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB2YWx1ZS5sZW5ndGggPD0gaXRlbUNoZWNrZXJzLmxlbmd0aCA/IHRydWUgOlxuICAgICAgICAgICAgICAgIGN0eC5mYWlsKGl0ZW1DaGVja2Vycy5sZW5ndGgsIFwiaXMgZXh0cmFuZW91c1wiLCAyKTtcbiAgICAgICAgfTtcbiAgICB9O1xuICAgIHJldHVybiBUUGFyYW1MaXN0O1xufShUVHlwZSkpO1xuZXhwb3J0cy5UUGFyYW1MaXN0ID0gVFBhcmFtTGlzdDtcbi8qKlxuICogU2luZ2xlIFRUeXBlIGltcGxlbWVudGF0aW9uIGZvciBhbGwgYmFzaWMgYnVpbHQtaW4gdHlwZXMuXG4gKi9cbnZhciBCYXNpY1R5cGUgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgX19leHRlbmRzKEJhc2ljVHlwZSwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBCYXNpY1R5cGUodmFsaWRhdG9yLCBtZXNzYWdlKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLnZhbGlkYXRvciA9IHZhbGlkYXRvcjtcbiAgICAgICAgX3RoaXMubWVzc2FnZSA9IG1lc3NhZ2U7XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgQmFzaWNUeXBlLnByb3RvdHlwZS5nZXRDaGVja2VyID0gZnVuY3Rpb24gKHN1aXRlLCBzdHJpY3QpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICh2YWx1ZSwgY3R4KSB7IHJldHVybiBfdGhpcy52YWxpZGF0b3IodmFsdWUpID8gdHJ1ZSA6IGN0eC5mYWlsKG51bGwsIF90aGlzLm1lc3NhZ2UsIDApOyB9O1xuICAgIH07XG4gICAgcmV0dXJuIEJhc2ljVHlwZTtcbn0oVFR5cGUpKTtcbmV4cG9ydHMuQmFzaWNUeXBlID0gQmFzaWNUeXBlO1xuLyoqXG4gKiBEZWZpbmVzIHRoZSBzdWl0ZSBvZiBiYXNpYyB0eXBlcy5cbiAqL1xuZXhwb3J0cy5iYXNpY1R5cGVzID0ge1xuICAgIGFueTogbmV3IEJhc2ljVHlwZShmdW5jdGlvbiAodikgeyByZXR1cm4gdHJ1ZTsgfSwgXCJpcyBpbnZhbGlkXCIpLFxuICAgIHVua25vd246IG5ldyBCYXNpY1R5cGUoZnVuY3Rpb24gKHYpIHsgcmV0dXJuIHRydWU7IH0sIFwiaXMgaW52YWxpZFwiKSxcbiAgICBudW1iZXI6IG5ldyBCYXNpY1R5cGUoZnVuY3Rpb24gKHYpIHsgcmV0dXJuICh0eXBlb2YgdiA9PT0gXCJudW1iZXJcIik7IH0sIFwiaXMgbm90IGEgbnVtYmVyXCIpLFxuICAgIG9iamVjdDogbmV3IEJhc2ljVHlwZShmdW5jdGlvbiAodikgeyByZXR1cm4gKHR5cGVvZiB2ID09PSBcIm9iamVjdFwiICYmIHYpOyB9LCBcImlzIG5vdCBhbiBvYmplY3RcIiksXG4gICAgYm9vbGVhbjogbmV3IEJhc2ljVHlwZShmdW5jdGlvbiAodikgeyByZXR1cm4gKHR5cGVvZiB2ID09PSBcImJvb2xlYW5cIik7IH0sIFwiaXMgbm90IGEgYm9vbGVhblwiKSxcbiAgICBzdHJpbmc6IG5ldyBCYXNpY1R5cGUoZnVuY3Rpb24gKHYpIHsgcmV0dXJuICh0eXBlb2YgdiA9PT0gXCJzdHJpbmdcIik7IH0sIFwiaXMgbm90IGEgc3RyaW5nXCIpLFxuICAgIHN5bWJvbDogbmV3IEJhc2ljVHlwZShmdW5jdGlvbiAodikgeyByZXR1cm4gKHR5cGVvZiB2ID09PSBcInN5bWJvbFwiKTsgfSwgXCJpcyBub3QgYSBzeW1ib2xcIiksXG4gICAgdm9pZDogbmV3IEJhc2ljVHlwZShmdW5jdGlvbiAodikgeyByZXR1cm4gKHYgPT0gbnVsbCk7IH0sIFwiaXMgbm90IHZvaWRcIiksXG4gICAgdW5kZWZpbmVkOiBuZXcgQmFzaWNUeXBlKGZ1bmN0aW9uICh2KSB7IHJldHVybiAodiA9PT0gdW5kZWZpbmVkKTsgfSwgXCJpcyBub3QgdW5kZWZpbmVkXCIpLFxuICAgIG51bGw6IG5ldyBCYXNpY1R5cGUoZnVuY3Rpb24gKHYpIHsgcmV0dXJuICh2ID09PSBudWxsKTsgfSwgXCJpcyBub3QgbnVsbFwiKSxcbiAgICBuZXZlcjogbmV3IEJhc2ljVHlwZShmdW5jdGlvbiAodikgeyByZXR1cm4gZmFsc2U7IH0sIFwiaXMgdW5leHBlY3RlZFwiKSxcbiAgICBEYXRlOiBuZXcgQmFzaWNUeXBlKGdldElzTmF0aXZlQ2hlY2tlcihcIltvYmplY3QgRGF0ZV1cIiksIFwiaXMgbm90IGEgRGF0ZVwiKSxcbiAgICBSZWdFeHA6IG5ldyBCYXNpY1R5cGUoZ2V0SXNOYXRpdmVDaGVja2VyKFwiW29iamVjdCBSZWdFeHBdXCIpLCBcImlzIG5vdCBhIFJlZ0V4cFwiKSxcbn07XG4vLyBUaGlzIGFwcHJvYWNoIGZvciBjaGVja2luZyBuYXRpdmUgb2JqZWN0IHR5cGVzIG1pcnJvcnMgdGhhdCBvZiBsb2Rhc2guIEl0cyBhZHZhbnRhZ2Ugb3ZlclxuLy8gYGlzaW5zdGFuY2VgIGlzIHRoYXQgaXQgY2FuIHN0aWxsIHJldHVybiB0cnVlIGZvciBuYXRpdmUgb2JqZWN0cyBjcmVhdGVkIGluIGRpZmZlcmVudCBKU1xuLy8gZXhlY3V0aW9uIGVudmlyb25tZW50cy5cbnZhciBuYXRpdmVUb1N0cmluZyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG5mdW5jdGlvbiBnZXRJc05hdGl2ZUNoZWNrZXIodGFnKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICh2KSB7IHJldHVybiB0eXBlb2YgdiA9PT0gXCJvYmplY3RcIiAmJiB2ICYmIG5hdGl2ZVRvU3RyaW5nLmNhbGwodikgPT09IHRhZzsgfTtcbn1cbmlmICh0eXBlb2YgQnVmZmVyICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgZXhwb3J0cy5iYXNpY1R5cGVzLkJ1ZmZlciA9IG5ldyBCYXNpY1R5cGUoZnVuY3Rpb24gKHYpIHsgcmV0dXJuIEJ1ZmZlci5pc0J1ZmZlcih2KTsgfSwgXCJpcyBub3QgYSBCdWZmZXJcIik7XG59XG52YXIgX2xvb3BfMSA9IGZ1bmN0aW9uIChhcnJheV8xKSB7XG4gICAgZXhwb3J0cy5iYXNpY1R5cGVzW2FycmF5XzEubmFtZV0gPSBuZXcgQmFzaWNUeXBlKGZ1bmN0aW9uICh2KSB7IHJldHVybiAodiBpbnN0YW5jZW9mIGFycmF5XzEpOyB9LCBcImlzIG5vdCBhIFwiICsgYXJyYXlfMS5uYW1lKTtcbn07XG4vLyBTdXBwb3J0IHR5cGVkIGFycmF5cyBvZiB2YXJpb3VzIGZsYXZvcnNcbmZvciAodmFyIF9pID0gMCwgX2EgPSBbSW50OEFycmF5LCBVaW50OEFycmF5LCBVaW50OENsYW1wZWRBcnJheSwgSW50MTZBcnJheSwgVWludDE2QXJyYXksXG4gICAgSW50MzJBcnJheSwgVWludDMyQXJyYXksIEZsb2F0MzJBcnJheSwgRmxvYXQ2NEFycmF5LCBBcnJheUJ1ZmZlcl07IF9pIDwgX2EubGVuZ3RoOyBfaSsrKSB7XG4gICAgdmFyIGFycmF5XzEgPSBfYVtfaV07XG4gICAgX2xvb3BfMShhcnJheV8xKTtcbn1cbmZ1bmN0aW9uIGdldFR5cGVOYW1lKHQpIHtcbiAgICBpZiAodCBpbnN0YW5jZW9mIFROYW1lIHx8IHQgaW5zdGFuY2VvZiBUTGl0ZXJhbCB8fCB0IGluc3RhbmNlb2YgVEFycmF5KSB7XG4gICAgICAgIHJldHVybiB0Lm5hbWU7XG4gICAgfVxufVxuIiwiXCJ1c2Ugc3RyaWN0XCI7XG52YXIgX19leHRlbmRzID0gKHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMpIHx8IChmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGV4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgICBleHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8XG4gICAgICAgICAgICAoeyBfX3Byb3RvX186IFtdIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikgeyBkLl9fcHJvdG9fXyA9IGI7IH0pIHx8XG4gICAgICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChiLmhhc093blByb3BlcnR5KHApKSBkW3BdID0gYltwXTsgfTtcbiAgICAgICAgcmV0dXJuIGV4dGVuZFN0YXRpY3MoZCwgYik7XG4gICAgfTtcbiAgICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgICAgZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgICAgICAgZnVuY3Rpb24gX18oKSB7IHRoaXMuY29uc3RydWN0b3IgPSBkOyB9XG4gICAgICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgICB9O1xufSkoKTtcbnZhciBfX3NwcmVhZEFycmF5cyA9ICh0aGlzICYmIHRoaXMuX19zcHJlYWRBcnJheXMpIHx8IGZ1bmN0aW9uICgpIHtcbiAgICBmb3IgKHZhciBzID0gMCwgaSA9IDAsIGlsID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IGlsOyBpKyspIHMgKz0gYXJndW1lbnRzW2ldLmxlbmd0aDtcbiAgICBmb3IgKHZhciByID0gQXJyYXkocyksIGsgPSAwLCBpID0gMDsgaSA8IGlsOyBpKyspXG4gICAgICAgIGZvciAodmFyIGEgPSBhcmd1bWVudHNbaV0sIGogPSAwLCBqbCA9IGEubGVuZ3RoOyBqIDwgamw7IGorKywgaysrKVxuICAgICAgICAgICAgcltrXSA9IGFbal07XG4gICAgcmV0dXJuIHI7XG59O1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5EZXRhaWxDb250ZXh0ID0gZXhwb3J0cy5Ob29wQ29udGV4dCA9IGV4cG9ydHMuVkVycm9yID0gdm9pZCAwO1xuLyoqXG4gKiBFcnJvciB0aHJvd24gYnkgdmFsaWRhdGlvbi4gQmVzaWRlcyBhbiBpbmZvcm1hdGl2ZSBtZXNzYWdlLCBpdCBpbmNsdWRlcyB0aGUgcGF0aCB0byB0aGVcbiAqIHByb3BlcnR5IHdoaWNoIHRyaWdnZXJlZCB0aGUgZmFpbHVyZS5cbiAqL1xudmFyIFZFcnJvciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICBfX2V4dGVuZHMoVkVycm9yLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFZFcnJvcihwYXRoLCBtZXNzYWdlKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIG1lc3NhZ2UpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLnBhdGggPSBwYXRoO1xuICAgICAgICAvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL01pY3Jvc29mdC9UeXBlU2NyaXB0L3dpa2kvQnJlYWtpbmctQ2hhbmdlcyNleHRlbmRpbmctYnVpbHQtaW5zLWxpa2UtZXJyb3ItYXJyYXktYW5kLW1hcC1tYXktbm8tbG9uZ2VyLXdvcmsgZm9yIGluZm8gYWJvdXQgdGhpcyB3b3JrYXJvdW5kLlxuICAgICAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YoX3RoaXMsIFZFcnJvci5wcm90b3R5cGUpO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIHJldHVybiBWRXJyb3I7XG59KEVycm9yKSk7XG5leHBvcnRzLlZFcnJvciA9IFZFcnJvcjtcbi8qKlxuICogRmFzdCBpbXBsZW1lbnRhdGlvbiBvZiBJQ29udGV4dCB1c2VkIGZvciBmaXJzdC1wYXNzIHZhbGlkYXRpb24uIElmIHRoYXQgZmFpbHMsIHdlIGNhbiB2YWxpZGF0ZVxuICogdXNpbmcgRGV0YWlsQ29udGV4dCB0byBjb2xsZWN0IGVycm9yIG1lc3NhZ2VzLiBUaGF0J3MgZmFzdGVyIGZvciB0aGUgY29tbW9uIGNhc2Ugd2hlbiBtZXNzYWdlc1xuICogbm9ybWFsbHkgcGFzcyB2YWxpZGF0aW9uLlxuICovXG52YXIgTm9vcENvbnRleHQgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gTm9vcENvbnRleHQoKSB7XG4gICAgICAgIHRoaXMuX2ZhaWxlZCA9IGZhbHNlO1xuICAgIH1cbiAgICBOb29wQ29udGV4dC5wcm90b3R5cGUuZmFpbCA9IGZ1bmN0aW9uIChyZWxQYXRoLCBtZXNzYWdlLCBzY29yZSkge1xuICAgICAgICB0aGlzLl9mYWlsZWQgPSB0cnVlO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfTtcbiAgICBOb29wQ29udGV4dC5wcm90b3R5cGUuZm9yayA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgICBOb29wQ29udGV4dC5wcm90b3R5cGUuY29tcGxldGVGb3JrID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gIXRoaXMuX2ZhaWxlZDtcbiAgICB9O1xuICAgIE5vb3BDb250ZXh0LnByb3RvdHlwZS5mYWlsZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9mYWlsZWQ7XG4gICAgfTtcbiAgICBOb29wQ29udGV4dC5wcm90b3R5cGUudW5pb25SZXNvbHZlciA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH07XG4gICAgTm9vcENvbnRleHQucHJvdG90eXBlLmNyZWF0ZUNvbnRleHQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuX2ZhaWxlZCA9IGZhbHNlO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICAgIE5vb3BDb250ZXh0LnByb3RvdHlwZS5yZXNvbHZlVW5pb24gPSBmdW5jdGlvbiAodXIpIHsgfTtcbiAgICByZXR1cm4gTm9vcENvbnRleHQ7XG59KCkpO1xuZXhwb3J0cy5Ob29wQ29udGV4dCA9IE5vb3BDb250ZXh0O1xuLyoqXG4gKiBDb21wbGV0ZSBpbXBsZW1lbnRhdGlvbiBvZiBJQ29udGV4dCB0aGF0IGNvbGxlY3RzIG1lYW5pbmdmdWxsIGVycm9ycy5cbiAqL1xudmFyIERldGFpbENvbnRleHQgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gRGV0YWlsQ29udGV4dCgpIHtcbiAgICAgICAgLy8gU3RhY2sgb2YgcHJvcGVydHkgbmFtZXMgYW5kIGFzc29jaWF0ZWQgbWVzc2FnZXMgZm9yIHJlcG9ydGluZyBoZWxwZnVsIGVycm9yIG1lc3NhZ2VzLlxuICAgICAgICB0aGlzLl9wcm9wTmFtZXMgPSBbXTtcbiAgICAgICAgdGhpcy5fbWVzc2FnZXMgPSBbXTtcbiAgICAgICAgLyoqIENvbnRleHRzIGNyZWF0ZWQgYnkgZm9yaygpIHdoaWNoIGhhdmUgY29tcGxldGVkIGFuZCBjb250YWluIGZhaWx1cmVzICovXG4gICAgICAgIHRoaXMuX2ZhaWxlZEZvcmtzID0gW107XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDb250YWlucyB0aGUgY29udGV4dCByZXR1cm5lZCBieSBmb3JrKCkgd2hpY2ggc2hvdWxkIGJlIGNoZWNrZWQgdW50aWxcbiAgICAgICAgICogY29tcGxldGVGb3JrKCkgaXMgY2FsbGVkLlxuICAgICAgICAgKiBXaWxsIGJlIHJldXNlZCBmb3IgdGhlIG5leHQgZm9yaygpIGlmIHRoZXJlIGFyZSBubyBmYWlsdXJlcy5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2N1cnJlbnRGb3JrID0gbnVsbDtcbiAgICAgICAgLy8gU2NvcmUgaXMgdXNlZCB0byBjaG9vc2UgdGhlIGJlc3QgdW5pb24gbWVtYmVyIHdob3NlIERldGFpbENvbnRleHQgdG8gdXNlIGZvciByZXBvcnRpbmcuXG4gICAgICAgIC8vIEhpZ2hlciBzY29yZSBtZWFucyBiZXR0ZXIgbWF0Y2ggKG9yIHJhdGhlciBsZXNzIHNldmVyZSBtaXNtYXRjaCkuXG4gICAgICAgIHRoaXMuX3Njb3JlID0gMDtcbiAgICB9XG4gICAgRGV0YWlsQ29udGV4dC5wcm90b3R5cGUuZmFpbCA9IGZ1bmN0aW9uIChyZWxQYXRoLCBtZXNzYWdlLCBzY29yZSkge1xuICAgICAgICB0aGlzLl9wcm9wTmFtZXMucHVzaChyZWxQYXRoKTtcbiAgICAgICAgdGhpcy5fbWVzc2FnZXMucHVzaChtZXNzYWdlKTtcbiAgICAgICAgdGhpcy5fc2NvcmUgKz0gc2NvcmU7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9O1xuICAgIERldGFpbENvbnRleHQucHJvdG90eXBlLnVuaW9uUmVzb2x2ZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBuZXcgRGV0YWlsVW5pb25SZXNvbHZlcigpO1xuICAgIH07XG4gICAgRGV0YWlsQ29udGV4dC5wcm90b3R5cGUucmVzb2x2ZVVuaW9uID0gZnVuY3Rpb24gKHVuaW9uUmVzb2x2ZXIpIHtcbiAgICAgICAgdmFyIF9hLCBfYiwgX2M7XG4gICAgICAgIHZhciB1ID0gdW5pb25SZXNvbHZlcjtcbiAgICAgICAgdmFyIGJlc3QgPSBudWxsO1xuICAgICAgICBmb3IgKHZhciBfaSA9IDAsIF9kID0gdS5jb250ZXh0czsgX2kgPCBfZC5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgICAgIHZhciBjdHggPSBfZFtfaV07XG4gICAgICAgICAgICBpZiAoIWJlc3QgfHwgY3R4Ll9zY29yZSA+PSBiZXN0Ll9zY29yZSkge1xuICAgICAgICAgICAgICAgIGJlc3QgPSBjdHg7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGJlc3QgJiYgYmVzdC5fc2NvcmUgPiAwKSB7XG4gICAgICAgICAgICAoX2EgPSB0aGlzLl9wcm9wTmFtZXMpLnB1c2guYXBwbHkoX2EsIGJlc3QuX3Byb3BOYW1lcyk7XG4gICAgICAgICAgICAoX2IgPSB0aGlzLl9tZXNzYWdlcykucHVzaC5hcHBseShfYiwgYmVzdC5fbWVzc2FnZXMpO1xuICAgICAgICAgICAgKF9jID0gdGhpcy5fZmFpbGVkRm9ya3MpLnB1c2guYXBwbHkoX2MsIGJlc3QuX2ZhaWxlZEZvcmtzKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgRGV0YWlsQ29udGV4dC5wcm90b3R5cGUuZ2V0RXJyb3IgPSBmdW5jdGlvbiAocGF0aCkge1xuICAgICAgICB2YXIgZnVsbE1lc3NhZ2UgPSBmbGF0dGVuKHRoaXMuZ2V0RXJyb3JEZXRhaWxzKHBhdGgpLm1hcChlcnJvckxpbmVzKSlcbiAgICAgICAgICAgIC5qb2luKFwiXFxuXCIpO1xuICAgICAgICByZXR1cm4gbmV3IFZFcnJvcihwYXRoLCBmdWxsTWVzc2FnZSk7XG4gICAgfTtcbiAgICBEZXRhaWxDb250ZXh0LnByb3RvdHlwZS5nZXRFcnJvckRldGFpbHMgPSBmdW5jdGlvbiAocGF0aCkge1xuICAgICAgICB2YXIgZGV0YWlsID0gbnVsbDtcbiAgICAgICAgdmFyIG5lc3RlZDtcbiAgICAgICAgdmFyIGRldGFpbHMgPSBbXTtcbiAgICAgICAgLy8gQXMgY2hlY2tlcnMgY2FsbCBmYWlsKCkgYW5kIHJldHVybiB0byB0aGVpciBwYXJlbnQgY2hlY2tlcnMsXG4gICAgICAgIC8vIHRoZSBkZWVwZXN0IGZhaWx1cmVzIGFyZSByZWNvcmRlZCBmaXJzdC5cbiAgICAgICAgLy8gR28gdGhyb3VnaCBmYWlsdXJlcyBpbiByZXZlcnNlIHRvIHN0YXJ0IGZyb20gdGhlIHJvb3QgdHlwZVxuICAgICAgICBmb3IgKHZhciBpID0gdGhpcy5fcHJvcE5hbWVzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgICB2YXIgcCA9IHRoaXMuX3Byb3BOYW1lc1tpXTtcbiAgICAgICAgICAgIHBhdGggKz0gKHR5cGVvZiBwID09PSBcIm51bWJlclwiKSA/IFwiW1wiICsgcCArIFwiXVwiIDogKHAgPyBcIi5cIiArIHAgOiBcIlwiKTtcbiAgICAgICAgICAgIHZhciBtZXNzYWdlID0gdGhpcy5fbWVzc2FnZXNbaV07XG4gICAgICAgICAgICBpZiAoIW1lc3NhZ2UpIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG5lc3RlZCA9IHsgcGF0aDogcGF0aCwgbWVzc2FnZTogbWVzc2FnZSB9O1xuICAgICAgICAgICAgaWYgKGRldGFpbCkge1xuICAgICAgICAgICAgICAgIGRldGFpbC5uZXN0ZWQgPSBbbmVzdGVkXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIFRoaXMgaXMgdGhlIHJvb3QgZmFpbHVyZSwgc28gaXQgd2lsbCBiZSByZXR1cm5lZFxuICAgICAgICAgICAgICAgIGRldGFpbHMucHVzaChuZXN0ZWQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gTW92ZSBpbnRvIHRoZSBkZWVwZXIgZXJyb3JcbiAgICAgICAgICAgIGRldGFpbCA9IG5lc3RlZDtcbiAgICAgICAgfVxuICAgICAgICB2YXIgZm9ya0Vycm9ycyA9IGZsYXR0ZW4odGhpcy5fZmFpbGVkRm9ya3MubWFwKGZ1bmN0aW9uIChmb3JrKSB7IHJldHVybiBmb3JrLmdldEVycm9yRGV0YWlscyhwYXRoKTsgfSkpO1xuICAgICAgICBpZiAoZGV0YWlsKSB7XG4gICAgICAgICAgICAvLyBkb24ndCBwdXQgYW4gZW1wdHkgYXJyYXkgaW4gZGV0YWlsLm5lc3RlZFxuICAgICAgICAgICAgaWYgKGZvcmtFcnJvcnMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgLy8gZGV0YWlsIGlzIHRoZSBkZWVwZXN0IG5lc3RlZCBlcnJvciwgc28gZGV0YWlsLm5lc3RlZCBpcyBudWxsIGF0IHRoaXMgcG9pbnRcbiAgICAgICAgICAgICAgICBkZXRhaWwubmVzdGVkID0gZm9ya0Vycm9ycztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIFRoZXJlIHdlcmUgbm8gJ3BsYWluJyBmYWlsdXJlcywgb25seSBmb3JrIGZhaWx1cmVzXG4gICAgICAgICAgICBkZXRhaWxzID0gZm9ya0Vycm9ycztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZGV0YWlscztcbiAgICB9O1xuICAgIERldGFpbENvbnRleHQucHJvdG90eXBlLmZvcmsgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLl9jdXJyZW50Rm9yayA9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLl9jdXJyZW50Rm9yayA9IG5ldyBEZXRhaWxDb250ZXh0KCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX2N1cnJlbnRGb3JrO1xuICAgIH07XG4gICAgRGV0YWlsQ29udGV4dC5wcm90b3R5cGUuY29tcGxldGVGb3JrID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgZm9yayA9IHRoaXMuX2N1cnJlbnRGb3JrO1xuICAgICAgICBpZiAoZm9yay5fZmFpbGVkKCkpIHtcbiAgICAgICAgICAgIHRoaXMuX2ZhaWxlZEZvcmtzLnB1c2goZm9yayk7XG4gICAgICAgICAgICB0aGlzLl9jdXJyZW50Rm9yayA9IG51bGw7XG4gICAgICAgICAgICAvLyBUbyBwcmVzZXJ2ZSBvbGQgYmVoYXZpb3VyLCB1c2UgdGhlIHNjb3JlIG9mIHRoZSBmaXJzdCBmYWlsdXJlXG4gICAgICAgICAgICAvLyBNaWdodCB3YW50IHRvIHJldmlzZSB0aGlzXG4gICAgICAgICAgICBpZiAodGhpcy5fZmFpbGVkRm9ya3MubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc2NvcmUgPSBmb3JrLl9zY29yZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fZmFpbGVkRm9ya3MubGVuZ3RoIDwgRGV0YWlsQ29udGV4dC5tYXhGb3JrcztcbiAgICB9O1xuICAgIC8vIGZhaWxlZCgpIGlzIHRoZSBwdWJsaWMgaW50ZXJmYWNlLFxuICAgIC8vIGl0IGdldHMgbW9ua2V5cGF0Y2hlZCB0byBlbnN1cmUgY29ycmVjdCB1c2FnZSBpbiBjaGVja2Vycy5cbiAgICAvLyBfZmFpbGVkKCkgbWF5IGJlIGNhbGxlZCBpbnRlcm5hbGx5XG4gICAgLy8gaW4gd2F5cyB3aGljaCB3b3VsZCBmYWlsIHRoZSBtb25rZXlwYXRjaGVkIGFzc2VydGlvbnMuXG4gICAgRGV0YWlsQ29udGV4dC5wcm90b3R5cGUuZmFpbGVkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZmFpbGVkKCk7XG4gICAgfTtcbiAgICBEZXRhaWxDb250ZXh0LnByb3RvdHlwZS5fZmFpbGVkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcHJvcE5hbWVzLmxlbmd0aCArIHRoaXMuX2ZhaWxlZEZvcmtzLmxlbmd0aCA+IDA7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBNYXhpbXVtIG51bWJlciBvZiBlcnJvcnMgcmVjb3JkZWQgYXQgb25lIGxldmVsIGZvciBhbiBvYmplY3QsXG4gICAgICogaS5lLiB0aGUgbWF4aW11bSBsZW5ndGggb2YgQ2hlY2tlci52YWxpZGF0ZSgpIG9yIElFcnJvckRldGFpbC5uZXN0ZWQuXG4gICAgICovXG4gICAgLy8gSWYgX2ZhaWxlZEZvcmtzIGhhcyB0aGlzIGxlbmd0aCB0aGVuIGNvbXBsZXRlRm9yaygpIHNob3VsZCByZXR1cm4gZmFsc2VcbiAgICAvLyBzbyB0aGF0IHRoZSBjaGVja2VyIHN0b3BzIG1ha2luZyBtb3JlIGZvcmtzLlxuICAgIERldGFpbENvbnRleHQubWF4Rm9ya3MgPSAzO1xuICAgIHJldHVybiBEZXRhaWxDb250ZXh0O1xufSgpKTtcbmV4cG9ydHMuRGV0YWlsQ29udGV4dCA9IERldGFpbENvbnRleHQ7XG52YXIgRGV0YWlsVW5pb25SZXNvbHZlciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBEZXRhaWxVbmlvblJlc29sdmVyKCkge1xuICAgICAgICB0aGlzLmNvbnRleHRzID0gW107XG4gICAgfVxuICAgIERldGFpbFVuaW9uUmVzb2x2ZXIucHJvdG90eXBlLmNyZWF0ZUNvbnRleHQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBjdHggPSBuZXcgRGV0YWlsQ29udGV4dCgpO1xuICAgICAgICB0aGlzLmNvbnRleHRzLnB1c2goY3R4KTtcbiAgICAgICAgcmV0dXJuIGN0eDtcbiAgICB9O1xuICAgIHJldHVybiBEZXRhaWxVbmlvblJlc29sdmVyO1xufSgpKTtcbi8qKlxuICogUmV0dXJucyBsaW5lcyBvZiBhIG1lc3NhZ2UgZGVzY3JpYmluZyBgZXJyb3JgLlxuICogVGhlIGxpbmVzIHNob3VsZCBiZSBuZXdsaW5lIHNlcGFyYXRlZCBpbiB0aGUgZmluYWwgbWVzc2FnZS5cbiAqIE9ubHkgcmV0dXJucyBtdWx0aXBsZSBsaW5lcyBpZiBgZXJyb3JgIG9yIGEgZGVzY2VuZGFudFxuICogaGFzIG11bHRpcGxlIGVycm9ycyBpbiBpdHMgYC5uZXN0ZWRgIGFycmF5LlxuICogU2ltcGxlIHBhdGhzIG9mIG5lc3RlZCBlcnJvcnMgYW55d2hlcmUgaW4gdGhlIHRyZWVcbiAqIGFyZSBjb2xsYXBzZWQgaW50byBhIHNpbmdsZSBsaW5lIHVudGlsIGEgYnJhbmNoIGlzIHJlYWNoZWQuXG4gKi9cbnZhciBlcnJvckxpbmVzID0gZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgdmFyIHJvb3RNZXNzYWdlID0gZXJyb3IucGF0aCArIFwiIFwiICsgZXJyb3IubWVzc2FnZTtcbiAgICB2YXIgbmVzdGVkRXJyb3JzID0gZXJyb3IubmVzdGVkIHx8IFtdO1xuICAgIHZhciBuZXN0ZWRMaW5lcyA9IGZsYXR0ZW4obmVzdGVkRXJyb3JzLm1hcChlcnJvckxpbmVzKSk7XG4gICAgaWYgKG5lc3RlZEVycm9ycy5sZW5ndGggPT0gMSkge1xuICAgICAgICAvLyBTaW5nbGUgbmVzdGVkIGVycm9ycyBhcmUgY29sbGFwc2VkIGludG8gdGhlIGZpcnN0IGxpbmUsXG4gICAgICAgIC8vIGJ1dCB0aGV5IG1heSBoYXZlIGJyYW5jaGVzIGRlZXBlciBkb3duIGxlYWRpbmcgdG8gbW9yZSBsaW5lc1xuICAgICAgICAvLyB3aGljaCBhcmUgYWxyZWFkeSBpbmRlbnRlZFxuICAgICAgICB2YXIgZmlyc3QgPSBuZXN0ZWRMaW5lc1swXSwgcmVzdCA9IG5lc3RlZExpbmVzLnNsaWNlKDEpO1xuICAgICAgICByZXR1cm4gX19zcHJlYWRBcnJheXMoW1xuICAgICAgICAgICAgcm9vdE1lc3NhZ2UgKyBcIjsgXCIgKyBmaXJzdFxuICAgICAgICBdLCByZXN0KTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIC8vIEluZGVudCBtZXNzYWdlcyBmcm9tIG5lc3RlZCBlcnJvcnNcbiAgICAgICAgLy8gb3IganVzdCByZXR1cm4gW3Jvb3RNZXNzYWdlXSBpZiB0aGVyZSBhcmUgbm8gbmVzdGVkIGVycm9yc1xuICAgICAgICByZXR1cm4gX19zcHJlYWRBcnJheXMoW1xuICAgICAgICAgICAgcm9vdE1lc3NhZ2VcbiAgICAgICAgXSwgbmVzdGVkTGluZXMubWFwKGZ1bmN0aW9uIChsaW5lKSB7IHJldHVybiBcIiAgICBcIiArIGxpbmU7IH0pKTtcbiAgICB9XG59O1xuLyoqIFNoYWxsb3cgZmxhdHRlbiBhIDJEIGFycmF5IGludG8gYSAxRCBhcnJheSAqL1xuZnVuY3Rpb24gZmxhdHRlbihhcnIpIHtcbiAgICB2YXIgX2E7XG4gICAgcmV0dXJuIChfYSA9IFtdKS5jb25jYXQuYXBwbHkoX2EsIGFycik7XG59XG4iXX0=