UNPKG

homebridge-homeconnect

Version:

A Homebridge plugin that connects Home Connect appliances to Apple HomeKit

6,862 lines 659 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-2025 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 {
  // 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-2025 Alexander Thoukydides

// Cards to select global or per-appliance configuration
class Cards {
  // Construct a new cards handler
  constructor(log) {
    this.log = log;
    // Current cards
    this.nonApplianceCards = [];
    this.applianceCards = [];
    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
    detail ?? (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-2025 Alexander Thoukydides

// Minimum time between duplicate toast notifications
const TOAST_DEDUP_TIME = 5 * _utils.MS;
// The current Home Connect client
class ClientClientID {
  // 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-2025 Alexander Thoukydides
// Client-side IPC implementation
class ClientIPC {
  // 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";

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-2025 Alexander Thoukydides

// A Homebridge HomeConnect custom UI client
class Client {
  // 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}],6:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.Config = void 0;
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-2025 Alexander Thoukydides

// The current plugin configuration
class Config {
  // Create a new configuration object
  constructor(log, ipc) {
    this.log = log;
    this.ipc = ipc;
    // The configuration being edited
    this.global = {};
    this.appliances = {};
    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) && key !== '_bridge');
    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;

},{"../../ti/config-types.js":11,"../../utils.js":12,"./utils-dom.js":9}],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-2025 Alexander Thoukydides

// A configuration form handler
class 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 {
  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 {
  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 {
  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 {
  // 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-2025 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 {
  // 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 {
  // 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-2025 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":13}],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 _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
/**
 * 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":61}],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-08-09T09:57:35.297Z

// 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":61}],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-2025 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":13}],13:[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":59,"util/":16}],14:[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
  }
}

},{}],15:[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';
}
},{}],16:[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":15,"_process":60,"inherits":14}],17:[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('')
}

},{}],18:[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":17,"buffer":18,"ieee754":46}],19:[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":20,"./functionCall":21,"./reflectApply":23,"function-bind":36}],20:[function(require,module,exports){
'use strict';

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

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

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

},{}],22:[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 {(args: [Function, thisArg?: unknown, ...args: unknown[]]) => Function} TODO FIXME, find a way to use 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":19,"./functionCall":21,"es-errors/type":32,"function-bind":36}],23:[function(require,module,exports){
'use strict';

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

},{}],24:[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 no-extra-parens: 0 */

  var intrinsic = /** @type {(this: unknown, ...args: unknown[]) => unknown} */GetIntrinsic(name, !!allowMissing);
  if (typeof intrinsic === 'function' && $indexOf(name, '.prototype.') > -1) {
    return callBindBasic(/** @type {const} */[intrinsic]);
  }
  return intrinsic;
};

},{"call-bind-apply-helpers":22,"get-intrinsic":37}],25:[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":22,"gopd":42}],26:[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;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

},{}],35:[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;
};

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

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

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

},{"./implementation":35}],37:[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,
	'%Float16Array%': typeof Float16Array === 'undefined' ? undefined : Float16Array,
	'%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":20,"call-bind-apply-helpers/functionCall":21,"es-define-property":26,"es-errors":28,"es-errors/eval":27,"es-errors/range":29,"es-errors/ref":30,"es-errors/syntax":31,"es-errors/type":32,"es-errors/uri":33,"es-object-atoms":34,"function-bind":36,"get-proto":40,"get-proto/Object.getPrototypeOf":38,"get-proto/Reflect.getPrototypeOf":39,"gopd":42,"has-symbols":43,"hasown":45,"math-intrinsics/abs":47,"math-intrinsics/floor":48,"math-intrinsics/max":50,"math-intrinsics/min":51,"math-intrinsics/pow":52,"math-intrinsics/round":53,"math-intrinsics/sign":54}],38:[function(require,module,exports){
'use strict';

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

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

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

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

},{}],40:[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":38,"./Reflect.getPrototypeOf":39,"dunder-proto/get":25}],41:[function(require,module,exports){
'use strict';

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

},{}],42:[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":41}],43:[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":44}],44:[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;
};

},{}],45:[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":36}],46:[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
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

},{}],54:[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":49}],55:[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":57}],56:[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":55,"./isArguments":57}],57:[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;
};

},{}],58:[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":24,"es-object-atoms":34,"has-symbols/shams":44,"object-keys":56}],59:[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":58}],60:[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; };

},{}],61:[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":62,"./util":63}],62:[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":63,"buffer":18}],63:[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,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJkaXN0L2hvbWVicmlkZ2UtdWkvcHVibGljL2FwaS1zdGF0dXMuanMiLCJkaXN0L2hvbWVicmlkZ2UtdWkvcHVibGljL2NhcmRzLmpzIiwiZGlzdC9ob21lYnJpZGdlLXVpL3B1YmxpYy9jbGllbnQtY2xpZW50aWQuanMiLCJkaXN0L2hvbWVicmlkZ2UtdWkvcHVibGljL2NsaWVudC1pcGMuanMiLCJkaXN0L2hvbWVicmlkZ2UtdWkvcHVibGljL2NsaWVudC5qcyIsImRpc3QvaG9tZWJyaWRnZS11aS9wdWJsaWMvY29uZmlnLmpzIiwiZGlzdC9ob21lYnJpZGdlLXVpL3B1YmxpYy9mb3Jtcy5qcyIsImRpc3QvaG9tZWJyaWRnZS11aS9wdWJsaWMvbG9nZ2VyLmpzIiwiZGlzdC9ob21lYnJpZGdlLXVpL3B1YmxpYy91dGlscy1kb20uanMiLCJkaXN0L3RpL2NvbmZpZy10eXBlcy10aS5qcyIsImRpc3QvdGkvY29uZmlnLXR5cGVzLmpzIiwiZGlzdC91dGlscy5qcyIsIm5vZGVfbW9kdWxlcy9hc3NlcnQvYXNzZXJ0LmpzIiwibm9kZV9tb2R1bGVzL2Fzc2VydC9ub2RlX21vZHVsZXMvaW5oZXJpdHMvaW5oZXJpdHNfYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9hc3NlcnQvbm9kZV9tb2R1bGVzL3V0aWwvc3VwcG9ydC9pc0J1ZmZlckJyb3dzZXIuanMiLCJub2RlX21vZHVsZXMvYXNzZXJ0L25vZGVfbW9kdWxlcy91dGlsL3V0aWwuanMiLCJub2RlX21vZHVsZXMvYmFzZTY0LWpzL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2J1ZmZlci9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9jYWxsLWJpbmQtYXBwbHktaGVscGVycy9hY3R1YWxBcHBseS5qcyIsIm5vZGVfbW9kdWxlcy9jYWxsLWJpbmQtYXBwbHktaGVscGVycy9mdW5jdGlvbkFwcGx5LmpzIiwibm9kZV9tb2R1bGVzL2NhbGwtYmluZC1hcHBseS1oZWxwZXJzL2Z1bmN0aW9uQ2FsbC5qcyIsIm5vZGVfbW9kdWxlcy9jYWxsLWJpbmQtYXBwbHktaGVscGVycy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9jYWxsLWJpbmQtYXBwbHktaGVscGVycy9yZWZsZWN0QXBwbHkuanMiLCJub2RlX21vZHVsZXMvY2FsbC1ib3VuZC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9kdW5kZXItcHJvdG8vZ2V0LmpzIiwibm9kZV9tb2R1bGVzL2VzLWRlZmluZS1wcm9wZXJ0eS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9lcy1lcnJvcnMvZXZhbC5qcyIsIm5vZGVfbW9kdWxlcy9lcy1lcnJvcnMvaW5kZXguanMiLCJub2RlX21vZHVsZXMvZXMtZXJyb3JzL3JhbmdlLmpzIiwibm9kZV9tb2R1bGVzL2VzLWVycm9ycy9yZWYuanMiLCJub2RlX21vZHVsZXMvZXMtZXJyb3JzL3N5bnRheC5qcyIsIm5vZGVfbW9kdWxlcy9lcy1lcnJvcnMvdHlwZS5qcyIsIm5vZGVfbW9kdWxlcy9lcy1lcnJvcnMvdXJpLmpzIiwibm9kZV9tb2R1bGVzL2VzLW9iamVjdC1hdG9tcy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9mdW5jdGlvbi1iaW5kL2ltcGxlbWVudGF0aW9uLmpzIiwibm9kZV9tb2R1bGVzL2Z1bmN0aW9uLWJpbmQvaW5kZXguanMiLCJub2RlX21vZHVsZXMvZ2V0LWludHJpbnNpYy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9nZXQtcHJvdG8vT2JqZWN0LmdldFByb3RvdHlwZU9mLmpzIiwibm9kZV9tb2R1bGVzL2dldC1wcm90by9SZWZsZWN0LmdldFByb3RvdHlwZU9mLmpzIiwibm9kZV9tb2R1bGVzL2dldC1wcm90by9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9nb3BkL2dPUEQuanMiLCJub2RlX21vZHVsZXMvZ29wZC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9oYXMtc3ltYm9scy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9oYXMtc3ltYm9scy9zaGFtcy5qcyIsIm5vZGVfbW9kdWxlcy9oYXNvd24vaW5kZXguanMiLCJub2RlX21vZHVsZXMvaWVlZTc1NC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9tYXRoLWludHJpbnNpY3MvYWJzLmpzIiwibm9kZV9tb2R1bGVzL21hdGgtaW50cmluc2ljcy9mbG9vci5qcyIsIm5vZGVfbW9kdWxlcy9tYXRoLWludHJpbnNpY3MvaXNOYU4uanMiLCJub2RlX21vZHVsZXMvbWF0aC1pbnRyaW5zaWNzL21heC5qcyIsIm5vZGVfbW9kdWxlcy9tYXRoLWludHJpbnNpY3MvbWluLmpzIiwibm9kZV9tb2R1bGVzL21hdGgtaW50cmluc2ljcy9wb3cuanMiLCJub2RlX21vZHVsZXMvbWF0aC1pbnRyaW5zaWNzL3JvdW5kLmpzIiwibm9kZV9tb2R1bGVzL21hdGgtaW50cmluc2ljcy9zaWduLmpzIiwibm9kZV9tb2R1bGVzL29iamVjdC1rZXlzL2ltcGxlbWVudGF0aW9uLmpzIiwibm9kZV9tb2R1bGVzL29iamVjdC1rZXlzL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL29iamVjdC1rZXlzL2lzQXJndW1lbnRzLmpzIiwibm9kZV9tb2R1bGVzL29iamVjdC5hc3NpZ24vaW1wbGVtZW50YXRpb24uanMiLCJub2RlX21vZHVsZXMvb2JqZWN0LmFzc2lnbi9wb2x5ZmlsbC5qcyIsIm5vZGVfbW9kdWxlcy9wcm9jZXNzL2Jyb3dzZXIuanMiLCJub2RlX21vZHVsZXMvdHMtaW50ZXJmYWNlLWNoZWNrZXIvZGlzdC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy90cy1pbnRlcmZhY2UtY2hlY2tlci9kaXN0L3R5cGVzLmpzIiwibm9kZV9tb2R1bGVzL3RzLWludGVyZmFjZS1jaGVja2VyL2Rpc3QvdXRpbC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2TEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0tBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25FQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDektBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQzFmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQzFrQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ3RKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDanZEQSxZQUFZOztBQUVaLElBQUksSUFBSSxHQUFHLE9BQU8sQ0FBQyxlQUFlLENBQUM7QUFFbkMsSUFBSSxNQUFNLEdBQUcsT0FBTyxDQUFDLGlCQUFpQixDQUFDO0FBQ3ZDLElBQUksS0FBSyxHQUFHLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQztBQUNyQyxJQUFJLGFBQWEsR0FBRyxPQUFPLENBQUMsZ0JBQWdCLENBQUM7O0FBRTdDO0FBQ0EsTUFBTSxDQUFDLE9BQU8sR0FBRyxhQUFhLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDOzs7QUNUMUQsWUFBWTs7QUFFWjtBQUNBLE1BQU0sQ0FBQyxPQUFPLEdBQUcsUUFBUSxDQUFDLFNBQVMsQ0FBQyxLQUFLOzs7QUNIekMsWUFBWTs7QUFFWjtBQUNBLE1BQU0sQ0FBQyxPQUFPLEdBQUcsUUFBUSxDQUFDLFNBQVMsQ0FBQyxJQUFJOzs7QUNIeEMsWUFBWTs7QUFFWixJQUFJLElBQUksR0FBRyxPQUFPLENBQUMsZUFBZSxDQUFDO0FBQ25DLElBQUksVUFBVSxHQUFHLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQztBQUUxQyxJQUFJLEtBQUssR0FBRyxPQUFPLENBQUMsZ0JBQWdCLENBQUM7QUFDckMsSUFBSSxZQUFZLEdBQUcsT0FBTyxDQUFDLGVBQWUsQ0FBQzs7QUFFM0M7QUFDQSxNQUFNLENBQUMsT0FBTyxHQUFHLFNBQVMsYUFBYSxDQUFDLElBQUksRUFBRTtFQUM3QyxJQUFJLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLE9BQU8sSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLLFVBQVUsRUFBRTtJQUNyRCxNQUFNLElBQUksVUFBVSxDQUFDLHdCQUF3QixDQUFDO0VBQy9DO0VBQ0EsT0FBTyxZQUFZLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUM7QUFDdkMsQ0FBQzs7O0FDZEQsWUFBWTs7QUFFWjtBQUNBLE1BQU0sQ0FBQyxPQUFPLEdBQUcsT0FBTyxPQUFPLEtBQUssV0FBVyxJQUFJLE9BQU8sSUFBSSxPQUFPLENBQUMsS0FBSzs7O0FDSDNFLFlBQVk7O0FBRVosSUFBSSxZQUFZLEdBQUcsT0FBTyxDQUFDLGVBQWUsQ0FBQztBQUUzQyxJQUFJLGFBQWEsR0FBRyxPQUFPLENBQUMseUJBQXlCLENBQUM7O0FBRXREO0FBQ0EsSUFBSSxRQUFRLEdBQUcsYUFBYSxDQUFDLENBQUMsWUFBWSxDQUFDLDRCQUE0QixDQUFDLENBQUMsQ0FBQzs7QUFFMUU7QUFDQSxNQUFNLENBQUMsT0FBTyxHQUFHLFNBQVMsa0JBQWtCLENBQUMsSUFBSSxFQUFFLFlBQVksRUFBRTtFQUNoRTs7RUFFQSxJQUFJLFNBQVMsR0FBRyw2REFBK0QsWUFBWSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsWUFBWSxDQUFFO0VBQ2xILElBQUksT0FBTyxTQUFTLEtBQUssVUFBVSxJQUFJLFFBQVEsQ0FBQyxJQUFJLEVBQUUsYUFBYSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUU7SUFDMUUsT0FBTyxhQUFhLENBQUMsb0JBQXNCLENBQUMsU0FBUyxDQUFFLENBQUM7RUFDekQ7RUFDQSxPQUFPLFNBQVM7QUFDakIsQ0FBQzs7O0FDbEJELFlBQVk7O0FBRVosSUFBSSxRQUFRLEdBQUcsT0FBTyxDQUFDLHlCQUF5QixDQUFDO0FBQ2pELElBQUksSUFBSSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUM7QUFFMUIsSUFBSSxnQkFBZ0I7QUFDcEIsSUFBSTtFQUNIO0VBQ0EsZ0JBQWdCLEdBQUcscURBQXVELEVBQUUsQ0FBRSxTQUFTLEtBQUssS0FBSyxDQUFDLFNBQVM7QUFDNUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxFQUFFO0VBQ1gsSUFBSSxDQUFDLENBQUMsSUFBSSxPQUFPLENBQUMsS0FBSyxRQUFRLElBQUksRUFBRSxNQUFNLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksS0FBSyxrQkFBa0IsRUFBRTtJQUNuRixNQUFNLENBQUM7RUFDUjtBQUNEOztBQUVBO0FBQ0EsSUFBSSxJQUFJLEdBQUcsQ0FBQyxDQUFDLGdCQUFnQixJQUFJLElBQUksSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsRUFBRSw0Q0FBOEMsV0FBWSxDQUFDO0FBRTNILElBQUksT0FBTyxHQUFHLE1BQU07QUFDcEIsSUFBSSxlQUFlLEdBQUcsT0FBTyxDQUFDLGNBQWM7O0FBRTVDO0FBQ0EsTUFBTSxDQUFDLE9BQU8sR0FBRyxJQUFJLElBQUksT0FBTyxJQUFJLENBQUMsR0FBRyxLQUFLLFVBQVUsR0FDcEQsUUFBUSxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQ3BCLE9BQU8sZUFBZSxLQUFLLFVBQVUsR0FDcEMsOEJBQStCLFNBQVMsU0FBUyxDQUFDLEtBQUssRUFBRTtFQUMxRDtFQUNBLE9BQU8sZUFBZSxDQUFDLEtBQUssSUFBSSxJQUFJLEdBQUcsS0FBSyxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUMvRCxDQUFDLEdBQ0MsS0FBSzs7O0FDN0JULFlBQVk7O0FBRVo7QUFDQSxJQUFJLGVBQWUsR0FBRyxNQUFNLENBQUMsY0FBYyxJQUFJLEtBQUs7QUFDcEQsSUFBSSxlQUFlLEVBQUU7RUFDcEIsSUFBSTtJQUNILGVBQWUsQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLEVBQUU7TUFBRSxLQUFLLEVBQUU7SUFBRSxDQUFDLENBQUM7RUFDdkMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxFQUFFO0lBQ1g7SUFDQSxlQUFlLEdBQUcsS0FBSztFQUN4QjtBQUNEO0FBRUEsTUFBTSxDQUFDLE9BQU8sR0FBRyxlQUFlOzs7QUNiaEMsWUFBWTs7QUFFWjtBQUNBLE1BQU0sQ0FBQyxPQUFPLEdBQUcsU0FBUzs7O0FDSDFCLFlBQVk7O0FBRVo7QUFDQSxNQUFNLENBQUMsT0FBTyxHQUFHLEtBQUs7OztBQ0h0QixZQUFZOztBQUVaO0FBQ0EsTUFBTSxDQUFDLE9BQU8sR0FBRyxVQUFVOzs7QUNIM0IsWUFBWTs7QUFFWjtBQUNBLE1BQU0sQ0FBQyxPQUFPLEdBQUcsY0FBYzs7O0FDSC9CLFlBQVk7O0FBRVo7QUFDQSxNQUFNLENBQUMsT0FBTyxHQUFHLFdBQVc7OztBQ0g1QixZQUFZOztBQUVaO0FBQ0EsTUFBTSxDQUFDLE9BQU8sR0FBRyxTQUFTOzs7QUNIMUIsWUFBWTs7QUFFWjtBQUNBLE1BQU0sQ0FBQyxPQUFPLEdBQUcsUUFBUTs7O0FDSHpCLFlBQVk7O0FBRVo7QUFDQSxNQUFNLENBQUMsT0FBTyxHQUFHLE1BQU07OztBQ0h2QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFYQSxZQUFZOztBQUVaLElBQUksT0FBTyxHQUFHLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQzs7QUFFeEM7QUFDQSxNQUFNLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQyxjQUFjLElBQUksSUFBSTs7O0FDTC9DLFlBQVk7O0FBRVo7QUFDQSxNQUFNLENBQUMsT0FBTyxHQUFJLE9BQU8sT0FBTyxLQUFLLFdBQVcsSUFBSSxPQUFPLENBQUMsY0FBYyxJQUFLLElBQUk7OztBQ0huRixZQUFZOztBQUVaLElBQUksZUFBZSxHQUFHLE9BQU8sQ0FBQywwQkFBMEIsQ0FBQztBQUN6RCxJQUFJLGdCQUFnQixHQUFHLE9BQU8sQ0FBQyx5QkFBeUIsQ0FBQztBQUV6RCxJQUFJLGNBQWMsR0FBRyxPQUFPLENBQUMsa0JBQWtCLENBQUM7O0FBRWhEO0FBQ0EsTUFBTSxDQUFDLE9BQU8sR0FBRyxlQUFlLEdBQzdCLFNBQVMsUUFBUSxDQUFDLENBQUMsRUFBRTtFQUN0QjtFQUNBLE9BQU8sZUFBZSxDQUFDLENBQUMsQ0FBQztBQUMxQixDQUFDLEdBQ0MsZ0JBQWdCLEdBQ2YsU0FBUyxRQUFRLENBQUMsQ0FBQyxFQUFFO0VBQ3RCLElBQUksQ0FBQyxDQUFDLElBQUssT0FBTyxDQUFDLEtBQUssUUFBUSxJQUFJLE9BQU8sQ0FBQyxLQUFLLFVBQVcsRUFBRTtJQUM3RCxNQUFNLElBQUksU0FBUyxDQUFDLHlCQUF5QixDQUFDO0VBQy9DO0VBQ0E7RUFDQSxPQUFPLGdCQUFnQixDQUFDLENBQUMsQ0FBQztBQUMzQixDQUFDLEdBQ0MsY0FBYyxHQUNiLFNBQVMsUUFBUSxDQUFDLENBQUMsRUFBRTtFQUN0QjtFQUNBLE9BQU8sY0FBYyxDQUFDLENBQUMsQ0FBQztBQUN6QixDQUFDLEdBQ0MsSUFBSTs7O0FDMUJULFlBQVk7O0FBRVo7QUFDQSxNQUFNLENBQUMsT0FBTyxHQUFHLE1BQU0sQ0FBQyx3QkFBd0I7OztBQ0hoRCxZQUFZOztBQUVaO0FBQ0EsSUFBSSxLQUFLLEdBQUcsT0FBTyxDQUFDLFFBQVEsQ0FBQztBQUU3QixJQUFJLEtBQUssRUFBRTtFQUNWLElBQUk7SUFDSCxLQUFLLENBQUMsRUFBRSxFQUFFLFFBQVEsQ0FBQztFQUNwQixDQUFDLENBQUMsT0FBTyxDQUFDLEVBQUU7SUFDWDtJQUNBLEtBQUssR0FBRyxJQUFJO0VBQ2I7QUFDRDtBQUVBLE1BQU0sQ0FBQyxPQUFPLEdBQUcsS0FBSzs7O0FDZHRCLFlBQVk7O0FBRVosSUFBSSxVQUFVLEdBQUcsT0FBTyxNQUFNLEtBQUssV0FBVyxJQUFJLE1BQU07QUFDeEQsSUFBSSxhQUFhLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQzs7QUFFdEM7QUFDQSxNQUFNLENBQUMsT0FBTyxHQUFHLFNBQVMsZ0JBQWdCLENBQUEsRUFBRztFQUM1QyxJQUFJLE9BQU8sVUFBVSxLQUFLLFVBQVUsRUFBRTtJQUFFLE9BQU8sS0FBSztFQUFFO0VBQ3RELElBQUksT0FBTyxNQUFNLEtBQUssVUFBVSxFQUFFO0lBQUUsT0FBTyxLQUFLO0VBQUU7RUFDbEQsSUFBSSxPQUFPLFVBQVUsQ0FBQyxLQUFLLENBQUMsS0FBSyxRQUFRLEVBQUU7SUFBRSxPQUFPLEtBQUs7RUFBRTtFQUMzRCxJQUFJLE9BQU8sTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLFFBQVEsRUFBRTtJQUFFLE9BQU8sS0FBSztFQUFFO0VBRXZELE9BQU8sYUFBYSxDQUFDLENBQUM7QUFDdkIsQ0FBQzs7O0FDYkQsWUFBWTs7QUFFWjtBQUNBO0FBQ0EsTUFBTSxDQUFDLE9BQU8sR0FBRyxTQUFTLFVBQVUsQ0FBQSxFQUFHO0VBQ3RDLElBQUksT0FBTyxNQUFNLEtBQUssVUFBVSxJQUFJLE9BQU8sTUFBTSxDQUFDLHFCQUFxQixLQUFLLFVBQVUsRUFBRTtJQUFFLE9BQU8sS0FBSztFQUFFO0VBQ3hHLElBQUksT0FBTyxNQUFNLENBQUMsUUFBUSxLQUFLLFFBQVEsRUFBRTtJQUFFLE9BQU8sSUFBSTtFQUFFOztFQUV4RDtFQUNBLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQztFQUNaLElBQUksR0FBRyxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUM7RUFDeEIsSUFBSSxNQUFNLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQztFQUN4QixJQUFJLE9BQU8sR0FBRyxLQUFLLFFBQVEsRUFBRTtJQUFFLE9BQU8sS0FBSztFQUFFO0VBRTdDLElBQUksTUFBTSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLGlCQUFpQixFQUFFO0lBQUUsT0FBTyxLQUFLO0VBQUU7RUFDL0UsSUFBSSxNQUFNLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssaUJBQWlCLEVBQUU7SUFBRSxPQUFPLEtBQUs7RUFBRTs7RUFFbEY7RUFDQTtFQUNBO0VBQ0E7O0VBRUE7RUFDQTs7RUFFQSxJQUFJLE1BQU0sR0FBRyxFQUFFO0VBQ2YsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLE1BQU07RUFDakIsS0FBSyxJQUFJLENBQUMsSUFBSSxHQUFHLEVBQUU7SUFBRSxPQUFPLEtBQUs7RUFBRSxDQUFDLENBQUM7RUFDckMsSUFBSSxPQUFPLE1BQU0sQ0FBQyxJQUFJLEtBQUssVUFBVSxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtJQUFFLE9BQU8sS0FBSztFQUFFO0VBRXhGLElBQUksT0FBTyxNQUFNLENBQUMsbUJBQW1CLEtBQUssVUFBVSxJQUFJLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO0lBQUUsT0FBTyxLQUFLO0VBQUU7RUFFdEgsSUFBSSxJQUFJLEdBQUcsTUFBTSxDQUFDLHFCQUFxQixDQUFDLEdBQUcsQ0FBQztFQUM1QyxJQUFJLElBQUksQ0FBQyxNQUFNLEtBQUssQ0FBQyxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsS0FBSyxHQUFHLEVBQUU7SUFBRSxPQUFPLEtBQUs7RUFBRTtFQUUxRCxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxFQUFFO0lBQUUsT0FBTyxLQUFLO0VBQUU7RUFFM0UsSUFBSSxPQUFPLE1BQU0sQ0FBQyx3QkFBd0IsS0FBSyxVQUFVLEVBQUU7SUFDMUQ7SUFDQSxJQUFJLFVBQVUsR0FBRyxpQ0FBbUMsTUFBTSxDQUFDLHdCQUF3QixDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUU7SUFDOUYsSUFBSSxVQUFVLENBQUMsS0FBSyxLQUFLLE1BQU0sSUFBSSxVQUFVLENBQUMsVUFBVSxLQUFLLElBQUksRUFBRTtNQUFFLE9BQU8sS0FBSztJQUFFO0VBQ3BGO0VBRUEsT0FBTyxJQUFJO0FBQ1osQ0FBQzs7O0FDNUNELFlBQVk7O0FBRVosSUFBSSxJQUFJLEdBQUcsUUFBUSxDQUFDLFNBQVMsQ0FBQyxJQUFJO0FBQ2xDLElBQUksT0FBTyxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUMsY0FBYztBQUM3QyxJQUFJLElBQUksR0FBRyxPQUFPLENBQUMsZUFBZSxDQUFDOztBQUVuQztBQUNBLE1BQU0sQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDOzs7QUNQekM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyRkEsWUFBWTs7QUFFWjtBQUNBLE1BQU0sQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLEdBQUc7OztBQ0h6QixZQUFZOztBQUVaO0FBQ0EsTUFBTSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsS0FBSzs7O0FDSDNCLFlBQVk7O0FBRVo7QUFDQSxNQUFNLENBQUMsT0FBTyxHQUFHLE1BQU0sQ0FBQyxLQUFLLElBQUksU0FBUyxLQUFLLENBQUMsQ0FBQyxFQUFFO0VBQ2xELE9BQU8sQ0FBQyxLQUFLLENBQUM7QUFDZixDQUFDOzs7QUNMRCxZQUFZOztBQUVaO0FBQ0EsTUFBTSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsR0FBRzs7O0FDSHpCLFlBQVk7O0FBRVo7QUFDQSxNQUFNLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxHQUFHOzs7QUNIekIsWUFBWTs7QUFFWjtBQUNBLE1BQU0sQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLEdBQUc7OztBQ0h6QixZQUFZOztBQUVaO0FBQ0EsTUFBTSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsS0FBSzs7O0FDSDNCLFlBQVk7O0FBRVosSUFBSSxNQUFNLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQzs7QUFFL0I7QUFDQSxNQUFNLENBQUMsT0FBTyxHQUFHLFNBQVMsSUFBSSxDQUFDLE1BQU0sRUFBRTtFQUN0QyxJQUFJLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxNQUFNLEtBQUssQ0FBQyxFQUFFO0lBQ25DLE9BQU8sTUFBTTtFQUNkO0VBQ0EsT0FBTyxNQUFNLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUM1QixDQUFDOzs7QUNWRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUNsT0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQzlwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbigpe2Z1bmN0aW9uIHIoZSxuLHQpe2Z1bmN0aW9uIG8oaSxmKXtpZighbltpXSl7aWYoIWVbaV0pe3ZhciBjPVwiZnVuY3Rpb25cIj09dHlwZW9mIHJlcXVpcmUmJnJlcXVpcmU7aWYoIWYmJmMpcmV0dXJuIGMoaSwhMCk7aWYodSlyZXR1cm4gdShpLCEwKTt2YXIgYT1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK2krXCInXCIpO3Rocm93IGEuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixhfXZhciBwPW5baV09e2V4cG9ydHM6e319O2VbaV1bMF0uY2FsbChwLmV4cG9ydHMsZnVuY3Rpb24ocil7dmFyIG49ZVtpXVsxXVtyXTtyZXR1cm4gbyhufHxyKX0scCxwLmV4cG9ydHMscixlLG4sdCl9cmV0dXJuIG5baV0uZXhwb3J0c31mb3IodmFyIHU9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZSxpPTA7aTx0Lmxlbmd0aDtpKyspbyh0W2ldKTtyZXR1cm4gb31yZXR1cm4gcn0pKCkiLCJcInVzZSBzdHJpY3RcIjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuQVBJU3RhdHVzID0gdm9pZCAwO1xudmFyIF91dGlscyA9IHJlcXVpcmUoXCIuLi8uLi91dGlscy5qc1wiKTtcbnZhciBfdXRpbHNEb20gPSByZXF1aXJlKFwiLi91dGlscy1kb20uanNcIik7XG4vLyBIb21lYnJpZGdlIHBsdWdpbiBmb3IgSG9tZSBDb25uZWN0IGhvbWUgYXBwbGlhbmNlc1xuLy8gQ29weXJpZ2h0IMKpIDIwMjQtMjAyNSBBbGV4YW5kZXIgVGhvdWt5ZGlkZXNcblxuLy8gVVJMIGZvciB0aGUgc2VydmVyIHN0YXR1cyBpbWFnZVxuY29uc3QgU1RBVFVTX1VSTCA9ICdodHRwczovL2hvbWVjb25uZWN0LnRob3VreS5jby51ay9hcGkvaW1hZ2VzL3BsdWdpbi1zdGF0dXMuc3ZnJztcbi8vIFdhcm4gZm9yIGVycm9ycyBtb3JlIHJlY2VudCB0aGFuIHRoaXNcbmNvbnN0IFNUQVRVU19TSU5DRSA9IDI0ICogNjAgKiA2MCAqIF91dGlscy5NUztcbi8vIEludGVydmFsIHRvIHBvbGwgZm9yIHVwZGF0ZXMgKGlmIHRoZXJlIGFyZSBpc3N1ZXMpXG5jb25zdCBQT0xMX0lOVEVSVkFMID0gMi41ICogNjAgKiBfdXRpbHMuTVM7XG4vLyBIb21lIENvbm5lY3QgQVBJIHNlcnZlciBzdGF0dXNcbmNsYXNzIEFQSVN0YXR1cyB7XG4gIC8vIENyZWF0ZSBhIG5ldyBBUEkgc2VydmVyIHN0YXR1cyBjaGVja2VyXG4gIGNvbnN0cnVjdG9yKGxvZykge1xuICAgIHRoaXMubG9nID0gbG9nO1xuICAgIHRoaXMucG9sbFN0YXR1cygpO1xuICB9XG4gIC8vIENoZWNrIHRoZSBzdGF0dXMgb2YgdGhlIEhvbWUgQ29ubmVjdCBBUEkgc2VydmVyc1xuICBhc3luYyBwb2xsU3RhdHVzKCkge1xuICAgIC8vIEF0dGVtcHQgdG8gZmV0Y2ggdGhlIHN0YXR1cyBpbWFnZVxuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goU1RBVFVTX1VSTCk7XG4gICAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgICAgdGhpcy5sb2cud2FybignY2hlY2tTdGF0dXMgZmV0Y2gnLCByZXNwb25zZS5zdGF0dXNUZXh0KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3Qgc3ZnID0gYXdhaXQgcmVzcG9uc2UudGV4dCgpO1xuICAgIC8vIEF0dGVtcHQgdG8gcGFyc2UgdGhlIHN0YXR1cyBoZWFkZXJcbiAgICBsZXQgc3RhdHVzO1xuICAgIHRyeSB7XG4gICAgICBzdGF0dXMgPSBKU09OLnBhcnNlKHJlc3BvbnNlLmhlYWRlcnMuZ2V0KCdYLVNlcnZlci1TdGF0dXMnKSA/PyAnJyk7XG4gICAgICAoMCwgX3V0aWxzLmFzc2VydElzQm9vbGVhbikoc3RhdHVzLnVwKTtcbiAgICAgICgwLCBfdXRpbHMuYXNzZXJ0SXNOdW1iZXIpKHN0YXR1cy5zaW5jZSk7XG4gICAgICAoMCwgX3V0aWxzLmFzc2VydElzTnVtYmVyKShzdGF0dXMudXBkYXRlZCk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICB0aGlzLmxvZy53YXJuKCdjaGVja1N0YXR1cyBYLVNlcnZlci1TdGF0dXMnLCBlcnIpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBVcGRhdGUgdGhlIGRpc3BsYXllZCBzdGF0dXMsIGlmIGl0IGhhcyBjaGFuZ2VkXG4gICAgbGV0IHBvbGxBZ2FpbiA9IHRydWU7XG4gICAgaWYgKHRoaXMubGFzdFVwZGF0ZWQgIT09IHN0YXR1cy51cGRhdGVkKSB7XG4gICAgICB0aGlzLmxhc3RVcGRhdGVkID0gc3RhdHVzLnVwZGF0ZWQ7XG4gICAgICBwb2xsQWdhaW4gPSB0aGlzLnNob3dTdGF0dXMoc3ZnLCBzdGF0dXMpO1xuICAgIH1cbiAgICAvLyBQZXJpb2RpY2FsbHkgcG9sbCB0aGUgc3RhdHVzIGlmIHRoZXJlIGFyZSBzZXJ2ZXIgaXNzdWVzXG4gICAgaWYgKHBvbGxBZ2Fpbikgc2V0VGltZW91dCgoKSA9PiB0aGlzLnBvbGxTdGF0dXMoKSwgUE9MTF9JTlRFUlZBTCk7XG4gIH1cbiAgLy8gRGlzcGxheSB0aGUgbGF0ZXN0IHN0YXR1cyBvZiB0aGUgSG9tZSBDb25uZWN0IEFQSSBzZXJ2ZXJzXG4gIHNob3dTdGF0dXMoc3ZnLCBzdGF0dXMpIHtcbiAgICAvLyBEaXNwbGF5IHRoZSBhcHByb3ByaWF0ZSBzdW1tYXJ5XG4gICAgKDAsIF91dGlsc0RvbS5nZXRFbGVtZW50QnlJZCkoJ2hjLWFwaS11cCcpLmhpZGRlbiA9ICFzdGF0dXMudXA7XG4gICAgKDAsIF91dGlsc0RvbS5nZXRFbGVtZW50QnlJZCkoJ2hjLWFwaS11cDInKS5oaWRkZW4gPSAhc3RhdHVzLnVwO1xuICAgICgwLCBfdXRpbHNEb20uZ2V0RWxlbWVudEJ5SWQpKCdoYy1hcGktZG93bicpLmhpZGRlbiA9IHN0YXR1cy51cDtcbiAgICAoMCwgX3V0aWxzRG9tLmdldEVsZW1lbnRCeUlkKSgnaGMtYXBpLWRvd24yJykuaGlkZGVuID0gc3RhdHVzLnVwO1xuICAgIC8vIEFkZCB0aGUgZGV0YWlsZWQgc3RhdHVzXG4gICAgKDAsIF91dGlsc0RvbS5nZXRFbGVtZW50QnlJZCkoJ2hjLWFwaS1zaW5jZScpLmlubmVyVGV4dCA9IHRoaXMuZm9ybWF0RGF0ZVRpbWUoc3RhdHVzLnNpbmNlKTtcbiAgICAvLyBBZGQgdGhlIHJldHJpZXZlZCBzdGF0dXMgaW1hZ2VcbiAgICAoMCwgX3V0aWxzRG9tLmdldEVsZW1lbnRCeUlkKSgnaGMtYXBpLXN2ZycpLmlubmVySFRNTCA9IHN2ZztcbiAgICAvLyBTaG93IG9yIGhpZGUgdGhlIHN0YXR1cyBhcyBhcHByb3ByaWF0ZVxuICAgIGNvbnN0IHNob3dTdGF0dXMgPSAhc3RhdHVzLnVwIHx8IERhdGUubm93KCkgPCBzdGF0dXMuc2luY2UgKyBTVEFUVVNfU0lOQ0U7XG4gICAgKDAsIF91dGlsc0RvbS5nZXRFbGVtZW50QnlJZCkoJ2hjLWFwaS1zdGF0dXMnKS5oaWRkZW4gPSAhc2hvd1N0YXR1cztcbiAgICByZXR1cm4gc2hvd1N0YXR1cztcbiAgfVxuICAvLyBGb3JtYXQgYSBkYXRlL3RpbWVcbiAgZm9ybWF0RGF0ZVRpbWUoZGF0ZSkge1xuICAgIHJldHVybiBuZXcgRGF0ZShkYXRlKS50b0xvY2FsZVN0cmluZyh1bmRlZmluZWQsIHtcbiAgICAgIHdlZWtkYXk6ICdsb25nJyxcbiAgICAgIG1vbnRoOiAnbG9uZycsXG4gICAgICBkYXk6ICdudW1lcmljJyxcbiAgICAgIGhvdXI6ICdudW1lcmljJyxcbiAgICAgIG1pbnV0ZTogJzItZGlnaXQnLFxuICAgICAgdGltZVpvbmVOYW1lOiAnc2hvcnQnXG4gICAgfSk7XG4gIH1cbn1cbmV4cG9ydHMuQVBJU3RhdHVzID0gQVBJU3RhdHVzO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ9dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p1WVcxbGN5STZXeUpmZFhScGJITWlMQ0p5WlhGMWFYSmxJaXdpWDNWMGFXeHpSRzl0SWl3aVUxUkJWRlZUWDFWU1RDSXNJbE5VUVZSVlUxOVRTVTVEUlNJc0lrMVRJaXdpVUU5TVRGOUpUbFJGVWxaQlRDSXNJa0ZRU1ZOMFlYUjFjeUlzSW1OdmJuTjBjblZqZEc5eUlpd2liRzluSWl3aWNHOXNiRk4wWVhSMWN5SXNJbkpsYzNCdmJuTmxJaXdpWm1WMFkyZ2lMQ0p2YXlJc0luZGhjbTRpTENKemRHRjBkWE5VWlhoMElpd2ljM1puSWl3aWRHVjRkQ0lzSW5OMFlYUjFjeUlzSWtwVFQwNGlMQ0p3WVhKelpTSXNJbWhsWVdSbGNuTWlMQ0puWlhRaUxDSmhjM05sY25SSmMwSnZiMnhsWVc0aUxDSjFjQ0lzSW1GemMyVnlkRWx6VG5WdFltVnlJaXdpYzJsdVkyVWlMQ0oxY0dSaGRHVmtJaXdpWlhKeUlpd2ljRzlzYkVGbllXbHVJaXdpYkdGemRGVndaR0YwWldRaUxDSnphRzkzVTNSaGRIVnpJaXdpYzJWMFZHbHRaVzkxZENJc0ltZGxkRVZzWlcxbGJuUkNlVWxrSWl3aWFHbGtaR1Z1SWl3aWFXNXVaWEpVWlhoMElpd2labTl5YldGMFJHRjBaVlJwYldVaUxDSnBibTVsY2toVVRVd2lMQ0pFWVhSbElpd2libTkzSWl3aVpHRjBaU0lzSW5SdlRHOWpZV3hsVTNSeWFXNW5JaXdpZFc1a1pXWnBibVZrSWl3aWQyVmxhMlJoZVNJc0ltMXZiblJvSWl3aVpHRjVJaXdpYUc5MWNpSXNJbTFwYm5WMFpTSXNJblJwYldWYWIyNWxUbUZ0WlNJc0ltVjRjRzl5ZEhNaVhTd2ljMjkxY21ObGN5STZXeUl1TGk4dUxpOHVMaTl6Y21NdmFHOXRaV0p5YVdSblpTMTFhUzl3ZFdKc2FXTXZZWEJwTFhOMFlYUjFjeTUwY3lKZExDSnpiM1Z5WTJWelEyOXVkR1Z1ZENJNlcyNTFiR3hkTENKdFlYQndhVzVuY3lJNklqczdPenM3TzBGQlNVRXNTVUZCUVVFc1RVRkJRU3hIUVVGQlF5eFBRVUZCTzBGQlEwRXNTVUZCUVVNc1UwRkJRU3hIUVVGQlJDeFBRVUZCTzBGQlRFRTdRVUZEUVRzN1FVRk5RVHRCUVVOQkxFMUJRVTFGTEZWQlFWVXNSMEZCUnl3clJFRkJLMFE3UVVGRmJFWTdRVUZEUVN4TlFVRk5ReXhaUVVGWkxFZEJRVWNzUlVGQlJTeEhRVUZITEVWQlFVVXNSMEZCUnl4RlFVRkZMRWRCUVVkRExGTkJRVVU3UVVGRmRFTTdRVUZEUVN4TlFVRk5ReXhoUVVGaExFZEJRVWNzUjBGQlJ5eEhRVUZITEVWQlFVVXNSMEZCUjBRc1UwRkJSVHRCUVZOdVF6dEJRVU5OTEUxQlFVOUZMRk5CUVZNN1JVRkxiRUk3UlVGRFFVTXNXVUZCY1VKRExFZEJRVmM3U1VGQldDeExRVUZCUVN4SFFVRkhMRWRCUVVoQkxFZEJRVWM3U1VGRGNFSXNTVUZCU1N4RFFVRkRReXhWUVVGVkxFVkJRVVU3UlVGRGNrSTdSVUZGUVR0RlFVTkJMRTFCUVUxQkxGVkJRVlZCTEVOQlFVRTdTVUZEV2p0SlFVTkJMRTFCUVUxRExGRkJRVkVzUjBGQlJ5eE5RVUZOUXl4TFFVRkxMRU5CUVVOVUxGVkJRVlVzUTBGQlF6dEpRVU40UXl4SlFVRkpMRU5CUVVOUkxGRkJRVkVzUTBGQlEwVXNSVUZCUlN4RlFVRkZPMDFCUTJRc1NVRkJTU3hEUVVGRFNpeEhRVUZITEVOQlFVTkxMRWxCUVVrc1EwRkJReXh0UWtGQmJVSXNSVUZCUlVnc1VVRkJVU3hEUVVGRFNTeFZRVUZWTEVOQlFVTTdUVUZEZGtRN1NVRkRTanRKUVVOQkxFMUJRVTFETEVkQlFVY3NSMEZCUnl4TlFVRk5UQ3hSUVVGUkxFTkJRVU5OTEVsQlFVa3NSVUZCUlR0SlFVVnFRenRKUVVOQkxFbEJRVWxETEUxQlFVMDdTVUZEVml4SlFVRkpPMDFCUTBGQkxFMUJRVTBzUjBGQlIwTXNTVUZCU1N4RFFVRkRReXhMUVVGTExFTkJRVU5VTEZGQlFWRXNRMEZCUTFVc1QwRkJUeXhEUVVGRFF5eEhRVUZITEVOQlFVTXNhVUpCUVdsQ0xFTkJRVU1zU1VGQlNTeEZRVUZGTEVOQlFXbENPMDFCUTJ4R0xFbEJRVUZETEhOQ1FVRmxMRVZCUVVOTUxFMUJRVTBzUTBGQlEwMHNSVUZCUlN4RFFVRkRPMDFCUXpGQ0xFbEJRVUZETEhGQ1FVRmpMRVZCUVVOUUxFMUJRVTBzUTBGQlExRXNTMEZCU3l4RFFVRkRPMDFCUXpWQ0xFbEJRVUZFTEhGQ1FVRmpMRVZCUVVOUUxFMUJRVTBzUTBGQlExTXNUMEZCVHl4RFFVRkRPMGxCUTJ4RExFTkJRVU1zUTBGQlF5eFBRVUZQUXl4SFFVRkhMRVZCUVVVN1RVRkRWaXhKUVVGSkxFTkJRVU51UWl4SFFVRkhMRU5CUVVOTExFbEJRVWtzUTBGQlF5dzJRa0ZCTmtJc1JVRkJSV01zUjBGQlJ5eERRVUZETzAxQlEycEVPMGxCUTBvN1NVRkZRVHRKUVVOQkxFbEJRVWxETEZOQlFWTXNSMEZCUnl4SlFVRkpPMGxCUTNCQ0xFbEJRVWtzU1VGQlNTeERRVUZEUXl4WFFVRlhMRXRCUVV0YUxFMUJRVTBzUTBGQlExTXNUMEZCVHl4RlFVRkZPMDFCUTNKRExFbEJRVWtzUTBGQlEwY3NWMEZCVnl4SFFVRkhXaXhOUVVGTkxFTkJRVU5UTEU5QlFVODdUVUZEYWtORkxGTkJRVk1zUjBGQlJ5eEpRVUZKTEVOQlFVTkZMRlZCUVZVc1EwRkJRMllzUjBGQlJ5eEZRVUZGUlN4TlFVRk5MRU5CUVVNN1NVRkROVU03U1VGRlFUdEpRVU5CTEVsQlFVbFhMRk5CUVZNc1JVRkJSVWNzVlVGQlZTeERRVUZETEUxQlFVMHNTVUZCU1N4RFFVRkRkRUlzVlVGQlZTeEZRVUZGTEVWQlFVVktMR0ZCUVdFc1EwRkJRenRGUVVOeVJUdEZRVVZCTzBWQlEwRjVRaXhWUVVGVlFTeERRVUZEWml4SFFVRlhMRVZCUVVWRkxFMUJRVzlDTzBsQlEzaERPMGxCUTBFc1NVRkJRV1VzZDBKQlFXTXNSVUZCUXl4WFFVRlhMRU5CUVVNc1EwRkJRME1zVFVGQlRTeEhRVUZITEVOQlFVTm9RaXhOUVVGTkxFTkJRVU5OTEVWQlFVVTdTVUZETDBNc1NVRkJRVk1zZDBKQlFXTXNSVUZCUXl4WlFVRlpMRU5CUVVNc1EwRkJRME1zVFVGQlRTeEhRVUZITEVOQlFVTm9RaXhOUVVGTkxFTkJRVU5OTEVWQlFVVTdTVUZEYUVRc1NVRkJRVk1zZDBKQlFXTXNSVUZCUXl4aFFVRmhMRU5CUVVNc1EwRkJRME1zVFVGQlRTeEhRVUZIYUVJc1RVRkJUU3hEUVVGRFRTeEZRVUZGTzBsQlEyaEVMRWxCUVVGVExIZENRVUZqTEVWQlFVTXNZMEZCWXl4RFFVRkRMRU5CUVVORExFMUJRVTBzUjBGQlIyaENMRTFCUVUwc1EwRkJRMDBzUlVGQlJUdEpRVVZxUkR0SlFVTkJMRWxCUVVGVExIZENRVUZqTEVWQlFVTXNZMEZCWXl4RFFVRkRMRU5CUVVORkxGTkJRVk1zUjBGQlJ5eEpRVUZKTEVOQlFVTkRMR05CUVdNc1EwRkJRMnhDTEUxQlFVMHNRMEZCUTFFc1MwRkJTeXhEUVVGRE8wbEJSVFZGTzBsQlEwRXNTVUZCUVU4c2QwSkJRV01zUlVGQlF5eFpRVUZaTEVOQlFVTXNRMEZCUTBrc1UwRkJVeXhIUVVGSGNrSXNSMEZCUnp0SlFVVTFRenRKUVVOQkxFMUJRVTFsTEZWQlFWVXNSMEZCUnl4RFFVRkRZaXhOUVVGTkxFTkJRVU5OTEVWQlFVVXNTVUZCU1dNc1NVRkJTU3hEUVVGRFF5eEhRVUZITEVWQlFVVXNSMEZCUjNKQ0xFMUJRVTBzUTBGQlExRXNTMEZCU3l4SFFVRkhkRUlzV1VGQldUdEpRVU42UlN4SlFVRkJOa0lzZDBKQlFXTXNSVUZCUXl4bFFVRmxMRU5CUVVNc1EwRkJRME1zVFVGQlRTeEhRVUZITEVOQlFVTklMRlZCUVZVN1NVRkRjRVFzVDBGQlQwRXNWVUZCVlR0RlFVTnlRanRGUVVWQk8wVkJRMEZMTEdOQlFXTkJMRU5CUVVOSkxFbEJRVms3U1VGRGRrSXNUMEZCVHl4SlFVRkpSaXhKUVVGSkxFTkJRVU5GTEVsQlFVa3NRMEZCUXl4RFFVRkRReXhqUVVGakxFTkJRVU5ETEZOQlFWTXNSVUZCUlR0TlFVTTFRME1zVDBGQlR5eEZRVUZUTEUxQlFVMDdUVUZEZEVKRExFdEJRVXNzUlVGQlZ5eE5RVUZOTzAxQlEzUkNReXhIUVVGSExFVkJRV0VzVTBGQlV6dE5RVU42UWtNc1NVRkJTU3hGUVVGWkxGTkJRVk03VFVGRGVrSkRMRTFCUVUwc1JVRkJWU3hUUVVGVE8wMUJRM3BDUXl4WlFVRlpMRVZCUVVrN1MwRkRia0lzUTBGQlF6dEZRVU5PT3p0QlFVTklReXhQUVVGQkxFTkJRVUV4UXl4VFFVRkJMRWRCUVVGQkxGTkJRVUVpTENKcFoyNXZjbVZNYVhOMElqcGJYWDA9IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLkNhcmRzID0gdm9pZCAwO1xudmFyIF91dGlscyA9IHJlcXVpcmUoXCIuLi8uLi91dGlscy5qc1wiKTtcbnZhciBfdXRpbHNEb20gPSByZXF1aXJlKFwiLi91dGlscy1kb20uanNcIik7XG4vLyBIb21lYnJpZGdlIHBsdWdpbiBmb3IgSG9tZSBDb25uZWN0IGhvbWUgYXBwbGlhbmNlc1xuLy8gQ29weXJpZ2h0IMKpIDIwMjMtMjAyNSBBbGV4YW5kZXIgVGhvdWt5ZGlkZXNcblxuLy8gQ2FyZHMgdG8gc2VsZWN0IGdsb2JhbCBvciBwZXItYXBwbGlhbmNlIGNvbmZpZ3VyYXRpb25cbmNsYXNzIENhcmRzIHtcbiAgLy8gQ29uc3RydWN0IGEgbmV3IGNhcmRzIGhhbmRsZXJcbiAgY29uc3RydWN0b3IobG9nKSB7XG4gICAgdGhpcy5sb2cgPSBsb2c7XG4gICAgLy8gQ3VycmVudCBjYXJkc1xuICAgIHRoaXMubm9uQXBwbGlhbmNlQ2FyZHMgPSBbXTtcbiAgICB0aGlzLmFwcGxpYW5jZUNhcmRzID0gW107XG4gICAgdGhpcy5wYXJlbnRFbGVtZW50ID0gKDAsIF91dGlsc0RvbS5nZXRFbGVtZW50QnlJZCkoJ2hjLWFwcGxpYW5jZS1jYXJkcycpO1xuICB9XG4gIC8vIFVwZGF0ZSB0aGUgbGlzdCBvZiBub24tYXBwbGlhbmNlIGNhcmRzXG4gIHNldE5vbkFwcGxpYW5jZXMoY2FyZHMpIHtcbiAgICB0aGlzLm5vbkFwcGxpYW5jZUNhcmRzID0gY2FyZHM7XG4gICAgdGhpcy51cGRhdGVDYXJkcygpO1xuICB9XG4gIC8vIFVwZGF0ZSB0aGUgbGlzdCBvZiBhcHBsaWFuY2VzXG4gIHNldEFwcGxpYW5jZXMoYXBwbGlhbmNlcykge1xuICAgIC8vIENvbnZlcnQgdGhlIGFwcGxpYW5jZXMgdG8gY2FyZCBkZXNjcmlwdGlvbnNcbiAgICBjb25zdCBhcHBsaWFuY2VDYXJkcyA9IGFwcGxpYW5jZXMubWFwKGFwcGxpYW5jZSA9PiAoe1xuICAgICAgaWQ6IGFwcGxpYW5jZS5oYUlkLFxuICAgICAgaWNvbjogYXBwbGlhbmNlLnR5cGUudG9Mb2NhbGVMb3dlckNhc2UoKSxcbiAgICAgIG5hbWU6IGFwcGxpYW5jZS5uYW1lLFxuICAgICAgZGV0YWlsOiBgJHthcHBsaWFuY2UuYnJhbmR9ICR7YXBwbGlhbmNlLmVudW1iZXJ9YFxuICAgIH0pKTtcbiAgICBhcHBsaWFuY2VDYXJkcy5zb3J0KChhLCBiKSA9PiBhLm5hbWUubG9jYWxlQ29tcGFyZShiLm5hbWUpKTtcbiAgICAvLyBDaGVjayB3aGV0aGVyIHRoZSBsaXN0IG9mIGFwcGxpYW5jZXMgaGFzIGNoYW5nZWRcbiAgICBpZiAoSlNPTi5zdHJpbmdpZnkoYXBwbGlhbmNlQ2FyZHMpICE9PSBKU09OLnN0cmluZ2lmeSh0aGlzLmFwcGxpYW5jZUNhcmRzKSkge1xuICAgICAgdGhpcy5hcHBsaWFuY2VDYXJkcyA9IGFwcGxpYW5jZUNhcmRzO1xuICAgICAgdGhpcy51cGRhdGVDYXJkcygpO1xuICAgIH1cbiAgfVxuICAvLyBVcGRhdGUgdGhlIGxpc3Qgb2YgY2FyZHMgYW5kIHJlc3RvcmUgdGhlIHNlbGVjdGlvbiwgaWYgc3RpbGwgdmFsaWRcbiAgdXBkYXRlQ2FyZHMoKSB7XG4gICAgLy8gUmVwbGFjZSB0aGUgZXhpc3RpbmcgY2FyZHMgd2l0aCBuZXcgb25lc1xuICAgIGNvbnN0IGFsbENhcmRzID0gWy4uLnRoaXMubm9uQXBwbGlhbmNlQ2FyZHMsIC4uLnRoaXMuYXBwbGlhbmNlQ2FyZHNdO1xuICAgIHRoaXMucGFyZW50RWxlbWVudC5yZXBsYWNlQ2hpbGRyZW4oLi4uYWxsQ2FyZHMubWFwKGNhcmQgPT4gdGhpcy5tYWtlQ2FyZChjYXJkKSkpO1xuICAgIHRoaXMucGFyZW50RWxlbWVudC5oaWRkZW4gPSAhYWxsQ2FyZHMubGVuZ3RoO1xuICAgIC8vIFJlc3RvcmUgYW55IHByZXZpb3VzIHNlbGVjdGlvblxuICAgIHRoaXMuc2VsZWN0Q2FyZCh0aGlzLnNlbGVjdGVkQ2FyZElkKTtcbiAgfVxuICAvLyBDcmVhdGUgYSBuZXcgY2FyZFxuICBtYWtlQ2FyZCh7XG4gICAgaWQsXG4gICAgaWNvbixcbiAgICBuYW1lLFxuICAgIGRldGFpbFxuICB9KSB7XG4gICAgLy8gQ3JlYXRlIGEgbmV3IGNhcmQgZnJvbSB0aGUgdGVtcGxhdGVcbiAgICBkZXRhaWwgPz8gKGRldGFpbCA9ICfCoCcpOyAvLyAobm9uLWJyZWFraW5nIHNwYWNlKVxuICAgIGNvbnN0IGNhcmQgPSAoMCwgX3V0aWxzRG9tLmNsb25lVGVtcGxhdGUpKCdoYy1hcHBsaWFuY2UtY2FyZCcsIHtcbiAgICAgIG5hbWUsXG4gICAgICBkZXRhaWxcbiAgICB9KTtcbiAgICB0aGlzLmxvYWRDYXJkSWNvbigoMCwgX3V0aWxzRG9tLmdldFNsb3QpKGNhcmQsICdpY29uJyksIGAuL2ltYWdlcy9pY29uLSR7aWNvbn0uc3ZnYCwgaWQpO1xuICAgIC8vIEhhbmRsZSBjYXJkIHNlbGVjdGlvblxuICAgIGNvbnN0IGVsZW1lbnQgPSBjYXJkLmNoaWxkcmVuWzBdO1xuICAgICgwLCBfdXRpbHMuYXNzZXJ0SXNJbnN0YW5jZU9mKShlbGVtZW50LCBIVE1MRWxlbWVudCk7XG4gICAgZWxlbWVudC5kYXRhc2V0LmlkID0gaWQ7XG4gICAgZWxlbWVudC5vbmNsaWNrID0gKCkgPT4ge1xuICAgICAgdGhpcy5zZWxlY3RDYXJkKGlkKTtcbiAgICB9O1xuICAgIHJldHVybiBjYXJkO1xuICB9XG4gIC8vIExvYWQgdGhlIGljb24gaW1hZ2UgZm9yIGEgY2FyZFxuICBhc3luYyBsb2FkQ2FyZEljb24oZWxlbWVudCwgdXJsLCBpZCkge1xuICAgIHRyeSB7XG4gICAgICAvLyBMb2FkIHRoZSBpY29uIGFuZCBhZGQgaXQgdG8gdGhlIGNhcmRcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2godXJsKTtcbiAgICAgIGlmICghcmVzcG9uc2Uub2spIHRocm93IG5ldyBFcnJvcihgRmFpbGVkIHRvIGZldGNoIGljb24gJHtyZXNwb25zZS51cmx9OiAke3Jlc3BvbnNlLnN0YXR1c1RleHR9YCk7XG4gICAgICBlbGVtZW50LmlubmVySFRNTCA9IGF3YWl0IHJlc3BvbnNlLnRleHQoKTtcbiAgICAgIC8vIENoYW5nZSB0aGUgZ3JvdXAgKGxheWVyKSBJRHMgdG8gY2xhc3Nlc1xuICAgICAgZWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKCdnW2lkXScpLmZvckVhY2goZ3JvdXAgPT4ge1xuICAgICAgICBjb25zdCBpZCA9IGdyb3VwLmdldEF0dHJpYnV0ZSgnaWQnKTtcbiAgICAgICAgKDAsIF91dGlscy5hc3NlcnRJc0RlZmluZWQpKGlkKTtcbiAgICAgICAgZ3JvdXAucmVtb3ZlQXR0cmlidXRlKCdpZCcpO1xuICAgICAgICBncm91cC5jbGFzc0xpc3QuYWRkKGlkKTtcbiAgICAgIH0pO1xuICAgICAgLy8gQXNzaWduIHVuaXF1ZSBJRHMgdG8gZ3JhZGllbnQgZmlsbHNcbiAgICAgIGVsZW1lbnQucXVlcnlTZWxlY3RvckFsbCgnZGVmcyBbaWRdJykuZm9yRWFjaChkZWYgPT4ge1xuICAgICAgICBjb25zdCBvbGRJZCA9IGRlZi5nZXRBdHRyaWJ1dGUoJ2lkJyk7XG4gICAgICAgIGNvbnN0IG5ld0lkID0gYCR7aWR9LSR7b2xkSWR9YDtcbiAgICAgICAgZGVmLnNldEF0dHJpYnV0ZSgnaWQnLCBuZXdJZCk7XG4gICAgICAgIGVsZW1lbnQucXVlcnlTZWxlY3RvckFsbChgW2ZpbGw9J3VybCgjJHtvbGRJZH0pJ11gKS5mb3JFYWNoKHJlZiA9PiB7XG4gICAgICAgICAgcmVmLnNldEF0dHJpYnV0ZSgnZmlsbCcsIGB1cmwoIyR7bmV3SWR9KWApO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgdGhpcy5sb2cuZXJyb3IoYGxvYWRDYXJkSWNvbigke2lkfSkgPT5gLCBlcnIpO1xuICAgIH1cbiAgfVxuICAvLyBBIGNhcmQgaGFzIGJlZW4gc2VsZWN0ZWRcbiAgc2VsZWN0Q2FyZChpZCkge1xuICAgIC8vIFNlbGVjdCB0aGlzIGNhcmQgYW5kIGRlc2VsZWN0IGFsbCBvdGhlcnNcbiAgICBsZXQgc2VsZWN0ZWRDYXJkO1xuICAgIGZvciAoY29uc3QgY2FyZCBvZiBBcnJheS5mcm9tKHRoaXMucGFyZW50RWxlbWVudC5jaGlsZHJlbikpIHtcbiAgICAgICgwLCBfdXRpbHMuYXNzZXJ0SXNJbnN0YW5jZU9mKShjYXJkLCBIVE1MRWxlbWVudCk7XG4gICAgICBpZiAoY2FyZC5kYXRhc2V0LmlkID09PSBpZCkgc2VsZWN0ZWRDYXJkID0gY2FyZDtcbiAgICAgIGNhcmQuY2xhc3NMaXN0LnRvZ2dsZSgnaGMtc2VsZWN0ZWQnLCBjYXJkLmRhdGFzZXQuaWQgPT09IGlkKTtcbiAgICB9XG4gICAgaWYgKCFzZWxlY3RlZENhcmQpIGlkID0gdW5kZWZpbmVkO1xuICAgIC8vIE5vdGlmeSB0aGUgY2xpZW50IG9mIHNlbGVjdGlvbiBjaGFuZ2VzXG4gICAgaWYgKHRoaXMuc2VsZWN0ZWRDYXJkSWQgIT09IGlkKSB7XG4gICAgICB0aGlzLmxvZy5kZWJ1Zyhgb25TZWxlY3QoJHtpZH0pICh3YXMgJHt0aGlzLnNlbGVjdGVkQ2FyZElkfSlgKTtcbiAgICAgIHRoaXMuc2VsZWN0ZWRDYXJkSWQgPSBpZDtcbiAgICAgIHRoaXMub25TZWxlY3Q/LihpZCk7XG4gICAgfVxuICB9XG59XG5leHBvcnRzLkNhcmRzID0gQ2FyZHM7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldD11dGYtODtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnVZVzFsY3lJNld5SmZkWFJwYkhNaUxDSnlaWEYxYVhKbElpd2lYM1YwYVd4elJHOXRJaXdpUTJGeVpITWlMQ0pqYjI1emRISjFZM1J2Y2lJc0lteHZaeUlzSW01dmJrRndjR3hwWVc1alpVTmhjbVJ6SWl3aVlYQndiR2xoYm1ObFEyRnlaSE1pTENKd1lYSmxiblJGYkdWdFpXNTBJaXdpWjJWMFJXeGxiV1Z1ZEVKNVNXUWlMQ0p6WlhST2IyNUJjSEJzYVdGdVkyVnpJaXdpWTJGeVpITWlMQ0oxY0dSaGRHVkRZWEprY3lJc0luTmxkRUZ3Y0d4cFlXNWpaWE1pTENKaGNIQnNhV0Z1WTJWeklpd2liV0Z3SWl3aVlYQndiR2xoYm1ObElpd2lhV1FpTENKb1lVbGtJaXdpYVdOdmJpSXNJblI1Y0dVaUxDSjBiMHh2WTJGc1pVeHZkMlZ5UTJGelpTSXNJbTVoYldVaUxDSmtaWFJoYVd3aUxDSmljbUZ1WkNJc0ltVnVkVzFpWlhJaUxDSnpiM0owSWl3aVlTSXNJbUlpTENKc2IyTmhiR1ZEYjIxd1lYSmxJaXdpU2xOUFRpSXNJbk4wY21sdVoybG1lU0lzSW1Gc2JFTmhjbVJ6SWl3aWNtVndiR0ZqWlVOb2FXeGtjbVZ1SWl3aVkyRnlaQ0lzSW0xaGEyVkRZWEprSWl3aWFHbGtaR1Z1SWl3aWJHVnVaM1JvSWl3aWMyVnNaV04wUTJGeVpDSXNJbk5sYkdWamRHVmtRMkZ5WkVsa0lpd2lZMnh2Ym1WVVpXMXdiR0YwWlNJc0lteHZZV1JEWVhKa1NXTnZiaUlzSW1kbGRGTnNiM1FpTENKbGJHVnRaVzUwSWl3aVkyaHBiR1J5Wlc0aUxDSmhjM05sY25SSmMwbHVjM1JoYm1ObFQyWWlMQ0pJVkUxTVJXeGxiV1Z1ZENJc0ltUmhkR0Z6WlhRaUxDSnZibU5zYVdOcklpd2lkWEpzSWl3aWNtVnpjRzl1YzJVaUxDSm1aWFJqYUNJc0ltOXJJaXdpUlhKeWIzSWlMQ0p6ZEdGMGRYTlVaWGgwSWl3aWFXNXVaWEpJVkUxTUlpd2lkR1Y0ZENJc0luRjFaWEo1VTJWc1pXTjBiM0pCYkd3aUxDSm1iM0pGWVdOb0lpd2laM0p2ZFhBaUxDSm5aWFJCZEhSeWFXSjFkR1VpTENKaGMzTmxjblJKYzBSbFptbHVaV1FpTENKeVpXMXZkbVZCZEhSeWFXSjFkR1VpTENKamJHRnpjMHhwYzNRaUxDSmhaR1FpTENKa1pXWWlMQ0p2YkdSSlpDSXNJbTVsZDBsa0lpd2ljMlYwUVhSMGNtbGlkWFJsSWl3aWNtVm1JaXdpWlhKeUlpd2laWEp5YjNJaUxDSnpaV3hsWTNSbFpFTmhjbVFpTENKQmNuSmhlU0lzSW1aeWIyMGlMQ0owYjJkbmJHVWlMQ0oxYm1SbFptbHVaV1FpTENKa1pXSjFaeUlzSW05dVUyVnNaV04wSWl3aVpYaHdiM0owY3lKZExDSnpiM1Z5WTJWeklqcGJJaTR1THk0dUx5NHVMM055WXk5b2IyMWxZbkpwWkdkbExYVnBMM0IxWW14cFl5OWpZWEprY3k1MGN5SmRMQ0p6YjNWeVkyVnpRMjl1ZEdWdWRDSTZXMjUxYkd4ZExDSnRZWEJ3YVc1bmN5STZJanM3T3pzN08wRkJUVUVzU1VGQlFVRXNUVUZCUVN4SFFVRkJReXhQUVVGQk8wRkJRMEVzU1VGQlFVTXNVMEZCUVN4SFFVRkJSQ3hQUVVGQk8wRkJVRUU3UVVGRFFUczdRVUZwUWtFN1FVRkRUU3hOUVVGUFJTeExRVUZMTzBWQllXUTdSVUZEUVVNc1dVRkJjVUpETEVkQlFWYzdTVUZCV0N4TFFVRkJRU3hIUVVGSExFZEJRVWhCTEVkQlFVYzdTVUZVZUVJN1NVRkRRU3hMUVVGQlF5eHBRa0ZCYVVJc1IwRkJkVUlzUlVGQlJUdEpRVU14UXl4TFFVRkJReXhqUVVGakxFZEJRVEJDTEVWQlFVVTdTVUZSZEVNc1NVRkJTU3hEUVVGRFF5eGhRVUZoTEVkQlFVY3NTVUZCUVVNc2QwSkJRV01zUlVGQlF5eHZRa0ZCYjBJc1EwRkJRenRGUVVNM1JEdEZRVVZCTzBWQlEwRkRMR2RDUVVGblFrRXNRMEZCUTBNc1MwRkJkMEk3U1VGRGNrTXNTVUZCU1N4RFFVRkRUQ3hwUWtGQmFVSXNSMEZCUjBzc1MwRkJTenRKUVVNNVFpeEpRVUZKTEVOQlFVTkRMRmRCUVZjc1JVRkJSVHRGUVVOMFFqdEZRVVZCTzBWQlEwRkRMR0ZCUVdGQkxFTkJRVU5ETEZWQlFUSkNPMGxCUTNKRE8wbEJRMEVzVFVGQlRWQXNZMEZCWXl4SFFVRkhUeXhWUVVGVkxFTkJRVU5ETEVkQlFVY3NRMEZCUTBNc1UwRkJVeXhMUVVGTE8wMUJRMmhFUXl4RlFVRkZMRVZCUVUxRUxGTkJRVk1zUTBGQlEwVXNTVUZCU1R0TlFVTjBRa01zU1VGQlNTeEZRVUZKU0N4VFFVRlRMRU5CUVVOSkxFbEJRVWtzUTBGQlEwTXNhVUpCUVdsQ0xFVkJRVVU3VFVGRE1VTkRMRWxCUVVrc1JVRkJTVTRzVTBGQlV5eERRVUZEVFN4SlFVRkpPMDFCUTNSQ1F5eE5RVUZOTEVWQlFVVXNSMEZCUjFBc1UwRkJVeXhEUVVGRFVTeExRVUZMTEVsQlFVbFNMRk5CUVZNc1EwRkJRMU1zVDBGQlR6dExRVU5zUkN4RFFVRkRMRU5CUVVNN1NVRkRTR3hDTEdOQlFXTXNRMEZCUTIxQ0xFbEJRVWtzUTBGQlF5eERRVUZEUXl4RFFVRkRMRVZCUVVWRExFTkJRVU1zUzBGQlMwUXNRMEZCUXl4RFFVRkRUQ3hKUVVGSkxFTkJRVU5QTEdGQlFXRXNRMEZCUTBRc1EwRkJReXhEUVVGRFRpeEpRVUZKTEVOQlFVTXNRMEZCUXp0SlFVVXpSRHRKUVVOQkxFbEJRVWxSTEVsQlFVa3NRMEZCUTBNc1UwRkJVeXhEUVVGRGVFSXNZMEZCWXl4RFFVRkRMRXRCUVV0MVFpeEpRVUZKTEVOQlFVTkRMRk5CUVZNc1EwRkJReXhKUVVGSkxFTkJRVU40UWl4alFVRmpMRU5CUVVNc1JVRkJSVHROUVVONFJTeEpRVUZKTEVOQlFVTkJMR05CUVdNc1IwRkJSMEVzWTBGQll6dE5RVU53UXl4SlFVRkpMRU5CUVVOTExGZEJRVmNzUlVGQlJUdEpRVU4wUWp0RlFVTktPMFZCUlVFN1JVRkRRVUVzVjBGQlYwRXNRMEZCUVR0SlFVTlFPMGxCUTBFc1RVRkJUVzlDTEZGQlFWRXNSMEZCUnl4RFFVRkRMRWRCUVVjc1NVRkJTU3hEUVVGRE1VSXNhVUpCUVdsQ0xFVkJRVVVzUjBGQlJ5eEpRVUZKTEVOQlFVTkRMR05CUVdNc1EwRkJRenRKUVVOd1JTeEpRVUZKTEVOQlFVTkRMR0ZCUVdFc1EwRkJRM2xDTEdWQlFXVXNRMEZCUXl4SFFVRkhSQ3hSUVVGUkxFTkJRVU5xUWl4SFFVRkhMRU5CUVVOdFFpeEpRVUZKTEVsQlFVa3NTVUZCU1N4RFFVRkRReXhSUVVGUkxFTkJRVU5FTEVsQlFVa3NRMEZCUXl4RFFVRkRMRU5CUVVNN1NVRkRhRVlzU1VGQlNTeERRVUZETVVJc1lVRkJZU3hEUVVGRE5FSXNUVUZCVFN4SFFVRkhMRU5CUVVOS0xGRkJRVkVzUTBGQlEwc3NUVUZCVFR0SlFVVTFRenRKUVVOQkxFbEJRVWtzUTBGQlEwTXNWVUZCVlN4RFFVRkRMRWxCUVVrc1EwRkJRME1zWTBGQll5eERRVUZETzBWQlEzaERPMFZCUjBFN1JVRkRRVW9zVVVGQlVVRXNRMEZCUXp0SlFVRkZiRUlzUlVGQlJUdEpRVUZGUlN4SlFVRkpPMGxCUVVWSExFbEJRVWs3U1VGQlJVTTdSVUZCVFN4RFFVRnRRanRKUVVOb1JEdEpRVU5CUVN4TlFVRk5MRXRCUVU1QkxFMUJRVTBzUjBGQlN5eEhRVUZITEVWQlFVTXNRMEZCUXp0SlFVTm9RaXhOUVVGTlZ5eEpRVUZKTEVkQlFVY3NTVUZCUVUwc2RVSkJRV0VzUlVGQlF5eHRRa0ZCYlVJc1JVRkJSVHROUVVGRmJFSXNTVUZCU1R0TlFVRkZRenRKUVVGTkxFTkJRVVVzUTBGQlF6dEpRVU5xUlN4SlFVRkpMRU5CUVVOclFpeFpRVUZaTEVOQlFVTXNTVUZCUVVNc2FVSkJRVThzUlVGQlExSXNTVUZCU1N4RlFVRkZMRTFCUVUwc1EwRkJReXhGUVVGRkxHbENRVUZwUW1Zc1NVRkJTU3hOUVVGTkxFVkJRVVZHTEVWQlFVVXNRMEZCUXp0SlFVVjZSVHRKUVVOQkxFMUJRVTB3UWl4UFFVRlBMRWRCUVVkVUxFbEJRVWtzUTBGQlExVXNVVUZCVVN4RFFVRkRMRU5CUVVNc1EwRkJRenRKUVVOb1F5eEpRVUZCUXl4NVFrRkJhMElzUlVGQlEwWXNUMEZCVHl4RlFVRkZSeXhYUVVGWExFTkJRVU03U1VGRGVFTklMRTlCUVU4c1EwRkJRMGtzVDBGQlR5eERRVUZET1VJc1JVRkJSU3hIUVVGSFFTeEZRVUZGTzBsQlEzWkNNRUlzVDBGQlR5eERRVUZEU3l4UFFVRlBMRWRCUVVjc1RVRkJWenROUVVGSExFbEJRVWtzUTBGQlExWXNWVUZCVlN4RFFVRkRja0lzUlVGQlJTeERRVUZETzBsQlFVVXNRMEZCUXp0SlFVTjBSQ3hQUVVGUGFVSXNTVUZCU1R0RlFVTm1PMFZCUlVFN1JVRkRRU3hOUVVGTlR5eFpRVUZaUVN4RFFVRkRSU3hQUVVGdlFpeEZRVUZGVFN4SFFVRlhMRVZCUVVWb1F5eEZRVUZWTzBsQlF6VkVMRWxCUVVrN1RVRkRRVHROUVVOQkxFMUJRVTFwUXl4UlFVRlJMRWRCUVVjc1RVRkJUVU1zUzBGQlN5eERRVUZEUml4SFFVRkhMRU5CUVVNN1RVRkRha01zU1VGQlNTeERRVUZEUXl4UlFVRlJMRU5CUVVORkxFVkJRVVVzUlVGQlJTeE5RVUZOTEVsQlFVbERMRXRCUVVzc1EwRkJReXgzUWtGQmQwSklMRkZCUVZFc1EwRkJRMFFzUjBGQlJ5eExRVUZMUXl4UlFVRlJMRU5CUVVOSkxGVkJRVlVzUlVGQlJTeERRVUZETzAxQlEycEhXQ3hQUVVGUExFTkJRVU5aTEZOQlFWTXNSMEZCUnl4TlFVRk5UQ3hSUVVGUkxFTkJRVU5OTEVsQlFVa3NSVUZCUlR0TlFVVjZRenROUVVOQllpeFBRVUZQTEVOQlFVTmpMR2RDUVVGblFpeERRVUZETEU5QlFVOHNRMEZCUXl4RFFVRkRReXhQUVVGUExFTkJRVU5ETEV0QlFVc3NTVUZCUnp0UlFVTTVReXhOUVVGTk1VTXNSVUZCUlN4SFFVRkhNRU1zUzBGQlN5eERRVUZEUXl4WlFVRlpMRU5CUVVNc1NVRkJTU3hEUVVGRE8xRkJRMjVETEVsQlFVRkRMSE5DUVVGbExFVkJRVU0xUXl4RlFVRkZMRU5CUVVNN1VVRkRia0l3UXl4TFFVRkxMRU5CUVVOSExHVkJRV1VzUTBGQlF5eEpRVUZKTEVOQlFVTTdVVUZETTBKSUxFdEJRVXNzUTBGQlEwa3NVMEZCVXl4RFFVRkRReXhIUVVGSExFTkJRVU12UXl4RlFVRkZMRU5CUVVNN1RVRkRNMElzUTBGQlF5eERRVUZETzAxQlJVWTdUVUZEUVRCQ0xFOUJRVThzUTBGQlEyTXNaMEpCUVdkQ0xFTkJRVU1zVjBGQlZ5eERRVUZETEVOQlFVTkRMRTlCUVU4c1EwRkJRMDhzUjBGQlJ5eEpRVUZITzFGQlEyaEVMRTFCUVUxRExFdEJRVXNzUjBGQlIwUXNSMEZCUnl4RFFVRkRUQ3haUVVGWkxFTkJRVU1zU1VGQlNTeERRVUZETzFGQlEzQkRMRTFCUVUxUExFdEJRVXNzUjBGQlJ5eEhRVUZIYkVRc1JVRkJSU3hKUVVGSmFVUXNTMEZCU3l4RlFVRkZPMUZCUXpsQ1JDeEhRVUZITEVOQlFVTkhMRmxCUVZrc1EwRkJReXhKUVVGSkxFVkJRVVZFTEV0QlFVc3NRMEZCUXp0UlFVTTNRbmhDTEU5QlFVOHNRMEZCUTJNc1owSkJRV2RDTEVOQlFVTXNaVUZCWlZNc1MwRkJTeXhMUVVGTExFTkJRVU1zUTBGQlExSXNUMEZCVHl4RFFVRkRWeXhIUVVGSExFbEJRVWM3VlVGQlIwRXNSMEZCUnl4RFFVRkRSQ3haUVVGWkxFTkJRVU1zVFVGQlRTeEZRVUZGTEZGQlFWRkVMRXRCUVVzc1IwRkJSeXhEUVVGRE8xRkJRVVVzUTBGQlF5eERRVUZETzAxQlEzWklMRU5CUVVNc1EwRkJRenRKUVVOT0xFTkJRVU1zUTBGQlF5eFBRVUZQUnl4SFFVRkhMRVZCUVVVN1RVRkRWaXhKUVVGSkxFTkJRVU5xUlN4SFFVRkhMRU5CUVVOclJTeExRVUZMTEVOQlFVTXNaMEpCUVdkQ2RFUXNSVUZCUlN4TlFVRk5MRVZCUVVWeFJDeEhRVUZITEVOQlFVTTdTVUZEYWtRN1JVRkRTanRGUVVWQk8wVkJRMEZvUXl4VlFVRlZRU3hEUVVGRGNrSXNSVUZCVnp0SlFVTnNRanRKUVVOQkxFbEJRVWwxUkN4WlFVRnhRenRKUVVONlF5eExRVUZMTEUxQlFVMTBReXhKUVVGSkxFbEJRVWwxUXl4TFFVRkxMRU5CUVVORExFbEJRVWtzUTBGQlF5eEpRVUZKTEVOQlFVTnNSU3hoUVVGaExFTkJRVU52UXl4UlFVRlJMRU5CUVVNc1JVRkJSVHROUVVONFJDeEpRVUZCUXl4NVFrRkJhMElzUlVGQlExZ3NTVUZCU1N4RlFVRkZXU3hYUVVGWExFTkJRVU03VFVGRGNrTXNTVUZCU1Zvc1NVRkJTU3hEUVVGRFlTeFBRVUZQTEVOQlFVTTVRaXhGUVVGRkxFdEJRVXRCTEVWQlFVVXNSVUZCUlhWRUxGbEJRVmtzUjBGQlIzUkRMRWxCUVVrN1RVRkRMME5CTEVsQlFVa3NRMEZCUXpaQ0xGTkJRVk1zUTBGQlExa3NUVUZCVFN4RFFVRkRMR0ZCUVdFc1JVRkJSWHBETEVsQlFVa3NRMEZCUTJFc1QwRkJUeXhEUVVGRE9VSXNSVUZCUlN4TFFVRkxRU3hGUVVGRkxFTkJRVU03U1VGRGFFVTdTVUZEUVN4SlFVRkpMRU5CUVVOMVJDeFpRVUZaTEVWQlFVVjJSQ3hGUVVGRkxFZEJRVWN5UkN4VFFVRlRPMGxCUldwRE8wbEJRMEVzU1VGQlNTeEpRVUZKTEVOQlFVTnlReXhqUVVGakxFdEJRVXQwUWl4RlFVRkZMRVZCUVVVN1RVRkROVUlzU1VGQlNTeERRVUZEV2l4SFFVRkhMRU5CUVVOM1JTeExRVUZMTEVOQlFVTXNXVUZCV1RWRUxFVkJRVVVzVlVGQlZTeEpRVUZKTEVOQlFVTnpRaXhqUVVGakxFZEJRVWNzUTBGQlF6dE5RVU01UkN4SlFVRkpMRU5CUVVOQkxHTkJRV01zUjBGQlIzUkNMRVZCUVVVN1RVRkRlRUlzU1VGQlNTeERRVUZETmtRc1VVRkJVU3hIUVVGSE4wUXNSVUZCUlN4RFFVRkRPMGxCUTNaQ08wVkJRMG83TzBGQlEwZzRSQ3hQUVVGQkxFTkJRVUUxUlN4TFFVRkJMRWRCUVVGQkxFdEJRVUVpTENKcFoyNXZjbVZNYVhOMElqcGJYWDA9IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLkNsaWVudENsaWVudElEID0gdm9pZCAwO1xudmFyIF91dGlscyA9IHJlcXVpcmUoXCIuLi8uLi91dGlscy5qc1wiKTtcbnZhciBfdXRpbHNEb20gPSByZXF1aXJlKFwiLi91dGlscy1kb20uanNcIik7XG4vLyBIb21lYnJpZGdlIHBsdWdpbiBmb3IgSG9tZSBDb25uZWN0IGhvbWUgYXBwbGlhbmNlc1xuLy8gQ29weXJpZ2h0IMKpIDIwMjMtMjAyNSBBbGV4YW5kZXIgVGhvdWt5ZGlkZXNcblxuLy8gTWluaW11bSB0aW1lIGJldHdlZW4gZHVwbGljYXRlIHRvYXN0IG5vdGlmaWNhdGlvbnNcbmNvbnN0IFRPQVNUX0RFRFVQX1RJTUUgPSA1ICogX3V0aWxzLk1TO1xuLy8gVGhlIGN1cnJlbnQgSG9tZSBDb25uZWN0IGNsaWVudFxuY2xhc3MgQ2xpZW50Q2xpZW50SUQge1xuICAvLyBDcmVhdGUgYSBuZXcgSG9tZSBDb25uZWN0IGNsaWVudFxuICBjb25zdHJ1Y3Rvcihsb2csIGlwYykge1xuICAgIHRoaXMubG9nID0gbG9nO1xuICAgIHRoaXMuaXBjID0gaXBjO1xuICAgIHRoaXMuaXBjLm9uRXZlbnQoJ3N0YXR1cycsIHN0YXR1cyA9PiB7XG4gICAgICB0aGlzLm9uQ2xpZW50U3RhdHVzKHN0YXR1cyk7XG4gICAgfSk7XG4gIH1cbiAgLy8gVGhlIEhvbWUgQ29ubmVjdCBjbGllbnQgY29uZmlndXJhdGlvbiBoYXMgY2hhbmdlZFxuICBhc3luYyBzZXRDbGllbnQoY29uZmlnKSB7XG4gICAgY29uc3QgY2xpZW50Q29uZmlnID0gdGhpcy5wcmVwYXJlQ2xpZW50Q29uZmlnKGNvbmZpZyk7XG4gICAgaWYgKGNsaWVudENvbmZpZykge1xuICAgICAgLy8gVGVzdCB0aGUgY2xpZW50IGNvbmZpZ3VyYXRpb25cbiAgICAgIHRoaXMuY2xpZW50Q29uZmlnID0gY2xpZW50Q29uZmlnO1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3Qgc3RhdHVzID0gYXdhaXQgdGhpcy5pcGMucmVxdWVzdCgnL2NsaWVudGlkJywgY2xpZW50Q29uZmlnKTtcbiAgICAgICAgdGhpcy5vbkNsaWVudFN0YXR1cyhzdGF0dXMpO1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGNvbnN0IG1lc3NhZ2UgPSBlcnIgaW5zdGFuY2VvZiBFcnJvciA/IGVyci5tZXNzYWdlIDogU3RyaW5nKGVycik7XG4gICAgICAgIHRoaXMuc2hvd1RvYXN0KCdlcnJvcicsIGBVbmFibGUgdG8gYXR0ZW1wdCBhdXRob3Jpc2F0aW9uICR7bWVzc2FnZX1gKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gSWdub3JlIHRoZSBjbGllbnQgY29uZmlndXJhdGlvbiB1bnRpbCBpdCBpcyB2YWxpZFxuICAgICAgdGhpcy5jbGllbnRDb25maWcgPSB1bmRlZmluZWQ7XG4gICAgICB0aGlzLnNob3dQYW5lbCgpO1xuICAgICAgdGhpcy5vbkFwcGxpYW5jZXM/LigpO1xuICAgIH1cbiAgfVxuICAvLyBUZXN0IHdoZXRoZXIgdGhlIGNsaWVudCBjb25maWd1cmF0aW9uIGlzIGxpa2VseSB0byBiZSB2YWxpZFxuICBwcmVwYXJlQ2xpZW50Q29uZmlnKGNvbmZpZykge1xuICAgIGlmIChjb25maWcuZGVidWc/LmluY2x1ZGVzKCdNb2NrIEFwcGxpYW5jZXMnKSkge1xuICAgICAgLy8gTW9jayBhcHBsaWFuY2VzOyB1c2UgYW4gZW1wdHkgY2xpZW50aWQgdG8gbWF0Y2ggdGhlIHN0YXR1c1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4uY29uZmlnLFxuICAgICAgICBjbGllbnRpZDogJydcbiAgICAgIH07XG4gICAgfSBlbHNlIGlmIChjb25maWcuY2xpZW50aWQgIT09IHVuZGVmaW5lZCAmJiAvXlswLTlBLUZdezY0fSQvaS50ZXN0KGNvbmZpZy5jbGllbnRpZCkpIHtcbiAgICAgIC8vIFZpYWJsZSBjbGllbnRpZFxuICAgICAgcmV0dXJuIGNvbmZpZztcbiAgICB9XG4gIH1cbiAgLy8gSGFuZGxlIGV2ZW50cyBmcm9tIHRoZSBIb21lIENvbm5lY3QgY2xpZW50XG4gIG9uQ2xpZW50U3RhdHVzKHN0YXR1cykge1xuICAgIC8vIElnbm9yZSB0aGUgc3RhdHVzIGlmIG5vIGxvbmdlciBtb25pdG9yaW5nIHRoZSBjbGllbnRcbiAgICBpZiAodGhpcy5jbGllbnRDb25maWc/LmNsaWVudGlkICE9PSBzdGF0dXMuY2xpZW50aWQpIHJldHVybjtcbiAgICAvLyBVcGRhdGUgdGhlIGxpc3Qgb2YgYXBwbGlhbmNlc1xuICAgIHRoaXMub25BcHBsaWFuY2VzPy4oc3RhdHVzLmFwcGxpYW5jZXMpO1xuICAgIC8vIERpc3BsYXkgYW4gYXBwcm9wcmlhdGUgdG9hc3Qgbm90aWZpY2F0aW9uXG4gICAgc3dpdGNoIChzdGF0dXMuYXV0aG9yaXNhdGlvbj8uc3RhdGUpIHtcbiAgICAgIGNhc2UgJ3N1Y2Nlc3MnOlxuICAgICAgICB0aGlzLnNob3dUb2FzdCgnc3VjY2VzcycsICdTdWNjZXNzZnVsbHkgYXV0aG9yaXNlZCcpO1xuICAgICAgICB0aGlzLnNob3dQYW5lbCgpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3VzZXInOlxuICAgICAgICB0aGlzLnNob3dUb2FzdCgnaW5mbycsICdVc2VyIGF1dGhvcmlzYXRpb24gcmVxdWlyZWQnKTtcbiAgICAgICAgdGhpcy5zaG93VXNlckF1dGhvcmlzYXRpb24oc3RhdHVzLmF1dGhvcmlzYXRpb24pO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2ZhaWwnOlxuICAgICAgICB0aGlzLnNob3dUb2FzdCgnZXJyb3InLCAnQXV0aG9yaXNhdGlvbiBmYWlsZWQnKTtcbiAgICAgICAgdGhpcy5zaG93RmFpbChzdGF0dXMuYXV0aG9yaXNhdGlvbik7XG4gICAgICAgIHRoaXMub25GYWlsPy4oKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdidXN5JzpcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRoaXMuc2hvd1BhbmVsKCk7XG4gICAgfVxuICB9XG4gIC8vIFByb21wdCB0aGUgdXNlciB0byBhdXRob3Jpc2UgdGhlIGNsaWVudFxuICBzaG93VXNlckF1dGhvcmlzYXRpb24oYXV0aG9yaXNhdGlvbikge1xuICAgIC8vIFNldCB0aGUgbGluay9jb2RlXG4gICAgY29uc3QgbGluayA9ICgwLCBfdXRpbHNEb20uZ2V0RWxlbWVudEJ5SWQpKCdoYy1jbGllbnQtdXNlci1saW5rJyk7XG4gICAgbGluay5zZXRBdHRyaWJ1dGUoJ2hyZWYnLCBhdXRob3Jpc2F0aW9uLnVyaSk7XG4gICAgKDAsIF91dGlsc0RvbS5zZXRTbG90VGV4dCkoZG9jdW1lbnQsIHtcbiAgICAgICdoYy1jbGllbnQtdXNlci1jb2RlJzogYXV0aG9yaXNhdGlvbi5jb2RlXG4gICAgfSk7XG4gICAgLy8gRW5hYmxlIGdlbmVyYXRpb24gb2YgYSBuZXcgYXV0aG9yaXNhdGlvbiBjb2RlXG4gICAgKDAsIF91dGlsc0RvbS5nZXRFbGVtZW50QnlJZCkoJ2hjLWNsaWVudC11c2VyLXJldHJ5Jykub25jbGljayA9ICgpID0+IHtcbiAgICAgIHRoaXMucmV0cnlBdXRob3Jpc2F0aW9uKCk7XG4gICAgfTtcbiAgICAvLyBNYWtlIHRoZSBhdXRob3Jpc2F0aW9uIGxpbmsgdmlzaWJsZSAoYmVmb3JlIHRyaWdnZXJpbmcgdHJhbnNpdGlvbilcbiAgICB0aGlzLnNob3dQYW5lbCgnaGMtY2xpZW50LXVzZXInKTtcbiAgICAvLyBTdGFydCBhbmltYXRpbmcgdGhlIHByb2dyZXNzIGJhciBmb3IgdGhlIHRpbWUgdW50aWwgdGhlIGxpbmsgZXhwaXJlc1xuICAgIGNvbnN0IHByb2dyZXNzID0gKDAsIF91dGlsc0RvbS5nZXRFbGVtZW50QnlJZCkoJ2hjLWNsaWVudC11c2VyLXByb2dyZXNzJyk7XG4gICAgcHJvZ3Jlc3MuY2xhc3NMaXN0LnJlbW92ZSgnaGMtcHJvZ3Jlc3MtemVybycpO1xuICAgIGlmIChhdXRob3Jpc2F0aW9uLmV4cGlyZXMgIT09IG51bGwpIHtcbiAgICAgIHByb2dyZXNzLnN0eWxlLnRyYW5zaXRpb25EdXJhdGlvbiA9IGAke2F1dGhvcmlzYXRpb24uZXhwaXJlcyAtIERhdGUubm93KCl9bXNgO1xuICAgICAgdm9pZCBwcm9ncmVzcy5vZmZzZXRIZWlnaHQ7IC8vIChmb3JjZSBhIHJlZmxvdylcbiAgICAgIHByb2dyZXNzLmNsYXNzTGlzdC5hZGQoJ2hjLXByb2dyZXNzLXplcm8nKTtcbiAgICB9XG4gIH1cbiAgLy8gRGlzcGxheSB0aGUgcmVzdWx0IG9mIGEgZmFpbGVkIGF1dGhvcmlzYXRpb25cbiAgc2hvd0ZhaWwoYXV0aG9yaXNhdGlvbikge1xuICAgIC8vIERpc3BsYXkgdGhlIGVycm9yIG1lc3NhZ2VcbiAgICAoMCwgX3V0aWxzRG9tLmdldEVsZW1lbnRCeUlkKSgnaGMtY2xpZW50LWZhaWwtbWVzc2FnZScpLnRleHRDb250ZW50ID0gYXV0aG9yaXNhdGlvbi5tZXNzYWdlO1xuICAgIC8vIEluZGljYXRlIHdoZXRoZXIgdGhlIGF1dGhvcmlzYXRpb24gY2FuIGJlIHJldHJpZWRcbiAgICAoMCwgX3V0aWxzRG9tLmdldEVsZW1lbnRCeUlkKSgnaGMtY2xpZW50LWZhaWwtcmV0cnlhYmxlJykuaGlkZGVuID0gIWF1dGhvcmlzYXRpb24ucmV0cnlhYmxlO1xuICAgICgwLCBfdXRpbHNEb20uZ2V0RWxlbWVudEJ5SWQpKCdoYy1jbGllbnQtZmFpbC1yZXRyeScpLmhpZGRlbiA9ICFhdXRob3Jpc2F0aW9uLnJldHJ5YWJsZTtcbiAgICAoMCwgX3V0aWxzRG9tLmdldEVsZW1lbnRCeUlkKSgnaGMtY2xpZW50LWZhaWwtcmV0cnknKS5vbmNsaWNrID0gKCkgPT4ge1xuICAgICAgdGhpcy5yZXRyeUF1dGhvcmlzYXRpb24oKTtcbiAgICB9O1xuICAgIC8vIEFkZCBhbnkgaGVscCB0aGF0IGhhcyBiZWVuIHByb3ZpZGVkXG4gICAgaWYgKGF1dGhvcmlzYXRpb24uaGVscCkge1xuICAgICAgLy8gU2V0IHRleHQgYmxvY2tzXG4gICAgICBjb25zdCBzZXRUZXh0ID0gKGlkLCB0ZXh0KSA9PiB7XG4gICAgICAgICgwLCBfdXRpbHNEb20uZ2V0RWxlbWVudEJ5SWQpKGlkKS5yZXBsYWNlQ2hpbGRyZW4oLi4udGV4dC5tYXAocGFyYWdyYXBoID0+ICgwLCBfdXRpbHNEb20uY2xvbmVUZW1wbGF0ZSkoJ2hjLWNsaWVudC1mYWlsLXBhcmFncmFwaCcsIHtcbiAgICAgICAgICBwYXJhZ3JhcGhcbiAgICAgICAgfSkpKTtcbiAgICAgIH07XG4gICAgICBzZXRUZXh0KCdoYy1jbGllbnQtZmFpbC1wcmVzY3JpcHQnLCBhdXRob3Jpc2F0aW9uLmhlbHAucHJlc2NyaXB0KTtcbiAgICAgIHNldFRleHQoJ2hjLWNsaWVudC1mYWlsLXBvc3RzY3JpcHQnLCBhdXRob3Jpc2F0aW9uLmhlbHAucG9zdHNjcmlwdCk7XG4gICAgICAvLyBQcm92aWRlIGFkZGl0aW9uYWwgaGVscCBmb3IgY3JlYXRpbmcgb3IgbW9kaWZ5aW5nIHRoZSBhcHBsaWNhdGlvblxuICAgICAgY29uc3Qge1xuICAgICAgICBjbGllbnRcbiAgICAgIH0gPSBhdXRob3Jpc2F0aW9uLmhlbHA7XG4gICAgICBjb25zdCBsaW5rID0gKDAsIF91dGlsc0RvbS5nZXRFbGVtZW50QnlJZCkoJ2hjLWNsaWVudC1mYWlsLXVyaScpO1xuICAgICAgaWYgKGNsaWVudCkge1xuICAgICAgICAoMCwgX3V0aWxzRG9tLmdldEVsZW1lbnRCeUlkKSgnaGMtY2xpZW50LWZhaWwtY2xpZW50LXNldHRpbmdzJykucmVwbGFjZUNoaWxkcmVuKC4uLk9iamVjdC5lbnRyaWVzKGNsaWVudC5zZXR0aW5ncykubWFwKChba2V5LCB2YWx1ZV0pID0+ICgwLCBfdXRpbHNEb20uY2xvbmVUZW1wbGF0ZSkoJ2hjLWNsaWVudC1mYWlsLWNsaWVudC1zZXR0aW5nJywge1xuICAgICAgICAgIGtleSxcbiAgICAgICAgICB2YWx1ZVxuICAgICAgICB9KSkpO1xuICAgICAgICBsaW5rLnNldEF0dHJpYnV0ZSgnaHJlZicsIGNsaWVudC51cmkpO1xuICAgICAgICBsaW5rLnRleHRDb250ZW50ID0gY2xpZW50LmFjdGlvbiA9PT0gJ2NyZWF0ZScgPyAnQ3JlYXRlIGFwcGxpY2F0aW9uJyA6ICdNb2RpZnkgYXBwbGljYXRpb24nO1xuICAgICAgICBsaW5rLmhpZGRlbiA9IGZhbHNlO1xuICAgICAgICAoMCwgX3V0aWxzRG9tLmdldEVsZW1lbnRCeUlkKSgnaGMtY2xpZW50LWZhaWwtY2xpZW50JykuaGlkZGVuID0gZmFsc2U7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsaW5rLmhpZGRlbiA9IHRydWU7XG4gICAgICAgICgwLCBfdXRpbHNEb20uZ2V0RWxlbWVudEJ5SWQpKCdoYy1jbGllbnQtZmFpbC1jbGllbnQnKS5oaWRkZW4gPSB0cnVlO1xuICAgICAgfVxuICAgICAgLy8gTWFrZSB0aGUgZGV0YWlscyB2aXNpYmxlXG4gICAgICAoMCwgX3V0aWxzRG9tLmdldEVsZW1lbnRCeUlkKSgnaGMtY2xpZW50LWZhaWwtZGV0YWlsJykuaGlkZGVuID0gZmFsc2U7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIE90aGVyd2lzZSBoaWRlIHRoZSBkZXRhaWxzXG4gICAgICAoMCwgX3V0aWxzRG9tLmdldEVsZW1lbnRCeUlkKSgnaGMtY2xpZW50LWZhaWwtdXJpJykuaGlkZGVuID0gdHJ1ZTtcbiAgICAgICgwLCBfdXRpbHNEb20uZ2V0RWxlbWVudEJ5SWQpKCdoYy1jbGllbnQtZmFpbC1kZXRhaWwnKS5oaWRkZW4gPSB0cnVlO1xuICAgIH1cbiAgICAvLyBNYWtlIHRoZSBmYWlsdXJlIG1lc3NhZ2UgdmlzaWJsZVxuICAgIHRoaXMuc2hvd1BhbmVsKCdoYy1jbGllbnQtZmFpbCcpO1xuICB9XG4gIC8vIFRyaWdnZXIgYXV0aG9yaXNhdGlvbiByZXRyeVxuICBhc3luYyByZXRyeUF1dGhvcmlzYXRpb24oKSB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMuaXBjLnJlcXVlc3QoJy9jbGllbnRpZC9yZXRyeScsIG51bGwpO1xuICAgICAgdGhpcy5zaG93VG9hc3QoJ2luZm8nLCAnUmVxdWVzdGluZyBuZXcgYXV0aG9yaXNhdGlvbiBjb2RlJyk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBjb25zdCBtZXNzYWdlID0gZXJyIGluc3RhbmNlb2YgRXJyb3IgPyBlcnIubWVzc2FnZSA6IFN0cmluZyhlcnIpO1xuICAgICAgdGhpcy5zaG93VG9hc3QoJ2Vycm9yJywgYFVuYWJsZSB0byByZXRyeSBhdXRob3Jpc2F0aW9uOiAke21lc3NhZ2V9YCk7XG4gICAgfVxuICB9XG4gIC8vIFNob3cgdGhlIHNwZWNpZmllZCBlbGVtZW50IGFuZCBoaWRlIGFsbCBvdGhlcnNcbiAgc2hvd1BhbmVsKGlkU2hvdykge1xuICAgIGZvciAoY29uc3QgaWQgb2YgWydoYy1jbGllbnQtZmFpbCcsICdoYy1jbGllbnQtdXNlciddKSB7XG4gICAgICAoMCwgX3V0aWxzRG9tLmdldEVsZW1lbnRCeUlkKShpZCkuaGlkZGVuID0gaWQgIT09IGlkU2hvdztcbiAgICB9XG4gIH1cbiAgLy8gRGlzcGxheSBhIHRvYXN0IG5vdGlmaWNhdGlvblxuICBzaG93VG9hc3QobGV2ZWwsIG1lc3NhZ2UpIHtcbiAgICAvLyBBdm9pZCBkdXBsaWNhdGUgdG9hc3Qgbm90aWZpY2F0aW9uc1xuICAgIGNvbnN0IGtleSA9IGAke2xldmVsfSAtICR7bWVzc2FnZX1gO1xuICAgIGlmICh0aGlzLmxhc3RUb2FzdCA9PT0ga2V5KSByZXR1cm47XG4gICAgdGhpcy5sYXN0VG9hc3QgPSBrZXk7XG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBpZiAodGhpcy5sYXN0VG9hc3QgPT09IGtleSkgdGhpcy5sYXN0VG9hc3QgPSB1bmRlZmluZWQ7XG4gICAgfSwgVE9BU1RfREVEVVBfVElNRSk7XG4gICAgLy8gRGlzcGxheSB0aGUgdG9hc3Qgbm90aWZpY2F0aW9uXG4gICAgd2luZG93LmhvbWVicmlkZ2UudG9hc3RbbGV2ZWxdKG1lc3NhZ2UsICdIb21lIENvbm5lY3QgQ2xpZW50Jyk7XG4gIH1cbn1cbmV4cG9ydHMuQ2xpZW50Q2xpZW50SUQgPSBDbGllbnRDbGllbnRJRDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRhdGE6YXBwbGljYXRpb24vanNvbjtjaGFyc2V0PXV0Zi04O2Jhc2U2NCxleUoyWlhKemFXOXVJam96TENKdVlXMWxjeUk2V3lKZmRYUnBiSE1pTENKeVpYRjFhWEpsSWl3aVgzVjBhV3h6Ukc5dElpd2lWRTlCVTFSZlJFVkVWVkJmVkVsTlJTSXNJazFUSWl3aVEyeHBaVzUwUTJ4cFpXNTBTVVFpTENKamIyNXpkSEoxWTNSdmNpSXNJbXh2WnlJc0ltbHdZeUlzSW05dVJYWmxiblFpTENKemRHRjBkWE1pTENKdmJrTnNhV1Z1ZEZOMFlYUjFjeUlzSW5ObGRFTnNhV1Z1ZENJc0ltTnZibVpwWnlJc0ltTnNhV1Z1ZEVOdmJtWnBaeUlzSW5CeVpYQmhjbVZEYkdsbGJuUkRiMjVtYVdjaUxDSnlaWEYxWlhOMElpd2laWEp5SWl3aWJXVnpjMkZuWlNJc0lrVnljbTl5SWl3aVUzUnlhVzVuSWl3aWMyaHZkMVJ2WVhOMElpd2lkVzVrWldacGJtVmtJaXdpYzJodmQxQmhibVZzSWl3aWIyNUJjSEJzYVdGdVkyVnpJaXdpWkdWaWRXY2lMQ0pwYm1Oc2RXUmxjeUlzSW1Oc2FXVnVkR2xrSWl3aWRHVnpkQ0lzSW1Gd2NHeHBZVzVqWlhNaUxDSmhkWFJvYjNKcGMyRjBhVzl1SWl3aWMzUmhkR1VpTENKemFHOTNWWE5sY2tGMWRHaHZjbWx6WVhScGIyNGlMQ0p6YUc5M1JtRnBiQ0lzSW05dVJtRnBiQ0lzSW14cGJtc2lMQ0puWlhSRmJHVnRaVzUwUW5sSlpDSXNJbk5sZEVGMGRISnBZblYwWlNJc0luVnlhU0lzSW5ObGRGTnNiM1JVWlhoMElpd2laRzlqZFcxbGJuUWlMQ0pqYjJSbElpd2liMjVqYkdsamF5SXNJbkpsZEhKNVFYVjBhRzl5YVhOaGRHbHZiaUlzSW5CeWIyZHlaWE56SWl3aVkyeGhjM05NYVhOMElpd2ljbVZ0YjNabElpd2laWGh3YVhKbGN5SXNJbk4wZVd4bElpd2lkSEpoYm5OcGRHbHZia1IxY21GMGFXOXVJaXdpUkdGMFpTSXNJbTV2ZHlJc0ltOW1abk5sZEVobGFXZG9kQ0lzSW1Ga1pDSXNJblJsZUhSRGIyNTBaVzUwSWl3aWFHbGtaR1Z1SWl3aWNtVjBjbmxoWW14bElpd2lhR1ZzY0NJc0luTmxkRlJsZUhRaUxDSnBaQ0lzSW5SbGVIUWlMQ0p5WlhCc1lXTmxRMmhwYkdSeVpXNGlMQ0p0WVhBaUxDSndZWEpoWjNKaGNHZ2lMQ0pqYkc5dVpWUmxiWEJzWVhSbElpd2ljSEpsYzJOeWFYQjBJaXdpY0c5emRITmpjbWx3ZENJc0ltTnNhV1Z1ZENJc0lrOWlhbVZqZENJc0ltVnVkSEpwWlhNaUxDSnpaWFIwYVc1bmN5SXNJbXRsZVNJc0luWmhiSFZsSWl3aVlXTjBhVzl1SWl3aWFXUlRhRzkzSWl3aWJHVjJaV3dpTENKc1lYTjBWRzloYzNRaUxDSnpaWFJVYVcxbGIzVjBJaXdpZDJsdVpHOTNJaXdpYUc5dFpXSnlhV1JuWlNJc0luUnZZWE4wSWl3aVpYaHdiM0owY3lKZExDSnpiM1Z5WTJWeklqcGJJaTR1THk0dUx5NHVMM055WXk5b2IyMWxZbkpwWkdkbExYVnBMM0IxWW14cFl5OWpiR2xsYm5RdFkyeHBaVzUwYVdRdWRITWlYU3dpYzI5MWNtTmxjME52Ym5SbGJuUWlPbHR1ZFd4c1hTd2liV0Z3Y0dsdVozTWlPaUk3T3pzN096dEJRVk5CTEVsQlFVRkJMRTFCUVVFc1IwRkJRVU1zVDBGQlFUdEJRVVZCTEVsQlFVRkRMRk5CUVVFc1IwRkJRVVFzVDBGQlFUdEJRVmhCTzBGQlEwRTdPMEZCWVVFN1FVRkRRU3hOUVVGTlJTeG5Ra0ZCWjBJc1IwRkJSeXhEUVVGRExFZEJRVWRETEZOQlFVVTdRVUZGTDBJN1FVRkRUU3hOUVVGUFF5eGpRVUZqTzBWQldYWkNPMFZCUTBGRExGbEJRWEZDUXl4SFFVRlhMRVZCUVZkRExFZEJRV003U1VGQmNFTXNTMEZCUVVRc1IwRkJSeXhIUVVGSVFTeEhRVUZITzBsQlFXMUNMRXRCUVVGRExFZEJRVWNzUjBGQlNFRXNSMEZCUnp0SlFVTXhReXhKUVVGSkxFTkJRVU5CTEVkQlFVY3NRMEZCUTBNc1QwRkJUeXhEUVVGRExGRkJRVkVzUlVGQlJVTXNUVUZCVFN4SlFVRkhPMDFCUVVjc1NVRkJTU3hEUVVGRFF5eGpRVUZqTEVOQlFVTkVMRTFCUVUwc1EwRkJRenRKUVVGRkxFTkJRVU1zUTBGQlF6dEZRVU14UlR0RlFVVkJPMFZCUTBFc1RVRkJUVVVzVTBGQlUwRXNRMEZCUTBNc1RVRkJOa0k3U1VGRGVrTXNUVUZCVFVNc1dVRkJXU3hIUVVGSExFbEJRVWtzUTBGQlEwTXNiVUpCUVcxQ0xFTkJRVU5HTEUxQlFVMHNRMEZCUXp0SlFVTnlSQ3hKUVVGSlF5eFpRVUZaTEVWQlFVVTdUVUZEWkR0TlFVTkJMRWxCUVVrc1EwRkJRMEVzV1VGQldTeEhRVUZIUVN4WlFVRlpPMDFCUTJoRExFbEJRVWs3VVVGRFFTeE5RVUZOU2l4TlFVRk5MRWRCUVVjc1RVRkJUU3hKUVVGSkxFTkJRVU5HTEVkQlFVY3NRMEZCUTFFc1QwRkJUeXhEUVVGRExGZEJRVmNzUlVGQlJVWXNXVUZCV1N4RFFVRkRPMUZCUTJoRkxFbEJRVWtzUTBGQlEwZ3NZMEZCWXl4RFFVRkRSQ3hOUVVGTkxFTkJRVU03VFVGREwwSXNRMEZCUXl4RFFVRkRMRTlCUVU5UExFZEJRVWNzUlVGQlJUdFJRVU5XTEUxQlFVMURMRTlCUVU4c1IwRkJSMFFzUjBGQlJ5eFpRVUZaUlN4TFFVRkxMRWRCUVVkR0xFZEJRVWNzUTBGQlEwTXNUMEZCVHl4SFFVRkhSU3hOUVVGTkxFTkJRVU5JTEVkQlFVY3NRMEZCUXp0UlFVTm9SU3hKUVVGSkxFTkJRVU5KTEZOQlFWTXNRMEZCUXl4UFFVRlBMRVZCUVVVc2JVTkJRVzFEU0N4UFFVRlBMRVZCUVVVc1EwRkJRenROUVVONlJUdEpRVU5LTEVOQlFVTXNUVUZCVFR0TlFVTklPMDFCUTBFc1NVRkJTU3hEUVVGRFNpeFpRVUZaTEVkQlFVZFJMRk5CUVZNN1RVRkROMElzU1VGQlNTeERRVUZEUXl4VFFVRlRMRVZCUVVVN1RVRkRhRUlzU1VGQlNTeERRVUZEUXl4WlFVRlpMRWRCUVVVc1EwRkJSVHRKUVVONlFqdEZRVU5LTzBWQlJVRTdSVUZEUVZRc2JVSkJRVzFDUVN4RFFVRkRSaXhOUVVFMlFqdEpRVU0zUXl4SlFVRkpRU3hOUVVGTkxFTkJRVU5aTEV0QlFVc3NSVUZCUlVNc1VVRkJVU3hEUVVGRExHbENRVUZwUWl4RFFVRkRMRVZCUVVVN1RVRkRNME03VFVGRFFTeFBRVUZQTzFGQlFVVXNSMEZCUjJJc1RVRkJUVHRSUVVGRll5eFJRVUZSTEVWQlFVVTdUVUZCUlN4RFFVRnJRanRKUVVOMFJDeERRVUZETEUxQlFVMHNTVUZCU1dRc1RVRkJUU3hEUVVGRFl5eFJRVUZSTEV0QlFVdE1MRk5CUVZNc1NVRkJTU3hwUWtGQmFVSXNRMEZCUTAwc1NVRkJTU3hEUVVGRFppeE5RVUZOTEVOQlFVTmpMRkZCUVZFc1EwRkJReXhGUVVGRk8wMUJRMnBHTzAxQlEwRXNUMEZCVDJRc1RVRkJjMEk3U1VGRGFrTTdSVUZEU2p0RlFVVkJPMFZCUTBGR0xHTkJRV05CTEVOQlFVTkVMRTFCUVhOQ08wbEJRMnBETzBsQlEwRXNTVUZCU1N4SlFVRkpMRU5CUVVOSkxGbEJRVmtzUlVGQlJXRXNVVUZCVVN4TFFVRkxha0lzVFVGQlRTeERRVUZEYVVJc1VVRkJVU3hGUVVGRk8wbEJSWEpFTzBsQlEwRXNTVUZCU1N4RFFVRkRTQ3haUVVGWkxFZEJRVWRrTEUxQlFVMHNRMEZCUTIxQ0xGVkJRVlVzUTBGQlF6dEpRVVYwUXp0SlFVTkJMRkZCUVZGdVFpeE5RVUZOTEVOQlFVTnZRaXhoUVVGaExFVkJRVVZETEV0QlFVczdUVUZEYmtNc1MwRkJTeXhUUVVGVE8xRkJRMVlzU1VGQlNTeERRVUZEVml4VFFVRlRMRU5CUVVNc1UwRkJVeXhGUVVGRkxIbENRVUY1UWl4RFFVRkRPMUZCUTNCRUxFbEJRVWtzUTBGQlEwVXNVMEZCVXl4RlFVRkZPMUZCUTJoQ08wMUJRMG9zUzBGQlN5eE5RVUZOTzFGQlExQXNTVUZCU1N4RFFVRkRSaXhUUVVGVExFTkJRVU1zVFVGQlRTeEZRVUZGTERaQ1FVRTJRaXhEUVVGRE8xRkJRM0pFTEVsQlFVa3NRMEZCUTFjc2NVSkJRWEZDTEVOQlFVTjBRaXhOUVVGTkxFTkJRVU52UWl4aFFVRmhMRU5CUVVNN1VVRkRhRVE3VFVGRFNpeExRVUZMTEUxQlFVMDdVVUZEVUN4SlFVRkpMRU5CUVVOVUxGTkJRVk1zUTBGQlF5eFBRVUZQTEVWQlFVVXNjMEpCUVhOQ0xFTkJRVU03VVVGREwwTXNTVUZCU1N4RFFVRkRXU3hSUVVGUkxFTkJRVU4yUWl4TlFVRk5MRU5CUVVOdlFpeGhRVUZoTEVOQlFVTTdVVUZEYmtNc1NVRkJTU3hEUVVGRFNTeE5RVUZOTEVkQlFVVXNRMEZCUlR0UlFVTm1PMDFCUTBvc1MwRkJTeXhOUVVGTk8wMUJRMWc3VVVGRFNTeEpRVUZKTEVOQlFVTllMRk5CUVZNc1JVRkJSVHRKUVVOd1FqdEZRVU5LTzBWQlJVRTdSVUZEUVZNc2NVSkJRWEZDUVN4RFFVRkRSaXhoUVVGelF6dEpRVU40UkR0SlFVTkJMRTFCUVUxTExFbEJRVWtzUjBGQlJ5eEpRVUZCUXl4M1FrRkJZeXhGUVVGRExIRkNRVUZ4UWl4RFFVRkRPMGxCUTJ4RVJDeEpRVUZKTEVOQlFVTkZMRmxCUVZrc1EwRkJReXhOUVVGTkxFVkJRVVZRTEdGQlFXRXNRMEZCUTFFc1IwRkJSeXhEUVVGRE8wbEJRelZETEVsQlFVRkRMSEZDUVVGWExFVkJRVU5ETEZGQlFWRXNSVUZCUlR0TlFVRkZMSEZDUVVGeFFpeEZRVUZGVml4aFFVRmhMRU5CUVVOWE8wbEJRVWtzUTBGQlJTeERRVUZETzBsQlJYQkZPMGxCUTBFc1NVRkJRVXdzZDBKQlFXTXNSVUZCUXl4elFrRkJjMElzUTBGQlF5eERRVUZEVFN4UFFVRlBMRWRCUVVjc1RVRkJWenROUVVGSExFbEJRVWtzUTBGQlEwTXNhMEpCUVd0Q0xFVkJRVVU3U1VGQlJTeERRVUZETzBsQlJUTkdPMGxCUTBFc1NVRkJTU3hEUVVGRGNFSXNVMEZCVXl4RFFVRkRMR2RDUVVGblFpeERRVUZETzBsQlJXaERPMGxCUTBFc1RVRkJUWEZDTEZGQlFWRXNSMEZCUnl4SlFVRkJVaXgzUWtGQll5eEZRVUZETEhsQ1FVRjVRaXhEUVVGRE8wbEJRekZFVVN4UlFVRlJMRU5CUVVORExGTkJRVk1zUTBGQlEwTXNUVUZCVFN4RFFVRkRMR3RDUVVGclFpeERRVUZETzBsQlF6ZERMRWxCUVVsb1FpeGhRVUZoTEVOQlFVTnBRaXhQUVVGUExFdEJRVXNzU1VGQlNTeEZRVUZGTzAxQlEyaERTQ3hSUVVGUkxFTkJRVU5KTEV0QlFVc3NRMEZCUTBNc2EwSkJRV3RDTEVkQlFVY3NSMEZCUjI1Q0xHRkJRV0VzUTBGQlEybENMRTlCUVU4c1IwRkJSMGNzU1VGQlNTeERRVUZEUXl4SFFVRkhMRVZCUVVVc1NVRkJTVHROUVVNM1JTeExRVUZMVUN4UlFVRlJMRU5CUVVOUkxGbEJRV0VzUTBGQlF5eERRVUZETzAxQlF6ZENVaXhSUVVGUkxFTkJRVU5ETEZOQlFWTXNRMEZCUTFFc1IwRkJSeXhEUVVGRExHdENRVUZyUWl4RFFVRkRPMGxCUXpsRE8wVkJRMG83UlVGRlFUdEZRVU5CY0VJc1VVRkJVVUVzUTBGQlEwZ3NZVUZCZDBNN1NVRkROME03U1VGRFFTeEpRVUZCVFN4M1FrRkJZeXhGUVVGRExIZENRVUYzUWl4RFFVRkRMRU5CUVVOclFpeFhRVUZYTEVkQlFVZDRRaXhoUVVGaExFTkJRVU5hTEU5QlFVODdTVUZGTlVVN1NVRkRRU3hKUVVGQmEwSXNkMEpCUVdNc1JVRkJReXd3UWtGQk1FSXNRMEZCUXl4RFFVRkRiVUlzVFVGQlRTeEhRVUZITEVOQlFVTjZRaXhoUVVGaExFTkJRVU13UWl4VFFVRlRPMGxCUXpWRkxFbEJRVUZ3UWl4M1FrRkJZeXhGUVVGRExITkNRVUZ6UWl4RFFVRkRMRU5CUVV0dFFpeE5RVUZOTEVkQlFVY3NRMEZCUTNwQ0xHRkJRV0VzUTBGQlF6QkNMRk5CUVZNN1NVRkROVVVzU1VGQlFYQkNMSGRDUVVGakxFVkJRVU1zYzBKQlFYTkNMRU5CUVVNc1EwRkJRMDBzVDBGQlR5eEhRVUZITEUxQlFWYzdUVUZCUnl4SlFVRkpMRU5CUVVORExHdENRVUZyUWl4RlFVRkZPMGxCUVVVc1EwRkJRenRKUVVVelJqdEpRVU5CTEVsQlFVbGlMR0ZCUVdFc1EwRkJRekpDTEVsQlFVa3NSVUZCUlR0TlFVTndRanROUVVOQkxFMUJRVTFETEU5QlFVOHNSMEZCUjBFc1EwRkJRME1zUlVGQlZTeEZRVUZGUXl4SlFVRmpMRXRCUVZVN1VVRkRha1FzU1VGQlFYaENMSGRDUVVGakxFVkJRVU4xUWl4RlFVRkZMRU5CUVVNc1EwRkJRMFVzWlVGQlpTeERRVUZETEVkQlFVZEVMRWxCUVVrc1EwRkJRMFVzUjBGQlJ5eERRVUZEUXl4VFFVRlRMRWxCUTNCRUxFbEJRVUZETEhWQ1FVRmhMRVZCUVVNc01FSkJRVEJDTEVWQlFVVTdWVUZCUlVRN1VVRkJVeXhEUVVGRkxFTkJRVVVzUTBGQlF5eERRVUZETzAxQlEyNUZMRU5CUVVNN1RVRkRSRXdzVDBGQlR5eERRVUZETERCQ1FVRXdRaXhGUVVGSE5VSXNZVUZCWVN4RFFVRkRNa0lzU1VGQlNTeERRVUZEVVN4VFFVRlRMRU5CUVVNN1RVRkRiRVZRTEU5QlFVOHNRMEZCUXl3eVFrRkJNa0lzUlVGQlJUVkNMR0ZCUVdFc1EwRkJRekpDTEVsQlFVa3NRMEZCUTFNc1ZVRkJWU3hEUVVGRE8wMUJSVzVGTzAxQlEwRXNUVUZCVFR0UlFVRkZRenROUVVGTkxFTkJRVVVzUjBGQlIzSkRMR0ZCUVdFc1EwRkJRekpDTEVsQlFVazdUVUZEY2tNc1RVRkJUWFJDTEVsQlFVa3NSMEZCUnl4SlFVRkJReXgzUWtGQll5eEZRVUZETEc5Q1FVRnZRaXhEUVVGRE8wMUJRMnBFTEVsQlFVa3JRaXhOUVVGTkxFVkJRVVU3VVVGRFVpeEpRVUZCTDBJc2QwSkJRV01zUlVGQlF5eG5RMEZCWjBNc1EwRkJReXhEUVVGRGVVSXNaVUZCWlN4RFFVTTFSQ3hIUVVGSFR5eE5RVUZOTEVOQlFVTkRMRTlCUVU4c1EwRkJRMFlzVFVGQlRTeERRVUZEUnl4UlFVRlJMRU5CUVVNc1EwRkJRMUlzUjBGQlJ5eERRVUZETEVOQlFVTXNRMEZCUTFNc1IwRkJSeXhGUVVGRlF5eExRVUZMTEVOQlFVTXNTMEZEYUVRc1NVRkJRVklzZFVKQlFXRXNSVUZCUXl3clFrRkJLMElzUlVGQlJUdFZRVUZGVHl4SFFVRkhPMVZCUVVWRE8xRkJRVXNzUTBGQlJTeERRVUZETEVOQlFVTXNRMEZCUXp0UlFVTjRSWEpETEVsQlFVa3NRMEZCUTBVc1dVRkJXU3hEUVVGRExFMUJRVTBzUlVGQlJUaENMRTFCUVUwc1EwRkJRemRDTEVkQlFVY3NRMEZCUXp0UlFVTnlRMGdzU1VGQlNTeERRVUZEYlVJc1YwRkJWeXhIUVVGSFlTeE5RVUZOTEVOQlFVTk5MRTFCUVUwc1MwRkJTeXhSUVVGUkxFZEJRVWNzYjBKQlFXOUNMRWRCUVVjc2IwSkJRVzlDTzFGQlF6TkdkRU1zU1VGQlNTeERRVUZEYjBJc1RVRkJUU3hIUVVGSExFdEJRVXM3VVVGRGJrSXNTVUZCUVc1Q0xIZENRVUZqTEVWQlFVTXNkVUpCUVhWQ0xFTkJRVU1zUTBGQlEyMUNMRTFCUVUwc1IwRkJSeXhMUVVGTE8wMUJRekZFTEVOQlFVTXNUVUZCVFR0UlFVTkljRUlzU1VGQlNTeERRVUZEYjBJc1RVRkJUU3hIUVVGSExFbEJRVWs3VVVGRGJFSXNTVUZCUVc1Q0xIZENRVUZqTEVWQlFVTXNkVUpCUVhWQ0xFTkJRVU1zUTBGQlEyMUNMRTFCUVUwc1IwRkJSeXhKUVVGSk8wMUJRM3BFTzAxQlJVRTdUVUZEUVN4SlFVRkJia0lzZDBKQlFXTXNSVUZCUXl4MVFrRkJkVUlzUTBGQlF5eERRVUZEYlVJc1RVRkJUU3hIUVVGSExFdEJRVXM3U1VGRE1VUXNRMEZCUXl4TlFVRk5PMDFCUTBnN1RVRkRRU3hKUVVGQmJrSXNkMEpCUVdNc1JVRkJReXh2UWtGQmIwSXNRMEZCUXl4RFFVRkpiVUlzVFVGQlRTeEhRVUZITEVsQlFVazdUVUZEY2tRc1NVRkJRVzVDTEhkQ1FVRmpMRVZCUVVNc2RVSkJRWFZDTEVOQlFVTXNRMEZCUTIxQ0xFMUJRVTBzUjBGQlJ5eEpRVUZKTzBsQlEzcEVPMGxCUlVFN1NVRkRRU3hKUVVGSkxFTkJRVU5vUXl4VFFVRlRMRU5CUVVNc1owSkJRV2RDTEVOQlFVTTdSVUZEY0VNN1JVRkZRVHRGUVVOQkxFMUJRVTF2UWl4clFrRkJhMEpCTEVOQlFVRTdTVUZEY0VJc1NVRkJTVHROUVVOQkxFMUJRVTBzU1VGQlNTeERRVUZEYmtNc1IwRkJSeXhEUVVGRFVTeFBRVUZQTEVOQlFVTXNhVUpCUVdsQ0xFVkJRVVVzU1VGQlNTeERRVUZETzAxQlF5OURMRWxCUVVrc1EwRkJRMHNzVTBGQlV5eERRVUZETEUxQlFVMHNSVUZCUlN4dFEwRkJiVU1zUTBGQlF6dEpRVU12UkN4RFFVRkRMRU5CUVVNc1QwRkJUMG9zUjBGQlJ5eEZRVUZGTzAxQlExWXNUVUZCVFVNc1QwRkJUeXhIUVVGSFJDeEhRVUZITEZsQlFWbEZMRXRCUVVzc1IwRkJSMFlzUjBGQlJ5eERRVUZEUXl4UFFVRlBMRWRCUVVkRkxFMUJRVTBzUTBGQlEwZ3NSMEZCUnl4RFFVRkRPMDFCUTJoRkxFbEJRVWtzUTBGQlEwa3NVMEZCVXl4RFFVRkRMRTlCUVU4c1JVRkJSU3hyUTBGQmEwTklMRTlCUVU4c1JVRkJSU3hEUVVGRE8wbEJRM2hGTzBWQlEwbzdSVUZGUVR0RlFVTkJTeXhUUVVGVFFTeERRVUZEYlVRc1RVRkJaVHRKUVVOeVFpeExRVUZMTEUxQlFVMW1MRVZCUVVVc1NVRkJTU3hEUVVGRExHZENRVUZuUWl4RlFVRkZMR2RDUVVGblFpeERRVUZETEVWQlFVVTdUVUZEYmtRc1NVRkJRWFpDTEhkQ1FVRmpMRVZCUVVOMVFpeEZRVUZGTEVOQlFVTXNRMEZCUTBvc1RVRkJUU3hIUVVGSFNTeEZRVUZGTEV0QlFVdGxMRTFCUVUwN1NVRkROME03UlVGRFNqdEZRVVZCTzBWQlEwRnlSQ3hUUVVGVFFTeERRVUZEYzBRc1MwRkJjVU1zUlVGQlJYcEVMRTlCUVdVN1NVRkROVVE3U1VGRFFTeE5RVUZOY1VRc1IwRkJSeXhIUVVGSExFZEJRVWRKTEV0QlFVc3NUVUZCVFhwRUxFOUJRVThzUlVGQlJUdEpRVU51UXl4SlFVRkpMRWxCUVVrc1EwRkJRekJFTEZOQlFWTXNTMEZCUzB3c1IwRkJSeXhGUVVGRk8wbEJRelZDTEVsQlFVa3NRMEZCUTBzc1UwRkJVeXhIUVVGSFRDeEhRVUZITzBsQlEzQkNUU3hWUVVGVkxFTkJRVU1zVFVGQlN6dE5RVU5hTEVsQlFVa3NTVUZCU1N4RFFVRkRSQ3hUUVVGVExFdEJRVXRNTEVkQlFVY3NSVUZCUlN4SlFVRkpMRU5CUVVOTExGTkJRVk1zUjBGQlIzUkVMRk5CUVZNN1NVRkRNVVFzUTBGQlF5eEZRVUZGYmtJc1owSkJRV2RDTEVOQlFVTTdTVUZGY0VJN1NVRkRRVEpGTEUxQlFVMHNRMEZCUTBNc1ZVRkJWU3hEUVVGRFF5eExRVUZMTEVOQlFVTk1MRXRCUVVzc1EwRkJReXhEUVVGRGVrUXNUMEZCVHl4RlFVRkZMSEZDUVVGeFFpeERRVUZETzBWQlEyeEZPenRCUVVOSUswUXNUMEZCUVN4RFFVRkJOVVVzWTBGQlFTeEhRVUZCUVN4alFVRkJJaXdpYVdkdWIzSmxUR2x6ZENJNlcxMTkiLCJcInVzZSBzdHJpY3RcIjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuQ2xpZW50SVBDID0gdm9pZCAwO1xuLy8gSG9tZWJyaWRnZSBwbHVnaW4gZm9yIEhvbWUgQ29ubmVjdCBob21lIGFwcGxpYW5jZXNcbi8vIENvcHlyaWdodCDCqSAyMDIzLTIwMjUgQWxleGFuZGVyIFRob3VreWRpZGVzXG4vLyBDbGllbnQtc2lkZSBJUEMgaW1wbGVtZW50YXRpb25cbmNsYXNzIENsaWVudElQQyB7XG4gIC8vIENyZWF0ZSBhIG5ldyBjbGllbnQgSVBDIGluc3RhbmNlXG4gIGNvbnN0cnVjdG9yKGxvZykge1xuICAgIHRoaXMubG9nID0gbG9nO1xuICB9XG4gIC8vIElzc3VlIGEgcmVxdWVzdCB0byB0aGUgc2VydmVyXG4gIGFzeW5jIHJlcXVlc3QocGF0aCwgZGF0YSkge1xuICAgIHRyeSB7XG4gICAgICB0aGlzLmxvZy5kZWJ1ZyhgcmVxdWVzdChcIiR7cGF0aH1cIiwgJU8pYCwgZGF0YSk7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB3aW5kb3cuaG9tZWJyaWRnZS5yZXF1ZXN0KHBhdGgsIGRhdGEpO1xuICAgICAgdGhpcy5sb2cuZGVidWcoYHJlcXVlc3QoXCIke3BhdGh9XCIsICVPKSA9PmAsIGRhdGEsIHJlc3VsdCk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgdGhpcy5sb2cuZXJyb3IoYHJlcXVlc3QoXCIke3BhdGh9XCIsICVPKSA9PmAsIGRhdGEsIGVycik7XG4gICAgICB0aHJvdyBlcnI7XG4gICAgfVxuICB9XG4gIC8vIEFkZCBhbiBldmVudCBsaXN0ZW5lclxuICBvbkV2ZW50KGV2ZW50LCBjYWxsYmFjaykge1xuICAgIHdpbmRvdy5ob21lYnJpZGdlLmFkZEV2ZW50TGlzdGVuZXIoZXZlbnQsIGFzeW5jIGV2dCA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBkYXRhID0gZXZ0LmRhdGE7XG4gICAgICAgIGlmIChldmVudCAhPT0gJ2xvZycpIHRoaXMubG9nLmRlYnVnKGBvbkV2ZW50KFwiJHtldmVudH1cIikgPT4gY2FsbGJhY2tgLCBkYXRhKTtcbiAgICAgICAgYXdhaXQgY2FsbGJhY2soZGF0YSk7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgdGhpcy5sb2cuZXJyb3IoYG9uRXZlbnQoXCIke2V2ZW50fVwiKSA9PmAsIGVycik7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbn1cbmV4cG9ydHMuQ2xpZW50SVBDID0gQ2xpZW50SVBDO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ9dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p1WVcxbGN5STZXeUpEYkdsbGJuUkpVRU1pTENKamIyNXpkSEoxWTNSdmNpSXNJbXh2WnlJc0luSmxjWFZsYzNRaUxDSndZWFJvSWl3aVpHRjBZU0lzSW1SbFluVm5JaXdpY21WemRXeDBJaXdpZDJsdVpHOTNJaXdpYUc5dFpXSnlhV1JuWlNJc0ltVnljaUlzSW1WeWNtOXlJaXdpYjI1RmRtVnVkQ0lzSW1WMlpXNTBJaXdpWTJGc2JHSmhZMnNpTENKaFpHUkZkbVZ1ZEV4cGMzUmxibVZ5SWl3aVpYWjBJaXdpWlhod2IzSjBjeUpkTENKemIzVnlZMlZ6SWpwYklpNHVMeTR1THk0dUwzTnlZeTlvYjIxbFluSnBaR2RsTFhWcEwzQjFZbXhwWXk5amJHbGxiblF0YVhCakxuUnpJbDBzSW5OdmRYSmpaWE5EYjI1MFpXNTBJanBiYm5Wc2JGMHNJbTFoY0hCcGJtZHpJam9pT3pzN096czdRVUZCUVR0QlFVTkJPMEZCVFVFN1FVRkRUU3hOUVVGUFFTeFRRVUZUTzBWQlJXeENPMFZCUTBGRExGbEJRWEZDUXl4SFFVRlhPMGxCUVZnc1MwRkJRVUVzUjBGQlJ5eEhRVUZJUVN4SFFVRkhPMFZCUVZjN1JVRkZia003UlVGRFFTeE5RVUZOUXl4UFFVRlBRU3hEUVVFd1FrTXNTVUZCVlN4RlFVRkZReXhKUVVGNVFqdEpRVU40UlN4SlFVRkpPMDFCUTBFc1NVRkJTU3hEUVVGRFNDeEhRVUZITEVOQlFVTkpMRXRCUVVzc1EwRkJReXhaUVVGWlJpeEpRVUZKTEZGQlFWRXNSVUZCUlVNc1NVRkJTU3hEUVVGRE8wMUJRemxETEUxQlFVMUZMRTFCUVUwc1IwRkJXU3hOUVVGTlF5eE5RVUZOTEVOQlFVTkRMRlZCUVZVc1EwRkJRMDRzVDBGQlR5eERRVUZEUXl4SlFVRkpMRVZCUVVWRExFbEJRVWtzUTBGQlF6dE5RVU51UlN4SlFVRkpMRU5CUVVOSUxFZEJRVWNzUTBGQlEwa3NTMEZCU3l4RFFVRkRMRmxCUVZsR0xFbEJRVWtzVjBGQlZ5eEZRVUZGUXl4SlFVRkpMRVZCUVVWRkxFMUJRVTBzUTBGQlF6dE5RVU42UkN4UFFVRlBRU3hOUVVFNFFqdEpRVU42UXl4RFFVRkRMRU5CUVVNc1QwRkJUMGNzUjBGQlJ5eEZRVUZGTzAxQlExWXNTVUZCU1N4RFFVRkRVaXhIUVVGSExFTkJRVU5UTEV0QlFVc3NRMEZCUXl4WlFVRlpVQ3hKUVVGSkxGZEJRVmNzUlVGQlJVTXNTVUZCU1N4RlFVRkZTeXhIUVVGSExFTkJRVU03VFVGRGRFUXNUVUZCVFVFc1IwRkJSenRKUVVOaU8wVkJRMG83UlVGRlFUdEZRVU5CUlN4UFFVRlBRU3hEUVVFMFFrTXNTMEZCV1N4RlFVRkZReXhSUVVFclJEdEpRVU0xUjA0c1RVRkJUU3hEUVVGRFF5eFZRVUZWTEVOQlFVTk5MR2RDUVVGblFpeERRVUZEUml4TFFVRkxMRVZCUVVVc1RVRkJUMGNzUjBGQlJ5eEpRVUZKTzAxQlEzQkVMRWxCUVVrN1VVRkRRU3hOUVVGTldDeEpRVUZKTEVkQlFVbFhMRWRCUVcxRUxFTkJRVU5ZTEVsQlFVazdVVUZEZEVVc1NVRkJTVkVzUzBGQlN5eExRVUZMTEV0QlFVc3NSVUZCUlN4SlFVRkpMRU5CUVVOWUxFZEJRVWNzUTBGQlEwa3NTMEZCU3l4RFFVRkRMRmxCUVZsUExFdEJRVXNzWjBKQlFXZENMRVZCUVVWU0xFbEJRVWtzUTBGQlF6dFJRVU0xUlN4TlFVRk5VeXhSUVVGUkxFTkJRVU5VTEVsQlFVa3NRMEZCUXp0TlFVTjRRaXhEUVVGRExFTkJRVU1zVDBGQlQwc3NSMEZCUnl4RlFVRkZPMUZCUTFZc1NVRkJTU3hEUVVGRFVpeEhRVUZITEVOQlFVTlRMRXRCUVVzc1EwRkJReXhaUVVGWlJTeExRVUZMTEU5QlFVOHNSVUZCUlVnc1IwRkJSeXhEUVVGRE8wMUJRMnBFTzBsQlEwb3NRMEZCUXl4RFFVRkRPMFZCUTA0N08wRkJRMGhQTEU5QlFVRXNRMEZCUVdwQ0xGTkJRVUVzUjBGQlFVRXNVMEZCUVNJc0ltbG5ibTl5WlV4cGMzUWlPbHRkZlE9PSIsIlwidXNlIHN0cmljdFwiO1xuXG52YXIgX2xvZ2dlciA9IHJlcXVpcmUoXCIuL2xvZ2dlci5qc1wiKTtcbnZhciBfY29uZmlnID0gcmVxdWlyZShcIi4vY29uZmlnLmpzXCIpO1xudmFyIF9jYXJkcyA9IHJlcXVpcmUoXCIuL2NhcmRzLmpzXCIpO1xudmFyIF9jbGllbnRDbGllbnRpZCA9IHJlcXVpcmUoXCIuL2NsaWVudC1jbGllbnRpZC5qc1wiKTtcbnZhciBfZm9ybXMgPSByZXF1aXJlKFwiLi9mb3Jtcy5qc1wiKTtcbnZhciBfY2xpZW50SXBjID0gcmVxdWlyZShcIi4vY2xpZW50LWlwYy5qc1wiKTtcbnZhciBfYXBpU3RhdHVzID0gcmVxdWlyZShcIi4vYXBpLXN0YXR1cy5qc1wiKTtcbi8vIEhvbWVicmlkZ2UgcGx1Z2luIGZvciBIb21lIENvbm5lY3QgaG9tZSBhcHBsaWFuY2VzXG4vLyBDb3B5cmlnaHQgwqkgMjAyMy0yMDI1IEFsZXhhbmRlciBUaG91a3lkaWRlc1xuXG4vLyBBIEhvbWVicmlkZ2UgSG9tZUNvbm5lY3QgY3VzdG9tIFVJIGNsaWVudFxuY2xhc3MgQ2xpZW50IHtcbiAgLy8gQ3JlYXRlIGEgbmV3IGN1c3RvbSBVSSBjbGllbnRcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgLy8gQ3JlYXRlIGEgbG9jYWwgbG9nZ2VyIGFuZCBJUEMgY2xpZW50XG4gICAgdGhpcy5sb2cgPSBuZXcgX2xvZ2dlci5DbGllbnRMb2dnZXIoKTtcbiAgICB0aGlzLmxvZy5kZWJ1ZygnaG9tZWJyaWRnZS5wbHVnaW4nLCB3aW5kb3cuaG9tZWJyaWRnZS5wbHVnaW4pO1xuICAgIHRoaXMuaXBjID0gbmV3IF9jbGllbnRJcGMuQ2xpZW50SVBDKHRoaXMubG9nKTtcbiAgICAvLyBXYWl0IGZvciB0aGUgc2VydmVyIGJlZm9yZSBjb250aW51aW5nIGluaXRpYWxpc2F0aW9uXG4gICAgdGhpcy5pcGMub25FdmVudCgncmVhZHknLCAoKSA9PiB7XG4gICAgICB0aGlzLnNlcnZlclJlYWR5KCk7XG4gICAgfSk7XG4gIH1cbiAgLy8gVGhlIHNlcnZlciBpcyByZWFkeSBzbyBmaW5pc2ggaW5pdGlhbGlzaW5nIHRoZSBjbGllbnRcbiAgc2VydmVyUmVhZHkoKSB7XG4gICAgLy8gU3RhcnQgcmVjZWl2aW5nIChpbXBvcnRhbnQpIGxvZyBtZXNzYWdlcyBmcm9tIHRoZSBzZXJ2ZXJcbiAgICB0aGlzLnNlcnZlckxvZyA9IG5ldyBfbG9nZ2VyLlNlcnZlckxvZ2dlcih0aGlzLmlwYywgXCJ3YXJuXCIgLyogTG9nTGV2ZWwuV0FSTiAqLyk7XG4gICAgLy8gQ3JlYXRlIGFsbCBvZiB0aGUgcmVxdWlyZWQgcmVzb3VyY2VzXG4gICAgY29uc3QgY29uZmlnID0gbmV3IF9jb25maWcuQ29uZmlnKHRoaXMubG9nLCB0aGlzLmlwYyk7XG4gICAgY29uc3QgZm9ybXMgPSBuZXcgX2Zvcm1zLkZvcm1zKHRoaXMubG9nLCB0aGlzLmlwYywgY29uZmlnKTtcbiAgICBjb25zdCBjYXJkcyA9IG5ldyBfY2FyZHMuQ2FyZHModGhpcy5sb2cpO1xuICAgIGNvbnN0IGNsaWVudCA9IG5ldyBfY2xpZW50Q2xpZW50aWQuQ2xpZW50Q2xpZW50SUQodGhpcy5sb2csIHRoaXMuaXBjKTtcbiAgICBuZXcgX2FwaVN0YXR1cy5BUElTdGF0dXModGhpcy5sb2cpO1xuICAgIC8vIENyZWF0ZSBjYXJkcyBmb3IgdGhlIGdsb2JhbCBzZXR0aW5ncyBhbmQgZWFjaCBhdmFpbGFibGUgYXBwbGlhbmNlXG4gICAgY2FyZHMuc2V0Tm9uQXBwbGlhbmNlcyhbe1xuICAgICAgaWQ6IF9mb3Jtcy5Gb3JtSWQuR2xvYmFsLFxuICAgICAgaWNvbjogJ2dsb2JhbCcsXG4gICAgICBuYW1lOiAnR2VuZXJhbCBTZXR0aW5ncydcbiAgICB9XSk7XG4gICAgY2xpZW50Lm9uQXBwbGlhbmNlcyA9IGFwcGxpYW5jZXMgPT4ge1xuICAgICAgY2FyZHMuc2V0QXBwbGlhbmNlcyhhcHBsaWFuY2VzID8/IFtdKTtcbiAgICB9O1xuICAgIGNhcmRzLm9uU2VsZWN0ID0gaWQgPT4ge1xuICAgICAgZm9ybXMuc2hvd0Zvcm0oaWQpO1xuICAgIH07XG4gICAgLy8gQXR0ZW1wdCB0byBhdXRob3Jpc2UgYSBjbGllbnQgd2hlbiB0aGUgY29uZmlndXJhdGlvbiBjaGFuZ2VzXG4gICAgY29uZmlnLm9uR2xvYmFsID0gY29uZmlnID0+IHtcbiAgICAgIGNsaWVudC5zZXRDbGllbnQoY29uZmlnKTtcbiAgICB9O1xuICAgIGNsaWVudC5vbkZhaWwgPSAoKSA9PiB7XG4gICAgICBmb3Jtcy5zaG93Rm9ybShfZm9ybXMuRm9ybUlkLkdsb2JhbCk7XG4gICAgfTtcbiAgfVxufVxuLy8gQ3JlYXRlIGEgY3VzdG9tIFVJIGNsaWVudCBpbnN0YW5jZVxubmV3IENsaWVudCgpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ9dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p1WVcxbGN5STZXeUpmYkc5bloyVnlJaXdpY21WeGRXbHlaU0lzSWw5amIyNW1hV2NpTENKZlkyRnlaSE1pTENKZlkyeHBaVzUwUTJ4cFpXNTBhV1FpTENKZlptOXliWE1pTENKZlkyeHBaVzUwU1hCaklpd2lYMkZ3YVZOMFlYUjFjeUlzSWtOc2FXVnVkQ0lzSW1OdmJuTjBjblZqZEc5eUlpd2liRzluSWl3aVEyeHBaVzUwVEc5bloyVnlJaXdpWkdWaWRXY2lMQ0ozYVc1a2IzY2lMQ0pvYjIxbFluSnBaR2RsSWl3aWNHeDFaMmx1SWl3aWFYQmpJaXdpUTJ4cFpXNTBTVkJESWl3aWIyNUZkbVZ1ZENJc0luTmxjblpsY2xKbFlXUjVJaXdpYzJWeWRtVnlURzluSWl3aVUyVnlkbVZ5VEc5bloyVnlJaXdpWTI5dVptbG5JaXdpUTI5dVptbG5JaXdpWm05eWJYTWlMQ0pHYjNKdGN5SXNJbU5oY21Seklpd2lRMkZ5WkhNaUxDSmpiR2xsYm5RaUxDSkRiR2xsYm5SRGJHbGxiblJKUkNJc0lrRlFTVk4wWVhSMWN5SXNJbk5sZEU1dmJrRndjR3hwWVc1alpYTWlMQ0pwWkNJc0lrWnZjbTFKWkNJc0lrZHNiMkpoYkNJc0ltbGpiMjRpTENKdVlXMWxJaXdpYjI1QmNIQnNhV0Z1WTJWeklpd2lZWEJ3YkdsaGJtTmxjeUlzSW5ObGRFRndjR3hwWVc1alpYTWlMQ0p2YmxObGJHVmpkQ0lzSW5Ob2IzZEdiM0p0SWl3aWIyNUhiRzlpWVd3aUxDSnpaWFJEYkdsbGJuUWlMQ0p2YmtaaGFXd2lYU3dpYzI5MWNtTmxjeUk2V3lJdUxpOHVMaTh1TGk5emNtTXZhRzl0WldKeWFXUm5aUzExYVM5d2RXSnNhV012WTJ4cFpXNTBMblJ6SWwwc0luTnZkWEpqWlhORGIyNTBaVzUwSWpwYmJuVnNiRjBzSW0xaGNIQnBibWR6SWpvaU96dEJRVXRCTEVsQlFVRkJMRTlCUVVFc1IwRkJRVU1zVDBGQlFUdEJRVU5CTEVsQlFVRkRMRTlCUVVFc1IwRkJRVVFzVDBGQlFUdEJRVU5CTEVsQlFVRkZMRTFCUVVFc1IwRkJRVVlzVDBGQlFUdEJRVU5CTEVsQlFVRkhMR1ZCUVVFc1IwRkJRVWdzVDBGQlFUdEJRVU5CTEVsQlFVRkpMRTFCUVVFc1IwRkJRVW9zVDBGQlFUdEJRVU5CTEVsQlFVRkxMRlZCUVVFc1IwRkJRVXdzVDBGQlFUdEJRVU5CTEVsQlFVRk5MRlZCUVVFc1IwRkJRVTRzVDBGQlFUdEJRVmhCTzBGQlEwRTdPMEZCV1VFN1FVRkRRU3hOUVVGTlR5eE5RVUZOTzBWQlUxSTdSVUZEUVVNc1dVRkJRVHRKUVVOSk8wbEJRMEVzU1VGQlNTeERRVUZEUXl4SFFVRkhMRWRCUVVjc1NVRkJTVU1zYjBKQlFWa3NSVUZCUlR0SlFVTTNRaXhKUVVGSkxFTkJRVU5FTEVkQlFVY3NRMEZCUTBVc1MwRkJTeXhEUVVGRExHMUNRVUZ0UWl4RlFVRkZReXhOUVVGTkxFTkJRVU5ETEZWQlFWVXNRMEZCUTBNc1RVRkJUU3hEUVVGRE8wbEJRemRFTEVsQlFVa3NRMEZCUTBNc1IwRkJSeXhIUVVGSExFbEJRVWxETEc5Q1FVRlRMRU5CUVVNc1NVRkJTU3hEUVVGRFVDeEhRVUZITEVOQlFVTTdTVUZGYkVNN1NVRkRRU3hKUVVGSkxFTkJRVU5OTEVkQlFVY3NRMEZCUTBVc1QwRkJUeXhEUVVGRExFOUJRVThzUlVGQlJTeE5RVUZMTzAxQlFVY3NTVUZCU1N4RFFVRkRReXhYUVVGWExFVkJRVVU3U1VGQlJTeERRVUZETEVOQlFVTTdSVUZETlVRN1JVRkZRVHRGUVVOQlFTeFhRVUZYUVN4RFFVRkJPMGxCUTFBN1NVRkRRU3hKUVVGSkxFTkJRVU5ETEZOQlFWTXNSMEZCUnl4SlFVRkpReXh2UWtGQldTeERRVUZETEVsQlFVa3NRMEZCUTB3c1IwRkJSeXcyUWtGQlowSTdTVUZGTVVRN1NVRkRRU3hOUVVGTlRTeE5RVUZOTEVkQlFVY3NTVUZCU1VNc1kwRkJUU3hEUVVGRExFbEJRVWtzUTBGQlEySXNSMEZCUnl4RlFVRkZMRWxCUVVrc1EwRkJRMDBzUjBGQlJ5eERRVUZETzBsQlF6ZERMRTFCUVUxUkxFdEJRVXNzUjBGQlNTeEpRVUZKUXl4WlFVRkxMRU5CUVVNc1NVRkJTU3hEUVVGRFppeEhRVUZITEVWQlFVVXNTVUZCU1N4RFFVRkRUU3hIUVVGSExFVkJRVVZOTEUxQlFVMHNRMEZCUXp0SlFVTndSQ3hOUVVGTlNTeExRVUZMTEVkQlFVa3NTVUZCU1VNc1dVRkJTeXhEUVVGRExFbEJRVWtzUTBGQlEycENMRWRCUVVjc1EwRkJRenRKUVVOc1F5eE5RVUZOYTBJc1RVRkJUU3hIUVVGSExFbEJRVWxETERoQ1FVRmpMRU5CUVVNc1NVRkJTU3hEUVVGRGJrSXNSMEZCUnl4RlFVRkZMRWxCUVVrc1EwRkJRMDBzUjBGQlJ5eERRVUZETzBsQlEzSkVMRWxCUVVsakxHOUNRVUZUTEVOQlFVTXNTVUZCU1N4RFFVRkRjRUlzUjBGQlJ5eERRVUZETzBsQlJYWkNPMGxCUTBGblFpeExRVUZMTEVOQlFVTkxMR2RDUVVGblFpeERRVUZETEVOQlFVTTdUVUZCUlVNc1JVRkJSU3hGUVVGRlF5eGhRVUZOTEVOQlFVTkRMRTFCUVUwN1RVRkJSVU1zU1VGQlNTeEZRVUZGTEZGQlFWRTdUVUZCUlVNc1NVRkJTU3hGUVVGRk8wbEJRV3RDTEVOQlFVVXNRMEZCUXl4RFFVRkRPMGxCUTNwR1VpeE5RVUZOTEVOQlFVTlRMRmxCUVZrc1IwRkJTVU1zVlVGQlZTeEpRVUZYTzAxQlFVZGFMRXRCUVVzc1EwRkJRMkVzWVVGQllTeERRVUZEUkN4VlFVRlZMRWxCUVVrc1JVRkJSU3hEUVVGRE8wbEJRVVVzUTBGQlF6dEpRVU4yUmxvc1MwRkJTeXhEUVVGRFl5eFJRVUZSTEVkQlFWTlNMRVZCUVZjc1NVRkJWVHROUVVGSFVpeExRVUZMTEVOQlFVTnBRaXhSUVVGUkxFTkJRVU5VTEVWQlFVVXNRMEZCUXp0SlFVRkZMRU5CUVVNN1NVRkZjRVU3U1VGRFFWWXNUVUZCVFN4RFFVRkRiMElzVVVGQlVTeEhRVUZKY0VJc1RVRkJUU3hKUVVGVk8wMUJRVWROTEUxQlFVMHNRMEZCUTJVc1UwRkJVeXhEUVVGRGNrSXNUVUZCVFN4RFFVRkRPMGxCUVVVc1EwRkJRenRKUVVOcVJVMHNUVUZCVFN4RFFVRkRaMElzVFVGQlRTeEhRVUZMTEUxQlFXbENPMDFCUVVkd1FpeExRVUZMTEVOQlFVTnBRaXhSUVVGUkxFTkJRVU5TTEdGQlFVMHNRMEZCUTBNc1RVRkJUU3hEUVVGRE8wbEJRVVVzUTBGQlF6dEZRVU14UlRzN1FVRkhTanRCUVVOQkxFbEJRVWt4UWl4TlFVRk5MRVZCUVVVaUxDSnBaMjV2Y21WTWFYTjBJanBiWFgwPSIsIlwidXNlIHN0cmljdFwiO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5Db25maWcgPSB2b2lkIDA7XG52YXIgX3V0aWxzID0gcmVxdWlyZShcIi4uLy4uL3V0aWxzLmpzXCIpO1xudmFyIF91dGlsc0RvbSA9IHJlcXVpcmUoXCIuL3V0aWxzLWRvbS5qc1wiKTtcbnZhciBfY29uZmlnVHlwZXMgPSByZXF1aXJlKFwiLi4vLi4vdGkvY29uZmlnLXR5cGVzLmpzXCIpO1xuLy8gSG9tZWJyaWRnZSBwbHVnaW4gZm9yIEhvbWUgQ29ubmVjdCBob21lIGFwcGxpYW5jZXNcbi8vIENvcHlyaWdodCDCqSAyMDIzLTIwMjUgQWxleGFuZGVyIFRob3VreWRpZGVzXG5cbi8vIFRoZSBjdXJyZW50IHBsdWdpbiBjb25maWd1cmF0aW9uXG5jbGFzcyBDb25maWcge1xuICAvLyBDcmVhdGUgYSBuZXcgY29uZmlndXJhdGlvbiBvYmplY3RcbiAgY29uc3RydWN0b3IobG9nLCBpcGMpIHtcbiAgICB0aGlzLmxvZyA9IGxvZztcbiAgICB0aGlzLmlwYyA9IGlwYztcbiAgICAvLyBUaGUgY29uZmlndXJhdGlvbiBiZWluZyBlZGl0ZWRcbiAgICB0aGlzLmdsb2JhbCA9IHt9O1xuICAgIHRoaXMuYXBwbGlhbmNlcyA9IHt9O1xuICAgIHRoaXMucmVhZHlQcm9taXNlID0gdGhpcy5nZXRDb25maWcoKTtcbiAgICB0aGlzLmFjdGl2ZVByb21pc2UgPSB0aGlzLmdldEFjdGl2ZUNvbmZpZygpO1xuICB9XG4gIC8vIFJldHJpZXZlIGFuZCBwYXJzZSB0aGUgY29uZmlndXJhdGlvbiB0byBiZSBlZGl0ZWRcbiAgYXN5bmMgZ2V0Q29uZmlnKCkge1xuICAgIC8vIFJldHJpZXZlIHRoZSBjdXJyZW50IHBsdWdpbiBjb25maWd1cmF0aW9uIChpZiBhbnkpXG4gICAgY29uc3QgY29uZmlnQXJyYXkgPSBhd2FpdCB3aW5kb3cuaG9tZWJyaWRnZS5nZXRQbHVnaW5Db25maWcoKTtcbiAgICBpZiAoY29uZmlnQXJyYXlbMF0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5sb2cud2FybignTm8gcGx1Z2luIGNvbmZpZ3VyYXRpb24gZm91bmQ7IGNyZWF0aW5nIGEgbmV3IG9uZScpO1xuICAgICAgdGhpcy5zYXZlZENvbmZpZyA9IHtcbiAgICAgICAgcGxhdGZvcm06IHdpbmRvdy5ob21lYnJpZGdlLnBsdWdpbi5kaXNwbGF5TmFtZVxuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKDEgPCBjb25maWdBcnJheS5sZW5ndGgpIHtcbiAgICAgICAgdGhpcy5sb2cuZXJyb3IoYFVzaW5nIHRoZSBmaXJzdCBvZiAke2NvbmZpZ0FycmF5Lmxlbmd0aH0gcGx1Z2luIGNvbmZpZ3VyYXRpb25zYCwgY29uZmlnQXJyYXkpO1xuICAgICAgICB3aW5kb3cuaG9tZWJyaWRnZS50b2FzdC5lcnJvcignT25seSBhIHNpbmdsZSBwbGF0Zm9ybSBpbnN0YW5jZSBpcyBzdXBwb3J0ZWQ7IHVzaW5nIHRoZSBmaXJzdCcsICdNdWx0aXBsZSBDb25maWd1cmF0aW9uIEJsb2NrcycpO1xuICAgICAgfVxuICAgICAgdGhpcy5zYXZlZENvbmZpZyA9IGNvbmZpZ0FycmF5WzBdO1xuICAgICAgdGhpcy5jaGVja0lmTW9kaWZpZWQodGhpcy5zYXZlZENvbmZpZyk7XG4gICAgfVxuICAgIC8vIFRyZWF0IGFsbCB1bmV4cGVjdGVkIHByb3BlcnRpZXMgYXMgYXBwbGlhbmNlIGNvbmZpZ3VyYXRpb25zXG4gICAgY29uc3Qga2V5b2ZDb25maWdQbHVnaW4gPSAoMCwgX3V0aWxzLmtleW9mQ2hlY2tlcikoX2NvbmZpZ1R5cGVzLnR5cGVTdWl0ZSwgX2NvbmZpZ1R5cGVzLnR5cGVTdWl0ZS5Db25maWdQbHVnaW4pO1xuICAgIGNvbnN0IHNlbGVjdCA9IHByZWRpY2F0ZSA9PiBPYmplY3QuZnJvbUVudHJpZXMoT2JqZWN0LmVudHJpZXModGhpcy5zYXZlZENvbmZpZyA/PyB7fSkuZmlsdGVyKHByZWRpY2F0ZSkpO1xuICAgIHRoaXMuZ2xvYmFsID0gc2VsZWN0KChba2V5XSkgPT4ga2V5b2ZDb25maWdQbHVnaW4uaW5jbHVkZXMoa2V5KSk7XG4gICAgdGhpcy5hcHBsaWFuY2VzID0gc2VsZWN0KChba2V5XSkgPT4gIWtleW9mQ29uZmlnUGx1Z2luLmluY2x1ZGVzKGtleSkpO1xuICAgIHRoaXMubG9nLmRlYnVnKCdnZXRDb25maWcoKSBnbG9iYWwgJU8gYXBwbGlhbmNlcyAlTycsIHRoaXMuZ2xvYmFsLCB0aGlzLmFwcGxpYW5jZXMpO1xuICAgIHRoaXMub25HbG9iYWw/Lih0aGlzLmdsb2JhbCk7XG4gIH1cbiAgLy8gUmV0cmlldmUgdGhlIG1vc3QgcmVjZW50bHkgdXNlZCBjb25maWd1cmF0aW9uXG4gIGFzeW5jIGdldEFjdGl2ZUNvbmZpZygpIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuaXBjLnJlcXVlc3QoJy9jb25maWcnLCBudWxsKTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gIH1cbiAgLy8gVXBkYXRlIHRoZSBob21lYnJpZGdlLXVpLXggY29weSBvZiB0aGUgY29uZmlndXJhdGlvblxuICBhc3luYyBwdXRDb25maWcoc2F2ZSA9IGZhbHNlKSB7XG4gICAgLy8gQ29uc3RydWN0IHRoZSBmdWxsIGNvbmZpZ3VyYXRpb25cbiAgICBjb25zdCBjb25maWcgPSB7XG4gICAgICAuLi50aGlzLmdsb2JhbCxcbiAgICAgIC4uLnRoaXMuYXBwbGlhbmNlc1xuICAgIH07XG4gICAgdGhpcy5sb2cuZGVidWcoYHB1dENvbmZpZygke3NhdmV9KSd9YCwgY29uZmlnKTtcbiAgICAvLyBJbmZvcm0gaG9tZWJyaWRnZS11aS14IG9mIHRoZSBuZXcgY29uZmlndXJhdGlvblxuICAgIGF3YWl0IHdpbmRvdy5ob21lYnJpZGdlLnVwZGF0ZVBsdWdpbkNvbmZpZyhbY29uZmlnXSk7XG4gICAgaWYgKHNhdmUpIHtcbiAgICAgIGF3YWl0IHdpbmRvdy5ob21lYnJpZGdlLnNhdmVQbHVnaW5Db25maWcoKTtcbiAgICAgIHRoaXMuc2F2ZWRDb25maWcgPSBjb25maWc7XG4gICAgICB0aGlzLmxvZy5pbmZvKCdQbHVnaW4gY29uZmlndXJhdGlvbiBzYXZlZCcpO1xuICAgIH1cbiAgICAvLyBDaGVjayB3aGV0aGVyIHRoZSBjb25maWd1cmF0aW9uIG1hdGNoZXMgdGhlIGFjdGl2ZSBwbHVnaW5cbiAgICB0aGlzLmNoZWNrSWZNb2RpZmllZChjb25maWcpO1xuICB9XG4gIC8vIENvbXBhcmUgdHdvIGNvbmZpZ3VyYXRpb24gb2JqZWN0c1xuICBkaWZmT2JqZWN0KHRvLCBmcm9tLCBrZXlQcmVmaXggPSAnJykge1xuICAgIGNvbnN0IGtleXMgPSBbLi4uT2JqZWN0LmtleXModG8pLCAuLi5PYmplY3Qua2V5cyhmcm9tKV0uZmlsdGVyKChrZXksIGluZGV4LCBzZWxmKSA9PiBpbmRleCA9PT0gc2VsZi5pbmRleE9mKGtleSkgJiYga2V5ICE9PSAnX2JyaWRnZScpO1xuICAgIGNvbnN0IGRpZmYgPSBbXTtcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBrZXlzKSB7XG4gICAgICBjb25zdCB2YWx1ZVRvID0gdG9ba2V5XTtcbiAgICAgIGNvbnN0IHZhbHVlRnJvbSA9IGZyb21ba2V5XTtcbiAgICAgIGNvbnN0IGtleU5hbWUgPSBgJHtrZXlQcmVmaXh9LiR7a2V5fWA7XG4gICAgICBjb25zdCBpc09iamVjdCA9IHZhbHVlID0+IHZhbHVlICE9PSB1bmRlZmluZWQgJiYgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JztcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlVG8pICYmIEFycmF5LmlzQXJyYXkodmFsdWVGcm9tKSkgZGlmZi5wdXNoKC4uLnRoaXMuZGlmZkFycmF5KHZhbHVlVG8sIHZhbHVlRnJvbSwga2V5TmFtZSkpO2Vsc2UgaWYgKGlzT2JqZWN0KHZhbHVlVG8pICYmIGlzT2JqZWN0KHZhbHVlRnJvbSkpIGRpZmYucHVzaCguLi50aGlzLmRpZmZPYmplY3QodmFsdWVUbywgdmFsdWVGcm9tLCBrZXlOYW1lKSk7ZWxzZSBpZiAodmFsdWVUbyAhPT0gdmFsdWVGcm9tKSBkaWZmLnB1c2goe1xuICAgICAgICBrZXk6IGtleU5hbWUsXG4gICAgICAgIGZyb206IHZhbHVlRnJvbSxcbiAgICAgICAgdG86IHZhbHVlVG9cbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gZGlmZjtcbiAgfVxuICAvLyBDb21wYXJlIHR3byBjb25maWd1cmF0aW9uIGFycmF5c1xuICBkaWZmQXJyYXkodG8sIGZyb20sIGtleVByZWZpeCA9ICcnKSB7XG4gICAgY29uc3QgaXNTaW1wbGUgPSBhcnJheSA9PiBhcnJheS5sZW5ndGggIT09IDAgJiYgdHlwZW9mIGFycmF5WzBdICE9PSAnb2JqZWN0JztcbiAgICBpZiAoaXNTaW1wbGUodG8pIHx8IGlzU2ltcGxlKGZyb20pKSB7XG4gICAgICBpZiAodG8ubGVuZ3RoID09PSBmcm9tLmxlbmd0aCAmJiB0by5ldmVyeSgodmFsdWUsIGluZGV4KSA9PiB2YWx1ZSA9PT0gZnJvbVtpbmRleF0pKSByZXR1cm4gW107ZWxzZSByZXR1cm4gW3tcbiAgICAgICAga2V5OiBrZXlQcmVmaXgsXG4gICAgICAgIGZyb20sXG4gICAgICAgIHRvXG4gICAgICB9XTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRoaXMuZGlmZk9iamVjdCh0bywgZnJvbSwga2V5UHJlZml4KTtcbiAgICB9XG4gIH1cbiAgLy8gQ2hlY2sgd2hldGhlciB0aGUgY29uZmlndXJhdGlvbiBoYXMgYmVlbiBtb2RpZmllZFxuICBhc3luYyBjaGVja0lmTW9kaWZpZWQoY29uZmlnKSB7XG4gICAgLy8gSWdub3JlIGNvbXBsZXRlbHkgbmV3L2VtcHR5IGNvbmZpZ3VyYXRpb25cbiAgICBpZiAoIU9iamVjdC5rZXlzKGNvbmZpZykubGVuZ3RoKSByZXR1cm47XG4gICAgLy8gQ29tcGFyZSB0aGUgY29uZmlndXJhdGlvbiB0byB0aGUgYWN0aXZlIHBsdWdpbiBhbmQgc2F2ZWQgdmVyc2lvbnNcbiAgICBjb25zdCBhY3RpdmVDb25maWcgPSBhd2FpdCB0aGlzLmFjdGl2ZVByb21pc2U7XG4gICAgY29uc3QgYWN0aXZlRGlmZiA9IHRoaXMuZGlmZk9iamVjdChjb25maWcsIGFjdGl2ZUNvbmZpZyk7XG4gICAgY29uc3Qgc2F2ZWREaWZmID0gdGhpcy5kaWZmT2JqZWN0KGNvbmZpZywgdGhpcy5zYXZlZENvbmZpZyA/PyB7fSk7XG4gICAgaWYgKGFjdGl2ZURpZmYubGVuZ3RoIHx8IHNhdmVkRGlmZi5sZW5ndGgpIHtcbiAgICAgIHRoaXMubG9nLmRlYnVnKCdjaGVja0lmTW9kaWZpZWQoJU8pIGFjdGl2ZSAlTyBzYXZlZCAlTycsIGNvbmZpZywgYWN0aXZlRGlmZiwgc2F2ZWREaWZmKTtcbiAgICB9XG4gICAgLy8gSGlkZSBvciBzaG93IHRoZSByZXN0YXJ0IHJlcXVpcmVkIG1lc3NhZ2VcbiAgICB0aGlzLnNob3dSZXN0YXJ0UmVxdWlyZWQoYWN0aXZlRGlmZiwgMCA8IHNhdmVkRGlmZi5sZW5ndGgpO1xuICB9XG4gIC8vIFNob3cgb3IgaGlkZSB0aGUgcmVzdGFydCByZXF1aXJlZCBtZXNzYWdlXG4gIHNob3dSZXN0YXJ0UmVxdWlyZWQoY2hhbmdlcywgaXNVbnNhdmVkKSB7XG4gICAgLy8gU2hvdyB0aGUgbWVzc2FnZSBpZiB0aGVyZSBhcmUgYW55IGRpZmZlcmVuY2VzXG4gICAgKDAsIF91dGlsc0RvbS5nZXRFbGVtZW50QnlJZCkoJ2hjLW1vZGlmaWVkJykuaGlkZGVuID0gY2hhbmdlcy5sZW5ndGggPT09IDAgJiYgIWlzVW5zYXZlZDtcbiAgICAoMCwgX3V0aWxzRG9tLmdldEVsZW1lbnRCeUlkKSgnaGMtbW9kaWZpZWQtc2F2ZWQnKS5oaWRkZW4gPSBpc1Vuc2F2ZWQ7XG4gICAgKDAsIF91dGlsc0RvbS5nZXRFbGVtZW50QnlJZCkoJ2hjLW1vZGlmaWVkLXVuc2F2ZWQnKS5oaWRkZW4gPSAhaXNVbnNhdmVkO1xuICAgIC8vIERpc3BsYXkgdGhlIGRpZmZcbiAgICBjb25zdCBmb3JtYXRWYWx1ZSA9IHZhbHVlID0+IEpTT04uc3RyaW5naWZ5KHZhbHVlLCBudWxsLCA0KTtcbiAgICAoMCwgX3V0aWxzRG9tLmdldEVsZW1lbnRCeUlkKSgnaGMtbW9kaWZpZWQtZGlmZicpLnJlcGxhY2VDaGlsZHJlbiguLi5jaGFuZ2VzLm1hcChjaGFuZ2UgPT4gKDAsIF91dGlsc0RvbS5jbG9uZVRlbXBsYXRlKSgnaGMtbW9kaWZpZWQtZGlmZi1kZWx0YScsIHtcbiAgICAgIGtleTogY2hhbmdlLmtleSxcbiAgICAgIGZyb206IGZvcm1hdFZhbHVlKGNoYW5nZS5mcm9tKSxcbiAgICAgIHRvOiBmb3JtYXRWYWx1ZShjaGFuZ2UudG8pXG4gICAgfSkpKTtcbiAgfVxuICAvLyBHZXQgdGhlIGN1cnJlbnQgZ2xvYmFsIGNvbmZpZ3VyYXRpb25cbiAgYXN5bmMgZ2V0R2xvYmFsKCkge1xuICAgIGF3YWl0IHRoaXMucmVhZHlQcm9taXNlO1xuICAgIHJldHVybiB0aGlzLmdsb2JhbDtcbiAgfVxuICAvLyBTZXQgdXBkYXRlZCBnbG9iYWwgY29uZmlndXJhdGlvblxuICBhc3luYyBzZXRHbG9iYWwoY29uZmlnKSB7XG4gICAgaWYgKHRoaXMuZGlmZk9iamVjdChjb25maWcsIGF3YWl0IHRoaXMuZ2V0R2xvYmFsKCkpLmxlbmd0aCkge1xuICAgICAgdGhpcy5sb2cuZGVidWcoJ3NldEdsb2JhbCglTyknLCBjb25maWcpO1xuICAgICAgdGhpcy5nbG9iYWwgPSBjb25maWc7XG4gICAgICB0aGlzLm9uR2xvYmFsPy4oY29uZmlnKTtcbiAgICAgIGF3YWl0IHRoaXMucHV0Q29uZmlnKCk7XG4gICAgfVxuICB9XG4gIC8vIEdldCB0aGUgY3VycmVudCBjb25maWd1cmF0aW9uIGZvciBhIHNwZWNpZmljIGFwcGxpYW5jZVxuICBhc3luYyBnZXRBcHBsaWFuY2UoaGFpZCkge1xuICAgIGF3YWl0IHRoaXMucmVhZHlQcm9taXNlO1xuICAgIHJldHVybiB0aGlzLmFwcGxpYW5jZXNbaGFpZF0gPz8ge307XG4gIH1cbiAgLy8gU2V0IHVwZGF0ZWQgZ2xvYmFsIGNvbmZpZ3VyYXRpb25cbiAgYXN5bmMgc2V0QXBwbGlhbmNlKGhhaWQsIGNvbmZpZykge1xuICAgIGlmICh0aGlzLmRpZmZPYmplY3QoY29uZmlnLCBhd2FpdCB0aGlzLmdldEFwcGxpYW5jZShoYWlkKSkubGVuZ3RoKSB7XG4gICAgICB0aGlzLmxvZy5kZWJ1Zyhgc2V0QXBwbGlhbmNlKFwiJHtoYWlkfVwiLCAlTylgLCBjb25maWcpO1xuICAgICAgdGhpcy5hcHBsaWFuY2VzW2hhaWRdID0gY29uZmlnO1xuICAgICAgYXdhaXQgdGhpcy5wdXRDb25maWcoKTtcbiAgICB9XG4gIH1cbn1cbmV4cG9ydHMuQ29uZmlnID0gQ29uZmlnO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ9dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p1WVcxbGN5STZXeUpmZFhScGJITWlMQ0p5WlhGMWFYSmxJaXdpWDNWMGFXeHpSRzl0SWl3aVgyTnZibVpwWjFSNWNHVnpJaXdpUTI5dVptbG5JaXdpWTI5dWMzUnlkV04wYjNJaUxDSnNiMmNpTENKcGNHTWlMQ0puYkc5aVlXd2lMQ0poY0hCc2FXRnVZMlZ6SWl3aWNtVmhaSGxRY205dGFYTmxJaXdpWjJWMFEyOXVabWxuSWl3aVlXTjBhWFpsVUhKdmJXbHpaU0lzSW1kbGRFRmpkR2wyWlVOdmJtWnBaeUlzSW1OdmJtWnBaMEZ5Y21GNUlpd2lkMmx1Wkc5M0lpd2lhRzl0WldKeWFXUm5aU0lzSW1kbGRGQnNkV2RwYmtOdmJtWnBaeUlzSW5WdVpHVm1hVzVsWkNJc0luZGhjbTRpTENKellYWmxaRU52Ym1acFp5SXNJbkJzWVhSbWIzSnRJaXdpY0d4MVoybHVJaXdpWkdsemNHeGhlVTVoYldVaUxDSnNaVzVuZEdnaUxDSmxjbkp2Y2lJc0luUnZZWE4wSWl3aVkyaGxZMnRKWmsxdlpHbG1hV1ZrSWl3aWEyVjViMlpEYjI1bWFXZFFiSFZuYVc0aUxDSnJaWGx2WmtOb1pXTnJaWElpTENKMGVYQmxVM1ZwZEdVaUxDSkRiMjVtYVdkUWJIVm5hVzRpTENKelpXeGxZM1FpTENKd2NtVmthV05oZEdVaUxDSlBZbXBsWTNRaUxDSm1jbTl0Ulc1MGNtbGxjeUlzSW1WdWRISnBaWE1pTENKbWFXeDBaWElpTENKclpYa2lMQ0pwYm1Oc2RXUmxjeUlzSW1SbFluVm5JaXdpYjI1SGJHOWlZV3dpTENKeVpYRjFaWE4wSWl3aWNIVjBRMjl1Wm1sbklpd2ljMkYyWlNJc0ltTnZibVpwWnlJc0luVndaR0YwWlZCc2RXZHBia052Ym1acFp5SXNJbk5oZG1WUWJIVm5hVzVEYjI1bWFXY2lMQ0pwYm1adklpd2laR2xtWms5aWFtVmpkQ0lzSW5Sdklpd2labkp2YlNJc0ltdGxlVkJ5WldacGVDSXNJbXRsZVhNaUxDSnBibVJsZUNJc0luTmxiR1lpTENKcGJtUmxlRTltSWl3aVpHbG1aaUlzSW5aaGJIVmxWRzhpTENKMllXeDFaVVp5YjIwaUxDSnJaWGxPWVcxbElpd2lhWE5QWW1wbFkzUWlMQ0oyWVd4MVpTSXNJa0Z5Y21GNUlpd2lhWE5CY25KaGVTSXNJbkIxYzJnaUxDSmthV1ptUVhKeVlYa2lMQ0pwYzFOcGJYQnNaU0lzSW1GeWNtRjVJaXdpWlhabGNua2lMQ0poWTNScGRtVkRiMjVtYVdjaUxDSmhZM1JwZG1WRWFXWm1JaXdpYzJGMlpXUkVhV1ptSWl3aWMyaHZkMUpsYzNSaGNuUlNaWEYxYVhKbFpDSXNJbU5vWVc1blpYTWlMQ0pwYzFWdWMyRjJaV1FpTENKblpYUkZiR1Z0Wlc1MFFubEpaQ0lzSW1ocFpHUmxiaUlzSW1admNtMWhkRlpoYkhWbElpd2lTbE5QVGlJc0luTjBjbWx1WjJsbWVTSXNJbkpsY0d4aFkyVkRhR2xzWkhKbGJpSXNJbTFoY0NJc0ltTm9ZVzVuWlNJc0ltTnNiMjVsVkdWdGNHeGhkR1VpTENKblpYUkhiRzlpWVd3aUxDSnpaWFJIYkc5aVlXd2lMQ0puWlhSQmNIQnNhV0Z1WTJVaUxDSm9ZV2xrSWl3aWMyVjBRWEJ3YkdsaGJtTmxJaXdpWlhod2IzSjBjeUpkTENKemIzVnlZMlZ6SWpwYklpNHVMeTR1THk0dUwzTnlZeTlvYjIxbFluSnBaR2RsTFhWcEwzQjFZbXhwWXk5amIyNW1hV2N1ZEhNaVhTd2ljMjkxY21ObGMwTnZiblJsYm5RaU9sdHVkV3hzWFN3aWJXRndjR2x1WjNNaU9pSTdPenM3T3p0QlFVOUJMRWxCUVVGQkxFMUJRVUVzUjBGQlFVTXNUMEZCUVR0QlFVVkJMRWxCUVVGRExGTkJRVUVzUjBGQlFVUXNUMEZCUVR0QlFVTkJMRWxCUVVGRkxGbEJRVUVzUjBGQlFVWXNUMEZCUVR0QlFWWkJPMEZCUTBFN08wRkJhMEpCTzBGQlEwMHNUVUZCVDBjc1RVRkJUVHRGUVdObU8wVkJRMEZETEZsQlFYRkNReXhIUVVGWExFVkJRMWhETEVkQlFXTTdTVUZFWkN4TFFVRkJSQ3hIUVVGSExFZEJRVWhCTEVkQlFVYzdTVUZEU0N4TFFVRkJReXhIUVVGSExFZEJRVWhCTEVkQlFVYzdTVUZZZUVJN1NVRkRRU3hMUVVGQlF5eE5RVUZOTEVkQlFXdERMRVZCUVVVN1NVRkRNVU1zUzBGQlFVTXNWVUZCVlN4SFFVRjVRaXhGUVVGRk8wbEJWV3BETEVsQlFVa3NRMEZCUTBNc1dVRkJXU3hIUVVGSkxFbEJRVWtzUTBGQlEwTXNVMEZCVXl4RlFVRkZPMGxCUTNKRExFbEJRVWtzUTBGQlEwTXNZVUZCWVN4SFFVRkhMRWxCUVVrc1EwRkJRME1zWlVGQlpTeEZRVUZGTzBWQlF5OURPMFZCUlVFN1JVRkRRU3hOUVVGTlJpeFRRVUZUUVN4RFFVRkJPMGxCUTFnN1NVRkRRU3hOUVVGTlJ5eFhRVUZYTEVkQlFVY3NUVUZCVFVNc1RVRkJUU3hEUVVGRFF5eFZRVUZWTEVOQlFVTkRMR1ZCUVdVc1JVRkJSVHRKUVVNM1JDeEpRVUZKU0N4WFFVRlhMRU5CUVVNc1EwRkJReXhEUVVGRExFdEJRVXRKTEZOQlFWTXNSVUZCUlR0TlFVTTVRaXhKUVVGSkxFTkJRVU5hTEVkQlFVY3NRMEZCUTJFc1NVRkJTU3hEUVVGRExHMUVRVUZ0UkN4RFFVRkRPMDFCUTJ4RkxFbEJRVWtzUTBGQlEwTXNWMEZCVnl4SFFVRkhPMUZCUVVWRExGRkJRVkVzUlVGQlJVNHNUVUZCVFN4RFFVRkRReXhWUVVGVkxFTkJRVU5OTEUxQlFVMHNRMEZCUTBNN1RVRkJWeXhEUVVGRk8wbEJRM3BGTEVOQlFVTXNUVUZCVFR0TlFVTklMRWxCUVVrc1EwRkJReXhIUVVGSFZDeFhRVUZYTEVOQlFVTlZMRTFCUVUwc1JVRkJSVHRSUVVONFFpeEpRVUZKTEVOQlFVTnNRaXhIUVVGSExFTkJRVU50UWl4TFFVRkxMRU5CUVVNc2MwSkJRWE5DV0N4WFFVRlhMRU5CUVVOVkxFMUJRVTBzZDBKQlFYZENMRVZCUVVWV0xGZEJRVmNzUTBGQlF6dFJRVU0zUmtNc1RVRkJUU3hEUVVGRFF5eFZRVUZWTEVOQlFVTlZMRXRCUVVzc1EwRkJRMFFzUzBGQlN5eERRVUZETEN0RVFVRXJSQ3hGUVVNdlJDd3JRa0ZCSzBJc1EwRkJRenROUVVOc1JUdE5RVU5CTEVsQlFVa3NRMEZCUTB3c1YwRkJWeXhIUVVGSFRpeFhRVUZYTEVOQlFVTXNRMEZCUXl4RFFVRkRPMDFCUTJwRExFbEJRVWtzUTBGQlEyRXNaVUZCWlN4RFFVRkRMRWxCUVVrc1EwRkJRMUFzVjBGQlZ5eERRVUZETzBsQlF6RkRPMGxCUlVFN1NVRkRRU3hOUVVGTlVTeHBRa0ZCYVVJc1IwRkJSeXhKUVVGQlF5eHRRa0ZCV1N4RlFVRkRReXh6UWtGQlV5eEZRVUZGUVN4elFrRkJVeXhEUVVGRFF5eFpRVUZaTEVOQlFVTTdTVUZEZWtVc1RVRkJUVU1zVFVGQlRTeEhRVUZKUXl4VFFVRjFSQ3hKUVVOdVJVTXNUVUZCVFN4RFFVRkRReXhYUVVGWExFTkJRVU5FTEUxQlFVMHNRMEZCUTBVc1QwRkJUeXhEUVVGRExFbEJRVWtzUTBGQlEyaENMRmRCUVZjc1NVRkJTU3hGUVVGRkxFTkJRVU1zUTBGQlEybENMRTFCUVUwc1EwRkJRMG9zVTBGQlV5eERRVUZETEVOQlFVTTdTVUZEYUVZc1NVRkJTU3hEUVVGRGVrSXNUVUZCVFN4SFFVRlBkMElzVFVGQlRTeERRVUZETEVOQlFVTXNRMEZCUTAwc1IwRkJSeXhEUVVGRExFdEJRVTFXTEdsQ1FVRnBRaXhEUVVGRFZ5eFJRVUZSTEVOQlFVTkVMRWRCUVVjc1EwRkJReXhEUVVFd1FqdEpRVU01Uml4SlFVRkpMRU5CUVVNM1FpeFZRVUZWTEVkQlFVZDFRaXhOUVVGTkxFTkJRVU1zUTBGQlF5eERRVUZEVFN4SFFVRkhMRU5CUVVNc1MwRkJTeXhEUVVGRFZpeHBRa0ZCYVVJc1EwRkJRMWNzVVVGQlVTeERRVUZEUkN4SFFVRkhMRU5CUVVNc1EwRkJjVUk3U1VGRGVrWXNTVUZCU1N4RFFVRkRhRU1zUjBGQlJ5eERRVUZEYTBNc1MwRkJTeXhEUVVGRExIRkRRVUZ4UXl4RlFVRkZMRWxCUVVrc1EwRkJRMmhETEUxQlFVMHNSVUZCUlN4SlFVRkpMRU5CUVVORExGVkJRVlVzUTBGQlF6dEpRVU51Uml4SlFVRkpMRU5CUVVOblF5eFJRVUZSTEVkQlFVY3NTVUZCU1N4RFFVRkRha01zVFVGQlRTeERRVUZETzBWQlEyaERPMFZCUlVFN1JVRkRRU3hOUVVGTlN5eGxRVUZsUVN4RFFVRkJPMGxCUTJwQ0xFbEJRVWs3VFVGRFFTeFBRVUZQTEUxQlFVMHNTVUZCU1N4RFFVRkRUaXhIUVVGSExFTkJRVU50UXl4UFFVRlBMRU5CUVVNc1UwRkJVeXhGUVVGRkxFbEJRVWtzUTBGQlF6dEpRVU5zUkN4RFFVRkRMRU5CUVVNc1RVRkJUVHROUVVOS0xFOUJRVThzUlVGQmIwSTdTVUZETDBJN1JVRkRTanRGUVVWQk8wVkJRMEVzVFVGQlRVTXNVMEZCVTBFc1EwRkJRME1zU1VGQlNTeEhRVUZITEV0QlFVczdTVUZEZUVJN1NVRkRRU3hOUVVGTlF5eE5RVUZOTEVkQlFVYzdUVUZCUlN4SFFVRkhMRWxCUVVrc1EwRkJRM0pETEUxQlFVMDdUVUZCUlN4SFFVRkhMRWxCUVVrc1EwRkJRME03U1VGQlZTeERRVUZGTzBsQlEzSkVMRWxCUVVrc1EwRkJRMGdzUjBGQlJ5eERRVUZEYTBNc1MwRkJTeXhEUVVGRExHRkJRV0ZKTEVsQlFVa3NTMEZCU3l4RlFVRkZReXhOUVVGTkxFTkJRVU03U1VGRk9VTTdTVUZEUVN4TlFVRk5PVUlzVFVGQlRTeERRVUZEUXl4VlFVRlZMRU5CUVVNNFFpeHJRa0ZCYTBJc1EwRkJReXhEUVVGRFJDeE5RVUZOTEVOQlFVTXNRMEZCUXp0SlFVTndSQ3hKUVVGSlJDeEpRVUZKTEVWQlFVVTdUVUZEVGl4TlFVRk5OMElzVFVGQlRTeERRVUZEUXl4VlFVRlZMRU5CUVVNclFpeG5Ra0ZCWjBJc1JVRkJSVHROUVVNeFF5eEpRVUZKTEVOQlFVTXpRaXhYUVVGWExFZEJRVWQ1UWl4TlFVRk5PMDFCUTNwQ0xFbEJRVWtzUTBGQlEzWkRMRWRCUVVjc1EwRkJRekJETEVsQlFVa3NRMEZCUXl3MFFrRkJORUlzUTBGQlF6dEpRVU12UXp0SlFVVkJPMGxCUTBFc1NVRkJTU3hEUVVGRGNrSXNaVUZCWlN4RFFVRkRhMElzVFVGQlRTeERRVUZETzBWQlEyaERPMFZCUlVFN1JVRkRRVWtzVlVGQlZVRXNRMEZCUTBNc1JVRkJWU3hGUVVGRlF5eEpRVUZaTEVWQlFVVkRMRk5CUVZNc1IwRkJSeXhGUVVGRk8wbEJReTlETEUxQlFVMURMRWxCUVVrc1IwRkJSeXhEUVVGRExFZEJRVWR1UWl4TlFVRk5MRU5CUVVOdFFpeEpRVUZKTEVOQlFVTklMRVZCUVVVc1EwRkJReXhGUVVGRkxFZEJRVWRvUWl4TlFVRk5MRU5CUVVOdFFpeEpRVUZKTEVOQlFVTkdMRWxCUVVrc1EwRkJReXhEUVVGRExFTkJRMnhFWkN4TlFVRk5MRU5CUVVNc1EwRkJRME1zUjBGQlJ5eEZRVUZGWjBJc1MwRkJTeXhGUVVGRlF5eEpRVUZKTEV0QlFVdEVMRXRCUVVzc1MwRkJTME1zU1VGQlNTeERRVUZEUXl4UFFVRlBMRU5CUVVOc1FpeEhRVUZITEVOQlFVTXNTVUZCU1VFc1IwRkJSeXhMUVVGTExGTkJRVk1zUTBGQlF6dEpRVU51Uml4TlFVRk5iVUlzU1VGQlNTeEhRVUZyUWl4RlFVRkZPMGxCUXpsQ0xFdEJRVXNzVFVGQlRXNUNMRWRCUVVjc1NVRkJTV1VzU1VGQlNTeEZRVUZGTzAxQlEzQkNMRTFCUVUxTExFOUJRVThzUjBGQlMxSXNSVUZCUlN4RFFVRkhXaXhIUVVGWkxFTkJRVU03VFVGRGNFTXNUVUZCVFhGQ0xGTkJRVk1zUjBGQlIxSXNTVUZCU1N4RFFVRkRZaXhIUVVGWkxFTkJRVU03VFVGRGNFTXNUVUZCVFhOQ0xFOUJRVThzUjBGQlJ5eEhRVUZIVWl4VFFVRlRMRWxCUVVsa0xFZEJRVWNzUlVGQlJUdE5RVU55UXl4TlFVRk5kVUlzVVVGQlVTeEhRVUZKUXl4TFFVRmpMRWxCUVdOQkxFdEJRVXNzUzBGQlN6VkRMRk5CUVZNc1NVRkJTU3hQUVVGUE5FTXNTMEZCU3l4TFFVRkxMRkZCUVZFN1RVRkRPVVlzU1VGQlNVTXNTMEZCU3l4RFFVRkRReXhQUVVGUExFTkJRVU5PTEU5QlFVOHNRMEZCUXl4SlFVRkpTeXhMUVVGTExFTkJRVU5ETEU5QlFVOHNRMEZCUTB3c1UwRkJVeXhEUVVGRExFVkJRVVZHTEVsQlFVa3NRMEZCUTFFc1NVRkJTU3hEUVVGRExFZEJRVWNzU1VGQlNTeERRVUZEUXl4VFFVRlRMRU5CUVVWU0xFOUJRVThzUlVGQlJVTXNVMEZCVXl4RlFVRkZReXhQUVVGUExFTkJRVU1zUTBGQlF5eERRVUZETEV0QlF6bEhMRWxCUVVsRExGRkJRVkVzUTBGQlEwZ3NUMEZCVHl4RFFVRkRMRWxCUVVsSExGRkJRVkVzUTBGQlEwWXNVMEZCVXl4RFFVRkRMRVZCUVU5R0xFbEJRVWtzUTBGQlExRXNTVUZCU1N4RFFVRkRMRWRCUVVjc1NVRkJTU3hEUVVGRGFFSXNWVUZCVlN4RFFVRkRVeXhQUVVGUExFVkJRVVZETEZOQlFWTXNSVUZCUlVNc1QwRkJUeXhEUVVGRExFTkJRVU1zUTBGQlF5eExRVU01Unl4SlFVRkpSaXhQUVVGUExFdEJRVXRETEZOQlFWTXNSVUZCUlVZc1NVRkJTU3hEUVVGRFVTeEpRVUZKTEVOQlFVTTdVVUZCUlROQ0xFZEJRVWNzUlVGQlJYTkNMRTlCUVU4N1VVRkJSVlFzU1VGQlNTeEZRVUZGVVN4VFFVRlRPMUZCUVVWVUxFVkJRVVVzUlVGQlJWRTdUVUZCVHl4RFFVRkZMRU5CUVVNN1NVRkROMFk3U1VGRFFTeFBRVUZQUkN4SlFVRkpPMFZCUTJZN1JVRkZRVHRGUVVOQlV5eFRRVUZUUVN4RFFVRkRhRUlzUlVGQllTeEZRVUZGUXl4SlFVRmxMRVZCUVVWRExGTkJRVk1zUjBGQlJ5eEZRVUZGTzBsQlEzQkVMRTFCUVUxbExGRkJRVkVzUjBGQlNVTXNTMEZCWjBJc1NVRkJZMEVzUzBGQlN5eERRVUZETlVNc1RVRkJUU3hMUVVGTExFTkJRVU1zU1VGQlNTeFBRVUZQTkVNc1MwRkJTeXhEUVVGRExFTkJRVU1zUTBGQlF5eExRVUZMTEZGQlFWRTdTVUZEYkVjc1NVRkJTVVFzVVVGQlVTeERRVUZEYWtJc1JVRkJSU3hEUVVGRExFbEJRVWxwUWl4UlFVRlJMRU5CUVVOb1FpeEpRVUZKTEVOQlFVTXNSVUZCUlR0TlFVTm9ReXhKUVVGSlJDeEZRVUZGTEVOQlFVTXhRaXhOUVVGTkxFdEJRVXN5UWl4SlFVRkpMRU5CUVVNelFpeE5RVUZOTEVsQlFVa3dRaXhGUVVGRkxFTkJRVU50UWl4TFFVRkxMRU5CUVVNc1EwRkJRMUFzUzBGQlN5eEZRVUZGVWl4TFFVRkxMRXRCUVV0UkxFdEJRVXNzUzBGQlMxZ3NTVUZCU1N4RFFVRkRSeXhMUVVGTExFTkJRVU1zUTBGQlF5eEZRVUZGTEU5QlFVOHNSVUZCUlN4RFFVRkRMRXRCUTNwR0xFOUJRVThzUTBGQlF6dFJRVUZGYUVJc1IwRkJSeXhGUVVGRll5eFRRVUZUTzFGQlFVVkVMRWxCUVVrN1VVRkJSVVE3VFVGQlJTeERRVUZGTEVOQlFVTTdTVUZET1VNc1EwRkJReXhOUVVGTk8wMUJRMGdzVDBGQlR5eEpRVUZKTEVOQlFVTkVMRlZCUVZVc1EwRkJRME1zUlVGQlJTeEZRVUZGUXl4SlFVRkpMRVZCUVVWRExGTkJRVk1zUTBGQlF6dEpRVU12UXp0RlFVTktPMFZCUlVFN1JVRkRRU3hOUVVGTmVrSXNaVUZCWlVFc1EwRkJRMnRDTEUxQlFXOUNPMGxCUTNSRE8wbEJRMEVzU1VGQlNTeERRVUZEV0N4TlFVRk5MRU5CUVVOdFFpeEpRVUZKTEVOQlFVTlNMRTFCUVUwc1EwRkJReXhEUVVGRGNrSXNUVUZCVFN4RlFVRkZPMGxCUldwRE8wbEJRMEVzVFVGQlRUaERMRmxCUVZrc1IwRkJSeXhOUVVGTkxFbEJRVWtzUTBGQlF6RkVMR0ZCUVdFN1NVRkROME1zVFVGQlRUSkVMRlZCUVZVc1IwRkJSeXhKUVVGSkxFTkJRVU4wUWl4VlFVRlZMRU5CUVVOS0xFMUJRVTBzUlVGQlJYbENMRmxCUVZrc1EwRkJRenRKUVVONFJDeE5RVUZOUlN4VFFVRlRMRWRCUVVjc1NVRkJTU3hEUVVGRGRrSXNWVUZCVlN4RFFVRkRTaXhOUVVGTkxFVkJRVVVzU1VGQlNTeERRVUZEZWtJc1YwRkJWeXhKUVVGSkxFVkJRVVVzUTBGQlF6dEpRVU5xUlN4SlFVRkpiVVFzVlVGQlZTeERRVUZETDBNc1RVRkJUU3hKUVVGSlowUXNVMEZCVXl4RFFVRkRhRVFzVFVGQlRTeEZRVUZGTzAxQlEzWkRMRWxCUVVrc1EwRkJRMnhDTEVkQlFVY3NRMEZCUTJ0RExFdEJRVXNzUTBGQlF5eDNRMEZCZDBNc1JVRkJSVXNzVFVGQlRTeEZRVUZGTUVJc1ZVRkJWU3hGUVVGRlF5eFRRVUZUTEVOQlFVTTdTVUZETTBZN1NVRkZRVHRKUVVOQkxFbEJRVWtzUTBGQlEwTXNiVUpCUVcxQ0xFTkJRVU5HTEZWQlFWVXNSVUZCUlN4RFFVRkRMRWRCUVVkRExGTkJRVk1zUTBGQlEyaEVMRTFCUVUwc1EwRkJRenRGUVVNNVJEdEZRVVZCTzBWQlEwRnBSQ3h0UWtGQmJVSkJMRU5CUVVORExFOUJRWEZDTEVWQlFVVkRMRk5CUVd0Q08wbEJRM3BFTzBsQlEwRXNTVUZCUVVNc2QwSkJRV01zUlVGQlF5eGhRVUZoTEVOQlFVTXNRMEZCUTBNc1RVRkJUU3hIUVVGSFNDeFBRVUZQTEVOQlFVTnNSQ3hOUVVGTkxFdEJRVXNzUTBGQlF5eEpRVUZKTEVOQlFVTnRSQ3hUUVVGVE8wbEJRM3BGTEVsQlFVRkRMSGRDUVVGakxFVkJRVU1zYlVKQlFXMUNMRU5CUVVNc1EwRkJSME1zVFVGQlRTeEhRVUZIUml4VFFVRlRPMGxCUTNoRUxFbEJRVUZETEhkQ1FVRmpMRVZCUVVNc2NVSkJRWEZDTEVOQlFVTXNRMEZCUTBNc1RVRkJUU3hIUVVGSExFTkJRVU5HTEZOQlFWTTdTVUZGZWtRN1NVRkRRU3hOUVVGTlJ5eFhRVUZYTEVkQlFVbG9RaXhMUVVGakxFbEJRV0ZwUWl4SlFVRkpMRU5CUVVORExGTkJRVk1zUTBGQlEyeENMRXRCUVVzc1JVRkJSU3hKUVVGSkxFVkJRVVVzUTBGQlF5eERRVUZETzBsQlF6bEZMRWxCUVVGakxIZENRVUZqTEVWQlFVTXNhMEpCUVd0Q0xFTkJRVU1zUTBGQlEwc3NaVUZCWlN4RFFVRkRMRWRCUVVkUUxFOUJRVThzUTBGQlExRXNSMEZCUnl4RFFVRkRReXhOUVVGTkxFbEJRM0JGTEVsQlFVRkRMSFZDUVVGaExFVkJRVU1zZDBKQlFYZENMRVZCUVVVN1RVRkRjRU01UXl4SFFVRkhMRVZCUVVzMlF5eE5RVUZOTEVOQlFVTTNReXhIUVVGSE8wMUJRMnhDWVN4SlFVRkpMRVZCUVVreVFpeFhRVUZYTEVOQlFVTkxMRTFCUVUwc1EwRkJRMmhETEVsQlFVa3NRMEZCUXp0TlFVTm9RMFFzUlVGQlJTeEZRVUZOTkVJc1YwRkJWeXhEUVVGRFN5eE5RVUZOTEVOQlFVTnFReXhGUVVGRk8wdEJRMmhETEVOQlFVTXNRMEZCUXl4RFFVRkRPMFZCUTFvN1JVRkZRVHRGUVVOQkxFMUJRVTF0UXl4VFFVRlRRU3hEUVVGQk8wbEJRMWdzVFVGQlRTeEpRVUZKTEVOQlFVTXpSU3haUVVGWk8wbEJRM1pDTEU5QlFVOHNTVUZCU1N4RFFVRkRSaXhOUVVGTk8wVkJRM1JDTzBWQlJVRTdSVUZEUVN4TlFVRk5PRVVzVTBGQlUwRXNRMEZCUTNwRExFMUJRVzlDTzBsQlEyaERMRWxCUVVrc1NVRkJTU3hEUVVGRFNTeFZRVUZWTEVOQlFVTktMRTFCUVUwc1JVRkJSU3hOUVVGTkxFbEJRVWtzUTBGQlEzZERMRk5CUVZNc1JVRkJSU3hEUVVGRExFTkJRVU0zUkN4TlFVRk5MRVZCUVVVN1RVRkRlRVFzU1VGQlNTeERRVUZEYkVJc1IwRkJSeXhEUVVGRGEwTXNTMEZCU3l4RFFVRkRMR1ZCUVdVc1JVRkJSVXNzVFVGQlRTeERRVUZETzAxQlEzWkRMRWxCUVVrc1EwRkJRM0pETEUxQlFVMHNSMEZCUjNGRExFMUJRVTA3VFVGRGNFSXNTVUZCU1N4RFFVRkRTaXhSUVVGUkxFZEJRVWRKTEUxQlFVMHNRMEZCUXp0TlFVTjJRaXhOUVVGTkxFbEJRVWtzUTBGQlEwWXNVMEZCVXl4RlFVRkZPMGxCUXpGQ08wVkJRMG83UlVGRlFUdEZRVU5CTEUxQlFVMDBReXhaUVVGWlFTeERRVUZEUXl4SlFVRlpPMGxCUXpOQ0xFMUJRVTBzU1VGQlNTeERRVUZET1VVc1dVRkJXVHRKUVVOMlFpeFBRVUZQTEVsQlFVa3NRMEZCUTBRc1ZVRkJWU3hEUVVGREswVXNTVUZCU1N4RFFVRkRMRWxCUVVrc1JVRkJSVHRGUVVOMFF6dEZRVVZCTzBWQlEwRXNUVUZCVFVNc1dVRkJXVUVzUTBGQlEwUXNTVUZCV1N4RlFVRkZNME1zVFVGQmRVSTdTVUZEY0VRc1NVRkJTU3hKUVVGSkxFTkJRVU5KTEZWQlFWVXNRMEZCUTBvc1RVRkJUU3hGUVVGRkxFMUJRVTBzU1VGQlNTeERRVUZETUVNc1dVRkJXU3hEUVVGRFF5eEpRVUZKTEVOQlFVTXNRMEZCUXl4RFFVRkRhRVVzVFVGQlRTeEZRVUZGTzAxQlF5OUVMRWxCUVVrc1EwRkJRMnhDTEVkQlFVY3NRMEZCUTJ0RExFdEJRVXNzUTBGQlF5eHBRa0ZCYVVKblJDeEpRVUZKTEZGQlFWRXNSVUZCUlRORExFMUJRVTBzUTBGQlF6dE5RVU55UkN4SlFVRkpMRU5CUVVOd1F5eFZRVUZWTEVOQlFVTXJSU3hKUVVGSkxFTkJRVU1zUjBGQlJ6TkRMRTFCUVUwN1RVRkRPVUlzVFVGQlRTeEpRVUZKTEVOQlFVTkdMRk5CUVZNc1JVRkJSVHRKUVVNeFFqdEZRVU5LT3p0QlFVTklLME1zVDBGQlFTeERRVUZCZEVZc1RVRkJRU3hIUVVGQlFTeE5RVUZCSWl3aWFXZHViM0psVEdsemRDSTZXMTE5IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLlRlbXBsYXRlRm9ybSA9IGV4cG9ydHMuR2xvYmFsRm9ybSA9IGV4cG9ydHMuRm9ybXMgPSBleHBvcnRzLkZvcm1JZCA9IGV4cG9ydHMuRm9ybSA9IGV4cG9ydHMuQXBwbGlhbmNlRm9ybSA9IHZvaWQgMDtcbnZhciBfdXRpbHNEb20gPSByZXF1aXJlKFwiLi91dGlscy1kb20uanNcIik7XG4vLyBIb21lYnJpZGdlIHBsdWdpbiBmb3IgSG9tZSBDb25uZWN0IGhvbWUgYXBwbGlhbmNlc1xuLy8gQ29weXJpZ2h0IMKpIDIwMjMtMjAyNSBBbGV4YW5kZXIgVGhvdWt5ZGlkZXNcblxuLy8gQSBjb25maWd1cmF0aW9uIGZvcm0gaGFuZGxlclxuY2xhc3MgRm9ybSB7XG4gIC8vIENyZWF0ZSBhIGNvbmZpZ3VyYXRpb24gZm9ybVxuICBjb25zdHJ1Y3Rvcihsb2cpIHtcbiAgICB0aGlzLmxvZyA9IGxvZztcbiAgfVxuICAvLyBSZXRyaWV2ZSBhbmQgZGlzcGxheSB0aGUgZm9ybVxuICBhc3luYyBjcmVhdGVGb3JtKCkge1xuICAgIC8vIFJldHJpZXZlIHRoZSBmb3JtIHNjaGVtYSBhbmQgZGF0YVxuICAgIGNvbnN0IHNjaGVtYSA9IGF3YWl0IHRoaXMuZ2V0U2NoZW1hKCk7XG4gICAgY29uc3QgZGF0YSA9IGF3YWl0IHRoaXMuZ2V0RGF0YSgpO1xuICAgIC8vIENyZWF0ZSB0aGUgZm9ybSAoYWRkaW5nIGhlYWRlciBhbmQgZm9vdGVyKVxuICAgIGNvbnN0IHBhdGNoZWRTY2hlbWEgPSB0aGlzLnBhdGNoU2NoZW1hKHNjaGVtYSk7XG4gICAgdGhpcy5sb2cuZGVidWcoJ2NyZWF0ZUZvcm0nLCBwYXRjaGVkU2NoZW1hLCBkYXRhKTtcbiAgICB0aGlzLmZvcm0gPSB3aW5kb3cuaG9tZWJyaWRnZS5jcmVhdGVGb3JtKHBhdGNoZWRTY2hlbWEsIGRhdGEpO1xuICAgIC8vIFJldHVybiBhbnkgY2hhbmdlcyB0byB0aGUgY29uZmlndXJhdGlvblxuICAgIHRoaXMuZm9ybS5vbkNoYW5nZShjb25maWcgPT4gdGhpcy5wdXREYXRhKGNvbmZpZykpO1xuICB9XG4gIC8vIEhpZGUgdGhlIGZvcm0gKGltcGxpY2l0bHkgY2FsbGVkIGlmIGEgZGlmZmVyZW50IGZvcm0gaXMgY3JlYXRlZClcbiAgZGVzdHJveUZvcm0oKSB7XG4gICAgdGhpcy5mb3JtPy5lbmQoKTtcbiAgICB0aGlzLmZvcm0gPSB1bmRlZmluZWQ7XG4gIH1cbiAgLy8gQWRkIGEgaGVhZGVyIGFuZCBmb290ZXIgdG8gdGhlIHNjaGVtYSBmb3JtXG4gIHBhdGNoU2NoZW1hKHNjaGVtYSkge1xuICAgIGNvbnN0IGZvcm0gPSBbLi4uKHNjaGVtYS5mb3JtID8/IFtdKSwgLi4udGhpcy5mb3JtRnJvbVRlbXBsYXRlKCdoYy1mb3JtLWZvb3RlcicpXTtcbiAgICByZXR1cm4ge1xuICAgICAgLi4uc2NoZW1hLFxuICAgICAgZm9ybVxuICAgIH07XG4gIH1cbiAgLy8gQ3JlYXRlIGEgZm9ybSBpdGVtIGZyb20gYSB0ZW1wbGF0ZVxuICBmb3JtRnJvbVRlbXBsYXRlKC4uLmFyZ3MpIHtcbiAgICBjb25zdCB0ZW1wbGF0ZSA9ICgwLCBfdXRpbHNEb20uY2xvbmVUZW1wbGF0ZSkoLi4uYXJncyk7XG4gICAgY29uc3QgYWJzVGVtcGxhdGUgPSAoMCwgX3V0aWxzRG9tLmVsZW1lbnRXaXRoQWJzb2x1dGVQYXRocykodGVtcGxhdGUpO1xuICAgIHJldHVybiB0aGlzLmZvcm1Gcm9tSFRNTChhYnNUZW1wbGF0ZSk7XG4gIH1cbiAgLy8gQ3JlYXRlIGEgZm9ybSBpdGVtIGZyb20gYW4gSFRNTCBlbGVtZW50XG4gIGZvcm1Gcm9tSFRNTChlbGVtZW50KSB7XG4gICAgcmV0dXJuIFt7XG4gICAgICB0eXBlOiAnaGVscCcsXG4gICAgICBoZWxwdmFsdWU6ICgwLCBfdXRpbHNEb20uZ2V0SFRNTCkoZWxlbWVudClcbiAgICB9XTtcbiAgfVxufVxuLy8gQSBnbG9iYWwgY29uZmlndXJhdGlvbiBmb3JtIGhhbmRsZXJcbmV4cG9ydHMuRm9ybSA9IEZvcm07XG5jbGFzcyBHbG9iYWxGb3JtIGV4dGVuZHMgRm9ybSB7XG4gIGNvbnN0cnVjdG9yKGxvZywgaXBjLCBjb25maWcpIHtcbiAgICBzdXBlcihsb2cpO1xuICAgIHRoaXMuaXBjID0gaXBjO1xuICAgIHRoaXMuY29uZmlnID0gY29uZmlnO1xuICB9XG4gIGdldFNjaGVtYSgpIHtcbiAgICByZXR1cm4gdGhpcy5pcGMucmVxdWVzdCgnL3NjaGVtYS9nbG9iYWwnLCBudWxsKTtcbiAgfVxuICBnZXREYXRhKCkge1xuICAgIHJldHVybiB0aGlzLmNvbmZpZy5nZXRHbG9iYWwoKTtcbiAgfVxuICBwdXREYXRhKGRhdGEpIHtcbiAgICByZXR1cm4gdGhpcy5jb25maWcuc2V0R2xvYmFsKGRhdGEpO1xuICB9XG59XG4vLyBBbiBjb25maWd1cmF0aW9uIGZvcm0gaGFuZGxlciBmb3IgYSBzcGVjaWZpYyBhcHBsaWFuY2VcbmV4cG9ydHMuR2xvYmFsRm9ybSA9IEdsb2JhbEZvcm07XG5jbGFzcyBBcHBsaWFuY2VGb3JtIGV4dGVuZHMgRm9ybSB7XG4gIGNvbnN0cnVjdG9yKGxvZywgaXBjLCBjb25maWcsIGhhaWQpIHtcbiAgICBzdXBlcihsb2cpO1xuICAgIHRoaXMuaXBjID0gaXBjO1xuICAgIHRoaXMuY29uZmlnID0gY29uZmlnO1xuICAgIHRoaXMuaGFpZCA9IGhhaWQ7XG4gIH1cbiAgZ2V0U2NoZW1hKCkge1xuICAgIHJldHVybiB0aGlzLmlwYy5yZXF1ZXN0KCcvc2NoZW1hL2FwcGxpYW5jZScsIHRoaXMuaGFpZCk7XG4gIH1cbiAgZ2V0RGF0YSgpIHtcbiAgICByZXR1cm4gdGhpcy5jb25maWcuZ2V0QXBwbGlhbmNlKHRoaXMuaGFpZCk7XG4gIH1cbiAgcHV0RGF0YShkYXRhKSB7XG4gICAgcmV0dXJuIHRoaXMuY29uZmlnLnNldEFwcGxpYW5jZSh0aGlzLmhhaWQsIGRhdGEpO1xuICB9XG59XG4vLyBBIHBsYWNlaG9sZGVyIGZvcm0gaGFuZGxlclxuZXhwb3J0cy5BcHBsaWFuY2VGb3JtID0gQXBwbGlhbmNlRm9ybTtcbmNsYXNzIFRlbXBsYXRlRm9ybSBleHRlbmRzIEZvcm0ge1xuICBjb25zdHJ1Y3Rvcihsb2csIC4uLmFyZ3MpIHtcbiAgICBzdXBlcihsb2cpO1xuICAgIHRoaXMuZWxlbWVudEFzRm9ybSA9IHRoaXMuZm9ybUZyb21UZW1wbGF0ZSguLi5hcmdzKTtcbiAgfVxuICAvLyBDcmVhdGUgYSBwbGFjZWhvbGRlciBzY2hlbWEgdXNpbmcgdGhlIHNwZWNpZmllZCBIVE1MIGVsZW1lbnRcbiAgYXN5bmMgZ2V0U2NoZW1hKCkge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoe1xuICAgICAgc2NoZW1hOiB7XG4gICAgICAgIHR5cGU6ICdvYmplY3QnLFxuICAgICAgICBwcm9wZXJ0aWVzOiB7fVxuICAgICAgfSxcbiAgICAgIGZvcm06IHRoaXMuZWxlbWVudEFzRm9ybVxuICAgIH0pO1xuICB9XG4gIGFzeW5jIGdldERhdGEoKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7fSk7XG4gIH1cbiAgYXN5bmMgcHV0RGF0YSgpIHt9XG59XG4vLyBJZGVudGlmaWVycyBmb3Igc3BlY2lhbCBmb3Jtc1xuZXhwb3J0cy5UZW1wbGF0ZUZvcm0gPSBUZW1wbGF0ZUZvcm07XG52YXIgRm9ybUlkO1xuKGZ1bmN0aW9uIChGb3JtSWQpIHtcbiAgRm9ybUlkW1wiR2xvYmFsXCJdID0gXCJnbG9iYWxcIjtcbiAgRm9ybUlkW1wiUGxhY2Vob2xkZXJcIl0gPSBcInBsYWNlaG9sZGVyXCI7XG4gIEZvcm1JZFtcIlVuYXZhaWxhYmxlXCJdID0gXCJ1bmF2YWlsYWJsZVwiO1xufSkoRm9ybUlkIHx8IChleHBvcnRzLkZvcm1JZCA9IEZvcm1JZCA9IHt9KSk7XG4vLyBUeXBlIGd1YXJkIHRvIGNoZWNrIHdoZXRoZXIgYSBzdHJpbmcgaXMgYSBzcGVjaWFsIGZvcm0gaWRlbnRpZmllclxuZnVuY3Rpb24gaXNGb3JtSWQodmFsdWUpIHtcbiAgcmV0dXJuIE9iamVjdC52YWx1ZXMoRm9ybUlkKS5pbmNsdWRlcyh2YWx1ZSk7XG59XG4vLyBNYW5hZ2UgdGhlIGNvbmZpZ3VyYXRpb24gZm9ybXNcbmNsYXNzIEZvcm1zIHtcbiAgLy8gQ3JlYXRlIGEgbmV3IGZvcm0gbWFuYWdlclxuICBjb25zdHJ1Y3Rvcihsb2csIGlwYywgY29uZmlnKSB7XG4gICAgdGhpcy5sb2cgPSBsb2c7XG4gICAgdGhpcy5pcGMgPSBpcGM7XG4gICAgdGhpcy5jb25maWcgPSBjb25maWc7XG4gICAgdGhpcy5zaG93Rm9ybSgpO1xuICB9XG4gIC8vIERpc3BsYXkgdGhlIHNwZWNpZmllZCBmb3JtIChkZWZhdWx0aW5nIHRvIHRoZSBwbGFjZWhvbGRlcilcbiAgYXN5bmMgc2hvd0Zvcm0oZm9ybUlkKSB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIFRoZSBmb3JtcyBhcmUgcmV0cmlldmVkIGZyb20gdGhlIHNlcnZlciwgc28gZGlzcGxheSBhIHNwaW5uZXJcbiAgICAgIHdpbmRvdy5ob21lYnJpZGdlLnNob3dTcGlubmVyKCk7XG4gICAgICAvLyBEaXNwbGF5IHRoZSByZXF1ZXN0ZWQgZm9ybSwgd2l0aCBmYWxsYmFjayB0byB0aGUgZXJyb3IgZm9ybVxuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdGhpcy5jb25zdHJ1Y3RBbmRTaG93Rm9ybShmb3JtSWQgPz8gRm9ybUlkLlBsYWNlaG9sZGVyKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICB0aGlzLmxvZy53YXJuKCdGYWlsZWQgdG8gZGlzcGxheSBmb3JtJywgZm9ybUlkLCBlcnIpO1xuICAgICAgICBhd2FpdCB0aGlzLmNvbnN0cnVjdEFuZFNob3dGb3JtKEZvcm1JZC5VbmF2YWlsYWJsZSk7XG4gICAgICB9XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIC8vIEVuc3VyZSB0aGF0IHRoZSBzcGlubmVyIGlzIGFsd2F5cyBoaWRkZW5cbiAgICAgIHdpbmRvdy5ob21lYnJpZGdlLmhpZGVTcGlubmVyKCk7XG4gICAgfVxuICB9XG4gIC8vIFRyeSB0byBjcmVhdGUgdGhlIHJlcXVlc3RlZCBmb3JtLCB3aXRoIGZhbGxiYWNrIHRvIHRoZSBwbGFjZWhvbGRlclxuICBhc3luYyBjb25zdHJ1Y3RBbmRTaG93Rm9ybShmb3JtSWQpIHtcbiAgICBjb25zdCBmb3JtID0gdGhpcy5jb25zdHJ1Y3RGb3JtKGZvcm1JZCk7XG4gICAgYXdhaXQgZm9ybS5jcmVhdGVGb3JtKCk7XG4gICAgdGhpcy5jdXJyZW50Rm9ybSA9IGZvcm07XG4gIH1cbiAgLy8gQ3JlYXRlIGEgc3BlY2lmaWMgZm9ybVxuICBjb25zdHJ1Y3RGb3JtKGZvcm1JZCkge1xuICAgIGlmIChpc0Zvcm1JZChmb3JtSWQpKSB7XG4gICAgICBzd2l0Y2ggKGZvcm1JZCkge1xuICAgICAgICBjYXNlIEZvcm1JZC5QbGFjZWhvbGRlcjpcbiAgICAgICAgICByZXR1cm4gbmV3IFRlbXBsYXRlRm9ybSh0aGlzLmxvZywgJ2hjLWZvcm0tcGxhY2Vob2xkZXInKTtcbiAgICAgICAgY2FzZSBGb3JtSWQuVW5hdmFpbGFibGU6XG4gICAgICAgICAgcmV0dXJuIG5ldyBUZW1wbGF0ZUZvcm0odGhpcy5sb2csICdoYy1mb3JtLXVuYXZhaWxhYmxlJyk7XG4gICAgICAgIGNhc2UgRm9ybUlkLkdsb2JhbDpcbiAgICAgICAgICByZXR1cm4gbmV3IEdsb2JhbEZvcm0odGhpcy5sb2csIHRoaXMuaXBjLCB0aGlzLmNvbmZpZyk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBuZXcgQXBwbGlhbmNlRm9ybSh0aGlzLmxvZywgdGhpcy5pcGMsIHRoaXMuY29uZmlnLCBmb3JtSWQpO1xuICAgIH1cbiAgfVxufVxuZXhwb3J0cy5Gb3JtcyA9IEZvcm1zO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ9dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p1WVcxbGN5STZXeUpmZFhScGJITkViMjBpTENKeVpYRjFhWEpsSWl3aVJtOXliU0lzSW1OdmJuTjBjblZqZEc5eUlpd2liRzluSWl3aVkzSmxZWFJsUm05eWJTSXNJbk5qYUdWdFlTSXNJbWRsZEZOamFHVnRZU0lzSW1SaGRHRWlMQ0puWlhSRVlYUmhJaXdpY0dGMFkyaGxaRk5qYUdWdFlTSXNJbkJoZEdOb1UyTm9aVzFoSWl3aVpHVmlkV2NpTENKbWIzSnRJaXdpZDJsdVpHOTNJaXdpYUc5dFpXSnlhV1JuWlNJc0ltOXVRMmhoYm1kbElpd2lZMjl1Wm1sbklpd2ljSFYwUkdGMFlTSXNJbVJsYzNSeWIzbEdiM0p0SWl3aVpXNWtJaXdpZFc1a1pXWnBibVZrSWl3aVptOXliVVp5YjIxVVpXMXdiR0YwWlNJc0ltRnlaM01pTENKMFpXMXdiR0YwWlNJc0ltTnNiMjVsVkdWdGNHeGhkR1VpTENKaFluTlVaVzF3YkdGMFpTSXNJbVZzWlcxbGJuUlhhWFJvUVdKemIyeDFkR1ZRWVhSb2N5SXNJbVp2Y20xR2NtOXRTRlJOVENJc0ltVnNaVzFsYm5RaUxDSjBlWEJsSWl3aWFHVnNjSFpoYkhWbElpd2laMlYwU0ZSTlRDSXNJbVY0Y0c5eWRITWlMQ0pIYkc5aVlXeEdiM0p0SWl3aWFYQmpJaXdpY21WeGRXVnpkQ0lzSW1kbGRFZHNiMkpoYkNJc0luTmxkRWRzYjJKaGJDSXNJa0Z3Y0d4cFlXNWpaVVp2Y20waUxDSm9ZV2xrSWl3aVoyVjBRWEJ3YkdsaGJtTmxJaXdpYzJWMFFYQndiR2xoYm1ObElpd2lWR1Z0Y0d4aGRHVkdiM0p0SWl3aVpXeGxiV1Z1ZEVGelJtOXliU0lzSWxCeWIyMXBjMlVpTENKeVpYTnZiSFpsSWl3aWNISnZjR1Z5ZEdsbGN5SXNJa1p2Y20xSlpDSXNJbWx6Um05eWJVbGtJaXdpZG1Gc2RXVWlMQ0pQWW1wbFkzUWlMQ0oyWVd4MVpYTWlMQ0pwYm1Oc2RXUmxjeUlzSWtadmNtMXpJaXdpYzJodmQwWnZjbTBpTENKbWIzSnRTV1FpTENKemFHOTNVM0JwYm01bGNpSXNJbU52Ym5OMGNuVmpkRUZ1WkZOb2IzZEdiM0p0SWl3aVVHeGhZMlZvYjJ4a1pYSWlMQ0psY25JaUxDSjNZWEp1SWl3aVZXNWhkbUZwYkdGaWJHVWlMQ0pvYVdSbFUzQnBibTVsY2lJc0ltTnZibk4wY25WamRFWnZjbTBpTENKamRYSnlaVzUwUm05eWJTSXNJa2RzYjJKaGJDSmRMQ0p6YjNWeVkyVnpJanBiSWk0dUx5NHVMeTR1TDNOeVl5OW9iMjFsWW5KcFpHZGxMWFZwTDNCMVlteHBZeTltYjNKdGN5NTBjeUpkTENKemIzVnlZMlZ6UTI5dWRHVnVkQ0k2VzI1MWJHeGRMQ0p0WVhCd2FXNW5jeUk2SWpzN096czdPMEZCVTBFc1NVRkJRVUVzVTBGQlFTeEhRVUZCUXl4UFFVRkJPMEZCVkVFN1FVRkRRVHM3UVVGVlFUdEJRVU5OTEUxQlFXZENReXhKUVVGSk8wVkJTM1JDTzBWQlEwRkRMRmxCUVhGQ1F5eEhRVUZYTzBsQlFWZ3NTMEZCUVVFc1IwRkJSeXhIUVVGSVFTeEhRVUZITzBWQlFWYzdSVUZYYmtNN1JVRkRRU3hOUVVGTlF5eFZRVUZWUVN4RFFVRkJPMGxCUTFvN1NVRkRRU3hOUVVGTlF5eE5RVUZOTEVkQlFVY3NUVUZCVFN4SlFVRkpMRU5CUVVORExGTkJRVk1zUlVGQlJUdEpRVU55UXl4TlFVRk5ReXhKUVVGSkxFZEJRVXNzVFVGQlRTeEpRVUZKTEVOQlFVTkRMRTlCUVU4c1JVRkJSVHRKUVVWdVF6dEpRVU5CTEUxQlFVMURMR0ZCUVdFc1IwRkJSeXhKUVVGSkxFTkJRVU5ETEZkQlFWY3NRMEZCUTB3c1RVRkJUU3hEUVVGRE8wbEJRemxETEVsQlFVa3NRMEZCUTBZc1IwRkJSeXhEUVVGRFVTeExRVUZMTEVOQlFVTXNXVUZCV1N4RlFVRkZSaXhoUVVGaExFVkJRVVZHTEVsQlFVa3NRMEZCUXp0SlFVTnFSQ3hKUVVGSkxFTkJRVU5MTEVsQlFVa3NSMEZCUjBNc1RVRkJUU3hEUVVGRFF5eFZRVUZWTEVOQlFVTldMRlZCUVZVc1EwRkJRMHNzWVVGQllTeEZRVUZGUml4SlFVRkpMRU5CUVVNN1NVRkZOMFE3U1VGRFFTeEpRVUZKTEVOQlFVTkxMRWxCUVVrc1EwRkJRMGNzVVVGQlVTeERRVUZEUXl4TlFVRk5MRWxCUVVrc1NVRkJTU3hEUVVGRFF5eFBRVUZQTEVOQlFVTkVMRTFCUVUwc1EwRkJReXhEUVVGRE8wVkJRM1JFTzBWQlJVRTdSVUZEUVVVc1YwRkJWMEVzUTBGQlFUdEpRVU5RTEVsQlFVa3NRMEZCUTA0c1NVRkJTU3hGUVVGRlR5eEhRVUZITEVWQlFVVTdTVUZEYUVJc1NVRkJTU3hEUVVGRFVDeEpRVUZKTEVkQlFVZFJMRk5CUVZNN1JVRkRla0k3UlVGRlFUdEZRVU5CVml4WFFVRlhRU3hEUVVGRFRDeE5RVUYzUWp0SlFVTm9ReXhOUVVGTlR5eEpRVUZKTEVkQlFVY3NRMEZEVkN4SlFVRkpVQ3hOUVVGTkxFTkJRVU5QTEVsQlFVa3NTVUZCU1N4RlFVRkZMRU5CUVVNc1JVRkRkRUlzUjBGQlJ5eEpRVUZKTEVOQlFVTlRMR2RDUVVGblFpeERRVUZETEdkQ1FVRm5RaXhEUVVGRExFTkJRemRETzBsQlEwUXNUMEZCVHp0TlFVRkZMRWRCUVVkb1FpeE5RVUZOTzAxQlFVVlBPMGxCUVVrc1EwRkJSVHRGUVVNNVFqdEZRVVZCTzBWQlEwRlRMR2RDUVVGblFrRXNRMEZCUXl4SFFVRkhReXhKUVVGelF6dEpRVU4wUkN4TlFVRk5ReXhSUVVGUkxFZEJRVWNzU1VGQlFVTXNkVUpCUVdFc1JVRkJReXhIUVVGSFJpeEpRVUZKTEVOQlFVTTdTVUZEZGtNc1RVRkJUVWNzVjBGQlZ5eEhRVUZITEVsQlFVRkRMR3REUVVGM1FpeEZRVUZEU0N4UlFVRlJMRU5CUVVNN1NVRkRkRVFzVDBGQlR5eEpRVUZKTEVOQlFVTkpMRmxCUVZrc1EwRkJRMFlzVjBGQlZ5eERRVUZETzBWQlEzcERPMFZCUlVFN1JVRkRRVVVzV1VGQldVRXNRMEZCUTBNc1QwRkJZVHRKUVVOMFFpeFBRVUZQTEVOQlFVTTdUVUZEU2tNc1NVRkJTU3hGUVVGUkxFMUJRVTA3VFVGRGJFSkRMRk5CUVZNc1JVRkJSeXhKUVVGQlF5eHBRa0ZCVHl4RlFVRkRTQ3hQUVVGUE8wdEJRemxDTEVOQlFVTTdSVUZEVGpzN1FVRkhTanRCUVVGQlNTeFBRVUZCTEVOQlFVRXZRaXhKUVVGQkxFZEJRVUZCTEVsQlFVRTdRVUZEVFN4TlFVRlBaME1zVlVGQlZ5eFRRVUZSYUVNc1NVRkJTVHRGUVVOb1EwTXNXVUZCV1VNc1IwRkJNRUlzUlVGRGFrSXJRaXhIUVVGdlFpeEZRVU53UW14Q0xFMUJRV2xDTzBsQlEyeERMRXRCUVVzc1EwRkJRMklzUjBGQlJ5eERRVUZETzBsQlJrOHNTMEZCUVN0Q0xFZEJRVWNzUjBGQlNFRXNSMEZCUnp0SlFVTklMRXRCUVVGc1FpeE5RVUZOTEVkQlFVNUJMRTFCUVUwN1JVRkZNMEk3UlVGRlFWWXNVMEZCVTBFc1EwRkJRVHRKUVVGeFF5eFBRVUZQTEVsQlFVa3NRMEZCUXpSQ0xFZEJRVWNzUTBGQlEwTXNUMEZCVHl4RFFVRkRMR2RDUVVGblFpeEZRVUZGTEVsQlFVa3NRMEZCUXp0RlFVRkZPMFZCUXk5R00wSXNUMEZCVDBFc1EwRkJRVHRKUVVGMVF5eFBRVUZQTEVsQlFVa3NRMEZCUTFFc1RVRkJUU3hEUVVGRGIwSXNVMEZCVXl4RlFVRkZPMFZCUVVVN1JVRkRPVVZ1UWl4UFFVRlBRU3hEUVVGRFZpeEpRVUZyUWp0SlFVRnZRaXhQUVVGUExFbEJRVWtzUTBGQlExTXNUVUZCVFN4RFFVRkRjVUlzVTBGQlV5eERRVUZET1VJc1NVRkJiMElzUTBGQlF6dEZRVUZGT3p0QlFVZDBSenRCUVVGQmVVSXNUMEZCUVN4RFFVRkJReXhWUVVGQkxFZEJRVUZCTEZWQlFVRTdRVUZEVFN4TlFVRlBTeXhoUVVGakxGTkJRVkZ5UXl4SlFVRkpPMFZCUTI1RFF5eFpRVUZaUXl4SFFVRXdRaXhGUVVOcVFpdENMRWRCUVc5Q0xFVkJRM0JDYkVJc1RVRkJhVUlzUlVGRGFrSjFRaXhKUVVGcFFqdEpRVU5zUXl4TFFVRkxMRU5CUVVOd1F5eEhRVUZITEVOQlFVTTdTVUZJVHl4TFFVRkJLMElzUjBGQlJ5eEhRVUZJUVN4SFFVRkhPMGxCUTBnc1MwRkJRV3hDTEUxQlFVMHNSMEZCVGtFc1RVRkJUVHRKUVVOT0xFdEJRVUYxUWl4SlFVRkpMRWRCUVVwQkxFbEJRVWs3UlVGRmVrSTdSVUZGUVdwRExGTkJRVk5CTEVOQlFVRTdTVUZCY1VNc1QwRkJUeXhKUVVGSkxFTkJRVU0wUWl4SFFVRkhMRU5CUVVORExFOUJRVThzUTBGQlF5eHRRa0ZCYlVJc1JVRkJSU3hKUVVGSkxFTkJRVU5KTEVsQlFVa3NRMEZCUXp0RlFVRkZPMFZCUTNaSEwwSXNUMEZCVDBFc1EwRkJRVHRKUVVGMVF5eFBRVUZQTEVsQlFVa3NRMEZCUTFFc1RVRkJUU3hEUVVGRGQwSXNXVUZCV1N4RFFVRkRMRWxCUVVrc1EwRkJRMFFzU1VGQlNTeERRVUZETzBWQlFVVTdSVUZETVVaMFFpeFBRVUZQUVN4RFFVRkRWaXhKUVVGclFqdEpRVUZ2UWl4UFFVRlBMRWxCUVVrc1EwRkJRMU1zVFVGQlRTeERRVUZEZVVJc1dVRkJXU3hEUVVGRExFbEJRVWtzUTBGQlEwWXNTVUZCU1N4RlFVRkZhRU1zU1VGQlNTeERRVUZETzBWQlFVVTdPMEZCUjNCSE8wRkJRVUY1UWl4UFFVRkJMRU5CUVVGTkxHRkJRVUVzUjBGQlFVRXNZVUZCUVR0QlFVTk5MRTFCUVU5SkxGbEJRV0VzVTBGQlVYcERMRWxCUVVrN1JVRkpiRU5ETEZsQlFWbERMRWRCUVd0Q0xFVkJRMnhDTEVkQlFVZHRRaXhKUVVGNVF6dEpRVU53UkN4TFFVRkxMRU5CUVVOdVFpeEhRVUZITEVOQlFVTTdTVUZEVml4SlFVRkpMRU5CUVVOM1F5eGhRVUZoTEVkQlFVY3NTVUZCU1N4RFFVRkRkRUlzWjBKQlFXZENMRU5CUVVNc1IwRkJSME1zU1VGQlNTeERRVUZETzBWQlEzWkVPMFZCUlVFN1JVRkRRU3hOUVVGTmFFSXNVMEZCVTBFc1EwRkJRVHRKUVVOWUxFOUJRVTl6UXl4UFFVRlBMRU5CUVVORExFOUJRVThzUTBGQlF6dE5RVU51UW5oRExFMUJRVTBzUlVGQlJUdFJRVU5LZDBJc1NVRkJTU3hGUVVGRkxGRkJRVkU3VVVGRFpHbENMRlZCUVZVc1JVRkJSVHRQUVVObU8wMUJRMFJzUXl4SlFVRkpMRVZCUVVrc1NVRkJTU3hEUVVGREswSTdTMEZEYUVJc1EwRkJRenRGUVVOT08wVkJSVUVzVFVGQlRXNURMRTlCUVU5QkxFTkJRVUU3U1VGQk5rSXNUMEZCVDI5RExFOUJRVThzUTBGQlEwTXNUMEZCVHl4RFFVRkRMRVZCUVVVc1EwRkJRenRGUVVGRk8wVkJRM1JGTEUxQlFVMDFRaXhQUVVGUFFTeERRVUZCTEVkQlFYbERPenRCUVVjeFJEdEJRVUZCWlN4UFFVRkJMRU5CUVVGVkxGbEJRVUVzUjBGQlFVRXNXVUZCUVR0QlFVTkJMRWxCUVZsTExFMUJTVmc3UVVGS1JDeFhRVUZaUVN4TlFVRk5PMFZCUTJSQkxFMUJRVUVzY1VKQlFYTkNPMFZCUTNSQ1FTeE5RVUZCTEN0Q1FVRXlRanRGUVVNelFrRXNUVUZCUVN3clFrRkJNa0k3UVVGREwwSXNRMEZCUXl4RlFVcFhRU3hOUVVGTkxFdEJRVUZtTEU5QlFVRXNRMEZCUVdVc1RVRkJRU3hIUVVGT1FTeE5RVUZOTzBGQlRXeENPMEZCUTBFc1UwRkJVME1zVVVGQlVVRXNRMEZCUTBNc1MwRkJZVHRGUVVNelFpeFBRVUZQUXl4TlFVRk5MRU5CUVVORExFMUJRVTBzUTBGQlEwb3NUVUZCVFN4RFFVRkRMRU5CUVVOTExGRkJRVkVzUTBGQlEwZ3NTMEZCWlN4RFFVRkRPMEZCUXpGRU8wRkJSVUU3UVVGRFRTeE5RVUZQU1N4TFFVRkxPMFZCUzJRN1JVRkRRVzVFTEZsQlFYRkNReXhIUVVGcFFpeEZRVU5xUWl0Q0xFZEJRVzlDTEVWQlEzQkNiRUlzVFVGQmFVSTdTVUZHYWtJc1MwRkJRV0lzUjBGQlJ5eEhRVUZJUVN4SFFVRkhPMGxCUTBnc1MwRkJRU3RDTEVkQlFVY3NSMEZCU0VFc1IwRkJSenRKUVVOSUxFdEJRVUZzUWl4TlFVRk5MRWRCUVU1QkxFMUJRVTA3U1VGRGRrSXNTVUZCU1N4RFFVRkRjME1zVVVGQlVTeEZRVUZGTzBWQlEyNUNPMFZCUlVFN1JVRkRRU3hOUVVGTlFTeFJRVUZSUVN4RFFVRkRReXhOUVVGbE8wbEJRekZDTEVsQlFVazdUVUZEUVR0TlFVTkJNVU1zVFVGQlRTeERRVUZEUXl4VlFVRlZMRU5CUVVNd1F5eFhRVUZYTEVWQlFVVTdUVUZGTDBJN1RVRkRRU3hKUVVGSk8xRkJRMEVzVFVGQlRTeEpRVUZKTEVOQlFVTkRMRzlDUVVGdlFpeERRVUZEUml4TlFVRk5MRWxCUVVsU0xFMUJRVTBzUTBGQlExY3NWMEZCVnl4RFFVRkRPMDFCUTJwRkxFTkJRVU1zUTBGQlF5eFBRVUZQUXl4SFFVRkhMRVZCUVVVN1VVRkRWaXhKUVVGSkxFTkJRVU40UkN4SFFVRkhMRU5CUVVONVJDeEpRVUZKTEVOQlFVTXNkMEpCUVhkQ0xFVkJRVVZNTEUxQlFVMHNSVUZCUlVrc1IwRkJSeXhEUVVGRE8xRkJRM0JFTEUxQlFVMHNTVUZCU1N4RFFVRkRSaXh2UWtGQmIwSXNRMEZCUTFZc1RVRkJUU3hEUVVGRFl5eFhRVUZYTEVOQlFVTTdUVUZEZGtRN1NVRkRTaXhEUVVGRExGTkJRVkU3VFVGRFREdE5RVU5CYUVRc1RVRkJUU3hEUVVGRFF5eFZRVUZWTEVOQlFVTm5SQ3hYUVVGWExFVkJRVVU3U1VGRGJrTTdSVUZEU2p0RlFVVkJPMFZCUTBFc1RVRkJUVXdzYjBKQlFXOUNRU3hEUVVGRFJpeE5RVUZqTzBsQlEzSkRMRTFCUVUwelF5eEpRVUZKTEVkQlFVY3NTVUZCU1N4RFFVRkRiVVFzWVVGQllTeERRVUZEVWl4TlFVRk5MRU5CUVVNN1NVRkRka01zVFVGQlRUTkRMRWxCUVVrc1EwRkJRMUlzVlVGQlZTeEZRVUZGTzBsQlEzWkNMRWxCUVVrc1EwRkJRelJFTEZkQlFWY3NSMEZCUjNCRUxFbEJRVWs3UlVGRE0wSTdSVUZGUVR0RlFVTkJiVVFzWVVGQllVRXNRMEZCUTFJc1RVRkJZenRKUVVONFFpeEpRVUZKVUN4UlFVRlJMRU5CUVVOUExFMUJRVTBzUTBGQlF5eEZRVUZGTzAxQlEyeENMRkZCUVZGQkxFMUJRVTA3VVVGRFpDeExRVUZMVWl4TlFVRk5MRU5CUVVOWExGZEJRVmM3VlVGQlJTeFBRVUZQTEVsQlFVbG9RaXhaUVVGWkxFTkJRVVVzU1VGQlNTeERRVUZEZGtNc1IwRkJSeXhGUVVGRkxIRkNRVUZ4UWl4RFFVRkRPMUZCUTJ4R0xFdEJRVXMwUXl4TlFVRk5MRU5CUVVOakxGZEJRVmM3VlVGQlJTeFBRVUZQTEVsQlFVbHVRaXhaUVVGWkxFTkJRVVVzU1VGQlNTeERRVUZEZGtNc1IwRkJSeXhGUVVGRkxIRkNRVUZ4UWl4RFFVRkRPMUZCUTJ4R0xFdEJRVXMwUXl4TlFVRk5MRU5CUVVOclFpeE5RVUZOTzFWQlFVOHNUMEZCVHl4SlFVRkphRU1zVlVGQlZTeERRVUZKTEVsQlFVa3NRMEZCUXpsQ0xFZEJRVWNzUlVGQlJTeEpRVUZKTEVOQlFVTXJRaXhIUVVGSExFVkJRVVVzU1VGQlNTeERRVUZEYkVJc1RVRkJUU3hEUVVGRE8wMUJRMnhHTzBsQlEwb3NRMEZCUXl4TlFVRk5PMDFCUTBnc1QwRkJUeXhKUVVGSmMwSXNZVUZCWVN4RFFVRkRMRWxCUVVrc1EwRkJRMjVETEVkQlFVY3NSVUZCUlN4SlFVRkpMRU5CUVVNclFpeEhRVUZITEVWQlFVVXNTVUZCU1N4RFFVRkRiRUlzVFVGQlRTeEZRVUZGZFVNc1RVRkJUU3hEUVVGRE8wbEJRM0pGTzBWQlEwbzdPMEZCUTBoMlFpeFBRVUZCTEVOQlFVRnhRaXhMUVVGQkxFZEJRVUZCTEV0QlFVRWlMQ0pwWjI1dmNtVk1hWE4wSWpwYlhYMD0iLCJcInVzZSBzdHJpY3RcIjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuU2VydmVyTG9nZ2VyID0gZXhwb3J0cy5Db25zb2xlTG9nZ2VyID0gZXhwb3J0cy5DbGllbnRMb2dnZXIgPSB2b2lkIDA7XG4vLyBIb21lYnJpZGdlIHBsdWdpbiBmb3IgSG9tZSBDb25uZWN0IGhvbWUgYXBwbGlhbmNlc1xuLy8gQ29weXJpZ2h0IMKpIDIwMjMtMjAyNSBBbGV4YW5kZXIgVGhvdWt5ZGlkZXNcbi8vIFByZWZpeCBmb3IgY2xpZW50IGFuZCBzZXJ2ZXIgbG9nIG1lc3NhZ2VzXG5jb25zdCBQTFVHSU5fUFJFRklYID0gd2luZG93LmhvbWVicmlkZ2UucGx1Z2luLmRpc3BsYXlOYW1lID8/IHdpbmRvdy5ob21lYnJpZGdlLnBsdWdpbi5uYW1lO1xuLy8gQSBsb2dnZXIgdGhhdCBzZW5kcyBtZXNzYWdlcyB0byB0aGUgZGVidWdnaW5nIGNvbnNvbGVcbmNsYXNzIENvbnNvbGVMb2dnZXIge1xuICAvLyBDcmVhdGUgYSBuZXcgY29uc29sZSBsb2dnZXJcbiAgY29uc3RydWN0b3IocHJlZml4ID0gJycpIHtcbiAgICB0aGlzLnByZWZpeCA9IHByZWZpeDtcbiAgfVxuICAvLyBTaW1wbGUgd3JhcHBlcnMgdG8gbG9nIGEgbWVzc2FnZVxuICBlcnJvcihtZXNzYWdlLCAuLi5wYXJhbXMpIHtcbiAgICB0aGlzLmxvZyhcImVycm9yXCIgLyogTG9nTGV2ZWwuRVJST1IgKi8sIG1lc3NhZ2UsIC4uLnBhcmFtcyk7XG4gIH1cbiAgd2FybihtZXNzYWdlLCAuLi5wYXJhbXMpIHtcbiAgICB0aGlzLmxvZyhcIndhcm5cIiAvKiBMb2dMZXZlbC5XQVJOICovLCBtZXNzYWdlLCAuLi5wYXJhbXMpO1xuICB9XG4gIHN1Y2Nlc3MobWVzc2FnZSwgLi4ucGFyYW1zKSB7XG4gICAgdGhpcy5sb2coXCJzdWNjZXNzXCIgLyogTG9nTGV2ZWwuU1VDQ0VTUyAqLywgbWVzc2FnZSwgLi4ucGFyYW1zKTtcbiAgfVxuICBpbmZvKG1lc3NhZ2UsIC4uLnBhcmFtcykge1xuICAgIHRoaXMubG9nKFwiaW5mb1wiIC8qIExvZ0xldmVsLklORk8gKi8sIG1lc3NhZ2UsIC4uLnBhcmFtcyk7XG4gIH1cbiAgZGVidWcobWVzc2FnZSwgLi4ucGFyYW1zKSB7XG4gICAgdGhpcy5sb2coXCJkZWJ1Z1wiIC8qIExvZ0xldmVsLkRFQlVHICovLCBtZXNzYWdlLCAuLi5wYXJhbXMpO1xuICB9XG4gIC8vIExvZyBhIG1lc3NhZ2UgYXQgdGhlIHNwZWNpZmllZCBsZXZlbFxuICBsb2cobGV2ZWwsIG1lc3NhZ2UsIC4uLnBhcmFtcykge1xuICAgIC8vIEFkZCB0aGUgcHJlZml4IHRvIHRoZSBtZXNzYWdlXG4gICAgaWYgKHRoaXMucHJlZml4Lmxlbmd0aCkgbWVzc2FnZSA9IGBbJHt0aGlzLnByZWZpeH1dICR7bWVzc2FnZX1gO1xuICAgIC8vIExvZyB0aGUgbWVzc2FnZVxuICAgIHN3aXRjaCAobGV2ZWwpIHtcbiAgICAgIGNhc2UgXCJlcnJvclwiIC8qIExvZ0xldmVsLkVSUk9SICovOlxuICAgICAgICBjb25zb2xlLmVycm9yKG1lc3NhZ2UsIC4uLnBhcmFtcyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBcIndhcm5cIiAvKiBMb2dMZXZlbC5XQVJOICovOlxuICAgICAgICBjb25zb2xlLndhcm4obWVzc2FnZSwgLi4ucGFyYW1zKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFwic3VjY2Vzc1wiIC8qIExvZ0xldmVsLlNVQ0NFU1MgKi86XG4gICAgICAgIGNvbnNvbGUuaW5mbyhtZXNzYWdlLCAuLi5wYXJhbXMpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgXCJpbmZvXCIgLyogTG9nTGV2ZWwuSU5GTyAqLzpcbiAgICAgICAgY29uc29sZS5pbmZvKG1lc3NhZ2UsIC4uLnBhcmFtcyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBcImRlYnVnXCIgLyogTG9nTGV2ZWwuREVCVUcgKi86XG4gICAgICAgIGNvbnNvbGUuZGVidWcobWVzc2FnZSwgLi4ucGFyYW1zKTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG59XG4vLyBMb2dnZXIgZm9yIGxvY2FsbHkgZ2VuZXJhdGVkIG1lc3NhZ2VzXG5leHBvcnRzLkNvbnNvbGVMb2dnZXIgPSBDb25zb2xlTG9nZ2VyO1xuY2xhc3MgQ2xpZW50TG9nZ2VyIGV4dGVuZHMgQ29uc29sZUxvZ2dlciB7XG4gIC8vIENyZWF0ZSBhIG5ldyBjbGllbnQgbG9nZ2VyXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKGAke1BMVUdJTl9QUkVGSVh9IGNsaWVudGApO1xuICB9XG59XG4vLyBMb2dnZXIgdGhhdCByZWNlaXZlcyBtZXNzYWdlcyBldmVudHMgZnJvbSB0aGUgc2VydmVyXG5leHBvcnRzLkNsaWVudExvZ2dlciA9IENsaWVudExvZ2dlcjtcbmNsYXNzIFNlcnZlckxvZ2dlciBleHRlbmRzIENvbnNvbGVMb2dnZXIge1xuICAvLyBDcmVhdGUgYSBuZXcgc2VydmVyIGxvZ2dlclxuICBjb25zdHJ1Y3RvcihpcGMsIG1pbkxldmVsKSB7XG4gICAgc3VwZXIoYCR7UExVR0lOX1BSRUZJWH0gc2VydmVyYCk7XG4gICAgdGhpcy5pcGMgPSBpcGM7XG4gICAgLy8gU3RhcnQgcmVjZWl2aW5nIGxvZyBldmVudHNcbiAgICBpcGMub25FdmVudCgnbG9nJywgbWVzc2FnZXMgPT4ge1xuICAgICAgdGhpcy5sb2dNZXNzYWdlcyhtZXNzYWdlcyk7XG4gICAgfSk7XG4gICAgdHJ5IHtcbiAgICAgIGlwYy5yZXF1ZXN0KCcvbG9nJywgbWluTGV2ZWwpO1xuICAgIH0gY2F0Y2ggey8qIGVtcHR5ICovfVxuICB9XG4gIC8vIExvZyBtZXNzYWdlcyByZWNlaXZlZCBmcm9tIHRoZSBzZXJ2ZXJcbiAgbG9nTWVzc2FnZXMobWVzc2FnZXMpIHtcbiAgICBmb3IgKGNvbnN0IHtcbiAgICAgIGxldmVsLFxuICAgICAgbWVzc2FnZSxcbiAgICAgIHBhcmFtc1xuICAgIH0gb2YgbWVzc2FnZXMpIHRoaXMubG9nKGxldmVsLCBtZXNzYWdlLCAuLi5wYXJhbXMpO1xuICB9XG59XG5leHBvcnRzLlNlcnZlckxvZ2dlciA9IFNlcnZlckxvZ2dlcjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRhdGE6YXBwbGljYXRpb24vanNvbjtjaGFyc2V0PXV0Zi04O2Jhc2U2NCxleUoyWlhKemFXOXVJam96TENKdVlXMWxjeUk2V3lKUVRGVkhTVTVmVUZKRlJrbFlJaXdpZDJsdVpHOTNJaXdpYUc5dFpXSnlhV1JuWlNJc0luQnNkV2RwYmlJc0ltUnBjM0JzWVhsT1lXMWxJaXdpYm1GdFpTSXNJa052Ym5OdmJHVk1iMmRuWlhJaUxDSmpiMjV6ZEhKMVkzUnZjaUlzSW5CeVpXWnBlQ0lzSW1WeWNtOXlJaXdpYldWemMyRm5aU0lzSW5CaGNtRnRjeUlzSW14dlp5SXNJbmRoY200aUxDSnpkV05qWlhOeklpd2lhVzVtYnlJc0ltUmxZblZuSWl3aWJHVjJaV3dpTENKc1pXNW5kR2dpTENKamIyNXpiMnhsSWl3aVpYaHdiM0owY3lJc0lrTnNhV1Z1ZEV4dloyZGxjaUlzSWxObGNuWmxja3h2WjJkbGNpSXNJbWx3WXlJc0ltMXBia3hsZG1Wc0lpd2liMjVGZG1WdWRDSXNJbTFsYzNOaFoyVnpJaXdpYkc5blRXVnpjMkZuWlhNaUxDSnlaWEYxWlhOMElsMHNJbk52ZFhKalpYTWlPbHNpTGk0dkxpNHZMaTR2YzNKakwyaHZiV1ZpY21sa1oyVXRkV2t2Y0hWaWJHbGpMMnh2WjJkbGNpNTBjeUpkTENKemIzVnlZMlZ6UTI5dWRHVnVkQ0k2VzI1MWJHeGRMQ0p0WVhCd2FXNW5jeUk2SWpzN096czdPMEZCUVVFN1FVRkRRVHRCUVU5Qk8wRkJRMEVzVFVGQlRVRXNZVUZCWVN4SFFVRkhReXhOUVVGTkxFTkJRVU5ETEZWQlFWVXNRMEZCUTBNc1RVRkJUU3hEUVVGRFF5eFhRVUZYTEVsQlFVbElMRTFCUVUwc1EwRkJRME1zVlVGQlZTeERRVUZEUXl4TlFVRk5MRU5CUVVORkxFbEJRVWs3UVVGRk0wWTdRVUZEVFN4TlFVRlBReXhoUVVGaE8wVkJSWFJDTzBWQlEwRkRMRmxCUVhGQ1F5eE5RVUZCTEVkQlFWTXNSVUZCUlR0SlFVRllMRXRCUVVGQkxFMUJRVTBzUjBGQlRrRXNUVUZCVFR0RlFVRlJPMFZCUlc1RE8wVkJRMEZETEV0QlFVdEJMRU5CUVVkRExFOUJRV1VzUlVGQlJTeEhRVUZIUXl4TlFVRnBRanRKUVVGVkxFbEJRVWtzUTBGQlEwTXNSMEZCUnl3clFrRkJiVUpHTEU5QlFVOHNSVUZCUlN4SFFVRkhReXhOUVVGTkxFTkJRVU03UlVGQlJUdEZRVU4yUjBVc1NVRkJTVUVzUTBGQlNVZ3NUMEZCWlN4RlFVRkZMRWRCUVVkRExFMUJRV2xDTzBsQlFWVXNTVUZCU1N4RFFVRkRReXhIUVVGSExEWkNRVUZ0UWtZc1QwRkJUeXhGUVVGRkxFZEJRVWRETEUxQlFVMHNRMEZCUXp0RlFVRkZPMFZCUTNaSFJ5eFBRVUZQUVN4RFFVRkRTaXhQUVVGbExFVkJRVVVzUjBGQlIwTXNUVUZCYVVJN1NVRkJWU3hKUVVGSkxFTkJRVU5ETEVkQlFVY3NiVU5CUVcxQ1JpeFBRVUZQTEVWQlFVVXNSMEZCUjBNc1RVRkJUU3hEUVVGRE8wVkJRVVU3UlVGRGRrZEpMRWxCUVVsQkxFTkJRVWxNTEU5QlFXVXNSVUZCUlN4SFFVRkhReXhOUVVGcFFqdEpRVUZWTEVsQlFVa3NRMEZCUTBNc1IwRkJSeXcyUWtGQmJVSkdMRTlCUVU4c1JVRkJSU3hIUVVGSFF5eE5RVUZOTEVOQlFVTTdSVUZCUlR0RlFVTjJSMHNzUzBGQlMwRXNRMEZCUjA0c1QwRkJaU3hGUVVGRkxFZEJRVWRETEUxQlFXbENPMGxCUVZVc1NVRkJTU3hEUVVGRFF5eEhRVUZITEN0Q1FVRnRRa1lzVDBGQlR5eEZRVUZGTEVkQlFVZERMRTFCUVUwc1EwRkJRenRGUVVGRk8wVkJSM1pITzBWQlEwRkRMRWRCUVVkQkxFTkJRVU5MTEV0QlFXVXNSVUZCUlZBc1QwRkJaU3hGUVVGRkxFZEJRVWRETEUxQlFXbENPMGxCUTNSRU8wbEJRMEVzU1VGQlNTeEpRVUZKTEVOQlFVTklMRTFCUVUwc1EwRkJRMVVzVFVGQlRTeEZRVUZGVWl4UFFVRlBMRWRCUVVjc1NVRkJTU3hKUVVGSkxFTkJRVU5HTEUxQlFVMHNTMEZCUzBVc1QwRkJUeXhGUVVGRk8wbEJSUzlFTzBsQlEwRXNVVUZCVVU4c1MwRkJTenROUVVOaU8xRkJRWFZDUlN4UFFVRlBMRU5CUVVOV0xFdEJRVXNzUTBGQlIwTXNUMEZCVHl4RlFVRkZMRWRCUVVkRExFMUJRVTBzUTBGQlF6dFJRVUZGTzAxQlF6VkVPMUZCUVhWQ1VTeFBRVUZQTEVOQlFVTk9MRWxCUVVrc1EwRkJTVWdzVDBGQlR5eEZRVUZGTEVkQlFVZERMRTFCUVUwc1EwRkJRenRSUVVGRk8wMUJRelZFTzFGQlFYVkNVU3hQUVVGUExFTkJRVU5LTEVsQlFVa3NRMEZCU1V3c1QwRkJUeXhGUVVGRkxFZEJRVWRETEUxQlFVMHNRMEZCUXp0UlFVRkZPMDFCUXpWRU8xRkJRWFZDVVN4UFFVRlBMRU5CUVVOS0xFbEJRVWtzUTBGQlNVd3NUMEZCVHl4RlFVRkZMRWRCUVVkRExFMUJRVTBzUTBGQlF6dFJRVUZGTzAxQlF6VkVPMUZCUVhWQ1VTeFBRVUZQTEVOQlFVTklMRXRCUVVzc1EwRkJSMDRzVDBGQlR5eEZRVUZGTEVkQlFVZERMRTFCUVUwc1EwRkJRenRSUVVGRk8wbEJRelZFTzBWQlEwbzdPMEZCU1VvN1FVRkJRVk1zVDBGQlFTeERRVUZCWkN4aFFVRkJMRWRCUVVGQkxHRkJRVUU3UVVGRFRTeE5RVUZQWlN4WlFVRmhMRk5CUVZGbUxHRkJRV0U3UlVGRk0wTTdSVUZEUVVNc1dVRkJRVHRKUVVOSkxFdEJRVXNzUTBGQlF5eEhRVUZIVUN4aFFVRmhMRk5CUVZNc1EwRkJRenRGUVVOd1F6czdRVUZIU2p0QlFVRkJiMElzVDBGQlFTeERRVUZCUXl4WlFVRkJMRWRCUVVGQkxGbEJRVUU3UVVGRFRTeE5RVUZQUXl4WlFVRmhMRk5CUVZGb1FpeGhRVUZoTzBWQlJUTkRPMFZCUTBGRExGbEJRWEZDWjBJc1IwRkJZeXhGUVVGRlF5eFJRVUZyUWp0SlFVTnVSQ3hMUVVGTExFTkJRVU1zUjBGQlIzaENMR0ZCUVdFc1UwRkJVeXhEUVVGRE8wbEJSR1lzUzBGQlFYVkNMRWRCUVVjc1IwRkJTRUVzUjBGQlJ6dEpRVWR3UWp0SlFVTkJRU3hIUVVGSExFTkJRVU5GTEU5QlFVOHNRMEZCUXl4TFFVRkxMRVZCUVVWRExGRkJRVkVzU1VGQlJ6dE5RVUZITEVsQlFVa3NRMEZCUTBNc1YwRkJWeXhEUVVGRFJDeFJRVUZSTEVOQlFVTTdTVUZCUlN4RFFVRkRMRU5CUVVNN1NVRkRMMFFzU1VGQlNUdE5RVUZGU0N4SFFVRkhMRU5CUVVOTExFOUJRVThzUTBGQlF5eE5RVUZOTEVWQlFVVktMRkZCUVZFc1EwRkJRenRKUVVGRkxFTkJRVU1zUTBGQlF5eE5RVUZOTEVOQlFVVTdSVUZEYmtRN1JVRkZRVHRGUVVOQlJ5eFhRVUZYUVN4RFFVRkRSQ3hSUVVFMFFqdEpRVU53UXl4TFFVRkxMRTFCUVUwN1RVRkJSVlFzUzBGQlN6dE5RVUZGVUN4UFFVRlBPMDFCUVVWRE8wbEJRVTBzUTBGQlJTeEpRVUZKWlN4UlFVRlJMRVZCUXpkRExFbEJRVWtzUTBGQlEyUXNSMEZCUnl4RFFVRkRTeXhMUVVGTExFVkJRVVZRTEU5QlFVOHNSVUZCUlN4SFFVRkhReXhOUVVGTkxFTkJRVU03UlVGRE0wTTdPMEZCUTBoVExFOUJRVUVzUTBGQlFVVXNXVUZCUVN4SFFVRkJRU3haUVVGQklpd2lhV2R1YjNKbFRHbHpkQ0k2VzExOSIsIlwidXNlIHN0cmljdFwiO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5jbG9uZVRlbXBsYXRlID0gY2xvbmVUZW1wbGF0ZTtcbmV4cG9ydHMuZWxlbWVudFdpdGhBYnNvbHV0ZVBhdGhzID0gZWxlbWVudFdpdGhBYnNvbHV0ZVBhdGhzO1xuZXhwb3J0cy5nZXRFbGVtZW50QnlJZCA9IGdldEVsZW1lbnRCeUlkO1xuZXhwb3J0cy5nZXRIVE1MID0gZ2V0SFRNTDtcbmV4cG9ydHMuZ2V0U2xvdCA9IGdldFNsb3Q7XG5leHBvcnRzLnNldFNsb3RUZXh0ID0gc2V0U2xvdFRleHQ7XG52YXIgX2Fzc2VydCA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcImFzc2VydFwiKSk7XG52YXIgX3V0aWxzID0gcmVxdWlyZShcIi4uLy4uL3V0aWxzLmpzXCIpO1xuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChlKSB7IHJldHVybiBlICYmIGUuX19lc01vZHVsZSA/IGUgOiB7IGRlZmF1bHQ6IGUgfTsgfVxuLy8gSG9tZWJyaWRnZSBwbHVnaW4gZm9yIEhvbWUgQ29ubmVjdCBob21lIGFwcGxpYW5jZXNcbi8vIENvcHlyaWdodCDCqSAyMDIzLTIwMjUgQWxleGFuZGVyIFRob3VreWRpZGVzXG5cbi8vIEdldCBhbiBIVE1MIGVsZW1lbnQgYnkgaXRzIFwiaWRcIiBhdHRyaWJ1dGVcbmZ1bmN0aW9uIGdldEVsZW1lbnRCeUlkKGVsZW1lbnRJZCkge1xuICBjb25zdCBlbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoZWxlbWVudElkKTtcbiAgKDAsIF91dGlscy5hc3NlcnRJc0luc3RhbmNlT2YpKGVsZW1lbnQsIEhUTUxFbGVtZW50KTtcbiAgcmV0dXJuIGVsZW1lbnQ7XG59XG4vLyBHZXQgYW4gSFRNTCBlbGVtZW50IHVzaW5nIGEgc2xvdCBuYW1lXG5mdW5jdGlvbiBnZXRTbG90KHdpdGhpbiwgc2xvdE5hbWUpIHtcbiAgY29uc3Qgc2xvdHMgPSB3aXRoaW4ucXVlcnlTZWxlY3RvckFsbChgW3Nsb3Q9XCIke3Nsb3ROYW1lfVwiXWApO1xuICBfYXNzZXJ0LmRlZmF1bHQuZXF1YWwoc2xvdHMubGVuZ3RoLCAxLCBgRXhwZWN0ZWQgZXhhY3RseSBvbmUgc2xvdCB3aXRoIG5hbWUgXCIke3Nsb3ROYW1lfVwiYCk7XG4gICgwLCBfdXRpbHMuYXNzZXJ0SXNJbnN0YW5jZU9mKShzbG90c1swXSwgSFRNTEVsZW1lbnQpO1xuICByZXR1cm4gc2xvdHNbMF07XG59XG4vLyBTZXQgdGhlIHRleHQgY29udGVudCBvZiBtdWx0aXBsZSBzbG90IGVsZW1lbnRzXG5mdW5jdGlvbiBzZXRTbG90VGV4dCh3aXRoaW4sIHNsb3RUZXh0KSB7XG4gIGZvciAoY29uc3QgW3Nsb3ROYW1lLCB0ZXh0XSBvZiBPYmplY3QuZW50cmllcyhzbG90VGV4dCkpIGdldFNsb3Qod2l0aGluLCBzbG90TmFtZSkudGV4dENvbnRlbnQgPSB0ZXh0O1xufVxuLy8gQ3JlYXRlIGEgY29weSBvZiBhIHRlbXBsYXRlIGVsZW1lbnRcbmZ1bmN0aW9uIGNsb25lVGVtcGxhdGUoZWxlbWVudElkLCBzbG90VGV4dCkge1xuICAvLyBGaW5kIHRoZSB0ZW1wbGF0ZSBlbGVtZW50XG4gIGNvbnN0IHRlbXBsYXRlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoZWxlbWVudElkKTtcbiAgKDAsIF91dGlscy5hc3NlcnRJc0luc3RhbmNlT2YpKHRlbXBsYXRlLCBIVE1MVGVtcGxhdGVFbGVtZW50KTtcbiAgLy8gQ2xvbmUgdGhlIHRlbXBsYXRlJ3MgZG9jdW1lbnQtZnJhZ21lbnQgYW5kIHNldCBzbG90IHZhbHVlc1xuICBjb25zdCBkb2N1bWVudEZyYWdtZW50ID0gdGVtcGxhdGUuY29udGVudC5jbG9uZU5vZGUodHJ1ZSk7XG4gICgwLCBfdXRpbHMuYXNzZXJ0SXNJbnN0YW5jZU9mKShkb2N1bWVudEZyYWdtZW50LCBEb2N1bWVudEZyYWdtZW50KTtcbiAgaWYgKHNsb3RUZXh0KSBzZXRTbG90VGV4dChkb2N1bWVudEZyYWdtZW50LCBzbG90VGV4dCk7XG4gIHJldHVybiBkb2N1bWVudEZyYWdtZW50O1xufVxuLy8gTWFrZSBVUkkgcGF0aHMgYWJzb2x1dGVcbmZ1bmN0aW9uIGVsZW1lbnRXaXRoQWJzb2x1dGVQYXRocyhmcmFnbWVudCkge1xuICBmb3IgKGNvbnN0IGF0dHJpYnV0ZSBvZiBbJ2hyZWYnLCAnc3JjJ10pIHtcbiAgICBjb25zdCBlbGVtZW50cyA9IGZyYWdtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoYFske2F0dHJpYnV0ZX1dYCk7XG4gICAgZm9yIChjb25zdCBlbGVtZW50IG9mIEFycmF5LmZyb20oZWxlbWVudHMpKSB7XG4gICAgICBjb25zdCBwYXRoID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUoYXR0cmlidXRlKTtcbiAgICAgICgwLCBfdXRpbHMuYXNzZXJ0SXNEZWZpbmVkKShwYXRoKTtcbiAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKGF0dHJpYnV0ZSwgbmV3IFVSTChwYXRoLCBsb2NhdGlvbi5ocmVmKS5ocmVmKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGZyYWdtZW50O1xufVxuLy8gT2J0YWluIHRoZSBIVE1MIHNlcmlhbGl6YXRpb24gb2YgYSB0ZW1wbGF0ZSBlbGVtZW50XG5mdW5jdGlvbiBnZXRIVE1MKGZyYWdtZW50KSB7XG4gIGNvbnN0IHNlcmlhbGl6ZXIgPSBuZXcgWE1MU2VyaWFsaXplcigpO1xuICByZXR1cm4gc2VyaWFsaXplci5zZXJpYWxpemVUb1N0cmluZyhmcmFnbWVudCk7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldD11dGYtODtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnVZVzFsY3lJNld5SmZZWE56WlhKMElpd2lYMmx1ZEdWeWIzQlNaWEYxYVhKbFJHVm1ZWFZzZENJc0luSmxjWFZwY21VaUxDSmZkWFJwYkhNaUxDSmxJaXdpWDE5bGMwMXZaSFZzWlNJc0ltUmxabUYxYkhRaUxDSm5aWFJGYkdWdFpXNTBRbmxKWkNJc0ltVnNaVzFsYm5SSlpDSXNJbVZzWlcxbGJuUWlMQ0prYjJOMWJXVnVkQ0lzSW1GemMyVnlkRWx6U1c1emRHRnVZMlZQWmlJc0lraFVUVXhGYkdWdFpXNTBJaXdpWjJWMFUyeHZkQ0lzSW5kcGRHaHBiaUlzSW5Oc2IzUk9ZVzFsSWl3aWMyeHZkSE1pTENKeGRXVnllVk5sYkdWamRHOXlRV3hzSWl3aVlYTnpaWEowSWl3aVpYRjFZV3dpTENKc1pXNW5kR2dpTENKelpYUlRiRzkwVkdWNGRDSXNJbk5zYjNSVVpYaDBJaXdpZEdWNGRDSXNJazlpYW1WamRDSXNJbVZ1ZEhKcFpYTWlMQ0owWlhoMFEyOXVkR1Z1ZENJc0ltTnNiMjVsVkdWdGNHeGhkR1VpTENKMFpXMXdiR0YwWlNJc0lraFVUVXhVWlcxd2JHRjBaVVZzWlcxbGJuUWlMQ0prYjJOMWJXVnVkRVp5WVdkdFpXNTBJaXdpWTI5dWRHVnVkQ0lzSW1Oc2IyNWxUbTlrWlNJc0lrUnZZM1Z0Wlc1MFJuSmhaMjFsYm5RaUxDSmxiR1Z0Wlc1MFYybDBhRUZpYzI5c2RYUmxVR0YwYUhNaUxDSm1jbUZuYldWdWRDSXNJbUYwZEhKcFluVjBaU0lzSW1Wc1pXMWxiblJ6SWl3aVFYSnlZWGtpTENKbWNtOXRJaXdpY0dGMGFDSXNJbWRsZEVGMGRISnBZblYwWlNJc0ltRnpjMlZ5ZEVselJHVm1hVzVsWkNJc0luTmxkRUYwZEhKcFluVjBaU0lzSWxWU1RDSXNJbXh2WTJGMGFXOXVJaXdpYUhKbFppSXNJbWRsZEVoVVRVd2lMQ0p6WlhKcFlXeHBlbVZ5SWl3aVdFMU1VMlZ5YVdGc2FYcGxjaUlzSW5ObGNtbGhiR2w2WlZSdlUzUnlhVzVuSWwwc0luTnZkWEpqWlhNaU9sc2lMaTR2TGk0dkxpNHZjM0pqTDJodmJXVmljbWxrWjJVdGRXa3ZjSFZpYkdsakwzVjBhV3h6TFdSdmJTNTBjeUpkTENKemIzVnlZMlZ6UTI5dWRHVnVkQ0k2VzI1MWJHeGRMQ0p0WVhCd2FXNW5jeUk2SWpzN096czdPenM3T3pzN1FVRkhRU3hKUVVGQlFTeFBRVUZCTEVkQlFVRkRMSE5DUVVGQkxFTkJRVUZETEU5QlFVRTdRVUZGUVN4SlFVRkJReXhOUVVGQkxFZEJRVUZFTEU5QlFVRTdRVUZCY1VVc1UwRkJRVVFzZFVKQlFVRkhMRU5CUVVFc1YwRkJRVUVzUTBGQlFTeEpRVUZCUVN4RFFVRkJMRU5CUVVGRExGVkJRVUVzUjBGQlFVUXNRMEZCUVN4TFFVRkJSU3hQUVVGQkxFVkJRVUZHTEVOQlFVRTdRVUZNY2tVN1FVRkRRVHM3UVVGWFFUdEJRVU5OTEZOQlFWVkhMR05CUVdOQkxFTkJRVU5ETEZOQlFXbENPMFZCUXpWRExFMUJRVTFETEU5QlFVOHNSMEZCUjBNc1VVRkJVU3hEUVVGRFNDeGpRVUZqTEVOQlFVTkRMRk5CUVZNc1EwRkJRenRGUVVOc1JDeEpRVUZCUnl4NVFrRkJhMElzUlVGQlEwWXNUMEZCVHl4RlFVRkZSeXhYUVVGWExFTkJRVU03UlVGRGVFTXNUMEZCVDBnc1QwRkJUenRCUVVOc1FqdEJRVVZCTzBGQlEwMHNVMEZCVlVrc1QwRkJUMEVzUTBGQlEwTXNUVUZCZDBJc1JVRkJSVU1zVVVGQlowSTdSVUZET1VRc1RVRkJUVU1zUzBGQlN5eEhRVUZIUml4TlFVRk5MRU5CUVVOSExHZENRVUZuUWl4RFFVRkRMRlZCUVZWR0xGRkJRVkVzU1VGQlNTeERRVUZETzBWQlF6ZEVSeXhsUVVGTkxFTkJRVU5ETEV0QlFVc3NRMEZCUTBnc1MwRkJTeXhEUVVGRFNTeE5RVUZOTEVWQlFVVXNRMEZCUXl4RlFVRkZMSGREUVVGM1Ewd3NVVUZCVVN4SFFVRkhMRU5CUVVNN1JVRkRiRVlzU1VGQlFVb3NlVUpCUVd0Q0xFVkJRVU5MTEV0QlFVc3NRMEZCUXl4RFFVRkRMRU5CUVVNc1JVRkJSVW9zVjBGQlZ5eERRVUZETzBWQlEzcERMRTlCUVU5SkxFdEJRVXNzUTBGQlF5eERRVUZETEVOQlFVTTdRVUZEYmtJN1FVRkZRVHRCUVVOTkxGTkJRVlZMTEZkQlFWZEJMRU5CUVVOUUxFMUJRWGRDTEVWQlFVVlJMRkZCUVdkRE8wVkJRMnhHTEV0QlFVc3NUVUZCVFN4RFFVRkRVQ3hSUVVGUkxFVkJRVVZSTEVsQlFVa3NRMEZCUXl4SlFVRkpReXhOUVVGTkxFTkJRVU5ETEU5QlFVOHNRMEZCUTBnc1VVRkJVU3hEUVVGRExFVkJRMjVFVkN4UFFVRlBMRU5CUVVORExFMUJRVTBzUlVGQlJVTXNVVUZCVVN4RFFVRkRMRU5CUVVOWExGZEJRVmNzUjBGQlIwZ3NTVUZCU1R0QlFVTndSRHRCUVVWQk8wRkJRMDBzVTBGQlZVa3NZVUZCWVVFc1EwRkJRMjVDTEZOQlFXbENMRVZCUVVWakxGRkJRV2xETzBWQlF6bEZPMFZCUTBFc1RVRkJUVTBzVVVGQlVTeEhRVUZIYkVJc1VVRkJVU3hEUVVGRFNDeGpRVUZqTEVOQlFVTkRMRk5CUVZNc1EwRkJRenRGUVVOdVJDeEpRVUZCUnl4NVFrRkJhMElzUlVGQlEybENMRkZCUVZFc1JVRkJSVU1zYlVKQlFXMUNMRU5CUVVNN1JVRkZha1E3UlVGRFFTeE5RVUZOUXl4blFrRkJaMElzUjBGQlIwWXNVVUZCVVN4RFFVRkRSeXhQUVVGUExFTkJRVU5ETEZOQlFWTXNRMEZCUXl4SlFVRkpMRU5CUVVNN1JVRkRla1FzU1VGQlFYSkNMSGxDUVVGclFpeEZRVUZEYlVJc1owSkJRV2RDTEVWQlFVVkhMR2RDUVVGblFpeERRVUZETzBWQlEzUkVMRWxCUVVsWUxGRkJRVkVzUlVGQlJVUXNWMEZCVnl4RFFVRkRVeXhuUWtGQlowSXNSVUZCUlZJc1VVRkJVU3hEUVVGRE8wVkJRM0pFTEU5QlFVOVJMR2RDUVVGblFqdEJRVU16UWp0QlFVVkJPMEZCUTAwc1UwRkJWVWtzZDBKQlFYZENRU3hEUVVGblEwTXNVVUZCWXp0RlFVTnNSaXhMUVVGTExFMUJRVTFETEZOQlFWTXNTVUZCU1N4RFFVRkRMRTFCUVUwc1JVRkJSU3hMUVVGTExFTkJRVU1zUlVGQlJUdEpRVU55UXl4TlFVRk5ReXhSUVVGUkxFZEJRVWRHTEZGQlFWRXNRMEZCUTJ4Q0xHZENRVUZuUWl4RFFVRkRMRWxCUVVsdFFpeFRRVUZUTEVkQlFVY3NRMEZCUXp0SlFVTTFSQ3hMUVVGTExFMUJRVTB6UWl4UFFVRlBMRWxCUVVrMlFpeExRVUZMTEVOQlFVTkRMRWxCUVVrc1EwRkJRMFlzVVVGQlVTeERRVUZETEVWQlFVVTdUVUZEZUVNc1RVRkJUVWNzU1VGQlNTeEhRVUZITDBJc1QwRkJUeXhEUVVGRFowTXNXVUZCV1N4RFFVRkRUQ3hUUVVGVExFTkJRVU03VFVGRE5VTXNTVUZCUVUwc2MwSkJRV1VzUlVGQlEwWXNTVUZCU1N4RFFVRkRPMDFCUTNKQ0wwSXNUMEZCVHl4RFFVRkRhME1zV1VGQldTeERRVUZEVUN4VFFVRlRMRVZCUVVVc1NVRkJTVkVzUjBGQlJ5eERRVUZEU2l4SlFVRkpMRVZCUVVWTExGRkJRVkVzUTBGQlEwTXNTVUZCU1N4RFFVRkRMRU5CUVVOQkxFbEJRVWtzUTBGQlF6dEpRVU4wUlR0RlFVTktPMFZCUTBFc1QwRkJUMWdzVVVGQlVUdEJRVU51UWp0QlFVVkJPMEZCUTAwc1UwRkJWVmtzVDBGQlQwRXNRMEZCUTFvc1VVRkJZenRGUVVOc1F5eE5RVUZOWVN4VlFVRlZMRWRCUVVjc1NVRkJTVU1zWVVGQllTeEZRVUZGTzBWQlEzUkRMRTlCUVU5RUxGVkJRVlVzUTBGQlEwVXNhVUpCUVdsQ0xFTkJRVU5tTEZGQlFWRXNRMEZCUXp0QlFVTnFSQ0lzSW1sbmJtOXlaVXhwYzNRaU9sdGRmUT09IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSBleHBvcnRzLkRlYnVnRmVhdHVyZXMgPSBleHBvcnRzLkNvbmZpZ1BsdWdpbiA9IGV4cG9ydHMuQ29uZmlnQXBwbGlhbmNlcyA9IGV4cG9ydHMuQXBwbGlhbmNlUHJvZ3JhbU9wdGlvbnMgPSBleHBvcnRzLkFwcGxpYW5jZVByb2dyYW1Db25maWcgPSBleHBvcnRzLkFwcGxpYW5jZU5hbWVzUHJlZml4ID0gZXhwb3J0cy5BcHBsaWFuY2VGZWF0dXJlcyA9IGV4cG9ydHMuQXBwbGlhbmNlQ29uZmlnID0gZXhwb3J0cy5BZGRQcm9ncmFtc0NvbmZpZyA9IHZvaWQgMDtcbnZhciB0ID0gX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQocmVxdWlyZShcInRzLWludGVyZmFjZS1jaGVja2VyXCIpKTtcbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkKGUsIHQpIHsgaWYgKFwiZnVuY3Rpb25cIiA9PSB0eXBlb2YgV2Vha01hcCkgdmFyIHIgPSBuZXcgV2Vha01hcCgpLCBuID0gbmV3IFdlYWtNYXAoKTsgcmV0dXJuIChfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCA9IGZ1bmN0aW9uIChlLCB0KSB7IGlmICghdCAmJiBlICYmIGUuX19lc01vZHVsZSkgcmV0dXJuIGU7IHZhciBvLCBpLCBmID0geyBfX3Byb3RvX186IG51bGwsIGRlZmF1bHQ6IGUgfTsgaWYgKG51bGwgPT09IGUgfHwgXCJvYmplY3RcIiAhPSB0eXBlb2YgZSAmJiBcImZ1bmN0aW9uXCIgIT0gdHlwZW9mIGUpIHJldHVybiBmOyBpZiAobyA9IHQgPyBuIDogcikgeyBpZiAoby5oYXMoZSkpIHJldHVybiBvLmdldChlKTsgby5zZXQoZSwgZik7IH0gZm9yIChjb25zdCB0IGluIGUpIFwiZGVmYXVsdFwiICE9PSB0ICYmIHt9Lmhhc093blByb3BlcnR5LmNhbGwoZSwgdCkgJiYgKChpID0gKG8gPSBPYmplY3QuZGVmaW5lUHJvcGVydHkpICYmIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoZSwgdCkpICYmIChpLmdldCB8fCBpLnNldCkgPyBvKGYsIHQsIGkpIDogZlt0XSA9IGVbdF0pOyByZXR1cm4gZjsgfSkoZSwgdCk7IH1cbi8qKlxuICogVGhpcyBtb2R1bGUgd2FzIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IGB0cy1pbnRlcmZhY2UtYnVpbGRlcmBcbiAqL1xuXG4vLyB0c2xpbnQ6ZGlzYWJsZTpvYmplY3QtbGl0ZXJhbC1rZXktcXVvdGVzXG5jb25zdCBDb25maWdQbHVnaW4gPSBleHBvcnRzLkNvbmZpZ1BsdWdpbiA9IHQuaWZhY2UoW10sIHtcbiAgXCJwbGF0Zm9ybVwiOiBcInN0cmluZ1wiLFxuICBcIm5hbWVcIjogdC5vcHQoXCJzdHJpbmdcIiksXG4gIFwiY2xpZW50aWRcIjogXCJzdHJpbmdcIixcbiAgXCJjbGllbnRzZWNyZXRcIjogdC5vcHQoXCJzdHJpbmdcIiksXG4gIFwic2ltdWxhdG9yXCI6IHQub3B0KFwiYm9vbGVhblwiKSxcbiAgXCJjaGluYVwiOiB0Lm9wdChcImJvb2xlYW5cIiksXG4gIFwibGFuZ3VhZ2VcIjogdC5pZmFjZShbXSwge1xuICAgIFwiYXBpXCI6IFwic3RyaW5nXCJcbiAgfSksXG4gIFwiZGVidWdcIjogdC5vcHQodC5hcnJheShcIkRlYnVnRmVhdHVyZXNcIikpXG59KTtcbmNvbnN0IERlYnVnRmVhdHVyZXMgPSBleHBvcnRzLkRlYnVnRmVhdHVyZXMgPSB0LnVuaW9uKHQubGl0KCdMb2cgQVBJIEhlYWRlcnMnKSwgdC5saXQoJ0xvZyBBUEkgQm9kaWVzJyksIHQubGl0KCdMb2cgQXBwbGlhbmNlIElEcycpLCB0LmxpdCgnTG9nIERlYnVnIGFzIEluZm8nKSwgdC5saXQoJ01vY2sgQXBwbGlhbmNlcycpKTtcbmNvbnN0IENvbmZpZ0FwcGxpYW5jZXMgPSBleHBvcnRzLkNvbmZpZ0FwcGxpYW5jZXMgPSB0LmlmYWNlKFtdLCB7XG4gIFt0LmluZGV4S2V5XTogXCJBcHBsaWFuY2VDb25maWdcIlxufSk7XG5jb25zdCBBZGRQcm9ncmFtc0NvbmZpZyA9IGV4cG9ydHMuQWRkUHJvZ3JhbXNDb25maWcgPSB0LnVuaW9uKHQubGl0KCdub25lJyksIHQubGl0KCdhdXRvJyksIHQubGl0KCdjdXN0b20nKSk7XG5jb25zdCBBcHBsaWFuY2VDb25maWcgPSBleHBvcnRzLkFwcGxpYW5jZUNvbmZpZyA9IHQuaWZhY2UoW10sIHtcbiAgXCJlbmFibGVkXCI6IHQub3B0KFwiYm9vbGVhblwiKSxcbiAgXCJuYW1lc1wiOiB0Lm9wdCh0LmlmYWNlKFtdLCB7XG4gICAgXCJwcmVmaXhcIjogXCJBcHBsaWFuY2VOYW1lc1ByZWZpeFwiXG4gIH0pKSxcbiAgXCJmZWF0dXJlc1wiOiB0Lm9wdChcIkFwcGxpYW5jZUZlYXR1cmVzXCIpLFxuICBcImFkZHByb2dyYW1zXCI6IHQub3B0KFwiQWRkUHJvZ3JhbXNDb25maWdcIiksXG4gIFwicHJvZ3JhbXNcIjogdC5vcHQodC5hcnJheShcIkFwcGxpYW5jZVByb2dyYW1Db25maWdcIikpXG59KTtcbmNvbnN0IEFwcGxpYW5jZU5hbWVzUHJlZml4ID0gZXhwb3J0cy5BcHBsaWFuY2VOYW1lc1ByZWZpeCA9IHQuaWZhY2UoW10sIHtcbiAgXCJwcm9ncmFtc1wiOiB0Lm9wdChcImJvb2xlYW5cIiksXG4gIFwib3RoZXJcIjogdC5vcHQoXCJib29sZWFuXCIpXG59KTtcbmNvbnN0IEFwcGxpYW5jZUZlYXR1cmVzID0gZXhwb3J0cy5BcHBsaWFuY2VGZWF0dXJlcyA9IHQuaWZhY2UoW10sIHtcbiAgW3QuaW5kZXhLZXldOiBcImJvb2xlYW5cIlxufSk7XG5jb25zdCBBcHBsaWFuY2VQcm9ncmFtQ29uZmlnID0gZXhwb3J0cy5BcHBsaWFuY2VQcm9ncmFtQ29uZmlnID0gdC5pZmFjZShbXSwge1xuICBcIm5hbWVcIjogXCJzdHJpbmdcIixcbiAgXCJrZXlcIjogXCJzdHJpbmdcIixcbiAgXCJzZWxlY3Rvbmx5XCI6IHQub3B0KFwiYm9vbGVhblwiKSxcbiAgXCJvcHRpb25zXCI6IHQub3B0KFwiQXBwbGlhbmNlUHJvZ3JhbU9wdGlvbnNcIilcbn0pO1xuY29uc3QgQXBwbGlhbmNlUHJvZ3JhbU9wdGlvbnMgPSBleHBvcnRzLkFwcGxpYW5jZVByb2dyYW1PcHRpb25zID0gdC5pZmFjZShbXSwge1xuICBbdC5pbmRleEtleV06IHQudW5pb24oXCJzdHJpbmdcIiwgXCJudW1iZXJcIiwgXCJib29sZWFuXCIpXG59KTtcbmNvbnN0IGV4cG9ydGVkVHlwZVN1aXRlID0ge1xuICBDb25maWdQbHVnaW4sXG4gIERlYnVnRmVhdHVyZXMsXG4gIENvbmZpZ0FwcGxpYW5jZXMsXG4gIEFkZFByb2dyYW1zQ29uZmlnLFxuICBBcHBsaWFuY2VDb25maWcsXG4gIEFwcGxpYW5jZU5hbWVzUHJlZml4LFxuICBBcHBsaWFuY2VGZWF0dXJlcyxcbiAgQXBwbGlhbmNlUHJvZ3JhbUNvbmZpZyxcbiAgQXBwbGlhbmNlUHJvZ3JhbU9wdGlvbnNcbn07XG52YXIgX2RlZmF1bHQgPSBleHBvcnRzLmRlZmF1bHQgPSBleHBvcnRlZFR5cGVTdWl0ZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRhdGE6YXBwbGljYXRpb24vanNvbjtjaGFyc2V0PXV0Zi04O2Jhc2U2NCxleUoyWlhKemFXOXVJam96TENKdVlXMWxjeUk2V3lKMElpd2lYMmx1ZEdWeWIzQlNaWEYxYVhKbFYybHNaR05oY21RaUxDSnlaWEYxYVhKbElpd2laU0lzSWxkbFlXdE5ZWEFpTENKeUlpd2liaUlzSWw5ZlpYTk5iMlIxYkdVaUxDSnZJaXdpYVNJc0ltWWlMQ0pmWDNCeWIzUnZYMThpTENKa1pXWmhkV3gwSWl3aWFHRnpJaXdpWjJWMElpd2ljMlYwSWl3aWFHRnpUM2R1VUhKdmNHVnlkSGtpTENKallXeHNJaXdpVDJKcVpXTjBJaXdpWkdWbWFXNWxVSEp2Y0dWeWRIa2lMQ0puWlhSUGQyNVFjbTl3WlhKMGVVUmxjMk55YVhCMGIzSWlMQ0pEYjI1bWFXZFFiSFZuYVc0aUxDSmxlSEJ2Y25Seklpd2lhV1poWTJVaUxDSnZjSFFpTENKaGNuSmhlU0lzSWtSbFluVm5SbVZoZEhWeVpYTWlMQ0oxYm1sdmJpSXNJbXhwZENJc0lrTnZibVpwWjBGd2NHeHBZVzVqWlhNaUxDSnBibVJsZUV0bGVTSXNJa0ZrWkZCeWIyZHlZVzF6UTI5dVptbG5JaXdpUVhCd2JHbGhibU5sUTI5dVptbG5JaXdpUVhCd2JHbGhibU5sVG1GdFpYTlFjbVZtYVhnaUxDSkJjSEJzYVdGdVkyVkdaV0YwZFhKbGN5SXNJa0Z3Y0d4cFlXNWpaVkJ5YjJkeVlXMURiMjVtYVdjaUxDSkJjSEJzYVdGdVkyVlFjbTluY21GdFQzQjBhVzl1Y3lJc0ltVjRjRzl5ZEdWa1ZIbHdaVk4xYVhSbElpd2lYMlJsWm1GMWJIUWlYU3dpYzI5MWNtTmxjeUk2V3lJdUxpOHVMaTl6Y21NdmRHa3ZZMjl1Wm1sbkxYUjVjR1Z6TFhScExuUnpJbDBzSW5OdmRYSmpaWE5EYjI1MFpXNTBJanBiYm5Wc2JGMHNJbTFoY0hCcGJtZHpJam9pT3pzN096czdRVUZIUVN4SlFVRkJRU3hEUVVGQkxFZEJRVUZETEhWQ1FVRkJMRU5CUVVGRExFOUJRVUU3UVVGQk1FTXNVMEZCUVVRc2QwSkJRVUZGTEVOQlFVRXNSVUZCUVVnc1EwRkJRU3cyUWtGQlFVa3NUMEZCUVN4TlFVRkJReXhEUVVGQkxFOUJRVUZFTEU5QlFVRXNTVUZCUVVVc1EwRkJRU3hQUVVGQlJpeFBRVUZCTEZsQlFVRklMSFZDUVVGQkxGbEJRVUZCTEVOQlFVRkZMRU5CUVVFc1JVRkJRVWdzUTBGQlFTeFRRVUZCUVN4RFFVRkJMRWxCUVVGSExFTkJRVUVzU1VGQlFVRXNRMEZCUVN4RFFVRkJTU3hWUVVGQkxGTkJRVUZLTEVOQlFVRXNUVUZCUVVzc1EwRkJRU3hGUVVGQlF5eERRVUZCTEVWQlFVRkRMRU5CUVVFc1MwRkJRVU1zVTBGQlFTeFJRVUZCUXl4UFFVRkJMRVZCUVVGVUxFTkJRVUVzYVVKQlFVRkJMRU5CUVVFc2RVSkJRVUZCTEVOQlFVRXNlVUpCUVVGQkxFTkJRVUVzVTBGQlFVOHNRMEZCUVN4TlFVRkJSaXhEUVVGQkxFZEJRVUZTTEVOQlFVRXNSMEZCUVUwc1EwRkJRU3hIUVVGQlJDeERRVUZCTEZGQlFVRkhMRU5CUVVFc1EwRkJRVXNzUjBGQlFTeERRVUZCVml4RFFVRkJMRlZCUVVGTExFTkJRVUVzUTBGQlFVMHNSMEZCUVN4RFFVRkJXQ3hEUVVGQkxFZEJRVUZMTEVOQlFVRXNRMEZCUVU4c1IwRkJRU3hEUVVGQldpeERRVUZCTEVWQlFVRlBMRU5CUVVFc1owSkJRVUZXTEVOQlFVRXNTVUZCUVVjc1EwRkJRU3huUWtGQlFVZ3NRMEZCUVN4UFFVRkJaMElzWTBGQlFTeERRVUZCUXl4SlFVRkJMRU5CUVVGa0xFTkJRVUVzUlVGQlFVZ3NRMEZCUVN4UFFVRkJVeXhEUVVGQkxFbEJRVUZFTEVOQlFVRXNSMEZCUVZVc1RVRkJRU3hEUVVGQlF5eGpRVUZCTEV0QlFVRkVMRTFCUVVFc1EwRkJRVVVzZDBKQlFVRXNRMEZCUVdwQ0xFTkJRVUVzUlVGQlFVZ3NRMEZCUVN4UFFVRkJVeXhEUVVGQkxFTkJRVUZMTEVkQlFVRXNTVUZCUVV3c1EwRkJRU3hEUVVGQlRTeEhRVUZCTEVsQlFVRlFMRU5CUVVFc1EwRkJRVVVzUTBGQlFTeEZRVUZCVml4RFFVRkJMRVZCUVVGVExFTkJRVUVzU1VGQlFVTXNRMEZCUVN4RFFVRkJWaXhEUVVGQkxFbEJRVUZITEVOQlFVRXNRMEZCUVVnc1EwRkJRU3hYUVVGQlZTeERRVUZCTEV0QlFVRlFMRU5CUVVFc1JVRkJRVWdzUTBGQlFUdEJRVWd4UXpzN096dEJRVWxCTzBGQlJVOHNUVUZCVFhGQ0xGbEJRVmtzUjBGQlFVTXNUMEZCUVN4RFFVRkJSQ3haUVVGQkxFZEJRVWR5UWl4RFFVRkRMRU5CUVVOMVFpeExRVUZMTEVOQlFVTXNSVUZCUlN4RlFVRkZPMFZCUTNSRExGVkJRVlVzUlVGQlJTeFJRVUZSTzBWQlEzQkNMRTFCUVUwc1JVRkJSWFpDTEVOQlFVTXNRMEZCUTNkQ0xFZEJRVWNzUTBGQlF5eFJRVUZSTEVOQlFVTTdSVUZEZGtJc1ZVRkJWU3hGUVVGRkxGRkJRVkU3UlVGRGNFSXNZMEZCWXl4RlFVRkZlRUlzUTBGQlF5eERRVUZEZDBJc1IwRkJSeXhEUVVGRExGRkJRVkVzUTBGQlF6dEZRVU12UWl4WFFVRlhMRVZCUVVWNFFpeERRVUZETEVOQlFVTjNRaXhIUVVGSExFTkJRVU1zVTBGQlV5eERRVUZETzBWQlF6ZENMRTlCUVU4c1JVRkJSWGhDTEVOQlFVTXNRMEZCUTNkQ0xFZEJRVWNzUTBGQlF5eFRRVUZUTEVOQlFVTTdSVUZEZWtJc1ZVRkJWU3hGUVVGRmVFSXNRMEZCUXl4RFFVRkRkVUlzUzBGQlN5eERRVUZETEVWQlFVVXNSVUZCUlR0SlFVTjBRaXhMUVVGTExFVkJRVVU3UjBGRFVpeERRVUZETzBWQlEwWXNUMEZCVHl4RlFVRkZka0lzUTBGQlF5eERRVUZEZDBJc1IwRkJSeXhEUVVGRGVFSXNRMEZCUXl4RFFVRkRlVUlzUzBGQlN5eERRVUZETEdWQlFXVXNRMEZCUXp0RFFVTjRReXhEUVVGRE8wRkJSVXNzVFVGQlRVTXNZVUZCWVN4SFFVRkJTaXhQUVVGQkxFTkJRVUZKTEdGQlFVRXNSMEZCUnpGQ0xFTkJRVU1zUTBGQlF6SkNMRXRCUVVzc1EwRkJRek5DTEVOQlFVTXNRMEZCUXpSQ0xFZEJRVWNzUTBGQlF5eHBRa0ZCYVVJc1EwRkJReXhGUVVGRk5VSXNRMEZCUXl4RFFVRkRORUlzUjBGQlJ5eERRVUZETEdkQ1FVRm5RaXhEUVVGRExFVkJRVVUxUWl4RFFVRkRMRU5CUVVNMFFpeEhRVUZITEVOQlFVTXNiVUpCUVcxQ0xFTkJRVU1zUlVGQlJUVkNMRU5CUVVNc1EwRkJRelJDTEVkQlFVY3NRMEZCUXl4dFFrRkJiVUlzUTBGQlF5eEZRVUZGTlVJc1EwRkJReXhEUVVGRE5FSXNSMEZCUnl4RFFVRkRMR2xDUVVGcFFpeERRVUZETEVOQlFVTTdRVUZGYkVzc1RVRkJUVU1zWjBKQlFXZENMRWRCUVVGUUxFOUJRVUVzUTBGQlFVOHNaMEpCUVVFc1IwRkJSemRDTEVOQlFVTXNRMEZCUTNWQ0xFdEJRVXNzUTBGQlF5eEZRVUZGTEVWQlFVVTdSVUZETVVNc1EwRkJRM1pDTEVOQlFVTXNRMEZCUXpoQ0xGRkJRVkVzUjBGQlJ6dERRVU5tTEVOQlFVTTdRVUZGU3l4TlFVRk5ReXhwUWtGQmFVSXNSMEZCUVZRc1QwRkJRU3hEUVVGQlV5eHBRa0ZCUVN4SFFVRkhMMElzUTBGQlF5eERRVUZETWtJc1MwRkJTeXhEUVVGRE0wSXNRMEZCUXl4RFFVRkRORUlzUjBGQlJ5eERRVUZETEUxQlFVMHNRMEZCUXl4RlFVRkZOVUlzUTBGQlF5eERRVUZETkVJc1IwRkJSeXhEUVVGRExFMUJRVTBzUTBGQlF5eEZRVUZGTlVJc1EwRkJReXhEUVVGRE5FSXNSMEZCUnl4RFFVRkRMRkZCUVZFc1EwRkJReXhEUVVGRE8wRkJSV2hHTEUxQlFVMUpMR1ZCUVdVc1IwRkJRVllzVDBGQlFTeERRVUZCVlN4bFFVRkJMRWRCUVVkb1F5eERRVUZETEVOQlFVTjFRaXhMUVVGTExFTkJRVU1zUlVGQlJTeEZRVUZGTzBWQlEzcERMRk5CUVZNc1JVRkJSWFpDTEVOQlFVTXNRMEZCUTNkQ0xFZEJRVWNzUTBGQlF5eFRRVUZUTEVOQlFVTTdSVUZETTBJc1QwRkJUeXhGUVVGRmVFSXNRMEZCUXl4RFFVRkRkMElzUjBGQlJ5eERRVUZEZUVJc1EwRkJReXhEUVVGRGRVSXNTMEZCU3l4RFFVRkRMRVZCUVVVc1JVRkJSVHRKUVVONlFpeFJRVUZSTEVWQlFVVTdSMEZEV0N4RFFVRkRMRU5CUVVNN1JVRkRTQ3hWUVVGVkxFVkJRVVYyUWl4RFFVRkRMRU5CUVVOM1FpeEhRVUZITEVOQlFVTXNiVUpCUVcxQ0xFTkJRVU03UlVGRGRFTXNZVUZCWVN4RlFVRkZlRUlzUTBGQlF5eERRVUZEZDBJc1IwRkJSeXhEUVVGRExHMUNRVUZ0UWl4RFFVRkRPMFZCUTNwRExGVkJRVlVzUlVGQlJYaENMRU5CUVVNc1EwRkJRM2RDTEVkQlFVY3NRMEZCUTNoQ0xFTkJRVU1zUTBGQlEzbENMRXRCUVVzc1EwRkJReXgzUWtGQmQwSXNRMEZCUXp0RFFVTndSQ3hEUVVGRE8wRkJSVXNzVFVGQlRWRXNiMEpCUVc5Q0xFZEJRVUZZTEU5QlFVRXNRMEZCUVZjc2IwSkJRVUVzUjBGQlIycERMRU5CUVVNc1EwRkJRM1ZDTEV0QlFVc3NRMEZCUXl4RlFVRkZMRVZCUVVVN1JVRkRPVU1zVlVGQlZTeEZRVUZGZGtJc1EwRkJReXhEUVVGRGQwSXNSMEZCUnl4RFFVRkRMRk5CUVZNc1EwRkJRenRGUVVNMVFpeFBRVUZQTEVWQlFVVjRRaXhEUVVGRExFTkJRVU4zUWl4SFFVRkhMRU5CUVVNc1UwRkJVenREUVVONlFpeERRVUZETzBGQlJVc3NUVUZCVFZVc2FVSkJRV2xDTEVkQlFVRmFMRTlCUVVFc1EwRkJRVmtzYVVKQlFVRXNSMEZCUjJ4RExFTkJRVU1zUTBGQlEzVkNMRXRCUVVzc1EwRkJReXhGUVVGRkxFVkJRVVU3UlVGRE0wTXNRMEZCUTNaQ0xFTkJRVU1zUTBGQlF6aENMRkZCUVZFc1IwRkJSenREUVVObUxFTkJRVU03UVVGRlN5eE5RVUZOU3l4elFrRkJjMElzUjBGQlFXSXNUMEZCUVN4RFFVRkJZU3h6UWtGQlFTeEhRVUZIYmtNc1EwRkJReXhEUVVGRGRVSXNTMEZCU3l4RFFVRkRMRVZCUVVVc1JVRkJSVHRGUVVOb1JDeE5RVUZOTEVWQlFVVXNVVUZCVVR0RlFVTm9RaXhMUVVGTExFVkJRVVVzVVVGQlVUdEZRVU5tTEZsQlFWa3NSVUZCUlhaQ0xFTkJRVU1zUTBGQlEzZENMRWRCUVVjc1EwRkJReXhUUVVGVExFTkJRVU03UlVGRE9VSXNVMEZCVXl4RlFVRkZlRUlzUTBGQlF5eERRVUZEZDBJc1IwRkJSeXhEUVVGRExIbENRVUY1UWp0RFFVTXpReXhEUVVGRE8wRkJSVXNzVFVGQlRWa3NkVUpCUVhWQ0xFZEJRVUZrTEU5QlFVRXNRMEZCUVdNc2RVSkJRVUVzUjBGQlIzQkRMRU5CUVVNc1EwRkJRM1ZDTEV0QlFVc3NRMEZCUXl4RlFVRkZMRVZCUVVVN1JVRkRha1FzUTBGQlEzWkNMRU5CUVVNc1EwRkJRemhDTEZGQlFWRXNSMEZCUnpsQ0xFTkJRVU1zUTBGQlF6SkNMRXRCUVVzc1EwRkJReXhSUVVGUkxFVkJRVVVzVVVGQlVTeEZRVUZGTEZOQlFWTTdRMEZEY0VRc1EwRkJRenRCUVVWR0xFMUJRVTFWTEdsQ1FVRnBRaXhIUVVGcFFqdEZRVU4wUTJoQ0xGbEJRVms3UlVGRFdrc3NZVUZCWVR0RlFVTmlSeXhuUWtGQlowSTdSVUZEYUVKRkxHbENRVUZwUWp0RlFVTnFRa01zWlVGQlpUdEZRVU5tUXl4dlFrRkJiMEk3UlVGRGNFSkRMR2xDUVVGcFFqdEZRVU5xUWtNc2MwSkJRWE5DTzBWQlEzUkNRenREUVVORU8wRkJRVU1zU1VGQlFVVXNVVUZCUVN4SFFVRkJhRUlzVDBGQlFTeERRVUZCVml4UFFVRkJMRWRCUTJGNVFpeHBRa0ZCYVVJaUxDSnBaMjV2Y21WTWFYTjBJanBiWFgwPSIsIlwidXNlIHN0cmljdFwiO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy50eXBlU3VpdGUgPSBleHBvcnRzLmRlZmF1bHQgPSBleHBvcnRzLmNoZWNrZXJzID0gdm9pZCAwO1xudmFyIF90c0ludGVyZmFjZUNoZWNrZXIgPSByZXF1aXJlKFwidHMtaW50ZXJmYWNlLWNoZWNrZXJcIik7XG52YXIgX2NvbmZpZ1R5cGVzVGkgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL2NvbmZpZy10eXBlcy10aS5qc1wiKSk7XG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KGUpIHsgcmV0dXJuIGUgJiYgZS5fX2VzTW9kdWxlID8gZSA6IHsgZGVmYXVsdDogZSB9OyB9XG4vLyBUaGlzIG1vZHVsZSB3YXMgYXV0b21hdGljYWxseSBnZW5lcmF0ZWQgYnkgbm9kZSB0cy1pbnRlcmZhY2UtcG9zdC50c1xuLy8gMjAyNS0wOC0wOVQwOTo1NzozNS4yOTdaXG5cbi8vIFR5cGUgZGVmaW5pdGlvbnNcbmNvbnN0IHR5cGVTdWl0ZSA9IGV4cG9ydHMudHlwZVN1aXRlID0gX2NvbmZpZ1R5cGVzVGkuZGVmYXVsdDtcbi8vIENoZWNrZXJzXG5jb25zdCBjaGVja2VycyA9IGV4cG9ydHMuY2hlY2tlcnMgPSAoMCwgX3RzSW50ZXJmYWNlQ2hlY2tlci5jcmVhdGVDaGVja2VycykoX2NvbmZpZ1R5cGVzVGkuZGVmYXVsdCk7XG4vLyBFeHBvcnQgdGhlIGNoZWNrZXJzIGJ5IGRlZmF1bHRcbnZhciBfZGVmYXVsdCA9IGV4cG9ydHMuZGVmYXVsdCA9IGNoZWNrZXJzO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ9dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p1WVcxbGN5STZXeUpmZEhOSmJuUmxjbVpoWTJWRGFHVmphMlZ5SWl3aWNtVnhkV2x5WlNJc0lsOWpiMjVtYVdkVWVYQmxjMVJwSWl3aVgybHVkR1Z5YjNCU1pYRjFhWEpsUkdWbVlYVnNkQ0lzSW1VaUxDSmZYMlZ6VFc5a2RXeGxJaXdpWkdWbVlYVnNkQ0lzSW5SNWNHVlRkV2wwWlNJc0ltVjRjRzl5ZEhNaUxDSmxlSEJ2Y25SbFpGUjVjR1ZUZFdsMFpTSXNJbU5vWldOclpYSnpJaXdpWTNKbFlYUmxRMmhsWTJ0bGNuTWlMQ0pmWkdWbVlYVnNkQ0pkTENKemIzVnlZMlZ6SWpwYklpNHVMeTR1TDNOeVl5OTBhUzlqYjI1bWFXY3RkSGx3WlhNdWRITWlYU3dpYzI5MWNtTmxjME52Ym5SbGJuUWlPbHR1ZFd4c1hTd2liV0Z3Y0dsdVozTWlPaUk3T3pzN096dEJRVWRCTEVsQlFVRkJMRzFDUVVGQkxFZEJRVUZETEU5QlFVRTdRVUZGUVN4SlFVRkJReXhqUVVGQkxFZEJRVUZETEhOQ1FVRkJMRU5CUVVGR0xFOUJRVUU3UVVGQmNVUXNVMEZCUVVVc2RVSkJRVUZETEVOQlFVRXNWMEZCUVVFc1EwRkJRU3hKUVVGQlFTeERRVUZCTEVOQlFVRkRMRlZCUVVFc1IwRkJRVVFzUTBGQlFTeExRVUZCUlN4UFFVRkJMRVZCUVVGR0xFTkJRVUU3UVVGTWNrUTdRVUZEUVRzN1FVRnRRa0U3UVVGRFR5eE5RVUZOUnl4VFFVRlRMRWRCUVVGRExFOUJRVUVzUTBGQlFVUXNVMEZCUVN4SFFVRkhSU3h6UWtGVmVFSTdRVUZGUkR0QlFVTlBMRTFCUVUxRExGRkJRVkVzUjBGQlFVWXNUMEZCUVN4RFFVRkJSU3hSUVVGQkxFZEJRVWNzU1VGQlFVTXNhME5CUVdNc1JVRkJRMFlzYzBKQlFXbENMRU5CVlhaRU8wRkJSVVE3UVVGQlFTeEpRVUZCUnl4UlFVRkJMRWRCUVVGS0xFOUJRVUVzUTBGQlFVWXNUMEZCUVN4SFFVTmxTU3hSUVVGUklpd2lhV2R1YjNKbFRHbHpkQ0k2VzExOSIsIlwidXNlIHN0cmljdFwiO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5NUyA9IHZvaWQgMDtcbmV4cG9ydHMuYXNzZXJ0SXNCb29sZWFuID0gYXNzZXJ0SXNCb29sZWFuO1xuZXhwb3J0cy5hc3NlcnRJc0RlZmluZWQgPSBhc3NlcnRJc0RlZmluZWQ7XG5leHBvcnRzLmFzc2VydElzSW5zdGFuY2VPZiA9IGFzc2VydElzSW5zdGFuY2VPZjtcbmV4cG9ydHMuYXNzZXJ0SXNOdW1iZXIgPSBhc3NlcnRJc051bWJlcjtcbmV4cG9ydHMuYXNzZXJ0SXNTdHJpbmcgPSBhc3NlcnRJc1N0cmluZztcbmV4cG9ydHMuYXNzZXJ0SXNVbmRlZmluZWQgPSBhc3NlcnRJc1VuZGVmaW5lZDtcbmV4cG9ydHMuY29sdW1ucyA9IGNvbHVtbnM7XG5leHBvcnRzLmRlZXBNZXJnZSA9IGRlZXBNZXJnZTtcbmV4cG9ydHMuZm9ybWF0TGlzdCA9IGZvcm1hdExpc3Q7XG5leHBvcnRzLmZvcm1hdE1pbGxpc2Vjb25kcyA9IGZvcm1hdE1pbGxpc2Vjb25kcztcbmV4cG9ydHMuZm9ybWF0U2Vjb25kcyA9IGZvcm1hdFNlY29uZHM7XG5leHBvcnRzLmdldFZhbGlkYXRpb25UcmVlID0gZ2V0VmFsaWRhdGlvblRyZWU7XG5leHBvcnRzLmtleW9mQ2hlY2tlciA9IGtleW9mQ2hlY2tlcjtcbmV4cG9ydHMucGx1cmFsID0gcGx1cmFsO1xudmFyIF9hc3NlcnQgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCJhc3NlcnRcIikpO1xuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChlKSB7IHJldHVybiBlICYmIGUuX19lc01vZHVsZSA/IGUgOiB7IGRlZmF1bHQ6IGUgfTsgfVxuLy8gSG9tZWJyaWRnZSBwbHVnaW4gZm9yIEhvbWUgQ29ubmVjdCBob21lIGFwcGxpYW5jZXNcbi8vIENvcHlyaWdodCDCqSAyMDIzLTIwMjUgQWxleGFuZGVyIFRob3VreWRpZGVzXG5cbi8vIE1pbGxpc2Vjb25kcyBpbiBhIHNlY29uZFxuY29uc3QgTVMgPSBleHBvcnRzLk1TID0gMTAwMDtcbi8vIFR5cGUgYXNzZXJ0aW9uc1xuZnVuY3Rpb24gYXNzZXJ0SXNEZWZpbmVkKHZhbHVlKSB7XG4gIF9hc3NlcnQuZGVmYXVsdC5ub3RTdHJpY3RFcXVhbCh2YWx1ZSwgdW5kZWZpbmVkKTtcbiAgX2Fzc2VydC5kZWZhdWx0Lm5vdFN0cmljdEVxdWFsKHZhbHVlLCBudWxsKTtcbn1cbmZ1bmN0aW9uIGFzc2VydElzVW5kZWZpbmVkKHZhbHVlKSB7XG4gIF9hc3NlcnQuZGVmYXVsdC5zdHJpY3RFcXVhbCh2YWx1ZSwgdW5kZWZpbmVkKTtcbn1cbmZ1bmN0aW9uIGFzc2VydElzU3RyaW5nKHZhbHVlKSB7XG4gIF9hc3NlcnQuZGVmYXVsdC5zdHJpY3RFcXVhbCh0eXBlb2YgdmFsdWUsICdzdHJpbmcnKTtcbn1cbmZ1bmN0aW9uIGFzc2VydElzTnVtYmVyKHZhbHVlKSB7XG4gIF9hc3NlcnQuZGVmYXVsdC5zdHJpY3RFcXVhbCh0eXBlb2YgdmFsdWUsICdudW1iZXInKTtcbn1cbmZ1bmN0aW9uIGFzc2VydElzQm9vbGVhbih2YWx1ZSkge1xuICBfYXNzZXJ0LmRlZmF1bHQuc3RyaWN0RXF1YWwodHlwZW9mIHZhbHVlLCAnYm9vbGVhbicpO1xufVxuZnVuY3Rpb24gYXNzZXJ0SXNJbnN0YW5jZU9mKHZhbHVlLCB0eXBlKSB7XG4gICgwLCBfYXNzZXJ0LmRlZmF1bHQpKHZhbHVlIGluc3RhbmNlb2YgdHlwZSwgYE5vdCBhbiBpbnN0YW5jZSBvZiAke3R5cGUubmFtZX1gKTtcbn1cbi8vIEZvcm1hdCBhIG1pbGxpc2Vjb25kcyBkdXJhdGlvblxuZnVuY3Rpb24gZm9ybWF0TWlsbGlzZWNvbmRzKG1zLCBtYXhQYXJ0cyA9IDIpIHtcbiAgaWYgKG1zIDwgMSkgcmV0dXJuICduL2EnO1xuICAvLyBTcGxpdCB0aGUgZHVyYXRpb24gaW50byBjb21wb25lbnRzXG4gIGNvbnN0IGR1cmF0aW9uID0gW1snZGF5JywgTWF0aC5mbG9vcihtcyAvICgyNCAqIDYwICogNjAgKiBNUykpXSwgWydob3VyJywgTWF0aC5mbG9vcihtcyAvICg2MCAqIDYwICogTVMpKSAlIDI0XSwgWydtaW51dGUnLCBNYXRoLmZsb29yKG1zIC8gKDYwICogTVMpKSAlIDYwXSwgWydzZWNvbmQnLCBNYXRoLmZsb29yKG1zIC8gTVMpICUgNjBdLCBbJ21pbGxpc2Vjb25kJywgTWF0aC5mbG9vcihtcykgJSBNU11dO1xuICAvLyBSZW1vdmUgYW55IGxlYWRpbmcgemVybyBjb21wb25lbnRzXG4gIHdoaWxlIChkdXJhdGlvblswXT8uWzFdID09PSAwKSBkdXJhdGlvbi5zaGlmdCgpO1xuICAvLyBDb21iaW5lIHRoZSByZXF1aXJlZCBudW1iZXIgb2YgcmVtYWluaW5nIGNvbXBvbmVudHNcbiAgcmV0dXJuIGR1cmF0aW9uLnNsaWNlKDAsIG1heFBhcnRzKS5maWx0ZXIoKFtfa2V5LCB2YWx1ZV0pID0+IHZhbHVlICE9PSAwKS5tYXAoKFtrZXksIHZhbHVlXSkgPT4gcGx1cmFsKHZhbHVlLCBrZXkpKS5qb2luKCcgJyk7XG59XG4vLyBGb3JtYXQgYSBzZWNvbmRzIGR1cmF0aW9uXG5mdW5jdGlvbiBmb3JtYXRTZWNvbmRzKHNlY29uZHMsIG1heFBhcnRzID0gMikge1xuICByZXR1cm4gZm9ybWF0TWlsbGlzZWNvbmRzKHNlY29uZHMgKiAxMDAwLCBtYXhQYXJ0cyk7XG59XG4vLyBGb3JtYXQgYSBsaXN0ICh3aXRoIE94Zm9yZCBjb21tYSlcbmZ1bmN0aW9uIGZvcm1hdExpc3QoaXRlbXMpIHtcbiAgc3dpdGNoIChpdGVtcy5sZW5ndGgpIHtcbiAgICBjYXNlIDA6XG4gICAgICByZXR1cm4gJ24vYSc7XG4gICAgY2FzZSAxOlxuICAgICAgcmV0dXJuIGl0ZW1zWzBdID8/ICcnO1xuICAgIGNhc2UgMjpcbiAgICAgIHJldHVybiBgJHtpdGVtc1swXX0gYW5kICR7aXRlbXNbMV19YDtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIFsuLi5pdGVtcy5zbGljZSgwLCAtMSksIGBhbmQgJHtpdGVtc1tpdGVtcy5sZW5ndGggLSAxXX1gXS5qb2luKCcsICcpO1xuICB9XG59XG4vLyBGb3JtYXQgYSBjb3VudGVkIG5vdW4gKGhhbmRsaW5nIG1vc3QgcmVndWxhciBjYXNlcyBhdXRvbWF0aWNhbGx5KVxuZnVuY3Rpb24gcGx1cmFsKGNvdW50LCBub3VuLCBzaG93Q291bnQgPSB0cnVlKSB7XG4gIGNvbnN0IFtzaW5ndWxhciwgcGx1cmFsXSA9IEFycmF5LmlzQXJyYXkobm91bikgPyBub3VuIDogW25vdW4sICcnXTtcbiAgbm91biA9IGNvdW50ID09PSAxID8gc2luZ3VsYXIgOiBwbHVyYWw7XG4gIGlmICghbm91bikge1xuICAgIC8vIEFwcGx5IHJlZ3VsYXIgcnVsZXNcbiAgICBjb25zdCBydWxlcyA9IFtbJ29uJCcsICdhJywgMl0sXG4gICAgLy8gcGhlbm9tZW5vbi9waGVub21lbmEgY3JpdGVyaW9uL2NyaXRlcmlhXG4gICAgWyd1cyQnLCAnaScsIDFdLFxuICAgIC8vICAgICBjYWN0dXMvY2FjdGkgICAgICAgICBmb2N1cy9mb2NpXG4gICAgWydbXmFlaW91XXkkJywgJ2llcycsIDFdLFxuICAgIC8vICAgICAgICBjdHkvY2l0ZXMgICAgICAgICBwdXBweS9wdXBwaWVzXG4gICAgWycoY2h8aXN8b3xzfHNofHh8eikkJywgJ2VzJywgMF0sXG4gICAgLy8gICAgICAgaXJpcy9pcmlzZXMgICAgICAgIHRydXNzL3RydXNzZXNcbiAgICBbJycsICdzJywgMF0gLy8gICAgICAgIGNhdC9jYXRzICAgICAgICAgIGhvdXNlL2hvdXNlc1xuICAgIF07XG4gICAgY29uc3QgcnVsZSA9IHJ1bGVzLmZpbmQoKFtlbmRpbmddKSA9PiBuZXcgUmVnRXhwKGVuZGluZywgJ2knKS50ZXN0KHNpbmd1bGFyKSk7XG4gICAgYXNzZXJ0SXNEZWZpbmVkKHJ1bGUpO1xuICAgIGNvbnN0IG1hdGNoQ2FzZSA9IHMgPT4gc2luZ3VsYXIgPT09IHNpbmd1bGFyLnRvVXBwZXJDYXNlKCkgPyBzLnRvVXBwZXJDYXNlKCkgOiBzO1xuICAgIG5vdW4gPSBzaW5ndWxhci5zdWJzdHJpbmcoMCwgc2luZ3VsYXIubGVuZ3RoIC0gcnVsZVsyXSkuY29uY2F0KG1hdGNoQ2FzZShydWxlWzFdKSk7XG4gIH1cbiAgcmV0dXJuIHNob3dDb3VudCA/IGAke2NvdW50fSAke25vdW59YCA6IG5vdW47XG59XG4vLyBGb3JtYXQgc3RyaW5ncyBpbiBjb2x1bW5zXG5mdW5jdGlvbiBjb2x1bW5zKHJvd3MsIHNlcGFyYXRvciA9ICcgICcpIHtcbiAgLy8gRGV0ZXJtaW5lIHRoZSByZXF1aXJlZCBjb2x1bW4gd2lkdGhzXG4gIGNvbnN0IHdpZHRoID0gW107XG4gIHJvd3MuZm9yRWFjaChyb3cgPT4ge1xuICAgIHJvdy5mb3JFYWNoKCh2YWx1ZSwgaW5kZXgpID0+IHtcbiAgICAgIHdpZHRoW2luZGV4XSA9IE1hdGgubWF4KHdpZHRoW2luZGV4XSA/PyAwLCB2YWx1ZS5sZW5ndGgpO1xuICAgIH0pO1xuICB9KTtcbiAgd2lkdGguc3BsaWNlKC0xLCAxLCAwKTtcbiAgLy8gRm9ybWF0IHRoZSByb3dzXG4gIHJldHVybiByb3dzLm1hcChyb3cgPT4gcm93Lm1hcCgodmFsdWUsIGluZGV4KSA9PiB2YWx1ZS5wYWRFbmQod2lkdGhbaW5kZXhdID8/IDApKS5qb2luKHNlcGFyYXRvcikpO1xufVxuLy8gUmVjdXJzaXZlIG9iamVjdCBhc3NpZ25tZW50LCBza2lwcGluZyB1bmRlZmluZWQgdmFsdWVzXG5mdW5jdGlvbiBkZWVwTWVyZ2UoLi4ub2JqZWN0cykge1xuICBjb25zdCBpc09iamVjdCA9IHZhbHVlID0+IHZhbHVlICE9PSB1bmRlZmluZWQgJiYgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiAhQXJyYXkuaXNBcnJheSh2YWx1ZSk7XG4gIHJldHVybiBvYmplY3RzLnJlZHVjZSgoYWNjLCBvYmplY3QpID0+IHtcbiAgICBPYmplY3QuZW50cmllcyhvYmplY3QpLmZvckVhY2goKFtrZXksIHZhbHVlXSkgPT4ge1xuICAgICAgY29uc3QgYWNjVmFsdWUgPSBhY2Nba2V5XTtcbiAgICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSByZXR1cm47XG4gICAgICBpZiAoaXNPYmplY3QoYWNjVmFsdWUpICYmIGlzT2JqZWN0KHZhbHVlKSkgYWNjW2tleV0gPSBkZWVwTWVyZ2UoYWNjVmFsdWUsIHZhbHVlKTtlbHNlIGFjY1trZXldID0gdmFsdWU7XG4gICAgfSk7XG4gICAgcmV0dXJuIGFjYztcbiAgfSwge30pO1xufVxuLy8gQ29udmVydCBjaGVja2VyIHZhbGlkYXRpb24gZXJyb3IgaW50byBsaW5lcyBvZiB0ZXh0XG5mdW5jdGlvbiBnZXRWYWxpZGF0aW9uVHJlZShlcnJvcnMpIHtcbiAgY29uc3QgbGluZXMgPSBbXTtcbiAgZXJyb3JzLmZvckVhY2goKGVycm9yLCBpbmRleCkgPT4ge1xuICAgIGNvbnN0IHByZWZpeCA9IChhLCBiKSA9PiBpbmRleCA8IGVycm9ycy5sZW5ndGggLSAxID8gYSA6IGI7XG4gICAgbGluZXMucHVzaChgJHtwcmVmaXgoJ+KUnOKUgCAnLCAn4pSU4pSAICcpfSR7ZXJyb3IucGF0aH0gJHtlcnJvci5tZXNzYWdlfWApO1xuICAgIGlmIChlcnJvci5uZXN0ZWQpIHtcbiAgICAgIGNvbnN0IG5lc3RlZCA9IGdldFZhbGlkYXRpb25UcmVlKGVycm9yLm5lc3RlZCk7XG4gICAgICBsaW5lcy5wdXNoKC4uLm5lc3RlZC5tYXAobGluZSA9PiBgJHtwcmVmaXgoJ+KUgiAgJywgJyAgICcpfSAke2xpbmV9YCkpO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiBsaW5lcztcbn1cbi8vIEV4dHJhY3QgcHJvcGVydHkga2V5cyBvciB1bmlvbiBsaXRlcmFsIGZyb20gYSB0aS1pbnRlcmZhY2UtY2hlY2tlciB0eXBlXG5mdW5jdGlvbiBrZXlvZkNoZWNrZXIodHlwZVN1aXRlLCB0eXBlKSB7XG4gIGNvbnN0IGNoZWNrZXIgPSB0eXBlO1xuICAvLyBUSWZhY2VcbiAgY29uc3QgcHJvcHMgPSBbXTtcbiAgaWYgKGNoZWNrZXIucHJvcFNldCBpbnN0YW5jZW9mIFNldCkge1xuICAgIHByb3BzLnB1c2goLi4uY2hlY2tlci5wcm9wU2V0KTtcbiAgfVxuICBpZiAoQXJyYXkuaXNBcnJheShjaGVja2VyLmJhc2VzKSkge1xuICAgIGZvciAoY29uc3QgYmFzZSBvZiBjaGVja2VyLmJhc2VzKSB7XG4gICAgICBjb25zdCBiYXNlVHlwZSA9IHR5cGVTdWl0ZVtiYXNlXTtcbiAgICAgIGFzc2VydElzRGVmaW5lZChiYXNlVHlwZSk7XG4gICAgICBwcm9wcy5wdXNoKC4uLmtleW9mQ2hlY2tlcih0eXBlU3VpdGUsIGJhc2VUeXBlKSk7XG4gICAgfVxuICB9XG4gIC8vIFRVbmlvbiBvciBUSW50ZXJzZWN0aW9uXG4gIGlmIChBcnJheS5pc0FycmF5KGNoZWNrZXIudHR5cGVzKSkge1xuICAgIGZvciAoY29uc3QgdHR5cGUgb2YgY2hlY2tlci50dHlwZXMpIHByb3BzLnB1c2goLi4ua2V5b2ZDaGVja2VyKHR5cGVTdWl0ZSwgdHR5cGUpKTtcbiAgfVxuICAvLyBURW51bVxuICBpZiAoY2hlY2tlci52YWxpZFZhbHVlcyBpbnN0YW5jZW9mIFNldCkge1xuICAgIHByb3BzLnB1c2goLi4uY2hlY2tlci52YWxpZFZhbHVlcyk7XG4gIH1cbiAgaWYgKHR5cGVvZiBjaGVja2VyLnZhbHVlID09PSAnc3RyaW5nJykge1xuICAgIC8vIFRMaXRlcmFsXG4gICAgcHJvcHMucHVzaChjaGVja2VyLnZhbHVlKTtcbiAgfSBlbHNlIGlmICh0eXBlb2YgY2hlY2tlci5uYW1lID09PSAnc3RyaW5nJykge1xuICAgIC8vIFROYW1lXG4gICAgY29uc3QgbmFtZVR5cGUgPSB0eXBlU3VpdGVbY2hlY2tlci5uYW1lXTtcbiAgICBhc3NlcnRJc0RlZmluZWQobmFtZVR5cGUpO1xuICAgIHByb3BzLnB1c2goLi4ua2V5b2ZDaGVja2VyKHR5cGVTdWl0ZSwgbmFtZVR5cGUpKTtcbiAgfVxuICByZXR1cm4gcHJvcHM7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldD11dGYtODtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnVZVzFsY3lJNld5SmZZWE56WlhKMElpd2lYMmx1ZEdWeWIzQlNaWEYxYVhKbFJHVm1ZWFZzZENJc0luSmxjWFZwY21VaUxDSmxJaXdpWDE5bGMwMXZaSFZzWlNJc0ltUmxabUYxYkhRaUxDSk5VeUlzSW1WNGNHOXlkSE1pTENKaGMzTmxjblJKYzBSbFptbHVaV1FpTENKMllXeDFaU0lzSW1GemMyVnlkQ0lzSW01dmRGTjBjbWxqZEVWeGRXRnNJaXdpZFc1a1pXWnBibVZrSWl3aVlYTnpaWEowU1hOVmJtUmxabWx1WldRaUxDSnpkSEpwWTNSRmNYVmhiQ0lzSW1GemMyVnlkRWx6VTNSeWFXNW5JaXdpWVhOelpYSjBTWE5PZFcxaVpYSWlMQ0poYzNObGNuUkpjMEp2YjJ4bFlXNGlMQ0poYzNObGNuUkpjMGx1YzNSaGJtTmxUMllpTENKMGVYQmxJaXdpYm1GdFpTSXNJbVp2Y20xaGRFMXBiR3hwYzJWamIyNWtjeUlzSW0xeklpd2liV0Y0VUdGeWRITWlMQ0prZFhKaGRHbHZiaUlzSWsxaGRHZ2lMQ0ptYkc5dmNpSXNJbk5vYVdaMElpd2ljMnhwWTJVaUxDSm1hV3gwWlhJaUxDSmZhMlY1SWl3aWJXRndJaXdpYTJWNUlpd2ljR3gxY21Gc0lpd2lhbTlwYmlJc0ltWnZjbTFoZEZObFkyOXVaSE1pTENKelpXTnZibVJ6SWl3aVptOXliV0YwVEdsemRDSXNJbWwwWlcxeklpd2liR1Z1WjNSb0lpd2lZMjkxYm5RaUxDSnViM1Z1SWl3aWMyaHZkME52ZFc1MElpd2ljMmx1WjNWc1lYSWlMQ0pCY25KaGVTSXNJbWx6UVhKeVlYa2lMQ0p5ZFd4bGN5SXNJbkoxYkdVaUxDSm1hVzVrSWl3aVpXNWthVzVuSWl3aVVtVm5SWGh3SWl3aWRHVnpkQ0lzSW0xaGRHTm9RMkZ6WlNJc0luTWlMQ0owYjFWd2NHVnlRMkZ6WlNJc0luTjFZbk4wY21sdVp5SXNJbU52Ym1OaGRDSXNJbU52YkhWdGJuTWlMQ0p5YjNkeklpd2ljMlZ3WVhKaGRHOXlJaXdpZDJsa2RHZ2lMQ0ptYjNKRllXTm9JaXdpY205M0lpd2lhVzVrWlhnaUxDSnRZWGdpTENKemNHeHBZMlVpTENKd1lXUkZibVFpTENKa1pXVndUV1Z5WjJVaUxDSnZZbXBsWTNSeklpd2lhWE5QWW1wbFkzUWlMQ0p5WldSMVkyVWlMQ0poWTJNaUxDSnZZbXBsWTNRaUxDSlBZbXBsWTNRaUxDSmxiblJ5YVdWeklpd2lZV05qVm1Gc2RXVWlMQ0puWlhSV1lXeHBaR0YwYVc5dVZISmxaU0lzSW1WeWNtOXljeUlzSW14cGJtVnpJaXdpWlhKeWIzSWlMQ0p3Y21WbWFYZ2lMQ0poSWl3aVlpSXNJbkIxYzJnaUxDSndZWFJvSWl3aWJXVnpjMkZuWlNJc0ltNWxjM1JsWkNJc0lteHBibVVpTENKclpYbHZaa05vWldOclpYSWlMQ0owZVhCbFUzVnBkR1VpTENKamFHVmphMlZ5SWl3aWNISnZjSE1pTENKd2NtOXdVMlYwSWl3aVUyVjBJaXdpWW1GelpYTWlMQ0ppWVhObElpd2lZbUZ6WlZSNWNHVWlMQ0owZEhsd1pYTWlMQ0owZEhsd1pTSXNJblpoYkdsa1ZtRnNkV1Z6SWl3aWJtRnRaVlI1Y0dVaVhTd2ljMjkxY21ObGN5STZXeUl1TGk5emNtTXZkWFJwYkhNdWRITWlYU3dpYzI5MWNtTmxjME52Ym5SbGJuUWlPbHR1ZFd4c1hTd2liV0Z3Y0dsdVozTWlPaUk3T3pzN096czdPenM3T3pzN096czdPenM3TzBGQlIwRXNTVUZCUVVFc1QwRkJRU3hIUVVGQlF5eHpRa0ZCUVN4RFFVRkJReXhQUVVGQk8wRkJRVFJDTEZOQlFVRkVMSFZDUVVGQlJTeERRVUZCTEZkQlFVRkJMRU5CUVVFc1NVRkJRVUVzUTBGQlFTeERRVUZCUXl4VlFVRkJMRWRCUVVGRUxFTkJRVUVzUzBGQlFVVXNUMEZCUVN4RlFVRkJSaXhEUVVGQk8wRkJTRFZDTzBGQlEwRTdPMEZCUzBFN1FVRkRUeXhOUVVGTlJ5eEZRVUZGTEVkQlFVRkRMRTlCUVVFc1EwRkJRVVFzUlVGQlFTeEhRVUZITEVsQlFVazdRVUZYZEVJN1FVRkRUU3hUUVVGVlJTeGxRVUZsUVN4RFFVRlBReXhMUVVGWE8wVkJRemREUXl4bFFVRk5MRU5CUVVORExHTkJRV01zUTBGQlEwWXNTMEZCU3l4RlFVRkZSeXhUUVVGVExFTkJRVU03UlVGRGRrTkdMR1ZCUVUwc1EwRkJRME1zWTBGQll5eERRVUZEUml4TFFVRkxMRVZCUVVVc1NVRkJTU3hEUVVGRE8wRkJRM1JETzBGQlEwMHNVMEZCVlVrc2FVSkJRV2xDUVN4RFFVRkRTaXhMUVVGak8wVkJRelZEUXl4bFFVRk5MRU5CUVVOSkxGZEJRVmNzUTBGQlEwd3NTMEZCU3l4RlFVRkZSeXhUUVVGVExFTkJRVU03UVVGRGVFTTdRVUZEVFN4VFFVRlZSeXhqUVVGalFTeERRVUZEVGl4TFFVRmpPMFZCUTNwRFF5eGxRVUZOTEVOQlFVTkpMRmRCUVZjc1EwRkJReXhQUVVGUFRDeExRVUZMTEVWQlFVVXNVVUZCVVN4RFFVRkRPMEZCUXpsRE8wRkJRMDBzVTBGQlZVOHNZMEZCWTBFc1EwRkJRMUFzUzBGQll6dEZRVU42UTBNc1pVRkJUU3hEUVVGRFNTeFhRVUZYTEVOQlFVTXNUMEZCVDB3c1MwRkJTeXhGUVVGRkxGRkJRVkVzUTBGQlF6dEJRVU01UXp0QlFVTk5MRk5CUVZWUkxHVkJRV1ZCTEVOQlFVTlNMRXRCUVdNN1JVRkRNVU5ETEdWQlFVMHNRMEZCUTBrc1YwRkJWeXhEUVVGRExFOUJRVTlNTEV0QlFVc3NSVUZCUlN4VFFVRlRMRU5CUVVNN1FVRkRMME03UVVGRFRTeFRRVUZWVXl4clFrRkJhMEpCTEVOQlFYTkNWQ3hMUVVGakxFVkJRVVZWTEVsQlFYVkNPMFZCUXpOR0xFbEJRVUZVTEdWQlFVMHNSVUZCUTBRc1MwRkJTeXhaUVVGWlZTeEpRVUZKTEVWQlFVVXNjMEpCUVhOQ1FTeEpRVUZKTEVOQlFVTkRMRWxCUVVrc1JVRkJSU3hEUVVGRE8wRkJRM0JGTzBGQlJVRTdRVUZEVFN4VFFVRlZReXhyUWtGQmEwSkJMRU5CUVVORExFVkJRVlVzUlVGQlJVTXNVVUZCVVN4SFFVRkhMRU5CUVVNN1JVRkRka1FzU1VGQlNVUXNSVUZCUlN4SFFVRkhMRU5CUVVNc1JVRkJSU3hQUVVGUExFdEJRVXM3UlVGRmVFSTdSVUZEUVN4TlFVRk5SU3hSUVVGUkxFZEJRWFZDTEVOQlEycERMRU5CUVVNc1MwRkJTeXhGUVVGVlF5eEpRVUZKTEVOQlFVTkRMRXRCUVVzc1EwRkJRMG9zUlVGQlJTeEpRVUZKTEVWQlFVVXNSMEZCUnl4RlFVRkZMRWRCUVVjc1JVRkJSU3hIUVVGSGFFSXNSVUZCUlN4RFFVRkRMRU5CUVVNc1EwRkJUU3hGUVVNeFJDeERRVUZETEUxQlFVMHNSVUZCVTIxQ0xFbEJRVWtzUTBGQlEwTXNTMEZCU3l4RFFVRkRTaXhGUVVGRkxFbEJRVk1zUlVGQlJTeEhRVUZITEVWQlFVVXNSMEZCUjJoQ0xFVkJRVVVzUTBGQlF5eERRVUZETEVkQlFVY3NSVUZCUlN4RFFVRkRMRVZCUXpGRUxFTkJRVU1zVVVGQlVTeEZRVUZQYlVJc1NVRkJTU3hEUVVGRFF5eExRVUZMTEVOQlFVTktMRVZCUVVVc1NVRkJZeXhGUVVGRkxFZEJRVWRvUWl4RlFVRkZMRU5CUVVNc1EwRkJReXhIUVVGSExFVkJRVVVzUTBGQlF5eEZRVU14UkN4RFFVRkRMRkZCUVZFc1JVRkJUMjFDTEVsQlFVa3NRMEZCUTBNc1MwRkJTeXhEUVVGRFNpeEZRVUZGTEVkQlFXMUNhRUlzUlVGQlJTeERRVUZGTEVkQlFVY3NSVUZCUlN4RFFVRkRMRVZCUXpGRUxFTkJRVU1zWVVGQllTeEZRVUZGYlVJc1NVRkJTU3hEUVVGRFF5eExRVUZMTEVOQlFVTktMRVZCUVVVc1EwRkJkVUlzUjBGQlIyaENMRVZCUVVVc1EwRkJReXhEUVVNM1JEdEZRVVZFTzBWQlEwRXNUMEZCVDJ0Q0xGRkJRVkVzUTBGQlF5eERRVUZETEVOQlFVTXNSMEZCUnl4RFFVRkRMRU5CUVVNc1MwRkJTeXhEUVVGRExFVkJRVVZCTEZGQlFWRXNRMEZCUTBjc1MwRkJTeXhGUVVGRk8wVkJSUzlETzBWQlEwRXNUMEZCVDBnc1VVRkJVU3hEUVVGRFNTeExRVUZMTEVOQlFVTXNRMEZCUXl4RlFVRkZUQ3hSUVVGUkxFTkJRVU1zUTBGRE4wSk5MRTFCUVUwc1EwRkJReXhEUVVGRExFTkJRVU5ETEVsQlFVa3NSVUZCUlhKQ0xFdEJRVXNzUTBGQlF5eExRVUZMUVN4TFFVRkxMRXRCUVVzc1EwRkJReXhEUVVGRExFTkJRM1JEYzBJc1IwRkJSeXhEUVVGRExFTkJRVU1zUTBGQlEwTXNSMEZCUnl4RlFVRkZka0lzUzBGQlN5eERRVUZETEV0QlFVdDNRaXhOUVVGTkxFTkJRVU40UWl4TFFVRkxMRVZCUVVWMVFpeEhRVUZITEVOQlFVTXNRMEZCUXl4RFFVTjZRMFVzU1VGQlNTeERRVUZETEVkQlFVY3NRMEZCUXp0QlFVTnNRanRCUVVWQk8wRkJRMDBzVTBGQlZVTXNZVUZCWVVFc1EwRkJRME1zVDBGQlpTeEZRVUZGWWl4UlFVRlJMRWRCUVVjc1EwRkJRenRGUVVOMlJDeFBRVUZQUml4clFrRkJhMElzUTBGQlEyVXNUMEZCVHl4SFFVRkhMRWxCUVVrc1JVRkJSV0lzVVVGQlVTeERRVUZETzBGQlEzWkVPMEZCUlVFN1FVRkRUU3hUUVVGVll5eFZRVUZWUVN4RFFVRkRReXhMUVVGbE8wVkJRM1JETEZGQlFWRkJMRXRCUVVzc1EwRkJRME1zVFVGQlRUdEpRVU53UWl4TFFVRkxMRU5CUVVNN1RVRkJUU3hQUVVGUExFdEJRVXM3U1VGRGVFSXNTMEZCU3l4RFFVRkRPMDFCUVUwc1QwRkJUMFFzUzBGQlN5eERRVUZETEVOQlFVTXNRMEZCUXl4SlFVRkpMRVZCUVVVN1NVRkRha01zUzBGQlN5eERRVUZETzAxQlFVMHNUMEZCVHl4SFFVRkhRU3hMUVVGTExFTkJRVU1zUTBGQlF5eERRVUZETEZGQlFWRkJMRXRCUVVzc1EwRkJReXhEUVVGRExFTkJRVU1zUlVGQlJUdEpRVU5vUkR0TlFVRlpMRTlCUVU4c1EwRkJReXhIUVVGSFFTeExRVUZMTEVOQlFVTldMRXRCUVVzc1EwRkJReXhEUVVGRExFVkJRVVVzUTBGQlF5eERRVUZETEVOQlFVTXNSVUZCUlN4UFFVRlBWU3hMUVVGTExFTkJRVU5CTEV0QlFVc3NRMEZCUTBNc1RVRkJUU3hIUVVGSExFTkJRVU1zUTBGQlF5eEZRVUZGTEVOQlFVTXNRMEZCUTB3c1NVRkJTU3hEUVVGRExFbEJRVWtzUTBGQlF6dEZRVU4yUmp0QlFVTktPMEZCUlVFN1FVRkRUU3hUUVVGVlJDeE5RVUZOUVN4RFFVRkRUeXhMUVVGaExFVkJRVVZETEVsQlFTdENMRVZCUVVWRExGTkJRVk1zUjBGQlJ5eEpRVUZKTzBWQlEyNUdMRTFCUVUwc1EwRkJRME1zVVVGQlVTeEZRVUZGVml4TlFVRk5MRU5CUVVNc1IwRkJSMWNzUzBGQlN5eERRVUZEUXl4UFFVRlBMRU5CUVVOS0xFbEJRVWtzUTBGQlF5eEhRVUZIUVN4SlFVRkpMRWRCUVVjc1EwRkJRMEVzU1VGQlNTeEZRVUZGTEVWQlFVVXNRMEZCUXp0RlFVTnNSVUVzU1VGQlNTeEhRVUZIUkN4TFFVRkxMRXRCUVVzc1EwRkJReXhIUVVGSFJ5eFJRVUZSTEVkQlFVZFdMRTFCUVUwN1JVRkRkRU1zU1VGQlNTeERRVUZEVVN4SlFVRkpMRVZCUVVVN1NVRkRVRHRKUVVOQkxFMUJRVTFMTEV0QlFVc3NSMEZCSzBJc1EwRkRkRU1zUTBGQlF5eExRVUZMTEVWQlFXdENMRWRCUVVjc1JVRkJTU3hEUVVGRExFTkJRVU03U1VGQlJUdEpRVU51UXl4RFFVRkRMRXRCUVVzc1JVRkJhMElzUjBGQlJ5eEZRVUZKTEVOQlFVTXNRMEZCUXp0SlFVRkZPMGxCUTI1RExFTkJRVU1zV1VGQldTeEZRVUZYTEV0QlFVc3NSVUZCUlN4RFFVRkRMRU5CUVVNN1NVRkJSVHRKUVVOdVF5eERRVUZETEhGQ1FVRnhRaXhGUVVGRkxFbEJRVWtzUlVGQlJ5eERRVUZETEVOQlFVTTdTVUZCUlR0SlFVTnVReXhEUVVGRExFVkJRVVVzUlVGQmNVSXNSMEZCUnl4RlFVRkpMRU5CUVVNc1EwRkJReXhEUVVGRk8wbEJRVUVzUTBGRGRFTTdTVUZEUkN4TlFVRk5ReXhKUVVGSkxFZEJRVWRFTEV0QlFVc3NRMEZCUTBVc1NVRkJTU3hEUVVGRExFTkJRVU1zUTBGQlEwTXNUVUZCVFN4RFFVRkRMRXRCUVVzc1NVRkJTVU1zVFVGQlRTeERRVUZEUkN4TlFVRk5MRVZCUVVVc1IwRkJSeXhEUVVGRExFTkJRVU5GTEVsQlFVa3NRMEZCUTFJc1VVRkJVU3hEUVVGRExFTkJRVU03U1VGRE4wVnVReXhsUVVGbExFTkJRVU4xUXl4SlFVRkpMRU5CUVVNN1NVRkRja0lzVFVGQlRVc3NVMEZCVXl4SFFVRkpReXhEUVVGVExFbEJRV0ZXTEZGQlFWRXNTMEZCUzBFc1VVRkJVU3hEUVVGRFZ5eFhRVUZYTEVWQlFVVXNSMEZCUjBRc1EwRkJReXhEUVVGRFF5eFhRVUZYTEVWQlFVVXNSMEZCUjBRc1EwRkJRenRKUVVOc1Ixb3NTVUZCU1N4SFFVRkhSU3hSUVVGUkxFTkJRVU5aTEZOQlFWTXNRMEZCUXl4RFFVRkRMRVZCUVVWYUxGRkJRVkVzUTBGQlEwb3NUVUZCVFN4SFFVRkhVU3hKUVVGSkxFTkJRVU1zUTBGQlF5eERRVUZETEVOQlFVTXNRMEZCUTFNc1RVRkJUU3hEUVVGRFNpeFRRVUZUTEVOQlFVTk1MRWxCUVVrc1EwRkJReXhEUVVGRExFTkJRVU1zUTBGQlF5eERRVUZETzBWQlEzUkdPMFZCUTBFc1QwRkJUMHdzVTBGQlV5eEhRVUZITEVkQlFVZEdMRXRCUVVzc1NVRkJTVU1zU1VGQlNTeEZRVUZGTEVkQlFVZEJMRWxCUVVrN1FVRkRhRVE3UVVGRlFUdEJRVU5OTEZOQlFWVm5RaXhQUVVGUFFTeERRVUZEUXl4SlFVRm5RaXhGUVVGRlF5eFRRVUZUTEVkQlFVY3NTVUZCU1R0RlFVTjBSRHRGUVVOQkxFMUJRVTFETEV0QlFVc3NSMEZCWVN4RlFVRkZPMFZCUXpGQ1JpeEpRVUZKTEVOQlFVTkhMRTlCUVU4c1EwRkJRME1zUjBGQlJ5eEpRVUZITzBsQlEyWkJMRWRCUVVjc1EwRkJRMFFzVDBGQlR5eERRVUZETEVOQlFVTndSQ3hMUVVGTExFVkJRVVZ6UkN4TFFVRkxMRXRCUVVrN1RVRkRla0pJTEV0QlFVc3NRMEZCUTBjc1MwRkJTeXhEUVVGRExFZEJRVWQwUXl4SlFVRkpMRU5CUVVOMVF5eEhRVUZITEVOQlFVTktMRXRCUVVzc1EwRkJRMGNzUzBGQlN5eERRVUZETEVsQlFVa3NRMEZCUXl4RlFVRkZkRVFzUzBGQlN5eERRVUZET0VJc1RVRkJUU3hEUVVGRE8wbEJRelZFTEVOQlFVTXNRMEZCUXp0RlFVTk9MRU5CUVVNc1EwRkJRenRGUVVOR2NVSXNTMEZCU3l4RFFVRkRTeXhOUVVGTkxFTkJRVU1zUTBGQlF5eERRVUZETEVWQlFVVXNRMEZCUXl4RlFVRkZMRU5CUVVNc1EwRkJRenRGUVVWMFFqdEZRVU5CTEU5QlFVOVFMRWxCUVVrc1EwRkJRek5DTEVkQlFVY3NRMEZCUXl0Q0xFZEJRVWNzU1VGQlNVRXNSMEZCUnl4RFFVRkRMMElzUjBGQlJ5eERRVUZETEVOQlFVTjBRaXhMUVVGTExFVkJRVVZ6UkN4TFFVRkxMRXRCUVV0MFJDeExRVUZMTEVOQlFVTjVSQ3hOUVVGTkxFTkJRVU5PTEV0QlFVc3NRMEZCUTBjc1MwRkJTeXhEUVVGRExFbEJRVWtzUTBGQlF5eERRVUZETEVOQlFVTXNRMEZCUXpkQ0xFbEJRVWtzUTBGQlEzbENMRk5CUVZNc1EwRkJReXhEUVVGRE8wRkJRM1JITzBGQlJVRTdRVUZEVFN4VFFVRlZVU3hUUVVGVFFTeERRVUZ6UWl4SFFVRkhReXhQUVVGdFF6dEZRVU5xUml4TlFVRk5ReXhSUVVGUkxFZEJRVWsxUkN4TFFVRmpMRWxCUXpWQ1FTeExRVUZMTEV0QlFVdEhMRk5CUVZNc1NVRkJTU3hQUVVGUFNDeExRVUZMTEV0QlFVc3NVVUZCVVN4SlFVRkpMRU5CUVVOdFF5eExRVUZMTEVOQlFVTkRMRTlCUVU4c1EwRkJRM0JETEV0QlFVc3NRMEZCUXp0RlFVTTNSU3hQUVVGUE1rUXNUMEZCVHl4RFFVRkRSU3hOUVVGTkxFTkJRVU1zUTBGQlEwTXNSMEZCTkVJc1JVRkJSVU1zVFVGQll5eExRVUZKTzBsQlEyNUZReXhOUVVGTkxFTkJRVU5ETEU5QlFVOHNRMEZCUTBZc1RVRkJUU3hEUVVGRExFTkJRVU5ZTEU5QlFVOHNRMEZCUXl4RFFVRkRMRU5CUVVNM1FpeEhRVUZITEVWQlFVVjJRaXhMUVVGTExFTkJRVU1zUzBGQlNUdE5RVU0xUXl4TlFVRk5hMFVzVVVGQlVTeEhRVUZIU2l4SFFVRkhMRU5CUVVOMlF5eEhRVUZITEVOQlFVTTdUVUZEZWtJc1NVRkJTWFpDTEV0QlFVc3NTMEZCUzBjc1UwRkJVeXhGUVVGRk8wMUJRM3BDTEVsQlFVbDVSQ3hSUVVGUkxFTkJRVU5OTEZGQlFWRXNRMEZCUXl4SlFVRkpUaXhSUVVGUkxFTkJRVU0xUkN4TFFVRkxMRU5CUVVNc1JVRkJSVGhFTEVkQlFVY3NRMEZCUTNaRExFZEJRVWNzUTBGQlF5eEhRVUZIYlVNc1UwRkJVeXhEUVVGRFVTeFJRVUZSTEVWQlFVVnNSU3hMUVVGTExFTkJRVU1zUTBGQlF5eExRVU0xUlRoRUxFZEJRVWNzUTBGQlEzWkRMRWRCUVVjc1EwRkJReXhIUVVGSGRrSXNTMEZCU3p0SlFVTjZRaXhEUVVGRExFTkJRVU03U1VGRFJpeFBRVUZQT0VRc1IwRkJSenRGUVVOa0xFTkJRVU1zUlVGQlJTeEZRVUZGTEVOQlFWTTdRVUZEYkVJN1FVRlJRVHRCUVVOTkxGTkJRVlZMTEdsQ1FVRnBRa0VzUTBGQlEwTXNUVUZCYzBJN1JVRkRjRVFzVFVGQlRVTXNTMEZCU3l4SFFVRmhMRVZCUVVVN1JVRkRNVUpFTEUxQlFVMHNRMEZCUTJoQ0xFOUJRVThzUTBGQlF5eERRVUZEYTBJc1MwRkJTeXhGUVVGRmFFSXNTMEZCU3l4TFFVRkpPMGxCUXpWQ0xFMUJRVTFwUWl4TlFVRk5MRWRCUVVkQkxFTkJRVU5ETEVOQlFWTXNSVUZCUlVNc1EwRkJVeXhMUVVGaGJrSXNTMEZCU3l4SFFVRkhZeXhOUVVGTkxFTkJRVU4wUXl4TlFVRk5MRWRCUVVjc1EwRkJReXhIUVVGSE1FTXNRMEZCUXl4SFFVRkhReXhEUVVGRE8wbEJRMnhHU2l4TFFVRkxMRU5CUVVOTExFbEJRVWtzUTBGQlF5eEhRVUZIU0N4TlFVRk5MRU5CUVVNc1MwRkJTeXhGUVVGRkxFdEJRVXNzUTBGQlF5eEhRVUZIUkN4TFFVRkxMRU5CUVVOTExFbEJRVWtzU1VGQlNVd3NTMEZCU3l4RFFVRkRUU3hQUVVGUExFVkJRVVVzUTBGQlF6dEpRVU51UlN4SlFVRkpUaXhMUVVGTExFTkJRVU5QTEUxQlFVMHNSVUZCUlR0TlFVTmtMRTFCUVUxQkxFMUJRVTBzUjBGQlIxWXNhVUpCUVdsQ0xFTkJRVU5ITEV0QlFVc3NRMEZCUTA4c1RVRkJUU3hEUVVGRE8wMUJRemxEVWl4TFFVRkxMRU5CUVVOTExFbEJRVWtzUTBGQlF5eEhRVUZIUnl4TlFVRk5MRU5CUVVOMlJDeEhRVUZITEVOQlFVTjNSQ3hKUVVGSkxFbEJRVWtzUjBGQlIxQXNUVUZCVFN4RFFVRkRMRXRCUVVzc1JVRkJSU3hMUVVGTExFTkJRVU1zU1VGQlNVOHNTVUZCU1N4RlFVRkZMRU5CUVVNc1EwRkJRenRKUVVONFJUdEZRVU5LTEVOQlFVTXNRMEZCUXp0RlFVTkdMRTlCUVU5VUxFdEJRVXM3UVVGRGFFSTdRVUZGUVR0QlFVTk5MRk5CUVZWVkxGbEJRVmxCTEVOQlFVTkRMRk5CUVhGQ0xFVkJRVVYwUlN4SlFVRlhPMFZCUXpORUxFMUJRVTExUlN4UFFVRlBMRWRCUVVkMlJTeEpRVTltTzBWQlJVUTdSVUZEUVN4TlFVRk5kMFVzUzBGQlN5eEhRVUZITEVWQlFVVTdSVUZEYUVJc1NVRkJTVVFzVDBGQlR5eERRVUZEUlN4UFFVRlBMRmxCUVZsRExFZEJRVWNzUlVGQlJUdEpRVU5vUTBZc1MwRkJTeXhEUVVGRFVpeEpRVUZKTEVOQlFVTXNSMEZCUjA4c1QwRkJUeXhEUVVGRFJTeFBRVUZQTEVOQlFVTTdSVUZEYkVNN1JVRkRRU3hKUVVGSmFFUXNTMEZCU3l4RFFVRkRReXhQUVVGUExFTkJRVU0yUXl4UFFVRlBMRU5CUVVOSkxFdEJRVXNzUTBGQlF5eEZRVUZGTzBsQlF6bENMRXRCUVVzc1RVRkJUVU1zU1VGQlNTeEpRVUZKVEN4UFFVRlBMRU5CUVVOSkxFdEJRVXNzUlVGQlJUdE5RVU01UWl4TlFVRk5SU3hSUVVGUkxFZEJRVWRRTEZOQlFWTXNRMEZCUTAwc1NVRkJTU3hEUVVGRE8wMUJRMmhEZGtZc1pVRkJaU3hEUVVGRGQwWXNVVUZCVVN4RFFVRkRPMDFCUTNwQ1RDeExRVUZMTEVOQlFVTlNMRWxCUVVrc1EwRkJReXhIUVVGSFN5eFpRVUZaTEVOQlFVTkRMRk5CUVZNc1JVRkJSVThzVVVGQlVTeERRVUZETEVOQlFVTTdTVUZEY0VRN1JVRkRTanRGUVVWQk8wVkJRMEVzU1VGQlNYQkVMRXRCUVVzc1EwRkJRME1zVDBGQlR5eERRVUZETmtNc1QwRkJUeXhEUVVGRFR5eE5RVUZOTEVOQlFVTXNSVUZCUlR0SlFVTXZRaXhMUVVGTExFMUJRVTFETEV0QlFVc3NTVUZCU1ZJc1QwRkJUeXhEUVVGRFR5eE5RVUZOTEVWQlF6bENUaXhMUVVGTExFTkJRVU5TTEVsQlFVa3NRMEZCUXl4SFFVRkhTeXhaUVVGWkxFTkJRVU5ETEZOQlFWTXNSVUZCUlZNc1MwRkJTeXhEUVVGRExFTkJRVU03UlVGRGNrUTdSVUZGUVR0RlFVTkJMRWxCUVVsU0xFOUJRVThzUTBGQlExTXNWMEZCVnl4WlFVRlpUaXhIUVVGSExFVkJRVVU3U1VGRGNFTkdMRXRCUVVzc1EwRkJRMUlzU1VGQlNTeERRVUZETEVkQlFVZFBMRTlCUVU4c1EwRkJRMU1zVjBGQlZ5eERRVUZETzBWQlEzUkRPMFZCUlVFc1NVRkJTU3hQUVVGUFZDeFBRVUZQTEVOQlFVTnFSaXhMUVVGTExFdEJRVXNzVVVGQlVTeEZRVUZGTzBsQlEyNURPMGxCUTBGclJpeExRVUZMTEVOQlFVTlNMRWxCUVVrc1EwRkJRMDhzVDBGQlR5eERRVUZEYWtZc1MwRkJTeXhEUVVGRE8wVkJRemRDTEVOQlFVTXNUVUZCVFN4SlFVRkpMRTlCUVU5cFJpeFBRVUZQTEVOQlFVTjBSU3hKUVVGSkxFdEJRVXNzVVVGQlVTeEZRVUZGTzBsQlEzcERPMGxCUTBFc1RVRkJUV2RHTEZGQlFWRXNSMEZCUjFnc1UwRkJVeXhEUVVGRFF5eFBRVUZQTEVOQlFVTjBSU3hKUVVGSkxFTkJRVU03U1VGRGVFTmFMR1ZCUVdVc1EwRkJRelJHTEZGQlFWRXNRMEZCUXp0SlFVTjZRbFFzUzBGQlN5eERRVUZEVWl4SlFVRkpMRU5CUVVNc1IwRkJSMHNzV1VGQldTeERRVUZEUXl4VFFVRlRMRVZCUVVWWExGRkJRVkVzUTBGQlF5eERRVUZETzBWQlEzQkVPMFZCUlVFc1QwRkJUMVFzUzBGQlN6dEJRVU5vUWlJc0ltbG5ibTl5WlV4cGMzUWlPbHRkZlE9PSIsIid1c2Ugc3RyaWN0JztcblxudmFyIG9iamVjdEFzc2lnbiA9IHJlcXVpcmUoJ29iamVjdC5hc3NpZ24vcG9seWZpbGwnKSgpO1xuXG4vLyBjb21wYXJlIGFuZCBpc0J1ZmZlciB0YWtlbiBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9mZXJvc3MvYnVmZmVyL2Jsb2IvNjgwZTllNWU0ODhmMjJhYWMyNzU5OWE1N2RjODQ0YTYzMTU5MjhkZC9pbmRleC5qc1xuLy8gb3JpZ2luYWwgbm90aWNlOlxuXG4vKiFcbiAqIFRoZSBidWZmZXIgbW9kdWxlIGZyb20gbm9kZS5qcywgZm9yIHRoZSBicm93c2VyLlxuICpcbiAqIEBhdXRob3IgICBGZXJvc3MgQWJvdWtoYWRpamVoIDxmZXJvc3NAZmVyb3NzLm9yZz4gPGh0dHA6Ly9mZXJvc3Mub3JnPlxuICogQGxpY2Vuc2UgIE1JVFxuICovXG5mdW5jdGlvbiBjb21wYXJlKGEsIGIpIHtcbiAgaWYgKGEgPT09IGIpIHtcbiAgICByZXR1cm4gMDtcbiAgfVxuXG4gIHZhciB4ID0gYS5sZW5ndGg7XG4gIHZhciB5ID0gYi5sZW5ndGg7XG5cbiAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IE1hdGgubWluKHgsIHkpOyBpIDwgbGVuOyArK2kpIHtcbiAgICBpZiAoYVtpXSAhPT0gYltpXSkge1xuICAgICAgeCA9IGFbaV07XG4gICAgICB5ID0gYltpXTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIGlmICh4IDwgeSkge1xuICAgIHJldHVybiAtMTtcbiAgfVxuICBpZiAoeSA8IHgpIHtcbiAgICByZXR1cm4gMTtcbiAgfVxuICByZXR1cm4gMDtcbn1cbmZ1bmN0aW9uIGlzQnVmZmVyKGIpIHtcbiAgaWYgKGdsb2JhbC5CdWZmZXIgJiYgdHlwZW9mIGdsb2JhbC5CdWZmZXIuaXNCdWZmZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gZ2xvYmFsLkJ1ZmZlci5pc0J1ZmZlcihiKTtcbiAgfVxuICByZXR1cm4gISEoYiAhPSBudWxsICYmIGIuX2lzQnVmZmVyKTtcbn1cblxuLy8gYmFzZWQgb24gbm9kZSBhc3NlcnQsIG9yaWdpbmFsIG5vdGljZTpcbi8vIE5COiBUaGUgVVJMIHRvIHRoZSBDb21tb25KUyBzcGVjIGlzIGtlcHQganVzdCBmb3IgdHJhZGl0aW9uLlxuLy8gICAgIG5vZGUtYXNzZXJ0IGhhcyBldm9sdmVkIGEgbG90IHNpbmNlIHRoZW4sIGJvdGggaW4gQVBJIGFuZCBiZWhhdmlvci5cblxuLy8gaHR0cDovL3dpa2kuY29tbW9uanMub3JnL3dpa2kvVW5pdF9UZXN0aW5nLzEuMFxuLy9cbi8vIFRISVMgSVMgTk9UIFRFU1RFRCBOT1IgTElLRUxZIFRPIFdPUksgT1VUU0lERSBWOCFcbi8vXG4vLyBPcmlnaW5hbGx5IGZyb20gbmFyd2hhbC5qcyAoaHR0cDovL25hcndoYWxqcy5vcmcpXG4vLyBDb3B5cmlnaHQgKGMpIDIwMDkgVGhvbWFzIFJvYmluc29uIDwyODBub3J0aC5jb20+XG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxuLy8gb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgJ1NvZnR3YXJlJyksIHRvXG4vLyBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZVxuLy8gcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yXG4vLyBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xuLy8gZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpblxuLy8gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICdBUyBJUycsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1Jcbi8vIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuLy8gRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG4vLyBBVVRIT1JTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTlxuLy8gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTlxuLy8gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbnZhciB1dGlsID0gcmVxdWlyZSgndXRpbC8nKTtcbnZhciBoYXNPd24gPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xudmFyIHBTbGljZSA9IEFycmF5LnByb3RvdHlwZS5zbGljZTtcbnZhciBmdW5jdGlvbnNIYXZlTmFtZXMgPSAoZnVuY3Rpb24gKCkge1xuICByZXR1cm4gZnVuY3Rpb24gZm9vKCkge30ubmFtZSA9PT0gJ2Zvbyc7XG59KCkpO1xuZnVuY3Rpb24gcFRvU3RyaW5nIChvYmopIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvYmopO1xufVxuZnVuY3Rpb24gaXNWaWV3KGFycmJ1Zikge1xuICBpZiAoaXNCdWZmZXIoYXJyYnVmKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAodHlwZW9mIGdsb2JhbC5BcnJheUJ1ZmZlciAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAodHlwZW9mIEFycmF5QnVmZmVyLmlzVmlldyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBBcnJheUJ1ZmZlci5pc1ZpZXcoYXJyYnVmKTtcbiAgfVxuICBpZiAoIWFycmJ1Zikge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAoYXJyYnVmIGluc3RhbmNlb2YgRGF0YVZpZXcpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICBpZiAoYXJyYnVmLmJ1ZmZlciAmJiBhcnJidWYuYnVmZmVyIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG4vLyAxLiBUaGUgYXNzZXJ0IG1vZHVsZSBwcm92aWRlcyBmdW5jdGlvbnMgdGhhdCB0aHJvd1xuLy8gQXNzZXJ0aW9uRXJyb3IncyB3aGVuIHBhcnRpY3VsYXIgY29uZGl0aW9ucyBhcmUgbm90IG1ldC4gVGhlXG4vLyBhc3NlcnQgbW9kdWxlIG11c3QgY29uZm9ybSB0byB0aGUgZm9sbG93aW5nIGludGVyZmFjZS5cblxudmFyIGFzc2VydCA9IG1vZHVsZS5leHBvcnRzID0gb2s7XG5cbi8vIDIuIFRoZSBBc3NlcnRpb25FcnJvciBpcyBkZWZpbmVkIGluIGFzc2VydC5cbi8vIG5ldyBhc3NlcnQuQXNzZXJ0aW9uRXJyb3IoeyBtZXNzYWdlOiBtZXNzYWdlLFxuLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjdHVhbDogYWN0dWFsLFxuLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkOiBleHBlY3RlZCB9KVxuXG52YXIgcmVnZXggPSAvXFxzKmZ1bmN0aW9uXFxzKyhbXlxcKFxcc10qKVxccyovO1xuLy8gYmFzZWQgb24gaHR0cHM6Ly9naXRodWIuY29tL2xqaGFyYi9mdW5jdGlvbi5wcm90b3R5cGUubmFtZS9ibG9iL2FkZWVlZWM4YmZjYzYwNjhiMTg3ZDdkOWZiM2Q1YmIxZDNhMzA4OTkvaW1wbGVtZW50YXRpb24uanNcbmZ1bmN0aW9uIGdldE5hbWUoZnVuYykge1xuICBpZiAoIXV0aWwuaXNGdW5jdGlvbihmdW5jKSkge1xuICAgIHJldHVybjtcbiAgfVxuICBpZiAoZnVuY3Rpb25zSGF2ZU5hbWVzKSB7XG4gICAgcmV0dXJuIGZ1bmMubmFtZTtcbiAgfVxuICB2YXIgc3RyID0gZnVuYy50b1N0cmluZygpO1xuICB2YXIgbWF0Y2ggPSBzdHIubWF0Y2gocmVnZXgpO1xuICByZXR1cm4gbWF0Y2ggJiYgbWF0Y2hbMV07XG59XG5hc3NlcnQuQXNzZXJ0aW9uRXJyb3IgPSBmdW5jdGlvbiBBc3NlcnRpb25FcnJvcihvcHRpb25zKSB7XG4gIHRoaXMubmFtZSA9ICdBc3NlcnRpb25FcnJvcic7XG4gIHRoaXMuYWN0dWFsID0gb3B0aW9ucy5hY3R1YWw7XG4gIHRoaXMuZXhwZWN0ZWQgPSBvcHRpb25zLmV4cGVjdGVkO1xuICB0aGlzLm9wZXJhdG9yID0gb3B0aW9ucy5vcGVyYXRvcjtcbiAgaWYgKG9wdGlvbnMubWVzc2FnZSkge1xuICAgIHRoaXMubWVzc2FnZSA9IG9wdGlvbnMubWVzc2FnZTtcbiAgICB0aGlzLmdlbmVyYXRlZE1lc3NhZ2UgPSBmYWxzZTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLm1lc3NhZ2UgPSBnZXRNZXNzYWdlKHRoaXMpO1xuICAgIHRoaXMuZ2VuZXJhdGVkTWVzc2FnZSA9IHRydWU7XG4gIH1cbiAgdmFyIHN0YWNrU3RhcnRGdW5jdGlvbiA9IG9wdGlvbnMuc3RhY2tTdGFydEZ1bmN0aW9uIHx8IGZhaWw7XG4gIGlmIChFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSkge1xuICAgIEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKHRoaXMsIHN0YWNrU3RhcnRGdW5jdGlvbik7XG4gIH0gZWxzZSB7XG4gICAgLy8gbm9uIHY4IGJyb3dzZXJzIHNvIHdlIGNhbiBoYXZlIGEgc3RhY2t0cmFjZVxuICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoKTtcbiAgICBpZiAoZXJyLnN0YWNrKSB7XG4gICAgICB2YXIgb3V0ID0gZXJyLnN0YWNrO1xuXG4gICAgICAvLyB0cnkgdG8gc3RyaXAgdXNlbGVzcyBmcmFtZXNcbiAgICAgIHZhciBmbl9uYW1lID0gZ2V0TmFtZShzdGFja1N0YXJ0RnVuY3Rpb24pO1xuICAgICAgdmFyIGlkeCA9IG91dC5pbmRleE9mKCdcXG4nICsgZm5fbmFtZSk7XG4gICAgICBpZiAoaWR4ID49IDApIHtcbiAgICAgICAgLy8gb25jZSB3ZSBoYXZlIGxvY2F0ZWQgdGhlIGZ1bmN0aW9uIGZyYW1lXG4gICAgICAgIC8vIHdlIG5lZWQgdG8gc3RyaXAgb3V0IGV2ZXJ5dGhpbmcgYmVmb3JlIGl0IChhbmQgaXRzIGxpbmUpXG4gICAgICAgIHZhciBuZXh0X2xpbmUgPSBvdXQuaW5kZXhPZignXFxuJywgaWR4ICsgMSk7XG4gICAgICAgIG91dCA9IG91dC5zdWJzdHJpbmcobmV4dF9saW5lICsgMSk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuc3RhY2sgPSBvdXQ7XG4gICAgfVxuICB9XG59O1xuXG4vLyBhc3NlcnQuQXNzZXJ0aW9uRXJyb3IgaW5zdGFuY2VvZiBFcnJvclxudXRpbC5pbmhlcml0cyhhc3NlcnQuQXNzZXJ0aW9uRXJyb3IsIEVycm9yKTtcblxuZnVuY3Rpb24gdHJ1bmNhdGUocywgbikge1xuICBpZiAodHlwZW9mIHMgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIHMubGVuZ3RoIDwgbiA/IHMgOiBzLnNsaWNlKDAsIG4pO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBzO1xuICB9XG59XG5mdW5jdGlvbiBpbnNwZWN0KHNvbWV0aGluZykge1xuICBpZiAoZnVuY3Rpb25zSGF2ZU5hbWVzIHx8ICF1dGlsLmlzRnVuY3Rpb24oc29tZXRoaW5nKSkge1xuICAgIHJldHVybiB1dGlsLmluc3BlY3Qoc29tZXRoaW5nKTtcbiAgfVxuICB2YXIgcmF3bmFtZSA9IGdldE5hbWUoc29tZXRoaW5nKTtcbiAgdmFyIG5hbWUgPSByYXduYW1lID8gJzogJyArIHJhd25hbWUgOiAnJztcbiAgcmV0dXJuICdbRnVuY3Rpb24nICsgIG5hbWUgKyAnXSc7XG59XG5mdW5jdGlvbiBnZXRNZXNzYWdlKHNlbGYpIHtcbiAgcmV0dXJuIHRydW5jYXRlKGluc3BlY3Qoc2VsZi5hY3R1YWwpLCAxMjgpICsgJyAnICtcbiAgICAgICAgIHNlbGYub3BlcmF0b3IgKyAnICcgK1xuICAgICAgICAgdHJ1bmNhdGUoaW5zcGVjdChzZWxmLmV4cGVjdGVkKSwgMTI4KTtcbn1cblxuLy8gQXQgcHJlc2VudCBvbmx5IHRoZSB0aHJlZSBrZXlzIG1lbnRpb25lZCBhYm92ZSBhcmUgdXNlZCBhbmRcbi8vIHVuZGVyc3Rvb2QgYnkgdGhlIHNwZWMuIEltcGxlbWVudGF0aW9ucyBvciBzdWIgbW9kdWxlcyBjYW4gcGFzc1xuLy8gb3RoZXIga2V5cyB0byB0aGUgQXNzZXJ0aW9uRXJyb3IncyBjb25zdHJ1Y3RvciAtIHRoZXkgd2lsbCBiZVxuLy8gaWdub3JlZC5cblxuLy8gMy4gQWxsIG9mIHRoZSBmb2xsb3dpbmcgZnVuY3Rpb25zIG11c3QgdGhyb3cgYW4gQXNzZXJ0aW9uRXJyb3Jcbi8vIHdoZW4gYSBjb3JyZXNwb25kaW5nIGNvbmRpdGlvbiBpcyBub3QgbWV0LCB3aXRoIGEgbWVzc2FnZSB0aGF0XG4vLyBtYXkgYmUgdW5kZWZpbmVkIGlmIG5vdCBwcm92aWRlZC4gIEFsbCBhc3NlcnRpb24gbWV0aG9kcyBwcm92aWRlXG4vLyBib3RoIHRoZSBhY3R1YWwgYW5kIGV4cGVjdGVkIHZhbHVlcyB0byB0aGUgYXNzZXJ0aW9uIGVycm9yIGZvclxuLy8gZGlzcGxheSBwdXJwb3Nlcy5cblxuZnVuY3Rpb24gZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCBvcGVyYXRvciwgc3RhY2tTdGFydEZ1bmN0aW9uKSB7XG4gIHRocm93IG5ldyBhc3NlcnQuQXNzZXJ0aW9uRXJyb3Ioe1xuICAgIG1lc3NhZ2U6IG1lc3NhZ2UsXG4gICAgYWN0dWFsOiBhY3R1YWwsXG4gICAgZXhwZWN0ZWQ6IGV4cGVjdGVkLFxuICAgIG9wZXJhdG9yOiBvcGVyYXRvcixcbiAgICBzdGFja1N0YXJ0RnVuY3Rpb246IHN0YWNrU3RhcnRGdW5jdGlvblxuICB9KTtcbn1cblxuLy8gRVhURU5TSU9OISBhbGxvd3MgZm9yIHdlbGwgYmVoYXZlZCBlcnJvcnMgZGVmaW5lZCBlbHNld2hlcmUuXG5hc3NlcnQuZmFpbCA9IGZhaWw7XG5cbi8vIDQuIFB1cmUgYXNzZXJ0aW9uIHRlc3RzIHdoZXRoZXIgYSB2YWx1ZSBpcyB0cnV0aHksIGFzIGRldGVybWluZWRcbi8vIGJ5ICEhZ3VhcmQuXG4vLyBhc3NlcnQub2soZ3VhcmQsIG1lc3NhZ2Vfb3B0KTtcbi8vIFRoaXMgc3RhdGVtZW50IGlzIGVxdWl2YWxlbnQgdG8gYXNzZXJ0LmVxdWFsKHRydWUsICEhZ3VhcmQsXG4vLyBtZXNzYWdlX29wdCk7LiBUbyB0ZXN0IHN0cmljdGx5IGZvciB0aGUgdmFsdWUgdHJ1ZSwgdXNlXG4vLyBhc3NlcnQuc3RyaWN0RXF1YWwodHJ1ZSwgZ3VhcmQsIG1lc3NhZ2Vfb3B0KTsuXG5cbmZ1bmN0aW9uIG9rKHZhbHVlLCBtZXNzYWdlKSB7XG4gIGlmICghdmFsdWUpIGZhaWwodmFsdWUsIHRydWUsIG1lc3NhZ2UsICc9PScsIGFzc2VydC5vayk7XG59XG5hc3NlcnQub2sgPSBvaztcblxuLy8gNS4gVGhlIGVxdWFsaXR5IGFzc2VydGlvbiB0ZXN0cyBzaGFsbG93LCBjb2VyY2l2ZSBlcXVhbGl0eSB3aXRoXG4vLyA9PS5cbi8vIGFzc2VydC5lcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlX29wdCk7XG5cbmFzc2VydC5lcXVhbCA9IGZ1bmN0aW9uIGVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UpIHtcbiAgaWYgKGFjdHVhbCAhPSBleHBlY3RlZCkgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCAnPT0nLCBhc3NlcnQuZXF1YWwpO1xufTtcblxuLy8gNi4gVGhlIG5vbi1lcXVhbGl0eSBhc3NlcnRpb24gdGVzdHMgZm9yIHdoZXRoZXIgdHdvIG9iamVjdHMgYXJlIG5vdCBlcXVhbFxuLy8gd2l0aCAhPSBhc3NlcnQubm90RXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZV9vcHQpO1xuXG5hc3NlcnQubm90RXF1YWwgPSBmdW5jdGlvbiBub3RFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlKSB7XG4gIGlmIChhY3R1YWwgPT0gZXhwZWN0ZWQpIHtcbiAgICBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UsICchPScsIGFzc2VydC5ub3RFcXVhbCk7XG4gIH1cbn07XG5cbi8vIDcuIFRoZSBlcXVpdmFsZW5jZSBhc3NlcnRpb24gdGVzdHMgYSBkZWVwIGVxdWFsaXR5IHJlbGF0aW9uLlxuLy8gYXNzZXJ0LmRlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlX29wdCk7XG5cbmFzc2VydC5kZWVwRXF1YWwgPSBmdW5jdGlvbiBkZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuICBpZiAoIV9kZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgZmFsc2UpKSB7XG4gICAgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCAnZGVlcEVxdWFsJywgYXNzZXJ0LmRlZXBFcXVhbCk7XG4gIH1cbn07XG5cbmFzc2VydC5kZWVwU3RyaWN0RXF1YWwgPSBmdW5jdGlvbiBkZWVwU3RyaWN0RXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuICBpZiAoIV9kZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgdHJ1ZSkpIHtcbiAgICBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UsICdkZWVwU3RyaWN0RXF1YWwnLCBhc3NlcnQuZGVlcFN0cmljdEVxdWFsKTtcbiAgfVxufTtcblxuZnVuY3Rpb24gX2RlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBzdHJpY3QsIG1lbW9zKSB7XG4gIC8vIDcuMS4gQWxsIGlkZW50aWNhbCB2YWx1ZXMgYXJlIGVxdWl2YWxlbnQsIGFzIGRldGVybWluZWQgYnkgPT09LlxuICBpZiAoYWN0dWFsID09PSBleHBlY3RlZCkge1xuICAgIHJldHVybiB0cnVlO1xuICB9IGVsc2UgaWYgKGlzQnVmZmVyKGFjdHVhbCkgJiYgaXNCdWZmZXIoZXhwZWN0ZWQpKSB7XG4gICAgcmV0dXJuIGNvbXBhcmUoYWN0dWFsLCBleHBlY3RlZCkgPT09IDA7XG5cbiAgLy8gNy4yLiBJZiB0aGUgZXhwZWN0ZWQgdmFsdWUgaXMgYSBEYXRlIG9iamVjdCwgdGhlIGFjdHVhbCB2YWx1ZSBpc1xuICAvLyBlcXVpdmFsZW50IGlmIGl0IGlzIGFsc28gYSBEYXRlIG9iamVjdCB0aGF0IHJlZmVycyB0byB0aGUgc2FtZSB0aW1lLlxuICB9IGVsc2UgaWYgKHV0aWwuaXNEYXRlKGFjdHVhbCkgJiYgdXRpbC5pc0RhdGUoZXhwZWN0ZWQpKSB7XG4gICAgcmV0dXJuIGFjdHVhbC5nZXRUaW1lKCkgPT09IGV4cGVjdGVkLmdldFRpbWUoKTtcblxuICAvLyA3LjMgSWYgdGhlIGV4cGVjdGVkIHZhbHVlIGlzIGEgUmVnRXhwIG9iamVjdCwgdGhlIGFjdHVhbCB2YWx1ZSBpc1xuICAvLyBlcXVpdmFsZW50IGlmIGl0IGlzIGFsc28gYSBSZWdFeHAgb2JqZWN0IHdpdGggdGhlIHNhbWUgc291cmNlIGFuZFxuICAvLyBwcm9wZXJ0aWVzIChgZ2xvYmFsYCwgYG11bHRpbGluZWAsIGBsYXN0SW5kZXhgLCBgaWdub3JlQ2FzZWApLlxuICB9IGVsc2UgaWYgKHV0aWwuaXNSZWdFeHAoYWN0dWFsKSAmJiB1dGlsLmlzUmVnRXhwKGV4cGVjdGVkKSkge1xuICAgIHJldHVybiBhY3R1YWwuc291cmNlID09PSBleHBlY3RlZC5zb3VyY2UgJiZcbiAgICAgICAgICAgYWN0dWFsLmdsb2JhbCA9PT0gZXhwZWN0ZWQuZ2xvYmFsICYmXG4gICAgICAgICAgIGFjdHVhbC5tdWx0aWxpbmUgPT09IGV4cGVjdGVkLm11bHRpbGluZSAmJlxuICAgICAgICAgICBhY3R1YWwubGFzdEluZGV4ID09PSBleHBlY3RlZC5sYXN0SW5kZXggJiZcbiAgICAgICAgICAgYWN0dWFsLmlnbm9yZUNhc2UgPT09IGV4cGVjdGVkLmlnbm9yZUNhc2U7XG5cbiAgLy8gNy40LiBPdGhlciBwYWlycyB0aGF0IGRvIG5vdCBib3RoIHBhc3MgdHlwZW9mIHZhbHVlID09ICdvYmplY3QnLFxuICAvLyBlcXVpdmFsZW5jZSBpcyBkZXRlcm1pbmVkIGJ5ID09LlxuICB9IGVsc2UgaWYgKChhY3R1YWwgPT09IG51bGwgfHwgdHlwZW9mIGFjdHVhbCAhPT0gJ29iamVjdCcpICYmXG4gICAgICAgICAgICAgKGV4cGVjdGVkID09PSBudWxsIHx8IHR5cGVvZiBleHBlY3RlZCAhPT0gJ29iamVjdCcpKSB7XG4gICAgcmV0dXJuIHN0cmljdCA/IGFjdHVhbCA9PT0gZXhwZWN0ZWQgOiBhY3R1YWwgPT0gZXhwZWN0ZWQ7XG5cbiAgLy8gSWYgYm90aCB2YWx1ZXMgYXJlIGluc3RhbmNlcyBvZiB0eXBlZCBhcnJheXMsIHdyYXAgdGhlaXIgdW5kZXJseWluZ1xuICAvLyBBcnJheUJ1ZmZlcnMgaW4gYSBCdWZmZXIgZWFjaCB0byBpbmNyZWFzZSBwZXJmb3JtYW5jZVxuICAvLyBUaGlzIG9wdGltaXphdGlvbiByZXF1aXJlcyB0aGUgYXJyYXlzIHRvIGhhdmUgdGhlIHNhbWUgdHlwZSBhcyBjaGVja2VkIGJ5XG4gIC8vIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcgKGFrYSBwVG9TdHJpbmcpLiBOZXZlciBwZXJmb3JtIGJpbmFyeVxuICAvLyBjb21wYXJpc29ucyBmb3IgRmxvYXQqQXJyYXlzLCB0aG91Z2gsIHNpbmNlIGUuZy4gKzAgPT09IC0wIGJ1dCB0aGVpclxuICAvLyBiaXQgcGF0dGVybnMgYXJlIG5vdCBpZGVudGljYWwuXG4gIH0gZWxzZSBpZiAoaXNWaWV3KGFjdHVhbCkgJiYgaXNWaWV3KGV4cGVjdGVkKSAmJlxuICAgICAgICAgICAgIHBUb1N0cmluZyhhY3R1YWwpID09PSBwVG9TdHJpbmcoZXhwZWN0ZWQpICYmXG4gICAgICAgICAgICAgIShhY3R1YWwgaW5zdGFuY2VvZiBGbG9hdDMyQXJyYXkgfHxcbiAgICAgICAgICAgICAgIGFjdHVhbCBpbnN0YW5jZW9mIEZsb2F0NjRBcnJheSkpIHtcbiAgICByZXR1cm4gY29tcGFyZShuZXcgVWludDhBcnJheShhY3R1YWwuYnVmZmVyKSxcbiAgICAgICAgICAgICAgICAgICBuZXcgVWludDhBcnJheShleHBlY3RlZC5idWZmZXIpKSA9PT0gMDtcblxuICAvLyA3LjUgRm9yIGFsbCBvdGhlciBPYmplY3QgcGFpcnMsIGluY2x1ZGluZyBBcnJheSBvYmplY3RzLCBlcXVpdmFsZW5jZSBpc1xuICAvLyBkZXRlcm1pbmVkIGJ5IGhhdmluZyB0aGUgc2FtZSBudW1iZXIgb2Ygb3duZWQgcHJvcGVydGllcyAoYXMgdmVyaWZpZWRcbiAgLy8gd2l0aCBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwpLCB0aGUgc2FtZSBzZXQgb2Yga2V5c1xuICAvLyAoYWx0aG91Z2ggbm90IG5lY2Vzc2FyaWx5IHRoZSBzYW1lIG9yZGVyKSwgZXF1aXZhbGVudCB2YWx1ZXMgZm9yIGV2ZXJ5XG4gIC8vIGNvcnJlc3BvbmRpbmcga2V5LCBhbmQgYW4gaWRlbnRpY2FsICdwcm90b3R5cGUnIHByb3BlcnR5LiBOb3RlOiB0aGlzXG4gIC8vIGFjY291bnRzIGZvciBib3RoIG5hbWVkIGFuZCBpbmRleGVkIHByb3BlcnRpZXMgb24gQXJyYXlzLlxuICB9IGVsc2UgaWYgKGlzQnVmZmVyKGFjdHVhbCkgIT09IGlzQnVmZmVyKGV4cGVjdGVkKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfSBlbHNlIHtcbiAgICBtZW1vcyA9IG1lbW9zIHx8IHthY3R1YWw6IFtdLCBleHBlY3RlZDogW119O1xuXG4gICAgdmFyIGFjdHVhbEluZGV4ID0gbWVtb3MuYWN0dWFsLmluZGV4T2YoYWN0dWFsKTtcbiAgICBpZiAoYWN0dWFsSW5kZXggIT09IC0xKSB7XG4gICAgICBpZiAoYWN0dWFsSW5kZXggPT09IG1lbW9zLmV4cGVjdGVkLmluZGV4T2YoZXhwZWN0ZWQpKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIG1lbW9zLmFjdHVhbC5wdXNoKGFjdHVhbCk7XG4gICAgbWVtb3MuZXhwZWN0ZWQucHVzaChleHBlY3RlZCk7XG5cbiAgICByZXR1cm4gb2JqRXF1aXYoYWN0dWFsLCBleHBlY3RlZCwgc3RyaWN0LCBtZW1vcyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gaXNBcmd1bWVudHMob2JqZWN0KSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwob2JqZWN0KSA9PSAnW29iamVjdCBBcmd1bWVudHNdJztcbn1cblxuZnVuY3Rpb24gb2JqRXF1aXYoYSwgYiwgc3RyaWN0LCBhY3R1YWxWaXNpdGVkT2JqZWN0cykge1xuICBpZiAoYSA9PT0gbnVsbCB8fCBhID09PSB1bmRlZmluZWQgfHwgYiA9PT0gbnVsbCB8fCBiID09PSB1bmRlZmluZWQpXG4gICAgcmV0dXJuIGZhbHNlO1xuICAvLyBpZiBvbmUgaXMgYSBwcmltaXRpdmUsIHRoZSBvdGhlciBtdXN0IGJlIHNhbWVcbiAgaWYgKHV0aWwuaXNQcmltaXRpdmUoYSkgfHwgdXRpbC5pc1ByaW1pdGl2ZShiKSlcbiAgICByZXR1cm4gYSA9PT0gYjtcbiAgaWYgKHN0cmljdCAmJiBPYmplY3QuZ2V0UHJvdG90eXBlT2YoYSkgIT09IE9iamVjdC5nZXRQcm90b3R5cGVPZihiKSlcbiAgICByZXR1cm4gZmFsc2U7XG4gIHZhciBhSXNBcmdzID0gaXNBcmd1bWVudHMoYSk7XG4gIHZhciBiSXNBcmdzID0gaXNBcmd1bWVudHMoYik7XG4gIGlmICgoYUlzQXJncyAmJiAhYklzQXJncykgfHwgKCFhSXNBcmdzICYmIGJJc0FyZ3MpKVxuICAgIHJldHVybiBmYWxzZTtcbiAgaWYgKGFJc0FyZ3MpIHtcbiAgICBhID0gcFNsaWNlLmNhbGwoYSk7XG4gICAgYiA9IHBTbGljZS5jYWxsKGIpO1xuICAgIHJldHVybiBfZGVlcEVxdWFsKGEsIGIsIHN0cmljdCk7XG4gIH1cbiAgdmFyIGthID0gb2JqZWN0S2V5cyhhKTtcbiAgdmFyIGtiID0gb2JqZWN0S2V5cyhiKTtcbiAgdmFyIGtleSwgaTtcbiAgLy8gaGF2aW5nIHRoZSBzYW1lIG51bWJlciBvZiBvd25lZCBwcm9wZXJ0aWVzIChrZXlzIGluY29ycG9yYXRlc1xuICAvLyBoYXNPd25Qcm9wZXJ0eSlcbiAgaWYgKGthLmxlbmd0aCAhPT0ga2IubGVuZ3RoKVxuICAgIHJldHVybiBmYWxzZTtcbiAgLy90aGUgc2FtZSBzZXQgb2Yga2V5cyAoYWx0aG91Z2ggbm90IG5lY2Vzc2FyaWx5IHRoZSBzYW1lIG9yZGVyKSxcbiAga2Euc29ydCgpO1xuICBrYi5zb3J0KCk7XG4gIC8vfn5+Y2hlYXAga2V5IHRlc3RcbiAgZm9yIChpID0ga2EubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICBpZiAoa2FbaV0gIT09IGtiW2ldKVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIC8vZXF1aXZhbGVudCB2YWx1ZXMgZm9yIGV2ZXJ5IGNvcnJlc3BvbmRpbmcga2V5LCBhbmRcbiAgLy9+fn5wb3NzaWJseSBleHBlbnNpdmUgZGVlcCB0ZXN0XG4gIGZvciAoaSA9IGthLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAga2V5ID0ga2FbaV07XG4gICAgaWYgKCFfZGVlcEVxdWFsKGFba2V5XSwgYltrZXldLCBzdHJpY3QsIGFjdHVhbFZpc2l0ZWRPYmplY3RzKSlcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxuLy8gOC4gVGhlIG5vbi1lcXVpdmFsZW5jZSBhc3NlcnRpb24gdGVzdHMgZm9yIGFueSBkZWVwIGluZXF1YWxpdHkuXG4vLyBhc3NlcnQubm90RGVlcEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2Vfb3B0KTtcblxuYXNzZXJ0Lm5vdERlZXBFcXVhbCA9IGZ1bmN0aW9uIG5vdERlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlKSB7XG4gIGlmIChfZGVlcEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIGZhbHNlKSkge1xuICAgIGZhaWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSwgJ25vdERlZXBFcXVhbCcsIGFzc2VydC5ub3REZWVwRXF1YWwpO1xuICB9XG59O1xuXG5hc3NlcnQubm90RGVlcFN0cmljdEVxdWFsID0gbm90RGVlcFN0cmljdEVxdWFsO1xuZnVuY3Rpb24gbm90RGVlcFN0cmljdEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UpIHtcbiAgaWYgKF9kZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgdHJ1ZSkpIHtcbiAgICBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UsICdub3REZWVwU3RyaWN0RXF1YWwnLCBub3REZWVwU3RyaWN0RXF1YWwpO1xuICB9XG59XG5cblxuLy8gOS4gVGhlIHN0cmljdCBlcXVhbGl0eSBhc3NlcnRpb24gdGVzdHMgc3RyaWN0IGVxdWFsaXR5LCBhcyBkZXRlcm1pbmVkIGJ5ID09PS5cbi8vIGFzc2VydC5zdHJpY3RFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlX29wdCk7XG5cbmFzc2VydC5zdHJpY3RFcXVhbCA9IGZ1bmN0aW9uIHN0cmljdEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UpIHtcbiAgaWYgKGFjdHVhbCAhPT0gZXhwZWN0ZWQpIHtcbiAgICBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UsICc9PT0nLCBhc3NlcnQuc3RyaWN0RXF1YWwpO1xuICB9XG59O1xuXG4vLyAxMC4gVGhlIHN0cmljdCBub24tZXF1YWxpdHkgYXNzZXJ0aW9uIHRlc3RzIGZvciBzdHJpY3QgaW5lcXVhbGl0eSwgYXNcbi8vIGRldGVybWluZWQgYnkgIT09LiAgYXNzZXJ0Lm5vdFN0cmljdEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2Vfb3B0KTtcblxuYXNzZXJ0Lm5vdFN0cmljdEVxdWFsID0gZnVuY3Rpb24gbm90U3RyaWN0RXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuICBpZiAoYWN0dWFsID09PSBleHBlY3RlZCkge1xuICAgIGZhaWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSwgJyE9PScsIGFzc2VydC5ub3RTdHJpY3RFcXVhbCk7XG4gIH1cbn07XG5cbmZ1bmN0aW9uIGV4cGVjdGVkRXhjZXB0aW9uKGFjdHVhbCwgZXhwZWN0ZWQpIHtcbiAgaWYgKCFhY3R1YWwgfHwgIWV4cGVjdGVkKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaWYgKE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChleHBlY3RlZCkgPT0gJ1tvYmplY3QgUmVnRXhwXScpIHtcbiAgICByZXR1cm4gZXhwZWN0ZWQudGVzdChhY3R1YWwpO1xuICB9XG5cbiAgdHJ5IHtcbiAgICBpZiAoYWN0dWFsIGluc3RhbmNlb2YgZXhwZWN0ZWQpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfSBjYXRjaCAoZSkge1xuICAgIC8vIElnbm9yZS4gIFRoZSBpbnN0YW5jZW9mIGNoZWNrIGRvZXNuJ3Qgd29yayBmb3IgYXJyb3cgZnVuY3Rpb25zLlxuICB9XG5cbiAgaWYgKEVycm9yLmlzUHJvdG90eXBlT2YoZXhwZWN0ZWQpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcmV0dXJuIGV4cGVjdGVkLmNhbGwoe30sIGFjdHVhbCkgPT09IHRydWU7XG59XG5cbmZ1bmN0aW9uIF90cnlCbG9jayhibG9jaykge1xuICB2YXIgZXJyb3I7XG4gIHRyeSB7XG4gICAgYmxvY2soKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIGVycm9yID0gZTtcbiAgfVxuICByZXR1cm4gZXJyb3I7XG59XG5cbmZ1bmN0aW9uIF90aHJvd3Moc2hvdWxkVGhyb3csIGJsb2NrLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuICB2YXIgYWN0dWFsO1xuXG4gIGlmICh0eXBlb2YgYmxvY2sgIT09ICdmdW5jdGlvbicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImJsb2NrXCIgYXJndW1lbnQgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gIH1cblxuICBpZiAodHlwZW9mIGV4cGVjdGVkID09PSAnc3RyaW5nJykge1xuICAgIG1lc3NhZ2UgPSBleHBlY3RlZDtcbiAgICBleHBlY3RlZCA9IG51bGw7XG4gIH1cblxuICBhY3R1YWwgPSBfdHJ5QmxvY2soYmxvY2spO1xuXG4gIG1lc3NhZ2UgPSAoZXhwZWN0ZWQgJiYgZXhwZWN0ZWQubmFtZSA/ICcgKCcgKyBleHBlY3RlZC5uYW1lICsgJykuJyA6ICcuJykgK1xuICAgICAgICAgICAgKG1lc3NhZ2UgPyAnICcgKyBtZXNzYWdlIDogJy4nKTtcblxuICBpZiAoc2hvdWxkVGhyb3cgJiYgIWFjdHVhbCkge1xuICAgIGZhaWwoYWN0dWFsLCBleHBlY3RlZCwgJ01pc3NpbmcgZXhwZWN0ZWQgZXhjZXB0aW9uJyArIG1lc3NhZ2UpO1xuICB9XG5cbiAgdmFyIHVzZXJQcm92aWRlZE1lc3NhZ2UgPSB0eXBlb2YgbWVzc2FnZSA9PT0gJ3N0cmluZyc7XG4gIHZhciBpc1Vud2FudGVkRXhjZXB0aW9uID0gIXNob3VsZFRocm93ICYmIHV0aWwuaXNFcnJvcihhY3R1YWwpO1xuICB2YXIgaXNVbmV4cGVjdGVkRXhjZXB0aW9uID0gIXNob3VsZFRocm93ICYmIGFjdHVhbCAmJiAhZXhwZWN0ZWQ7XG5cbiAgaWYgKChpc1Vud2FudGVkRXhjZXB0aW9uICYmXG4gICAgICB1c2VyUHJvdmlkZWRNZXNzYWdlICYmXG4gICAgICBleHBlY3RlZEV4Y2VwdGlvbihhY3R1YWwsIGV4cGVjdGVkKSkgfHxcbiAgICAgIGlzVW5leHBlY3RlZEV4Y2VwdGlvbikge1xuICAgIGZhaWwoYWN0dWFsLCBleHBlY3RlZCwgJ0dvdCB1bndhbnRlZCBleGNlcHRpb24nICsgbWVzc2FnZSk7XG4gIH1cblxuICBpZiAoKHNob3VsZFRocm93ICYmIGFjdHVhbCAmJiBleHBlY3RlZCAmJlxuICAgICAgIWV4cGVjdGVkRXhjZXB0aW9uKGFjdHVhbCwgZXhwZWN0ZWQpKSB8fCAoIXNob3VsZFRocm93ICYmIGFjdHVhbCkpIHtcbiAgICB0aHJvdyBhY3R1YWw7XG4gIH1cbn1cblxuLy8gMTEuIEV4cGVjdGVkIHRvIHRocm93IGFuIGVycm9yOlxuLy8gYXNzZXJ0LnRocm93cyhibG9jaywgRXJyb3Jfb3B0LCBtZXNzYWdlX29wdCk7XG5cbmFzc2VydC50aHJvd3MgPSBmdW5jdGlvbihibG9jaywgLypvcHRpb25hbCovZXJyb3IsIC8qb3B0aW9uYWwqL21lc3NhZ2UpIHtcbiAgX3Rocm93cyh0cnVlLCBibG9jaywgZXJyb3IsIG1lc3NhZ2UpO1xufTtcblxuLy8gRVhURU5TSU9OISBUaGlzIGlzIGFubm95aW5nIHRvIHdyaXRlIG91dHNpZGUgdGhpcyBtb2R1bGUuXG5hc3NlcnQuZG9lc05vdFRocm93ID0gZnVuY3Rpb24oYmxvY2ssIC8qb3B0aW9uYWwqL2Vycm9yLCAvKm9wdGlvbmFsKi9tZXNzYWdlKSB7XG4gIF90aHJvd3MoZmFsc2UsIGJsb2NrLCBlcnJvciwgbWVzc2FnZSk7XG59O1xuXG5hc3NlcnQuaWZFcnJvciA9IGZ1bmN0aW9uKGVycikgeyBpZiAoZXJyKSB0aHJvdyBlcnI7IH07XG5cbi8vIEV4cG9zZSBhIHN0cmljdCBvbmx5IHZhcmlhbnQgb2YgYXNzZXJ0XG5mdW5jdGlvbiBzdHJpY3QodmFsdWUsIG1lc3NhZ2UpIHtcbiAgaWYgKCF2YWx1ZSkgZmFpbCh2YWx1ZSwgdHJ1ZSwgbWVzc2FnZSwgJz09Jywgc3RyaWN0KTtcbn1cbmFzc2VydC5zdHJpY3QgPSBvYmplY3RBc3NpZ24oc3RyaWN0LCBhc3NlcnQsIHtcbiAgZXF1YWw6IGFzc2VydC5zdHJpY3RFcXVhbCxcbiAgZGVlcEVxdWFsOiBhc3NlcnQuZGVlcFN0cmljdEVxdWFsLFxuICBub3RFcXVhbDogYXNzZXJ0Lm5vdFN0cmljdEVxdWFsLFxuICBub3REZWVwRXF1YWw6IGFzc2VydC5ub3REZWVwU3RyaWN0RXF1YWxcbn0pO1xuYXNzZXJ0LnN0cmljdC5zdHJpY3QgPSBhc3NlcnQuc3RyaWN0O1xuXG52YXIgb2JqZWN0S2V5cyA9IE9iamVjdC5rZXlzIHx8IGZ1bmN0aW9uIChvYmopIHtcbiAgdmFyIGtleXMgPSBbXTtcbiAgZm9yICh2YXIga2V5IGluIG9iaikge1xuICAgIGlmIChoYXNPd24uY2FsbChvYmosIGtleSkpIGtleXMucHVzaChrZXkpO1xuICB9XG4gIHJldHVybiBrZXlzO1xufTtcbiIsImlmICh0eXBlb2YgT2JqZWN0LmNyZWF0ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAvLyBpbXBsZW1lbnRhdGlvbiBmcm9tIHN0YW5kYXJkIG5vZGUuanMgJ3V0aWwnIG1vZHVsZVxuICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGluaGVyaXRzKGN0b3IsIHN1cGVyQ3Rvcikge1xuICAgIGN0b3Iuc3VwZXJfID0gc3VwZXJDdG9yXG4gICAgY3Rvci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ3Rvci5wcm90b3R5cGUsIHtcbiAgICAgIGNvbnN0cnVjdG9yOiB7XG4gICAgICAgIHZhbHVlOiBjdG9yLFxuICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgICAgfVxuICAgIH0pO1xuICB9O1xufSBlbHNlIHtcbiAgLy8gb2xkIHNjaG9vbCBzaGltIGZvciBvbGQgYnJvd3NlcnNcbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpbmhlcml0cyhjdG9yLCBzdXBlckN0b3IpIHtcbiAgICBjdG9yLnN1cGVyXyA9IHN1cGVyQ3RvclxuICAgIHZhciBUZW1wQ3RvciA9IGZ1bmN0aW9uICgpIHt9XG4gICAgVGVtcEN0b3IucHJvdG90eXBlID0gc3VwZXJDdG9yLnByb3RvdHlwZVxuICAgIGN0b3IucHJvdG90eXBlID0gbmV3IFRlbXBDdG9yKClcbiAgICBjdG9yLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IGN0b3JcbiAgfVxufVxuIiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpc0J1ZmZlcihhcmcpIHtcbiAgcmV0dXJuIGFyZyAmJiB0eXBlb2YgYXJnID09PSAnb2JqZWN0J1xuICAgICYmIHR5cGVvZiBhcmcuY29weSA9PT0gJ2Z1bmN0aW9uJ1xuICAgICYmIHR5cGVvZiBhcmcuZmlsbCA9PT0gJ2Z1bmN0aW9uJ1xuICAgICYmIHR5cGVvZiBhcmcucmVhZFVJbnQ4ID09PSAnZnVuY3Rpb24nO1xufSIsIi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG52YXIgZm9ybWF0UmVnRXhwID0gLyVbc2RqJV0vZztcbmV4cG9ydHMuZm9ybWF0ID0gZnVuY3Rpb24oZikge1xuICBpZiAoIWlzU3RyaW5nKGYpKSB7XG4gICAgdmFyIG9iamVjdHMgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgb2JqZWN0cy5wdXNoKGluc3BlY3QoYXJndW1lbnRzW2ldKSk7XG4gICAgfVxuICAgIHJldHVybiBvYmplY3RzLmpvaW4oJyAnKTtcbiAgfVxuXG4gIHZhciBpID0gMTtcbiAgdmFyIGFyZ3MgPSBhcmd1bWVudHM7XG4gIHZhciBsZW4gPSBhcmdzLmxlbmd0aDtcbiAgdmFyIHN0ciA9IFN0cmluZyhmKS5yZXBsYWNlKGZvcm1hdFJlZ0V4cCwgZnVuY3Rpb24oeCkge1xuICAgIGlmICh4ID09PSAnJSUnKSByZXR1cm4gJyUnO1xuICAgIGlmIChpID49IGxlbikgcmV0dXJuIHg7XG4gICAgc3dpdGNoICh4KSB7XG4gICAgICBjYXNlICclcyc6IHJldHVybiBTdHJpbmcoYXJnc1tpKytdKTtcbiAgICAgIGNhc2UgJyVkJzogcmV0dXJuIE51bWJlcihhcmdzW2krK10pO1xuICAgICAgY2FzZSAnJWonOlxuICAgICAgICB0cnkge1xuICAgICAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShhcmdzW2krK10pO1xuICAgICAgICB9IGNhdGNoIChfKSB7XG4gICAgICAgICAgcmV0dXJuICdbQ2lyY3VsYXJdJztcbiAgICAgICAgfVxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIHg7XG4gICAgfVxuICB9KTtcbiAgZm9yICh2YXIgeCA9IGFyZ3NbaV07IGkgPCBsZW47IHggPSBhcmdzWysraV0pIHtcbiAgICBpZiAoaXNOdWxsKHgpIHx8ICFpc09iamVjdCh4KSkge1xuICAgICAgc3RyICs9ICcgJyArIHg7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0ciArPSAnICcgKyBpbnNwZWN0KHgpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gc3RyO1xufTtcblxuXG4vLyBNYXJrIHRoYXQgYSBtZXRob2Qgc2hvdWxkIG5vdCBiZSB1c2VkLlxuLy8gUmV0dXJucyBhIG1vZGlmaWVkIGZ1bmN0aW9uIHdoaWNoIHdhcm5zIG9uY2UgYnkgZGVmYXVsdC5cbi8vIElmIC0tbm8tZGVwcmVjYXRpb24gaXMgc2V0LCB0aGVuIGl0IGlzIGEgbm8tb3AuXG5leHBvcnRzLmRlcHJlY2F0ZSA9IGZ1bmN0aW9uKGZuLCBtc2cpIHtcbiAgLy8gQWxsb3cgZm9yIGRlcHJlY2F0aW5nIHRoaW5ncyBpbiB0aGUgcHJvY2VzcyBvZiBzdGFydGluZyB1cC5cbiAgaWYgKGlzVW5kZWZpbmVkKGdsb2JhbC5wcm9jZXNzKSkge1xuICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBleHBvcnRzLmRlcHJlY2F0ZShmbiwgbXNnKS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH07XG4gIH1cblxuICBpZiAocHJvY2Vzcy5ub0RlcHJlY2F0aW9uID09PSB0cnVlKSB7XG4gICAgcmV0dXJuIGZuO1xuICB9XG5cbiAgdmFyIHdhcm5lZCA9IGZhbHNlO1xuICBmdW5jdGlvbiBkZXByZWNhdGVkKCkge1xuICAgIGlmICghd2FybmVkKSB7XG4gICAgICBpZiAocHJvY2Vzcy50aHJvd0RlcHJlY2F0aW9uKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihtc2cpO1xuICAgICAgfSBlbHNlIGlmIChwcm9jZXNzLnRyYWNlRGVwcmVjYXRpb24pIHtcbiAgICAgICAgY29uc29sZS50cmFjZShtc2cpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihtc2cpO1xuICAgICAgfVxuICAgICAgd2FybmVkID0gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gIH1cblxuICByZXR1cm4gZGVwcmVjYXRlZDtcbn07XG5cblxudmFyIGRlYnVncyA9IHt9O1xudmFyIGRlYnVnRW52aXJvbjtcbmV4cG9ydHMuZGVidWdsb2cgPSBmdW5jdGlvbihzZXQpIHtcbiAgaWYgKGlzVW5kZWZpbmVkKGRlYnVnRW52aXJvbikpXG4gICAgZGVidWdFbnZpcm9uID0gcHJvY2Vzcy5lbnYuTk9ERV9ERUJVRyB8fCAnJztcbiAgc2V0ID0gc2V0LnRvVXBwZXJDYXNlKCk7XG4gIGlmICghZGVidWdzW3NldF0pIHtcbiAgICBpZiAobmV3IFJlZ0V4cCgnXFxcXGInICsgc2V0ICsgJ1xcXFxiJywgJ2knKS50ZXN0KGRlYnVnRW52aXJvbikpIHtcbiAgICAgIHZhciBwaWQgPSBwcm9jZXNzLnBpZDtcbiAgICAgIGRlYnVnc1tzZXRdID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBtc2cgPSBleHBvcnRzLmZvcm1hdC5hcHBseShleHBvcnRzLCBhcmd1bWVudHMpO1xuICAgICAgICBjb25zb2xlLmVycm9yKCclcyAlZDogJXMnLCBzZXQsIHBpZCwgbXNnKTtcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIGRlYnVnc1tzZXRdID0gZnVuY3Rpb24oKSB7fTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGRlYnVnc1tzZXRdO1xufTtcblxuXG4vKipcbiAqIEVjaG9zIHRoZSB2YWx1ZSBvZiBhIHZhbHVlLiBUcnlzIHRvIHByaW50IHRoZSB2YWx1ZSBvdXRcbiAqIGluIHRoZSBiZXN0IHdheSBwb3NzaWJsZSBnaXZlbiB0aGUgZGlmZmVyZW50IHR5cGVzLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmogVGhlIG9iamVjdCB0byBwcmludCBvdXQuXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0cyBPcHRpb25hbCBvcHRpb25zIG9iamVjdCB0aGF0IGFsdGVycyB0aGUgb3V0cHV0LlxuICovXG4vKiBsZWdhY3k6IG9iaiwgc2hvd0hpZGRlbiwgZGVwdGgsIGNvbG9ycyovXG5mdW5jdGlvbiBpbnNwZWN0KG9iaiwgb3B0cykge1xuICAvLyBkZWZhdWx0IG9wdGlvbnNcbiAgdmFyIGN0eCA9IHtcbiAgICBzZWVuOiBbXSxcbiAgICBzdHlsaXplOiBzdHlsaXplTm9Db2xvclxuICB9O1xuICAvLyBsZWdhY3kuLi5cbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPj0gMykgY3R4LmRlcHRoID0gYXJndW1lbnRzWzJdO1xuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+PSA0KSBjdHguY29sb3JzID0gYXJndW1lbnRzWzNdO1xuICBpZiAoaXNCb29sZWFuKG9wdHMpKSB7XG4gICAgLy8gbGVnYWN5Li4uXG4gICAgY3R4LnNob3dIaWRkZW4gPSBvcHRzO1xuICB9IGVsc2UgaWYgKG9wdHMpIHtcbiAgICAvLyBnb3QgYW4gXCJvcHRpb25zXCIgb2JqZWN0XG4gICAgZXhwb3J0cy5fZXh0ZW5kKGN0eCwgb3B0cyk7XG4gIH1cbiAgLy8gc2V0IGRlZmF1bHQgb3B0aW9uc1xuICBpZiAoaXNVbmRlZmluZWQoY3R4LnNob3dIaWRkZW4pKSBjdHguc2hvd0hpZGRlbiA9IGZhbHNlO1xuICBpZiAoaXNVbmRlZmluZWQoY3R4LmRlcHRoKSkgY3R4LmRlcHRoID0gMjtcbiAgaWYgKGlzVW5kZWZpbmVkKGN0eC5jb2xvcnMpKSBjdHguY29sb3JzID0gZmFsc2U7XG4gIGlmIChpc1VuZGVmaW5lZChjdHguY3VzdG9tSW5zcGVjdCkpIGN0eC5jdXN0b21JbnNwZWN0ID0gdHJ1ZTtcbiAgaWYgKGN0eC5jb2xvcnMpIGN0eC5zdHlsaXplID0gc3R5bGl6ZVdpdGhDb2xvcjtcbiAgcmV0dXJuIGZvcm1hdFZhbHVlKGN0eCwgb2JqLCBjdHguZGVwdGgpO1xufVxuZXhwb3J0cy5pbnNwZWN0ID0gaW5zcGVjdDtcblxuXG4vLyBodHRwOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0FOU0lfZXNjYXBlX2NvZGUjZ3JhcGhpY3Ncbmluc3BlY3QuY29sb3JzID0ge1xuICAnYm9sZCcgOiBbMSwgMjJdLFxuICAnaXRhbGljJyA6IFszLCAyM10sXG4gICd1bmRlcmxpbmUnIDogWzQsIDI0XSxcbiAgJ2ludmVyc2UnIDogWzcsIDI3XSxcbiAgJ3doaXRlJyA6IFszNywgMzldLFxuICAnZ3JleScgOiBbOTAsIDM5XSxcbiAgJ2JsYWNrJyA6IFszMCwgMzldLFxuICAnYmx1ZScgOiBbMzQsIDM5XSxcbiAgJ2N5YW4nIDogWzM2LCAzOV0sXG4gICdncmVlbicgOiBbMzIsIDM5XSxcbiAgJ21hZ2VudGEnIDogWzM1LCAzOV0sXG4gICdyZWQnIDogWzMxLCAzOV0sXG4gICd5ZWxsb3cnIDogWzMzLCAzOV1cbn07XG5cbi8vIERvbid0IHVzZSAnYmx1ZScgbm90IHZpc2libGUgb24gY21kLmV4ZVxuaW5zcGVjdC5zdHlsZXMgPSB7XG4gICdzcGVjaWFsJzogJ2N5YW4nLFxuICAnbnVtYmVyJzogJ3llbGxvdycsXG4gICdib29sZWFuJzogJ3llbGxvdycsXG4gICd1bmRlZmluZWQnOiAnZ3JleScsXG4gICdudWxsJzogJ2JvbGQnLFxuICAnc3RyaW5nJzogJ2dyZWVuJyxcbiAgJ2RhdGUnOiAnbWFnZW50YScsXG4gIC8vIFwibmFtZVwiOiBpbnRlbnRpb25hbGx5IG5vdCBzdHlsaW5nXG4gICdyZWdleHAnOiAncmVkJ1xufTtcblxuXG5mdW5jdGlvbiBzdHlsaXplV2l0aENvbG9yKHN0ciwgc3R5bGVUeXBlKSB7XG4gIHZhciBzdHlsZSA9IGluc3BlY3Quc3R5bGVzW3N0eWxlVHlwZV07XG5cbiAgaWYgKHN0eWxlKSB7XG4gICAgcmV0dXJuICdcXHUwMDFiWycgKyBpbnNwZWN0LmNvbG9yc1tzdHlsZV1bMF0gKyAnbScgKyBzdHIgK1xuICAgICAgICAgICAnXFx1MDAxYlsnICsgaW5zcGVjdC5jb2xvcnNbc3R5bGVdWzFdICsgJ20nO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBzdHI7XG4gIH1cbn1cblxuXG5mdW5jdGlvbiBzdHlsaXplTm9Db2xvcihzdHIsIHN0eWxlVHlwZSkge1xuICByZXR1cm4gc3RyO1xufVxuXG5cbmZ1bmN0aW9uIGFycmF5VG9IYXNoKGFycmF5KSB7XG4gIHZhciBoYXNoID0ge307XG5cbiAgYXJyYXkuZm9yRWFjaChmdW5jdGlvbih2YWwsIGlkeCkge1xuICAgIGhhc2hbdmFsXSA9IHRydWU7XG4gIH0pO1xuXG4gIHJldHVybiBoYXNoO1xufVxuXG5cbmZ1bmN0aW9uIGZvcm1hdFZhbHVlKGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcykge1xuICAvLyBQcm92aWRlIGEgaG9vayBmb3IgdXNlci1zcGVjaWZpZWQgaW5zcGVjdCBmdW5jdGlvbnMuXG4gIC8vIENoZWNrIHRoYXQgdmFsdWUgaXMgYW4gb2JqZWN0IHdpdGggYW4gaW5zcGVjdCBmdW5jdGlvbiBvbiBpdFxuICBpZiAoY3R4LmN1c3RvbUluc3BlY3QgJiZcbiAgICAgIHZhbHVlICYmXG4gICAgICBpc0Z1bmN0aW9uKHZhbHVlLmluc3BlY3QpICYmXG4gICAgICAvLyBGaWx0ZXIgb3V0IHRoZSB1dGlsIG1vZHVsZSwgaXQncyBpbnNwZWN0IGZ1bmN0aW9uIGlzIHNwZWNpYWxcbiAgICAgIHZhbHVlLmluc3BlY3QgIT09IGV4cG9ydHMuaW5zcGVjdCAmJlxuICAgICAgLy8gQWxzbyBmaWx0ZXIgb3V0IGFueSBwcm90b3R5cGUgb2JqZWN0cyB1c2luZyB0aGUgY2lyY3VsYXIgY2hlY2suXG4gICAgICAhKHZhbHVlLmNvbnN0cnVjdG9yICYmIHZhbHVlLmNvbnN0cnVjdG9yLnByb3RvdHlwZSA9PT0gdmFsdWUpKSB7XG4gICAgdmFyIHJldCA9IHZhbHVlLmluc3BlY3QocmVjdXJzZVRpbWVzLCBjdHgpO1xuICAgIGlmICghaXNTdHJpbmcocmV0KSkge1xuICAgICAgcmV0ID0gZm9ybWF0VmFsdWUoY3R4LCByZXQsIHJlY3Vyc2VUaW1lcyk7XG4gICAgfVxuICAgIHJldHVybiByZXQ7XG4gIH1cblxuICAvLyBQcmltaXRpdmUgdHlwZXMgY2Fubm90IGhhdmUgcHJvcGVydGllc1xuICB2YXIgcHJpbWl0aXZlID0gZm9ybWF0UHJpbWl0aXZlKGN0eCwgdmFsdWUpO1xuICBpZiAocHJpbWl0aXZlKSB7XG4gICAgcmV0dXJuIHByaW1pdGl2ZTtcbiAgfVxuXG4gIC8vIExvb2sgdXAgdGhlIGtleXMgb2YgdGhlIG9iamVjdC5cbiAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyh2YWx1ZSk7XG4gIHZhciB2aXNpYmxlS2V5cyA9IGFycmF5VG9IYXNoKGtleXMpO1xuXG4gIGlmIChjdHguc2hvd0hpZGRlbikge1xuICAgIGtleXMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh2YWx1ZSk7XG4gIH1cblxuICAvLyBJRSBkb2Vzbid0IG1ha2UgZXJyb3IgZmllbGRzIG5vbi1lbnVtZXJhYmxlXG4gIC8vIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9pZS9kd3c1MnNidCh2PXZzLjk0KS5hc3B4XG4gIGlmIChpc0Vycm9yKHZhbHVlKVxuICAgICAgJiYgKGtleXMuaW5kZXhPZignbWVzc2FnZScpID49IDAgfHwga2V5cy5pbmRleE9mKCdkZXNjcmlwdGlvbicpID49IDApKSB7XG4gICAgcmV0dXJuIGZvcm1hdEVycm9yKHZhbHVlKTtcbiAgfVxuXG4gIC8vIFNvbWUgdHlwZSBvZiBvYmplY3Qgd2l0aG91dCBwcm9wZXJ0aWVzIGNhbiBiZSBzaG9ydGN1dHRlZC5cbiAgaWYgKGtleXMubGVuZ3RoID09PSAwKSB7XG4gICAgaWYgKGlzRnVuY3Rpb24odmFsdWUpKSB7XG4gICAgICB2YXIgbmFtZSA9IHZhbHVlLm5hbWUgPyAnOiAnICsgdmFsdWUubmFtZSA6ICcnO1xuICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKCdbRnVuY3Rpb24nICsgbmFtZSArICddJywgJ3NwZWNpYWwnKTtcbiAgICB9XG4gICAgaWYgKGlzUmVnRXhwKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKFJlZ0V4cC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSksICdyZWdleHAnKTtcbiAgICB9XG4gICAgaWYgKGlzRGF0ZSh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBjdHguc3R5bGl6ZShEYXRlLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKSwgJ2RhdGUnKTtcbiAgICB9XG4gICAgaWYgKGlzRXJyb3IodmFsdWUpKSB7XG4gICAgICByZXR1cm4gZm9ybWF0RXJyb3IodmFsdWUpO1xuICAgIH1cbiAgfVxuXG4gIHZhciBiYXNlID0gJycsIGFycmF5ID0gZmFsc2UsIGJyYWNlcyA9IFsneycsICd9J107XG5cbiAgLy8gTWFrZSBBcnJheSBzYXkgdGhhdCB0aGV5IGFyZSBBcnJheVxuICBpZiAoaXNBcnJheSh2YWx1ZSkpIHtcbiAgICBhcnJheSA9IHRydWU7XG4gICAgYnJhY2VzID0gWydbJywgJ10nXTtcbiAgfVxuXG4gIC8vIE1ha2UgZnVuY3Rpb25zIHNheSB0aGF0IHRoZXkgYXJlIGZ1bmN0aW9uc1xuICBpZiAoaXNGdW5jdGlvbih2YWx1ZSkpIHtcbiAgICB2YXIgbiA9IHZhbHVlLm5hbWUgPyAnOiAnICsgdmFsdWUubmFtZSA6ICcnO1xuICAgIGJhc2UgPSAnIFtGdW5jdGlvbicgKyBuICsgJ10nO1xuICB9XG5cbiAgLy8gTWFrZSBSZWdFeHBzIHNheSB0aGF0IHRoZXkgYXJlIFJlZ0V4cHNcbiAgaWYgKGlzUmVnRXhwKHZhbHVlKSkge1xuICAgIGJhc2UgPSAnICcgKyBSZWdFeHAucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpO1xuICB9XG5cbiAgLy8gTWFrZSBkYXRlcyB3aXRoIHByb3BlcnRpZXMgZmlyc3Qgc2F5IHRoZSBkYXRlXG4gIGlmIChpc0RhdGUodmFsdWUpKSB7XG4gICAgYmFzZSA9ICcgJyArIERhdGUucHJvdG90eXBlLnRvVVRDU3RyaW5nLmNhbGwodmFsdWUpO1xuICB9XG5cbiAgLy8gTWFrZSBlcnJvciB3aXRoIG1lc3NhZ2UgZmlyc3Qgc2F5IHRoZSBlcnJvclxuICBpZiAoaXNFcnJvcih2YWx1ZSkpIHtcbiAgICBiYXNlID0gJyAnICsgZm9ybWF0RXJyb3IodmFsdWUpO1xuICB9XG5cbiAgaWYgKGtleXMubGVuZ3RoID09PSAwICYmICghYXJyYXkgfHwgdmFsdWUubGVuZ3RoID09IDApKSB7XG4gICAgcmV0dXJuIGJyYWNlc1swXSArIGJhc2UgKyBicmFjZXNbMV07XG4gIH1cblxuICBpZiAocmVjdXJzZVRpbWVzIDwgMCkge1xuICAgIGlmIChpc1JlZ0V4cCh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBjdHguc3R5bGl6ZShSZWdFeHAucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpLCAncmVnZXhwJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBjdHguc3R5bGl6ZSgnW09iamVjdF0nLCAnc3BlY2lhbCcpO1xuICAgIH1cbiAgfVxuXG4gIGN0eC5zZWVuLnB1c2godmFsdWUpO1xuXG4gIHZhciBvdXRwdXQ7XG4gIGlmIChhcnJheSkge1xuICAgIG91dHB1dCA9IGZvcm1hdEFycmF5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsIGtleXMpO1xuICB9IGVsc2Uge1xuICAgIG91dHB1dCA9IGtleXMubWFwKGZ1bmN0aW9uKGtleSkge1xuICAgICAgcmV0dXJuIGZvcm1hdFByb3BlcnR5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsIGtleSwgYXJyYXkpO1xuICAgIH0pO1xuICB9XG5cbiAgY3R4LnNlZW4ucG9wKCk7XG5cbiAgcmV0dXJuIHJlZHVjZVRvU2luZ2xlU3RyaW5nKG91dHB1dCwgYmFzZSwgYnJhY2VzKTtcbn1cblxuXG5mdW5jdGlvbiBmb3JtYXRQcmltaXRpdmUoY3R4LCB2YWx1ZSkge1xuICBpZiAoaXNVbmRlZmluZWQodmFsdWUpKVxuICAgIHJldHVybiBjdHguc3R5bGl6ZSgndW5kZWZpbmVkJywgJ3VuZGVmaW5lZCcpO1xuICBpZiAoaXNTdHJpbmcodmFsdWUpKSB7XG4gICAgdmFyIHNpbXBsZSA9ICdcXCcnICsgSlNPTi5zdHJpbmdpZnkodmFsdWUpLnJlcGxhY2UoL15cInxcIiQvZywgJycpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAucmVwbGFjZSgvJy9nLCBcIlxcXFwnXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAucmVwbGFjZSgvXFxcXFwiL2csICdcIicpICsgJ1xcJyc7XG4gICAgcmV0dXJuIGN0eC5zdHlsaXplKHNpbXBsZSwgJ3N0cmluZycpO1xuICB9XG4gIGlmIChpc051bWJlcih2YWx1ZSkpXG4gICAgcmV0dXJuIGN0eC5zdHlsaXplKCcnICsgdmFsdWUsICdudW1iZXInKTtcbiAgaWYgKGlzQm9vbGVhbih2YWx1ZSkpXG4gICAgcmV0dXJuIGN0eC5zdHlsaXplKCcnICsgdmFsdWUsICdib29sZWFuJyk7XG4gIC8vIEZvciBzb21lIHJlYXNvbiB0eXBlb2YgbnVsbCBpcyBcIm9iamVjdFwiLCBzbyBzcGVjaWFsIGNhc2UgaGVyZS5cbiAgaWYgKGlzTnVsbCh2YWx1ZSkpXG4gICAgcmV0dXJuIGN0eC5zdHlsaXplKCdudWxsJywgJ251bGwnKTtcbn1cblxuXG5mdW5jdGlvbiBmb3JtYXRFcnJvcih2YWx1ZSkge1xuICByZXR1cm4gJ1snICsgRXJyb3IucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpICsgJ10nO1xufVxuXG5cbmZ1bmN0aW9uIGZvcm1hdEFycmF5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsIGtleXMpIHtcbiAgdmFyIG91dHB1dCA9IFtdO1xuICBmb3IgKHZhciBpID0gMCwgbCA9IHZhbHVlLmxlbmd0aDsgaSA8IGw7ICsraSkge1xuICAgIGlmIChoYXNPd25Qcm9wZXJ0eSh2YWx1ZSwgU3RyaW5nKGkpKSkge1xuICAgICAgb3V0cHV0LnB1c2goZm9ybWF0UHJvcGVydHkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cyxcbiAgICAgICAgICBTdHJpbmcoaSksIHRydWUpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgb3V0cHV0LnB1c2goJycpO1xuICAgIH1cbiAgfVxuICBrZXlzLmZvckVhY2goZnVuY3Rpb24oa2V5KSB7XG4gICAgaWYgKCFrZXkubWF0Y2goL15cXGQrJC8pKSB7XG4gICAgICBvdXRwdXQucHVzaChmb3JtYXRQcm9wZXJ0eShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLFxuICAgICAgICAgIGtleSwgdHJ1ZSkpO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiBvdXRwdXQ7XG59XG5cblxuZnVuY3Rpb24gZm9ybWF0UHJvcGVydHkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cywga2V5LCBhcnJheSkge1xuICB2YXIgbmFtZSwgc3RyLCBkZXNjO1xuICBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih2YWx1ZSwga2V5KSB8fCB7IHZhbHVlOiB2YWx1ZVtrZXldIH07XG4gIGlmIChkZXNjLmdldCkge1xuICAgIGlmIChkZXNjLnNldCkge1xuICAgICAgc3RyID0gY3R4LnN0eWxpemUoJ1tHZXR0ZXIvU2V0dGVyXScsICdzcGVjaWFsJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0ciA9IGN0eC5zdHlsaXplKCdbR2V0dGVyXScsICdzcGVjaWFsJyk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGlmIChkZXNjLnNldCkge1xuICAgICAgc3RyID0gY3R4LnN0eWxpemUoJ1tTZXR0ZXJdJywgJ3NwZWNpYWwnKTtcbiAgICB9XG4gIH1cbiAgaWYgKCFoYXNPd25Qcm9wZXJ0eSh2aXNpYmxlS2V5cywga2V5KSkge1xuICAgIG5hbWUgPSAnWycgKyBrZXkgKyAnXSc7XG4gIH1cbiAgaWYgKCFzdHIpIHtcbiAgICBpZiAoY3R4LnNlZW4uaW5kZXhPZihkZXNjLnZhbHVlKSA8IDApIHtcbiAgICAgIGlmIChpc051bGwocmVjdXJzZVRpbWVzKSkge1xuICAgICAgICBzdHIgPSBmb3JtYXRWYWx1ZShjdHgsIGRlc2MudmFsdWUsIG51bGwpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3RyID0gZm9ybWF0VmFsdWUoY3R4LCBkZXNjLnZhbHVlLCByZWN1cnNlVGltZXMgLSAxKTtcbiAgICAgIH1cbiAgICAgIGlmIChzdHIuaW5kZXhPZignXFxuJykgPiAtMSkge1xuICAgICAgICBpZiAoYXJyYXkpIHtcbiAgICAgICAgICBzdHIgPSBzdHIuc3BsaXQoJ1xcbicpLm1hcChmdW5jdGlvbihsaW5lKSB7XG4gICAgICAgICAgICByZXR1cm4gJyAgJyArIGxpbmU7XG4gICAgICAgICAgfSkuam9pbignXFxuJykuc3Vic3RyKDIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHN0ciA9ICdcXG4nICsgc3RyLnNwbGl0KCdcXG4nKS5tYXAoZnVuY3Rpb24obGluZSkge1xuICAgICAgICAgICAgcmV0dXJuICcgICAnICsgbGluZTtcbiAgICAgICAgICB9KS5qb2luKCdcXG4nKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBzdHIgPSBjdHguc3R5bGl6ZSgnW0NpcmN1bGFyXScsICdzcGVjaWFsJyk7XG4gICAgfVxuICB9XG4gIGlmIChpc1VuZGVmaW5lZChuYW1lKSkge1xuICAgIGlmIChhcnJheSAmJiBrZXkubWF0Y2goL15cXGQrJC8pKSB7XG4gICAgICByZXR1cm4gc3RyO1xuICAgIH1cbiAgICBuYW1lID0gSlNPTi5zdHJpbmdpZnkoJycgKyBrZXkpO1xuICAgIGlmIChuYW1lLm1hdGNoKC9eXCIoW2EtekEtWl9dW2EtekEtWl8wLTldKilcIiQvKSkge1xuICAgICAgbmFtZSA9IG5hbWUuc3Vic3RyKDEsIG5hbWUubGVuZ3RoIC0gMik7XG4gICAgICBuYW1lID0gY3R4LnN0eWxpemUobmFtZSwgJ25hbWUnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbmFtZSA9IG5hbWUucmVwbGFjZSgvJy9nLCBcIlxcXFwnXCIpXG4gICAgICAgICAgICAgICAgIC5yZXBsYWNlKC9cXFxcXCIvZywgJ1wiJylcbiAgICAgICAgICAgICAgICAgLnJlcGxhY2UoLyheXCJ8XCIkKS9nLCBcIidcIik7XG4gICAgICBuYW1lID0gY3R4LnN0eWxpemUobmFtZSwgJ3N0cmluZycpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBuYW1lICsgJzogJyArIHN0cjtcbn1cblxuXG5mdW5jdGlvbiByZWR1Y2VUb1NpbmdsZVN0cmluZyhvdXRwdXQsIGJhc2UsIGJyYWNlcykge1xuICB2YXIgbnVtTGluZXNFc3QgPSAwO1xuICB2YXIgbGVuZ3RoID0gb3V0cHV0LnJlZHVjZShmdW5jdGlvbihwcmV2LCBjdXIpIHtcbiAgICBudW1MaW5lc0VzdCsrO1xuICAgIGlmIChjdXIuaW5kZXhPZignXFxuJykgPj0gMCkgbnVtTGluZXNFc3QrKztcbiAgICByZXR1cm4gcHJldiArIGN1ci5yZXBsYWNlKC9cXHUwMDFiXFxbXFxkXFxkP20vZywgJycpLmxlbmd0aCArIDE7XG4gIH0sIDApO1xuXG4gIGlmIChsZW5ndGggPiA2MCkge1xuICAgIHJldHVybiBicmFjZXNbMF0gK1xuICAgICAgICAgICAoYmFzZSA9PT0gJycgPyAnJyA6IGJhc2UgKyAnXFxuICcpICtcbiAgICAgICAgICAgJyAnICtcbiAgICAgICAgICAgb3V0cHV0LmpvaW4oJyxcXG4gICcpICtcbiAgICAgICAgICAgJyAnICtcbiAgICAgICAgICAgYnJhY2VzWzFdO1xuICB9XG5cbiAgcmV0dXJuIGJyYWNlc1swXSArIGJhc2UgKyAnICcgKyBvdXRwdXQuam9pbignLCAnKSArICcgJyArIGJyYWNlc1sxXTtcbn1cblxuXG4vLyBOT1RFOiBUaGVzZSB0eXBlIGNoZWNraW5nIGZ1bmN0aW9ucyBpbnRlbnRpb25hbGx5IGRvbid0IHVzZSBgaW5zdGFuY2VvZmBcbi8vIGJlY2F1c2UgaXQgaXMgZnJhZ2lsZSBhbmQgY2FuIGJlIGVhc2lseSBmYWtlZCB3aXRoIGBPYmplY3QuY3JlYXRlKClgLlxuZnVuY3Rpb24gaXNBcnJheShhcikge1xuICByZXR1cm4gQXJyYXkuaXNBcnJheShhcik7XG59XG5leHBvcnRzLmlzQXJyYXkgPSBpc0FycmF5O1xuXG5mdW5jdGlvbiBpc0Jvb2xlYW4oYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnYm9vbGVhbic7XG59XG5leHBvcnRzLmlzQm9vbGVhbiA9IGlzQm9vbGVhbjtcblxuZnVuY3Rpb24gaXNOdWxsKGFyZykge1xuICByZXR1cm4gYXJnID09PSBudWxsO1xufVxuZXhwb3J0cy5pc051bGwgPSBpc051bGw7XG5cbmZ1bmN0aW9uIGlzTnVsbE9yVW5kZWZpbmVkKGFyZykge1xuICByZXR1cm4gYXJnID09IG51bGw7XG59XG5leHBvcnRzLmlzTnVsbE9yVW5kZWZpbmVkID0gaXNOdWxsT3JVbmRlZmluZWQ7XG5cbmZ1bmN0aW9uIGlzTnVtYmVyKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ251bWJlcic7XG59XG5leHBvcnRzLmlzTnVtYmVyID0gaXNOdW1iZXI7XG5cbmZ1bmN0aW9uIGlzU3RyaW5nKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ3N0cmluZyc7XG59XG5leHBvcnRzLmlzU3RyaW5nID0gaXNTdHJpbmc7XG5cbmZ1bmN0aW9uIGlzU3ltYm9sKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ3N5bWJvbCc7XG59XG5leHBvcnRzLmlzU3ltYm9sID0gaXNTeW1ib2w7XG5cbmZ1bmN0aW9uIGlzVW5kZWZpbmVkKGFyZykge1xuICByZXR1cm4gYXJnID09PSB2b2lkIDA7XG59XG5leHBvcnRzLmlzVW5kZWZpbmVkID0gaXNVbmRlZmluZWQ7XG5cbmZ1bmN0aW9uIGlzUmVnRXhwKHJlKSB7XG4gIHJldHVybiBpc09iamVjdChyZSkgJiYgb2JqZWN0VG9TdHJpbmcocmUpID09PSAnW29iamVjdCBSZWdFeHBdJztcbn1cbmV4cG9ydHMuaXNSZWdFeHAgPSBpc1JlZ0V4cDtcblxuZnVuY3Rpb24gaXNPYmplY3QoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnb2JqZWN0JyAmJiBhcmcgIT09IG51bGw7XG59XG5leHBvcnRzLmlzT2JqZWN0ID0gaXNPYmplY3Q7XG5cbmZ1bmN0aW9uIGlzRGF0ZShkKSB7XG4gIHJldHVybiBpc09iamVjdChkKSAmJiBvYmplY3RUb1N0cmluZyhkKSA9PT0gJ1tvYmplY3QgRGF0ZV0nO1xufVxuZXhwb3J0cy5pc0RhdGUgPSBpc0RhdGU7XG5cbmZ1bmN0aW9uIGlzRXJyb3IoZSkge1xuICByZXR1cm4gaXNPYmplY3QoZSkgJiZcbiAgICAgIChvYmplY3RUb1N0cmluZyhlKSA9PT0gJ1tvYmplY3QgRXJyb3JdJyB8fCBlIGluc3RhbmNlb2YgRXJyb3IpO1xufVxuZXhwb3J0cy5pc0Vycm9yID0gaXNFcnJvcjtcblxuZnVuY3Rpb24gaXNGdW5jdGlvbihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdmdW5jdGlvbic7XG59XG5leHBvcnRzLmlzRnVuY3Rpb24gPSBpc0Z1bmN0aW9uO1xuXG5mdW5jdGlvbiBpc1ByaW1pdGl2ZShhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gbnVsbCB8fFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ2Jvb2xlYW4nIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnbnVtYmVyJyB8fFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ3N0cmluZycgfHxcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICdzeW1ib2wnIHx8ICAvLyBFUzYgc3ltYm9sXG4gICAgICAgICB0eXBlb2YgYXJnID09PSAndW5kZWZpbmVkJztcbn1cbmV4cG9ydHMuaXNQcmltaXRpdmUgPSBpc1ByaW1pdGl2ZTtcblxuZXhwb3J0cy5pc0J1ZmZlciA9IHJlcXVpcmUoJy4vc3VwcG9ydC9pc0J1ZmZlcicpO1xuXG5mdW5jdGlvbiBvYmplY3RUb1N0cmluZyhvKSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobyk7XG59XG5cblxuZnVuY3Rpb24gcGFkKG4pIHtcbiAgcmV0dXJuIG4gPCAxMCA/ICcwJyArIG4udG9TdHJpbmcoMTApIDogbi50b1N0cmluZygxMCk7XG59XG5cblxudmFyIG1vbnRocyA9IFsnSmFuJywgJ0ZlYicsICdNYXInLCAnQXByJywgJ01heScsICdKdW4nLCAnSnVsJywgJ0F1ZycsICdTZXAnLFxuICAgICAgICAgICAgICAnT2N0JywgJ05vdicsICdEZWMnXTtcblxuLy8gMjYgRmViIDE2OjE5OjM0XG5mdW5jdGlvbiB0aW1lc3RhbXAoKSB7XG4gIHZhciBkID0gbmV3IERhdGUoKTtcbiAgdmFyIHRpbWUgPSBbcGFkKGQuZ2V0SG91cnMoKSksXG4gICAgICAgICAgICAgIHBhZChkLmdldE1pbnV0ZXMoKSksXG4gICAgICAgICAgICAgIHBhZChkLmdldFNlY29uZHMoKSldLmpvaW4oJzonKTtcbiAgcmV0dXJuIFtkLmdldERhdGUoKSwgbW9udGhzW2QuZ2V0TW9udGgoKV0sIHRpbWVdLmpvaW4oJyAnKTtcbn1cblxuXG4vLyBsb2cgaXMganVzdCBhIHRoaW4gd3JhcHBlciB0byBjb25zb2xlLmxvZyB0aGF0IHByZXBlbmRzIGEgdGltZXN0YW1wXG5leHBvcnRzLmxvZyA9IGZ1bmN0aW9uKCkge1xuICBjb25zb2xlLmxvZygnJXMgLSAlcycsIHRpbWVzdGFtcCgpLCBleHBvcnRzLmZvcm1hdC5hcHBseShleHBvcnRzLCBhcmd1bWVudHMpKTtcbn07XG5cblxuLyoqXG4gKiBJbmhlcml0IHRoZSBwcm90b3R5cGUgbWV0aG9kcyBmcm9tIG9uZSBjb25zdHJ1Y3RvciBpbnRvIGFub3RoZXIuXG4gKlxuICogVGhlIEZ1bmN0aW9uLnByb3RvdHlwZS5pbmhlcml0cyBmcm9tIGxhbmcuanMgcmV3cml0dGVuIGFzIGEgc3RhbmRhbG9uZVxuICogZnVuY3Rpb24gKG5vdCBvbiBGdW5jdGlvbi5wcm90b3R5cGUpLiBOT1RFOiBJZiB0aGlzIGZpbGUgaXMgdG8gYmUgbG9hZGVkXG4gKiBkdXJpbmcgYm9vdHN0cmFwcGluZyB0aGlzIGZ1bmN0aW9uIG5lZWRzIHRvIGJlIHJld3JpdHRlbiB1c2luZyBzb21lIG5hdGl2ZVxuICogZnVuY3Rpb25zIGFzIHByb3RvdHlwZSBzZXR1cCB1c2luZyBub3JtYWwgSmF2YVNjcmlwdCBkb2VzIG5vdCB3b3JrIGFzXG4gKiBleHBlY3RlZCBkdXJpbmcgYm9vdHN0cmFwcGluZyAoc2VlIG1pcnJvci5qcyBpbiByMTE0OTAzKS5cbiAqXG4gKiBAcGFyYW0ge2Z1bmN0aW9ufSBjdG9yIENvbnN0cnVjdG9yIGZ1bmN0aW9uIHdoaWNoIG5lZWRzIHRvIGluaGVyaXQgdGhlXG4gKiAgICAgcHJvdG90eXBlLlxuICogQHBhcmFtIHtmdW5jdGlvbn0gc3VwZXJDdG9yIENvbnN0cnVjdG9yIGZ1bmN0aW9uIHRvIGluaGVyaXQgcHJvdG90eXBlIGZyb20uXG4gKi9cbmV4cG9ydHMuaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xuXG5leHBvcnRzLl9leHRlbmQgPSBmdW5jdGlvbihvcmlnaW4sIGFkZCkge1xuICAvLyBEb24ndCBkbyBhbnl0aGluZyBpZiBhZGQgaXNuJ3QgYW4gb2JqZWN0XG4gIGlmICghYWRkIHx8ICFpc09iamVjdChhZGQpKSByZXR1cm4gb3JpZ2luO1xuXG4gIHZhciBrZXlzID0gT2JqZWN0LmtleXMoYWRkKTtcbiAgdmFyIGkgPSBrZXlzLmxlbmd0aDtcbiAgd2hpbGUgKGktLSkge1xuICAgIG9yaWdpbltrZXlzW2ldXSA9IGFkZFtrZXlzW2ldXTtcbiAgfVxuICByZXR1cm4gb3JpZ2luO1xufTtcblxuZnVuY3Rpb24gaGFzT3duUHJvcGVydHkob2JqLCBwcm9wKSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBwcm9wKTtcbn1cbiIsIid1c2Ugc3RyaWN0J1xuXG5leHBvcnRzLmJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoXG5leHBvcnRzLnRvQnl0ZUFycmF5ID0gdG9CeXRlQXJyYXlcbmV4cG9ydHMuZnJvbUJ5dGVBcnJheSA9IGZyb21CeXRlQXJyYXlcblxudmFyIGxvb2t1cCA9IFtdXG52YXIgcmV2TG9va3VwID0gW11cbnZhciBBcnIgPSB0eXBlb2YgVWludDhBcnJheSAhPT0gJ3VuZGVmaW5lZCcgPyBVaW50OEFycmF5IDogQXJyYXlcblxudmFyIGNvZGUgPSAnQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLydcbmZvciAodmFyIGkgPSAwLCBsZW4gPSBjb2RlLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XG4gIGxvb2t1cFtpXSA9IGNvZGVbaV1cbiAgcmV2TG9va3VwW2NvZGUuY2hhckNvZGVBdChpKV0gPSBpXG59XG5cbi8vIFN1cHBvcnQgZGVjb2RpbmcgVVJMLXNhZmUgYmFzZTY0IHN0cmluZ3MsIGFzIE5vZGUuanMgZG9lcy5cbi8vIFNlZTogaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQmFzZTY0I1VSTF9hcHBsaWNhdGlvbnNcbnJldkxvb2t1cFsnLScuY2hhckNvZGVBdCgwKV0gPSA2MlxucmV2TG9va3VwWydfJy5jaGFyQ29kZUF0KDApXSA9IDYzXG5cbmZ1bmN0aW9uIGdldExlbnMgKGI2NCkge1xuICB2YXIgbGVuID0gYjY0Lmxlbmd0aFxuXG4gIGlmIChsZW4gJSA0ID4gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBzdHJpbmcuIExlbmd0aCBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgNCcpXG4gIH1cblxuICAvLyBUcmltIG9mZiBleHRyYSBieXRlcyBhZnRlciBwbGFjZWhvbGRlciBieXRlcyBhcmUgZm91bmRcbiAgLy8gU2VlOiBodHRwczovL2dpdGh1Yi5jb20vYmVhdGdhbW1pdC9iYXNlNjQtanMvaXNzdWVzLzQyXG4gIHZhciB2YWxpZExlbiA9IGI2NC5pbmRleE9mKCc9JylcbiAgaWYgKHZhbGlkTGVuID09PSAtMSkgdmFsaWRMZW4gPSBsZW5cblxuICB2YXIgcGxhY2VIb2xkZXJzTGVuID0gdmFsaWRMZW4gPT09IGxlblxuICAgID8gMFxuICAgIDogNCAtICh2YWxpZExlbiAlIDQpXG5cbiAgcmV0dXJuIFt2YWxpZExlbiwgcGxhY2VIb2xkZXJzTGVuXVxufVxuXG4vLyBiYXNlNjQgaXMgNC8zICsgdXAgdG8gdHdvIGNoYXJhY3RlcnMgb2YgdGhlIG9yaWdpbmFsIGRhdGFcbmZ1bmN0aW9uIGJ5dGVMZW5ndGggKGI2NCkge1xuICB2YXIgbGVucyA9IGdldExlbnMoYjY0KVxuICB2YXIgdmFsaWRMZW4gPSBsZW5zWzBdXG4gIHZhciBwbGFjZUhvbGRlcnNMZW4gPSBsZW5zWzFdXG4gIHJldHVybiAoKHZhbGlkTGVuICsgcGxhY2VIb2xkZXJzTGVuKSAqIDMgLyA0KSAtIHBsYWNlSG9sZGVyc0xlblxufVxuXG5mdW5jdGlvbiBfYnl0ZUxlbmd0aCAoYjY0LCB2YWxpZExlbiwgcGxhY2VIb2xkZXJzTGVuKSB7XG4gIHJldHVybiAoKHZhbGlkTGVuICsgcGxhY2VIb2xkZXJzTGVuKSAqIDMgLyA0KSAtIHBsYWNlSG9sZGVyc0xlblxufVxuXG5mdW5jdGlvbiB0b0J5dGVBcnJheSAoYjY0KSB7XG4gIHZhciB0bXBcbiAgdmFyIGxlbnMgPSBnZXRMZW5zKGI2NClcbiAgdmFyIHZhbGlkTGVuID0gbGVuc1swXVxuICB2YXIgcGxhY2VIb2xkZXJzTGVuID0gbGVuc1sxXVxuXG4gIHZhciBhcnIgPSBuZXcgQXJyKF9ieXRlTGVuZ3RoKGI2NCwgdmFsaWRMZW4sIHBsYWNlSG9sZGVyc0xlbikpXG5cbiAgdmFyIGN1ckJ5dGUgPSAwXG5cbiAgLy8gaWYgdGhlcmUgYXJlIHBsYWNlaG9sZGVycywgb25seSBnZXQgdXAgdG8gdGhlIGxhc3QgY29tcGxldGUgNCBjaGFyc1xuICB2YXIgbGVuID0gcGxhY2VIb2xkZXJzTGVuID4gMFxuICAgID8gdmFsaWRMZW4gLSA0XG4gICAgOiB2YWxpZExlblxuXG4gIHZhciBpXG4gIGZvciAoaSA9IDA7IGkgPCBsZW47IGkgKz0gNCkge1xuICAgIHRtcCA9XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkpXSA8PCAxOCkgfFxuICAgICAgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpICsgMSldIDw8IDEyKSB8XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkgKyAyKV0gPDwgNikgfFxuICAgICAgcmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkgKyAzKV1cbiAgICBhcnJbY3VyQnl0ZSsrXSA9ICh0bXAgPj4gMTYpICYgMHhGRlxuICAgIGFycltjdXJCeXRlKytdID0gKHRtcCA+PiA4KSAmIDB4RkZcbiAgICBhcnJbY3VyQnl0ZSsrXSA9IHRtcCAmIDB4RkZcbiAgfVxuXG4gIGlmIChwbGFjZUhvbGRlcnNMZW4gPT09IDIpIHtcbiAgICB0bXAgPVxuICAgICAgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpKV0gPDwgMikgfFxuICAgICAgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpICsgMSldID4+IDQpXG4gICAgYXJyW2N1ckJ5dGUrK10gPSB0bXAgJiAweEZGXG4gIH1cblxuICBpZiAocGxhY2VIb2xkZXJzTGVuID09PSAxKSB7XG4gICAgdG1wID1cbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSldIDw8IDEwKSB8XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkgKyAxKV0gPDwgNCkgfFxuICAgICAgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpICsgMildID4+IDIpXG4gICAgYXJyW2N1ckJ5dGUrK10gPSAodG1wID4+IDgpICYgMHhGRlxuICAgIGFycltjdXJCeXRlKytdID0gdG1wICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIGFyclxufVxuXG5mdW5jdGlvbiB0cmlwbGV0VG9CYXNlNjQgKG51bSkge1xuICByZXR1cm4gbG9va3VwW251bSA+PiAxOCAmIDB4M0ZdICtcbiAgICBsb29rdXBbbnVtID4+IDEyICYgMHgzRl0gK1xuICAgIGxvb2t1cFtudW0gPj4gNiAmIDB4M0ZdICtcbiAgICBsb29rdXBbbnVtICYgMHgzRl1cbn1cblxuZnVuY3Rpb24gZW5jb2RlQ2h1bmsgKHVpbnQ4LCBzdGFydCwgZW5kKSB7XG4gIHZhciB0bXBcbiAgdmFyIG91dHB1dCA9IFtdXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgaSArPSAzKSB7XG4gICAgdG1wID1cbiAgICAgICgodWludDhbaV0gPDwgMTYpICYgMHhGRjAwMDApICtcbiAgICAgICgodWludDhbaSArIDFdIDw8IDgpICYgMHhGRjAwKSArXG4gICAgICAodWludDhbaSArIDJdICYgMHhGRilcbiAgICBvdXRwdXQucHVzaCh0cmlwbGV0VG9CYXNlNjQodG1wKSlcbiAgfVxuICByZXR1cm4gb3V0cHV0LmpvaW4oJycpXG59XG5cbmZ1bmN0aW9uIGZyb21CeXRlQXJyYXkgKHVpbnQ4KSB7XG4gIHZhciB0bXBcbiAgdmFyIGxlbiA9IHVpbnQ4Lmxlbmd0aFxuICB2YXIgZXh0cmFCeXRlcyA9IGxlbiAlIDMgLy8gaWYgd2UgaGF2ZSAxIGJ5dGUgbGVmdCwgcGFkIDIgYnl0ZXNcbiAgdmFyIHBhcnRzID0gW11cbiAgdmFyIG1heENodW5rTGVuZ3RoID0gMTYzODMgLy8gbXVzdCBiZSBtdWx0aXBsZSBvZiAzXG5cbiAgLy8gZ28gdGhyb3VnaCB0aGUgYXJyYXkgZXZlcnkgdGhyZWUgYnl0ZXMsIHdlJ2xsIGRlYWwgd2l0aCB0cmFpbGluZyBzdHVmZiBsYXRlclxuICBmb3IgKHZhciBpID0gMCwgbGVuMiA9IGxlbiAtIGV4dHJhQnl0ZXM7IGkgPCBsZW4yOyBpICs9IG1heENodW5rTGVuZ3RoKSB7XG4gICAgcGFydHMucHVzaChlbmNvZGVDaHVuayh1aW50OCwgaSwgKGkgKyBtYXhDaHVua0xlbmd0aCkgPiBsZW4yID8gbGVuMiA6IChpICsgbWF4Q2h1bmtMZW5ndGgpKSlcbiAgfVxuXG4gIC8vIHBhZCB0aGUgZW5kIHdpdGggemVyb3MsIGJ1dCBtYWtlIHN1cmUgdG8gbm90IGZvcmdldCB0aGUgZXh0cmEgYnl0ZXNcbiAgaWYgKGV4dHJhQnl0ZXMgPT09IDEpIHtcbiAgICB0bXAgPSB1aW50OFtsZW4gLSAxXVxuICAgIHBhcnRzLnB1c2goXG4gICAgICBsb29rdXBbdG1wID4+IDJdICtcbiAgICAgIGxvb2t1cFsodG1wIDw8IDQpICYgMHgzRl0gK1xuICAgICAgJz09J1xuICAgIClcbiAgfSBlbHNlIGlmIChleHRyYUJ5dGVzID09PSAyKSB7XG4gICAgdG1wID0gKHVpbnQ4W2xlbiAtIDJdIDw8IDgpICsgdWludDhbbGVuIC0gMV1cbiAgICBwYXJ0cy5wdXNoKFxuICAgICAgbG9va3VwW3RtcCA+PiAxMF0gK1xuICAgICAgbG9va3VwWyh0bXAgPj4gNCkgJiAweDNGXSArXG4gICAgICBsb29rdXBbKHRtcCA8PCAyKSAmIDB4M0ZdICtcbiAgICAgICc9J1xuICAgIClcbiAgfVxuXG4gIHJldHVybiBwYXJ0cy5qb2luKCcnKVxufVxuIiwiLyohXG4gKiBUaGUgYnVmZmVyIG1vZHVsZSBmcm9tIG5vZGUuanMsIGZvciB0aGUgYnJvd3Nlci5cbiAqXG4gKiBAYXV0aG9yICAgRmVyb3NzIEFib3VraGFkaWplaCA8aHR0cHM6Ly9mZXJvc3Mub3JnPlxuICogQGxpY2Vuc2UgIE1JVFxuICovXG4vKiBlc2xpbnQtZGlzYWJsZSBuby1wcm90byAqL1xuXG4ndXNlIHN0cmljdCdcblxudmFyIGJhc2U2NCA9IHJlcXVpcmUoJ2Jhc2U2NC1qcycpXG52YXIgaWVlZTc1NCA9IHJlcXVpcmUoJ2llZWU3NTQnKVxuXG5leHBvcnRzLkJ1ZmZlciA9IEJ1ZmZlclxuZXhwb3J0cy5TbG93QnVmZmVyID0gU2xvd0J1ZmZlclxuZXhwb3J0cy5JTlNQRUNUX01BWF9CWVRFUyA9IDUwXG5cbnZhciBLX01BWF9MRU5HVEggPSAweDdmZmZmZmZmXG5leHBvcnRzLmtNYXhMZW5ndGggPSBLX01BWF9MRU5HVEhcblxuLyoqXG4gKiBJZiBgQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlRgOlxuICogICA9PT0gdHJ1ZSAgICBVc2UgVWludDhBcnJheSBpbXBsZW1lbnRhdGlvbiAoZmFzdGVzdClcbiAqICAgPT09IGZhbHNlICAgUHJpbnQgd2FybmluZyBhbmQgcmVjb21tZW5kIHVzaW5nIGBidWZmZXJgIHY0Lnggd2hpY2ggaGFzIGFuIE9iamVjdFxuICogICAgICAgICAgICAgICBpbXBsZW1lbnRhdGlvbiAobW9zdCBjb21wYXRpYmxlLCBldmVuIElFNilcbiAqXG4gKiBCcm93c2VycyB0aGF0IHN1cHBvcnQgdHlwZWQgYXJyYXlzIGFyZSBJRSAxMCssIEZpcmVmb3ggNCssIENocm9tZSA3KywgU2FmYXJpIDUuMSssXG4gKiBPcGVyYSAxMS42KywgaU9TIDQuMisuXG4gKlxuICogV2UgcmVwb3J0IHRoYXQgdGhlIGJyb3dzZXIgZG9lcyBub3Qgc3VwcG9ydCB0eXBlZCBhcnJheXMgaWYgdGhlIGFyZSBub3Qgc3ViY2xhc3NhYmxlXG4gKiB1c2luZyBfX3Byb3RvX18uIEZpcmVmb3ggNC0yOSBsYWNrcyBzdXBwb3J0IGZvciBhZGRpbmcgbmV3IHByb3BlcnRpZXMgdG8gYFVpbnQ4QXJyYXlgXG4gKiAoU2VlOiBodHRwczovL2J1Z3ppbGxhLm1vemlsbGEub3JnL3Nob3dfYnVnLmNnaT9pZD02OTU0MzgpLiBJRSAxMCBsYWNrcyBzdXBwb3J0XG4gKiBmb3IgX19wcm90b19fIGFuZCBoYXMgYSBidWdneSB0eXBlZCBhcnJheSBpbXBsZW1lbnRhdGlvbi5cbiAqL1xuQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQgPSB0eXBlZEFycmF5U3VwcG9ydCgpXG5cbmlmICghQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQgJiYgdHlwZW9mIGNvbnNvbGUgIT09ICd1bmRlZmluZWQnICYmXG4gICAgdHlwZW9mIGNvbnNvbGUuZXJyb3IgPT09ICdmdW5jdGlvbicpIHtcbiAgY29uc29sZS5lcnJvcihcbiAgICAnVGhpcyBicm93c2VyIGxhY2tzIHR5cGVkIGFycmF5IChVaW50OEFycmF5KSBzdXBwb3J0IHdoaWNoIGlzIHJlcXVpcmVkIGJ5ICcgK1xuICAgICdgYnVmZmVyYCB2NS54LiBVc2UgYGJ1ZmZlcmAgdjQueCBpZiB5b3UgcmVxdWlyZSBvbGQgYnJvd3NlciBzdXBwb3J0LidcbiAgKVxufVxuXG5mdW5jdGlvbiB0eXBlZEFycmF5U3VwcG9ydCAoKSB7XG4gIC8vIENhbiB0eXBlZCBhcnJheSBpbnN0YW5jZXMgY2FuIGJlIGF1Z21lbnRlZD9cbiAgdHJ5IHtcbiAgICB2YXIgYXJyID0gbmV3IFVpbnQ4QXJyYXkoMSlcbiAgICBhcnIuX19wcm90b19fID0geyBfX3Byb3RvX186IFVpbnQ4QXJyYXkucHJvdG90eXBlLCBmb286IGZ1bmN0aW9uICgpIHsgcmV0dXJuIDQyIH0gfVxuICAgIHJldHVybiBhcnIuZm9vKCkgPT09IDQyXG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxufVxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoQnVmZmVyLnByb3RvdHlwZSwgJ3BhcmVudCcsIHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKCFCdWZmZXIuaXNCdWZmZXIodGhpcykpIHJldHVybiB1bmRlZmluZWRcbiAgICByZXR1cm4gdGhpcy5idWZmZXJcbiAgfVxufSlcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KEJ1ZmZlci5wcm90b3R5cGUsICdvZmZzZXQnLCB7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIGlmICghQnVmZmVyLmlzQnVmZmVyKHRoaXMpKSByZXR1cm4gdW5kZWZpbmVkXG4gICAgcmV0dXJuIHRoaXMuYnl0ZU9mZnNldFxuICB9XG59KVxuXG5mdW5jdGlvbiBjcmVhdGVCdWZmZXIgKGxlbmd0aCkge1xuICBpZiAobGVuZ3RoID4gS19NQVhfTEVOR1RIKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1RoZSB2YWx1ZSBcIicgKyBsZW5ndGggKyAnXCIgaXMgaW52YWxpZCBmb3Igb3B0aW9uIFwic2l6ZVwiJylcbiAgfVxuICAvLyBSZXR1cm4gYW4gYXVnbWVudGVkIGBVaW50OEFycmF5YCBpbnN0YW5jZVxuICB2YXIgYnVmID0gbmV3IFVpbnQ4QXJyYXkobGVuZ3RoKVxuICBidWYuX19wcm90b19fID0gQnVmZmVyLnByb3RvdHlwZVxuICByZXR1cm4gYnVmXG59XG5cbi8qKlxuICogVGhlIEJ1ZmZlciBjb25zdHJ1Y3RvciByZXR1cm5zIGluc3RhbmNlcyBvZiBgVWludDhBcnJheWAgdGhhdCBoYXZlIHRoZWlyXG4gKiBwcm90b3R5cGUgY2hhbmdlZCB0byBgQnVmZmVyLnByb3RvdHlwZWAuIEZ1cnRoZXJtb3JlLCBgQnVmZmVyYCBpcyBhIHN1YmNsYXNzIG9mXG4gKiBgVWludDhBcnJheWAsIHNvIHRoZSByZXR1cm5lZCBpbnN0YW5jZXMgd2lsbCBoYXZlIGFsbCB0aGUgbm9kZSBgQnVmZmVyYCBtZXRob2RzXG4gKiBhbmQgdGhlIGBVaW50OEFycmF5YCBtZXRob2RzLiBTcXVhcmUgYnJhY2tldCBub3RhdGlvbiB3b3JrcyBhcyBleHBlY3RlZCAtLSBpdFxuICogcmV0dXJucyBhIHNpbmdsZSBvY3RldC5cbiAqXG4gKiBUaGUgYFVpbnQ4QXJyYXlgIHByb3RvdHlwZSByZW1haW5zIHVubW9kaWZpZWQuXG4gKi9cblxuZnVuY3Rpb24gQnVmZmVyIChhcmcsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aCkge1xuICAvLyBDb21tb24gY2FzZS5cbiAgaWYgKHR5cGVvZiBhcmcgPT09ICdudW1iZXInKSB7XG4gICAgaWYgKHR5cGVvZiBlbmNvZGluZ09yT2Zmc2V0ID09PSAnc3RyaW5nJykge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgICAgJ1RoZSBcInN0cmluZ1wiIGFyZ3VtZW50IG11c3QgYmUgb2YgdHlwZSBzdHJpbmcuIFJlY2VpdmVkIHR5cGUgbnVtYmVyJ1xuICAgICAgKVxuICAgIH1cbiAgICByZXR1cm4gYWxsb2NVbnNhZmUoYXJnKVxuICB9XG4gIHJldHVybiBmcm9tKGFyZywgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKVxufVxuXG4vLyBGaXggc3ViYXJyYXkoKSBpbiBFUzIwMTYuIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL2Zlcm9zcy9idWZmZXIvcHVsbC85N1xuaWYgKHR5cGVvZiBTeW1ib2wgIT09ICd1bmRlZmluZWQnICYmIFN5bWJvbC5zcGVjaWVzICE9IG51bGwgJiZcbiAgICBCdWZmZXJbU3ltYm9sLnNwZWNpZXNdID09PSBCdWZmZXIpIHtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEJ1ZmZlciwgU3ltYm9sLnNwZWNpZXMsIHtcbiAgICB2YWx1ZTogbnVsbCxcbiAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgd3JpdGFibGU6IGZhbHNlXG4gIH0pXG59XG5cbkJ1ZmZlci5wb29sU2l6ZSA9IDgxOTIgLy8gbm90IHVzZWQgYnkgdGhpcyBpbXBsZW1lbnRhdGlvblxuXG5mdW5jdGlvbiBmcm9tICh2YWx1ZSwgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKSB7XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIGZyb21TdHJpbmcodmFsdWUsIGVuY29kaW5nT3JPZmZzZXQpXG4gIH1cblxuICBpZiAoQXJyYXlCdWZmZXIuaXNWaWV3KHZhbHVlKSkge1xuICAgIHJldHVybiBmcm9tQXJyYXlMaWtlKHZhbHVlKVxuICB9XG5cbiAgaWYgKHZhbHVlID09IG51bGwpIHtcbiAgICB0aHJvdyBUeXBlRXJyb3IoXG4gICAgICAnVGhlIGZpcnN0IGFyZ3VtZW50IG11c3QgYmUgb25lIG9mIHR5cGUgc3RyaW5nLCBCdWZmZXIsIEFycmF5QnVmZmVyLCBBcnJheSwgJyArXG4gICAgICAnb3IgQXJyYXktbGlrZSBPYmplY3QuIFJlY2VpdmVkIHR5cGUgJyArICh0eXBlb2YgdmFsdWUpXG4gICAgKVxuICB9XG5cbiAgaWYgKGlzSW5zdGFuY2UodmFsdWUsIEFycmF5QnVmZmVyKSB8fFxuICAgICAgKHZhbHVlICYmIGlzSW5zdGFuY2UodmFsdWUuYnVmZmVyLCBBcnJheUJ1ZmZlcikpKSB7XG4gICAgcmV0dXJuIGZyb21BcnJheUJ1ZmZlcih2YWx1ZSwgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKVxuICB9XG5cbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgJ1RoZSBcInZhbHVlXCIgYXJndW1lbnQgbXVzdCBub3QgYmUgb2YgdHlwZSBudW1iZXIuIFJlY2VpdmVkIHR5cGUgbnVtYmVyJ1xuICAgIClcbiAgfVxuXG4gIHZhciB2YWx1ZU9mID0gdmFsdWUudmFsdWVPZiAmJiB2YWx1ZS52YWx1ZU9mKClcbiAgaWYgKHZhbHVlT2YgIT0gbnVsbCAmJiB2YWx1ZU9mICE9PSB2YWx1ZSkge1xuICAgIHJldHVybiBCdWZmZXIuZnJvbSh2YWx1ZU9mLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpXG4gIH1cblxuICB2YXIgYiA9IGZyb21PYmplY3QodmFsdWUpXG4gIGlmIChiKSByZXR1cm4gYlxuXG4gIGlmICh0eXBlb2YgU3ltYm9sICE9PSAndW5kZWZpbmVkJyAmJiBTeW1ib2wudG9QcmltaXRpdmUgIT0gbnVsbCAmJlxuICAgICAgdHlwZW9mIHZhbHVlW1N5bWJvbC50b1ByaW1pdGl2ZV0gPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gQnVmZmVyLmZyb20oXG4gICAgICB2YWx1ZVtTeW1ib2wudG9QcmltaXRpdmVdKCdzdHJpbmcnKSwgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoXG4gICAgKVxuICB9XG5cbiAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAnVGhlIGZpcnN0IGFyZ3VtZW50IG11c3QgYmUgb25lIG9mIHR5cGUgc3RyaW5nLCBCdWZmZXIsIEFycmF5QnVmZmVyLCBBcnJheSwgJyArXG4gICAgJ29yIEFycmF5LWxpa2UgT2JqZWN0LiBSZWNlaXZlZCB0eXBlICcgKyAodHlwZW9mIHZhbHVlKVxuICApXG59XG5cbi8qKlxuICogRnVuY3Rpb25hbGx5IGVxdWl2YWxlbnQgdG8gQnVmZmVyKGFyZywgZW5jb2RpbmcpIGJ1dCB0aHJvd3MgYSBUeXBlRXJyb3JcbiAqIGlmIHZhbHVlIGlzIGEgbnVtYmVyLlxuICogQnVmZmVyLmZyb20oc3RyWywgZW5jb2RpbmddKVxuICogQnVmZmVyLmZyb20oYXJyYXkpXG4gKiBCdWZmZXIuZnJvbShidWZmZXIpXG4gKiBCdWZmZXIuZnJvbShhcnJheUJ1ZmZlclssIGJ5dGVPZmZzZXRbLCBsZW5ndGhdXSlcbiAqKi9cbkJ1ZmZlci5mcm9tID0gZnVuY3Rpb24gKHZhbHVlLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGZyb20odmFsdWUsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aClcbn1cblxuLy8gTm90ZTogQ2hhbmdlIHByb3RvdHlwZSAqYWZ0ZXIqIEJ1ZmZlci5mcm9tIGlzIGRlZmluZWQgdG8gd29ya2Fyb3VuZCBDaHJvbWUgYnVnOlxuLy8gaHR0cHM6Ly9naXRodWIuY29tL2Zlcm9zcy9idWZmZXIvcHVsbC8xNDhcbkJ1ZmZlci5wcm90b3R5cGUuX19wcm90b19fID0gVWludDhBcnJheS5wcm90b3R5cGVcbkJ1ZmZlci5fX3Byb3RvX18gPSBVaW50OEFycmF5XG5cbmZ1bmN0aW9uIGFzc2VydFNpemUgKHNpemUpIHtcbiAgaWYgKHR5cGVvZiBzaXplICE9PSAnbnVtYmVyJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wic2l6ZVwiIGFyZ3VtZW50IG11c3QgYmUgb2YgdHlwZSBudW1iZXInKVxuICB9IGVsc2UgaWYgKHNpemUgPCAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1RoZSB2YWx1ZSBcIicgKyBzaXplICsgJ1wiIGlzIGludmFsaWQgZm9yIG9wdGlvbiBcInNpemVcIicpXG4gIH1cbn1cblxuZnVuY3Rpb24gYWxsb2MgKHNpemUsIGZpbGwsIGVuY29kaW5nKSB7XG4gIGFzc2VydFNpemUoc2l6ZSlcbiAgaWYgKHNpemUgPD0gMCkge1xuICAgIHJldHVybiBjcmVhdGVCdWZmZXIoc2l6ZSlcbiAgfVxuICBpZiAoZmlsbCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgLy8gT25seSBwYXkgYXR0ZW50aW9uIHRvIGVuY29kaW5nIGlmIGl0J3MgYSBzdHJpbmcuIFRoaXNcbiAgICAvLyBwcmV2ZW50cyBhY2NpZGVudGFsbHkgc2VuZGluZyBpbiBhIG51bWJlciB0aGF0IHdvdWxkXG4gICAgLy8gYmUgaW50ZXJwcmV0dGVkIGFzIGEgc3RhcnQgb2Zmc2V0LlxuICAgIHJldHVybiB0eXBlb2YgZW5jb2RpbmcgPT09ICdzdHJpbmcnXG4gICAgICA/IGNyZWF0ZUJ1ZmZlcihzaXplKS5maWxsKGZpbGwsIGVuY29kaW5nKVxuICAgICAgOiBjcmVhdGVCdWZmZXIoc2l6ZSkuZmlsbChmaWxsKVxuICB9XG4gIHJldHVybiBjcmVhdGVCdWZmZXIoc2l6ZSlcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IGZpbGxlZCBCdWZmZXIgaW5zdGFuY2UuXG4gKiBhbGxvYyhzaXplWywgZmlsbFssIGVuY29kaW5nXV0pXG4gKiovXG5CdWZmZXIuYWxsb2MgPSBmdW5jdGlvbiAoc2l6ZSwgZmlsbCwgZW5jb2RpbmcpIHtcbiAgcmV0dXJuIGFsbG9jKHNpemUsIGZpbGwsIGVuY29kaW5nKVxufVxuXG5mdW5jdGlvbiBhbGxvY1Vuc2FmZSAoc2l6ZSkge1xuICBhc3NlcnRTaXplKHNpemUpXG4gIHJldHVybiBjcmVhdGVCdWZmZXIoc2l6ZSA8IDAgPyAwIDogY2hlY2tlZChzaXplKSB8IDApXG59XG5cbi8qKlxuICogRXF1aXZhbGVudCB0byBCdWZmZXIobnVtKSwgYnkgZGVmYXVsdCBjcmVhdGVzIGEgbm9uLXplcm8tZmlsbGVkIEJ1ZmZlciBpbnN0YW5jZS5cbiAqICovXG5CdWZmZXIuYWxsb2NVbnNhZmUgPSBmdW5jdGlvbiAoc2l6ZSkge1xuICByZXR1cm4gYWxsb2NVbnNhZmUoc2l6ZSlcbn1cbi8qKlxuICogRXF1aXZhbGVudCB0byBTbG93QnVmZmVyKG51bSksIGJ5IGRlZmF1bHQgY3JlYXRlcyBhIG5vbi16ZXJvLWZpbGxlZCBCdWZmZXIgaW5zdGFuY2UuXG4gKi9cbkJ1ZmZlci5hbGxvY1Vuc2FmZVNsb3cgPSBmdW5jdGlvbiAoc2l6ZSkge1xuICByZXR1cm4gYWxsb2NVbnNhZmUoc2l6ZSlcbn1cblxuZnVuY3Rpb24gZnJvbVN0cmluZyAoc3RyaW5nLCBlbmNvZGluZykge1xuICBpZiAodHlwZW9mIGVuY29kaW5nICE9PSAnc3RyaW5nJyB8fCBlbmNvZGluZyA9PT0gJycpIHtcbiAgICBlbmNvZGluZyA9ICd1dGY4J1xuICB9XG5cbiAgaWYgKCFCdWZmZXIuaXNFbmNvZGluZyhlbmNvZGluZykpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpXG4gIH1cblxuICB2YXIgbGVuZ3RoID0gYnl0ZUxlbmd0aChzdHJpbmcsIGVuY29kaW5nKSB8IDBcbiAgdmFyIGJ1ZiA9IGNyZWF0ZUJ1ZmZlcihsZW5ndGgpXG5cbiAgdmFyIGFjdHVhbCA9IGJ1Zi53cml0ZShzdHJpbmcsIGVuY29kaW5nKVxuXG4gIGlmIChhY3R1YWwgIT09IGxlbmd0aCkge1xuICAgIC8vIFdyaXRpbmcgYSBoZXggc3RyaW5nLCBmb3IgZXhhbXBsZSwgdGhhdCBjb250YWlucyBpbnZhbGlkIGNoYXJhY3RlcnMgd2lsbFxuICAgIC8vIGNhdXNlIGV2ZXJ5dGhpbmcgYWZ0ZXIgdGhlIGZpcnN0IGludmFsaWQgY2hhcmFjdGVyIHRvIGJlIGlnbm9yZWQuIChlLmcuXG4gICAgLy8gJ2FieHhjZCcgd2lsbCBiZSB0cmVhdGVkIGFzICdhYicpXG4gICAgYnVmID0gYnVmLnNsaWNlKDAsIGFjdHVhbClcbiAgfVxuXG4gIHJldHVybiBidWZcbn1cblxuZnVuY3Rpb24gZnJvbUFycmF5TGlrZSAoYXJyYXkpIHtcbiAgdmFyIGxlbmd0aCA9IGFycmF5Lmxlbmd0aCA8IDAgPyAwIDogY2hlY2tlZChhcnJheS5sZW5ndGgpIHwgMFxuICB2YXIgYnVmID0gY3JlYXRlQnVmZmVyKGxlbmd0aClcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gMSkge1xuICAgIGJ1ZltpXSA9IGFycmF5W2ldICYgMjU1XG4gIH1cbiAgcmV0dXJuIGJ1ZlxufVxuXG5mdW5jdGlvbiBmcm9tQXJyYXlCdWZmZXIgKGFycmF5LCBieXRlT2Zmc2V0LCBsZW5ndGgpIHtcbiAgaWYgKGJ5dGVPZmZzZXQgPCAwIHx8IGFycmF5LmJ5dGVMZW5ndGggPCBieXRlT2Zmc2V0KSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1wib2Zmc2V0XCIgaXMgb3V0c2lkZSBvZiBidWZmZXIgYm91bmRzJylcbiAgfVxuXG4gIGlmIChhcnJheS5ieXRlTGVuZ3RoIDwgYnl0ZU9mZnNldCArIChsZW5ndGggfHwgMCkpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignXCJsZW5ndGhcIiBpcyBvdXRzaWRlIG9mIGJ1ZmZlciBib3VuZHMnKVxuICB9XG5cbiAgdmFyIGJ1ZlxuICBpZiAoYnl0ZU9mZnNldCA9PT0gdW5kZWZpbmVkICYmIGxlbmd0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgYnVmID0gbmV3IFVpbnQ4QXJyYXkoYXJyYXkpXG4gIH0gZWxzZSBpZiAobGVuZ3RoID09PSB1bmRlZmluZWQpIHtcbiAgICBidWYgPSBuZXcgVWludDhBcnJheShhcnJheSwgYnl0ZU9mZnNldClcbiAgfSBlbHNlIHtcbiAgICBidWYgPSBuZXcgVWludDhBcnJheShhcnJheSwgYnl0ZU9mZnNldCwgbGVuZ3RoKVxuICB9XG5cbiAgLy8gUmV0dXJuIGFuIGF1Z21lbnRlZCBgVWludDhBcnJheWAgaW5zdGFuY2VcbiAgYnVmLl9fcHJvdG9fXyA9IEJ1ZmZlci5wcm90b3R5cGVcbiAgcmV0dXJuIGJ1ZlxufVxuXG5mdW5jdGlvbiBmcm9tT2JqZWN0IChvYmopIHtcbiAgaWYgKEJ1ZmZlci5pc0J1ZmZlcihvYmopKSB7XG4gICAgdmFyIGxlbiA9IGNoZWNrZWQob2JqLmxlbmd0aCkgfCAwXG4gICAgdmFyIGJ1ZiA9IGNyZWF0ZUJ1ZmZlcihsZW4pXG5cbiAgICBpZiAoYnVmLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIGJ1ZlxuICAgIH1cblxuICAgIG9iai5jb3B5KGJ1ZiwgMCwgMCwgbGVuKVxuICAgIHJldHVybiBidWZcbiAgfVxuXG4gIGlmIChvYmoubGVuZ3RoICE9PSB1bmRlZmluZWQpIHtcbiAgICBpZiAodHlwZW9mIG9iai5sZW5ndGggIT09ICdudW1iZXInIHx8IG51bWJlcklzTmFOKG9iai5sZW5ndGgpKSB7XG4gICAgICByZXR1cm4gY3JlYXRlQnVmZmVyKDApXG4gICAgfVxuICAgIHJldHVybiBmcm9tQXJyYXlMaWtlKG9iailcbiAgfVxuXG4gIGlmIChvYmoudHlwZSA9PT0gJ0J1ZmZlcicgJiYgQXJyYXkuaXNBcnJheShvYmouZGF0YSkpIHtcbiAgICByZXR1cm4gZnJvbUFycmF5TGlrZShvYmouZGF0YSlcbiAgfVxufVxuXG5mdW5jdGlvbiBjaGVja2VkIChsZW5ndGgpIHtcbiAgLy8gTm90ZTogY2Fubm90IHVzZSBgbGVuZ3RoIDwgS19NQVhfTEVOR1RIYCBoZXJlIGJlY2F1c2UgdGhhdCBmYWlscyB3aGVuXG4gIC8vIGxlbmd0aCBpcyBOYU4gKHdoaWNoIGlzIG90aGVyd2lzZSBjb2VyY2VkIHRvIHplcm8uKVxuICBpZiAobGVuZ3RoID49IEtfTUFYX0xFTkdUSCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdBdHRlbXB0IHRvIGFsbG9jYXRlIEJ1ZmZlciBsYXJnZXIgdGhhbiBtYXhpbXVtICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICdzaXplOiAweCcgKyBLX01BWF9MRU5HVEgudG9TdHJpbmcoMTYpICsgJyBieXRlcycpXG4gIH1cbiAgcmV0dXJuIGxlbmd0aCB8IDBcbn1cblxuZnVuY3Rpb24gU2xvd0J1ZmZlciAobGVuZ3RoKSB7XG4gIGlmICgrbGVuZ3RoICE9IGxlbmd0aCkgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIGVxZXFlcVxuICAgIGxlbmd0aCA9IDBcbiAgfVxuICByZXR1cm4gQnVmZmVyLmFsbG9jKCtsZW5ndGgpXG59XG5cbkJ1ZmZlci5pc0J1ZmZlciA9IGZ1bmN0aW9uIGlzQnVmZmVyIChiKSB7XG4gIHJldHVybiBiICE9IG51bGwgJiYgYi5faXNCdWZmZXIgPT09IHRydWUgJiZcbiAgICBiICE9PSBCdWZmZXIucHJvdG90eXBlIC8vIHNvIEJ1ZmZlci5pc0J1ZmZlcihCdWZmZXIucHJvdG90eXBlKSB3aWxsIGJlIGZhbHNlXG59XG5cbkJ1ZmZlci5jb21wYXJlID0gZnVuY3Rpb24gY29tcGFyZSAoYSwgYikge1xuICBpZiAoaXNJbnN0YW5jZShhLCBVaW50OEFycmF5KSkgYSA9IEJ1ZmZlci5mcm9tKGEsIGEub2Zmc2V0LCBhLmJ5dGVMZW5ndGgpXG4gIGlmIChpc0luc3RhbmNlKGIsIFVpbnQ4QXJyYXkpKSBiID0gQnVmZmVyLmZyb20oYiwgYi5vZmZzZXQsIGIuYnl0ZUxlbmd0aClcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYSkgfHwgIUJ1ZmZlci5pc0J1ZmZlcihiKSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICAnVGhlIFwiYnVmMVwiLCBcImJ1ZjJcIiBhcmd1bWVudHMgbXVzdCBiZSBvbmUgb2YgdHlwZSBCdWZmZXIgb3IgVWludDhBcnJheSdcbiAgICApXG4gIH1cblxuICBpZiAoYSA9PT0gYikgcmV0dXJuIDBcblxuICB2YXIgeCA9IGEubGVuZ3RoXG4gIHZhciB5ID0gYi5sZW5ndGhcblxuICBmb3IgKHZhciBpID0gMCwgbGVuID0gTWF0aC5taW4oeCwgeSk7IGkgPCBsZW47ICsraSkge1xuICAgIGlmIChhW2ldICE9PSBiW2ldKSB7XG4gICAgICB4ID0gYVtpXVxuICAgICAgeSA9IGJbaV1cbiAgICAgIGJyZWFrXG4gICAgfVxuICB9XG5cbiAgaWYgKHggPCB5KSByZXR1cm4gLTFcbiAgaWYgKHkgPCB4KSByZXR1cm4gMVxuICByZXR1cm4gMFxufVxuXG5CdWZmZXIuaXNFbmNvZGluZyA9IGZ1bmN0aW9uIGlzRW5jb2RpbmcgKGVuY29kaW5nKSB7XG4gIHN3aXRjaCAoU3RyaW5nKGVuY29kaW5nKS50b0xvd2VyQ2FzZSgpKSB7XG4gICAgY2FzZSAnaGV4JzpcbiAgICBjYXNlICd1dGY4JzpcbiAgICBjYXNlICd1dGYtOCc6XG4gICAgY2FzZSAnYXNjaWknOlxuICAgIGNhc2UgJ2xhdGluMSc6XG4gICAgY2FzZSAnYmluYXJ5JzpcbiAgICBjYXNlICdiYXNlNjQnOlxuICAgIGNhc2UgJ3VjczInOlxuICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICBjYXNlICd1dGYxNmxlJzpcbiAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICByZXR1cm4gdHJ1ZVxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gZmFsc2VcbiAgfVxufVxuXG5CdWZmZXIuY29uY2F0ID0gZnVuY3Rpb24gY29uY2F0IChsaXN0LCBsZW5ndGgpIHtcbiAgaWYgKCFBcnJheS5pc0FycmF5KGxpc3QpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJsaXN0XCIgYXJndW1lbnQgbXVzdCBiZSBhbiBBcnJheSBvZiBCdWZmZXJzJylcbiAgfVxuXG4gIGlmIChsaXN0Lmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBCdWZmZXIuYWxsb2MoMClcbiAgfVxuXG4gIHZhciBpXG4gIGlmIChsZW5ndGggPT09IHVuZGVmaW5lZCkge1xuICAgIGxlbmd0aCA9IDBcbiAgICBmb3IgKGkgPSAwOyBpIDwgbGlzdC5sZW5ndGg7ICsraSkge1xuICAgICAgbGVuZ3RoICs9IGxpc3RbaV0ubGVuZ3RoXG4gICAgfVxuICB9XG5cbiAgdmFyIGJ1ZmZlciA9IEJ1ZmZlci5hbGxvY1Vuc2FmZShsZW5ndGgpXG4gIHZhciBwb3MgPSAwXG4gIGZvciAoaSA9IDA7IGkgPCBsaXN0Lmxlbmd0aDsgKytpKSB7XG4gICAgdmFyIGJ1ZiA9IGxpc3RbaV1cbiAgICBpZiAoaXNJbnN0YW5jZShidWYsIFVpbnQ4QXJyYXkpKSB7XG4gICAgICBidWYgPSBCdWZmZXIuZnJvbShidWYpXG4gICAgfVxuICAgIGlmICghQnVmZmVyLmlzQnVmZmVyKGJ1ZikpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wibGlzdFwiIGFyZ3VtZW50IG11c3QgYmUgYW4gQXJyYXkgb2YgQnVmZmVycycpXG4gICAgfVxuICAgIGJ1Zi5jb3B5KGJ1ZmZlciwgcG9zKVxuICAgIHBvcyArPSBidWYubGVuZ3RoXG4gIH1cbiAgcmV0dXJuIGJ1ZmZlclxufVxuXG5mdW5jdGlvbiBieXRlTGVuZ3RoIChzdHJpbmcsIGVuY29kaW5nKSB7XG4gIGlmIChCdWZmZXIuaXNCdWZmZXIoc3RyaW5nKSkge1xuICAgIHJldHVybiBzdHJpbmcubGVuZ3RoXG4gIH1cbiAgaWYgKEFycmF5QnVmZmVyLmlzVmlldyhzdHJpbmcpIHx8IGlzSW5zdGFuY2Uoc3RyaW5nLCBBcnJheUJ1ZmZlcikpIHtcbiAgICByZXR1cm4gc3RyaW5nLmJ5dGVMZW5ndGhcbiAgfVxuICBpZiAodHlwZW9mIHN0cmluZyAhPT0gJ3N0cmluZycpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgJ1RoZSBcInN0cmluZ1wiIGFyZ3VtZW50IG11c3QgYmUgb25lIG9mIHR5cGUgc3RyaW5nLCBCdWZmZXIsIG9yIEFycmF5QnVmZmVyLiAnICtcbiAgICAgICdSZWNlaXZlZCB0eXBlICcgKyB0eXBlb2Ygc3RyaW5nXG4gICAgKVxuICB9XG5cbiAgdmFyIGxlbiA9IHN0cmluZy5sZW5ndGhcbiAgdmFyIG11c3RNYXRjaCA9IChhcmd1bWVudHMubGVuZ3RoID4gMiAmJiBhcmd1bWVudHNbMl0gPT09IHRydWUpXG4gIGlmICghbXVzdE1hdGNoICYmIGxlbiA9PT0gMCkgcmV0dXJuIDBcblxuICAvLyBVc2UgYSBmb3IgbG9vcCB0byBhdm9pZCByZWN1cnNpb25cbiAgdmFyIGxvd2VyZWRDYXNlID0gZmFsc2VcbiAgZm9yICg7Oykge1xuICAgIHN3aXRjaCAoZW5jb2RpbmcpIHtcbiAgICAgIGNhc2UgJ2FzY2lpJzpcbiAgICAgIGNhc2UgJ2xhdGluMSc6XG4gICAgICBjYXNlICdiaW5hcnknOlxuICAgICAgICByZXR1cm4gbGVuXG4gICAgICBjYXNlICd1dGY4JzpcbiAgICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgICAgcmV0dXJuIHV0ZjhUb0J5dGVzKHN0cmluZykubGVuZ3RoXG4gICAgICBjYXNlICd1Y3MyJzpcbiAgICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgICByZXR1cm4gbGVuICogMlxuICAgICAgY2FzZSAnaGV4JzpcbiAgICAgICAgcmV0dXJuIGxlbiA+Pj4gMVxuICAgICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgICAgcmV0dXJuIGJhc2U2NFRvQnl0ZXMoc3RyaW5nKS5sZW5ndGhcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmIChsb3dlcmVkQ2FzZSkge1xuICAgICAgICAgIHJldHVybiBtdXN0TWF0Y2ggPyAtMSA6IHV0ZjhUb0J5dGVzKHN0cmluZykubGVuZ3RoIC8vIGFzc3VtZSB1dGY4XG4gICAgICAgIH1cbiAgICAgICAgZW5jb2RpbmcgPSAoJycgKyBlbmNvZGluZykudG9Mb3dlckNhc2UoKVxuICAgICAgICBsb3dlcmVkQ2FzZSA9IHRydWVcbiAgICB9XG4gIH1cbn1cbkJ1ZmZlci5ieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aFxuXG5mdW5jdGlvbiBzbG93VG9TdHJpbmcgKGVuY29kaW5nLCBzdGFydCwgZW5kKSB7XG4gIHZhciBsb3dlcmVkQ2FzZSA9IGZhbHNlXG5cbiAgLy8gTm8gbmVlZCB0byB2ZXJpZnkgdGhhdCBcInRoaXMubGVuZ3RoIDw9IE1BWF9VSU5UMzJcIiBzaW5jZSBpdCdzIGEgcmVhZC1vbmx5XG4gIC8vIHByb3BlcnR5IG9mIGEgdHlwZWQgYXJyYXkuXG5cbiAgLy8gVGhpcyBiZWhhdmVzIG5laXRoZXIgbGlrZSBTdHJpbmcgbm9yIFVpbnQ4QXJyYXkgaW4gdGhhdCB3ZSBzZXQgc3RhcnQvZW5kXG4gIC8vIHRvIHRoZWlyIHVwcGVyL2xvd2VyIGJvdW5kcyBpZiB0aGUgdmFsdWUgcGFzc2VkIGlzIG91dCBvZiByYW5nZS5cbiAgLy8gdW5kZWZpbmVkIGlzIGhhbmRsZWQgc3BlY2lhbGx5IGFzIHBlciBFQ01BLTI2MiA2dGggRWRpdGlvbixcbiAgLy8gU2VjdGlvbiAxMy4zLjMuNyBSdW50aW1lIFNlbWFudGljczogS2V5ZWRCaW5kaW5nSW5pdGlhbGl6YXRpb24uXG4gIGlmIChzdGFydCA9PT0gdW5kZWZpbmVkIHx8IHN0YXJ0IDwgMCkge1xuICAgIHN0YXJ0ID0gMFxuICB9XG4gIC8vIFJldHVybiBlYXJseSBpZiBzdGFydCA+IHRoaXMubGVuZ3RoLiBEb25lIGhlcmUgdG8gcHJldmVudCBwb3RlbnRpYWwgdWludDMyXG4gIC8vIGNvZXJjaW9uIGZhaWwgYmVsb3cuXG4gIGlmIChzdGFydCA+IHRoaXMubGVuZ3RoKSB7XG4gICAgcmV0dXJuICcnXG4gIH1cblxuICBpZiAoZW5kID09PSB1bmRlZmluZWQgfHwgZW5kID4gdGhpcy5sZW5ndGgpIHtcbiAgICBlbmQgPSB0aGlzLmxlbmd0aFxuICB9XG5cbiAgaWYgKGVuZCA8PSAwKSB7XG4gICAgcmV0dXJuICcnXG4gIH1cblxuICAvLyBGb3JjZSBjb2Vyc2lvbiB0byB1aW50MzIuIFRoaXMgd2lsbCBhbHNvIGNvZXJjZSBmYWxzZXkvTmFOIHZhbHVlcyB0byAwLlxuICBlbmQgPj4+PSAwXG4gIHN0YXJ0ID4+Pj0gMFxuXG4gIGlmIChlbmQgPD0gc3RhcnQpIHtcbiAgICByZXR1cm4gJydcbiAgfVxuXG4gIGlmICghZW5jb2RpbmcpIGVuY29kaW5nID0gJ3V0ZjgnXG5cbiAgd2hpbGUgKHRydWUpIHtcbiAgICBzd2l0Y2ggKGVuY29kaW5nKSB7XG4gICAgICBjYXNlICdoZXgnOlxuICAgICAgICByZXR1cm4gaGV4U2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAndXRmOCc6XG4gICAgICBjYXNlICd1dGYtOCc6XG4gICAgICAgIHJldHVybiB1dGY4U2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAnYXNjaWknOlxuICAgICAgICByZXR1cm4gYXNjaWlTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICdsYXRpbjEnOlxuICAgICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgICAgcmV0dXJuIGxhdGluMVNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICAgIHJldHVybiBiYXNlNjRTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICd1Y3MyJzpcbiAgICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgICByZXR1cm4gdXRmMTZsZVNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmIChsb3dlcmVkQ2FzZSkgdGhyb3cgbmV3IFR5cGVFcnJvcignVW5rbm93biBlbmNvZGluZzogJyArIGVuY29kaW5nKVxuICAgICAgICBlbmNvZGluZyA9IChlbmNvZGluZyArICcnKS50b0xvd2VyQ2FzZSgpXG4gICAgICAgIGxvd2VyZWRDYXNlID0gdHJ1ZVxuICAgIH1cbiAgfVxufVxuXG4vLyBUaGlzIHByb3BlcnR5IGlzIHVzZWQgYnkgYEJ1ZmZlci5pc0J1ZmZlcmAgKGFuZCB0aGUgYGlzLWJ1ZmZlcmAgbnBtIHBhY2thZ2UpXG4vLyB0byBkZXRlY3QgYSBCdWZmZXIgaW5zdGFuY2UuIEl0J3Mgbm90IHBvc3NpYmxlIHRvIHVzZSBgaW5zdGFuY2VvZiBCdWZmZXJgXG4vLyByZWxpYWJseSBpbiBhIGJyb3dzZXJpZnkgY29udGV4dCBiZWNhdXNlIHRoZXJlIGNvdWxkIGJlIG11bHRpcGxlIGRpZmZlcmVudFxuLy8gY29waWVzIG9mIHRoZSAnYnVmZmVyJyBwYWNrYWdlIGluIHVzZS4gVGhpcyBtZXRob2Qgd29ya3MgZXZlbiBmb3IgQnVmZmVyXG4vLyBpbnN0YW5jZXMgdGhhdCB3ZXJlIGNyZWF0ZWQgZnJvbSBhbm90aGVyIGNvcHkgb2YgdGhlIGBidWZmZXJgIHBhY2thZ2UuXG4vLyBTZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9mZXJvc3MvYnVmZmVyL2lzc3Vlcy8xNTRcbkJ1ZmZlci5wcm90b3R5cGUuX2lzQnVmZmVyID0gdHJ1ZVxuXG5mdW5jdGlvbiBzd2FwIChiLCBuLCBtKSB7XG4gIHZhciBpID0gYltuXVxuICBiW25dID0gYlttXVxuICBiW21dID0gaVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnN3YXAxNiA9IGZ1bmN0aW9uIHN3YXAxNiAoKSB7XG4gIHZhciBsZW4gPSB0aGlzLmxlbmd0aFxuICBpZiAobGVuICUgMiAhPT0gMCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdCdWZmZXIgc2l6ZSBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgMTYtYml0cycpXG4gIH1cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkgKz0gMikge1xuICAgIHN3YXAodGhpcywgaSwgaSArIDEpXG4gIH1cbiAgcmV0dXJuIHRoaXNcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5zd2FwMzIgPSBmdW5jdGlvbiBzd2FwMzIgKCkge1xuICB2YXIgbGVuID0gdGhpcy5sZW5ndGhcbiAgaWYgKGxlbiAlIDQgIT09IDApIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignQnVmZmVyIHNpemUgbXVzdCBiZSBhIG11bHRpcGxlIG9mIDMyLWJpdHMnKVxuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpICs9IDQpIHtcbiAgICBzd2FwKHRoaXMsIGksIGkgKyAzKVxuICAgIHN3YXAodGhpcywgaSArIDEsIGkgKyAyKVxuICB9XG4gIHJldHVybiB0aGlzXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuc3dhcDY0ID0gZnVuY3Rpb24gc3dhcDY0ICgpIHtcbiAgdmFyIGxlbiA9IHRoaXMubGVuZ3RoXG4gIGlmIChsZW4gJSA4ICE9PSAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0J1ZmZlciBzaXplIG11c3QgYmUgYSBtdWx0aXBsZSBvZiA2NC1iaXRzJylcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSArPSA4KSB7XG4gICAgc3dhcCh0aGlzLCBpLCBpICsgNylcbiAgICBzd2FwKHRoaXMsIGkgKyAxLCBpICsgNilcbiAgICBzd2FwKHRoaXMsIGkgKyAyLCBpICsgNSlcbiAgICBzd2FwKHRoaXMsIGkgKyAzLCBpICsgNClcbiAgfVxuICByZXR1cm4gdGhpc1xufVxuXG5CdWZmZXIucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gdG9TdHJpbmcgKCkge1xuICB2YXIgbGVuZ3RoID0gdGhpcy5sZW5ndGhcbiAgaWYgKGxlbmd0aCA9PT0gMCkgcmV0dXJuICcnXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSByZXR1cm4gdXRmOFNsaWNlKHRoaXMsIDAsIGxlbmd0aClcbiAgcmV0dXJuIHNsb3dUb1N0cmluZy5hcHBseSh0aGlzLCBhcmd1bWVudHMpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUudG9Mb2NhbGVTdHJpbmcgPSBCdWZmZXIucHJvdG90eXBlLnRvU3RyaW5nXG5cbkJ1ZmZlci5wcm90b3R5cGUuZXF1YWxzID0gZnVuY3Rpb24gZXF1YWxzIChiKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudCBtdXN0IGJlIGEgQnVmZmVyJylcbiAgaWYgKHRoaXMgPT09IGIpIHJldHVybiB0cnVlXG4gIHJldHVybiBCdWZmZXIuY29tcGFyZSh0aGlzLCBiKSA9PT0gMFxufVxuXG5CdWZmZXIucHJvdG90eXBlLmluc3BlY3QgPSBmdW5jdGlvbiBpbnNwZWN0ICgpIHtcbiAgdmFyIHN0ciA9ICcnXG4gIHZhciBtYXggPSBleHBvcnRzLklOU1BFQ1RfTUFYX0JZVEVTXG4gIHN0ciA9IHRoaXMudG9TdHJpbmcoJ2hleCcsIDAsIG1heCkucmVwbGFjZSgvKC57Mn0pL2csICckMSAnKS50cmltKClcbiAgaWYgKHRoaXMubGVuZ3RoID4gbWF4KSBzdHIgKz0gJyAuLi4gJ1xuICByZXR1cm4gJzxCdWZmZXIgJyArIHN0ciArICc+J1xufVxuXG5CdWZmZXIucHJvdG90eXBlLmNvbXBhcmUgPSBmdW5jdGlvbiBjb21wYXJlICh0YXJnZXQsIHN0YXJ0LCBlbmQsIHRoaXNTdGFydCwgdGhpc0VuZCkge1xuICBpZiAoaXNJbnN0YW5jZSh0YXJnZXQsIFVpbnQ4QXJyYXkpKSB7XG4gICAgdGFyZ2V0ID0gQnVmZmVyLmZyb20odGFyZ2V0LCB0YXJnZXQub2Zmc2V0LCB0YXJnZXQuYnl0ZUxlbmd0aClcbiAgfVxuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcih0YXJnZXQpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgICdUaGUgXCJ0YXJnZXRcIiBhcmd1bWVudCBtdXN0IGJlIG9uZSBvZiB0eXBlIEJ1ZmZlciBvciBVaW50OEFycmF5LiAnICtcbiAgICAgICdSZWNlaXZlZCB0eXBlICcgKyAodHlwZW9mIHRhcmdldClcbiAgICApXG4gIH1cblxuICBpZiAoc3RhcnQgPT09IHVuZGVmaW5lZCkge1xuICAgIHN0YXJ0ID0gMFxuICB9XG4gIGlmIChlbmQgPT09IHVuZGVmaW5lZCkge1xuICAgIGVuZCA9IHRhcmdldCA/IHRhcmdldC5sZW5ndGggOiAwXG4gIH1cbiAgaWYgKHRoaXNTdGFydCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgdGhpc1N0YXJ0ID0gMFxuICB9XG4gIGlmICh0aGlzRW5kID09PSB1bmRlZmluZWQpIHtcbiAgICB0aGlzRW5kID0gdGhpcy5sZW5ndGhcbiAgfVxuXG4gIGlmIChzdGFydCA8IDAgfHwgZW5kID4gdGFyZ2V0Lmxlbmd0aCB8fCB0aGlzU3RhcnQgPCAwIHx8IHRoaXNFbmQgPiB0aGlzLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdvdXQgb2YgcmFuZ2UgaW5kZXgnKVxuICB9XG5cbiAgaWYgKHRoaXNTdGFydCA+PSB0aGlzRW5kICYmIHN0YXJ0ID49IGVuZCkge1xuICAgIHJldHVybiAwXG4gIH1cbiAgaWYgKHRoaXNTdGFydCA+PSB0aGlzRW5kKSB7XG4gICAgcmV0dXJuIC0xXG4gIH1cbiAgaWYgKHN0YXJ0ID49IGVuZCkge1xuICAgIHJldHVybiAxXG4gIH1cblxuICBzdGFydCA+Pj49IDBcbiAgZW5kID4+Pj0gMFxuICB0aGlzU3RhcnQgPj4+PSAwXG4gIHRoaXNFbmQgPj4+PSAwXG5cbiAgaWYgKHRoaXMgPT09IHRhcmdldCkgcmV0dXJuIDBcblxuICB2YXIgeCA9IHRoaXNFbmQgLSB0aGlzU3RhcnRcbiAgdmFyIHkgPSBlbmQgLSBzdGFydFxuICB2YXIgbGVuID0gTWF0aC5taW4oeCwgeSlcblxuICB2YXIgdGhpc0NvcHkgPSB0aGlzLnNsaWNlKHRoaXNTdGFydCwgdGhpc0VuZClcbiAgdmFyIHRhcmdldENvcHkgPSB0YXJnZXQuc2xpY2Uoc3RhcnQsIGVuZClcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKSB7XG4gICAgaWYgKHRoaXNDb3B5W2ldICE9PSB0YXJnZXRDb3B5W2ldKSB7XG4gICAgICB4ID0gdGhpc0NvcHlbaV1cbiAgICAgIHkgPSB0YXJnZXRDb3B5W2ldXG4gICAgICBicmVha1xuICAgIH1cbiAgfVxuXG4gIGlmICh4IDwgeSkgcmV0dXJuIC0xXG4gIGlmICh5IDwgeCkgcmV0dXJuIDFcbiAgcmV0dXJuIDBcbn1cblxuLy8gRmluZHMgZWl0aGVyIHRoZSBmaXJzdCBpbmRleCBvZiBgdmFsYCBpbiBgYnVmZmVyYCBhdCBvZmZzZXQgPj0gYGJ5dGVPZmZzZXRgLFxuLy8gT1IgdGhlIGxhc3QgaW5kZXggb2YgYHZhbGAgaW4gYGJ1ZmZlcmAgYXQgb2Zmc2V0IDw9IGBieXRlT2Zmc2V0YC5cbi8vXG4vLyBBcmd1bWVudHM6XG4vLyAtIGJ1ZmZlciAtIGEgQnVmZmVyIHRvIHNlYXJjaFxuLy8gLSB2YWwgLSBhIHN0cmluZywgQnVmZmVyLCBvciBudW1iZXJcbi8vIC0gYnl0ZU9mZnNldCAtIGFuIGluZGV4IGludG8gYGJ1ZmZlcmA7IHdpbGwgYmUgY2xhbXBlZCB0byBhbiBpbnQzMlxuLy8gLSBlbmNvZGluZyAtIGFuIG9wdGlvbmFsIGVuY29kaW5nLCByZWxldmFudCBpcyB2YWwgaXMgYSBzdHJpbmdcbi8vIC0gZGlyIC0gdHJ1ZSBmb3IgaW5kZXhPZiwgZmFsc2UgZm9yIGxhc3RJbmRleE9mXG5mdW5jdGlvbiBiaWRpcmVjdGlvbmFsSW5kZXhPZiAoYnVmZmVyLCB2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nLCBkaXIpIHtcbiAgLy8gRW1wdHkgYnVmZmVyIG1lYW5zIG5vIG1hdGNoXG4gIGlmIChidWZmZXIubGVuZ3RoID09PSAwKSByZXR1cm4gLTFcblxuICAvLyBOb3JtYWxpemUgYnl0ZU9mZnNldFxuICBpZiAodHlwZW9mIGJ5dGVPZmZzZXQgPT09ICdzdHJpbmcnKSB7XG4gICAgZW5jb2RpbmcgPSBieXRlT2Zmc2V0XG4gICAgYnl0ZU9mZnNldCA9IDBcbiAgfSBlbHNlIGlmIChieXRlT2Zmc2V0ID4gMHg3ZmZmZmZmZikge1xuICAgIGJ5dGVPZmZzZXQgPSAweDdmZmZmZmZmXG4gIH0gZWxzZSBpZiAoYnl0ZU9mZnNldCA8IC0weDgwMDAwMDAwKSB7XG4gICAgYnl0ZU9mZnNldCA9IC0weDgwMDAwMDAwXG4gIH1cbiAgYnl0ZU9mZnNldCA9ICtieXRlT2Zmc2V0IC8vIENvZXJjZSB0byBOdW1iZXIuXG4gIGlmIChudW1iZXJJc05hTihieXRlT2Zmc2V0KSkge1xuICAgIC8vIGJ5dGVPZmZzZXQ6IGl0IGl0J3MgdW5kZWZpbmVkLCBudWxsLCBOYU4sIFwiZm9vXCIsIGV0Yywgc2VhcmNoIHdob2xlIGJ1ZmZlclxuICAgIGJ5dGVPZmZzZXQgPSBkaXIgPyAwIDogKGJ1ZmZlci5sZW5ndGggLSAxKVxuICB9XG5cbiAgLy8gTm9ybWFsaXplIGJ5dGVPZmZzZXQ6IG5lZ2F0aXZlIG9mZnNldHMgc3RhcnQgZnJvbSB0aGUgZW5kIG9mIHRoZSBidWZmZXJcbiAgaWYgKGJ5dGVPZmZzZXQgPCAwKSBieXRlT2Zmc2V0ID0gYnVmZmVyLmxlbmd0aCArIGJ5dGVPZmZzZXRcbiAgaWYgKGJ5dGVPZmZzZXQgPj0gYnVmZmVyLmxlbmd0aCkge1xuICAgIGlmIChkaXIpIHJldHVybiAtMVxuICAgIGVsc2UgYnl0ZU9mZnNldCA9IGJ1ZmZlci5sZW5ndGggLSAxXG4gIH0gZWxzZSBpZiAoYnl0ZU9mZnNldCA8IDApIHtcbiAgICBpZiAoZGlyKSBieXRlT2Zmc2V0ID0gMFxuICAgIGVsc2UgcmV0dXJuIC0xXG4gIH1cblxuICAvLyBOb3JtYWxpemUgdmFsXG4gIGlmICh0eXBlb2YgdmFsID09PSAnc3RyaW5nJykge1xuICAgIHZhbCA9IEJ1ZmZlci5mcm9tKHZhbCwgZW5jb2RpbmcpXG4gIH1cblxuICAvLyBGaW5hbGx5LCBzZWFyY2ggZWl0aGVyIGluZGV4T2YgKGlmIGRpciBpcyB0cnVlKSBvciBsYXN0SW5kZXhPZlxuICBpZiAoQnVmZmVyLmlzQnVmZmVyKHZhbCkpIHtcbiAgICAvLyBTcGVjaWFsIGNhc2U6IGxvb2tpbmcgZm9yIGVtcHR5IHN0cmluZy9idWZmZXIgYWx3YXlzIGZhaWxzXG4gICAgaWYgKHZhbC5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiAtMVxuICAgIH1cbiAgICByZXR1cm4gYXJyYXlJbmRleE9mKGJ1ZmZlciwgdmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgZGlyKVxuICB9IGVsc2UgaWYgKHR5cGVvZiB2YWwgPT09ICdudW1iZXInKSB7XG4gICAgdmFsID0gdmFsICYgMHhGRiAvLyBTZWFyY2ggZm9yIGEgYnl0ZSB2YWx1ZSBbMC0yNTVdXG4gICAgaWYgKHR5cGVvZiBVaW50OEFycmF5LnByb3RvdHlwZS5pbmRleE9mID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBpZiAoZGlyKSB7XG4gICAgICAgIHJldHVybiBVaW50OEFycmF5LnByb3RvdHlwZS5pbmRleE9mLmNhbGwoYnVmZmVyLCB2YWwsIGJ5dGVPZmZzZXQpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gVWludDhBcnJheS5wcm90b3R5cGUubGFzdEluZGV4T2YuY2FsbChidWZmZXIsIHZhbCwgYnl0ZU9mZnNldClcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGFycmF5SW5kZXhPZihidWZmZXIsIFsgdmFsIF0sIGJ5dGVPZmZzZXQsIGVuY29kaW5nLCBkaXIpXG4gIH1cblxuICB0aHJvdyBuZXcgVHlwZUVycm9yKCd2YWwgbXVzdCBiZSBzdHJpbmcsIG51bWJlciBvciBCdWZmZXInKVxufVxuXG5mdW5jdGlvbiBhcnJheUluZGV4T2YgKGFyciwgdmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgZGlyKSB7XG4gIHZhciBpbmRleFNpemUgPSAxXG4gIHZhciBhcnJMZW5ndGggPSBhcnIubGVuZ3RoXG4gIHZhciB2YWxMZW5ndGggPSB2YWwubGVuZ3RoXG5cbiAgaWYgKGVuY29kaW5nICE9PSB1bmRlZmluZWQpIHtcbiAgICBlbmNvZGluZyA9IFN0cmluZyhlbmNvZGluZykudG9Mb3dlckNhc2UoKVxuICAgIGlmIChlbmNvZGluZyA9PT0gJ3VjczInIHx8IGVuY29kaW5nID09PSAndWNzLTInIHx8XG4gICAgICAgIGVuY29kaW5nID09PSAndXRmMTZsZScgfHwgZW5jb2RpbmcgPT09ICd1dGYtMTZsZScpIHtcbiAgICAgIGlmIChhcnIubGVuZ3RoIDwgMiB8fCB2YWwubGVuZ3RoIDwgMikge1xuICAgICAgICByZXR1cm4gLTFcbiAgICAgIH1cbiAgICAgIGluZGV4U2l6ZSA9IDJcbiAgICAgIGFyckxlbmd0aCAvPSAyXG4gICAgICB2YWxMZW5ndGggLz0gMlxuICAgICAgYnl0ZU9mZnNldCAvPSAyXG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gcmVhZCAoYnVmLCBpKSB7XG4gICAgaWYgKGluZGV4U2l6ZSA9PT0gMSkge1xuICAgICAgcmV0dXJuIGJ1ZltpXVxuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gYnVmLnJlYWRVSW50MTZCRShpICogaW5kZXhTaXplKVxuICAgIH1cbiAgfVxuXG4gIHZhciBpXG4gIGlmIChkaXIpIHtcbiAgICB2YXIgZm91bmRJbmRleCA9IC0xXG4gICAgZm9yIChpID0gYnl0ZU9mZnNldDsgaSA8IGFyckxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAocmVhZChhcnIsIGkpID09PSByZWFkKHZhbCwgZm91bmRJbmRleCA9PT0gLTEgPyAwIDogaSAtIGZvdW5kSW5kZXgpKSB7XG4gICAgICAgIGlmIChmb3VuZEluZGV4ID09PSAtMSkgZm91bmRJbmRleCA9IGlcbiAgICAgICAgaWYgKGkgLSBmb3VuZEluZGV4ICsgMSA9PT0gdmFsTGVuZ3RoKSByZXR1cm4gZm91bmRJbmRleCAqIGluZGV4U2l6ZVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGZvdW5kSW5kZXggIT09IC0xKSBpIC09IGkgLSBmb3VuZEluZGV4XG4gICAgICAgIGZvdW5kSW5kZXggPSAtMVxuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBpZiAoYnl0ZU9mZnNldCArIHZhbExlbmd0aCA+IGFyckxlbmd0aCkgYnl0ZU9mZnNldCA9IGFyckxlbmd0aCAtIHZhbExlbmd0aFxuICAgIGZvciAoaSA9IGJ5dGVPZmZzZXQ7IGkgPj0gMDsgaS0tKSB7XG4gICAgICB2YXIgZm91bmQgPSB0cnVlXG4gICAgICBmb3IgKHZhciBqID0gMDsgaiA8IHZhbExlbmd0aDsgaisrKSB7XG4gICAgICAgIGlmIChyZWFkKGFyciwgaSArIGopICE9PSByZWFkKHZhbCwgaikpIHtcbiAgICAgICAgICBmb3VuZCA9IGZhbHNlXG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGZvdW5kKSByZXR1cm4gaVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiAtMVxufVxuXG5CdWZmZXIucHJvdG90eXBlLmluY2x1ZGVzID0gZnVuY3Rpb24gaW5jbHVkZXMgKHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcpIHtcbiAgcmV0dXJuIHRoaXMuaW5kZXhPZih2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nKSAhPT0gLTFcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5pbmRleE9mID0gZnVuY3Rpb24gaW5kZXhPZiAodmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZykge1xuICByZXR1cm4gYmlkaXJlY3Rpb25hbEluZGV4T2YodGhpcywgdmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgdHJ1ZSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5sYXN0SW5kZXhPZiA9IGZ1bmN0aW9uIGxhc3RJbmRleE9mICh2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nKSB7XG4gIHJldHVybiBiaWRpcmVjdGlvbmFsSW5kZXhPZih0aGlzLCB2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nLCBmYWxzZSlcbn1cblxuZnVuY3Rpb24gaGV4V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICBvZmZzZXQgPSBOdW1iZXIob2Zmc2V0KSB8fCAwXG4gIHZhciByZW1haW5pbmcgPSBidWYubGVuZ3RoIC0gb2Zmc2V0XG4gIGlmICghbGVuZ3RoKSB7XG4gICAgbGVuZ3RoID0gcmVtYWluaW5nXG4gIH0gZWxzZSB7XG4gICAgbGVuZ3RoID0gTnVtYmVyKGxlbmd0aClcbiAgICBpZiAobGVuZ3RoID4gcmVtYWluaW5nKSB7XG4gICAgICBsZW5ndGggPSByZW1haW5pbmdcbiAgICB9XG4gIH1cblxuICB2YXIgc3RyTGVuID0gc3RyaW5nLmxlbmd0aFxuXG4gIGlmIChsZW5ndGggPiBzdHJMZW4gLyAyKSB7XG4gICAgbGVuZ3RoID0gc3RyTGVuIC8gMlxuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHtcbiAgICB2YXIgcGFyc2VkID0gcGFyc2VJbnQoc3RyaW5nLnN1YnN0cihpICogMiwgMiksIDE2KVxuICAgIGlmIChudW1iZXJJc05hTihwYXJzZWQpKSByZXR1cm4gaVxuICAgIGJ1ZltvZmZzZXQgKyBpXSA9IHBhcnNlZFxuICB9XG4gIHJldHVybiBpXG59XG5cbmZ1bmN0aW9uIHV0ZjhXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBibGl0QnVmZmVyKHV0ZjhUb0J5dGVzKHN0cmluZywgYnVmLmxlbmd0aCAtIG9mZnNldCksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIGFzY2lpV3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYmxpdEJ1ZmZlcihhc2NpaVRvQnl0ZXMoc3RyaW5nKSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gbGF0aW4xV3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYXNjaWlXcml0ZShidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIGJhc2U2NFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGJsaXRCdWZmZXIoYmFzZTY0VG9CeXRlcyhzdHJpbmcpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5mdW5jdGlvbiB1Y3MyV3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYmxpdEJ1ZmZlcih1dGYxNmxlVG9CeXRlcyhzdHJpbmcsIGJ1Zi5sZW5ndGggLSBvZmZzZXQpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24gd3JpdGUgKHN0cmluZywgb2Zmc2V0LCBsZW5ndGgsIGVuY29kaW5nKSB7XG4gIC8vIEJ1ZmZlciN3cml0ZShzdHJpbmcpXG4gIGlmIChvZmZzZXQgPT09IHVuZGVmaW5lZCkge1xuICAgIGVuY29kaW5nID0gJ3V0ZjgnXG4gICAgbGVuZ3RoID0gdGhpcy5sZW5ndGhcbiAgICBvZmZzZXQgPSAwXG4gIC8vIEJ1ZmZlciN3cml0ZShzdHJpbmcsIGVuY29kaW5nKVxuICB9IGVsc2UgaWYgKGxlbmd0aCA9PT0gdW5kZWZpbmVkICYmIHR5cGVvZiBvZmZzZXQgPT09ICdzdHJpbmcnKSB7XG4gICAgZW5jb2RpbmcgPSBvZmZzZXRcbiAgICBsZW5ndGggPSB0aGlzLmxlbmd0aFxuICAgIG9mZnNldCA9IDBcbiAgLy8gQnVmZmVyI3dyaXRlKHN0cmluZywgb2Zmc2V0WywgbGVuZ3RoXVssIGVuY29kaW5nXSlcbiAgfSBlbHNlIGlmIChpc0Zpbml0ZShvZmZzZXQpKSB7XG4gICAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gICAgaWYgKGlzRmluaXRlKGxlbmd0aCkpIHtcbiAgICAgIGxlbmd0aCA9IGxlbmd0aCA+Pj4gMFxuICAgICAgaWYgKGVuY29kaW5nID09PSB1bmRlZmluZWQpIGVuY29kaW5nID0gJ3V0ZjgnXG4gICAgfSBlbHNlIHtcbiAgICAgIGVuY29kaW5nID0gbGVuZ3RoXG4gICAgICBsZW5ndGggPSB1bmRlZmluZWRcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgJ0J1ZmZlci53cml0ZShzdHJpbmcsIGVuY29kaW5nLCBvZmZzZXRbLCBsZW5ndGhdKSBpcyBubyBsb25nZXIgc3VwcG9ydGVkJ1xuICAgIClcbiAgfVxuXG4gIHZhciByZW1haW5pbmcgPSB0aGlzLmxlbmd0aCAtIG9mZnNldFxuICBpZiAobGVuZ3RoID09PSB1bmRlZmluZWQgfHwgbGVuZ3RoID4gcmVtYWluaW5nKSBsZW5ndGggPSByZW1haW5pbmdcblxuICBpZiAoKHN0cmluZy5sZW5ndGggPiAwICYmIChsZW5ndGggPCAwIHx8IG9mZnNldCA8IDApKSB8fCBvZmZzZXQgPiB0aGlzLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdBdHRlbXB0IHRvIHdyaXRlIG91dHNpZGUgYnVmZmVyIGJvdW5kcycpXG4gIH1cblxuICBpZiAoIWVuY29kaW5nKSBlbmNvZGluZyA9ICd1dGY4J1xuXG4gIHZhciBsb3dlcmVkQ2FzZSA9IGZhbHNlXG4gIGZvciAoOzspIHtcbiAgICBzd2l0Y2ggKGVuY29kaW5nKSB7XG4gICAgICBjYXNlICdoZXgnOlxuICAgICAgICByZXR1cm4gaGV4V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAndXRmOCc6XG4gICAgICBjYXNlICd1dGYtOCc6XG4gICAgICAgIHJldHVybiB1dGY4V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAnYXNjaWknOlxuICAgICAgICByZXR1cm4gYXNjaWlXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICdsYXRpbjEnOlxuICAgICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgICAgcmV0dXJuIGxhdGluMVdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICAgIC8vIFdhcm5pbmc6IG1heExlbmd0aCBub3QgdGFrZW4gaW50byBhY2NvdW50IGluIGJhc2U2NFdyaXRlXG4gICAgICAgIHJldHVybiBiYXNlNjRXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICd1Y3MyJzpcbiAgICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgICByZXR1cm4gdWNzMldyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmIChsb3dlcmVkQ2FzZSkgdGhyb3cgbmV3IFR5cGVFcnJvcignVW5rbm93biBlbmNvZGluZzogJyArIGVuY29kaW5nKVxuICAgICAgICBlbmNvZGluZyA9ICgnJyArIGVuY29kaW5nKS50b0xvd2VyQ2FzZSgpXG4gICAgICAgIGxvd2VyZWRDYXNlID0gdHJ1ZVxuICAgIH1cbiAgfVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTiAoKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogJ0J1ZmZlcicsXG4gICAgZGF0YTogQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwodGhpcy5fYXJyIHx8IHRoaXMsIDApXG4gIH1cbn1cblxuZnVuY3Rpb24gYmFzZTY0U2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICBpZiAoc3RhcnQgPT09IDAgJiYgZW5kID09PSBidWYubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGJhc2U2NC5mcm9tQnl0ZUFycmF5KGJ1ZilcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gYmFzZTY0LmZyb21CeXRlQXJyYXkoYnVmLnNsaWNlKHN0YXJ0LCBlbmQpKVxuICB9XG59XG5cbmZ1bmN0aW9uIHV0ZjhTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIGVuZCA9IE1hdGgubWluKGJ1Zi5sZW5ndGgsIGVuZClcbiAgdmFyIHJlcyA9IFtdXG5cbiAgdmFyIGkgPSBzdGFydFxuICB3aGlsZSAoaSA8IGVuZCkge1xuICAgIHZhciBmaXJzdEJ5dGUgPSBidWZbaV1cbiAgICB2YXIgY29kZVBvaW50ID0gbnVsbFxuICAgIHZhciBieXRlc1BlclNlcXVlbmNlID0gKGZpcnN0Qnl0ZSA+IDB4RUYpID8gNFxuICAgICAgOiAoZmlyc3RCeXRlID4gMHhERikgPyAzXG4gICAgICAgIDogKGZpcnN0Qnl0ZSA+IDB4QkYpID8gMlxuICAgICAgICAgIDogMVxuXG4gICAgaWYgKGkgKyBieXRlc1BlclNlcXVlbmNlIDw9IGVuZCkge1xuICAgICAgdmFyIHNlY29uZEJ5dGUsIHRoaXJkQnl0ZSwgZm91cnRoQnl0ZSwgdGVtcENvZGVQb2ludFxuXG4gICAgICBzd2l0Y2ggKGJ5dGVzUGVyU2VxdWVuY2UpIHtcbiAgICAgICAgY2FzZSAxOlxuICAgICAgICAgIGlmIChmaXJzdEJ5dGUgPCAweDgwKSB7XG4gICAgICAgICAgICBjb2RlUG9pbnQgPSBmaXJzdEJ5dGVcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSAyOlxuICAgICAgICAgIHNlY29uZEJ5dGUgPSBidWZbaSArIDFdXG4gICAgICAgICAgaWYgKChzZWNvbmRCeXRlICYgMHhDMCkgPT09IDB4ODApIHtcbiAgICAgICAgICAgIHRlbXBDb2RlUG9pbnQgPSAoZmlyc3RCeXRlICYgMHgxRikgPDwgMHg2IHwgKHNlY29uZEJ5dGUgJiAweDNGKVxuICAgICAgICAgICAgaWYgKHRlbXBDb2RlUG9pbnQgPiAweDdGKSB7XG4gICAgICAgICAgICAgIGNvZGVQb2ludCA9IHRlbXBDb2RlUG9pbnRcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSAzOlxuICAgICAgICAgIHNlY29uZEJ5dGUgPSBidWZbaSArIDFdXG4gICAgICAgICAgdGhpcmRCeXRlID0gYnVmW2kgKyAyXVxuICAgICAgICAgIGlmICgoc2Vjb25kQnl0ZSAmIDB4QzApID09PSAweDgwICYmICh0aGlyZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCkge1xuICAgICAgICAgICAgdGVtcENvZGVQb2ludCA9IChmaXJzdEJ5dGUgJiAweEYpIDw8IDB4QyB8IChzZWNvbmRCeXRlICYgMHgzRikgPDwgMHg2IHwgKHRoaXJkQnl0ZSAmIDB4M0YpXG4gICAgICAgICAgICBpZiAodGVtcENvZGVQb2ludCA+IDB4N0ZGICYmICh0ZW1wQ29kZVBvaW50IDwgMHhEODAwIHx8IHRlbXBDb2RlUG9pbnQgPiAweERGRkYpKSB7XG4gICAgICAgICAgICAgIGNvZGVQb2ludCA9IHRlbXBDb2RlUG9pbnRcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSA0OlxuICAgICAgICAgIHNlY29uZEJ5dGUgPSBidWZbaSArIDFdXG4gICAgICAgICAgdGhpcmRCeXRlID0gYnVmW2kgKyAyXVxuICAgICAgICAgIGZvdXJ0aEJ5dGUgPSBidWZbaSArIDNdXG4gICAgICAgICAgaWYgKChzZWNvbmRCeXRlICYgMHhDMCkgPT09IDB4ODAgJiYgKHRoaXJkQnl0ZSAmIDB4QzApID09PSAweDgwICYmIChmb3VydGhCeXRlICYgMHhDMCkgPT09IDB4ODApIHtcbiAgICAgICAgICAgIHRlbXBDb2RlUG9pbnQgPSAoZmlyc3RCeXRlICYgMHhGKSA8PCAweDEyIHwgKHNlY29uZEJ5dGUgJiAweDNGKSA8PCAweEMgfCAodGhpcmRCeXRlICYgMHgzRikgPDwgMHg2IHwgKGZvdXJ0aEJ5dGUgJiAweDNGKVxuICAgICAgICAgICAgaWYgKHRlbXBDb2RlUG9pbnQgPiAweEZGRkYgJiYgdGVtcENvZGVQb2ludCA8IDB4MTEwMDAwKSB7XG4gICAgICAgICAgICAgIGNvZGVQb2ludCA9IHRlbXBDb2RlUG9pbnRcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGNvZGVQb2ludCA9PT0gbnVsbCkge1xuICAgICAgLy8gd2UgZGlkIG5vdCBnZW5lcmF0ZSBhIHZhbGlkIGNvZGVQb2ludCBzbyBpbnNlcnQgYVxuICAgICAgLy8gcmVwbGFjZW1lbnQgY2hhciAoVStGRkZEKSBhbmQgYWR2YW5jZSBvbmx5IDEgYnl0ZVxuICAgICAgY29kZVBvaW50ID0gMHhGRkZEXG4gICAgICBieXRlc1BlclNlcXVlbmNlID0gMVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50ID4gMHhGRkZGKSB7XG4gICAgICAvLyBlbmNvZGUgdG8gdXRmMTYgKHN1cnJvZ2F0ZSBwYWlyIGRhbmNlKVxuICAgICAgY29kZVBvaW50IC09IDB4MTAwMDBcbiAgICAgIHJlcy5wdXNoKGNvZGVQb2ludCA+Pj4gMTAgJiAweDNGRiB8IDB4RDgwMClcbiAgICAgIGNvZGVQb2ludCA9IDB4REMwMCB8IGNvZGVQb2ludCAmIDB4M0ZGXG4gICAgfVxuXG4gICAgcmVzLnB1c2goY29kZVBvaW50KVxuICAgIGkgKz0gYnl0ZXNQZXJTZXF1ZW5jZVxuICB9XG5cbiAgcmV0dXJuIGRlY29kZUNvZGVQb2ludHNBcnJheShyZXMpXG59XG5cbi8vIEJhc2VkIG9uIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9hLzIyNzQ3MjcyLzY4MDc0MiwgdGhlIGJyb3dzZXIgd2l0aFxuLy8gdGhlIGxvd2VzdCBsaW1pdCBpcyBDaHJvbWUsIHdpdGggMHgxMDAwMCBhcmdzLlxuLy8gV2UgZ28gMSBtYWduaXR1ZGUgbGVzcywgZm9yIHNhZmV0eVxudmFyIE1BWF9BUkdVTUVOVFNfTEVOR1RIID0gMHgxMDAwXG5cbmZ1bmN0aW9uIGRlY29kZUNvZGVQb2ludHNBcnJheSAoY29kZVBvaW50cykge1xuICB2YXIgbGVuID0gY29kZVBvaW50cy5sZW5ndGhcbiAgaWYgKGxlbiA8PSBNQVhfQVJHVU1FTlRTX0xFTkdUSCkge1xuICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KFN0cmluZywgY29kZVBvaW50cykgLy8gYXZvaWQgZXh0cmEgc2xpY2UoKVxuICB9XG5cbiAgLy8gRGVjb2RlIGluIGNodW5rcyB0byBhdm9pZCBcImNhbGwgc3RhY2sgc2l6ZSBleGNlZWRlZFwiLlxuICB2YXIgcmVzID0gJydcbiAgdmFyIGkgPSAwXG4gIHdoaWxlIChpIDwgbGVuKSB7XG4gICAgcmVzICs9IFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoXG4gICAgICBTdHJpbmcsXG4gICAgICBjb2RlUG9pbnRzLnNsaWNlKGksIGkgKz0gTUFYX0FSR1VNRU5UU19MRU5HVEgpXG4gICAgKVxuICB9XG4gIHJldHVybiByZXNcbn1cblxuZnVuY3Rpb24gYXNjaWlTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciByZXQgPSAnJ1xuICBlbmQgPSBNYXRoLm1pbihidWYubGVuZ3RoLCBlbmQpXG5cbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyArK2kpIHtcbiAgICByZXQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShidWZbaV0gJiAweDdGKVxuICB9XG4gIHJldHVybiByZXRcbn1cblxuZnVuY3Rpb24gbGF0aW4xU2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgcmV0ID0gJydcbiAgZW5kID0gTWF0aC5taW4oYnVmLmxlbmd0aCwgZW5kKVxuXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgKytpKSB7XG4gICAgcmV0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYnVmW2ldKVxuICB9XG4gIHJldHVybiByZXRcbn1cblxuZnVuY3Rpb24gaGV4U2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgbGVuID0gYnVmLmxlbmd0aFxuXG4gIGlmICghc3RhcnQgfHwgc3RhcnQgPCAwKSBzdGFydCA9IDBcbiAgaWYgKCFlbmQgfHwgZW5kIDwgMCB8fCBlbmQgPiBsZW4pIGVuZCA9IGxlblxuXG4gIHZhciBvdXQgPSAnJ1xuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7ICsraSkge1xuICAgIG91dCArPSB0b0hleChidWZbaV0pXG4gIH1cbiAgcmV0dXJuIG91dFxufVxuXG5mdW5jdGlvbiB1dGYxNmxlU2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgYnl0ZXMgPSBidWYuc2xpY2Uoc3RhcnQsIGVuZClcbiAgdmFyIHJlcyA9ICcnXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYnl0ZXMubGVuZ3RoOyBpICs9IDIpIHtcbiAgICByZXMgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShieXRlc1tpXSArIChieXRlc1tpICsgMV0gKiAyNTYpKVxuICB9XG4gIHJldHVybiByZXNcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5zbGljZSA9IGZ1bmN0aW9uIHNsaWNlIChzdGFydCwgZW5kKSB7XG4gIHZhciBsZW4gPSB0aGlzLmxlbmd0aFxuICBzdGFydCA9IH5+c3RhcnRcbiAgZW5kID0gZW5kID09PSB1bmRlZmluZWQgPyBsZW4gOiB+fmVuZFxuXG4gIGlmIChzdGFydCA8IDApIHtcbiAgICBzdGFydCArPSBsZW5cbiAgICBpZiAoc3RhcnQgPCAwKSBzdGFydCA9IDBcbiAgfSBlbHNlIGlmIChzdGFydCA+IGxlbikge1xuICAgIHN0YXJ0ID0gbGVuXG4gIH1cblxuICBpZiAoZW5kIDwgMCkge1xuICAgIGVuZCArPSBsZW5cbiAgICBpZiAoZW5kIDwgMCkgZW5kID0gMFxuICB9IGVsc2UgaWYgKGVuZCA+IGxlbikge1xuICAgIGVuZCA9IGxlblxuICB9XG5cbiAgaWYgKGVuZCA8IHN0YXJ0KSBlbmQgPSBzdGFydFxuXG4gIHZhciBuZXdCdWYgPSB0aGlzLnN1YmFycmF5KHN0YXJ0LCBlbmQpXG4gIC8vIFJldHVybiBhbiBhdWdtZW50ZWQgYFVpbnQ4QXJyYXlgIGluc3RhbmNlXG4gIG5ld0J1Zi5fX3Byb3RvX18gPSBCdWZmZXIucHJvdG90eXBlXG4gIHJldHVybiBuZXdCdWZcbn1cblxuLypcbiAqIE5lZWQgdG8gbWFrZSBzdXJlIHRoYXQgYnVmZmVyIGlzbid0IHRyeWluZyB0byB3cml0ZSBvdXQgb2YgYm91bmRzLlxuICovXG5mdW5jdGlvbiBjaGVja09mZnNldCAob2Zmc2V0LCBleHQsIGxlbmd0aCkge1xuICBpZiAoKG9mZnNldCAlIDEpICE9PSAwIHx8IG9mZnNldCA8IDApIHRocm93IG5ldyBSYW5nZUVycm9yKCdvZmZzZXQgaXMgbm90IHVpbnQnKVxuICBpZiAob2Zmc2V0ICsgZXh0ID4gbGVuZ3RoKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignVHJ5aW5nIHRvIGFjY2VzcyBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnRMRSA9IGZ1bmN0aW9uIHJlYWRVSW50TEUgKG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgYnl0ZUxlbmd0aCwgdGhpcy5sZW5ndGgpXG5cbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0XVxuICB2YXIgbXVsID0gMVxuICB2YXIgaSA9IDBcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyBpXSAqIG11bFxuICB9XG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50QkUgPSBmdW5jdGlvbiByZWFkVUludEJFIChvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcbiAgfVxuXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldCArIC0tYnl0ZUxlbmd0aF1cbiAgdmFyIG11bCA9IDFcbiAgd2hpbGUgKGJ5dGVMZW5ndGggPiAwICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgLS1ieXRlTGVuZ3RoXSAqIG11bFxuICB9XG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50OCA9IGZ1bmN0aW9uIHJlYWRVSW50OCAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAxLCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIHRoaXNbb2Zmc2V0XVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MTZMRSA9IGZ1bmN0aW9uIHJlYWRVSW50MTZMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAyLCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIHRoaXNbb2Zmc2V0XSB8ICh0aGlzW29mZnNldCArIDFdIDw8IDgpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQxNkJFID0gZnVuY3Rpb24gcmVhZFVJbnQxNkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSA8PCA4KSB8IHRoaXNbb2Zmc2V0ICsgMV1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDMyTEUgPSBmdW5jdGlvbiByZWFkVUludDMyTEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICgodGhpc1tvZmZzZXRdKSB8XG4gICAgICAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KSB8XG4gICAgICAodGhpc1tvZmZzZXQgKyAyXSA8PCAxNikpICtcbiAgICAgICh0aGlzW29mZnNldCArIDNdICogMHgxMDAwMDAwKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MzJCRSA9IGZ1bmN0aW9uIHJlYWRVSW50MzJCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSAqIDB4MTAwMDAwMCkgK1xuICAgICgodGhpc1tvZmZzZXQgKyAxXSA8PCAxNikgfFxuICAgICh0aGlzW29mZnNldCArIDJdIDw8IDgpIHxcbiAgICB0aGlzW29mZnNldCArIDNdKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnRMRSA9IGZ1bmN0aW9uIHJlYWRJbnRMRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcblxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXRdXG4gIHZhciBtdWwgPSAxXG4gIHZhciBpID0gMFxuICB3aGlsZSAoKytpIDwgYnl0ZUxlbmd0aCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHZhbCArPSB0aGlzW29mZnNldCArIGldICogbXVsXG4gIH1cbiAgbXVsICo9IDB4ODBcblxuICBpZiAodmFsID49IG11bCkgdmFsIC09IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50QkUgPSBmdW5jdGlvbiByZWFkSW50QkUgKG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgYnl0ZUxlbmd0aCwgdGhpcy5sZW5ndGgpXG5cbiAgdmFyIGkgPSBieXRlTGVuZ3RoXG4gIHZhciBtdWwgPSAxXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldCArIC0taV1cbiAgd2hpbGUgKGkgPiAwICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgLS1pXSAqIG11bFxuICB9XG4gIG11bCAqPSAweDgwXG5cbiAgaWYgKHZhbCA+PSBtdWwpIHZhbCAtPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aClcblxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDggPSBmdW5jdGlvbiByZWFkSW50OCAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAxLCB0aGlzLmxlbmd0aClcbiAgaWYgKCEodGhpc1tvZmZzZXRdICYgMHg4MCkpIHJldHVybiAodGhpc1tvZmZzZXRdKVxuICByZXR1cm4gKCgweGZmIC0gdGhpc1tvZmZzZXRdICsgMSkgKiAtMSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MTZMRSA9IGZ1bmN0aW9uIHJlYWRJbnQxNkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXRdIHwgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgOClcbiAgcmV0dXJuICh2YWwgJiAweDgwMDApID8gdmFsIHwgMHhGRkZGMDAwMCA6IHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQxNkJFID0gZnVuY3Rpb24gcmVhZEludDE2QkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldCArIDFdIHwgKHRoaXNbb2Zmc2V0XSA8PCA4KVxuICByZXR1cm4gKHZhbCAmIDB4ODAwMCkgPyB2YWwgfCAweEZGRkYwMDAwIDogdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDMyTEUgPSBmdW5jdGlvbiByZWFkSW50MzJMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSkgfFxuICAgICh0aGlzW29mZnNldCArIDFdIDw8IDgpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAyXSA8PCAxNikgfFxuICAgICh0aGlzW29mZnNldCArIDNdIDw8IDI0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQzMkJFID0gZnVuY3Rpb24gcmVhZEludDMyQkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICh0aGlzW29mZnNldF0gPDwgMjQpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAxXSA8PCAxNikgfFxuICAgICh0aGlzW29mZnNldCArIDJdIDw8IDgpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAzXSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRmxvYXRMRSA9IGZ1bmN0aW9uIHJlYWRGbG9hdExFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gaWVlZTc1NC5yZWFkKHRoaXMsIG9mZnNldCwgdHJ1ZSwgMjMsIDQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEZsb2F0QkUgPSBmdW5jdGlvbiByZWFkRmxvYXRCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIGZhbHNlLCAyMywgNClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRG91YmxlTEUgPSBmdW5jdGlvbiByZWFkRG91YmxlTEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgOCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCB0cnVlLCA1MiwgOClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRG91YmxlQkUgPSBmdW5jdGlvbiByZWFkRG91YmxlQkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgOCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCBmYWxzZSwgNTIsIDgpXG59XG5cbmZ1bmN0aW9uIGNoZWNrSW50IChidWYsIHZhbHVlLCBvZmZzZXQsIGV4dCwgbWF4LCBtaW4pIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYnVmKSkgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJidWZmZXJcIiBhcmd1bWVudCBtdXN0IGJlIGEgQnVmZmVyIGluc3RhbmNlJylcbiAgaWYgKHZhbHVlID4gbWF4IHx8IHZhbHVlIDwgbWluKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignXCJ2YWx1ZVwiIGFyZ3VtZW50IGlzIG91dCBvZiBib3VuZHMnKVxuICBpZiAob2Zmc2V0ICsgZXh0ID4gYnVmLmxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0luZGV4IG91dCBvZiByYW5nZScpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50TEUgPSBmdW5jdGlvbiB3cml0ZVVJbnRMRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICB2YXIgbWF4Qnl0ZXMgPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aCkgLSAxXG4gICAgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbWF4Qnl0ZXMsIDApXG4gIH1cblxuICB2YXIgbXVsID0gMVxuICB2YXIgaSA9IDBcbiAgdGhpc1tvZmZzZXRdID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdGhpc1tvZmZzZXQgKyBpXSA9ICh2YWx1ZSAvIG11bCkgJiAweEZGXG4gIH1cblxuICByZXR1cm4gb2Zmc2V0ICsgYnl0ZUxlbmd0aFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludEJFID0gZnVuY3Rpb24gd3JpdGVVSW50QkUgKHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgdmFyIG1heEJ5dGVzID0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpIC0gMVxuICAgIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG1heEJ5dGVzLCAwKVxuICB9XG5cbiAgdmFyIGkgPSBieXRlTGVuZ3RoIC0gMVxuICB2YXIgbXVsID0gMVxuICB0aGlzW29mZnNldCArIGldID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgtLWkgPj0gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAodmFsdWUgLyBtdWwpICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQ4ID0gZnVuY3Rpb24gd3JpdGVVSW50OCAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDEsIDB4ZmYsIDApXG4gIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIHJldHVybiBvZmZzZXQgKyAxXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MTZMRSA9IGZ1bmN0aW9uIHdyaXRlVUludDE2TEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAyLCAweGZmZmYsIDApXG4gIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MTZCRSA9IGZ1bmN0aW9uIHdyaXRlVUludDE2QkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAyLCAweGZmZmYsIDApXG4gIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gOClcbiAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MzJMRSA9IGZ1bmN0aW9uIHdyaXRlVUludDMyTEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCA0LCAweGZmZmZmZmZmLCAwKVxuICB0aGlzW29mZnNldCArIDNdID0gKHZhbHVlID4+PiAyNClcbiAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MzJCRSA9IGZ1bmN0aW9uIHdyaXRlVUludDMyQkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCA0LCAweGZmZmZmZmZmLCAwKVxuICB0aGlzW29mZnNldF0gPSAodmFsdWUgPj4+IDI0KVxuICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiAxNilcbiAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gOClcbiAgdGhpc1tvZmZzZXQgKyAzXSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnRMRSA9IGZ1bmN0aW9uIHdyaXRlSW50TEUgKHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgdmFyIGxpbWl0ID0gTWF0aC5wb3coMiwgKDggKiBieXRlTGVuZ3RoKSAtIDEpXG5cbiAgICBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBsaW1pdCAtIDEsIC1saW1pdClcbiAgfVxuXG4gIHZhciBpID0gMFxuICB2YXIgbXVsID0gMVxuICB2YXIgc3ViID0gMFxuICB0aGlzW29mZnNldF0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICBpZiAodmFsdWUgPCAwICYmIHN1YiA9PT0gMCAmJiB0aGlzW29mZnNldCArIGkgLSAxXSAhPT0gMCkge1xuICAgICAgc3ViID0gMVxuICAgIH1cbiAgICB0aGlzW29mZnNldCArIGldID0gKCh2YWx1ZSAvIG11bCkgPj4gMCkgLSBzdWIgJiAweEZGXG4gIH1cblxuICByZXR1cm4gb2Zmc2V0ICsgYnl0ZUxlbmd0aFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50QkUgPSBmdW5jdGlvbiB3cml0ZUludEJFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIHZhciBsaW1pdCA9IE1hdGgucG93KDIsICg4ICogYnl0ZUxlbmd0aCkgLSAxKVxuXG4gICAgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbGltaXQgLSAxLCAtbGltaXQpXG4gIH1cblxuICB2YXIgaSA9IGJ5dGVMZW5ndGggLSAxXG4gIHZhciBtdWwgPSAxXG4gIHZhciBzdWIgPSAwXG4gIHRoaXNbb2Zmc2V0ICsgaV0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKC0taSA+PSAwICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgaWYgKHZhbHVlIDwgMCAmJiBzdWIgPT09IDAgJiYgdGhpc1tvZmZzZXQgKyBpICsgMV0gIT09IDApIHtcbiAgICAgIHN1YiA9IDFcbiAgICB9XG4gICAgdGhpc1tvZmZzZXQgKyBpXSA9ICgodmFsdWUgLyBtdWwpID4+IDApIC0gc3ViICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDggPSBmdW5jdGlvbiB3cml0ZUludDggKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAxLCAweDdmLCAtMHg4MClcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmICsgdmFsdWUgKyAxXG4gIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIHJldHVybiBvZmZzZXQgKyAxXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQxNkxFID0gZnVuY3Rpb24gd3JpdGVJbnQxNkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMiwgMHg3ZmZmLCAtMHg4MDAwKVxuICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICByZXR1cm4gb2Zmc2V0ICsgMlxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MTZCRSA9IGZ1bmN0aW9uIHdyaXRlSW50MTZCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4N2ZmZiwgLTB4ODAwMClcbiAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiA4KVxuICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlICYgMHhmZilcbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDMyTEUgPSBmdW5jdGlvbiB3cml0ZUludDMyTEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCA0LCAweDdmZmZmZmZmLCAtMHg4MDAwMDAwMClcbiAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gOClcbiAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gIHRoaXNbb2Zmc2V0ICsgM10gPSAodmFsdWUgPj4+IDI0KVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MzJCRSA9IGZ1bmN0aW9uIHdyaXRlSW50MzJCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4N2ZmZmZmZmYsIC0weDgwMDAwMDAwKVxuICBpZiAodmFsdWUgPCAwKSB2YWx1ZSA9IDB4ZmZmZmZmZmYgKyB2YWx1ZSArIDFcbiAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiAyNClcbiAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gIHRoaXNbb2Zmc2V0ICsgMl0gPSAodmFsdWUgPj4+IDgpXG4gIHRoaXNbb2Zmc2V0ICsgM10gPSAodmFsdWUgJiAweGZmKVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5mdW5jdGlvbiBjaGVja0lFRUU3NTQgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgZXh0LCBtYXgsIG1pbikge1xuICBpZiAob2Zmc2V0ICsgZXh0ID4gYnVmLmxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0luZGV4IG91dCBvZiByYW5nZScpXG4gIGlmIChvZmZzZXQgPCAwKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignSW5kZXggb3V0IG9mIHJhbmdlJylcbn1cblxuZnVuY3Rpb24gd3JpdGVGbG9hdCAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgY2hlY2tJRUVFNzU0KGJ1ZiwgdmFsdWUsIG9mZnNldCwgNCwgMy40MDI4MjM0NjYzODUyODg2ZSszOCwgLTMuNDAyODIzNDY2Mzg1Mjg4NmUrMzgpXG4gIH1cbiAgaWVlZTc1NC53cml0ZShidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgMjMsIDQpXG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVGbG9hdExFID0gZnVuY3Rpb24gd3JpdGVGbG9hdExFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVGbG9hdCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUZsb2F0QkUgPSBmdW5jdGlvbiB3cml0ZUZsb2F0QkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiB3cml0ZUZsb2F0KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydClcbn1cblxuZnVuY3Rpb24gd3JpdGVEb3VibGUgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGNoZWNrSUVFRTc1NChidWYsIHZhbHVlLCBvZmZzZXQsIDgsIDEuNzk3NjkzMTM0ODYyMzE1N0UrMzA4LCAtMS43OTc2OTMxMzQ4NjIzMTU3RSszMDgpXG4gIH1cbiAgaWVlZTc1NC53cml0ZShidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgNTIsIDgpXG4gIHJldHVybiBvZmZzZXQgKyA4XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVEb3VibGVMRSA9IGZ1bmN0aW9uIHdyaXRlRG91YmxlTEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiB3cml0ZURvdWJsZSh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZURvdWJsZUJFID0gZnVuY3Rpb24gd3JpdGVEb3VibGVCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHdyaXRlRG91YmxlKHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydClcbn1cblxuLy8gY29weSh0YXJnZXRCdWZmZXIsIHRhcmdldFN0YXJ0PTAsIHNvdXJjZVN0YXJ0PTAsIHNvdXJjZUVuZD1idWZmZXIubGVuZ3RoKVxuQnVmZmVyLnByb3RvdHlwZS5jb3B5ID0gZnVuY3Rpb24gY29weSAodGFyZ2V0LCB0YXJnZXRTdGFydCwgc3RhcnQsIGVuZCkge1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcih0YXJnZXQpKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdhcmd1bWVudCBzaG91bGQgYmUgYSBCdWZmZXInKVxuICBpZiAoIXN0YXJ0KSBzdGFydCA9IDBcbiAgaWYgKCFlbmQgJiYgZW5kICE9PSAwKSBlbmQgPSB0aGlzLmxlbmd0aFxuICBpZiAodGFyZ2V0U3RhcnQgPj0gdGFyZ2V0Lmxlbmd0aCkgdGFyZ2V0U3RhcnQgPSB0YXJnZXQubGVuZ3RoXG4gIGlmICghdGFyZ2V0U3RhcnQpIHRhcmdldFN0YXJ0ID0gMFxuICBpZiAoZW5kID4gMCAmJiBlbmQgPCBzdGFydCkgZW5kID0gc3RhcnRcblxuICAvLyBDb3B5IDAgYnl0ZXM7IHdlJ3JlIGRvbmVcbiAgaWYgKGVuZCA9PT0gc3RhcnQpIHJldHVybiAwXG4gIGlmICh0YXJnZXQubGVuZ3RoID09PSAwIHx8IHRoaXMubGVuZ3RoID09PSAwKSByZXR1cm4gMFxuXG4gIC8vIEZhdGFsIGVycm9yIGNvbmRpdGlvbnNcbiAgaWYgKHRhcmdldFN0YXJ0IDwgMCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCd0YXJnZXRTdGFydCBvdXQgb2YgYm91bmRzJylcbiAgfVxuICBpZiAoc3RhcnQgPCAwIHx8IHN0YXJ0ID49IHRoaXMubGVuZ3RoKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignSW5kZXggb3V0IG9mIHJhbmdlJylcbiAgaWYgKGVuZCA8IDApIHRocm93IG5ldyBSYW5nZUVycm9yKCdzb3VyY2VFbmQgb3V0IG9mIGJvdW5kcycpXG5cbiAgLy8gQXJlIHdlIG9vYj9cbiAgaWYgKGVuZCA+IHRoaXMubGVuZ3RoKSBlbmQgPSB0aGlzLmxlbmd0aFxuICBpZiAodGFyZ2V0Lmxlbmd0aCAtIHRhcmdldFN0YXJ0IDwgZW5kIC0gc3RhcnQpIHtcbiAgICBlbmQgPSB0YXJnZXQubGVuZ3RoIC0gdGFyZ2V0U3RhcnQgKyBzdGFydFxuICB9XG5cbiAgdmFyIGxlbiA9IGVuZCAtIHN0YXJ0XG5cbiAgaWYgKHRoaXMgPT09IHRhcmdldCAmJiB0eXBlb2YgVWludDhBcnJheS5wcm90b3R5cGUuY29weVdpdGhpbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIC8vIFVzZSBidWlsdC1pbiB3aGVuIGF2YWlsYWJsZSwgbWlzc2luZyBmcm9tIElFMTFcbiAgICB0aGlzLmNvcHlXaXRoaW4odGFyZ2V0U3RhcnQsIHN0YXJ0LCBlbmQpXG4gIH0gZWxzZSBpZiAodGhpcyA9PT0gdGFyZ2V0ICYmIHN0YXJ0IDwgdGFyZ2V0U3RhcnQgJiYgdGFyZ2V0U3RhcnQgPCBlbmQpIHtcbiAgICAvLyBkZXNjZW5kaW5nIGNvcHkgZnJvbSBlbmRcbiAgICBmb3IgKHZhciBpID0gbGVuIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgIHRhcmdldFtpICsgdGFyZ2V0U3RhcnRdID0gdGhpc1tpICsgc3RhcnRdXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIFVpbnQ4QXJyYXkucHJvdG90eXBlLnNldC5jYWxsKFxuICAgICAgdGFyZ2V0LFxuICAgICAgdGhpcy5zdWJhcnJheShzdGFydCwgZW5kKSxcbiAgICAgIHRhcmdldFN0YXJ0XG4gICAgKVxuICB9XG5cbiAgcmV0dXJuIGxlblxufVxuXG4vLyBVc2FnZTpcbi8vICAgIGJ1ZmZlci5maWxsKG51bWJlclssIG9mZnNldFssIGVuZF1dKVxuLy8gICAgYnVmZmVyLmZpbGwoYnVmZmVyWywgb2Zmc2V0WywgZW5kXV0pXG4vLyAgICBidWZmZXIuZmlsbChzdHJpbmdbLCBvZmZzZXRbLCBlbmRdXVssIGVuY29kaW5nXSlcbkJ1ZmZlci5wcm90b3R5cGUuZmlsbCA9IGZ1bmN0aW9uIGZpbGwgKHZhbCwgc3RhcnQsIGVuZCwgZW5jb2RpbmcpIHtcbiAgLy8gSGFuZGxlIHN0cmluZyBjYXNlczpcbiAgaWYgKHR5cGVvZiB2YWwgPT09ICdzdHJpbmcnKSB7XG4gICAgaWYgKHR5cGVvZiBzdGFydCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGVuY29kaW5nID0gc3RhcnRcbiAgICAgIHN0YXJ0ID0gMFxuICAgICAgZW5kID0gdGhpcy5sZW5ndGhcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBlbmQgPT09ICdzdHJpbmcnKSB7XG4gICAgICBlbmNvZGluZyA9IGVuZFxuICAgICAgZW5kID0gdGhpcy5sZW5ndGhcbiAgICB9XG4gICAgaWYgKGVuY29kaW5nICE9PSB1bmRlZmluZWQgJiYgdHlwZW9mIGVuY29kaW5nICE9PSAnc3RyaW5nJykge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignZW5jb2RpbmcgbXVzdCBiZSBhIHN0cmluZycpXG4gICAgfVxuICAgIGlmICh0eXBlb2YgZW5jb2RpbmcgPT09ICdzdHJpbmcnICYmICFCdWZmZXIuaXNFbmNvZGluZyhlbmNvZGluZykpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmNvZGluZylcbiAgICB9XG4gICAgaWYgKHZhbC5sZW5ndGggPT09IDEpIHtcbiAgICAgIHZhciBjb2RlID0gdmFsLmNoYXJDb2RlQXQoMClcbiAgICAgIGlmICgoZW5jb2RpbmcgPT09ICd1dGY4JyAmJiBjb2RlIDwgMTI4KSB8fFxuICAgICAgICAgIGVuY29kaW5nID09PSAnbGF0aW4xJykge1xuICAgICAgICAvLyBGYXN0IHBhdGg6IElmIGB2YWxgIGZpdHMgaW50byBhIHNpbmdsZSBieXRlLCB1c2UgdGhhdCBudW1lcmljIHZhbHVlLlxuICAgICAgICB2YWwgPSBjb2RlXG4gICAgICB9XG4gICAgfVxuICB9IGVsc2UgaWYgKHR5cGVvZiB2YWwgPT09ICdudW1iZXInKSB7XG4gICAgdmFsID0gdmFsICYgMjU1XG4gIH1cblxuICAvLyBJbnZhbGlkIHJhbmdlcyBhcmUgbm90IHNldCB0byBhIGRlZmF1bHQsIHNvIGNhbiByYW5nZSBjaGVjayBlYXJseS5cbiAgaWYgKHN0YXJ0IDwgMCB8fCB0aGlzLmxlbmd0aCA8IHN0YXJ0IHx8IHRoaXMubGVuZ3RoIDwgZW5kKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ091dCBvZiByYW5nZSBpbmRleCcpXG4gIH1cblxuICBpZiAoZW5kIDw9IHN0YXJ0KSB7XG4gICAgcmV0dXJuIHRoaXNcbiAgfVxuXG4gIHN0YXJ0ID0gc3RhcnQgPj4+IDBcbiAgZW5kID0gZW5kID09PSB1bmRlZmluZWQgPyB0aGlzLmxlbmd0aCA6IGVuZCA+Pj4gMFxuXG4gIGlmICghdmFsKSB2YWwgPSAwXG5cbiAgdmFyIGlcbiAgaWYgKHR5cGVvZiB2YWwgPT09ICdudW1iZXInKSB7XG4gICAgZm9yIChpID0gc3RhcnQ7IGkgPCBlbmQ7ICsraSkge1xuICAgICAgdGhpc1tpXSA9IHZhbFxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB2YXIgYnl0ZXMgPSBCdWZmZXIuaXNCdWZmZXIodmFsKVxuICAgICAgPyB2YWxcbiAgICAgIDogQnVmZmVyLmZyb20odmFsLCBlbmNvZGluZylcbiAgICB2YXIgbGVuID0gYnl0ZXMubGVuZ3RoXG4gICAgaWYgKGxlbiA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhlIHZhbHVlIFwiJyArIHZhbCArXG4gICAgICAgICdcIiBpcyBpbnZhbGlkIGZvciBhcmd1bWVudCBcInZhbHVlXCInKVxuICAgIH1cbiAgICBmb3IgKGkgPSAwOyBpIDwgZW5kIC0gc3RhcnQ7ICsraSkge1xuICAgICAgdGhpc1tpICsgc3RhcnRdID0gYnl0ZXNbaSAlIGxlbl1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGhpc1xufVxuXG4vLyBIRUxQRVIgRlVOQ1RJT05TXG4vLyA9PT09PT09PT09PT09PT09XG5cbnZhciBJTlZBTElEX0JBU0U2NF9SRSA9IC9bXisvMC05QS1aYS16LV9dL2dcblxuZnVuY3Rpb24gYmFzZTY0Y2xlYW4gKHN0cikge1xuICAvLyBOb2RlIHRha2VzIGVxdWFsIHNpZ25zIGFzIGVuZCBvZiB0aGUgQmFzZTY0IGVuY29kaW5nXG4gIHN0ciA9IHN0ci5zcGxpdCgnPScpWzBdXG4gIC8vIE5vZGUgc3RyaXBzIG91dCBpbnZhbGlkIGNoYXJhY3RlcnMgbGlrZSBcXG4gYW5kIFxcdCBmcm9tIHRoZSBzdHJpbmcsIGJhc2U2NC1qcyBkb2VzIG5vdFxuICBzdHIgPSBzdHIudHJpbSgpLnJlcGxhY2UoSU5WQUxJRF9CQVNFNjRfUkUsICcnKVxuICAvLyBOb2RlIGNvbnZlcnRzIHN0cmluZ3Mgd2l0aCBsZW5ndGggPCAyIHRvICcnXG4gIGlmIChzdHIubGVuZ3RoIDwgMikgcmV0dXJuICcnXG4gIC8vIE5vZGUgYWxsb3dzIGZvciBub24tcGFkZGVkIGJhc2U2NCBzdHJpbmdzIChtaXNzaW5nIHRyYWlsaW5nID09PSksIGJhc2U2NC1qcyBkb2VzIG5vdFxuICB3aGlsZSAoc3RyLmxlbmd0aCAlIDQgIT09IDApIHtcbiAgICBzdHIgPSBzdHIgKyAnPSdcbiAgfVxuICByZXR1cm4gc3RyXG59XG5cbmZ1bmN0aW9uIHRvSGV4IChuKSB7XG4gIGlmIChuIDwgMTYpIHJldHVybiAnMCcgKyBuLnRvU3RyaW5nKDE2KVxuICByZXR1cm4gbi50b1N0cmluZygxNilcbn1cblxuZnVuY3Rpb24gdXRmOFRvQnl0ZXMgKHN0cmluZywgdW5pdHMpIHtcbiAgdW5pdHMgPSB1bml0cyB8fCBJbmZpbml0eVxuICB2YXIgY29kZVBvaW50XG4gIHZhciBsZW5ndGggPSBzdHJpbmcubGVuZ3RoXG4gIHZhciBsZWFkU3Vycm9nYXRlID0gbnVsbFxuICB2YXIgYnl0ZXMgPSBbXVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHtcbiAgICBjb2RlUG9pbnQgPSBzdHJpbmcuY2hhckNvZGVBdChpKVxuXG4gICAgLy8gaXMgc3Vycm9nYXRlIGNvbXBvbmVudFxuICAgIGlmIChjb2RlUG9pbnQgPiAweEQ3RkYgJiYgY29kZVBvaW50IDwgMHhFMDAwKSB7XG4gICAgICAvLyBsYXN0IGNoYXIgd2FzIGEgbGVhZFxuICAgICAgaWYgKCFsZWFkU3Vycm9nYXRlKSB7XG4gICAgICAgIC8vIG5vIGxlYWQgeWV0XG4gICAgICAgIGlmIChjb2RlUG9pbnQgPiAweERCRkYpIHtcbiAgICAgICAgICAvLyB1bmV4cGVjdGVkIHRyYWlsXG4gICAgICAgICAgaWYgKCh1bml0cyAtPSAzKSA+IC0xKSBieXRlcy5wdXNoKDB4RUYsIDB4QkYsIDB4QkQpXG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfSBlbHNlIGlmIChpICsgMSA9PT0gbGVuZ3RoKSB7XG4gICAgICAgICAgLy8gdW5wYWlyZWQgbGVhZFxuICAgICAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH1cblxuICAgICAgICAvLyB2YWxpZCBsZWFkXG4gICAgICAgIGxlYWRTdXJyb2dhdGUgPSBjb2RlUG9pbnRcblxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICAvLyAyIGxlYWRzIGluIGEgcm93XG4gICAgICBpZiAoY29kZVBvaW50IDwgMHhEQzAwKSB7XG4gICAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgICAgICBsZWFkU3Vycm9nYXRlID0gY29kZVBvaW50XG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIC8vIHZhbGlkIHN1cnJvZ2F0ZSBwYWlyXG4gICAgICBjb2RlUG9pbnQgPSAobGVhZFN1cnJvZ2F0ZSAtIDB4RDgwMCA8PCAxMCB8IGNvZGVQb2ludCAtIDB4REMwMCkgKyAweDEwMDAwXG4gICAgfSBlbHNlIGlmIChsZWFkU3Vycm9nYXRlKSB7XG4gICAgICAvLyB2YWxpZCBibXAgY2hhciwgYnV0IGxhc3QgY2hhciB3YXMgYSBsZWFkXG4gICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICB9XG5cbiAgICBsZWFkU3Vycm9nYXRlID0gbnVsbFxuXG4gICAgLy8gZW5jb2RlIHV0ZjhcbiAgICBpZiAoY29kZVBvaW50IDwgMHg4MCkge1xuICAgICAgaWYgKCh1bml0cyAtPSAxKSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKGNvZGVQb2ludClcbiAgICB9IGVsc2UgaWYgKGNvZGVQb2ludCA8IDB4ODAwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDIpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goXG4gICAgICAgIGNvZGVQb2ludCA+PiAweDYgfCAweEMwLFxuICAgICAgICBjb2RlUG9pbnQgJiAweDNGIHwgMHg4MFxuICAgICAgKVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50IDwgMHgxMDAwMCkge1xuICAgICAgaWYgKCh1bml0cyAtPSAzKSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHhDIHwgMHhFMCxcbiAgICAgICAgY29kZVBvaW50ID4+IDB4NiAmIDB4M0YgfCAweDgwLFxuICAgICAgICBjb2RlUG9pbnQgJiAweDNGIHwgMHg4MFxuICAgICAgKVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50IDwgMHgxMTAwMDApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gNCkgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChcbiAgICAgICAgY29kZVBvaW50ID4+IDB4MTIgfCAweEYwLFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHhDICYgMHgzRiB8IDB4ODAsXG4gICAgICAgIGNvZGVQb2ludCA+PiAweDYgJiAweDNGIHwgMHg4MCxcbiAgICAgICAgY29kZVBvaW50ICYgMHgzRiB8IDB4ODBcbiAgICAgIClcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGNvZGUgcG9pbnQnKVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBieXRlc1xufVxuXG5mdW5jdGlvbiBhc2NpaVRvQnl0ZXMgKHN0cikge1xuICB2YXIgYnl0ZUFycmF5ID0gW11cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyArK2kpIHtcbiAgICAvLyBOb2RlJ3MgY29kZSBzZWVtcyB0byBiZSBkb2luZyB0aGlzIGFuZCBub3QgJiAweDdGLi5cbiAgICBieXRlQXJyYXkucHVzaChzdHIuY2hhckNvZGVBdChpKSAmIDB4RkYpXG4gIH1cbiAgcmV0dXJuIGJ5dGVBcnJheVxufVxuXG5mdW5jdGlvbiB1dGYxNmxlVG9CeXRlcyAoc3RyLCB1bml0cykge1xuICB2YXIgYywgaGksIGxvXG4gIHZhciBieXRlQXJyYXkgPSBbXVxuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0ci5sZW5ndGg7ICsraSkge1xuICAgIGlmICgodW5pdHMgLT0gMikgPCAwKSBicmVha1xuXG4gICAgYyA9IHN0ci5jaGFyQ29kZUF0KGkpXG4gICAgaGkgPSBjID4+IDhcbiAgICBsbyA9IGMgJSAyNTZcbiAgICBieXRlQXJyYXkucHVzaChsbylcbiAgICBieXRlQXJyYXkucHVzaChoaSlcbiAgfVxuXG4gIHJldHVybiBieXRlQXJyYXlcbn1cblxuZnVuY3Rpb24gYmFzZTY0VG9CeXRlcyAoc3RyKSB7XG4gIHJldHVybiBiYXNlNjQudG9CeXRlQXJyYXkoYmFzZTY0Y2xlYW4oc3RyKSlcbn1cblxuZnVuY3Rpb24gYmxpdEJ1ZmZlciAoc3JjLCBkc3QsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHtcbiAgICBpZiAoKGkgKyBvZmZzZXQgPj0gZHN0Lmxlbmd0aCkgfHwgKGkgPj0gc3JjLmxlbmd0aCkpIGJyZWFrXG4gICAgZHN0W2kgKyBvZmZzZXRdID0gc3JjW2ldXG4gIH1cbiAgcmV0dXJuIGlcbn1cblxuLy8gQXJyYXlCdWZmZXIgb3IgVWludDhBcnJheSBvYmplY3RzIGZyb20gb3RoZXIgY29udGV4dHMgKGkuZS4gaWZyYW1lcykgZG8gbm90IHBhc3Ncbi8vIHRoZSBgaW5zdGFuY2VvZmAgY2hlY2sgYnV0IHRoZXkgc2hvdWxkIGJlIHRyZWF0ZWQgYXMgb2YgdGhhdCB0eXBlLlxuLy8gU2VlOiBodHRwczovL2dpdGh1Yi5jb20vZmVyb3NzL2J1ZmZlci9pc3N1ZXMvMTY2XG5mdW5jdGlvbiBpc0luc3RhbmNlIChvYmosIHR5cGUpIHtcbiAgcmV0dXJuIG9iaiBpbnN0YW5jZW9mIHR5cGUgfHxcbiAgICAob2JqICE9IG51bGwgJiYgb2JqLmNvbnN0cnVjdG9yICE9IG51bGwgJiYgb2JqLmNvbnN0cnVjdG9yLm5hbWUgIT0gbnVsbCAmJlxuICAgICAgb2JqLmNvbnN0cnVjdG9yLm5hbWUgPT09IHR5cGUubmFtZSlcbn1cbmZ1bmN0aW9uIG51bWJlcklzTmFOIChvYmopIHtcbiAgLy8gRm9yIElFMTEgc3VwcG9ydFxuICByZXR1cm4gb2JqICE9PSBvYmogLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1zZWxmLWNvbXBhcmVcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGJpbmQgPSByZXF1aXJlKCdmdW5jdGlvbi1iaW5kJyk7XG5cbnZhciAkYXBwbHkgPSByZXF1aXJlKCcuL2Z1bmN0aW9uQXBwbHknKTtcbnZhciAkY2FsbCA9IHJlcXVpcmUoJy4vZnVuY3Rpb25DYWxsJyk7XG52YXIgJHJlZmxlY3RBcHBseSA9IHJlcXVpcmUoJy4vcmVmbGVjdEFwcGx5Jyk7XG5cbi8qKiBAdHlwZSB7aW1wb3J0KCcuL2FjdHVhbEFwcGx5Jyl9ICovXG5tb2R1bGUuZXhwb3J0cyA9ICRyZWZsZWN0QXBwbHkgfHwgYmluZC5jYWxsKCRjYWxsLCAkYXBwbHkpO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKiogQHR5cGUge2ltcG9ydCgnLi9mdW5jdGlvbkFwcGx5Jyl9ICovXG5tb2R1bGUuZXhwb3J0cyA9IEZ1bmN0aW9uLnByb3RvdHlwZS5hcHBseTtcbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqIEB0eXBlIHtpbXBvcnQoJy4vZnVuY3Rpb25DYWxsJyl9ICovXG5tb2R1bGUuZXhwb3J0cyA9IEZ1bmN0aW9uLnByb3RvdHlwZS5jYWxsO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYmluZCA9IHJlcXVpcmUoJ2Z1bmN0aW9uLWJpbmQnKTtcbnZhciAkVHlwZUVycm9yID0gcmVxdWlyZSgnZXMtZXJyb3JzL3R5cGUnKTtcblxudmFyICRjYWxsID0gcmVxdWlyZSgnLi9mdW5jdGlvbkNhbGwnKTtcbnZhciAkYWN0dWFsQXBwbHkgPSByZXF1aXJlKCcuL2FjdHVhbEFwcGx5Jyk7XG5cbi8qKiBAdHlwZSB7KGFyZ3M6IFtGdW5jdGlvbiwgdGhpc0FyZz86IHVua25vd24sIC4uLmFyZ3M6IHVua25vd25bXV0pID0+IEZ1bmN0aW9ufSBUT0RPIEZJWE1FLCBmaW5kIGEgd2F5IHRvIHVzZSBpbXBvcnQoJy4nKSAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBjYWxsQmluZEJhc2ljKGFyZ3MpIHtcblx0aWYgKGFyZ3MubGVuZ3RoIDwgMSB8fCB0eXBlb2YgYXJnc1swXSAhPT0gJ2Z1bmN0aW9uJykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdhIGZ1bmN0aW9uIGlzIHJlcXVpcmVkJyk7XG5cdH1cblx0cmV0dXJuICRhY3R1YWxBcHBseShiaW5kLCAkY2FsbCwgYXJncyk7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKiogQHR5cGUge2ltcG9ydCgnLi9yZWZsZWN0QXBwbHknKX0gKi9cbm1vZHVsZS5leHBvcnRzID0gdHlwZW9mIFJlZmxlY3QgIT09ICd1bmRlZmluZWQnICYmIFJlZmxlY3QgJiYgUmVmbGVjdC5hcHBseTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyIGNhbGxCaW5kQmFzaWMgPSByZXF1aXJlKCdjYWxsLWJpbmQtYXBwbHktaGVscGVycycpO1xuXG4vKiogQHR5cGUgeyh0aGlzQXJnOiBzdHJpbmcsIHNlYXJjaFN0cmluZzogc3RyaW5nLCBwb3NpdGlvbj86IG51bWJlcikgPT4gbnVtYmVyfSAqL1xudmFyICRpbmRleE9mID0gY2FsbEJpbmRCYXNpYyhbR2V0SW50cmluc2ljKCclU3RyaW5nLnByb3RvdHlwZS5pbmRleE9mJScpXSk7XG5cbi8qKiBAdHlwZSB7aW1wb3J0KCcuJyl9ICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGNhbGxCb3VuZEludHJpbnNpYyhuYW1lLCBhbGxvd01pc3NpbmcpIHtcblx0LyogZXNsaW50IG5vLWV4dHJhLXBhcmVuczogMCAqL1xuXG5cdHZhciBpbnRyaW5zaWMgPSAvKiogQHR5cGUgeyh0aGlzOiB1bmtub3duLCAuLi5hcmdzOiB1bmtub3duW10pID0+IHVua25vd259ICovIChHZXRJbnRyaW5zaWMobmFtZSwgISFhbGxvd01pc3NpbmcpKTtcblx0aWYgKHR5cGVvZiBpbnRyaW5zaWMgPT09ICdmdW5jdGlvbicgJiYgJGluZGV4T2YobmFtZSwgJy5wcm90b3R5cGUuJykgPiAtMSkge1xuXHRcdHJldHVybiBjYWxsQmluZEJhc2ljKC8qKiBAdHlwZSB7Y29uc3R9ICovIChbaW50cmluc2ljXSkpO1xuXHR9XG5cdHJldHVybiBpbnRyaW5zaWM7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgY2FsbEJpbmQgPSByZXF1aXJlKCdjYWxsLWJpbmQtYXBwbHktaGVscGVycycpO1xudmFyIGdPUEQgPSByZXF1aXJlKCdnb3BkJyk7XG5cbnZhciBoYXNQcm90b0FjY2Vzc29yO1xudHJ5IHtcblx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWV4dHJhLXBhcmVucywgbm8tcHJvdG9cblx0aGFzUHJvdG9BY2Nlc3NvciA9IC8qKiBAdHlwZSB7eyBfX3Byb3RvX18/OiB0eXBlb2YgQXJyYXkucHJvdG90eXBlIH19ICovIChbXSkuX19wcm90b19fID09PSBBcnJheS5wcm90b3R5cGU7XG59IGNhdGNoIChlKSB7XG5cdGlmICghZSB8fCB0eXBlb2YgZSAhPT0gJ29iamVjdCcgfHwgISgnY29kZScgaW4gZSkgfHwgZS5jb2RlICE9PSAnRVJSX1BST1RPX0FDQ0VTUycpIHtcblx0XHR0aHJvdyBlO1xuXHR9XG59XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1leHRyYS1wYXJlbnNcbnZhciBkZXNjID0gISFoYXNQcm90b0FjY2Vzc29yICYmIGdPUEQgJiYgZ09QRChPYmplY3QucHJvdG90eXBlLCAvKiogQHR5cGUge2tleW9mIHR5cGVvZiBPYmplY3QucHJvdG90eXBlfSAqLyAoJ19fcHJvdG9fXycpKTtcblxudmFyICRPYmplY3QgPSBPYmplY3Q7XG52YXIgJGdldFByb3RvdHlwZU9mID0gJE9iamVjdC5nZXRQcm90b3R5cGVPZjtcblxuLyoqIEB0eXBlIHtpbXBvcnQoJy4vZ2V0Jyl9ICovXG5tb2R1bGUuZXhwb3J0cyA9IGRlc2MgJiYgdHlwZW9mIGRlc2MuZ2V0ID09PSAnZnVuY3Rpb24nXG5cdD8gY2FsbEJpbmQoW2Rlc2MuZ2V0XSlcblx0OiB0eXBlb2YgJGdldFByb3RvdHlwZU9mID09PSAnZnVuY3Rpb24nXG5cdFx0PyAvKiogQHR5cGUge2ltcG9ydCgnLi9nZXQnKX0gKi8gZnVuY3Rpb24gZ2V0RHVuZGVyKHZhbHVlKSB7XG5cdFx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZXFlcWVxXG5cdFx0XHRyZXR1cm4gJGdldFByb3RvdHlwZU9mKHZhbHVlID09IG51bGwgPyB2YWx1ZSA6ICRPYmplY3QodmFsdWUpKTtcblx0XHR9XG5cdFx0OiBmYWxzZTtcbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqIEB0eXBlIHtpbXBvcnQoJy4nKX0gKi9cbnZhciAkZGVmaW5lUHJvcGVydHkgPSBPYmplY3QuZGVmaW5lUHJvcGVydHkgfHwgZmFsc2U7XG5pZiAoJGRlZmluZVByb3BlcnR5KSB7XG5cdHRyeSB7XG5cdFx0JGRlZmluZVByb3BlcnR5KHt9LCAnYScsIHsgdmFsdWU6IDEgfSk7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHQvLyBJRSA4IGhhcyBhIGJyb2tlbiBkZWZpbmVQcm9wZXJ0eVxuXHRcdCRkZWZpbmVQcm9wZXJ0eSA9IGZhbHNlO1xuXHR9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gJGRlZmluZVByb3BlcnR5O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKiogQHR5cGUge2ltcG9ydCgnLi9ldmFsJyl9ICovXG5tb2R1bGUuZXhwb3J0cyA9IEV2YWxFcnJvcjtcbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqIEB0eXBlIHtpbXBvcnQoJy4nKX0gKi9cbm1vZHVsZS5leHBvcnRzID0gRXJyb3I7XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKiBAdHlwZSB7aW1wb3J0KCcuL3JhbmdlJyl9ICovXG5tb2R1bGUuZXhwb3J0cyA9IFJhbmdlRXJyb3I7XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKiBAdHlwZSB7aW1wb3J0KCcuL3JlZicpfSAqL1xubW9kdWxlLmV4cG9ydHMgPSBSZWZlcmVuY2VFcnJvcjtcbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqIEB0eXBlIHtpbXBvcnQoJy4vc3ludGF4Jyl9ICovXG5tb2R1bGUuZXhwb3J0cyA9IFN5bnRheEVycm9yO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKiogQHR5cGUge2ltcG9ydCgnLi90eXBlJyl9ICovXG5tb2R1bGUuZXhwb3J0cyA9IFR5cGVFcnJvcjtcbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqIEB0eXBlIHtpbXBvcnQoJy4vdXJpJyl9ICovXG5tb2R1bGUuZXhwb3J0cyA9IFVSSUVycm9yO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKiogQHR5cGUge2ltcG9ydCgnLicpfSAqL1xubW9kdWxlLmV4cG9ydHMgPSBPYmplY3Q7XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qIGVzbGludCBuby1pbnZhbGlkLXRoaXM6IDEgKi9cblxudmFyIEVSUk9SX01FU1NBR0UgPSAnRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQgY2FsbGVkIG9uIGluY29tcGF0aWJsZSAnO1xudmFyIHRvU3RyID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZztcbnZhciBtYXggPSBNYXRoLm1heDtcbnZhciBmdW5jVHlwZSA9ICdbb2JqZWN0IEZ1bmN0aW9uXSc7XG5cbnZhciBjb25jYXR0eSA9IGZ1bmN0aW9uIGNvbmNhdHR5KGEsIGIpIHtcbiAgICB2YXIgYXJyID0gW107XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGEubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgYXJyW2ldID0gYVtpXTtcbiAgICB9XG4gICAgZm9yICh2YXIgaiA9IDA7IGogPCBiLmxlbmd0aDsgaiArPSAxKSB7XG4gICAgICAgIGFycltqICsgYS5sZW5ndGhdID0gYltqXTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXJyO1xufTtcblxudmFyIHNsaWN5ID0gZnVuY3Rpb24gc2xpY3koYXJyTGlrZSwgb2Zmc2V0KSB7XG4gICAgdmFyIGFyciA9IFtdO1xuICAgIGZvciAodmFyIGkgPSBvZmZzZXQgfHwgMCwgaiA9IDA7IGkgPCBhcnJMaWtlLmxlbmd0aDsgaSArPSAxLCBqICs9IDEpIHtcbiAgICAgICAgYXJyW2pdID0gYXJyTGlrZVtpXTtcbiAgICB9XG4gICAgcmV0dXJuIGFycjtcbn07XG5cbnZhciBqb2lueSA9IGZ1bmN0aW9uIChhcnIsIGpvaW5lcikge1xuICAgIHZhciBzdHIgPSAnJztcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICBzdHIgKz0gYXJyW2ldO1xuICAgICAgICBpZiAoaSArIDEgPCBhcnIubGVuZ3RoKSB7XG4gICAgICAgICAgICBzdHIgKz0gam9pbmVyO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBzdHI7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGJpbmQodGhhdCkge1xuICAgIHZhciB0YXJnZXQgPSB0aGlzO1xuICAgIGlmICh0eXBlb2YgdGFyZ2V0ICE9PSAnZnVuY3Rpb24nIHx8IHRvU3RyLmFwcGx5KHRhcmdldCkgIT09IGZ1bmNUeXBlKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoRVJST1JfTUVTU0FHRSArIHRhcmdldCk7XG4gICAgfVxuICAgIHZhciBhcmdzID0gc2xpY3koYXJndW1lbnRzLCAxKTtcblxuICAgIHZhciBib3VuZDtcbiAgICB2YXIgYmluZGVyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAodGhpcyBpbnN0YW5jZW9mIGJvdW5kKSB7XG4gICAgICAgICAgICB2YXIgcmVzdWx0ID0gdGFyZ2V0LmFwcGx5KFxuICAgICAgICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgICAgICAgY29uY2F0dHkoYXJncywgYXJndW1lbnRzKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGlmIChPYmplY3QocmVzdWx0KSA9PT0gcmVzdWx0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0YXJnZXQuYXBwbHkoXG4gICAgICAgICAgICB0aGF0LFxuICAgICAgICAgICAgY29uY2F0dHkoYXJncywgYXJndW1lbnRzKVxuICAgICAgICApO1xuXG4gICAgfTtcblxuICAgIHZhciBib3VuZExlbmd0aCA9IG1heCgwLCB0YXJnZXQubGVuZ3RoIC0gYXJncy5sZW5ndGgpO1xuICAgIHZhciBib3VuZEFyZ3MgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJvdW5kTGVuZ3RoOyBpKyspIHtcbiAgICAgICAgYm91bmRBcmdzW2ldID0gJyQnICsgaTtcbiAgICB9XG5cbiAgICBib3VuZCA9IEZ1bmN0aW9uKCdiaW5kZXInLCAncmV0dXJuIGZ1bmN0aW9uICgnICsgam9pbnkoYm91bmRBcmdzLCAnLCcpICsgJyl7IHJldHVybiBiaW5kZXIuYXBwbHkodGhpcyxhcmd1bWVudHMpOyB9JykoYmluZGVyKTtcblxuICAgIGlmICh0YXJnZXQucHJvdG90eXBlKSB7XG4gICAgICAgIHZhciBFbXB0eSA9IGZ1bmN0aW9uIEVtcHR5KCkge307XG4gICAgICAgIEVtcHR5LnByb3RvdHlwZSA9IHRhcmdldC5wcm90b3R5cGU7XG4gICAgICAgIGJvdW5kLnByb3RvdHlwZSA9IG5ldyBFbXB0eSgpO1xuICAgICAgICBFbXB0eS5wcm90b3R5cGUgPSBudWxsO1xuICAgIH1cblxuICAgIHJldHVybiBib3VuZDtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBpbXBsZW1lbnRhdGlvbiA9IHJlcXVpcmUoJy4vaW1wbGVtZW50YXRpb24nKTtcblxubW9kdWxlLmV4cG9ydHMgPSBGdW5jdGlvbi5wcm90b3R5cGUuYmluZCB8fCBpbXBsZW1lbnRhdGlvbjtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHVuZGVmaW5lZDtcblxudmFyICRPYmplY3QgPSByZXF1aXJlKCdlcy1vYmplY3QtYXRvbXMnKTtcblxudmFyICRFcnJvciA9IHJlcXVpcmUoJ2VzLWVycm9ycycpO1xudmFyICRFdmFsRXJyb3IgPSByZXF1aXJlKCdlcy1lcnJvcnMvZXZhbCcpO1xudmFyICRSYW5nZUVycm9yID0gcmVxdWlyZSgnZXMtZXJyb3JzL3JhbmdlJyk7XG52YXIgJFJlZmVyZW5jZUVycm9yID0gcmVxdWlyZSgnZXMtZXJyb3JzL3JlZicpO1xudmFyICRTeW50YXhFcnJvciA9IHJlcXVpcmUoJ2VzLWVycm9ycy9zeW50YXgnKTtcbnZhciAkVHlwZUVycm9yID0gcmVxdWlyZSgnZXMtZXJyb3JzL3R5cGUnKTtcbnZhciAkVVJJRXJyb3IgPSByZXF1aXJlKCdlcy1lcnJvcnMvdXJpJyk7XG5cbnZhciBhYnMgPSByZXF1aXJlKCdtYXRoLWludHJpbnNpY3MvYWJzJyk7XG52YXIgZmxvb3IgPSByZXF1aXJlKCdtYXRoLWludHJpbnNpY3MvZmxvb3InKTtcbnZhciBtYXggPSByZXF1aXJlKCdtYXRoLWludHJpbnNpY3MvbWF4Jyk7XG52YXIgbWluID0gcmVxdWlyZSgnbWF0aC1pbnRyaW5zaWNzL21pbicpO1xudmFyIHBvdyA9IHJlcXVpcmUoJ21hdGgtaW50cmluc2ljcy9wb3cnKTtcbnZhciByb3VuZCA9IHJlcXVpcmUoJ21hdGgtaW50cmluc2ljcy9yb3VuZCcpO1xudmFyIHNpZ24gPSByZXF1aXJlKCdtYXRoLWludHJpbnNpY3Mvc2lnbicpO1xuXG52YXIgJEZ1bmN0aW9uID0gRnVuY3Rpb247XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjb25zaXN0ZW50LXJldHVyblxudmFyIGdldEV2YWxsZWRDb25zdHJ1Y3RvciA9IGZ1bmN0aW9uIChleHByZXNzaW9uU3ludGF4KSB7XG5cdHRyeSB7XG5cdFx0cmV0dXJuICRGdW5jdGlvbignXCJ1c2Ugc3RyaWN0XCI7IHJldHVybiAoJyArIGV4cHJlc3Npb25TeW50YXggKyAnKS5jb25zdHJ1Y3RvcjsnKSgpO1xuXHR9IGNhdGNoIChlKSB7fVxufTtcblxudmFyICRnT1BEID0gcmVxdWlyZSgnZ29wZCcpO1xudmFyICRkZWZpbmVQcm9wZXJ0eSA9IHJlcXVpcmUoJ2VzLWRlZmluZS1wcm9wZXJ0eScpO1xuXG52YXIgdGhyb3dUeXBlRXJyb3IgPSBmdW5jdGlvbiAoKSB7XG5cdHRocm93IG5ldyAkVHlwZUVycm9yKCk7XG59O1xudmFyIFRocm93VHlwZUVycm9yID0gJGdPUERcblx0PyAoZnVuY3Rpb24gKCkge1xuXHRcdHRyeSB7XG5cdFx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLWV4cHJlc3Npb25zLCBuby1jYWxsZXIsIG5vLXJlc3RyaWN0ZWQtcHJvcGVydGllc1xuXHRcdFx0YXJndW1lbnRzLmNhbGxlZTsgLy8gSUUgOCBkb2VzIG5vdCB0aHJvdyBoZXJlXG5cdFx0XHRyZXR1cm4gdGhyb3dUeXBlRXJyb3I7XG5cdFx0fSBjYXRjaCAoY2FsbGVlVGhyb3dzKSB7XG5cdFx0XHR0cnkge1xuXHRcdFx0XHQvLyBJRSA4IHRocm93cyBvbiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGFyZ3VtZW50cywgJycpXG5cdFx0XHRcdHJldHVybiAkZ09QRChhcmd1bWVudHMsICdjYWxsZWUnKS5nZXQ7XG5cdFx0XHR9IGNhdGNoIChnT1BEdGhyb3dzKSB7XG5cdFx0XHRcdHJldHVybiB0aHJvd1R5cGVFcnJvcjtcblx0XHRcdH1cblx0XHR9XG5cdH0oKSlcblx0OiB0aHJvd1R5cGVFcnJvcjtcblxudmFyIGhhc1N5bWJvbHMgPSByZXF1aXJlKCdoYXMtc3ltYm9scycpKCk7XG5cbnZhciBnZXRQcm90byA9IHJlcXVpcmUoJ2dldC1wcm90bycpO1xudmFyICRPYmplY3RHUE8gPSByZXF1aXJlKCdnZXQtcHJvdG8vT2JqZWN0LmdldFByb3RvdHlwZU9mJyk7XG52YXIgJFJlZmxlY3RHUE8gPSByZXF1aXJlKCdnZXQtcHJvdG8vUmVmbGVjdC5nZXRQcm90b3R5cGVPZicpO1xuXG52YXIgJGFwcGx5ID0gcmVxdWlyZSgnY2FsbC1iaW5kLWFwcGx5LWhlbHBlcnMvZnVuY3Rpb25BcHBseScpO1xudmFyICRjYWxsID0gcmVxdWlyZSgnY2FsbC1iaW5kLWFwcGx5LWhlbHBlcnMvZnVuY3Rpb25DYWxsJyk7XG5cbnZhciBuZWVkc0V2YWwgPSB7fTtcblxudmFyIFR5cGVkQXJyYXkgPSB0eXBlb2YgVWludDhBcnJheSA9PT0gJ3VuZGVmaW5lZCcgfHwgIWdldFByb3RvID8gdW5kZWZpbmVkIDogZ2V0UHJvdG8oVWludDhBcnJheSk7XG5cbnZhciBJTlRSSU5TSUNTID0ge1xuXHRfX3Byb3RvX186IG51bGwsXG5cdCclQWdncmVnYXRlRXJyb3IlJzogdHlwZW9mIEFnZ3JlZ2F0ZUVycm9yID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IEFnZ3JlZ2F0ZUVycm9yLFxuXHQnJUFycmF5JSc6IEFycmF5LFxuXHQnJUFycmF5QnVmZmVyJSc6IHR5cGVvZiBBcnJheUJ1ZmZlciA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBBcnJheUJ1ZmZlcixcblx0JyVBcnJheUl0ZXJhdG9yUHJvdG90eXBlJSc6IGhhc1N5bWJvbHMgJiYgZ2V0UHJvdG8gPyBnZXRQcm90byhbXVtTeW1ib2wuaXRlcmF0b3JdKCkpIDogdW5kZWZpbmVkLFxuXHQnJUFzeW5jRnJvbVN5bmNJdGVyYXRvclByb3RvdHlwZSUnOiB1bmRlZmluZWQsXG5cdCclQXN5bmNGdW5jdGlvbiUnOiBuZWVkc0V2YWwsXG5cdCclQXN5bmNHZW5lcmF0b3IlJzogbmVlZHNFdmFsLFxuXHQnJUFzeW5jR2VuZXJhdG9yRnVuY3Rpb24lJzogbmVlZHNFdmFsLFxuXHQnJUFzeW5jSXRlcmF0b3JQcm90b3R5cGUlJzogbmVlZHNFdmFsLFxuXHQnJUF0b21pY3MlJzogdHlwZW9mIEF0b21pY3MgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogQXRvbWljcyxcblx0JyVCaWdJbnQlJzogdHlwZW9mIEJpZ0ludCA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBCaWdJbnQsXG5cdCclQmlnSW50NjRBcnJheSUnOiB0eXBlb2YgQmlnSW50NjRBcnJheSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBCaWdJbnQ2NEFycmF5LFxuXHQnJUJpZ1VpbnQ2NEFycmF5JSc6IHR5cGVvZiBCaWdVaW50NjRBcnJheSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBCaWdVaW50NjRBcnJheSxcblx0JyVCb29sZWFuJSc6IEJvb2xlYW4sXG5cdCclRGF0YVZpZXclJzogdHlwZW9mIERhdGFWaWV3ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IERhdGFWaWV3LFxuXHQnJURhdGUlJzogRGF0ZSxcblx0JyVkZWNvZGVVUkklJzogZGVjb2RlVVJJLFxuXHQnJWRlY29kZVVSSUNvbXBvbmVudCUnOiBkZWNvZGVVUklDb21wb25lbnQsXG5cdCclZW5jb2RlVVJJJSc6IGVuY29kZVVSSSxcblx0JyVlbmNvZGVVUklDb21wb25lbnQlJzogZW5jb2RlVVJJQ29tcG9uZW50LFxuXHQnJUVycm9yJSc6ICRFcnJvcixcblx0JyVldmFsJSc6IGV2YWwsIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tZXZhbFxuXHQnJUV2YWxFcnJvciUnOiAkRXZhbEVycm9yLFxuXHQnJUZsb2F0MTZBcnJheSUnOiB0eXBlb2YgRmxvYXQxNkFycmF5ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IEZsb2F0MTZBcnJheSxcblx0JyVGbG9hdDMyQXJyYXklJzogdHlwZW9mIEZsb2F0MzJBcnJheSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBGbG9hdDMyQXJyYXksXG5cdCclRmxvYXQ2NEFycmF5JSc6IHR5cGVvZiBGbG9hdDY0QXJyYXkgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogRmxvYXQ2NEFycmF5LFxuXHQnJUZpbmFsaXphdGlvblJlZ2lzdHJ5JSc6IHR5cGVvZiBGaW5hbGl6YXRpb25SZWdpc3RyeSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBGaW5hbGl6YXRpb25SZWdpc3RyeSxcblx0JyVGdW5jdGlvbiUnOiAkRnVuY3Rpb24sXG5cdCclR2VuZXJhdG9yRnVuY3Rpb24lJzogbmVlZHNFdmFsLFxuXHQnJUludDhBcnJheSUnOiB0eXBlb2YgSW50OEFycmF5ID09PSAndW5kZWZpbmVkJyA/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=