UNPKG

homebridge-homeconnect

Version:

A Homebridge plugin that connects Home Connect appliances to Apple HomeKit

15,487 lines 1.46 MB
(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.APIValidationError = exports.APIStatusCodeError = exports.APIEventStreamError = exports.APIError = exports.APIAuthorisationError = void 0;
var _http = require("http");
var _utils = require("./utils.js");
var _apiTypes = require("./ti/api-types.js");
var _apiAuthTypes = require("./ti/api-auth-types.js");
// Homebridge plugin for Home Connect home appliances
// Copyright © 2023-2026 Alexander Thoukydides

// Base for reporting all Home Connect API errors
class APIError extends Error {
  constructor(request, response, message, options) {
    // Standard error object initialisation
    super(message);
    this.request = request;
    this.response = response;
    Error.captureStackTrace(this, APIError);
    this.name = 'Home Connect API Error';
    if (options?.cause) this.errCause = options.cause;
  }
}
// API could not be authorised
exports.APIError = APIError;
class APIAuthorisationError extends APIError {
  constructor(request, response, message, options) {
    super(request, response, message, options);
    Error.captureStackTrace(this, APIAuthorisationError);
    this.name = 'Home Connect API Authorisation Error';
  }
}
// API returned a non-success status code
exports.APIAuthorisationError = APIAuthorisationError;
class APIStatusCodeError extends APIError {
  constructor(request, response, text, options) {
    super(request, response, APIStatusCodeError.getMessage(response, text), options);
    this.text = text;
    Error.captureStackTrace(this, APIStatusCodeError);
    this.name = 'Home Connect Status Code Error';
  }
  // Construct an error message from a response
  static getMessage(response, text) {
    const statusCode = response.statusCode;
    const statusCodeName = _http.STATUS_CODES[statusCode];
    const description = APIStatusCodeError.getBodyDescription(text) ?? 'No error message returned';
    return `[${statusCode} ${statusCodeName}] ${description}`;
  }
  // Attempt to retrieve the error key
  get key() {
    return APIStatusCodeError.parseBody(this.text).key;
  }
  // Attempt to retrieve the error key
  get description() {
    return APIStatusCodeError.parseBody(this.text).description;
  }
  // Attempt to retrieve the error description
  get simpleMessage() {
    return APIStatusCodeError.getBodyDescription(this.text);
  }
  // Attempt to extract a useful description from the response body
  static getBodyDescription(text) {
    const {
      key,
      description
    } = APIStatusCodeError.parseBody(text);
    if (key) {
      return (description ? `${description} ` : '') + `[${key}]`;
    } else {
      return text.length ? text : undefined;
    }
  }
  // Attempt to parse the response body
  static parseBody(text) {
    try {
      const json = JSON.parse(text);
      if (_apiTypes.checkers.ErrorResponse.test(json)) {
        return {
          key: json.error.key,
          description: json.error.developerMessage ?? json.error.description ?? json.error.value
        };
      } else if (_apiAuthTypes.checkers.AuthorisationError.test(json)) {
        return {
          key: json.error,
          description: json.error_description
        };
      }
    } catch {/* empty */}
    return {};
  }
}
// API returned a response that failed checker validation
exports.APIStatusCodeError = APIStatusCodeError;
class APIValidationError extends APIError {
  constructor(request, response, validation, options) {
    super(request, response, APIValidationError.getMessage(validation), options);
    this.validation = validation;
    Error.captureStackTrace(this, APIValidationError);
    this.name = 'Home Connect API Validation Error';
  }
  // Construct an error message from a checker validation error
  static getMessage(errors) {
    (0, _utils.assertIsDefined)(errors[0]);
    const description = `${errors[0].path} ${errors[0].message}`;
    return `Structure validation failed (${description})`;
  }
}
// API returned event stream that could not be parsed
exports.APIValidationError = APIValidationError;
class APIEventStreamError extends APIError {
  constructor(request, response, message, sse, options) {
    super(request, response, APIEventStreamError.getMessage(message, sse), options);
    this.sse = sse;
    Error.captureStackTrace(this, APIEventStreamError);
    this.name = 'Home Connect API Event Stream Error';
  }
  // Construct an error message from a checker validation error
  static getMessage(description, sse) {
    const fields = Object.entries(sse).map(([name, value]) => [`${name}:`, value]);
    return [`Unable to parse ${description}:`, ...(0, _utils.columns)(fields)].join('\n');
  }
}
exports.APIEventStreamError = APIEventStreamError;

},{"./ti/api-auth-types.js":13,"./ti/api-types.js":15,"./utils.js":18,"http":83}],2:[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");
var _logError = require("../../log-error.js");
// Homebridge plugin for Home Connect home appliances
// Copyright © 2024-2026 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;
    (0, _logError.detached)(this.log, 'Poll status', () => this.pollStatus())();
  }
  // Check the status of the Home Connect API servers
  async pollStatus() {
    let pollAgain = true;
    while (pollAgain) {
      // 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
      if (this.lastUpdated !== status.updated) {
        this.lastUpdated = status.updated;
        pollAgain = this.showStatus(svg, status);
      }
      // Delay before polling the status again (if there are server issues)
      await new Promise(resolve => setTimeout(resolve, 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;

},{"../../log-error.js":11,"../../utils.js":18,"./utils-dom.js":10}],3:[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");
var _logError = require("../../log-error.js");
// Homebridge plugin for Home Connect home appliances
// Copyright © 2023-2026 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
    });
    (0, _logError.detached)(this.log, 'Load card icon', () => 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) {
    // 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})`);
      });
    });
  }
  // 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;

},{"../../log-error.js":11,"../../utils.js":18,"./utils-dom.js":10}],4:[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");
var _logError = require("../../log-error.js");
// Homebridge plugin for Home Connect home appliances
// Copyright © 2023-2026 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
  retryAuthorisation() {
    (0, _logError.detached)(this.log, 'Retry authorisation', async () => {
      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;

},{"../../log-error.js":11,"../../utils.js":18,"./utils-dom.js":10}],5:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.ClientIPC = void 0;
var _logError = require("../../log-error.js");
// Homebridge plugin for Home Connect home appliances
// Copyright © 2023-2026 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, (0, _logError.detached)(this.log, 'onEvent', async evt => {
      const data = evt.data;
      if (event !== 'log') this.log.debug(`onEvent("${event}") => callback`, data);
      await callback(data);
    }));
  }
}
exports.ClientIPC = ClientIPC;

},{"../../log-error.js":11}],6:[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-2026 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":2,"./cards.js":3,"./client-clientid.js":4,"./client-ipc.js":5,"./config.js":7,"./forms.js":8,"./logger.js":9}],7:[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-2026 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 ${(0, _utils.plural)(configArray.length, 'plugin configuration')}`, configArray);
        window.homebridge.toast.error('Only a single platform instance is supported; using the first', 'Multiple Configuration Blocks');
      }
      this.savedConfig = configArray[0];
      await 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);
    await 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
    await 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;
      await 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) {
    // Patch-up the programs list based on the addprograms setting
    switch (config.addprograms) {
      case 'none':
        config.programs = [];
        break;
      case 'auto':
        config.programs = undefined;
        break;
    }
    // Update the appliance configuration if it has changed
    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":17,"../../utils.js":18,"./utils-dom.js":10}],8:[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");
var _logError = require("../../log-error.js");
// Homebridge plugin for Home Connect home appliances
// Copyright © 2023-2026 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)
  showForm(formId) {
    (0, _logError.detached)(this.log, 'Show form', async () => {
      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;

},{"../../log-error.js":11,"./utils-dom.js":10}],9:[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-2026 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);
    });
    ipc.request('/log', minLevel).catch(() => {});
  }
  // Log messages received from the server
  logMessages(messages) {
    for (const {
      level,
      message,
      params
    } of messages) this.log(level, message, ...params);
  }
}
exports.ServerLogger = ServerLogger;

},{}],10:[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-2026 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":18,"assert":19}],11:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.detached = detached;
exports.logError = logError;
var _apiErrors = require("./api-errors.js");
// Homebridge plugin for Home Connect home appliances
// Copyright © 2023-2026 Alexander Thoukydides

// Log an error
let lastLoggedError;
function logError(log, when, err) {
  try {
    // Suppress duplicate reports
    if (lastLoggedError === err) return err;
    lastLoggedError = err;
    // Log the top-level error message
    const message = err instanceof Error ? `${err.name}: ${err.message}` : String(err);
    log.error(`[${when}] ${message}`);
    const prefix = ' '.repeat(when.length + 3);
    // Log the request details for API errors
    if (err instanceof _apiErrors.APIError) {
      log.error(`${err.request.method} ${err.request.path}`);
    }
    // Log any history of causes or sub-errors
    logSubErrors(log, prefix, err);
    // Log any stack backtrace (for the top-level error only)
    if (err instanceof Error && err.stack) log.debug(err.stack);
  } catch {/* empty */}
  return err;
}
// Trap any detached promise rejections
function detached(log, when, fn) {
  return (...args) => {
    fn(...args)?.catch(err => logError(log, when, err));
  };
}
// Log any sub-errors (causes or aggregates) of an error, formatted as a tree
function logSubErrors(log, prefix, err) {
  // Collect all aggregate or causal errors
  const subErrs = [];
  if (err instanceof _apiErrors.APIError && err.errCause) subErrs.push(err.errCause);
  if (err instanceof Error && err.cause) subErrs.push(err.cause);
  if (err instanceof AggregateError && Array.isArray(err.errors)) subErrs.push(...err.errors);
  // Log the collected errors formatted as a tree
  subErrs.forEach((subErr, index) => {
    const subPrefix = index < subErrs.length - 1 ? ['├─', '│ '] : ['└─', '  '];
    const message = subErr instanceof Error ? `${subErr.name}: ${subErr.message}` : String(subErr);
    log.error(`${prefix}${subPrefix[0]} ${message}`);
    logSubErrors(log, `${prefix}${subPrefix[1]} `, subErr);
  });
}

},{"./api-errors.js":1}],12:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = exports.Scope = exports.PersistAbsoluteTokens = exports.DeviceAuthorisationResponse = exports.DeviceAuthorisationRequest = exports.DeviceAccessTokenResponse = exports.DeviceAccessTokenRequest = exports.AuthorisationState = exports.AuthorisationResponse = exports.AuthorisationRequest = exports.AuthorisationError = exports.AccessTokenResponse = exports.AccessTokenRequest = exports.AccessTokenRefreshResponse = exports.AccessTokenRefreshRequest = exports.AbsoluteToken = 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 Scope = exports.Scope = t.union(t.lit('Monitor'), t.lit('Control'), t.lit('Settings'), t.lit('Images'), t.lit('AirConditioner'), t.lit('AirConditioner-Monitor'), t.lit('AirConditioner-Control'), t.lit('AirConditioner-Settings'), t.lit('CleaningRobot'), t.lit('CleaningRobot-Monitor'), t.lit('CleaningRobot-Control'), t.lit('CleaningRobot-Settings'), t.lit('CoffeeMaker'), t.lit('CoffeeMaker-Monitor'), t.lit('CoffeeMaker-Control'), t.lit('CoffeeMaker-Settings'), t.lit('CookProcessor'), t.lit('CookProcessor-Monitor'), t.lit('CookProcessor-Control'), t.lit('CookProcessor-Settings'), t.lit('Dishwasher'), t.lit('Dishwasher-Monitor'), t.lit('Dishwasher-Control'), t.lit('Dishwasher-Settings'), t.lit('Dryer'), t.lit('Dryer-Monitor'), t.lit('Dryer-Control'), t.lit('Dryer-Settings'), t.lit('Freezer'), t.lit('Freezer-Monitor'), t.lit('Freezer-Control'), t.lit('Freezer-Settings'), t.lit('FridgeFreezer'), t.lit('FridgeFreezer-Monitor'), t.lit('FridgeFreezer-Control'), t.lit('FridgeFreezer-Settings'), t.lit('FridgeFreezer-Images'), t.lit('Hob'), t.lit('Hob-Monitor'), t.lit('Hob-Control'), t.lit('Hob-Settings'), t.lit('Hood'), t.lit('Hood-Monitor'), t.lit('Hood-Control'), t.lit('Hood-Settings'), t.lit('Microwave'), t.lit('Microwave-Monitor'), t.lit('Microwave-Control'), t.lit('Microwave-Settings'), t.lit('Oven'), t.lit('Oven-Monitor'), t.lit('Oven-Control'), t.lit('Oven-Settings'), t.lit('Refrigerator'), t.lit('Refrigerator-Monitor'), t.lit('Refrigerator-Control'), t.lit('Refrigerator-Settings'), t.lit('Washer'), t.lit('Washer-Monitor'), t.lit('Washer-Control'), t.lit('Washer-Settings'), t.lit('WasherDryer'), t.lit('WasherDryer-Monitor'), t.lit('WasherDryer-Control'), t.lit('WasherDryer-Settings'), t.lit('WineCooler'), t.lit('WineCooler-Monitor'), t.lit('WineCooler-Control'), t.lit('WineCooler-Settings'));
const AuthorisationRequest = exports.AuthorisationRequest = t.iface([], {
  "client_id": "string",
  "redirect_uri": t.opt("string"),
  "response_type": t.lit('code'),
  "scope": t.opt("string"),
  "state": t.opt("AuthorisationState"),
  "nonce": t.opt("string"),
  "code_challenge": t.opt("string"),
  "code_challenge_method": t.opt(t.union(t.lit('plain'), t.lit('S256')))
});
const AuthorisationState = exports.AuthorisationState = t.union("string", "number");
const AuthorisationResponse = exports.AuthorisationResponse = t.iface([], {
  "code": "string",
  "grant_type": t.opt(t.lit('authorization_code')),
  "state": t.opt("AuthorisationState")
});
const AccessTokenRequest = exports.AccessTokenRequest = t.iface([], {
  "client_id": "string",
  "client_secret": t.opt("string"),
  "redirect_uri": t.opt("string"),
  "grant_type": t.lit('authorization_code'),
  "code": "string",
  "code_verifier": t.opt("string")
});
const AccessTokenResponse = exports.AccessTokenResponse = t.iface([], {
  "id_token": "string",
  "access_token": "string",
  "expires_in": "number",
  "scope": "string",
  "refresh_token": "string",
  "token_type": t.opt(t.lit('Bearer'))
});
const DeviceAuthorisationRequest = exports.DeviceAuthorisationRequest = t.iface([], {
  "client_id": "string",
  "scope": t.opt("string")
});
const DeviceAuthorisationResponse = exports.DeviceAuthorisationResponse = t.iface([], {
  "device_code": "string",
  "user_code": "string",
  "verification_uri": "string",
  "verification_uri_complete": t.opt("string"),
  "expires_in": t.opt("number"),
  "interval": t.opt("number")
});
const DeviceAccessTokenRequest = exports.DeviceAccessTokenRequest = t.iface([], {
  "grant_type": t.union(t.lit('urn:ietf:params:oauth:grant-type:device_code'), t.lit('device_code')),
  "device_code": "string",
  "client_id": "string",
  "client_secret": t.opt("string")
});
const DeviceAccessTokenResponse = exports.DeviceAccessTokenResponse = t.iface([], {
  "id_token": "string",
  "access_token": "string",
  "expires_in": "number",
  "scope": "string",
  "refresh_token": "string",
  "token_type": t.opt(t.lit('Bearer'))
});
const AccessTokenRefreshRequest = exports.AccessTokenRefreshRequest = t.iface([], {
  "grant_type": t.lit('refresh_token'),
  "refresh_token": "string",
  "client_secret": t.opt("string"),
  "scope": t.opt("string"),
  "expires_in": t.opt("number")
});
const AccessTokenRefreshResponse = exports.AccessTokenRefreshResponse = t.iface([], {
  "id_token": "string",
  "access_token": "string",
  "expires_in": "number",
  "scope": "string",
  "refresh_token": "string",
  "token_type": t.lit('Bearer')
});
const AbsoluteToken = exports.AbsoluteToken = t.iface([], {
  "refreshToken": "string",
  "accessToken": "string",
  "accessExpires": "number",
  "scopes": t.array("string")
});
const PersistAbsoluteTokens = exports.PersistAbsoluteTokens = t.iface([], {
  [t.indexKey]: "AbsoluteToken"
});
const AuthorisationError = exports.AuthorisationError = t.iface([], {
  "error": "string",
  "error_description": "string"
});
const exportedTypeSuite = {
  Scope,
  AuthorisationRequest,
  AuthorisationState,
  AuthorisationResponse,
  AccessTokenRequest,
  AccessTokenResponse,
  DeviceAuthorisationRequest,
  DeviceAuthorisationResponse,
  DeviceAccessTokenRequest,
  DeviceAccessTokenResponse,
  AccessTokenRefreshRequest,
  AccessTokenRefreshResponse,
  AbsoluteToken,
  PersistAbsoluteTokens,
  AuthorisationError
};
var _default = exports.default = exportedTypeSuite;

},{"ts-interface-checker":103}],13:[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 _apiAuthTypesTi = _interopRequireDefault(require("./api-auth-types-ti.js"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
// This module was automatically generated by node ts-interface-post.ts
// 2026-05-31T15:27:42.412Z

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

},{"./api-auth-types-ti.js":12,"ts-interface-checker":103}],14:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = exports.Value = exports.StatusesWrapper = exports.StatusWrapper = exports.StatusString = exports.StatusNumber = exports.StatusCommon = exports.StatusBoolean = exports.Status = exports.SettingsWrapper = exports.SettingWrapper = exports.SettingString = exports.SettingNumber = exports.SettingCommon = exports.SettingBoolean = exports.Setting = exports.ProgramsWrapper = exports.Programs = exports.ProgramWrapper = exports.ProgramPartial = exports.ProgramList = exports.ProgramExecution = exports.ProgramDefinitionWrapper = exports.ProgramDefinition = exports.ProgramConstraints = exports.Program = exports.OptionsWrapper = exports.OptionWrapper = exports.OptionDefinitionString = exports.OptionDefinitionNumber = exports.OptionDefinitionCommon = exports.OptionDefinitionBoolean = exports.OptionDefinition = exports.OptionConstraintsCommon = exports.Option = exports.ImagesWrapper = exports.ImageQuality = exports.Image = exports.HomeAppliancesWrapper = exports.HomeApplianceWrapper = exports.HomeAppliance = exports.ExecuteCommandWrapper = exports.ExecuteCommand = exports.EventLevel = exports.EventKeepAlive = exports.EventHandling = exports.EventData = exports.EventApplianceData = exports.EventApplianceConnection = exports.Event = exports.ErrorResponse = exports.ConstraintsString = exports.ConstraintsNumber = exports.ConstraintsCommon = exports.ConstraintsBoolean = exports.Constraints = exports.CommandsWrapper = exports.Command = exports.Access = 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 Value = exports.Value = t.union("string", "number", "boolean");
const Constraints = exports.Constraints = t.union("ConstraintsString", "ConstraintsNumber", "ConstraintsBoolean");
const ConstraintsString = exports.ConstraintsString = t.iface(["ConstraintsCommon"], {
  "default": t.opt("string"),
  "allowedvalues": t.opt(t.array("string")),
  "displayvalues": t.opt(t.array("string"))
});
const ConstraintsNumber = exports.ConstraintsNumber = t.iface(["ConstraintsCommon"], {
  "default": t.opt("number"),
  "min": t.opt("number"),
  "max": t.opt("number"),
  "stepsize": t.opt("number")
});
const ConstraintsBoolean = exports.ConstraintsBoolean = t.iface(["ConstraintsCommon"], {
  "default": t.opt("boolean")
});
const ConstraintsCommon = exports.ConstraintsCommon = t.iface([], {
  "access": t.opt("Access")
});
const Access = exports.Access = t.union(t.lit('read'), t.lit('readWrite'));
const ExecuteCommandWrapper = exports.ExecuteCommandWrapper = t.iface([], {
  "data": "ExecuteCommand"
});
const ExecuteCommand = exports.ExecuteCommand = t.iface([], {
  "key": "string",
  "value": t.lit(true)
});
const CommandsWrapper = exports.CommandsWrapper = t.iface([], {
  "data": t.iface([], {
    "commands": t.array("Command")
  })
});
const Command = exports.Command = t.iface([], {
  "key": "string",
  "name": t.opt("string"),
  "description": t.opt("string")
});
const Event = exports.Event = t.union("EventKeepAlive", "EventApplianceConnection", "EventApplianceData");
const EventKeepAlive = exports.EventKeepAlive = t.iface([], {
  "event": t.lit('KEEP-ALIVE'),
  "data": t.opt(t.lit(''))
});
const EventApplianceConnection = exports.EventApplianceConnection = t.iface([], {
  "event": t.union(t.lit('CONNECTED'), t.lit('DISCONNECTED'), t.lit('PAIRED'), t.lit('DEPAIRED')),
  "id": "string",
  "data": t.opt(t.union(t.lit(''), "EventData"))
});
const EventApplianceData = exports.EventApplianceData = t.iface([], {
  "event": t.union(t.lit('STATUS'), t.lit('EVENT'), t.lit('NOTIFY')),
  "id": "string",
  "data": t.iface([], {
    "items": t.array("EventData"),
    "haId": t.opt("string")
  })
});
const EventData = exports.EventData = t.iface([], {
  "key": "string",
  "name": t.opt("string"),
  "uri": t.opt("string"),
  "timestamp": t.union("number", "null"),
  "level": "EventLevel",
  "handling": "EventHandling",
  "value": t.union("Value", "null"),
  "displayvalue": t.opt("string"),
  "unit": t.opt("string"),
  "haId": t.opt("string")
});
const EventLevel = exports.EventLevel = t.union(t.lit('critical'), t.lit('alert'), t.lit('warning'), t.lit('hint'), t.lit('info'));
const EventHandling = exports.EventHandling = t.union(t.lit('none'), t.lit('acknowledge'), t.lit('decision'));
const HomeAppliancesWrapper = exports.HomeAppliancesWrapper = t.iface([], {
  "data": t.iface([], {
    "homeappliances": t.array("HomeAppliance")
  })
});
const HomeApplianceWrapper = exports.HomeApplianceWrapper = t.iface([], {
  "data": "HomeAppliance"
});
const HomeAppliance = exports.HomeAppliance = t.iface([], {
  "haId": "string",
  "name": "string",
  "type": "string",
  "brand": "string",
  "vib": "string",
  "enumber": "string",
  "connected": "boolean"
});
const ImagesWrapper = exports.ImagesWrapper = t.iface([], {
  "data": t.iface([], {
    "images": t.array("Image")
  })
});
const Image = exports.Image = t.iface([], {
  "key": "string",
  "name": t.opt("string"),
  "imagekey": "string",
  "previewimagekey": "string",
  "timestamp": "number",
  "quality": "ImageQuality"
});
const ImageQuality = exports.ImageQuality = t.union(t.lit('good'), t.lit('bad'));
const ProgramsWrapper = exports.ProgramsWrapper = t.iface([], {
  "data": "Programs"
});
const Programs = exports.Programs = t.iface([], {
  "programs": t.array("ProgramList"),
  "selected": t.opt("ProgramPartial"),
  "active": t.opt("ProgramPartial")
});
const ProgramList = exports.ProgramList = t.iface([], {
  "key": "string",
  "name": t.opt("string"),
  "constraints": t.opt("ProgramConstraints")
});
const ProgramConstraints = exports.ProgramConstraints = t.iface([], {
  "available": t.opt("boolean"),
  "execution": t.opt("ProgramExecution"),
  "access": t.opt("Access")
});
const ProgramExecution = exports.ProgramExecution = t.union(t.lit('none'), t.lit('selectonly'), t.lit('startonly'), t.lit('selectandstart'));
const ProgramWrapper = exports.ProgramWrapper = t.iface([], {
  "data": "Program"
});
const Program = exports.Program = t.iface(["ProgramPartial"], {
  "key": "string"
});
const ProgramPartial = exports.ProgramPartial = t.iface([], {
  "key": t.opt("string"),
  "name": t.opt("string"),
  "options": t.opt(t.array("Option")),
  "constraints": t.opt("ProgramConstraints")
});
const ProgramDefinitionWrapper = exports.ProgramDefinitionWrapper = t.iface([], {
  "data": "ProgramDefinition"
});
const ProgramDefinition = exports.ProgramDefinition = t.iface([], {
  "key": "string",
  "name": t.opt("string"),
  "options": t.opt(t.array("OptionDefinition"))
});
const OptionDefinition = exports.OptionDefinition = t.union("OptionDefinitionString", "OptionDefinitionNumber", "OptionDefinitionBoolean");
const OptionDefinitionString = exports.OptionDefinitionString = t.iface(["OptionDefinitionCommon"], {
  "type": t.union(t.lit('String'), "string"),
  "constraints": t.opt(t.intersection("OptionConstraintsCommon", "ConstraintsString"))
});
const OptionDefinitionNumber = exports.OptionDefinitionNumber = t.iface(["OptionDefinitionCommon"], {
  "type": t.union(t.lit('Double'), t.lit('Int')),
  "constraints": t.opt(t.intersection("OptionConstraintsCommon", "ConstraintsNumber"))
});
const OptionDefinitionBoolean = exports.OptionDefinitionBoolean = t.iface(["OptionDefinitionCommon"], {
  "type": t.lit('Boolean'),
  "constraints": t.opt(t.intersection("OptionConstraintsCommon", "ConstraintsBoolean"))
});
const OptionDefinitionCommon = exports.OptionDefinitionCommon = t.iface([], {
  "key": "string",
  "name": t.opt("string"),
  "unit": t.opt("string")
});
const OptionConstraintsCommon = exports.OptionConstraintsCommon = t.iface([], {
  "liveupdate": t.opt("boolean")
});
const OptionsWrapper = exports.OptionsWrapper = t.iface([], {
  "data": t.iface([], {
    "options": t.array("Option")
  })
});
const OptionWrapper = exports.OptionWrapper = t.iface([], {
  "data": "Option"
});
const Option = exports.Option = t.iface([], {
  "key": "string",
  "name": t.opt("string"),
  "value": "Value",
  "displayvalue": t.opt("string"),
  "unit": t.opt("string")
});
const SettingsWrapper = exports.SettingsWrapper = t.iface([], {
  "data": t.iface([], {
    "settings": t.array("Setting")
  })
});
const SettingWrapper = exports.SettingWrapper = t.iface([], {
  "data": "Setting"
});
const Setting = exports.Setting = t.union("SettingString", "SettingNumber", "SettingBoolean");
const SettingString = exports.SettingString = t.iface(["SettingCommon"], {
  "value": "string",
  "constraints": t.opt("ConstraintsString")
});
const SettingNumber = exports.SettingNumber = t.iface(["SettingCommon"], {
  "value": "number",
  "constraints": t.opt("ConstraintsNumber")
});
const SettingBoolean = exports.SettingBoolean = t.iface(["SettingCommon"], {
  "value": "boolean",
  "constraints": t.opt("ConstraintsBoolean")
});
const SettingCommon = exports.SettingCommon = t.iface([], {
  "key": "string",
  "name": t.opt("string"),
  "type": t.opt("string"),
  "displayvalue": t.opt("string"),
  "unit": t.opt("string")
});
const StatusesWrapper = exports.StatusesWrapper = t.iface([], {
  "data": t.iface([], {
    "status": t.array("Status")
  })
});
const StatusWrapper = exports.StatusWrapper = t.iface([], {
  "data": "Status"
});
const Status = exports.Status = t.union("StatusString", "StatusNumber", "StatusBoolean");
const StatusString = exports.StatusString = t.iface(["StatusCommon"], {
  "value": "string",
  "constraints": t.opt("ConstraintsString")
});
const StatusNumber = exports.StatusNumber = t.iface(["StatusCommon"], {
  "value": "number",
  "constraints": t.opt("ConstraintsNumber")
});
const StatusBoolean = exports.StatusBoolean = t.iface(["StatusCommon"], {
  "value": "boolean",
  "constraints": t.opt("ConstraintsBoolean")
});
const StatusCommon = exports.StatusCommon = t.iface([], {
  "key": "string",
  "name": t.opt("string"),
  "displayvalue": t.opt("string"),
  "unit": t.opt("string")
});
const ErrorResponse = exports.ErrorResponse = t.iface([], {
  "error": t.iface([], {
    "key": "string",
    "description": t.opt("string"),
    "developerMessage": t.opt("string"),
    "value": t.opt("string")
  })
});
const exportedTypeSuite = {
  Value,
  Constraints,
  ConstraintsString,
  ConstraintsNumber,
  ConstraintsBoolean,
  ConstraintsCommon,
  Access,
  ExecuteCommandWrapper,
  ExecuteCommand,
  CommandsWrapper,
  Command,
  Event,
  EventKeepAlive,
  EventApplianceConnection,
  EventApplianceData,
  EventData,
  EventLevel,
  EventHandling,
  HomeAppliancesWrapper,
  HomeApplianceWrapper,
  HomeAppliance,
  ImagesWrapper,
  Image,
  ImageQuality,
  ProgramsWrapper,
  Programs,
  ProgramList,
  ProgramConstraints,
  ProgramExecution,
  ProgramWrapper,
  Program,
  ProgramPartial,
  ProgramDefinitionWrapper,
  ProgramDefinition,
  OptionDefinition,
  OptionDefinitionString,
  OptionDefinitionNumber,
  OptionDefinitionBoolean,
  OptionDefinitionCommon,
  OptionConstraintsCommon,
  OptionsWrapper,
  OptionWrapper,
  Option,
  SettingsWrapper,
  SettingWrapper,
  Setting,
  SettingString,
  SettingNumber,
  SettingBoolean,
  SettingCommon,
  StatusesWrapper,
  StatusWrapper,
  Status,
  StatusString,
  StatusNumber,
  StatusBoolean,
  StatusCommon,
  ErrorResponse
};
var _default = exports.default = exportedTypeSuite;

},{"ts-interface-checker":103}],15:[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 _apiTypesTi = _interopRequireDefault(require("./api-types-ti.js"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
// This module was automatically generated by node ts-interface-post.ts
// 2026-05-31T15:27:42.413Z

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

},{"./api-types-ti.js":14,"ts-interface-checker":103}],16:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = exports.ExperimentalFeatures = 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"
  }),
  "experimental": t.opt(t.array("ExperimentalFeatures")),
  "debug": t.opt(t.array("DebugFeatures"))
});
const ExperimentalFeatures = exports.ExperimentalFeatures = t.lit('Disconnected as Off');
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,
  ExperimentalFeatures,
  DebugFeatures,
  ConfigAppliances,
  AddProgramsConfig,
  ApplianceConfig,
  ApplianceNamesPrefix,
  ApplianceFeatures,
  ApplianceProgramConfig,
  ApplianceProgramOptions
};
var _default = exports.default = exportedTypeSuite;

},{"ts-interface-checker":103}],17:[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
// 2026-05-31T15:27:42.414Z

// 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":16,"ts-interface-checker":103}],18:[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-2026 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":19}],19:[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":70,"util/":22}],20:[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
  }
}

},{}],21:[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';
}
},{}],22:[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":21,"_process":71,"inherits":20}],23:[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('')
}

},{}],24:[function(require,module,exports){

},{}],25:[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":23,"buffer":25,"ieee754":55}],26:[function(require,module,exports){
module.exports = {
  "100": "Continue",
  "101": "Switching Protocols",
  "102": "Processing",
  "200": "OK",
  "201": "Created",
  "202": "Accepted",
  "203": "Non-Authoritative Information",
  "204": "No Content",
  "205": "Reset Content",
  "206": "Partial Content",
  "207": "Multi-Status",
  "208": "Already Reported",
  "226": "IM Used",
  "300": "Multiple Choices",
  "301": "Moved Permanently",
  "302": "Found",
  "303": "See Other",
  "304": "Not Modified",
  "305": "Use Proxy",
  "307": "Temporary Redirect",
  "308": "Permanent Redirect",
  "400": "Bad Request",
  "401": "Unauthorized",
  "402": "Payment Required",
  "403": "Forbidden",
  "404": "Not Found",
  "405": "Method Not Allowed",
  "406": "Not Acceptable",
  "407": "Proxy Authentication Required",
  "408": "Request Timeout",
  "409": "Conflict",
  "410": "Gone",
  "411": "Length Required",
  "412": "Precondition Failed",
  "413": "Payload Too Large",
  "414": "URI Too Long",
  "415": "Unsupported Media Type",
  "416": "Range Not Satisfiable",
  "417": "Expectation Failed",
  "418": "I'm a teapot",
  "421": "Misdirected Request",
  "422": "Unprocessable Entity",
  "423": "Locked",
  "424": "Failed Dependency",
  "425": "Unordered Collection",
  "426": "Upgrade Required",
  "428": "Precondition Required",
  "429": "Too Many Requests",
  "431": "Request Header Fields Too Large",
  "451": "Unavailable For Legal Reasons",
  "500": "Internal Server Error",
  "501": "Not Implemented",
  "502": "Bad Gateway",
  "503": "Service Unavailable",
  "504": "Gateway Timeout",
  "505": "HTTP Version Not Supported",
  "506": "Variant Also Negotiates",
  "507": "Insufficient Storage",
  "508": "Loop Detected",
  "509": "Bandwidth Limit Exceeded",
  "510": "Not Extended",
  "511": "Network Authentication Required"
}

},{}],27:[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":28,"./functionCall":29,"./reflectApply":31,"function-bind":45}],28:[function(require,module,exports){
'use strict';

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

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

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

},{}],30:[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":27,"./functionCall":29,"es-errors/type":40,"function-bind":45}],31:[function(require,module,exports){
'use strict';

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

},{}],32:[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":30,"get-intrinsic":46}],33:[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":30,"gopd":51}],34:[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;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

},{}],43:[function(require,module,exports){
// 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.

'use strict';

var R = typeof Reflect === 'object' ? Reflect : null
var ReflectApply = R && typeof R.apply === 'function'
  ? R.apply
  : function ReflectApply(target, receiver, args) {
    return Function.prototype.apply.call(target, receiver, args);
  }

var ReflectOwnKeys
if (R && typeof R.ownKeys === 'function') {
  ReflectOwnKeys = R.ownKeys
} else if (Object.getOwnPropertySymbols) {
  ReflectOwnKeys = function ReflectOwnKeys(target) {
    return Object.getOwnPropertyNames(target)
      .concat(Object.getOwnPropertySymbols(target));
  };
} else {
  ReflectOwnKeys = function ReflectOwnKeys(target) {
    return Object.getOwnPropertyNames(target);
  };
}

function ProcessEmitWarning(warning) {
  if (console && console.warn) console.warn(warning);
}

var NumberIsNaN = Number.isNaN || function NumberIsNaN(value) {
  return value !== value;
}

function EventEmitter() {
  EventEmitter.init.call(this);
}
module.exports = EventEmitter;
module.exports.once = once;

// Backwards-compat with node 0.10.x
EventEmitter.EventEmitter = EventEmitter;

EventEmitter.prototype._events = undefined;
EventEmitter.prototype._eventsCount = 0;
EventEmitter.prototype._maxListeners = undefined;

// By default EventEmitters will print a warning if more than 10 listeners are
// added to it. This is a useful default which helps finding memory leaks.
var defaultMaxListeners = 10;

function checkListener(listener) {
  if (typeof listener !== 'function') {
    throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener);
  }
}

Object.defineProperty(EventEmitter, 'defaultMaxListeners', {
  enumerable: true,
  get: function() {
    return defaultMaxListeners;
  },
  set: function(arg) {
    if (typeof arg !== 'number' || arg < 0 || NumberIsNaN(arg)) {
      throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received ' + arg + '.');
    }
    defaultMaxListeners = arg;
  }
});

EventEmitter.init = function() {

  if (this._events === undefined ||
      this._events === Object.getPrototypeOf(this)._events) {
    this._events = Object.create(null);
    this._eventsCount = 0;
  }

  this._maxListeners = this._maxListeners || undefined;
};

// Obviously not all Emitters should be limited to 10. This function allows
// that to be increased. Set to zero for unlimited.
EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) {
  if (typeof n !== 'number' || n < 0 || NumberIsNaN(n)) {
    throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received ' + n + '.');
  }
  this._maxListeners = n;
  return this;
};

function _getMaxListeners(that) {
  if (that._maxListeners === undefined)
    return EventEmitter.defaultMaxListeners;
  return that._maxListeners;
}

EventEmitter.prototype.getMaxListeners = function getMaxListeners() {
  return _getMaxListeners(this);
};

EventEmitter.prototype.emit = function emit(type) {
  var args = [];
  for (var i = 1; i < arguments.length; i++) args.push(arguments[i]);
  var doError = (type === 'error');

  var events = this._events;
  if (events !== undefined)
    doError = (doError && events.error === undefined);
  else if (!doError)
    return false;

  // If there is no 'error' event listener then throw.
  if (doError) {
    var er;
    if (args.length > 0)
      er = args[0];
    if (er instanceof Error) {
      // Note: The comments on the `throw` lines are intentional, they show
      // up in Node's output if this results in an unhandled exception.
      throw er; // Unhandled 'error' event
    }
    // At least give some kind of context to the user
    var err = new Error('Unhandled error.' + (er ? ' (' + er.message + ')' : ''));
    err.context = er;
    throw err; // Unhandled 'error' event
  }

  var handler = events[type];

  if (handler === undefined)
    return false;

  if (typeof handler === 'function') {
    ReflectApply(handler, this, args);
  } else {
    var len = handler.length;
    var listeners = arrayClone(handler, len);
    for (var i = 0; i < len; ++i)
      ReflectApply(listeners[i], this, args);
  }

  return true;
};

function _addListener(target, type, listener, prepend) {
  var m;
  var events;
  var existing;

  checkListener(listener);

  events = target._events;
  if (events === undefined) {
    events = target._events = Object.create(null);
    target._eventsCount = 0;
  } else {
    // To avoid recursion in the case that type === "newListener"! Before
    // adding it to the listeners, first emit "newListener".
    if (events.newListener !== undefined) {
      target.emit('newListener', type,
                  listener.listener ? listener.listener : listener);

      // Re-assign `events` because a newListener handler could have caused the
      // this._events to be assigned to a new object
      events = target._events;
    }
    existing = events[type];
  }

  if (existing === undefined) {
    // Optimize the case of one listener. Don't need the extra array object.
    existing = events[type] = listener;
    ++target._eventsCount;
  } else {
    if (typeof existing === 'function') {
      // Adding the second element, need to change to array.
      existing = events[type] =
        prepend ? [listener, existing] : [existing, listener];
      // If we've already got an array, just append.
    } else if (prepend) {
      existing.unshift(listener);
    } else {
      existing.push(listener);
    }

    // Check for listener leak
    m = _getMaxListeners(target);
    if (m > 0 && existing.length > m && !existing.warned) {
      existing.warned = true;
      // No error code for this since it is a Warning
      // eslint-disable-next-line no-restricted-syntax
      var w = new Error('Possible EventEmitter memory leak detected. ' +
                          existing.length + ' ' + String(type) + ' listeners ' +
                          'added. Use emitter.setMaxListeners() to ' +
                          'increase limit');
      w.name = 'MaxListenersExceededWarning';
      w.emitter = target;
      w.type = type;
      w.count = existing.length;
      ProcessEmitWarning(w);
    }
  }

  return target;
}

EventEmitter.prototype.addListener = function addListener(type, listener) {
  return _addListener(this, type, listener, false);
};

EventEmitter.prototype.on = EventEmitter.prototype.addListener;

EventEmitter.prototype.prependListener =
    function prependListener(type, listener) {
      return _addListener(this, type, listener, true);
    };

function onceWrapper() {
  if (!this.fired) {
    this.target.removeListener(this.type, this.wrapFn);
    this.fired = true;
    if (arguments.length === 0)
      return this.listener.call(this.target);
    return this.listener.apply(this.target, arguments);
  }
}

function _onceWrap(target, type, listener) {
  var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener };
  var wrapped = onceWrapper.bind(state);
  wrapped.listener = listener;
  state.wrapFn = wrapped;
  return wrapped;
}

EventEmitter.prototype.once = function once(type, listener) {
  checkListener(listener);
  this.on(type, _onceWrap(this, type, listener));
  return this;
};

EventEmitter.prototype.prependOnceListener =
    function prependOnceListener(type, listener) {
      checkListener(listener);
      this.prependListener(type, _onceWrap(this, type, listener));
      return this;
    };

// Emits a 'removeListener' event if and only if the listener was removed.
EventEmitter.prototype.removeListener =
    function removeListener(type, listener) {
      var list, events, position, i, originalListener;

      checkListener(listener);

      events = this._events;
      if (events === undefined)
        return this;

      list = events[type];
      if (list === undefined)
        return this;

      if (list === listener || list.listener === listener) {
        if (--this._eventsCount === 0)
          this._events = Object.create(null);
        else {
          delete events[type];
          if (events.removeListener)
            this.emit('removeListener', type, list.listener || listener);
        }
      } else if (typeof list !== 'function') {
        position = -1;

        for (i = list.length - 1; i >= 0; i--) {
          if (list[i] === listener || list[i].listener === listener) {
            originalListener = list[i].listener;
            position = i;
            break;
          }
        }

        if (position < 0)
          return this;

        if (position === 0)
          list.shift();
        else {
          spliceOne(list, position);
        }

        if (list.length === 1)
          events[type] = list[0];

        if (events.removeListener !== undefined)
          this.emit('removeListener', type, originalListener || listener);
      }

      return this;
    };

EventEmitter.prototype.off = EventEmitter.prototype.removeListener;

EventEmitter.prototype.removeAllListeners =
    function removeAllListeners(type) {
      var listeners, events, i;

      events = this._events;
      if (events === undefined)
        return this;

      // not listening for removeListener, no need to emit
      if (events.removeListener === undefined) {
        if (arguments.length === 0) {
          this._events = Object.create(null);
          this._eventsCount = 0;
        } else if (events[type] !== undefined) {
          if (--this._eventsCount === 0)
            this._events = Object.create(null);
          else
            delete events[type];
        }
        return this;
      }

      // emit removeListener for all listeners on all events
      if (arguments.length === 0) {
        var keys = Object.keys(events);
        var key;
        for (i = 0; i < keys.length; ++i) {
          key = keys[i];
          if (key === 'removeListener') continue;
          this.removeAllListeners(key);
        }
        this.removeAllListeners('removeListener');
        this._events = Object.create(null);
        this._eventsCount = 0;
        return this;
      }

      listeners = events[type];

      if (typeof listeners === 'function') {
        this.removeListener(type, listeners);
      } else if (listeners !== undefined) {
        // LIFO order
        for (i = listeners.length - 1; i >= 0; i--) {
          this.removeListener(type, listeners[i]);
        }
      }

      return this;
    };

function _listeners(target, type, unwrap) {
  var events = target._events;

  if (events === undefined)
    return [];

  var evlistener = events[type];
  if (evlistener === undefined)
    return [];

  if (typeof evlistener === 'function')
    return unwrap ? [evlistener.listener || evlistener] : [evlistener];

  return unwrap ?
    unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length);
}

EventEmitter.prototype.listeners = function listeners(type) {
  return _listeners(this, type, true);
};

EventEmitter.prototype.rawListeners = function rawListeners(type) {
  return _listeners(this, type, false);
};

EventEmitter.listenerCount = function(emitter, type) {
  if (typeof emitter.listenerCount === 'function') {
    return emitter.listenerCount(type);
  } else {
    return listenerCount.call(emitter, type);
  }
};

EventEmitter.prototype.listenerCount = listenerCount;
function listenerCount(type) {
  var events = this._events;

  if (events !== undefined) {
    var evlistener = events[type];

    if (typeof evlistener === 'function') {
      return 1;
    } else if (evlistener !== undefined) {
      return evlistener.length;
    }
  }

  return 0;
}

EventEmitter.prototype.eventNames = function eventNames() {
  return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : [];
};

function arrayClone(arr, n) {
  var copy = new Array(n);
  for (var i = 0; i < n; ++i)
    copy[i] = arr[i];
  return copy;
}

function spliceOne(list, index) {
  for (; index + 1 < list.length; index++)
    list[index] = list[index + 1];
  list.pop();
}

function unwrapListeners(arr) {
  var ret = new Array(arr.length);
  for (var i = 0; i < ret.length; ++i) {
    ret[i] = arr[i].listener || arr[i];
  }
  return ret;
}

function once(emitter, name) {
  return new Promise(function (resolve, reject) {
    function errorListener(err) {
      emitter.removeListener(name, resolver);
      reject(err);
    }

    function resolver() {
      if (typeof emitter.removeListener === 'function') {
        emitter.removeListener('error', errorListener);
      }
      resolve([].slice.call(arguments));
    };

    eventTargetAgnosticAddListener(emitter, name, resolver, { once: true });
    if (name !== 'error') {
      addErrorHandlerIfEventEmitter(emitter, errorListener, { once: true });
    }
  });
}

function addErrorHandlerIfEventEmitter(emitter, handler, flags) {
  if (typeof emitter.on === 'function') {
    eventTargetAgnosticAddListener(emitter, 'error', handler, flags);
  }
}

function eventTargetAgnosticAddListener(emitter, name, listener, flags) {
  if (typeof emitter.on === 'function') {
    if (flags.once) {
      emitter.once(name, listener);
    } else {
      emitter.on(name, listener);
    }
  } else if (typeof emitter.addEventListener === 'function') {
    // EventTarget does not have `error` event semantics like Node
    // EventEmitters, we do not listen for `error` events here.
    emitter.addEventListener(name, function wrapListener(arg) {
      // IE does not have builtin `{ once: true }` support so we
      // have to do it manually.
      if (flags.once) {
        emitter.removeEventListener(name, wrapListener);
      }
      listener(arg);
    });
  } else {
    throw new TypeError('The "emitter" argument must be of type EventEmitter. Received type ' + typeof emitter);
  }
}

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

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

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

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

},{"./implementation":44}],46:[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":28,"call-bind-apply-helpers/functionCall":29,"es-define-property":34,"es-errors":36,"es-errors/eval":35,"es-errors/range":37,"es-errors/ref":38,"es-errors/syntax":39,"es-errors/type":40,"es-errors/uri":41,"es-object-atoms":42,"function-bind":45,"get-proto":49,"get-proto/Object.getPrototypeOf":47,"get-proto/Reflect.getPrototypeOf":48,"gopd":51,"has-symbols":52,"hasown":54,"math-intrinsics/abs":57,"math-intrinsics/floor":58,"math-intrinsics/max":60,"math-intrinsics/min":61,"math-intrinsics/pow":62,"math-intrinsics/round":63,"math-intrinsics/sign":64}],47:[function(require,module,exports){
'use strict';

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

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

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

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

},{}],49:[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":47,"./Reflect.getPrototypeOf":48,"dunder-proto/get":33}],50:[function(require,module,exports){
'use strict';

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

},{}],51:[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":50}],52:[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":53}],53:[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;
};

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

},{}],56:[function(require,module,exports){
if (typeof Object.create === 'function') {
  // implementation from standard node.js 'util' module
  module.exports = function inherits(ctor, superCtor) {
    if (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) {
    if (superCtor) {
      ctor.super_ = superCtor
      var TempCtor = function () {}
      TempCtor.prototype = superCtor.prototype
      ctor.prototype = new TempCtor()
      ctor.prototype.constructor = ctor
    }
  }
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

},{}],64:[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":59}],65:[function(require,module,exports){
(function (global){(function (){
var hasMap = typeof Map === 'function' && Map.prototype;
var mapSizeDescriptor = Object.getOwnPropertyDescriptor && hasMap ? Object.getOwnPropertyDescriptor(Map.prototype, 'size') : null;
var mapSize = hasMap && mapSizeDescriptor && typeof mapSizeDescriptor.get === 'function' ? mapSizeDescriptor.get : null;
var mapForEach = hasMap && Map.prototype.forEach;
var hasSet = typeof Set === 'function' && Set.prototype;
var setSizeDescriptor = Object.getOwnPropertyDescriptor && hasSet ? Object.getOwnPropertyDescriptor(Set.prototype, 'size') : null;
var setSize = hasSet && setSizeDescriptor && typeof setSizeDescriptor.get === 'function' ? setSizeDescriptor.get : null;
var setForEach = hasSet && Set.prototype.forEach;
var hasWeakMap = typeof WeakMap === 'function' && WeakMap.prototype;
var weakMapHas = hasWeakMap ? WeakMap.prototype.has : null;
var hasWeakSet = typeof WeakSet === 'function' && WeakSet.prototype;
var weakSetHas = hasWeakSet ? WeakSet.prototype.has : null;
var hasWeakRef = typeof WeakRef === 'function' && WeakRef.prototype;
var weakRefDeref = hasWeakRef ? WeakRef.prototype.deref : null;
var booleanValueOf = Boolean.prototype.valueOf;
var objectToString = Object.prototype.toString;
var functionToString = Function.prototype.toString;
var $match = String.prototype.match;
var $slice = String.prototype.slice;
var $replace = String.prototype.replace;
var $toUpperCase = String.prototype.toUpperCase;
var $toLowerCase = String.prototype.toLowerCase;
var $test = RegExp.prototype.test;
var $concat = Array.prototype.concat;
var $join = Array.prototype.join;
var $arrSlice = Array.prototype.slice;
var $floor = Math.floor;
var bigIntValueOf = typeof BigInt === 'function' ? BigInt.prototype.valueOf : null;
var gOPS = Object.getOwnPropertySymbols;
var symToString = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? Symbol.prototype.toString : null;
var hasShammedSymbols = typeof Symbol === 'function' && typeof Symbol.iterator === 'object';
// ie, `has-tostringtag/shams
var toStringTag = typeof Symbol === 'function' && Symbol.toStringTag && (typeof Symbol.toStringTag === hasShammedSymbols ? 'object' : 'symbol')
    ? Symbol.toStringTag
    : null;
var isEnumerable = Object.prototype.propertyIsEnumerable;

var gPO = (typeof Reflect === 'function' ? Reflect.getPrototypeOf : Object.getPrototypeOf) || (
    [].__proto__ === Array.prototype // eslint-disable-line no-proto
        ? function (O) {
            return O.__proto__; // eslint-disable-line no-proto
        }
        : null
);

function addNumericSeparator(num, str) {
    if (
        num === Infinity
        || num === -Infinity
        || num !== num
        || (num && num > -1000 && num < 1000)
        || $test.call(/e/, str)
    ) {
        return str;
    }
    var sepRegex = /[0-9](?=(?:[0-9]{3})+(?![0-9]))/g;
    if (typeof num === 'number') {
        var int = num < 0 ? -$floor(-num) : $floor(num); // trunc(num)
        if (int !== num) {
            var intStr = String(int);
            var dec = $slice.call(str, intStr.length + 1);
            return $replace.call(intStr, sepRegex, '$&_') + '.' + $replace.call($replace.call(dec, /([0-9]{3})/g, '$&_'), /_$/, '');
        }
    }
    return $replace.call(str, sepRegex, '$&_');
}

var utilInspect = require('./util.inspect');
var inspectCustom = utilInspect.custom;
var inspectSymbol = isSymbol(inspectCustom) ? inspectCustom : null;

var quotes = {
    __proto__: null,
    'double': '"',
    single: "'"
};
var quoteREs = {
    __proto__: null,
    'double': /(["\\])/g,
    single: /(['\\])/g
};

module.exports = function inspect_(obj, options, depth, seen) {
    var opts = options || {};

    if (has(opts, 'quoteStyle') && !has(quotes, opts.quoteStyle)) {
        throw new TypeError('option "quoteStyle" must be "single" or "double"');
    }
    if (
        has(opts, 'maxStringLength') && (typeof opts.maxStringLength === 'number'
            ? opts.maxStringLength < 0 && opts.maxStringLength !== Infinity
            : opts.maxStringLength !== null
        )
    ) {
        throw new TypeError('option "maxStringLength", if provided, must be a positive integer, Infinity, or `null`');
    }
    var customInspect = has(opts, 'customInspect') ? opts.customInspect : true;
    if (typeof customInspect !== 'boolean' && customInspect !== 'symbol') {
        throw new TypeError('option "customInspect", if provided, must be `true`, `false`, or `\'symbol\'`');
    }

    if (
        has(opts, 'indent')
        && opts.indent !== null
        && opts.indent !== '\t'
        && !(parseInt(opts.indent, 10) === opts.indent && opts.indent > 0)
    ) {
        throw new TypeError('option "indent" must be "\\t", an integer > 0, or `null`');
    }
    if (has(opts, 'numericSeparator') && typeof opts.numericSeparator !== 'boolean') {
        throw new TypeError('option "numericSeparator", if provided, must be `true` or `false`');
    }
    var numericSeparator = opts.numericSeparator;

    if (typeof obj === 'undefined') {
        return 'undefined';
    }
    if (obj === null) {
        return 'null';
    }
    if (typeof obj === 'boolean') {
        return obj ? 'true' : 'false';
    }

    if (typeof obj === 'string') {
        return inspectString(obj, opts);
    }
    if (typeof obj === 'number') {
        if (obj === 0) {
            return Infinity / obj > 0 ? '0' : '-0';
        }
        var str = String(obj);
        return numericSeparator ? addNumericSeparator(obj, str) : str;
    }
    if (typeof obj === 'bigint') {
        var bigIntStr = String(obj) + 'n';
        return numericSeparator ? addNumericSeparator(obj, bigIntStr) : bigIntStr;
    }

    var maxDepth = typeof opts.depth === 'undefined' ? 5 : opts.depth;
    if (typeof depth === 'undefined') { depth = 0; }
    if (depth >= maxDepth && maxDepth > 0 && typeof obj === 'object') {
        return isArray(obj) ? '[Array]' : '[Object]';
    }

    var indent = getIndent(opts, depth);

    if (typeof seen === 'undefined') {
        seen = [];
    } else if (indexOf(seen, obj) >= 0) {
        return '[Circular]';
    }

    function inspect(value, from, noIndent) {
        if (from) {
            seen = $arrSlice.call(seen);
            seen.push(from);
        }
        if (noIndent) {
            var newOpts = {
                depth: opts.depth
            };
            if (has(opts, 'quoteStyle')) {
                newOpts.quoteStyle = opts.quoteStyle;
            }
            return inspect_(value, newOpts, depth + 1, seen);
        }
        return inspect_(value, opts, depth + 1, seen);
    }

    if (typeof obj === 'function' && !isRegExp(obj)) { // in older engines, regexes are callable
        var name = nameOf(obj);
        var keys = arrObjKeys(obj, inspect);
        return '[Function' + (name ? ': ' + name : ' (anonymous)') + ']' + (keys.length > 0 ? ' { ' + $join.call(keys, ', ') + ' }' : '');
    }
    if (isSymbol(obj)) {
        var symString = hasShammedSymbols ? $replace.call(String(obj), /^(Symbol\(.*\))_[^)]*$/, '$1') : symToString.call(obj);
        return typeof obj === 'object' && !hasShammedSymbols ? markBoxed(symString) : symString;
    }
    if (isElement(obj)) {
        var s = '<' + $toLowerCase.call(String(obj.nodeName));
        var attrs = obj.attributes || [];
        for (var i = 0; i < attrs.length; i++) {
            s += ' ' + attrs[i].name + '=' + wrapQuotes(quote(attrs[i].value), 'double', opts);
        }
        s += '>';
        if (obj.childNodes && obj.childNodes.length) { s += '...'; }
        s += '</' + $toLowerCase.call(String(obj.nodeName)) + '>';
        return s;
    }
    if (isArray(obj)) {
        if (obj.length === 0) { return '[]'; }
        var xs = arrObjKeys(obj, inspect);
        if (indent && !singleLineValues(xs)) {
            return '[' + indentedJoin(xs, indent) + ']';
        }
        return '[ ' + $join.call(xs, ', ') + ' ]';
    }
    if (isError(obj)) {
        var parts = arrObjKeys(obj, inspect);
        if (!('cause' in Error.prototype) && 'cause' in obj && !isEnumerable.call(obj, 'cause')) {
            return '{ [' + String(obj) + '] ' + $join.call($concat.call('[cause]: ' + inspect(obj.cause), parts), ', ') + ' }';
        }
        if (parts.length === 0) { return '[' + String(obj) + ']'; }
        return '{ [' + String(obj) + '] ' + $join.call(parts, ', ') + ' }';
    }
    if (typeof obj === 'object' && customInspect) {
        if (inspectSymbol && typeof obj[inspectSymbol] === 'function' && utilInspect) {
            return utilInspect(obj, { depth: maxDepth - depth });
        } else if (customInspect !== 'symbol' && typeof obj.inspect === 'function') {
            return obj.inspect();
        }
    }
    if (isMap(obj)) {
        var mapParts = [];
        if (mapForEach) {
            mapForEach.call(obj, function (value, key) {
                mapParts.push(inspect(key, obj, true) + ' => ' + inspect(value, obj));
            });
        }
        return collectionOf('Map', mapSize.call(obj), mapParts, indent);
    }
    if (isSet(obj)) {
        var setParts = [];
        if (setForEach) {
            setForEach.call(obj, function (value) {
                setParts.push(inspect(value, obj));
            });
        }
        return collectionOf('Set', setSize.call(obj), setParts, indent);
    }
    if (isWeakMap(obj)) {
        return weakCollectionOf('WeakMap');
    }
    if (isWeakSet(obj)) {
        return weakCollectionOf('WeakSet');
    }
    if (isWeakRef(obj)) {
        return weakCollectionOf('WeakRef');
    }
    if (isNumber(obj)) {
        return markBoxed(inspect(Number(obj)));
    }
    if (isBigInt(obj)) {
        return markBoxed(inspect(bigIntValueOf.call(obj)));
    }
    if (isBoolean(obj)) {
        return markBoxed(booleanValueOf.call(obj));
    }
    if (isString(obj)) {
        return markBoxed(inspect(String(obj)));
    }
    // note: in IE 8, sometimes `global !== window` but both are the prototypes of each other
    /* eslint-env browser */
    if (typeof window !== 'undefined' && obj === window) {
        return '{ [object Window] }';
    }
    if (
        (typeof globalThis !== 'undefined' && obj === globalThis)
        || (typeof global !== 'undefined' && obj === global)
    ) {
        return '{ [object globalThis] }';
    }
    if (!isDate(obj) && !isRegExp(obj)) {
        var ys = arrObjKeys(obj, inspect);
        var isPlainObject = gPO ? gPO(obj) === Object.prototype : obj instanceof Object || obj.constructor === Object;
        var protoTag = obj instanceof Object ? '' : 'null prototype';
        var stringTag = !isPlainObject && toStringTag && Object(obj) === obj && toStringTag in obj ? $slice.call(toStr(obj), 8, -1) : protoTag ? 'Object' : '';
        var constructorTag = isPlainObject || typeof obj.constructor !== 'function' ? '' : obj.constructor.name ? obj.constructor.name + ' ' : '';
        var tag = constructorTag + (stringTag || protoTag ? '[' + $join.call($concat.call([], stringTag || [], protoTag || []), ': ') + '] ' : '');
        if (ys.length === 0) { return tag + '{}'; }
        if (indent) {
            return tag + '{' + indentedJoin(ys, indent) + '}';
        }
        return tag + '{ ' + $join.call(ys, ', ') + ' }';
    }
    return String(obj);
};

function wrapQuotes(s, defaultStyle, opts) {
    var style = opts.quoteStyle || defaultStyle;
    var quoteChar = quotes[style];
    return quoteChar + s + quoteChar;
}

function quote(s) {
    return $replace.call(String(s), /"/g, '&quot;');
}

function canTrustToString(obj) {
    return !toStringTag || !(typeof obj === 'object' && (toStringTag in obj || typeof obj[toStringTag] !== 'undefined'));
}
function isArray(obj) { return toStr(obj) === '[object Array]' && canTrustToString(obj); }
function isDate(obj) { return toStr(obj) === '[object Date]' && canTrustToString(obj); }
function isRegExp(obj) { return toStr(obj) === '[object RegExp]' && canTrustToString(obj); }
function isError(obj) { return toStr(obj) === '[object Error]' && canTrustToString(obj); }
function isString(obj) { return toStr(obj) === '[object String]' && canTrustToString(obj); }
function isNumber(obj) { return toStr(obj) === '[object Number]' && canTrustToString(obj); }
function isBoolean(obj) { return toStr(obj) === '[object Boolean]' && canTrustToString(obj); }

// Symbol and BigInt do have Symbol.toStringTag by spec, so that can't be used to eliminate false positives
function isSymbol(obj) {
    if (hasShammedSymbols) {
        return obj && typeof obj === 'object' && obj instanceof Symbol;
    }
    if (typeof obj === 'symbol') {
        return true;
    }
    if (!obj || typeof obj !== 'object' || !symToString) {
        return false;
    }
    try {
        symToString.call(obj);
        return true;
    } catch (e) {}
    return false;
}

function isBigInt(obj) {
    if (!obj || typeof obj !== 'object' || !bigIntValueOf) {
        return false;
    }
    try {
        bigIntValueOf.call(obj);
        return true;
    } catch (e) {}
    return false;
}

var hasOwn = Object.prototype.hasOwnProperty || function (key) { return key in this; };
function has(obj, key) {
    return hasOwn.call(obj, key);
}

function toStr(obj) {
    return objectToString.call(obj);
}

function nameOf(f) {
    if (f.name) { return f.name; }
    var m = $match.call(functionToString.call(f), /^function\s*([\w$]+)/);
    if (m) { return m[1]; }
    return null;
}

function indexOf(xs, x) {
    if (xs.indexOf) { return xs.indexOf(x); }
    for (var i = 0, l = xs.length; i < l; i++) {
        if (xs[i] === x) { return i; }
    }
    return -1;
}

function isMap(x) {
    if (!mapSize || !x || typeof x !== 'object') {
        return false;
    }
    try {
        mapSize.call(x);
        try {
            setSize.call(x);
        } catch (s) {
            return true;
        }
        return x instanceof Map; // core-js workaround, pre-v2.5.0
    } catch (e) {}
    return false;
}

function isWeakMap(x) {
    if (!weakMapHas || !x || typeof x !== 'object') {
        return false;
    }
    try {
        weakMapHas.call(x, weakMapHas);
        try {
            weakSetHas.call(x, weakSetHas);
        } catch (s) {
            return true;
        }
        return x instanceof WeakMap; // core-js workaround, pre-v2.5.0
    } catch (e) {}
    return false;
}

function isWeakRef(x) {
    if (!weakRefDeref || !x || typeof x !== 'object') {
        return false;
    }
    try {
        weakRefDeref.call(x);
        return true;
    } catch (e) {}
    return false;
}

function isSet(x) {
    if (!setSize || !x || typeof x !== 'object') {
        return false;
    }
    try {
        setSize.call(x);
        try {
            mapSize.call(x);
        } catch (m) {
            return true;
        }
        return x instanceof Set; // core-js workaround, pre-v2.5.0
    } catch (e) {}
    return false;
}

function isWeakSet(x) {
    if (!weakSetHas || !x || typeof x !== 'object') {
        return false;
    }
    try {
        weakSetHas.call(x, weakSetHas);
        try {
            weakMapHas.call(x, weakMapHas);
        } catch (s) {
            return true;
        }
        return x instanceof WeakSet; // core-js workaround, pre-v2.5.0
    } catch (e) {}
    return false;
}

function isElement(x) {
    if (!x || typeof x !== 'object') { return false; }
    if (typeof HTMLElement !== 'undefined' && x instanceof HTMLElement) {
        return true;
    }
    return typeof x.nodeName === 'string' && typeof x.getAttribute === 'function';
}

function inspectString(str, opts) {
    if (str.length > opts.maxStringLength) {
        var remaining = str.length - opts.maxStringLength;
        var trailer = '... ' + remaining + ' more character' + (remaining > 1 ? 's' : '');
        return inspectString($slice.call(str, 0, opts.maxStringLength), opts) + trailer;
    }
    var quoteRE = quoteREs[opts.quoteStyle || 'single'];
    quoteRE.lastIndex = 0;
    // eslint-disable-next-line no-control-regex
    var s = $replace.call($replace.call(str, quoteRE, '\\$1'), /[\x00-\x1f]/g, lowbyte);
    return wrapQuotes(s, 'single', opts);
}

function lowbyte(c) {
    var n = c.charCodeAt(0);
    var x = {
        8: 'b',
        9: 't',
        10: 'n',
        12: 'f',
        13: 'r'
    }[n];
    if (x) { return '\\' + x; }
    return '\\x' + (n < 0x10 ? '0' : '') + $toUpperCase.call(n.toString(16));
}

function markBoxed(str) {
    return 'Object(' + str + ')';
}

function weakCollectionOf(type) {
    return type + ' { ? }';
}

function collectionOf(type, size, entries, indent) {
    var joinedEntries = indent ? indentedJoin(entries, indent) : $join.call(entries, ', ');
    return type + ' (' + size + ') {' + joinedEntries + '}';
}

function singleLineValues(xs) {
    for (var i = 0; i < xs.length; i++) {
        if (indexOf(xs[i], '\n') >= 0) {
            return false;
        }
    }
    return true;
}

function getIndent(opts, depth) {
    var baseIndent;
    if (opts.indent === '\t') {
        baseIndent = '\t';
    } else if (typeof opts.indent === 'number' && opts.indent > 0) {
        baseIndent = $join.call(Array(opts.indent + 1), ' ');
    } else {
        return null;
    }
    return {
        base: baseIndent,
        prev: $join.call(Array(depth + 1), baseIndent)
    };
}

function indentedJoin(xs, indent) {
    if (xs.length === 0) { return ''; }
    var lineJoiner = '\n' + indent.prev + indent.base;
    return lineJoiner + $join.call(xs, ',' + lineJoiner) + '\n' + indent.prev;
}

function arrObjKeys(obj, inspect) {
    var isArr = isArray(obj);
    var xs = [];
    if (isArr) {
        xs.length = obj.length;
        for (var i = 0; i < obj.length; i++) {
            xs[i] = has(obj, i) ? inspect(obj[i], obj) : '';
        }
    }
    var syms = typeof gOPS === 'function' ? gOPS(obj) : [];
    var symMap;
    if (hasShammedSymbols) {
        symMap = {};
        for (var k = 0; k < syms.length; k++) {
            symMap['$' + syms[k]] = syms[k];
        }
    }

    for (var key in obj) { // eslint-disable-line no-restricted-syntax
        if (!has(obj, key)) { continue; } // eslint-disable-line no-restricted-syntax, no-continue
        if (isArr && String(Number(key)) === key && key < obj.length) { continue; } // eslint-disable-line no-restricted-syntax, no-continue
        if (hasShammedSymbols && symMap['$' + key] instanceof Symbol) {
            // this is to prevent shammed Symbols, which are stored as strings, from being included in the string key section
            continue; // eslint-disable-line no-restricted-syntax, no-continue
        } else if ($test.call(/[^\w$]/, key)) {
            xs.push(inspect(key, obj) + ': ' + inspect(obj[key], obj));
        } else {
            xs.push(key + ': ' + inspect(obj[key], obj));
        }
    }
    if (typeof gOPS === 'function') {
        for (var j = 0; j < syms.length; j++) {
            if (isEnumerable.call(obj, syms[j])) {
                xs.push('[' + inspect(syms[j]) + ']: ' + inspect(obj[syms[j]], obj));
            }
        }
    }
    return xs;
}

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

},{"./util.inspect":24}],66:[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":68}],67:[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":66,"./isArguments":68}],68:[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;
};

},{}],69:[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":32,"es-object-atoms":42,"has-symbols/shams":53,"object-keys":67}],70:[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":69}],71:[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; };

},{}],72:[function(require,module,exports){
(function (global){(function (){
/*! https://mths.be/punycode v1.4.1 by @mathias */
;(function(root) {

	/** Detect free variables */
	var freeExports = typeof exports == 'object' && exports &&
		!exports.nodeType && exports;
	var freeModule = typeof module == 'object' && module &&
		!module.nodeType && module;
	var freeGlobal = typeof global == 'object' && global;
	if (
		freeGlobal.global === freeGlobal ||
		freeGlobal.window === freeGlobal ||
		freeGlobal.self === freeGlobal
	) {
		root = freeGlobal;
	}

	/**
	 * The `punycode` object.
	 * @name punycode
	 * @type Object
	 */
	var punycode,

	/** Highest positive signed 32-bit float value */
	maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1

	/** Bootstring parameters */
	base = 36,
	tMin = 1,
	tMax = 26,
	skew = 38,
	damp = 700,
	initialBias = 72,
	initialN = 128, // 0x80
	delimiter = '-', // '\x2D'

	/** Regular expressions */
	regexPunycode = /^xn--/,
	regexNonASCII = /[^\x20-\x7E]/, // unprintable ASCII chars + non-ASCII chars
	regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g, // RFC 3490 separators

	/** Error messages */
	errors = {
		'overflow': 'Overflow: input needs wider integers to process',
		'not-basic': 'Illegal input >= 0x80 (not a basic code point)',
		'invalid-input': 'Invalid input'
	},

	/** Convenience shortcuts */
	baseMinusTMin = base - tMin,
	floor = Math.floor,
	stringFromCharCode = String.fromCharCode,

	/** Temporary variable */
	key;

	/*--------------------------------------------------------------------------*/

	/**
	 * A generic error utility function.
	 * @private
	 * @param {String} type The error type.
	 * @returns {Error} Throws a `RangeError` with the applicable error message.
	 */
	function error(type) {
		throw new RangeError(errors[type]);
	}

	/**
	 * A generic `Array#map` utility function.
	 * @private
	 * @param {Array} array The array to iterate over.
	 * @param {Function} callback The function that gets called for every array
	 * item.
	 * @returns {Array} A new array of values returned by the callback function.
	 */
	function map(array, fn) {
		var length = array.length;
		var result = [];
		while (length--) {
			result[length] = fn(array[length]);
		}
		return result;
	}

	/**
	 * A simple `Array#map`-like wrapper to work with domain name strings or email
	 * addresses.
	 * @private
	 * @param {String} domain The domain name or email address.
	 * @param {Function} callback The function that gets called for every
	 * character.
	 * @returns {Array} A new string of characters returned by the callback
	 * function.
	 */
	function mapDomain(string, fn) {
		var parts = string.split('@');
		var result = '';
		if (parts.length > 1) {
			// In email addresses, only the domain name should be punycoded. Leave
			// the local part (i.e. everything up to `@`) intact.
			result = parts[0] + '@';
			string = parts[1];
		}
		// Avoid `split(regex)` for IE8 compatibility. See #17.
		string = string.replace(regexSeparators, '\x2E');
		var labels = string.split('.');
		var encoded = map(labels, fn).join('.');
		return result + encoded;
	}

	/**
	 * Creates an array containing the numeric code points of each Unicode
	 * character in the string. While JavaScript uses UCS-2 internally,
	 * this function will convert a pair of surrogate halves (each of which
	 * UCS-2 exposes as separate characters) into a single code point,
	 * matching UTF-16.
	 * @see `punycode.ucs2.encode`
	 * @see <https://mathiasbynens.be/notes/javascript-encoding>
	 * @memberOf punycode.ucs2
	 * @name decode
	 * @param {String} string The Unicode input string (UCS-2).
	 * @returns {Array} The new array of code points.
	 */
	function ucs2decode(string) {
		var output = [],
		    counter = 0,
		    length = string.length,
		    value,
		    extra;
		while (counter < length) {
			value = string.charCodeAt(counter++);
			if (value >= 0xD800 && value <= 0xDBFF && counter < length) {
				// high surrogate, and there is a next character
				extra = string.charCodeAt(counter++);
				if ((extra & 0xFC00) == 0xDC00) { // low surrogate
					output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);
				} else {
					// unmatched surrogate; only append this code unit, in case the next
					// code unit is the high surrogate of a surrogate pair
					output.push(value);
					counter--;
				}
			} else {
				output.push(value);
			}
		}
		return output;
	}

	/**
	 * Creates a string based on an array of numeric code points.
	 * @see `punycode.ucs2.decode`
	 * @memberOf punycode.ucs2
	 * @name encode
	 * @param {Array} codePoints The array of numeric code points.
	 * @returns {String} The new Unicode string (UCS-2).
	 */
	function ucs2encode(array) {
		return map(array, function(value) {
			var output = '';
			if (value > 0xFFFF) {
				value -= 0x10000;
				output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800);
				value = 0xDC00 | value & 0x3FF;
			}
			output += stringFromCharCode(value);
			return output;
		}).join('');
	}

	/**
	 * Converts a basic code point into a digit/integer.
	 * @see `digitToBasic()`
	 * @private
	 * @param {Number} codePoint The basic numeric code point value.
	 * @returns {Number} The numeric value of a basic code point (for use in
	 * representing integers) in the range `0` to `base - 1`, or `base` if
	 * the code point does not represent a value.
	 */
	function basicToDigit(codePoint) {
		if (codePoint - 48 < 10) {
			return codePoint - 22;
		}
		if (codePoint - 65 < 26) {
			return codePoint - 65;
		}
		if (codePoint - 97 < 26) {
			return codePoint - 97;
		}
		return base;
	}

	/**
	 * Converts a digit/integer into a basic code point.
	 * @see `basicToDigit()`
	 * @private
	 * @param {Number} digit The numeric value of a basic code point.
	 * @returns {Number} The basic code point whose value (when used for
	 * representing integers) is `digit`, which needs to be in the range
	 * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is
	 * used; else, the lowercase form is used. The behavior is undefined
	 * if `flag` is non-zero and `digit` has no uppercase form.
	 */
	function digitToBasic(digit, flag) {
		//  0..25 map to ASCII a..z or A..Z
		// 26..35 map to ASCII 0..9
		return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5);
	}

	/**
	 * Bias adaptation function as per section 3.4 of RFC 3492.
	 * https://tools.ietf.org/html/rfc3492#section-3.4
	 * @private
	 */
	function adapt(delta, numPoints, firstTime) {
		var k = 0;
		delta = firstTime ? floor(delta / damp) : delta >> 1;
		delta += floor(delta / numPoints);
		for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) {
			delta = floor(delta / baseMinusTMin);
		}
		return floor(k + (baseMinusTMin + 1) * delta / (delta + skew));
	}

	/**
	 * Converts a Punycode string of ASCII-only symbols to a string of Unicode
	 * symbols.
	 * @memberOf punycode
	 * @param {String} input The Punycode string of ASCII-only symbols.
	 * @returns {String} The resulting string of Unicode symbols.
	 */
	function decode(input) {
		// Don't use UCS-2
		var output = [],
		    inputLength = input.length,
		    out,
		    i = 0,
		    n = initialN,
		    bias = initialBias,
		    basic,
		    j,
		    index,
		    oldi,
		    w,
		    k,
		    digit,
		    t,
		    /** Cached calculation results */
		    baseMinusT;

		// Handle the basic code points: let `basic` be the number of input code
		// points before the last delimiter, or `0` if there is none, then copy
		// the first basic code points to the output.

		basic = input.lastIndexOf(delimiter);
		if (basic < 0) {
			basic = 0;
		}

		for (j = 0; j < basic; ++j) {
			// if it's not a basic code point
			if (input.charCodeAt(j) >= 0x80) {
				error('not-basic');
			}
			output.push(input.charCodeAt(j));
		}

		// Main decoding loop: start just after the last delimiter if any basic code
		// points were copied; start at the beginning otherwise.

		for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) {

			// `index` is the index of the next character to be consumed.
			// Decode a generalized variable-length integer into `delta`,
			// which gets added to `i`. The overflow checking is easier
			// if we increase `i` as we go, then subtract off its starting
			// value at the end to obtain `delta`.
			for (oldi = i, w = 1, k = base; /* no condition */; k += base) {

				if (index >= inputLength) {
					error('invalid-input');
				}

				digit = basicToDigit(input.charCodeAt(index++));

				if (digit >= base || digit > floor((maxInt - i) / w)) {
					error('overflow');
				}

				i += digit * w;
				t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);

				if (digit < t) {
					break;
				}

				baseMinusT = base - t;
				if (w > floor(maxInt / baseMinusT)) {
					error('overflow');
				}

				w *= baseMinusT;

			}

			out = output.length + 1;
			bias = adapt(i - oldi, out, oldi == 0);

			// `i` was supposed to wrap around from `out` to `0`,
			// incrementing `n` each time, so we'll fix that now:
			if (floor(i / out) > maxInt - n) {
				error('overflow');
			}

			n += floor(i / out);
			i %= out;

			// Insert `n` at position `i` of the output
			output.splice(i++, 0, n);

		}

		return ucs2encode(output);
	}

	/**
	 * Converts a string of Unicode symbols (e.g. a domain name label) to a
	 * Punycode string of ASCII-only symbols.
	 * @memberOf punycode
	 * @param {String} input The string of Unicode symbols.
	 * @returns {String} The resulting Punycode string of ASCII-only symbols.
	 */
	function encode(input) {
		var n,
		    delta,
		    handledCPCount,
		    basicLength,
		    bias,
		    j,
		    m,
		    q,
		    k,
		    t,
		    currentValue,
		    output = [],
		    /** `inputLength` will hold the number of code points in `input`. */
		    inputLength,
		    /** Cached calculation results */
		    handledCPCountPlusOne,
		    baseMinusT,
		    qMinusT;

		// Convert the input in UCS-2 to Unicode
		input = ucs2decode(input);

		// Cache the length
		inputLength = input.length;

		// Initialize the state
		n = initialN;
		delta = 0;
		bias = initialBias;

		// Handle the basic code points
		for (j = 0; j < inputLength; ++j) {
			currentValue = input[j];
			if (currentValue < 0x80) {
				output.push(stringFromCharCode(currentValue));
			}
		}

		handledCPCount = basicLength = output.length;

		// `handledCPCount` is the number of code points that have been handled;
		// `basicLength` is the number of basic code points.

		// Finish the basic string - if it is not empty - with a delimiter
		if (basicLength) {
			output.push(delimiter);
		}

		// Main encoding loop:
		while (handledCPCount < inputLength) {

			// All non-basic code points < n have been handled already. Find the next
			// larger one:
			for (m = maxInt, j = 0; j < inputLength; ++j) {
				currentValue = input[j];
				if (currentValue >= n && currentValue < m) {
					m = currentValue;
				}
			}

			// Increase `delta` enough to advance the decoder's <n,i> state to <m,0>,
			// but guard against overflow
			handledCPCountPlusOne = handledCPCount + 1;
			if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) {
				error('overflow');
			}

			delta += (m - n) * handledCPCountPlusOne;
			n = m;

			for (j = 0; j < inputLength; ++j) {
				currentValue = input[j];

				if (currentValue < n && ++delta > maxInt) {
					error('overflow');
				}

				if (currentValue == n) {
					// Represent delta as a generalized variable-length integer
					for (q = delta, k = base; /* no condition */; k += base) {
						t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
						if (q < t) {
							break;
						}
						qMinusT = q - t;
						baseMinusT = base - t;
						output.push(
							stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0))
						);
						q = floor(qMinusT / baseMinusT);
					}

					output.push(stringFromCharCode(digitToBasic(q, 0)));
					bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength);
					delta = 0;
					++handledCPCount;
				}
			}

			++delta;
			++n;

		}
		return output.join('');
	}

	/**
	 * Converts a Punycode string representing a domain name or an email address
	 * to Unicode. Only the Punycoded parts of the input will be converted, i.e.
	 * it doesn't matter if you call it on a string that has already been
	 * converted to Unicode.
	 * @memberOf punycode
	 * @param {String} input The Punycoded domain name or email address to
	 * convert to Unicode.
	 * @returns {String} The Unicode representation of the given Punycode
	 * string.
	 */
	function toUnicode(input) {
		return mapDomain(input, function(string) {
			return regexPunycode.test(string)
				? decode(string.slice(4).toLowerCase())
				: string;
		});
	}

	/**
	 * Converts a Unicode string representing a domain name or an email address to
	 * Punycode. Only the non-ASCII parts of the domain name will be converted,
	 * i.e. it doesn't matter if you call it with a domain that's already in
	 * ASCII.
	 * @memberOf punycode
	 * @param {String} input The domain name or email address to convert, as a
	 * Unicode string.
	 * @returns {String} The Punycode representation of the given domain name or
	 * email address.
	 */
	function toASCII(input) {
		return mapDomain(input, function(string) {
			return regexNonASCII.test(string)
				? 'xn--' + encode(string)
				: string;
		});
	}

	/*--------------------------------------------------------------------------*/

	/** Define the public API */
	punycode = {
		/**
		 * A string representing the current Punycode.js version number.
		 * @memberOf punycode
		 * @type String
		 */
		'version': '1.4.1',
		/**
		 * An object of methods to convert from JavaScript's internal character
		 * representation (UCS-2) to Unicode code points, and back.
		 * @see <https://mathiasbynens.be/notes/javascript-encoding>
		 * @memberOf punycode
		 * @type Object
		 */
		'ucs2': {
			'decode': ucs2decode,
			'encode': ucs2encode
		},
		'decode': decode,
		'encode': encode,
		'toASCII': toASCII,
		'toUnicode': toUnicode
	};

	/** Expose `punycode` */
	// Some AMD build optimizers, like r.js, check for specific condition patterns
	// like the following:
	if (
		typeof define == 'function' &&
		typeof define.amd == 'object' &&
		define.amd
	) {
		define('punycode', function() {
			return punycode;
		});
	} else if (freeExports && freeModule) {
		if (module.exports == freeExports) {
			// in Node.js, io.js, or RingoJS v0.8.0+
			freeModule.exports = punycode;
		} else {
			// in Narwhal or RingoJS v0.7.0-
			for (key in punycode) {
				punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]);
			}
		}
	} else {
		// in Rhino or a web browser
		root.punycode = punycode;
	}

}(this));

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

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

var replace = String.prototype.replace;
var percentTwenties = /%20/g;

var Format = {
    RFC1738: 'RFC1738',
    RFC3986: 'RFC3986'
};

module.exports = {
    'default': Format.RFC3986,
    formatters: {
        RFC1738: function (value) {
            return replace.call(value, percentTwenties, '+');
        },
        RFC3986: function (value) {
            return String(value);
        }
    },
    RFC1738: Format.RFC1738,
    RFC3986: Format.RFC3986
};

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

var stringify = require('./stringify');
var parse = require('./parse');
var formats = require('./formats');

module.exports = {
    formats: formats,
    parse: parse,
    stringify: stringify
};

},{"./formats":73,"./parse":75,"./stringify":76}],75:[function(require,module,exports){
'use strict';

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

var has = Object.prototype.hasOwnProperty;
var isArray = Array.isArray;

var defaults = {
    allowDots: false,
    allowEmptyArrays: false,
    allowPrototypes: false,
    allowSparse: false,
    arrayLimit: 20,
    charset: 'utf-8',
    charsetSentinel: false,
    comma: false,
    decodeDotInKeys: false,
    decoder: utils.decode,
    delimiter: '&',
    depth: 5,
    duplicates: 'combine',
    ignoreQueryPrefix: false,
    interpretNumericEntities: false,
    parameterLimit: 1000,
    parseArrays: true,
    plainObjects: false,
    strictDepth: false,
    strictMerge: true,
    strictNullHandling: false,
    throwOnLimitExceeded: false
};

var interpretNumericEntities = function (str) {
    return str.replace(/&#(\d+);/g, function ($0, numberStr) {
        return String.fromCharCode(parseInt(numberStr, 10));
    });
};

var parseArrayValue = function (val, options, currentArrayLength) {
    if (val && typeof val === 'string' && options.comma && val.indexOf(',') > -1) {
        return val.split(',');
    }

    if (options.throwOnLimitExceeded && currentArrayLength >= options.arrayLimit) {
        throw new RangeError('Array limit exceeded. Only ' + options.arrayLimit + ' element' + (options.arrayLimit === 1 ? '' : 's') + ' allowed in an array.');
    }

    return val;
};

// This is what browsers will submit when the ✓ character occurs in an
// application/x-www-form-urlencoded body and the encoding of the page containing
// the form is iso-8859-1, or when the submitted form has an accept-charset
// attribute of iso-8859-1. Presumably also with other charsets that do not contain
// the ✓ character, such as us-ascii.
var isoSentinel = 'utf8=%26%2310003%3B'; // encodeURIComponent('&#10003;')

// These are the percent-encoded utf-8 octets representing a checkmark, indicating that the request actually is utf-8 encoded.
var charsetSentinel = 'utf8=%E2%9C%93'; // encodeURIComponent('✓')

var parseValues = function parseQueryStringValues(str, options) {
    var obj = { __proto__: null };

    var cleanStr = options.ignoreQueryPrefix ? str.replace(/^\?/, '') : str;
    cleanStr = cleanStr.replace(/%5B/gi, '[').replace(/%5D/gi, ']');

    var limit = options.parameterLimit === Infinity ? void undefined : options.parameterLimit;
    var parts = cleanStr.split(
        options.delimiter,
        options.throwOnLimitExceeded && typeof limit !== 'undefined' ? limit + 1 : limit
    );

    if (options.throwOnLimitExceeded && typeof limit !== 'undefined' && parts.length > limit) {
        throw new RangeError('Parameter limit exceeded. Only ' + limit + ' parameter' + (limit === 1 ? '' : 's') + ' allowed.');
    }

    var skipIndex = -1; // Keep track of where the utf8 sentinel was found
    var i;

    var charset = options.charset;
    if (options.charsetSentinel) {
        for (i = 0; i < parts.length; ++i) {
            if (parts[i].indexOf('utf8=') === 0) {
                if (parts[i] === charsetSentinel) {
                    charset = 'utf-8';
                } else if (parts[i] === isoSentinel) {
                    charset = 'iso-8859-1';
                }
                skipIndex = i;
                i = parts.length; // The eslint settings do not allow break;
            }
        }
    }

    for (i = 0; i < parts.length; ++i) {
        if (i === skipIndex) {
            continue;
        }
        var part = parts[i];

        var bracketEqualsPos = part.indexOf(']=');
        var pos = bracketEqualsPos === -1 ? part.indexOf('=') : bracketEqualsPos + 1;

        var key;
        var val;
        if (pos === -1) {
            key = options.decoder(part, defaults.decoder, charset, 'key');
            val = options.strictNullHandling ? null : '';
        } else {
            key = options.decoder(part.slice(0, pos), defaults.decoder, charset, 'key');

            if (key !== null) {
                val = utils.maybeMap(
                    parseArrayValue(
                        part.slice(pos + 1),
                        options,
                        isArray(obj[key]) ? obj[key].length : 0
                    ),
                    function (encodedVal) {
                        return options.decoder(encodedVal, defaults.decoder, charset, 'value');
                    }
                );
            }
        }

        if (val && options.interpretNumericEntities && charset === 'iso-8859-1') {
            val = interpretNumericEntities(String(val));
        }

        if (part.indexOf('[]=') > -1) {
            val = isArray(val) ? [val] : val;
        }

        if (options.comma && isArray(val) && val.length > options.arrayLimit) {
            if (options.throwOnLimitExceeded) {
                throw new RangeError('Array limit exceeded. Only ' + options.arrayLimit + ' element' + (options.arrayLimit === 1 ? '' : 's') + ' allowed in an array.');
            }
            val = utils.combine([], val, options.arrayLimit, options.plainObjects);
        }

        if (key !== null) {
            var existing = has.call(obj, key);
            if (existing && (options.duplicates === 'combine' || part.indexOf('[]=') > -1)) {
                obj[key] = utils.combine(
                    obj[key],
                    val,
                    options.arrayLimit,
                    options.plainObjects
                );
            } else if (!existing || options.duplicates === 'last') {
                obj[key] = val;
            }
        }
    }

    return obj;
};

var parseObject = function (chain, val, options, valuesParsed) {
    var currentArrayLength = 0;
    if (chain.length > 0 && chain[chain.length - 1] === '[]') {
        var parentKey = chain.slice(0, -1).join('');
        currentArrayLength = Array.isArray(val) && val[parentKey] ? val[parentKey].length : 0;
    }

    var leaf = valuesParsed ? val : parseArrayValue(val, options, currentArrayLength);

    for (var i = chain.length - 1; i >= 0; --i) {
        var obj;
        var root = chain[i];

        if (root === '[]' && options.parseArrays) {
            if (utils.isOverflow(leaf)) {
                // leaf is already an overflow object, preserve it
                obj = leaf;
            } else {
                obj = options.allowEmptyArrays && (leaf === '' || (options.strictNullHandling && leaf === null))
                    ? []
                    : utils.combine(
                        [],
                        leaf,
                        options.arrayLimit,
                        options.plainObjects
                    );
            }
        } else {
            obj = options.plainObjects ? { __proto__: null } : {};
            var cleanRoot = root.charAt(0) === '[' && root.charAt(root.length - 1) === ']' ? root.slice(1, -1) : root;
            var decodedRoot = options.decodeDotInKeys ? cleanRoot.replace(/%2E/g, '.') : cleanRoot;
            var index = parseInt(decodedRoot, 10);
            var isValidArrayIndex = !isNaN(index)
                && root !== decodedRoot
                && String(index) === decodedRoot
                && index >= 0
                && options.parseArrays;
            if (!options.parseArrays && decodedRoot === '') {
                obj = { 0: leaf };
            } else if (isValidArrayIndex && index < options.arrayLimit) {
                obj = [];
                obj[index] = leaf;
            } else if (isValidArrayIndex && options.throwOnLimitExceeded) {
                throw new RangeError('Array limit exceeded. Only ' + options.arrayLimit + ' element' + (options.arrayLimit === 1 ? '' : 's') + ' allowed in an array.');
            } else if (isValidArrayIndex) {
                obj[index] = leaf;
                utils.markOverflow(obj, index);
            } else if (decodedRoot !== '__proto__') {
                obj[decodedRoot] = leaf;
            }
        }

        leaf = obj;
    }

    return leaf;
};

// Split a key like "a[b][c[]]" into ['a', '[b]', '[c[]]'] while preserving
// qs parse semantics for depth/prototype guards.
var splitKeyIntoSegments = function splitKeyIntoSegments(originalKey, options) {
    var key = options.allowDots ? originalKey.replace(/\.([^.[]+)/g, '[$1]') : originalKey;

    // depth <= 0 keeps the whole key as one segment
    if (options.depth <= 0) {
        if (!options.plainObjects && has.call(Object.prototype, key)) {
            if (!options.allowPrototypes) {
                return;
            }
        }

        return [key];
    }

    var segments = [];

    // parent before the first '[' (may be empty if key starts with '[')
    var first = key.indexOf('[');
    var parent = first >= 0 ? key.slice(0, first) : key;
    if (parent) {
        if (!options.plainObjects && has.call(Object.prototype, parent)) {
            if (!options.allowPrototypes) {
                return;
            }
        }

        segments[segments.length] = parent;
    }

    var n = key.length;
    var open = first;
    var collected = 0;

    while (open >= 0 && collected < options.depth) {
        var level = 1;
        var i = open + 1;
        var close = -1;

        // balance nested '[' and ']' inside this bracket group using a nesting level counter
        while (i < n && close < 0) {
            var cu = key.charCodeAt(i);
            if (cu === 0x5B) { // '['
                level += 1;
            } else if (cu === 0x5D) { // ']'
                level -= 1;
                if (level === 0) {
                    close = i; // found matching close; loop will exit by condition
                }
            }
            i += 1;
        }

        if (close < 0) {
            // Unterminated group: wrap the raw remainder in one bracket pair so it stays
            // a single literal segment (e.g. "[[]b" -> "[[]b]"); we do not infer missing ']'.
            segments[segments.length] = '[' + key.slice(open) + ']';
            return segments;
        }

        var seg = key.slice(open, close + 1);
        // prototype guard for the content of this group
        var content = seg.slice(1, -1);
        if (!options.plainObjects && has.call(Object.prototype, content) && !options.allowPrototypes) {
            return;
        }

        segments[segments.length] = seg;
        collected += 1;

        // find the next '[' after this balanced group
        open = key.indexOf('[', close + 1);
    }

    if (open >= 0) {
        if (options.strictDepth === true) {
            throw new RangeError('Input depth exceeded depth option of ' + options.depth + ' and strictDepth is true');
        }

        segments[segments.length] = '[' + key.slice(open) + ']';
    }

    return segments;
};

var parseKeys = function parseQueryStringKeys(givenKey, val, options, valuesParsed) {
    if (!givenKey) {
        return;
    }

    var keys = splitKeyIntoSegments(givenKey, options);

    if (!keys) {
        return;
    }

    return parseObject(keys, val, options, valuesParsed);
};

var normalizeParseOptions = function normalizeParseOptions(opts) {
    if (!opts) {
        return defaults;
    }

    if (typeof opts.allowEmptyArrays !== 'undefined' && typeof opts.allowEmptyArrays !== 'boolean') {
        throw new TypeError('`allowEmptyArrays` option can only be `true` or `false`, when provided');
    }

    if (typeof opts.decodeDotInKeys !== 'undefined' && typeof opts.decodeDotInKeys !== 'boolean') {
        throw new TypeError('`decodeDotInKeys` option can only be `true` or `false`, when provided');
    }

    if (opts.decoder !== null && typeof opts.decoder !== 'undefined' && typeof opts.decoder !== 'function') {
        throw new TypeError('Decoder has to be a function.');
    }

    if (typeof opts.charset !== 'undefined' && opts.charset !== 'utf-8' && opts.charset !== 'iso-8859-1') {
        throw new TypeError('The charset option must be either utf-8, iso-8859-1, or undefined');
    }

    if (typeof opts.throwOnLimitExceeded !== 'undefined' && typeof opts.throwOnLimitExceeded !== 'boolean') {
        throw new TypeError('`throwOnLimitExceeded` option must be a boolean');
    }

    var charset = typeof opts.charset === 'undefined' ? defaults.charset : opts.charset;

    var duplicates = typeof opts.duplicates === 'undefined' ? defaults.duplicates : opts.duplicates;

    if (duplicates !== 'combine' && duplicates !== 'first' && duplicates !== 'last') {
        throw new TypeError('The duplicates option must be either combine, first, or last');
    }

    var allowDots = typeof opts.allowDots === 'undefined' ? opts.decodeDotInKeys === true ? true : defaults.allowDots : !!opts.allowDots;

    return {
        allowDots: allowDots,
        allowEmptyArrays: typeof opts.allowEmptyArrays === 'boolean' ? !!opts.allowEmptyArrays : defaults.allowEmptyArrays,
        allowPrototypes: typeof opts.allowPrototypes === 'boolean' ? opts.allowPrototypes : defaults.allowPrototypes,
        allowSparse: typeof opts.allowSparse === 'boolean' ? opts.allowSparse : defaults.allowSparse,
        arrayLimit: typeof opts.arrayLimit === 'number' ? opts.arrayLimit : defaults.arrayLimit,
        charset: charset,
        charsetSentinel: typeof opts.charsetSentinel === 'boolean' ? opts.charsetSentinel : defaults.charsetSentinel,
        comma: typeof opts.comma === 'boolean' ? opts.comma : defaults.comma,
        decodeDotInKeys: typeof opts.decodeDotInKeys === 'boolean' ? opts.decodeDotInKeys : defaults.decodeDotInKeys,
        decoder: typeof opts.decoder === 'function' ? opts.decoder : defaults.decoder,
        delimiter: typeof opts.delimiter === 'string' || utils.isRegExp(opts.delimiter) ? opts.delimiter : defaults.delimiter,
        // eslint-disable-next-line no-implicit-coercion, no-extra-parens
        depth: (typeof opts.depth === 'number' || opts.depth === false) ? +opts.depth : defaults.depth,
        duplicates: duplicates,
        ignoreQueryPrefix: opts.ignoreQueryPrefix === true,
        interpretNumericEntities: typeof opts.interpretNumericEntities === 'boolean' ? opts.interpretNumericEntities : defaults.interpretNumericEntities,
        parameterLimit: typeof opts.parameterLimit === 'number' ? opts.parameterLimit : defaults.parameterLimit,
        parseArrays: opts.parseArrays !== false,
        plainObjects: typeof opts.plainObjects === 'boolean' ? opts.plainObjects : defaults.plainObjects,
        strictDepth: typeof opts.strictDepth === 'boolean' ? !!opts.strictDepth : defaults.strictDepth,
        strictMerge: typeof opts.strictMerge === 'boolean' ? !!opts.strictMerge : defaults.strictMerge,
        strictNullHandling: typeof opts.strictNullHandling === 'boolean' ? opts.strictNullHandling : defaults.strictNullHandling,
        throwOnLimitExceeded: typeof opts.throwOnLimitExceeded === 'boolean' ? opts.throwOnLimitExceeded : false
    };
};

module.exports = function (str, opts) {
    var options = normalizeParseOptions(opts);

    if (str === '' || str === null || typeof str === 'undefined') {
        return options.plainObjects ? { __proto__: null } : {};
    }

    var tempObj = typeof str === 'string' ? parseValues(str, options) : str;
    var obj = options.plainObjects ? { __proto__: null } : {};

    // Iterate over the keys and setup the new object

    var keys = Object.keys(tempObj);
    for (var i = 0; i < keys.length; ++i) {
        var key = keys[i];
        var newObj = parseKeys(key, tempObj[key], options, typeof str === 'string');
        obj = utils.merge(obj, newObj, options);
    }

    if (options.allowSparse === true) {
        return obj;
    }

    return utils.compact(obj);
};

},{"./utils":77}],76:[function(require,module,exports){
'use strict';

var getSideChannel = require('side-channel');
var utils = require('./utils');
var formats = require('./formats');
var has = Object.prototype.hasOwnProperty;

var arrayPrefixGenerators = {
    brackets: function brackets(prefix) {
        return prefix + '[]';
    },
    comma: 'comma',
    indices: function indices(prefix, key) {
        return prefix + '[' + key + ']';
    },
    repeat: function repeat(prefix) {
        return prefix;
    }
};

var isArray = Array.isArray;
var push = Array.prototype.push;
var pushToArray = function (arr, valueOrArray) {
    push.apply(arr, isArray(valueOrArray) ? valueOrArray : [valueOrArray]);
};

var toISO = Date.prototype.toISOString;

var defaultFormat = formats['default'];
var defaults = {
    addQueryPrefix: false,
    allowDots: false,
    allowEmptyArrays: false,
    arrayFormat: 'indices',
    charset: 'utf-8',
    charsetSentinel: false,
    commaRoundTrip: false,
    delimiter: '&',
    encode: true,
    encodeDotInKeys: false,
    encoder: utils.encode,
    encodeValuesOnly: false,
    filter: void undefined,
    format: defaultFormat,
    formatter: formats.formatters[defaultFormat],
    // deprecated
    indices: false,
    serializeDate: function serializeDate(date) {
        return toISO.call(date);
    },
    skipNulls: false,
    strictNullHandling: false
};

var isNonNullishPrimitive = function isNonNullishPrimitive(v) {
    return typeof v === 'string'
        || typeof v === 'number'
        || typeof v === 'boolean'
        || typeof v === 'symbol'
        || typeof v === 'bigint';
};

var sentinel = {};

var stringify = function stringify(
    object,
    prefix,
    generateArrayPrefix,
    commaRoundTrip,
    allowEmptyArrays,
    strictNullHandling,
    skipNulls,
    encodeDotInKeys,
    encoder,
    filter,
    sort,
    allowDots,
    serializeDate,
    format,
    formatter,
    encodeValuesOnly,
    charset,
    sideChannel
) {
    var obj = object;

    var tmpSc = sideChannel;
    var step = 0;
    var findFlag = false;
    while ((tmpSc = tmpSc.get(sentinel)) !== void undefined && !findFlag) {
        // Where object last appeared in the ref tree
        var pos = tmpSc.get(object);
        step += 1;
        if (typeof pos !== 'undefined') {
            if (pos === step) {
                throw new RangeError('Cyclic object value');
            } else {
                findFlag = true; // Break while
            }
        }
        if (typeof tmpSc.get(sentinel) === 'undefined') {
            step = 0;
        }
    }

    if (typeof filter === 'function') {
        obj = filter(prefix, obj);
    } else if (obj instanceof Date) {
        obj = serializeDate(obj);
    } else if (generateArrayPrefix === 'comma' && isArray(obj)) {
        obj = utils.maybeMap(obj, function (value) {
            if (value instanceof Date) {
                return serializeDate(value);
            }
            return value;
        });
    }

    if (obj === null) {
        if (strictNullHandling) {
            return formatter(encoder && !encodeValuesOnly ? encoder(prefix, defaults.encoder, charset, 'key', format) : prefix);
        }

        obj = '';
    }

    if (isNonNullishPrimitive(obj) || utils.isBuffer(obj)) {
        if (encoder) {
            var keyValue = encodeValuesOnly ? prefix : encoder(prefix, defaults.encoder, charset, 'key', format);
            return [formatter(keyValue) + '=' + formatter(encoder(obj, defaults.encoder, charset, 'value', format))];
        }
        return [formatter(prefix) + '=' + formatter(String(obj))];
    }

    var values = [];

    if (typeof obj === 'undefined') {
        return values;
    }

    var objKeys;
    if (generateArrayPrefix === 'comma' && isArray(obj)) {
        // we need to join elements in
        if (encodeValuesOnly && encoder) {
            obj = utils.maybeMap(obj, function (v) {
                return v == null ? v : encoder(v);
            });
        }
        objKeys = [{ value: obj.length > 0 ? obj.join(',') || null : void undefined }];
    } else if (isArray(filter)) {
        objKeys = filter;
    } else {
        var keys = Object.keys(obj);
        objKeys = sort ? keys.sort(sort) : keys;
    }

    var encodedPrefix = encodeDotInKeys ? String(prefix).replace(/\./g, '%2E') : String(prefix);

    var adjustedPrefix = commaRoundTrip && isArray(obj) && obj.length === 1 ? encodedPrefix + '[]' : encodedPrefix;

    if (allowEmptyArrays && isArray(obj) && obj.length === 0) {
        return adjustedPrefix + '[]';
    }

    for (var j = 0; j < objKeys.length; ++j) {
        var key = objKeys[j];
        var value = typeof key === 'object' && key && typeof key.value !== 'undefined'
            ? key.value
            : obj[key];

        if (skipNulls && value === null) {
            continue;
        }

        var encodedKey = allowDots && encodeDotInKeys ? String(key).replace(/\./g, '%2E') : String(key);
        var keyPrefix = isArray(obj)
            ? typeof generateArrayPrefix === 'function' ? generateArrayPrefix(adjustedPrefix, encodedKey) : adjustedPrefix
            : adjustedPrefix + (allowDots ? '.' + encodedKey : '[' + encodedKey + ']');

        sideChannel.set(object, step);
        var valueSideChannel = getSideChannel();
        valueSideChannel.set(sentinel, sideChannel);
        pushToArray(values, stringify(
            value,
            keyPrefix,
            generateArrayPrefix,
            commaRoundTrip,
            allowEmptyArrays,
            strictNullHandling,
            skipNulls,
            encodeDotInKeys,
            generateArrayPrefix === 'comma' && encodeValuesOnly && isArray(obj) ? null : encoder,
            filter,
            sort,
            allowDots,
            serializeDate,
            format,
            formatter,
            encodeValuesOnly,
            charset,
            valueSideChannel
        ));
    }

    return values;
};

var normalizeStringifyOptions = function normalizeStringifyOptions(opts) {
    if (!opts) {
        return defaults;
    }

    if (typeof opts.allowEmptyArrays !== 'undefined' && typeof opts.allowEmptyArrays !== 'boolean') {
        throw new TypeError('`allowEmptyArrays` option can only be `true` or `false`, when provided');
    }

    if (typeof opts.encodeDotInKeys !== 'undefined' && typeof opts.encodeDotInKeys !== 'boolean') {
        throw new TypeError('`encodeDotInKeys` option can only be `true` or `false`, when provided');
    }

    if (opts.encoder !== null && typeof opts.encoder !== 'undefined' && typeof opts.encoder !== 'function') {
        throw new TypeError('Encoder has to be a function.');
    }

    var charset = opts.charset || defaults.charset;
    if (typeof opts.charset !== 'undefined' && opts.charset !== 'utf-8' && opts.charset !== 'iso-8859-1') {
        throw new TypeError('The charset option must be either utf-8, iso-8859-1, or undefined');
    }

    var format = formats['default'];
    if (typeof opts.format !== 'undefined') {
        if (!has.call(formats.formatters, opts.format)) {
            throw new TypeError('Unknown format option provided.');
        }
        format = opts.format;
    }
    var formatter = formats.formatters[format];

    var filter = defaults.filter;
    if (typeof opts.filter === 'function' || isArray(opts.filter)) {
        filter = opts.filter;
    }

    var arrayFormat;
    if (opts.arrayFormat in arrayPrefixGenerators) {
        arrayFormat = opts.arrayFormat;
    } else if ('indices' in opts) {
        arrayFormat = opts.indices ? 'indices' : 'repeat';
    } else {
        arrayFormat = defaults.arrayFormat;
    }

    if ('commaRoundTrip' in opts && typeof opts.commaRoundTrip !== 'boolean') {
        throw new TypeError('`commaRoundTrip` must be a boolean, or absent');
    }

    var allowDots = typeof opts.allowDots === 'undefined' ? opts.encodeDotInKeys === true ? true : defaults.allowDots : !!opts.allowDots;

    return {
        addQueryPrefix: typeof opts.addQueryPrefix === 'boolean' ? opts.addQueryPrefix : defaults.addQueryPrefix,
        allowDots: allowDots,
        allowEmptyArrays: typeof opts.allowEmptyArrays === 'boolean' ? !!opts.allowEmptyArrays : defaults.allowEmptyArrays,
        arrayFormat: arrayFormat,
        charset: charset,
        charsetSentinel: typeof opts.charsetSentinel === 'boolean' ? opts.charsetSentinel : defaults.charsetSentinel,
        commaRoundTrip: !!opts.commaRoundTrip,
        delimiter: typeof opts.delimiter === 'undefined' ? defaults.delimiter : opts.delimiter,
        encode: typeof opts.encode === 'boolean' ? opts.encode : defaults.encode,
        encodeDotInKeys: typeof opts.encodeDotInKeys === 'boolean' ? opts.encodeDotInKeys : defaults.encodeDotInKeys,
        encoder: typeof opts.encoder === 'function' ? opts.encoder : defaults.encoder,
        encodeValuesOnly: typeof opts.encodeValuesOnly === 'boolean' ? opts.encodeValuesOnly : defaults.encodeValuesOnly,
        filter: filter,
        format: format,
        formatter: formatter,
        serializeDate: typeof opts.serializeDate === 'function' ? opts.serializeDate : defaults.serializeDate,
        skipNulls: typeof opts.skipNulls === 'boolean' ? opts.skipNulls : defaults.skipNulls,
        sort: typeof opts.sort === 'function' ? opts.sort : null,
        strictNullHandling: typeof opts.strictNullHandling === 'boolean' ? opts.strictNullHandling : defaults.strictNullHandling
    };
};

module.exports = function (object, opts) {
    var obj = object;
    var options = normalizeStringifyOptions(opts);

    var objKeys;
    var filter;

    if (typeof options.filter === 'function') {
        filter = options.filter;
        obj = filter('', obj);
    } else if (isArray(options.filter)) {
        filter = options.filter;
        objKeys = filter;
    }

    var keys = [];

    if (typeof obj !== 'object' || obj === null) {
        return '';
    }

    var generateArrayPrefix = arrayPrefixGenerators[options.arrayFormat];
    var commaRoundTrip = generateArrayPrefix === 'comma' && options.commaRoundTrip;

    if (!objKeys) {
        objKeys = Object.keys(obj);
    }

    if (options.sort) {
        objKeys.sort(options.sort);
    }

    var sideChannel = getSideChannel();
    for (var i = 0; i < objKeys.length; ++i) {
        var key = objKeys[i];

        if (typeof key === 'undefined' || key === null) {
            continue;
        }

        var value = obj[key];

        if (options.skipNulls && value === null) {
            continue;
        }
        pushToArray(keys, stringify(
            value,
            key,
            generateArrayPrefix,
            commaRoundTrip,
            options.allowEmptyArrays,
            options.strictNullHandling,
            options.skipNulls,
            options.encodeDotInKeys,
            options.encode ? options.encoder : null,
            options.filter,
            options.sort,
            options.allowDots,
            options.serializeDate,
            options.format,
            options.formatter,
            options.encodeValuesOnly,
            options.charset,
            sideChannel
        ));
    }

    var joined = keys.join(options.delimiter);
    var prefix = options.addQueryPrefix === true ? '?' : '';

    if (options.charsetSentinel) {
        if (options.charset === 'iso-8859-1') {
            // encodeURIComponent('&#10003;'), the "numeric entity" representation of a checkmark
            prefix += 'utf8=%26%2310003%3B' + options.delimiter;
        } else {
            // encodeURIComponent('✓')
            prefix += 'utf8=%E2%9C%93' + options.delimiter;
        }
    }

    return joined.length > 0 ? prefix + joined : '';
};

},{"./formats":73,"./utils":77,"side-channel":82}],77:[function(require,module,exports){
'use strict';

var formats = require('./formats');
var getSideChannel = require('side-channel');

var has = Object.prototype.hasOwnProperty;
var isArray = Array.isArray;

// Track objects created from arrayLimit overflow using side-channel
// Stores the current max numeric index for O(1) lookup
var overflowChannel = getSideChannel();

var markOverflow = function markOverflow(obj, maxIndex) {
    overflowChannel.set(obj, maxIndex);
    return obj;
};

var isOverflow = function isOverflow(obj) {
    return overflowChannel.has(obj);
};

var getMaxIndex = function getMaxIndex(obj) {
    return overflowChannel.get(obj);
};

var setMaxIndex = function setMaxIndex(obj, maxIndex) {
    overflowChannel.set(obj, maxIndex);
};

var hexTable = (function () {
    var array = [];
    for (var i = 0; i < 256; ++i) {
        array[array.length] = '%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase();
    }

    return array;
}());

var compactQueue = function compactQueue(queue) {
    while (queue.length > 1) {
        var item = queue.pop();
        var obj = item.obj[item.prop];

        if (isArray(obj)) {
            var compacted = [];

            for (var j = 0; j < obj.length; ++j) {
                if (typeof obj[j] !== 'undefined') {
                    compacted[compacted.length] = obj[j];
                }
            }

            item.obj[item.prop] = compacted;
        }
    }
};

var arrayToObject = function arrayToObject(source, options) {
    var obj = options && options.plainObjects ? { __proto__: null } : {};
    for (var i = 0; i < source.length; ++i) {
        if (typeof source[i] !== 'undefined') {
            obj[i] = source[i];
        }
    }

    return obj;
};

var merge = function merge(target, source, options) {
    /* eslint no-param-reassign: 0 */
    if (!source) {
        return target;
    }

    if (typeof source !== 'object' && typeof source !== 'function') {
        if (isArray(target)) {
            var nextIndex = target.length;
            if (options && typeof options.arrayLimit === 'number' && nextIndex > options.arrayLimit) {
                return markOverflow(arrayToObject(target.concat(source), options), nextIndex);
            }
            target[nextIndex] = source;
        } else if (target && typeof target === 'object') {
            if (isOverflow(target)) {
                // Add at next numeric index for overflow objects
                var newIndex = getMaxIndex(target) + 1;
                target[newIndex] = source;
                setMaxIndex(target, newIndex);
            } else if (options && options.strictMerge) {
                return [target, source];
            } else if (
                (options && (options.plainObjects || options.allowPrototypes))
                || !has.call(Object.prototype, source)
            ) {
                target[source] = true;
            }
        } else {
            return [target, source];
        }

        return target;
    }

    if (!target || typeof target !== 'object') {
        if (isOverflow(source)) {
            // Create new object with target at 0, source values shifted by 1
            var sourceKeys = Object.keys(source);
            var result = options && options.plainObjects
                ? { __proto__: null, 0: target }
                : { 0: target };
            for (var m = 0; m < sourceKeys.length; m++) {
                var oldKey = parseInt(sourceKeys[m], 10);
                result[oldKey + 1] = source[sourceKeys[m]];
            }
            return markOverflow(result, getMaxIndex(source) + 1);
        }
        var combined = [target].concat(source);
        if (options && typeof options.arrayLimit === 'number' && combined.length > options.arrayLimit) {
            return markOverflow(arrayToObject(combined, options), combined.length - 1);
        }
        return combined;
    }

    var mergeTarget = target;
    if (isArray(target) && !isArray(source)) {
        mergeTarget = arrayToObject(target, options);
    }

    if (isArray(target) && isArray(source)) {
        source.forEach(function (item, i) {
            if (has.call(target, i)) {
                var targetItem = target[i];
                if (targetItem && typeof targetItem === 'object' && item && typeof item === 'object') {
                    target[i] = merge(targetItem, item, options);
                } else {
                    target[target.length] = item;
                }
            } else {
                target[i] = item;
            }
        });
        return target;
    }

    return Object.keys(source).reduce(function (acc, key) {
        var value = source[key];

        if (has.call(acc, key)) {
            acc[key] = merge(acc[key], value, options);
        } else {
            acc[key] = value;
        }

        if (isOverflow(source) && !isOverflow(acc)) {
            markOverflow(acc, getMaxIndex(source));
        }
        if (isOverflow(acc)) {
            var keyNum = parseInt(key, 10);
            if (String(keyNum) === key && keyNum >= 0 && keyNum > getMaxIndex(acc)) {
                setMaxIndex(acc, keyNum);
            }
        }

        return acc;
    }, mergeTarget);
};

var assign = function assignSingleSource(target, source) {
    return Object.keys(source).reduce(function (acc, key) {
        acc[key] = source[key];
        return acc;
    }, target);
};

var decode = function (str, defaultDecoder, charset) {
    var strWithoutPlus = str.replace(/\+/g, ' ');
    if (charset === 'iso-8859-1') {
        // unescape never throws, no try...catch needed:
        return strWithoutPlus.replace(/%[0-9a-f]{2}/gi, unescape);
    }
    // utf-8
    try {
        return decodeURIComponent(strWithoutPlus);
    } catch (e) {
        return strWithoutPlus;
    }
};

var limit = 1024;

/* eslint operator-linebreak: [2, "before"] */

var encode = function encode(str, defaultEncoder, charset, kind, format) {
    // This code was originally written by Brian White (mscdex) for the io.js core querystring library.
    // It has been adapted here for stricter adherence to RFC 3986
    if (str.length === 0) {
        return str;
    }

    var string = str;
    if (typeof str === 'symbol') {
        string = Symbol.prototype.toString.call(str);
    } else if (typeof str !== 'string') {
        string = String(str);
    }

    if (charset === 'iso-8859-1') {
        return escape(string).replace(/%u[0-9a-f]{4}/gi, function ($0) {
            return '%26%23' + parseInt($0.slice(2), 16) + '%3B';
        });
    }

    var out = '';
    for (var j = 0; j < string.length; j += limit) {
        var segment = string.length >= limit ? string.slice(j, j + limit) : string;
        var arr = [];

        for (var i = 0; i < segment.length; ++i) {
            var c = segment.charCodeAt(i);
            if (
                c === 0x2D // -
                || c === 0x2E // .
                || c === 0x5F // _
                || c === 0x7E // ~
                || (c >= 0x30 && c <= 0x39) // 0-9
                || (c >= 0x41 && c <= 0x5A) // a-z
                || (c >= 0x61 && c <= 0x7A) // A-Z
                || (format === formats.RFC1738 && (c === 0x28 || c === 0x29)) // ( )
            ) {
                arr[arr.length] = segment.charAt(i);
                continue;
            }

            if (c < 0x80) {
                arr[arr.length] = hexTable[c];
                continue;
            }

            if (c < 0x800) {
                arr[arr.length] = hexTable[0xC0 | (c >> 6)]
                    + hexTable[0x80 | (c & 0x3F)];
                continue;
            }

            if (c < 0xD800 || c >= 0xE000) {
                arr[arr.length] = hexTable[0xE0 | (c >> 12)]
                    + hexTable[0x80 | ((c >> 6) & 0x3F)]
                    + hexTable[0x80 | (c & 0x3F)];
                continue;
            }

            i += 1;
            c = 0x10000 + (((c & 0x3FF) << 10) | (segment.charCodeAt(i) & 0x3FF));

            arr[arr.length] = hexTable[0xF0 | (c >> 18)]
                + hexTable[0x80 | ((c >> 12) & 0x3F)]
                + hexTable[0x80 | ((c >> 6) & 0x3F)]
                + hexTable[0x80 | (c & 0x3F)];
        }

        out += arr.join('');
    }

    return out;
};

var compact = function compact(value) {
    var queue = [{ obj: { o: value }, prop: 'o' }];
    var refs = [];

    for (var i = 0; i < queue.length; ++i) {
        var item = queue[i];
        var obj = item.obj[item.prop];

        var keys = Object.keys(obj);
        for (var j = 0; j < keys.length; ++j) {
            var key = keys[j];
            var val = obj[key];
            if (typeof val === 'object' && val !== null && refs.indexOf(val) === -1) {
                queue[queue.length] = { obj: obj, prop: key };
                refs[refs.length] = val;
            }
        }
    }

    compactQueue(queue);

    return value;
};

var isRegExp = function isRegExp(obj) {
    return Object.prototype.toString.call(obj) === '[object RegExp]';
};

var isBuffer = function isBuffer(obj) {
    if (!obj || typeof obj !== 'object') {
        return false;
    }

    return !!(obj.constructor && obj.constructor.isBuffer && obj.constructor.isBuffer(obj));
};

var combine = function combine(a, b, arrayLimit, plainObjects) {
    // If 'a' is already an overflow object, add to it
    if (isOverflow(a)) {
        var newIndex = getMaxIndex(a) + 1;
        a[newIndex] = b;
        setMaxIndex(a, newIndex);
        return a;
    }

    var result = [].concat(a, b);
    if (result.length > arrayLimit) {
        return markOverflow(arrayToObject(result, { plainObjects: plainObjects }), result.length - 1);
    }
    return result;
};

var maybeMap = function maybeMap(val, fn) {
    if (isArray(val)) {
        var mapped = [];
        for (var i = 0; i < val.length; i += 1) {
            mapped[mapped.length] = fn(val[i]);
        }
        return mapped;
    }
    return fn(val);
};

module.exports = {
    arrayToObject: arrayToObject,
    assign: assign,
    combine: combine,
    compact: compact,
    decode: decode,
    encode: encode,
    isBuffer: isBuffer,
    isOverflow: isOverflow,
    isRegExp: isRegExp,
    markOverflow: markOverflow,
    maybeMap: maybeMap,
    merge: merge
};

},{"./formats":73,"side-channel":82}],78:[function(require,module,exports){
/*! safe-buffer. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */
/* eslint-disable node/no-deprecated-api */
var buffer = require('buffer')
var Buffer = buffer.Buffer

// alternative to using Object.keys for old browsers
function copyProps (src, dst) {
  for (var key in src) {
    dst[key] = src[key]
  }
}
if (Buffer.from && Buffer.alloc && Buffer.allocUnsafe && Buffer.allocUnsafeSlow) {
  module.exports = buffer
} else {
  // Copy properties from require('buffer')
  copyProps(buffer, exports)
  exports.Buffer = SafeBuffer
}

function SafeBuffer (arg, encodingOrOffset, length) {
  return Buffer(arg, encodingOrOffset, length)
}

SafeBuffer.prototype = Object.create(Buffer.prototype)

// Copy static methods from Buffer
copyProps(Buffer, SafeBuffer)

SafeBuffer.from = function (arg, encodingOrOffset, length) {
  if (typeof arg === 'number') {
    throw new TypeError('Argument must not be a number')
  }
  return Buffer(arg, encodingOrOffset, length)
}

SafeBuffer.alloc = function (size, fill, encoding) {
  if (typeof size !== 'number') {
    throw new TypeError('Argument must be a number')
  }
  var buf = Buffer(size)
  if (fill !== undefined) {
    if (typeof encoding === 'string') {
      buf.fill(fill, encoding)
    } else {
      buf.fill(fill)
    }
  } else {
    buf.fill(0)
  }
  return buf
}

SafeBuffer.allocUnsafe = function (size) {
  if (typeof size !== 'number') {
    throw new TypeError('Argument must be a number')
  }
  return Buffer(size)
}

SafeBuffer.allocUnsafeSlow = function (size) {
  if (typeof size !== 'number') {
    throw new TypeError('Argument must be a number')
  }
  return buffer.SlowBuffer(size)
}

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

var inspect = require('object-inspect');
var $TypeError = require('es-errors/type');

/*
* This function traverses the list returning the node corresponding to the given key.
*
* That node is also moved to the head of the list, so that if it's accessed again we don't need to traverse the whole list.
* By doing so, all the recently used nodes can be accessed relatively quickly.
*/
/** @type {import('./list.d.ts').listGetNode} */
// eslint-disable-next-line consistent-return
var listGetNode = function (list, key, isDelete) {
  /** @type {typeof list | NonNullable<(typeof list)['next']>} */
  var prev = list;
  /** @type {(typeof list)['next']} */
  var curr;
  // eslint-disable-next-line eqeqeq
  for (; (curr = prev.next) != null; prev = curr) {
    if (curr.key === key) {
      prev.next = curr.next;
      if (!isDelete) {
        // eslint-disable-next-line no-extra-parens
        curr.next = /** @type {NonNullable<typeof list.next>} */list.next;
        list.next = curr; // eslint-disable-line no-param-reassign
      }
      return curr;
    }
  }
};

/** @type {import('./list.d.ts').listGet} */
var listGet = function (objects, key) {
  if (!objects) {
    return void undefined;
  }
  var node = listGetNode(objects, key);
  return node && node.value;
};
/** @type {import('./list.d.ts').listSet} */
var listSet = function (objects, key, value) {
  var node = listGetNode(objects, key);
  if (node) {
    node.value = value;
  } else {
    // Prepend the new node to the beginning of the list
    objects.next = /** @type {import('./list.d.ts').ListNode<typeof value, typeof key>} */{
      // eslint-disable-line no-param-reassign, no-extra-parens
      key: key,
      next: objects.next,
      value: value
    };
  }
};
/** @type {import('./list.d.ts').listHas} */
var listHas = function (objects, key) {
  if (!objects) {
    return false;
  }
  return !!listGetNode(objects, key);
};
/** @type {import('./list.d.ts').listDelete} */
// eslint-disable-next-line consistent-return
var listDelete = function (objects, key) {
  if (objects) {
    return listGetNode(objects, key, true);
  }
};

/** @type {import('.')} */
module.exports = function getSideChannelList() {
  /** @typedef {ReturnType<typeof getSideChannelList>} Channel */
  /** @typedef {Parameters<Channel['get']>[0]} K */
  /** @typedef {Parameters<Channel['set']>[1]} V */

  /** @type {import('./list.d.ts').RootNode<V, K> | undefined} */var $o;

  /** @type {Channel} */
  var channel = {
    assert: function (key) {
      if (!channel.has(key)) {
        throw new $TypeError('Side channel does not contain ' + inspect(key));
      }
    },
    'delete': function (key) {
      var deletedNode = listDelete($o, key);
      if (deletedNode && $o && !$o.next) {
        $o = void undefined;
      }
      return !!deletedNode;
    },
    get: function (key) {
      return listGet($o, key);
    },
    has: function (key) {
      return listHas($o, key);
    },
    set: function (key, value) {
      if (!$o) {
        // Initialize the linked list as an empty node, so that we don't have to special-case handling of the first node: we can always refer to it as (previous node).next, instead of something like (list).head
        $o = {
          next: void undefined
        };
      }
      // eslint-disable-next-line no-extra-parens
      listSet(/** @type {NonNullable<typeof $o>} */$o, key, value);
    }
  };
  return channel;
};

},{"es-errors/type":40,"object-inspect":65}],80:[function(require,module,exports){
'use strict';

var GetIntrinsic = require('get-intrinsic');
var callBound = require('call-bound');
var inspect = require('object-inspect');
var $TypeError = require('es-errors/type');
var $Map = GetIntrinsic('%Map%', true);

/** @type {<K, V>(thisArg: Map<K, V>, key: K) => V} */
var $mapGet = callBound('Map.prototype.get', true);
/** @type {<K, V>(thisArg: Map<K, V>, key: K, value: V) => void} */
var $mapSet = callBound('Map.prototype.set', true);
/** @type {<K, V>(thisArg: Map<K, V>, key: K) => boolean} */
var $mapHas = callBound('Map.prototype.has', true);
/** @type {<K, V>(thisArg: Map<K, V>, key: K) => boolean} */
var $mapDelete = callBound('Map.prototype.delete', true);
/** @type {<K, V>(thisArg: Map<K, V>) => number} */
var $mapSize = callBound('Map.prototype.size', true);

/** @type {import('.')} */
module.exports = !!$Map && /** @type {Exclude<import('.'), false>} */function getSideChannelMap() {
  /** @typedef {ReturnType<typeof getSideChannelMap>} Channel */
  /** @typedef {Parameters<Channel['get']>[0]} K */
  /** @typedef {Parameters<Channel['set']>[1]} V */

  /** @type {Map<K, V> | undefined} */var $m;

  /** @type {Channel} */
  var channel = {
    assert: function (key) {
      if (!channel.has(key)) {
        throw new $TypeError('Side channel does not contain ' + inspect(key));
      }
    },
    'delete': function (key) {
      if ($m) {
        var result = $mapDelete($m, key);
        if ($mapSize($m) === 0) {
          $m = void undefined;
        }
        return result;
      }
      return false;
    },
    get: function (key) {
      // eslint-disable-line consistent-return
      if ($m) {
        return $mapGet($m, key);
      }
    },
    has: function (key) {
      if ($m) {
        return $mapHas($m, key);
      }
      return false;
    },
    set: function (key, value) {
      if (!$m) {
        // @ts-expect-error TS can't handle narrowing a variable inside a closure
        $m = new $Map();
      }
      $mapSet($m, key, value);
    }
  };

  // @ts-expect-error TODO: figure out why TS is erroring here
  return channel;
};

},{"call-bound":32,"es-errors/type":40,"get-intrinsic":46,"object-inspect":65}],81:[function(require,module,exports){
'use strict';

var GetIntrinsic = require('get-intrinsic');
var callBound = require('call-bound');
var inspect = require('object-inspect');
var getSideChannelMap = require('side-channel-map');
var $TypeError = require('es-errors/type');
var $WeakMap = GetIntrinsic('%WeakMap%', true);

/** @type {<K extends object, V>(thisArg: WeakMap<K, V>, key: K) => V} */
var $weakMapGet = callBound('WeakMap.prototype.get', true);
/** @type {<K extends object, V>(thisArg: WeakMap<K, V>, key: K, value: V) => void} */
var $weakMapSet = callBound('WeakMap.prototype.set', true);
/** @type {<K extends object, V>(thisArg: WeakMap<K, V>, key: K) => boolean} */
var $weakMapHas = callBound('WeakMap.prototype.has', true);
/** @type {<K extends object, V>(thisArg: WeakMap<K, V>, key: K) => boolean} */
var $weakMapDelete = callBound('WeakMap.prototype.delete', true);

/** @type {import('.')} */
module.exports = $WeakMap ? /** @type {Exclude<import('.'), false>} */function getSideChannelWeakMap() {
  /** @typedef {ReturnType<typeof getSideChannelWeakMap>} Channel */
  /** @typedef {Parameters<Channel['get']>[0]} K */
  /** @typedef {Parameters<Channel['set']>[1]} V */

  /** @type {WeakMap<K & object, V> | undefined} */var $wm;
  /** @type {Channel | undefined} */
  var $m;

  /** @type {Channel} */
  var channel = {
    assert: function (key) {
      if (!channel.has(key)) {
        throw new $TypeError('Side channel does not contain ' + inspect(key));
      }
    },
    'delete': function (key) {
      if ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) {
        if ($wm) {
          return $weakMapDelete($wm, key);
        }
      } else if (getSideChannelMap) {
        if ($m) {
          return $m['delete'](key);
        }
      }
      return false;
    },
    get: function (key) {
      if ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) {
        if ($wm) {
          return $weakMapGet($wm, key);
        }
      }
      return $m && $m.get(key);
    },
    has: function (key) {
      if ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) {
        if ($wm) {
          return $weakMapHas($wm, key);
        }
      }
      return !!$m && $m.has(key);
    },
    set: function (key, value) {
      if ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) {
        if (!$wm) {
          $wm = new $WeakMap();
        }
        $weakMapSet($wm, key, value);
      } else if (getSideChannelMap) {
        if (!$m) {
          $m = getSideChannelMap();
        }
        // eslint-disable-next-line no-extra-parens
        /** @type {NonNullable<typeof $m>} */
        $m.set(key, value);
      }
    }
  };

  // @ts-expect-error TODO: figure out why this is erroring
  return channel;
} : getSideChannelMap;

},{"call-bound":32,"es-errors/type":40,"get-intrinsic":46,"object-inspect":65,"side-channel-map":80}],82:[function(require,module,exports){
'use strict';

var $TypeError = require('es-errors/type');
var inspect = require('object-inspect');
var getSideChannelList = require('side-channel-list');
var getSideChannelMap = require('side-channel-map');
var getSideChannelWeakMap = require('side-channel-weakmap');
var makeChannel = getSideChannelWeakMap || getSideChannelMap || getSideChannelList;

/** @type {import('.')} */
module.exports = function getSideChannel() {
  /** @typedef {ReturnType<typeof getSideChannel>} Channel */

  /** @type {Channel | undefined} */var $channelData;

  /** @type {Channel} */
  var channel = {
    assert: function (key) {
      if (!channel.has(key)) {
        throw new $TypeError('Side channel does not contain ' + inspect(key));
      }
    },
    'delete': function (key) {
      return !!$channelData && $channelData['delete'](key);
    },
    get: function (key) {
      return $channelData && $channelData.get(key);
    },
    has: function (key) {
      return !!$channelData && $channelData.has(key);
    },
    set: function (key, value) {
      if (!$channelData) {
        $channelData = makeChannel();
      }
      $channelData.set(key, value);
    }
  };
  // @ts-expect-error TODO: figure out why this is erroring
  return channel;
};

},{"es-errors/type":40,"object-inspect":65,"side-channel-list":79,"side-channel-map":80,"side-channel-weakmap":81}],83:[function(require,module,exports){
(function (global){(function (){
var ClientRequest = require('./lib/request')
var response = require('./lib/response')
var extend = require('xtend')
var statusCodes = require('builtin-status-codes')
var url = require('url')

var http = exports

http.request = function (opts, cb) {
	if (typeof opts === 'string')
		opts = url.parse(opts)
	else
		opts = extend(opts)

	// Normally, the page is loaded from http or https, so not specifying a protocol
	// will result in a (valid) protocol-relative url. However, this won't work if
	// the protocol is something else, like 'file:'
	var defaultProtocol = global.location.protocol.search(/^https?:$/) === -1 ? 'http:' : ''

	var protocol = opts.protocol || defaultProtocol
	var host = opts.hostname || opts.host
	var port = opts.port
	var path = opts.path || '/'

	// Necessary for IPv6 addresses
	if (host && host.indexOf(':') !== -1)
		host = '[' + host + ']'

	// This may be a relative url. The browser should always be able to interpret it correctly.
	opts.url = (host ? (protocol + '//' + host) : '') + (port ? ':' + port : '') + path
	opts.method = (opts.method || 'GET').toUpperCase()
	opts.headers = opts.headers || {}

	// Also valid opts.auth, opts.mode

	var req = new ClientRequest(opts)
	if (cb)
		req.on('response', cb)
	return req
}

http.get = function get (opts, cb) {
	var req = http.request(opts, cb)
	req.end()
	return req
}

http.ClientRequest = ClientRequest
http.IncomingMessage = response.IncomingMessage

http.Agent = function () {}
http.Agent.defaultMaxSockets = 4

http.globalAgent = new http.Agent()

http.STATUS_CODES = statusCodes

http.METHODS = [
	'CHECKOUT',
	'CONNECT',
	'COPY',
	'DELETE',
	'GET',
	'HEAD',
	'LOCK',
	'M-SEARCH',
	'MERGE',
	'MKACTIVITY',
	'MKCOL',
	'MOVE',
	'NOTIFY',
	'OPTIONS',
	'PATCH',
	'POST',
	'PROPFIND',
	'PROPPATCH',
	'PURGE',
	'PUT',
	'REPORT',
	'SEARCH',
	'SUBSCRIBE',
	'TRACE',
	'UNLOCK',
	'UNSUBSCRIBE'
]
}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})

},{"./lib/request":85,"./lib/response":86,"builtin-status-codes":26,"url":106,"xtend":108}],84:[function(require,module,exports){
(function (global){(function (){
exports.fetch = isFunction(global.fetch) && isFunction(global.ReadableStream)

exports.writableStream = isFunction(global.WritableStream)

exports.abortController = isFunction(global.AbortController)

// The xhr request to example.com may violate some restrictive CSP configurations,
// so if we're running in a browser that supports `fetch`, avoid calling getXHR()
// and assume support for certain features below.
var xhr
function getXHR () {
	// Cache the xhr value
	if (xhr !== undefined) return xhr

	if (global.XMLHttpRequest) {
		xhr = new global.XMLHttpRequest()
		// If XDomainRequest is available (ie only, where xhr might not work
		// cross domain), use the page location. Otherwise use example.com
		// Note: this doesn't actually make an http request.
		try {
			xhr.open('GET', global.XDomainRequest ? '/' : 'https://example.com')
		} catch(e) {
			xhr = null
		}
	} else {
		// Service workers don't have XHR
		xhr = null
	}
	return xhr
}

function checkTypeSupport (type) {
	var xhr = getXHR()
	if (!xhr) return false
	try {
		xhr.responseType = type
		return xhr.responseType === type
	} catch (e) {}
	return false
}

// If fetch is supported, then arraybuffer will be supported too. Skip calling
// checkTypeSupport(), since that calls getXHR().
exports.arraybuffer = exports.fetch || checkTypeSupport('arraybuffer')

// These next two tests unavoidably show warnings in Chrome. Since fetch will always
// be used if it's available, just return false for these to avoid the warnings.
exports.msstream = !exports.fetch && checkTypeSupport('ms-stream')
exports.mozchunkedarraybuffer = !exports.fetch && checkTypeSupport('moz-chunked-arraybuffer')

// If fetch is supported, then overrideMimeType will be supported too. Skip calling
// getXHR().
exports.overrideMimeType = exports.fetch || (getXHR() ? isFunction(getXHR().overrideMimeType) : false)

function isFunction (value) {
	return typeof value === 'function'
}

xhr = null // Help gc

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

},{}],85:[function(require,module,exports){
(function (process,global,Buffer){(function (){
var capability = require('./capability')
var inherits = require('inherits')
var response = require('./response')
var stream = require('readable-stream')

var IncomingMessage = response.IncomingMessage
var rStates = response.readyStates

function decideMode (preferBinary, useFetch) {
	if (capability.fetch && useFetch) {
		return 'fetch'
	} else if (capability.mozchunkedarraybuffer) {
		return 'moz-chunked-arraybuffer'
	} else if (capability.msstream) {
		return 'ms-stream'
	} else if (capability.arraybuffer && preferBinary) {
		return 'arraybuffer'
	} else {
		return 'text'
	}
}

var ClientRequest = module.exports = function (opts) {
	var self = this
	stream.Writable.call(self)

	self._opts = opts
	self._body = []
	self._headers = {}
	if (opts.auth)
		self.setHeader('Authorization', 'Basic ' + Buffer.from(opts.auth).toString('base64'))
	Object.keys(opts.headers).forEach(function (name) {
		self.setHeader(name, opts.headers[name])
	})

	var preferBinary
	var useFetch = true
	if (opts.mode === 'disable-fetch' || ('requestTimeout' in opts && !capability.abortController)) {
		// If the use of XHR should be preferred. Not typically needed.
		useFetch = false
		preferBinary = true
	} else if (opts.mode === 'prefer-streaming') {
		// If streaming is a high priority but binary compatibility and
		// the accuracy of the 'content-type' header aren't
		preferBinary = false
	} else if (opts.mode === 'allow-wrong-content-type') {
		// If streaming is more important than preserving the 'content-type' header
		preferBinary = !capability.overrideMimeType
	} else if (!opts.mode || opts.mode === 'default' || opts.mode === 'prefer-fast') {
		// Use binary if text streaming may corrupt data or the content-type header, or for speed
		preferBinary = true
	} else {
		throw new Error('Invalid value for opts.mode')
	}
	self._mode = decideMode(preferBinary, useFetch)
	self._fetchTimer = null
	self._socketTimeout = null
	self._socketTimer = null

	self.on('finish', function () {
		self._onFinish()
	})
}

inherits(ClientRequest, stream.Writable)

ClientRequest.prototype.setHeader = function (name, value) {
	var self = this
	var lowerName = name.toLowerCase()
	// This check is not necessary, but it prevents warnings from browsers about setting unsafe
	// headers. To be honest I'm not entirely sure hiding these warnings is a good thing, but
	// http-browserify did it, so I will too.
	if (unsafeHeaders.indexOf(lowerName) !== -1)
		return

	self._headers[lowerName] = {
		name: name,
		value: value
	}
}

ClientRequest.prototype.getHeader = function (name) {
	var header = this._headers[name.toLowerCase()]
	if (header)
		return header.value
	return null
}

ClientRequest.prototype.removeHeader = function (name) {
	var self = this
	delete self._headers[name.toLowerCase()]
}

ClientRequest.prototype._onFinish = function () {
	var self = this

	if (self._destroyed)
		return
	var opts = self._opts

	if ('timeout' in opts && opts.timeout !== 0) {
		self.setTimeout(opts.timeout)
	}

	var headersObj = self._headers
	var body = null
	if (opts.method !== 'GET' && opts.method !== 'HEAD') {
        body = new Blob(self._body, {
            type: (headersObj['content-type'] || {}).value || ''
        });
    }

	// create flattened list of headers
	var headersList = []
	Object.keys(headersObj).forEach(function (keyName) {
		var name = headersObj[keyName].name
		var value = headersObj[keyName].value
		if (Array.isArray(value)) {
			value.forEach(function (v) {
				headersList.push([name, v])
			})
		} else {
			headersList.push([name, value])
		}
	})

	if (self._mode === 'fetch') {
		var signal = null
		if (capability.abortController) {
			var controller = new AbortController()
			signal = controller.signal
			self._fetchAbortController = controller

			if ('requestTimeout' in opts && opts.requestTimeout !== 0) {
				self._fetchTimer = global.setTimeout(function () {
					self.emit('requestTimeout')
					if (self._fetchAbortController)
						self._fetchAbortController.abort()
				}, opts.requestTimeout)
			}
		}

		global.fetch(self._opts.url, {
			method: self._opts.method,
			headers: headersList,
			body: body || undefined,
			mode: 'cors',
			credentials: opts.withCredentials ? 'include' : 'same-origin',
			signal: signal
		}).then(function (response) {
			self._fetchResponse = response
			self._resetTimers(false)
			self._connect()
		}, function (reason) {
			self._resetTimers(true)
			if (!self._destroyed)
				self.emit('error', reason)
		})
	} else {
		var xhr = self._xhr = new global.XMLHttpRequest()
		try {
			xhr.open(self._opts.method, self._opts.url, true)
		} catch (err) {
			process.nextTick(function () {
				self.emit('error', err)
			})
			return
		}

		// Can't set responseType on really old browsers
		if ('responseType' in xhr)
			xhr.responseType = self._mode

		if ('withCredentials' in xhr)
			xhr.withCredentials = !!opts.withCredentials

		if (self._mode === 'text' && 'overrideMimeType' in xhr)
			xhr.overrideMimeType('text/plain; charset=x-user-defined')

		if ('requestTimeout' in opts) {
			xhr.timeout = opts.requestTimeout
			xhr.ontimeout = function () {
				self.emit('requestTimeout')
			}
		}

		headersList.forEach(function (header) {
			xhr.setRequestHeader(header[0], header[1])
		})

		self._response = null
		xhr.onreadystatechange = function () {
			switch (xhr.readyState) {
				case rStates.LOADING:
				case rStates.DONE:
					self._onXHRProgress()
					break
			}
		}
		// Necessary for streaming in Firefox, since xhr.response is ONLY defined
		// in onprogress, not in onreadystatechange with xhr.readyState = 3
		if (self._mode === 'moz-chunked-arraybuffer') {
			xhr.onprogress = function () {
				self._onXHRProgress()
			}
		}

		xhr.onerror = function () {
			if (self._destroyed)
				return
			self._resetTimers(true)
			self.emit('error', new Error('XHR error'))
		}

		try {
			xhr.send(body)
		} catch (err) {
			process.nextTick(function () {
				self.emit('error', err)
			})
			return
		}
	}
}

/**
 * Checks if xhr.status is readable and non-zero, indicating no error.
 * Even though the spec says it should be available in readyState 3,
 * accessing it throws an exception in IE8
 */
function statusValid (xhr) {
	try {
		var status = xhr.status
		return (status !== null && status !== 0)
	} catch (e) {
		return false
	}
}

ClientRequest.prototype._onXHRProgress = function () {
	var self = this

	self._resetTimers(false)

	if (!statusValid(self._xhr) || self._destroyed)
		return

	if (!self._response)
		self._connect()

	self._response._onXHRProgress(self._resetTimers.bind(self))
}

ClientRequest.prototype._connect = function () {
	var self = this

	if (self._destroyed)
		return

	self._response = new IncomingMessage(self._xhr, self._fetchResponse, self._mode, self._resetTimers.bind(self))
	self._response.on('error', function(err) {
		self.emit('error', err)
	})

	self.emit('response', self._response)
}

ClientRequest.prototype._write = function (chunk, encoding, cb) {
	var self = this

	self._body.push(chunk)
	cb()
}

ClientRequest.prototype._resetTimers = function (done) {
	var self = this

	global.clearTimeout(self._socketTimer)
	self._socketTimer = null

	if (done) {
		global.clearTimeout(self._fetchTimer)
		self._fetchTimer = null
	} else if (self._socketTimeout) {
		self._socketTimer = global.setTimeout(function () {
			self.emit('timeout')
		}, self._socketTimeout)
	}
}

ClientRequest.prototype.abort = ClientRequest.prototype.destroy = function (err) {
	var self = this
	self._destroyed = true
	self._resetTimers(true)
	if (self._response)
		self._response._destroyed = true
	if (self._xhr)
		self._xhr.abort()
	else if (self._fetchAbortController)
		self._fetchAbortController.abort()

	if (err)
		self.emit('error', err)
}

ClientRequest.prototype.end = function (data, encoding, cb) {
	var self = this
	if (typeof data === 'function') {
		cb = data
		data = undefined
	}

	stream.Writable.prototype.end.call(self, data, encoding, cb)
}

ClientRequest.prototype.setTimeout = function (timeout, cb) {
	var self = this

	if (cb)
		self.once('timeout', cb)

	self._socketTimeout = timeout
	self._resetTimers(false)
}

ClientRequest.prototype.flushHeaders = function () {}
ClientRequest.prototype.setNoDelay = function () {}
ClientRequest.prototype.setSocketKeepAlive = function () {}

// Taken from http://www.w3.org/TR/XMLHttpRequest/#the-setrequestheader%28%29-method
var unsafeHeaders = [
	'accept-charset',
	'accept-encoding',
	'access-control-request-headers',
	'access-control-request-method',
	'connection',
	'content-length',
	'cookie',
	'cookie2',
	'date',
	'dnt',
	'expect',
	'host',
	'keep-alive',
	'origin',
	'referer',
	'te',
	'trailer',
	'transfer-encoding',
	'upgrade',
	'via'
]

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

},{"./capability":84,"./response":86,"_process":71,"buffer":25,"inherits":56,"readable-stream":101}],86:[function(require,module,exports){
(function (process,global,Buffer){(function (){
var capability = require('./capability')
var inherits = require('inherits')
var stream = require('readable-stream')

var rStates = exports.readyStates = {
	UNSENT: 0,
	OPENED: 1,
	HEADERS_RECEIVED: 2,
	LOADING: 3,
	DONE: 4
}

var IncomingMessage = exports.IncomingMessage = function (xhr, response, mode, resetTimers) {
	var self = this
	stream.Readable.call(self)

	self._mode = mode
	self.headers = {}
	self.rawHeaders = []
	self.trailers = {}
	self.rawTrailers = []

	// Fake the 'close' event, but only once 'end' fires
	self.on('end', function () {
		// The nextTick is necessary to prevent the 'request' module from causing an infinite loop
		process.nextTick(function () {
			self.emit('close')
		})
	})

	if (mode === 'fetch') {
		self._fetchResponse = response

		self.url = response.url
		self.statusCode = response.status
		self.statusMessage = response.statusText
		
		response.headers.forEach(function (header, key){
			self.headers[key.toLowerCase()] = header
			self.rawHeaders.push(key, header)
		})

		if (capability.writableStream) {
			var writable = new WritableStream({
				write: function (chunk) {
					resetTimers(false)
					return new Promise(function (resolve, reject) {
						if (self._destroyed) {
							reject()
						} else if(self.push(Buffer.from(chunk))) {
							resolve()
						} else {
							self._resumeFetch = resolve
						}
					})
				},
				close: function () {
					resetTimers(true)
					if (!self._destroyed)
						self.push(null)
				},
				abort: function (err) {
					resetTimers(true)
					if (!self._destroyed)
						self.emit('error', err)
				}
			})

			try {
				response.body.pipeTo(writable).catch(function (err) {
					resetTimers(true)
					if (!self._destroyed)
						self.emit('error', err)
				})
				return
			} catch (e) {} // pipeTo method isn't defined. Can't find a better way to feature test this
		}
		// fallback for when writableStream or pipeTo aren't available
		var reader = response.body.getReader()
		function read () {
			reader.read().then(function (result) {
				if (self._destroyed)
					return
				resetTimers(result.done)
				if (result.done) {
					self.push(null)
					return
				}
				self.push(Buffer.from(result.value))
				read()
			}).catch(function (err) {
				resetTimers(true)
				if (!self._destroyed)
					self.emit('error', err)
			})
		}
		read()
	} else {
		self._xhr = xhr
		self._pos = 0

		self.url = xhr.responseURL
		self.statusCode = xhr.status
		self.statusMessage = xhr.statusText
		var headers = xhr.getAllResponseHeaders().split(/\r?\n/)
		headers.forEach(function (header) {
			var matches = header.match(/^([^:]+):\s*(.*)/)
			if (matches) {
				var key = matches[1].toLowerCase()
				if (key === 'set-cookie') {
					if (self.headers[key] === undefined) {
						self.headers[key] = []
					}
					self.headers[key].push(matches[2])
				} else if (self.headers[key] !== undefined) {
					self.headers[key] += ', ' + matches[2]
				} else {
					self.headers[key] = matches[2]
				}
				self.rawHeaders.push(matches[1], matches[2])
			}
		})

		self._charset = 'x-user-defined'
		if (!capability.overrideMimeType) {
			var mimeType = self.rawHeaders['mime-type']
			if (mimeType) {
				var charsetMatch = mimeType.match(/;\s*charset=([^;])(;|$)/)
				if (charsetMatch) {
					self._charset = charsetMatch[1].toLowerCase()
				}
			}
			if (!self._charset)
				self._charset = 'utf-8' // best guess
		}
	}
}

inherits(IncomingMessage, stream.Readable)

IncomingMessage.prototype._read = function () {
	var self = this

	var resolve = self._resumeFetch
	if (resolve) {
		self._resumeFetch = null
		resolve()
	}
}

IncomingMessage.prototype._onXHRProgress = function (resetTimers) {
	var self = this

	var xhr = self._xhr

	var response = null
	switch (self._mode) {
		case 'text':
			response = xhr.responseText
			if (response.length > self._pos) {
				var newData = response.substr(self._pos)
				if (self._charset === 'x-user-defined') {
					var buffer = Buffer.alloc(newData.length)
					for (var i = 0; i < newData.length; i++)
						buffer[i] = newData.charCodeAt(i) & 0xff

					self.push(buffer)
				} else {
					self.push(newData, self._charset)
				}
				self._pos = response.length
			}
			break
		case 'arraybuffer':
			if (xhr.readyState !== rStates.DONE || !xhr.response)
				break
			response = xhr.response
			self.push(Buffer.from(new Uint8Array(response)))
			break
		case 'moz-chunked-arraybuffer': // take whole
			response = xhr.response
			if (xhr.readyState !== rStates.LOADING || !response)
				break
			self.push(Buffer.from(new Uint8Array(response)))
			break
		case 'ms-stream':
			response = xhr.response
			if (xhr.readyState !== rStates.LOADING)
				break
			var reader = new global.MSStreamReader()
			reader.onprogress = function () {
				if (reader.result.byteLength > self._pos) {
					self.push(Buffer.from(new Uint8Array(reader.result.slice(self._pos))))
					self._pos = reader.result.byteLength
				}
			}
			reader.onload = function () {
				resetTimers(true)
				self.push(null)
			}
			// reader.onerror = ??? // TODO: this
			reader.readAsArrayBuffer(response)
			break
	}

	// The ms-stream case handles end separately in reader.onload()
	if (self._xhr.readyState === rStates.DONE && self._mode !== 'ms-stream') {
		resetTimers(true)
		self.push(null)
	}
}

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

},{"./capability":84,"_process":71,"buffer":25,"inherits":56,"readable-stream":101}],87:[function(require,module,exports){
'use strict';

function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }

var codes = {};

function createErrorType(code, message, Base) {
  if (!Base) {
    Base = Error;
  }

  function getMessage(arg1, arg2, arg3) {
    if (typeof message === 'string') {
      return message;
    } else {
      return message(arg1, arg2, arg3);
    }
  }

  var NodeError =
  /*#__PURE__*/
  function (_Base) {
    _inheritsLoose(NodeError, _Base);

    function NodeError(arg1, arg2, arg3) {
      return _Base.call(this, getMessage(arg1, arg2, arg3)) || this;
    }

    return NodeError;
  }(Base);

  NodeError.prototype.name = Base.name;
  NodeError.prototype.code = code;
  codes[code] = NodeError;
} // https://github.com/nodejs/node/blob/v10.8.0/lib/internal/errors.js


function oneOf(expected, thing) {
  if (Array.isArray(expected)) {
    var len = expected.length;
    expected = expected.map(function (i) {
      return String(i);
    });

    if (len > 2) {
      return "one of ".concat(thing, " ").concat(expected.slice(0, len - 1).join(', '), ", or ") + expected[len - 1];
    } else if (len === 2) {
      return "one of ".concat(thing, " ").concat(expected[0], " or ").concat(expected[1]);
    } else {
      return "of ".concat(thing, " ").concat(expected[0]);
    }
  } else {
    return "of ".concat(thing, " ").concat(String(expected));
  }
} // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith


function startsWith(str, search, pos) {
  return str.substr(!pos || pos < 0 ? 0 : +pos, search.length) === search;
} // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith


function endsWith(str, search, this_len) {
  if (this_len === undefined || this_len > str.length) {
    this_len = str.length;
  }

  return str.substring(this_len - search.length, this_len) === search;
} // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes


function includes(str, search, start) {
  if (typeof start !== 'number') {
    start = 0;
  }

  if (start + search.length > str.length) {
    return false;
  } else {
    return str.indexOf(search, start) !== -1;
  }
}

createErrorType('ERR_INVALID_OPT_VALUE', function (name, value) {
  return 'The value "' + value + '" is invalid for option "' + name + '"';
}, TypeError);
createErrorType('ERR_INVALID_ARG_TYPE', function (name, expected, actual) {
  // determiner: 'must be' or 'must not be'
  var determiner;

  if (typeof expected === 'string' && startsWith(expected, 'not ')) {
    determiner = 'must not be';
    expected = expected.replace(/^not /, '');
  } else {
    determiner = 'must be';
  }

  var msg;

  if (endsWith(name, ' argument')) {
    // For cases like 'first argument'
    msg = "The ".concat(name, " ").concat(determiner, " ").concat(oneOf(expected, 'type'));
  } else {
    var type = includes(name, '.') ? 'property' : 'argument';
    msg = "The \"".concat(name, "\" ").concat(type, " ").concat(determiner, " ").concat(oneOf(expected, 'type'));
  }

  msg += ". Received type ".concat(typeof actual);
  return msg;
}, TypeError);
createErrorType('ERR_STREAM_PUSH_AFTER_EOF', 'stream.push() after EOF');
createErrorType('ERR_METHOD_NOT_IMPLEMENTED', function (name) {
  return 'The ' + name + ' method is not implemented';
});
createErrorType('ERR_STREAM_PREMATURE_CLOSE', 'Premature close');
createErrorType('ERR_STREAM_DESTROYED', function (name) {
  return 'Cannot call ' + name + ' after a stream was destroyed';
});
createErrorType('ERR_MULTIPLE_CALLBACK', 'Callback called multiple times');
createErrorType('ERR_STREAM_CANNOT_PIPE', 'Cannot pipe, not readable');
createErrorType('ERR_STREAM_WRITE_AFTER_END', 'write after end');
createErrorType('ERR_STREAM_NULL_VALUES', 'May not write null values to stream', TypeError);
createErrorType('ERR_UNKNOWN_ENCODING', function (arg) {
  return 'Unknown encoding: ' + arg;
}, TypeError);
createErrorType('ERR_STREAM_UNSHIFT_AFTER_END_EVENT', 'stream.unshift() after end event');
module.exports.codes = codes;

},{}],88:[function(require,module,exports){
(function (process){(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.

// a duplex stream is just a stream that is both readable and writable.
// Since JS doesn't have multiple prototypal inheritance, this class
// prototypally inherits from Readable, and then parasitically from
// Writable.

'use strict';

/*<replacement>*/
var objectKeys = Object.keys || function (obj) {
  var keys = [];
  for (var key in obj) keys.push(key);
  return keys;
};
/*</replacement>*/

module.exports = Duplex;
var Readable = require('./_stream_readable');
var Writable = require('./_stream_writable');
require('inherits')(Duplex, Readable);
{
  // Allow the keys array to be GC'ed.
  var keys = objectKeys(Writable.prototype);
  for (var v = 0; v < keys.length; v++) {
    var method = keys[v];
    if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method];
  }
}
function Duplex(options) {
  if (!(this instanceof Duplex)) return new Duplex(options);
  Readable.call(this, options);
  Writable.call(this, options);
  this.allowHalfOpen = true;
  if (options) {
    if (options.readable === false) this.readable = false;
    if (options.writable === false) this.writable = false;
    if (options.allowHalfOpen === false) {
      this.allowHalfOpen = false;
      this.once('end', onend);
    }
  }
}
Object.defineProperty(Duplex.prototype, 'writableHighWaterMark', {
  // making it explicit this property is not enumerable
  // because otherwise some prototype manipulation in
  // userland will fail
  enumerable: false,
  get: function get() {
    return this._writableState.highWaterMark;
  }
});
Object.defineProperty(Duplex.prototype, 'writableBuffer', {
  // making it explicit this property is not enumerable
  // because otherwise some prototype manipulation in
  // userland will fail
  enumerable: false,
  get: function get() {
    return this._writableState && this._writableState.getBuffer();
  }
});
Object.defineProperty(Duplex.prototype, 'writableLength', {
  // making it explicit this property is not enumerable
  // because otherwise some prototype manipulation in
  // userland will fail
  enumerable: false,
  get: function get() {
    return this._writableState.length;
  }
});

// the no-half-open enforcer
function onend() {
  // If the writable side ended, then we're ok.
  if (this._writableState.ended) return;

  // no more data can be written.
  // But allow more writes to happen in this tick.
  process.nextTick(onEndNT, this);
}
function onEndNT(self) {
  self.end();
}
Object.defineProperty(Duplex.prototype, 'destroyed', {
  // making it explicit this property is not enumerable
  // because otherwise some prototype manipulation in
  // userland will fail
  enumerable: false,
  get: function get() {
    if (this._readableState === undefined || this._writableState === undefined) {
      return false;
    }
    return this._readableState.destroyed && this._writableState.destroyed;
  },
  set: function set(value) {
    // we ignore the value if the stream
    // has not been initialized yet
    if (this._readableState === undefined || this._writableState === undefined) {
      return;
    }

    // backward compatibility, the user is explicitly
    // managing destroyed
    this._readableState.destroyed = value;
    this._writableState.destroyed = value;
  }
});
}).call(this)}).call(this,require('_process'))

},{"./_stream_readable":90,"./_stream_writable":92,"_process":71,"inherits":56}],89:[function(require,module,exports){
// 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.

// a passthrough stream.
// basically just the most minimal sort of Transform stream.
// Every written chunk gets output as-is.

'use strict';

module.exports = PassThrough;
var Transform = require('./_stream_transform');
require('inherits')(PassThrough, Transform);
function PassThrough(options) {
  if (!(this instanceof PassThrough)) return new PassThrough(options);
  Transform.call(this, options);
}
PassThrough.prototype._transform = function (chunk, encoding, cb) {
  cb(null, chunk);
};
},{"./_stream_transform":91,"inherits":56}],90:[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.

'use strict';

module.exports = Readable;

/*<replacement>*/
var Duplex;
/*</replacement>*/

Readable.ReadableState = ReadableState;

/*<replacement>*/
var EE = require('events').EventEmitter;
var EElistenerCount = function EElistenerCount(emitter, type) {
  return emitter.listeners(type).length;
};
/*</replacement>*/

/*<replacement>*/
var Stream = require('./internal/streams/stream');
/*</replacement>*/

var Buffer = require('buffer').Buffer;
var OurUint8Array = (typeof global !== 'undefined' ? global : typeof window !== 'undefined' ? window : typeof self !== 'undefined' ? self : {}).Uint8Array || function () {};
function _uint8ArrayToBuffer(chunk) {
  return Buffer.from(chunk);
}
function _isUint8Array(obj) {
  return Buffer.isBuffer(obj) || obj instanceof OurUint8Array;
}

/*<replacement>*/
var debugUtil = require('util');
var debug;
if (debugUtil && debugUtil.debuglog) {
  debug = debugUtil.debuglog('stream');
} else {
  debug = function debug() {};
}
/*</replacement>*/

var BufferList = require('./internal/streams/buffer_list');
var destroyImpl = require('./internal/streams/destroy');
var _require = require('./internal/streams/state'),
  getHighWaterMark = _require.getHighWaterMark;
var _require$codes = require('../errors').codes,
  ERR_INVALID_ARG_TYPE = _require$codes.ERR_INVALID_ARG_TYPE,
  ERR_STREAM_PUSH_AFTER_EOF = _require$codes.ERR_STREAM_PUSH_AFTER_EOF,
  ERR_METHOD_NOT_IMPLEMENTED = _require$codes.ERR_METHOD_NOT_IMPLEMENTED,
  ERR_STREAM_UNSHIFT_AFTER_END_EVENT = _require$codes.ERR_STREAM_UNSHIFT_AFTER_END_EVENT;

// Lazy loaded to improve the startup performance.
var StringDecoder;
var createReadableStreamAsyncIterator;
var from;
require('inherits')(Readable, Stream);
var errorOrDestroy = destroyImpl.errorOrDestroy;
var kProxyEvents = ['error', 'close', 'destroy', 'pause', 'resume'];
function prependListener(emitter, event, fn) {
  // Sadly this is not cacheable as some libraries bundle their own
  // event emitter implementation with them.
  if (typeof emitter.prependListener === 'function') return emitter.prependListener(event, fn);

  // This is a hack to make sure that our error handler is attached before any
  // userland ones.  NEVER DO THIS. This is here only because this code needs
  // to continue to work with older versions of Node.js that do not include
  // the prependListener() method. The goal is to eventually remove this hack.
  if (!emitter._events || !emitter._events[event]) emitter.on(event, fn);else if (Array.isArray(emitter._events[event])) emitter._events[event].unshift(fn);else emitter._events[event] = [fn, emitter._events[event]];
}
function ReadableState(options, stream, isDuplex) {
  Duplex = Duplex || require('./_stream_duplex');
  options = options || {};

  // Duplex streams are both readable and writable, but share
  // the same options object.
  // However, some cases require setting options to different
  // values for the readable and the writable sides of the duplex stream.
  // These options can be provided separately as readableXXX and writableXXX.
  if (typeof isDuplex !== 'boolean') isDuplex = stream instanceof Duplex;

  // object stream flag. Used to make read(n) ignore n and to
  // make all the buffer merging and length checks go away
  this.objectMode = !!options.objectMode;
  if (isDuplex) this.objectMode = this.objectMode || !!options.readableObjectMode;

  // the point at which it stops calling _read() to fill the buffer
  // Note: 0 is a valid value, means "don't call _read preemptively ever"
  this.highWaterMark = getHighWaterMark(this, options, 'readableHighWaterMark', isDuplex);

  // A linked list is used to store data chunks instead of an array because the
  // linked list can remove elements from the beginning faster than
  // array.shift()
  this.buffer = new BufferList();
  this.length = 0;
  this.pipes = null;
  this.pipesCount = 0;
  this.flowing = null;
  this.ended = false;
  this.endEmitted = false;
  this.reading = false;

  // a flag to be able to tell if the event 'readable'/'data' is emitted
  // immediately, or on a later tick.  We set this to true at first, because
  // any actions that shouldn't happen until "later" should generally also
  // not happen before the first read call.
  this.sync = true;

  // whenever we return null, then we set a flag to say
  // that we're awaiting a 'readable' event emission.
  this.needReadable = false;
  this.emittedReadable = false;
  this.readableListening = false;
  this.resumeScheduled = false;
  this.paused = true;

  // Should close be emitted on destroy. Defaults to true.
  this.emitClose = options.emitClose !== false;

  // Should .destroy() be called after 'end' (and potentially 'finish')
  this.autoDestroy = !!options.autoDestroy;

  // has it been destroyed
  this.destroyed = false;

  // Crypto is kind of old and crusty.  Historically, its default string
  // encoding is 'binary' so we have to make this configurable.
  // Everything else in the universe uses 'utf8', though.
  this.defaultEncoding = options.defaultEncoding || 'utf8';

  // the number of writers that are awaiting a drain event in .pipe()s
  this.awaitDrain = 0;

  // if true, a maybeReadMore has been scheduled
  this.readingMore = false;
  this.decoder = null;
  this.encoding = null;
  if (options.encoding) {
    if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder;
    this.decoder = new StringDecoder(options.encoding);
    this.encoding = options.encoding;
  }
}
function Readable(options) {
  Duplex = Duplex || require('./_stream_duplex');
  if (!(this instanceof Readable)) return new Readable(options);

  // Checking for a Stream.Duplex instance is faster here instead of inside
  // the ReadableState constructor, at least with V8 6.5
  var isDuplex = this instanceof Duplex;
  this._readableState = new ReadableState(options, this, isDuplex);

  // legacy
  this.readable = true;
  if (options) {
    if (typeof options.read === 'function') this._read = options.read;
    if (typeof options.destroy === 'function') this._destroy = options.destroy;
  }
  Stream.call(this);
}
Object.defineProperty(Readable.prototype, 'destroyed', {
  // making it explicit this property is not enumerable
  // because otherwise some prototype manipulation in
  // userland will fail
  enumerable: false,
  get: function get() {
    if (this._readableState === undefined) {
      return false;
    }
    return this._readableState.destroyed;
  },
  set: function set(value) {
    // we ignore the value if the stream
    // has not been initialized yet
    if (!this._readableState) {
      return;
    }

    // backward compatibility, the user is explicitly
    // managing destroyed
    this._readableState.destroyed = value;
  }
});
Readable.prototype.destroy = destroyImpl.destroy;
Readable.prototype._undestroy = destroyImpl.undestroy;
Readable.prototype._destroy = function (err, cb) {
  cb(err);
};

// Manually shove something into the read() buffer.
// This returns true if the highWaterMark has not been hit yet,
// similar to how Writable.write() returns true if you should
// write() some more.
Readable.prototype.push = function (chunk, encoding) {
  var state = this._readableState;
  var skipChunkCheck;
  if (!state.objectMode) {
    if (typeof chunk === 'string') {
      encoding = encoding || state.defaultEncoding;
      if (encoding !== state.encoding) {
        chunk = Buffer.from(chunk, encoding);
        encoding = '';
      }
      skipChunkCheck = true;
    }
  } else {
    skipChunkCheck = true;
  }
  return readableAddChunk(this, chunk, encoding, false, skipChunkCheck);
};

// Unshift should *always* be something directly out of read()
Readable.prototype.unshift = function (chunk) {
  return readableAddChunk(this, chunk, null, true, false);
};
function readableAddChunk(stream, chunk, encoding, addToFront, skipChunkCheck) {
  debug('readableAddChunk', chunk);
  var state = stream._readableState;
  if (chunk === null) {
    state.reading = false;
    onEofChunk(stream, state);
  } else {
    var er;
    if (!skipChunkCheck) er = chunkInvalid(state, chunk);
    if (er) {
      errorOrDestroy(stream, er);
    } else if (state.objectMode || chunk && chunk.length > 0) {
      if (typeof chunk !== 'string' && !state.objectMode && Object.getPrototypeOf(chunk) !== Buffer.prototype) {
        chunk = _uint8ArrayToBuffer(chunk);
      }
      if (addToFront) {
        if (state.endEmitted) errorOrDestroy(stream, new ERR_STREAM_UNSHIFT_AFTER_END_EVENT());else addChunk(stream, state, chunk, true);
      } else if (state.ended) {
        errorOrDestroy(stream, new ERR_STREAM_PUSH_AFTER_EOF());
      } else if (state.destroyed) {
        return false;
      } else {
        state.reading = false;
        if (state.decoder && !encoding) {
          chunk = state.decoder.write(chunk);
          if (state.objectMode || chunk.length !== 0) addChunk(stream, state, chunk, false);else maybeReadMore(stream, state);
        } else {
          addChunk(stream, state, chunk, false);
        }
      }
    } else if (!addToFront) {
      state.reading = false;
      maybeReadMore(stream, state);
    }
  }

  // We can push more data if we are below the highWaterMark.
  // Also, if we have no data yet, we can stand some more bytes.
  // This is to work around cases where hwm=0, such as the repl.
  return !state.ended && (state.length < state.highWaterMark || state.length === 0);
}
function addChunk(stream, state, chunk, addToFront) {
  if (state.flowing && state.length === 0 && !state.sync) {
    state.awaitDrain = 0;
    stream.emit('data', chunk);
  } else {
    // update the buffer info.
    state.length += state.objectMode ? 1 : chunk.length;
    if (addToFront) state.buffer.unshift(chunk);else state.buffer.push(chunk);
    if (state.needReadable) emitReadable(stream);
  }
  maybeReadMore(stream, state);
}
function chunkInvalid(state, chunk) {
  var er;
  if (!_isUint8Array(chunk) && typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) {
    er = new ERR_INVALID_ARG_TYPE('chunk', ['string', 'Buffer', 'Uint8Array'], chunk);
  }
  return er;
}
Readable.prototype.isPaused = function () {
  return this._readableState.flowing === false;
};

// backwards compatibility.
Readable.prototype.setEncoding = function (enc) {
  if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder;
  var decoder = new StringDecoder(enc);
  this._readableState.decoder = decoder;
  // If setEncoding(null), decoder.encoding equals utf8
  this._readableState.encoding = this._readableState.decoder.encoding;

  // Iterate over current buffer to convert already stored Buffers:
  var p = this._readableState.buffer.head;
  var content = '';
  while (p !== null) {
    content += decoder.write(p.data);
    p = p.next;
  }
  this._readableState.buffer.clear();
  if (content !== '') this._readableState.buffer.push(content);
  this._readableState.length = content.length;
  return this;
};

// Don't raise the hwm > 1GB
var MAX_HWM = 0x40000000;
function computeNewHighWaterMark(n) {
  if (n >= MAX_HWM) {
    // TODO(ronag): Throw ERR_VALUE_OUT_OF_RANGE.
    n = MAX_HWM;
  } else {
    // Get the next highest power of 2 to prevent increasing hwm excessively in
    // tiny amounts
    n--;
    n |= n >>> 1;
    n |= n >>> 2;
    n |= n >>> 4;
    n |= n >>> 8;
    n |= n >>> 16;
    n++;
  }
  return n;
}

// This function is designed to be inlinable, so please take care when making
// changes to the function body.
function howMuchToRead(n, state) {
  if (n <= 0 || state.length === 0 && state.ended) return 0;
  if (state.objectMode) return 1;
  if (n !== n) {
    // Only flow one buffer at a time
    if (state.flowing && state.length) return state.buffer.head.data.length;else return state.length;
  }
  // If we're asking for more than the current hwm, then raise the hwm.
  if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n);
  if (n <= state.length) return n;
  // Don't have enough
  if (!state.ended) {
    state.needReadable = true;
    return 0;
  }
  return state.length;
}

// you can override either this method, or the async _read(n) below.
Readable.prototype.read = function (n) {
  debug('read', n);
  n = parseInt(n, 10);
  var state = this._readableState;
  var nOrig = n;
  if (n !== 0) state.emittedReadable = false;

  // if we're doing read(0) to trigger a readable event, but we
  // already have a bunch of data in the buffer, then just trigger
  // the 'readable' event and move on.
  if (n === 0 && state.needReadable && ((state.highWaterMark !== 0 ? state.length >= state.highWaterMark : state.length > 0) || state.ended)) {
    debug('read: emitReadable', state.length, state.ended);
    if (state.length === 0 && state.ended) endReadable(this);else emitReadable(this);
    return null;
  }
  n = howMuchToRead(n, state);

  // if we've ended, and we're now clear, then finish it up.
  if (n === 0 && state.ended) {
    if (state.length === 0) endReadable(this);
    return null;
  }

  // All the actual chunk generation logic needs to be
  // *below* the call to _read.  The reason is that in certain
  // synthetic stream cases, such as passthrough streams, _read
  // may be a completely synchronous operation which may change
  // the state of the read buffer, providing enough data when
  // before there was *not* enough.
  //
  // So, the steps are:
  // 1. Figure out what the state of things will be after we do
  // a read from the buffer.
  //
  // 2. If that resulting state will trigger a _read, then call _read.
  // Note that this may be asynchronous, or synchronous.  Yes, it is
  // deeply ugly to write APIs this way, but that still doesn't mean
  // that the Readable class should behave improperly, as streams are
  // designed to be sync/async agnostic.
  // Take note if the _read call is sync or async (ie, if the read call
  // has returned yet), so that we know whether or not it's safe to emit
  // 'readable' etc.
  //
  // 3. Actually pull the requested chunks out of the buffer and return.

  // if we need a readable event, then we need to do some reading.
  var doRead = state.needReadable;
  debug('need readable', doRead);

  // if we currently have less than the highWaterMark, then also read some
  if (state.length === 0 || state.length - n < state.highWaterMark) {
    doRead = true;
    debug('length less than watermark', doRead);
  }

  // however, if we've ended, then there's no point, and if we're already
  // reading, then it's unnecessary.
  if (state.ended || state.reading) {
    doRead = false;
    debug('reading or ended', doRead);
  } else if (doRead) {
    debug('do read');
    state.reading = true;
    state.sync = true;
    // if the length is currently zero, then we *need* a readable event.
    if (state.length === 0) state.needReadable = true;
    // call internal read method
    this._read(state.highWaterMark);
    state.sync = false;
    // If _read pushed data synchronously, then `reading` will be false,
    // and we need to re-evaluate how much data we can return to the user.
    if (!state.reading) n = howMuchToRead(nOrig, state);
  }
  var ret;
  if (n > 0) ret = fromList(n, state);else ret = null;
  if (ret === null) {
    state.needReadable = state.length <= state.highWaterMark;
    n = 0;
  } else {
    state.length -= n;
    state.awaitDrain = 0;
  }
  if (state.length === 0) {
    // If we have nothing in the buffer, then we want to know
    // as soon as we *do* get something into the buffer.
    if (!state.ended) state.needReadable = true;

    // If we tried to read() past the EOF, then emit end on the next tick.
    if (nOrig !== n && state.ended) endReadable(this);
  }
  if (ret !== null) this.emit('data', ret);
  return ret;
};
function onEofChunk(stream, state) {
  debug('onEofChunk');
  if (state.ended) return;
  if (state.decoder) {
    var chunk = state.decoder.end();
    if (chunk && chunk.length) {
      state.buffer.push(chunk);
      state.length += state.objectMode ? 1 : chunk.length;
    }
  }
  state.ended = true;
  if (state.sync) {
    // if we are sync, wait until next tick to emit the data.
    // Otherwise we risk emitting data in the flow()
    // the readable code triggers during a read() call
    emitReadable(stream);
  } else {
    // emit 'readable' now to make sure it gets picked up.
    state.needReadable = false;
    if (!state.emittedReadable) {
      state.emittedReadable = true;
      emitReadable_(stream);
    }
  }
}

// Don't emit readable right away in sync mode, because this can trigger
// another read() call => stack overflow.  This way, it might trigger
// a nextTick recursion warning, but that's not so bad.
function emitReadable(stream) {
  var state = stream._readableState;
  debug('emitReadable', state.needReadable, state.emittedReadable);
  state.needReadable = false;
  if (!state.emittedReadable) {
    debug('emitReadable', state.flowing);
    state.emittedReadable = true;
    process.nextTick(emitReadable_, stream);
  }
}
function emitReadable_(stream) {
  var state = stream._readableState;
  debug('emitReadable_', state.destroyed, state.length, state.ended);
  if (!state.destroyed && (state.length || state.ended)) {
    stream.emit('readable');
    state.emittedReadable = false;
  }

  // The stream needs another readable event if
  // 1. It is not flowing, as the flow mechanism will take
  //    care of it.
  // 2. It is not ended.
  // 3. It is below the highWaterMark, so we can schedule
  //    another readable later.
  state.needReadable = !state.flowing && !state.ended && state.length <= state.highWaterMark;
  flow(stream);
}

// at this point, the user has presumably seen the 'readable' event,
// and called read() to consume some data.  that may have triggered
// in turn another _read(n) call, in which case reading = true if
// it's in progress.
// However, if we're not ended, or reading, and the length < hwm,
// then go ahead and try to read some more preemptively.
function maybeReadMore(stream, state) {
  if (!state.readingMore) {
    state.readingMore = true;
    process.nextTick(maybeReadMore_, stream, state);
  }
}
function maybeReadMore_(stream, state) {
  // Attempt to read more data if we should.
  //
  // The conditions for reading more data are (one of):
  // - Not enough data buffered (state.length < state.highWaterMark). The loop
  //   is responsible for filling the buffer with enough data if such data
  //   is available. If highWaterMark is 0 and we are not in the flowing mode
  //   we should _not_ attempt to buffer any extra data. We'll get more data
  //   when the stream consumer calls read() instead.
  // - No data in the buffer, and the stream is in flowing mode. In this mode
  //   the loop below is responsible for ensuring read() is called. Failing to
  //   call read here would abort the flow and there's no other mechanism for
  //   continuing the flow if the stream consumer has just subscribed to the
  //   'data' event.
  //
  // In addition to the above conditions to keep reading data, the following
  // conditions prevent the data from being read:
  // - The stream has ended (state.ended).
  // - There is already a pending 'read' operation (state.reading). This is a
  //   case where the the stream has called the implementation defined _read()
  //   method, but they are processing the call asynchronously and have _not_
  //   called push() with new data. In this case we skip performing more
  //   read()s. The execution ends in this method again after the _read() ends
  //   up calling push() with more data.
  while (!state.reading && !state.ended && (state.length < state.highWaterMark || state.flowing && state.length === 0)) {
    var len = state.length;
    debug('maybeReadMore read 0');
    stream.read(0);
    if (len === state.length)
      // didn't get any data, stop spinning.
      break;
  }
  state.readingMore = false;
}

// abstract method.  to be overridden in specific implementation classes.
// call cb(er, data) where data is <= n in length.
// for virtual (non-string, non-buffer) streams, "length" is somewhat
// arbitrary, and perhaps not very meaningful.
Readable.prototype._read = function (n) {
  errorOrDestroy(this, new ERR_METHOD_NOT_IMPLEMENTED('_read()'));
};
Readable.prototype.pipe = function (dest, pipeOpts) {
  var src = this;
  var state = this._readableState;
  switch (state.pipesCount) {
    case 0:
      state.pipes = dest;
      break;
    case 1:
      state.pipes = [state.pipes, dest];
      break;
    default:
      state.pipes.push(dest);
      break;
  }
  state.pipesCount += 1;
  debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts);
  var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr;
  var endFn = doEnd ? onend : unpipe;
  if (state.endEmitted) process.nextTick(endFn);else src.once('end', endFn);
  dest.on('unpipe', onunpipe);
  function onunpipe(readable, unpipeInfo) {
    debug('onunpipe');
    if (readable === src) {
      if (unpipeInfo && unpipeInfo.hasUnpiped === false) {
        unpipeInfo.hasUnpiped = true;
        cleanup();
      }
    }
  }
  function onend() {
    debug('onend');
    dest.end();
  }

  // when the dest drains, it reduces the awaitDrain counter
  // on the source.  This would be more elegant with a .once()
  // handler in flow(), but adding and removing repeatedly is
  // too slow.
  var ondrain = pipeOnDrain(src);
  dest.on('drain', ondrain);
  var cleanedUp = false;
  function cleanup() {
    debug('cleanup');
    // cleanup event handlers once the pipe is broken
    dest.removeListener('close', onclose);
    dest.removeListener('finish', onfinish);
    dest.removeListener('drain', ondrain);
    dest.removeListener('error', onerror);
    dest.removeListener('unpipe', onunpipe);
    src.removeListener('end', onend);
    src.removeListener('end', unpipe);
    src.removeListener('data', ondata);
    cleanedUp = true;

    // if the reader is waiting for a drain event from this
    // specific writer, then it would cause it to never start
    // flowing again.
    // So, if this is awaiting a drain, then we just call it now.
    // If we don't know, then assume that we are waiting for one.
    if (state.awaitDrain && (!dest._writableState || dest._writableState.needDrain)) ondrain();
  }
  src.on('data', ondata);
  function ondata(chunk) {
    debug('ondata');
    var ret = dest.write(chunk);
    debug('dest.write', ret);
    if (ret === false) {
      // If the user unpiped during `dest.write()`, it is possible
      // to get stuck in a permanently paused state if that write
      // also returned false.
      // => Check whether `dest` is still a piping destination.
      if ((state.pipesCount === 1 && state.pipes === dest || state.pipesCount > 1 && indexOf(state.pipes, dest) !== -1) && !cleanedUp) {
        debug('false write response, pause', state.awaitDrain);
        state.awaitDrain++;
      }
      src.pause();
    }
  }

  // if the dest has an error, then stop piping into it.
  // however, don't suppress the throwing behavior for this.
  function onerror(er) {
    debug('onerror', er);
    unpipe();
    dest.removeListener('error', onerror);
    if (EElistenerCount(dest, 'error') === 0) errorOrDestroy(dest, er);
  }

  // Make sure our error handler is attached before userland ones.
  prependListener(dest, 'error', onerror);

  // Both close and finish should trigger unpipe, but only once.
  function onclose() {
    dest.removeListener('finish', onfinish);
    unpipe();
  }
  dest.once('close', onclose);
  function onfinish() {
    debug('onfinish');
    dest.removeListener('close', onclose);
    unpipe();
  }
  dest.once('finish', onfinish);
  function unpipe() {
    debug('unpipe');
    src.unpipe(dest);
  }

  // tell the dest that it's being piped to
  dest.emit('pipe', src);

  // start the flow if it hasn't been started already.
  if (!state.flowing) {
    debug('pipe resume');
    src.resume();
  }
  return dest;
};
function pipeOnDrain(src) {
  return function pipeOnDrainFunctionResult() {
    var state = src._readableState;
    debug('pipeOnDrain', state.awaitDrain);
    if (state.awaitDrain) state.awaitDrain--;
    if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) {
      state.flowing = true;
      flow(src);
    }
  };
}
Readable.prototype.unpipe = function (dest) {
  var state = this._readableState;
  var unpipeInfo = {
    hasUnpiped: false
  };

  // if we're not piping anywhere, then do nothing.
  if (state.pipesCount === 0) return this;

  // just one destination.  most common case.
  if (state.pipesCount === 1) {
    // passed in one, but it's not the right one.
    if (dest && dest !== state.pipes) return this;
    if (!dest) dest = state.pipes;

    // got a match.
    state.pipes = null;
    state.pipesCount = 0;
    state.flowing = false;
    if (dest) dest.emit('unpipe', this, unpipeInfo);
    return this;
  }

  // slow case. multiple pipe destinations.

  if (!dest) {
    // remove all.
    var dests = state.pipes;
    var len = state.pipesCount;
    state.pipes = null;
    state.pipesCount = 0;
    state.flowing = false;
    for (var i = 0; i < len; i++) dests[i].emit('unpipe', this, {
      hasUnpiped: false
    });
    return this;
  }

  // try to find the right one.
  var index = indexOf(state.pipes, dest);
  if (index === -1) return this;
  state.pipes.splice(index, 1);
  state.pipesCount -= 1;
  if (state.pipesCount === 1) state.pipes = state.pipes[0];
  dest.emit('unpipe', this, unpipeInfo);
  return this;
};

// set up data events if they are asked for
// Ensure readable listeners eventually get something
Readable.prototype.on = function (ev, fn) {
  var res = Stream.prototype.on.call(this, ev, fn);
  var state = this._readableState;
  if (ev === 'data') {
    // update readableListening so that resume() may be a no-op
    // a few lines down. This is needed to support once('readable').
    state.readableListening = this.listenerCount('readable') > 0;

    // Try start flowing on next tick if stream isn't explicitly paused
    if (state.flowing !== false) this.resume();
  } else if (ev === 'readable') {
    if (!state.endEmitted && !state.readableListening) {
      state.readableListening = state.needReadable = true;
      state.flowing = false;
      state.emittedReadable = false;
      debug('on readable', state.length, state.reading);
      if (state.length) {
        emitReadable(this);
      } else if (!state.reading) {
        process.nextTick(nReadingNextTick, this);
      }
    }
  }
  return res;
};
Readable.prototype.addListener = Readable.prototype.on;
Readable.prototype.removeListener = function (ev, fn) {
  var res = Stream.prototype.removeListener.call(this, ev, fn);
  if (ev === 'readable') {
    // We need to check if there is someone still listening to
    // readable and reset the state. However this needs to happen
    // after readable has been emitted but before I/O (nextTick) to
    // support once('readable', fn) cycles. This means that calling
    // resume within the same tick will have no
    // effect.
    process.nextTick(updateReadableListening, this);
  }
  return res;
};
Readable.prototype.removeAllListeners = function (ev) {
  var res = Stream.prototype.removeAllListeners.apply(this, arguments);
  if (ev === 'readable' || ev === undefined) {
    // We need to check if there is someone still listening to
    // readable and reset the state. However this needs to happen
    // after readable has been emitted but before I/O (nextTick) to
    // support once('readable', fn) cycles. This means that calling
    // resume within the same tick will have no
    // effect.
    process.nextTick(updateReadableListening, this);
  }
  return res;
};
function updateReadableListening(self) {
  var state = self._readableState;
  state.readableListening = self.listenerCount('readable') > 0;
  if (state.resumeScheduled && !state.paused) {
    // flowing needs to be set to true now, otherwise
    // the upcoming resume will not flow.
    state.flowing = true;

    // crude way to check if we should resume
  } else if (self.listenerCount('data') > 0) {
    self.resume();
  }
}
function nReadingNextTick(self) {
  debug('readable nexttick read 0');
  self.read(0);
}

// pause() and resume() are remnants of the legacy readable stream API
// If the user uses them, then switch into old mode.
Readable.prototype.resume = function () {
  var state = this._readableState;
  if (!state.flowing) {
    debug('resume');
    // we flow only if there is no one listening
    // for readable, but we still have to call
    // resume()
    state.flowing = !state.readableListening;
    resume(this, state);
  }
  state.paused = false;
  return this;
};
function resume(stream, state) {
  if (!state.resumeScheduled) {
    state.resumeScheduled = true;
    process.nextTick(resume_, stream, state);
  }
}
function resume_(stream, state) {
  debug('resume', state.reading);
  if (!state.reading) {
    stream.read(0);
  }
  state.resumeScheduled = false;
  stream.emit('resume');
  flow(stream);
  if (state.flowing && !state.reading) stream.read(0);
}
Readable.prototype.pause = function () {
  debug('call pause flowing=%j', this._readableState.flowing);
  if (this._readableState.flowing !== false) {
    debug('pause');
    this._readableState.flowing = false;
    this.emit('pause');
  }
  this._readableState.paused = true;
  return this;
};
function flow(stream) {
  var state = stream._readableState;
  debug('flow', state.flowing);
  while (state.flowing && stream.read() !== null);
}

// wrap an old-style stream as the async data source.
// This is *not* part of the readable stream interface.
// It is an ugly unfortunate mess of history.
Readable.prototype.wrap = function (stream) {
  var _this = this;
  var state = this._readableState;
  var paused = false;
  stream.on('end', function () {
    debug('wrapped end');
    if (state.decoder && !state.ended) {
      var chunk = state.decoder.end();
      if (chunk && chunk.length) _this.push(chunk);
    }
    _this.push(null);
  });
  stream.on('data', function (chunk) {
    debug('wrapped data');
    if (state.decoder) chunk = state.decoder.write(chunk);

    // don't skip over falsy values in objectMode
    if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return;
    var ret = _this.push(chunk);
    if (!ret) {
      paused = true;
      stream.pause();
    }
  });

  // proxy all the other methods.
  // important when wrapping filters and duplexes.
  for (var i in stream) {
    if (this[i] === undefined && typeof stream[i] === 'function') {
      this[i] = function methodWrap(method) {
        return function methodWrapReturnFunction() {
          return stream[method].apply(stream, arguments);
        };
      }(i);
    }
  }

  // proxy certain important events.
  for (var n = 0; n < kProxyEvents.length; n++) {
    stream.on(kProxyEvents[n], this.emit.bind(this, kProxyEvents[n]));
  }

  // when we try to consume some more bytes, simply unpause the
  // underlying stream.
  this._read = function (n) {
    debug('wrapped _read', n);
    if (paused) {
      paused = false;
      stream.resume();
    }
  };
  return this;
};
if (typeof Symbol === 'function') {
  Readable.prototype[Symbol.asyncIterator] = function () {
    if (createReadableStreamAsyncIterator === undefined) {
      createReadableStreamAsyncIterator = require('./internal/streams/async_iterator');
    }
    return createReadableStreamAsyncIterator(this);
  };
}
Object.defineProperty(Readable.prototype, 'readableHighWaterMark', {
  // making it explicit this property is not enumerable
  // because otherwise some prototype manipulation in
  // userland will fail
  enumerable: false,
  get: function get() {
    return this._readableState.highWaterMark;
  }
});
Object.defineProperty(Readable.prototype, 'readableBuffer', {
  // making it explicit this property is not enumerable
  // because otherwise some prototype manipulation in
  // userland will fail
  enumerable: false,
  get: function get() {
    return this._readableState && this._readableState.buffer;
  }
});
Object.defineProperty(Readable.prototype, 'readableFlowing', {
  // making it explicit this property is not enumerable
  // because otherwise some prototype manipulation in
  // userland will fail
  enumerable: false,
  get: function get() {
    return this._readableState.flowing;
  },
  set: function set(state) {
    if (this._readableState) {
      this._readableState.flowing = state;
    }
  }
});

// exposed for testing purposes only.
Readable._fromList = fromList;
Object.defineProperty(Readable.prototype, 'readableLength', {
  // making it explicit this property is not enumerable
  // because otherwise some prototype manipulation in
  // userland will fail
  enumerable: false,
  get: function get() {
    return this._readableState.length;
  }
});

// Pluck off n bytes from an array of buffers.
// Length is the combined lengths of all the buffers in the list.
// This function is designed to be inlinable, so please take care when making
// changes to the function body.
function fromList(n, state) {
  // nothing buffered
  if (state.length === 0) return null;
  var ret;
  if (state.objectMode) ret = state.buffer.shift();else if (!n || n >= state.length) {
    // read it all, truncate the list
    if (state.decoder) ret = state.buffer.join('');else if (state.buffer.length === 1) ret = state.buffer.first();else ret = state.buffer.concat(state.length);
    state.buffer.clear();
  } else {
    // read part of list
    ret = state.buffer.consume(n, state.decoder);
  }
  return ret;
}
function endReadable(stream) {
  var state = stream._readableState;
  debug('endReadable', state.endEmitted);
  if (!state.endEmitted) {
    state.ended = true;
    process.nextTick(endReadableNT, state, stream);
  }
}
function endReadableNT(state, stream) {
  debug('endReadableNT', state.endEmitted, state.length);

  // Check that we didn't get one last unshift.
  if (!state.endEmitted && state.length === 0) {
    state.endEmitted = true;
    stream.readable = false;
    stream.emit('end');
    if (state.autoDestroy) {
      // In case of duplex streams we need a way to detect
      // if the writable side is ready for autoDestroy as well
      var wState = stream._writableState;
      if (!wState || wState.autoDestroy && wState.finished) {
        stream.destroy();
      }
    }
  }
}
if (typeof Symbol === 'function') {
  Readable.from = function (iterable, opts) {
    if (from === undefined) {
      from = require('./internal/streams/from');
    }
    return from(Readable, iterable, opts);
  };
}
function indexOf(xs, x) {
  for (var i = 0, l = xs.length; i < l; i++) {
    if (xs[i] === x) return i;
  }
  return -1;
}
}).call(this)}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})

},{"../errors":87,"./_stream_duplex":88,"./internal/streams/async_iterator":93,"./internal/streams/buffer_list":94,"./internal/streams/destroy":95,"./internal/streams/from":97,"./internal/streams/state":99,"./internal/streams/stream":100,"_process":71,"buffer":25,"events":43,"inherits":56,"string_decoder/":102,"util":24}],91:[function(require,module,exports){
// 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.

// a transform stream is a readable/writable stream where you do
// something with the data.  Sometimes it's called a "filter",
// but that's not a great name for it, since that implies a thing where
// some bits pass through, and others are simply ignored.  (That would
// be a valid example of a transform, of course.)
//
// While the output is causally related to the input, it's not a
// necessarily symmetric or synchronous transformation.  For example,
// a zlib stream might take multiple plain-text writes(), and then
// emit a single compressed chunk some time in the future.
//
// Here's how this works:
//
// The Transform stream has all the aspects of the readable and writable
// stream classes.  When you write(chunk), that calls _write(chunk,cb)
// internally, and returns false if there's a lot of pending writes
// buffered up.  When you call read(), that calls _read(n) until
// there's enough pending readable data buffered up.
//
// In a transform stream, the written data is placed in a buffer.  When
// _read(n) is called, it transforms the queued up data, calling the
// buffered _write cb's as it consumes chunks.  If consuming a single
// written chunk would result in multiple output chunks, then the first
// outputted bit calls the readcb, and subsequent chunks just go into
// the read buffer, and will cause it to emit 'readable' if necessary.
//
// This way, back-pressure is actually determined by the reading side,
// since _read has to be called to start processing a new chunk.  However,
// a pathological inflate type of transform can cause excessive buffering
// here.  For example, imagine a stream where every byte of input is
// interpreted as an integer from 0-255, and then results in that many
// bytes of output.  Writing the 4 bytes {ff,ff,ff,ff} would result in
// 1kb of data being output.  In this case, you could write a very small
// amount of input, and end up with a very large amount of output.  In
// such a pathological inflating mechanism, there'd be no way to tell
// the system to stop doing the transform.  A single 4MB write could
// cause the system to run out of memory.
//
// However, even in such a pathological case, only a single written chunk
// would be consumed, and then the rest would wait (un-transformed) until
// the results of the previous transformed chunk were consumed.

'use strict';

module.exports = Transform;
var _require$codes = require('../errors').codes,
  ERR_METHOD_NOT_IMPLEMENTED = _require$codes.ERR_METHOD_NOT_IMPLEMENTED,
  ERR_MULTIPLE_CALLBACK = _require$codes.ERR_MULTIPLE_CALLBACK,
  ERR_TRANSFORM_ALREADY_TRANSFORMING = _require$codes.ERR_TRANSFORM_ALREADY_TRANSFORMING,
  ERR_TRANSFORM_WITH_LENGTH_0 = _require$codes.ERR_TRANSFORM_WITH_LENGTH_0;
var Duplex = require('./_stream_duplex');
require('inherits')(Transform, Duplex);
function afterTransform(er, data) {
  var ts = this._transformState;
  ts.transforming = false;
  var cb = ts.writecb;
  if (cb === null) {
    return this.emit('error', new ERR_MULTIPLE_CALLBACK());
  }
  ts.writechunk = null;
  ts.writecb = null;
  if (data != null)
    // single equals check for both `null` and `undefined`
    this.push(data);
  cb(er);
  var rs = this._readableState;
  rs.reading = false;
  if (rs.needReadable || rs.length < rs.highWaterMark) {
    this._read(rs.highWaterMark);
  }
}
function Transform(options) {
  if (!(this instanceof Transform)) return new Transform(options);
  Duplex.call(this, options);
  this._transformState = {
    afterTransform: afterTransform.bind(this),
    needTransform: false,
    transforming: false,
    writecb: null,
    writechunk: null,
    writeencoding: null
  };

  // start out asking for a readable event once data is transformed.
  this._readableState.needReadable = true;

  // we have implemented the _read method, and done the other things
  // that Readable wants before the first _read call, so unset the
  // sync guard flag.
  this._readableState.sync = false;
  if (options) {
    if (typeof options.transform === 'function') this._transform = options.transform;
    if (typeof options.flush === 'function') this._flush = options.flush;
  }

  // When the writable side finishes, then flush out anything remaining.
  this.on('prefinish', prefinish);
}
function prefinish() {
  var _this = this;
  if (typeof this._flush === 'function' && !this._readableState.destroyed) {
    this._flush(function (er, data) {
      done(_this, er, data);
    });
  } else {
    done(this, null, null);
  }
}
Transform.prototype.push = function (chunk, encoding) {
  this._transformState.needTransform = false;
  return Duplex.prototype.push.call(this, chunk, encoding);
};

// This is the part where you do stuff!
// override this function in implementation classes.
// 'chunk' is an input chunk.
//
// Call `push(newChunk)` to pass along transformed output
// to the readable side.  You may call 'push' zero or more times.
//
// Call `cb(err)` when you are done with this chunk.  If you pass
// an error, then that'll put the hurt on the whole operation.  If you
// never call cb(), then you'll never get another chunk.
Transform.prototype._transform = function (chunk, encoding, cb) {
  cb(new ERR_METHOD_NOT_IMPLEMENTED('_transform()'));
};
Transform.prototype._write = function (chunk, encoding, cb) {
  var ts = this._transformState;
  ts.writecb = cb;
  ts.writechunk = chunk;
  ts.writeencoding = encoding;
  if (!ts.transforming) {
    var rs = this._readableState;
    if (ts.needTransform || rs.needReadable || rs.length < rs.highWaterMark) this._read(rs.highWaterMark);
  }
};

// Doesn't matter what the args are here.
// _transform does all the work.
// That we got here means that the readable side wants more data.
Transform.prototype._read = function (n) {
  var ts = this._transformState;
  if (ts.writechunk !== null && !ts.transforming) {
    ts.transforming = true;
    this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform);
  } else {
    // mark that we need a transform, so that any data that comes in
    // will get processed, now that we've asked for it.
    ts.needTransform = true;
  }
};
Transform.prototype._destroy = function (err, cb) {
  Duplex.prototype._destroy.call(this, err, function (err2) {
    cb(err2);
  });
};
function done(stream, er, data) {
  if (er) return stream.emit('error', er);
  if (data != null)
    // single equals check for both `null` and `undefined`
    stream.push(data);

  // TODO(BridgeAR): Write a test for these two error cases
  // if there's nothing in the write buffer, then that means
  // that nothing more will ever be provided
  if (stream._writableState.length) throw new ERR_TRANSFORM_WITH_LENGTH_0();
  if (stream._transformState.transforming) throw new ERR_TRANSFORM_ALREADY_TRANSFORMING();
  return stream.push(null);
}
},{"../errors":87,"./_stream_duplex":88,"inherits":56}],92:[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.

// A bit simpler than readable streams.
// Implement an async ._write(chunk, encoding, cb), and it'll handle all
// the drain event emission and buffering.

'use strict';

module.exports = Writable;

/* <replacement> */
function WriteReq(chunk, encoding, cb) {
  this.chunk = chunk;
  this.encoding = encoding;
  this.callback = cb;
  this.next = null;
}

// It seems a linked list but it is not
// there will be only 2 of these for each stream
function CorkedRequest(state) {
  var _this = this;
  this.next = null;
  this.entry = null;
  this.finish = function () {
    onCorkedFinish(_this, state);
  };
}
/* </replacement> */

/*<replacement>*/
var Duplex;
/*</replacement>*/

Writable.WritableState = WritableState;

/*<replacement>*/
var internalUtil = {
  deprecate: require('util-deprecate')
};
/*</replacement>*/

/*<replacement>*/
var Stream = require('./internal/streams/stream');
/*</replacement>*/

var Buffer = require('buffer').Buffer;
var OurUint8Array = (typeof global !== 'undefined' ? global : typeof window !== 'undefined' ? window : typeof self !== 'undefined' ? self : {}).Uint8Array || function () {};
function _uint8ArrayToBuffer(chunk) {
  return Buffer.from(chunk);
}
function _isUint8Array(obj) {
  return Buffer.isBuffer(obj) || obj instanceof OurUint8Array;
}
var destroyImpl = require('./internal/streams/destroy');
var _require = require('./internal/streams/state'),
  getHighWaterMark = _require.getHighWaterMark;
var _require$codes = require('../errors').codes,
  ERR_INVALID_ARG_TYPE = _require$codes.ERR_INVALID_ARG_TYPE,
  ERR_METHOD_NOT_IMPLEMENTED = _require$codes.ERR_METHOD_NOT_IMPLEMENTED,
  ERR_MULTIPLE_CALLBACK = _require$codes.ERR_MULTIPLE_CALLBACK,
  ERR_STREAM_CANNOT_PIPE = _require$codes.ERR_STREAM_CANNOT_PIPE,
  ERR_STREAM_DESTROYED = _require$codes.ERR_STREAM_DESTROYED,
  ERR_STREAM_NULL_VALUES = _require$codes.ERR_STREAM_NULL_VALUES,
  ERR_STREAM_WRITE_AFTER_END = _require$codes.ERR_STREAM_WRITE_AFTER_END,
  ERR_UNKNOWN_ENCODING = _require$codes.ERR_UNKNOWN_ENCODING;
var errorOrDestroy = destroyImpl.errorOrDestroy;
require('inherits')(Writable, Stream);
function nop() {}
function WritableState(options, stream, isDuplex) {
  Duplex = Duplex || require('./_stream_duplex');
  options = options || {};

  // Duplex streams are both readable and writable, but share
  // the same options object.
  // However, some cases require setting options to different
  // values for the readable and the writable sides of the duplex stream,
  // e.g. options.readableObjectMode vs. options.writableObjectMode, etc.
  if (typeof isDuplex !== 'boolean') isDuplex = stream instanceof Duplex;

  // object stream flag to indicate whether or not this stream
  // contains buffers or objects.
  this.objectMode = !!options.objectMode;
  if (isDuplex) this.objectMode = this.objectMode || !!options.writableObjectMode;

  // the point at which write() starts returning false
  // Note: 0 is a valid value, means that we always return false if
  // the entire buffer is not flushed immediately on write()
  this.highWaterMark = getHighWaterMark(this, options, 'writableHighWaterMark', isDuplex);

  // if _final has been called
  this.finalCalled = false;

  // drain event flag.
  this.needDrain = false;
  // at the start of calling end()
  this.ending = false;
  // when end() has been called, and returned
  this.ended = false;
  // when 'finish' is emitted
  this.finished = false;

  // has it been destroyed
  this.destroyed = false;

  // should we decode strings into buffers before passing to _write?
  // this is here so that some node-core streams can optimize string
  // handling at a lower level.
  var noDecode = options.decodeStrings === false;
  this.decodeStrings = !noDecode;

  // Crypto is kind of old and crusty.  Historically, its default string
  // encoding is 'binary' so we have to make this configurable.
  // Everything else in the universe uses 'utf8', though.
  this.defaultEncoding = options.defaultEncoding || 'utf8';

  // not an actual buffer we keep track of, but a measurement
  // of how much we're waiting to get pushed to some underlying
  // socket or file.
  this.length = 0;

  // a flag to see when we're in the middle of a write.
  this.writing = false;

  // when true all writes will be buffered until .uncork() call
  this.corked = 0;

  // a flag to be able to tell if the onwrite cb is called immediately,
  // or on a later tick.  We set this to true at first, because any
  // actions that shouldn't happen until "later" should generally also
  // not happen before the first write call.
  this.sync = true;

  // a flag to know if we're processing previously buffered items, which
  // may call the _write() callback in the same tick, so that we don't
  // end up in an overlapped onwrite situation.
  this.bufferProcessing = false;

  // the callback that's passed to _write(chunk,cb)
  this.onwrite = function (er) {
    onwrite(stream, er);
  };

  // the callback that the user supplies to write(chunk,encoding,cb)
  this.writecb = null;

  // the amount that is being written when _write is called.
  this.writelen = 0;
  this.bufferedRequest = null;
  this.lastBufferedRequest = null;

  // number of pending user-supplied write callbacks
  // this must be 0 before 'finish' can be emitted
  this.pendingcb = 0;

  // emit prefinish if the only thing we're waiting for is _write cbs
  // This is relevant for synchronous Transform streams
  this.prefinished = false;

  // True if the error was already emitted and should not be thrown again
  this.errorEmitted = false;

  // Should close be emitted on destroy. Defaults to true.
  this.emitClose = options.emitClose !== false;

  // Should .destroy() be called after 'finish' (and potentially 'end')
  this.autoDestroy = !!options.autoDestroy;

  // count buffered requests
  this.bufferedRequestCount = 0;

  // allocate the first CorkedRequest, there is always
  // one allocated and free to use, and we maintain at most two
  this.corkedRequestsFree = new CorkedRequest(this);
}
WritableState.prototype.getBuffer = function getBuffer() {
  var current = this.bufferedRequest;
  var out = [];
  while (current) {
    out.push(current);
    current = current.next;
  }
  return out;
};
(function () {
  try {
    Object.defineProperty(WritableState.prototype, 'buffer', {
      get: internalUtil.deprecate(function writableStateBufferGetter() {
        return this.getBuffer();
      }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.', 'DEP0003')
    });
  } catch (_) {}
})();

// Test _writableState for inheritance to account for Duplex streams,
// whose prototype chain only points to Readable.
var realHasInstance;
if (typeof Symbol === 'function' && Symbol.hasInstance && typeof Function.prototype[Symbol.hasInstance] === 'function') {
  realHasInstance = Function.prototype[Symbol.hasInstance];
  Object.defineProperty(Writable, Symbol.hasInstance, {
    value: function value(object) {
      if (realHasInstance.call(this, object)) return true;
      if (this !== Writable) return false;
      return object && object._writableState instanceof WritableState;
    }
  });
} else {
  realHasInstance = function realHasInstance(object) {
    return object instanceof this;
  };
}
function Writable(options) {
  Duplex = Duplex || require('./_stream_duplex');

  // Writable ctor is applied to Duplexes, too.
  // `realHasInstance` is necessary because using plain `instanceof`
  // would return false, as no `_writableState` property is attached.

  // Trying to use the custom `instanceof` for Writable here will also break the
  // Node.js LazyTransform implementation, which has a non-trivial getter for
  // `_writableState` that would lead to infinite recursion.

  // Checking for a Stream.Duplex instance is faster here instead of inside
  // the WritableState constructor, at least with V8 6.5
  var isDuplex = this instanceof Duplex;
  if (!isDuplex && !realHasInstance.call(Writable, this)) return new Writable(options);
  this._writableState = new WritableState(options, this, isDuplex);

  // legacy.
  this.writable = true;
  if (options) {
    if (typeof options.write === 'function') this._write = options.write;
    if (typeof options.writev === 'function') this._writev = options.writev;
    if (typeof options.destroy === 'function') this._destroy = options.destroy;
    if (typeof options.final === 'function') this._final = options.final;
  }
  Stream.call(this);
}

// Otherwise people can pipe Writable streams, which is just wrong.
Writable.prototype.pipe = function () {
  errorOrDestroy(this, new ERR_STREAM_CANNOT_PIPE());
};
function writeAfterEnd(stream, cb) {
  var er = new ERR_STREAM_WRITE_AFTER_END();
  // TODO: defer error events consistently everywhere, not just the cb
  errorOrDestroy(stream, er);
  process.nextTick(cb, er);
}

// Checks that a user-supplied chunk is valid, especially for the particular
// mode the stream is in. Currently this means that `null` is never accepted
// and undefined/non-string values are only allowed in object mode.
function validChunk(stream, state, chunk, cb) {
  var er;
  if (chunk === null) {
    er = new ERR_STREAM_NULL_VALUES();
  } else if (typeof chunk !== 'string' && !state.objectMode) {
    er = new ERR_INVALID_ARG_TYPE('chunk', ['string', 'Buffer'], chunk);
  }
  if (er) {
    errorOrDestroy(stream, er);
    process.nextTick(cb, er);
    return false;
  }
  return true;
}
Writable.prototype.write = function (chunk, encoding, cb) {
  var state = this._writableState;
  var ret = false;
  var isBuf = !state.objectMode && _isUint8Array(chunk);
  if (isBuf && !Buffer.isBuffer(chunk)) {
    chunk = _uint8ArrayToBuffer(chunk);
  }
  if (typeof encoding === 'function') {
    cb = encoding;
    encoding = null;
  }
  if (isBuf) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding;
  if (typeof cb !== 'function') cb = nop;
  if (state.ending) writeAfterEnd(this, cb);else if (isBuf || validChunk(this, state, chunk, cb)) {
    state.pendingcb++;
    ret = writeOrBuffer(this, state, isBuf, chunk, encoding, cb);
  }
  return ret;
};
Writable.prototype.cork = function () {
  this._writableState.corked++;
};
Writable.prototype.uncork = function () {
  var state = this._writableState;
  if (state.corked) {
    state.corked--;
    if (!state.writing && !state.corked && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state);
  }
};
Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) {
  // node::ParseEncoding() requires lower case.
  if (typeof encoding === 'string') encoding = encoding.toLowerCase();
  if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', 'raw'].indexOf((encoding + '').toLowerCase()) > -1)) throw new ERR_UNKNOWN_ENCODING(encoding);
  this._writableState.defaultEncoding = encoding;
  return this;
};
Object.defineProperty(Writable.prototype, 'writableBuffer', {
  // making it explicit this property is not enumerable
  // because otherwise some prototype manipulation in
  // userland will fail
  enumerable: false,
  get: function get() {
    return this._writableState && this._writableState.getBuffer();
  }
});
function decodeChunk(state, chunk, encoding) {
  if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') {
    chunk = Buffer.from(chunk, encoding);
  }
  return chunk;
}
Object.defineProperty(Writable.prototype, 'writableHighWaterMark', {
  // making it explicit this property is not enumerable
  // because otherwise some prototype manipulation in
  // userland will fail
  enumerable: false,
  get: function get() {
    return this._writableState.highWaterMark;
  }
});

// if we're already writing something, then just put this
// in the queue, and wait our turn.  Otherwise, call _write
// If we return false, then we need a drain event, so set that flag.
function writeOrBuffer(stream, state, isBuf, chunk, encoding, cb) {
  if (!isBuf) {
    var newChunk = decodeChunk(state, chunk, encoding);
    if (chunk !== newChunk) {
      isBuf = true;
      encoding = 'buffer';
      chunk = newChunk;
    }
  }
  var len = state.objectMode ? 1 : chunk.length;
  state.length += len;
  var ret = state.length < state.highWaterMark;
  // we must ensure that previous needDrain will not be reset to false.
  if (!ret) state.needDrain = true;
  if (state.writing || state.corked) {
    var last = state.lastBufferedRequest;
    state.lastBufferedRequest = {
      chunk: chunk,
      encoding: encoding,
      isBuf: isBuf,
      callback: cb,
      next: null
    };
    if (last) {
      last.next = state.lastBufferedRequest;
    } else {
      state.bufferedRequest = state.lastBufferedRequest;
    }
    state.bufferedRequestCount += 1;
  } else {
    doWrite(stream, state, false, len, chunk, encoding, cb);
  }
  return ret;
}
function doWrite(stream, state, writev, len, chunk, encoding, cb) {
  state.writelen = len;
  state.writecb = cb;
  state.writing = true;
  state.sync = true;
  if (state.destroyed) state.onwrite(new ERR_STREAM_DESTROYED('write'));else if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite);
  state.sync = false;
}
function onwriteError(stream, state, sync, er, cb) {
  --state.pendingcb;
  if (sync) {
    // defer the callback if we are being called synchronously
    // to avoid piling up things on the stack
    process.nextTick(cb, er);
    // this can emit finish, and it will always happen
    // after error
    process.nextTick(finishMaybe, stream, state);
    stream._writableState.errorEmitted = true;
    errorOrDestroy(stream, er);
  } else {
    // the caller expect this to happen before if
    // it is async
    cb(er);
    stream._writableState.errorEmitted = true;
    errorOrDestroy(stream, er);
    // this can emit finish, but finish must
    // always follow error
    finishMaybe(stream, state);
  }
}
function onwriteStateUpdate(state) {
  state.writing = false;
  state.writecb = null;
  state.length -= state.writelen;
  state.writelen = 0;
}
function onwrite(stream, er) {
  var state = stream._writableState;
  var sync = state.sync;
  var cb = state.writecb;
  if (typeof cb !== 'function') throw new ERR_MULTIPLE_CALLBACK();
  onwriteStateUpdate(state);
  if (er) onwriteError(stream, state, sync, er, cb);else {
    // Check if we're actually ready to finish, but don't emit yet
    var finished = needFinish(state) || stream.destroyed;
    if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) {
      clearBuffer(stream, state);
    }
    if (sync) {
      process.nextTick(afterWrite, stream, state, finished, cb);
    } else {
      afterWrite(stream, state, finished, cb);
    }
  }
}
function afterWrite(stream, state, finished, cb) {
  if (!finished) onwriteDrain(stream, state);
  state.pendingcb--;
  cb();
  finishMaybe(stream, state);
}

// Must force callback to be called on nextTick, so that we don't
// emit 'drain' before the write() consumer gets the 'false' return
// value, and has a chance to attach a 'drain' listener.
function onwriteDrain(stream, state) {
  if (state.length === 0 && state.needDrain) {
    state.needDrain = false;
    stream.emit('drain');
  }
}

// if there's something in the buffer waiting, then process it
function clearBuffer(stream, state) {
  state.bufferProcessing = true;
  var entry = state.bufferedRequest;
  if (stream._writev && entry && entry.next) {
    // Fast case, write everything using _writev()
    var l = state.bufferedRequestCount;
    var buffer = new Array(l);
    var holder = state.corkedRequestsFree;
    holder.entry = entry;
    var count = 0;
    var allBuffers = true;
    while (entry) {
      buffer[count] = entry;
      if (!entry.isBuf) allBuffers = false;
      entry = entry.next;
      count += 1;
    }
    buffer.allBuffers = allBuffers;
    doWrite(stream, state, true, state.length, buffer, '', holder.finish);

    // doWrite is almost always async, defer these to save a bit of time
    // as the hot path ends with doWrite
    state.pendingcb++;
    state.lastBufferedRequest = null;
    if (holder.next) {
      state.corkedRequestsFree = holder.next;
      holder.next = null;
    } else {
      state.corkedRequestsFree = new CorkedRequest(state);
    }
    state.bufferedRequestCount = 0;
  } else {
    // Slow case, write chunks one-by-one
    while (entry) {
      var chunk = entry.chunk;
      var encoding = entry.encoding;
      var cb = entry.callback;
      var len = state.objectMode ? 1 : chunk.length;
      doWrite(stream, state, false, len, chunk, encoding, cb);
      entry = entry.next;
      state.bufferedRequestCount--;
      // if we didn't call the onwrite immediately, then
      // it means that we need to wait until it does.
      // also, that means that the chunk and cb are currently
      // being processed, so move the buffer counter past them.
      if (state.writing) {
        break;
      }
    }
    if (entry === null) state.lastBufferedRequest = null;
  }
  state.bufferedRequest = entry;
  state.bufferProcessing = false;
}
Writable.prototype._write = function (chunk, encoding, cb) {
  cb(new ERR_METHOD_NOT_IMPLEMENTED('_write()'));
};
Writable.prototype._writev = null;
Writable.prototype.end = function (chunk, encoding, cb) {
  var state = this._writableState;
  if (typeof chunk === 'function') {
    cb = chunk;
    chunk = null;
    encoding = null;
  } else if (typeof encoding === 'function') {
    cb = encoding;
    encoding = null;
  }
  if (chunk !== null && chunk !== undefined) this.write(chunk, encoding);

  // .end() fully uncorks
  if (state.corked) {
    state.corked = 1;
    this.uncork();
  }

  // ignore unnecessary end() calls.
  if (!state.ending) endWritable(this, state, cb);
  return this;
};
Object.defineProperty(Writable.prototype, 'writableLength', {
  // making it explicit this property is not enumerable
  // because otherwise some prototype manipulation in
  // userland will fail
  enumerable: false,
  get: function get() {
    return this._writableState.length;
  }
});
function needFinish(state) {
  return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing;
}
function callFinal(stream, state) {
  stream._final(function (err) {
    state.pendingcb--;
    if (err) {
      errorOrDestroy(stream, err);
    }
    state.prefinished = true;
    stream.emit('prefinish');
    finishMaybe(stream, state);
  });
}
function prefinish(stream, state) {
  if (!state.prefinished && !state.finalCalled) {
    if (typeof stream._final === 'function' && !state.destroyed) {
      state.pendingcb++;
      state.finalCalled = true;
      process.nextTick(callFinal, stream, state);
    } else {
      state.prefinished = true;
      stream.emit('prefinish');
    }
  }
}
function finishMaybe(stream, state) {
  var need = needFinish(state);
  if (need) {
    prefinish(stream, state);
    if (state.pendingcb === 0) {
      state.finished = true;
      stream.emit('finish');
      if (state.autoDestroy) {
        // In case of duplex streams we need a way to detect
        // if the readable side is ready for autoDestroy as well
        var rState = stream._readableState;
        if (!rState || rState.autoDestroy && rState.endEmitted) {
          stream.destroy();
        }
      }
    }
  }
  return need;
}
function endWritable(stream, state, cb) {
  state.ending = true;
  finishMaybe(stream, state);
  if (cb) {
    if (state.finished) process.nextTick(cb);else stream.once('finish', cb);
  }
  state.ended = true;
  stream.writable = false;
}
function onCorkedFinish(corkReq, state, err) {
  var entry = corkReq.entry;
  corkReq.entry = null;
  while (entry) {
    var cb = entry.callback;
    state.pendingcb--;
    cb(err);
    entry = entry.next;
  }

  // reuse the free corkReq.
  state.corkedRequestsFree.next = corkReq;
}
Object.defineProperty(Writable.prototype, 'destroyed', {
  // making it explicit this property is not enumerable
  // because otherwise some prototype manipulation in
  // userland will fail
  enumerable: false,
  get: function get() {
    if (this._writableState === undefined) {
      return false;
    }
    return this._writableState.destroyed;
  },
  set: function set(value) {
    // we ignore the value if the stream
    // has not been initialized yet
    if (!this._writableState) {
      return;
    }

    // backward compatibility, the user is explicitly
    // managing destroyed
    this._writableState.destroyed = value;
  }
});
Writable.prototype.destroy = destroyImpl.destroy;
Writable.prototype._undestroy = destroyImpl.undestroy;
Writable.prototype._destroy = function (err, cb) {
  cb(err);
};
}).call(this)}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})

},{"../errors":87,"./_stream_duplex":88,"./internal/streams/destroy":95,"./internal/streams/state":99,"./internal/streams/stream":100,"_process":71,"buffer":25,"inherits":56,"util-deprecate":107}],93:[function(require,module,exports){
(function (process){(function (){
'use strict';

var _Object$setPrototypeO;
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
var finished = require('./end-of-stream');
var kLastResolve = Symbol('lastResolve');
var kLastReject = Symbol('lastReject');
var kError = Symbol('error');
var kEnded = Symbol('ended');
var kLastPromise = Symbol('lastPromise');
var kHandlePromise = Symbol('handlePromise');
var kStream = Symbol('stream');
function createIterResult(value, done) {
  return {
    value: value,
    done: done
  };
}
function readAndResolve(iter) {
  var resolve = iter[kLastResolve];
  if (resolve !== null) {
    var data = iter[kStream].read();
    // we defer if data is null
    // we can be expecting either 'end' or
    // 'error'
    if (data !== null) {
      iter[kLastPromise] = null;
      iter[kLastResolve] = null;
      iter[kLastReject] = null;
      resolve(createIterResult(data, false));
    }
  }
}
function onReadable(iter) {
  // we wait for the next tick, because it might
  // emit an error with process.nextTick
  process.nextTick(readAndResolve, iter);
}
function wrapForNext(lastPromise, iter) {
  return function (resolve, reject) {
    lastPromise.then(function () {
      if (iter[kEnded]) {
        resolve(createIterResult(undefined, true));
        return;
      }
      iter[kHandlePromise](resolve, reject);
    }, reject);
  };
}
var AsyncIteratorPrototype = Object.getPrototypeOf(function () {});
var ReadableStreamAsyncIteratorPrototype = Object.setPrototypeOf((_Object$setPrototypeO = {
  get stream() {
    return this[kStream];
  },
  next: function next() {
    var _this = this;
    // if we have detected an error in the meanwhile
    // reject straight away
    var error = this[kError];
    if (error !== null) {
      return Promise.reject(error);
    }
    if (this[kEnded]) {
      return Promise.resolve(createIterResult(undefined, true));
    }
    if (this[kStream].destroyed) {
      // We need to defer via nextTick because if .destroy(err) is
      // called, the error will be emitted via nextTick, and
      // we cannot guarantee that there is no error lingering around
      // waiting to be emitted.
      return new Promise(function (resolve, reject) {
        process.nextTick(function () {
          if (_this[kError]) {
            reject(_this[kError]);
          } else {
            resolve(createIterResult(undefined, true));
          }
        });
      });
    }

    // if we have multiple next() calls
    // we will wait for the previous Promise to finish
    // this logic is optimized to support for await loops,
    // where next() is only called once at a time
    var lastPromise = this[kLastPromise];
    var promise;
    if (lastPromise) {
      promise = new Promise(wrapForNext(lastPromise, this));
    } else {
      // fast path needed to support multiple this.push()
      // without triggering the next() queue
      var data = this[kStream].read();
      if (data !== null) {
        return Promise.resolve(createIterResult(data, false));
      }
      promise = new Promise(this[kHandlePromise]);
    }
    this[kLastPromise] = promise;
    return promise;
  }
}, _defineProperty(_Object$setPrototypeO, Symbol.asyncIterator, function () {
  return this;
}), _defineProperty(_Object$setPrototypeO, "return", function _return() {
  var _this2 = this;
  // destroy(err, cb) is a private API
  // we can guarantee we have that here, because we control the
  // Readable class this is attached to
  return new Promise(function (resolve, reject) {
    _this2[kStream].destroy(null, function (err) {
      if (err) {
        reject(err);
        return;
      }
      resolve(createIterResult(undefined, true));
    });
  });
}), _Object$setPrototypeO), AsyncIteratorPrototype);
var createReadableStreamAsyncIterator = function createReadableStreamAsyncIterator(stream) {
  var _Object$create;
  var iterator = Object.create(ReadableStreamAsyncIteratorPrototype, (_Object$create = {}, _defineProperty(_Object$create, kStream, {
    value: stream,
    writable: true
  }), _defineProperty(_Object$create, kLastResolve, {
    value: null,
    writable: true
  }), _defineProperty(_Object$create, kLastReject, {
    value: null,
    writable: true
  }), _defineProperty(_Object$create, kError, {
    value: null,
    writable: true
  }), _defineProperty(_Object$create, kEnded, {
    value: stream._readableState.endEmitted,
    writable: true
  }), _defineProperty(_Object$create, kHandlePromise, {
    value: function value(resolve, reject) {
      var data = iterator[kStream].read();
      if (data) {
        iterator[kLastPromise] = null;
        iterator[kLastResolve] = null;
        iterator[kLastReject] = null;
        resolve(createIterResult(data, false));
      } else {
        iterator[kLastResolve] = resolve;
        iterator[kLastReject] = reject;
      }
    },
    writable: true
  }), _Object$create));
  iterator[kLastPromise] = null;
  finished(stream, function (err) {
    if (err && err.code !== 'ERR_STREAM_PREMATURE_CLOSE') {
      var reject = iterator[kLastReject];
      // reject if we are waiting for data in the Promise
      // returned by next() and store the error
      if (reject !== null) {
        iterator[kLastPromise] = null;
        iterator[kLastResolve] = null;
        iterator[kLastReject] = null;
        reject(err);
      }
      iterator[kError] = err;
      return;
    }
    var resolve = iterator[kLastResolve];
    if (resolve !== null) {
      iterator[kLastPromise] = null;
      iterator[kLastResolve] = null;
      iterator[kLastReject] = null;
      resolve(createIterResult(undefined, true));
    }
    iterator[kEnded] = true;
  });
  stream.on('readable', onReadable.bind(null, iterator));
  return iterator;
};
module.exports = createReadableStreamAsyncIterator;
}).call(this)}).call(this,require('_process'))

},{"./end-of-stream":96,"_process":71}],94:[function(require,module,exports){
'use strict';

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
var _require = require('buffer'),
  Buffer = _require.Buffer;
var _require2 = require('util'),
  inspect = _require2.inspect;
var custom = inspect && inspect.custom || 'inspect';
function copyBuffer(src, target, offset) {
  Buffer.prototype.copy.call(src, target, offset);
}
module.exports = /*#__PURE__*/function () {
  function BufferList() {
    _classCallCheck(this, BufferList);
    this.head = null;
    this.tail = null;
    this.length = 0;
  }
  _createClass(BufferList, [{
    key: "push",
    value: function push(v) {
      var entry = {
        data: v,
        next: null
      };
      if (this.length > 0) this.tail.next = entry;else this.head = entry;
      this.tail = entry;
      ++this.length;
    }
  }, {
    key: "unshift",
    value: function unshift(v) {
      var entry = {
        data: v,
        next: this.head
      };
      if (this.length === 0) this.tail = entry;
      this.head = entry;
      ++this.length;
    }
  }, {
    key: "shift",
    value: function shift() {
      if (this.length === 0) return;
      var ret = this.head.data;
      if (this.length === 1) this.head = this.tail = null;else this.head = this.head.next;
      --this.length;
      return ret;
    }
  }, {
    key: "clear",
    value: function clear() {
      this.head = this.tail = null;
      this.length = 0;
    }
  }, {
    key: "join",
    value: function join(s) {
      if (this.length === 0) return '';
      var p = this.head;
      var ret = '' + p.data;
      while (p = p.next) ret += s + p.data;
      return ret;
    }
  }, {
    key: "concat",
    value: function concat(n) {
      if (this.length === 0) return Buffer.alloc(0);
      var ret = Buffer.allocUnsafe(n >>> 0);
      var p = this.head;
      var i = 0;
      while (p) {
        copyBuffer(p.data, ret, i);
        i += p.data.length;
        p = p.next;
      }
      return ret;
    }

    // Consumes a specified amount of bytes or characters from the buffered data.
  }, {
    key: "consume",
    value: function consume(n, hasStrings) {
      var ret;
      if (n < this.head.data.length) {
        // `slice` is the same for buffers and strings.
        ret = this.head.data.slice(0, n);
        this.head.data = this.head.data.slice(n);
      } else if (n === this.head.data.length) {
        // First chunk is a perfect match.
        ret = this.shift();
      } else {
        // Result spans more than one buffer.
        ret = hasStrings ? this._getString(n) : this._getBuffer(n);
      }
      return ret;
    }
  }, {
    key: "first",
    value: function first() {
      return this.head.data;
    }

    // Consumes a specified amount of characters from the buffered data.
  }, {
    key: "_getString",
    value: function _getString(n) {
      var p = this.head;
      var c = 1;
      var ret = p.data;
      n -= ret.length;
      while (p = p.next) {
        var str = p.data;
        var nb = n > str.length ? str.length : n;
        if (nb === str.length) ret += str;else ret += str.slice(0, n);
        n -= nb;
        if (n === 0) {
          if (nb === str.length) {
            ++c;
            if (p.next) this.head = p.next;else this.head = this.tail = null;
          } else {
            this.head = p;
            p.data = str.slice(nb);
          }
          break;
        }
        ++c;
      }
      this.length -= c;
      return ret;
    }

    // Consumes a specified amount of bytes from the buffered data.
  }, {
    key: "_getBuffer",
    value: function _getBuffer(n) {
      var ret = Buffer.allocUnsafe(n);
      var p = this.head;
      var c = 1;
      p.data.copy(ret);
      n -= p.data.length;
      while (p = p.next) {
        var buf = p.data;
        var nb = n > buf.length ? buf.length : n;
        buf.copy(ret, ret.length - n, 0, nb);
        n -= nb;
        if (n === 0) {
          if (nb === buf.length) {
            ++c;
            if (p.next) this.head = p.next;else this.head = this.tail = null;
          } else {
            this.head = p;
            p.data = buf.slice(nb);
          }
          break;
        }
        ++c;
      }
      this.length -= c;
      return ret;
    }

    // Make sure the linked list only shows the minimal necessary information.
  }, {
    key: custom,
    value: function value(_, options) {
      return inspect(this, _objectSpread(_objectSpread({}, options), {}, {
        // Only inspect one level.
        depth: 0,
        // It should not recurse.
        customInspect: false
      }));
    }
  }]);
  return BufferList;
}();
},{"buffer":25,"util":24}],95:[function(require,module,exports){
(function (process){(function (){
'use strict';

// undocumented cb() API, needed for core, not for public API
function destroy(err, cb) {
  var _this = this;
  var readableDestroyed = this._readableState && this._readableState.destroyed;
  var writableDestroyed = this._writableState && this._writableState.destroyed;
  if (readableDestroyed || writableDestroyed) {
    if (cb) {
      cb(err);
    } else if (err) {
      if (!this._writableState) {
        process.nextTick(emitErrorNT, this, err);
      } else if (!this._writableState.errorEmitted) {
        this._writableState.errorEmitted = true;
        process.nextTick(emitErrorNT, this, err);
      }
    }
    return this;
  }

  // we set destroyed to true before firing error callbacks in order
  // to make it re-entrance safe in case destroy() is called within callbacks

  if (this._readableState) {
    this._readableState.destroyed = true;
  }

  // if this is a duplex stream mark the writable part as destroyed as well
  if (this._writableState) {
    this._writableState.destroyed = true;
  }
  this._destroy(err || null, function (err) {
    if (!cb && err) {
      if (!_this._writableState) {
        process.nextTick(emitErrorAndCloseNT, _this, err);
      } else if (!_this._writableState.errorEmitted) {
        _this._writableState.errorEmitted = true;
        process.nextTick(emitErrorAndCloseNT, _this, err);
      } else {
        process.nextTick(emitCloseNT, _this);
      }
    } else if (cb) {
      process.nextTick(emitCloseNT, _this);
      cb(err);
    } else {
      process.nextTick(emitCloseNT, _this);
    }
  });
  return this;
}
function emitErrorAndCloseNT(self, err) {
  emitErrorNT(self, err);
  emitCloseNT(self);
}
function emitCloseNT(self) {
  if (self._writableState && !self._writableState.emitClose) return;
  if (self._readableState && !self._readableState.emitClose) return;
  self.emit('close');
}
function undestroy() {
  if (this._readableState) {
    this._readableState.destroyed = false;
    this._readableState.reading = false;
    this._readableState.ended = false;
    this._readableState.endEmitted = false;
  }
  if (this._writableState) {
    this._writableState.destroyed = false;
    this._writableState.ended = false;
    this._writableState.ending = false;
    this._writableState.finalCalled = false;
    this._writableState.prefinished = false;
    this._writableState.finished = false;
    this._writableState.errorEmitted = false;
  }
}
function emitErrorNT(self, err) {
  self.emit('error', err);
}
function errorOrDestroy(stream, err) {
  // We have tests that rely on errors being emitted
  // in the same tick, so changing this is semver major.
  // For now when you opt-in to autoDestroy we allow
  // the error to be emitted nextTick. In a future
  // semver major update we should change the default to this.

  var rState = stream._readableState;
  var wState = stream._writableState;
  if (rState && rState.autoDestroy || wState && wState.autoDestroy) stream.destroy(err);else stream.emit('error', err);
}
module.exports = {
  destroy: destroy,
  undestroy: undestroy,
  errorOrDestroy: errorOrDestroy
};
}).call(this)}).call(this,require('_process'))

},{"_process":71}],96:[function(require,module,exports){
// Ported from https://github.com/mafintosh/end-of-stream with
// permission from the author, Mathias Buus (@mafintosh).

'use strict';

var ERR_STREAM_PREMATURE_CLOSE = require('../../../errors').codes.ERR_STREAM_PREMATURE_CLOSE;
function once(callback) {
  var called = false;
  return function () {
    if (called) return;
    called = true;
    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
      args[_key] = arguments[_key];
    }
    callback.apply(this, args);
  };
}
function noop() {}
function isRequest(stream) {
  return stream.setHeader && typeof stream.abort === 'function';
}
function eos(stream, opts, callback) {
  if (typeof opts === 'function') return eos(stream, null, opts);
  if (!opts) opts = {};
  callback = once(callback || noop);
  var readable = opts.readable || opts.readable !== false && stream.readable;
  var writable = opts.writable || opts.writable !== false && stream.writable;
  var onlegacyfinish = function onlegacyfinish() {
    if (!stream.writable) onfinish();
  };
  var writableEnded = stream._writableState && stream._writableState.finished;
  var onfinish = function onfinish() {
    writable = false;
    writableEnded = true;
    if (!readable) callback.call(stream);
  };
  var readableEnded = stream._readableState && stream._readableState.endEmitted;
  var onend = function onend() {
    readable = false;
    readableEnded = true;
    if (!writable) callback.call(stream);
  };
  var onerror = function onerror(err) {
    callback.call(stream, err);
  };
  var onclose = function onclose() {
    var err;
    if (readable && !readableEnded) {
      if (!stream._readableState || !stream._readableState.ended) err = new ERR_STREAM_PREMATURE_CLOSE();
      return callback.call(stream, err);
    }
    if (writable && !writableEnded) {
      if (!stream._writableState || !stream._writableState.ended) err = new ERR_STREAM_PREMATURE_CLOSE();
      return callback.call(stream, err);
    }
  };
  var onrequest = function onrequest() {
    stream.req.on('finish', onfinish);
  };
  if (isRequest(stream)) {
    stream.on('complete', onfinish);
    stream.on('abort', onclose);
    if (stream.req) onrequest();else stream.on('request', onrequest);
  } else if (writable && !stream._writableState) {
    // legacy streams
    stream.on('end', onlegacyfinish);
    stream.on('close', onlegacyfinish);
  }
  stream.on('end', onend);
  stream.on('finish', onfinish);
  if (opts.error !== false) stream.on('error', onerror);
  stream.on('close', onclose);
  return function () {
    stream.removeListener('complete', onfinish);
    stream.removeListener('abort', onclose);
    stream.removeListener('request', onrequest);
    if (stream.req) stream.req.removeListener('finish', onfinish);
    stream.removeListener('end', onlegacyfinish);
    stream.removeListener('close', onlegacyfinish);
    stream.removeListener('finish', onfinish);
    stream.removeListener('end', onend);
    stream.removeListener('error', onerror);
    stream.removeListener('close', onclose);
  };
}
module.exports = eos;
},{"../../../errors":87}],97:[function(require,module,exports){
module.exports = function () {
  throw new Error('Readable.from is not available in the browser')
};

},{}],98:[function(require,module,exports){
// Ported from https://github.com/mafintosh/pump with
// permission from the author, Mathias Buus (@mafintosh).

'use strict';

var eos;
function once(callback) {
  var called = false;
  return function () {
    if (called) return;
    called = true;
    callback.apply(void 0, arguments);
  };
}
var _require$codes = require('../../../errors').codes,
  ERR_MISSING_ARGS = _require$codes.ERR_MISSING_ARGS,
  ERR_STREAM_DESTROYED = _require$codes.ERR_STREAM_DESTROYED;
function noop(err) {
  // Rethrow the error if it exists to avoid swallowing it
  if (err) throw err;
}
function isRequest(stream) {
  return stream.setHeader && typeof stream.abort === 'function';
}
function destroyer(stream, reading, writing, callback) {
  callback = once(callback);
  var closed = false;
  stream.on('close', function () {
    closed = true;
  });
  if (eos === undefined) eos = require('./end-of-stream');
  eos(stream, {
    readable: reading,
    writable: writing
  }, function (err) {
    if (err) return callback(err);
    closed = true;
    callback();
  });
  var destroyed = false;
  return function (err) {
    if (closed) return;
    if (destroyed) return;
    destroyed = true;

    // request.destroy just do .end - .abort is what we want
    if (isRequest(stream)) return stream.abort();
    if (typeof stream.destroy === 'function') return stream.destroy();
    callback(err || new ERR_STREAM_DESTROYED('pipe'));
  };
}
function call(fn) {
  fn();
}
function pipe(from, to) {
  return from.pipe(to);
}
function popCallback(streams) {
  if (!streams.length) return noop;
  if (typeof streams[streams.length - 1] !== 'function') return noop;
  return streams.pop();
}
function pipeline() {
  for (var _len = arguments.length, streams = new Array(_len), _key = 0; _key < _len; _key++) {
    streams[_key] = arguments[_key];
  }
  var callback = popCallback(streams);
  if (Array.isArray(streams[0])) streams = streams[0];
  if (streams.length < 2) {
    throw new ERR_MISSING_ARGS('streams');
  }
  var error;
  var destroys = streams.map(function (stream, i) {
    var reading = i < streams.length - 1;
    var writing = i > 0;
    return destroyer(stream, reading, writing, function (err) {
      if (!error) error = err;
      if (err) destroys.forEach(call);
      if (reading) return;
      destroys.forEach(call);
      callback(error);
    });
  });
  return streams.reduce(pipe);
}
module.exports = pipeline;
},{"../../../errors":87,"./end-of-stream":96}],99:[function(require,module,exports){
'use strict';

var ERR_INVALID_OPT_VALUE = require('../../../errors').codes.ERR_INVALID_OPT_VALUE;
function highWaterMarkFrom(options, isDuplex, duplexKey) {
  return options.highWaterMark != null ? options.highWaterMark : isDuplex ? options[duplexKey] : null;
}
function getHighWaterMark(state, options, duplexKey, isDuplex) {
  var hwm = highWaterMarkFrom(options, isDuplex, duplexKey);
  if (hwm != null) {
    if (!(isFinite(hwm) && Math.floor(hwm) === hwm) || hwm < 0) {
      var name = isDuplex ? duplexKey : 'highWaterMark';
      throw new ERR_INVALID_OPT_VALUE(name, hwm);
    }
    return Math.floor(hwm);
  }

  // Default value
  return state.objectMode ? 16 : 16 * 1024;
}
module.exports = {
  getHighWaterMark: getHighWaterMark
};
},{"../../../errors":87}],100:[function(require,module,exports){
module.exports = require('events').EventEmitter;

},{"events":43}],101:[function(require,module,exports){
exports = module.exports = require('./lib/_stream_readable.js');
exports.Stream = exports;
exports.Readable = exports;
exports.Writable = require('./lib/_stream_writable.js');
exports.Duplex = require('./lib/_stream_duplex.js');
exports.Transform = require('./lib/_stream_transform.js');
exports.PassThrough = require('./lib/_stream_passthrough.js');
exports.finished = require('./lib/internal/streams/end-of-stream.js');
exports.pipeline = require('./lib/internal/streams/pipeline.js');

},{"./lib/_stream_duplex.js":88,"./lib/_stream_passthrough.js":89,"./lib/_stream_readable.js":90,"./lib/_stream_transform.js":91,"./lib/_stream_writable.js":92,"./lib/internal/streams/end-of-stream.js":96,"./lib/internal/streams/pipeline.js":98}],102:[function(require,module,exports){
// 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.

'use strict';

/*<replacement>*/

var Buffer = require('safe-buffer').Buffer;
/*</replacement>*/

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

function _normalizeEncoding(enc) {
  if (!enc) return 'utf8';
  var retried;
  while (true) {
    switch (enc) {
      case 'utf8':
      case 'utf-8':
        return 'utf8';
      case 'ucs2':
      case 'ucs-2':
      case 'utf16le':
      case 'utf-16le':
        return 'utf16le';
      case 'latin1':
      case 'binary':
        return 'latin1';
      case 'base64':
      case 'ascii':
      case 'hex':
        return enc;
      default:
        if (retried) return; // undefined
        enc = ('' + enc).toLowerCase();
        retried = true;
    }
  }
};

// Do not cache `Buffer.isEncoding` when checking encoding names as some
// modules monkey-patch it to support additional encodings
function normalizeEncoding(enc) {
  var nenc = _normalizeEncoding(enc);
  if (typeof nenc !== 'string' && (Buffer.isEncoding === isEncoding || !isEncoding(enc))) throw new Error('Unknown encoding: ' + enc);
  return nenc || enc;
}

// StringDecoder provides an interface for efficiently splitting a series of
// buffers into a series of JS strings without breaking apart multi-byte
// characters.
exports.StringDecoder = StringDecoder;
function StringDecoder(encoding) {
  this.encoding = normalizeEncoding(encoding);
  var nb;
  switch (this.encoding) {
    case 'utf16le':
      this.text = utf16Text;
      this.end = utf16End;
      nb = 4;
      break;
    case 'utf8':
      this.fillLast = utf8FillLast;
      nb = 4;
      break;
    case 'base64':
      this.text = base64Text;
      this.end = base64End;
      nb = 3;
      break;
    default:
      this.write = simpleWrite;
      this.end = simpleEnd;
      return;
  }
  this.lastNeed = 0;
  this.lastTotal = 0;
  this.lastChar = Buffer.allocUnsafe(nb);
}

StringDecoder.prototype.write = function (buf) {
  if (buf.length === 0) return '';
  var r;
  var i;
  if (this.lastNeed) {
    r = this.fillLast(buf);
    if (r === undefined) return '';
    i = this.lastNeed;
    this.lastNeed = 0;
  } else {
    i = 0;
  }
  if (i < buf.length) return r ? r + this.text(buf, i) : this.text(buf, i);
  return r || '';
};

StringDecoder.prototype.end = utf8End;

// Returns only complete characters in a Buffer
StringDecoder.prototype.text = utf8Text;

// Attempts to complete a partial non-UTF-8 character using bytes from a Buffer
StringDecoder.prototype.fillLast = function (buf) {
  if (this.lastNeed <= buf.length) {
    buf.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, this.lastNeed);
    return this.lastChar.toString(this.encoding, 0, this.lastTotal);
  }
  buf.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, buf.length);
  this.lastNeed -= buf.length;
};

// Checks the type of a UTF-8 byte, whether it's ASCII, a leading byte, or a
// continuation byte. If an invalid byte is detected, -2 is returned.
function utf8CheckByte(byte) {
  if (byte <= 0x7F) return 0;else if (byte >> 5 === 0x06) return 2;else if (byte >> 4 === 0x0E) return 3;else if (byte >> 3 === 0x1E) return 4;
  return byte >> 6 === 0x02 ? -1 : -2;
}

// Checks at most 3 bytes at the end of a Buffer in order to detect an
// incomplete multi-byte UTF-8 character. The total number of bytes (2, 3, or 4)
// needed to complete the UTF-8 character (if applicable) are returned.
function utf8CheckIncomplete(self, buf, i) {
  var j = buf.length - 1;
  if (j < i) return 0;
  var nb = utf8CheckByte(buf[j]);
  if (nb >= 0) {
    if (nb > 0) self.lastNeed = nb - 1;
    return nb;
  }
  if (--j < i || nb === -2) return 0;
  nb = utf8CheckByte(buf[j]);
  if (nb >= 0) {
    if (nb > 0) self.lastNeed = nb - 2;
    return nb;
  }
  if (--j < i || nb === -2) return 0;
  nb = utf8CheckByte(buf[j]);
  if (nb >= 0) {
    if (nb > 0) {
      if (nb === 2) nb = 0;else self.lastNeed = nb - 3;
    }
    return nb;
  }
  return 0;
}

// Validates as many continuation bytes for a multi-byte UTF-8 character as
// needed or are available. If we see a non-continuation byte where we expect
// one, we "replace" the validated continuation bytes we've seen so far with
// a single UTF-8 replacement character ('\ufffd'), to match v8's UTF-8 decoding
// behavior. The continuation byte check is included three times in the case
// where all of the continuation bytes for a character exist in the same buffer.
// It is also done this way as a slight performance increase instead of using a
// loop.
function utf8CheckExtraBytes(self, buf, p) {
  if ((buf[0] & 0xC0) !== 0x80) {
    self.lastNeed = 0;
    return '\ufffd';
  }
  if (self.lastNeed > 1 && buf.length > 1) {
    if ((buf[1] & 0xC0) !== 0x80) {
      self.lastNeed = 1;
      return '\ufffd';
    }
    if (self.lastNeed > 2 && buf.length > 2) {
      if ((buf[2] & 0xC0) !== 0x80) {
        self.lastNeed = 2;
        return '\ufffd';
      }
    }
  }
}

// Attempts to complete a multi-byte UTF-8 character using bytes from a Buffer.
function utf8FillLast(buf) {
  var p = this.lastTotal - this.lastNeed;
  var r = utf8CheckExtraBytes(this, buf, p);
  if (r !== undefined) return r;
  if (this.lastNeed <= buf.length) {
    buf.copy(this.lastChar, p, 0, this.lastNeed);
    return this.lastChar.toString(this.encoding, 0, this.lastTotal);
  }
  buf.copy(this.lastChar, p, 0, buf.length);
  this.lastNeed -= buf.length;
}

// Returns all complete UTF-8 characters in a Buffer. If the Buffer ended on a
// partial character, the character's bytes are buffered until the required
// number of bytes are available.
function utf8Text(buf, i) {
  var total = utf8CheckIncomplete(this, buf, i);
  if (!this.lastNeed) return buf.toString('utf8', i);
  this.lastTotal = total;
  var end = buf.length - (total - this.lastNeed);
  buf.copy(this.lastChar, 0, end);
  return buf.toString('utf8', i, end);
}

// For UTF-8, a replacement character is added when ending on a partial
// character.
function utf8End(buf) {
  var r = buf && buf.length ? this.write(buf) : '';
  if (this.lastNeed) return r + '\ufffd';
  return r;
}

// UTF-16LE typically needs two bytes per character, but even if we have an even
// number of bytes available, we need to check if we end on a leading/high
// surrogate. In that case, we need to wait for the next two bytes in order to
// decode the last character properly.
function utf16Text(buf, i) {
  if ((buf.length - i) % 2 === 0) {
    var r = buf.toString('utf16le', i);
    if (r) {
      var c = r.charCodeAt(r.length - 1);
      if (c >= 0xD800 && c <= 0xDBFF) {
        this.lastNeed = 2;
        this.lastTotal = 4;
        this.lastChar[0] = buf[buf.length - 2];
        this.lastChar[1] = buf[buf.length - 1];
        return r.slice(0, -1);
      }
    }
    return r;
  }
  this.lastNeed = 1;
  this.lastTotal = 2;
  this.lastChar[0] = buf[buf.length - 1];
  return buf.toString('utf16le', i, buf.length - 1);
}

// For UTF-16LE we do not explicitly append special replacement characters if we
// end on a partial character, we simply let v8 handle that.
function utf16End(buf) {
  var r = buf && buf.length ? this.write(buf) : '';
  if (this.lastNeed) {
    var end = this.lastTotal - this.lastNeed;
    return r + this.lastChar.toString('utf16le', 0, end);
  }
  return r;
}

function base64Text(buf, i) {
  var n = (buf.length - i) % 3;
  if (n === 0) return buf.toString('base64', i);
  this.lastNeed = 3 - n;
  this.lastTotal = 3;
  if (n === 1) {
    this.lastChar[0] = buf[buf.length - 1];
  } else {
    this.lastChar[0] = buf[buf.length - 2];
    this.lastChar[1] = buf[buf.length - 1];
  }
  return buf.toString('base64', i, buf.length - n);
}

function base64End(buf) {
  var r = buf && buf.length ? this.write(buf) : '';
  if (this.lastNeed) return r + this.lastChar.toString('base64', 0, 3 - this.lastNeed);
  return r;
}

// Pass bytes on through for single-byte encodings (e.g. ascii, latin1, hex)
function simpleWrite(buf) {
  return buf.toString(this.encoding);
}

function simpleEnd(buf) {
  return buf && buf.length ? this.write(buf) : '';
}
},{"safe-buffer":78}],103:[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":104,"./util":105}],104:[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":105,"buffer":25}],105:[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);
}

},{}],106:[function(require,module,exports){
/*
 * 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.
 */

'use strict';

var punycode = require('punycode/');

function Url() {
  this.protocol = null;
  this.slashes = null;
  this.auth = null;
  this.host = null;
  this.port = null;
  this.hostname = null;
  this.hash = null;
  this.search = null;
  this.query = null;
  this.pathname = null;
  this.path = null;
  this.href = null;
}

// Reference: RFC 3986, RFC 1808, RFC 2396

/*
 * define these here so at least they only have to be
 * compiled once on the first module load.
 */
var protocolPattern = /^([a-z0-9.+-]+:)/i,
  portPattern = /:[0-9]*$/,

  // Special case for a simple path URL
  simplePathPattern = /^(\/\/?(?!\/)[^?\s]*)(\?[^\s]*)?$/,

  /*
   * RFC 2396: characters reserved for delimiting URLs.
   * We actually just auto-escape these.
   */
  delims = [
    '<', '>', '"', '`', ' ', '\r', '\n', '\t'
  ],

  // RFC 2396: characters not allowed for various reasons.
  unwise = [
    '{', '}', '|', '\\', '^', '`'
  ].concat(delims),

  // Allowed by RFCs, but cause of XSS attacks.  Always escape these.
  autoEscape = ['\''].concat(unwise),
  /*
   * Characters that are never ever allowed in a hostname.
   * Note that any invalid chars are also handled, but these
   * are the ones that are *expected* to be seen, so we fast-path
   * them.
   */
  nonHostChars = [
    '%', '/', '?', ';', '#'
  ].concat(autoEscape),
  hostEndingChars = [
    '/', '?', '#'
  ],
  hostnameMaxLen = 255,
  hostnamePartPattern = /^[+a-z0-9A-Z_-]{0,63}$/,
  hostnamePartStart = /^([+a-z0-9A-Z_-]{0,63})(.*)$/,
  // protocols that can allow "unsafe" and "unwise" chars.
  unsafeProtocol = {
    javascript: true,
    'javascript:': true
  },
  // protocols that never have a hostname.
  hostlessProtocol = {
    javascript: true,
    'javascript:': true
  },
  // protocols that always contain a // bit.
  slashedProtocol = {
    http: true,
    https: true,
    ftp: true,
    gopher: true,
    file: true,
    'http:': true,
    'https:': true,
    'ftp:': true,
    'gopher:': true,
    'file:': true
  },
  querystring = require('qs');

function urlParse(url, parseQueryString, slashesDenoteHost) {
  if (url && typeof url === 'object' && url instanceof Url) { return url; }

  var u = new Url();
  u.parse(url, parseQueryString, slashesDenoteHost);
  return u;
}

Url.prototype.parse = function (url, parseQueryString, slashesDenoteHost) {
  if (typeof url !== 'string') {
    throw new TypeError("Parameter 'url' must be a string, not " + typeof url);
  }

  /*
   * Copy chrome, IE, opera backslash-handling behavior.
   * Back slashes before the query string get converted to forward slashes
   * See: https://code.google.com/p/chromium/issues/detail?id=25916
   */
  var queryIndex = url.indexOf('?'),
    splitter = queryIndex !== -1 && queryIndex < url.indexOf('#') ? '?' : '#',
    uSplit = url.split(splitter),
    slashRegex = /\\/g;
  uSplit[0] = uSplit[0].replace(slashRegex, '/');
  url = uSplit.join(splitter);

  var rest = url;

  /*
   * trim before proceeding.
   * This is to support parse stuff like "  http://foo.com  \n"
   */
  rest = rest.trim();

  if (!slashesDenoteHost && url.split('#').length === 1) {
    // Try fast path regexp
    var simplePath = simplePathPattern.exec(rest);
    if (simplePath) {
      this.path = rest;
      this.href = rest;
      this.pathname = simplePath[1];
      if (simplePath[2]) {
        this.search = simplePath[2];
        if (parseQueryString) {
          this.query = querystring.parse(this.search.substr(1));
        } else {
          this.query = this.search.substr(1);
        }
      } else if (parseQueryString) {
        this.search = '';
        this.query = {};
      }
      return this;
    }
  }

  var proto = protocolPattern.exec(rest);
  if (proto) {
    proto = proto[0];
    var lowerProto = proto.toLowerCase();
    this.protocol = lowerProto;
    rest = rest.substr(proto.length);
  }

  /*
   * figure out if it's got a host
   * user@server is *always* interpreted as a hostname, and url
   * resolution will treat //foo/bar as host=foo,path=bar because that's
   * how the browser resolves relative URLs.
   */
  if (slashesDenoteHost || proto || rest.match(/^\/\/[^@/]+@[^@/]+/)) {
    var slashes = rest.substr(0, 2) === '//';
    if (slashes && !(proto && hostlessProtocol[proto])) {
      rest = rest.substr(2);
      this.slashes = true;
    }
  }

  if (!hostlessProtocol[proto] && (slashes || (proto && !slashedProtocol[proto]))) {

    /*
     * there's a hostname.
     * the first instance of /, ?, ;, or # ends the host.
     *
     * If there is an @ in the hostname, then non-host chars *are* allowed
     * to the left of the last @ sign, unless some host-ending character
     * comes *before* the @-sign.
     * URLs are obnoxious.
     *
     * ex:
     * http://a@b@c/ => user:a@b host:c
     * http://a@b?@c => user:a host:c path:/?@c
     */

    /*
     * v0.12 TODO(isaacs): This is not quite how Chrome does things.
     * Review our test case against browsers more comprehensively.
     */

    // find the first instance of any hostEndingChars
    var hostEnd = -1;
    for (var i = 0; i < hostEndingChars.length; i++) {
      var hec = rest.indexOf(hostEndingChars[i]);
      if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) { hostEnd = hec; }
    }

    /*
     * at this point, either we have an explicit point where the
     * auth portion cannot go past, or the last @ char is the decider.
     */
    var auth, atSign;
    if (hostEnd === -1) {
      // atSign can be anywhere.
      atSign = rest.lastIndexOf('@');
    } else {
      /*
       * atSign must be in auth portion.
       * http://a@b/c@d => host:b auth:a path:/c@d
       */
      atSign = rest.lastIndexOf('@', hostEnd);
    }

    /*
     * Now we have a portion which is definitely the auth.
     * Pull that off.
     */
    if (atSign !== -1) {
      auth = rest.slice(0, atSign);
      rest = rest.slice(atSign + 1);
      this.auth = decodeURIComponent(auth);
    }

    // the host is the remaining to the left of the first non-host char
    hostEnd = -1;
    for (var i = 0; i < nonHostChars.length; i++) {
      var hec = rest.indexOf(nonHostChars[i]);
      if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) { hostEnd = hec; }
    }
    // if we still have not hit it, then the entire thing is a host.
    if (hostEnd === -1) { hostEnd = rest.length; }

    this.host = rest.slice(0, hostEnd);
    rest = rest.slice(hostEnd);

    // pull out port.
    this.parseHost();

    /*
     * we've indicated that there is a hostname,
     * so even if it's empty, it has to be present.
     */
    this.hostname = this.hostname || '';

    /*
     * if hostname begins with [ and ends with ]
     * assume that it's an IPv6 address.
     */
    var ipv6Hostname = this.hostname[0] === '[' && this.hostname[this.hostname.length - 1] === ']';

    // validate a little.
    if (!ipv6Hostname) {
      var hostparts = this.hostname.split(/\./);
      for (var i = 0, l = hostparts.length; i < l; i++) {
        var part = hostparts[i];
        if (!part) { continue; }
        if (!part.match(hostnamePartPattern)) {
          var newpart = '';
          for (var j = 0, k = part.length; j < k; j++) {
            if (part.charCodeAt(j) > 127) {
              /*
               * we replace non-ASCII char with a temporary placeholder
               * we need this to make sure size of hostname is not
               * broken by replacing non-ASCII by nothing
               */
              newpart += 'x';
            } else {
              newpart += part[j];
            }
          }
          // we test again with ASCII char only
          if (!newpart.match(hostnamePartPattern)) {
            var validParts = hostparts.slice(0, i);
            var notHost = hostparts.slice(i + 1);
            var bit = part.match(hostnamePartStart);
            if (bit) {
              validParts.push(bit[1]);
              notHost.unshift(bit[2]);
            }
            if (notHost.length) {
              rest = '/' + notHost.join('.') + rest;
            }
            this.hostname = validParts.join('.');
            break;
          }
        }
      }
    }

    if (this.hostname.length > hostnameMaxLen) {
      this.hostname = '';
    } else {
      // hostnames are always lower case.
      this.hostname = this.hostname.toLowerCase();
    }

    if (!ipv6Hostname) {
      /*
       * IDNA Support: Returns a punycoded representation of "domain".
       * It only converts parts of the domain name that
       * have non-ASCII characters, i.e. it doesn't matter if
       * you call it with a domain that already is ASCII-only.
       */
      this.hostname = punycode.toASCII(this.hostname);
    }

    var p = this.port ? ':' + this.port : '';
    var h = this.hostname || '';
    this.host = h + p;
    this.href += this.host;

    /*
     * strip [ and ] from the hostname
     * the host field still retains them, though
     */
    if (ipv6Hostname) {
      this.hostname = this.hostname.substr(1, this.hostname.length - 2);
      if (rest[0] !== '/') {
        rest = '/' + rest;
      }
    }
  }

  /*
   * now rest is set to the post-host stuff.
   * chop off any delim chars.
   */
  if (!unsafeProtocol[lowerProto]) {

    /*
     * First, make 100% sure that any "autoEscape" chars get
     * escaped, even if encodeURIComponent doesn't think they
     * need to be.
     */
    for (var i = 0, l = autoEscape.length; i < l; i++) {
      var ae = autoEscape[i];
      if (rest.indexOf(ae) === -1) { continue; }
      var esc = encodeURIComponent(ae);
      if (esc === ae) {
        esc = escape(ae);
      }
      rest = rest.split(ae).join(esc);
    }
  }

  // chop off from the tail first.
  var hash = rest.indexOf('#');
  if (hash !== -1) {
    // got a fragment string.
    this.hash = rest.substr(hash);
    rest = rest.slice(0, hash);
  }
  var qm = rest.indexOf('?');
  if (qm !== -1) {
    this.search = rest.substr(qm);
    this.query = rest.substr(qm + 1);
    if (parseQueryString) {
      this.query = querystring.parse(this.query);
    }
    rest = rest.slice(0, qm);
  } else if (parseQueryString) {
    // no query string, but parseQueryString still requested
    this.search = '';
    this.query = {};
  }
  if (rest) { this.pathname = rest; }
  if (slashedProtocol[lowerProto] && this.hostname && !this.pathname) {
    this.pathname = '/';
  }

  // to support http.request
  if (this.pathname || this.search) {
    var p = this.pathname || '';
    var s = this.search || '';
    this.path = p + s;
  }

  // finally, reconstruct the href based on what has been validated.
  this.href = this.format();
  return this;
};

// format a parsed object into a url string
function urlFormat(obj) {
  /*
   * ensure it's an object, and not a string url.
   * If it's an obj, this is a no-op.
   * this way, you can call url_format() on strings
   * to clean up potentially wonky urls.
   */
  if (typeof obj === 'string') { obj = urlParse(obj); }
  if (!(obj instanceof Url)) { return Url.prototype.format.call(obj); }
  return obj.format();
}

Url.prototype.format = function () {
  var auth = this.auth || '';
  if (auth) {
    auth = encodeURIComponent(auth);
    auth = auth.replace(/%3A/i, ':');
    auth += '@';
  }

  var protocol = this.protocol || '',
    pathname = this.pathname || '',
    hash = this.hash || '',
    host = false,
    query = '';

  if (this.host) {
    host = auth + this.host;
  } else if (this.hostname) {
    host = auth + (this.hostname.indexOf(':') === -1 ? this.hostname : '[' + this.hostname + ']');
    if (this.port) {
      host += ':' + this.port;
    }
  }

  if (this.query && typeof this.query === 'object' && Object.keys(this.query).length) {
    query = querystring.stringify(this.query, {
      arrayFormat: 'repeat',
      addQueryPrefix: false
    });
  }

  var search = this.search || (query && ('?' + query)) || '';

  if (protocol && protocol.substr(-1) !== ':') { protocol += ':'; }

  /*
   * only the slashedProtocols get the //.  Not mailto:, xmpp:, etc.
   * unless they had them to begin with.
   */
  if (this.slashes || (!protocol || slashedProtocol[protocol]) && host !== false) {
    host = '//' + (host || '');
    if (pathname && pathname.charAt(0) !== '/') { pathname = '/' + pathname; }
  } else if (!host) {
    host = '';
  }

  if (hash && hash.charAt(0) !== '#') { hash = '#' + hash; }
  if (search && search.charAt(0) !== '?') { search = '?' + search; }

  pathname = pathname.replace(/[?#]/g, function (match) {
    return encodeURIComponent(match);
  });
  search = search.replace('#', '%23');

  return protocol + host + pathname + search + hash;
};

function urlResolve(source, relative) {
  return urlParse(source, false, true).resolve(relative);
}

Url.prototype.resolve = function (relative) {
  return this.resolveObject(urlParse(relative, false, true)).format();
};

function urlResolveObject(source, relative) {
  if (!source) { return relative; }
  return urlParse(source, false, true).resolveObject(relative);
}

Url.prototype.resolveObject = function (relative) {
  if (typeof relative === 'string') {
    var rel = new Url();
    rel.parse(relative, false, true);
    relative = rel;
  }

  var result = new Url();
  var tkeys = Object.keys(this);
  for (var tk = 0; tk < tkeys.length; tk++) {
    var tkey = tkeys[tk];
    result[tkey] = this[tkey];
  }

  /*
   * hash is always overridden, no matter what.
   * even href="" will remove it.
   */
  result.hash = relative.hash;

  // if the relative url is empty, then there's nothing left to do here.
  if (relative.href === '') {
    result.href = result.format();
    return result;
  }

  // hrefs like //foo/bar always cut to the protocol.
  if (relative.slashes && !relative.protocol) {
    // take everything except the protocol from relative
    var rkeys = Object.keys(relative);
    for (var rk = 0; rk < rkeys.length; rk++) {
      var rkey = rkeys[rk];
      if (rkey !== 'protocol') { result[rkey] = relative[rkey]; }
    }

    // urlParse appends trailing / to urls like http://www.example.com
    if (slashedProtocol[result.protocol] && result.hostname && !result.pathname) {
      result.pathname = '/';
      result.path = result.pathname;
    }

    result.href = result.format();
    return result;
  }

  if (relative.protocol && relative.protocol !== result.protocol) {
    /*
     * if it's a known url protocol, then changing
     * the protocol does weird things
     * first, if it's not file:, then we MUST have a host,
     * and if there was a path
     * to begin with, then we MUST have a path.
     * if it is file:, then the host is dropped,
     * because that's known to be hostless.
     * anything else is assumed to be absolute.
     */
    if (!slashedProtocol[relative.protocol]) {
      var keys = Object.keys(relative);
      for (var v = 0; v < keys.length; v++) {
        var k = keys[v];
        result[k] = relative[k];
      }
      result.href = result.format();
      return result;
    }

    result.protocol = relative.protocol;
    if (!relative.host && !hostlessProtocol[relative.protocol]) {
      var relPath = (relative.pathname || '').split('/');
      while (relPath.length && !(relative.host = relPath.shift())) { }
      if (!relative.host) { relative.host = ''; }
      if (!relative.hostname) { relative.hostname = ''; }
      if (relPath[0] !== '') { relPath.unshift(''); }
      if (relPath.length < 2) { relPath.unshift(''); }
      result.pathname = relPath.join('/');
    } else {
      result.pathname = relative.pathname;
    }
    result.search = relative.search;
    result.query = relative.query;
    result.host = relative.host || '';
    result.auth = relative.auth;
    result.hostname = relative.hostname || relative.host;
    result.port = relative.port;
    // to support http.request
    if (result.pathname || result.search) {
      var p = result.pathname || '';
      var s = result.search || '';
      result.path = p + s;
    }
    result.slashes = result.slashes || relative.slashes;
    result.href = result.format();
    return result;
  }

  var isSourceAbs = result.pathname && result.pathname.charAt(0) === '/',
    isRelAbs = relative.host || relative.pathname && relative.pathname.charAt(0) === '/',
    mustEndAbs = isRelAbs || isSourceAbs || (result.host && relative.pathname),
    removeAllDots = mustEndAbs,
    srcPath = result.pathname && result.pathname.split('/') || [],
    relPath = relative.pathname && relative.pathname.split('/') || [],
    psychotic = result.protocol && !slashedProtocol[result.protocol];

  /*
   * if the url is a non-slashed url, then relative
   * links like ../.. should be able
   * to crawl up to the hostname, as well.  This is strange.
   * result.protocol has already been set by now.
   * Later on, put the first path part into the host field.
   */
  if (psychotic) {
    result.hostname = '';
    result.port = null;
    if (result.host) {
      if (srcPath[0] === '') { srcPath[0] = result.host; } else { srcPath.unshift(result.host); }
    }
    result.host = '';
    if (relative.protocol) {
      relative.hostname = null;
      relative.port = null;
      if (relative.host) {
        if (relPath[0] === '') { relPath[0] = relative.host; } else { relPath.unshift(relative.host); }
      }
      relative.host = null;
    }
    mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === '');
  }

  if (isRelAbs) {
    // it's absolute.
    result.host = relative.host || relative.host === '' ? relative.host : result.host;
    result.hostname = relative.hostname || relative.hostname === '' ? relative.hostname : result.hostname;
    result.search = relative.search;
    result.query = relative.query;
    srcPath = relPath;
    // fall through to the dot-handling below.
  } else if (relPath.length) {
    /*
     * it's relative
     * throw away the existing file, and take the new path instead.
     */
    if (!srcPath) { srcPath = []; }
    srcPath.pop();
    srcPath = srcPath.concat(relPath);
    result.search = relative.search;
    result.query = relative.query;
  } else if (relative.search != null) {
    /*
     * just pull out the search.
     * like href='?foo'.
     * Put this after the other two cases because it simplifies the booleans
     */
    if (psychotic) {
      result.host = srcPath.shift();
      result.hostname = result.host;
      /*
       * occationaly the auth can get stuck only in host
       * this especially happens in cases like
       * url.resolveObject('mailto:local1@domain1', 'local2@domain2')
       */
      var authInHost = result.host && result.host.indexOf('@') > 0 ? result.host.split('@') : false;
      if (authInHost) {
        result.auth = authInHost.shift();
        result.hostname = authInHost.shift();
        result.host = result.hostname;
      }
    }
    result.search = relative.search;
    result.query = relative.query;
    // to support http.request
    if (result.pathname !== null || result.search !== null) {
      result.path = (result.pathname ? result.pathname : '') + (result.search ? result.search : '');
    }
    result.href = result.format();
    return result;
  }

  if (!srcPath.length) {
    /*
     * no path at all.  easy.
     * we've already handled the other stuff above.
     */
    result.pathname = null;
    // to support http.request
    if (result.search) {
      result.path = '/' + result.search;
    } else {
      result.path = null;
    }
    result.href = result.format();
    return result;
  }

  /*
   * if a url ENDs in . or .., then it must get a trailing slash.
   * however, if it ends in anything else non-slashy,
   * then it must NOT get a trailing slash.
   */
  var last = srcPath.slice(-1)[0];
  var hasTrailingSlash = (result.host || relative.host || srcPath.length > 1) && (last === '.' || last === '..') || last === '';

  /*
   * strip single dots, resolve double dots to parent dir
   * if the path tries to go above the root, `up` ends up > 0
   */
  var up = 0;
  for (var i = srcPath.length; i >= 0; i--) {
    last = srcPath[i];
    if (last === '.') {
      srcPath.splice(i, 1);
    } else if (last === '..') {
      srcPath.splice(i, 1);
      up++;
    } else if (up) {
      srcPath.splice(i, 1);
      up--;
    }
  }

  // if the path is allowed to go above the root, restore leading ..s
  if (!mustEndAbs && !removeAllDots) {
    for (; up--; up) {
      srcPath.unshift('..');
    }
  }

  if (mustEndAbs && srcPath[0] !== '' && (!srcPath[0] || srcPath[0].charAt(0) !== '/')) {
    srcPath.unshift('');
  }

  if (hasTrailingSlash && (srcPath.join('/').substr(-1) !== '/')) {
    srcPath.push('');
  }

  var isAbsolute = srcPath[0] === '' || (srcPath[0] && srcPath[0].charAt(0) === '/');

  // put the host back
  if (psychotic) {
    result.hostname = isAbsolute ? '' : srcPath.length ? srcPath.shift() : '';
    result.host = result.hostname;
    /*
     * occationaly the auth can get stuck only in host
     * this especially happens in cases like
     * url.resolveObject('mailto:local1@domain1', 'local2@domain2')
     */
    var authInHost = result.host && result.host.indexOf('@') > 0 ? result.host.split('@') : false;
    if (authInHost) {
      result.auth = authInHost.shift();
      result.hostname = authInHost.shift();
      result.host = result.hostname;
    }
  }

  mustEndAbs = mustEndAbs || (result.host && srcPath.length);

  if (mustEndAbs && !isAbsolute) {
    srcPath.unshift('');
  }

  if (srcPath.length > 0) {
    result.pathname = srcPath.join('/');
  } else {
    result.pathname = null;
    result.path = null;
  }

  // to support request.http
  if (result.pathname !== null || result.search !== null) {
    result.path = (result.pathname ? result.pathname : '') + (result.search ? result.search : '');
  }
  result.auth = relative.auth || result.auth;
  result.slashes = result.slashes || relative.slashes;
  result.href = result.format();
  return result;
};

Url.prototype.parseHost = function () {
  var host = this.host;
  var port = portPattern.exec(host);
  if (port) {
    port = port[0];
    if (port !== ':') {
      this.port = port.substr(1);
    }
    host = host.substr(0, host.length - port.length);
  }
  if (host) { this.hostname = host; }
};

exports.parse = urlParse;
exports.resolve = urlResolve;
exports.resolveObject = urlResolveObject;
exports.format = urlFormat;

exports.Url = Url;

},{"punycode/":72,"qs":74}],107:[function(require,module,exports){
(function (global){(function (){

/**
 * Module exports.
 */

module.exports = deprecate;

/**
 * Mark that a method should not be used.
 * Returns a modified function which warns once by default.
 *
 * If `localStorage.noDeprecation = true` is set, then it is a no-op.
 *
 * If `localStorage.throwDeprecation = true` is set, then deprecated functions
 * will throw an Error when invoked.
 *
 * If `localStorage.traceDeprecation = true` is set, then deprecated functions
 * will invoke `console.trace()` instead of `console.error()`.
 *
 * @param {Function} fn - the function to deprecate
 * @param {String} msg - the string to print to the console when `fn` is invoked
 * @returns {Function} a new "deprecated" version of `fn`
 * @api public
 */

function deprecate (fn, msg) {
  if (config('noDeprecation')) {
    return fn;
  }

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

  return deprecated;
}

/**
 * Checks `localStorage` for boolean values for the given `name`.
 *
 * @param {String} name
 * @returns {Boolean}
 * @api private
 */

function config (name) {
  // accessing global.localStorage can trigger a DOMException in sandboxed iframes
  try {
    if (!global.localStorage) return false;
  } catch (_) {
    return false;
  }
  var val = global.localStorage[name];
  if (null == val) return false;
  return String(val).toLowerCase() === 'true';
}

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

},{}],108:[function(require,module,exports){
module.exports = extend

var hasOwnProperty = Object.prototype.hasOwnProperty;

function extend() {
    var target = {}

    for (var i = 0; i < arguments.length; i++) {
        var source = arguments[i]

        for (var key in source) {
            if (hasOwnProperty.call(source, key)) {
                target[key] = source[key]
            }
        }
    }

    return target
}

},{}]},{},[6])
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJkaXN0L2FwaS1lcnJvcnMuanMiLCJkaXN0L2hvbWVicmlkZ2UtdWkvcHVibGljL2FwaS1zdGF0dXMuanMiLCJkaXN0L2hvbWVicmlkZ2UtdWkvcHVibGljL2NhcmRzLmpzIiwiZGlzdC9ob21lYnJpZGdlLXVpL3B1YmxpYy9jbGllbnQtY2xpZW50aWQuanMiLCJkaXN0L2hvbWVicmlkZ2UtdWkvcHVibGljL2NsaWVudC1pcGMuanMiLCJkaXN0L2hvbWVicmlkZ2UtdWkvcHVibGljL2NsaWVudC5qcyIsImRpc3QvaG9tZWJyaWRnZS11aS9wdWJsaWMvY29uZmlnLmpzIiwiZGlzdC9ob21lYnJpZGdlLXVpL3B1YmxpYy9mb3Jtcy5qcyIsImRpc3QvaG9tZWJyaWRnZS11aS9wdWJsaWMvbG9nZ2VyLmpzIiwiZGlzdC9ob21lYnJpZGdlLXVpL3B1YmxpYy91dGlscy1kb20uanMiLCJkaXN0L2xvZy1lcnJvci5qcyIsImRpc3QvdGkvYXBpLWF1dGgtdHlwZXMtdGkuanMiLCJkaXN0L3RpL2FwaS1hdXRoLXR5cGVzLmpzIiwiZGlzdC90aS9hcGktdHlwZXMtdGkuanMiLCJkaXN0L3RpL2FwaS10eXBlcy5qcyIsImRpc3QvdGkvY29uZmlnLXR5cGVzLXRpLmpzIiwiZGlzdC90aS9jb25maWctdHlwZXMuanMiLCJkaXN0L3V0aWxzLmpzIiwibm9kZV9tb2R1bGVzL2Fzc2VydC9hc3NlcnQuanMiLCJub2RlX21vZHVsZXMvYXNzZXJ0L25vZGVfbW9kdWxlcy9pbmhlcml0cy9pbmhlcml0c19icm93c2VyLmpzIiwibm9kZV9tb2R1bGVzL2Fzc2VydC9ub2RlX21vZHVsZXMvdXRpbC9zdXBwb3J0L2lzQnVmZmVyQnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9hc3NlcnQvbm9kZV9tb2R1bGVzL3V0aWwvdXRpbC5qcyIsIm5vZGVfbW9kdWxlcy9iYXNlNjQtanMvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnJvd3Nlci1yZXNvbHZlL2VtcHR5LmpzIiwibm9kZV9tb2R1bGVzL2J1ZmZlci9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9idWlsdGluLXN0YXR1cy1jb2Rlcy9icm93c2VyLmpzIiwibm9kZV9tb2R1bGVzL2NhbGwtYmluZC1hcHBseS1oZWxwZXJzL2FjdHVhbEFwcGx5LmpzIiwibm9kZV9tb2R1bGVzL2NhbGwtYmluZC1hcHBseS1oZWxwZXJzL2Z1bmN0aW9uQXBwbHkuanMiLCJub2RlX21vZHVsZXMvY2FsbC1iaW5kLWFwcGx5LWhlbHBlcnMvZnVuY3Rpb25DYWxsLmpzIiwibm9kZV9tb2R1bGVzL2NhbGwtYmluZC1hcHBseS1oZWxwZXJzL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2NhbGwtYmluZC1hcHBseS1oZWxwZXJzL3JlZmxlY3RBcHBseS5qcyIsIm5vZGVfbW9kdWxlcy9jYWxsLWJvdW5kL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2R1bmRlci1wcm90by9nZXQuanMiLCJub2RlX21vZHVsZXMvZXMtZGVmaW5lLXByb3BlcnR5L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2VzLWVycm9ycy9ldmFsLmpzIiwibm9kZV9tb2R1bGVzL2VzLWVycm9ycy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9lcy1lcnJvcnMvcmFuZ2UuanMiLCJub2RlX21vZHVsZXMvZXMtZXJyb3JzL3JlZi5qcyIsIm5vZGVfbW9kdWxlcy9lcy1lcnJvcnMvc3ludGF4LmpzIiwibm9kZV9tb2R1bGVzL2VzLWVycm9ycy90eXBlLmpzIiwibm9kZV9tb2R1bGVzL2VzLWVycm9ycy91cmkuanMiLCJub2RlX21vZHVsZXMvZXMtb2JqZWN0LWF0b21zL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2V2ZW50cy9ldmVudHMuanMiLCJub2RlX21vZHVsZXMvZnVuY3Rpb24tYmluZC9pbXBsZW1lbnRhdGlvbi5qcyIsIm5vZGVfbW9kdWxlcy9mdW5jdGlvbi1iaW5kL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2dldC1pbnRyaW5zaWMvaW5kZXguanMiLCJub2RlX21vZHVsZXMvZ2V0LXByb3RvL09iamVjdC5nZXRQcm90b3R5cGVPZi5qcyIsIm5vZGVfbW9kdWxlcy9nZXQtcHJvdG8vUmVmbGVjdC5nZXRQcm90b3R5cGVPZi5qcyIsIm5vZGVfbW9kdWxlcy9nZXQtcHJvdG8vaW5kZXguanMiLCJub2RlX21vZHVsZXMvZ29wZC9nT1BELmpzIiwibm9kZV9tb2R1bGVzL2dvcGQvaW5kZXguanMiLCJub2RlX21vZHVsZXMvaGFzLXN5bWJvbHMvaW5kZXguanMiLCJub2RlX21vZHVsZXMvaGFzLXN5bWJvbHMvc2hhbXMuanMiLCJub2RlX21vZHVsZXMvaGFzb3duL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2llZWU3NTQvaW5kZXguanMiLCJub2RlX21vZHVsZXMvaW5oZXJpdHMvaW5oZXJpdHNfYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9tYXRoLWludHJpbnNpY3MvYWJzLmpzIiwibm9kZV9tb2R1bGVzL21hdGgtaW50cmluc2ljcy9mbG9vci5qcyIsIm5vZGVfbW9kdWxlcy9tYXRoLWludHJpbnNpY3MvaXNOYU4uanMiLCJub2RlX21vZHVsZXMvbWF0aC1pbnRyaW5zaWNzL21heC5qcyIsIm5vZGVfbW9kdWxlcy9tYXRoLWludHJpbnNpY3MvbWluLmpzIiwibm9kZV9tb2R1bGVzL21hdGgtaW50cmluc2ljcy9wb3cuanMiLCJub2RlX21vZHVsZXMvbWF0aC1pbnRyaW5zaWNzL3JvdW5kLmpzIiwibm9kZV9tb2R1bGVzL21hdGgtaW50cmluc2ljcy9zaWduLmpzIiwibm9kZV9tb2R1bGVzL29iamVjdC1pbnNwZWN0L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL29iamVjdC1rZXlzL2ltcGxlbWVudGF0aW9uLmpzIiwibm9kZV9tb2R1bGVzL29iamVjdC1rZXlzL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL29iamVjdC1rZXlzL2lzQXJndW1lbnRzLmpzIiwibm9kZV9tb2R1bGVzL29iamVjdC5hc3NpZ24vaW1wbGVtZW50YXRpb24uanMiLCJub2RlX21vZHVsZXMvb2JqZWN0LmFzc2lnbi9wb2x5ZmlsbC5qcyIsIm5vZGVfbW9kdWxlcy9wcm9jZXNzL2Jyb3dzZXIuanMiLCJub2RlX21vZHVsZXMvcHVueWNvZGUvcHVueWNvZGUuanMiLCJub2RlX21vZHVsZXMvcXMvbGliL2Zvcm1hdHMuanMiLCJub2RlX21vZHVsZXMvcXMvbGliL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL3FzL2xpYi9wYXJzZS5qcyIsIm5vZGVfbW9kdWxlcy9xcy9saWIvc3RyaW5naWZ5LmpzIiwibm9kZV9tb2R1bGVzL3FzL2xpYi91dGlscy5qcyIsIm5vZGVfbW9kdWxlcy9zYWZlLWJ1ZmZlci9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9zaWRlLWNoYW5uZWwtbGlzdC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9zaWRlLWNoYW5uZWwtbWFwL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL3NpZGUtY2hhbm5lbC13ZWFrbWFwL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL3NpZGUtY2hhbm5lbC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9zdHJlYW0taHR0cC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9zdHJlYW0taHR0cC9saWIvY2FwYWJpbGl0eS5qcyIsIm5vZGVfbW9kdWxlcy9zdHJlYW0taHR0cC9saWIvcmVxdWVzdC5qcyIsIm5vZGVfbW9kdWxlcy9zdHJlYW0taHR0cC9saWIvcmVzcG9uc2UuanMiLCJub2RlX21vZHVsZXMvc3RyZWFtLWh0dHAvbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9lcnJvcnMtYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9zdHJlYW0taHR0cC9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9fc3RyZWFtX2R1cGxleC5qcyIsIm5vZGVfbW9kdWxlcy9zdHJlYW0taHR0cC9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9fc3RyZWFtX3Bhc3N0aHJvdWdoLmpzIiwibm9kZV9tb2R1bGVzL3N0cmVhbS1odHRwL25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vbGliL19zdHJlYW1fcmVhZGFibGUuanMiLCJub2RlX21vZHVsZXMvc3RyZWFtLWh0dHAvbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvX3N0cmVhbV90cmFuc2Zvcm0uanMiLCJub2RlX21vZHVsZXMvc3RyZWFtLWh0dHAvbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvX3N0cmVhbV93cml0YWJsZS5qcyIsIm5vZGVfbW9kdWxlcy9zdHJlYW0taHR0cC9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9pbnRlcm5hbC9zdHJlYW1zL2FzeW5jX2l0ZXJhdG9yLmpzIiwibm9kZV9tb2R1bGVzL3N0cmVhbS1odHRwL25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vbGliL2ludGVybmFsL3N0cmVhbXMvYnVmZmVyX2xpc3QuanMiLCJub2RlX21vZHVsZXMvc3RyZWFtLWh0dHAvbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvaW50ZXJuYWwvc3RyZWFtcy9kZXN0cm95LmpzIiwibm9kZV9tb2R1bGVzL3N0cmVhbS1odHRwL25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vbGliL2ludGVybmFsL3N0cmVhbXMvZW5kLW9mLXN0cmVhbS5qcyIsIm5vZGVfbW9kdWxlcy9zdHJlYW0taHR0cC9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9pbnRlcm5hbC9zdHJlYW1zL2Zyb20tYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9zdHJlYW0taHR0cC9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9pbnRlcm5hbC9zdHJlYW1zL3BpcGVsaW5lLmpzIiwibm9kZV9tb2R1bGVzL3N0cmVhbS1odHRwL25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vbGliL2ludGVybmFsL3N0cmVhbXMvc3RhdGUuanMiLCJub2RlX21vZHVsZXMvc3RyZWFtLWh0dHAvbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvaW50ZXJuYWwvc3RyZWFtcy9zdHJlYW0tYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9zdHJlYW0taHR0cC9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL3JlYWRhYmxlLWJyb3dzZXIuanMiLCJub2RlX21vZHVsZXMvc3RyaW5nX2RlY29kZXIvbGliL3N0cmluZ19kZWNvZGVyLmpzIiwibm9kZV9tb2R1bGVzL3RzLWludGVyZmFjZS1jaGVja2VyL2Rpc3QvaW5kZXguanMiLCJub2RlX21vZHVsZXMvdHMtaW50ZXJmYWNlLWNoZWNrZXIvZGlzdC90eXBlcy5qcyIsIm5vZGVfbW9kdWxlcy90cy1pbnRlcmZhY2UtY2hlY2tlci9kaXN0L3V0aWwuanMiLCJub2RlX21vZHVsZXMvdXJsL3VybC5qcyIsIm5vZGVfbW9kdWxlcy91dGlsLWRlcHJlY2F0ZS9icm93c2VyLmpzIiwibm9kZV9tb2R1bGVzL3h0ZW5kL2ltbXV0YWJsZS5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3SEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1S0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4VEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUN6S0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDMWZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUNMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDMWtCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0SkE7OztBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUNqdkRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEVBLFlBQVk7O0FBRVosSUFBSSxJQUFJLEdBQUcsT0FBTyxDQUFDLGVBQWUsQ0FBQztBQUVuQyxJQUFJLE1BQU0sR0FBRyxPQUFPLENBQUMsaUJBQWlCLENBQUM7QUFDdkMsSUFBSSxLQUFLLEdBQUcsT0FBTyxDQUFDLGdCQUFnQixDQUFDO0FBQ3JDLElBQUksYUFBYSxHQUFHLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQzs7QUFFN0M7QUFDQSxNQUFNLENBQUMsT0FBTyxHQUFHLGFBQWEsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUM7OztBQ1QxRCxZQUFZOztBQUVaO0FBQ0EsTUFBTSxDQUFDLE9BQU8sR0FBRyxRQUFRLENBQUMsU0FBUyxDQUFDLEtBQUs7OztBQ0h6QyxZQUFZOztBQUVaO0FBQ0EsTUFBTSxDQUFDLE9BQU8sR0FBRyxRQUFRLENBQUMsU0FBUyxDQUFDLElBQUk7OztBQ0h4QyxZQUFZOztBQUVaLElBQUksSUFBSSxHQUFHLE9BQU8sQ0FBQyxlQUFlLENBQUM7QUFDbkMsSUFBSSxVQUFVLEdBQUcsT0FBTyxDQUFDLGdCQUFnQixDQUFDO0FBRTFDLElBQUksS0FBSyxHQUFHLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQztBQUNyQyxJQUFJLFlBQVksR0FBRyxPQUFPLENBQUMsZUFBZSxDQUFDOztBQUUzQztBQUNBLE1BQU0sQ0FBQyxPQUFPLEdBQUcsU0FBUyxhQUFhLENBQUMsSUFBSSxFQUFFO0VBQzdDLElBQUksSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLElBQUksT0FBTyxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssVUFBVSxFQUFFO0lBQ3JELE1BQU0sSUFBSSxVQUFVLENBQUMsd0JBQXdCLENBQUM7RUFDL0M7RUFDQSxPQUFPLFlBQVksQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQztBQUN2QyxDQUFDOzs7QUNkRCxZQUFZOztBQUVaO0FBQ0EsTUFBTSxDQUFDLE9BQU8sR0FBRyxPQUFPLE9BQU8sS0FBSyxXQUFXLElBQUksT0FBTyxJQUFJLE9BQU8sQ0FBQyxLQUFLOzs7QUNIM0UsWUFBWTs7QUFFWixJQUFJLFlBQVksR0FBRyxPQUFPLENBQUMsZUFBZSxDQUFDO0FBRTNDLElBQUksYUFBYSxHQUFHLE9BQU8sQ0FBQyx5QkFBeUIsQ0FBQzs7QUFFdEQ7QUFDQSxJQUFJLFFBQVEsR0FBRyxhQUFhLENBQUMsQ0FBQyxZQUFZLENBQUMsNEJBQTRCLENBQUMsQ0FBQyxDQUFDOztBQUUxRTtBQUNBLE1BQU0sQ0FBQyxPQUFPLEdBQUcsU0FBUyxrQkFBa0IsQ0FBQyxJQUFJLEVBQUUsWUFBWSxFQUFFO0VBQ2hFOztFQUVBLElBQUksU0FBUyxHQUFHLDZEQUErRCxZQUFZLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxZQUFZLENBQUU7RUFDbEgsSUFBSSxPQUFPLFNBQVMsS0FBSyxVQUFVLElBQUksUUFBUSxDQUFDLElBQUksRUFBRSxhQUFhLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRTtJQUMxRSxPQUFPLGFBQWEsQ0FBQyxvQkFBc0IsQ0FBQyxTQUFTLENBQUUsQ0FBQztFQUN6RDtFQUNBLE9BQU8sU0FBUztBQUNqQixDQUFDOzs7QUNsQkQsWUFBWTs7QUFFWixJQUFJLFFBQVEsR0FBRyxPQUFPLENBQUMseUJBQXlCLENBQUM7QUFDakQsSUFBSSxJQUFJLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQztBQUUxQixJQUFJLGdCQUFnQjtBQUNwQixJQUFJO0VBQ0g7RUFDQSxnQkFBZ0IsR0FBRyxxREFBdUQsRUFBRSxDQUFFLFNBQVMsS0FBSyxLQUFLLENBQUMsU0FBUztBQUM1RyxDQUFDLENBQUMsT0FBTyxDQUFDLEVBQUU7RUFDWCxJQUFJLENBQUMsQ0FBQyxJQUFJLE9BQU8sQ0FBQyxLQUFLLFFBQVEsSUFBSSxFQUFFLE1BQU0sSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxLQUFLLGtCQUFrQixFQUFFO0lBQ25GLE1BQU0sQ0FBQztFQUNSO0FBQ0Q7O0FBRUE7QUFDQSxJQUFJLElBQUksR0FBRyxDQUFDLENBQUMsZ0JBQWdCLElBQUksSUFBSSxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxFQUFFLDRDQUE4QyxXQUFZLENBQUM7QUFFM0gsSUFBSSxPQUFPLEdBQUcsTUFBTTtBQUNwQixJQUFJLGVBQWUsR0FBRyxPQUFPLENBQUMsY0FBYzs7QUFFNUM7QUFDQSxNQUFNLENBQUMsT0FBTyxHQUFHLElBQUksSUFBSSxPQUFPLElBQUksQ0FBQyxHQUFHLEtBQUssVUFBVSxHQUNwRCxRQUFRLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsR0FDcEIsT0FBTyxlQUFlLEtBQUssVUFBVSxHQUNwQyw4QkFBK0IsU0FBUyxTQUFTLENBQUMsS0FBSyxFQUFFO0VBQzFEO0VBQ0EsT0FBTyxlQUFlLENBQUMsS0FBSyxJQUFJLElBQUksR0FBRyxLQUFLLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQy9ELENBQUMsR0FDQyxLQUFLOzs7QUM3QlQsWUFBWTs7QUFFWjtBQUNBLElBQUksZUFBZSxHQUFHLE1BQU0sQ0FBQyxjQUFjLElBQUksS0FBSztBQUNwRCxJQUFJLGVBQWUsRUFBRTtFQUNwQixJQUFJO0lBQ0gsZUFBZSxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUcsRUFBRTtNQUFFLEtBQUssRUFBRTtJQUFFLENBQUMsQ0FBQztFQUN2QyxDQUFDLENBQUMsT0FBTyxDQUFDLEVBQUU7SUFDWDtJQUNBLGVBQWUsR0FBRyxLQUFLO0VBQ3hCO0FBQ0Q7QUFFQSxNQUFNLENBQUMsT0FBTyxHQUFHLGVBQWU7OztBQ2JoQyxZQUFZOztBQUVaO0FBQ0EsTUFBTSxDQUFDLE9BQU8sR0FBRyxTQUFTOzs7QUNIMUIsWUFBWTs7QUFFWjtBQUNBLE1BQU0sQ0FBQyxPQUFPLEdBQUcsS0FBSzs7O0FDSHRCLFlBQVk7O0FBRVo7QUFDQSxNQUFNLENBQUMsT0FBTyxHQUFHLFVBQVU7OztBQ0gzQixZQUFZOztBQUVaO0FBQ0EsTUFBTSxDQUFDLE9BQU8sR0FBRyxjQUFjOzs7QUNIL0IsWUFBWTs7QUFFWjtBQUNBLE1BQU0sQ0FBQyxPQUFPLEdBQUcsV0FBVzs7O0FDSDVCLFlBQVk7O0FBRVo7QUFDQSxNQUFNLENBQUMsT0FBTyxHQUFHLFNBQVM7OztBQ0gxQixZQUFZOztBQUVaO0FBQ0EsTUFBTSxDQUFDLE9BQU8sR0FBRyxRQUFROzs7QUNIekIsWUFBWTs7QUFFWjtBQUNBLE1BQU0sQ0FBQyxPQUFPLEdBQUcsTUFBTTs7O0FDSHZCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxWEEsWUFBWTs7QUFFWixJQUFJLE9BQU8sR0FBRyxPQUFPLENBQUMsaUJBQWlCLENBQUM7O0FBRXhDO0FBQ0EsTUFBTSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUMsY0FBYyxJQUFJLElBQUk7OztBQ0wvQyxZQUFZOztBQUVaO0FBQ0EsTUFBTSxDQUFDLE9BQU8sR0FBSSxPQUFPLE9BQU8sS0FBSyxXQUFXLElBQUksT0FBTyxDQUFDLGNBQWMsSUFBSyxJQUFJOzs7QUNIbkYsWUFBWTs7QUFFWixJQUFJLGVBQWUsR0FBRyxPQUFPLENBQUMsMEJBQTBCLENBQUM7QUFDekQsSUFBSSxnQkFBZ0IsR0FBRyxPQUFPLENBQUMseUJBQXlCLENBQUM7QUFFekQsSUFBSSxjQUFjLEdBQUcsT0FBTyxDQUFDLGtCQUFrQixDQUFDOztBQUVoRDtBQUNBLE1BQU0sQ0FBQyxPQUFPLEdBQUcsZUFBZSxHQUM3QixTQUFTLFFBQVEsQ0FBQyxDQUFDLEVBQUU7RUFDdEI7RUFDQSxPQUFPLGVBQWUsQ0FBQyxDQUFDLENBQUM7QUFDMUIsQ0FBQyxHQUNDLGdCQUFnQixHQUNmLFNBQVMsUUFBUSxDQUFDLENBQUMsRUFBRTtFQUN0QixJQUFJLENBQUMsQ0FBQyxJQUFLLE9BQU8sQ0FBQyxLQUFLLFFBQVEsSUFBSSxPQUFPLENBQUMsS0FBSyxVQUFXLEVBQUU7SUFDN0QsTUFBTSxJQUFJLFNBQVMsQ0FBQyx5QkFBeUIsQ0FBQztFQUMvQztFQUNBO0VBQ0EsT0FBTyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUM7QUFDM0IsQ0FBQyxHQUNDLGNBQWMsR0FDYixTQUFTLFFBQVEsQ0FBQyxDQUFDLEVBQUU7RUFDdEI7RUFDQSxPQUFPLGNBQWMsQ0FBQyxDQUFDLENBQUM7QUFDekIsQ0FBQyxHQUNDLElBQUk7OztBQzFCVCxZQUFZOztBQUVaO0FBQ0EsTUFBTSxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUMsd0JBQXdCOzs7QUNIaEQsWUFBWTs7QUFFWjtBQUNBLElBQUksS0FBSyxHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUM7QUFFN0IsSUFBSSxLQUFLLEVBQUU7RUFDVixJQUFJO0lBQ0gsS0FBSyxDQUFDLEVBQUUsRUFBRSxRQUFRLENBQUM7RUFDcEIsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxFQUFFO0lBQ1g7SUFDQSxLQUFLLEdBQUcsSUFBSTtFQUNiO0FBQ0Q7QUFFQSxNQUFNLENBQUMsT0FBTyxHQUFHLEtBQUs7OztBQ2R0QixZQUFZOztBQUVaLElBQUksVUFBVSxHQUFHLE9BQU8sTUFBTSxLQUFLLFdBQVcsSUFBSSxNQUFNO0FBQ3hELElBQUksYUFBYSxHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUM7O0FBRXRDO0FBQ0EsTUFBTSxDQUFDLE9BQU8sR0FBRyxTQUFTLGdCQUFnQixDQUFBLEVBQUc7RUFDNUMsSUFBSSxPQUFPLFVBQVUsS0FBSyxVQUFVLEVBQUU7SUFBRSxPQUFPLEtBQUs7RUFBRTtFQUN0RCxJQUFJLE9BQU8sTUFBTSxLQUFLLFVBQVUsRUFBRTtJQUFFLE9BQU8sS0FBSztFQUFFO0VBQ2xELElBQUksT0FBTyxVQUFVLENBQUMsS0FBSyxDQUFDLEtBQUssUUFBUSxFQUFFO0lBQUUsT0FBTyxLQUFLO0VBQUU7RUFDM0QsSUFBSSxPQUFPLE1BQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxRQUFRLEVBQUU7SUFBRSxPQUFPLEtBQUs7RUFBRTtFQUV2RCxPQUFPLGFBQWEsQ0FBQyxDQUFDO0FBQ3ZCLENBQUM7OztBQ2JELFlBQVk7O0FBRVo7QUFDQTtBQUNBLE1BQU0sQ0FBQyxPQUFPLEdBQUcsU0FBUyxVQUFVLENBQUEsRUFBRztFQUN0QyxJQUFJLE9BQU8sTUFBTSxLQUFLLFVBQVUsSUFBSSxPQUFPLE1BQU0sQ0FBQyxxQkFBcUIsS0FBSyxVQUFVLEVBQUU7SUFBRSxPQUFPLEtBQUs7RUFBRTtFQUN4RyxJQUFJLE9BQU8sTUFBTSxDQUFDLFFBQVEsS0FBSyxRQUFRLEVBQUU7SUFBRSxPQUFPLElBQUk7RUFBRTs7RUFFeEQ7RUFDQSxJQUFJLEdBQUcsR0FBRyxDQUFDLENBQUM7RUFDWixJQUFJLEdBQUcsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDO0VBQ3hCLElBQUksTUFBTSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUM7RUFDeEIsSUFBSSxPQUFPLEdBQUcsS0FBSyxRQUFRLEVBQUU7SUFBRSxPQUFPLEtBQUs7RUFBRTtFQUU3QyxJQUFJLE1BQU0sQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxpQkFBaUIsRUFBRTtJQUFFLE9BQU8sS0FBSztFQUFFO0VBQy9FLElBQUksTUFBTSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLGlCQUFpQixFQUFFO0lBQUUsT0FBTyxLQUFLO0VBQUU7O0VBRWxGO0VBQ0E7RUFDQTtFQUNBOztFQUVBO0VBQ0E7O0VBRUEsSUFBSSxNQUFNLEdBQUcsRUFBRTtFQUNmLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxNQUFNO0VBQ2pCLEtBQUssSUFBSSxDQUFDLElBQUksR0FBRyxFQUFFO0lBQUUsT0FBTyxLQUFLO0VBQUUsQ0FBQyxDQUFDO0VBQ3JDLElBQUksT0FBTyxNQUFNLENBQUMsSUFBSSxLQUFLLFVBQVUsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUU7SUFBRSxPQUFPLEtBQUs7RUFBRTtFQUV4RixJQUFJLE9BQU8sTUFBTSxDQUFDLG1CQUFtQixLQUFLLFVBQVUsSUFBSSxNQUFNLENBQUMsbUJBQW1CLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtJQUFFLE9BQU8sS0FBSztFQUFFO0VBRXRILElBQUksSUFBSSxHQUFHLE1BQU0sQ0FBQyxxQkFBcUIsQ0FBQyxHQUFHLENBQUM7RUFDNUMsSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLENBQUMsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssR0FBRyxFQUFFO0lBQUUsT0FBTyxLQUFLO0VBQUU7RUFFMUQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsb0JBQW9CLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsRUFBRTtJQUFFLE9BQU8sS0FBSztFQUFFO0VBRTNFLElBQUksT0FBTyxNQUFNLENBQUMsd0JBQXdCLEtBQUssVUFBVSxFQUFFO0lBQzFEO0lBQ0EsSUFBSSxVQUFVLEdBQUcsaUNBQW1DLE1BQU0sQ0FBQyx3QkFBd0IsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFFO0lBQzlGLElBQUksVUFBVSxDQUFDLEtBQUssS0FBSyxNQUFNLElBQUksVUFBVSxDQUFDLFVBQVUsS0FBSyxJQUFJLEVBQUU7TUFBRSxPQUFPLEtBQUs7SUFBRTtFQUNwRjtFQUVBLE9BQU8sSUFBSTtBQUNaLENBQUM7OztBQzVDRCxZQUFZOztBQUVaLElBQUksSUFBSSxHQUFHLFFBQVEsQ0FBQyxTQUFTLENBQUMsSUFBSTtBQUNsQyxJQUFJLE9BQU8sR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDLGNBQWM7QUFDN0MsSUFBSSxJQUFJLEdBQUcsT0FBTyxDQUFDLGVBQWUsQ0FBQzs7QUFFbkM7QUFDQSxNQUFNLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQzs7O0FDUHpDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNCQSxZQUFZOztBQUVaO0FBQ0EsTUFBTSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsR0FBRzs7O0FDSHpCLFlBQVk7O0FBRVo7QUFDQSxNQUFNLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxLQUFLOzs7QUNIM0IsWUFBWTs7QUFFWjtBQUNBLE1BQU0sQ0FBQyxPQUFPLEdBQUcsTUFBTSxDQUFDLEtBQUssSUFBSSxTQUFTLEtBQUssQ0FBQyxDQUFDLEVBQUU7RUFDbEQsT0FBTyxDQUFDLEtBQUssQ0FBQztBQUNmLENBQUM7OztBQ0xELFlBQVk7O0FBRVo7QUFDQSxNQUFNLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxHQUFHOzs7QUNIekIsWUFBWTs7QUFFWjtBQUNBLE1BQU0sQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLEdBQUc7OztBQ0h6QixZQUFZOztBQUVaO0FBQ0EsTUFBTSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsR0FBRzs7O0FDSHpCLFlBQVk7O0FBRVo7QUFDQSxNQUFNLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxLQUFLOzs7QUNIM0IsWUFBWTs7QUFFWixJQUFJLE1BQU0sR0FBRyxPQUFPLENBQUMsU0FBUyxDQUFDOztBQUUvQjtBQUNBLE1BQU0sQ0FBQyxPQUFPLEdBQUcsU0FBUyxJQUFJLENBQUMsTUFBTSxFQUFFO0VBQ3RDLElBQUksTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLE1BQU0sS0FBSyxDQUFDLEVBQUU7SUFDbkMsT0FBTyxNQUFNO0VBQ2Q7RUFDQSxPQUFPLE1BQU0sR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQzVCLENBQUM7Ozs7QUNWRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDaGlCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUN4TEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDcmhCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNYQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25aQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzV0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdFZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqRUEsWUFBWTs7QUFFWixJQUFJLE9BQU8sR0FBRyxPQUFPLENBQUMsZ0JBQWdCLENBQUM7QUFFdkMsSUFBSSxVQUFVLEdBQUcsT0FBTyxDQUFDLGdCQUFnQixDQUFDOztBQUUxQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxXQUFXLEdBQUcsU0FBQSxDQUFVLElBQUksRUFBRSxHQUFHLEVBQUUsUUFBUSxFQUFFO0VBQ2hEO0VBQ0EsSUFBSSxJQUFJLEdBQUcsSUFBSTtFQUNmO0VBQ0EsSUFBSSxJQUFJO0VBQ1I7RUFDQSxPQUFPLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLEtBQUssSUFBSSxFQUFFLElBQUksR0FBRyxJQUFJLEVBQUU7SUFDL0MsSUFBSSxJQUFJLENBQUMsR0FBRyxLQUFLLEdBQUcsRUFBRTtNQUNyQixJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJO01BQ3JCLElBQUksQ0FBQyxRQUFRLEVBQUU7UUFDZDtRQUNBLElBQUksQ0FBQyxJQUFJLEdBQUcsNENBQThDLElBQUksQ0FBQyxJQUFLO1FBQ3BFLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLENBQUM7TUFDbkI7TUFDQSxPQUFPLElBQUk7SUFDWjtFQUNEO0FBQ0QsQ0FBQzs7QUFFRDtBQUNBLElBQUksT0FBTyxHQUFHLFNBQUEsQ0FBVSxPQUFPLEVBQUUsR0FBRyxFQUFFO0VBQ3JDLElBQUksQ0FBQyxPQUFPLEVBQUU7SUFDYixPQUFPLEtBQUssU0FBUztFQUN0QjtFQUNBLElBQUksSUFBSSxHQUFHLFdBQVcsQ0FBQyxPQUFPLEVBQUUsR0FBRyxDQUFDO0VBQ3BDLE9BQU8sSUFBSSxJQUFJLElBQUksQ0FBQyxLQUFLO0FBQzFCLENBQUM7QUFDRDtBQUNBLElBQUksT0FBTyxHQUFHLFNBQUEsQ0FBVSxPQUFPLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRTtFQUM1QyxJQUFJLElBQUksR0FBRyxXQUFXLENBQUMsT0FBTyxFQUFFLEdBQUcsQ0FBQztFQUNwQyxJQUFJLElBQUksRUFBRTtJQUNULElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSztFQUNuQixDQUFDLE1BQU07SUFDTjtJQUNBLE9BQU8sQ0FBQyxJQUFJLEdBQUcsdUVBQXlFO01BQUU7TUFDekYsR0FBRyxFQUFFLEdBQUc7TUFDUixJQUFJLEVBQUUsT0FBTyxDQUFDLElBQUk7TUFDbEIsS0FBSyxFQUFFO0lBQ1IsQ0FBRTtFQUNIO0FBQ0QsQ0FBQztBQUNEO0FBQ0EsSUFBSSxPQUFPLEdBQUcsU0FBQSxDQUFVLE9BQU8sRUFBRSxHQUFHLEVBQUU7RUFDckMsSUFBSSxDQUFDLE9BQU8sRUFBRTtJQUNiLE9BQU8sS0FBSztFQUNiO0VBQ0EsT0FBTyxDQUFDLENBQUMsV0FBVyxDQUFDLE9BQU8sRUFBRSxHQUFHLENBQUM7QUFDbkMsQ0FBQztBQUNEO0FBQ0E7QUFDQSxJQUFJLFVBQVUsR0FBRyxTQUFBLENBQVUsT0FBTyxFQUFFLEdBQUcsRUFBRTtFQUN4QyxJQUFJLE9BQU8sRUFBRTtJQUNaLE9BQU8sV0FBVyxDQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUUsSUFBSSxDQUFDO0VBQ3ZDO0FBQ0QsQ0FBQzs7QUFFRDtBQUNBLE1BQU0sQ0FBQyxPQUFPLEdBQUcsU0FBUyxrQkFBa0IsQ0FBQSxFQUFHO0VBQzlDO0VBQ0E7RUFDQTs7RUFFQSwrREFBZ0UsSUFBSSxFQUFFOztFQUV0RTtFQUNBLElBQUksT0FBTyxHQUFHO0lBQ2IsTUFBTSxFQUFFLFNBQUEsQ0FBVSxHQUFHLEVBQUU7TUFDdEIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUU7UUFDdEIsTUFBTSxJQUFJLFVBQVUsQ0FBQyxnQ0FBZ0MsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUM7TUFDdEU7SUFDRCxDQUFDO0lBQ0QsUUFBUSxFQUFFLFNBQUEsQ0FBVSxHQUFHLEVBQUU7TUFDeEIsSUFBSSxXQUFXLEdBQUcsVUFBVSxDQUFDLEVBQUUsRUFBRSxHQUFHLENBQUM7TUFDckMsSUFBSSxXQUFXLElBQUksRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRTtRQUNsQyxFQUFFLEdBQUcsS0FBSyxTQUFTO01BQ3BCO01BQ0EsT0FBTyxDQUFDLENBQUMsV0FBVztJQUNyQixDQUFDO0lBQ0QsR0FBRyxFQUFFLFNBQUEsQ0FBVSxHQUFHLEVBQUU7TUFDbkIsT0FBTyxPQUFPLENBQUMsRUFBRSxFQUFFLEdBQUcsQ0FBQztJQUN4QixDQUFDO0lBQ0QsR0FBRyxFQUFFLFNBQUEsQ0FBVSxHQUFHLEVBQUU7TUFDbkIsT0FBTyxPQUFPLENBQUMsRUFBRSxFQUFFLEdBQUcsQ0FBQztJQUN4QixDQUFDO0lBQ0QsR0FBRyxFQUFFLFNBQUEsQ0FBVSxHQUFHLEVBQUUsS0FBSyxFQUFFO01BQzFCLElBQUksQ0FBQyxFQUFFLEVBQUU7UUFDUjtRQUNBLEVBQUUsR0FBRztVQUNKLElBQUksRUFBRSxLQUFLO1FBQ1osQ0FBQztNQUNGO01BQ0E7TUFDQSxPQUFPLENBQUMscUNBQXVDLEVBQUUsRUFBRyxHQUFHLEVBQUUsS0FBSyxDQUFDO0lBQ2hFO0VBQ0QsQ0FBQztFQUNELE9BQU8sT0FBTztBQUNmLENBQUM7OztBQzlHRCxZQUFZOztBQUVaLElBQUksWUFBWSxHQUFHLE9BQU8sQ0FBQyxlQUFlLENBQUM7QUFDM0MsSUFBSSxTQUFTLEdBQUcsT0FBTyxDQUFDLFlBQVksQ0FBQztBQUNyQyxJQUFJLE9BQU8sR0FBRyxPQUFPLENBQUMsZ0JBQWdCLENBQUM7QUFFdkMsSUFBSSxVQUFVLEdBQUcsT0FBTyxDQUFDLGdCQUFnQixDQUFDO0FBQzFDLElBQUksSUFBSSxHQUFHLFlBQVksQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDOztBQUV0QztBQUNBLElBQUksT0FBTyxHQUFHLFNBQVMsQ0FBQyxtQkFBbUIsRUFBRSxJQUFJLENBQUM7QUFDbEQ7QUFDQSxJQUFJLE9BQU8sR0FBRyxTQUFTLENBQUMsbUJBQW1CLEVBQUUsSUFBSSxDQUFDO0FBQ2xEO0FBQ0EsSUFBSSxPQUFPLEdBQUcsU0FBUyxDQUFDLG1CQUFtQixFQUFFLElBQUksQ0FBQztBQUNsRDtBQUNBLElBQUksVUFBVSxHQUFHLFNBQVMsQ0FBQyxzQkFBc0IsRUFBRSxJQUFJLENBQUM7QUFDeEQ7QUFDQSxJQUFJLFFBQVEsR0FBRyxTQUFTLENBQUMsb0JBQW9CLEVBQUUsSUFBSSxDQUFDOztBQUVwRDtBQUNBLE1BQU0sQ0FBQyxPQUFPLEdBQUcsQ0FBQyxDQUFDLElBQUksSUFBSSwwQ0FBMkMsU0FBUyxpQkFBaUIsQ0FBQSxFQUFHO0VBQ2xHO0VBQ0E7RUFDQTs7RUFFQSxvQ0FBcUMsSUFBSSxFQUFFOztFQUUzQztFQUNBLElBQUksT0FBTyxHQUFHO0lBQ2IsTUFBTSxFQUFFLFNBQUEsQ0FBVSxHQUFHLEVBQUU7TUFDdEIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUU7UUFDdEIsTUFBTSxJQUFJLFVBQVUsQ0FBQyxnQ0FBZ0MsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUM7TUFDdEU7SUFDRCxDQUFDO0lBQ0QsUUFBUSxFQUFFLFNBQUEsQ0FBVSxHQUFHLEVBQUU7TUFDeEIsSUFBSSxFQUFFLEVBQUU7UUFDUCxJQUFJLE1BQU0sR0FBRyxVQUFVLENBQUMsRUFBRSxFQUFFLEdBQUcsQ0FBQztRQUNoQyxJQUFJLFFBQVEsQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLEVBQUU7VUFDdkIsRUFBRSxHQUFHLEtBQUssU0FBUztRQUNwQjtRQUNBLE9BQU8sTUFBTTtNQUNkO01BQ0EsT0FBTyxLQUFLO0lBQ2IsQ0FBQztJQUNELEdBQUcsRUFBRSxTQUFBLENBQVUsR0FBRyxFQUFFO01BQUU7TUFDckIsSUFBSSxFQUFFLEVBQUU7UUFDUCxPQUFPLE9BQU8sQ0FBQyxFQUFFLEVBQUUsR0FBRyxDQUFDO01BQ3hCO0lBQ0QsQ0FBQztJQUNELEdBQUcsRUFBRSxTQUFBLENBQVUsR0FBRyxFQUFFO01BQ25CLElBQUksRUFBRSxFQUFFO1FBQ1AsT0FBTyxPQUFPLENBQUMsRUFBRSxFQUFFLEdBQUcsQ0FBQztNQUN4QjtNQUNBLE9BQU8sS0FBSztJQUNiLENBQUM7SUFDRCxHQUFHLEVBQUUsU0FBQSxDQUFVLEdBQUcsRUFBRSxLQUFLLEVBQUU7TUFDMUIsSUFBSSxDQUFDLEVBQUUsRUFBRTtRQUNSO1FBQ0EsRUFBRSxHQUFHLElBQUksSUFBSSxDQUFDLENBQUM7TUFDaEI7TUFDQSxPQUFPLENBQUMsRUFBRSxFQUFFLEdBQUcsRUFBRSxLQUFLLENBQUM7SUFDeEI7RUFDRCxDQUFDOztFQUVEO0VBQ0EsT0FBTyxPQUFPO0FBQ2YsQ0FBQzs7O0FDbkVELFlBQVk7O0FBRVosSUFBSSxZQUFZLEdBQUcsT0FBTyxDQUFDLGVBQWUsQ0FBQztBQUMzQyxJQUFJLFNBQVMsR0FBRyxPQUFPLENBQUMsWUFBWSxDQUFDO0FBQ3JDLElBQUksT0FBTyxHQUFHLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQztBQUN2QyxJQUFJLGlCQUFpQixHQUFHLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQztBQUVuRCxJQUFJLFVBQVUsR0FBRyxPQUFPLENBQUMsZ0JBQWdCLENBQUM7QUFDMUMsSUFBSSxRQUFRLEdBQUcsWUFBWSxDQUFDLFdBQVcsRUFBRSxJQUFJLENBQUM7O0FBRTlDO0FBQ0EsSUFBSSxXQUFXLEdBQUcsU0FBUyxDQUFDLHVCQUF1QixFQUFFLElBQUksQ0FBQztBQUMxRDtBQUNBLElBQUksV0FBVyxHQUFHLFNBQVMsQ0FBQyx1QkFBdUIsRUFBRSxJQUFJLENBQUM7QUFDMUQ7QUFDQSxJQUFJLFdBQVcsR0FBRyxTQUFTLENBQUMsdUJBQXVCLEVBQUUsSUFBSSxDQUFDO0FBQzFEO0FBQ0EsSUFBSSxjQUFjLEdBQUcsU0FBUyxDQUFDLDBCQUEwQixFQUFFLElBQUksQ0FBQzs7QUFFaEU7QUFDQSxNQUFNLENBQUMsT0FBTyxHQUFHLFFBQVEsR0FDdEIsMENBQTJDLFNBQVMscUJBQXFCLENBQUEsRUFBRztFQUM3RTtFQUNBO0VBQ0E7O0VBRUEsaURBQWtELElBQUksR0FBRztFQUN6RDtFQUFtQyxJQUFJLEVBQUU7O0VBRXpDO0VBQ0EsSUFBSSxPQUFPLEdBQUc7SUFDYixNQUFNLEVBQUUsU0FBQSxDQUFVLEdBQUcsRUFBRTtNQUN0QixJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRTtRQUN0QixNQUFNLElBQUksVUFBVSxDQUFDLGdDQUFnQyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQztNQUN0RTtJQUNELENBQUM7SUFDRCxRQUFRLEVBQUUsU0FBQSxDQUFVLEdBQUcsRUFBRTtNQUN4QixJQUFJLFFBQVEsSUFBSSxHQUFHLEtBQUssT0FBTyxHQUFHLEtBQUssUUFBUSxJQUFJLE9BQU8sR0FBRyxLQUFLLFVBQVUsQ0FBQyxFQUFFO1FBQzlFLElBQUksR0FBRyxFQUFFO1VBQ1IsT0FBTyxjQUFjLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQztRQUNoQztNQUNELENBQUMsTUFBTSxJQUFJLGlCQUFpQixFQUFFO1FBQzdCLElBQUksRUFBRSxFQUFFO1VBQ1AsT0FBTyxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsR0FBRyxDQUFDO1FBQ3pCO01BQ0Q7TUFDQSxPQUFPLEtBQUs7SUFDYixDQUFDO0lBQ0QsR0FBRyxFQUFFLFNBQUEsQ0FBVSxHQUFHLEVBQUU7TUFDbkIsSUFBSSxRQUFRLElBQUksR0FBRyxLQUFLLE9BQU8sR0FBRyxLQUFLLFFBQVEsSUFBSSxPQUFPLEdBQUcsS0FBSyxVQUFVLENBQUMsRUFBRTtRQUM5RSxJQUFJLEdBQUcsRUFBRTtVQUNSLE9BQU8sV0FBVyxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUM7UUFDN0I7TUFDRDtNQUNBLE9BQU8sRUFBRSxJQUFJLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDO0lBQ3pCLENBQUM7SUFDRCxHQUFHLEVBQUUsU0FBQSxDQUFVLEdBQUcsRUFBRTtNQUNuQixJQUFJLFFBQVEsSUFBSSxHQUFHLEtBQUssT0FBTyxHQUFHLEtBQUssUUFBUSxJQUFJLE9BQU8sR0FBRyxLQUFLLFVBQVUsQ0FBQyxFQUFFO1FBQzlFLElBQUksR0FBRyxFQUFFO1VBQ1IsT0FBTyxXQUFXLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQztRQUM3QjtNQUNEO01BQ0EsT0FBTyxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDO0lBQzNCLENBQUM7SUFDRCxHQUFHLEVBQUUsU0FBQSxDQUFVLEdBQUcsRUFBRSxLQUFLLEVBQUU7TUFDMUIsSUFBSSxRQUFRLElBQUksR0FBRyxLQUFLLE9BQU8sR0FBRyxLQUFLLFFBQVEsSUFBSSxPQUFPLEdBQUcsS0FBSyxVQUFVLENBQUMsRUFBRTtRQUM5RSxJQUFJLENBQUMsR0FBRyxFQUFFO1VBQ1QsR0FBRyxHQUFHLElBQUksUUFBUSxDQUFDLENBQUM7UUFDckI7UUFDQSxXQUFXLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxLQUFLLENBQUM7TUFDN0IsQ0FBQyxNQUFNLElBQUksaUJBQWlCLEVBQUU7UUFDN0IsSUFBSSxDQUFDLEVBQUUsRUFBRTtVQUNSLEVBQUUsR0FBRyxpQkFBaUIsQ0FBQyxDQUFDO1FBQ3pCO1FBQ0E7UUFDQTtRQUF1QyxFQUFFLENBQUUsR0FBRyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUM7TUFDM0Q7SUFDRDtFQUNELENBQUM7O0VBRUQ7RUFDQSxPQUFPLE9BQU87QUFDZixDQUFDLEdBQ0MsaUJBQWlCOzs7QUNuRnBCLFlBQVk7O0FBRVosSUFBSSxVQUFVLEdBQUcsT0FBTyxDQUFDLGdCQUFnQixDQUFDO0FBQzFDLElBQUksT0FBTyxHQUFHLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQztBQUN2QyxJQUFJLGtCQUFrQixHQUFHLE9BQU8sQ0FBQyxtQkFBbUIsQ0FBQztBQUNyRCxJQUFJLGlCQUFpQixHQUFHLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQztBQUNuRCxJQUFJLHFCQUFxQixHQUFHLE9BQU8sQ0FBQyxzQkFBc0IsQ0FBQztBQUUzRCxJQUFJLFdBQVcsR0FBRyxxQkFBcUIsSUFBSSxpQkFBaUIsSUFBSSxrQkFBa0I7O0FBRWxGO0FBQ0EsTUFBTSxDQUFDLE9BQU8sR0FBRyxTQUFTLGNBQWMsQ0FBQSxFQUFHO0VBQzFDOztFQUVBLGtDQUFtQyxJQUFJLFlBQVk7O0VBRW5EO0VBQ0EsSUFBSSxPQUFPLEdBQUc7SUFDYixNQUFNLEVBQUUsU0FBQSxDQUFVLEdBQUcsRUFBRTtNQUN0QixJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRTtRQUN0QixNQUFNLElBQUksVUFBVSxDQUFDLGdDQUFnQyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQztNQUN0RTtJQUNELENBQUM7SUFDRCxRQUFRLEVBQUUsU0FBQSxDQUFVLEdBQUcsRUFBRTtNQUN4QixPQUFPLENBQUMsQ0FBQyxZQUFZLElBQUksWUFBWSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEdBQUcsQ0FBQztJQUNyRCxDQUFDO0lBQ0QsR0FBRyxFQUFFLFNBQUEsQ0FBVSxHQUFHLEVBQUU7TUFDbkIsT0FBTyxZQUFZLElBQUksWUFBWSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUM7SUFDN0MsQ0FBQztJQUNELEdBQUcsRUFBRSxTQUFBLENBQVUsR0FBRyxFQUFFO01BQ25CLE9BQU8sQ0FBQyxDQUFDLFlBQVksSUFBSSxZQUFZLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQztJQUMvQyxDQUFDO0lBQ0QsR0FBRyxFQUFFLFNBQUEsQ0FBVSxHQUFHLEVBQUUsS0FBSyxFQUFFO01BQzFCLElBQUksQ0FBQyxZQUFZLEVBQUU7UUFDbEIsWUFBWSxHQUFHLFdBQVcsQ0FBQyxDQUFDO01BQzdCO01BRUEsWUFBWSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDO0lBQzdCO0VBQ0QsQ0FBQztFQUNEO0VBQ0EsT0FBTyxPQUFPO0FBQ2YsQ0FBQzs7OztBQzFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUNwRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQzNEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ2hXQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDbk5BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQy9IQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUM3SEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ3BDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ2xnQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQzdMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ2hvQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDbkxBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDdExBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQy9GQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JGQTtBQUNBO0FBQ0E7QUFDQTs7QUNIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQkE7QUFDQTs7QUNEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZTQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUNsT0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQzlwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDblBBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDeHdCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDbkVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbigpe2Z1bmN0aW9uIHIoZSxuLHQpe2Z1bmN0aW9uIG8oaSxmKXtpZighbltpXSl7aWYoIWVbaV0pe3ZhciBjPVwiZnVuY3Rpb25cIj09dHlwZW9mIHJlcXVpcmUmJnJlcXVpcmU7aWYoIWYmJmMpcmV0dXJuIGMoaSwhMCk7aWYodSlyZXR1cm4gdShpLCEwKTt2YXIgYT1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK2krXCInXCIpO3Rocm93IGEuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixhfXZhciBwPW5baV09e2V4cG9ydHM6e319O2VbaV1bMF0uY2FsbChwLmV4cG9ydHMsZnVuY3Rpb24ocil7dmFyIG49ZVtpXVsxXVtyXTtyZXR1cm4gbyhufHxyKX0scCxwLmV4cG9ydHMscixlLG4sdCl9cmV0dXJuIG5baV0uZXhwb3J0c31mb3IodmFyIHU9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZSxpPTA7aTx0Lmxlbmd0aDtpKyspbyh0W2ldKTtyZXR1cm4gb31yZXR1cm4gcn0pKCkiLCJcInVzZSBzdHJpY3RcIjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuQVBJVmFsaWRhdGlvbkVycm9yID0gZXhwb3J0cy5BUElTdGF0dXNDb2RlRXJyb3IgPSBleHBvcnRzLkFQSUV2ZW50U3RyZWFtRXJyb3IgPSBleHBvcnRzLkFQSUVycm9yID0gZXhwb3J0cy5BUElBdXRob3Jpc2F0aW9uRXJyb3IgPSB2b2lkIDA7XG52YXIgX2h0dHAgPSByZXF1aXJlKFwiaHR0cFwiKTtcbnZhciBfdXRpbHMgPSByZXF1aXJlKFwiLi91dGlscy5qc1wiKTtcbnZhciBfYXBpVHlwZXMgPSByZXF1aXJlKFwiLi90aS9hcGktdHlwZXMuanNcIik7XG52YXIgX2FwaUF1dGhUeXBlcyA9IHJlcXVpcmUoXCIuL3RpL2FwaS1hdXRoLXR5cGVzLmpzXCIpO1xuLy8gSG9tZWJyaWRnZSBwbHVnaW4gZm9yIEhvbWUgQ29ubmVjdCBob21lIGFwcGxpYW5jZXNcbi8vIENvcHlyaWdodCDCqSAyMDIzLTIwMjYgQWxleGFuZGVyIFRob3VreWRpZGVzXG5cbi8vIEJhc2UgZm9yIHJlcG9ydGluZyBhbGwgSG9tZSBDb25uZWN0IEFQSSBlcnJvcnNcbmNsYXNzIEFQSUVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICBjb25zdHJ1Y3RvcihyZXF1ZXN0LCByZXNwb25zZSwgbWVzc2FnZSwgb3B0aW9ucykge1xuICAgIC8vIFN0YW5kYXJkIGVycm9yIG9iamVjdCBpbml0aWFsaXNhdGlvblxuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgIHRoaXMucmVxdWVzdCA9IHJlcXVlc3Q7XG4gICAgdGhpcy5yZXNwb25zZSA9IHJlc3BvbnNlO1xuICAgIEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKHRoaXMsIEFQSUVycm9yKTtcbiAgICB0aGlzLm5hbWUgPSAnSG9tZSBDb25uZWN0IEFQSSBFcnJvcic7XG4gICAgaWYgKG9wdGlvbnM/LmNhdXNlKSB0aGlzLmVyckNhdXNlID0gb3B0aW9ucy5jYXVzZTtcbiAgfVxufVxuLy8gQVBJIGNvdWxkIG5vdCBiZSBhdXRob3Jpc2VkXG5leHBvcnRzLkFQSUVycm9yID0gQVBJRXJyb3I7XG5jbGFzcyBBUElBdXRob3Jpc2F0aW9uRXJyb3IgZXh0ZW5kcyBBUElFcnJvciB7XG4gIGNvbnN0cnVjdG9yKHJlcXVlc3QsIHJlc3BvbnNlLCBtZXNzYWdlLCBvcHRpb25zKSB7XG4gICAgc3VwZXIocmVxdWVzdCwgcmVzcG9uc2UsIG1lc3NhZ2UsIG9wdGlvbnMpO1xuICAgIEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKHRoaXMsIEFQSUF1dGhvcmlzYXRpb25FcnJvcik7XG4gICAgdGhpcy5uYW1lID0gJ0hvbWUgQ29ubmVjdCBBUEkgQXV0aG9yaXNhdGlvbiBFcnJvcic7XG4gIH1cbn1cbi8vIEFQSSByZXR1cm5lZCBhIG5vbi1zdWNjZXNzIHN0YXR1cyBjb2RlXG5leHBvcnRzLkFQSUF1dGhvcmlzYXRpb25FcnJvciA9IEFQSUF1dGhvcmlzYXRpb25FcnJvcjtcbmNsYXNzIEFQSVN0YXR1c0NvZGVFcnJvciBleHRlbmRzIEFQSUVycm9yIHtcbiAgY29uc3RydWN0b3IocmVxdWVzdCwgcmVzcG9uc2UsIHRleHQsIG9wdGlvbnMpIHtcbiAgICBzdXBlcihyZXF1ZXN0LCByZXNwb25zZSwgQVBJU3RhdHVzQ29kZUVycm9yLmdldE1lc3NhZ2UocmVzcG9uc2UsIHRleHQpLCBvcHRpb25zKTtcbiAgICB0aGlzLnRleHQgPSB0ZXh0O1xuICAgIEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKHRoaXMsIEFQSVN0YXR1c0NvZGVFcnJvcik7XG4gICAgdGhpcy5uYW1lID0gJ0hvbWUgQ29ubmVjdCBTdGF0dXMgQ29kZSBFcnJvcic7XG4gIH1cbiAgLy8gQ29uc3RydWN0IGFuIGVycm9yIG1lc3NhZ2UgZnJvbSBhIHJlc3BvbnNlXG4gIHN0YXRpYyBnZXRNZXNzYWdlKHJlc3BvbnNlLCB0ZXh0KSB7XG4gICAgY29uc3Qgc3RhdHVzQ29kZSA9IHJlc3BvbnNlLnN0YXR1c0NvZGU7XG4gICAgY29uc3Qgc3RhdHVzQ29kZU5hbWUgPSBfaHR0cC5TVEFUVVNfQ09ERVNbc3RhdHVzQ29kZV07XG4gICAgY29uc3QgZGVzY3JpcHRpb24gPSBBUElTdGF0dXNDb2RlRXJyb3IuZ2V0Qm9keURlc2NyaXB0aW9uKHRleHQpID8/ICdObyBlcnJvciBtZXNzYWdlIHJldHVybmVkJztcbiAgICByZXR1cm4gYFske3N0YXR1c0NvZGV9ICR7c3RhdHVzQ29kZU5hbWV9XSAke2Rlc2NyaXB0aW9ufWA7XG4gIH1cbiAgLy8gQXR0ZW1wdCB0byByZXRyaWV2ZSB0aGUgZXJyb3Iga2V5XG4gIGdldCBrZXkoKSB7XG4gICAgcmV0dXJuIEFQSVN0YXR1c0NvZGVFcnJvci5wYXJzZUJvZHkodGhpcy50ZXh0KS5rZXk7XG4gIH1cbiAgLy8gQXR0ZW1wdCB0byByZXRyaWV2ZSB0aGUgZXJyb3Iga2V5XG4gIGdldCBkZXNjcmlwdGlvbigpIHtcbiAgICByZXR1cm4gQVBJU3RhdHVzQ29kZUVycm9yLnBhcnNlQm9keSh0aGlzLnRleHQpLmRlc2NyaXB0aW9uO1xuICB9XG4gIC8vIEF0dGVtcHQgdG8gcmV0cmlldmUgdGhlIGVycm9yIGRlc2NyaXB0aW9uXG4gIGdldCBzaW1wbGVNZXNzYWdlKCkge1xuICAgIHJldHVybiBBUElTdGF0dXNDb2RlRXJyb3IuZ2V0Qm9keURlc2NyaXB0aW9uKHRoaXMudGV4dCk7XG4gIH1cbiAgLy8gQXR0ZW1wdCB0byBleHRyYWN0IGEgdXNlZnVsIGRlc2NyaXB0aW9uIGZyb20gdGhlIHJlc3BvbnNlIGJvZHlcbiAgc3RhdGljIGdldEJvZHlEZXNjcmlwdGlvbih0ZXh0KSB7XG4gICAgY29uc3Qge1xuICAgICAga2V5LFxuICAgICAgZGVzY3JpcHRpb25cbiAgICB9ID0gQVBJU3RhdHVzQ29kZUVycm9yLnBhcnNlQm9keSh0ZXh0KTtcbiAgICBpZiAoa2V5KSB7XG4gICAgICByZXR1cm4gKGRlc2NyaXB0aW9uID8gYCR7ZGVzY3JpcHRpb259IGAgOiAnJykgKyBgWyR7a2V5fV1gO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGV4dC5sZW5ndGggPyB0ZXh0IDogdW5kZWZpbmVkO1xuICAgIH1cbiAgfVxuICAvLyBBdHRlbXB0IHRvIHBhcnNlIHRoZSByZXNwb25zZSBib2R5XG4gIHN0YXRpYyBwYXJzZUJvZHkodGV4dCkge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBqc29uID0gSlNPTi5wYXJzZSh0ZXh0KTtcbiAgICAgIGlmIChfYXBpVHlwZXMuY2hlY2tlcnMuRXJyb3JSZXNwb25zZS50ZXN0KGpzb24pKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAga2V5OiBqc29uLmVycm9yLmtleSxcbiAgICAgICAgICBkZXNjcmlwdGlvbjoganNvbi5lcnJvci5kZXZlbG9wZXJNZXNzYWdlID8/IGpzb24uZXJyb3IuZGVzY3JpcHRpb24gPz8ganNvbi5lcnJvci52YWx1ZVxuICAgICAgICB9O1xuICAgICAgfSBlbHNlIGlmIChfYXBpQXV0aFR5cGVzLmNoZWNrZXJzLkF1dGhvcmlzYXRpb25FcnJvci50ZXN0KGpzb24pKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAga2V5OiBqc29uLmVycm9yLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiBqc29uLmVycm9yX2Rlc2NyaXB0aW9uXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgfSBjYXRjaCB7LyogZW1wdHkgKi99XG4gICAgcmV0dXJuIHt9O1xuICB9XG59XG4vLyBBUEkgcmV0dXJuZWQgYSByZXNwb25zZSB0aGF0IGZhaWxlZCBjaGVja2VyIHZhbGlkYXRpb25cbmV4cG9ydHMuQVBJU3RhdHVzQ29kZUVycm9yID0gQVBJU3RhdHVzQ29kZUVycm9yO1xuY2xhc3MgQVBJVmFsaWRhdGlvbkVycm9yIGV4dGVuZHMgQVBJRXJyb3Ige1xuICBjb25zdHJ1Y3RvcihyZXF1ZXN0LCByZXNwb25zZSwgdmFsaWRhdGlvbiwgb3B0aW9ucykge1xuICAgIHN1cGVyKHJlcXVlc3QsIHJlc3BvbnNlLCBBUElWYWxpZGF0aW9uRXJyb3IuZ2V0TWVzc2FnZSh2YWxpZGF0aW9uKSwgb3B0aW9ucyk7XG4gICAgdGhpcy52YWxpZGF0aW9uID0gdmFsaWRhdGlvbjtcbiAgICBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSh0aGlzLCBBUElWYWxpZGF0aW9uRXJyb3IpO1xuICAgIHRoaXMubmFtZSA9ICdIb21lIENvbm5lY3QgQVBJIFZhbGlkYXRpb24gRXJyb3InO1xuICB9XG4gIC8vIENvbnN0cnVjdCBhbiBlcnJvciBtZXNzYWdlIGZyb20gYSBjaGVja2VyIHZhbGlkYXRpb24gZXJyb3JcbiAgc3RhdGljIGdldE1lc3NhZ2UoZXJyb3JzKSB7XG4gICAgKDAsIF91dGlscy5hc3NlcnRJc0RlZmluZWQpKGVycm9yc1swXSk7XG4gICAgY29uc3QgZGVzY3JpcHRpb24gPSBgJHtlcnJvcnNbMF0ucGF0aH0gJHtlcnJvcnNbMF0ubWVzc2FnZX1gO1xuICAgIHJldHVybiBgU3RydWN0dXJlIHZhbGlkYXRpb24gZmFpbGVkICgke2Rlc2NyaXB0aW9ufSlgO1xuICB9XG59XG4vLyBBUEkgcmV0dXJuZWQgZXZlbnQgc3RyZWFtIHRoYXQgY291bGQgbm90IGJlIHBhcnNlZFxuZXhwb3J0cy5BUElWYWxpZGF0aW9uRXJyb3IgPSBBUElWYWxpZGF0aW9uRXJyb3I7XG5jbGFzcyBBUElFdmVudFN0cmVhbUVycm9yIGV4dGVuZHMgQVBJRXJyb3Ige1xuICBjb25zdHJ1Y3RvcihyZXF1ZXN0LCByZXNwb25zZSwgbWVzc2FnZSwgc3NlLCBvcHRpb25zKSB7XG4gICAgc3VwZXIocmVxdWVzdCwgcmVzcG9uc2UsIEFQSUV2ZW50U3RyZWFtRXJyb3IuZ2V0TWVzc2FnZShtZXNzYWdlLCBzc2UpLCBvcHRpb25zKTtcbiAgICB0aGlzLnNzZSA9IHNzZTtcbiAgICBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSh0aGlzLCBBUElFdmVudFN0cmVhbUVycm9yKTtcbiAgICB0aGlzLm5hbWUgPSAnSG9tZSBDb25uZWN0IEFQSSBFdmVudCBTdHJlYW0gRXJyb3InO1xuICB9XG4gIC8vIENvbnN0cnVjdCBhbiBlcnJvciBtZXNzYWdlIGZyb20gYSBjaGVja2VyIHZhbGlkYXRpb24gZXJyb3JcbiAgc3RhdGljIGdldE1lc3NhZ2UoZGVzY3JpcHRpb24sIHNzZSkge1xuICAgIGNvbnN0IGZpZWxkcyA9IE9iamVjdC5lbnRyaWVzKHNzZSkubWFwKChbbmFtZSwgdmFsdWVdKSA9PiBbYCR7bmFtZX06YCwgdmFsdWVdKTtcbiAgICByZXR1cm4gW2BVbmFibGUgdG8gcGFyc2UgJHtkZXNjcmlwdGlvbn06YCwgLi4uKDAsIF91dGlscy5jb2x1bW5zKShmaWVsZHMpXS5qb2luKCdcXG4nKTtcbiAgfVxufVxuZXhwb3J0cy5BUElFdmVudFN0cmVhbUVycm9yID0gQVBJRXZlbnRTdHJlYW1FcnJvcjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRhdGE6YXBwbGljYXRpb24vanNvbjtjaGFyc2V0PXV0Zi04O2Jhc2U2NCxleUoyWlhKemFXOXVJam96TENKdVlXMWxjeUk2V3lKZmFIUjBjQ0lzSW5KbGNYVnBjbVVpTENKZmRYUnBiSE1pTENKZllYQnBWSGx3WlhNaUxDSmZZWEJwUVhWMGFGUjVjR1Z6SWl3aVFWQkpSWEp5YjNJaUxDSkZjbkp2Y2lJc0ltTnZibk4wY25WamRHOXlJaXdpY21WeGRXVnpkQ0lzSW5KbGMzQnZibk5sSWl3aWJXVnpjMkZuWlNJc0ltOXdkR2x2Ym5NaUxDSmpZWEIwZFhKbFUzUmhZMnRVY21GalpTSXNJbTVoYldVaUxDSmpZWFZ6WlNJc0ltVnlja05oZFhObElpd2laWGh3YjNKMGN5SXNJa0ZRU1VGMWRHaHZjbWx6WVhScGIyNUZjbkp2Y2lJc0lrRlFTVk4wWVhSMWMwTnZaR1ZGY25KdmNpSXNJblJsZUhRaUxDSm5aWFJOWlhOellXZGxJaXdpYzNSaGRIVnpRMjlrWlNJc0luTjBZWFIxYzBOdlpHVk9ZVzFsSWl3aVUxUkJWRlZUWDBOUFJFVlRJaXdpWkdWelkzSnBjSFJwYjI0aUxDSm5aWFJDYjJSNVJHVnpZM0pwY0hScGIyNGlMQ0pyWlhraUxDSndZWEp6WlVKdlpIa2lMQ0p6YVcxd2JHVk5aWE56WVdkbElpd2liR1Z1WjNSb0lpd2lkVzVrWldacGJtVmtJaXdpYW5OdmJpSXNJa3BUVDA0aUxDSndZWEp6WlNJc0ltRndhVU5vWldOclpYSnpJaXdpUlhKeWIzSlNaWE53YjI1elpTSXNJblJsYzNRaUxDSmxjbkp2Y2lJc0ltUmxkbVZzYjNCbGNrMWxjM05oWjJVaUxDSjJZV3gxWlNJc0ltRjFkR2hEYUdWamEyVnljeUlzSWtGMWRHaHZjbWx6WVhScGIyNUZjbkp2Y2lJc0ltVnljbTl5WDJSbGMyTnlhWEIwYVc5dUlpd2lRVkJKVm1Gc2FXUmhkR2x2YmtWeWNtOXlJaXdpZG1Gc2FXUmhkR2x2YmlJc0ltVnljbTl5Y3lJc0ltRnpjMlZ5ZEVselJHVm1hVzVsWkNJc0luQmhkR2dpTENKQlVFbEZkbVZ1ZEZOMGNtVmhiVVZ5Y205eUlpd2ljM05sSWl3aVptbGxiR1J6SWl3aVQySnFaV04wSWl3aVpXNTBjbWxsY3lJc0ltMWhjQ0lzSW1OdmJIVnRibk1pTENKcWIybHVJbDBzSW5OdmRYSmpaWE1pT2xzaUxpNHZjM0pqTDJGd2FTMWxjbkp2Y25NdWRITWlYU3dpYzI5MWNtTmxjME52Ym5SbGJuUWlPbHR1ZFd4c1hTd2liV0Z3Y0dsdVozTWlPaUk3T3pzN096dEJRVWRCTEVsQlFVRkJMRXRCUVVFc1IwRkJRVU1zVDBGQlFUdEJRVWxCTEVsQlFVRkRMRTFCUVVFc1IwRkJRVVFzVDBGQlFUdEJRVU5CTEVsQlFVRkZMRk5CUVVFc1IwRkJRVVlzVDBGQlFUdEJRVU5CTEVsQlFVRkhMR0ZCUVVFc1IwRkJRVWdzVDBGQlFUdEJRVlJCTzBGQlEwRTdPMEZCWlVFN1FVRkRUU3hOUVVGUFNTeFJRVUZUTEZOQlFWRkRMRXRCUVVzN1JVRkpMMEpETEZsQlEyRkRMRTlCUVd0Q0xFVkJRMnhDUXl4UlFVRXJRaXhGUVVONFEwTXNUMEZCTUVJc1JVRkRNVUpETEU5QlFUSkNPMGxCUlROQ08wbEJRMEVzUzBGQlN5eERRVUZEUkN4UFFVRlBMRU5CUVVNN1NVRk9UQ3hMUVVGQlJpeFBRVUZQTEVkQlFWQkJMRTlCUVU4N1NVRkRVQ3hMUVVGQlF5eFJRVUZSTEVkQlFWSkJMRkZCUVZFN1NVRk5ha0pJTEV0QlFVc3NRMEZCUTAwc2FVSkJRV2xDTEVOQlFVTXNTVUZCU1N4RlFVRkZVQ3hSUVVGUkxFTkJRVU03U1VGRGRrTXNTVUZCU1N4RFFVRkRVU3hKUVVGSkxFZEJRVWNzZDBKQlFYZENPMGxCUTNCRExFbEJRVWxHTEU5QlFVOHNSVUZCUlVjc1MwRkJTeXhGUVVGRkxFbEJRVWtzUTBGQlEwTXNVVUZCVVN4SFFVRkhTaXhQUVVGUExFTkJRVU5ITEV0QlFVczdSVUZEY2tRN08wRkJSMG83UVVGQlFVVXNUMEZCUVN4RFFVRkJXQ3hSUVVGQkxFZEJRVUZCTEZGQlFVRTdRVUZEVFN4TlFVRlBXU3h4UWtGQmMwSXNVMEZCVVZvc1VVRkJVVHRGUVVVdlEwVXNXVUZEU1VNc1QwRkJNa0lzUlVGRE0wSkRMRkZCUVhkRExFVkJRM2hEUXl4UFFVRXdRaXhGUVVNeFFrTXNUMEZCTWtJN1NVRkZNMElzUzBGQlN5eERRVUZEU0N4UFFVRlBMRVZCUVVWRExGRkJRVkVzUlVGQlJVTXNUMEZCVHl4RlFVRkZReXhQUVVGUExFTkJRVU03U1VGRE1VTk1MRXRCUVVzc1EwRkJRMDBzYVVKQlFXbENMRU5CUVVNc1NVRkJTU3hGUVVGRlN5eHhRa0ZCY1VJc1EwRkJRenRKUVVOd1JDeEpRVUZKTEVOQlFVTktMRWxCUVVrc1IwRkJSeXh6UTBGQmMwTTdSVUZEZEVRN08wRkJTVW83UVVGQlFVY3NUMEZCUVN4RFFVRkJReXh4UWtGQlFTeEhRVUZCUVN4eFFrRkJRVHRCUVVOTkxFMUJRVTlETEd0Q1FVRnRRaXhUUVVGUllpeFJRVUZSTzBWQlJUVkRSU3haUVVOSlF5eFBRVUV5UWl4RlFVTXpRa01zVVVGQk5FSXNSVUZEYmtKVkxFbEJRV2xDTEVWQlF6RkNVaXhQUVVFeVFqdEpRVVV6UWl4TFFVRkxMRU5CUVVOSUxFOUJRVThzUlVGQlJVTXNVVUZCVVN4RlFVRkZVeXhyUWtGQmEwSXNRMEZCUTBVc1ZVRkJWU3hEUVVGRFdDeFJRVUZSTEVWQlFVVlZMRWxCUVVrc1EwRkJReXhGUVVGRlVpeFBRVUZQTEVOQlFVTTdTVUZJZGtVc1MwRkJRVkVzU1VGQlNTeEhRVUZLUVN4SlFVRkpPMGxCU1dKaUxFdEJRVXNzUTBGQlEwMHNhVUpCUVdsQ0xFTkJRVU1zU1VGQlNTeEZRVUZGVFN4clFrRkJhMElzUTBGQlF6dEpRVU5xUkN4SlFVRkpMRU5CUVVOTUxFbEJRVWtzUjBGQlJ5eG5RMEZCWjBNN1JVRkRhRVE3UlVGRlFUdEZRVU5CTEU5QlFVOVBMRlZCUVZWQkxFTkJRVU5ZTEZGQlFXdENMRVZCUVVWVkxFbEJRVms3U1VGRE9VTXNUVUZCVFVVc1ZVRkJWU3hIUVVGSFdpeFJRVUZSTEVOQlFVTlpMRlZCUVZVN1NVRkRkRU1zVFVGQlRVTXNZMEZCWXl4SFFVRkhReXhyUWtGQldTeERRVUZEUml4VlFVRlZMRU5CUVVNN1NVRkRMME1zVFVGQlRVY3NWMEZCVnl4SFFVRkhUaXhyUWtGQmEwSXNRMEZCUTA4c2EwSkJRV3RDTEVOQlFVTk9MRWxCUVVrc1EwRkJReXhKUVVONFF5d3lRa0ZCTWtJN1NVRkRiRVFzVDBGQlR5eEpRVUZKUlN4VlFVRlZMRWxCUVVsRExHTkJRV01zUzBGQlMwVXNWMEZCVnl4RlFVRkZPMFZCUXpkRU8wVkJSVUU3UlVGRFFTeEpRVUZKUlN4SFFVRkhRU3hEUVVGQk8wbEJRMGdzVDBGQlQxSXNhMEpCUVd0Q0xFTkJRVU5UTEZOQlFWTXNRMEZCUXl4SlFVRkpMRU5CUVVOU0xFbEJRVWtzUTBGQlF5eERRVUZEVHl4SFFVRkhPMFZCUTNSRU8wVkJSVUU3UlVGRFFTeEpRVUZKUml4WFFVRlhRU3hEUVVGQk8wbEJRMWdzVDBGQlQwNHNhMEpCUVd0Q0xFTkJRVU5UTEZOQlFWTXNRMEZCUXl4SlFVRkpMRU5CUVVOU0xFbEJRVWtzUTBGQlF5eERRVUZEU3l4WFFVRlhPMFZCUXpsRU8wVkJSVUU3UlVGRFFTeEpRVUZKU1N4aFFVRmhRU3hEUVVGQk8wbEJRMklzVDBGQlQxWXNhMEpCUVd0Q0xFTkJRVU5QTEd0Q1FVRnJRaXhEUVVGRExFbEJRVWtzUTBGQlEwNHNTVUZCU1N4RFFVRkRPMFZCUXpORU8wVkJSVUU3UlVGRFFTeFBRVUZQVFN4clFrRkJhMEpCTEVOQlFVTk9MRWxCUVZrN1NVRkRiRU1zVFVGQlRUdE5RVUZGVHl4SFFVRkhPMDFCUVVWR08wbEJRVmNzUTBGQlJTeEhRVUZIVGl4clFrRkJhMElzUTBGQlExTXNVMEZCVXl4RFFVRkRVaXhKUVVGSkxFTkJRVU03U1VGREwwUXNTVUZCU1U4c1IwRkJSeXhGUVVGRk8wMUJRMHdzVDBGQlR5eERRVUZEUml4WFFVRlhMRWRCUVVjc1IwRkJSMEVzVjBGQlZ5eEhRVUZITEVkQlFVY3NSVUZCUlN4SlFVRkpMRWxCUVVsRkxFZEJRVWNzUjBGQlJ6dEpRVU01UkN4RFFVRkRMRTFCUVUwN1RVRkRTQ3hQUVVGUFVDeEpRVUZKTEVOQlFVTlZMRTFCUVUwc1IwRkJSMVlzU1VGQlNTeEhRVUZIVnl4VFFVRlRPMGxCUTNwRE8wVkJRMG83UlVGRlFUdEZRVU5CTEU5QlFVOUlMRk5CUVZOQkxFTkJRVU5TTEVsQlFWazdTVUZEZWtJc1NVRkJTVHROUVVOQkxFMUJRVTFaTEVsQlFVa3NSMEZCV1VNc1NVRkJTU3hEUVVGRFF5eExRVUZMTEVOQlFVTmtMRWxCUVVrc1EwRkJRenROUVVOMFF5eEpRVUZKWlN4clFrRkJWeXhEUVVGRFF5eGhRVUZoTEVOQlFVTkRMRWxCUVVrc1EwRkJRMHdzU1VGQlNTeERRVUZETEVWQlFVVTdVVUZEZEVNc1QwRkJUenRWUVVOSVRDeEhRVUZITEVWQlFWVkxMRWxCUVVrc1EwRkJRMDBzUzBGQlN5eERRVUZEV0N4SFFVRkhPMVZCUXpOQ1JpeFhRVUZYTEVWQlFVVlBMRWxCUVVrc1EwRkJRMDBzUzBGQlN5eERRVUZEUXl4blFrRkJaMElzU1VGRGVFSlFMRWxCUVVrc1EwRkJRMDBzUzBGQlN5eERRVUZEWWl4WFFVRlhMRWxCUTNSQ1R5eEpRVUZKTEVOQlFVTk5MRXRCUVVzc1EwRkJRMFU3VTBGRE9VSTdUVUZEVEN4RFFVRkRMRTFCUVUwc1NVRkJTVU1zYzBKQlFWa3NRMEZCUTBNc2EwSkJRV3RDTEVOQlFVTk1MRWxCUVVrc1EwRkJRMHdzU1VGQlNTeERRVUZETEVWQlFVVTdVVUZEYmtRc1QwRkJUenRWUVVOSVRDeEhRVUZITEVWQlFXRkxMRWxCUVVrc1EwRkJRMDBzUzBGQlN6dFZRVU14UW1Jc1YwRkJWeXhGUVVGTFR5eEpRVUZKTEVOQlFVTlhPMU5CUTNoQ08wMUJRMHc3U1VGRFNpeERRVUZETEVOQlFVTXNUVUZCVFN4RFFVRkZPMGxCUTFZc1QwRkJUeXhGUVVGRk8wVkJRMkk3TzBGQlIwbzdRVUZCUVRGQ0xFOUJRVUVzUTBGQlFVVXNhMEpCUVVFc1IwRkJRVUVzYTBKQlFVRTdRVUZEVFN4TlFVRlBlVUlzYTBKQlFXMUNMRk5CUVZGMFF5eFJRVUZSTzBWQlJUVkRSU3haUVVOSlF5eFBRVUVyUWl4RlFVTXZRa01zVVVGQlowTXNSVUZEZGtKdFF5eFZRVUUyUWl4RlFVTjBRMnBETEU5QlFTdENPMGxCUlM5Q0xFdEJRVXNzUTBGQlEwZ3NUMEZCVHl4RlFVRkZReXhSUVVGUkxFVkJRVVZyUXl4clFrRkJhMElzUTBGQlEzWkNMRlZCUVZVc1EwRkJRM2RDTEZWQlFWVXNRMEZCUXl4RlFVRkZha01zVDBGQlR5eERRVUZETzBsQlNHNUZMRXRCUVVGcFF5eFZRVUZWTEVkQlFWWkJMRlZCUVZVN1NVRkpia0owUXl4TFFVRkxMRU5CUVVOTkxHbENRVUZwUWl4RFFVRkRMRWxCUVVrc1JVRkJSU3RDTEd0Q1FVRnJRaXhEUVVGRE8wbEJRMnBFTEVsQlFVa3NRMEZCUXpsQ0xFbEJRVWtzUjBGQlJ5eHRRMEZCYlVNN1JVRkRia1E3UlVGRlFUdEZRVU5CTEU5QlFVOVBMRlZCUVZWQkxFTkJRVU41UWl4TlFVRnpRanRKUVVOd1F5eEpRVUZCUXl4elFrRkJaU3hGUVVGRFJDeE5RVUZOTEVOQlFVTXNRMEZCUXl4RFFVRkRMRU5CUVVNN1NVRkRNVUlzVFVGQlRYSkNMRmRCUVZjc1IwRkJSeXhIUVVGSGNVSXNUVUZCVFN4RFFVRkRMRU5CUVVNc1EwRkJReXhEUVVGRFJTeEpRVUZKTEVsQlFVbEdMRTFCUVUwc1EwRkJReXhEUVVGRExFTkJRVU1zUTBGQlEyNURMRTlCUVU4c1JVRkJSVHRKUVVNMVJDeFBRVUZQTEdkRFFVRm5RMk1zVjBGQlZ5eEhRVUZITzBWQlEzcEVPenRCUVVkS08wRkJRVUZTTEU5QlFVRXNRMEZCUVRKQ0xHdENRVUZCTEVkQlFVRkJMR3RDUVVGQk8wRkJRMDBzVFVGQlQwc3NiVUpCUVc5Q0xGTkJRVkV6UXl4UlFVRlJPMFZCUlRkRFJTeFpRVU5KUXl4UFFVRXlRaXhGUVVNelFrTXNVVUZCTkVJc1JVRkROVUpETEU5QlFUQkNMRVZCUTJwQ2RVTXNSMEZCYVVNc1JVRkRNVU4wUXl4UFFVRXlRanRKUVVVelFpeExRVUZMTEVOQlFVTklMRTlCUVU4c1JVRkJSVU1zVVVGQlVTeEZRVUZGZFVNc2JVSkJRVzFDTEVOQlFVTTFRaXhWUVVGVkxFTkJRVU5XTEU5QlFVOHNSVUZCUlhWRExFZEJRVWNzUTBGQlF5eEZRVUZGZEVNc1QwRkJUeXhEUVVGRE8wbEJTSFJGTEV0QlFVRnpReXhIUVVGSExFZEJRVWhCTEVkQlFVYzdTVUZKV2pORExFdEJRVXNzUTBGQlEwMHNhVUpCUVdsQ0xFTkJRVU1zU1VGQlNTeEZRVUZGYjBNc2JVSkJRVzFDTEVOQlFVTTdTVUZEYkVRc1NVRkJTU3hEUVVGRGJrTXNTVUZCU1N4SFFVRkhMSEZEUVVGeFF6dEZRVU55UkR0RlFVVkJPMFZCUTBFc1QwRkJUMDhzVlVGQlZVRXNRMEZCUTBrc1YwRkJiVUlzUlVGQlJYbENMRWRCUVRKQ08wbEJRemxFTEUxQlFVMURMRTFCUVUwc1IwRkJSME1zVFVGQlRTeERRVUZEUXl4UFFVRlBMRU5CUVVOSUxFZEJRVWNzUTBGQlF5eERRVUZEU1N4SFFVRkhMRU5CUVVNc1EwRkJReXhEUVVGRGVFTXNTVUZCU1N4RlFVRkZNRUlzUzBGQlN5eERRVUZ0UWl4TFFVRkxMRU5CUVVNc1IwRkJSekZDTEVsQlFVa3NSMEZCUnl4RlFVRkZNRUlzUzBGQlN5eERRVUZETEVOQlFVTTdTVUZEYUVjc1QwRkJUeXhEUVVGRExHMUNRVUZ0UW1Zc1YwRkJWeXhIUVVGSExFVkJRVVVzUjBGQlJ5eEpRVUZCT0VJc1kwRkJUeXhGUVVGRFNpeE5RVUZOTEVOQlFVTXNRMEZCUXl4RFFVRkRTeXhKUVVGSkxFTkJRVU1zU1VGQlNTeERRVUZETzBWQlF6ZEZPenRCUVVOSWRrTXNUMEZCUVN4RFFVRkJaME1zYlVKQlFVRXNSMEZCUVVFc2JVSkJRVUVpTENKcFoyNXZjbVZNYVhOMElqcGJYWDA9IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLkFQSVN0YXR1cyA9IHZvaWQgMDtcbnZhciBfdXRpbHMgPSByZXF1aXJlKFwiLi4vLi4vdXRpbHMuanNcIik7XG52YXIgX3V0aWxzRG9tID0gcmVxdWlyZShcIi4vdXRpbHMtZG9tLmpzXCIpO1xudmFyIF9sb2dFcnJvciA9IHJlcXVpcmUoXCIuLi8uLi9sb2ctZXJyb3IuanNcIik7XG4vLyBIb21lYnJpZGdlIHBsdWdpbiBmb3IgSG9tZSBDb25uZWN0IGhvbWUgYXBwbGlhbmNlc1xuLy8gQ29weXJpZ2h0IMKpIDIwMjQtMjAyNiBBbGV4YW5kZXIgVGhvdWt5ZGlkZXNcblxuLy8gVVJMIGZvciB0aGUgc2VydmVyIHN0YXR1cyBpbWFnZVxuY29uc3QgU1RBVFVTX1VSTCA9ICdodHRwczovL2hvbWVjb25uZWN0LnRob3VreS5jby51ay9hcGkvaW1hZ2VzL3BsdWdpbi1zdGF0dXMuc3ZnJztcbi8vIFdhcm4gZm9yIGVycm9ycyBtb3JlIHJlY2VudCB0aGFuIHRoaXNcbmNvbnN0IFNUQVRVU19TSU5DRSA9IDI0ICogNjAgKiA2MCAqIF91dGlscy5NUztcbi8vIEludGVydmFsIHRvIHBvbGwgZm9yIHVwZGF0ZXMgKGlmIHRoZXJlIGFyZSBpc3N1ZXMpXG5jb25zdCBQT0xMX0lOVEVSVkFMID0gMi41ICogNjAgKiBfdXRpbHMuTVM7XG4vLyBIb21lIENvbm5lY3QgQVBJIHNlcnZlciBzdGF0dXNcbmNsYXNzIEFQSVN0YXR1cyB7XG4gIC8vIENyZWF0ZSBhIG5ldyBBUEkgc2VydmVyIHN0YXR1cyBjaGVja2VyXG4gIGNvbnN0cnVjdG9yKGxvZykge1xuICAgIHRoaXMubG9nID0gbG9nO1xuICAgICgwLCBfbG9nRXJyb3IuZGV0YWNoZWQpKHRoaXMubG9nLCAnUG9sbCBzdGF0dXMnLCAoKSA9PiB0aGlzLnBvbGxTdGF0dXMoKSkoKTtcbiAgfVxuICAvLyBDaGVjayB0aGUgc3RhdHVzIG9mIHRoZSBIb21lIENvbm5lY3QgQVBJIHNlcnZlcnNcbiAgYXN5bmMgcG9sbFN0YXR1cygpIHtcbiAgICBsZXQgcG9sbEFnYWluID0gdHJ1ZTtcbiAgICB3aGlsZSAocG9sbEFnYWluKSB7XG4gICAgICAvLyBBdHRlbXB0IHRvIGZldGNoIHRoZSBzdGF0dXMgaW1hZ2VcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goU1RBVFVTX1VSTCk7XG4gICAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgICAgIHRoaXMubG9nLndhcm4oJ2NoZWNrU3RhdHVzIGZldGNoJywgcmVzcG9uc2Uuc3RhdHVzVGV4dCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHN2ZyA9IGF3YWl0IHJlc3BvbnNlLnRleHQoKTtcbiAgICAgIC8vIEF0dGVtcHQgdG8gcGFyc2UgdGhlIHN0YXR1cyBoZWFkZXJcbiAgICAgIGxldCBzdGF0dXM7XG4gICAgICB0cnkge1xuICAgICAgICBzdGF0dXMgPSBKU09OLnBhcnNlKHJlc3BvbnNlLmhlYWRlcnMuZ2V0KCdYLVNlcnZlci1TdGF0dXMnKSA/PyAnJyk7XG4gICAgICAgICgwLCBfdXRpbHMuYXNzZXJ0SXNCb29sZWFuKShzdGF0dXMudXApO1xuICAgICAgICAoMCwgX3V0aWxzLmFzc2VydElzTnVtYmVyKShzdGF0dXMuc2luY2UpO1xuICAgICAgICAoMCwgX3V0aWxzLmFzc2VydElzTnVtYmVyKShzdGF0dXMudXBkYXRlZCk7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgdGhpcy5sb2cud2FybignY2hlY2tTdGF0dXMgWC1TZXJ2ZXItU3RhdHVzJywgZXJyKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgLy8gVXBkYXRlIHRoZSBkaXNwbGF5ZWQgc3RhdHVzLCBpZiBpdCBoYXMgY2hhbmdlZFxuICAgICAgaWYgKHRoaXMubGFzdFVwZGF0ZWQgIT09IHN0YXR1cy51cGRhdGVkKSB7XG4gICAgICAgIHRoaXMubGFzdFVwZGF0ZWQgPSBzdGF0dXMudXBkYXRlZDtcbiAgICAgICAgcG9sbEFnYWluID0gdGhpcy5zaG93U3RhdHVzKHN2Zywgc3RhdHVzKTtcbiAgICAgIH1cbiAgICAgIC8vIERlbGF5IGJlZm9yZSBwb2xsaW5nIHRoZSBzdGF0dXMgYWdhaW4gKGlmIHRoZXJlIGFyZSBzZXJ2ZXIgaXNzdWVzKVxuICAgICAgYXdhaXQgbmV3IFByb21pc2UocmVzb2x2ZSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIFBPTExfSU5URVJWQUwpKTtcbiAgICB9XG4gIH1cbiAgLy8gRGlzcGxheSB0aGUgbGF0ZXN0IHN0YXR1cyBvZiB0aGUgSG9tZSBDb25uZWN0IEFQSSBzZXJ2ZXJzXG4gIHNob3dTdGF0dXMoc3ZnLCBzdGF0dXMpIHtcbiAgICAvLyBEaXNwbGF5IHRoZSBhcHByb3ByaWF0ZSBzdW1tYXJ5XG4gICAgKDAsIF91dGlsc0RvbS5nZXRFbGVtZW50QnlJZCkoJ2hjLWFwaS11cCcpLmhpZGRlbiA9ICFzdGF0dXMudXA7XG4gICAgKDAsIF91dGlsc0RvbS5nZXRFbGVtZW50QnlJZCkoJ2hjLWFwaS11cDInKS5oaWRkZW4gPSAhc3RhdHVzLnVwO1xuICAgICgwLCBfdXRpbHNEb20uZ2V0RWxlbWVudEJ5SWQpKCdoYy1hcGktZG93bicpLmhpZGRlbiA9IHN0YXR1cy51cDtcbiAgICAoMCwgX3V0aWxzRG9tLmdldEVsZW1lbnRCeUlkKSgnaGMtYXBpLWRvd24yJykuaGlkZGVuID0gc3RhdHVzLnVwO1xuICAgIC8vIEFkZCB0aGUgZGV0YWlsZWQgc3RhdHVzXG4gICAgKDAsIF91dGlsc0RvbS5nZXRFbGVtZW50QnlJZCkoJ2hjLWFwaS1zaW5jZScpLmlubmVyVGV4dCA9IHRoaXMuZm9ybWF0RGF0ZVRpbWUoc3RhdHVzLnNpbmNlKTtcbiAgICAvLyBBZGQgdGhlIHJldHJpZXZlZCBzdGF0dXMgaW1hZ2VcbiAgICAoMCwgX3V0aWxzRG9tLmdldEVsZW1lbnRCeUlkKSgnaGMtYXBpLXN2ZycpLmlubmVySFRNTCA9IHN2ZztcbiAgICAvLyBTaG93IG9yIGhpZGUgdGhlIHN0YXR1cyBhcyBhcHByb3ByaWF0ZVxuICAgIGNvbnN0IHNob3dTdGF0dXMgPSAhc3RhdHVzLnVwIHx8IERhdGUubm93KCkgPCBzdGF0dXMuc2luY2UgKyBTVEFUVVNfU0lOQ0U7XG4gICAgKDAsIF91dGlsc0RvbS5nZXRFbGVtZW50QnlJZCkoJ2hjLWFwaS1zdGF0dXMnKS5oaWRkZW4gPSAhc2hvd1N0YXR1cztcbiAgICByZXR1cm4gc2hvd1N0YXR1cztcbiAgfVxuICAvLyBGb3JtYXQgYSBkYXRlL3RpbWVcbiAgZm9ybWF0RGF0ZVRpbWUoZGF0ZSkge1xuICAgIHJldHVybiBuZXcgRGF0ZShkYXRlKS50b0xvY2FsZVN0cmluZyh1bmRlZmluZWQsIHtcbiAgICAgIHdlZWtkYXk6ICdsb25nJyxcbiAgICAgIG1vbnRoOiAnbG9uZycsXG4gICAgICBkYXk6ICdudW1lcmljJyxcbiAgICAgIGhvdXI6ICdudW1lcmljJyxcbiAgICAgIG1pbnV0ZTogJzItZGlnaXQnLFxuICAgICAgdGltZVpvbmVOYW1lOiAnc2hvcnQnXG4gICAgfSk7XG4gIH1cbn1cbmV4cG9ydHMuQVBJU3RhdHVzID0gQVBJU3RhdHVzO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ9dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p1WVcxbGN5STZXeUpmZFhScGJITWlMQ0p5WlhGMWFYSmxJaXdpWDNWMGFXeHpSRzl0SWl3aVgyeHZaMFZ5Y205eUlpd2lVMVJCVkZWVFgxVlNUQ0lzSWxOVVFWUlZVMTlUU1U1RFJTSXNJazFUSWl3aVVFOU1URjlKVGxSRlVsWkJUQ0lzSWtGUVNWTjBZWFIxY3lJc0ltTnZibk4wY25WamRHOXlJaXdpYkc5bklpd2laR1YwWVdOb1pXUWlMQ0p3YjJ4c1UzUmhkSFZ6SWl3aWNHOXNiRUZuWVdsdUlpd2ljbVZ6Y0c5dWMyVWlMQ0ptWlhSamFDSXNJbTlySWl3aWQyRnliaUlzSW5OMFlYUjFjMVJsZUhRaUxDSnpkbWNpTENKMFpYaDBJaXdpYzNSaGRIVnpJaXdpU2xOUFRpSXNJbkJoY25ObElpd2lhR1ZoWkdWeWN5SXNJbWRsZENJc0ltRnpjMlZ5ZEVselFtOXZiR1ZoYmlJc0luVndJaXdpWVhOelpYSjBTWE5PZFcxaVpYSWlMQ0p6YVc1alpTSXNJblZ3WkdGMFpXUWlMQ0psY25JaUxDSnNZWE4wVlhCa1lYUmxaQ0lzSW5Ob2IzZFRkR0YwZFhNaUxDSlFjbTl0YVhObElpd2ljbVZ6YjJ4MlpTSXNJbk5sZEZScGJXVnZkWFFpTENKblpYUkZiR1Z0Wlc1MFFubEpaQ0lzSW1ocFpHUmxiaUlzSW1sdWJtVnlWR1Y0ZENJc0ltWnZjbTFoZEVSaGRHVlVhVzFsSWl3aWFXNXVaWEpJVkUxTUlpd2lSR0YwWlNJc0ltNXZkeUlzSW1SaGRHVWlMQ0owYjB4dlkyRnNaVk4wY21sdVp5SXNJblZ1WkdWbWFXNWxaQ0lzSW5kbFpXdGtZWGtpTENKdGIyNTBhQ0lzSW1SaGVTSXNJbWh2ZFhJaUxDSnRhVzUxZEdVaUxDSjBhVzFsV205dVpVNWhiV1VpTENKbGVIQnZjblJ6SWwwc0luTnZkWEpqWlhNaU9sc2lMaTR2TGk0dkxpNHZjM0pqTDJodmJXVmljbWxrWjJVdGRXa3ZjSFZpYkdsakwyRndhUzF6ZEdGMGRYTXVkSE1pWFN3aWMyOTFjbU5sYzBOdmJuUmxiblFpT2x0dWRXeHNYU3dpYldGd2NHbHVaM01pT2lJN096czdPenRCUVVsQkxFbEJRVUZCTEUxQlFVRXNSMEZCUVVNc1QwRkJRVHRCUVVOQkxFbEJRVUZETEZOQlFVRXNSMEZCUVVRc1QwRkJRVHRCUVVOQkxFbEJRVUZGTEZOQlFVRXNSMEZCUVVZc1QwRkJRVHRCUVU1Qk8wRkJRMEU3TzBGQlQwRTdRVUZEUVN4TlFVRk5SeXhWUVVGVkxFZEJRVWNzSzBSQlFTdEVPMEZCUld4R08wRkJRMEVzVFVGQlRVTXNXVUZCV1N4SFFVRkhMRVZCUVVVc1IwRkJSeXhGUVVGRkxFZEJRVWNzUlVGQlJTeEhRVUZIUXl4VFFVRkZPMEZCUlhSRE8wRkJRMEVzVFVGQlRVTXNZVUZCWVN4SFFVRkhMRWRCUVVjc1IwRkJSeXhGUVVGRkxFZEJRVWRFTEZOQlFVVTdRVUZUYmtNN1FVRkRUU3hOUVVGUFJTeFRRVUZUTzBWQlMyeENPMFZCUTBGRExGbEJRWEZDUXl4SFFVRlhPMGxCUVZnc1MwRkJRVUVzUjBGQlJ5eEhRVUZJUVN4SFFVRkhPMGxCUTNCQ0xFbEJRVUZETEd0Q1FVRlJMRVZCUVVNc1NVRkJTU3hEUVVGRFJDeEhRVUZITEVWQlFVVXNZVUZCWVN4RlFVRkZMRTFCUVUwc1NVRkJTU3hEUVVGRFJTeFZRVUZWTEVWQlFVVXNRMEZCUXl4RlFVRkZPMFZCUTJoRk8wVkJSVUU3UlVGRFFTeE5RVUZOUVN4VlFVRlZRU3hEUVVGQk8wbEJRMW9zU1VGQlNVTXNVMEZCVXl4SFFVRkhMRWxCUVVrN1NVRkRjRUlzVDBGQlQwRXNVMEZCVXl4RlFVRkZPMDFCUTJRN1RVRkRRU3hOUVVGTlF5eFJRVUZSTEVkQlFVY3NUVUZCVFVNc1MwRkJTeXhEUVVGRFdDeFZRVUZWTEVOQlFVTTdUVUZEZUVNc1NVRkJTU3hEUVVGRFZTeFJRVUZSTEVOQlFVTkZMRVZCUVVVc1JVRkJSVHRSUVVOa0xFbEJRVWtzUTBGQlEwNHNSMEZCUnl4RFFVRkRUeXhKUVVGSkxFTkJRVU1zYlVKQlFXMUNMRVZCUVVWSUxGRkJRVkVzUTBGQlEwa3NWVUZCVlN4RFFVRkRPMUZCUTNaRU8wMUJRMG83VFVGRFFTeE5RVUZOUXl4SFFVRkhMRWRCUVVjc1RVRkJUVXdzVVVGQlVTeERRVUZEVFN4SlFVRkpMRVZCUVVVN1RVRkZha003VFVGRFFTeEpRVUZKUXl4TlFVRk5PMDFCUTFZc1NVRkJTVHRSUVVOQlFTeE5RVUZOTEVkQlFVZERMRWxCUVVrc1EwRkJRME1zUzBGQlN5eERRVUZEVkN4UlFVRlJMRU5CUVVOVkxFOUJRVThzUTBGQlEwTXNSMEZCUnl4RFFVRkRMR2xDUVVGcFFpeERRVUZETEVsQlFVa3NSVUZCUlN4RFFVRnBRanRSUVVOc1JpeEpRVUZCUXl4elFrRkJaU3hGUVVGRFRDeE5RVUZOTEVOQlFVTk5MRVZCUVVVc1EwRkJRenRSUVVNeFFpeEpRVUZCUXl4eFFrRkJZeXhGUVVGRFVDeE5RVUZOTEVOQlFVTlJMRXRCUVVzc1EwRkJRenRSUVVNMVFpeEpRVUZCUkN4eFFrRkJZeXhGUVVGRFVDeE5RVUZOTEVOQlFVTlRMRTlCUVU4c1EwRkJRenROUVVOc1F5eERRVUZETEVOQlFVTXNUMEZCVDBNc1IwRkJSeXhGUVVGRk8xRkJRMVlzU1VGQlNTeERRVUZEY2tJc1IwRkJSeXhEUVVGRFR5eEpRVUZKTEVOQlFVTXNOa0pCUVRaQ0xFVkJRVVZqTEVkQlFVY3NRMEZCUXp0UlFVTnFSRHROUVVOS08wMUJSVUU3VFVGRFFTeEpRVUZKTEVsQlFVa3NRMEZCUTBNc1YwRkJWeXhMUVVGTFdDeE5RVUZOTEVOQlFVTlRMRTlCUVU4c1JVRkJSVHRSUVVOeVF5eEpRVUZKTEVOQlFVTkZMRmRCUVZjc1IwRkJSMWdzVFVGQlRTeERRVUZEVXl4UFFVRlBPMUZCUTJwRGFrSXNVMEZCVXl4SFFVRkhMRWxCUVVrc1EwRkJRMjlDTEZWQlFWVXNRMEZCUTJRc1IwRkJSeXhGUVVGRlJTeE5RVUZOTEVOQlFVTTdUVUZETlVNN1RVRkZRVHROUVVOQkxFMUJRVTBzU1VGQlNXRXNUMEZCVHl4RFFVRkRReXhQUVVGUExFbEJRVWxETEZWQlFWVXNRMEZCUTBRc1QwRkJUeXhGUVVGRk5VSXNZVUZCWVN4RFFVRkRMRU5CUVVNN1NVRkRjRVU3UlVGRFNqdEZRVVZCTzBWQlEwRXdRaXhWUVVGVlFTeERRVUZEWkN4SFFVRlhMRVZCUVVWRkxFMUJRVzlDTzBsQlEzaERPMGxCUTBFc1NVRkJRV2RDTEhkQ1FVRmpMRVZCUVVNc1YwRkJWeXhEUVVGRExFTkJRVU5ETEUxQlFVMHNSMEZCUnl4RFFVRkRha0lzVFVGQlRTeERRVUZEVFN4RlFVRkZPMGxCUXk5RExFbEJRVUZWTEhkQ1FVRmpMRVZCUVVNc1dVRkJXU3hEUVVGRExFTkJRVU5ETEUxQlFVMHNSMEZCUnl4RFFVRkRha0lzVFVGQlRTeERRVUZEVFN4RlFVRkZPMGxCUTJoRUxFbEJRVUZWTEhkQ1FVRmpMRVZCUVVNc1lVRkJZU3hEUVVGRExFTkJRVU5ETEUxQlFVMHNSMEZCUjJwQ0xFMUJRVTBzUTBGQlEwMHNSVUZCUlR0SlFVTm9SQ3hKUVVGQlZTeDNRa0ZCWXl4RlFVRkRMR05CUVdNc1EwRkJReXhEUVVGRFF5eE5RVUZOTEVkQlFVZHFRaXhOUVVGTkxFTkJRVU5OTEVWQlFVVTdTVUZGYWtRN1NVRkRRU3hKUVVGQlZTeDNRa0ZCWXl4RlFVRkRMR05CUVdNc1EwRkJReXhEUVVGRFJTeFRRVUZUTEVkQlFVY3NTVUZCU1N4RFFVRkRReXhqUVVGakxFTkJRVU51UWl4TlFVRk5MRU5CUVVOUkxFdEJRVXNzUTBGQlF6dEpRVVUxUlR0SlFVTkJMRWxCUVVGUkxIZENRVUZqTEVWQlFVTXNXVUZCV1N4RFFVRkRMRU5CUVVOSkxGTkJRVk1zUjBGQlIzUkNMRWRCUVVjN1NVRkZOVU03U1VGRFFTeE5RVUZOWXl4VlFVRlZMRWRCUVVjc1EwRkJRMW9zVFVGQlRTeERRVUZEVFN4RlFVRkZMRWxCUVVsbExFbEJRVWtzUTBGQlEwTXNSMEZCUnl4RlFVRkZMRWRCUVVkMFFpeE5RVUZOTEVOQlFVTlJMRXRCUVVzc1IwRkJSM2hDTEZsQlFWazdTVUZEZWtVc1NVRkJRV2RETEhkQ1FVRmpMRVZCUVVNc1pVRkJaU3hEUVVGRExFTkJRVU5ETEUxQlFVMHNSMEZCUnl4RFFVRkRUQ3hWUVVGVk8wbEJRM0JFTEU5QlFVOUJMRlZCUVZVN1JVRkRja0k3UlVGRlFUdEZRVU5CVHl4alFVRmpRU3hEUVVGRFNTeEpRVUZaTzBsQlEzWkNMRTlCUVU4c1NVRkJTVVlzU1VGQlNTeERRVUZEUlN4SlFVRkpMRU5CUVVNc1EwRkJRME1zWTBGQll5eERRVUZEUXl4VFFVRlRMRVZCUVVVN1RVRkROVU5ETEU5QlFVOHNSVUZCVXl4TlFVRk5PMDFCUTNSQ1F5eExRVUZMTEVWQlFWY3NUVUZCVFR0TlFVTjBRa01zUjBGQlJ5eEZRVUZoTEZOQlFWTTdUVUZEZWtKRExFbEJRVWtzUlVGQldTeFRRVUZUTzAxQlEzcENReXhOUVVGTkxFVkJRVlVzVTBGQlV6dE5RVU42UWtNc1dVRkJXU3hGUVVGSk8wdEJRMjVDTEVOQlFVTTdSVUZEVGpzN1FVRkRTRU1zVDBGQlFTeERRVUZCTjBNc1UwRkJRU3hIUVVGQlFTeFRRVUZCSWl3aWFXZHViM0psVEdsemRDSTZXMTE5IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLkNhcmRzID0gdm9pZCAwO1xudmFyIF91dGlscyA9IHJlcXVpcmUoXCIuLi8uLi91dGlscy5qc1wiKTtcbnZhciBfdXRpbHNEb20gPSByZXF1aXJlKFwiLi91dGlscy1kb20uanNcIik7XG52YXIgX2xvZ0Vycm9yID0gcmVxdWlyZShcIi4uLy4uL2xvZy1lcnJvci5qc1wiKTtcbi8vIEhvbWVicmlkZ2UgcGx1Z2luIGZvciBIb21lIENvbm5lY3QgaG9tZSBhcHBsaWFuY2VzXG4vLyBDb3B5cmlnaHQgwqkgMjAyMy0yMDI2IEFsZXhhbmRlciBUaG91a3lkaWRlc1xuXG4vLyBDYXJkcyB0byBzZWxlY3QgZ2xvYmFsIG9yIHBlci1hcHBsaWFuY2UgY29uZmlndXJhdGlvblxuY2xhc3MgQ2FyZHMge1xuICAvLyBDb25zdHJ1Y3QgYSBuZXcgY2FyZHMgaGFuZGxlclxuICBjb25zdHJ1Y3Rvcihsb2cpIHtcbiAgICB0aGlzLmxvZyA9IGxvZztcbiAgICAvLyBDdXJyZW50IGNhcmRzXG4gICAgdGhpcy5ub25BcHBsaWFuY2VDYXJkcyA9IFtdO1xuICAgIHRoaXMuYXBwbGlhbmNlQ2FyZHMgPSBbXTtcbiAgICB0aGlzLnBhcmVudEVsZW1lbnQgPSAoMCwgX3V0aWxzRG9tLmdldEVsZW1lbnRCeUlkKSgnaGMtYXBwbGlhbmNlLWNhcmRzJyk7XG4gIH1cbiAgLy8gVXBkYXRlIHRoZSBsaXN0IG9mIG5vbi1hcHBsaWFuY2UgY2FyZHNcbiAgc2V0Tm9uQXBwbGlhbmNlcyhjYXJkcykge1xuICAgIHRoaXMubm9uQXBwbGlhbmNlQ2FyZHMgPSBjYXJkcztcbiAgICB0aGlzLnVwZGF0ZUNhcmRzKCk7XG4gIH1cbiAgLy8gVXBkYXRlIHRoZSBsaXN0IG9mIGFwcGxpYW5jZXNcbiAgc2V0QXBwbGlhbmNlcyhhcHBsaWFuY2VzKSB7XG4gICAgLy8gQ29udmVydCB0aGUgYXBwbGlhbmNlcyB0byBjYXJkIGRlc2NyaXB0aW9uc1xuICAgIGNvbnN0IGFwcGxpYW5jZUNhcmRzID0gYXBwbGlhbmNlcy5tYXAoYXBwbGlhbmNlID0+ICh7XG4gICAgICBpZDogYXBwbGlhbmNlLmhhSWQsXG4gICAgICBpY29uOiBhcHBsaWFuY2UudHlwZS50b0xvY2FsZUxvd2VyQ2FzZSgpLFxuICAgICAgbmFtZTogYXBwbGlhbmNlLm5hbWUsXG4gICAgICBkZXRhaWw6IGAke2FwcGxpYW5jZS5icmFuZH0gJHthcHBsaWFuY2UuZW51bWJlcn1gXG4gICAgfSkpO1xuICAgIGFwcGxpYW5jZUNhcmRzLnNvcnQoKGEsIGIpID0+IGEubmFtZS5sb2NhbGVDb21wYXJlKGIubmFtZSkpO1xuICAgIC8vIENoZWNrIHdoZXRoZXIgdGhlIGxpc3Qgb2YgYXBwbGlhbmNlcyBoYXMgY2hhbmdlZFxuICAgIGlmIChKU09OLnN0cmluZ2lmeShhcHBsaWFuY2VDYXJkcykgIT09IEpTT04uc3RyaW5naWZ5KHRoaXMuYXBwbGlhbmNlQ2FyZHMpKSB7XG4gICAgICB0aGlzLmFwcGxpYW5jZUNhcmRzID0gYXBwbGlhbmNlQ2FyZHM7XG4gICAgICB0aGlzLnVwZGF0ZUNhcmRzKCk7XG4gICAgfVxuICB9XG4gIC8vIFVwZGF0ZSB0aGUgbGlzdCBvZiBjYXJkcyBhbmQgcmVzdG9yZSB0aGUgc2VsZWN0aW9uLCBpZiBzdGlsbCB2YWxpZFxuICB1cGRhdGVDYXJkcygpIHtcbiAgICAvLyBSZXBsYWNlIHRoZSBleGlzdGluZyBjYXJkcyB3aXRoIG5ldyBvbmVzXG4gICAgY29uc3QgYWxsQ2FyZHMgPSBbLi4udGhpcy5ub25BcHBsaWFuY2VDYXJkcywgLi4udGhpcy5hcHBsaWFuY2VDYXJkc107XG4gICAgdGhpcy5wYXJlbnRFbGVtZW50LnJlcGxhY2VDaGlsZHJlbiguLi5hbGxDYXJkcy5tYXAoY2FyZCA9PiB0aGlzLm1ha2VDYXJkKGNhcmQpKSk7XG4gICAgdGhpcy5wYXJlbnRFbGVtZW50LmhpZGRlbiA9ICFhbGxDYXJkcy5sZW5ndGg7XG4gICAgLy8gUmVzdG9yZSBhbnkgcHJldmlvdXMgc2VsZWN0aW9uXG4gICAgdGhpcy5zZWxlY3RDYXJkKHRoaXMuc2VsZWN0ZWRDYXJkSWQpO1xuICB9XG4gIC8vIENyZWF0ZSBhIG5ldyBjYXJkXG4gIG1ha2VDYXJkKHtcbiAgICBpZCxcbiAgICBpY29uLFxuICAgIG5hbWUsXG4gICAgZGV0YWlsXG4gIH0pIHtcbiAgICAvLyBDcmVhdGUgYSBuZXcgY2FyZCBmcm9tIHRoZSB0ZW1wbGF0ZVxuICAgIGRldGFpbCA/PyAoZGV0YWlsID0gJ8KgJyk7IC8vIChub24tYnJlYWtpbmcgc3BhY2UpXG4gICAgY29uc3QgY2FyZCA9ICgwLCBfdXRpbHNEb20uY2xvbmVUZW1wbGF0ZSkoJ2hjLWFwcGxpYW5jZS1jYXJkJywge1xuICAgICAgbmFtZSxcbiAgICAgIGRldGFpbFxuICAgIH0pO1xuICAgICgwLCBfbG9nRXJyb3IuZGV0YWNoZWQpKHRoaXMubG9nLCAnTG9hZCBjYXJkIGljb24nLCAoKSA9PiB0aGlzLmxvYWRDYXJkSWNvbigoMCwgX3V0aWxzRG9tLmdldFNsb3QpKGNhcmQsICdpY29uJyksIGAuL2ltYWdlcy9pY29uLSR7aWNvbn0uc3ZnYCwgaWQpKSgpO1xuICAgIC8vIEhhbmRsZSBjYXJkIHNlbGVjdGlvblxuICAgIGNvbnN0IGVsZW1lbnQgPSBjYXJkLmNoaWxkcmVuWzBdO1xuICAgICgwLCBfdXRpbHMuYXNzZXJ0SXNJbnN0YW5jZU9mKShlbGVtZW50LCBIVE1MRWxlbWVudCk7XG4gICAgZWxlbWVudC5kYXRhc2V0LmlkID0gaWQ7XG4gICAgZWxlbWVudC5vbmNsaWNrID0gKCkgPT4ge1xuICAgICAgdGhpcy5zZWxlY3RDYXJkKGlkKTtcbiAgICB9O1xuICAgIHJldHVybiBjYXJkO1xuICB9XG4gIC8vIExvYWQgdGhlIGljb24gaW1hZ2UgZm9yIGEgY2FyZFxuICBhc3luYyBsb2FkQ2FyZEljb24oZWxlbWVudCwgdXJsLCBpZCkge1xuICAgIC8vIExvYWQgdGhlIGljb24gYW5kIGFkZCBpdCB0byB0aGUgY2FyZFxuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2godXJsKTtcbiAgICBpZiAoIXJlc3BvbnNlLm9rKSB0aHJvdyBuZXcgRXJyb3IoYEZhaWxlZCB0byBmZXRjaCBpY29uICR7cmVzcG9uc2UudXJsfTogJHtyZXNwb25zZS5zdGF0dXNUZXh0fWApO1xuICAgIGVsZW1lbnQuaW5uZXJIVE1MID0gYXdhaXQgcmVzcG9uc2UudGV4dCgpO1xuICAgIC8vIENoYW5nZSB0aGUgZ3JvdXAgKGxheWVyKSBJRHMgdG8gY2xhc3Nlc1xuICAgIGVsZW1lbnQucXVlcnlTZWxlY3RvckFsbCgnZ1tpZF0nKS5mb3JFYWNoKGdyb3VwID0+IHtcbiAgICAgIGNvbnN0IGlkID0gZ3JvdXAuZ2V0QXR0cmlidXRlKCdpZCcpO1xuICAgICAgKDAsIF91dGlscy5hc3NlcnRJc0RlZmluZWQpKGlkKTtcbiAgICAgIGdyb3VwLnJlbW92ZUF0dHJpYnV0ZSgnaWQnKTtcbiAgICAgIGdyb3VwLmNsYXNzTGlzdC5hZGQoaWQpO1xuICAgIH0pO1xuICAgIC8vIEFzc2lnbiB1bmlxdWUgSURzIHRvIGdyYWRpZW50IGZpbGxzXG4gICAgZWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKCdkZWZzIFtpZF0nKS5mb3JFYWNoKGRlZiA9PiB7XG4gICAgICBjb25zdCBvbGRJZCA9IGRlZi5nZXRBdHRyaWJ1dGUoJ2lkJyk7XG4gICAgICBjb25zdCBuZXdJZCA9IGAke2lkfS0ke29sZElkfWA7XG4gICAgICBkZWYuc2V0QXR0cmlidXRlKCdpZCcsIG5ld0lkKTtcbiAgICAgIGVsZW1lbnQucXVlcnlTZWxlY3RvckFsbChgW2ZpbGw9J3VybCgjJHtvbGRJZH0pJ11gKS5mb3JFYWNoKHJlZiA9PiB7XG4gICAgICAgIHJlZi5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCBgdXJsKCMke25ld0lkfSlgKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG4gIC8vIEEgY2FyZCBoYXMgYmVlbiBzZWxlY3RlZFxuICBzZWxlY3RDYXJkKGlkKSB7XG4gICAgLy8gU2VsZWN0IHRoaXMgY2FyZCBhbmQgZGVzZWxlY3QgYWxsIG90aGVyc1xuICAgIGxldCBzZWxlY3RlZENhcmQ7XG4gICAgZm9yIChjb25zdCBjYXJkIG9mIEFycmF5LmZyb20odGhpcy5wYXJlbnRFbGVtZW50LmNoaWxkcmVuKSkge1xuICAgICAgKDAsIF91dGlscy5hc3NlcnRJc0luc3RhbmNlT2YpKGNhcmQsIEhUTUxFbGVtZW50KTtcbiAgICAgIGlmIChjYXJkLmRhdGFzZXQuaWQgPT09IGlkKSBzZWxlY3RlZENhcmQgPSBjYXJkO1xuICAgICAgY2FyZC5jbGFzc0xpc3QudG9nZ2xlKCdoYy1zZWxlY3RlZCcsIGNhcmQuZGF0YXNldC5pZCA9PT0gaWQpO1xuICAgIH1cbiAgICBpZiAoIXNlbGVjdGVkQ2FyZCkgaWQgPSB1bmRlZmluZWQ7XG4gICAgLy8gTm90aWZ5IHRoZSBjbGllbnQgb2Ygc2VsZWN0aW9uIGNoYW5nZXNcbiAgICBpZiAodGhpcy5zZWxlY3RlZENhcmRJZCAhPT0gaWQpIHtcbiAgICAgIHRoaXMubG9nLmRlYnVnKGBvblNlbGVjdCgke2lkfSkgKHdhcyAke3RoaXMuc2VsZWN0ZWRDYXJkSWR9KWApO1xuICAgICAgdGhpcy5zZWxlY3RlZENhcmRJZCA9IGlkO1xuICAgICAgdGhpcy5vblNlbGVjdD8uKGlkKTtcbiAgICB9XG4gIH1cbn1cbmV4cG9ydHMuQ2FyZHMgPSBDYXJkcztcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRhdGE6YXBwbGljYXRpb24vanNvbjtjaGFyc2V0PXV0Zi04O2Jhc2U2NCxleUoyWlhKemFXOXVJam96TENKdVlXMWxjeUk2V3lKZmRYUnBiSE1pTENKeVpYRjFhWEpsSWl3aVgzVjBhV3h6Ukc5dElpd2lYMnh2WjBWeWNtOXlJaXdpUTJGeVpITWlMQ0pqYjI1emRISjFZM1J2Y2lJc0lteHZaeUlzSW01dmJrRndjR3hwWVc1alpVTmhjbVJ6SWl3aVlYQndiR2xoYm1ObFEyRnlaSE1pTENKd1lYSmxiblJGYkdWdFpXNTBJaXdpWjJWMFJXeGxiV1Z1ZEVKNVNXUWlMQ0p6WlhST2IyNUJjSEJzYVdGdVkyVnpJaXdpWTJGeVpITWlMQ0oxY0dSaGRHVkRZWEprY3lJc0luTmxkRUZ3Y0d4cFlXNWpaWE1pTENKaGNIQnNhV0Z1WTJWeklpd2liV0Z3SWl3aVlYQndiR2xoYm1ObElpd2lhV1FpTENKb1lVbGtJaXdpYVdOdmJpSXNJblI1Y0dVaUxDSjBiMHh2WTJGc1pVeHZkMlZ5UTJGelpTSXNJbTVoYldVaUxDSmtaWFJoYVd3aUxDSmljbUZ1WkNJc0ltVnVkVzFpWlhJaUxDSnpiM0owSWl3aVlTSXNJbUlpTENKc2IyTmhiR1ZEYjIxd1lYSmxJaXdpU2xOUFRpSXNJbk4wY21sdVoybG1lU0lzSW1Gc2JFTmhjbVJ6SWl3aWNtVndiR0ZqWlVOb2FXeGtjbVZ1SWl3aVkyRnlaQ0lzSW0xaGEyVkRZWEprSWl3aWFHbGtaR1Z1SWl3aWJHVnVaM1JvSWl3aWMyVnNaV04wUTJGeVpDSXNJbk5sYkdWamRHVmtRMkZ5WkVsa0lpd2lZMnh2Ym1WVVpXMXdiR0YwWlNJc0ltUmxkR0ZqYUdWa0lpd2liRzloWkVOaGNtUkpZMjl1SWl3aVoyVjBVMnh2ZENJc0ltVnNaVzFsYm5RaUxDSmphR2xzWkhKbGJpSXNJbUZ6YzJWeWRFbHpTVzV6ZEdGdVkyVlBaaUlzSWtoVVRVeEZiR1Z0Wlc1MElpd2laR0YwWVhObGRDSXNJbTl1WTJ4cFkyc2lMQ0oxY213aUxDSnlaWE53YjI1elpTSXNJbVpsZEdOb0lpd2liMnNpTENKRmNuSnZjaUlzSW5OMFlYUjFjMVJsZUhRaUxDSnBibTVsY2toVVRVd2lMQ0owWlhoMElpd2ljWFZsY25sVFpXeGxZM1J2Y2tGc2JDSXNJbVp2Y2tWaFkyZ2lMQ0puY205MWNDSXNJbWRsZEVGMGRISnBZblYwWlNJc0ltRnpjMlZ5ZEVselJHVm1hVzVsWkNJc0luSmxiVzkyWlVGMGRISnBZblYwWlNJc0ltTnNZWE56VEdsemRDSXNJbUZrWkNJc0ltUmxaaUlzSW05c1pFbGtJaXdpYm1WM1NXUWlMQ0p6WlhSQmRIUnlhV0oxZEdVaUxDSnlaV1lpTENKelpXeGxZM1JsWkVOaGNtUWlMQ0pCY25KaGVTSXNJbVp5YjIwaUxDSjBiMmRuYkdVaUxDSjFibVJsWm1sdVpXUWlMQ0prWldKMVp5SXNJbTl1VTJWc1pXTjBJaXdpWlhod2IzSjBjeUpkTENKemIzVnlZMlZ6SWpwYklpNHVMeTR1THk0dUwzTnlZeTlvYjIxbFluSnBaR2RsTFhWcEwzQjFZbXhwWXk5allYSmtjeTUwY3lKZExDSnpiM1Z5WTJWelEyOXVkR1Z1ZENJNlcyNTFiR3hkTENKdFlYQndhVzVuY3lJNklqczdPenM3TzBGQlRVRXNTVUZCUVVFc1RVRkJRU3hIUVVGQlF5eFBRVUZCTzBGQlEwRXNTVUZCUVVNc1UwRkJRU3hIUVVGQlJDeFBRVUZCTzBGQlEwRXNTVUZCUVVVc1UwRkJRU3hIUVVGQlJpeFBRVUZCTzBGQlVrRTdRVUZEUVRzN1FVRnJRa0U3UVVGRFRTeE5RVUZQUnl4TFFVRkxPMFZCWVdRN1JVRkRRVU1zV1VGQmNVSkRMRWRCUVZjN1NVRkJXQ3hMUVVGQlFTeEhRVUZITEVkQlFVaEJMRWRCUVVjN1NVRlVlRUk3U1VGRFFTeExRVUZCUXl4cFFrRkJhVUlzUjBGQmRVSXNSVUZCUlR0SlFVTXhReXhMUVVGQlF5eGpRVUZqTEVkQlFUQkNMRVZCUVVVN1NVRlJkRU1zU1VGQlNTeERRVUZEUXl4aFFVRmhMRWRCUVVjc1NVRkJRVU1zZDBKQlFXTXNSVUZCUXl4dlFrRkJiMElzUTBGQlF6dEZRVU0zUkR0RlFVVkJPMFZCUTBGRExHZENRVUZuUWtFc1EwRkJRME1zUzBGQmQwSTdTVUZEY2tNc1NVRkJTU3hEUVVGRFRDeHBRa0ZCYVVJc1IwRkJSMHNzUzBGQlN6dEpRVU01UWl4SlFVRkpMRU5CUVVORExGZEJRVmNzUlVGQlJUdEZRVU4wUWp0RlFVVkJPMFZCUTBGRExHRkJRV0ZCTEVOQlFVTkRMRlZCUVRKQ08wbEJRM0pETzBsQlEwRXNUVUZCVFZBc1kwRkJZeXhIUVVGSFR5eFZRVUZWTEVOQlFVTkRMRWRCUVVjc1EwRkJRME1zVTBGQlV5eExRVUZMTzAxQlEyaEVReXhGUVVGRkxFVkJRVTFFTEZOQlFWTXNRMEZCUTBVc1NVRkJTVHROUVVOMFFrTXNTVUZCU1N4RlFVRkpTQ3hUUVVGVExFTkJRVU5KTEVsQlFVa3NRMEZCUTBNc2FVSkJRV2xDTEVWQlFVVTdUVUZETVVORExFbEJRVWtzUlVGQlNVNHNVMEZCVXl4RFFVRkRUU3hKUVVGSk8wMUJRM1JDUXl4TlFVRk5MRVZCUVVVc1IwRkJSMUFzVTBGQlV5eERRVUZEVVN4TFFVRkxMRWxCUVVsU0xGTkJRVk1zUTBGQlExTXNUMEZCVHp0TFFVTnNSQ3hEUVVGRExFTkJRVU03U1VGRFNHeENMR05CUVdNc1EwRkJRMjFDTEVsQlFVa3NRMEZCUXl4RFFVRkRReXhEUVVGRExFVkJRVVZETEVOQlFVTXNTMEZCUzBRc1EwRkJReXhEUVVGRFRDeEpRVUZKTEVOQlFVTlBMR0ZCUVdFc1EwRkJRMFFzUTBGQlF5eERRVUZEVGl4SlFVRkpMRU5CUVVNc1EwRkJRenRKUVVVelJEdEpRVU5CTEVsQlFVbFJMRWxCUVVrc1EwRkJRME1zVTBGQlV5eERRVUZEZUVJc1kwRkJZeXhEUVVGRExFdEJRVXQxUWl4SlFVRkpMRU5CUVVORExGTkJRVk1zUTBGQlF5eEpRVUZKTEVOQlFVTjRRaXhqUVVGakxFTkJRVU1zUlVGQlJUdE5RVU40UlN4SlFVRkpMRU5CUVVOQkxHTkJRV01zUjBGQlIwRXNZMEZCWXp0TlFVTndReXhKUVVGSkxFTkJRVU5MTEZkQlFWY3NSVUZCUlR0SlFVTjBRanRGUVVOS08wVkJSVUU3UlVGRFFVRXNWMEZCVjBFc1EwRkJRVHRKUVVOUU8wbEJRMEVzVFVGQlRXOUNMRkZCUVZFc1IwRkJSeXhEUVVGRExFZEJRVWNzU1VGQlNTeERRVUZETVVJc2FVSkJRV2xDTEVWQlFVVXNSMEZCUnl4SlFVRkpMRU5CUVVORExHTkJRV01zUTBGQlF6dEpRVU53UlN4SlFVRkpMRU5CUVVORExHRkJRV0VzUTBGQlEzbENMR1ZCUVdVc1EwRkJReXhIUVVGSFJDeFJRVUZSTEVOQlFVTnFRaXhIUVVGSExFTkJRVU50UWl4SlFVRkpMRWxCUVVrc1NVRkJTU3hEUVVGRFF5eFJRVUZSTEVOQlFVTkVMRWxCUVVrc1EwRkJReXhEUVVGRExFTkJRVU03U1VGRGFFWXNTVUZCU1N4RFFVRkRNVUlzWVVGQllTeERRVUZETkVJc1RVRkJUU3hIUVVGSExFTkJRVU5LTEZGQlFWRXNRMEZCUTBzc1RVRkJUVHRKUVVVMVF6dEpRVU5CTEVsQlFVa3NRMEZCUTBNc1ZVRkJWU3hEUVVGRExFbEJRVWtzUTBGQlEwTXNZMEZCWXl4RFFVRkRPMFZCUTNoRE8wVkJSMEU3UlVGRFFVb3NVVUZCVVVFc1EwRkJRenRKUVVGRmJFSXNSVUZCUlR0SlFVRkZSU3hKUVVGSk8wbEJRVVZITEVsQlFVazdTVUZCUlVNN1JVRkJUU3hEUVVGdFFqdEpRVU5vUkR0SlFVTkJRU3hOUVVGTkxFdEJRVTVCTEUxQlFVMHNSMEZCU3l4SFFVRkhMRVZCUVVNc1EwRkJRenRKUVVOb1FpeE5RVUZOVnl4SlFVRkpMRWRCUVVjc1NVRkJRVTBzZFVKQlFXRXNSVUZCUXl4dFFrRkJiVUlzUlVGQlJUdE5RVUZGYkVJc1NVRkJTVHROUVVGRlF6dEpRVUZOTEVOQlFVVXNRMEZCUXp0SlFVTnFSU3hKUVVGQmEwSXNhMEpCUVZFc1JVRkJReXhKUVVGSkxFTkJRVU53UXl4SFFVRkhMRVZCUVVVc1owSkJRV2RDTEVWQlF6RkNMRTFCUVUwc1NVRkJTU3hEUVVGRGNVTXNXVUZCV1N4RFFVRkRMRWxCUVVGRExHbENRVUZQTEVWQlFVTlVMRWxCUVVrc1JVRkJSU3hOUVVGTkxFTkJRVU1zUlVGQlJTeHBRa0ZCYVVKbUxFbEJRVWtzVFVGQlRTeEZRVUZGUml4RlFVRkZMRU5CUVVNc1EwRkJReXhGUVVGRk8wbEJSVE5HTzBsQlEwRXNUVUZCVFRKQ0xFOUJRVThzUjBGQlIxWXNTVUZCU1N4RFFVRkRWeXhSUVVGUkxFTkJRVU1zUTBGQlF5eERRVUZETzBsQlEyaERMRWxCUVVGRExIbENRVUZyUWl4RlFVRkRSaXhQUVVGUExFVkJRVVZITEZkQlFWY3NRMEZCUXp0SlFVTjRRMGdzVDBGQlR5eERRVUZEU1N4UFFVRlBMRU5CUVVNdlFpeEZRVUZGTEVkQlFVZEJMRVZCUVVVN1NVRkRka0l5UWl4UFFVRlBMRU5CUVVOTExFOUJRVThzUjBGQlJ5eE5RVUZYTzAxQlFVY3NTVUZCU1N4RFFVRkRXQ3hWUVVGVkxFTkJRVU55UWl4RlFVRkZMRU5CUVVNN1NVRkJSU3hEUVVGRE8wbEJRM1JFTEU5QlFVOXBRaXhKUVVGSk8wVkJRMlk3UlVGRlFUdEZRVU5CTEUxQlFVMVJMRmxCUVZsQkxFTkJRVU5GTEU5QlFXOUNMRVZCUVVWTkxFZEJRVmNzUlVGQlJXcERMRVZCUVZVN1NVRkROVVE3U1VGRFFTeE5RVUZOYTBNc1VVRkJVU3hIUVVGSExFMUJRVTFETEV0QlFVc3NRMEZCUTBZc1IwRkJSeXhEUVVGRE8wbEJRMnBETEVsQlFVa3NRMEZCUTBNc1VVRkJVU3hEUVVGRFJTeEZRVUZGTEVWQlFVVXNUVUZCVFN4SlFVRkpReXhMUVVGTExFTkJRVU1zZDBKQlFYZENTQ3hSUVVGUkxFTkJRVU5FTEVkQlFVY3NTMEZCUzBNc1VVRkJVU3hEUVVGRFNTeFZRVUZWTEVWQlFVVXNRMEZCUXp0SlFVTnFSMWdzVDBGQlR5eERRVUZEV1N4VFFVRlRMRWRCUVVjc1RVRkJUVXdzVVVGQlVTeERRVUZEVFN4SlFVRkpMRVZCUVVVN1NVRkZla003U1VGRFFXSXNUMEZCVHl4RFFVRkRZeXhuUWtGQlowSXNRMEZCUXl4UFFVRlBMRU5CUVVNc1EwRkJRME1zVDBGQlR5eERRVUZEUXl4TFFVRkxMRWxCUVVjN1RVRkRPVU1zVFVGQlRUTkRMRVZCUVVVc1IwRkJSekpETEV0QlFVc3NRMEZCUTBNc1dVRkJXU3hEUVVGRExFbEJRVWtzUTBGQlF6dE5RVU51UXl4SlFVRkJReXh6UWtGQlpTeEZRVUZETjBNc1JVRkJSU3hEUVVGRE8wMUJRMjVDTWtNc1MwRkJTeXhEUVVGRFJ5eGxRVUZsTEVOQlFVTXNTVUZCU1N4RFFVRkRPMDFCUXpOQ1NDeExRVUZMTEVOQlFVTkpMRk5CUVZNc1EwRkJRME1zUjBGQlJ5eERRVUZEYUVRc1JVRkJSU3hEUVVGRE8wbEJRek5DTEVOQlFVTXNRMEZCUXp0SlFVVkdPMGxCUTBFeVFpeFBRVUZQTEVOQlFVTmpMR2RDUVVGblFpeERRVUZETEZkQlFWY3NRMEZCUXl4RFFVRkRReXhQUVVGUExFTkJRVU5QTEVkQlFVY3NTVUZCUnp0TlFVTm9SQ3hOUVVGTlF5eExRVUZMTEVkQlFVZEVMRWRCUVVjc1EwRkJRMHdzV1VGQldTeERRVUZETEVsQlFVa3NRMEZCUXp0TlFVTndReXhOUVVGTlR5eExRVUZMTEVkQlFVY3NSMEZCUjI1RUxFVkJRVVVzU1VGQlNXdEVMRXRCUVVzc1JVRkJSVHROUVVNNVFrUXNSMEZCUnl4RFFVRkRSeXhaUVVGWkxFTkJRVU1zU1VGQlNTeEZRVUZGUkN4TFFVRkxMRU5CUVVNN1RVRkROMEo0UWl4UFFVRlBMRU5CUVVOakxHZENRVUZuUWl4RFFVRkRMR1ZCUVdWVExFdEJRVXNzUzBGQlN5eERRVUZETEVOQlFVTlNMRTlCUVU4c1EwRkJRMWNzUjBGQlJ5eEpRVUZITzFGQlFVZEJMRWRCUVVjc1EwRkJRMFFzV1VGQldTeERRVUZETEUxQlFVMHNSVUZCUlN4UlFVRlJSQ3hMUVVGTExFZEJRVWNzUTBGQlF6dE5RVUZGTEVOQlFVTXNRMEZCUXp0SlFVTjJTQ3hEUVVGRExFTkJRVU03UlVGRFRqdEZRVVZCTzBWQlEwRTVRaXhWUVVGVlFTeERRVUZEY2tJc1JVRkJWenRKUVVOc1FqdEpRVU5CTEVsQlFVbHpSQ3haUVVGeFF6dEpRVU42UXl4TFFVRkxMRTFCUVUxeVF5eEpRVUZKTEVsQlFVbHpReXhMUVVGTExFTkJRVU5ETEVsQlFVa3NRMEZCUXl4SlFVRkpMRU5CUVVOcVJTeGhRVUZoTEVOQlFVTnhReXhSUVVGUkxFTkJRVU1zUlVGQlJUdE5RVU40UkN4SlFVRkJReXg1UWtGQmEwSXNSVUZCUTFvc1NVRkJTU3hGUVVGRllTeFhRVUZYTEVOQlFVTTdUVUZEY2tNc1NVRkJTV0lzU1VGQlNTeERRVUZEWXl4UFFVRlBMRU5CUVVNdlFpeEZRVUZGTEV0QlFVdEJMRVZCUVVVc1JVRkJSWE5FTEZsQlFWa3NSMEZCUjNKRExFbEJRVWs3VFVGREwwTkJMRWxCUVVrc1EwRkJRemhDTEZOQlFWTXNRMEZCUTFVc1RVRkJUU3hEUVVGRExHRkJRV0VzUlVGQlJYaERMRWxCUVVrc1EwRkJRMk1zVDBGQlR5eERRVUZETDBJc1JVRkJSU3hMUVVGTFFTeEZRVUZGTEVOQlFVTTdTVUZEYUVVN1NVRkRRU3hKUVVGSkxFTkJRVU56UkN4WlFVRlpMRVZCUVVWMFJDeEZRVUZGTEVkQlFVY3dSQ3hUUVVGVE8wbEJSV3BETzBsQlEwRXNTVUZCU1N4SlFVRkpMRU5CUVVOd1F5eGpRVUZqTEV0QlFVdDBRaXhGUVVGRkxFVkJRVVU3VFVGRE5VSXNTVUZCU1N4RFFVRkRXaXhIUVVGSExFTkJRVU4xUlN4TFFVRkxMRU5CUVVNc1dVRkJXVE5FTEVWQlFVVXNWVUZCVlN4SlFVRkpMRU5CUVVOelFpeGpRVUZqTEVkQlFVY3NRMEZCUXp0TlFVTTVSQ3hKUVVGSkxFTkJRVU5CTEdOQlFXTXNSMEZCUjNSQ0xFVkJRVVU3VFVGRGVFSXNTVUZCU1N4RFFVRkRORVFzVVVGQlVTeEhRVUZITlVRc1JVRkJSU3hEUVVGRE8wbEJRM1pDTzBWQlEwbzdPMEZCUTBnMlJDeFBRVUZCTEVOQlFVRXpSU3hMUVVGQkxFZEJRVUZCTEV0QlFVRWlMQ0pwWjI1dmNtVk1hWE4wSWpwYlhYMD0iLCJcInVzZSBzdHJpY3RcIjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuQ2xpZW50Q2xpZW50SUQgPSB2b2lkIDA7XG52YXIgX3V0aWxzID0gcmVxdWlyZShcIi4uLy4uL3V0aWxzLmpzXCIpO1xudmFyIF91dGlsc0RvbSA9IHJlcXVpcmUoXCIuL3V0aWxzLWRvbS5qc1wiKTtcbnZhciBfbG9nRXJyb3IgPSByZXF1aXJlKFwiLi4vLi4vbG9nLWVycm9yLmpzXCIpO1xuLy8gSG9tZWJyaWRnZSBwbHVnaW4gZm9yIEhvbWUgQ29ubmVjdCBob21lIGFwcGxpYW5jZXNcbi8vIENvcHlyaWdodCDCqSAyMDIzLTIwMjYgQWxleGFuZGVyIFRob3VreWRpZGVzXG5cbi8vIE1pbmltdW0gdGltZSBiZXR3ZWVuIGR1cGxpY2F0ZSB0b2FzdCBub3RpZmljYXRpb25zXG5jb25zdCBUT0FTVF9ERURVUF9USU1FID0gNSAqIF91dGlscy5NUztcbi8vIFRoZSBjdXJyZW50IEhvbWUgQ29ubmVjdCBjbGllbnRcbmNsYXNzIENsaWVudENsaWVudElEIHtcbiAgLy8gQ3JlYXRlIGEgbmV3IEhvbWUgQ29ubmVjdCBjbGllbnRcbiAgY29uc3RydWN0b3IobG9nLCBpcGMpIHtcbiAgICB0aGlzLmxvZyA9IGxvZztcbiAgICB0aGlzLmlwYyA9IGlwYztcbiAgICB0aGlzLmlwYy5vbkV2ZW50KCdzdGF0dXMnLCBzdGF0dXMgPT4ge1xuICAgICAgdGhpcy5vbkNsaWVudFN0YXR1cyhzdGF0dXMpO1xuICAgIH0pO1xuICB9XG4gIC8vIFRoZSBIb21lIENvbm5lY3QgY2xpZW50IGNvbmZpZ3VyYXRpb24gaGFzIGNoYW5nZWRcbiAgYXN5bmMgc2V0Q2xpZW50KGNvbmZpZykge1xuICAgIGNvbnN0IGNsaWVudENvbmZpZyA9IHRoaXMucHJlcGFyZUNsaWVudENvbmZpZyhjb25maWcpO1xuICAgIGlmIChjbGllbnRDb25maWcpIHtcbiAgICAgIC8vIFRlc3QgdGhlIGNsaWVudCBjb25maWd1cmF0aW9uXG4gICAgICB0aGlzLmNsaWVudENvbmZpZyA9IGNsaWVudENvbmZpZztcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHN0YXR1cyA9IGF3YWl0IHRoaXMuaXBjLnJlcXVlc3QoJy9jbGllbnRpZCcsIGNsaWVudENvbmZpZyk7XG4gICAgICAgIHRoaXMub25DbGllbnRTdGF0dXMoc3RhdHVzKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBjb25zdCBtZXNzYWdlID0gZXJyIGluc3RhbmNlb2YgRXJyb3IgPyBlcnIubWVzc2FnZSA6IFN0cmluZyhlcnIpO1xuICAgICAgICB0aGlzLnNob3dUb2FzdCgnZXJyb3InLCBgVW5hYmxlIHRvIGF0dGVtcHQgYXV0aG9yaXNhdGlvbiAke21lc3NhZ2V9YCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIElnbm9yZSB0aGUgY2xpZW50IGNvbmZpZ3VyYXRpb24gdW50aWwgaXQgaXMgdmFsaWRcbiAgICAgIHRoaXMuY2xpZW50Q29uZmlnID0gdW5kZWZpbmVkO1xuICAgICAgdGhpcy5zaG93UGFuZWwoKTtcbiAgICAgIHRoaXMub25BcHBsaWFuY2VzPy4oKTtcbiAgICB9XG4gIH1cbiAgLy8gVGVzdCB3aGV0aGVyIHRoZSBjbGllbnQgY29uZmlndXJhdGlvbiBpcyBsaWtlbHkgdG8gYmUgdmFsaWRcbiAgcHJlcGFyZUNsaWVudENvbmZpZyhjb25maWcpIHtcbiAgICBpZiAoY29uZmlnLmRlYnVnPy5pbmNsdWRlcygnTW9jayBBcHBsaWFuY2VzJykpIHtcbiAgICAgIC8vIE1vY2sgYXBwbGlhbmNlczsgdXNlIGFuIGVtcHR5IGNsaWVudGlkIHRvIG1hdGNoIHRoZSBzdGF0dXNcbiAgICAgIHJldHVybiB7XG4gICAgICAgIC4uLmNvbmZpZyxcbiAgICAgICAgY2xpZW50aWQ6ICcnXG4gICAgICB9O1xuICAgIH0gZWxzZSBpZiAoY29uZmlnLmNsaWVudGlkICE9PSB1bmRlZmluZWQgJiYgL15bMC05QS1GXXs2NH0kL2kudGVzdChjb25maWcuY2xpZW50aWQpKSB7XG4gICAgICAvLyBWaWFibGUgY2xpZW50aWRcbiAgICAgIHJldHVybiBjb25maWc7XG4gICAgfVxuICB9XG4gIC8vIEhhbmRsZSBldmVudHMgZnJvbSB0aGUgSG9tZSBDb25uZWN0IGNsaWVudFxuICBvbkNsaWVudFN0YXR1cyhzdGF0dXMpIHtcbiAgICAvLyBJZ25vcmUgdGhlIHN0YXR1cyBpZiBubyBsb25nZXIgbW9uaXRvcmluZyB0aGUgY2xpZW50XG4gICAgaWYgKHRoaXMuY2xpZW50Q29uZmlnPy5jbGllbnRpZCAhPT0gc3RhdHVzLmNsaWVudGlkKSByZXR1cm47XG4gICAgLy8gVXBkYXRlIHRoZSBsaXN0IG9mIGFwcGxpYW5jZXNcbiAgICB0aGlzLm9uQXBwbGlhbmNlcz8uKHN0YXR1cy5hcHBsaWFuY2VzKTtcbiAgICAvLyBEaXNwbGF5IGFuIGFwcHJvcHJpYXRlIHRvYXN0IG5vdGlmaWNhdGlvblxuICAgIHN3aXRjaCAoc3RhdHVzLmF1dGhvcmlzYXRpb24/LnN0YXRlKSB7XG4gICAgICBjYXNlICdzdWNjZXNzJzpcbiAgICAgICAgdGhpcy5zaG93VG9hc3QoJ3N1Y2Nlc3MnLCAnU3VjY2Vzc2Z1bGx5IGF1dGhvcmlzZWQnKTtcbiAgICAgICAgdGhpcy5zaG93UGFuZWwoKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICd1c2VyJzpcbiAgICAgICAgdGhpcy5zaG93VG9hc3QoJ2luZm8nLCAnVXNlciBhdXRob3Jpc2F0aW9uIHJlcXVpcmVkJyk7XG4gICAgICAgIHRoaXMuc2hvd1VzZXJBdXRob3Jpc2F0aW9uKHN0YXR1cy5hdXRob3Jpc2F0aW9uKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdmYWlsJzpcbiAgICAgICAgdGhpcy5zaG93VG9hc3QoJ2Vycm9yJywgJ0F1dGhvcmlzYXRpb24gZmFpbGVkJyk7XG4gICAgICAgIHRoaXMuc2hvd0ZhaWwoc3RhdHVzLmF1dGhvcmlzYXRpb24pO1xuICAgICAgICB0aGlzLm9uRmFpbD8uKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnYnVzeSc6XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aGlzLnNob3dQYW5lbCgpO1xuICAgIH1cbiAgfVxuICAvLyBQcm9tcHQgdGhlIHVzZXIgdG8gYXV0aG9yaXNlIHRoZSBjbGllbnRcbiAgc2hvd1VzZXJBdXRob3Jpc2F0aW9uKGF1dGhvcmlzYXRpb24pIHtcbiAgICAvLyBTZXQgdGhlIGxpbmsvY29kZVxuICAgIGNvbnN0IGxpbmsgPSAoMCwgX3V0aWxzRG9tLmdldEVsZW1lbnRCeUlkKSgnaGMtY2xpZW50LXVzZXItbGluaycpO1xuICAgIGxpbmsuc2V0QXR0cmlidXRlKCdocmVmJywgYXV0aG9yaXNhdGlvbi51cmkpO1xuICAgICgwLCBfdXRpbHNEb20uc2V0U2xvdFRleHQpKGRvY3VtZW50LCB7XG4gICAgICAnaGMtY2xpZW50LXVzZXItY29kZSc6IGF1dGhvcmlzYXRpb24uY29kZVxuICAgIH0pO1xuICAgIC8vIEVuYWJsZSBnZW5lcmF0aW9uIG9mIGEgbmV3IGF1dGhvcmlzYXRpb24gY29kZVxuICAgICgwLCBfdXRpbHNEb20uZ2V0RWxlbWVudEJ5SWQpKCdoYy1jbGllbnQtdXNlci1yZXRyeScpLm9uY2xpY2sgPSAoKSA9PiB7XG4gICAgICB0aGlzLnJldHJ5QXV0aG9yaXNhdGlvbigpO1xuICAgIH07XG4gICAgLy8gTWFrZSB0aGUgYXV0aG9yaXNhdGlvbiBsaW5rIHZpc2libGUgKGJlZm9yZSB0cmlnZ2VyaW5nIHRyYW5zaXRpb24pXG4gICAgdGhpcy5zaG93UGFuZWwoJ2hjLWNsaWVudC11c2VyJyk7XG4gICAgLy8gU3RhcnQgYW5pbWF0aW5nIHRoZSBwcm9ncmVzcyBiYXIgZm9yIHRoZSB0aW1lIHVudGlsIHRoZSBsaW5rIGV4cGlyZXNcbiAgICBjb25zdCBwcm9ncmVzcyA9ICgwLCBfdXRpbHNEb20uZ2V0RWxlbWVudEJ5SWQpKCdoYy1jbGllbnQtdXNlci1wcm9ncmVzcycpO1xuICAgIHByb2dyZXNzLmNsYXNzTGlzdC5yZW1vdmUoJ2hjLXByb2dyZXNzLXplcm8nKTtcbiAgICBpZiAoYXV0aG9yaXNhdGlvbi5leHBpcmVzICE9PSBudWxsKSB7XG4gICAgICBwcm9ncmVzcy5zdHlsZS50cmFuc2l0aW9uRHVyYXRpb24gPSBgJHthdXRob3Jpc2F0aW9uLmV4cGlyZXMgLSBEYXRlLm5vdygpfW1zYDtcbiAgICAgIHZvaWQgcHJvZ3Jlc3Mub2Zmc2V0SGVpZ2h0OyAvLyAoZm9yY2UgYSByZWZsb3cpXG4gICAgICBwcm9ncmVzcy5jbGFzc0xpc3QuYWRkKCdoYy1wcm9ncmVzcy16ZXJvJyk7XG4gICAgfVxuICB9XG4gIC8vIERpc3BsYXkgdGhlIHJlc3VsdCBvZiBhIGZhaWxlZCBhdXRob3Jpc2F0aW9uXG4gIHNob3dGYWlsKGF1dGhvcmlzYXRpb24pIHtcbiAgICAvLyBEaXNwbGF5IHRoZSBlcnJvciBtZXNzYWdlXG4gICAgKDAsIF91dGlsc0RvbS5nZXRFbGVtZW50QnlJZCkoJ2hjLWNsaWVudC1mYWlsLW1lc3NhZ2UnKS50ZXh0Q29udGVudCA9IGF1dGhvcmlzYXRpb24ubWVzc2FnZTtcbiAgICAvLyBJbmRpY2F0ZSB3aGV0aGVyIHRoZSBhdXRob3Jpc2F0aW9uIGNhbiBiZSByZXRyaWVkXG4gICAgKDAsIF91dGlsc0RvbS5nZXRFbGVtZW50QnlJZCkoJ2hjLWNsaWVudC1mYWlsLXJldHJ5YWJsZScpLmhpZGRlbiA9ICFhdXRob3Jpc2F0aW9uLnJldHJ5YWJsZTtcbiAgICAoMCwgX3V0aWxzRG9tLmdldEVsZW1lbnRCeUlkKSgnaGMtY2xpZW50LWZhaWwtcmV0cnknKS5oaWRkZW4gPSAhYXV0aG9yaXNhdGlvbi5yZXRyeWFibGU7XG4gICAgKDAsIF91dGlsc0RvbS5nZXRFbGVtZW50QnlJZCkoJ2hjLWNsaWVudC1mYWlsLXJldHJ5Jykub25jbGljayA9ICgpID0+IHtcbiAgICAgIHRoaXMucmV0cnlBdXRob3Jpc2F0aW9uKCk7XG4gICAgfTtcbiAgICAvLyBBZGQgYW55IGhlbHAgdGhhdCBoYXMgYmVlbiBwcm92aWRlZFxuICAgIGlmIChhdXRob3Jpc2F0aW9uLmhlbHApIHtcbiAgICAgIC8vIFNldCB0ZXh0IGJsb2Nrc1xuICAgICAgY29uc3Qgc2V0VGV4dCA9IChpZCwgdGV4dCkgPT4ge1xuICAgICAgICAoMCwgX3V0aWxzRG9tLmdldEVsZW1lbnRCeUlkKShpZCkucmVwbGFjZUNoaWxkcmVuKC4uLnRleHQubWFwKHBhcmFncmFwaCA9PiAoMCwgX3V0aWxzRG9tLmNsb25lVGVtcGxhdGUpKCdoYy1jbGllbnQtZmFpbC1wYXJhZ3JhcGgnLCB7XG4gICAgICAgICAgcGFyYWdyYXBoXG4gICAgICAgIH0pKSk7XG4gICAgICB9O1xuICAgICAgc2V0VGV4dCgnaGMtY2xpZW50LWZhaWwtcHJlc2NyaXB0JywgYXV0aG9yaXNhdGlvbi5oZWxwLnByZXNjcmlwdCk7XG4gICAgICBzZXRUZXh0KCdoYy1jbGllbnQtZmFpbC1wb3N0c2NyaXB0JywgYXV0aG9yaXNhdGlvbi5oZWxwLnBvc3RzY3JpcHQpO1xuICAgICAgLy8gUHJvdmlkZSBhZGRpdGlvbmFsIGhlbHAgZm9yIGNyZWF0aW5nIG9yIG1vZGlmeWluZyB0aGUgYXBwbGljYXRpb25cbiAgICAgIGNvbnN0IHtcbiAgICAgICAgY2xpZW50XG4gICAgICB9ID0gYXV0aG9yaXNhdGlvbi5oZWxwO1xuICAgICAgY29uc3QgbGluayA9ICgwLCBfdXRpbHNEb20uZ2V0RWxlbWVudEJ5SWQpKCdoYy1jbGllbnQtZmFpbC11cmknKTtcbiAgICAgIGlmIChjbGllbnQpIHtcbiAgICAgICAgKDAsIF91dGlsc0RvbS5nZXRFbGVtZW50QnlJZCkoJ2hjLWNsaWVudC1mYWlsLWNsaWVudC1zZXR0aW5ncycpLnJlcGxhY2VDaGlsZHJlbiguLi5PYmplY3QuZW50cmllcyhjbGllbnQuc2V0dGluZ3MpLm1hcCgoW2tleSwgdmFsdWVdKSA9PiAoMCwgX3V0aWxzRG9tLmNsb25lVGVtcGxhdGUpKCdoYy1jbGllbnQtZmFpbC1jbGllbnQtc2V0dGluZycsIHtcbiAgICAgICAgICBrZXksXG4gICAgICAgICAgdmFsdWVcbiAgICAgICAgfSkpKTtcbiAgICAgICAgbGluay5zZXRBdHRyaWJ1dGUoJ2hyZWYnLCBjbGllbnQudXJpKTtcbiAgICAgICAgbGluay50ZXh0Q29udGVudCA9IGNsaWVudC5hY3Rpb24gPT09ICdjcmVhdGUnID8gJ0NyZWF0ZSBhcHBsaWNhdGlvbicgOiAnTW9kaWZ5IGFwcGxpY2F0aW9uJztcbiAgICAgICAgbGluay5oaWRkZW4gPSBmYWxzZTtcbiAgICAgICAgKDAsIF91dGlsc0RvbS5nZXRFbGVtZW50QnlJZCkoJ2hjLWNsaWVudC1mYWlsLWNsaWVudCcpLmhpZGRlbiA9IGZhbHNlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbGluay5oaWRkZW4gPSB0cnVlO1xuICAgICAgICAoMCwgX3V0aWxzRG9tLmdldEVsZW1lbnRCeUlkKSgnaGMtY2xpZW50LWZhaWwtY2xpZW50JykuaGlkZGVuID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIC8vIE1ha2UgdGhlIGRldGFpbHMgdmlzaWJsZVxuICAgICAgKDAsIF91dGlsc0RvbS5nZXRFbGVtZW50QnlJZCkoJ2hjLWNsaWVudC1mYWlsLWRldGFpbCcpLmhpZGRlbiA9IGZhbHNlO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBPdGhlcndpc2UgaGlkZSB0aGUgZGV0YWlsc1xuICAgICAgKDAsIF91dGlsc0RvbS5nZXRFbGVtZW50QnlJZCkoJ2hjLWNsaWVudC1mYWlsLXVyaScpLmhpZGRlbiA9IHRydWU7XG4gICAgICAoMCwgX3V0aWxzRG9tLmdldEVsZW1lbnRCeUlkKSgnaGMtY2xpZW50LWZhaWwtZGV0YWlsJykuaGlkZGVuID0gdHJ1ZTtcbiAgICB9XG4gICAgLy8gTWFrZSB0aGUgZmFpbHVyZSBtZXNzYWdlIHZpc2libGVcbiAgICB0aGlzLnNob3dQYW5lbCgnaGMtY2xpZW50LWZhaWwnKTtcbiAgfVxuICAvLyBUcmlnZ2VyIGF1dGhvcmlzYXRpb24gcmV0cnlcbiAgcmV0cnlBdXRob3Jpc2F0aW9uKCkge1xuICAgICgwLCBfbG9nRXJyb3IuZGV0YWNoZWQpKHRoaXMubG9nLCAnUmV0cnkgYXV0aG9yaXNhdGlvbicsIGFzeW5jICgpID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHRoaXMuaXBjLnJlcXVlc3QoJy9jbGllbnRpZC9yZXRyeScsIG51bGwpO1xuICAgICAgICB0aGlzLnNob3dUb2FzdCgnaW5mbycsICdSZXF1ZXN0aW5nIG5ldyBhdXRob3Jpc2F0aW9uIGNvZGUnKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBjb25zdCBtZXNzYWdlID0gZXJyIGluc3RhbmNlb2YgRXJyb3IgPyBlcnIubWVzc2FnZSA6IFN0cmluZyhlcnIpO1xuICAgICAgICB0aGlzLnNob3dUb2FzdCgnZXJyb3InLCBgVW5hYmxlIHRvIHJldHJ5IGF1dGhvcmlzYXRpb246ICR7bWVzc2FnZX1gKTtcbiAgICAgIH1cbiAgICB9KSgpO1xuICB9XG4gIC8vIFNob3cgdGhlIHNwZWNpZmllZCBlbGVtZW50IGFuZCBoaWRlIGFsbCBvdGhlcnNcbiAgc2hvd1BhbmVsKGlkU2hvdykge1xuICAgIGZvciAoY29uc3QgaWQgb2YgWydoYy1jbGllbnQtZmFpbCcsICdoYy1jbGllbnQtdXNlciddKSB7XG4gICAgICAoMCwgX3V0aWxzRG9tLmdldEVsZW1lbnRCeUlkKShpZCkuaGlkZGVuID0gaWQgIT09IGlkU2hvdztcbiAgICB9XG4gIH1cbiAgLy8gRGlzcGxheSBhIHRvYXN0IG5vdGlmaWNhdGlvblxuICBzaG93VG9hc3QobGV2ZWwsIG1lc3NhZ2UpIHtcbiAgICAvLyBBdm9pZCBkdXBsaWNhdGUgdG9hc3Qgbm90aWZpY2F0aW9uc1xuICAgIGNvbnN0IGtleSA9IGAke2xldmVsfSAtICR7bWVzc2FnZX1gO1xuICAgIGlmICh0aGlzLmxhc3RUb2FzdCA9PT0ga2V5KSByZXR1cm47XG4gICAgdGhpcy5sYXN0VG9hc3QgPSBrZXk7XG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBpZiAodGhpcy5sYXN0VG9hc3QgPT09IGtleSkgdGhpcy5sYXN0VG9hc3QgPSB1bmRlZmluZWQ7XG4gICAgfSwgVE9BU1RfREVEVVBfVElNRSk7XG4gICAgLy8gRGlzcGxheSB0aGUgdG9hc3Qgbm90aWZpY2F0aW9uXG4gICAgd2luZG93LmhvbWVicmlkZ2UudG9hc3RbbGV2ZWxdKG1lc3NhZ2UsICdIb21lIENvbm5lY3QgQ2xpZW50Jyk7XG4gIH1cbn1cbmV4cG9ydHMuQ2xpZW50Q2xpZW50SUQgPSBDbGllbnRDbGllbnRJRDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRhdGE6YXBwbGljYXRpb24vanNvbjtjaGFyc2V0PXV0Zi04O2Jhc2U2NCxleUoyWlhKemFXOXVJam96TENKdVlXMWxjeUk2V3lKZmRYUnBiSE1pTENKeVpYRjFhWEpsSWl3aVgzVjBhV3h6Ukc5dElpd2lYMnh2WjBWeWNtOXlJaXdpVkU5QlUxUmZSRVZFVlZCZlZFbE5SU0lzSWsxVElpd2lRMnhwWlc1MFEyeHBaVzUwU1VRaUxDSmpiMjV6ZEhKMVkzUnZjaUlzSW14dlp5SXNJbWx3WXlJc0ltOXVSWFpsYm5RaUxDSnpkR0YwZFhNaUxDSnZia05zYVdWdWRGTjBZWFIxY3lJc0luTmxkRU5zYVdWdWRDSXNJbU52Ym1acFp5SXNJbU5zYVdWdWRFTnZibVpwWnlJc0luQnlaWEJoY21WRGJHbGxiblJEYjI1bWFXY2lMQ0p5WlhGMVpYTjBJaXdpWlhKeUlpd2liV1Z6YzJGblpTSXNJa1Z5Y205eUlpd2lVM1J5YVc1bklpd2ljMmh2ZDFSdllYTjBJaXdpZFc1a1pXWnBibVZrSWl3aWMyaHZkMUJoYm1Wc0lpd2liMjVCY0hCc2FXRnVZMlZ6SWl3aVpHVmlkV2NpTENKcGJtTnNkV1JsY3lJc0ltTnNhV1Z1ZEdsa0lpd2lkR1Z6ZENJc0ltRndjR3hwWVc1alpYTWlMQ0poZFhSb2IzSnBjMkYwYVc5dUlpd2ljM1JoZEdVaUxDSnphRzkzVlhObGNrRjFkR2h2Y21sellYUnBiMjRpTENKemFHOTNSbUZwYkNJc0ltOXVSbUZwYkNJc0lteHBibXNpTENKblpYUkZiR1Z0Wlc1MFFubEpaQ0lzSW5ObGRFRjBkSEpwWW5WMFpTSXNJblZ5YVNJc0luTmxkRk5zYjNSVVpYaDBJaXdpWkc5amRXMWxiblFpTENKamIyUmxJaXdpYjI1amJHbGpheUlzSW5KbGRISjVRWFYwYUc5eWFYTmhkR2x2YmlJc0luQnliMmR5WlhOeklpd2lZMnhoYzNOTWFYTjBJaXdpY21WdGIzWmxJaXdpWlhod2FYSmxjeUlzSW5OMGVXeGxJaXdpZEhKaGJuTnBkR2x2YmtSMWNtRjBhVzl1SWl3aVJHRjBaU0lzSW01dmR5SXNJbTltWm5ObGRFaGxhV2RvZENJc0ltRmtaQ0lzSW5SbGVIUkRiMjUwWlc1MElpd2lhR2xrWkdWdUlpd2ljbVYwY25saFlteGxJaXdpYUdWc2NDSXNJbk5sZEZSbGVIUWlMQ0pwWkNJc0luUmxlSFFpTENKeVpYQnNZV05sUTJocGJHUnlaVzRpTENKdFlYQWlMQ0p3WVhKaFozSmhjR2dpTENKamJHOXVaVlJsYlhCc1lYUmxJaXdpY0hKbGMyTnlhWEIwSWl3aWNHOXpkSE5qY21sd2RDSXNJbU5zYVdWdWRDSXNJazlpYW1WamRDSXNJbVZ1ZEhKcFpYTWlMQ0p6WlhSMGFXNW5jeUlzSW10bGVTSXNJblpoYkhWbElpd2lZV04wYVc5dUlpd2laR1YwWVdOb1pXUWlMQ0pwWkZOb2IzY2lMQ0pzWlhabGJDSXNJbXhoYzNSVWIyRnpkQ0lzSW5ObGRGUnBiV1Z2ZFhRaUxDSjNhVzVrYjNjaUxDSm9iMjFsWW5KcFpHZGxJaXdpZEc5aGMzUWlMQ0psZUhCdmNuUnpJbDBzSW5OdmRYSmpaWE1pT2xzaUxpNHZMaTR2TGk0dmMzSmpMMmh2YldWaWNtbGtaMlV0ZFdrdmNIVmliR2xqTDJOc2FXVnVkQzFqYkdsbGJuUnBaQzUwY3lKZExDSnpiM1Z5WTJWelEyOXVkR1Z1ZENJNlcyNTFiR3hkTENKdFlYQndhVzVuY3lJNklqczdPenM3TzBGQlUwRXNTVUZCUVVFc1RVRkJRU3hIUVVGQlF5eFBRVUZCTzBGQlJVRXNTVUZCUVVNc1UwRkJRU3hIUVVGQlJDeFBRVUZCTzBGQlJVRXNTVUZCUVVVc1UwRkJRU3hIUVVGQlJpeFBRVUZCTzBGQllrRTdRVUZEUVRzN1FVRmpRVHRCUVVOQkxFMUJRVTFITEdkQ1FVRm5RaXhIUVVGSExFTkJRVU1zUjBGQlIwTXNVMEZCUlR0QlFVVXZRanRCUVVOTkxFMUJRVTlETEdOQlFXTTdSVUZaZGtJN1JVRkRRVU1zV1VGQmNVSkRMRWRCUVZjc1JVRkJWME1zUjBGQll6dEpRVUZ3UXl4TFFVRkJSQ3hIUVVGSExFZEJRVWhCTEVkQlFVYzdTVUZCYlVJc1MwRkJRVU1zUjBGQlJ5eEhRVUZJUVN4SFFVRkhPMGxCUXpGRExFbEJRVWtzUTBGQlEwRXNSMEZCUnl4RFFVRkRReXhQUVVGUExFTkJRVU1zVVVGQlVTeEZRVUZGUXl4TlFVRk5MRWxCUVVjN1RVRkJSeXhKUVVGSkxFTkJRVU5ETEdOQlFXTXNRMEZCUTBRc1RVRkJUU3hEUVVGRE8wbEJRVVVzUTBGQlF5eERRVUZETzBWQlF6RkZPMFZCUlVFN1JVRkRRU3hOUVVGTlJTeFRRVUZUUVN4RFFVRkRReXhOUVVFMlFqdEpRVU42UXl4TlFVRk5ReXhaUVVGWkxFZEJRVWNzU1VGQlNTeERRVUZEUXl4dFFrRkJiVUlzUTBGQlEwWXNUVUZCVFN4RFFVRkRPMGxCUTNKRUxFbEJRVWxETEZsQlFWa3NSVUZCUlR0TlFVTmtPMDFCUTBFc1NVRkJTU3hEUVVGRFFTeFpRVUZaTEVkQlFVZEJMRmxCUVZrN1RVRkRhRU1zU1VGQlNUdFJRVU5CTEUxQlFVMUtMRTFCUVUwc1IwRkJSeXhOUVVGTkxFbEJRVWtzUTBGQlEwWXNSMEZCUnl4RFFVRkRVU3hQUVVGUExFTkJRVU1zVjBGQlZ5eEZRVUZGUml4WlFVRlpMRU5CUVVNN1VVRkRhRVVzU1VGQlNTeERRVUZEU0N4alFVRmpMRU5CUVVORUxFMUJRVTBzUTBGQlF6dE5RVU12UWl4RFFVRkRMRU5CUVVNc1QwRkJUMDhzUjBGQlJ5eEZRVUZGTzFGQlExWXNUVUZCVFVNc1QwRkJUeXhIUVVGSFJDeEhRVUZITEZsQlFWbEZMRXRCUVVzc1IwRkJSMFlzUjBGQlJ5eERRVUZEUXl4UFFVRlBMRWRCUVVkRkxFMUJRVTBzUTBGQlEwZ3NSMEZCUnl4RFFVRkRPMUZCUTJoRkxFbEJRVWtzUTBGQlEwa3NVMEZCVXl4RFFVRkRMRTlCUVU4c1JVRkJSU3h0UTBGQmJVTklMRTlCUVU4c1JVRkJSU3hEUVVGRE8wMUJRM3BGTzBsQlEwb3NRMEZCUXl4TlFVRk5PMDFCUTBnN1RVRkRRU3hKUVVGSkxFTkJRVU5LTEZsQlFWa3NSMEZCUjFFc1UwRkJVenROUVVNM1FpeEpRVUZKTEVOQlFVTkRMRk5CUVZNc1JVRkJSVHROUVVOb1FpeEpRVUZKTEVOQlFVTkRMRmxCUVZrc1IwRkJSU3hEUVVGRk8wbEJRM3BDTzBWQlEwbzdSVUZGUVR0RlFVTkJWQ3h0UWtGQmJVSkJMRU5CUVVOR0xFMUJRVFpDTzBsQlF6ZERMRWxCUVVsQkxFMUJRVTBzUTBGQlExa3NTMEZCU3l4RlFVRkZReXhSUVVGUkxFTkJRVU1zYVVKQlFXbENMRU5CUVVNc1JVRkJSVHROUVVNelF6dE5RVU5CTEU5QlFVODdVVUZCUlN4SFFVRkhZaXhOUVVGTk8xRkJRVVZqTEZGQlFWRXNSVUZCUlR0TlFVRkZMRU5CUVd0Q08wbEJRM1JFTEVOQlFVTXNUVUZCVFN4SlFVRkpaQ3hOUVVGTkxFTkJRVU5qTEZGQlFWRXNTMEZCUzB3c1UwRkJVeXhKUVVGSkxHbENRVUZwUWl4RFFVRkRUU3hKUVVGSkxFTkJRVU5tTEUxQlFVMHNRMEZCUTJNc1VVRkJVU3hEUVVGRExFVkJRVVU3VFVGRGFrWTdUVUZEUVN4UFFVRlBaQ3hOUVVGelFqdEpRVU5xUXp0RlFVTktPMFZCUlVFN1JVRkRRVVlzWTBGQlkwRXNRMEZCUTBRc1RVRkJjMEk3U1VGRGFrTTdTVUZEUVN4SlFVRkpMRWxCUVVrc1EwRkJRMGtzV1VGQldTeEZRVUZGWVN4UlFVRlJMRXRCUVV0cVFpeE5RVUZOTEVOQlFVTnBRaXhSUVVGUkxFVkJRVVU3U1VGRmNrUTdTVUZEUVN4SlFVRkpMRU5CUVVOSUxGbEJRVmtzUjBGQlIyUXNUVUZCVFN4RFFVRkRiVUlzVlVGQlZTeERRVUZETzBsQlJYUkRPMGxCUTBFc1VVRkJVVzVDTEUxQlFVMHNRMEZCUTI5Q0xHRkJRV0VzUlVGQlJVTXNTMEZCU3p0TlFVTnVReXhMUVVGTExGTkJRVk03VVVGRFZpeEpRVUZKTEVOQlFVTldMRk5CUVZNc1EwRkJReXhUUVVGVExFVkJRVVVzZVVKQlFYbENMRU5CUVVNN1VVRkRjRVFzU1VGQlNTeERRVUZEUlN4VFFVRlRMRVZCUVVVN1VVRkRhRUk3VFVGRFNpeExRVUZMTEUxQlFVMDdVVUZEVUN4SlFVRkpMRU5CUVVOR0xGTkJRVk1zUTBGQlF5eE5RVUZOTEVWQlFVVXNOa0pCUVRaQ0xFTkJRVU03VVVGRGNrUXNTVUZCU1N4RFFVRkRWeXh4UWtGQmNVSXNRMEZCUTNSQ0xFMUJRVTBzUTBGQlEyOUNMR0ZCUVdFc1EwRkJRenRSUVVOb1JEdE5RVU5LTEV0QlFVc3NUVUZCVFR0UlFVTlFMRWxCUVVrc1EwRkJRMVFzVTBGQlV5eERRVUZETEU5QlFVOHNSVUZCUlN4elFrRkJjMElzUTBGQlF6dFJRVU12UXl4SlFVRkpMRU5CUVVOWkxGRkJRVkVzUTBGQlEzWkNMRTFCUVUwc1EwRkJRMjlDTEdGQlFXRXNRMEZCUXp0UlFVTnVReXhKUVVGSkxFTkJRVU5KTEUxQlFVMHNSMEZCUlN4RFFVRkZPMUZCUTJZN1RVRkRTaXhMUVVGTExFMUJRVTA3VFVGRFdEdFJRVU5KTEVsQlFVa3NRMEZCUTFnc1UwRkJVeXhGUVVGRk8wbEJRM0JDTzBWQlEwbzdSVUZGUVR0RlFVTkJVeXh4UWtGQmNVSkJMRU5CUVVOR0xHRkJRWE5ETzBsQlEzaEVPMGxCUTBFc1RVRkJUVXNzU1VGQlNTeEhRVUZITEVsQlFVRkRMSGRDUVVGakxFVkJRVU1zY1VKQlFYRkNMRU5CUVVNN1NVRkRiRVJFTEVsQlFVa3NRMEZCUTBVc1dVRkJXU3hEUVVGRExFMUJRVTBzUlVGQlJWQXNZVUZCWVN4RFFVRkRVU3hIUVVGSExFTkJRVU03U1VGRE5VTXNTVUZCUVVNc2NVSkJRVmNzUlVGQlEwTXNVVUZCVVN4RlFVRkZPMDFCUVVVc2NVSkJRWEZDTEVWQlFVVldMR0ZCUVdFc1EwRkJRMWM3U1VGQlNTeERRVUZGTEVOQlFVTTdTVUZGY0VVN1NVRkRRU3hKUVVGQlRDeDNRa0ZCWXl4RlFVRkRMSE5DUVVGelFpeERRVUZETEVOQlFVTk5MRTlCUVU4c1IwRkJSeXhOUVVGWE8wMUJRVWNzU1VGQlNTeERRVUZEUXl4clFrRkJhMElzUlVGQlJUdEpRVUZGTEVOQlFVTTdTVUZGTTBZN1NVRkRRU3hKUVVGSkxFTkJRVU53UWl4VFFVRlRMRU5CUVVNc1owSkJRV2RDTEVOQlFVTTdTVUZGYUVNN1NVRkRRU3hOUVVGTmNVSXNVVUZCVVN4SFFVRkhMRWxCUVVGU0xIZENRVUZqTEVWQlFVTXNlVUpCUVhsQ0xFTkJRVU03U1VGRE1VUlJMRkZCUVZFc1EwRkJRME1zVTBGQlV5eERRVUZEUXl4TlFVRk5MRU5CUVVNc2EwSkJRV3RDTEVOQlFVTTdTVUZETjBNc1NVRkJTV2hDTEdGQlFXRXNRMEZCUTJsQ0xFOUJRVThzUzBGQlN5eEpRVUZKTEVWQlFVVTdUVUZEYUVOSUxGRkJRVkVzUTBGQlEwa3NTMEZCU3l4RFFVRkRReXhyUWtGQmEwSXNSMEZCUnl4SFFVRkhia0lzWVVGQllTeERRVUZEYVVJc1QwRkJUeXhIUVVGSFJ5eEpRVUZKTEVOQlFVTkRMRWRCUVVjc1JVRkJSU3hKUVVGSk8wMUJRemRGTEV0QlFVdFFMRkZCUVZFc1EwRkJRMUVzV1VGQllTeERRVUZETEVOQlFVTTdUVUZETjBKU0xGRkJRVkVzUTBGQlEwTXNVMEZCVXl4RFFVRkRVU3hIUVVGSExFTkJRVU1zYTBKQlFXdENMRU5CUVVNN1NVRkRPVU03UlVGRFNqdEZRVVZCTzBWQlEwRndRaXhSUVVGUlFTeERRVUZEU0N4aFFVRjNRenRKUVVNM1F6dEpRVU5CTEVsQlFVRk5MSGRDUVVGakxFVkJRVU1zZDBKQlFYZENMRU5CUVVNc1EwRkJRMnRDTEZkQlFWY3NSMEZCUjNoQ0xHRkJRV0VzUTBGQlExb3NUMEZCVHp0SlFVVTFSVHRKUVVOQkxFbEJRVUZyUWl4M1FrRkJZeXhGUVVGRExEQkNRVUV3UWl4RFFVRkRMRU5CUVVOdFFpeE5RVUZOTEVkQlFVY3NRMEZCUTNwQ0xHRkJRV0VzUTBGQlF6QkNMRk5CUVZNN1NVRkROVVVzU1VGQlFYQkNMSGRDUVVGakxFVkJRVU1zYzBKQlFYTkNMRU5CUVVNc1EwRkJTMjFDTEUxQlFVMHNSMEZCUnl4RFFVRkRla0lzWVVGQllTeERRVUZETUVJc1UwRkJVenRKUVVNMVJTeEpRVUZCY0VJc2QwSkJRV01zUlVGQlF5eHpRa0ZCYzBJc1EwRkJReXhEUVVGRFRTeFBRVUZQTEVkQlFVY3NUVUZCVnp0TlFVRkhMRWxCUVVrc1EwRkJRME1zYTBKQlFXdENMRVZCUVVVN1NVRkJSU3hEUVVGRE8wbEJSVE5HTzBsQlEwRXNTVUZCU1dJc1lVRkJZU3hEUVVGRE1rSXNTVUZCU1N4RlFVRkZPMDFCUTNCQ08wMUJRMEVzVFVGQlRVTXNUMEZCVHl4SFFVRkhRU3hEUVVGRFF5eEZRVUZWTEVWQlFVVkRMRWxCUVdNc1MwRkJWVHRSUVVOcVJDeEpRVUZCZUVJc2QwSkJRV01zUlVGQlEzVkNMRVZCUVVVc1EwRkJReXhEUVVGRFJTeGxRVUZsTEVOQlFVTXNSMEZCUjBRc1NVRkJTU3hEUVVGRFJTeEhRVUZITEVOQlFVTkRMRk5CUVZNc1NVRkRjRVFzU1VGQlFVTXNkVUpCUVdFc1JVRkJReXd3UWtGQk1FSXNSVUZCUlR0VlFVRkZSRHRSUVVGVExFTkJRVVVzUTBGQlJTeERRVUZETEVOQlFVTTdUVUZEYmtVc1EwRkJRenROUVVORVRDeFBRVUZQTEVOQlFVTXNNRUpCUVRCQ0xFVkJRVWMxUWl4aFFVRmhMRU5CUVVNeVFpeEpRVUZKTEVOQlFVTlJMRk5CUVZNc1EwRkJRenROUVVOc1JWQXNUMEZCVHl4RFFVRkRMREpDUVVFeVFpeEZRVUZGTlVJc1lVRkJZU3hEUVVGRE1rSXNTVUZCU1N4RFFVRkRVeXhWUVVGVkxFTkJRVU03VFVGRmJrVTdUVUZEUVN4TlFVRk5PMUZCUVVWRE8wMUJRVTBzUTBGQlJTeEhRVUZIY2tNc1lVRkJZU3hEUVVGRE1rSXNTVUZCU1R0TlFVTnlReXhOUVVGTmRFSXNTVUZCU1N4SFFVRkhMRWxCUVVGRExIZENRVUZqTEVWQlFVTXNiMEpCUVc5Q0xFTkJRVU03VFVGRGFrUXNTVUZCU1N0Q0xFMUJRVTBzUlVGQlJUdFJRVU5TTEVsQlFVRXZRaXgzUWtGQll5eEZRVUZETEdkRFFVRm5ReXhEUVVGRExFTkJRVU41UWl4bFFVRmxMRU5CUXpWRUxFZEJRVWRQTEUxQlFVMHNRMEZCUTBNc1QwRkJUeXhEUVVGRFJpeE5RVUZOTEVOQlFVTkhMRkZCUVZFc1EwRkJReXhEUVVGRFVpeEhRVUZITEVOQlFVTXNRMEZCUXl4RFFVRkRVeXhIUVVGSExFVkJRVVZETEV0QlFVc3NRMEZCUXl4TFFVTm9SQ3hKUVVGQlVpeDFRa0ZCWVN4RlFVRkRMQ3RDUVVFclFpeEZRVUZGTzFWQlFVVlBMRWRCUVVjN1ZVRkJSVU03VVVGQlN5eERRVUZGTEVOQlFVTXNRMEZCUXl4RFFVRkRPMUZCUTNoRmNrTXNTVUZCU1N4RFFVRkRSU3haUVVGWkxFTkJRVU1zVFVGQlRTeEZRVUZGT0VJc1RVRkJUU3hEUVVGRE4wSXNSMEZCUnl4RFFVRkRPMUZCUTNKRFNDeEpRVUZKTEVOQlFVTnRRaXhYUVVGWExFZEJRVWRoTEUxQlFVMHNRMEZCUTAwc1RVRkJUU3hMUVVGTExGRkJRVkVzUjBGQlJ5eHZRa0ZCYjBJc1IwRkJSeXh2UWtGQmIwSTdVVUZETTBaMFF5eEpRVUZKTEVOQlFVTnZRaXhOUVVGTkxFZEJRVWNzUzBGQlN6dFJRVU51UWl4SlFVRkJia0lzZDBKQlFXTXNSVUZCUXl4MVFrRkJkVUlzUTBGQlF5eERRVUZEYlVJc1RVRkJUU3hIUVVGSExFdEJRVXM3VFVGRE1VUXNRMEZCUXl4TlFVRk5PMUZCUTBod1FpeEpRVUZKTEVOQlFVTnZRaXhOUVVGTkxFZEJRVWNzU1VGQlNUdFJRVU5zUWl4SlFVRkJia0lzZDBKQlFXTXNSVUZCUXl4MVFrRkJkVUlzUTBGQlF5eERRVUZEYlVJc1RVRkJUU3hIUVVGSExFbEJRVWs3VFVGRGVrUTdUVUZGUVR0TlFVTkJMRWxCUVVGdVFpeDNRa0ZCWXl4RlFVRkRMSFZDUVVGMVFpeERRVUZETEVOQlFVTnRRaXhOUVVGTkxFZEJRVWNzUzBGQlN6dEpRVU14UkN4RFFVRkRMRTFCUVUwN1RVRkRTRHROUVVOQkxFbEJRVUZ1UWl4M1FrRkJZeXhGUVVGRExHOUNRVUZ2UWl4RFFVRkRMRU5CUVVsdFFpeE5RVUZOTEVkQlFVY3NTVUZCU1R0TlFVTnlSQ3hKUVVGQmJrSXNkMEpCUVdNc1JVRkJReXgxUWtGQmRVSXNRMEZCUXl4RFFVRkRiVUlzVFVGQlRTeEhRVUZITEVsQlFVazdTVUZEZWtRN1NVRkZRVHRKUVVOQkxFbEJRVWtzUTBGQlEyaERMRk5CUVZNc1EwRkJReXhuUWtGQlowSXNRMEZCUXp0RlFVTndRenRGUVVWQk8wVkJRMEZ2UWl4clFrRkJhMEpCTEVOQlFVRTdTVUZEWkN4SlFVRkJLMElzYTBKQlFWRXNSVUZCUXl4SlFVRkpMRU5CUVVOdVJTeEhRVUZITEVWQlFVVXNjVUpCUVhGQ0xFVkJRVVVzV1VGQlZ6dE5RVU5xUkN4SlFVRkpPMUZCUTBFc1RVRkJUU3hKUVVGSkxFTkJRVU5ETEVkQlFVY3NRMEZCUTFFc1QwRkJUeXhEUVVGRExHbENRVUZwUWl4RlFVRkZMRWxCUVVrc1EwRkJRenRSUVVNdlF5eEpRVUZKTEVOQlFVTkxMRk5CUVZNc1EwRkJReXhOUVVGTkxFVkJRVVVzYlVOQlFXMURMRU5CUVVNN1RVRkRMMFFzUTBGQlF5eERRVUZETEU5QlFVOUtMRWRCUVVjc1JVRkJSVHRSUVVOV0xFMUJRVTFETEU5QlFVOHNSMEZCUjBRc1IwRkJSeXhaUVVGWlJTeExRVUZMTEVkQlFVZEdMRWRCUVVjc1EwRkJRME1zVDBGQlR5eEhRVUZIUlN4TlFVRk5MRU5CUVVOSUxFZEJRVWNzUTBGQlF6dFJRVU5vUlN4SlFVRkpMRU5CUVVOSkxGTkJRVk1zUTBGQlF5eFBRVUZQTEVWQlFVVXNhME5CUVd0RFNDeFBRVUZQTEVWQlFVVXNRMEZCUXp0TlFVTjRSVHRKUVVOS0xFTkJRVU1zUTBGQlF5eEZRVUZGTzBWQlExSTdSVUZGUVR0RlFVTkJTeXhUUVVGVFFTeERRVUZEYjBRc1RVRkJaVHRKUVVOeVFpeExRVUZMTEUxQlFVMW9RaXhGUVVGRkxFbEJRVWtzUTBGQlF5eG5Ra0ZCWjBJc1JVRkJSU3huUWtGQlowSXNRMEZCUXl4RlFVRkZPMDFCUTI1RUxFbEJRVUYyUWl4M1FrRkJZeXhGUVVGRGRVSXNSVUZCUlN4RFFVRkRMRU5CUVVOS0xFMUJRVTBzUjBGQlIwa3NSVUZCUlN4TFFVRkxaMElzVFVGQlRUdEpRVU0zUXp0RlFVTktPMFZCUlVFN1JVRkRRWFJFTEZOQlFWTkJMRU5CUVVOMVJDeExRVUZ4UXl4RlFVRkZNVVFzVDBGQlpUdEpRVU0xUkR0SlFVTkJMRTFCUVUxeFJDeEhRVUZITEVkQlFVY3NSMEZCUjBzc1MwRkJTeXhOUVVGTk1VUXNUMEZCVHl4RlFVRkZPMGxCUTI1RExFbEJRVWtzU1VGQlNTeERRVUZETWtRc1UwRkJVeXhMUVVGTFRpeEhRVUZITEVWQlFVVTdTVUZETlVJc1NVRkJTU3hEUVVGRFRTeFRRVUZUTEVkQlFVZE9MRWRCUVVjN1NVRkRjRUpQTEZWQlFWVXNRMEZCUXl4TlFVRkxPMDFCUTFvc1NVRkJTU3hKUVVGSkxFTkJRVU5FTEZOQlFWTXNTMEZCUzA0c1IwRkJSeXhGUVVGRkxFbEJRVWtzUTBGQlEwMHNVMEZCVXl4SFFVRkhka1FzVTBGQlV6dEpRVU14UkN4RFFVRkRMRVZCUVVWdVFpeG5Ra0ZCWjBJc1EwRkJRenRKUVVWd1FqdEpRVU5CTkVVc1RVRkJUU3hEUVVGRFF5eFZRVUZWTEVOQlFVTkRMRXRCUVVzc1EwRkJRMHdzUzBGQlN5eERRVUZETEVOQlFVTXhSQ3hQUVVGUExFVkJRVVVzY1VKQlFYRkNMRU5CUVVNN1JVRkRiRVU3TzBGQlEwaG5SU3hQUVVGQkxFTkJRVUUzUlN4alFVRkJMRWRCUVVGQkxHTkJRVUVpTENKcFoyNXZjbVZNYVhOMElqcGJYWDA9IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLkNsaWVudElQQyA9IHZvaWQgMDtcbnZhciBfbG9nRXJyb3IgPSByZXF1aXJlKFwiLi4vLi4vbG9nLWVycm9yLmpzXCIpO1xuLy8gSG9tZWJyaWRnZSBwbHVnaW4gZm9yIEhvbWUgQ29ubmVjdCBob21lIGFwcGxpYW5jZXNcbi8vIENvcHlyaWdodCDCqSAyMDIzLTIwMjYgQWxleGFuZGVyIFRob3VreWRpZGVzXG5cbi8vIENsaWVudC1zaWRlIElQQyBpbXBsZW1lbnRhdGlvblxuY2xhc3MgQ2xpZW50SVBDIHtcbiAgLy8gQ3JlYXRlIGEgbmV3IGNsaWVudCBJUEMgaW5zdGFuY2VcbiAgY29uc3RydWN0b3IobG9nKSB7XG4gICAgdGhpcy5sb2cgPSBsb2c7XG4gIH1cbiAgLy8gSXNzdWUgYSByZXF1ZXN0IHRvIHRoZSBzZXJ2ZXJcbiAgYXN5bmMgcmVxdWVzdChwYXRoLCBkYXRhKSB7XG4gICAgdHJ5IHtcbiAgICAgIHRoaXMubG9nLmRlYnVnKGByZXF1ZXN0KFwiJHtwYXRofVwiLCAlTylgLCBkYXRhKTtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHdpbmRvdy5ob21lYnJpZGdlLnJlcXVlc3QocGF0aCwgZGF0YSk7XG4gICAgICB0aGlzLmxvZy5kZWJ1ZyhgcmVxdWVzdChcIiR7cGF0aH1cIiwgJU8pID0+YCwgZGF0YSwgcmVzdWx0KTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICB0aGlzLmxvZy5lcnJvcihgcmVxdWVzdChcIiR7cGF0aH1cIiwgJU8pID0+YCwgZGF0YSwgZXJyKTtcbiAgICAgIHRocm93IGVycjtcbiAgICB9XG4gIH1cbiAgLy8gQWRkIGFuIGV2ZW50IGxpc3RlbmVyXG4gIG9uRXZlbnQoZXZlbnQsIGNhbGxiYWNrKSB7XG4gICAgd2luZG93LmhvbWVicmlkZ2UuYWRkRXZlbnRMaXN0ZW5lcihldmVudCwgKDAsIF9sb2dFcnJvci5kZXRhY2hlZCkodGhpcy5sb2csICdvbkV2ZW50JywgYXN5bmMgZXZ0ID0+IHtcbiAgICAgIGNvbnN0IGRhdGEgPSBldnQuZGF0YTtcbiAgICAgIGlmIChldmVudCAhPT0gJ2xvZycpIHRoaXMubG9nLmRlYnVnKGBvbkV2ZW50KFwiJHtldmVudH1cIikgPT4gY2FsbGJhY2tgLCBkYXRhKTtcbiAgICAgIGF3YWl0IGNhbGxiYWNrKGRhdGEpO1xuICAgIH0pKTtcbiAgfVxufVxuZXhwb3J0cy5DbGllbnRJUEMgPSBDbGllbnRJUEM7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldD11dGYtODtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnVZVzFsY3lJNld5SmZiRzluUlhKeWIzSWlMQ0p5WlhGMWFYSmxJaXdpUTJ4cFpXNTBTVkJESWl3aVkyOXVjM1J5ZFdOMGIzSWlMQ0pzYjJjaUxDSnlaWEYxWlhOMElpd2ljR0YwYUNJc0ltUmhkR0VpTENKa1pXSjFaeUlzSW5KbGMzVnNkQ0lzSW5kcGJtUnZkeUlzSW1odmJXVmljbWxrWjJVaUxDSmxjbklpTENKbGNuSnZjaUlzSW05dVJYWmxiblFpTENKbGRtVnVkQ0lzSW1OaGJHeGlZV05ySWl3aVlXUmtSWFpsYm5STWFYTjBaVzVsY2lJc0ltUmxkR0ZqYUdWa0lpd2laWFowSWl3aVpYaHdiM0owY3lKZExDSnpiM1Z5WTJWeklqcGJJaTR1THk0dUx5NHVMM055WXk5b2IyMWxZbkpwWkdkbExYVnBMM0IxWW14cFl5OWpiR2xsYm5RdGFYQmpMblJ6SWwwc0luTnZkWEpqWlhORGIyNTBaVzUwSWpwYmJuVnNiRjBzSW0xaGNIQnBibWR6SWpvaU96czdPenM3UVVGTlFTeEpRVUZCUVN4VFFVRkJMRWRCUVVGRExFOUJRVUU3UVVGT1FUdEJRVU5CT3p0QlFVOUJPMEZCUTAwc1RVRkJUME1zVTBGQlV6dEZRVVZzUWp0RlFVTkJReXhaUVVGeFFrTXNSMEZCVnp0SlFVRllMRXRCUVVGQkxFZEJRVWNzUjBGQlNFRXNSMEZCUnp0RlFVRlhPMFZCUlc1RE8wVkJRMEVzVFVGQlRVTXNUMEZCVDBFc1EwRkJNRUpETEVsQlFWVXNSVUZCUlVNc1NVRkJlVUk3U1VGRGVFVXNTVUZCU1R0TlFVTkJMRWxCUVVrc1EwRkJRMGdzUjBGQlJ5eERRVUZEU1N4TFFVRkxMRU5CUVVNc1dVRkJXVVlzU1VGQlNTeFJRVUZSTEVWQlFVVkRMRWxCUVVrc1EwRkJRenROUVVNNVF5eE5RVUZOUlN4TlFVRk5MRWRCUVZrc1RVRkJUVU1zVFVGQlRTeERRVUZEUXl4VlFVRlZMRU5CUVVOT0xFOUJRVThzUTBGQlEwTXNTVUZCU1N4RlFVRkZReXhKUVVGSkxFTkJRVU03VFVGRGJrVXNTVUZCU1N4RFFVRkRTQ3hIUVVGSExFTkJRVU5KTEV0QlFVc3NRMEZCUXl4WlFVRlpSaXhKUVVGSkxGZEJRVmNzUlVGQlJVTXNTVUZCU1N4RlFVRkZSU3hOUVVGTkxFTkJRVU03VFVGRGVrUXNUMEZCVDBFc1RVRkJPRUk3U1VGRGVrTXNRMEZCUXl4RFFVRkRMRTlCUVU5SExFZEJRVWNzUlVGQlJUdE5RVU5XTEVsQlFVa3NRMEZCUTFJc1IwRkJSeXhEUVVGRFV5eExRVUZMTEVOQlFVTXNXVUZCV1ZBc1NVRkJTU3hYUVVGWExFVkJRVVZETEVsQlFVa3NSVUZCUlVzc1IwRkJSeXhEUVVGRE8wMUJRM1JFTEUxQlFVMUJMRWRCUVVjN1NVRkRZanRGUVVOS08wVkJSVUU3UlVGRFFVVXNUMEZCVDBFc1EwRkJORUpETEV0QlFWa3NSVUZCUlVNc1VVRkJLMFE3U1VGRE5VZE9MRTFCUVUwc1EwRkJRME1zVlVGQlZTeERRVUZEVFN4blFrRkJaMElzUTBGQlEwWXNTMEZCU3l4RlFVRkZMRWxCUVVGSExHdENRVUZSTEVWQlFVTXNTVUZCU1N4RFFVRkRaQ3hIUVVGSExFVkJRVVVzVTBGQlV5eEZRVUZGTEUxQlFVOWxMRWRCUVVjc1NVRkJTVHROUVVOc1JpeE5RVUZOV2l4SlFVRkpMRWRCUVVsWkxFZEJRVzFFTEVOQlFVTmFMRWxCUVVrN1RVRkRkRVVzU1VGQlNWRXNTMEZCU3l4TFFVRkxMRXRCUVVzc1JVRkJSU3hKUVVGSkxFTkJRVU5ZTEVkQlFVY3NRMEZCUTBrc1MwRkJTeXhEUVVGRExGbEJRVmxQTEV0QlFVc3NaMEpCUVdkQ0xFVkJRVVZTTEVsQlFVa3NRMEZCUXp0TlFVTTFSU3hOUVVGTlV5eFJRVUZSTEVOQlFVTlVMRWxCUVVrc1EwRkJRenRKUVVONFFpeERRVUZETEVOQlFVTXNRMEZCUXp0RlFVTlFPenRCUVVOSVlTeFBRVUZCTEVOQlFVRnNRaXhUUVVGQkxFZEJRVUZCTEZOQlFVRWlMQ0pwWjI1dmNtVk1hWE4wSWpwYlhYMD0iLCJcInVzZSBzdHJpY3RcIjtcblxudmFyIF9sb2dnZXIgPSByZXF1aXJlKFwiLi9sb2dnZXIuanNcIik7XG52YXIgX2NvbmZpZyA9IHJlcXVpcmUoXCIuL2NvbmZpZy5qc1wiKTtcbnZhciBfY2FyZHMgPSByZXF1aXJlKFwiLi9jYXJkcy5qc1wiKTtcbnZhciBfY2xpZW50Q2xpZW50aWQgPSByZXF1aXJlKFwiLi9jbGllbnQtY2xpZW50aWQuanNcIik7XG52YXIgX2Zvcm1zID0gcmVxdWlyZShcIi4vZm9ybXMuanNcIik7XG52YXIgX2NsaWVudElwYyA9IHJlcXVpcmUoXCIuL2NsaWVudC1pcGMuanNcIik7XG52YXIgX2FwaVN0YXR1cyA9IHJlcXVpcmUoXCIuL2FwaS1zdGF0dXMuanNcIik7XG4vLyBIb21lYnJpZGdlIHBsdWdpbiBmb3IgSG9tZSBDb25uZWN0IGhvbWUgYXBwbGlhbmNlc1xuLy8gQ29weXJpZ2h0IMKpIDIwMjMtMjAyNiBBbGV4YW5kZXIgVGhvdWt5ZGlkZXNcblxuLy8gQSBIb21lYnJpZGdlIEhvbWVDb25uZWN0IGN1c3RvbSBVSSBjbGllbnRcbmNsYXNzIENsaWVudCB7XG4gIC8vIENyZWF0ZSBhIG5ldyBjdXN0b20gVUkgY2xpZW50XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIC8vIENyZWF0ZSBhIGxvY2FsIGxvZ2dlciBhbmQgSVBDIGNsaWVudFxuICAgIHRoaXMubG9nID0gbmV3IF9sb2dnZXIuQ2xpZW50TG9nZ2VyKCk7XG4gICAgdGhpcy5sb2cuZGVidWcoJ2hvbWVicmlkZ2UucGx1Z2luJywgd2luZG93LmhvbWVicmlkZ2UucGx1Z2luKTtcbiAgICB0aGlzLmlwYyA9IG5ldyBfY2xpZW50SXBjLkNsaWVudElQQyh0aGlzLmxvZyk7XG4gICAgLy8gV2FpdCBmb3IgdGhlIHNlcnZlciBiZWZvcmUgY29udGludWluZyBpbml0aWFsaXNhdGlvblxuICAgIHRoaXMuaXBjLm9uRXZlbnQoJ3JlYWR5JywgKCkgPT4ge1xuICAgICAgdGhpcy5zZXJ2ZXJSZWFkeSgpO1xuICAgIH0pO1xuICB9XG4gIC8vIFRoZSBzZXJ2ZXIgaXMgcmVhZHkgc28gZmluaXNoIGluaXRpYWxpc2luZyB0aGUgY2xpZW50XG4gIHNlcnZlclJlYWR5KCkge1xuICAgIC8vIFN0YXJ0IHJlY2VpdmluZyAoaW1wb3J0YW50KSBsb2cgbWVzc2FnZXMgZnJvbSB0aGUgc2VydmVyXG4gICAgdGhpcy5zZXJ2ZXJMb2cgPSBuZXcgX2xvZ2dlci5TZXJ2ZXJMb2dnZXIodGhpcy5pcGMsIFwid2FyblwiIC8qIExvZ0xldmVsLldBUk4gKi8pO1xuICAgIC8vIENyZWF0ZSBhbGwgb2YgdGhlIHJlcXVpcmVkIHJlc291cmNlc1xuICAgIGNvbnN0IGNvbmZpZyA9IG5ldyBfY29uZmlnLkNvbmZpZyh0aGlzLmxvZywgdGhpcy5pcGMpO1xuICAgIGNvbnN0IGZvcm1zID0gbmV3IF9mb3Jtcy5Gb3Jtcyh0aGlzLmxvZywgdGhpcy5pcGMsIGNvbmZpZyk7XG4gICAgY29uc3QgY2FyZHMgPSBuZXcgX2NhcmRzLkNhcmRzKHRoaXMubG9nKTtcbiAgICBjb25zdCBjbGllbnQgPSBuZXcgX2NsaWVudENsaWVudGlkLkNsaWVudENsaWVudElEKHRoaXMubG9nLCB0aGlzLmlwYyk7XG4gICAgbmV3IF9hcGlTdGF0dXMuQVBJU3RhdHVzKHRoaXMubG9nKTtcbiAgICAvLyBDcmVhdGUgY2FyZHMgZm9yIHRoZSBnbG9iYWwgc2V0dGluZ3MgYW5kIGVhY2ggYXZhaWxhYmxlIGFwcGxpYW5jZVxuICAgIGNhcmRzLnNldE5vbkFwcGxpYW5jZXMoW3tcbiAgICAgIGlkOiBfZm9ybXMuRm9ybUlkLkdsb2JhbCxcbiAgICAgIGljb246ICdnbG9iYWwnLFxuICAgICAgbmFtZTogJ0dlbmVyYWwgU2V0dGluZ3MnXG4gICAgfV0pO1xuICAgIGNsaWVudC5vbkFwcGxpYW5jZXMgPSBhcHBsaWFuY2VzID0+IHtcbiAgICAgIGNhcmRzLnNldEFwcGxpYW5jZXMoYXBwbGlhbmNlcyA/PyBbXSk7XG4gICAgfTtcbiAgICBjYXJkcy5vblNlbGVjdCA9IGlkID0+IHtcbiAgICAgIGZvcm1zLnNob3dGb3JtKGlkKTtcbiAgICB9O1xuICAgIC8vIEF0dGVtcHQgdG8gYXV0aG9yaXNlIGEgY2xpZW50IHdoZW4gdGhlIGNvbmZpZ3VyYXRpb24gY2hhbmdlc1xuICAgIGNvbmZpZy5vbkdsb2JhbCA9IGNvbmZpZyA9PiBjbGllbnQuc2V0Q2xpZW50KGNvbmZpZyk7XG4gICAgY2xpZW50Lm9uRmFpbCA9ICgpID0+IHtcbiAgICAgIGZvcm1zLnNob3dGb3JtKF9mb3Jtcy5Gb3JtSWQuR2xvYmFsKTtcbiAgICB9O1xuICB9XG59XG4vLyBDcmVhdGUgYSBjdXN0b20gVUkgY2xpZW50IGluc3RhbmNlXG5uZXcgQ2xpZW50KCk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldD11dGYtODtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnVZVzFsY3lJNld5SmZiRzluWjJWeUlpd2ljbVZ4ZFdseVpTSXNJbDlqYjI1bWFXY2lMQ0pmWTJGeVpITWlMQ0pmWTJ4cFpXNTBRMnhwWlc1MGFXUWlMQ0pmWm05eWJYTWlMQ0pmWTJ4cFpXNTBTWEJqSWl3aVgyRndhVk4wWVhSMWN5SXNJa05zYVdWdWRDSXNJbU52Ym5OMGNuVmpkRzl5SWl3aWJHOW5JaXdpUTJ4cFpXNTBURzluWjJWeUlpd2laR1ZpZFdjaUxDSjNhVzVrYjNjaUxDSm9iMjFsWW5KcFpHZGxJaXdpY0d4MVoybHVJaXdpYVhCaklpd2lRMnhwWlc1MFNWQkRJaXdpYjI1RmRtVnVkQ0lzSW5ObGNuWmxjbEpsWVdSNUlpd2ljMlZ5ZG1WeVRHOW5JaXdpVTJWeWRtVnlURzluWjJWeUlpd2lZMjl1Wm1sbklpd2lRMjl1Wm1sbklpd2labTl5YlhNaUxDSkdiM0p0Y3lJc0ltTmhjbVJ6SWl3aVEyRnlaSE1pTENKamJHbGxiblFpTENKRGJHbGxiblJEYkdsbGJuUkpSQ0lzSWtGUVNWTjBZWFIxY3lJc0luTmxkRTV2YmtGd2NHeHBZVzVqWlhNaUxDSnBaQ0lzSWtadmNtMUpaQ0lzSWtkc2IySmhiQ0lzSW1samIyNGlMQ0p1WVcxbElpd2liMjVCY0hCc2FXRnVZMlZ6SWl3aVlYQndiR2xoYm1ObGN5SXNJbk5sZEVGd2NHeHBZVzVqWlhNaUxDSnZibE5sYkdWamRDSXNJbk5vYjNkR2IzSnRJaXdpYjI1SGJHOWlZV3dpTENKelpYUkRiR2xsYm5RaUxDSnZia1poYVd3aVhTd2ljMjkxY21ObGN5STZXeUl1TGk4dUxpOHVMaTl6Y21NdmFHOXRaV0p5YVdSblpTMTFhUzl3ZFdKc2FXTXZZMnhwWlc1MExuUnpJbDBzSW5OdmRYSmpaWE5EYjI1MFpXNTBJanBiYm5Wc2JGMHNJbTFoY0hCcGJtZHpJam9pT3p0QlFVdEJMRWxCUVVGQkxFOUJRVUVzUjBGQlFVTXNUMEZCUVR0QlFVTkJMRWxCUVVGRExFOUJRVUVzUjBGQlFVUXNUMEZCUVR0QlFVTkJMRWxCUVVGRkxFMUJRVUVzUjBGQlFVWXNUMEZCUVR0QlFVTkJMRWxCUVVGSExHVkJRVUVzUjBGQlFVZ3NUMEZCUVR0QlFVTkJMRWxCUVVGSkxFMUJRVUVzUjBGQlFVb3NUMEZCUVR0QlFVTkJMRWxCUVVGTExGVkJRVUVzUjBGQlFVd3NUMEZCUVR0QlFVTkJMRWxCUVVGTkxGVkJRVUVzUjBGQlFVNHNUMEZCUVR0QlFWaEJPMEZCUTBFN08wRkJXVUU3UVVGRFFTeE5RVUZOVHl4TlFVRk5PMFZCVTFJN1JVRkRRVU1zV1VGQlFUdEpRVU5KTzBsQlEwRXNTVUZCU1N4RFFVRkRReXhIUVVGSExFZEJRVWNzU1VGQlNVTXNiMEpCUVZrc1JVRkJSVHRKUVVNM1FpeEpRVUZKTEVOQlFVTkVMRWRCUVVjc1EwRkJRMFVzUzBGQlN5eERRVUZETEcxQ1FVRnRRaXhGUVVGRlF5eE5RVUZOTEVOQlFVTkRMRlZCUVZVc1EwRkJRME1zVFVGQlRTeERRVUZETzBsQlF6ZEVMRWxCUVVrc1EwRkJRME1zUjBGQlJ5eEhRVUZITEVsQlFVbERMRzlDUVVGVExFTkJRVU1zU1VGQlNTeERRVUZEVUN4SFFVRkhMRU5CUVVNN1NVRkZiRU03U1VGRFFTeEpRVUZKTEVOQlFVTk5MRWRCUVVjc1EwRkJRMFVzVDBGQlR5eERRVUZETEU5QlFVOHNSVUZCUlN4TlFVRkxPMDFCUVVjc1NVRkJTU3hEUVVGRFF5eFhRVUZYTEVWQlFVVTdTVUZCUlN4RFFVRkRMRU5CUVVNN1JVRkROVVE3UlVGRlFUdEZRVU5CUVN4WFFVRlhRU3hEUVVGQk8wbEJRMUE3U1VGRFFTeEpRVUZKTEVOQlFVTkRMRk5CUVZNc1IwRkJSeXhKUVVGSlF5eHZRa0ZCV1N4RFFVRkRMRWxCUVVrc1EwRkJRMHdzUjBGQlJ5dzJRa0ZCWjBJN1NVRkZNVVE3U1VGRFFTeE5RVUZOVFN4TlFVRk5MRWRCUVVjc1NVRkJTVU1zWTBGQlRTeERRVUZETEVsQlFVa3NRMEZCUTJJc1IwRkJSeXhGUVVGRkxFbEJRVWtzUTBGQlEwMHNSMEZCUnl4RFFVRkRPMGxCUXpkRExFMUJRVTFSTEV0QlFVc3NSMEZCU1N4SlFVRkpReXhaUVVGTExFTkJRVU1zU1VGQlNTeERRVUZEWml4SFFVRkhMRVZCUVVVc1NVRkJTU3hEUVVGRFRTeEhRVUZITEVWQlFVVk5MRTFCUVUwc1EwRkJRenRKUVVOd1JDeE5RVUZOU1N4TFFVRkxMRWRCUVVrc1NVRkJTVU1zV1VGQlN5eERRVUZETEVsQlFVa3NRMEZCUTJwQ0xFZEJRVWNzUTBGQlF6dEpRVU5zUXl4TlFVRk5hMElzVFVGQlRTeEhRVUZITEVsQlFVbERMRGhDUVVGakxFTkJRVU1zU1VGQlNTeERRVUZEYmtJc1IwRkJSeXhGUVVGRkxFbEJRVWtzUTBGQlEwMHNSMEZCUnl4RFFVRkRPMGxCUTNKRUxFbEJRVWxqTEc5Q1FVRlRMRU5CUVVNc1NVRkJTU3hEUVVGRGNFSXNSMEZCUnl4RFFVRkRPMGxCUlhaQ08wbEJRMEZuUWl4TFFVRkxMRU5CUVVOTExHZENRVUZuUWl4RFFVRkRMRU5CUVVNN1RVRkJSVU1zUlVGQlJTeEZRVUZGUXl4aFFVRk5MRU5CUVVORExFMUJRVTA3VFVGQlJVTXNTVUZCU1N4RlFVRkZMRkZCUVZFN1RVRkJSVU1zU1VGQlNTeEZRVUZGTzBsQlFXdENMRU5CUVVVc1EwRkJReXhEUVVGRE8wbEJRM3BHVWl4TlFVRk5MRU5CUVVOVExGbEJRVmtzUjBGQlNVTXNWVUZCVlN4SlFVRlhPMDFCUVVkYUxFdEJRVXNzUTBGQlEyRXNZVUZCWVN4RFFVRkRSQ3hWUVVGVkxFbEJRVWtzUlVGQlJTeERRVUZETzBsQlFVVXNRMEZCUXp0SlFVTjJSbG9zUzBGQlN5eERRVUZEWXl4UlFVRlJMRWRCUVZOU0xFVkJRVmNzU1VGQlZUdE5RVUZIVWl4TFFVRkxMRU5CUVVOcFFpeFJRVUZSTEVOQlFVTlVMRVZCUVVVc1EwRkJRenRKUVVGRkxFTkJRVU03U1VGRmNFVTdTVUZEUVZZc1RVRkJUU3hEUVVGRGIwSXNVVUZCVVN4SFFVRkpjRUlzVFVGQlRTeEpRVUZ2UWswc1RVRkJUU3hEUVVGRFpTeFRRVUZUTEVOQlFVTnlRaXhOUVVGTkxFTkJRVU03U1VGRGNrVk5MRTFCUVUwc1EwRkJRMmRDTEUxQlFVMHNSMEZCU3l4TlFVRnBRanROUVVGSGNFSXNTMEZCU3l4RFFVRkRhVUlzVVVGQlVTeERRVUZEVWl4aFFVRk5MRU5CUVVORExFMUJRVTBzUTBGQlF6dEpRVUZGTEVOQlFVTTdSVUZETVVVN08wRkJSMG83UVVGRFFTeEpRVUZKTVVJc1RVRkJUU3hGUVVGRklpd2lhV2R1YjNKbFRHbHpkQ0k2VzExOSIsIlwidXNlIHN0cmljdFwiO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5Db25maWcgPSB2b2lkIDA7XG52YXIgX3V0aWxzID0gcmVxdWlyZShcIi4uLy4uL3V0aWxzLmpzXCIpO1xudmFyIF91dGlsc0RvbSA9IHJlcXVpcmUoXCIuL3V0aWxzLWRvbS5qc1wiKTtcbnZhciBfY29uZmlnVHlwZXMgPSByZXF1aXJlKFwiLi4vLi4vdGkvY29uZmlnLXR5cGVzLmpzXCIpO1xuLy8gSG9tZWJyaWRnZSBwbHVnaW4gZm9yIEhvbWUgQ29ubmVjdCBob21lIGFwcGxpYW5jZXNcbi8vIENvcHlyaWdodCDCqSAyMDIzLTIwMjYgQWxleGFuZGVyIFRob3VreWRpZGVzXG5cbi8vIFRoZSBjdXJyZW50IHBsdWdpbiBjb25maWd1cmF0aW9uXG5jbGFzcyBDb25maWcge1xuICAvLyBDcmVhdGUgYSBuZXcgY29uZmlndXJhdGlvbiBvYmplY3RcbiAgY29uc3RydWN0b3IobG9nLCBpcGMpIHtcbiAgICB0aGlzLmxvZyA9IGxvZztcbiAgICB0aGlzLmlwYyA9IGlwYztcbiAgICAvLyBUaGUgY29uZmlndXJhdGlvbiBiZWluZyBlZGl0ZWRcbiAgICB0aGlzLmdsb2JhbCA9IHt9O1xuICAgIHRoaXMuYXBwbGlhbmNlcyA9IHt9O1xuICAgIHRoaXMucmVhZHlQcm9taXNlID0gdGhpcy5nZXRDb25maWcoKTtcbiAgICB0aGlzLmFjdGl2ZVByb21pc2UgPSB0aGlzLmdldEFjdGl2ZUNvbmZpZygpO1xuICB9XG4gIC8vIFJldHJpZXZlIGFuZCBwYXJzZSB0aGUgY29uZmlndXJhdGlvbiB0byBiZSBlZGl0ZWRcbiAgYXN5bmMgZ2V0Q29uZmlnKCkge1xuICAgIC8vIFJldHJpZXZlIHRoZSBjdXJyZW50IHBsdWdpbiBjb25maWd1cmF0aW9uIChpZiBhbnkpXG4gICAgY29uc3QgY29uZmlnQXJyYXkgPSBhd2FpdCB3aW5kb3cuaG9tZWJyaWRnZS5nZXRQbHVnaW5Db25maWcoKTtcbiAgICBpZiAoY29uZmlnQXJyYXlbMF0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5sb2cud2FybignTm8gcGx1Z2luIGNvbmZpZ3VyYXRpb24gZm91bmQ7IGNyZWF0aW5nIGEgbmV3IG9uZScpO1xuICAgICAgdGhpcy5zYXZlZENvbmZpZyA9IHtcbiAgICAgICAgcGxhdGZvcm06IHdpbmRvdy5ob21lYnJpZGdlLnBsdWdpbi5kaXNwbGF5TmFtZVxuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKDEgPCBjb25maWdBcnJheS5sZW5ndGgpIHtcbiAgICAgICAgdGhpcy5sb2cuZXJyb3IoYFVzaW5nIHRoZSBmaXJzdCBvZiAkeygwLCBfdXRpbHMucGx1cmFsKShjb25maWdBcnJheS5sZW5ndGgsICdwbHVnaW4gY29uZmlndXJhdGlvbicpfWAsIGNvbmZpZ0FycmF5KTtcbiAgICAgICAgd2luZG93LmhvbWVicmlkZ2UudG9hc3QuZXJyb3IoJ09ubHkgYSBzaW5nbGUgcGxhdGZvcm0gaW5zdGFuY2UgaXMgc3VwcG9ydGVkOyB1c2luZyB0aGUgZmlyc3QnLCAnTXVsdGlwbGUgQ29uZmlndXJhdGlvbiBCbG9ja3MnKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuc2F2ZWRDb25maWcgPSBjb25maWdBcnJheVswXTtcbiAgICAgIGF3YWl0IHRoaXMuY2hlY2tJZk1vZGlmaWVkKHRoaXMuc2F2ZWRDb25maWcpO1xuICAgIH1cbiAgICAvLyBUcmVhdCBhbGwgdW5leHBlY3RlZCBwcm9wZXJ0aWVzIGFzIGFwcGxpYW5jZSBjb25maWd1cmF0aW9uc1xuICAgIGNvbnN0IGtleW9mQ29uZmlnUGx1Z2luID0gKDAsIF91dGlscy5rZXlvZkNoZWNrZXIpKF9jb25maWdUeXBlcy50eXBlU3VpdGUsIF9jb25maWdUeXBlcy50eXBlU3VpdGUuQ29uZmlnUGx1Z2luKTtcbiAgICBjb25zdCBzZWxlY3QgPSBwcmVkaWNhdGUgPT4gT2JqZWN0LmZyb21FbnRyaWVzKE9iamVjdC5lbnRyaWVzKHRoaXMuc2F2ZWRDb25maWcgPz8ge30pLmZpbHRlcihwcmVkaWNhdGUpKTtcbiAgICB0aGlzLmdsb2JhbCA9IHNlbGVjdCgoW2tleV0pID0+IGtleW9mQ29uZmlnUGx1Z2luLmluY2x1ZGVzKGtleSkpO1xuICAgIHRoaXMuYXBwbGlhbmNlcyA9IHNlbGVjdCgoW2tleV0pID0+ICFrZXlvZkNvbmZpZ1BsdWdpbi5pbmNsdWRlcyhrZXkpKTtcbiAgICB0aGlzLmxvZy5kZWJ1ZygnZ2V0Q29uZmlnKCkgZ2xvYmFsICVPIGFwcGxpYW5jZXMgJU8nLCB0aGlzLmdsb2JhbCwgdGhpcy5hcHBsaWFuY2VzKTtcbiAgICBhd2FpdCB0aGlzLm9uR2xvYmFsPy4odGhpcy5nbG9iYWwpO1xuICB9XG4gIC8vIFJldHJpZXZlIHRoZSBtb3N0IHJlY2VudGx5IHVzZWQgY29uZmlndXJhdGlvblxuICBhc3luYyBnZXRBY3RpdmVDb25maWcoKSB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLmlwYy5yZXF1ZXN0KCcvY29uZmlnJywgbnVsbCk7XG4gICAgfSBjYXRjaCB7XG4gICAgICByZXR1cm4ge307XG4gICAgfVxuICB9XG4gIC8vIFVwZGF0ZSB0aGUgaG9tZWJyaWRnZS11aS14IGNvcHkgb2YgdGhlIGNvbmZpZ3VyYXRpb25cbiAgYXN5bmMgcHV0Q29uZmlnKHNhdmUgPSBmYWxzZSkge1xuICAgIC8vIENvbnN0cnVjdCB0aGUgZnVsbCBjb25maWd1cmF0aW9uXG4gICAgY29uc3QgY29uZmlnID0ge1xuICAgICAgLi4udGhpcy5nbG9iYWwsXG4gICAgICAuLi50aGlzLmFwcGxpYW5jZXNcbiAgICB9O1xuICAgIHRoaXMubG9nLmRlYnVnKGBwdXRDb25maWcoJHtzYXZlfSknfWAsIGNvbmZpZyk7XG4gICAgLy8gSW5mb3JtIGhvbWVicmlkZ2UtdWkteCBvZiB0aGUgbmV3IGNvbmZpZ3VyYXRpb25cbiAgICBhd2FpdCB3aW5kb3cuaG9tZWJyaWRnZS51cGRhdGVQbHVnaW5Db25maWcoW2NvbmZpZ10pO1xuICAgIGlmIChzYXZlKSB7XG4gICAgICBhd2FpdCB3aW5kb3cuaG9tZWJyaWRnZS5zYXZlUGx1Z2luQ29uZmlnKCk7XG4gICAgICB0aGlzLnNhdmVkQ29uZmlnID0gY29uZmlnO1xuICAgICAgdGhpcy5sb2cuaW5mbygnUGx1Z2luIGNvbmZpZ3VyYXRpb24gc2F2ZWQnKTtcbiAgICB9XG4gICAgLy8gQ2hlY2sgd2hldGhlciB0aGUgY29uZmlndXJhdGlvbiBtYXRjaGVzIHRoZSBhY3RpdmUgcGx1Z2luXG4gICAgYXdhaXQgdGhpcy5jaGVja0lmTW9kaWZpZWQoY29uZmlnKTtcbiAgfVxuICAvLyBDb21wYXJlIHR3byBjb25maWd1cmF0aW9uIG9iamVjdHNcbiAgZGlmZk9iamVjdCh0bywgZnJvbSwga2V5UHJlZml4ID0gJycpIHtcbiAgICBjb25zdCBrZXlzID0gWy4uLk9iamVjdC5rZXlzKHRvKSwgLi4uT2JqZWN0LmtleXMoZnJvbSldLmZpbHRlcigoa2V5LCBpbmRleCwgc2VsZikgPT4gaW5kZXggPT09IHNlbGYuaW5kZXhPZihrZXkpICYmIGtleSAhPT0gJ19icmlkZ2UnKTtcbiAgICBjb25zdCBkaWZmID0gW107XG4gICAgZm9yIChjb25zdCBrZXkgb2Yga2V5cykge1xuICAgICAgY29uc3QgdmFsdWVUbyA9IHRvW2tleV07XG4gICAgICBjb25zdCB2YWx1ZUZyb20gPSBmcm9tW2tleV07XG4gICAgICBjb25zdCBrZXlOYW1lID0gYCR7a2V5UHJlZml4fS4ke2tleX1gO1xuICAgICAgY29uc3QgaXNPYmplY3QgPSB2YWx1ZSA9PiB2YWx1ZSAhPT0gdW5kZWZpbmVkICYmIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCc7XG4gICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZVRvKSAmJiBBcnJheS5pc0FycmF5KHZhbHVlRnJvbSkpIGRpZmYucHVzaCguLi50aGlzLmRpZmZBcnJheSh2YWx1ZVRvLCB2YWx1ZUZyb20sIGtleU5hbWUpKTtlbHNlIGlmIChpc09iamVjdCh2YWx1ZVRvKSAmJiBpc09iamVjdCh2YWx1ZUZyb20pKSBkaWZmLnB1c2goLi4udGhpcy5kaWZmT2JqZWN0KHZhbHVlVG8sIHZhbHVlRnJvbSwga2V5TmFtZSkpO2Vsc2UgaWYgKHZhbHVlVG8gIT09IHZhbHVlRnJvbSkgZGlmZi5wdXNoKHtcbiAgICAgICAga2V5OiBrZXlOYW1lLFxuICAgICAgICBmcm9tOiB2YWx1ZUZyb20sXG4gICAgICAgIHRvOiB2YWx1ZVRvXG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIGRpZmY7XG4gIH1cbiAgLy8gQ29tcGFyZSB0d28gY29uZmlndXJhdGlvbiBhcnJheXNcbiAgZGlmZkFycmF5KHRvLCBmcm9tLCBrZXlQcmVmaXggPSAnJykge1xuICAgIGNvbnN0IGlzU2ltcGxlID0gYXJyYXkgPT4gYXJyYXkubGVuZ3RoICE9PSAwICYmIHR5cGVvZiBhcnJheVswXSAhPT0gJ29iamVjdCc7XG4gICAgaWYgKGlzU2ltcGxlKHRvKSB8fCBpc1NpbXBsZShmcm9tKSkge1xuICAgICAgaWYgKHRvLmxlbmd0aCA9PT0gZnJvbS5sZW5ndGggJiYgdG8uZXZlcnkoKHZhbHVlLCBpbmRleCkgPT4gdmFsdWUgPT09IGZyb21baW5kZXhdKSkgcmV0dXJuIFtdO2Vsc2UgcmV0dXJuIFt7XG4gICAgICAgIGtleToga2V5UHJlZml4LFxuICAgICAgICBmcm9tLFxuICAgICAgICB0b1xuICAgICAgfV07XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0aGlzLmRpZmZPYmplY3QodG8sIGZyb20sIGtleVByZWZpeCk7XG4gICAgfVxuICB9XG4gIC8vIENoZWNrIHdoZXRoZXIgdGhlIGNvbmZpZ3VyYXRpb24gaGFzIGJlZW4gbW9kaWZpZWRcbiAgYXN5bmMgY2hlY2tJZk1vZGlmaWVkKGNvbmZpZykge1xuICAgIC8vIElnbm9yZSBjb21wbGV0ZWx5IG5ldy9lbXB0eSBjb25maWd1cmF0aW9uXG4gICAgaWYgKCFPYmplY3Qua2V5cyhjb25maWcpLmxlbmd0aCkgcmV0dXJuO1xuICAgIC8vIENvbXBhcmUgdGhlIGNvbmZpZ3VyYXRpb24gdG8gdGhlIGFjdGl2ZSBwbHVnaW4gYW5kIHNhdmVkIHZlcnNpb25zXG4gICAgY29uc3QgYWN0aXZlQ29uZmlnID0gYXdhaXQgdGhpcy5hY3RpdmVQcm9taXNlO1xuICAgIGNvbnN0IGFjdGl2ZURpZmYgPSB0aGlzLmRpZmZPYmplY3QoY29uZmlnLCBhY3RpdmVDb25maWcpO1xuICAgIGNvbnN0IHNhdmVkRGlmZiA9IHRoaXMuZGlmZk9iamVjdChjb25maWcsIHRoaXMuc2F2ZWRDb25maWcgPz8ge30pO1xuICAgIGlmIChhY3RpdmVEaWZmLmxlbmd0aCB8fCBzYXZlZERpZmYubGVuZ3RoKSB7XG4gICAgICB0aGlzLmxvZy5kZWJ1ZygnY2hlY2tJZk1vZGlmaWVkKCVPKSBhY3RpdmUgJU8gc2F2ZWQgJU8nLCBjb25maWcsIGFjdGl2ZURpZmYsIHNhdmVkRGlmZik7XG4gICAgfVxuICAgIC8vIEhpZGUgb3Igc2hvdyB0aGUgcmVzdGFydCByZXF1aXJlZCBtZXNzYWdlXG4gICAgdGhpcy5zaG93UmVzdGFydFJlcXVpcmVkKGFjdGl2ZURpZmYsIDAgPCBzYXZlZERpZmYubGVuZ3RoKTtcbiAgfVxuICAvLyBTaG93IG9yIGhpZGUgdGhlIHJlc3RhcnQgcmVxdWlyZWQgbWVzc2FnZVxuICBzaG93UmVzdGFydFJlcXVpcmVkKGNoYW5nZXMsIGlzVW5zYXZlZCkge1xuICAgIC8vIFNob3cgdGhlIG1lc3NhZ2UgaWYgdGhlcmUgYXJlIGFueSBkaWZmZXJlbmNlc1xuICAgICgwLCBfdXRpbHNEb20uZ2V0RWxlbWVudEJ5SWQpKCdoYy1tb2RpZmllZCcpLmhpZGRlbiA9IGNoYW5nZXMubGVuZ3RoID09PSAwICYmICFpc1Vuc2F2ZWQ7XG4gICAgKDAsIF91dGlsc0RvbS5nZXRFbGVtZW50QnlJZCkoJ2hjLW1vZGlmaWVkLXNhdmVkJykuaGlkZGVuID0gaXNVbnNhdmVkO1xuICAgICgwLCBfdXRpbHNEb20uZ2V0RWxlbWVudEJ5SWQpKCdoYy1tb2RpZmllZC11bnNhdmVkJykuaGlkZGVuID0gIWlzVW5zYXZlZDtcbiAgICAvLyBEaXNwbGF5IHRoZSBkaWZmXG4gICAgY29uc3QgZm9ybWF0VmFsdWUgPSB2YWx1ZSA9PiBKU09OLnN0cmluZ2lmeSh2YWx1ZSwgbnVsbCwgNCk7XG4gICAgKDAsIF91dGlsc0RvbS5nZXRFbGVtZW50QnlJZCkoJ2hjLW1vZGlmaWVkLWRpZmYnKS5yZXBsYWNlQ2hpbGRyZW4oLi4uY2hhbmdlcy5tYXAoY2hhbmdlID0+ICgwLCBfdXRpbHNEb20uY2xvbmVUZW1wbGF0ZSkoJ2hjLW1vZGlmaWVkLWRpZmYtZGVsdGEnLCB7XG4gICAgICBrZXk6IGNoYW5nZS5rZXksXG4gICAgICBmcm9tOiBmb3JtYXRWYWx1ZShjaGFuZ2UuZnJvbSksXG4gICAgICB0bzogZm9ybWF0VmFsdWUoY2hhbmdlLnRvKVxuICAgIH0pKSk7XG4gIH1cbiAgLy8gR2V0IHRoZSBjdXJyZW50IGdsb2JhbCBjb25maWd1cmF0aW9uXG4gIGFzeW5jIGdldEdsb2JhbCgpIHtcbiAgICBhd2FpdCB0aGlzLnJlYWR5UHJvbWlzZTtcbiAgICByZXR1cm4gdGhpcy5nbG9iYWw7XG4gIH1cbiAgLy8gU2V0IHVwZGF0ZWQgZ2xvYmFsIGNvbmZpZ3VyYXRpb25cbiAgYXN5bmMgc2V0R2xvYmFsKGNvbmZpZykge1xuICAgIGlmICh0aGlzLmRpZmZPYmplY3QoY29uZmlnLCBhd2FpdCB0aGlzLmdldEdsb2JhbCgpKS5sZW5ndGgpIHtcbiAgICAgIHRoaXMubG9nLmRlYnVnKCdzZXRHbG9iYWwoJU8pJywgY29uZmlnKTtcbiAgICAgIHRoaXMuZ2xvYmFsID0gY29uZmlnO1xuICAgICAgYXdhaXQgdGhpcy5vbkdsb2JhbD8uKGNvbmZpZyk7XG4gICAgICBhd2FpdCB0aGlzLnB1dENvbmZpZygpO1xuICAgIH1cbiAgfVxuICAvLyBHZXQgdGhlIGN1cnJlbnQgY29uZmlndXJhdGlvbiBmb3IgYSBzcGVjaWZpYyBhcHBsaWFuY2VcbiAgYXN5bmMgZ2V0QXBwbGlhbmNlKGhhaWQpIHtcbiAgICBhd2FpdCB0aGlzLnJlYWR5UHJvbWlzZTtcbiAgICByZXR1cm4gdGhpcy5hcHBsaWFuY2VzW2hhaWRdID8/IHt9O1xuICB9XG4gIC8vIFNldCB1cGRhdGVkIGdsb2JhbCBjb25maWd1cmF0aW9uXG4gIGFzeW5jIHNldEFwcGxpYW5jZShoYWlkLCBjb25maWcpIHtcbiAgICAvLyBQYXRjaC11cCB0aGUgcHJvZ3JhbXMgbGlzdCBiYXNlZCBvbiB0aGUgYWRkcHJvZ3JhbXMgc2V0dGluZ1xuICAgIHN3aXRjaCAoY29uZmlnLmFkZHByb2dyYW1zKSB7XG4gICAgICBjYXNlICdub25lJzpcbiAgICAgICAgY29uZmlnLnByb2dyYW1zID0gW107XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnYXV0byc6XG4gICAgICAgIGNvbmZpZy5wcm9ncmFtcyA9IHVuZGVmaW5lZDtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICAgIC8vIFVwZGF0ZSB0aGUgYXBwbGlhbmNlIGNvbmZpZ3VyYXRpb24gaWYgaXQgaGFzIGNoYW5nZWRcbiAgICBpZiAodGhpcy5kaWZmT2JqZWN0KGNvbmZpZywgYXdhaXQgdGhpcy5nZXRBcHBsaWFuY2UoaGFpZCkpLmxlbmd0aCkge1xuICAgICAgdGhpcy5sb2cuZGVidWcoYHNldEFwcGxpYW5jZShcIiR7aGFpZH1cIiwgJU8pYCwgY29uZmlnKTtcbiAgICAgIHRoaXMuYXBwbGlhbmNlc1toYWlkXSA9IGNvbmZpZztcbiAgICAgIGF3YWl0IHRoaXMucHV0Q29uZmlnKCk7XG4gICAgfVxuICB9XG59XG5leHBvcnRzLkNvbmZpZyA9IENvbmZpZztcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRhdGE6YXBwbGljYXRpb24vanNvbjtjaGFyc2V0PXV0Zi04O2Jhc2U2NCxleUoyWlhKemFXOXVJam96TENKdVlXMWxjeUk2V3lKZmRYUnBiSE1pTENKeVpYRjFhWEpsSWl3aVgzVjBhV3h6Ukc5dElpd2lYMk52Ym1acFoxUjVjR1Z6SWl3aVEyOXVabWxuSWl3aVkyOXVjM1J5ZFdOMGIzSWlMQ0pzYjJjaUxDSnBjR01pTENKbmJHOWlZV3dpTENKaGNIQnNhV0Z1WTJWeklpd2ljbVZoWkhsUWNtOXRhWE5sSWl3aVoyVjBRMjl1Wm1sbklpd2lZV04wYVhabFVISnZiV2x6WlNJc0ltZGxkRUZqZEdsMlpVTnZibVpwWnlJc0ltTnZibVpwWjBGeWNtRjVJaXdpZDJsdVpHOTNJaXdpYUc5dFpXSnlhV1JuWlNJc0ltZGxkRkJzZFdkcGJrTnZibVpwWnlJc0luVnVaR1ZtYVc1bFpDSXNJbmRoY200aUxDSnpZWFpsWkVOdmJtWnBaeUlzSW5Cc1lYUm1iM0p0SWl3aWNHeDFaMmx1SWl3aVpHbHpjR3hoZVU1aGJXVWlMQ0pzWlc1bmRHZ2lMQ0psY25KdmNpSXNJbkJzZFhKaGJDSXNJblJ2WVhOMElpd2lZMmhsWTJ0SlprMXZaR2xtYVdWa0lpd2lhMlY1YjJaRGIyNW1hV2RRYkhWbmFXNGlMQ0pyWlhsdlprTm9aV05yWlhJaUxDSjBlWEJsVTNWcGRHVWlMQ0pEYjI1bWFXZFFiSFZuYVc0aUxDSnpaV3hsWTNRaUxDSndjbVZrYVdOaGRHVWlMQ0pQWW1wbFkzUWlMQ0ptY205dFJXNTBjbWxsY3lJc0ltVnVkSEpwWlhNaUxDSm1hV3gwWlhJaUxDSnJaWGtpTENKcGJtTnNkV1JsY3lJc0ltUmxZblZuSWl3aWIyNUhiRzlpWVd3aUxDSnlaWEYxWlhOMElpd2ljSFYwUTI5dVptbG5JaXdpYzJGMlpTSXNJbU52Ym1acFp5SXNJblZ3WkdGMFpWQnNkV2RwYmtOdmJtWnBaeUlzSW5OaGRtVlFiSFZuYVc1RGIyNW1hV2NpTENKcGJtWnZJaXdpWkdsbVprOWlhbVZqZENJc0luUnZJaXdpWm5KdmJTSXNJbXRsZVZCeVpXWnBlQ0lzSW10bGVYTWlMQ0pwYm1SbGVDSXNJbk5sYkdZaUxDSnBibVJsZUU5bUlpd2laR2xtWmlJc0luWmhiSFZsVkc4aUxDSjJZV3gxWlVaeWIyMGlMQ0pyWlhsT1lXMWxJaXdpYVhOUFltcGxZM1FpTENKMllXeDFaU0lzSWtGeWNtRjVJaXdpYVhOQmNuSmhlU0lzSW5CMWMyZ2lMQ0prYVdabVFYSnlZWGtpTENKcGMxTnBiWEJzWlNJc0ltRnljbUY1SWl3aVpYWmxjbmtpTENKaFkzUnBkbVZEYjI1bWFXY2lMQ0poWTNScGRtVkVhV1ptSWl3aWMyRjJaV1JFYVdabUlpd2ljMmh2ZDFKbGMzUmhjblJTWlhGMWFYSmxaQ0lzSW1Ob1lXNW5aWE1pTENKcGMxVnVjMkYyWldRaUxDSm5aWFJGYkdWdFpXNTBRbmxKWkNJc0ltaHBaR1JsYmlJc0ltWnZjbTFoZEZaaGJIVmxJaXdpU2xOUFRpSXNJbk4wY21sdVoybG1lU0lzSW5KbGNHeGhZMlZEYUdsc1pISmxiaUlzSW0xaGNDSXNJbU5vWVc1blpTSXNJbU5zYjI1bFZHVnRjR3hoZEdVaUxDSm5aWFJIYkc5aVlXd2lMQ0p6WlhSSGJHOWlZV3dpTENKblpYUkJjSEJzYVdGdVkyVWlMQ0pvWVdsa0lpd2ljMlYwUVhCd2JHbGhibU5sSWl3aVlXUmtjSEp2WjNKaGJYTWlMQ0p3Y205bmNtRnRjeUlzSW1WNGNHOXlkSE1pWFN3aWMyOTFjbU5sY3lJNld5SXVMaTh1TGk4dUxpOXpjbU12YUc5dFpXSnlhV1JuWlMxMWFTOXdkV0pzYVdNdlkyOXVabWxuTG5SeklsMHNJbk52ZFhKalpYTkRiMjUwWlc1MElqcGJiblZzYkYwc0ltMWhjSEJwYm1keklqb2lPenM3T3pzN1FVRlBRU3hKUVVGQlFTeE5RVUZCTEVkQlFVRkRMRTlCUVVFN1FVRkZRU3hKUVVGQlF5eFRRVUZCTEVkQlFVRkVMRTlCUVVFN1FVRkRRU3hKUVVGQlJTeFpRVUZCTEVkQlFVRkdMRTlCUVVFN1FVRldRVHRCUVVOQk96dEJRV3RDUVR0QlFVTk5MRTFCUVU5SExFMUJRVTA3UlVGalpqdEZRVU5CUXl4WlFVRnhRa01zUjBGQlZ5eEZRVU5ZUXl4SFFVRmpPMGxCUkdRc1MwRkJRVVFzUjBGQlJ5eEhRVUZJUVN4SFFVRkhPMGxCUTBnc1MwRkJRVU1zUjBGQlJ5eEhRVUZJUVN4SFFVRkhPMGxCV0hoQ08wbEJRMEVzUzBGQlFVTXNUVUZCVFN4SFFVRnJReXhGUVVGRk8wbEJRekZETEV0QlFVRkRMRlZCUVZVc1IwRkJlVUlzUlVGQlJUdEpRVlZxUXl4SlFVRkpMRU5CUVVORExGbEJRVmtzUjBGQlNTeEpRVUZKTEVOQlFVTkRMRk5CUVZNc1JVRkJSVHRKUVVOeVF5eEpRVUZKTEVOQlFVTkRMR0ZCUVdFc1IwRkJSeXhKUVVGSkxFTkJRVU5ETEdWQlFXVXNSVUZCUlR0RlFVTXZRenRGUVVWQk8wVkJRMEVzVFVGQlRVWXNVMEZCVTBFc1EwRkJRVHRKUVVOWU8wbEJRMEVzVFVGQlRVY3NWMEZCVnl4SFFVRkhMRTFCUVUxRExFMUJRVTBzUTBGQlEwTXNWVUZCVlN4RFFVRkRReXhsUVVGbExFVkJRVVU3U1VGRE4wUXNTVUZCU1Vnc1YwRkJWeXhEUVVGRExFTkJRVU1zUTBGQlF5eExRVUZMU1N4VFFVRlRMRVZCUVVVN1RVRkRPVUlzU1VGQlNTeERRVUZEV2l4SFFVRkhMRU5CUVVOaExFbEJRVWtzUTBGQlF5eHRSRUZCYlVRc1EwRkJRenROUVVOc1JTeEpRVUZKTEVOQlFVTkRMRmRCUVZjc1IwRkJSenRSUVVGRlF5eFJRVUZSTEVWQlFVVk9MRTFCUVUwc1EwRkJRME1zVlVGQlZTeERRVUZEVFN4TlFVRk5MRU5CUVVORE8wMUJRVmNzUTBGQlJUdEpRVU42UlN4RFFVRkRMRTFCUVUwN1RVRkRTQ3hKUVVGSkxFTkJRVU1zUjBGQlIxUXNWMEZCVnl4RFFVRkRWU3hOUVVGTkxFVkJRVVU3VVVGRGVFSXNTVUZCU1N4RFFVRkRiRUlzUjBGQlJ5eERRVUZEYlVJc1MwRkJTeXhEUVVGRExITkNRVUZ6UWl4SlFVRkJReXhoUVVGTkxFVkJRVU5hTEZkQlFWY3NRMEZCUTFVc1RVRkJUU3hGUVVGRkxITkNRVUZ6UWl4RFFVRkRMRVZCUVVVc1JVRkJSVllzVjBGQlZ5eERRVUZETzFGQlEzWkhReXhOUVVGTkxFTkJRVU5ETEZWQlFWVXNRMEZCUTFjc1MwRkJTeXhEUVVGRFJpeExRVUZMTEVOQlFVTXNLMFJCUVN0RUxFVkJReTlFTEN0Q1FVRXJRaXhEUVVGRE8wMUJRMnhGTzAxQlEwRXNTVUZCU1N4RFFVRkRUQ3hYUVVGWExFZEJRVWRPTEZkQlFWY3NRMEZCUXl4RFFVRkRMRU5CUVVNN1RVRkRha01zVFVGQlRTeEpRVUZKTEVOQlFVTmpMR1ZCUVdVc1EwRkJReXhKUVVGSkxFTkJRVU5TTEZkQlFWY3NRMEZCUXp0SlFVTm9SRHRKUVVWQk8wbEJRMEVzVFVGQlRWTXNhVUpCUVdsQ0xFZEJRVWNzU1VGQlFVTXNiVUpCUVZrc1JVRkJRME1zYzBKQlFWTXNSVUZCUlVFc2MwSkJRVk1zUTBGQlEwTXNXVUZCV1N4RFFVRkRPMGxCUTNwRkxFMUJRVTFETEUxQlFVMHNSMEZCU1VNc1UwRkJkVVFzU1VGRGJrVkRMRTFCUVUwc1EwRkJRME1zVjBGQlZ5eERRVUZEUkN4TlFVRk5MRU5CUVVORkxFOUJRVThzUTBGQlF5eEpRVUZKTEVOQlFVTnFRaXhYUVVGWExFbEJRVWtzUlVGQlJTeERRVUZETEVOQlFVTnJRaXhOUVVGTkxFTkJRVU5LTEZOQlFWTXNRMEZCUXl4RFFVRkRPMGxCUTJoR0xFbEJRVWtzUTBGQlF6RkNMRTFCUVUwc1IwRkJUM2xDTEUxQlFVMHNRMEZCUXl4RFFVRkRMRU5CUVVOTkxFZEJRVWNzUTBGQlF5eExRVUZOVml4cFFrRkJhVUlzUTBGQlExY3NVVUZCVVN4RFFVRkRSQ3hIUVVGSExFTkJRVU1zUTBGQlF6dEpRVU55UlN4SlFVRkpMRU5CUVVNNVFpeFZRVUZWTEVkQlFVZDNRaXhOUVVGTkxFTkJRVU1zUTBGQlF5eERRVUZEVFN4SFFVRkhMRU5CUVVNc1MwRkJTeXhEUVVGRFZpeHBRa0ZCYVVJc1EwRkJRMWNzVVVGQlVTeERRVUZEUkN4SFFVRkhMRU5CUVVNc1EwRkJjVUk3U1VGRGVrWXNTVUZCU1N4RFFVRkRha01zUjBGQlJ5eERRVUZEYlVNc1MwRkJTeXhEUVVGRExIRkRRVUZ4UXl4RlFVRkZMRWxCUVVrc1EwRkJRMnBETEUxQlFVMHNSVUZCUlN4SlFVRkpMRU5CUVVORExGVkJRVlVzUTBGQlF6dEpRVU51Uml4TlFVRk5MRWxCUVVrc1EwRkJRMmxETEZGQlFWRXNSMEZCUnl4SlFVRkpMRU5CUVVOc1F5eE5RVUZOTEVOQlFVTTdSVUZEZEVNN1JVRkZRVHRGUVVOQkxFMUJRVTFMTEdWQlFXVkJMRU5CUVVFN1NVRkRha0lzU1VGQlNUdE5RVU5CTEU5QlFVOHNUVUZCVFN4SlFVRkpMRU5CUVVOT0xFZEJRVWNzUTBGQlEyOURMRTlCUVU4c1EwRkJReXhUUVVGVExFVkJRVVVzU1VGQlNTeERRVUZETzBsQlEyeEVMRU5CUVVNc1EwRkJReXhOUVVGTk8wMUJRMG9zVDBGQlR5eEZRVUZ2UWp0SlFVTXZRanRGUVVOS08wVkJSVUU3UlVGRFFTeE5RVUZOUXl4VFFVRlRRU3hEUVVGRFF5eEpRVUZKTEVkQlFVY3NTMEZCU3p0SlFVTjRRanRKUVVOQkxFMUJRVTFETEUxQlFVMHNSMEZCUnp0TlFVRkZMRWRCUVVjc1NVRkJTU3hEUVVGRGRFTXNUVUZCVFR0TlFVRkZMRWRCUVVjc1NVRkJTU3hEUVVGRFF6dEpRVUZWTEVOQlFVVTdTVUZEY2tRc1NVRkJTU3hEUVVGRFNDeEhRVUZITEVOQlFVTnRReXhMUVVGTExFTkJRVU1zWVVGQllVa3NTVUZCU1N4TFFVRkxMRVZCUVVWRExFMUJRVTBzUTBGQlF6dEpRVVU1UXp0SlFVTkJMRTFCUVUwdlFpeE5RVUZOTEVOQlFVTkRMRlZCUVZVc1EwRkJReXRDTEd0Q1FVRnJRaXhEUVVGRExFTkJRVU5FTEUxQlFVMHNRMEZCUXl4RFFVRkRPMGxCUTNCRUxFbEJRVWxFTEVsQlFVa3NSVUZCUlR0TlFVTk9MRTFCUVUwNVFpeE5RVUZOTEVOQlFVTkRMRlZCUVZVc1EwRkJRMmRETEdkQ1FVRm5RaXhGUVVGRk8wMUJRekZETEVsQlFVa3NRMEZCUXpWQ0xGZEJRVmNzUjBGQlJ6QkNMRTFCUVUwN1RVRkRla0lzU1VGQlNTeERRVUZEZUVNc1IwRkJSeXhEUVVGRE1rTXNTVUZCU1N4RFFVRkRMRFJDUVVFMFFpeERRVUZETzBsQlF5OURPMGxCUlVFN1NVRkRRU3hOUVVGTkxFbEJRVWtzUTBGQlEzSkNMR1ZCUVdVc1EwRkJRMnRDTEUxQlFVMHNRMEZCUXp0RlFVTjBRenRGUVVWQk8wVkJRMEZKTEZWQlFWVkJMRU5CUVVORExFVkJRVlVzUlVGQlJVTXNTVUZCV1N4RlFVRkZReXhUUVVGVExFZEJRVWNzUlVGQlJUdEpRVU12UXl4TlFVRk5ReXhKUVVGSkxFZEJRVWNzUTBGQlF5eEhRVUZIYmtJc1RVRkJUU3hEUVVGRGJVSXNTVUZCU1N4RFFVRkRTQ3hGUVVGRkxFTkJRVU1zUlVGQlJTeEhRVUZIYUVJc1RVRkJUU3hEUVVGRGJVSXNTVUZCU1N4RFFVRkRSaXhKUVVGSkxFTkJRVU1zUTBGQlF5eERRVU5zUkdRc1RVRkJUU3hEUVVGRExFTkJRVU5ETEVkQlFVY3NSVUZCUldkQ0xFdEJRVXNzUlVGQlJVTXNTVUZCU1N4TFFVRkxSQ3hMUVVGTExFdEJRVXRETEVsQlFVa3NRMEZCUTBNc1QwRkJUeXhEUVVGRGJFSXNSMEZCUnl4RFFVRkRMRWxCUVVsQkxFZEJRVWNzUzBGQlN5eFRRVUZUTEVOQlFVTTdTVUZEYmtZc1RVRkJUVzFDTEVsQlFVa3NSMEZCYTBJc1JVRkJSVHRKUVVNNVFpeExRVUZMTEUxQlFVMXVRaXhIUVVGSExFbEJRVWxsTEVsQlFVa3NSVUZCUlR0TlFVTndRaXhOUVVGTlN5eFBRVUZQTEVkQlFVdFNMRVZCUVVVc1EwRkJSMW9zUjBGQldTeERRVUZETzAxQlEzQkRMRTFCUVUxeFFpeFRRVUZUTEVkQlFVZFNMRWxCUVVrc1EwRkJRMklzUjBGQldTeERRVUZETzAxQlEzQkRMRTFCUVUxelFpeFBRVUZQTEVkQlFVY3NSMEZCUjFJc1UwRkJVeXhKUVVGSlpDeEhRVUZITEVWQlFVVTdUVUZEY2tNc1RVRkJUWFZDTEZGQlFWRXNSMEZCU1VNc1MwRkJZeXhKUVVGalFTeExRVUZMTEV0QlFVczNReXhUUVVGVExFbEJRVWtzVDBGQlR6WkRMRXRCUVVzc1MwRkJTeXhSUVVGUk8wMUJRemxHTEVsQlFVbERMRXRCUVVzc1EwRkJRME1zVDBGQlR5eERRVUZEVGl4UFFVRlBMRU5CUVVNc1NVRkJTVXNzUzBGQlN5eERRVUZEUXl4UFFVRlBMRU5CUVVOTUxGTkJRVk1zUTBGQlF5eEZRVUZGUml4SlFVRkpMRU5CUVVOUkxFbEJRVWtzUTBGQlF5eEhRVUZITEVsQlFVa3NRMEZCUTBNc1UwRkJVeXhEUVVGRlVpeFBRVUZQTEVWQlFVVkRMRk5CUVZNc1JVRkJSVU1zVDBGQlR5eERRVUZETEVOQlFVTXNRMEZCUXl4TFFVTTVSeXhKUVVGSlF5eFJRVUZSTEVOQlFVTklMRTlCUVU4c1EwRkJReXhKUVVGSlJ5eFJRVUZSTEVOQlFVTkdMRk5CUVZNc1EwRkJReXhGUVVGUFJpeEpRVUZKTEVOQlFVTlJMRWxCUVVrc1EwRkJReXhIUVVGSExFbEJRVWtzUTBGQlEyaENMRlZCUVZVc1EwRkJRMU1zVDBGQlR5eEZRVUZGUXl4VFFVRlRMRVZCUVVWRExFOUJRVThzUTBGQlF5eERRVUZETEVOQlFVTXNTMEZET1Vjc1NVRkJTVVlzVDBGQlR5eExRVUZMUXl4VFFVRlRMRVZCUVVWR0xFbEJRVWtzUTBGQlExRXNTVUZCU1N4RFFVRkRPMUZCUVVVelFpeEhRVUZITEVWQlFVVnpRaXhQUVVGUE8xRkJRVVZVTEVsQlFVa3NSVUZCUlZFc1UwRkJVenRSUVVGRlZDeEZRVUZGTEVWQlFVVlJPMDFCUVU4c1EwRkJSU3hEUVVGRE8wbEJRemRHTzBsQlEwRXNUMEZCVDBRc1NVRkJTVHRGUVVObU8wVkJSVUU3UlVGRFFWTXNVMEZCVTBFc1EwRkJRMmhDTEVWQlFXRXNSVUZCUlVNc1NVRkJaU3hGUVVGRlF5eFRRVUZUTEVkQlFVY3NSVUZCUlR0SlFVTndSQ3hOUVVGTlpTeFJRVUZSTEVkQlFVbERMRXRCUVdkQ0xFbEJRV05CTEV0QlFVc3NRMEZCUXpkRExFMUJRVTBzUzBGQlN5eERRVUZETEVsQlFVa3NUMEZCVHpaRExFdEJRVXNzUTBGQlF5eERRVUZETEVOQlFVTXNTMEZCU3l4UlFVRlJPMGxCUTJ4SExFbEJRVWxFTEZGQlFWRXNRMEZCUTJwQ0xFVkJRVVVzUTBGQlF5eEpRVUZKYVVJc1VVRkJVU3hEUVVGRGFFSXNTVUZCU1N4RFFVRkRMRVZCUVVVN1RVRkRhRU1zU1VGQlNVUXNSVUZCUlN4RFFVRkRNMElzVFVGQlRTeExRVUZMTkVJc1NVRkJTU3hEUVVGRE5VSXNUVUZCVFN4SlFVRkpNa0lzUlVGQlJTeERRVUZEYlVJc1MwRkJTeXhEUVVGRExFTkJRVU5RTEV0QlFVc3NSVUZCUlZJc1MwRkJTeXhMUVVGTFVTeExRVUZMTEV0QlFVdFlMRWxCUVVrc1EwRkJRMGNzUzBGQlN5eERRVUZETEVOQlFVTXNSVUZCUlN4UFFVRlBMRVZCUVVVc1EwRkJReXhMUVVONlJpeFBRVUZQTEVOQlFVTTdVVUZCUldoQ0xFZEJRVWNzUlVGQlJXTXNVMEZCVXp0UlFVRkZSQ3hKUVVGSk8xRkJRVVZFTzAxQlFVVXNRMEZCUlN4RFFVRkRPMGxCUXpsRExFTkJRVU1zVFVGQlRUdE5RVU5JTEU5QlFVOHNTVUZCU1N4RFFVRkRSQ3hWUVVGVkxFTkJRVU5ETEVWQlFVVXNSVUZCUlVNc1NVRkJTU3hGUVVGRlF5eFRRVUZUTEVOQlFVTTdTVUZETDBNN1JVRkRTanRGUVVWQk8wVkJRMEVzVFVGQlRYcENMR1ZCUVdWQkxFTkJRVU5yUWl4TlFVRnZRanRKUVVOMFF6dEpRVU5CTEVsQlFVa3NRMEZCUTFnc1RVRkJUU3hEUVVGRGJVSXNTVUZCU1N4RFFVRkRVaXhOUVVGTkxFTkJRVU1zUTBGQlEzUkNMRTFCUVUwc1JVRkJSVHRKUVVWcVF6dEpRVU5CTEUxQlFVMHJReXhaUVVGWkxFZEJRVWNzVFVGQlRTeEpRVUZKTEVOQlFVTXpSQ3hoUVVGaE8wbEJRemRETEUxQlFVMDBSQ3hWUVVGVkxFZEJRVWNzU1VGQlNTeERRVUZEZEVJc1ZVRkJWU3hEUVVGRFNpeE5RVUZOTEVWQlFVVjVRaXhaUVVGWkxFTkJRVU03U1VGRGVFUXNUVUZCVFVVc1UwRkJVeXhIUVVGSExFbEJRVWtzUTBGQlEzWkNMRlZCUVZVc1EwRkJRMG9zVFVGQlRTeEZRVUZGTEVsQlFVa3NRMEZCUXpGQ0xGZEJRVmNzU1VGQlNTeEZRVUZGTEVOQlFVTTdTVUZEYWtVc1NVRkJTVzlFTEZWQlFWVXNRMEZCUTJoRUxFMUJRVTBzU1VGQlNXbEVMRk5CUVZNc1EwRkJRMnBFTEUxQlFVMHNSVUZCUlR0TlFVTjJReXhKUVVGSkxFTkJRVU5zUWl4SFFVRkhMRU5CUVVOdFF5eExRVUZMTEVOQlFVTXNkME5CUVhkRExFVkJRVVZMTEUxQlFVMHNSVUZCUlRCQ0xGVkJRVlVzUlVGQlJVTXNVMEZCVXl4RFFVRkRPMGxCUXpOR08wbEJSVUU3U1VGRFFTeEpRVUZKTEVOQlFVTkRMRzFDUVVGdFFpeERRVUZEUml4VlFVRlZMRVZCUVVVc1EwRkJReXhIUVVGSFF5eFRRVUZUTEVOQlFVTnFSQ3hOUVVGTkxFTkJRVU03UlVGRE9VUTdSVUZGUVR0RlFVTkJhMFFzYlVKQlFXMUNRU3hEUVVGRFF5eFBRVUZ4UWl4RlFVRkZReXhUUVVGclFqdEpRVU42UkR0SlFVTkJMRWxCUVVGRExIZENRVUZqTEVWQlFVTXNZVUZCWVN4RFFVRkRMRU5CUVVORExFMUJRVTBzUjBGQlIwZ3NUMEZCVHl4RFFVRkRia1FzVFVGQlRTeExRVUZMTEVOQlFVTXNTVUZCU1N4RFFVRkRiMFFzVTBGQlV6dEpRVU42UlN4SlFVRkJReXgzUWtGQll5eEZRVUZETEcxQ1FVRnRRaXhEUVVGRExFTkJRVWRETEUxQlFVMHNSMEZCUjBZc1UwRkJVenRKUVVONFJDeEpRVUZCUXl4M1FrRkJZeXhGUVVGRExIRkNRVUZ4UWl4RFFVRkRMRU5CUVVORExFMUJRVTBzUjBGQlJ5eERRVUZEUml4VFFVRlRPMGxCUlhwRU8wbEJRMEVzVFVGQlRVY3NWMEZCVnl4SFFVRkphRUlzUzBGQll5eEpRVUZoYVVJc1NVRkJTU3hEUVVGRFF5eFRRVUZUTEVOQlFVTnNRaXhMUVVGTExFVkJRVVVzU1VGQlNTeEZRVUZGTEVOQlFVTXNRMEZCUXp0SlFVTTVSU3hKUVVGQll5eDNRa0ZCWXl4RlFVRkRMR3RDUVVGclFpeERRVUZETEVOQlFVTkxMR1ZCUVdVc1EwRkJReXhIUVVGSFVDeFBRVUZQTEVOQlFVTlJMRWRCUVVjc1EwRkJRME1zVFVGQlRTeEpRVU53UlN4SlFVRkJReXgxUWtGQllTeEZRVUZETEhkQ1FVRjNRaXhGUVVGRk8wMUJRM0JET1VNc1IwRkJSeXhGUVVGTE5rTXNUVUZCVFN4RFFVRkROME1zUjBGQlJ6dE5RVU5zUW1Fc1NVRkJTU3hGUVVGSk1rSXNWMEZCVnl4RFFVRkRTeXhOUVVGTkxFTkJRVU5vUXl4SlFVRkpMRU5CUVVNN1RVRkRhRU5FTEVWQlFVVXNSVUZCVFRSQ0xGZEJRVmNzUTBGQlEwc3NUVUZCVFN4RFFVRkRha01zUlVGQlJUdExRVU5vUXl4RFFVRkRMRU5CUVVNc1EwRkJRenRGUVVOYU8wVkJSVUU3UlVGRFFTeE5RVUZOYlVNc1UwRkJVMEVzUTBGQlFUdEpRVU5ZTEUxQlFVMHNTVUZCU1N4RFFVRkROVVVzV1VGQldUdEpRVU4yUWl4UFFVRlBMRWxCUVVrc1EwRkJRMFlzVFVGQlRUdEZRVU4wUWp0RlFVVkJPMFZCUTBFc1RVRkJUU3RGTEZOQlFWTkJMRU5CUVVONlF5eE5RVUZ2UWp0SlFVTm9ReXhKUVVGSkxFbEJRVWtzUTBGQlEwa3NWVUZCVlN4RFFVRkRTaXhOUVVGTkxFVkJRVVVzVFVGQlRTeEpRVUZKTEVOQlFVTjNReXhUUVVGVExFVkJRVVVzUTBGQlF5eERRVUZET1VRc1RVRkJUU3hGUVVGRk8wMUJRM2hFTEVsQlFVa3NRMEZCUTJ4Q0xFZEJRVWNzUTBGQlEyMURMRXRCUVVzc1EwRkJReXhsUVVGbExFVkJRVVZMTEUxQlFVMHNRMEZCUXp0TlFVTjJReXhKUVVGSkxFTkJRVU4wUXl4TlFVRk5MRWRCUVVkelF5eE5RVUZOTzAxQlEzQkNMRTFCUVUwc1NVRkJTU3hEUVVGRFNpeFJRVUZSTEVkQlFVZEpMRTFCUVUwc1EwRkJRenROUVVNM1FpeE5RVUZOTEVsQlFVa3NRMEZCUTBZc1UwRkJVeXhGUVVGRk8wbEJRekZDTzBWQlEwbzdSVUZGUVR0RlFVTkJMRTFCUVUwMFF5eFpRVUZaUVN4RFFVRkRReXhKUVVGWk8wbEJRek5DTEUxQlFVMHNTVUZCU1N4RFFVRkRMMFVzV1VGQldUdEpRVU4yUWl4UFFVRlBMRWxCUVVrc1EwRkJRMFFzVlVGQlZTeERRVUZEWjBZc1NVRkJTU3hEUVVGRExFbEJRVWtzUlVGQlJUdEZRVU4wUXp0RlFVVkJPMFZCUTBFc1RVRkJUVU1zV1VGQldVRXNRMEZCUTBRc1NVRkJXU3hGUVVGRk0wTXNUVUZCZFVJN1NVRkRjRVE3U1VGRFFTeFJRVUZSUVN4TlFVRk5MRU5CUVVNMlF5eFhRVUZYTzAxQlF6RkNMRXRCUVVzc1RVRkJUVHRSUVVGRk4wTXNUVUZCVFN4RFFVRkRPRU1zVVVGQlVTeEhRVUZITEVWQlFVVTdVVUZCVnp0TlFVTTFReXhMUVVGTExFMUJRVTA3VVVGQlJUbERMRTFCUVUwc1EwRkJRemhETEZGQlFWRXNSMEZCUnpGRkxGTkJRVk03VVVGQlNUdEpRVU0xUXp0SlFVVkJPMGxCUTBFc1NVRkJTU3hKUVVGSkxFTkJRVU5uUXl4VlFVRlZMRU5CUVVOS0xFMUJRVTBzUlVGQlJTeE5RVUZOTEVsQlFVa3NRMEZCUXpCRExGbEJRVmtzUTBGQlEwTXNTVUZCU1N4RFFVRkRMRU5CUVVNc1EwRkJRMnBGTEUxQlFVMHNSVUZCUlR0TlFVTXZSQ3hKUVVGSkxFTkJRVU5zUWl4SFFVRkhMRU5CUVVOdFF5eExRVUZMTEVOQlFVTXNhVUpCUVdsQ1owUXNTVUZCU1N4UlFVRlJMRVZCUVVVelF5eE5RVUZOTEVOQlFVTTdUVUZEY2tRc1NVRkJTU3hEUVVGRGNrTXNWVUZCVlN4RFFVRkRaMFlzU1VGQlNTeERRVUZETEVkQlFVY3pReXhOUVVGTk8wMUJRemxDTEUxQlFVMHNTVUZCU1N4RFFVRkRSaXhUUVVGVExFVkJRVVU3U1VGRE1VSTdSVUZEU2pzN1FVRkRTR2xFTEU5QlFVRXNRMEZCUVhwR0xFMUJRVUVzUjBGQlFVRXNUVUZCUVNJc0ltbG5ibTl5WlV4cGMzUWlPbHRkZlE9PSIsIlwidXNlIHN0cmljdFwiO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5UZW1wbGF0ZUZvcm0gPSBleHBvcnRzLkdsb2JhbEZvcm0gPSBleHBvcnRzLkZvcm1zID0gZXhwb3J0cy5Gb3JtSWQgPSBleHBvcnRzLkZvcm0gPSBleHBvcnRzLkFwcGxpYW5jZUZvcm0gPSB2b2lkIDA7XG52YXIgX3V0aWxzRG9tID0gcmVxdWlyZShcIi4vdXRpbHMtZG9tLmpzXCIpO1xudmFyIF9sb2dFcnJvciA9IHJlcXVpcmUoXCIuLi8uLi9sb2ctZXJyb3IuanNcIik7XG4vLyBIb21lYnJpZGdlIHBsdWdpbiBmb3IgSG9tZSBDb25uZWN0IGhvbWUgYXBwbGlhbmNlc1xuLy8gQ29weXJpZ2h0IMKpIDIwMjMtMjAyNiBBbGV4YW5kZXIgVGhvdWt5ZGlkZXNcblxuLy8gQSBjb25maWd1cmF0aW9uIGZvcm0gaGFuZGxlclxuY2xhc3MgRm9ybSB7XG4gIC8vIENyZWF0ZSBhIGNvbmZpZ3VyYXRpb24gZm9ybVxuICBjb25zdHJ1Y3Rvcihsb2cpIHtcbiAgICB0aGlzLmxvZyA9IGxvZztcbiAgfVxuICAvLyBSZXRyaWV2ZSBhbmQgZGlzcGxheSB0aGUgZm9ybVxuICBhc3luYyBjcmVhdGVGb3JtKCkge1xuICAgIC8vIFJldHJpZXZlIHRoZSBmb3JtIHNjaGVtYSBhbmQgZGF0YVxuICAgIGNvbnN0IHNjaGVtYSA9IGF3YWl0IHRoaXMuZ2V0U2NoZW1hKCk7XG4gICAgY29uc3QgZGF0YSA9IGF3YWl0IHRoaXMuZ2V0RGF0YSgpO1xuICAgIC8vIENyZWF0ZSB0aGUgZm9ybSAoYWRkaW5nIGhlYWRlciBhbmQgZm9vdGVyKVxuICAgIGNvbnN0IHBhdGNoZWRTY2hlbWEgPSB0aGlzLnBhdGNoU2NoZW1hKHNjaGVtYSk7XG4gICAgdGhpcy5sb2cuZGVidWcoJ2NyZWF0ZUZvcm0nLCBwYXRjaGVkU2NoZW1hLCBkYXRhKTtcbiAgICB0aGlzLmZvcm0gPSB3aW5kb3cuaG9tZWJyaWRnZS5jcmVhdGVGb3JtKHBhdGNoZWRTY2hlbWEsIGRhdGEpO1xuICAgIC8vIFJldHVybiBhbnkgY2hhbmdlcyB0byB0aGUgY29uZmlndXJhdGlvblxuICAgIHRoaXMuZm9ybS5vbkNoYW5nZShjb25maWcgPT4gdGhpcy5wdXREYXRhKGNvbmZpZykpO1xuICB9XG4gIC8vIEhpZGUgdGhlIGZvcm0gKGltcGxpY2l0bHkgY2FsbGVkIGlmIGEgZGlmZmVyZW50IGZvcm0gaXMgY3JlYXRlZClcbiAgZGVzdHJveUZvcm0oKSB7XG4gICAgdGhpcy5mb3JtPy5lbmQoKTtcbiAgICB0aGlzLmZvcm0gPSB1bmRlZmluZWQ7XG4gIH1cbiAgLy8gQWRkIGEgaGVhZGVyIGFuZCBmb290ZXIgdG8gdGhlIHNjaGVtYSBmb3JtXG4gIHBhdGNoU2NoZW1hKHNjaGVtYSkge1xuICAgIGNvbnN0IGZvcm0gPSBbLi4uKHNjaGVtYS5mb3JtID8/IFtdKSwgLi4udGhpcy5mb3JtRnJvbVRlbXBsYXRlKCdoYy1mb3JtLWZvb3RlcicpXTtcbiAgICByZXR1cm4ge1xuICAgICAgLi4uc2NoZW1hLFxuICAgICAgZm9ybVxuICAgIH07XG4gIH1cbiAgLy8gQ3JlYXRlIGEgZm9ybSBpdGVtIGZyb20gYSB0ZW1wbGF0ZVxuICBmb3JtRnJvbVRlbXBsYXRlKC4uLmFyZ3MpIHtcbiAgICBjb25zdCB0ZW1wbGF0ZSA9ICgwLCBfdXRpbHNEb20uY2xvbmVUZW1wbGF0ZSkoLi4uYXJncyk7XG4gICAgY29uc3QgYWJzVGVtcGxhdGUgPSAoMCwgX3V0aWxzRG9tLmVsZW1lbnRXaXRoQWJzb2x1dGVQYXRocykodGVtcGxhdGUpO1xuICAgIHJldHVybiB0aGlzLmZvcm1Gcm9tSFRNTChhYnNUZW1wbGF0ZSk7XG4gIH1cbiAgLy8gQ3JlYXRlIGEgZm9ybSBpdGVtIGZyb20gYW4gSFRNTCBlbGVtZW50XG4gIGZvcm1Gcm9tSFRNTChlbGVtZW50KSB7XG4gICAgcmV0dXJuIFt7XG4gICAgICB0eXBlOiAnaGVscCcsXG4gICAgICBoZWxwdmFsdWU6ICgwLCBfdXRpbHNEb20uZ2V0SFRNTCkoZWxlbWVudClcbiAgICB9XTtcbiAgfVxufVxuLy8gQSBnbG9iYWwgY29uZmlndXJhdGlvbiBmb3JtIGhhbmRsZXJcbmV4cG9ydHMuRm9ybSA9IEZvcm07XG5jbGFzcyBHbG9iYWxGb3JtIGV4dGVuZHMgRm9ybSB7XG4gIGNvbnN0cnVjdG9yKGxvZywgaXBjLCBjb25maWcpIHtcbiAgICBzdXBlcihsb2cpO1xuICAgIHRoaXMuaXBjID0gaXBjO1xuICAgIHRoaXMuY29uZmlnID0gY29uZmlnO1xuICB9XG4gIGdldFNjaGVtYSgpIHtcbiAgICByZXR1cm4gdGhpcy5pcGMucmVxdWVzdCgnL3NjaGVtYS9nbG9iYWwnLCBudWxsKTtcbiAgfVxuICBnZXREYXRhKCkge1xuICAgIHJldHVybiB0aGlzLmNvbmZpZy5nZXRHbG9iYWwoKTtcbiAgfVxuICBwdXREYXRhKGRhdGEpIHtcbiAgICByZXR1cm4gdGhpcy5jb25maWcuc2V0R2xvYmFsKGRhdGEpO1xuICB9XG59XG4vLyBBbiBjb25maWd1cmF0aW9uIGZvcm0gaGFuZGxlciBmb3IgYSBzcGVjaWZpYyBhcHBsaWFuY2VcbmV4cG9ydHMuR2xvYmFsRm9ybSA9IEdsb2JhbEZvcm07XG5jbGFzcyBBcHBsaWFuY2VGb3JtIGV4dGVuZHMgRm9ybSB7XG4gIGNvbnN0cnVjdG9yKGxvZywgaXBjLCBjb25maWcsIGhhaWQpIHtcbiAgICBzdXBlcihsb2cpO1xuICAgIHRoaXMuaXBjID0gaXBjO1xuICAgIHRoaXMuY29uZmlnID0gY29uZmlnO1xuICAgIHRoaXMuaGFpZCA9IGhhaWQ7XG4gIH1cbiAgZ2V0U2NoZW1hKCkge1xuICAgIHJldHVybiB0aGlzLmlwYy5yZXF1ZXN0KCcvc2NoZW1hL2FwcGxpYW5jZScsIHRoaXMuaGFpZCk7XG4gIH1cbiAgZ2V0RGF0YSgpIHtcbiAgICByZXR1cm4gdGhpcy5jb25maWcuZ2V0QXBwbGlhbmNlKHRoaXMuaGFpZCk7XG4gIH1cbiAgcHV0RGF0YShkYXRhKSB7XG4gICAgcmV0dXJuIHRoaXMuY29uZmlnLnNldEFwcGxpYW5jZSh0aGlzLmhhaWQsIGRhdGEpO1xuICB9XG59XG4vLyBBIHBsYWNlaG9sZGVyIGZvcm0gaGFuZGxlclxuZXhwb3J0cy5BcHBsaWFuY2VGb3JtID0gQXBwbGlhbmNlRm9ybTtcbmNsYXNzIFRlbXBsYXRlRm9ybSBleHRlbmRzIEZvcm0ge1xuICBjb25zdHJ1Y3Rvcihsb2csIC4uLmFyZ3MpIHtcbiAgICBzdXBlcihsb2cpO1xuICAgIHRoaXMuZWxlbWVudEFzRm9ybSA9IHRoaXMuZm9ybUZyb21UZW1wbGF0ZSguLi5hcmdzKTtcbiAgfVxuICAvLyBDcmVhdGUgYSBwbGFjZWhvbGRlciBzY2hlbWEgdXNpbmcgdGhlIHNwZWNpZmllZCBIVE1MIGVsZW1lbnRcbiAgYXN5bmMgZ2V0U2NoZW1hKCkge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoe1xuICAgICAgc2NoZW1hOiB7XG4gICAgICAgIHR5cGU6ICdvYmplY3QnLFxuICAgICAgICBwcm9wZXJ0aWVzOiB7fVxuICAgICAgfSxcbiAgICAgIGZvcm06IHRoaXMuZWxlbWVudEFzRm9ybVxuICAgIH0pO1xuICB9XG4gIGFzeW5jIGdldERhdGEoKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7fSk7XG4gIH1cbiAgYXN5bmMgcHV0RGF0YSgpIHt9XG59XG4vLyBJZGVudGlmaWVycyBmb3Igc3BlY2lhbCBmb3Jtc1xuZXhwb3J0cy5UZW1wbGF0ZUZvcm0gPSBUZW1wbGF0ZUZvcm07XG52YXIgRm9ybUlkO1xuKGZ1bmN0aW9uIChGb3JtSWQpIHtcbiAgRm9ybUlkW1wiR2xvYmFsXCJdID0gXCJnbG9iYWxcIjtcbiAgRm9ybUlkW1wiUGxhY2Vob2xkZXJcIl0gPSBcInBsYWNlaG9sZGVyXCI7XG4gIEZvcm1JZFtcIlVuYXZhaWxhYmxlXCJdID0gXCJ1bmF2YWlsYWJsZVwiO1xufSkoRm9ybUlkIHx8IChleHBvcnRzLkZvcm1JZCA9IEZvcm1JZCA9IHt9KSk7XG4vLyBUeXBlIGd1YXJkIHRvIGNoZWNrIHdoZXRoZXIgYSBzdHJpbmcgaXMgYSBzcGVjaWFsIGZvcm0gaWRlbnRpZmllclxuZnVuY3Rpb24gaXNGb3JtSWQodmFsdWUpIHtcbiAgcmV0dXJuIE9iamVjdC52YWx1ZXMoRm9ybUlkKS5pbmNsdWRlcyh2YWx1ZSk7XG59XG4vLyBNYW5hZ2UgdGhlIGNvbmZpZ3VyYXRpb24gZm9ybXNcbmNsYXNzIEZvcm1zIHtcbiAgLy8gQ3JlYXRlIGEgbmV3IGZvcm0gbWFuYWdlclxuICBjb25zdHJ1Y3Rvcihsb2csIGlwYywgY29uZmlnKSB7XG4gICAgdGhpcy5sb2cgPSBsb2c7XG4gICAgdGhpcy5pcGMgPSBpcGM7XG4gICAgdGhpcy5jb25maWcgPSBjb25maWc7XG4gICAgdGhpcy5zaG93Rm9ybSgpO1xuICB9XG4gIC8vIERpc3BsYXkgdGhlIHNwZWNpZmllZCBmb3JtIChkZWZhdWx0aW5nIHRvIHRoZSBwbGFjZWhvbGRlcilcbiAgc2hvd0Zvcm0oZm9ybUlkKSB7XG4gICAgKDAsIF9sb2dFcnJvci5kZXRhY2hlZCkodGhpcy5sb2csICdTaG93IGZvcm0nLCBhc3luYyAoKSA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICAvLyBUaGUgZm9ybXMgYXJlIHJldHJpZXZlZCBmcm9tIHRoZSBzZXJ2ZXIsIHNvIGRpc3BsYXkgYSBzcGlubmVyXG4gICAgICAgIHdpbmRvdy5ob21lYnJpZGdlLnNob3dTcGlubmVyKCk7XG4gICAgICAgIC8vIERpc3BsYXkgdGhlIHJlcXVlc3RlZCBmb3JtLCB3aXRoIGZhbGxiYWNrIHRvIHRoZSBlcnJvciBmb3JtXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgYXdhaXQgdGhpcy5jb25zdHJ1Y3RBbmRTaG93Rm9ybShmb3JtSWQgPz8gRm9ybUlkLlBsYWNlaG9sZGVyKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgdGhpcy5sb2cud2FybignRmFpbGVkIHRvIGRpc3BsYXkgZm9ybScsIGZvcm1JZCwgZXJyKTtcbiAgICAgICAgICBhd2FpdCB0aGlzLmNvbnN0cnVjdEFuZFNob3dGb3JtKEZvcm1JZC5VbmF2YWlsYWJsZSk7XG4gICAgICAgIH1cbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIC8vIEVuc3VyZSB0aGF0IHRoZSBzcGlubmVyIGlzIGFsd2F5cyBoaWRkZW5cbiAgICAgICAgd2luZG93LmhvbWVicmlkZ2UuaGlkZVNwaW5uZXIoKTtcbiAgICAgIH1cbiAgICB9KSgpO1xuICB9XG4gIC8vIFRyeSB0byBjcmVhdGUgdGhlIHJlcXVlc3RlZCBmb3JtLCB3aXRoIGZhbGxiYWNrIHRvIHRoZSBwbGFjZWhvbGRlclxuICBhc3luYyBjb25zdHJ1Y3RBbmRTaG93Rm9ybShmb3JtSWQpIHtcbiAgICBjb25zdCBmb3JtID0gdGhpcy5jb25zdHJ1Y3RGb3JtKGZvcm1JZCk7XG4gICAgYXdhaXQgZm9ybS5jcmVhdGVGb3JtKCk7XG4gICAgdGhpcy5jdXJyZW50Rm9ybSA9IGZvcm07XG4gIH1cbiAgLy8gQ3JlYXRlIGEgc3BlY2lmaWMgZm9ybVxuICBjb25zdHJ1Y3RGb3JtKGZvcm1JZCkge1xuICAgIGlmIChpc0Zvcm1JZChmb3JtSWQpKSB7XG4gICAgICBzd2l0Y2ggKGZvcm1JZCkge1xuICAgICAgICBjYXNlIEZvcm1JZC5QbGFjZWhvbGRlcjpcbiAgICAgICAgICByZXR1cm4gbmV3IFRlbXBsYXRlRm9ybSh0aGlzLmxvZywgJ2hjLWZvcm0tcGxhY2Vob2xkZXInKTtcbiAgICAgICAgY2FzZSBGb3JtSWQuVW5hdmFpbGFibGU6XG4gICAgICAgICAgcmV0dXJuIG5ldyBUZW1wbGF0ZUZvcm0odGhpcy5sb2csICdoYy1mb3JtLXVuYXZhaWxhYmxlJyk7XG4gICAgICAgIGNhc2UgRm9ybUlkLkdsb2JhbDpcbiAgICAgICAgICByZXR1cm4gbmV3IEdsb2JhbEZvcm0odGhpcy5sb2csIHRoaXMuaXBjLCB0aGlzLmNvbmZpZyk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBuZXcgQXBwbGlhbmNlRm9ybSh0aGlzLmxvZywgdGhpcy5pcGMsIHRoaXMuY29uZmlnLCBmb3JtSWQpO1xuICAgIH1cbiAgfVxufVxuZXhwb3J0cy5Gb3JtcyA9IEZvcm1zO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ9dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p1WVcxbGN5STZXeUpmZFhScGJITkViMjBpTENKeVpYRjFhWEpsSWl3aVgyeHZaMFZ5Y205eUlpd2lSbTl5YlNJc0ltTnZibk4wY25WamRHOXlJaXdpYkc5bklpd2lZM0psWVhSbFJtOXliU0lzSW5OamFHVnRZU0lzSW1kbGRGTmphR1Z0WVNJc0ltUmhkR0VpTENKblpYUkVZWFJoSWl3aWNHRjBZMmhsWkZOamFHVnRZU0lzSW5CaGRHTm9VMk5vWlcxaElpd2laR1ZpZFdjaUxDSm1iM0p0SWl3aWQybHVaRzkzSWl3aWFHOXRaV0p5YVdSblpTSXNJbTl1UTJoaGJtZGxJaXdpWTI5dVptbG5JaXdpY0hWMFJHRjBZU0lzSW1SbGMzUnliM2xHYjNKdElpd2laVzVrSWl3aWRXNWtaV1pwYm1Wa0lpd2labTl5YlVaeWIyMVVaVzF3YkdGMFpTSXNJbUZ5WjNNaUxDSjBaVzF3YkdGMFpTSXNJbU5zYjI1bFZHVnRjR3hoZEdVaUxDSmhZbk5VWlcxd2JHRjBaU0lzSW1Wc1pXMWxiblJYYVhSb1FXSnpiMngxZEdWUVlYUm9jeUlzSW1admNtMUdjbTl0U0ZSTlRDSXNJbVZzWlcxbGJuUWlMQ0owZVhCbElpd2lhR1ZzY0haaGJIVmxJaXdpWjJWMFNGUk5UQ0lzSW1WNGNHOXlkSE1pTENKSGJHOWlZV3hHYjNKdElpd2lhWEJqSWl3aWNtVnhkV1Z6ZENJc0ltZGxkRWRzYjJKaGJDSXNJbk5sZEVkc2IySmhiQ0lzSWtGd2NHeHBZVzVqWlVadmNtMGlMQ0pvWVdsa0lpd2laMlYwUVhCd2JHbGhibU5sSWl3aWMyVjBRWEJ3YkdsaGJtTmxJaXdpVkdWdGNHeGhkR1ZHYjNKdElpd2laV3hsYldWdWRFRnpSbTl5YlNJc0lsQnliMjFwYzJVaUxDSnlaWE52YkhabElpd2ljSEp2Y0dWeWRHbGxjeUlzSWtadmNtMUpaQ0lzSW1selJtOXliVWxrSWl3aWRtRnNkV1VpTENKUFltcGxZM1FpTENKMllXeDFaWE1pTENKcGJtTnNkV1JsY3lJc0lrWnZjbTF6SWl3aWMyaHZkMFp2Y20waUxDSm1iM0p0U1dRaUxDSmtaWFJoWTJobFpDSXNJbk5vYjNkVGNHbHVibVZ5SWl3aVkyOXVjM1J5ZFdOMFFXNWtVMmh2ZDBadmNtMGlMQ0pRYkdGalpXaHZiR1JsY2lJc0ltVnljaUlzSW5kaGNtNGlMQ0pWYm1GMllXbHNZV0pzWlNJc0ltaHBaR1ZUY0dsdWJtVnlJaXdpWTI5dWMzUnlkV04wUm05eWJTSXNJbU4xY25KbGJuUkdiM0p0SWl3aVIyeHZZbUZzSWwwc0luTnZkWEpqWlhNaU9sc2lMaTR2TGk0dkxpNHZjM0pqTDJodmJXVmljbWxrWjJVdGRXa3ZjSFZpYkdsakwyWnZjbTF6TG5SeklsMHNJbk52ZFhKalpYTkRiMjUwWlc1MElqcGJiblZzYkYwc0ltMWhjSEJwYm1keklqb2lPenM3T3pzN1FVRlRRU3hKUVVGQlFTeFRRVUZCTEVkQlFVRkRMRTlCUVVFN1FVRkRRU3hKUVVGQlF5eFRRVUZCTEVkQlFVRkVMRTlCUVVFN1FVRldRVHRCUVVOQk96dEJRVmRCTzBGQlEwMHNUVUZCWjBKRkxFbEJRVWs3UlVGTGRFSTdSVUZEUVVNc1dVRkJjVUpETEVkQlFWYzdTVUZCV0N4TFFVRkJRU3hIUVVGSExFZEJRVWhCTEVkQlFVYzdSVUZCVnp0RlFWZHVRenRGUVVOQkxFMUJRVTFETEZWQlFWVkJMRU5CUVVFN1NVRkRXanRKUVVOQkxFMUJRVTFETEUxQlFVMHNSMEZCUnl4TlFVRk5MRWxCUVVrc1EwRkJRME1zVTBGQlV5eEZRVUZGTzBsQlEzSkRMRTFCUVUxRExFbEJRVWtzUjBGQlN5eE5RVUZOTEVsQlFVa3NRMEZCUTBNc1QwRkJUeXhGUVVGRk8wbEJSVzVETzBsQlEwRXNUVUZCVFVNc1lVRkJZU3hIUVVGSExFbEJRVWtzUTBGQlEwTXNWMEZCVnl4RFFVRkRUQ3hOUVVGTkxFTkJRVU03U1VGRE9VTXNTVUZCU1N4RFFVRkRSaXhIUVVGSExFTkJRVU5STEV0QlFVc3NRMEZCUXl4WlFVRlpMRVZCUVVWR0xHRkJRV0VzUlVGQlJVWXNTVUZCU1N4RFFVRkRPMGxCUTJwRUxFbEJRVWtzUTBGQlEwc3NTVUZCU1N4SFFVRkhReXhOUVVGTkxFTkJRVU5ETEZWQlFWVXNRMEZCUTFZc1ZVRkJWU3hEUVVGRFN5eGhRVUZoTEVWQlFVVkdMRWxCUVVrc1EwRkJRenRKUVVVM1JEdEpRVU5CTEVsQlFVa3NRMEZCUTBzc1NVRkJTU3hEUVVGRFJ5eFJRVUZSTEVOQlFVTkRMRTFCUVUwc1NVRkJTU3hKUVVGSkxFTkJRVU5ETEU5QlFVOHNRMEZCUTBRc1RVRkJUU3hEUVVGRExFTkJRVU03UlVGRGRFUTdSVUZGUVR0RlFVTkJSU3hYUVVGWFFTeERRVUZCTzBsQlExQXNTVUZCU1N4RFFVRkRUaXhKUVVGSkxFVkJRVVZQTEVkQlFVY3NSVUZCUlR0SlFVTm9RaXhKUVVGSkxFTkJRVU5RTEVsQlFVa3NSMEZCUjFFc1UwRkJVenRGUVVONlFqdEZRVVZCTzBWQlEwRldMRmRCUVZkQkxFTkJRVU5NTEUxQlFYZENPMGxCUTJoRExFMUJRVTFQTEVsQlFVa3NSMEZCUnl4RFFVTlVMRWxCUVVsUUxFMUJRVTBzUTBGQlEwOHNTVUZCU1N4SlFVRkpMRVZCUVVVc1EwRkJReXhGUVVOMFFpeEhRVUZITEVsQlFVa3NRMEZCUTFNc1owSkJRV2RDTEVOQlFVTXNaMEpCUVdkQ0xFTkJRVU1zUTBGRE4wTTdTVUZEUkN4UFFVRlBPMDFCUVVVc1IwRkJSMmhDTEUxQlFVMDdUVUZCUlU4N1NVRkJTU3hEUVVGRk8wVkJRemxDTzBWQlJVRTdSVUZEUVZNc1owSkJRV2RDUVN4RFFVRkRMRWRCUVVkRExFbEJRWE5ETzBsQlEzUkVMRTFCUVUxRExGRkJRVkVzUjBGQlJ5eEpRVUZCUXl4MVFrRkJZU3hGUVVGRExFZEJRVWRHTEVsQlFVa3NRMEZCUXp0SlFVTjJReXhOUVVGTlJ5eFhRVUZYTEVkQlFVY3NTVUZCUVVNc2EwTkJRWGRDTEVWQlFVTklMRkZCUVZFc1EwRkJRenRKUVVOMFJDeFBRVUZQTEVsQlFVa3NRMEZCUTBrc1dVRkJXU3hEUVVGRFJpeFhRVUZYTEVOQlFVTTdSVUZEZWtNN1JVRkZRVHRGUVVOQlJTeFpRVUZaUVN4RFFVRkRReXhQUVVGaE8wbEJRM1JDTEU5QlFVOHNRMEZCUXp0TlFVTktReXhKUVVGSkxFVkJRVkVzVFVGQlRUdE5RVU5zUWtNc1UwRkJVeXhGUVVGSExFbEJRVUZETEdsQ1FVRlBMRVZCUVVOSUxFOUJRVTg3UzBGRE9VSXNRMEZCUXp0RlFVTk9PenRCUVVkS08wRkJRVUZKTEU5QlFVRXNRMEZCUVM5Q0xFbEJRVUVzUjBGQlFVRXNTVUZCUVR0QlFVTk5MRTFCUVU5blF5eFZRVUZYTEZOQlFWRm9ReXhKUVVGSk8wVkJRMmhEUXl4WlFVRlpReXhIUVVFd1FpeEZRVU5xUWl0Q0xFZEJRVzlDTEVWQlEzQkNiRUlzVFVGQmFVSTdTVUZEYkVNc1MwRkJTeXhEUVVGRFlpeEhRVUZITEVOQlFVTTdTVUZHVHl4TFFVRkJLMElzUjBGQlJ5eEhRVUZJUVN4SFFVRkhPMGxCUTBnc1MwRkJRV3hDTEUxQlFVMHNSMEZCVGtFc1RVRkJUVHRGUVVVelFqdEZRVVZCVml4VFFVRlRRU3hEUVVGQk8wbEJRWEZETEU5QlFVOHNTVUZCU1N4RFFVRkRORUlzUjBGQlJ5eERRVUZEUXl4UFFVRlBMRU5CUVVNc1owSkJRV2RDTEVWQlFVVXNTVUZCU1N4RFFVRkRPMFZCUVVVN1JVRkRMMFl6UWl4UFFVRlBRU3hEUVVGQk8wbEJRWFZETEU5QlFVOHNTVUZCU1N4RFFVRkRVU3hOUVVGTkxFTkJRVU52UWl4VFFVRlRMRVZCUVVVN1JVRkJSVHRGUVVNNVJXNUNMRTlCUVU5QkxFTkJRVU5XTEVsQlFXdENPMGxCUVc5Q0xFOUJRVThzU1VGQlNTeERRVUZEVXl4TlFVRk5MRU5CUVVOeFFpeFRRVUZUTEVOQlFVTTVRaXhKUVVGdlFpeERRVUZETzBWQlFVVTdPMEZCUjNSSE8wRkJRVUY1UWl4UFFVRkJMRU5CUVVGRExGVkJRVUVzUjBGQlFVRXNWVUZCUVR0QlFVTk5MRTFCUVU5TExHRkJRV01zVTBGQlVYSkRMRWxCUVVrN1JVRkRia05ETEZsQlFWbERMRWRCUVRCQ0xFVkJRMnBDSzBJc1IwRkJiMElzUlVGRGNFSnNRaXhOUVVGcFFpeEZRVU5xUW5WQ0xFbEJRV2xDTzBsQlEyeERMRXRCUVVzc1EwRkJRM0JETEVkQlFVY3NRMEZCUXp0SlFVaFBMRXRCUVVFclFpeEhRVUZITEVkQlFVaEJMRWRCUVVjN1NVRkRTQ3hMUVVGQmJFSXNUVUZCVFN4SFFVRk9RU3hOUVVGTk8wbEJRMDRzUzBGQlFYVkNMRWxCUVVrc1IwRkJTa0VzU1VGQlNUdEZRVVY2UWp0RlFVVkJha01zVTBGQlUwRXNRMEZCUVR0SlFVRnhReXhQUVVGUExFbEJRVWtzUTBGQlF6UkNMRWRCUVVjc1EwRkJRME1zVDBGQlR5eERRVUZETEcxQ1FVRnRRaXhGUVVGRkxFbEJRVWtzUTBGQlEwa3NTVUZCU1N4RFFVRkRPMFZCUVVVN1JVRkRka2N2UWl4UFFVRlBRU3hEUVVGQk8wbEJRWFZETEU5QlFVOHNTVUZCU1N4RFFVRkRVU3hOUVVGTkxFTkJRVU4zUWl4WlFVRlpMRU5CUVVNc1NVRkJTU3hEUVVGRFJDeEpRVUZKTEVOQlFVTTdSVUZCUlR0RlFVTXhSblJDTEU5QlFVOUJMRU5CUVVOV0xFbEJRV3RDTzBsQlFXOUNMRTlCUVU4c1NVRkJTU3hEUVVGRFV5eE5RVUZOTEVOQlFVTjVRaXhaUVVGWkxFTkJRVU1zU1VGQlNTeERRVUZEUml4SlFVRkpMRVZCUVVWb1F5eEpRVUZKTEVOQlFVTTdSVUZCUlRzN1FVRkhjRWM3UVVGQlFYbENMRTlCUVVFc1EwRkJRVTBzWVVGQlFTeEhRVUZCUVN4aFFVRkJPMEZCUTAwc1RVRkJUMGtzV1VGQllTeFRRVUZSZWtNc1NVRkJTVHRGUVVsc1EwTXNXVUZCV1VNc1IwRkJhMElzUlVGRGJFSXNSMEZCUjIxQ0xFbEJRWGxETzBsQlEzQkVMRXRCUVVzc1EwRkJRMjVDTEVkQlFVY3NRMEZCUXp0SlFVTldMRWxCUVVrc1EwRkJRM2RETEdGQlFXRXNSMEZCUnl4SlFVRkpMRU5CUVVOMFFpeG5Ra0ZCWjBJc1EwRkJReXhIUVVGSFF5eEpRVUZKTEVOQlFVTTdSVUZEZGtRN1JVRkZRVHRGUVVOQkxFMUJRVTFvUWl4VFFVRlRRU3hEUVVGQk8wbEJRMWdzVDBGQlQzTkRMRTlCUVU4c1EwRkJRME1zVDBGQlR5eERRVUZETzAxQlEyNUNlRU1zVFVGQlRTeEZRVUZGTzFGQlEwcDNRaXhKUVVGSkxFVkJRVVVzVVVGQlVUdFJRVU5rYVVJc1ZVRkJWU3hGUVVGRk8wOUJRMlk3VFVGRFJHeERMRWxCUVVrc1JVRkJTU3hKUVVGSkxFTkJRVU1yUWp0TFFVTm9RaXhEUVVGRE8wVkJRMDQ3UlVGRlFTeE5RVUZOYmtNc1QwRkJUMEVzUTBGQlFUdEpRVUUyUWl4UFFVRlBiME1zVDBGQlR5eERRVUZEUXl4UFFVRlBMRU5CUVVNc1JVRkJSU3hEUVVGRE8wVkJRVVU3UlVGRGRFVXNUVUZCVFRWQ0xFOUJRVTlCTEVOQlFVRXNSMEZCZVVNN08wRkJSekZFTzBGQlFVRmxMRTlCUVVFc1EwRkJRVlVzV1VGQlFTeEhRVUZCUVN4WlFVRkJPMEZCUTBFc1NVRkJXVXNzVFVGSldEdEJRVXBFTEZkQlFWbEJMRTFCUVUwN1JVRkRaRUVzVFVGQlFTeHhRa0ZCYzBJN1JVRkRkRUpCTEUxQlFVRXNLMEpCUVRKQ08wVkJRek5DUVN4TlFVRkJMQ3RDUVVFeVFqdEJRVU12UWl4RFFVRkRMRVZCU2xkQkxFMUJRVTBzUzBGQlFXWXNUMEZCUVN4RFFVRkJaU3hOUVVGQkxFZEJRVTVCTEUxQlFVMDdRVUZOYkVJN1FVRkRRU3hUUVVGVFF5eFJRVUZSUVN4RFFVRkRReXhMUVVGaE8wVkJRek5DTEU5QlFVOURMRTFCUVUwc1EwRkJRME1zVFVGQlRTeERRVUZEU2l4TlFVRk5MRU5CUVVNc1EwRkJRMHNzVVVGQlVTeERRVUZEU0N4TFFVRmxMRU5CUVVNN1FVRkRNVVE3UVVGRlFUdEJRVU5OTEUxQlFVOUpMRXRCUVVzN1JVRkxaRHRGUVVOQmJrUXNXVUZCY1VKRExFZEJRV2xDTEVWQlEycENLMElzUjBGQmIwSXNSVUZEY0VKc1FpeE5RVUZwUWp0SlFVWnFRaXhMUVVGQllpeEhRVUZITEVkQlFVaEJMRWRCUVVjN1NVRkRTQ3hMUVVGQkswSXNSMEZCUnl4SFFVRklRU3hIUVVGSE8wbEJRMGdzUzBGQlFXeENMRTFCUVUwc1IwRkJUa0VzVFVGQlRUdEpRVU4yUWl4SlFVRkpMRU5CUVVOelF5eFJRVUZSTEVWQlFVVTdSVUZEYmtJN1JVRkZRVHRGUVVOQlFTeFJRVUZSUVN4RFFVRkRReXhOUVVGbE8wbEJRM0JDTEVsQlFVRkRMR3RDUVVGUkxFVkJRVU1zU1VGQlNTeERRVUZEY2tRc1IwRkJSeXhGUVVGRkxGZEJRVmNzUlVGQlJTeFpRVUZYTzAxQlEzWkRMRWxCUVVrN1VVRkRRVHRSUVVOQlZTeE5RVUZOTEVOQlFVTkRMRlZCUVZVc1EwRkJRekpETEZkQlFWY3NSVUZCUlR0UlFVVXZRanRSUVVOQkxFbEJRVWs3VlVGRFFTeE5RVUZOTEVsQlFVa3NRMEZCUTBNc2IwSkJRVzlDTEVOQlFVTklMRTFCUVUwc1NVRkJTVklzVFVGQlRTeERRVUZEV1N4WFFVRlhMRU5CUVVNN1VVRkRha1VzUTBGQlF5eERRVUZETEU5QlFVOURMRWRCUVVjc1JVRkJSVHRWUVVOV0xFbEJRVWtzUTBGQlEzcEVMRWRCUVVjc1EwRkJRekJFTEVsQlFVa3NRMEZCUXl4M1FrRkJkMElzUlVGQlJVNHNUVUZCVFN4RlFVRkZTeXhIUVVGSExFTkJRVU03VlVGRGNFUXNUVUZCVFN4SlFVRkpMRU5CUVVOR0xHOUNRVUZ2UWl4RFFVRkRXQ3hOUVVGTkxFTkJRVU5sTEZkQlFWY3NRMEZCUXp0UlFVTjJSRHROUVVOS0xFTkJRVU1zVTBGQlVUdFJRVU5NTzFGQlEwRnFSQ3hOUVVGTkxFTkJRVU5ETEZWQlFWVXNRMEZCUTJsRUxGZEJRVmNzUlVGQlJUdE5RVU51UXp0SlFVTktMRU5CUVVNc1EwRkJReXhGUVVGRk8wVkJRMUk3UlVGRlFUdEZRVU5CTEUxQlFVMU1MRzlDUVVGdlFrRXNRMEZCUTBnc1RVRkJZenRKUVVOeVF5eE5RVUZOTTBNc1NVRkJTU3hIUVVGSExFbEJRVWtzUTBGQlEyOUVMR0ZCUVdFc1EwRkJRMVFzVFVGQlRTeERRVUZETzBsQlEzWkRMRTFCUVUwelF5eEpRVUZKTEVOQlFVTlNMRlZCUVZVc1JVRkJSVHRKUVVOMlFpeEpRVUZKTEVOQlFVTTJSQ3hYUVVGWExFZEJRVWR5UkN4SlFVRkpPMFZCUXpOQ08wVkJSVUU3UlVGRFFXOUVMR0ZCUVdGQkxFTkJRVU5VTEUxQlFXTTdTVUZEZUVJc1NVRkJTVkFzVVVGQlVTeERRVUZEVHl4TlFVRk5MRU5CUVVNc1JVRkJSVHROUVVOc1FpeFJRVUZSUVN4TlFVRk5PMUZCUTJRc1MwRkJTMUlzVFVGQlRTeERRVUZEV1N4WFFVRlhPMVZCUVVVc1QwRkJUeXhKUVVGSmFrSXNXVUZCV1N4RFFVRkZMRWxCUVVrc1EwRkJRM1pETEVkQlFVY3NSVUZCUlN4eFFrRkJjVUlzUTBGQlF6dFJRVU5zUml4TFFVRkxORU1zVFVGQlRTeERRVUZEWlN4WFFVRlhPMVZCUVVVc1QwRkJUeXhKUVVGSmNFSXNXVUZCV1N4RFFVRkZMRWxCUVVrc1EwRkJRM1pETEVkQlFVY3NSVUZCUlN4eFFrRkJjVUlzUTBGQlF6dFJRVU5zUml4TFFVRkxORU1zVFVGQlRTeERRVUZEYlVJc1RVRkJUVHRWUVVGUExFOUJRVThzU1VGQlNXcERMRlZCUVZVc1EwRkJTU3hKUVVGSkxFTkJRVU01UWl4SFFVRkhMRVZCUVVVc1NVRkJTU3hEUVVGREswSXNSMEZCUnl4RlFVRkZMRWxCUVVrc1EwRkJRMnhDTEUxQlFVMHNRMEZCUXp0TlFVTnNSanRKUVVOS0xFTkJRVU1zVFVGQlRUdE5RVU5JTEU5QlFVOHNTVUZCU1hOQ0xHRkJRV0VzUTBGQlF5eEpRVUZKTEVOQlFVTnVReXhIUVVGSExFVkJRVVVzU1VGQlNTeERRVUZESzBJc1IwRkJSeXhGUVVGRkxFbEJRVWtzUTBGQlEyeENMRTFCUVUwc1JVRkJSWFZETEUxQlFVMHNRMEZCUXp0SlFVTnlSVHRGUVVOS096dEJRVU5JZGtJc1QwRkJRU3hEUVVGQmNVSXNTMEZCUVN4SFFVRkJRU3hMUVVGQklpd2lhV2R1YjNKbFRHbHpkQ0k2VzExOSIsIlwidXNlIHN0cmljdFwiO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5TZXJ2ZXJMb2dnZXIgPSBleHBvcnRzLkNvbnNvbGVMb2dnZXIgPSBleHBvcnRzLkNsaWVudExvZ2dlciA9IHZvaWQgMDtcbi8vIEhvbWVicmlkZ2UgcGx1Z2luIGZvciBIb21lIENvbm5lY3QgaG9tZSBhcHBsaWFuY2VzXG4vLyBDb3B5cmlnaHQgwqkgMjAyMy0yMDI2IEFsZXhhbmRlciBUaG91a3lkaWRlc1xuLy8gUHJlZml4IGZvciBjbGllbnQgYW5kIHNlcnZlciBsb2cgbWVzc2FnZXNcbmNvbnN0IFBMVUdJTl9QUkVGSVggPSB3aW5kb3cuaG9tZWJyaWRnZS5wbHVnaW4uZGlzcGxheU5hbWUgPz8gd2luZG93LmhvbWVicmlkZ2UucGx1Z2luLm5hbWU7XG4vLyBBIGxvZ2dlciB0aGF0IHNlbmRzIG1lc3NhZ2VzIHRvIHRoZSBkZWJ1Z2dpbmcgY29uc29sZVxuY2xhc3MgQ29uc29sZUxvZ2dlciB7XG4gIC8vIENyZWF0ZSBhIG5ldyBjb25zb2xlIGxvZ2dlclxuICBjb25zdHJ1Y3RvcihwcmVmaXggPSAnJykge1xuICAgIHRoaXMucHJlZml4ID0gcHJlZml4O1xuICB9XG4gIC8vIFNpbXBsZSB3cmFwcGVycyB0byBsb2cgYSBtZXNzYWdlXG4gIGVycm9yKG1lc3NhZ2UsIC4uLnBhcmFtcykge1xuICAgIHRoaXMubG9nKFwiZXJyb3JcIiAvKiBMb2dMZXZlbC5FUlJPUiAqLywgbWVzc2FnZSwgLi4ucGFyYW1zKTtcbiAgfVxuICB3YXJuKG1lc3NhZ2UsIC4uLnBhcmFtcykge1xuICAgIHRoaXMubG9nKFwid2FyblwiIC8qIExvZ0xldmVsLldBUk4gKi8sIG1lc3NhZ2UsIC4uLnBhcmFtcyk7XG4gIH1cbiAgc3VjY2VzcyhtZXNzYWdlLCAuLi5wYXJhbXMpIHtcbiAgICB0aGlzLmxvZyhcInN1Y2Nlc3NcIiAvKiBMb2dMZXZlbC5TVUNDRVNTICovLCBtZXNzYWdlLCAuLi5wYXJhbXMpO1xuICB9XG4gIGluZm8obWVzc2FnZSwgLi4ucGFyYW1zKSB7XG4gICAgdGhpcy5sb2coXCJpbmZvXCIgLyogTG9nTGV2ZWwuSU5GTyAqLywgbWVzc2FnZSwgLi4ucGFyYW1zKTtcbiAgfVxuICBkZWJ1ZyhtZXNzYWdlLCAuLi5wYXJhbXMpIHtcbiAgICB0aGlzLmxvZyhcImRlYnVnXCIgLyogTG9nTGV2ZWwuREVCVUcgKi8sIG1lc3NhZ2UsIC4uLnBhcmFtcyk7XG4gIH1cbiAgLy8gTG9nIGEgbWVzc2FnZSBhdCB0aGUgc3BlY2lmaWVkIGxldmVsXG4gIGxvZyhsZXZlbCwgbWVzc2FnZSwgLi4ucGFyYW1zKSB7XG4gICAgLy8gQWRkIHRoZSBwcmVmaXggdG8gdGhlIG1lc3NhZ2VcbiAgICBpZiAodGhpcy5wcmVmaXgubGVuZ3RoKSBtZXNzYWdlID0gYFske3RoaXMucHJlZml4fV0gJHttZXNzYWdlfWA7XG4gICAgLy8gTG9nIHRoZSBtZXNzYWdlXG4gICAgc3dpdGNoIChsZXZlbCkge1xuICAgICAgY2FzZSBcImVycm9yXCIgLyogTG9nTGV2ZWwuRVJST1IgKi86XG4gICAgICAgIGNvbnNvbGUuZXJyb3IobWVzc2FnZSwgLi4ucGFyYW1zKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFwid2FyblwiIC8qIExvZ0xldmVsLldBUk4gKi86XG4gICAgICAgIGNvbnNvbGUud2FybihtZXNzYWdlLCAuLi5wYXJhbXMpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgXCJzdWNjZXNzXCIgLyogTG9nTGV2ZWwuU1VDQ0VTUyAqLzpcbiAgICAgICAgY29uc29sZS5pbmZvKG1lc3NhZ2UsIC4uLnBhcmFtcyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBcImluZm9cIiAvKiBMb2dMZXZlbC5JTkZPICovOlxuICAgICAgICBjb25zb2xlLmluZm8obWVzc2FnZSwgLi4ucGFyYW1zKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFwiZGVidWdcIiAvKiBMb2dMZXZlbC5ERUJVRyAqLzpcbiAgICAgICAgY29uc29sZS5kZWJ1ZyhtZXNzYWdlLCAuLi5wYXJhbXMpO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gIH1cbn1cbi8vIExvZ2dlciBmb3IgbG9jYWxseSBnZW5lcmF0ZWQgbWVzc2FnZXNcbmV4cG9ydHMuQ29uc29sZUxvZ2dlciA9IENvbnNvbGVMb2dnZXI7XG5jbGFzcyBDbGllbnRMb2dnZXIgZXh0ZW5kcyBDb25zb2xlTG9nZ2VyIHtcbiAgLy8gQ3JlYXRlIGEgbmV3IGNsaWVudCBsb2dnZXJcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoYCR7UExVR0lOX1BSRUZJWH0gY2xpZW50YCk7XG4gIH1cbn1cbi8vIExvZ2dlciB0aGF0IHJlY2VpdmVzIG1lc3NhZ2VzIGV2ZW50cyBmcm9tIHRoZSBzZXJ2ZXJcbmV4cG9ydHMuQ2xpZW50TG9nZ2VyID0gQ2xpZW50TG9nZ2VyO1xuY2xhc3MgU2VydmVyTG9nZ2VyIGV4dGVuZHMgQ29uc29sZUxvZ2dlciB7XG4gIC8vIENyZWF0ZSBhIG5ldyBzZXJ2ZXIgbG9nZ2VyXG4gIGNvbnN0cnVjdG9yKGlwYywgbWluTGV2ZWwpIHtcbiAgICBzdXBlcihgJHtQTFVHSU5fUFJFRklYfSBzZXJ2ZXJgKTtcbiAgICB0aGlzLmlwYyA9IGlwYztcbiAgICAvLyBTdGFydCByZWNlaXZpbmcgbG9nIGV2ZW50c1xuICAgIGlwYy5vbkV2ZW50KCdsb2cnLCBtZXNzYWdlcyA9PiB7XG4gICAgICB0aGlzLmxvZ01lc3NhZ2VzKG1lc3NhZ2VzKTtcbiAgICB9KTtcbiAgICBpcGMucmVxdWVzdCgnL2xvZycsIG1pbkxldmVsKS5jYXRjaCgoKSA9PiB7fSk7XG4gIH1cbiAgLy8gTG9nIG1lc3NhZ2VzIHJlY2VpdmVkIGZyb20gdGhlIHNlcnZlclxuICBsb2dNZXNzYWdlcyhtZXNzYWdlcykge1xuICAgIGZvciAoY29uc3Qge1xuICAgICAgbGV2ZWwsXG4gICAgICBtZXNzYWdlLFxuICAgICAgcGFyYW1zXG4gICAgfSBvZiBtZXNzYWdlcykgdGhpcy5sb2cobGV2ZWwsIG1lc3NhZ2UsIC4uLnBhcmFtcyk7XG4gIH1cbn1cbmV4cG9ydHMuU2VydmVyTG9nZ2VyID0gU2VydmVyTG9nZ2VyO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ9dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p1WVcxbGN5STZXeUpRVEZWSFNVNWZVRkpGUmtsWUlpd2lkMmx1Wkc5M0lpd2lhRzl0WldKeWFXUm5aU0lzSW5Cc2RXZHBiaUlzSW1ScGMzQnNZWGxPWVcxbElpd2libUZ0WlNJc0lrTnZibk52YkdWTWIyZG5aWElpTENKamIyNXpkSEoxWTNSdmNpSXNJbkJ5WldacGVDSXNJbVZ5Y205eUlpd2liV1Z6YzJGblpTSXNJbkJoY21GdGN5SXNJbXh2WnlJc0luZGhjbTRpTENKemRXTmpaWE56SWl3aWFXNW1ieUlzSW1SbFluVm5JaXdpYkdWMlpXd2lMQ0pzWlc1bmRHZ2lMQ0pqYjI1emIyeGxJaXdpWlhod2IzSjBjeUlzSWtOc2FXVnVkRXh2WjJkbGNpSXNJbE5sY25abGNreHZaMmRsY2lJc0ltbHdZeUlzSW0xcGJreGxkbVZzSWl3aWIyNUZkbVZ1ZENJc0ltMWxjM05oWjJWeklpd2liRzluVFdWemMyRm5aWE1pTENKeVpYRjFaWE4wSWl3aVkyRjBZMmdpWFN3aWMyOTFjbU5sY3lJNld5SXVMaTh1TGk4dUxpOXpjbU12YUc5dFpXSnlhV1JuWlMxMWFTOXdkV0pzYVdNdmJHOW5aMlZ5TG5SeklsMHNJbk52ZFhKalpYTkRiMjUwWlc1MElqcGJiblZzYkYwc0ltMWhjSEJwYm1keklqb2lPenM3T3pzN1FVRkJRVHRCUVVOQk8wRkJUMEU3UVVGRFFTeE5RVUZOUVN4aFFVRmhMRWRCUVVkRExFMUJRVTBzUTBGQlEwTXNWVUZCVlN4RFFVRkRReXhOUVVGTkxFTkJRVU5ETEZkQlFWY3NTVUZCU1Vnc1RVRkJUU3hEUVVGRFF5eFZRVUZWTEVOQlFVTkRMRTFCUVUwc1EwRkJRMFVzU1VGQlNUdEJRVVV6Ump0QlFVTk5MRTFCUVU5RExHRkJRV0U3UlVGRmRFSTdSVUZEUVVNc1dVRkJjVUpETEUxQlFVRXNSMEZCVXl4RlFVRkZPMGxCUVZnc1MwRkJRVUVzVFVGQlRTeEhRVUZPUVN4TlFVRk5PMFZCUVZFN1JVRkZia003UlVGRFFVTXNTMEZCUzBFc1EwRkJSME1zVDBGQlpTeEZRVUZGTEVkQlFVZERMRTFCUVdsQ08wbEJRVlVzU1VGQlNTeERRVUZEUXl4SFFVRkhMQ3RDUVVGdFFrWXNUMEZCVHl4RlFVRkZMRWRCUVVkRExFMUJRVTBzUTBGQlF6dEZRVUZGTzBWQlEzWkhSU3hKUVVGSlFTeERRVUZKU0N4UFFVRmxMRVZCUVVVc1IwRkJSME1zVFVGQmFVSTdTVUZCVlN4SlFVRkpMRU5CUVVORExFZEJRVWNzTmtKQlFXMUNSaXhQUVVGUExFVkJRVVVzUjBGQlIwTXNUVUZCVFN4RFFVRkRPMFZCUVVVN1JVRkRka2RITEU5QlFVOUJMRU5CUVVOS0xFOUJRV1VzUlVGQlJTeEhRVUZIUXl4TlFVRnBRanRKUVVGVkxFbEJRVWtzUTBGQlEwTXNSMEZCUnl4dFEwRkJiVUpHTEU5QlFVOHNSVUZCUlN4SFFVRkhReXhOUVVGTkxFTkJRVU03UlVGQlJUdEZRVU4yUjBrc1NVRkJTVUVzUTBGQlNVd3NUMEZCWlN4RlFVRkZMRWRCUVVkRExFMUJRV2xDTzBsQlFWVXNTVUZCU1N4RFFVRkRReXhIUVVGSExEWkNRVUZ0UWtZc1QwRkJUeXhGUVVGRkxFZEJRVWRETEUxQlFVMHNRMEZCUXp0RlFVRkZPMFZCUTNaSFN5eExRVUZMUVN4RFFVRkhUaXhQUVVGbExFVkJRVVVzUjBGQlIwTXNUVUZCYVVJN1NVRkJWU3hKUVVGSkxFTkJRVU5ETEVkQlFVY3NLMEpCUVcxQ1JpeFBRVUZQTEVWQlFVVXNSMEZCUjBNc1RVRkJUU3hEUVVGRE8wVkJRVVU3UlVGSGRrYzdSVUZEUVVNc1IwRkJSMEVzUTBGQlEwc3NTMEZCWlN4RlFVRkZVQ3hQUVVGbExFVkJRVVVzUjBGQlIwTXNUVUZCYVVJN1NVRkRkRVE3U1VGRFFTeEpRVUZKTEVsQlFVa3NRMEZCUTBnc1RVRkJUU3hEUVVGRFZTeE5RVUZOTEVWQlFVVlNMRTlCUVU4c1IwRkJSeXhKUVVGSkxFbEJRVWtzUTBGQlEwWXNUVUZCVFN4TFFVRkxSU3hQUVVGUExFVkJRVVU3U1VGRkwwUTdTVUZEUVN4UlFVRlJUeXhMUVVGTE8wMUJRMkk3VVVGQmRVSkZMRTlCUVU4c1EwRkJRMVlzUzBGQlN5eERRVUZIUXl4UFFVRlBMRVZCUVVVc1IwRkJSME1zVFVGQlRTeERRVUZETzFGQlFVVTdUVUZETlVRN1VVRkJkVUpSTEU5QlFVOHNRMEZCUTA0c1NVRkJTU3hEUVVGSlNDeFBRVUZQTEVWQlFVVXNSMEZCUjBNc1RVRkJUU3hEUVVGRE8xRkJRVVU3VFVGRE5VUTdVVUZCZFVKUkxFOUJRVThzUTBGQlEwb3NTVUZCU1N4RFFVRkpUQ3hQUVVGUExFVkJRVVVzUjBGQlIwTXNUVUZCVFN4RFFVRkRPMUZCUVVVN1RVRkROVVE3VVVGQmRVSlJMRTlCUVU4c1EwRkJRMG9zU1VGQlNTeERRVUZKVEN4UFFVRlBMRVZCUVVVc1IwRkJSME1zVFVGQlRTeERRVUZETzFGQlFVVTdUVUZETlVRN1VVRkJkVUpSTEU5QlFVOHNRMEZCUTBnc1MwRkJTeXhEUVVGSFRpeFBRVUZQTEVWQlFVVXNSMEZCUjBNc1RVRkJUU3hEUVVGRE8xRkJRVVU3U1VGRE5VUTdSVUZEU2pzN1FVRkpTanRCUVVGQlV5eFBRVUZCTEVOQlFVRmtMR0ZCUVVFc1IwRkJRVUVzWVVGQlFUdEJRVU5OTEUxQlFVOWxMRmxCUVdFc1UwRkJVV1lzWVVGQllUdEZRVVV6UXp0RlFVTkJReXhaUVVGQk8wbEJRMGtzUzBGQlN5eERRVUZETEVkQlFVZFFMR0ZCUVdFc1UwRkJVeXhEUVVGRE8wVkJRM0JET3p0QlFVZEtPMEZCUVVGdlFpeFBRVUZCTEVOQlFVRkRMRmxCUVVFc1IwRkJRVUVzV1VGQlFUdEJRVU5OTEUxQlFVOURMRmxCUVdFc1UwRkJVV2hDTEdGQlFXRTdSVUZGTTBNN1JVRkRRVU1zV1VGQmNVSm5RaXhIUVVGakxFVkJRVVZETEZGQlFXdENPMGxCUTI1RUxFdEJRVXNzUTBGQlF5eEhRVUZIZUVJc1lVRkJZU3hUUVVGVExFTkJRVU03U1VGRVppeExRVUZCZFVJc1IwRkJSeXhIUVVGSVFTeEhRVUZITzBsQlIzQkNPMGxCUTBGQkxFZEJRVWNzUTBGQlEwVXNUMEZCVHl4RFFVRkRMRXRCUVVzc1JVRkJSVU1zVVVGQlVTeEpRVUZITzAxQlFVY3NTVUZCU1N4RFFVRkRReXhYUVVGWExFTkJRVU5FTEZGQlFWRXNRMEZCUXp0SlFVRkZMRU5CUVVNc1EwRkJRenRKUVVNdlJFZ3NSMEZCUnl4RFFVRkRTeXhQUVVGUExFTkJRVU1zVFVGQlRTeEZRVUZGU2l4UlFVRlJMRU5CUVVNc1EwRkJRMHNzUzBGQlN5eERRVUZETEUxQlFVc3NRMEZCWlN4RFFVRkRMRU5CUVVNN1JVRkRPVVE3UlVGRlFUdEZRVU5CUml4WFFVRlhRU3hEUVVGRFJDeFJRVUUwUWp0SlFVTndReXhMUVVGTExFMUJRVTA3VFVGQlJWUXNTMEZCU3p0TlFVRkZVQ3hQUVVGUE8wMUJRVVZETzBsQlFVMHNRMEZCUlN4SlFVRkpaU3hSUVVGUkxFVkJRemRETEVsQlFVa3NRMEZCUTJRc1IwRkJSeXhEUVVGRFN5eExRVUZMTEVWQlFVVlFMRTlCUVU4c1JVRkJSU3hIUVVGSFF5eE5RVUZOTEVOQlFVTTdSVUZETTBNN08wRkJRMGhUTEU5QlFVRXNRMEZCUVVVc1dVRkJRU3hIUVVGQlFTeFpRVUZCSWl3aWFXZHViM0psVEdsemRDSTZXMTE5IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmNsb25lVGVtcGxhdGUgPSBjbG9uZVRlbXBsYXRlO1xuZXhwb3J0cy5lbGVtZW50V2l0aEFic29sdXRlUGF0aHMgPSBlbGVtZW50V2l0aEFic29sdXRlUGF0aHM7XG5leHBvcnRzLmdldEVsZW1lbnRCeUlkID0gZ2V0RWxlbWVudEJ5SWQ7XG5leHBvcnRzLmdldEhUTUwgPSBnZXRIVE1MO1xuZXhwb3J0cy5nZXRTbG90ID0gZ2V0U2xvdDtcbmV4cG9ydHMuc2V0U2xvdFRleHQgPSBzZXRTbG90VGV4dDtcbnZhciBfYXNzZXJ0ID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiYXNzZXJ0XCIpKTtcbnZhciBfdXRpbHMgPSByZXF1aXJlKFwiLi4vLi4vdXRpbHMuanNcIik7XG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KGUpIHsgcmV0dXJuIGUgJiYgZS5fX2VzTW9kdWxlID8gZSA6IHsgZGVmYXVsdDogZSB9OyB9XG4vLyBIb21lYnJpZGdlIHBsdWdpbiBmb3IgSG9tZSBDb25uZWN0IGhvbWUgYXBwbGlhbmNlc1xuLy8gQ29weXJpZ2h0IMKpIDIwMjMtMjAyNiBBbGV4YW5kZXIgVGhvdWt5ZGlkZXNcblxuLy8gR2V0IGFuIEhUTUwgZWxlbWVudCBieSBpdHMgXCJpZFwiIGF0dHJpYnV0ZVxuZnVuY3Rpb24gZ2V0RWxlbWVudEJ5SWQoZWxlbWVudElkKSB7XG4gIGNvbnN0IGVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChlbGVtZW50SWQpO1xuICAoMCwgX3V0aWxzLmFzc2VydElzSW5zdGFuY2VPZikoZWxlbWVudCwgSFRNTEVsZW1lbnQpO1xuICByZXR1cm4gZWxlbWVudDtcbn1cbi8vIEdldCBhbiBIVE1MIGVsZW1lbnQgdXNpbmcgYSBzbG90IG5hbWVcbmZ1bmN0aW9uIGdldFNsb3Qod2l0aGluLCBzbG90TmFtZSkge1xuICBjb25zdCBzbG90cyA9IHdpdGhpbi5xdWVyeVNlbGVjdG9yQWxsKGBbc2xvdD1cIiR7c2xvdE5hbWV9XCJdYCk7XG4gIF9hc3NlcnQuZGVmYXVsdC5lcXVhbChzbG90cy5sZW5ndGgsIDEsIGBFeHBlY3RlZCBleGFjdGx5IG9uZSBzbG90IHdpdGggbmFtZSBcIiR7c2xvdE5hbWV9XCJgKTtcbiAgKDAsIF91dGlscy5hc3NlcnRJc0luc3RhbmNlT2YpKHNsb3RzWzBdLCBIVE1MRWxlbWVudCk7XG4gIHJldHVybiBzbG90c1swXTtcbn1cbi8vIFNldCB0aGUgdGV4dCBjb250ZW50IG9mIG11bHRpcGxlIHNsb3QgZWxlbWVudHNcbmZ1bmN0aW9uIHNldFNsb3RUZXh0KHdpdGhpbiwgc2xvdFRleHQpIHtcbiAgZm9yIChjb25zdCBbc2xvdE5hbWUsIHRleHRdIG9mIE9iamVjdC5lbnRyaWVzKHNsb3RUZXh0KSkgZ2V0U2xvdCh3aXRoaW4sIHNsb3ROYW1lKS50ZXh0Q29udGVudCA9IHRleHQ7XG59XG4vLyBDcmVhdGUgYSBjb3B5IG9mIGEgdGVtcGxhdGUgZWxlbWVudFxuZnVuY3Rpb24gY2xvbmVUZW1wbGF0ZShlbGVtZW50SWQsIHNsb3RUZXh0KSB7XG4gIC8vIEZpbmQgdGhlIHRlbXBsYXRlIGVsZW1lbnRcbiAgY29uc3QgdGVtcGxhdGUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChlbGVtZW50SWQpO1xuICAoMCwgX3V0aWxzLmFzc2VydElzSW5zdGFuY2VPZikodGVtcGxhdGUsIEhUTUxUZW1wbGF0ZUVsZW1lbnQpO1xuICAvLyBDbG9uZSB0aGUgdGVtcGxhdGUncyBkb2N1bWVudC1mcmFnbWVudCBhbmQgc2V0IHNsb3QgdmFsdWVzXG4gIGNvbnN0IGRvY3VtZW50RnJhZ21lbnQgPSB0ZW1wbGF0ZS5jb250ZW50LmNsb25lTm9kZSh0cnVlKTtcbiAgKDAsIF91dGlscy5hc3NlcnRJc0luc3RhbmNlT2YpKGRvY3VtZW50RnJhZ21lbnQsIERvY3VtZW50RnJhZ21lbnQpO1xuICBpZiAoc2xvdFRleHQpIHNldFNsb3RUZXh0KGRvY3VtZW50RnJhZ21lbnQsIHNsb3RUZXh0KTtcbiAgcmV0dXJuIGRvY3VtZW50RnJhZ21lbnQ7XG59XG4vLyBNYWtlIFVSSSBwYXRocyBhYnNvbHV0ZVxuZnVuY3Rpb24gZWxlbWVudFdpdGhBYnNvbHV0ZVBhdGhzKGZyYWdtZW50KSB7XG4gIGZvciAoY29uc3QgYXR0cmlidXRlIG9mIFsnaHJlZicsICdzcmMnXSkge1xuICAgIGNvbnN0IGVsZW1lbnRzID0gZnJhZ21lbnQucXVlcnlTZWxlY3RvckFsbChgWyR7YXR0cmlidXRlfV1gKTtcbiAgICBmb3IgKGNvbnN0IGVsZW1lbnQgb2YgQXJyYXkuZnJvbShlbGVtZW50cykpIHtcbiAgICAgIGNvbnN0IHBhdGggPSBlbGVtZW50LmdldEF0dHJpYnV0ZShhdHRyaWJ1dGUpO1xuICAgICAgKDAsIF91dGlscy5hc3NlcnRJc0RlZmluZWQpKHBhdGgpO1xuICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoYXR0cmlidXRlLCBuZXcgVVJMKHBhdGgsIGxvY2F0aW9uLmhyZWYpLmhyZWYpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZnJhZ21lbnQ7XG59XG4vLyBPYnRhaW4gdGhlIEhUTUwgc2VyaWFsaXphdGlvbiBvZiBhIHRlbXBsYXRlIGVsZW1lbnRcbmZ1bmN0aW9uIGdldEhUTUwoZnJhZ21lbnQpIHtcbiAgY29uc3Qgc2VyaWFsaXplciA9IG5ldyBYTUxTZXJpYWxpemVyKCk7XG4gIHJldHVybiBzZXJpYWxpemVyLnNlcmlhbGl6ZVRvU3RyaW5nKGZyYWdtZW50KTtcbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRhdGE6YXBwbGljYXRpb24vanNvbjtjaGFyc2V0PXV0Zi04O2Jhc2U2NCxleUoyWlhKemFXOXVJam96TENKdVlXMWxjeUk2V3lKZllYTnpaWEowSWl3aVgybHVkR1Z5YjNCU1pYRjFhWEpsUkdWbVlYVnNkQ0lzSW5KbGNYVnBjbVVpTENKZmRYUnBiSE1pTENKbElpd2lYMTlsYzAxdlpIVnNaU0lzSW1SbFptRjFiSFFpTENKblpYUkZiR1Z0Wlc1MFFubEpaQ0lzSW1Wc1pXMWxiblJKWkNJc0ltVnNaVzFsYm5RaUxDSmtiMk4xYldWdWRDSXNJbUZ6YzJWeWRFbHpTVzV6ZEdGdVkyVlBaaUlzSWtoVVRVeEZiR1Z0Wlc1MElpd2laMlYwVTJ4dmRDSXNJbmRwZEdocGJpSXNJbk5zYjNST1lXMWxJaXdpYzJ4dmRITWlMQ0p4ZFdWeWVWTmxiR1ZqZEc5eVFXeHNJaXdpWVhOelpYSjBJaXdpWlhGMVlXd2lMQ0pzWlc1bmRHZ2lMQ0p6WlhSVGJHOTBWR1Y0ZENJc0luTnNiM1JVWlhoMElpd2lkR1Y0ZENJc0lrOWlhbVZqZENJc0ltVnVkSEpwWlhNaUxDSjBaWGgwUTI5dWRHVnVkQ0lzSW1Oc2IyNWxWR1Z0Y0d4aGRHVWlMQ0owWlcxd2JHRjBaU0lzSWtoVVRVeFVaVzF3YkdGMFpVVnNaVzFsYm5RaUxDSmtiMk4xYldWdWRFWnlZV2R0Wlc1MElpd2lZMjl1ZEdWdWRDSXNJbU5zYjI1bFRtOWtaU0lzSWtSdlkzVnRaVzUwUm5KaFoyMWxiblFpTENKbGJHVnRaVzUwVjJsMGFFRmljMjlzZFhSbFVHRjBhSE1pTENKbWNtRm5iV1Z1ZENJc0ltRjBkSEpwWW5WMFpTSXNJbVZzWlcxbGJuUnpJaXdpUVhKeVlYa2lMQ0ptY205dElpd2ljR0YwYUNJc0ltZGxkRUYwZEhKcFluVjBaU0lzSW1GemMyVnlkRWx6UkdWbWFXNWxaQ0lzSW5ObGRFRjBkSEpwWW5WMFpTSXNJbFZTVENJc0lteHZZMkYwYVc5dUlpd2lhSEpsWmlJc0ltZGxkRWhVVFV3aUxDSnpaWEpwWVd4cGVtVnlJaXdpV0UxTVUyVnlhV0ZzYVhwbGNpSXNJbk5sY21saGJHbDZaVlJ2VTNSeWFXNW5JbDBzSW5OdmRYSmpaWE1pT2xzaUxpNHZMaTR2TGk0dmMzSmpMMmh2YldWaWNtbGtaMlV0ZFdrdmNIVmliR2xqTDNWMGFXeHpMV1J2YlM1MGN5SmRMQ0p6YjNWeVkyVnpRMjl1ZEdWdWRDSTZXMjUxYkd4ZExDSnRZWEJ3YVc1bmN5STZJanM3T3pzN096czdPenM3UVVGSFFTeEpRVUZCUVN4UFFVRkJMRWRCUVVGRExITkNRVUZCTEVOQlFVRkRMRTlCUVVFN1FVRkZRU3hKUVVGQlF5eE5RVUZCTEVkQlFVRkVMRTlCUVVFN1FVRkJjVVVzVTBGQlFVUXNkVUpCUVVGSExFTkJRVUVzVjBGQlFVRXNRMEZCUVN4SlFVRkJRU3hEUVVGQkxFTkJRVUZETEZWQlFVRXNSMEZCUVVRc1EwRkJRU3hMUVVGQlJTeFBRVUZCTEVWQlFVRkdMRU5CUVVFN1FVRk1ja1U3UVVGRFFUczdRVUZYUVR0QlFVTk5MRk5CUVZWSExHTkJRV05CTEVOQlFVTkRMRk5CUVdsQ08wVkJRelZETEUxQlFVMURMRTlCUVU4c1IwRkJSME1zVVVGQlVTeERRVUZEU0N4alFVRmpMRU5CUVVORExGTkJRVk1zUTBGQlF6dEZRVU5zUkN4SlFVRkJSeXg1UWtGQmEwSXNSVUZCUTBZc1QwRkJUeXhGUVVGRlJ5eFhRVUZYTEVOQlFVTTdSVUZEZUVNc1QwRkJUMGdzVDBGQlR6dEJRVU5zUWp0QlFVVkJPMEZCUTAwc1UwRkJWVWtzVDBGQlQwRXNRMEZCUTBNc1RVRkJkMElzUlVGQlJVTXNVVUZCWjBJN1JVRkRPVVFzVFVGQlRVTXNTMEZCU3l4SFFVRkhSaXhOUVVGTkxFTkJRVU5ITEdkQ1FVRm5RaXhEUVVGRExGVkJRVlZHTEZGQlFWRXNTVUZCU1N4RFFVRkRPMFZCUXpkRVJ5eGxRVUZOTEVOQlFVTkRMRXRCUVVzc1EwRkJRMGdzUzBGQlN5eERRVUZEU1N4TlFVRk5MRVZCUVVVc1EwRkJReXhGUVVGRkxIZERRVUYzUTB3c1VVRkJVU3hIUVVGSExFTkJRVU03UlVGRGJFWXNTVUZCUVVvc2VVSkJRV3RDTEVWQlFVTkxMRXRCUVVzc1EwRkJReXhEUVVGRExFTkJRVU1zUlVGQlJVb3NWMEZCVnl4RFFVRkRPMFZCUTNwRExFOUJRVTlKTEV0QlFVc3NRMEZCUXl4RFFVRkRMRU5CUVVNN1FVRkRia0k3UVVGRlFUdEJRVU5OTEZOQlFWVkxMRmRCUVZkQkxFTkJRVU5RTEUxQlFYZENMRVZCUVVWUkxGRkJRV2RETzBWQlEyeEdMRXRCUVVzc1RVRkJUU3hEUVVGRFVDeFJRVUZSTEVWQlFVVlJMRWxCUVVrc1EwRkJReXhKUVVGSlF5eE5RVUZOTEVOQlFVTkRMRTlCUVU4c1EwRkJRMGdzVVVGQlVTeERRVUZETEVWQlEyNUVWQ3hQUVVGUExFTkJRVU5ETEUxQlFVMHNSVUZCUlVNc1VVRkJVU3hEUVVGRExFTkJRVU5YTEZkQlFWY3NSMEZCUjBnc1NVRkJTVHRCUVVOd1JEdEJRVVZCTzBGQlEwMHNVMEZCVlVrc1lVRkJZVUVzUTBGQlEyNUNMRk5CUVdsQ0xFVkJRVVZqTEZGQlFXbERPMFZCUXpsRk8wVkJRMEVzVFVGQlRVMHNVVUZCVVN4SFFVRkhiRUlzVVVGQlVTeERRVUZEU0N4alFVRmpMRU5CUVVORExGTkJRVk1zUTBGQlF6dEZRVU51UkN4SlFVRkJSeXg1UWtGQmEwSXNSVUZCUTJsQ0xGRkJRVkVzUlVGQlJVTXNiVUpCUVcxQ0xFTkJRVU03UlVGRmFrUTdSVUZEUVN4TlFVRk5ReXhuUWtGQlowSXNSMEZCUjBZc1VVRkJVU3hEUVVGRFJ5eFBRVUZQTEVOQlFVTkRMRk5CUVZNc1EwRkJReXhKUVVGSkxFTkJRVU03UlVGRGVrUXNTVUZCUVhKQ0xIbENRVUZyUWl4RlFVRkRiVUlzWjBKQlFXZENMRVZCUVVWSExHZENRVUZuUWl4RFFVRkRPMFZCUTNSRUxFbEJRVWxZTEZGQlFWRXNSVUZCUlVRc1YwRkJWeXhEUVVGRFV5eG5Ra0ZCWjBJc1JVRkJSVklzVVVGQlVTeERRVUZETzBWQlEzSkVMRTlCUVU5UkxHZENRVUZuUWp0QlFVTXpRanRCUVVWQk8wRkJRMDBzVTBGQlZVa3NkMEpCUVhkQ1FTeERRVUZuUTBNc1VVRkJZenRGUVVOc1JpeExRVUZMTEUxQlFVMURMRk5CUVZNc1NVRkJTU3hEUVVGRExFMUJRVTBzUlVGQlJTeExRVUZMTEVOQlFVTXNSVUZCUlR0SlFVTnlReXhOUVVGTlF5eFJRVUZSTEVkQlFVZEdMRkZCUVZFc1EwRkJRMnhDTEdkQ1FVRm5RaXhEUVVGRExFbEJRVWx0UWl4VFFVRlRMRWRCUVVjc1EwRkJRenRKUVVNMVJDeExRVUZMTEUxQlFVMHpRaXhQUVVGUExFbEJRVWsyUWl4TFFVRkxMRU5CUVVORExFbEJRVWtzUTBGQlEwWXNVVUZCVVN4RFFVRkRMRVZCUVVVN1RVRkRlRU1zVFVGQlRVY3NTVUZCU1N4SFFVRkhMMElzVDBGQlR5eERRVUZEWjBNc1dVRkJXU3hEUVVGRFRDeFRRVUZUTEVOQlFVTTdUVUZETlVNc1NVRkJRVTBzYzBKQlFXVXNSVUZCUTBZc1NVRkJTU3hEUVVGRE8wMUJRM0pDTDBJc1QwRkJUeXhEUVVGRGEwTXNXVUZCV1N4RFFVRkRVQ3hUUVVGVExFVkJRVVVzU1VGQlNWRXNSMEZCUnl4RFFVRkRTaXhKUVVGSkxFVkJRVVZMTEZGQlFWRXNRMEZCUTBNc1NVRkJTU3hEUVVGRExFTkJRVU5CTEVsQlFVa3NRMEZCUXp0SlFVTjBSVHRGUVVOS08wVkJRMEVzVDBGQlQxZ3NVVUZCVVR0QlFVTnVRanRCUVVWQk8wRkJRMDBzVTBGQlZWa3NUMEZCVDBFc1EwRkJRMW9zVVVGQll6dEZRVU5zUXl4TlFVRk5ZU3hWUVVGVkxFZEJRVWNzU1VGQlNVTXNZVUZCWVN4RlFVRkZPMFZCUTNSRExFOUJRVTlFTEZWQlFWVXNRMEZCUTBVc2FVSkJRV2xDTEVOQlFVTm1MRkZCUVZFc1EwRkJRenRCUVVOcVJDSXNJbWxuYm05eVpVeHBjM1FpT2x0ZGZRPT0iLCJcInVzZSBzdHJpY3RcIjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGV0YWNoZWQgPSBkZXRhY2hlZDtcbmV4cG9ydHMubG9nRXJyb3IgPSBsb2dFcnJvcjtcbnZhciBfYXBpRXJyb3JzID0gcmVxdWlyZShcIi4vYXBpLWVycm9ycy5qc1wiKTtcbi8vIEhvbWVicmlkZ2UgcGx1Z2luIGZvciBIb21lIENvbm5lY3QgaG9tZSBhcHBsaWFuY2VzXG4vLyBDb3B5cmlnaHQgwqkgMjAyMy0yMDI2IEFsZXhhbmRlciBUaG91a3lkaWRlc1xuXG4vLyBMb2cgYW4gZXJyb3JcbmxldCBsYXN0TG9nZ2VkRXJyb3I7XG5mdW5jdGlvbiBsb2dFcnJvcihsb2csIHdoZW4sIGVycikge1xuICB0cnkge1xuICAgIC8vIFN1cHByZXNzIGR1cGxpY2F0ZSByZXBvcnRzXG4gICAgaWYgKGxhc3RMb2dnZWRFcnJvciA9PT0gZXJyKSByZXR1cm4gZXJyO1xuICAgIGxhc3RMb2dnZWRFcnJvciA9IGVycjtcbiAgICAvLyBMb2cgdGhlIHRvcC1sZXZlbCBlcnJvciBtZXNzYWdlXG4gICAgY29uc3QgbWVzc2FnZSA9IGVyciBpbnN0YW5jZW9mIEVycm9yID8gYCR7ZXJyLm5hbWV9OiAke2Vyci5tZXNzYWdlfWAgOiBTdHJpbmcoZXJyKTtcbiAgICBsb2cuZXJyb3IoYFske3doZW59XSAke21lc3NhZ2V9YCk7XG4gICAgY29uc3QgcHJlZml4ID0gJyAnLnJlcGVhdCh3aGVuLmxlbmd0aCArIDMpO1xuICAgIC8vIExvZyB0aGUgcmVxdWVzdCBkZXRhaWxzIGZvciBBUEkgZXJyb3JzXG4gICAgaWYgKGVyciBpbnN0YW5jZW9mIF9hcGlFcnJvcnMuQVBJRXJyb3IpIHtcbiAgICAgIGxvZy5lcnJvcihgJHtlcnIucmVxdWVzdC5tZXRob2R9ICR7ZXJyLnJlcXVlc3QucGF0aH1gKTtcbiAgICB9XG4gICAgLy8gTG9nIGFueSBoaXN0b3J5IG9mIGNhdXNlcyBvciBzdWItZXJyb3JzXG4gICAgbG9nU3ViRXJyb3JzKGxvZywgcHJlZml4LCBlcnIpO1xuICAgIC8vIExvZyBhbnkgc3RhY2sgYmFja3RyYWNlIChmb3IgdGhlIHRvcC1sZXZlbCBlcnJvciBvbmx5KVxuICAgIGlmIChlcnIgaW5zdGFuY2VvZiBFcnJvciAmJiBlcnIuc3RhY2spIGxvZy5kZWJ1ZyhlcnIuc3RhY2spO1xuICB9IGNhdGNoIHsvKiBlbXB0eSAqL31cbiAgcmV0dXJuIGVycjtcbn1cbi8vIFRyYXAgYW55IGRldGFjaGVkIHByb21pc2UgcmVqZWN0aW9uc1xuZnVuY3Rpb24gZGV0YWNoZWQobG9nLCB3aGVuLCBmbikge1xuICByZXR1cm4gKC4uLmFyZ3MpID0+IHtcbiAgICBmbiguLi5hcmdzKT8uY2F0Y2goZXJyID0+IGxvZ0Vycm9yKGxvZywgd2hlbiwgZXJyKSk7XG4gIH07XG59XG4vLyBMb2cgYW55IHN1Yi1lcnJvcnMgKGNhdXNlcyBvciBhZ2dyZWdhdGVzKSBvZiBhbiBlcnJvciwgZm9ybWF0dGVkIGFzIGEgdHJlZVxuZnVuY3Rpb24gbG9nU3ViRXJyb3JzKGxvZywgcHJlZml4LCBlcnIpIHtcbiAgLy8gQ29sbGVjdCBhbGwgYWdncmVnYXRlIG9yIGNhdXNhbCBlcnJvcnNcbiAgY29uc3Qgc3ViRXJycyA9IFtdO1xuICBpZiAoZXJyIGluc3RhbmNlb2YgX2FwaUVycm9ycy5BUElFcnJvciAmJiBlcnIuZXJyQ2F1c2UpIHN1YkVycnMucHVzaChlcnIuZXJyQ2F1c2UpO1xuICBpZiAoZXJyIGluc3RhbmNlb2YgRXJyb3IgJiYgZXJyLmNhdXNlKSBzdWJFcnJzLnB1c2goZXJyLmNhdXNlKTtcbiAgaWYgKGVyciBpbnN0YW5jZW9mIEFnZ3JlZ2F0ZUVycm9yICYmIEFycmF5LmlzQXJyYXkoZXJyLmVycm9ycykpIHN1YkVycnMucHVzaCguLi5lcnIuZXJyb3JzKTtcbiAgLy8gTG9nIHRoZSBjb2xsZWN0ZWQgZXJyb3JzIGZvcm1hdHRlZCBhcyBhIHRyZWVcbiAgc3ViRXJycy5mb3JFYWNoKChzdWJFcnIsIGluZGV4KSA9PiB7XG4gICAgY29uc3Qgc3ViUHJlZml4ID0gaW5kZXggPCBzdWJFcnJzLmxlbmd0aCAtIDEgPyBbJ+KUnOKUgCcsICfilIIgJ10gOiBbJ+KUlOKUgCcsICcgICddO1xuICAgIGNvbnN0IG1lc3NhZ2UgPSBzdWJFcnIgaW5zdGFuY2VvZiBFcnJvciA/IGAke3N1YkVyci5uYW1lfTogJHtzdWJFcnIubWVzc2FnZX1gIDogU3RyaW5nKHN1YkVycik7XG4gICAgbG9nLmVycm9yKGAke3ByZWZpeH0ke3N1YlByZWZpeFswXX0gJHttZXNzYWdlfWApO1xuICAgIGxvZ1N1YkVycm9ycyhsb2csIGAke3ByZWZpeH0ke3N1YlByZWZpeFsxXX0gYCwgc3ViRXJyKTtcbiAgfSk7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldD11dGYtODtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnVZVzFsY3lJNld5SmZZWEJwUlhKeWIzSnpJaXdpY21WeGRXbHlaU0lzSW14aGMzUk1iMmRuWldSRmNuSnZjaUlzSW14dlowVnljbTl5SWl3aWJHOW5JaXdpZDJobGJpSXNJbVZ5Y2lJc0ltMWxjM05oWjJVaUxDSkZjbkp2Y2lJc0ltNWhiV1VpTENKVGRISnBibWNpTENKbGNuSnZjaUlzSW5CeVpXWnBlQ0lzSW5KbGNHVmhkQ0lzSW14bGJtZDBhQ0lzSWtGUVNVVnljbTl5SWl3aWNtVnhkV1Z6ZENJc0ltMWxkR2h2WkNJc0luQmhkR2dpTENKc2IyZFRkV0pGY25KdmNuTWlMQ0p6ZEdGamF5SXNJbVJsWW5Wbklpd2laR1YwWVdOb1pXUWlMQ0ptYmlJc0ltRnlaM01pTENKallYUmphQ0lzSW5OMVlrVnljbk1pTENKbGNuSkRZWFZ6WlNJc0luQjFjMmdpTENKallYVnpaU0lzSWtGblozSmxaMkYwWlVWeWNtOXlJaXdpUVhKeVlYa2lMQ0pwYzBGeWNtRjVJaXdpWlhKeWIzSnpJaXdpWm05eVJXRmphQ0lzSW5OMVlrVnljaUlzSW1sdVpHVjRJaXdpYzNWaVVISmxabWw0SWwwc0luTnZkWEpqWlhNaU9sc2lMaTR2YzNKakwyeHZaeTFsY25KdmNpNTBjeUpkTENKemIzVnlZMlZ6UTI5dWRHVnVkQ0k2VzI1MWJHeGRMQ0p0WVhCd2FXNW5jeUk2SWpzN096czdPenRCUVV0QkxFbEJRVUZCTEZWQlFVRXNSMEZCUVVNc1QwRkJRVHRCUVV4Qk8wRkJRMEU3TzBGQlQwRTdRVUZEUVN4SlFVRkpReXhsUVVGM1FqdEJRVU4wUWl4VFFVRlZReXhSUVVGUlFTeERRVUZQUXl4SFFVRlhMRVZCUVVWRExFbEJRVmtzUlVGQlJVTXNSMEZCVXp0RlFVTXZSQ3hKUVVGSk8wbEJRMEU3U1VGRFFTeEpRVUZKU2l4bFFVRmxMRXRCUVV0SkxFZEJRVWNzUlVGQlJTeFBRVUZQUVN4SFFVRkhPMGxCUTNaRFNpeGxRVUZsTEVkQlFVZEpMRWRCUVVjN1NVRkZja0k3U1VGRFFTeE5RVUZOUXl4UFFVRlBMRWRCUVVkRUxFZEJRVWNzV1VGQldVVXNTMEZCU3l4SFFVRkhMRWRCUVVkR0xFZEJRVWNzUTBGQlEwY3NTVUZCU1N4TFFVRkxTQ3hIUVVGSExFTkJRVU5ETEU5QlFVOHNSVUZCUlN4SFFVRkhSeXhOUVVGTkxFTkJRVU5LTEVkQlFVY3NRMEZCUXp0SlFVTnNSa1lzUjBGQlJ5eERRVUZEVHl4TFFVRkxMRU5CUVVNc1NVRkJTVTRzU1VGQlNTeExRVUZMUlN4UFFVRlBMRVZCUVVVc1EwRkJRenRKUVVOcVF5eE5RVUZOU3l4TlFVRk5MRWRCUVVjc1IwRkJSeXhEUVVGRFF5eE5RVUZOTEVOQlFVTlNMRWxCUVVrc1EwRkJRMU1zVFVGQlRTeEhRVUZITEVOQlFVTXNRMEZCUXp0SlFVVXhRenRKUVVOQkxFbEJRVWxTTEVkQlFVY3NXVUZCV1ZNc2JVSkJRVkVzUlVGQlJUdE5RVU42UWxnc1IwRkJSeXhEUVVGRFR5eExRVUZMTEVOQlFVTXNSMEZCUjB3c1IwRkJSeXhEUVVGRFZTeFBRVUZQTEVOQlFVTkRMRTFCUVUwc1NVRkJTVmdzUjBGQlJ5eERRVUZEVlN4UFFVRlBMRU5CUVVORkxFbEJRVWtzUlVGQlJTeERRVUZETzBsQlF6RkVPMGxCUlVFN1NVRkRRVU1zV1VGQldTeERRVUZEWml4SFFVRkhMRVZCUVVWUkxFMUJRVTBzUlVGQlJVNHNSMEZCUnl4RFFVRkRPMGxCUlRsQ08wbEJRMEVzU1VGQlNVRXNSMEZCUnl4WlFVRlpSU3hMUVVGTExFbEJRVWxHTEVkQlFVY3NRMEZCUTJNc1MwRkJTeXhGUVVGRmFFSXNSMEZCUnl4RFFVRkRhVUlzUzBGQlN5eERRVUZEWml4SFFVRkhMRU5CUVVOakxFdEJRVXNzUTBGQlF6dEZRVU12UkN4RFFVRkRMRU5CUVVNc1RVRkJUU3hEUVVGRk8wVkJRMVlzVDBGQlQyUXNSMEZCUnp0QlFVTmtPMEZCUlVFN1FVRkRUU3hUUVVGVlowSXNVVUZCVVVFc1EwRkRjRUpzUWl4SFFVRmpMRVZCUTJSRExFbEJRV01zUlVGRFpHdENMRVZCUVhWRE8wVkJSWFpETEU5QlFVOHNRMEZCUXl4SFFVRkhReXhKUVVGVkxFdEJRVWs3U1VGRGNrSkVMRVZCUVVVc1EwRkJReXhIUVVGSFF5eEpRVUZKTEVOQlFVTXNSVUZCUlVNc1MwRkJTeXhEUVVGRmJrSXNSMEZCV1N4SlFVRkxTQ3hSUVVGUkxFTkJRVU5ETEVkQlFVY3NSVUZCUlVNc1NVRkJTU3hGUVVGRlF5eEhRVUZITEVOQlFVTXNRMEZCUXp0RlFVTnNSU3hEUVVGRE8wRkJRMHc3UVVGRlFUdEJRVU5CTEZOQlFWTmhMRmxCUVZsQkxFTkJRVU5tTEVkQlFWY3NSVUZCUlZFc1RVRkJZeXhGUVVGRlRpeEhRVUZaTzBWQlF6TkVPMFZCUTBFc1RVRkJUVzlDTEU5QlFVOHNSMEZCWXl4RlFVRkZPMFZCUXpkQ0xFbEJRVWx3UWl4SFFVRkhMRmxCUVZsVExHMUNRVUZSTEVsQlFVbFVMRWRCUVVjc1EwRkJRM0ZDTEZGQlFWRXNSVUZCUlVRc1QwRkJUeXhEUVVGRFJTeEpRVUZKTEVOQlFVTjBRaXhIUVVGSExFTkJRVU54UWl4UlFVRlJMRU5CUVVNN1JVRkRka1VzU1VGQlNYSkNMRWRCUVVjc1dVRkJXVVVzUzBGQlN5eEpRVUZKUml4SFFVRkhMRU5CUVVOMVFpeExRVUZMTEVWQlFVVklMRTlCUVU4c1EwRkJRMFVzU1VGQlNTeERRVUZEZEVJc1IwRkJSeXhEUVVGRGRVSXNTMEZCU3l4RFFVRkRPMFZCUXpsRUxFbEJRVWwyUWl4SFFVRkhMRmxCUVZsM1FpeGpRVUZqTEVsQlFVbERMRXRCUVVzc1EwRkJRME1zVDBGQlR5eERRVUZETVVJc1IwRkJSeXhEUVVGRE1rSXNUVUZCVFN4RFFVRkRMRVZCUVVWUUxFOUJRVThzUTBGQlEwVXNTVUZCU1N4RFFVRkRMRWRCUVVsMFFpeEhRVUZITEVOQlFVTXlRaXhOUVVGdlFpeERRVUZETzBWQlJURkhPMFZCUTBGUUxFOUJRVThzUTBGQlExRXNUMEZCVHl4RFFVRkRMRU5CUVVORExFMUJRVTBzUlVGQlJVTXNTMEZCU3l4TFFVRkpPMGxCUXpsQ0xFMUJRVTFETEZOQlFWTXNSMEZCUjBRc1MwRkJTeXhIUVVGSFZpeFBRVUZQTEVOQlFVTmFMRTFCUVUwc1IwRkJSeXhEUVVGRExFZEJRVWNzUTBGQlF5eEpRVUZKTEVWQlFVVXNTVUZCU1N4RFFVRkRMRWRCUVVjc1EwRkJReXhKUVVGSkxFVkJRVVVzU1VGQlNTeERRVUZETzBsQlF6RkZMRTFCUVUxUUxFOUJRVThzUjBGQlJ6UkNMRTFCUVUwc1dVRkJXVE5DTEV0QlFVc3NSMEZCUnl4SFFVRkhNa0lzVFVGQlRTeERRVUZETVVJc1NVRkJTU3hMUVVGTE1FSXNUVUZCVFN4RFFVRkROVUlzVDBGQlR5eEZRVUZGTEVkQlFVZEhMRTFCUVUwc1EwRkJRM2xDTEUxQlFVMHNRMEZCUXp0SlFVTTVSaTlDTEVkQlFVY3NRMEZCUTA4c1MwRkJTeXhEUVVGRExFZEJRVWRETEUxQlFVMHNSMEZCUjNsQ0xGTkJRVk1zUTBGQlF5eERRVUZETEVOQlFVTXNTVUZCU1RsQ0xFOUJRVThzUlVGQlJTeERRVUZETzBsQlEyaEVXU3haUVVGWkxFTkJRVU5tTEVkQlFVY3NSVUZCUlN4SFFVRkhVU3hOUVVGTkxFZEJRVWQ1UWl4VFFVRlRMRU5CUVVNc1EwRkJReXhEUVVGRExFZEJRVWNzUlVGQlJVWXNUVUZCVFN4RFFVRkRPMFZCUXpGRUxFTkJRVU1zUTBGQlF6dEJRVU5PSWl3aWFXZHViM0psVEdsemRDSTZXMTE5IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSBleHBvcnRzLlNjb3BlID0gZXhwb3J0cy5QZXJzaXN0QWJzb2x1dGVUb2tlbnMgPSBleHBvcnRzLkRldmljZUF1dGhvcmlzYXRpb25SZXNwb25zZSA9IGV4cG9ydHMuRGV2aWNlQXV0aG9yaXNhdGlvblJlcXVlc3QgPSBleHBvcnRzLkRldmljZUFjY2Vzc1Rva2VuUmVzcG9uc2UgPSBleHBvcnRzLkRldmljZUFjY2Vzc1Rva2VuUmVxdWVzdCA9IGV4cG9ydHMuQXV0aG9yaXNhdGlvblN0YXRlID0gZXhwb3J0cy5BdXRob3Jpc2F0aW9uUmVzcG9uc2UgPSBleHBvcnRzLkF1dGhvcmlzYXRpb25SZXF1ZXN0ID0gZXhwb3J0cy5BdXRob3Jpc2F0aW9uRXJyb3IgPSBleHBvcnRzLkFjY2Vzc1Rva2VuUmVzcG9uc2UgPSBleHBvcnRzLkFjY2Vzc1Rva2VuUmVxdWVzdCA9IGV4cG9ydHMuQWNjZXNzVG9rZW5SZWZyZXNoUmVzcG9uc2UgPSBleHBvcnRzLkFjY2Vzc1Rva2VuUmVmcmVzaFJlcXVlc3QgPSBleHBvcnRzLkFic29sdXRlVG9rZW4gPSB2b2lkIDA7XG52YXIgdCA9IF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkKHJlcXVpcmUoXCJ0cy1pbnRlcmZhY2UtY2hlY2tlclwiKSk7XG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZChlLCB0KSB7IGlmIChcImZ1bmN0aW9uXCIgPT0gdHlwZW9mIFdlYWtNYXApIHZhciByID0gbmV3IFdlYWtNYXAoKSwgbiA9IG5ldyBXZWFrTWFwKCk7IHJldHVybiAoX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQgPSBmdW5jdGlvbiAoZSwgdCkgeyBpZiAoIXQgJiYgZSAmJiBlLl9fZXNNb2R1bGUpIHJldHVybiBlOyB2YXIgbywgaSwgZiA9IHsgX19wcm90b19fOiBudWxsLCBkZWZhdWx0OiBlIH07IGlmIChudWxsID09PSBlIHx8IFwib2JqZWN0XCIgIT0gdHlwZW9mIGUgJiYgXCJmdW5jdGlvblwiICE9IHR5cGVvZiBlKSByZXR1cm4gZjsgaWYgKG8gPSB0ID8gbiA6IHIpIHsgaWYgKG8uaGFzKGUpKSByZXR1cm4gby5nZXQoZSk7IG8uc2V0KGUsIGYpOyB9IGZvciAoY29uc3QgdCBpbiBlKSBcImRlZmF1bHRcIiAhPT0gdCAmJiB7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGUsIHQpICYmICgoaSA9IChvID0gT2JqZWN0LmRlZmluZVByb3BlcnR5KSAmJiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGUsIHQpKSAmJiAoaS5nZXQgfHwgaS5zZXQpID8gbyhmLCB0LCBpKSA6IGZbdF0gPSBlW3RdKTsgcmV0dXJuIGY7IH0pKGUsIHQpOyB9XG4vKipcbiAqIFRoaXMgbW9kdWxlIHdhcyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBieSBgdHMtaW50ZXJmYWNlLWJ1aWxkZXJgXG4gKi9cblxuLy8gdHNsaW50OmRpc2FibGU6b2JqZWN0LWxpdGVyYWwta2V5LXF1b3Rlc1xuY29uc3QgU2NvcGUgPSBleHBvcnRzLlNjb3BlID0gdC51bmlvbih0LmxpdCgnTW9uaXRvcicpLCB0LmxpdCgnQ29udHJvbCcpLCB0LmxpdCgnU2V0dGluZ3MnKSwgdC5saXQoJ0ltYWdlcycpLCB0LmxpdCgnQWlyQ29uZGl0aW9uZXInKSwgdC5saXQoJ0FpckNvbmRpdGlvbmVyLU1vbml0b3InKSwgdC5saXQoJ0FpckNvbmRpdGlvbmVyLUNvbnRyb2wnKSwgdC5saXQoJ0FpckNvbmRpdGlvbmVyLVNldHRpbmdzJyksIHQubGl0KCdDbGVhbmluZ1JvYm90JyksIHQubGl0KCdDbGVhbmluZ1JvYm90LU1vbml0b3InKSwgdC5saXQoJ0NsZWFuaW5nUm9ib3QtQ29udHJvbCcpLCB0LmxpdCgnQ2xlYW5pbmdSb2JvdC1TZXR0aW5ncycpLCB0LmxpdCgnQ29mZmVlTWFrZXInKSwgdC5saXQoJ0NvZmZlZU1ha2VyLU1vbml0b3InKSwgdC5saXQoJ0NvZmZlZU1ha2VyLUNvbnRyb2wnKSwgdC5saXQoJ0NvZmZlZU1ha2VyLVNldHRpbmdzJyksIHQubGl0KCdDb29rUHJvY2Vzc29yJyksIHQubGl0KCdDb29rUHJvY2Vzc29yLU1vbml0b3InKSwgdC5saXQoJ0Nvb2tQcm9jZXNzb3ItQ29udHJvbCcpLCB0LmxpdCgnQ29va1Byb2Nlc3Nvci1TZXR0aW5ncycpLCB0LmxpdCgnRGlzaHdhc2hlcicpLCB0LmxpdCgnRGlzaHdhc2hlci1Nb25pdG9yJyksIHQubGl0KCdEaXNod2FzaGVyLUNvbnRyb2wnKSwgdC5saXQoJ0Rpc2h3YXNoZXItU2V0dGluZ3MnKSwgdC5saXQoJ0RyeWVyJyksIHQubGl0KCdEcnllci1Nb25pdG9yJyksIHQubGl0KCdEcnllci1Db250cm9sJyksIHQubGl0KCdEcnllci1TZXR0aW5ncycpLCB0LmxpdCgnRnJlZXplcicpLCB0LmxpdCgnRnJlZXplci1Nb25pdG9yJyksIHQubGl0KCdGcmVlemVyLUNvbnRyb2wnKSwgdC5saXQoJ0ZyZWV6ZXItU2V0dGluZ3MnKSwgdC5saXQoJ0ZyaWRnZUZyZWV6ZXInKSwgdC5saXQoJ0ZyaWRnZUZyZWV6ZXItTW9uaXRvcicpLCB0LmxpdCgnRnJpZGdlRnJlZXplci1Db250cm9sJyksIHQubGl0KCdGcmlkZ2VGcmVlemVyLVNldHRpbmdzJyksIHQubGl0KCdGcmlkZ2VGcmVlemVyLUltYWdlcycpLCB0LmxpdCgnSG9iJyksIHQubGl0KCdIb2ItTW9uaXRvcicpLCB0LmxpdCgnSG9iLUNvbnRyb2wnKSwgdC5saXQoJ0hvYi1TZXR0aW5ncycpLCB0LmxpdCgnSG9vZCcpLCB0LmxpdCgnSG9vZC1Nb25pdG9yJyksIHQubGl0KCdIb29kLUNvbnRyb2wnKSwgdC5saXQoJ0hvb2QtU2V0dGluZ3MnKSwgdC5saXQoJ01pY3Jvd2F2ZScpLCB0LmxpdCgnTWljcm93YXZlLU1vbml0b3InKSwgdC5saXQoJ01pY3Jvd2F2ZS1Db250cm9sJyksIHQubGl0KCdNaWNyb3dhdmUtU2V0dGluZ3MnKSwgdC5saXQoJ092ZW4nKSwgdC5saXQoJ092ZW4tTW9uaXRvcicpLCB0LmxpdCgnT3Zlbi1Db250cm9sJyksIHQubGl0KCdPdmVuLVNldHRpbmdzJyksIHQubGl0KCdSZWZyaWdlcmF0b3InKSwgdC5saXQoJ1JlZnJpZ2VyYXRvci1Nb25pdG9yJyksIHQubGl0KCdSZWZyaWdlcmF0b3ItQ29udHJvbCcpLCB0LmxpdCgnUmVmcmlnZXJhdG9yLVNldHRpbmdzJyksIHQubGl0KCdXYXNoZXInKSwgdC5saXQoJ1dhc2hlci1Nb25pdG9yJyksIHQubGl0KCdXYXNoZXItQ29udHJvbCcpLCB0LmxpdCgnV2FzaGVyLVNldHRpbmdzJyksIHQubGl0KCdXYXNoZXJEcnllcicpLCB0LmxpdCgnV2FzaGVyRHJ5ZXItTW9uaXRvcicpLCB0LmxpdCgnV2FzaGVyRHJ5ZXItQ29udHJvbCcpLCB0LmxpdCgnV2FzaGVyRHJ5ZXItU2V0dGluZ3MnKSwgdC5saXQoJ1dpbmVDb29sZXInKSwgdC5saXQoJ1dpbmVDb29sZXItTW9uaXRvcicpLCB0LmxpdCgnV2luZUNvb2xlci1Db250cm9sJyksIHQubGl0KCdXaW5lQ29vbGVyLVNldHRpbmdzJykpO1xuY29uc3QgQXV0aG9yaXNhdGlvblJlcXVlc3QgPSBleHBvcnRzLkF1dGhvcmlzYXRpb25SZXF1ZXN0ID0gdC5pZmFjZShbXSwge1xuICBcImNsaWVudF9pZFwiOiBcInN0cmluZ1wiLFxuICBcInJlZGlyZWN0X3VyaVwiOiB0Lm9wdChcInN0cmluZ1wiKSxcbiAgXCJyZXNwb25zZV90eXBlXCI6IHQubGl0KCdjb2RlJyksXG4gIFwic2NvcGVcIjogdC5vcHQoXCJzdHJpbmdcIiksXG4gIFwic3RhdGVcIjogdC5vcHQoXCJBdXRob3Jpc2F0aW9uU3RhdGVcIiksXG4gIFwibm9uY2VcIjogdC5vcHQoXCJzdHJpbmdcIiksXG4gIFwiY29kZV9jaGFsbGVuZ2VcIjogdC5vcHQoXCJzdHJpbmdcIiksXG4gIFwiY29kZV9jaGFsbGVuZ2VfbWV0aG9kXCI6IHQub3B0KHQudW5pb24odC5saXQoJ3BsYWluJyksIHQubGl0KCdTMjU2JykpKVxufSk7XG5jb25zdCBBdXRob3Jpc2F0aW9uU3RhdGUgPSBleHBvcnRzLkF1dGhvcmlzYXRpb25TdGF0ZSA9IHQudW5pb24oXCJzdHJpbmdcIiwgXCJudW1iZXJcIik7XG5jb25zdCBBdXRob3Jpc2F0aW9uUmVzcG9uc2UgPSBleHBvcnRzLkF1dGhvcmlzYXRpb25SZXNwb25zZSA9IHQuaWZhY2UoW10sIHtcbiAgXCJjb2RlXCI6IFwic3RyaW5nXCIsXG4gIFwiZ3JhbnRfdHlwZVwiOiB0Lm9wdCh0LmxpdCgnYXV0aG9yaXphdGlvbl9jb2RlJykpLFxuICBcInN0YXRlXCI6IHQub3B0KFwiQXV0aG9yaXNhdGlvblN0YXRlXCIpXG59KTtcbmNvbnN0IEFjY2Vzc1Rva2VuUmVxdWVzdCA9IGV4cG9ydHMuQWNjZXNzVG9rZW5SZXF1ZXN0ID0gdC5pZmFjZShbXSwge1xuICBcImNsaWVudF9pZFwiOiBcInN0cmluZ1wiLFxuICBcImNsaWVudF9zZWNyZXRcIjogdC5vcHQoXCJzdHJpbmdcIiksXG4gIFwicmVkaXJlY3RfdXJpXCI6IHQub3B0KFwic3RyaW5nXCIpLFxuICBcImdyYW50X3R5cGVcIjogdC5saXQoJ2F1dGhvcml6YXRpb25fY29kZScpLFxuICBcImNvZGVcIjogXCJzdHJpbmdcIixcbiAgXCJjb2RlX3ZlcmlmaWVyXCI6IHQub3B0KFwic3RyaW5nXCIpXG59KTtcbmNvbnN0IEFjY2Vzc1Rva2VuUmVzcG9uc2UgPSBleHBvcnRzLkFjY2Vzc1Rva2VuUmVzcG9uc2UgPSB0LmlmYWNlKFtdLCB7XG4gIFwiaWRfdG9rZW5cIjogXCJzdHJpbmdcIixcbiAgXCJhY2Nlc3NfdG9rZW5cIjogXCJzdHJpbmdcIixcbiAgXCJleHBpcmVzX2luXCI6IFwibnVtYmVyXCIsXG4gIFwic2NvcGVcIjogXCJzdHJpbmdcIixcbiAgXCJyZWZyZXNoX3Rva2VuXCI6IFwic3RyaW5nXCIsXG4gIFwidG9rZW5fdHlwZVwiOiB0Lm9wdCh0LmxpdCgnQmVhcmVyJykpXG59KTtcbmNvbnN0IERldmljZUF1dGhvcmlzYXRpb25SZXF1ZXN0ID0gZXhwb3J0cy5EZXZpY2VBdXRob3Jpc2F0aW9uUmVxdWVzdCA9IHQuaWZhY2UoW10sIHtcbiAgXCJjbGllbnRfaWRcIjogXCJzdHJpbmdcIixcbiAgXCJzY29wZVwiOiB0Lm9wdChcInN0cmluZ1wiKVxufSk7XG5jb25zdCBEZXZpY2VBdXRob3Jpc2F0aW9uUmVzcG9uc2UgPSBleHBvcnRzLkRldmljZUF1dGhvcmlzYXRpb25SZXNwb25zZSA9IHQuaWZhY2UoW10sIHtcbiAgXCJkZXZpY2VfY29kZVwiOiBcInN0cmluZ1wiLFxuICBcInVzZXJfY29kZVwiOiBcInN0cmluZ1wiLFxuICBcInZlcmlmaWNhdGlvbl91cmlcIjogXCJzdHJpbmdcIixcbiAgXCJ2ZXJpZmljYXRpb25fdXJpX2NvbXBsZXRlXCI6IHQub3B0KFwic3RyaW5nXCIpLFxuICBcImV4cGlyZXNfaW5cIjogdC5vcHQoXCJudW1iZXJcIiksXG4gIFwiaW50ZXJ2YWxcIjogdC5vcHQoXCJudW1iZXJcIilcbn0pO1xuY29uc3QgRGV2aWNlQWNjZXNzVG9rZW5SZXF1ZXN0ID0gZXhwb3J0cy5EZXZpY2VBY2Nlc3NUb2tlblJlcXVlc3QgPSB0LmlmYWNlKFtdLCB7XG4gIFwiZ3JhbnRfdHlwZVwiOiB0LnVuaW9uKHQubGl0KCd1cm46aWV0ZjpwYXJhbXM6b2F1dGg6Z3JhbnQtdHlwZTpkZXZpY2VfY29kZScpLCB0LmxpdCgnZGV2aWNlX2NvZGUnKSksXG4gIFwiZGV2aWNlX2NvZGVcIjogXCJzdHJpbmdcIixcbiAgXCJjbGllbnRfaWRcIjogXCJzdHJpbmdcIixcbiAgXCJjbGllbnRfc2VjcmV0XCI6IHQub3B0KFwic3RyaW5nXCIpXG59KTtcbmNvbnN0IERldmljZUFjY2Vzc1Rva2VuUmVzcG9uc2UgPSBleHBvcnRzLkRldmljZUFjY2Vzc1Rva2VuUmVzcG9uc2UgPSB0LmlmYWNlKFtdLCB7XG4gIFwiaWRfdG9rZW5cIjogXCJzdHJpbmdcIixcbiAgXCJhY2Nlc3NfdG9rZW5cIjogXCJzdHJpbmdcIixcbiAgXCJleHBpcmVzX2luXCI6IFwibnVtYmVyXCIsXG4gIFwic2NvcGVcIjogXCJzdHJpbmdcIixcbiAgXCJyZWZyZXNoX3Rva2VuXCI6IFwic3RyaW5nXCIsXG4gIFwidG9rZW5fdHlwZVwiOiB0Lm9wdCh0LmxpdCgnQmVhcmVyJykpXG59KTtcbmNvbnN0IEFjY2Vzc1Rva2VuUmVmcmVzaFJlcXVlc3QgPSBleHBvcnRzLkFjY2Vzc1Rva2VuUmVmcmVzaFJlcXVlc3QgPSB0LmlmYWNlKFtdLCB7XG4gIFwiZ3JhbnRfdHlwZVwiOiB0LmxpdCgncmVmcmVzaF90b2tlbicpLFxuICBcInJlZnJlc2hfdG9rZW5cIjogXCJzdHJpbmdcIixcbiAgXCJjbGllbnRfc2VjcmV0XCI6IHQub3B0KFwic3RyaW5nXCIpLFxuICBcInNjb3BlXCI6IHQub3B0KFwic3RyaW5nXCIpLFxuICBcImV4cGlyZXNfaW5cIjogdC5vcHQoXCJudW1iZXJcIilcbn0pO1xuY29uc3QgQWNjZXNzVG9rZW5SZWZyZXNoUmVzcG9uc2UgPSBleHBvcnRzLkFjY2Vzc1Rva2VuUmVmcmVzaFJlc3BvbnNlID0gdC5pZmFjZShbXSwge1xuICBcImlkX3Rva2VuXCI6IFwic3RyaW5nXCIsXG4gIFwiYWNjZXNzX3Rva2VuXCI6IFwic3RyaW5nXCIsXG4gIFwiZXhwaXJlc19pblwiOiBcIm51bWJlclwiLFxuICBcInNjb3BlXCI6IFwic3RyaW5nXCIsXG4gIFwicmVmcmVzaF90b2tlblwiOiBcInN0cmluZ1wiLFxuICBcInRva2VuX3R5cGVcIjogdC5saXQoJ0JlYXJlcicpXG59KTtcbmNvbnN0IEFic29sdXRlVG9rZW4gPSBleHBvcnRzLkFic29sdXRlVG9rZW4gPSB0LmlmYWNlKFtdLCB7XG4gIFwicmVmcmVzaFRva2VuXCI6IFwic3RyaW5nXCIsXG4gIFwiYWNjZXNzVG9rZW5cIjogXCJzdHJpbmdcIixcbiAgXCJhY2Nlc3NFeHBpcmVzXCI6IFwibnVtYmVyXCIsXG4gIFwic2NvcGVzXCI6IHQuYXJyYXkoXCJzdHJpbmdcIilcbn0pO1xuY29uc3QgUGVyc2lzdEFic29sdXRlVG9rZW5zID0gZXhwb3J0cy5QZXJzaXN0QWJzb2x1dGVUb2tlbnMgPSB0LmlmYWNlKFtdLCB7XG4gIFt0LmluZGV4S2V5XTogXCJBYnNvbHV0ZVRva2VuXCJcbn0pO1xuY29uc3QgQXV0aG9yaXNhdGlvbkVycm9yID0gZXhwb3J0cy5BdXRob3Jpc2F0aW9uRXJyb3IgPSB0LmlmYWNlKFtdLCB7XG4gIFwiZXJyb3JcIjogXCJzdHJpbmdcIixcbiAgXCJlcnJvcl9kZXNjcmlwdGlvblwiOiBcInN0cmluZ1wiXG59KTtcbmNvbnN0IGV4cG9ydGVkVHlwZVN1aXRlID0ge1xuICBTY29wZSxcbiAgQXV0aG9yaXNhdGlvblJlcXVlc3QsXG4gIEF1dGhvcmlzYXRpb25TdGF0ZSxcbiAgQXV0aG9yaXNhdGlvblJlc3BvbnNlLFxuICBBY2Nlc3NUb2tlblJlcXVlc3QsXG4gIEFjY2Vzc1Rva2VuUmVzcG9uc2UsXG4gIERldmljZUF1dGhvcmlzYXRpb25SZXF1ZXN0LFxuICBEZXZpY2VBdXRob3Jpc2F0aW9uUmVzcG9uc2UsXG4gIERldmljZUFjY2Vzc1Rva2VuUmVxdWVzdCxcbiAgRGV2aWNlQWNjZXNzVG9rZW5SZXNwb25zZSxcbiAgQWNjZXNzVG9rZW5SZWZyZXNoUmVxdWVzdCxcbiAgQWNjZXNzVG9rZW5SZWZyZXNoUmVzcG9uc2UsXG4gIEFic29sdXRlVG9rZW4sXG4gIFBlcnNpc3RBYnNvbHV0ZVRva2VucyxcbiAgQXV0aG9yaXNhdGlvbkVycm9yXG59O1xudmFyIF9kZWZhdWx0ID0gZXhwb3J0cy5kZWZhdWx0ID0gZXhwb3J0ZWRUeXBlU3VpdGU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldD11dGYtODtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnVZVzFsY3lJNld5SjBJaXdpWDJsdWRHVnliM0JTWlhGMWFYSmxWMmxzWkdOaGNtUWlMQ0p5WlhGMWFYSmxJaXdpWlNJc0lsZGxZV3ROWVhBaUxDSnlJaXdpYmlJc0lsOWZaWE5OYjJSMWJHVWlMQ0p2SWl3aWFTSXNJbVlpTENKZlgzQnliM1J2WDE4aUxDSmtaV1poZFd4MElpd2lhR0Z6SWl3aVoyVjBJaXdpYzJWMElpd2lhR0Z6VDNkdVVISnZjR1Z5ZEhraUxDSmpZV3hzSWl3aVQySnFaV04wSWl3aVpHVm1hVzVsVUhKdmNHVnlkSGtpTENKblpYUlBkMjVRY205d1pYSjBlVVJsYzJOeWFYQjBiM0lpTENKVFkyOXdaU0lzSW1WNGNHOXlkSE1pTENKMWJtbHZiaUlzSW14cGRDSXNJa0YxZEdodmNtbHpZWFJwYjI1U1pYRjFaWE4wSWl3aWFXWmhZMlVpTENKdmNIUWlMQ0pCZFhSb2IzSnBjMkYwYVc5dVUzUmhkR1VpTENKQmRYUm9iM0pwYzJGMGFXOXVVbVZ6Y0c5dWMyVWlMQ0pCWTJObGMzTlViMnRsYmxKbGNYVmxjM1FpTENKQlkyTmxjM05VYjJ0bGJsSmxjM0J2Ym5ObElpd2lSR1YyYVdObFFYVjBhRzl5YVhOaGRHbHZibEpsY1hWbGMzUWlMQ0pFWlhacFkyVkJkWFJvYjNKcGMyRjBhVzl1VW1WemNHOXVjMlVpTENKRVpYWnBZMlZCWTJObGMzTlViMnRsYmxKbGNYVmxjM1FpTENKRVpYWnBZMlZCWTJObGMzTlViMnRsYmxKbGMzQnZibk5sSWl3aVFXTmpaWE56Vkc5clpXNVNaV1p5WlhOb1VtVnhkV1Z6ZENJc0lrRmpZMlZ6YzFSdmEyVnVVbVZtY21WemFGSmxjM0J2Ym5ObElpd2lRV0p6YjJ4MWRHVlViMnRsYmlJc0ltRnljbUY1SWl3aVVHVnljMmx6ZEVGaWMyOXNkWFJsVkc5clpXNXpJaXdpYVc1a1pYaExaWGtpTENKQmRYUm9iM0pwYzJGMGFXOXVSWEp5YjNJaUxDSmxlSEJ2Y25SbFpGUjVjR1ZUZFdsMFpTSXNJbDlrWldaaGRXeDBJbDBzSW5OdmRYSmpaWE1pT2xzaUxpNHZMaTR2YzNKakwzUnBMMkZ3YVMxaGRYUm9MWFI1Y0dWekxYUnBMblJ6SWwwc0luTnZkWEpqWlhORGIyNTBaVzUwSWpwYmJuVnNiRjBzSW0xaGNIQnBibWR6SWpvaU96czdPenM3UVVGSFFTeEpRVUZCUVN4RFFVRkJMRWRCUVVGRExIVkNRVUZCTEVOQlFVRkRMRTlCUVVFN1FVRkJNRU1zVTBGQlFVUXNkMEpCUVVGRkxFTkJRVUVzUlVGQlFVZ3NRMEZCUVN3MlFrRkJRVWtzVDBGQlFTeE5RVUZCUXl4RFFVRkJMRTlCUVVGRUxFOUJRVUVzU1VGQlFVVXNRMEZCUVN4UFFVRkJSaXhQUVVGQkxGbEJRVUZJTEhWQ1FVRkJMRmxCUVVGQkxFTkJRVUZGTEVOQlFVRXNSVUZCUVVnc1EwRkJRU3hUUVVGQlFTeERRVUZCTEVsQlFVRkhMRU5CUVVFc1NVRkJRVUVzUTBGQlFTeERRVUZCU1N4VlFVRkJMRk5CUVVGS0xFTkJRVUVzVFVGQlFVc3NRMEZCUVN4RlFVRkJReXhEUVVGQkxFVkJRVUZETEVOQlFVRXNTMEZCUVVNc1UwRkJRU3hSUVVGQlF5eFBRVUZCTEVWQlFVRlVMRU5CUVVFc2FVSkJRVUZCTEVOQlFVRXNkVUpCUVVGQkxFTkJRVUVzZVVKQlFVRkJMRU5CUVVFc1UwRkJRVThzUTBGQlFTeE5RVUZCUml4RFFVRkJMRWRCUVVGU0xFTkJRVUVzUjBGQlFVMHNRMEZCUVN4SFFVRkJSQ3hEUVVGQkxGRkJRVUZITEVOQlFVRXNRMEZCUVVzc1IwRkJRU3hEUVVGQlZpeERRVUZCTEZWQlFVRkxMRU5CUVVFc1EwRkJRVTBzUjBGQlFTeERRVUZCV0N4RFFVRkJMRWRCUVVGTExFTkJRVUVzUTBGQlFVOHNSMEZCUVN4RFFVRkJXaXhEUVVGQkxFVkJRVUZQTEVOQlFVRXNaMEpCUVVGV0xFTkJRVUVzU1VGQlFVY3NRMEZCUVN4blFrRkJRVWdzUTBGQlFTeFBRVUZCWjBJc1kwRkJRU3hEUVVGQlF5eEpRVUZCTEVOQlFVRmtMRU5CUVVFc1JVRkJRVWdzUTBGQlFTeFBRVUZCVXl4RFFVRkJMRWxCUVVGRUxFTkJRVUVzUjBGQlFWVXNUVUZCUVN4RFFVRkJReXhqUVVGQkxFdEJRVUZFTEUxQlFVRXNRMEZCUVVVc2QwSkJRVUVzUTBGQlFXcENMRU5CUVVFc1JVRkJRVWdzUTBGQlFTeFBRVUZCVXl4RFFVRkJMRU5CUVVGTExFZEJRVUVzU1VGQlFVd3NRMEZCUVN4RFFVRkJUU3hIUVVGQkxFbEJRVUZRTEVOQlFVRXNRMEZCUVVVc1EwRkJRU3hGUVVGQlZpeERRVUZCTEVWQlFVRlRMRU5CUVVFc1NVRkJRVU1zUTBGQlFTeERRVUZCVml4RFFVRkJMRWxCUVVGSExFTkJRVUVzUTBGQlFVZ3NRMEZCUVN4WFFVRkJWU3hEUVVGQkxFdEJRVUZRTEVOQlFVRXNSVUZCUVVnc1EwRkJRVHRCUVVneFF6czdPenRCUVVsQk8wRkJSVThzVFVGQlRYRkNMRXRCUVVzc1IwRkJRVU1zVDBGQlFTeERRVUZCUkN4TFFVRkJMRWRCUVVkeVFpeERRVUZETEVOQlFVTjFRaXhMUVVGTExFTkJRVU4yUWl4RFFVRkRMRU5CUVVOM1FpeEhRVUZITEVOQlFVTXNVMEZCVXl4RFFVRkRMRVZCUVVWNFFpeERRVUZETEVOQlFVTjNRaXhIUVVGSExFTkJRVU1zVTBGQlV5eERRVUZETEVWQlFVVjRRaXhEUVVGRExFTkJRVU4zUWl4SFFVRkhMRU5CUVVNc1ZVRkJWU3hEUVVGRExFVkJRVVY0UWl4RFFVRkRMRU5CUVVOM1FpeEhRVUZITEVOQlFVTXNVVUZCVVN4RFFVRkRMRVZCUVVWNFFpeERRVUZETEVOQlFVTjNRaXhIUVVGSExFTkJRVU1zWjBKQlFXZENMRU5CUVVNc1JVRkJSWGhDTEVOQlFVTXNRMEZCUTNkQ0xFZEJRVWNzUTBGQlF5eDNRa0ZCZDBJc1EwRkJReXhGUVVGRmVFSXNRMEZCUXl4RFFVRkRkMElzUjBGQlJ5eERRVUZETEhkQ1FVRjNRaXhEUVVGRExFVkJRVVY0UWl4RFFVRkRMRU5CUVVOM1FpeEhRVUZITEVOQlFVTXNlVUpCUVhsQ0xFTkJRVU1zUlVGQlJYaENMRU5CUVVNc1EwRkJRM2RDTEVkQlFVY3NRMEZCUXl4bFFVRmxMRU5CUVVNc1JVRkJSWGhDTEVOQlFVTXNRMEZCUTNkQ0xFZEJRVWNzUTBGQlF5eDFRa0ZCZFVJc1EwRkJReXhGUVVGRmVFSXNRMEZCUXl4RFFVRkRkMElzUjBGQlJ5eERRVUZETEhWQ1FVRjFRaXhEUVVGRExFVkJRVVY0UWl4RFFVRkRMRU5CUVVOM1FpeEhRVUZITEVOQlFVTXNkMEpCUVhkQ0xFTkJRVU1zUlVGQlJYaENMRU5CUVVNc1EwRkJRM2RDTEVkQlFVY3NRMEZCUXl4aFFVRmhMRU5CUVVNc1JVRkJSWGhDTEVOQlFVTXNRMEZCUTNkQ0xFZEJRVWNzUTBGQlF5eHhRa0ZCY1VJc1EwRkJReXhGUVVGRmVFSXNRMEZCUXl4RFFVRkRkMElzUjBGQlJ5eERRVUZETEhGQ1FVRnhRaXhEUVVGRExFVkJRVVY0UWl4RFFVRkRMRU5CUVVOM1FpeEhRVUZITEVOQlFVTXNjMEpCUVhOQ0xFTkJRVU1zUlVGQlJYaENMRU5CUVVNc1EwRkJRM2RDTEVkQlFVY3NRMEZCUXl4bFFVRmxMRU5CUVVNc1JVRkJSWGhDTEVOQlFVTXNRMEZCUTNkQ0xFZEJRVWNzUTBGQlF5eDFRa0ZCZFVJc1EwRkJReXhGUVVGRmVFSXNRMEZCUXl4RFFVRkRkMElzUjBGQlJ5eERRVUZETEhWQ1FVRjFRaXhEUVVGRExFVkJRVVY0UWl4RFFVRkRMRU5CUVVOM1FpeEhRVUZITEVOQlFVTXNkMEpCUVhkQ0xFTkJRVU1zUlVGQlJYaENMRU5CUVVNc1EwRkJRM2RDTEVkQlFVY3NRMEZCUXl4WlFVRlpMRU5CUVVNc1JVRkJSWGhDTEVOQlFVTXNRMEZCUTNkQ0xFZEJRVWNzUTBGQlF5eHZRa0ZCYjBJc1EwRkJReXhGUVVGRmVFSXNRMEZCUXl4RFFVRkRkMElzUjBGQlJ5eERRVUZETEc5Q1FVRnZRaXhEUVVGRExFVkJRVVY0UWl4RFFVRkRMRU5CUVVOM1FpeEhRVUZITEVOQlFVTXNjVUpCUVhGQ0xFTkJRVU1zUlVGQlJYaENMRU5CUVVNc1EwRkJRM2RDTEVkQlFVY3NRMEZCUXl4UFFVRlBMRU5CUVVNc1JVRkJSWGhDTEVOQlFVTXNRMEZCUTNkQ0xFZEJRVWNzUTBGQlF5eGxRVUZsTEVOQlFVTXNSVUZCUlhoQ0xFTkJRVU1zUTBGQlEzZENMRWRCUVVjc1EwRkJReXhsUVVGbExFTkJRVU1zUlVGQlJYaENMRU5CUVVNc1EwRkJRM2RDTEVkQlFVY3NRMEZCUXl4blFrRkJaMElzUTBGQlF5eEZRVUZGZUVJc1EwRkJReXhEUVVGRGQwSXNSMEZCUnl4RFFVRkRMRk5CUVZNc1EwRkJReXhGUVVGRmVFSXNRMEZCUXl4RFFVRkRkMElzUjBGQlJ5eERRVUZETEdsQ1FVRnBRaXhEUVVGRExFVkJRVVY0UWl4RFFVRkRMRU5CUVVOM1FpeEhRVUZITEVOQlFVTXNhVUpCUVdsQ0xFTkJRVU1zUlVGQlJYaENMRU5CUVVNc1EwRkJRM2RDTEVkQlFVY3NRMEZCUXl4clFrRkJhMElzUTBGQlF5eEZRVUZGZUVJc1EwRkJReXhEUVVGRGQwSXNSMEZCUnl4RFFVRkRMR1ZCUVdVc1EwRkJReXhGUVVGRmVFSXNRMEZCUXl4RFFVRkRkMElzUjBGQlJ5eERRVUZETEhWQ1FVRjFRaXhEUVVGRExFVkJRVVY0UWl4RFFVRkRMRU5CUVVOM1FpeEhRVUZITEVOQlFVTXNkVUpCUVhWQ0xFTkJRVU1zUlVGQlJYaENMRU5CUVVNc1EwRkJRM2RDTEVkQlFVY3NRMEZCUXl4M1FrRkJkMElzUTBGQlF5eEZRVUZGZUVJc1EwRkJReXhEUVVGRGQwSXNSMEZCUnl4RFFVRkRMSE5DUVVGelFpeERRVUZETEVWQlFVVjRRaXhEUVVGRExFTkJRVU4zUWl4SFFVRkhMRU5CUVVNc1MwRkJTeXhEUVVGRExFVkJRVVY0UWl4RFFVRkRMRU5CUVVOM1FpeEhRVUZITEVOQlFVTXNZVUZCWVN4RFFVRkRMRVZCUVVWNFFpeERRVUZETEVOQlFVTjNRaXhIUVVGSExFTkJRVU1zWVVGQllTeERRVUZETEVWQlFVVjRRaXhEUVVGRExFTkJRVU4zUWl4SFFVRkhMRU5CUVVNc1kwRkJZeXhEUVVGRExFVkJRVVY0UWl4RFFVRkRMRU5CUVVOM1FpeEhRVUZITEVOQlFVTXNUVUZCVFN4RFFVRkRMRVZCUVVWNFFpeERRVUZETEVOQlFVTjNRaXhIUVVGSExFTkJRVU1zWTBGQll5eERRVUZETEVWQlFVVjRRaXhEUVVGRExFTkJRVU4zUWl4SFFVRkhMRU5CUVVNc1kwRkJZeXhEUVVGRExFVkJRVVY0UWl4RFFVRkRMRU5CUVVOM1FpeEhRVUZITEVOQlFVTXNaVUZCWlN4RFFVRkRMRVZCUVVWNFFpeERRVUZETEVOQlFVTjNRaXhIUVVGSExFTkJRVU1zVjBGQlZ5eERRVUZETEVWQlFVVjRRaXhEUVVGRExFTkJRVU4zUWl4SFFVRkhMRU5CUVVNc2JVSkJRVzFDTEVOQlFVTXNSVUZCUlhoQ0xFTkJRVU1zUTBGQlEzZENMRWRCUVVjc1EwRkJReXh0UWtGQmJVSXNRMEZCUXl4RlFVRkZlRUlzUTBGQlF5eERRVUZEZDBJc1IwRkJSeXhEUVVGRExHOUNRVUZ2UWl4RFFVRkRMRVZCUVVWNFFpeERRVUZETEVOQlFVTjNRaXhIUVVGSExFTkJRVU1zVFVGQlRTeERRVUZETEVWQlFVVjRRaXhEUVVGRExFTkJRVU4zUWl4SFFVRkhMRU5CUVVNc1kwRkJZeXhEUVVGRExFVkJRVVY0UWl4RFFVRkRMRU5CUVVOM1FpeEhRVUZITEVOQlFVTXNZMEZCWXl4RFFVRkRMRVZCUVVWNFFpeERRVUZETEVOQlFVTjNRaXhIUVVGSExFTkJRVU1zWlVGQlpTeERRVUZETEVWQlFVVjRRaXhEUVVGRExFTkJRVU4zUWl4SFFVRkhMRU5CUVVNc1kwRkJZeXhEUVVGRExFVkJRVVY0UWl4RFFVRkRMRU5CUVVOM1FpeEhRVUZITEVOQlFVTXNjMEpCUVhOQ0xFTkJRVU1zUlVGQlJYaENMRU5CUVVNc1EwRkJRM2RDTEVkQlFVY3NRMEZCUXl4elFrRkJjMElzUTBGQlF5eEZRVUZGZUVJc1EwRkJReXhEUVVGRGQwSXNSMEZCUnl4RFFVRkRMSFZDUVVGMVFpeERRVUZETEVWQlFVVjRRaXhEUVVGRExFTkJRVU4zUWl4SFFVRkhMRU5CUVVNc1VVRkJVU3hEUVVGRExFVkJRVVY0UWl4RFFVRkRMRU5CUVVOM1FpeEhRVUZITEVOQlFVTXNaMEpCUVdkQ0xFTkJRVU1zUlVGQlJYaENMRU5CUVVNc1EwRkJRM2RDTEVkQlFVY3NRMEZCUXl4blFrRkJaMElzUTBGQlF5eEZRVUZGZUVJc1EwRkJReXhEUVVGRGQwSXNSMEZCUnl4RFFVRkRMR2xDUVVGcFFpeERRVUZETEVWQlFVVjRRaXhEUVVGRExFTkJRVU4zUWl4SFFVRkhMRU5CUVVNc1lVRkJZU3hEUVVGRExFVkJRVVY0UWl4RFFVRkRMRU5CUVVOM1FpeEhRVUZITEVOQlFVTXNjVUpCUVhGQ0xFTkJRVU1zUlVGQlJYaENMRU5CUVVNc1EwRkJRM2RDTEVkQlFVY3NRMEZCUXl4eFFrRkJjVUlzUTBGQlF5eEZRVUZGZUVJc1EwRkJReXhEUVVGRGQwSXNSMEZCUnl4RFFVRkRMSE5DUVVGelFpeERRVUZETEVWQlFVVjRRaXhEUVVGRExFTkJRVU4zUWl4SFFVRkhMRU5CUVVNc1dVRkJXU3hEUVVGRExFVkJRVVY0UWl4RFFVRkRMRU5CUVVOM1FpeEhRVUZITEVOQlFVTXNiMEpCUVc5Q0xFTkJRVU1zUlVGQlJYaENMRU5CUVVNc1EwRkJRM2RDTEVkQlFVY3NRMEZCUXl4dlFrRkJiMElzUTBGQlF5eEZRVUZGZUVJc1EwRkJReXhEUVVGRGQwSXNSMEZCUnl4RFFVRkRMSEZDUVVGeFFpeERRVUZETEVOQlFVTTdRVUZGYUhoRUxFMUJRVTFETEc5Q1FVRnZRaXhIUVVGQlNDeFBRVUZCTEVOQlFVRkhMRzlDUVVGQkxFZEJRVWQ2UWl4RFFVRkRMRU5CUVVNd1FpeExRVUZMTEVOQlFVTXNSVUZCUlN4RlFVRkZPMFZCUXpsRExGZEJRVmNzUlVGQlJTeFJRVUZSTzBWQlEzSkNMR05CUVdNc1JVRkJSVEZDTEVOQlFVTXNRMEZCUXpKQ0xFZEJRVWNzUTBGQlF5eFJRVUZSTEVOQlFVTTdSVUZETDBJc1pVRkJaU3hGUVVGRk0wSXNRMEZCUXl4RFFVRkRkMElzUjBGQlJ5eERRVUZETEUxQlFVMHNRMEZCUXp0RlFVTTVRaXhQUVVGUExFVkJRVVY0UWl4RFFVRkRMRU5CUVVNeVFpeEhRVUZITEVOQlFVTXNVVUZCVVN4RFFVRkRPMFZCUTNoQ0xFOUJRVThzUlVGQlJUTkNMRU5CUVVNc1EwRkJRekpDTEVkQlFVY3NRMEZCUXl4dlFrRkJiMElzUTBGQlF6dEZRVU53UXl4UFFVRlBMRVZCUVVVelFpeERRVUZETEVOQlFVTXlRaXhIUVVGSExFTkJRVU1zVVVGQlVTeERRVUZETzBWQlEzaENMR2RDUVVGblFpeEZRVUZGTTBJc1EwRkJReXhEUVVGRE1rSXNSMEZCUnl4RFFVRkRMRkZCUVZFc1EwRkJRenRGUVVOcVF5eDFRa0ZCZFVJc1JVRkJSVE5DTEVOQlFVTXNRMEZCUXpKQ0xFZEJRVWNzUTBGQlF6TkNMRU5CUVVNc1EwRkJRM1ZDTEV0QlFVc3NRMEZCUTNaQ0xFTkJRVU1zUTBGQlEzZENMRWRCUVVjc1EwRkJReXhQUVVGUExFTkJRVU1zUlVGQlJYaENMRU5CUVVNc1EwRkJRM2RDTEVkQlFVY3NRMEZCUXl4TlFVRk5MRU5CUVVNc1EwRkJRenREUVVOMFJTeERRVUZETzBGQlJVc3NUVUZCVFVrc2EwSkJRV3RDTEVkQlFVRk9MRTlCUVVFc1EwRkJRVTBzYTBKQlFVRXNSMEZCUnpWQ0xFTkJRVU1zUTBGQlEzVkNMRXRCUVVzc1EwRkJReXhSUVVGUkxFVkJRVVVzVVVGQlVTeERRVUZETzBGQlJYUkVMRTFCUVUxTkxIRkNRVUZ4UWl4SFFVRkJVQ3hQUVVGQkxFTkJRVUZQTEhGQ1FVRkJMRWRCUVVjM1FpeERRVUZETEVOQlFVTXdRaXhMUVVGTExFTkJRVU1zUlVGQlJTeEZRVUZGTzBWQlF5OURMRTFCUVUwc1JVRkJSU3hSUVVGUk8wVkJRMmhDTEZsQlFWa3NSVUZCUlRGQ0xFTkJRVU1zUTBGQlF6SkNMRWRCUVVjc1EwRkJRek5DTEVOQlFVTXNRMEZCUTNkQ0xFZEJRVWNzUTBGQlF5eHZRa0ZCYjBJc1EwRkJReXhEUVVGRE8wVkJRMmhFTEU5QlFVOHNSVUZCUlhoQ0xFTkJRVU1zUTBGQlF6SkNMRWRCUVVjc1EwRkJReXh2UWtGQmIwSTdRMEZEY0VNc1EwRkJRenRCUVVWTExFMUJRVTFITEd0Q1FVRnJRaXhIUVVGQlVpeFBRVUZCTEVOQlFVRlJMR3RDUVVGQkxFZEJRVWM1UWl4RFFVRkRMRU5CUVVNd1FpeExRVUZMTEVOQlFVTXNSVUZCUlN4RlFVRkZPMFZCUXpWRExGZEJRVmNzUlVGQlJTeFJRVUZSTzBWQlEzSkNMR1ZCUVdVc1JVRkJSVEZDTEVOQlFVTXNRMEZCUXpKQ0xFZEJRVWNzUTBGQlF5eFJRVUZSTEVOQlFVTTdSVUZEYUVNc1kwRkJZeXhGUVVGRk0wSXNRMEZCUXl4RFFVRkRNa0lzUjBGQlJ5eERRVUZETEZGQlFWRXNRMEZCUXp0RlFVTXZRaXhaUVVGWkxFVkJRVVV6UWl4RFFVRkRMRU5CUVVOM1FpeEhRVUZITEVOQlFVTXNiMEpCUVc5Q0xFTkJRVU03UlVGRGVrTXNUVUZCVFN4RlFVRkZMRkZCUVZFN1JVRkRhRUlzWlVGQlpTeEZRVUZGZUVJc1EwRkJReXhEUVVGRE1rSXNSMEZCUnl4RFFVRkRMRkZCUVZFN1EwRkRhRU1zUTBGQlF6dEJRVVZMTEUxQlFVMUpMRzFDUVVGdFFpeEhRVUZCVkN4UFFVRkJMRU5CUVVGVExHMUNRVUZCTEVkQlFVY3ZRaXhEUVVGRExFTkJRVU13UWl4TFFVRkxMRU5CUVVNc1JVRkJSU3hGUVVGRk8wVkJRemRETEZWQlFWVXNSVUZCUlN4UlFVRlJPMFZCUTNCQ0xHTkJRV01zUlVGQlJTeFJRVUZSTzBWQlEzaENMRmxCUVZrc1JVRkJSU3hSUVVGUk8wVkJRM1JDTEU5QlFVOHNSVUZCUlN4UlFVRlJPMFZCUTJwQ0xHVkJRV1VzUlVGQlJTeFJRVUZSTzBWQlEzcENMRmxCUVZrc1JVRkJSVEZDTEVOQlFVTXNRMEZCUXpKQ0xFZEJRVWNzUTBGQlF6TkNMRU5CUVVNc1EwRkJRM2RDTEVkQlFVY3NRMEZCUXl4UlFVRlJMRU5CUVVNN1EwRkRjRU1zUTBGQlF6dEJRVVZMTEUxQlFVMVJMREJDUVVFd1FpeEhRVUZCVml4UFFVRkJMRU5CUVVGVkxEQkNRVUZCTEVkQlFVZG9ReXhEUVVGRExFTkJRVU13UWl4TFFVRkxMRU5CUVVNc1JVRkJSU3hGUVVGRk8wVkJRM0JFTEZkQlFWY3NSVUZCUlN4UlFVRlJPMFZCUTNKQ0xFOUJRVThzUlVGQlJURkNMRU5CUVVNc1EwRkJRekpDTEVkQlFVY3NRMEZCUXl4UlFVRlJPME5CUTNoQ0xFTkJRVU03UVVGRlN5eE5RVUZOVFN3eVFrRkJNa0lzUjBGQlFWZ3NUMEZCUVN4RFFVRkJWeXd5UWtGQlFTeEhRVUZIYWtNc1EwRkJReXhEUVVGRE1FSXNTMEZCU3l4RFFVRkRMRVZCUVVVc1JVRkJSVHRGUVVOeVJDeGhRVUZoTEVWQlFVVXNVVUZCVVR0RlFVTjJRaXhYUVVGWExFVkJRVVVzVVVGQlVUdEZRVU55UWl4clFrRkJhMElzUlVGQlJTeFJRVUZSTzBWQlF6VkNMREpDUVVFeVFpeEZRVUZGTVVJc1EwRkJReXhEUVVGRE1rSXNSMEZCUnl4RFFVRkRMRkZCUVZFc1EwRkJRenRGUVVNMVF5eFpRVUZaTEVWQlFVVXpRaXhEUVVGRExFTkJRVU15UWl4SFFVRkhMRU5CUVVNc1VVRkJVU3hEUVVGRE8wVkJRemRDTEZWQlFWVXNSVUZCUlROQ0xFTkJRVU1zUTBGQlF6SkNMRWRCUVVjc1EwRkJReXhSUVVGUk8wTkJRek5DTEVOQlFVTTdRVUZGU3l4TlFVRk5UeXgzUWtGQmQwSXNSMEZCUVZvc1QwRkJRU3hEUVVGQldTeDNRa0ZCUVN4SFFVRkhiRU1zUTBGQlF5eERRVUZETUVJc1MwRkJTeXhEUVVGRExFVkJRVVVzUlVGQlJUdEZRVU5zUkN4WlFVRlpMRVZCUVVVeFFpeERRVUZETEVOQlFVTjFRaXhMUVVGTExFTkJRVU4yUWl4RFFVRkRMRU5CUVVOM1FpeEhRVUZITEVOQlFVTXNPRU5CUVRoRExFTkJRVU1zUlVGQlJYaENMRU5CUVVNc1EwRkJRM2RDTEVkQlFVY3NRMEZCUXl4aFFVRmhMRU5CUVVNc1EwRkJRenRGUVVOc1J5eGhRVUZoTEVWQlFVVXNVVUZCVVR0RlFVTjJRaXhYUVVGWExFVkJRVVVzVVVGQlVUdEZRVU55UWl4bFFVRmxMRVZCUVVWNFFpeERRVUZETEVOQlFVTXlRaXhIUVVGSExFTkJRVU1zVVVGQlVUdERRVU5vUXl4RFFVRkRPMEZCUlVzc1RVRkJUVkVzZVVKQlFYbENMRWRCUVVGaUxFOUJRVUVzUTBGQlFXRXNlVUpCUVVFc1IwRkJSMjVETEVOQlFVTXNRMEZCUXpCQ0xFdEJRVXNzUTBGQlF5eEZRVUZGTEVWQlFVVTdSVUZEYmtRc1ZVRkJWU3hGUVVGRkxGRkJRVkU3UlVGRGNFSXNZMEZCWXl4RlFVRkZMRkZCUVZFN1JVRkRlRUlzV1VGQldTeEZRVUZGTEZGQlFWRTdSVUZEZEVJc1QwRkJUeXhGUVVGRkxGRkJRVkU3UlVGRGFrSXNaVUZCWlN4RlFVRkZMRkZCUVZFN1JVRkRla0lzV1VGQldTeEZRVUZGTVVJc1EwRkJReXhEUVVGRE1rSXNSMEZCUnl4RFFVRkRNMElzUTBGQlF5eERRVUZEZDBJc1IwRkJSeXhEUVVGRExGRkJRVkVzUTBGQlF6dERRVU53UXl4RFFVRkRPMEZCUlVzc1RVRkJUVmtzZVVKQlFYbENMRWRCUVVGa0xFOUJRVUVzUTBGQlFXTXNlVUpCUVVFc1IwRkJSM0JETEVOQlFVTXNRMEZCUXpCQ0xFdEJRVXNzUTBGQlF5eEZRVUZGTEVWQlFVVTdSVUZEYmtRc1dVRkJXU3hGUVVGRk1VSXNRMEZCUXl4RFFVRkRkMElzUjBGQlJ5eERRVUZETEdWQlFXVXNRMEZCUXp0RlFVTndReXhsUVVGbExFVkJRVVVzVVVGQlVUdEZRVU42UWl4bFFVRmxMRVZCUVVWNFFpeERRVUZETEVOQlFVTXlRaXhIUVVGSExFTkJRVU1zVVVGQlVTeERRVUZETzBWQlEyaERMRTlCUVU4c1JVRkJSVE5DTEVOQlFVTXNRMEZCUXpKQ0xFZEJRVWNzUTBGQlF5eFJRVUZSTEVOQlFVTTdSVUZEZUVJc1dVRkJXU3hGUVVGRk0wSXNRMEZCUXl4RFFVRkRNa0lzUjBGQlJ5eERRVUZETEZGQlFWRTdRMEZETjBJc1EwRkJRenRCUVVWTExFMUJRVTFWTERCQ1FVRXdRaXhIUVVGQlppeFBRVUZCTEVOQlFVRmxMREJDUVVGQkxFZEJRVWR5UXl4RFFVRkRMRU5CUVVNd1FpeExRVUZMTEVOQlFVTXNSVUZCUlN4RlFVRkZPMFZCUTNCRUxGVkJRVlVzUlVGQlJTeFJRVUZSTzBWQlEzQkNMR05CUVdNc1JVRkJSU3hSUVVGUk8wVkJRM2hDTEZsQlFWa3NSVUZCUlN4UlFVRlJPMFZCUTNSQ0xFOUJRVThzUlVGQlJTeFJRVUZSTzBWQlEycENMR1ZCUVdVc1JVRkJSU3hSUVVGUk8wVkJRM3BDTEZsQlFWa3NSVUZCUlRGQ0xFTkJRVU1zUTBGQlEzZENMRWRCUVVjc1EwRkJReXhSUVVGUk8wTkJRemRDTEVOQlFVTTdRVUZGU3l4TlFVRk5ZeXhoUVVGaExFZEJRVUZvUWl4UFFVRkJMRU5CUVVGblFpeGhRVUZCTEVkQlFVZDBReXhEUVVGRExFTkJRVU13UWl4TFFVRkxMRU5CUVVNc1JVRkJSU3hGUVVGRk8wVkJRM1pETEdOQlFXTXNSVUZCUlN4UlFVRlJPMFZCUTNoQ0xHRkJRV0VzUlVGQlJTeFJRVUZSTzBWQlEzWkNMR1ZCUVdVc1JVRkJSU3hSUVVGUk8wVkJRM3BDTEZGQlFWRXNSVUZCUlRGQ0xFTkJRVU1zUTBGQlEzVkRMRXRCUVVzc1EwRkJReXhSUVVGUk8wTkJRek5DTEVOQlFVTTdRVUZGU3l4TlFVRk5ReXh4UWtGQmNVSXNSMEZCUVd4Q0xFOUJRVUVzUTBGQlFXdENMSEZDUVVGQkxFZEJRVWQ0UXl4RFFVRkRMRU5CUVVNd1FpeExRVUZMTEVOQlFVTXNSVUZCUlN4RlFVRkZPMFZCUXk5RExFTkJRVU14UWl4RFFVRkRMRU5CUVVONVF5eFJRVUZSTEVkQlFVYzdRMEZEWml4RFFVRkRPMEZCUlVzc1RVRkJUVU1zYTBKQlFXdENMRWRCUVVGd1FpeFBRVUZCTEVOQlFVRnZRaXhyUWtGQlFTeEhRVUZITVVNc1EwRkJReXhEUVVGRE1FSXNTMEZCU3l4RFFVRkRMRVZCUVVVc1JVRkJSVHRGUVVNMVF5eFBRVUZQTEVWQlFVVXNVVUZCVVR0RlFVTnFRaXh0UWtGQmJVSXNSVUZCUlR0RFFVTjBRaXhEUVVGRE8wRkJSVVlzVFVGQlRXbENMR2xDUVVGcFFpeEhRVUZwUWp0RlFVTjBRM1JDTEV0QlFVczdSVUZEVEVrc2IwSkJRVzlDTzBWQlEzQkNSeXhyUWtGQmEwSTdSVUZEYkVKRExIRkNRVUZ4UWp0RlFVTnlRa01zYTBKQlFXdENPMFZCUTJ4Q1F5eHRRa0ZCYlVJN1JVRkRia0pETERCQ1FVRXdRanRGUVVNeFFrTXNNa0pCUVRKQ08wVkJRek5DUXl4M1FrRkJkMEk3UlVGRGVFSkRMSGxDUVVGNVFqdEZRVU42UWtNc2VVSkJRWGxDTzBWQlEzcENReXd3UWtGQk1FSTdSVUZETVVKRExHRkJRV0U3UlVGRFlrVXNjVUpCUVhGQ08wVkJRM0pDUlR0RFFVTkVPMEZCUVVNc1NVRkJRVVVzVVVGQlFTeEhRVUZCZEVJc1QwRkJRU3hEUVVGQlZpeFBRVUZCTEVkQlEyRXJRaXhwUWtGQmFVSWlMQ0pwWjI1dmNtVk1hWE4wSWpwYlhYMD0iLCJcInVzZSBzdHJpY3RcIjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMudHlwZVN1aXRlID0gZXhwb3J0cy5kZWZhdWx0ID0gZXhwb3J0cy5jaGVja2VycyA9IHZvaWQgMDtcbnZhciBfdHNJbnRlcmZhY2VDaGVja2VyID0gcmVxdWlyZShcInRzLWludGVyZmFjZS1jaGVja2VyXCIpO1xudmFyIF9hcGlBdXRoVHlwZXNUaSA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIi4vYXBpLWF1dGgtdHlwZXMtdGkuanNcIikpO1xuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChlKSB7IHJldHVybiBlICYmIGUuX19lc01vZHVsZSA/IGUgOiB7IGRlZmF1bHQ6IGUgfTsgfVxuLy8gVGhpcyBtb2R1bGUgd2FzIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IG5vZGUgdHMtaW50ZXJmYWNlLXBvc3QudHNcbi8vIDIwMjYtMDUtMzFUMTU6Mjc6NDIuNDEyWlxuXG4vLyBUeXBlIGRlZmluaXRpb25zXG5jb25zdCB0eXBlU3VpdGUgPSBleHBvcnRzLnR5cGVTdWl0ZSA9IF9hcGlBdXRoVHlwZXNUaS5kZWZhdWx0O1xuLy8gQ2hlY2tlcnNcbmNvbnN0IGNoZWNrZXJzID0gZXhwb3J0cy5jaGVja2VycyA9ICgwLCBfdHNJbnRlcmZhY2VDaGVja2VyLmNyZWF0ZUNoZWNrZXJzKShfYXBpQXV0aFR5cGVzVGkuZGVmYXVsdCk7XG4vLyBFeHBvcnQgdGhlIGNoZWNrZXJzIGJ5IGRlZmF1bHRcbnZhciBfZGVmYXVsdCA9IGV4cG9ydHMuZGVmYXVsdCA9IGNoZWNrZXJzO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ9dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p1WVcxbGN5STZXeUpmZEhOSmJuUmxjbVpoWTJWRGFHVmphMlZ5SWl3aWNtVnhkV2x5WlNJc0lsOWhjR2xCZFhSb1ZIbHdaWE5VYVNJc0lsOXBiblJsY205d1VtVnhkV2x5WlVSbFptRjFiSFFpTENKbElpd2lYMTlsYzAxdlpIVnNaU0lzSW1SbFptRjFiSFFpTENKMGVYQmxVM1ZwZEdVaUxDSmxlSEJ2Y25Seklpd2laWGh3YjNKMFpXUlVlWEJsVTNWcGRHVWlMQ0pqYUdWamEyVnljeUlzSW1OeVpXRjBaVU5vWldOclpYSnpJaXdpWDJSbFptRjFiSFFpWFN3aWMyOTFjbU5sY3lJNld5SXVMaTh1TGk5emNtTXZkR2t2WVhCcExXRjFkR2d0ZEhsd1pYTXVkSE1pWFN3aWMyOTFjbU5sYzBOdmJuUmxiblFpT2x0dWRXeHNYU3dpYldGd2NHbHVaM01pT2lJN096czdPenRCUVVkQkxFbEJRVUZCTEcxQ1FVRkJMRWRCUVVGRExFOUJRVUU3UVVGRlFTeEpRVUZCUXl4bFFVRkJMRWRCUVVGRExITkNRVUZCTEVOQlFVRkdMRTlCUVVFN1FVRkJkVVFzVTBGQlFVVXNkVUpCUVVGRExFTkJRVUVzVjBGQlFVRXNRMEZCUVN4SlFVRkJRU3hEUVVGQkxFTkJRVUZETEZWQlFVRXNSMEZCUVVRc1EwRkJRU3hMUVVGQlJTeFBRVUZCTEVWQlFVRkdMRU5CUVVFN1FVRk1ka1E3UVVGRFFUczdRVUY1UWtFN1FVRkRUeXhOUVVGTlJ5eFRRVUZUTEVkQlFVRkRMRTlCUVVFc1EwRkJRVVFzVTBGQlFTeEhRVUZIUlN4MVFrRm5RbmhDTzBGQlJVUTdRVUZEVHl4TlFVRk5ReXhSUVVGUkxFZEJRVUZHTEU5QlFVRXNRMEZCUVVVc1VVRkJRU3hIUVVGSExFbEJRVUZETEd0RFFVRmpMRVZCUVVOR0xIVkNRVUZwUWl4RFFXZENka1E3UVVGRlJEdEJRVUZCTEVsQlFVRkhMRkZCUVVFc1IwRkJRVW9zVDBGQlFTeERRVUZCUml4UFFVRkJMRWRCUTJWSkxGRkJRVkVpTENKcFoyNXZjbVZNYVhOMElqcGJYWDA9IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSBleHBvcnRzLlZhbHVlID0gZXhwb3J0cy5TdGF0dXNlc1dyYXBwZXIgPSBleHBvcnRzLlN0YXR1c1dyYXBwZXIgPSBleHBvcnRzLlN0YXR1c1N0cmluZyA9IGV4cG9ydHMuU3RhdHVzTnVtYmVyID0gZXhwb3J0cy5TdGF0dXNDb21tb24gPSBleHBvcnRzLlN0YXR1c0Jvb2xlYW4gPSBleHBvcnRzLlN0YXR1cyA9IGV4cG9ydHMuU2V0dGluZ3NXcmFwcGVyID0gZXhwb3J0cy5TZXR0aW5nV3JhcHBlciA9IGV4cG9ydHMuU2V0dGluZ1N0cmluZyA9IGV4cG9ydHMuU2V0dGluZ051bWJlciA9IGV4cG9ydHMuU2V0dGluZ0NvbW1vbiA9IGV4cG9ydHMuU2V0dGluZ0Jvb2xlYW4gPSBleHBvcnRzLlNldHRpbmcgPSBleHBvcnRzLlByb2dyYW1zV3JhcHBlciA9IGV4cG9ydHMuUHJvZ3JhbXMgPSBleHBvcnRzLlByb2dyYW1XcmFwcGVyID0gZXhwb3J0cy5Qcm9ncmFtUGFydGlhbCA9IGV4cG9ydHMuUHJvZ3JhbUxpc3QgPSBleHBvcnRzLlByb2dyYW1FeGVjdXRpb24gPSBleHBvcnRzLlByb2dyYW1EZWZpbml0aW9uV3JhcHBlciA9IGV4cG9ydHMuUHJvZ3JhbURlZmluaXRpb24gPSBleHBvcnRzLlByb2dyYW1Db25zdHJhaW50cyA9IGV4cG9ydHMuUHJvZ3JhbSA9IGV4cG9ydHMuT3B0aW9uc1dyYXBwZXIgPSBleHBvcnRzLk9wdGlvbldyYXBwZXIgPSBleHBvcnRzLk9wdGlvbkRlZmluaXRpb25TdHJpbmcgPSBleHBvcnRzLk9wdGlvbkRlZmluaXRpb25OdW1iZXIgPSBleHBvcnRzLk9wdGlvbkRlZmluaXRpb25Db21tb24gPSBleHBvcnRzLk9wdGlvbkRlZmluaXRpb25Cb29sZWFuID0gZXhwb3J0cy5PcHRpb25EZWZpbml0aW9uID0gZXhwb3J0cy5PcHRpb25Db25zdHJhaW50c0NvbW1vbiA9IGV4cG9ydHMuT3B0aW9uID0gZXhwb3J0cy5JbWFnZXNXcmFwcGVyID0gZXhwb3J0cy5JbWFnZVF1YWxpdHkgPSBleHBvcnRzLkltYWdlID0gZXhwb3J0cy5Ib21lQXBwbGlhbmNlc1dyYXBwZXIgPSBleHBvcnRzLkhvbWVBcHBsaWFuY2VXcmFwcGVyID0gZXhwb3J0cy5Ib21lQXBwbGlhbmNlID0gZXhwb3J0cy5FeGVjdXRlQ29tbWFuZFdyYXBwZXIgPSBleHBvcnRzLkV4ZWN1dGVDb21tYW5kID0gZXhwb3J0cy5FdmVudExldmVsID0gZXhwb3J0cy5FdmVudEtlZXBBbGl2ZSA9IGV4cG9ydHMuRXZlbnRIYW5kbGluZyA9IGV4cG9ydHMuRXZlbnREYXRhID0gZXhwb3J0cy5FdmVudEFwcGxpYW5jZURhdGEgPSBleHBvcnRzLkV2ZW50QXBwbGlhbmNlQ29ubmVjdGlvbiA9IGV4cG9ydHMuRXZlbnQgPSBleHBvcnRzLkVycm9yUmVzcG9uc2UgPSBleHBvcnRzLkNvbnN0cmFpbnRzU3RyaW5nID0gZXhwb3J0cy5Db25zdHJhaW50c051bWJlciA9IGV4cG9ydHMuQ29uc3RyYWludHNDb21tb24gPSBleHBvcnRzLkNvbnN0cmFpbnRzQm9vbGVhbiA9IGV4cG9ydHMuQ29uc3RyYWludHMgPSBleHBvcnRzLkNvbW1hbmRzV3JhcHBlciA9IGV4cG9ydHMuQ29tbWFuZCA9IGV4cG9ydHMuQWNjZXNzID0gdm9pZCAwO1xudmFyIHQgPSBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZChyZXF1aXJlKFwidHMtaW50ZXJmYWNlLWNoZWNrZXJcIikpO1xuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQoZSwgdCkgeyBpZiAoXCJmdW5jdGlvblwiID09IHR5cGVvZiBXZWFrTWFwKSB2YXIgciA9IG5ldyBXZWFrTWFwKCksIG4gPSBuZXcgV2Vha01hcCgpOyByZXR1cm4gKF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkID0gZnVuY3Rpb24gKGUsIHQpIHsgaWYgKCF0ICYmIGUgJiYgZS5fX2VzTW9kdWxlKSByZXR1cm4gZTsgdmFyIG8sIGksIGYgPSB7IF9fcHJvdG9fXzogbnVsbCwgZGVmYXVsdDogZSB9OyBpZiAobnVsbCA9PT0gZSB8fCBcIm9iamVjdFwiICE9IHR5cGVvZiBlICYmIFwiZnVuY3Rpb25cIiAhPSB0eXBlb2YgZSkgcmV0dXJuIGY7IGlmIChvID0gdCA/IG4gOiByKSB7IGlmIChvLmhhcyhlKSkgcmV0dXJuIG8uZ2V0KGUpOyBvLnNldChlLCBmKTsgfSBmb3IgKGNvbnN0IHQgaW4gZSkgXCJkZWZhdWx0XCIgIT09IHQgJiYge30uaGFzT3duUHJvcGVydHkuY2FsbChlLCB0KSAmJiAoKGkgPSAobyA9IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSkgJiYgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihlLCB0KSkgJiYgKGkuZ2V0IHx8IGkuc2V0KSA/IG8oZiwgdCwgaSkgOiBmW3RdID0gZVt0XSk7IHJldHVybiBmOyB9KShlLCB0KTsgfVxuLyoqXG4gKiBUaGlzIG1vZHVsZSB3YXMgYXV0b21hdGljYWxseSBnZW5lcmF0ZWQgYnkgYHRzLWludGVyZmFjZS1idWlsZGVyYFxuICovXG5cbi8vIHRzbGludDpkaXNhYmxlOm9iamVjdC1saXRlcmFsLWtleS1xdW90ZXNcbmNvbnN0IFZhbHVlID0gZXhwb3J0cy5WYWx1ZSA9IHQudW5pb24oXCJzdHJpbmdcIiwgXCJudW1iZXJcIiwgXCJib29sZWFuXCIpO1xuY29uc3QgQ29uc3RyYWludHMgPSBleHBvcnRzLkNvbnN0cmFpbnRzID0gdC51bmlvbihcIkNvbnN0cmFpbnRzU3RyaW5nXCIsIFwiQ29uc3RyYWludHNOdW1iZXJcIiwgXCJDb25zdHJhaW50c0Jvb2xlYW5cIik7XG5jb25zdCBDb25zdHJhaW50c1N0cmluZyA9IGV4cG9ydHMuQ29uc3RyYWludHNTdHJpbmcgPSB0LmlmYWNlKFtcIkNvbnN0cmFpbnRzQ29tbW9uXCJdLCB7XG4gIFwiZGVmYXVsdFwiOiB0Lm9wdChcInN0cmluZ1wiKSxcbiAgXCJhbGxvd2VkdmFsdWVzXCI6IHQub3B0KHQuYXJyYXkoXCJzdHJpbmdcIikpLFxuICBcImRpc3BsYXl2YWx1ZXNcIjogdC5vcHQodC5hcnJheShcInN0cmluZ1wiKSlcbn0pO1xuY29uc3QgQ29uc3RyYWludHNOdW1iZXIgPSBleHBvcnRzLkNvbnN0cmFpbnRzTnVtYmVyID0gdC5pZmFjZShbXCJDb25zdHJhaW50c0NvbW1vblwiXSwge1xuICBcImRlZmF1bHRcIjogdC5vcHQoXCJudW1iZXJcIiksXG4gIFwibWluXCI6IHQub3B0KFwibnVtYmVyXCIpLFxuICBcIm1heFwiOiB0Lm9wdChcIm51bWJlclwiKSxcbiAgXCJzdGVwc2l6ZVwiOiB0Lm9wdChcIm51bWJlclwiKVxufSk7XG5jb25zdCBDb25zdHJhaW50c0Jvb2xlYW4gPSBleHBvcnRzLkNvbnN0cmFpbnRzQm9vbGVhbiA9IHQuaWZhY2UoW1wiQ29uc3RyYWludHNDb21tb25cIl0sIHtcbiAgXCJkZWZhdWx0XCI6IHQub3B0KFwiYm9vbGVhblwiKVxufSk7XG5jb25zdCBDb25zdHJhaW50c0NvbW1vbiA9IGV4cG9ydHMuQ29uc3RyYWludHNDb21tb24gPSB0LmlmYWNlKFtdLCB7XG4gIFwiYWNjZXNzXCI6IHQub3B0KFwiQWNjZXNzXCIpXG59KTtcbmNvbnN0IEFjY2VzcyA9IGV4cG9ydHMuQWNjZXNzID0gdC51bmlvbih0LmxpdCgncmVhZCcpLCB0LmxpdCgncmVhZFdyaXRlJykpO1xuY29uc3QgRXhlY3V0ZUNvbW1hbmRXcmFwcGVyID0gZXhwb3J0cy5FeGVjdXRlQ29tbWFuZFdyYXBwZXIgPSB0LmlmYWNlKFtdLCB7XG4gIFwiZGF0YVwiOiBcIkV4ZWN1dGVDb21tYW5kXCJcbn0pO1xuY29uc3QgRXhlY3V0ZUNvbW1hbmQgPSBleHBvcnRzLkV4ZWN1dGVDb21tYW5kID0gdC5pZmFjZShbXSwge1xuICBcImtleVwiOiBcInN0cmluZ1wiLFxuICBcInZhbHVlXCI6IHQubGl0KHRydWUpXG59KTtcbmNvbnN0IENvbW1hbmRzV3JhcHBlciA9IGV4cG9ydHMuQ29tbWFuZHNXcmFwcGVyID0gdC5pZmFjZShbXSwge1xuICBcImRhdGFcIjogdC5pZmFjZShbXSwge1xuICAgIFwiY29tbWFuZHNcIjogdC5hcnJheShcIkNvbW1hbmRcIilcbiAgfSlcbn0pO1xuY29uc3QgQ29tbWFuZCA9IGV4cG9ydHMuQ29tbWFuZCA9IHQuaWZhY2UoW10sIHtcbiAgXCJrZXlcIjogXCJzdHJpbmdcIixcbiAgXCJuYW1lXCI6IHQub3B0KFwic3RyaW5nXCIpLFxuICBcImRlc2NyaXB0aW9uXCI6IHQub3B0KFwic3RyaW5nXCIpXG59KTtcbmNvbnN0IEV2ZW50ID0gZXhwb3J0cy5FdmVudCA9IHQudW5pb24oXCJFdmVudEtlZXBBbGl2ZVwiLCBcIkV2ZW50QXBwbGlhbmNlQ29ubmVjdGlvblwiLCBcIkV2ZW50QXBwbGlhbmNlRGF0YVwiKTtcbmNvbnN0IEV2ZW50S2VlcEFsaXZlID0gZXhwb3J0cy5FdmVudEtlZXBBbGl2ZSA9IHQuaWZhY2UoW10sIHtcbiAgXCJldmVudFwiOiB0LmxpdCgnS0VFUC1BTElWRScpLFxuICBcImRhdGFcIjogdC5vcHQodC5saXQoJycpKVxufSk7XG5jb25zdCBFdmVudEFwcGxpYW5jZUNvbm5lY3Rpb24gPSBleHBvcnRzLkV2ZW50QXBwbGlhbmNlQ29ubmVjdGlvbiA9IHQuaWZhY2UoW10sIHtcbiAgXCJldmVudFwiOiB0LnVuaW9uKHQubGl0KCdDT05ORUNURUQnKSwgdC5saXQoJ0RJU0NPTk5FQ1RFRCcpLCB0LmxpdCgnUEFJUkVEJyksIHQubGl0KCdERVBBSVJFRCcpKSxcbiAgXCJpZFwiOiBcInN0cmluZ1wiLFxuICBcImRhdGFcIjogdC5vcHQodC51bmlvbih0LmxpdCgnJyksIFwiRXZlbnREYXRhXCIpKVxufSk7XG5jb25zdCBFdmVudEFwcGxpYW5jZURhdGEgPSBleHBvcnRzLkV2ZW50QXBwbGlhbmNlRGF0YSA9IHQuaWZhY2UoW10sIHtcbiAgXCJldmVudFwiOiB0LnVuaW9uKHQubGl0KCdTVEFUVVMnKSwgdC5saXQoJ0VWRU5UJyksIHQubGl0KCdOT1RJRlknKSksXG4gIFwiaWRcIjogXCJzdHJpbmdcIixcbiAgXCJkYXRhXCI6IHQuaWZhY2UoW10sIHtcbiAgICBcIml0ZW1zXCI6IHQuYXJyYXkoXCJFdmVudERhdGFcIiksXG4gICAgXCJoYUlkXCI6IHQub3B0KFwic3RyaW5nXCIpXG4gIH0pXG59KTtcbmNvbnN0IEV2ZW50RGF0YSA9IGV4cG9ydHMuRXZlbnREYXRhID0gdC5pZmFjZShbXSwge1xuICBcImtleVwiOiBcInN0cmluZ1wiLFxuICBcIm5hbWVcIjogdC5vcHQoXCJzdHJpbmdcIiksXG4gIFwidXJpXCI6IHQub3B0KFwic3RyaW5nXCIpLFxuICBcInRpbWVzdGFtcFwiOiB0LnVuaW9uKFwibnVtYmVyXCIsIFwibnVsbFwiKSxcbiAgXCJsZXZlbFwiOiBcIkV2ZW50TGV2ZWxcIixcbiAgXCJoYW5kbGluZ1wiOiBcIkV2ZW50SGFuZGxpbmdcIixcbiAgXCJ2YWx1ZVwiOiB0LnVuaW9uKFwiVmFsdWVcIiwgXCJudWxsXCIpLFxuICBcImRpc3BsYXl2YWx1ZVwiOiB0Lm9wdChcInN0cmluZ1wiKSxcbiAgXCJ1bml0XCI6IHQub3B0KFwic3RyaW5nXCIpLFxuICBcImhhSWRcIjogdC5vcHQoXCJzdHJpbmdcIilcbn0pO1xuY29uc3QgRXZlbnRMZXZlbCA9IGV4cG9ydHMuRXZlbnRMZXZlbCA9IHQudW5pb24odC5saXQoJ2NyaXRpY2FsJyksIHQubGl0KCdhbGVydCcpLCB0LmxpdCgnd2FybmluZycpLCB0LmxpdCgnaGludCcpLCB0LmxpdCgnaW5mbycpKTtcbmNvbnN0IEV2ZW50SGFuZGxpbmcgPSBleHBvcnRzLkV2ZW50SGFuZGxpbmcgPSB0LnVuaW9uKHQubGl0KCdub25lJyksIHQubGl0KCdhY2tub3dsZWRnZScpLCB0LmxpdCgnZGVjaXNpb24nKSk7XG5jb25zdCBIb21lQXBwbGlhbmNlc1dyYXBwZXIgPSBleHBvcnRzLkhvbWVBcHBsaWFuY2VzV3JhcHBlciA9IHQuaWZhY2UoW10sIHtcbiAgXCJkYXRhXCI6IHQuaWZhY2UoW10sIHtcbiAgICBcImhvbWVhcHBsaWFuY2VzXCI6IHQuYXJyYXkoXCJIb21lQXBwbGlhbmNlXCIpXG4gIH0pXG59KTtcbmNvbnN0IEhvbWVBcHBsaWFuY2VXcmFwcGVyID0gZXhwb3J0cy5Ib21lQXBwbGlhbmNlV3JhcHBlciA9IHQuaWZhY2UoW10sIHtcbiAgXCJkYXRhXCI6IFwiSG9tZUFwcGxpYW5jZVwiXG59KTtcbmNvbnN0IEhvbWVBcHBsaWFuY2UgPSBleHBvcnRzLkhvbWVBcHBsaWFuY2UgPSB0LmlmYWNlKFtdLCB7XG4gIFwiaGFJZFwiOiBcInN0cmluZ1wiLFxuICBcIm5hbWVcIjogXCJzdHJpbmdcIixcbiAgXCJ0eXBlXCI6IFwic3RyaW5nXCIsXG4gIFwiYnJhbmRcIjogXCJzdHJpbmdcIixcbiAgXCJ2aWJcIjogXCJzdHJpbmdcIixcbiAgXCJlbnVtYmVyXCI6IFwic3RyaW5nXCIsXG4gIFwiY29ubmVjdGVkXCI6IFwiYm9vbGVhblwiXG59KTtcbmNvbnN0IEltYWdlc1dyYXBwZXIgPSBleHBvcnRzLkltYWdlc1dyYXBwZXIgPSB0LmlmYWNlKFtdLCB7XG4gIFwiZGF0YVwiOiB0LmlmYWNlKFtdLCB7XG4gICAgXCJpbWFnZXNcIjogdC5hcnJheShcIkltYWdlXCIpXG4gIH0pXG59KTtcbmNvbnN0IEltYWdlID0gZXhwb3J0cy5JbWFnZSA9IHQuaWZhY2UoW10sIHtcbiAgXCJrZXlcIjogXCJzdHJpbmdcIixcbiAgXCJuYW1lXCI6IHQub3B0KFwic3RyaW5nXCIpLFxuICBcImltYWdla2V5XCI6IFwic3RyaW5nXCIsXG4gIFwicHJldmlld2ltYWdla2V5XCI6IFwic3RyaW5nXCIsXG4gIFwidGltZXN0YW1wXCI6IFwibnVtYmVyXCIsXG4gIFwicXVhbGl0eVwiOiBcIkltYWdlUXVhbGl0eVwiXG59KTtcbmNvbnN0IEltYWdlUXVhbGl0eSA9IGV4cG9ydHMuSW1hZ2VRdWFsaXR5ID0gdC51bmlvbih0LmxpdCgnZ29vZCcpLCB0LmxpdCgnYmFkJykpO1xuY29uc3QgUHJvZ3JhbXNXcmFwcGVyID0gZXhwb3J0cy5Qcm9ncmFtc1dyYXBwZXIgPSB0LmlmYWNlKFtdLCB7XG4gIFwiZGF0YVwiOiBcIlByb2dyYW1zXCJcbn0pO1xuY29uc3QgUHJvZ3JhbXMgPSBleHBvcnRzLlByb2dyYW1zID0gdC5pZmFjZShbXSwge1xuICBcInByb2dyYW1zXCI6IHQuYXJyYXkoXCJQcm9ncmFtTGlzdFwiKSxcbiAgXCJzZWxlY3RlZFwiOiB0Lm9wdChcIlByb2dyYW1QYXJ0aWFsXCIpLFxuICBcImFjdGl2ZVwiOiB0Lm9wdChcIlByb2dyYW1QYXJ0aWFsXCIpXG59KTtcbmNvbnN0IFByb2dyYW1MaXN0ID0gZXhwb3J0cy5Qcm9ncmFtTGlzdCA9IHQuaWZhY2UoW10sIHtcbiAgXCJrZXlcIjogXCJzdHJpbmdcIixcbiAgXCJuYW1lXCI6IHQub3B0KFwic3RyaW5nXCIpLFxuICBcImNvbnN0cmFpbnRzXCI6IHQub3B0KFwiUHJvZ3JhbUNvbnN0cmFpbnRzXCIpXG59KTtcbmNvbnN0IFByb2dyYW1Db25zdHJhaW50cyA9IGV4cG9ydHMuUHJvZ3JhbUNvbnN0cmFpbnRzID0gdC5pZmFjZShbXSwge1xuICBcImF2YWlsYWJsZVwiOiB0Lm9wdChcImJvb2xlYW5cIiksXG4gIFwiZXhlY3V0aW9uXCI6IHQub3B0KFwiUHJvZ3JhbUV4ZWN1dGlvblwiKSxcbiAgXCJhY2Nlc3NcIjogdC5vcHQoXCJBY2Nlc3NcIilcbn0pO1xuY29uc3QgUHJvZ3JhbUV4ZWN1dGlvbiA9IGV4cG9ydHMuUHJvZ3JhbUV4ZWN1dGlvbiA9IHQudW5pb24odC5saXQoJ25vbmUnKSwgdC5saXQoJ3NlbGVjdG9ubHknKSwgdC5saXQoJ3N0YXJ0b25seScpLCB0LmxpdCgnc2VsZWN0YW5kc3RhcnQnKSk7XG5jb25zdCBQcm9ncmFtV3JhcHBlciA9IGV4cG9ydHMuUHJvZ3JhbVdyYXBwZXIgPSB0LmlmYWNlKFtdLCB7XG4gIFwiZGF0YVwiOiBcIlByb2dyYW1cIlxufSk7XG5jb25zdCBQcm9ncmFtID0gZXhwb3J0cy5Qcm9ncmFtID0gdC5pZmFjZShbXCJQcm9ncmFtUGFydGlhbFwiXSwge1xuICBcImtleVwiOiBcInN0cmluZ1wiXG59KTtcbmNvbnN0IFByb2dyYW1QYXJ0aWFsID0gZXhwb3J0cy5Qcm9ncmFtUGFydGlhbCA9IHQuaWZhY2UoW10sIHtcbiAgXCJrZXlcIjogdC5vcHQoXCJzdHJpbmdcIiksXG4gIFwibmFtZVwiOiB0Lm9wdChcInN0cmluZ1wiKSxcbiAgXCJvcHRpb25zXCI6IHQub3B0KHQuYXJyYXkoXCJPcHRpb25cIikpLFxuICBcImNvbnN0cmFpbnRzXCI6IHQub3B0KFwiUHJvZ3JhbUNvbnN0cmFpbnRzXCIpXG59KTtcbmNvbnN0IFByb2dyYW1EZWZpbml0aW9uV3JhcHBlciA9IGV4cG9ydHMuUHJvZ3JhbURlZmluaXRpb25XcmFwcGVyID0gdC5pZmFjZShbXSwge1xuICBcImRhdGFcIjogXCJQcm9ncmFtRGVmaW5pdGlvblwiXG59KTtcbmNvbnN0IFByb2dyYW1EZWZpbml0aW9uID0gZXhwb3J0cy5Qcm9ncmFtRGVmaW5pdGlvbiA9IHQuaWZhY2UoW10sIHtcbiAgXCJrZXlcIjogXCJzdHJpbmdcIixcbiAgXCJuYW1lXCI6IHQub3B0KFwic3RyaW5nXCIpLFxuICBcIm9wdGlvbnNcIjogdC5vcHQodC5hcnJheShcIk9wdGlvbkRlZmluaXRpb25cIikpXG59KTtcbmNvbnN0IE9wdGlvbkRlZmluaXRpb24gPSBleHBvcnRzLk9wdGlvbkRlZmluaXRpb24gPSB0LnVuaW9uKFwiT3B0aW9uRGVmaW5pdGlvblN0cmluZ1wiLCBcIk9wdGlvbkRlZmluaXRpb25OdW1iZXJcIiwgXCJPcHRpb25EZWZpbml0aW9uQm9vbGVhblwiKTtcbmNvbnN0IE9wdGlvbkRlZmluaXRpb25TdHJpbmcgPSBleHBvcnRzLk9wdGlvbkRlZmluaXRpb25TdHJpbmcgPSB0LmlmYWNlKFtcIk9wdGlvbkRlZmluaXRpb25Db21tb25cIl0sIHtcbiAgXCJ0eXBlXCI6IHQudW5pb24odC5saXQoJ1N0cmluZycpLCBcInN0cmluZ1wiKSxcbiAgXCJjb25zdHJhaW50c1wiOiB0Lm9wdCh0LmludGVyc2VjdGlvbihcIk9wdGlvbkNvbnN0cmFpbnRzQ29tbW9uXCIsIFwiQ29uc3RyYWludHNTdHJpbmdcIikpXG59KTtcbmNvbnN0IE9wdGlvbkRlZmluaXRpb25OdW1iZXIgPSBleHBvcnRzLk9wdGlvbkRlZmluaXRpb25OdW1iZXIgPSB0LmlmYWNlKFtcIk9wdGlvbkRlZmluaXRpb25Db21tb25cIl0sIHtcbiAgXCJ0eXBlXCI6IHQudW5pb24odC5saXQoJ0RvdWJsZScpLCB0LmxpdCgnSW50JykpLFxuICBcImNvbnN0cmFpbnRzXCI6IHQub3B0KHQuaW50ZXJzZWN0aW9uKFwiT3B0aW9uQ29uc3RyYWludHNDb21tb25cIiwgXCJDb25zdHJhaW50c051bWJlclwiKSlcbn0pO1xuY29uc3QgT3B0aW9uRGVmaW5pdGlvbkJvb2xlYW4gPSBleHBvcnRzLk9wdGlvbkRlZmluaXRpb25Cb29sZWFuID0gdC5pZmFjZShbXCJPcHRpb25EZWZpbml0aW9uQ29tbW9uXCJdLCB7XG4gIFwidHlwZVwiOiB0LmxpdCgnQm9vbGVhbicpLFxuICBcImNvbnN0cmFpbnRzXCI6IHQub3B0KHQuaW50ZXJzZWN0aW9uKFwiT3B0aW9uQ29uc3RyYWludHNDb21tb25cIiwgXCJDb25zdHJhaW50c0Jvb2xlYW5cIikpXG59KTtcbmNvbnN0IE9wdGlvbkRlZmluaXRpb25Db21tb24gPSBleHBvcnRzLk9wdGlvbkRlZmluaXRpb25Db21tb24gPSB0LmlmYWNlKFtdLCB7XG4gIFwia2V5XCI6IFwic3RyaW5nXCIsXG4gIFwibmFtZVwiOiB0Lm9wdChcInN0cmluZ1wiKSxcbiAgXCJ1bml0XCI6IHQub3B0KFwic3RyaW5nXCIpXG59KTtcbmNvbnN0IE9wdGlvbkNvbnN0cmFpbnRzQ29tbW9uID0gZXhwb3J0cy5PcHRpb25Db25zdHJhaW50c0NvbW1vbiA9IHQuaWZhY2UoW10sIHtcbiAgXCJsaXZldXBkYXRlXCI6IHQub3B0KFwiYm9vbGVhblwiKVxufSk7XG5jb25zdCBPcHRpb25zV3JhcHBlciA9IGV4cG9ydHMuT3B0aW9uc1dyYXBwZXIgPSB0LmlmYWNlKFtdLCB7XG4gIFwiZGF0YVwiOiB0LmlmYWNlKFtdLCB7XG4gICAgXCJvcHRpb25zXCI6IHQuYXJyYXkoXCJPcHRpb25cIilcbiAgfSlcbn0pO1xuY29uc3QgT3B0aW9uV3JhcHBlciA9IGV4cG9ydHMuT3B0aW9uV3JhcHBlciA9IHQuaWZhY2UoW10sIHtcbiAgXCJkYXRhXCI6IFwiT3B0aW9uXCJcbn0pO1xuY29uc3QgT3B0aW9uID0gZXhwb3J0cy5PcHRpb24gPSB0LmlmYWNlKFtdLCB7XG4gIFwia2V5XCI6IFwic3RyaW5nXCIsXG4gIFwibmFtZVwiOiB0Lm9wdChcInN0cmluZ1wiKSxcbiAgXCJ2YWx1ZVwiOiBcIlZhbHVlXCIsXG4gIFwiZGlzcGxheXZhbHVlXCI6IHQub3B0KFwic3RyaW5nXCIpLFxuICBcInVuaXRcIjogdC5vcHQoXCJzdHJpbmdcIilcbn0pO1xuY29uc3QgU2V0dGluZ3NXcmFwcGVyID0gZXhwb3J0cy5TZXR0aW5nc1dyYXBwZXIgPSB0LmlmYWNlKFtdLCB7XG4gIFwiZGF0YVwiOiB0LmlmYWNlKFtdLCB7XG4gICAgXCJzZXR0aW5nc1wiOiB0LmFycmF5KFwiU2V0dGluZ1wiKVxuICB9KVxufSk7XG5jb25zdCBTZXR0aW5nV3JhcHBlciA9IGV4cG9ydHMuU2V0dGluZ1dyYXBwZXIgPSB0LmlmYWNlKFtdLCB7XG4gIFwiZGF0YVwiOiBcIlNldHRpbmdcIlxufSk7XG5jb25zdCBTZXR0aW5nID0gZXhwb3J0cy5TZXR0aW5nID0gdC51bmlvbihcIlNldHRpbmdTdHJpbmdcIiwgXCJTZXR0aW5nTnVtYmVyXCIsIFwiU2V0dGluZ0Jvb2xlYW5cIik7XG5jb25zdCBTZXR0aW5nU3RyaW5nID0gZXhwb3J0cy5TZXR0aW5nU3RyaW5nID0gdC5pZmFjZShbXCJTZXR0aW5nQ29tbW9uXCJdLCB7XG4gIFwidmFsdWVcIjogXCJzdHJpbmdcIixcbiAgXCJjb25zdHJhaW50c1wiOiB0Lm9wdChcIkNvbnN0cmFpbnRzU3RyaW5nXCIpXG59KTtcbmNvbnN0IFNldHRpbmdOdW1iZXIgPSBleHBvcnRzLlNldHRpbmdOdW1iZXIgPSB0LmlmYWNlKFtcIlNldHRpbmdDb21tb25cIl0sIHtcbiAgXCJ2YWx1ZVwiOiBcIm51bWJlclwiLFxuICBcImNvbnN0cmFpbnRzXCI6IHQub3B0KFwiQ29uc3RyYWludHNOdW1iZXJcIilcbn0pO1xuY29uc3QgU2V0dGluZ0Jvb2xlYW4gPSBleHBvcnRzLlNldHRpbmdCb29sZWFuID0gdC5pZmFjZShbXCJTZXR0aW5nQ29tbW9uXCJdLCB7XG4gIFwidmFsdWVcIjogXCJib29sZWFuXCIsXG4gIFwiY29uc3RyYWludHNcIjogdC5vcHQoXCJDb25zdHJhaW50c0Jvb2xlYW5cIilcbn0pO1xuY29uc3QgU2V0dGluZ0NvbW1vbiA9IGV4cG9ydHMuU2V0dGluZ0NvbW1vbiA9IHQuaWZhY2UoW10sIHtcbiAgXCJrZXlcIjogXCJzdHJpbmdcIixcbiAgXCJuYW1lXCI6IHQub3B0KFwic3RyaW5nXCIpLFxuICBcInR5cGVcIjogdC5vcHQoXCJzdHJpbmdcIiksXG4gIFwiZGlzcGxheXZhbHVlXCI6IHQub3B0KFwic3RyaW5nXCIpLFxuICBcInVuaXRcIjogdC5vcHQoXCJzdHJpbmdcIilcbn0pO1xuY29uc3QgU3RhdHVzZXNXcmFwcGVyID0gZXhwb3J0cy5TdGF0dXNlc1dyYXBwZXIgPSB0LmlmYWNlKFtdLCB7XG4gIFwiZGF0YVwiOiB0LmlmYWNlKFtdLCB7XG4gICAgXCJzdGF0dXNcIjogdC5hcnJheShcIlN0YXR1c1wiKVxuICB9KVxufSk7XG5jb25zdCBTdGF0dXNXcmFwcGVyID0gZXhwb3J0cy5TdGF0dXNXcmFwcGVyID0gdC5pZmFjZShbXSwge1xuICBcImRhdGFcIjogXCJTdGF0dXNcIlxufSk7XG5jb25zdCBTdGF0dXMgPSBleHBvcnRzLlN0YXR1cyA9IHQudW5pb24oXCJTdGF0dXNTdHJpbmdcIiwgXCJTdGF0dXNOdW1iZXJcIiwgXCJTdGF0dXNCb29sZWFuXCIpO1xuY29uc3QgU3RhdHVzU3RyaW5nID0gZXhwb3J0cy5TdGF0dXNTdHJpbmcgPSB0LmlmYWNlKFtcIlN0YXR1c0NvbW1vblwiXSwge1xuICBcInZhbHVlXCI6IFwic3RyaW5nXCIsXG4gIFwiY29uc3RyYWludHNcIjogdC5vcHQoXCJDb25zdHJhaW50c1N0cmluZ1wiKVxufSk7XG5jb25zdCBTdGF0dXNOdW1iZXIgPSBleHBvcnRzLlN0YXR1c051bWJlciA9IHQuaWZhY2UoW1wiU3RhdHVzQ29tbW9uXCJdLCB7XG4gIFwidmFsdWVcIjogXCJudW1iZXJcIixcbiAgXCJjb25zdHJhaW50c1wiOiB0Lm9wdChcIkNvbnN0cmFpbnRzTnVtYmVyXCIpXG59KTtcbmNvbnN0IFN0YXR1c0Jvb2xlYW4gPSBleHBvcnRzLlN0YXR1c0Jvb2xlYW4gPSB0LmlmYWNlKFtcIlN0YXR1c0NvbW1vblwiXSwge1xuICBcInZhbHVlXCI6IFwiYm9vbGVhblwiLFxuICBcImNvbnN0cmFpbnRzXCI6IHQub3B0KFwiQ29uc3RyYWludHNCb29sZWFuXCIpXG59KTtcbmNvbnN0IFN0YXR1c0NvbW1vbiA9IGV4cG9ydHMuU3RhdHVzQ29tbW9uID0gdC5pZmFjZShbXSwge1xuICBcImtleVwiOiBcInN0cmluZ1wiLFxuICBcIm5hbWVcIjogdC5vcHQoXCJzdHJpbmdcIiksXG4gIFwiZGlzcGxheXZhbHVlXCI6IHQub3B0KFwic3RyaW5nXCIpLFxuICBcInVuaXRcIjogdC5vcHQoXCJzdHJpbmdcIilcbn0pO1xuY29uc3QgRXJyb3JSZXNwb25zZSA9IGV4cG9ydHMuRXJyb3JSZXNwb25zZSA9IHQuaWZhY2UoW10sIHtcbiAgXCJlcnJvclwiOiB0LmlmYWNlKFtdLCB7XG4gICAgXCJrZXlcIjogXCJzdHJpbmdcIixcbiAgICBcImRlc2NyaXB0aW9uXCI6IHQub3B0KFwic3RyaW5nXCIpLFxuICAgIFwiZGV2ZWxvcGVyTWVzc2FnZVwiOiB0Lm9wdChcInN0cmluZ1wiKSxcbiAgICBcInZhbHVlXCI6IHQub3B0KFwic3RyaW5nXCIpXG4gIH0pXG59KTtcbmNvbnN0IGV4cG9ydGVkVHlwZVN1aXRlID0ge1xuICBWYWx1ZSxcbiAgQ29uc3RyYWludHMsXG4gIENvbnN0cmFpbnRzU3RyaW5nLFxuICBDb25zdHJhaW50c051bWJlcixcbiAgQ29uc3RyYWludHNCb29sZWFuLFxuICBDb25zdHJhaW50c0NvbW1vbixcbiAgQWNjZXNzLFxuICBFeGVjdXRlQ29tbWFuZFdyYXBwZXIsXG4gIEV4ZWN1dGVDb21tYW5kLFxuICBDb21tYW5kc1dyYXBwZXIsXG4gIENvbW1hbmQsXG4gIEV2ZW50LFxuICBFdmVudEtlZXBBbGl2ZSxcbiAgRXZlbnRBcHBsaWFuY2VDb25uZWN0aW9uLFxuICBFdmVudEFwcGxpYW5jZURhdGEsXG4gIEV2ZW50RGF0YSxcbiAgRXZlbnRMZXZlbCxcbiAgRXZlbnRIYW5kbGluZyxcbiAgSG9tZUFwcGxpYW5jZXNXcmFwcGVyLFxuICBIb21lQXBwbGlhbmNlV3JhcHBlcixcbiAgSG9tZUFwcGxpYW5jZSxcbiAgSW1hZ2VzV3JhcHBlcixcbiAgSW1hZ2UsXG4gIEltYWdlUXVhbGl0eSxcbiAgUHJvZ3JhbXNXcmFwcGVyLFxuICBQcm9ncmFtcyxcbiAgUHJvZ3JhbUxpc3QsXG4gIFByb2dyYW1Db25zdHJhaW50cyxcbiAgUHJvZ3JhbUV4ZWN1dGlvbixcbiAgUHJvZ3JhbVdyYXBwZXIsXG4gIFByb2dyYW0sXG4gIFByb2dyYW1QYXJ0aWFsLFxuICBQcm9ncmFtRGVmaW5pdGlvbldyYXBwZXIsXG4gIFByb2dyYW1EZWZpbml0aW9uLFxuICBPcHRpb25EZWZpbml0aW9uLFxuICBPcHRpb25EZWZpbml0aW9uU3RyaW5nLFxuICBPcHRpb25EZWZpbml0aW9uTnVtYmVyLFxuICBPcHRpb25EZWZpbml0aW9uQm9vbGVhbixcbiAgT3B0aW9uRGVmaW5pdGlvbkNvbW1vbixcbiAgT3B0aW9uQ29uc3RyYWludHNDb21tb24sXG4gIE9wdGlvbnNXcmFwcGVyLFxuICBPcHRpb25XcmFwcGVyLFxuICBPcHRpb24sXG4gIFNldHRpbmdzV3JhcHBlcixcbiAgU2V0dGluZ1dyYXBwZXIsXG4gIFNldHRpbmcsXG4gIFNldHRpbmdTdHJpbmcsXG4gIFNldHRpbmdOdW1iZXIsXG4gIFNldHRpbmdCb29sZWFuLFxuICBTZXR0aW5nQ29tbW9uLFxuICBTdGF0dXNlc1dyYXBwZXIsXG4gIFN0YXR1c1dyYXBwZXIsXG4gIFN0YXR1cyxcbiAgU3RhdHVzU3RyaW5nLFxuICBTdGF0dXNOdW1iZXIsXG4gIFN0YXR1c0Jvb2xlYW4sXG4gIFN0YXR1c0NvbW1vbixcbiAgRXJyb3JSZXNwb25zZVxufTtcbnZhciBfZGVmYXVsdCA9IGV4cG9ydHMuZGVmYXVsdCA9IGV4cG9ydGVkVHlwZVN1aXRlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ9dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p1WVcxbGN5STZXeUowSWl3aVgybHVkR1Z5YjNCU1pYRjFhWEpsVjJsc1pHTmhjbVFpTENKeVpYRjFhWEpsSWl3aVpTSXNJbGRsWVd0TllYQWlMQ0p5SWl3aWJpSXNJbDlmWlhOTmIyUjFiR1VpTENKdklpd2lhU0lzSW1ZaUxDSmZYM0J5YjNSdlgxOGlMQ0prWldaaGRXeDBJaXdpYUdGeklpd2laMlYwSWl3aWMyVjBJaXdpYUdGelQzZHVVSEp2Y0dWeWRIa2lMQ0pqWVd4c0lpd2lUMkpxWldOMElpd2laR1ZtYVc1bFVISnZjR1Z5ZEhraUxDSm5aWFJQZDI1UWNtOXdaWEowZVVSbGMyTnlhWEIwYjNJaUxDSldZV3gxWlNJc0ltVjRjRzl5ZEhNaUxDSjFibWx2YmlJc0lrTnZibk4wY21GcGJuUnpJaXdpUTI5dWMzUnlZV2x1ZEhOVGRISnBibWNpTENKcFptRmpaU0lzSW05d2RDSXNJbUZ5Y21GNUlpd2lRMjl1YzNSeVlXbHVkSE5PZFcxaVpYSWlMQ0pEYjI1emRISmhhVzUwYzBKdmIyeGxZVzRpTENKRGIyNXpkSEpoYVc1MGMwTnZiVzF2YmlJc0lrRmpZMlZ6Y3lJc0lteHBkQ0lzSWtWNFpXTjFkR1ZEYjIxdFlXNWtWM0poY0hCbGNpSXNJa1Y0WldOMWRHVkRiMjF0WVc1a0lpd2lRMjl0YldGdVpITlhjbUZ3Y0dWeUlpd2lRMjl0YldGdVpDSXNJa1YyWlc1MElpd2lSWFpsYm5STFpXVndRV3hwZG1VaUxDSkZkbVZ1ZEVGd2NHeHBZVzVqWlVOdmJtNWxZM1JwYjI0aUxDSkZkbVZ1ZEVGd2NHeHBZVzVqWlVSaGRHRWlMQ0pGZG1WdWRFUmhkR0VpTENKRmRtVnVkRXhsZG1Wc0lpd2lSWFpsYm5SSVlXNWtiR2x1WnlJc0lraHZiV1ZCY0hCc2FXRnVZMlZ6VjNKaGNIQmxjaUlzSWtodmJXVkJjSEJzYVdGdVkyVlhjbUZ3Y0dWeUlpd2lTRzl0WlVGd2NHeHBZVzVqWlNJc0lrbHRZV2RsYzFkeVlYQndaWElpTENKSmJXRm5aU0lzSWtsdFlXZGxVWFZoYkdsMGVTSXNJbEJ5YjJkeVlXMXpWM0poY0hCbGNpSXNJbEJ5YjJkeVlXMXpJaXdpVUhKdlozSmhiVXhwYzNRaUxDSlFjbTluY21GdFEyOXVjM1J5WVdsdWRITWlMQ0pRY205bmNtRnRSWGhsWTNWMGFXOXVJaXdpVUhKdlozSmhiVmR5WVhCd1pYSWlMQ0pRY205bmNtRnRJaXdpVUhKdlozSmhiVkJoY25ScFlXd2lMQ0pRY205bmNtRnRSR1ZtYVc1cGRHbHZibGR5WVhCd1pYSWlMQ0pRY205bmNtRnRSR1ZtYVc1cGRHbHZiaUlzSWs5d2RHbHZia1JsWm1sdWFYUnBiMjRpTENKUGNIUnBiMjVFWldacGJtbDBhVzl1VTNSeWFXNW5JaXdpYVc1MFpYSnpaV04wYVc5dUlpd2lUM0IwYVc5dVJHVm1hVzVwZEdsdmJrNTFiV0psY2lJc0lrOXdkR2x2YmtSbFptbHVhWFJwYjI1Q2IyOXNaV0Z1SWl3aVQzQjBhVzl1UkdWbWFXNXBkR2x2YmtOdmJXMXZiaUlzSWs5d2RHbHZia052Ym5OMGNtRnBiblJ6UTI5dGJXOXVJaXdpVDNCMGFXOXVjMWR5WVhCd1pYSWlMQ0pQY0hScGIyNVhjbUZ3Y0dWeUlpd2lUM0IwYVc5dUlpd2lVMlYwZEdsdVozTlhjbUZ3Y0dWeUlpd2lVMlYwZEdsdVoxZHlZWEJ3WlhJaUxDSlRaWFIwYVc1bklpd2lVMlYwZEdsdVoxTjBjbWx1WnlJc0lsTmxkSFJwYm1kT2RXMWlaWElpTENKVFpYUjBhVzVuUW05dmJHVmhiaUlzSWxObGRIUnBibWREYjIxdGIyNGlMQ0pUZEdGMGRYTmxjMWR5WVhCd1pYSWlMQ0pUZEdGMGRYTlhjbUZ3Y0dWeUlpd2lVM1JoZEhWeklpd2lVM1JoZEhWelUzUnlhVzVuSWl3aVUzUmhkSFZ6VG5WdFltVnlJaXdpVTNSaGRIVnpRbTl2YkdWaGJpSXNJbE4wWVhSMWMwTnZiVzF2YmlJc0lrVnljbTl5VW1WemNHOXVjMlVpTENKbGVIQnZjblJsWkZSNWNHVlRkV2wwWlNJc0lsOWtaV1poZFd4MElsMHNJbk52ZFhKalpYTWlPbHNpTGk0dkxpNHZjM0pqTDNScEwyRndhUzEwZVhCbGN5MTBhUzUwY3lKZExDSnpiM1Z5WTJWelEyOXVkR1Z1ZENJNlcyNTFiR3hkTENKdFlYQndhVzVuY3lJNklqczdPenM3TzBGQlIwRXNTVUZCUVVFc1EwRkJRU3hIUVVGQlF5eDFRa0ZCUVN4RFFVRkJReXhQUVVGQk8wRkJRVEJETEZOQlFVRkVMSGRDUVVGQlJTeERRVUZCTEVWQlFVRklMRU5CUVVFc05rSkJRVUZKTEU5QlFVRXNUVUZCUVVNc1EwRkJRU3hQUVVGQlJDeFBRVUZCTEVsQlFVRkZMRU5CUVVFc1QwRkJRVVlzVDBGQlFTeFpRVUZCU0N4MVFrRkJRU3haUVVGQlFTeERRVUZCUlN4RFFVRkJMRVZCUVVGSUxFTkJRVUVzVTBGQlFVRXNRMEZCUVN4SlFVRkJSeXhEUVVGQkxFbEJRVUZCTEVOQlFVRXNRMEZCUVVrc1ZVRkJRU3hUUVVGQlNpeERRVUZCTEUxQlFVRkxMRU5CUVVFc1JVRkJRVU1zUTBGQlFTeEZRVUZCUXl4RFFVRkJMRXRCUVVGRExGTkJRVUVzVVVGQlFVTXNUMEZCUVN4RlFVRkJWQ3hEUVVGQkxHbENRVUZCUVN4RFFVRkJMSFZDUVVGQlFTeERRVUZCTEhsQ1FVRkJRU3hEUVVGQkxGTkJRVUZQTEVOQlFVRXNUVUZCUVVZc1EwRkJRU3hIUVVGQlVpeERRVUZCTEVkQlFVRk5MRU5CUVVFc1IwRkJRVVFzUTBGQlFTeFJRVUZCUnl4RFFVRkJMRU5CUVVGTExFZEJRVUVzUTBGQlFWWXNRMEZCUVN4VlFVRkJTeXhEUVVGQkxFTkJRVUZOTEVkQlFVRXNRMEZCUVZnc1EwRkJRU3hIUVVGQlN5eERRVUZCTEVOQlFVRlBMRWRCUVVFc1EwRkJRVm9zUTBGQlFTeEZRVUZCVHl4RFFVRkJMR2RDUVVGQlZpeERRVUZCTEVsQlFVRkhMRU5CUVVFc1owSkJRVUZJTEVOQlFVRXNUMEZCUVdkQ0xHTkJRVUVzUTBGQlFVTXNTVUZCUVN4RFFVRkJaQ3hEUVVGQkxFVkJRVUZJTEVOQlFVRXNUMEZCUVZNc1EwRkJRU3hKUVVGQlJDeERRVUZCTEVkQlFVRlZMRTFCUVVFc1EwRkJRVU1zWTBGQlFTeExRVUZCUkN4TlFVRkJMRU5CUVVGRkxIZENRVUZCTEVOQlFVRnFRaXhEUVVGQkxFVkJRVUZJTEVOQlFVRXNUMEZCUVZNc1EwRkJRU3hEUVVGQlN5eEhRVUZCTEVsQlFVRk1MRU5CUVVFc1EwRkJRVTBzUjBGQlFTeEpRVUZCVUN4RFFVRkJMRU5CUVVGRkxFTkJRVUVzUlVGQlFWWXNRMEZCUVN4RlFVRkJVeXhEUVVGQkxFbEJRVUZETEVOQlFVRXNRMEZCUVZZc1EwRkJRU3hKUVVGQlJ5eERRVUZCTEVOQlFVRklMRU5CUVVFc1YwRkJRVlVzUTBGQlFTeExRVUZCVUN4RFFVRkJMRVZCUVVGSUxFTkJRVUU3UVVGSU1VTTdPenM3UVVGSlFUdEJRVVZQTEUxQlFVMXhRaXhMUVVGTExFZEJRVUZETEU5QlFVRXNRMEZCUVVRc1MwRkJRU3hIUVVGSGNrSXNRMEZCUXl4RFFVRkRkVUlzUzBGQlN5eERRVUZETEZGQlFWRXNSVUZCUlN4UlFVRlJMRVZCUVVVc1UwRkJVeXhEUVVGRE8wRkJSWEJFTEUxQlFVMURMRmRCUVZjc1IwRkJRVVlzVDBGQlFTeERRVUZCUlN4WFFVRkJMRWRCUVVkNFFpeERRVUZETEVOQlFVTjFRaXhMUVVGTExFTkJRVU1zYlVKQlFXMUNMRVZCUVVVc2JVSkJRVzFDTEVWQlFVVXNiMEpCUVc5Q0xFTkJRVU03UVVGRk0wWXNUVUZCVFVVc2FVSkJRV2xDTEVkQlFVRklMRTlCUVVFc1EwRkJRVWNzYVVKQlFVRXNSMEZCUjNwQ0xFTkJRVU1zUTBGQlF6QkNMRXRCUVVzc1EwRkJReXhEUVVGRExHMUNRVUZ0UWl4RFFVRkRMRVZCUVVVN1JVRkRPVVFzVTBGQlV5eEZRVUZGTVVJc1EwRkJReXhEUVVGRE1rSXNSMEZCUnl4RFFVRkRMRkZCUVZFc1EwRkJRenRGUVVNeFFpeGxRVUZsTEVWQlFVVXpRaXhEUVVGRExFTkJRVU15UWl4SFFVRkhMRU5CUVVNelFpeERRVUZETEVOQlFVTTBRaXhMUVVGTExFTkJRVU1zVVVGQlVTeERRVUZETEVOQlFVTTdSVUZEZWtNc1pVRkJaU3hGUVVGRk5VSXNRMEZCUXl4RFFVRkRNa0lzUjBGQlJ5eERRVUZETTBJc1EwRkJReXhEUVVGRE5FSXNTMEZCU3l4RFFVRkRMRkZCUVZFc1EwRkJRenREUVVONlF5eERRVUZETzBGQlJVc3NUVUZCVFVNc2FVSkJRV2xDTEVkQlFVRlFMRTlCUVVFc1EwRkJRVThzYVVKQlFVRXNSMEZCUnpkQ0xFTkJRVU1zUTBGQlF6QkNMRXRCUVVzc1EwRkJReXhEUVVGRExHMUNRVUZ0UWl4RFFVRkRMRVZCUVVVN1JVRkRPVVFzVTBGQlV5eEZRVUZGTVVJc1EwRkJReXhEUVVGRE1rSXNSMEZCUnl4RFFVRkRMRkZCUVZFc1EwRkJRenRGUVVNeFFpeExRVUZMTEVWQlFVVXpRaXhEUVVGRExFTkJRVU15UWl4SFFVRkhMRU5CUVVNc1VVRkJVU3hEUVVGRE8wVkJRM1JDTEV0QlFVc3NSVUZCUlROQ0xFTkJRVU1zUTBGQlF6SkNMRWRCUVVjc1EwRkJReXhSUVVGUkxFTkJRVU03UlVGRGRFSXNWVUZCVlN4RlFVRkZNMElzUTBGQlF5eERRVUZETWtJc1IwRkJSeXhEUVVGRExGRkJRVkU3UTBGRE0wSXNRMEZCUXp0QlFVVkxMRTFCUVUxSExHdENRVUZyUWl4SFFVRkJVaXhQUVVGQkxFTkJRVUZSTEd0Q1FVRkJMRWRCUVVjNVFpeERRVUZETEVOQlFVTXdRaXhMUVVGTExFTkJRVU1zUTBGQlF5eHRRa0ZCYlVJc1EwRkJReXhGUVVGRk8wVkJReTlFTEZOQlFWTXNSVUZCUlRGQ0xFTkJRVU1zUTBGQlF6SkNMRWRCUVVjc1EwRkJReXhUUVVGVE8wTkJRek5DTEVOQlFVTTdRVUZGU3l4TlFVRk5TU3hwUWtGQmFVSXNSMEZCUVZRc1QwRkJRU3hEUVVGQlV5eHBRa0ZCUVN4SFFVRkhMMElzUTBGQlF5eERRVUZETUVJc1MwRkJTeXhEUVVGRExFVkJRVVVzUlVGQlJUdEZRVU16UXl4UlFVRlJMRVZCUVVVeFFpeERRVUZETEVOQlFVTXlRaXhIUVVGSExFTkJRVU1zVVVGQlVUdERRVU42UWl4RFFVRkRPMEZCUlVzc1RVRkJUVXNzVFVGQlRTeEhRVUZCVml4UFFVRkJMRU5CUVVGVkxFMUJRVUVzUjBGQlIyaERMRU5CUVVNc1EwRkJRM1ZDTEV0QlFVc3NRMEZCUTNaQ0xFTkJRVU1zUTBGQlEybERMRWRCUVVjc1EwRkJReXhOUVVGTkxFTkJRVU1zUlVGQlJXcERMRU5CUVVNc1EwRkJRMmxETEVkQlFVY3NRMEZCUXl4WFFVRlhMRU5CUVVNc1EwRkJRenRCUVVWNlJDeE5RVUZOUXl4eFFrRkJjVUlzUjBGQlFWb3NUMEZCUVN4RFFVRkJXU3h4UWtGQlFTeEhRVUZIYkVNc1EwRkJReXhEUVVGRE1FSXNTMEZCU3l4RFFVRkRMRVZCUVVVc1JVRkJSVHRGUVVNdlF5eE5RVUZOTEVWQlFVVTdRMEZEVkN4RFFVRkRPMEZCUlVzc1RVRkJUVk1zWTBGQll5eEhRVUZCWWl4UFFVRkJMRU5CUVVGaExHTkJRVUVzUjBGQlIyNURMRU5CUVVNc1EwRkJRekJDTEV0QlFVc3NRMEZCUXl4RlFVRkZMRVZCUVVVN1JVRkRlRU1zUzBGQlN5eEZRVUZGTEZGQlFWRTdSVUZEWml4UFFVRlBMRVZCUVVVeFFpeERRVUZETEVOQlFVTnBReXhIUVVGSExFTkJRVU1zU1VGQlNUdERRVU53UWl4RFFVRkRPMEZCUlVzc1RVRkJUVWNzWlVGQlpTeEhRVUZCWkN4UFFVRkJMRU5CUVVGakxHVkJRVUVzUjBGQlIzQkRMRU5CUVVNc1EwRkJRekJDTEV0QlFVc3NRMEZCUXl4RlFVRkZMRVZCUVVVN1JVRkRla01zVFVGQlRTeEZRVUZGTVVJc1EwRkJReXhEUVVGRE1FSXNTMEZCU3l4RFFVRkRMRVZCUVVVc1JVRkJSVHRKUVVOc1FpeFZRVUZWTEVWQlFVVXhRaXhEUVVGRExFTkJRVU0wUWl4TFFVRkxMRU5CUVVNc1UwRkJVenRIUVVNNVFqdERRVU5HTEVOQlFVTTdRVUZGU3l4TlFVRk5VeXhQUVVGUExFZEJRVUZtTEU5QlFVRXNRMEZCUVdVc1QwRkJRU3hIUVVGSGNrTXNRMEZCUXl4RFFVRkRNRUlzUzBGQlN5eERRVUZETEVWQlFVVXNSVUZCUlR0RlFVTnFReXhMUVVGTExFVkJRVVVzVVVGQlVUdEZRVU5tTEUxQlFVMHNSVUZCUlRGQ0xFTkJRVU1zUTBGQlF6SkNMRWRCUVVjc1EwRkJReXhSUVVGUkxFTkJRVU03UlVGRGRrSXNZVUZCWVN4RlFVRkZNMElzUTBGQlF5eERRVUZETWtJc1IwRkJSeXhEUVVGRExGRkJRVkU3UTBGRE9VSXNRMEZCUXp0QlFVVkxMRTFCUVUxWExFdEJRVXNzUjBGQlFXaENMRTlCUVVFc1EwRkJRV2RDTEV0QlFVRXNSMEZCUjNSRExFTkJRVU1zUTBGQlEzVkNMRXRCUVVzc1EwRkJReXhuUWtGQlowSXNSVUZCUlN3d1FrRkJNRUlzUlVGQlJTeHZRa0ZCYjBJc1EwRkJRenRCUVVWNlJpeE5RVUZOWjBJc1kwRkJZeXhIUVVGQmFrSXNUMEZCUVN4RFFVRkJhVUlzWTBGQlFTeEhRVUZIZGtNc1EwRkJReXhEUVVGRE1FSXNTMEZCU3l4RFFVRkRMRVZCUVVVc1JVRkJSVHRGUVVONFF5eFBRVUZQTEVWQlFVVXhRaXhEUVVGRExFTkJRVU5wUXl4SFFVRkhMRU5CUVVNc1dVRkJXU3hEUVVGRE8wVkJRelZDTEUxQlFVMHNSVUZCUldwRExFTkJRVU1zUTBGQlF6SkNMRWRCUVVjc1EwRkJRek5DTEVOQlFVTXNRMEZCUTJsRExFZEJRVWNzUTBGQlF5eEZRVUZGTEVOQlFVTTdRMEZEZUVJc1EwRkJRenRCUVVWTExFMUJRVTFQTEhkQ1FVRjNRaXhIUVVGQmJFSXNUMEZCUVN4RFFVRkJhMElzZDBKQlFVRXNSMEZCUjNoRExFTkJRVU1zUTBGQlF6QkNMRXRCUVVzc1EwRkJReXhGUVVGRkxFVkJRVVU3UlVGRGJFUXNUMEZCVHl4RlFVRkZNVUlzUTBGQlF5eERRVUZEZFVJc1MwRkJTeXhEUVVGRGRrSXNRMEZCUXl4RFFVRkRhVU1zUjBGQlJ5eERRVUZETEZkQlFWY3NRMEZCUXl4RlFVRkZha01zUTBGQlF5eERRVUZEYVVNc1IwRkJSeXhEUVVGRExHTkJRV01zUTBGQlF5eEZRVUZGYWtNc1EwRkJReXhEUVVGRGFVTXNSMEZCUnl4RFFVRkRMRkZCUVZFc1EwRkJReXhGUVVGRmFrTXNRMEZCUXl4RFFVRkRhVU1zUjBGQlJ5eERRVUZETEZWQlFWVXNRMEZCUXl4RFFVRkRPMFZCUXk5R0xFbEJRVWtzUlVGQlJTeFJRVUZSTzBWQlEyUXNUVUZCVFN4RlFVRkZha01zUTBGQlF5eERRVUZETWtJc1IwRkJSeXhEUVVGRE0wSXNRMEZCUXl4RFFVRkRkVUlzUzBGQlN5eERRVUZEZGtJc1EwRkJReXhEUVVGRGFVTXNSMEZCUnl4RFFVRkRMRVZCUVVVc1EwRkJReXhGUVVGRkxGZEJRVmNzUTBGQlF6dERRVU01UXl4RFFVRkRPMEZCUlVzc1RVRkJUVkVzYTBKQlFXdENMRWRCUVVGdVFpeFBRVUZCTEVOQlFVRnRRaXhyUWtGQlFTeEhRVUZIZWtNc1EwRkJReXhEUVVGRE1FSXNTMEZCU3l4RFFVRkRMRVZCUVVVc1JVRkJSVHRGUVVNMVF5eFBRVUZQTEVWQlFVVXhRaXhEUVVGRExFTkJRVU4xUWl4TFFVRkxMRU5CUVVOMlFpeERRVUZETEVOQlFVTnBReXhIUVVGSExFTkJRVU1zVVVGQlVTeERRVUZETEVWQlFVVnFReXhEUVVGRExFTkJRVU5wUXl4SFFVRkhMRU5CUVVNc1QwRkJUeXhEUVVGRExFVkJRVVZxUXl4RFFVRkRMRU5CUVVOcFF5eEhRVUZITEVOQlFVTXNVVUZCVVN4RFFVRkRMRU5CUVVNN1JVRkRiRVVzU1VGQlNTeEZRVUZGTEZGQlFWRTdSVUZEWkN4TlFVRk5MRVZCUVVWcVF5eERRVUZETEVOQlFVTXdRaXhMUVVGTExFTkJRVU1zUlVGQlJTeEZRVUZGTzBsQlEyeENMRTlCUVU4c1JVRkJSVEZDTEVOQlFVTXNRMEZCUXpSQ0xFdEJRVXNzUTBGQlF5eFhRVUZYTEVOQlFVTTdTVUZETjBJc1RVRkJUU3hGUVVGRk5VSXNRMEZCUXl4RFFVRkRNa0lzUjBGQlJ5eERRVUZETEZGQlFWRTdSMEZEZGtJN1EwRkRSaXhEUVVGRE8wRkJSVXNzVFVGQlRXVXNVMEZCVXl4SFFVRkJjRUlzVDBGQlFTeERRVUZCYjBJc1UwRkJRU3hIUVVGSE1VTXNRMEZCUXl4RFFVRkRNRUlzUzBGQlN5eERRVUZETEVWQlFVVXNSVUZCUlR0RlFVTnVReXhMUVVGTExFVkJRVVVzVVVGQlVUdEZRVU5tTEUxQlFVMHNSVUZCUlRGQ0xFTkJRVU1zUTBGQlF6SkNMRWRCUVVjc1EwRkJReXhSUVVGUkxFTkJRVU03UlVGRGRrSXNTMEZCU3l4RlFVRkZNMElzUTBGQlF5eERRVUZETWtJc1IwRkJSeXhEUVVGRExGRkJRVkVzUTBGQlF6dEZRVU4wUWl4WFFVRlhMRVZCUVVVelFpeERRVUZETEVOQlFVTjFRaXhMUVVGTExFTkJRVU1zVVVGQlVTeEZRVUZGTEUxQlFVMHNRMEZCUXp0RlFVTjBReXhQUVVGUExFVkJRVVVzV1VGQldUdEZRVU55UWl4VlFVRlZMRVZCUVVVc1pVRkJaVHRGUVVNelFpeFBRVUZQTEVWQlFVVjJRaXhEUVVGRExFTkJRVU4xUWl4TFFVRkxMRU5CUVVNc1QwRkJUeXhGUVVGRkxFMUJRVTBzUTBGQlF6dEZRVU5xUXl4alFVRmpMRVZCUVVWMlFpeERRVUZETEVOQlFVTXlRaXhIUVVGSExFTkJRVU1zVVVGQlVTeERRVUZETzBWQlF5OUNMRTFCUVUwc1JVRkJSVE5DTEVOQlFVTXNRMEZCUXpKQ0xFZEJRVWNzUTBGQlF5eFJRVUZSTEVOQlFVTTdSVUZEZGtJc1RVRkJUU3hGUVVGRk0wSXNRMEZCUXl4RFFVRkRNa0lzUjBGQlJ5eERRVUZETEZGQlFWRTdRMEZEZGtJc1EwRkJRenRCUVVWTExFMUJRVTFuUWl4VlFVRlZMRWRCUVVGeVFpeFBRVUZCTEVOQlFVRnhRaXhWUVVGQkxFZEJRVWN6UXl4RFFVRkRMRU5CUVVOMVFpeExRVUZMTEVOQlFVTjJRaXhEUVVGRExFTkJRVU5wUXl4SFFVRkhMRU5CUVVNc1ZVRkJWU3hEUVVGRExFVkJRVVZxUXl4RFFVRkRMRU5CUVVOcFF5eEhRVUZITEVOQlFVTXNUMEZCVHl4RFFVRkRMRVZCUVVWcVF5eERRVUZETEVOQlFVTnBReXhIUVVGSExFTkJRVU1zVTBGQlV5eERRVUZETEVWQlFVVnFReXhEUVVGRExFTkJRVU5wUXl4SFFVRkhMRU5CUVVNc1RVRkJUU3hEUVVGRExFVkJRVVZxUXl4RFFVRkRMRU5CUVVOcFF5eEhRVUZITEVOQlFVTXNUVUZCVFN4RFFVRkRMRU5CUVVNN1FVRkZOMGNzVFVGQlRWY3NZVUZCWVN4SFFVRkJkRUlzVDBGQlFTeERRVUZCYzBJc1lVRkJRU3hIUVVGSE5VTXNRMEZCUXl4RFFVRkRkVUlzUzBGQlN5eERRVUZEZGtJc1EwRkJReXhEUVVGRGFVTXNSMEZCUnl4RFFVRkRMRTFCUVUwc1EwRkJReXhGUVVGRmFrTXNRMEZCUXl4RFFVRkRhVU1zUjBGQlJ5eERRVUZETEdGQlFXRXNRMEZCUXl4RlFVRkZha01zUTBGQlF5eERRVUZEYVVNc1IwRkJSeXhEUVVGRExGVkJRVlVzUTBGQlF5eERRVUZETzBGQlJYSkdMRTFCUVUxWkxIRkNRVUZ4UWl4SFFVRkJka0lzVDBGQlFTeERRVUZCZFVJc2NVSkJRVUVzUjBGQlJ6ZERMRU5CUVVNc1EwRkJRekJDTEV0QlFVc3NRMEZCUXl4RlFVRkZMRVZCUVVVN1JVRkRMME1zVFVGQlRTeEZRVUZGTVVJc1EwRkJReXhEUVVGRE1FSXNTMEZCU3l4RFFVRkRMRVZCUVVVc1JVRkJSVHRKUVVOc1FpeG5Ra0ZCWjBJc1JVRkJSVEZDTEVOQlFVTXNRMEZCUXpSQ0xFdEJRVXNzUTBGQlF5eGxRVUZsTzBkQlF6RkRPME5CUTBZc1EwRkJRenRCUVVWTExFMUJRVTFyUWl4dlFrRkJiMElzUjBGQlFYaENMRTlCUVVFc1EwRkJRWGRDTEc5Q1FVRkJMRWRCUVVjNVF5eERRVUZETEVOQlFVTXdRaXhMUVVGTExFTkJRVU1zUlVGQlJTeEZRVUZGTzBWQlF6bERMRTFCUVUwc1JVRkJSVHREUVVOVUxFTkJRVU03UVVGRlN5eE5RVUZOY1VJc1lVRkJZU3hIUVVGQmVrSXNUMEZCUVN4RFFVRkJlVUlzWVVGQlFTeEhRVUZITDBNc1EwRkJReXhEUVVGRE1FSXNTMEZCU3l4RFFVRkRMRVZCUVVVc1JVRkJSVHRGUVVOMlF5eE5RVUZOTEVWQlFVVXNVVUZCVVR0RlFVTm9RaXhOUVVGTkxFVkJRVVVzVVVGQlVUdEZRVU5vUWl4TlFVRk5MRVZCUVVVc1VVRkJVVHRGUVVOb1FpeFBRVUZQTEVWQlFVVXNVVUZCVVR0RlFVTnFRaXhMUVVGTExFVkJRVVVzVVVGQlVUdEZRVU5tTEZOQlFWTXNSVUZCUlN4UlFVRlJPMFZCUTI1Q0xGZEJRVmNzUlVGQlJUdERRVU5rTEVOQlFVTTdRVUZGU3l4TlFVRk5jMElzWVVGQllTeEhRVUZCTVVJc1QwRkJRU3hEUVVGQk1FSXNZVUZCUVN4SFFVRkhhRVFzUTBGQlF5eERRVUZETUVJc1MwRkJTeXhEUVVGRExFVkJRVVVzUlVGQlJUdEZRVU4yUXl4TlFVRk5MRVZCUVVVeFFpeERRVUZETEVOQlFVTXdRaXhMUVVGTExFTkJRVU1zUlVGQlJTeEZRVUZGTzBsQlEyeENMRkZCUVZFc1JVRkJSVEZDTEVOQlFVTXNRMEZCUXpSQ0xFdEJRVXNzUTBGQlF5eFBRVUZQTzBkQlF6RkNPME5CUTBZc1EwRkJRenRCUVVWTExFMUJRVTF4UWl4TFFVRkxMRWRCUVVFelFpeFBRVUZCTEVOQlFVRXlRaXhMUVVGQkxFZEJRVWRxUkN4RFFVRkRMRU5CUVVNd1FpeExRVUZMTEVOQlFVTXNSVUZCUlN4RlFVRkZPMFZCUXk5Q0xFdEJRVXNzUlVGQlJTeFJRVUZSTzBWQlEyWXNUVUZCVFN4RlFVRkZNVUlzUTBGQlF5eERRVUZETWtJc1IwRkJSeXhEUVVGRExGRkJRVkVzUTBGQlF6dEZRVU4yUWl4VlFVRlZMRVZCUVVVc1VVRkJVVHRGUVVOd1FpeHBRa0ZCYVVJc1JVRkJSU3hSUVVGUk8wVkJRek5DTEZkQlFWY3NSVUZCUlN4UlFVRlJPMFZCUTNKQ0xGTkJRVk1zUlVGQlJUdERRVU5hTEVOQlFVTTdRVUZGU3l4TlFVRk5kVUlzV1VGQldTeEhRVUZCTlVJc1QwRkJRU3hEUVVGQk5FSXNXVUZCUVN4SFFVRkhiRVFzUTBGQlF5eERRVUZEZFVJc1MwRkJTeXhEUVVGRGRrSXNRMEZCUXl4RFFVRkRhVU1zUjBGQlJ5eERRVUZETEUxQlFVMHNRMEZCUXl4RlFVRkZha01zUTBGQlF5eERRVUZEYVVNc1IwRkJSeXhEUVVGRExFdEJRVXNzUTBGQlF5eERRVUZETzBGQlJYcEVMRTFCUVUxclFpeGxRVUZsTEVkQlFVRTNRaXhQUVVGQkxFTkJRVUUyUWl4bFFVRkJMRWRCUVVkdVJDeERRVUZETEVOQlFVTXdRaXhMUVVGTExFTkJRVU1zUlVGQlJTeEZRVUZGTzBWQlEzcERMRTFCUVUwc1JVRkJSVHREUVVOVUxFTkJRVU03UVVGRlN5eE5RVUZOTUVJc1VVRkJVU3hIUVVGQk9VSXNUMEZCUVN4RFFVRkJPRUlzVVVGQlFTeEhRVUZIY0VRc1EwRkJReXhEUVVGRE1FSXNTMEZCU3l4RFFVRkRMRVZCUVVVc1JVRkJSVHRGUVVOc1F5eFZRVUZWTEVWQlFVVXhRaXhEUVVGRExFTkJRVU0wUWl4TFFVRkxMRU5CUVVNc1lVRkJZU3hEUVVGRE8wVkJRMnhETEZWQlFWVXNSVUZCUlRWQ0xFTkJRVU1zUTBGQlF6SkNMRWRCUVVjc1EwRkJReXhuUWtGQlowSXNRMEZCUXp0RlFVTnVReXhSUVVGUkxFVkJRVVV6UWl4RFFVRkRMRU5CUVVNeVFpeEhRVUZITEVOQlFVTXNaMEpCUVdkQ08wTkJRMnBETEVOQlFVTTdRVUZGU3l4TlFVRk5NRUlzVjBGQlZ5eEhRVUZCTDBJc1QwRkJRU3hEUVVGQkswSXNWMEZCUVN4SFFVRkhja1FzUTBGQlF5eERRVUZETUVJc1MwRkJTeXhEUVVGRExFVkJRVVVzUlVGQlJUdEZRVU55UXl4TFFVRkxMRVZCUVVVc1VVRkJVVHRGUVVObUxFMUJRVTBzUlVGQlJURkNMRU5CUVVNc1EwRkJRekpDTEVkQlFVY3NRMEZCUXl4UlFVRlJMRU5CUVVNN1JVRkRka0lzWVVGQllTeEZRVUZGTTBJc1EwRkJReXhEUVVGRE1rSXNSMEZCUnl4RFFVRkRMRzlDUVVGdlFqdERRVU14UXl4RFFVRkRPMEZCUlVzc1RVRkJUVEpDTEd0Q1FVRnJRaXhIUVVGQmFFTXNUMEZCUVN4RFFVRkJaME1zYTBKQlFVRXNSMEZCUjNSRUxFTkJRVU1zUTBGQlF6QkNMRXRCUVVzc1EwRkJReXhGUVVGRkxFVkJRVVU3UlVGRE5VTXNWMEZCVnl4RlFVRkZNVUlzUTBGQlF5eERRVUZETWtJc1IwRkJSeXhEUVVGRExGTkJRVk1zUTBGQlF6dEZRVU0zUWl4WFFVRlhMRVZCUVVVelFpeERRVUZETEVOQlFVTXlRaXhIUVVGSExFTkJRVU1zYTBKQlFXdENMRU5CUVVNN1JVRkRkRU1zVVVGQlVTeEZRVUZGTTBJc1EwRkJReXhEUVVGRE1rSXNSMEZCUnl4RFFVRkRMRkZCUVZFN1EwRkRla0lzUTBGQlF6dEJRVVZMTEUxQlFVMDBRaXhuUWtGQlowSXNSMEZCUVdwRExFOUJRVUVzUTBGQlFXbERMR2RDUVVGQkxFZEJRVWQyUkN4RFFVRkRMRU5CUVVOMVFpeExRVUZMTEVOQlFVTjJRaXhEUVVGRExFTkJRVU5wUXl4SFFVRkhMRU5CUVVNc1RVRkJUU3hEUVVGRExFVkJRVVZxUXl4RFFVRkRMRU5CUVVOcFF5eEhRVUZITEVOQlFVTXNXVUZCV1N4RFFVRkRMRVZCUVVWcVF5eERRVUZETEVOQlFVTnBReXhIUVVGSExFTkJRVU1zVjBGQlZ5eERRVUZETEVWQlFVVnFReXhEUVVGRExFTkJRVU5wUXl4SFFVRkhMRU5CUVVNc1owSkJRV2RDTEVOQlFVTXNRMEZCUXp0QlFVVnFTQ3hOUVVGTmRVSXNZMEZCWXl4SFFVRkJiRU1zVDBGQlFTeERRVUZCYTBNc1kwRkJRU3hIUVVGSGVFUXNRMEZCUXl4RFFVRkRNRUlzUzBGQlN5eERRVUZETEVWQlFVVXNSVUZCUlR0RlFVTjRReXhOUVVGTkxFVkJRVVU3UTBGRFZDeERRVUZETzBGQlJVc3NUVUZCVFN0Q0xFOUJRVThzUjBGQlFXNURMRTlCUVVFc1EwRkJRVzFETEU5QlFVRXNSMEZCUjNwRUxFTkJRVU1zUTBGQlF6QkNMRXRCUVVzc1EwRkJReXhEUVVGRExHZENRVUZuUWl4RFFVRkRMRVZCUVVVN1JVRkRha1FzUzBGQlN5eEZRVUZGTzBOQlExSXNRMEZCUXp0QlFVVkxMRTFCUVUxblF5eGpRVUZqTEVkQlFVRndReXhQUVVGQkxFTkJRVUZ2UXl4alFVRkJMRWRCUVVjeFJDeERRVUZETEVOQlFVTXdRaXhMUVVGTExFTkJRVU1zUlVGQlJTeEZRVUZGTzBWQlEzaERMRXRCUVVzc1JVRkJSVEZDTEVOQlFVTXNRMEZCUXpKQ0xFZEJRVWNzUTBGQlF5eFJRVUZSTEVOQlFVTTdSVUZEZEVJc1RVRkJUU3hGUVVGRk0wSXNRMEZCUXl4RFFVRkRNa0lzUjBGQlJ5eERRVUZETEZGQlFWRXNRMEZCUXp0RlFVTjJRaXhUUVVGVExFVkJRVVV6UWl4RFFVRkRMRU5CUVVNeVFpeEhRVUZITEVOQlFVTXpRaXhEUVVGRExFTkJRVU0wUWl4TFFVRkxMRU5CUVVNc1VVRkJVU3hEUVVGRExFTkJRVU03UlVGRGJrTXNZVUZCWVN4RlFVRkZOVUlzUTBGQlF5eERRVUZETWtJc1IwRkJSeXhEUVVGRExHOUNRVUZ2UWp0RFFVTXhReXhEUVVGRE8wRkJSVXNzVFVGQlRXZERMSGRDUVVGM1FpeEhRVUZCY2tNc1QwRkJRU3hEUVVGQmNVTXNkMEpCUVVFc1IwRkJSek5FTEVOQlFVTXNRMEZCUXpCQ0xFdEJRVXNzUTBGQlF5eEZRVUZGTEVWQlFVVTdSVUZEYkVRc1RVRkJUU3hGUVVGRk8wTkJRMVFzUTBGQlF6dEJRVVZMTEUxQlFVMXJReXhwUWtGQmFVSXNSMEZCUVhSRExFOUJRVUVzUTBGQlFYTkRMR2xDUVVGQkxFZEJRVWMxUkN4RFFVRkRMRU5CUVVNd1FpeExRVUZMTEVOQlFVTXNSVUZCUlN4RlFVRkZPMFZCUXpORExFdEJRVXNzUlVGQlJTeFJRVUZSTzBWQlEyWXNUVUZCVFN4RlFVRkZNVUlzUTBGQlF5eERRVUZETWtJc1IwRkJSeXhEUVVGRExGRkJRVkVzUTBGQlF6dEZRVU4yUWl4VFFVRlRMRVZCUVVVelFpeERRVUZETEVOQlFVTXlRaXhIUVVGSExFTkJRVU16UWl4RFFVRkRMRU5CUVVNMFFpeExRVUZMTEVOQlFVTXNhMEpCUVd0Q0xFTkJRVU03UTBGRE4wTXNRMEZCUXp0QlFVVkxMRTFCUVUxcFF5eG5Ra0ZCWjBJc1IwRkJRWFpETEU5QlFVRXNRMEZCUVhWRExHZENRVUZCTEVkQlFVYzNSQ3hEUVVGRExFTkJRVU4xUWl4TFFVRkxMRU5CUVVNc2QwSkJRWGRDTEVWQlFVVXNkMEpCUVhkQ0xFVkJRVVVzZVVKQlFYbENMRU5CUVVNN1FVRkZMMGNzVFVGQlRYVkRMSE5DUVVGelFpeEhRVUZCZUVNc1QwRkJRU3hEUVVGQmQwTXNjMEpCUVVFc1IwRkJSemxFTEVOQlFVTXNRMEZCUXpCQ0xFdEJRVXNzUTBGQlF5eERRVUZETEhkQ1FVRjNRaXhEUVVGRExFVkJRVVU3UlVGRGVFVXNUVUZCVFN4RlFVRkZNVUlzUTBGQlF5eERRVUZEZFVJc1MwRkJTeXhEUVVGRGRrSXNRMEZCUXl4RFFVRkRhVU1zUjBGQlJ5eERRVUZETEZGQlFWRXNRMEZCUXl4RlFVRkZMRkZCUVZFc1EwRkJRenRGUVVNeFF5eGhRVUZoTEVWQlFVVnFReXhEUVVGRExFTkJRVU15UWl4SFFVRkhMRU5CUVVNelFpeERRVUZETEVOQlFVTXJSQ3haUVVGWkxFTkJRVU1zZVVKQlFYbENMRVZCUVVVc2JVSkJRVzFDTEVOQlFVTTdRMEZEY0VZc1EwRkJRenRCUVVWTExFMUJRVTFETEhOQ1FVRnpRaXhIUVVGQk1VTXNUMEZCUVN4RFFVRkJNRU1zYzBKQlFVRXNSMEZCUjJoRkxFTkJRVU1zUTBGQlF6QkNMRXRCUVVzc1EwRkJReXhEUVVGRExIZENRVUYzUWl4RFFVRkRMRVZCUVVVN1JVRkRlRVVzVFVGQlRTeEZRVUZGTVVJc1EwRkJReXhEUVVGRGRVSXNTMEZCU3l4RFFVRkRka0lzUTBGQlF5eERRVUZEYVVNc1IwRkJSeXhEUVVGRExGRkJRVkVzUTBGQlF5eEZRVUZGYWtNc1EwRkJReXhEUVVGRGFVTXNSMEZCUnl4RFFVRkRMRXRCUVVzc1EwRkJReXhEUVVGRE8wVkJRemxETEdGQlFXRXNSVUZCUldwRExFTkJRVU1zUTBGQlF6SkNMRWRCUVVjc1EwRkJRek5DTEVOQlFVTXNRMEZCUXl0RUxGbEJRVmtzUTBGQlF5eDVRa0ZCZVVJc1JVRkJSU3h0UWtGQmJVSXNRMEZCUXp0RFFVTndSaXhEUVVGRE8wRkJSVXNzVFVGQlRVVXNkVUpCUVhWQ0xFZEJRVUV6UXl4UFFVRkJMRU5CUVVFeVF5eDFRa0ZCUVN4SFFVRkhha1VzUTBGQlF5eERRVUZETUVJc1MwRkJTeXhEUVVGRExFTkJRVU1zZDBKQlFYZENMRU5CUVVNc1JVRkJSVHRGUVVONlJTeE5RVUZOTEVWQlFVVXhRaXhEUVVGRExFTkJRVU5wUXl4SFFVRkhMRU5CUVVNc1UwRkJVeXhEUVVGRE8wVkJRM2hDTEdGQlFXRXNSVUZCUldwRExFTkJRVU1zUTBGQlF6SkNMRWRCUVVjc1EwRkJRek5DTEVOQlFVTXNRMEZCUXl0RUxGbEJRVmtzUTBGQlF5eDVRa0ZCZVVJc1JVRkJSU3h2UWtGQmIwSXNRMEZCUXp0RFFVTnlSaXhEUVVGRE8wRkJSVXNzVFVGQlRVY3NjMEpCUVhOQ0xFZEJRVUUxUXl4UFFVRkJMRU5CUVVFMFF5eHpRa0ZCUVN4SFFVRkhiRVVzUTBGQlF5eERRVUZETUVJc1MwRkJTeXhEUVVGRExFVkJRVVVzUlVGQlJUdEZRVU5vUkN4TFFVRkxMRVZCUVVVc1VVRkJVVHRGUVVObUxFMUJRVTBzUlVGQlJURkNMRU5CUVVNc1EwRkJRekpDTEVkQlFVY3NRMEZCUXl4UlFVRlJMRU5CUVVNN1JVRkRka0lzVFVGQlRTeEZRVUZGTTBJc1EwRkJReXhEUVVGRE1rSXNSMEZCUnl4RFFVRkRMRkZCUVZFN1EwRkRka0lzUTBGQlF6dEJRVVZMTEUxQlFVMTNReXgxUWtGQmRVSXNSMEZCUVRkRExFOUJRVUVzUTBGQlFUWkRMSFZDUVVGQkxFZEJRVWR1UlN4RFFVRkRMRU5CUVVNd1FpeExRVUZMTEVOQlFVTXNSVUZCUlN4RlFVRkZPMFZCUTJwRUxGbEJRVmtzUlVGQlJURkNMRU5CUVVNc1EwRkJRekpDTEVkQlFVY3NRMEZCUXl4VFFVRlRPME5CUXpsQ0xFTkJRVU03UVVGRlN5eE5RVUZOZVVNc1kwRkJZeXhIUVVGQk9VTXNUMEZCUVN4RFFVRkJPRU1zWTBGQlFTeEhRVUZIY0VVc1EwRkJReXhEUVVGRE1FSXNTMEZCU3l4RFFVRkRMRVZCUVVVc1JVRkJSVHRGUVVONFF5eE5RVUZOTEVWQlFVVXhRaXhEUVVGRExFTkJRVU13UWl4TFFVRkxMRU5CUVVNc1JVRkJSU3hGUVVGRk8wbEJRMnhDTEZOQlFWTXNSVUZCUlRGQ0xFTkJRVU1zUTBGQlF6UkNMRXRCUVVzc1EwRkJReXhSUVVGUk8wZEJRelZDTzBOQlEwWXNRMEZCUXp0QlFVVkxMRTFCUVUxNVF5eGhRVUZoTEVkQlFVRXZReXhQUVVGQkxFTkJRVUVyUXl4aFFVRkJMRWRCUVVkeVJTeERRVUZETEVOQlFVTXdRaXhMUVVGTExFTkJRVU1zUlVGQlJTeEZRVUZGTzBWQlEzWkRMRTFCUVUwc1JVRkJSVHREUVVOVUxFTkJRVU03UVVGRlN5eE5RVUZOTkVNc1RVRkJUU3hIUVVGQmFFUXNUMEZCUVN4RFFVRkJaMFFzVFVGQlFTeEhRVUZIZEVVc1EwRkJReXhEUVVGRE1FSXNTMEZCU3l4RFFVRkRMRVZCUVVVc1JVRkJSVHRGUVVOb1F5eExRVUZMTEVWQlFVVXNVVUZCVVR0RlFVTm1MRTFCUVUwc1JVRkJSVEZDTEVOQlFVTXNRMEZCUXpKQ0xFZEJRVWNzUTBGQlF5eFJRVUZSTEVOQlFVTTdSVUZEZGtJc1QwRkJUeXhGUVVGRkxFOUJRVTg3UlVGRGFFSXNZMEZCWXl4RlFVRkZNMElzUTBGQlF5eERRVUZETWtJc1IwRkJSeXhEUVVGRExGRkJRVkVzUTBGQlF6dEZRVU12UWl4TlFVRk5MRVZCUVVVelFpeERRVUZETEVOQlFVTXlRaXhIUVVGSExFTkJRVU1zVVVGQlVUdERRVU4yUWl4RFFVRkRPMEZCUlVzc1RVRkJUVFJETEdWQlFXVXNSMEZCUVdwRUxFOUJRVUVzUTBGQlFXbEVMR1ZCUVVFc1IwRkJSM1pGTEVOQlFVTXNRMEZCUXpCQ0xFdEJRVXNzUTBGQlF5eEZRVUZGTEVWQlFVVTdSVUZEZWtNc1RVRkJUU3hGUVVGRk1VSXNRMEZCUXl4RFFVRkRNRUlzUzBGQlN5eERRVUZETEVWQlFVVXNSVUZCUlR0SlFVTnNRaXhWUVVGVkxFVkJRVVV4UWl4RFFVRkRMRU5CUVVNMFFpeExRVUZMTEVOQlFVTXNVMEZCVXp0SFFVTTVRanREUVVOR0xFTkJRVU03UVVGRlN5eE5RVUZOTkVNc1kwRkJZeXhIUVVGQmJFUXNUMEZCUVN4RFFVRkJhMFFzWTBGQlFTeEhRVUZIZUVVc1EwRkJReXhEUVVGRE1FSXNTMEZCU3l4RFFVRkRMRVZCUVVVc1JVRkJSVHRGUVVONFF5eE5RVUZOTEVWQlFVVTdRMEZEVkN4RFFVRkRPMEZCUlVzc1RVRkJUU3RETEU5QlFVOHNSMEZCUVc1RUxFOUJRVUVzUTBGQlFXMUVMRTlCUVVFc1IwRkJSM3BGTEVOQlFVTXNRMEZCUTNWQ0xFdEJRVXNzUTBGQlF5eGxRVUZsTEVWQlFVVXNaVUZCWlN4RlFVRkZMR2RDUVVGblFpeERRVUZETzBGQlJUTkZMRTFCUVUxdFJDeGhRVUZoTEVkQlFVRndSQ3hQUVVGQkxFTkJRVUZ2UkN4aFFVRkJMRWRCUVVjeFJTeERRVUZETEVOQlFVTXdRaXhMUVVGTExFTkJRVU1zUTBGQlF5eGxRVUZsTEVOQlFVTXNSVUZCUlR0RlFVTjBSQ3hQUVVGUExFVkJRVVVzVVVGQlVUdEZRVU5xUWl4aFFVRmhMRVZCUVVVeFFpeERRVUZETEVOQlFVTXlRaXhIUVVGSExFTkJRVU1zYlVKQlFXMUNPME5CUTNwRExFTkJRVU03UVVGRlN5eE5RVUZOWjBRc1lVRkJZU3hIUVVGQmNrUXNUMEZCUVN4RFFVRkJjVVFzWVVGQlFTeEhRVUZITTBVc1EwRkJReXhEUVVGRE1FSXNTMEZCU3l4RFFVRkRMRU5CUVVNc1pVRkJaU3hEUVVGRExFVkJRVVU3UlVGRGRFUXNUMEZCVHl4RlFVRkZMRkZCUVZFN1JVRkRha0lzWVVGQllTeEZRVUZGTVVJc1EwRkJReXhEUVVGRE1rSXNSMEZCUnl4RFFVRkRMRzFDUVVGdFFqdERRVU42UXl4RFFVRkRPMEZCUlVzc1RVRkJUV2xFTEdOQlFXTXNSMEZCUVhSRUxFOUJRVUVzUTBGQlFYTkVMR05CUVVFc1IwRkJSelZGTEVOQlFVTXNRMEZCUXpCQ0xFdEJRVXNzUTBGQlF5eERRVUZETEdWQlFXVXNRMEZCUXl4RlFVRkZPMFZCUTNaRUxFOUJRVThzUlVGQlJTeFRRVUZUTzBWQlEyeENMR0ZCUVdFc1JVRkJSVEZDTEVOQlFVTXNRMEZCUXpKQ0xFZEJRVWNzUTBGQlF5eHZRa0ZCYjBJN1EwRkRNVU1zUTBGQlF6dEJRVVZMTEUxQlFVMXJSQ3hoUVVGaExFZEJRVUYyUkN4UFFVRkJMRU5CUVVGMVJDeGhRVUZCTEVkQlFVYzNSU3hEUVVGRExFTkJRVU13UWl4TFFVRkxMRU5CUVVNc1JVRkJSU3hGUVVGRk8wVkJRM1pETEV0QlFVc3NSVUZCUlN4UlFVRlJPMFZCUTJZc1RVRkJUU3hGUVVGRk1VSXNRMEZCUXl4RFFVRkRNa0lzUjBGQlJ5eERRVUZETEZGQlFWRXNRMEZCUXp0RlFVTjJRaXhOUVVGTkxFVkJRVVV6UWl4RFFVRkRMRU5CUVVNeVFpeEhRVUZITEVOQlFVTXNVVUZCVVN4RFFVRkRPMFZCUTNaQ0xHTkJRV01zUlVGQlJUTkNMRU5CUVVNc1EwRkJRekpDTEVkQlFVY3NRMEZCUXl4UlFVRlJMRU5CUVVNN1JVRkRMMElzVFVGQlRTeEZRVUZGTTBJc1EwRkJReXhEUVVGRE1rSXNSMEZCUnl4RFFVRkRMRkZCUVZFN1EwRkRka0lzUTBGQlF6dEJRVVZMTEUxQlFVMXRSQ3hsUVVGbExFZEJRVUY0UkN4UFFVRkJMRU5CUVVGM1JDeGxRVUZCTEVkQlFVYzVSU3hEUVVGRExFTkJRVU13UWl4TFFVRkxMRU5CUVVNc1JVRkJSU3hGUVVGRk8wVkJRM3BETEUxQlFVMHNSVUZCUlRGQ0xFTkJRVU1zUTBGQlF6QkNMRXRCUVVzc1EwRkJReXhGUVVGRkxFVkJRVVU3U1VGRGJFSXNVVUZCVVN4RlFVRkZNVUlzUTBGQlF5eERRVUZETkVJc1MwRkJTeXhEUVVGRExGRkJRVkU3UjBGRE0wSTdRMEZEUml4RFFVRkRPMEZCUlVzc1RVRkJUVzFFTEdGQlFXRXNSMEZCUVhwRUxFOUJRVUVzUTBGQlFYbEVMR0ZCUVVFc1IwRkJSeTlGTEVOQlFVTXNRMEZCUXpCQ0xFdEJRVXNzUTBGQlF5eEZRVUZGTEVWQlFVVTdSVUZEZGtNc1RVRkJUU3hGUVVGRk8wTkJRMVFzUTBGQlF6dEJRVVZMTEUxQlFVMXpSQ3hOUVVGTkxFZEJRVUV4UkN4UFFVRkJMRU5CUVVFd1JDeE5RVUZCTEVkQlFVZG9SaXhEUVVGRExFTkJRVU4xUWl4TFFVRkxMRU5CUVVNc1kwRkJZeXhGUVVGRkxHTkJRV01zUlVGQlJTeGxRVUZsTEVOQlFVTTdRVUZGZGtVc1RVRkJUVEJFTEZsQlFWa3NSMEZCUVRORUxFOUJRVUVzUTBGQlFUSkVMRmxCUVVFc1IwRkJSMnBHTEVOQlFVTXNRMEZCUXpCQ0xFdEJRVXNzUTBGQlF5eERRVUZETEdOQlFXTXNRMEZCUXl4RlFVRkZPMFZCUTNCRUxFOUJRVThzUlVGQlJTeFJRVUZSTzBWQlEycENMR0ZCUVdFc1JVRkJSVEZDTEVOQlFVTXNRMEZCUXpKQ0xFZEJRVWNzUTBGQlF5eHRRa0ZCYlVJN1EwRkRla01zUTBGQlF6dEJRVVZMTEUxQlFVMTFSQ3haUVVGWkxFZEJRVUUxUkN4UFFVRkJMRU5CUVVFMFJDeFpRVUZCTEVkQlFVZHNSaXhEUVVGRExFTkJRVU13UWl4TFFVRkxMRU5CUVVNc1EwRkJReXhqUVVGakxFTkJRVU1zUlVGQlJUdEZRVU53UkN4UFFVRlBMRVZCUVVVc1VVRkJVVHRGUVVOcVFpeGhRVUZoTEVWQlFVVXhRaXhEUVVGRExFTkJRVU15UWl4SFFVRkhMRU5CUVVNc2JVSkJRVzFDTzBOQlEzcERMRU5CUVVNN1FVRkZTeXhOUVVGTmQwUXNZVUZCWVN4SFFVRkJOMFFzVDBGQlFTeERRVUZCTmtRc1lVRkJRU3hIUVVGSGJrWXNRMEZCUXl4RFFVRkRNRUlzUzBGQlN5eERRVUZETEVOQlFVTXNZMEZCWXl4RFFVRkRMRVZCUVVVN1JVRkRja1FzVDBGQlR5eEZRVUZGTEZOQlFWTTdSVUZEYkVJc1lVRkJZU3hGUVVGRk1VSXNRMEZCUXl4RFFVRkRNa0lzUjBGQlJ5eERRVUZETEc5Q1FVRnZRanREUVVNeFF5eERRVUZETzBGQlJVc3NUVUZCVFhsRUxGbEJRVmtzUjBGQlFUbEVMRTlCUVVFc1EwRkJRVGhFTEZsQlFVRXNSMEZCUjNCR0xFTkJRVU1zUTBGQlF6QkNMRXRCUVVzc1EwRkJReXhGUVVGRkxFVkJRVVU3UlVGRGRFTXNTMEZCU3l4RlFVRkZMRkZCUVZFN1JVRkRaaXhOUVVGTkxFVkJRVVV4UWl4RFFVRkRMRU5CUVVNeVFpeEhRVUZITEVOQlFVTXNVVUZCVVN4RFFVRkRPMFZCUTNaQ0xHTkJRV01zUlVGQlJUTkNMRU5CUVVNc1EwRkJRekpDTEVkQlFVY3NRMEZCUXl4UlFVRlJMRU5CUVVNN1JVRkRMMElzVFVGQlRTeEZRVUZGTTBJc1EwRkJReXhEUVVGRE1rSXNSMEZCUnl4RFFVRkRMRkZCUVZFN1EwRkRka0lzUTBGQlF6dEJRVVZMTEUxQlFVMHdSQ3hoUVVGaExFZEJRVUV2UkN4UFFVRkJMRU5CUVVFclJDeGhRVUZCTEVkQlFVZHlSaXhEUVVGRExFTkJRVU13UWl4TFFVRkxMRU5CUVVNc1JVRkJSU3hGUVVGRk8wVkJRM1pETEU5QlFVOHNSVUZCUlRGQ0xFTkJRVU1zUTBGQlF6QkNMRXRCUVVzc1EwRkJReXhGUVVGRkxFVkJRVVU3U1VGRGJrSXNTMEZCU3l4RlFVRkZMRkZCUVZFN1NVRkRaaXhoUVVGaExFVkJRVVV4UWl4RFFVRkRMRU5CUVVNeVFpeEhRVUZITEVOQlFVTXNVVUZCVVN4RFFVRkRPMGxCUXpsQ0xHdENRVUZyUWl4RlFVRkZNMElzUTBGQlF5eERRVUZETWtJc1IwRkJSeXhEUVVGRExGRkJRVkVzUTBGQlF6dEpRVU51UXl4UFFVRlBMRVZCUVVVelFpeERRVUZETEVOQlFVTXlRaXhIUVVGSExFTkJRVU1zVVVGQlVUdEhRVU40UWp0RFFVTkdMRU5CUVVNN1FVRkZSaXhOUVVGTk1rUXNhVUpCUVdsQ0xFZEJRV2xDTzBWQlEzUkRha1VzUzBGQlN6dEZRVU5NUnl4WFFVRlhPMFZCUTFoRExHbENRVUZwUWp0RlFVTnFRa2tzYVVKQlFXbENPMFZCUTJwQ1F5eHJRa0ZCYTBJN1JVRkRiRUpETEdsQ1FVRnBRanRGUVVOcVFrTXNUVUZCVFR0RlFVTk9SU3h4UWtGQmNVSTdSVUZEY2tKRExHTkJRV003UlVGRFpFTXNaVUZCWlR0RlFVTm1ReXhQUVVGUE8wVkJRMUJETEV0QlFVczdSVUZEVEVNc1kwRkJZenRGUVVOa1F5eDNRa0ZCZDBJN1JVRkRlRUpETEd0Q1FVRnJRanRGUVVOc1FrTXNVMEZCVXp0RlFVTlVReXhWUVVGVk8wVkJRMVpETEdGQlFXRTdSVUZEWWtNc2NVSkJRWEZDTzBWQlEzSkNReXh2UWtGQmIwSTdSVUZEY0VKRExHRkJRV0U3UlVGRFlrTXNZVUZCWVR0RlFVTmlReXhMUVVGTE8wVkJRMHhETEZsQlFWazdSVUZEV2tNc1pVRkJaVHRGUVVObVF5eFJRVUZSTzBWQlExSkRMRmRCUVZjN1JVRkRXRU1zYTBKQlFXdENPMFZCUTJ4Q1F5eG5Ra0ZCWjBJN1JVRkRhRUpETEdOQlFXTTdSVUZEWkVNc1QwRkJUenRGUVVOUVF5eGpRVUZqTzBWQlEyUkRMSGRDUVVGM1FqdEZRVU40UWtNc2FVSkJRV2xDTzBWQlEycENReXhuUWtGQlowSTdSVUZEYUVKRExITkNRVUZ6UWp0RlFVTjBRa1VzYzBKQlFYTkNPMFZCUTNSQ1F5eDFRa0ZCZFVJN1JVRkRka0pETEhOQ1FVRnpRanRGUVVOMFFrTXNkVUpCUVhWQ08wVkJRM1pDUXl4alFVRmpPMFZCUTJSRExHRkJRV0U3UlVGRFlrTXNUVUZCVFR0RlFVTk9ReXhsUVVGbE8wVkJRMlpETEdOQlFXTTdSVUZEWkVNc1QwRkJUenRGUVVOUVF5eGhRVUZoTzBWQlEySkRMR0ZCUVdFN1JVRkRZa01zWTBGQll6dEZRVU5rUXl4aFFVRmhPMFZCUTJKRExHVkJRV1U3UlVGRFprTXNZVUZCWVR0RlFVTmlReXhOUVVGTk8wVkJRMDVETEZsQlFWazdSVUZEV2tNc1dVRkJXVHRGUVVOYVF5eGhRVUZoTzBWQlEySkRMRmxCUVZrN1JVRkRXa003UTBGRFJEdEJRVUZETEVsQlFVRkZMRkZCUVVFc1IwRkJRV3BGTEU5QlFVRXNRMEZCUVZZc1QwRkJRU3hIUVVOaE1FVXNhVUpCUVdsQ0lpd2lhV2R1YjNKbFRHbHpkQ0k2VzExOSIsIlwidXNlIHN0cmljdFwiO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy50eXBlU3VpdGUgPSBleHBvcnRzLmRlZmF1bHQgPSBleHBvcnRzLmNoZWNrZXJzID0gdm9pZCAwO1xudmFyIF90c0ludGVyZmFjZUNoZWNrZXIgPSByZXF1aXJlKFwidHMtaW50ZXJmYWNlLWNoZWNrZXJcIik7XG52YXIgX2FwaVR5cGVzVGkgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL2FwaS10eXBlcy10aS5qc1wiKSk7XG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KGUpIHsgcmV0dXJuIGUgJiYgZS5fX2VzTW9kdWxlID8gZSA6IHsgZGVmYXVsdDogZSB9OyB9XG4vLyBUaGlzIG1vZHVsZSB3YXMgYXV0b21hdGljYWxseSBnZW5lcmF0ZWQgYnkgbm9kZSB0cy1pbnRlcmZhY2UtcG9zdC50c1xuLy8gMjAyNi0wNS0zMVQxNToyNzo0Mi40MTNaXG5cbi8vIFR5cGUgZGVmaW5pdGlvbnNcbmNvbnN0IHR5cGVTdWl0ZSA9IGV4cG9ydHMudHlwZVN1aXRlID0gX2FwaVR5cGVzVGkuZGVmYXVsdDtcbi8vIENoZWNrZXJzXG5jb25zdCBjaGVja2VycyA9IGV4cG9ydHMuY2hlY2tlcnMgPSAoMCwgX3RzSW50ZXJmYWNlQ2hlY2tlci5jcmVhdGVDaGVja2VycykoX2FwaVR5cGVzVGkuZGVmYXVsdCk7XG4vLyBFeHBvcnQgdGhlIGNoZWNrZXJzIGJ5IGRlZmF1bHRcbnZhciBfZGVmYXVsdCA9IGV4cG9ydHMuZGVmYXVsdCA9IGNoZWNrZXJzO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ9dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p1WVcxbGN5STZXeUpmZEhOSmJuUmxjbVpoWTJWRGFHVmphMlZ5SWl3aWNtVnhkV2x5WlNJc0lsOWhjR2xVZVhCbGMxUnBJaXdpWDJsdWRHVnliM0JTWlhGMWFYSmxSR1ZtWVhWc2RDSXNJbVVpTENKZlgyVnpUVzlrZFd4bElpd2laR1ZtWVhWc2RDSXNJblI1Y0dWVGRXbDBaU0lzSW1WNGNHOXlkSE1pTENKbGVIQnZjblJsWkZSNWNHVlRkV2wwWlNJc0ltTm9aV05yWlhKeklpd2lZM0psWVhSbFEyaGxZMnRsY25NaUxDSmZaR1ZtWVhWc2RDSmRMQ0p6YjNWeVkyVnpJanBiSWk0dUx5NHVMM055WXk5MGFTOWhjR2t0ZEhsd1pYTXVkSE1pWFN3aWMyOTFjbU5sYzBOdmJuUmxiblFpT2x0dWRXeHNYU3dpYldGd2NHbHVaM01pT2lJN096czdPenRCUVVkQkxFbEJRVUZCTEcxQ1FVRkJMRWRCUVVGRExFOUJRVUU3UVVGRlFTeEpRVUZCUXl4WFFVRkJMRWRCUVVGRExITkNRVUZCTEVOQlFVRkdMRTlCUVVFN1FVRkJhMFFzVTBGQlFVVXNkVUpCUVVGRExFTkJRVUVzVjBGQlFVRXNRMEZCUVN4SlFVRkJRU3hEUVVGQkxFTkJRVUZETEZWQlFVRXNSMEZCUVVRc1EwRkJRU3hMUVVGQlJTeFBRVUZCTEVWQlFVRkdMRU5CUVVFN1FVRk1iRVE3UVVGRFFUczdRVUZ2UlVFN1FVRkRUeXhOUVVGTlJ5eFRRVUZUTEVkQlFVRkRMRTlCUVVFc1EwRkJRVVFzVTBGQlFTeEhRVUZIUlN4dFFrRXlSSGhDTzBGQlJVUTdRVUZEVHl4TlFVRk5ReXhSUVVGUkxFZEJRVUZHTEU5QlFVRXNRMEZCUVVVc1VVRkJRU3hIUVVGSExFbEJRVUZETEd0RFFVRmpMRVZCUVVOR0xHMUNRVUZwUWl4RFFUSkVka1E3UVVGRlJEdEJRVUZCTEVsQlFVRkhMRkZCUVVFc1IwRkJRVW9zVDBGQlFTeERRVUZCUml4UFFVRkJMRWRCUTJWSkxGRkJRVkVpTENKcFoyNXZjbVZNYVhOMElqcGJYWDA9IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSBleHBvcnRzLkV4cGVyaW1lbnRhbEZlYXR1cmVzID0gZXhwb3J0cy5EZWJ1Z0ZlYXR1cmVzID0gZXhwb3J0cy5Db25maWdQbHVnaW4gPSBleHBvcnRzLkNvbmZpZ0FwcGxpYW5jZXMgPSBleHBvcnRzLkFwcGxpYW5jZVByb2dyYW1PcHRpb25zID0gZXhwb3J0cy5BcHBsaWFuY2VQcm9ncmFtQ29uZmlnID0gZXhwb3J0cy5BcHBsaWFuY2VOYW1lc1ByZWZpeCA9IGV4cG9ydHMuQXBwbGlhbmNlRmVhdHVyZXMgPSBleHBvcnRzLkFwcGxpYW5jZUNvbmZpZyA9IGV4cG9ydHMuQWRkUHJvZ3JhbXNDb25maWcgPSB2b2lkIDA7XG52YXIgdCA9IF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkKHJlcXVpcmUoXCJ0cy1pbnRlcmZhY2UtY2hlY2tlclwiKSk7XG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZChlLCB0KSB7IGlmIChcImZ1bmN0aW9uXCIgPT0gdHlwZW9mIFdlYWtNYXApIHZhciByID0gbmV3IFdlYWtNYXAoKSwgbiA9IG5ldyBXZWFrTWFwKCk7IHJldHVybiAoX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQgPSBmdW5jdGlvbiAoZSwgdCkgeyBpZiAoIXQgJiYgZSAmJiBlLl9fZXNNb2R1bGUpIHJldHVybiBlOyB2YXIgbywgaSwgZiA9IHsgX19wcm90b19fOiBudWxsLCBkZWZhdWx0OiBlIH07IGlmIChudWxsID09PSBlIHx8IFwib2JqZWN0XCIgIT0gdHlwZW9mIGUgJiYgXCJmdW5jdGlvblwiICE9IHR5cGVvZiBlKSByZXR1cm4gZjsgaWYgKG8gPSB0ID8gbiA6IHIpIHsgaWYgKG8uaGFzKGUpKSByZXR1cm4gby5nZXQoZSk7IG8uc2V0KGUsIGYpOyB9IGZvciAoY29uc3QgdCBpbiBlKSBcImRlZmF1bHRcIiAhPT0gdCAmJiB7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGUsIHQpICYmICgoaSA9IChvID0gT2JqZWN0LmRlZmluZVByb3BlcnR5KSAmJiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGUsIHQpKSAmJiAoaS5nZXQgfHwgaS5zZXQpID8gbyhmLCB0LCBpKSA6IGZbdF0gPSBlW3RdKTsgcmV0dXJuIGY7IH0pKGUsIHQpOyB9XG4vKipcbiAqIFRoaXMgbW9kdWxlIHdhcyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBieSBgdHMtaW50ZXJmYWNlLWJ1aWxkZXJgXG4gKi9cblxuLy8gdHNsaW50OmRpc2FibGU6b2JqZWN0LWxpdGVyYWwta2V5LXF1b3Rlc1xuY29uc3QgQ29uZmlnUGx1Z2luID0gZXhwb3J0cy5Db25maWdQbHVnaW4gPSB0LmlmYWNlKFtdLCB7XG4gIFwicGxhdGZvcm1cIjogXCJzdHJpbmdcIixcbiAgXCJuYW1lXCI6IHQub3B0KFwic3RyaW5nXCIpLFxuICBcImNsaWVudGlkXCI6IFwic3RyaW5nXCIsXG4gIFwiY2xpZW50c2VjcmV0XCI6IHQub3B0KFwic3RyaW5nXCIpLFxuICBcInNpbXVsYXRvclwiOiB0Lm9wdChcImJvb2xlYW5cIiksXG4gIFwiY2hpbmFcIjogdC5vcHQoXCJib29sZWFuXCIpLFxuICBcImxhbmd1YWdlXCI6IHQuaWZhY2UoW10sIHtcbiAgICBcImFwaVwiOiBcInN0cmluZ1wiXG4gIH0pLFxuICBcImV4cGVyaW1lbnRhbFwiOiB0Lm9wdCh0LmFycmF5KFwiRXhwZXJpbWVudGFsRmVhdHVyZXNcIikpLFxuICBcImRlYnVnXCI6IHQub3B0KHQuYXJyYXkoXCJEZWJ1Z0ZlYXR1cmVzXCIpKVxufSk7XG5jb25zdCBFeHBlcmltZW50YWxGZWF0dXJlcyA9IGV4cG9ydHMuRXhwZXJpbWVudGFsRmVhdHVyZXMgPSB0LmxpdCgnRGlzY29ubmVjdGVkIGFzIE9mZicpO1xuY29uc3QgRGVidWdGZWF0dXJlcyA9IGV4cG9ydHMuRGVidWdGZWF0dXJlcyA9IHQudW5pb24odC5saXQoJ0xvZyBBUEkgSGVhZGVycycpLCB0LmxpdCgnTG9nIEFQSSBCb2RpZXMnKSwgdC5saXQoJ0xvZyBBcHBsaWFuY2UgSURzJyksIHQubGl0KCdMb2cgRGVidWcgYXMgSW5mbycpLCB0LmxpdCgnTW9jayBBcHBsaWFuY2VzJykpO1xuY29uc3QgQ29uZmlnQXBwbGlhbmNlcyA9IGV4cG9ydHMuQ29uZmlnQXBwbGlhbmNlcyA9IHQuaWZhY2UoW10sIHtcbiAgW3QuaW5kZXhLZXldOiBcIkFwcGxpYW5jZUNvbmZpZ1wiXG59KTtcbmNvbnN0IEFkZFByb2dyYW1zQ29uZmlnID0gZXhwb3J0cy5BZGRQcm9ncmFtc0NvbmZpZyA9IHQudW5pb24odC5saXQoJ25vbmUnKSwgdC5saXQoJ2F1dG8nKSwgdC5saXQoJ2N1c3RvbScpKTtcbmNvbnN0IEFwcGxpYW5jZUNvbmZpZyA9IGV4cG9ydHMuQXBwbGlhbmNlQ29uZmlnID0gdC5pZmFjZShbXSwge1xuICBcImVuYWJsZWRcIjogdC5vcHQoXCJib29sZWFuXCIpLFxuICBcIm5hbWVzXCI6IHQub3B0KHQuaWZhY2UoW10sIHtcbiAgICBcInByZWZpeFwiOiBcIkFwcGxpYW5jZU5hbWVzUHJlZml4XCJcbiAgfSkpLFxuICBcImZlYXR1cmVzXCI6IHQub3B0KFwiQXBwbGlhbmNlRmVhdHVyZXNcIiksXG4gIFwiYWRkcHJvZ3JhbXNcIjogdC5vcHQoXCJBZGRQcm9ncmFtc0NvbmZpZ1wiKSxcbiAgXCJwcm9ncmFtc1wiOiB0Lm9wdCh0LmFycmF5KFwiQXBwbGlhbmNlUHJvZ3JhbUNvbmZpZ1wiKSlcbn0pO1xuY29uc3QgQXBwbGlhbmNlTmFtZXNQcmVmaXggPSBleHBvcnRzLkFwcGxpYW5jZU5hbWVzUHJlZml4ID0gdC5pZmFjZShbXSwge1xuICBcInByb2dyYW1zXCI6IHQub3B0KFwiYm9vbGVhblwiKSxcbiAgXCJvdGhlclwiOiB0Lm9wdChcImJvb2xlYW5cIilcbn0pO1xuY29uc3QgQXBwbGlhbmNlRmVhdHVyZXMgPSBleHBvcnRzLkFwcGxpYW5jZUZlYXR1cmVzID0gdC5pZmFjZShbXSwge1xuICBbdC5pbmRleEtleV06IFwiYm9vbGVhblwiXG59KTtcbmNvbnN0IEFwcGxpYW5jZVByb2dyYW1Db25maWcgPSBleHBvcnRzLkFwcGxpYW5jZVByb2dyYW1Db25maWcgPSB0LmlmYWNlKFtdLCB7XG4gIFwibmFtZVwiOiBcInN0cmluZ1wiLFxuICBcImtleVwiOiBcInN0cmluZ1wiLFxuICBcInNlbGVjdG9ubHlcIjogdC5vcHQoXCJib29sZWFuXCIpLFxuICBcIm9wdGlvbnNcIjogdC5vcHQoXCJBcHBsaWFuY2VQcm9ncmFtT3B0aW9uc1wiKVxufSk7XG5jb25zdCBBcHBsaWFuY2VQcm9ncmFtT3B0aW9ucyA9IGV4cG9ydHMuQXBwbGlhbmNlUHJvZ3JhbU9wdGlvbnMgPSB0LmlmYWNlKFtdLCB7XG4gIFt0LmluZGV4S2V5XTogdC51bmlvbihcInN0cmluZ1wiLCBcIm51bWJlclwiLCBcImJvb2xlYW5cIilcbn0pO1xuY29uc3QgZXhwb3J0ZWRUeXBlU3VpdGUgPSB7XG4gIENvbmZpZ1BsdWdpbixcbiAgRXhwZXJpbWVudGFsRmVhdHVyZXMsXG4gIERlYnVnRmVhdHVyZXMsXG4gIENvbmZpZ0FwcGxpYW5jZXMsXG4gIEFkZFByb2dyYW1zQ29uZmlnLFxuICBBcHBsaWFuY2VDb25maWcsXG4gIEFwcGxpYW5jZU5hbWVzUHJlZml4LFxuICBBcHBsaWFuY2VGZWF0dXJlcyxcbiAgQXBwbGlhbmNlUHJvZ3JhbUNvbmZpZyxcbiAgQXBwbGlhbmNlUHJvZ3JhbU9wdGlvbnNcbn07XG52YXIgX2RlZmF1bHQgPSBleHBvcnRzLmRlZmF1bHQgPSBleHBvcnRlZFR5cGVTdWl0ZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRhdGE6YXBwbGljYXRpb24vanNvbjtjaGFyc2V0PXV0Zi04O2Jhc2U2NCxleUoyWlhKemFXOXVJam96TENKdVlXMWxjeUk2V3lKMElpd2lYMmx1ZEdWeWIzQlNaWEYxYVhKbFYybHNaR05oY21RaUxDSnlaWEYxYVhKbElpd2laU0lzSWxkbFlXdE5ZWEFpTENKeUlpd2liaUlzSWw5ZlpYTk5iMlIxYkdVaUxDSnZJaXdpYVNJc0ltWWlMQ0pmWDNCeWIzUnZYMThpTENKa1pXWmhkV3gwSWl3aWFHRnpJaXdpWjJWMElpd2ljMlYwSWl3aWFHRnpUM2R1VUhKdmNHVnlkSGtpTENKallXeHNJaXdpVDJKcVpXTjBJaXdpWkdWbWFXNWxVSEp2Y0dWeWRIa2lMQ0puWlhSUGQyNVFjbTl3WlhKMGVVUmxjMk55YVhCMGIzSWlMQ0pEYjI1bWFXZFFiSFZuYVc0aUxDSmxlSEJ2Y25Seklpd2lhV1poWTJVaUxDSnZjSFFpTENKaGNuSmhlU0lzSWtWNGNHVnlhVzFsYm5SaGJFWmxZWFIxY21Weklpd2liR2wwSWl3aVJHVmlkV2RHWldGMGRYSmxjeUlzSW5WdWFXOXVJaXdpUTI5dVptbG5RWEJ3YkdsaGJtTmxjeUlzSW1sdVpHVjRTMlY1SWl3aVFXUmtVSEp2WjNKaGJYTkRiMjVtYVdjaUxDSkJjSEJzYVdGdVkyVkRiMjVtYVdjaUxDSkJjSEJzYVdGdVkyVk9ZVzFsYzFCeVpXWnBlQ0lzSWtGd2NHeHBZVzVqWlVabFlYUjFjbVZ6SWl3aVFYQndiR2xoYm1ObFVISnZaM0poYlVOdmJtWnBaeUlzSWtGd2NHeHBZVzVqWlZCeWIyZHlZVzFQY0hScGIyNXpJaXdpWlhod2IzSjBaV1JVZVhCbFUzVnBkR1VpTENKZlpHVm1ZWFZzZENKZExDSnpiM1Z5WTJWeklqcGJJaTR1THk0dUwzTnlZeTkwYVM5amIyNW1hV2N0ZEhsd1pYTXRkR2t1ZEhNaVhTd2ljMjkxY21ObGMwTnZiblJsYm5RaU9sdHVkV3hzWFN3aWJXRndjR2x1WjNNaU9pSTdPenM3T3p0QlFVZEJMRWxCUVVGQkxFTkJRVUVzUjBGQlFVTXNkVUpCUVVFc1EwRkJRVU1zVDBGQlFUdEJRVUV3UXl4VFFVRkJSQ3gzUWtGQlFVVXNRMEZCUVN4RlFVRkJTQ3hEUVVGQkxEWkNRVUZCU1N4UFFVRkJMRTFCUVVGRExFTkJRVUVzVDBGQlFVUXNUMEZCUVN4SlFVRkJSU3hEUVVGQkxFOUJRVUZHTEU5QlFVRXNXVUZCUVVnc2RVSkJRVUVzV1VGQlFVRXNRMEZCUVVVc1EwRkJRU3hGUVVGQlNDeERRVUZCTEZOQlFVRkJMRU5CUVVFc1NVRkJRVWNzUTBGQlFTeEpRVUZCUVN4RFFVRkJMRU5CUVVGSkxGVkJRVUVzVTBGQlFVb3NRMEZCUVN4TlFVRkJTeXhEUVVGQkxFVkJRVUZETEVOQlFVRXNSVUZCUVVNc1EwRkJRU3hMUVVGQlF5eFRRVUZCTEZGQlFVRkRMRTlCUVVFc1JVRkJRVlFzUTBGQlFTeHBRa0ZCUVVFc1EwRkJRU3gxUWtGQlFVRXNRMEZCUVN4NVFrRkJRVUVzUTBGQlFTeFRRVUZCVHl4RFFVRkJMRTFCUVVGR0xFTkJRVUVzUjBGQlFWSXNRMEZCUVN4SFFVRkJUU3hEUVVGQkxFZEJRVUZFTEVOQlFVRXNVVUZCUVVjc1EwRkJRU3hEUVVGQlN5eEhRVUZCTEVOQlFVRldMRU5CUVVFc1ZVRkJRVXNzUTBGQlFTeERRVUZCVFN4SFFVRkJMRU5CUVVGWUxFTkJRVUVzUjBGQlFVc3NRMEZCUVN4RFFVRkJUeXhIUVVGQkxFTkJRVUZhTEVOQlFVRXNSVUZCUVU4c1EwRkJRU3huUWtGQlFWWXNRMEZCUVN4SlFVRkJSeXhEUVVGQkxHZENRVUZCU0N4RFFVRkJMRTlCUVVGblFpeGpRVUZCTEVOQlFVRkRMRWxCUVVFc1EwRkJRV1FzUTBGQlFTeEZRVUZCU0N4RFFVRkJMRTlCUVVGVExFTkJRVUVzU1VGQlFVUXNRMEZCUVN4SFFVRkJWU3hOUVVGQkxFTkJRVUZETEdOQlFVRXNTMEZCUVVRc1RVRkJRU3hEUVVGQlJTeDNRa0ZCUVN4RFFVRkJha0lzUTBGQlFTeEZRVUZCU0N4RFFVRkJMRTlCUVVGVExFTkJRVUVzUTBGQlFVc3NSMEZCUVN4SlFVRkJUQ3hEUVVGQkxFTkJRVUZOTEVkQlFVRXNTVUZCUVZBc1EwRkJRU3hEUVVGQlJTeERRVUZCTEVWQlFVRldMRU5CUVVFc1JVRkJRVk1zUTBGQlFTeEpRVUZCUXl4RFFVRkJMRU5CUVVGV0xFTkJRVUVzU1VGQlFVY3NRMEZCUVN4RFFVRkJTQ3hEUVVGQkxGZEJRVUZWTEVOQlFVRXNTMEZCUVZBc1EwRkJRU3hGUVVGQlNDeERRVUZCTzBGQlNERkRPenM3TzBGQlNVRTdRVUZGVHl4TlFVRk5jVUlzV1VGQldTeEhRVUZCUXl4UFFVRkJMRU5CUVVGRUxGbEJRVUVzUjBGQlIzSkNMRU5CUVVNc1EwRkJRM1ZDTEV0QlFVc3NRMEZCUXl4RlFVRkZMRVZCUVVVN1JVRkRkRU1zVlVGQlZTeEZRVUZGTEZGQlFWRTdSVUZEY0VJc1RVRkJUU3hGUVVGRmRrSXNRMEZCUXl4RFFVRkRkMElzUjBGQlJ5eERRVUZETEZGQlFWRXNRMEZCUXp0RlFVTjJRaXhWUVVGVkxFVkJRVVVzVVVGQlVUdEZRVU53UWl4alFVRmpMRVZCUVVWNFFpeERRVUZETEVOQlFVTjNRaXhIUVVGSExFTkJRVU1zVVVGQlVTeERRVUZETzBWQlF5OUNMRmRCUVZjc1JVRkJSWGhDTEVOQlFVTXNRMEZCUTNkQ0xFZEJRVWNzUTBGQlF5eFRRVUZUTEVOQlFVTTdSVUZETjBJc1QwRkJUeXhGUVVGRmVFSXNRMEZCUXl4RFFVRkRkMElzUjBGQlJ5eERRVUZETEZOQlFWTXNRMEZCUXp0RlFVTjZRaXhWUVVGVkxFVkJRVVY0UWl4RFFVRkRMRU5CUVVOMVFpeExRVUZMTEVOQlFVTXNSVUZCUlN4RlFVRkZPMGxCUTNSQ0xFdEJRVXNzUlVGQlJUdEhRVU5TTEVOQlFVTTdSVUZEUml4alFVRmpMRVZCUVVWMlFpeERRVUZETEVOQlFVTjNRaXhIUVVGSExFTkJRVU40UWl4RFFVRkRMRU5CUVVONVFpeExRVUZMTEVOQlFVTXNjMEpCUVhOQ0xFTkJRVU1zUTBGQlF6dEZRVU4wUkN4UFFVRlBMRVZCUVVWNlFpeERRVUZETEVOQlFVTjNRaXhIUVVGSExFTkJRVU40UWl4RFFVRkRMRU5CUVVONVFpeExRVUZMTEVOQlFVTXNaVUZCWlN4RFFVRkRPME5CUTNoRExFTkJRVU03UVVGRlN5eE5RVUZOUXl4dlFrRkJiMElzUjBGQlFVb3NUMEZCUVN4RFFVRkJTU3h2UWtGQlFTeEhRVUZITVVJc1EwRkJReXhEUVVGRE1rSXNSMEZCUnl4RFFVRkRMSEZDUVVGeFFpeERRVUZETzBGQlJYcEVMRTFCUVUxRExHRkJRV0VzUjBGQlFVNHNUMEZCUVN4RFFVRkJUU3hoUVVGQkxFZEJRVWMxUWl4RFFVRkRMRU5CUVVNMlFpeExRVUZMTEVOQlFVTTNRaXhEUVVGRExFTkJRVU15UWl4SFFVRkhMRU5CUVVNc2FVSkJRV2xDTEVOQlFVTXNSVUZCUlROQ0xFTkJRVU1zUTBGQlF6SkNMRWRCUVVjc1EwRkJReXhuUWtGQlowSXNRMEZCUXl4RlFVRkZNMElzUTBGQlF5eERRVUZETWtJc1IwRkJSeXhEUVVGRExHMUNRVUZ0UWl4RFFVRkRMRVZCUVVVelFpeERRVUZETEVOQlFVTXlRaXhIUVVGSExFTkJRVU1zYlVKQlFXMUNMRU5CUVVNc1JVRkJSVE5DTEVOQlFVTXNRMEZCUXpKQ0xFZEJRVWNzUTBGQlF5eHBRa0ZCYVVJc1EwRkJReXhEUVVGRE8wRkJSV3hMTEUxQlFVMUhMR2RDUVVGblFpeEhRVUZCVWl4UFFVRkJMRU5CUVVGUkxHZENRVUZCTEVkQlFVYzVRaXhEUVVGRExFTkJRVU4xUWl4TFFVRkxMRU5CUVVNc1JVRkJSU3hGUVVGRk8wVkJRekZETEVOQlFVTjJRaXhEUVVGRExFTkJRVU1yUWl4UlFVRlJMRWRCUVVjN1EwRkRaaXhEUVVGRE8wRkJSVXNzVFVGQlRVTXNhVUpCUVdsQ0xFZEJRVUZXTEU5QlFVRXNRMEZCUVZVc2FVSkJRVUVzUjBGQlIyaERMRU5CUVVNc1EwRkJRelpDTEV0QlFVc3NRMEZCUXpkQ0xFTkJRVU1zUTBGQlF6SkNMRWRCUVVjc1EwRkJReXhOUVVGTkxFTkJRVU1zUlVGQlJUTkNMRU5CUVVNc1EwRkJRekpDTEVkQlFVY3NRMEZCUXl4TlFVRk5MRU5CUVVNc1JVRkJSVE5DTEVOQlFVTXNRMEZCUXpKQ0xFZEJRVWNzUTBGQlF5eFJRVUZSTEVOQlFVTXNRMEZCUXp0QlFVVm9SaXhOUVVGTlRTeGxRVUZsTEVkQlFVRllMRTlCUVVFc1EwRkJRVmNzWlVGQlFTeEhRVUZIYWtNc1EwRkJReXhEUVVGRGRVSXNTMEZCU3l4RFFVRkRMRVZCUVVVc1JVRkJSVHRGUVVONlF5eFRRVUZUTEVWQlFVVjJRaXhEUVVGRExFTkJRVU4zUWl4SFFVRkhMRU5CUVVNc1UwRkJVeXhEUVVGRE8wVkJRek5DTEU5QlFVOHNSVUZCUlhoQ0xFTkJRVU1zUTBGQlEzZENMRWRCUVVjc1EwRkJRM2hDTEVOQlFVTXNRMEZCUTNWQ0xFdEJRVXNzUTBGQlF5eEZRVUZGTEVWQlFVVTdTVUZEZWtJc1VVRkJVU3hGUVVGRk8wZEJRMWdzUTBGQlF5eERRVUZETzBWQlEwZ3NWVUZCVlN4RlFVRkZka0lzUTBGQlF5eERRVUZEZDBJc1IwRkJSeXhEUVVGRExHMUNRVUZ0UWl4RFFVRkRPMFZCUTNSRExHRkJRV0VzUlVGQlJYaENMRU5CUVVNc1EwRkJRM2RDTEVkQlFVY3NRMEZCUXl4dFFrRkJiVUlzUTBGQlF6dEZRVU42UXl4VlFVRlZMRVZCUVVWNFFpeERRVUZETEVOQlFVTjNRaXhIUVVGSExFTkJRVU40UWl4RFFVRkRMRU5CUVVONVFpeExRVUZMTEVOQlFVTXNkMEpCUVhkQ0xFTkJRVU03UTBGRGNFUXNRMEZCUXp0QlFVVkxMRTFCUVUxVExHOUNRVUZ2UWl4SFFVRkJXaXhQUVVGQkxFTkJRVUZaTEc5Q1FVRkJMRWRCUVVkc1F5eERRVUZETEVOQlFVTjFRaXhMUVVGTExFTkJRVU1zUlVGQlJTeEZRVUZGTzBWQlF6bERMRlZCUVZVc1JVRkJSWFpDTEVOQlFVTXNRMEZCUTNkQ0xFZEJRVWNzUTBGQlF5eFRRVUZUTEVOQlFVTTdSVUZETlVJc1QwRkJUeXhGUVVGRmVFSXNRMEZCUXl4RFFVRkRkMElzUjBGQlJ5eERRVUZETEZOQlFWTTdRMEZEZWtJc1EwRkJRenRCUVVWTExFMUJRVTFYTEdsQ1FVRnBRaXhIUVVGQllpeFBRVUZCTEVOQlFVRmhMR2xDUVVGQkxFZEJRVWR1UXl4RFFVRkRMRU5CUVVOMVFpeExRVUZMTEVOQlFVTXNSVUZCUlN4RlFVRkZPMFZCUXpORExFTkJRVU4yUWl4RFFVRkRMRU5CUVVNclFpeFJRVUZSTEVkQlFVYzdRMEZEWml4RFFVRkRPMEZCUlVzc1RVRkJUVXNzYzBKQlFYTkNMRWRCUVVGa0xFOUJRVUVzUTBGQlFXTXNjMEpCUVVFc1IwRkJSM0JETEVOQlFVTXNRMEZCUTNWQ0xFdEJRVXNzUTBGQlF5eEZRVUZGTEVWQlFVVTdSVUZEYUVRc1RVRkJUU3hGUVVGRkxGRkJRVkU3UlVGRGFFSXNTMEZCU3l4RlFVRkZMRkZCUVZFN1JVRkRaaXhaUVVGWkxFVkJRVVYyUWl4RFFVRkRMRU5CUVVOM1FpeEhRVUZITEVOQlFVTXNVMEZCVXl4RFFVRkRPMFZCUXpsQ0xGTkJRVk1zUlVGQlJYaENMRU5CUVVNc1EwRkJRM2RDTEVkQlFVY3NRMEZCUXl4NVFrRkJlVUk3UTBGRE0wTXNRMEZCUXp0QlFVVkxMRTFCUVUxaExIVkNRVUYxUWl4SFFVRkJaaXhQUVVGQkxFTkJRVUZsTEhWQ1FVRkJMRWRCUVVkeVF5eERRVUZETEVOQlFVTjFRaXhMUVVGTExFTkJRVU1zUlVGQlJTeEZRVUZGTzBWQlEycEVMRU5CUVVOMlFpeERRVUZETEVOQlFVTXJRaXhSUVVGUkxFZEJRVWN2UWl4RFFVRkRMRU5CUVVNMlFpeExRVUZMTEVOQlFVTXNVVUZCVVN4RlFVRkZMRkZCUVZFc1JVRkJSU3hUUVVGVE8wTkJRM0JFTEVOQlFVTTdRVUZGUml4TlFVRk5VeXhwUWtGQmFVSXNSMEZCYVVJN1JVRkRkRU5xUWl4WlFVRlpPMFZCUTFwTExHOUNRVUZ2UWp0RlFVTndRa1VzWVVGQllUdEZRVU5pUlN4blFrRkJaMEk3UlVGRGFFSkZMR2xDUVVGcFFqdEZRVU5xUWtNc1pVRkJaVHRGUVVObVF5eHZRa0ZCYjBJN1JVRkRjRUpETEdsQ1FVRnBRanRGUVVOcVFrTXNjMEpCUVhOQ08wVkJRM1JDUXp0RFFVTkVPMEZCUVVNc1NVRkJRVVVzVVVGQlFTeEhRVUZCYWtJc1QwRkJRU3hEUVVGQlZpeFBRVUZCTEVkQlEyRXdRaXhwUWtGQmFVSWlMQ0pwWjI1dmNtVk1hWE4wSWpwYlhYMD0iLCJcInVzZSBzdHJpY3RcIjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMudHlwZVN1aXRlID0gZXhwb3J0cy5kZWZhdWx0ID0gZXhwb3J0cy5jaGVja2VycyA9IHZvaWQgMDtcbnZhciBfdHNJbnRlcmZhY2VDaGVja2VyID0gcmVxdWlyZShcInRzLWludGVyZmFjZS1jaGVja2VyXCIpO1xudmFyIF9jb25maWdUeXBlc1RpID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiLi9jb25maWctdHlwZXMtdGkuanNcIikpO1xuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChlKSB7IHJldHVybiBlICYmIGUuX19lc01vZHVsZSA/IGUgOiB7IGRlZmF1bHQ6IGUgfTsgfVxuLy8gVGhpcyBtb2R1bGUgd2FzIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IG5vZGUgdHMtaW50ZXJmYWNlLXBvc3QudHNcbi8vIDIwMjYtMDUtMzFUMTU6Mjc6NDIuNDE0WlxuXG4vLyBUeXBlIGRlZmluaXRpb25zXG5jb25zdCB0eXBlU3VpdGUgPSBleHBvcnRzLnR5cGVTdWl0ZSA9IF9jb25maWdUeXBlc1RpLmRlZmF1bHQ7XG4vLyBDaGVja2Vyc1xuY29uc3QgY2hlY2tlcnMgPSBleHBvcnRzLmNoZWNrZXJzID0gKDAsIF90c0ludGVyZmFjZUNoZWNrZXIuY3JlYXRlQ2hlY2tlcnMpKF9jb25maWdUeXBlc1RpLmRlZmF1bHQpO1xuLy8gRXhwb3J0IHRoZSBjaGVja2VycyBieSBkZWZhdWx0XG52YXIgX2RlZmF1bHQgPSBleHBvcnRzLmRlZmF1bHQgPSBjaGVja2Vycztcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRhdGE6YXBwbGljYXRpb24vanNvbjtjaGFyc2V0PXV0Zi04O2Jhc2U2NCxleUoyWlhKemFXOXVJam96TENKdVlXMWxjeUk2V3lKZmRITkpiblJsY21aaFkyVkRhR1ZqYTJWeUlpd2ljbVZ4ZFdseVpTSXNJbDlqYjI1bWFXZFVlWEJsYzFScElpd2lYMmx1ZEdWeWIzQlNaWEYxYVhKbFJHVm1ZWFZzZENJc0ltVWlMQ0pmWDJWelRXOWtkV3hsSWl3aVpHVm1ZWFZzZENJc0luUjVjR1ZUZFdsMFpTSXNJbVY0Y0c5eWRITWlMQ0psZUhCdmNuUmxaRlI1Y0dWVGRXbDBaU0lzSW1Ob1pXTnJaWEp6SWl3aVkzSmxZWFJsUTJobFkydGxjbk1pTENKZlpHVm1ZWFZzZENKZExDSnpiM1Z5WTJWeklqcGJJaTR1THk0dUwzTnlZeTkwYVM5amIyNW1hV2N0ZEhsd1pYTXVkSE1pWFN3aWMyOTFjbU5sYzBOdmJuUmxiblFpT2x0dWRXeHNYU3dpYldGd2NHbHVaM01pT2lJN096czdPenRCUVVkQkxFbEJRVUZCTEcxQ1FVRkJMRWRCUVVGRExFOUJRVUU3UVVGRlFTeEpRVUZCUXl4alFVRkJMRWRCUVVGRExITkNRVUZCTEVOQlFVRkdMRTlCUVVFN1FVRkJjVVFzVTBGQlFVVXNkVUpCUVVGRExFTkJRVUVzVjBGQlFVRXNRMEZCUVN4SlFVRkJRU3hEUVVGQkxFTkJRVUZETEZWQlFVRXNSMEZCUVVRc1EwRkJRU3hMUVVGQlJTeFBRVUZCTEVWQlFVRkdMRU5CUVVFN1FVRk1ja1E3UVVGRFFUczdRVUZ2UWtFN1FVRkRUeXhOUVVGTlJ5eFRRVUZUTEVkQlFVRkRMRTlCUVVFc1EwRkJRVVFzVTBGQlFTeEhRVUZIUlN4elFrRlhlRUk3UVVGRlJEdEJRVU5QTEUxQlFVMURMRkZCUVZFc1IwRkJRVVlzVDBGQlFTeERRVUZCUlN4UlFVRkJMRWRCUVVjc1NVRkJRVU1zYTBOQlFXTXNSVUZCUTBZc2MwSkJRV2xDTEVOQlYzWkVPMEZCUlVRN1FVRkJRU3hKUVVGQlJ5eFJRVUZCTEVkQlFVRktMRTlCUVVFc1EwRkJRVVlzVDBGQlFTeEhRVU5sU1N4UlFVRlJJaXdpYVdkdWIzSmxUR2x6ZENJNlcxMTkiLCJcInVzZSBzdHJpY3RcIjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuTVMgPSB2b2lkIDA7XG5leHBvcnRzLmFzc2VydElzQm9vbGVhbiA9IGFzc2VydElzQm9vbGVhbjtcbmV4cG9ydHMuYXNzZXJ0SXNEZWZpbmVkID0gYXNzZXJ0SXNEZWZpbmVkO1xuZXhwb3J0cy5hc3NlcnRJc0luc3RhbmNlT2YgPSBhc3NlcnRJc0luc3RhbmNlT2Y7XG5leHBvcnRzLmFzc2VydElzTnVtYmVyID0gYXNzZXJ0SXNOdW1iZXI7XG5leHBvcnRzLmFzc2VydElzU3RyaW5nID0gYXNzZXJ0SXNTdHJpbmc7XG5leHBvcnRzLmFzc2VydElzVW5kZWZpbmVkID0gYXNzZXJ0SXNVbmRlZmluZWQ7XG5leHBvcnRzLmNvbHVtbnMgPSBjb2x1bW5zO1xuZXhwb3J0cy5kZWVwTWVyZ2UgPSBkZWVwTWVyZ2U7XG5leHBvcnRzLmZvcm1hdExpc3QgPSBmb3JtYXRMaXN0O1xuZXhwb3J0cy5mb3JtYXRNaWxsaXNlY29uZHMgPSBmb3JtYXRNaWxsaXNlY29uZHM7XG5leHBvcnRzLmZvcm1hdFNlY29uZHMgPSBmb3JtYXRTZWNvbmRzO1xuZXhwb3J0cy5nZXRWYWxpZGF0aW9uVHJlZSA9IGdldFZhbGlkYXRpb25UcmVlO1xuZXhwb3J0cy5rZXlvZkNoZWNrZXIgPSBrZXlvZkNoZWNrZXI7XG5leHBvcnRzLnBsdXJhbCA9IHBsdXJhbDtcbnZhciBfYXNzZXJ0ID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiYXNzZXJ0XCIpKTtcbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoZSkgeyByZXR1cm4gZSAmJiBlLl9fZXNNb2R1bGUgPyBlIDogeyBkZWZhdWx0OiBlIH07IH1cbi8vIEhvbWVicmlkZ2UgcGx1Z2luIGZvciBIb21lIENvbm5lY3QgaG9tZSBhcHBsaWFuY2VzXG4vLyBDb3B5cmlnaHQgwqkgMjAyMy0yMDI2IEFsZXhhbmRlciBUaG91a3lkaWRlc1xuXG4vLyBNaWxsaXNlY29uZHMgaW4gYSBzZWNvbmRcbmNvbnN0IE1TID0gZXhwb3J0cy5NUyA9IDEwMDA7XG4vLyBUeXBlIGFzc2VydGlvbnNcbmZ1bmN0aW9uIGFzc2VydElzRGVmaW5lZCh2YWx1ZSkge1xuICBfYXNzZXJ0LmRlZmF1bHQubm90U3RyaWN0RXF1YWwodmFsdWUsIHVuZGVmaW5lZCk7XG4gIF9hc3NlcnQuZGVmYXVsdC5ub3RTdHJpY3RFcXVhbCh2YWx1ZSwgbnVsbCk7XG59XG5mdW5jdGlvbiBhc3NlcnRJc1VuZGVmaW5lZCh2YWx1ZSkge1xuICBfYXNzZXJ0LmRlZmF1bHQuc3RyaWN0RXF1YWwodmFsdWUsIHVuZGVmaW5lZCk7XG59XG5mdW5jdGlvbiBhc3NlcnRJc1N0cmluZyh2YWx1ZSkge1xuICBfYXNzZXJ0LmRlZmF1bHQuc3RyaWN0RXF1YWwodHlwZW9mIHZhbHVlLCAnc3RyaW5nJyk7XG59XG5mdW5jdGlvbiBhc3NlcnRJc051bWJlcih2YWx1ZSkge1xuICBfYXNzZXJ0LmRlZmF1bHQuc3RyaWN0RXF1YWwodHlwZW9mIHZhbHVlLCAnbnVtYmVyJyk7XG59XG5mdW5jdGlvbiBhc3NlcnRJc0Jvb2xlYW4odmFsdWUpIHtcbiAgX2Fzc2VydC5kZWZhdWx0LnN0cmljdEVxdWFsKHR5cGVvZiB2YWx1ZSwgJ2Jvb2xlYW4nKTtcbn1cbmZ1bmN0aW9uIGFzc2VydElzSW5zdGFuY2VPZih2YWx1ZSwgdHlwZSkge1xuICAoMCwgX2Fzc2VydC5kZWZhdWx0KSh2YWx1ZSBpbnN0YW5jZW9mIHR5cGUsIGBOb3QgYW4gaW5zdGFuY2Ugb2YgJHt0eXBlLm5hbWV9YCk7XG59XG4vLyBGb3JtYXQgYSBtaWxsaXNlY29uZHMgZHVyYXRpb25cbmZ1bmN0aW9uIGZvcm1hdE1pbGxpc2Vjb25kcyhtcywgbWF4UGFydHMgPSAyKSB7XG4gIGlmIChtcyA8IDEpIHJldHVybiAnbi9hJztcbiAgLy8gU3BsaXQgdGhlIGR1cmF0aW9uIGludG8gY29tcG9uZW50c1xuICBjb25zdCBkdXJhdGlvbiA9IFtbJ2RheScsIE1hdGguZmxvb3IobXMgLyAoMjQgKiA2MCAqIDYwICogTVMpKV0sIFsnaG91cicsIE1hdGguZmxvb3IobXMgLyAoNjAgKiA2MCAqIE1TKSkgJSAyNF0sIFsnbWludXRlJywgTWF0aC5mbG9vcihtcyAvICg2MCAqIE1TKSkgJSA2MF0sIFsnc2Vjb25kJywgTWF0aC5mbG9vcihtcyAvIE1TKSAlIDYwXSwgWydtaWxsaXNlY29uZCcsIE1hdGguZmxvb3IobXMpICUgTVNdXTtcbiAgLy8gUmVtb3ZlIGFueSBsZWFkaW5nIHplcm8gY29tcG9uZW50c1xuICB3aGlsZSAoZHVyYXRpb25bMF0/LlsxXSA9PT0gMCkgZHVyYXRpb24uc2hpZnQoKTtcbiAgLy8gQ29tYmluZSB0aGUgcmVxdWlyZWQgbnVtYmVyIG9mIHJlbWFpbmluZyBjb21wb25lbnRzXG4gIHJldHVybiBkdXJhdGlvbi5zbGljZSgwLCBtYXhQYXJ0cykuZmlsdGVyKChbX2tleSwgdmFsdWVdKSA9PiB2YWx1ZSAhPT0gMCkubWFwKChba2V5LCB2YWx1ZV0pID0+IHBsdXJhbCh2YWx1ZSwga2V5KSkuam9pbignICcpO1xufVxuLy8gRm9ybWF0IGEgc2Vjb25kcyBkdXJhdGlvblxuZnVuY3Rpb24gZm9ybWF0U2Vjb25kcyhzZWNvbmRzLCBtYXhQYXJ0cyA9IDIpIHtcbiAgcmV0dXJuIGZvcm1hdE1pbGxpc2Vjb25kcyhzZWNvbmRzICogMTAwMCwgbWF4UGFydHMpO1xufVxuLy8gRm9ybWF0IGEgbGlzdCAod2l0aCBPeGZvcmQgY29tbWEpXG5mdW5jdGlvbiBmb3JtYXRMaXN0KGl0ZW1zKSB7XG4gIHN3aXRjaCAoaXRlbXMubGVuZ3RoKSB7XG4gICAgY2FzZSAwOlxuICAgICAgcmV0dXJuICduL2EnO1xuICAgIGNhc2UgMTpcbiAgICAgIHJldHVybiBpdGVtc1swXSA/PyAnJztcbiAgICBjYXNlIDI6XG4gICAgICByZXR1cm4gYCR7aXRlbXNbMF19IGFuZCAke2l0ZW1zWzFdfWA7XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBbLi4uaXRlbXMuc2xpY2UoMCwgLTEpLCBgYW5kICR7aXRlbXNbaXRlbXMubGVuZ3RoIC0gMV19YF0uam9pbignLCAnKTtcbiAgfVxufVxuLy8gRm9ybWF0IGEgY291bnRlZCBub3VuIChoYW5kbGluZyBtb3N0IHJlZ3VsYXIgY2FzZXMgYXV0b21hdGljYWxseSlcbmZ1bmN0aW9uIHBsdXJhbChjb3VudCwgbm91biwgc2hvd0NvdW50ID0gdHJ1ZSkge1xuICBjb25zdCBbc2luZ3VsYXIsIHBsdXJhbF0gPSBBcnJheS5pc0FycmF5KG5vdW4pID8gbm91biA6IFtub3VuLCAnJ107XG4gIG5vdW4gPSBjb3VudCA9PT0gMSA/IHNpbmd1bGFyIDogcGx1cmFsO1xuICBpZiAoIW5vdW4pIHtcbiAgICAvLyBBcHBseSByZWd1bGFyIHJ1bGVzXG4gICAgY29uc3QgcnVsZXMgPSBbWydvbiQnLCAnYScsIDJdLFxuICAgIC8vIHBoZW5vbWVub24vcGhlbm9tZW5hIGNyaXRlcmlvbi9jcml0ZXJpYVxuICAgIFsndXMkJywgJ2knLCAxXSxcbiAgICAvLyAgICAgY2FjdHVzL2NhY3RpICAgICAgICAgZm9jdXMvZm9jaVxuICAgIFsnW15hZWlvdV15JCcsICdpZXMnLCAxXSxcbiAgICAvLyAgICAgICAgY3R5L2NpdGVzICAgICAgICAgcHVwcHkvcHVwcGllc1xuICAgIFsnKGNofGlzfG98c3xzaHx4fHopJCcsICdlcycsIDBdLFxuICAgIC8vICAgICAgIGlyaXMvaXJpc2VzICAgICAgICB0cnVzcy90cnVzc2VzXG4gICAgWycnLCAncycsIDBdIC8vICAgICAgICBjYXQvY2F0cyAgICAgICAgICBob3VzZS9ob3VzZXNcbiAgICBdO1xuICAgIGNvbnN0IHJ1bGUgPSBydWxlcy5maW5kKChbZW5kaW5nXSkgPT4gbmV3IFJlZ0V4cChlbmRpbmcsICdpJykudGVzdChzaW5ndWxhcikpO1xuICAgIGFzc2VydElzRGVmaW5lZChydWxlKTtcbiAgICBjb25zdCBtYXRjaENhc2UgPSBzID0+IHNpbmd1bGFyID09PSBzaW5ndWxhci50b1VwcGVyQ2FzZSgpID8gcy50b1VwcGVyQ2FzZSgpIDogcztcbiAgICBub3VuID0gc2luZ3VsYXIuc3Vic3RyaW5nKDAsIHNpbmd1bGFyLmxlbmd0aCAtIHJ1bGVbMl0pLmNvbmNhdChtYXRjaENhc2UocnVsZVsxXSkpO1xuICB9XG4gIHJldHVybiBzaG93Q291bnQgPyBgJHtjb3VudH0gJHtub3VufWAgOiBub3VuO1xufVxuLy8gRm9ybWF0IHN0cmluZ3MgaW4gY29sdW1uc1xuZnVuY3Rpb24gY29sdW1ucyhyb3dzLCBzZXBhcmF0b3IgPSAnICAnKSB7XG4gIC8vIERldGVybWluZSB0aGUgcmVxdWlyZWQgY29sdW1uIHdpZHRoc1xuICBjb25zdCB3aWR0aCA9IFtdO1xuICByb3dzLmZvckVhY2gocm93ID0+IHtcbiAgICByb3cuZm9yRWFjaCgodmFsdWUsIGluZGV4KSA9PiB7XG4gICAgICB3aWR0aFtpbmRleF0gPSBNYXRoLm1heCh3aWR0aFtpbmRleF0gPz8gMCwgdmFsdWUubGVuZ3RoKTtcbiAgICB9KTtcbiAgfSk7XG4gIHdpZHRoLnNwbGljZSgtMSwgMSwgMCk7XG4gIC8vIEZvcm1hdCB0aGUgcm93c1xuICByZXR1cm4gcm93cy5tYXAocm93ID0+IHJvdy5tYXAoKHZhbHVlLCBpbmRleCkgPT4gdmFsdWUucGFkRW5kKHdpZHRoW2luZGV4XSA/PyAwKSkuam9pbihzZXBhcmF0b3IpKTtcbn1cbi8vIFJlY3Vyc2l2ZSBvYmplY3QgYXNzaWdubWVudCwgc2tpcHBpbmcgdW5kZWZpbmVkIHZhbHVlc1xuZnVuY3Rpb24gZGVlcE1lcmdlKC4uLm9iamVjdHMpIHtcbiAgY29uc3QgaXNPYmplY3QgPSB2YWx1ZSA9PiB2YWx1ZSAhPT0gdW5kZWZpbmVkICYmIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgIUFycmF5LmlzQXJyYXkodmFsdWUpO1xuICByZXR1cm4gb2JqZWN0cy5yZWR1Y2UoKGFjYywgb2JqZWN0KSA9PiB7XG4gICAgT2JqZWN0LmVudHJpZXMob2JqZWN0KS5mb3JFYWNoKChba2V5LCB2YWx1ZV0pID0+IHtcbiAgICAgIGNvbnN0IGFjY1ZhbHVlID0gYWNjW2tleV07XG4gICAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCkgcmV0dXJuO1xuICAgICAgaWYgKGlzT2JqZWN0KGFjY1ZhbHVlKSAmJiBpc09iamVjdCh2YWx1ZSkpIGFjY1trZXldID0gZGVlcE1lcmdlKGFjY1ZhbHVlLCB2YWx1ZSk7ZWxzZSBhY2Nba2V5XSA9IHZhbHVlO1xuICAgIH0pO1xuICAgIHJldHVybiBhY2M7XG4gIH0sIHt9KTtcbn1cbi8vIENvbnZlcnQgY2hlY2tlciB2YWxpZGF0aW9uIGVycm9yIGludG8gbGluZXMgb2YgdGV4dFxuZnVuY3Rpb24gZ2V0VmFsaWRhdGlvblRyZWUoZXJyb3JzKSB7XG4gIGNvbnN0IGxpbmVzID0gW107XG4gIGVycm9ycy5mb3JFYWNoKChlcnJvciwgaW5kZXgpID0+IHtcbiAgICBjb25zdCBwcmVmaXggPSAoYSwgYikgPT4gaW5kZXggPCBlcnJvcnMubGVuZ3RoIC0gMSA/IGEgOiBiO1xuICAgIGxpbmVzLnB1c2goYCR7cHJlZml4KCfilJzilIAgJywgJ+KUlOKUgCAnKX0ke2Vycm9yLnBhdGh9ICR7ZXJyb3IubWVzc2FnZX1gKTtcbiAgICBpZiAoZXJyb3IubmVzdGVkKSB7XG4gICAgICBjb25zdCBuZXN0ZWQgPSBnZXRWYWxpZGF0aW9uVHJlZShlcnJvci5uZXN0ZWQpO1xuICAgICAgbGluZXMucHVzaCguLi5uZXN0ZWQubWFwKGxpbmUgPT4gYCR7cHJlZml4KCfilIIgICcsICcgICAnKX0gJHtsaW5lfWApKTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gbGluZXM7XG59XG4vLyBFeHRyYWN0IHByb3BlcnR5IGtleXMgb3IgdW5pb24gbGl0ZXJhbCBmcm9tIGEgdGktaW50ZXJmYWNlLWNoZWNrZXIgdHlwZVxuZnVuY3Rpb24ga2V5b2ZDaGVja2VyKHR5cGVTdWl0ZSwgdHlwZSkge1xuICBjb25zdCBjaGVja2VyID0gdHlwZTtcbiAgLy8gVElmYWNlXG4gIGNvbnN0IHByb3BzID0gW107XG4gIGlmIChjaGVja2VyLnByb3BTZXQgaW5zdGFuY2VvZiBTZXQpIHtcbiAgICBwcm9wcy5wdXNoKC4uLmNoZWNrZXIucHJvcFNldCk7XG4gIH1cbiAgaWYgKEFycmF5LmlzQXJyYXkoY2hlY2tlci5iYXNlcykpIHtcbiAgICBmb3IgKGNvbnN0IGJhc2Ugb2YgY2hlY2tlci5iYXNlcykge1xuICAgICAgY29uc3QgYmFzZVR5cGUgPSB0eXBlU3VpdGVbYmFzZV07XG4gICAgICBhc3NlcnRJc0RlZmluZWQoYmFzZVR5cGUpO1xuICAgICAgcHJvcHMucHVzaCguLi5rZXlvZkNoZWNrZXIodHlwZVN1aXRlLCBiYXNlVHlwZSkpO1xuICAgIH1cbiAgfVxuICAvLyBUVW5pb24gb3IgVEludGVyc2VjdGlvblxuICBpZiAoQXJyYXkuaXNBcnJheShjaGVja2VyLnR0eXBlcykpIHtcbiAgICBmb3IgKGNvbnN0IHR0eXBlIG9mIGNoZWNrZXIudHR5cGVzKSBwcm9wcy5wdXNoKC4uLmtleW9mQ2hlY2tlcih0eXBlU3VpdGUsIHR0eXBlKSk7XG4gIH1cbiAgLy8gVEVudW1cbiAgaWYgKGNoZWNrZXIudmFsaWRWYWx1ZXMgaW5zdGFuY2VvZiBTZXQpIHtcbiAgICBwcm9wcy5wdXNoKC4uLmNoZWNrZXIudmFsaWRWYWx1ZXMpO1xuICB9XG4gIGlmICh0eXBlb2YgY2hlY2tlci52YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAvLyBUTGl0ZXJhbFxuICAgIHByb3BzLnB1c2goY2hlY2tlci52YWx1ZSk7XG4gIH0gZWxzZSBpZiAodHlwZW9mIGNoZWNrZXIubmFtZSA9PT0gJ3N0cmluZycpIHtcbiAgICAvLyBUTmFtZVxuICAgIGNvbnN0IG5hbWVUeXBlID0gdHlwZVN1aXRlW2NoZWNrZXIubmFtZV07XG4gICAgYXNzZXJ0SXNEZWZpbmVkKG5hbWVUeXBlKTtcbiAgICBwcm9wcy5wdXNoKC4uLmtleW9mQ2hlY2tlcih0eXBlU3VpdGUsIG5hbWVUeXBlKSk7XG4gIH1cbiAgcmV0dXJuIHByb3BzO1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ9dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p1WVcxbGN5STZXeUpmWVhOelpYSjBJaXdpWDJsdWRHVnliM0JTWlhGMWFYSmxSR1ZtWVhWc2RDSXNJbkpsY1hWcGNtVWlMQ0psSWl3aVgxOWxjMDF2WkhWc1pTSXNJbVJsWm1GMWJIUWlMQ0pOVXlJc0ltVjRjRzl5ZEhNaUxDSmhjM05sY25SSmMwUmxabWx1WldRaUxDSjJZV3gxWlNJc0ltRnpjMlZ5ZENJc0ltNXZkRk4wY21samRFVnhkV0ZzSWl3aWRXNWtaV1pwYm1Wa0lpd2lZWE56WlhKMFNYTlZibVJsWm1sdVpXUWlMQ0p6ZEhKcFkzUkZjWFZoYkNJc0ltRnpjMlZ5ZEVselUzUnlhVzVuSWl3aVlYTnpaWEowU1hOT2RXMWlaWElpTENKaGMzTmxjblJKYzBKdmIyeGxZVzRpTENKaGMzTmxjblJKYzBsdWMzUmhibU5sVDJZaUxDSjBlWEJsSWl3aWJtRnRaU0lzSW1admNtMWhkRTFwYkd4cGMyVmpiMjVrY3lJc0ltMXpJaXdpYldGNFVHRnlkSE1pTENKa2RYSmhkR2x2YmlJc0lrMWhkR2dpTENKbWJHOXZjaUlzSW5Ob2FXWjBJaXdpYzJ4cFkyVWlMQ0ptYVd4MFpYSWlMQ0pmYTJWNUlpd2liV0Z3SWl3aWEyVjVJaXdpY0d4MWNtRnNJaXdpYW05cGJpSXNJbVp2Y20xaGRGTmxZMjl1WkhNaUxDSnpaV052Ym1Seklpd2labTl5YldGMFRHbHpkQ0lzSW1sMFpXMXpJaXdpYkdWdVozUm9JaXdpWTI5MWJuUWlMQ0p1YjNWdUlpd2ljMmh2ZDBOdmRXNTBJaXdpYzJsdVozVnNZWElpTENKQmNuSmhlU0lzSW1selFYSnlZWGtpTENKeWRXeGxjeUlzSW5KMWJHVWlMQ0ptYVc1a0lpd2laVzVrYVc1bklpd2lVbVZuUlhod0lpd2lkR1Z6ZENJc0ltMWhkR05vUTJGelpTSXNJbk1pTENKMGIxVndjR1Z5UTJGelpTSXNJbk4xWW5OMGNtbHVaeUlzSW1OdmJtTmhkQ0lzSW1OdmJIVnRibk1pTENKeWIzZHpJaXdpYzJWd1lYSmhkRzl5SWl3aWQybGtkR2dpTENKbWIzSkZZV05vSWl3aWNtOTNJaXdpYVc1a1pYZ2lMQ0p0WVhnaUxDSnpjR3hwWTJVaUxDSndZV1JGYm1RaUxDSmtaV1Z3VFdWeVoyVWlMQ0p2WW1wbFkzUnpJaXdpYVhOUFltcGxZM1FpTENKeVpXUjFZMlVpTENKaFkyTWlMQ0p2WW1wbFkzUWlMQ0pQWW1wbFkzUWlMQ0psYm5SeWFXVnpJaXdpWVdOalZtRnNkV1VpTENKblpYUldZV3hwWkdGMGFXOXVWSEpsWlNJc0ltVnljbTl5Y3lJc0lteHBibVZ6SWl3aVpYSnliM0lpTENKd2NtVm1hWGdpTENKaElpd2lZaUlzSW5CMWMyZ2lMQ0p3WVhSb0lpd2liV1Z6YzJGblpTSXNJbTVsYzNSbFpDSXNJbXhwYm1VaUxDSnJaWGx2WmtOb1pXTnJaWElpTENKMGVYQmxVM1ZwZEdVaUxDSmphR1ZqYTJWeUlpd2ljSEp2Y0hNaUxDSndjbTl3VTJWMElpd2lVMlYwSWl3aVltRnpaWE1pTENKaVlYTmxJaXdpWW1GelpWUjVjR1VpTENKMGRIbHdaWE1pTENKMGRIbHdaU0lzSW5aaGJHbGtWbUZzZFdWeklpd2libUZ0WlZSNWNHVWlYU3dpYzI5MWNtTmxjeUk2V3lJdUxpOXpjbU12ZFhScGJITXVkSE1pWFN3aWMyOTFjbU5sYzBOdmJuUmxiblFpT2x0dWRXeHNYU3dpYldGd2NHbHVaM01pT2lJN096czdPenM3T3pzN096czdPenM3T3pzN08wRkJSMEVzU1VGQlFVRXNUMEZCUVN4SFFVRkJReXh6UWtGQlFTeERRVUZCUXl4UFFVRkJPMEZCUVRSQ0xGTkJRVUZFTEhWQ1FVRkJSU3hEUVVGQkxGZEJRVUZCTEVOQlFVRXNTVUZCUVVFc1EwRkJRU3hEUVVGQlF5eFZRVUZCTEVkQlFVRkVMRU5CUVVFc1MwRkJRVVVzVDBGQlFTeEZRVUZCUml4RFFVRkJPMEZCU0RWQ08wRkJRMEU3TzBGQlMwRTdRVUZEVHl4TlFVRk5SeXhGUVVGRkxFZEJRVUZETEU5QlFVRXNRMEZCUVVRc1JVRkJRU3hIUVVGSExFbEJRVWs3UVVGamRFSTdRVUZEVFN4VFFVRlZSU3hsUVVGbFFTeERRVUZQUXl4TFFVRlhPMFZCUXpkRFF5eGxRVUZOTEVOQlFVTkRMR05CUVdNc1EwRkJRMFlzUzBGQlN5eEZRVUZGUnl4VFFVRlRMRU5CUVVNN1JVRkRka05HTEdWQlFVMHNRMEZCUTBNc1kwRkJZeXhEUVVGRFJpeExRVUZMTEVWQlFVVXNTVUZCU1N4RFFVRkRPMEZCUTNSRE8wRkJRMDBzVTBGQlZVa3NhVUpCUVdsQ1FTeERRVUZEU2l4TFFVRmpPMFZCUXpWRFF5eGxRVUZOTEVOQlFVTkpMRmRCUVZjc1EwRkJRMHdzUzBGQlN5eEZRVUZGUnl4VFFVRlRMRU5CUVVNN1FVRkRlRU03UVVGRFRTeFRRVUZWUnl4alFVRmpRU3hEUVVGRFRpeExRVUZqTzBWQlEzcERReXhsUVVGTkxFTkJRVU5KTEZkQlFWY3NRMEZCUXl4UFFVRlBUQ3hMUVVGTExFVkJRVVVzVVVGQlVTeERRVUZETzBGQlF6bERPMEZCUTAwc1UwRkJWVThzWTBGQlkwRXNRMEZCUTFBc1MwRkJZenRGUVVONlEwTXNaVUZCVFN4RFFVRkRTU3hYUVVGWExFTkJRVU1zVDBGQlQwd3NTMEZCU3l4RlFVRkZMRkZCUVZFc1EwRkJRenRCUVVNNVF6dEJRVU5OTEZOQlFWVlJMR1ZCUVdWQkxFTkJRVU5TTEV0QlFXTTdSVUZETVVORExHVkJRVTBzUTBGQlEwa3NWMEZCVnl4RFFVRkRMRTlCUVU5TUxFdEJRVXNzUlVGQlJTeFRRVUZUTEVOQlFVTTdRVUZETDBNN1FVRkRUU3hUUVVGVlV5eHJRa0ZCYTBKQkxFTkJRWE5DVkN4TFFVRmpMRVZCUVVWVkxFbEJRWFZDTzBWQlF6TkdMRWxCUVVGVUxHVkJRVTBzUlVGQlEwUXNTMEZCU3l4WlFVRlpWU3hKUVVGSkxFVkJRVVVzYzBKQlFYTkNRU3hKUVVGSkxFTkJRVU5ETEVsQlFVa3NSVUZCUlN4RFFVRkRPMEZCUTNCRk8wRkJSVUU3UVVGRFRTeFRRVUZWUXl4clFrRkJhMEpCTEVOQlFVTkRMRVZCUVZVc1JVRkJSVU1zVVVGQlVTeEhRVUZITEVOQlFVTTdSVUZEZGtRc1NVRkJTVVFzUlVGQlJTeEhRVUZITEVOQlFVTXNSVUZCUlN4UFFVRlBMRXRCUVVzN1JVRkZlRUk3UlVGRFFTeE5RVUZOUlN4UlFVRlJMRWRCUVhWQ0xFTkJRMnBETEVOQlFVTXNTMEZCU3l4RlFVRlZReXhKUVVGSkxFTkJRVU5ETEV0QlFVc3NRMEZCUTBvc1JVRkJSU3hKUVVGSkxFVkJRVVVzUjBGQlJ5eEZRVUZGTEVkQlFVY3NSVUZCUlN4SFFVRkhhRUlzUlVGQlJTeERRVUZETEVOQlFVTXNRMEZCVFN4RlFVTXhSQ3hEUVVGRExFMUJRVTBzUlVGQlUyMUNMRWxCUVVrc1EwRkJRME1zUzBGQlN5eERRVUZEU2l4RlFVRkZMRWxCUVZNc1JVRkJSU3hIUVVGSExFVkJRVVVzUjBGQlIyaENMRVZCUVVVc1EwRkJReXhEUVVGRExFZEJRVWNzUlVGQlJTeERRVUZETEVWQlF6RkVMRU5CUVVNc1VVRkJVU3hGUVVGUGJVSXNTVUZCU1N4RFFVRkRReXhMUVVGTExFTkJRVU5LTEVWQlFVVXNTVUZCWXl4RlFVRkZMRWRCUVVkb1FpeEZRVUZGTEVOQlFVTXNRMEZCUXl4SFFVRkhMRVZCUVVVc1EwRkJReXhGUVVNeFJDeERRVUZETEZGQlFWRXNSVUZCVDIxQ0xFbEJRVWtzUTBGQlEwTXNTMEZCU3l4RFFVRkRTaXhGUVVGRkxFZEJRVzFDYUVJc1JVRkJSU3hEUVVGRkxFZEJRVWNzUlVGQlJTeERRVUZETEVWQlF6RkVMRU5CUVVNc1lVRkJZU3hGUVVGRmJVSXNTVUZCU1N4RFFVRkRReXhMUVVGTExFTkJRVU5LTEVWQlFVVXNRMEZCZFVJc1IwRkJSMmhDTEVWQlFVVXNRMEZCUXl4RFFVTTNSRHRGUVVWRU8wVkJRMEVzVDBGQlQydENMRkZCUVZFc1EwRkJReXhEUVVGRExFTkJRVU1zUjBGQlJ5eERRVUZETEVOQlFVTXNTMEZCU3l4RFFVRkRMRVZCUVVWQkxGRkJRVkVzUTBGQlEwY3NTMEZCU3l4RlFVRkZPMFZCUlM5RE8wVkJRMEVzVDBGQlQwZ3NVVUZCVVN4RFFVRkRTU3hMUVVGTExFTkJRVU1zUTBGQlF5eEZRVUZGVEN4UlFVRlJMRU5CUVVNc1EwRkROMEpOTEUxQlFVMHNRMEZCUXl4RFFVRkRMRU5CUVVORExFbEJRVWtzUlVGQlJYSkNMRXRCUVVzc1EwRkJReXhMUVVGTFFTeExRVUZMTEV0QlFVc3NRMEZCUXl4RFFVRkRMRU5CUTNSRGMwSXNSMEZCUnl4RFFVRkRMRU5CUVVNc1EwRkJRME1zUjBGQlJ5eEZRVUZGZGtJc1MwRkJTeXhEUVVGRExFdEJRVXQzUWl4TlFVRk5MRU5CUVVONFFpeExRVUZMTEVWQlFVVjFRaXhIUVVGSExFTkJRVU1zUTBGQlF5eERRVU42UTBVc1NVRkJTU3hEUVVGRExFZEJRVWNzUTBGQlF6dEJRVU5zUWp0QlFVVkJPMEZCUTAwc1UwRkJWVU1zWVVGQllVRXNRMEZCUTBNc1QwRkJaU3hGUVVGRllpeFJRVUZSTEVkQlFVY3NRMEZCUXp0RlFVTjJSQ3hQUVVGUFJpeHJRa0ZCYTBJc1EwRkJRMlVzVDBGQlR5eEhRVUZITEVsQlFVa3NSVUZCUldJc1VVRkJVU3hEUVVGRE8wRkJRM1pFTzBGQlJVRTdRVUZEVFN4VFFVRlZZeXhWUVVGVlFTeERRVUZEUXl4TFFVRmxPMFZCUTNSRExGRkJRVkZCTEV0QlFVc3NRMEZCUTBNc1RVRkJUVHRKUVVOd1FpeExRVUZMTEVOQlFVTTdUVUZCVFN4UFFVRlBMRXRCUVVzN1NVRkRlRUlzUzBGQlN5eERRVUZETzAxQlFVMHNUMEZCVDBRc1MwRkJTeXhEUVVGRExFTkJRVU1zUTBGQlF5eEpRVUZKTEVWQlFVVTdTVUZEYWtNc1MwRkJTeXhEUVVGRE8wMUJRVTBzVDBGQlR5eEhRVUZIUVN4TFFVRkxMRU5CUVVNc1EwRkJReXhEUVVGRExGRkJRVkZCTEV0QlFVc3NRMEZCUXl4RFFVRkRMRU5CUVVNc1JVRkJSVHRKUVVOb1JEdE5RVUZaTEU5QlFVOHNRMEZCUXl4SFFVRkhRU3hMUVVGTExFTkJRVU5XTEV0QlFVc3NRMEZCUXl4RFFVRkRMRVZCUVVVc1EwRkJReXhEUVVGRExFTkJRVU1zUlVGQlJTeFBRVUZQVlN4TFFVRkxMRU5CUVVOQkxFdEJRVXNzUTBGQlEwTXNUVUZCVFN4SFFVRkhMRU5CUVVNc1EwRkJReXhGUVVGRkxFTkJRVU1zUTBGQlEwd3NTVUZCU1N4RFFVRkRMRWxCUVVrc1EwRkJRenRGUVVOMlJqdEJRVU5LTzBGQlJVRTdRVUZEVFN4VFFVRlZSQ3hOUVVGTlFTeERRVUZEVHl4TFFVRmhMRVZCUVVWRExFbEJRU3RDTEVWQlFVVkRMRk5CUVZNc1IwRkJSeXhKUVVGSk8wVkJRMjVHTEUxQlFVMHNRMEZCUTBNc1VVRkJVU3hGUVVGRlZpeE5RVUZOTEVOQlFVTXNSMEZCUjFjc1MwRkJTeXhEUVVGRFF5eFBRVUZQTEVOQlFVTktMRWxCUVVrc1EwRkJReXhIUVVGSFFTeEpRVUZKTEVkQlFVY3NRMEZCUTBFc1NVRkJTU3hGUVVGRkxFVkJRVVVzUTBGQlF6dEZRVU5zUlVFc1NVRkJTU3hIUVVGSFJDeExRVUZMTEV0QlFVc3NRMEZCUXl4SFFVRkhSeXhSUVVGUkxFZEJRVWRXTEUxQlFVMDdSVUZEZEVNc1NVRkJTU3hEUVVGRFVTeEpRVUZKTEVWQlFVVTdTVUZEVUR0SlFVTkJMRTFCUVUxTExFdEJRVXNzUjBGQkswSXNRMEZEZEVNc1EwRkJReXhMUVVGTExFVkJRV3RDTEVkQlFVY3NSVUZCU1N4RFFVRkRMRU5CUVVNN1NVRkJSVHRKUVVOdVF5eERRVUZETEV0QlFVc3NSVUZCYTBJc1IwRkJSeXhGUVVGSkxFTkJRVU1zUTBGQlF6dEpRVUZGTzBsQlEyNURMRU5CUVVNc1dVRkJXU3hGUVVGWExFdEJRVXNzUlVGQlJTeERRVUZETEVOQlFVTTdTVUZCUlR0SlFVTnVReXhEUVVGRExIRkNRVUZ4UWl4RlFVRkZMRWxCUVVrc1JVRkJSeXhEUVVGRExFTkJRVU03U1VGQlJUdEpRVU51UXl4RFFVRkRMRVZCUVVVc1JVRkJjVUlzUjBGQlJ5eEZRVUZKTEVOQlFVTXNRMEZCUXl4RFFVRkZPMGxCUVVFc1EwRkRkRU03U1VGRFJDeE5RVUZOUXl4SlFVRkpMRWRCUVVkRUxFdEJRVXNzUTBGQlEwVXNTVUZCU1N4RFFVRkRMRU5CUVVNc1EwRkJRME1zVFVGQlRTeERRVUZETEV0QlFVc3NTVUZCU1VNc1RVRkJUU3hEUVVGRFJDeE5RVUZOTEVWQlFVVXNSMEZCUnl4RFFVRkRMRU5CUVVORkxFbEJRVWtzUTBGQlExSXNVVUZCVVN4RFFVRkRMRU5CUVVNN1NVRkROMFZ1UXl4bFFVRmxMRU5CUVVOMVF5eEpRVUZKTEVOQlFVTTdTVUZEY2tJc1RVRkJUVXNzVTBGQlV5eEhRVUZKUXl4RFFVRlRMRWxCUVdGV0xGRkJRVkVzUzBGQlMwRXNVVUZCVVN4RFFVRkRWeXhYUVVGWExFVkJRVVVzUjBGQlIwUXNRMEZCUXl4RFFVRkRReXhYUVVGWExFVkJRVVVzUjBGQlIwUXNRMEZCUXp0SlFVTnNSMW9zU1VGQlNTeEhRVUZIUlN4UlFVRlJMRU5CUVVOWkxGTkJRVk1zUTBGQlF5eERRVUZETEVWQlFVVmFMRkZCUVZFc1EwRkJRMG9zVFVGQlRTeEhRVUZIVVN4SlFVRkpMRU5CUVVNc1EwRkJReXhEUVVGRExFTkJRVU1zUTBGQlExTXNUVUZCVFN4RFFVRkRTaXhUUVVGVExFTkJRVU5NTEVsQlFVa3NRMEZCUXl4RFFVRkRMRU5CUVVNc1EwRkJReXhEUVVGRE8wVkJRM1JHTzBWQlEwRXNUMEZCVDB3c1UwRkJVeXhIUVVGSExFZEJRVWRHTEV0QlFVc3NTVUZCU1VNc1NVRkJTU3hGUVVGRkxFZEJRVWRCTEVsQlFVazdRVUZEYUVRN1FVRkZRVHRCUVVOTkxGTkJRVlZuUWl4UFFVRlBRU3hEUVVGRFF5eEpRVUZuUWl4RlFVRkZReXhUUVVGVExFZEJRVWNzU1VGQlNUdEZRVU4wUkR0RlFVTkJMRTFCUVUxRExFdEJRVXNzUjBGQllTeEZRVUZGTzBWQlF6RkNSaXhKUVVGSkxFTkJRVU5ITEU5QlFVOHNRMEZCUTBNc1IwRkJSeXhKUVVGSE8wbEJRMlpCTEVkQlFVY3NRMEZCUTBRc1QwRkJUeXhEUVVGRExFTkJRVU53UkN4TFFVRkxMRVZCUVVWelJDeExRVUZMTEV0QlFVazdUVUZEZWtKSUxFdEJRVXNzUTBGQlEwY3NTMEZCU3l4RFFVRkRMRWRCUVVkMFF5eEpRVUZKTEVOQlFVTjFReXhIUVVGSExFTkJRVU5LTEV0QlFVc3NRMEZCUTBjc1MwRkJTeXhEUVVGRExFbEJRVWtzUTBGQlF5eEZRVUZGZEVRc1MwRkJTeXhEUVVGRE9FSXNUVUZCVFN4RFFVRkRPMGxCUXpWRUxFTkJRVU1zUTBGQlF6dEZRVU5PTEVOQlFVTXNRMEZCUXp0RlFVTkdjVUlzUzBGQlN5eERRVUZEU3l4TlFVRk5MRU5CUVVNc1EwRkJReXhEUVVGRExFVkJRVVVzUTBGQlF5eEZRVUZGTEVOQlFVTXNRMEZCUXp0RlFVVjBRanRGUVVOQkxFOUJRVTlRTEVsQlFVa3NRMEZCUXpOQ0xFZEJRVWNzUTBGQlF5dENMRWRCUVVjc1NVRkJTVUVzUjBGQlJ5eERRVUZETDBJc1IwRkJSeXhEUVVGRExFTkJRVU4wUWl4TFFVRkxMRVZCUVVWelJDeExRVUZMTEV0QlFVdDBSQ3hMUVVGTExFTkJRVU41UkN4TlFVRk5MRU5CUVVOT0xFdEJRVXNzUTBGQlEwY3NTMEZCU3l4RFFVRkRMRWxCUVVrc1EwRkJReXhEUVVGRExFTkJRVU1zUTBGQlF6ZENMRWxCUVVrc1EwRkJRM2xDTEZOQlFWTXNRMEZCUXl4RFFVRkRPMEZCUTNSSE8wRkJSVUU3UVVGRFRTeFRRVUZWVVN4VFFVRlRRU3hEUVVGelFpeEhRVUZIUXl4UFFVRnRRenRGUVVOcVJpeE5RVUZOUXl4UlFVRlJMRWRCUVVrMVJDeExRVUZqTEVsQlF6VkNRU3hMUVVGTExFdEJRVXRITEZOQlFWTXNTVUZCU1N4UFFVRlBTQ3hMUVVGTExFdEJRVXNzVVVGQlVTeEpRVUZKTEVOQlFVTnRReXhMUVVGTExFTkJRVU5ETEU5QlFVOHNRMEZCUTNCRExFdEJRVXNzUTBGQlF6dEZRVU0zUlN4UFFVRlBNa1FzVDBGQlR5eERRVUZEUlN4TlFVRk5MRU5CUVVNc1EwRkJRME1zUjBGQk5FSXNSVUZCUlVNc1RVRkJZeXhMUVVGSk8wbEJRMjVGUXl4TlFVRk5MRU5CUVVORExFOUJRVThzUTBGQlEwWXNUVUZCVFN4RFFVRkRMRU5CUVVOWUxFOUJRVThzUTBGQlF5eERRVUZETEVOQlFVTTNRaXhIUVVGSExFVkJRVVYyUWl4TFFVRkxMRU5CUVVNc1MwRkJTVHROUVVNMVF5eE5RVUZOYTBVc1VVRkJVU3hIUVVGSFNpeEhRVUZITEVOQlFVTjJReXhIUVVGSExFTkJRVU03VFVGRGVrSXNTVUZCU1haQ0xFdEJRVXNzUzBGQlMwY3NVMEZCVXl4RlFVRkZPMDFCUTNwQ0xFbEJRVWw1UkN4UlFVRlJMRU5CUVVOTkxGRkJRVkVzUTBGQlF5eEpRVUZKVGl4UlFVRlJMRU5CUVVNMVJDeExRVUZMTEVOQlFVTXNSVUZCUlRoRUxFZEJRVWNzUTBGQlEzWkRMRWRCUVVjc1EwRkJReXhIUVVGSGJVTXNVMEZCVXl4RFFVRkRVU3hSUVVGUkxFVkJRVVZzUlN4TFFVRkxMRU5CUVVNc1EwRkJReXhMUVVNMVJUaEVMRWRCUVVjc1EwRkJRM1pETEVkQlFVY3NRMEZCUXl4SFFVRkhka0lzUzBGQlN6dEpRVU42UWl4RFFVRkRMRU5CUVVNN1NVRkRSaXhQUVVGUE9FUXNSMEZCUnp0RlFVTmtMRU5CUVVNc1JVRkJSU3hGUVVGRkxFTkJRVk03UVVGRGJFSTdRVUZSUVR0QlFVTk5MRk5CUVZWTExHbENRVUZwUWtFc1EwRkJRME1zVFVGQmMwSTdSVUZEY0VRc1RVRkJUVU1zUzBGQlN5eEhRVUZoTEVWQlFVVTdSVUZETVVKRUxFMUJRVTBzUTBGQlEyaENMRTlCUVU4c1EwRkJReXhEUVVGRGEwSXNTMEZCU3l4RlFVRkZhRUlzUzBGQlN5eExRVUZKTzBsQlF6VkNMRTFCUVUxcFFpeE5RVUZOTEVkQlFVZEJMRU5CUVVORExFTkJRVk1zUlVGQlJVTXNRMEZCVXl4TFFVRmhia0lzUzBGQlN5eEhRVUZIWXl4TlFVRk5MRU5CUVVOMFF5eE5RVUZOTEVkQlFVY3NRMEZCUXl4SFFVRkhNRU1zUTBGQlF5eEhRVUZIUXl4RFFVRkRPMGxCUTJ4R1NpeExRVUZMTEVOQlFVTkxMRWxCUVVrc1EwRkJReXhIUVVGSFNDeE5RVUZOTEVOQlFVTXNTMEZCU3l4RlFVRkZMRXRCUVVzc1EwRkJReXhIUVVGSFJDeExRVUZMTEVOQlFVTkxMRWxCUVVrc1NVRkJTVXdzUzBGQlN5eERRVUZEVFN4UFFVRlBMRVZCUVVVc1EwRkJRenRKUVVOdVJTeEpRVUZKVGl4TFFVRkxMRU5CUVVOUExFMUJRVTBzUlVGQlJUdE5RVU5rTEUxQlFVMUJMRTFCUVUwc1IwRkJSMVlzYVVKQlFXbENMRU5CUVVOSExFdEJRVXNzUTBGQlEwOHNUVUZCVFN4RFFVRkRPMDFCUXpsRFVpeExRVUZMTEVOQlFVTkxMRWxCUVVrc1EwRkJReXhIUVVGSFJ5eE5RVUZOTEVOQlFVTjJSQ3hIUVVGSExFTkJRVU4zUkN4SlFVRkpMRWxCUVVrc1IwRkJSMUFzVFVGQlRTeERRVUZETEV0QlFVc3NSVUZCUlN4TFFVRkxMRU5CUVVNc1NVRkJTVThzU1VGQlNTeEZRVUZGTEVOQlFVTXNRMEZCUXp0SlFVTjRSVHRGUVVOS0xFTkJRVU1zUTBGQlF6dEZRVU5HTEU5QlFVOVVMRXRCUVVzN1FVRkRhRUk3UVVGRlFUdEJRVU5OTEZOQlFWVlZMRmxCUVZsQkxFTkJRVU5ETEZOQlFYRkNMRVZCUVVWMFJTeEpRVUZYTzBWQlF6TkVMRTFCUVUxMVJTeFBRVUZQTEVkQlFVZDJSU3hKUVU5bU8wVkJSVVE3UlVGRFFTeE5RVUZOZDBVc1MwRkJTeXhIUVVGSExFVkJRVVU3UlVGRGFFSXNTVUZCU1VRc1QwRkJUeXhEUVVGRFJTeFBRVUZQTEZsQlFWbERMRWRCUVVjc1JVRkJSVHRKUVVOb1EwWXNTMEZCU3l4RFFVRkRVaXhKUVVGSkxFTkJRVU1zUjBGQlIwOHNUMEZCVHl4RFFVRkRSU3hQUVVGUExFTkJRVU03UlVGRGJFTTdSVUZEUVN4SlFVRkphRVFzUzBGQlN5eERRVUZEUXl4UFFVRlBMRU5CUVVNMlF5eFBRVUZQTEVOQlFVTkpMRXRCUVVzc1EwRkJReXhGUVVGRk8wbEJRemxDTEV0QlFVc3NUVUZCVFVNc1NVRkJTU3hKUVVGSlRDeFBRVUZQTEVOQlFVTkpMRXRCUVVzc1JVRkJSVHROUVVNNVFpeE5RVUZOUlN4UlFVRlJMRWRCUVVkUUxGTkJRVk1zUTBGQlEwMHNTVUZCU1N4RFFVRkRPMDFCUTJoRGRrWXNaVUZCWlN4RFFVRkRkMFlzVVVGQlVTeERRVUZETzAxQlEzcENUQ3hMUVVGTExFTkJRVU5TTEVsQlFVa3NRMEZCUXl4SFFVRkhTeXhaUVVGWkxFTkJRVU5ETEZOQlFWTXNSVUZCUlU4c1VVRkJVU3hEUVVGRExFTkJRVU03U1VGRGNFUTdSVUZEU2p0RlFVVkJPMFZCUTBFc1NVRkJTWEJFTEV0QlFVc3NRMEZCUTBNc1QwRkJUeXhEUVVGRE5rTXNUMEZCVHl4RFFVRkRUeXhOUVVGTkxFTkJRVU1zUlVGQlJUdEpRVU12UWl4TFFVRkxMRTFCUVUxRExFdEJRVXNzU1VGQlNWSXNUMEZCVHl4RFFVRkRUeXhOUVVGTkxFVkJRemxDVGl4TFFVRkxMRU5CUVVOU0xFbEJRVWtzUTBGQlF5eEhRVUZIU3l4WlFVRlpMRU5CUVVORExGTkJRVk1zUlVGQlJWTXNTMEZCU3l4RFFVRkRMRU5CUVVNN1JVRkRja1E3UlVGRlFUdEZRVU5CTEVsQlFVbFNMRTlCUVU4c1EwRkJRMU1zVjBGQlZ5eFpRVUZaVGl4SFFVRkhMRVZCUVVVN1NVRkRjRU5HTEV0QlFVc3NRMEZCUTFJc1NVRkJTU3hEUVVGRExFZEJRVWRQTEU5QlFVOHNRMEZCUTFNc1YwRkJWeXhEUVVGRE8wVkJRM1JETzBWQlJVRXNTVUZCU1N4UFFVRlBWQ3hQUVVGUExFTkJRVU5xUml4TFFVRkxMRXRCUVVzc1VVRkJVU3hGUVVGRk8wbEJRMjVETzBsQlEwRnJSaXhMUVVGTExFTkJRVU5TTEVsQlFVa3NRMEZCUTA4c1QwRkJUeXhEUVVGRGFrWXNTMEZCU3l4RFFVRkRPMFZCUXpkQ0xFTkJRVU1zVFVGQlRTeEpRVUZKTEU5QlFVOXBSaXhQUVVGUExFTkJRVU4wUlN4SlFVRkpMRXRCUVVzc1VVRkJVU3hGUVVGRk8wbEJRM3BETzBsQlEwRXNUVUZCVFdkR0xGRkJRVkVzUjBGQlIxZ3NVMEZCVXl4RFFVRkRReXhQUVVGUExFTkJRVU4wUlN4SlFVRkpMRU5CUVVNN1NVRkRlRU5hTEdWQlFXVXNRMEZCUXpSR0xGRkJRVkVzUTBGQlF6dEpRVU42UWxRc1MwRkJTeXhEUVVGRFVpeEpRVUZKTEVOQlFVTXNSMEZCUjBzc1dVRkJXU3hEUVVGRFF5eFRRVUZUTEVWQlFVVlhMRkZCUVZFc1EwRkJReXhEUVVGRE8wVkJRM0JFTzBWQlJVRXNUMEZCVDFRc1MwRkJTenRCUVVOb1FpSXNJbWxuYm05eVpVeHBjM1FpT2x0ZGZRPT0iLCIndXNlIHN0cmljdCc7XG5cbnZhciBvYmplY3RBc3NpZ24gPSByZXF1aXJlKCdvYmplY3QuYXNzaWduL3BvbHlmaWxsJykoKTtcblxuLy8gY29tcGFyZSBhbmQgaXNCdWZmZXIgdGFrZW4gZnJvbSBodHRwczovL2dpdGh1Yi5jb20vZmVyb3NzL2J1ZmZlci9ibG9iLzY4MGU5ZTVlNDg4ZjIyYWFjMjc1OTlhNTdkYzg0NGE2MzE1OTI4ZGQvaW5kZXguanNcbi8vIG9yaWdpbmFsIG5vdGljZTpcblxuLyohXG4gKiBUaGUgYnVmZmVyIG1vZHVsZSBmcm9tIG5vZGUuanMsIGZvciB0aGUgYnJvd3Nlci5cbiAqXG4gKiBAYXV0aG9yICAgRmVyb3NzIEFib3VraGFkaWplaCA8ZmVyb3NzQGZlcm9zcy5vcmc+IDxodHRwOi8vZmVyb3NzLm9yZz5cbiAqIEBsaWNlbnNlICBNSVRcbiAqL1xuZnVuY3Rpb24gY29tcGFyZShhLCBiKSB7XG4gIGlmIChhID09PSBiKSB7XG4gICAgcmV0dXJuIDA7XG4gIH1cblxuICB2YXIgeCA9IGEubGVuZ3RoO1xuICB2YXIgeSA9IGIubGVuZ3RoO1xuXG4gIGZvciAodmFyIGkgPSAwLCBsZW4gPSBNYXRoLm1pbih4LCB5KTsgaSA8IGxlbjsgKytpKSB7XG4gICAgaWYgKGFbaV0gIT09IGJbaV0pIHtcbiAgICAgIHggPSBhW2ldO1xuICAgICAgeSA9IGJbaV07XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICBpZiAoeCA8IHkpIHtcbiAgICByZXR1cm4gLTE7XG4gIH1cbiAgaWYgKHkgPCB4KSB7XG4gICAgcmV0dXJuIDE7XG4gIH1cbiAgcmV0dXJuIDA7XG59XG5mdW5jdGlvbiBpc0J1ZmZlcihiKSB7XG4gIGlmIChnbG9iYWwuQnVmZmVyICYmIHR5cGVvZiBnbG9iYWwuQnVmZmVyLmlzQnVmZmVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuIGdsb2JhbC5CdWZmZXIuaXNCdWZmZXIoYik7XG4gIH1cbiAgcmV0dXJuICEhKGIgIT0gbnVsbCAmJiBiLl9pc0J1ZmZlcik7XG59XG5cbi8vIGJhc2VkIG9uIG5vZGUgYXNzZXJ0LCBvcmlnaW5hbCBub3RpY2U6XG4vLyBOQjogVGhlIFVSTCB0byB0aGUgQ29tbW9uSlMgc3BlYyBpcyBrZXB0IGp1c3QgZm9yIHRyYWRpdGlvbi5cbi8vICAgICBub2RlLWFzc2VydCBoYXMgZXZvbHZlZCBhIGxvdCBzaW5jZSB0aGVuLCBib3RoIGluIEFQSSBhbmQgYmVoYXZpb3IuXG5cbi8vIGh0dHA6Ly93aWtpLmNvbW1vbmpzLm9yZy93aWtpL1VuaXRfVGVzdGluZy8xLjBcbi8vXG4vLyBUSElTIElTIE5PVCBURVNURUQgTk9SIExJS0VMWSBUTyBXT1JLIE9VVFNJREUgVjghXG4vL1xuLy8gT3JpZ2luYWxseSBmcm9tIG5hcndoYWwuanMgKGh0dHA6Ly9uYXJ3aGFsanMub3JnKVxuLy8gQ29weXJpZ2h0IChjKSAyMDA5IFRob21hcyBSb2JpbnNvbiA8Mjgwbm9ydGguY29tPlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbi8vIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlICdTb2Z0d2FyZScpLCB0b1xuLy8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGVcbi8vIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vclxuLy8gc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbi8vIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW5cbi8vIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAnQVMgSVMnLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4vLyBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbi8vIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuLy8gQVVUSE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU5cbi8vIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT05cbi8vIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG52YXIgdXRpbCA9IHJlcXVpcmUoJ3V0aWwvJyk7XG52YXIgaGFzT3duID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcbnZhciBwU2xpY2UgPSBBcnJheS5wcm90b3R5cGUuc2xpY2U7XG52YXIgZnVuY3Rpb25zSGF2ZU5hbWVzID0gKGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIGZvbygpIHt9Lm5hbWUgPT09ICdmb28nO1xufSgpKTtcbmZ1bmN0aW9uIHBUb1N0cmluZyAob2JqKSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwob2JqKTtcbn1cbmZ1bmN0aW9uIGlzVmlldyhhcnJidWYpIHtcbiAgaWYgKGlzQnVmZmVyKGFycmJ1ZikpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKHR5cGVvZiBnbG9iYWwuQXJyYXlCdWZmZXIgIT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKHR5cGVvZiBBcnJheUJ1ZmZlci5pc1ZpZXcgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gQXJyYXlCdWZmZXIuaXNWaWV3KGFycmJ1Zik7XG4gIH1cbiAgaWYgKCFhcnJidWYpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKGFycmJ1ZiBpbnN0YW5jZW9mIERhdGFWaWV3KSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgaWYgKGFycmJ1Zi5idWZmZXIgJiYgYXJyYnVmLmJ1ZmZlciBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuLy8gMS4gVGhlIGFzc2VydCBtb2R1bGUgcHJvdmlkZXMgZnVuY3Rpb25zIHRoYXQgdGhyb3dcbi8vIEFzc2VydGlvbkVycm9yJ3Mgd2hlbiBwYXJ0aWN1bGFyIGNvbmRpdGlvbnMgYXJlIG5vdCBtZXQuIFRoZVxuLy8gYXNzZXJ0IG1vZHVsZSBtdXN0IGNvbmZvcm0gdG8gdGhlIGZvbGxvd2luZyBpbnRlcmZhY2UuXG5cbnZhciBhc3NlcnQgPSBtb2R1bGUuZXhwb3J0cyA9IG9rO1xuXG4vLyAyLiBUaGUgQXNzZXJ0aW9uRXJyb3IgaXMgZGVmaW5lZCBpbiBhc3NlcnQuXG4vLyBuZXcgYXNzZXJ0LkFzc2VydGlvbkVycm9yKHsgbWVzc2FnZTogbWVzc2FnZSxcbi8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY3R1YWw6IGFjdHVhbCxcbi8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHBlY3RlZDogZXhwZWN0ZWQgfSlcblxudmFyIHJlZ2V4ID0gL1xccypmdW5jdGlvblxccysoW15cXChcXHNdKilcXHMqLztcbi8vIGJhc2VkIG9uIGh0dHBzOi8vZ2l0aHViLmNvbS9samhhcmIvZnVuY3Rpb24ucHJvdG90eXBlLm5hbWUvYmxvYi9hZGVlZWVjOGJmY2M2MDY4YjE4N2Q3ZDlmYjNkNWJiMWQzYTMwODk5L2ltcGxlbWVudGF0aW9uLmpzXG5mdW5jdGlvbiBnZXROYW1lKGZ1bmMpIHtcbiAgaWYgKCF1dGlsLmlzRnVuY3Rpb24oZnVuYykpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKGZ1bmN0aW9uc0hhdmVOYW1lcykge1xuICAgIHJldHVybiBmdW5jLm5hbWU7XG4gIH1cbiAgdmFyIHN0ciA9IGZ1bmMudG9TdHJpbmcoKTtcbiAgdmFyIG1hdGNoID0gc3RyLm1hdGNoKHJlZ2V4KTtcbiAgcmV0dXJuIG1hdGNoICYmIG1hdGNoWzFdO1xufVxuYXNzZXJ0LkFzc2VydGlvbkVycm9yID0gZnVuY3Rpb24gQXNzZXJ0aW9uRXJyb3Iob3B0aW9ucykge1xuICB0aGlzLm5hbWUgPSAnQXNzZXJ0aW9uRXJyb3InO1xuICB0aGlzLmFjdHVhbCA9IG9wdGlvbnMuYWN0dWFsO1xuICB0aGlzLmV4cGVjdGVkID0gb3B0aW9ucy5leHBlY3RlZDtcbiAgdGhpcy5vcGVyYXRvciA9IG9wdGlvbnMub3BlcmF0b3I7XG4gIGlmIChvcHRpb25zLm1lc3NhZ2UpIHtcbiAgICB0aGlzLm1lc3NhZ2UgPSBvcHRpb25zLm1lc3NhZ2U7XG4gICAgdGhpcy5nZW5lcmF0ZWRNZXNzYWdlID0gZmFsc2U7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5tZXNzYWdlID0gZ2V0TWVzc2FnZSh0aGlzKTtcbiAgICB0aGlzLmdlbmVyYXRlZE1lc3NhZ2UgPSB0cnVlO1xuICB9XG4gIHZhciBzdGFja1N0YXJ0RnVuY3Rpb24gPSBvcHRpb25zLnN0YWNrU3RhcnRGdW5jdGlvbiB8fCBmYWlsO1xuICBpZiAoRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UpIHtcbiAgICBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSh0aGlzLCBzdGFja1N0YXJ0RnVuY3Rpb24pO1xuICB9IGVsc2Uge1xuICAgIC8vIG5vbiB2OCBicm93c2VycyBzbyB3ZSBjYW4gaGF2ZSBhIHN0YWNrdHJhY2VcbiAgICB2YXIgZXJyID0gbmV3IEVycm9yKCk7XG4gICAgaWYgKGVyci5zdGFjaykge1xuICAgICAgdmFyIG91dCA9IGVyci5zdGFjaztcblxuICAgICAgLy8gdHJ5IHRvIHN0cmlwIHVzZWxlc3MgZnJhbWVzXG4gICAgICB2YXIgZm5fbmFtZSA9IGdldE5hbWUoc3RhY2tTdGFydEZ1bmN0aW9uKTtcbiAgICAgIHZhciBpZHggPSBvdXQuaW5kZXhPZignXFxuJyArIGZuX25hbWUpO1xuICAgICAgaWYgKGlkeCA+PSAwKSB7XG4gICAgICAgIC8vIG9uY2Ugd2UgaGF2ZSBsb2NhdGVkIHRoZSBmdW5jdGlvbiBmcmFtZVxuICAgICAgICAvLyB3ZSBuZWVkIHRvIHN0cmlwIG91dCBldmVyeXRoaW5nIGJlZm9yZSBpdCAoYW5kIGl0cyBsaW5lKVxuICAgICAgICB2YXIgbmV4dF9saW5lID0gb3V0LmluZGV4T2YoJ1xcbicsIGlkeCArIDEpO1xuICAgICAgICBvdXQgPSBvdXQuc3Vic3RyaW5nKG5leHRfbGluZSArIDEpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLnN0YWNrID0gb3V0O1xuICAgIH1cbiAgfVxufTtcblxuLy8gYXNzZXJ0LkFzc2VydGlvbkVycm9yIGluc3RhbmNlb2YgRXJyb3JcbnV0aWwuaW5oZXJpdHMoYXNzZXJ0LkFzc2VydGlvbkVycm9yLCBFcnJvcik7XG5cbmZ1bmN0aW9uIHRydW5jYXRlKHMsIG4pIHtcbiAgaWYgKHR5cGVvZiBzID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBzLmxlbmd0aCA8IG4gPyBzIDogcy5zbGljZSgwLCBuKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gcztcbiAgfVxufVxuZnVuY3Rpb24gaW5zcGVjdChzb21ldGhpbmcpIHtcbiAgaWYgKGZ1bmN0aW9uc0hhdmVOYW1lcyB8fCAhdXRpbC5pc0Z1bmN0aW9uKHNvbWV0aGluZykpIHtcbiAgICByZXR1cm4gdXRpbC5pbnNwZWN0KHNvbWV0aGluZyk7XG4gIH1cbiAgdmFyIHJhd25hbWUgPSBnZXROYW1lKHNvbWV0aGluZyk7XG4gIHZhciBuYW1lID0gcmF3bmFtZSA/ICc6ICcgKyByYXduYW1lIDogJyc7XG4gIHJldHVybiAnW0Z1bmN0aW9uJyArICBuYW1lICsgJ10nO1xufVxuZnVuY3Rpb24gZ2V0TWVzc2FnZShzZWxmKSB7XG4gIHJldHVybiB0cnVuY2F0ZShpbnNwZWN0KHNlbGYuYWN0dWFsKSwgMTI4KSArICcgJyArXG4gICAgICAgICBzZWxmLm9wZXJhdG9yICsgJyAnICtcbiAgICAgICAgIHRydW5jYXRlKGluc3BlY3Qoc2VsZi5leHBlY3RlZCksIDEyOCk7XG59XG5cbi8vIEF0IHByZXNlbnQgb25seSB0aGUgdGhyZWUga2V5cyBtZW50aW9uZWQgYWJvdmUgYXJlIHVzZWQgYW5kXG4vLyB1bmRlcnN0b29kIGJ5IHRoZSBzcGVjLiBJbXBsZW1lbnRhdGlvbnMgb3Igc3ViIG1vZHVsZXMgY2FuIHBhc3Ncbi8vIG90aGVyIGtleXMgdG8gdGhlIEFzc2VydGlvbkVycm9yJ3MgY29uc3RydWN0b3IgLSB0aGV5IHdpbGwgYmVcbi8vIGlnbm9yZWQuXG5cbi8vIDMuIEFsbCBvZiB0aGUgZm9sbG93aW5nIGZ1bmN0aW9ucyBtdXN0IHRocm93IGFuIEFzc2VydGlvbkVycm9yXG4vLyB3aGVuIGEgY29ycmVzcG9uZGluZyBjb25kaXRpb24gaXMgbm90IG1ldCwgd2l0aCBhIG1lc3NhZ2UgdGhhdFxuLy8gbWF5IGJlIHVuZGVmaW5lZCBpZiBub3QgcHJvdmlkZWQuICBBbGwgYXNzZXJ0aW9uIG1ldGhvZHMgcHJvdmlkZVxuLy8gYm90aCB0aGUgYWN0dWFsIGFuZCBleHBlY3RlZCB2YWx1ZXMgdG8gdGhlIGFzc2VydGlvbiBlcnJvciBmb3Jcbi8vIGRpc3BsYXkgcHVycG9zZXMuXG5cbmZ1bmN0aW9uIGZhaWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSwgb3BlcmF0b3IsIHN0YWNrU3RhcnRGdW5jdGlvbikge1xuICB0aHJvdyBuZXcgYXNzZXJ0LkFzc2VydGlvbkVycm9yKHtcbiAgICBtZXNzYWdlOiBtZXNzYWdlLFxuICAgIGFjdHVhbDogYWN0dWFsLFxuICAgIGV4cGVjdGVkOiBleHBlY3RlZCxcbiAgICBvcGVyYXRvcjogb3BlcmF0b3IsXG4gICAgc3RhY2tTdGFydEZ1bmN0aW9uOiBzdGFja1N0YXJ0RnVuY3Rpb25cbiAgfSk7XG59XG5cbi8vIEVYVEVOU0lPTiEgYWxsb3dzIGZvciB3ZWxsIGJlaGF2ZWQgZXJyb3JzIGRlZmluZWQgZWxzZXdoZXJlLlxuYXNzZXJ0LmZhaWwgPSBmYWlsO1xuXG4vLyA0LiBQdXJlIGFzc2VydGlvbiB0ZXN0cyB3aGV0aGVyIGEgdmFsdWUgaXMgdHJ1dGh5LCBhcyBkZXRlcm1pbmVkXG4vLyBieSAhIWd1YXJkLlxuLy8gYXNzZXJ0Lm9rKGd1YXJkLCBtZXNzYWdlX29wdCk7XG4vLyBUaGlzIHN0YXRlbWVudCBpcyBlcXVpdmFsZW50IHRvIGFzc2VydC5lcXVhbCh0cnVlLCAhIWd1YXJkLFxuLy8gbWVzc2FnZV9vcHQpOy4gVG8gdGVzdCBzdHJpY3RseSBmb3IgdGhlIHZhbHVlIHRydWUsIHVzZVxuLy8gYXNzZXJ0LnN0cmljdEVxdWFsKHRydWUsIGd1YXJkLCBtZXNzYWdlX29wdCk7LlxuXG5mdW5jdGlvbiBvayh2YWx1ZSwgbWVzc2FnZSkge1xuICBpZiAoIXZhbHVlKSBmYWlsKHZhbHVlLCB0cnVlLCBtZXNzYWdlLCAnPT0nLCBhc3NlcnQub2spO1xufVxuYXNzZXJ0Lm9rID0gb2s7XG5cbi8vIDUuIFRoZSBlcXVhbGl0eSBhc3NlcnRpb24gdGVzdHMgc2hhbGxvdywgY29lcmNpdmUgZXF1YWxpdHkgd2l0aFxuLy8gPT0uXG4vLyBhc3NlcnQuZXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZV9vcHQpO1xuXG5hc3NlcnQuZXF1YWwgPSBmdW5jdGlvbiBlcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlKSB7XG4gIGlmIChhY3R1YWwgIT0gZXhwZWN0ZWQpIGZhaWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSwgJz09JywgYXNzZXJ0LmVxdWFsKTtcbn07XG5cbi8vIDYuIFRoZSBub24tZXF1YWxpdHkgYXNzZXJ0aW9uIHRlc3RzIGZvciB3aGV0aGVyIHR3byBvYmplY3RzIGFyZSBub3QgZXF1YWxcbi8vIHdpdGggIT0gYXNzZXJ0Lm5vdEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2Vfb3B0KTtcblxuYXNzZXJ0Lm5vdEVxdWFsID0gZnVuY3Rpb24gbm90RXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuICBpZiAoYWN0dWFsID09IGV4cGVjdGVkKSB7XG4gICAgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCAnIT0nLCBhc3NlcnQubm90RXF1YWwpO1xuICB9XG59O1xuXG4vLyA3LiBUaGUgZXF1aXZhbGVuY2UgYXNzZXJ0aW9uIHRlc3RzIGEgZGVlcCBlcXVhbGl0eSByZWxhdGlvbi5cbi8vIGFzc2VydC5kZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZV9vcHQpO1xuXG5hc3NlcnQuZGVlcEVxdWFsID0gZnVuY3Rpb24gZGVlcEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UpIHtcbiAgaWYgKCFfZGVlcEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIGZhbHNlKSkge1xuICAgIGZhaWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSwgJ2RlZXBFcXVhbCcsIGFzc2VydC5kZWVwRXF1YWwpO1xuICB9XG59O1xuXG5hc3NlcnQuZGVlcFN0cmljdEVxdWFsID0gZnVuY3Rpb24gZGVlcFN0cmljdEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UpIHtcbiAgaWYgKCFfZGVlcEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIHRydWUpKSB7XG4gICAgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCAnZGVlcFN0cmljdEVxdWFsJywgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbCk7XG4gIH1cbn07XG5cbmZ1bmN0aW9uIF9kZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgc3RyaWN0LCBtZW1vcykge1xuICAvLyA3LjEuIEFsbCBpZGVudGljYWwgdmFsdWVzIGFyZSBlcXVpdmFsZW50LCBhcyBkZXRlcm1pbmVkIGJ5ID09PS5cbiAgaWYgKGFjdHVhbCA9PT0gZXhwZWN0ZWQpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBlbHNlIGlmIChpc0J1ZmZlcihhY3R1YWwpICYmIGlzQnVmZmVyKGV4cGVjdGVkKSkge1xuICAgIHJldHVybiBjb21wYXJlKGFjdHVhbCwgZXhwZWN0ZWQpID09PSAwO1xuXG4gIC8vIDcuMi4gSWYgdGhlIGV4cGVjdGVkIHZhbHVlIGlzIGEgRGF0ZSBvYmplY3QsIHRoZSBhY3R1YWwgdmFsdWUgaXNcbiAgLy8gZXF1aXZhbGVudCBpZiBpdCBpcyBhbHNvIGEgRGF0ZSBvYmplY3QgdGhhdCByZWZlcnMgdG8gdGhlIHNhbWUgdGltZS5cbiAgfSBlbHNlIGlmICh1dGlsLmlzRGF0ZShhY3R1YWwpICYmIHV0aWwuaXNEYXRlKGV4cGVjdGVkKSkge1xuICAgIHJldHVybiBhY3R1YWwuZ2V0VGltZSgpID09PSBleHBlY3RlZC5nZXRUaW1lKCk7XG5cbiAgLy8gNy4zIElmIHRoZSBleHBlY3RlZCB2YWx1ZSBpcyBhIFJlZ0V4cCBvYmplY3QsIHRoZSBhY3R1YWwgdmFsdWUgaXNcbiAgLy8gZXF1aXZhbGVudCBpZiBpdCBpcyBhbHNvIGEgUmVnRXhwIG9iamVjdCB3aXRoIHRoZSBzYW1lIHNvdXJjZSBhbmRcbiAgLy8gcHJvcGVydGllcyAoYGdsb2JhbGAsIGBtdWx0aWxpbmVgLCBgbGFzdEluZGV4YCwgYGlnbm9yZUNhc2VgKS5cbiAgfSBlbHNlIGlmICh1dGlsLmlzUmVnRXhwKGFjdHVhbCkgJiYgdXRpbC5pc1JlZ0V4cChleHBlY3RlZCkpIHtcbiAgICByZXR1cm4gYWN0dWFsLnNvdXJjZSA9PT0gZXhwZWN0ZWQuc291cmNlICYmXG4gICAgICAgICAgIGFjdHVhbC5nbG9iYWwgPT09IGV4cGVjdGVkLmdsb2JhbCAmJlxuICAgICAgICAgICBhY3R1YWwubXVsdGlsaW5lID09PSBleHBlY3RlZC5tdWx0aWxpbmUgJiZcbiAgICAgICAgICAgYWN0dWFsLmxhc3RJbmRleCA9PT0gZXhwZWN0ZWQubGFzdEluZGV4ICYmXG4gICAgICAgICAgIGFjdHVhbC5pZ25vcmVDYXNlID09PSBleHBlY3RlZC5pZ25vcmVDYXNlO1xuXG4gIC8vIDcuNC4gT3RoZXIgcGFpcnMgdGhhdCBkbyBub3QgYm90aCBwYXNzIHR5cGVvZiB2YWx1ZSA9PSAnb2JqZWN0JyxcbiAgLy8gZXF1aXZhbGVuY2UgaXMgZGV0ZXJtaW5lZCBieSA9PS5cbiAgfSBlbHNlIGlmICgoYWN0dWFsID09PSBudWxsIHx8IHR5cGVvZiBhY3R1YWwgIT09ICdvYmplY3QnKSAmJlxuICAgICAgICAgICAgIChleHBlY3RlZCA9PT0gbnVsbCB8fCB0eXBlb2YgZXhwZWN0ZWQgIT09ICdvYmplY3QnKSkge1xuICAgIHJldHVybiBzdHJpY3QgPyBhY3R1YWwgPT09IGV4cGVjdGVkIDogYWN0dWFsID09IGV4cGVjdGVkO1xuXG4gIC8vIElmIGJvdGggdmFsdWVzIGFyZSBpbnN0YW5jZXMgb2YgdHlwZWQgYXJyYXlzLCB3cmFwIHRoZWlyIHVuZGVybHlpbmdcbiAgLy8gQXJyYXlCdWZmZXJzIGluIGEgQnVmZmVyIGVhY2ggdG8gaW5jcmVhc2UgcGVyZm9ybWFuY2VcbiAgLy8gVGhpcyBvcHRpbWl6YXRpb24gcmVxdWlyZXMgdGhlIGFycmF5cyB0byBoYXZlIHRoZSBzYW1lIHR5cGUgYXMgY2hlY2tlZCBieVxuICAvLyBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nIChha2EgcFRvU3RyaW5nKS4gTmV2ZXIgcGVyZm9ybSBiaW5hcnlcbiAgLy8gY29tcGFyaXNvbnMgZm9yIEZsb2F0KkFycmF5cywgdGhvdWdoLCBzaW5jZSBlLmcuICswID09PSAtMCBidXQgdGhlaXJcbiAgLy8gYml0IHBhdHRlcm5zIGFyZSBub3QgaWRlbnRpY2FsLlxuICB9IGVsc2UgaWYgKGlzVmlldyhhY3R1YWwpICYmIGlzVmlldyhleHBlY3RlZCkgJiZcbiAgICAgICAgICAgICBwVG9TdHJpbmcoYWN0dWFsKSA9PT0gcFRvU3RyaW5nKGV4cGVjdGVkKSAmJlxuICAgICAgICAgICAgICEoYWN0dWFsIGluc3RhbmNlb2YgRmxvYXQzMkFycmF5IHx8XG4gICAgICAgICAgICAgICBhY3R1YWwgaW5zdGFuY2VvZiBGbG9hdDY0QXJyYXkpKSB7XG4gICAgcmV0dXJuIGNvbXBhcmUobmV3IFVpbnQ4QXJyYXkoYWN0dWFsLmJ1ZmZlciksXG4gICAgICAgICAgICAgICAgICAgbmV3IFVpbnQ4QXJyYXkoZXhwZWN0ZWQuYnVmZmVyKSkgPT09IDA7XG5cbiAgLy8gNy41IEZvciBhbGwgb3RoZXIgT2JqZWN0IHBhaXJzLCBpbmNsdWRpbmcgQXJyYXkgb2JqZWN0cywgZXF1aXZhbGVuY2UgaXNcbiAgLy8gZGV0ZXJtaW5lZCBieSBoYXZpbmcgdGhlIHNhbWUgbnVtYmVyIG9mIG93bmVkIHByb3BlcnRpZXMgKGFzIHZlcmlmaWVkXG4gIC8vIHdpdGggT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKSwgdGhlIHNhbWUgc2V0IG9mIGtleXNcbiAgLy8gKGFsdGhvdWdoIG5vdCBuZWNlc3NhcmlseSB0aGUgc2FtZSBvcmRlciksIGVxdWl2YWxlbnQgdmFsdWVzIGZvciBldmVyeVxuICAvLyBjb3JyZXNwb25kaW5nIGtleSwgYW5kIGFuIGlkZW50aWNhbCAncHJvdG90eXBlJyBwcm9wZXJ0eS4gTm90ZTogdGhpc1xuICAvLyBhY2NvdW50cyBmb3IgYm90aCBuYW1lZCBhbmQgaW5kZXhlZCBwcm9wZXJ0aWVzIG9uIEFycmF5cy5cbiAgfSBlbHNlIGlmIChpc0J1ZmZlcihhY3R1YWwpICE9PSBpc0J1ZmZlcihleHBlY3RlZCkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH0gZWxzZSB7XG4gICAgbWVtb3MgPSBtZW1vcyB8fCB7YWN0dWFsOiBbXSwgZXhwZWN0ZWQ6IFtdfTtcblxuICAgIHZhciBhY3R1YWxJbmRleCA9IG1lbW9zLmFjdHVhbC5pbmRleE9mKGFjdHVhbCk7XG4gICAgaWYgKGFjdHVhbEluZGV4ICE9PSAtMSkge1xuICAgICAgaWYgKGFjdHVhbEluZGV4ID09PSBtZW1vcy5leHBlY3RlZC5pbmRleE9mKGV4cGVjdGVkKSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBtZW1vcy5hY3R1YWwucHVzaChhY3R1YWwpO1xuICAgIG1lbW9zLmV4cGVjdGVkLnB1c2goZXhwZWN0ZWQpO1xuXG4gICAgcmV0dXJuIG9iakVxdWl2KGFjdHVhbCwgZXhwZWN0ZWQsIHN0cmljdCwgbWVtb3MpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGlzQXJndW1lbnRzKG9iamVjdCkge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG9iamVjdCkgPT0gJ1tvYmplY3QgQXJndW1lbnRzXSc7XG59XG5cbmZ1bmN0aW9uIG9iakVxdWl2KGEsIGIsIHN0cmljdCwgYWN0dWFsVmlzaXRlZE9iamVjdHMpIHtcbiAgaWYgKGEgPT09IG51bGwgfHwgYSA9PT0gdW5kZWZpbmVkIHx8IGIgPT09IG51bGwgfHwgYiA9PT0gdW5kZWZpbmVkKVxuICAgIHJldHVybiBmYWxzZTtcbiAgLy8gaWYgb25lIGlzIGEgcHJpbWl0aXZlLCB0aGUgb3RoZXIgbXVzdCBiZSBzYW1lXG4gIGlmICh1dGlsLmlzUHJpbWl0aXZlKGEpIHx8IHV0aWwuaXNQcmltaXRpdmUoYikpXG4gICAgcmV0dXJuIGEgPT09IGI7XG4gIGlmIChzdHJpY3QgJiYgT2JqZWN0LmdldFByb3RvdHlwZU9mKGEpICE9PSBPYmplY3QuZ2V0UHJvdG90eXBlT2YoYikpXG4gICAgcmV0dXJuIGZhbHNlO1xuICB2YXIgYUlzQXJncyA9IGlzQXJndW1lbnRzKGEpO1xuICB2YXIgYklzQXJncyA9IGlzQXJndW1lbnRzKGIpO1xuICBpZiAoKGFJc0FyZ3MgJiYgIWJJc0FyZ3MpIHx8ICghYUlzQXJncyAmJiBiSXNBcmdzKSlcbiAgICByZXR1cm4gZmFsc2U7XG4gIGlmIChhSXNBcmdzKSB7XG4gICAgYSA9IHBTbGljZS5jYWxsKGEpO1xuICAgIGIgPSBwU2xpY2UuY2FsbChiKTtcbiAgICByZXR1cm4gX2RlZXBFcXVhbChhLCBiLCBzdHJpY3QpO1xuICB9XG4gIHZhciBrYSA9IG9iamVjdEtleXMoYSk7XG4gIHZhciBrYiA9IG9iamVjdEtleXMoYik7XG4gIHZhciBrZXksIGk7XG4gIC8vIGhhdmluZyB0aGUgc2FtZSBudW1iZXIgb2Ygb3duZWQgcHJvcGVydGllcyAoa2V5cyBpbmNvcnBvcmF0ZXNcbiAgLy8gaGFzT3duUHJvcGVydHkpXG4gIGlmIChrYS5sZW5ndGggIT09IGtiLmxlbmd0aClcbiAgICByZXR1cm4gZmFsc2U7XG4gIC8vdGhlIHNhbWUgc2V0IG9mIGtleXMgKGFsdGhvdWdoIG5vdCBuZWNlc3NhcmlseSB0aGUgc2FtZSBvcmRlciksXG4gIGthLnNvcnQoKTtcbiAga2Iuc29ydCgpO1xuICAvL35+fmNoZWFwIGtleSB0ZXN0XG4gIGZvciAoaSA9IGthLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgaWYgKGthW2ldICE9PSBrYltpXSlcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICAvL2VxdWl2YWxlbnQgdmFsdWVzIGZvciBldmVyeSBjb3JyZXNwb25kaW5nIGtleSwgYW5kXG4gIC8vfn5+cG9zc2libHkgZXhwZW5zaXZlIGRlZXAgdGVzdFxuICBmb3IgKGkgPSBrYS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgIGtleSA9IGthW2ldO1xuICAgIGlmICghX2RlZXBFcXVhbChhW2tleV0sIGJba2V5XSwgc3RyaWN0LCBhY3R1YWxWaXNpdGVkT2JqZWN0cykpXG4gICAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5cbi8vIDguIFRoZSBub24tZXF1aXZhbGVuY2UgYXNzZXJ0aW9uIHRlc3RzIGZvciBhbnkgZGVlcCBpbmVxdWFsaXR5LlxuLy8gYXNzZXJ0Lm5vdERlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlX29wdCk7XG5cbmFzc2VydC5ub3REZWVwRXF1YWwgPSBmdW5jdGlvbiBub3REZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuICBpZiAoX2RlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBmYWxzZSkpIHtcbiAgICBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UsICdub3REZWVwRXF1YWwnLCBhc3NlcnQubm90RGVlcEVxdWFsKTtcbiAgfVxufTtcblxuYXNzZXJ0Lm5vdERlZXBTdHJpY3RFcXVhbCA9IG5vdERlZXBTdHJpY3RFcXVhbDtcbmZ1bmN0aW9uIG5vdERlZXBTdHJpY3RFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlKSB7XG4gIGlmIChfZGVlcEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIHRydWUpKSB7XG4gICAgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCAnbm90RGVlcFN0cmljdEVxdWFsJywgbm90RGVlcFN0cmljdEVxdWFsKTtcbiAgfVxufVxuXG5cbi8vIDkuIFRoZSBzdHJpY3QgZXF1YWxpdHkgYXNzZXJ0aW9uIHRlc3RzIHN0cmljdCBlcXVhbGl0eSwgYXMgZGV0ZXJtaW5lZCBieSA9PT0uXG4vLyBhc3NlcnQuc3RyaWN0RXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZV9vcHQpO1xuXG5hc3NlcnQuc3RyaWN0RXF1YWwgPSBmdW5jdGlvbiBzdHJpY3RFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlKSB7XG4gIGlmIChhY3R1YWwgIT09IGV4cGVjdGVkKSB7XG4gICAgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCAnPT09JywgYXNzZXJ0LnN0cmljdEVxdWFsKTtcbiAgfVxufTtcblxuLy8gMTAuIFRoZSBzdHJpY3Qgbm9uLWVxdWFsaXR5IGFzc2VydGlvbiB0ZXN0cyBmb3Igc3RyaWN0IGluZXF1YWxpdHksIGFzXG4vLyBkZXRlcm1pbmVkIGJ5ICE9PS4gIGFzc2VydC5ub3RTdHJpY3RFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlX29wdCk7XG5cbmFzc2VydC5ub3RTdHJpY3RFcXVhbCA9IGZ1bmN0aW9uIG5vdFN0cmljdEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UpIHtcbiAgaWYgKGFjdHVhbCA9PT0gZXhwZWN0ZWQpIHtcbiAgICBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UsICchPT0nLCBhc3NlcnQubm90U3RyaWN0RXF1YWwpO1xuICB9XG59O1xuXG5mdW5jdGlvbiBleHBlY3RlZEV4Y2VwdGlvbihhY3R1YWwsIGV4cGVjdGVkKSB7XG4gIGlmICghYWN0dWFsIHx8ICFleHBlY3RlZCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGlmIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoZXhwZWN0ZWQpID09ICdbb2JqZWN0IFJlZ0V4cF0nKSB7XG4gICAgcmV0dXJuIGV4cGVjdGVkLnRlc3QoYWN0dWFsKTtcbiAgfVxuXG4gIHRyeSB7XG4gICAgaWYgKGFjdHVhbCBpbnN0YW5jZW9mIGV4cGVjdGVkKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICAvLyBJZ25vcmUuICBUaGUgaW5zdGFuY2VvZiBjaGVjayBkb2Vzbid0IHdvcmsgZm9yIGFycm93IGZ1bmN0aW9ucy5cbiAgfVxuXG4gIGlmIChFcnJvci5pc1Byb3RvdHlwZU9mKGV4cGVjdGVkKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiBleHBlY3RlZC5jYWxsKHt9LCBhY3R1YWwpID09PSB0cnVlO1xufVxuXG5mdW5jdGlvbiBfdHJ5QmxvY2soYmxvY2spIHtcbiAgdmFyIGVycm9yO1xuICB0cnkge1xuICAgIGJsb2NrKCk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBlcnJvciA9IGU7XG4gIH1cbiAgcmV0dXJuIGVycm9yO1xufVxuXG5mdW5jdGlvbiBfdGhyb3dzKHNob3VsZFRocm93LCBibG9jaywgZXhwZWN0ZWQsIG1lc3NhZ2UpIHtcbiAgdmFyIGFjdHVhbDtcblxuICBpZiAodHlwZW9mIGJsb2NrICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJibG9ja1wiIGFyZ3VtZW50IG11c3QgYmUgYSBmdW5jdGlvbicpO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBleHBlY3RlZCA9PT0gJ3N0cmluZycpIHtcbiAgICBtZXNzYWdlID0gZXhwZWN0ZWQ7XG4gICAgZXhwZWN0ZWQgPSBudWxsO1xuICB9XG5cbiAgYWN0dWFsID0gX3RyeUJsb2NrKGJsb2NrKTtcblxuICBtZXNzYWdlID0gKGV4cGVjdGVkICYmIGV4cGVjdGVkLm5hbWUgPyAnICgnICsgZXhwZWN0ZWQubmFtZSArICcpLicgOiAnLicpICtcbiAgICAgICAgICAgIChtZXNzYWdlID8gJyAnICsgbWVzc2FnZSA6ICcuJyk7XG5cbiAgaWYgKHNob3VsZFRocm93ICYmICFhY3R1YWwpIHtcbiAgICBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsICdNaXNzaW5nIGV4cGVjdGVkIGV4Y2VwdGlvbicgKyBtZXNzYWdlKTtcbiAgfVxuXG4gIHZhciB1c2VyUHJvdmlkZWRNZXNzYWdlID0gdHlwZW9mIG1lc3NhZ2UgPT09ICdzdHJpbmcnO1xuICB2YXIgaXNVbndhbnRlZEV4Y2VwdGlvbiA9ICFzaG91bGRUaHJvdyAmJiB1dGlsLmlzRXJyb3IoYWN0dWFsKTtcbiAgdmFyIGlzVW5leHBlY3RlZEV4Y2VwdGlvbiA9ICFzaG91bGRUaHJvdyAmJiBhY3R1YWwgJiYgIWV4cGVjdGVkO1xuXG4gIGlmICgoaXNVbndhbnRlZEV4Y2VwdGlvbiAmJlxuICAgICAgdXNlclByb3ZpZGVkTWVzc2FnZSAmJlxuICAgICAgZXhwZWN0ZWRFeGNlcHRpb24oYWN0dWFsLCBleHBlY3RlZCkpIHx8XG4gICAgICBpc1VuZXhwZWN0ZWRFeGNlcHRpb24pIHtcbiAgICBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsICdHb3QgdW53YW50ZWQgZXhjZXB0aW9uJyArIG1lc3NhZ2UpO1xuICB9XG5cbiAgaWYgKChzaG91bGRUaHJvdyAmJiBhY3R1YWwgJiYgZXhwZWN0ZWQgJiZcbiAgICAgICFleHBlY3RlZEV4Y2VwdGlvbihhY3R1YWwsIGV4cGVjdGVkKSkgfHwgKCFzaG91bGRUaHJvdyAmJiBhY3R1YWwpKSB7XG4gICAgdGhyb3cgYWN0dWFsO1xuICB9XG59XG5cbi8vIDExLiBFeHBlY3RlZCB0byB0aHJvdyBhbiBlcnJvcjpcbi8vIGFzc2VydC50aHJvd3MoYmxvY2ssIEVycm9yX29wdCwgbWVzc2FnZV9vcHQpO1xuXG5hc3NlcnQudGhyb3dzID0gZnVuY3Rpb24oYmxvY2ssIC8qb3B0aW9uYWwqL2Vycm9yLCAvKm9wdGlvbmFsKi9tZXNzYWdlKSB7XG4gIF90aHJvd3ModHJ1ZSwgYmxvY2ssIGVycm9yLCBtZXNzYWdlKTtcbn07XG5cbi8vIEVYVEVOU0lPTiEgVGhpcyBpcyBhbm5veWluZyB0byB3cml0ZSBvdXRzaWRlIHRoaXMgbW9kdWxlLlxuYXNzZXJ0LmRvZXNOb3RUaHJvdyA9IGZ1bmN0aW9uKGJsb2NrLCAvKm9wdGlvbmFsKi9lcnJvciwgLypvcHRpb25hbCovbWVzc2FnZSkge1xuICBfdGhyb3dzKGZhbHNlLCBibG9jaywgZXJyb3IsIG1lc3NhZ2UpO1xufTtcblxuYXNzZXJ0LmlmRXJyb3IgPSBmdW5jdGlvbihlcnIpIHsgaWYgKGVycikgdGhyb3cgZXJyOyB9O1xuXG4vLyBFeHBvc2UgYSBzdHJpY3Qgb25seSB2YXJpYW50IG9mIGFzc2VydFxuZnVuY3Rpb24gc3RyaWN0KHZhbHVlLCBtZXNzYWdlKSB7XG4gIGlmICghdmFsdWUpIGZhaWwodmFsdWUsIHRydWUsIG1lc3NhZ2UsICc9PScsIHN0cmljdCk7XG59XG5hc3NlcnQuc3RyaWN0ID0gb2JqZWN0QXNzaWduKHN0cmljdCwgYXNzZXJ0LCB7XG4gIGVxdWFsOiBhc3NlcnQuc3RyaWN0RXF1YWwsXG4gIGRlZXBFcXVhbDogYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbCxcbiAgbm90RXF1YWw6IGFzc2VydC5ub3RTdHJpY3RFcXVhbCxcbiAgbm90RGVlcEVxdWFsOiBhc3NlcnQubm90RGVlcFN0cmljdEVxdWFsXG59KTtcbmFzc2VydC5zdHJpY3Quc3RyaWN0ID0gYXNzZXJ0LnN0cmljdDtcblxudmFyIG9iamVjdEtleXMgPSBPYmplY3Qua2V5cyB8fCBmdW5jdGlvbiAob2JqKSB7XG4gIHZhciBrZXlzID0gW107XG4gIGZvciAodmFyIGtleSBpbiBvYmopIHtcbiAgICBpZiAoaGFzT3duLmNhbGwob2JqLCBrZXkpKSBrZXlzLnB1c2goa2V5KTtcbiAgfVxuICByZXR1cm4ga2V5cztcbn07XG4iLCJpZiAodHlwZW9mIE9iamVjdC5jcmVhdGUgPT09ICdmdW5jdGlvbicpIHtcbiAgLy8gaW1wbGVtZW50YXRpb24gZnJvbSBzdGFuZGFyZCBub2RlLmpzICd1dGlsJyBtb2R1bGVcbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpbmhlcml0cyhjdG9yLCBzdXBlckN0b3IpIHtcbiAgICBjdG9yLnN1cGVyXyA9IHN1cGVyQ3RvclxuICAgIGN0b3IucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckN0b3IucHJvdG90eXBlLCB7XG4gICAgICBjb25zdHJ1Y3Rvcjoge1xuICAgICAgICB2YWx1ZTogY3RvcixcbiAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICAgIH1cbiAgICB9KTtcbiAgfTtcbn0gZWxzZSB7XG4gIC8vIG9sZCBzY2hvb2wgc2hpbSBmb3Igb2xkIGJyb3dzZXJzXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICB2YXIgVGVtcEN0b3IgPSBmdW5jdGlvbiAoKSB7fVxuICAgIFRlbXBDdG9yLnByb3RvdHlwZSA9IHN1cGVyQ3Rvci5wcm90b3R5cGVcbiAgICBjdG9yLnByb3RvdHlwZSA9IG5ldyBUZW1wQ3RvcigpXG4gICAgY3Rvci5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBjdG9yXG4gIH1cbn1cbiIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaXNCdWZmZXIoYXJnKSB7XG4gIHJldHVybiBhcmcgJiYgdHlwZW9mIGFyZyA9PT0gJ29iamVjdCdcbiAgICAmJiB0eXBlb2YgYXJnLmNvcHkgPT09ICdmdW5jdGlvbidcbiAgICAmJiB0eXBlb2YgYXJnLmZpbGwgPT09ICdmdW5jdGlvbidcbiAgICAmJiB0eXBlb2YgYXJnLnJlYWRVSW50OCA9PT0gJ2Z1bmN0aW9uJztcbn0iLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxudmFyIGZvcm1hdFJlZ0V4cCA9IC8lW3NkaiVdL2c7XG5leHBvcnRzLmZvcm1hdCA9IGZ1bmN0aW9uKGYpIHtcbiAgaWYgKCFpc1N0cmluZyhmKSkge1xuICAgIHZhciBvYmplY3RzID0gW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIG9iamVjdHMucHVzaChpbnNwZWN0KGFyZ3VtZW50c1tpXSkpO1xuICAgIH1cbiAgICByZXR1cm4gb2JqZWN0cy5qb2luKCcgJyk7XG4gIH1cblxuICB2YXIgaSA9IDE7XG4gIHZhciBhcmdzID0gYXJndW1lbnRzO1xuICB2YXIgbGVuID0gYXJncy5sZW5ndGg7XG4gIHZhciBzdHIgPSBTdHJpbmcoZikucmVwbGFjZShmb3JtYXRSZWdFeHAsIGZ1bmN0aW9uKHgpIHtcbiAgICBpZiAoeCA9PT0gJyUlJykgcmV0dXJuICclJztcbiAgICBpZiAoaSA+PSBsZW4pIHJldHVybiB4O1xuICAgIHN3aXRjaCAoeCkge1xuICAgICAgY2FzZSAnJXMnOiByZXR1cm4gU3RyaW5nKGFyZ3NbaSsrXSk7XG4gICAgICBjYXNlICclZCc6IHJldHVybiBOdW1iZXIoYXJnc1tpKytdKTtcbiAgICAgIGNhc2UgJyVqJzpcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoYXJnc1tpKytdKTtcbiAgICAgICAgfSBjYXRjaCAoXykge1xuICAgICAgICAgIHJldHVybiAnW0NpcmN1bGFyXSc7XG4gICAgICAgIH1cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiB4O1xuICAgIH1cbiAgfSk7XG4gIGZvciAodmFyIHggPSBhcmdzW2ldOyBpIDwgbGVuOyB4ID0gYXJnc1srK2ldKSB7XG4gICAgaWYgKGlzTnVsbCh4KSB8fCAhaXNPYmplY3QoeCkpIHtcbiAgICAgIHN0ciArPSAnICcgKyB4O1xuICAgIH0gZWxzZSB7XG4gICAgICBzdHIgKz0gJyAnICsgaW5zcGVjdCh4KTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHN0cjtcbn07XG5cblxuLy8gTWFyayB0aGF0IGEgbWV0aG9kIHNob3VsZCBub3QgYmUgdXNlZC5cbi8vIFJldHVybnMgYSBtb2RpZmllZCBmdW5jdGlvbiB3aGljaCB3YXJucyBvbmNlIGJ5IGRlZmF1bHQuXG4vLyBJZiAtLW5vLWRlcHJlY2F0aW9uIGlzIHNldCwgdGhlbiBpdCBpcyBhIG5vLW9wLlxuZXhwb3J0cy5kZXByZWNhdGUgPSBmdW5jdGlvbihmbiwgbXNnKSB7XG4gIC8vIEFsbG93IGZvciBkZXByZWNhdGluZyB0aGluZ3MgaW4gdGhlIHByb2Nlc3Mgb2Ygc3RhcnRpbmcgdXAuXG4gIGlmIChpc1VuZGVmaW5lZChnbG9iYWwucHJvY2VzcykpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gZXhwb3J0cy5kZXByZWNhdGUoZm4sIG1zZykuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9O1xuICB9XG5cbiAgaWYgKHByb2Nlc3Mubm9EZXByZWNhdGlvbiA9PT0gdHJ1ZSkge1xuICAgIHJldHVybiBmbjtcbiAgfVxuXG4gIHZhciB3YXJuZWQgPSBmYWxzZTtcbiAgZnVuY3Rpb24gZGVwcmVjYXRlZCgpIHtcbiAgICBpZiAoIXdhcm5lZCkge1xuICAgICAgaWYgKHByb2Nlc3MudGhyb3dEZXByZWNhdGlvbikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IobXNnKTtcbiAgICAgIH0gZWxzZSBpZiAocHJvY2Vzcy50cmFjZURlcHJlY2F0aW9uKSB7XG4gICAgICAgIGNvbnNvbGUudHJhY2UobXNnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IobXNnKTtcbiAgICAgIH1cbiAgICAgIHdhcm5lZCA9IHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICB9XG5cbiAgcmV0dXJuIGRlcHJlY2F0ZWQ7XG59O1xuXG5cbnZhciBkZWJ1Z3MgPSB7fTtcbnZhciBkZWJ1Z0Vudmlyb247XG5leHBvcnRzLmRlYnVnbG9nID0gZnVuY3Rpb24oc2V0KSB7XG4gIGlmIChpc1VuZGVmaW5lZChkZWJ1Z0Vudmlyb24pKVxuICAgIGRlYnVnRW52aXJvbiA9IHByb2Nlc3MuZW52Lk5PREVfREVCVUcgfHwgJyc7XG4gIHNldCA9IHNldC50b1VwcGVyQ2FzZSgpO1xuICBpZiAoIWRlYnVnc1tzZXRdKSB7XG4gICAgaWYgKG5ldyBSZWdFeHAoJ1xcXFxiJyArIHNldCArICdcXFxcYicsICdpJykudGVzdChkZWJ1Z0Vudmlyb24pKSB7XG4gICAgICB2YXIgcGlkID0gcHJvY2Vzcy5waWQ7XG4gICAgICBkZWJ1Z3Nbc2V0XSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgbXNnID0gZXhwb3J0cy5mb3JtYXQuYXBwbHkoZXhwb3J0cywgYXJndW1lbnRzKTtcbiAgICAgICAgY29uc29sZS5lcnJvcignJXMgJWQ6ICVzJywgc2V0LCBwaWQsIG1zZyk7XG4gICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICBkZWJ1Z3Nbc2V0XSA9IGZ1bmN0aW9uKCkge307XG4gICAgfVxuICB9XG4gIHJldHVybiBkZWJ1Z3Nbc2V0XTtcbn07XG5cblxuLyoqXG4gKiBFY2hvcyB0aGUgdmFsdWUgb2YgYSB2YWx1ZS4gVHJ5cyB0byBwcmludCB0aGUgdmFsdWUgb3V0XG4gKiBpbiB0aGUgYmVzdCB3YXkgcG9zc2libGUgZ2l2ZW4gdGhlIGRpZmZlcmVudCB0eXBlcy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqIFRoZSBvYmplY3QgdG8gcHJpbnQgb3V0LlxuICogQHBhcmFtIHtPYmplY3R9IG9wdHMgT3B0aW9uYWwgb3B0aW9ucyBvYmplY3QgdGhhdCBhbHRlcnMgdGhlIG91dHB1dC5cbiAqL1xuLyogbGVnYWN5OiBvYmosIHNob3dIaWRkZW4sIGRlcHRoLCBjb2xvcnMqL1xuZnVuY3Rpb24gaW5zcGVjdChvYmosIG9wdHMpIHtcbiAgLy8gZGVmYXVsdCBvcHRpb25zXG4gIHZhciBjdHggPSB7XG4gICAgc2VlbjogW10sXG4gICAgc3R5bGl6ZTogc3R5bGl6ZU5vQ29sb3JcbiAgfTtcbiAgLy8gbGVnYWN5Li4uXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID49IDMpIGN0eC5kZXB0aCA9IGFyZ3VtZW50c1syXTtcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPj0gNCkgY3R4LmNvbG9ycyA9IGFyZ3VtZW50c1szXTtcbiAgaWYgKGlzQm9vbGVhbihvcHRzKSkge1xuICAgIC8vIGxlZ2FjeS4uLlxuICAgIGN0eC5zaG93SGlkZGVuID0gb3B0cztcbiAgfSBlbHNlIGlmIChvcHRzKSB7XG4gICAgLy8gZ290IGFuIFwib3B0aW9uc1wiIG9iamVjdFxuICAgIGV4cG9ydHMuX2V4dGVuZChjdHgsIG9wdHMpO1xuICB9XG4gIC8vIHNldCBkZWZhdWx0IG9wdGlvbnNcbiAgaWYgKGlzVW5kZWZpbmVkKGN0eC5zaG93SGlkZGVuKSkgY3R4LnNob3dIaWRkZW4gPSBmYWxzZTtcbiAgaWYgKGlzVW5kZWZpbmVkKGN0eC5kZXB0aCkpIGN0eC5kZXB0aCA9IDI7XG4gIGlmIChpc1VuZGVmaW5lZChjdHguY29sb3JzKSkgY3R4LmNvbG9ycyA9IGZhbHNlO1xuICBpZiAoaXNVbmRlZmluZWQoY3R4LmN1c3RvbUluc3BlY3QpKSBjdHguY3VzdG9tSW5zcGVjdCA9IHRydWU7XG4gIGlmIChjdHguY29sb3JzKSBjdHguc3R5bGl6ZSA9IHN0eWxpemVXaXRoQ29sb3I7XG4gIHJldHVybiBmb3JtYXRWYWx1ZShjdHgsIG9iaiwgY3R4LmRlcHRoKTtcbn1cbmV4cG9ydHMuaW5zcGVjdCA9IGluc3BlY3Q7XG5cblxuLy8gaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9BTlNJX2VzY2FwZV9jb2RlI2dyYXBoaWNzXG5pbnNwZWN0LmNvbG9ycyA9IHtcbiAgJ2JvbGQnIDogWzEsIDIyXSxcbiAgJ2l0YWxpYycgOiBbMywgMjNdLFxuICAndW5kZXJsaW5lJyA6IFs0LCAyNF0sXG4gICdpbnZlcnNlJyA6IFs3LCAyN10sXG4gICd3aGl0ZScgOiBbMzcsIDM5XSxcbiAgJ2dyZXknIDogWzkwLCAzOV0sXG4gICdibGFjaycgOiBbMzAsIDM5XSxcbiAgJ2JsdWUnIDogWzM0LCAzOV0sXG4gICdjeWFuJyA6IFszNiwgMzldLFxuICAnZ3JlZW4nIDogWzMyLCAzOV0sXG4gICdtYWdlbnRhJyA6IFszNSwgMzldLFxuICAncmVkJyA6IFszMSwgMzldLFxuICAneWVsbG93JyA6IFszMywgMzldXG59O1xuXG4vLyBEb24ndCB1c2UgJ2JsdWUnIG5vdCB2aXNpYmxlIG9uIGNtZC5leGVcbmluc3BlY3Quc3R5bGVzID0ge1xuICAnc3BlY2lhbCc6ICdjeWFuJyxcbiAgJ251bWJlcic6ICd5ZWxsb3cnLFxuICAnYm9vbGVhbic6ICd5ZWxsb3cnLFxuICAndW5kZWZpbmVkJzogJ2dyZXknLFxuICAnbnVsbCc6ICdib2xkJyxcbiAgJ3N0cmluZyc6ICdncmVlbicsXG4gICdkYXRlJzogJ21hZ2VudGEnLFxuICAvLyBcIm5hbWVcIjogaW50ZW50aW9uYWxseSBub3Qgc3R5bGluZ1xuICAncmVnZXhwJzogJ3JlZCdcbn07XG5cblxuZnVuY3Rpb24gc3R5bGl6ZVdpdGhDb2xvcihzdHIsIHN0eWxlVHlwZSkge1xuICB2YXIgc3R5bGUgPSBpbnNwZWN0LnN0eWxlc1tzdHlsZVR5cGVdO1xuXG4gIGlmIChzdHlsZSkge1xuICAgIHJldHVybiAnXFx1MDAxYlsnICsgaW5zcGVjdC5jb2xvcnNbc3R5bGVdWzBdICsgJ20nICsgc3RyICtcbiAgICAgICAgICAgJ1xcdTAwMWJbJyArIGluc3BlY3QuY29sb3JzW3N0eWxlXVsxXSArICdtJztcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gc3RyO1xuICB9XG59XG5cblxuZnVuY3Rpb24gc3R5bGl6ZU5vQ29sb3Ioc3RyLCBzdHlsZVR5cGUpIHtcbiAgcmV0dXJuIHN0cjtcbn1cblxuXG5mdW5jdGlvbiBhcnJheVRvSGFzaChhcnJheSkge1xuICB2YXIgaGFzaCA9IHt9O1xuXG4gIGFycmF5LmZvckVhY2goZnVuY3Rpb24odmFsLCBpZHgpIHtcbiAgICBoYXNoW3ZhbF0gPSB0cnVlO1xuICB9KTtcblxuICByZXR1cm4gaGFzaDtcbn1cblxuXG5mdW5jdGlvbiBmb3JtYXRWYWx1ZShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMpIHtcbiAgLy8gUHJvdmlkZSBhIGhvb2sgZm9yIHVzZXItc3BlY2lmaWVkIGluc3BlY3QgZnVuY3Rpb25zLlxuICAvLyBDaGVjayB0aGF0IHZhbHVlIGlzIGFuIG9iamVjdCB3aXRoIGFuIGluc3BlY3QgZnVuY3Rpb24gb24gaXRcbiAgaWYgKGN0eC5jdXN0b21JbnNwZWN0ICYmXG4gICAgICB2YWx1ZSAmJlxuICAgICAgaXNGdW5jdGlvbih2YWx1ZS5pbnNwZWN0KSAmJlxuICAgICAgLy8gRmlsdGVyIG91dCB0aGUgdXRpbCBtb2R1bGUsIGl0J3MgaW5zcGVjdCBmdW5jdGlvbiBpcyBzcGVjaWFsXG4gICAgICB2YWx1ZS5pbnNwZWN0ICE9PSBleHBvcnRzLmluc3BlY3QgJiZcbiAgICAgIC8vIEFsc28gZmlsdGVyIG91dCBhbnkgcHJvdG90eXBlIG9iamVjdHMgdXNpbmcgdGhlIGNpcmN1bGFyIGNoZWNrLlxuICAgICAgISh2YWx1ZS5jb25zdHJ1Y3RvciAmJiB2YWx1ZS5jb25zdHJ1Y3Rvci5wcm90b3R5cGUgPT09IHZhbHVlKSkge1xuICAgIHZhciByZXQgPSB2YWx1ZS5pbnNwZWN0KHJlY3Vyc2VUaW1lcywgY3R4KTtcbiAgICBpZiAoIWlzU3RyaW5nKHJldCkpIHtcbiAgICAgIHJldCA9IGZvcm1hdFZhbHVlKGN0eCwgcmV0LCByZWN1cnNlVGltZXMpO1xuICAgIH1cbiAgICByZXR1cm4gcmV0O1xuICB9XG5cbiAgLy8gUHJpbWl0aXZlIHR5cGVzIGNhbm5vdCBoYXZlIHByb3BlcnRpZXNcbiAgdmFyIHByaW1pdGl2ZSA9IGZvcm1hdFByaW1pdGl2ZShjdHgsIHZhbHVlKTtcbiAgaWYgKHByaW1pdGl2ZSkge1xuICAgIHJldHVybiBwcmltaXRpdmU7XG4gIH1cblxuICAvLyBMb29rIHVwIHRoZSBrZXlzIG9mIHRoZSBvYmplY3QuXG4gIHZhciBrZXlzID0gT2JqZWN0LmtleXModmFsdWUpO1xuICB2YXIgdmlzaWJsZUtleXMgPSBhcnJheVRvSGFzaChrZXlzKTtcblxuICBpZiAoY3R4LnNob3dIaWRkZW4pIHtcbiAgICBrZXlzID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXModmFsdWUpO1xuICB9XG5cbiAgLy8gSUUgZG9lc24ndCBtYWtlIGVycm9yIGZpZWxkcyBub24tZW51bWVyYWJsZVxuICAvLyBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2VuLXVzL2xpYnJhcnkvaWUvZHd3NTJzYnQodj12cy45NCkuYXNweFxuICBpZiAoaXNFcnJvcih2YWx1ZSlcbiAgICAgICYmIChrZXlzLmluZGV4T2YoJ21lc3NhZ2UnKSA+PSAwIHx8IGtleXMuaW5kZXhPZignZGVzY3JpcHRpb24nKSA+PSAwKSkge1xuICAgIHJldHVybiBmb3JtYXRFcnJvcih2YWx1ZSk7XG4gIH1cblxuICAvLyBTb21lIHR5cGUgb2Ygb2JqZWN0IHdpdGhvdXQgcHJvcGVydGllcyBjYW4gYmUgc2hvcnRjdXR0ZWQuXG4gIGlmIChrZXlzLmxlbmd0aCA9PT0gMCkge1xuICAgIGlmIChpc0Z1bmN0aW9uKHZhbHVlKSkge1xuICAgICAgdmFyIG5hbWUgPSB2YWx1ZS5uYW1lID8gJzogJyArIHZhbHVlLm5hbWUgOiAnJztcbiAgICAgIHJldHVybiBjdHguc3R5bGl6ZSgnW0Z1bmN0aW9uJyArIG5hbWUgKyAnXScsICdzcGVjaWFsJyk7XG4gICAgfVxuICAgIGlmIChpc1JlZ0V4cCh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBjdHguc3R5bGl6ZShSZWdFeHAucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpLCAncmVnZXhwJyk7XG4gICAgfVxuICAgIGlmIChpc0RhdGUodmFsdWUpKSB7XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoRGF0ZS5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSksICdkYXRlJyk7XG4gICAgfVxuICAgIGlmIChpc0Vycm9yKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIGZvcm1hdEVycm9yKHZhbHVlKTtcbiAgICB9XG4gIH1cblxuICB2YXIgYmFzZSA9ICcnLCBhcnJheSA9IGZhbHNlLCBicmFjZXMgPSBbJ3snLCAnfSddO1xuXG4gIC8vIE1ha2UgQXJyYXkgc2F5IHRoYXQgdGhleSBhcmUgQXJyYXlcbiAgaWYgKGlzQXJyYXkodmFsdWUpKSB7XG4gICAgYXJyYXkgPSB0cnVlO1xuICAgIGJyYWNlcyA9IFsnWycsICddJ107XG4gIH1cblxuICAvLyBNYWtlIGZ1bmN0aW9ucyBzYXkgdGhhdCB0aGV5IGFyZSBmdW5jdGlvbnNcbiAgaWYgKGlzRnVuY3Rpb24odmFsdWUpKSB7XG4gICAgdmFyIG4gPSB2YWx1ZS5uYW1lID8gJzogJyArIHZhbHVlLm5hbWUgOiAnJztcbiAgICBiYXNlID0gJyBbRnVuY3Rpb24nICsgbiArICddJztcbiAgfVxuXG4gIC8vIE1ha2UgUmVnRXhwcyBzYXkgdGhhdCB0aGV5IGFyZSBSZWdFeHBzXG4gIGlmIChpc1JlZ0V4cCh2YWx1ZSkpIHtcbiAgICBiYXNlID0gJyAnICsgUmVnRXhwLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKTtcbiAgfVxuXG4gIC8vIE1ha2UgZGF0ZXMgd2l0aCBwcm9wZXJ0aWVzIGZpcnN0IHNheSB0aGUgZGF0ZVxuICBpZiAoaXNEYXRlKHZhbHVlKSkge1xuICAgIGJhc2UgPSAnICcgKyBEYXRlLnByb3RvdHlwZS50b1VUQ1N0cmluZy5jYWxsKHZhbHVlKTtcbiAgfVxuXG4gIC8vIE1ha2UgZXJyb3Igd2l0aCBtZXNzYWdlIGZpcnN0IHNheSB0aGUgZXJyb3JcbiAgaWYgKGlzRXJyb3IodmFsdWUpKSB7XG4gICAgYmFzZSA9ICcgJyArIGZvcm1hdEVycm9yKHZhbHVlKTtcbiAgfVxuXG4gIGlmIChrZXlzLmxlbmd0aCA9PT0gMCAmJiAoIWFycmF5IHx8IHZhbHVlLmxlbmd0aCA9PSAwKSkge1xuICAgIHJldHVybiBicmFjZXNbMF0gKyBiYXNlICsgYnJhY2VzWzFdO1xuICB9XG5cbiAgaWYgKHJlY3Vyc2VUaW1lcyA8IDApIHtcbiAgICBpZiAoaXNSZWdFeHAodmFsdWUpKSB7XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoUmVnRXhwLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKSwgJ3JlZ2V4cCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoJ1tPYmplY3RdJywgJ3NwZWNpYWwnKTtcbiAgICB9XG4gIH1cblxuICBjdHguc2Vlbi5wdXNoKHZhbHVlKTtcblxuICB2YXIgb3V0cHV0O1xuICBpZiAoYXJyYXkpIHtcbiAgICBvdXRwdXQgPSBmb3JtYXRBcnJheShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLCBrZXlzKTtcbiAgfSBlbHNlIHtcbiAgICBvdXRwdXQgPSBrZXlzLm1hcChmdW5jdGlvbihrZXkpIHtcbiAgICAgIHJldHVybiBmb3JtYXRQcm9wZXJ0eShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLCBrZXksIGFycmF5KTtcbiAgICB9KTtcbiAgfVxuXG4gIGN0eC5zZWVuLnBvcCgpO1xuXG4gIHJldHVybiByZWR1Y2VUb1NpbmdsZVN0cmluZyhvdXRwdXQsIGJhc2UsIGJyYWNlcyk7XG59XG5cblxuZnVuY3Rpb24gZm9ybWF0UHJpbWl0aXZlKGN0eCwgdmFsdWUpIHtcbiAgaWYgKGlzVW5kZWZpbmVkKHZhbHVlKSlcbiAgICByZXR1cm4gY3R4LnN0eWxpemUoJ3VuZGVmaW5lZCcsICd1bmRlZmluZWQnKTtcbiAgaWYgKGlzU3RyaW5nKHZhbHVlKSkge1xuICAgIHZhciBzaW1wbGUgPSAnXFwnJyArIEpTT04uc3RyaW5naWZ5KHZhbHVlKS5yZXBsYWNlKC9eXCJ8XCIkL2csICcnKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnJlcGxhY2UoLycvZywgXCJcXFxcJ1wiKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnJlcGxhY2UoL1xcXFxcIi9nLCAnXCInKSArICdcXCcnO1xuICAgIHJldHVybiBjdHguc3R5bGl6ZShzaW1wbGUsICdzdHJpbmcnKTtcbiAgfVxuICBpZiAoaXNOdW1iZXIodmFsdWUpKVxuICAgIHJldHVybiBjdHguc3R5bGl6ZSgnJyArIHZhbHVlLCAnbnVtYmVyJyk7XG4gIGlmIChpc0Jvb2xlYW4odmFsdWUpKVxuICAgIHJldHVybiBjdHguc3R5bGl6ZSgnJyArIHZhbHVlLCAnYm9vbGVhbicpO1xuICAvLyBGb3Igc29tZSByZWFzb24gdHlwZW9mIG51bGwgaXMgXCJvYmplY3RcIiwgc28gc3BlY2lhbCBjYXNlIGhlcmUuXG4gIGlmIChpc051bGwodmFsdWUpKVxuICAgIHJldHVybiBjdHguc3R5bGl6ZSgnbnVsbCcsICdudWxsJyk7XG59XG5cblxuZnVuY3Rpb24gZm9ybWF0RXJyb3IodmFsdWUpIHtcbiAgcmV0dXJuICdbJyArIEVycm9yLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKSArICddJztcbn1cblxuXG5mdW5jdGlvbiBmb3JtYXRBcnJheShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLCBrZXlzKSB7XG4gIHZhciBvdXRwdXQgPSBbXTtcbiAgZm9yICh2YXIgaSA9IDAsIGwgPSB2YWx1ZS5sZW5ndGg7IGkgPCBsOyArK2kpIHtcbiAgICBpZiAoaGFzT3duUHJvcGVydHkodmFsdWUsIFN0cmluZyhpKSkpIHtcbiAgICAgIG91dHB1dC5wdXNoKGZvcm1hdFByb3BlcnR5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsXG4gICAgICAgICAgU3RyaW5nKGkpLCB0cnVlKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG91dHB1dC5wdXNoKCcnKTtcbiAgICB9XG4gIH1cbiAga2V5cy5mb3JFYWNoKGZ1bmN0aW9uKGtleSkge1xuICAgIGlmICgha2V5Lm1hdGNoKC9eXFxkKyQvKSkge1xuICAgICAgb3V0cHV0LnB1c2goZm9ybWF0UHJvcGVydHkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cyxcbiAgICAgICAgICBrZXksIHRydWUpKTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gb3V0cHV0O1xufVxuXG5cbmZ1bmN0aW9uIGZvcm1hdFByb3BlcnR5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsIGtleSwgYXJyYXkpIHtcbiAgdmFyIG5hbWUsIHN0ciwgZGVzYztcbiAgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodmFsdWUsIGtleSkgfHwgeyB2YWx1ZTogdmFsdWVba2V5XSB9O1xuICBpZiAoZGVzYy5nZXQpIHtcbiAgICBpZiAoZGVzYy5zZXQpIHtcbiAgICAgIHN0ciA9IGN0eC5zdHlsaXplKCdbR2V0dGVyL1NldHRlcl0nLCAnc3BlY2lhbCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdHIgPSBjdHguc3R5bGl6ZSgnW0dldHRlcl0nLCAnc3BlY2lhbCcpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBpZiAoZGVzYy5zZXQpIHtcbiAgICAgIHN0ciA9IGN0eC5zdHlsaXplKCdbU2V0dGVyXScsICdzcGVjaWFsJyk7XG4gICAgfVxuICB9XG4gIGlmICghaGFzT3duUHJvcGVydHkodmlzaWJsZUtleXMsIGtleSkpIHtcbiAgICBuYW1lID0gJ1snICsga2V5ICsgJ10nO1xuICB9XG4gIGlmICghc3RyKSB7XG4gICAgaWYgKGN0eC5zZWVuLmluZGV4T2YoZGVzYy52YWx1ZSkgPCAwKSB7XG4gICAgICBpZiAoaXNOdWxsKHJlY3Vyc2VUaW1lcykpIHtcbiAgICAgICAgc3RyID0gZm9ybWF0VmFsdWUoY3R4LCBkZXNjLnZhbHVlLCBudWxsKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0ciA9IGZvcm1hdFZhbHVlKGN0eCwgZGVzYy52YWx1ZSwgcmVjdXJzZVRpbWVzIC0gMSk7XG4gICAgICB9XG4gICAgICBpZiAoc3RyLmluZGV4T2YoJ1xcbicpID4gLTEpIHtcbiAgICAgICAgaWYgKGFycmF5KSB7XG4gICAgICAgICAgc3RyID0gc3RyLnNwbGl0KCdcXG4nKS5tYXAoZnVuY3Rpb24obGluZSkge1xuICAgICAgICAgICAgcmV0dXJuICcgICcgKyBsaW5lO1xuICAgICAgICAgIH0pLmpvaW4oJ1xcbicpLnN1YnN0cigyKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzdHIgPSAnXFxuJyArIHN0ci5zcGxpdCgnXFxuJykubWFwKGZ1bmN0aW9uKGxpbmUpIHtcbiAgICAgICAgICAgIHJldHVybiAnICAgJyArIGxpbmU7XG4gICAgICAgICAgfSkuam9pbignXFxuJyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgc3RyID0gY3R4LnN0eWxpemUoJ1tDaXJjdWxhcl0nLCAnc3BlY2lhbCcpO1xuICAgIH1cbiAgfVxuICBpZiAoaXNVbmRlZmluZWQobmFtZSkpIHtcbiAgICBpZiAoYXJyYXkgJiYga2V5Lm1hdGNoKC9eXFxkKyQvKSkge1xuICAgICAgcmV0dXJuIHN0cjtcbiAgICB9XG4gICAgbmFtZSA9IEpTT04uc3RyaW5naWZ5KCcnICsga2V5KTtcbiAgICBpZiAobmFtZS5tYXRjaCgvXlwiKFthLXpBLVpfXVthLXpBLVpfMC05XSopXCIkLykpIHtcbiAgICAgIG5hbWUgPSBuYW1lLnN1YnN0cigxLCBuYW1lLmxlbmd0aCAtIDIpO1xuICAgICAgbmFtZSA9IGN0eC5zdHlsaXplKG5hbWUsICduYW1lJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG5hbWUgPSBuYW1lLnJlcGxhY2UoLycvZywgXCJcXFxcJ1wiKVxuICAgICAgICAgICAgICAgICAucmVwbGFjZSgvXFxcXFwiL2csICdcIicpXG4gICAgICAgICAgICAgICAgIC5yZXBsYWNlKC8oXlwifFwiJCkvZywgXCInXCIpO1xuICAgICAgbmFtZSA9IGN0eC5zdHlsaXplKG5hbWUsICdzdHJpbmcnKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbmFtZSArICc6ICcgKyBzdHI7XG59XG5cblxuZnVuY3Rpb24gcmVkdWNlVG9TaW5nbGVTdHJpbmcob3V0cHV0LCBiYXNlLCBicmFjZXMpIHtcbiAgdmFyIG51bUxpbmVzRXN0ID0gMDtcbiAgdmFyIGxlbmd0aCA9IG91dHB1dC5yZWR1Y2UoZnVuY3Rpb24ocHJldiwgY3VyKSB7XG4gICAgbnVtTGluZXNFc3QrKztcbiAgICBpZiAoY3VyLmluZGV4T2YoJ1xcbicpID49IDApIG51bUxpbmVzRXN0Kys7XG4gICAgcmV0dXJuIHByZXYgKyBjdXIucmVwbGFjZSgvXFx1MDAxYlxcW1xcZFxcZD9tL2csICcnKS5sZW5ndGggKyAxO1xuICB9LCAwKTtcblxuICBpZiAobGVuZ3RoID4gNjApIHtcbiAgICByZXR1cm4gYnJhY2VzWzBdICtcbiAgICAgICAgICAgKGJhc2UgPT09ICcnID8gJycgOiBiYXNlICsgJ1xcbiAnKSArXG4gICAgICAgICAgICcgJyArXG4gICAgICAgICAgIG91dHB1dC5qb2luKCcsXFxuICAnKSArXG4gICAgICAgICAgICcgJyArXG4gICAgICAgICAgIGJyYWNlc1sxXTtcbiAgfVxuXG4gIHJldHVybiBicmFjZXNbMF0gKyBiYXNlICsgJyAnICsgb3V0cHV0LmpvaW4oJywgJykgKyAnICcgKyBicmFjZXNbMV07XG59XG5cblxuLy8gTk9URTogVGhlc2UgdHlwZSBjaGVja2luZyBmdW5jdGlvbnMgaW50ZW50aW9uYWxseSBkb24ndCB1c2UgYGluc3RhbmNlb2ZgXG4vLyBiZWNhdXNlIGl0IGlzIGZyYWdpbGUgYW5kIGNhbiBiZSBlYXNpbHkgZmFrZWQgd2l0aCBgT2JqZWN0LmNyZWF0ZSgpYC5cbmZ1bmN0aW9uIGlzQXJyYXkoYXIpIHtcbiAgcmV0dXJuIEFycmF5LmlzQXJyYXkoYXIpO1xufVxuZXhwb3J0cy5pc0FycmF5ID0gaXNBcnJheTtcblxuZnVuY3Rpb24gaXNCb29sZWFuKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ2Jvb2xlYW4nO1xufVxuZXhwb3J0cy5pc0Jvb2xlYW4gPSBpc0Jvb2xlYW47XG5cbmZ1bmN0aW9uIGlzTnVsbChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gbnVsbDtcbn1cbmV4cG9ydHMuaXNOdWxsID0gaXNOdWxsO1xuXG5mdW5jdGlvbiBpc051bGxPclVuZGVmaW5lZChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PSBudWxsO1xufVxuZXhwb3J0cy5pc051bGxPclVuZGVmaW5lZCA9IGlzTnVsbE9yVW5kZWZpbmVkO1xuXG5mdW5jdGlvbiBpc051bWJlcihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdudW1iZXInO1xufVxuZXhwb3J0cy5pc051bWJlciA9IGlzTnVtYmVyO1xuXG5mdW5jdGlvbiBpc1N0cmluZyhhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdzdHJpbmcnO1xufVxuZXhwb3J0cy5pc1N0cmluZyA9IGlzU3RyaW5nO1xuXG5mdW5jdGlvbiBpc1N5bWJvbChhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdzeW1ib2wnO1xufVxuZXhwb3J0cy5pc1N5bWJvbCA9IGlzU3ltYm9sO1xuXG5mdW5jdGlvbiBpc1VuZGVmaW5lZChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gdm9pZCAwO1xufVxuZXhwb3J0cy5pc1VuZGVmaW5lZCA9IGlzVW5kZWZpbmVkO1xuXG5mdW5jdGlvbiBpc1JlZ0V4cChyZSkge1xuICByZXR1cm4gaXNPYmplY3QocmUpICYmIG9iamVjdFRvU3RyaW5nKHJlKSA9PT0gJ1tvYmplY3QgUmVnRXhwXSc7XG59XG5leHBvcnRzLmlzUmVnRXhwID0gaXNSZWdFeHA7XG5cbmZ1bmN0aW9uIGlzT2JqZWN0KGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ29iamVjdCcgJiYgYXJnICE9PSBudWxsO1xufVxuZXhwb3J0cy5pc09iamVjdCA9IGlzT2JqZWN0O1xuXG5mdW5jdGlvbiBpc0RhdGUoZCkge1xuICByZXR1cm4gaXNPYmplY3QoZCkgJiYgb2JqZWN0VG9TdHJpbmcoZCkgPT09ICdbb2JqZWN0IERhdGVdJztcbn1cbmV4cG9ydHMuaXNEYXRlID0gaXNEYXRlO1xuXG5mdW5jdGlvbiBpc0Vycm9yKGUpIHtcbiAgcmV0dXJuIGlzT2JqZWN0KGUpICYmXG4gICAgICAob2JqZWN0VG9TdHJpbmcoZSkgPT09ICdbb2JqZWN0IEVycm9yXScgfHwgZSBpbnN0YW5jZW9mIEVycm9yKTtcbn1cbmV4cG9ydHMuaXNFcnJvciA9IGlzRXJyb3I7XG5cbmZ1bmN0aW9uIGlzRnVuY3Rpb24oYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnZnVuY3Rpb24nO1xufVxuZXhwb3J0cy5pc0Z1bmN0aW9uID0gaXNGdW5jdGlvbjtcblxuZnVuY3Rpb24gaXNQcmltaXRpdmUoYXJnKSB7XG4gIHJldHVybiBhcmcgPT09IG51bGwgfHxcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICdib29sZWFuJyB8fFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ251bWJlcicgfHxcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICdzdHJpbmcnIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnc3ltYm9sJyB8fCAgLy8gRVM2IHN5bWJvbFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ3VuZGVmaW5lZCc7XG59XG5leHBvcnRzLmlzUHJpbWl0aXZlID0gaXNQcmltaXRpdmU7XG5cbmV4cG9ydHMuaXNCdWZmZXIgPSByZXF1aXJlKCcuL3N1cHBvcnQvaXNCdWZmZXInKTtcblxuZnVuY3Rpb24gb2JqZWN0VG9TdHJpbmcobykge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG8pO1xufVxuXG5cbmZ1bmN0aW9uIHBhZChuKSB7XG4gIHJldHVybiBuIDwgMTAgPyAnMCcgKyBuLnRvU3RyaW5nKDEwKSA6IG4udG9TdHJpbmcoMTApO1xufVxuXG5cbnZhciBtb250aHMgPSBbJ0phbicsICdGZWInLCAnTWFyJywgJ0FwcicsICdNYXknLCAnSnVuJywgJ0p1bCcsICdBdWcnLCAnU2VwJyxcbiAgICAgICAgICAgICAgJ09jdCcsICdOb3YnLCAnRGVjJ107XG5cbi8vIDI2IEZlYiAxNjoxOTozNFxuZnVuY3Rpb24gdGltZXN0YW1wKCkge1xuICB2YXIgZCA9IG5ldyBEYXRlKCk7XG4gIHZhciB0aW1lID0gW3BhZChkLmdldEhvdXJzKCkpLFxuICAgICAgICAgICAgICBwYWQoZC5nZXRNaW51dGVzKCkpLFxuICAgICAgICAgICAgICBwYWQoZC5nZXRTZWNvbmRzKCkpXS5qb2luKCc6Jyk7XG4gIHJldHVybiBbZC5nZXREYXRlKCksIG1vbnRoc1tkLmdldE1vbnRoKCldLCB0aW1lXS5qb2luKCcgJyk7XG59XG5cblxuLy8gbG9nIGlzIGp1c3QgYSB0aGluIHdyYXBwZXIgdG8gY29uc29sZS5sb2cgdGhhdCBwcmVwZW5kcyBhIHRpbWVzdGFtcFxuZXhwb3J0cy5sb2cgPSBmdW5jdGlvbigpIHtcbiAgY29uc29sZS5sb2coJyVzIC0gJXMnLCB0aW1lc3RhbXAoKSwgZXhwb3J0cy5mb3JtYXQuYXBwbHkoZXhwb3J0cywgYXJndW1lbnRzKSk7XG59O1xuXG5cbi8qKlxuICogSW5oZXJpdCB0aGUgcHJvdG90eXBlIG1ldGhvZHMgZnJvbSBvbmUgY29uc3RydWN0b3IgaW50byBhbm90aGVyLlxuICpcbiAqIFRoZSBGdW5jdGlvbi5wcm90b3R5cGUuaW5oZXJpdHMgZnJvbSBsYW5nLmpzIHJld3JpdHRlbiBhcyBhIHN0YW5kYWxvbmVcbiAqIGZ1bmN0aW9uIChub3Qgb24gRnVuY3Rpb24ucHJvdG90eXBlKS4gTk9URTogSWYgdGhpcyBmaWxlIGlzIHRvIGJlIGxvYWRlZFxuICogZHVyaW5nIGJvb3RzdHJhcHBpbmcgdGhpcyBmdW5jdGlvbiBuZWVkcyB0byBiZSByZXdyaXR0ZW4gdXNpbmcgc29tZSBuYXRpdmVcbiAqIGZ1bmN0aW9ucyBhcyBwcm90b3R5cGUgc2V0dXAgdXNpbmcgbm9ybWFsIEphdmFTY3JpcHQgZG9lcyBub3Qgd29yayBhc1xuICogZXhwZWN0ZWQgZHVyaW5nIGJvb3RzdHJhcHBpbmcgKHNlZSBtaXJyb3IuanMgaW4gcjExNDkwMykuXG4gKlxuICogQHBhcmFtIHtmdW5jdGlvbn0gY3RvciBDb25zdHJ1Y3RvciBmdW5jdGlvbiB3aGljaCBuZWVkcyB0byBpbmhlcml0IHRoZVxuICogICAgIHByb3RvdHlwZS5cbiAqIEBwYXJhbSB7ZnVuY3Rpb259IHN1cGVyQ3RvciBDb25zdHJ1Y3RvciBmdW5jdGlvbiB0byBpbmhlcml0IHByb3RvdHlwZSBmcm9tLlxuICovXG5leHBvcnRzLmluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcblxuZXhwb3J0cy5fZXh0ZW5kID0gZnVuY3Rpb24ob3JpZ2luLCBhZGQpIHtcbiAgLy8gRG9uJ3QgZG8gYW55dGhpbmcgaWYgYWRkIGlzbid0IGFuIG9iamVjdFxuICBpZiAoIWFkZCB8fCAhaXNPYmplY3QoYWRkKSkgcmV0dXJuIG9yaWdpbjtcblxuICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKGFkZCk7XG4gIHZhciBpID0ga2V5cy5sZW5ndGg7XG4gIHdoaWxlIChpLS0pIHtcbiAgICBvcmlnaW5ba2V5c1tpXV0gPSBhZGRba2V5c1tpXV07XG4gIH1cbiAgcmV0dXJuIG9yaWdpbjtcbn07XG5cbmZ1bmN0aW9uIGhhc093blByb3BlcnR5KG9iaiwgcHJvcCkge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwgcHJvcCk7XG59XG4iLCIndXNlIHN0cmljdCdcblxuZXhwb3J0cy5ieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aFxuZXhwb3J0cy50b0J5dGVBcnJheSA9IHRvQnl0ZUFycmF5XG5leHBvcnRzLmZyb21CeXRlQXJyYXkgPSBmcm9tQnl0ZUFycmF5XG5cbnZhciBsb29rdXAgPSBbXVxudmFyIHJldkxvb2t1cCA9IFtdXG52YXIgQXJyID0gdHlwZW9mIFVpbnQ4QXJyYXkgIT09ICd1bmRlZmluZWQnID8gVWludDhBcnJheSA6IEFycmF5XG5cbnZhciBjb2RlID0gJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky8nXG5mb3IgKHZhciBpID0gMCwgbGVuID0gY29kZS5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuICBsb29rdXBbaV0gPSBjb2RlW2ldXG4gIHJldkxvb2t1cFtjb2RlLmNoYXJDb2RlQXQoaSldID0gaVxufVxuXG4vLyBTdXBwb3J0IGRlY29kaW5nIFVSTC1zYWZlIGJhc2U2NCBzdHJpbmdzLCBhcyBOb2RlLmpzIGRvZXMuXG4vLyBTZWU6IGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0Jhc2U2NCNVUkxfYXBwbGljYXRpb25zXG5yZXZMb29rdXBbJy0nLmNoYXJDb2RlQXQoMCldID0gNjJcbnJldkxvb2t1cFsnXycuY2hhckNvZGVBdCgwKV0gPSA2M1xuXG5mdW5jdGlvbiBnZXRMZW5zIChiNjQpIHtcbiAgdmFyIGxlbiA9IGI2NC5sZW5ndGhcblxuICBpZiAobGVuICUgNCA+IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgc3RyaW5nLiBMZW5ndGggbXVzdCBiZSBhIG11bHRpcGxlIG9mIDQnKVxuICB9XG5cbiAgLy8gVHJpbSBvZmYgZXh0cmEgYnl0ZXMgYWZ0ZXIgcGxhY2Vob2xkZXIgYnl0ZXMgYXJlIGZvdW5kXG4gIC8vIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL2JlYXRnYW1taXQvYmFzZTY0LWpzL2lzc3Vlcy80MlxuICB2YXIgdmFsaWRMZW4gPSBiNjQuaW5kZXhPZignPScpXG4gIGlmICh2YWxpZExlbiA9PT0gLTEpIHZhbGlkTGVuID0gbGVuXG5cbiAgdmFyIHBsYWNlSG9sZGVyc0xlbiA9IHZhbGlkTGVuID09PSBsZW5cbiAgICA/IDBcbiAgICA6IDQgLSAodmFsaWRMZW4gJSA0KVxuXG4gIHJldHVybiBbdmFsaWRMZW4sIHBsYWNlSG9sZGVyc0xlbl1cbn1cblxuLy8gYmFzZTY0IGlzIDQvMyArIHVwIHRvIHR3byBjaGFyYWN0ZXJzIG9mIHRoZSBvcmlnaW5hbCBkYXRhXG5mdW5jdGlvbiBieXRlTGVuZ3RoIChiNjQpIHtcbiAgdmFyIGxlbnMgPSBnZXRMZW5zKGI2NClcbiAgdmFyIHZhbGlkTGVuID0gbGVuc1swXVxuICB2YXIgcGxhY2VIb2xkZXJzTGVuID0gbGVuc1sxXVxuICByZXR1cm4gKCh2YWxpZExlbiArIHBsYWNlSG9sZGVyc0xlbikgKiAzIC8gNCkgLSBwbGFjZUhvbGRlcnNMZW5cbn1cblxuZnVuY3Rpb24gX2J5dGVMZW5ndGggKGI2NCwgdmFsaWRMZW4sIHBsYWNlSG9sZGVyc0xlbikge1xuICByZXR1cm4gKCh2YWxpZExlbiArIHBsYWNlSG9sZGVyc0xlbikgKiAzIC8gNCkgLSBwbGFjZUhvbGRlcnNMZW5cbn1cblxuZnVuY3Rpb24gdG9CeXRlQXJyYXkgKGI2NCkge1xuICB2YXIgdG1wXG4gIHZhciBsZW5zID0gZ2V0TGVucyhiNjQpXG4gIHZhciB2YWxpZExlbiA9IGxlbnNbMF1cbiAgdmFyIHBsYWNlSG9sZGVyc0xlbiA9IGxlbnNbMV1cblxuICB2YXIgYXJyID0gbmV3IEFycihfYnl0ZUxlbmd0aChiNjQsIHZhbGlkTGVuLCBwbGFjZUhvbGRlcnNMZW4pKVxuXG4gIHZhciBjdXJCeXRlID0gMFxuXG4gIC8vIGlmIHRoZXJlIGFyZSBwbGFjZWhvbGRlcnMsIG9ubHkgZ2V0IHVwIHRvIHRoZSBsYXN0IGNvbXBsZXRlIDQgY2hhcnNcbiAgdmFyIGxlbiA9IHBsYWNlSG9sZGVyc0xlbiA+IDBcbiAgICA/IHZhbGlkTGVuIC0gNFxuICAgIDogdmFsaWRMZW5cblxuICB2YXIgaVxuICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpICs9IDQpIHtcbiAgICB0bXAgPVxuICAgICAgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpKV0gPDwgMTgpIHxcbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDEpXSA8PCAxMikgfFxuICAgICAgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpICsgMildIDw8IDYpIHxcbiAgICAgIHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpICsgMyldXG4gICAgYXJyW2N1ckJ5dGUrK10gPSAodG1wID4+IDE2KSAmIDB4RkZcbiAgICBhcnJbY3VyQnl0ZSsrXSA9ICh0bXAgPj4gOCkgJiAweEZGXG4gICAgYXJyW2N1ckJ5dGUrK10gPSB0bXAgJiAweEZGXG4gIH1cblxuICBpZiAocGxhY2VIb2xkZXJzTGVuID09PSAyKSB7XG4gICAgdG1wID1cbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSldIDw8IDIpIHxcbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDEpXSA+PiA0KVxuICAgIGFycltjdXJCeXRlKytdID0gdG1wICYgMHhGRlxuICB9XG5cbiAgaWYgKHBsYWNlSG9sZGVyc0xlbiA9PT0gMSkge1xuICAgIHRtcCA9XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkpXSA8PCAxMCkgfFxuICAgICAgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpICsgMSldIDw8IDQpIHxcbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDIpXSA+PiAyKVxuICAgIGFycltjdXJCeXRlKytdID0gKHRtcCA+PiA4KSAmIDB4RkZcbiAgICBhcnJbY3VyQnl0ZSsrXSA9IHRtcCAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBhcnJcbn1cblxuZnVuY3Rpb24gdHJpcGxldFRvQmFzZTY0IChudW0pIHtcbiAgcmV0dXJuIGxvb2t1cFtudW0gPj4gMTggJiAweDNGXSArXG4gICAgbG9va3VwW251bSA+PiAxMiAmIDB4M0ZdICtcbiAgICBsb29rdXBbbnVtID4+IDYgJiAweDNGXSArXG4gICAgbG9va3VwW251bSAmIDB4M0ZdXG59XG5cbmZ1bmN0aW9uIGVuY29kZUNodW5rICh1aW50OCwgc3RhcnQsIGVuZCkge1xuICB2YXIgdG1wXG4gIHZhciBvdXRwdXQgPSBbXVxuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkgKz0gMykge1xuICAgIHRtcCA9XG4gICAgICAoKHVpbnQ4W2ldIDw8IDE2KSAmIDB4RkYwMDAwKSArXG4gICAgICAoKHVpbnQ4W2kgKyAxXSA8PCA4KSAmIDB4RkYwMCkgK1xuICAgICAgKHVpbnQ4W2kgKyAyXSAmIDB4RkYpXG4gICAgb3V0cHV0LnB1c2godHJpcGxldFRvQmFzZTY0KHRtcCkpXG4gIH1cbiAgcmV0dXJuIG91dHB1dC5qb2luKCcnKVxufVxuXG5mdW5jdGlvbiBmcm9tQnl0ZUFycmF5ICh1aW50OCkge1xuICB2YXIgdG1wXG4gIHZhciBsZW4gPSB1aW50OC5sZW5ndGhcbiAgdmFyIGV4dHJhQnl0ZXMgPSBsZW4gJSAzIC8vIGlmIHdlIGhhdmUgMSBieXRlIGxlZnQsIHBhZCAyIGJ5dGVzXG4gIHZhciBwYXJ0cyA9IFtdXG4gIHZhciBtYXhDaHVua0xlbmd0aCA9IDE2MzgzIC8vIG11c3QgYmUgbXVsdGlwbGUgb2YgM1xuXG4gIC8vIGdvIHRocm91Z2ggdGhlIGFycmF5IGV2ZXJ5IHRocmVlIGJ5dGVzLCB3ZSdsbCBkZWFsIHdpdGggdHJhaWxpbmcgc3R1ZmYgbGF0ZXJcbiAgZm9yICh2YXIgaSA9IDAsIGxlbjIgPSBsZW4gLSBleHRyYUJ5dGVzOyBpIDwgbGVuMjsgaSArPSBtYXhDaHVua0xlbmd0aCkge1xuICAgIHBhcnRzLnB1c2goZW5jb2RlQ2h1bmsodWludDgsIGksIChpICsgbWF4Q2h1bmtMZW5ndGgpID4gbGVuMiA/IGxlbjIgOiAoaSArIG1heENodW5rTGVuZ3RoKSkpXG4gIH1cblxuICAvLyBwYWQgdGhlIGVuZCB3aXRoIHplcm9zLCBidXQgbWFrZSBzdXJlIHRvIG5vdCBmb3JnZXQgdGhlIGV4dHJhIGJ5dGVzXG4gIGlmIChleHRyYUJ5dGVzID09PSAxKSB7XG4gICAgdG1wID0gdWludDhbbGVuIC0gMV1cbiAgICBwYXJ0cy5wdXNoKFxuICAgICAgbG9va3VwW3RtcCA+PiAyXSArXG4gICAgICBsb29rdXBbKHRtcCA8PCA0KSAmIDB4M0ZdICtcbiAgICAgICc9PSdcbiAgICApXG4gIH0gZWxzZSBpZiAoZXh0cmFCeXRlcyA9PT0gMikge1xuICAgIHRtcCA9ICh1aW50OFtsZW4gLSAyXSA8PCA4KSArIHVpbnQ4W2xlbiAtIDFdXG4gICAgcGFydHMucHVzaChcbiAgICAgIGxvb2t1cFt0bXAgPj4gMTBdICtcbiAgICAgIGxvb2t1cFsodG1wID4+IDQpICYgMHgzRl0gK1xuICAgICAgbG9va3VwWyh0bXAgPDwgMikgJiAweDNGXSArXG4gICAgICAnPSdcbiAgICApXG4gIH1cblxuICByZXR1cm4gcGFydHMuam9pbignJylcbn1cbiIsIiIsIi8qIVxuICogVGhlIGJ1ZmZlciBtb2R1bGUgZnJvbSBub2RlLmpzLCBmb3IgdGhlIGJyb3dzZXIuXG4gKlxuICogQGF1dGhvciAgIEZlcm9zcyBBYm91a2hhZGlqZWggPGh0dHBzOi8vZmVyb3NzLm9yZz5cbiAqIEBsaWNlbnNlICBNSVRcbiAqL1xuLyogZXNsaW50LWRpc2FibGUgbm8tcHJvdG8gKi9cblxuJ3VzZSBzdHJpY3QnXG5cbnZhciBiYXNlNjQgPSByZXF1aXJlKCdiYXNlNjQtanMnKVxudmFyIGllZWU3NTQgPSByZXF1aXJlKCdpZWVlNzU0JylcblxuZXhwb3J0cy5CdWZmZXIgPSBCdWZmZXJcbmV4cG9ydHMuU2xvd0J1ZmZlciA9IFNsb3dCdWZmZXJcbmV4cG9ydHMuSU5TUEVDVF9NQVhfQllURVMgPSA1MFxuXG52YXIgS19NQVhfTEVOR1RIID0gMHg3ZmZmZmZmZlxuZXhwb3J0cy5rTWF4TGVuZ3RoID0gS19NQVhfTEVOR1RIXG5cbi8qKlxuICogSWYgYEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUYDpcbiAqICAgPT09IHRydWUgICAgVXNlIFVpbnQ4QXJyYXkgaW1wbGVtZW50YXRpb24gKGZhc3Rlc3QpXG4gKiAgID09PSBmYWxzZSAgIFByaW50IHdhcm5pbmcgYW5kIHJlY29tbWVuZCB1c2luZyBgYnVmZmVyYCB2NC54IHdoaWNoIGhhcyBhbiBPYmplY3RcbiAqICAgICAgICAgICAgICAgaW1wbGVtZW50YXRpb24gKG1vc3QgY29tcGF0aWJsZSwgZXZlbiBJRTYpXG4gKlxuICogQnJvd3NlcnMgdGhhdCBzdXBwb3J0IHR5cGVkIGFycmF5cyBhcmUgSUUgMTArLCBGaXJlZm94IDQrLCBDaHJvbWUgNyssIFNhZmFyaSA1LjErLFxuICogT3BlcmEgMTEuNissIGlPUyA0LjIrLlxuICpcbiAqIFdlIHJlcG9ydCB0aGF0IHRoZSBicm93c2VyIGRvZXMgbm90IHN1cHBvcnQgdHlwZWQgYXJyYXlzIGlmIHRoZSBhcmUgbm90IHN1YmNsYXNzYWJsZVxuICogdXNpbmcgX19wcm90b19fLiBGaXJlZm94IDQtMjkgbGFja3Mgc3VwcG9ydCBmb3IgYWRkaW5nIG5ldyBwcm9wZXJ0aWVzIHRvIGBVaW50OEFycmF5YFxuICogKFNlZTogaHR0cHM6Ly9idWd6aWxsYS5tb3ppbGxhLm9yZy9zaG93X2J1Zy5jZ2k/aWQ9Njk1NDM4KS4gSUUgMTAgbGFja3Mgc3VwcG9ydFxuICogZm9yIF9fcHJvdG9fXyBhbmQgaGFzIGEgYnVnZ3kgdHlwZWQgYXJyYXkgaW1wbGVtZW50YXRpb24uXG4gKi9cbkJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUID0gdHlwZWRBcnJheVN1cHBvcnQoKVxuXG5pZiAoIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUICYmIHR5cGVvZiBjb25zb2xlICE9PSAndW5kZWZpbmVkJyAmJlxuICAgIHR5cGVvZiBjb25zb2xlLmVycm9yID09PSAnZnVuY3Rpb24nKSB7XG4gIGNvbnNvbGUuZXJyb3IoXG4gICAgJ1RoaXMgYnJvd3NlciBsYWNrcyB0eXBlZCBhcnJheSAoVWludDhBcnJheSkgc3VwcG9ydCB3aGljaCBpcyByZXF1aXJlZCBieSAnICtcbiAgICAnYGJ1ZmZlcmAgdjUueC4gVXNlIGBidWZmZXJgIHY0LnggaWYgeW91IHJlcXVpcmUgb2xkIGJyb3dzZXIgc3VwcG9ydC4nXG4gIClcbn1cblxuZnVuY3Rpb24gdHlwZWRBcnJheVN1cHBvcnQgKCkge1xuICAvLyBDYW4gdHlwZWQgYXJyYXkgaW5zdGFuY2VzIGNhbiBiZSBhdWdtZW50ZWQ/XG4gIHRyeSB7XG4gICAgdmFyIGFyciA9IG5ldyBVaW50OEFycmF5KDEpXG4gICAgYXJyLl9fcHJvdG9fXyA9IHsgX19wcm90b19fOiBVaW50OEFycmF5LnByb3RvdHlwZSwgZm9vOiBmdW5jdGlvbiAoKSB7IHJldHVybiA0MiB9IH1cbiAgICByZXR1cm4gYXJyLmZvbygpID09PSA0MlxuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cbn1cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KEJ1ZmZlci5wcm90b3R5cGUsICdwYXJlbnQnLCB7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIGlmICghQnVmZmVyLmlzQnVmZmVyKHRoaXMpKSByZXR1cm4gdW5kZWZpbmVkXG4gICAgcmV0dXJuIHRoaXMuYnVmZmVyXG4gIH1cbn0pXG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShCdWZmZXIucHJvdG90eXBlLCAnb2Zmc2V0Jywge1xuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcih0aGlzKSkgcmV0dXJuIHVuZGVmaW5lZFxuICAgIHJldHVybiB0aGlzLmJ5dGVPZmZzZXRcbiAgfVxufSlcblxuZnVuY3Rpb24gY3JlYXRlQnVmZmVyIChsZW5ndGgpIHtcbiAgaWYgKGxlbmd0aCA+IEtfTUFYX0xFTkdUSCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdUaGUgdmFsdWUgXCInICsgbGVuZ3RoICsgJ1wiIGlzIGludmFsaWQgZm9yIG9wdGlvbiBcInNpemVcIicpXG4gIH1cbiAgLy8gUmV0dXJuIGFuIGF1Z21lbnRlZCBgVWludDhBcnJheWAgaW5zdGFuY2VcbiAgdmFyIGJ1ZiA9IG5ldyBVaW50OEFycmF5KGxlbmd0aClcbiAgYnVmLl9fcHJvdG9fXyA9IEJ1ZmZlci5wcm90b3R5cGVcbiAgcmV0dXJuIGJ1ZlxufVxuXG4vKipcbiAqIFRoZSBCdWZmZXIgY29uc3RydWN0b3IgcmV0dXJucyBpbnN0YW5jZXMgb2YgYFVpbnQ4QXJyYXlgIHRoYXQgaGF2ZSB0aGVpclxuICogcHJvdG90eXBlIGNoYW5nZWQgdG8gYEJ1ZmZlci5wcm90b3R5cGVgLiBGdXJ0aGVybW9yZSwgYEJ1ZmZlcmAgaXMgYSBzdWJjbGFzcyBvZlxuICogYFVpbnQ4QXJyYXlgLCBzbyB0aGUgcmV0dXJuZWQgaW5zdGFuY2VzIHdpbGwgaGF2ZSBhbGwgdGhlIG5vZGUgYEJ1ZmZlcmAgbWV0aG9kc1xuICogYW5kIHRoZSBgVWludDhBcnJheWAgbWV0aG9kcy4gU3F1YXJlIGJyYWNrZXQgbm90YXRpb24gd29ya3MgYXMgZXhwZWN0ZWQgLS0gaXRcbiAqIHJldHVybnMgYSBzaW5nbGUgb2N0ZXQuXG4gKlxuICogVGhlIGBVaW50OEFycmF5YCBwcm90b3R5cGUgcmVtYWlucyB1bm1vZGlmaWVkLlxuICovXG5cbmZ1bmN0aW9uIEJ1ZmZlciAoYXJnLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpIHtcbiAgLy8gQ29tbW9uIGNhc2UuXG4gIGlmICh0eXBlb2YgYXJnID09PSAnbnVtYmVyJykge1xuICAgIGlmICh0eXBlb2YgZW5jb2RpbmdPck9mZnNldCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICAgICdUaGUgXCJzdHJpbmdcIiBhcmd1bWVudCBtdXN0IGJlIG9mIHR5cGUgc3RyaW5nLiBSZWNlaXZlZCB0eXBlIG51bWJlcidcbiAgICAgIClcbiAgICB9XG4gICAgcmV0dXJuIGFsbG9jVW5zYWZlKGFyZylcbiAgfVxuICByZXR1cm4gZnJvbShhcmcsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aClcbn1cblxuLy8gRml4IHN1YmFycmF5KCkgaW4gRVMyMDE2LiBTZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9mZXJvc3MvYnVmZmVyL3B1bGwvOTdcbmlmICh0eXBlb2YgU3ltYm9sICE9PSAndW5kZWZpbmVkJyAmJiBTeW1ib2wuc3BlY2llcyAhPSBudWxsICYmXG4gICAgQnVmZmVyW1N5bWJvbC5zcGVjaWVzXSA9PT0gQnVmZmVyKSB7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShCdWZmZXIsIFN5bWJvbC5zcGVjaWVzLCB7XG4gICAgdmFsdWU6IG51bGwsXG4gICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgIHdyaXRhYmxlOiBmYWxzZVxuICB9KVxufVxuXG5CdWZmZXIucG9vbFNpemUgPSA4MTkyIC8vIG5vdCB1c2VkIGJ5IHRoaXMgaW1wbGVtZW50YXRpb25cblxuZnVuY3Rpb24gZnJvbSAodmFsdWUsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aCkge1xuICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBmcm9tU3RyaW5nKHZhbHVlLCBlbmNvZGluZ09yT2Zmc2V0KVxuICB9XG5cbiAgaWYgKEFycmF5QnVmZmVyLmlzVmlldyh2YWx1ZSkpIHtcbiAgICByZXR1cm4gZnJvbUFycmF5TGlrZSh2YWx1ZSlcbiAgfVxuXG4gIGlmICh2YWx1ZSA9PSBudWxsKSB7XG4gICAgdGhyb3cgVHlwZUVycm9yKFxuICAgICAgJ1RoZSBmaXJzdCBhcmd1bWVudCBtdXN0IGJlIG9uZSBvZiB0eXBlIHN0cmluZywgQnVmZmVyLCBBcnJheUJ1ZmZlciwgQXJyYXksICcgK1xuICAgICAgJ29yIEFycmF5LWxpa2UgT2JqZWN0LiBSZWNlaXZlZCB0eXBlICcgKyAodHlwZW9mIHZhbHVlKVxuICAgIClcbiAgfVxuXG4gIGlmIChpc0luc3RhbmNlKHZhbHVlLCBBcnJheUJ1ZmZlcikgfHxcbiAgICAgICh2YWx1ZSAmJiBpc0luc3RhbmNlKHZhbHVlLmJ1ZmZlciwgQXJyYXlCdWZmZXIpKSkge1xuICAgIHJldHVybiBmcm9tQXJyYXlCdWZmZXIodmFsdWUsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aClcbiAgfVxuXG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgICdUaGUgXCJ2YWx1ZVwiIGFyZ3VtZW50IG11c3Qgbm90IGJlIG9mIHR5cGUgbnVtYmVyLiBSZWNlaXZlZCB0eXBlIG51bWJlcidcbiAgICApXG4gIH1cblxuICB2YXIgdmFsdWVPZiA9IHZhbHVlLnZhbHVlT2YgJiYgdmFsdWUudmFsdWVPZigpXG4gIGlmICh2YWx1ZU9mICE9IG51bGwgJiYgdmFsdWVPZiAhPT0gdmFsdWUpIHtcbiAgICByZXR1cm4gQnVmZmVyLmZyb20odmFsdWVPZiwgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKVxuICB9XG5cbiAgdmFyIGIgPSBmcm9tT2JqZWN0KHZhbHVlKVxuICBpZiAoYikgcmV0dXJuIGJcblxuICBpZiAodHlwZW9mIFN5bWJvbCAhPT0gJ3VuZGVmaW5lZCcgJiYgU3ltYm9sLnRvUHJpbWl0aXZlICE9IG51bGwgJiZcbiAgICAgIHR5cGVvZiB2YWx1ZVtTeW1ib2wudG9QcmltaXRpdmVdID09PSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuIEJ1ZmZlci5mcm9tKFxuICAgICAgdmFsdWVbU3ltYm9sLnRvUHJpbWl0aXZlXSgnc3RyaW5nJyksIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aFxuICAgIClcbiAgfVxuXG4gIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgJ1RoZSBmaXJzdCBhcmd1bWVudCBtdXN0IGJlIG9uZSBvZiB0eXBlIHN0cmluZywgQnVmZmVyLCBBcnJheUJ1ZmZlciwgQXJyYXksICcgK1xuICAgICdvciBBcnJheS1saWtlIE9iamVjdC4gUmVjZWl2ZWQgdHlwZSAnICsgKHR5cGVvZiB2YWx1ZSlcbiAgKVxufVxuXG4vKipcbiAqIEZ1bmN0aW9uYWxseSBlcXVpdmFsZW50IHRvIEJ1ZmZlcihhcmcsIGVuY29kaW5nKSBidXQgdGhyb3dzIGEgVHlwZUVycm9yXG4gKiBpZiB2YWx1ZSBpcyBhIG51bWJlci5cbiAqIEJ1ZmZlci5mcm9tKHN0clssIGVuY29kaW5nXSlcbiAqIEJ1ZmZlci5mcm9tKGFycmF5KVxuICogQnVmZmVyLmZyb20oYnVmZmVyKVxuICogQnVmZmVyLmZyb20oYXJyYXlCdWZmZXJbLCBieXRlT2Zmc2V0WywgbGVuZ3RoXV0pXG4gKiovXG5CdWZmZXIuZnJvbSA9IGZ1bmN0aW9uICh2YWx1ZSwgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBmcm9tKHZhbHVlLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpXG59XG5cbi8vIE5vdGU6IENoYW5nZSBwcm90b3R5cGUgKmFmdGVyKiBCdWZmZXIuZnJvbSBpcyBkZWZpbmVkIHRvIHdvcmthcm91bmQgQ2hyb21lIGJ1Zzpcbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9mZXJvc3MvYnVmZmVyL3B1bGwvMTQ4XG5CdWZmZXIucHJvdG90eXBlLl9fcHJvdG9fXyA9IFVpbnQ4QXJyYXkucHJvdG90eXBlXG5CdWZmZXIuX19wcm90b19fID0gVWludDhBcnJheVxuXG5mdW5jdGlvbiBhc3NlcnRTaXplIChzaXplKSB7XG4gIGlmICh0eXBlb2Ygc2l6ZSAhPT0gJ251bWJlcicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcInNpemVcIiBhcmd1bWVudCBtdXN0IGJlIG9mIHR5cGUgbnVtYmVyJylcbiAgfSBlbHNlIGlmIChzaXplIDwgMCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdUaGUgdmFsdWUgXCInICsgc2l6ZSArICdcIiBpcyBpbnZhbGlkIGZvciBvcHRpb24gXCJzaXplXCInKVxuICB9XG59XG5cbmZ1bmN0aW9uIGFsbG9jIChzaXplLCBmaWxsLCBlbmNvZGluZykge1xuICBhc3NlcnRTaXplKHNpemUpXG4gIGlmIChzaXplIDw9IDApIHtcbiAgICByZXR1cm4gY3JlYXRlQnVmZmVyKHNpemUpXG4gIH1cbiAgaWYgKGZpbGwgIT09IHVuZGVmaW5lZCkge1xuICAgIC8vIE9ubHkgcGF5IGF0dGVudGlvbiB0byBlbmNvZGluZyBpZiBpdCdzIGEgc3RyaW5nLiBUaGlzXG4gICAgLy8gcHJldmVudHMgYWNjaWRlbnRhbGx5IHNlbmRpbmcgaW4gYSBudW1iZXIgdGhhdCB3b3VsZFxuICAgIC8vIGJlIGludGVycHJldHRlZCBhcyBhIHN0YXJ0IG9mZnNldC5cbiAgICByZXR1cm4gdHlwZW9mIGVuY29kaW5nID09PSAnc3RyaW5nJ1xuICAgICAgPyBjcmVhdGVCdWZmZXIoc2l6ZSkuZmlsbChmaWxsLCBlbmNvZGluZylcbiAgICAgIDogY3JlYXRlQnVmZmVyKHNpemUpLmZpbGwoZmlsbClcbiAgfVxuICByZXR1cm4gY3JlYXRlQnVmZmVyKHNpemUpXG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyBmaWxsZWQgQnVmZmVyIGluc3RhbmNlLlxuICogYWxsb2Moc2l6ZVssIGZpbGxbLCBlbmNvZGluZ11dKVxuICoqL1xuQnVmZmVyLmFsbG9jID0gZnVuY3Rpb24gKHNpemUsIGZpbGwsIGVuY29kaW5nKSB7XG4gIHJldHVybiBhbGxvYyhzaXplLCBmaWxsLCBlbmNvZGluZylcbn1cblxuZnVuY3Rpb24gYWxsb2NVbnNhZmUgKHNpemUpIHtcbiAgYXNzZXJ0U2l6ZShzaXplKVxuICByZXR1cm4gY3JlYXRlQnVmZmVyKHNpemUgPCAwID8gMCA6IGNoZWNrZWQoc2l6ZSkgfCAwKVxufVxuXG4vKipcbiAqIEVxdWl2YWxlbnQgdG8gQnVmZmVyKG51bSksIGJ5IGRlZmF1bHQgY3JlYXRlcyBhIG5vbi16ZXJvLWZpbGxlZCBCdWZmZXIgaW5zdGFuY2UuXG4gKiAqL1xuQnVmZmVyLmFsbG9jVW5zYWZlID0gZnVuY3Rpb24gKHNpemUpIHtcbiAgcmV0dXJuIGFsbG9jVW5zYWZlKHNpemUpXG59XG4vKipcbiAqIEVxdWl2YWxlbnQgdG8gU2xvd0J1ZmZlcihudW0pLCBieSBkZWZhdWx0IGNyZWF0ZXMgYSBub24temVyby1maWxsZWQgQnVmZmVyIGluc3RhbmNlLlxuICovXG5CdWZmZXIuYWxsb2NVbnNhZmVTbG93ID0gZnVuY3Rpb24gKHNpemUpIHtcbiAgcmV0dXJuIGFsbG9jVW5zYWZlKHNpemUpXG59XG5cbmZ1bmN0aW9uIGZyb21TdHJpbmcgKHN0cmluZywgZW5jb2RpbmcpIHtcbiAgaWYgKHR5cGVvZiBlbmNvZGluZyAhPT0gJ3N0cmluZycgfHwgZW5jb2RpbmcgPT09ICcnKSB7XG4gICAgZW5jb2RpbmcgPSAndXRmOCdcbiAgfVxuXG4gIGlmICghQnVmZmVyLmlzRW5jb2RpbmcoZW5jb2RpbmcpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVW5rbm93biBlbmNvZGluZzogJyArIGVuY29kaW5nKVxuICB9XG5cbiAgdmFyIGxlbmd0aCA9IGJ5dGVMZW5ndGgoc3RyaW5nLCBlbmNvZGluZykgfCAwXG4gIHZhciBidWYgPSBjcmVhdGVCdWZmZXIobGVuZ3RoKVxuXG4gIHZhciBhY3R1YWwgPSBidWYud3JpdGUoc3RyaW5nLCBlbmNvZGluZylcblxuICBpZiAoYWN0dWFsICE9PSBsZW5ndGgpIHtcbiAgICAvLyBXcml0aW5nIGEgaGV4IHN0cmluZywgZm9yIGV4YW1wbGUsIHRoYXQgY29udGFpbnMgaW52YWxpZCBjaGFyYWN0ZXJzIHdpbGxcbiAgICAvLyBjYXVzZSBldmVyeXRoaW5nIGFmdGVyIHRoZSBmaXJzdCBpbnZhbGlkIGNoYXJhY3RlciB0byBiZSBpZ25vcmVkLiAoZS5nLlxuICAgIC8vICdhYnh4Y2QnIHdpbGwgYmUgdHJlYXRlZCBhcyAnYWInKVxuICAgIGJ1ZiA9IGJ1Zi5zbGljZSgwLCBhY3R1YWwpXG4gIH1cblxuICByZXR1cm4gYnVmXG59XG5cbmZ1bmN0aW9uIGZyb21BcnJheUxpa2UgKGFycmF5KSB7XG4gIHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGggPCAwID8gMCA6IGNoZWNrZWQoYXJyYXkubGVuZ3RoKSB8IDBcbiAgdmFyIGJ1ZiA9IGNyZWF0ZUJ1ZmZlcihsZW5ndGgpXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpICs9IDEpIHtcbiAgICBidWZbaV0gPSBhcnJheVtpXSAmIDI1NVxuICB9XG4gIHJldHVybiBidWZcbn1cblxuZnVuY3Rpb24gZnJvbUFycmF5QnVmZmVyIChhcnJheSwgYnl0ZU9mZnNldCwgbGVuZ3RoKSB7XG4gIGlmIChieXRlT2Zmc2V0IDwgMCB8fCBhcnJheS5ieXRlTGVuZ3RoIDwgYnl0ZU9mZnNldCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdcIm9mZnNldFwiIGlzIG91dHNpZGUgb2YgYnVmZmVyIGJvdW5kcycpXG4gIH1cblxuICBpZiAoYXJyYXkuYnl0ZUxlbmd0aCA8IGJ5dGVPZmZzZXQgKyAobGVuZ3RoIHx8IDApKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1wibGVuZ3RoXCIgaXMgb3V0c2lkZSBvZiBidWZmZXIgYm91bmRzJylcbiAgfVxuXG4gIHZhciBidWZcbiAgaWYgKGJ5dGVPZmZzZXQgPT09IHVuZGVmaW5lZCAmJiBsZW5ndGggPT09IHVuZGVmaW5lZCkge1xuICAgIGJ1ZiA9IG5ldyBVaW50OEFycmF5KGFycmF5KVxuICB9IGVsc2UgaWYgKGxlbmd0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgYnVmID0gbmV3IFVpbnQ4QXJyYXkoYXJyYXksIGJ5dGVPZmZzZXQpXG4gIH0gZWxzZSB7XG4gICAgYnVmID0gbmV3IFVpbnQ4QXJyYXkoYXJyYXksIGJ5dGVPZmZzZXQsIGxlbmd0aClcbiAgfVxuXG4gIC8vIFJldHVybiBhbiBhdWdtZW50ZWQgYFVpbnQ4QXJyYXlgIGluc3RhbmNlXG4gIGJ1Zi5fX3Byb3RvX18gPSBCdWZmZXIucHJvdG90eXBlXG4gIHJldHVybiBidWZcbn1cblxuZnVuY3Rpb24gZnJvbU9iamVjdCAob2JqKSB7XG4gIGlmIChCdWZmZXIuaXNCdWZmZXIob2JqKSkge1xuICAgIHZhciBsZW4gPSBjaGVja2VkKG9iai5sZW5ndGgpIHwgMFxuICAgIHZhciBidWYgPSBjcmVhdGVCdWZmZXIobGVuKVxuXG4gICAgaWYgKGJ1Zi5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBidWZcbiAgICB9XG5cbiAgICBvYmouY29weShidWYsIDAsIDAsIGxlbilcbiAgICByZXR1cm4gYnVmXG4gIH1cblxuICBpZiAob2JqLmxlbmd0aCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgaWYgKHR5cGVvZiBvYmoubGVuZ3RoICE9PSAnbnVtYmVyJyB8fCBudW1iZXJJc05hTihvYmoubGVuZ3RoKSkge1xuICAgICAgcmV0dXJuIGNyZWF0ZUJ1ZmZlcigwKVxuICAgIH1cbiAgICByZXR1cm4gZnJvbUFycmF5TGlrZShvYmopXG4gIH1cblxuICBpZiAob2JqLnR5cGUgPT09ICdCdWZmZXInICYmIEFycmF5LmlzQXJyYXkob2JqLmRhdGEpKSB7XG4gICAgcmV0dXJuIGZyb21BcnJheUxpa2Uob2JqLmRhdGEpXG4gIH1cbn1cblxuZnVuY3Rpb24gY2hlY2tlZCAobGVuZ3RoKSB7XG4gIC8vIE5vdGU6IGNhbm5vdCB1c2UgYGxlbmd0aCA8IEtfTUFYX0xFTkdUSGAgaGVyZSBiZWNhdXNlIHRoYXQgZmFpbHMgd2hlblxuICAvLyBsZW5ndGggaXMgTmFOICh3aGljaCBpcyBvdGhlcndpc2UgY29lcmNlZCB0byB6ZXJvLilcbiAgaWYgKGxlbmd0aCA+PSBLX01BWF9MRU5HVEgpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignQXR0ZW1wdCB0byBhbGxvY2F0ZSBCdWZmZXIgbGFyZ2VyIHRoYW4gbWF4aW11bSAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAnc2l6ZTogMHgnICsgS19NQVhfTEVOR1RILnRvU3RyaW5nKDE2KSArICcgYnl0ZXMnKVxuICB9XG4gIHJldHVybiBsZW5ndGggfCAwXG59XG5cbmZ1bmN0aW9uIFNsb3dCdWZmZXIgKGxlbmd0aCkge1xuICBpZiAoK2xlbmd0aCAhPSBsZW5ndGgpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBlcWVxZXFcbiAgICBsZW5ndGggPSAwXG4gIH1cbiAgcmV0dXJuIEJ1ZmZlci5hbGxvYygrbGVuZ3RoKVxufVxuXG5CdWZmZXIuaXNCdWZmZXIgPSBmdW5jdGlvbiBpc0J1ZmZlciAoYikge1xuICByZXR1cm4gYiAhPSBudWxsICYmIGIuX2lzQnVmZmVyID09PSB0cnVlICYmXG4gICAgYiAhPT0gQnVmZmVyLnByb3RvdHlwZSAvLyBzbyBCdWZmZXIuaXNCdWZmZXIoQnVmZmVyLnByb3RvdHlwZSkgd2lsbCBiZSBmYWxzZVxufVxuXG5CdWZmZXIuY29tcGFyZSA9IGZ1bmN0aW9uIGNvbXBhcmUgKGEsIGIpIHtcbiAgaWYgKGlzSW5zdGFuY2UoYSwgVWludDhBcnJheSkpIGEgPSBCdWZmZXIuZnJvbShhLCBhLm9mZnNldCwgYS5ieXRlTGVuZ3RoKVxuICBpZiAoaXNJbnN0YW5jZShiLCBVaW50OEFycmF5KSkgYiA9IEJ1ZmZlci5mcm9tKGIsIGIub2Zmc2V0LCBiLmJ5dGVMZW5ndGgpXG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGEpIHx8ICFCdWZmZXIuaXNCdWZmZXIoYikpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgJ1RoZSBcImJ1ZjFcIiwgXCJidWYyXCIgYXJndW1lbnRzIG11c3QgYmUgb25lIG9mIHR5cGUgQnVmZmVyIG9yIFVpbnQ4QXJyYXknXG4gICAgKVxuICB9XG5cbiAgaWYgKGEgPT09IGIpIHJldHVybiAwXG5cbiAgdmFyIHggPSBhLmxlbmd0aFxuICB2YXIgeSA9IGIubGVuZ3RoXG5cbiAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IE1hdGgubWluKHgsIHkpOyBpIDwgbGVuOyArK2kpIHtcbiAgICBpZiAoYVtpXSAhPT0gYltpXSkge1xuICAgICAgeCA9IGFbaV1cbiAgICAgIHkgPSBiW2ldXG4gICAgICBicmVha1xuICAgIH1cbiAgfVxuXG4gIGlmICh4IDwgeSkgcmV0dXJuIC0xXG4gIGlmICh5IDwgeCkgcmV0dXJuIDFcbiAgcmV0dXJuIDBcbn1cblxuQnVmZmVyLmlzRW5jb2RpbmcgPSBmdW5jdGlvbiBpc0VuY29kaW5nIChlbmNvZGluZykge1xuICBzd2l0Y2ggKFN0cmluZyhlbmNvZGluZykudG9Mb3dlckNhc2UoKSkge1xuICAgIGNhc2UgJ2hleCc6XG4gICAgY2FzZSAndXRmOCc6XG4gICAgY2FzZSAndXRmLTgnOlxuICAgIGNhc2UgJ2FzY2lpJzpcbiAgICBjYXNlICdsYXRpbjEnOlxuICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgY2FzZSAnYmFzZTY0JzpcbiAgICBjYXNlICd1Y3MyJzpcbiAgICBjYXNlICd1Y3MtMic6XG4gICAgY2FzZSAndXRmMTZsZSc6XG4gICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgcmV0dXJuIHRydWVcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIGZhbHNlXG4gIH1cbn1cblxuQnVmZmVyLmNvbmNhdCA9IGZ1bmN0aW9uIGNvbmNhdCAobGlzdCwgbGVuZ3RoKSB7XG4gIGlmICghQXJyYXkuaXNBcnJheShsaXN0KSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wibGlzdFwiIGFyZ3VtZW50IG11c3QgYmUgYW4gQXJyYXkgb2YgQnVmZmVycycpXG4gIH1cblxuICBpZiAobGlzdC5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gQnVmZmVyLmFsbG9jKDApXG4gIH1cblxuICB2YXIgaVxuICBpZiAobGVuZ3RoID09PSB1bmRlZmluZWQpIHtcbiAgICBsZW5ndGggPSAwXG4gICAgZm9yIChpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyArK2kpIHtcbiAgICAgIGxlbmd0aCArPSBsaXN0W2ldLmxlbmd0aFxuICAgIH1cbiAgfVxuXG4gIHZhciBidWZmZXIgPSBCdWZmZXIuYWxsb2NVbnNhZmUobGVuZ3RoKVxuICB2YXIgcG9zID0gMFxuICBmb3IgKGkgPSAwOyBpIDwgbGlzdC5sZW5ndGg7ICsraSkge1xuICAgIHZhciBidWYgPSBsaXN0W2ldXG4gICAgaWYgKGlzSW5zdGFuY2UoYnVmLCBVaW50OEFycmF5KSkge1xuICAgICAgYnVmID0gQnVmZmVyLmZyb20oYnVmKVxuICAgIH1cbiAgICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihidWYpKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RcIiBhcmd1bWVudCBtdXN0IGJlIGFuIEFycmF5IG9mIEJ1ZmZlcnMnKVxuICAgIH1cbiAgICBidWYuY29weShidWZmZXIsIHBvcylcbiAgICBwb3MgKz0gYnVmLmxlbmd0aFxuICB9XG4gIHJldHVybiBidWZmZXJcbn1cblxuZnVuY3Rpb24gYnl0ZUxlbmd0aCAoc3RyaW5nLCBlbmNvZGluZykge1xuICBpZiAoQnVmZmVyLmlzQnVmZmVyKHN0cmluZykpIHtcbiAgICByZXR1cm4gc3RyaW5nLmxlbmd0aFxuICB9XG4gIGlmIChBcnJheUJ1ZmZlci5pc1ZpZXcoc3RyaW5nKSB8fCBpc0luc3RhbmNlKHN0cmluZywgQXJyYXlCdWZmZXIpKSB7XG4gICAgcmV0dXJuIHN0cmluZy5ieXRlTGVuZ3RoXG4gIH1cbiAgaWYgKHR5cGVvZiBzdHJpbmcgIT09ICdzdHJpbmcnKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgICdUaGUgXCJzdHJpbmdcIiBhcmd1bWVudCBtdXN0IGJlIG9uZSBvZiB0eXBlIHN0cmluZywgQnVmZmVyLCBvciBBcnJheUJ1ZmZlci4gJyArXG4gICAgICAnUmVjZWl2ZWQgdHlwZSAnICsgdHlwZW9mIHN0cmluZ1xuICAgIClcbiAgfVxuXG4gIHZhciBsZW4gPSBzdHJpbmcubGVuZ3RoXG4gIHZhciBtdXN0TWF0Y2ggPSAoYXJndW1lbnRzLmxlbmd0aCA+IDIgJiYgYXJndW1lbnRzWzJdID09PSB0cnVlKVxuICBpZiAoIW11c3RNYXRjaCAmJiBsZW4gPT09IDApIHJldHVybiAwXG5cbiAgLy8gVXNlIGEgZm9yIGxvb3AgdG8gYXZvaWQgcmVjdXJzaW9uXG4gIHZhciBsb3dlcmVkQ2FzZSA9IGZhbHNlXG4gIGZvciAoOzspIHtcbiAgICBzd2l0Y2ggKGVuY29kaW5nKSB7XG4gICAgICBjYXNlICdhc2NpaSc6XG4gICAgICBjYXNlICdsYXRpbjEnOlxuICAgICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgICAgcmV0dXJuIGxlblxuICAgICAgY2FzZSAndXRmOCc6XG4gICAgICBjYXNlICd1dGYtOCc6XG4gICAgICAgIHJldHVybiB1dGY4VG9CeXRlcyhzdHJpbmcpLmxlbmd0aFxuICAgICAgY2FzZSAndWNzMic6XG4gICAgICBjYXNlICd1Y3MtMic6XG4gICAgICBjYXNlICd1dGYxNmxlJzpcbiAgICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgICAgcmV0dXJuIGxlbiAqIDJcbiAgICAgIGNhc2UgJ2hleCc6XG4gICAgICAgIHJldHVybiBsZW4gPj4+IDFcbiAgICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICAgIHJldHVybiBiYXNlNjRUb0J5dGVzKHN0cmluZykubGVuZ3RoXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpZiAobG93ZXJlZENhc2UpIHtcbiAgICAgICAgICByZXR1cm4gbXVzdE1hdGNoID8gLTEgOiB1dGY4VG9CeXRlcyhzdHJpbmcpLmxlbmd0aCAvLyBhc3N1bWUgdXRmOFxuICAgICAgICB9XG4gICAgICAgIGVuY29kaW5nID0gKCcnICsgZW5jb2RpbmcpLnRvTG93ZXJDYXNlKClcbiAgICAgICAgbG93ZXJlZENhc2UgPSB0cnVlXG4gICAgfVxuICB9XG59XG5CdWZmZXIuYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGhcblxuZnVuY3Rpb24gc2xvd1RvU3RyaW5nIChlbmNvZGluZywgc3RhcnQsIGVuZCkge1xuICB2YXIgbG93ZXJlZENhc2UgPSBmYWxzZVxuXG4gIC8vIE5vIG5lZWQgdG8gdmVyaWZ5IHRoYXQgXCJ0aGlzLmxlbmd0aCA8PSBNQVhfVUlOVDMyXCIgc2luY2UgaXQncyBhIHJlYWQtb25seVxuICAvLyBwcm9wZXJ0eSBvZiBhIHR5cGVkIGFycmF5LlxuXG4gIC8vIFRoaXMgYmVoYXZlcyBuZWl0aGVyIGxpa2UgU3RyaW5nIG5vciBVaW50OEFycmF5IGluIHRoYXQgd2Ugc2V0IHN0YXJ0L2VuZFxuICAvLyB0byB0aGVpciB1cHBlci9sb3dlciBib3VuZHMgaWYgdGhlIHZhbHVlIHBhc3NlZCBpcyBvdXQgb2YgcmFuZ2UuXG4gIC8vIHVuZGVmaW5lZCBpcyBoYW5kbGVkIHNwZWNpYWxseSBhcyBwZXIgRUNNQS0yNjIgNnRoIEVkaXRpb24sXG4gIC8vIFNlY3Rpb24gMTMuMy4zLjcgUnVudGltZSBTZW1hbnRpY3M6IEtleWVkQmluZGluZ0luaXRpYWxpemF0aW9uLlxuICBpZiAoc3RhcnQgPT09IHVuZGVmaW5lZCB8fCBzdGFydCA8IDApIHtcbiAgICBzdGFydCA9IDBcbiAgfVxuICAvLyBSZXR1cm4gZWFybHkgaWYgc3RhcnQgPiB0aGlzLmxlbmd0aC4gRG9uZSBoZXJlIHRvIHByZXZlbnQgcG90ZW50aWFsIHVpbnQzMlxuICAvLyBjb2VyY2lvbiBmYWlsIGJlbG93LlxuICBpZiAoc3RhcnQgPiB0aGlzLmxlbmd0aCkge1xuICAgIHJldHVybiAnJ1xuICB9XG5cbiAgaWYgKGVuZCA9PT0gdW5kZWZpbmVkIHx8IGVuZCA+IHRoaXMubGVuZ3RoKSB7XG4gICAgZW5kID0gdGhpcy5sZW5ndGhcbiAgfVxuXG4gIGlmIChlbmQgPD0gMCkge1xuICAgIHJldHVybiAnJ1xuICB9XG5cbiAgLy8gRm9yY2UgY29lcnNpb24gdG8gdWludDMyLiBUaGlzIHdpbGwgYWxzbyBjb2VyY2UgZmFsc2V5L05hTiB2YWx1ZXMgdG8gMC5cbiAgZW5kID4+Pj0gMFxuICBzdGFydCA+Pj49IDBcblxuICBpZiAoZW5kIDw9IHN0YXJ0KSB7XG4gICAgcmV0dXJuICcnXG4gIH1cblxuICBpZiAoIWVuY29kaW5nKSBlbmNvZGluZyA9ICd1dGY4J1xuXG4gIHdoaWxlICh0cnVlKSB7XG4gICAgc3dpdGNoIChlbmNvZGluZykge1xuICAgICAgY2FzZSAnaGV4JzpcbiAgICAgICAgcmV0dXJuIGhleFNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgY2FzZSAndXRmLTgnOlxuICAgICAgICByZXR1cm4gdXRmOFNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ2FzY2lpJzpcbiAgICAgICAgcmV0dXJuIGFzY2lpU2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAnbGF0aW4xJzpcbiAgICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICAgIHJldHVybiBsYXRpbjFTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgICByZXR1cm4gYmFzZTY0U2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAndWNzMic6XG4gICAgICBjYXNlICd1Y3MtMic6XG4gICAgICBjYXNlICd1dGYxNmxlJzpcbiAgICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgICAgcmV0dXJuIHV0ZjE2bGVTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpZiAobG93ZXJlZENhc2UpIHRocm93IG5ldyBUeXBlRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmNvZGluZylcbiAgICAgICAgZW5jb2RpbmcgPSAoZW5jb2RpbmcgKyAnJykudG9Mb3dlckNhc2UoKVxuICAgICAgICBsb3dlcmVkQ2FzZSA9IHRydWVcbiAgICB9XG4gIH1cbn1cblxuLy8gVGhpcyBwcm9wZXJ0eSBpcyB1c2VkIGJ5IGBCdWZmZXIuaXNCdWZmZXJgIChhbmQgdGhlIGBpcy1idWZmZXJgIG5wbSBwYWNrYWdlKVxuLy8gdG8gZGV0ZWN0IGEgQnVmZmVyIGluc3RhbmNlLiBJdCdzIG5vdCBwb3NzaWJsZSB0byB1c2UgYGluc3RhbmNlb2YgQnVmZmVyYFxuLy8gcmVsaWFibHkgaW4gYSBicm93c2VyaWZ5IGNvbnRleHQgYmVjYXVzZSB0aGVyZSBjb3VsZCBiZSBtdWx0aXBsZSBkaWZmZXJlbnRcbi8vIGNvcGllcyBvZiB0aGUgJ2J1ZmZlcicgcGFja2FnZSBpbiB1c2UuIFRoaXMgbWV0aG9kIHdvcmtzIGV2ZW4gZm9yIEJ1ZmZlclxuLy8gaW5zdGFuY2VzIHRoYXQgd2VyZSBjcmVhdGVkIGZyb20gYW5vdGhlciBjb3B5IG9mIHRoZSBgYnVmZmVyYCBwYWNrYWdlLlxuLy8gU2VlOiBodHRwczovL2dpdGh1Yi5jb20vZmVyb3NzL2J1ZmZlci9pc3N1ZXMvMTU0XG5CdWZmZXIucHJvdG90eXBlLl9pc0J1ZmZlciA9IHRydWVcblxuZnVuY3Rpb24gc3dhcCAoYiwgbiwgbSkge1xuICB2YXIgaSA9IGJbbl1cbiAgYltuXSA9IGJbbV1cbiAgYlttXSA9IGlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5zd2FwMTYgPSBmdW5jdGlvbiBzd2FwMTYgKCkge1xuICB2YXIgbGVuID0gdGhpcy5sZW5ndGhcbiAgaWYgKGxlbiAlIDIgIT09IDApIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignQnVmZmVyIHNpemUgbXVzdCBiZSBhIG11bHRpcGxlIG9mIDE2LWJpdHMnKVxuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpICs9IDIpIHtcbiAgICBzd2FwKHRoaXMsIGksIGkgKyAxKVxuICB9XG4gIHJldHVybiB0aGlzXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuc3dhcDMyID0gZnVuY3Rpb24gc3dhcDMyICgpIHtcbiAgdmFyIGxlbiA9IHRoaXMubGVuZ3RoXG4gIGlmIChsZW4gJSA0ICE9PSAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0J1ZmZlciBzaXplIG11c3QgYmUgYSBtdWx0aXBsZSBvZiAzMi1iaXRzJylcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSArPSA0KSB7XG4gICAgc3dhcCh0aGlzLCBpLCBpICsgMylcbiAgICBzd2FwKHRoaXMsIGkgKyAxLCBpICsgMilcbiAgfVxuICByZXR1cm4gdGhpc1xufVxuXG5CdWZmZXIucHJvdG90eXBlLnN3YXA2NCA9IGZ1bmN0aW9uIHN3YXA2NCAoKSB7XG4gIHZhciBsZW4gPSB0aGlzLmxlbmd0aFxuICBpZiAobGVuICUgOCAhPT0gMCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdCdWZmZXIgc2l6ZSBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgNjQtYml0cycpXG4gIH1cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkgKz0gOCkge1xuICAgIHN3YXAodGhpcywgaSwgaSArIDcpXG4gICAgc3dhcCh0aGlzLCBpICsgMSwgaSArIDYpXG4gICAgc3dhcCh0aGlzLCBpICsgMiwgaSArIDUpXG4gICAgc3dhcCh0aGlzLCBpICsgMywgaSArIDQpXG4gIH1cbiAgcmV0dXJuIHRoaXNcbn1cblxuQnVmZmVyLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nICgpIHtcbiAgdmFyIGxlbmd0aCA9IHRoaXMubGVuZ3RoXG4gIGlmIChsZW5ndGggPT09IDApIHJldHVybiAnJ1xuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIHV0ZjhTbGljZSh0aGlzLCAwLCBsZW5ndGgpXG4gIHJldHVybiBzbG93VG9TdHJpbmcuYXBwbHkodGhpcywgYXJndW1lbnRzKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnRvTG9jYWxlU3RyaW5nID0gQnVmZmVyLnByb3RvdHlwZS50b1N0cmluZ1xuXG5CdWZmZXIucHJvdG90eXBlLmVxdWFscyA9IGZ1bmN0aW9uIGVxdWFscyAoYikge1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihiKSkgdGhyb3cgbmV3IFR5cGVFcnJvcignQXJndW1lbnQgbXVzdCBiZSBhIEJ1ZmZlcicpXG4gIGlmICh0aGlzID09PSBiKSByZXR1cm4gdHJ1ZVxuICByZXR1cm4gQnVmZmVyLmNvbXBhcmUodGhpcywgYikgPT09IDBcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5pbnNwZWN0ID0gZnVuY3Rpb24gaW5zcGVjdCAoKSB7XG4gIHZhciBzdHIgPSAnJ1xuICB2YXIgbWF4ID0gZXhwb3J0cy5JTlNQRUNUX01BWF9CWVRFU1xuICBzdHIgPSB0aGlzLnRvU3RyaW5nKCdoZXgnLCAwLCBtYXgpLnJlcGxhY2UoLyguezJ9KS9nLCAnJDEgJykudHJpbSgpXG4gIGlmICh0aGlzLmxlbmd0aCA+IG1heCkgc3RyICs9ICcgLi4uICdcbiAgcmV0dXJuICc8QnVmZmVyICcgKyBzdHIgKyAnPidcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5jb21wYXJlID0gZnVuY3Rpb24gY29tcGFyZSAodGFyZ2V0LCBzdGFydCwgZW5kLCB0aGlzU3RhcnQsIHRoaXNFbmQpIHtcbiAgaWYgKGlzSW5zdGFuY2UodGFyZ2V0LCBVaW50OEFycmF5KSkge1xuICAgIHRhcmdldCA9IEJ1ZmZlci5mcm9tKHRhcmdldCwgdGFyZ2V0Lm9mZnNldCwgdGFyZ2V0LmJ5dGVMZW5ndGgpXG4gIH1cbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIodGFyZ2V0KSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICAnVGhlIFwidGFyZ2V0XCIgYXJndW1lbnQgbXVzdCBiZSBvbmUgb2YgdHlwZSBCdWZmZXIgb3IgVWludDhBcnJheS4gJyArXG4gICAgICAnUmVjZWl2ZWQgdHlwZSAnICsgKHR5cGVvZiB0YXJnZXQpXG4gICAgKVxuICB9XG5cbiAgaWYgKHN0YXJ0ID09PSB1bmRlZmluZWQpIHtcbiAgICBzdGFydCA9IDBcbiAgfVxuICBpZiAoZW5kID09PSB1bmRlZmluZWQpIHtcbiAgICBlbmQgPSB0YXJnZXQgPyB0YXJnZXQubGVuZ3RoIDogMFxuICB9XG4gIGlmICh0aGlzU3RhcnQgPT09IHVuZGVmaW5lZCkge1xuICAgIHRoaXNTdGFydCA9IDBcbiAgfVxuICBpZiAodGhpc0VuZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgdGhpc0VuZCA9IHRoaXMubGVuZ3RoXG4gIH1cblxuICBpZiAoc3RhcnQgPCAwIHx8IGVuZCA+IHRhcmdldC5sZW5ndGggfHwgdGhpc1N0YXJ0IDwgMCB8fCB0aGlzRW5kID4gdGhpcy5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignb3V0IG9mIHJhbmdlIGluZGV4JylcbiAgfVxuXG4gIGlmICh0aGlzU3RhcnQgPj0gdGhpc0VuZCAmJiBzdGFydCA+PSBlbmQpIHtcbiAgICByZXR1cm4gMFxuICB9XG4gIGlmICh0aGlzU3RhcnQgPj0gdGhpc0VuZCkge1xuICAgIHJldHVybiAtMVxuICB9XG4gIGlmIChzdGFydCA+PSBlbmQpIHtcbiAgICByZXR1cm4gMVxuICB9XG5cbiAgc3RhcnQgPj4+PSAwXG4gIGVuZCA+Pj49IDBcbiAgdGhpc1N0YXJ0ID4+Pj0gMFxuICB0aGlzRW5kID4+Pj0gMFxuXG4gIGlmICh0aGlzID09PSB0YXJnZXQpIHJldHVybiAwXG5cbiAgdmFyIHggPSB0aGlzRW5kIC0gdGhpc1N0YXJ0XG4gIHZhciB5ID0gZW5kIC0gc3RhcnRcbiAgdmFyIGxlbiA9IE1hdGgubWluKHgsIHkpXG5cbiAgdmFyIHRoaXNDb3B5ID0gdGhpcy5zbGljZSh0aGlzU3RhcnQsIHRoaXNFbmQpXG4gIHZhciB0YXJnZXRDb3B5ID0gdGFyZ2V0LnNsaWNlKHN0YXJ0LCBlbmQpXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47ICsraSkge1xuICAgIGlmICh0aGlzQ29weVtpXSAhPT0gdGFyZ2V0Q29weVtpXSkge1xuICAgICAgeCA9IHRoaXNDb3B5W2ldXG4gICAgICB5ID0gdGFyZ2V0Q29weVtpXVxuICAgICAgYnJlYWtcbiAgICB9XG4gIH1cblxuICBpZiAoeCA8IHkpIHJldHVybiAtMVxuICBpZiAoeSA8IHgpIHJldHVybiAxXG4gIHJldHVybiAwXG59XG5cbi8vIEZpbmRzIGVpdGhlciB0aGUgZmlyc3QgaW5kZXggb2YgYHZhbGAgaW4gYGJ1ZmZlcmAgYXQgb2Zmc2V0ID49IGBieXRlT2Zmc2V0YCxcbi8vIE9SIHRoZSBsYXN0IGluZGV4IG9mIGB2YWxgIGluIGBidWZmZXJgIGF0IG9mZnNldCA8PSBgYnl0ZU9mZnNldGAuXG4vL1xuLy8gQXJndW1lbnRzOlxuLy8gLSBidWZmZXIgLSBhIEJ1ZmZlciB0byBzZWFyY2hcbi8vIC0gdmFsIC0gYSBzdHJpbmcsIEJ1ZmZlciwgb3IgbnVtYmVyXG4vLyAtIGJ5dGVPZmZzZXQgLSBhbiBpbmRleCBpbnRvIGBidWZmZXJgOyB3aWxsIGJlIGNsYW1wZWQgdG8gYW4gaW50MzJcbi8vIC0gZW5jb2RpbmcgLSBhbiBvcHRpb25hbCBlbmNvZGluZywgcmVsZXZhbnQgaXMgdmFsIGlzIGEgc3RyaW5nXG4vLyAtIGRpciAtIHRydWUgZm9yIGluZGV4T2YsIGZhbHNlIGZvciBsYXN0SW5kZXhPZlxuZnVuY3Rpb24gYmlkaXJlY3Rpb25hbEluZGV4T2YgKGJ1ZmZlciwgdmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgZGlyKSB7XG4gIC8vIEVtcHR5IGJ1ZmZlciBtZWFucyBubyBtYXRjaFxuICBpZiAoYnVmZmVyLmxlbmd0aCA9PT0gMCkgcmV0dXJuIC0xXG5cbiAgLy8gTm9ybWFsaXplIGJ5dGVPZmZzZXRcbiAgaWYgKHR5cGVvZiBieXRlT2Zmc2V0ID09PSAnc3RyaW5nJykge1xuICAgIGVuY29kaW5nID0gYnl0ZU9mZnNldFxuICAgIGJ5dGVPZmZzZXQgPSAwXG4gIH0gZWxzZSBpZiAoYnl0ZU9mZnNldCA+IDB4N2ZmZmZmZmYpIHtcbiAgICBieXRlT2Zmc2V0ID0gMHg3ZmZmZmZmZlxuICB9IGVsc2UgaWYgKGJ5dGVPZmZzZXQgPCAtMHg4MDAwMDAwMCkge1xuICAgIGJ5dGVPZmZzZXQgPSAtMHg4MDAwMDAwMFxuICB9XG4gIGJ5dGVPZmZzZXQgPSArYnl0ZU9mZnNldCAvLyBDb2VyY2UgdG8gTnVtYmVyLlxuICBpZiAobnVtYmVySXNOYU4oYnl0ZU9mZnNldCkpIHtcbiAgICAvLyBieXRlT2Zmc2V0OiBpdCBpdCdzIHVuZGVmaW5lZCwgbnVsbCwgTmFOLCBcImZvb1wiLCBldGMsIHNlYXJjaCB3aG9sZSBidWZmZXJcbiAgICBieXRlT2Zmc2V0ID0gZGlyID8gMCA6IChidWZmZXIubGVuZ3RoIC0gMSlcbiAgfVxuXG4gIC8vIE5vcm1hbGl6ZSBieXRlT2Zmc2V0OiBuZWdhdGl2ZSBvZmZzZXRzIHN0YXJ0IGZyb20gdGhlIGVuZCBvZiB0aGUgYnVmZmVyXG4gIGlmIChieXRlT2Zmc2V0IDwgMCkgYnl0ZU9mZnNldCA9IGJ1ZmZlci5sZW5ndGggKyBieXRlT2Zmc2V0XG4gIGlmIChieXRlT2Zmc2V0ID49IGJ1ZmZlci5sZW5ndGgpIHtcbiAgICBpZiAoZGlyKSByZXR1cm4gLTFcbiAgICBlbHNlIGJ5dGVPZmZzZXQgPSBidWZmZXIubGVuZ3RoIC0gMVxuICB9IGVsc2UgaWYgKGJ5dGVPZmZzZXQgPCAwKSB7XG4gICAgaWYgKGRpcikgYnl0ZU9mZnNldCA9IDBcbiAgICBlbHNlIHJldHVybiAtMVxuICB9XG5cbiAgLy8gTm9ybWFsaXplIHZhbFxuICBpZiAodHlwZW9mIHZhbCA9PT0gJ3N0cmluZycpIHtcbiAgICB2YWwgPSBCdWZmZXIuZnJvbSh2YWwsIGVuY29kaW5nKVxuICB9XG5cbiAgLy8gRmluYWxseSwgc2VhcmNoIGVpdGhlciBpbmRleE9mIChpZiBkaXIgaXMgdHJ1ZSkgb3IgbGFzdEluZGV4T2ZcbiAgaWYgKEJ1ZmZlci5pc0J1ZmZlcih2YWwpKSB7XG4gICAgLy8gU3BlY2lhbCBjYXNlOiBsb29raW5nIGZvciBlbXB0eSBzdHJpbmcvYnVmZmVyIGFsd2F5cyBmYWlsc1xuICAgIGlmICh2YWwubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gLTFcbiAgICB9XG4gICAgcmV0dXJuIGFycmF5SW5kZXhPZihidWZmZXIsIHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcsIGRpcilcbiAgfSBlbHNlIGlmICh0eXBlb2YgdmFsID09PSAnbnVtYmVyJykge1xuICAgIHZhbCA9IHZhbCAmIDB4RkYgLy8gU2VhcmNoIGZvciBhIGJ5dGUgdmFsdWUgWzAtMjU1XVxuICAgIGlmICh0eXBlb2YgVWludDhBcnJheS5wcm90b3R5cGUuaW5kZXhPZiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgaWYgKGRpcikge1xuICAgICAgICByZXR1cm4gVWludDhBcnJheS5wcm90b3R5cGUuaW5kZXhPZi5jYWxsKGJ1ZmZlciwgdmFsLCBieXRlT2Zmc2V0KVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIFVpbnQ4QXJyYXkucHJvdG90eXBlLmxhc3RJbmRleE9mLmNhbGwoYnVmZmVyLCB2YWwsIGJ5dGVPZmZzZXQpXG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBhcnJheUluZGV4T2YoYnVmZmVyLCBbIHZhbCBdLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgZGlyKVxuICB9XG5cbiAgdGhyb3cgbmV3IFR5cGVFcnJvcigndmFsIG11c3QgYmUgc3RyaW5nLCBudW1iZXIgb3IgQnVmZmVyJylcbn1cblxuZnVuY3Rpb24gYXJyYXlJbmRleE9mIChhcnIsIHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcsIGRpcikge1xuICB2YXIgaW5kZXhTaXplID0gMVxuICB2YXIgYXJyTGVuZ3RoID0gYXJyLmxlbmd0aFxuICB2YXIgdmFsTGVuZ3RoID0gdmFsLmxlbmd0aFxuXG4gIGlmIChlbmNvZGluZyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgZW5jb2RpbmcgPSBTdHJpbmcoZW5jb2RpbmcpLnRvTG93ZXJDYXNlKClcbiAgICBpZiAoZW5jb2RpbmcgPT09ICd1Y3MyJyB8fCBlbmNvZGluZyA9PT0gJ3Vjcy0yJyB8fFxuICAgICAgICBlbmNvZGluZyA9PT0gJ3V0ZjE2bGUnIHx8IGVuY29kaW5nID09PSAndXRmLTE2bGUnKSB7XG4gICAgICBpZiAoYXJyLmxlbmd0aCA8IDIgfHwgdmFsLmxlbmd0aCA8IDIpIHtcbiAgICAgICAgcmV0dXJuIC0xXG4gICAgICB9XG4gICAgICBpbmRleFNpemUgPSAyXG4gICAgICBhcnJMZW5ndGggLz0gMlxuICAgICAgdmFsTGVuZ3RoIC89IDJcbiAgICAgIGJ5dGVPZmZzZXQgLz0gMlxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHJlYWQgKGJ1ZiwgaSkge1xuICAgIGlmIChpbmRleFNpemUgPT09IDEpIHtcbiAgICAgIHJldHVybiBidWZbaV1cbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGJ1Zi5yZWFkVUludDE2QkUoaSAqIGluZGV4U2l6ZSlcbiAgICB9XG4gIH1cblxuICB2YXIgaVxuICBpZiAoZGlyKSB7XG4gICAgdmFyIGZvdW5kSW5kZXggPSAtMVxuICAgIGZvciAoaSA9IGJ5dGVPZmZzZXQ7IGkgPCBhcnJMZW5ndGg7IGkrKykge1xuICAgICAgaWYgKHJlYWQoYXJyLCBpKSA9PT0gcmVhZCh2YWwsIGZvdW5kSW5kZXggPT09IC0xID8gMCA6IGkgLSBmb3VuZEluZGV4KSkge1xuICAgICAgICBpZiAoZm91bmRJbmRleCA9PT0gLTEpIGZvdW5kSW5kZXggPSBpXG4gICAgICAgIGlmIChpIC0gZm91bmRJbmRleCArIDEgPT09IHZhbExlbmd0aCkgcmV0dXJuIGZvdW5kSW5kZXggKiBpbmRleFNpemVcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChmb3VuZEluZGV4ICE9PSAtMSkgaSAtPSBpIC0gZm91bmRJbmRleFxuICAgICAgICBmb3VuZEluZGV4ID0gLTFcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaWYgKGJ5dGVPZmZzZXQgKyB2YWxMZW5ndGggPiBhcnJMZW5ndGgpIGJ5dGVPZmZzZXQgPSBhcnJMZW5ndGggLSB2YWxMZW5ndGhcbiAgICBmb3IgKGkgPSBieXRlT2Zmc2V0OyBpID49IDA7IGktLSkge1xuICAgICAgdmFyIGZvdW5kID0gdHJ1ZVxuICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCB2YWxMZW5ndGg7IGorKykge1xuICAgICAgICBpZiAocmVhZChhcnIsIGkgKyBqKSAhPT0gcmVhZCh2YWwsIGopKSB7XG4gICAgICAgICAgZm91bmQgPSBmYWxzZVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChmb3VuZCkgcmV0dXJuIGlcbiAgICB9XG4gIH1cblxuICByZXR1cm4gLTFcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5pbmNsdWRlcyA9IGZ1bmN0aW9uIGluY2x1ZGVzICh2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nKSB7XG4gIHJldHVybiB0aGlzLmluZGV4T2YodmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZykgIT09IC0xXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuaW5kZXhPZiA9IGZ1bmN0aW9uIGluZGV4T2YgKHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcpIHtcbiAgcmV0dXJuIGJpZGlyZWN0aW9uYWxJbmRleE9mKHRoaXMsIHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcsIHRydWUpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUubGFzdEluZGV4T2YgPSBmdW5jdGlvbiBsYXN0SW5kZXhPZiAodmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZykge1xuICByZXR1cm4gYmlkaXJlY3Rpb25hbEluZGV4T2YodGhpcywgdmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgZmFsc2UpXG59XG5cbmZ1bmN0aW9uIGhleFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgb2Zmc2V0ID0gTnVtYmVyKG9mZnNldCkgfHwgMFxuICB2YXIgcmVtYWluaW5nID0gYnVmLmxlbmd0aCAtIG9mZnNldFxuICBpZiAoIWxlbmd0aCkge1xuICAgIGxlbmd0aCA9IHJlbWFpbmluZ1xuICB9IGVsc2Uge1xuICAgIGxlbmd0aCA9IE51bWJlcihsZW5ndGgpXG4gICAgaWYgKGxlbmd0aCA+IHJlbWFpbmluZykge1xuICAgICAgbGVuZ3RoID0gcmVtYWluaW5nXG4gICAgfVxuICB9XG5cbiAgdmFyIHN0ckxlbiA9IHN0cmluZy5sZW5ndGhcblxuICBpZiAobGVuZ3RoID4gc3RyTGVuIC8gMikge1xuICAgIGxlbmd0aCA9IHN0ckxlbiAvIDJcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7XG4gICAgdmFyIHBhcnNlZCA9IHBhcnNlSW50KHN0cmluZy5zdWJzdHIoaSAqIDIsIDIpLCAxNilcbiAgICBpZiAobnVtYmVySXNOYU4ocGFyc2VkKSkgcmV0dXJuIGlcbiAgICBidWZbb2Zmc2V0ICsgaV0gPSBwYXJzZWRcbiAgfVxuICByZXR1cm4gaVxufVxuXG5mdW5jdGlvbiB1dGY4V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYmxpdEJ1ZmZlcih1dGY4VG9CeXRlcyhzdHJpbmcsIGJ1Zi5sZW5ndGggLSBvZmZzZXQpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5mdW5jdGlvbiBhc2NpaVdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGJsaXRCdWZmZXIoYXNjaWlUb0J5dGVzKHN0cmluZyksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIGxhdGluMVdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGFzY2lpV3JpdGUoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5mdW5jdGlvbiBiYXNlNjRXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBibGl0QnVmZmVyKGJhc2U2NFRvQnl0ZXMoc3RyaW5nKSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gdWNzMldyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGJsaXRCdWZmZXIodXRmMTZsZVRvQnl0ZXMoc3RyaW5nLCBidWYubGVuZ3RoIC0gb2Zmc2V0KSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uIHdyaXRlIChzdHJpbmcsIG9mZnNldCwgbGVuZ3RoLCBlbmNvZGluZykge1xuICAvLyBCdWZmZXIjd3JpdGUoc3RyaW5nKVxuICBpZiAob2Zmc2V0ID09PSB1bmRlZmluZWQpIHtcbiAgICBlbmNvZGluZyA9ICd1dGY4J1xuICAgIGxlbmd0aCA9IHRoaXMubGVuZ3RoXG4gICAgb2Zmc2V0ID0gMFxuICAvLyBCdWZmZXIjd3JpdGUoc3RyaW5nLCBlbmNvZGluZylcbiAgfSBlbHNlIGlmIChsZW5ndGggPT09IHVuZGVmaW5lZCAmJiB0eXBlb2Ygb2Zmc2V0ID09PSAnc3RyaW5nJykge1xuICAgIGVuY29kaW5nID0gb2Zmc2V0XG4gICAgbGVuZ3RoID0gdGhpcy5sZW5ndGhcbiAgICBvZmZzZXQgPSAwXG4gIC8vIEJ1ZmZlciN3cml0ZShzdHJpbmcsIG9mZnNldFssIGxlbmd0aF1bLCBlbmNvZGluZ10pXG4gIH0gZWxzZSBpZiAoaXNGaW5pdGUob2Zmc2V0KSkge1xuICAgIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICAgIGlmIChpc0Zpbml0ZShsZW5ndGgpKSB7XG4gICAgICBsZW5ndGggPSBsZW5ndGggPj4+IDBcbiAgICAgIGlmIChlbmNvZGluZyA9PT0gdW5kZWZpbmVkKSBlbmNvZGluZyA9ICd1dGY4J1xuICAgIH0gZWxzZSB7XG4gICAgICBlbmNvZGluZyA9IGxlbmd0aFxuICAgICAgbGVuZ3RoID0gdW5kZWZpbmVkXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICdCdWZmZXIud3JpdGUoc3RyaW5nLCBlbmNvZGluZywgb2Zmc2V0WywgbGVuZ3RoXSkgaXMgbm8gbG9uZ2VyIHN1cHBvcnRlZCdcbiAgICApXG4gIH1cblxuICB2YXIgcmVtYWluaW5nID0gdGhpcy5sZW5ndGggLSBvZmZzZXRcbiAgaWYgKGxlbmd0aCA9PT0gdW5kZWZpbmVkIHx8IGxlbmd0aCA+IHJlbWFpbmluZykgbGVuZ3RoID0gcmVtYWluaW5nXG5cbiAgaWYgKChzdHJpbmcubGVuZ3RoID4gMCAmJiAobGVuZ3RoIDwgMCB8fCBvZmZzZXQgPCAwKSkgfHwgb2Zmc2V0ID4gdGhpcy5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignQXR0ZW1wdCB0byB3cml0ZSBvdXRzaWRlIGJ1ZmZlciBib3VuZHMnKVxuICB9XG5cbiAgaWYgKCFlbmNvZGluZykgZW5jb2RpbmcgPSAndXRmOCdcblxuICB2YXIgbG93ZXJlZENhc2UgPSBmYWxzZVxuICBmb3IgKDs7KSB7XG4gICAgc3dpdGNoIChlbmNvZGluZykge1xuICAgICAgY2FzZSAnaGV4JzpcbiAgICAgICAgcmV0dXJuIGhleFdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgY2FzZSAndXRmLTgnOlxuICAgICAgICByZXR1cm4gdXRmOFdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ2FzY2lpJzpcbiAgICAgICAgcmV0dXJuIGFzY2lpV3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAnbGF0aW4xJzpcbiAgICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICAgIHJldHVybiBsYXRpbjFXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgICAvLyBXYXJuaW5nOiBtYXhMZW5ndGggbm90IHRha2VuIGludG8gYWNjb3VudCBpbiBiYXNlNjRXcml0ZVxuICAgICAgICByZXR1cm4gYmFzZTY0V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAndWNzMic6XG4gICAgICBjYXNlICd1Y3MtMic6XG4gICAgICBjYXNlICd1dGYxNmxlJzpcbiAgICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgICAgcmV0dXJuIHVjczJXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpZiAobG93ZXJlZENhc2UpIHRocm93IG5ldyBUeXBlRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmNvZGluZylcbiAgICAgICAgZW5jb2RpbmcgPSAoJycgKyBlbmNvZGluZykudG9Mb3dlckNhc2UoKVxuICAgICAgICBsb3dlcmVkQ2FzZSA9IHRydWVcbiAgICB9XG4gIH1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiB0b0pTT04gKCkge1xuICByZXR1cm4ge1xuICAgIHR5cGU6ICdCdWZmZXInLFxuICAgIGRhdGE6IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKHRoaXMuX2FyciB8fCB0aGlzLCAwKVxuICB9XG59XG5cbmZ1bmN0aW9uIGJhc2U2NFNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgaWYgKHN0YXJ0ID09PSAwICYmIGVuZCA9PT0gYnVmLmxlbmd0aCkge1xuICAgIHJldHVybiBiYXNlNjQuZnJvbUJ5dGVBcnJheShidWYpXG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGJhc2U2NC5mcm9tQnl0ZUFycmF5KGJ1Zi5zbGljZShzdGFydCwgZW5kKSlcbiAgfVxufVxuXG5mdW5jdGlvbiB1dGY4U2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICBlbmQgPSBNYXRoLm1pbihidWYubGVuZ3RoLCBlbmQpXG4gIHZhciByZXMgPSBbXVxuXG4gIHZhciBpID0gc3RhcnRcbiAgd2hpbGUgKGkgPCBlbmQpIHtcbiAgICB2YXIgZmlyc3RCeXRlID0gYnVmW2ldXG4gICAgdmFyIGNvZGVQb2ludCA9IG51bGxcbiAgICB2YXIgYnl0ZXNQZXJTZXF1ZW5jZSA9IChmaXJzdEJ5dGUgPiAweEVGKSA/IDRcbiAgICAgIDogKGZpcnN0Qnl0ZSA+IDB4REYpID8gM1xuICAgICAgICA6IChmaXJzdEJ5dGUgPiAweEJGKSA/IDJcbiAgICAgICAgICA6IDFcblxuICAgIGlmIChpICsgYnl0ZXNQZXJTZXF1ZW5jZSA8PSBlbmQpIHtcbiAgICAgIHZhciBzZWNvbmRCeXRlLCB0aGlyZEJ5dGUsIGZvdXJ0aEJ5dGUsIHRlbXBDb2RlUG9pbnRcblxuICAgICAgc3dpdGNoIChieXRlc1BlclNlcXVlbmNlKSB7XG4gICAgICAgIGNhc2UgMTpcbiAgICAgICAgICBpZiAoZmlyc3RCeXRlIDwgMHg4MCkge1xuICAgICAgICAgICAgY29kZVBvaW50ID0gZmlyc3RCeXRlXG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGNhc2UgMjpcbiAgICAgICAgICBzZWNvbmRCeXRlID0gYnVmW2kgKyAxXVxuICAgICAgICAgIGlmICgoc2Vjb25kQnl0ZSAmIDB4QzApID09PSAweDgwKSB7XG4gICAgICAgICAgICB0ZW1wQ29kZVBvaW50ID0gKGZpcnN0Qnl0ZSAmIDB4MUYpIDw8IDB4NiB8IChzZWNvbmRCeXRlICYgMHgzRilcbiAgICAgICAgICAgIGlmICh0ZW1wQ29kZVBvaW50ID4gMHg3Rikge1xuICAgICAgICAgICAgICBjb2RlUG9pbnQgPSB0ZW1wQ29kZVBvaW50XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGNhc2UgMzpcbiAgICAgICAgICBzZWNvbmRCeXRlID0gYnVmW2kgKyAxXVxuICAgICAgICAgIHRoaXJkQnl0ZSA9IGJ1ZltpICsgMl1cbiAgICAgICAgICBpZiAoKHNlY29uZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCAmJiAodGhpcmRCeXRlICYgMHhDMCkgPT09IDB4ODApIHtcbiAgICAgICAgICAgIHRlbXBDb2RlUG9pbnQgPSAoZmlyc3RCeXRlICYgMHhGKSA8PCAweEMgfCAoc2Vjb25kQnl0ZSAmIDB4M0YpIDw8IDB4NiB8ICh0aGlyZEJ5dGUgJiAweDNGKVxuICAgICAgICAgICAgaWYgKHRlbXBDb2RlUG9pbnQgPiAweDdGRiAmJiAodGVtcENvZGVQb2ludCA8IDB4RDgwMCB8fCB0ZW1wQ29kZVBvaW50ID4gMHhERkZGKSkge1xuICAgICAgICAgICAgICBjb2RlUG9pbnQgPSB0ZW1wQ29kZVBvaW50XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGNhc2UgNDpcbiAgICAgICAgICBzZWNvbmRCeXRlID0gYnVmW2kgKyAxXVxuICAgICAgICAgIHRoaXJkQnl0ZSA9IGJ1ZltpICsgMl1cbiAgICAgICAgICBmb3VydGhCeXRlID0gYnVmW2kgKyAzXVxuICAgICAgICAgIGlmICgoc2Vjb25kQnl0ZSAmIDB4QzApID09PSAweDgwICYmICh0aGlyZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCAmJiAoZm91cnRoQnl0ZSAmIDB4QzApID09PSAweDgwKSB7XG4gICAgICAgICAgICB0ZW1wQ29kZVBvaW50ID0gKGZpcnN0Qnl0ZSAmIDB4RikgPDwgMHgxMiB8IChzZWNvbmRCeXRlICYgMHgzRikgPDwgMHhDIHwgKHRoaXJkQnl0ZSAmIDB4M0YpIDw8IDB4NiB8IChmb3VydGhCeXRlICYgMHgzRilcbiAgICAgICAgICAgIGlmICh0ZW1wQ29kZVBvaW50ID4gMHhGRkZGICYmIHRlbXBDb2RlUG9pbnQgPCAweDExMDAwMCkge1xuICAgICAgICAgICAgICBjb2RlUG9pbnQgPSB0ZW1wQ29kZVBvaW50XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChjb2RlUG9pbnQgPT09IG51bGwpIHtcbiAgICAgIC8vIHdlIGRpZCBub3QgZ2VuZXJhdGUgYSB2YWxpZCBjb2RlUG9pbnQgc28gaW5zZXJ0IGFcbiAgICAgIC8vIHJlcGxhY2VtZW50IGNoYXIgKFUrRkZGRCkgYW5kIGFkdmFuY2Ugb25seSAxIGJ5dGVcbiAgICAgIGNvZGVQb2ludCA9IDB4RkZGRFxuICAgICAgYnl0ZXNQZXJTZXF1ZW5jZSA9IDFcbiAgICB9IGVsc2UgaWYgKGNvZGVQb2ludCA+IDB4RkZGRikge1xuICAgICAgLy8gZW5jb2RlIHRvIHV0ZjE2IChzdXJyb2dhdGUgcGFpciBkYW5jZSlcbiAgICAgIGNvZGVQb2ludCAtPSAweDEwMDAwXG4gICAgICByZXMucHVzaChjb2RlUG9pbnQgPj4+IDEwICYgMHgzRkYgfCAweEQ4MDApXG4gICAgICBjb2RlUG9pbnQgPSAweERDMDAgfCBjb2RlUG9pbnQgJiAweDNGRlxuICAgIH1cblxuICAgIHJlcy5wdXNoKGNvZGVQb2ludClcbiAgICBpICs9IGJ5dGVzUGVyU2VxdWVuY2VcbiAgfVxuXG4gIHJldHVybiBkZWNvZGVDb2RlUG9pbnRzQXJyYXkocmVzKVxufVxuXG4vLyBCYXNlZCBvbiBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8yMjc0NzI3Mi82ODA3NDIsIHRoZSBicm93c2VyIHdpdGhcbi8vIHRoZSBsb3dlc3QgbGltaXQgaXMgQ2hyb21lLCB3aXRoIDB4MTAwMDAgYXJncy5cbi8vIFdlIGdvIDEgbWFnbml0dWRlIGxlc3MsIGZvciBzYWZldHlcbnZhciBNQVhfQVJHVU1FTlRTX0xFTkdUSCA9IDB4MTAwMFxuXG5mdW5jdGlvbiBkZWNvZGVDb2RlUG9pbnRzQXJyYXkgKGNvZGVQb2ludHMpIHtcbiAgdmFyIGxlbiA9IGNvZGVQb2ludHMubGVuZ3RoXG4gIGlmIChsZW4gPD0gTUFYX0FSR1VNRU5UU19MRU5HVEgpIHtcbiAgICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShTdHJpbmcsIGNvZGVQb2ludHMpIC8vIGF2b2lkIGV4dHJhIHNsaWNlKClcbiAgfVxuXG4gIC8vIERlY29kZSBpbiBjaHVua3MgdG8gYXZvaWQgXCJjYWxsIHN0YWNrIHNpemUgZXhjZWVkZWRcIi5cbiAgdmFyIHJlcyA9ICcnXG4gIHZhciBpID0gMFxuICB3aGlsZSAoaSA8IGxlbikge1xuICAgIHJlcyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KFxuICAgICAgU3RyaW5nLFxuICAgICAgY29kZVBvaW50cy5zbGljZShpLCBpICs9IE1BWF9BUkdVTUVOVFNfTEVOR1RIKVxuICAgIClcbiAgfVxuICByZXR1cm4gcmVzXG59XG5cbmZ1bmN0aW9uIGFzY2lpU2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgcmV0ID0gJydcbiAgZW5kID0gTWF0aC5taW4oYnVmLmxlbmd0aCwgZW5kKVxuXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgKytpKSB7XG4gICAgcmV0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYnVmW2ldICYgMHg3RilcbiAgfVxuICByZXR1cm4gcmV0XG59XG5cbmZ1bmN0aW9uIGxhdGluMVNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIHJldCA9ICcnXG4gIGVuZCA9IE1hdGgubWluKGJ1Zi5sZW5ndGgsIGVuZClcblxuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7ICsraSkge1xuICAgIHJldCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ1ZltpXSlcbiAgfVxuICByZXR1cm4gcmV0XG59XG5cbmZ1bmN0aW9uIGhleFNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGxlbiA9IGJ1Zi5sZW5ndGhcblxuICBpZiAoIXN0YXJ0IHx8IHN0YXJ0IDwgMCkgc3RhcnQgPSAwXG4gIGlmICghZW5kIHx8IGVuZCA8IDAgfHwgZW5kID4gbGVuKSBlbmQgPSBsZW5cblxuICB2YXIgb3V0ID0gJydcbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyArK2kpIHtcbiAgICBvdXQgKz0gdG9IZXgoYnVmW2ldKVxuICB9XG4gIHJldHVybiBvdXRcbn1cblxuZnVuY3Rpb24gdXRmMTZsZVNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGJ5dGVzID0gYnVmLnNsaWNlKHN0YXJ0LCBlbmQpXG4gIHZhciByZXMgPSAnJ1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGJ5dGVzLmxlbmd0aDsgaSArPSAyKSB7XG4gICAgcmVzICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYnl0ZXNbaV0gKyAoYnl0ZXNbaSArIDFdICogMjU2KSlcbiAgfVxuICByZXR1cm4gcmVzXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuc2xpY2UgPSBmdW5jdGlvbiBzbGljZSAoc3RhcnQsIGVuZCkge1xuICB2YXIgbGVuID0gdGhpcy5sZW5ndGhcbiAgc3RhcnQgPSB+fnN0YXJ0XG4gIGVuZCA9IGVuZCA9PT0gdW5kZWZpbmVkID8gbGVuIDogfn5lbmRcblxuICBpZiAoc3RhcnQgPCAwKSB7XG4gICAgc3RhcnQgKz0gbGVuXG4gICAgaWYgKHN0YXJ0IDwgMCkgc3RhcnQgPSAwXG4gIH0gZWxzZSBpZiAoc3RhcnQgPiBsZW4pIHtcbiAgICBzdGFydCA9IGxlblxuICB9XG5cbiAgaWYgKGVuZCA8IDApIHtcbiAgICBlbmQgKz0gbGVuXG4gICAgaWYgKGVuZCA8IDApIGVuZCA9IDBcbiAgfSBlbHNlIGlmIChlbmQgPiBsZW4pIHtcbiAgICBlbmQgPSBsZW5cbiAgfVxuXG4gIGlmIChlbmQgPCBzdGFydCkgZW5kID0gc3RhcnRcblxuICB2YXIgbmV3QnVmID0gdGhpcy5zdWJhcnJheShzdGFydCwgZW5kKVxuICAvLyBSZXR1cm4gYW4gYXVnbWVudGVkIGBVaW50OEFycmF5YCBpbnN0YW5jZVxuICBuZXdCdWYuX19wcm90b19fID0gQnVmZmVyLnByb3RvdHlwZVxuICByZXR1cm4gbmV3QnVmXG59XG5cbi8qXG4gKiBOZWVkIHRvIG1ha2Ugc3VyZSB0aGF0IGJ1ZmZlciBpc24ndCB0cnlpbmcgdG8gd3JpdGUgb3V0IG9mIGJvdW5kcy5cbiAqL1xuZnVuY3Rpb24gY2hlY2tPZmZzZXQgKG9mZnNldCwgZXh0LCBsZW5ndGgpIHtcbiAgaWYgKChvZmZzZXQgJSAxKSAhPT0gMCB8fCBvZmZzZXQgPCAwKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignb2Zmc2V0IGlzIG5vdCB1aW50JylcbiAgaWYgKG9mZnNldCArIGV4dCA+IGxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1RyeWluZyB0byBhY2Nlc3MgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50TEUgPSBmdW5jdGlvbiByZWFkVUludExFIChvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldF1cbiAgdmFyIG11bCA9IDFcbiAgdmFyIGkgPSAwXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgaV0gKiBtdWxcbiAgfVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludEJFID0gZnVuY3Rpb24gcmVhZFVJbnRCRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGNoZWNrT2Zmc2V0KG9mZnNldCwgYnl0ZUxlbmd0aCwgdGhpcy5sZW5ndGgpXG4gIH1cblxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXQgKyAtLWJ5dGVMZW5ndGhdXG4gIHZhciBtdWwgPSAxXG4gIHdoaWxlIChieXRlTGVuZ3RoID4gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHZhbCArPSB0aGlzW29mZnNldCArIC0tYnl0ZUxlbmd0aF0gKiBtdWxcbiAgfVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDggPSBmdW5jdGlvbiByZWFkVUludDggKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMSwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiB0aGlzW29mZnNldF1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDE2TEUgPSBmdW5jdGlvbiByZWFkVUludDE2TEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiB0aGlzW29mZnNldF0gfCAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MTZCRSA9IGZ1bmN0aW9uIHJlYWRVSW50MTZCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAyLCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuICh0aGlzW29mZnNldF0gPDwgOCkgfCB0aGlzW29mZnNldCArIDFdXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQzMkxFID0gZnVuY3Rpb24gcmVhZFVJbnQzMkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuXG4gIHJldHVybiAoKHRoaXNbb2Zmc2V0XSkgfFxuICAgICAgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgOCkgfFxuICAgICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgMTYpKSArXG4gICAgICAodGhpc1tvZmZzZXQgKyAzXSAqIDB4MTAwMDAwMClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDMyQkUgPSBmdW5jdGlvbiByZWFkVUludDMyQkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICh0aGlzW29mZnNldF0gKiAweDEwMDAwMDApICtcbiAgICAoKHRoaXNbb2Zmc2V0ICsgMV0gPDwgMTYpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAyXSA8PCA4KSB8XG4gICAgdGhpc1tvZmZzZXQgKyAzXSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50TEUgPSBmdW5jdGlvbiByZWFkSW50TEUgKG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgYnl0ZUxlbmd0aCwgdGhpcy5sZW5ndGgpXG5cbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0XVxuICB2YXIgbXVsID0gMVxuICB2YXIgaSA9IDBcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyBpXSAqIG11bFxuICB9XG4gIG11bCAqPSAweDgwXG5cbiAgaWYgKHZhbCA+PSBtdWwpIHZhbCAtPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aClcblxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludEJFID0gZnVuY3Rpb24gcmVhZEludEJFIChvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuXG4gIHZhciBpID0gYnl0ZUxlbmd0aFxuICB2YXIgbXVsID0gMVxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXQgKyAtLWldXG4gIHdoaWxlIChpID4gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHZhbCArPSB0aGlzW29mZnNldCArIC0taV0gKiBtdWxcbiAgfVxuICBtdWwgKj0gMHg4MFxuXG4gIGlmICh2YWwgPj0gbXVsKSB2YWwgLT0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpXG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQ4ID0gZnVuY3Rpb24gcmVhZEludDggKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMSwgdGhpcy5sZW5ndGgpXG4gIGlmICghKHRoaXNbb2Zmc2V0XSAmIDB4ODApKSByZXR1cm4gKHRoaXNbb2Zmc2V0XSlcbiAgcmV0dXJuICgoMHhmZiAtIHRoaXNbb2Zmc2V0XSArIDEpICogLTEpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDE2TEUgPSBmdW5jdGlvbiByZWFkSW50MTZMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAyLCB0aGlzLmxlbmd0aClcbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0XSB8ICh0aGlzW29mZnNldCArIDFdIDw8IDgpXG4gIHJldHVybiAodmFsICYgMHg4MDAwKSA/IHZhbCB8IDB4RkZGRjAwMDAgOiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MTZCRSA9IGZ1bmN0aW9uIHJlYWRJbnQxNkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXQgKyAxXSB8ICh0aGlzW29mZnNldF0gPDwgOClcbiAgcmV0dXJuICh2YWwgJiAweDgwMDApID8gdmFsIHwgMHhGRkZGMDAwMCA6IHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQzMkxFID0gZnVuY3Rpb24gcmVhZEludDMyTEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICh0aGlzW29mZnNldF0pIHxcbiAgICAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgMTYpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAzXSA8PCAyNClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MzJCRSA9IGZ1bmN0aW9uIHJlYWRJbnQzMkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuXG4gIHJldHVybiAodGhpc1tvZmZzZXRdIDw8IDI0KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgMTYpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAyXSA8PCA4KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgM10pXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEZsb2F0TEUgPSBmdW5jdGlvbiByZWFkRmxvYXRMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIHRydWUsIDIzLCA0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRGbG9hdEJFID0gZnVuY3Rpb24gcmVhZEZsb2F0QkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCBmYWxzZSwgMjMsIDQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZERvdWJsZUxFID0gZnVuY3Rpb24gcmVhZERvdWJsZUxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDgsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gaWVlZTc1NC5yZWFkKHRoaXMsIG9mZnNldCwgdHJ1ZSwgNTIsIDgpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZERvdWJsZUJFID0gZnVuY3Rpb24gcmVhZERvdWJsZUJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDgsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gaWVlZTc1NC5yZWFkKHRoaXMsIG9mZnNldCwgZmFsc2UsIDUyLCA4KVxufVxuXG5mdW5jdGlvbiBjaGVja0ludCAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBleHQsIG1heCwgbWluKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGJ1ZikpIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wiYnVmZmVyXCIgYXJndW1lbnQgbXVzdCBiZSBhIEJ1ZmZlciBpbnN0YW5jZScpXG4gIGlmICh2YWx1ZSA+IG1heCB8fCB2YWx1ZSA8IG1pbikgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1widmFsdWVcIiBhcmd1bWVudCBpcyBvdXQgb2YgYm91bmRzJylcbiAgaWYgKG9mZnNldCArIGV4dCA+IGJ1Zi5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdJbmRleCBvdXQgb2YgcmFuZ2UnKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludExFID0gZnVuY3Rpb24gd3JpdGVVSW50TEUgKHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgdmFyIG1heEJ5dGVzID0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpIC0gMVxuICAgIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG1heEJ5dGVzLCAwKVxuICB9XG5cbiAgdmFyIG11bCA9IDFcbiAgdmFyIGkgPSAwXG4gIHRoaXNbb2Zmc2V0XSA9IHZhbHVlICYgMHhGRlxuICB3aGlsZSAoKytpIDwgYnl0ZUxlbmd0aCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAodmFsdWUgLyBtdWwpICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnRCRSA9IGZ1bmN0aW9uIHdyaXRlVUludEJFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIHZhciBtYXhCeXRlcyA9IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKSAtIDFcbiAgICBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBtYXhCeXRlcywgMClcbiAgfVxuXG4gIHZhciBpID0gYnl0ZUxlbmd0aCAtIDFcbiAgdmFyIG11bCA9IDFcbiAgdGhpc1tvZmZzZXQgKyBpXSA9IHZhbHVlICYgMHhGRlxuICB3aGlsZSAoLS1pID49IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB0aGlzW29mZnNldCArIGldID0gKHZhbHVlIC8gbXVsKSAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50OCA9IGZ1bmN0aW9uIHdyaXRlVUludDggKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAxLCAweGZmLCAwKVxuICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICByZXR1cm4gb2Zmc2V0ICsgMVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDE2TEUgPSBmdW5jdGlvbiB3cml0ZVVJbnQxNkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMiwgMHhmZmZmLCAwKVxuICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICByZXR1cm4gb2Zmc2V0ICsgMlxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDE2QkUgPSBmdW5jdGlvbiB3cml0ZVVJbnQxNkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMiwgMHhmZmZmLCAwKVxuICB0aGlzW29mZnNldF0gPSAodmFsdWUgPj4+IDgpXG4gIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgJiAweGZmKVxuICByZXR1cm4gb2Zmc2V0ICsgMlxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDMyTEUgPSBmdW5jdGlvbiB3cml0ZVVJbnQzMkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgNCwgMHhmZmZmZmZmZiwgMClcbiAgdGhpc1tvZmZzZXQgKyAzXSA9ICh2YWx1ZSA+Pj4gMjQpXG4gIHRoaXNbb2Zmc2V0ICsgMl0gPSAodmFsdWUgPj4+IDE2KVxuICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDMyQkUgPSBmdW5jdGlvbiB3cml0ZVVJbnQzMkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgNCwgMHhmZmZmZmZmZiwgMClcbiAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiAyNClcbiAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gIHRoaXNbb2Zmc2V0ICsgMl0gPSAodmFsdWUgPj4+IDgpXG4gIHRoaXNbb2Zmc2V0ICsgM10gPSAodmFsdWUgJiAweGZmKVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50TEUgPSBmdW5jdGlvbiB3cml0ZUludExFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIHZhciBsaW1pdCA9IE1hdGgucG93KDIsICg4ICogYnl0ZUxlbmd0aCkgLSAxKVxuXG4gICAgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbGltaXQgLSAxLCAtbGltaXQpXG4gIH1cblxuICB2YXIgaSA9IDBcbiAgdmFyIG11bCA9IDFcbiAgdmFyIHN1YiA9IDBcbiAgdGhpc1tvZmZzZXRdID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgaWYgKHZhbHVlIDwgMCAmJiBzdWIgPT09IDAgJiYgdGhpc1tvZmZzZXQgKyBpIC0gMV0gIT09IDApIHtcbiAgICAgIHN1YiA9IDFcbiAgICB9XG4gICAgdGhpc1tvZmZzZXQgKyBpXSA9ICgodmFsdWUgLyBtdWwpID4+IDApIC0gc3ViICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludEJFID0gZnVuY3Rpb24gd3JpdGVJbnRCRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICB2YXIgbGltaXQgPSBNYXRoLnBvdygyLCAoOCAqIGJ5dGVMZW5ndGgpIC0gMSlcblxuICAgIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIGxpbWl0IC0gMSwgLWxpbWl0KVxuICB9XG5cbiAgdmFyIGkgPSBieXRlTGVuZ3RoIC0gMVxuICB2YXIgbXVsID0gMVxuICB2YXIgc3ViID0gMFxuICB0aGlzW29mZnNldCArIGldID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgtLWkgPj0gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIGlmICh2YWx1ZSA8IDAgJiYgc3ViID09PSAwICYmIHRoaXNbb2Zmc2V0ICsgaSArIDFdICE9PSAwKSB7XG4gICAgICBzdWIgPSAxXG4gICAgfVxuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAoKHZhbHVlIC8gbXVsKSA+PiAwKSAtIHN1YiAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQ4ID0gZnVuY3Rpb24gd3JpdGVJbnQ4ICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMSwgMHg3ZiwgLTB4ODApXG4gIGlmICh2YWx1ZSA8IDApIHZhbHVlID0gMHhmZiArIHZhbHVlICsgMVxuICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICByZXR1cm4gb2Zmc2V0ICsgMVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MTZMRSA9IGZ1bmN0aW9uIHdyaXRlSW50MTZMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4N2ZmZiwgLTB4ODAwMClcbiAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gOClcbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDE2QkUgPSBmdW5jdGlvbiB3cml0ZUludDE2QkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAyLCAweDdmZmYsIC0weDgwMDApXG4gIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gOClcbiAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQzMkxFID0gZnVuY3Rpb24gd3JpdGVJbnQzMkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgNCwgMHg3ZmZmZmZmZiwgLTB4ODAwMDAwMDApXG4gIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gIHRoaXNbb2Zmc2V0ICsgMl0gPSAodmFsdWUgPj4+IDE2KVxuICB0aGlzW29mZnNldCArIDNdID0gKHZhbHVlID4+PiAyNClcbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDMyQkUgPSBmdW5jdGlvbiB3cml0ZUludDMyQkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCA0LCAweDdmZmZmZmZmLCAtMHg4MDAwMDAwMClcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmZmZmZmZmICsgdmFsdWUgKyAxXG4gIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gMjQpXG4gIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDE2KVxuICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiA4KVxuICB0aGlzW29mZnNldCArIDNdID0gKHZhbHVlICYgMHhmZilcbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuZnVuY3Rpb24gY2hlY2tJRUVFNzU0IChidWYsIHZhbHVlLCBvZmZzZXQsIGV4dCwgbWF4LCBtaW4pIHtcbiAgaWYgKG9mZnNldCArIGV4dCA+IGJ1Zi5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdJbmRleCBvdXQgb2YgcmFuZ2UnKVxuICBpZiAob2Zmc2V0IDwgMCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0luZGV4IG91dCBvZiByYW5nZScpXG59XG5cbmZ1bmN0aW9uIHdyaXRlRmxvYXQgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGNoZWNrSUVFRTc1NChidWYsIHZhbHVlLCBvZmZzZXQsIDQsIDMuNDAyODIzNDY2Mzg1Mjg4NmUrMzgsIC0zLjQwMjgyMzQ2NjM4NTI4ODZlKzM4KVxuICB9XG4gIGllZWU3NTQud3JpdGUoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIDIzLCA0KVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRmxvYXRMRSA9IGZ1bmN0aW9uIHdyaXRlRmxvYXRMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHdyaXRlRmxvYXQodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVGbG9hdEJFID0gZnVuY3Rpb24gd3JpdGVGbG9hdEJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVGbG9hdCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpXG59XG5cbmZ1bmN0aW9uIHdyaXRlRG91YmxlIChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBjaGVja0lFRUU3NTQoYnVmLCB2YWx1ZSwgb2Zmc2V0LCA4LCAxLjc5NzY5MzEzNDg2MjMxNTdFKzMwOCwgLTEuNzk3NjkzMTM0ODYyMzE1N0UrMzA4KVxuICB9XG4gIGllZWU3NTQud3JpdGUoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIDUyLCA4KVxuICByZXR1cm4gb2Zmc2V0ICsgOFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRG91YmxlTEUgPSBmdW5jdGlvbiB3cml0ZURvdWJsZUxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVEb3VibGUodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVEb3VibGVCRSA9IGZ1bmN0aW9uIHdyaXRlRG91YmxlQkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiB3cml0ZURvdWJsZSh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpXG59XG5cbi8vIGNvcHkodGFyZ2V0QnVmZmVyLCB0YXJnZXRTdGFydD0wLCBzb3VyY2VTdGFydD0wLCBzb3VyY2VFbmQ9YnVmZmVyLmxlbmd0aClcbkJ1ZmZlci5wcm90b3R5cGUuY29weSA9IGZ1bmN0aW9uIGNvcHkgKHRhcmdldCwgdGFyZ2V0U3RhcnQsIHN0YXJ0LCBlbmQpIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIodGFyZ2V0KSkgdGhyb3cgbmV3IFR5cGVFcnJvcignYXJndW1lbnQgc2hvdWxkIGJlIGEgQnVmZmVyJylcbiAgaWYgKCFzdGFydCkgc3RhcnQgPSAwXG4gIGlmICghZW5kICYmIGVuZCAhPT0gMCkgZW5kID0gdGhpcy5sZW5ndGhcbiAgaWYgKHRhcmdldFN0YXJ0ID49IHRhcmdldC5sZW5ndGgpIHRhcmdldFN0YXJ0ID0gdGFyZ2V0Lmxlbmd0aFxuICBpZiAoIXRhcmdldFN0YXJ0KSB0YXJnZXRTdGFydCA9IDBcbiAgaWYgKGVuZCA+IDAgJiYgZW5kIDwgc3RhcnQpIGVuZCA9IHN0YXJ0XG5cbiAgLy8gQ29weSAwIGJ5dGVzOyB3ZSdyZSBkb25lXG4gIGlmIChlbmQgPT09IHN0YXJ0KSByZXR1cm4gMFxuICBpZiAodGFyZ2V0Lmxlbmd0aCA9PT0gMCB8fCB0aGlzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIDBcblxuICAvLyBGYXRhbCBlcnJvciBjb25kaXRpb25zXG4gIGlmICh0YXJnZXRTdGFydCA8IDApIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcigndGFyZ2V0U3RhcnQgb3V0IG9mIGJvdW5kcycpXG4gIH1cbiAgaWYgKHN0YXJ0IDwgMCB8fCBzdGFydCA+PSB0aGlzLmxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0luZGV4IG91dCBvZiByYW5nZScpXG4gIGlmIChlbmQgPCAwKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignc291cmNlRW5kIG91dCBvZiBib3VuZHMnKVxuXG4gIC8vIEFyZSB3ZSBvb2I/XG4gIGlmIChlbmQgPiB0aGlzLmxlbmd0aCkgZW5kID0gdGhpcy5sZW5ndGhcbiAgaWYgKHRhcmdldC5sZW5ndGggLSB0YXJnZXRTdGFydCA8IGVuZCAtIHN0YXJ0KSB7XG4gICAgZW5kID0gdGFyZ2V0Lmxlbmd0aCAtIHRhcmdldFN0YXJ0ICsgc3RhcnRcbiAgfVxuXG4gIHZhciBsZW4gPSBlbmQgLSBzdGFydFxuXG4gIGlmICh0aGlzID09PSB0YXJnZXQgJiYgdHlwZW9mIFVpbnQ4QXJyYXkucHJvdG90eXBlLmNvcHlXaXRoaW4gPT09ICdmdW5jdGlvbicpIHtcbiAgICAvLyBVc2UgYnVpbHQtaW4gd2hlbiBhdmFpbGFibGUsIG1pc3NpbmcgZnJvbSBJRTExXG4gICAgdGhpcy5jb3B5V2l0aGluKHRhcmdldFN0YXJ0LCBzdGFydCwgZW5kKVxuICB9IGVsc2UgaWYgKHRoaXMgPT09IHRhcmdldCAmJiBzdGFydCA8IHRhcmdldFN0YXJ0ICYmIHRhcmdldFN0YXJ0IDwgZW5kKSB7XG4gICAgLy8gZGVzY2VuZGluZyBjb3B5IGZyb20gZW5kXG4gICAgZm9yICh2YXIgaSA9IGxlbiAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICB0YXJnZXRbaSArIHRhcmdldFN0YXJ0XSA9IHRoaXNbaSArIHN0YXJ0XVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBVaW50OEFycmF5LnByb3RvdHlwZS5zZXQuY2FsbChcbiAgICAgIHRhcmdldCxcbiAgICAgIHRoaXMuc3ViYXJyYXkoc3RhcnQsIGVuZCksXG4gICAgICB0YXJnZXRTdGFydFxuICAgIClcbiAgfVxuXG4gIHJldHVybiBsZW5cbn1cblxuLy8gVXNhZ2U6XG4vLyAgICBidWZmZXIuZmlsbChudW1iZXJbLCBvZmZzZXRbLCBlbmRdXSlcbi8vICAgIGJ1ZmZlci5maWxsKGJ1ZmZlclssIG9mZnNldFssIGVuZF1dKVxuLy8gICAgYnVmZmVyLmZpbGwoc3RyaW5nWywgb2Zmc2V0WywgZW5kXV1bLCBlbmNvZGluZ10pXG5CdWZmZXIucHJvdG90eXBlLmZpbGwgPSBmdW5jdGlvbiBmaWxsICh2YWwsIHN0YXJ0LCBlbmQsIGVuY29kaW5nKSB7XG4gIC8vIEhhbmRsZSBzdHJpbmcgY2FzZXM6XG4gIGlmICh0eXBlb2YgdmFsID09PSAnc3RyaW5nJykge1xuICAgIGlmICh0eXBlb2Ygc3RhcnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICBlbmNvZGluZyA9IHN0YXJ0XG4gICAgICBzdGFydCA9IDBcbiAgICAgIGVuZCA9IHRoaXMubGVuZ3RoXG4gICAgfSBlbHNlIGlmICh0eXBlb2YgZW5kID09PSAnc3RyaW5nJykge1xuICAgICAgZW5jb2RpbmcgPSBlbmRcbiAgICAgIGVuZCA9IHRoaXMubGVuZ3RoXG4gICAgfVxuICAgIGlmIChlbmNvZGluZyAhPT0gdW5kZWZpbmVkICYmIHR5cGVvZiBlbmNvZGluZyAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2VuY29kaW5nIG11c3QgYmUgYSBzdHJpbmcnKVxuICAgIH1cbiAgICBpZiAodHlwZW9mIGVuY29kaW5nID09PSAnc3RyaW5nJyAmJiAhQnVmZmVyLmlzRW5jb2RpbmcoZW5jb2RpbmcpKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpXG4gICAgfVxuICAgIGlmICh2YWwubGVuZ3RoID09PSAxKSB7XG4gICAgICB2YXIgY29kZSA9IHZhbC5jaGFyQ29kZUF0KDApXG4gICAgICBpZiAoKGVuY29kaW5nID09PSAndXRmOCcgJiYgY29kZSA8IDEyOCkgfHxcbiAgICAgICAgICBlbmNvZGluZyA9PT0gJ2xhdGluMScpIHtcbiAgICAgICAgLy8gRmFzdCBwYXRoOiBJZiBgdmFsYCBmaXRzIGludG8gYSBzaW5nbGUgYnl0ZSwgdXNlIHRoYXQgbnVtZXJpYyB2YWx1ZS5cbiAgICAgICAgdmFsID0gY29kZVxuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIGlmICh0eXBlb2YgdmFsID09PSAnbnVtYmVyJykge1xuICAgIHZhbCA9IHZhbCAmIDI1NVxuICB9XG5cbiAgLy8gSW52YWxpZCByYW5nZXMgYXJlIG5vdCBzZXQgdG8gYSBkZWZhdWx0LCBzbyBjYW4gcmFuZ2UgY2hlY2sgZWFybHkuXG4gIGlmIChzdGFydCA8IDAgfHwgdGhpcy5sZW5ndGggPCBzdGFydCB8fCB0aGlzLmxlbmd0aCA8IGVuZCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdPdXQgb2YgcmFuZ2UgaW5kZXgnKVxuICB9XG5cbiAgaWYgKGVuZCA8PSBzdGFydCkge1xuICAgIHJldHVybiB0aGlzXG4gIH1cblxuICBzdGFydCA9IHN0YXJ0ID4+PiAwXG4gIGVuZCA9IGVuZCA9PT0gdW5kZWZpbmVkID8gdGhpcy5sZW5ndGggOiBlbmQgPj4+IDBcblxuICBpZiAoIXZhbCkgdmFsID0gMFxuXG4gIHZhciBpXG4gIGlmICh0eXBlb2YgdmFsID09PSAnbnVtYmVyJykge1xuICAgIGZvciAoaSA9IHN0YXJ0OyBpIDwgZW5kOyArK2kpIHtcbiAgICAgIHRoaXNbaV0gPSB2YWxcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdmFyIGJ5dGVzID0gQnVmZmVyLmlzQnVmZmVyKHZhbClcbiAgICAgID8gdmFsXG4gICAgICA6IEJ1ZmZlci5mcm9tKHZhbCwgZW5jb2RpbmcpXG4gICAgdmFyIGxlbiA9IGJ5dGVzLmxlbmd0aFxuICAgIGlmIChsZW4gPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSB2YWx1ZSBcIicgKyB2YWwgK1xuICAgICAgICAnXCIgaXMgaW52YWxpZCBmb3IgYXJndW1lbnQgXCJ2YWx1ZVwiJylcbiAgICB9XG4gICAgZm9yIChpID0gMDsgaSA8IGVuZCAtIHN0YXJ0OyArK2kpIHtcbiAgICAgIHRoaXNbaSArIHN0YXJ0XSA9IGJ5dGVzW2kgJSBsZW5dXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRoaXNcbn1cblxuLy8gSEVMUEVSIEZVTkNUSU9OU1xuLy8gPT09PT09PT09PT09PT09PVxuXG52YXIgSU5WQUxJRF9CQVNFNjRfUkUgPSAvW14rLzAtOUEtWmEtei1fXS9nXG5cbmZ1bmN0aW9uIGJhc2U2NGNsZWFuIChzdHIpIHtcbiAgLy8gTm9kZSB0YWtlcyBlcXVhbCBzaWducyBhcyBlbmQgb2YgdGhlIEJhc2U2NCBlbmNvZGluZ1xuICBzdHIgPSBzdHIuc3BsaXQoJz0nKVswXVxuICAvLyBOb2RlIHN0cmlwcyBvdXQgaW52YWxpZCBjaGFyYWN0ZXJzIGxpa2UgXFxuIGFuZCBcXHQgZnJvbSB0aGUgc3RyaW5nLCBiYXNlNjQtanMgZG9lcyBub3RcbiAgc3RyID0gc3RyLnRyaW0oKS5yZXBsYWNlKElOVkFMSURfQkFTRTY0X1JFLCAnJylcbiAgLy8gTm9kZSBjb252ZXJ0cyBzdHJpbmdzIHdpdGggbGVuZ3RoIDwgMiB0byAnJ1xuICBpZiAoc3RyLmxlbmd0aCA8IDIpIHJldHVybiAnJ1xuICAvLyBOb2RlIGFsbG93cyBmb3Igbm9uLXBhZGRlZCBiYXNlNjQgc3RyaW5ncyAobWlzc2luZyB0cmFpbGluZyA9PT0pLCBiYXNlNjQtanMgZG9lcyBub3RcbiAgd2hpbGUgKHN0ci5sZW5ndGggJSA0ICE9PSAwKSB7XG4gICAgc3RyID0gc3RyICsgJz0nXG4gIH1cbiAgcmV0dXJuIHN0clxufVxuXG5mdW5jdGlvbiB0b0hleCAobikge1xuICBpZiAobiA8IDE2KSByZXR1cm4gJzAnICsgbi50b1N0cmluZygxNilcbiAgcmV0dXJuIG4udG9TdHJpbmcoMTYpXG59XG5cbmZ1bmN0aW9uIHV0ZjhUb0J5dGVzIChzdHJpbmcsIHVuaXRzKSB7XG4gIHVuaXRzID0gdW5pdHMgfHwgSW5maW5pdHlcbiAgdmFyIGNvZGVQb2ludFxuICB2YXIgbGVuZ3RoID0gc3RyaW5nLmxlbmd0aFxuICB2YXIgbGVhZFN1cnJvZ2F0ZSA9IG51bGxcbiAgdmFyIGJ5dGVzID0gW11cblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7XG4gICAgY29kZVBvaW50ID0gc3RyaW5nLmNoYXJDb2RlQXQoaSlcblxuICAgIC8vIGlzIHN1cnJvZ2F0ZSBjb21wb25lbnRcbiAgICBpZiAoY29kZVBvaW50ID4gMHhEN0ZGICYmIGNvZGVQb2ludCA8IDB4RTAwMCkge1xuICAgICAgLy8gbGFzdCBjaGFyIHdhcyBhIGxlYWRcbiAgICAgIGlmICghbGVhZFN1cnJvZ2F0ZSkge1xuICAgICAgICAvLyBubyBsZWFkIHlldFxuICAgICAgICBpZiAoY29kZVBvaW50ID4gMHhEQkZGKSB7XG4gICAgICAgICAgLy8gdW5leHBlY3RlZCB0cmFpbFxuICAgICAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH0gZWxzZSBpZiAoaSArIDEgPT09IGxlbmd0aCkge1xuICAgICAgICAgIC8vIHVucGFpcmVkIGxlYWRcbiAgICAgICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gdmFsaWQgbGVhZFxuICAgICAgICBsZWFkU3Vycm9nYXRlID0gY29kZVBvaW50XG5cbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgLy8gMiBsZWFkcyBpbiBhIHJvd1xuICAgICAgaWYgKGNvZGVQb2ludCA8IDB4REMwMCkge1xuICAgICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICAgICAgbGVhZFN1cnJvZ2F0ZSA9IGNvZGVQb2ludFxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICAvLyB2YWxpZCBzdXJyb2dhdGUgcGFpclxuICAgICAgY29kZVBvaW50ID0gKGxlYWRTdXJyb2dhdGUgLSAweEQ4MDAgPDwgMTAgfCBjb2RlUG9pbnQgLSAweERDMDApICsgMHgxMDAwMFxuICAgIH0gZWxzZSBpZiAobGVhZFN1cnJvZ2F0ZSkge1xuICAgICAgLy8gdmFsaWQgYm1wIGNoYXIsIGJ1dCBsYXN0IGNoYXIgd2FzIGEgbGVhZFxuICAgICAgaWYgKCh1bml0cyAtPSAzKSA+IC0xKSBieXRlcy5wdXNoKDB4RUYsIDB4QkYsIDB4QkQpXG4gICAgfVxuXG4gICAgbGVhZFN1cnJvZ2F0ZSA9IG51bGxcblxuICAgIC8vIGVuY29kZSB1dGY4XG4gICAgaWYgKGNvZGVQb2ludCA8IDB4ODApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gMSkgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChjb2RlUG9pbnQpXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPCAweDgwMCkge1xuICAgICAgaWYgKCh1bml0cyAtPSAyKSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHg2IHwgMHhDMCxcbiAgICAgICAgY29kZVBvaW50ICYgMHgzRiB8IDB4ODBcbiAgICAgIClcbiAgICB9IGVsc2UgaWYgKGNvZGVQb2ludCA8IDB4MTAwMDApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gMykgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChcbiAgICAgICAgY29kZVBvaW50ID4+IDB4QyB8IDB4RTAsXG4gICAgICAgIGNvZGVQb2ludCA+PiAweDYgJiAweDNGIHwgMHg4MCxcbiAgICAgICAgY29kZVBvaW50ICYgMHgzRiB8IDB4ODBcbiAgICAgIClcbiAgICB9IGVsc2UgaWYgKGNvZGVQb2ludCA8IDB4MTEwMDAwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDQpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goXG4gICAgICAgIGNvZGVQb2ludCA+PiAweDEyIHwgMHhGMCxcbiAgICAgICAgY29kZVBvaW50ID4+IDB4QyAmIDB4M0YgfCAweDgwLFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHg2ICYgMHgzRiB8IDB4ODAsXG4gICAgICAgIGNvZGVQb2ludCAmIDB4M0YgfCAweDgwXG4gICAgICApXG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBjb2RlIHBvaW50JylcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYnl0ZXNcbn1cblxuZnVuY3Rpb24gYXNjaWlUb0J5dGVzIChzdHIpIHtcbiAgdmFyIGJ5dGVBcnJheSA9IFtdXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgKytpKSB7XG4gICAgLy8gTm9kZSdzIGNvZGUgc2VlbXMgdG8gYmUgZG9pbmcgdGhpcyBhbmQgbm90ICYgMHg3Ri4uXG4gICAgYnl0ZUFycmF5LnB1c2goc3RyLmNoYXJDb2RlQXQoaSkgJiAweEZGKVxuICB9XG4gIHJldHVybiBieXRlQXJyYXlcbn1cblxuZnVuY3Rpb24gdXRmMTZsZVRvQnl0ZXMgKHN0ciwgdW5pdHMpIHtcbiAgdmFyIGMsIGhpLCBsb1xuICB2YXIgYnl0ZUFycmF5ID0gW11cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyArK2kpIHtcbiAgICBpZiAoKHVuaXRzIC09IDIpIDwgMCkgYnJlYWtcblxuICAgIGMgPSBzdHIuY2hhckNvZGVBdChpKVxuICAgIGhpID0gYyA+PiA4XG4gICAgbG8gPSBjICUgMjU2XG4gICAgYnl0ZUFycmF5LnB1c2gobG8pXG4gICAgYnl0ZUFycmF5LnB1c2goaGkpXG4gIH1cblxuICByZXR1cm4gYnl0ZUFycmF5XG59XG5cbmZ1bmN0aW9uIGJhc2U2NFRvQnl0ZXMgKHN0cikge1xuICByZXR1cm4gYmFzZTY0LnRvQnl0ZUFycmF5KGJhc2U2NGNsZWFuKHN0cikpXG59XG5cbmZ1bmN0aW9uIGJsaXRCdWZmZXIgKHNyYywgZHN0LCBvZmZzZXQsIGxlbmd0aCkge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7XG4gICAgaWYgKChpICsgb2Zmc2V0ID49IGRzdC5sZW5ndGgpIHx8IChpID49IHNyYy5sZW5ndGgpKSBicmVha1xuICAgIGRzdFtpICsgb2Zmc2V0XSA9IHNyY1tpXVxuICB9XG4gIHJldHVybiBpXG59XG5cbi8vIEFycmF5QnVmZmVyIG9yIFVpbnQ4QXJyYXkgb2JqZWN0cyBmcm9tIG90aGVyIGNvbnRleHRzIChpLmUuIGlmcmFtZXMpIGRvIG5vdCBwYXNzXG4vLyB0aGUgYGluc3RhbmNlb2ZgIGNoZWNrIGJ1dCB0aGV5IHNob3VsZCBiZSB0cmVhdGVkIGFzIG9mIHRoYXQgdHlwZS5cbi8vIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL2Zlcm9zcy9idWZmZXIvaXNzdWVzLzE2NlxuZnVuY3Rpb24gaXNJbnN0YW5jZSAob2JqLCB0eXBlKSB7XG4gIHJldHVybiBvYmogaW5zdGFuY2VvZiB0eXBlIHx8XG4gICAgKG9iaiAhPSBudWxsICYmIG9iai5jb25zdHJ1Y3RvciAhPSBudWxsICYmIG9iai5jb25zdHJ1Y3Rvci5uYW1lICE9IG51bGwgJiZcbiAgICAgIG9iai5jb25zdHJ1Y3Rvci5uYW1lID09PSB0eXBlLm5hbWUpXG59XG5mdW5jdGlvbiBudW1iZXJJc05hTiAob2JqKSB7XG4gIC8vIEZvciBJRTExIHN1cHBvcnRcbiAgcmV0dXJuIG9iaiAhPT0gb2JqIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tc2VsZi1jb21wYXJlXG59XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHtcbiAgXCIxMDBcIjogXCJDb250aW51ZVwiLFxuICBcIjEwMVwiOiBcIlN3aXRjaGluZyBQcm90b2NvbHNcIixcbiAgXCIxMDJcIjogXCJQcm9jZXNzaW5nXCIsXG4gIFwiMjAwXCI6IFwiT0tcIixcbiAgXCIyMDFcIjogXCJDcmVhdGVkXCIsXG4gIFwiMjAyXCI6IFwiQWNjZXB0ZWRcIixcbiAgXCIyMDNcIjogXCJOb24tQXV0aG9yaXRhdGl2ZSBJbmZvcm1hdGlvblwiLFxuICBcIjIwNFwiOiBcIk5vIENvbnRlbnRcIixcbiAgXCIyMDVcIjogXCJSZXNldCBDb250ZW50XCIsXG4gIFwiMjA2XCI6IFwiUGFydGlhbCBDb250ZW50XCIsXG4gIFwiMjA3XCI6IFwiTXVsdGktU3RhdHVzXCIsXG4gIFwiMjA4XCI6IFwiQWxyZWFkeSBSZXBvcnRlZFwiLFxuICBcIjIyNlwiOiBcIklNIFVzZWRcIixcbiAgXCIzMDBcIjogXCJNdWx0aXBsZSBDaG9pY2VzXCIsXG4gIFwiMzAxXCI6IFwiTW92ZWQgUGVybWFuZW50bHlcIixcbiAgXCIzMDJcIjogXCJGb3VuZFwiLFxuICBcIjMwM1wiOiBcIlNlZSBPdGhlclwiLFxuICBcIjMwNFwiOiBcIk5vdCBNb2RpZmllZFwiLFxuICBcIjMwNVwiOiBcIlVzZSBQcm94eVwiLFxuICBcIjMwN1wiOiBcIlRlbXBvcmFyeSBSZWRpcmVjdFwiLFxuICBcIjMwOFwiOiBcIlBlcm1hbmVudCBSZWRpcmVjdFwiLFxuICBcIjQwMFwiOiBcIkJhZCBSZXF1ZXN0XCIsXG4gIFwiNDAxXCI6IFwiVW5hdXRob3JpemVkXCIsXG4gIFwiNDAyXCI6IFwiUGF5bWVudCBSZXF1aXJlZFwiLFxuICBcIjQwM1wiOiBcIkZvcmJpZGRlblwiLFxuICBcIjQwNFwiOiBcIk5vdCBGb3VuZFwiLFxuICBcIjQwNVwiOiBcIk1ldGhvZCBOb3QgQWxsb3dlZFwiLFxuICBcIjQwNlwiOiBcIk5vdCBBY2NlcHRhYmxlXCIsXG4gIFwiNDA3XCI6IFwiUHJveHkgQXV0aGVudGljYXRpb24gUmVxdWlyZWRcIixcbiAgXCI0MDhcIjogXCJSZXF1ZXN0IFRpbWVvdXRcIixcbiAgXCI0MDlcIjogXCJDb25mbGljdFwiLFxuICBcIjQxMFwiOiBcIkdvbmVcIixcbiAgXCI0MTFcIjogXCJMZW5ndGggUmVxdWlyZWRcIixcbiAgXCI0MTJcIjogXCJQcmVjb25kaXRpb24gRmFpbGVkXCIsXG4gIFwiNDEzXCI6IFwiUGF5bG9hZCBUb28gTGFyZ2VcIixcbiAgXCI0MTRcIjogXCJVUkkgVG9vIExvbmdcIixcbiAgXCI0MTVcIjogXCJVbnN1cHBvcnRlZCBNZWRpYSBUeXBlXCIsXG4gIFwiNDE2XCI6IFwiUmFuZ2UgTm90IFNhdGlzZmlhYmxlXCIsXG4gIFwiNDE3XCI6IFwiRXhwZWN0YXRpb24gRmFpbGVkXCIsXG4gIFwiNDE4XCI6IFwiSSdtIGEgdGVhcG90XCIsXG4gIFwiNDIxXCI6IFwiTWlzZGlyZWN0ZWQgUmVxdWVzdFwiLFxuICBcIjQyMlwiOiBcIlVucHJvY2Vzc2FibGUgRW50aXR5XCIsXG4gIFwiNDIzXCI6IFwiTG9ja2VkXCIsXG4gIFwiNDI0XCI6IFwiRmFpbGVkIERlcGVuZGVuY3lcIixcbiAgXCI0MjVcIjogXCJVbm9yZGVyZWQgQ29sbGVjdGlvblwiLFxuICBcIjQyNlwiOiBcIlVwZ3JhZGUgUmVxdWlyZWRcIixcbiAgXCI0MjhcIjogXCJQcmVjb25kaXRpb24gUmVxdWlyZWRcIixcbiAgXCI0MjlcIjogXCJUb28gTWFueSBSZXF1ZXN0c1wiLFxuICBcIjQzMVwiOiBcIlJlcXVlc3QgSGVhZGVyIEZpZWxkcyBUb28gTGFyZ2VcIixcbiAgXCI0NTFcIjogXCJVbmF2YWlsYWJsZSBGb3IgTGVnYWwgUmVhc29uc1wiLFxuICBcIjUwMFwiOiBcIkludGVybmFsIFNlcnZlciBFcnJvclwiLFxuICBcIjUwMVwiOiBcIk5vdCBJbXBsZW1lbnRlZFwiLFxuICBcIjUwMlwiOiBcIkJhZCBHYXRld2F5XCIsXG4gIFwiNTAzXCI6IFwiU2VydmljZSBVbmF2YWlsYWJsZVwiLFxuICBcIjUwNFwiOiBcIkdhdGV3YXkgVGltZW91dFwiLFxuICBcIjUwNVwiOiBcIkhUVFAgVmVyc2lvbiBOb3QgU3VwcG9ydGVkXCIsXG4gIFwiNTA2XCI6IFwiVmFyaWFudCBBbHNvIE5lZ290aWF0ZXNcIixcbiAgXCI1MDdcIjogXCJJbnN1ZmZpY2llbnQgU3RvcmFnZVwiLFxuICBcIjUwOFwiOiBcIkxvb3AgRGV0ZWN0ZWRcIixcbiAgXCI1MDlcIjogXCJCYW5kd2lkdGggTGltaXQgRXhjZWVkZWRcIixcbiAgXCI1MTBcIjogXCJOb3QgRXh0ZW5kZWRcIixcbiAgXCI1MTFcIjogXCJOZXR3b3JrIEF1dGhlbnRpY2F0aW9uIFJlcXVpcmVkXCJcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGJpbmQgPSByZXF1aXJlKCdmdW5jdGlvbi1iaW5kJyk7XG5cbnZhciAkYXBwbHkgPSByZXF1aXJlKCcuL2Z1bmN0aW9uQXBwbHknKTtcbnZhciAkY2FsbCA9IHJlcXVpcmUoJy4vZnVuY3Rpb25DYWxsJyk7XG52YXIgJHJlZmxlY3RBcHBseSA9IHJlcXVpcmUoJy4vcmVmbGVjdEFwcGx5Jyk7XG5cbi8qKiBAdHlwZSB7aW1wb3J0KCcuL2FjdHVhbEFwcGx5Jyl9ICovXG5tb2R1bGUuZXhwb3J0cyA9ICRyZWZsZWN0QXBwbHkgfHwgYmluZC5jYWxsKCRjYWxsLCAkYXBwbHkpO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKiogQHR5cGUge2ltcG9ydCgnLi9mdW5jdGlvbkFwcGx5Jyl9ICovXG5tb2R1bGUuZXhwb3J0cyA9IEZ1bmN0aW9uLnByb3RvdHlwZS5hcHBseTtcbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqIEB0eXBlIHtpbXBvcnQoJy4vZnVuY3Rpb25DYWxsJyl9ICovXG5tb2R1bGUuZXhwb3J0cyA9IEZ1bmN0aW9uLnByb3RvdHlwZS5jYWxsO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYmluZCA9IHJlcXVpcmUoJ2Z1bmN0aW9uLWJpbmQnKTtcbnZhciAkVHlwZUVycm9yID0gcmVxdWlyZSgnZXMtZXJyb3JzL3R5cGUnKTtcblxudmFyICRjYWxsID0gcmVxdWlyZSgnLi9mdW5jdGlvbkNhbGwnKTtcbnZhciAkYWN0dWFsQXBwbHkgPSByZXF1aXJlKCcuL2FjdHVhbEFwcGx5Jyk7XG5cbi8qKiBAdHlwZSB7KGFyZ3M6IFtGdW5jdGlvbiwgdGhpc0FyZz86IHVua25vd24sIC4uLmFyZ3M6IHVua25vd25bXV0pID0+IEZ1bmN0aW9ufSBUT0RPIEZJWE1FLCBmaW5kIGEgd2F5IHRvIHVzZSBpbXBvcnQoJy4nKSAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBjYWxsQmluZEJhc2ljKGFyZ3MpIHtcblx0aWYgKGFyZ3MubGVuZ3RoIDwgMSB8fCB0eXBlb2YgYXJnc1swXSAhPT0gJ2Z1bmN0aW9uJykge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdhIGZ1bmN0aW9uIGlzIHJlcXVpcmVkJyk7XG5cdH1cblx0cmV0dXJuICRhY3R1YWxBcHBseShiaW5kLCAkY2FsbCwgYXJncyk7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKiogQHR5cGUge2ltcG9ydCgnLi9yZWZsZWN0QXBwbHknKX0gKi9cbm1vZHVsZS5leHBvcnRzID0gdHlwZW9mIFJlZmxlY3QgIT09ICd1bmRlZmluZWQnICYmIFJlZmxlY3QgJiYgUmVmbGVjdC5hcHBseTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcblxudmFyIGNhbGxCaW5kQmFzaWMgPSByZXF1aXJlKCdjYWxsLWJpbmQtYXBwbHktaGVscGVycycpO1xuXG4vKiogQHR5cGUgeyh0aGlzQXJnOiBzdHJpbmcsIHNlYXJjaFN0cmluZzogc3RyaW5nLCBwb3NpdGlvbj86IG51bWJlcikgPT4gbnVtYmVyfSAqL1xudmFyICRpbmRleE9mID0gY2FsbEJpbmRCYXNpYyhbR2V0SW50cmluc2ljKCclU3RyaW5nLnByb3RvdHlwZS5pbmRleE9mJScpXSk7XG5cbi8qKiBAdHlwZSB7aW1wb3J0KCcuJyl9ICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGNhbGxCb3VuZEludHJpbnNpYyhuYW1lLCBhbGxvd01pc3NpbmcpIHtcblx0LyogZXNsaW50IG5vLWV4dHJhLXBhcmVuczogMCAqL1xuXG5cdHZhciBpbnRyaW5zaWMgPSAvKiogQHR5cGUgeyh0aGlzOiB1bmtub3duLCAuLi5hcmdzOiB1bmtub3duW10pID0+IHVua25vd259ICovIChHZXRJbnRyaW5zaWMobmFtZSwgISFhbGxvd01pc3NpbmcpKTtcblx0aWYgKHR5cGVvZiBpbnRyaW5zaWMgPT09ICdmdW5jdGlvbicgJiYgJGluZGV4T2YobmFtZSwgJy5wcm90b3R5cGUuJykgPiAtMSkge1xuXHRcdHJldHVybiBjYWxsQmluZEJhc2ljKC8qKiBAdHlwZSB7Y29uc3R9ICovIChbaW50cmluc2ljXSkpO1xuXHR9XG5cdHJldHVybiBpbnRyaW5zaWM7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgY2FsbEJpbmQgPSByZXF1aXJlKCdjYWxsLWJpbmQtYXBwbHktaGVscGVycycpO1xudmFyIGdPUEQgPSByZXF1aXJlKCdnb3BkJyk7XG5cbnZhciBoYXNQcm90b0FjY2Vzc29yO1xudHJ5IHtcblx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWV4dHJhLXBhcmVucywgbm8tcHJvdG9cblx0aGFzUHJvdG9BY2Nlc3NvciA9IC8qKiBAdHlwZSB7eyBfX3Byb3RvX18/OiB0eXBlb2YgQXJyYXkucHJvdG90eXBlIH19ICovIChbXSkuX19wcm90b19fID09PSBBcnJheS5wcm90b3R5cGU7XG59IGNhdGNoIChlKSB7XG5cdGlmICghZSB8fCB0eXBlb2YgZSAhPT0gJ29iamVjdCcgfHwgISgnY29kZScgaW4gZSkgfHwgZS5jb2RlICE9PSAnRVJSX1BST1RPX0FDQ0VTUycpIHtcblx0XHR0aHJvdyBlO1xuXHR9XG59XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1leHRyYS1wYXJlbnNcbnZhciBkZXNjID0gISFoYXNQcm90b0FjY2Vzc29yICYmIGdPUEQgJiYgZ09QRChPYmplY3QucHJvdG90eXBlLCAvKiogQHR5cGUge2tleW9mIHR5cGVvZiBPYmplY3QucHJvdG90eXBlfSAqLyAoJ19fcHJvdG9fXycpKTtcblxudmFyICRPYmplY3QgPSBPYmplY3Q7XG52YXIgJGdldFByb3RvdHlwZU9mID0gJE9iamVjdC5nZXRQcm90b3R5cGVPZjtcblxuLyoqIEB0eXBlIHtpbXBvcnQoJy4vZ2V0Jyl9ICovXG5tb2R1bGUuZXhwb3J0cyA9IGRlc2MgJiYgdHlwZW9mIGRlc2MuZ2V0ID09PSAnZnVuY3Rpb24nXG5cdD8gY2FsbEJpbmQoW2Rlc2MuZ2V0XSlcblx0OiB0eXBlb2YgJGdldFByb3RvdHlwZU9mID09PSAnZnVuY3Rpb24nXG5cdFx0PyAvKiogQHR5cGUge2ltcG9ydCgnLi9nZXQnKX0gKi8gZnVuY3Rpb24gZ2V0RHVuZGVyKHZhbHVlKSB7XG5cdFx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZXFlcWVxXG5cdFx0XHRyZXR1cm4gJGdldFByb3RvdHlwZU9mKHZhbHVlID09IG51bGwgPyB2YWx1ZSA6ICRPYmplY3QodmFsdWUpKTtcblx0XHR9XG5cdFx0OiBmYWxzZTtcbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqIEB0eXBlIHtpbXBvcnQoJy4nKX0gKi9cbnZhciAkZGVmaW5lUHJvcGVydHkgPSBPYmplY3QuZGVmaW5lUHJvcGVydHkgfHwgZmFsc2U7XG5pZiAoJGRlZmluZVByb3BlcnR5KSB7XG5cdHRyeSB7XG5cdFx0JGRlZmluZVByb3BlcnR5KHt9LCAnYScsIHsgdmFsdWU6IDEgfSk7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHQvLyBJRSA4IGhhcyBhIGJyb2tlbiBkZWZpbmVQcm9wZXJ0eVxuXHRcdCRkZWZpbmVQcm9wZXJ0eSA9IGZhbHNlO1xuXHR9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gJGRlZmluZVByb3BlcnR5O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKiogQHR5cGUge2ltcG9ydCgnLi9ldmFsJyl9ICovXG5tb2R1bGUuZXhwb3J0cyA9IEV2YWxFcnJvcjtcbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqIEB0eXBlIHtpbXBvcnQoJy4nKX0gKi9cbm1vZHVsZS5leHBvcnRzID0gRXJyb3I7XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKiBAdHlwZSB7aW1wb3J0KCcuL3JhbmdlJyl9ICovXG5tb2R1bGUuZXhwb3J0cyA9IFJhbmdlRXJyb3I7XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKiBAdHlwZSB7aW1wb3J0KCcuL3JlZicpfSAqL1xubW9kdWxlLmV4cG9ydHMgPSBSZWZlcmVuY2VFcnJvcjtcbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqIEB0eXBlIHtpbXBvcnQoJy4vc3ludGF4Jyl9ICovXG5tb2R1bGUuZXhwb3J0cyA9IFN5bnRheEVycm9yO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKiogQHR5cGUge2ltcG9ydCgnLi90eXBlJyl9ICovXG5tb2R1bGUuZXhwb3J0cyA9IFR5cGVFcnJvcjtcbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqIEB0eXBlIHtpbXBvcnQoJy4vdXJpJyl9ICovXG5tb2R1bGUuZXhwb3J0cyA9IFVSSUVycm9yO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKiogQHR5cGUge2ltcG9ydCgnLicpfSAqL1xubW9kdWxlLmV4cG9ydHMgPSBPYmplY3Q7XG4iLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgUiA9IHR5cGVvZiBSZWZsZWN0ID09PSAnb2JqZWN0JyA/IFJlZmxlY3QgOiBudWxsXG52YXIgUmVmbGVjdEFwcGx5ID0gUiAmJiB0eXBlb2YgUi5hcHBseSA9PT0gJ2Z1bmN0aW9uJ1xuICA/IFIuYXBwbHlcbiAgOiBmdW5jdGlvbiBSZWZsZWN0QXBwbHkodGFyZ2V0LCByZWNlaXZlciwgYXJncykge1xuICAgIHJldHVybiBGdW5jdGlvbi5wcm90b3R5cGUuYXBwbHkuY2FsbCh0YXJnZXQsIHJlY2VpdmVyLCBhcmdzKTtcbiAgfVxuXG52YXIgUmVmbGVjdE93bktleXNcbmlmIChSICYmIHR5cGVvZiBSLm93bktleXMgPT09ICdmdW5jdGlvbicpIHtcbiAgUmVmbGVjdE93bktleXMgPSBSLm93bktleXNcbn0gZWxzZSBpZiAoT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scykge1xuICBSZWZsZWN0T3duS2V5cyA9IGZ1bmN0aW9uIFJlZmxlY3RPd25LZXlzKHRhcmdldCkge1xuICAgIHJldHVybiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh0YXJnZXQpXG4gICAgICAuY29uY2F0KE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHModGFyZ2V0KSk7XG4gIH07XG59IGVsc2Uge1xuICBSZWZsZWN0T3duS2V5cyA9IGZ1bmN0aW9uIFJlZmxlY3RPd25LZXlzKHRhcmdldCkge1xuICAgIHJldHVybiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh0YXJnZXQpO1xuICB9O1xufVxuXG5mdW5jdGlvbiBQcm9jZXNzRW1pdFdhcm5pbmcod2FybmluZykge1xuICBpZiAoY29uc29sZSAmJiBjb25zb2xlLndhcm4pIGNvbnNvbGUud2Fybih3YXJuaW5nKTtcbn1cblxudmFyIE51bWJlcklzTmFOID0gTnVtYmVyLmlzTmFOIHx8IGZ1bmN0aW9uIE51bWJlcklzTmFOKHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZSAhPT0gdmFsdWU7XG59XG5cbmZ1bmN0aW9uIEV2ZW50RW1pdHRlcigpIHtcbiAgRXZlbnRFbWl0dGVyLmluaXQuY2FsbCh0aGlzKTtcbn1cbm1vZHVsZS5leHBvcnRzID0gRXZlbnRFbWl0dGVyO1xubW9kdWxlLmV4cG9ydHMub25jZSA9IG9uY2U7XG5cbi8vIEJhY2t3YXJkcy1jb21wYXQgd2l0aCBub2RlIDAuMTAueFxuRXZlbnRFbWl0dGVyLkV2ZW50RW1pdHRlciA9IEV2ZW50RW1pdHRlcjtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5fZXZlbnRzID0gdW5kZWZpbmVkO1xuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5fZXZlbnRzQ291bnQgPSAwO1xuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5fbWF4TGlzdGVuZXJzID0gdW5kZWZpbmVkO1xuXG4vLyBCeSBkZWZhdWx0IEV2ZW50RW1pdHRlcnMgd2lsbCBwcmludCBhIHdhcm5pbmcgaWYgbW9yZSB0aGFuIDEwIGxpc3RlbmVycyBhcmVcbi8vIGFkZGVkIHRvIGl0LiBUaGlzIGlzIGEgdXNlZnVsIGRlZmF1bHQgd2hpY2ggaGVscHMgZmluZGluZyBtZW1vcnkgbGVha3MuXG52YXIgZGVmYXVsdE1heExpc3RlbmVycyA9IDEwO1xuXG5mdW5jdGlvbiBjaGVja0xpc3RlbmVyKGxpc3RlbmVyKSB7XG4gIGlmICh0eXBlb2YgbGlzdGVuZXIgIT09ICdmdW5jdGlvbicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgXCJsaXN0ZW5lclwiIGFyZ3VtZW50IG11c3QgYmUgb2YgdHlwZSBGdW5jdGlvbi4gUmVjZWl2ZWQgdHlwZSAnICsgdHlwZW9mIGxpc3RlbmVyKTtcbiAgfVxufVxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoRXZlbnRFbWl0dGVyLCAnZGVmYXVsdE1heExpc3RlbmVycycsIHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gZGVmYXVsdE1heExpc3RlbmVycztcbiAgfSxcbiAgc2V0OiBmdW5jdGlvbihhcmcpIHtcbiAgICBpZiAodHlwZW9mIGFyZyAhPT0gJ251bWJlcicgfHwgYXJnIDwgMCB8fCBOdW1iZXJJc05hTihhcmcpKSB7XG4gICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignVGhlIHZhbHVlIG9mIFwiZGVmYXVsdE1heExpc3RlbmVyc1wiIGlzIG91dCBvZiByYW5nZS4gSXQgbXVzdCBiZSBhIG5vbi1uZWdhdGl2ZSBudW1iZXIuIFJlY2VpdmVkICcgKyBhcmcgKyAnLicpO1xuICAgIH1cbiAgICBkZWZhdWx0TWF4TGlzdGVuZXJzID0gYXJnO1xuICB9XG59KTtcblxuRXZlbnRFbWl0dGVyLmluaXQgPSBmdW5jdGlvbigpIHtcblxuICBpZiAodGhpcy5fZXZlbnRzID09PSB1bmRlZmluZWQgfHxcbiAgICAgIHRoaXMuX2V2ZW50cyA9PT0gT2JqZWN0LmdldFByb3RvdHlwZU9mKHRoaXMpLl9ldmVudHMpIHtcbiAgICB0aGlzLl9ldmVudHMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIHRoaXMuX2V2ZW50c0NvdW50ID0gMDtcbiAgfVxuXG4gIHRoaXMuX21heExpc3RlbmVycyA9IHRoaXMuX21heExpc3RlbmVycyB8fCB1bmRlZmluZWQ7XG59O1xuXG4vLyBPYnZpb3VzbHkgbm90IGFsbCBFbWl0dGVycyBzaG91bGQgYmUgbGltaXRlZCB0byAxMC4gVGhpcyBmdW5jdGlvbiBhbGxvd3Ncbi8vIHRoYXQgdG8gYmUgaW5jcmVhc2VkLiBTZXQgdG8gemVybyBmb3IgdW5saW1pdGVkLlxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5zZXRNYXhMaXN0ZW5lcnMgPSBmdW5jdGlvbiBzZXRNYXhMaXN0ZW5lcnMobikge1xuICBpZiAodHlwZW9mIG4gIT09ICdudW1iZXInIHx8IG4gPCAwIHx8IE51bWJlcklzTmFOKG4pKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1RoZSB2YWx1ZSBvZiBcIm5cIiBpcyBvdXQgb2YgcmFuZ2UuIEl0IG11c3QgYmUgYSBub24tbmVnYXRpdmUgbnVtYmVyLiBSZWNlaXZlZCAnICsgbiArICcuJyk7XG4gIH1cbiAgdGhpcy5fbWF4TGlzdGVuZXJzID0gbjtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5mdW5jdGlvbiBfZ2V0TWF4TGlzdGVuZXJzKHRoYXQpIHtcbiAgaWYgKHRoYXQuX21heExpc3RlbmVycyA9PT0gdW5kZWZpbmVkKVxuICAgIHJldHVybiBFdmVudEVtaXR0ZXIuZGVmYXVsdE1heExpc3RlbmVycztcbiAgcmV0dXJuIHRoYXQuX21heExpc3RlbmVycztcbn1cblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5nZXRNYXhMaXN0ZW5lcnMgPSBmdW5jdGlvbiBnZXRNYXhMaXN0ZW5lcnMoKSB7XG4gIHJldHVybiBfZ2V0TWF4TGlzdGVuZXJzKHRoaXMpO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5lbWl0ID0gZnVuY3Rpb24gZW1pdCh0eXBlKSB7XG4gIHZhciBhcmdzID0gW107XG4gIGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSBhcmdzLnB1c2goYXJndW1lbnRzW2ldKTtcbiAgdmFyIGRvRXJyb3IgPSAodHlwZSA9PT0gJ2Vycm9yJyk7XG5cbiAgdmFyIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcbiAgaWYgKGV2ZW50cyAhPT0gdW5kZWZpbmVkKVxuICAgIGRvRXJyb3IgPSAoZG9FcnJvciAmJiBldmVudHMuZXJyb3IgPT09IHVuZGVmaW5lZCk7XG4gIGVsc2UgaWYgKCFkb0Vycm9yKVxuICAgIHJldHVybiBmYWxzZTtcblxuICAvLyBJZiB0aGVyZSBpcyBubyAnZXJyb3InIGV2ZW50IGxpc3RlbmVyIHRoZW4gdGhyb3cuXG4gIGlmIChkb0Vycm9yKSB7XG4gICAgdmFyIGVyO1xuICAgIGlmIChhcmdzLmxlbmd0aCA+IDApXG4gICAgICBlciA9IGFyZ3NbMF07XG4gICAgaWYgKGVyIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgIC8vIE5vdGU6IFRoZSBjb21tZW50cyBvbiB0aGUgYHRocm93YCBsaW5lcyBhcmUgaW50ZW50aW9uYWwsIHRoZXkgc2hvd1xuICAgICAgLy8gdXAgaW4gTm9kZSdzIG91dHB1dCBpZiB0aGlzIHJlc3VsdHMgaW4gYW4gdW5oYW5kbGVkIGV4Y2VwdGlvbi5cbiAgICAgIHRocm93IGVyOyAvLyBVbmhhbmRsZWQgJ2Vycm9yJyBldmVudFxuICAgIH1cbiAgICAvLyBBdCBsZWFzdCBnaXZlIHNvbWUga2luZCBvZiBjb250ZXh0IHRvIHRoZSB1c2VyXG4gICAgdmFyIGVyciA9IG5ldyBFcnJvcignVW5oYW5kbGVkIGVycm9yLicgKyAoZXIgPyAnICgnICsgZXIubWVzc2FnZSArICcpJyA6ICcnKSk7XG4gICAgZXJyLmNvbnRleHQgPSBlcjtcbiAgICB0aHJvdyBlcnI7IC8vIFVuaGFuZGxlZCAnZXJyb3InIGV2ZW50XG4gIH1cblxuICB2YXIgaGFuZGxlciA9IGV2ZW50c1t0eXBlXTtcblxuICBpZiAoaGFuZGxlciA9PT0gdW5kZWZpbmVkKVxuICAgIHJldHVybiBmYWxzZTtcblxuICBpZiAodHlwZW9mIGhhbmRsZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICBSZWZsZWN0QXBwbHkoaGFuZGxlciwgdGhpcywgYXJncyk7XG4gIH0gZWxzZSB7XG4gICAgdmFyIGxlbiA9IGhhbmRsZXIubGVuZ3RoO1xuICAgIHZhciBsaXN0ZW5lcnMgPSBhcnJheUNsb25lKGhhbmRsZXIsIGxlbik7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47ICsraSlcbiAgICAgIFJlZmxlY3RBcHBseShsaXN0ZW5lcnNbaV0sIHRoaXMsIGFyZ3MpO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59O1xuXG5mdW5jdGlvbiBfYWRkTGlzdGVuZXIodGFyZ2V0LCB0eXBlLCBsaXN0ZW5lciwgcHJlcGVuZCkge1xuICB2YXIgbTtcbiAgdmFyIGV2ZW50cztcbiAgdmFyIGV4aXN0aW5nO1xuXG4gIGNoZWNrTGlzdGVuZXIobGlzdGVuZXIpO1xuXG4gIGV2ZW50cyA9IHRhcmdldC5fZXZlbnRzO1xuICBpZiAoZXZlbnRzID09PSB1bmRlZmluZWQpIHtcbiAgICBldmVudHMgPSB0YXJnZXQuX2V2ZW50cyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgdGFyZ2V0Ll9ldmVudHNDb3VudCA9IDA7XG4gIH0gZWxzZSB7XG4gICAgLy8gVG8gYXZvaWQgcmVjdXJzaW9uIGluIHRoZSBjYXNlIHRoYXQgdHlwZSA9PT0gXCJuZXdMaXN0ZW5lclwiISBCZWZvcmVcbiAgICAvLyBhZGRpbmcgaXQgdG8gdGhlIGxpc3RlbmVycywgZmlyc3QgZW1pdCBcIm5ld0xpc3RlbmVyXCIuXG4gICAgaWYgKGV2ZW50cy5uZXdMaXN0ZW5lciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0YXJnZXQuZW1pdCgnbmV3TGlzdGVuZXInLCB0eXBlLFxuICAgICAgICAgICAgICAgICAgbGlzdGVuZXIubGlzdGVuZXIgPyBsaXN0ZW5lci5saXN0ZW5lciA6IGxpc3RlbmVyKTtcblxuICAgICAgLy8gUmUtYXNzaWduIGBldmVudHNgIGJlY2F1c2UgYSBuZXdMaXN0ZW5lciBoYW5kbGVyIGNvdWxkIGhhdmUgY2F1c2VkIHRoZVxuICAgICAgLy8gdGhpcy5fZXZlbnRzIHRvIGJlIGFzc2lnbmVkIHRvIGEgbmV3IG9iamVjdFxuICAgICAgZXZlbnRzID0gdGFyZ2V0Ll9ldmVudHM7XG4gICAgfVxuICAgIGV4aXN0aW5nID0gZXZlbnRzW3R5cGVdO1xuICB9XG5cbiAgaWYgKGV4aXN0aW5nID09PSB1bmRlZmluZWQpIHtcbiAgICAvLyBPcHRpbWl6ZSB0aGUgY2FzZSBvZiBvbmUgbGlzdGVuZXIuIERvbid0IG5lZWQgdGhlIGV4dHJhIGFycmF5IG9iamVjdC5cbiAgICBleGlzdGluZyA9IGV2ZW50c1t0eXBlXSA9IGxpc3RlbmVyO1xuICAgICsrdGFyZ2V0Ll9ldmVudHNDb3VudDtcbiAgfSBlbHNlIHtcbiAgICBpZiAodHlwZW9mIGV4aXN0aW5nID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAvLyBBZGRpbmcgdGhlIHNlY29uZCBlbGVtZW50LCBuZWVkIHRvIGNoYW5nZSB0byBhcnJheS5cbiAgICAgIGV4aXN0aW5nID0gZXZlbnRzW3R5cGVdID1cbiAgICAgICAgcHJlcGVuZCA/IFtsaXN0ZW5lciwgZXhpc3RpbmddIDogW2V4aXN0aW5nLCBsaXN0ZW5lcl07XG4gICAgICAvLyBJZiB3ZSd2ZSBhbHJlYWR5IGdvdCBhbiBhcnJheSwganVzdCBhcHBlbmQuXG4gICAgfSBlbHNlIGlmIChwcmVwZW5kKSB7XG4gICAgICBleGlzdGluZy51bnNoaWZ0KGxpc3RlbmVyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZXhpc3RpbmcucHVzaChsaXN0ZW5lcik7XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgZm9yIGxpc3RlbmVyIGxlYWtcbiAgICBtID0gX2dldE1heExpc3RlbmVycyh0YXJnZXQpO1xuICAgIGlmIChtID4gMCAmJiBleGlzdGluZy5sZW5ndGggPiBtICYmICFleGlzdGluZy53YXJuZWQpIHtcbiAgICAgIGV4aXN0aW5nLndhcm5lZCA9IHRydWU7XG4gICAgICAvLyBObyBlcnJvciBjb2RlIGZvciB0aGlzIHNpbmNlIGl0IGlzIGEgV2FybmluZ1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXJlc3RyaWN0ZWQtc3ludGF4XG4gICAgICB2YXIgdyA9IG5ldyBFcnJvcignUG9zc2libGUgRXZlbnRFbWl0dGVyIG1lbW9yeSBsZWFrIGRldGVjdGVkLiAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgZXhpc3RpbmcubGVuZ3RoICsgJyAnICsgU3RyaW5nKHR5cGUpICsgJyBsaXN0ZW5lcnMgJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICdhZGRlZC4gVXNlIGVtaXR0ZXIuc2V0TWF4TGlzdGVuZXJzKCkgdG8gJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICdpbmNyZWFzZSBsaW1pdCcpO1xuICAgICAgdy5uYW1lID0gJ01heExpc3RlbmVyc0V4Y2VlZGVkV2FybmluZyc7XG4gICAgICB3LmVtaXR0ZXIgPSB0YXJnZXQ7XG4gICAgICB3LnR5cGUgPSB0eXBlO1xuICAgICAgdy5jb3VudCA9IGV4aXN0aW5nLmxlbmd0aDtcbiAgICAgIFByb2Nlc3NFbWl0V2FybmluZyh3KTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGFyZ2V0O1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmFkZExpc3RlbmVyID0gZnVuY3Rpb24gYWRkTGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpIHtcbiAgcmV0dXJuIF9hZGRMaXN0ZW5lcih0aGlzLCB0eXBlLCBsaXN0ZW5lciwgZmFsc2UpO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbiA9IEV2ZW50RW1pdHRlci5wcm90b3R5cGUuYWRkTGlzdGVuZXI7XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucHJlcGVuZExpc3RlbmVyID1cbiAgICBmdW5jdGlvbiBwcmVwZW5kTGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpIHtcbiAgICAgIHJldHVybiBfYWRkTGlzdGVuZXIodGhpcywgdHlwZSwgbGlzdGVuZXIsIHRydWUpO1xuICAgIH07XG5cbmZ1bmN0aW9uIG9uY2VXcmFwcGVyKCkge1xuICBpZiAoIXRoaXMuZmlyZWQpIHtcbiAgICB0aGlzLnRhcmdldC5yZW1vdmVMaXN0ZW5lcih0aGlzLnR5cGUsIHRoaXMud3JhcEZuKTtcbiAgICB0aGlzLmZpcmVkID0gdHJ1ZTtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMClcbiAgICAgIHJldHVybiB0aGlzLmxpc3RlbmVyLmNhbGwodGhpcy50YXJnZXQpO1xuICAgIHJldHVybiB0aGlzLmxpc3RlbmVyLmFwcGx5KHRoaXMudGFyZ2V0LCBhcmd1bWVudHMpO1xuICB9XG59XG5cbmZ1bmN0aW9uIF9vbmNlV3JhcCh0YXJnZXQsIHR5cGUsIGxpc3RlbmVyKSB7XG4gIHZhciBzdGF0ZSA9IHsgZmlyZWQ6IGZhbHNlLCB3cmFwRm46IHVuZGVmaW5lZCwgdGFyZ2V0OiB0YXJnZXQsIHR5cGU6IHR5cGUsIGxpc3RlbmVyOiBsaXN0ZW5lciB9O1xuICB2YXIgd3JhcHBlZCA9IG9uY2VXcmFwcGVyLmJpbmQoc3RhdGUpO1xuICB3cmFwcGVkLmxpc3RlbmVyID0gbGlzdGVuZXI7XG4gIHN0YXRlLndyYXBGbiA9IHdyYXBwZWQ7XG4gIHJldHVybiB3cmFwcGVkO1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbiBvbmNlKHR5cGUsIGxpc3RlbmVyKSB7XG4gIGNoZWNrTGlzdGVuZXIobGlzdGVuZXIpO1xuICB0aGlzLm9uKHR5cGUsIF9vbmNlV3JhcCh0aGlzLCB0eXBlLCBsaXN0ZW5lcikpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucHJlcGVuZE9uY2VMaXN0ZW5lciA9XG4gICAgZnVuY3Rpb24gcHJlcGVuZE9uY2VMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcikge1xuICAgICAgY2hlY2tMaXN0ZW5lcihsaXN0ZW5lcik7XG4gICAgICB0aGlzLnByZXBlbmRMaXN0ZW5lcih0eXBlLCBfb25jZVdyYXAodGhpcywgdHlwZSwgbGlzdGVuZXIpKTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbi8vIEVtaXRzIGEgJ3JlbW92ZUxpc3RlbmVyJyBldmVudCBpZiBhbmQgb25seSBpZiB0aGUgbGlzdGVuZXIgd2FzIHJlbW92ZWQuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUxpc3RlbmVyID1cbiAgICBmdW5jdGlvbiByZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcikge1xuICAgICAgdmFyIGxpc3QsIGV2ZW50cywgcG9zaXRpb24sIGksIG9yaWdpbmFsTGlzdGVuZXI7XG5cbiAgICAgIGNoZWNrTGlzdGVuZXIobGlzdGVuZXIpO1xuXG4gICAgICBldmVudHMgPSB0aGlzLl9ldmVudHM7XG4gICAgICBpZiAoZXZlbnRzID09PSB1bmRlZmluZWQpXG4gICAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgICBsaXN0ID0gZXZlbnRzW3R5cGVdO1xuICAgICAgaWYgKGxpc3QgPT09IHVuZGVmaW5lZClcbiAgICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICAgIGlmIChsaXN0ID09PSBsaXN0ZW5lciB8fCBsaXN0Lmxpc3RlbmVyID09PSBsaXN0ZW5lcikge1xuICAgICAgICBpZiAoLS10aGlzLl9ldmVudHNDb3VudCA9PT0gMClcbiAgICAgICAgICB0aGlzLl9ldmVudHMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBkZWxldGUgZXZlbnRzW3R5cGVdO1xuICAgICAgICAgIGlmIChldmVudHMucmVtb3ZlTGlzdGVuZXIpXG4gICAgICAgICAgICB0aGlzLmVtaXQoJ3JlbW92ZUxpc3RlbmVyJywgdHlwZSwgbGlzdC5saXN0ZW5lciB8fCBsaXN0ZW5lcik7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGxpc3QgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgcG9zaXRpb24gPSAtMTtcblxuICAgICAgICBmb3IgKGkgPSBsaXN0Lmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgaWYgKGxpc3RbaV0gPT09IGxpc3RlbmVyIHx8IGxpc3RbaV0ubGlzdGVuZXIgPT09IGxpc3RlbmVyKSB7XG4gICAgICAgICAgICBvcmlnaW5hbExpc3RlbmVyID0gbGlzdFtpXS5saXN0ZW5lcjtcbiAgICAgICAgICAgIHBvc2l0aW9uID0gaTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwb3NpdGlvbiA8IDApXG4gICAgICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICAgICAgaWYgKHBvc2l0aW9uID09PSAwKVxuICAgICAgICAgIGxpc3Quc2hpZnQoKTtcbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgc3BsaWNlT25lKGxpc3QsIHBvc2l0aW9uKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChsaXN0Lmxlbmd0aCA9PT0gMSlcbiAgICAgICAgICBldmVudHNbdHlwZV0gPSBsaXN0WzBdO1xuXG4gICAgICAgIGlmIChldmVudHMucmVtb3ZlTGlzdGVuZXIgIT09IHVuZGVmaW5lZClcbiAgICAgICAgICB0aGlzLmVtaXQoJ3JlbW92ZUxpc3RlbmVyJywgdHlwZSwgb3JpZ2luYWxMaXN0ZW5lciB8fCBsaXN0ZW5lcik7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub2ZmID0gRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVMaXN0ZW5lcjtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVBbGxMaXN0ZW5lcnMgPVxuICAgIGZ1bmN0aW9uIHJlbW92ZUFsbExpc3RlbmVycyh0eXBlKSB7XG4gICAgICB2YXIgbGlzdGVuZXJzLCBldmVudHMsIGk7XG5cbiAgICAgIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcbiAgICAgIGlmIChldmVudHMgPT09IHVuZGVmaW5lZClcbiAgICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICAgIC8vIG5vdCBsaXN0ZW5pbmcgZm9yIHJlbW92ZUxpc3RlbmVyLCBubyBuZWVkIHRvIGVtaXRcbiAgICAgIGlmIChldmVudHMucmVtb3ZlTGlzdGVuZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHRoaXMuX2V2ZW50cyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgICAgICAgdGhpcy5fZXZlbnRzQ291bnQgPSAwO1xuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50c1t0eXBlXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgaWYgKC0tdGhpcy5fZXZlbnRzQ291bnQgPT09IDApXG4gICAgICAgICAgICB0aGlzLl9ldmVudHMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIGRlbGV0ZSBldmVudHNbdHlwZV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG5cbiAgICAgIC8vIGVtaXQgcmVtb3ZlTGlzdGVuZXIgZm9yIGFsbCBsaXN0ZW5lcnMgb24gYWxsIGV2ZW50c1xuICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhldmVudHMpO1xuICAgICAgICB2YXIga2V5O1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIGtleSA9IGtleXNbaV07XG4gICAgICAgICAgaWYgKGtleSA9PT0gJ3JlbW92ZUxpc3RlbmVyJykgY29udGludWU7XG4gICAgICAgICAgdGhpcy5yZW1vdmVBbGxMaXN0ZW5lcnMoa2V5KTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnJlbW92ZUFsbExpc3RlbmVycygncmVtb3ZlTGlzdGVuZXInKTtcbiAgICAgICAgdGhpcy5fZXZlbnRzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICAgICAgdGhpcy5fZXZlbnRzQ291bnQgPSAwO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cblxuICAgICAgbGlzdGVuZXJzID0gZXZlbnRzW3R5cGVdO1xuXG4gICAgICBpZiAodHlwZW9mIGxpc3RlbmVycyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVycyk7XG4gICAgICB9IGVsc2UgaWYgKGxpc3RlbmVycyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIC8vIExJRk8gb3JkZXJcbiAgICAgICAgZm9yIChpID0gbGlzdGVuZXJzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgdGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcnNbaV0pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbmZ1bmN0aW9uIF9saXN0ZW5lcnModGFyZ2V0LCB0eXBlLCB1bndyYXApIHtcbiAgdmFyIGV2ZW50cyA9IHRhcmdldC5fZXZlbnRzO1xuXG4gIGlmIChldmVudHMgPT09IHVuZGVmaW5lZClcbiAgICByZXR1cm4gW107XG5cbiAgdmFyIGV2bGlzdGVuZXIgPSBldmVudHNbdHlwZV07XG4gIGlmIChldmxpc3RlbmVyID09PSB1bmRlZmluZWQpXG4gICAgcmV0dXJuIFtdO1xuXG4gIGlmICh0eXBlb2YgZXZsaXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJylcbiAgICByZXR1cm4gdW53cmFwID8gW2V2bGlzdGVuZXIubGlzdGVuZXIgfHwgZXZsaXN0ZW5lcl0gOiBbZXZsaXN0ZW5lcl07XG5cbiAgcmV0dXJuIHVud3JhcCA/XG4gICAgdW53cmFwTGlzdGVuZXJzKGV2bGlzdGVuZXIpIDogYXJyYXlDbG9uZShldmxpc3RlbmVyLCBldmxpc3RlbmVyLmxlbmd0aCk7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUubGlzdGVuZXJzID0gZnVuY3Rpb24gbGlzdGVuZXJzKHR5cGUpIHtcbiAgcmV0dXJuIF9saXN0ZW5lcnModGhpcywgdHlwZSwgdHJ1ZSk7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJhd0xpc3RlbmVycyA9IGZ1bmN0aW9uIHJhd0xpc3RlbmVycyh0eXBlKSB7XG4gIHJldHVybiBfbGlzdGVuZXJzKHRoaXMsIHR5cGUsIGZhbHNlKTtcbn07XG5cbkV2ZW50RW1pdHRlci5saXN0ZW5lckNvdW50ID0gZnVuY3Rpb24oZW1pdHRlciwgdHlwZSkge1xuICBpZiAodHlwZW9mIGVtaXR0ZXIubGlzdGVuZXJDb3VudCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBlbWl0dGVyLmxpc3RlbmVyQ291bnQodHlwZSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGxpc3RlbmVyQ291bnQuY2FsbChlbWl0dGVyLCB0eXBlKTtcbiAgfVxufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5saXN0ZW5lckNvdW50ID0gbGlzdGVuZXJDb3VudDtcbmZ1bmN0aW9uIGxpc3RlbmVyQ291bnQodHlwZSkge1xuICB2YXIgZXZlbnRzID0gdGhpcy5fZXZlbnRzO1xuXG4gIGlmIChldmVudHMgIT09IHVuZGVmaW5lZCkge1xuICAgIHZhciBldmxpc3RlbmVyID0gZXZlbnRzW3R5cGVdO1xuXG4gICAgaWYgKHR5cGVvZiBldmxpc3RlbmVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZXR1cm4gMTtcbiAgICB9IGVsc2UgaWYgKGV2bGlzdGVuZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIGV2bGlzdGVuZXIubGVuZ3RoO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiAwO1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmV2ZW50TmFtZXMgPSBmdW5jdGlvbiBldmVudE5hbWVzKCkge1xuICByZXR1cm4gdGhpcy5fZXZlbnRzQ291bnQgPiAwID8gUmVmbGVjdE93bktleXModGhpcy5fZXZlbnRzKSA6IFtdO1xufTtcblxuZnVuY3Rpb24gYXJyYXlDbG9uZShhcnIsIG4pIHtcbiAgdmFyIGNvcHkgPSBuZXcgQXJyYXkobik7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbjsgKytpKVxuICAgIGNvcHlbaV0gPSBhcnJbaV07XG4gIHJldHVybiBjb3B5O1xufVxuXG5mdW5jdGlvbiBzcGxpY2VPbmUobGlzdCwgaW5kZXgpIHtcbiAgZm9yICg7IGluZGV4ICsgMSA8IGxpc3QubGVuZ3RoOyBpbmRleCsrKVxuICAgIGxpc3RbaW5kZXhdID0gbGlzdFtpbmRleCArIDFdO1xuICBsaXN0LnBvcCgpO1xufVxuXG5mdW5jdGlvbiB1bndyYXBMaXN0ZW5lcnMoYXJyKSB7XG4gIHZhciByZXQgPSBuZXcgQXJyYXkoYXJyLmxlbmd0aCk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcmV0Lmxlbmd0aDsgKytpKSB7XG4gICAgcmV0W2ldID0gYXJyW2ldLmxpc3RlbmVyIHx8IGFycltpXTtcbiAgfVxuICByZXR1cm4gcmV0O1xufVxuXG5mdW5jdGlvbiBvbmNlKGVtaXR0ZXIsIG5hbWUpIHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICBmdW5jdGlvbiBlcnJvckxpc3RlbmVyKGVycikge1xuICAgICAgZW1pdHRlci5yZW1vdmVMaXN0ZW5lcihuYW1lLCByZXNvbHZlcik7XG4gICAgICByZWplY3QoZXJyKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiByZXNvbHZlcigpIHtcbiAgICAgIGlmICh0eXBlb2YgZW1pdHRlci5yZW1vdmVMaXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBlbWl0dGVyLnJlbW92ZUxpc3RlbmVyKCdlcnJvcicsIGVycm9yTGlzdGVuZXIpO1xuICAgICAgfVxuICAgICAgcmVzb2x2ZShbXS5zbGljZS5jYWxsKGFyZ3VtZW50cykpO1xuICAgIH07XG5cbiAgICBldmVudFRhcmdldEFnbm9zdGljQWRkTGlzdGVuZXIoZW1pdHRlciwgbmFtZSwgcmVzb2x2ZXIsIHsgb25jZTogdHJ1ZSB9KTtcbiAgICBpZiAobmFtZSAhPT0gJ2Vycm9yJykge1xuICAgICAgYWRkRXJyb3JIYW5kbGVySWZFdmVudEVtaXR0ZXIoZW1pdHRlciwgZXJyb3JMaXN0ZW5lciwgeyBvbmNlOiB0cnVlIH0pO1xuICAgIH1cbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGFkZEVycm9ySGFuZGxlcklmRXZlbnRFbWl0dGVyKGVtaXR0ZXIsIGhhbmRsZXIsIGZsYWdzKSB7XG4gIGlmICh0eXBlb2YgZW1pdHRlci5vbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGV2ZW50VGFyZ2V0QWdub3N0aWNBZGRMaXN0ZW5lcihlbWl0dGVyLCAnZXJyb3InLCBoYW5kbGVyLCBmbGFncyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZXZlbnRUYXJnZXRBZ25vc3RpY0FkZExpc3RlbmVyKGVtaXR0ZXIsIG5hbWUsIGxpc3RlbmVyLCBmbGFncykge1xuICBpZiAodHlwZW9mIGVtaXR0ZXIub24gPT09ICdmdW5jdGlvbicpIHtcbiAgICBpZiAoZmxhZ3Mub25jZSkge1xuICAgICAgZW1pdHRlci5vbmNlKG5hbWUsIGxpc3RlbmVyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZW1pdHRlci5vbihuYW1lLCBsaXN0ZW5lcik7XG4gICAgfVxuICB9IGVsc2UgaWYgKHR5cGVvZiBlbWl0dGVyLmFkZEV2ZW50TGlzdGVuZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICAvLyBFdmVudFRhcmdldCBkb2VzIG5vdCBoYXZlIGBlcnJvcmAgZXZlbnQgc2VtYW50aWNzIGxpa2UgTm9kZVxuICAgIC8vIEV2ZW50RW1pdHRlcnMsIHdlIGRvIG5vdCBsaXN0ZW4gZm9yIGBlcnJvcmAgZXZlbnRzIGhlcmUuXG4gICAgZW1pdHRlci5hZGRFdmVudExpc3RlbmVyKG5hbWUsIGZ1bmN0aW9uIHdyYXBMaXN0ZW5lcihhcmcpIHtcbiAgICAgIC8vIElFIGRvZXMgbm90IGhhdmUgYnVpbHRpbiBgeyBvbmNlOiB0cnVlIH1gIHN1cHBvcnQgc28gd2VcbiAgICAgIC8vIGhhdmUgdG8gZG8gaXQgbWFudWFsbHkuXG4gICAgICBpZiAoZmxhZ3Mub25jZSkge1xuICAgICAgICBlbWl0dGVyLnJlbW92ZUV2ZW50TGlzdGVuZXIobmFtZSwgd3JhcExpc3RlbmVyKTtcbiAgICAgIH1cbiAgICAgIGxpc3RlbmVyKGFyZyk7XG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhlIFwiZW1pdHRlclwiIGFyZ3VtZW50IG11c3QgYmUgb2YgdHlwZSBFdmVudEVtaXR0ZXIuIFJlY2VpdmVkIHR5cGUgJyArIHR5cGVvZiBlbWl0dGVyKTtcbiAgfVxufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKiBlc2xpbnQgbm8taW52YWxpZC10aGlzOiAxICovXG5cbnZhciBFUlJPUl9NRVNTQUdFID0gJ0Z1bmN0aW9uLnByb3RvdHlwZS5iaW5kIGNhbGxlZCBvbiBpbmNvbXBhdGlibGUgJztcbnZhciB0b1N0ciA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG52YXIgbWF4ID0gTWF0aC5tYXg7XG52YXIgZnVuY1R5cGUgPSAnW29iamVjdCBGdW5jdGlvbl0nO1xuXG52YXIgY29uY2F0dHkgPSBmdW5jdGlvbiBjb25jYXR0eShhLCBiKSB7XG4gICAgdmFyIGFyciA9IFtdO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgIGFycltpXSA9IGFbaV07XG4gICAgfVxuICAgIGZvciAodmFyIGogPSAwOyBqIDwgYi5sZW5ndGg7IGogKz0gMSkge1xuICAgICAgICBhcnJbaiArIGEubGVuZ3RoXSA9IGJbal07XG4gICAgfVxuXG4gICAgcmV0dXJuIGFycjtcbn07XG5cbnZhciBzbGljeSA9IGZ1bmN0aW9uIHNsaWN5KGFyckxpa2UsIG9mZnNldCkge1xuICAgIHZhciBhcnIgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gb2Zmc2V0IHx8IDAsIGogPSAwOyBpIDwgYXJyTGlrZS5sZW5ndGg7IGkgKz0gMSwgaiArPSAxKSB7XG4gICAgICAgIGFycltqXSA9IGFyckxpa2VbaV07XG4gICAgfVxuICAgIHJldHVybiBhcnI7XG59O1xuXG52YXIgam9pbnkgPSBmdW5jdGlvbiAoYXJyLCBqb2luZXIpIHtcbiAgICB2YXIgc3RyID0gJyc7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgc3RyICs9IGFycltpXTtcbiAgICAgICAgaWYgKGkgKyAxIDwgYXJyLmxlbmd0aCkge1xuICAgICAgICAgICAgc3RyICs9IGpvaW5lcjtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gc3RyO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBiaW5kKHRoYXQpIHtcbiAgICB2YXIgdGFyZ2V0ID0gdGhpcztcbiAgICBpZiAodHlwZW9mIHRhcmdldCAhPT0gJ2Z1bmN0aW9uJyB8fCB0b1N0ci5hcHBseSh0YXJnZXQpICE9PSBmdW5jVHlwZSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKEVSUk9SX01FU1NBR0UgKyB0YXJnZXQpO1xuICAgIH1cbiAgICB2YXIgYXJncyA9IHNsaWN5KGFyZ3VtZW50cywgMSk7XG5cbiAgICB2YXIgYm91bmQ7XG4gICAgdmFyIGJpbmRlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMgaW5zdGFuY2VvZiBib3VuZCkge1xuICAgICAgICAgICAgdmFyIHJlc3VsdCA9IHRhcmdldC5hcHBseShcbiAgICAgICAgICAgICAgICB0aGlzLFxuICAgICAgICAgICAgICAgIGNvbmNhdHR5KGFyZ3MsIGFyZ3VtZW50cylcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBpZiAoT2JqZWN0KHJlc3VsdCkgPT09IHJlc3VsdCkge1xuICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGFyZ2V0LmFwcGx5KFxuICAgICAgICAgICAgdGhhdCxcbiAgICAgICAgICAgIGNvbmNhdHR5KGFyZ3MsIGFyZ3VtZW50cylcbiAgICAgICAgKTtcblxuICAgIH07XG5cbiAgICB2YXIgYm91bmRMZW5ndGggPSBtYXgoMCwgdGFyZ2V0Lmxlbmd0aCAtIGFyZ3MubGVuZ3RoKTtcbiAgICB2YXIgYm91bmRBcmdzID0gW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBib3VuZExlbmd0aDsgaSsrKSB7XG4gICAgICAgIGJvdW5kQXJnc1tpXSA9ICckJyArIGk7XG4gICAgfVxuXG4gICAgYm91bmQgPSBGdW5jdGlvbignYmluZGVyJywgJ3JldHVybiBmdW5jdGlvbiAoJyArIGpvaW55KGJvdW5kQXJncywgJywnKSArICcpeyByZXR1cm4gYmluZGVyLmFwcGx5KHRoaXMsYXJndW1lbnRzKTsgfScpKGJpbmRlcik7XG5cbiAgICBpZiAodGFyZ2V0LnByb3RvdHlwZSkge1xuICAgICAgICB2YXIgRW1wdHkgPSBmdW5jdGlvbiBFbXB0eSgpIHt9O1xuICAgICAgICBFbXB0eS5wcm90b3R5cGUgPSB0YXJnZXQucHJvdG90eXBlO1xuICAgICAgICBib3VuZC5wcm90b3R5cGUgPSBuZXcgRW1wdHkoKTtcbiAgICAgICAgRW1wdHkucHJvdG90eXBlID0gbnVsbDtcbiAgICB9XG5cbiAgICByZXR1cm4gYm91bmQ7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgaW1wbGVtZW50YXRpb24gPSByZXF1aXJlKCcuL2ltcGxlbWVudGF0aW9uJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQgfHwgaW1wbGVtZW50YXRpb247XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciB1bmRlZmluZWQ7XG5cbnZhciAkT2JqZWN0ID0gcmVxdWlyZSgnZXMtb2JqZWN0LWF0b21zJyk7XG5cbnZhciAkRXJyb3IgPSByZXF1aXJlKCdlcy1lcnJvcnMnKTtcbnZhciAkRXZhbEVycm9yID0gcmVxdWlyZSgnZXMtZXJyb3JzL2V2YWwnKTtcbnZhciAkUmFuZ2VFcnJvciA9IHJlcXVpcmUoJ2VzLWVycm9ycy9yYW5nZScpO1xudmFyICRSZWZlcmVuY2VFcnJvciA9IHJlcXVpcmUoJ2VzLWVycm9ycy9yZWYnKTtcbnZhciAkU3ludGF4RXJyb3IgPSByZXF1aXJlKCdlcy1lcnJvcnMvc3ludGF4Jyk7XG52YXIgJFR5cGVFcnJvciA9IHJlcXVpcmUoJ2VzLWVycm9ycy90eXBlJyk7XG52YXIgJFVSSUVycm9yID0gcmVxdWlyZSgnZXMtZXJyb3JzL3VyaScpO1xuXG52YXIgYWJzID0gcmVxdWlyZSgnbWF0aC1pbnRyaW5zaWNzL2FicycpO1xudmFyIGZsb29yID0gcmVxdWlyZSgnbWF0aC1pbnRyaW5zaWNzL2Zsb29yJyk7XG52YXIgbWF4ID0gcmVxdWlyZSgnbWF0aC1pbnRyaW5zaWNzL21heCcpO1xudmFyIG1pbiA9IHJlcXVpcmUoJ21hdGgtaW50cmluc2ljcy9taW4nKTtcbnZhciBwb3cgPSByZXF1aXJlKCdtYXRoLWludHJpbnNpY3MvcG93Jyk7XG52YXIgcm91bmQgPSByZXF1aXJlKCdtYXRoLWludHJpbnNpY3Mvcm91bmQnKTtcbnZhciBzaWduID0gcmVxdWlyZSgnbWF0aC1pbnRyaW5zaWNzL3NpZ24nKTtcblxudmFyICRGdW5jdGlvbiA9IEZ1bmN0aW9uO1xuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY29uc2lzdGVudC1yZXR1cm5cbnZhciBnZXRFdmFsbGVkQ29uc3RydWN0b3IgPSBmdW5jdGlvbiAoZXhwcmVzc2lvblN5bnRheCkge1xuXHR0cnkge1xuXHRcdHJldHVybiAkRnVuY3Rpb24oJ1widXNlIHN0cmljdFwiOyByZXR1cm4gKCcgKyBleHByZXNzaW9uU3ludGF4ICsgJykuY29uc3RydWN0b3I7JykoKTtcblx0fSBjYXRjaCAoZSkge31cbn07XG5cbnZhciAkZ09QRCA9IHJlcXVpcmUoJ2dvcGQnKTtcbnZhciAkZGVmaW5lUHJvcGVydHkgPSByZXF1aXJlKCdlcy1kZWZpbmUtcHJvcGVydHknKTtcblxudmFyIHRocm93VHlwZUVycm9yID0gZnVuY3Rpb24gKCkge1xuXHR0aHJvdyBuZXcgJFR5cGVFcnJvcigpO1xufTtcbnZhciBUaHJvd1R5cGVFcnJvciA9ICRnT1BEXG5cdD8gKGZ1bmN0aW9uICgpIHtcblx0XHR0cnkge1xuXHRcdFx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVudXNlZC1leHByZXNzaW9ucywgbm8tY2FsbGVyLCBuby1yZXN0cmljdGVkLXByb3BlcnRpZXNcblx0XHRcdGFyZ3VtZW50cy5jYWxsZWU7IC8vIElFIDggZG9lcyBub3QgdGhyb3cgaGVyZVxuXHRcdFx0cmV0dXJuIHRocm93VHlwZUVycm9yO1xuXHRcdH0gY2F0Y2ggKGNhbGxlZVRocm93cykge1xuXHRcdFx0dHJ5IHtcblx0XHRcdFx0Ly8gSUUgOCB0aHJvd3Mgb24gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihhcmd1bWVudHMsICcnKVxuXHRcdFx0XHRyZXR1cm4gJGdPUEQoYXJndW1lbnRzLCAnY2FsbGVlJykuZ2V0O1xuXHRcdFx0fSBjYXRjaCAoZ09QRHRocm93cykge1xuXHRcdFx0XHRyZXR1cm4gdGhyb3dUeXBlRXJyb3I7XG5cdFx0XHR9XG5cdFx0fVxuXHR9KCkpXG5cdDogdGhyb3dUeXBlRXJyb3I7XG5cbnZhciBoYXNTeW1ib2xzID0gcmVxdWlyZSgnaGFzLXN5bWJvbHMnKSgpO1xuXG52YXIgZ2V0UHJvdG8gPSByZXF1aXJlKCdnZXQtcHJvdG8nKTtcbnZhciAkT2JqZWN0R1BPID0gcmVxdWlyZSgnZ2V0LXByb3RvL09iamVjdC5nZXRQcm90b3R5cGVPZicpO1xudmFyICRSZWZsZWN0R1BPID0gcmVxdWlyZSgnZ2V0LXByb3RvL1JlZmxlY3QuZ2V0UHJvdG90eXBlT2YnKTtcblxudmFyICRhcHBseSA9IHJlcXVpcmUoJ2NhbGwtYmluZC1hcHBseS1oZWxwZXJzL2Z1bmN0aW9uQXBwbHknKTtcbnZhciAkY2FsbCA9IHJlcXVpcmUoJ2NhbGwtYmluZC1hcHBseS1oZWxwZXJzL2Z1bmN0aW9uQ2FsbCcpO1xuXG52YXIgbmVlZHNFdmFsID0ge307XG5cbnZhciBUeXBlZEFycmF5ID0gdHlwZW9mIFVpbnQ4QXJyYXkgPT09ICd1bmRlZmluZWQnIHx8ICFnZXRQcm90byA/IHVuZGVmaW5lZCA6IGdldFByb3RvKFVpbnQ4QXJyYXkpO1xuXG52YXIgSU5UUklOU0lDUyA9IHtcblx0X19wcm90b19fOiBudWxsLFxuXHQnJUFnZ3JlZ2F0ZUVycm9yJSc6IHR5cGVvZiBBZ2dyZWdhdGVFcnJvciA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBBZ2dyZWdhdGVFcnJvcixcblx0JyVBcnJheSUnOiBBcnJheSxcblx0JyVBcnJheUJ1ZmZlciUnOiB0eXBlb2YgQXJyYXlCdWZmZXIgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogQXJyYXlCdWZmZXIsXG5cdCclQXJyYXlJdGVyYXRvclByb3RvdHlwZSUnOiBoYXNTeW1ib2xzICYmIGdldFByb3RvID8gZ2V0UHJvdG8oW11bU3ltYm9sLml0ZXJhdG9yXSgpKSA6IHVuZGVmaW5lZCxcblx0JyVBc3luY0Zyb21TeW5jSXRlcmF0b3JQcm90b3R5cGUlJzogdW5kZWZpbmVkLFxuXHQnJUFzeW5jRnVuY3Rpb24lJzogbmVlZHNFdmFsLFxuXHQnJUFzeW5jR2VuZXJhdG9yJSc6IG5lZWRzRXZhbCxcblx0JyVBc3luY0dlbmVyYXRvckZ1bmN0aW9uJSc6IG5lZWRzRXZhbCxcblx0JyVBc3luY0l0ZXJhdG9yUHJvdG90eXBlJSc6IG5lZWRzRXZhbCxcblx0JyVBdG9taWNzJSc6IHR5cGVvZiBBdG9taWNzID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IEF0b21pY3MsXG5cdCclQmlnSW50JSc6IHR5cGVvZiBCaWdJbnQgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogQmlnSW50LFxuXHQnJUJpZ0ludDY0QXJyYXklJzogdHlwZW9mIEJpZ0ludDY0QXJyYXkgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogQmlnSW50NjRBcnJheSxcblx0JyVCaWdVaW50NjRBcnJheSUnOiB0eXBlb2YgQmlnVWludDY0QXJyYXkgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogQmlnVWludDY0QXJyYXksXG5cdCclQm9vbGVhbiUnOiBCb29sZWFuLFxuXHQnJURhdGFWaWV3JSc6IHR5cGVvZiBEYXRhVmlldyA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBEYXRhVmlldyxcblx0JyVEYXRlJSc6IERhdGUsXG5cdCclZGVjb2RlVVJJJSc6IGRlY29kZVVSSSxcblx0JyVkZWNvZGVVUklDb21wb25lbnQlJzogZGVjb2RlVVJJQ29tcG9uZW50LFxuXHQnJWVuY29kZVVSSSUnOiBlbmNvZGVVUkksXG5cdCclZW5jb2RlVVJJQ29tcG9uZW50JSc6IGVuY29kZVVSSUNvbXBvbmVudCxcblx0JyVFcnJvciUnOiAkRXJyb3IsXG5cdCclZXZhbCUnOiBldmFsLCAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLWV2YWxcblx0JyVFdmFsRXJyb3IlJzogJEV2YWxFcnJvcixcblx0JyVGbG9hdDE2QXJyYXklJzogdHlwZW9mIEZsb2F0MTZBcnJheSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBGbG9hdDE2QXJyYXksXG5cdCclRmxvYXQzMkFycmF5JSc6IHR5cGVvZiBGbG9hdDMyQXJyYXkgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogRmxvYXQzMkFycmF5LFxuXHQnJUZsb2F0NjRBcnJheSUnOiB0eXBlb2YgRmxvYXQ2NEFycmF5ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IEZsb2F0NjRBcnJheSxcblx0JyVGaW5hbGl6YXRpb25SZWdpc3RyeSUnOiB0eXBlb2YgRmluYWxpemF0aW9uUmVnaXN0cnkgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogRmluYWxpemF0aW9uUmVnaXN0cnksXG5cdCclRnVuY3Rpb24lJzogJEZ1bmN0aW9uLFxuXHQnJUdlbmVyYXRvckZ1bmN0aW9uJSc6IG5lZWRzRXZhbCxcblx0JyVJbnQ4QXJyYXklJzogdHlwZW9mIEludDhBcnJheSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBJbnQ4QXJyYXksXG5cdCclSW50MTZBcnJheSUnOiB0eXBlb2YgSW50MTZBcnJheSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBJbnQxNkFycmF5LFxuXHQnJUludDMyQXJyYXklJzogdHlwZW9mIEludDMyQXJyYXkgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogSW50MzJBcnJheSxcblx0JyVpc0Zpbml0ZSUnOiBpc0Zpbml0ZSxcblx0JyVpc05hTiUnOiBpc05hTixcblx0JyVJdGVyYXRvclByb3RvdHlwZSUnOiBoYXNTeW1ib2xzICYmIGdldFByb3RvID8gZ2V0UHJvdG8oZ2V0UHJvdG8oW11bU3ltYm9sLml0ZXJhdG9yXSgpKSkgOiB1bmRlZmluZWQsXG5cdCclSlNPTiUnOiB0eXBlb2YgSlNPTiA9PT0gJ29iamVjdCcgPyBKU09OIDogdW5kZWZpbmVkLFxuXHQnJU1hcCUnOiB0eXBlb2YgTWFwID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IE1hcCxcblx0JyVNYXBJdGVyYXRvclByb3RvdHlwZSUnOiB0eXBlb2YgTWFwID09PSAndW5kZWZpbmVkJyB8fCAhaGFzU3ltYm9scyB8fCAhZ2V0UHJvdG8gPyB1bmRlZmluZWQgOiBnZXRQcm90byhuZXcgTWFwKClbU3ltYm9sLml0ZXJhdG9yXSgpKSxcblx0JyVNYXRoJSc6IE1hdGgsXG5cdCclTnVtYmVyJSc6IE51bWJlcixcblx0JyVPYmplY3QlJzogJE9iamVjdCxcblx0JyVPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yJSc6ICRnT1BELFxuXHQnJXBhcnNlRmxvYXQlJzogcGFyc2VGbG9hdCxcblx0JyVwYXJzZUludCUnOiBwYXJzZUludCxcblx0JyVQcm9taXNlJSc6IHR5cGVvZiBQcm9taXNlID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IFByb21pc2UsXG5cdCclUHJveHklJzogdHlwZW9mIFByb3h5ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IFByb3h5LFxuXHQnJVJhbmdlRXJyb3IlJzogJFJhbmdlRXJyb3IsXG5cdCclUmVmZXJlbmNlRXJyb3IlJzogJFJlZmVyZW5jZUVycm9yLFxuXHQnJVJlZmxlY3QlJzogdHlwZW9mIFJlZmxlY3QgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogUmVmbGVjdCxcblx0JyVSZWdFeHAlJzogUmVnRXhwLFxuXHQnJVNldCUnOiB0eXBlb2YgU2V0ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IFNldCxcblx0JyVTZXRJdGVyYXRvclByb3RvdHlwZSUnOiB0eXBlb2YgU2V0ID09PSAndW5kZWZpbmVkJyB8fCAhaGFzU3ltYm9scyB8fCAhZ2V0UHJvdG8gPyB1bmRlZmluZWQgOiBnZXRQcm90byhuZXcgU2V0KClbU3ltYm9sLml0ZXJhdG9yXSgpKSxcblx0JyVTaGFyZWRBcnJheUJ1ZmZlciUnOiB0eXBlb2YgU2hhcmVkQXJyYXlCdWZmZXIgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogU2hhcmVkQXJyYXlCdWZmZXIsXG5cdCclU3RyaW5nJSc6IFN0cmluZyxcblx0JyVTdHJpbmdJdGVyYXRvclByb3RvdHlwZSUnOiBoYXNTeW1ib2xzICYmIGdldFByb3RvID8gZ2V0UHJvdG8oJydbU3ltYm9sLml0ZXJhdG9yXSgpKSA6IHVuZGVmaW5lZCxcblx0JyVTeW1ib2wlJzogaGFzU3ltYm9scyA/IFN5bWJvbCA6IHVuZGVmaW5lZCxcblx0JyVTeW50YXhFcnJvciUnOiAkU3ludGF4RXJyb3IsXG5cdCclVGhyb3dUeXBlRXJyb3IlJzogVGhyb3dUeXBlRXJyb3IsXG5cdCclVHlwZWRBcnJheSUnOiBUeXBlZEFycmF5LFxuXHQnJVR5cGVFcnJvciUnOiAkVHlwZUVycm9yLFxuXHQnJVVpbnQ4QXJyYXklJzogdHlwZW9mIFVpbnQ4QXJyYXkgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogVWludDhBcnJheSxcblx0JyVVaW50OENsYW1wZWRBcnJheSUnOiB0eXBlb2YgVWludDhDbGFtcGVkQXJyYXkgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogVWludDhDbGFtcGVkQXJyYXksXG5cdCclVWludDE2QXJyYXklJzogdHlwZW9mIFVpbnQxNkFycmF5ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IFVpbnQxNkFycmF5LFxuXHQnJVVpbnQzMkFycmF5JSc6IHR5cGVvZiBVaW50MzJBcnJheSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBVaW50MzJBcnJheSxcblx0JyVVUklFcnJvciUnOiAkVVJJRXJyb3IsXG5cdCclV2Vha01hcCUnOiB0eXBlb2YgV2Vha01hcCA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBXZWFrTWFwLFxuXHQnJVdlYWtSZWYlJzogdHlwZW9mIFdlYWtSZWYgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogV2Vha1JlZixcblx0JyVXZWFrU2V0JSc6IHR5cGVvZiBXZWFrU2V0ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IFdlYWtTZXQsXG5cblx0JyVGdW5jdGlvbi5wcm90b3R5cGUuY2FsbCUnOiAkY2FsbCxcblx0JyVGdW5jdGlvbi5wcm90b3R5cGUuYXBwbHklJzogJGFwcGx5LFxuXHQnJU9iamVjdC5kZWZpbmVQcm9wZXJ0eSUnOiAkZGVmaW5lUHJvcGVydHksXG5cdCclT2JqZWN0LmdldFByb3RvdHlwZU9mJSc6ICRPYmplY3RHUE8sXG5cdCclTWF0aC5hYnMlJzogYWJzLFxuXHQnJU1hdGguZmxvb3IlJzogZmxvb3IsXG5cdCclTWF0aC5tYXglJzogbWF4LFxuXHQnJU1hdGgubWluJSc6IG1pbixcblx0JyVNYXRoLnBvdyUnOiBwb3csXG5cdCclTWF0aC5yb3VuZCUnOiByb3VuZCxcblx0JyVNYXRoLnNpZ24lJzogc2lnbixcblx0JyVSZWZsZWN0LmdldFByb3RvdHlwZU9mJSc6ICRSZWZsZWN0R1BPXG59O1xuXG5pZiAoZ2V0UHJvdG8pIHtcblx0dHJ5IHtcblx0XHRudWxsLmVycm9yOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVudXNlZC1leHByZXNzaW9uc1xuXHR9IGNhdGNoIChlKSB7XG5cdFx0Ly8gaHR0cHM6Ly9naXRodWIuY29tL3RjMzkvcHJvcG9zYWwtc2hhZG93cmVhbG0vcHVsbC8zODQjaXNzdWVjb21tZW50LTEzNjQyNjQyMjlcblx0XHR2YXIgZXJyb3JQcm90byA9IGdldFByb3RvKGdldFByb3RvKGUpKTtcblx0XHRJTlRSSU5TSUNTWyclRXJyb3IucHJvdG90eXBlJSddID0gZXJyb3JQcm90bztcblx0fVxufVxuXG52YXIgZG9FdmFsID0gZnVuY3Rpb24gZG9FdmFsKG5hbWUpIHtcblx0dmFyIHZhbHVlO1xuXHRpZiAobmFtZSA9PT0gJyVBc3luY0Z1bmN0aW9uJScpIHtcblx0XHR2YWx1ZSA9IGdldEV2YWxsZWRDb25zdHJ1Y3RvcignYXN5bmMgZnVuY3Rpb24gKCkge30nKTtcblx0fSBlbHNlIGlmIChuYW1lID09PSAnJUdlbmVyYXRvckZ1bmN0aW9uJScpIHtcblx0XHR2YWx1ZSA9IGdldEV2YWxsZWRDb25zdHJ1Y3RvcignZnVuY3Rpb24qICgpIHt9Jyk7XG5cdH0gZWxzZSBpZiAobmFtZSA9PT0gJyVBc3luY0dlbmVyYXRvckZ1bmN0aW9uJScpIHtcblx0XHR2YWx1ZSA9IGdldEV2YWxsZWRDb25zdHJ1Y3RvcignYXN5bmMgZnVuY3Rpb24qICgpIHt9Jyk7XG5cdH0gZWxzZSBpZiAobmFtZSA9PT0gJyVBc3luY0dlbmVyYXRvciUnKSB7XG5cdFx0dmFyIGZuID0gZG9FdmFsKCclQXN5bmNHZW5lcmF0b3JGdW5jdGlvbiUnKTtcblx0XHRpZiAoZm4pIHtcblx0XHRcdHZhbHVlID0gZm4ucHJvdG90eXBlO1xuXHRcdH1cblx0fSBlbHNlIGlmIChuYW1lID09PSAnJUFzeW5jSXRlcmF0b3JQcm90b3R5cGUlJykge1xuXHRcdHZhciBnZW4gPSBkb0V2YWwoJyVBc3luY0dlbmVyYXRvciUnKTtcblx0XHRpZiAoZ2VuICYmIGdldFByb3RvKSB7XG5cdFx0XHR2YWx1ZSA9IGdldFByb3RvKGdlbi5wcm90b3R5cGUpO1xuXHRcdH1cblx0fVxuXG5cdElOVFJJTlNJQ1NbbmFtZV0gPSB2YWx1ZTtcblxuXHRyZXR1cm4gdmFsdWU7XG59O1xuXG52YXIgTEVHQUNZX0FMSUFTRVMgPSB7XG5cdF9fcHJvdG9fXzogbnVsbCxcblx0JyVBcnJheUJ1ZmZlclByb3RvdHlwZSUnOiBbJ0FycmF5QnVmZmVyJywgJ3Byb3RvdHlwZSddLFxuXHQnJUFycmF5UHJvdG90eXBlJSc6IFsnQXJyYXknLCAncHJvdG90eXBlJ10sXG5cdCclQXJyYXlQcm90b19lbnRyaWVzJSc6IFsnQXJyYXknLCAncHJvdG90eXBlJywgJ2VudHJpZXMnXSxcblx0JyVBcnJheVByb3RvX2ZvckVhY2glJzogWydBcnJheScsICdwcm90b3R5cGUnLCAnZm9yRWFjaCddLFxuXHQnJUFycmF5UHJvdG9fa2V5cyUnOiBbJ0FycmF5JywgJ3Byb3RvdHlwZScsICdrZXlzJ10sXG5cdCclQXJyYXlQcm90b192YWx1ZXMlJzogWydBcnJheScsICdwcm90b3R5cGUnLCAndmFsdWVzJ10sXG5cdCclQXN5bmNGdW5jdGlvblByb3RvdHlwZSUnOiBbJ0FzeW5jRnVuY3Rpb24nLCAncHJvdG90eXBlJ10sXG5cdCclQXN5bmNHZW5lcmF0b3IlJzogWydBc3luY0dlbmVyYXRvckZ1bmN0aW9uJywgJ3Byb3RvdHlwZSddLFxuXHQnJUFzeW5jR2VuZXJhdG9yUHJvdG90eXBlJSc6IFsnQXN5bmNHZW5lcmF0b3JGdW5jdGlvbicsICdwcm90b3R5cGUnLCAncHJvdG90eXBlJ10sXG5cdCclQm9vbGVhblByb3RvdHlwZSUnOiBbJ0Jvb2xlYW4nLCAncHJvdG90eXBlJ10sXG5cdCclRGF0YVZpZXdQcm90b3R5cGUlJzogWydEYXRhVmlldycsICdwcm90b3R5cGUnXSxcblx0JyVEYXRlUHJvdG90eXBlJSc6IFsnRGF0ZScsICdwcm90b3R5cGUnXSxcblx0JyVFcnJvclByb3RvdHlwZSUnOiBbJ0Vycm9yJywgJ3Byb3RvdHlwZSddLFxuXHQnJUV2YWxFcnJvclByb3RvdHlwZSUnOiBbJ0V2YWxFcnJvcicsICdwcm90b3R5cGUnXSxcblx0JyVGbG9hdDMyQXJyYXlQcm90b3R5cGUlJzogWydGbG9hdDMyQXJyYXknLCAncHJvdG90eXBlJ10sXG5cdCclRmxvYXQ2NEFycmF5UHJvdG90eXBlJSc6IFsnRmxvYXQ2NEFycmF5JywgJ3Byb3RvdHlwZSddLFxuXHQnJUZ1bmN0aW9uUHJvdG90eXBlJSc6IFsnRnVuY3Rpb24nLCAncHJvdG90eXBlJ10sXG5cdCclR2VuZXJhdG9yJSc6IFsnR2VuZXJhdG9yRnVuY3Rpb24nLCAncHJvdG90eXBlJ10sXG5cdCclR2VuZXJhdG9yUHJvdG90eXBlJSc6IFsnR2VuZXJhdG9yRnVuY3Rpb24nLCAncHJvdG90eXBlJywgJ3Byb3RvdHlwZSddLFxuXHQnJUludDhBcnJheVByb3RvdHlwZSUnOiBbJ0ludDhBcnJheScsICdwcm90b3R5cGUnXSxcblx0JyVJbnQxNkFycmF5UHJvdG90eXBlJSc6IFsnSW50MTZBcnJheScsICdwcm90b3R5cGUnXSxcblx0JyVJbnQzMkFycmF5UHJvdG90eXBlJSc6IFsnSW50MzJBcnJheScsICdwcm90b3R5cGUnXSxcblx0JyVKU09OUGFyc2UlJzogWydKU09OJywgJ3BhcnNlJ10sXG5cdCclSlNPTlN0cmluZ2lmeSUnOiBbJ0pTT04nLCAnc3RyaW5naWZ5J10sXG5cdCclTWFwUHJvdG90eXBlJSc6IFsnTWFwJywgJ3Byb3RvdHlwZSddLFxuXHQnJU51bWJlclByb3RvdHlwZSUnOiBbJ051bWJlcicsICdwcm90b3R5cGUnXSxcblx0JyVPYmplY3RQcm90b3R5cGUlJzogWydPYmplY3QnLCAncHJvdG90eXBlJ10sXG5cdCclT2JqUHJvdG9fdG9TdHJpbmclJzogWydPYmplY3QnLCAncHJvdG90eXBlJywgJ3RvU3RyaW5nJ10sXG5cdCclT2JqUHJvdG9fdmFsdWVPZiUnOiBbJ09iamVjdCcsICdwcm90b3R5cGUnLCAndmFsdWVPZiddLFxuXHQnJVByb21pc2VQcm90b3R5cGUlJzogWydQcm9taXNlJywgJ3Byb3RvdHlwZSddLFxuXHQnJVByb21pc2VQcm90b190aGVuJSc6IFsnUHJvbWlzZScsICdwcm90b3R5cGUnLCAndGhlbiddLFxuXHQnJVByb21pc2VfYWxsJSc6IFsnUHJvbWlzZScsICdhbGwnXSxcblx0JyVQcm9taXNlX3JlamVjdCUnOiBbJ1Byb21pc2UnLCAncmVqZWN0J10sXG5cdCclUHJvbWlzZV9yZXNvbHZlJSc6IFsnUHJvbWlzZScsICdyZXNvbHZlJ10sXG5cdCclUmFuZ2VFcnJvclByb3RvdHlwZSUnOiBbJ1JhbmdlRXJyb3InLCAncHJvdG90eXBlJ10sXG5cdCclUmVmZXJlbmNlRXJyb3JQcm90b3R5cGUlJzogWydSZWZlcmVuY2VFcnJvcicsICdwcm90b3R5cGUnXSxcblx0JyVSZWdFeHBQcm90b3R5cGUlJzogWydSZWdFeHAnLCAncHJvdG90eXBlJ10sXG5cdCclU2V0UHJvdG90eXBlJSc6IFsnU2V0JywgJ3Byb3RvdHlwZSddLFxuXHQnJVNoYXJlZEFycmF5QnVmZmVyUHJvdG90eXBlJSc6IFsnU2hhcmVkQXJyYXlCdWZmZXInLCAncHJvdG90eXBlJ10sXG5cdCclU3RyaW5nUHJvdG90eXBlJSc6IFsnU3RyaW5nJywgJ3Byb3RvdHlwZSddLFxuXHQnJVN5bWJvbFByb3RvdHlwZSUnOiBbJ1N5bWJvbCcsICdwcm90b3R5cGUnXSxcblx0JyVTeW50YXhFcnJvclByb3RvdHlwZSUnOiBbJ1N5bnRheEVycm9yJywgJ3Byb3RvdHlwZSddLFxuXHQnJVR5cGVkQXJyYXlQcm90b3R5cGUlJzogWydUeXBlZEFycmF5JywgJ3Byb3RvdHlwZSddLFxuXHQnJVR5cGVFcnJvclByb3RvdHlwZSUnOiBbJ1R5cGVFcnJvcicsICdwcm90b3R5cGUnXSxcblx0JyVVaW50OEFycmF5UHJvdG90eXBlJSc6IFsnVWludDhBcnJheScsICdwcm90b3R5cGUnXSxcblx0JyVVaW50OENsYW1wZWRBcnJheVByb3RvdHlwZSUnOiBbJ1VpbnQ4Q2xhbXBlZEFycmF5JywgJ3Byb3RvdHlwZSddLFxuXHQnJVVpbnQxNkFycmF5UHJvdG90eXBlJSc6IFsnVWludDE2QXJyYXknLCAncHJvdG90eXBlJ10sXG5cdCclVWludDMyQXJyYXlQcm90b3R5cGUlJzogWydVaW50MzJBcnJheScsICdwcm90b3R5cGUnXSxcblx0JyVVUklFcnJvclByb3RvdHlwZSUnOiBbJ1VSSUVycm9yJywgJ3Byb3RvdHlwZSddLFxuXHQnJVdlYWtNYXBQcm90b3R5cGUlJzogWydXZWFrTWFwJywgJ3Byb3RvdHlwZSddLFxuXHQnJVdlYWtTZXRQcm90b3R5cGUlJzogWydXZWFrU2V0JywgJ3Byb3RvdHlwZSddXG59O1xuXG52YXIgYmluZCA9IHJlcXVpcmUoJ2Z1bmN0aW9uLWJpbmQnKTtcbnZhciBoYXNPd24gPSByZXF1aXJlKCdoYXNvd24nKTtcbnZhciAkY29uY2F0ID0gYmluZC5jYWxsKCRjYWxsLCBBcnJheS5wcm90b3R5cGUuY29uY2F0KTtcbnZhciAkc3BsaWNlQXBwbHkgPSBiaW5kLmNhbGwoJGFwcGx5LCBBcnJheS5wcm90b3R5cGUuc3BsaWNlKTtcbnZhciAkcmVwbGFjZSA9IGJpbmQuY2FsbCgkY2FsbCwgU3RyaW5nLnByb3RvdHlwZS5yZXBsYWNlKTtcbnZhciAkc3RyU2xpY2UgPSBiaW5kLmNhbGwoJGNhbGwsIFN0cmluZy5wcm90b3R5cGUuc2xpY2UpO1xudmFyICRleGVjID0gYmluZC5jYWxsKCRjYWxsLCBSZWdFeHAucHJvdG90eXBlLmV4ZWMpO1xuXG4vKiBhZGFwdGVkIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL2xvZGFzaC9sb2Rhc2gvYmxvYi80LjE3LjE1L2Rpc3QvbG9kYXNoLmpzI0w2NzM1LUw2NzQ0ICovXG52YXIgcmVQcm9wTmFtZSA9IC9bXiUuW1xcXV0rfFxcWyg/OigtP1xcZCsoPzpcXC5cXGQrKT8pfChbXCInXSkoKD86KD8hXFwyKVteXFxcXF18XFxcXC4pKj8pXFwyKVxcXXwoPz0oPzpcXC58XFxbXFxdKSg/OlxcLnxcXFtcXF18JSQpKS9nO1xudmFyIHJlRXNjYXBlQ2hhciA9IC9cXFxcKFxcXFwpPy9nOyAvKiogVXNlZCB0byBtYXRjaCBiYWNrc2xhc2hlcyBpbiBwcm9wZXJ0eSBwYXRocy4gKi9cbnZhciBzdHJpbmdUb1BhdGggPSBmdW5jdGlvbiBzdHJpbmdUb1BhdGgoc3RyaW5nKSB7XG5cdHZhciBmaXJzdCA9ICRzdHJTbGljZShzdHJpbmcsIDAsIDEpO1xuXHR2YXIgbGFzdCA9ICRzdHJTbGljZShzdHJpbmcsIC0xKTtcblx0aWYgKGZpcnN0ID09PSAnJScgJiYgbGFzdCAhPT0gJyUnKSB7XG5cdFx0dGhyb3cgbmV3ICRTeW50YXhFcnJvcignaW52YWxpZCBpbnRyaW5zaWMgc3ludGF4LCBleHBlY3RlZCBjbG9zaW5nIGAlYCcpO1xuXHR9IGVsc2UgaWYgKGxhc3QgPT09ICclJyAmJiBmaXJzdCAhPT0gJyUnKSB7XG5cdFx0dGhyb3cgbmV3ICRTeW50YXhFcnJvcignaW52YWxpZCBpbnRyaW5zaWMgc3ludGF4LCBleHBlY3RlZCBvcGVuaW5nIGAlYCcpO1xuXHR9XG5cdHZhciByZXN1bHQgPSBbXTtcblx0JHJlcGxhY2Uoc3RyaW5nLCByZVByb3BOYW1lLCBmdW5jdGlvbiAobWF0Y2gsIG51bWJlciwgcXVvdGUsIHN1YlN0cmluZykge1xuXHRcdHJlc3VsdFtyZXN1bHQubGVuZ3RoXSA9IHF1b3RlID8gJHJlcGxhY2Uoc3ViU3RyaW5nLCByZUVzY2FwZUNoYXIsICckMScpIDogbnVtYmVyIHx8IG1hdGNoO1xuXHR9KTtcblx0cmV0dXJuIHJlc3VsdDtcbn07XG4vKiBlbmQgYWRhcHRhdGlvbiAqL1xuXG52YXIgZ2V0QmFzZUludHJpbnNpYyA9IGZ1bmN0aW9uIGdldEJhc2VJbnRyaW5zaWMobmFtZSwgYWxsb3dNaXNzaW5nKSB7XG5cdHZhciBpbnRyaW5zaWNOYW1lID0gbmFtZTtcblx0dmFyIGFsaWFzO1xuXHRpZiAoaGFzT3duKExFR0FDWV9BTElBU0VTLCBpbnRyaW5zaWNOYW1lKSkge1xuXHRcdGFsaWFzID0gTEVHQUNZX0FMSUFTRVNbaW50cmluc2ljTmFtZV07XG5cdFx0aW50cmluc2ljTmFtZSA9ICclJyArIGFsaWFzWzBdICsgJyUnO1xuXHR9XG5cblx0aWYgKGhhc093bihJTlRSSU5TSUNTLCBpbnRyaW5zaWNOYW1lKSkge1xuXHRcdHZhciB2YWx1ZSA9IElOVFJJTlNJQ1NbaW50cmluc2ljTmFtZV07XG5cdFx0aWYgKHZhbHVlID09PSBuZWVkc0V2YWwpIHtcblx0XHRcdHZhbHVlID0gZG9FdmFsKGludHJpbnNpY05hbWUpO1xuXHRcdH1cblx0XHRpZiAodHlwZW9mIHZhbHVlID09PSAndW5kZWZpbmVkJyAmJiAhYWxsb3dNaXNzaW5nKSB7XG5cdFx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignaW50cmluc2ljICcgKyBuYW1lICsgJyBleGlzdHMsIGJ1dCBpcyBub3QgYXZhaWxhYmxlLiBQbGVhc2UgZmlsZSBhbiBpc3N1ZSEnKTtcblx0XHR9XG5cblx0XHRyZXR1cm4ge1xuXHRcdFx0YWxpYXM6IGFsaWFzLFxuXHRcdFx0bmFtZTogaW50cmluc2ljTmFtZSxcblx0XHRcdHZhbHVlOiB2YWx1ZVxuXHRcdH07XG5cdH1cblxuXHR0aHJvdyBuZXcgJFN5bnRheEVycm9yKCdpbnRyaW5zaWMgJyArIG5hbWUgKyAnIGRvZXMgbm90IGV4aXN0IScpO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBHZXRJbnRyaW5zaWMobmFtZSwgYWxsb3dNaXNzaW5nKSB7XG5cdGlmICh0eXBlb2YgbmFtZSAhPT0gJ3N0cmluZycgfHwgbmFtZS5sZW5ndGggPT09IDApIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignaW50cmluc2ljIG5hbWUgbXVzdCBiZSBhIG5vbi1lbXB0eSBzdHJpbmcnKTtcblx0fVxuXHRpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgdHlwZW9mIGFsbG93TWlzc2luZyAhPT0gJ2Jvb2xlYW4nKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ1wiYWxsb3dNaXNzaW5nXCIgYXJndW1lbnQgbXVzdCBiZSBhIGJvb2xlYW4nKTtcblx0fVxuXG5cdGlmICgkZXhlYygvXiU/W14lXSolPyQvLCBuYW1lKSA9PT0gbnVsbCkge1xuXHRcdHRocm93IG5ldyAkU3ludGF4RXJyb3IoJ2AlYCBtYXkgbm90IGJlIHByZXNlbnQgYW55d2hlcmUgYnV0IGF0IHRoZSBiZWdpbm5pbmcgYW5kIGVuZCBvZiB0aGUgaW50cmluc2ljIG5hbWUnKTtcblx0fVxuXHR2YXIgcGFydHMgPSBzdHJpbmdUb1BhdGgobmFtZSk7XG5cdHZhciBpbnRyaW5zaWNCYXNlTmFtZSA9IHBhcnRzLmxlbmd0aCA+IDAgPyBwYXJ0c1swXSA6ICcnO1xuXG5cdHZhciBpbnRyaW5zaWMgPSBnZXRCYXNlSW50cmluc2ljKCclJyArIGludHJpbnNpY0Jhc2VOYW1lICsgJyUnLCBhbGxvd01pc3NpbmcpO1xuXHR2YXIgaW50cmluc2ljUmVhbE5hbWUgPSBpbnRyaW5zaWMubmFtZTtcblx0dmFyIHZhbHVlID0gaW50cmluc2ljLnZhbHVlO1xuXHR2YXIgc2tpcEZ1cnRoZXJDYWNoaW5nID0gZmFsc2U7XG5cblx0dmFyIGFsaWFzID0gaW50cmluc2ljLmFsaWFzO1xuXHRpZiAoYWxpYXMpIHtcblx0XHRpbnRyaW5zaWNCYXNlTmFtZSA9IGFsaWFzWzBdO1xuXHRcdCRzcGxpY2VBcHBseShwYXJ0cywgJGNvbmNhdChbMCwgMV0sIGFsaWFzKSk7XG5cdH1cblxuXHRmb3IgKHZhciBpID0gMSwgaXNPd24gPSB0cnVlOyBpIDwgcGFydHMubGVuZ3RoOyBpICs9IDEpIHtcblx0XHR2YXIgcGFydCA9IHBhcnRzW2ldO1xuXHRcdHZhciBmaXJzdCA9ICRzdHJTbGljZShwYXJ0LCAwLCAxKTtcblx0XHR2YXIgbGFzdCA9ICRzdHJTbGljZShwYXJ0LCAtMSk7XG5cdFx0aWYgKFxuXHRcdFx0KFxuXHRcdFx0XHQoZmlyc3QgPT09ICdcIicgfHwgZmlyc3QgPT09IFwiJ1wiIHx8IGZpcnN0ID09PSAnYCcpXG5cdFx0XHRcdHx8IChsYXN0ID09PSAnXCInIHx8IGxhc3QgPT09IFwiJ1wiIHx8IGxhc3QgPT09ICdgJylcblx0XHRcdClcblx0XHRcdCYmIGZpcnN0ICE9PSBsYXN0XG5cdFx0KSB7XG5cdFx0XHR0aHJvdyBuZXcgJFN5bnRheEVycm9yKCdwcm9wZXJ0eSBuYW1lcyB3aXRoIHF1b3RlcyBtdXN0IGhhdmUgbWF0Y2hpbmcgcXVvdGVzJyk7XG5cdFx0fVxuXHRcdGlmIChwYXJ0ID09PSAnY29uc3RydWN0b3InIHx8ICFpc093bikge1xuXHRcdFx0c2tpcEZ1cnRoZXJDYWNoaW5nID0gdHJ1ZTtcblx0XHR9XG5cblx0XHRpbnRyaW5zaWNCYXNlTmFtZSArPSAnLicgKyBwYXJ0O1xuXHRcdGludHJpbnNpY1JlYWxOYW1lID0gJyUnICsgaW50cmluc2ljQmFzZU5hbWUgKyAnJSc7XG5cblx0XHRpZiAoaGFzT3duKElOVFJJTlNJQ1MsIGludHJpbnNpY1JlYWxOYW1lKSkge1xuXHRcdFx0dmFsdWUgPSBJTlRSSU5TSUNTW2ludHJpbnNpY1JlYWxOYW1lXTtcblx0XHR9IGVsc2UgaWYgKHZhbHVlICE9IG51bGwpIHtcblx0XHRcdGlmICghKHBhcnQgaW4gdmFsdWUpKSB7XG5cdFx0XHRcdGlmICghYWxsb3dNaXNzaW5nKSB7XG5cdFx0XHRcdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ2Jhc2UgaW50cmluc2ljIGZvciAnICsgbmFtZSArICcgZXhpc3RzLCBidXQgdGhlIHByb3BlcnR5IGlzIG5vdCBhdmFpbGFibGUuJyk7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHZvaWQgdW5kZWZpbmVkO1xuXHRcdFx0fVxuXHRcdFx0aWYgKCRnT1BEICYmIChpICsgMSkgPj0gcGFydHMubGVuZ3RoKSB7XG5cdFx0XHRcdHZhciBkZXNjID0gJGdPUEQodmFsdWUsIHBhcnQpO1xuXHRcdFx0XHRpc093biA9ICEhZGVzYztcblxuXHRcdFx0XHQvLyBCeSBjb252ZW50aW9uLCB3aGVuIGEgZGF0YSBwcm9wZXJ0eSBpcyBjb252ZXJ0ZWQgdG8gYW4gYWNjZXNzb3Jcblx0XHRcdFx0Ly8gcHJvcGVydHkgdG8gZW11bGF0ZSBhIGRhdGEgcHJvcGVydHkgdGhhdCBkb2VzIG5vdCBzdWZmZXIgZnJvbVxuXHRcdFx0XHQvLyB0aGUgb3ZlcnJpZGUgbWlzdGFrZSwgdGhhdCBhY2Nlc3NvcidzIGdldHRlciBpcyBtYXJrZWQgd2l0aFxuXHRcdFx0XHQvLyBhbiBgb3JpZ2luYWxWYWx1ZWAgcHJvcGVydHkuIEhlcmUsIHdoZW4gd2UgZGV0ZWN0IHRoaXMsIHdlXG5cdFx0XHRcdC8vIHVwaG9sZCB0aGUgaWxsdXNpb24gYnkgcHJldGVuZGluZyB0byBzZWUgdGhhdCBvcmlnaW5hbCBkYXRhXG5cdFx0XHRcdC8vIHByb3BlcnR5LCBpLmUuLCByZXR1cm5pbmcgdGhlIHZhbHVlIHJhdGhlciB0aGFuIHRoZSBnZXR0ZXJcblx0XHRcdFx0Ly8gaXRzZWxmLlxuXHRcdFx0XHRpZiAoaXNPd24gJiYgJ2dldCcgaW4gZGVzYyAmJiAhKCdvcmlnaW5hbFZhbHVlJyBpbiBkZXNjLmdldCkpIHtcblx0XHRcdFx0XHR2YWx1ZSA9IGRlc2MuZ2V0O1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHZhbHVlID0gdmFsdWVbcGFydF07XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGlzT3duID0gaGFzT3duKHZhbHVlLCBwYXJ0KTtcblx0XHRcdFx0dmFsdWUgPSB2YWx1ZVtwYXJ0XTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKGlzT3duICYmICFza2lwRnVydGhlckNhY2hpbmcpIHtcblx0XHRcdFx0SU5UUklOU0lDU1tpbnRyaW5zaWNSZWFsTmFtZV0gPSB2YWx1ZTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblx0cmV0dXJuIHZhbHVlO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyICRPYmplY3QgPSByZXF1aXJlKCdlcy1vYmplY3QtYXRvbXMnKTtcblxuLyoqIEB0eXBlIHtpbXBvcnQoJy4vT2JqZWN0LmdldFByb3RvdHlwZU9mJyl9ICovXG5tb2R1bGUuZXhwb3J0cyA9ICRPYmplY3QuZ2V0UHJvdG90eXBlT2YgfHwgbnVsbDtcbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqIEB0eXBlIHtpbXBvcnQoJy4vUmVmbGVjdC5nZXRQcm90b3R5cGVPZicpfSAqL1xubW9kdWxlLmV4cG9ydHMgPSAodHlwZW9mIFJlZmxlY3QgIT09ICd1bmRlZmluZWQnICYmIFJlZmxlY3QuZ2V0UHJvdG90eXBlT2YpIHx8IG51bGw7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciByZWZsZWN0R2V0UHJvdG8gPSByZXF1aXJlKCcuL1JlZmxlY3QuZ2V0UHJvdG90eXBlT2YnKTtcbnZhciBvcmlnaW5hbEdldFByb3RvID0gcmVxdWlyZSgnLi9PYmplY3QuZ2V0UHJvdG90eXBlT2YnKTtcblxudmFyIGdldER1bmRlclByb3RvID0gcmVxdWlyZSgnZHVuZGVyLXByb3RvL2dldCcpO1xuXG4vKiogQHR5cGUge2ltcG9ydCgnLicpfSAqL1xubW9kdWxlLmV4cG9ydHMgPSByZWZsZWN0R2V0UHJvdG9cblx0PyBmdW5jdGlvbiBnZXRQcm90byhPKSB7XG5cdFx0Ly8gQHRzLWV4cGVjdC1lcnJvciBUUyBjYW4ndCBuYXJyb3cgaW5zaWRlIGEgY2xvc3VyZSwgZm9yIHNvbWUgcmVhc29uXG5cdFx0cmV0dXJuIHJlZmxlY3RHZXRQcm90byhPKTtcblx0fVxuXHQ6IG9yaWdpbmFsR2V0UHJvdG9cblx0XHQ/IGZ1bmN0aW9uIGdldFByb3RvKE8pIHtcblx0XHRcdGlmICghTyB8fCAodHlwZW9mIE8gIT09ICdvYmplY3QnICYmIHR5cGVvZiBPICE9PSAnZnVuY3Rpb24nKSkge1xuXHRcdFx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCdnZXRQcm90bzogbm90IGFuIG9iamVjdCcpO1xuXHRcdFx0fVxuXHRcdFx0Ly8gQHRzLWV4cGVjdC1lcnJvciBUUyBjYW4ndCBuYXJyb3cgaW5zaWRlIGEgY2xvc3VyZSwgZm9yIHNvbWUgcmVhc29uXG5cdFx0XHRyZXR1cm4gb3JpZ2luYWxHZXRQcm90byhPKTtcblx0XHR9XG5cdFx0OiBnZXREdW5kZXJQcm90b1xuXHRcdFx0PyBmdW5jdGlvbiBnZXRQcm90byhPKSB7XG5cdFx0XHRcdC8vIEB0cy1leHBlY3QtZXJyb3IgVFMgY2FuJ3QgbmFycm93IGluc2lkZSBhIGNsb3N1cmUsIGZvciBzb21lIHJlYXNvblxuXHRcdFx0XHRyZXR1cm4gZ2V0RHVuZGVyUHJvdG8oTyk7XG5cdFx0XHR9XG5cdFx0XHQ6IG51bGw7XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKiBAdHlwZSB7aW1wb3J0KCcuL2dPUEQnKX0gKi9cbm1vZHVsZS5leHBvcnRzID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcjtcbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqIEB0eXBlIHtpbXBvcnQoJy4nKX0gKi9cbnZhciAkZ09QRCA9IHJlcXVpcmUoJy4vZ09QRCcpO1xuXG5pZiAoJGdPUEQpIHtcblx0dHJ5IHtcblx0XHQkZ09QRChbXSwgJ2xlbmd0aCcpO1xuXHR9IGNhdGNoIChlKSB7XG5cdFx0Ly8gSUUgOCBoYXMgYSBicm9rZW4gZ09QRFxuXHRcdCRnT1BEID0gbnVsbDtcblx0fVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9ICRnT1BEO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgb3JpZ1N5bWJvbCA9IHR5cGVvZiBTeW1ib2wgIT09ICd1bmRlZmluZWQnICYmIFN5bWJvbDtcbnZhciBoYXNTeW1ib2xTaGFtID0gcmVxdWlyZSgnLi9zaGFtcycpO1xuXG4vKiogQHR5cGUge2ltcG9ydCgnLicpfSAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBoYXNOYXRpdmVTeW1ib2xzKCkge1xuXHRpZiAodHlwZW9mIG9yaWdTeW1ib2wgIT09ICdmdW5jdGlvbicpIHsgcmV0dXJuIGZhbHNlOyB9XG5cdGlmICh0eXBlb2YgU3ltYm9sICE9PSAnZnVuY3Rpb24nKSB7IHJldHVybiBmYWxzZTsgfVxuXHRpZiAodHlwZW9mIG9yaWdTeW1ib2woJ2ZvbycpICE9PSAnc3ltYm9sJykgeyByZXR1cm4gZmFsc2U7IH1cblx0aWYgKHR5cGVvZiBTeW1ib2woJ2JhcicpICE9PSAnc3ltYm9sJykgeyByZXR1cm4gZmFsc2U7IH1cblxuXHRyZXR1cm4gaGFzU3ltYm9sU2hhbSgpO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqIEB0eXBlIHtpbXBvcnQoJy4vc2hhbXMnKX0gKi9cbi8qIGVzbGludCBjb21wbGV4aXR5OiBbMiwgMThdLCBtYXgtc3RhdGVtZW50czogWzIsIDMzXSAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBoYXNTeW1ib2xzKCkge1xuXHRpZiAodHlwZW9mIFN5bWJvbCAhPT0gJ2Z1bmN0aW9uJyB8fCB0eXBlb2YgT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyAhPT0gJ2Z1bmN0aW9uJykgeyByZXR1cm4gZmFsc2U7IH1cblx0aWYgKHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPT09ICdzeW1ib2wnKSB7IHJldHVybiB0cnVlOyB9XG5cblx0LyoqIEB0eXBlIHt7IFtrIGluIHN5bWJvbF0/OiB1bmtub3duIH19ICovXG5cdHZhciBvYmogPSB7fTtcblx0dmFyIHN5bSA9IFN5bWJvbCgndGVzdCcpO1xuXHR2YXIgc3ltT2JqID0gT2JqZWN0KHN5bSk7XG5cdGlmICh0eXBlb2Ygc3ltID09PSAnc3RyaW5nJykgeyByZXR1cm4gZmFsc2U7IH1cblxuXHRpZiAoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHN5bSkgIT09ICdbb2JqZWN0IFN5bWJvbF0nKSB7IHJldHVybiBmYWxzZTsgfVxuXHRpZiAoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHN5bU9iaikgIT09ICdbb2JqZWN0IFN5bWJvbF0nKSB7IHJldHVybiBmYWxzZTsgfVxuXG5cdC8vIHRlbXAgZGlzYWJsZWQgcGVyIGh0dHBzOi8vZ2l0aHViLmNvbS9samhhcmIvb2JqZWN0LmFzc2lnbi9pc3N1ZXMvMTdcblx0Ly8gaWYgKHN5bSBpbnN0YW5jZW9mIFN5bWJvbCkgeyByZXR1cm4gZmFsc2U7IH1cblx0Ly8gdGVtcCBkaXNhYmxlZCBwZXIgaHR0cHM6Ly9naXRodWIuY29tL1dlYlJlZmxlY3Rpb24vZ2V0LW93bi1wcm9wZXJ0eS1zeW1ib2xzL2lzc3Vlcy80XG5cdC8vIGlmICghKHN5bU9iaiBpbnN0YW5jZW9mIFN5bWJvbCkpIHsgcmV0dXJuIGZhbHNlOyB9XG5cblx0Ly8gaWYgKHR5cGVvZiBTeW1ib2wucHJvdG90eXBlLnRvU3RyaW5nICE9PSAnZnVuY3Rpb24nKSB7IHJldHVybiBmYWxzZTsgfVxuXHQvLyBpZiAoU3RyaW5nKHN5bSkgIT09IFN5bWJvbC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChzeW0pKSB7IHJldHVybiBmYWxzZTsgfVxuXG5cdHZhciBzeW1WYWwgPSA0Mjtcblx0b2JqW3N5bV0gPSBzeW1WYWw7XG5cdGZvciAodmFyIF8gaW4gb2JqKSB7IHJldHVybiBmYWxzZTsgfSAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXJlc3RyaWN0ZWQtc3ludGF4LCBuby11bnJlYWNoYWJsZS1sb29wXG5cdGlmICh0eXBlb2YgT2JqZWN0LmtleXMgPT09ICdmdW5jdGlvbicgJiYgT2JqZWN0LmtleXMob2JqKS5sZW5ndGggIT09IDApIHsgcmV0dXJuIGZhbHNlOyB9XG5cblx0aWYgKHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyA9PT0gJ2Z1bmN0aW9uJyAmJiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhvYmopLmxlbmd0aCAhPT0gMCkgeyByZXR1cm4gZmFsc2U7IH1cblxuXHR2YXIgc3ltcyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMob2JqKTtcblx0aWYgKHN5bXMubGVuZ3RoICE9PSAxIHx8IHN5bXNbMF0gIT09IHN5bSkgeyByZXR1cm4gZmFsc2U7IH1cblxuXHRpZiAoIU9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUuY2FsbChvYmosIHN5bSkpIHsgcmV0dXJuIGZhbHNlOyB9XG5cblx0aWYgKHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yID09PSAnZnVuY3Rpb24nKSB7XG5cdFx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWV4dHJhLXBhcmVuc1xuXHRcdHZhciBkZXNjcmlwdG9yID0gLyoqIEB0eXBlIHtQcm9wZXJ0eURlc2NyaXB0b3J9ICovIChPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iaiwgc3ltKSk7XG5cdFx0aWYgKGRlc2NyaXB0b3IudmFsdWUgIT09IHN5bVZhbCB8fCBkZXNjcmlwdG9yLmVudW1lcmFibGUgIT09IHRydWUpIHsgcmV0dXJuIGZhbHNlOyB9XG5cdH1cblxuXHRyZXR1cm4gdHJ1ZTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBjYWxsID0gRnVuY3Rpb24ucHJvdG90eXBlLmNhbGw7XG52YXIgJGhhc093biA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG52YXIgYmluZCA9IHJlcXVpcmUoJ2Z1bmN0aW9uLWJpbmQnKTtcblxuLyoqIEB0eXBlIHtpbXBvcnQoJy4nKX0gKi9cbm1vZHVsZS5leHBvcnRzID0gYmluZC5jYWxsKGNhbGwsICRoYXNPd24pO1xuIiwiLyohIGllZWU3NTQuIEJTRC0zLUNsYXVzZSBMaWNlbnNlLiBGZXJvc3MgQWJvdWtoYWRpamVoIDxodHRwczovL2Zlcm9zcy5vcmcvb3BlbnNvdXJjZT4gKi9cbmV4cG9ydHMucmVhZCA9IGZ1bmN0aW9uIChidWZmZXIsIG9mZnNldCwgaXNMRSwgbUxlbiwgbkJ5dGVzKSB7XG4gIHZhciBlLCBtXG4gIHZhciBlTGVuID0gKG5CeXRlcyAqIDgpIC0gbUxlbiAtIDFcbiAgdmFyIGVNYXggPSAoMSA8PCBlTGVuKSAtIDFcbiAgdmFyIGVCaWFzID0gZU1heCA+PiAxXG4gIHZhciBuQml0cyA9IC03XG4gIHZhciBpID0gaXNMRSA/IChuQnl0ZXMgLSAxKSA6IDBcbiAgdmFyIGQgPSBpc0xFID8gLTEgOiAxXG4gIHZhciBzID0gYnVmZmVyW29mZnNldCArIGldXG5cbiAgaSArPSBkXG5cbiAgZSA9IHMgJiAoKDEgPDwgKC1uQml0cykpIC0gMSlcbiAgcyA+Pj0gKC1uQml0cylcbiAgbkJpdHMgKz0gZUxlblxuICBmb3IgKDsgbkJpdHMgPiAwOyBlID0gKGUgKiAyNTYpICsgYnVmZmVyW29mZnNldCArIGldLCBpICs9IGQsIG5CaXRzIC09IDgpIHt9XG5cbiAgbSA9IGUgJiAoKDEgPDwgKC1uQml0cykpIC0gMSlcbiAgZSA+Pj0gKC1uQml0cylcbiAgbkJpdHMgKz0gbUxlblxuICBmb3IgKDsgbkJpdHMgPiAwOyBtID0gKG0gKiAyNTYpICsgYnVmZmVyW29mZnNldCArIGldLCBpICs9IGQsIG5CaXRzIC09IDgpIHt9XG5cbiAgaWYgKGUgPT09IDApIHtcbiAgICBlID0gMSAtIGVCaWFzXG4gIH0gZWxzZSBpZiAoZSA9PT0gZU1heCkge1xuICAgIHJldHVybiBtID8gTmFOIDogKChzID8gLTEgOiAxKSAqIEluZmluaXR5KVxuICB9IGVsc2Uge1xuICAgIG0gPSBtICsgTWF0aC5wb3coMiwgbUxlbilcbiAgICBlID0gZSAtIGVCaWFzXG4gIH1cbiAgcmV0dXJuIChzID8gLTEgOiAxKSAqIG0gKiBNYXRoLnBvdygyLCBlIC0gbUxlbilcbn1cblxuZXhwb3J0cy53cml0ZSA9IGZ1bmN0aW9uIChidWZmZXIsIHZhbHVlLCBvZmZzZXQsIGlzTEUsIG1MZW4sIG5CeXRlcykge1xuICB2YXIgZSwgbSwgY1xuICB2YXIgZUxlbiA9IChuQnl0ZXMgKiA4KSAtIG1MZW4gLSAxXG4gIHZhciBlTWF4ID0gKDEgPDwgZUxlbikgLSAxXG4gIHZhciBlQmlhcyA9IGVNYXggPj4gMVxuICB2YXIgcnQgPSAobUxlbiA9PT0gMjMgPyBNYXRoLnBvdygyLCAtMjQpIC0gTWF0aC5wb3coMiwgLTc3KSA6IDApXG4gIHZhciBpID0gaXNMRSA/IDAgOiAobkJ5dGVzIC0gMSlcbiAgdmFyIGQgPSBpc0xFID8gMSA6IC0xXG4gIHZhciBzID0gdmFsdWUgPCAwIHx8ICh2YWx1ZSA9PT0gMCAmJiAxIC8gdmFsdWUgPCAwKSA/IDEgOiAwXG5cbiAgdmFsdWUgPSBNYXRoLmFicyh2YWx1ZSlcblxuICBpZiAoaXNOYU4odmFsdWUpIHx8IHZhbHVlID09PSBJbmZpbml0eSkge1xuICAgIG0gPSBpc05hTih2YWx1ZSkgPyAxIDogMFxuICAgIGUgPSBlTWF4XG4gIH0gZWxzZSB7XG4gICAgZSA9IE1hdGguZmxvb3IoTWF0aC5sb2codmFsdWUpIC8gTWF0aC5MTjIpXG4gICAgaWYgKHZhbHVlICogKGMgPSBNYXRoLnBvdygyLCAtZSkpIDwgMSkge1xuICAgICAgZS0tXG4gICAgICBjICo9IDJcbiAgICB9XG4gICAgaWYgKGUgKyBlQmlhcyA+PSAxKSB7XG4gICAgICB2YWx1ZSArPSBydCAvIGNcbiAgICB9IGVsc2Uge1xuICAgICAgdmFsdWUgKz0gcnQgKiBNYXRoLnBvdygyLCAxIC0gZUJpYXMpXG4gICAgfVxuICAgIGlmICh2YWx1ZSAqIGMgPj0gMikge1xuICAgICAgZSsrXG4gICAgICBjIC89IDJcbiAgICB9XG5cbiAgICBpZiAoZSArIGVCaWFzID49IGVNYXgpIHtcbiAgICAgIG0gPSAwXG4gICAgICBlID0gZU1heFxuICAgIH0gZWxzZSBpZiAoZSArIGVCaWFzID49IDEpIHtcbiAgICAgIG0gPSAoKHZhbHVlICogYykgLSAxKSAqIE1hdGgucG93KDIsIG1MZW4pXG4gICAgICBlID0gZSArIGVCaWFzXG4gICAgfSBlbHNlIHtcbiAgICAgIG0gPSB2YWx1ZSAqIE1hdGgucG93KDIsIGVCaWFzIC0gMSkgKiBNYXRoLnBvdygyLCBtTGVuKVxuICAgICAgZSA9IDBcbiAgICB9XG4gIH1cblxuICBmb3IgKDsgbUxlbiA+PSA4OyBidWZmZXJbb2Zmc2V0ICsgaV0gPSBtICYgMHhmZiwgaSArPSBkLCBtIC89IDI1NiwgbUxlbiAtPSA4KSB7fVxuXG4gIGUgPSAoZSA8PCBtTGVuKSB8IG1cbiAgZUxlbiArPSBtTGVuXG4gIGZvciAoOyBlTGVuID4gMDsgYnVmZmVyW29mZnNldCArIGldID0gZSAmIDB4ZmYsIGkgKz0gZCwgZSAvPSAyNTYsIGVMZW4gLT0gOCkge31cblxuICBidWZmZXJbb2Zmc2V0ICsgaSAtIGRdIHw9IHMgKiAxMjhcbn1cbiIsImlmICh0eXBlb2YgT2JqZWN0LmNyZWF0ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAvLyBpbXBsZW1lbnRhdGlvbiBmcm9tIHN0YW5kYXJkIG5vZGUuanMgJ3V0aWwnIG1vZHVsZVxuICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGluaGVyaXRzKGN0b3IsIHN1cGVyQ3Rvcikge1xuICAgIGlmIChzdXBlckN0b3IpIHtcbiAgICAgIGN0b3Iuc3VwZXJfID0gc3VwZXJDdG9yXG4gICAgICBjdG9yLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDdG9yLnByb3RvdHlwZSwge1xuICAgICAgICBjb25zdHJ1Y3Rvcjoge1xuICAgICAgICAgIHZhbHVlOiBjdG9yLFxuICAgICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgICAgICB9XG4gICAgICB9KVxuICAgIH1cbiAgfTtcbn0gZWxzZSB7XG4gIC8vIG9sZCBzY2hvb2wgc2hpbSBmb3Igb2xkIGJyb3dzZXJzXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgaWYgKHN1cGVyQ3Rvcikge1xuICAgICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICAgIHZhciBUZW1wQ3RvciA9IGZ1bmN0aW9uICgpIHt9XG4gICAgICBUZW1wQ3Rvci5wcm90b3R5cGUgPSBzdXBlckN0b3IucHJvdG90eXBlXG4gICAgICBjdG9yLnByb3RvdHlwZSA9IG5ldyBUZW1wQ3RvcigpXG4gICAgICBjdG9yLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IGN0b3JcbiAgICB9XG4gIH1cbn1cbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqIEB0eXBlIHtpbXBvcnQoJy4vYWJzJyl9ICovXG5tb2R1bGUuZXhwb3J0cyA9IE1hdGguYWJzO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKiogQHR5cGUge2ltcG9ydCgnLi9mbG9vcicpfSAqL1xubW9kdWxlLmV4cG9ydHMgPSBNYXRoLmZsb29yO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKiogQHR5cGUge2ltcG9ydCgnLi9pc05hTicpfSAqL1xubW9kdWxlLmV4cG9ydHMgPSBOdW1iZXIuaXNOYU4gfHwgZnVuY3Rpb24gaXNOYU4oYSkge1xuXHRyZXR1cm4gYSAhPT0gYTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKiBAdHlwZSB7aW1wb3J0KCcuL21heCcpfSAqL1xubW9kdWxlLmV4cG9ydHMgPSBNYXRoLm1heDtcbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqIEB0eXBlIHtpbXBvcnQoJy4vbWluJyl9ICovXG5tb2R1bGUuZXhwb3J0cyA9IE1hdGgubWluO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKiogQHR5cGUge2ltcG9ydCgnLi9wb3cnKX0gKi9cbm1vZHVsZS5leHBvcnRzID0gTWF0aC5wb3c7XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKiBAdHlwZSB7aW1wb3J0KCcuL3JvdW5kJyl9ICovXG5tb2R1bGUuZXhwb3J0cyA9IE1hdGgucm91bmQ7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciAkaXNOYU4gPSByZXF1aXJlKCcuL2lzTmFOJyk7XG5cbi8qKiBAdHlwZSB7aW1wb3J0KCcuL3NpZ24nKX0gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gc2lnbihudW1iZXIpIHtcblx0aWYgKCRpc05hTihudW1iZXIpIHx8IG51bWJlciA9PT0gMCkge1xuXHRcdHJldHVybiBudW1iZXI7XG5cdH1cblx0cmV0dXJuIG51bWJlciA8IDAgPyAtMSA6ICsxO1xufTtcbiIsInZhciBoYXNNYXAgPSB0eXBlb2YgTWFwID09PSAnZnVuY3Rpb24nICYmIE1hcC5wcm90b3R5cGU7XG52YXIgbWFwU2l6ZURlc2NyaXB0b3IgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yICYmIGhhc01hcCA/IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoTWFwLnByb3RvdHlwZSwgJ3NpemUnKSA6IG51bGw7XG52YXIgbWFwU2l6ZSA9IGhhc01hcCAmJiBtYXBTaXplRGVzY3JpcHRvciAmJiB0eXBlb2YgbWFwU2l6ZURlc2NyaXB0b3IuZ2V0ID09PSAnZnVuY3Rpb24nID8gbWFwU2l6ZURlc2NyaXB0b3IuZ2V0IDogbnVsbDtcbnZhciBtYXBGb3JFYWNoID0gaGFzTWFwICYmIE1hcC5wcm90b3R5cGUuZm9yRWFjaDtcbnZhciBoYXNTZXQgPSB0eXBlb2YgU2V0ID09PSAnZnVuY3Rpb24nICYmIFNldC5wcm90b3R5cGU7XG52YXIgc2V0U2l6ZURlc2NyaXB0b3IgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yICYmIGhhc1NldCA/IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoU2V0LnByb3RvdHlwZSwgJ3NpemUnKSA6IG51bGw7XG52YXIgc2V0U2l6ZSA9IGhhc1NldCAmJiBzZXRTaXplRGVzY3JpcHRvciAmJiB0eXBlb2Ygc2V0U2l6ZURlc2NyaXB0b3IuZ2V0ID09PSAnZnVuY3Rpb24nID8gc2V0U2l6ZURlc2NyaXB0b3IuZ2V0IDogbnVsbDtcbnZhciBzZXRGb3JFYWNoID0gaGFzU2V0ICYmIFNldC5wcm90b3R5cGUuZm9yRWFjaDtcbnZhciBoYXNXZWFrTWFwID0gdHlwZW9mIFdlYWtNYXAgPT09ICdmdW5jdGlvbicgJiYgV2Vha01hcC5wcm90b3R5cGU7XG52YXIgd2Vha01hcEhhcyA9IGhhc1dlYWtNYXAgPyBXZWFrTWFwLnByb3RvdHlwZS5oYXMgOiBudWxsO1xudmFyIGhhc1dlYWtTZXQgPSB0eXBlb2YgV2Vha1NldCA9PT0gJ2Z1bmN0aW9uJyAmJiBXZWFrU2V0LnByb3RvdHlwZTtcbnZhciB3ZWFrU2V0SGFzID0gaGFzV2Vha1NldCA/IFdlYWtTZXQucHJvdG90eXBlLmhhcyA6IG51bGw7XG52YXIgaGFzV2Vha1JlZiA9IHR5cGVvZiBXZWFrUmVmID09PSAnZnVuY3Rpb24nICYmIFdlYWtSZWYucHJvdG90eXBlO1xudmFyIHdlYWtSZWZEZXJlZiA9IGhhc1dlYWtSZWYgPyBXZWFrUmVmLnByb3RvdHlwZS5kZXJlZiA6IG51bGw7XG52YXIgYm9vbGVhblZhbHVlT2YgPSBCb29sZWFuLnByb3RvdHlwZS52YWx1ZU9mO1xudmFyIG9iamVjdFRvU3RyaW5nID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZztcbnZhciBmdW5jdGlvblRvU3RyaW5nID0gRnVuY3Rpb24ucHJvdG90eXBlLnRvU3RyaW5nO1xudmFyICRtYXRjaCA9IFN0cmluZy5wcm90b3R5cGUubWF0Y2g7XG52YXIgJHNsaWNlID0gU3RyaW5nLnByb3RvdHlwZS5zbGljZTtcbnZhciAkcmVwbGFjZSA9IFN0cmluZy5wcm90b3R5cGUucmVwbGFjZTtcbnZhciAkdG9VcHBlckNhc2UgPSBTdHJpbmcucHJvdG90eXBlLnRvVXBwZXJDYXNlO1xudmFyICR0b0xvd2VyQ2FzZSA9IFN0cmluZy5wcm90b3R5cGUudG9Mb3dlckNhc2U7XG52YXIgJHRlc3QgPSBSZWdFeHAucHJvdG90eXBlLnRlc3Q7XG52YXIgJGNvbmNhdCA9IEFycmF5LnByb3RvdHlwZS5jb25jYXQ7XG52YXIgJGpvaW4gPSBBcnJheS5wcm90b3R5cGUuam9pbjtcbnZhciAkYXJyU2xpY2UgPSBBcnJheS5wcm90b3R5cGUuc2xpY2U7XG52YXIgJGZsb29yID0gTWF0aC5mbG9vcjtcbnZhciBiaWdJbnRWYWx1ZU9mID0gdHlwZW9mIEJpZ0ludCA9PT0gJ2Z1bmN0aW9uJyA/IEJpZ0ludC5wcm90b3R5cGUudmFsdWVPZiA6IG51bGw7XG52YXIgZ09QUyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHM7XG52YXIgc3ltVG9TdHJpbmcgPSB0eXBlb2YgU3ltYm9sID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPT09ICdzeW1ib2wnID8gU3ltYm9sLnByb3RvdHlwZS50b1N0cmluZyA6IG51bGw7XG52YXIgaGFzU2hhbW1lZFN5bWJvbHMgPSB0eXBlb2YgU3ltYm9sID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPT09ICdvYmplY3QnO1xuLy8gaWUsIGBoYXMtdG9zdHJpbmd0YWcvc2hhbXNcbnZhciB0b1N0cmluZ1RhZyA9IHR5cGVvZiBTeW1ib2wgPT09ICdmdW5jdGlvbicgJiYgU3ltYm9sLnRvU3RyaW5nVGFnICYmICh0eXBlb2YgU3ltYm9sLnRvU3RyaW5nVGFnID09PSBoYXNTaGFtbWVkU3ltYm9scyA/ICdvYmplY3QnIDogJ3N5bWJvbCcpXG4gICAgPyBTeW1ib2wudG9TdHJpbmdUYWdcbiAgICA6IG51bGw7XG52YXIgaXNFbnVtZXJhYmxlID0gT2JqZWN0LnByb3RvdHlwZS5wcm9wZXJ0eUlzRW51bWVyYWJsZTtcblxudmFyIGdQTyA9ICh0eXBlb2YgUmVmbGVjdCA9PT0gJ2Z1bmN0aW9uJyA/IFJlZmxlY3QuZ2V0UHJvdG90eXBlT2YgOiBPYmplY3QuZ2V0UHJvdG90eXBlT2YpIHx8IChcbiAgICBbXS5fX3Byb3RvX18gPT09IEFycmF5LnByb3RvdHlwZSAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXByb3RvXG4gICAgICAgID8gZnVuY3Rpb24gKE8pIHtcbiAgICAgICAgICAgIHJldHVybiBPLl9fcHJvdG9fXzsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1wcm90b1xuICAgICAgICB9XG4gICAgICAgIDogbnVsbFxuKTtcblxuZnVuY3Rpb24gYWRkTnVtZXJpY1NlcGFyYXRvcihudW0sIHN0cikge1xuICAgIGlmIChcbiAgICAgICAgbnVtID09PSBJbmZpbml0eVxuICAgICAgICB8fCBudW0gPT09IC1JbmZpbml0eVxuICAgICAgICB8fCBudW0gIT09IG51bVxuICAgICAgICB8fCAobnVtICYmIG51bSA+IC0xMDAwICYmIG51bSA8IDEwMDApXG4gICAgICAgIHx8ICR0ZXN0LmNhbGwoL2UvLCBzdHIpXG4gICAgKSB7XG4gICAgICAgIHJldHVybiBzdHI7XG4gICAgfVxuICAgIHZhciBzZXBSZWdleCA9IC9bMC05XSg/PSg/OlswLTldezN9KSsoPyFbMC05XSkpL2c7XG4gICAgaWYgKHR5cGVvZiBudW0gPT09ICdudW1iZXInKSB7XG4gICAgICAgIHZhciBpbnQgPSBudW0gPCAwID8gLSRmbG9vcigtbnVtKSA6ICRmbG9vcihudW0pOyAvLyB0cnVuYyhudW0pXG4gICAgICAgIGlmIChpbnQgIT09IG51bSkge1xuICAgICAgICAgICAgdmFyIGludFN0ciA9IFN0cmluZyhpbnQpO1xuICAgICAgICAgICAgdmFyIGRlYyA9ICRzbGljZS5jYWxsKHN0ciwgaW50U3RyLmxlbmd0aCArIDEpO1xuICAgICAgICAgICAgcmV0dXJuICRyZXBsYWNlLmNhbGwoaW50U3RyLCBzZXBSZWdleCwgJyQmXycpICsgJy4nICsgJHJlcGxhY2UuY2FsbCgkcmVwbGFjZS5jYWxsKGRlYywgLyhbMC05XXszfSkvZywgJyQmXycpLCAvXyQvLCAnJyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuICRyZXBsYWNlLmNhbGwoc3RyLCBzZXBSZWdleCwgJyQmXycpO1xufVxuXG52YXIgdXRpbEluc3BlY3QgPSByZXF1aXJlKCcuL3V0aWwuaW5zcGVjdCcpO1xudmFyIGluc3BlY3RDdXN0b20gPSB1dGlsSW5zcGVjdC5jdXN0b207XG52YXIgaW5zcGVjdFN5bWJvbCA9IGlzU3ltYm9sKGluc3BlY3RDdXN0b20pID8gaW5zcGVjdEN1c3RvbSA6IG51bGw7XG5cbnZhciBxdW90ZXMgPSB7XG4gICAgX19wcm90b19fOiBudWxsLFxuICAgICdkb3VibGUnOiAnXCInLFxuICAgIHNpbmdsZTogXCInXCJcbn07XG52YXIgcXVvdGVSRXMgPSB7XG4gICAgX19wcm90b19fOiBudWxsLFxuICAgICdkb3VibGUnOiAvKFtcIlxcXFxdKS9nLFxuICAgIHNpbmdsZTogLyhbJ1xcXFxdKS9nXG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGluc3BlY3RfKG9iaiwgb3B0aW9ucywgZGVwdGgsIHNlZW4pIHtcbiAgICB2YXIgb3B0cyA9IG9wdGlvbnMgfHwge307XG5cbiAgICBpZiAoaGFzKG9wdHMsICdxdW90ZVN0eWxlJykgJiYgIWhhcyhxdW90ZXMsIG9wdHMucXVvdGVTdHlsZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignb3B0aW9uIFwicXVvdGVTdHlsZVwiIG11c3QgYmUgXCJzaW5nbGVcIiBvciBcImRvdWJsZVwiJyk7XG4gICAgfVxuICAgIGlmIChcbiAgICAgICAgaGFzKG9wdHMsICdtYXhTdHJpbmdMZW5ndGgnKSAmJiAodHlwZW9mIG9wdHMubWF4U3RyaW5nTGVuZ3RoID09PSAnbnVtYmVyJ1xuICAgICAgICAgICAgPyBvcHRzLm1heFN0cmluZ0xlbmd0aCA8IDAgJiYgb3B0cy5tYXhTdHJpbmdMZW5ndGggIT09IEluZmluaXR5XG4gICAgICAgICAgICA6IG9wdHMubWF4U3RyaW5nTGVuZ3RoICE9PSBudWxsXG4gICAgICAgIClcbiAgICApIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignb3B0aW9uIFwibWF4U3RyaW5nTGVuZ3RoXCIsIGlmIHByb3ZpZGVkLCBtdXN0IGJlIGEgcG9zaXRpdmUgaW50ZWdlciwgSW5maW5pdHksIG9yIGBudWxsYCcpO1xuICAgIH1cbiAgICB2YXIgY3VzdG9tSW5zcGVjdCA9IGhhcyhvcHRzLCAnY3VzdG9tSW5zcGVjdCcpID8gb3B0cy5jdXN0b21JbnNwZWN0IDogdHJ1ZTtcbiAgICBpZiAodHlwZW9mIGN1c3RvbUluc3BlY3QgIT09ICdib29sZWFuJyAmJiBjdXN0b21JbnNwZWN0ICE9PSAnc3ltYm9sJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdvcHRpb24gXCJjdXN0b21JbnNwZWN0XCIsIGlmIHByb3ZpZGVkLCBtdXN0IGJlIGB0cnVlYCwgYGZhbHNlYCwgb3IgYFxcJ3N5bWJvbFxcJ2AnKTtcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICAgIGhhcyhvcHRzLCAnaW5kZW50JylcbiAgICAgICAgJiYgb3B0cy5pbmRlbnQgIT09IG51bGxcbiAgICAgICAgJiYgb3B0cy5pbmRlbnQgIT09ICdcXHQnXG4gICAgICAgICYmICEocGFyc2VJbnQob3B0cy5pbmRlbnQsIDEwKSA9PT0gb3B0cy5pbmRlbnQgJiYgb3B0cy5pbmRlbnQgPiAwKVxuICAgICkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdvcHRpb24gXCJpbmRlbnRcIiBtdXN0IGJlIFwiXFxcXHRcIiwgYW4gaW50ZWdlciA+IDAsIG9yIGBudWxsYCcpO1xuICAgIH1cbiAgICBpZiAoaGFzKG9wdHMsICdudW1lcmljU2VwYXJhdG9yJykgJiYgdHlwZW9mIG9wdHMubnVtZXJpY1NlcGFyYXRvciAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ29wdGlvbiBcIm51bWVyaWNTZXBhcmF0b3JcIiwgaWYgcHJvdmlkZWQsIG11c3QgYmUgYHRydWVgIG9yIGBmYWxzZWAnKTtcbiAgICB9XG4gICAgdmFyIG51bWVyaWNTZXBhcmF0b3IgPSBvcHRzLm51bWVyaWNTZXBhcmF0b3I7XG5cbiAgICBpZiAodHlwZW9mIG9iaiA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgcmV0dXJuICd1bmRlZmluZWQnO1xuICAgIH1cbiAgICBpZiAob2JqID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiAnbnVsbCc7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2JqID09PSAnYm9vbGVhbicpIHtcbiAgICAgICAgcmV0dXJuIG9iaiA/ICd0cnVlJyA6ICdmYWxzZSc7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBvYmogPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHJldHVybiBpbnNwZWN0U3RyaW5nKG9iaiwgb3B0cyk7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2JqID09PSAnbnVtYmVyJykge1xuICAgICAgICBpZiAob2JqID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gSW5maW5pdHkgLyBvYmogPiAwID8gJzAnIDogJy0wJztcbiAgICAgICAgfVxuICAgICAgICB2YXIgc3RyID0gU3RyaW5nKG9iaik7XG4gICAgICAgIHJldHVybiBudW1lcmljU2VwYXJhdG9yID8gYWRkTnVtZXJpY1NlcGFyYXRvcihvYmosIHN0cikgOiBzdHI7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2JqID09PSAnYmlnaW50Jykge1xuICAgICAgICB2YXIgYmlnSW50U3RyID0gU3RyaW5nKG9iaikgKyAnbic7XG4gICAgICAgIHJldHVybiBudW1lcmljU2VwYXJhdG9yID8gYWRkTnVtZXJpY1NlcGFyYXRvcihvYmosIGJpZ0ludFN0cikgOiBiaWdJbnRTdHI7XG4gICAgfVxuXG4gICAgdmFyIG1heERlcHRoID0gdHlwZW9mIG9wdHMuZGVwdGggPT09ICd1bmRlZmluZWQnID8gNSA6IG9wdHMuZGVwdGg7XG4gICAgaWYgKHR5cGVvZiBkZXB0aCA9PT0gJ3VuZGVmaW5lZCcpIHsgZGVwdGggPSAwOyB9XG4gICAgaWYgKGRlcHRoID49IG1heERlcHRoICYmIG1heERlcHRoID4gMCAmJiB0eXBlb2Ygb2JqID09PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gaXNBcnJheShvYmopID8gJ1tBcnJheV0nIDogJ1tPYmplY3RdJztcbiAgICB9XG5cbiAgICB2YXIgaW5kZW50ID0gZ2V0SW5kZW50KG9wdHMsIGRlcHRoKTtcblxuICAgIGlmICh0eXBlb2Ygc2VlbiA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgc2VlbiA9IFtdO1xuICAgIH0gZWxzZSBpZiAoaW5kZXhPZihzZWVuLCBvYmopID49IDApIHtcbiAgICAgICAgcmV0dXJuICdbQ2lyY3VsYXJdJztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpbnNwZWN0KHZhbHVlLCBmcm9tLCBub0luZGVudCkge1xuICAgICAgICBpZiAoZnJvbSkge1xuICAgICAgICAgICAgc2VlbiA9ICRhcnJTbGljZS5jYWxsKHNlZW4pO1xuICAgICAgICAgICAgc2Vlbi5wdXNoKGZyb20pO1xuICAgICAgICB9XG4gICAgICAgIGlmIChub0luZGVudCkge1xuICAgICAgICAgICAgdmFyIG5ld09wdHMgPSB7XG4gICAgICAgICAgICAgICAgZGVwdGg6IG9wdHMuZGVwdGhcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBpZiAoaGFzKG9wdHMsICdxdW90ZVN0eWxlJykpIHtcbiAgICAgICAgICAgICAgICBuZXdPcHRzLnF1b3RlU3R5bGUgPSBvcHRzLnF1b3RlU3R5bGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gaW5zcGVjdF8odmFsdWUsIG5ld09wdHMsIGRlcHRoICsgMSwgc2Vlbik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGluc3BlY3RfKHZhbHVlLCBvcHRzLCBkZXB0aCArIDEsIHNlZW4pO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2Ygb2JqID09PSAnZnVuY3Rpb24nICYmICFpc1JlZ0V4cChvYmopKSB7IC8vIGluIG9sZGVyIGVuZ2luZXMsIHJlZ2V4ZXMgYXJlIGNhbGxhYmxlXG4gICAgICAgIHZhciBuYW1lID0gbmFtZU9mKG9iaik7XG4gICAgICAgIHZhciBrZXlzID0gYXJyT2JqS2V5cyhvYmosIGluc3BlY3QpO1xuICAgICAgICByZXR1cm4gJ1tGdW5jdGlvbicgKyAobmFtZSA/ICc6ICcgKyBuYW1lIDogJyAoYW5vbnltb3VzKScpICsgJ10nICsgKGtleXMubGVuZ3RoID4gMCA/ICcgeyAnICsgJGpvaW4uY2FsbChrZXlzLCAnLCAnKSArICcgfScgOiAnJyk7XG4gICAgfVxuICAgIGlmIChpc1N5bWJvbChvYmopKSB7XG4gICAgICAgIHZhciBzeW1TdHJpbmcgPSBoYXNTaGFtbWVkU3ltYm9scyA/ICRyZXBsYWNlLmNhbGwoU3RyaW5nKG9iaiksIC9eKFN5bWJvbFxcKC4qXFwpKV9bXildKiQvLCAnJDEnKSA6IHN5bVRvU3RyaW5nLmNhbGwob2JqKTtcbiAgICAgICAgcmV0dXJuIHR5cGVvZiBvYmogPT09ICdvYmplY3QnICYmICFoYXNTaGFtbWVkU3ltYm9scyA/IG1hcmtCb3hlZChzeW1TdHJpbmcpIDogc3ltU3RyaW5nO1xuICAgIH1cbiAgICBpZiAoaXNFbGVtZW50KG9iaikpIHtcbiAgICAgICAgdmFyIHMgPSAnPCcgKyAkdG9Mb3dlckNhc2UuY2FsbChTdHJpbmcob2JqLm5vZGVOYW1lKSk7XG4gICAgICAgIHZhciBhdHRycyA9IG9iai5hdHRyaWJ1dGVzIHx8IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGF0dHJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBzICs9ICcgJyArIGF0dHJzW2ldLm5hbWUgKyAnPScgKyB3cmFwUXVvdGVzKHF1b3RlKGF0dHJzW2ldLnZhbHVlKSwgJ2RvdWJsZScsIG9wdHMpO1xuICAgICAgICB9XG4gICAgICAgIHMgKz0gJz4nO1xuICAgICAgICBpZiAob2JqLmNoaWxkTm9kZXMgJiYgb2JqLmNoaWxkTm9kZXMubGVuZ3RoKSB7IHMgKz0gJy4uLic7IH1cbiAgICAgICAgcyArPSAnPC8nICsgJHRvTG93ZXJDYXNlLmNhbGwoU3RyaW5nKG9iai5ub2RlTmFtZSkpICsgJz4nO1xuICAgICAgICByZXR1cm4gcztcbiAgICB9XG4gICAgaWYgKGlzQXJyYXkob2JqKSkge1xuICAgICAgICBpZiAob2JqLmxlbmd0aCA9PT0gMCkgeyByZXR1cm4gJ1tdJzsgfVxuICAgICAgICB2YXIgeHMgPSBhcnJPYmpLZXlzKG9iaiwgaW5zcGVjdCk7XG4gICAgICAgIGlmIChpbmRlbnQgJiYgIXNpbmdsZUxpbmVWYWx1ZXMoeHMpKSB7XG4gICAgICAgICAgICByZXR1cm4gJ1snICsgaW5kZW50ZWRKb2luKHhzLCBpbmRlbnQpICsgJ10nO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAnWyAnICsgJGpvaW4uY2FsbCh4cywgJywgJykgKyAnIF0nO1xuICAgIH1cbiAgICBpZiAoaXNFcnJvcihvYmopKSB7XG4gICAgICAgIHZhciBwYXJ0cyA9IGFyck9iaktleXMob2JqLCBpbnNwZWN0KTtcbiAgICAgICAgaWYgKCEoJ2NhdXNlJyBpbiBFcnJvci5wcm90b3R5cGUpICYmICdjYXVzZScgaW4gb2JqICYmICFpc0VudW1lcmFibGUuY2FsbChvYmosICdjYXVzZScpKSB7XG4gICAgICAgICAgICByZXR1cm4gJ3sgWycgKyBTdHJpbmcob2JqKSArICddICcgKyAkam9pbi5jYWxsKCRjb25jYXQuY2FsbCgnW2NhdXNlXTogJyArIGluc3BlY3Qob2JqLmNhdXNlKSwgcGFydHMpLCAnLCAnKSArICcgfSc7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHBhcnRzLmxlbmd0aCA9PT0gMCkgeyByZXR1cm4gJ1snICsgU3RyaW5nKG9iaikgKyAnXSc7IH1cbiAgICAgICAgcmV0dXJuICd7IFsnICsgU3RyaW5nKG9iaikgKyAnXSAnICsgJGpvaW4uY2FsbChwYXJ0cywgJywgJykgKyAnIH0nO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIG9iaiA9PT0gJ29iamVjdCcgJiYgY3VzdG9tSW5zcGVjdCkge1xuICAgICAgICBpZiAoaW5zcGVjdFN5bWJvbCAmJiB0eXBlb2Ygb2JqW2luc3BlY3RTeW1ib2xdID09PSAnZnVuY3Rpb24nICYmIHV0aWxJbnNwZWN0KSB7XG4gICAgICAgICAgICByZXR1cm4gdXRpbEluc3BlY3Qob2JqLCB7IGRlcHRoOiBtYXhEZXB0aCAtIGRlcHRoIH0pO1xuICAgICAgICB9IGVsc2UgaWYgKGN1c3RvbUluc3BlY3QgIT09ICdzeW1ib2wnICYmIHR5cGVvZiBvYmouaW5zcGVjdCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgcmV0dXJuIG9iai5pbnNwZWN0KCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKGlzTWFwKG9iaikpIHtcbiAgICAgICAgdmFyIG1hcFBhcnRzID0gW107XG4gICAgICAgIGlmIChtYXBGb3JFYWNoKSB7XG4gICAgICAgICAgICBtYXBGb3JFYWNoLmNhbGwob2JqLCBmdW5jdGlvbiAodmFsdWUsIGtleSkge1xuICAgICAgICAgICAgICAgIG1hcFBhcnRzLnB1c2goaW5zcGVjdChrZXksIG9iaiwgdHJ1ZSkgKyAnID0+ICcgKyBpbnNwZWN0KHZhbHVlLCBvYmopKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjb2xsZWN0aW9uT2YoJ01hcCcsIG1hcFNpemUuY2FsbChvYmopLCBtYXBQYXJ0cywgaW5kZW50KTtcbiAgICB9XG4gICAgaWYgKGlzU2V0KG9iaikpIHtcbiAgICAgICAgdmFyIHNldFBhcnRzID0gW107XG4gICAgICAgIGlmIChzZXRGb3JFYWNoKSB7XG4gICAgICAgICAgICBzZXRGb3JFYWNoLmNhbGwob2JqLCBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBzZXRQYXJ0cy5wdXNoKGluc3BlY3QodmFsdWUsIG9iaikpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNvbGxlY3Rpb25PZignU2V0Jywgc2V0U2l6ZS5jYWxsKG9iaiksIHNldFBhcnRzLCBpbmRlbnQpO1xuICAgIH1cbiAgICBpZiAoaXNXZWFrTWFwKG9iaikpIHtcbiAgICAgICAgcmV0dXJuIHdlYWtDb2xsZWN0aW9uT2YoJ1dlYWtNYXAnKTtcbiAgICB9XG4gICAgaWYgKGlzV2Vha1NldChvYmopKSB7XG4gICAgICAgIHJldHVybiB3ZWFrQ29sbGVjdGlvbk9mKCdXZWFrU2V0Jyk7XG4gICAgfVxuICAgIGlmIChpc1dlYWtSZWYob2JqKSkge1xuICAgICAgICByZXR1cm4gd2Vha0NvbGxlY3Rpb25PZignV2Vha1JlZicpO1xuICAgIH1cbiAgICBpZiAoaXNOdW1iZXIob2JqKSkge1xuICAgICAgICByZXR1cm4gbWFya0JveGVkKGluc3BlY3QoTnVtYmVyKG9iaikpKTtcbiAgICB9XG4gICAgaWYgKGlzQmlnSW50KG9iaikpIHtcbiAgICAgICAgcmV0dXJuIG1hcmtCb3hlZChpbnNwZWN0KGJpZ0ludFZhbHVlT2YuY2FsbChvYmopKSk7XG4gICAgfVxuICAgIGlmIChpc0Jvb2xlYW4ob2JqKSkge1xuICAgICAgICByZXR1cm4gbWFya0JveGVkKGJvb2xlYW5WYWx1ZU9mLmNhbGwob2JqKSk7XG4gICAgfVxuICAgIGlmIChpc1N0cmluZyhvYmopKSB7XG4gICAgICAgIHJldHVybiBtYXJrQm94ZWQoaW5zcGVjdChTdHJpbmcob2JqKSkpO1xuICAgIH1cbiAgICAvLyBub3RlOiBpbiBJRSA4LCBzb21ldGltZXMgYGdsb2JhbCAhPT0gd2luZG93YCBidXQgYm90aCBhcmUgdGhlIHByb3RvdHlwZXMgb2YgZWFjaCBvdGhlclxuICAgIC8qIGVzbGludC1lbnYgYnJvd3NlciAqL1xuICAgIGlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJiBvYmogPT09IHdpbmRvdykge1xuICAgICAgICByZXR1cm4gJ3sgW29iamVjdCBXaW5kb3ddIH0nO1xuICAgIH1cbiAgICBpZiAoXG4gICAgICAgICh0eXBlb2YgZ2xvYmFsVGhpcyAhPT0gJ3VuZGVmaW5lZCcgJiYgb2JqID09PSBnbG9iYWxUaGlzKVxuICAgICAgICB8fCAodHlwZW9mIGdsb2JhbCAhPT0gJ3VuZGVmaW5lZCcgJiYgb2JqID09PSBnbG9iYWwpXG4gICAgKSB7XG4gICAgICAgIHJldHVybiAneyBbb2JqZWN0IGdsb2JhbFRoaXNdIH0nO1xuICAgIH1cbiAgICBpZiAoIWlzRGF0ZShvYmopICYmICFpc1JlZ0V4cChvYmopKSB7XG4gICAgICAgIHZhciB5cyA9IGFyck9iaktleXMob2JqLCBpbnNwZWN0KTtcbiAgICAgICAgdmFyIGlzUGxhaW5PYmplY3QgPSBnUE8gPyBnUE8ob2JqKSA9PT0gT2JqZWN0LnByb3RvdHlwZSA6IG9iaiBpbnN0YW5jZW9mIE9iamVjdCB8fCBvYmouY29uc3RydWN0b3IgPT09IE9iamVjdDtcbiAgICAgICAgdmFyIHByb3RvVGFnID0gb2JqIGluc3RhbmNlb2YgT2JqZWN0ID8gJycgOiAnbnVsbCBwcm90b3R5cGUnO1xuICAgICAgICB2YXIgc3RyaW5nVGFnID0gIWlzUGxhaW5PYmplY3QgJiYgdG9TdHJpbmdUYWcgJiYgT2JqZWN0KG9iaikgPT09IG9iaiAmJiB0b1N0cmluZ1RhZyBpbiBvYmogPyAkc2xpY2UuY2FsbCh0b1N0cihvYmopLCA4LCAtMSkgOiBwcm90b1RhZyA/ICdPYmplY3QnIDogJyc7XG4gICAgICAgIHZhciBjb25zdHJ1Y3RvclRhZyA9IGlzUGxhaW5PYmplY3QgfHwgdHlwZW9mIG9iai5jb25zdHJ1Y3RvciAhPT0gJ2Z1bmN0aW9uJyA/ICcnIDogb2JqLmNvbnN0cnVjdG9yLm5hbWUgPyBvYmouY29uc3RydWN0b3IubmFtZSArICcgJyA6ICcnO1xuICAgICAgICB2YXIgdGFnID0gY29uc3RydWN0b3JUYWcgKyAoc3RyaW5nVGFnIHx8IHByb3RvVGFnID8gJ1snICsgJGpvaW4uY2FsbCgkY29uY2F0LmNhbGwoW10sIHN0cmluZ1RhZyB8fCBbXSwgcHJvdG9UYWcgfHwgW10pLCAnOiAnKSArICddICcgOiAnJyk7XG4gICAgICAgIGlmICh5cy5sZW5ndGggPT09IDApIHsgcmV0dXJuIHRhZyArICd7fSc7IH1cbiAgICAgICAgaWYgKGluZGVudCkge1xuICAgICAgICAgICAgcmV0dXJuIHRhZyArICd7JyArIGluZGVudGVkSm9pbih5cywgaW5kZW50KSArICd9JztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGFnICsgJ3sgJyArICRqb2luLmNhbGwoeXMsICcsICcpICsgJyB9JztcbiAgICB9XG4gICAgcmV0dXJuIFN0cmluZyhvYmopO1xufTtcblxuZnVuY3Rpb24gd3JhcFF1b3RlcyhzLCBkZWZhdWx0U3R5bGUsIG9wdHMpIHtcbiAgICB2YXIgc3R5bGUgPSBvcHRzLnF1b3RlU3R5bGUgfHwgZGVmYXVsdFN0eWxlO1xuICAgIHZhciBxdW90ZUNoYXIgPSBxdW90ZXNbc3R5bGVdO1xuICAgIHJldHVybiBxdW90ZUNoYXIgKyBzICsgcXVvdGVDaGFyO1xufVxuXG5mdW5jdGlvbiBxdW90ZShzKSB7XG4gICAgcmV0dXJuICRyZXBsYWNlLmNhbGwoU3RyaW5nKHMpLCAvXCIvZywgJyZxdW90OycpO1xufVxuXG5mdW5jdGlvbiBjYW5UcnVzdFRvU3RyaW5nKG9iaikge1xuICAgIHJldHVybiAhdG9TdHJpbmdUYWcgfHwgISh0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJiAodG9TdHJpbmdUYWcgaW4gb2JqIHx8IHR5cGVvZiBvYmpbdG9TdHJpbmdUYWddICE9PSAndW5kZWZpbmVkJykpO1xufVxuZnVuY3Rpb24gaXNBcnJheShvYmopIHsgcmV0dXJuIHRvU3RyKG9iaikgPT09ICdbb2JqZWN0IEFycmF5XScgJiYgY2FuVHJ1c3RUb1N0cmluZyhvYmopOyB9XG5mdW5jdGlvbiBpc0RhdGUob2JqKSB7IHJldHVybiB0b1N0cihvYmopID09PSAnW29iamVjdCBEYXRlXScgJiYgY2FuVHJ1c3RUb1N0cmluZyhvYmopOyB9XG5mdW5jdGlvbiBpc1JlZ0V4cChvYmopIHsgcmV0dXJuIHRvU3RyKG9iaikgPT09ICdbb2JqZWN0IFJlZ0V4cF0nICYmIGNhblRydXN0VG9TdHJpbmcob2JqKTsgfVxuZnVuY3Rpb24gaXNFcnJvcihvYmopIHsgcmV0dXJuIHRvU3RyKG9iaikgPT09ICdbb2JqZWN0IEVycm9yXScgJiYgY2FuVHJ1c3RUb1N0cmluZyhvYmopOyB9XG5mdW5jdGlvbiBpc1N0cmluZyhvYmopIHsgcmV0dXJuIHRvU3RyKG9iaikgPT09ICdbb2JqZWN0IFN0cmluZ10nICYmIGNhblRydXN0VG9TdHJpbmcob2JqKTsgfVxuZnVuY3Rpb24gaXNOdW1iZXIob2JqKSB7IHJldHVybiB0b1N0cihvYmopID09PSAnW29iamVjdCBOdW1iZXJdJyAmJiBjYW5UcnVzdFRvU3RyaW5nKG9iaik7IH1cbmZ1bmN0aW9uIGlzQm9vbGVhbihvYmopIHsgcmV0dXJuIHRvU3RyKG9iaikgPT09ICdbb2JqZWN0IEJvb2xlYW5dJyAmJiBjYW5UcnVzdFRvU3RyaW5nKG9iaik7IH1cblxuLy8gU3ltYm9sIGFuZCBCaWdJbnQgZG8gaGF2ZSBTeW1ib2wudG9TdHJpbmdUYWcgYnkgc3BlYywgc28gdGhhdCBjYW4ndCBiZSB1c2VkIHRvIGVsaW1pbmF0ZSBmYWxzZSBwb3NpdGl2ZXNcbmZ1bmN0aW9uIGlzU3ltYm9sKG9iaikge1xuICAgIGlmIChoYXNTaGFtbWVkU3ltYm9scykge1xuICAgICAgICByZXR1cm4gb2JqICYmIHR5cGVvZiBvYmogPT09ICdvYmplY3QnICYmIG9iaiBpbnN0YW5jZW9mIFN5bWJvbDtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBvYmogPT09ICdzeW1ib2wnKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBpZiAoIW9iaiB8fCB0eXBlb2Ygb2JqICE9PSAnb2JqZWN0JyB8fCAhc3ltVG9TdHJpbmcpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICBzeW1Ub1N0cmluZy5jYWxsKG9iaik7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gY2F0Y2ggKGUpIHt9XG4gICAgcmV0dXJuIGZhbHNlO1xufVxuXG5mdW5jdGlvbiBpc0JpZ0ludChvYmopIHtcbiAgICBpZiAoIW9iaiB8fCB0eXBlb2Ygb2JqICE9PSAnb2JqZWN0JyB8fCAhYmlnSW50VmFsdWVPZikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIGJpZ0ludFZhbHVlT2YuY2FsbChvYmopO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIChlKSB7fVxuICAgIHJldHVybiBmYWxzZTtcbn1cblxudmFyIGhhc093biA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkgfHwgZnVuY3Rpb24gKGtleSkgeyByZXR1cm4ga2V5IGluIHRoaXM7IH07XG5mdW5jdGlvbiBoYXMob2JqLCBrZXkpIHtcbiAgICByZXR1cm4gaGFzT3duLmNhbGwob2JqLCBrZXkpO1xufVxuXG5mdW5jdGlvbiB0b1N0cihvYmopIHtcbiAgICByZXR1cm4gb2JqZWN0VG9TdHJpbmcuY2FsbChvYmopO1xufVxuXG5mdW5jdGlvbiBuYW1lT2YoZikge1xuICAgIGlmIChmLm5hbWUpIHsgcmV0dXJuIGYubmFtZTsgfVxuICAgIHZhciBtID0gJG1hdGNoLmNhbGwoZnVuY3Rpb25Ub1N0cmluZy5jYWxsKGYpLCAvXmZ1bmN0aW9uXFxzKihbXFx3JF0rKS8pO1xuICAgIGlmIChtKSB7IHJldHVybiBtWzFdOyB9XG4gICAgcmV0dXJuIG51bGw7XG59XG5cbmZ1bmN0aW9uIGluZGV4T2YoeHMsIHgpIHtcbiAgICBpZiAoeHMuaW5kZXhPZikgeyByZXR1cm4geHMuaW5kZXhPZih4KTsgfVxuICAgIGZvciAodmFyIGkgPSAwLCBsID0geHMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgIGlmICh4c1tpXSA9PT0geCkgeyByZXR1cm4gaTsgfVxuICAgIH1cbiAgICByZXR1cm4gLTE7XG59XG5cbmZ1bmN0aW9uIGlzTWFwKHgpIHtcbiAgICBpZiAoIW1hcFNpemUgfHwgIXggfHwgdHlwZW9mIHggIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgbWFwU2l6ZS5jYWxsKHgpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgc2V0U2l6ZS5jYWxsKHgpO1xuICAgICAgICB9IGNhdGNoIChzKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geCBpbnN0YW5jZW9mIE1hcDsgLy8gY29yZS1qcyB3b3JrYXJvdW5kLCBwcmUtdjIuNS4wXG4gICAgfSBjYXRjaCAoZSkge31cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGlzV2Vha01hcCh4KSB7XG4gICAgaWYgKCF3ZWFrTWFwSGFzIHx8ICF4IHx8IHR5cGVvZiB4ICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIHdlYWtNYXBIYXMuY2FsbCh4LCB3ZWFrTWFwSGFzKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHdlYWtTZXRIYXMuY2FsbCh4LCB3ZWFrU2V0SGFzKTtcbiAgICAgICAgfSBjYXRjaCAocykge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHggaW5zdGFuY2VvZiBXZWFrTWFwOyAvLyBjb3JlLWpzIHdvcmthcm91bmQsIHByZS12Mi41LjBcbiAgICB9IGNhdGNoIChlKSB7fVxuICAgIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gaXNXZWFrUmVmKHgpIHtcbiAgICBpZiAoIXdlYWtSZWZEZXJlZiB8fCAheCB8fCB0eXBlb2YgeCAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICB3ZWFrUmVmRGVyZWYuY2FsbCh4KTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCAoZSkge31cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGlzU2V0KHgpIHtcbiAgICBpZiAoIXNldFNpemUgfHwgIXggfHwgdHlwZW9mIHggIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgc2V0U2l6ZS5jYWxsKHgpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgbWFwU2l6ZS5jYWxsKHgpO1xuICAgICAgICB9IGNhdGNoIChtKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geCBpbnN0YW5jZW9mIFNldDsgLy8gY29yZS1qcyB3b3JrYXJvdW5kLCBwcmUtdjIuNS4wXG4gICAgfSBjYXRjaCAoZSkge31cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGlzV2Vha1NldCh4KSB7XG4gICAgaWYgKCF3ZWFrU2V0SGFzIHx8ICF4IHx8IHR5cGVvZiB4ICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIHdlYWtTZXRIYXMuY2FsbCh4LCB3ZWFrU2V0SGFzKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHdlYWtNYXBIYXMuY2FsbCh4LCB3ZWFrTWFwSGFzKTtcbiAgICAgICAgfSBjYXRjaCAocykge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHggaW5zdGFuY2VvZiBXZWFrU2V0OyAvLyBjb3JlLWpzIHdvcmthcm91bmQsIHByZS12Mi41LjBcbiAgICB9IGNhdGNoIChlKSB7fVxuICAgIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gaXNFbGVtZW50KHgpIHtcbiAgICBpZiAoIXggfHwgdHlwZW9mIHggIT09ICdvYmplY3QnKSB7IHJldHVybiBmYWxzZTsgfVxuICAgIGlmICh0eXBlb2YgSFRNTEVsZW1lbnQgIT09ICd1bmRlZmluZWQnICYmIHggaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIHR5cGVvZiB4Lm5vZGVOYW1lID09PSAnc3RyaW5nJyAmJiB0eXBlb2YgeC5nZXRBdHRyaWJ1dGUgPT09ICdmdW5jdGlvbic7XG59XG5cbmZ1bmN0aW9uIGluc3BlY3RTdHJpbmcoc3RyLCBvcHRzKSB7XG4gICAgaWYgKHN0ci5sZW5ndGggPiBvcHRzLm1heFN0cmluZ0xlbmd0aCkge1xuICAgICAgICB2YXIgcmVtYWluaW5nID0gc3RyLmxlbmd0aCAtIG9wdHMubWF4U3RyaW5nTGVuZ3RoO1xuICAgICAgICB2YXIgdHJhaWxlciA9ICcuLi4gJyArIHJlbWFpbmluZyArICcgbW9yZSBjaGFyYWN0ZXInICsgKHJlbWFpbmluZyA+IDEgPyAncycgOiAnJyk7XG4gICAgICAgIHJldHVybiBpbnNwZWN0U3RyaW5nKCRzbGljZS5jYWxsKHN0ciwgMCwgb3B0cy5tYXhTdHJpbmdMZW5ndGgpLCBvcHRzKSArIHRyYWlsZXI7XG4gICAgfVxuICAgIHZhciBxdW90ZVJFID0gcXVvdGVSRXNbb3B0cy5xdW90ZVN0eWxlIHx8ICdzaW5nbGUnXTtcbiAgICBxdW90ZVJFLmxhc3RJbmRleCA9IDA7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnRyb2wtcmVnZXhcbiAgICB2YXIgcyA9ICRyZXBsYWNlLmNhbGwoJHJlcGxhY2UuY2FsbChzdHIsIHF1b3RlUkUsICdcXFxcJDEnKSwgL1tcXHgwMC1cXHgxZl0vZywgbG93Ynl0ZSk7XG4gICAgcmV0dXJuIHdyYXBRdW90ZXMocywgJ3NpbmdsZScsIG9wdHMpO1xufVxuXG5mdW5jdGlvbiBsb3dieXRlKGMpIHtcbiAgICB2YXIgbiA9IGMuY2hhckNvZGVBdCgwKTtcbiAgICB2YXIgeCA9IHtcbiAgICAgICAgODogJ2InLFxuICAgICAgICA5OiAndCcsXG4gICAgICAgIDEwOiAnbicsXG4gICAgICAgIDEyOiAnZicsXG4gICAgICAgIDEzOiAncidcbiAgICB9W25dO1xuICAgIGlmICh4KSB7IHJldHVybiAnXFxcXCcgKyB4OyB9XG4gICAgcmV0dXJuICdcXFxceCcgKyAobiA8IDB4MTAgPyAnMCcgOiAnJykgKyAkdG9VcHBlckNhc2UuY2FsbChuLnRvU3RyaW5nKDE2KSk7XG59XG5cbmZ1bmN0aW9uIG1hcmtCb3hlZChzdHIpIHtcbiAgICByZXR1cm4gJ09iamVjdCgnICsgc3RyICsgJyknO1xufVxuXG5mdW5jdGlvbiB3ZWFrQ29sbGVjdGlvbk9mKHR5cGUpIHtcbiAgICByZXR1cm4gdHlwZSArICcgeyA/IH0nO1xufVxuXG5mdW5jdGlvbiBjb2xsZWN0aW9uT2YodHlwZSwgc2l6ZSwgZW50cmllcywgaW5kZW50KSB7XG4gICAgdmFyIGpvaW5lZEVudHJpZXMgPSBpbmRlbnQgPyBpbmRlbnRlZEpvaW4oZW50cmllcywgaW5kZW50KSA6ICRqb2luLmNhbGwoZW50cmllcywgJywgJyk7XG4gICAgcmV0dXJuIHR5cGUgKyAnICgnICsgc2l6ZSArICcpIHsnICsgam9pbmVkRW50cmllcyArICd9Jztcbn1cblxuZnVuY3Rpb24gc2luZ2xlTGluZVZhbHVlcyh4cykge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgeHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKGluZGV4T2YoeHNbaV0sICdcXG4nKSA+PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGdldEluZGVudChvcHRzLCBkZXB0aCkge1xuICAgIHZhciBiYXNlSW5kZW50O1xuICAgIGlmIChvcHRzLmluZGVudCA9PT0gJ1xcdCcpIHtcbiAgICAgICAgYmFzZUluZGVudCA9ICdcXHQnO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIG9wdHMuaW5kZW50ID09PSAnbnVtYmVyJyAmJiBvcHRzLmluZGVudCA+IDApIHtcbiAgICAgICAgYmFzZUluZGVudCA9ICRqb2luLmNhbGwoQXJyYXkob3B0cy5pbmRlbnQgKyAxKSwgJyAnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgICAgYmFzZTogYmFzZUluZGVudCxcbiAgICAgICAgcHJldjogJGpvaW4uY2FsbChBcnJheShkZXB0aCArIDEpLCBiYXNlSW5kZW50KVxuICAgIH07XG59XG5cbmZ1bmN0aW9uIGluZGVudGVkSm9pbih4cywgaW5kZW50KSB7XG4gICAgaWYgKHhzLmxlbmd0aCA9PT0gMCkgeyByZXR1cm4gJyc7IH1cbiAgICB2YXIgbGluZUpvaW5lciA9ICdcXG4nICsgaW5kZW50LnByZXYgKyBpbmRlbnQuYmFzZTtcbiAgICByZXR1cm4gbGluZUpvaW5lciArICRqb2luLmNhbGwoeHMsICcsJyArIGxpbmVKb2luZXIpICsgJ1xcbicgKyBpbmRlbnQucHJldjtcbn1cblxuZnVuY3Rpb24gYXJyT2JqS2V5cyhvYmosIGluc3BlY3QpIHtcbiAgICB2YXIgaXNBcnIgPSBpc0FycmF5KG9iaik7XG4gICAgdmFyIHhzID0gW107XG4gICAgaWYgKGlzQXJyKSB7XG4gICAgICAgIHhzLmxlbmd0aCA9IG9iai5sZW5ndGg7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB4c1tpXSA9IGhhcyhvYmosIGkpID8gaW5zcGVjdChvYmpbaV0sIG9iaikgOiAnJztcbiAgICAgICAgfVxuICAgIH1cbiAgICB2YXIgc3ltcyA9IHR5cGVvZiBnT1BTID09PSAnZnVuY3Rpb24nID8gZ09QUyhvYmopIDogW107XG4gICAgdmFyIHN5bU1hcDtcbiAgICBpZiAoaGFzU2hhbW1lZFN5bWJvbHMpIHtcbiAgICAgICAgc3ltTWFwID0ge307XG4gICAgICAgIGZvciAodmFyIGsgPSAwOyBrIDwgc3ltcy5sZW5ndGg7IGsrKykge1xuICAgICAgICAgICAgc3ltTWFwWyckJyArIHN5bXNba11dID0gc3ltc1trXTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZvciAodmFyIGtleSBpbiBvYmopIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1yZXN0cmljdGVkLXN5bnRheFxuICAgICAgICBpZiAoIWhhcyhvYmosIGtleSkpIHsgY29udGludWU7IH0gLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1yZXN0cmljdGVkLXN5bnRheCwgbm8tY29udGludWVcbiAgICAgICAgaWYgKGlzQXJyICYmIFN0cmluZyhOdW1iZXIoa2V5KSkgPT09IGtleSAmJiBrZXkgPCBvYmoubGVuZ3RoKSB7IGNvbnRpbnVlOyB9IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tcmVzdHJpY3RlZC1zeW50YXgsIG5vLWNvbnRpbnVlXG4gICAgICAgIGlmIChoYXNTaGFtbWVkU3ltYm9scyAmJiBzeW1NYXBbJyQnICsga2V5XSBpbnN0YW5jZW9mIFN5bWJvbCkge1xuICAgICAgICAgICAgLy8gdGhpcyBpcyB0byBwcmV2ZW50IHNoYW1tZWQgU3ltYm9scywgd2hpY2ggYXJlIHN0b3JlZCBhcyBzdHJpbmdzLCBmcm9tIGJlaW5nIGluY2x1ZGVkIGluIHRoZSBzdHJpbmcga2V5IHNlY3Rpb25cbiAgICAgICAgICAgIGNvbnRpbnVlOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXJlc3RyaWN0ZWQtc3ludGF4LCBuby1jb250aW51ZVxuICAgICAgICB9IGVsc2UgaWYgKCR0ZXN0LmNhbGwoL1teXFx3JF0vLCBrZXkpKSB7XG4gICAgICAgICAgICB4cy5wdXNoKGluc3BlY3Qoa2V5LCBvYmopICsgJzogJyArIGluc3BlY3Qob2JqW2tleV0sIG9iaikpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgeHMucHVzaChrZXkgKyAnOiAnICsgaW5zcGVjdChvYmpba2V5XSwgb2JqKSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKHR5cGVvZiBnT1BTID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgc3ltcy5sZW5ndGg7IGorKykge1xuICAgICAgICAgICAgaWYgKGlzRW51bWVyYWJsZS5jYWxsKG9iaiwgc3ltc1tqXSkpIHtcbiAgICAgICAgICAgICAgICB4cy5wdXNoKCdbJyArIGluc3BlY3Qoc3ltc1tqXSkgKyAnXTogJyArIGluc3BlY3Qob2JqW3N5bXNbal1dLCBvYmopKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4geHM7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBrZXlzU2hpbTtcbmlmICghT2JqZWN0LmtleXMpIHtcblx0Ly8gbW9kaWZpZWQgZnJvbSBodHRwczovL2dpdGh1Yi5jb20vZXMtc2hpbXMvZXM1LXNoaW1cblx0dmFyIGhhcyA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG5cdHZhciB0b1N0ciA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG5cdHZhciBpc0FyZ3MgPSByZXF1aXJlKCcuL2lzQXJndW1lbnRzJyk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgZ2xvYmFsLXJlcXVpcmVcblx0dmFyIGlzRW51bWVyYWJsZSA9IE9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGU7XG5cdHZhciBoYXNEb250RW51bUJ1ZyA9ICFpc0VudW1lcmFibGUuY2FsbCh7IHRvU3RyaW5nOiBudWxsIH0sICd0b1N0cmluZycpO1xuXHR2YXIgaGFzUHJvdG9FbnVtQnVnID0gaXNFbnVtZXJhYmxlLmNhbGwoZnVuY3Rpb24gKCkge30sICdwcm90b3R5cGUnKTtcblx0dmFyIGRvbnRFbnVtcyA9IFtcblx0XHQndG9TdHJpbmcnLFxuXHRcdCd0b0xvY2FsZVN0cmluZycsXG5cdFx0J3ZhbHVlT2YnLFxuXHRcdCdoYXNPd25Qcm9wZXJ0eScsXG5cdFx0J2lzUHJvdG90eXBlT2YnLFxuXHRcdCdwcm9wZXJ0eUlzRW51bWVyYWJsZScsXG5cdFx0J2NvbnN0cnVjdG9yJ1xuXHRdO1xuXHR2YXIgZXF1YWxzQ29uc3RydWN0b3JQcm90b3R5cGUgPSBmdW5jdGlvbiAobykge1xuXHRcdHZhciBjdG9yID0gby5jb25zdHJ1Y3Rvcjtcblx0XHRyZXR1cm4gY3RvciAmJiBjdG9yLnByb3RvdHlwZSA9PT0gbztcblx0fTtcblx0dmFyIGV4Y2x1ZGVkS2V5cyA9IHtcblx0XHQkYXBwbGljYXRpb25DYWNoZTogdHJ1ZSxcblx0XHQkY29uc29sZTogdHJ1ZSxcblx0XHQkZXh0ZXJuYWw6IHRydWUsXG5cdFx0JGZyYW1lOiB0cnVlLFxuXHRcdCRmcmFtZUVsZW1lbnQ6IHRydWUsXG5cdFx0JGZyYW1lczogdHJ1ZSxcblx0XHQkaW5uZXJIZWlnaHQ6IHRydWUsXG5cdFx0JGlubmVyV2lkdGg6IHRydWUsXG5cdFx0JG9ubW96ZnVsbHNjcmVlbmNoYW5nZTogdHJ1ZSxcblx0XHQkb25tb3pmdWxsc2NyZWVuZXJyb3I6IHRydWUsXG5cdFx0JG91dGVySGVpZ2h0OiB0cnVlLFxuXHRcdCRvdXRlcldpZHRoOiB0cnVlLFxuXHRcdCRwYWdlWE9mZnNldDogdHJ1ZSxcblx0XHQkcGFnZVlPZmZzZXQ6IHRydWUsXG5cdFx0JHBhcmVudDogdHJ1ZSxcblx0XHQkc2Nyb2xsTGVmdDogdHJ1ZSxcblx0XHQkc2Nyb2xsVG9wOiB0cnVlLFxuXHRcdCRzY3JvbGxYOiB0cnVlLFxuXHRcdCRzY3JvbGxZOiB0cnVlLFxuXHRcdCRzZWxmOiB0cnVlLFxuXHRcdCR3ZWJraXRJbmRleGVkREI6IHRydWUsXG5cdFx0JHdlYmtpdFN0b3JhZ2VJbmZvOiB0cnVlLFxuXHRcdCR3aW5kb3c6IHRydWVcblx0fTtcblx0dmFyIGhhc0F1dG9tYXRpb25FcXVhbGl0eUJ1ZyA9IChmdW5jdGlvbiAoKSB7XG5cdFx0LyogZ2xvYmFsIHdpbmRvdyAqL1xuXHRcdGlmICh0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJykgeyByZXR1cm4gZmFsc2U7IH1cblx0XHRmb3IgKHZhciBrIGluIHdpbmRvdykge1xuXHRcdFx0dHJ5IHtcblx0XHRcdFx0aWYgKCFleGNsdWRlZEtleXNbJyQnICsga10gJiYgaGFzLmNhbGwod2luZG93LCBrKSAmJiB3aW5kb3dba10gIT09IG51bGwgJiYgdHlwZW9mIHdpbmRvd1trXSA9PT0gJ29iamVjdCcpIHtcblx0XHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdFx0ZXF1YWxzQ29uc3RydWN0b3JQcm90b3R5cGUod2luZG93W2tdKTtcblx0XHRcdFx0XHR9IGNhdGNoIChlKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH0gY2F0Y2ggKGUpIHtcblx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiBmYWxzZTtcblx0fSgpKTtcblx0dmFyIGVxdWFsc0NvbnN0cnVjdG9yUHJvdG90eXBlSWZOb3RCdWdneSA9IGZ1bmN0aW9uIChvKSB7XG5cdFx0LyogZ2xvYmFsIHdpbmRvdyAqL1xuXHRcdGlmICh0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJyB8fCAhaGFzQXV0b21hdGlvbkVxdWFsaXR5QnVnKSB7XG5cdFx0XHRyZXR1cm4gZXF1YWxzQ29uc3RydWN0b3JQcm90b3R5cGUobyk7XG5cdFx0fVxuXHRcdHRyeSB7XG5cdFx0XHRyZXR1cm4gZXF1YWxzQ29uc3RydWN0b3JQcm90b3R5cGUobyk7XG5cdFx0fSBjYXRjaCAoZSkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0fTtcblxuXHRrZXlzU2hpbSA9IGZ1bmN0aW9uIGtleXMob2JqZWN0KSB7XG5cdFx0dmFyIGlzT2JqZWN0ID0gb2JqZWN0ICE9PSBudWxsICYmIHR5cGVvZiBvYmplY3QgPT09ICdvYmplY3QnO1xuXHRcdHZhciBpc0Z1bmN0aW9uID0gdG9TdHIuY2FsbChvYmplY3QpID09PSAnW29iamVjdCBGdW5jdGlvbl0nO1xuXHRcdHZhciBpc0FyZ3VtZW50cyA9IGlzQXJncyhvYmplY3QpO1xuXHRcdHZhciBpc1N0cmluZyA9IGlzT2JqZWN0ICYmIHRvU3RyLmNhbGwob2JqZWN0KSA9PT0gJ1tvYmplY3QgU3RyaW5nXSc7XG5cdFx0dmFyIHRoZUtleXMgPSBbXTtcblxuXHRcdGlmICghaXNPYmplY3QgJiYgIWlzRnVuY3Rpb24gJiYgIWlzQXJndW1lbnRzKSB7XG5cdFx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCdPYmplY3Qua2V5cyBjYWxsZWQgb24gYSBub24tb2JqZWN0Jyk7XG5cdFx0fVxuXG5cdFx0dmFyIHNraXBQcm90byA9IGhhc1Byb3RvRW51bUJ1ZyAmJiBpc0Z1bmN0aW9uO1xuXHRcdGlmIChpc1N0cmluZyAmJiBvYmplY3QubGVuZ3RoID4gMCAmJiAhaGFzLmNhbGwob2JqZWN0LCAwKSkge1xuXHRcdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QubGVuZ3RoOyArK2kpIHtcblx0XHRcdFx0dGhlS2V5cy5wdXNoKFN0cmluZyhpKSk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0aWYgKGlzQXJndW1lbnRzICYmIG9iamVjdC5sZW5ndGggPiAwKSB7XG5cdFx0XHRmb3IgKHZhciBqID0gMDsgaiA8IG9iamVjdC5sZW5ndGg7ICsraikge1xuXHRcdFx0XHR0aGVLZXlzLnB1c2goU3RyaW5nKGopKTtcblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0Zm9yICh2YXIgbmFtZSBpbiBvYmplY3QpIHtcblx0XHRcdFx0aWYgKCEoc2tpcFByb3RvICYmIG5hbWUgPT09ICdwcm90b3R5cGUnKSAmJiBoYXMuY2FsbChvYmplY3QsIG5hbWUpKSB7XG5cdFx0XHRcdFx0dGhlS2V5cy5wdXNoKFN0cmluZyhuYW1lKSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAoaGFzRG9udEVudW1CdWcpIHtcblx0XHRcdHZhciBza2lwQ29uc3RydWN0b3IgPSBlcXVhbHNDb25zdHJ1Y3RvclByb3RvdHlwZUlmTm90QnVnZ3kob2JqZWN0KTtcblxuXHRcdFx0Zm9yICh2YXIgayA9IDA7IGsgPCBkb250RW51bXMubGVuZ3RoOyArK2spIHtcblx0XHRcdFx0aWYgKCEoc2tpcENvbnN0cnVjdG9yICYmIGRvbnRFbnVtc1trXSA9PT0gJ2NvbnN0cnVjdG9yJykgJiYgaGFzLmNhbGwob2JqZWN0LCBkb250RW51bXNba10pKSB7XG5cdFx0XHRcdFx0dGhlS2V5cy5wdXNoKGRvbnRFbnVtc1trXSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIHRoZUtleXM7XG5cdH07XG59XG5tb2R1bGUuZXhwb3J0cyA9IGtleXNTaGltO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgc2xpY2UgPSBBcnJheS5wcm90b3R5cGUuc2xpY2U7XG52YXIgaXNBcmdzID0gcmVxdWlyZSgnLi9pc0FyZ3VtZW50cycpO1xuXG52YXIgb3JpZ0tleXMgPSBPYmplY3Qua2V5cztcbnZhciBrZXlzU2hpbSA9IG9yaWdLZXlzID8gZnVuY3Rpb24ga2V5cyhvKSB7IHJldHVybiBvcmlnS2V5cyhvKTsgfSA6IHJlcXVpcmUoJy4vaW1wbGVtZW50YXRpb24nKTtcblxudmFyIG9yaWdpbmFsS2V5cyA9IE9iamVjdC5rZXlzO1xuXG5rZXlzU2hpbS5zaGltID0gZnVuY3Rpb24gc2hpbU9iamVjdEtleXMoKSB7XG5cdGlmIChPYmplY3Qua2V5cykge1xuXHRcdHZhciBrZXlzV29ya3NXaXRoQXJndW1lbnRzID0gKGZ1bmN0aW9uICgpIHtcblx0XHRcdC8vIFNhZmFyaSA1LjAgYnVnXG5cdFx0XHR2YXIgYXJncyA9IE9iamVjdC5rZXlzKGFyZ3VtZW50cyk7XG5cdFx0XHRyZXR1cm4gYXJncyAmJiBhcmdzLmxlbmd0aCA9PT0gYXJndW1lbnRzLmxlbmd0aDtcblx0XHR9KDEsIDIpKTtcblx0XHRpZiAoIWtleXNXb3Jrc1dpdGhBcmd1bWVudHMpIHtcblx0XHRcdE9iamVjdC5rZXlzID0gZnVuY3Rpb24ga2V5cyhvYmplY3QpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBmdW5jLW5hbWUtbWF0Y2hpbmdcblx0XHRcdFx0aWYgKGlzQXJncyhvYmplY3QpKSB7XG5cdFx0XHRcdFx0cmV0dXJuIG9yaWdpbmFsS2V5cyhzbGljZS5jYWxsKG9iamVjdCkpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiBvcmlnaW5hbEtleXMob2JqZWN0KTtcblx0XHRcdH07XG5cdFx0fVxuXHR9IGVsc2Uge1xuXHRcdE9iamVjdC5rZXlzID0ga2V5c1NoaW07XG5cdH1cblx0cmV0dXJuIE9iamVjdC5rZXlzIHx8IGtleXNTaGltO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBrZXlzU2hpbTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHRvU3RyID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpc0FyZ3VtZW50cyh2YWx1ZSkge1xuXHR2YXIgc3RyID0gdG9TdHIuY2FsbCh2YWx1ZSk7XG5cdHZhciBpc0FyZ3MgPSBzdHIgPT09ICdbb2JqZWN0IEFyZ3VtZW50c10nO1xuXHRpZiAoIWlzQXJncykge1xuXHRcdGlzQXJncyA9IHN0ciAhPT0gJ1tvYmplY3QgQXJyYXldJyAmJlxuXHRcdFx0dmFsdWUgIT09IG51bGwgJiZcblx0XHRcdHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiZcblx0XHRcdHR5cGVvZiB2YWx1ZS5sZW5ndGggPT09ICdudW1iZXInICYmXG5cdFx0XHR2YWx1ZS5sZW5ndGggPj0gMCAmJlxuXHRcdFx0dG9TdHIuY2FsbCh2YWx1ZS5jYWxsZWUpID09PSAnW29iamVjdCBGdW5jdGlvbl0nO1xuXHR9XG5cdHJldHVybiBpc0FyZ3M7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vLyBtb2RpZmllZCBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9lcy1zaGltcy9lczYtc2hpbVxudmFyIG9iamVjdEtleXMgPSByZXF1aXJlKCdvYmplY3Qta2V5cycpO1xudmFyIGhhc1N5bWJvbHMgPSByZXF1aXJlKCdoYXMtc3ltYm9scy9zaGFtcycpKCk7XG52YXIgY2FsbEJvdW5kID0gcmVxdWlyZSgnY2FsbC1ib3VuZCcpO1xudmFyICRPYmplY3QgPSByZXF1aXJlKCdlcy1vYmplY3QtYXRvbXMnKTtcbnZhciAkcHVzaCA9IGNhbGxCb3VuZCgnQXJyYXkucHJvdG90eXBlLnB1c2gnKTtcbnZhciAkcHJvcElzRW51bWVyYWJsZSA9IGNhbGxCb3VuZCgnT2JqZWN0LnByb3RvdHlwZS5wcm9wZXJ0eUlzRW51bWVyYWJsZScpO1xudmFyIG9yaWdpbmFsR2V0U3ltYm9scyA9IGhhc1N5bWJvbHMgPyAkT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyA6IG51bGw7XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bnVzZWQtdmFyc1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBhc3NpZ24odGFyZ2V0LCBzb3VyY2UxKSB7XG5cdGlmICh0YXJnZXQgPT0gbnVsbCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCd0YXJnZXQgbXVzdCBiZSBhbiBvYmplY3QnKTsgfVxuXHR2YXIgdG8gPSAkT2JqZWN0KHRhcmdldCk7IC8vIHN0ZXAgMVxuXHRpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMSkge1xuXHRcdHJldHVybiB0bzsgLy8gc3RlcCAyXG5cdH1cblx0Zm9yICh2YXIgcyA9IDE7IHMgPCBhcmd1bWVudHMubGVuZ3RoOyArK3MpIHtcblx0XHR2YXIgZnJvbSA9ICRPYmplY3QoYXJndW1lbnRzW3NdKTsgLy8gc3RlcCAzLmEuaVxuXG5cdFx0Ly8gc3RlcCAzLmEuaWk6XG5cdFx0dmFyIGtleXMgPSBvYmplY3RLZXlzKGZyb20pO1xuXHRcdHZhciBnZXRTeW1ib2xzID0gaGFzU3ltYm9scyAmJiAoJE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMgfHwgb3JpZ2luYWxHZXRTeW1ib2xzKTtcblx0XHRpZiAoZ2V0U3ltYm9scykge1xuXHRcdFx0dmFyIHN5bXMgPSBnZXRTeW1ib2xzKGZyb20pO1xuXHRcdFx0Zm9yICh2YXIgaiA9IDA7IGogPCBzeW1zLmxlbmd0aDsgKytqKSB7XG5cdFx0XHRcdHZhciBrZXkgPSBzeW1zW2pdO1xuXHRcdFx0XHRpZiAoJHByb3BJc0VudW1lcmFibGUoZnJvbSwga2V5KSkge1xuXHRcdFx0XHRcdCRwdXNoKGtleXMsIGtleSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBzdGVwIDMuYS5paWk6XG5cdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKSB7XG5cdFx0XHR2YXIgbmV4dEtleSA9IGtleXNbaV07XG5cdFx0XHRpZiAoJHByb3BJc0VudW1lcmFibGUoZnJvbSwgbmV4dEtleSkpIHsgLy8gc3RlcCAzLmEuaWlpLjJcblx0XHRcdFx0dmFyIHByb3BWYWx1ZSA9IGZyb21bbmV4dEtleV07IC8vIHN0ZXAgMy5hLmlpaS4yLmFcblx0XHRcdFx0dG9bbmV4dEtleV0gPSBwcm9wVmFsdWU7IC8vIHN0ZXAgMy5hLmlpaS4yLmJcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gdG87IC8vIHN0ZXAgNFxufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGltcGxlbWVudGF0aW9uID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbicpO1xuXG52YXIgbGFja3NQcm9wZXJFbnVtZXJhdGlvbk9yZGVyID0gZnVuY3Rpb24gKCkge1xuXHRpZiAoIU9iamVjdC5hc3NpZ24pIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblx0Lypcblx0ICogdjgsIHNwZWNpZmljYWxseSBpbiBub2RlIDQueCwgaGFzIGEgYnVnIHdpdGggaW5jb3JyZWN0IHByb3BlcnR5IGVudW1lcmF0aW9uIG9yZGVyXG5cdCAqIG5vdGU6IHRoaXMgZG9lcyBub3QgZGV0ZWN0IHRoZSBidWcgdW5sZXNzIHRoZXJlJ3MgMjAgY2hhcmFjdGVyc1xuXHQgKi9cblx0dmFyIHN0ciA9ICdhYmNkZWZnaGlqa2xtbm9wcXJzdCc7XG5cdHZhciBsZXR0ZXJzID0gc3RyLnNwbGl0KCcnKTtcblx0dmFyIG1hcCA9IHt9O1xuXHRmb3IgKHZhciBpID0gMDsgaSA8IGxldHRlcnMubGVuZ3RoOyArK2kpIHtcblx0XHRtYXBbbGV0dGVyc1tpXV0gPSBsZXR0ZXJzW2ldO1xuXHR9XG5cdHZhciBvYmogPSBPYmplY3QuYXNzaWduKHt9LCBtYXApO1xuXHR2YXIgYWN0dWFsID0gJyc7XG5cdGZvciAodmFyIGsgaW4gb2JqKSB7XG5cdFx0YWN0dWFsICs9IGs7XG5cdH1cblx0cmV0dXJuIHN0ciAhPT0gYWN0dWFsO1xufTtcblxudmFyIGFzc2lnbkhhc1BlbmRpbmdFeGNlcHRpb25zID0gZnVuY3Rpb24gKCkge1xuXHRpZiAoIU9iamVjdC5hc3NpZ24gfHwgIU9iamVjdC5wcmV2ZW50RXh0ZW5zaW9ucykge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXHQvKlxuXHQgKiBGaXJlZm94IDM3IHN0aWxsIGhhcyBcInBlbmRpbmcgZXhjZXB0aW9uXCIgbG9naWMgaW4gaXRzIE9iamVjdC5hc3NpZ24gaW1wbGVtZW50YXRpb24sXG5cdCAqIHdoaWNoIGlzIDcyJSBzbG93ZXIgdGhhbiBvdXIgc2hpbSwgYW5kIEZpcmVmb3ggNDAncyBuYXRpdmUgaW1wbGVtZW50YXRpb24uXG5cdCAqL1xuXHR2YXIgdGhyb3dlciA9IE9iamVjdC5wcmV2ZW50RXh0ZW5zaW9ucyh7IDE6IDIgfSk7XG5cdHRyeSB7XG5cdFx0T2JqZWN0LmFzc2lnbih0aHJvd2VyLCAneHknKTtcblx0fSBjYXRjaCAoZSkge1xuXHRcdHJldHVybiB0aHJvd2VyWzFdID09PSAneSc7XG5cdH1cblx0cmV0dXJuIGZhbHNlO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBnZXRQb2x5ZmlsbCgpIHtcblx0aWYgKCFPYmplY3QuYXNzaWduKSB7XG5cdFx0cmV0dXJuIGltcGxlbWVudGF0aW9uO1xuXHR9XG5cdGlmIChsYWNrc1Byb3BlckVudW1lcmF0aW9uT3JkZXIoKSkge1xuXHRcdHJldHVybiBpbXBsZW1lbnRhdGlvbjtcblx0fVxuXHRpZiAoYXNzaWduSGFzUGVuZGluZ0V4Y2VwdGlvbnMoKSkge1xuXHRcdHJldHVybiBpbXBsZW1lbnRhdGlvbjtcblx0fVxuXHRyZXR1cm4gT2JqZWN0LmFzc2lnbjtcbn07XG4iLCIvLyBzaGltIGZvciB1c2luZyBwcm9jZXNzIGluIGJyb3dzZXJcbnZhciBwcm9jZXNzID0gbW9kdWxlLmV4cG9ydHMgPSB7fTtcblxuLy8gY2FjaGVkIGZyb20gd2hhdGV2ZXIgZ2xvYmFsIGlzIHByZXNlbnQgc28gdGhhdCB0ZXN0IHJ1bm5lcnMgdGhhdCBzdHViIGl0XG4vLyBkb24ndCBicmVhayB0aGluZ3MuICBCdXQgd2UgbmVlZCB0byB3cmFwIGl0IGluIGEgdHJ5IGNhdGNoIGluIGNhc2UgaXQgaXNcbi8vIHdyYXBwZWQgaW4gc3RyaWN0IG1vZGUgY29kZSB3aGljaCBkb2Vzbid0IGRlZmluZSBhbnkgZ2xvYmFscy4gIEl0J3MgaW5zaWRlIGFcbi8vIGZ1bmN0aW9uIGJlY2F1c2UgdHJ5L2NhdGNoZXMgZGVvcHRpbWl6ZSBpbiBjZXJ0YWluIGVuZ2luZXMuXG5cbnZhciBjYWNoZWRTZXRUaW1lb3V0O1xudmFyIGNhY2hlZENsZWFyVGltZW91dDtcblxuZnVuY3Rpb24gZGVmYXVsdFNldFRpbW91dCgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3NldFRpbWVvdXQgaGFzIG5vdCBiZWVuIGRlZmluZWQnKTtcbn1cbmZ1bmN0aW9uIGRlZmF1bHRDbGVhclRpbWVvdXQgKCkge1xuICAgIHRocm93IG5ldyBFcnJvcignY2xlYXJUaW1lb3V0IGhhcyBub3QgYmVlbiBkZWZpbmVkJyk7XG59XG4oZnVuY3Rpb24gKCkge1xuICAgIHRyeSB7XG4gICAgICAgIGlmICh0eXBlb2Ygc2V0VGltZW91dCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IHNldFRpbWVvdXQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjYWNoZWRTZXRUaW1lb3V0ID0gZGVmYXVsdFNldFRpbW91dDtcbiAgICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IGRlZmF1bHRTZXRUaW1vdXQ7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIGlmICh0eXBlb2YgY2xlYXJUaW1lb3V0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBjbGVhclRpbWVvdXQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBkZWZhdWx0Q2xlYXJUaW1lb3V0O1xuICAgICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBkZWZhdWx0Q2xlYXJUaW1lb3V0O1xuICAgIH1cbn0gKCkpXG5mdW5jdGlvbiBydW5UaW1lb3V0KGZ1bikge1xuICAgIGlmIChjYWNoZWRTZXRUaW1lb3V0ID09PSBzZXRUaW1lb3V0KSB7XG4gICAgICAgIC8vbm9ybWFsIGVudmlyb21lbnRzIGluIHNhbmUgc2l0dWF0aW9uc1xuICAgICAgICByZXR1cm4gc2V0VGltZW91dChmdW4sIDApO1xuICAgIH1cbiAgICAvLyBpZiBzZXRUaW1lb3V0IHdhc24ndCBhdmFpbGFibGUgYnV0IHdhcyBsYXR0ZXIgZGVmaW5lZFxuICAgIGlmICgoY2FjaGVkU2V0VGltZW91dCA9PT0gZGVmYXVsdFNldFRpbW91dCB8fCAhY2FjaGVkU2V0VGltZW91dCkgJiYgc2V0VGltZW91dCkge1xuICAgICAgICBjYWNoZWRTZXRUaW1lb3V0ID0gc2V0VGltZW91dDtcbiAgICAgICAgcmV0dXJuIHNldFRpbWVvdXQoZnVuLCAwKTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgLy8gd2hlbiB3aGVuIHNvbWVib2R5IGhhcyBzY3Jld2VkIHdpdGggc2V0VGltZW91dCBidXQgbm8gSS5FLiBtYWRkbmVzc1xuICAgICAgICByZXR1cm4gY2FjaGVkU2V0VGltZW91dChmdW4sIDApO1xuICAgIH0gY2F0Y2goZSl7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBXaGVuIHdlIGFyZSBpbiBJLkUuIGJ1dCB0aGUgc2NyaXB0IGhhcyBiZWVuIGV2YWxlZCBzbyBJLkUuIGRvZXNuJ3QgdHJ1c3QgdGhlIGdsb2JhbCBvYmplY3Qgd2hlbiBjYWxsZWQgbm9ybWFsbHlcbiAgICAgICAgICAgIHJldHVybiBjYWNoZWRTZXRUaW1lb3V0LmNhbGwobnVsbCwgZnVuLCAwKTtcbiAgICAgICAgfSBjYXRjaChlKXtcbiAgICAgICAgICAgIC8vIHNhbWUgYXMgYWJvdmUgYnV0IHdoZW4gaXQncyBhIHZlcnNpb24gb2YgSS5FLiB0aGF0IG11c3QgaGF2ZSB0aGUgZ2xvYmFsIG9iamVjdCBmb3IgJ3RoaXMnLCBob3BmdWxseSBvdXIgY29udGV4dCBjb3JyZWN0IG90aGVyd2lzZSBpdCB3aWxsIHRocm93IGEgZ2xvYmFsIGVycm9yXG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkU2V0VGltZW91dC5jYWxsKHRoaXMsIGZ1biwgMCk7XG4gICAgICAgIH1cbiAgICB9XG5cblxufVxuZnVuY3Rpb24gcnVuQ2xlYXJUaW1lb3V0KG1hcmtlcikge1xuICAgIGlmIChjYWNoZWRDbGVhclRpbWVvdXQgPT09IGNsZWFyVGltZW91dCkge1xuICAgICAgICAvL25vcm1hbCBlbnZpcm9tZW50cyBpbiBzYW5lIHNpdHVhdGlvbnNcbiAgICAgICAgcmV0dXJuIGNsZWFyVGltZW91dChtYXJrZXIpO1xuICAgIH1cbiAgICAvLyBpZiBjbGVhclRpbWVvdXQgd2Fzbid0IGF2YWlsYWJsZSBidXQgd2FzIGxhdHRlciBkZWZpbmVkXG4gICAgaWYgKChjYWNoZWRDbGVhclRpbWVvdXQgPT09IGRlZmF1bHRDbGVhclRpbWVvdXQgfHwgIWNhY2hlZENsZWFyVGltZW91dCkgJiYgY2xlYXJUaW1lb3V0KSB7XG4gICAgICAgIGNhY2hlZENsZWFyVGltZW91dCA9IGNsZWFyVGltZW91dDtcbiAgICAgICAgcmV0dXJuIGNsZWFyVGltZW91dChtYXJrZXIpO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICAvLyB3aGVuIHdoZW4gc29tZWJvZHkgaGFzIHNjcmV3ZWQgd2l0aCBzZXRUaW1lb3V0IGJ1dCBubyBJLkUuIG1hZGRuZXNzXG4gICAgICAgIHJldHVybiBjYWNoZWRDbGVhclRpbWVvdXQobWFya2VyKTtcbiAgICB9IGNhdGNoIChlKXtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vIFdoZW4gd2UgYXJlIGluIEkuRS4gYnV0IHRoZSBzY3JpcHQgaGFzIGJlZW4gZXZhbGVkIHNvIEkuRS4gZG9lc24ndCAgdHJ1c3QgdGhlIGdsb2JhbCBvYmplY3Qgd2hlbiBjYWxsZWQgbm9ybWFsbHlcbiAgICAgICAgICAgIHJldHVybiBjYWNoZWRDbGVhclRpbWVvdXQuY2FsbChudWxsLCBtYXJrZXIpO1xuICAgICAgICB9IGNhdGNoIChlKXtcbiAgICAgICAgICAgIC8vIHNhbWUgYXMgYWJvdmUgYnV0IHdoZW4gaXQncyBhIHZlcnNpb24gb2YgSS5FLiB0aGF0IG11c3QgaGF2ZSB0aGUgZ2xvYmFsIG9iamVjdCBmb3IgJ3RoaXMnLCBob3BmdWxseSBvdXIgY29udGV4dCBjb3JyZWN0IG90aGVyd2lzZSBpdCB3aWxsIHRocm93IGEgZ2xvYmFsIGVycm9yLlxuICAgICAgICAgICAgLy8gU29tZSB2ZXJzaW9ucyBvZiBJLkUuIGhhdmUgZGlmZmVyZW50IHJ1bGVzIGZvciBjbGVhclRpbWVvdXQgdnMgc2V0VGltZW91dFxuICAgICAgICAgICAgcmV0dXJuIGNhY2hlZENsZWFyVGltZW91dC5jYWxsKHRoaXMsIG1hcmtlcik7XG4gICAgICAgIH1cbiAgICB9XG5cblxuXG59XG52YXIgcXVldWUgPSBbXTtcbnZhciBkcmFpbmluZyA9IGZhbHNlO1xudmFyIGN1cnJlbnRRdWV1ZTtcbnZhciBxdWV1ZUluZGV4ID0gLTE7XG5cbmZ1bmN0aW9uIGNsZWFuVXBOZXh0VGljaygpIHtcbiAgICBpZiAoIWRyYWluaW5nIHx8ICFjdXJyZW50UXVldWUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBkcmFpbmluZyA9IGZhbHNlO1xuICAgIGlmIChjdXJyZW50UXVldWUubGVuZ3RoKSB7XG4gICAgICAgIHF1ZXVlID0gY3VycmVudFF1ZXVlLmNvbmNhdChxdWV1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcXVldWVJbmRleCA9IC0xO1xuICAgIH1cbiAgICBpZiAocXVldWUubGVuZ3RoKSB7XG4gICAgICAgIGRyYWluUXVldWUoKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGRyYWluUXVldWUoKSB7XG4gICAgaWYgKGRyYWluaW5nKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdmFyIHRpbWVvdXQgPSBydW5UaW1lb3V0KGNsZWFuVXBOZXh0VGljayk7XG4gICAgZHJhaW5pbmcgPSB0cnVlO1xuXG4gICAgdmFyIGxlbiA9IHF1ZXVlLmxlbmd0aDtcbiAgICB3aGlsZShsZW4pIHtcbiAgICAgICAgY3VycmVudFF1ZXVlID0gcXVldWU7XG4gICAgICAgIHF1ZXVlID0gW107XG4gICAgICAgIHdoaWxlICgrK3F1ZXVlSW5kZXggPCBsZW4pIHtcbiAgICAgICAgICAgIGlmIChjdXJyZW50UXVldWUpIHtcbiAgICAgICAgICAgICAgICBjdXJyZW50UXVldWVbcXVldWVJbmRleF0ucnVuKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcXVldWVJbmRleCA9IC0xO1xuICAgICAgICBsZW4gPSBxdWV1ZS5sZW5ndGg7XG4gICAgfVxuICAgIGN1cnJlbnRRdWV1ZSA9IG51bGw7XG4gICAgZHJhaW5pbmcgPSBmYWxzZTtcbiAgICBydW5DbGVhclRpbWVvdXQodGltZW91dCk7XG59XG5cbnByb2Nlc3MubmV4dFRpY2sgPSBmdW5jdGlvbiAoZnVuKSB7XG4gICAgdmFyIGFyZ3MgPSBuZXcgQXJyYXkoYXJndW1lbnRzLmxlbmd0aCAtIDEpO1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgICBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgYXJnc1tpIC0gMV0gPSBhcmd1bWVudHNbaV07XG4gICAgICAgIH1cbiAgICB9XG4gICAgcXVldWUucHVzaChuZXcgSXRlbShmdW4sIGFyZ3MpKTtcbiAgICBpZiAocXVldWUubGVuZ3RoID09PSAxICYmICFkcmFpbmluZykge1xuICAgICAgICBydW5UaW1lb3V0KGRyYWluUXVldWUpO1xuICAgIH1cbn07XG5cbi8vIHY4IGxpa2VzIHByZWRpY3RpYmxlIG9iamVjdHNcbmZ1bmN0aW9uIEl0ZW0oZnVuLCBhcnJheSkge1xuICAgIHRoaXMuZnVuID0gZnVuO1xuICAgIHRoaXMuYXJyYXkgPSBhcnJheTtcbn1cbkl0ZW0ucHJvdG90eXBlLnJ1biA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmZ1bi5hcHBseShudWxsLCB0aGlzLmFycmF5KTtcbn07XG5wcm9jZXNzLnRpdGxlID0gJ2Jyb3dzZXInO1xucHJvY2Vzcy5icm93c2VyID0gdHJ1ZTtcbnByb2Nlc3MuZW52ID0ge307XG5wcm9jZXNzLmFyZ3YgPSBbXTtcbnByb2Nlc3MudmVyc2lvbiA9ICcnOyAvLyBlbXB0eSBzdHJpbmcgdG8gYXZvaWQgcmVnZXhwIGlzc3Vlc1xucHJvY2Vzcy52ZXJzaW9ucyA9IHt9O1xuXG5mdW5jdGlvbiBub29wKCkge31cblxucHJvY2Vzcy5vbiA9IG5vb3A7XG5wcm9jZXNzLmFkZExpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3Mub25jZSA9IG5vb3A7XG5wcm9jZXNzLm9mZiA9IG5vb3A7XG5wcm9jZXNzLnJlbW92ZUxpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3MucmVtb3ZlQWxsTGlzdGVuZXJzID0gbm9vcDtcbnByb2Nlc3MuZW1pdCA9IG5vb3A7XG5wcm9jZXNzLnByZXBlbmRMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLnByZXBlbmRPbmNlTGlzdGVuZXIgPSBub29wO1xuXG5wcm9jZXNzLmxpc3RlbmVycyA9IGZ1bmN0aW9uIChuYW1lKSB7IHJldHVybiBbXSB9XG5cbnByb2Nlc3MuYmluZGluZyA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwcm9jZXNzLmJpbmRpbmcgaXMgbm90IHN1cHBvcnRlZCcpO1xufTtcblxucHJvY2Vzcy5jd2QgPSBmdW5jdGlvbiAoKSB7IHJldHVybiAnLycgfTtcbnByb2Nlc3MuY2hkaXIgPSBmdW5jdGlvbiAoZGlyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwcm9jZXNzLmNoZGlyIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn07XG5wcm9jZXNzLnVtYXNrID0gZnVuY3Rpb24oKSB7IHJldHVybiAwOyB9O1xuIiwiLyohIGh0dHBzOi8vbXRocy5iZS9wdW55Y29kZSB2MS40LjEgYnkgQG1hdGhpYXMgKi9cbjsoZnVuY3Rpb24ocm9vdCkge1xuXG5cdC8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZXMgKi9cblx0dmFyIGZyZWVFeHBvcnRzID0gdHlwZW9mIGV4cG9ydHMgPT0gJ29iamVjdCcgJiYgZXhwb3J0cyAmJlxuXHRcdCFleHBvcnRzLm5vZGVUeXBlICYmIGV4cG9ydHM7XG5cdHZhciBmcmVlTW9kdWxlID0gdHlwZW9mIG1vZHVsZSA9PSAnb2JqZWN0JyAmJiBtb2R1bGUgJiZcblx0XHQhbW9kdWxlLm5vZGVUeXBlICYmIG1vZHVsZTtcblx0dmFyIGZyZWVHbG9iYWwgPSB0eXBlb2YgZ2xvYmFsID09ICdvYmplY3QnICYmIGdsb2JhbDtcblx0aWYgKFxuXHRcdGZyZWVHbG9iYWwuZ2xvYmFsID09PSBmcmVlR2xvYmFsIHx8XG5cdFx0ZnJlZUdsb2JhbC53aW5kb3cgPT09IGZyZWVHbG9iYWwgfHxcblx0XHRmcmVlR2xvYmFsLnNlbGYgPT09IGZyZWVHbG9iYWxcblx0KSB7XG5cdFx0cm9vdCA9IGZyZWVHbG9iYWw7XG5cdH1cblxuXHQvKipcblx0ICogVGhlIGBwdW55Y29kZWAgb2JqZWN0LlxuXHQgKiBAbmFtZSBwdW55Y29kZVxuXHQgKiBAdHlwZSBPYmplY3Rcblx0ICovXG5cdHZhciBwdW55Y29kZSxcblxuXHQvKiogSGlnaGVzdCBwb3NpdGl2ZSBzaWduZWQgMzItYml0IGZsb2F0IHZhbHVlICovXG5cdG1heEludCA9IDIxNDc0ODM2NDcsIC8vIGFrYS4gMHg3RkZGRkZGRiBvciAyXjMxLTFcblxuXHQvKiogQm9vdHN0cmluZyBwYXJhbWV0ZXJzICovXG5cdGJhc2UgPSAzNixcblx0dE1pbiA9IDEsXG5cdHRNYXggPSAyNixcblx0c2tldyA9IDM4LFxuXHRkYW1wID0gNzAwLFxuXHRpbml0aWFsQmlhcyA9IDcyLFxuXHRpbml0aWFsTiA9IDEyOCwgLy8gMHg4MFxuXHRkZWxpbWl0ZXIgPSAnLScsIC8vICdcXHgyRCdcblxuXHQvKiogUmVndWxhciBleHByZXNzaW9ucyAqL1xuXHRyZWdleFB1bnljb2RlID0gL154bi0tLyxcblx0cmVnZXhOb25BU0NJSSA9IC9bXlxceDIwLVxceDdFXS8sIC8vIHVucHJpbnRhYmxlIEFTQ0lJIGNoYXJzICsgbm9uLUFTQ0lJIGNoYXJzXG5cdHJlZ2V4U2VwYXJhdG9ycyA9IC9bXFx4MkVcXHUzMDAyXFx1RkYwRVxcdUZGNjFdL2csIC8vIFJGQyAzNDkwIHNlcGFyYXRvcnNcblxuXHQvKiogRXJyb3IgbWVzc2FnZXMgKi9cblx0ZXJyb3JzID0ge1xuXHRcdCdvdmVyZmxvdyc6ICdPdmVyZmxvdzogaW5wdXQgbmVlZHMgd2lkZXIgaW50ZWdlcnMgdG8gcHJvY2VzcycsXG5cdFx0J25vdC1iYXNpYyc6ICdJbGxlZ2FsIGlucHV0ID49IDB4ODAgKG5vdCBhIGJhc2ljIGNvZGUgcG9pbnQpJyxcblx0XHQnaW52YWxpZC1pbnB1dCc6ICdJbnZhbGlkIGlucHV0J1xuXHR9LFxuXG5cdC8qKiBDb252ZW5pZW5jZSBzaG9ydGN1dHMgKi9cblx0YmFzZU1pbnVzVE1pbiA9IGJhc2UgLSB0TWluLFxuXHRmbG9vciA9IE1hdGguZmxvb3IsXG5cdHN0cmluZ0Zyb21DaGFyQ29kZSA9IFN0cmluZy5mcm9tQ2hhckNvZGUsXG5cblx0LyoqIFRlbXBvcmFyeSB2YXJpYWJsZSAqL1xuXHRrZXk7XG5cblx0LyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cblx0LyoqXG5cdCAqIEEgZ2VuZXJpYyBlcnJvciB1dGlsaXR5IGZ1bmN0aW9uLlxuXHQgKiBAcHJpdmF0ZVxuXHQgKiBAcGFyYW0ge1N0cmluZ30gdHlwZSBUaGUgZXJyb3IgdHlwZS5cblx0ICogQHJldHVybnMge0Vycm9yfSBUaHJvd3MgYSBgUmFuZ2VFcnJvcmAgd2l0aCB0aGUgYXBwbGljYWJsZSBlcnJvciBtZXNzYWdlLlxuXHQgKi9cblx0ZnVuY3Rpb24gZXJyb3IodHlwZSkge1xuXHRcdHRocm93IG5ldyBSYW5nZUVycm9yKGVycm9yc1t0eXBlXSk7XG5cdH1cblxuXHQvKipcblx0ICogQSBnZW5lcmljIGBBcnJheSNtYXBgIHV0aWxpdHkgZnVuY3Rpb24uXG5cdCAqIEBwcml2YXRlXG5cdCAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG5cdCAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIFRoZSBmdW5jdGlvbiB0aGF0IGdldHMgY2FsbGVkIGZvciBldmVyeSBhcnJheVxuXHQgKiBpdGVtLlxuXHQgKiBAcmV0dXJucyB7QXJyYXl9IEEgbmV3IGFycmF5IG9mIHZhbHVlcyByZXR1cm5lZCBieSB0aGUgY2FsbGJhY2sgZnVuY3Rpb24uXG5cdCAqL1xuXHRmdW5jdGlvbiBtYXAoYXJyYXksIGZuKSB7XG5cdFx0dmFyIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDtcblx0XHR2YXIgcmVzdWx0ID0gW107XG5cdFx0d2hpbGUgKGxlbmd0aC0tKSB7XG5cdFx0XHRyZXN1bHRbbGVuZ3RoXSA9IGZuKGFycmF5W2xlbmd0aF0pO1xuXHRcdH1cblx0XHRyZXR1cm4gcmVzdWx0O1xuXHR9XG5cblx0LyoqXG5cdCAqIEEgc2ltcGxlIGBBcnJheSNtYXBgLWxpa2Ugd3JhcHBlciB0byB3b3JrIHdpdGggZG9tYWluIG5hbWUgc3RyaW5ncyBvciBlbWFpbFxuXHQgKiBhZGRyZXNzZXMuXG5cdCAqIEBwcml2YXRlXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBkb21haW4gVGhlIGRvbWFpbiBuYW1lIG9yIGVtYWlsIGFkZHJlc3MuXG5cdCAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIFRoZSBmdW5jdGlvbiB0aGF0IGdldHMgY2FsbGVkIGZvciBldmVyeVxuXHQgKiBjaGFyYWN0ZXIuXG5cdCAqIEByZXR1cm5zIHtBcnJheX0gQSBuZXcgc3RyaW5nIG9mIGNoYXJhY3RlcnMgcmV0dXJuZWQgYnkgdGhlIGNhbGxiYWNrXG5cdCAqIGZ1bmN0aW9uLlxuXHQgKi9cblx0ZnVuY3Rpb24gbWFwRG9tYWluKHN0cmluZywgZm4pIHtcblx0XHR2YXIgcGFydHMgPSBzdHJpbmcuc3BsaXQoJ0AnKTtcblx0XHR2YXIgcmVzdWx0ID0gJyc7XG5cdFx0aWYgKHBhcnRzLmxlbmd0aCA+IDEpIHtcblx0XHRcdC8vIEluIGVtYWlsIGFkZHJlc3Nlcywgb25seSB0aGUgZG9tYWluIG5hbWUgc2hvdWxkIGJlIHB1bnljb2RlZC4gTGVhdmVcblx0XHRcdC8vIHRoZSBsb2NhbCBwYXJ0IChpLmUuIGV2ZXJ5dGhpbmcgdXAgdG8gYEBgKSBpbnRhY3QuXG5cdFx0XHRyZXN1bHQgPSBwYXJ0c1swXSArICdAJztcblx0XHRcdHN0cmluZyA9IHBhcnRzWzFdO1xuXHRcdH1cblx0XHQvLyBBdm9pZCBgc3BsaXQocmVnZXgpYCBmb3IgSUU4IGNvbXBhdGliaWxpdHkuIFNlZSAjMTcuXG5cdFx0c3RyaW5nID0gc3RyaW5nLnJlcGxhY2UocmVnZXhTZXBhcmF0b3JzLCAnXFx4MkUnKTtcblx0XHR2YXIgbGFiZWxzID0gc3RyaW5nLnNwbGl0KCcuJyk7XG5cdFx0dmFyIGVuY29kZWQgPSBtYXAobGFiZWxzLCBmbikuam9pbignLicpO1xuXHRcdHJldHVybiByZXN1bHQgKyBlbmNvZGVkO1xuXHR9XG5cblx0LyoqXG5cdCAqIENyZWF0ZXMgYW4gYXJyYXkgY29udGFpbmluZyB0aGUgbnVtZXJpYyBjb2RlIHBvaW50cyBvZiBlYWNoIFVuaWNvZGVcblx0ICogY2hhcmFjdGVyIGluIHRoZSBzdHJpbmcuIFdoaWxlIEphdmFTY3JpcHQgdXNlcyBVQ1MtMiBpbnRlcm5hbGx5LFxuXHQgKiB0aGlzIGZ1bmN0aW9uIHdpbGwgY29udmVydCBhIHBhaXIgb2Ygc3Vycm9nYXRlIGhhbHZlcyAoZWFjaCBvZiB3aGljaFxuXHQgKiBVQ1MtMiBleHBvc2VzIGFzIHNlcGFyYXRlIGNoYXJhY3RlcnMpIGludG8gYSBzaW5nbGUgY29kZSBwb2ludCxcblx0ICogbWF0Y2hpbmcgVVRGLTE2LlxuXHQgKiBAc2VlIGBwdW55Y29kZS51Y3MyLmVuY29kZWBcblx0ICogQHNlZSA8aHR0cHM6Ly9tYXRoaWFzYnluZW5zLmJlL25vdGVzL2phdmFzY3JpcHQtZW5jb2Rpbmc+XG5cdCAqIEBtZW1iZXJPZiBwdW55Y29kZS51Y3MyXG5cdCAqIEBuYW1lIGRlY29kZVxuXHQgKiBAcGFyYW0ge1N0cmluZ30gc3RyaW5nIFRoZSBVbmljb2RlIGlucHV0IHN0cmluZyAoVUNTLTIpLlxuXHQgKiBAcmV0dXJucyB7QXJyYXl9IFRoZSBuZXcgYXJyYXkgb2YgY29kZSBwb2ludHMuXG5cdCAqL1xuXHRmdW5jdGlvbiB1Y3MyZGVjb2RlKHN0cmluZykge1xuXHRcdHZhciBvdXRwdXQgPSBbXSxcblx0XHQgICAgY291bnRlciA9IDAsXG5cdFx0ICAgIGxlbmd0aCA9IHN0cmluZy5sZW5ndGgsXG5cdFx0ICAgIHZhbHVlLFxuXHRcdCAgICBleHRyYTtcblx0XHR3aGlsZSAoY291bnRlciA8IGxlbmd0aCkge1xuXHRcdFx0dmFsdWUgPSBzdHJpbmcuY2hhckNvZGVBdChjb3VudGVyKyspO1xuXHRcdFx0aWYgKHZhbHVlID49IDB4RDgwMCAmJiB2YWx1ZSA8PSAweERCRkYgJiYgY291bnRlciA8IGxlbmd0aCkge1xuXHRcdFx0XHQvLyBoaWdoIHN1cnJvZ2F0ZSwgYW5kIHRoZXJlIGlzIGEgbmV4dCBjaGFyYWN0ZXJcblx0XHRcdFx0ZXh0cmEgPSBzdHJpbmcuY2hhckNvZGVBdChjb3VudGVyKyspO1xuXHRcdFx0XHRpZiAoKGV4dHJhICYgMHhGQzAwKSA9PSAweERDMDApIHsgLy8gbG93IHN1cnJvZ2F0ZVxuXHRcdFx0XHRcdG91dHB1dC5wdXNoKCgodmFsdWUgJiAweDNGRikgPDwgMTApICsgKGV4dHJhICYgMHgzRkYpICsgMHgxMDAwMCk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0Ly8gdW5tYXRjaGVkIHN1cnJvZ2F0ZTsgb25seSBhcHBlbmQgdGhpcyBjb2RlIHVuaXQsIGluIGNhc2UgdGhlIG5leHRcblx0XHRcdFx0XHQvLyBjb2RlIHVuaXQgaXMgdGhlIGhpZ2ggc3Vycm9nYXRlIG9mIGEgc3Vycm9nYXRlIHBhaXJcblx0XHRcdFx0XHRvdXRwdXQucHVzaCh2YWx1ZSk7XG5cdFx0XHRcdFx0Y291bnRlci0tO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRvdXRwdXQucHVzaCh2YWx1ZSk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiBvdXRwdXQ7XG5cdH1cblxuXHQvKipcblx0ICogQ3JlYXRlcyBhIHN0cmluZyBiYXNlZCBvbiBhbiBhcnJheSBvZiBudW1lcmljIGNvZGUgcG9pbnRzLlxuXHQgKiBAc2VlIGBwdW55Y29kZS51Y3MyLmRlY29kZWBcblx0ICogQG1lbWJlck9mIHB1bnljb2RlLnVjczJcblx0ICogQG5hbWUgZW5jb2RlXG5cdCAqIEBwYXJhbSB7QXJyYXl9IGNvZGVQb2ludHMgVGhlIGFycmF5IG9mIG51bWVyaWMgY29kZSBwb2ludHMuXG5cdCAqIEByZXR1cm5zIHtTdHJpbmd9IFRoZSBuZXcgVW5pY29kZSBzdHJpbmcgKFVDUy0yKS5cblx0ICovXG5cdGZ1bmN0aW9uIHVjczJlbmNvZGUoYXJyYXkpIHtcblx0XHRyZXR1cm4gbWFwKGFycmF5LCBmdW5jdGlvbih2YWx1ZSkge1xuXHRcdFx0dmFyIG91dHB1dCA9ICcnO1xuXHRcdFx0aWYgKHZhbHVlID4gMHhGRkZGKSB7XG5cdFx0XHRcdHZhbHVlIC09IDB4MTAwMDA7XG5cdFx0XHRcdG91dHB1dCArPSBzdHJpbmdGcm9tQ2hhckNvZGUodmFsdWUgPj4+IDEwICYgMHgzRkYgfCAweEQ4MDApO1xuXHRcdFx0XHR2YWx1ZSA9IDB4REMwMCB8IHZhbHVlICYgMHgzRkY7XG5cdFx0XHR9XG5cdFx0XHRvdXRwdXQgKz0gc3RyaW5nRnJvbUNoYXJDb2RlKHZhbHVlKTtcblx0XHRcdHJldHVybiBvdXRwdXQ7XG5cdFx0fSkuam9pbignJyk7XG5cdH1cblxuXHQvKipcblx0ICogQ29udmVydHMgYSBiYXNpYyBjb2RlIHBvaW50IGludG8gYSBkaWdpdC9pbnRlZ2VyLlxuXHQgKiBAc2VlIGBkaWdpdFRvQmFzaWMoKWBcblx0ICogQHByaXZhdGVcblx0ICogQHBhcmFtIHtOdW1iZXJ9IGNvZGVQb2ludCBUaGUgYmFzaWMgbnVtZXJpYyBjb2RlIHBvaW50IHZhbHVlLlxuXHQgKiBAcmV0dXJucyB7TnVtYmVyfSBUaGUgbnVtZXJpYyB2YWx1ZSBvZiBhIGJhc2ljIGNvZGUgcG9pbnQgKGZvciB1c2UgaW5cblx0ICogcmVwcmVzZW50aW5nIGludGVnZXJzKSBpbiB0aGUgcmFuZ2UgYDBgIHRvIGBiYXNlIC0gMWAsIG9yIGBiYXNlYCBpZlxuXHQgKiB0aGUgY29kZSBwb2ludCBkb2VzIG5vdCByZXByZXNlbnQgYSB2YWx1ZS5cblx0ICovXG5cdGZ1bmN0aW9uIGJhc2ljVG9EaWdpdChjb2RlUG9pbnQpIHtcblx0XHRpZiAoY29kZVBvaW50IC0gNDggPCAxMCkge1xuXHRcdFx0cmV0dXJuIGNvZGVQb2ludCAtIDIyO1xuXHRcdH1cblx0XHRpZiAoY29kZVBvaW50IC0gNjUgPCAyNikge1xuXHRcdFx0cmV0dXJuIGNvZGVQb2ludCAtIDY1O1xuXHRcdH1cblx0XHRpZiAoY29kZVBvaW50IC0gOTcgPCAyNikge1xuXHRcdFx0cmV0dXJuIGNvZGVQb2ludCAtIDk3O1xuXHRcdH1cblx0XHRyZXR1cm4gYmFzZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDb252ZXJ0cyBhIGRpZ2l0L2ludGVnZXIgaW50byBhIGJhc2ljIGNvZGUgcG9pbnQuXG5cdCAqIEBzZWUgYGJhc2ljVG9EaWdpdCgpYFxuXHQgKiBAcHJpdmF0ZVxuXHQgKiBAcGFyYW0ge051bWJlcn0gZGlnaXQgVGhlIG51bWVyaWMgdmFsdWUgb2YgYSBiYXNpYyBjb2RlIHBvaW50LlxuXHQgKiBAcmV0dXJucyB7TnVtYmVyfSBUaGUgYmFzaWMgY29kZSBwb2ludCB3aG9zZSB2YWx1ZSAod2hlbiB1c2VkIGZvclxuXHQgKiByZXByZXNlbnRpbmcgaW50ZWdlcnMpIGlzIGBkaWdpdGAsIHdoaWNoIG5lZWRzIHRvIGJlIGluIHRoZSByYW5nZVxuXHQgKiBgMGAgdG8gYGJhc2UgLSAxYC4gSWYgYGZsYWdgIGlzIG5vbi16ZXJvLCB0aGUgdXBwZXJjYXNlIGZvcm0gaXNcblx0ICogdXNlZDsgZWxzZSwgdGhlIGxvd2VyY2FzZSBmb3JtIGlzIHVzZWQuIFRoZSBiZWhhdmlvciBpcyB1bmRlZmluZWRcblx0ICogaWYgYGZsYWdgIGlzIG5vbi16ZXJvIGFuZCBgZGlnaXRgIGhhcyBubyB1cHBlcmNhc2UgZm9ybS5cblx0ICovXG5cdGZ1bmN0aW9uIGRpZ2l0VG9CYXNpYyhkaWdpdCwgZmxhZykge1xuXHRcdC8vICAwLi4yNSBtYXAgdG8gQVNDSUkgYS4ueiBvciBBLi5aXG5cdFx0Ly8gMjYuLjM1IG1hcCB0byBBU0NJSSAwLi45XG5cdFx0cmV0dXJuIGRpZ2l0ICsgMjIgKyA3NSAqIChkaWdpdCA8IDI2KSAtICgoZmxhZyAhPSAwKSA8PCA1KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBCaWFzIGFkYXB0YXRpb24gZnVuY3Rpb24gYXMgcGVyIHNlY3Rpb24gMy40IG9mIFJGQyAzNDkyLlxuXHQgKiBodHRwczovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjMzQ5MiNzZWN0aW9uLTMuNFxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cblx0ZnVuY3Rpb24gYWRhcHQoZGVsdGEsIG51bVBvaW50cywgZmlyc3RUaW1lKSB7XG5cdFx0dmFyIGsgPSAwO1xuXHRcdGRlbHRhID0gZmlyc3RUaW1lID8gZmxvb3IoZGVsdGEgLyBkYW1wKSA6IGRlbHRhID4+IDE7XG5cdFx0ZGVsdGEgKz0gZmxvb3IoZGVsdGEgLyBudW1Qb2ludHMpO1xuXHRcdGZvciAoLyogbm8gaW5pdGlhbGl6YXRpb24gKi87IGRlbHRhID4gYmFzZU1pbnVzVE1pbiAqIHRNYXggPj4gMTsgayArPSBiYXNlKSB7XG5cdFx0XHRkZWx0YSA9IGZsb29yKGRlbHRhIC8gYmFzZU1pbnVzVE1pbik7XG5cdFx0fVxuXHRcdHJldHVybiBmbG9vcihrICsgKGJhc2VNaW51c1RNaW4gKyAxKSAqIGRlbHRhIC8gKGRlbHRhICsgc2tldykpO1xuXHR9XG5cblx0LyoqXG5cdCAqIENvbnZlcnRzIGEgUHVueWNvZGUgc3RyaW5nIG9mIEFTQ0lJLW9ubHkgc3ltYm9scyB0byBhIHN0cmluZyBvZiBVbmljb2RlXG5cdCAqIHN5bWJvbHMuXG5cdCAqIEBtZW1iZXJPZiBwdW55Y29kZVxuXHQgKiBAcGFyYW0ge1N0cmluZ30gaW5wdXQgVGhlIFB1bnljb2RlIHN0cmluZyBvZiBBU0NJSS1vbmx5IHN5bWJvbHMuXG5cdCAqIEByZXR1cm5zIHtTdHJpbmd9IFRoZSByZXN1bHRpbmcgc3RyaW5nIG9mIFVuaWNvZGUgc3ltYm9scy5cblx0ICovXG5cdGZ1bmN0aW9uIGRlY29kZShpbnB1dCkge1xuXHRcdC8vIERvbid0IHVzZSBVQ1MtMlxuXHRcdHZhciBvdXRwdXQgPSBbXSxcblx0XHQgICAgaW5wdXRMZW5ndGggPSBpbnB1dC5sZW5ndGgsXG5cdFx0ICAgIG91dCxcblx0XHQgICAgaSA9IDAsXG5cdFx0ICAgIG4gPSBpbml0aWFsTixcblx0XHQgICAgYmlhcyA9IGluaXRpYWxCaWFzLFxuXHRcdCAgICBiYXNpYyxcblx0XHQgICAgaixcblx0XHQgICAgaW5kZXgsXG5cdFx0ICAgIG9sZGksXG5cdFx0ICAgIHcsXG5cdFx0ICAgIGssXG5cdFx0ICAgIGRpZ2l0LFxuXHRcdCAgICB0LFxuXHRcdCAgICAvKiogQ2FjaGVkIGNhbGN1bGF0aW9uIHJlc3VsdHMgKi9cblx0XHQgICAgYmFzZU1pbnVzVDtcblxuXHRcdC8vIEhhbmRsZSB0aGUgYmFzaWMgY29kZSBwb2ludHM6IGxldCBgYmFzaWNgIGJlIHRoZSBudW1iZXIgb2YgaW5wdXQgY29kZVxuXHRcdC8vIHBvaW50cyBiZWZvcmUgdGhlIGxhc3QgZGVsaW1pdGVyLCBvciBgMGAgaWYgdGhlcmUgaXMgbm9uZSwgdGhlbiBjb3B5XG5cdFx0Ly8gdGhlIGZpcnN0IGJhc2ljIGNvZGUgcG9pbnRzIHRvIHRoZSBvdXRwdXQuXG5cblx0XHRiYXNpYyA9IGlucHV0Lmxhc3RJbmRleE9mKGRlbGltaXRlcik7XG5cdFx0aWYgKGJhc2ljIDwgMCkge1xuXHRcdFx0YmFzaWMgPSAwO1xuXHRcdH1cblxuXHRcdGZvciAoaiA9IDA7IGogPCBiYXNpYzsgKytqKSB7XG5cdFx0XHQvLyBpZiBpdCdzIG5vdCBhIGJhc2ljIGNvZGUgcG9pbnRcblx0XHRcdGlmIChpbnB1dC5jaGFyQ29kZUF0KGopID49IDB4ODApIHtcblx0XHRcdFx0ZXJyb3IoJ25vdC1iYXNpYycpO1xuXHRcdFx0fVxuXHRcdFx0b3V0cHV0LnB1c2goaW5wdXQuY2hhckNvZGVBdChqKSk7XG5cdFx0fVxuXG5cdFx0Ly8gTWFpbiBkZWNvZGluZyBsb29wOiBzdGFydCBqdXN0IGFmdGVyIHRoZSBsYXN0IGRlbGltaXRlciBpZiBhbnkgYmFzaWMgY29kZVxuXHRcdC8vIHBvaW50cyB3ZXJlIGNvcGllZDsgc3RhcnQgYXQgdGhlIGJlZ2lubmluZyBvdGhlcndpc2UuXG5cblx0XHRmb3IgKGluZGV4ID0gYmFzaWMgPiAwID8gYmFzaWMgKyAxIDogMDsgaW5kZXggPCBpbnB1dExlbmd0aDsgLyogbm8gZmluYWwgZXhwcmVzc2lvbiAqLykge1xuXG5cdFx0XHQvLyBgaW5kZXhgIGlzIHRoZSBpbmRleCBvZiB0aGUgbmV4dCBjaGFyYWN0ZXIgdG8gYmUgY29uc3VtZWQuXG5cdFx0XHQvLyBEZWNvZGUgYSBnZW5lcmFsaXplZCB2YXJpYWJsZS1sZW5ndGggaW50ZWdlciBpbnRvIGBkZWx0YWAsXG5cdFx0XHQvLyB3aGljaCBnZXRzIGFkZGVkIHRvIGBpYC4gVGhlIG92ZXJmbG93IGNoZWNraW5nIGlzIGVhc2llclxuXHRcdFx0Ly8gaWYgd2UgaW5jcmVhc2UgYGlgIGFzIHdlIGdvLCB0aGVuIHN1YnRyYWN0IG9mZiBpdHMgc3RhcnRpbmdcblx0XHRcdC8vIHZhbHVlIGF0IHRoZSBlbmQgdG8gb2J0YWluIGBkZWx0YWAuXG5cdFx0XHRmb3IgKG9sZGkgPSBpLCB3ID0gMSwgayA9IGJhc2U7IC8qIG5vIGNvbmRpdGlvbiAqLzsgayArPSBiYXNlKSB7XG5cblx0XHRcdFx0aWYgKGluZGV4ID49IGlucHV0TGVuZ3RoKSB7XG5cdFx0XHRcdFx0ZXJyb3IoJ2ludmFsaWQtaW5wdXQnKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGRpZ2l0ID0gYmFzaWNUb0RpZ2l0KGlucHV0LmNoYXJDb2RlQXQoaW5kZXgrKykpO1xuXG5cdFx0XHRcdGlmIChkaWdpdCA+PSBiYXNlIHx8IGRpZ2l0ID4gZmxvb3IoKG1heEludCAtIGkpIC8gdykpIHtcblx0XHRcdFx0XHRlcnJvcignb3ZlcmZsb3cnKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGkgKz0gZGlnaXQgKiB3O1xuXHRcdFx0XHR0ID0gayA8PSBiaWFzID8gdE1pbiA6IChrID49IGJpYXMgKyB0TWF4ID8gdE1heCA6IGsgLSBiaWFzKTtcblxuXHRcdFx0XHRpZiAoZGlnaXQgPCB0KSB7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRiYXNlTWludXNUID0gYmFzZSAtIHQ7XG5cdFx0XHRcdGlmICh3ID4gZmxvb3IobWF4SW50IC8gYmFzZU1pbnVzVCkpIHtcblx0XHRcdFx0XHRlcnJvcignb3ZlcmZsb3cnKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHcgKj0gYmFzZU1pbnVzVDtcblxuXHRcdFx0fVxuXG5cdFx0XHRvdXQgPSBvdXRwdXQubGVuZ3RoICsgMTtcblx0XHRcdGJpYXMgPSBhZGFwdChpIC0gb2xkaSwgb3V0LCBvbGRpID09IDApO1xuXG5cdFx0XHQvLyBgaWAgd2FzIHN1cHBvc2VkIHRvIHdyYXAgYXJvdW5kIGZyb20gYG91dGAgdG8gYDBgLFxuXHRcdFx0Ly8gaW5jcmVtZW50aW5nIGBuYCBlYWNoIHRpbWUsIHNvIHdlJ2xsIGZpeCB0aGF0IG5vdzpcblx0XHRcdGlmIChmbG9vcihpIC8gb3V0KSA+IG1heEludCAtIG4pIHtcblx0XHRcdFx0ZXJyb3IoJ292ZXJmbG93Jyk7XG5cdFx0XHR9XG5cblx0XHRcdG4gKz0gZmxvb3IoaSAvIG91dCk7XG5cdFx0XHRpICU9IG91dDtcblxuXHRcdFx0Ly8gSW5zZXJ0IGBuYCBhdCBwb3NpdGlvbiBgaWAgb2YgdGhlIG91dHB1dFxuXHRcdFx0b3V0cHV0LnNwbGljZShpKyssIDAsIG4pO1xuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIHVjczJlbmNvZGUob3V0cHV0KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDb252ZXJ0cyBhIHN0cmluZyBvZiBVbmljb2RlIHN5bWJvbHMgKGUuZy4gYSBkb21haW4gbmFtZSBsYWJlbCkgdG8gYVxuXHQgKiBQdW55Y29kZSBzdHJpbmcgb2YgQVNDSUktb25seSBzeW1ib2xzLlxuXHQgKiBAbWVtYmVyT2YgcHVueWNvZGVcblx0ICogQHBhcmFtIHtTdHJpbmd9IGlucHV0IFRoZSBzdHJpbmcgb2YgVW5pY29kZSBzeW1ib2xzLlxuXHQgKiBAcmV0dXJucyB7U3RyaW5nfSBUaGUgcmVzdWx0aW5nIFB1bnljb2RlIHN0cmluZyBvZiBBU0NJSS1vbmx5IHN5bWJvbHMuXG5cdCAqL1xuXHRmdW5jdGlvbiBlbmNvZGUoaW5wdXQpIHtcblx0XHR2YXIgbixcblx0XHQgICAgZGVsdGEsXG5cdFx0ICAgIGhhbmRsZWRDUENvdW50LFxuXHRcdCAgICBiYXNpY0xlbmd0aCxcblx0XHQgICAgYmlhcyxcblx0XHQgICAgaixcblx0XHQgICAgbSxcblx0XHQgICAgcSxcblx0XHQgICAgayxcblx0XHQgICAgdCxcblx0XHQgICAgY3VycmVudFZhbHVlLFxuXHRcdCAgICBvdXRwdXQgPSBbXSxcblx0XHQgICAgLyoqIGBpbnB1dExlbmd0aGAgd2lsbCBob2xkIHRoZSBudW1iZXIgb2YgY29kZSBwb2ludHMgaW4gYGlucHV0YC4gKi9cblx0XHQgICAgaW5wdXRMZW5ndGgsXG5cdFx0ICAgIC8qKiBDYWNoZWQgY2FsY3VsYXRpb24gcmVzdWx0cyAqL1xuXHRcdCAgICBoYW5kbGVkQ1BDb3VudFBsdXNPbmUsXG5cdFx0ICAgIGJhc2VNaW51c1QsXG5cdFx0ICAgIHFNaW51c1Q7XG5cblx0XHQvLyBDb252ZXJ0IHRoZSBpbnB1dCBpbiBVQ1MtMiB0byBVbmljb2RlXG5cdFx0aW5wdXQgPSB1Y3MyZGVjb2RlKGlucHV0KTtcblxuXHRcdC8vIENhY2hlIHRoZSBsZW5ndGhcblx0XHRpbnB1dExlbmd0aCA9IGlucHV0Lmxlbmd0aDtcblxuXHRcdC8vIEluaXRpYWxpemUgdGhlIHN0YXRlXG5cdFx0biA9IGluaXRpYWxOO1xuXHRcdGRlbHRhID0gMDtcblx0XHRiaWFzID0gaW5pdGlhbEJpYXM7XG5cblx0XHQvLyBIYW5kbGUgdGhlIGJhc2ljIGNvZGUgcG9pbnRzXG5cdFx0Zm9yIChqID0gMDsgaiA8IGlucHV0TGVuZ3RoOyArK2opIHtcblx0XHRcdGN1cnJlbnRWYWx1ZSA9IGlucHV0W2pdO1xuXHRcdFx0aWYgKGN1cnJlbnRWYWx1ZSA8IDB4ODApIHtcblx0XHRcdFx0b3V0cHV0LnB1c2goc3RyaW5nRnJvbUNoYXJDb2RlKGN1cnJlbnRWYWx1ZSkpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGhhbmRsZWRDUENvdW50ID0gYmFzaWNMZW5ndGggPSBvdXRwdXQubGVuZ3RoO1xuXG5cdFx0Ly8gYGhhbmRsZWRDUENvdW50YCBpcyB0aGUgbnVtYmVyIG9mIGNvZGUgcG9pbnRzIHRoYXQgaGF2ZSBiZWVuIGhhbmRsZWQ7XG5cdFx0Ly8gYGJhc2ljTGVuZ3RoYCBpcyB0aGUgbnVtYmVyIG9mIGJhc2ljIGNvZGUgcG9pbnRzLlxuXG5cdFx0Ly8gRmluaXNoIHRoZSBiYXNpYyBzdHJpbmcgLSBpZiBpdCBpcyBub3QgZW1wdHkgLSB3aXRoIGEgZGVsaW1pdGVyXG5cdFx0aWYgKGJhc2ljTGVuZ3RoKSB7XG5cdFx0XHRvdXRwdXQucHVzaChkZWxpbWl0ZXIpO1xuXHRcdH1cblxuXHRcdC8vIE1haW4gZW5jb2RpbmcgbG9vcDpcblx0XHR3aGlsZSAoaGFuZGxlZENQQ291bnQgPCBpbnB1dExlbmd0aCkge1xuXG5cdFx0XHQvLyBBbGwgbm9uLWJhc2ljIGNvZGUgcG9pbnRzIDwgbiBoYXZlIGJlZW4gaGFuZGxlZCBhbHJlYWR5LiBGaW5kIHRoZSBuZXh0XG5cdFx0XHQvLyBsYXJnZXIgb25lOlxuXHRcdFx0Zm9yIChtID0gbWF4SW50LCBqID0gMDsgaiA8IGlucHV0TGVuZ3RoOyArK2opIHtcblx0XHRcdFx0Y3VycmVudFZhbHVlID0gaW5wdXRbal07XG5cdFx0XHRcdGlmIChjdXJyZW50VmFsdWUgPj0gbiAmJiBjdXJyZW50VmFsdWUgPCBtKSB7XG5cdFx0XHRcdFx0bSA9IGN1cnJlbnRWYWx1ZTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyBJbmNyZWFzZSBgZGVsdGFgIGVub3VnaCB0byBhZHZhbmNlIHRoZSBkZWNvZGVyJ3MgPG4saT4gc3RhdGUgdG8gPG0sMD4sXG5cdFx0XHQvLyBidXQgZ3VhcmQgYWdhaW5zdCBvdmVyZmxvd1xuXHRcdFx0aGFuZGxlZENQQ291bnRQbHVzT25lID0gaGFuZGxlZENQQ291bnQgKyAxO1xuXHRcdFx0aWYgKG0gLSBuID4gZmxvb3IoKG1heEludCAtIGRlbHRhKSAvIGhhbmRsZWRDUENvdW50UGx1c09uZSkpIHtcblx0XHRcdFx0ZXJyb3IoJ292ZXJmbG93Jyk7XG5cdFx0XHR9XG5cblx0XHRcdGRlbHRhICs9IChtIC0gbikgKiBoYW5kbGVkQ1BDb3VudFBsdXNPbmU7XG5cdFx0XHRuID0gbTtcblxuXHRcdFx0Zm9yIChqID0gMDsgaiA8IGlucHV0TGVuZ3RoOyArK2opIHtcblx0XHRcdFx0Y3VycmVudFZhbHVlID0gaW5wdXRbal07XG5cblx0XHRcdFx0aWYgKGN1cnJlbnRWYWx1ZSA8IG4gJiYgKytkZWx0YSA+IG1heEludCkge1xuXHRcdFx0XHRcdGVycm9yKCdvdmVyZmxvdycpO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0aWYgKGN1cnJlbnRWYWx1ZSA9PSBuKSB7XG5cdFx0XHRcdFx0Ly8gUmVwcmVzZW50IGRlbHRhIGFzIGEgZ2VuZXJhbGl6ZWQgdmFyaWFibGUtbGVuZ3RoIGludGVnZXJcblx0XHRcdFx0XHRmb3IgKHEgPSBkZWx0YSwgayA9IGJhc2U7IC8qIG5vIGNvbmRpdGlvbiAqLzsgayArPSBiYXNlKSB7XG5cdFx0XHRcdFx0XHR0ID0gayA8PSBiaWFzID8gdE1pbiA6IChrID49IGJpYXMgKyB0TWF4ID8gdE1heCA6IGsgLSBiaWFzKTtcblx0XHRcdFx0XHRcdGlmIChxIDwgdCkge1xuXHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdHFNaW51c1QgPSBxIC0gdDtcblx0XHRcdFx0XHRcdGJhc2VNaW51c1QgPSBiYXNlIC0gdDtcblx0XHRcdFx0XHRcdG91dHB1dC5wdXNoKFxuXHRcdFx0XHRcdFx0XHRzdHJpbmdGcm9tQ2hhckNvZGUoZGlnaXRUb0Jhc2ljKHQgKyBxTWludXNUICUgYmFzZU1pbnVzVCwgMCkpXG5cdFx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdFx0cSA9IGZsb29yKHFNaW51c1QgLyBiYXNlTWludXNUKTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRvdXRwdXQucHVzaChzdHJpbmdGcm9tQ2hhckNvZGUoZGlnaXRUb0Jhc2ljKHEsIDApKSk7XG5cdFx0XHRcdFx0YmlhcyA9IGFkYXB0KGRlbHRhLCBoYW5kbGVkQ1BDb3VudFBsdXNPbmUsIGhhbmRsZWRDUENvdW50ID09IGJhc2ljTGVuZ3RoKTtcblx0XHRcdFx0XHRkZWx0YSA9IDA7XG5cdFx0XHRcdFx0KytoYW5kbGVkQ1BDb3VudDtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQrK2RlbHRhO1xuXHRcdFx0KytuO1xuXG5cdFx0fVxuXHRcdHJldHVybiBvdXRwdXQuam9pbignJyk7XG5cdH1cblxuXHQvKipcblx0ICogQ29udmVydHMgYSBQdW55Y29kZSBzdHJpbmcgcmVwcmVzZW50aW5nIGEgZG9tYWluIG5hbWUgb3IgYW4gZW1haWwgYWRkcmVzc1xuXHQgKiB0byBVbmljb2RlLiBPbmx5IHRoZSBQdW55Y29kZWQgcGFydHMgb2YgdGhlIGlucHV0IHdpbGwgYmUgY29udmVydGVkLCBpLmUuXG5cdCAqIGl0IGRvZXNuJ3QgbWF0dGVyIGlmIHlvdSBjYWxsIGl0IG9uIGEgc3RyaW5nIHRoYXQgaGFzIGFscmVhZHkgYmVlblxuXHQgKiBjb252ZXJ0ZWQgdG8gVW5pY29kZS5cblx0ICogQG1lbWJlck9mIHB1bnljb2RlXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dCBUaGUgUHVueWNvZGVkIGRvbWFpbiBuYW1lIG9yIGVtYWlsIGFkZHJlc3MgdG9cblx0ICogY29udmVydCB0byBVbmljb2RlLlxuXHQgKiBAcmV0dXJucyB7U3RyaW5nfSBUaGUgVW5pY29kZSByZXByZXNlbnRhdGlvbiBvZiB0aGUgZ2l2ZW4gUHVueWNvZGVcblx0ICogc3RyaW5nLlxuXHQgKi9cblx0ZnVuY3Rpb24gdG9Vbmljb2RlKGlucHV0KSB7XG5cdFx0cmV0dXJuIG1hcERvbWFpbihpbnB1dCwgZnVuY3Rpb24oc3RyaW5nKSB7XG5cdFx0XHRyZXR1cm4gcmVnZXhQdW55Y29kZS50ZXN0KHN0cmluZylcblx0XHRcdFx0PyBkZWNvZGUoc3RyaW5nLnNsaWNlKDQpLnRvTG93ZXJDYXNlKCkpXG5cdFx0XHRcdDogc3RyaW5nO1xuXHRcdH0pO1xuXHR9XG5cblx0LyoqXG5cdCAqIENvbnZlcnRzIGEgVW5pY29kZSBzdHJpbmcgcmVwcmVzZW50aW5nIGEgZG9tYWluIG5hbWUgb3IgYW4gZW1haWwgYWRkcmVzcyB0b1xuXHQgKiBQdW55Y29kZS4gT25seSB0aGUgbm9uLUFTQ0lJIHBhcnRzIG9mIHRoZSBkb21haW4gbmFtZSB3aWxsIGJlIGNvbnZlcnRlZCxcblx0ICogaS5lLiBpdCBkb2Vzbid0IG1hdHRlciBpZiB5b3UgY2FsbCBpdCB3aXRoIGEgZG9tYWluIHRoYXQncyBhbHJlYWR5IGluXG5cdCAqIEFTQ0lJLlxuXHQgKiBAbWVtYmVyT2YgcHVueWNvZGVcblx0ICogQHBhcmFtIHtTdHJpbmd9IGlucHV0IFRoZSBkb21haW4gbmFtZSBvciBlbWFpbCBhZGRyZXNzIHRvIGNvbnZlcnQsIGFzIGFcblx0ICogVW5pY29kZSBzdHJpbmcuXG5cdCAqIEByZXR1cm5zIHtTdHJpbmd9IFRoZSBQdW55Y29kZSByZXByZXNlbnRhdGlvbiBvZiB0aGUgZ2l2ZW4gZG9tYWluIG5hbWUgb3Jcblx0ICogZW1haWwgYWRkcmVzcy5cblx0ICovXG5cdGZ1bmN0aW9uIHRvQVNDSUkoaW5wdXQpIHtcblx0XHRyZXR1cm4gbWFwRG9tYWluKGlucHV0LCBmdW5jdGlvbihzdHJpbmcpIHtcblx0XHRcdHJldHVybiByZWdleE5vbkFTQ0lJLnRlc3Qoc3RyaW5nKVxuXHRcdFx0XHQ/ICd4bi0tJyArIGVuY29kZShzdHJpbmcpXG5cdFx0XHRcdDogc3RyaW5nO1xuXHRcdH0pO1xuXHR9XG5cblx0LyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cblx0LyoqIERlZmluZSB0aGUgcHVibGljIEFQSSAqL1xuXHRwdW55Y29kZSA9IHtcblx0XHQvKipcblx0XHQgKiBBIHN0cmluZyByZXByZXNlbnRpbmcgdGhlIGN1cnJlbnQgUHVueWNvZGUuanMgdmVyc2lvbiBudW1iZXIuXG5cdFx0ICogQG1lbWJlck9mIHB1bnljb2RlXG5cdFx0ICogQHR5cGUgU3RyaW5nXG5cdFx0ICovXG5cdFx0J3ZlcnNpb24nOiAnMS40LjEnLFxuXHRcdC8qKlxuXHRcdCAqIEFuIG9iamVjdCBvZiBtZXRob2RzIHRvIGNvbnZlcnQgZnJvbSBKYXZhU2NyaXB0J3MgaW50ZXJuYWwgY2hhcmFjdGVyXG5cdFx0ICogcmVwcmVzZW50YXRpb24gKFVDUy0yKSB0byBVbmljb2RlIGNvZGUgcG9pbnRzLCBhbmQgYmFjay5cblx0XHQgKiBAc2VlIDxodHRwczovL21hdGhpYXNieW5lbnMuYmUvbm90ZXMvamF2YXNjcmlwdC1lbmNvZGluZz5cblx0XHQgKiBAbWVtYmVyT2YgcHVueWNvZGVcblx0XHQgKiBAdHlwZSBPYmplY3Rcblx0XHQgKi9cblx0XHQndWNzMic6IHtcblx0XHRcdCdkZWNvZGUnOiB1Y3MyZGVjb2RlLFxuXHRcdFx0J2VuY29kZSc6IHVjczJlbmNvZGVcblx0XHR9LFxuXHRcdCdkZWNvZGUnOiBkZWNvZGUsXG5cdFx0J2VuY29kZSc6IGVuY29kZSxcblx0XHQndG9BU0NJSSc6IHRvQVNDSUksXG5cdFx0J3RvVW5pY29kZSc6IHRvVW5pY29kZVxuXHR9O1xuXG5cdC8qKiBFeHBvc2UgYHB1bnljb2RlYCAqL1xuXHQvLyBTb21lIEFNRCBidWlsZCBvcHRpbWl6ZXJzLCBsaWtlIHIuanMsIGNoZWNrIGZvciBzcGVjaWZpYyBjb25kaXRpb24gcGF0dGVybnNcblx0Ly8gbGlrZSB0aGUgZm9sbG93aW5nOlxuXHRpZiAoXG5cdFx0dHlwZW9mIGRlZmluZSA9PSAnZnVuY3Rpb24nICYmXG5cdFx0dHlwZW9mIGRlZmluZS5hbWQgPT0gJ29iamVjdCcgJiZcblx0XHRkZWZpbmUuYW1kXG5cdCkge1xuXHRcdGRlZmluZSgncHVueWNvZGUnLCBmdW5jdGlvbigpIHtcblx0XHRcdHJldHVybiBwdW55Y29kZTtcblx0XHR9KTtcblx0fSBlbHNlIGlmIChmcmVlRXhwb3J0cyAmJiBmcmVlTW9kdWxlKSB7XG5cdFx0aWYgKG1vZHVsZS5leHBvcnRzID09IGZyZWVFeHBvcnRzKSB7XG5cdFx0XHQvLyBpbiBOb2RlLmpzLCBpby5qcywgb3IgUmluZ29KUyB2MC44LjArXG5cdFx0XHRmcmVlTW9kdWxlLmV4cG9ydHMgPSBwdW55Y29kZTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0Ly8gaW4gTmFyd2hhbCBvciBSaW5nb0pTIHYwLjcuMC1cblx0XHRcdGZvciAoa2V5IGluIHB1bnljb2RlKSB7XG5cdFx0XHRcdHB1bnljb2RlLmhhc093blByb3BlcnR5KGtleSkgJiYgKGZyZWVFeHBvcnRzW2tleV0gPSBwdW55Y29kZVtrZXldKTtcblx0XHRcdH1cblx0XHR9XG5cdH0gZWxzZSB7XG5cdFx0Ly8gaW4gUmhpbm8gb3IgYSB3ZWIgYnJvd3NlclxuXHRcdHJvb3QucHVueWNvZGUgPSBwdW55Y29kZTtcblx0fVxuXG59KHRoaXMpKTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHJlcGxhY2UgPSBTdHJpbmcucHJvdG90eXBlLnJlcGxhY2U7XG52YXIgcGVyY2VudFR3ZW50aWVzID0gLyUyMC9nO1xuXG52YXIgRm9ybWF0ID0ge1xuICAgIFJGQzE3Mzg6ICdSRkMxNzM4JyxcbiAgICBSRkMzOTg2OiAnUkZDMzk4Nidcbn07XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICAgICdkZWZhdWx0JzogRm9ybWF0LlJGQzM5ODYsXG4gICAgZm9ybWF0dGVyczoge1xuICAgICAgICBSRkMxNzM4OiBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICAgIHJldHVybiByZXBsYWNlLmNhbGwodmFsdWUsIHBlcmNlbnRUd2VudGllcywgJysnKTtcbiAgICAgICAgfSxcbiAgICAgICAgUkZDMzk4NjogZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgICAgICByZXR1cm4gU3RyaW5nKHZhbHVlKTtcbiAgICAgICAgfVxuICAgIH0sXG4gICAgUkZDMTczODogRm9ybWF0LlJGQzE3MzgsXG4gICAgUkZDMzk4NjogRm9ybWF0LlJGQzM5ODZcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBzdHJpbmdpZnkgPSByZXF1aXJlKCcuL3N0cmluZ2lmeScpO1xudmFyIHBhcnNlID0gcmVxdWlyZSgnLi9wYXJzZScpO1xudmFyIGZvcm1hdHMgPSByZXF1aXJlKCcuL2Zvcm1hdHMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gICAgZm9ybWF0czogZm9ybWF0cyxcbiAgICBwYXJzZTogcGFyc2UsXG4gICAgc3RyaW5naWZ5OiBzdHJpbmdpZnlcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4vdXRpbHMnKTtcblxudmFyIGhhcyA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG52YXIgaXNBcnJheSA9IEFycmF5LmlzQXJyYXk7XG5cbnZhciBkZWZhdWx0cyA9IHtcbiAgICBhbGxvd0RvdHM6IGZhbHNlLFxuICAgIGFsbG93RW1wdHlBcnJheXM6IGZhbHNlLFxuICAgIGFsbG93UHJvdG90eXBlczogZmFsc2UsXG4gICAgYWxsb3dTcGFyc2U6IGZhbHNlLFxuICAgIGFycmF5TGltaXQ6IDIwLFxuICAgIGNoYXJzZXQ6ICd1dGYtOCcsXG4gICAgY2hhcnNldFNlbnRpbmVsOiBmYWxzZSxcbiAgICBjb21tYTogZmFsc2UsXG4gICAgZGVjb2RlRG90SW5LZXlzOiBmYWxzZSxcbiAgICBkZWNvZGVyOiB1dGlscy5kZWNvZGUsXG4gICAgZGVsaW1pdGVyOiAnJicsXG4gICAgZGVwdGg6IDUsXG4gICAgZHVwbGljYXRlczogJ2NvbWJpbmUnLFxuICAgIGlnbm9yZVF1ZXJ5UHJlZml4OiBmYWxzZSxcbiAgICBpbnRlcnByZXROdW1lcmljRW50aXRpZXM6IGZhbHNlLFxuICAgIHBhcmFtZXRlckxpbWl0OiAxMDAwLFxuICAgIHBhcnNlQXJyYXlzOiB0cnVlLFxuICAgIHBsYWluT2JqZWN0czogZmFsc2UsXG4gICAgc3RyaWN0RGVwdGg6IGZhbHNlLFxuICAgIHN0cmljdE1lcmdlOiB0cnVlLFxuICAgIHN0cmljdE51bGxIYW5kbGluZzogZmFsc2UsXG4gICAgdGhyb3dPbkxpbWl0RXhjZWVkZWQ6IGZhbHNlXG59O1xuXG52YXIgaW50ZXJwcmV0TnVtZXJpY0VudGl0aWVzID0gZnVuY3Rpb24gKHN0cikge1xuICAgIHJldHVybiBzdHIucmVwbGFjZSgvJiMoXFxkKyk7L2csIGZ1bmN0aW9uICgkMCwgbnVtYmVyU3RyKSB7XG4gICAgICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKHBhcnNlSW50KG51bWJlclN0ciwgMTApKTtcbiAgICB9KTtcbn07XG5cbnZhciBwYXJzZUFycmF5VmFsdWUgPSBmdW5jdGlvbiAodmFsLCBvcHRpb25zLCBjdXJyZW50QXJyYXlMZW5ndGgpIHtcbiAgICBpZiAodmFsICYmIHR5cGVvZiB2YWwgPT09ICdzdHJpbmcnICYmIG9wdGlvbnMuY29tbWEgJiYgdmFsLmluZGV4T2YoJywnKSA+IC0xKSB7XG4gICAgICAgIHJldHVybiB2YWwuc3BsaXQoJywnKTtcbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucy50aHJvd09uTGltaXRFeGNlZWRlZCAmJiBjdXJyZW50QXJyYXlMZW5ndGggPj0gb3B0aW9ucy5hcnJheUxpbWl0KSB7XG4gICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdBcnJheSBsaW1pdCBleGNlZWRlZC4gT25seSAnICsgb3B0aW9ucy5hcnJheUxpbWl0ICsgJyBlbGVtZW50JyArIChvcHRpb25zLmFycmF5TGltaXQgPT09IDEgPyAnJyA6ICdzJykgKyAnIGFsbG93ZWQgaW4gYW4gYXJyYXkuJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbDtcbn07XG5cbi8vIFRoaXMgaXMgd2hhdCBicm93c2VycyB3aWxsIHN1Ym1pdCB3aGVuIHRoZSDinJMgY2hhcmFjdGVyIG9jY3VycyBpbiBhblxuLy8gYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkIGJvZHkgYW5kIHRoZSBlbmNvZGluZyBvZiB0aGUgcGFnZSBjb250YWluaW5nXG4vLyB0aGUgZm9ybSBpcyBpc28tODg1OS0xLCBvciB3aGVuIHRoZSBzdWJtaXR0ZWQgZm9ybSBoYXMgYW4gYWNjZXB0LWNoYXJzZXRcbi8vIGF0dHJpYnV0ZSBvZiBpc28tODg1OS0xLiBQcmVzdW1hYmx5IGFsc28gd2l0aCBvdGhlciBjaGFyc2V0cyB0aGF0IGRvIG5vdCBjb250YWluXG4vLyB0aGUg4pyTIGNoYXJhY3Rlciwgc3VjaCBhcyB1cy1hc2NpaS5cbnZhciBpc29TZW50aW5lbCA9ICd1dGY4PSUyNiUyMzEwMDAzJTNCJzsgLy8gZW5jb2RlVVJJQ29tcG9uZW50KCcmIzEwMDAzOycpXG5cbi8vIFRoZXNlIGFyZSB0aGUgcGVyY2VudC1lbmNvZGVkIHV0Zi04IG9jdGV0cyByZXByZXNlbnRpbmcgYSBjaGVja21hcmssIGluZGljYXRpbmcgdGhhdCB0aGUgcmVxdWVzdCBhY3R1YWxseSBpcyB1dGYtOCBlbmNvZGVkLlxudmFyIGNoYXJzZXRTZW50aW5lbCA9ICd1dGY4PSVFMiU5QyU5Myc7IC8vIGVuY29kZVVSSUNvbXBvbmVudCgn4pyTJylcblxudmFyIHBhcnNlVmFsdWVzID0gZnVuY3Rpb24gcGFyc2VRdWVyeVN0cmluZ1ZhbHVlcyhzdHIsIG9wdGlvbnMpIHtcbiAgICB2YXIgb2JqID0geyBfX3Byb3RvX186IG51bGwgfTtcblxuICAgIHZhciBjbGVhblN0ciA9IG9wdGlvbnMuaWdub3JlUXVlcnlQcmVmaXggPyBzdHIucmVwbGFjZSgvXlxcPy8sICcnKSA6IHN0cjtcbiAgICBjbGVhblN0ciA9IGNsZWFuU3RyLnJlcGxhY2UoLyU1Qi9naSwgJ1snKS5yZXBsYWNlKC8lNUQvZ2ksICddJyk7XG5cbiAgICB2YXIgbGltaXQgPSBvcHRpb25zLnBhcmFtZXRlckxpbWl0ID09PSBJbmZpbml0eSA/IHZvaWQgdW5kZWZpbmVkIDogb3B0aW9ucy5wYXJhbWV0ZXJMaW1pdDtcbiAgICB2YXIgcGFydHMgPSBjbGVhblN0ci5zcGxpdChcbiAgICAgICAgb3B0aW9ucy5kZWxpbWl0ZXIsXG4gICAgICAgIG9wdGlvbnMudGhyb3dPbkxpbWl0RXhjZWVkZWQgJiYgdHlwZW9mIGxpbWl0ICE9PSAndW5kZWZpbmVkJyA/IGxpbWl0ICsgMSA6IGxpbWl0XG4gICAgKTtcblxuICAgIGlmIChvcHRpb25zLnRocm93T25MaW1pdEV4Y2VlZGVkICYmIHR5cGVvZiBsaW1pdCAhPT0gJ3VuZGVmaW5lZCcgJiYgcGFydHMubGVuZ3RoID4gbGltaXQpIHtcbiAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1BhcmFtZXRlciBsaW1pdCBleGNlZWRlZC4gT25seSAnICsgbGltaXQgKyAnIHBhcmFtZXRlcicgKyAobGltaXQgPT09IDEgPyAnJyA6ICdzJykgKyAnIGFsbG93ZWQuJyk7XG4gICAgfVxuXG4gICAgdmFyIHNraXBJbmRleCA9IC0xOyAvLyBLZWVwIHRyYWNrIG9mIHdoZXJlIHRoZSB1dGY4IHNlbnRpbmVsIHdhcyBmb3VuZFxuICAgIHZhciBpO1xuXG4gICAgdmFyIGNoYXJzZXQgPSBvcHRpb25zLmNoYXJzZXQ7XG4gICAgaWYgKG9wdGlvbnMuY2hhcnNldFNlbnRpbmVsKSB7XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBwYXJ0cy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgaWYgKHBhcnRzW2ldLmluZGV4T2YoJ3V0Zjg9JykgPT09IDApIHtcbiAgICAgICAgICAgICAgICBpZiAocGFydHNbaV0gPT09IGNoYXJzZXRTZW50aW5lbCkge1xuICAgICAgICAgICAgICAgICAgICBjaGFyc2V0ID0gJ3V0Zi04JztcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHBhcnRzW2ldID09PSBpc29TZW50aW5lbCkge1xuICAgICAgICAgICAgICAgICAgICBjaGFyc2V0ID0gJ2lzby04ODU5LTEnO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBza2lwSW5kZXggPSBpO1xuICAgICAgICAgICAgICAgIGkgPSBwYXJ0cy5sZW5ndGg7IC8vIFRoZSBlc2xpbnQgc2V0dGluZ3MgZG8gbm90IGFsbG93IGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZm9yIChpID0gMDsgaSA8IHBhcnRzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIGlmIChpID09PSBza2lwSW5kZXgpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIHZhciBwYXJ0ID0gcGFydHNbaV07XG5cbiAgICAgICAgdmFyIGJyYWNrZXRFcXVhbHNQb3MgPSBwYXJ0LmluZGV4T2YoJ109Jyk7XG4gICAgICAgIHZhciBwb3MgPSBicmFja2V0RXF1YWxzUG9zID09PSAtMSA/IHBhcnQuaW5kZXhPZignPScpIDogYnJhY2tldEVxdWFsc1BvcyArIDE7XG5cbiAgICAgICAgdmFyIGtleTtcbiAgICAgICAgdmFyIHZhbDtcbiAgICAgICAgaWYgKHBvcyA9PT0gLTEpIHtcbiAgICAgICAgICAgIGtleSA9IG9wdGlvbnMuZGVjb2RlcihwYXJ0LCBkZWZhdWx0cy5kZWNvZGVyLCBjaGFyc2V0LCAna2V5Jyk7XG4gICAgICAgICAgICB2YWwgPSBvcHRpb25zLnN0cmljdE51bGxIYW5kbGluZyA/IG51bGwgOiAnJztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGtleSA9IG9wdGlvbnMuZGVjb2RlcihwYXJ0LnNsaWNlKDAsIHBvcyksIGRlZmF1bHRzLmRlY29kZXIsIGNoYXJzZXQsICdrZXknKTtcblxuICAgICAgICAgICAgaWYgKGtleSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHZhbCA9IHV0aWxzLm1heWJlTWFwKFxuICAgICAgICAgICAgICAgICAgICBwYXJzZUFycmF5VmFsdWUoXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXJ0LnNsaWNlKHBvcyArIDEpLFxuICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGlzQXJyYXkob2JqW2tleV0pID8gb2JqW2tleV0ubGVuZ3RoIDogMFxuICAgICAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiAoZW5jb2RlZFZhbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG9wdGlvbnMuZGVjb2RlcihlbmNvZGVkVmFsLCBkZWZhdWx0cy5kZWNvZGVyLCBjaGFyc2V0LCAndmFsdWUnKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodmFsICYmIG9wdGlvbnMuaW50ZXJwcmV0TnVtZXJpY0VudGl0aWVzICYmIGNoYXJzZXQgPT09ICdpc28tODg1OS0xJykge1xuICAgICAgICAgICAgdmFsID0gaW50ZXJwcmV0TnVtZXJpY0VudGl0aWVzKFN0cmluZyh2YWwpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwYXJ0LmluZGV4T2YoJ1tdPScpID4gLTEpIHtcbiAgICAgICAgICAgIHZhbCA9IGlzQXJyYXkodmFsKSA/IFt2YWxdIDogdmFsO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG9wdGlvbnMuY29tbWEgJiYgaXNBcnJheSh2YWwpICYmIHZhbC5sZW5ndGggPiBvcHRpb25zLmFycmF5TGltaXQpIHtcbiAgICAgICAgICAgIGlmIChvcHRpb25zLnRocm93T25MaW1pdEV4Y2VlZGVkKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0FycmF5IGxpbWl0IGV4Y2VlZGVkLiBPbmx5ICcgKyBvcHRpb25zLmFycmF5TGltaXQgKyAnIGVsZW1lbnQnICsgKG9wdGlvbnMuYXJyYXlMaW1pdCA9PT0gMSA/ICcnIDogJ3MnKSArICcgYWxsb3dlZCBpbiBhbiBhcnJheS4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhbCA9IHV0aWxzLmNvbWJpbmUoW10sIHZhbCwgb3B0aW9ucy5hcnJheUxpbWl0LCBvcHRpb25zLnBsYWluT2JqZWN0cyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoa2V5ICE9PSBudWxsKSB7XG4gICAgICAgICAgICB2YXIgZXhpc3RpbmcgPSBoYXMuY2FsbChvYmosIGtleSk7XG4gICAgICAgICAgICBpZiAoZXhpc3RpbmcgJiYgKG9wdGlvbnMuZHVwbGljYXRlcyA9PT0gJ2NvbWJpbmUnIHx8IHBhcnQuaW5kZXhPZignW109JykgPiAtMSkpIHtcbiAgICAgICAgICAgICAgICBvYmpba2V5XSA9IHV0aWxzLmNvbWJpbmUoXG4gICAgICAgICAgICAgICAgICAgIG9ialtrZXldLFxuICAgICAgICAgICAgICAgICAgICB2YWwsXG4gICAgICAgICAgICAgICAgICAgIG9wdGlvbnMuYXJyYXlMaW1pdCxcbiAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5wbGFpbk9iamVjdHNcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfSBlbHNlIGlmICghZXhpc3RpbmcgfHwgb3B0aW9ucy5kdXBsaWNhdGVzID09PSAnbGFzdCcpIHtcbiAgICAgICAgICAgICAgICBvYmpba2V5XSA9IHZhbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBvYmo7XG59O1xuXG52YXIgcGFyc2VPYmplY3QgPSBmdW5jdGlvbiAoY2hhaW4sIHZhbCwgb3B0aW9ucywgdmFsdWVzUGFyc2VkKSB7XG4gICAgdmFyIGN1cnJlbnRBcnJheUxlbmd0aCA9IDA7XG4gICAgaWYgKGNoYWluLmxlbmd0aCA+IDAgJiYgY2hhaW5bY2hhaW4ubGVuZ3RoIC0gMV0gPT09ICdbXScpIHtcbiAgICAgICAgdmFyIHBhcmVudEtleSA9IGNoYWluLnNsaWNlKDAsIC0xKS5qb2luKCcnKTtcbiAgICAgICAgY3VycmVudEFycmF5TGVuZ3RoID0gQXJyYXkuaXNBcnJheSh2YWwpICYmIHZhbFtwYXJlbnRLZXldID8gdmFsW3BhcmVudEtleV0ubGVuZ3RoIDogMDtcbiAgICB9XG5cbiAgICB2YXIgbGVhZiA9IHZhbHVlc1BhcnNlZCA/IHZhbCA6IHBhcnNlQXJyYXlWYWx1ZSh2YWwsIG9wdGlvbnMsIGN1cnJlbnRBcnJheUxlbmd0aCk7XG5cbiAgICBmb3IgKHZhciBpID0gY2hhaW4ubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgICAgdmFyIG9iajtcbiAgICAgICAgdmFyIHJvb3QgPSBjaGFpbltpXTtcblxuICAgICAgICBpZiAocm9vdCA9PT0gJ1tdJyAmJiBvcHRpb25zLnBhcnNlQXJyYXlzKSB7XG4gICAgICAgICAgICBpZiAodXRpbHMuaXNPdmVyZmxvdyhsZWFmKSkge1xuICAgICAgICAgICAgICAgIC8vIGxlYWYgaXMgYWxyZWFkeSBhbiBvdmVyZmxvdyBvYmplY3QsIHByZXNlcnZlIGl0XG4gICAgICAgICAgICAgICAgb2JqID0gbGVhZjtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgb2JqID0gb3B0aW9ucy5hbGxvd0VtcHR5QXJyYXlzICYmIChsZWFmID09PSAnJyB8fCAob3B0aW9ucy5zdHJpY3ROdWxsSGFuZGxpbmcgJiYgbGVhZiA9PT0gbnVsbCkpXG4gICAgICAgICAgICAgICAgICAgID8gW11cbiAgICAgICAgICAgICAgICAgICAgOiB1dGlscy5jb21iaW5lKFxuICAgICAgICAgICAgICAgICAgICAgICAgW10sXG4gICAgICAgICAgICAgICAgICAgICAgICBsZWFmLFxuICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5hcnJheUxpbWl0LFxuICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5wbGFpbk9iamVjdHNcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG9iaiA9IG9wdGlvbnMucGxhaW5PYmplY3RzID8geyBfX3Byb3RvX186IG51bGwgfSA6IHt9O1xuICAgICAgICAgICAgdmFyIGNsZWFuUm9vdCA9IHJvb3QuY2hhckF0KDApID09PSAnWycgJiYgcm9vdC5jaGFyQXQocm9vdC5sZW5ndGggLSAxKSA9PT0gJ10nID8gcm9vdC5zbGljZSgxLCAtMSkgOiByb290O1xuICAgICAgICAgICAgdmFyIGRlY29kZWRSb290ID0gb3B0aW9ucy5kZWNvZGVEb3RJbktleXMgPyBjbGVhblJvb3QucmVwbGFjZSgvJTJFL2csICcuJykgOiBjbGVhblJvb3Q7XG4gICAgICAgICAgICB2YXIgaW5kZXggPSBwYXJzZUludChkZWNvZGVkUm9vdCwgMTApO1xuICAgICAgICAgICAgdmFyIGlzVmFsaWRBcnJheUluZGV4ID0gIWlzTmFOKGluZGV4KVxuICAgICAgICAgICAgICAgICYmIHJvb3QgIT09IGRlY29kZWRSb290XG4gICAgICAgICAgICAgICAgJiYgU3RyaW5nKGluZGV4KSA9PT0gZGVjb2RlZFJvb3RcbiAgICAgICAgICAgICAgICAmJiBpbmRleCA+PSAwXG4gICAgICAgICAgICAgICAgJiYgb3B0aW9ucy5wYXJzZUFycmF5cztcbiAgICAgICAgICAgIGlmICghb3B0aW9ucy5wYXJzZUFycmF5cyAmJiBkZWNvZGVkUm9vdCA9PT0gJycpIHtcbiAgICAgICAgICAgICAgICBvYmogPSB7IDA6IGxlYWYgfTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNWYWxpZEFycmF5SW5kZXggJiYgaW5kZXggPCBvcHRpb25zLmFycmF5TGltaXQpIHtcbiAgICAgICAgICAgICAgICBvYmogPSBbXTtcbiAgICAgICAgICAgICAgICBvYmpbaW5kZXhdID0gbGVhZjtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNWYWxpZEFycmF5SW5kZXggJiYgb3B0aW9ucy50aHJvd09uTGltaXRFeGNlZWRlZCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdBcnJheSBsaW1pdCBleGNlZWRlZC4gT25seSAnICsgb3B0aW9ucy5hcnJheUxpbWl0ICsgJyBlbGVtZW50JyArIChvcHRpb25zLmFycmF5TGltaXQgPT09IDEgPyAnJyA6ICdzJykgKyAnIGFsbG93ZWQgaW4gYW4gYXJyYXkuJyk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGlzVmFsaWRBcnJheUluZGV4KSB7XG4gICAgICAgICAgICAgICAgb2JqW2luZGV4XSA9IGxlYWY7XG4gICAgICAgICAgICAgICAgdXRpbHMubWFya092ZXJmbG93KG9iaiwgaW5kZXgpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChkZWNvZGVkUm9vdCAhPT0gJ19fcHJvdG9fXycpIHtcbiAgICAgICAgICAgICAgICBvYmpbZGVjb2RlZFJvb3RdID0gbGVhZjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGxlYWYgPSBvYmo7XG4gICAgfVxuXG4gICAgcmV0dXJuIGxlYWY7XG59O1xuXG4vLyBTcGxpdCBhIGtleSBsaWtlIFwiYVtiXVtjW11dXCIgaW50byBbJ2EnLCAnW2JdJywgJ1tjW11dJ10gd2hpbGUgcHJlc2VydmluZ1xuLy8gcXMgcGFyc2Ugc2VtYW50aWNzIGZvciBkZXB0aC9wcm90b3R5cGUgZ3VhcmRzLlxudmFyIHNwbGl0S2V5SW50b1NlZ21lbnRzID0gZnVuY3Rpb24gc3BsaXRLZXlJbnRvU2VnbWVudHMob3JpZ2luYWxLZXksIG9wdGlvbnMpIHtcbiAgICB2YXIga2V5ID0gb3B0aW9ucy5hbGxvd0RvdHMgPyBvcmlnaW5hbEtleS5yZXBsYWNlKC9cXC4oW14uW10rKS9nLCAnWyQxXScpIDogb3JpZ2luYWxLZXk7XG5cbiAgICAvLyBkZXB0aCA8PSAwIGtlZXBzIHRoZSB3aG9sZSBrZXkgYXMgb25lIHNlZ21lbnRcbiAgICBpZiAob3B0aW9ucy5kZXB0aCA8PSAwKSB7XG4gICAgICAgIGlmICghb3B0aW9ucy5wbGFpbk9iamVjdHMgJiYgaGFzLmNhbGwoT2JqZWN0LnByb3RvdHlwZSwga2V5KSkge1xuICAgICAgICAgICAgaWYgKCFvcHRpb25zLmFsbG93UHJvdG90eXBlcykge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBba2V5XTtcbiAgICB9XG5cbiAgICB2YXIgc2VnbWVudHMgPSBbXTtcblxuICAgIC8vIHBhcmVudCBiZWZvcmUgdGhlIGZpcnN0ICdbJyAobWF5IGJlIGVtcHR5IGlmIGtleSBzdGFydHMgd2l0aCAnWycpXG4gICAgdmFyIGZpcnN0ID0ga2V5LmluZGV4T2YoJ1snKTtcbiAgICB2YXIgcGFyZW50ID0gZmlyc3QgPj0gMCA/IGtleS5zbGljZSgwLCBmaXJzdCkgOiBrZXk7XG4gICAgaWYgKHBhcmVudCkge1xuICAgICAgICBpZiAoIW9wdGlvbnMucGxhaW5PYmplY3RzICYmIGhhcy5jYWxsKE9iamVjdC5wcm90b3R5cGUsIHBhcmVudCkpIHtcbiAgICAgICAgICAgIGlmICghb3B0aW9ucy5hbGxvd1Byb3RvdHlwZXMpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBzZWdtZW50c1tzZWdtZW50cy5sZW5ndGhdID0gcGFyZW50O1xuICAgIH1cblxuICAgIHZhciBuID0ga2V5Lmxlbmd0aDtcbiAgICB2YXIgb3BlbiA9IGZpcnN0O1xuICAgIHZhciBjb2xsZWN0ZWQgPSAwO1xuXG4gICAgd2hpbGUgKG9wZW4gPj0gMCAmJiBjb2xsZWN0ZWQgPCBvcHRpb25zLmRlcHRoKSB7XG4gICAgICAgIHZhciBsZXZlbCA9IDE7XG4gICAgICAgIHZhciBpID0gb3BlbiArIDE7XG4gICAgICAgIHZhciBjbG9zZSA9IC0xO1xuXG4gICAgICAgIC8vIGJhbGFuY2UgbmVzdGVkICdbJyBhbmQgJ10nIGluc2lkZSB0aGlzIGJyYWNrZXQgZ3JvdXAgdXNpbmcgYSBuZXN0aW5nIGxldmVsIGNvdW50ZXJcbiAgICAgICAgd2hpbGUgKGkgPCBuICYmIGNsb3NlIDwgMCkge1xuICAgICAgICAgICAgdmFyIGN1ID0ga2V5LmNoYXJDb2RlQXQoaSk7XG4gICAgICAgICAgICBpZiAoY3UgPT09IDB4NUIpIHsgLy8gJ1snXG4gICAgICAgICAgICAgICAgbGV2ZWwgKz0gMTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoY3UgPT09IDB4NUQpIHsgLy8gJ10nXG4gICAgICAgICAgICAgICAgbGV2ZWwgLT0gMTtcbiAgICAgICAgICAgICAgICBpZiAobGV2ZWwgPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgY2xvc2UgPSBpOyAvLyBmb3VuZCBtYXRjaGluZyBjbG9zZTsgbG9vcCB3aWxsIGV4aXQgYnkgY29uZGl0aW9uXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaSArPSAxO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGNsb3NlIDwgMCkge1xuICAgICAgICAgICAgLy8gVW50ZXJtaW5hdGVkIGdyb3VwOiB3cmFwIHRoZSByYXcgcmVtYWluZGVyIGluIG9uZSBicmFja2V0IHBhaXIgc28gaXQgc3RheXNcbiAgICAgICAgICAgIC8vIGEgc2luZ2xlIGxpdGVyYWwgc2VnbWVudCAoZS5nLiBcIltbXWJcIiAtPiBcIltbXWJdXCIpOyB3ZSBkbyBub3QgaW5mZXIgbWlzc2luZyAnXScuXG4gICAgICAgICAgICBzZWdtZW50c1tzZWdtZW50cy5sZW5ndGhdID0gJ1snICsga2V5LnNsaWNlKG9wZW4pICsgJ10nO1xuICAgICAgICAgICAgcmV0dXJuIHNlZ21lbnRzO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHNlZyA9IGtleS5zbGljZShvcGVuLCBjbG9zZSArIDEpO1xuICAgICAgICAvLyBwcm90b3R5cGUgZ3VhcmQgZm9yIHRoZSBjb250ZW50IG9mIHRoaXMgZ3JvdXBcbiAgICAgICAgdmFyIGNvbnRlbnQgPSBzZWcuc2xpY2UoMSwgLTEpO1xuICAgICAgICBpZiAoIW9wdGlvbnMucGxhaW5PYmplY3RzICYmIGhhcy5jYWxsKE9iamVjdC5wcm90b3R5cGUsIGNvbnRlbnQpICYmICFvcHRpb25zLmFsbG93UHJvdG90eXBlcykge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgc2VnbWVudHNbc2VnbWVudHMubGVuZ3RoXSA9IHNlZztcbiAgICAgICAgY29sbGVjdGVkICs9IDE7XG5cbiAgICAgICAgLy8gZmluZCB0aGUgbmV4dCAnWycgYWZ0ZXIgdGhpcyBiYWxhbmNlZCBncm91cFxuICAgICAgICBvcGVuID0ga2V5LmluZGV4T2YoJ1snLCBjbG9zZSArIDEpO1xuICAgIH1cblxuICAgIGlmIChvcGVuID49IDApIHtcbiAgICAgICAgaWYgKG9wdGlvbnMuc3RyaWN0RGVwdGggPT09IHRydWUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdJbnB1dCBkZXB0aCBleGNlZWRlZCBkZXB0aCBvcHRpb24gb2YgJyArIG9wdGlvbnMuZGVwdGggKyAnIGFuZCBzdHJpY3REZXB0aCBpcyB0cnVlJyk7XG4gICAgICAgIH1cblxuICAgICAgICBzZWdtZW50c1tzZWdtZW50cy5sZW5ndGhdID0gJ1snICsga2V5LnNsaWNlKG9wZW4pICsgJ10nO1xuICAgIH1cblxuICAgIHJldHVybiBzZWdtZW50cztcbn07XG5cbnZhciBwYXJzZUtleXMgPSBmdW5jdGlvbiBwYXJzZVF1ZXJ5U3RyaW5nS2V5cyhnaXZlbktleSwgdmFsLCBvcHRpb25zLCB2YWx1ZXNQYXJzZWQpIHtcbiAgICBpZiAoIWdpdmVuS2V5KSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIga2V5cyA9IHNwbGl0S2V5SW50b1NlZ21lbnRzKGdpdmVuS2V5LCBvcHRpb25zKTtcblxuICAgIGlmICgha2V5cykge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgcmV0dXJuIHBhcnNlT2JqZWN0KGtleXMsIHZhbCwgb3B0aW9ucywgdmFsdWVzUGFyc2VkKTtcbn07XG5cbnZhciBub3JtYWxpemVQYXJzZU9wdGlvbnMgPSBmdW5jdGlvbiBub3JtYWxpemVQYXJzZU9wdGlvbnMob3B0cykge1xuICAgIGlmICghb3B0cykge1xuICAgICAgICByZXR1cm4gZGVmYXVsdHM7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBvcHRzLmFsbG93RW1wdHlBcnJheXMgIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiBvcHRzLmFsbG93RW1wdHlBcnJheXMgIT09ICdib29sZWFuJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdgYWxsb3dFbXB0eUFycmF5c2Agb3B0aW9uIGNhbiBvbmx5IGJlIGB0cnVlYCBvciBgZmFsc2VgLCB3aGVuIHByb3ZpZGVkJyk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBvcHRzLmRlY29kZURvdEluS2V5cyAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIG9wdHMuZGVjb2RlRG90SW5LZXlzICE9PSAnYm9vbGVhbicpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignYGRlY29kZURvdEluS2V5c2Agb3B0aW9uIGNhbiBvbmx5IGJlIGB0cnVlYCBvciBgZmFsc2VgLCB3aGVuIHByb3ZpZGVkJyk7XG4gICAgfVxuXG4gICAgaWYgKG9wdHMuZGVjb2RlciAhPT0gbnVsbCAmJiB0eXBlb2Ygb3B0cy5kZWNvZGVyICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2Ygb3B0cy5kZWNvZGVyICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0RlY29kZXIgaGFzIHRvIGJlIGEgZnVuY3Rpb24uJyk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBvcHRzLmNoYXJzZXQgIT09ICd1bmRlZmluZWQnICYmIG9wdHMuY2hhcnNldCAhPT0gJ3V0Zi04JyAmJiBvcHRzLmNoYXJzZXQgIT09ICdpc28tODg1OS0xJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgY2hhcnNldCBvcHRpb24gbXVzdCBiZSBlaXRoZXIgdXRmLTgsIGlzby04ODU5LTEsIG9yIHVuZGVmaW5lZCcpO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2Ygb3B0cy50aHJvd09uTGltaXRFeGNlZWRlZCAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIG9wdHMudGhyb3dPbkxpbWl0RXhjZWVkZWQgIT09ICdib29sZWFuJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdgdGhyb3dPbkxpbWl0RXhjZWVkZWRgIG9wdGlvbiBtdXN0IGJlIGEgYm9vbGVhbicpO1xuICAgIH1cblxuICAgIHZhciBjaGFyc2V0ID0gdHlwZW9mIG9wdHMuY2hhcnNldCA9PT0gJ3VuZGVmaW5lZCcgPyBkZWZhdWx0cy5jaGFyc2V0IDogb3B0cy5jaGFyc2V0O1xuXG4gICAgdmFyIGR1cGxpY2F0ZXMgPSB0eXBlb2Ygb3B0cy5kdXBsaWNhdGVzID09PSAndW5kZWZpbmVkJyA/IGRlZmF1bHRzLmR1cGxpY2F0ZXMgOiBvcHRzLmR1cGxpY2F0ZXM7XG5cbiAgICBpZiAoZHVwbGljYXRlcyAhPT0gJ2NvbWJpbmUnICYmIGR1cGxpY2F0ZXMgIT09ICdmaXJzdCcgJiYgZHVwbGljYXRlcyAhPT0gJ2xhc3QnKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBkdXBsaWNhdGVzIG9wdGlvbiBtdXN0IGJlIGVpdGhlciBjb21iaW5lLCBmaXJzdCwgb3IgbGFzdCcpO1xuICAgIH1cblxuICAgIHZhciBhbGxvd0RvdHMgPSB0eXBlb2Ygb3B0cy5hbGxvd0RvdHMgPT09ICd1bmRlZmluZWQnID8gb3B0cy5kZWNvZGVEb3RJbktleXMgPT09IHRydWUgPyB0cnVlIDogZGVmYXVsdHMuYWxsb3dEb3RzIDogISFvcHRzLmFsbG93RG90cztcblxuICAgIHJldHVybiB7XG4gICAgICAgIGFsbG93RG90czogYWxsb3dEb3RzLFxuICAgICAgICBhbGxvd0VtcHR5QXJyYXlzOiB0eXBlb2Ygb3B0cy5hbGxvd0VtcHR5QXJyYXlzID09PSAnYm9vbGVhbicgPyAhIW9wdHMuYWxsb3dFbXB0eUFycmF5cyA6IGRlZmF1bHRzLmFsbG93RW1wdHlBcnJheXMsXG4gICAgICAgIGFsbG93UHJvdG90eXBlczogdHlwZW9mIG9wdHMuYWxsb3dQcm90b3R5cGVzID09PSAnYm9vbGVhbicgPyBvcHRzLmFsbG93UHJvdG90eXBlcyA6IGRlZmF1bHRzLmFsbG93UHJvdG90eXBlcyxcbiAgICAgICAgYWxsb3dTcGFyc2U6IHR5cGVvZiBvcHRzLmFsbG93U3BhcnNlID09PSAnYm9vbGVhbicgPyBvcHRzLmFsbG93U3BhcnNlIDogZGVmYXVsdHMuYWxsb3dTcGFyc2UsXG4gICAgICAgIGFycmF5TGltaXQ6IHR5cGVvZiBvcHRzLmFycmF5TGltaXQgPT09ICdudW1iZXInID8gb3B0cy5hcnJheUxpbWl0IDogZGVmYXVsdHMuYXJyYXlMaW1pdCxcbiAgICAgICAgY2hhcnNldDogY2hhcnNldCxcbiAgICAgICAgY2hhcnNldFNlbnRpbmVsOiB0eXBlb2Ygb3B0cy5jaGFyc2V0U2VudGluZWwgPT09ICdib29sZWFuJyA/IG9wdHMuY2hhcnNldFNlbnRpbmVsIDogZGVmYXVsdHMuY2hhcnNldFNlbnRpbmVsLFxuICAgICAgICBjb21tYTogdHlwZW9mIG9wdHMuY29tbWEgPT09ICdib29sZWFuJyA/IG9wdHMuY29tbWEgOiBkZWZhdWx0cy5jb21tYSxcbiAgICAgICAgZGVjb2RlRG90SW5LZXlzOiB0eXBlb2Ygb3B0cy5kZWNvZGVEb3RJbktleXMgPT09ICdib29sZWFuJyA/IG9wdHMuZGVjb2RlRG90SW5LZXlzIDogZGVmYXVsdHMuZGVjb2RlRG90SW5LZXlzLFxuICAgICAgICBkZWNvZGVyOiB0eXBlb2Ygb3B0cy5kZWNvZGVyID09PSAnZnVuY3Rpb24nID8gb3B0cy5kZWNvZGVyIDogZGVmYXVsdHMuZGVjb2RlcixcbiAgICAgICAgZGVsaW1pdGVyOiB0eXBlb2Ygb3B0cy5kZWxpbWl0ZXIgPT09ICdzdHJpbmcnIHx8IHV0aWxzLmlzUmVnRXhwKG9wdHMuZGVsaW1pdGVyKSA/IG9wdHMuZGVsaW1pdGVyIDogZGVmYXVsdHMuZGVsaW1pdGVyLFxuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8taW1wbGljaXQtY29lcmNpb24sIG5vLWV4dHJhLXBhcmVuc1xuICAgICAgICBkZXB0aDogKHR5cGVvZiBvcHRzLmRlcHRoID09PSAnbnVtYmVyJyB8fCBvcHRzLmRlcHRoID09PSBmYWxzZSkgPyArb3B0cy5kZXB0aCA6IGRlZmF1bHRzLmRlcHRoLFxuICAgICAgICBkdXBsaWNhdGVzOiBkdXBsaWNhdGVzLFxuICAgICAgICBpZ25vcmVRdWVyeVByZWZpeDogb3B0cy5pZ25vcmVRdWVyeVByZWZpeCA9PT0gdHJ1ZSxcbiAgICAgICAgaW50ZXJwcmV0TnVtZXJpY0VudGl0aWVzOiB0eXBlb2Ygb3B0cy5pbnRlcnByZXROdW1lcmljRW50aXRpZXMgPT09ICdib29sZWFuJyA/IG9wdHMuaW50ZXJwcmV0TnVtZXJpY0VudGl0aWVzIDogZGVmYXVsdHMuaW50ZXJwcmV0TnVtZXJpY0VudGl0aWVzLFxuICAgICAgICBwYXJhbWV0ZXJMaW1pdDogdHlwZW9mIG9wdHMucGFyYW1ldGVyTGltaXQgPT09ICdudW1iZXInID8gb3B0cy5wYXJhbWV0ZXJMaW1pdCA6IGRlZmF1bHRzLnBhcmFtZXRlckxpbWl0LFxuICAgICAgICBwYXJzZUFycmF5czogb3B0cy5wYXJzZUFycmF5cyAhPT0gZmFsc2UsXG4gICAgICAgIHBsYWluT2JqZWN0czogdHlwZW9mIG9wdHMucGxhaW5PYmplY3RzID09PSAnYm9vbGVhbicgPyBvcHRzLnBsYWluT2JqZWN0cyA6IGRlZmF1bHRzLnBsYWluT2JqZWN0cyxcbiAgICAgICAgc3RyaWN0RGVwdGg6IHR5cGVvZiBvcHRzLnN0cmljdERlcHRoID09PSAnYm9vbGVhbicgPyAhIW9wdHMuc3RyaWN0RGVwdGggOiBkZWZhdWx0cy5zdHJpY3REZXB0aCxcbiAgICAgICAgc3RyaWN0TWVyZ2U6IHR5cGVvZiBvcHRzLnN0cmljdE1lcmdlID09PSAnYm9vbGVhbicgPyAhIW9wdHMuc3RyaWN0TWVyZ2UgOiBkZWZhdWx0cy5zdHJpY3RNZXJnZSxcbiAgICAgICAgc3RyaWN0TnVsbEhhbmRsaW5nOiB0eXBlb2Ygb3B0cy5zdHJpY3ROdWxsSGFuZGxpbmcgPT09ICdib29sZWFuJyA/IG9wdHMuc3RyaWN0TnVsbEhhbmRsaW5nIDogZGVmYXVsdHMuc3RyaWN0TnVsbEhhbmRsaW5nLFxuICAgICAgICB0aHJvd09uTGltaXRFeGNlZWRlZDogdHlwZW9mIG9wdHMudGhyb3dPbkxpbWl0RXhjZWVkZWQgPT09ICdib29sZWFuJyA/IG9wdHMudGhyb3dPbkxpbWl0RXhjZWVkZWQgOiBmYWxzZVxuICAgIH07XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChzdHIsIG9wdHMpIHtcbiAgICB2YXIgb3B0aW9ucyA9IG5vcm1hbGl6ZVBhcnNlT3B0aW9ucyhvcHRzKTtcblxuICAgIGlmIChzdHIgPT09ICcnIHx8IHN0ciA9PT0gbnVsbCB8fCB0eXBlb2Ygc3RyID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICByZXR1cm4gb3B0aW9ucy5wbGFpbk9iamVjdHMgPyB7IF9fcHJvdG9fXzogbnVsbCB9IDoge307XG4gICAgfVxuXG4gICAgdmFyIHRlbXBPYmogPSB0eXBlb2Ygc3RyID09PSAnc3RyaW5nJyA/IHBhcnNlVmFsdWVzKHN0ciwgb3B0aW9ucykgOiBzdHI7XG4gICAgdmFyIG9iaiA9IG9wdGlvbnMucGxhaW5PYmplY3RzID8geyBfX3Byb3RvX186IG51bGwgfSA6IHt9O1xuXG4gICAgLy8gSXRlcmF0ZSBvdmVyIHRoZSBrZXlzIGFuZCBzZXR1cCB0aGUgbmV3IG9iamVjdFxuXG4gICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyh0ZW1wT2JqKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgdmFyIGtleSA9IGtleXNbaV07XG4gICAgICAgIHZhciBuZXdPYmogPSBwYXJzZUtleXMoa2V5LCB0ZW1wT2JqW2tleV0sIG9wdGlvbnMsIHR5cGVvZiBzdHIgPT09ICdzdHJpbmcnKTtcbiAgICAgICAgb2JqID0gdXRpbHMubWVyZ2Uob2JqLCBuZXdPYmosIG9wdGlvbnMpO1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zLmFsbG93U3BhcnNlID09PSB0cnVlKSB7XG4gICAgICAgIHJldHVybiBvYmo7XG4gICAgfVxuXG4gICAgcmV0dXJuIHV0aWxzLmNvbXBhY3Qob2JqKTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBnZXRTaWRlQ2hhbm5lbCA9IHJlcXVpcmUoJ3NpZGUtY2hhbm5lbCcpO1xudmFyIHV0aWxzID0gcmVxdWlyZSgnLi91dGlscycpO1xudmFyIGZvcm1hdHMgPSByZXF1aXJlKCcuL2Zvcm1hdHMnKTtcbnZhciBoYXMgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuXG52YXIgYXJyYXlQcmVmaXhHZW5lcmF0b3JzID0ge1xuICAgIGJyYWNrZXRzOiBmdW5jdGlvbiBicmFja2V0cyhwcmVmaXgpIHtcbiAgICAgICAgcmV0dXJuIHByZWZpeCArICdbXSc7XG4gICAgfSxcbiAgICBjb21tYTogJ2NvbW1hJyxcbiAgICBpbmRpY2VzOiBmdW5jdGlvbiBpbmRpY2VzKHByZWZpeCwga2V5KSB7XG4gICAgICAgIHJldHVybiBwcmVmaXggKyAnWycgKyBrZXkgKyAnXSc7XG4gICAgfSxcbiAgICByZXBlYXQ6IGZ1bmN0aW9uIHJlcGVhdChwcmVmaXgpIHtcbiAgICAgICAgcmV0dXJuIHByZWZpeDtcbiAgICB9XG59O1xuXG52YXIgaXNBcnJheSA9IEFycmF5LmlzQXJyYXk7XG52YXIgcHVzaCA9IEFycmF5LnByb3RvdHlwZS5wdXNoO1xudmFyIHB1c2hUb0FycmF5ID0gZnVuY3Rpb24gKGFyciwgdmFsdWVPckFycmF5KSB7XG4gICAgcHVzaC5hcHBseShhcnIsIGlzQXJyYXkodmFsdWVPckFycmF5KSA/IHZhbHVlT3JBcnJheSA6IFt2YWx1ZU9yQXJyYXldKTtcbn07XG5cbnZhciB0b0lTTyA9IERhdGUucHJvdG90eXBlLnRvSVNPU3RyaW5nO1xuXG52YXIgZGVmYXVsdEZvcm1hdCA9IGZvcm1hdHNbJ2RlZmF1bHQnXTtcbnZhciBkZWZhdWx0cyA9IHtcbiAgICBhZGRRdWVyeVByZWZpeDogZmFsc2UsXG4gICAgYWxsb3dEb3RzOiBmYWxzZSxcbiAgICBhbGxvd0VtcHR5QXJyYXlzOiBmYWxzZSxcbiAgICBhcnJheUZvcm1hdDogJ2luZGljZXMnLFxuICAgIGNoYXJzZXQ6ICd1dGYtOCcsXG4gICAgY2hhcnNldFNlbnRpbmVsOiBmYWxzZSxcbiAgICBjb21tYVJvdW5kVHJpcDogZmFsc2UsXG4gICAgZGVsaW1pdGVyOiAnJicsXG4gICAgZW5jb2RlOiB0cnVlLFxuICAgIGVuY29kZURvdEluS2V5czogZmFsc2UsXG4gICAgZW5jb2RlcjogdXRpbHMuZW5jb2RlLFxuICAgIGVuY29kZVZhbHVlc09ubHk6IGZhbHNlLFxuICAgIGZpbHRlcjogdm9pZCB1bmRlZmluZWQsXG4gICAgZm9ybWF0OiBkZWZhdWx0Rm9ybWF0LFxuICAgIGZvcm1hdHRlcjogZm9ybWF0cy5mb3JtYXR0ZXJzW2RlZmF1bHRGb3JtYXRdLFxuICAgIC8vIGRlcHJlY2F0ZWRcbiAgICBpbmRpY2VzOiBmYWxzZSxcbiAgICBzZXJpYWxpemVEYXRlOiBmdW5jdGlvbiBzZXJpYWxpemVEYXRlKGRhdGUpIHtcbiAgICAgICAgcmV0dXJuIHRvSVNPLmNhbGwoZGF0ZSk7XG4gICAgfSxcbiAgICBza2lwTnVsbHM6IGZhbHNlLFxuICAgIHN0cmljdE51bGxIYW5kbGluZzogZmFsc2Vcbn07XG5cbnZhciBpc05vbk51bGxpc2hQcmltaXRpdmUgPSBmdW5jdGlvbiBpc05vbk51bGxpc2hQcmltaXRpdmUodikge1xuICAgIHJldHVybiB0eXBlb2YgdiA9PT0gJ3N0cmluZydcbiAgICAgICAgfHwgdHlwZW9mIHYgPT09ICdudW1iZXInXG4gICAgICAgIHx8IHR5cGVvZiB2ID09PSAnYm9vbGVhbidcbiAgICAgICAgfHwgdHlwZW9mIHYgPT09ICdzeW1ib2wnXG4gICAgICAgIHx8IHR5cGVvZiB2ID09PSAnYmlnaW50Jztcbn07XG5cbnZhciBzZW50aW5lbCA9IHt9O1xuXG52YXIgc3RyaW5naWZ5ID0gZnVuY3Rpb24gc3RyaW5naWZ5KFxuICAgIG9iamVjdCxcbiAgICBwcmVmaXgsXG4gICAgZ2VuZXJhdGVBcnJheVByZWZpeCxcbiAgICBjb21tYVJvdW5kVHJpcCxcbiAgICBhbGxvd0VtcHR5QXJyYXlzLFxuICAgIHN0cmljdE51bGxIYW5kbGluZyxcbiAgICBza2lwTnVsbHMsXG4gICAgZW5jb2RlRG90SW5LZXlzLFxuICAgIGVuY29kZXIsXG4gICAgZmlsdGVyLFxuICAgIHNvcnQsXG4gICAgYWxsb3dEb3RzLFxuICAgIHNlcmlhbGl6ZURhdGUsXG4gICAgZm9ybWF0LFxuICAgIGZvcm1hdHRlcixcbiAgICBlbmNvZGVWYWx1ZXNPbmx5LFxuICAgIGNoYXJzZXQsXG4gICAgc2lkZUNoYW5uZWxcbikge1xuICAgIHZhciBvYmogPSBvYmplY3Q7XG5cbiAgICB2YXIgdG1wU2MgPSBzaWRlQ2hhbm5lbDtcbiAgICB2YXIgc3RlcCA9IDA7XG4gICAgdmFyIGZpbmRGbGFnID0gZmFsc2U7XG4gICAgd2hpbGUgKCh0bXBTYyA9IHRtcFNjLmdldChzZW50aW5lbCkpICE9PSB2b2lkIHVuZGVmaW5lZCAmJiAhZmluZEZsYWcpIHtcbiAgICAgICAgLy8gV2hlcmUgb2JqZWN0IGxhc3QgYXBwZWFyZWQgaW4gdGhlIHJlZiB0cmVlXG4gICAgICAgIHZhciBwb3MgPSB0bXBTYy5nZXQob2JqZWN0KTtcbiAgICAgICAgc3RlcCArPSAxO1xuICAgICAgICBpZiAodHlwZW9mIHBvcyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIGlmIChwb3MgPT09IHN0ZXApIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignQ3ljbGljIG9iamVjdCB2YWx1ZScpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBmaW5kRmxhZyA9IHRydWU7IC8vIEJyZWFrIHdoaWxlXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiB0bXBTYy5nZXQoc2VudGluZWwpID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgc3RlcCA9IDA7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGZpbHRlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBvYmogPSBmaWx0ZXIocHJlZml4LCBvYmopO1xuICAgIH0gZWxzZSBpZiAob2JqIGluc3RhbmNlb2YgRGF0ZSkge1xuICAgICAgICBvYmogPSBzZXJpYWxpemVEYXRlKG9iaik7XG4gICAgfSBlbHNlIGlmIChnZW5lcmF0ZUFycmF5UHJlZml4ID09PSAnY29tbWEnICYmIGlzQXJyYXkob2JqKSkge1xuICAgICAgICBvYmogPSB1dGlscy5tYXliZU1hcChvYmosIGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgRGF0ZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBzZXJpYWxpemVEYXRlKHZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKG9iaiA9PT0gbnVsbCkge1xuICAgICAgICBpZiAoc3RyaWN0TnVsbEhhbmRsaW5nKSB7XG4gICAgICAgICAgICByZXR1cm4gZm9ybWF0dGVyKGVuY29kZXIgJiYgIWVuY29kZVZhbHVlc09ubHkgPyBlbmNvZGVyKHByZWZpeCwgZGVmYXVsdHMuZW5jb2RlciwgY2hhcnNldCwgJ2tleScsIGZvcm1hdCkgOiBwcmVmaXgpO1xuICAgICAgICB9XG5cbiAgICAgICAgb2JqID0gJyc7XG4gICAgfVxuXG4gICAgaWYgKGlzTm9uTnVsbGlzaFByaW1pdGl2ZShvYmopIHx8IHV0aWxzLmlzQnVmZmVyKG9iaikpIHtcbiAgICAgICAgaWYgKGVuY29kZXIpIHtcbiAgICAgICAgICAgIHZhciBrZXlWYWx1ZSA9IGVuY29kZVZhbHVlc09ubHkgPyBwcmVmaXggOiBlbmNvZGVyKHByZWZpeCwgZGVmYXVsdHMuZW5jb2RlciwgY2hhcnNldCwgJ2tleScsIGZvcm1hdCk7XG4gICAgICAgICAgICByZXR1cm4gW2Zvcm1hdHRlcihrZXlWYWx1ZSkgKyAnPScgKyBmb3JtYXR0ZXIoZW5jb2RlcihvYmosIGRlZmF1bHRzLmVuY29kZXIsIGNoYXJzZXQsICd2YWx1ZScsIGZvcm1hdCkpXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gW2Zvcm1hdHRlcihwcmVmaXgpICsgJz0nICsgZm9ybWF0dGVyKFN0cmluZyhvYmopKV07XG4gICAgfVxuXG4gICAgdmFyIHZhbHVlcyA9IFtdO1xuXG4gICAgaWYgKHR5cGVvZiBvYmogPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZXM7XG4gICAgfVxuXG4gICAgdmFyIG9iaktleXM7XG4gICAgaWYgKGdlbmVyYXRlQXJyYXlQcmVmaXggPT09ICdjb21tYScgJiYgaXNBcnJheShvYmopKSB7XG4gICAgICAgIC8vIHdlIG5lZWQgdG8gam9pbiBlbGVtZW50cyBpblxuICAgICAgICBpZiAoZW5jb2RlVmFsdWVzT25seSAmJiBlbmNvZGVyKSB7XG4gICAgICAgICAgICBvYmogPSB1dGlscy5tYXliZU1hcChvYmosIGZ1bmN0aW9uICh2KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHYgPT0gbnVsbCA/IHYgOiBlbmNvZGVyKHYpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgb2JqS2V5cyA9IFt7IHZhbHVlOiBvYmoubGVuZ3RoID4gMCA/IG9iai5qb2luKCcsJykgfHwgbnVsbCA6IHZvaWQgdW5kZWZpbmVkIH1dO1xuICAgIH0gZWxzZSBpZiAoaXNBcnJheShmaWx0ZXIpKSB7XG4gICAgICAgIG9iaktleXMgPSBmaWx0ZXI7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhvYmopO1xuICAgICAgICBvYmpLZXlzID0gc29ydCA/IGtleXMuc29ydChzb3J0KSA6IGtleXM7XG4gICAgfVxuXG4gICAgdmFyIGVuY29kZWRQcmVmaXggPSBlbmNvZGVEb3RJbktleXMgPyBTdHJpbmcocHJlZml4KS5yZXBsYWNlKC9cXC4vZywgJyUyRScpIDogU3RyaW5nKHByZWZpeCk7XG5cbiAgICB2YXIgYWRqdXN0ZWRQcmVmaXggPSBjb21tYVJvdW5kVHJpcCAmJiBpc0FycmF5KG9iaikgJiYgb2JqLmxlbmd0aCA9PT0gMSA/IGVuY29kZWRQcmVmaXggKyAnW10nIDogZW5jb2RlZFByZWZpeDtcblxuICAgIGlmIChhbGxvd0VtcHR5QXJyYXlzICYmIGlzQXJyYXkob2JqKSAmJiBvYmoubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJldHVybiBhZGp1c3RlZFByZWZpeCArICdbXSc7XG4gICAgfVxuXG4gICAgZm9yICh2YXIgaiA9IDA7IGogPCBvYmpLZXlzLmxlbmd0aDsgKytqKSB7XG4gICAgICAgIHZhciBrZXkgPSBvYmpLZXlzW2pdO1xuICAgICAgICB2YXIgdmFsdWUgPSB0eXBlb2Yga2V5ID09PSAnb2JqZWN0JyAmJiBrZXkgJiYgdHlwZW9mIGtleS52YWx1ZSAhPT0gJ3VuZGVmaW5lZCdcbiAgICAgICAgICAgID8ga2V5LnZhbHVlXG4gICAgICAgICAgICA6IG9ialtrZXldO1xuXG4gICAgICAgIGlmIChza2lwTnVsbHMgJiYgdmFsdWUgPT09IG51bGwpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGVuY29kZWRLZXkgPSBhbGxvd0RvdHMgJiYgZW5jb2RlRG90SW5LZXlzID8gU3RyaW5nKGtleSkucmVwbGFjZSgvXFwuL2csICclMkUnKSA6IFN0cmluZyhrZXkpO1xuICAgICAgICB2YXIga2V5UHJlZml4ID0gaXNBcnJheShvYmopXG4gICAgICAgICAgICA/IHR5cGVvZiBnZW5lcmF0ZUFycmF5UHJlZml4ID09PSAnZnVuY3Rpb24nID8gZ2VuZXJhdGVBcnJheVByZWZpeChhZGp1c3RlZFByZWZpeCwgZW5jb2RlZEtleSkgOiBhZGp1c3RlZFByZWZpeFxuICAgICAgICAgICAgOiBhZGp1c3RlZFByZWZpeCArIChhbGxvd0RvdHMgPyAnLicgKyBlbmNvZGVkS2V5IDogJ1snICsgZW5jb2RlZEtleSArICddJyk7XG5cbiAgICAgICAgc2lkZUNoYW5uZWwuc2V0KG9iamVjdCwgc3RlcCk7XG4gICAgICAgIHZhciB2YWx1ZVNpZGVDaGFubmVsID0gZ2V0U2lkZUNoYW5uZWwoKTtcbiAgICAgICAgdmFsdWVTaWRlQ2hhbm5lbC5zZXQoc2VudGluZWwsIHNpZGVDaGFubmVsKTtcbiAgICAgICAgcHVzaFRvQXJyYXkodmFsdWVzLCBzdHJpbmdpZnkoXG4gICAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICAgIGtleVByZWZpeCxcbiAgICAgICAgICAgIGdlbmVyYXRlQXJyYXlQcmVmaXgsXG4gICAgICAgICAgICBjb21tYVJvdW5kVHJpcCxcbiAgICAgICAgICAgIGFsbG93RW1wdHlBcnJheXMsXG4gICAgICAgICAgICBzdHJpY3ROdWxsSGFuZGxpbmcsXG4gICAgICAgICAgICBza2lwTnVsbHMsXG4gICAgICAgICAgICBlbmNvZGVEb3RJbktleXMsXG4gICAgICAgICAgICBnZW5lcmF0ZUFycmF5UHJlZml4ID09PSAnY29tbWEnICYmIGVuY29kZVZhbHVlc09ubHkgJiYgaXNBcnJheShvYmopID8gbnVsbCA6IGVuY29kZXIsXG4gICAgICAgICAgICBmaWx0ZXIsXG4gICAgICAgICAgICBzb3J0LFxuICAgICAgICAgICAgYWxsb3dEb3RzLFxuICAgICAgICAgICAgc2VyaWFsaXplRGF0ZSxcbiAgICAgICAgICAgIGZvcm1hdCxcbiAgICAgICAgICAgIGZvcm1hdHRlcixcbiAgICAgICAgICAgIGVuY29kZVZhbHVlc09ubHksXG4gICAgICAgICAgICBjaGFyc2V0LFxuICAgICAgICAgICAgdmFsdWVTaWRlQ2hhbm5lbFxuICAgICAgICApKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdmFsdWVzO1xufTtcblxudmFyIG5vcm1hbGl6ZVN0cmluZ2lmeU9wdGlvbnMgPSBmdW5jdGlvbiBub3JtYWxpemVTdHJpbmdpZnlPcHRpb25zKG9wdHMpIHtcbiAgICBpZiAoIW9wdHMpIHtcbiAgICAgICAgcmV0dXJuIGRlZmF1bHRzO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2Ygb3B0cy5hbGxvd0VtcHR5QXJyYXlzICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2Ygb3B0cy5hbGxvd0VtcHR5QXJyYXlzICE9PSAnYm9vbGVhbicpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignYGFsbG93RW1wdHlBcnJheXNgIG9wdGlvbiBjYW4gb25seSBiZSBgdHJ1ZWAgb3IgYGZhbHNlYCwgd2hlbiBwcm92aWRlZCcpO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2Ygb3B0cy5lbmNvZGVEb3RJbktleXMgIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiBvcHRzLmVuY29kZURvdEluS2V5cyAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2BlbmNvZGVEb3RJbktleXNgIG9wdGlvbiBjYW4gb25seSBiZSBgdHJ1ZWAgb3IgYGZhbHNlYCwgd2hlbiBwcm92aWRlZCcpO1xuICAgIH1cblxuICAgIGlmIChvcHRzLmVuY29kZXIgIT09IG51bGwgJiYgdHlwZW9mIG9wdHMuZW5jb2RlciAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIG9wdHMuZW5jb2RlciAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdFbmNvZGVyIGhhcyB0byBiZSBhIGZ1bmN0aW9uLicpO1xuICAgIH1cblxuICAgIHZhciBjaGFyc2V0ID0gb3B0cy5jaGFyc2V0IHx8IGRlZmF1bHRzLmNoYXJzZXQ7XG4gICAgaWYgKHR5cGVvZiBvcHRzLmNoYXJzZXQgIT09ICd1bmRlZmluZWQnICYmIG9wdHMuY2hhcnNldCAhPT0gJ3V0Zi04JyAmJiBvcHRzLmNoYXJzZXQgIT09ICdpc28tODg1OS0xJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgY2hhcnNldCBvcHRpb24gbXVzdCBiZSBlaXRoZXIgdXRmLTgsIGlzby04ODU5LTEsIG9yIHVuZGVmaW5lZCcpO1xuICAgIH1cblxuICAgIHZhciBmb3JtYXQgPSBmb3JtYXRzWydkZWZhdWx0J107XG4gICAgaWYgKHR5cGVvZiBvcHRzLmZvcm1hdCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgaWYgKCFoYXMuY2FsbChmb3JtYXRzLmZvcm1hdHRlcnMsIG9wdHMuZm9ybWF0KSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVW5rbm93biBmb3JtYXQgb3B0aW9uIHByb3ZpZGVkLicpO1xuICAgICAgICB9XG4gICAgICAgIGZvcm1hdCA9IG9wdHMuZm9ybWF0O1xuICAgIH1cbiAgICB2YXIgZm9ybWF0dGVyID0gZm9ybWF0cy5mb3JtYXR0ZXJzW2Zvcm1hdF07XG5cbiAgICB2YXIgZmlsdGVyID0gZGVmYXVsdHMuZmlsdGVyO1xuICAgIGlmICh0eXBlb2Ygb3B0cy5maWx0ZXIgPT09ICdmdW5jdGlvbicgfHwgaXNBcnJheShvcHRzLmZpbHRlcikpIHtcbiAgICAgICAgZmlsdGVyID0gb3B0cy5maWx0ZXI7XG4gICAgfVxuXG4gICAgdmFyIGFycmF5Rm9ybWF0O1xuICAgIGlmIChvcHRzLmFycmF5Rm9ybWF0IGluIGFycmF5UHJlZml4R2VuZXJhdG9ycykge1xuICAgICAgICBhcnJheUZvcm1hdCA9IG9wdHMuYXJyYXlGb3JtYXQ7XG4gICAgfSBlbHNlIGlmICgnaW5kaWNlcycgaW4gb3B0cykge1xuICAgICAgICBhcnJheUZvcm1hdCA9IG9wdHMuaW5kaWNlcyA/ICdpbmRpY2VzJyA6ICdyZXBlYXQnO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGFycmF5Rm9ybWF0ID0gZGVmYXVsdHMuYXJyYXlGb3JtYXQ7XG4gICAgfVxuXG4gICAgaWYgKCdjb21tYVJvdW5kVHJpcCcgaW4gb3B0cyAmJiB0eXBlb2Ygb3B0cy5jb21tYVJvdW5kVHJpcCAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2Bjb21tYVJvdW5kVHJpcGAgbXVzdCBiZSBhIGJvb2xlYW4sIG9yIGFic2VudCcpO1xuICAgIH1cblxuICAgIHZhciBhbGxvd0RvdHMgPSB0eXBlb2Ygb3B0cy5hbGxvd0RvdHMgPT09ICd1bmRlZmluZWQnID8gb3B0cy5lbmNvZGVEb3RJbktleXMgPT09IHRydWUgPyB0cnVlIDogZGVmYXVsdHMuYWxsb3dEb3RzIDogISFvcHRzLmFsbG93RG90cztcblxuICAgIHJldHVybiB7XG4gICAgICAgIGFkZFF1ZXJ5UHJlZml4OiB0eXBlb2Ygb3B0cy5hZGRRdWVyeVByZWZpeCA9PT0gJ2Jvb2xlYW4nID8gb3B0cy5hZGRRdWVyeVByZWZpeCA6IGRlZmF1bHRzLmFkZFF1ZXJ5UHJlZml4LFxuICAgICAgICBhbGxvd0RvdHM6IGFsbG93RG90cyxcbiAgICAgICAgYWxsb3dFbXB0eUFycmF5czogdHlwZW9mIG9wdHMuYWxsb3dFbXB0eUFycmF5cyA9PT0gJ2Jvb2xlYW4nID8gISFvcHRzLmFsbG93RW1wdHlBcnJheXMgOiBkZWZhdWx0cy5hbGxvd0VtcHR5QXJyYXlzLFxuICAgICAgICBhcnJheUZvcm1hdDogYXJyYXlGb3JtYXQsXG4gICAgICAgIGNoYXJzZXQ6IGNoYXJzZXQsXG4gICAgICAgIGNoYXJzZXRTZW50aW5lbDogdHlwZW9mIG9wdHMuY2hhcnNldFNlbnRpbmVsID09PSAnYm9vbGVhbicgPyBvcHRzLmNoYXJzZXRTZW50aW5lbCA6IGRlZmF1bHRzLmNoYXJzZXRTZW50aW5lbCxcbiAgICAgICAgY29tbWFSb3VuZFRyaXA6ICEhb3B0cy5jb21tYVJvdW5kVHJpcCxcbiAgICAgICAgZGVsaW1pdGVyOiB0eXBlb2Ygb3B0cy5kZWxpbWl0ZXIgPT09ICd1bmRlZmluZWQnID8gZGVmYXVsdHMuZGVsaW1pdGVyIDogb3B0cy5kZWxpbWl0ZXIsXG4gICAgICAgIGVuY29kZTogdHlwZW9mIG9wdHMuZW5jb2RlID09PSAnYm9vbGVhbicgPyBvcHRzLmVuY29kZSA6IGRlZmF1bHRzLmVuY29kZSxcbiAgICAgICAgZW5jb2RlRG90SW5LZXlzOiB0eXBlb2Ygb3B0cy5lbmNvZGVEb3RJbktleXMgPT09ICdib29sZWFuJyA/IG9wdHMuZW5jb2RlRG90SW5LZXlzIDogZGVmYXVsdHMuZW5jb2RlRG90SW5LZXlzLFxuICAgICAgICBlbmNvZGVyOiB0eXBlb2Ygb3B0cy5lbmNvZGVyID09PSAnZnVuY3Rpb24nID8gb3B0cy5lbmNvZGVyIDogZGVmYXVsdHMuZW5jb2RlcixcbiAgICAgICAgZW5jb2RlVmFsdWVzT25seTogdHlwZW9mIG9wdHMuZW5jb2RlVmFsdWVzT25seSA9PT0gJ2Jvb2xlYW4nID8gb3B0cy5lbmNvZGVWYWx1ZXNPbmx5IDogZGVmYXVsdHMuZW5jb2RlVmFsdWVzT25seSxcbiAgICAgICAgZmlsdGVyOiBmaWx0ZXIsXG4gICAgICAgIGZvcm1hdDogZm9ybWF0LFxuICAgICAgICBmb3JtYXR0ZXI6IGZvcm1hdHRlcixcbiAgICAgICAgc2VyaWFsaXplRGF0ZTogdHlwZW9mIG9wdHMuc2VyaWFsaXplRGF0ZSA9PT0gJ2Z1bmN0aW9uJyA/IG9wdHMuc2VyaWFsaXplRGF0ZSA6IGRlZmF1bHRzLnNlcmlhbGl6ZURhdGUsXG4gICAgICAgIHNraXBOdWxsczogdHlwZW9mIG9wdHMuc2tpcE51bGxzID09PSAnYm9vbGVhbicgPyBvcHRzLnNraXBOdWxscyA6IGRlZmF1bHRzLnNraXBOdWxscyxcbiAgICAgICAgc29ydDogdHlwZW9mIG9wdHMuc29ydCA9PT0gJ2Z1bmN0aW9uJyA/IG9wdHMuc29ydCA6IG51bGwsXG4gICAgICAgIHN0cmljdE51bGxIYW5kbGluZzogdHlwZW9mIG9wdHMuc3RyaWN0TnVsbEhhbmRsaW5nID09PSAnYm9vbGVhbicgPyBvcHRzLnN0cmljdE51bGxIYW5kbGluZyA6IGRlZmF1bHRzLnN0cmljdE51bGxIYW5kbGluZ1xuICAgIH07XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChvYmplY3QsIG9wdHMpIHtcbiAgICB2YXIgb2JqID0gb2JqZWN0O1xuICAgIHZhciBvcHRpb25zID0gbm9ybWFsaXplU3RyaW5naWZ5T3B0aW9ucyhvcHRzKTtcblxuICAgIHZhciBvYmpLZXlzO1xuICAgIHZhciBmaWx0ZXI7XG5cbiAgICBpZiAodHlwZW9mIG9wdGlvbnMuZmlsdGVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGZpbHRlciA9IG9wdGlvbnMuZmlsdGVyO1xuICAgICAgICBvYmogPSBmaWx0ZXIoJycsIG9iaik7XG4gICAgfSBlbHNlIGlmIChpc0FycmF5KG9wdGlvbnMuZmlsdGVyKSkge1xuICAgICAgICBmaWx0ZXIgPSBvcHRpb25zLmZpbHRlcjtcbiAgICAgICAgb2JqS2V5cyA9IGZpbHRlcjtcbiAgICB9XG5cbiAgICB2YXIga2V5cyA9IFtdO1xuXG4gICAgaWYgKHR5cGVvZiBvYmogIT09ICdvYmplY3QnIHx8IG9iaiA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gJyc7XG4gICAgfVxuXG4gICAgdmFyIGdlbmVyYXRlQXJyYXlQcmVmaXggPSBhcnJheVByZWZpeEdlbmVyYXRvcnNbb3B0aW9ucy5hcnJheUZvcm1hdF07XG4gICAgdmFyIGNvbW1hUm91bmRUcmlwID0gZ2VuZXJhdGVBcnJheVByZWZpeCA9PT0gJ2NvbW1hJyAmJiBvcHRpb25zLmNvbW1hUm91bmRUcmlwO1xuXG4gICAgaWYgKCFvYmpLZXlzKSB7XG4gICAgICAgIG9iaktleXMgPSBPYmplY3Qua2V5cyhvYmopO1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zLnNvcnQpIHtcbiAgICAgICAgb2JqS2V5cy5zb3J0KG9wdGlvbnMuc29ydCk7XG4gICAgfVxuXG4gICAgdmFyIHNpZGVDaGFubmVsID0gZ2V0U2lkZUNoYW5uZWwoKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iaktleXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgdmFyIGtleSA9IG9iaktleXNbaV07XG5cbiAgICAgICAgaWYgKHR5cGVvZiBrZXkgPT09ICd1bmRlZmluZWQnIHx8IGtleSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgdmFsdWUgPSBvYmpba2V5XTtcblxuICAgICAgICBpZiAob3B0aW9ucy5za2lwTnVsbHMgJiYgdmFsdWUgPT09IG51bGwpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIHB1c2hUb0FycmF5KGtleXMsIHN0cmluZ2lmeShcbiAgICAgICAgICAgIHZhbHVlLFxuICAgICAgICAgICAga2V5LFxuICAgICAgICAgICAgZ2VuZXJhdGVBcnJheVByZWZpeCxcbiAgICAgICAgICAgIGNvbW1hUm91bmRUcmlwLFxuICAgICAgICAgICAgb3B0aW9ucy5hbGxvd0VtcHR5QXJyYXlzLFxuICAgICAgICAgICAgb3B0aW9ucy5zdHJpY3ROdWxsSGFuZGxpbmcsXG4gICAgICAgICAgICBvcHRpb25zLnNraXBOdWxscyxcbiAgICAgICAgICAgIG9wdGlvbnMuZW5jb2RlRG90SW5LZXlzLFxuICAgICAgICAgICAgb3B0aW9ucy5lbmNvZGUgPyBvcHRpb25zLmVuY29kZXIgOiBudWxsLFxuICAgICAgICAgICAgb3B0aW9ucy5maWx0ZXIsXG4gICAgICAgICAgICBvcHRpb25zLnNvcnQsXG4gICAgICAgICAgICBvcHRpb25zLmFsbG93RG90cyxcbiAgICAgICAgICAgIG9wdGlvbnMuc2VyaWFsaXplRGF0ZSxcbiAgICAgICAgICAgIG9wdGlvbnMuZm9ybWF0LFxuICAgICAgICAgICAgb3B0aW9ucy5mb3JtYXR0ZXIsXG4gICAgICAgICAgICBvcHRpb25zLmVuY29kZVZhbHVlc09ubHksXG4gICAgICAgICAgICBvcHRpb25zLmNoYXJzZXQsXG4gICAgICAgICAgICBzaWRlQ2hhbm5lbFxuICAgICAgICApKTtcbiAgICB9XG5cbiAgICB2YXIgam9pbmVkID0ga2V5cy5qb2luKG9wdGlvbnMuZGVsaW1pdGVyKTtcbiAgICB2YXIgcHJlZml4ID0gb3B0aW9ucy5hZGRRdWVyeVByZWZpeCA9PT0gdHJ1ZSA/ICc/JyA6ICcnO1xuXG4gICAgaWYgKG9wdGlvbnMuY2hhcnNldFNlbnRpbmVsKSB7XG4gICAgICAgIGlmIChvcHRpb25zLmNoYXJzZXQgPT09ICdpc28tODg1OS0xJykge1xuICAgICAgICAgICAgLy8gZW5jb2RlVVJJQ29tcG9uZW50KCcmIzEwMDAzOycpLCB0aGUgXCJudW1lcmljIGVudGl0eVwiIHJlcHJlc2VudGF0aW9uIG9mIGEgY2hlY2ttYXJrXG4gICAgICAgICAgICBwcmVmaXggKz0gJ3V0Zjg9JTI2JTIzMTAwMDMlM0InICsgb3B0aW9ucy5kZWxpbWl0ZXI7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBlbmNvZGVVUklDb21wb25lbnQoJ+KckycpXG4gICAgICAgICAgICBwcmVmaXggKz0gJ3V0Zjg9JUUyJTlDJTkzJyArIG9wdGlvbnMuZGVsaW1pdGVyO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGpvaW5lZC5sZW5ndGggPiAwID8gcHJlZml4ICsgam9pbmVkIDogJyc7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgZm9ybWF0cyA9IHJlcXVpcmUoJy4vZm9ybWF0cycpO1xudmFyIGdldFNpZGVDaGFubmVsID0gcmVxdWlyZSgnc2lkZS1jaGFubmVsJyk7XG5cbnZhciBoYXMgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xudmFyIGlzQXJyYXkgPSBBcnJheS5pc0FycmF5O1xuXG4vLyBUcmFjayBvYmplY3RzIGNyZWF0ZWQgZnJvbSBhcnJheUxpbWl0IG92ZXJmbG93IHVzaW5nIHNpZGUtY2hhbm5lbFxuLy8gU3RvcmVzIHRoZSBjdXJyZW50IG1heCBudW1lcmljIGluZGV4IGZvciBPKDEpIGxvb2t1cFxudmFyIG92ZXJmbG93Q2hhbm5lbCA9IGdldFNpZGVDaGFubmVsKCk7XG5cbnZhciBtYXJrT3ZlcmZsb3cgPSBmdW5jdGlvbiBtYXJrT3ZlcmZsb3cob2JqLCBtYXhJbmRleCkge1xuICAgIG92ZXJmbG93Q2hhbm5lbC5zZXQob2JqLCBtYXhJbmRleCk7XG4gICAgcmV0dXJuIG9iajtcbn07XG5cbnZhciBpc092ZXJmbG93ID0gZnVuY3Rpb24gaXNPdmVyZmxvdyhvYmopIHtcbiAgICByZXR1cm4gb3ZlcmZsb3dDaGFubmVsLmhhcyhvYmopO1xufTtcblxudmFyIGdldE1heEluZGV4ID0gZnVuY3Rpb24gZ2V0TWF4SW5kZXgob2JqKSB7XG4gICAgcmV0dXJuIG92ZXJmbG93Q2hhbm5lbC5nZXQob2JqKTtcbn07XG5cbnZhciBzZXRNYXhJbmRleCA9IGZ1bmN0aW9uIHNldE1heEluZGV4KG9iaiwgbWF4SW5kZXgpIHtcbiAgICBvdmVyZmxvd0NoYW5uZWwuc2V0KG9iaiwgbWF4SW5kZXgpO1xufTtcblxudmFyIGhleFRhYmxlID0gKGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgYXJyYXkgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IDI1NjsgKytpKSB7XG4gICAgICAgIGFycmF5W2FycmF5Lmxlbmd0aF0gPSAnJScgKyAoKGkgPCAxNiA/ICcwJyA6ICcnKSArIGkudG9TdHJpbmcoMTYpKS50b1VwcGVyQ2FzZSgpO1xuICAgIH1cblxuICAgIHJldHVybiBhcnJheTtcbn0oKSk7XG5cbnZhciBjb21wYWN0UXVldWUgPSBmdW5jdGlvbiBjb21wYWN0UXVldWUocXVldWUpIHtcbiAgICB3aGlsZSAocXVldWUubGVuZ3RoID4gMSkge1xuICAgICAgICB2YXIgaXRlbSA9IHF1ZXVlLnBvcCgpO1xuICAgICAgICB2YXIgb2JqID0gaXRlbS5vYmpbaXRlbS5wcm9wXTtcblxuICAgICAgICBpZiAoaXNBcnJheShvYmopKSB7XG4gICAgICAgICAgICB2YXIgY29tcGFjdGVkID0gW107XG5cbiAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgb2JqLmxlbmd0aDsgKytqKSB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvYmpbal0gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbXBhY3RlZFtjb21wYWN0ZWQubGVuZ3RoXSA9IG9ialtqXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGl0ZW0ub2JqW2l0ZW0ucHJvcF0gPSBjb21wYWN0ZWQ7XG4gICAgICAgIH1cbiAgICB9XG59O1xuXG52YXIgYXJyYXlUb09iamVjdCA9IGZ1bmN0aW9uIGFycmF5VG9PYmplY3Qoc291cmNlLCBvcHRpb25zKSB7XG4gICAgdmFyIG9iaiA9IG9wdGlvbnMgJiYgb3B0aW9ucy5wbGFpbk9iamVjdHMgPyB7IF9fcHJvdG9fXzogbnVsbCB9IDoge307XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzb3VyY2UubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBzb3VyY2VbaV0gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBvYmpbaV0gPSBzb3VyY2VbaV07XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gb2JqO1xufTtcblxudmFyIG1lcmdlID0gZnVuY3Rpb24gbWVyZ2UodGFyZ2V0LCBzb3VyY2UsIG9wdGlvbnMpIHtcbiAgICAvKiBlc2xpbnQgbm8tcGFyYW0tcmVhc3NpZ246IDAgKi9cbiAgICBpZiAoIXNvdXJjZSkge1xuICAgICAgICByZXR1cm4gdGFyZ2V0O1xuICAgIH1cblxuICAgIGlmICh0eXBlb2Ygc291cmNlICE9PSAnb2JqZWN0JyAmJiB0eXBlb2Ygc291cmNlICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGlmIChpc0FycmF5KHRhcmdldCkpIHtcbiAgICAgICAgICAgIHZhciBuZXh0SW5kZXggPSB0YXJnZXQubGVuZ3RoO1xuICAgICAgICAgICAgaWYgKG9wdGlvbnMgJiYgdHlwZW9mIG9wdGlvbnMuYXJyYXlMaW1pdCA9PT0gJ251bWJlcicgJiYgbmV4dEluZGV4ID4gb3B0aW9ucy5hcnJheUxpbWl0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1hcmtPdmVyZmxvdyhhcnJheVRvT2JqZWN0KHRhcmdldC5jb25jYXQoc291cmNlKSwgb3B0aW9ucyksIG5leHRJbmRleCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0YXJnZXRbbmV4dEluZGV4XSA9IHNvdXJjZTtcbiAgICAgICAgfSBlbHNlIGlmICh0YXJnZXQgJiYgdHlwZW9mIHRhcmdldCA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIGlmIChpc092ZXJmbG93KHRhcmdldCkpIHtcbiAgICAgICAgICAgICAgICAvLyBBZGQgYXQgbmV4dCBudW1lcmljIGluZGV4IGZvciBvdmVyZmxvdyBvYmplY3RzXG4gICAgICAgICAgICAgICAgdmFyIG5ld0luZGV4ID0gZ2V0TWF4SW5kZXgodGFyZ2V0KSArIDE7XG4gICAgICAgICAgICAgICAgdGFyZ2V0W25ld0luZGV4XSA9IHNvdXJjZTtcbiAgICAgICAgICAgICAgICBzZXRNYXhJbmRleCh0YXJnZXQsIG5ld0luZGV4KTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAob3B0aW9ucyAmJiBvcHRpb25zLnN0cmljdE1lcmdlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFt0YXJnZXQsIHNvdXJjZV07XG4gICAgICAgICAgICB9IGVsc2UgaWYgKFxuICAgICAgICAgICAgICAgIChvcHRpb25zICYmIChvcHRpb25zLnBsYWluT2JqZWN0cyB8fCBvcHRpb25zLmFsbG93UHJvdG90eXBlcykpXG4gICAgICAgICAgICAgICAgfHwgIWhhcy5jYWxsKE9iamVjdC5wcm90b3R5cGUsIHNvdXJjZSlcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIHRhcmdldFtzb3VyY2VdID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBbdGFyZ2V0LCBzb3VyY2VdO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRhcmdldDtcbiAgICB9XG5cbiAgICBpZiAoIXRhcmdldCB8fCB0eXBlb2YgdGFyZ2V0ICE9PSAnb2JqZWN0Jykge1xuICAgICAgICBpZiAoaXNPdmVyZmxvdyhzb3VyY2UpKSB7XG4gICAgICAgICAgICAvLyBDcmVhdGUgbmV3IG9iamVjdCB3aXRoIHRhcmdldCBhdCAwLCBzb3VyY2UgdmFsdWVzIHNoaWZ0ZWQgYnkgMVxuICAgICAgICAgICAgdmFyIHNvdXJjZUtleXMgPSBPYmplY3Qua2V5cyhzb3VyY2UpO1xuICAgICAgICAgICAgdmFyIHJlc3VsdCA9IG9wdGlvbnMgJiYgb3B0aW9ucy5wbGFpbk9iamVjdHNcbiAgICAgICAgICAgICAgICA/IHsgX19wcm90b19fOiBudWxsLCAwOiB0YXJnZXQgfVxuICAgICAgICAgICAgICAgIDogeyAwOiB0YXJnZXQgfTtcbiAgICAgICAgICAgIGZvciAodmFyIG0gPSAwOyBtIDwgc291cmNlS2V5cy5sZW5ndGg7IG0rKykge1xuICAgICAgICAgICAgICAgIHZhciBvbGRLZXkgPSBwYXJzZUludChzb3VyY2VLZXlzW21dLCAxMCk7XG4gICAgICAgICAgICAgICAgcmVzdWx0W29sZEtleSArIDFdID0gc291cmNlW3NvdXJjZUtleXNbbV1dO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG1hcmtPdmVyZmxvdyhyZXN1bHQsIGdldE1heEluZGV4KHNvdXJjZSkgKyAxKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgY29tYmluZWQgPSBbdGFyZ2V0XS5jb25jYXQoc291cmNlKTtcbiAgICAgICAgaWYgKG9wdGlvbnMgJiYgdHlwZW9mIG9wdGlvbnMuYXJyYXlMaW1pdCA9PT0gJ251bWJlcicgJiYgY29tYmluZWQubGVuZ3RoID4gb3B0aW9ucy5hcnJheUxpbWl0KSB7XG4gICAgICAgICAgICByZXR1cm4gbWFya092ZXJmbG93KGFycmF5VG9PYmplY3QoY29tYmluZWQsIG9wdGlvbnMpLCBjb21iaW5lZC5sZW5ndGggLSAxKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY29tYmluZWQ7XG4gICAgfVxuXG4gICAgdmFyIG1lcmdlVGFyZ2V0ID0gdGFyZ2V0O1xuICAgIGlmIChpc0FycmF5KHRhcmdldCkgJiYgIWlzQXJyYXkoc291cmNlKSkge1xuICAgICAgICBtZXJnZVRhcmdldCA9IGFycmF5VG9PYmplY3QodGFyZ2V0LCBvcHRpb25zKTtcbiAgICB9XG5cbiAgICBpZiAoaXNBcnJheSh0YXJnZXQpICYmIGlzQXJyYXkoc291cmNlKSkge1xuICAgICAgICBzb3VyY2UuZm9yRWFjaChmdW5jdGlvbiAoaXRlbSwgaSkge1xuICAgICAgICAgICAgaWYgKGhhcy5jYWxsKHRhcmdldCwgaSkpIHtcbiAgICAgICAgICAgICAgICB2YXIgdGFyZ2V0SXRlbSA9IHRhcmdldFtpXTtcbiAgICAgICAgICAgICAgICBpZiAodGFyZ2V0SXRlbSAmJiB0eXBlb2YgdGFyZ2V0SXRlbSA9PT0gJ29iamVjdCcgJiYgaXRlbSAmJiB0eXBlb2YgaXRlbSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0W2ldID0gbWVyZ2UodGFyZ2V0SXRlbSwgaXRlbSwgb3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0W3RhcmdldC5sZW5ndGhdID0gaXRlbTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRhcmdldFtpXSA9IGl0ZW07XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdGFyZ2V0O1xuICAgIH1cblxuICAgIHJldHVybiBPYmplY3Qua2V5cyhzb3VyY2UpLnJlZHVjZShmdW5jdGlvbiAoYWNjLCBrZXkpIHtcbiAgICAgICAgdmFyIHZhbHVlID0gc291cmNlW2tleV07XG5cbiAgICAgICAgaWYgKGhhcy5jYWxsKGFjYywga2V5KSkge1xuICAgICAgICAgICAgYWNjW2tleV0gPSBtZXJnZShhY2Nba2V5XSwgdmFsdWUsIG9wdGlvbnMpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYWNjW2tleV0gPSB2YWx1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpc092ZXJmbG93KHNvdXJjZSkgJiYgIWlzT3ZlcmZsb3coYWNjKSkge1xuICAgICAgICAgICAgbWFya092ZXJmbG93KGFjYywgZ2V0TWF4SW5kZXgoc291cmNlKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzT3ZlcmZsb3coYWNjKSkge1xuICAgICAgICAgICAgdmFyIGtleU51bSA9IHBhcnNlSW50KGtleSwgMTApO1xuICAgICAgICAgICAgaWYgKFN0cmluZyhrZXlOdW0pID09PSBrZXkgJiYga2V5TnVtID49IDAgJiYga2V5TnVtID4gZ2V0TWF4SW5kZXgoYWNjKSkge1xuICAgICAgICAgICAgICAgIHNldE1heEluZGV4KGFjYywga2V5TnVtKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhY2M7XG4gICAgfSwgbWVyZ2VUYXJnZXQpO1xufTtcblxudmFyIGFzc2lnbiA9IGZ1bmN0aW9uIGFzc2lnblNpbmdsZVNvdXJjZSh0YXJnZXQsIHNvdXJjZSkge1xuICAgIHJldHVybiBPYmplY3Qua2V5cyhzb3VyY2UpLnJlZHVjZShmdW5jdGlvbiAoYWNjLCBrZXkpIHtcbiAgICAgICAgYWNjW2tleV0gPSBzb3VyY2Vba2V5XTtcbiAgICAgICAgcmV0dXJuIGFjYztcbiAgICB9LCB0YXJnZXQpO1xufTtcblxudmFyIGRlY29kZSA9IGZ1bmN0aW9uIChzdHIsIGRlZmF1bHREZWNvZGVyLCBjaGFyc2V0KSB7XG4gICAgdmFyIHN0cldpdGhvdXRQbHVzID0gc3RyLnJlcGxhY2UoL1xcKy9nLCAnICcpO1xuICAgIGlmIChjaGFyc2V0ID09PSAnaXNvLTg4NTktMScpIHtcbiAgICAgICAgLy8gdW5lc2NhcGUgbmV2ZXIgdGhyb3dzLCBubyB0cnkuLi5jYXRjaCBuZWVkZWQ6XG4gICAgICAgIHJldHVybiBzdHJXaXRob3V0UGx1cy5yZXBsYWNlKC8lWzAtOWEtZl17Mn0vZ2ksIHVuZXNjYXBlKTtcbiAgICB9XG4gICAgLy8gdXRmLThcbiAgICB0cnkge1xuICAgICAgICByZXR1cm4gZGVjb2RlVVJJQ29tcG9uZW50KHN0cldpdGhvdXRQbHVzKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHJldHVybiBzdHJXaXRob3V0UGx1cztcbiAgICB9XG59O1xuXG52YXIgbGltaXQgPSAxMDI0O1xuXG4vKiBlc2xpbnQgb3BlcmF0b3ItbGluZWJyZWFrOiBbMiwgXCJiZWZvcmVcIl0gKi9cblxudmFyIGVuY29kZSA9IGZ1bmN0aW9uIGVuY29kZShzdHIsIGRlZmF1bHRFbmNvZGVyLCBjaGFyc2V0LCBraW5kLCBmb3JtYXQpIHtcbiAgICAvLyBUaGlzIGNvZGUgd2FzIG9yaWdpbmFsbHkgd3JpdHRlbiBieSBCcmlhbiBXaGl0ZSAobXNjZGV4KSBmb3IgdGhlIGlvLmpzIGNvcmUgcXVlcnlzdHJpbmcgbGlicmFyeS5cbiAgICAvLyBJdCBoYXMgYmVlbiBhZGFwdGVkIGhlcmUgZm9yIHN0cmljdGVyIGFkaGVyZW5jZSB0byBSRkMgMzk4NlxuICAgIGlmIChzdHIubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJldHVybiBzdHI7XG4gICAgfVxuXG4gICAgdmFyIHN0cmluZyA9IHN0cjtcbiAgICBpZiAodHlwZW9mIHN0ciA9PT0gJ3N5bWJvbCcpIHtcbiAgICAgICAgc3RyaW5nID0gU3ltYm9sLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHN0cik7XG4gICAgfSBlbHNlIGlmICh0eXBlb2Ygc3RyICE9PSAnc3RyaW5nJykge1xuICAgICAgICBzdHJpbmcgPSBTdHJpbmcoc3RyKTtcbiAgICB9XG5cbiAgICBpZiAoY2hhcnNldCA9PT0gJ2lzby04ODU5LTEnKSB7XG4gICAgICAgIHJldHVybiBlc2NhcGUoc3RyaW5nKS5yZXBsYWNlKC8ldVswLTlhLWZdezR9L2dpLCBmdW5jdGlvbiAoJDApIHtcbiAgICAgICAgICAgIHJldHVybiAnJTI2JTIzJyArIHBhcnNlSW50KCQwLnNsaWNlKDIpLCAxNikgKyAnJTNCJztcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgdmFyIG91dCA9ICcnO1xuICAgIGZvciAodmFyIGogPSAwOyBqIDwgc3RyaW5nLmxlbmd0aDsgaiArPSBsaW1pdCkge1xuICAgICAgICB2YXIgc2VnbWVudCA9IHN0cmluZy5sZW5ndGggPj0gbGltaXQgPyBzdHJpbmcuc2xpY2UoaiwgaiArIGxpbWl0KSA6IHN0cmluZztcbiAgICAgICAgdmFyIGFyciA9IFtdO1xuXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2VnbWVudC5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgdmFyIGMgPSBzZWdtZW50LmNoYXJDb2RlQXQoaSk7XG4gICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgYyA9PT0gMHgyRCAvLyAtXG4gICAgICAgICAgICAgICAgfHwgYyA9PT0gMHgyRSAvLyAuXG4gICAgICAgICAgICAgICAgfHwgYyA9PT0gMHg1RiAvLyBfXG4gICAgICAgICAgICAgICAgfHwgYyA9PT0gMHg3RSAvLyB+XG4gICAgICAgICAgICAgICAgfHwgKGMgPj0gMHgzMCAmJiBjIDw9IDB4MzkpIC8vIDAtOVxuICAgICAgICAgICAgICAgIHx8IChjID49IDB4NDEgJiYgYyA8PSAweDVBKSAvLyBhLXpcbiAgICAgICAgICAgICAgICB8fCAoYyA+PSAweDYxICYmIGMgPD0gMHg3QSkgLy8gQS1aXG4gICAgICAgICAgICAgICAgfHwgKGZvcm1hdCA9PT0gZm9ybWF0cy5SRkMxNzM4ICYmIChjID09PSAweDI4IHx8IGMgPT09IDB4MjkpKSAvLyAoIClcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIGFyclthcnIubGVuZ3RoXSA9IHNlZ21lbnQuY2hhckF0KGkpO1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoYyA8IDB4ODApIHtcbiAgICAgICAgICAgICAgICBhcnJbYXJyLmxlbmd0aF0gPSBoZXhUYWJsZVtjXTtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGMgPCAweDgwMCkge1xuICAgICAgICAgICAgICAgIGFyclthcnIubGVuZ3RoXSA9IGhleFRhYmxlWzB4QzAgfCAoYyA+PiA2KV1cbiAgICAgICAgICAgICAgICAgICAgKyBoZXhUYWJsZVsweDgwIHwgKGMgJiAweDNGKV07XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChjIDwgMHhEODAwIHx8IGMgPj0gMHhFMDAwKSB7XG4gICAgICAgICAgICAgICAgYXJyW2Fyci5sZW5ndGhdID0gaGV4VGFibGVbMHhFMCB8IChjID4+IDEyKV1cbiAgICAgICAgICAgICAgICAgICAgKyBoZXhUYWJsZVsweDgwIHwgKChjID4+IDYpICYgMHgzRildXG4gICAgICAgICAgICAgICAgICAgICsgaGV4VGFibGVbMHg4MCB8IChjICYgMHgzRildO1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpICs9IDE7XG4gICAgICAgICAgICBjID0gMHgxMDAwMCArICgoKGMgJiAweDNGRikgPDwgMTApIHwgKHNlZ21lbnQuY2hhckNvZGVBdChpKSAmIDB4M0ZGKSk7XG5cbiAgICAgICAgICAgIGFyclthcnIubGVuZ3RoXSA9IGhleFRhYmxlWzB4RjAgfCAoYyA+PiAxOCldXG4gICAgICAgICAgICAgICAgKyBoZXhUYWJsZVsweDgwIHwgKChjID4+IDEyKSAmIDB4M0YpXVxuICAgICAgICAgICAgICAgICsgaGV4VGFibGVbMHg4MCB8ICgoYyA+PiA2KSAmIDB4M0YpXVxuICAgICAgICAgICAgICAgICsgaGV4VGFibGVbMHg4MCB8IChjICYgMHgzRildO1xuICAgICAgICB9XG5cbiAgICAgICAgb3V0ICs9IGFyci5qb2luKCcnKTtcbiAgICB9XG5cbiAgICByZXR1cm4gb3V0O1xufTtcblxudmFyIGNvbXBhY3QgPSBmdW5jdGlvbiBjb21wYWN0KHZhbHVlKSB7XG4gICAgdmFyIHF1ZXVlID0gW3sgb2JqOiB7IG86IHZhbHVlIH0sIHByb3A6ICdvJyB9XTtcbiAgICB2YXIgcmVmcyA9IFtdO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBxdWV1ZS5sZW5ndGg7ICsraSkge1xuICAgICAgICB2YXIgaXRlbSA9IHF1ZXVlW2ldO1xuICAgICAgICB2YXIgb2JqID0gaXRlbS5vYmpbaXRlbS5wcm9wXTtcblxuICAgICAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKG9iaik7XG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwga2V5cy5sZW5ndGg7ICsraikge1xuICAgICAgICAgICAgdmFyIGtleSA9IGtleXNbal07XG4gICAgICAgICAgICB2YXIgdmFsID0gb2JqW2tleV07XG4gICAgICAgICAgICBpZiAodHlwZW9mIHZhbCA9PT0gJ29iamVjdCcgJiYgdmFsICE9PSBudWxsICYmIHJlZnMuaW5kZXhPZih2YWwpID09PSAtMSkge1xuICAgICAgICAgICAgICAgIHF1ZXVlW3F1ZXVlLmxlbmd0aF0gPSB7IG9iajogb2JqLCBwcm9wOiBrZXkgfTtcbiAgICAgICAgICAgICAgICByZWZzW3JlZnMubGVuZ3RoXSA9IHZhbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGNvbXBhY3RRdWV1ZShxdWV1ZSk7XG5cbiAgICByZXR1cm4gdmFsdWU7XG59O1xuXG52YXIgaXNSZWdFeHAgPSBmdW5jdGlvbiBpc1JlZ0V4cChvYmopIHtcbiAgICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG9iaikgPT09ICdbb2JqZWN0IFJlZ0V4cF0nO1xufTtcblxudmFyIGlzQnVmZmVyID0gZnVuY3Rpb24gaXNCdWZmZXIob2JqKSB7XG4gICAgaWYgKCFvYmogfHwgdHlwZW9mIG9iaiAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHJldHVybiAhIShvYmouY29uc3RydWN0b3IgJiYgb2JqLmNvbnN0cnVjdG9yLmlzQnVmZmVyICYmIG9iai5jb25zdHJ1Y3Rvci5pc0J1ZmZlcihvYmopKTtcbn07XG5cbnZhciBjb21iaW5lID0gZnVuY3Rpb24gY29tYmluZShhLCBiLCBhcnJheUxpbWl0LCBwbGFpbk9iamVjdHMpIHtcbiAgICAvLyBJZiAnYScgaXMgYWxyZWFkeSBhbiBvdmVyZmxvdyBvYmplY3QsIGFkZCB0byBpdFxuICAgIGlmIChpc092ZXJmbG93KGEpKSB7XG4gICAgICAgIHZhciBuZXdJbmRleCA9IGdldE1heEluZGV4KGEpICsgMTtcbiAgICAgICAgYVtuZXdJbmRleF0gPSBiO1xuICAgICAgICBzZXRNYXhJbmRleChhLCBuZXdJbmRleCk7XG4gICAgICAgIHJldHVybiBhO1xuICAgIH1cblxuICAgIHZhciByZXN1bHQgPSBbXS5jb25jYXQoYSwgYik7XG4gICAgaWYgKHJlc3VsdC5sZW5ndGggPiBhcnJheUxpbWl0KSB7XG4gICAgICAgIHJldHVybiBtYXJrT3ZlcmZsb3coYXJyYXlUb09iamVjdChyZXN1bHQsIHsgcGxhaW5PYmplY3RzOiBwbGFpbk9iamVjdHMgfSksIHJlc3VsdC5sZW5ndGggLSAxKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbn07XG5cbnZhciBtYXliZU1hcCA9IGZ1bmN0aW9uIG1heWJlTWFwKHZhbCwgZm4pIHtcbiAgICBpZiAoaXNBcnJheSh2YWwpKSB7XG4gICAgICAgIHZhciBtYXBwZWQgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB2YWwubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgIG1hcHBlZFttYXBwZWQubGVuZ3RoXSA9IGZuKHZhbFtpXSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1hcHBlZDtcbiAgICB9XG4gICAgcmV0dXJuIGZuKHZhbCk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgICBhcnJheVRvT2JqZWN0OiBhcnJheVRvT2JqZWN0LFxuICAgIGFzc2lnbjogYXNzaWduLFxuICAgIGNvbWJpbmU6IGNvbWJpbmUsXG4gICAgY29tcGFjdDogY29tcGFjdCxcbiAgICBkZWNvZGU6IGRlY29kZSxcbiAgICBlbmNvZGU6IGVuY29kZSxcbiAgICBpc0J1ZmZlcjogaXNCdWZmZXIsXG4gICAgaXNPdmVyZmxvdzogaXNPdmVyZmxvdyxcbiAgICBpc1JlZ0V4cDogaXNSZWdFeHAsXG4gICAgbWFya092ZXJmbG93OiBtYXJrT3ZlcmZsb3csXG4gICAgbWF5YmVNYXA6IG1heWJlTWFwLFxuICAgIG1lcmdlOiBtZXJnZVxufTtcbiIsIi8qISBzYWZlLWJ1ZmZlci4gTUlUIExpY2Vuc2UuIEZlcm9zcyBBYm91a2hhZGlqZWggPGh0dHBzOi8vZmVyb3NzLm9yZy9vcGVuc291cmNlPiAqL1xuLyogZXNsaW50LWRpc2FibGUgbm9kZS9uby1kZXByZWNhdGVkLWFwaSAqL1xudmFyIGJ1ZmZlciA9IHJlcXVpcmUoJ2J1ZmZlcicpXG52YXIgQnVmZmVyID0gYnVmZmVyLkJ1ZmZlclxuXG4vLyBhbHRlcm5hdGl2ZSB0byB1c2luZyBPYmplY3Qua2V5cyBmb3Igb2xkIGJyb3dzZXJzXG5mdW5jdGlvbiBjb3B5UHJvcHMgKHNyYywgZHN0KSB7XG4gIGZvciAodmFyIGtleSBpbiBzcmMpIHtcbiAgICBkc3Rba2V5XSA9IHNyY1trZXldXG4gIH1cbn1cbmlmIChCdWZmZXIuZnJvbSAmJiBCdWZmZXIuYWxsb2MgJiYgQnVmZmVyLmFsbG9jVW5zYWZlICYmIEJ1ZmZlci5hbGxvY1Vuc2FmZVNsb3cpIHtcbiAgbW9kdWxlLmV4cG9ydHMgPSBidWZmZXJcbn0gZWxzZSB7XG4gIC8vIENvcHkgcHJvcGVydGllcyBmcm9tIHJlcXVpcmUoJ2J1ZmZlcicpXG4gIGNvcHlQcm9wcyhidWZmZXIsIGV4cG9ydHMpXG4gIGV4cG9ydHMuQnVmZmVyID0gU2FmZUJ1ZmZlclxufVxuXG5mdW5jdGlvbiBTYWZlQnVmZmVyIChhcmcsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gQnVmZmVyKGFyZywgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKVxufVxuXG5TYWZlQnVmZmVyLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoQnVmZmVyLnByb3RvdHlwZSlcblxuLy8gQ29weSBzdGF0aWMgbWV0aG9kcyBmcm9tIEJ1ZmZlclxuY29weVByb3BzKEJ1ZmZlciwgU2FmZUJ1ZmZlcilcblxuU2FmZUJ1ZmZlci5mcm9tID0gZnVuY3Rpb24gKGFyZywgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKSB7XG4gIGlmICh0eXBlb2YgYXJnID09PSAnbnVtYmVyJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50IG11c3Qgbm90IGJlIGEgbnVtYmVyJylcbiAgfVxuICByZXR1cm4gQnVmZmVyKGFyZywgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKVxufVxuXG5TYWZlQnVmZmVyLmFsbG9jID0gZnVuY3Rpb24gKHNpemUsIGZpbGwsIGVuY29kaW5nKSB7XG4gIGlmICh0eXBlb2Ygc2l6ZSAhPT0gJ251bWJlcicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudCBtdXN0IGJlIGEgbnVtYmVyJylcbiAgfVxuICB2YXIgYnVmID0gQnVmZmVyKHNpemUpXG4gIGlmIChmaWxsICE9PSB1bmRlZmluZWQpIHtcbiAgICBpZiAodHlwZW9mIGVuY29kaW5nID09PSAnc3RyaW5nJykge1xuICAgICAgYnVmLmZpbGwoZmlsbCwgZW5jb2RpbmcpXG4gICAgfSBlbHNlIHtcbiAgICAgIGJ1Zi5maWxsKGZpbGwpXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGJ1Zi5maWxsKDApXG4gIH1cbiAgcmV0dXJuIGJ1ZlxufVxuXG5TYWZlQnVmZmVyLmFsbG9jVW5zYWZlID0gZnVuY3Rpb24gKHNpemUpIHtcbiAgaWYgKHR5cGVvZiBzaXplICE9PSAnbnVtYmVyJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50IG11c3QgYmUgYSBudW1iZXInKVxuICB9XG4gIHJldHVybiBCdWZmZXIoc2l6ZSlcbn1cblxuU2FmZUJ1ZmZlci5hbGxvY1Vuc2FmZVNsb3cgPSBmdW5jdGlvbiAoc2l6ZSkge1xuICBpZiAodHlwZW9mIHNpemUgIT09ICdudW1iZXInKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQXJndW1lbnQgbXVzdCBiZSBhIG51bWJlcicpXG4gIH1cbiAgcmV0dXJuIGJ1ZmZlci5TbG93QnVmZmVyKHNpemUpXG59XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBpbnNwZWN0ID0gcmVxdWlyZSgnb2JqZWN0LWluc3BlY3QnKTtcblxudmFyICRUeXBlRXJyb3IgPSByZXF1aXJlKCdlcy1lcnJvcnMvdHlwZScpO1xuXG4vKlxuKiBUaGlzIGZ1bmN0aW9uIHRyYXZlcnNlcyB0aGUgbGlzdCByZXR1cm5pbmcgdGhlIG5vZGUgY29ycmVzcG9uZGluZyB0byB0aGUgZ2l2ZW4ga2V5LlxuKlxuKiBUaGF0IG5vZGUgaXMgYWxzbyBtb3ZlZCB0byB0aGUgaGVhZCBvZiB0aGUgbGlzdCwgc28gdGhhdCBpZiBpdCdzIGFjY2Vzc2VkIGFnYWluIHdlIGRvbid0IG5lZWQgdG8gdHJhdmVyc2UgdGhlIHdob2xlIGxpc3QuXG4qIEJ5IGRvaW5nIHNvLCBhbGwgdGhlIHJlY2VudGx5IHVzZWQgbm9kZXMgY2FuIGJlIGFjY2Vzc2VkIHJlbGF0aXZlbHkgcXVpY2tseS5cbiovXG4vKiogQHR5cGUge2ltcG9ydCgnLi9saXN0LmQudHMnKS5saXN0R2V0Tm9kZX0gKi9cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjb25zaXN0ZW50LXJldHVyblxudmFyIGxpc3RHZXROb2RlID0gZnVuY3Rpb24gKGxpc3QsIGtleSwgaXNEZWxldGUpIHtcblx0LyoqIEB0eXBlIHt0eXBlb2YgbGlzdCB8IE5vbk51bGxhYmxlPCh0eXBlb2YgbGlzdClbJ25leHQnXT59ICovXG5cdHZhciBwcmV2ID0gbGlzdDtcblx0LyoqIEB0eXBlIHsodHlwZW9mIGxpc3QpWyduZXh0J119ICovXG5cdHZhciBjdXJyO1xuXHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZXFlcWVxXG5cdGZvciAoOyAoY3VyciA9IHByZXYubmV4dCkgIT0gbnVsbDsgcHJldiA9IGN1cnIpIHtcblx0XHRpZiAoY3Vyci5rZXkgPT09IGtleSkge1xuXHRcdFx0cHJldi5uZXh0ID0gY3Vyci5uZXh0O1xuXHRcdFx0aWYgKCFpc0RlbGV0ZSkge1xuXHRcdFx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tZXh0cmEtcGFyZW5zXG5cdFx0XHRcdGN1cnIubmV4dCA9IC8qKiBAdHlwZSB7Tm9uTnVsbGFibGU8dHlwZW9mIGxpc3QubmV4dD59ICovIChsaXN0Lm5leHQpO1xuXHRcdFx0XHRsaXN0Lm5leHQgPSBjdXJyOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXBhcmFtLXJlYXNzaWduXG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gY3Vycjtcblx0XHR9XG5cdH1cbn07XG5cbi8qKiBAdHlwZSB7aW1wb3J0KCcuL2xpc3QuZC50cycpLmxpc3RHZXR9ICovXG52YXIgbGlzdEdldCA9IGZ1bmN0aW9uIChvYmplY3RzLCBrZXkpIHtcblx0aWYgKCFvYmplY3RzKSB7XG5cdFx0cmV0dXJuIHZvaWQgdW5kZWZpbmVkO1xuXHR9XG5cdHZhciBub2RlID0gbGlzdEdldE5vZGUob2JqZWN0cywga2V5KTtcblx0cmV0dXJuIG5vZGUgJiYgbm9kZS52YWx1ZTtcbn07XG4vKiogQHR5cGUge2ltcG9ydCgnLi9saXN0LmQudHMnKS5saXN0U2V0fSAqL1xudmFyIGxpc3RTZXQgPSBmdW5jdGlvbiAob2JqZWN0cywga2V5LCB2YWx1ZSkge1xuXHR2YXIgbm9kZSA9IGxpc3RHZXROb2RlKG9iamVjdHMsIGtleSk7XG5cdGlmIChub2RlKSB7XG5cdFx0bm9kZS52YWx1ZSA9IHZhbHVlO1xuXHR9IGVsc2Uge1xuXHRcdC8vIFByZXBlbmQgdGhlIG5ldyBub2RlIHRvIHRoZSBiZWdpbm5pbmcgb2YgdGhlIGxpc3Rcblx0XHRvYmplY3RzLm5leHQgPSAvKiogQHR5cGUge2ltcG9ydCgnLi9saXN0LmQudHMnKS5MaXN0Tm9kZTx0eXBlb2YgdmFsdWUsIHR5cGVvZiBrZXk+fSAqLyAoeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXBhcmFtLXJlYXNzaWduLCBuby1leHRyYS1wYXJlbnNcblx0XHRcdGtleToga2V5LFxuXHRcdFx0bmV4dDogb2JqZWN0cy5uZXh0LFxuXHRcdFx0dmFsdWU6IHZhbHVlXG5cdFx0fSk7XG5cdH1cbn07XG4vKiogQHR5cGUge2ltcG9ydCgnLi9saXN0LmQudHMnKS5saXN0SGFzfSAqL1xudmFyIGxpc3RIYXMgPSBmdW5jdGlvbiAob2JqZWN0cywga2V5KSB7XG5cdGlmICghb2JqZWN0cykge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXHRyZXR1cm4gISFsaXN0R2V0Tm9kZShvYmplY3RzLCBrZXkpO1xufTtcbi8qKiBAdHlwZSB7aW1wb3J0KCcuL2xpc3QuZC50cycpLmxpc3REZWxldGV9ICovXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY29uc2lzdGVudC1yZXR1cm5cbnZhciBsaXN0RGVsZXRlID0gZnVuY3Rpb24gKG9iamVjdHMsIGtleSkge1xuXHRpZiAob2JqZWN0cykge1xuXHRcdHJldHVybiBsaXN0R2V0Tm9kZShvYmplY3RzLCBrZXksIHRydWUpO1xuXHR9XG59O1xuXG4vKiogQHR5cGUge2ltcG9ydCgnLicpfSAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBnZXRTaWRlQ2hhbm5lbExpc3QoKSB7XG5cdC8qKiBAdHlwZWRlZiB7UmV0dXJuVHlwZTx0eXBlb2YgZ2V0U2lkZUNoYW5uZWxMaXN0Pn0gQ2hhbm5lbCAqL1xuXHQvKiogQHR5cGVkZWYge1BhcmFtZXRlcnM8Q2hhbm5lbFsnZ2V0J10+WzBdfSBLICovXG5cdC8qKiBAdHlwZWRlZiB7UGFyYW1ldGVyczxDaGFubmVsWydzZXQnXT5bMV19IFYgKi9cblxuXHQvKiogQHR5cGUge2ltcG9ydCgnLi9saXN0LmQudHMnKS5Sb290Tm9kZTxWLCBLPiB8IHVuZGVmaW5lZH0gKi8gdmFyICRvO1xuXG5cdC8qKiBAdHlwZSB7Q2hhbm5lbH0gKi9cblx0dmFyIGNoYW5uZWwgPSB7XG5cdFx0YXNzZXJ0OiBmdW5jdGlvbiAoa2V5KSB7XG5cdFx0XHRpZiAoIWNoYW5uZWwuaGFzKGtleSkpIHtcblx0XHRcdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ1NpZGUgY2hhbm5lbCBkb2VzIG5vdCBjb250YWluICcgKyBpbnNwZWN0KGtleSkpO1xuXHRcdFx0fVxuXHRcdH0sXG5cdFx0J2RlbGV0ZSc6IGZ1bmN0aW9uIChrZXkpIHtcblx0XHRcdHZhciBkZWxldGVkTm9kZSA9IGxpc3REZWxldGUoJG8sIGtleSk7XG5cdFx0XHRpZiAoZGVsZXRlZE5vZGUgJiYgJG8gJiYgISRvLm5leHQpIHtcblx0XHRcdFx0JG8gPSB2b2lkIHVuZGVmaW5lZDtcblx0XHRcdH1cblx0XHRcdHJldHVybiAhIWRlbGV0ZWROb2RlO1xuXHRcdH0sXG5cdFx0Z2V0OiBmdW5jdGlvbiAoa2V5KSB7XG5cdFx0XHRyZXR1cm4gbGlzdEdldCgkbywga2V5KTtcblx0XHR9LFxuXHRcdGhhczogZnVuY3Rpb24gKGtleSkge1xuXHRcdFx0cmV0dXJuIGxpc3RIYXMoJG8sIGtleSk7XG5cdFx0fSxcblx0XHRzZXQ6IGZ1bmN0aW9uIChrZXksIHZhbHVlKSB7XG5cdFx0XHRpZiAoISRvKSB7XG5cdFx0XHRcdC8vIEluaXRpYWxpemUgdGhlIGxpbmtlZCBsaXN0IGFzIGFuIGVtcHR5IG5vZGUsIHNvIHRoYXQgd2UgZG9uJ3QgaGF2ZSB0byBzcGVjaWFsLWNhc2UgaGFuZGxpbmcgb2YgdGhlIGZpcnN0IG5vZGU6IHdlIGNhbiBhbHdheXMgcmVmZXIgdG8gaXQgYXMgKHByZXZpb3VzIG5vZGUpLm5leHQsIGluc3RlYWQgb2Ygc29tZXRoaW5nIGxpa2UgKGxpc3QpLmhlYWRcblx0XHRcdFx0JG8gPSB7XG5cdFx0XHRcdFx0bmV4dDogdm9pZCB1bmRlZmluZWRcblx0XHRcdFx0fTtcblx0XHRcdH1cblx0XHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1leHRyYS1wYXJlbnNcblx0XHRcdGxpc3RTZXQoLyoqIEB0eXBlIHtOb25OdWxsYWJsZTx0eXBlb2YgJG8+fSAqLyAoJG8pLCBrZXksIHZhbHVlKTtcblx0XHR9XG5cdH07XG5cdHJldHVybiBjaGFubmVsO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcbnZhciBjYWxsQm91bmQgPSByZXF1aXJlKCdjYWxsLWJvdW5kJyk7XG52YXIgaW5zcGVjdCA9IHJlcXVpcmUoJ29iamVjdC1pbnNwZWN0Jyk7XG5cbnZhciAkVHlwZUVycm9yID0gcmVxdWlyZSgnZXMtZXJyb3JzL3R5cGUnKTtcbnZhciAkTWFwID0gR2V0SW50cmluc2ljKCclTWFwJScsIHRydWUpO1xuXG4vKiogQHR5cGUgezxLLCBWPih0aGlzQXJnOiBNYXA8SywgVj4sIGtleTogSykgPT4gVn0gKi9cbnZhciAkbWFwR2V0ID0gY2FsbEJvdW5kKCdNYXAucHJvdG90eXBlLmdldCcsIHRydWUpO1xuLyoqIEB0eXBlIHs8SywgVj4odGhpc0FyZzogTWFwPEssIFY+LCBrZXk6IEssIHZhbHVlOiBWKSA9PiB2b2lkfSAqL1xudmFyICRtYXBTZXQgPSBjYWxsQm91bmQoJ01hcC5wcm90b3R5cGUuc2V0JywgdHJ1ZSk7XG4vKiogQHR5cGUgezxLLCBWPih0aGlzQXJnOiBNYXA8SywgVj4sIGtleTogSykgPT4gYm9vbGVhbn0gKi9cbnZhciAkbWFwSGFzID0gY2FsbEJvdW5kKCdNYXAucHJvdG90eXBlLmhhcycsIHRydWUpO1xuLyoqIEB0eXBlIHs8SywgVj4odGhpc0FyZzogTWFwPEssIFY+LCBrZXk6IEspID0+IGJvb2xlYW59ICovXG52YXIgJG1hcERlbGV0ZSA9IGNhbGxCb3VuZCgnTWFwLnByb3RvdHlwZS5kZWxldGUnLCB0cnVlKTtcbi8qKiBAdHlwZSB7PEssIFY+KHRoaXNBcmc6IE1hcDxLLCBWPikgPT4gbnVtYmVyfSAqL1xudmFyICRtYXBTaXplID0gY2FsbEJvdW5kKCdNYXAucHJvdG90eXBlLnNpemUnLCB0cnVlKTtcblxuLyoqIEB0eXBlIHtpbXBvcnQoJy4nKX0gKi9cbm1vZHVsZS5leHBvcnRzID0gISEkTWFwICYmIC8qKiBAdHlwZSB7RXhjbHVkZTxpbXBvcnQoJy4nKSwgZmFsc2U+fSAqLyBmdW5jdGlvbiBnZXRTaWRlQ2hhbm5lbE1hcCgpIHtcblx0LyoqIEB0eXBlZGVmIHtSZXR1cm5UeXBlPHR5cGVvZiBnZXRTaWRlQ2hhbm5lbE1hcD59IENoYW5uZWwgKi9cblx0LyoqIEB0eXBlZGVmIHtQYXJhbWV0ZXJzPENoYW5uZWxbJ2dldCddPlswXX0gSyAqL1xuXHQvKiogQHR5cGVkZWYge1BhcmFtZXRlcnM8Q2hhbm5lbFsnc2V0J10+WzFdfSBWICovXG5cblx0LyoqIEB0eXBlIHtNYXA8SywgVj4gfCB1bmRlZmluZWR9ICovIHZhciAkbTtcblxuXHQvKiogQHR5cGUge0NoYW5uZWx9ICovXG5cdHZhciBjaGFubmVsID0ge1xuXHRcdGFzc2VydDogZnVuY3Rpb24gKGtleSkge1xuXHRcdFx0aWYgKCFjaGFubmVsLmhhcyhrZXkpKSB7XG5cdFx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdTaWRlIGNoYW5uZWwgZG9lcyBub3QgY29udGFpbiAnICsgaW5zcGVjdChrZXkpKTtcblx0XHRcdH1cblx0XHR9LFxuXHRcdCdkZWxldGUnOiBmdW5jdGlvbiAoa2V5KSB7XG5cdFx0XHRpZiAoJG0pIHtcblx0XHRcdFx0dmFyIHJlc3VsdCA9ICRtYXBEZWxldGUoJG0sIGtleSk7XG5cdFx0XHRcdGlmICgkbWFwU2l6ZSgkbSkgPT09IDApIHtcblx0XHRcdFx0XHQkbSA9IHZvaWQgdW5kZWZpbmVkO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiByZXN1bHQ7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fSxcblx0XHRnZXQ6IGZ1bmN0aW9uIChrZXkpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBjb25zaXN0ZW50LXJldHVyblxuXHRcdFx0aWYgKCRtKSB7XG5cdFx0XHRcdHJldHVybiAkbWFwR2V0KCRtLCBrZXkpO1xuXHRcdFx0fVxuXHRcdH0sXG5cdFx0aGFzOiBmdW5jdGlvbiAoa2V5KSB7XG5cdFx0XHRpZiAoJG0pIHtcblx0XHRcdFx0cmV0dXJuICRtYXBIYXMoJG0sIGtleSk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fSxcblx0XHRzZXQ6IGZ1bmN0aW9uIChrZXksIHZhbHVlKSB7XG5cdFx0XHRpZiAoISRtKSB7XG5cdFx0XHRcdC8vIEB0cy1leHBlY3QtZXJyb3IgVFMgY2FuJ3QgaGFuZGxlIG5hcnJvd2luZyBhIHZhcmlhYmxlIGluc2lkZSBhIGNsb3N1cmVcblx0XHRcdFx0JG0gPSBuZXcgJE1hcCgpO1xuXHRcdFx0fVxuXHRcdFx0JG1hcFNldCgkbSwga2V5LCB2YWx1ZSk7XG5cdFx0fVxuXHR9O1xuXG5cdC8vIEB0cy1leHBlY3QtZXJyb3IgVE9ETzogZmlndXJlIG91dCB3aHkgVFMgaXMgZXJyb3JpbmcgaGVyZVxuXHRyZXR1cm4gY2hhbm5lbDtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBHZXRJbnRyaW5zaWMgPSByZXF1aXJlKCdnZXQtaW50cmluc2ljJyk7XG52YXIgY2FsbEJvdW5kID0gcmVxdWlyZSgnY2FsbC1ib3VuZCcpO1xudmFyIGluc3BlY3QgPSByZXF1aXJlKCdvYmplY3QtaW5zcGVjdCcpO1xudmFyIGdldFNpZGVDaGFubmVsTWFwID0gcmVxdWlyZSgnc2lkZS1jaGFubmVsLW1hcCcpO1xuXG52YXIgJFR5cGVFcnJvciA9IHJlcXVpcmUoJ2VzLWVycm9ycy90eXBlJyk7XG52YXIgJFdlYWtNYXAgPSBHZXRJbnRyaW5zaWMoJyVXZWFrTWFwJScsIHRydWUpO1xuXG4vKiogQHR5cGUgezxLIGV4dGVuZHMgb2JqZWN0LCBWPih0aGlzQXJnOiBXZWFrTWFwPEssIFY+LCBrZXk6IEspID0+IFZ9ICovXG52YXIgJHdlYWtNYXBHZXQgPSBjYWxsQm91bmQoJ1dlYWtNYXAucHJvdG90eXBlLmdldCcsIHRydWUpO1xuLyoqIEB0eXBlIHs8SyBleHRlbmRzIG9iamVjdCwgVj4odGhpc0FyZzogV2Vha01hcDxLLCBWPiwga2V5OiBLLCB2YWx1ZTogVikgPT4gdm9pZH0gKi9cbnZhciAkd2Vha01hcFNldCA9IGNhbGxCb3VuZCgnV2Vha01hcC5wcm90b3R5cGUuc2V0JywgdHJ1ZSk7XG4vKiogQHR5cGUgezxLIGV4dGVuZHMgb2JqZWN0LCBWPih0aGlzQXJnOiBXZWFrTWFwPEssIFY+LCBrZXk6IEspID0+IGJvb2xlYW59ICovXG52YXIgJHdlYWtNYXBIYXMgPSBjYWxsQm91bmQoJ1dlYWtNYXAucHJvdG90eXBlLmhhcycsIHRydWUpO1xuLyoqIEB0eXBlIHs8SyBleHRlbmRzIG9iamVjdCwgVj4odGhpc0FyZzogV2Vha01hcDxLLCBWPiwga2V5OiBLKSA9PiBib29sZWFufSAqL1xudmFyICR3ZWFrTWFwRGVsZXRlID0gY2FsbEJvdW5kKCdXZWFrTWFwLnByb3RvdHlwZS5kZWxldGUnLCB0cnVlKTtcblxuLyoqIEB0eXBlIHtpbXBvcnQoJy4nKX0gKi9cbm1vZHVsZS5leHBvcnRzID0gJFdlYWtNYXBcblx0PyAvKiogQHR5cGUge0V4Y2x1ZGU8aW1wb3J0KCcuJyksIGZhbHNlPn0gKi8gZnVuY3Rpb24gZ2V0U2lkZUNoYW5uZWxXZWFrTWFwKCkge1xuXHRcdC8qKiBAdHlwZWRlZiB7UmV0dXJuVHlwZTx0eXBlb2YgZ2V0U2lkZUNoYW5uZWxXZWFrTWFwPn0gQ2hhbm5lbCAqL1xuXHRcdC8qKiBAdHlwZWRlZiB7UGFyYW1ldGVyczxDaGFubmVsWydnZXQnXT5bMF19IEsgKi9cblx0XHQvKiogQHR5cGVkZWYge1BhcmFtZXRlcnM8Q2hhbm5lbFsnc2V0J10+WzFdfSBWICovXG5cblx0XHQvKiogQHR5cGUge1dlYWtNYXA8SyAmIG9iamVjdCwgVj4gfCB1bmRlZmluZWR9ICovIHZhciAkd207XG5cdFx0LyoqIEB0eXBlIHtDaGFubmVsIHwgdW5kZWZpbmVkfSAqLyB2YXIgJG07XG5cblx0XHQvKiogQHR5cGUge0NoYW5uZWx9ICovXG5cdFx0dmFyIGNoYW5uZWwgPSB7XG5cdFx0XHRhc3NlcnQ6IGZ1bmN0aW9uIChrZXkpIHtcblx0XHRcdFx0aWYgKCFjaGFubmVsLmhhcyhrZXkpKSB7XG5cdFx0XHRcdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ1NpZGUgY2hhbm5lbCBkb2VzIG5vdCBjb250YWluICcgKyBpbnNwZWN0KGtleSkpO1xuXHRcdFx0XHR9XG5cdFx0XHR9LFxuXHRcdFx0J2RlbGV0ZSc6IGZ1bmN0aW9uIChrZXkpIHtcblx0XHRcdFx0aWYgKCRXZWFrTWFwICYmIGtleSAmJiAodHlwZW9mIGtleSA9PT0gJ29iamVjdCcgfHwgdHlwZW9mIGtleSA9PT0gJ2Z1bmN0aW9uJykpIHtcblx0XHRcdFx0XHRpZiAoJHdtKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gJHdlYWtNYXBEZWxldGUoJHdtLCBrZXkpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSBlbHNlIGlmIChnZXRTaWRlQ2hhbm5lbE1hcCkge1xuXHRcdFx0XHRcdGlmICgkbSkge1xuXHRcdFx0XHRcdFx0cmV0dXJuICRtWydkZWxldGUnXShrZXkpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHR9LFxuXHRcdFx0Z2V0OiBmdW5jdGlvbiAoa2V5KSB7XG5cdFx0XHRcdGlmICgkV2Vha01hcCAmJiBrZXkgJiYgKHR5cGVvZiBrZXkgPT09ICdvYmplY3QnIHx8IHR5cGVvZiBrZXkgPT09ICdmdW5jdGlvbicpKSB7XG5cdFx0XHRcdFx0aWYgKCR3bSkge1xuXHRcdFx0XHRcdFx0cmV0dXJuICR3ZWFrTWFwR2V0KCR3bSwga2V5KTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuICRtICYmICRtLmdldChrZXkpO1xuXHRcdFx0fSxcblx0XHRcdGhhczogZnVuY3Rpb24gKGtleSkge1xuXHRcdFx0XHRpZiAoJFdlYWtNYXAgJiYga2V5ICYmICh0eXBlb2Yga2V5ID09PSAnb2JqZWN0JyB8fCB0eXBlb2Yga2V5ID09PSAnZnVuY3Rpb24nKSkge1xuXHRcdFx0XHRcdGlmICgkd20pIHtcblx0XHRcdFx0XHRcdHJldHVybiAkd2Vha01hcEhhcygkd20sIGtleSk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiAhISRtICYmICRtLmhhcyhrZXkpO1xuXHRcdFx0fSxcblx0XHRcdHNldDogZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcblx0XHRcdFx0aWYgKCRXZWFrTWFwICYmIGtleSAmJiAodHlwZW9mIGtleSA9PT0gJ29iamVjdCcgfHwgdHlwZW9mIGtleSA9PT0gJ2Z1bmN0aW9uJykpIHtcblx0XHRcdFx0XHRpZiAoISR3bSkge1xuXHRcdFx0XHRcdFx0JHdtID0gbmV3ICRXZWFrTWFwKCk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdCR3ZWFrTWFwU2V0KCR3bSwga2V5LCB2YWx1ZSk7XG5cdFx0XHRcdH0gZWxzZSBpZiAoZ2V0U2lkZUNoYW5uZWxNYXApIHtcblx0XHRcdFx0XHRpZiAoISRtKSB7XG5cdFx0XHRcdFx0XHQkbSA9IGdldFNpZGVDaGFubmVsTWFwKCk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1leHRyYS1wYXJlbnNcblx0XHRcdFx0XHQvKiogQHR5cGUge05vbk51bGxhYmxlPHR5cGVvZiAkbT59ICovICgkbSkuc2V0KGtleSwgdmFsdWUpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fTtcblxuXHRcdC8vIEB0cy1leHBlY3QtZXJyb3IgVE9ETzogZmlndXJlIG91dCB3aHkgdGhpcyBpcyBlcnJvcmluZ1xuXHRcdHJldHVybiBjaGFubmVsO1xuXHR9XG5cdDogZ2V0U2lkZUNoYW5uZWxNYXA7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciAkVHlwZUVycm9yID0gcmVxdWlyZSgnZXMtZXJyb3JzL3R5cGUnKTtcbnZhciBpbnNwZWN0ID0gcmVxdWlyZSgnb2JqZWN0LWluc3BlY3QnKTtcbnZhciBnZXRTaWRlQ2hhbm5lbExpc3QgPSByZXF1aXJlKCdzaWRlLWNoYW5uZWwtbGlzdCcpO1xudmFyIGdldFNpZGVDaGFubmVsTWFwID0gcmVxdWlyZSgnc2lkZS1jaGFubmVsLW1hcCcpO1xudmFyIGdldFNpZGVDaGFubmVsV2Vha01hcCA9IHJlcXVpcmUoJ3NpZGUtY2hhbm5lbC13ZWFrbWFwJyk7XG5cbnZhciBtYWtlQ2hhbm5lbCA9IGdldFNpZGVDaGFubmVsV2Vha01hcCB8fCBnZXRTaWRlQ2hhbm5lbE1hcCB8fCBnZXRTaWRlQ2hhbm5lbExpc3Q7XG5cbi8qKiBAdHlwZSB7aW1wb3J0KCcuJyl9ICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGdldFNpZGVDaGFubmVsKCkge1xuXHQvKiogQHR5cGVkZWYge1JldHVyblR5cGU8dHlwZW9mIGdldFNpZGVDaGFubmVsPn0gQ2hhbm5lbCAqL1xuXG5cdC8qKiBAdHlwZSB7Q2hhbm5lbCB8IHVuZGVmaW5lZH0gKi8gdmFyICRjaGFubmVsRGF0YTtcblxuXHQvKiogQHR5cGUge0NoYW5uZWx9ICovXG5cdHZhciBjaGFubmVsID0ge1xuXHRcdGFzc2VydDogZnVuY3Rpb24gKGtleSkge1xuXHRcdFx0aWYgKCFjaGFubmVsLmhhcyhrZXkpKSB7XG5cdFx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdTaWRlIGNoYW5uZWwgZG9lcyBub3QgY29udGFpbiAnICsgaW5zcGVjdChrZXkpKTtcblx0XHRcdH1cblx0XHR9LFxuXHRcdCdkZWxldGUnOiBmdW5jdGlvbiAoa2V5KSB7XG5cdFx0XHRyZXR1cm4gISEkY2hhbm5lbERhdGEgJiYgJGNoYW5uZWxEYXRhWydkZWxldGUnXShrZXkpO1xuXHRcdH0sXG5cdFx0Z2V0OiBmdW5jdGlvbiAoa2V5KSB7XG5cdFx0XHRyZXR1cm4gJGNoYW5uZWxEYXRhICYmICRjaGFubmVsRGF0YS5nZXQoa2V5KTtcblx0XHR9LFxuXHRcdGhhczogZnVuY3Rpb24gKGtleSkge1xuXHRcdFx0cmV0dXJuICEhJGNoYW5uZWxEYXRhICYmICRjaGFubmVsRGF0YS5oYXMoa2V5KTtcblx0XHR9LFxuXHRcdHNldDogZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcblx0XHRcdGlmICghJGNoYW5uZWxEYXRhKSB7XG5cdFx0XHRcdCRjaGFubmVsRGF0YSA9IG1ha2VDaGFubmVsKCk7XG5cdFx0XHR9XG5cblx0XHRcdCRjaGFubmVsRGF0YS5zZXQoa2V5LCB2YWx1ZSk7XG5cdFx0fVxuXHR9O1xuXHQvLyBAdHMtZXhwZWN0LWVycm9yIFRPRE86IGZpZ3VyZSBvdXQgd2h5IHRoaXMgaXMgZXJyb3Jpbmdcblx0cmV0dXJuIGNoYW5uZWw7XG59O1xuIiwidmFyIENsaWVudFJlcXVlc3QgPSByZXF1aXJlKCcuL2xpYi9yZXF1ZXN0JylcbnZhciByZXNwb25zZSA9IHJlcXVpcmUoJy4vbGliL3Jlc3BvbnNlJylcbnZhciBleHRlbmQgPSByZXF1aXJlKCd4dGVuZCcpXG52YXIgc3RhdHVzQ29kZXMgPSByZXF1aXJlKCdidWlsdGluLXN0YXR1cy1jb2RlcycpXG52YXIgdXJsID0gcmVxdWlyZSgndXJsJylcblxudmFyIGh0dHAgPSBleHBvcnRzXG5cbmh0dHAucmVxdWVzdCA9IGZ1bmN0aW9uIChvcHRzLCBjYikge1xuXHRpZiAodHlwZW9mIG9wdHMgPT09ICdzdHJpbmcnKVxuXHRcdG9wdHMgPSB1cmwucGFyc2Uob3B0cylcblx0ZWxzZVxuXHRcdG9wdHMgPSBleHRlbmQob3B0cylcblxuXHQvLyBOb3JtYWxseSwgdGhlIHBhZ2UgaXMgbG9hZGVkIGZyb20gaHR0cCBvciBodHRwcywgc28gbm90IHNwZWNpZnlpbmcgYSBwcm90b2NvbFxuXHQvLyB3aWxsIHJlc3VsdCBpbiBhICh2YWxpZCkgcHJvdG9jb2wtcmVsYXRpdmUgdXJsLiBIb3dldmVyLCB0aGlzIHdvbid0IHdvcmsgaWZcblx0Ly8gdGhlIHByb3RvY29sIGlzIHNvbWV0aGluZyBlbHNlLCBsaWtlICdmaWxlOidcblx0dmFyIGRlZmF1bHRQcm90b2NvbCA9IGdsb2JhbC5sb2NhdGlvbi5wcm90b2NvbC5zZWFyY2goL15odHRwcz86JC8pID09PSAtMSA/ICdodHRwOicgOiAnJ1xuXG5cdHZhciBwcm90b2NvbCA9IG9wdHMucHJvdG9jb2wgfHwgZGVmYXVsdFByb3RvY29sXG5cdHZhciBob3N0ID0gb3B0cy5ob3N0bmFtZSB8fCBvcHRzLmhvc3Rcblx0dmFyIHBvcnQgPSBvcHRzLnBvcnRcblx0dmFyIHBhdGggPSBvcHRzLnBhdGggfHwgJy8nXG5cblx0Ly8gTmVjZXNzYXJ5IGZvciBJUHY2IGFkZHJlc3Nlc1xuXHRpZiAoaG9zdCAmJiBob3N0LmluZGV4T2YoJzonKSAhPT0gLTEpXG5cdFx0aG9zdCA9ICdbJyArIGhvc3QgKyAnXSdcblxuXHQvLyBUaGlzIG1heSBiZSBhIHJlbGF0aXZlIHVybC4gVGhlIGJyb3dzZXIgc2hvdWxkIGFsd2F5cyBiZSBhYmxlIHRvIGludGVycHJldCBpdCBjb3JyZWN0bHkuXG5cdG9wdHMudXJsID0gKGhvc3QgPyAocHJvdG9jb2wgKyAnLy8nICsgaG9zdCkgOiAnJykgKyAocG9ydCA/ICc6JyArIHBvcnQgOiAnJykgKyBwYXRoXG5cdG9wdHMubWV0aG9kID0gKG9wdHMubWV0aG9kIHx8ICdHRVQnKS50b1VwcGVyQ2FzZSgpXG5cdG9wdHMuaGVhZGVycyA9IG9wdHMuaGVhZGVycyB8fCB7fVxuXG5cdC8vIEFsc28gdmFsaWQgb3B0cy5hdXRoLCBvcHRzLm1vZGVcblxuXHR2YXIgcmVxID0gbmV3IENsaWVudFJlcXVlc3Qob3B0cylcblx0aWYgKGNiKVxuXHRcdHJlcS5vbigncmVzcG9uc2UnLCBjYilcblx0cmV0dXJuIHJlcVxufVxuXG5odHRwLmdldCA9IGZ1bmN0aW9uIGdldCAob3B0cywgY2IpIHtcblx0dmFyIHJlcSA9IGh0dHAucmVxdWVzdChvcHRzLCBjYilcblx0cmVxLmVuZCgpXG5cdHJldHVybiByZXFcbn1cblxuaHR0cC5DbGllbnRSZXF1ZXN0ID0gQ2xpZW50UmVxdWVzdFxuaHR0cC5JbmNvbWluZ01lc3NhZ2UgPSByZXNwb25zZS5JbmNvbWluZ01lc3NhZ2VcblxuaHR0cC5BZ2VudCA9IGZ1bmN0aW9uICgpIHt9XG5odHRwLkFnZW50LmRlZmF1bHRNYXhTb2NrZXRzID0gNFxuXG5odHRwLmdsb2JhbEFnZW50ID0gbmV3IGh0dHAuQWdlbnQoKVxuXG5odHRwLlNUQVRVU19DT0RFUyA9IHN0YXR1c0NvZGVzXG5cbmh0dHAuTUVUSE9EUyA9IFtcblx0J0NIRUNLT1VUJyxcblx0J0NPTk5FQ1QnLFxuXHQnQ09QWScsXG5cdCdERUxFVEUnLFxuXHQnR0VUJyxcblx0J0hFQUQnLFxuXHQnTE9DSycsXG5cdCdNLVNFQVJDSCcsXG5cdCdNRVJHRScsXG5cdCdNS0FDVElWSVRZJyxcblx0J01LQ09MJyxcblx0J01PVkUnLFxuXHQnTk9USUZZJyxcblx0J09QVElPTlMnLFxuXHQnUEFUQ0gnLFxuXHQnUE9TVCcsXG5cdCdQUk9QRklORCcsXG5cdCdQUk9QUEFUQ0gnLFxuXHQnUFVSR0UnLFxuXHQnUFVUJyxcblx0J1JFUE9SVCcsXG5cdCdTRUFSQ0gnLFxuXHQnU1VCU0NSSUJFJyxcblx0J1RSQUNFJyxcblx0J1VOTE9DSycsXG5cdCdVTlNVQlNDUklCRSdcbl0iLCJleHBvcnRzLmZldGNoID0gaXNGdW5jdGlvbihnbG9iYWwuZmV0Y2gpICYmIGlzRnVuY3Rpb24oZ2xvYmFsLlJlYWRhYmxlU3RyZWFtKVxuXG5leHBvcnRzLndyaXRhYmxlU3RyZWFtID0gaXNGdW5jdGlvbihnbG9iYWwuV3JpdGFibGVTdHJlYW0pXG5cbmV4cG9ydHMuYWJvcnRDb250cm9sbGVyID0gaXNGdW5jdGlvbihnbG9iYWwuQWJvcnRDb250cm9sbGVyKVxuXG4vLyBUaGUgeGhyIHJlcXVlc3QgdG8gZXhhbXBsZS5jb20gbWF5IHZpb2xhdGUgc29tZSByZXN0cmljdGl2ZSBDU1AgY29uZmlndXJhdGlvbnMsXG4vLyBzbyBpZiB3ZSdyZSBydW5uaW5nIGluIGEgYnJvd3NlciB0aGF0IHN1cHBvcnRzIGBmZXRjaGAsIGF2b2lkIGNhbGxpbmcgZ2V0WEhSKClcbi8vIGFuZCBhc3N1bWUgc3VwcG9ydCBmb3IgY2VydGFpbiBmZWF0dXJlcyBiZWxvdy5cbnZhciB4aHJcbmZ1bmN0aW9uIGdldFhIUiAoKSB7XG5cdC8vIENhY2hlIHRoZSB4aHIgdmFsdWVcblx0aWYgKHhociAhPT0gdW5kZWZpbmVkKSByZXR1cm4geGhyXG5cblx0aWYgKGdsb2JhbC5YTUxIdHRwUmVxdWVzdCkge1xuXHRcdHhociA9IG5ldyBnbG9iYWwuWE1MSHR0cFJlcXVlc3QoKVxuXHRcdC8vIElmIFhEb21haW5SZXF1ZXN0IGlzIGF2YWlsYWJsZSAoaWUgb25seSwgd2hlcmUgeGhyIG1pZ2h0IG5vdCB3b3JrXG5cdFx0Ly8gY3Jvc3MgZG9tYWluKSwgdXNlIHRoZSBwYWdlIGxvY2F0aW9uLiBPdGhlcndpc2UgdXNlIGV4YW1wbGUuY29tXG5cdFx0Ly8gTm90ZTogdGhpcyBkb2Vzbid0IGFjdHVhbGx5IG1ha2UgYW4gaHR0cCByZXF1ZXN0LlxuXHRcdHRyeSB7XG5cdFx0XHR4aHIub3BlbignR0VUJywgZ2xvYmFsLlhEb21haW5SZXF1ZXN0ID8gJy8nIDogJ2h0dHBzOi8vZXhhbXBsZS5jb20nKVxuXHRcdH0gY2F0Y2goZSkge1xuXHRcdFx0eGhyID0gbnVsbFxuXHRcdH1cblx0fSBlbHNlIHtcblx0XHQvLyBTZXJ2aWNlIHdvcmtlcnMgZG9uJ3QgaGF2ZSBYSFJcblx0XHR4aHIgPSBudWxsXG5cdH1cblx0cmV0dXJuIHhoclxufVxuXG5mdW5jdGlvbiBjaGVja1R5cGVTdXBwb3J0ICh0eXBlKSB7XG5cdHZhciB4aHIgPSBnZXRYSFIoKVxuXHRpZiAoIXhocikgcmV0dXJuIGZhbHNlXG5cdHRyeSB7XG5cdFx0eGhyLnJlc3BvbnNlVHlwZSA9IHR5cGVcblx0XHRyZXR1cm4geGhyLnJlc3BvbnNlVHlwZSA9PT0gdHlwZVxuXHR9IGNhdGNoIChlKSB7fVxuXHRyZXR1cm4gZmFsc2Vcbn1cblxuLy8gSWYgZmV0Y2ggaXMgc3VwcG9ydGVkLCB0aGVuIGFycmF5YnVmZmVyIHdpbGwgYmUgc3VwcG9ydGVkIHRvby4gU2tpcCBjYWxsaW5nXG4vLyBjaGVja1R5cGVTdXBwb3J0KCksIHNpbmNlIHRoYXQgY2FsbHMgZ2V0WEhSKCkuXG5leHBvcnRzLmFycmF5YnVmZmVyID0gZXhwb3J0cy5mZXRjaCB8fCBjaGVja1R5cGVTdXBwb3J0KCdhcnJheWJ1ZmZlcicpXG5cbi8vIFRoZXNlIG5leHQgdHdvIHRlc3RzIHVuYXZvaWRhYmx5IHNob3cgd2FybmluZ3MgaW4gQ2hyb21lLiBTaW5jZSBmZXRjaCB3aWxsIGFsd2F5c1xuLy8gYmUgdXNlZCBpZiBpdCdzIGF2YWlsYWJsZSwganVzdCByZXR1cm4gZmFsc2UgZm9yIHRoZXNlIHRvIGF2b2lkIHRoZSB3YXJuaW5ncy5cbmV4cG9ydHMubXNzdHJlYW0gPSAhZXhwb3J0cy5mZXRjaCAmJiBjaGVja1R5cGVTdXBwb3J0KCdtcy1zdHJlYW0nKVxuZXhwb3J0cy5tb3pjaHVua2VkYXJyYXlidWZmZXIgPSAhZXhwb3J0cy5mZXRjaCAmJiBjaGVja1R5cGVTdXBwb3J0KCdtb3otY2h1bmtlZC1hcnJheWJ1ZmZlcicpXG5cbi8vIElmIGZldGNoIGlzIHN1cHBvcnRlZCwgdGhlbiBvdmVycmlkZU1pbWVUeXBlIHdpbGwgYmUgc3VwcG9ydGVkIHRvby4gU2tpcCBjYWxsaW5nXG4vLyBnZXRYSFIoKS5cbmV4cG9ydHMub3ZlcnJpZGVNaW1lVHlwZSA9IGV4cG9ydHMuZmV0Y2ggfHwgKGdldFhIUigpID8gaXNGdW5jdGlvbihnZXRYSFIoKS5vdmVycmlkZU1pbWVUeXBlKSA6IGZhbHNlKVxuXG5mdW5jdGlvbiBpc0Z1bmN0aW9uICh2YWx1ZSkge1xuXHRyZXR1cm4gdHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nXG59XG5cbnhociA9IG51bGwgLy8gSGVscCBnY1xuIiwidmFyIGNhcGFiaWxpdHkgPSByZXF1aXJlKCcuL2NhcGFiaWxpdHknKVxudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxudmFyIHJlc3BvbnNlID0gcmVxdWlyZSgnLi9yZXNwb25zZScpXG52YXIgc3RyZWFtID0gcmVxdWlyZSgncmVhZGFibGUtc3RyZWFtJylcblxudmFyIEluY29taW5nTWVzc2FnZSA9IHJlc3BvbnNlLkluY29taW5nTWVzc2FnZVxudmFyIHJTdGF0ZXMgPSByZXNwb25zZS5yZWFkeVN0YXRlc1xuXG5mdW5jdGlvbiBkZWNpZGVNb2RlIChwcmVmZXJCaW5hcnksIHVzZUZldGNoKSB7XG5cdGlmIChjYXBhYmlsaXR5LmZldGNoICYmIHVzZUZldGNoKSB7XG5cdFx0cmV0dXJuICdmZXRjaCdcblx0fSBlbHNlIGlmIChjYXBhYmlsaXR5Lm1vemNodW5rZWRhcnJheWJ1ZmZlcikge1xuXHRcdHJldHVybiAnbW96LWNodW5rZWQtYXJyYXlidWZmZXInXG5cdH0gZWxzZSBpZiAoY2FwYWJpbGl0eS5tc3N0cmVhbSkge1xuXHRcdHJldHVybiAnbXMtc3RyZWFtJ1xuXHR9IGVsc2UgaWYgKGNhcGFiaWxpdHkuYXJyYXlidWZmZXIgJiYgcHJlZmVyQmluYXJ5KSB7XG5cdFx0cmV0dXJuICdhcnJheWJ1ZmZlcidcblx0fSBlbHNlIHtcblx0XHRyZXR1cm4gJ3RleHQnXG5cdH1cbn1cblxudmFyIENsaWVudFJlcXVlc3QgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChvcHRzKSB7XG5cdHZhciBzZWxmID0gdGhpc1xuXHRzdHJlYW0uV3JpdGFibGUuY2FsbChzZWxmKVxuXG5cdHNlbGYuX29wdHMgPSBvcHRzXG5cdHNlbGYuX2JvZHkgPSBbXVxuXHRzZWxmLl9oZWFkZXJzID0ge31cblx0aWYgKG9wdHMuYXV0aClcblx0XHRzZWxmLnNldEhlYWRlcignQXV0aG9yaXphdGlvbicsICdCYXNpYyAnICsgQnVmZmVyLmZyb20ob3B0cy5hdXRoKS50b1N0cmluZygnYmFzZTY0JykpXG5cdE9iamVjdC5rZXlzKG9wdHMuaGVhZGVycykuZm9yRWFjaChmdW5jdGlvbiAobmFtZSkge1xuXHRcdHNlbGYuc2V0SGVhZGVyKG5hbWUsIG9wdHMuaGVhZGVyc1tuYW1lXSlcblx0fSlcblxuXHR2YXIgcHJlZmVyQmluYXJ5XG5cdHZhciB1c2VGZXRjaCA9IHRydWVcblx0aWYgKG9wdHMubW9kZSA9PT0gJ2Rpc2FibGUtZmV0Y2gnIHx8ICgncmVxdWVzdFRpbWVvdXQnIGluIG9wdHMgJiYgIWNhcGFiaWxpdHkuYWJvcnRDb250cm9sbGVyKSkge1xuXHRcdC8vIElmIHRoZSB1c2Ugb2YgWEhSIHNob3VsZCBiZSBwcmVmZXJyZWQuIE5vdCB0eXBpY2FsbHkgbmVlZGVkLlxuXHRcdHVzZUZldGNoID0gZmFsc2Vcblx0XHRwcmVmZXJCaW5hcnkgPSB0cnVlXG5cdH0gZWxzZSBpZiAob3B0cy5tb2RlID09PSAncHJlZmVyLXN0cmVhbWluZycpIHtcblx0XHQvLyBJZiBzdHJlYW1pbmcgaXMgYSBoaWdoIHByaW9yaXR5IGJ1dCBiaW5hcnkgY29tcGF0aWJpbGl0eSBhbmRcblx0XHQvLyB0aGUgYWNjdXJhY3kgb2YgdGhlICdjb250ZW50LXR5cGUnIGhlYWRlciBhcmVuJ3Rcblx0XHRwcmVmZXJCaW5hcnkgPSBmYWxzZVxuXHR9IGVsc2UgaWYgKG9wdHMubW9kZSA9PT0gJ2FsbG93LXdyb25nLWNvbnRlbnQtdHlwZScpIHtcblx0XHQvLyBJZiBzdHJlYW1pbmcgaXMgbW9yZSBpbXBvcnRhbnQgdGhhbiBwcmVzZXJ2aW5nIHRoZSAnY29udGVudC10eXBlJyBoZWFkZXJcblx0XHRwcmVmZXJCaW5hcnkgPSAhY2FwYWJpbGl0eS5vdmVycmlkZU1pbWVUeXBlXG5cdH0gZWxzZSBpZiAoIW9wdHMubW9kZSB8fCBvcHRzLm1vZGUgPT09ICdkZWZhdWx0JyB8fCBvcHRzLm1vZGUgPT09ICdwcmVmZXItZmFzdCcpIHtcblx0XHQvLyBVc2UgYmluYXJ5IGlmIHRleHQgc3RyZWFtaW5nIG1heSBjb3JydXB0IGRhdGEgb3IgdGhlIGNvbnRlbnQtdHlwZSBoZWFkZXIsIG9yIGZvciBzcGVlZFxuXHRcdHByZWZlckJpbmFyeSA9IHRydWVcblx0fSBlbHNlIHtcblx0XHR0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgdmFsdWUgZm9yIG9wdHMubW9kZScpXG5cdH1cblx0c2VsZi5fbW9kZSA9IGRlY2lkZU1vZGUocHJlZmVyQmluYXJ5LCB1c2VGZXRjaClcblx0c2VsZi5fZmV0Y2hUaW1lciA9IG51bGxcblx0c2VsZi5fc29ja2V0VGltZW91dCA9IG51bGxcblx0c2VsZi5fc29ja2V0VGltZXIgPSBudWxsXG5cblx0c2VsZi5vbignZmluaXNoJywgZnVuY3Rpb24gKCkge1xuXHRcdHNlbGYuX29uRmluaXNoKClcblx0fSlcbn1cblxuaW5oZXJpdHMoQ2xpZW50UmVxdWVzdCwgc3RyZWFtLldyaXRhYmxlKVxuXG5DbGllbnRSZXF1ZXN0LnByb3RvdHlwZS5zZXRIZWFkZXIgPSBmdW5jdGlvbiAobmFtZSwgdmFsdWUpIHtcblx0dmFyIHNlbGYgPSB0aGlzXG5cdHZhciBsb3dlck5hbWUgPSBuYW1lLnRvTG93ZXJDYXNlKClcblx0Ly8gVGhpcyBjaGVjayBpcyBub3QgbmVjZXNzYXJ5LCBidXQgaXQgcHJldmVudHMgd2FybmluZ3MgZnJvbSBicm93c2VycyBhYm91dCBzZXR0aW5nIHVuc2FmZVxuXHQvLyBoZWFkZXJzLiBUbyBiZSBob25lc3QgSSdtIG5vdCBlbnRpcmVseSBzdXJlIGhpZGluZyB0aGVzZSB3YXJuaW5ncyBpcyBhIGdvb2QgdGhpbmcsIGJ1dFxuXHQvLyBodHRwLWJyb3dzZXJpZnkgZGlkIGl0LCBzbyBJIHdpbGwgdG9vLlxuXHRpZiAodW5zYWZlSGVhZGVycy5pbmRleE9mKGxvd2VyTmFtZSkgIT09IC0xKVxuXHRcdHJldHVyblxuXG5cdHNlbGYuX2hlYWRlcnNbbG93ZXJOYW1lXSA9IHtcblx0XHRuYW1lOiBuYW1lLFxuXHRcdHZhbHVlOiB2YWx1ZVxuXHR9XG59XG5cbkNsaWVudFJlcXVlc3QucHJvdG90eXBlLmdldEhlYWRlciA9IGZ1bmN0aW9uIChuYW1lKSB7XG5cdHZhciBoZWFkZXIgPSB0aGlzLl9oZWFkZXJzW25hbWUudG9Mb3dlckNhc2UoKV1cblx0aWYgKGhlYWRlcilcblx0XHRyZXR1cm4gaGVhZGVyLnZhbHVlXG5cdHJldHVybiBudWxsXG59XG5cbkNsaWVudFJlcXVlc3QucHJvdG90eXBlLnJlbW92ZUhlYWRlciA9IGZ1bmN0aW9uIChuYW1lKSB7XG5cdHZhciBzZWxmID0gdGhpc1xuXHRkZWxldGUgc2VsZi5faGVhZGVyc1tuYW1lLnRvTG93ZXJDYXNlKCldXG59XG5cbkNsaWVudFJlcXVlc3QucHJvdG90eXBlLl9vbkZpbmlzaCA9IGZ1bmN0aW9uICgpIHtcblx0dmFyIHNlbGYgPSB0aGlzXG5cblx0aWYgKHNlbGYuX2Rlc3Ryb3llZClcblx0XHRyZXR1cm5cblx0dmFyIG9wdHMgPSBzZWxmLl9vcHRzXG5cblx0aWYgKCd0aW1lb3V0JyBpbiBvcHRzICYmIG9wdHMudGltZW91dCAhPT0gMCkge1xuXHRcdHNlbGYuc2V0VGltZW91dChvcHRzLnRpbWVvdXQpXG5cdH1cblxuXHR2YXIgaGVhZGVyc09iaiA9IHNlbGYuX2hlYWRlcnNcblx0dmFyIGJvZHkgPSBudWxsXG5cdGlmIChvcHRzLm1ldGhvZCAhPT0gJ0dFVCcgJiYgb3B0cy5tZXRob2QgIT09ICdIRUFEJykge1xuICAgICAgICBib2R5ID0gbmV3IEJsb2Ioc2VsZi5fYm9keSwge1xuICAgICAgICAgICAgdHlwZTogKGhlYWRlcnNPYmpbJ2NvbnRlbnQtdHlwZSddIHx8IHt9KS52YWx1ZSB8fCAnJ1xuICAgICAgICB9KTtcbiAgICB9XG5cblx0Ly8gY3JlYXRlIGZsYXR0ZW5lZCBsaXN0IG9mIGhlYWRlcnNcblx0dmFyIGhlYWRlcnNMaXN0ID0gW11cblx0T2JqZWN0LmtleXMoaGVhZGVyc09iaikuZm9yRWFjaChmdW5jdGlvbiAoa2V5TmFtZSkge1xuXHRcdHZhciBuYW1lID0gaGVhZGVyc09ialtrZXlOYW1lXS5uYW1lXG5cdFx0dmFyIHZhbHVlID0gaGVhZGVyc09ialtrZXlOYW1lXS52YWx1ZVxuXHRcdGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuXHRcdFx0dmFsdWUuZm9yRWFjaChmdW5jdGlvbiAodikge1xuXHRcdFx0XHRoZWFkZXJzTGlzdC5wdXNoKFtuYW1lLCB2XSlcblx0XHRcdH0pXG5cdFx0fSBlbHNlIHtcblx0XHRcdGhlYWRlcnNMaXN0LnB1c2goW25hbWUsIHZhbHVlXSlcblx0XHR9XG5cdH0pXG5cblx0aWYgKHNlbGYuX21vZGUgPT09ICdmZXRjaCcpIHtcblx0XHR2YXIgc2lnbmFsID0gbnVsbFxuXHRcdGlmIChjYXBhYmlsaXR5LmFib3J0Q29udHJvbGxlcikge1xuXHRcdFx0dmFyIGNvbnRyb2xsZXIgPSBuZXcgQWJvcnRDb250cm9sbGVyKClcblx0XHRcdHNpZ25hbCA9IGNvbnRyb2xsZXIuc2lnbmFsXG5cdFx0XHRzZWxmLl9mZXRjaEFib3J0Q29udHJvbGxlciA9IGNvbnRyb2xsZXJcblxuXHRcdFx0aWYgKCdyZXF1ZXN0VGltZW91dCcgaW4gb3B0cyAmJiBvcHRzLnJlcXVlc3RUaW1lb3V0ICE9PSAwKSB7XG5cdFx0XHRcdHNlbGYuX2ZldGNoVGltZXIgPSBnbG9iYWwuc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0c2VsZi5lbWl0KCdyZXF1ZXN0VGltZW91dCcpXG5cdFx0XHRcdFx0aWYgKHNlbGYuX2ZldGNoQWJvcnRDb250cm9sbGVyKVxuXHRcdFx0XHRcdFx0c2VsZi5fZmV0Y2hBYm9ydENvbnRyb2xsZXIuYWJvcnQoKVxuXHRcdFx0XHR9LCBvcHRzLnJlcXVlc3RUaW1lb3V0KVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGdsb2JhbC5mZXRjaChzZWxmLl9vcHRzLnVybCwge1xuXHRcdFx0bWV0aG9kOiBzZWxmLl9vcHRzLm1ldGhvZCxcblx0XHRcdGhlYWRlcnM6IGhlYWRlcnNMaXN0LFxuXHRcdFx0Ym9keTogYm9keSB8fCB1bmRlZmluZWQsXG5cdFx0XHRtb2RlOiAnY29ycycsXG5cdFx0XHRjcmVkZW50aWFsczogb3B0cy53aXRoQ3JlZGVudGlhbHMgPyAnaW5jbHVkZScgOiAnc2FtZS1vcmlnaW4nLFxuXHRcdFx0c2lnbmFsOiBzaWduYWxcblx0XHR9KS50aGVuKGZ1bmN0aW9uIChyZXNwb25zZSkge1xuXHRcdFx0c2VsZi5fZmV0Y2hSZXNwb25zZSA9IHJlc3BvbnNlXG5cdFx0XHRzZWxmLl9yZXNldFRpbWVycyhmYWxzZSlcblx0XHRcdHNlbGYuX2Nvbm5lY3QoKVxuXHRcdH0sIGZ1bmN0aW9uIChyZWFzb24pIHtcblx0XHRcdHNlbGYuX3Jlc2V0VGltZXJzKHRydWUpXG5cdFx0XHRpZiAoIXNlbGYuX2Rlc3Ryb3llZClcblx0XHRcdFx0c2VsZi5lbWl0KCdlcnJvcicsIHJlYXNvbilcblx0XHR9KVxuXHR9IGVsc2Uge1xuXHRcdHZhciB4aHIgPSBzZWxmLl94aHIgPSBuZXcgZ2xvYmFsLlhNTEh0dHBSZXF1ZXN0KClcblx0XHR0cnkge1xuXHRcdFx0eGhyLm9wZW4oc2VsZi5fb3B0cy5tZXRob2QsIHNlbGYuX29wdHMudXJsLCB0cnVlKVxuXHRcdH0gY2F0Y2ggKGVycikge1xuXHRcdFx0cHJvY2Vzcy5uZXh0VGljayhmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdHNlbGYuZW1pdCgnZXJyb3InLCBlcnIpXG5cdFx0XHR9KVxuXHRcdFx0cmV0dXJuXG5cdFx0fVxuXG5cdFx0Ly8gQ2FuJ3Qgc2V0IHJlc3BvbnNlVHlwZSBvbiByZWFsbHkgb2xkIGJyb3dzZXJzXG5cdFx0aWYgKCdyZXNwb25zZVR5cGUnIGluIHhocilcblx0XHRcdHhoci5yZXNwb25zZVR5cGUgPSBzZWxmLl9tb2RlXG5cblx0XHRpZiAoJ3dpdGhDcmVkZW50aWFscycgaW4geGhyKVxuXHRcdFx0eGhyLndpdGhDcmVkZW50aWFscyA9ICEhb3B0cy53aXRoQ3JlZGVudGlhbHNcblxuXHRcdGlmIChzZWxmLl9tb2RlID09PSAndGV4dCcgJiYgJ292ZXJyaWRlTWltZVR5cGUnIGluIHhocilcblx0XHRcdHhoci5vdmVycmlkZU1pbWVUeXBlKCd0ZXh0L3BsYWluOyBjaGFyc2V0PXgtdXNlci1kZWZpbmVkJylcblxuXHRcdGlmICgncmVxdWVzdFRpbWVvdXQnIGluIG9wdHMpIHtcblx0XHRcdHhoci50aW1lb3V0ID0gb3B0cy5yZXF1ZXN0VGltZW91dFxuXHRcdFx0eGhyLm9udGltZW91dCA9IGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0c2VsZi5lbWl0KCdyZXF1ZXN0VGltZW91dCcpXG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0aGVhZGVyc0xpc3QuZm9yRWFjaChmdW5jdGlvbiAoaGVhZGVyKSB7XG5cdFx0XHR4aHIuc2V0UmVxdWVzdEhlYWRlcihoZWFkZXJbMF0sIGhlYWRlclsxXSlcblx0XHR9KVxuXG5cdFx0c2VsZi5fcmVzcG9uc2UgPSBudWxsXG5cdFx0eGhyLm9ucmVhZHlzdGF0ZWNoYW5nZSA9IGZ1bmN0aW9uICgpIHtcblx0XHRcdHN3aXRjaCAoeGhyLnJlYWR5U3RhdGUpIHtcblx0XHRcdFx0Y2FzZSByU3RhdGVzLkxPQURJTkc6XG5cdFx0XHRcdGNhc2UgclN0YXRlcy5ET05FOlxuXHRcdFx0XHRcdHNlbGYuX29uWEhSUHJvZ3Jlc3MoKVxuXHRcdFx0XHRcdGJyZWFrXG5cdFx0XHR9XG5cdFx0fVxuXHRcdC8vIE5lY2Vzc2FyeSBmb3Igc3RyZWFtaW5nIGluIEZpcmVmb3gsIHNpbmNlIHhoci5yZXNwb25zZSBpcyBPTkxZIGRlZmluZWRcblx0XHQvLyBpbiBvbnByb2dyZXNzLCBub3QgaW4gb25yZWFkeXN0YXRlY2hhbmdlIHdpdGggeGhyLnJlYWR5U3RhdGUgPSAzXG5cdFx0aWYgKHNlbGYuX21vZGUgPT09ICdtb3otY2h1bmtlZC1hcnJheWJ1ZmZlcicpIHtcblx0XHRcdHhoci5vbnByb2dyZXNzID0gZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRzZWxmLl9vblhIUlByb2dyZXNzKClcblx0XHRcdH1cblx0XHR9XG5cblx0XHR4aHIub25lcnJvciA9IGZ1bmN0aW9uICgpIHtcblx0XHRcdGlmIChzZWxmLl9kZXN0cm95ZWQpXG5cdFx0XHRcdHJldHVyblxuXHRcdFx0c2VsZi5fcmVzZXRUaW1lcnModHJ1ZSlcblx0XHRcdHNlbGYuZW1pdCgnZXJyb3InLCBuZXcgRXJyb3IoJ1hIUiBlcnJvcicpKVxuXHRcdH1cblxuXHRcdHRyeSB7XG5cdFx0XHR4aHIuc2VuZChib2R5KVxuXHRcdH0gY2F0Y2ggKGVycikge1xuXHRcdFx0cHJvY2Vzcy5uZXh0VGljayhmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdHNlbGYuZW1pdCgnZXJyb3InLCBlcnIpXG5cdFx0XHR9KVxuXHRcdFx0cmV0dXJuXG5cdFx0fVxuXHR9XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIHhoci5zdGF0dXMgaXMgcmVhZGFibGUgYW5kIG5vbi16ZXJvLCBpbmRpY2F0aW5nIG5vIGVycm9yLlxuICogRXZlbiB0aG91Z2ggdGhlIHNwZWMgc2F5cyBpdCBzaG91bGQgYmUgYXZhaWxhYmxlIGluIHJlYWR5U3RhdGUgMyxcbiAqIGFjY2Vzc2luZyBpdCB0aHJvd3MgYW4gZXhjZXB0aW9uIGluIElFOFxuICovXG5mdW5jdGlvbiBzdGF0dXNWYWxpZCAoeGhyKSB7XG5cdHRyeSB7XG5cdFx0dmFyIHN0YXR1cyA9IHhoci5zdGF0dXNcblx0XHRyZXR1cm4gKHN0YXR1cyAhPT0gbnVsbCAmJiBzdGF0dXMgIT09IDApXG5cdH0gY2F0Y2ggKGUpIHtcblx0XHRyZXR1cm4gZmFsc2Vcblx0fVxufVxuXG5DbGllbnRSZXF1ZXN0LnByb3RvdHlwZS5fb25YSFJQcm9ncmVzcyA9IGZ1bmN0aW9uICgpIHtcblx0dmFyIHNlbGYgPSB0aGlzXG5cblx0c2VsZi5fcmVzZXRUaW1lcnMoZmFsc2UpXG5cblx0aWYgKCFzdGF0dXNWYWxpZChzZWxmLl94aHIpIHx8IHNlbGYuX2Rlc3Ryb3llZClcblx0XHRyZXR1cm5cblxuXHRpZiAoIXNlbGYuX3Jlc3BvbnNlKVxuXHRcdHNlbGYuX2Nvbm5lY3QoKVxuXG5cdHNlbGYuX3Jlc3BvbnNlLl9vblhIUlByb2dyZXNzKHNlbGYuX3Jlc2V0VGltZXJzLmJpbmQoc2VsZikpXG59XG5cbkNsaWVudFJlcXVlc3QucHJvdG90eXBlLl9jb25uZWN0ID0gZnVuY3Rpb24gKCkge1xuXHR2YXIgc2VsZiA9IHRoaXNcblxuXHRpZiAoc2VsZi5fZGVzdHJveWVkKVxuXHRcdHJldHVyblxuXG5cdHNlbGYuX3Jlc3BvbnNlID0gbmV3IEluY29taW5nTWVzc2FnZShzZWxmLl94aHIsIHNlbGYuX2ZldGNoUmVzcG9uc2UsIHNlbGYuX21vZGUsIHNlbGYuX3Jlc2V0VGltZXJzLmJpbmQoc2VsZikpXG5cdHNlbGYuX3Jlc3BvbnNlLm9uKCdlcnJvcicsIGZ1bmN0aW9uKGVycikge1xuXHRcdHNlbGYuZW1pdCgnZXJyb3InLCBlcnIpXG5cdH0pXG5cblx0c2VsZi5lbWl0KCdyZXNwb25zZScsIHNlbGYuX3Jlc3BvbnNlKVxufVxuXG5DbGllbnRSZXF1ZXN0LnByb3RvdHlwZS5fd3JpdGUgPSBmdW5jdGlvbiAoY2h1bmssIGVuY29kaW5nLCBjYikge1xuXHR2YXIgc2VsZiA9IHRoaXNcblxuXHRzZWxmLl9ib2R5LnB1c2goY2h1bmspXG5cdGNiKClcbn1cblxuQ2xpZW50UmVxdWVzdC5wcm90b3R5cGUuX3Jlc2V0VGltZXJzID0gZnVuY3Rpb24gKGRvbmUpIHtcblx0dmFyIHNlbGYgPSB0aGlzXG5cblx0Z2xvYmFsLmNsZWFyVGltZW91dChzZWxmLl9zb2NrZXRUaW1lcilcblx0c2VsZi5fc29ja2V0VGltZXIgPSBudWxsXG5cblx0aWYgKGRvbmUpIHtcblx0XHRnbG9iYWwuY2xlYXJUaW1lb3V0KHNlbGYuX2ZldGNoVGltZXIpXG5cdFx0c2VsZi5fZmV0Y2hUaW1lciA9IG51bGxcblx0fSBlbHNlIGlmIChzZWxmLl9zb2NrZXRUaW1lb3V0KSB7XG5cdFx0c2VsZi5fc29ja2V0VGltZXIgPSBnbG9iYWwuc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG5cdFx0XHRzZWxmLmVtaXQoJ3RpbWVvdXQnKVxuXHRcdH0sIHNlbGYuX3NvY2tldFRpbWVvdXQpXG5cdH1cbn1cblxuQ2xpZW50UmVxdWVzdC5wcm90b3R5cGUuYWJvcnQgPSBDbGllbnRSZXF1ZXN0LnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24gKGVycikge1xuXHR2YXIgc2VsZiA9IHRoaXNcblx0c2VsZi5fZGVzdHJveWVkID0gdHJ1ZVxuXHRzZWxmLl9yZXNldFRpbWVycyh0cnVlKVxuXHRpZiAoc2VsZi5fcmVzcG9uc2UpXG5cdFx0c2VsZi5fcmVzcG9uc2UuX2Rlc3Ryb3llZCA9IHRydWVcblx0aWYgKHNlbGYuX3hocilcblx0XHRzZWxmLl94aHIuYWJvcnQoKVxuXHRlbHNlIGlmIChzZWxmLl9mZXRjaEFib3J0Q29udHJvbGxlcilcblx0XHRzZWxmLl9mZXRjaEFib3J0Q29udHJvbGxlci5hYm9ydCgpXG5cblx0aWYgKGVycilcblx0XHRzZWxmLmVtaXQoJ2Vycm9yJywgZXJyKVxufVxuXG5DbGllbnRSZXF1ZXN0LnByb3RvdHlwZS5lbmQgPSBmdW5jdGlvbiAoZGF0YSwgZW5jb2RpbmcsIGNiKSB7XG5cdHZhciBzZWxmID0gdGhpc1xuXHRpZiAodHlwZW9mIGRhdGEgPT09ICdmdW5jdGlvbicpIHtcblx0XHRjYiA9IGRhdGFcblx0XHRkYXRhID0gdW5kZWZpbmVkXG5cdH1cblxuXHRzdHJlYW0uV3JpdGFibGUucHJvdG90eXBlLmVuZC5jYWxsKHNlbGYsIGRhdGEsIGVuY29kaW5nLCBjYilcbn1cblxuQ2xpZW50UmVxdWVzdC5wcm90b3R5cGUuc2V0VGltZW91dCA9IGZ1bmN0aW9uICh0aW1lb3V0LCBjYikge1xuXHR2YXIgc2VsZiA9IHRoaXNcblxuXHRpZiAoY2IpXG5cdFx0c2VsZi5vbmNlKCd0aW1lb3V0JywgY2IpXG5cblx0c2VsZi5fc29ja2V0VGltZW91dCA9IHRpbWVvdXRcblx0c2VsZi5fcmVzZXRUaW1lcnMoZmFsc2UpXG59XG5cbkNsaWVudFJlcXVlc3QucHJvdG90eXBlLmZsdXNoSGVhZGVycyA9IGZ1bmN0aW9uICgpIHt9XG5DbGllbnRSZXF1ZXN0LnByb3RvdHlwZS5zZXROb0RlbGF5ID0gZnVuY3Rpb24gKCkge31cbkNsaWVudFJlcXVlc3QucHJvdG90eXBlLnNldFNvY2tldEtlZXBBbGl2ZSA9IGZ1bmN0aW9uICgpIHt9XG5cbi8vIFRha2VuIGZyb20gaHR0cDovL3d3dy53My5vcmcvVFIvWE1MSHR0cFJlcXVlc3QvI3RoZS1zZXRyZXF1ZXN0aGVhZGVyJTI4JTI5LW1ldGhvZFxudmFyIHVuc2FmZUhlYWRlcnMgPSBbXG5cdCdhY2NlcHQtY2hhcnNldCcsXG5cdCdhY2NlcHQtZW5jb2RpbmcnLFxuXHQnYWNjZXNzLWNvbnRyb2wtcmVxdWVzdC1oZWFkZXJzJyxcblx0J2FjY2Vzcy1jb250cm9sLXJlcXVlc3QtbWV0aG9kJyxcblx0J2Nvbm5lY3Rpb24nLFxuXHQnY29udGVudC1sZW5ndGgnLFxuXHQnY29va2llJyxcblx0J2Nvb2tpZTInLFxuXHQnZGF0ZScsXG5cdCdkbnQnLFxuXHQnZXhwZWN0Jyxcblx0J2hvc3QnLFxuXHQna2VlcC1hbGl2ZScsXG5cdCdvcmlnaW4nLFxuXHQncmVmZXJlcicsXG5cdCd0ZScsXG5cdCd0cmFpbGVyJyxcblx0J3RyYW5zZmVyLWVuY29kaW5nJyxcblx0J3VwZ3JhZGUnLFxuXHQndmlhJ1xuXVxuIiwidmFyIGNhcGFiaWxpdHkgPSByZXF1aXJlKCcuL2NhcGFiaWxpdHknKVxudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxudmFyIHN0cmVhbSA9IHJlcXVpcmUoJ3JlYWRhYmxlLXN0cmVhbScpXG5cbnZhciByU3RhdGVzID0gZXhwb3J0cy5yZWFkeVN0YXRlcyA9IHtcblx0VU5TRU5UOiAwLFxuXHRPUEVORUQ6IDEsXG5cdEhFQURFUlNfUkVDRUlWRUQ6IDIsXG5cdExPQURJTkc6IDMsXG5cdERPTkU6IDRcbn1cblxudmFyIEluY29taW5nTWVzc2FnZSA9IGV4cG9ydHMuSW5jb21pbmdNZXNzYWdlID0gZnVuY3Rpb24gKHhociwgcmVzcG9uc2UsIG1vZGUsIHJlc2V0VGltZXJzKSB7XG5cdHZhciBzZWxmID0gdGhpc1xuXHRzdHJlYW0uUmVhZGFibGUuY2FsbChzZWxmKVxuXG5cdHNlbGYuX21vZGUgPSBtb2RlXG5cdHNlbGYuaGVhZGVycyA9IHt9XG5cdHNlbGYucmF3SGVhZGVycyA9IFtdXG5cdHNlbGYudHJhaWxlcnMgPSB7fVxuXHRzZWxmLnJhd1RyYWlsZXJzID0gW11cblxuXHQvLyBGYWtlIHRoZSAnY2xvc2UnIGV2ZW50LCBidXQgb25seSBvbmNlICdlbmQnIGZpcmVzXG5cdHNlbGYub24oJ2VuZCcsIGZ1bmN0aW9uICgpIHtcblx0XHQvLyBUaGUgbmV4dFRpY2sgaXMgbmVjZXNzYXJ5IHRvIHByZXZlbnQgdGhlICdyZXF1ZXN0JyBtb2R1bGUgZnJvbSBjYXVzaW5nIGFuIGluZmluaXRlIGxvb3Bcblx0XHRwcm9jZXNzLm5leHRUaWNrKGZ1bmN0aW9uICgpIHtcblx0XHRcdHNlbGYuZW1pdCgnY2xvc2UnKVxuXHRcdH0pXG5cdH0pXG5cblx0aWYgKG1vZGUgPT09ICdmZXRjaCcpIHtcblx0XHRzZWxmLl9mZXRjaFJlc3BvbnNlID0gcmVzcG9uc2VcblxuXHRcdHNlbGYudXJsID0gcmVzcG9uc2UudXJsXG5cdFx0c2VsZi5zdGF0dXNDb2RlID0gcmVzcG9uc2Uuc3RhdHVzXG5cdFx0c2VsZi5zdGF0dXNNZXNzYWdlID0gcmVzcG9uc2Uuc3RhdHVzVGV4dFxuXHRcdFxuXHRcdHJlc3BvbnNlLmhlYWRlcnMuZm9yRWFjaChmdW5jdGlvbiAoaGVhZGVyLCBrZXkpe1xuXHRcdFx0c2VsZi5oZWFkZXJzW2tleS50b0xvd2VyQ2FzZSgpXSA9IGhlYWRlclxuXHRcdFx0c2VsZi5yYXdIZWFkZXJzLnB1c2goa2V5LCBoZWFkZXIpXG5cdFx0fSlcblxuXHRcdGlmIChjYXBhYmlsaXR5LndyaXRhYmxlU3RyZWFtKSB7XG5cdFx0XHR2YXIgd3JpdGFibGUgPSBuZXcgV3JpdGFibGVTdHJlYW0oe1xuXHRcdFx0XHR3cml0ZTogZnVuY3Rpb24gKGNodW5rKSB7XG5cdFx0XHRcdFx0cmVzZXRUaW1lcnMoZmFsc2UpXG5cdFx0XHRcdFx0cmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcblx0XHRcdFx0XHRcdGlmIChzZWxmLl9kZXN0cm95ZWQpIHtcblx0XHRcdFx0XHRcdFx0cmVqZWN0KClcblx0XHRcdFx0XHRcdH0gZWxzZSBpZihzZWxmLnB1c2goQnVmZmVyLmZyb20oY2h1bmspKSkge1xuXHRcdFx0XHRcdFx0XHRyZXNvbHZlKClcblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdHNlbGYuX3Jlc3VtZUZldGNoID0gcmVzb2x2ZVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0pXG5cdFx0XHRcdH0sXG5cdFx0XHRcdGNsb3NlOiBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0cmVzZXRUaW1lcnModHJ1ZSlcblx0XHRcdFx0XHRpZiAoIXNlbGYuX2Rlc3Ryb3llZClcblx0XHRcdFx0XHRcdHNlbGYucHVzaChudWxsKVxuXHRcdFx0XHR9LFxuXHRcdFx0XHRhYm9ydDogZnVuY3Rpb24gKGVycikge1xuXHRcdFx0XHRcdHJlc2V0VGltZXJzKHRydWUpXG5cdFx0XHRcdFx0aWYgKCFzZWxmLl9kZXN0cm95ZWQpXG5cdFx0XHRcdFx0XHRzZWxmLmVtaXQoJ2Vycm9yJywgZXJyKVxuXHRcdFx0XHR9XG5cdFx0XHR9KVxuXG5cdFx0XHR0cnkge1xuXHRcdFx0XHRyZXNwb25zZS5ib2R5LnBpcGVUbyh3cml0YWJsZSkuY2F0Y2goZnVuY3Rpb24gKGVycikge1xuXHRcdFx0XHRcdHJlc2V0VGltZXJzKHRydWUpXG5cdFx0XHRcdFx0aWYgKCFzZWxmLl9kZXN0cm95ZWQpXG5cdFx0XHRcdFx0XHRzZWxmLmVtaXQoJ2Vycm9yJywgZXJyKVxuXHRcdFx0XHR9KVxuXHRcdFx0XHRyZXR1cm5cblx0XHRcdH0gY2F0Y2ggKGUpIHt9IC8vIHBpcGVUbyBtZXRob2QgaXNuJ3QgZGVmaW5lZC4gQ2FuJ3QgZmluZCBhIGJldHRlciB3YXkgdG8gZmVhdHVyZSB0ZXN0IHRoaXNcblx0XHR9XG5cdFx0Ly8gZmFsbGJhY2sgZm9yIHdoZW4gd3JpdGFibGVTdHJlYW0gb3IgcGlwZVRvIGFyZW4ndCBhdmFpbGFibGVcblx0XHR2YXIgcmVhZGVyID0gcmVzcG9uc2UuYm9keS5nZXRSZWFkZXIoKVxuXHRcdGZ1bmN0aW9uIHJlYWQgKCkge1xuXHRcdFx0cmVhZGVyLnJlYWQoKS50aGVuKGZ1bmN0aW9uIChyZXN1bHQpIHtcblx0XHRcdFx0aWYgKHNlbGYuX2Rlc3Ryb3llZClcblx0XHRcdFx0XHRyZXR1cm5cblx0XHRcdFx0cmVzZXRUaW1lcnMocmVzdWx0LmRvbmUpXG5cdFx0XHRcdGlmIChyZXN1bHQuZG9uZSkge1xuXHRcdFx0XHRcdHNlbGYucHVzaChudWxsKVxuXHRcdFx0XHRcdHJldHVyblxuXHRcdFx0XHR9XG5cdFx0XHRcdHNlbGYucHVzaChCdWZmZXIuZnJvbShyZXN1bHQudmFsdWUpKVxuXHRcdFx0XHRyZWFkKClcblx0XHRcdH0pLmNhdGNoKGZ1bmN0aW9uIChlcnIpIHtcblx0XHRcdFx0cmVzZXRUaW1lcnModHJ1ZSlcblx0XHRcdFx0aWYgKCFzZWxmLl9kZXN0cm95ZWQpXG5cdFx0XHRcdFx0c2VsZi5lbWl0KCdlcnJvcicsIGVycilcblx0XHRcdH0pXG5cdFx0fVxuXHRcdHJlYWQoKVxuXHR9IGVsc2Uge1xuXHRcdHNlbGYuX3hociA9IHhoclxuXHRcdHNlbGYuX3BvcyA9IDBcblxuXHRcdHNlbGYudXJsID0geGhyLnJlc3BvbnNlVVJMXG5cdFx0c2VsZi5zdGF0dXNDb2RlID0geGhyLnN0YXR1c1xuXHRcdHNlbGYuc3RhdHVzTWVzc2FnZSA9IHhoci5zdGF0dXNUZXh0XG5cdFx0dmFyIGhlYWRlcnMgPSB4aHIuZ2V0QWxsUmVzcG9uc2VIZWFkZXJzKCkuc3BsaXQoL1xccj9cXG4vKVxuXHRcdGhlYWRlcnMuZm9yRWFjaChmdW5jdGlvbiAoaGVhZGVyKSB7XG5cdFx0XHR2YXIgbWF0Y2hlcyA9IGhlYWRlci5tYXRjaCgvXihbXjpdKyk6XFxzKiguKikvKVxuXHRcdFx0aWYgKG1hdGNoZXMpIHtcblx0XHRcdFx0dmFyIGtleSA9IG1hdGNoZXNbMV0udG9Mb3dlckNhc2UoKVxuXHRcdFx0XHRpZiAoa2V5ID09PSAnc2V0LWNvb2tpZScpIHtcblx0XHRcdFx0XHRpZiAoc2VsZi5oZWFkZXJzW2tleV0gPT09IHVuZGVmaW5lZCkge1xuXHRcdFx0XHRcdFx0c2VsZi5oZWFkZXJzW2tleV0gPSBbXVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRzZWxmLmhlYWRlcnNba2V5XS5wdXNoKG1hdGNoZXNbMl0pXG5cdFx0XHRcdH0gZWxzZSBpZiAoc2VsZi5oZWFkZXJzW2tleV0gIT09IHVuZGVmaW5lZCkge1xuXHRcdFx0XHRcdHNlbGYuaGVhZGVyc1trZXldICs9ICcsICcgKyBtYXRjaGVzWzJdXG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0c2VsZi5oZWFkZXJzW2tleV0gPSBtYXRjaGVzWzJdXG5cdFx0XHRcdH1cblx0XHRcdFx0c2VsZi5yYXdIZWFkZXJzLnB1c2gobWF0Y2hlc1sxXSwgbWF0Y2hlc1syXSlcblx0XHRcdH1cblx0XHR9KVxuXG5cdFx0c2VsZi5fY2hhcnNldCA9ICd4LXVzZXItZGVmaW5lZCdcblx0XHRpZiAoIWNhcGFiaWxpdHkub3ZlcnJpZGVNaW1lVHlwZSkge1xuXHRcdFx0dmFyIG1pbWVUeXBlID0gc2VsZi5yYXdIZWFkZXJzWydtaW1lLXR5cGUnXVxuXHRcdFx0aWYgKG1pbWVUeXBlKSB7XG5cdFx0XHRcdHZhciBjaGFyc2V0TWF0Y2ggPSBtaW1lVHlwZS5tYXRjaCgvO1xccypjaGFyc2V0PShbXjtdKSg7fCQpLylcblx0XHRcdFx0aWYgKGNoYXJzZXRNYXRjaCkge1xuXHRcdFx0XHRcdHNlbGYuX2NoYXJzZXQgPSBjaGFyc2V0TWF0Y2hbMV0udG9Mb3dlckNhc2UoKVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRpZiAoIXNlbGYuX2NoYXJzZXQpXG5cdFx0XHRcdHNlbGYuX2NoYXJzZXQgPSAndXRmLTgnIC8vIGJlc3QgZ3Vlc3Ncblx0XHR9XG5cdH1cbn1cblxuaW5oZXJpdHMoSW5jb21pbmdNZXNzYWdlLCBzdHJlYW0uUmVhZGFibGUpXG5cbkluY29taW5nTWVzc2FnZS5wcm90b3R5cGUuX3JlYWQgPSBmdW5jdGlvbiAoKSB7XG5cdHZhciBzZWxmID0gdGhpc1xuXG5cdHZhciByZXNvbHZlID0gc2VsZi5fcmVzdW1lRmV0Y2hcblx0aWYgKHJlc29sdmUpIHtcblx0XHRzZWxmLl9yZXN1bWVGZXRjaCA9IG51bGxcblx0XHRyZXNvbHZlKClcblx0fVxufVxuXG5JbmNvbWluZ01lc3NhZ2UucHJvdG90eXBlLl9vblhIUlByb2dyZXNzID0gZnVuY3Rpb24gKHJlc2V0VGltZXJzKSB7XG5cdHZhciBzZWxmID0gdGhpc1xuXG5cdHZhciB4aHIgPSBzZWxmLl94aHJcblxuXHR2YXIgcmVzcG9uc2UgPSBudWxsXG5cdHN3aXRjaCAoc2VsZi5fbW9kZSkge1xuXHRcdGNhc2UgJ3RleHQnOlxuXHRcdFx0cmVzcG9uc2UgPSB4aHIucmVzcG9uc2VUZXh0XG5cdFx0XHRpZiAocmVzcG9uc2UubGVuZ3RoID4gc2VsZi5fcG9zKSB7XG5cdFx0XHRcdHZhciBuZXdEYXRhID0gcmVzcG9uc2Uuc3Vic3RyKHNlbGYuX3Bvcylcblx0XHRcdFx0aWYgKHNlbGYuX2NoYXJzZXQgPT09ICd4LXVzZXItZGVmaW5lZCcpIHtcblx0XHRcdFx0XHR2YXIgYnVmZmVyID0gQnVmZmVyLmFsbG9jKG5ld0RhdGEubGVuZ3RoKVxuXHRcdFx0XHRcdGZvciAodmFyIGkgPSAwOyBpIDwgbmV3RGF0YS5sZW5ndGg7IGkrKylcblx0XHRcdFx0XHRcdGJ1ZmZlcltpXSA9IG5ld0RhdGEuY2hhckNvZGVBdChpKSAmIDB4ZmZcblxuXHRcdFx0XHRcdHNlbGYucHVzaChidWZmZXIpXG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0c2VsZi5wdXNoKG5ld0RhdGEsIHNlbGYuX2NoYXJzZXQpXG5cdFx0XHRcdH1cblx0XHRcdFx0c2VsZi5fcG9zID0gcmVzcG9uc2UubGVuZ3RoXG5cdFx0XHR9XG5cdFx0XHRicmVha1xuXHRcdGNhc2UgJ2FycmF5YnVmZmVyJzpcblx0XHRcdGlmICh4aHIucmVhZHlTdGF0ZSAhPT0gclN0YXRlcy5ET05FIHx8ICF4aHIucmVzcG9uc2UpXG5cdFx0XHRcdGJyZWFrXG5cdFx0XHRyZXNwb25zZSA9IHhoci5yZXNwb25zZVxuXHRcdFx0c2VsZi5wdXNoKEJ1ZmZlci5mcm9tKG5ldyBVaW50OEFycmF5KHJlc3BvbnNlKSkpXG5cdFx0XHRicmVha1xuXHRcdGNhc2UgJ21vei1jaHVua2VkLWFycmF5YnVmZmVyJzogLy8gdGFrZSB3aG9sZVxuXHRcdFx0cmVzcG9uc2UgPSB4aHIucmVzcG9uc2Vcblx0XHRcdGlmICh4aHIucmVhZHlTdGF0ZSAhPT0gclN0YXRlcy5MT0FESU5HIHx8ICFyZXNwb25zZSlcblx0XHRcdFx0YnJlYWtcblx0XHRcdHNlbGYucHVzaChCdWZmZXIuZnJvbShuZXcgVWludDhBcnJheShyZXNwb25zZSkpKVxuXHRcdFx0YnJlYWtcblx0XHRjYXNlICdtcy1zdHJlYW0nOlxuXHRcdFx0cmVzcG9uc2UgPSB4aHIucmVzcG9uc2Vcblx0XHRcdGlmICh4aHIucmVhZHlTdGF0ZSAhPT0gclN0YXRlcy5MT0FESU5HKVxuXHRcdFx0XHRicmVha1xuXHRcdFx0dmFyIHJlYWRlciA9IG5ldyBnbG9iYWwuTVNTdHJlYW1SZWFkZXIoKVxuXHRcdFx0cmVhZGVyLm9ucHJvZ3Jlc3MgPSBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdGlmIChyZWFkZXIucmVzdWx0LmJ5dGVMZW5ndGggPiBzZWxmLl9wb3MpIHtcblx0XHRcdFx0XHRzZWxmLnB1c2goQnVmZmVyLmZyb20obmV3IFVpbnQ4QXJyYXkocmVhZGVyLnJlc3VsdC5zbGljZShzZWxmLl9wb3MpKSkpXG5cdFx0XHRcdFx0c2VsZi5fcG9zID0gcmVhZGVyLnJlc3VsdC5ieXRlTGVuZ3RoXG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHJlYWRlci5vbmxvYWQgPSBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdHJlc2V0VGltZXJzKHRydWUpXG5cdFx0XHRcdHNlbGYucHVzaChudWxsKVxuXHRcdFx0fVxuXHRcdFx0Ly8gcmVhZGVyLm9uZXJyb3IgPSA/Pz8gLy8gVE9ETzogdGhpc1xuXHRcdFx0cmVhZGVyLnJlYWRBc0FycmF5QnVmZmVyKHJlc3BvbnNlKVxuXHRcdFx0YnJlYWtcblx0fVxuXG5cdC8vIFRoZSBtcy1zdHJlYW0gY2FzZSBoYW5kbGVzIGVuZCBzZXBhcmF0ZWx5IGluIHJlYWRlci5vbmxvYWQoKVxuXHRpZiAoc2VsZi5feGhyLnJlYWR5U3RhdGUgPT09IHJTdGF0ZXMuRE9ORSAmJiBzZWxmLl9tb2RlICE9PSAnbXMtc3RyZWFtJykge1xuXHRcdHJlc2V0VGltZXJzKHRydWUpXG5cdFx0c2VsZi5wdXNoKG51bGwpXG5cdH1cbn1cbiIsIid1c2Ugc3RyaWN0JztcblxuZnVuY3Rpb24gX2luaGVyaXRzTG9vc2Uoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzLnByb3RvdHlwZSk7IHN1YkNsYXNzLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IHN1YkNsYXNzOyBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9XG5cbnZhciBjb2RlcyA9IHt9O1xuXG5mdW5jdGlvbiBjcmVhdGVFcnJvclR5cGUoY29kZSwgbWVzc2FnZSwgQmFzZSkge1xuICBpZiAoIUJhc2UpIHtcbiAgICBCYXNlID0gRXJyb3I7XG4gIH1cblxuICBmdW5jdGlvbiBnZXRNZXNzYWdlKGFyZzEsIGFyZzIsIGFyZzMpIHtcbiAgICBpZiAodHlwZW9mIG1lc3NhZ2UgPT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG1lc3NhZ2UoYXJnMSwgYXJnMiwgYXJnMyk7XG4gICAgfVxuICB9XG5cbiAgdmFyIE5vZGVFcnJvciA9XG4gIC8qI19fUFVSRV9fKi9cbiAgZnVuY3Rpb24gKF9CYXNlKSB7XG4gICAgX2luaGVyaXRzTG9vc2UoTm9kZUVycm9yLCBfQmFzZSk7XG5cbiAgICBmdW5jdGlvbiBOb2RlRXJyb3IoYXJnMSwgYXJnMiwgYXJnMykge1xuICAgICAgcmV0dXJuIF9CYXNlLmNhbGwodGhpcywgZ2V0TWVzc2FnZShhcmcxLCBhcmcyLCBhcmczKSkgfHwgdGhpcztcbiAgICB9XG5cbiAgICByZXR1cm4gTm9kZUVycm9yO1xuICB9KEJhc2UpO1xuXG4gIE5vZGVFcnJvci5wcm90b3R5cGUubmFtZSA9IEJhc2UubmFtZTtcbiAgTm9kZUVycm9yLnByb3RvdHlwZS5jb2RlID0gY29kZTtcbiAgY29kZXNbY29kZV0gPSBOb2RlRXJyb3I7XG59IC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9ub2RlanMvbm9kZS9ibG9iL3YxMC44LjAvbGliL2ludGVybmFsL2Vycm9ycy5qc1xuXG5cbmZ1bmN0aW9uIG9uZU9mKGV4cGVjdGVkLCB0aGluZykge1xuICBpZiAoQXJyYXkuaXNBcnJheShleHBlY3RlZCkpIHtcbiAgICB2YXIgbGVuID0gZXhwZWN0ZWQubGVuZ3RoO1xuICAgIGV4cGVjdGVkID0gZXhwZWN0ZWQubWFwKGZ1bmN0aW9uIChpKSB7XG4gICAgICByZXR1cm4gU3RyaW5nKGkpO1xuICAgIH0pO1xuXG4gICAgaWYgKGxlbiA+IDIpIHtcbiAgICAgIHJldHVybiBcIm9uZSBvZiBcIi5jb25jYXQodGhpbmcsIFwiIFwiKS5jb25jYXQoZXhwZWN0ZWQuc2xpY2UoMCwgbGVuIC0gMSkuam9pbignLCAnKSwgXCIsIG9yIFwiKSArIGV4cGVjdGVkW2xlbiAtIDFdO1xuICAgIH0gZWxzZSBpZiAobGVuID09PSAyKSB7XG4gICAgICByZXR1cm4gXCJvbmUgb2YgXCIuY29uY2F0KHRoaW5nLCBcIiBcIikuY29uY2F0KGV4cGVjdGVkWzBdLCBcIiBvciBcIikuY29uY2F0KGV4cGVjdGVkWzFdKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIFwib2YgXCIuY29uY2F0KHRoaW5nLCBcIiBcIikuY29uY2F0KGV4cGVjdGVkWzBdKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIFwib2YgXCIuY29uY2F0KHRoaW5nLCBcIiBcIikuY29uY2F0KFN0cmluZyhleHBlY3RlZCkpO1xuICB9XG59IC8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL1N0cmluZy9zdGFydHNXaXRoXG5cblxuZnVuY3Rpb24gc3RhcnRzV2l0aChzdHIsIHNlYXJjaCwgcG9zKSB7XG4gIHJldHVybiBzdHIuc3Vic3RyKCFwb3MgfHwgcG9zIDwgMCA/IDAgOiArcG9zLCBzZWFyY2gubGVuZ3RoKSA9PT0gc2VhcmNoO1xufSAvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9TdHJpbmcvZW5kc1dpdGhcblxuXG5mdW5jdGlvbiBlbmRzV2l0aChzdHIsIHNlYXJjaCwgdGhpc19sZW4pIHtcbiAgaWYgKHRoaXNfbGVuID09PSB1bmRlZmluZWQgfHwgdGhpc19sZW4gPiBzdHIubGVuZ3RoKSB7XG4gICAgdGhpc19sZW4gPSBzdHIubGVuZ3RoO1xuICB9XG5cbiAgcmV0dXJuIHN0ci5zdWJzdHJpbmcodGhpc19sZW4gLSBzZWFyY2gubGVuZ3RoLCB0aGlzX2xlbikgPT09IHNlYXJjaDtcbn0gLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvU3RyaW5nL2luY2x1ZGVzXG5cblxuZnVuY3Rpb24gaW5jbHVkZXMoc3RyLCBzZWFyY2gsIHN0YXJ0KSB7XG4gIGlmICh0eXBlb2Ygc3RhcnQgIT09ICdudW1iZXInKSB7XG4gICAgc3RhcnQgPSAwO1xuICB9XG5cbiAgaWYgKHN0YXJ0ICsgc2VhcmNoLmxlbmd0aCA+IHN0ci5sZW5ndGgpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHN0ci5pbmRleE9mKHNlYXJjaCwgc3RhcnQpICE9PSAtMTtcbiAgfVxufVxuXG5jcmVhdGVFcnJvclR5cGUoJ0VSUl9JTlZBTElEX09QVF9WQUxVRScsIGZ1bmN0aW9uIChuYW1lLCB2YWx1ZSkge1xuICByZXR1cm4gJ1RoZSB2YWx1ZSBcIicgKyB2YWx1ZSArICdcIiBpcyBpbnZhbGlkIGZvciBvcHRpb24gXCInICsgbmFtZSArICdcIic7XG59LCBUeXBlRXJyb3IpO1xuY3JlYXRlRXJyb3JUeXBlKCdFUlJfSU5WQUxJRF9BUkdfVFlQRScsIGZ1bmN0aW9uIChuYW1lLCBleHBlY3RlZCwgYWN0dWFsKSB7XG4gIC8vIGRldGVybWluZXI6ICdtdXN0IGJlJyBvciAnbXVzdCBub3QgYmUnXG4gIHZhciBkZXRlcm1pbmVyO1xuXG4gIGlmICh0eXBlb2YgZXhwZWN0ZWQgPT09ICdzdHJpbmcnICYmIHN0YXJ0c1dpdGgoZXhwZWN0ZWQsICdub3QgJykpIHtcbiAgICBkZXRlcm1pbmVyID0gJ211c3Qgbm90IGJlJztcbiAgICBleHBlY3RlZCA9IGV4cGVjdGVkLnJlcGxhY2UoL15ub3QgLywgJycpO1xuICB9IGVsc2Uge1xuICAgIGRldGVybWluZXIgPSAnbXVzdCBiZSc7XG4gIH1cblxuICB2YXIgbXNnO1xuXG4gIGlmIChlbmRzV2l0aChuYW1lLCAnIGFyZ3VtZW50JykpIHtcbiAgICAvLyBGb3IgY2FzZXMgbGlrZSAnZmlyc3QgYXJndW1lbnQnXG4gICAgbXNnID0gXCJUaGUgXCIuY29uY2F0KG5hbWUsIFwiIFwiKS5jb25jYXQoZGV0ZXJtaW5lciwgXCIgXCIpLmNvbmNhdChvbmVPZihleHBlY3RlZCwgJ3R5cGUnKSk7XG4gIH0gZWxzZSB7XG4gICAgdmFyIHR5cGUgPSBpbmNsdWRlcyhuYW1lLCAnLicpID8gJ3Byb3BlcnR5JyA6ICdhcmd1bWVudCc7XG4gICAgbXNnID0gXCJUaGUgXFxcIlwiLmNvbmNhdChuYW1lLCBcIlxcXCIgXCIpLmNvbmNhdCh0eXBlLCBcIiBcIikuY29uY2F0KGRldGVybWluZXIsIFwiIFwiKS5jb25jYXQob25lT2YoZXhwZWN0ZWQsICd0eXBlJykpO1xuICB9XG5cbiAgbXNnICs9IFwiLiBSZWNlaXZlZCB0eXBlIFwiLmNvbmNhdCh0eXBlb2YgYWN0dWFsKTtcbiAgcmV0dXJuIG1zZztcbn0sIFR5cGVFcnJvcik7XG5jcmVhdGVFcnJvclR5cGUoJ0VSUl9TVFJFQU1fUFVTSF9BRlRFUl9FT0YnLCAnc3RyZWFtLnB1c2goKSBhZnRlciBFT0YnKTtcbmNyZWF0ZUVycm9yVHlwZSgnRVJSX01FVEhPRF9OT1RfSU1QTEVNRU5URUQnLCBmdW5jdGlvbiAobmFtZSkge1xuICByZXR1cm4gJ1RoZSAnICsgbmFtZSArICcgbWV0aG9kIGlzIG5vdCBpbXBsZW1lbnRlZCc7XG59KTtcbmNyZWF0ZUVycm9yVHlwZSgnRVJSX1NUUkVBTV9QUkVNQVRVUkVfQ0xPU0UnLCAnUHJlbWF0dXJlIGNsb3NlJyk7XG5jcmVhdGVFcnJvclR5cGUoJ0VSUl9TVFJFQU1fREVTVFJPWUVEJywgZnVuY3Rpb24gKG5hbWUpIHtcbiAgcmV0dXJuICdDYW5ub3QgY2FsbCAnICsgbmFtZSArICcgYWZ0ZXIgYSBzdHJlYW0gd2FzIGRlc3Ryb3llZCc7XG59KTtcbmNyZWF0ZUVycm9yVHlwZSgnRVJSX01VTFRJUExFX0NBTExCQUNLJywgJ0NhbGxiYWNrIGNhbGxlZCBtdWx0aXBsZSB0aW1lcycpO1xuY3JlYXRlRXJyb3JUeXBlKCdFUlJfU1RSRUFNX0NBTk5PVF9QSVBFJywgJ0Nhbm5vdCBwaXBlLCBub3QgcmVhZGFibGUnKTtcbmNyZWF0ZUVycm9yVHlwZSgnRVJSX1NUUkVBTV9XUklURV9BRlRFUl9FTkQnLCAnd3JpdGUgYWZ0ZXIgZW5kJyk7XG5jcmVhdGVFcnJvclR5cGUoJ0VSUl9TVFJFQU1fTlVMTF9WQUxVRVMnLCAnTWF5IG5vdCB3cml0ZSBudWxsIHZhbHVlcyB0byBzdHJlYW0nLCBUeXBlRXJyb3IpO1xuY3JlYXRlRXJyb3JUeXBlKCdFUlJfVU5LTk9XTl9FTkNPRElORycsIGZ1bmN0aW9uIChhcmcpIHtcbiAgcmV0dXJuICdVbmtub3duIGVuY29kaW5nOiAnICsgYXJnO1xufSwgVHlwZUVycm9yKTtcbmNyZWF0ZUVycm9yVHlwZSgnRVJSX1NUUkVBTV9VTlNISUZUX0FGVEVSX0VORF9FVkVOVCcsICdzdHJlYW0udW5zaGlmdCgpIGFmdGVyIGVuZCBldmVudCcpO1xubW9kdWxlLmV4cG9ydHMuY29kZXMgPSBjb2RlcztcbiIsIi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG4vLyBhIGR1cGxleCBzdHJlYW0gaXMganVzdCBhIHN0cmVhbSB0aGF0IGlzIGJvdGggcmVhZGFibGUgYW5kIHdyaXRhYmxlLlxuLy8gU2luY2UgSlMgZG9lc24ndCBoYXZlIG11bHRpcGxlIHByb3RvdHlwYWwgaW5oZXJpdGFuY2UsIHRoaXMgY2xhc3Ncbi8vIHByb3RvdHlwYWxseSBpbmhlcml0cyBmcm9tIFJlYWRhYmxlLCBhbmQgdGhlbiBwYXJhc2l0aWNhbGx5IGZyb21cbi8vIFdyaXRhYmxlLlxuXG4ndXNlIHN0cmljdCc7XG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgb2JqZWN0S2V5cyA9IE9iamVjdC5rZXlzIHx8IGZ1bmN0aW9uIChvYmopIHtcbiAgdmFyIGtleXMgPSBbXTtcbiAgZm9yICh2YXIga2V5IGluIG9iaikga2V5cy5wdXNoKGtleSk7XG4gIHJldHVybiBrZXlzO1xufTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG5tb2R1bGUuZXhwb3J0cyA9IER1cGxleDtcbnZhciBSZWFkYWJsZSA9IHJlcXVpcmUoJy4vX3N0cmVhbV9yZWFkYWJsZScpO1xudmFyIFdyaXRhYmxlID0gcmVxdWlyZSgnLi9fc3RyZWFtX3dyaXRhYmxlJyk7XG5yZXF1aXJlKCdpbmhlcml0cycpKER1cGxleCwgUmVhZGFibGUpO1xue1xuICAvLyBBbGxvdyB0aGUga2V5cyBhcnJheSB0byBiZSBHQydlZC5cbiAgdmFyIGtleXMgPSBvYmplY3RLZXlzKFdyaXRhYmxlLnByb3RvdHlwZSk7XG4gIGZvciAodmFyIHYgPSAwOyB2IDwga2V5cy5sZW5ndGg7IHYrKykge1xuICAgIHZhciBtZXRob2QgPSBrZXlzW3ZdO1xuICAgIGlmICghRHVwbGV4LnByb3RvdHlwZVttZXRob2RdKSBEdXBsZXgucHJvdG90eXBlW21ldGhvZF0gPSBXcml0YWJsZS5wcm90b3R5cGVbbWV0aG9kXTtcbiAgfVxufVxuZnVuY3Rpb24gRHVwbGV4KG9wdGlvbnMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIER1cGxleCkpIHJldHVybiBuZXcgRHVwbGV4KG9wdGlvbnMpO1xuICBSZWFkYWJsZS5jYWxsKHRoaXMsIG9wdGlvbnMpO1xuICBXcml0YWJsZS5jYWxsKHRoaXMsIG9wdGlvbnMpO1xuICB0aGlzLmFsbG93SGFsZk9wZW4gPSB0cnVlO1xuICBpZiAob3B0aW9ucykge1xuICAgIGlmIChvcHRpb25zLnJlYWRhYmxlID09PSBmYWxzZSkgdGhpcy5yZWFkYWJsZSA9IGZhbHNlO1xuICAgIGlmIChvcHRpb25zLndyaXRhYmxlID09PSBmYWxzZSkgdGhpcy53cml0YWJsZSA9IGZhbHNlO1xuICAgIGlmIChvcHRpb25zLmFsbG93SGFsZk9wZW4gPT09IGZhbHNlKSB7XG4gICAgICB0aGlzLmFsbG93SGFsZk9wZW4gPSBmYWxzZTtcbiAgICAgIHRoaXMub25jZSgnZW5kJywgb25lbmQpO1xuICAgIH1cbiAgfVxufVxuT2JqZWN0LmRlZmluZVByb3BlcnR5KER1cGxleC5wcm90b3R5cGUsICd3cml0YWJsZUhpZ2hXYXRlck1hcmsnLCB7XG4gIC8vIG1ha2luZyBpdCBleHBsaWNpdCB0aGlzIHByb3BlcnR5IGlzIG5vdCBlbnVtZXJhYmxlXG4gIC8vIGJlY2F1c2Ugb3RoZXJ3aXNlIHNvbWUgcHJvdG90eXBlIG1hbmlwdWxhdGlvbiBpblxuICAvLyB1c2VybGFuZCB3aWxsIGZhaWxcbiAgZW51bWVyYWJsZTogZmFsc2UsXG4gIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgIHJldHVybiB0aGlzLl93cml0YWJsZVN0YXRlLmhpZ2hXYXRlck1hcms7XG4gIH1cbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KER1cGxleC5wcm90b3R5cGUsICd3cml0YWJsZUJ1ZmZlcicsIHtcbiAgLy8gbWFraW5nIGl0IGV4cGxpY2l0IHRoaXMgcHJvcGVydHkgaXMgbm90IGVudW1lcmFibGVcbiAgLy8gYmVjYXVzZSBvdGhlcndpc2Ugc29tZSBwcm90b3R5cGUgbWFuaXB1bGF0aW9uIGluXG4gIC8vIHVzZXJsYW5kIHdpbGwgZmFpbFxuICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3dyaXRhYmxlU3RhdGUgJiYgdGhpcy5fd3JpdGFibGVTdGF0ZS5nZXRCdWZmZXIoKTtcbiAgfVxufSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoRHVwbGV4LnByb3RvdHlwZSwgJ3dyaXRhYmxlTGVuZ3RoJywge1xuICAvLyBtYWtpbmcgaXQgZXhwbGljaXQgdGhpcyBwcm9wZXJ0eSBpcyBub3QgZW51bWVyYWJsZVxuICAvLyBiZWNhdXNlIG90aGVyd2lzZSBzb21lIHByb3RvdHlwZSBtYW5pcHVsYXRpb24gaW5cbiAgLy8gdXNlcmxhbmQgd2lsbCBmYWlsXG4gIGVudW1lcmFibGU6IGZhbHNlLFxuICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICByZXR1cm4gdGhpcy5fd3JpdGFibGVTdGF0ZS5sZW5ndGg7XG4gIH1cbn0pO1xuXG4vLyB0aGUgbm8taGFsZi1vcGVuIGVuZm9yY2VyXG5mdW5jdGlvbiBvbmVuZCgpIHtcbiAgLy8gSWYgdGhlIHdyaXRhYmxlIHNpZGUgZW5kZWQsIHRoZW4gd2UncmUgb2suXG4gIGlmICh0aGlzLl93cml0YWJsZVN0YXRlLmVuZGVkKSByZXR1cm47XG5cbiAgLy8gbm8gbW9yZSBkYXRhIGNhbiBiZSB3cml0dGVuLlxuICAvLyBCdXQgYWxsb3cgbW9yZSB3cml0ZXMgdG8gaGFwcGVuIGluIHRoaXMgdGljay5cbiAgcHJvY2Vzcy5uZXh0VGljayhvbkVuZE5ULCB0aGlzKTtcbn1cbmZ1bmN0aW9uIG9uRW5kTlQoc2VsZikge1xuICBzZWxmLmVuZCgpO1xufVxuT2JqZWN0LmRlZmluZVByb3BlcnR5KER1cGxleC5wcm90b3R5cGUsICdkZXN0cm95ZWQnLCB7XG4gIC8vIG1ha2luZyBpdCBleHBsaWNpdCB0aGlzIHByb3BlcnR5IGlzIG5vdCBlbnVtZXJhYmxlXG4gIC8vIGJlY2F1c2Ugb3RoZXJ3aXNlIHNvbWUgcHJvdG90eXBlIG1hbmlwdWxhdGlvbiBpblxuICAvLyB1c2VybGFuZCB3aWxsIGZhaWxcbiAgZW51bWVyYWJsZTogZmFsc2UsXG4gIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgIGlmICh0aGlzLl9yZWFkYWJsZVN0YXRlID09PSB1bmRlZmluZWQgfHwgdGhpcy5fd3JpdGFibGVTdGF0ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9yZWFkYWJsZVN0YXRlLmRlc3Ryb3llZCAmJiB0aGlzLl93cml0YWJsZVN0YXRlLmRlc3Ryb3llZDtcbiAgfSxcbiAgc2V0OiBmdW5jdGlvbiBzZXQodmFsdWUpIHtcbiAgICAvLyB3ZSBpZ25vcmUgdGhlIHZhbHVlIGlmIHRoZSBzdHJlYW1cbiAgICAvLyBoYXMgbm90IGJlZW4gaW5pdGlhbGl6ZWQgeWV0XG4gICAgaWYgKHRoaXMuX3JlYWRhYmxlU3RhdGUgPT09IHVuZGVmaW5lZCB8fCB0aGlzLl93cml0YWJsZVN0YXRlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBiYWNrd2FyZCBjb21wYXRpYmlsaXR5LCB0aGUgdXNlciBpcyBleHBsaWNpdGx5XG4gICAgLy8gbWFuYWdpbmcgZGVzdHJveWVkXG4gICAgdGhpcy5fcmVhZGFibGVTdGF0ZS5kZXN0cm95ZWQgPSB2YWx1ZTtcbiAgICB0aGlzLl93cml0YWJsZVN0YXRlLmRlc3Ryb3llZCA9IHZhbHVlO1xuICB9XG59KTsiLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxuLy8gYSBwYXNzdGhyb3VnaCBzdHJlYW0uXG4vLyBiYXNpY2FsbHkganVzdCB0aGUgbW9zdCBtaW5pbWFsIHNvcnQgb2YgVHJhbnNmb3JtIHN0cmVhbS5cbi8vIEV2ZXJ5IHdyaXR0ZW4gY2h1bmsgZ2V0cyBvdXRwdXQgYXMtaXMuXG5cbid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSBQYXNzVGhyb3VnaDtcbnZhciBUcmFuc2Zvcm0gPSByZXF1aXJlKCcuL19zdHJlYW1fdHJhbnNmb3JtJyk7XG5yZXF1aXJlKCdpbmhlcml0cycpKFBhc3NUaHJvdWdoLCBUcmFuc2Zvcm0pO1xuZnVuY3Rpb24gUGFzc1Rocm91Z2gob3B0aW9ucykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgUGFzc1Rocm91Z2gpKSByZXR1cm4gbmV3IFBhc3NUaHJvdWdoKG9wdGlvbnMpO1xuICBUcmFuc2Zvcm0uY2FsbCh0aGlzLCBvcHRpb25zKTtcbn1cblBhc3NUaHJvdWdoLnByb3RvdHlwZS5fdHJhbnNmb3JtID0gZnVuY3Rpb24gKGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgY2IobnVsbCwgY2h1bmspO1xufTsiLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxuJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFJlYWRhYmxlO1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIER1cGxleDtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG5SZWFkYWJsZS5SZWFkYWJsZVN0YXRlID0gUmVhZGFibGVTdGF0ZTtcblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBFRSA9IHJlcXVpcmUoJ2V2ZW50cycpLkV2ZW50RW1pdHRlcjtcbnZhciBFRWxpc3RlbmVyQ291bnQgPSBmdW5jdGlvbiBFRWxpc3RlbmVyQ291bnQoZW1pdHRlciwgdHlwZSkge1xuICByZXR1cm4gZW1pdHRlci5saXN0ZW5lcnModHlwZSkubGVuZ3RoO1xufTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIFN0cmVhbSA9IHJlcXVpcmUoJy4vaW50ZXJuYWwvc3RyZWFtcy9zdHJlYW0nKTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG52YXIgQnVmZmVyID0gcmVxdWlyZSgnYnVmZmVyJykuQnVmZmVyO1xudmFyIE91clVpbnQ4QXJyYXkgPSAodHlwZW9mIGdsb2JhbCAhPT0gJ3VuZGVmaW5lZCcgPyBnbG9iYWwgOiB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyA/IHdpbmRvdyA6IHR5cGVvZiBzZWxmICE9PSAndW5kZWZpbmVkJyA/IHNlbGYgOiB7fSkuVWludDhBcnJheSB8fCBmdW5jdGlvbiAoKSB7fTtcbmZ1bmN0aW9uIF91aW50OEFycmF5VG9CdWZmZXIoY2h1bmspIHtcbiAgcmV0dXJuIEJ1ZmZlci5mcm9tKGNodW5rKTtcbn1cbmZ1bmN0aW9uIF9pc1VpbnQ4QXJyYXkob2JqKSB7XG4gIHJldHVybiBCdWZmZXIuaXNCdWZmZXIob2JqKSB8fCBvYmogaW5zdGFuY2VvZiBPdXJVaW50OEFycmF5O1xufVxuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIGRlYnVnVXRpbCA9IHJlcXVpcmUoJ3V0aWwnKTtcbnZhciBkZWJ1ZztcbmlmIChkZWJ1Z1V0aWwgJiYgZGVidWdVdGlsLmRlYnVnbG9nKSB7XG4gIGRlYnVnID0gZGVidWdVdGlsLmRlYnVnbG9nKCdzdHJlYW0nKTtcbn0gZWxzZSB7XG4gIGRlYnVnID0gZnVuY3Rpb24gZGVidWcoKSB7fTtcbn1cbi8qPC9yZXBsYWNlbWVudD4qL1xuXG52YXIgQnVmZmVyTGlzdCA9IHJlcXVpcmUoJy4vaW50ZXJuYWwvc3RyZWFtcy9idWZmZXJfbGlzdCcpO1xudmFyIGRlc3Ryb3lJbXBsID0gcmVxdWlyZSgnLi9pbnRlcm5hbC9zdHJlYW1zL2Rlc3Ryb3knKTtcbnZhciBfcmVxdWlyZSA9IHJlcXVpcmUoJy4vaW50ZXJuYWwvc3RyZWFtcy9zdGF0ZScpLFxuICBnZXRIaWdoV2F0ZXJNYXJrID0gX3JlcXVpcmUuZ2V0SGlnaFdhdGVyTWFyaztcbnZhciBfcmVxdWlyZSRjb2RlcyA9IHJlcXVpcmUoJy4uL2Vycm9ycycpLmNvZGVzLFxuICBFUlJfSU5WQUxJRF9BUkdfVFlQRSA9IF9yZXF1aXJlJGNvZGVzLkVSUl9JTlZBTElEX0FSR19UWVBFLFxuICBFUlJfU1RSRUFNX1BVU0hfQUZURVJfRU9GID0gX3JlcXVpcmUkY29kZXMuRVJSX1NUUkVBTV9QVVNIX0FGVEVSX0VPRixcbiAgRVJSX01FVEhPRF9OT1RfSU1QTEVNRU5URUQgPSBfcmVxdWlyZSRjb2Rlcy5FUlJfTUVUSE9EX05PVF9JTVBMRU1FTlRFRCxcbiAgRVJSX1NUUkVBTV9VTlNISUZUX0FGVEVSX0VORF9FVkVOVCA9IF9yZXF1aXJlJGNvZGVzLkVSUl9TVFJFQU1fVU5TSElGVF9BRlRFUl9FTkRfRVZFTlQ7XG5cbi8vIExhenkgbG9hZGVkIHRvIGltcHJvdmUgdGhlIHN0YXJ0dXAgcGVyZm9ybWFuY2UuXG52YXIgU3RyaW5nRGVjb2RlcjtcbnZhciBjcmVhdGVSZWFkYWJsZVN0cmVhbUFzeW5jSXRlcmF0b3I7XG52YXIgZnJvbTtcbnJlcXVpcmUoJ2luaGVyaXRzJykoUmVhZGFibGUsIFN0cmVhbSk7XG52YXIgZXJyb3JPckRlc3Ryb3kgPSBkZXN0cm95SW1wbC5lcnJvck9yRGVzdHJveTtcbnZhciBrUHJveHlFdmVudHMgPSBbJ2Vycm9yJywgJ2Nsb3NlJywgJ2Rlc3Ryb3knLCAncGF1c2UnLCAncmVzdW1lJ107XG5mdW5jdGlvbiBwcmVwZW5kTGlzdGVuZXIoZW1pdHRlciwgZXZlbnQsIGZuKSB7XG4gIC8vIFNhZGx5IHRoaXMgaXMgbm90IGNhY2hlYWJsZSBhcyBzb21lIGxpYnJhcmllcyBidW5kbGUgdGhlaXIgb3duXG4gIC8vIGV2ZW50IGVtaXR0ZXIgaW1wbGVtZW50YXRpb24gd2l0aCB0aGVtLlxuICBpZiAodHlwZW9mIGVtaXR0ZXIucHJlcGVuZExpc3RlbmVyID09PSAnZnVuY3Rpb24nKSByZXR1cm4gZW1pdHRlci5wcmVwZW5kTGlzdGVuZXIoZXZlbnQsIGZuKTtcblxuICAvLyBUaGlzIGlzIGEgaGFjayB0byBtYWtlIHN1cmUgdGhhdCBvdXIgZXJyb3IgaGFuZGxlciBpcyBhdHRhY2hlZCBiZWZvcmUgYW55XG4gIC8vIHVzZXJsYW5kIG9uZXMuICBORVZFUiBETyBUSElTLiBUaGlzIGlzIGhlcmUgb25seSBiZWNhdXNlIHRoaXMgY29kZSBuZWVkc1xuICAvLyB0byBjb250aW51ZSB0byB3b3JrIHdpdGggb2xkZXIgdmVyc2lvbnMgb2YgTm9kZS5qcyB0aGF0IGRvIG5vdCBpbmNsdWRlXG4gIC8vIHRoZSBwcmVwZW5kTGlzdGVuZXIoKSBtZXRob2QuIFRoZSBnb2FsIGlzIHRvIGV2ZW50dWFsbHkgcmVtb3ZlIHRoaXMgaGFjay5cbiAgaWYgKCFlbWl0dGVyLl9ldmVudHMgfHwgIWVtaXR0ZXIuX2V2ZW50c1tldmVudF0pIGVtaXR0ZXIub24oZXZlbnQsIGZuKTtlbHNlIGlmIChBcnJheS5pc0FycmF5KGVtaXR0ZXIuX2V2ZW50c1tldmVudF0pKSBlbWl0dGVyLl9ldmVudHNbZXZlbnRdLnVuc2hpZnQoZm4pO2Vsc2UgZW1pdHRlci5fZXZlbnRzW2V2ZW50XSA9IFtmbiwgZW1pdHRlci5fZXZlbnRzW2V2ZW50XV07XG59XG5mdW5jdGlvbiBSZWFkYWJsZVN0YXRlKG9wdGlvbnMsIHN0cmVhbSwgaXNEdXBsZXgpIHtcbiAgRHVwbGV4ID0gRHVwbGV4IHx8IHJlcXVpcmUoJy4vX3N0cmVhbV9kdXBsZXgnKTtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cbiAgLy8gRHVwbGV4IHN0cmVhbXMgYXJlIGJvdGggcmVhZGFibGUgYW5kIHdyaXRhYmxlLCBidXQgc2hhcmVcbiAgLy8gdGhlIHNhbWUgb3B0aW9ucyBvYmplY3QuXG4gIC8vIEhvd2V2ZXIsIHNvbWUgY2FzZXMgcmVxdWlyZSBzZXR0aW5nIG9wdGlvbnMgdG8gZGlmZmVyZW50XG4gIC8vIHZhbHVlcyBmb3IgdGhlIHJlYWRhYmxlIGFuZCB0aGUgd3JpdGFibGUgc2lkZXMgb2YgdGhlIGR1cGxleCBzdHJlYW0uXG4gIC8vIFRoZXNlIG9wdGlvbnMgY2FuIGJlIHByb3ZpZGVkIHNlcGFyYXRlbHkgYXMgcmVhZGFibGVYWFggYW5kIHdyaXRhYmxlWFhYLlxuICBpZiAodHlwZW9mIGlzRHVwbGV4ICE9PSAnYm9vbGVhbicpIGlzRHVwbGV4ID0gc3RyZWFtIGluc3RhbmNlb2YgRHVwbGV4O1xuXG4gIC8vIG9iamVjdCBzdHJlYW0gZmxhZy4gVXNlZCB0byBtYWtlIHJlYWQobikgaWdub3JlIG4gYW5kIHRvXG4gIC8vIG1ha2UgYWxsIHRoZSBidWZmZXIgbWVyZ2luZyBhbmQgbGVuZ3RoIGNoZWNrcyBnbyBhd2F5XG4gIHRoaXMub2JqZWN0TW9kZSA9ICEhb3B0aW9ucy5vYmplY3RNb2RlO1xuICBpZiAoaXNEdXBsZXgpIHRoaXMub2JqZWN0TW9kZSA9IHRoaXMub2JqZWN0TW9kZSB8fCAhIW9wdGlvbnMucmVhZGFibGVPYmplY3RNb2RlO1xuXG4gIC8vIHRoZSBwb2ludCBhdCB3aGljaCBpdCBzdG9wcyBjYWxsaW5nIF9yZWFkKCkgdG8gZmlsbCB0aGUgYnVmZmVyXG4gIC8vIE5vdGU6IDAgaXMgYSB2YWxpZCB2YWx1ZSwgbWVhbnMgXCJkb24ndCBjYWxsIF9yZWFkIHByZWVtcHRpdmVseSBldmVyXCJcbiAgdGhpcy5oaWdoV2F0ZXJNYXJrID0gZ2V0SGlnaFdhdGVyTWFyayh0aGlzLCBvcHRpb25zLCAncmVhZGFibGVIaWdoV2F0ZXJNYXJrJywgaXNEdXBsZXgpO1xuXG4gIC8vIEEgbGlua2VkIGxpc3QgaXMgdXNlZCB0byBzdG9yZSBkYXRhIGNodW5rcyBpbnN0ZWFkIG9mIGFuIGFycmF5IGJlY2F1c2UgdGhlXG4gIC8vIGxpbmtlZCBsaXN0IGNhbiByZW1vdmUgZWxlbWVudHMgZnJvbSB0aGUgYmVnaW5uaW5nIGZhc3RlciB0aGFuXG4gIC8vIGFycmF5LnNoaWZ0KClcbiAgdGhpcy5idWZmZXIgPSBuZXcgQnVmZmVyTGlzdCgpO1xuICB0aGlzLmxlbmd0aCA9IDA7XG4gIHRoaXMucGlwZXMgPSBudWxsO1xuICB0aGlzLnBpcGVzQ291bnQgPSAwO1xuICB0aGlzLmZsb3dpbmcgPSBudWxsO1xuICB0aGlzLmVuZGVkID0gZmFsc2U7XG4gIHRoaXMuZW5kRW1pdHRlZCA9IGZhbHNlO1xuICB0aGlzLnJlYWRpbmcgPSBmYWxzZTtcblxuICAvLyBhIGZsYWcgdG8gYmUgYWJsZSB0byB0ZWxsIGlmIHRoZSBldmVudCAncmVhZGFibGUnLydkYXRhJyBpcyBlbWl0dGVkXG4gIC8vIGltbWVkaWF0ZWx5LCBvciBvbiBhIGxhdGVyIHRpY2suICBXZSBzZXQgdGhpcyB0byB0cnVlIGF0IGZpcnN0LCBiZWNhdXNlXG4gIC8vIGFueSBhY3Rpb25zIHRoYXQgc2hvdWxkbid0IGhhcHBlbiB1bnRpbCBcImxhdGVyXCIgc2hvdWxkIGdlbmVyYWxseSBhbHNvXG4gIC8vIG5vdCBoYXBwZW4gYmVmb3JlIHRoZSBmaXJzdCByZWFkIGNhbGwuXG4gIHRoaXMuc3luYyA9IHRydWU7XG5cbiAgLy8gd2hlbmV2ZXIgd2UgcmV0dXJuIG51bGwsIHRoZW4gd2Ugc2V0IGEgZmxhZyB0byBzYXlcbiAgLy8gdGhhdCB3ZSdyZSBhd2FpdGluZyBhICdyZWFkYWJsZScgZXZlbnQgZW1pc3Npb24uXG4gIHRoaXMubmVlZFJlYWRhYmxlID0gZmFsc2U7XG4gIHRoaXMuZW1pdHRlZFJlYWRhYmxlID0gZmFsc2U7XG4gIHRoaXMucmVhZGFibGVMaXN0ZW5pbmcgPSBmYWxzZTtcbiAgdGhpcy5yZXN1bWVTY2hlZHVsZWQgPSBmYWxzZTtcbiAgdGhpcy5wYXVzZWQgPSB0cnVlO1xuXG4gIC8vIFNob3VsZCBjbG9zZSBiZSBlbWl0dGVkIG9uIGRlc3Ryb3kuIERlZmF1bHRzIHRvIHRydWUuXG4gIHRoaXMuZW1pdENsb3NlID0gb3B0aW9ucy5lbWl0Q2xvc2UgIT09IGZhbHNlO1xuXG4gIC8vIFNob3VsZCAuZGVzdHJveSgpIGJlIGNhbGxlZCBhZnRlciAnZW5kJyAoYW5kIHBvdGVudGlhbGx5ICdmaW5pc2gnKVxuICB0aGlzLmF1dG9EZXN0cm95ID0gISFvcHRpb25zLmF1dG9EZXN0cm95O1xuXG4gIC8vIGhhcyBpdCBiZWVuIGRlc3Ryb3llZFxuICB0aGlzLmRlc3Ryb3llZCA9IGZhbHNlO1xuXG4gIC8vIENyeXB0byBpcyBraW5kIG9mIG9sZCBhbmQgY3J1c3R5LiAgSGlzdG9yaWNhbGx5LCBpdHMgZGVmYXVsdCBzdHJpbmdcbiAgLy8gZW5jb2RpbmcgaXMgJ2JpbmFyeScgc28gd2UgaGF2ZSB0byBtYWtlIHRoaXMgY29uZmlndXJhYmxlLlxuICAvLyBFdmVyeXRoaW5nIGVsc2UgaW4gdGhlIHVuaXZlcnNlIHVzZXMgJ3V0ZjgnLCB0aG91Z2guXG4gIHRoaXMuZGVmYXVsdEVuY29kaW5nID0gb3B0aW9ucy5kZWZhdWx0RW5jb2RpbmcgfHwgJ3V0ZjgnO1xuXG4gIC8vIHRoZSBudW1iZXIgb2Ygd3JpdGVycyB0aGF0IGFyZSBhd2FpdGluZyBhIGRyYWluIGV2ZW50IGluIC5waXBlKClzXG4gIHRoaXMuYXdhaXREcmFpbiA9IDA7XG5cbiAgLy8gaWYgdHJ1ZSwgYSBtYXliZVJlYWRNb3JlIGhhcyBiZWVuIHNjaGVkdWxlZFxuICB0aGlzLnJlYWRpbmdNb3JlID0gZmFsc2U7XG4gIHRoaXMuZGVjb2RlciA9IG51bGw7XG4gIHRoaXMuZW5jb2RpbmcgPSBudWxsO1xuICBpZiAob3B0aW9ucy5lbmNvZGluZykge1xuICAgIGlmICghU3RyaW5nRGVjb2RlcikgU3RyaW5nRGVjb2RlciA9IHJlcXVpcmUoJ3N0cmluZ19kZWNvZGVyLycpLlN0cmluZ0RlY29kZXI7XG4gICAgdGhpcy5kZWNvZGVyID0gbmV3IFN0cmluZ0RlY29kZXIob3B0aW9ucy5lbmNvZGluZyk7XG4gICAgdGhpcy5lbmNvZGluZyA9IG9wdGlvbnMuZW5jb2Rpbmc7XG4gIH1cbn1cbmZ1bmN0aW9uIFJlYWRhYmxlKG9wdGlvbnMpIHtcbiAgRHVwbGV4ID0gRHVwbGV4IHx8IHJlcXVpcmUoJy4vX3N0cmVhbV9kdXBsZXgnKTtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFJlYWRhYmxlKSkgcmV0dXJuIG5ldyBSZWFkYWJsZShvcHRpb25zKTtcblxuICAvLyBDaGVja2luZyBmb3IgYSBTdHJlYW0uRHVwbGV4IGluc3RhbmNlIGlzIGZhc3RlciBoZXJlIGluc3RlYWQgb2YgaW5zaWRlXG4gIC8vIHRoZSBSZWFkYWJsZVN0YXRlIGNvbnN0cnVjdG9yLCBhdCBsZWFzdCB3aXRoIFY4IDYuNVxuICB2YXIgaXNEdXBsZXggPSB0aGlzIGluc3RhbmNlb2YgRHVwbGV4O1xuICB0aGlzLl9yZWFkYWJsZVN0YXRlID0gbmV3IFJlYWRhYmxlU3RhdGUob3B0aW9ucywgdGhpcywgaXNEdXBsZXgpO1xuXG4gIC8vIGxlZ2FjeVxuICB0aGlzLnJlYWRhYmxlID0gdHJ1ZTtcbiAgaWYgKG9wdGlvbnMpIHtcbiAgICBpZiAodHlwZW9mIG9wdGlvbnMucmVhZCA9PT0gJ2Z1bmN0aW9uJykgdGhpcy5fcmVhZCA9IG9wdGlvbnMucmVhZDtcbiAgICBpZiAodHlwZW9mIG9wdGlvbnMuZGVzdHJveSA9PT0gJ2Z1bmN0aW9uJykgdGhpcy5fZGVzdHJveSA9IG9wdGlvbnMuZGVzdHJveTtcbiAgfVxuICBTdHJlYW0uY2FsbCh0aGlzKTtcbn1cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZWFkYWJsZS5wcm90b3R5cGUsICdkZXN0cm95ZWQnLCB7XG4gIC8vIG1ha2luZyBpdCBleHBsaWNpdCB0aGlzIHByb3BlcnR5IGlzIG5vdCBlbnVtZXJhYmxlXG4gIC8vIGJlY2F1c2Ugb3RoZXJ3aXNlIHNvbWUgcHJvdG90eXBlIG1hbmlwdWxhdGlvbiBpblxuICAvLyB1c2VybGFuZCB3aWxsIGZhaWxcbiAgZW51bWVyYWJsZTogZmFsc2UsXG4gIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgIGlmICh0aGlzLl9yZWFkYWJsZVN0YXRlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX3JlYWRhYmxlU3RhdGUuZGVzdHJveWVkO1xuICB9LFxuICBzZXQ6IGZ1bmN0aW9uIHNldCh2YWx1ZSkge1xuICAgIC8vIHdlIGlnbm9yZSB0aGUgdmFsdWUgaWYgdGhlIHN0cmVhbVxuICAgIC8vIGhhcyBub3QgYmVlbiBpbml0aWFsaXplZCB5ZXRcbiAgICBpZiAoIXRoaXMuX3JlYWRhYmxlU3RhdGUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBiYWNrd2FyZCBjb21wYXRpYmlsaXR5LCB0aGUgdXNlciBpcyBleHBsaWNpdGx5XG4gICAgLy8gbWFuYWdpbmcgZGVzdHJveWVkXG4gICAgdGhpcy5fcmVhZGFibGVTdGF0ZS5kZXN0cm95ZWQgPSB2YWx1ZTtcbiAgfVxufSk7XG5SZWFkYWJsZS5wcm90b3R5cGUuZGVzdHJveSA9IGRlc3Ryb3lJbXBsLmRlc3Ryb3k7XG5SZWFkYWJsZS5wcm90b3R5cGUuX3VuZGVzdHJveSA9IGRlc3Ryb3lJbXBsLnVuZGVzdHJveTtcblJlYWRhYmxlLnByb3RvdHlwZS5fZGVzdHJveSA9IGZ1bmN0aW9uIChlcnIsIGNiKSB7XG4gIGNiKGVycik7XG59O1xuXG4vLyBNYW51YWxseSBzaG92ZSBzb21ldGhpbmcgaW50byB0aGUgcmVhZCgpIGJ1ZmZlci5cbi8vIFRoaXMgcmV0dXJucyB0cnVlIGlmIHRoZSBoaWdoV2F0ZXJNYXJrIGhhcyBub3QgYmVlbiBoaXQgeWV0LFxuLy8gc2ltaWxhciB0byBob3cgV3JpdGFibGUud3JpdGUoKSByZXR1cm5zIHRydWUgaWYgeW91IHNob3VsZFxuLy8gd3JpdGUoKSBzb21lIG1vcmUuXG5SZWFkYWJsZS5wcm90b3R5cGUucHVzaCA9IGZ1bmN0aW9uIChjaHVuaywgZW5jb2RpbmcpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcbiAgdmFyIHNraXBDaHVua0NoZWNrO1xuICBpZiAoIXN0YXRlLm9iamVjdE1vZGUpIHtcbiAgICBpZiAodHlwZW9mIGNodW5rID09PSAnc3RyaW5nJykge1xuICAgICAgZW5jb2RpbmcgPSBlbmNvZGluZyB8fCBzdGF0ZS5kZWZhdWx0RW5jb2Rpbmc7XG4gICAgICBpZiAoZW5jb2RpbmcgIT09IHN0YXRlLmVuY29kaW5nKSB7XG4gICAgICAgIGNodW5rID0gQnVmZmVyLmZyb20oY2h1bmssIGVuY29kaW5nKTtcbiAgICAgICAgZW5jb2RpbmcgPSAnJztcbiAgICAgIH1cbiAgICAgIHNraXBDaHVua0NoZWNrID0gdHJ1ZTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgc2tpcENodW5rQ2hlY2sgPSB0cnVlO1xuICB9XG4gIHJldHVybiByZWFkYWJsZUFkZENodW5rKHRoaXMsIGNodW5rLCBlbmNvZGluZywgZmFsc2UsIHNraXBDaHVua0NoZWNrKTtcbn07XG5cbi8vIFVuc2hpZnQgc2hvdWxkICphbHdheXMqIGJlIHNvbWV0aGluZyBkaXJlY3RseSBvdXQgb2YgcmVhZCgpXG5SZWFkYWJsZS5wcm90b3R5cGUudW5zaGlmdCA9IGZ1bmN0aW9uIChjaHVuaykge1xuICByZXR1cm4gcmVhZGFibGVBZGRDaHVuayh0aGlzLCBjaHVuaywgbnVsbCwgdHJ1ZSwgZmFsc2UpO1xufTtcbmZ1bmN0aW9uIHJlYWRhYmxlQWRkQ2h1bmsoc3RyZWFtLCBjaHVuaywgZW5jb2RpbmcsIGFkZFRvRnJvbnQsIHNraXBDaHVua0NoZWNrKSB7XG4gIGRlYnVnKCdyZWFkYWJsZUFkZENodW5rJywgY2h1bmspO1xuICB2YXIgc3RhdGUgPSBzdHJlYW0uX3JlYWRhYmxlU3RhdGU7XG4gIGlmIChjaHVuayA9PT0gbnVsbCkge1xuICAgIHN0YXRlLnJlYWRpbmcgPSBmYWxzZTtcbiAgICBvbkVvZkNodW5rKHN0cmVhbSwgc3RhdGUpO1xuICB9IGVsc2Uge1xuICAgIHZhciBlcjtcbiAgICBpZiAoIXNraXBDaHVua0NoZWNrKSBlciA9IGNodW5rSW52YWxpZChzdGF0ZSwgY2h1bmspO1xuICAgIGlmIChlcikge1xuICAgICAgZXJyb3JPckRlc3Ryb3koc3RyZWFtLCBlcik7XG4gICAgfSBlbHNlIGlmIChzdGF0ZS5vYmplY3RNb2RlIHx8IGNodW5rICYmIGNodW5rLmxlbmd0aCA+IDApIHtcbiAgICAgIGlmICh0eXBlb2YgY2h1bmsgIT09ICdzdHJpbmcnICYmICFzdGF0ZS5vYmplY3RNb2RlICYmIE9iamVjdC5nZXRQcm90b3R5cGVPZihjaHVuaykgIT09IEJ1ZmZlci5wcm90b3R5cGUpIHtcbiAgICAgICAgY2h1bmsgPSBfdWludDhBcnJheVRvQnVmZmVyKGNodW5rKTtcbiAgICAgIH1cbiAgICAgIGlmIChhZGRUb0Zyb250KSB7XG4gICAgICAgIGlmIChzdGF0ZS5lbmRFbWl0dGVkKSBlcnJvck9yRGVzdHJveShzdHJlYW0sIG5ldyBFUlJfU1RSRUFNX1VOU0hJRlRfQUZURVJfRU5EX0VWRU5UKCkpO2Vsc2UgYWRkQ2h1bmsoc3RyZWFtLCBzdGF0ZSwgY2h1bmssIHRydWUpO1xuICAgICAgfSBlbHNlIGlmIChzdGF0ZS5lbmRlZCkge1xuICAgICAgICBlcnJvck9yRGVzdHJveShzdHJlYW0sIG5ldyBFUlJfU1RSRUFNX1BVU0hfQUZURVJfRU9GKCkpO1xuICAgICAgfSBlbHNlIGlmIChzdGF0ZS5kZXN0cm95ZWQpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3RhdGUucmVhZGluZyA9IGZhbHNlO1xuICAgICAgICBpZiAoc3RhdGUuZGVjb2RlciAmJiAhZW5jb2RpbmcpIHtcbiAgICAgICAgICBjaHVuayA9IHN0YXRlLmRlY29kZXIud3JpdGUoY2h1bmspO1xuICAgICAgICAgIGlmIChzdGF0ZS5vYmplY3RNb2RlIHx8IGNodW5rLmxlbmd0aCAhPT0gMCkgYWRkQ2h1bmsoc3RyZWFtLCBzdGF0ZSwgY2h1bmssIGZhbHNlKTtlbHNlIG1heWJlUmVhZE1vcmUoc3RyZWFtLCBzdGF0ZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYWRkQ2h1bmsoc3RyZWFtLCBzdGF0ZSwgY2h1bmssIGZhbHNlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoIWFkZFRvRnJvbnQpIHtcbiAgICAgIHN0YXRlLnJlYWRpbmcgPSBmYWxzZTtcbiAgICAgIG1heWJlUmVhZE1vcmUoc3RyZWFtLCBzdGF0ZSk7XG4gICAgfVxuICB9XG5cbiAgLy8gV2UgY2FuIHB1c2ggbW9yZSBkYXRhIGlmIHdlIGFyZSBiZWxvdyB0aGUgaGlnaFdhdGVyTWFyay5cbiAgLy8gQWxzbywgaWYgd2UgaGF2ZSBubyBkYXRhIHlldCwgd2UgY2FuIHN0YW5kIHNvbWUgbW9yZSBieXRlcy5cbiAgLy8gVGhpcyBpcyB0byB3b3JrIGFyb3VuZCBjYXNlcyB3aGVyZSBod209MCwgc3VjaCBhcyB0aGUgcmVwbC5cbiAgcmV0dXJuICFzdGF0ZS5lbmRlZCAmJiAoc3RhdGUubGVuZ3RoIDwgc3RhdGUuaGlnaFdhdGVyTWFyayB8fCBzdGF0ZS5sZW5ndGggPT09IDApO1xufVxuZnVuY3Rpb24gYWRkQ2h1bmsoc3RyZWFtLCBzdGF0ZSwgY2h1bmssIGFkZFRvRnJvbnQpIHtcbiAgaWYgKHN0YXRlLmZsb3dpbmcgJiYgc3RhdGUubGVuZ3RoID09PSAwICYmICFzdGF0ZS5zeW5jKSB7XG4gICAgc3RhdGUuYXdhaXREcmFpbiA9IDA7XG4gICAgc3RyZWFtLmVtaXQoJ2RhdGEnLCBjaHVuayk7XG4gIH0gZWxzZSB7XG4gICAgLy8gdXBkYXRlIHRoZSBidWZmZXIgaW5mby5cbiAgICBzdGF0ZS5sZW5ndGggKz0gc3RhdGUub2JqZWN0TW9kZSA/IDEgOiBjaHVuay5sZW5ndGg7XG4gICAgaWYgKGFkZFRvRnJvbnQpIHN0YXRlLmJ1ZmZlci51bnNoaWZ0KGNodW5rKTtlbHNlIHN0YXRlLmJ1ZmZlci5wdXNoKGNodW5rKTtcbiAgICBpZiAoc3RhdGUubmVlZFJlYWRhYmxlKSBlbWl0UmVhZGFibGUoc3RyZWFtKTtcbiAgfVxuICBtYXliZVJlYWRNb3JlKHN0cmVhbSwgc3RhdGUpO1xufVxuZnVuY3Rpb24gY2h1bmtJbnZhbGlkKHN0YXRlLCBjaHVuaykge1xuICB2YXIgZXI7XG4gIGlmICghX2lzVWludDhBcnJheShjaHVuaykgJiYgdHlwZW9mIGNodW5rICE9PSAnc3RyaW5nJyAmJiBjaHVuayAhPT0gdW5kZWZpbmVkICYmICFzdGF0ZS5vYmplY3RNb2RlKSB7XG4gICAgZXIgPSBuZXcgRVJSX0lOVkFMSURfQVJHX1RZUEUoJ2NodW5rJywgWydzdHJpbmcnLCAnQnVmZmVyJywgJ1VpbnQ4QXJyYXknXSwgY2h1bmspO1xuICB9XG4gIHJldHVybiBlcjtcbn1cblJlYWRhYmxlLnByb3RvdHlwZS5pc1BhdXNlZCA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIHRoaXMuX3JlYWRhYmxlU3RhdGUuZmxvd2luZyA9PT0gZmFsc2U7XG59O1xuXG4vLyBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eS5cblJlYWRhYmxlLnByb3RvdHlwZS5zZXRFbmNvZGluZyA9IGZ1bmN0aW9uIChlbmMpIHtcbiAgaWYgKCFTdHJpbmdEZWNvZGVyKSBTdHJpbmdEZWNvZGVyID0gcmVxdWlyZSgnc3RyaW5nX2RlY29kZXIvJykuU3RyaW5nRGVjb2RlcjtcbiAgdmFyIGRlY29kZXIgPSBuZXcgU3RyaW5nRGVjb2RlcihlbmMpO1xuICB0aGlzLl9yZWFkYWJsZVN0YXRlLmRlY29kZXIgPSBkZWNvZGVyO1xuICAvLyBJZiBzZXRFbmNvZGluZyhudWxsKSwgZGVjb2Rlci5lbmNvZGluZyBlcXVhbHMgdXRmOFxuICB0aGlzLl9yZWFkYWJsZVN0YXRlLmVuY29kaW5nID0gdGhpcy5fcmVhZGFibGVTdGF0ZS5kZWNvZGVyLmVuY29kaW5nO1xuXG4gIC8vIEl0ZXJhdGUgb3ZlciBjdXJyZW50IGJ1ZmZlciB0byBjb252ZXJ0IGFscmVhZHkgc3RvcmVkIEJ1ZmZlcnM6XG4gIHZhciBwID0gdGhpcy5fcmVhZGFibGVTdGF0ZS5idWZmZXIuaGVhZDtcbiAgdmFyIGNvbnRlbnQgPSAnJztcbiAgd2hpbGUgKHAgIT09IG51bGwpIHtcbiAgICBjb250ZW50ICs9IGRlY29kZXIud3JpdGUocC5kYXRhKTtcbiAgICBwID0gcC5uZXh0O1xuICB9XG4gIHRoaXMuX3JlYWRhYmxlU3RhdGUuYnVmZmVyLmNsZWFyKCk7XG4gIGlmIChjb250ZW50ICE9PSAnJykgdGhpcy5fcmVhZGFibGVTdGF0ZS5idWZmZXIucHVzaChjb250ZW50KTtcbiAgdGhpcy5fcmVhZGFibGVTdGF0ZS5sZW5ndGggPSBjb250ZW50Lmxlbmd0aDtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vLyBEb24ndCByYWlzZSB0aGUgaHdtID4gMUdCXG52YXIgTUFYX0hXTSA9IDB4NDAwMDAwMDA7XG5mdW5jdGlvbiBjb21wdXRlTmV3SGlnaFdhdGVyTWFyayhuKSB7XG4gIGlmIChuID49IE1BWF9IV00pIHtcbiAgICAvLyBUT0RPKHJvbmFnKTogVGhyb3cgRVJSX1ZBTFVFX09VVF9PRl9SQU5HRS5cbiAgICBuID0gTUFYX0hXTTtcbiAgfSBlbHNlIHtcbiAgICAvLyBHZXQgdGhlIG5leHQgaGlnaGVzdCBwb3dlciBvZiAyIHRvIHByZXZlbnQgaW5jcmVhc2luZyBod20gZXhjZXNzaXZlbHkgaW5cbiAgICAvLyB0aW55IGFtb3VudHNcbiAgICBuLS07XG4gICAgbiB8PSBuID4+PiAxO1xuICAgIG4gfD0gbiA+Pj4gMjtcbiAgICBuIHw9IG4gPj4+IDQ7XG4gICAgbiB8PSBuID4+PiA4O1xuICAgIG4gfD0gbiA+Pj4gMTY7XG4gICAgbisrO1xuICB9XG4gIHJldHVybiBuO1xufVxuXG4vLyBUaGlzIGZ1bmN0aW9uIGlzIGRlc2lnbmVkIHRvIGJlIGlubGluYWJsZSwgc28gcGxlYXNlIHRha2UgY2FyZSB3aGVuIG1ha2luZ1xuLy8gY2hhbmdlcyB0byB0aGUgZnVuY3Rpb24gYm9keS5cbmZ1bmN0aW9uIGhvd011Y2hUb1JlYWQobiwgc3RhdGUpIHtcbiAgaWYgKG4gPD0gMCB8fCBzdGF0ZS5sZW5ndGggPT09IDAgJiYgc3RhdGUuZW5kZWQpIHJldHVybiAwO1xuICBpZiAoc3RhdGUub2JqZWN0TW9kZSkgcmV0dXJuIDE7XG4gIGlmIChuICE9PSBuKSB7XG4gICAgLy8gT25seSBmbG93IG9uZSBidWZmZXIgYXQgYSB0aW1lXG4gICAgaWYgKHN0YXRlLmZsb3dpbmcgJiYgc3RhdGUubGVuZ3RoKSByZXR1cm4gc3RhdGUuYnVmZmVyLmhlYWQuZGF0YS5sZW5ndGg7ZWxzZSByZXR1cm4gc3RhdGUubGVuZ3RoO1xuICB9XG4gIC8vIElmIHdlJ3JlIGFza2luZyBmb3IgbW9yZSB0aGFuIHRoZSBjdXJyZW50IGh3bSwgdGhlbiByYWlzZSB0aGUgaHdtLlxuICBpZiAobiA+IHN0YXRlLmhpZ2hXYXRlck1hcmspIHN0YXRlLmhpZ2hXYXRlck1hcmsgPSBjb21wdXRlTmV3SGlnaFdhdGVyTWFyayhuKTtcbiAgaWYgKG4gPD0gc3RhdGUubGVuZ3RoKSByZXR1cm4gbjtcbiAgLy8gRG9uJ3QgaGF2ZSBlbm91Z2hcbiAgaWYgKCFzdGF0ZS5lbmRlZCkge1xuICAgIHN0YXRlLm5lZWRSZWFkYWJsZSA9IHRydWU7XG4gICAgcmV0dXJuIDA7XG4gIH1cbiAgcmV0dXJuIHN0YXRlLmxlbmd0aDtcbn1cblxuLy8geW91IGNhbiBvdmVycmlkZSBlaXRoZXIgdGhpcyBtZXRob2QsIG9yIHRoZSBhc3luYyBfcmVhZChuKSBiZWxvdy5cblJlYWRhYmxlLnByb3RvdHlwZS5yZWFkID0gZnVuY3Rpb24gKG4pIHtcbiAgZGVidWcoJ3JlYWQnLCBuKTtcbiAgbiA9IHBhcnNlSW50KG4sIDEwKTtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcbiAgdmFyIG5PcmlnID0gbjtcbiAgaWYgKG4gIT09IDApIHN0YXRlLmVtaXR0ZWRSZWFkYWJsZSA9IGZhbHNlO1xuXG4gIC8vIGlmIHdlJ3JlIGRvaW5nIHJlYWQoMCkgdG8gdHJpZ2dlciBhIHJlYWRhYmxlIGV2ZW50LCBidXQgd2VcbiAgLy8gYWxyZWFkeSBoYXZlIGEgYnVuY2ggb2YgZGF0YSBpbiB0aGUgYnVmZmVyLCB0aGVuIGp1c3QgdHJpZ2dlclxuICAvLyB0aGUgJ3JlYWRhYmxlJyBldmVudCBhbmQgbW92ZSBvbi5cbiAgaWYgKG4gPT09IDAgJiYgc3RhdGUubmVlZFJlYWRhYmxlICYmICgoc3RhdGUuaGlnaFdhdGVyTWFyayAhPT0gMCA/IHN0YXRlLmxlbmd0aCA+PSBzdGF0ZS5oaWdoV2F0ZXJNYXJrIDogc3RhdGUubGVuZ3RoID4gMCkgfHwgc3RhdGUuZW5kZWQpKSB7XG4gICAgZGVidWcoJ3JlYWQ6IGVtaXRSZWFkYWJsZScsIHN0YXRlLmxlbmd0aCwgc3RhdGUuZW5kZWQpO1xuICAgIGlmIChzdGF0ZS5sZW5ndGggPT09IDAgJiYgc3RhdGUuZW5kZWQpIGVuZFJlYWRhYmxlKHRoaXMpO2Vsc2UgZW1pdFJlYWRhYmxlKHRoaXMpO1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIG4gPSBob3dNdWNoVG9SZWFkKG4sIHN0YXRlKTtcblxuICAvLyBpZiB3ZSd2ZSBlbmRlZCwgYW5kIHdlJ3JlIG5vdyBjbGVhciwgdGhlbiBmaW5pc2ggaXQgdXAuXG4gIGlmIChuID09PSAwICYmIHN0YXRlLmVuZGVkKSB7XG4gICAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMCkgZW5kUmVhZGFibGUodGhpcyk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvLyBBbGwgdGhlIGFjdHVhbCBjaHVuayBnZW5lcmF0aW9uIGxvZ2ljIG5lZWRzIHRvIGJlXG4gIC8vICpiZWxvdyogdGhlIGNhbGwgdG8gX3JlYWQuICBUaGUgcmVhc29uIGlzIHRoYXQgaW4gY2VydGFpblxuICAvLyBzeW50aGV0aWMgc3RyZWFtIGNhc2VzLCBzdWNoIGFzIHBhc3N0aHJvdWdoIHN0cmVhbXMsIF9yZWFkXG4gIC8vIG1heSBiZSBhIGNvbXBsZXRlbHkgc3luY2hyb25vdXMgb3BlcmF0aW9uIHdoaWNoIG1heSBjaGFuZ2VcbiAgLy8gdGhlIHN0YXRlIG9mIHRoZSByZWFkIGJ1ZmZlciwgcHJvdmlkaW5nIGVub3VnaCBkYXRhIHdoZW5cbiAgLy8gYmVmb3JlIHRoZXJlIHdhcyAqbm90KiBlbm91Z2guXG4gIC8vXG4gIC8vIFNvLCB0aGUgc3RlcHMgYXJlOlxuICAvLyAxLiBGaWd1cmUgb3V0IHdoYXQgdGhlIHN0YXRlIG9mIHRoaW5ncyB3aWxsIGJlIGFmdGVyIHdlIGRvXG4gIC8vIGEgcmVhZCBmcm9tIHRoZSBidWZmZXIuXG4gIC8vXG4gIC8vIDIuIElmIHRoYXQgcmVzdWx0aW5nIHN0YXRlIHdpbGwgdHJpZ2dlciBhIF9yZWFkLCB0aGVuIGNhbGwgX3JlYWQuXG4gIC8vIE5vdGUgdGhhdCB0aGlzIG1heSBiZSBhc3luY2hyb25vdXMsIG9yIHN5bmNocm9ub3VzLiAgWWVzLCBpdCBpc1xuICAvLyBkZWVwbHkgdWdseSB0byB3cml0ZSBBUElzIHRoaXMgd2F5LCBidXQgdGhhdCBzdGlsbCBkb2Vzbid0IG1lYW5cbiAgLy8gdGhhdCB0aGUgUmVhZGFibGUgY2xhc3Mgc2hvdWxkIGJlaGF2ZSBpbXByb3Blcmx5LCBhcyBzdHJlYW1zIGFyZVxuICAvLyBkZXNpZ25lZCB0byBiZSBzeW5jL2FzeW5jIGFnbm9zdGljLlxuICAvLyBUYWtlIG5vdGUgaWYgdGhlIF9yZWFkIGNhbGwgaXMgc3luYyBvciBhc3luYyAoaWUsIGlmIHRoZSByZWFkIGNhbGxcbiAgLy8gaGFzIHJldHVybmVkIHlldCksIHNvIHRoYXQgd2Uga25vdyB3aGV0aGVyIG9yIG5vdCBpdCdzIHNhZmUgdG8gZW1pdFxuICAvLyAncmVhZGFibGUnIGV0Yy5cbiAgLy9cbiAgLy8gMy4gQWN0dWFsbHkgcHVsbCB0aGUgcmVxdWVzdGVkIGNodW5rcyBvdXQgb2YgdGhlIGJ1ZmZlciBhbmQgcmV0dXJuLlxuXG4gIC8vIGlmIHdlIG5lZWQgYSByZWFkYWJsZSBldmVudCwgdGhlbiB3ZSBuZWVkIHRvIGRvIHNvbWUgcmVhZGluZy5cbiAgdmFyIGRvUmVhZCA9IHN0YXRlLm5lZWRSZWFkYWJsZTtcbiAgZGVidWcoJ25lZWQgcmVhZGFibGUnLCBkb1JlYWQpO1xuXG4gIC8vIGlmIHdlIGN1cnJlbnRseSBoYXZlIGxlc3MgdGhhbiB0aGUgaGlnaFdhdGVyTWFyaywgdGhlbiBhbHNvIHJlYWQgc29tZVxuICBpZiAoc3RhdGUubGVuZ3RoID09PSAwIHx8IHN0YXRlLmxlbmd0aCAtIG4gPCBzdGF0ZS5oaWdoV2F0ZXJNYXJrKSB7XG4gICAgZG9SZWFkID0gdHJ1ZTtcbiAgICBkZWJ1ZygnbGVuZ3RoIGxlc3MgdGhhbiB3YXRlcm1hcmsnLCBkb1JlYWQpO1xuICB9XG5cbiAgLy8gaG93ZXZlciwgaWYgd2UndmUgZW5kZWQsIHRoZW4gdGhlcmUncyBubyBwb2ludCwgYW5kIGlmIHdlJ3JlIGFscmVhZHlcbiAgLy8gcmVhZGluZywgdGhlbiBpdCdzIHVubmVjZXNzYXJ5LlxuICBpZiAoc3RhdGUuZW5kZWQgfHwgc3RhdGUucmVhZGluZykge1xuICAgIGRvUmVhZCA9IGZhbHNlO1xuICAgIGRlYnVnKCdyZWFkaW5nIG9yIGVuZGVkJywgZG9SZWFkKTtcbiAgfSBlbHNlIGlmIChkb1JlYWQpIHtcbiAgICBkZWJ1ZygnZG8gcmVhZCcpO1xuICAgIHN0YXRlLnJlYWRpbmcgPSB0cnVlO1xuICAgIHN0YXRlLnN5bmMgPSB0cnVlO1xuICAgIC8vIGlmIHRoZSBsZW5ndGggaXMgY3VycmVudGx5IHplcm8sIHRoZW4gd2UgKm5lZWQqIGEgcmVhZGFibGUgZXZlbnQuXG4gICAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMCkgc3RhdGUubmVlZFJlYWRhYmxlID0gdHJ1ZTtcbiAgICAvLyBjYWxsIGludGVybmFsIHJlYWQgbWV0aG9kXG4gICAgdGhpcy5fcmVhZChzdGF0ZS5oaWdoV2F0ZXJNYXJrKTtcbiAgICBzdGF0ZS5zeW5jID0gZmFsc2U7XG4gICAgLy8gSWYgX3JlYWQgcHVzaGVkIGRhdGEgc3luY2hyb25vdXNseSwgdGhlbiBgcmVhZGluZ2Agd2lsbCBiZSBmYWxzZSxcbiAgICAvLyBhbmQgd2UgbmVlZCB0byByZS1ldmFsdWF0ZSBob3cgbXVjaCBkYXRhIHdlIGNhbiByZXR1cm4gdG8gdGhlIHVzZXIuXG4gICAgaWYgKCFzdGF0ZS5yZWFkaW5nKSBuID0gaG93TXVjaFRvUmVhZChuT3JpZywgc3RhdGUpO1xuICB9XG4gIHZhciByZXQ7XG4gIGlmIChuID4gMCkgcmV0ID0gZnJvbUxpc3Qobiwgc3RhdGUpO2Vsc2UgcmV0ID0gbnVsbDtcbiAgaWYgKHJldCA9PT0gbnVsbCkge1xuICAgIHN0YXRlLm5lZWRSZWFkYWJsZSA9IHN0YXRlLmxlbmd0aCA8PSBzdGF0ZS5oaWdoV2F0ZXJNYXJrO1xuICAgIG4gPSAwO1xuICB9IGVsc2Uge1xuICAgIHN0YXRlLmxlbmd0aCAtPSBuO1xuICAgIHN0YXRlLmF3YWl0RHJhaW4gPSAwO1xuICB9XG4gIGlmIChzdGF0ZS5sZW5ndGggPT09IDApIHtcbiAgICAvLyBJZiB3ZSBoYXZlIG5vdGhpbmcgaW4gdGhlIGJ1ZmZlciwgdGhlbiB3ZSB3YW50IHRvIGtub3dcbiAgICAvLyBhcyBzb29uIGFzIHdlICpkbyogZ2V0IHNvbWV0aGluZyBpbnRvIHRoZSBidWZmZXIuXG4gICAgaWYgKCFzdGF0ZS5lbmRlZCkgc3RhdGUubmVlZFJlYWRhYmxlID0gdHJ1ZTtcblxuICAgIC8vIElmIHdlIHRyaWVkIHRvIHJlYWQoKSBwYXN0IHRoZSBFT0YsIHRoZW4gZW1pdCBlbmQgb24gdGhlIG5leHQgdGljay5cbiAgICBpZiAobk9yaWcgIT09IG4gJiYgc3RhdGUuZW5kZWQpIGVuZFJlYWRhYmxlKHRoaXMpO1xuICB9XG4gIGlmIChyZXQgIT09IG51bGwpIHRoaXMuZW1pdCgnZGF0YScsIHJldCk7XG4gIHJldHVybiByZXQ7XG59O1xuZnVuY3Rpb24gb25Fb2ZDaHVuayhzdHJlYW0sIHN0YXRlKSB7XG4gIGRlYnVnKCdvbkVvZkNodW5rJyk7XG4gIGlmIChzdGF0ZS5lbmRlZCkgcmV0dXJuO1xuICBpZiAoc3RhdGUuZGVjb2Rlcikge1xuICAgIHZhciBjaHVuayA9IHN0YXRlLmRlY29kZXIuZW5kKCk7XG4gICAgaWYgKGNodW5rICYmIGNodW5rLmxlbmd0aCkge1xuICAgICAgc3RhdGUuYnVmZmVyLnB1c2goY2h1bmspO1xuICAgICAgc3RhdGUubGVuZ3RoICs9IHN0YXRlLm9iamVjdE1vZGUgPyAxIDogY2h1bmsubGVuZ3RoO1xuICAgIH1cbiAgfVxuICBzdGF0ZS5lbmRlZCA9IHRydWU7XG4gIGlmIChzdGF0ZS5zeW5jKSB7XG4gICAgLy8gaWYgd2UgYXJlIHN5bmMsIHdhaXQgdW50aWwgbmV4dCB0aWNrIHRvIGVtaXQgdGhlIGRhdGEuXG4gICAgLy8gT3RoZXJ3aXNlIHdlIHJpc2sgZW1pdHRpbmcgZGF0YSBpbiB0aGUgZmxvdygpXG4gICAgLy8gdGhlIHJlYWRhYmxlIGNvZGUgdHJpZ2dlcnMgZHVyaW5nIGEgcmVhZCgpIGNhbGxcbiAgICBlbWl0UmVhZGFibGUoc3RyZWFtKTtcbiAgfSBlbHNlIHtcbiAgICAvLyBlbWl0ICdyZWFkYWJsZScgbm93IHRvIG1ha2Ugc3VyZSBpdCBnZXRzIHBpY2tlZCB1cC5cbiAgICBzdGF0ZS5uZWVkUmVhZGFibGUgPSBmYWxzZTtcbiAgICBpZiAoIXN0YXRlLmVtaXR0ZWRSZWFkYWJsZSkge1xuICAgICAgc3RhdGUuZW1pdHRlZFJlYWRhYmxlID0gdHJ1ZTtcbiAgICAgIGVtaXRSZWFkYWJsZV8oc3RyZWFtKTtcbiAgICB9XG4gIH1cbn1cblxuLy8gRG9uJ3QgZW1pdCByZWFkYWJsZSByaWdodCBhd2F5IGluIHN5bmMgbW9kZSwgYmVjYXVzZSB0aGlzIGNhbiB0cmlnZ2VyXG4vLyBhbm90aGVyIHJlYWQoKSBjYWxsID0+IHN0YWNrIG92ZXJmbG93LiAgVGhpcyB3YXksIGl0IG1pZ2h0IHRyaWdnZXJcbi8vIGEgbmV4dFRpY2sgcmVjdXJzaW9uIHdhcm5pbmcsIGJ1dCB0aGF0J3Mgbm90IHNvIGJhZC5cbmZ1bmN0aW9uIGVtaXRSZWFkYWJsZShzdHJlYW0pIHtcbiAgdmFyIHN0YXRlID0gc3RyZWFtLl9yZWFkYWJsZVN0YXRlO1xuICBkZWJ1ZygnZW1pdFJlYWRhYmxlJywgc3RhdGUubmVlZFJlYWRhYmxlLCBzdGF0ZS5lbWl0dGVkUmVhZGFibGUpO1xuICBzdGF0ZS5uZWVkUmVhZGFibGUgPSBmYWxzZTtcbiAgaWYgKCFzdGF0ZS5lbWl0dGVkUmVhZGFibGUpIHtcbiAgICBkZWJ1ZygnZW1pdFJlYWRhYmxlJywgc3RhdGUuZmxvd2luZyk7XG4gICAgc3RhdGUuZW1pdHRlZFJlYWRhYmxlID0gdHJ1ZTtcbiAgICBwcm9jZXNzLm5leHRUaWNrKGVtaXRSZWFkYWJsZV8sIHN0cmVhbSk7XG4gIH1cbn1cbmZ1bmN0aW9uIGVtaXRSZWFkYWJsZV8oc3RyZWFtKSB7XG4gIHZhciBzdGF0ZSA9IHN0cmVhbS5fcmVhZGFibGVTdGF0ZTtcbiAgZGVidWcoJ2VtaXRSZWFkYWJsZV8nLCBzdGF0ZS5kZXN0cm95ZWQsIHN0YXRlLmxlbmd0aCwgc3RhdGUuZW5kZWQpO1xuICBpZiAoIXN0YXRlLmRlc3Ryb3llZCAmJiAoc3RhdGUubGVuZ3RoIHx8IHN0YXRlLmVuZGVkKSkge1xuICAgIHN0cmVhbS5lbWl0KCdyZWFkYWJsZScpO1xuICAgIHN0YXRlLmVtaXR0ZWRSZWFkYWJsZSA9IGZhbHNlO1xuICB9XG5cbiAgLy8gVGhlIHN0cmVhbSBuZWVkcyBhbm90aGVyIHJlYWRhYmxlIGV2ZW50IGlmXG4gIC8vIDEuIEl0IGlzIG5vdCBmbG93aW5nLCBhcyB0aGUgZmxvdyBtZWNoYW5pc20gd2lsbCB0YWtlXG4gIC8vICAgIGNhcmUgb2YgaXQuXG4gIC8vIDIuIEl0IGlzIG5vdCBlbmRlZC5cbiAgLy8gMy4gSXQgaXMgYmVsb3cgdGhlIGhpZ2hXYXRlck1hcmssIHNvIHdlIGNhbiBzY2hlZHVsZVxuICAvLyAgICBhbm90aGVyIHJlYWRhYmxlIGxhdGVyLlxuICBzdGF0ZS5uZWVkUmVhZGFibGUgPSAhc3RhdGUuZmxvd2luZyAmJiAhc3RhdGUuZW5kZWQgJiYgc3RhdGUubGVuZ3RoIDw9IHN0YXRlLmhpZ2hXYXRlck1hcms7XG4gIGZsb3coc3RyZWFtKTtcbn1cblxuLy8gYXQgdGhpcyBwb2ludCwgdGhlIHVzZXIgaGFzIHByZXN1bWFibHkgc2VlbiB0aGUgJ3JlYWRhYmxlJyBldmVudCxcbi8vIGFuZCBjYWxsZWQgcmVhZCgpIHRvIGNvbnN1bWUgc29tZSBkYXRhLiAgdGhhdCBtYXkgaGF2ZSB0cmlnZ2VyZWRcbi8vIGluIHR1cm4gYW5vdGhlciBfcmVhZChuKSBjYWxsLCBpbiB3aGljaCBjYXNlIHJlYWRpbmcgPSB0cnVlIGlmXG4vLyBpdCdzIGluIHByb2dyZXNzLlxuLy8gSG93ZXZlciwgaWYgd2UncmUgbm90IGVuZGVkLCBvciByZWFkaW5nLCBhbmQgdGhlIGxlbmd0aCA8IGh3bSxcbi8vIHRoZW4gZ28gYWhlYWQgYW5kIHRyeSB0byByZWFkIHNvbWUgbW9yZSBwcmVlbXB0aXZlbHkuXG5mdW5jdGlvbiBtYXliZVJlYWRNb3JlKHN0cmVhbSwgc3RhdGUpIHtcbiAgaWYgKCFzdGF0ZS5yZWFkaW5nTW9yZSkge1xuICAgIHN0YXRlLnJlYWRpbmdNb3JlID0gdHJ1ZTtcbiAgICBwcm9jZXNzLm5leHRUaWNrKG1heWJlUmVhZE1vcmVfLCBzdHJlYW0sIHN0YXRlKTtcbiAgfVxufVxuZnVuY3Rpb24gbWF5YmVSZWFkTW9yZV8oc3RyZWFtLCBzdGF0ZSkge1xuICAvLyBBdHRlbXB0IHRvIHJlYWQgbW9yZSBkYXRhIGlmIHdlIHNob3VsZC5cbiAgLy9cbiAgLy8gVGhlIGNvbmRpdGlvbnMgZm9yIHJlYWRpbmcgbW9yZSBkYXRhIGFyZSAob25lIG9mKTpcbiAgLy8gLSBOb3QgZW5vdWdoIGRhdGEgYnVmZmVyZWQgKHN0YXRlLmxlbmd0aCA8IHN0YXRlLmhpZ2hXYXRlck1hcmspLiBUaGUgbG9vcFxuICAvLyAgIGlzIHJlc3BvbnNpYmxlIGZvciBmaWxsaW5nIHRoZSBidWZmZXIgd2l0aCBlbm91Z2ggZGF0YSBpZiBzdWNoIGRhdGFcbiAgLy8gICBpcyBhdmFpbGFibGUuIElmIGhpZ2hXYXRlck1hcmsgaXMgMCBhbmQgd2UgYXJlIG5vdCBpbiB0aGUgZmxvd2luZyBtb2RlXG4gIC8vICAgd2Ugc2hvdWxkIF9ub3RfIGF0dGVtcHQgdG8gYnVmZmVyIGFueSBleHRyYSBkYXRhLiBXZSdsbCBnZXQgbW9yZSBkYXRhXG4gIC8vICAgd2hlbiB0aGUgc3RyZWFtIGNvbnN1bWVyIGNhbGxzIHJlYWQoKSBpbnN0ZWFkLlxuICAvLyAtIE5vIGRhdGEgaW4gdGhlIGJ1ZmZlciwgYW5kIHRoZSBzdHJlYW0gaXMgaW4gZmxvd2luZyBtb2RlLiBJbiB0aGlzIG1vZGVcbiAgLy8gICB0aGUgbG9vcCBiZWxvdyBpcyByZXNwb25zaWJsZSBmb3IgZW5zdXJpbmcgcmVhZCgpIGlzIGNhbGxlZC4gRmFpbGluZyB0b1xuICAvLyAgIGNhbGwgcmVhZCBoZXJlIHdvdWxkIGFib3J0IHRoZSBmbG93IGFuZCB0aGVyZSdzIG5vIG90aGVyIG1lY2hhbmlzbSBmb3JcbiAgLy8gICBjb250aW51aW5nIHRoZSBmbG93IGlmIHRoZSBzdHJlYW0gY29uc3VtZXIgaGFzIGp1c3Qgc3Vic2NyaWJlZCB0byB0aGVcbiAgLy8gICAnZGF0YScgZXZlbnQuXG4gIC8vXG4gIC8vIEluIGFkZGl0aW9uIHRvIHRoZSBhYm92ZSBjb25kaXRpb25zIHRvIGtlZXAgcmVhZGluZyBkYXRhLCB0aGUgZm9sbG93aW5nXG4gIC8vIGNvbmRpdGlvbnMgcHJldmVudCB0aGUgZGF0YSBmcm9tIGJlaW5nIHJlYWQ6XG4gIC8vIC0gVGhlIHN0cmVhbSBoYXMgZW5kZWQgKHN0YXRlLmVuZGVkKS5cbiAgLy8gLSBUaGVyZSBpcyBhbHJlYWR5IGEgcGVuZGluZyAncmVhZCcgb3BlcmF0aW9uIChzdGF0ZS5yZWFkaW5nKS4gVGhpcyBpcyBhXG4gIC8vICAgY2FzZSB3aGVyZSB0aGUgdGhlIHN0cmVhbSBoYXMgY2FsbGVkIHRoZSBpbXBsZW1lbnRhdGlvbiBkZWZpbmVkIF9yZWFkKClcbiAgLy8gICBtZXRob2QsIGJ1dCB0aGV5IGFyZSBwcm9jZXNzaW5nIHRoZSBjYWxsIGFzeW5jaHJvbm91c2x5IGFuZCBoYXZlIF9ub3RfXG4gIC8vICAgY2FsbGVkIHB1c2goKSB3aXRoIG5ldyBkYXRhLiBJbiB0aGlzIGNhc2Ugd2Ugc2tpcCBwZXJmb3JtaW5nIG1vcmVcbiAgLy8gICByZWFkKClzLiBUaGUgZXhlY3V0aW9uIGVuZHMgaW4gdGhpcyBtZXRob2QgYWdhaW4gYWZ0ZXIgdGhlIF9yZWFkKCkgZW5kc1xuICAvLyAgIHVwIGNhbGxpbmcgcHVzaCgpIHdpdGggbW9yZSBkYXRhLlxuICB3aGlsZSAoIXN0YXRlLnJlYWRpbmcgJiYgIXN0YXRlLmVuZGVkICYmIChzdGF0ZS5sZW5ndGggPCBzdGF0ZS5oaWdoV2F0ZXJNYXJrIHx8IHN0YXRlLmZsb3dpbmcgJiYgc3RhdGUubGVuZ3RoID09PSAwKSkge1xuICAgIHZhciBsZW4gPSBzdGF0ZS5sZW5ndGg7XG4gICAgZGVidWcoJ21heWJlUmVhZE1vcmUgcmVhZCAwJyk7XG4gICAgc3RyZWFtLnJlYWQoMCk7XG4gICAgaWYgKGxlbiA9PT0gc3RhdGUubGVuZ3RoKVxuICAgICAgLy8gZGlkbid0IGdldCBhbnkgZGF0YSwgc3RvcCBzcGlubmluZy5cbiAgICAgIGJyZWFrO1xuICB9XG4gIHN0YXRlLnJlYWRpbmdNb3JlID0gZmFsc2U7XG59XG5cbi8vIGFic3RyYWN0IG1ldGhvZC4gIHRvIGJlIG92ZXJyaWRkZW4gaW4gc3BlY2lmaWMgaW1wbGVtZW50YXRpb24gY2xhc3Nlcy5cbi8vIGNhbGwgY2IoZXIsIGRhdGEpIHdoZXJlIGRhdGEgaXMgPD0gbiBpbiBsZW5ndGguXG4vLyBmb3IgdmlydHVhbCAobm9uLXN0cmluZywgbm9uLWJ1ZmZlcikgc3RyZWFtcywgXCJsZW5ndGhcIiBpcyBzb21ld2hhdFxuLy8gYXJiaXRyYXJ5LCBhbmQgcGVyaGFwcyBub3QgdmVyeSBtZWFuaW5nZnVsLlxuUmVhZGFibGUucHJvdG90eXBlLl9yZWFkID0gZnVuY3Rpb24gKG4pIHtcbiAgZXJyb3JPckRlc3Ryb3kodGhpcywgbmV3IEVSUl9NRVRIT0RfTk9UX0lNUExFTUVOVEVEKCdfcmVhZCgpJykpO1xufTtcblJlYWRhYmxlLnByb3RvdHlwZS5waXBlID0gZnVuY3Rpb24gKGRlc3QsIHBpcGVPcHRzKSB7XG4gIHZhciBzcmMgPSB0aGlzO1xuICB2YXIgc3RhdGUgPSB0aGlzLl9yZWFkYWJsZVN0YXRlO1xuICBzd2l0Y2ggKHN0YXRlLnBpcGVzQ291bnQpIHtcbiAgICBjYXNlIDA6XG4gICAgICBzdGF0ZS5waXBlcyA9IGRlc3Q7XG4gICAgICBicmVhaztcbiAgICBjYXNlIDE6XG4gICAgICBzdGF0ZS5waXBlcyA9IFtzdGF0ZS5waXBlcywgZGVzdF07XG4gICAgICBicmVhaztcbiAgICBkZWZhdWx0OlxuICAgICAgc3RhdGUucGlwZXMucHVzaChkZXN0KTtcbiAgICAgIGJyZWFrO1xuICB9XG4gIHN0YXRlLnBpcGVzQ291bnQgKz0gMTtcbiAgZGVidWcoJ3BpcGUgY291bnQ9JWQgb3B0cz0laicsIHN0YXRlLnBpcGVzQ291bnQsIHBpcGVPcHRzKTtcbiAgdmFyIGRvRW5kID0gKCFwaXBlT3B0cyB8fCBwaXBlT3B0cy5lbmQgIT09IGZhbHNlKSAmJiBkZXN0ICE9PSBwcm9jZXNzLnN0ZG91dCAmJiBkZXN0ICE9PSBwcm9jZXNzLnN0ZGVycjtcbiAgdmFyIGVuZEZuID0gZG9FbmQgPyBvbmVuZCA6IHVucGlwZTtcbiAgaWYgKHN0YXRlLmVuZEVtaXR0ZWQpIHByb2Nlc3MubmV4dFRpY2soZW5kRm4pO2Vsc2Ugc3JjLm9uY2UoJ2VuZCcsIGVuZEZuKTtcbiAgZGVzdC5vbigndW5waXBlJywgb251bnBpcGUpO1xuICBmdW5jdGlvbiBvbnVucGlwZShyZWFkYWJsZSwgdW5waXBlSW5mbykge1xuICAgIGRlYnVnKCdvbnVucGlwZScpO1xuICAgIGlmIChyZWFkYWJsZSA9PT0gc3JjKSB7XG4gICAgICBpZiAodW5waXBlSW5mbyAmJiB1bnBpcGVJbmZvLmhhc1VucGlwZWQgPT09IGZhbHNlKSB7XG4gICAgICAgIHVucGlwZUluZm8uaGFzVW5waXBlZCA9IHRydWU7XG4gICAgICAgIGNsZWFudXAoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgZnVuY3Rpb24gb25lbmQoKSB7XG4gICAgZGVidWcoJ29uZW5kJyk7XG4gICAgZGVzdC5lbmQoKTtcbiAgfVxuXG4gIC8vIHdoZW4gdGhlIGRlc3QgZHJhaW5zLCBpdCByZWR1Y2VzIHRoZSBhd2FpdERyYWluIGNvdW50ZXJcbiAgLy8gb24gdGhlIHNvdXJjZS4gIFRoaXMgd291bGQgYmUgbW9yZSBlbGVnYW50IHdpdGggYSAub25jZSgpXG4gIC8vIGhhbmRsZXIgaW4gZmxvdygpLCBidXQgYWRkaW5nIGFuZCByZW1vdmluZyByZXBlYXRlZGx5IGlzXG4gIC8vIHRvbyBzbG93LlxuICB2YXIgb25kcmFpbiA9IHBpcGVPbkRyYWluKHNyYyk7XG4gIGRlc3Qub24oJ2RyYWluJywgb25kcmFpbik7XG4gIHZhciBjbGVhbmVkVXAgPSBmYWxzZTtcbiAgZnVuY3Rpb24gY2xlYW51cCgpIHtcbiAgICBkZWJ1ZygnY2xlYW51cCcpO1xuICAgIC8vIGNsZWFudXAgZXZlbnQgaGFuZGxlcnMgb25jZSB0aGUgcGlwZSBpcyBicm9rZW5cbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdjbG9zZScsIG9uY2xvc2UpO1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2ZpbmlzaCcsIG9uZmluaXNoKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdkcmFpbicsIG9uZHJhaW4pO1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2Vycm9yJywgb25lcnJvcik7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcigndW5waXBlJywgb251bnBpcGUpO1xuICAgIHNyYy5yZW1vdmVMaXN0ZW5lcignZW5kJywgb25lbmQpO1xuICAgIHNyYy5yZW1vdmVMaXN0ZW5lcignZW5kJywgdW5waXBlKTtcbiAgICBzcmMucmVtb3ZlTGlzdGVuZXIoJ2RhdGEnLCBvbmRhdGEpO1xuICAgIGNsZWFuZWRVcCA9IHRydWU7XG5cbiAgICAvLyBpZiB0aGUgcmVhZGVyIGlzIHdhaXRpbmcgZm9yIGEgZHJhaW4gZXZlbnQgZnJvbSB0aGlzXG4gICAgLy8gc3BlY2lmaWMgd3JpdGVyLCB0aGVuIGl0IHdvdWxkIGNhdXNlIGl0IHRvIG5ldmVyIHN0YXJ0XG4gICAgLy8gZmxvd2luZyBhZ2Fpbi5cbiAgICAvLyBTbywgaWYgdGhpcyBpcyBhd2FpdGluZyBhIGRyYWluLCB0aGVuIHdlIGp1c3QgY2FsbCBpdCBub3cuXG4gICAgLy8gSWYgd2UgZG9uJ3Qga25vdywgdGhlbiBhc3N1bWUgdGhhdCB3ZSBhcmUgd2FpdGluZyBmb3Igb25lLlxuICAgIGlmIChzdGF0ZS5hd2FpdERyYWluICYmICghZGVzdC5fd3JpdGFibGVTdGF0ZSB8fCBkZXN0Ll93cml0YWJsZVN0YXRlLm5lZWREcmFpbikpIG9uZHJhaW4oKTtcbiAgfVxuICBzcmMub24oJ2RhdGEnLCBvbmRhdGEpO1xuICBmdW5jdGlvbiBvbmRhdGEoY2h1bmspIHtcbiAgICBkZWJ1Zygnb25kYXRhJyk7XG4gICAgdmFyIHJldCA9IGRlc3Qud3JpdGUoY2h1bmspO1xuICAgIGRlYnVnKCdkZXN0LndyaXRlJywgcmV0KTtcbiAgICBpZiAocmV0ID09PSBmYWxzZSkge1xuICAgICAgLy8gSWYgdGhlIHVzZXIgdW5waXBlZCBkdXJpbmcgYGRlc3Qud3JpdGUoKWAsIGl0IGlzIHBvc3NpYmxlXG4gICAgICAvLyB0byBnZXQgc3R1Y2sgaW4gYSBwZXJtYW5lbnRseSBwYXVzZWQgc3RhdGUgaWYgdGhhdCB3cml0ZVxuICAgICAgLy8gYWxzbyByZXR1cm5lZCBmYWxzZS5cbiAgICAgIC8vID0+IENoZWNrIHdoZXRoZXIgYGRlc3RgIGlzIHN0aWxsIGEgcGlwaW5nIGRlc3RpbmF0aW9uLlxuICAgICAgaWYgKChzdGF0ZS5waXBlc0NvdW50ID09PSAxICYmIHN0YXRlLnBpcGVzID09PSBkZXN0IHx8IHN0YXRlLnBpcGVzQ291bnQgPiAxICYmIGluZGV4T2Yoc3RhdGUucGlwZXMsIGRlc3QpICE9PSAtMSkgJiYgIWNsZWFuZWRVcCkge1xuICAgICAgICBkZWJ1ZygnZmFsc2Ugd3JpdGUgcmVzcG9uc2UsIHBhdXNlJywgc3RhdGUuYXdhaXREcmFpbik7XG4gICAgICAgIHN0YXRlLmF3YWl0RHJhaW4rKztcbiAgICAgIH1cbiAgICAgIHNyYy5wYXVzZSgpO1xuICAgIH1cbiAgfVxuXG4gIC8vIGlmIHRoZSBkZXN0IGhhcyBhbiBlcnJvciwgdGhlbiBzdG9wIHBpcGluZyBpbnRvIGl0LlxuICAvLyBob3dldmVyLCBkb24ndCBzdXBwcmVzcyB0aGUgdGhyb3dpbmcgYmVoYXZpb3IgZm9yIHRoaXMuXG4gIGZ1bmN0aW9uIG9uZXJyb3IoZXIpIHtcbiAgICBkZWJ1Zygnb25lcnJvcicsIGVyKTtcbiAgICB1bnBpcGUoKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdlcnJvcicsIG9uZXJyb3IpO1xuICAgIGlmIChFRWxpc3RlbmVyQ291bnQoZGVzdCwgJ2Vycm9yJykgPT09IDApIGVycm9yT3JEZXN0cm95KGRlc3QsIGVyKTtcbiAgfVxuXG4gIC8vIE1ha2Ugc3VyZSBvdXIgZXJyb3IgaGFuZGxlciBpcyBhdHRhY2hlZCBiZWZvcmUgdXNlcmxhbmQgb25lcy5cbiAgcHJlcGVuZExpc3RlbmVyKGRlc3QsICdlcnJvcicsIG9uZXJyb3IpO1xuXG4gIC8vIEJvdGggY2xvc2UgYW5kIGZpbmlzaCBzaG91bGQgdHJpZ2dlciB1bnBpcGUsIGJ1dCBvbmx5IG9uY2UuXG4gIGZ1bmN0aW9uIG9uY2xvc2UoKSB7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignZmluaXNoJywgb25maW5pc2gpO1xuICAgIHVucGlwZSgpO1xuICB9XG4gIGRlc3Qub25jZSgnY2xvc2UnLCBvbmNsb3NlKTtcbiAgZnVuY3Rpb24gb25maW5pc2goKSB7XG4gICAgZGVidWcoJ29uZmluaXNoJyk7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignY2xvc2UnLCBvbmNsb3NlKTtcbiAgICB1bnBpcGUoKTtcbiAgfVxuICBkZXN0Lm9uY2UoJ2ZpbmlzaCcsIG9uZmluaXNoKTtcbiAgZnVuY3Rpb24gdW5waXBlKCkge1xuICAgIGRlYnVnKCd1bnBpcGUnKTtcbiAgICBzcmMudW5waXBlKGRlc3QpO1xuICB9XG5cbiAgLy8gdGVsbCB0aGUgZGVzdCB0aGF0IGl0J3MgYmVpbmcgcGlwZWQgdG9cbiAgZGVzdC5lbWl0KCdwaXBlJywgc3JjKTtcblxuICAvLyBzdGFydCB0aGUgZmxvdyBpZiBpdCBoYXNuJ3QgYmVlbiBzdGFydGVkIGFscmVhZHkuXG4gIGlmICghc3RhdGUuZmxvd2luZykge1xuICAgIGRlYnVnKCdwaXBlIHJlc3VtZScpO1xuICAgIHNyYy5yZXN1bWUoKTtcbiAgfVxuICByZXR1cm4gZGVzdDtcbn07XG5mdW5jdGlvbiBwaXBlT25EcmFpbihzcmMpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIHBpcGVPbkRyYWluRnVuY3Rpb25SZXN1bHQoKSB7XG4gICAgdmFyIHN0YXRlID0gc3JjLl9yZWFkYWJsZVN0YXRlO1xuICAgIGRlYnVnKCdwaXBlT25EcmFpbicsIHN0YXRlLmF3YWl0RHJhaW4pO1xuICAgIGlmIChzdGF0ZS5hd2FpdERyYWluKSBzdGF0ZS5hd2FpdERyYWluLS07XG4gICAgaWYgKHN0YXRlLmF3YWl0RHJhaW4gPT09IDAgJiYgRUVsaXN0ZW5lckNvdW50KHNyYywgJ2RhdGEnKSkge1xuICAgICAgc3RhdGUuZmxvd2luZyA9IHRydWU7XG4gICAgICBmbG93KHNyYyk7XG4gICAgfVxuICB9O1xufVxuUmVhZGFibGUucHJvdG90eXBlLnVucGlwZSA9IGZ1bmN0aW9uIChkZXN0KSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gIHZhciB1bnBpcGVJbmZvID0ge1xuICAgIGhhc1VucGlwZWQ6IGZhbHNlXG4gIH07XG5cbiAgLy8gaWYgd2UncmUgbm90IHBpcGluZyBhbnl3aGVyZSwgdGhlbiBkbyBub3RoaW5nLlxuICBpZiAoc3RhdGUucGlwZXNDb3VudCA9PT0gMCkgcmV0dXJuIHRoaXM7XG5cbiAgLy8ganVzdCBvbmUgZGVzdGluYXRpb24uICBtb3N0IGNvbW1vbiBjYXNlLlxuICBpZiAoc3RhdGUucGlwZXNDb3VudCA9PT0gMSkge1xuICAgIC8vIHBhc3NlZCBpbiBvbmUsIGJ1dCBpdCdzIG5vdCB0aGUgcmlnaHQgb25lLlxuICAgIGlmIChkZXN0ICYmIGRlc3QgIT09IHN0YXRlLnBpcGVzKSByZXR1cm4gdGhpcztcbiAgICBpZiAoIWRlc3QpIGRlc3QgPSBzdGF0ZS5waXBlcztcblxuICAgIC8vIGdvdCBhIG1hdGNoLlxuICAgIHN0YXRlLnBpcGVzID0gbnVsbDtcbiAgICBzdGF0ZS5waXBlc0NvdW50ID0gMDtcbiAgICBzdGF0ZS5mbG93aW5nID0gZmFsc2U7XG4gICAgaWYgKGRlc3QpIGRlc3QuZW1pdCgndW5waXBlJywgdGhpcywgdW5waXBlSW5mbyk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLyBzbG93IGNhc2UuIG11bHRpcGxlIHBpcGUgZGVzdGluYXRpb25zLlxuXG4gIGlmICghZGVzdCkge1xuICAgIC8vIHJlbW92ZSBhbGwuXG4gICAgdmFyIGRlc3RzID0gc3RhdGUucGlwZXM7XG4gICAgdmFyIGxlbiA9IHN0YXRlLnBpcGVzQ291bnQ7XG4gICAgc3RhdGUucGlwZXMgPSBudWxsO1xuICAgIHN0YXRlLnBpcGVzQ291bnQgPSAwO1xuICAgIHN0YXRlLmZsb3dpbmcgPSBmYWxzZTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSBkZXN0c1tpXS5lbWl0KCd1bnBpcGUnLCB0aGlzLCB7XG4gICAgICBoYXNVbnBpcGVkOiBmYWxzZVxuICAgIH0pO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gdHJ5IHRvIGZpbmQgdGhlIHJpZ2h0IG9uZS5cbiAgdmFyIGluZGV4ID0gaW5kZXhPZihzdGF0ZS5waXBlcywgZGVzdCk7XG4gIGlmIChpbmRleCA9PT0gLTEpIHJldHVybiB0aGlzO1xuICBzdGF0ZS5waXBlcy5zcGxpY2UoaW5kZXgsIDEpO1xuICBzdGF0ZS5waXBlc0NvdW50IC09IDE7XG4gIGlmIChzdGF0ZS5waXBlc0NvdW50ID09PSAxKSBzdGF0ZS5waXBlcyA9IHN0YXRlLnBpcGVzWzBdO1xuICBkZXN0LmVtaXQoJ3VucGlwZScsIHRoaXMsIHVucGlwZUluZm8pO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8vIHNldCB1cCBkYXRhIGV2ZW50cyBpZiB0aGV5IGFyZSBhc2tlZCBmb3Jcbi8vIEVuc3VyZSByZWFkYWJsZSBsaXN0ZW5lcnMgZXZlbnR1YWxseSBnZXQgc29tZXRoaW5nXG5SZWFkYWJsZS5wcm90b3R5cGUub24gPSBmdW5jdGlvbiAoZXYsIGZuKSB7XG4gIHZhciByZXMgPSBTdHJlYW0ucHJvdG90eXBlLm9uLmNhbGwodGhpcywgZXYsIGZuKTtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcbiAgaWYgKGV2ID09PSAnZGF0YScpIHtcbiAgICAvLyB1cGRhdGUgcmVhZGFibGVMaXN0ZW5pbmcgc28gdGhhdCByZXN1bWUoKSBtYXkgYmUgYSBuby1vcFxuICAgIC8vIGEgZmV3IGxpbmVzIGRvd24uIFRoaXMgaXMgbmVlZGVkIHRvIHN1cHBvcnQgb25jZSgncmVhZGFibGUnKS5cbiAgICBzdGF0ZS5yZWFkYWJsZUxpc3RlbmluZyA9IHRoaXMubGlzdGVuZXJDb3VudCgncmVhZGFibGUnKSA+IDA7XG5cbiAgICAvLyBUcnkgc3RhcnQgZmxvd2luZyBvbiBuZXh0IHRpY2sgaWYgc3RyZWFtIGlzbid0IGV4cGxpY2l0bHkgcGF1c2VkXG4gICAgaWYgKHN0YXRlLmZsb3dpbmcgIT09IGZhbHNlKSB0aGlzLnJlc3VtZSgpO1xuICB9IGVsc2UgaWYgKGV2ID09PSAncmVhZGFibGUnKSB7XG4gICAgaWYgKCFzdGF0ZS5lbmRFbWl0dGVkICYmICFzdGF0ZS5yZWFkYWJsZUxpc3RlbmluZykge1xuICAgICAgc3RhdGUucmVhZGFibGVMaXN0ZW5pbmcgPSBzdGF0ZS5uZWVkUmVhZGFibGUgPSB0cnVlO1xuICAgICAgc3RhdGUuZmxvd2luZyA9IGZhbHNlO1xuICAgICAgc3RhdGUuZW1pdHRlZFJlYWRhYmxlID0gZmFsc2U7XG4gICAgICBkZWJ1Zygnb24gcmVhZGFibGUnLCBzdGF0ZS5sZW5ndGgsIHN0YXRlLnJlYWRpbmcpO1xuICAgICAgaWYgKHN0YXRlLmxlbmd0aCkge1xuICAgICAgICBlbWl0UmVhZGFibGUodGhpcyk7XG4gICAgICB9IGVsc2UgaWYgKCFzdGF0ZS5yZWFkaW5nKSB7XG4gICAgICAgIHByb2Nlc3MubmV4dFRpY2soblJlYWRpbmdOZXh0VGljaywgdGhpcyk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiByZXM7XG59O1xuUmVhZGFibGUucHJvdG90eXBlLmFkZExpc3RlbmVyID0gUmVhZGFibGUucHJvdG90eXBlLm9uO1xuUmVhZGFibGUucHJvdG90eXBlLnJlbW92ZUxpc3RlbmVyID0gZnVuY3Rpb24gKGV2LCBmbikge1xuICB2YXIgcmVzID0gU3RyZWFtLnByb3RvdHlwZS5yZW1vdmVMaXN0ZW5lci5jYWxsKHRoaXMsIGV2LCBmbik7XG4gIGlmIChldiA9PT0gJ3JlYWRhYmxlJykge1xuICAgIC8vIFdlIG5lZWQgdG8gY2hlY2sgaWYgdGhlcmUgaXMgc29tZW9uZSBzdGlsbCBsaXN0ZW5pbmcgdG9cbiAgICAvLyByZWFkYWJsZSBhbmQgcmVzZXQgdGhlIHN0YXRlLiBIb3dldmVyIHRoaXMgbmVlZHMgdG8gaGFwcGVuXG4gICAgLy8gYWZ0ZXIgcmVhZGFibGUgaGFzIGJlZW4gZW1pdHRlZCBidXQgYmVmb3JlIEkvTyAobmV4dFRpY2spIHRvXG4gICAgLy8gc3VwcG9ydCBvbmNlKCdyZWFkYWJsZScsIGZuKSBjeWNsZXMuIFRoaXMgbWVhbnMgdGhhdCBjYWxsaW5nXG4gICAgLy8gcmVzdW1lIHdpdGhpbiB0aGUgc2FtZSB0aWNrIHdpbGwgaGF2ZSBub1xuICAgIC8vIGVmZmVjdC5cbiAgICBwcm9jZXNzLm5leHRUaWNrKHVwZGF0ZVJlYWRhYmxlTGlzdGVuaW5nLCB0aGlzKTtcbiAgfVxuICByZXR1cm4gcmVzO1xufTtcblJlYWRhYmxlLnByb3RvdHlwZS5yZW1vdmVBbGxMaXN0ZW5lcnMgPSBmdW5jdGlvbiAoZXYpIHtcbiAgdmFyIHJlcyA9IFN0cmVhbS5wcm90b3R5cGUucmVtb3ZlQWxsTGlzdGVuZXJzLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gIGlmIChldiA9PT0gJ3JlYWRhYmxlJyB8fCBldiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgLy8gV2UgbmVlZCB0byBjaGVjayBpZiB0aGVyZSBpcyBzb21lb25lIHN0aWxsIGxpc3RlbmluZyB0b1xuICAgIC8vIHJlYWRhYmxlIGFuZCByZXNldCB0aGUgc3RhdGUuIEhvd2V2ZXIgdGhpcyBuZWVkcyB0byBoYXBwZW5cbiAgICAvLyBhZnRlciByZWFkYWJsZSBoYXMgYmVlbiBlbWl0dGVkIGJ1dCBiZWZvcmUgSS9PIChuZXh0VGljaykgdG9cbiAgICAvLyBzdXBwb3J0IG9uY2UoJ3JlYWRhYmxlJywgZm4pIGN5Y2xlcy4gVGhpcyBtZWFucyB0aGF0IGNhbGxpbmdcbiAgICAvLyByZXN1bWUgd2l0aGluIHRoZSBzYW1lIHRpY2sgd2lsbCBoYXZlIG5vXG4gICAgLy8gZWZmZWN0LlxuICAgIHByb2Nlc3MubmV4dFRpY2sodXBkYXRlUmVhZGFibGVMaXN0ZW5pbmcsIHRoaXMpO1xuICB9XG4gIHJldHVybiByZXM7XG59O1xuZnVuY3Rpb24gdXBkYXRlUmVhZGFibGVMaXN0ZW5pbmcoc2VsZikge1xuICB2YXIgc3RhdGUgPSBzZWxmLl9yZWFkYWJsZVN0YXRlO1xuICBzdGF0ZS5yZWFkYWJsZUxpc3RlbmluZyA9IHNlbGYubGlzdGVuZXJDb3VudCgncmVhZGFibGUnKSA+IDA7XG4gIGlmIChzdGF0ZS5yZXN1bWVTY2hlZHVsZWQgJiYgIXN0YXRlLnBhdXNlZCkge1xuICAgIC8vIGZsb3dpbmcgbmVlZHMgdG8gYmUgc2V0IHRvIHRydWUgbm93LCBvdGhlcndpc2VcbiAgICAvLyB0aGUgdXBjb21pbmcgcmVzdW1lIHdpbGwgbm90IGZsb3cuXG4gICAgc3RhdGUuZmxvd2luZyA9IHRydWU7XG5cbiAgICAvLyBjcnVkZSB3YXkgdG8gY2hlY2sgaWYgd2Ugc2hvdWxkIHJlc3VtZVxuICB9IGVsc2UgaWYgKHNlbGYubGlzdGVuZXJDb3VudCgnZGF0YScpID4gMCkge1xuICAgIHNlbGYucmVzdW1lKCk7XG4gIH1cbn1cbmZ1bmN0aW9uIG5SZWFkaW5nTmV4dFRpY2soc2VsZikge1xuICBkZWJ1ZygncmVhZGFibGUgbmV4dHRpY2sgcmVhZCAwJyk7XG4gIHNlbGYucmVhZCgwKTtcbn1cblxuLy8gcGF1c2UoKSBhbmQgcmVzdW1lKCkgYXJlIHJlbW5hbnRzIG9mIHRoZSBsZWdhY3kgcmVhZGFibGUgc3RyZWFtIEFQSVxuLy8gSWYgdGhlIHVzZXIgdXNlcyB0aGVtLCB0aGVuIHN3aXRjaCBpbnRvIG9sZCBtb2RlLlxuUmVhZGFibGUucHJvdG90eXBlLnJlc3VtZSA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcbiAgaWYgKCFzdGF0ZS5mbG93aW5nKSB7XG4gICAgZGVidWcoJ3Jlc3VtZScpO1xuICAgIC8vIHdlIGZsb3cgb25seSBpZiB0aGVyZSBpcyBubyBvbmUgbGlzdGVuaW5nXG4gICAgLy8gZm9yIHJlYWRhYmxlLCBidXQgd2Ugc3RpbGwgaGF2ZSB0byBjYWxsXG4gICAgLy8gcmVzdW1lKClcbiAgICBzdGF0ZS5mbG93aW5nID0gIXN0YXRlLnJlYWRhYmxlTGlzdGVuaW5nO1xuICAgIHJlc3VtZSh0aGlzLCBzdGF0ZSk7XG4gIH1cbiAgc3RhdGUucGF1c2VkID0gZmFsc2U7XG4gIHJldHVybiB0aGlzO1xufTtcbmZ1bmN0aW9uIHJlc3VtZShzdHJlYW0sIHN0YXRlKSB7XG4gIGlmICghc3RhdGUucmVzdW1lU2NoZWR1bGVkKSB7XG4gICAgc3RhdGUucmVzdW1lU2NoZWR1bGVkID0gdHJ1ZTtcbiAgICBwcm9jZXNzLm5leHRUaWNrKHJlc3VtZV8sIHN0cmVhbSwgc3RhdGUpO1xuICB9XG59XG5mdW5jdGlvbiByZXN1bWVfKHN0cmVhbSwgc3RhdGUpIHtcbiAgZGVidWcoJ3Jlc3VtZScsIHN0YXRlLnJlYWRpbmcpO1xuICBpZiAoIXN0YXRlLnJlYWRpbmcpIHtcbiAgICBzdHJlYW0ucmVhZCgwKTtcbiAgfVxuICBzdGF0ZS5yZXN1bWVTY2hlZHVsZWQgPSBmYWxzZTtcbiAgc3RyZWFtLmVtaXQoJ3Jlc3VtZScpO1xuICBmbG93KHN0cmVhbSk7XG4gIGlmIChzdGF0ZS5mbG93aW5nICYmICFzdGF0ZS5yZWFkaW5nKSBzdHJlYW0ucmVhZCgwKTtcbn1cblJlYWRhYmxlLnByb3RvdHlwZS5wYXVzZSA9IGZ1bmN0aW9uICgpIHtcbiAgZGVidWcoJ2NhbGwgcGF1c2UgZmxvd2luZz0laicsIHRoaXMuX3JlYWRhYmxlU3RhdGUuZmxvd2luZyk7XG4gIGlmICh0aGlzLl9yZWFkYWJsZVN0YXRlLmZsb3dpbmcgIT09IGZhbHNlKSB7XG4gICAgZGVidWcoJ3BhdXNlJyk7XG4gICAgdGhpcy5fcmVhZGFibGVTdGF0ZS5mbG93aW5nID0gZmFsc2U7XG4gICAgdGhpcy5lbWl0KCdwYXVzZScpO1xuICB9XG4gIHRoaXMuX3JlYWRhYmxlU3RhdGUucGF1c2VkID0gdHJ1ZTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuZnVuY3Rpb24gZmxvdyhzdHJlYW0pIHtcbiAgdmFyIHN0YXRlID0gc3RyZWFtLl9yZWFkYWJsZVN0YXRlO1xuICBkZWJ1ZygnZmxvdycsIHN0YXRlLmZsb3dpbmcpO1xuICB3aGlsZSAoc3RhdGUuZmxvd2luZyAmJiBzdHJlYW0ucmVhZCgpICE9PSBudWxsKTtcbn1cblxuLy8gd3JhcCBhbiBvbGQtc3R5bGUgc3RyZWFtIGFzIHRoZSBhc3luYyBkYXRhIHNvdXJjZS5cbi8vIFRoaXMgaXMgKm5vdCogcGFydCBvZiB0aGUgcmVhZGFibGUgc3RyZWFtIGludGVyZmFjZS5cbi8vIEl0IGlzIGFuIHVnbHkgdW5mb3J0dW5hdGUgbWVzcyBvZiBoaXN0b3J5LlxuUmVhZGFibGUucHJvdG90eXBlLndyYXAgPSBmdW5jdGlvbiAoc3RyZWFtKSB7XG4gIHZhciBfdGhpcyA9IHRoaXM7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gIHZhciBwYXVzZWQgPSBmYWxzZTtcbiAgc3RyZWFtLm9uKCdlbmQnLCBmdW5jdGlvbiAoKSB7XG4gICAgZGVidWcoJ3dyYXBwZWQgZW5kJyk7XG4gICAgaWYgKHN0YXRlLmRlY29kZXIgJiYgIXN0YXRlLmVuZGVkKSB7XG4gICAgICB2YXIgY2h1bmsgPSBzdGF0ZS5kZWNvZGVyLmVuZCgpO1xuICAgICAgaWYgKGNodW5rICYmIGNodW5rLmxlbmd0aCkgX3RoaXMucHVzaChjaHVuayk7XG4gICAgfVxuICAgIF90aGlzLnB1c2gobnVsbCk7XG4gIH0pO1xuICBzdHJlYW0ub24oJ2RhdGEnLCBmdW5jdGlvbiAoY2h1bmspIHtcbiAgICBkZWJ1Zygnd3JhcHBlZCBkYXRhJyk7XG4gICAgaWYgKHN0YXRlLmRlY29kZXIpIGNodW5rID0gc3RhdGUuZGVjb2Rlci53cml0ZShjaHVuayk7XG5cbiAgICAvLyBkb24ndCBza2lwIG92ZXIgZmFsc3kgdmFsdWVzIGluIG9iamVjdE1vZGVcbiAgICBpZiAoc3RhdGUub2JqZWN0TW9kZSAmJiAoY2h1bmsgPT09IG51bGwgfHwgY2h1bmsgPT09IHVuZGVmaW5lZCkpIHJldHVybjtlbHNlIGlmICghc3RhdGUub2JqZWN0TW9kZSAmJiAoIWNodW5rIHx8ICFjaHVuay5sZW5ndGgpKSByZXR1cm47XG4gICAgdmFyIHJldCA9IF90aGlzLnB1c2goY2h1bmspO1xuICAgIGlmICghcmV0KSB7XG4gICAgICBwYXVzZWQgPSB0cnVlO1xuICAgICAgc3RyZWFtLnBhdXNlKCk7XG4gICAgfVxuICB9KTtcblxuICAvLyBwcm94eSBhbGwgdGhlIG90aGVyIG1ldGhvZHMuXG4gIC8vIGltcG9ydGFudCB3aGVuIHdyYXBwaW5nIGZpbHRlcnMgYW5kIGR1cGxleGVzLlxuICBmb3IgKHZhciBpIGluIHN0cmVhbSkge1xuICAgIGlmICh0aGlzW2ldID09PSB1bmRlZmluZWQgJiYgdHlwZW9mIHN0cmVhbVtpXSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdGhpc1tpXSA9IGZ1bmN0aW9uIG1ldGhvZFdyYXAobWV0aG9kKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiBtZXRob2RXcmFwUmV0dXJuRnVuY3Rpb24oKSB7XG4gICAgICAgICAgcmV0dXJuIHN0cmVhbVttZXRob2RdLmFwcGx5KHN0cmVhbSwgYXJndW1lbnRzKTtcbiAgICAgICAgfTtcbiAgICAgIH0oaSk7XG4gICAgfVxuICB9XG5cbiAgLy8gcHJveHkgY2VydGFpbiBpbXBvcnRhbnQgZXZlbnRzLlxuICBmb3IgKHZhciBuID0gMDsgbiA8IGtQcm94eUV2ZW50cy5sZW5ndGg7IG4rKykge1xuICAgIHN0cmVhbS5vbihrUHJveHlFdmVudHNbbl0sIHRoaXMuZW1pdC5iaW5kKHRoaXMsIGtQcm94eUV2ZW50c1tuXSkpO1xuICB9XG5cbiAgLy8gd2hlbiB3ZSB0cnkgdG8gY29uc3VtZSBzb21lIG1vcmUgYnl0ZXMsIHNpbXBseSB1bnBhdXNlIHRoZVxuICAvLyB1bmRlcmx5aW5nIHN0cmVhbS5cbiAgdGhpcy5fcmVhZCA9IGZ1bmN0aW9uIChuKSB7XG4gICAgZGVidWcoJ3dyYXBwZWQgX3JlYWQnLCBuKTtcbiAgICBpZiAocGF1c2VkKSB7XG4gICAgICBwYXVzZWQgPSBmYWxzZTtcbiAgICAgIHN0cmVhbS5yZXN1bWUoKTtcbiAgICB9XG4gIH07XG4gIHJldHVybiB0aGlzO1xufTtcbmlmICh0eXBlb2YgU3ltYm9sID09PSAnZnVuY3Rpb24nKSB7XG4gIFJlYWRhYmxlLnByb3RvdHlwZVtTeW1ib2wuYXN5bmNJdGVyYXRvcl0gPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKGNyZWF0ZVJlYWRhYmxlU3RyZWFtQXN5bmNJdGVyYXRvciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBjcmVhdGVSZWFkYWJsZVN0cmVhbUFzeW5jSXRlcmF0b3IgPSByZXF1aXJlKCcuL2ludGVybmFsL3N0cmVhbXMvYXN5bmNfaXRlcmF0b3InKTtcbiAgICB9XG4gICAgcmV0dXJuIGNyZWF0ZVJlYWRhYmxlU3RyZWFtQXN5bmNJdGVyYXRvcih0aGlzKTtcbiAgfTtcbn1cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZWFkYWJsZS5wcm90b3R5cGUsICdyZWFkYWJsZUhpZ2hXYXRlck1hcmsnLCB7XG4gIC8vIG1ha2luZyBpdCBleHBsaWNpdCB0aGlzIHByb3BlcnR5IGlzIG5vdCBlbnVtZXJhYmxlXG4gIC8vIGJlY2F1c2Ugb3RoZXJ3aXNlIHNvbWUgcHJvdG90eXBlIG1hbmlwdWxhdGlvbiBpblxuICAvLyB1c2VybGFuZCB3aWxsIGZhaWxcbiAgZW51bWVyYWJsZTogZmFsc2UsXG4gIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgIHJldHVybiB0aGlzLl9yZWFkYWJsZVN0YXRlLmhpZ2hXYXRlck1hcms7XG4gIH1cbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlYWRhYmxlLnByb3RvdHlwZSwgJ3JlYWRhYmxlQnVmZmVyJywge1xuICAvLyBtYWtpbmcgaXQgZXhwbGljaXQgdGhpcyBwcm9wZXJ0eSBpcyBub3QgZW51bWVyYWJsZVxuICAvLyBiZWNhdXNlIG90aGVyd2lzZSBzb21lIHByb3RvdHlwZSBtYW5pcHVsYXRpb24gaW5cbiAgLy8gdXNlcmxhbmQgd2lsbCBmYWlsXG4gIGVudW1lcmFibGU6IGZhbHNlLFxuICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICByZXR1cm4gdGhpcy5fcmVhZGFibGVTdGF0ZSAmJiB0aGlzLl9yZWFkYWJsZVN0YXRlLmJ1ZmZlcjtcbiAgfVxufSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoUmVhZGFibGUucHJvdG90eXBlLCAncmVhZGFibGVGbG93aW5nJywge1xuICAvLyBtYWtpbmcgaXQgZXhwbGljaXQgdGhpcyBwcm9wZXJ0eSBpcyBub3QgZW51bWVyYWJsZVxuICAvLyBiZWNhdXNlIG90aGVyd2lzZSBzb21lIHByb3RvdHlwZSBtYW5pcHVsYXRpb24gaW5cbiAgLy8gdXNlcmxhbmQgd2lsbCBmYWlsXG4gIGVudW1lcmFibGU6IGZhbHNlLFxuICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICByZXR1cm4gdGhpcy5fcmVhZGFibGVTdGF0ZS5mbG93aW5nO1xuICB9LFxuICBzZXQ6IGZ1bmN0aW9uIHNldChzdGF0ZSkge1xuICAgIGlmICh0aGlzLl9yZWFkYWJsZVN0YXRlKSB7XG4gICAgICB0aGlzLl9yZWFkYWJsZVN0YXRlLmZsb3dpbmcgPSBzdGF0ZTtcbiAgICB9XG4gIH1cbn0pO1xuXG4vLyBleHBvc2VkIGZvciB0ZXN0aW5nIHB1cnBvc2VzIG9ubHkuXG5SZWFkYWJsZS5fZnJvbUxpc3QgPSBmcm9tTGlzdDtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZWFkYWJsZS5wcm90b3R5cGUsICdyZWFkYWJsZUxlbmd0aCcsIHtcbiAgLy8gbWFraW5nIGl0IGV4cGxpY2l0IHRoaXMgcHJvcGVydHkgaXMgbm90IGVudW1lcmFibGVcbiAgLy8gYmVjYXVzZSBvdGhlcndpc2Ugc29tZSBwcm90b3R5cGUgbWFuaXB1bGF0aW9uIGluXG4gIC8vIHVzZXJsYW5kIHdpbGwgZmFpbFxuICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3JlYWRhYmxlU3RhdGUubGVuZ3RoO1xuICB9XG59KTtcblxuLy8gUGx1Y2sgb2ZmIG4gYnl0ZXMgZnJvbSBhbiBhcnJheSBvZiBidWZmZXJzLlxuLy8gTGVuZ3RoIGlzIHRoZSBjb21iaW5lZCBsZW5ndGhzIG9mIGFsbCB0aGUgYnVmZmVycyBpbiB0aGUgbGlzdC5cbi8vIFRoaXMgZnVuY3Rpb24gaXMgZGVzaWduZWQgdG8gYmUgaW5saW5hYmxlLCBzbyBwbGVhc2UgdGFrZSBjYXJlIHdoZW4gbWFraW5nXG4vLyBjaGFuZ2VzIHRvIHRoZSBmdW5jdGlvbiBib2R5LlxuZnVuY3Rpb24gZnJvbUxpc3Qobiwgc3RhdGUpIHtcbiAgLy8gbm90aGluZyBidWZmZXJlZFxuICBpZiAoc3RhdGUubGVuZ3RoID09PSAwKSByZXR1cm4gbnVsbDtcbiAgdmFyIHJldDtcbiAgaWYgKHN0YXRlLm9iamVjdE1vZGUpIHJldCA9IHN0YXRlLmJ1ZmZlci5zaGlmdCgpO2Vsc2UgaWYgKCFuIHx8IG4gPj0gc3RhdGUubGVuZ3RoKSB7XG4gICAgLy8gcmVhZCBpdCBhbGwsIHRydW5jYXRlIHRoZSBsaXN0XG4gICAgaWYgKHN0YXRlLmRlY29kZXIpIHJldCA9IHN0YXRlLmJ1ZmZlci5qb2luKCcnKTtlbHNlIGlmIChzdGF0ZS5idWZmZXIubGVuZ3RoID09PSAxKSByZXQgPSBzdGF0ZS5idWZmZXIuZmlyc3QoKTtlbHNlIHJldCA9IHN0YXRlLmJ1ZmZlci5jb25jYXQoc3RhdGUubGVuZ3RoKTtcbiAgICBzdGF0ZS5idWZmZXIuY2xlYXIoKTtcbiAgfSBlbHNlIHtcbiAgICAvLyByZWFkIHBhcnQgb2YgbGlzdFxuICAgIHJldCA9IHN0YXRlLmJ1ZmZlci5jb25zdW1lKG4sIHN0YXRlLmRlY29kZXIpO1xuICB9XG4gIHJldHVybiByZXQ7XG59XG5mdW5jdGlvbiBlbmRSZWFkYWJsZShzdHJlYW0pIHtcbiAgdmFyIHN0YXRlID0gc3RyZWFtLl9yZWFkYWJsZVN0YXRlO1xuICBkZWJ1ZygnZW5kUmVhZGFibGUnLCBzdGF0ZS5lbmRFbWl0dGVkKTtcbiAgaWYgKCFzdGF0ZS5lbmRFbWl0dGVkKSB7XG4gICAgc3RhdGUuZW5kZWQgPSB0cnVlO1xuICAgIHByb2Nlc3MubmV4dFRpY2soZW5kUmVhZGFibGVOVCwgc3RhdGUsIHN0cmVhbSk7XG4gIH1cbn1cbmZ1bmN0aW9uIGVuZFJlYWRhYmxlTlQoc3RhdGUsIHN0cmVhbSkge1xuICBkZWJ1ZygnZW5kUmVhZGFibGVOVCcsIHN0YXRlLmVuZEVtaXR0ZWQsIHN0YXRlLmxlbmd0aCk7XG5cbiAgLy8gQ2hlY2sgdGhhdCB3ZSBkaWRuJ3QgZ2V0IG9uZSBsYXN0IHVuc2hpZnQuXG4gIGlmICghc3RhdGUuZW5kRW1pdHRlZCAmJiBzdGF0ZS5sZW5ndGggPT09IDApIHtcbiAgICBzdGF0ZS5lbmRFbWl0dGVkID0gdHJ1ZTtcbiAgICBzdHJlYW0ucmVhZGFibGUgPSBmYWxzZTtcbiAgICBzdHJlYW0uZW1pdCgnZW5kJyk7XG4gICAgaWYgKHN0YXRlLmF1dG9EZXN0cm95KSB7XG4gICAgICAvLyBJbiBjYXNlIG9mIGR1cGxleCBzdHJlYW1zIHdlIG5lZWQgYSB3YXkgdG8gZGV0ZWN0XG4gICAgICAvLyBpZiB0aGUgd3JpdGFibGUgc2lkZSBpcyByZWFkeSBmb3IgYXV0b0Rlc3Ryb3kgYXMgd2VsbFxuICAgICAgdmFyIHdTdGF0ZSA9IHN0cmVhbS5fd3JpdGFibGVTdGF0ZTtcbiAgICAgIGlmICghd1N0YXRlIHx8IHdTdGF0ZS5hdXRvRGVzdHJveSAmJiB3U3RhdGUuZmluaXNoZWQpIHtcbiAgICAgICAgc3RyZWFtLmRlc3Ryb3koKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cbmlmICh0eXBlb2YgU3ltYm9sID09PSAnZnVuY3Rpb24nKSB7XG4gIFJlYWRhYmxlLmZyb20gPSBmdW5jdGlvbiAoaXRlcmFibGUsIG9wdHMpIHtcbiAgICBpZiAoZnJvbSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBmcm9tID0gcmVxdWlyZSgnLi9pbnRlcm5hbC9zdHJlYW1zL2Zyb20nKTtcbiAgICB9XG4gICAgcmV0dXJuIGZyb20oUmVhZGFibGUsIGl0ZXJhYmxlLCBvcHRzKTtcbiAgfTtcbn1cbmZ1bmN0aW9uIGluZGV4T2YoeHMsIHgpIHtcbiAgZm9yICh2YXIgaSA9IDAsIGwgPSB4cy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICBpZiAoeHNbaV0gPT09IHgpIHJldHVybiBpO1xuICB9XG4gIHJldHVybiAtMTtcbn0iLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxuLy8gYSB0cmFuc2Zvcm0gc3RyZWFtIGlzIGEgcmVhZGFibGUvd3JpdGFibGUgc3RyZWFtIHdoZXJlIHlvdSBkb1xuLy8gc29tZXRoaW5nIHdpdGggdGhlIGRhdGEuICBTb21ldGltZXMgaXQncyBjYWxsZWQgYSBcImZpbHRlclwiLFxuLy8gYnV0IHRoYXQncyBub3QgYSBncmVhdCBuYW1lIGZvciBpdCwgc2luY2UgdGhhdCBpbXBsaWVzIGEgdGhpbmcgd2hlcmVcbi8vIHNvbWUgYml0cyBwYXNzIHRocm91Z2gsIGFuZCBvdGhlcnMgYXJlIHNpbXBseSBpZ25vcmVkLiAgKFRoYXQgd291bGRcbi8vIGJlIGEgdmFsaWQgZXhhbXBsZSBvZiBhIHRyYW5zZm9ybSwgb2YgY291cnNlLilcbi8vXG4vLyBXaGlsZSB0aGUgb3V0cHV0IGlzIGNhdXNhbGx5IHJlbGF0ZWQgdG8gdGhlIGlucHV0LCBpdCdzIG5vdCBhXG4vLyBuZWNlc3NhcmlseSBzeW1tZXRyaWMgb3Igc3luY2hyb25vdXMgdHJhbnNmb3JtYXRpb24uICBGb3IgZXhhbXBsZSxcbi8vIGEgemxpYiBzdHJlYW0gbWlnaHQgdGFrZSBtdWx0aXBsZSBwbGFpbi10ZXh0IHdyaXRlcygpLCBhbmQgdGhlblxuLy8gZW1pdCBhIHNpbmdsZSBjb21wcmVzc2VkIGNodW5rIHNvbWUgdGltZSBpbiB0aGUgZnV0dXJlLlxuLy9cbi8vIEhlcmUncyBob3cgdGhpcyB3b3Jrczpcbi8vXG4vLyBUaGUgVHJhbnNmb3JtIHN0cmVhbSBoYXMgYWxsIHRoZSBhc3BlY3RzIG9mIHRoZSByZWFkYWJsZSBhbmQgd3JpdGFibGVcbi8vIHN0cmVhbSBjbGFzc2VzLiAgV2hlbiB5b3Ugd3JpdGUoY2h1bmspLCB0aGF0IGNhbGxzIF93cml0ZShjaHVuayxjYilcbi8vIGludGVybmFsbHksIGFuZCByZXR1cm5zIGZhbHNlIGlmIHRoZXJlJ3MgYSBsb3Qgb2YgcGVuZGluZyB3cml0ZXNcbi8vIGJ1ZmZlcmVkIHVwLiAgV2hlbiB5b3UgY2FsbCByZWFkKCksIHRoYXQgY2FsbHMgX3JlYWQobikgdW50aWxcbi8vIHRoZXJlJ3MgZW5vdWdoIHBlbmRpbmcgcmVhZGFibGUgZGF0YSBidWZmZXJlZCB1cC5cbi8vXG4vLyBJbiBhIHRyYW5zZm9ybSBzdHJlYW0sIHRoZSB3cml0dGVuIGRhdGEgaXMgcGxhY2VkIGluIGEgYnVmZmVyLiAgV2hlblxuLy8gX3JlYWQobikgaXMgY2FsbGVkLCBpdCB0cmFuc2Zvcm1zIHRoZSBxdWV1ZWQgdXAgZGF0YSwgY2FsbGluZyB0aGVcbi8vIGJ1ZmZlcmVkIF93cml0ZSBjYidzIGFzIGl0IGNvbnN1bWVzIGNodW5rcy4gIElmIGNvbnN1bWluZyBhIHNpbmdsZVxuLy8gd3JpdHRlbiBjaHVuayB3b3VsZCByZXN1bHQgaW4gbXVsdGlwbGUgb3V0cHV0IGNodW5rcywgdGhlbiB0aGUgZmlyc3Rcbi8vIG91dHB1dHRlZCBiaXQgY2FsbHMgdGhlIHJlYWRjYiwgYW5kIHN1YnNlcXVlbnQgY2h1bmtzIGp1c3QgZ28gaW50b1xuLy8gdGhlIHJlYWQgYnVmZmVyLCBhbmQgd2lsbCBjYXVzZSBpdCB0byBlbWl0ICdyZWFkYWJsZScgaWYgbmVjZXNzYXJ5LlxuLy9cbi8vIFRoaXMgd2F5LCBiYWNrLXByZXNzdXJlIGlzIGFjdHVhbGx5IGRldGVybWluZWQgYnkgdGhlIHJlYWRpbmcgc2lkZSxcbi8vIHNpbmNlIF9yZWFkIGhhcyB0byBiZSBjYWxsZWQgdG8gc3RhcnQgcHJvY2Vzc2luZyBhIG5ldyBjaHVuay4gIEhvd2V2ZXIsXG4vLyBhIHBhdGhvbG9naWNhbCBpbmZsYXRlIHR5cGUgb2YgdHJhbnNmb3JtIGNhbiBjYXVzZSBleGNlc3NpdmUgYnVmZmVyaW5nXG4vLyBoZXJlLiAgRm9yIGV4YW1wbGUsIGltYWdpbmUgYSBzdHJlYW0gd2hlcmUgZXZlcnkgYnl0ZSBvZiBpbnB1dCBpc1xuLy8gaW50ZXJwcmV0ZWQgYXMgYW4gaW50ZWdlciBmcm9tIDAtMjU1LCBhbmQgdGhlbiByZXN1bHRzIGluIHRoYXQgbWFueVxuLy8gYnl0ZXMgb2Ygb3V0cHV0LiAgV3JpdGluZyB0aGUgNCBieXRlcyB7ZmYsZmYsZmYsZmZ9IHdvdWxkIHJlc3VsdCBpblxuLy8gMWtiIG9mIGRhdGEgYmVpbmcgb3V0cHV0LiAgSW4gdGhpcyBjYXNlLCB5b3UgY291bGQgd3JpdGUgYSB2ZXJ5IHNtYWxsXG4vLyBhbW91bnQgb2YgaW5wdXQsIGFuZCBlbmQgdXAgd2l0aCBhIHZlcnkgbGFyZ2UgYW1vdW50IG9mIG91dHB1dC4gIEluXG4vLyBzdWNoIGEgcGF0aG9sb2dpY2FsIGluZmxhdGluZyBtZWNoYW5pc20sIHRoZXJlJ2QgYmUgbm8gd2F5IHRvIHRlbGxcbi8vIHRoZSBzeXN0ZW0gdG8gc3RvcCBkb2luZyB0aGUgdHJhbnNmb3JtLiAgQSBzaW5nbGUgNE1CIHdyaXRlIGNvdWxkXG4vLyBjYXVzZSB0aGUgc3lzdGVtIHRvIHJ1biBvdXQgb2YgbWVtb3J5LlxuLy9cbi8vIEhvd2V2ZXIsIGV2ZW4gaW4gc3VjaCBhIHBhdGhvbG9naWNhbCBjYXNlLCBvbmx5IGEgc2luZ2xlIHdyaXR0ZW4gY2h1bmtcbi8vIHdvdWxkIGJlIGNvbnN1bWVkLCBhbmQgdGhlbiB0aGUgcmVzdCB3b3VsZCB3YWl0ICh1bi10cmFuc2Zvcm1lZCkgdW50aWxcbi8vIHRoZSByZXN1bHRzIG9mIHRoZSBwcmV2aW91cyB0cmFuc2Zvcm1lZCBjaHVuayB3ZXJlIGNvbnN1bWVkLlxuXG4ndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gVHJhbnNmb3JtO1xudmFyIF9yZXF1aXJlJGNvZGVzID0gcmVxdWlyZSgnLi4vZXJyb3JzJykuY29kZXMsXG4gIEVSUl9NRVRIT0RfTk9UX0lNUExFTUVOVEVEID0gX3JlcXVpcmUkY29kZXMuRVJSX01FVEhPRF9OT1RfSU1QTEVNRU5URUQsXG4gIEVSUl9NVUxUSVBMRV9DQUxMQkFDSyA9IF9yZXF1aXJlJGNvZGVzLkVSUl9NVUxUSVBMRV9DQUxMQkFDSyxcbiAgRVJSX1RSQU5TRk9STV9BTFJFQURZX1RSQU5TRk9STUlORyA9IF9yZXF1aXJlJGNvZGVzLkVSUl9UUkFOU0ZPUk1fQUxSRUFEWV9UUkFOU0ZPUk1JTkcsXG4gIEVSUl9UUkFOU0ZPUk1fV0lUSF9MRU5HVEhfMCA9IF9yZXF1aXJlJGNvZGVzLkVSUl9UUkFOU0ZPUk1fV0lUSF9MRU5HVEhfMDtcbnZhciBEdXBsZXggPSByZXF1aXJlKCcuL19zdHJlYW1fZHVwbGV4Jyk7XG5yZXF1aXJlKCdpbmhlcml0cycpKFRyYW5zZm9ybSwgRHVwbGV4KTtcbmZ1bmN0aW9uIGFmdGVyVHJhbnNmb3JtKGVyLCBkYXRhKSB7XG4gIHZhciB0cyA9IHRoaXMuX3RyYW5zZm9ybVN0YXRlO1xuICB0cy50cmFuc2Zvcm1pbmcgPSBmYWxzZTtcbiAgdmFyIGNiID0gdHMud3JpdGVjYjtcbiAgaWYgKGNiID09PSBudWxsKSB7XG4gICAgcmV0dXJuIHRoaXMuZW1pdCgnZXJyb3InLCBuZXcgRVJSX01VTFRJUExFX0NBTExCQUNLKCkpO1xuICB9XG4gIHRzLndyaXRlY2h1bmsgPSBudWxsO1xuICB0cy53cml0ZWNiID0gbnVsbDtcbiAgaWYgKGRhdGEgIT0gbnVsbClcbiAgICAvLyBzaW5nbGUgZXF1YWxzIGNoZWNrIGZvciBib3RoIGBudWxsYCBhbmQgYHVuZGVmaW5lZGBcbiAgICB0aGlzLnB1c2goZGF0YSk7XG4gIGNiKGVyKTtcbiAgdmFyIHJzID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcbiAgcnMucmVhZGluZyA9IGZhbHNlO1xuICBpZiAocnMubmVlZFJlYWRhYmxlIHx8IHJzLmxlbmd0aCA8IHJzLmhpZ2hXYXRlck1hcmspIHtcbiAgICB0aGlzLl9yZWFkKHJzLmhpZ2hXYXRlck1hcmspO1xuICB9XG59XG5mdW5jdGlvbiBUcmFuc2Zvcm0ob3B0aW9ucykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgVHJhbnNmb3JtKSkgcmV0dXJuIG5ldyBUcmFuc2Zvcm0ob3B0aW9ucyk7XG4gIER1cGxleC5jYWxsKHRoaXMsIG9wdGlvbnMpO1xuICB0aGlzLl90cmFuc2Zvcm1TdGF0ZSA9IHtcbiAgICBhZnRlclRyYW5zZm9ybTogYWZ0ZXJUcmFuc2Zvcm0uYmluZCh0aGlzKSxcbiAgICBuZWVkVHJhbnNmb3JtOiBmYWxzZSxcbiAgICB0cmFuc2Zvcm1pbmc6IGZhbHNlLFxuICAgIHdyaXRlY2I6IG51bGwsXG4gICAgd3JpdGVjaHVuazogbnVsbCxcbiAgICB3cml0ZWVuY29kaW5nOiBudWxsXG4gIH07XG5cbiAgLy8gc3RhcnQgb3V0IGFza2luZyBmb3IgYSByZWFkYWJsZSBldmVudCBvbmNlIGRhdGEgaXMgdHJhbnNmb3JtZWQuXG4gIHRoaXMuX3JlYWRhYmxlU3RhdGUubmVlZFJlYWRhYmxlID0gdHJ1ZTtcblxuICAvLyB3ZSBoYXZlIGltcGxlbWVudGVkIHRoZSBfcmVhZCBtZXRob2QsIGFuZCBkb25lIHRoZSBvdGhlciB0aGluZ3NcbiAgLy8gdGhhdCBSZWFkYWJsZSB3YW50cyBiZWZvcmUgdGhlIGZpcnN0IF9yZWFkIGNhbGwsIHNvIHVuc2V0IHRoZVxuICAvLyBzeW5jIGd1YXJkIGZsYWcuXG4gIHRoaXMuX3JlYWRhYmxlU3RhdGUuc3luYyA9IGZhbHNlO1xuICBpZiAob3B0aW9ucykge1xuICAgIGlmICh0eXBlb2Ygb3B0aW9ucy50cmFuc2Zvcm0gPT09ICdmdW5jdGlvbicpIHRoaXMuX3RyYW5zZm9ybSA9IG9wdGlvbnMudHJhbnNmb3JtO1xuICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5mbHVzaCA9PT0gJ2Z1bmN0aW9uJykgdGhpcy5fZmx1c2ggPSBvcHRpb25zLmZsdXNoO1xuICB9XG5cbiAgLy8gV2hlbiB0aGUgd3JpdGFibGUgc2lkZSBmaW5pc2hlcywgdGhlbiBmbHVzaCBvdXQgYW55dGhpbmcgcmVtYWluaW5nLlxuICB0aGlzLm9uKCdwcmVmaW5pc2gnLCBwcmVmaW5pc2gpO1xufVxuZnVuY3Rpb24gcHJlZmluaXNoKCkge1xuICB2YXIgX3RoaXMgPSB0aGlzO1xuICBpZiAodHlwZW9mIHRoaXMuX2ZsdXNoID09PSAnZnVuY3Rpb24nICYmICF0aGlzLl9yZWFkYWJsZVN0YXRlLmRlc3Ryb3llZCkge1xuICAgIHRoaXMuX2ZsdXNoKGZ1bmN0aW9uIChlciwgZGF0YSkge1xuICAgICAgZG9uZShfdGhpcywgZXIsIGRhdGEpO1xuICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIGRvbmUodGhpcywgbnVsbCwgbnVsbCk7XG4gIH1cbn1cblRyYW5zZm9ybS5wcm90b3R5cGUucHVzaCA9IGZ1bmN0aW9uIChjaHVuaywgZW5jb2RpbmcpIHtcbiAgdGhpcy5fdHJhbnNmb3JtU3RhdGUubmVlZFRyYW5zZm9ybSA9IGZhbHNlO1xuICByZXR1cm4gRHVwbGV4LnByb3RvdHlwZS5wdXNoLmNhbGwodGhpcywgY2h1bmssIGVuY29kaW5nKTtcbn07XG5cbi8vIFRoaXMgaXMgdGhlIHBhcnQgd2hlcmUgeW91IGRvIHN0dWZmIVxuLy8gb3ZlcnJpZGUgdGhpcyBmdW5jdGlvbiBpbiBpbXBsZW1lbnRhdGlvbiBjbGFzc2VzLlxuLy8gJ2NodW5rJyBpcyBhbiBpbnB1dCBjaHVuay5cbi8vXG4vLyBDYWxsIGBwdXNoKG5ld0NodW5rKWAgdG8gcGFzcyBhbG9uZyB0cmFuc2Zvcm1lZCBvdXRwdXRcbi8vIHRvIHRoZSByZWFkYWJsZSBzaWRlLiAgWW91IG1heSBjYWxsICdwdXNoJyB6ZXJvIG9yIG1vcmUgdGltZXMuXG4vL1xuLy8gQ2FsbCBgY2IoZXJyKWAgd2hlbiB5b3UgYXJlIGRvbmUgd2l0aCB0aGlzIGNodW5rLiAgSWYgeW91IHBhc3Ncbi8vIGFuIGVycm9yLCB0aGVuIHRoYXQnbGwgcHV0IHRoZSBodXJ0IG9uIHRoZSB3aG9sZSBvcGVyYXRpb24uICBJZiB5b3Vcbi8vIG5ldmVyIGNhbGwgY2IoKSwgdGhlbiB5b3UnbGwgbmV2ZXIgZ2V0IGFub3RoZXIgY2h1bmsuXG5UcmFuc2Zvcm0ucHJvdG90eXBlLl90cmFuc2Zvcm0gPSBmdW5jdGlvbiAoY2h1bmssIGVuY29kaW5nLCBjYikge1xuICBjYihuZXcgRVJSX01FVEhPRF9OT1RfSU1QTEVNRU5URUQoJ190cmFuc2Zvcm0oKScpKTtcbn07XG5UcmFuc2Zvcm0ucHJvdG90eXBlLl93cml0ZSA9IGZ1bmN0aW9uIChjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIHZhciB0cyA9IHRoaXMuX3RyYW5zZm9ybVN0YXRlO1xuICB0cy53cml0ZWNiID0gY2I7XG4gIHRzLndyaXRlY2h1bmsgPSBjaHVuaztcbiAgdHMud3JpdGVlbmNvZGluZyA9IGVuY29kaW5nO1xuICBpZiAoIXRzLnRyYW5zZm9ybWluZykge1xuICAgIHZhciBycyA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gICAgaWYgKHRzLm5lZWRUcmFuc2Zvcm0gfHwgcnMubmVlZFJlYWRhYmxlIHx8IHJzLmxlbmd0aCA8IHJzLmhpZ2hXYXRlck1hcmspIHRoaXMuX3JlYWQocnMuaGlnaFdhdGVyTWFyayk7XG4gIH1cbn07XG5cbi8vIERvZXNuJ3QgbWF0dGVyIHdoYXQgdGhlIGFyZ3MgYXJlIGhlcmUuXG4vLyBfdHJhbnNmb3JtIGRvZXMgYWxsIHRoZSB3b3JrLlxuLy8gVGhhdCB3ZSBnb3QgaGVyZSBtZWFucyB0aGF0IHRoZSByZWFkYWJsZSBzaWRlIHdhbnRzIG1vcmUgZGF0YS5cblRyYW5zZm9ybS5wcm90b3R5cGUuX3JlYWQgPSBmdW5jdGlvbiAobikge1xuICB2YXIgdHMgPSB0aGlzLl90cmFuc2Zvcm1TdGF0ZTtcbiAgaWYgKHRzLndyaXRlY2h1bmsgIT09IG51bGwgJiYgIXRzLnRyYW5zZm9ybWluZykge1xuICAgIHRzLnRyYW5zZm9ybWluZyA9IHRydWU7XG4gICAgdGhpcy5fdHJhbnNmb3JtKHRzLndyaXRlY2h1bmssIHRzLndyaXRlZW5jb2RpbmcsIHRzLmFmdGVyVHJhbnNmb3JtKTtcbiAgfSBlbHNlIHtcbiAgICAvLyBtYXJrIHRoYXQgd2UgbmVlZCBhIHRyYW5zZm9ybSwgc28gdGhhdCBhbnkgZGF0YSB0aGF0IGNvbWVzIGluXG4gICAgLy8gd2lsbCBnZXQgcHJvY2Vzc2VkLCBub3cgdGhhdCB3ZSd2ZSBhc2tlZCBmb3IgaXQuXG4gICAgdHMubmVlZFRyYW5zZm9ybSA9IHRydWU7XG4gIH1cbn07XG5UcmFuc2Zvcm0ucHJvdG90eXBlLl9kZXN0cm95ID0gZnVuY3Rpb24gKGVyciwgY2IpIHtcbiAgRHVwbGV4LnByb3RvdHlwZS5fZGVzdHJveS5jYWxsKHRoaXMsIGVyciwgZnVuY3Rpb24gKGVycjIpIHtcbiAgICBjYihlcnIyKTtcbiAgfSk7XG59O1xuZnVuY3Rpb24gZG9uZShzdHJlYW0sIGVyLCBkYXRhKSB7XG4gIGlmIChlcikgcmV0dXJuIHN0cmVhbS5lbWl0KCdlcnJvcicsIGVyKTtcbiAgaWYgKGRhdGEgIT0gbnVsbClcbiAgICAvLyBzaW5nbGUgZXF1YWxzIGNoZWNrIGZvciBib3RoIGBudWxsYCBhbmQgYHVuZGVmaW5lZGBcbiAgICBzdHJlYW0ucHVzaChkYXRhKTtcblxuICAvLyBUT0RPKEJyaWRnZUFSKTogV3JpdGUgYSB0ZXN0IGZvciB0aGVzZSB0d28gZXJyb3IgY2FzZXNcbiAgLy8gaWYgdGhlcmUncyBub3RoaW5nIGluIHRoZSB3cml0ZSBidWZmZXIsIHRoZW4gdGhhdCBtZWFuc1xuICAvLyB0aGF0IG5vdGhpbmcgbW9yZSB3aWxsIGV2ZXIgYmUgcHJvdmlkZWRcbiAgaWYgKHN0cmVhbS5fd3JpdGFibGVTdGF0ZS5sZW5ndGgpIHRocm93IG5ldyBFUlJfVFJBTlNGT1JNX1dJVEhfTEVOR1RIXzAoKTtcbiAgaWYgKHN0cmVhbS5fdHJhbnNmb3JtU3RhdGUudHJhbnNmb3JtaW5nKSB0aHJvdyBuZXcgRVJSX1RSQU5TRk9STV9BTFJFQURZX1RSQU5TRk9STUlORygpO1xuICByZXR1cm4gc3RyZWFtLnB1c2gobnVsbCk7XG59IiwiLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbi8vIEEgYml0IHNpbXBsZXIgdGhhbiByZWFkYWJsZSBzdHJlYW1zLlxuLy8gSW1wbGVtZW50IGFuIGFzeW5jIC5fd3JpdGUoY2h1bmssIGVuY29kaW5nLCBjYiksIGFuZCBpdCdsbCBoYW5kbGUgYWxsXG4vLyB0aGUgZHJhaW4gZXZlbnQgZW1pc3Npb24gYW5kIGJ1ZmZlcmluZy5cblxuJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFdyaXRhYmxlO1xuXG4vKiA8cmVwbGFjZW1lbnQ+ICovXG5mdW5jdGlvbiBXcml0ZVJlcShjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIHRoaXMuY2h1bmsgPSBjaHVuaztcbiAgdGhpcy5lbmNvZGluZyA9IGVuY29kaW5nO1xuICB0aGlzLmNhbGxiYWNrID0gY2I7XG4gIHRoaXMubmV4dCA9IG51bGw7XG59XG5cbi8vIEl0IHNlZW1zIGEgbGlua2VkIGxpc3QgYnV0IGl0IGlzIG5vdFxuLy8gdGhlcmUgd2lsbCBiZSBvbmx5IDIgb2YgdGhlc2UgZm9yIGVhY2ggc3RyZWFtXG5mdW5jdGlvbiBDb3JrZWRSZXF1ZXN0KHN0YXRlKSB7XG4gIHZhciBfdGhpcyA9IHRoaXM7XG4gIHRoaXMubmV4dCA9IG51bGw7XG4gIHRoaXMuZW50cnkgPSBudWxsO1xuICB0aGlzLmZpbmlzaCA9IGZ1bmN0aW9uICgpIHtcbiAgICBvbkNvcmtlZEZpbmlzaChfdGhpcywgc3RhdGUpO1xuICB9O1xufVxuLyogPC9yZXBsYWNlbWVudD4gKi9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBEdXBsZXg7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuV3JpdGFibGUuV3JpdGFibGVTdGF0ZSA9IFdyaXRhYmxlU3RhdGU7XG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgaW50ZXJuYWxVdGlsID0ge1xuICBkZXByZWNhdGU6IHJlcXVpcmUoJ3V0aWwtZGVwcmVjYXRlJylcbn07XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBTdHJlYW0gPSByZXF1aXJlKCcuL2ludGVybmFsL3N0cmVhbXMvc3RyZWFtJyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ2J1ZmZlcicpLkJ1ZmZlcjtcbnZhciBPdXJVaW50OEFycmF5ID0gKHR5cGVvZiBnbG9iYWwgIT09ICd1bmRlZmluZWQnID8gZ2xvYmFsIDogdHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgPyB3aW5kb3cgOiB0eXBlb2Ygc2VsZiAhPT0gJ3VuZGVmaW5lZCcgPyBzZWxmIDoge30pLlVpbnQ4QXJyYXkgfHwgZnVuY3Rpb24gKCkge307XG5mdW5jdGlvbiBfdWludDhBcnJheVRvQnVmZmVyKGNodW5rKSB7XG4gIHJldHVybiBCdWZmZXIuZnJvbShjaHVuayk7XG59XG5mdW5jdGlvbiBfaXNVaW50OEFycmF5KG9iaikge1xuICByZXR1cm4gQnVmZmVyLmlzQnVmZmVyKG9iaikgfHwgb2JqIGluc3RhbmNlb2YgT3VyVWludDhBcnJheTtcbn1cbnZhciBkZXN0cm95SW1wbCA9IHJlcXVpcmUoJy4vaW50ZXJuYWwvc3RyZWFtcy9kZXN0cm95Jyk7XG52YXIgX3JlcXVpcmUgPSByZXF1aXJlKCcuL2ludGVybmFsL3N0cmVhbXMvc3RhdGUnKSxcbiAgZ2V0SGlnaFdhdGVyTWFyayA9IF9yZXF1aXJlLmdldEhpZ2hXYXRlck1hcms7XG52YXIgX3JlcXVpcmUkY29kZXMgPSByZXF1aXJlKCcuLi9lcnJvcnMnKS5jb2RlcyxcbiAgRVJSX0lOVkFMSURfQVJHX1RZUEUgPSBfcmVxdWlyZSRjb2Rlcy5FUlJfSU5WQUxJRF9BUkdfVFlQRSxcbiAgRVJSX01FVEhPRF9OT1RfSU1QTEVNRU5URUQgPSBfcmVxdWlyZSRjb2Rlcy5FUlJfTUVUSE9EX05PVF9JTVBMRU1FTlRFRCxcbiAgRVJSX01VTFRJUExFX0NBTExCQUNLID0gX3JlcXVpcmUkY29kZXMuRVJSX01VTFRJUExFX0NBTExCQUNLLFxuICBFUlJfU1RSRUFNX0NBTk5PVF9QSVBFID0gX3JlcXVpcmUkY29kZXMuRVJSX1NUUkVBTV9DQU5OT1RfUElQRSxcbiAgRVJSX1NUUkVBTV9ERVNUUk9ZRUQgPSBfcmVxdWlyZSRjb2Rlcy5FUlJfU1RSRUFNX0RFU1RST1lFRCxcbiAgRVJSX1NUUkVBTV9OVUxMX1ZBTFVFUyA9IF9yZXF1aXJlJGNvZGVzLkVSUl9TVFJFQU1fTlVMTF9WQUxVRVMsXG4gIEVSUl9TVFJFQU1fV1JJVEVfQUZURVJfRU5EID0gX3JlcXVpcmUkY29kZXMuRVJSX1NUUkVBTV9XUklURV9BRlRFUl9FTkQsXG4gIEVSUl9VTktOT1dOX0VOQ09ESU5HID0gX3JlcXVpcmUkY29kZXMuRVJSX1VOS05PV05fRU5DT0RJTkc7XG52YXIgZXJyb3JPckRlc3Ryb3kgPSBkZXN0cm95SW1wbC5lcnJvck9yRGVzdHJveTtcbnJlcXVpcmUoJ2luaGVyaXRzJykoV3JpdGFibGUsIFN0cmVhbSk7XG5mdW5jdGlvbiBub3AoKSB7fVxuZnVuY3Rpb24gV3JpdGFibGVTdGF0ZShvcHRpb25zLCBzdHJlYW0sIGlzRHVwbGV4KSB7XG4gIER1cGxleCA9IER1cGxleCB8fCByZXF1aXJlKCcuL19zdHJlYW1fZHVwbGV4Jyk7XG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gIC8vIER1cGxleCBzdHJlYW1zIGFyZSBib3RoIHJlYWRhYmxlIGFuZCB3cml0YWJsZSwgYnV0IHNoYXJlXG4gIC8vIHRoZSBzYW1lIG9wdGlvbnMgb2JqZWN0LlxuICAvLyBIb3dldmVyLCBzb21lIGNhc2VzIHJlcXVpcmUgc2V0dGluZyBvcHRpb25zIHRvIGRpZmZlcmVudFxuICAvLyB2YWx1ZXMgZm9yIHRoZSByZWFkYWJsZSBhbmQgdGhlIHdyaXRhYmxlIHNpZGVzIG9mIHRoZSBkdXBsZXggc3RyZWFtLFxuICAvLyBlLmcuIG9wdGlvbnMucmVhZGFibGVPYmplY3RNb2RlIHZzLiBvcHRpb25zLndyaXRhYmxlT2JqZWN0TW9kZSwgZXRjLlxuICBpZiAodHlwZW9mIGlzRHVwbGV4ICE9PSAnYm9vbGVhbicpIGlzRHVwbGV4ID0gc3RyZWFtIGluc3RhbmNlb2YgRHVwbGV4O1xuXG4gIC8vIG9iamVjdCBzdHJlYW0gZmxhZyB0byBpbmRpY2F0ZSB3aGV0aGVyIG9yIG5vdCB0aGlzIHN0cmVhbVxuICAvLyBjb250YWlucyBidWZmZXJzIG9yIG9iamVjdHMuXG4gIHRoaXMub2JqZWN0TW9kZSA9ICEhb3B0aW9ucy5vYmplY3RNb2RlO1xuICBpZiAoaXNEdXBsZXgpIHRoaXMub2JqZWN0TW9kZSA9IHRoaXMub2JqZWN0TW9kZSB8fCAhIW9wdGlvbnMud3JpdGFibGVPYmplY3RNb2RlO1xuXG4gIC8vIHRoZSBwb2ludCBhdCB3aGljaCB3cml0ZSgpIHN0YXJ0cyByZXR1cm5pbmcgZmFsc2VcbiAgLy8gTm90ZTogMCBpcyBhIHZhbGlkIHZhbHVlLCBtZWFucyB0aGF0IHdlIGFsd2F5cyByZXR1cm4gZmFsc2UgaWZcbiAgLy8gdGhlIGVudGlyZSBidWZmZXIgaXMgbm90IGZsdXNoZWQgaW1tZWRpYXRlbHkgb24gd3JpdGUoKVxuICB0aGlzLmhpZ2hXYXRlck1hcmsgPSBnZXRIaWdoV2F0ZXJNYXJrKHRoaXMsIG9wdGlvbnMsICd3cml0YWJsZUhpZ2hXYXRlck1hcmsnLCBpc0R1cGxleCk7XG5cbiAgLy8gaWYgX2ZpbmFsIGhhcyBiZWVuIGNhbGxlZFxuICB0aGlzLmZpbmFsQ2FsbGVkID0gZmFsc2U7XG5cbiAgLy8gZHJhaW4gZXZlbnQgZmxhZy5cbiAgdGhpcy5uZWVkRHJhaW4gPSBmYWxzZTtcbiAgLy8gYXQgdGhlIHN0YXJ0IG9mIGNhbGxpbmcgZW5kKClcbiAgdGhpcy5lbmRpbmcgPSBmYWxzZTtcbiAgLy8gd2hlbiBlbmQoKSBoYXMgYmVlbiBjYWxsZWQsIGFuZCByZXR1cm5lZFxuICB0aGlzLmVuZGVkID0gZmFsc2U7XG4gIC8vIHdoZW4gJ2ZpbmlzaCcgaXMgZW1pdHRlZFxuICB0aGlzLmZpbmlzaGVkID0gZmFsc2U7XG5cbiAgLy8gaGFzIGl0IGJlZW4gZGVzdHJveWVkXG4gIHRoaXMuZGVzdHJveWVkID0gZmFsc2U7XG5cbiAgLy8gc2hvdWxkIHdlIGRlY29kZSBzdHJpbmdzIGludG8gYnVmZmVycyBiZWZvcmUgcGFzc2luZyB0byBfd3JpdGU/XG4gIC8vIHRoaXMgaXMgaGVyZSBzbyB0aGF0IHNvbWUgbm9kZS1jb3JlIHN0cmVhbXMgY2FuIG9wdGltaXplIHN0cmluZ1xuICAvLyBoYW5kbGluZyBhdCBhIGxvd2VyIGxldmVsLlxuICB2YXIgbm9EZWNvZGUgPSBvcHRpb25zLmRlY29kZVN0cmluZ3MgPT09IGZhbHNlO1xuICB0aGlzLmRlY29kZVN0cmluZ3MgPSAhbm9EZWNvZGU7XG5cbiAgLy8gQ3J5cHRvIGlzIGtpbmQgb2Ygb2xkIGFuZCBjcnVzdHkuICBIaXN0b3JpY2FsbHksIGl0cyBkZWZhdWx0IHN0cmluZ1xuICAvLyBlbmNvZGluZyBpcyAnYmluYXJ5JyBzbyB3ZSBoYXZlIHRvIG1ha2UgdGhpcyBjb25maWd1cmFibGUuXG4gIC8vIEV2ZXJ5dGhpbmcgZWxzZSBpbiB0aGUgdW5pdmVyc2UgdXNlcyAndXRmOCcsIHRob3VnaC5cbiAgdGhpcy5kZWZhdWx0RW5jb2RpbmcgPSBvcHRpb25zLmRlZmF1bHRFbmNvZGluZyB8fCAndXRmOCc7XG5cbiAgLy8gbm90IGFuIGFjdHVhbCBidWZmZXIgd2Uga2VlcCB0cmFjayBvZiwgYnV0IGEgbWVhc3VyZW1lbnRcbiAgLy8gb2YgaG93IG11Y2ggd2UncmUgd2FpdGluZyB0byBnZXQgcHVzaGVkIHRvIHNvbWUgdW5kZXJseWluZ1xuICAvLyBzb2NrZXQgb3IgZmlsZS5cbiAgdGhpcy5sZW5ndGggPSAwO1xuXG4gIC8vIGEgZmxhZyB0byBzZWUgd2hlbiB3ZSdyZSBpbiB0aGUgbWlkZGxlIG9mIGEgd3JpdGUuXG4gIHRoaXMud3JpdGluZyA9IGZhbHNlO1xuXG4gIC8vIHdoZW4gdHJ1ZSBhbGwgd3JpdGVzIHdpbGwgYmUgYnVmZmVyZWQgdW50aWwgLnVuY29yaygpIGNhbGxcbiAgdGhpcy5jb3JrZWQgPSAwO1xuXG4gIC8vIGEgZmxhZyB0byBiZSBhYmxlIHRvIHRlbGwgaWYgdGhlIG9ud3JpdGUgY2IgaXMgY2FsbGVkIGltbWVkaWF0ZWx5LFxuICAvLyBvciBvbiBhIGxhdGVyIHRpY2suICBXZSBzZXQgdGhpcyB0byB0cnVlIGF0IGZpcnN0LCBiZWNhdXNlIGFueVxuICAvLyBhY3Rpb25zIHRoYXQgc2hvdWxkbid0IGhhcHBlbiB1bnRpbCBcImxhdGVyXCIgc2hvdWxkIGdlbmVyYWxseSBhbHNvXG4gIC8vIG5vdCBoYXBwZW4gYmVmb3JlIHRoZSBmaXJzdCB3cml0ZSBjYWxsLlxuICB0aGlzLnN5bmMgPSB0cnVlO1xuXG4gIC8vIGEgZmxhZyB0byBrbm93IGlmIHdlJ3JlIHByb2Nlc3NpbmcgcHJldmlvdXNseSBidWZmZXJlZCBpdGVtcywgd2hpY2hcbiAgLy8gbWF5IGNhbGwgdGhlIF93cml0ZSgpIGNhbGxiYWNrIGluIHRoZSBzYW1lIHRpY2ssIHNvIHRoYXQgd2UgZG9uJ3RcbiAgLy8gZW5kIHVwIGluIGFuIG92ZXJsYXBwZWQgb253cml0ZSBzaXR1YXRpb24uXG4gIHRoaXMuYnVmZmVyUHJvY2Vzc2luZyA9IGZhbHNlO1xuXG4gIC8vIHRoZSBjYWxsYmFjayB0aGF0J3MgcGFzc2VkIHRvIF93cml0ZShjaHVuayxjYilcbiAgdGhpcy5vbndyaXRlID0gZnVuY3Rpb24gKGVyKSB7XG4gICAgb253cml0ZShzdHJlYW0sIGVyKTtcbiAgfTtcblxuICAvLyB0aGUgY2FsbGJhY2sgdGhhdCB0aGUgdXNlciBzdXBwbGllcyB0byB3cml0ZShjaHVuayxlbmNvZGluZyxjYilcbiAgdGhpcy53cml0ZWNiID0gbnVsbDtcblxuICAvLyB0aGUgYW1vdW50IHRoYXQgaXMgYmVpbmcgd3JpdHRlbiB3aGVuIF93cml0ZSBpcyBjYWxsZWQuXG4gIHRoaXMud3JpdGVsZW4gPSAwO1xuICB0aGlzLmJ1ZmZlcmVkUmVxdWVzdCA9IG51bGw7XG4gIHRoaXMubGFzdEJ1ZmZlcmVkUmVxdWVzdCA9IG51bGw7XG5cbiAgLy8gbnVtYmVyIG9mIHBlbmRpbmcgdXNlci1zdXBwbGllZCB3cml0ZSBjYWxsYmFja3NcbiAgLy8gdGhpcyBtdXN0IGJlIDAgYmVmb3JlICdmaW5pc2gnIGNhbiBiZSBlbWl0dGVkXG4gIHRoaXMucGVuZGluZ2NiID0gMDtcblxuICAvLyBlbWl0IHByZWZpbmlzaCBpZiB0aGUgb25seSB0aGluZyB3ZSdyZSB3YWl0aW5nIGZvciBpcyBfd3JpdGUgY2JzXG4gIC8vIFRoaXMgaXMgcmVsZXZhbnQgZm9yIHN5bmNocm9ub3VzIFRyYW5zZm9ybSBzdHJlYW1zXG4gIHRoaXMucHJlZmluaXNoZWQgPSBmYWxzZTtcblxuICAvLyBUcnVlIGlmIHRoZSBlcnJvciB3YXMgYWxyZWFkeSBlbWl0dGVkIGFuZCBzaG91bGQgbm90IGJlIHRocm93biBhZ2FpblxuICB0aGlzLmVycm9yRW1pdHRlZCA9IGZhbHNlO1xuXG4gIC8vIFNob3VsZCBjbG9zZSBiZSBlbWl0dGVkIG9uIGRlc3Ryb3kuIERlZmF1bHRzIHRvIHRydWUuXG4gIHRoaXMuZW1pdENsb3NlID0gb3B0aW9ucy5lbWl0Q2xvc2UgIT09IGZhbHNlO1xuXG4gIC8vIFNob3VsZCAuZGVzdHJveSgpIGJlIGNhbGxlZCBhZnRlciAnZmluaXNoJyAoYW5kIHBvdGVudGlhbGx5ICdlbmQnKVxuICB0aGlzLmF1dG9EZXN0cm95ID0gISFvcHRpb25zLmF1dG9EZXN0cm95O1xuXG4gIC8vIGNvdW50IGJ1ZmZlcmVkIHJlcXVlc3RzXG4gIHRoaXMuYnVmZmVyZWRSZXF1ZXN0Q291bnQgPSAwO1xuXG4gIC8vIGFsbG9jYXRlIHRoZSBmaXJzdCBDb3JrZWRSZXF1ZXN0LCB0aGVyZSBpcyBhbHdheXNcbiAgLy8gb25lIGFsbG9jYXRlZCBhbmQgZnJlZSB0byB1c2UsIGFuZCB3ZSBtYWludGFpbiBhdCBtb3N0IHR3b1xuICB0aGlzLmNvcmtlZFJlcXVlc3RzRnJlZSA9IG5ldyBDb3JrZWRSZXF1ZXN0KHRoaXMpO1xufVxuV3JpdGFibGVTdGF0ZS5wcm90b3R5cGUuZ2V0QnVmZmVyID0gZnVuY3Rpb24gZ2V0QnVmZmVyKCkge1xuICB2YXIgY3VycmVudCA9IHRoaXMuYnVmZmVyZWRSZXF1ZXN0O1xuICB2YXIgb3V0ID0gW107XG4gIHdoaWxlIChjdXJyZW50KSB7XG4gICAgb3V0LnB1c2goY3VycmVudCk7XG4gICAgY3VycmVudCA9IGN1cnJlbnQubmV4dDtcbiAgfVxuICByZXR1cm4gb3V0O1xufTtcbihmdW5jdGlvbiAoKSB7XG4gIHRyeSB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFdyaXRhYmxlU3RhdGUucHJvdG90eXBlLCAnYnVmZmVyJywge1xuICAgICAgZ2V0OiBpbnRlcm5hbFV0aWwuZGVwcmVjYXRlKGZ1bmN0aW9uIHdyaXRhYmxlU3RhdGVCdWZmZXJHZXR0ZXIoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldEJ1ZmZlcigpO1xuICAgICAgfSwgJ193cml0YWJsZVN0YXRlLmJ1ZmZlciBpcyBkZXByZWNhdGVkLiBVc2UgX3dyaXRhYmxlU3RhdGUuZ2V0QnVmZmVyICcgKyAnaW5zdGVhZC4nLCAnREVQMDAwMycpXG4gICAgfSk7XG4gIH0gY2F0Y2ggKF8pIHt9XG59KSgpO1xuXG4vLyBUZXN0IF93cml0YWJsZVN0YXRlIGZvciBpbmhlcml0YW5jZSB0byBhY2NvdW50IGZvciBEdXBsZXggc3RyZWFtcyxcbi8vIHdob3NlIHByb3RvdHlwZSBjaGFpbiBvbmx5IHBvaW50cyB0byBSZWFkYWJsZS5cbnZhciByZWFsSGFzSW5zdGFuY2U7XG5pZiAodHlwZW9mIFN5bWJvbCA9PT0gJ2Z1bmN0aW9uJyAmJiBTeW1ib2wuaGFzSW5zdGFuY2UgJiYgdHlwZW9mIEZ1bmN0aW9uLnByb3RvdHlwZVtTeW1ib2wuaGFzSW5zdGFuY2VdID09PSAnZnVuY3Rpb24nKSB7XG4gIHJlYWxIYXNJbnN0YW5jZSA9IEZ1bmN0aW9uLnByb3RvdHlwZVtTeW1ib2wuaGFzSW5zdGFuY2VdO1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoV3JpdGFibGUsIFN5bWJvbC5oYXNJbnN0YW5jZSwge1xuICAgIHZhbHVlOiBmdW5jdGlvbiB2YWx1ZShvYmplY3QpIHtcbiAgICAgIGlmIChyZWFsSGFzSW5zdGFuY2UuY2FsbCh0aGlzLCBvYmplY3QpKSByZXR1cm4gdHJ1ZTtcbiAgICAgIGlmICh0aGlzICE9PSBXcml0YWJsZSkgcmV0dXJuIGZhbHNlO1xuICAgICAgcmV0dXJuIG9iamVjdCAmJiBvYmplY3QuX3dyaXRhYmxlU3RhdGUgaW5zdGFuY2VvZiBXcml0YWJsZVN0YXRlO1xuICAgIH1cbiAgfSk7XG59IGVsc2Uge1xuICByZWFsSGFzSW5zdGFuY2UgPSBmdW5jdGlvbiByZWFsSGFzSW5zdGFuY2Uob2JqZWN0KSB7XG4gICAgcmV0dXJuIG9iamVjdCBpbnN0YW5jZW9mIHRoaXM7XG4gIH07XG59XG5mdW5jdGlvbiBXcml0YWJsZShvcHRpb25zKSB7XG4gIER1cGxleCA9IER1cGxleCB8fCByZXF1aXJlKCcuL19zdHJlYW1fZHVwbGV4Jyk7XG5cbiAgLy8gV3JpdGFibGUgY3RvciBpcyBhcHBsaWVkIHRvIER1cGxleGVzLCB0b28uXG4gIC8vIGByZWFsSGFzSW5zdGFuY2VgIGlzIG5lY2Vzc2FyeSBiZWNhdXNlIHVzaW5nIHBsYWluIGBpbnN0YW5jZW9mYFxuICAvLyB3b3VsZCByZXR1cm4gZmFsc2UsIGFzIG5vIGBfd3JpdGFibGVTdGF0ZWAgcHJvcGVydHkgaXMgYXR0YWNoZWQuXG5cbiAgLy8gVHJ5aW5nIHRvIHVzZSB0aGUgY3VzdG9tIGBpbnN0YW5jZW9mYCBmb3IgV3JpdGFibGUgaGVyZSB3aWxsIGFsc28gYnJlYWsgdGhlXG4gIC8vIE5vZGUuanMgTGF6eVRyYW5zZm9ybSBpbXBsZW1lbnRhdGlvbiwgd2hpY2ggaGFzIGEgbm9uLXRyaXZpYWwgZ2V0dGVyIGZvclxuICAvLyBgX3dyaXRhYmxlU3RhdGVgIHRoYXQgd291bGQgbGVhZCB0byBpbmZpbml0ZSByZWN1cnNpb24uXG5cbiAgLy8gQ2hlY2tpbmcgZm9yIGEgU3RyZWFtLkR1cGxleCBpbnN0YW5jZSBpcyBmYXN0ZXIgaGVyZSBpbnN0ZWFkIG9mIGluc2lkZVxuICAvLyB0aGUgV3JpdGFibGVTdGF0ZSBjb25zdHJ1Y3RvciwgYXQgbGVhc3Qgd2l0aCBWOCA2LjVcbiAgdmFyIGlzRHVwbGV4ID0gdGhpcyBpbnN0YW5jZW9mIER1cGxleDtcbiAgaWYgKCFpc0R1cGxleCAmJiAhcmVhbEhhc0luc3RhbmNlLmNhbGwoV3JpdGFibGUsIHRoaXMpKSByZXR1cm4gbmV3IFdyaXRhYmxlKG9wdGlvbnMpO1xuICB0aGlzLl93cml0YWJsZVN0YXRlID0gbmV3IFdyaXRhYmxlU3RhdGUob3B0aW9ucywgdGhpcywgaXNEdXBsZXgpO1xuXG4gIC8vIGxlZ2FjeS5cbiAgdGhpcy53cml0YWJsZSA9IHRydWU7XG4gIGlmIChvcHRpb25zKSB7XG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLndyaXRlID09PSAnZnVuY3Rpb24nKSB0aGlzLl93cml0ZSA9IG9wdGlvbnMud3JpdGU7XG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLndyaXRldiA9PT0gJ2Z1bmN0aW9uJykgdGhpcy5fd3JpdGV2ID0gb3B0aW9ucy53cml0ZXY7XG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLmRlc3Ryb3kgPT09ICdmdW5jdGlvbicpIHRoaXMuX2Rlc3Ryb3kgPSBvcHRpb25zLmRlc3Ryb3k7XG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLmZpbmFsID09PSAnZnVuY3Rpb24nKSB0aGlzLl9maW5hbCA9IG9wdGlvbnMuZmluYWw7XG4gIH1cbiAgU3RyZWFtLmNhbGwodGhpcyk7XG59XG5cbi8vIE90aGVyd2lzZSBwZW9wbGUgY2FuIHBpcGUgV3JpdGFibGUgc3RyZWFtcywgd2hpY2ggaXMganVzdCB3cm9uZy5cbldyaXRhYmxlLnByb3RvdHlwZS5waXBlID0gZnVuY3Rpb24gKCkge1xuICBlcnJvck9yRGVzdHJveSh0aGlzLCBuZXcgRVJSX1NUUkVBTV9DQU5OT1RfUElQRSgpKTtcbn07XG5mdW5jdGlvbiB3cml0ZUFmdGVyRW5kKHN0cmVhbSwgY2IpIHtcbiAgdmFyIGVyID0gbmV3IEVSUl9TVFJFQU1fV1JJVEVfQUZURVJfRU5EKCk7XG4gIC8vIFRPRE86IGRlZmVyIGVycm9yIGV2ZW50cyBjb25zaXN0ZW50bHkgZXZlcnl3aGVyZSwgbm90IGp1c3QgdGhlIGNiXG4gIGVycm9yT3JEZXN0cm95KHN0cmVhbSwgZXIpO1xuICBwcm9jZXNzLm5leHRUaWNrKGNiLCBlcik7XG59XG5cbi8vIENoZWNrcyB0aGF0IGEgdXNlci1zdXBwbGllZCBjaHVuayBpcyB2YWxpZCwgZXNwZWNpYWxseSBmb3IgdGhlIHBhcnRpY3VsYXJcbi8vIG1vZGUgdGhlIHN0cmVhbSBpcyBpbi4gQ3VycmVudGx5IHRoaXMgbWVhbnMgdGhhdCBgbnVsbGAgaXMgbmV2ZXIgYWNjZXB0ZWRcbi8vIGFuZCB1bmRlZmluZWQvbm9uLXN0cmluZyB2YWx1ZXMgYXJlIG9ubHkgYWxsb3dlZCBpbiBvYmplY3QgbW9kZS5cbmZ1bmN0aW9uIHZhbGlkQ2h1bmsoc3RyZWFtLCBzdGF0ZSwgY2h1bmssIGNiKSB7XG4gIHZhciBlcjtcbiAgaWYgKGNodW5rID09PSBudWxsKSB7XG4gICAgZXIgPSBuZXcgRVJSX1NUUkVBTV9OVUxMX1ZBTFVFUygpO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBjaHVuayAhPT0gJ3N0cmluZycgJiYgIXN0YXRlLm9iamVjdE1vZGUpIHtcbiAgICBlciA9IG5ldyBFUlJfSU5WQUxJRF9BUkdfVFlQRSgnY2h1bmsnLCBbJ3N0cmluZycsICdCdWZmZXInXSwgY2h1bmspO1xuICB9XG4gIGlmIChlcikge1xuICAgIGVycm9yT3JEZXN0cm95KHN0cmVhbSwgZXIpO1xuICAgIHByb2Nlc3MubmV4dFRpY2soY2IsIGVyKTtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5Xcml0YWJsZS5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbiAoY2h1bmssIGVuY29kaW5nLCBjYikge1xuICB2YXIgc3RhdGUgPSB0aGlzLl93cml0YWJsZVN0YXRlO1xuICB2YXIgcmV0ID0gZmFsc2U7XG4gIHZhciBpc0J1ZiA9ICFzdGF0ZS5vYmplY3RNb2RlICYmIF9pc1VpbnQ4QXJyYXkoY2h1bmspO1xuICBpZiAoaXNCdWYgJiYgIUJ1ZmZlci5pc0J1ZmZlcihjaHVuaykpIHtcbiAgICBjaHVuayA9IF91aW50OEFycmF5VG9CdWZmZXIoY2h1bmspO1xuICB9XG4gIGlmICh0eXBlb2YgZW5jb2RpbmcgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjYiA9IGVuY29kaW5nO1xuICAgIGVuY29kaW5nID0gbnVsbDtcbiAgfVxuICBpZiAoaXNCdWYpIGVuY29kaW5nID0gJ2J1ZmZlcic7ZWxzZSBpZiAoIWVuY29kaW5nKSBlbmNvZGluZyA9IHN0YXRlLmRlZmF1bHRFbmNvZGluZztcbiAgaWYgKHR5cGVvZiBjYiAhPT0gJ2Z1bmN0aW9uJykgY2IgPSBub3A7XG4gIGlmIChzdGF0ZS5lbmRpbmcpIHdyaXRlQWZ0ZXJFbmQodGhpcywgY2IpO2Vsc2UgaWYgKGlzQnVmIHx8IHZhbGlkQ2h1bmsodGhpcywgc3RhdGUsIGNodW5rLCBjYikpIHtcbiAgICBzdGF0ZS5wZW5kaW5nY2IrKztcbiAgICByZXQgPSB3cml0ZU9yQnVmZmVyKHRoaXMsIHN0YXRlLCBpc0J1ZiwgY2h1bmssIGVuY29kaW5nLCBjYik7XG4gIH1cbiAgcmV0dXJuIHJldDtcbn07XG5Xcml0YWJsZS5wcm90b3R5cGUuY29yayA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5fd3JpdGFibGVTdGF0ZS5jb3JrZWQrKztcbn07XG5Xcml0YWJsZS5wcm90b3R5cGUudW5jb3JrID0gZnVuY3Rpb24gKCkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl93cml0YWJsZVN0YXRlO1xuICBpZiAoc3RhdGUuY29ya2VkKSB7XG4gICAgc3RhdGUuY29ya2VkLS07XG4gICAgaWYgKCFzdGF0ZS53cml0aW5nICYmICFzdGF0ZS5jb3JrZWQgJiYgIXN0YXRlLmJ1ZmZlclByb2Nlc3NpbmcgJiYgc3RhdGUuYnVmZmVyZWRSZXF1ZXN0KSBjbGVhckJ1ZmZlcih0aGlzLCBzdGF0ZSk7XG4gIH1cbn07XG5Xcml0YWJsZS5wcm90b3R5cGUuc2V0RGVmYXVsdEVuY29kaW5nID0gZnVuY3Rpb24gc2V0RGVmYXVsdEVuY29kaW5nKGVuY29kaW5nKSB7XG4gIC8vIG5vZGU6OlBhcnNlRW5jb2RpbmcoKSByZXF1aXJlcyBsb3dlciBjYXNlLlxuICBpZiAodHlwZW9mIGVuY29kaW5nID09PSAnc3RyaW5nJykgZW5jb2RpbmcgPSBlbmNvZGluZy50b0xvd2VyQ2FzZSgpO1xuICBpZiAoIShbJ2hleCcsICd1dGY4JywgJ3V0Zi04JywgJ2FzY2lpJywgJ2JpbmFyeScsICdiYXNlNjQnLCAndWNzMicsICd1Y3MtMicsICd1dGYxNmxlJywgJ3V0Zi0xNmxlJywgJ3JhdyddLmluZGV4T2YoKGVuY29kaW5nICsgJycpLnRvTG93ZXJDYXNlKCkpID4gLTEpKSB0aHJvdyBuZXcgRVJSX1VOS05PV05fRU5DT0RJTkcoZW5jb2RpbmcpO1xuICB0aGlzLl93cml0YWJsZVN0YXRlLmRlZmF1bHRFbmNvZGluZyA9IGVuY29kaW5nO1xuICByZXR1cm4gdGhpcztcbn07XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoV3JpdGFibGUucHJvdG90eXBlLCAnd3JpdGFibGVCdWZmZXInLCB7XG4gIC8vIG1ha2luZyBpdCBleHBsaWNpdCB0aGlzIHByb3BlcnR5IGlzIG5vdCBlbnVtZXJhYmxlXG4gIC8vIGJlY2F1c2Ugb3RoZXJ3aXNlIHNvbWUgcHJvdG90eXBlIG1hbmlwdWxhdGlvbiBpblxuICAvLyB1c2VybGFuZCB3aWxsIGZhaWxcbiAgZW51bWVyYWJsZTogZmFsc2UsXG4gIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgIHJldHVybiB0aGlzLl93cml0YWJsZVN0YXRlICYmIHRoaXMuX3dyaXRhYmxlU3RhdGUuZ2V0QnVmZmVyKCk7XG4gIH1cbn0pO1xuZnVuY3Rpb24gZGVjb2RlQ2h1bmsoc3RhdGUsIGNodW5rLCBlbmNvZGluZykge1xuICBpZiAoIXN0YXRlLm9iamVjdE1vZGUgJiYgc3RhdGUuZGVjb2RlU3RyaW5ncyAhPT0gZmFsc2UgJiYgdHlwZW9mIGNodW5rID09PSAnc3RyaW5nJykge1xuICAgIGNodW5rID0gQnVmZmVyLmZyb20oY2h1bmssIGVuY29kaW5nKTtcbiAgfVxuICByZXR1cm4gY2h1bms7XG59XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoV3JpdGFibGUucHJvdG90eXBlLCAnd3JpdGFibGVIaWdoV2F0ZXJNYXJrJywge1xuICAvLyBtYWtpbmcgaXQgZXhwbGljaXQgdGhpcyBwcm9wZXJ0eSBpcyBub3QgZW51bWVyYWJsZVxuICAvLyBiZWNhdXNlIG90aGVyd2lzZSBzb21lIHByb3RvdHlwZSBtYW5pcHVsYXRpb24gaW5cbiAgLy8gdXNlcmxhbmQgd2lsbCBmYWlsXG4gIGVudW1lcmFibGU6IGZhbHNlLFxuICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICByZXR1cm4gdGhpcy5fd3JpdGFibGVTdGF0ZS5oaWdoV2F0ZXJNYXJrO1xuICB9XG59KTtcblxuLy8gaWYgd2UncmUgYWxyZWFkeSB3cml0aW5nIHNvbWV0aGluZywgdGhlbiBqdXN0IHB1dCB0aGlzXG4vLyBpbiB0aGUgcXVldWUsIGFuZCB3YWl0IG91ciB0dXJuLiAgT3RoZXJ3aXNlLCBjYWxsIF93cml0ZVxuLy8gSWYgd2UgcmV0dXJuIGZhbHNlLCB0aGVuIHdlIG5lZWQgYSBkcmFpbiBldmVudCwgc28gc2V0IHRoYXQgZmxhZy5cbmZ1bmN0aW9uIHdyaXRlT3JCdWZmZXIoc3RyZWFtLCBzdGF0ZSwgaXNCdWYsIGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgaWYgKCFpc0J1Zikge1xuICAgIHZhciBuZXdDaHVuayA9IGRlY29kZUNodW5rKHN0YXRlLCBjaHVuaywgZW5jb2RpbmcpO1xuICAgIGlmIChjaHVuayAhPT0gbmV3Q2h1bmspIHtcbiAgICAgIGlzQnVmID0gdHJ1ZTtcbiAgICAgIGVuY29kaW5nID0gJ2J1ZmZlcic7XG4gICAgICBjaHVuayA9IG5ld0NodW5rO1xuICAgIH1cbiAgfVxuICB2YXIgbGVuID0gc3RhdGUub2JqZWN0TW9kZSA/IDEgOiBjaHVuay5sZW5ndGg7XG4gIHN0YXRlLmxlbmd0aCArPSBsZW47XG4gIHZhciByZXQgPSBzdGF0ZS5sZW5ndGggPCBzdGF0ZS5oaWdoV2F0ZXJNYXJrO1xuICAvLyB3ZSBtdXN0IGVuc3VyZSB0aGF0IHByZXZpb3VzIG5lZWREcmFpbiB3aWxsIG5vdCBiZSByZXNldCB0byBmYWxzZS5cbiAgaWYgKCFyZXQpIHN0YXRlLm5lZWREcmFpbiA9IHRydWU7XG4gIGlmIChzdGF0ZS53cml0aW5nIHx8IHN0YXRlLmNvcmtlZCkge1xuICAgIHZhciBsYXN0ID0gc3RhdGUubGFzdEJ1ZmZlcmVkUmVxdWVzdDtcbiAgICBzdGF0ZS5sYXN0QnVmZmVyZWRSZXF1ZXN0ID0ge1xuICAgICAgY2h1bms6IGNodW5rLFxuICAgICAgZW5jb2Rpbmc6IGVuY29kaW5nLFxuICAgICAgaXNCdWY6IGlzQnVmLFxuICAgICAgY2FsbGJhY2s6IGNiLFxuICAgICAgbmV4dDogbnVsbFxuICAgIH07XG4gICAgaWYgKGxhc3QpIHtcbiAgICAgIGxhc3QubmV4dCA9IHN0YXRlLmxhc3RCdWZmZXJlZFJlcXVlc3Q7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0YXRlLmJ1ZmZlcmVkUmVxdWVzdCA9IHN0YXRlLmxhc3RCdWZmZXJlZFJlcXVlc3Q7XG4gICAgfVxuICAgIHN0YXRlLmJ1ZmZlcmVkUmVxdWVzdENvdW50ICs9IDE7XG4gIH0gZWxzZSB7XG4gICAgZG9Xcml0ZShzdHJlYW0sIHN0YXRlLCBmYWxzZSwgbGVuLCBjaHVuaywgZW5jb2RpbmcsIGNiKTtcbiAgfVxuICByZXR1cm4gcmV0O1xufVxuZnVuY3Rpb24gZG9Xcml0ZShzdHJlYW0sIHN0YXRlLCB3cml0ZXYsIGxlbiwgY2h1bmssIGVuY29kaW5nLCBjYikge1xuICBzdGF0ZS53cml0ZWxlbiA9IGxlbjtcbiAgc3RhdGUud3JpdGVjYiA9IGNiO1xuICBzdGF0ZS53cml0aW5nID0gdHJ1ZTtcbiAgc3RhdGUuc3luYyA9IHRydWU7XG4gIGlmIChzdGF0ZS5kZXN0cm95ZWQpIHN0YXRlLm9ud3JpdGUobmV3IEVSUl9TVFJFQU1fREVTVFJPWUVEKCd3cml0ZScpKTtlbHNlIGlmICh3cml0ZXYpIHN0cmVhbS5fd3JpdGV2KGNodW5rLCBzdGF0ZS5vbndyaXRlKTtlbHNlIHN0cmVhbS5fd3JpdGUoY2h1bmssIGVuY29kaW5nLCBzdGF0ZS5vbndyaXRlKTtcbiAgc3RhdGUuc3luYyA9IGZhbHNlO1xufVxuZnVuY3Rpb24gb253cml0ZUVycm9yKHN0cmVhbSwgc3RhdGUsIHN5bmMsIGVyLCBjYikge1xuICAtLXN0YXRlLnBlbmRpbmdjYjtcbiAgaWYgKHN5bmMpIHtcbiAgICAvLyBkZWZlciB0aGUgY2FsbGJhY2sgaWYgd2UgYXJlIGJlaW5nIGNhbGxlZCBzeW5jaHJvbm91c2x5XG4gICAgLy8gdG8gYXZvaWQgcGlsaW5nIHVwIHRoaW5ncyBvbiB0aGUgc3RhY2tcbiAgICBwcm9jZXNzLm5leHRUaWNrKGNiLCBlcik7XG4gICAgLy8gdGhpcyBjYW4gZW1pdCBmaW5pc2gsIGFuZCBpdCB3aWxsIGFsd2F5cyBoYXBwZW5cbiAgICAvLyBhZnRlciBlcnJvclxuICAgIHByb2Nlc3MubmV4dFRpY2soZmluaXNoTWF5YmUsIHN0cmVhbSwgc3RhdGUpO1xuICAgIHN0cmVhbS5fd3JpdGFibGVTdGF0ZS5lcnJvckVtaXR0ZWQgPSB0cnVlO1xuICAgIGVycm9yT3JEZXN0cm95KHN0cmVhbSwgZXIpO1xuICB9IGVsc2Uge1xuICAgIC8vIHRoZSBjYWxsZXIgZXhwZWN0IHRoaXMgdG8gaGFwcGVuIGJlZm9yZSBpZlxuICAgIC8vIGl0IGlzIGFzeW5jXG4gICAgY2IoZXIpO1xuICAgIHN0cmVhbS5fd3JpdGFibGVTdGF0ZS5lcnJvckVtaXR0ZWQgPSB0cnVlO1xuICAgIGVycm9yT3JEZXN0cm95KHN0cmVhbSwgZXIpO1xuICAgIC8vIHRoaXMgY2FuIGVtaXQgZmluaXNoLCBidXQgZmluaXNoIG11c3RcbiAgICAvLyBhbHdheXMgZm9sbG93IGVycm9yXG4gICAgZmluaXNoTWF5YmUoc3RyZWFtLCBzdGF0ZSk7XG4gIH1cbn1cbmZ1bmN0aW9uIG9ud3JpdGVTdGF0ZVVwZGF0ZShzdGF0ZSkge1xuICBzdGF0ZS53cml0aW5nID0gZmFsc2U7XG4gIHN0YXRlLndyaXRlY2IgPSBudWxsO1xuICBzdGF0ZS5sZW5ndGggLT0gc3RhdGUud3JpdGVsZW47XG4gIHN0YXRlLndyaXRlbGVuID0gMDtcbn1cbmZ1bmN0aW9uIG9ud3JpdGUoc3RyZWFtLCBlcikge1xuICB2YXIgc3RhdGUgPSBzdHJlYW0uX3dyaXRhYmxlU3RhdGU7XG4gIHZhciBzeW5jID0gc3RhdGUuc3luYztcbiAgdmFyIGNiID0gc3RhdGUud3JpdGVjYjtcbiAgaWYgKHR5cGVvZiBjYiAhPT0gJ2Z1bmN0aW9uJykgdGhyb3cgbmV3IEVSUl9NVUxUSVBMRV9DQUxMQkFDSygpO1xuICBvbndyaXRlU3RhdGVVcGRhdGUoc3RhdGUpO1xuICBpZiAoZXIpIG9ud3JpdGVFcnJvcihzdHJlYW0sIHN0YXRlLCBzeW5jLCBlciwgY2IpO2Vsc2Uge1xuICAgIC8vIENoZWNrIGlmIHdlJ3JlIGFjdHVhbGx5IHJlYWR5IHRvIGZpbmlzaCwgYnV0IGRvbid0IGVtaXQgeWV0XG4gICAgdmFyIGZpbmlzaGVkID0gbmVlZEZpbmlzaChzdGF0ZSkgfHwgc3RyZWFtLmRlc3Ryb3llZDtcbiAgICBpZiAoIWZpbmlzaGVkICYmICFzdGF0ZS5jb3JrZWQgJiYgIXN0YXRlLmJ1ZmZlclByb2Nlc3NpbmcgJiYgc3RhdGUuYnVmZmVyZWRSZXF1ZXN0KSB7XG4gICAgICBjbGVhckJ1ZmZlcihzdHJlYW0sIHN0YXRlKTtcbiAgICB9XG4gICAgaWYgKHN5bmMpIHtcbiAgICAgIHByb2Nlc3MubmV4dFRpY2soYWZ0ZXJXcml0ZSwgc3RyZWFtLCBzdGF0ZSwgZmluaXNoZWQsIGNiKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYWZ0ZXJXcml0ZShzdHJlYW0sIHN0YXRlLCBmaW5pc2hlZCwgY2IpO1xuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gYWZ0ZXJXcml0ZShzdHJlYW0sIHN0YXRlLCBmaW5pc2hlZCwgY2IpIHtcbiAgaWYgKCFmaW5pc2hlZCkgb253cml0ZURyYWluKHN0cmVhbSwgc3RhdGUpO1xuICBzdGF0ZS5wZW5kaW5nY2ItLTtcbiAgY2IoKTtcbiAgZmluaXNoTWF5YmUoc3RyZWFtLCBzdGF0ZSk7XG59XG5cbi8vIE11c3QgZm9yY2UgY2FsbGJhY2sgdG8gYmUgY2FsbGVkIG9uIG5leHRUaWNrLCBzbyB0aGF0IHdlIGRvbid0XG4vLyBlbWl0ICdkcmFpbicgYmVmb3JlIHRoZSB3cml0ZSgpIGNvbnN1bWVyIGdldHMgdGhlICdmYWxzZScgcmV0dXJuXG4vLyB2YWx1ZSwgYW5kIGhhcyBhIGNoYW5jZSB0byBhdHRhY2ggYSAnZHJhaW4nIGxpc3RlbmVyLlxuZnVuY3Rpb24gb253cml0ZURyYWluKHN0cmVhbSwgc3RhdGUpIHtcbiAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMCAmJiBzdGF0ZS5uZWVkRHJhaW4pIHtcbiAgICBzdGF0ZS5uZWVkRHJhaW4gPSBmYWxzZTtcbiAgICBzdHJlYW0uZW1pdCgnZHJhaW4nKTtcbiAgfVxufVxuXG4vLyBpZiB0aGVyZSdzIHNvbWV0aGluZyBpbiB0aGUgYnVmZmVyIHdhaXRpbmcsIHRoZW4gcHJvY2VzcyBpdFxuZnVuY3Rpb24gY2xlYXJCdWZmZXIoc3RyZWFtLCBzdGF0ZSkge1xuICBzdGF0ZS5idWZmZXJQcm9jZXNzaW5nID0gdHJ1ZTtcbiAgdmFyIGVudHJ5ID0gc3RhdGUuYnVmZmVyZWRSZXF1ZXN0O1xuICBpZiAoc3RyZWFtLl93cml0ZXYgJiYgZW50cnkgJiYgZW50cnkubmV4dCkge1xuICAgIC8vIEZhc3QgY2FzZSwgd3JpdGUgZXZlcnl0aGluZyB1c2luZyBfd3JpdGV2KClcbiAgICB2YXIgbCA9IHN0YXRlLmJ1ZmZlcmVkUmVxdWVzdENvdW50O1xuICAgIHZhciBidWZmZXIgPSBuZXcgQXJyYXkobCk7XG4gICAgdmFyIGhvbGRlciA9IHN0YXRlLmNvcmtlZFJlcXVlc3RzRnJlZTtcbiAgICBob2xkZXIuZW50cnkgPSBlbnRyeTtcbiAgICB2YXIgY291bnQgPSAwO1xuICAgIHZhciBhbGxCdWZmZXJzID0gdHJ1ZTtcbiAgICB3aGlsZSAoZW50cnkpIHtcbiAgICAgIGJ1ZmZlcltjb3VudF0gPSBlbnRyeTtcbiAgICAgIGlmICghZW50cnkuaXNCdWYpIGFsbEJ1ZmZlcnMgPSBmYWxzZTtcbiAgICAgIGVudHJ5ID0gZW50cnkubmV4dDtcbiAgICAgIGNvdW50ICs9IDE7XG4gICAgfVxuICAgIGJ1ZmZlci5hbGxCdWZmZXJzID0gYWxsQnVmZmVycztcbiAgICBkb1dyaXRlKHN0cmVhbSwgc3RhdGUsIHRydWUsIHN0YXRlLmxlbmd0aCwgYnVmZmVyLCAnJywgaG9sZGVyLmZpbmlzaCk7XG5cbiAgICAvLyBkb1dyaXRlIGlzIGFsbW9zdCBhbHdheXMgYXN5bmMsIGRlZmVyIHRoZXNlIHRvIHNhdmUgYSBiaXQgb2YgdGltZVxuICAgIC8vIGFzIHRoZSBob3QgcGF0aCBlbmRzIHdpdGggZG9Xcml0ZVxuICAgIHN0YXRlLnBlbmRpbmdjYisrO1xuICAgIHN0YXRlLmxhc3RCdWZmZXJlZFJlcXVlc3QgPSBudWxsO1xuICAgIGlmIChob2xkZXIubmV4dCkge1xuICAgICAgc3RhdGUuY29ya2VkUmVxdWVzdHNGcmVlID0gaG9sZGVyLm5leHQ7XG4gICAgICBob2xkZXIubmV4dCA9IG51bGw7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0YXRlLmNvcmtlZFJlcXVlc3RzRnJlZSA9IG5ldyBDb3JrZWRSZXF1ZXN0KHN0YXRlKTtcbiAgICB9XG4gICAgc3RhdGUuYnVmZmVyZWRSZXF1ZXN0Q291bnQgPSAwO1xuICB9IGVsc2Uge1xuICAgIC8vIFNsb3cgY2FzZSwgd3JpdGUgY2h1bmtzIG9uZS1ieS1vbmVcbiAgICB3aGlsZSAoZW50cnkpIHtcbiAgICAgIHZhciBjaHVuayA9IGVudHJ5LmNodW5rO1xuICAgICAgdmFyIGVuY29kaW5nID0gZW50cnkuZW5jb2Rpbmc7XG4gICAgICB2YXIgY2IgPSBlbnRyeS5jYWxsYmFjaztcbiAgICAgIHZhciBsZW4gPSBzdGF0ZS5vYmplY3RNb2RlID8gMSA6IGNodW5rLmxlbmd0aDtcbiAgICAgIGRvV3JpdGUoc3RyZWFtLCBzdGF0ZSwgZmFsc2UsIGxlbiwgY2h1bmssIGVuY29kaW5nLCBjYik7XG4gICAgICBlbnRyeSA9IGVudHJ5Lm5leHQ7XG4gICAgICBzdGF0ZS5idWZmZXJlZFJlcXVlc3RDb3VudC0tO1xuICAgICAgLy8gaWYgd2UgZGlkbid0IGNhbGwgdGhlIG9ud3JpdGUgaW1tZWRpYXRlbHksIHRoZW5cbiAgICAgIC8vIGl0IG1lYW5zIHRoYXQgd2UgbmVlZCB0byB3YWl0IHVudGlsIGl0IGRvZXMuXG4gICAgICAvLyBhbHNvLCB0aGF0IG1lYW5zIHRoYXQgdGhlIGNodW5rIGFuZCBjYiBhcmUgY3VycmVudGx5XG4gICAgICAvLyBiZWluZyBwcm9jZXNzZWQsIHNvIG1vdmUgdGhlIGJ1ZmZlciBjb3VudGVyIHBhc3QgdGhlbS5cbiAgICAgIGlmIChzdGF0ZS53cml0aW5nKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoZW50cnkgPT09IG51bGwpIHN0YXRlLmxhc3RCdWZmZXJlZFJlcXVlc3QgPSBudWxsO1xuICB9XG4gIHN0YXRlLmJ1ZmZlcmVkUmVxdWVzdCA9IGVudHJ5O1xuICBzdGF0ZS5idWZmZXJQcm9jZXNzaW5nID0gZmFsc2U7XG59XG5Xcml0YWJsZS5wcm90b3R5cGUuX3dyaXRlID0gZnVuY3Rpb24gKGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgY2IobmV3IEVSUl9NRVRIT0RfTk9UX0lNUExFTUVOVEVEKCdfd3JpdGUoKScpKTtcbn07XG5Xcml0YWJsZS5wcm90b3R5cGUuX3dyaXRldiA9IG51bGw7XG5Xcml0YWJsZS5wcm90b3R5cGUuZW5kID0gZnVuY3Rpb24gKGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fd3JpdGFibGVTdGF0ZTtcbiAgaWYgKHR5cGVvZiBjaHVuayA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNiID0gY2h1bms7XG4gICAgY2h1bmsgPSBudWxsO1xuICAgIGVuY29kaW5nID0gbnVsbDtcbiAgfSBlbHNlIGlmICh0eXBlb2YgZW5jb2RpbmcgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjYiA9IGVuY29kaW5nO1xuICAgIGVuY29kaW5nID0gbnVsbDtcbiAgfVxuICBpZiAoY2h1bmsgIT09IG51bGwgJiYgY2h1bmsgIT09IHVuZGVmaW5lZCkgdGhpcy53cml0ZShjaHVuaywgZW5jb2RpbmcpO1xuXG4gIC8vIC5lbmQoKSBmdWxseSB1bmNvcmtzXG4gIGlmIChzdGF0ZS5jb3JrZWQpIHtcbiAgICBzdGF0ZS5jb3JrZWQgPSAxO1xuICAgIHRoaXMudW5jb3JrKCk7XG4gIH1cblxuICAvLyBpZ25vcmUgdW5uZWNlc3NhcnkgZW5kKCkgY2FsbHMuXG4gIGlmICghc3RhdGUuZW5kaW5nKSBlbmRXcml0YWJsZSh0aGlzLCBzdGF0ZSwgY2IpO1xuICByZXR1cm4gdGhpcztcbn07XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoV3JpdGFibGUucHJvdG90eXBlLCAnd3JpdGFibGVMZW5ndGgnLCB7XG4gIC8vIG1ha2luZyBpdCBleHBsaWNpdCB0aGlzIHByb3BlcnR5IGlzIG5vdCBlbnVtZXJhYmxlXG4gIC8vIGJlY2F1c2Ugb3RoZXJ3aXNlIHNvbWUgcHJvdG90eXBlIG1hbmlwdWxhdGlvbiBpblxuICAvLyB1c2VybGFuZCB3aWxsIGZhaWxcbiAgZW51bWVyYWJsZTogZmFsc2UsXG4gIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgIHJldHVybiB0aGlzLl93cml0YWJsZVN0YXRlLmxlbmd0aDtcbiAgfVxufSk7XG5mdW5jdGlvbiBuZWVkRmluaXNoKHN0YXRlKSB7XG4gIHJldHVybiBzdGF0ZS5lbmRpbmcgJiYgc3RhdGUubGVuZ3RoID09PSAwICYmIHN0YXRlLmJ1ZmZlcmVkUmVxdWVzdCA9PT0gbnVsbCAmJiAhc3RhdGUuZmluaXNoZWQgJiYgIXN0YXRlLndyaXRpbmc7XG59XG5mdW5jdGlvbiBjYWxsRmluYWwoc3RyZWFtLCBzdGF0ZSkge1xuICBzdHJlYW0uX2ZpbmFsKGZ1bmN0aW9uIChlcnIpIHtcbiAgICBzdGF0ZS5wZW5kaW5nY2ItLTtcbiAgICBpZiAoZXJyKSB7XG4gICAgICBlcnJvck9yRGVzdHJveShzdHJlYW0sIGVycik7XG4gICAgfVxuICAgIHN0YXRlLnByZWZpbmlzaGVkID0gdHJ1ZTtcbiAgICBzdHJlYW0uZW1pdCgncHJlZmluaXNoJyk7XG4gICAgZmluaXNoTWF5YmUoc3RyZWFtLCBzdGF0ZSk7XG4gIH0pO1xufVxuZnVuY3Rpb24gcHJlZmluaXNoKHN0cmVhbSwgc3RhdGUpIHtcbiAgaWYgKCFzdGF0ZS5wcmVmaW5pc2hlZCAmJiAhc3RhdGUuZmluYWxDYWxsZWQpIHtcbiAgICBpZiAodHlwZW9mIHN0cmVhbS5fZmluYWwgPT09ICdmdW5jdGlvbicgJiYgIXN0YXRlLmRlc3Ryb3llZCkge1xuICAgICAgc3RhdGUucGVuZGluZ2NiKys7XG4gICAgICBzdGF0ZS5maW5hbENhbGxlZCA9IHRydWU7XG4gICAgICBwcm9jZXNzLm5leHRUaWNrKGNhbGxGaW5hbCwgc3RyZWFtLCBzdGF0ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0YXRlLnByZWZpbmlzaGVkID0gdHJ1ZTtcbiAgICAgIHN0cmVhbS5lbWl0KCdwcmVmaW5pc2gnKTtcbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIGZpbmlzaE1heWJlKHN0cmVhbSwgc3RhdGUpIHtcbiAgdmFyIG5lZWQgPSBuZWVkRmluaXNoKHN0YXRlKTtcbiAgaWYgKG5lZWQpIHtcbiAgICBwcmVmaW5pc2goc3RyZWFtLCBzdGF0ZSk7XG4gICAgaWYgKHN0YXRlLnBlbmRpbmdjYiA9PT0gMCkge1xuICAgICAgc3RhdGUuZmluaXNoZWQgPSB0cnVlO1xuICAgICAgc3RyZWFtLmVtaXQoJ2ZpbmlzaCcpO1xuICAgICAgaWYgKHN0YXRlLmF1dG9EZXN0cm95KSB7XG4gICAgICAgIC8vIEluIGNhc2Ugb2YgZHVwbGV4IHN0cmVhbXMgd2UgbmVlZCBhIHdheSB0byBkZXRlY3RcbiAgICAgICAgLy8gaWYgdGhlIHJlYWRhYmxlIHNpZGUgaXMgcmVhZHkgZm9yIGF1dG9EZXN0cm95IGFzIHdlbGxcbiAgICAgICAgdmFyIHJTdGF0ZSA9IHN0cmVhbS5fcmVhZGFibGVTdGF0ZTtcbiAgICAgICAgaWYgKCFyU3RhdGUgfHwgclN0YXRlLmF1dG9EZXN0cm95ICYmIHJTdGF0ZS5lbmRFbWl0dGVkKSB7XG4gICAgICAgICAgc3RyZWFtLmRlc3Ryb3koKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gbmVlZDtcbn1cbmZ1bmN0aW9uIGVuZFdyaXRhYmxlKHN0cmVhbSwgc3RhdGUsIGNiKSB7XG4gIHN0YXRlLmVuZGluZyA9IHRydWU7XG4gIGZpbmlzaE1heWJlKHN0cmVhbSwgc3RhdGUpO1xuICBpZiAoY2IpIHtcbiAgICBpZiAoc3RhdGUuZmluaXNoZWQpIHByb2Nlc3MubmV4dFRpY2soY2IpO2Vsc2Ugc3RyZWFtLm9uY2UoJ2ZpbmlzaCcsIGNiKTtcbiAgfVxuICBzdGF0ZS5lbmRlZCA9IHRydWU7XG4gIHN0cmVhbS53cml0YWJsZSA9IGZhbHNlO1xufVxuZnVuY3Rpb24gb25Db3JrZWRGaW5pc2goY29ya1JlcSwgc3RhdGUsIGVycikge1xuICB2YXIgZW50cnkgPSBjb3JrUmVxLmVudHJ5O1xuICBjb3JrUmVxLmVudHJ5ID0gbnVsbDtcbiAgd2hpbGUgKGVudHJ5KSB7XG4gICAgdmFyIGNiID0gZW50cnkuY2FsbGJhY2s7XG4gICAgc3RhdGUucGVuZGluZ2NiLS07XG4gICAgY2IoZXJyKTtcbiAgICBlbnRyeSA9IGVudHJ5Lm5leHQ7XG4gIH1cblxuICAvLyByZXVzZSB0aGUgZnJlZSBjb3JrUmVxLlxuICBzdGF0ZS5jb3JrZWRSZXF1ZXN0c0ZyZWUubmV4dCA9IGNvcmtSZXE7XG59XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoV3JpdGFibGUucHJvdG90eXBlLCAnZGVzdHJveWVkJywge1xuICAvLyBtYWtpbmcgaXQgZXhwbGljaXQgdGhpcyBwcm9wZXJ0eSBpcyBub3QgZW51bWVyYWJsZVxuICAvLyBiZWNhdXNlIG90aGVyd2lzZSBzb21lIHByb3RvdHlwZSBtYW5pcHVsYXRpb24gaW5cbiAgLy8gdXNlcmxhbmQgd2lsbCBmYWlsXG4gIGVudW1lcmFibGU6IGZhbHNlLFxuICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICBpZiAodGhpcy5fd3JpdGFibGVTdGF0ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl93cml0YWJsZVN0YXRlLmRlc3Ryb3llZDtcbiAgfSxcbiAgc2V0OiBmdW5jdGlvbiBzZXQodmFsdWUpIHtcbiAgICAvLyB3ZSBpZ25vcmUgdGhlIHZhbHVlIGlmIHRoZSBzdHJlYW1cbiAgICAvLyBoYXMgbm90IGJlZW4gaW5pdGlhbGl6ZWQgeWV0XG4gICAgaWYgKCF0aGlzLl93cml0YWJsZVN0YXRlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gYmFja3dhcmQgY29tcGF0aWJpbGl0eSwgdGhlIHVzZXIgaXMgZXhwbGljaXRseVxuICAgIC8vIG1hbmFnaW5nIGRlc3Ryb3llZFxuICAgIHRoaXMuX3dyaXRhYmxlU3RhdGUuZGVzdHJveWVkID0gdmFsdWU7XG4gIH1cbn0pO1xuV3JpdGFibGUucHJvdG90eXBlLmRlc3Ryb3kgPSBkZXN0cm95SW1wbC5kZXN0cm95O1xuV3JpdGFibGUucHJvdG90eXBlLl91bmRlc3Ryb3kgPSBkZXN0cm95SW1wbC51bmRlc3Ryb3k7XG5Xcml0YWJsZS5wcm90b3R5cGUuX2Rlc3Ryb3kgPSBmdW5jdGlvbiAoZXJyLCBjYikge1xuICBjYihlcnIpO1xufTsiLCIndXNlIHN0cmljdCc7XG5cbnZhciBfT2JqZWN0JHNldFByb3RvdHlwZU87XG5mdW5jdGlvbiBfZGVmaW5lUHJvcGVydHkob2JqLCBrZXksIHZhbHVlKSB7IGtleSA9IF90b1Byb3BlcnR5S2V5KGtleSk7IGlmIChrZXkgaW4gb2JqKSB7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvYmosIGtleSwgeyB2YWx1ZTogdmFsdWUsIGVudW1lcmFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSwgd3JpdGFibGU6IHRydWUgfSk7IH0gZWxzZSB7IG9ialtrZXldID0gdmFsdWU7IH0gcmV0dXJuIG9iajsgfVxuZnVuY3Rpb24gX3RvUHJvcGVydHlLZXkoYXJnKSB7IHZhciBrZXkgPSBfdG9QcmltaXRpdmUoYXJnLCBcInN0cmluZ1wiKTsgcmV0dXJuIHR5cGVvZiBrZXkgPT09IFwic3ltYm9sXCIgPyBrZXkgOiBTdHJpbmcoa2V5KTsgfVxuZnVuY3Rpb24gX3RvUHJpbWl0aXZlKGlucHV0LCBoaW50KSB7IGlmICh0eXBlb2YgaW5wdXQgIT09IFwib2JqZWN0XCIgfHwgaW5wdXQgPT09IG51bGwpIHJldHVybiBpbnB1dDsgdmFyIHByaW0gPSBpbnB1dFtTeW1ib2wudG9QcmltaXRpdmVdOyBpZiAocHJpbSAhPT0gdW5kZWZpbmVkKSB7IHZhciByZXMgPSBwcmltLmNhbGwoaW5wdXQsIGhpbnQgfHwgXCJkZWZhdWx0XCIpOyBpZiAodHlwZW9mIHJlcyAhPT0gXCJvYmplY3RcIikgcmV0dXJuIHJlczsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkBAdG9QcmltaXRpdmUgbXVzdCByZXR1cm4gYSBwcmltaXRpdmUgdmFsdWUuXCIpOyB9IHJldHVybiAoaGludCA9PT0gXCJzdHJpbmdcIiA/IFN0cmluZyA6IE51bWJlcikoaW5wdXQpOyB9XG52YXIgZmluaXNoZWQgPSByZXF1aXJlKCcuL2VuZC1vZi1zdHJlYW0nKTtcbnZhciBrTGFzdFJlc29sdmUgPSBTeW1ib2woJ2xhc3RSZXNvbHZlJyk7XG52YXIga0xhc3RSZWplY3QgPSBTeW1ib2woJ2xhc3RSZWplY3QnKTtcbnZhciBrRXJyb3IgPSBTeW1ib2woJ2Vycm9yJyk7XG52YXIga0VuZGVkID0gU3ltYm9sKCdlbmRlZCcpO1xudmFyIGtMYXN0UHJvbWlzZSA9IFN5bWJvbCgnbGFzdFByb21pc2UnKTtcbnZhciBrSGFuZGxlUHJvbWlzZSA9IFN5bWJvbCgnaGFuZGxlUHJvbWlzZScpO1xudmFyIGtTdHJlYW0gPSBTeW1ib2woJ3N0cmVhbScpO1xuZnVuY3Rpb24gY3JlYXRlSXRlclJlc3VsdCh2YWx1ZSwgZG9uZSkge1xuICByZXR1cm4ge1xuICAgIHZhbHVlOiB2YWx1ZSxcbiAgICBkb25lOiBkb25lXG4gIH07XG59XG5mdW5jdGlvbiByZWFkQW5kUmVzb2x2ZShpdGVyKSB7XG4gIHZhciByZXNvbHZlID0gaXRlcltrTGFzdFJlc29sdmVdO1xuICBpZiAocmVzb2x2ZSAhPT0gbnVsbCkge1xuICAgIHZhciBkYXRhID0gaXRlcltrU3RyZWFtXS5yZWFkKCk7XG4gICAgLy8gd2UgZGVmZXIgaWYgZGF0YSBpcyBudWxsXG4gICAgLy8gd2UgY2FuIGJlIGV4cGVjdGluZyBlaXRoZXIgJ2VuZCcgb3JcbiAgICAvLyAnZXJyb3InXG4gICAgaWYgKGRhdGEgIT09IG51bGwpIHtcbiAgICAgIGl0ZXJba0xhc3RQcm9taXNlXSA9IG51bGw7XG4gICAgICBpdGVyW2tMYXN0UmVzb2x2ZV0gPSBudWxsO1xuICAgICAgaXRlcltrTGFzdFJlamVjdF0gPSBudWxsO1xuICAgICAgcmVzb2x2ZShjcmVhdGVJdGVyUmVzdWx0KGRhdGEsIGZhbHNlKSk7XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBvblJlYWRhYmxlKGl0ZXIpIHtcbiAgLy8gd2Ugd2FpdCBmb3IgdGhlIG5leHQgdGljaywgYmVjYXVzZSBpdCBtaWdodFxuICAvLyBlbWl0IGFuIGVycm9yIHdpdGggcHJvY2Vzcy5uZXh0VGlja1xuICBwcm9jZXNzLm5leHRUaWNrKHJlYWRBbmRSZXNvbHZlLCBpdGVyKTtcbn1cbmZ1bmN0aW9uIHdyYXBGb3JOZXh0KGxhc3RQcm9taXNlLCBpdGVyKSB7XG4gIHJldHVybiBmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgbGFzdFByb21pc2UudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICBpZiAoaXRlcltrRW5kZWRdKSB7XG4gICAgICAgIHJlc29sdmUoY3JlYXRlSXRlclJlc3VsdCh1bmRlZmluZWQsIHRydWUpKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaXRlcltrSGFuZGxlUHJvbWlzZV0ocmVzb2x2ZSwgcmVqZWN0KTtcbiAgICB9LCByZWplY3QpO1xuICB9O1xufVxudmFyIEFzeW5jSXRlcmF0b3JQcm90b3R5cGUgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YoZnVuY3Rpb24gKCkge30pO1xudmFyIFJlYWRhYmxlU3RyZWFtQXN5bmNJdGVyYXRvclByb3RvdHlwZSA9IE9iamVjdC5zZXRQcm90b3R5cGVPZigoX09iamVjdCRzZXRQcm90b3R5cGVPID0ge1xuICBnZXQgc3RyZWFtKCkge1xuICAgIHJldHVybiB0aGlzW2tTdHJlYW1dO1xuICB9LFxuICBuZXh0OiBmdW5jdGlvbiBuZXh0KCkge1xuICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgLy8gaWYgd2UgaGF2ZSBkZXRlY3RlZCBhbiBlcnJvciBpbiB0aGUgbWVhbndoaWxlXG4gICAgLy8gcmVqZWN0IHN0cmFpZ2h0IGF3YXlcbiAgICB2YXIgZXJyb3IgPSB0aGlzW2tFcnJvcl07XG4gICAgaWYgKGVycm9yICE9PSBudWxsKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoZXJyb3IpO1xuICAgIH1cbiAgICBpZiAodGhpc1trRW5kZWRdKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGNyZWF0ZUl0ZXJSZXN1bHQodW5kZWZpbmVkLCB0cnVlKSk7XG4gICAgfVxuICAgIGlmICh0aGlzW2tTdHJlYW1dLmRlc3Ryb3llZCkge1xuICAgICAgLy8gV2UgbmVlZCB0byBkZWZlciB2aWEgbmV4dFRpY2sgYmVjYXVzZSBpZiAuZGVzdHJveShlcnIpIGlzXG4gICAgICAvLyBjYWxsZWQsIHRoZSBlcnJvciB3aWxsIGJlIGVtaXR0ZWQgdmlhIG5leHRUaWNrLCBhbmRcbiAgICAgIC8vIHdlIGNhbm5vdCBndWFyYW50ZWUgdGhhdCB0aGVyZSBpcyBubyBlcnJvciBsaW5nZXJpbmcgYXJvdW5kXG4gICAgICAvLyB3YWl0aW5nIHRvIGJlIGVtaXR0ZWQuXG4gICAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICBwcm9jZXNzLm5leHRUaWNrKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBpZiAoX3RoaXNba0Vycm9yXSkge1xuICAgICAgICAgICAgcmVqZWN0KF90aGlzW2tFcnJvcl0pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXNvbHZlKGNyZWF0ZUl0ZXJSZXN1bHQodW5kZWZpbmVkLCB0cnVlKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIGlmIHdlIGhhdmUgbXVsdGlwbGUgbmV4dCgpIGNhbGxzXG4gICAgLy8gd2Ugd2lsbCB3YWl0IGZvciB0aGUgcHJldmlvdXMgUHJvbWlzZSB0byBmaW5pc2hcbiAgICAvLyB0aGlzIGxvZ2ljIGlzIG9wdGltaXplZCB0byBzdXBwb3J0IGZvciBhd2FpdCBsb29wcyxcbiAgICAvLyB3aGVyZSBuZXh0KCkgaXMgb25seSBjYWxsZWQgb25jZSBhdCBhIHRpbWVcbiAgICB2YXIgbGFzdFByb21pc2UgPSB0aGlzW2tMYXN0UHJvbWlzZV07XG4gICAgdmFyIHByb21pc2U7XG4gICAgaWYgKGxhc3RQcm9taXNlKSB7XG4gICAgICBwcm9taXNlID0gbmV3IFByb21pc2Uod3JhcEZvck5leHQobGFzdFByb21pc2UsIHRoaXMpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gZmFzdCBwYXRoIG5lZWRlZCB0byBzdXBwb3J0IG11bHRpcGxlIHRoaXMucHVzaCgpXG4gICAgICAvLyB3aXRob3V0IHRyaWdnZXJpbmcgdGhlIG5leHQoKSBxdWV1ZVxuICAgICAgdmFyIGRhdGEgPSB0aGlzW2tTdHJlYW1dLnJlYWQoKTtcbiAgICAgIGlmIChkYXRhICE9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoY3JlYXRlSXRlclJlc3VsdChkYXRhLCBmYWxzZSkpO1xuICAgICAgfVxuICAgICAgcHJvbWlzZSA9IG5ldyBQcm9taXNlKHRoaXNba0hhbmRsZVByb21pc2VdKTtcbiAgICB9XG4gICAgdGhpc1trTGFzdFByb21pc2VdID0gcHJvbWlzZTtcbiAgICByZXR1cm4gcHJvbWlzZTtcbiAgfVxufSwgX2RlZmluZVByb3BlcnR5KF9PYmplY3Qkc2V0UHJvdG90eXBlTywgU3ltYm9sLmFzeW5jSXRlcmF0b3IsIGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIHRoaXM7XG59KSwgX2RlZmluZVByb3BlcnR5KF9PYmplY3Qkc2V0UHJvdG90eXBlTywgXCJyZXR1cm5cIiwgZnVuY3Rpb24gX3JldHVybigpIHtcbiAgdmFyIF90aGlzMiA9IHRoaXM7XG4gIC8vIGRlc3Ryb3koZXJyLCBjYikgaXMgYSBwcml2YXRlIEFQSVxuICAvLyB3ZSBjYW4gZ3VhcmFudGVlIHdlIGhhdmUgdGhhdCBoZXJlLCBiZWNhdXNlIHdlIGNvbnRyb2wgdGhlXG4gIC8vIFJlYWRhYmxlIGNsYXNzIHRoaXMgaXMgYXR0YWNoZWQgdG9cbiAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICBfdGhpczJba1N0cmVhbV0uZGVzdHJveShudWxsLCBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICBpZiAoZXJyKSB7XG4gICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICByZXNvbHZlKGNyZWF0ZUl0ZXJSZXN1bHQodW5kZWZpbmVkLCB0cnVlKSk7XG4gICAgfSk7XG4gIH0pO1xufSksIF9PYmplY3Qkc2V0UHJvdG90eXBlTyksIEFzeW5jSXRlcmF0b3JQcm90b3R5cGUpO1xudmFyIGNyZWF0ZVJlYWRhYmxlU3RyZWFtQXN5bmNJdGVyYXRvciA9IGZ1bmN0aW9uIGNyZWF0ZVJlYWRhYmxlU3RyZWFtQXN5bmNJdGVyYXRvcihzdHJlYW0pIHtcbiAgdmFyIF9PYmplY3QkY3JlYXRlO1xuICB2YXIgaXRlcmF0b3IgPSBPYmplY3QuY3JlYXRlKFJlYWRhYmxlU3RyZWFtQXN5bmNJdGVyYXRvclByb3RvdHlwZSwgKF9PYmplY3QkY3JlYXRlID0ge30sIF9kZWZpbmVQcm9wZXJ0eShfT2JqZWN0JGNyZWF0ZSwga1N0cmVhbSwge1xuICAgIHZhbHVlOiBzdHJlYW0sXG4gICAgd3JpdGFibGU6IHRydWVcbiAgfSksIF9kZWZpbmVQcm9wZXJ0eShfT2JqZWN0JGNyZWF0ZSwga0xhc3RSZXNvbHZlLCB7XG4gICAgdmFsdWU6IG51bGwsXG4gICAgd3JpdGFibGU6IHRydWVcbiAgfSksIF9kZWZpbmVQcm9wZXJ0eShfT2JqZWN0JGNyZWF0ZSwga0xhc3RSZWplY3QsIHtcbiAgICB2YWx1ZTogbnVsbCxcbiAgICB3cml0YWJsZTogdHJ1ZVxuICB9KSwgX2RlZmluZVByb3BlcnR5KF9PYmplY3QkY3JlYXRlLCBrRXJyb3IsIHtcbiAgICB2YWx1ZTogbnVsbCxcbiAgICB3cml0YWJsZTogdHJ1ZVxuICB9KSwgX2RlZmluZVByb3BlcnR5KF9PYmplY3QkY3JlYXRlLCBrRW5kZWQsIHtcbiAgICB2YWx1ZTogc3RyZWFtLl9yZWFkYWJsZVN0YXRlLmVuZEVtaXR0ZWQsXG4gICAgd3JpdGFibGU6IHRydWVcbiAgfSksIF9kZWZpbmVQcm9wZXJ0eShfT2JqZWN0JGNyZWF0ZSwga0hhbmRsZVByb21pc2UsIHtcbiAgICB2YWx1ZTogZnVuY3Rpb24gdmFsdWUocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICB2YXIgZGF0YSA9IGl0ZXJhdG9yW2tTdHJlYW1dLnJlYWQoKTtcbiAgICAgIGlmIChkYXRhKSB7XG4gICAgICAgIGl0ZXJhdG9yW2tMYXN0UHJvbWlzZV0gPSBudWxsO1xuICAgICAgICBpdGVyYXRvcltrTGFzdFJlc29sdmVdID0gbnVsbDtcbiAgICAgICAgaXRlcmF0b3Jba0xhc3RSZWplY3RdID0gbnVsbDtcbiAgICAgICAgcmVzb2x2ZShjcmVhdGVJdGVyUmVzdWx0KGRhdGEsIGZhbHNlKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpdGVyYXRvcltrTGFzdFJlc29sdmVdID0gcmVzb2x2ZTtcbiAgICAgICAgaXRlcmF0b3Jba0xhc3RSZWplY3RdID0gcmVqZWN0O1xuICAgICAgfVxuICAgIH0sXG4gICAgd3JpdGFibGU6IHRydWVcbiAgfSksIF9PYmplY3QkY3JlYXRlKSk7XG4gIGl0ZXJhdG9yW2tMYXN0UHJvbWlzZV0gPSBudWxsO1xuICBmaW5pc2hlZChzdHJlYW0sIGZ1bmN0aW9uIChlcnIpIHtcbiAgICBpZiAoZXJyICYmIGVyci5jb2RlICE9PSAnRVJSX1NUUkVBTV9QUkVNQVRVUkVfQ0xPU0UnKSB7XG4gICAgICB2YXIgcmVqZWN0ID0gaXRlcmF0b3Jba0xhc3RSZWplY3RdO1xuICAgICAgLy8gcmVqZWN0IGlmIHdlIGFyZSB3YWl0aW5nIGZvciBkYXRhIGluIHRoZSBQcm9taXNlXG4gICAgICAvLyByZXR1cm5lZCBieSBuZXh0KCkgYW5kIHN0b3JlIHRoZSBlcnJvclxuICAgICAgaWYgKHJlamVjdCAhPT0gbnVsbCkge1xuICAgICAgICBpdGVyYXRvcltrTGFzdFByb21pc2VdID0gbnVsbDtcbiAgICAgICAgaXRlcmF0b3Jba0xhc3RSZXNvbHZlXSA9IG51bGw7XG4gICAgICAgIGl0ZXJhdG9yW2tMYXN0UmVqZWN0XSA9IG51bGw7XG4gICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgfVxuICAgICAgaXRlcmF0b3Jba0Vycm9yXSA9IGVycjtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdmFyIHJlc29sdmUgPSBpdGVyYXRvcltrTGFzdFJlc29sdmVdO1xuICAgIGlmIChyZXNvbHZlICE9PSBudWxsKSB7XG4gICAgICBpdGVyYXRvcltrTGFzdFByb21pc2VdID0gbnVsbDtcbiAgICAgIGl0ZXJhdG9yW2tMYXN0UmVzb2x2ZV0gPSBudWxsO1xuICAgICAgaXRlcmF0b3Jba0xhc3RSZWplY3RdID0gbnVsbDtcbiAgICAgIHJlc29sdmUoY3JlYXRlSXRlclJlc3VsdCh1bmRlZmluZWQsIHRydWUpKTtcbiAgICB9XG4gICAgaXRlcmF0b3Jba0VuZGVkXSA9IHRydWU7XG4gIH0pO1xuICBzdHJlYW0ub24oJ3JlYWRhYmxlJywgb25SZWFkYWJsZS5iaW5kKG51bGwsIGl0ZXJhdG9yKSk7XG4gIHJldHVybiBpdGVyYXRvcjtcbn07XG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZVJlYWRhYmxlU3RyZWFtQXN5bmNJdGVyYXRvcjsiLCIndXNlIHN0cmljdCc7XG5cbmZ1bmN0aW9uIG93bktleXMob2JqZWN0LCBlbnVtZXJhYmxlT25seSkgeyB2YXIga2V5cyA9IE9iamVjdC5rZXlzKG9iamVjdCk7IGlmIChPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKSB7IHZhciBzeW1ib2xzID0gT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhvYmplY3QpOyBlbnVtZXJhYmxlT25seSAmJiAoc3ltYm9scyA9IHN5bWJvbHMuZmlsdGVyKGZ1bmN0aW9uIChzeW0pIHsgcmV0dXJuIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Iob2JqZWN0LCBzeW0pLmVudW1lcmFibGU7IH0pKSwga2V5cy5wdXNoLmFwcGx5KGtleXMsIHN5bWJvbHMpOyB9IHJldHVybiBrZXlzOyB9XG5mdW5jdGlvbiBfb2JqZWN0U3ByZWFkKHRhcmdldCkgeyBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykgeyB2YXIgc291cmNlID0gbnVsbCAhPSBhcmd1bWVudHNbaV0gPyBhcmd1bWVudHNbaV0gOiB7fTsgaSAlIDIgPyBvd25LZXlzKE9iamVjdChzb3VyY2UpLCAhMCkuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7IF9kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGtleSwgc291cmNlW2tleV0pOyB9KSA6IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzID8gT2JqZWN0LmRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9ycyhzb3VyY2UpKSA6IG93bktleXMoT2JqZWN0KHNvdXJjZSkpLmZvckVhY2goZnVuY3Rpb24gKGtleSkgeyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBrZXksIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Ioc291cmNlLCBrZXkpKTsgfSk7IH0gcmV0dXJuIHRhcmdldDsgfVxuZnVuY3Rpb24gX2RlZmluZVByb3BlcnR5KG9iaiwga2V5LCB2YWx1ZSkgeyBrZXkgPSBfdG9Qcm9wZXJ0eUtleShrZXkpOyBpZiAoa2V5IGluIG9iaikgeyBPYmplY3QuZGVmaW5lUHJvcGVydHkob2JqLCBrZXksIHsgdmFsdWU6IHZhbHVlLCBlbnVtZXJhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUsIHdyaXRhYmxlOiB0cnVlIH0pOyB9IGVsc2UgeyBvYmpba2V5XSA9IHZhbHVlOyB9IHJldHVybiBvYmo7IH1cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9XG5mdW5jdGlvbiBfZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmIChcInZhbHVlXCIgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIF90b1Byb3BlcnR5S2V5KGRlc2NyaXB0b3Iua2V5KSwgZGVzY3JpcHRvcik7IH0gfVxuZnVuY3Rpb24gX2NyZWF0ZUNsYXNzKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgX2RlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTsgaWYgKHN0YXRpY1Byb3BzKSBfZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyBPYmplY3QuZGVmaW5lUHJvcGVydHkoQ29uc3RydWN0b3IsIFwicHJvdG90eXBlXCIsIHsgd3JpdGFibGU6IGZhbHNlIH0pOyByZXR1cm4gQ29uc3RydWN0b3I7IH1cbmZ1bmN0aW9uIF90b1Byb3BlcnR5S2V5KGFyZykgeyB2YXIga2V5ID0gX3RvUHJpbWl0aXZlKGFyZywgXCJzdHJpbmdcIik7IHJldHVybiB0eXBlb2Yga2V5ID09PSBcInN5bWJvbFwiID8ga2V5IDogU3RyaW5nKGtleSk7IH1cbmZ1bmN0aW9uIF90b1ByaW1pdGl2ZShpbnB1dCwgaGludCkgeyBpZiAodHlwZW9mIGlucHV0ICE9PSBcIm9iamVjdFwiIHx8IGlucHV0ID09PSBudWxsKSByZXR1cm4gaW5wdXQ7IHZhciBwcmltID0gaW5wdXRbU3ltYm9sLnRvUHJpbWl0aXZlXTsgaWYgKHByaW0gIT09IHVuZGVmaW5lZCkgeyB2YXIgcmVzID0gcHJpbS5jYWxsKGlucHV0LCBoaW50IHx8IFwiZGVmYXVsdFwiKTsgaWYgKHR5cGVvZiByZXMgIT09IFwib2JqZWN0XCIpIHJldHVybiByZXM7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJAQHRvUHJpbWl0aXZlIG11c3QgcmV0dXJuIGEgcHJpbWl0aXZlIHZhbHVlLlwiKTsgfSByZXR1cm4gKGhpbnQgPT09IFwic3RyaW5nXCIgPyBTdHJpbmcgOiBOdW1iZXIpKGlucHV0KTsgfVxudmFyIF9yZXF1aXJlID0gcmVxdWlyZSgnYnVmZmVyJyksXG4gIEJ1ZmZlciA9IF9yZXF1aXJlLkJ1ZmZlcjtcbnZhciBfcmVxdWlyZTIgPSByZXF1aXJlKCd1dGlsJyksXG4gIGluc3BlY3QgPSBfcmVxdWlyZTIuaW5zcGVjdDtcbnZhciBjdXN0b20gPSBpbnNwZWN0ICYmIGluc3BlY3QuY3VzdG9tIHx8ICdpbnNwZWN0JztcbmZ1bmN0aW9uIGNvcHlCdWZmZXIoc3JjLCB0YXJnZXQsIG9mZnNldCkge1xuICBCdWZmZXIucHJvdG90eXBlLmNvcHkuY2FsbChzcmMsIHRhcmdldCwgb2Zmc2V0KTtcbn1cbm1vZHVsZS5leHBvcnRzID0gLyojX19QVVJFX18qL2Z1bmN0aW9uICgpIHtcbiAgZnVuY3Rpb24gQnVmZmVyTGlzdCgpIHtcbiAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgQnVmZmVyTGlzdCk7XG4gICAgdGhpcy5oZWFkID0gbnVsbDtcbiAgICB0aGlzLnRhaWwgPSBudWxsO1xuICAgIHRoaXMubGVuZ3RoID0gMDtcbiAgfVxuICBfY3JlYXRlQ2xhc3MoQnVmZmVyTGlzdCwgW3tcbiAgICBrZXk6IFwicHVzaFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBwdXNoKHYpIHtcbiAgICAgIHZhciBlbnRyeSA9IHtcbiAgICAgICAgZGF0YTogdixcbiAgICAgICAgbmV4dDogbnVsbFxuICAgICAgfTtcbiAgICAgIGlmICh0aGlzLmxlbmd0aCA+IDApIHRoaXMudGFpbC5uZXh0ID0gZW50cnk7ZWxzZSB0aGlzLmhlYWQgPSBlbnRyeTtcbiAgICAgIHRoaXMudGFpbCA9IGVudHJ5O1xuICAgICAgKyt0aGlzLmxlbmd0aDtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwidW5zaGlmdFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiB1bnNoaWZ0KHYpIHtcbiAgICAgIHZhciBlbnRyeSA9IHtcbiAgICAgICAgZGF0YTogdixcbiAgICAgICAgbmV4dDogdGhpcy5oZWFkXG4gICAgICB9O1xuICAgICAgaWYgKHRoaXMubGVuZ3RoID09PSAwKSB0aGlzLnRhaWwgPSBlbnRyeTtcbiAgICAgIHRoaXMuaGVhZCA9IGVudHJ5O1xuICAgICAgKyt0aGlzLmxlbmd0aDtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwic2hpZnRcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gc2hpZnQoKSB7XG4gICAgICBpZiAodGhpcy5sZW5ndGggPT09IDApIHJldHVybjtcbiAgICAgIHZhciByZXQgPSB0aGlzLmhlYWQuZGF0YTtcbiAgICAgIGlmICh0aGlzLmxlbmd0aCA9PT0gMSkgdGhpcy5oZWFkID0gdGhpcy50YWlsID0gbnVsbDtlbHNlIHRoaXMuaGVhZCA9IHRoaXMuaGVhZC5uZXh0O1xuICAgICAgLS10aGlzLmxlbmd0aDtcbiAgICAgIHJldHVybiByZXQ7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImNsZWFyXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGNsZWFyKCkge1xuICAgICAgdGhpcy5oZWFkID0gdGhpcy50YWlsID0gbnVsbDtcbiAgICAgIHRoaXMubGVuZ3RoID0gMDtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiam9pblwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBqb2luKHMpIHtcbiAgICAgIGlmICh0aGlzLmxlbmd0aCA9PT0gMCkgcmV0dXJuICcnO1xuICAgICAgdmFyIHAgPSB0aGlzLmhlYWQ7XG4gICAgICB2YXIgcmV0ID0gJycgKyBwLmRhdGE7XG4gICAgICB3aGlsZSAocCA9IHAubmV4dCkgcmV0ICs9IHMgKyBwLmRhdGE7XG4gICAgICByZXR1cm4gcmV0O1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJjb25jYXRcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gY29uY2F0KG4pIHtcbiAgICAgIGlmICh0aGlzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIEJ1ZmZlci5hbGxvYygwKTtcbiAgICAgIHZhciByZXQgPSBCdWZmZXIuYWxsb2NVbnNhZmUobiA+Pj4gMCk7XG4gICAgICB2YXIgcCA9IHRoaXMuaGVhZDtcbiAgICAgIHZhciBpID0gMDtcbiAgICAgIHdoaWxlIChwKSB7XG4gICAgICAgIGNvcHlCdWZmZXIocC5kYXRhLCByZXQsIGkpO1xuICAgICAgICBpICs9IHAuZGF0YS5sZW5ndGg7XG4gICAgICAgIHAgPSBwLm5leHQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmV0O1xuICAgIH1cblxuICAgIC8vIENvbnN1bWVzIGEgc3BlY2lmaWVkIGFtb3VudCBvZiBieXRlcyBvciBjaGFyYWN0ZXJzIGZyb20gdGhlIGJ1ZmZlcmVkIGRhdGEuXG4gIH0sIHtcbiAgICBrZXk6IFwiY29uc3VtZVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBjb25zdW1lKG4sIGhhc1N0cmluZ3MpIHtcbiAgICAgIHZhciByZXQ7XG4gICAgICBpZiAobiA8IHRoaXMuaGVhZC5kYXRhLmxlbmd0aCkge1xuICAgICAgICAvLyBgc2xpY2VgIGlzIHRoZSBzYW1lIGZvciBidWZmZXJzIGFuZCBzdHJpbmdzLlxuICAgICAgICByZXQgPSB0aGlzLmhlYWQuZGF0YS5zbGljZSgwLCBuKTtcbiAgICAgICAgdGhpcy5oZWFkLmRhdGEgPSB0aGlzLmhlYWQuZGF0YS5zbGljZShuKTtcbiAgICAgIH0gZWxzZSBpZiAobiA9PT0gdGhpcy5oZWFkLmRhdGEubGVuZ3RoKSB7XG4gICAgICAgIC8vIEZpcnN0IGNodW5rIGlzIGEgcGVyZmVjdCBtYXRjaC5cbiAgICAgICAgcmV0ID0gdGhpcy5zaGlmdCgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gUmVzdWx0IHNwYW5zIG1vcmUgdGhhbiBvbmUgYnVmZmVyLlxuICAgICAgICByZXQgPSBoYXNTdHJpbmdzID8gdGhpcy5fZ2V0U3RyaW5nKG4pIDogdGhpcy5fZ2V0QnVmZmVyKG4pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJldDtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiZmlyc3RcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gZmlyc3QoKSB7XG4gICAgICByZXR1cm4gdGhpcy5oZWFkLmRhdGE7XG4gICAgfVxuXG4gICAgLy8gQ29uc3VtZXMgYSBzcGVjaWZpZWQgYW1vdW50IG9mIGNoYXJhY3RlcnMgZnJvbSB0aGUgYnVmZmVyZWQgZGF0YS5cbiAgfSwge1xuICAgIGtleTogXCJfZ2V0U3RyaW5nXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIF9nZXRTdHJpbmcobikge1xuICAgICAgdmFyIHAgPSB0aGlzLmhlYWQ7XG4gICAgICB2YXIgYyA9IDE7XG4gICAgICB2YXIgcmV0ID0gcC5kYXRhO1xuICAgICAgbiAtPSByZXQubGVuZ3RoO1xuICAgICAgd2hpbGUgKHAgPSBwLm5leHQpIHtcbiAgICAgICAgdmFyIHN0ciA9IHAuZGF0YTtcbiAgICAgICAgdmFyIG5iID0gbiA+IHN0ci5sZW5ndGggPyBzdHIubGVuZ3RoIDogbjtcbiAgICAgICAgaWYgKG5iID09PSBzdHIubGVuZ3RoKSByZXQgKz0gc3RyO2Vsc2UgcmV0ICs9IHN0ci5zbGljZSgwLCBuKTtcbiAgICAgICAgbiAtPSBuYjtcbiAgICAgICAgaWYgKG4gPT09IDApIHtcbiAgICAgICAgICBpZiAobmIgPT09IHN0ci5sZW5ndGgpIHtcbiAgICAgICAgICAgICsrYztcbiAgICAgICAgICAgIGlmIChwLm5leHQpIHRoaXMuaGVhZCA9IHAubmV4dDtlbHNlIHRoaXMuaGVhZCA9IHRoaXMudGFpbCA9IG51bGw7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuaGVhZCA9IHA7XG4gICAgICAgICAgICBwLmRhdGEgPSBzdHIuc2xpY2UobmIpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICArK2M7XG4gICAgICB9XG4gICAgICB0aGlzLmxlbmd0aCAtPSBjO1xuICAgICAgcmV0dXJuIHJldDtcbiAgICB9XG5cbiAgICAvLyBDb25zdW1lcyBhIHNwZWNpZmllZCBhbW91bnQgb2YgYnl0ZXMgZnJvbSB0aGUgYnVmZmVyZWQgZGF0YS5cbiAgfSwge1xuICAgIGtleTogXCJfZ2V0QnVmZmVyXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIF9nZXRCdWZmZXIobikge1xuICAgICAgdmFyIHJldCA9IEJ1ZmZlci5hbGxvY1Vuc2FmZShuKTtcbiAgICAgIHZhciBwID0gdGhpcy5oZWFkO1xuICAgICAgdmFyIGMgPSAxO1xuICAgICAgcC5kYXRhLmNvcHkocmV0KTtcbiAgICAgIG4gLT0gcC5kYXRhLmxlbmd0aDtcbiAgICAgIHdoaWxlIChwID0gcC5uZXh0KSB7XG4gICAgICAgIHZhciBidWYgPSBwLmRhdGE7XG4gICAgICAgIHZhciBuYiA9IG4gPiBidWYubGVuZ3RoID8gYnVmLmxlbmd0aCA6IG47XG4gICAgICAgIGJ1Zi5jb3B5KHJldCwgcmV0Lmxlbmd0aCAtIG4sIDAsIG5iKTtcbiAgICAgICAgbiAtPSBuYjtcbiAgICAgICAgaWYgKG4gPT09IDApIHtcbiAgICAgICAgICBpZiAobmIgPT09IGJ1Zi5sZW5ndGgpIHtcbiAgICAgICAgICAgICsrYztcbiAgICAgICAgICAgIGlmIChwLm5leHQpIHRoaXMuaGVhZCA9IHAubmV4dDtlbHNlIHRoaXMuaGVhZCA9IHRoaXMudGFpbCA9IG51bGw7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuaGVhZCA9IHA7XG4gICAgICAgICAgICBwLmRhdGEgPSBidWYuc2xpY2UobmIpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICArK2M7XG4gICAgICB9XG4gICAgICB0aGlzLmxlbmd0aCAtPSBjO1xuICAgICAgcmV0dXJuIHJldDtcbiAgICB9XG5cbiAgICAvLyBNYWtlIHN1cmUgdGhlIGxpbmtlZCBsaXN0IG9ubHkgc2hvd3MgdGhlIG1pbmltYWwgbmVjZXNzYXJ5IGluZm9ybWF0aW9uLlxuICB9LCB7XG4gICAga2V5OiBjdXN0b20sXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHZhbHVlKF8sIG9wdGlvbnMpIHtcbiAgICAgIHJldHVybiBpbnNwZWN0KHRoaXMsIF9vYmplY3RTcHJlYWQoX29iamVjdFNwcmVhZCh7fSwgb3B0aW9ucyksIHt9LCB7XG4gICAgICAgIC8vIE9ubHkgaW5zcGVjdCBvbmUgbGV2ZWwuXG4gICAgICAgIGRlcHRoOiAwLFxuICAgICAgICAvLyBJdCBzaG91bGQgbm90IHJlY3Vyc2UuXG4gICAgICAgIGN1c3RvbUluc3BlY3Q6IGZhbHNlXG4gICAgICB9KSk7XG4gICAgfVxuICB9XSk7XG4gIHJldHVybiBCdWZmZXJMaXN0O1xufSgpOyIsIid1c2Ugc3RyaWN0JztcblxuLy8gdW5kb2N1bWVudGVkIGNiKCkgQVBJLCBuZWVkZWQgZm9yIGNvcmUsIG5vdCBmb3IgcHVibGljIEFQSVxuZnVuY3Rpb24gZGVzdHJveShlcnIsIGNiKSB7XG4gIHZhciBfdGhpcyA9IHRoaXM7XG4gIHZhciByZWFkYWJsZURlc3Ryb3llZCA9IHRoaXMuX3JlYWRhYmxlU3RhdGUgJiYgdGhpcy5fcmVhZGFibGVTdGF0ZS5kZXN0cm95ZWQ7XG4gIHZhciB3cml0YWJsZURlc3Ryb3llZCA9IHRoaXMuX3dyaXRhYmxlU3RhdGUgJiYgdGhpcy5fd3JpdGFibGVTdGF0ZS5kZXN0cm95ZWQ7XG4gIGlmIChyZWFkYWJsZURlc3Ryb3llZCB8fCB3cml0YWJsZURlc3Ryb3llZCkge1xuICAgIGlmIChjYikge1xuICAgICAgY2IoZXJyKTtcbiAgICB9IGVsc2UgaWYgKGVycikge1xuICAgICAgaWYgKCF0aGlzLl93cml0YWJsZVN0YXRlKSB7XG4gICAgICAgIHByb2Nlc3MubmV4dFRpY2soZW1pdEVycm9yTlQsIHRoaXMsIGVycik7XG4gICAgICB9IGVsc2UgaWYgKCF0aGlzLl93cml0YWJsZVN0YXRlLmVycm9yRW1pdHRlZCkge1xuICAgICAgICB0aGlzLl93cml0YWJsZVN0YXRlLmVycm9yRW1pdHRlZCA9IHRydWU7XG4gICAgICAgIHByb2Nlc3MubmV4dFRpY2soZW1pdEVycm9yTlQsIHRoaXMsIGVycik7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gd2Ugc2V0IGRlc3Ryb3llZCB0byB0cnVlIGJlZm9yZSBmaXJpbmcgZXJyb3IgY2FsbGJhY2tzIGluIG9yZGVyXG4gIC8vIHRvIG1ha2UgaXQgcmUtZW50cmFuY2Ugc2FmZSBpbiBjYXNlIGRlc3Ryb3koKSBpcyBjYWxsZWQgd2l0aGluIGNhbGxiYWNrc1xuXG4gIGlmICh0aGlzLl9yZWFkYWJsZVN0YXRlKSB7XG4gICAgdGhpcy5fcmVhZGFibGVTdGF0ZS5kZXN0cm95ZWQgPSB0cnVlO1xuICB9XG5cbiAgLy8gaWYgdGhpcyBpcyBhIGR1cGxleCBzdHJlYW0gbWFyayB0aGUgd3JpdGFibGUgcGFydCBhcyBkZXN0cm95ZWQgYXMgd2VsbFxuICBpZiAodGhpcy5fd3JpdGFibGVTdGF0ZSkge1xuICAgIHRoaXMuX3dyaXRhYmxlU3RhdGUuZGVzdHJveWVkID0gdHJ1ZTtcbiAgfVxuICB0aGlzLl9kZXN0cm95KGVyciB8fCBudWxsLCBmdW5jdGlvbiAoZXJyKSB7XG4gICAgaWYgKCFjYiAmJiBlcnIpIHtcbiAgICAgIGlmICghX3RoaXMuX3dyaXRhYmxlU3RhdGUpIHtcbiAgICAgICAgcHJvY2Vzcy5uZXh0VGljayhlbWl0RXJyb3JBbmRDbG9zZU5ULCBfdGhpcywgZXJyKTtcbiAgICAgIH0gZWxzZSBpZiAoIV90aGlzLl93cml0YWJsZVN0YXRlLmVycm9yRW1pdHRlZCkge1xuICAgICAgICBfdGhpcy5fd3JpdGFibGVTdGF0ZS5lcnJvckVtaXR0ZWQgPSB0cnVlO1xuICAgICAgICBwcm9jZXNzLm5leHRUaWNrKGVtaXRFcnJvckFuZENsb3NlTlQsIF90aGlzLCBlcnIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcHJvY2Vzcy5uZXh0VGljayhlbWl0Q2xvc2VOVCwgX3RoaXMpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoY2IpIHtcbiAgICAgIHByb2Nlc3MubmV4dFRpY2soZW1pdENsb3NlTlQsIF90aGlzKTtcbiAgICAgIGNiKGVycik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHByb2Nlc3MubmV4dFRpY2soZW1pdENsb3NlTlQsIF90aGlzKTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gdGhpcztcbn1cbmZ1bmN0aW9uIGVtaXRFcnJvckFuZENsb3NlTlQoc2VsZiwgZXJyKSB7XG4gIGVtaXRFcnJvck5UKHNlbGYsIGVycik7XG4gIGVtaXRDbG9zZU5UKHNlbGYpO1xufVxuZnVuY3Rpb24gZW1pdENsb3NlTlQoc2VsZikge1xuICBpZiAoc2VsZi5fd3JpdGFibGVTdGF0ZSAmJiAhc2VsZi5fd3JpdGFibGVTdGF0ZS5lbWl0Q2xvc2UpIHJldHVybjtcbiAgaWYgKHNlbGYuX3JlYWRhYmxlU3RhdGUgJiYgIXNlbGYuX3JlYWRhYmxlU3RhdGUuZW1pdENsb3NlKSByZXR1cm47XG4gIHNlbGYuZW1pdCgnY2xvc2UnKTtcbn1cbmZ1bmN0aW9uIHVuZGVzdHJveSgpIHtcbiAgaWYgKHRoaXMuX3JlYWRhYmxlU3RhdGUpIHtcbiAgICB0aGlzLl9yZWFkYWJsZVN0YXRlLmRlc3Ryb3llZCA9IGZhbHNlO1xuICAgIHRoaXMuX3JlYWRhYmxlU3RhdGUucmVhZGluZyA9IGZhbHNlO1xuICAgIHRoaXMuX3JlYWRhYmxlU3RhdGUuZW5kZWQgPSBmYWxzZTtcbiAgICB0aGlzLl9yZWFkYWJsZVN0YXRlLmVuZEVtaXR0ZWQgPSBmYWxzZTtcbiAgfVxuICBpZiAodGhpcy5fd3JpdGFibGVTdGF0ZSkge1xuICAgIHRoaXMuX3dyaXRhYmxlU3RhdGUuZGVzdHJveWVkID0gZmFsc2U7XG4gICAgdGhpcy5fd3JpdGFibGVTdGF0ZS5lbmRlZCA9IGZhbHNlO1xuICAgIHRoaXMuX3dyaXRhYmxlU3RhdGUuZW5kaW5nID0gZmFsc2U7XG4gICAgdGhpcy5fd3JpdGFibGVTdGF0ZS5maW5hbENhbGxlZCA9IGZhbHNlO1xuICAgIHRoaXMuX3dyaXRhYmxlU3RhdGUucHJlZmluaXNoZWQgPSBmYWxzZTtcbiAgICB0aGlzLl93cml0YWJsZVN0YXRlLmZpbmlzaGVkID0gZmFsc2U7XG4gICAgdGhpcy5fd3JpdGFibGVTdGF0ZS5lcnJvckVtaXR0ZWQgPSBmYWxzZTtcbiAgfVxufVxuZnVuY3Rpb24gZW1pdEVycm9yTlQoc2VsZiwgZXJyKSB7XG4gIHNlbGYuZW1pdCgnZXJyb3InLCBlcnIpO1xufVxuZnVuY3Rpb24gZXJyb3JPckRlc3Ryb3koc3RyZWFtLCBlcnIpIHtcbiAgLy8gV2UgaGF2ZSB0ZXN0cyB0aGF0IHJlbHkgb24gZXJyb3JzIGJlaW5nIGVtaXR0ZWRcbiAgLy8gaW4gdGhlIHNhbWUgdGljaywgc28gY2hhbmdpbmcgdGhpcyBpcyBzZW12ZXIgbWFqb3IuXG4gIC8vIEZvciBub3cgd2hlbiB5b3Ugb3B0LWluIHRvIGF1dG9EZXN0cm95IHdlIGFsbG93XG4gIC8vIHRoZSBlcnJvciB0byBiZSBlbWl0dGVkIG5leHRUaWNrLiBJbiBhIGZ1dHVyZVxuICAvLyBzZW12ZXIgbWFqb3IgdXBkYXRlIHdlIHNob3VsZCBjaGFuZ2UgdGhlIGRlZmF1bHQgdG8gdGhpcy5cblxuICB2YXIgclN0YXRlID0gc3RyZWFtLl9yZWFkYWJsZVN0YXRlO1xuICB2YXIgd1N0YXRlID0gc3RyZWFtLl93cml0YWJsZVN0YXRlO1xuICBpZiAoclN0YXRlICYmIHJTdGF0ZS5hdXRvRGVzdHJveSB8fCB3U3RhdGUgJiYgd1N0YXRlLmF1dG9EZXN0cm95KSBzdHJlYW0uZGVzdHJveShlcnIpO2Vsc2Ugc3RyZWFtLmVtaXQoJ2Vycm9yJywgZXJyKTtcbn1cbm1vZHVsZS5leHBvcnRzID0ge1xuICBkZXN0cm95OiBkZXN0cm95LFxuICB1bmRlc3Ryb3k6IHVuZGVzdHJveSxcbiAgZXJyb3JPckRlc3Ryb3k6IGVycm9yT3JEZXN0cm95XG59OyIsIi8vIFBvcnRlZCBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9tYWZpbnRvc2gvZW5kLW9mLXN0cmVhbSB3aXRoXG4vLyBwZXJtaXNzaW9uIGZyb20gdGhlIGF1dGhvciwgTWF0aGlhcyBCdXVzIChAbWFmaW50b3NoKS5cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgRVJSX1NUUkVBTV9QUkVNQVRVUkVfQ0xPU0UgPSByZXF1aXJlKCcuLi8uLi8uLi9lcnJvcnMnKS5jb2Rlcy5FUlJfU1RSRUFNX1BSRU1BVFVSRV9DTE9TRTtcbmZ1bmN0aW9uIG9uY2UoY2FsbGJhY2spIHtcbiAgdmFyIGNhbGxlZCA9IGZhbHNlO1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIGlmIChjYWxsZWQpIHJldHVybjtcbiAgICBjYWxsZWQgPSB0cnVlO1xuICAgIGZvciAodmFyIF9sZW4gPSBhcmd1bWVudHMubGVuZ3RoLCBhcmdzID0gbmV3IEFycmF5KF9sZW4pLCBfa2V5ID0gMDsgX2tleSA8IF9sZW47IF9rZXkrKykge1xuICAgICAgYXJnc1tfa2V5XSA9IGFyZ3VtZW50c1tfa2V5XTtcbiAgICB9XG4gICAgY2FsbGJhY2suYXBwbHkodGhpcywgYXJncyk7XG4gIH07XG59XG5mdW5jdGlvbiBub29wKCkge31cbmZ1bmN0aW9uIGlzUmVxdWVzdChzdHJlYW0pIHtcbiAgcmV0dXJuIHN0cmVhbS5zZXRIZWFkZXIgJiYgdHlwZW9mIHN0cmVhbS5hYm9ydCA9PT0gJ2Z1bmN0aW9uJztcbn1cbmZ1bmN0aW9uIGVvcyhzdHJlYW0sIG9wdHMsIGNhbGxiYWNrKSB7XG4gIGlmICh0eXBlb2Ygb3B0cyA9PT0gJ2Z1bmN0aW9uJykgcmV0dXJuIGVvcyhzdHJlYW0sIG51bGwsIG9wdHMpO1xuICBpZiAoIW9wdHMpIG9wdHMgPSB7fTtcbiAgY2FsbGJhY2sgPSBvbmNlKGNhbGxiYWNrIHx8IG5vb3ApO1xuICB2YXIgcmVhZGFibGUgPSBvcHRzLnJlYWRhYmxlIHx8IG9wdHMucmVhZGFibGUgIT09IGZhbHNlICYmIHN0cmVhbS5yZWFkYWJsZTtcbiAgdmFyIHdyaXRhYmxlID0gb3B0cy53cml0YWJsZSB8fCBvcHRzLndyaXRhYmxlICE9PSBmYWxzZSAmJiBzdHJlYW0ud3JpdGFibGU7XG4gIHZhciBvbmxlZ2FjeWZpbmlzaCA9IGZ1bmN0aW9uIG9ubGVnYWN5ZmluaXNoKCkge1xuICAgIGlmICghc3RyZWFtLndyaXRhYmxlKSBvbmZpbmlzaCgpO1xuICB9O1xuICB2YXIgd3JpdGFibGVFbmRlZCA9IHN0cmVhbS5fd3JpdGFibGVTdGF0ZSAmJiBzdHJlYW0uX3dyaXRhYmxlU3RhdGUuZmluaXNoZWQ7XG4gIHZhciBvbmZpbmlzaCA9IGZ1bmN0aW9uIG9uZmluaXNoKCkge1xuICAgIHdyaXRhYmxlID0gZmFsc2U7XG4gICAgd3JpdGFibGVFbmRlZCA9IHRydWU7XG4gICAgaWYgKCFyZWFkYWJsZSkgY2FsbGJhY2suY2FsbChzdHJlYW0pO1xuICB9O1xuICB2YXIgcmVhZGFibGVFbmRlZCA9IHN0cmVhbS5fcmVhZGFibGVTdGF0ZSAmJiBzdHJlYW0uX3JlYWRhYmxlU3RhdGUuZW5kRW1pdHRlZDtcbiAgdmFyIG9uZW5kID0gZnVuY3Rpb24gb25lbmQoKSB7XG4gICAgcmVhZGFibGUgPSBmYWxzZTtcbiAgICByZWFkYWJsZUVuZGVkID0gdHJ1ZTtcbiAgICBpZiAoIXdyaXRhYmxlKSBjYWxsYmFjay5jYWxsKHN0cmVhbSk7XG4gIH07XG4gIHZhciBvbmVycm9yID0gZnVuY3Rpb24gb25lcnJvcihlcnIpIHtcbiAgICBjYWxsYmFjay5jYWxsKHN0cmVhbSwgZXJyKTtcbiAgfTtcbiAgdmFyIG9uY2xvc2UgPSBmdW5jdGlvbiBvbmNsb3NlKCkge1xuICAgIHZhciBlcnI7XG4gICAgaWYgKHJlYWRhYmxlICYmICFyZWFkYWJsZUVuZGVkKSB7XG4gICAgICBpZiAoIXN0cmVhbS5fcmVhZGFibGVTdGF0ZSB8fCAhc3RyZWFtLl9yZWFkYWJsZVN0YXRlLmVuZGVkKSBlcnIgPSBuZXcgRVJSX1NUUkVBTV9QUkVNQVRVUkVfQ0xPU0UoKTtcbiAgICAgIHJldHVybiBjYWxsYmFjay5jYWxsKHN0cmVhbSwgZXJyKTtcbiAgICB9XG4gICAgaWYgKHdyaXRhYmxlICYmICF3cml0YWJsZUVuZGVkKSB7XG4gICAgICBpZiAoIXN0cmVhbS5fd3JpdGFibGVTdGF0ZSB8fCAhc3RyZWFtLl93cml0YWJsZVN0YXRlLmVuZGVkKSBlcnIgPSBuZXcgRVJSX1NUUkVBTV9QUkVNQVRVUkVfQ0xPU0UoKTtcbiAgICAgIHJldHVybiBjYWxsYmFjay5jYWxsKHN0cmVhbSwgZXJyKTtcbiAgICB9XG4gIH07XG4gIHZhciBvbnJlcXVlc3QgPSBmdW5jdGlvbiBvbnJlcXVlc3QoKSB7XG4gICAgc3RyZWFtLnJlcS5vbignZmluaXNoJywgb25maW5pc2gpO1xuICB9O1xuICBpZiAoaXNSZXF1ZXN0KHN0cmVhbSkpIHtcbiAgICBzdHJlYW0ub24oJ2NvbXBsZXRlJywgb25maW5pc2gpO1xuICAgIHN0cmVhbS5vbignYWJvcnQnLCBvbmNsb3NlKTtcbiAgICBpZiAoc3RyZWFtLnJlcSkgb25yZXF1ZXN0KCk7ZWxzZSBzdHJlYW0ub24oJ3JlcXVlc3QnLCBvbnJlcXVlc3QpO1xuICB9IGVsc2UgaWYgKHdyaXRhYmxlICYmICFzdHJlYW0uX3dyaXRhYmxlU3RhdGUpIHtcbiAgICAvLyBsZWdhY3kgc3RyZWFtc1xuICAgIHN0cmVhbS5vbignZW5kJywgb25sZWdhY3lmaW5pc2gpO1xuICAgIHN0cmVhbS5vbignY2xvc2UnLCBvbmxlZ2FjeWZpbmlzaCk7XG4gIH1cbiAgc3RyZWFtLm9uKCdlbmQnLCBvbmVuZCk7XG4gIHN0cmVhbS5vbignZmluaXNoJywgb25maW5pc2gpO1xuICBpZiAob3B0cy5lcnJvciAhPT0gZmFsc2UpIHN0cmVhbS5vbignZXJyb3InLCBvbmVycm9yKTtcbiAgc3RyZWFtLm9uKCdjbG9zZScsIG9uY2xvc2UpO1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIHN0cmVhbS5yZW1vdmVMaXN0ZW5lcignY29tcGxldGUnLCBvbmZpbmlzaCk7XG4gICAgc3RyZWFtLnJlbW92ZUxpc3RlbmVyKCdhYm9ydCcsIG9uY2xvc2UpO1xuICAgIHN0cmVhbS5yZW1vdmVMaXN0ZW5lcigncmVxdWVzdCcsIG9ucmVxdWVzdCk7XG4gICAgaWYgKHN0cmVhbS5yZXEpIHN0cmVhbS5yZXEucmVtb3ZlTGlzdGVuZXIoJ2ZpbmlzaCcsIG9uZmluaXNoKTtcbiAgICBzdHJlYW0ucmVtb3ZlTGlzdGVuZXIoJ2VuZCcsIG9ubGVnYWN5ZmluaXNoKTtcbiAgICBzdHJlYW0ucmVtb3ZlTGlzdGVuZXIoJ2Nsb3NlJywgb25sZWdhY3lmaW5pc2gpO1xuICAgIHN0cmVhbS5yZW1vdmVMaXN0ZW5lcignZmluaXNoJywgb25maW5pc2gpO1xuICAgIHN0cmVhbS5yZW1vdmVMaXN0ZW5lcignZW5kJywgb25lbmQpO1xuICAgIHN0cmVhbS5yZW1vdmVMaXN0ZW5lcignZXJyb3InLCBvbmVycm9yKTtcbiAgICBzdHJlYW0ucmVtb3ZlTGlzdGVuZXIoJ2Nsb3NlJywgb25jbG9zZSk7XG4gIH07XG59XG5tb2R1bGUuZXhwb3J0cyA9IGVvczsiLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICgpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCdSZWFkYWJsZS5mcm9tIGlzIG5vdCBhdmFpbGFibGUgaW4gdGhlIGJyb3dzZXInKVxufTtcbiIsIi8vIFBvcnRlZCBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9tYWZpbnRvc2gvcHVtcCB3aXRoXG4vLyBwZXJtaXNzaW9uIGZyb20gdGhlIGF1dGhvciwgTWF0aGlhcyBCdXVzIChAbWFmaW50b3NoKS5cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgZW9zO1xuZnVuY3Rpb24gb25jZShjYWxsYmFjaykge1xuICB2YXIgY2FsbGVkID0gZmFsc2U7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKGNhbGxlZCkgcmV0dXJuO1xuICAgIGNhbGxlZCA9IHRydWU7XG4gICAgY2FsbGJhY2suYXBwbHkodm9pZCAwLCBhcmd1bWVudHMpO1xuICB9O1xufVxudmFyIF9yZXF1aXJlJGNvZGVzID0gcmVxdWlyZSgnLi4vLi4vLi4vZXJyb3JzJykuY29kZXMsXG4gIEVSUl9NSVNTSU5HX0FSR1MgPSBfcmVxdWlyZSRjb2Rlcy5FUlJfTUlTU0lOR19BUkdTLFxuICBFUlJfU1RSRUFNX0RFU1RST1lFRCA9IF9yZXF1aXJlJGNvZGVzLkVSUl9TVFJFQU1fREVTVFJPWUVEO1xuZnVuY3Rpb24gbm9vcChlcnIpIHtcbiAgLy8gUmV0aHJvdyB0aGUgZXJyb3IgaWYgaXQgZXhpc3RzIHRvIGF2b2lkIHN3YWxsb3dpbmcgaXRcbiAgaWYgKGVycikgdGhyb3cgZXJyO1xufVxuZnVuY3Rpb24gaXNSZXF1ZXN0KHN0cmVhbSkge1xuICByZXR1cm4gc3RyZWFtLnNldEhlYWRlciAmJiB0eXBlb2Ygc3RyZWFtLmFib3J0ID09PSAnZnVuY3Rpb24nO1xufVxuZnVuY3Rpb24gZGVzdHJveWVyKHN0cmVhbSwgcmVhZGluZywgd3JpdGluZywgY2FsbGJhY2spIHtcbiAgY2FsbGJhY2sgPSBvbmNlKGNhbGxiYWNrKTtcbiAgdmFyIGNsb3NlZCA9IGZhbHNlO1xuICBzdHJlYW0ub24oJ2Nsb3NlJywgZnVuY3Rpb24gKCkge1xuICAgIGNsb3NlZCA9IHRydWU7XG4gIH0pO1xuICBpZiAoZW9zID09PSB1bmRlZmluZWQpIGVvcyA9IHJlcXVpcmUoJy4vZW5kLW9mLXN0cmVhbScpO1xuICBlb3Moc3RyZWFtLCB7XG4gICAgcmVhZGFibGU6IHJlYWRpbmcsXG4gICAgd3JpdGFibGU6IHdyaXRpbmdcbiAgfSwgZnVuY3Rpb24gKGVycikge1xuICAgIGlmIChlcnIpIHJldHVybiBjYWxsYmFjayhlcnIpO1xuICAgIGNsb3NlZCA9IHRydWU7XG4gICAgY2FsbGJhY2soKTtcbiAgfSk7XG4gIHZhciBkZXN0cm95ZWQgPSBmYWxzZTtcbiAgcmV0dXJuIGZ1bmN0aW9uIChlcnIpIHtcbiAgICBpZiAoY2xvc2VkKSByZXR1cm47XG4gICAgaWYgKGRlc3Ryb3llZCkgcmV0dXJuO1xuICAgIGRlc3Ryb3llZCA9IHRydWU7XG5cbiAgICAvLyByZXF1ZXN0LmRlc3Ryb3kganVzdCBkbyAuZW5kIC0gLmFib3J0IGlzIHdoYXQgd2Ugd2FudFxuICAgIGlmIChpc1JlcXVlc3Qoc3RyZWFtKSkgcmV0dXJuIHN0cmVhbS5hYm9ydCgpO1xuICAgIGlmICh0eXBlb2Ygc3RyZWFtLmRlc3Ryb3kgPT09ICdmdW5jdGlvbicpIHJldHVybiBzdHJlYW0uZGVzdHJveSgpO1xuICAgIGNhbGxiYWNrKGVyciB8fCBuZXcgRVJSX1NUUkVBTV9ERVNUUk9ZRUQoJ3BpcGUnKSk7XG4gIH07XG59XG5mdW5jdGlvbiBjYWxsKGZuKSB7XG4gIGZuKCk7XG59XG5mdW5jdGlvbiBwaXBlKGZyb20sIHRvKSB7XG4gIHJldHVybiBmcm9tLnBpcGUodG8pO1xufVxuZnVuY3Rpb24gcG9wQ2FsbGJhY2soc3RyZWFtcykge1xuICBpZiAoIXN0cmVhbXMubGVuZ3RoKSByZXR1cm4gbm9vcDtcbiAgaWYgKHR5cGVvZiBzdHJlYW1zW3N0cmVhbXMubGVuZ3RoIC0gMV0gIT09ICdmdW5jdGlvbicpIHJldHVybiBub29wO1xuICByZXR1cm4gc3RyZWFtcy5wb3AoKTtcbn1cbmZ1bmN0aW9uIHBpcGVsaW5lKCkge1xuICBmb3IgKHZhciBfbGVuID0gYXJndW1lbnRzLmxlbmd0aCwgc3RyZWFtcyA9IG5ldyBBcnJheShfbGVuKSwgX2tleSA9IDA7IF9rZXkgPCBfbGVuOyBfa2V5KyspIHtcbiAgICBzdHJlYW1zW19rZXldID0gYXJndW1lbnRzW19rZXldO1xuICB9XG4gIHZhciBjYWxsYmFjayA9IHBvcENhbGxiYWNrKHN0cmVhbXMpO1xuICBpZiAoQXJyYXkuaXNBcnJheShzdHJlYW1zWzBdKSkgc3RyZWFtcyA9IHN0cmVhbXNbMF07XG4gIGlmIChzdHJlYW1zLmxlbmd0aCA8IDIpIHtcbiAgICB0aHJvdyBuZXcgRVJSX01JU1NJTkdfQVJHUygnc3RyZWFtcycpO1xuICB9XG4gIHZhciBlcnJvcjtcbiAgdmFyIGRlc3Ryb3lzID0gc3RyZWFtcy5tYXAoZnVuY3Rpb24gKHN0cmVhbSwgaSkge1xuICAgIHZhciByZWFkaW5nID0gaSA8IHN0cmVhbXMubGVuZ3RoIC0gMTtcbiAgICB2YXIgd3JpdGluZyA9IGkgPiAwO1xuICAgIHJldHVybiBkZXN0cm95ZXIoc3RyZWFtLCByZWFkaW5nLCB3cml0aW5nLCBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICBpZiAoIWVycm9yKSBlcnJvciA9IGVycjtcbiAgICAgIGlmIChlcnIpIGRlc3Ryb3lzLmZvckVhY2goY2FsbCk7XG4gICAgICBpZiAocmVhZGluZykgcmV0dXJuO1xuICAgICAgZGVzdHJveXMuZm9yRWFjaChjYWxsKTtcbiAgICAgIGNhbGxiYWNrKGVycm9yKTtcbiAgICB9KTtcbiAgfSk7XG4gIHJldHVybiBzdHJlYW1zLnJlZHVjZShwaXBlKTtcbn1cbm1vZHVsZS5leHBvcnRzID0gcGlwZWxpbmU7IiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgRVJSX0lOVkFMSURfT1BUX1ZBTFVFID0gcmVxdWlyZSgnLi4vLi4vLi4vZXJyb3JzJykuY29kZXMuRVJSX0lOVkFMSURfT1BUX1ZBTFVFO1xuZnVuY3Rpb24gaGlnaFdhdGVyTWFya0Zyb20ob3B0aW9ucywgaXNEdXBsZXgsIGR1cGxleEtleSkge1xuICByZXR1cm4gb3B0aW9ucy5oaWdoV2F0ZXJNYXJrICE9IG51bGwgPyBvcHRpb25zLmhpZ2hXYXRlck1hcmsgOiBpc0R1cGxleCA/IG9wdGlvbnNbZHVwbGV4S2V5XSA6IG51bGw7XG59XG5mdW5jdGlvbiBnZXRIaWdoV2F0ZXJNYXJrKHN0YXRlLCBvcHRpb25zLCBkdXBsZXhLZXksIGlzRHVwbGV4KSB7XG4gIHZhciBod20gPSBoaWdoV2F0ZXJNYXJrRnJvbShvcHRpb25zLCBpc0R1cGxleCwgZHVwbGV4S2V5KTtcbiAgaWYgKGh3bSAhPSBudWxsKSB7XG4gICAgaWYgKCEoaXNGaW5pdGUoaHdtKSAmJiBNYXRoLmZsb29yKGh3bSkgPT09IGh3bSkgfHwgaHdtIDwgMCkge1xuICAgICAgdmFyIG5hbWUgPSBpc0R1cGxleCA/IGR1cGxleEtleSA6ICdoaWdoV2F0ZXJNYXJrJztcbiAgICAgIHRocm93IG5ldyBFUlJfSU5WQUxJRF9PUFRfVkFMVUUobmFtZSwgaHdtKTtcbiAgICB9XG4gICAgcmV0dXJuIE1hdGguZmxvb3IoaHdtKTtcbiAgfVxuXG4gIC8vIERlZmF1bHQgdmFsdWVcbiAgcmV0dXJuIHN0YXRlLm9iamVjdE1vZGUgPyAxNiA6IDE2ICogMTAyNDtcbn1cbm1vZHVsZS5leHBvcnRzID0ge1xuICBnZXRIaWdoV2F0ZXJNYXJrOiBnZXRIaWdoV2F0ZXJNYXJrXG59OyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnZXZlbnRzJykuRXZlbnRFbWl0dGVyO1xuIiwiZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9saWIvX3N0cmVhbV9yZWFkYWJsZS5qcycpO1xuZXhwb3J0cy5TdHJlYW0gPSBleHBvcnRzO1xuZXhwb3J0cy5SZWFkYWJsZSA9IGV4cG9ydHM7XG5leHBvcnRzLldyaXRhYmxlID0gcmVxdWlyZSgnLi9saWIvX3N0cmVhbV93cml0YWJsZS5qcycpO1xuZXhwb3J0cy5EdXBsZXggPSByZXF1aXJlKCcuL2xpYi9fc3RyZWFtX2R1cGxleC5qcycpO1xuZXhwb3J0cy5UcmFuc2Zvcm0gPSByZXF1aXJlKCcuL2xpYi9fc3RyZWFtX3RyYW5zZm9ybS5qcycpO1xuZXhwb3J0cy5QYXNzVGhyb3VnaCA9IHJlcXVpcmUoJy4vbGliL19zdHJlYW1fcGFzc3Rocm91Z2guanMnKTtcbmV4cG9ydHMuZmluaXNoZWQgPSByZXF1aXJlKCcuL2xpYi9pbnRlcm5hbC9zdHJlYW1zL2VuZC1vZi1zdHJlYW0uanMnKTtcbmV4cG9ydHMucGlwZWxpbmUgPSByZXF1aXJlKCcuL2xpYi9pbnRlcm5hbC9zdHJlYW1zL3BpcGVsaW5lLmpzJyk7XG4iLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxuJ3VzZSBzdHJpY3QnO1xuXG4vKjxyZXBsYWNlbWVudD4qL1xuXG52YXIgQnVmZmVyID0gcmVxdWlyZSgnc2FmZS1idWZmZXInKS5CdWZmZXI7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxudmFyIGlzRW5jb2RpbmcgPSBCdWZmZXIuaXNFbmNvZGluZyB8fCBmdW5jdGlvbiAoZW5jb2RpbmcpIHtcbiAgZW5jb2RpbmcgPSAnJyArIGVuY29kaW5nO1xuICBzd2l0Y2ggKGVuY29kaW5nICYmIGVuY29kaW5nLnRvTG93ZXJDYXNlKCkpIHtcbiAgICBjYXNlICdoZXgnOmNhc2UgJ3V0ZjgnOmNhc2UgJ3V0Zi04JzpjYXNlICdhc2NpaSc6Y2FzZSAnYmluYXJ5JzpjYXNlICdiYXNlNjQnOmNhc2UgJ3VjczInOmNhc2UgJ3Vjcy0yJzpjYXNlICd1dGYxNmxlJzpjYXNlICd1dGYtMTZsZSc6Y2FzZSAncmF3JzpcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn07XG5cbmZ1bmN0aW9uIF9ub3JtYWxpemVFbmNvZGluZyhlbmMpIHtcbiAgaWYgKCFlbmMpIHJldHVybiAndXRmOCc7XG4gIHZhciByZXRyaWVkO1xuICB3aGlsZSAodHJ1ZSkge1xuICAgIHN3aXRjaCAoZW5jKSB7XG4gICAgICBjYXNlICd1dGY4JzpcbiAgICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgICAgcmV0dXJuICd1dGY4JztcbiAgICAgIGNhc2UgJ3VjczInOlxuICAgICAgY2FzZSAndWNzLTInOlxuICAgICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICAgIHJldHVybiAndXRmMTZsZSc7XG4gICAgICBjYXNlICdsYXRpbjEnOlxuICAgICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgICAgcmV0dXJuICdsYXRpbjEnO1xuICAgICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgIGNhc2UgJ2FzY2lpJzpcbiAgICAgIGNhc2UgJ2hleCc6XG4gICAgICAgIHJldHVybiBlbmM7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpZiAocmV0cmllZCkgcmV0dXJuOyAvLyB1bmRlZmluZWRcbiAgICAgICAgZW5jID0gKCcnICsgZW5jKS50b0xvd2VyQ2FzZSgpO1xuICAgICAgICByZXRyaWVkID0gdHJ1ZTtcbiAgICB9XG4gIH1cbn07XG5cbi8vIERvIG5vdCBjYWNoZSBgQnVmZmVyLmlzRW5jb2RpbmdgIHdoZW4gY2hlY2tpbmcgZW5jb2RpbmcgbmFtZXMgYXMgc29tZVxuLy8gbW9kdWxlcyBtb25rZXktcGF0Y2ggaXQgdG8gc3VwcG9ydCBhZGRpdGlvbmFsIGVuY29kaW5nc1xuZnVuY3Rpb24gbm9ybWFsaXplRW5jb2RpbmcoZW5jKSB7XG4gIHZhciBuZW5jID0gX25vcm1hbGl6ZUVuY29kaW5nKGVuYyk7XG4gIGlmICh0eXBlb2YgbmVuYyAhPT0gJ3N0cmluZycgJiYgKEJ1ZmZlci5pc0VuY29kaW5nID09PSBpc0VuY29kaW5nIHx8ICFpc0VuY29kaW5nKGVuYykpKSB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmMpO1xuICByZXR1cm4gbmVuYyB8fCBlbmM7XG59XG5cbi8vIFN0cmluZ0RlY29kZXIgcHJvdmlkZXMgYW4gaW50ZXJmYWNlIGZvciBlZmZpY2llbnRseSBzcGxpdHRpbmcgYSBzZXJpZXMgb2Zcbi8vIGJ1ZmZlcnMgaW50byBhIHNlcmllcyBvZiBKUyBzdHJpbmdzIHdpdGhvdXQgYnJlYWtpbmcgYXBhcnQgbXVsdGktYnl0ZVxuLy8gY2hhcmFjdGVycy5cbmV4cG9ydHMuU3RyaW5nRGVjb2RlciA9IFN0cmluZ0RlY29kZXI7XG5mdW5jdGlvbiBTdHJpbmdEZWNvZGVyKGVuY29kaW5nKSB7XG4gIHRoaXMuZW5jb2RpbmcgPSBub3JtYWxpemVFbmNvZGluZyhlbmNvZGluZyk7XG4gIHZhciBuYjtcbiAgc3dpdGNoICh0aGlzLmVuY29kaW5nKSB7XG4gICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICB0aGlzLnRleHQgPSB1dGYxNlRleHQ7XG4gICAgICB0aGlzLmVuZCA9IHV0ZjE2RW5kO1xuICAgICAgbmIgPSA0O1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAndXRmOCc6XG4gICAgICB0aGlzLmZpbGxMYXN0ID0gdXRmOEZpbGxMYXN0O1xuICAgICAgbmIgPSA0O1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgIHRoaXMudGV4dCA9IGJhc2U2NFRleHQ7XG4gICAgICB0aGlzLmVuZCA9IGJhc2U2NEVuZDtcbiAgICAgIG5iID0gMztcbiAgICAgIGJyZWFrO1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aGlzLndyaXRlID0gc2ltcGxlV3JpdGU7XG4gICAgICB0aGlzLmVuZCA9IHNpbXBsZUVuZDtcbiAgICAgIHJldHVybjtcbiAgfVxuICB0aGlzLmxhc3ROZWVkID0gMDtcbiAgdGhpcy5sYXN0VG90YWwgPSAwO1xuICB0aGlzLmxhc3RDaGFyID0gQnVmZmVyLmFsbG9jVW5zYWZlKG5iKTtcbn1cblxuU3RyaW5nRGVjb2Rlci5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbiAoYnVmKSB7XG4gIGlmIChidWYubGVuZ3RoID09PSAwKSByZXR1cm4gJyc7XG4gIHZhciByO1xuICB2YXIgaTtcbiAgaWYgKHRoaXMubGFzdE5lZWQpIHtcbiAgICByID0gdGhpcy5maWxsTGFzdChidWYpO1xuICAgIGlmIChyID09PSB1bmRlZmluZWQpIHJldHVybiAnJztcbiAgICBpID0gdGhpcy5sYXN0TmVlZDtcbiAgICB0aGlzLmxhc3ROZWVkID0gMDtcbiAgfSBlbHNlIHtcbiAgICBpID0gMDtcbiAgfVxuICBpZiAoaSA8IGJ1Zi5sZW5ndGgpIHJldHVybiByID8gciArIHRoaXMudGV4dChidWYsIGkpIDogdGhpcy50ZXh0KGJ1ZiwgaSk7XG4gIHJldHVybiByIHx8ICcnO1xufTtcblxuU3RyaW5nRGVjb2Rlci5wcm90b3R5cGUuZW5kID0gdXRmOEVuZDtcblxuLy8gUmV0dXJucyBvbmx5IGNvbXBsZXRlIGNoYXJhY3RlcnMgaW4gYSBCdWZmZXJcblN0cmluZ0RlY29kZXIucHJvdG90eXBlLnRleHQgPSB1dGY4VGV4dDtcblxuLy8gQXR0ZW1wdHMgdG8gY29tcGxldGUgYSBwYXJ0aWFsIG5vbi1VVEYtOCBjaGFyYWN0ZXIgdXNpbmcgYnl0ZXMgZnJvbSBhIEJ1ZmZlclxuU3RyaW5nRGVjb2Rlci5wcm90b3R5cGUuZmlsbExhc3QgPSBmdW5jdGlvbiAoYnVmKSB7XG4gIGlmICh0aGlzLmxhc3ROZWVkIDw9IGJ1Zi5sZW5ndGgpIHtcbiAgICBidWYuY29weSh0aGlzLmxhc3RDaGFyLCB0aGlzLmxhc3RUb3RhbCAtIHRoaXMubGFzdE5lZWQsIDAsIHRoaXMubGFzdE5lZWQpO1xuICAgIHJldHVybiB0aGlzLmxhc3RDaGFyLnRvU3RyaW5nKHRoaXMuZW5jb2RpbmcsIDAsIHRoaXMubGFzdFRvdGFsKTtcbiAgfVxuICBidWYuY29weSh0aGlzLmxhc3RDaGFyLCB0aGlzLmxhc3RUb3RhbCAtIHRoaXMubGFzdE5lZWQsIDAsIGJ1Zi5sZW5ndGgpO1xuICB0aGlzLmxhc3ROZWVkIC09IGJ1Zi5sZW5ndGg7XG59O1xuXG4vLyBDaGVja3MgdGhlIHR5cGUgb2YgYSBVVEYtOCBieXRlLCB3aGV0aGVyIGl0J3MgQVNDSUksIGEgbGVhZGluZyBieXRlLCBvciBhXG4vLyBjb250aW51YXRpb24gYnl0ZS4gSWYgYW4gaW52YWxpZCBieXRlIGlzIGRldGVjdGVkLCAtMiBpcyByZXR1cm5lZC5cbmZ1bmN0aW9uIHV0ZjhDaGVja0J5dGUoYnl0ZSkge1xuICBpZiAoYnl0ZSA8PSAweDdGKSByZXR1cm4gMDtlbHNlIGlmIChieXRlID4+IDUgPT09IDB4MDYpIHJldHVybiAyO2Vsc2UgaWYgKGJ5dGUgPj4gNCA9PT0gMHgwRSkgcmV0dXJuIDM7ZWxzZSBpZiAoYnl0ZSA+PiAzID09PSAweDFFKSByZXR1cm4gNDtcbiAgcmV0dXJuIGJ5dGUgPj4gNiA9PT0gMHgwMiA/IC0xIDogLTI7XG59XG5cbi8vIENoZWNrcyBhdCBtb3N0IDMgYnl0ZXMgYXQgdGhlIGVuZCBvZiBhIEJ1ZmZlciBpbiBvcmRlciB0byBkZXRlY3QgYW5cbi8vIGluY29tcGxldGUgbXVsdGktYnl0ZSBVVEYtOCBjaGFyYWN0ZXIuIFRoZSB0b3RhbCBudW1iZXIgb2YgYnl0ZXMgKDIsIDMsIG9yIDQpXG4vLyBuZWVkZWQgdG8gY29tcGxldGUgdGhlIFVURi04IGNoYXJhY3RlciAoaWYgYXBwbGljYWJsZSkgYXJlIHJldHVybmVkLlxuZnVuY3Rpb24gdXRmOENoZWNrSW5jb21wbGV0ZShzZWxmLCBidWYsIGkpIHtcbiAgdmFyIGogPSBidWYubGVuZ3RoIC0gMTtcbiAgaWYgKGogPCBpKSByZXR1cm4gMDtcbiAgdmFyIG5iID0gdXRmOENoZWNrQnl0ZShidWZbal0pO1xuICBpZiAobmIgPj0gMCkge1xuICAgIGlmIChuYiA+IDApIHNlbGYubGFzdE5lZWQgPSBuYiAtIDE7XG4gICAgcmV0dXJuIG5iO1xuICB9XG4gIGlmICgtLWogPCBpIHx8IG5iID09PSAtMikgcmV0dXJuIDA7XG4gIG5iID0gdXRmOENoZWNrQnl0ZShidWZbal0pO1xuICBpZiAobmIgPj0gMCkge1xuICAgIGlmIChuYiA+IDApIHNlbGYubGFzdE5lZWQgPSBuYiAtIDI7XG4gICAgcmV0dXJuIG5iO1xuICB9XG4gIGlmICgtLWogPCBpIHx8IG5iID09PSAtMikgcmV0dXJuIDA7XG4gIG5iID0gdXRmOENoZWNrQnl0ZShidWZbal0pO1xuICBpZiAobmIgPj0gMCkge1xuICAgIGlmIChuYiA+IDApIHtcbiAgICAgIGlmIChuYiA9PT0gMikgbmIgPSAwO2Vsc2Ugc2VsZi5sYXN0TmVlZCA9IG5iIC0gMztcbiAgICB9XG4gICAgcmV0dXJuIG5iO1xuICB9XG4gIHJldHVybiAwO1xufVxuXG4vLyBWYWxpZGF0ZXMgYXMgbWFueSBjb250aW51YXRpb24gYnl0ZXMgZm9yIGEgbXVsdGktYnl0ZSBVVEYtOCBjaGFyYWN0ZXIgYXNcbi8vIG5lZWRlZCBvciBhcmUgYXZhaWxhYmxlLiBJZiB3ZSBzZWUgYSBub24tY29udGludWF0aW9uIGJ5dGUgd2hlcmUgd2UgZXhwZWN0XG4vLyBvbmUsIHdlIFwicmVwbGFjZVwiIHRoZSB2YWxpZGF0ZWQgY29udGludWF0aW9uIGJ5dGVzIHdlJ3ZlIHNlZW4gc28gZmFyIHdpdGhcbi8vIGEgc2luZ2xlIFVURi04IHJlcGxhY2VtZW50IGNoYXJhY3RlciAoJ1xcdWZmZmQnKSwgdG8gbWF0Y2ggdjgncyBVVEYtOCBkZWNvZGluZ1xuLy8gYmVoYXZpb3IuIFRoZSBjb250aW51YXRpb24gYnl0ZSBjaGVjayBpcyBpbmNsdWRlZCB0aHJlZSB0aW1lcyBpbiB0aGUgY2FzZVxuLy8gd2hlcmUgYWxsIG9mIHRoZSBjb250aW51YXRpb24gYnl0ZXMgZm9yIGEgY2hhcmFjdGVyIGV4aXN0IGluIHRoZSBzYW1lIGJ1ZmZlci5cbi8vIEl0IGlzIGFsc28gZG9uZSB0aGlzIHdheSBhcyBhIHNsaWdodCBwZXJmb3JtYW5jZSBpbmNyZWFzZSBpbnN0ZWFkIG9mIHVzaW5nIGFcbi8vIGxvb3AuXG5mdW5jdGlvbiB1dGY4Q2hlY2tFeHRyYUJ5dGVzKHNlbGYsIGJ1ZiwgcCkge1xuICBpZiAoKGJ1ZlswXSAmIDB4QzApICE9PSAweDgwKSB7XG4gICAgc2VsZi5sYXN0TmVlZCA9IDA7XG4gICAgcmV0dXJuICdcXHVmZmZkJztcbiAgfVxuICBpZiAoc2VsZi5sYXN0TmVlZCA+IDEgJiYgYnVmLmxlbmd0aCA+IDEpIHtcbiAgICBpZiAoKGJ1ZlsxXSAmIDB4QzApICE9PSAweDgwKSB7XG4gICAgICBzZWxmLmxhc3ROZWVkID0gMTtcbiAgICAgIHJldHVybiAnXFx1ZmZmZCc7XG4gICAgfVxuICAgIGlmIChzZWxmLmxhc3ROZWVkID4gMiAmJiBidWYubGVuZ3RoID4gMikge1xuICAgICAgaWYgKChidWZbMl0gJiAweEMwKSAhPT0gMHg4MCkge1xuICAgICAgICBzZWxmLmxhc3ROZWVkID0gMjtcbiAgICAgICAgcmV0dXJuICdcXHVmZmZkJztcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuLy8gQXR0ZW1wdHMgdG8gY29tcGxldGUgYSBtdWx0aS1ieXRlIFVURi04IGNoYXJhY3RlciB1c2luZyBieXRlcyBmcm9tIGEgQnVmZmVyLlxuZnVuY3Rpb24gdXRmOEZpbGxMYXN0KGJ1Zikge1xuICB2YXIgcCA9IHRoaXMubGFzdFRvdGFsIC0gdGhpcy5sYXN0TmVlZDtcbiAgdmFyIHIgPSB1dGY4Q2hlY2tFeHRyYUJ5dGVzKHRoaXMsIGJ1ZiwgcCk7XG4gIGlmIChyICE9PSB1bmRlZmluZWQpIHJldHVybiByO1xuICBpZiAodGhpcy5sYXN0TmVlZCA8PSBidWYubGVuZ3RoKSB7XG4gICAgYnVmLmNvcHkodGhpcy5sYXN0Q2hhciwgcCwgMCwgdGhpcy5sYXN0TmVlZCk7XG4gICAgcmV0dXJuIHRoaXMubGFzdENoYXIudG9TdHJpbmcodGhpcy5lbmNvZGluZywgMCwgdGhpcy5sYXN0VG90YWwpO1xuICB9XG4gIGJ1Zi5jb3B5KHRoaXMubGFzdENoYXIsIHAsIDAsIGJ1Zi5sZW5ndGgpO1xuICB0aGlzLmxhc3ROZWVkIC09IGJ1Zi5sZW5ndGg7XG59XG5cbi8vIFJldHVybnMgYWxsIGNvbXBsZXRlIFVURi04IGNoYXJhY3RlcnMgaW4gYSBCdWZmZXIuIElmIHRoZSBCdWZmZXIgZW5kZWQgb24gYVxuLy8gcGFydGlhbCBjaGFyYWN0ZXIsIHRoZSBjaGFyYWN0ZXIncyBieXRlcyBhcmUgYnVmZmVyZWQgdW50aWwgdGhlIHJlcXVpcmVkXG4vLyBudW1iZXIgb2YgYnl0ZXMgYXJlIGF2YWlsYWJsZS5cbmZ1bmN0aW9uIHV0ZjhUZXh0KGJ1ZiwgaSkge1xuICB2YXIgdG90YWwgPSB1dGY4Q2hlY2tJbmNvbXBsZXRlKHRoaXMsIGJ1ZiwgaSk7XG4gIGlmICghdGhpcy5sYXN0TmVlZCkgcmV0dXJuIGJ1Zi50b1N0cmluZygndXRmOCcsIGkpO1xuICB0aGlzLmxhc3RUb3RhbCA9IHRvdGFsO1xuICB2YXIgZW5kID0gYnVmLmxlbmd0aCAtICh0b3RhbCAtIHRoaXMubGFzdE5lZWQpO1xuICBidWYuY29weSh0aGlzLmxhc3RDaGFyLCAwLCBlbmQpO1xuICByZXR1cm4gYnVmLnRvU3RyaW5nKCd1dGY4JywgaSwgZW5kKTtcbn1cblxuLy8gRm9yIFVURi04LCBhIHJlcGxhY2VtZW50IGNoYXJhY3RlciBpcyBhZGRlZCB3aGVuIGVuZGluZyBvbiBhIHBhcnRpYWxcbi8vIGNoYXJhY3Rlci5cbmZ1bmN0aW9uIHV0ZjhFbmQoYnVmKSB7XG4gIHZhciByID0gYnVmICYmIGJ1Zi5sZW5ndGggPyB0aGlzLndyaXRlKGJ1ZikgOiAnJztcbiAgaWYgKHRoaXMubGFzdE5lZWQpIHJldHVybiByICsgJ1xcdWZmZmQnO1xuICByZXR1cm4gcjtcbn1cblxuLy8gVVRGLTE2TEUgdHlwaWNhbGx5IG5lZWRzIHR3byBieXRlcyBwZXIgY2hhcmFjdGVyLCBidXQgZXZlbiBpZiB3ZSBoYXZlIGFuIGV2ZW5cbi8vIG51bWJlciBvZiBieXRlcyBhdmFpbGFibGUsIHdlIG5lZWQgdG8gY2hlY2sgaWYgd2UgZW5kIG9uIGEgbGVhZGluZy9oaWdoXG4vLyBzdXJyb2dhdGUuIEluIHRoYXQgY2FzZSwgd2UgbmVlZCB0byB3YWl0IGZvciB0aGUgbmV4dCB0d28gYnl0ZXMgaW4gb3JkZXIgdG9cbi8vIGRlY29kZSB0aGUgbGFzdCBjaGFyYWN0ZXIgcHJvcGVybHkuXG5mdW5jdGlvbiB1dGYxNlRleHQoYnVmLCBpKSB7XG4gIGlmICgoYnVmLmxlbmd0aCAtIGkpICUgMiA9PT0gMCkge1xuICAgIHZhciByID0gYnVmLnRvU3RyaW5nKCd1dGYxNmxlJywgaSk7XG4gICAgaWYgKHIpIHtcbiAgICAgIHZhciBjID0gci5jaGFyQ29kZUF0KHIubGVuZ3RoIC0gMSk7XG4gICAgICBpZiAoYyA+PSAweEQ4MDAgJiYgYyA8PSAweERCRkYpIHtcbiAgICAgICAgdGhpcy5sYXN0TmVlZCA9IDI7XG4gICAgICAgIHRoaXMubGFzdFRvdGFsID0gNDtcbiAgICAgICAgdGhpcy5sYXN0Q2hhclswXSA9IGJ1ZltidWYubGVuZ3RoIC0gMl07XG4gICAgICAgIHRoaXMubGFzdENoYXJbMV0gPSBidWZbYnVmLmxlbmd0aCAtIDFdO1xuICAgICAgICByZXR1cm4gci5zbGljZSgwLCAtMSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByO1xuICB9XG4gIHRoaXMubGFzdE5lZWQgPSAxO1xuICB0aGlzLmxhc3RUb3RhbCA9IDI7XG4gIHRoaXMubGFzdENoYXJbMF0gPSBidWZbYnVmLmxlbmd0aCAtIDFdO1xuICByZXR1cm4gYnVmLnRvU3RyaW5nKCd1dGYxNmxlJywgaSwgYnVmLmxlbmd0aCAtIDEpO1xufVxuXG4vLyBGb3IgVVRGLTE2TEUgd2UgZG8gbm90IGV4cGxpY2l0bHkgYXBwZW5kIHNwZWNpYWwgcmVwbGFjZW1lbnQgY2hhcmFjdGVycyBpZiB3ZVxuLy8gZW5kIG9uIGEgcGFydGlhbCBjaGFyYWN0ZXIsIHdlIHNpbXBseSBsZXQgdjggaGFuZGxlIHRoYXQuXG5mdW5jdGlvbiB1dGYxNkVuZChidWYpIHtcbiAgdmFyIHIgPSBidWYgJiYgYnVmLmxlbmd0aCA/IHRoaXMud3JpdGUoYnVmKSA6ICcnO1xuICBpZiAodGhpcy5sYXN0TmVlZCkge1xuICAgIHZhciBlbmQgPSB0aGlzLmxhc3RUb3RhbCAtIHRoaXMubGFzdE5lZWQ7XG4gICAgcmV0dXJuIHIgKyB0aGlzLmxhc3RDaGFyLnRvU3RyaW5nKCd1dGYxNmxlJywgMCwgZW5kKTtcbiAgfVxuICByZXR1cm4gcjtcbn1cblxuZnVuY3Rpb24gYmFzZTY0VGV4dChidWYsIGkpIHtcbiAgdmFyIG4gPSAoYnVmLmxlbmd0aCAtIGkpICUgMztcbiAgaWYgKG4gPT09IDApIHJldHVybiBidWYudG9TdHJpbmcoJ2Jhc2U2NCcsIGkpO1xuICB0aGlzLmxhc3ROZWVkID0gMyAtIG47XG4gIHRoaXMubGFzdFRvdGFsID0gMztcbiAgaWYgKG4gPT09IDEpIHtcbiAgICB0aGlzLmxhc3RDaGFyWzBdID0gYnVmW2J1Zi5sZW5ndGggLSAxXTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLmxhc3RDaGFyWzBdID0gYnVmW2J1Zi5sZW5ndGggLSAyXTtcbiAgICB0aGlzLmxhc3RDaGFyWzFdID0gYnVmW2J1Zi5sZW5ndGggLSAxXTtcbiAgfVxuICByZXR1cm4gYnVmLnRvU3RyaW5nKCdiYXNlNjQnLCBpLCBidWYubGVuZ3RoIC0gbik7XG59XG5cbmZ1bmN0aW9uIGJhc2U2NEVuZChidWYpIHtcbiAgdmFyIHIgPSBidWYgJiYgYnVmLmxlbmd0aCA/IHRoaXMud3JpdGUoYnVmKSA6ICcnO1xuICBpZiAodGhpcy5sYXN0TmVlZCkgcmV0dXJuIHIgKyB0aGlzLmxhc3RDaGFyLnRvU3RyaW5nKCdiYXNlNjQnLCAwLCAzIC0gdGhpcy5sYXN0TmVlZCk7XG4gIHJldHVybiByO1xufVxuXG4vLyBQYXNzIGJ5dGVzIG9uIHRocm91Z2ggZm9yIHNpbmdsZS1ieXRlIGVuY29kaW5ncyAoZS5nLiBhc2NpaSwgbGF0aW4xLCBoZXgpXG5mdW5jdGlvbiBzaW1wbGVXcml0ZShidWYpIHtcbiAgcmV0dXJuIGJ1Zi50b1N0cmluZyh0aGlzLmVuY29kaW5nKTtcbn1cblxuZnVuY3Rpb24gc2ltcGxlRW5kKGJ1Zikge1xuICByZXR1cm4gYnVmICYmIGJ1Zi5sZW5ndGggPyB0aGlzLndyaXRlKGJ1ZikgOiAnJztcbn0iLCJcInVzZSBzdHJpY3RcIjtcbnZhciBfX3NwcmVhZEFycmF5cyA9ICh0aGlzICYmIHRoaXMuX19zcHJlYWRBcnJheXMpIHx8IGZ1bmN0aW9uICgpIHtcbiAgICBmb3IgKHZhciBzID0gMCwgaSA9IDAsIGlsID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IGlsOyBpKyspIHMgKz0gYXJndW1lbnRzW2ldLmxlbmd0aDtcbiAgICBmb3IgKHZhciByID0gQXJyYXkocyksIGsgPSAwLCBpID0gMDsgaSA8IGlsOyBpKyspXG4gICAgICAgIGZvciAodmFyIGEgPSBhcmd1bWVudHNbaV0sIGogPSAwLCBqbCA9IGEubGVuZ3RoOyBqIDwgamw7IGorKywgaysrKVxuICAgICAgICAgICAgcltrXSA9IGFbal07XG4gICAgcmV0dXJuIHI7XG59O1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5DaGVja2VyID0gZXhwb3J0cy5jcmVhdGVDaGVja2VycyA9IHZvaWQgMDtcbnZhciB0eXBlc18xID0gcmVxdWlyZShcIi4vdHlwZXNcIik7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIi4vdXRpbFwiKTtcbi8qKlxuICogRXhwb3J0IGZ1bmN0aW9ucyB1c2VkIHRvIGRlZmluZSBpbnRlcmZhY2VzLlxuICovXG52YXIgdHlwZXNfMiA9IHJlcXVpcmUoXCIuL3R5cGVzXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiVEFycmF5XCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiB0eXBlc18yLlRBcnJheTsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlRFbnVtVHlwZVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdHlwZXNfMi5URW51bVR5cGU7IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJURW51bUxpdGVyYWxcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHR5cGVzXzIuVEVudW1MaXRlcmFsOyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiVEZ1bmNcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHR5cGVzXzIuVEZ1bmM7IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJUSWZhY2VcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHR5cGVzXzIuVElmYWNlOyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiVExpdGVyYWxcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHR5cGVzXzIuVExpdGVyYWw7IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJUTmFtZVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdHlwZXNfMi5UTmFtZTsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlRPcHRpb25hbFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdHlwZXNfMi5UT3B0aW9uYWw7IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJUUGFyYW1cIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHR5cGVzXzIuVFBhcmFtOyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiVFBhcmFtTGlzdFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdHlwZXNfMi5UUGFyYW1MaXN0OyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiVFByb3BcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHR5cGVzXzIuVFByb3A7IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJUVHVwbGVcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHR5cGVzXzIuVFR1cGxlOyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiVFR5cGVcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHR5cGVzXzIuVFR5cGU7IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJUVW5pb25cIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHR5cGVzXzIuVFVuaW9uOyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiVEludGVyc2VjdGlvblwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdHlwZXNfMi5USW50ZXJzZWN0aW9uOyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiYXJyYXlcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHR5cGVzXzIuYXJyYXk7IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJlbnVtbGl0XCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiB0eXBlc18yLmVudW1saXQ7IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJlbnVtdHlwZVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdHlwZXNfMi5lbnVtdHlwZTsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcImZ1bmNcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHR5cGVzXzIuZnVuYzsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcImlmYWNlXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiB0eXBlc18yLmlmYWNlOyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwibGl0XCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiB0eXBlc18yLmxpdDsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIm5hbWVcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHR5cGVzXzIubmFtZTsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIm9wdFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdHlwZXNfMi5vcHQ7IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJwYXJhbVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdHlwZXNfMi5wYXJhbTsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcInR1cGxlXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiB0eXBlc18yLnR1cGxlOyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwidW5pb25cIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHR5cGVzXzIudW5pb247IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJpbnRlcnNlY3Rpb25cIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHR5cGVzXzIuaW50ZXJzZWN0aW9uOyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwicmVzdFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdHlwZXNfMi5yZXN0OyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiaW5kZXhLZXlcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHR5cGVzXzIuaW5kZXhLZXk7IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJCYXNpY1R5cGVcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHR5cGVzXzIuQmFzaWNUeXBlOyB9IH0pO1xudmFyIHV0aWxfMiA9IHJlcXVpcmUoXCIuL3V0aWxcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJWRXJyb3JcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHV0aWxfMi5WRXJyb3I7IH0gfSk7XG4vKipcbiAqIFRha2VzIG9uZSBvZiBtb3JlIHR5cGUgc3VpdGVzIChlLmcuIGEgbW9kdWxlIGdlbmVyYXRlZCBieSBgdHMtaW50ZXJmYWNlLWJ1aWxkZXJgKSwgYW5kIGNvbWJpbmVzXG4gKiB0aGVtIGludG8gYSBzdWl0ZSBvZiBpbnRlcmZhY2UgY2hlY2tlcnMuIElmIGEgdHlwZSBpcyB1c2VkIGJ5IG5hbWUsIHRoYXQgbmFtZSBzaG91bGQgYmUgcHJlc2VudFxuICogYW1vbmcgdGhlIHBhc3NlZC1pbiB0eXBlIHN1aXRlcy5cbiAqXG4gKiBUaGUgcmV0dXJuZWQgb2JqZWN0IG1hcHMgdHlwZSBuYW1lcyB0byBDaGVja2VyIG9iamVjdHMuXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUNoZWNrZXJzKCkge1xuICAgIHZhciB0eXBlU3VpdGUgPSBbXTtcbiAgICBmb3IgKHZhciBfaSA9IDA7IF9pIDwgYXJndW1lbnRzLmxlbmd0aDsgX2krKykge1xuICAgICAgICB0eXBlU3VpdGVbX2ldID0gYXJndW1lbnRzW19pXTtcbiAgICB9XG4gICAgdmFyIGZ1bGxTdWl0ZSA9IE9iamVjdC5hc3NpZ24uYXBwbHkoT2JqZWN0LCBfX3NwcmVhZEFycmF5cyhbe30sIHR5cGVzXzEuYmFzaWNUeXBlc10sIHR5cGVTdWl0ZSkpO1xuICAgIHZhciBjaGVja2VycyA9IHt9O1xuICAgIGZvciAodmFyIF9hID0gMCwgdHlwZVN1aXRlXzEgPSB0eXBlU3VpdGU7IF9hIDwgdHlwZVN1aXRlXzEubGVuZ3RoOyBfYSsrKSB7XG4gICAgICAgIHZhciBzdWl0ZV8xID0gdHlwZVN1aXRlXzFbX2FdO1xuICAgICAgICBmb3IgKHZhciBfYiA9IDAsIF9jID0gT2JqZWN0LmtleXMoc3VpdGVfMSk7IF9iIDwgX2MubGVuZ3RoOyBfYisrKSB7XG4gICAgICAgICAgICB2YXIgbmFtZSA9IF9jW19iXTtcbiAgICAgICAgICAgIGNoZWNrZXJzW25hbWVdID0gbmV3IENoZWNrZXIoZnVsbFN1aXRlLCBzdWl0ZV8xW25hbWVdKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gY2hlY2tlcnM7XG59XG5leHBvcnRzLmNyZWF0ZUNoZWNrZXJzID0gY3JlYXRlQ2hlY2tlcnM7XG4vKipcbiAqIENoZWNrZXIgaW1wbGVtZW50cyB2YWxpZGF0aW9uIG9mIG9iamVjdHMsIGFuZCBhbHNvIGluY2x1ZGVzIGFjY2Vzc29ycyB0byB2YWxpZGF0ZSBtZXRob2QgY2FsbHMuXG4gKiBDaGVja2VycyBzaG91bGQgYmUgY3JlYXRlZCB1c2luZyBgY3JlYXRlQ2hlY2tlcnMoKWAuXG4gKi9cbnZhciBDaGVja2VyID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xuICAgIC8vIENyZWF0ZSBjaGVja2VycyBieSB1c2luZyBgY3JlYXRlQ2hlY2tlcnMoKWAgZnVuY3Rpb24uXG4gICAgZnVuY3Rpb24gQ2hlY2tlcihzdWl0ZSwgdHR5cGUsIF9wYXRoKSB7XG4gICAgICAgIGlmIChfcGF0aCA9PT0gdm9pZCAwKSB7IF9wYXRoID0gJ3ZhbHVlJzsgfVxuICAgICAgICB0aGlzLnN1aXRlID0gc3VpdGU7XG4gICAgICAgIHRoaXMudHR5cGUgPSB0dHlwZTtcbiAgICAgICAgdGhpcy5fcGF0aCA9IF9wYXRoO1xuICAgICAgICB0aGlzLnByb3BzID0gbmV3IE1hcCgpO1xuICAgICAgICBpZiAodHR5cGUgaW5zdGFuY2VvZiB0eXBlc18xLlRJZmFjZSkge1xuICAgICAgICAgICAgZm9yICh2YXIgX2kgPSAwLCBfYSA9IHR0eXBlLnByb3BzOyBfaSA8IF9hLmxlbmd0aDsgX2krKykge1xuICAgICAgICAgICAgICAgIHZhciBwID0gX2FbX2ldO1xuICAgICAgICAgICAgICAgIHRoaXMucHJvcHMuc2V0KHAubmFtZSwgcC50dHlwZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jaGVja2VyUGxhaW4gPSB0aGlzLnR0eXBlLmdldENoZWNrZXIoc3VpdGUsIGZhbHNlKTtcbiAgICAgICAgdGhpcy5jaGVja2VyU3RyaWN0ID0gdGhpcy50dHlwZS5nZXRDaGVja2VyKHN1aXRlLCB0cnVlKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2V0IHRoZSBwYXRoIHRvIHJlcG9ydCBpbiBlcnJvcnMsIGluc3RlYWQgb2YgdGhlIGRlZmF1bHQgXCJ2YWx1ZVwiLiAoRS5nLiBpZiB0aGUgQ2hlY2tlciBpcyBmb3JcbiAgICAgKiBhIFwicGVyc29uXCIgaW50ZXJmYWNlLCBzZXQgcGF0aCB0byBcInBlcnNvblwiIHRvIHJlcG9ydCBlLmcuIFwicGVyc29uLm5hbWUgaXMgbm90IGEgc3RyaW5nXCIuKVxuICAgICAqL1xuICAgIENoZWNrZXIucHJvdG90eXBlLnNldFJlcG9ydGVkUGF0aCA9IGZ1bmN0aW9uIChwYXRoKSB7XG4gICAgICAgIHRoaXMuX3BhdGggPSBwYXRoO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogQ2hlY2sgdGhhdCB0aGUgZ2l2ZW4gdmFsdWUgc2F0aXNmaWVzIHRoaXMgY2hlY2tlcidzIHR5cGUsIG9yIHRocm93IEVycm9yLlxuICAgICAqL1xuICAgIENoZWNrZXIucHJvdG90eXBlLmNoZWNrID0gZnVuY3Rpb24gKHZhbHVlKSB7IHJldHVybiB0aGlzLl9kb0NoZWNrKHRoaXMuY2hlY2tlclBsYWluLCB2YWx1ZSk7IH07XG4gICAgLyoqXG4gICAgICogQSBmYXN0IGNoZWNrIGZvciB3aGV0aGVyIG9yIG5vdCB0aGUgZ2l2ZW4gdmFsdWUgc2F0aXNmaWVzIHRoaXMgQ2hlY2tlcidzIHR5cGUuIFRoaXMgcmV0dXJuc1xuICAgICAqIHRydWUgb3IgZmFsc2UsIGRvZXMgbm90IHByb2R1Y2UgYW4gZXJyb3IgbWVzc2FnZSwgYW5kIGlzIGZhc3QgYm90aCBvbiBzdWNjZXNzIGFuZCBvbiBmYWlsdXJlLlxuICAgICAqL1xuICAgIENoZWNrZXIucHJvdG90eXBlLnRlc3QgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2hlY2tlclBsYWluKHZhbHVlLCBuZXcgdXRpbF8xLk5vb3BDb250ZXh0KCkpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIG5vbi1lbXB0eSBhcnJheSBvZiBlcnJvciBvYmplY3RzIGRlc2NyaWJpbmcgdGhlIGVycm9ycyBpZiB0aGUgZ2l2ZW4gdmFsdWUgZG9lcyBub3Qgc2F0aXNmeSB0aGlzXG4gICAgICogQ2hlY2tlcidzIHR5cGUsIG9yIG51bGwgaWYgaXQgZG9lcy5cbiAgICAgKi9cbiAgICBDaGVja2VyLnByb3RvdHlwZS52YWxpZGF0ZSA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZG9WYWxpZGF0ZSh0aGlzLmNoZWNrZXJQbGFpbiwgdmFsdWUpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogQ2hlY2sgdGhhdCB0aGUgZ2l2ZW4gdmFsdWUgc2F0aXNmaWVzIHRoaXMgY2hlY2tlcidzIHR5cGUgc3RyaWN0bHkuIFRoaXMgY2hlY2tzIHRoYXQgb2JqZWN0c1xuICAgICAqIGFuZCB0dXBsZXMgaGF2ZSBubyBleHRyYSBtZW1iZXJzLiBOb3RlIHRoYXQgdGhpcyBwcmV2ZW50cyBiYWNrd2FyZCBjb21wYXRpYmlsaXR5LCBzbyB1c3VhbGx5XG4gICAgICogYSBwbGFpbiBjaGVjaygpIGlzIG1vcmUgYXBwcm9wcmlhdGUuXG4gICAgICovXG4gICAgQ2hlY2tlci5wcm90b3R5cGUuc3RyaWN0Q2hlY2sgPSBmdW5jdGlvbiAodmFsdWUpIHsgcmV0dXJuIHRoaXMuX2RvQ2hlY2sodGhpcy5jaGVja2VyU3RyaWN0LCB2YWx1ZSk7IH07XG4gICAgLyoqXG4gICAgICogQSBmYXN0IHN0cmljdCBjaGVjayBmb3Igd2hldGhlciBvciBub3QgdGhlIGdpdmVuIHZhbHVlIHNhdGlzZmllcyB0aGlzIENoZWNrZXIncyB0eXBlLiBSZXR1cm5zXG4gICAgICogdHJ1ZSBvciBmYWxzZSwgZG9lcyBub3QgcHJvZHVjZSBhbiBlcnJvciBtZXNzYWdlLCBhbmQgaXMgZmFzdCBib3RoIG9uIHN1Y2Nlc3MgYW5kIG9uIGZhaWx1cmUuXG4gICAgICovXG4gICAgQ2hlY2tlci5wcm90b3R5cGUuc3RyaWN0VGVzdCA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5jaGVja2VyU3RyaWN0KHZhbHVlLCBuZXcgdXRpbF8xLk5vb3BDb250ZXh0KCkpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIG5vbi1lbXB0eSBhcnJheSBvZiBlcnJvciBvYmplY3RzIGRlc2NyaWJpbmcgdGhlIGVycm9ycyBpZiB0aGUgZ2l2ZW4gdmFsdWUgZG9lcyBub3Qgc2F0aXNmeSB0aGlzXG4gICAgICogQ2hlY2tlcidzIHR5cGUgc3RyaWN0bHksIG9yIG51bGwgaWYgaXQgZG9lcy5cbiAgICAgKi9cbiAgICBDaGVja2VyLnByb3RvdHlwZS5zdHJpY3RWYWxpZGF0ZSA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZG9WYWxpZGF0ZSh0aGlzLmNoZWNrZXJTdHJpY3QsIHZhbHVlKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIElmIHRoaXMgY2hlY2tlciBpcyBmb3IgYW4gaW50ZXJmYWNlLCByZXR1cm5zIGEgQ2hlY2tlciBmb3IgdGhlIHR5cGUgcmVxdWlyZWQgZm9yIHRoZSBnaXZlblxuICAgICAqIHByb3BlcnR5IG9mIHRoaXMgaW50ZXJmYWNlLlxuICAgICAqL1xuICAgIENoZWNrZXIucHJvdG90eXBlLmdldFByb3AgPSBmdW5jdGlvbiAocHJvcCkge1xuICAgICAgICB2YXIgdHR5cGUgPSB0aGlzLnByb3BzLmdldChwcm9wKTtcbiAgICAgICAgaWYgKCF0dHlwZSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVHlwZSBoYXMgbm8gcHJvcGVydHkgXCIgKyBwcm9wKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IENoZWNrZXIodGhpcy5zdWl0ZSwgdHR5cGUsIHRoaXMuX3BhdGggKyBcIi5cIiArIHByb3ApO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogSWYgdGhpcyBjaGVja2VyIGlzIGZvciBhbiBpbnRlcmZhY2UsIHJldHVybnMgYSBDaGVja2VyIGZvciB0aGUgYXJndW1lbnQtbGlzdCByZXF1aXJlZCB0byBjYWxsXG4gICAgICogdGhlIGdpdmVuIG1ldGhvZCBvZiB0aGlzIGludGVyZmFjZS4gRS5nLiBpZiB0aGlzIENoZWNrZXIgaXMgZm9yIHRoZSBpbnRlcmZhY2U6XG4gICAgICogICAgaW50ZXJmYWNlIEZvbyB7XG4gICAgICogICAgICBmaW5kKHM6IHN0cmluZywgcG9zPzogbnVtYmVyKTogbnVtYmVyO1xuICAgICAqICAgIH1cbiAgICAgKiBUaGVuIG1ldGhvZEFyZ3MoXCJmaW5kXCIpLmNoZWNrKC4uLikgd2lsbCBzdWNjZWVkIGZvciBbXCJmb29cIl0gYW5kIFtcImZvb1wiLCAzXSwgYnV0IG5vdCBmb3IgWzE3XS5cbiAgICAgKi9cbiAgICBDaGVja2VyLnByb3RvdHlwZS5tZXRob2RBcmdzID0gZnVuY3Rpb24gKG1ldGhvZE5hbWUpIHtcbiAgICAgICAgdmFyIHRmdW5jID0gdGhpcy5fZ2V0TWV0aG9kKG1ldGhvZE5hbWUpO1xuICAgICAgICByZXR1cm4gbmV3IENoZWNrZXIodGhpcy5zdWl0ZSwgdGZ1bmMucGFyYW1MaXN0KTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIElmIHRoaXMgY2hlY2tlciBpcyBmb3IgYW4gaW50ZXJmYWNlLCByZXR1cm5zIGEgQ2hlY2tlciBmb3IgdGhlIHJldHVybiB2YWx1ZSBvZiB0aGUgZ2l2ZW5cbiAgICAgKiBtZXRob2Qgb2YgdGhpcyBpbnRlcmZhY2UuXG4gICAgICovXG4gICAgQ2hlY2tlci5wcm90b3R5cGUubWV0aG9kUmVzdWx0ID0gZnVuY3Rpb24gKG1ldGhvZE5hbWUpIHtcbiAgICAgICAgdmFyIHRmdW5jID0gdGhpcy5fZ2V0TWV0aG9kKG1ldGhvZE5hbWUpO1xuICAgICAgICByZXR1cm4gbmV3IENoZWNrZXIodGhpcy5zdWl0ZSwgdGZ1bmMucmVzdWx0KTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIElmIHRoaXMgY2hlY2tlciBpcyBmb3IgYSBmdW5jdGlvbiwgcmV0dXJucyBhIENoZWNrZXIgZm9yIGl0cyBhcmd1bWVudC1saXN0LlxuICAgICAqL1xuICAgIENoZWNrZXIucHJvdG90eXBlLmdldEFyZ3MgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICghKHRoaXMudHR5cGUgaW5zdGFuY2VvZiB0eXBlc18xLlRGdW5jKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiZ2V0QXJncygpIGFwcGxpZWQgdG8gbm9uLWZ1bmN0aW9uXCIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgQ2hlY2tlcih0aGlzLnN1aXRlLCB0aGlzLnR0eXBlLnBhcmFtTGlzdCk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBJZiB0aGlzIGNoZWNrZXIgaXMgZm9yIGEgZnVuY3Rpb24sIHJldHVybnMgYSBDaGVja2VyIGZvciBpdHMgcmVzdWx0LlxuICAgICAqL1xuICAgIENoZWNrZXIucHJvdG90eXBlLmdldFJlc3VsdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKCEodGhpcy50dHlwZSBpbnN0YW5jZW9mIHR5cGVzXzEuVEZ1bmMpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJnZXRSZXN1bHQoKSBhcHBsaWVkIHRvIG5vbi1mdW5jdGlvblwiKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IENoZWNrZXIodGhpcy5zdWl0ZSwgdGhpcy50dHlwZS5yZXN1bHQpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSB0eXBlIGZvciB3aGljaCB0aGlzIGlzIGEgY2hlY2tlci5cbiAgICAgKi9cbiAgICBDaGVja2VyLnByb3RvdHlwZS5nZXRUeXBlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy50dHlwZTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIEFjdHVhbCBpbXBsZW1lbnRhdGlvbiBvZiBjaGVjaygpIGFuZCBzdHJpY3RDaGVjaygpLlxuICAgICAqL1xuICAgIENoZWNrZXIucHJvdG90eXBlLl9kb0NoZWNrID0gZnVuY3Rpb24gKGNoZWNrZXJGdW5jLCB2YWx1ZSkge1xuICAgICAgICB2YXIgbm9vcEN0eCA9IG5ldyB1dGlsXzEuTm9vcENvbnRleHQoKTtcbiAgICAgICAgaWYgKCFjaGVja2VyRnVuYyh2YWx1ZSwgbm9vcEN0eCkpIHtcbiAgICAgICAgICAgIHZhciBkZXRhaWxDdHggPSBuZXcgdXRpbF8xLkRldGFpbENvbnRleHQoKTtcbiAgICAgICAgICAgIGNoZWNrZXJGdW5jKHZhbHVlLCBkZXRhaWxDdHgpO1xuICAgICAgICAgICAgdGhyb3cgZGV0YWlsQ3R4LmdldEVycm9yKHRoaXMuX3BhdGgpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBDaGVja2VyLnByb3RvdHlwZS5fZG9WYWxpZGF0ZSA9IGZ1bmN0aW9uIChjaGVja2VyRnVuYywgdmFsdWUpIHtcbiAgICAgICAgdmFyIG5vb3BDdHggPSBuZXcgdXRpbF8xLk5vb3BDb250ZXh0KCk7XG4gICAgICAgIGlmIChjaGVja2VyRnVuYyh2YWx1ZSwgbm9vcEN0eCkpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgICAgIHZhciBkZXRhaWxDdHggPSBuZXcgdXRpbF8xLkRldGFpbENvbnRleHQoKTtcbiAgICAgICAgY2hlY2tlckZ1bmModmFsdWUsIGRldGFpbEN0eCk7XG4gICAgICAgIHJldHVybiBkZXRhaWxDdHguZ2V0RXJyb3JEZXRhaWxzKHRoaXMuX3BhdGgpO1xuICAgIH07XG4gICAgQ2hlY2tlci5wcm90b3R5cGUuX2dldE1ldGhvZCA9IGZ1bmN0aW9uIChtZXRob2ROYW1lKSB7XG4gICAgICAgIHZhciB0dHlwZSA9IHRoaXMucHJvcHMuZ2V0KG1ldGhvZE5hbWUpO1xuICAgICAgICBpZiAoIXR0eXBlKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUeXBlIGhhcyBubyBwcm9wZXJ0eSBcIiArIG1ldGhvZE5hbWUpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghKHR0eXBlIGluc3RhbmNlb2YgdHlwZXNfMS5URnVuYykpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlByb3BlcnR5IFwiICsgbWV0aG9kTmFtZSArIFwiIGlzIG5vdCBhIG1ldGhvZFwiKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHR5cGU7XG4gICAgfTtcbiAgICByZXR1cm4gQ2hlY2tlcjtcbn0oKSk7XG5leHBvcnRzLkNoZWNrZXIgPSBDaGVja2VyO1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG4vKipcbiAqIFRoaXMgbW9kdWxlIGRlZmluZXMgbm9kZXMgdXNlZCB0byBkZWZpbmUgdHlwZXMgYW5kIHZhbGlkYXRpb25zIGZvciBvYmplY3RzIGFuZCBpbnRlcmZhY2VzLlxuICovXG4vLyB0c2xpbnQ6ZGlzYWJsZTpuby1zaGFkb3dlZC12YXJpYWJsZSBwcmVmZXItZm9yLW9mXG52YXIgX19leHRlbmRzID0gKHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMpIHx8IChmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGV4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgICBleHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8XG4gICAgICAgICAgICAoeyBfX3Byb3RvX186IFtdIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikgeyBkLl9fcHJvdG9fXyA9IGI7IH0pIHx8XG4gICAgICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChiLmhhc093blByb3BlcnR5KHApKSBkW3BdID0gYltwXTsgfTtcbiAgICAgICAgcmV0dXJuIGV4dGVuZFN0YXRpY3MoZCwgYik7XG4gICAgfTtcbiAgICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgICAgZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgICAgICAgZnVuY3Rpb24gX18oKSB7IHRoaXMuY29uc3RydWN0b3IgPSBkOyB9XG4gICAgICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgICB9O1xufSkoKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuYmFzaWNUeXBlcyA9IGV4cG9ydHMuQmFzaWNUeXBlID0gZXhwb3J0cy5UUGFyYW1MaXN0ID0gZXhwb3J0cy5UUGFyYW0gPSBleHBvcnRzLnBhcmFtID0gZXhwb3J0cy5URnVuYyA9IGV4cG9ydHMuZnVuYyA9IGV4cG9ydHMuVFByb3AgPSBleHBvcnRzLlRPcHRpb25hbCA9IGV4cG9ydHMub3B0ID0gZXhwb3J0cy5USWZhY2UgPSBleHBvcnRzLmlmYWNlID0gZXhwb3J0cy5pbmRleEtleSA9IGV4cG9ydHMuVEVudW1MaXRlcmFsID0gZXhwb3J0cy5lbnVtbGl0ID0gZXhwb3J0cy5URW51bVR5cGUgPSBleHBvcnRzLmVudW10eXBlID0gZXhwb3J0cy5USW50ZXJzZWN0aW9uID0gZXhwb3J0cy5pbnRlcnNlY3Rpb24gPSBleHBvcnRzLlRVbmlvbiA9IGV4cG9ydHMudW5pb24gPSBleHBvcnRzLlRUdXBsZSA9IGV4cG9ydHMudHVwbGUgPSBleHBvcnRzLlJlc3RUeXBlID0gZXhwb3J0cy5yZXN0ID0gZXhwb3J0cy5UQXJyYXkgPSBleHBvcnRzLmFycmF5ID0gZXhwb3J0cy5UTGl0ZXJhbCA9IGV4cG9ydHMubGl0ID0gZXhwb3J0cy5UTmFtZSA9IGV4cG9ydHMubmFtZSA9IGV4cG9ydHMuVFR5cGUgPSB2b2lkIDA7XG52YXIgdXRpbF8xID0gcmVxdWlyZShcIi4vdXRpbFwiKTtcbi8qKiBOb2RlIHRoYXQgcmVwcmVzZW50cyBhIHR5cGUuICovXG52YXIgVFR5cGUgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gVFR5cGUoKSB7XG4gICAgfVxuICAgIHJldHVybiBUVHlwZTtcbn0oKSk7XG5leHBvcnRzLlRUeXBlID0gVFR5cGU7XG4vKiogUGFyc2VzIGEgdHlwZSBzcGVjIGludG8gYSBUVHlwZSBub2RlLiAqL1xuZnVuY3Rpb24gcGFyc2VTcGVjKHR5cGVTcGVjKSB7XG4gICAgcmV0dXJuIHR5cGVvZiB0eXBlU3BlYyA9PT0gXCJzdHJpbmdcIiA/IG5hbWUodHlwZVNwZWMpIDogdHlwZVNwZWM7XG59XG5mdW5jdGlvbiBnZXROYW1lZFR5cGUoc3VpdGUsIG5hbWUpIHtcbiAgICB2YXIgdHR5cGUgPSBzdWl0ZVtuYW1lXTtcbiAgICBpZiAoIXR0eXBlKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gdHlwZSBcIiArIG5hbWUpO1xuICAgIH1cbiAgICByZXR1cm4gdHR5cGU7XG59XG4vKipcbiAqIERlZmluZXMgYSB0eXBlIG5hbWUsIGVpdGhlciBidWlsdC1pbiwgb3IgZGVmaW5lZCBpbiB0aGlzIHN1aXRlLiBJdCBjYW4gdHlwaWNhbGx5IGJlIGluY2x1ZGVkIGluXG4gKiB0aGUgc3BlY3MgYXMganVzdCBhIHBsYWluIHN0cmluZy5cbiAqL1xuZnVuY3Rpb24gbmFtZSh2YWx1ZSkgeyByZXR1cm4gbmV3IFROYW1lKHZhbHVlKTsgfVxuZXhwb3J0cy5uYW1lID0gbmFtZTtcbnZhciBUTmFtZSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICBfX2V4dGVuZHMoVE5hbWUsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gVE5hbWUobmFtZSkge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy5uYW1lID0gbmFtZTtcbiAgICAgICAgX3RoaXMuX2ZhaWxNc2cgPSBcImlzIG5vdCBhIFwiICsgbmFtZTtcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICBUTmFtZS5wcm90b3R5cGUuZ2V0Q2hlY2tlciA9IGZ1bmN0aW9uIChzdWl0ZSwgc3RyaWN0LCBhbGxvd2VkUHJvcHMpIHtcbiAgICAgICAgLy8gVXNpbmcgbmFtZXMsIHdlIGNhbiByZWZlcmVuY2UgYSB0eXBlIHJlY3Vyc2l2ZWx5IGluIGl0cyBvd24gZGVmaW5pdGlvbi4gVG8gYXZvaWQgYW5cbiAgICAgICAgLy8gaW5maW5pdGUgcmVjdXJzaW9uIGluIGdldENoZWNrZXIoKSBjYWxscywgd2UgY2FjaGUgYW5kIHJldXNlIHRoZSBjaGVja2VyIHRoYXQncyBiZWluZyBidWlsdFxuICAgICAgICAvLyB3aGVuIGl0IHJlZmVyZW5jZXMgaXRzIG93biBUTmFtZSBub2RlLiBOb3RlIHRoYXQgaXQncyBpbXBvcnRhbnQgdG8gcmV1c2UgdGhlIHJlc3VsdCBvbmx5XG4gICAgICAgIC8vIHdoZW4gZ2V0Q2hlY2tlcigpIGlzIGNhbGxlZCB3aXRoIHRoZSBzYW1lIGFyZ3VtZW50cywgYnV0IHRoYXQncyBhbHJlYWR5IGd1YXJhbnRlZWQgYmVjYXVzZVxuICAgICAgICAvLyB3ZSBhcmUgY2FjaGluZyBvbmx5IGZvciB0aGUgY3VycmVudCBjYWxsIGFuZCBvbmx5IGZvciB0aGUgc2FtZSBUTmFtZSBvYmplY3QgKG5vdCBhbm90aGVyXG4gICAgICAgIC8vIGluc3RhbmNlIG9mIG5hbWUoKSBjYWxsIGZvciB0aGUgc2FtZSBuYW1lKS5cbiAgICAgICAgLy9cbiAgICAgICAgLy8gTm90ZSBhbHNvIHRoYXQgdGhpcyBpcyBhYm91dCBoYW5kbGluZyByZWN1cnNpdmUgdHlwZXM7IGl0IGRvZXMgTk9UIGhlbHAgdmFsaWRhdGluZyBkYXRhXG4gICAgICAgIC8vIHdpdGggY2lyY3VsYXIgcmVmZXJlbmNlcy5cbiAgICAgICAgdmFyIGNoZWNrZXJGdW5jID0gdGhpcy5fY2hlY2tlckJlaW5nQnVpbHQ7XG4gICAgICAgIGlmICghY2hlY2tlckZ1bmMpIHtcbiAgICAgICAgICAgIHRoaXMuX2NoZWNrZXJCZWluZ0J1aWx0ID0gZnVuY3Rpb24gKHZhbHVlLCBjdHgpIHsgcmV0dXJuIGNoZWNrZXJGdW5jKHZhbHVlLCBjdHgpOyB9O1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBjaGVja2VyRnVuYyA9IHRoaXMuX2dldENoZWNrZXIoc3VpdGUsIHN0cmljdCwgYWxsb3dlZFByb3BzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZpbmFsbHkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2NoZWNrZXJCZWluZ0J1aWx0ID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjaGVja2VyRnVuYztcbiAgICB9O1xuICAgIFROYW1lLnByb3RvdHlwZS5fZ2V0Q2hlY2tlciA9IGZ1bmN0aW9uIChzdWl0ZSwgc3RyaWN0LCBhbGxvd2VkUHJvcHMpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIHR0eXBlID0gZ2V0TmFtZWRUeXBlKHN1aXRlLCB0aGlzLm5hbWUpO1xuICAgICAgICB2YXIgY2hlY2tlciA9IHR0eXBlLmdldENoZWNrZXIoc3VpdGUsIHN0cmljdCwgYWxsb3dlZFByb3BzKTtcbiAgICAgICAgaWYgKHR0eXBlIGluc3RhbmNlb2YgQmFzaWNUeXBlIHx8IHR0eXBlIGluc3RhbmNlb2YgVE5hbWUpIHtcbiAgICAgICAgICAgIHJldHVybiBjaGVja2VyO1xuICAgICAgICB9XG4gICAgICAgIC8vIEZvciBjb21wbGV4IHR5cGVzLCBhZGQgYW4gYWRkaXRpb25hbCBcImlzIG5vdCBhIDxUeXBlPlwiIG1lc3NhZ2Ugb24gZmFpbHVyZS5cbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICh2YWx1ZSwgY3R4KSB7IHJldHVybiBjaGVja2VyKHZhbHVlLCBjdHgpID8gdHJ1ZSA6IGN0eC5mYWlsKG51bGwsIF90aGlzLl9mYWlsTXNnLCAwKTsgfTtcbiAgICB9O1xuICAgIHJldHVybiBUTmFtZTtcbn0oVFR5cGUpKTtcbmV4cG9ydHMuVE5hbWUgPSBUTmFtZTtcbi8qKlxuICogRGVmaW5lcyBhIGxpdGVyYWwgdmFsdWUsIGUuZy4gbGl0KCdoZWxsbycpIG9yIGxpdCgxMjMpLlxuICovXG5mdW5jdGlvbiBsaXQodmFsdWUpIHsgcmV0dXJuIG5ldyBUTGl0ZXJhbCh2YWx1ZSk7IH1cbmV4cG9ydHMubGl0ID0gbGl0O1xudmFyIFRMaXRlcmFsID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIF9fZXh0ZW5kcyhUTGl0ZXJhbCwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBUTGl0ZXJhbCh2YWx1ZSkge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy52YWx1ZSA9IHZhbHVlO1xuICAgICAgICBfdGhpcy5uYW1lID0gSlNPTi5zdHJpbmdpZnkodmFsdWUpO1xuICAgICAgICBfdGhpcy5fZmFpbE1zZyA9IFwiaXMgbm90IFwiICsgX3RoaXMubmFtZTtcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICBUTGl0ZXJhbC5wcm90b3R5cGUuZ2V0Q2hlY2tlciA9IGZ1bmN0aW9uIChzdWl0ZSwgc3RyaWN0KSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAodmFsdWUsIGN0eCkgeyByZXR1cm4gKHZhbHVlID09PSBfdGhpcy52YWx1ZSkgPyB0cnVlIDogY3R4LmZhaWwobnVsbCwgX3RoaXMuX2ZhaWxNc2csIC0xKTsgfTtcbiAgICB9O1xuICAgIHJldHVybiBUTGl0ZXJhbDtcbn0oVFR5cGUpKTtcbmV4cG9ydHMuVExpdGVyYWwgPSBUTGl0ZXJhbDtcbi8qKlxuICogRGVmaW5lcyBhbiBhcnJheSB0eXBlLCBlLmcuIGFycmF5KCdudW1iZXInKS5cbiAqL1xuZnVuY3Rpb24gYXJyYXkodHlwZVNwZWMpIHsgcmV0dXJuIG5ldyBUQXJyYXkocGFyc2VTcGVjKHR5cGVTcGVjKSk7IH1cbmV4cG9ydHMuYXJyYXkgPSBhcnJheTtcbnZhciBUQXJyYXkgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgX19leHRlbmRzKFRBcnJheSwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBUQXJyYXkodHR5cGUpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMudHR5cGUgPSB0dHlwZTtcbiAgICAgICAgdmFyIGVsZW1lbnRUeXBlTmFtZSA9IGdldFR5cGVOYW1lKHR0eXBlKTtcbiAgICAgICAgaWYgKGVsZW1lbnRUeXBlTmFtZSkge1xuICAgICAgICAgICAgX3RoaXMubmFtZSA9IGVsZW1lbnRUeXBlTmFtZSArIFwiW11cIjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIFRBcnJheS5wcm90b3R5cGUuZ2V0Q2hlY2tlciA9IGZ1bmN0aW9uIChzdWl0ZSwgc3RyaWN0KSB7XG4gICAgICAgIHZhciBpdGVtQ2hlY2tlciA9IHRoaXMudHR5cGUuZ2V0Q2hlY2tlcihzdWl0ZSwgc3RyaWN0KTtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICh2YWx1ZSwgY3R4KSB7XG4gICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGN0eC5mYWlsKG51bGwsIFwiaXMgbm90IGFuIGFycmF5XCIsIDApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB2YWx1ZS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIHZhciBvayA9IGl0ZW1DaGVja2VyKHZhbHVlW2ldLCBjdHgpO1xuICAgICAgICAgICAgICAgIGlmICghb2spIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGN0eC5mYWlsKGksIG51bGwsIDEpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9O1xuICAgIH07XG4gICAgcmV0dXJuIFRBcnJheTtcbn0oVFR5cGUpKTtcbmV4cG9ydHMuVEFycmF5ID0gVEFycmF5O1xuLyoqXG4gKiBEZWZpbmVzIGEgcmVzdCB0eXBlLCBlLmcuIHR1cGxlKCdzdHJpbmcnLCByZXN0KGFycmF5KCdudW1iZXInKSkpLlxuICovXG5mdW5jdGlvbiByZXN0KHR5cGVTcGVjKSB7XG4gICAgcmV0dXJuIG5ldyBSZXN0VHlwZSh0eXBlU3BlYyk7XG59XG5leHBvcnRzLnJlc3QgPSByZXN0O1xudmFyIFJlc3RUeXBlID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIF9fZXh0ZW5kcyhSZXN0VHlwZSwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBSZXN0VHlwZSh0eXBlU3BlYykge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy50eXBlU3BlYyA9IHR5cGVTcGVjO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIFJlc3RUeXBlLnByb3RvdHlwZS5zZXRTdGFydCA9IGZ1bmN0aW9uIChzdGFydCkge1xuICAgICAgICB0aGlzLl9zdGFydCA9IHN0YXJ0O1xuICAgIH07XG4gICAgUmVzdFR5cGUucHJvdG90eXBlLmdldENoZWNrZXIgPSBmdW5jdGlvbiAoc3VpdGUsIHN0cmljdCkge1xuICAgICAgICB2YXIgYXJyVHlwZSA9IHR5cGVvZiB0aGlzLnR5cGVTcGVjID09PSBcInN0cmluZ1wiID8gZ2V0TmFtZWRUeXBlKHN1aXRlLCB0aGlzLnR5cGVTcGVjKSA6IHRoaXMudHlwZVNwZWM7XG4gICAgICAgIGlmICghKGFyclR5cGUgaW5zdGFuY2VvZiBUQXJyYXkpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJSZXN0IHR5cGUgbXVzdCBiZSBhbiBhcnJheVwiKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgaXRlbUNoZWNrZXIgPSBhcnJUeXBlLnR0eXBlLmdldENoZWNrZXIoc3VpdGUsIHN0cmljdCk7XG4gICAgICAgIHZhciBzdGFydCA9IHRoaXMuX3N0YXJ0O1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKHZhbHVlLCBjdHgpIHtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IHZhbHVlLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFpdGVtQ2hlY2tlcih2YWx1ZVtpXSwgY3R4KSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY3R4LmZhaWwoaSwgbnVsbCwgMSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH07XG4gICAgfTtcbiAgICByZXR1cm4gUmVzdFR5cGU7XG59KFRUeXBlKSk7XG5leHBvcnRzLlJlc3RUeXBlID0gUmVzdFR5cGU7XG4vKipcbiAqIERlZmluZXMgYSB0dXBsZSB0eXBlLCBlLmcuIHR1cGxlKCdzdHJpbmcnLCAnbnVtYmVyJykuXG4gKi9cbmZ1bmN0aW9uIHR1cGxlKCkge1xuICAgIHZhciB0eXBlU3BlYyA9IFtdO1xuICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCBhcmd1bWVudHMubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgIHR5cGVTcGVjW19pXSA9IGFyZ3VtZW50c1tfaV07XG4gICAgfVxuICAgIHJldHVybiBuZXcgVFR1cGxlKHR5cGVTcGVjLm1hcChmdW5jdGlvbiAodCkgeyByZXR1cm4gcGFyc2VTcGVjKHQpOyB9KSk7XG59XG5leHBvcnRzLnR1cGxlID0gdHVwbGU7XG52YXIgVFR1cGxlID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIF9fZXh0ZW5kcyhUVHVwbGUsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gVFR1cGxlKHR0eXBlcykge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy50dHlwZXMgPSB0dHlwZXM7XG4gICAgICAgIHZhciBsYXN0ID0gdHR5cGVzW3R0eXBlcy5sZW5ndGggLSAxXTtcbiAgICAgICAgaWYgKGxhc3QgaW5zdGFuY2VvZiBSZXN0VHlwZSkge1xuICAgICAgICAgICAgdHR5cGVzLnBvcCgpO1xuICAgICAgICAgICAgX3RoaXMuX3Jlc3RUeXBlID0gbGFzdDtcbiAgICAgICAgICAgIF90aGlzLl9yZXN0VHlwZS5zZXRTdGFydCh0dHlwZXMubGVuZ3RoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIFRUdXBsZS5wcm90b3R5cGUuZ2V0Q2hlY2tlciA9IGZ1bmN0aW9uIChzdWl0ZSwgc3RyaWN0KSB7XG4gICAgICAgIHZhciBpdGVtQ2hlY2tlcnMgPSB0aGlzLnR0eXBlcy5tYXAoZnVuY3Rpb24gKHQpIHsgcmV0dXJuIHQuZ2V0Q2hlY2tlcihzdWl0ZSwgc3RyaWN0KTsgfSk7XG4gICAgICAgIHZhciBjaGVja2VyID0gZnVuY3Rpb24gKHZhbHVlLCBjdHgpIHtcbiAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gY3R4LmZhaWwobnVsbCwgXCJpcyBub3QgYW4gYXJyYXlcIiwgMCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGl0ZW1DaGVja2Vycy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIHZhciBvayA9IGl0ZW1DaGVja2Vyc1tpXSh2YWx1ZVtpXSwgY3R4KTtcbiAgICAgICAgICAgICAgICBpZiAoIW9rKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjdHguZmFpbChpLCBudWxsLCAxKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfTtcbiAgICAgICAgaWYgKHRoaXMuX3Jlc3RUeXBlKSB7XG4gICAgICAgICAgICB2YXIgcmVzdENoZWNrZXJfMSA9IHRoaXMuX3Jlc3RUeXBlLmdldENoZWNrZXIoc3VpdGUsIHN0cmljdCk7XG4gICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKHZhbHVlLCBjdHgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gY2hlY2tlcih2YWx1ZSwgY3R4KSAmJiByZXN0Q2hlY2tlcl8xKHZhbHVlLCBjdHgpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXN0cmljdCkge1xuICAgICAgICAgICAgcmV0dXJuIGNoZWNrZXI7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICh2YWx1ZSwgY3R4KSB7XG4gICAgICAgICAgICBpZiAoIWNoZWNrZXIodmFsdWUsIGN0eCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdmFsdWUubGVuZ3RoIDw9IGl0ZW1DaGVja2Vycy5sZW5ndGggPyB0cnVlIDpcbiAgICAgICAgICAgICAgICBjdHguZmFpbChpdGVtQ2hlY2tlcnMubGVuZ3RoLCBcImlzIGV4dHJhbmVvdXNcIiwgMik7XG4gICAgICAgIH07XG4gICAgfTtcbiAgICByZXR1cm4gVFR1cGxlO1xufShUVHlwZSkpO1xuZXhwb3J0cy5UVHVwbGUgPSBUVHVwbGU7XG4vKipcbiAqIERlZmluZXMgYSB1bmlvbiB0eXBlLCBlLmcuIHVuaW9uKCdudW1iZXInLCAnbnVsbCcpLlxuICovXG5mdW5jdGlvbiB1bmlvbigpIHtcbiAgICB2YXIgdHlwZVNwZWMgPSBbXTtcbiAgICBmb3IgKHZhciBfaSA9IDA7IF9pIDwgYXJndW1lbnRzLmxlbmd0aDsgX2krKykge1xuICAgICAgICB0eXBlU3BlY1tfaV0gPSBhcmd1bWVudHNbX2ldO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IFRVbmlvbih0eXBlU3BlYy5tYXAoZnVuY3Rpb24gKHQpIHsgcmV0dXJuIHBhcnNlU3BlYyh0KTsgfSkpO1xufVxuZXhwb3J0cy51bmlvbiA9IHVuaW9uO1xudmFyIFRVbmlvbiA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICBfX2V4dGVuZHMoVFVuaW9uLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFRVbmlvbih0dHlwZXMpIHtcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcykgfHwgdGhpcztcbiAgICAgICAgX3RoaXMudHR5cGVzID0gdHR5cGVzO1xuICAgICAgICB2YXIgbmFtZXMgPSB0dHlwZXMubWFwKGdldFR5cGVOYW1lKVxuICAgICAgICAgICAgLmZpbHRlcihmdW5jdGlvbiAobikgeyByZXR1cm4gbjsgfSk7XG4gICAgICAgIHZhciBvdGhlclR5cGVzID0gdHR5cGVzLmxlbmd0aCAtIG5hbWVzLmxlbmd0aDtcbiAgICAgICAgaWYgKG5hbWVzLmxlbmd0aCkge1xuICAgICAgICAgICAgaWYgKG90aGVyVHlwZXMgPiAwKSB7XG4gICAgICAgICAgICAgICAgbmFtZXMucHVzaChvdGhlclR5cGVzICsgXCIgbW9yZVwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIF90aGlzLl9mYWlsTXNnID0gXCJpcyBub25lIG9mIFwiICsgbmFtZXMuam9pbihcIiwgXCIpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgX3RoaXMuX2ZhaWxNc2cgPSBcImlzIG5vbmUgb2YgXCIgKyBvdGhlclR5cGVzICsgXCIgdHlwZXNcIjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIFRVbmlvbi5wcm90b3R5cGUuZ2V0Q2hlY2tlciA9IGZ1bmN0aW9uIChzdWl0ZSwgc3RyaWN0LCBhbGxvd2VkUHJvcHMpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIGl0ZW1DaGVja2VycyA9IHRoaXMudHR5cGVzLm1hcChmdW5jdGlvbiAodCkgeyByZXR1cm4gdC5nZXRDaGVja2VyKHN1aXRlLCBzdHJpY3QsIGFsbG93ZWRQcm9wcyk7IH0pO1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKHZhbHVlLCBjdHgpIHtcbiAgICAgICAgICAgIHZhciB1ciA9IGN0eC51bmlvblJlc29sdmVyKCk7XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGl0ZW1DaGVja2Vycy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIHZhciBvayA9IGl0ZW1DaGVja2Vyc1tpXSh2YWx1ZSwgdXIuY3JlYXRlQ29udGV4dCgpKTtcbiAgICAgICAgICAgICAgICBpZiAob2spIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY3R4LnJlc29sdmVVbmlvbih1cik7XG4gICAgICAgICAgICByZXR1cm4gY3R4LmZhaWwobnVsbCwgX3RoaXMuX2ZhaWxNc2csIDApO1xuICAgICAgICB9O1xuICAgIH07XG4gICAgcmV0dXJuIFRVbmlvbjtcbn0oVFR5cGUpKTtcbmV4cG9ydHMuVFVuaW9uID0gVFVuaW9uO1xuLyoqXG4gKiBEZWZpbmVzIGFuIGludGVyc2VjdGlvbiB0eXBlLCBlLmcuIGludGVyc2VjdGlvbignbnVtYmVyJywgJ251bGwnKS5cbiAqL1xuZnVuY3Rpb24gaW50ZXJzZWN0aW9uKCkge1xuICAgIHZhciB0eXBlU3BlYyA9IFtdO1xuICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCBhcmd1bWVudHMubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgIHR5cGVTcGVjW19pXSA9IGFyZ3VtZW50c1tfaV07XG4gICAgfVxuICAgIHJldHVybiBuZXcgVEludGVyc2VjdGlvbih0eXBlU3BlYy5tYXAoZnVuY3Rpb24gKHQpIHsgcmV0dXJuIHBhcnNlU3BlYyh0KTsgfSkpO1xufVxuZXhwb3J0cy5pbnRlcnNlY3Rpb24gPSBpbnRlcnNlY3Rpb247XG52YXIgVEludGVyc2VjdGlvbiA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICBfX2V4dGVuZHMoVEludGVyc2VjdGlvbiwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBUSW50ZXJzZWN0aW9uKHR0eXBlcykge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy50dHlwZXMgPSB0dHlwZXM7XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgVEludGVyc2VjdGlvbi5wcm90b3R5cGUuZ2V0Q2hlY2tlciA9IGZ1bmN0aW9uIChzdWl0ZSwgc3RyaWN0LCBhbGxvd2VkUHJvcHMpIHtcbiAgICAgICAgaWYgKGFsbG93ZWRQcm9wcyA9PT0gdm9pZCAwKSB7IGFsbG93ZWRQcm9wcyA9IG5ldyBTZXQoKTsgfVxuICAgICAgICB2YXIgaXRlbUNoZWNrZXJzID0gdGhpcy50dHlwZXMubWFwKGZ1bmN0aW9uICh0KSB7IHJldHVybiB0LmdldENoZWNrZXIoc3VpdGUsIHN0cmljdCwgYWxsb3dlZFByb3BzKTsgfSk7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAodmFsdWUsIGN0eCkge1xuICAgICAgICAgICAgcmV0dXJuIGl0ZW1DaGVja2Vycy5ldmVyeShmdW5jdGlvbiAoY2hlY2tlcikge1xuICAgICAgICAgICAgICAgIGNoZWNrZXIodmFsdWUsIGN0eC5mb3JrKCkpO1xuICAgICAgICAgICAgICAgIHJldHVybiBjdHguY29tcGxldGVGb3JrKCk7XG4gICAgICAgICAgICB9KSAmJiAhY3R4LmZhaWxlZCgpO1xuICAgICAgICB9O1xuICAgIH07XG4gICAgcmV0dXJuIFRJbnRlcnNlY3Rpb247XG59KFRUeXBlKSk7XG5leHBvcnRzLlRJbnRlcnNlY3Rpb24gPSBUSW50ZXJzZWN0aW9uO1xuLyoqXG4gKiBEZWZpbmVzIGFuIGVudW0gdHlwZSwgZS5nLiBlbnVtKHsnQSc6IDEsICdCJzogMn0pLlxuICovXG5mdW5jdGlvbiBlbnVtdHlwZSh2YWx1ZXMpIHtcbiAgICByZXR1cm4gbmV3IFRFbnVtVHlwZSh2YWx1ZXMpO1xufVxuZXhwb3J0cy5lbnVtdHlwZSA9IGVudW10eXBlO1xudmFyIFRFbnVtVHlwZSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICBfX2V4dGVuZHMoVEVudW1UeXBlLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFRFbnVtVHlwZShtZW1iZXJzKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLm1lbWJlcnMgPSBtZW1iZXJzO1xuICAgICAgICBfdGhpcy52YWxpZFZhbHVlcyA9IG5ldyBTZXQoKTtcbiAgICAgICAgX3RoaXMuX2ZhaWxNc2cgPSBcImlzIG5vdCBhIHZhbGlkIGVudW0gdmFsdWVcIjtcbiAgICAgICAgX3RoaXMudmFsaWRWYWx1ZXMgPSBuZXcgU2V0KE9iamVjdC5rZXlzKG1lbWJlcnMpLm1hcChmdW5jdGlvbiAobmFtZSkgeyByZXR1cm4gbWVtYmVyc1tuYW1lXTsgfSkpO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIFRFbnVtVHlwZS5wcm90b3R5cGUuZ2V0Q2hlY2tlciA9IGZ1bmN0aW9uIChzdWl0ZSwgc3RyaWN0KSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAodmFsdWUsIGN0eCkge1xuICAgICAgICAgICAgcmV0dXJuIChfdGhpcy52YWxpZFZhbHVlcy5oYXModmFsdWUpID8gdHJ1ZSA6IGN0eC5mYWlsKG51bGwsIF90aGlzLl9mYWlsTXNnLCAwKSk7XG4gICAgICAgIH07XG4gICAgfTtcbiAgICByZXR1cm4gVEVudW1UeXBlO1xufShUVHlwZSkpO1xuZXhwb3J0cy5URW51bVR5cGUgPSBURW51bVR5cGU7XG4vKipcbiAqIERlZmluZXMgYSBsaXRlcmFsIGVudW0gdmFsdWUsIHN1Y2ggYXMgRGlyZWN0aW9uLlVwLCBzcGVjaWZpZWQgYXMgZW51bWxpdChcIkRpcmVjdGlvblwiLCBcIlVwXCIpLlxuICovXG5mdW5jdGlvbiBlbnVtbGl0KG5hbWUsIHByb3ApIHtcbiAgICByZXR1cm4gbmV3IFRFbnVtTGl0ZXJhbChuYW1lLCBwcm9wKTtcbn1cbmV4cG9ydHMuZW51bWxpdCA9IGVudW1saXQ7XG52YXIgVEVudW1MaXRlcmFsID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIF9fZXh0ZW5kcyhURW51bUxpdGVyYWwsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gVEVudW1MaXRlcmFsKGVudW1OYW1lLCBwcm9wKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLmVudW1OYW1lID0gZW51bU5hbWU7XG4gICAgICAgIF90aGlzLnByb3AgPSBwcm9wO1xuICAgICAgICBfdGhpcy5fZmFpbE1zZyA9IFwiaXMgbm90IFwiICsgZW51bU5hbWUgKyBcIi5cIiArIHByb3A7XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgVEVudW1MaXRlcmFsLnByb3RvdHlwZS5nZXRDaGVja2VyID0gZnVuY3Rpb24gKHN1aXRlLCBzdHJpY3QpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIHR0eXBlID0gZ2V0TmFtZWRUeXBlKHN1aXRlLCB0aGlzLmVudW1OYW1lKTtcbiAgICAgICAgaWYgKCEodHR5cGUgaW5zdGFuY2VvZiBURW51bVR5cGUpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUeXBlIFwiICsgdGhpcy5lbnVtTmFtZSArIFwiIHVzZWQgaW4gZW51bWxpdCBpcyBub3QgYW4gZW51bSB0eXBlXCIpO1xuICAgICAgICB9XG4gICAgICAgIHZhciB2YWwgPSB0dHlwZS5tZW1iZXJzW3RoaXMucHJvcF07XG4gICAgICAgIGlmICghdHR5cGUubWVtYmVycy5oYXNPd25Qcm9wZXJ0eSh0aGlzLnByb3ApKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIHZhbHVlIFwiICsgdGhpcy5lbnVtTmFtZSArIFwiLlwiICsgdGhpcy5wcm9wICsgXCIgdXNlZCBpbiBlbnVtbGl0XCIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAodmFsdWUsIGN0eCkgeyByZXR1cm4gKHZhbHVlID09PSB2YWwpID8gdHJ1ZSA6IGN0eC5mYWlsKG51bGwsIF90aGlzLl9mYWlsTXNnLCAtMSk7IH07XG4gICAgfTtcbiAgICByZXR1cm4gVEVudW1MaXRlcmFsO1xufShUVHlwZSkpO1xuZXhwb3J0cy5URW51bUxpdGVyYWwgPSBURW51bUxpdGVyYWw7XG5mdW5jdGlvbiBtYWtlSWZhY2VQcm9wcyhwcm9wcykge1xuICAgIHJldHVybiBPYmplY3Qua2V5cyhwcm9wcylcbiAgICAgICAgLmZpbHRlcihmdW5jdGlvbiAobmFtZSkgeyByZXR1cm4gKG5hbWUgIT09IGV4cG9ydHMuaW5kZXhLZXkpOyB9KVxuICAgICAgICAubWFwKGZ1bmN0aW9uIChuYW1lKSB7IHJldHVybiBtYWtlSWZhY2VQcm9wKG5hbWUsIHByb3BzW25hbWVdKTsgfSk7XG59XG5mdW5jdGlvbiBtYWtlSWZhY2VQcm9wKG5hbWUsIHByb3ApIHtcbiAgICByZXR1cm4gcHJvcCBpbnN0YW5jZW9mIFRPcHRpb25hbCA/XG4gICAgICAgIG5ldyBUUHJvcChuYW1lLCBwcm9wLnR0eXBlLCB0cnVlKSA6XG4gICAgICAgIG5ldyBUUHJvcChuYW1lLCBwYXJzZVNwZWMocHJvcCksIGZhbHNlKTtcbn1cbi8qKlxuICogaW5kZXhLZXkgaXMgYSBzcGVjaWFsIGtleSB0aGF0IGluZGljYXRlcyBhbiBpbmRleCBzaWduYXR1cmUgd2hlbiB1c2VkIGFzIGEga2V5IGluIGFuIGludGVyZmFjZS5cbiAqIEUuZy4ge1trZXk6IHN0cmluZ106IG51bWJlcn0gYmVjb21lcyB0LmlmYWNlKFtdLCB7W3QuaW5kZXhLZXldOiBcIm51bWJlclwifSkuXG4gKlxuICogV2UgZG9uJ3QgZGlzdGluZ3Vpc2ggYmV0d2VlbiBzdHJpbmctIGFuZCBudW1iZXItdHlwZSBpbmRleCBzaWduYXR1cmVzLCBhbmQgZG9uJ3Qgc3VwcG9ydFxuICogbXVsdGlwbGUgaW5kZXggc2lnbmF0dXJlcy5cbiAqL1xuZXhwb3J0cy5pbmRleEtleSA9IFN5bWJvbCgpO1xuLyoqXG4gKiBEZWZpbmVzIGFuIGludGVyZmFjZS4gVGhlIGZpcnN0IGFyZ3VtZW50IGlzIGFuIGFycmF5IG9mIGludGVyZmFjZXMgdGhhdCBpdCBleHRlbmRzLCBhbmQgdGhlXG4gKiBzZWNvbmQgaXMgYW4gYXJyYXkgb2YgcHJvcGVydGllcy5cbiAqL1xuZnVuY3Rpb24gaWZhY2UoYmFzZXMsIHByb3BzKSB7XG4gICAgcmV0dXJuIG5ldyBUSWZhY2UoYmFzZXMsIG1ha2VJZmFjZVByb3BzKHByb3BzKSwgcHJvcHNbZXhwb3J0cy5pbmRleEtleV0pO1xufVxuZXhwb3J0cy5pZmFjZSA9IGlmYWNlO1xudmFyIFRJZmFjZSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICBfX2V4dGVuZHMoVElmYWNlLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFRJZmFjZShiYXNlcywgcHJvcHMsIGluZGV4VHlwZSkge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy5iYXNlcyA9IGJhc2VzO1xuICAgICAgICBfdGhpcy5wcm9wcyA9IHByb3BzO1xuICAgICAgICBfdGhpcy5pbmRleFR5cGUgPSBpbmRleFR5cGUgPyBwYXJzZVNwZWMoaW5kZXhUeXBlKSA6IHVuZGVmaW5lZDtcbiAgICAgICAgX3RoaXMucHJvcFNldCA9IG5ldyBTZXQocHJvcHMubWFwKGZ1bmN0aW9uIChwKSB7IHJldHVybiBwLm5hbWU7IH0pKTtcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICBUSWZhY2UucHJvdG90eXBlLmdldENoZWNrZXIgPSBmdW5jdGlvbiAoc3VpdGUsIHN0cmljdCwgYWxsb3dlZFByb3BzKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciBfYTtcbiAgICAgICAgaWYgKGFsbG93ZWRQcm9wcyA9PT0gdm9pZCAwKSB7IGFsbG93ZWRQcm9wcyA9IG5ldyBTZXQoKTsgfVxuICAgICAgICB0aGlzLnByb3BTZXQuZm9yRWFjaChmdW5jdGlvbiAocHJvcCkgeyByZXR1cm4gYWxsb3dlZFByb3BzLmFkZChwcm9wKTsgfSk7XG4gICAgICAgIHZhciBiYXNlQ2hlY2tlcnMgPSB0aGlzLmJhc2VzLm1hcChmdW5jdGlvbiAoYikgeyByZXR1cm4gZ2V0TmFtZWRUeXBlKHN1aXRlLCBiKS5nZXRDaGVja2VyKHN1aXRlLCBzdHJpY3QsIGFsbG93ZWRQcm9wcyk7IH0pO1xuICAgICAgICB2YXIgcHJvcENoZWNrZXJzID0gdGhpcy5wcm9wcy5tYXAoZnVuY3Rpb24gKHByb3ApIHsgcmV0dXJuIHByb3AudHR5cGUuZ2V0Q2hlY2tlcihzdWl0ZSwgc3RyaWN0KTsgfSk7XG4gICAgICAgIHZhciBpbmRleFR5cGVDaGVja2VyID0gKF9hID0gdGhpcy5pbmRleFR5cGUpID09PSBudWxsIHx8IF9hID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYS5nZXRDaGVja2VyKHN1aXRlLCBzdHJpY3QpO1xuICAgICAgICB2YXIgdGVzdEN0eCA9IG5ldyB1dGlsXzEuTm9vcENvbnRleHQoKTtcbiAgICAgICAgLy8gQ29uc2lkZXIgYSBwcm9wIHJlcXVpcmVkIGlmIGl0J3Mgbm90IG9wdGlvbmFsIEFORCBkb2VzIG5vdCBhbGxvdyBmb3IgdW5kZWZpbmVkIGFzIGEgdmFsdWUuXG4gICAgICAgIHZhciBpc1Byb3BSZXF1aXJlZCA9IHRoaXMucHJvcHMubWFwKGZ1bmN0aW9uIChwcm9wLCBpKSB7XG4gICAgICAgICAgICByZXR1cm4gIXByb3AuaXNPcHQgJiYgIXByb3BDaGVja2Vyc1tpXSh1bmRlZmluZWQsIHRlc3RDdHgpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICh2YWx1ZSwgY3R4KSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSBcIm9iamVjdFwiIHx8IHZhbHVlID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGN0eC5mYWlsKG51bGwsIFwiaXMgbm90IGFuIG9iamVjdFwiLCAwKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYmFzZUNoZWNrZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgYmFzZUNoZWNrZXJzW2ldKHZhbHVlLCBjdHguZm9yaygpKTtcbiAgICAgICAgICAgICAgICBpZiAoIWN0eC5jb21wbGV0ZUZvcmsoKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wQ2hlY2tlcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICB2YXIgbmFtZV8xID0gX3RoaXMucHJvcHNbaV0ubmFtZTtcbiAgICAgICAgICAgICAgICB2YXIgdiA9IHZhbHVlW25hbWVfMV07XG4gICAgICAgICAgICAgICAgaWYgKHYgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNQcm9wUmVxdWlyZWRbaV0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGN0eC5mb3JrKCkuZmFpbChuYW1lXzEsIFwiaXMgbWlzc2luZ1wiLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghY3R4LmNvbXBsZXRlRm9yaygpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB2YXIgZm9yayA9IGN0eC5mb3JrKCk7XG4gICAgICAgICAgICAgICAgICAgIHZhciBvayA9IHByb3BDaGVja2Vyc1tpXSh2LCBmb3JrKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFvaykge1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9yay5mYWlsKG5hbWVfMSwgbnVsbCwgMSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKCFjdHguY29tcGxldGVGb3JrKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChpbmRleFR5cGVDaGVja2VyKSB7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgcHJvcCBpbiB2YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgZm9yayA9IGN0eC5mb3JrKCk7XG4gICAgICAgICAgICAgICAgICAgIGlmICghaW5kZXhUeXBlQ2hlY2tlcih2YWx1ZVtwcm9wXSwgZm9yaykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvcmsuZmFpbChwcm9wLCBudWxsLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoIWN0eC5jb21wbGV0ZUZvcmsoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoc3RyaWN0KSB7XG4gICAgICAgICAgICAgICAgLy8gSW4gc3RyaWN0IG1vZGUsIGNoZWNrIGFsc28gZm9yIHVua25vd24gZW51bWVyYWJsZSBwcm9wZXJ0aWVzLlxuICAgICAgICAgICAgICAgIGZvciAodmFyIHByb3AgaW4gdmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFhbGxvd2VkUHJvcHMuaGFzKHByb3ApKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjdHguZm9yaygpLmZhaWwocHJvcCwgXCJpcyBleHRyYW5lb3VzXCIsIDIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFjdHguY29tcGxldGVGb3JrKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gIWN0eC5mYWlsZWQoKTtcbiAgICAgICAgfTtcbiAgICB9O1xuICAgIHJldHVybiBUSWZhY2U7XG59KFRUeXBlKSk7XG5leHBvcnRzLlRJZmFjZSA9IFRJZmFjZTtcbi8qKlxuICogRGVmaW5lcyBhbiBvcHRpb25hbCBwcm9wZXJ0eSBvbiBhbiBpbnRlcmZhY2UuXG4gKi9cbmZ1bmN0aW9uIG9wdCh0eXBlU3BlYykgeyByZXR1cm4gbmV3IFRPcHRpb25hbChwYXJzZVNwZWModHlwZVNwZWMpKTsgfVxuZXhwb3J0cy5vcHQgPSBvcHQ7XG52YXIgVE9wdGlvbmFsID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIF9fZXh0ZW5kcyhUT3B0aW9uYWwsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gVE9wdGlvbmFsKHR0eXBlKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLnR0eXBlID0gdHR5cGU7XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgVE9wdGlvbmFsLnByb3RvdHlwZS5nZXRDaGVja2VyID0gZnVuY3Rpb24gKHN1aXRlLCBzdHJpY3QpIHtcbiAgICAgICAgdmFyIGl0ZW1DaGVja2VyID0gdGhpcy50dHlwZS5nZXRDaGVja2VyKHN1aXRlLCBzdHJpY3QpO1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKHZhbHVlLCBjdHgpIHtcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZSA9PT0gdW5kZWZpbmVkIHx8IGl0ZW1DaGVja2VyKHZhbHVlLCBjdHgpO1xuICAgICAgICB9O1xuICAgIH07XG4gICAgcmV0dXJuIFRPcHRpb25hbDtcbn0oVFR5cGUpKTtcbmV4cG9ydHMuVE9wdGlvbmFsID0gVE9wdGlvbmFsO1xuLyoqXG4gKiBEZWZpbmVzIGEgcHJvcGVydHkgaW4gYW4gaW50ZXJmYWNlLlxuICovXG52YXIgVFByb3AgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gVFByb3AobmFtZSwgdHR5cGUsIGlzT3B0KSB7XG4gICAgICAgIHRoaXMubmFtZSA9IG5hbWU7XG4gICAgICAgIHRoaXMudHR5cGUgPSB0dHlwZTtcbiAgICAgICAgdGhpcy5pc09wdCA9IGlzT3B0O1xuICAgIH1cbiAgICByZXR1cm4gVFByb3A7XG59KCkpO1xuZXhwb3J0cy5UUHJvcCA9IFRQcm9wO1xuLyoqXG4gKiBEZWZpbmVzIGEgZnVuY3Rpb24uIFRoZSBmaXJzdCBhcmd1bWVudCBkZWNsYXJlcyB0aGUgZnVuY3Rpb24ncyByZXR1cm4gdHlwZSwgdGhlIHJlc3QgZGVjbGFyZVxuICogaXRzIHBhcmFtZXRlcnMuXG4gKi9cbmZ1bmN0aW9uIGZ1bmMocmVzdWx0U3BlYykge1xuICAgIHZhciBwYXJhbXMgPSBbXTtcbiAgICBmb3IgKHZhciBfaSA9IDE7IF9pIDwgYXJndW1lbnRzLmxlbmd0aDsgX2krKykge1xuICAgICAgICBwYXJhbXNbX2kgLSAxXSA9IGFyZ3VtZW50c1tfaV07XG4gICAgfVxuICAgIHJldHVybiBuZXcgVEZ1bmMobmV3IFRQYXJhbUxpc3QocGFyYW1zKSwgcGFyc2VTcGVjKHJlc3VsdFNwZWMpKTtcbn1cbmV4cG9ydHMuZnVuYyA9IGZ1bmM7XG52YXIgVEZ1bmMgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgX19leHRlbmRzKFRGdW5jLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFRGdW5jKHBhcmFtTGlzdCwgcmVzdWx0KSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLnBhcmFtTGlzdCA9IHBhcmFtTGlzdDtcbiAgICAgICAgX3RoaXMucmVzdWx0ID0gcmVzdWx0O1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIFRGdW5jLnByb3RvdHlwZS5nZXRDaGVja2VyID0gZnVuY3Rpb24gKHN1aXRlLCBzdHJpY3QpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICh2YWx1ZSwgY3R4KSB7XG4gICAgICAgICAgICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSBcImZ1bmN0aW9uXCIgPyB0cnVlIDogY3R4LmZhaWwobnVsbCwgXCJpcyBub3QgYSBmdW5jdGlvblwiLCAwKTtcbiAgICAgICAgfTtcbiAgICB9O1xuICAgIHJldHVybiBURnVuYztcbn0oVFR5cGUpKTtcbmV4cG9ydHMuVEZ1bmMgPSBURnVuYztcbi8qKlxuICogRGVmaW5lcyBhIGZ1bmN0aW9uIHBhcmFtZXRlci5cbiAqL1xuZnVuY3Rpb24gcGFyYW0obmFtZSwgdHlwZVNwZWMsIGlzT3B0KSB7XG4gICAgcmV0dXJuIG5ldyBUUGFyYW0obmFtZSwgcGFyc2VTcGVjKHR5cGVTcGVjKSwgQm9vbGVhbihpc09wdCkpO1xufVxuZXhwb3J0cy5wYXJhbSA9IHBhcmFtO1xudmFyIFRQYXJhbSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBUUGFyYW0obmFtZSwgdHR5cGUsIGlzT3B0KSB7XG4gICAgICAgIHRoaXMubmFtZSA9IG5hbWU7XG4gICAgICAgIHRoaXMudHR5cGUgPSB0dHlwZTtcbiAgICAgICAgdGhpcy5pc09wdCA9IGlzT3B0O1xuICAgIH1cbiAgICByZXR1cm4gVFBhcmFtO1xufSgpKTtcbmV4cG9ydHMuVFBhcmFtID0gVFBhcmFtO1xuLyoqXG4gKiBEZWZpbmVzIGEgZnVuY3Rpb24gcGFyYW1ldGVyIGxpc3QuXG4gKi9cbnZhciBUUGFyYW1MaXN0ID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIF9fZXh0ZW5kcyhUUGFyYW1MaXN0LCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIFRQYXJhbUxpc3QocGFyYW1zKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMpIHx8IHRoaXM7XG4gICAgICAgIF90aGlzLnBhcmFtcyA9IHBhcmFtcztcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICBUUGFyYW1MaXN0LnByb3RvdHlwZS5nZXRDaGVja2VyID0gZnVuY3Rpb24gKHN1aXRlLCBzdHJpY3QpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIGl0ZW1DaGVja2VycyA9IHRoaXMucGFyYW1zLm1hcChmdW5jdGlvbiAodCkgeyByZXR1cm4gdC50dHlwZS5nZXRDaGVja2VyKHN1aXRlLCBzdHJpY3QpOyB9KTtcbiAgICAgICAgdmFyIHRlc3RDdHggPSBuZXcgdXRpbF8xLk5vb3BDb250ZXh0KCk7XG4gICAgICAgIHZhciBpc1BhcmFtUmVxdWlyZWQgPSB0aGlzLnBhcmFtcy5tYXAoZnVuY3Rpb24gKHBhcmFtLCBpKSB7XG4gICAgICAgICAgICByZXR1cm4gIXBhcmFtLmlzT3B0ICYmICFpdGVtQ2hlY2tlcnNbaV0odW5kZWZpbmVkLCB0ZXN0Q3R4KTtcbiAgICAgICAgfSk7XG4gICAgICAgIHZhciBjaGVja2VyID0gZnVuY3Rpb24gKHZhbHVlLCBjdHgpIHtcbiAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gY3R4LmZhaWwobnVsbCwgXCJpcyBub3QgYW4gYXJyYXlcIiwgMCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGl0ZW1DaGVja2Vycy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIHZhciBwID0gX3RoaXMucGFyYW1zW2ldO1xuICAgICAgICAgICAgICAgIGlmICh2YWx1ZVtpXSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc1BhcmFtUmVxdWlyZWRbaV0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjdHguZmFpbChwLm5hbWUsIFwiaXMgbWlzc2luZ1wiLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIG9rID0gaXRlbUNoZWNrZXJzW2ldKHZhbHVlW2ldLCBjdHgpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIW9rKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gY3R4LmZhaWwocC5uYW1lLCBudWxsLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9O1xuICAgICAgICBpZiAoIXN0cmljdCkge1xuICAgICAgICAgICAgcmV0dXJuIGNoZWNrZXI7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICh2YWx1ZSwgY3R4KSB7XG4gICAgICAgICAgICBpZiAoIWNoZWNrZXIodmFsdWUsIGN0eCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdmFsdWUubGVuZ3RoIDw9IGl0ZW1DaGVja2Vycy5sZW5ndGggPyB0cnVlIDpcbiAgICAgICAgICAgICAgICBjdHguZmFpbChpdGVtQ2hlY2tlcnMubGVuZ3RoLCBcImlzIGV4dHJhbmVvdXNcIiwgMik7XG4gICAgICAgIH07XG4gICAgfTtcbiAgICByZXR1cm4gVFBhcmFtTGlzdDtcbn0oVFR5cGUpKTtcbmV4cG9ydHMuVFBhcmFtTGlzdCA9IFRQYXJhbUxpc3Q7XG4vKipcbiAqIFNpbmdsZSBUVHlwZSBpbXBsZW1lbnRhdGlvbiBmb3IgYWxsIGJhc2ljIGJ1aWx0LWluIHR5cGVzLlxuICovXG52YXIgQmFzaWNUeXBlID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIF9fZXh0ZW5kcyhCYXNpY1R5cGUsIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gQmFzaWNUeXBlKHZhbGlkYXRvciwgbWVzc2FnZSkge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy52YWxpZGF0b3IgPSB2YWxpZGF0b3I7XG4gICAgICAgIF90aGlzLm1lc3NhZ2UgPSBtZXNzYWdlO1xuICAgICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIEJhc2ljVHlwZS5wcm90b3R5cGUuZ2V0Q2hlY2tlciA9IGZ1bmN0aW9uIChzdWl0ZSwgc3RyaWN0KSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAodmFsdWUsIGN0eCkgeyByZXR1cm4gX3RoaXMudmFsaWRhdG9yKHZhbHVlKSA/IHRydWUgOiBjdHguZmFpbChudWxsLCBfdGhpcy5tZXNzYWdlLCAwKTsgfTtcbiAgICB9O1xuICAgIHJldHVybiBCYXNpY1R5cGU7XG59KFRUeXBlKSk7XG5leHBvcnRzLkJhc2ljVHlwZSA9IEJhc2ljVHlwZTtcbi8qKlxuICogRGVmaW5lcyB0aGUgc3VpdGUgb2YgYmFzaWMgdHlwZXMuXG4gKi9cbmV4cG9ydHMuYmFzaWNUeXBlcyA9IHtcbiAgICBhbnk6IG5ldyBCYXNpY1R5cGUoZnVuY3Rpb24gKHYpIHsgcmV0dXJuIHRydWU7IH0sIFwiaXMgaW52YWxpZFwiKSxcbiAgICB1bmtub3duOiBuZXcgQmFzaWNUeXBlKGZ1bmN0aW9uICh2KSB7IHJldHVybiB0cnVlOyB9LCBcImlzIGludmFsaWRcIiksXG4gICAgbnVtYmVyOiBuZXcgQmFzaWNUeXBlKGZ1bmN0aW9uICh2KSB7IHJldHVybiAodHlwZW9mIHYgPT09IFwibnVtYmVyXCIpOyB9LCBcImlzIG5vdCBhIG51bWJlclwiKSxcbiAgICBvYmplY3Q6IG5ldyBCYXNpY1R5cGUoZnVuY3Rpb24gKHYpIHsgcmV0dXJuICh0eXBlb2YgdiA9PT0gXCJvYmplY3RcIiAmJiB2KTsgfSwgXCJpcyBub3QgYW4gb2JqZWN0XCIpLFxuICAgIGJvb2xlYW46IG5ldyBCYXNpY1R5cGUoZnVuY3Rpb24gKHYpIHsgcmV0dXJuICh0eXBlb2YgdiA9PT0gXCJib29sZWFuXCIpOyB9LCBcImlzIG5vdCBhIGJvb2xlYW5cIiksXG4gICAgc3RyaW5nOiBuZXcgQmFzaWNUeXBlKGZ1bmN0aW9uICh2KSB7IHJldHVybiAodHlwZW9mIHYgPT09IFwic3RyaW5nXCIpOyB9LCBcImlzIG5vdCBhIHN0cmluZ1wiKSxcbiAgICBzeW1ib2w6IG5ldyBCYXNpY1R5cGUoZnVuY3Rpb24gKHYpIHsgcmV0dXJuICh0eXBlb2YgdiA9PT0gXCJzeW1ib2xcIik7IH0sIFwiaXMgbm90IGEgc3ltYm9sXCIpLFxuICAgIHZvaWQ6IG5ldyBCYXNpY1R5cGUoZnVuY3Rpb24gKHYpIHsgcmV0dXJuICh2ID09IG51bGwpOyB9LCBcImlzIG5vdCB2b2lkXCIpLFxuICAgIHVuZGVmaW5lZDogbmV3IEJhc2ljVHlwZShmdW5jdGlvbiAodikgeyByZXR1cm4gKHYgPT09IHVuZGVmaW5lZCk7IH0sIFwiaXMgbm90IHVuZGVmaW5lZFwiKSxcbiAgICBudWxsOiBuZXcgQmFzaWNUeXBlKGZ1bmN0aW9uICh2KSB7IHJldHVybiAodiA9PT0gbnVsbCk7IH0sIFwiaXMgbm90IG51bGxcIiksXG4gICAgbmV2ZXI6IG5ldyBCYXNpY1R5cGUoZnVuY3Rpb24gKHYpIHsgcmV0dXJuIGZhbHNlOyB9LCBcImlzIHVuZXhwZWN0ZWRcIiksXG4gICAgRGF0ZTogbmV3IEJhc2ljVHlwZShnZXRJc05hdGl2ZUNoZWNrZXIoXCJbb2JqZWN0IERhdGVdXCIpLCBcImlzIG5vdCBhIERhdGVcIiksXG4gICAgUmVnRXhwOiBuZXcgQmFzaWNUeXBlKGdldElzTmF0aXZlQ2hlY2tlcihcIltvYmplY3QgUmVnRXhwXVwiKSwgXCJpcyBub3QgYSBSZWdFeHBcIiksXG59O1xuLy8gVGhpcyBhcHByb2FjaCBmb3IgY2hlY2tpbmcgbmF0aXZlIG9iamVjdCB0eXBlcyBtaXJyb3JzIHRoYXQgb2YgbG9kYXNoLiBJdHMgYWR2YW50YWdlIG92ZXJcbi8vIGBpc2luc3RhbmNlYCBpcyB0aGF0IGl0IGNhbiBzdGlsbCByZXR1cm4gdHJ1ZSBmb3IgbmF0aXZlIG9iamVjdHMgY3JlYXRlZCBpbiBkaWZmZXJlbnQgSlNcbi8vIGV4ZWN1dGlvbiBlbnZpcm9ubWVudHMuXG52YXIgbmF0aXZlVG9TdHJpbmcgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xuZnVuY3Rpb24gZ2V0SXNOYXRpdmVDaGVja2VyKHRhZykge1xuICAgIHJldHVybiBmdW5jdGlvbiAodikgeyByZXR1cm4gdHlwZW9mIHYgPT09IFwib2JqZWN0XCIgJiYgdiAmJiBuYXRpdmVUb1N0cmluZy5jYWxsKHYpID09PSB0YWc7IH07XG59XG5pZiAodHlwZW9mIEJ1ZmZlciAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgIGV4cG9ydHMuYmFzaWNUeXBlcy5CdWZmZXIgPSBuZXcgQmFzaWNUeXBlKGZ1bmN0aW9uICh2KSB7IHJldHVybiBCdWZmZXIuaXNCdWZmZXIodik7IH0sIFwiaXMgbm90IGEgQnVmZmVyXCIpO1xufVxudmFyIF9sb29wXzEgPSBmdW5jdGlvbiAoYXJyYXlfMSkge1xuICAgIGV4cG9ydHMuYmFzaWNUeXBlc1thcnJheV8xLm5hbWVdID0gbmV3IEJhc2ljVHlwZShmdW5jdGlvbiAodikgeyByZXR1cm4gKHYgaW5zdGFuY2VvZiBhcnJheV8xKTsgfSwgXCJpcyBub3QgYSBcIiArIGFycmF5XzEubmFtZSk7XG59O1xuLy8gU3VwcG9ydCB0eXBlZCBhcnJheXMgb2YgdmFyaW91cyBmbGF2b3JzXG5mb3IgKHZhciBfaSA9IDAsIF9hID0gW0ludDhBcnJheSwgVWludDhBcnJheSwgVWludDhDbGFtcGVkQXJyYXksIEludDE2QXJyYXksIFVpbnQxNkFycmF5LFxuICAgIEludDMyQXJyYXksIFVpbnQzMkFycmF5LCBGbG9hdDMyQXJyYXksIEZsb2F0NjRBcnJheSwgQXJyYXlCdWZmZXJdOyBfaSA8IF9hLmxlbmd0aDsgX2krKykge1xuICAgIHZhciBhcnJheV8xID0gX2FbX2ldO1xuICAgIF9sb29wXzEoYXJyYXlfMSk7XG59XG5mdW5jdGlvbiBnZXRUeXBlTmFtZSh0KSB7XG4gICAgaWYgKHQgaW5zdGFuY2VvZiBUTmFtZSB8fCB0IGluc3RhbmNlb2YgVExpdGVyYWwgfHwgdCBpbnN0YW5jZW9mIFRBcnJheSkge1xuICAgICAgICByZXR1cm4gdC5uYW1lO1xuICAgIH1cbn1cbiIsIlwidXNlIHN0cmljdFwiO1xudmFyIF9fZXh0ZW5kcyA9ICh0aGlzICYmIHRoaXMuX19leHRlbmRzKSB8fCAoZnVuY3Rpb24gKCkge1xuICAgIHZhciBleHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgICAgZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fFxuICAgICAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fFxuICAgICAgICAgICAgZnVuY3Rpb24gKGQsIGIpIHsgZm9yICh2YXIgcCBpbiBiKSBpZiAoYi5oYXNPd25Qcm9wZXJ0eShwKSkgZFtwXSA9IGJbcF07IH07XG4gICAgICAgIHJldHVybiBleHRlbmRTdGF0aWNzKGQsIGIpO1xuICAgIH07XG4gICAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7XG4gICAgICAgIGZ1bmN0aW9uIF9fKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gZDsgfVxuICAgICAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gICAgfTtcbn0pKCk7XG52YXIgX19zcHJlYWRBcnJheXMgPSAodGhpcyAmJiB0aGlzLl9fc3ByZWFkQXJyYXlzKSB8fCBmdW5jdGlvbiAoKSB7XG4gICAgZm9yICh2YXIgcyA9IDAsIGkgPSAwLCBpbCA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBpbDsgaSsrKSBzICs9IGFyZ3VtZW50c1tpXS5sZW5ndGg7XG4gICAgZm9yICh2YXIgciA9IEFycmF5KHMpLCBrID0gMCwgaSA9IDA7IGkgPCBpbDsgaSsrKVxuICAgICAgICBmb3IgKHZhciBhID0gYXJndW1lbnRzW2ldLCBqID0gMCwgamwgPSBhLmxlbmd0aDsgaiA8IGpsOyBqKyssIGsrKylcbiAgICAgICAgICAgIHJba10gPSBhW2pdO1xuICAgIHJldHVybiByO1xufTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuRGV0YWlsQ29udGV4dCA9IGV4cG9ydHMuTm9vcENvbnRleHQgPSBleHBvcnRzLlZFcnJvciA9IHZvaWQgMDtcbi8qKlxuICogRXJyb3IgdGhyb3duIGJ5IHZhbGlkYXRpb24uIEJlc2lkZXMgYW4gaW5mb3JtYXRpdmUgbWVzc2FnZSwgaXQgaW5jbHVkZXMgdGhlIHBhdGggdG8gdGhlXG4gKiBwcm9wZXJ0eSB3aGljaCB0cmlnZ2VyZWQgdGhlIGZhaWx1cmUuXG4gKi9cbnZhciBWRXJyb3IgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgX19leHRlbmRzKFZFcnJvciwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBWRXJyb3IocGF0aCwgbWVzc2FnZSkge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCBtZXNzYWdlKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy5wYXRoID0gcGF0aDtcbiAgICAgICAgLy8gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9NaWNyb3NvZnQvVHlwZVNjcmlwdC93aWtpL0JyZWFraW5nLUNoYW5nZXMjZXh0ZW5kaW5nLWJ1aWx0LWlucy1saWtlLWVycm9yLWFycmF5LWFuZC1tYXAtbWF5LW5vLWxvbmdlci13b3JrIGZvciBpbmZvIGFib3V0IHRoaXMgd29ya2Fyb3VuZC5cbiAgICAgICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKF90aGlzLCBWRXJyb3IucHJvdG90eXBlKTtcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICByZXR1cm4gVkVycm9yO1xufShFcnJvcikpO1xuZXhwb3J0cy5WRXJyb3IgPSBWRXJyb3I7XG4vKipcbiAqIEZhc3QgaW1wbGVtZW50YXRpb24gb2YgSUNvbnRleHQgdXNlZCBmb3IgZmlyc3QtcGFzcyB2YWxpZGF0aW9uLiBJZiB0aGF0IGZhaWxzLCB3ZSBjYW4gdmFsaWRhdGVcbiAqIHVzaW5nIERldGFpbENvbnRleHQgdG8gY29sbGVjdCBlcnJvciBtZXNzYWdlcy4gVGhhdCdzIGZhc3RlciBmb3IgdGhlIGNvbW1vbiBjYXNlIHdoZW4gbWVzc2FnZXNcbiAqIG5vcm1hbGx5IHBhc3MgdmFsaWRhdGlvbi5cbiAqL1xudmFyIE5vb3BDb250ZXh0ID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIE5vb3BDb250ZXh0KCkge1xuICAgICAgICB0aGlzLl9mYWlsZWQgPSBmYWxzZTtcbiAgICB9XG4gICAgTm9vcENvbnRleHQucHJvdG90eXBlLmZhaWwgPSBmdW5jdGlvbiAocmVsUGF0aCwgbWVzc2FnZSwgc2NvcmUpIHtcbiAgICAgICAgdGhpcy5fZmFpbGVkID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH07XG4gICAgTm9vcENvbnRleHQucHJvdG90eXBlLmZvcmsgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG4gICAgTm9vcENvbnRleHQucHJvdG90eXBlLmNvbXBsZXRlRm9yayA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuICF0aGlzLl9mYWlsZWQ7XG4gICAgfTtcbiAgICBOb29wQ29udGV4dC5wcm90b3R5cGUuZmFpbGVkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZmFpbGVkO1xuICAgIH07XG4gICAgTm9vcENvbnRleHQucHJvdG90eXBlLnVuaW9uUmVzb2x2ZXIgPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9O1xuICAgIE5vb3BDb250ZXh0LnByb3RvdHlwZS5jcmVhdGVDb250ZXh0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLl9mYWlsZWQgPSBmYWxzZTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgICBOb29wQ29udGV4dC5wcm90b3R5cGUucmVzb2x2ZVVuaW9uID0gZnVuY3Rpb24gKHVyKSB7IH07XG4gICAgcmV0dXJuIE5vb3BDb250ZXh0O1xufSgpKTtcbmV4cG9ydHMuTm9vcENvbnRleHQgPSBOb29wQ29udGV4dDtcbi8qKlxuICogQ29tcGxldGUgaW1wbGVtZW50YXRpb24gb2YgSUNvbnRleHQgdGhhdCBjb2xsZWN0cyBtZWFuaW5nZnVsbCBlcnJvcnMuXG4gKi9cbnZhciBEZXRhaWxDb250ZXh0ID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIERldGFpbENvbnRleHQoKSB7XG4gICAgICAgIC8vIFN0YWNrIG9mIHByb3BlcnR5IG5hbWVzIGFuZCBhc3NvY2lhdGVkIG1lc3NhZ2VzIGZvciByZXBvcnRpbmcgaGVscGZ1bCBlcnJvciBtZXNzYWdlcy5cbiAgICAgICAgdGhpcy5fcHJvcE5hbWVzID0gW107XG4gICAgICAgIHRoaXMuX21lc3NhZ2VzID0gW107XG4gICAgICAgIC8qKiBDb250ZXh0cyBjcmVhdGVkIGJ5IGZvcmsoKSB3aGljaCBoYXZlIGNvbXBsZXRlZCBhbmQgY29udGFpbiBmYWlsdXJlcyAqL1xuICAgICAgICB0aGlzLl9mYWlsZWRGb3JrcyA9IFtdO1xuICAgICAgICAvKipcbiAgICAgICAgICogQ29udGFpbnMgdGhlIGNvbnRleHQgcmV0dXJuZWQgYnkgZm9yaygpIHdoaWNoIHNob3VsZCBiZSBjaGVja2VkIHVudGlsXG4gICAgICAgICAqIGNvbXBsZXRlRm9yaygpIGlzIGNhbGxlZC5cbiAgICAgICAgICogV2lsbCBiZSByZXVzZWQgZm9yIHRoZSBuZXh0IGZvcmsoKSBpZiB0aGVyZSBhcmUgbm8gZmFpbHVyZXMuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9jdXJyZW50Rm9yayA9IG51bGw7XG4gICAgICAgIC8vIFNjb3JlIGlzIHVzZWQgdG8gY2hvb3NlIHRoZSBiZXN0IHVuaW9uIG1lbWJlciB3aG9zZSBEZXRhaWxDb250ZXh0IHRvIHVzZSBmb3IgcmVwb3J0aW5nLlxuICAgICAgICAvLyBIaWdoZXIgc2NvcmUgbWVhbnMgYmV0dGVyIG1hdGNoIChvciByYXRoZXIgbGVzcyBzZXZlcmUgbWlzbWF0Y2gpLlxuICAgICAgICB0aGlzLl9zY29yZSA9IDA7XG4gICAgfVxuICAgIERldGFpbENvbnRleHQucHJvdG90eXBlLmZhaWwgPSBmdW5jdGlvbiAocmVsUGF0aCwgbWVzc2FnZSwgc2NvcmUpIHtcbiAgICAgICAgdGhpcy5fcHJvcE5hbWVzLnB1c2gocmVsUGF0aCk7XG4gICAgICAgIHRoaXMuX21lc3NhZ2VzLnB1c2gobWVzc2FnZSk7XG4gICAgICAgIHRoaXMuX3Njb3JlICs9IHNjb3JlO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfTtcbiAgICBEZXRhaWxDb250ZXh0LnByb3RvdHlwZS51bmlvblJlc29sdmVyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gbmV3IERldGFpbFVuaW9uUmVzb2x2ZXIoKTtcbiAgICB9O1xuICAgIERldGFpbENvbnRleHQucHJvdG90eXBlLnJlc29sdmVVbmlvbiA9IGZ1bmN0aW9uICh1bmlvblJlc29sdmVyKSB7XG4gICAgICAgIHZhciBfYSwgX2IsIF9jO1xuICAgICAgICB2YXIgdSA9IHVuaW9uUmVzb2x2ZXI7XG4gICAgICAgIHZhciBiZXN0ID0gbnVsbDtcbiAgICAgICAgZm9yICh2YXIgX2kgPSAwLCBfZCA9IHUuY29udGV4dHM7IF9pIDwgX2QubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgICAgICB2YXIgY3R4ID0gX2RbX2ldO1xuICAgICAgICAgICAgaWYgKCFiZXN0IHx8IGN0eC5fc2NvcmUgPj0gYmVzdC5fc2NvcmUpIHtcbiAgICAgICAgICAgICAgICBiZXN0ID0gY3R4O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChiZXN0ICYmIGJlc3QuX3Njb3JlID4gMCkge1xuICAgICAgICAgICAgKF9hID0gdGhpcy5fcHJvcE5hbWVzKS5wdXNoLmFwcGx5KF9hLCBiZXN0Ll9wcm9wTmFtZXMpO1xuICAgICAgICAgICAgKF9iID0gdGhpcy5fbWVzc2FnZXMpLnB1c2guYXBwbHkoX2IsIGJlc3QuX21lc3NhZ2VzKTtcbiAgICAgICAgICAgIChfYyA9IHRoaXMuX2ZhaWxlZEZvcmtzKS5wdXNoLmFwcGx5KF9jLCBiZXN0Ll9mYWlsZWRGb3Jrcyk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIERldGFpbENvbnRleHQucHJvdG90eXBlLmdldEVycm9yID0gZnVuY3Rpb24gKHBhdGgpIHtcbiAgICAgICAgdmFyIGZ1bGxNZXNzYWdlID0gZmxhdHRlbih0aGlzLmdldEVycm9yRGV0YWlscyhwYXRoKS5tYXAoZXJyb3JMaW5lcykpXG4gICAgICAgICAgICAuam9pbihcIlxcblwiKTtcbiAgICAgICAgcmV0dXJuIG5ldyBWRXJyb3IocGF0aCwgZnVsbE1lc3NhZ2UpO1xuICAgIH07XG4gICAgRGV0YWlsQ29udGV4dC5wcm90b3R5cGUuZ2V0RXJyb3JEZXRhaWxzID0gZnVuY3Rpb24gKHBhdGgpIHtcbiAgICAgICAgdmFyIGRldGFpbCA9IG51bGw7XG4gICAgICAgIHZhciBuZXN0ZWQ7XG4gICAgICAgIHZhciBkZXRhaWxzID0gW107XG4gICAgICAgIC8vIEFzIGNoZWNrZXJzIGNhbGwgZmFpbCgpIGFuZCByZXR1cm4gdG8gdGhlaXIgcGFyZW50IGNoZWNrZXJzLFxuICAgICAgICAvLyB0aGUgZGVlcGVzdCBmYWlsdXJlcyBhcmUgcmVjb3JkZWQgZmlyc3QuXG4gICAgICAgIC8vIEdvIHRocm91Z2ggZmFpbHVyZXMgaW4gcmV2ZXJzZSB0byBzdGFydCBmcm9tIHRoZSByb290IHR5cGVcbiAgICAgICAgZm9yICh2YXIgaSA9IHRoaXMuX3Byb3BOYW1lcy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgICAgdmFyIHAgPSB0aGlzLl9wcm9wTmFtZXNbaV07XG4gICAgICAgICAgICBwYXRoICs9ICh0eXBlb2YgcCA9PT0gXCJudW1iZXJcIikgPyBcIltcIiArIHAgKyBcIl1cIiA6IChwID8gXCIuXCIgKyBwIDogXCJcIik7XG4gICAgICAgICAgICB2YXIgbWVzc2FnZSA9IHRoaXMuX21lc3NhZ2VzW2ldO1xuICAgICAgICAgICAgaWYgKCFtZXNzYWdlKSB7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBuZXN0ZWQgPSB7IHBhdGg6IHBhdGgsIG1lc3NhZ2U6IG1lc3NhZ2UgfTtcbiAgICAgICAgICAgIGlmIChkZXRhaWwpIHtcbiAgICAgICAgICAgICAgICBkZXRhaWwubmVzdGVkID0gW25lc3RlZF07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIHRoZSByb290IGZhaWx1cmUsIHNvIGl0IHdpbGwgYmUgcmV0dXJuZWRcbiAgICAgICAgICAgICAgICBkZXRhaWxzLnB1c2gobmVzdGVkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIE1vdmUgaW50byB0aGUgZGVlcGVyIGVycm9yXG4gICAgICAgICAgICBkZXRhaWwgPSBuZXN0ZWQ7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGZvcmtFcnJvcnMgPSBmbGF0dGVuKHRoaXMuX2ZhaWxlZEZvcmtzLm1hcChmdW5jdGlvbiAoZm9yaykgeyByZXR1cm4gZm9yay5nZXRFcnJvckRldGFpbHMocGF0aCk7IH0pKTtcbiAgICAgICAgaWYgKGRldGFpbCkge1xuICAgICAgICAgICAgLy8gZG9uJ3QgcHV0IGFuIGVtcHR5IGFycmF5IGluIGRldGFpbC5uZXN0ZWRcbiAgICAgICAgICAgIGlmIChmb3JrRXJyb3JzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIC8vIGRldGFpbCBpcyB0aGUgZGVlcGVzdCBuZXN0ZWQgZXJyb3IsIHNvIGRldGFpbC5uZXN0ZWQgaXMgbnVsbCBhdCB0aGlzIHBvaW50XG4gICAgICAgICAgICAgICAgZGV0YWlsLm5lc3RlZCA9IGZvcmtFcnJvcnM7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBUaGVyZSB3ZXJlIG5vICdwbGFpbicgZmFpbHVyZXMsIG9ubHkgZm9yayBmYWlsdXJlc1xuICAgICAgICAgICAgZGV0YWlscyA9IGZvcmtFcnJvcnM7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGRldGFpbHM7XG4gICAgfTtcbiAgICBEZXRhaWxDb250ZXh0LnByb3RvdHlwZS5mb3JrID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAodGhpcy5fY3VycmVudEZvcmsgPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5fY3VycmVudEZvcmsgPSBuZXcgRGV0YWlsQ29udGV4dCgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9jdXJyZW50Rm9yaztcbiAgICB9O1xuICAgIERldGFpbENvbnRleHQucHJvdG90eXBlLmNvbXBsZXRlRm9yayA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGZvcmsgPSB0aGlzLl9jdXJyZW50Rm9yaztcbiAgICAgICAgaWYgKGZvcmsuX2ZhaWxlZCgpKSB7XG4gICAgICAgICAgICB0aGlzLl9mYWlsZWRGb3Jrcy5wdXNoKGZvcmspO1xuICAgICAgICAgICAgdGhpcy5fY3VycmVudEZvcmsgPSBudWxsO1xuICAgICAgICAgICAgLy8gVG8gcHJlc2VydmUgb2xkIGJlaGF2aW91ciwgdXNlIHRoZSBzY29yZSBvZiB0aGUgZmlyc3QgZmFpbHVyZVxuICAgICAgICAgICAgLy8gTWlnaHQgd2FudCB0byByZXZpc2UgdGhpc1xuICAgICAgICAgICAgaWYgKHRoaXMuX2ZhaWxlZEZvcmtzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX3Njb3JlID0gZm9yay5fc2NvcmU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX2ZhaWxlZEZvcmtzLmxlbmd0aCA8IERldGFpbENvbnRleHQubWF4Rm9ya3M7XG4gICAgfTtcbiAgICAvLyBmYWlsZWQoKSBpcyB0aGUgcHVibGljIGludGVyZmFjZSxcbiAgICAvLyBpdCBnZXRzIG1vbmtleXBhdGNoZWQgdG8gZW5zdXJlIGNvcnJlY3QgdXNhZ2UgaW4gY2hlY2tlcnMuXG4gICAgLy8gX2ZhaWxlZCgpIG1heSBiZSBjYWxsZWQgaW50ZXJuYWxseVxuICAgIC8vIGluIHdheXMgd2hpY2ggd291bGQgZmFpbCB0aGUgbW9ua2V5cGF0Y2hlZCBhc3NlcnRpb25zLlxuICAgIERldGFpbENvbnRleHQucHJvdG90eXBlLmZhaWxlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ZhaWxlZCgpO1xuICAgIH07XG4gICAgRGV0YWlsQ29udGV4dC5wcm90b3R5cGUuX2ZhaWxlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Byb3BOYW1lcy5sZW5ndGggKyB0aGlzLl9mYWlsZWRGb3Jrcy5sZW5ndGggPiAwO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogTWF4aW11bSBudW1iZXIgb2YgZXJyb3JzIHJlY29yZGVkIGF0IG9uZSBsZXZlbCBmb3IgYW4gb2JqZWN0LFxuICAgICAqIGkuZS4gdGhlIG1heGltdW0gbGVuZ3RoIG9mIENoZWNrZXIudmFsaWRhdGUoKSBvciBJRXJyb3JEZXRhaWwubmVzdGVkLlxuICAgICAqL1xuICAgIC8vIElmIF9mYWlsZWRGb3JrcyBoYXMgdGhpcyBsZW5ndGggdGhlbiBjb21wbGV0ZUZvcmsoKSBzaG91bGQgcmV0dXJuIGZhbHNlXG4gICAgLy8gc28gdGhhdCB0aGUgY2hlY2tlciBzdG9wcyBtYWtpbmcgbW9yZSBmb3Jrcy5cbiAgICBEZXRhaWxDb250ZXh0Lm1heEZvcmtzID0gMztcbiAgICByZXR1cm4gRGV0YWlsQ29udGV4dDtcbn0oKSk7XG5leHBvcnRzLkRldGFpbENvbnRleHQgPSBEZXRhaWxDb250ZXh0O1xudmFyIERldGFpbFVuaW9uUmVzb2x2ZXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gRGV0YWlsVW5pb25SZXNvbHZlcigpIHtcbiAgICAgICAgdGhpcy5jb250ZXh0cyA9IFtdO1xuICAgIH1cbiAgICBEZXRhaWxVbmlvblJlc29sdmVyLnByb3RvdHlwZS5jcmVhdGVDb250ZXh0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgY3R4ID0gbmV3IERldGFpbENvbnRleHQoKTtcbiAgICAgICAgdGhpcy5jb250ZXh0cy5wdXNoKGN0eCk7XG4gICAgICAgIHJldHVybiBjdHg7XG4gICAgfTtcbiAgICByZXR1cm4gRGV0YWlsVW5pb25SZXNvbHZlcjtcbn0oKSk7XG4vKipcbiAqIFJldHVybnMgbGluZXMgb2YgYSBtZXNzYWdlIGRlc2NyaWJpbmcgYGVycm9yYC5cbiAqIFRoZSBsaW5lcyBzaG91bGQgYmUgbmV3bGluZSBzZXBhcmF0ZWQgaW4gdGhlIGZpbmFsIG1lc3NhZ2UuXG4gKiBPbmx5IHJldHVybnMgbXVsdGlwbGUgbGluZXMgaWYgYGVycm9yYCBvciBhIGRlc2NlbmRhbnRcbiAqIGhhcyBtdWx0aXBsZSBlcnJvcnMgaW4gaXRzIGAubmVzdGVkYCBhcnJheS5cbiAqIFNpbXBsZSBwYXRocyBvZiBuZXN0ZWQgZXJyb3JzIGFueXdoZXJlIGluIHRoZSB0cmVlXG4gKiBhcmUgY29sbGFwc2VkIGludG8gYSBzaW5nbGUgbGluZSB1bnRpbCBhIGJyYW5jaCBpcyByZWFjaGVkLlxuICovXG52YXIgZXJyb3JMaW5lcyA9IGZ1bmN0aW9uIChlcnJvcikge1xuICAgIHZhciByb290TWVzc2FnZSA9IGVycm9yLnBhdGggKyBcIiBcIiArIGVycm9yLm1lc3NhZ2U7XG4gICAgdmFyIG5lc3RlZEVycm9ycyA9IGVycm9yLm5lc3RlZCB8fCBbXTtcbiAgICB2YXIgbmVzdGVkTGluZXMgPSBmbGF0dGVuKG5lc3RlZEVycm9ycy5tYXAoZXJyb3JMaW5lcykpO1xuICAgIGlmIChuZXN0ZWRFcnJvcnMubGVuZ3RoID09IDEpIHtcbiAgICAgICAgLy8gU2luZ2xlIG5lc3RlZCBlcnJvcnMgYXJlIGNvbGxhcHNlZCBpbnRvIHRoZSBmaXJzdCBsaW5lLFxuICAgICAgICAvLyBidXQgdGhleSBtYXkgaGF2ZSBicmFuY2hlcyBkZWVwZXIgZG93biBsZWFkaW5nIHRvIG1vcmUgbGluZXNcbiAgICAgICAgLy8gd2hpY2ggYXJlIGFscmVhZHkgaW5kZW50ZWRcbiAgICAgICAgdmFyIGZpcnN0ID0gbmVzdGVkTGluZXNbMF0sIHJlc3QgPSBuZXN0ZWRMaW5lcy5zbGljZSgxKTtcbiAgICAgICAgcmV0dXJuIF9fc3ByZWFkQXJyYXlzKFtcbiAgICAgICAgICAgIHJvb3RNZXNzYWdlICsgXCI7IFwiICsgZmlyc3RcbiAgICAgICAgXSwgcmVzdCk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICAvLyBJbmRlbnQgbWVzc2FnZXMgZnJvbSBuZXN0ZWQgZXJyb3JzXG4gICAgICAgIC8vIG9yIGp1c3QgcmV0dXJuIFtyb290TWVzc2FnZV0gaWYgdGhlcmUgYXJlIG5vIG5lc3RlZCBlcnJvcnNcbiAgICAgICAgcmV0dXJuIF9fc3ByZWFkQXJyYXlzKFtcbiAgICAgICAgICAgIHJvb3RNZXNzYWdlXG4gICAgICAgIF0sIG5lc3RlZExpbmVzLm1hcChmdW5jdGlvbiAobGluZSkgeyByZXR1cm4gXCIgICAgXCIgKyBsaW5lOyB9KSk7XG4gICAgfVxufTtcbi8qKiBTaGFsbG93IGZsYXR0ZW4gYSAyRCBhcnJheSBpbnRvIGEgMUQgYXJyYXkgKi9cbmZ1bmN0aW9uIGZsYXR0ZW4oYXJyKSB7XG4gICAgdmFyIF9hO1xuICAgIHJldHVybiAoX2EgPSBbXSkuY29uY2F0LmFwcGx5KF9hLCBhcnIpO1xufVxuIiwiLypcbiAqIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuICpcbiAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4gKiBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4gKiBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbiAqIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbiAqIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbiAqIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuICogZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4gKlxuICogVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbiAqIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuICpcbiAqIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1NcbiAqIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0ZcbiAqIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbiAqIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuICogREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4gKiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4gKiBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxudmFyIHB1bnljb2RlID0gcmVxdWlyZSgncHVueWNvZGUvJyk7XG5cbmZ1bmN0aW9uIFVybCgpIHtcbiAgdGhpcy5wcm90b2NvbCA9IG51bGw7XG4gIHRoaXMuc2xhc2hlcyA9IG51bGw7XG4gIHRoaXMuYXV0aCA9IG51bGw7XG4gIHRoaXMuaG9zdCA9IG51bGw7XG4gIHRoaXMucG9ydCA9IG51bGw7XG4gIHRoaXMuaG9zdG5hbWUgPSBudWxsO1xuICB0aGlzLmhhc2ggPSBudWxsO1xuICB0aGlzLnNlYXJjaCA9IG51bGw7XG4gIHRoaXMucXVlcnkgPSBudWxsO1xuICB0aGlzLnBhdGhuYW1lID0gbnVsbDtcbiAgdGhpcy5wYXRoID0gbnVsbDtcbiAgdGhpcy5ocmVmID0gbnVsbDtcbn1cblxuLy8gUmVmZXJlbmNlOiBSRkMgMzk4NiwgUkZDIDE4MDgsIFJGQyAyMzk2XG5cbi8qXG4gKiBkZWZpbmUgdGhlc2UgaGVyZSBzbyBhdCBsZWFzdCB0aGV5IG9ubHkgaGF2ZSB0byBiZVxuICogY29tcGlsZWQgb25jZSBvbiB0aGUgZmlyc3QgbW9kdWxlIGxvYWQuXG4gKi9cbnZhciBwcm90b2NvbFBhdHRlcm4gPSAvXihbYS16MC05ListXSs6KS9pLFxuICBwb3J0UGF0dGVybiA9IC86WzAtOV0qJC8sXG5cbiAgLy8gU3BlY2lhbCBjYXNlIGZvciBhIHNpbXBsZSBwYXRoIFVSTFxuICBzaW1wbGVQYXRoUGF0dGVybiA9IC9eKFxcL1xcLz8oPyFcXC8pW14/XFxzXSopKFxcP1teXFxzXSopPyQvLFxuXG4gIC8qXG4gICAqIFJGQyAyMzk2OiBjaGFyYWN0ZXJzIHJlc2VydmVkIGZvciBkZWxpbWl0aW5nIFVSTHMuXG4gICAqIFdlIGFjdHVhbGx5IGp1c3QgYXV0by1lc2NhcGUgdGhlc2UuXG4gICAqL1xuICBkZWxpbXMgPSBbXG4gICAgJzwnLCAnPicsICdcIicsICdgJywgJyAnLCAnXFxyJywgJ1xcbicsICdcXHQnXG4gIF0sXG5cbiAgLy8gUkZDIDIzOTY6IGNoYXJhY3RlcnMgbm90IGFsbG93ZWQgZm9yIHZhcmlvdXMgcmVhc29ucy5cbiAgdW53aXNlID0gW1xuICAgICd7JywgJ30nLCAnfCcsICdcXFxcJywgJ14nLCAnYCdcbiAgXS5jb25jYXQoZGVsaW1zKSxcblxuICAvLyBBbGxvd2VkIGJ5IFJGQ3MsIGJ1dCBjYXVzZSBvZiBYU1MgYXR0YWNrcy4gIEFsd2F5cyBlc2NhcGUgdGhlc2UuXG4gIGF1dG9Fc2NhcGUgPSBbJ1xcJyddLmNvbmNhdCh1bndpc2UpLFxuICAvKlxuICAgKiBDaGFyYWN0ZXJzIHRoYXQgYXJlIG5ldmVyIGV2ZXIgYWxsb3dlZCBpbiBhIGhvc3RuYW1lLlxuICAgKiBOb3RlIHRoYXQgYW55IGludmFsaWQgY2hhcnMgYXJlIGFsc28gaGFuZGxlZCwgYnV0IHRoZXNlXG4gICAqIGFyZSB0aGUgb25lcyB0aGF0IGFyZSAqZXhwZWN0ZWQqIHRvIGJlIHNlZW4sIHNvIHdlIGZhc3QtcGF0aFxuICAgKiB0aGVtLlxuICAgKi9cbiAgbm9uSG9zdENoYXJzID0gW1xuICAgICclJywgJy8nLCAnPycsICc7JywgJyMnXG4gIF0uY29uY2F0KGF1dG9Fc2NhcGUpLFxuICBob3N0RW5kaW5nQ2hhcnMgPSBbXG4gICAgJy8nLCAnPycsICcjJ1xuICBdLFxuICBob3N0bmFtZU1heExlbiA9IDI1NSxcbiAgaG9zdG5hbWVQYXJ0UGF0dGVybiA9IC9eWythLXowLTlBLVpfLV17MCw2M30kLyxcbiAgaG9zdG5hbWVQYXJ0U3RhcnQgPSAvXihbK2EtejAtOUEtWl8tXXswLDYzfSkoLiopJC8sXG4gIC8vIHByb3RvY29scyB0aGF0IGNhbiBhbGxvdyBcInVuc2FmZVwiIGFuZCBcInVud2lzZVwiIGNoYXJzLlxuICB1bnNhZmVQcm90b2NvbCA9IHtcbiAgICBqYXZhc2NyaXB0OiB0cnVlLFxuICAgICdqYXZhc2NyaXB0Oic6IHRydWVcbiAgfSxcbiAgLy8gcHJvdG9jb2xzIHRoYXQgbmV2ZXIgaGF2ZSBhIGhvc3RuYW1lLlxuICBob3N0bGVzc1Byb3RvY29sID0ge1xuICAgIGphdmFzY3JpcHQ6IHRydWUsXG4gICAgJ2phdmFzY3JpcHQ6JzogdHJ1ZVxuICB9LFxuICAvLyBwcm90b2NvbHMgdGhhdCBhbHdheXMgY29udGFpbiBhIC8vIGJpdC5cbiAgc2xhc2hlZFByb3RvY29sID0ge1xuICAgIGh0dHA6IHRydWUsXG4gICAgaHR0cHM6IHRydWUsXG4gICAgZnRwOiB0cnVlLFxuICAgIGdvcGhlcjogdHJ1ZSxcbiAgICBmaWxlOiB0cnVlLFxuICAgICdodHRwOic6IHRydWUsXG4gICAgJ2h0dHBzOic6IHRydWUsXG4gICAgJ2Z0cDonOiB0cnVlLFxuICAgICdnb3BoZXI6JzogdHJ1ZSxcbiAgICAnZmlsZTonOiB0cnVlXG4gIH0sXG4gIHF1ZXJ5c3RyaW5nID0gcmVxdWlyZSgncXMnKTtcblxuZnVuY3Rpb24gdXJsUGFyc2UodXJsLCBwYXJzZVF1ZXJ5U3RyaW5nLCBzbGFzaGVzRGVub3RlSG9zdCkge1xuICBpZiAodXJsICYmIHR5cGVvZiB1cmwgPT09ICdvYmplY3QnICYmIHVybCBpbnN0YW5jZW9mIFVybCkgeyByZXR1cm4gdXJsOyB9XG5cbiAgdmFyIHUgPSBuZXcgVXJsKCk7XG4gIHUucGFyc2UodXJsLCBwYXJzZVF1ZXJ5U3RyaW5nLCBzbGFzaGVzRGVub3RlSG9zdCk7XG4gIHJldHVybiB1O1xufVxuXG5VcmwucHJvdG90eXBlLnBhcnNlID0gZnVuY3Rpb24gKHVybCwgcGFyc2VRdWVyeVN0cmluZywgc2xhc2hlc0Rlbm90ZUhvc3QpIHtcbiAgaWYgKHR5cGVvZiB1cmwgIT09ICdzdHJpbmcnKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlBhcmFtZXRlciAndXJsJyBtdXN0IGJlIGEgc3RyaW5nLCBub3QgXCIgKyB0eXBlb2YgdXJsKTtcbiAgfVxuXG4gIC8qXG4gICAqIENvcHkgY2hyb21lLCBJRSwgb3BlcmEgYmFja3NsYXNoLWhhbmRsaW5nIGJlaGF2aW9yLlxuICAgKiBCYWNrIHNsYXNoZXMgYmVmb3JlIHRoZSBxdWVyeSBzdHJpbmcgZ2V0IGNvbnZlcnRlZCB0byBmb3J3YXJkIHNsYXNoZXNcbiAgICogU2VlOiBodHRwczovL2NvZGUuZ29vZ2xlLmNvbS9wL2Nocm9taXVtL2lzc3Vlcy9kZXRhaWw/aWQ9MjU5MTZcbiAgICovXG4gIHZhciBxdWVyeUluZGV4ID0gdXJsLmluZGV4T2YoJz8nKSxcbiAgICBzcGxpdHRlciA9IHF1ZXJ5SW5kZXggIT09IC0xICYmIHF1ZXJ5SW5kZXggPCB1cmwuaW5kZXhPZignIycpID8gJz8nIDogJyMnLFxuICAgIHVTcGxpdCA9IHVybC5zcGxpdChzcGxpdHRlciksXG4gICAgc2xhc2hSZWdleCA9IC9cXFxcL2c7XG4gIHVTcGxpdFswXSA9IHVTcGxpdFswXS5yZXBsYWNlKHNsYXNoUmVnZXgsICcvJyk7XG4gIHVybCA9IHVTcGxpdC5qb2luKHNwbGl0dGVyKTtcblxuICB2YXIgcmVzdCA9IHVybDtcblxuICAvKlxuICAgKiB0cmltIGJlZm9yZSBwcm9jZWVkaW5nLlxuICAgKiBUaGlzIGlzIHRvIHN1cHBvcnQgcGFyc2Ugc3R1ZmYgbGlrZSBcIiAgaHR0cDovL2Zvby5jb20gIFxcblwiXG4gICAqL1xuICByZXN0ID0gcmVzdC50cmltKCk7XG5cbiAgaWYgKCFzbGFzaGVzRGVub3RlSG9zdCAmJiB1cmwuc3BsaXQoJyMnKS5sZW5ndGggPT09IDEpIHtcbiAgICAvLyBUcnkgZmFzdCBwYXRoIHJlZ2V4cFxuICAgIHZhciBzaW1wbGVQYXRoID0gc2ltcGxlUGF0aFBhdHRlcm4uZXhlYyhyZXN0KTtcbiAgICBpZiAoc2ltcGxlUGF0aCkge1xuICAgICAgdGhpcy5wYXRoID0gcmVzdDtcbiAgICAgIHRoaXMuaHJlZiA9IHJlc3Q7XG4gICAgICB0aGlzLnBhdGhuYW1lID0gc2ltcGxlUGF0aFsxXTtcbiAgICAgIGlmIChzaW1wbGVQYXRoWzJdKSB7XG4gICAgICAgIHRoaXMuc2VhcmNoID0gc2ltcGxlUGF0aFsyXTtcbiAgICAgICAgaWYgKHBhcnNlUXVlcnlTdHJpbmcpIHtcbiAgICAgICAgICB0aGlzLnF1ZXJ5ID0gcXVlcnlzdHJpbmcucGFyc2UodGhpcy5zZWFyY2guc3Vic3RyKDEpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLnF1ZXJ5ID0gdGhpcy5zZWFyY2guc3Vic3RyKDEpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHBhcnNlUXVlcnlTdHJpbmcpIHtcbiAgICAgICAgdGhpcy5zZWFyY2ggPSAnJztcbiAgICAgICAgdGhpcy5xdWVyeSA9IHt9O1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICB9XG5cbiAgdmFyIHByb3RvID0gcHJvdG9jb2xQYXR0ZXJuLmV4ZWMocmVzdCk7XG4gIGlmIChwcm90bykge1xuICAgIHByb3RvID0gcHJvdG9bMF07XG4gICAgdmFyIGxvd2VyUHJvdG8gPSBwcm90by50b0xvd2VyQ2FzZSgpO1xuICAgIHRoaXMucHJvdG9jb2wgPSBsb3dlclByb3RvO1xuICAgIHJlc3QgPSByZXN0LnN1YnN0cihwcm90by5sZW5ndGgpO1xuICB9XG5cbiAgLypcbiAgICogZmlndXJlIG91dCBpZiBpdCdzIGdvdCBhIGhvc3RcbiAgICogdXNlckBzZXJ2ZXIgaXMgKmFsd2F5cyogaW50ZXJwcmV0ZWQgYXMgYSBob3N0bmFtZSwgYW5kIHVybFxuICAgKiByZXNvbHV0aW9uIHdpbGwgdHJlYXQgLy9mb28vYmFyIGFzIGhvc3Q9Zm9vLHBhdGg9YmFyIGJlY2F1c2UgdGhhdCdzXG4gICAqIGhvdyB0aGUgYnJvd3NlciByZXNvbHZlcyByZWxhdGl2ZSBVUkxzLlxuICAgKi9cbiAgaWYgKHNsYXNoZXNEZW5vdGVIb3N0IHx8IHByb3RvIHx8IHJlc3QubWF0Y2goL15cXC9cXC9bXkAvXStAW15AL10rLykpIHtcbiAgICB2YXIgc2xhc2hlcyA9IHJlc3Quc3Vic3RyKDAsIDIpID09PSAnLy8nO1xuICAgIGlmIChzbGFzaGVzICYmICEocHJvdG8gJiYgaG9zdGxlc3NQcm90b2NvbFtwcm90b10pKSB7XG4gICAgICByZXN0ID0gcmVzdC5zdWJzdHIoMik7XG4gICAgICB0aGlzLnNsYXNoZXMgPSB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIGlmICghaG9zdGxlc3NQcm90b2NvbFtwcm90b10gJiYgKHNsYXNoZXMgfHwgKHByb3RvICYmICFzbGFzaGVkUHJvdG9jb2xbcHJvdG9dKSkpIHtcblxuICAgIC8qXG4gICAgICogdGhlcmUncyBhIGhvc3RuYW1lLlxuICAgICAqIHRoZSBmaXJzdCBpbnN0YW5jZSBvZiAvLCA/LCA7LCBvciAjIGVuZHMgdGhlIGhvc3QuXG4gICAgICpcbiAgICAgKiBJZiB0aGVyZSBpcyBhbiBAIGluIHRoZSBob3N0bmFtZSwgdGhlbiBub24taG9zdCBjaGFycyAqYXJlKiBhbGxvd2VkXG4gICAgICogdG8gdGhlIGxlZnQgb2YgdGhlIGxhc3QgQCBzaWduLCB1bmxlc3Mgc29tZSBob3N0LWVuZGluZyBjaGFyYWN0ZXJcbiAgICAgKiBjb21lcyAqYmVmb3JlKiB0aGUgQC1zaWduLlxuICAgICAqIFVSTHMgYXJlIG9ibm94aW91cy5cbiAgICAgKlxuICAgICAqIGV4OlxuICAgICAqIGh0dHA6Ly9hQGJAYy8gPT4gdXNlcjphQGIgaG9zdDpjXG4gICAgICogaHR0cDovL2FAYj9AYyA9PiB1c2VyOmEgaG9zdDpjIHBhdGg6Lz9AY1xuICAgICAqL1xuXG4gICAgLypcbiAgICAgKiB2MC4xMiBUT0RPKGlzYWFjcyk6IFRoaXMgaXMgbm90IHF1aXRlIGhvdyBDaHJvbWUgZG9lcyB0aGluZ3MuXG4gICAgICogUmV2aWV3IG91ciB0ZXN0IGNhc2UgYWdhaW5zdCBicm93c2VycyBtb3JlIGNvbXByZWhlbnNpdmVseS5cbiAgICAgKi9cblxuICAgIC8vIGZpbmQgdGhlIGZpcnN0IGluc3RhbmNlIG9mIGFueSBob3N0RW5kaW5nQ2hhcnNcbiAgICB2YXIgaG9zdEVuZCA9IC0xO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaG9zdEVuZGluZ0NoYXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgaGVjID0gcmVzdC5pbmRleE9mKGhvc3RFbmRpbmdDaGFyc1tpXSk7XG4gICAgICBpZiAoaGVjICE9PSAtMSAmJiAoaG9zdEVuZCA9PT0gLTEgfHwgaGVjIDwgaG9zdEVuZCkpIHsgaG9zdEVuZCA9IGhlYzsgfVxuICAgIH1cblxuICAgIC8qXG4gICAgICogYXQgdGhpcyBwb2ludCwgZWl0aGVyIHdlIGhhdmUgYW4gZXhwbGljaXQgcG9pbnQgd2hlcmUgdGhlXG4gICAgICogYXV0aCBwb3J0aW9uIGNhbm5vdCBnbyBwYXN0LCBvciB0aGUgbGFzdCBAIGNoYXIgaXMgdGhlIGRlY2lkZXIuXG4gICAgICovXG4gICAgdmFyIGF1dGgsIGF0U2lnbjtcbiAgICBpZiAoaG9zdEVuZCA9PT0gLTEpIHtcbiAgICAgIC8vIGF0U2lnbiBjYW4gYmUgYW55d2hlcmUuXG4gICAgICBhdFNpZ24gPSByZXN0Lmxhc3RJbmRleE9mKCdAJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8qXG4gICAgICAgKiBhdFNpZ24gbXVzdCBiZSBpbiBhdXRoIHBvcnRpb24uXG4gICAgICAgKiBodHRwOi8vYUBiL2NAZCA9PiBob3N0OmIgYXV0aDphIHBhdGg6L2NAZFxuICAgICAgICovXG4gICAgICBhdFNpZ24gPSByZXN0Lmxhc3RJbmRleE9mKCdAJywgaG9zdEVuZCk7XG4gICAgfVxuXG4gICAgLypcbiAgICAgKiBOb3cgd2UgaGF2ZSBhIHBvcnRpb24gd2hpY2ggaXMgZGVmaW5pdGVseSB0aGUgYXV0aC5cbiAgICAgKiBQdWxsIHRoYXQgb2ZmLlxuICAgICAqL1xuICAgIGlmIChhdFNpZ24gIT09IC0xKSB7XG4gICAgICBhdXRoID0gcmVzdC5zbGljZSgwLCBhdFNpZ24pO1xuICAgICAgcmVzdCA9IHJlc3Quc2xpY2UoYXRTaWduICsgMSk7XG4gICAgICB0aGlzLmF1dGggPSBkZWNvZGVVUklDb21wb25lbnQoYXV0aCk7XG4gICAgfVxuXG4gICAgLy8gdGhlIGhvc3QgaXMgdGhlIHJlbWFpbmluZyB0byB0aGUgbGVmdCBvZiB0aGUgZmlyc3Qgbm9uLWhvc3QgY2hhclxuICAgIGhvc3RFbmQgPSAtMTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG5vbkhvc3RDaGFycy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIGhlYyA9IHJlc3QuaW5kZXhPZihub25Ib3N0Q2hhcnNbaV0pO1xuICAgICAgaWYgKGhlYyAhPT0gLTEgJiYgKGhvc3RFbmQgPT09IC0xIHx8IGhlYyA8IGhvc3RFbmQpKSB7IGhvc3RFbmQgPSBoZWM7IH1cbiAgICB9XG4gICAgLy8gaWYgd2Ugc3RpbGwgaGF2ZSBub3QgaGl0IGl0LCB0aGVuIHRoZSBlbnRpcmUgdGhpbmcgaXMgYSBob3N0LlxuICAgIGlmIChob3N0RW5kID09PSAtMSkgeyBob3N0RW5kID0gcmVzdC5sZW5ndGg7IH1cblxuICAgIHRoaXMuaG9zdCA9IHJlc3Quc2xpY2UoMCwgaG9zdEVuZCk7XG4gICAgcmVzdCA9IHJlc3Quc2xpY2UoaG9zdEVuZCk7XG5cbiAgICAvLyBwdWxsIG91dCBwb3J0LlxuICAgIHRoaXMucGFyc2VIb3N0KCk7XG5cbiAgICAvKlxuICAgICAqIHdlJ3ZlIGluZGljYXRlZCB0aGF0IHRoZXJlIGlzIGEgaG9zdG5hbWUsXG4gICAgICogc28gZXZlbiBpZiBpdCdzIGVtcHR5LCBpdCBoYXMgdG8gYmUgcHJlc2VudC5cbiAgICAgKi9cbiAgICB0aGlzLmhvc3RuYW1lID0gdGhpcy5ob3N0bmFtZSB8fCAnJztcblxuICAgIC8qXG4gICAgICogaWYgaG9zdG5hbWUgYmVnaW5zIHdpdGggWyBhbmQgZW5kcyB3aXRoIF1cbiAgICAgKiBhc3N1bWUgdGhhdCBpdCdzIGFuIElQdjYgYWRkcmVzcy5cbiAgICAgKi9cbiAgICB2YXIgaXB2Nkhvc3RuYW1lID0gdGhpcy5ob3N0bmFtZVswXSA9PT0gJ1snICYmIHRoaXMuaG9zdG5hbWVbdGhpcy5ob3N0bmFtZS5sZW5ndGggLSAxXSA9PT0gJ10nO1xuXG4gICAgLy8gdmFsaWRhdGUgYSBsaXR0bGUuXG4gICAgaWYgKCFpcHY2SG9zdG5hbWUpIHtcbiAgICAgIHZhciBob3N0cGFydHMgPSB0aGlzLmhvc3RuYW1lLnNwbGl0KC9cXC4vKTtcbiAgICAgIGZvciAodmFyIGkgPSAwLCBsID0gaG9zdHBhcnRzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgICB2YXIgcGFydCA9IGhvc3RwYXJ0c1tpXTtcbiAgICAgICAgaWYgKCFwYXJ0KSB7IGNvbnRpbnVlOyB9XG4gICAgICAgIGlmICghcGFydC5tYXRjaChob3N0bmFtZVBhcnRQYXR0ZXJuKSkge1xuICAgICAgICAgIHZhciBuZXdwYXJ0ID0gJyc7XG4gICAgICAgICAgZm9yICh2YXIgaiA9IDAsIGsgPSBwYXJ0Lmxlbmd0aDsgaiA8IGs7IGorKykge1xuICAgICAgICAgICAgaWYgKHBhcnQuY2hhckNvZGVBdChqKSA+IDEyNykge1xuICAgICAgICAgICAgICAvKlxuICAgICAgICAgICAgICAgKiB3ZSByZXBsYWNlIG5vbi1BU0NJSSBjaGFyIHdpdGggYSB0ZW1wb3JhcnkgcGxhY2Vob2xkZXJcbiAgICAgICAgICAgICAgICogd2UgbmVlZCB0aGlzIHRvIG1ha2Ugc3VyZSBzaXplIG9mIGhvc3RuYW1lIGlzIG5vdFxuICAgICAgICAgICAgICAgKiBicm9rZW4gYnkgcmVwbGFjaW5nIG5vbi1BU0NJSSBieSBub3RoaW5nXG4gICAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgICBuZXdwYXJ0ICs9ICd4JztcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIG5ld3BhcnQgKz0gcGFydFtqXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gd2UgdGVzdCBhZ2FpbiB3aXRoIEFTQ0lJIGNoYXIgb25seVxuICAgICAgICAgIGlmICghbmV3cGFydC5tYXRjaChob3N0bmFtZVBhcnRQYXR0ZXJuKSkge1xuICAgICAgICAgICAgdmFyIHZhbGlkUGFydHMgPSBob3N0cGFydHMuc2xpY2UoMCwgaSk7XG4gICAgICAgICAgICB2YXIgbm90SG9zdCA9IGhvc3RwYXJ0cy5zbGljZShpICsgMSk7XG4gICAgICAgICAgICB2YXIgYml0ID0gcGFydC5tYXRjaChob3N0bmFtZVBhcnRTdGFydCk7XG4gICAgICAgICAgICBpZiAoYml0KSB7XG4gICAgICAgICAgICAgIHZhbGlkUGFydHMucHVzaChiaXRbMV0pO1xuICAgICAgICAgICAgICBub3RIb3N0LnVuc2hpZnQoYml0WzJdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChub3RIb3N0Lmxlbmd0aCkge1xuICAgICAgICAgICAgICByZXN0ID0gJy8nICsgbm90SG9zdC5qb2luKCcuJykgKyByZXN0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5ob3N0bmFtZSA9IHZhbGlkUGFydHMuam9pbignLicpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuaG9zdG5hbWUubGVuZ3RoID4gaG9zdG5hbWVNYXhMZW4pIHtcbiAgICAgIHRoaXMuaG9zdG5hbWUgPSAnJztcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gaG9zdG5hbWVzIGFyZSBhbHdheXMgbG93ZXIgY2FzZS5cbiAgICAgIHRoaXMuaG9zdG5hbWUgPSB0aGlzLmhvc3RuYW1lLnRvTG93ZXJDYXNlKCk7XG4gICAgfVxuXG4gICAgaWYgKCFpcHY2SG9zdG5hbWUpIHtcbiAgICAgIC8qXG4gICAgICAgKiBJRE5BIFN1cHBvcnQ6IFJldHVybnMgYSBwdW55Y29kZWQgcmVwcmVzZW50YXRpb24gb2YgXCJkb21haW5cIi5cbiAgICAgICAqIEl0IG9ubHkgY29udmVydHMgcGFydHMgb2YgdGhlIGRvbWFpbiBuYW1lIHRoYXRcbiAgICAgICAqIGhhdmUgbm9uLUFTQ0lJIGNoYXJhY3RlcnMsIGkuZS4gaXQgZG9lc24ndCBtYXR0ZXIgaWZcbiAgICAgICAqIHlvdSBjYWxsIGl0IHdpdGggYSBkb21haW4gdGhhdCBhbHJlYWR5IGlzIEFTQ0lJLW9ubHkuXG4gICAgICAgKi9cbiAgICAgIHRoaXMuaG9zdG5hbWUgPSBwdW55Y29kZS50b0FTQ0lJKHRoaXMuaG9zdG5hbWUpO1xuICAgIH1cblxuICAgIHZhciBwID0gdGhpcy5wb3J0ID8gJzonICsgdGhpcy5wb3J0IDogJyc7XG4gICAgdmFyIGggPSB0aGlzLmhvc3RuYW1lIHx8ICcnO1xuICAgIHRoaXMuaG9zdCA9IGggKyBwO1xuICAgIHRoaXMuaHJlZiArPSB0aGlzLmhvc3Q7XG5cbiAgICAvKlxuICAgICAqIHN0cmlwIFsgYW5kIF0gZnJvbSB0aGUgaG9zdG5hbWVcbiAgICAgKiB0aGUgaG9zdCBmaWVsZCBzdGlsbCByZXRhaW5zIHRoZW0sIHRob3VnaFxuICAgICAqL1xuICAgIGlmIChpcHY2SG9zdG5hbWUpIHtcbiAgICAgIHRoaXMuaG9zdG5hbWUgPSB0aGlzLmhvc3RuYW1lLnN1YnN0cigxLCB0aGlzLmhvc3RuYW1lLmxlbmd0aCAtIDIpO1xuICAgICAgaWYgKHJlc3RbMF0gIT09ICcvJykge1xuICAgICAgICByZXN0ID0gJy8nICsgcmVzdDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKlxuICAgKiBub3cgcmVzdCBpcyBzZXQgdG8gdGhlIHBvc3QtaG9zdCBzdHVmZi5cbiAgICogY2hvcCBvZmYgYW55IGRlbGltIGNoYXJzLlxuICAgKi9cbiAgaWYgKCF1bnNhZmVQcm90b2NvbFtsb3dlclByb3RvXSkge1xuXG4gICAgLypcbiAgICAgKiBGaXJzdCwgbWFrZSAxMDAlIHN1cmUgdGhhdCBhbnkgXCJhdXRvRXNjYXBlXCIgY2hhcnMgZ2V0XG4gICAgICogZXNjYXBlZCwgZXZlbiBpZiBlbmNvZGVVUklDb21wb25lbnQgZG9lc24ndCB0aGluayB0aGV5XG4gICAgICogbmVlZCB0byBiZS5cbiAgICAgKi9cbiAgICBmb3IgKHZhciBpID0gMCwgbCA9IGF1dG9Fc2NhcGUubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICB2YXIgYWUgPSBhdXRvRXNjYXBlW2ldO1xuICAgICAgaWYgKHJlc3QuaW5kZXhPZihhZSkgPT09IC0xKSB7IGNvbnRpbnVlOyB9XG4gICAgICB2YXIgZXNjID0gZW5jb2RlVVJJQ29tcG9uZW50KGFlKTtcbiAgICAgIGlmIChlc2MgPT09IGFlKSB7XG4gICAgICAgIGVzYyA9IGVzY2FwZShhZSk7XG4gICAgICB9XG4gICAgICByZXN0ID0gcmVzdC5zcGxpdChhZSkuam9pbihlc2MpO1xuICAgIH1cbiAgfVxuXG4gIC8vIGNob3Agb2ZmIGZyb20gdGhlIHRhaWwgZmlyc3QuXG4gIHZhciBoYXNoID0gcmVzdC5pbmRleE9mKCcjJyk7XG4gIGlmIChoYXNoICE9PSAtMSkge1xuICAgIC8vIGdvdCBhIGZyYWdtZW50IHN0cmluZy5cbiAgICB0aGlzLmhhc2ggPSByZXN0LnN1YnN0cihoYXNoKTtcbiAgICByZXN0ID0gcmVzdC5zbGljZSgwLCBoYXNoKTtcbiAgfVxuICB2YXIgcW0gPSByZXN0LmluZGV4T2YoJz8nKTtcbiAgaWYgKHFtICE9PSAtMSkge1xuICAgIHRoaXMuc2VhcmNoID0gcmVzdC5zdWJzdHIocW0pO1xuICAgIHRoaXMucXVlcnkgPSByZXN0LnN1YnN0cihxbSArIDEpO1xuICAgIGlmIChwYXJzZVF1ZXJ5U3RyaW5nKSB7XG4gICAgICB0aGlzLnF1ZXJ5ID0gcXVlcnlzdHJpbmcucGFyc2UodGhpcy5xdWVyeSk7XG4gICAgfVxuICAgIHJlc3QgPSByZXN0LnNsaWNlKDAsIHFtKTtcbiAgfSBlbHNlIGlmIChwYXJzZVF1ZXJ5U3RyaW5nKSB7XG4gICAgLy8gbm8gcXVlcnkgc3RyaW5nLCBidXQgcGFyc2VRdWVyeVN0cmluZyBzdGlsbCByZXF1ZXN0ZWRcbiAgICB0aGlzLnNlYXJjaCA9ICcnO1xuICAgIHRoaXMucXVlcnkgPSB7fTtcbiAgfVxuICBpZiAocmVzdCkgeyB0aGlzLnBhdGhuYW1lID0gcmVzdDsgfVxuICBpZiAoc2xhc2hlZFByb3RvY29sW2xvd2VyUHJvdG9dICYmIHRoaXMuaG9zdG5hbWUgJiYgIXRoaXMucGF0aG5hbWUpIHtcbiAgICB0aGlzLnBhdGhuYW1lID0gJy8nO1xuICB9XG5cbiAgLy8gdG8gc3VwcG9ydCBodHRwLnJlcXVlc3RcbiAgaWYgKHRoaXMucGF0aG5hbWUgfHwgdGhpcy5zZWFyY2gpIHtcbiAgICB2YXIgcCA9IHRoaXMucGF0aG5hbWUgfHwgJyc7XG4gICAgdmFyIHMgPSB0aGlzLnNlYXJjaCB8fCAnJztcbiAgICB0aGlzLnBhdGggPSBwICsgcztcbiAgfVxuXG4gIC8vIGZpbmFsbHksIHJlY29uc3RydWN0IHRoZSBocmVmIGJhc2VkIG9uIHdoYXQgaGFzIGJlZW4gdmFsaWRhdGVkLlxuICB0aGlzLmhyZWYgPSB0aGlzLmZvcm1hdCgpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8vIGZvcm1hdCBhIHBhcnNlZCBvYmplY3QgaW50byBhIHVybCBzdHJpbmdcbmZ1bmN0aW9uIHVybEZvcm1hdChvYmopIHtcbiAgLypcbiAgICogZW5zdXJlIGl0J3MgYW4gb2JqZWN0LCBhbmQgbm90IGEgc3RyaW5nIHVybC5cbiAgICogSWYgaXQncyBhbiBvYmosIHRoaXMgaXMgYSBuby1vcC5cbiAgICogdGhpcyB3YXksIHlvdSBjYW4gY2FsbCB1cmxfZm9ybWF0KCkgb24gc3RyaW5nc1xuICAgKiB0byBjbGVhbiB1cCBwb3RlbnRpYWxseSB3b25reSB1cmxzLlxuICAgKi9cbiAgaWYgKHR5cGVvZiBvYmogPT09ICdzdHJpbmcnKSB7IG9iaiA9IHVybFBhcnNlKG9iaik7IH1cbiAgaWYgKCEob2JqIGluc3RhbmNlb2YgVXJsKSkgeyByZXR1cm4gVXJsLnByb3RvdHlwZS5mb3JtYXQuY2FsbChvYmopOyB9XG4gIHJldHVybiBvYmouZm9ybWF0KCk7XG59XG5cblVybC5wcm90b3R5cGUuZm9ybWF0ID0gZnVuY3Rpb24gKCkge1xuICB2YXIgYXV0aCA9IHRoaXMuYXV0aCB8fCAnJztcbiAgaWYgKGF1dGgpIHtcbiAgICBhdXRoID0gZW5jb2RlVVJJQ29tcG9uZW50KGF1dGgpO1xuICAgIGF1dGggPSBhdXRoLnJlcGxhY2UoLyUzQS9pLCAnOicpO1xuICAgIGF1dGggKz0gJ0AnO1xuICB9XG5cbiAgdmFyIHByb3RvY29sID0gdGhpcy5wcm90b2NvbCB8fCAnJyxcbiAgICBwYXRobmFtZSA9IHRoaXMucGF0aG5hbWUgfHwgJycsXG4gICAgaGFzaCA9IHRoaXMuaGFzaCB8fCAnJyxcbiAgICBob3N0ID0gZmFsc2UsXG4gICAgcXVlcnkgPSAnJztcblxuICBpZiAodGhpcy5ob3N0KSB7XG4gICAgaG9zdCA9IGF1dGggKyB0aGlzLmhvc3Q7XG4gIH0gZWxzZSBpZiAodGhpcy5ob3N0bmFtZSkge1xuICAgIGhvc3QgPSBhdXRoICsgKHRoaXMuaG9zdG5hbWUuaW5kZXhPZignOicpID09PSAtMSA/IHRoaXMuaG9zdG5hbWUgOiAnWycgKyB0aGlzLmhvc3RuYW1lICsgJ10nKTtcbiAgICBpZiAodGhpcy5wb3J0KSB7XG4gICAgICBob3N0ICs9ICc6JyArIHRoaXMucG9ydDtcbiAgICB9XG4gIH1cblxuICBpZiAodGhpcy5xdWVyeSAmJiB0eXBlb2YgdGhpcy5xdWVyeSA9PT0gJ29iamVjdCcgJiYgT2JqZWN0LmtleXModGhpcy5xdWVyeSkubGVuZ3RoKSB7XG4gICAgcXVlcnkgPSBxdWVyeXN0cmluZy5zdHJpbmdpZnkodGhpcy5xdWVyeSwge1xuICAgICAgYXJyYXlGb3JtYXQ6ICdyZXBlYXQnLFxuICAgICAgYWRkUXVlcnlQcmVmaXg6IGZhbHNlXG4gICAgfSk7XG4gIH1cblxuICB2YXIgc2VhcmNoID0gdGhpcy5zZWFyY2ggfHwgKHF1ZXJ5ICYmICgnPycgKyBxdWVyeSkpIHx8ICcnO1xuXG4gIGlmIChwcm90b2NvbCAmJiBwcm90b2NvbC5zdWJzdHIoLTEpICE9PSAnOicpIHsgcHJvdG9jb2wgKz0gJzonOyB9XG5cbiAgLypcbiAgICogb25seSB0aGUgc2xhc2hlZFByb3RvY29scyBnZXQgdGhlIC8vLiAgTm90IG1haWx0bzosIHhtcHA6LCBldGMuXG4gICAqIHVubGVzcyB0aGV5IGhhZCB0aGVtIHRvIGJlZ2luIHdpdGguXG4gICAqL1xuICBpZiAodGhpcy5zbGFzaGVzIHx8ICghcHJvdG9jb2wgfHwgc2xhc2hlZFByb3RvY29sW3Byb3RvY29sXSkgJiYgaG9zdCAhPT0gZmFsc2UpIHtcbiAgICBob3N0ID0gJy8vJyArIChob3N0IHx8ICcnKTtcbiAgICBpZiAocGF0aG5hbWUgJiYgcGF0aG5hbWUuY2hhckF0KDApICE9PSAnLycpIHsgcGF0aG5hbWUgPSAnLycgKyBwYXRobmFtZTsgfVxuICB9IGVsc2UgaWYgKCFob3N0KSB7XG4gICAgaG9zdCA9ICcnO1xuICB9XG5cbiAgaWYgKGhhc2ggJiYgaGFzaC5jaGFyQXQoMCkgIT09ICcjJykgeyBoYXNoID0gJyMnICsgaGFzaDsgfVxuICBpZiAoc2VhcmNoICYmIHNlYXJjaC5jaGFyQXQoMCkgIT09ICc/JykgeyBzZWFyY2ggPSAnPycgKyBzZWFyY2g7IH1cblxuICBwYXRobmFtZSA9IHBhdGhuYW1lLnJlcGxhY2UoL1s/I10vZywgZnVuY3Rpb24gKG1hdGNoKSB7XG4gICAgcmV0dXJuIGVuY29kZVVSSUNvbXBvbmVudChtYXRjaCk7XG4gIH0pO1xuICBzZWFyY2ggPSBzZWFyY2gucmVwbGFjZSgnIycsICclMjMnKTtcblxuICByZXR1cm4gcHJvdG9jb2wgKyBob3N0ICsgcGF0aG5hbWUgKyBzZWFyY2ggKyBoYXNoO1xufTtcblxuZnVuY3Rpb24gdXJsUmVzb2x2ZShzb3VyY2UsIHJlbGF0aXZlKSB7XG4gIHJldHVybiB1cmxQYXJzZShzb3VyY2UsIGZhbHNlLCB0cnVlKS5yZXNvbHZlKHJlbGF0aXZlKTtcbn1cblxuVXJsLnByb3RvdHlwZS5yZXNvbHZlID0gZnVuY3Rpb24gKHJlbGF0aXZlKSB7XG4gIHJldHVybiB0aGlzLnJlc29sdmVPYmplY3QodXJsUGFyc2UocmVsYXRpdmUsIGZhbHNlLCB0cnVlKSkuZm9ybWF0KCk7XG59O1xuXG5mdW5jdGlvbiB1cmxSZXNvbHZlT2JqZWN0KHNvdXJjZSwgcmVsYXRpdmUpIHtcbiAgaWYgKCFzb3VyY2UpIHsgcmV0dXJuIHJlbGF0aXZlOyB9XG4gIHJldHVybiB1cmxQYXJzZShzb3VyY2UsIGZhbHNlLCB0cnVlKS5yZXNvbHZlT2JqZWN0KHJlbGF0aXZlKTtcbn1cblxuVXJsLnByb3RvdHlwZS5yZXNvbHZlT2JqZWN0ID0gZnVuY3Rpb24gKHJlbGF0aXZlKSB7XG4gIGlmICh0eXBlb2YgcmVsYXRpdmUgPT09ICdzdHJpbmcnKSB7XG4gICAgdmFyIHJlbCA9IG5ldyBVcmwoKTtcbiAgICByZWwucGFyc2UocmVsYXRpdmUsIGZhbHNlLCB0cnVlKTtcbiAgICByZWxhdGl2ZSA9IHJlbDtcbiAgfVxuXG4gIHZhciByZXN1bHQgPSBuZXcgVXJsKCk7XG4gIHZhciB0a2V5cyA9IE9iamVjdC5rZXlzKHRoaXMpO1xuICBmb3IgKHZhciB0ayA9IDA7IHRrIDwgdGtleXMubGVuZ3RoOyB0aysrKSB7XG4gICAgdmFyIHRrZXkgPSB0a2V5c1t0a107XG4gICAgcmVzdWx0W3RrZXldID0gdGhpc1t0a2V5XTtcbiAgfVxuXG4gIC8qXG4gICAqIGhhc2ggaXMgYWx3YXlzIG92ZXJyaWRkZW4sIG5vIG1hdHRlciB3aGF0LlxuICAgKiBldmVuIGhyZWY9XCJcIiB3aWxsIHJlbW92ZSBpdC5cbiAgICovXG4gIHJlc3VsdC5oYXNoID0gcmVsYXRpdmUuaGFzaDtcblxuICAvLyBpZiB0aGUgcmVsYXRpdmUgdXJsIGlzIGVtcHR5LCB0aGVuIHRoZXJlJ3Mgbm90aGluZyBsZWZ0IHRvIGRvIGhlcmUuXG4gIGlmIChyZWxhdGl2ZS5ocmVmID09PSAnJykge1xuICAgIHJlc3VsdC5ocmVmID0gcmVzdWx0LmZvcm1hdCgpO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvLyBocmVmcyBsaWtlIC8vZm9vL2JhciBhbHdheXMgY3V0IHRvIHRoZSBwcm90b2NvbC5cbiAgaWYgKHJlbGF0aXZlLnNsYXNoZXMgJiYgIXJlbGF0aXZlLnByb3RvY29sKSB7XG4gICAgLy8gdGFrZSBldmVyeXRoaW5nIGV4Y2VwdCB0aGUgcHJvdG9jb2wgZnJvbSByZWxhdGl2ZVxuICAgIHZhciBya2V5cyA9IE9iamVjdC5rZXlzKHJlbGF0aXZlKTtcbiAgICBmb3IgKHZhciByayA9IDA7IHJrIDwgcmtleXMubGVuZ3RoOyByaysrKSB7XG4gICAgICB2YXIgcmtleSA9IHJrZXlzW3JrXTtcbiAgICAgIGlmIChya2V5ICE9PSAncHJvdG9jb2wnKSB7IHJlc3VsdFtya2V5XSA9IHJlbGF0aXZlW3JrZXldOyB9XG4gICAgfVxuXG4gICAgLy8gdXJsUGFyc2UgYXBwZW5kcyB0cmFpbGluZyAvIHRvIHVybHMgbGlrZSBodHRwOi8vd3d3LmV4YW1wbGUuY29tXG4gICAgaWYgKHNsYXNoZWRQcm90b2NvbFtyZXN1bHQucHJvdG9jb2xdICYmIHJlc3VsdC5ob3N0bmFtZSAmJiAhcmVzdWx0LnBhdGhuYW1lKSB7XG4gICAgICByZXN1bHQucGF0aG5hbWUgPSAnLyc7XG4gICAgICByZXN1bHQucGF0aCA9IHJlc3VsdC5wYXRobmFtZTtcbiAgICB9XG5cbiAgICByZXN1bHQuaHJlZiA9IHJlc3VsdC5mb3JtYXQoKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgaWYgKHJlbGF0aXZlLnByb3RvY29sICYmIHJlbGF0aXZlLnByb3RvY29sICE9PSByZXN1bHQucHJvdG9jb2wpIHtcbiAgICAvKlxuICAgICAqIGlmIGl0J3MgYSBrbm93biB1cmwgcHJvdG9jb2wsIHRoZW4gY2hhbmdpbmdcbiAgICAgKiB0aGUgcHJvdG9jb2wgZG9lcyB3ZWlyZCB0aGluZ3NcbiAgICAgKiBmaXJzdCwgaWYgaXQncyBub3QgZmlsZTosIHRoZW4gd2UgTVVTVCBoYXZlIGEgaG9zdCxcbiAgICAgKiBhbmQgaWYgdGhlcmUgd2FzIGEgcGF0aFxuICAgICAqIHRvIGJlZ2luIHdpdGgsIHRoZW4gd2UgTVVTVCBoYXZlIGEgcGF0aC5cbiAgICAgKiBpZiBpdCBpcyBmaWxlOiwgdGhlbiB0aGUgaG9zdCBpcyBkcm9wcGVkLFxuICAgICAqIGJlY2F1c2UgdGhhdCdzIGtub3duIHRvIGJlIGhvc3RsZXNzLlxuICAgICAqIGFueXRoaW5nIGVsc2UgaXMgYXNzdW1lZCB0byBiZSBhYnNvbHV0ZS5cbiAgICAgKi9cbiAgICBpZiAoIXNsYXNoZWRQcm90b2NvbFtyZWxhdGl2ZS5wcm90b2NvbF0pIHtcbiAgICAgIHZhciBrZXlzID0gT2JqZWN0LmtleXMocmVsYXRpdmUpO1xuICAgICAgZm9yICh2YXIgdiA9IDA7IHYgPCBrZXlzLmxlbmd0aDsgdisrKSB7XG4gICAgICAgIHZhciBrID0ga2V5c1t2XTtcbiAgICAgICAgcmVzdWx0W2tdID0gcmVsYXRpdmVba107XG4gICAgICB9XG4gICAgICByZXN1bHQuaHJlZiA9IHJlc3VsdC5mb3JtYXQoKTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgcmVzdWx0LnByb3RvY29sID0gcmVsYXRpdmUucHJvdG9jb2w7XG4gICAgaWYgKCFyZWxhdGl2ZS5ob3N0ICYmICFob3N0bGVzc1Byb3RvY29sW3JlbGF0aXZlLnByb3RvY29sXSkge1xuICAgICAgdmFyIHJlbFBhdGggPSAocmVsYXRpdmUucGF0aG5hbWUgfHwgJycpLnNwbGl0KCcvJyk7XG4gICAgICB3aGlsZSAocmVsUGF0aC5sZW5ndGggJiYgIShyZWxhdGl2ZS5ob3N0ID0gcmVsUGF0aC5zaGlmdCgpKSkgeyB9XG4gICAgICBpZiAoIXJlbGF0aXZlLmhvc3QpIHsgcmVsYXRpdmUuaG9zdCA9ICcnOyB9XG4gICAgICBpZiAoIXJlbGF0aXZlLmhvc3RuYW1lKSB7IHJlbGF0aXZlLmhvc3RuYW1lID0gJyc7IH1cbiAgICAgIGlmIChyZWxQYXRoWzBdICE9PSAnJykgeyByZWxQYXRoLnVuc2hpZnQoJycpOyB9XG4gICAgICBpZiAocmVsUGF0aC5sZW5ndGggPCAyKSB7IHJlbFBhdGgudW5zaGlmdCgnJyk7IH1cbiAgICAgIHJlc3VsdC5wYXRobmFtZSA9IHJlbFBhdGguam9pbignLycpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXN1bHQucGF0aG5hbWUgPSByZWxhdGl2ZS5wYXRobmFtZTtcbiAgICB9XG4gICAgcmVzdWx0LnNlYXJjaCA9IHJlbGF0aXZlLnNlYXJjaDtcbiAgICByZXN1bHQucXVlcnkgPSByZWxhdGl2ZS5xdWVyeTtcbiAgICByZXN1bHQuaG9zdCA9IHJlbGF0aXZlLmhvc3QgfHwgJyc7XG4gICAgcmVzdWx0LmF1dGggPSByZWxhdGl2ZS5hdXRoO1xuICAgIHJlc3VsdC5ob3N0bmFtZSA9IHJlbGF0aXZlLmhvc3RuYW1lIHx8IHJlbGF0aXZlLmhvc3Q7XG4gICAgcmVzdWx0LnBvcnQgPSByZWxhdGl2ZS5wb3J0O1xuICAgIC8vIHRvIHN1cHBvcnQgaHR0cC5yZXF1ZXN0XG4gICAgaWYgKHJlc3VsdC5wYXRobmFtZSB8fCByZXN1bHQuc2VhcmNoKSB7XG4gICAgICB2YXIgcCA9IHJlc3VsdC5wYXRobmFtZSB8fCAnJztcbiAgICAgIHZhciBzID0gcmVzdWx0LnNlYXJjaCB8fCAnJztcbiAgICAgIHJlc3VsdC5wYXRoID0gcCArIHM7XG4gICAgfVxuICAgIHJlc3VsdC5zbGFzaGVzID0gcmVzdWx0LnNsYXNoZXMgfHwgcmVsYXRpdmUuc2xhc2hlcztcbiAgICByZXN1bHQuaHJlZiA9IHJlc3VsdC5mb3JtYXQoKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgdmFyIGlzU291cmNlQWJzID0gcmVzdWx0LnBhdGhuYW1lICYmIHJlc3VsdC5wYXRobmFtZS5jaGFyQXQoMCkgPT09ICcvJyxcbiAgICBpc1JlbEFicyA9IHJlbGF0aXZlLmhvc3QgfHwgcmVsYXRpdmUucGF0aG5hbWUgJiYgcmVsYXRpdmUucGF0aG5hbWUuY2hhckF0KDApID09PSAnLycsXG4gICAgbXVzdEVuZEFicyA9IGlzUmVsQWJzIHx8IGlzU291cmNlQWJzIHx8IChyZXN1bHQuaG9zdCAmJiByZWxhdGl2ZS5wYXRobmFtZSksXG4gICAgcmVtb3ZlQWxsRG90cyA9IG11c3RFbmRBYnMsXG4gICAgc3JjUGF0aCA9IHJlc3VsdC5wYXRobmFtZSAmJiByZXN1bHQucGF0aG5hbWUuc3BsaXQoJy8nKSB8fCBbXSxcbiAgICByZWxQYXRoID0gcmVsYXRpdmUucGF0aG5hbWUgJiYgcmVsYXRpdmUucGF0aG5hbWUuc3BsaXQoJy8nKSB8fCBbXSxcbiAgICBwc3ljaG90aWMgPSByZXN1bHQucHJvdG9jb2wgJiYgIXNsYXNoZWRQcm90b2NvbFtyZXN1bHQucHJvdG9jb2xdO1xuXG4gIC8qXG4gICAqIGlmIHRoZSB1cmwgaXMgYSBub24tc2xhc2hlZCB1cmwsIHRoZW4gcmVsYXRpdmVcbiAgICogbGlua3MgbGlrZSAuLi8uLiBzaG91bGQgYmUgYWJsZVxuICAgKiB0byBjcmF3bCB1cCB0byB0aGUgaG9zdG5hbWUsIGFzIHdlbGwuICBUaGlzIGlzIHN0cmFuZ2UuXG4gICAqIHJlc3VsdC5wcm90b2NvbCBoYXMgYWxyZWFkeSBiZWVuIHNldCBieSBub3cuXG4gICAqIExhdGVyIG9uLCBwdXQgdGhlIGZpcnN0IHBhdGggcGFydCBpbnRvIHRoZSBob3N0IGZpZWxkLlxuICAgKi9cbiAgaWYgKHBzeWNob3RpYykge1xuICAgIHJlc3VsdC5ob3N0bmFtZSA9ICcnO1xuICAgIHJlc3VsdC5wb3J0ID0gbnVsbDtcbiAgICBpZiAocmVzdWx0Lmhvc3QpIHtcbiAgICAgIGlmIChzcmNQYXRoWzBdID09PSAnJykgeyBzcmNQYXRoWzBdID0gcmVzdWx0Lmhvc3Q7IH0gZWxzZSB7IHNyY1BhdGgudW5zaGlmdChyZXN1bHQuaG9zdCk7IH1cbiAgICB9XG4gICAgcmVzdWx0Lmhvc3QgPSAnJztcbiAgICBpZiAocmVsYXRpdmUucHJvdG9jb2wpIHtcbiAgICAgIHJlbGF0aXZlLmhvc3RuYW1lID0gbnVsbDtcbiAgICAgIHJlbGF0aXZlLnBvcnQgPSBudWxsO1xuICAgICAgaWYgKHJlbGF0aXZlLmhvc3QpIHtcbiAgICAgICAgaWYgKHJlbFBhdGhbMF0gPT09ICcnKSB7IHJlbFBhdGhbMF0gPSByZWxhdGl2ZS5ob3N0OyB9IGVsc2UgeyByZWxQYXRoLnVuc2hpZnQocmVsYXRpdmUuaG9zdCk7IH1cbiAgICAgIH1cbiAgICAgIHJlbGF0aXZlLmhvc3QgPSBudWxsO1xuICAgIH1cbiAgICBtdXN0RW5kQWJzID0gbXVzdEVuZEFicyAmJiAocmVsUGF0aFswXSA9PT0gJycgfHwgc3JjUGF0aFswXSA9PT0gJycpO1xuICB9XG5cbiAgaWYgKGlzUmVsQWJzKSB7XG4gICAgLy8gaXQncyBhYnNvbHV0ZS5cbiAgICByZXN1bHQuaG9zdCA9IHJlbGF0aXZlLmhvc3QgfHwgcmVsYXRpdmUuaG9zdCA9PT0gJycgPyByZWxhdGl2ZS5ob3N0IDogcmVzdWx0Lmhvc3Q7XG4gICAgcmVzdWx0Lmhvc3RuYW1lID0gcmVsYXRpdmUuaG9zdG5hbWUgfHwgcmVsYXRpdmUuaG9zdG5hbWUgPT09ICcnID8gcmVsYXRpdmUuaG9zdG5hbWUgOiByZXN1bHQuaG9zdG5hbWU7XG4gICAgcmVzdWx0LnNlYXJjaCA9IHJlbGF0aXZlLnNlYXJjaDtcbiAgICByZXN1bHQucXVlcnkgPSByZWxhdGl2ZS5xdWVyeTtcbiAgICBzcmNQYXRoID0gcmVsUGF0aDtcbiAgICAvLyBmYWxsIHRocm91Z2ggdG8gdGhlIGRvdC1oYW5kbGluZyBiZWxvdy5cbiAgfSBlbHNlIGlmIChyZWxQYXRoLmxlbmd0aCkge1xuICAgIC8qXG4gICAgICogaXQncyByZWxhdGl2ZVxuICAgICAqIHRocm93IGF3YXkgdGhlIGV4aXN0aW5nIGZpbGUsIGFuZCB0YWtlIHRoZSBuZXcgcGF0aCBpbnN0ZWFkLlxuICAgICAqL1xuICAgIGlmICghc3JjUGF0aCkgeyBzcmNQYXRoID0gW107IH1cbiAgICBzcmNQYXRoLnBvcCgpO1xuICAgIHNyY1BhdGggPSBzcmNQYXRoLmNvbmNhdChyZWxQYXRoKTtcbiAgICByZXN1bHQuc2VhcmNoID0gcmVsYXRpdmUuc2VhcmNoO1xuICAgIHJlc3VsdC5xdWVyeSA9IHJlbGF0aXZlLnF1ZXJ5O1xuICB9IGVsc2UgaWYgKHJlbGF0aXZlLnNlYXJjaCAhPSBudWxsKSB7XG4gICAgLypcbiAgICAgKiBqdXN0IHB1bGwgb3V0IHRoZSBzZWFyY2guXG4gICAgICogbGlrZSBocmVmPSc/Zm9vJy5cbiAgICAgKiBQdXQgdGhpcyBhZnRlciB0aGUgb3RoZXIgdHdvIGNhc2VzIGJlY2F1c2UgaXQgc2ltcGxpZmllcyB0aGUgYm9vbGVhbnNcbiAgICAgKi9cbiAgICBpZiAocHN5Y2hvdGljKSB7XG4gICAgICByZXN1bHQuaG9zdCA9IHNyY1BhdGguc2hpZnQoKTtcbiAgICAgIHJlc3VsdC5ob3N0bmFtZSA9IHJlc3VsdC5ob3N0O1xuICAgICAgLypcbiAgICAgICAqIG9jY2F0aW9uYWx5IHRoZSBhdXRoIGNhbiBnZXQgc3R1Y2sgb25seSBpbiBob3N0XG4gICAgICAgKiB0aGlzIGVzcGVjaWFsbHkgaGFwcGVucyBpbiBjYXNlcyBsaWtlXG4gICAgICAgKiB1cmwucmVzb2x2ZU9iamVjdCgnbWFpbHRvOmxvY2FsMUBkb21haW4xJywgJ2xvY2FsMkBkb21haW4yJylcbiAgICAgICAqL1xuICAgICAgdmFyIGF1dGhJbkhvc3QgPSByZXN1bHQuaG9zdCAmJiByZXN1bHQuaG9zdC5pbmRleE9mKCdAJykgPiAwID8gcmVzdWx0Lmhvc3Quc3BsaXQoJ0AnKSA6IGZhbHNlO1xuICAgICAgaWYgKGF1dGhJbkhvc3QpIHtcbiAgICAgICAgcmVzdWx0LmF1dGggPSBhdXRoSW5Ib3N0LnNoaWZ0KCk7XG4gICAgICAgIHJlc3VsdC5ob3N0bmFtZSA9IGF1dGhJbkhvc3Quc2hpZnQoKTtcbiAgICAgICAgcmVzdWx0Lmhvc3QgPSByZXN1bHQuaG9zdG5hbWU7XG4gICAgICB9XG4gICAgfVxuICAgIHJlc3VsdC5zZWFyY2ggPSByZWxhdGl2ZS5zZWFyY2g7XG4gICAgcmVzdWx0LnF1ZXJ5ID0gcmVsYXRpdmUucXVlcnk7XG4gICAgLy8gdG8gc3VwcG9ydCBodHRwLnJlcXVlc3RcbiAgICBpZiAocmVzdWx0LnBhdGhuYW1lICE9PSBudWxsIHx8IHJlc3VsdC5zZWFyY2ggIT09IG51bGwpIHtcbiAgICAgIHJlc3VsdC5wYXRoID0gKHJlc3VsdC5wYXRobmFtZSA/IHJlc3VsdC5wYXRobmFtZSA6ICcnKSArIChyZXN1bHQuc2VhcmNoID8gcmVzdWx0LnNlYXJjaCA6ICcnKTtcbiAgICB9XG4gICAgcmVzdWx0LmhyZWYgPSByZXN1bHQuZm9ybWF0KCk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIGlmICghc3JjUGF0aC5sZW5ndGgpIHtcbiAgICAvKlxuICAgICAqIG5vIHBhdGggYXQgYWxsLiAgZWFzeS5cbiAgICAgKiB3ZSd2ZSBhbHJlYWR5IGhhbmRsZWQgdGhlIG90aGVyIHN0dWZmIGFib3ZlLlxuICAgICAqL1xuICAgIHJlc3VsdC5wYXRobmFtZSA9IG51bGw7XG4gICAgLy8gdG8gc3VwcG9ydCBodHRwLnJlcXVlc3RcbiAgICBpZiAocmVzdWx0LnNlYXJjaCkge1xuICAgICAgcmVzdWx0LnBhdGggPSAnLycgKyByZXN1bHQuc2VhcmNoO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXN1bHQucGF0aCA9IG51bGw7XG4gICAgfVxuICAgIHJlc3VsdC5ocmVmID0gcmVzdWx0LmZvcm1hdCgpO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKlxuICAgKiBpZiBhIHVybCBFTkRzIGluIC4gb3IgLi4sIHRoZW4gaXQgbXVzdCBnZXQgYSB0cmFpbGluZyBzbGFzaC5cbiAgICogaG93ZXZlciwgaWYgaXQgZW5kcyBpbiBhbnl0aGluZyBlbHNlIG5vbi1zbGFzaHksXG4gICAqIHRoZW4gaXQgbXVzdCBOT1QgZ2V0IGEgdHJhaWxpbmcgc2xhc2guXG4gICAqL1xuICB2YXIgbGFzdCA9IHNyY1BhdGguc2xpY2UoLTEpWzBdO1xuICB2YXIgaGFzVHJhaWxpbmdTbGFzaCA9IChyZXN1bHQuaG9zdCB8fCByZWxhdGl2ZS5ob3N0IHx8IHNyY1BhdGgubGVuZ3RoID4gMSkgJiYgKGxhc3QgPT09ICcuJyB8fCBsYXN0ID09PSAnLi4nKSB8fCBsYXN0ID09PSAnJztcblxuICAvKlxuICAgKiBzdHJpcCBzaW5nbGUgZG90cywgcmVzb2x2ZSBkb3VibGUgZG90cyB0byBwYXJlbnQgZGlyXG4gICAqIGlmIHRoZSBwYXRoIHRyaWVzIHRvIGdvIGFib3ZlIHRoZSByb290LCBgdXBgIGVuZHMgdXAgPiAwXG4gICAqL1xuICB2YXIgdXAgPSAwO1xuICBmb3IgKHZhciBpID0gc3JjUGF0aC5sZW5ndGg7IGkgPj0gMDsgaS0tKSB7XG4gICAgbGFzdCA9IHNyY1BhdGhbaV07XG4gICAgaWYgKGxhc3QgPT09ICcuJykge1xuICAgICAgc3JjUGF0aC5zcGxpY2UoaSwgMSk7XG4gICAgfSBlbHNlIGlmIChsYXN0ID09PSAnLi4nKSB7XG4gICAgICBzcmNQYXRoLnNwbGljZShpLCAxKTtcbiAgICAgIHVwKys7XG4gICAgfSBlbHNlIGlmICh1cCkge1xuICAgICAgc3JjUGF0aC5zcGxpY2UoaSwgMSk7XG4gICAgICB1cC0tO1xuICAgIH1cbiAgfVxuXG4gIC8vIGlmIHRoZSBwYXRoIGlzIGFsbG93ZWQgdG8gZ28gYWJvdmUgdGhlIHJvb3QsIHJlc3RvcmUgbGVhZGluZyAuLnNcbiAgaWYgKCFtdXN0RW5kQWJzICYmICFyZW1vdmVBbGxEb3RzKSB7XG4gICAgZm9yICg7IHVwLS07IHVwKSB7XG4gICAgICBzcmNQYXRoLnVuc2hpZnQoJy4uJyk7XG4gICAgfVxuICB9XG5cbiAgaWYgKG11c3RFbmRBYnMgJiYgc3JjUGF0aFswXSAhPT0gJycgJiYgKCFzcmNQYXRoWzBdIHx8IHNyY1BhdGhbMF0uY2hhckF0KDApICE9PSAnLycpKSB7XG4gICAgc3JjUGF0aC51bnNoaWZ0KCcnKTtcbiAgfVxuXG4gIGlmIChoYXNUcmFpbGluZ1NsYXNoICYmIChzcmNQYXRoLmpvaW4oJy8nKS5zdWJzdHIoLTEpICE9PSAnLycpKSB7XG4gICAgc3JjUGF0aC5wdXNoKCcnKTtcbiAgfVxuXG4gIHZhciBpc0Fic29sdXRlID0gc3JjUGF0aFswXSA9PT0gJycgfHwgKHNyY1BhdGhbMF0gJiYgc3JjUGF0aFswXS5jaGFyQXQoMCkgPT09ICcvJyk7XG5cbiAgLy8gcHV0IHRoZSBob3N0IGJhY2tcbiAgaWYgKHBzeWNob3RpYykge1xuICAgIHJlc3VsdC5ob3N0bmFtZSA9IGlzQWJzb2x1dGUgPyAnJyA6IHNyY1BhdGgubGVuZ3RoID8gc3JjUGF0aC5zaGlmdCgpIDogJyc7XG4gICAgcmVzdWx0Lmhvc3QgPSByZXN1bHQuaG9zdG5hbWU7XG4gICAgLypcbiAgICAgKiBvY2NhdGlvbmFseSB0aGUgYXV0aCBjYW4gZ2V0IHN0dWNrIG9ubHkgaW4gaG9zdFxuICAgICAqIHRoaXMgZXNwZWNpYWxseSBoYXBwZW5zIGluIGNhc2VzIGxpa2VcbiAgICAgKiB1cmwucmVzb2x2ZU9iamVjdCgnbWFpbHRvOmxvY2FsMUBkb21haW4xJywgJ2xvY2FsMkBkb21haW4yJylcbiAgICAgKi9cbiAgICB2YXIgYXV0aEluSG9zdCA9IHJlc3VsdC5ob3N0ICYmIHJlc3VsdC5ob3N0LmluZGV4T2YoJ0AnKSA+IDAgPyByZXN1bHQuaG9zdC5zcGxpdCgnQCcpIDogZmFsc2U7XG4gICAgaWYgKGF1dGhJbkhvc3QpIHtcbiAgICAgIHJlc3VsdC5hdXRoID0gYXV0aEluSG9zdC5zaGlmdCgpO1xuICAgICAgcmVzdWx0Lmhvc3RuYW1lID0gYXV0aEluSG9zdC5zaGlmdCgpO1xuICAgICAgcmVzdWx0Lmhvc3QgPSByZXN1bHQuaG9zdG5hbWU7XG4gICAgfVxuICB9XG5cbiAgbXVzdEVuZEFicyA9IG11c3RFbmRBYnMgfHwgKHJlc3VsdC5ob3N0ICYmIHNyY1BhdGgubGVuZ3RoKTtcblxuICBpZiAobXVzdEVuZEFicyAmJiAhaXNBYnNvbHV0ZSkge1xuICAgIHNyY1BhdGgudW5zaGlmdCgnJyk7XG4gIH1cblxuICBpZiAoc3JjUGF0aC5sZW5ndGggPiAwKSB7XG4gICAgcmVzdWx0LnBhdGhuYW1lID0gc3JjUGF0aC5qb2luKCcvJyk7XG4gIH0gZWxzZSB7XG4gICAgcmVzdWx0LnBhdGhuYW1lID0gbnVsbDtcbiAgICByZXN1bHQucGF0aCA9IG51bGw7XG4gIH1cblxuICAvLyB0byBzdXBwb3J0IHJlcXVlc3QuaHR0cFxuICBpZiAocmVzdWx0LnBhdGhuYW1lICE9PSBudWxsIHx8IHJlc3VsdC5zZWFyY2ggIT09IG51bGwpIHtcbiAgICByZXN1bHQucGF0aCA9IChyZXN1bHQucGF0aG5hbWUgPyByZXN1bHQucGF0aG5hbWUgOiAnJykgKyAocmVzdWx0LnNlYXJjaCA/IHJlc3VsdC5zZWFyY2ggOiAnJyk7XG4gIH1cbiAgcmVzdWx0LmF1dGggPSByZWxhdGl2ZS5hdXRoIHx8IHJlc3VsdC5hdXRoO1xuICByZXN1bHQuc2xhc2hlcyA9IHJlc3VsdC5zbGFzaGVzIHx8IHJlbGF0aXZlLnNsYXNoZXM7XG4gIHJlc3VsdC5ocmVmID0gcmVzdWx0LmZvcm1hdCgpO1xuICByZXR1cm4gcmVzdWx0O1xufTtcblxuVXJsLnByb3RvdHlwZS5wYXJzZUhvc3QgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBob3N0ID0gdGhpcy5ob3N0O1xuICB2YXIgcG9ydCA9IHBvcnRQYXR0ZXJuLmV4ZWMoaG9zdCk7XG4gIGlmIChwb3J0KSB7XG4gICAgcG9ydCA9IHBvcnRbMF07XG4gICAgaWYgKHBvcnQgIT09ICc6Jykge1xuICAgICAgdGhpcy5wb3J0ID0gcG9ydC5zdWJzdHIoMSk7XG4gICAgfVxuICAgIGhvc3QgPSBob3N0LnN1YnN0cigwLCBob3N0Lmxlbmd0aCAtIHBvcnQubGVuZ3RoKTtcbiAgfVxuICBpZiAoaG9zdCkgeyB0aGlzLmhvc3RuYW1lID0gaG9zdDsgfVxufTtcblxuZXhwb3J0cy5wYXJzZSA9IHVybFBhcnNlO1xuZXhwb3J0cy5yZXNvbHZlID0gdXJsUmVzb2x2ZTtcbmV4cG9ydHMucmVzb2x2ZU9iamVjdCA9IHVybFJlc29sdmVPYmplY3Q7XG5leHBvcnRzLmZvcm1hdCA9IHVybEZvcm1hdDtcblxuZXhwb3J0cy5VcmwgPSBVcmw7XG4iLCJcbi8qKlxuICogTW9kdWxlIGV4cG9ydHMuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBkZXByZWNhdGU7XG5cbi8qKlxuICogTWFyayB0aGF0IGEgbWV0aG9kIHNob3VsZCBub3QgYmUgdXNlZC5cbiAqIFJldHVybnMgYSBtb2RpZmllZCBmdW5jdGlvbiB3aGljaCB3YXJucyBvbmNlIGJ5IGRlZmF1bHQuXG4gKlxuICogSWYgYGxvY2FsU3RvcmFnZS5ub0RlcHJlY2F0aW9uID0gdHJ1ZWAgaXMgc2V0LCB0aGVuIGl0IGlzIGEgbm8tb3AuXG4gKlxuICogSWYgYGxvY2FsU3RvcmFnZS50aHJvd0RlcHJlY2F0aW9uID0gdHJ1ZWAgaXMgc2V0LCB0aGVuIGRlcHJlY2F0ZWQgZnVuY3Rpb25zXG4gKiB3aWxsIHRocm93IGFuIEVycm9yIHdoZW4gaW52b2tlZC5cbiAqXG4gKiBJZiBgbG9jYWxTdG9yYWdlLnRyYWNlRGVwcmVjYXRpb24gPSB0cnVlYCBpcyBzZXQsIHRoZW4gZGVwcmVjYXRlZCBmdW5jdGlvbnNcbiAqIHdpbGwgaW52b2tlIGBjb25zb2xlLnRyYWNlKClgIGluc3RlYWQgb2YgYGNvbnNvbGUuZXJyb3IoKWAuXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gLSB0aGUgZnVuY3Rpb24gdG8gZGVwcmVjYXRlXG4gKiBAcGFyYW0ge1N0cmluZ30gbXNnIC0gdGhlIHN0cmluZyB0byBwcmludCB0byB0aGUgY29uc29sZSB3aGVuIGBmbmAgaXMgaW52b2tlZFxuICogQHJldHVybnMge0Z1bmN0aW9ufSBhIG5ldyBcImRlcHJlY2F0ZWRcIiB2ZXJzaW9uIG9mIGBmbmBcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gZGVwcmVjYXRlIChmbiwgbXNnKSB7XG4gIGlmIChjb25maWcoJ25vRGVwcmVjYXRpb24nKSkge1xuICAgIHJldHVybiBmbjtcbiAgfVxuXG4gIHZhciB3YXJuZWQgPSBmYWxzZTtcbiAgZnVuY3Rpb24gZGVwcmVjYXRlZCgpIHtcbiAgICBpZiAoIXdhcm5lZCkge1xuICAgICAgaWYgKGNvbmZpZygndGhyb3dEZXByZWNhdGlvbicpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihtc2cpO1xuICAgICAgfSBlbHNlIGlmIChjb25maWcoJ3RyYWNlRGVwcmVjYXRpb24nKSkge1xuICAgICAgICBjb25zb2xlLnRyYWNlKG1zZyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zb2xlLndhcm4obXNnKTtcbiAgICAgIH1cbiAgICAgIHdhcm5lZCA9IHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICB9XG5cbiAgcmV0dXJuIGRlcHJlY2F0ZWQ7XG59XG5cbi8qKlxuICogQ2hlY2tzIGBsb2NhbFN0b3JhZ2VgIGZvciBib29sZWFuIHZhbHVlcyBmb3IgdGhlIGdpdmVuIGBuYW1lYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZVxuICogQHJldHVybnMge0Jvb2xlYW59XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBjb25maWcgKG5hbWUpIHtcbiAgLy8gYWNjZXNzaW5nIGdsb2JhbC5sb2NhbFN0b3JhZ2UgY2FuIHRyaWdnZXIgYSBET01FeGNlcHRpb24gaW4gc2FuZGJveGVkIGlmcmFtZXNcbiAgdHJ5IHtcbiAgICBpZiAoIWdsb2JhbC5sb2NhbFN0b3JhZ2UpIHJldHVybiBmYWxzZTtcbiAgfSBjYXRjaCAoXykge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICB2YXIgdmFsID0gZ2xvYmFsLmxvY2FsU3RvcmFnZVtuYW1lXTtcbiAgaWYgKG51bGwgPT0gdmFsKSByZXR1cm4gZmFsc2U7XG4gIHJldHVybiBTdHJpbmcodmFsKS50b0xvd2VyQ2FzZSgpID09PSAndHJ1ZSc7XG59XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGV4dGVuZFxuXG52YXIgaGFzT3duUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuXG5mdW5jdGlvbiBleHRlbmQoKSB7XG4gICAgdmFyIHRhcmdldCA9IHt9XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldXG5cbiAgICAgICAgZm9yICh2YXIga2V5IGluIHNvdXJjZSkge1xuICAgICAgICAgICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwoc291cmNlLCBrZXkpKSB7XG4gICAgICAgICAgICAgICAgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRhcmdldFxufVxuIl19