homebridge-homeconnect
Version:
A Homebridge plugin that connects Home Connect appliances to Apple HomeKit
15,537 lines • 1.47 MB
JavaScript
(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-08-21T06:20:54.626Z
// 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-08-21T06:20:54.627Z
// 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-08-21T06:20:54.629Z
// 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, '"');
}
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, isFlatArrayValue) {
if (val && typeof val === 'string' && options.comma && val.indexOf(',') > -1) {
if (isFlatArrayValue && options.throwOnLimitExceeded) {
var commaCount = 0;
var commaIndex = val.indexOf(',');
while (commaIndex > -1) {
commaCount += 1;
if (commaCount >= options.arrayLimit) {
throw new RangeError('Array limit exceeded. Only ' + options.arrayLimit + ' element' + (options.arrayLimit === 1 ? '' : 's') + ' allowed in an array.');
}
commaIndex = val.indexOf(',', commaIndex + 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('✓')
// 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,
part.indexOf('[]=') === -1
),
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) {
val = utils.combine([], val, options.arrayLimit, options.plainObjects, options.throwOnLimitExceeded);
}
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,
options.throwOnLimitExceeded
);
} 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,
options.throwOnLimitExceeded
);
}
} 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('✓'), 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 defineProperty = require('es-define-property');
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 setProperty = function setProperty(obj, key, value) {
if (key === '__proto__' && defineProperty) {
defineProperty(obj, key, {
configurable: true,
enumerable: true,
value: value,
writable: true
});
} else {
obj[key] = value;
}
};
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) {
if (options.throwOnLimitExceeded) {
throw new RangeError('Array limit exceeded. Only ' + options.arrayLimit + ' element' + (options.arrayLimit === 1 ? '' : 's') + ' allowed in an array.');
}
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) {
if (options.throwOnLimitExceeded) {
throw new RangeError('Array limit exceeded. Only ' + options.arrayLimit + ' element' + (options.arrayLimit === 1 ? '' : 's') + ' allowed in an array.');
}
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;
}
});
if (options && typeof options.arrayLimit === 'number' && target.length > options.arrayLimit) {
if (options.throwOnLimitExceeded) {
throw new RangeError('Array limit exceeded. Only ' + options.arrayLimit + ' element' + (options.arrayLimit === 1 ? '' : 's') + ' allowed in an array.');
}
return markOverflow(arrayToObject(target, options), target.length - 1);
}
return target;
}
return Object.keys(source).reduce(function (acc, key) {
var value = source[key];
if (has.call(acc, key)) {
setProperty(acc, key, merge(acc[key], value, options));
} else {
setProperty(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) {
setProperty(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;
if (j + limit < string.length) {
var last = segment.charCodeAt(segment.length - 1);
if (last >= 0xD800 && last <= 0xDBFF) {
segment = segment.slice(0, -1);
j -= 1;
}
}
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 = getSideChannel();
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.has(val)) {
queue[queue.length] = { obj: obj, prop: key };
refs.set(val, true);
}
}
}
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, throwOnLimitExceeded) {
// If 'a' is already an overflow object, add to it
if (isOverflow(a)) {
if (throwOnLimitExceeded) {
throw new RangeError('Array limit exceeded. Only ' + arrayLimit + ' element' + (arrayLimit === 1 ? '' : 's') + ' allowed in an array.');
}
var newIndex = getMaxIndex(a) + 1;
a[newIndex] = b;
setMaxIndex(a, newIndex);
return a;
}
var result = [].concat(a, b);
if (result.length > arrayLimit) {
if (throwOnLimitExceeded) {
throw new RangeError('Array limit exceeded. Only ' + arrayLimit + ' element' + (arrayLimit === 1 ? '' : 's') + ' allowed in an array.');
}
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,"es-define-property":34,"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)) {
var keyDesc = key && Object(key) === key ? 'the given object key' : inspect(key);
throw new $TypeError('Side channel does not contain ' + keyDesc);
}
},
'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);
}
};
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,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJkaXN0L2FwaS1lcnJvcnMuanMiLCJkaXN0L2hvbWVicmlkZ2UtdWkvcHVibGljL2FwaS1zdGF0dXMuanMiLCJkaXN0L2hvbWVicmlkZ2UtdWkvcHVibGljL2NhcmRzLmpzIiwiZGlzdC9ob21lYnJpZGdlLXVpL3B1YmxpYy9jbGllbnQtY2xpZW50aWQuanMiLCJkaXN0L2hvbWVicmlkZ2UtdWkvcHVibGljL2NsaWVudC1pcGMuanMiLCJkaXN0L2hvbWVicmlkZ2UtdWkvcHVibGljL2NsaWVudC5qcyIsImRpc3QvaG9tZWJyaWRnZS11aS9wdWJsaWMvY29uZmlnLmpzIiwiZGlzdC9ob21lYnJpZGdlLXVpL3B1YmxpYy9mb3Jtcy5qcyIsImRpc3QvaG9tZWJyaWRnZS11aS9wdWJsaWMvbG9nZ2VyLmpzIiwiZGlzdC9ob21lYnJpZGdlLXVpL3B1YmxpYy91dGlscy1kb20uanMiLCJkaXN0L2xvZy1lcnJvci5qcyIsImRpc3QvdGkvYXBpLWF1dGgtdHlwZXMtdGkuanMiLCJkaXN0L3RpL2FwaS1hdXRoLXR5cGVzLmpzIiwiZGlzdC90aS9hcGktdHlwZXMtdGkuanMiLCJkaXN0L3RpL2FwaS10eXBlcy5qcyIsImRpc3QvdGkvY29uZmlnLXR5cGVzLXRpLmpzIiwiZGlzdC90aS9jb25maWctdHlwZXMuanMiLCJkaXN0L3V0aWxzLmpzIiwibm9kZV9tb2R1bGVzL2Fzc2VydC9hc3NlcnQuanMiLCJub2RlX21vZHVsZXMvYXNzZXJ0L25vZGVfbW9kdWxlcy9pbmhlcml0cy9pbmhlcml0c19icm93c2VyLmpzIiwibm9kZV9tb2R1bGVzL2Fzc2VydC9ub2RlX21vZHVsZXMvdXRpbC9zdXBwb3J0L2lzQnVmZmVyQnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9hc3NlcnQvbm9kZV9tb2R1bGVzL3V0aWwvdXRpbC5qcyIsIm5vZGVfbW9kdWxlcy9iYXNlNjQtanMvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnJvd3Nlci1yZXNvbHZlL2VtcHR5LmpzIiwibm9kZV9tb2R1bGVzL2J1ZmZlci9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9idWlsdGluLXN0YXR1cy1jb2Rlcy9icm93c2VyLmpzIiwibm9kZV9tb2R1bGVzL2NhbGwtYmluZC1hcHBseS1oZWxwZXJzL2FjdHVhbEFwcGx5LmpzIiwibm9kZV9tb2R1bGVzL2NhbGwtYmluZC1hcHBseS1oZWxwZXJzL2Z1bmN0aW9uQXBwbHkuanMiLCJub2RlX21vZHVsZXMvY2FsbC1iaW5kLWFwcGx5LWhlbHBlcnMvZnVuY3Rpb25DYWxsLmpzIiwibm9kZV9tb2R1bGVzL2NhbGwtYmluZC1hcHBseS1oZWxwZXJzL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2NhbGwtYmluZC1hcHBseS1oZWxwZXJzL3JlZmxlY3RBcHBseS5qcyIsIm5vZGVfbW9kdWxlcy9jYWxsLWJvdW5kL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2R1bmRlci1wcm90by9nZXQuanMiLCJub2RlX21vZHVsZXMvZXMtZGVmaW5lLXByb3BlcnR5L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2VzLWVycm9ycy9ldmFsLmpzIiwibm9kZV9tb2R1bGVzL2VzLWVycm9ycy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9lcy1lcnJvcnMvcmFuZ2UuanMiLCJub2RlX21vZHVsZXMvZXMtZXJyb3JzL3JlZi5qcyIsIm5vZGVfbW9kdWxlcy9lcy1lcnJvcnMvc3ludGF4LmpzIiwibm9kZV9tb2R1bGVzL2VzLWVycm9ycy90eXBlLmpzIiwibm9kZV9tb2R1bGVzL2VzLWVycm9ycy91cmkuanMiLCJub2RlX21vZHVsZXMvZXMtb2JqZWN0LWF0b21zL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2V2ZW50cy9ldmVudHMuanMiLCJub2RlX21vZHVsZXMvZnVuY3Rpb24tYmluZC9pbXBsZW1lbnRhdGlvbi5qcyIsIm5vZGVfbW9kdWxlcy9mdW5jdGlvbi1iaW5kL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2dldC1pbnRyaW5zaWMvaW5kZXguanMiLCJub2RlX21vZHVsZXMvZ2V0LXByb3RvL09iamVjdC5nZXRQcm90b3R5cGVPZi5qcyIsIm5vZGVfbW9kdWxlcy9nZXQtcHJvdG8vUmVmbGVjdC5nZXRQcm90b3R5cGVPZi5qcyIsIm5vZGVfbW9kdWxlcy9nZXQtcHJvdG8vaW5kZXguanMiLCJub2RlX21vZHVsZXMvZ29wZC9nT1BELmpzIiwibm9kZV9tb2R1bGVzL2dvcGQvaW5kZXguanMiLCJub2RlX21vZHVsZXMvaGFzLXN5bWJvbHMvaW5kZXguanMiLCJub2RlX21vZHVsZXMvaGFzLXN5bWJvbHMvc2hhbXMuanMiLCJub2RlX21vZHVsZXMvaGFzb3duL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2llZWU3NTQvaW5kZXguanMiLCJub2RlX21vZHVsZXMvaW5oZXJpdHMvaW5oZXJpdHNfYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9tYXRoLWludHJpbnNpY3MvYWJzLmpzIiwibm9kZV9tb2R1bGVzL21hdGgtaW50cmluc2ljcy9mbG9vci5qcyIsIm5vZGVfbW9kdWxlcy9tYXRoLWludHJpbnNpY3MvaXNOYU4uanMiLCJub2RlX21vZHVsZXMvbWF0aC1pbnRyaW5zaWNzL21heC5qcyIsIm5vZGVfbW9kdWxlcy9tYXRoLWludHJpbnNpY3MvbWluLmpzIiwibm9kZV9tb2R1bGVzL21hdGgtaW50cmluc2ljcy9wb3cuanMiLCJub2RlX21vZHVsZXMvbWF0aC1pbnRyaW5zaWNzL3JvdW5kLmpzIiwibm9kZV9tb2R1bGVzL21hdGgtaW50cmluc2ljcy9zaWduLmpzIiwibm9kZV9tb2R1bGVzL29iamVjdC1pbnNwZWN0L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL29iamVjdC1rZXlzL2ltcGxlbWVudGF0aW9uLmpzIiwibm9kZV9tb2R1bGVzL29iamVjdC1rZXlzL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL29iamVjdC1rZXlzL2lzQXJndW1lbnRzLmpzIiwibm9kZV9tb2R1bGVzL29iamVjdC5hc3NpZ24vaW1wbGVtZW50YXRpb24uanMiLCJub2RlX21vZHVsZXMvb2JqZWN0LmFzc2lnbi9wb2x5ZmlsbC5qcyIsIm5vZGVfbW9kdWxlcy9wcm9jZXNzL2Jyb3dzZXIuanMiLCJub2RlX21vZHVsZXMvcHVueWNvZGUvcHVueWNvZGUuanMiLCJub2RlX21vZHVsZXMvcXMvbGliL2Zvcm1hdHMuanMiLCJub2RlX21vZHVsZXMvcXMvbGliL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL3FzL2xpYi9wYXJzZS5qcyIsIm5vZGVfbW9kdWxlcy9xcy9saWIvc3RyaW5naWZ5LmpzIiwibm9kZV9tb2R1bGVzL3FzL2xpYi91dGlscy5qcyIsIm5vZGVfbW9kdWxlcy9zYWZlLWJ1ZmZlci9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9zaWRlLWNoYW5uZWwtbGlzdC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9zaWRlLWNoYW5uZWwtbWFwL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL3NpZGUtY2hhbm5lbC13ZWFrbWFwL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL3NpZGUtY2hhbm5lbC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9zdHJlYW0taHR0cC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9zdHJlYW0taHR0cC9saWIvY2FwYWJpbGl0eS5qcyIsIm5vZGVfbW9kdWxlcy9zdHJlYW0taHR0cC9saWIvcmVxdWVzdC5qcyIsIm5vZGVfbW9kdWxlcy9zdHJlYW0taHR0cC9saWIvcmVzcG9uc2UuanMiLCJub2RlX21vZHVsZXMvc3RyZWFtLWh0dHAvbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9lcnJvcnMtYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9zdHJlYW0taHR0cC9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9fc3RyZWFtX2R1cGxleC5qcyIsIm5vZGVfbW9kdWxlcy9zdHJlYW0taHR0cC9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9fc3RyZWFtX3Bhc3N0aHJvdWdoLmpzIiwibm9kZV9tb2R1bGVzL3N0cmVhbS1odHRwL25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vbGliL19zdHJlYW1fcmVhZGFibGUuanMiLCJub2RlX21vZHVsZXMvc3RyZWFtLWh0dHAvbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvX3N0cmVhbV90cmFuc2Zvcm0uanMiLCJub2RlX21vZHVsZXMvc3RyZWFtLWh0dHAvbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvX3N0cmVhbV93cml0YWJsZS5qcyIsIm5vZGVfbW9kdWxlcy9zdHJlYW0taHR0cC9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9pbnRlcm5hbC9zdHJlYW1zL2FzeW5jX2l0ZXJhdG9yLmpzIiwibm9kZV9tb2R1bGVzL3N0cmVhbS1odHRwL25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vbGliL2ludGVybmFsL3N0cmVhbXMvYnVmZmVyX2xpc3QuanMiLCJub2RlX21vZHVsZXMvc3RyZWFtLWh0dHAvbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvaW50ZXJuYWwvc3RyZWFtcy9kZXN0cm95LmpzIiwibm9kZV9tb2R1bGVzL3N0cmVhbS1odHRwL25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vbGliL2ludGVybmFsL3N0cmVhbXMvZW5kLW9mLXN0cmVhbS5qcyIsIm5vZGVfbW9kdWxlcy9zdHJlYW0taHR0cC9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9pbnRlcm5hbC9zdHJlYW1zL2Zyb20tYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9zdHJlYW0taHR0cC9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9pbnRlcm5hbC9zdHJlYW1zL3BpcGVsaW5lLmpzIiwibm9kZV9tb2R1bGVzL3N0cmVhbS1odHRwL25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vbGliL2ludGVybmFsL3N0cmVhbXMvc3RhdGUuanMiLCJub2RlX21vZHVsZXMvc3RyZWFtLWh0dHAvbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvaW50ZXJuYWwvc3RyZWFtcy9zdHJlYW0tYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9zdHJlYW0taHR0cC9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL3JlYWRhYmxlLWJyb3dzZXIuanMiLCJub2RlX21vZHVsZXMvc3RyaW5nX2RlY29kZXIvbGliL3N0cmluZ19kZWNvZGVyLmpzIiwibm9kZV9tb2R1bGVzL3RzLWludGVyZmFjZS1jaGVja2VyL2Rpc3QvaW5kZXguanMiLCJub2RlX21vZHVsZXMvdHMtaW50ZXJmYWNlLWNoZWNrZXIvZGlzdC90eXBlcy5qcyIsIm5vZGVfbW9kdWxlcy90cy1pbnRlcmZhY2UtY2hlY2tlci9kaXN0L3V0aWwuanMiLCJub2RlX21vZHVsZXMvdXJsL3VybC5qcyIsIm5vZGVfbW9kdWxlcy91dGlsLWRlcHJlY2F0ZS9icm93c2VyLmpzIiwibm9kZV9tb2R1bGVzL3h0ZW5kL2ltbXV0YWJsZS5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3SEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1S0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4VEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUN6S0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDMWZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUNMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDMWtCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0SkE7OztBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUNqdkRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEVBLFlBQVk7O0FBRVosSUFBSSxJQUFJLEdBQUcsT0FBTyxDQUFDLGVBQWUsQ0FBQztBQUVuQyxJQUFJLE1BQU0sR0FBRyxPQUFPLENBQUMsaUJBQWlCLENBQUM7QUFDdkMsSUFBSSxLQUFLLEdBQUcsT0FBTyxDQUFDLGdCQUFnQixDQUFDO0FBQ3JDLElBQUksYUFBYSxHQUFHLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQzs7QUFFN0M7QUFDQSxNQUFNLENBQUMsT0FBTyxHQUFHLGFBQWEsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUM7OztBQ1QxRCxZQUFZOztBQUVaO0FBQ0EsTUFBTSxDQUFDLE9BQU8sR0FBRyxRQUFRLENBQUMsU0FBUyxDQUFDLEtBQUs7OztBQ0h6QyxZQUFZOztBQUVaO0FBQ0EsTUFBTSxDQUFDLE9BQU8sR0FBRyxRQUFRLENBQUMsU0FBUyxDQUFDLElBQUk7OztBQ0h4QyxZQUFZOztBQUVaLElBQUksSUFBSSxHQUFHLE9BQU8sQ0FBQyxlQUFlLENBQUM7QUFDbkMsSUFBSSxVQUFVLEdBQUcsT0FBTyxDQUFDLGdCQUFnQixDQUFDO0FBRTFDLElBQUksS0FBSyxHQUFHLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQztBQUNyQyxJQUFJLFlBQVksR0FBRyxPQUFPLENBQUMsZUFBZSxDQUFDOztBQUUzQztBQUNBLE1BQU0sQ0FBQyxPQUFPLEdBQUcsU0FBUyxhQUFhLENBQUMsSUFBSSxFQUFFO0VBQzdDLElBQUksSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLElBQUksT0FBTyxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssVUFBVSxFQUFFO0lBQ3JELE1BQU0sSUFBSSxVQUFVLENBQUMsd0JBQXdCLENBQUM7RUFDL0M7RUFDQSxPQUFPLFlBQVksQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQztBQUN2QyxDQUFDOzs7QUNkRCxZQUFZOztBQUVaO0FBQ0EsTUFBTSxDQUFDLE9BQU8sR0FBRyxPQUFPLE9BQU8sS0FBSyxXQUFXLElBQUksT0FBTyxJQUFJLE9BQU8sQ0FBQyxLQUFLOzs7QUNIM0UsWUFBWTs7QUFFWixJQUFJLFlBQVksR0FBRyxPQUFPLENBQUMsZUFBZSxDQUFDO0FBRTNDLElBQUksYUFBYSxHQUFHLE9BQU8sQ0FBQyx5QkFBeUIsQ0FBQzs7QUFFdEQ7QUFDQSxJQUFJLFFBQVEsR0FBRyxhQUFhLENBQUMsQ0FBQyxZQUFZLENBQUMsNEJBQTRCLENBQUMsQ0FBQyxDQUFDOztBQUUxRTtBQUNBLE1BQU0sQ0FBQyxPQUFPLEdBQUcsU0FBUyxrQkFBa0IsQ0FBQyxJQUFJLEVBQUUsWUFBWSxFQUFFO0VBQ2hFOztFQUVBLElBQUksU0FBUyxHQUFHLDZEQUErRCxZQUFZLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxZQUFZLENBQUU7RUFDbEgsSUFBSSxPQUFPLFNBQVMsS0FBSyxVQUFVLElBQUksUUFBUSxDQUFDLElBQUksRUFBRSxhQUFhLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRTtJQUMxRSxPQUFPLGFBQWEsQ0FBQyxvQkFBc0IsQ0FBQyxTQUFTLENBQUUsQ0FBQztFQUN6RDtFQUNBLE9BQU8sU0FBUztBQUNqQixDQUFDOzs7QUNsQkQsWUFBWTs7QUFFWixJQUFJLFFBQVEsR0FBRyxPQUFPLENBQUMseUJBQXlCLENBQUM7QUFDakQsSUFBSSxJQUFJLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQztBQUUxQixJQUFJLGdCQUFnQjtBQUNwQixJQUFJO0VBQ0g7RUFDQSxnQkFBZ0IsR0FBRyxxREFBdUQsRUFBRSxDQUFFLFNBQVMsS0FBSyxLQUFLLENBQUMsU0FBUztBQUM1RyxDQUFDLENBQUMsT0FBTyxDQUFDLEVBQUU7RUFDWCxJQUFJLENBQUMsQ0FBQyxJQUFJLE9BQU8sQ0FBQyxLQUFLLFFBQVEsSUFBSSxFQUFFLE1BQU0sSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxLQUFLLGtCQUFrQixFQUFFO0lBQ25GLE1BQU0sQ0FBQztFQUNSO0FBQ0Q7O0FBRUE7QUFDQSxJQUFJLElBQUksR0FBRyxDQUFDLENBQUMsZ0JBQWdCLElBQUksSUFBSSxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxFQUFFLDRDQUE4QyxXQUFZLENBQUM7QUFFM0gsSUFBSSxPQUFPLEdBQUcsTUFBTTtBQUNwQixJQUFJLGVBQWUsR0FBRyxPQUFPLENBQUMsY0FBYzs7QUFFNUM7QUFDQSxNQUFNLENBQUMsT0FBTyxHQUFHLElBQUksSUFBSSxPQUFPLElBQUksQ0FBQyxHQUFHLEtBQUssVUFBVSxHQUNwRCxRQUFRLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsR0FDcEIsT0FBTyxlQUFlLEtBQUssVUFBVSxHQUNwQyw4QkFBK0IsU0FBUyxTQUFTLENBQUMsS0FBSyxFQUFFO0VBQzFEO0VBQ0EsT0FBTyxlQUFlLENBQUMsS0FBSyxJQUFJLElBQUksR0FBRyxLQUFLLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQy9ELENBQUMsR0FDQyxLQUFLOzs7QUM3QlQsWUFBWTs7QUFFWjtBQUNBLElBQUksZUFBZSxHQUFHLE1BQU0sQ0FBQyxjQUFjLElBQUksS0FBSztBQUNwRCxJQUFJLGVBQWUsRUFBRTtFQUNwQixJQUFJO0lBQ0gsZUFBZSxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUcsRUFBRTtNQUFFLEtBQUssRUFBRTtJQUFFLENBQUMsQ0FBQztFQUN2QyxDQUFDLENBQUMsT0FBTyxDQUFDLEVBQUU7SUFDWDtJQUNBLGVBQWUsR0FBRyxLQUFLO0VBQ3hCO0FBQ0Q7QUFFQSxNQUFNLENBQUMsT0FBTyxHQUFHLGVBQWU7OztBQ2JoQyxZQUFZOztBQUVaO0FBQ0EsTUFBTSxDQUFDLE9BQU8sR0FBRyxTQUFTOzs7QUNIMUIsWUFBWTs7QUFFWjtBQUNBLE1BQU0sQ0FBQyxPQUFPLEdBQUcsS0FBSzs7O0FDSHRCLFlBQVk7O0FBRVo7QUFDQSxNQUFNLENBQUMsT0FBTyxHQUFHLFVBQVU7OztBQ0gzQixZQUFZOztBQUVaO0FBQ0EsTUFBTSxDQUFDLE9BQU8sR0FBRyxjQUFjOzs7QUNIL0IsWUFBWTs7QUFFWjtBQUNBLE1BQU0sQ0FBQyxPQUFPLEdBQUcsV0FBVzs7O0FDSDVCLFlBQVk7O0FBRVo7QUFDQSxNQUFNLENBQUMsT0FBTyxHQUFHLFNBQVM7OztBQ0gxQixZQUFZOztBQUVaO0FBQ0EsTUFBTSxDQUFDLE9BQU8sR0FBRyxRQUFROzs7QUNIekIsWUFBWTs7QUFFWjtBQUNBLE1BQU0sQ0FBQyxPQUFPLEdBQUcsTUFBTTs7O0FDSHZCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxWEEsWUFBWTs7QUFFWixJQUFJLE9BQU8sR0FBRyxPQUFPLENBQUMsaUJBQWlCLENBQUM7O0FBRXhDO0FBQ0EsTUFBTSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUMsY0FBYyxJQUFJLElBQUk7OztBQ0wvQyxZQUFZOztBQUVaO0FBQ0EsTUFBTSxDQUFDLE9BQU8sR0FBSSxPQUFPLE9BQU8sS0FBSyxXQUFXLElBQUksT0FBTyxDQUFDLGNBQWMsSUFBSyxJQUFJOzs7QUNIbkYsWUFBWTs7QUFFWixJQUFJLGVBQWUsR0FBRyxPQUFPLENBQUMsMEJBQTBCLENBQUM7QUFDekQsSUFBSSxnQkFBZ0IsR0FBRyxPQUFPLENBQUMseUJBQXlCLENBQUM7QUFFekQsSUFBSSxjQUFjLEdBQUcsT0FBTyxDQUFDLGtCQUFrQixDQUFDOztBQUVoRDtBQUNBLE1BQU0sQ0FBQyxPQUFPLEdBQUcsZUFBZSxHQUM3QixTQUFTLFFBQVEsQ0FBQyxDQUFDLEVBQUU7RUFDdEI7RUFDQSxPQUFPLGVBQWUsQ0FBQyxDQUFDLENBQUM7QUFDMUIsQ0FBQyxHQUNDLGdCQUFnQixHQUNmLFNBQVMsUUFBUSxDQUFDLENBQUMsRUFBRTtFQUN0QixJQUFJLENBQUMsQ0FBQyxJQUFLLE9BQU8sQ0FBQyxLQUFLLFFBQVEsSUFBSSxPQUFPLENBQUMsS0FBSyxVQUFXLEVBQUU7SUFDN0QsTUFBTSxJQUFJLFNBQVMsQ0FBQyx5QkFBeUIsQ0FBQztFQUMvQztFQUNBO0VBQ0EsT0FBTyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUM7QUFDM0IsQ0FBQyxHQUNDLGNBQWMsR0FDYixTQUFTLFFBQVEsQ0FBQyxDQUFDLEVBQUU7RUFDdEI7RUFDQSxPQUFPLGNBQWMsQ0FBQyxDQUFDLENBQUM7QUFDekIsQ0FBQyxHQUNDLElBQUk7OztBQzFCVCxZQUFZOztBQUVaO0FBQ0EsTUFBTSxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUMsd0JBQXdCOzs7QUNIaEQsWUFBWTs7QUFFWjtBQUNBLElBQUksS0FBSyxHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUM7QUFFN0IsSUFBSSxLQUFLLEVBQUU7RUFDVixJQUFJO0lBQ0gsS0FBSyxDQUFDLEVBQUUsRUFBRSxRQUFRLENBQUM7RUFDcEIsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxFQUFFO0lBQ1g7SUFDQSxLQUFLLEdBQUcsSUFBSTtFQUNiO0FBQ0Q7QUFFQSxNQUFNLENBQUMsT0FBTyxHQUFHLEtBQUs7OztBQ2R0QixZQUFZOztBQUVaLElBQUksVUFBVSxHQUFHLE9BQU8sTUFBTSxLQUFLLFdBQVcsSUFBSSxNQUFNO0FBQ3hELElBQUksYUFBYSxHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUM7O0FBRXRDO0FBQ0EsTUFBTSxDQUFDLE9BQU8sR0FBRyxTQUFTLGdCQUFnQixDQUFBLEVBQUc7RUFDNUMsSUFBSSxPQUFPLFVBQVUsS0FBSyxVQUFVLEVBQUU7SUFBRSxPQUFPLEtBQUs7RUFBRTtFQUN0RCxJQUFJLE9BQU8sTUFBTSxLQUFLLFVBQVUsRUFBRTtJQUFFLE9BQU8sS0FBSztFQUFFO0VBQ2xELElBQUksT0FBTyxVQUFVLENBQUMsS0FBSyxDQUFDLEtBQUssUUFBUSxFQUFFO0lBQUUsT0FBTyxLQUFLO0VBQUU7RUFDM0QsSUFBSSxPQUFPLE1BQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxRQUFRLEVBQUU7SUFBRSxPQUFPLEtBQUs7RUFBRTtFQUV2RCxPQUFPLGFBQWEsQ0FBQyxDQUFDO0FBQ3ZCLENBQUM7OztBQ2JELFlBQVk7O0FBRVo7QUFDQTtBQUNBLE1BQU0sQ0FBQyxPQUFPLEdBQUcsU0FBUyxVQUFVLENBQUEsRUFBRztFQUN0QyxJQUFJLE9BQU8sTUFBTSxLQUFLLFVBQVUsSUFBSSxPQUFPLE1BQU0sQ0FBQyxxQkFBcUIsS0FBSyxVQUFVLEVBQUU7SUFBRSxPQUFPLEtBQUs7RUFBRTtFQUN4RyxJQUFJLE9BQU8sTUFBTSxDQUFDLFFBQVEsS0FBSyxRQUFRLEVBQUU7SUFBRSxPQUFPLElBQUk7RUFBRTs7RUFFeEQ7RUFDQSxJQUFJLEdBQUcsR0FBRyxDQUFDLENBQUM7RUFDWixJQUFJLEdBQUcsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDO0VBQ3hCLElBQUksTUFBTSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUM7RUFDeEIsSUFBSSxPQUFPLEdBQUcsS0FBSyxRQUFRLEVBQUU7SUFBRSxPQUFPLEtBQUs7RUFBRTtFQUU3QyxJQUFJLE1BQU0sQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxpQkFBaUIsRUFBRTtJQUFFLE9BQU8sS0FBSztFQUFFO0VBQy9FLElBQUksTUFBTSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLGlCQUFpQixFQUFFO0lBQUUsT0FBTyxLQUFLO0VBQUU7O0VBRWxGO0VBQ0E7RUFDQTtFQUNBOztFQUVBO0VBQ0E7O0VBRUEsSUFBSSxNQUFNLEdBQUcsRUFBRTtFQUNmLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxNQUFNO0VBQ2pCLEtBQUssSUFBSSxDQUFDLElBQUksR0FBRyxFQUFFO0lBQUUsT0FBTyxLQUFLO0VBQUUsQ0FBQyxDQUFDO0VBQ3JDLElBQUksT0FBTyxNQUFNLENBQUMsSUFBSSxLQUFLLFVBQVUsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUU7SUFBRSxPQUFPLEtBQUs7RUFBRTtFQUV4RixJQUFJLE9BQU8sTUFBTSxDQUFDLG1CQUFtQixLQUFLLFVBQVUsSUFBSSxNQUFNLENBQUMsbUJBQW1CLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtJQUFFLE9BQU8sS0FBSztFQUFFO0VBRXRILElBQUksSUFBSSxHQUFHLE1BQU0sQ0FBQyxxQkFBcUIsQ0FBQyxHQUFHLENBQUM7RUFDNUMsSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLENBQUMsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssR0FBRyxFQUFFO0lBQUUsT0FBTyxLQUFLO0VBQUU7RUFFMUQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsb0JBQW9CLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsRUFBRTtJQUFFLE9BQU8sS0FBSztFQUFFO0VBRTNFLElBQUksT0FBTyxNQUFNLENBQUMsd0JBQXdCLEtBQUssVUFBVSxFQUFFO0lBQzFEO0lBQ0EsSUFBSSxVQUFVLEdBQUcsaUNBQW1DLE1BQU0sQ0FBQyx3QkFBd0IsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFFO0lBQzlGLElBQUksVUFBVSxDQUFDLEtBQUssS0FBSyxNQUFNLElBQUksVUFBVSxDQUFDLFVBQVUsS0FBSyxJQUFJLEVBQUU7TUFBRSxPQUFPLEtBQUs7SUFBRTtFQUNwRjtFQUVBLE9BQU8sSUFBSTtBQUNaLENBQUM7OztBQzVDRCxZQUFZOztBQUVaLElBQUksSUFBSSxHQUFHLFFBQVEsQ0FBQyxTQUFTLENBQUMsSUFBSTtBQUNsQyxJQUFJLE9BQU8sR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDLGNBQWM7QUFDN0MsSUFBSSxJQUFJLEdBQUcsT0FBTyxDQUFDLGVBQWUsQ0FBQzs7QUFFbkM7QUFDQSxNQUFNLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQzs7O0FDUHpDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNCQSxZQUFZOztBQUVaO0FBQ0EsTUFBTSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsR0FBRzs7O0FDSHpCLFlBQVk7O0FBRVo7QUFDQSxNQUFNLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxLQUFLOzs7QUNIM0IsWUFBWTs7QUFFWjtBQUNBLE1BQU0sQ0FBQyxPQUFPLEdBQUcsTUFBTSxDQUFDLEtBQUssSUFBSSxTQUFTLEtBQUssQ0FBQyxDQUFDLEVBQUU7RUFDbEQsT0FBTyxDQUFDLEtBQUssQ0FBQztBQUNmLENBQUM7OztBQ0xELFlBQVk7O0FBRVo7QUFDQSxNQUFNLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxHQUFHOzs7QUNIekIsWUFBWTs7QUFFWjtBQUNBLE1BQU0sQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLEdBQUc7OztBQ0h6QixZQUFZOztBQUVaO0FBQ0EsTUFBTSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsR0FBRzs7O0FDSHpCLFlBQVk7O0FBRVo7QUFDQSxNQUFNLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxLQUFLOzs7QUNIM0IsWUFBWTs7QUFFWixJQUFJLE1BQU0sR0FBRyxPQUFPLENBQUMsU0FBUyxDQUFDOztBQUUvQjtBQUNBLE1BQU0sQ0FBQyxPQUFPLEdBQUcsU0FBUyxJQUFJLENBQUMsTUFBTSxFQUFFO0VBQ3RDLElBQUksTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLE1BQU0sS0FBSyxDQUFDLEVBQUU7SUFDbkMsT0FBTyxNQUFNO0VBQ2Q7RUFDQSxPQUFPLE1BQU0sR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQzVCLENBQUM7Ozs7QUNWRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDaGlCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUN4TEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDcmhCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNYQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5WkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM1dBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdYQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakVBLFlBQVk7O0FBRVosSUFBSSxPQUFPLEdBQUcsT0FBTyxDQUFDLGdCQUFnQixDQUFDO0FBRXZDLElBQUksVUFBVSxHQUFHLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQzs7QUFFMUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUksV0FBVyxHQUFHLFNBQUEsQ0FBVSxJQUFJLEVBQUUsR0FBRyxFQUFFLFFBQVEsRUFBRTtFQUNoRDtFQUNBLElBQUksSUFBSSxHQUFHLElBQUk7RUFDZjtFQUNBLElBQUksSUFBSTtFQUNSO0VBQ0EsT0FBTyxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxLQUFLLElBQUksRUFBRSxJQUFJLEdBQUcsSUFBSSxFQUFFO0lBQy9DLElBQUksSUFBSSxDQUFDLEdBQUcsS0FBSyxHQUFHLEVBQUU7TUFDckIsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSTtNQUNyQixJQUFJLENBQUMsUUFBUSxFQUFFO1FBQ2Q7UUFDQSxJQUFJLENBQUMsSUFBSSxHQUFHLDRDQUE4QyxJQUFJLENBQUMsSUFBSztRQUNwRSxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxDQUFDO01BQ25CO01BQ0EsT0FBTyxJQUFJO0lBQ1o7RUFDRDtBQUNELENBQUM7O0FBRUQ7QUFDQSxJQUFJLE9BQU8sR0FBRyxTQUFBLENBQVUsT0FBTyxFQUFFLEdBQUcsRUFBRTtFQUNyQyxJQUFJLENBQUMsT0FBTyxFQUFFO0lBQ2IsT0FBTyxLQUFLLFNBQVM7RUFDdEI7RUFDQSxJQUFJLElBQUksR0FBRyxXQUFXLENBQUMsT0FBTyxFQUFFLEdBQUcsQ0FBQztFQUNwQyxPQUFPLElBQUksSUFBSSxJQUFJLENBQUMsS0FBSztBQUMxQixDQUFDO0FBQ0Q7QUFDQSxJQUFJLE9BQU8sR0FBRyxTQUFBLENBQVUsT0FBTyxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUU7RUFDNUMsSUFBSSxJQUFJLEdBQUcsV0FBVyxDQUFDLE9BQU8sRUFBRSxHQUFHLENBQUM7RUFDcEMsSUFBSSxJQUFJLEVBQUU7SUFDVCxJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUs7RUFDbkIsQ0FBQyxNQUFNO0lBQ047SUFDQSxPQUFPLENBQUMsSUFBSSxHQUFHLHVFQUF5RTtNQUFFO01BQ3pGLEdBQUcsRUFBRSxHQUFHO01BQ1IsSUFBSSxFQUFFLE9BQU8sQ0FBQyxJQUFJO01BQ2xCLEtBQUssRUFBRTtJQUNSLENBQUU7RUFDSDtBQUNELENBQUM7QUFDRDtBQUNBLElBQUksT0FBTyxHQUFHLFNBQUEsQ0FBVSxPQUFPLEVBQUUsR0FBRyxFQUFFO0VBQ3JDLElBQUksQ0FBQyxPQUFPLEVBQUU7SUFDYixPQUFPLEtBQUs7RUFDYjtFQUNBLE9BQU8sQ0FBQyxDQUFDLFdBQVcsQ0FBQyxPQUFPLEVBQUUsR0FBRyxDQUFDO0FBQ25DLENBQUM7QUFDRDtBQUNBO0FBQ0EsSUFBSSxVQUFVLEdBQUcsU0FBQSxDQUFVLE9BQU8sRUFBRSxHQUFHLEVBQUU7RUFDeEMsSUFBSSxPQUFPLEVBQUU7SUFDWixPQUFPLFdBQVcsQ0FBQyxPQUFPLEVBQUUsR0FBRyxFQUFFLElBQUksQ0FBQztFQUN2QztBQUNELENBQUM7O0FBRUQ7QUFDQSxNQUFNLENBQUMsT0FBTyxHQUFHLFNBQVMsa0JBQWtCLENBQUEsRUFBRztFQUM5QztFQUNBO0VBQ0E7O0VBRUEsK0RBQWdFLElBQUksRUFBRTs7RUFFdEU7RUFDQSxJQUFJLE9BQU8sR0FBRztJQUNiLE1BQU0sRUFBRSxTQUFBLENBQVUsR0FBRyxFQUFFO01BQ3RCLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFO1FBQ3RCLE1BQU0sSUFBSSxVQUFVLENBQUMsZ0NBQWdDLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDO01BQ3RFO0lBQ0QsQ0FBQztJQUNELFFBQVEsRUFBRSxTQUFBLENBQVUsR0FBRyxFQUFFO01BQ3hCLElBQUksV0FBVyxHQUFHLFVBQVUsQ0FBQyxFQUFFLEVBQUUsR0FBRyxDQUFDO01BQ3JDLElBQUksV0FBVyxJQUFJLEVBQUUsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUU7UUFDbEMsRUFBRSxHQUFHLEtBQUssU0FBUztNQUNwQjtNQUNBLE9BQU8sQ0FBQyxDQUFDLFdBQVc7SUFDckIsQ0FBQztJQUNELEdBQUcsRUFBRSxTQUFBLENBQVUsR0FBRyxFQUFFO01BQ25CLE9BQU8sT0FBTyxDQUFDLEVBQUUsRUFBRSxHQUFHLENBQUM7SUFDeEIsQ0FBQztJQUNELEdBQUcsRUFBRSxTQUFBLENBQVUsR0FBRyxFQUFFO01BQ25CLE9BQU8sT0FBTyxDQUFDLEVBQUUsRUFBRSxHQUFHLENBQUM7SUFDeEIsQ0FBQztJQUNELEdBQUcsRUFBRSxTQUFBLENBQVUsR0FBRyxFQUFFLEtBQUssRUFBRTtNQUMxQixJQUFJLENBQUMsRUFBRSxFQUFFO1FBQ1I7UUFDQSxFQUFFLEdBQUc7VUFDSixJQUFJLEVBQUUsS0FBSztRQUNaLENBQUM7TUFDRjtNQUNBO01BQ0EsT0FBTyxDQUFDLHFDQUF1QyxFQUFFLEVBQUcsR0FBRyxFQUFFLEtBQUssQ0FBQztJQUNoRTtFQUNELENBQUM7RUFDRCxPQUFPLE9BQU87QUFDZixDQUFDOzs7QUM5R0QsWUFBWTs7QUFFWixJQUFJLFlBQVksR0FBRyxPQUFPLENBQUMsZUFBZSxDQUFDO0FBQzNDLElBQUksU0FBUyxHQUFHLE9BQU8sQ0FBQyxZQUFZLENBQUM7QUFDckMsSUFBSSxPQUFPLEdBQUcsT0FBTyxDQUFDLGdCQUFnQixDQUFDO0FBRXZDLElBQUksVUFBVSxHQUFHLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQztBQUMxQyxJQUFJLElBQUksR0FBRyxZQUFZLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQzs7QUFFdEM7QUFDQSxJQUFJLE9BQU8sR0FBRyxTQUFTLENBQUMsbUJBQW1CLEVBQUUsSUFBSSxDQUFDO0FBQ2xEO0FBQ0EsSUFBSSxPQUFPLEdBQUcsU0FBUyxDQUFDLG1CQUFtQixFQUFFLElBQUksQ0FBQztBQUNsRDtBQUNBLElBQUksT0FBTyxHQUFHLFNBQVMsQ0FBQyxtQkFBbUIsRUFBRSxJQUFJLENBQUM7QUFDbEQ7QUFDQSxJQUFJLFVBQVUsR0FBRyxTQUFTLENBQUMsc0JBQXNCLEVBQUUsSUFBSSxDQUFDO0FBQ3hEO0FBQ0EsSUFBSSxRQUFRLEdBQUcsU0FBUyxDQUFDLG9CQUFvQixFQUFFLElBQUksQ0FBQzs7QUFFcEQ7QUFDQSxNQUFNLENBQUMsT0FBTyxHQUFHLENBQUMsQ0FBQyxJQUFJLElBQUksMENBQTJDLFNBQVMsaUJBQWlCLENBQUEsRUFBRztFQUNsRztFQUNBO0VBQ0E7O0VBRUEsb0NBQXFDLElBQUksRUFBRTs7RUFFM0M7RUFDQSxJQUFJLE9BQU8sR0FBRztJQUNiLE1BQU0sRUFBRSxTQUFBLENBQVUsR0FBRyxFQUFFO01BQ3RCLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFO1FBQ3RCLE1BQU0sSUFBSSxVQUFVLENBQUMsZ0NBQWdDLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDO01BQ3RFO0lBQ0QsQ0FBQztJQUNELFFBQVEsRUFBRSxTQUFBLENBQVUsR0FBRyxFQUFFO01BQ3hCLElBQUksRUFBRSxFQUFFO1FBQ1AsSUFBSSxNQUFNLEdBQUcsVUFBVSxDQUFDLEVBQUUsRUFBRSxHQUFHLENBQUM7UUFDaEMsSUFBSSxRQUFRLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxFQUFFO1VBQ3ZCLEVBQUUsR0FBRyxLQUFLLFNBQVM7UUFDcEI7UUFDQSxPQUFPLE1BQU07TUFDZDtNQUNBLE9BQU8sS0FBSztJQUNiLENBQUM7SUFDRCxHQUFHLEVBQUUsU0FBQSxDQUFVLEdBQUcsRUFBRTtNQUFFO01BQ3JCLElBQUksRUFBRSxFQUFFO1FBQ1AsT0FBTyxPQUFPLENBQUMsRUFBRSxFQUFFLEdBQUcsQ0FBQztNQUN4QjtJQUNELENBQUM7SUFDRCxHQUFHLEVBQUUsU0FBQSxDQUFVLEdBQUcsRUFBRTtNQUNuQixJQUFJLEVBQUUsRUFBRTtRQUNQLE9BQU8sT0FBTyxDQUFDLEVBQUUsRUFBRSxHQUFHLENBQUM7TUFDeEI7TUFDQSxPQUFPLEtBQUs7SUFDYixDQUFDO0lBQ0QsR0FBRyxFQUFFLFNBQUEsQ0FBVSxHQUFHLEVBQUUsS0FBSyxFQUFFO01BQzFCLElBQUksQ0FBQyxFQUFFLEVBQUU7UUFDUjtRQUNBLEVBQUUsR0FBRyxJQUFJLElBQUksQ0FBQyxDQUFDO01BQ2hCO01BQ0EsT0FBTyxDQUFDLEVBQUUsRUFBRSxHQUFHLEVBQUUsS0FBSyxDQUFDO0lBQ3hCO0VBQ0QsQ0FBQzs7RUFFRDtFQUNBLE9BQU8sT0FBTztBQUNmLENBQUM7OztBQ25FRCxZQUFZOztBQUVaLElBQUksWUFBWSxHQUFHLE9BQU8sQ0FBQyxlQUFlLENBQUM7QUFDM0MsSUFBSSxTQUFTLEdBQUcsT0FBTyxDQUFDLFlBQVksQ0FBQztBQUNyQyxJQUFJLE9BQU8sR0FBRyxPQUFPLENBQUMsZ0JBQWdCLENBQUM7QUFDdkMsSUFBSSxpQkFBaUIsR0FBRyxPQUFPLENBQUMsa0JBQWtCLENBQUM7QUFFbkQsSUFBSSxVQUFVLEdBQUcsT0FBTyxDQUFDLGdCQUFnQixDQUFDO0FBQzFDLElBQUksUUFBUSxHQUFHLFlBQVksQ0FBQyxXQUFXLEVBQUUsSUFBSSxDQUFDOztBQUU5QztBQUNBLElBQUksV0FBVyxHQUFHLFNBQVMsQ0FBQyx1QkFBdUIsRUFBRSxJQUFJLENBQUM7QUFDMUQ7QUFDQSxJQUFJLFdBQVcsR0FBRyxTQUFTLENBQUMsdUJBQXVCLEVBQUUsSUFBSSxDQUFDO0FBQzFEO0FBQ0EsSUFBSSxXQUFXLEdBQUcsU0FBUyxDQUFDLHVCQUF1QixFQUFFLElBQUksQ0FBQztBQUMxRDtBQUNBLElBQUksY0FBYyxHQUFHLFNBQVMsQ0FBQywwQkFBMEIsRUFBRSxJQUFJLENBQUM7O0FBRWhFO0FBQ0EsTUFBTSxDQUFDLE9BQU8sR0FBRyxRQUFRLEdBQ3RCLDBDQUEyQyxTQUFTLHFCQUFxQixDQUFBLEVBQUc7RUFDN0U7RUFDQTtFQUNBOztFQUVBLGlEQUFrRCxJQUFJLEdBQUc7RUFDekQ7RUFBbUMsSUFBSSxFQUFFOztFQUV6QztFQUNBLElBQUksT0FBTyxHQUFHO0lBQ2IsTUFBTSxFQUFFLFNBQUEsQ0FBVSxHQUFHLEVBQUU7TUFDdEIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUU7UUFDdEIsTUFBTSxJQUFJLFVBQVUsQ0FBQyxnQ0FBZ0MsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUM7TUFDdEU7SUFDRCxDQUFDO0lBQ0QsUUFBUSxFQUFFLFNBQUEsQ0FBVSxHQUFHLEVBQUU7TUFDeEIsSUFBSSxRQUFRLElBQUksR0FBRyxLQUFLLE9BQU8sR0FBRyxLQUFLLFFBQVEsSUFBSSxPQUFPLEdBQUcsS0FBSyxVQUFVLENBQUMsRUFBRTtRQUM5RSxJQUFJLEdBQUcsRUFBRTtVQUNSLE9BQU8sY0FBYyxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUM7UUFDaEM7TUFDRCxDQUFDLE1BQU0sSUFBSSxpQkFBaUIsRUFBRTtRQUM3QixJQUFJLEVBQUUsRUFBRTtVQUNQLE9BQU8sRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEdBQUcsQ0FBQztRQUN6QjtNQUNEO01BQ0EsT0FBTyxLQUFLO0lBQ2IsQ0FBQztJQUNELEdBQUcsRUFBRSxTQUFBLENBQVUsR0FBRyxFQUFFO01BQ25CLElBQUksUUFBUSxJQUFJLEdBQUcsS0FBSyxPQUFPLEdBQUcsS0FBSyxRQUFRLElBQUksT0FBTyxHQUFHLEtBQUssVUFBVSxDQUFDLEVBQUU7UUFDOUUsSUFBSSxHQUFHLEVBQUU7VUFDUixPQUFPLFdBQVcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDO1FBQzdCO01BQ0Q7TUFDQSxPQUFPLEVBQUUsSUFBSSxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQztJQUN6QixDQUFDO0lBQ0QsR0FBRyxFQUFFLFNBQUEsQ0FBVSxHQUFHLEVBQUU7TUFDbkIsSUFBSSxRQUFRLElBQUksR0FBRyxLQUFLLE9BQU8sR0FBRyxLQUFLLFFBQVEsSUFBSSxPQUFPLEdBQUcsS0FBSyxVQUFVLENBQUMsRUFBRTtRQUM5RSxJQUFJLEdBQUcsRUFBRTtVQUNSLE9BQU8sV0FBVyxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUM7UUFDN0I7TUFDRDtNQUNBLE9BQU8sQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQztJQUMzQixDQUFDO0lBQ0QsR0FBRyxFQUFFLFNBQUEsQ0FBVSxHQUFHLEVBQUUsS0FBSyxFQUFFO01BQzFCLElBQUksUUFBUSxJQUFJLEdBQUcsS0FBSyxPQUFPLEdBQUcsS0FBSyxRQUFRLElBQUksT0FBTyxHQUFHLEtBQUssVUFBVSxDQUFDLEVBQUU7UUFDOUUsSUFBSSxDQUFDLEdBQUcsRUFBRTtVQUNULEdBQUcsR0FBRyxJQUFJLFFBQVEsQ0FBQyxDQUFDO1FBQ3JCO1FBQ0EsV0FBVyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsS0FBSyxDQUFDO01BQzdCLENBQUMsTUFBTSxJQUFJLGlCQUFpQixFQUFFO1FBQzdCLElBQUksQ0FBQyxFQUFFLEVBQUU7VUFDUixFQUFFLEdBQUcsaUJBQWlCLENBQUMsQ0FBQztRQUN6QjtRQUNBO1FBQ0E7UUFBdUMsRUFBRSxDQUFFLEdBQUcsQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDO01BQzNEO0lBQ0Q7RUFDRCxDQUFDOztFQUVEO0VBQ0EsT0FBTyxPQUFPO0FBQ2YsQ0FBQyxHQUNDLGlCQUFpQjs7O0FDbkZwQixZQUFZOztBQUVaLElBQUksVUFBVSxHQUFHLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQztBQUMxQyxJQUFJLE9BQU8sR0FBRyxPQUFPLENBQUMsZ0JBQWdCLENBQUM7QUFDdkMsSUFBSSxrQkFBa0IsR0FBRyxPQUFPLENBQUMsbUJBQW1CLENBQUM7QUFDckQsSUFBSSxpQkFBaUIsR0FBRyxPQUFPLENBQUMsa0JBQWtCLENBQUM7QUFDbkQsSUFBSSxxQkFBcUIsR0FBRyxPQUFPLENBQUMsc0JBQXNCLENBQUM7QUFFM0QsSUFBSSxXQUFXLEdBQUcscUJBQXFCLElBQUksaUJBQWlCLElBQUksa0JBQWtCOztBQUVsRjtBQUNBLE1BQU0sQ0FBQyxPQUFPLEdBQUcsU0FBUyxjQUFjLENBQUEsRUFBRztFQUMxQzs7RUFFQSxrQ0FBbUMsSUFBSSxZQUFZOztFQUVuRDtFQUNBLElBQUksT0FBTyxHQUFHO0lBQ2IsTUFBTSxFQUFFLFNBQUEsQ0FBVSxHQUFHLEVBQUU7TUFDdEIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUU7UUFDdEIsSUFBSSxPQUFPLEdBQUcsR0FBRyxJQUFJLE1BQU0sQ0FBQyxHQUFHLENBQUMsS0FBSyxHQUFHLEdBQ3JDLHNCQUFzQixHQUN0QixPQUFPLENBQUMsR0FBRyxDQUFDO1FBQ2YsTUFBTSxJQUFJLFVBQVUsQ0FBQyxnQ0FBZ0MsR0FBRyxPQUFPLENBQUM7TUFDakU7SUFDRCxDQUFDO0lBQ0QsUUFBUSxFQUFFLFNBQUEsQ0FBVSxHQUFHLEVBQUU7TUFDeEIsT0FBTyxDQUFDLENBQUMsWUFBWSxJQUFJLFlBQVksQ0FBQyxRQUFRLENBQUMsQ0FBQyxHQUFHLENBQUM7SUFDckQsQ0FBQztJQUNELEdBQUcsRUFBRSxTQUFBLENBQVUsR0FBRyxFQUFFO01BQ25CLE9BQU8sWUFBWSxJQUFJLFlBQVksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDO0lBQzdDLENBQUM7SUFDRCxHQUFHLEVBQUUsU0FBQSxDQUFVLEdBQUcsRUFBRTtNQUNuQixPQUFPLENBQUMsQ0FBQyxZQUFZLElBQUksWUFBWSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUM7SUFDL0MsQ0FBQztJQUNELEdBQUcsRUFBRSxTQUFBLENBQVUsR0FBRyxFQUFFLEtBQUssRUFBRTtNQUMxQixJQUFJLENBQUMsWUFBWSxFQUFFO1FBQ2xCLFlBQVksR0FBRyxXQUFXLENBQUMsQ0FBQztNQUM3QjtNQUVBLFlBQVksQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQztJQUM3QjtFQUNELENBQUM7RUFFRCxPQUFPLE9BQU87QUFDZixDQUFDOzs7O0FDN0NEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ3BGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDM0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDaFdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUNuTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDL0hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQzdIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDcENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDbGdDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDN0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDaG9CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUNuTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUN0TEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDL0ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckZBO0FBQ0E7QUFDQTtBQUNBOztBQ0hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JCQTtBQUNBOztBQ0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdlNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ2xPQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDOXBCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUN4d0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUNuRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uKCl7ZnVuY3Rpb24gcihlLG4sdCl7ZnVuY3Rpb24gbyhpLGYpe2lmKCFuW2ldKXtpZighZVtpXSl7dmFyIGM9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZTtpZighZiYmYylyZXR1cm4gYyhpLCEwKTtpZih1KXJldHVybiB1KGksITApO3ZhciBhPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIraStcIidcIik7dGhyb3cgYS5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGF9dmFyIHA9bltpXT17ZXhwb3J0czp7fX07ZVtpXVswXS5jYWxsKHAuZXhwb3J0cyxmdW5jdGlvbihyKXt2YXIgbj1lW2ldWzFdW3JdO3JldHVybiBvKG58fHIpfSxwLHAuZXhwb3J0cyxyLGUsbix0KX1yZXR1cm4gbltpXS5leHBvcnRzfWZvcih2YXIgdT1cImZ1bmN0aW9uXCI9PXR5cGVvZiByZXF1aXJlJiZyZXF1aXJlLGk9MDtpPHQubGVuZ3RoO2krKylvKHRbaV0pO3JldHVybiBvfXJldHVybiByfSkoKSIsIlwidXNlIHN0cmljdFwiO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5BUElWYWxpZGF0aW9uRXJyb3IgPSBleHBvcnRzLkFQSVN0YXR1c0NvZGVFcnJvciA9IGV4cG9ydHMuQVBJRXZlbnRTdHJlYW1FcnJvciA9IGV4cG9ydHMuQVBJRXJyb3IgPSBleHBvcnRzLkFQSUF1dGhvcmlzYXRpb25FcnJvciA9IHZvaWQgMDtcbnZhciBfaHR0cCA9IHJlcXVpcmUoXCJodHRwXCIpO1xudmFyIF91dGlscyA9IHJlcXVpcmUoXCIuL3V0aWxzLmpzXCIpO1xudmFyIF9hcGlUeXBlcyA9IHJlcXVpcmUoXCIuL3RpL2FwaS10eXBlcy5qc1wiKTtcbnZhciBfYXBpQXV0aFR5cGVzID0gcmVxdWlyZShcIi4vdGkvYXBpLWF1dGgtdHlwZXMuanNcIik7XG4vLyBIb21lYnJpZGdlIHBsdWdpbiBmb3IgSG9tZSBDb25uZWN0IGhvbWUgYXBwbGlhbmNlc1xuLy8gQ29weXJpZ2h0IMKpIDIwMjMtMjAyNiBBbGV4YW5kZXIgVGhvdWt5ZGlkZXNcblxuLy8gQmFzZSBmb3IgcmVwb3J0aW5nIGFsbCBIb21lIENvbm5lY3QgQVBJIGVycm9yc1xuY2xhc3MgQVBJRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gIGNvbnN0cnVjdG9yKHJlcXVlc3QsIHJlc3BvbnNlLCBtZXNzYWdlLCBvcHRpb25zKSB7XG4gICAgLy8gU3RhbmRhcmQgZXJyb3Igb2JqZWN0IGluaXRpYWxpc2F0aW9uXG4gICAgc3VwZXIobWVzc2FnZSk7XG4gICAgdGhpcy5yZXF1ZXN0ID0gcmVxdWVzdDtcbiAgICB0aGlzLnJlc3BvbnNlID0gcmVzcG9uc2U7XG4gICAgRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UodGhpcywgQVBJRXJyb3IpO1xuICAgIHRoaXMubmFtZSA9ICdIb21lIENvbm5lY3QgQVBJIEVycm9yJztcbiAgICBpZiAob3B0aW9ucz8uY2F1c2UpIHRoaXMuZXJyQ2F1c2UgPSBvcHRpb25zLmNhdXNlO1xuICB9XG59XG4vLyBBUEkgY291bGQgbm90IGJlIGF1dGhvcmlzZWRcbmV4cG9ydHMuQVBJRXJyb3IgPSBBUElFcnJvcjtcbmNsYXNzIEFQSUF1dGhvcmlzYXRpb25FcnJvciBleHRlbmRzIEFQSUVycm9yIHtcbiAgY29uc3RydWN0b3IocmVxdWVzdCwgcmVzcG9uc2UsIG1lc3NhZ2UsIG9wdGlvbnMpIHtcbiAgICBzdXBlcihyZXF1ZXN0LCByZXNwb25zZSwgbWVzc2FnZSwgb3B0aW9ucyk7XG4gICAgRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UodGhpcywgQVBJQXV0aG9yaXNhdGlvbkVycm9yKTtcbiAgICB0aGlzLm5hbWUgPSAnSG9tZSBDb25uZWN0IEFQSSBBdXRob3Jpc2F0aW9uIEVycm9yJztcbiAgfVxufVxuLy8gQVBJIHJldHVybmVkIGEgbm9uLXN1Y2Nlc3Mgc3RhdHVzIGNvZGVcbmV4cG9ydHMuQVBJQXV0aG9yaXNhdGlvbkVycm9yID0gQVBJQXV0aG9yaXNhdGlvbkVycm9yO1xuY2xhc3MgQVBJU3RhdHVzQ29kZUVycm9yIGV4dGVuZHMgQVBJRXJyb3Ige1xuICBjb25zdHJ1Y3RvcihyZXF1ZXN0LCByZXNwb25zZSwgdGV4dCwgb3B0aW9ucykge1xuICAgIHN1cGVyKHJlcXVlc3QsIHJlc3BvbnNlLCBBUElTdGF0dXNDb2RlRXJyb3IuZ2V0TWVzc2FnZShyZXNwb25zZSwgdGV4dCksIG9wdGlvbnMpO1xuICAgIHRoaXMudGV4dCA9IHRleHQ7XG4gICAgRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UodGhpcywgQVBJU3RhdHVzQ29kZUVycm9yKTtcbiAgICB0aGlzLm5hbWUgPSAnSG9tZSBDb25uZWN0IFN0YXR1cyBDb2RlIEVycm9yJztcbiAgfVxuICAvLyBDb25zdHJ1Y3QgYW4gZXJyb3IgbWVzc2FnZSBmcm9tIGEgcmVzcG9uc2VcbiAgc3RhdGljIGdldE1lc3NhZ2UocmVzcG9uc2UsIHRleHQpIHtcbiAgICBjb25zdCBzdGF0dXNDb2RlID0gcmVzcG9uc2Uuc3RhdHVzQ29kZTtcbiAgICBjb25zdCBzdGF0dXNDb2RlTmFtZSA9IF9odHRwLlNUQVRVU19DT0RFU1tzdGF0dXNDb2RlXTtcbiAgICBjb25zdCBkZXNjcmlwdGlvbiA9IEFQSVN0YXR1c0NvZGVFcnJvci5nZXRCb2R5RGVzY3JpcHRpb24odGV4dCkgPz8gJ05vIGVycm9yIG1lc3NhZ2UgcmV0dXJuZWQnO1xuICAgIHJldHVybiBgWyR7c3RhdHVzQ29kZX0gJHtzdGF0dXNDb2RlTmFtZX1dICR7ZGVzY3JpcHRpb259YDtcbiAgfVxuICAvLyBBdHRlbXB0IHRvIHJldHJpZXZlIHRoZSBlcnJvciBrZXlcbiAgZ2V0IGtleSgpIHtcbiAgICByZXR1cm4gQVBJU3RhdHVzQ29kZUVycm9yLnBhcnNlQm9keSh0aGlzLnRleHQpLmtleTtcbiAgfVxuICAvLyBBdHRlbXB0IHRvIHJldHJpZXZlIHRoZSBlcnJvciBrZXlcbiAgZ2V0IGRlc2NyaXB0aW9uKCkge1xuICAgIHJldHVybiBBUElTdGF0dXNDb2RlRXJyb3IucGFyc2VCb2R5KHRoaXMudGV4dCkuZGVzY3JpcHRpb247XG4gIH1cbiAgLy8gQXR0ZW1wdCB0byByZXRyaWV2ZSB0aGUgZXJyb3IgZGVzY3JpcHRpb25cbiAgZ2V0IHNpbXBsZU1lc3NhZ2UoKSB7XG4gICAgcmV0dXJuIEFQSVN0YXR1c0NvZGVFcnJvci5nZXRCb2R5RGVzY3JpcHRpb24odGhpcy50ZXh0KTtcbiAgfVxuICAvLyBBdHRlbXB0IHRvIGV4dHJhY3QgYSB1c2VmdWwgZGVzY3JpcHRpb24gZnJvbSB0aGUgcmVzcG9uc2UgYm9keVxuICBzdGF0aWMgZ2V0Qm9keURlc2NyaXB0aW9uKHRleHQpIHtcbiAgICBjb25zdCB7XG4gICAgICBrZXksXG4gICAgICBkZXNjcmlwdGlvblxuICAgIH0gPSBBUElTdGF0dXNDb2RlRXJyb3IucGFyc2VCb2R5KHRleHQpO1xuICAgIGlmIChrZXkpIHtcbiAgICAgIHJldHVybiAoZGVzY3JpcHRpb24gPyBgJHtkZXNjcmlwdGlvbn0gYCA6ICcnKSArIGBbJHtrZXl9XWA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0ZXh0Lmxlbmd0aCA/IHRleHQgOiB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG4gIC8vIEF0dGVtcHQgdG8gcGFyc2UgdGhlIHJlc3BvbnNlIGJvZHlcbiAgc3RhdGljIHBhcnNlQm9keSh0ZXh0KSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGpzb24gPSBKU09OLnBhcnNlKHRleHQpO1xuICAgICAgaWYgKF9hcGlUeXBlcy5jaGVja2Vycy5FcnJvclJlc3BvbnNlLnRlc3QoanNvbikpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBrZXk6IGpzb24uZXJyb3Iua2V5LFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiBqc29uLmVycm9yLmRldmVsb3Blck1lc3NhZ2UgPz8ganNvbi5lcnJvci5kZXNjcmlwdGlvbiA/PyBqc29uLmVycm9yLnZhbHVlXG4gICAgICAgIH07XG4gICAgICB9IGVsc2UgaWYgKF9hcGlBdXRoVHlwZXMuY2hlY2tlcnMuQXV0aG9yaXNhdGlvbkVycm9yLnRlc3QoanNvbikpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBrZXk6IGpzb24uZXJyb3IsXG4gICAgICAgICAgZGVzY3JpcHRpb246IGpzb24uZXJyb3JfZGVzY3JpcHRpb25cbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIHsvKiBlbXB0eSAqL31cbiAgICByZXR1cm4ge307XG4gIH1cbn1cbi8vIEFQSSByZXR1cm5lZCBhIHJlc3BvbnNlIHRoYXQgZmFpbGVkIGNoZWNrZXIgdmFsaWRhdGlvblxuZXhwb3J0cy5BUElTdGF0dXNDb2RlRXJyb3IgPSBBUElTdGF0dXNDb2RlRXJyb3I7XG5jbGFzcyBBUElWYWxpZGF0aW9uRXJyb3IgZXh0ZW5kcyBBUElFcnJvciB7XG4gIGNvbnN0cnVjdG9yKHJlcXVlc3QsIHJlc3BvbnNlLCB2YWxpZGF0aW9uLCBvcHRpb25zKSB7XG4gICAgc3VwZXIocmVxdWVzdCwgcmVzcG9uc2UsIEFQSVZhbGlkYXRpb25FcnJvci5nZXRNZXNzYWdlKHZhbGlkYXRpb24pLCBvcHRpb25zKTtcbiAgICB0aGlzLnZhbGlkYXRpb24gPSB2YWxpZGF0aW9uO1xuICAgIEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKHRoaXMsIEFQSVZhbGlkYXRpb25FcnJvcik7XG4gICAgdGhpcy5uYW1lID0gJ0hvbWUgQ29ubmVjdCBBUEkgVmFsaWRhdGlvbiBFcnJvcic7XG4gIH1cbiAgLy8gQ29uc3RydWN0IGFuIGVycm9yIG1lc3NhZ2UgZnJvbSBhIGNoZWNrZXIgdmFsaWRhdGlvbiBlcnJvclxuICBzdGF0aWMgZ2V0TWVzc2FnZShlcnJvcnMpIHtcbiAgICAoMCwgX3V0aWxzLmFzc2VydElzRGVmaW5lZCkoZXJyb3JzWzBdKTtcbiAgICBjb25zdCBkZXNjcmlwdGlvbiA9IGAke2Vycm9yc1swXS5wYXRofSAke2Vycm9yc1swXS5tZXNzYWdlfWA7XG4gICAgcmV0dXJuIGBTdHJ1Y3R1cmUgdmFsaWRhdGlvbiBmYWlsZWQgKCR7ZGVzY3JpcHRpb259KWA7XG4gIH1cbn1cbi8vIEFQSSByZXR1cm5lZCBldmVudCBzdHJlYW0gdGhhdCBjb3VsZCBub3QgYmUgcGFyc2VkXG5leHBvcnRzLkFQSVZhbGlkYXRpb25FcnJvciA9IEFQSVZhbGlkYXRpb25FcnJvcjtcbmNsYXNzIEFQSUV2ZW50U3RyZWFtRXJyb3IgZXh0ZW5kcyBBUElFcnJvciB7XG4gIGNvbnN0cnVjdG9yKHJlcXVlc3QsIHJlc3BvbnNlLCBtZXNzYWdlLCBzc2UsIG9wdGlvbnMpIHtcbiAgICBzdXBlcihyZXF1ZXN0LCByZXNwb25zZSwgQVBJRXZlbnRTdHJlYW1FcnJvci5nZXRNZXNzYWdlKG1lc3NhZ2UsIHNzZSksIG9wdGlvbnMpO1xuICAgIHRoaXMuc3NlID0gc3NlO1xuICAgIEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKHRoaXMsIEFQSUV2ZW50U3RyZWFtRXJyb3IpO1xuICAgIHRoaXMubmFtZSA9ICdIb21lIENvbm5lY3QgQVBJIEV2ZW50IFN0cmVhbSBFcnJvcic7XG4gIH1cbiAgLy8gQ29uc3RydWN0IGFuIGVycm9yIG1lc3NhZ2UgZnJvbSBhIGNoZWNrZXIgdmFsaWRhdGlvbiBlcnJvclxuICBzdGF0aWMgZ2V0TWVzc2FnZShkZXNjcmlwdGlvbiwgc3NlKSB7XG4gICAgY29uc3QgZmllbGRzID0gT2JqZWN0LmVudHJpZXMoc3NlKS5tYXAoKFtuYW1lLCB2YWx1ZV0pID0+IFtgJHtuYW1lfTpgLCB2YWx1ZV0pO1xuICAgIHJldHVybiBbYFVuYWJsZSB0byBwYXJzZSAke2Rlc2NyaXB0aW9ufTpgLCAuLi4oMCwgX3V0aWxzLmNvbHVtbnMpKGZpZWxkcyldLmpvaW4oJ1xcbicpO1xuICB9XG59XG5leHBvcnRzLkFQSUV2ZW50U3RyZWFtRXJyb3IgPSBBUElFdmVudFN0cmVhbUVycm9yO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ9dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p1WVcxbGN5STZXeUpmYUhSMGNDSXNJbkpsY1hWcGNtVWlMQ0pmZFhScGJITWlMQ0pmWVhCcFZIbHdaWE1pTENKZllYQnBRWFYwYUZSNWNHVnpJaXdpUVZCSlJYSnliM0lpTENKRmNuSnZjaUlzSW1OdmJuTjBjblZqZEc5eUlpd2ljbVZ4ZFdWemRDSXNJbkpsYzNCdmJuTmxJaXdpYldWemMyRm5aU0lzSW05d2RHbHZibk1pTENKallYQjBkWEpsVTNSaFkydFVjbUZqWlNJc0ltNWhiV1VpTENKallYVnpaU0lzSW1WeWNrTmhkWE5sSWl3aVpYaHdiM0owY3lJc0lrRlFTVUYxZEdodmNtbHpZWFJwYjI1RmNuSnZjaUlzSWtGUVNWTjBZWFIxYzBOdlpHVkZjbkp2Y2lJc0luUmxlSFFpTENKblpYUk5aWE56WVdkbElpd2ljM1JoZEhWelEyOWtaU0lzSW5OMFlYUjFjME52WkdWT1lXMWxJaXdpVTFSQlZGVlRYME5QUkVWVElpd2laR1Z6WTNKcGNIUnBiMjRpTENKblpYUkNiMlI1UkdWelkzSnBjSFJwYjI0aUxDSnJaWGtpTENKd1lYSnpaVUp2WkhraUxDSnphVzF3YkdWTlpYTnpZV2RsSWl3aWJHVnVaM1JvSWl3aWRXNWtaV1pwYm1Wa0lpd2lhbk52YmlJc0lrcFRUMDRpTENKd1lYSnpaU0lzSW1Gd2FVTm9aV05yWlhKeklpd2lSWEp5YjNKU1pYTndiMjV6WlNJc0luUmxjM1FpTENKbGNuSnZjaUlzSW1SbGRtVnNiM0JsY2sxbGMzTmhaMlVpTENKMllXeDFaU0lzSW1GMWRHaERhR1ZqYTJWeWN5SXNJa0YxZEdodmNtbHpZWFJwYjI1RmNuSnZjaUlzSW1WeWNtOXlYMlJsYzJOeWFYQjBhVzl1SWl3aVFWQkpWbUZzYVdSaGRHbHZia1Z5Y205eUlpd2lkbUZzYVdSaGRHbHZiaUlzSW1WeWNtOXljeUlzSW1GemMyVnlkRWx6UkdWbWFXNWxaQ0lzSW5CaGRHZ2lMQ0pCVUVsRmRtVnVkRk4wY21WaGJVVnljbTl5SWl3aWMzTmxJaXdpWm1sbGJHUnpJaXdpVDJKcVpXTjBJaXdpWlc1MGNtbGxjeUlzSW0xaGNDSXNJbU52YkhWdGJuTWlMQ0pxYjJsdUlsMHNJbk52ZFhKalpYTWlPbHNpTGk0dmMzSmpMMkZ3YVMxbGNuSnZjbk11ZEhNaVhTd2ljMjkxY21ObGMwTnZiblJsYm5RaU9sdHVkV3hzWFN3aWJXRndjR2x1WjNNaU9pSTdPenM3T3p0QlFVZEJMRWxCUVVGQkxFdEJRVUVzUjBGQlFVTXNUMEZCUVR0QlFVbEJMRWxCUVVGRExFMUJRVUVzUjBGQlFVUXNUMEZCUVR0QlFVTkJMRWxCUVVGRkxGTkJRVUVzUjBGQlFVWXNUMEZCUVR0QlFVTkJMRWxCUVVGSExHRkJRVUVzUjBGQlFVZ3NUMEZCUVR0QlFWUkJPMEZCUTBFN08wRkJaVUU3UVVGRFRTeE5RVUZQU1N4UlFVRlRMRk5CUVZGRExFdEJRVXM3UlVGSkwwSkRMRmxCUTJGRExFOUJRV3RDTEVWQlEyeENReXhSUVVFclFpeEZRVU40UTBNc1QwRkJNRUlzUlVGRE1VSkRMRTlCUVRKQ08wbEJSVE5DTzBsQlEwRXNTMEZCU3l4RFFVRkRSQ3hQUVVGUExFTkJRVU03YlVKQlRreEdMRTlCUVU4N2IwSkJRMUJETEZGQlFWRTdTVUZOYWtKSUxFdEJRVXNzUTBGQlEwMHNhVUpCUVdsQ0xFTkJRVU1zU1VGQlNTeEZRVUZGVUN4UlFVRlJMRU5CUVVNN1NVRkRka01zU1VGQlNTeERRVUZEVVN4SlFVRkpMRWRCUVVjc2QwSkJRWGRDTzBsQlEzQkRMRWxCUVVsR0xFOUJRVThzUlVGQlJVY3NTMEZCU3l4RlFVRkZMRWxCUVVrc1EwRkJRME1zVVVGQlVTeEhRVUZIU2l4UFFVRlBMRU5CUVVOSExFdEJRVXM3UlVGRGNrUTdPMEZCUjBvN1FVRkJRVVVzVDBGQlFTeERRVUZCV0N4UlFVRkJMRWRCUVVGQkxGRkJRVUU3UVVGRFRTeE5RVUZQV1N4eFFrRkJjMElzVTBGQlVWb3NVVUZCVVR0RlFVVXZRMFVzV1VGRFNVTXNUMEZCTWtJc1JVRkRNMEpETEZGQlFYZERMRVZCUTNoRFF5eFBRVUV3UWl4RlFVTXhRa01zVDBGQk1rSTdTVUZGTTBJc1MwRkJTeXhEUVVGRFNDeFBRVUZQTEVWQlFVVkRMRkZCUVZFc1JVRkJSVU1zVDBGQlR5eEZRVUZGUXl4UFFVRlBMRU5CUVVNN1NVRkRNVU5NTEV0QlFVc3NRMEZCUTAwc2FVSkJRV2xDTEVOQlFVTXNTVUZCU1N4RlFVRkZTeXh4UWtGQmNVSXNRMEZCUXp0SlFVTndSQ3hKUVVGSkxFTkJRVU5LTEVsQlFVa3NSMEZCUnl4elEwRkJjME03UlVGRGRFUTdPMEZCU1VvN1FVRkJRVWNzVDBGQlFTeERRVUZCUXl4eFFrRkJRU3hIUVVGQlFTeHhRa0ZCUVR0QlFVTk5MRTFCUVU5RExHdENRVUZ0UWl4VFFVRlJZaXhSUVVGUk8wVkJSVFZEUlN4WlFVTkpReXhQUVVFeVFpeEZRVU16UWtNc1VVRkJORUlzUlVGRGJrSlZMRWxCUVdsQ0xFVkJRekZDVWl4UFFVRXlRanRKUVVVelFpeExRVUZMTEVOQlFVTklMRTlCUVU4c1JVRkJSVU1zVVVGQlVTeEZRVUZGVXl4clFrRkJhMElzUTBGQlEwVXNWVUZCVlN4RFFVRkRXQ3hSUVVGUkxFVkJRVVZWTEVsQlFVa3NRMEZCUXl4RlFVRkZVaXhQUVVGUExFTkJRVU03WjBKQlNIWkZVU3hKUVVGSk8wbEJTV0ppTEV0QlFVc3NRMEZCUTAwc2FVSkJRV2xDTEVOQlFVTXNTVUZCU1N4RlFVRkZUU3hyUWtGQmEwSXNRMEZCUXp0SlFVTnFSQ3hKUVVGSkxFTkJRVU5NTEVsQlFVa3NSMEZCUnl4blEwRkJaME03UlVGRGFFUTdSVUZGUVR0RlFVTkJMRTlCUVU5UExGVkJRVlZCTEVOQlFVTllMRkZCUVd0Q0xFVkJRVVZWTEVsQlFWazdTVUZET1VNc1RVRkJUVVVzVlVGQlZTeEhRVUZIV2l4UlFVRlJMRU5CUVVOWkxGVkJRVlU3U1VGRGRFTXNUVUZCVFVNc1kwRkJZeXhIUVVGSFF5eHJRa0ZCV1N4RFFVRkRSaXhWUVVGVkxFTkJRVU03U1VGREwwTXNUVUZCVFVjc1YwRkJWeXhIUVVGSFRpeHJRa0ZCYTBJc1EwRkJRMDhzYTBKQlFXdENMRU5CUVVOT0xFbEJRVWtzUTBGQlF5eEpRVU40UXl3eVFrRkJNa0k3U1VGRGJFUXNUMEZCVHl4SlFVRkpSU3hWUVVGVkxFbEJRVWxETEdOQlFXTXNTMEZCUzBVc1YwRkJWeXhGUVVGRk8wVkJRemRFTzBWQlJVRTdSVUZEUVN4SlFVRkpSU3hIUVVGSFFTeERRVUZCTzBsQlEwZ3NUMEZCVDFJc2EwSkJRV3RDTEVOQlFVTlRMRk5CUVZNc1EwRkJReXhKUVVGSkxFTkJRVU5TTEVsQlFVa3NRMEZCUXl4RFFVRkRUeXhIUVVGSE8wVkJRM1JFTzBWQlJVRTdSVUZEUVN4SlFVRkpSaXhYUVVGWFFTeERRVUZCTzBsQlExZ3NUMEZCVDA0c2EwSkJRV3RDTEVOQlFVTlRMRk5CUVZNc1EwRkJReXhKUVVGSkxFTkJRVU5TTEVsQlFVa3NRMEZCUXl4RFFVRkRTeXhYUVVGWE8wVkJRemxFTzBWQlJVRTdSVUZEUVN4SlFVRkpTU3hoUVVGaFFTeERRVUZCTzBsQlEySXNUMEZCVDFZc2EwSkJRV3RDTEVOQlFVTlBMR3RDUVVGclFpeERRVUZETEVsQlFVa3NRMEZCUTA0c1NVRkJTU3hEUVVGRE8wVkJRek5FTzBWQlJVRTdSVUZEUVN4UFFVRlBUU3hyUWtGQmEwSkJMRU5CUVVOT0xFbEJRVms3U1VGRGJFTXNUVUZCVFR0TlFVRkZUeXhIUVVGSE8wMUJRVVZHTzBsQlFWY3NRMEZCUlN4SFFVRkhUaXhyUWtGQmEwSXNRMEZCUTFNc1UwRkJVeXhEUVVGRFVpeEpRVUZKTEVOQlFVTTdTVUZETDBRc1NVRkJTVThzUjBGQlJ5eEZRVUZGTzAxQlEwd3NUMEZCVHl4RFFVRkRSaXhYUVVGWExFZEJRVWNzUjBGQlIwRXNWMEZCVnl4SFFVRkhMRWRCUVVjc1JVRkJSU3hKUVVGSkxFbEJRVWxGTEVkQlFVY3NSMEZCUnp0SlFVTTVSQ3hEUVVGRExFMUJRVTA3VFVGRFNDeFBRVUZQVUN4SlFVRkpMRU5CUVVOVkxFMUJRVTBzUjBGQlIxWXNTVUZCU1N4SFFVRkhWeXhUUVVGVE8wbEJRM3BETzBWQlEwbzdSVUZGUVR0RlFVTkJMRTlCUVU5SUxGTkJRVk5CTEVOQlFVTlNMRWxCUVZrN1NVRkRla0lzU1VGQlNUdE5RVU5CTEUxQlFVMVpMRWxCUVVrc1IwRkJXVU1zU1VGQlNTeERRVUZEUXl4TFFVRkxMRU5CUVVOa0xFbEJRVWtzUTBGQlF6dE5RVU4wUXl4SlFVRkpaU3hyUWtGQlZ5eERRVUZEUXl4aFFVRmhMRU5CUVVORExFbEJRVWtzUTBGQlEwd3NTVUZCU1N4RFFVRkRMRVZCUVVVN1VVRkRkRU1zVDBGQlR6dFZRVU5JVEN4SFFVRkhMRVZCUVZWTExFbEJRVWtzUTBGQlEwMHNTMEZCU3l4RFFVRkRXQ3hIUVVGSE8xVkJRek5DUml4WFFVRlhMRVZCUVVWUExFbEJRVWtzUTBGQlEwMHNTMEZCU3l4RFFVRkRReXhuUWtGQlowSXNTVUZEZUVKUUxFbEJRVWtzUTBGQlEwMHNTMEZCU3l4RFFVRkRZaXhYUVVGWExFbEJRM1JDVHl4SlFVRkpMRU5CUVVOTkxFdEJRVXNzUTBGQlEwVTdVMEZET1VJN1RVRkRUQ3hEUVVGRExFMUJRVTBzU1VGQlNVTXNjMEpCUVZrc1EwRkJRME1zYTBKQlFXdENMRU5CUVVOTUxFbEJRVWtzUTBGQlEwd3NTVUZCU1N4RFFVRkRMRVZCUVVVN1VVRkRia1FzVDBGQlR6dFZRVU5JVEN4SFFVRkhMRVZCUVdGTExFbEJRVWtzUTBGQlEwMHNTMEZCU3p0VlFVTXhRbUlzVjBGQlZ5eEZRVUZMVHl4SlFVRkpMRU5CUVVOWE8xTkJRM2hDTzAxQlEwdzdTVUZEU2l4RFFVRkRMRU5CUVVNc1RVRkJUU3hEUVVGRk8wbEJRMVlzVDBGQlR5eEZRVUZGTzBWQlEySTdPMEZCUjBvN1FVRkJRVEZDTEU5QlFVRXNRMEZCUVVVc2EwSkJRVUVzUjBGQlFVRXNhMEpCUVVFN1FVRkRUU3hOUVVGUGVVSXNhMEpCUVcxQ0xGTkJRVkYwUXl4UlFVRlJPMFZCUlRWRFJTeFpRVU5KUXl4UFFVRXJRaXhGUVVNdlFrTXNVVUZCWjBNc1JVRkRka0p0UXl4VlFVRTJRaXhGUVVOMFEycERMRTlCUVN0Q08wbEJSUzlDTEV0QlFVc3NRMEZCUTBnc1QwRkJUeXhGUVVGRlF5eFJRVUZSTEVWQlFVVnJReXhyUWtGQmEwSXNRMEZCUTNaQ0xGVkJRVlVzUTBGQlEzZENMRlZCUVZVc1EwRkJReXhGUVVGRmFrTXNUMEZCVHl4RFFVRkRPM05DUVVodVJXbERMRlZCUVZVN1NVRkpia0owUXl4TFFVRkxMRU5CUVVOTkxHbENRVUZwUWl4RFFVRkRMRWxCUVVrc1JVRkJSU3RDTEd0Q1FVRnJRaXhEUVVGRE8wbEJRMnBFTEVsQlFVa3NRMEZCUXpsQ0xFbEJRVWtzUjBGQlJ5eHRRMEZCYlVNN1JVRkRia1E3UlVGRlFUdEZRVU5CTEU5QlFVOVBMRlZCUVZWQkxFTkJRVU41UWl4TlFVRnpRanRKUVVOd1F5eEpRVUZCUXl4elFrRkJaU3hGUVVGRFJDeE5RVUZOTEVOQlFVTXNRMEZCUXl4RFFVRkRMRU5CUVVNN1NVRkRNVUlzVFVGQlRYSkNMRmRCUVZjc1IwRkJSeXhIUVVGSGNVSXNUVUZCVFN4RFFVRkRMRU5CUVVNc1EwRkJReXhEUVVGRFJTeEpRVUZKTEVsQlFVbEdMRTFCUVUwc1EwRkJReXhEUVVGRExFTkJRVU1zUTBGQlEyNURMRTlCUVU4c1JVRkJSVHRKUVVNMVJDeFBRVUZQTEdkRFFVRm5RMk1zVjBGQlZ5eEhRVUZITzBWQlEzcEVPenRCUVVkS08wRkJRVUZTTEU5QlFVRXNRMEZCUVRKQ0xHdENRVUZCTEVkQlFVRkJMR3RDUVVGQk8wRkJRMDBzVFVGQlQwc3NiVUpCUVc5Q0xGTkJRVkV6UXl4UlFVRlJPMFZCUlRkRFJTeFpRVU5KUXl4UFFVRXlRaXhGUVVNelFrTXNVVUZCTkVJc1JVRkROVUpETEU5QlFUQkNMRVZCUTJwQ2RVTXNSMEZCYVVNc1JVRkRNVU4wUXl4UFFVRXlRanRKUVVVelFpeExRVUZMTEVOQlFVTklMRTlCUVU4c1JVRkJSVU1zVVVGQlVTeEZRVUZGZFVNc2JVSkJRVzFDTEVOQlFVTTFRaXhWUVVGVkxFTkJRVU5XTEU5QlFVOHNSVUZCUlhWRExFZEJRVWNzUTBGQlF5eEZRVUZGZEVNc1QwRkJUeXhEUVVGRE8yVkJTSFJGYzBNc1IwRkJSenRKUVVsYU0wTXNTMEZCU3l4RFFVRkRUU3hwUWtGQmFVSXNRMEZCUXl4SlFVRkpMRVZCUVVWdlF5eHRRa0ZCYlVJc1EwRkJRenRKUVVOc1JDeEpRVUZKTEVOQlFVTnVReXhKUVVGSkxFZEJRVWNzY1VOQlFYRkRPMFZCUTNKRU8wVkJSVUU3UlVGRFFTeFBRVUZQVHl4VlFVRlZRU3hEUVVGRFNTeFhRVUZ0UWl4RlFVRkZlVUlzUjBGQk1rSTdTVUZET1VRc1RVRkJUVU1zVFVGQlRTeEhRVUZIUXl4TlFVRk5MRU5CUVVORExFOUJRVThzUTBGQlEwZ3NSMEZCUnl4RFFVRkRMRU5CUVVOSkxFZEJRVWNzUTBGQlF5eERRVUZETEVOQlFVTjRReXhKUVVGSkxFVkJRVVV3UWl4TFFVRkxMRU5CUVcxQ0xFdEJRVXNzUTBGQlF5eEhRVUZITVVJc1NVRkJTU3hIUVVGSExFVkJRVVV3UWl4TFFVRkxMRU5CUVVNc1EwRkJRenRKUVVOb1J5eFBRVUZQTEVOQlFVTXNiVUpCUVcxQ1ppeFhRVUZYTEVkQlFVY3NSVUZCUlN4SFFVRkhMRWxCUVVFNFFpeGpRVUZQTEVWQlFVTktMRTFCUVUwc1EwRkJReXhEUVVGRExFTkJRVU5MTEVsQlFVa3NRMEZCUXl4SlFVRkpMRU5CUVVNN1JVRkROMFU3TzBGQlEwaDJReXhQUVVGQkxFTkJRVUZuUXl4dFFrRkJRU3hIUVVGQlFTeHRRa0ZCUVNJc0ltbG5ibTl5WlV4cGMzUWlPbHRkZlE9PSIsIlwidXNlIHN0cmljdFwiO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5BUElTdGF0dXMgPSB2b2lkIDA7XG52YXIgX3V0aWxzID0gcmVxdWlyZShcIi4uLy4uL3V0aWxzLmpzXCIpO1xudmFyIF91dGlsc0RvbSA9IHJlcXVpcmUoXCIuL3V0aWxzLWRvbS5qc1wiKTtcbnZhciBfbG9nRXJyb3IgPSByZXF1aXJlKFwiLi4vLi4vbG9nLWVycm9yLmpzXCIpO1xuLy8gSG9tZWJyaWRnZSBwbHVnaW4gZm9yIEhvbWUgQ29ubmVjdCBob21lIGFwcGxpYW5jZXNcbi8vIENvcHlyaWdodCDCqSAyMDI0LTIwMjYgQWxleGFuZGVyIFRob3VreWRpZGVzXG5cbi8vIFVSTCBmb3IgdGhlIHNlcnZlciBzdGF0dXMgaW1hZ2VcbmNvbnN0IFNUQVRVU19VUkwgPSAnaHR0cHM6Ly9ob21lY29ubmVjdC50aG91a3kuY28udWsvYXBpL2ltYWdlcy9wbHVnaW4tc3RhdHVzLnN2Zyc7XG4vLyBXYXJuIGZvciBlcnJvcnMgbW9yZSByZWNlbnQgdGhhbiB0aGlzXG5jb25zdCBTVEFUVVNfU0lOQ0UgPSAyNCAqIDYwICogNjAgKiBfdXRpbHMuTVM7XG4vLyBJbnRlcnZhbCB0byBwb2xsIGZvciB1cGRhdGVzIChpZiB0aGVyZSBhcmUgaXNzdWVzKVxuY29uc3QgUE9MTF9JTlRFUlZBTCA9IDIuNSAqIDYwICogX3V0aWxzLk1TO1xuLy8gSG9tZSBDb25uZWN0IEFQSSBzZXJ2ZXIgc3RhdHVzXG5jbGFzcyBBUElTdGF0dXMge1xuICAvLyBDcmVhdGUgYSBuZXcgQVBJIHNlcnZlciBzdGF0dXMgY2hlY2tlclxuICBjb25zdHJ1Y3Rvcihsb2cpIHtcbiAgICB0aGlzLmxvZyA9IGxvZztcbiAgICAoMCwgX2xvZ0Vycm9yLmRldGFjaGVkKSh0aGlzLmxvZywgJ1BvbGwgc3RhdHVzJywgKCkgPT4gdGhpcy5wb2xsU3RhdHVzKCkpKCk7XG4gIH1cbiAgLy8gQ2hlY2sgdGhlIHN0YXR1cyBvZiB0aGUgSG9tZSBDb25uZWN0IEFQSSBzZXJ2ZXJzXG4gIGFzeW5jIHBvbGxTdGF0dXMoKSB7XG4gICAgbGV0IHBvbGxBZ2FpbiA9IHRydWU7XG4gICAgd2hpbGUgKHBvbGxBZ2Fpbikge1xuICAgICAgLy8gQXR0ZW1wdCB0byBmZXRjaCB0aGUgc3RhdHVzIGltYWdlXG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKFNUQVRVU19VUkwpO1xuICAgICAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgICAgICB0aGlzLmxvZy53YXJuKCdjaGVja1N0YXR1cyBmZXRjaCcsIHJlc3BvbnNlLnN0YXR1c1RleHQpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBjb25zdCBzdmcgPSBhd2FpdCByZXNwb25zZS50ZXh0KCk7XG4gICAgICAvLyBBdHRlbXB0IHRvIHBhcnNlIHRoZSBzdGF0dXMgaGVhZGVyXG4gICAgICBsZXQgc3RhdHVzO1xuICAgICAgdHJ5IHtcbiAgICAgICAgc3RhdHVzID0gSlNPTi5wYXJzZShyZXNwb25zZS5oZWFkZXJzLmdldCgnWC1TZXJ2ZXItU3RhdHVzJykgPz8gJycpO1xuICAgICAgICAoMCwgX3V0aWxzLmFzc2VydElzQm9vbGVhbikoc3RhdHVzLnVwKTtcbiAgICAgICAgKDAsIF91dGlscy5hc3NlcnRJc051bWJlcikoc3RhdHVzLnNpbmNlKTtcbiAgICAgICAgKDAsIF91dGlscy5hc3NlcnRJc051bWJlcikoc3RhdHVzLnVwZGF0ZWQpO1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIHRoaXMubG9nLndhcm4oJ2NoZWNrU3RhdHVzIFgtU2VydmVyLVN0YXR1cycsIGVycik7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIC8vIFVwZGF0ZSB0aGUgZGlzcGxheWVkIHN0YXR1cywgaWYgaXQgaGFzIGNoYW5nZWRcbiAgICAgIGlmICh0aGlzLmxhc3RVcGRhdGVkICE9PSBzdGF0dXMudXBkYXRlZCkge1xuICAgICAgICB0aGlzLmxhc3RVcGRhdGVkID0gc3RhdHVzLnVwZGF0ZWQ7XG4gICAgICAgIHBvbGxBZ2FpbiA9IHRoaXMuc2hvd1N0YXR1cyhzdmcsIHN0YXR1cyk7XG4gICAgICB9XG4gICAgICAvLyBEZWxheSBiZWZvcmUgcG9sbGluZyB0aGUgc3RhdHVzIGFnYWluIChpZiB0aGVyZSBhcmUgc2VydmVyIGlzc3VlcylcbiAgICAgIGF3YWl0IG5ldyBQcm9taXNlKHJlc29sdmUgPT4gc2V0VGltZW91dChyZXNvbHZlLCBQT0xMX0lOVEVSVkFMKSk7XG4gICAgfVxuICB9XG4gIC8vIERpc3BsYXkgdGhlIGxhdGVzdCBzdGF0dXMgb2YgdGhlIEhvbWUgQ29ubmVjdCBBUEkgc2VydmVyc1xuICBzaG93U3RhdHVzKHN2Zywgc3RhdHVzKSB7XG4gICAgLy8gRGlzcGxheSB0aGUgYXBwcm9wcmlhdGUgc3VtbWFyeVxuICAgICgwLCBfdXRpbHNEb20uZ2V0RWxlbWVudEJ5SWQpKCdoYy1hcGktdXAnKS5oaWRkZW4gPSAhc3RhdHVzLnVwO1xuICAgICgwLCBfdXRpbHNEb20uZ2V0RWxlbWVudEJ5SWQpKCdoYy1hcGktdXAyJykuaGlkZGVuID0gIXN0YXR1cy51cDtcbiAgICAoMCwgX3V0aWxzRG9tLmdldEVsZW1lbnRCeUlkKSgnaGMtYXBpLWRvd24nKS5oaWRkZW4gPSBzdGF0dXMudXA7XG4gICAgKDAsIF91dGlsc0RvbS5nZXRFbGVtZW50QnlJZCkoJ2hjLWFwaS1kb3duMicpLmhpZGRlbiA9IHN0YXR1cy51cDtcbiAgICAvLyBBZGQgdGhlIGRldGFpbGVkIHN0YXR1c1xuICAgICgwLCBfdXRpbHNEb20uZ2V0RWxlbWVudEJ5SWQpKCdoYy1hcGktc2luY2UnKS5pbm5lclRleHQgPSB0aGlzLmZvcm1hdERhdGVUaW1lKHN0YXR1cy5zaW5jZSk7XG4gICAgLy8gQWRkIHRoZSByZXRyaWV2ZWQgc3RhdHVzIGltYWdlXG4gICAgKDAsIF91dGlsc0RvbS5nZXRFbGVtZW50QnlJZCkoJ2hjLWFwaS1zdmcnKS5pbm5lckhUTUwgPSBzdmc7XG4gICAgLy8gU2hvdyBvciBoaWRlIHRoZSBzdGF0dXMgYXMgYXBwcm9wcmlhdGVcbiAgICBjb25zdCBzaG93U3RhdHVzID0gIXN0YXR1cy51cCB8fCBEYXRlLm5vdygpIDwgc3RhdHVzLnNpbmNlICsgU1RBVFVTX1NJTkNFO1xuICAgICgwLCBfdXRpbHNEb20uZ2V0RWxlbWVudEJ5SWQpKCdoYy1hcGktc3RhdHVzJykuaGlkZGVuID0gIXNob3dTdGF0dXM7XG4gICAgcmV0dXJuIHNob3dTdGF0dXM7XG4gIH1cbiAgLy8gRm9ybWF0IGEgZGF0ZS90aW1lXG4gIGZvcm1hdERhdGVUaW1lKGRhdGUpIHtcbiAgICByZXR1cm4gbmV3IERhdGUoZGF0ZSkudG9Mb2NhbGVTdHJpbmcodW5kZWZpbmVkLCB7XG4gICAgICB3ZWVrZGF5OiAnbG9uZycsXG4gICAgICBtb250aDogJ2xvbmcnLFxuICAgICAgZGF5OiAnbnVtZXJpYycsXG4gICAgICBob3VyOiAnbnVtZXJpYycsXG4gICAgICBtaW51dGU6ICcyLWRpZ2l0JyxcbiAgICAgIHRpbWVab25lTmFtZTogJ3Nob3J0J1xuICAgIH0pO1xuICB9XG59XG5leHBvcnRzLkFQSVN0YXR1cyA9IEFQSVN0YXR1cztcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRhdGE6YXBwbGljYXRpb24vanNvbjtjaGFyc2V0PXV0Zi04O2Jhc2U2NCxleUoyWlhKemFXOXVJam96TENKdVlXMWxjeUk2V3lKZmRYUnBiSE1pTENKeVpYRjFhWEpsSWl3aVgzVjBhV3h6Ukc5dElpd2lYMnh2WjBWeWNtOXlJaXdpVTFSQlZGVlRYMVZTVENJc0lsTlVRVlJWVTE5VFNVNURSU0lzSWsxVElpd2lVRTlNVEY5SlRsUkZVbFpCVENJc0lrRlFTVk4wWVhSMWN5SXNJbU52Ym5OMGNuVmpkRzl5SWl3aWJHOW5JaXdpWkdWMFlXTm9aV1FpTENKd2IyeHNVM1JoZEhWeklpd2ljRzlzYkVGbllXbHVJaXdpY21WemNHOXVjMlVpTENKbVpYUmphQ0lzSW05cklpd2lkMkZ5YmlJc0luTjBZWFIxYzFSbGVIUWlMQ0p6ZG1jaUxDSjBaWGgwSWl3aWMzUmhkSFZ6SWl3aVNsTlBUaUlzSW5CaGNuTmxJaXdpYUdWaFpHVnljeUlzSW1kbGRDSXNJbUZ6YzJWeWRFbHpRbTl2YkdWaGJpSXNJblZ3SWl3aVlYTnpaWEowU1hOT2RXMWlaWElpTENKemFXNWpaU0lzSW5Wd1pHRjBaV1FpTENKbGNuSWlMQ0pzWVhOMFZYQmtZWFJsWkNJc0luTm9iM2RUZEdGMGRYTWlMQ0pRY205dGFYTmxJaXdpY21WemIyeDJaU0lzSW5ObGRGUnBiV1Z2ZFhRaUxDSm5aWFJGYkdWdFpXNTBRbmxKWkNJc0ltaHBaR1JsYmlJc0ltbHVibVZ5VkdWNGRDSXNJbVp2Y20xaGRFUmhkR1ZVYVcxbElpd2lhVzV1WlhKSVZFMU1JaXdpUkdGMFpTSXNJbTV2ZHlJc0ltUmhkR1VpTENKMGIweHZZMkZzWlZOMGNtbHVaeUlzSW5WdVpHVm1hVzVsWkNJc0luZGxaV3RrWVhraUxDSnRiMjUwYUNJc0ltUmhlU0lzSW1odmRYSWlMQ0p0YVc1MWRHVWlMQ0owYVcxbFdtOXVaVTVoYldVaUxDSmxlSEJ2Y25SeklsMHNJbk52ZFhKalpYTWlPbHNpTGk0dkxpNHZMaTR2YzNKakwyaHZiV1ZpY21sa1oyVXRkV2t2Y0hWaWJHbGpMMkZ3YVMxemRHRjBkWE11ZEhNaVhTd2ljMjkxY21ObGMwTnZiblJsYm5RaU9sdHVkV3hzWFN3aWJXRndjR2x1WjNNaU9pSTdPenM3T3p0QlFVbEJMRWxCUVVGQkxFMUJRVUVzUjBGQlFVTXNUMEZCUVR0QlFVTkJMRWxCUVVGRExGTkJRVUVzUjBGQlFVUXNUMEZCUVR0QlFVTkJMRWxCUVVGRkxGTkJRVUVzUjBGQlFVWXNUMEZCUVR0QlFVNUJPMEZCUTBFN08wRkJUMEU3UVVGRFFTeE5RVUZOUnl4VlFVRlZMRWRCUVVjc0swUkJRU3RFTzBGQlJXeEdPMEZCUTBFc1RVRkJUVU1zV1VGQldTeEhRVUZITEVWQlFVVXNSMEZCUnl4RlFVRkZMRWRCUVVjc1JVRkJSU3hIUVVGSFF5eFRRVUZGTzBGQlJYUkRPMEZCUTBFc1RVRkJUVU1zWVVGQllTeEhRVUZITEVkQlFVY3NSMEZCUnl4RlFVRkZMRWRCUVVkRUxGTkJRVVU3UVVGVGJrTTdRVUZEVFN4TlFVRlBSU3hUUVVGVE8wVkJTMnhDTzBWQlEwRkRMRmxCUVhGQ1F5eEhRVUZYTzJWQlFWaEJMRWRCUVVjN1NVRkRjRUlzU1VGQlFVTXNhMEpCUVZFc1JVRkJReXhKUVVGSkxFTkJRVU5FTEVkQlFVY3NSVUZCUlN4aFFVRmhMRVZCUVVVc1RVRkJUU3hKUVVGSkxFTkJRVU5GTEZWQlFWVXNSVUZCUlN4RFFVRkRMRVZCUVVVN1JVRkRhRVU3UlVGRlFUdEZRVU5CTEUxQlFVMUJMRlZCUVZWQkxFTkJRVUU3U1VGRFdpeEpRVUZKUXl4VFFVRlRMRWRCUVVjc1NVRkJTVHRKUVVOd1FpeFBRVUZQUVN4VFFVRlRMRVZCUVVVN1RVRkRaRHROUVVOQkxFMUJRVTFETEZGQlFWRXNSMEZCUnl4TlFVRk5ReXhMUVVGTExFTkJRVU5ZTEZWQlFWVXNRMEZCUXp0TlFVTjRReXhKUVVGSkxFTkJRVU5WTEZGQlFWRXNRMEZCUTBVc1JVRkJSU3hGUVVGRk8xRkJRMlFzU1VGQlNTeERRVUZEVGl4SFFVRkhMRU5CUVVOUExFbEJRVWtzUTBGQlF5eHRRa0ZCYlVJc1JVRkJSVWdzVVVGQlVTeERRVUZEU1N4VlFVRlZMRU5CUVVNN1VVRkRka1E3VFVGRFNqdE5RVU5CTEUxQlFVMURMRWRCUVVjc1IwRkJSeXhOUVVGTlRDeFJRVUZSTEVOQlFVTk5MRWxCUVVrc1JVRkJSVHROUVVWcVF6dE5RVU5CTEVsQlFVbERMRTFCUVUwN1RVRkRWaXhKUVVGSk8xRkJRMEZCTEUxQlFVMHNSMEZCUjBNc1NVRkJTU3hEUVVGRFF5eExRVUZMTEVOQlFVTlVMRkZCUVZFc1EwRkJRMVVzVDBGQlR5eERRVUZEUXl4SFFVRkhMRU5CUVVNc2FVSkJRV2xDTEVOQlFVTXNTVUZCU1N4RlFVRkZMRU5CUVdsQ08xRkJRMnhHTEVsQlFVRkRMSE5DUVVGbExFVkJRVU5NTEUxQlFVMHNRMEZCUTAwc1JVRkJSU3hEUVVGRE8xRkJRekZDTEVsQlFVRkRMSEZDUVVGakxFVkJRVU5RTEUxQlFVMHNRMEZCUTFFc1MwRkJTeXhEUVVGRE8xRkJRelZDTEVsQlFVRkVMSEZDUVVGakxFVkJRVU5RTEUxQlFVMHNRMEZCUTFNc1QwRkJUeXhEUVVGRE8wMUJRMnhETEVOQlFVTXNRMEZCUXl4UFFVRlBReXhIUVVGSExFVkJRVVU3VVVGRFZpeEpRVUZKTEVOQlFVTnlRaXhIUVVGSExFTkJRVU5QTEVsQlFVa3NRMEZCUXl3MlFrRkJOa0lzUlVGQlJXTXNSMEZCUnl4RFFVRkRPMUZCUTJwRU8wMUJRMG83VFVGRlFUdE5RVU5CTEVsQlFVa3NTVUZCU1N4RFFVRkRReXhYUVVGWExFdEJRVXRZTEUxQlFVMHNRMEZCUTFNc1QwRkJUeXhGUVVGRk8xRkJRM0pETEVsQlFVa3NRMEZCUTBVc1YwRkJWeXhIUVVGSFdDeE5RVUZOTEVOQlFVTlRMRTlCUVU4N1VVRkRha05xUWl4VFFVRlRMRWRCUVVjc1NVRkJTU3hEUVVGRGIwSXNWVUZCVlN4RFFVRkRaQ3hIUVVGSExFVkJRVVZGTEUxQlFVMHNRMEZCUXp0TlFVTTFRenROUVVWQk8wMUJRMEVzVFVGQlRTeEpRVUZKWVN4UFFVRlBMRU5CUVVORExFOUJRVThzU1VGQlNVTXNWVUZCVlN4RFFVRkRSQ3hQUVVGUExFVkJRVVUxUWl4aFFVRmhMRU5CUVVNc1EwRkJRenRKUVVOd1JUdEZRVU5LTzBWQlJVRTdSVUZEUVRCQ0xGVkJRVlZCTEVOQlFVTmtMRWRCUVZjc1JVRkJSVVVzVFVGQmIwSTdTVUZEZUVNN1NVRkRRU3hKUVVGQlowSXNkMEpCUVdNc1JVRkJReXhYUVVGWExFTkJRVU1zUTBGQlEwTXNUVUZCVFN4SFFVRkhMRU5CUVVOcVFpeE5RVUZOTEVOQlFVTk5MRVZCUVVVN1NVRkRMME1zU1VGQlFWVXNkMEpCUVdNc1JVRkJReXhaUVVGWkxFTkJRVU1zUTBGQlEwTXNUVUZCVFN4SFFVRkhMRU5CUVVOcVFpeE5RVUZOTEVOQlFVTk5MRVZCUVVVN1NVRkRhRVFzU1VGQlFWVXNkMEpCUVdNc1JVRkJReXhoUVVGaExFTkJRVU1zUTBGQlEwTXNUVUZCVFN4SFFVRkhha0lzVFVGQlRTeERRVUZEVFN4RlFVRkZPMGxCUTJoRUxFbEJRVUZWTEhkQ1FVRmpMRVZCUVVNc1kwRkJZeXhEUVVGRExFTkJRVU5ETEUxQlFVMHNSMEZCUjJwQ0xFMUJRVTBzUTBGQlEwMHNSVUZCUlR0SlFVVnFSRHRKUVVOQkxFbEJRVUZWTEhkQ1FVRmpMRVZCUVVNc1kwRkJZeXhEUVVGRExFTkJRVU5GTEZOQlFWTXNSMEZCUnl4SlFVRkpMRU5CUVVORExHTkJRV01zUTBGQlEyNUNMRTFCUVUwc1EwRkJRMUVzUzBGQlN5eERRVUZETzBsQlJUVkZPMGxCUTBFc1NVRkJRVkVzZDBKQlFXTXNSVUZCUXl4WlFVRlpMRU5CUVVNc1EwRkJRMGtzVTBGQlV5eEhRVUZIZEVJc1IwRkJSenRKUVVVMVF6dEpRVU5CTEUxQlFVMWpMRlZCUVZVc1IwRkJSeXhEUVVGRFdpeE5RVUZOTEVOQlFVTk5MRVZCUVVVc1NVRkJTV1VzU1VGQlNTeERRVUZEUXl4SFFVRkhMRVZCUVVVc1IwRkJSM1JDTEUxQlFVMHNRMEZCUTFFc1MwRkJTeXhIUVVGSGVFSXNXVUZCV1R0SlFVTjZSU3hKUVVGQlowTXNkMEpCUVdNc1JVRkJReXhsUVVGbExFTkJRVU1zUTBGQlEwTXNUVUZCVFN4SFFVRkhMRU5CUVVOTUxGVkJRVlU3U1VGRGNFUXNUMEZCVDBFc1ZVRkJWVHRGUVVOeVFqdEZRVVZCTzBWQlEwRlBMR05CUVdOQkxFTkJRVU5KTEVsQlFWazdTVUZEZGtJc1QwRkJUeXhKUVVGSlJpeEpRVUZKTEVOQlFVTkZMRWxCUVVrc1EwRkJReXhEUVVGRFF5eGpRVUZqTEVOQlFVTkRMRk5CUVZNc1JVRkJSVHROUVVNMVEwTXNUMEZCVHl4RlFVRlRMRTFCUVUwN1RVRkRkRUpETEV0QlFVc3NSVUZCVnl4TlFVRk5PMDFCUTNSQ1F5eEhRVUZITEVWQlFXRXNVMEZCVXp0TlFVTjZRa01zU1VGQlNTeEZRVUZaTEZOQlFWTTdUVUZEZWtKRExFMUJRVTBzUlVGQlZTeFRRVUZUTzAxQlEzcENReXhaUVVGWkxFVkJRVWs3UzBGRGJrSXNRMEZCUXp0RlFVTk9PenRCUVVOSVF5eFBRVUZCTEVOQlFVRTNReXhUUVVGQkxFZEJRVUZCTEZOQlFVRWlMQ0pwWjI1dmNtVk1hWE4wSWpwYlhYMD0iLCJcInVzZSBzdHJpY3RcIjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuQ2FyZHMgPSB2b2lkIDA7XG52YXIgX3V0aWxzID0gcmVxdWlyZShcIi4uLy4uL3V0aWxzLmpzXCIpO1xudmFyIF91dGlsc0RvbSA9IHJlcXVpcmUoXCIuL3V0aWxzLWRvbS5qc1wiKTtcbnZhciBfbG9nRXJyb3IgPSByZXF1aXJlKFwiLi4vLi4vbG9nLWVycm9yLmpzXCIpO1xuLy8gSG9tZWJyaWRnZSBwbHVnaW4gZm9yIEhvbWUgQ29ubmVjdCBob21lIGFwcGxpYW5jZXNcbi8vIENvcHlyaWdodCDCqSAyMDIzLTIwMjYgQWxleGFuZGVyIFRob3VreWRpZGVzXG5cbi8vIENhcmRzIHRvIHNlbGVjdCBnbG9iYWwgb3IgcGVyLWFwcGxpYW5jZSBjb25maWd1cmF0aW9uXG5jbGFzcyBDYXJkcyB7XG4gIC8vIENvbnN0cnVjdCBhIG5ldyBjYXJkcyBoYW5kbGVyXG4gIGNvbnN0cnVjdG9yKGxvZykge1xuICAgIHRoaXMubG9nID0gbG9nO1xuICAgIC8vIEN1cnJlbnQgY2FyZHNcbiAgICB0aGlzLm5vbkFwcGxpYW5jZUNhcmRzID0gW107XG4gICAgdGhpcy5hcHBsaWFuY2VDYXJkcyA9IFtdO1xuICAgIHRoaXMucGFyZW50RWxlbWVudCA9ICgwLCBfdXRpbHNEb20uZ2V0RWxlbWVudEJ5SWQpKCdoYy1hcHBsaWFuY2UtY2FyZHMnKTtcbiAgfVxuICAvLyBVcGRhdGUgdGhlIGxpc3Qgb2Ygbm9uLWFwcGxpYW5jZSBjYXJkc1xuICBzZXROb25BcHBsaWFuY2VzKGNhcmRzKSB7XG4gICAgdGhpcy5ub25BcHBsaWFuY2VDYXJkcyA9IGNhcmRzO1xuICAgIHRoaXMudXBkYXRlQ2FyZHMoKTtcbiAgfVxuICAvLyBVcGRhdGUgdGhlIGxpc3Qgb2YgYXBwbGlhbmNlc1xuICBzZXRBcHBsaWFuY2VzKGFwcGxpYW5jZXMpIHtcbiAgICAvLyBDb252ZXJ0IHRoZSBhcHBsaWFuY2VzIHRvIGNhcmQgZGVzY3JpcHRpb25zXG4gICAgY29uc3QgYXBwbGlhbmNlQ2FyZHMgPSBhcHBsaWFuY2VzLm1hcChhcHBsaWFuY2UgPT4gKHtcbiAgICAgIGlkOiBhcHBsaWFuY2UuaGFJZCxcbiAgICAgIGljb246IGFwcGxpYW5jZS50eXBlLnRvTG9jYWxlTG93ZXJDYXNlKCksXG4gICAgICBuYW1lOiBhcHBsaWFuY2UubmFtZSxcbiAgICAgIGRldGFpbDogYCR7YXBwbGlhbmNlLmJyYW5kfSAke2FwcGxpYW5jZS5lbnVtYmVyfWBcbiAgICB9KSk7XG4gICAgYXBwbGlhbmNlQ2FyZHMuc29ydCgoYSwgYikgPT4gYS5uYW1lLmxvY2FsZUNvbXBhcmUoYi5uYW1lKSk7XG4gICAgLy8gQ2hlY2sgd2hldGhlciB0aGUgbGlzdCBvZiBhcHBsaWFuY2VzIGhhcyBjaGFuZ2VkXG4gICAgaWYgKEpTT04uc3RyaW5naWZ5KGFwcGxpYW5jZUNhcmRzKSAhPT0gSlNPTi5zdHJpbmdpZnkodGhpcy5hcHBsaWFuY2VDYXJkcykpIHtcbiAgICAgIHRoaXMuYXBwbGlhbmNlQ2FyZHMgPSBhcHBsaWFuY2VDYXJkcztcbiAgICAgIHRoaXMudXBkYXRlQ2FyZHMoKTtcbiAgICB9XG4gIH1cbiAgLy8gVXBkYXRlIHRoZSBsaXN0IG9mIGNhcmRzIGFuZCByZXN0b3JlIHRoZSBzZWxlY3Rpb24sIGlmIHN0aWxsIHZhbGlkXG4gIHVwZGF0ZUNhcmRzKCkge1xuICAgIC8vIFJlcGxhY2UgdGhlIGV4aXN0aW5nIGNhcmRzIHdpdGggbmV3IG9uZXNcbiAgICBjb25zdCBhbGxDYXJkcyA9IFsuLi50aGlzLm5vbkFwcGxpYW5jZUNhcmRzLCAuLi50aGlzLmFwcGxpYW5jZUNhcmRzXTtcbiAgICB0aGlzLnBhcmVudEVsZW1lbnQucmVwbGFjZUNoaWxkcmVuKC4uLmFsbENhcmRzLm1hcChjYXJkID0+IHRoaXMubWFrZUNhcmQoY2FyZCkpKTtcbiAgICB0aGlzLnBhcmVudEVsZW1lbnQuaGlkZGVuID0gIWFsbENhcmRzLmxlbmd0aDtcbiAgICAvLyBSZXN0b3JlIGFueSBwcmV2aW91cyBzZWxlY3Rpb25cbiAgICB0aGlzLnNlbGVjdENhcmQodGhpcy5zZWxlY3RlZENhcmRJZCk7XG4gIH1cbiAgLy8gQ3JlYXRlIGEgbmV3IGNhcmRcbiAgbWFrZUNhcmQoe1xuICAgIGlkLFxuICAgIGljb24sXG4gICAgbmFtZSxcbiAgICBkZXRhaWxcbiAgfSkge1xuICAgIC8vIENyZWF0ZSBhIG5ldyBjYXJkIGZyb20gdGhlIHRlbXBsYXRlXG4gICAgZGV0YWlsID8/IChkZXRhaWwgPSAnwqAnKTsgLy8gKG5vbi1icmVha2luZyBzcGFjZSlcbiAgICBjb25zdCBjYXJkID0gKDAsIF91dGlsc0RvbS5jbG9uZVRlbXBsYXRlKSgnaGMtYXBwbGlhbmNlLWNhcmQnLCB7XG4gICAgICBuYW1lLFxuICAgICAgZGV0YWlsXG4gICAgfSk7XG4gICAgKDAsIF9sb2dFcnJvci5kZXRhY2hlZCkodGhpcy5sb2csICdMb2FkIGNhcmQgaWNvbicsICgpID0+IHRoaXMubG9hZENhcmRJY29uKCgwLCBfdXRpbHNEb20uZ2V0U2xvdCkoY2FyZCwgJ2ljb24nKSwgYC4vaW1hZ2VzL2ljb24tJHtpY29ufS5zdmdgLCBpZCkpKCk7XG4gICAgLy8gSGFuZGxlIGNhcmQgc2VsZWN0aW9uXG4gICAgY29uc3QgZWxlbWVudCA9IGNhcmQuY2hpbGRyZW5bMF07XG4gICAgKDAsIF91dGlscy5hc3NlcnRJc0luc3RhbmNlT2YpKGVsZW1lbnQsIEhUTUxFbGVtZW50KTtcbiAgICBlbGVtZW50LmRhdGFzZXQuaWQgPSBpZDtcbiAgICBlbGVtZW50Lm9uY2xpY2sgPSAoKSA9PiB7XG4gICAgICB0aGlzLnNlbGVjdENhcmQoaWQpO1xuICAgIH07XG4gICAgcmV0dXJuIGNhcmQ7XG4gIH1cbiAgLy8gTG9hZCB0aGUgaWNvbiBpbWFnZSBmb3IgYSBjYXJkXG4gIGFzeW5jIGxvYWRDYXJkSWNvbihlbGVtZW50LCB1cmwsIGlkKSB7XG4gICAgLy8gTG9hZCB0aGUgaWNvbiBhbmQgYWRkIGl0IHRvIHRoZSBjYXJkXG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCh1cmwpO1xuICAgIGlmICghcmVzcG9uc2Uub2spIHRocm93IG5ldyBFcnJvcihgRmFpbGVkIHRvIGZldGNoIGljb24gJHtyZXNwb25zZS51cmx9OiAke3Jlc3BvbnNlLnN0YXR1c1RleHR9YCk7XG4gICAgZWxlbWVudC5pbm5lckhUTUwgPSBhd2FpdCByZXNwb25zZS50ZXh0KCk7XG4gICAgLy8gQ2hhbmdlIHRoZSBncm91cCAobGF5ZXIpIElEcyB0byBjbGFzc2VzXG4gICAgZWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKCdnW2lkXScpLmZvckVhY2goZ3JvdXAgPT4ge1xuICAgICAgY29uc3QgaWQgPSBncm91cC5nZXRBdHRyaWJ1dGUoJ2lkJyk7XG4gICAgICAoMCwgX3V0aWxzLmFzc2VydElzRGVmaW5lZCkoaWQpO1xuICAgICAgZ3JvdXAucmVtb3ZlQXR0cmlidXRlKCdpZCcpO1xuICAgICAgZ3JvdXAuY2xhc3NMaXN0LmFkZChpZCk7XG4gICAgfSk7XG4gICAgLy8gQXNzaWduIHVuaXF1ZSBJRHMgdG8gZ3JhZGllbnQgZmlsbHNcbiAgICBlbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ2RlZnMgW2lkXScpLmZvckVhY2goZGVmID0+IHtcbiAgICAgIGNvbnN0IG9sZElkID0gZGVmLmdldEF0dHJpYnV0ZSgnaWQnKTtcbiAgICAgIGNvbnN0IG5ld0lkID0gYCR7aWR9LSR7b2xkSWR9YDtcbiAgICAgIGRlZi5zZXRBdHRyaWJ1dGUoJ2lkJywgbmV3SWQpO1xuICAgICAgZWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKGBbZmlsbD0ndXJsKCMke29sZElkfSknXWApLmZvckVhY2gocmVmID0+IHtcbiAgICAgICAgcmVmLnNldEF0dHJpYnV0ZSgnZmlsbCcsIGB1cmwoIyR7bmV3SWR9KWApO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cbiAgLy8gQSBjYXJkIGhhcyBiZWVuIHNlbGVjdGVkXG4gIHNlbGVjdENhcmQoaWQpIHtcbiAgICAvLyBTZWxlY3QgdGhpcyBjYXJkIGFuZCBkZXNlbGVjdCBhbGwgb3RoZXJzXG4gICAgbGV0IHNlbGVjdGVkQ2FyZDtcbiAgICBmb3IgKGNvbnN0IGNhcmQgb2YgQXJyYXkuZnJvbSh0aGlzLnBhcmVudEVsZW1lbnQuY2hpbGRyZW4pKSB7XG4gICAgICAoMCwgX3V0aWxzLmFzc2VydElzSW5zdGFuY2VPZikoY2FyZCwgSFRNTEVsZW1lbnQpO1xuICAgICAgaWYgKGNhcmQuZGF0YXNldC5pZCA9PT0gaWQpIHNlbGVjdGVkQ2FyZCA9IGNhcmQ7XG4gICAgICBjYXJkLmNsYXNzTGlzdC50b2dnbGUoJ2hjLXNlbGVjdGVkJywgY2FyZC5kYXRhc2V0LmlkID09PSBpZCk7XG4gICAgfVxuICAgIGlmICghc2VsZWN0ZWRDYXJkKSBpZCA9IHVuZGVmaW5lZDtcbiAgICAvLyBOb3RpZnkgdGhlIGNsaWVudCBvZiBzZWxlY3Rpb24gY2hhbmdlc1xuICAgIGlmICh0aGlzLnNlbGVjdGVkQ2FyZElkICE9PSBpZCkge1xuICAgICAgdGhpcy5sb2cuZGVidWcoYG9uU2VsZWN0KCR7aWR9KSAod2FzICR7dGhpcy5zZWxlY3RlZENhcmRJZH0pYCk7XG4gICAgICB0aGlzLnNlbGVjdGVkQ2FyZElkID0gaWQ7XG4gICAgICB0aGlzLm9uU2VsZWN0Py4oaWQpO1xuICAgIH1cbiAgfVxufVxuZXhwb3J0cy5DYXJkcyA9IENhcmRzO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ9dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p1WVcxbGN5STZXeUpmZFhScGJITWlMQ0p5WlhGMWFYSmxJaXdpWDNWMGFXeHpSRzl0SWl3aVgyeHZaMFZ5Y205eUlpd2lRMkZ5WkhNaUxDSmpiMjV6ZEhKMVkzUnZjaUlzSW14dlp5SXNJbTV2YmtGd2NHeHBZVzVqWlVOaGNtUnpJaXdpWVhCd2JHbGhibU5sUTJGeVpITWlMQ0p3WVhKbGJuUkZiR1Z0Wlc1MElpd2laMlYwUld4bGJXVnVkRUo1U1dRaUxDSnpaWFJPYjI1QmNIQnNhV0Z1WTJWeklpd2lZMkZ5WkhNaUxDSjFjR1JoZEdWRFlYSmtjeUlzSW5ObGRFRndjR3hwWVc1alpYTWlMQ0poY0hCc2FXRnVZMlZ6SWl3aWJXRndJaXdpWVhCd2JHbGhibU5sSWl3aWFXUWlMQ0pvWVVsa0lpd2lhV052YmlJc0luUjVjR1VpTENKMGIweHZZMkZzWlV4dmQyVnlRMkZ6WlNJc0ltNWhiV1VpTENKa1pYUmhhV3dpTENKaWNtRnVaQ0lzSW1WdWRXMWlaWElpTENKemIzSjBJaXdpWVNJc0ltSWlMQ0pzYjJOaGJHVkRiMjF3WVhKbElpd2lTbE5QVGlJc0luTjBjbWx1WjJsbWVTSXNJbUZzYkVOaGNtUnpJaXdpY21Wd2JHRmpaVU5vYVd4a2NtVnVJaXdpWTJGeVpDSXNJbTFoYTJWRFlYSmtJaXdpYUdsa1pHVnVJaXdpYkdWdVozUm9JaXdpYzJWc1pXTjBRMkZ5WkNJc0luTmxiR1ZqZEdWa1EyRnlaRWxrSWl3aVkyeHZibVZVWlcxd2JHRjBaU0lzSW1SbGRHRmphR1ZrSWl3aWJHOWhaRU5oY21SSlkyOXVJaXdpWjJWMFUyeHZkQ0lzSW1Wc1pXMWxiblFpTENKamFHbHNaSEpsYmlJc0ltRnpjMlZ5ZEVselNXNXpkR0Z1WTJWUFppSXNJa2hVVFV4RmJHVnRaVzUwSWl3aVpHRjBZWE5sZENJc0ltOXVZMnhwWTJzaUxDSjFjbXdpTENKeVpYTndiMjV6WlNJc0ltWmxkR05vSWl3aWIyc2lMQ0pGY25KdmNpSXNJbk4wWVhSMWMxUmxlSFFpTENKcGJtNWxja2hVVFV3aUxDSjBaWGgwSWl3aWNYVmxjbmxUWld4bFkzUnZja0ZzYkNJc0ltWnZja1ZoWTJnaUxDSm5jbTkxY0NJc0ltZGxkRUYwZEhKcFluVjBaU0lzSW1GemMyVnlkRWx6UkdWbWFXNWxaQ0lzSW5KbGJXOTJaVUYwZEhKcFluVjBaU0lzSW1Oc1lYTnpUR2x6ZENJc0ltRmtaQ0lzSW1SbFppSXNJbTlzWkVsa0lpd2libVYzU1dRaUxDSnpaWFJCZEhSeWFXSjFkR1VpTENKeVpXWWlMQ0p6Wld4bFkzUmxaRU5oY21RaUxDSkJjbkpoZVNJc0ltWnliMjBpTENKMGIyZG5iR1VpTENKMWJtUmxabWx1WldRaUxDSmtaV0oxWnlJc0ltOXVVMlZzWldOMElpd2laWGh3YjNKMGN5SmRMQ0p6YjNWeVkyVnpJanBiSWk0dUx5NHVMeTR1TDNOeVl5OW9iMjFsWW5KcFpHZGxMWFZwTDNCMVlteHBZeTlqWVhKa2N5NTBjeUpkTENKemIzVnlZMlZ6UTI5dWRHVnVkQ0k2VzI1MWJHeGRMQ0p0WVhCd2FXNW5jeUk2SWpzN096czdPMEZCVFVFc1NVRkJRVUVzVFVGQlFTeEhRVUZCUXl4UFFVRkJPMEZCUTBFc1NVRkJRVU1zVTBGQlFTeEhRVUZCUkN4UFFVRkJPMEZCUTBFc1NVRkJRVVVzVTBGQlFTeEhRVUZCUml4UFFVRkJPMEZCVWtFN1FVRkRRVHM3UVVGclFrRTdRVUZEVFN4TlFVRlBSeXhMUVVGTE8wVkJZV1E3UlVGRFFVTXNXVUZCY1VKRExFZEJRVmM3U1VGQldDeExRVUZCUVN4SFFVRkhMRWRCUVVoQkxFZEJRVWM3U1VGVWVFSTdTVUZEUVN4TFFVRkJReXhwUWtGQmFVSXNSMEZCZFVJc1JVRkJSVHRKUVVNeFF5eExRVUZCUXl4alFVRmpMRWRCUVRCQ0xFVkJRVVU3U1VGUmRFTXNTVUZCU1N4RFFVRkRReXhoUVVGaExFZEJRVWNzU1VGQlFVTXNkMEpCUVdNc1JVRkJReXh2UWtGQmIwSXNRMEZCUXp0RlFVTTNSRHRGUVVWQk8wVkJRMEZETEdkQ1FVRm5Ra0VzUTBGQlEwTXNTMEZCZDBJN1NVRkRja01zU1VGQlNTeERRVUZEVEN4cFFrRkJhVUlzUjBGQlIwc3NTMEZCU3p0SlFVTTVRaXhKUVVGSkxFTkJRVU5ETEZkQlFWY3NSVUZCUlR0RlFVTjBRanRGUVVWQk8wVkJRMEZETEdGQlFXRkJMRU5CUVVORExGVkJRVEpDTzBsQlEzSkRPMGxCUTBFc1RVRkJUVkFzWTBGQll5eEhRVUZIVHl4VlFVRlZMRU5CUVVORExFZEJRVWNzUTBGQlEwTXNVMEZCVXl4TFFVRkxPMDFCUTJoRVF5eEZRVUZGTEVWQlFVMUVMRk5CUVZNc1EwRkJRMFVzU1VGQlNUdE5RVU4wUWtNc1NVRkJTU3hGUVVGSlNDeFRRVUZUTEVOQlFVTkpMRWxCUVVrc1EwRkJRME1zYVVKQlFXbENMRVZCUVVVN1RVRkRNVU5ETEVsQlFVa3NSVUZCU1U0c1UwRkJVeXhEUVVGRFRTeEpRVUZKTzAxQlEzUkNReXhOUVVGTkxFVkJRVVVzUjBGQlIxQXNVMEZCVXl4RFFVRkRVU3hMUVVGTExFbEJRVWxTTEZOQlFWTXNRMEZCUTFNc1QwRkJUenRMUVVOc1JDeERRVUZETEVOQlFVTTdTVUZEU0d4Q0xHTkJRV01zUTBGQlEyMUNMRWxCUVVrc1EwRkJReXhEUVVGRFF5eERRVUZETEVWQlFVVkRMRU5CUVVNc1MwRkJTMFFzUTBGQlF5eERRVUZEVEN4SlFVRkpMRU5CUVVOUExHRkJRV0VzUTBGQlEwUXNRMEZCUXl4RFFVRkRUaXhKUVVGSkxFTkJRVU1zUTBGQlF6dEpRVVV6UkR0SlFVTkJMRWxCUVVsUkxFbEJRVWtzUTBGQlEwTXNVMEZCVXl4RFFVRkRlRUlzWTBGQll5eERRVUZETEV0QlFVdDFRaXhKUVVGSkxFTkJRVU5ETEZOQlFWTXNRMEZCUXl4SlFVRkpMRU5CUVVONFFpeGpRVUZqTEVOQlFVTXNSVUZCUlR0TlFVTjRSU3hKUVVGSkxFTkJRVU5CTEdOQlFXTXNSMEZCUjBFc1kwRkJZenROUVVOd1F5eEpRVUZKTEVOQlFVTkxMRmRCUVZjc1JVRkJSVHRKUVVOMFFqdEZRVU5LTzBWQlJVRTdSVUZEUVVFc1YwRkJWMEVzUTBGQlFUdEpRVU5RTzBsQlEwRXNUVUZCVFc5Q0xGRkJRVkVzUjBGQlJ5eERRVUZETEVkQlFVY3NTVUZCU1N4RFFVRkRNVUlzYVVKQlFXbENMRVZCUVVVc1IwRkJSeXhKUVVGSkxFTkJRVU5ETEdOQlFXTXNRMEZCUXp0SlFVTndSU3hKUVVGSkxFTkJRVU5ETEdGQlFXRXNRMEZCUTNsQ0xHVkJRV1VzUTBGQlF5eEhRVUZIUkN4UlFVRlJMRU5CUVVOcVFpeEhRVUZITEVOQlFVTnRRaXhKUVVGSkxFbEJRVWtzU1VGQlNTeERRVUZEUXl4UlFVRlJMRU5CUVVORUxFbEJRVWtzUTBGQlF5eERRVUZETEVOQlFVTTdTVUZEYUVZc1NVRkJTU3hEUVVGRE1VSXNZVUZCWVN4RFFVRkRORUlzVFVGQlRTeEhRVUZITEVOQlFVTktMRkZCUVZFc1EwRkJRMHNzVFVGQlRUdEpRVVUxUXp0SlFVTkJMRWxCUVVrc1EwRkJRME1zVlVGQlZTeERRVUZETEVsQlFVa3NRMEZCUTBNc1kwRkJZeXhEUVVGRE8wVkJRM2hETzBWQlIwRTdSVUZEUVVvc1VVRkJVVUVzUTBGQlF6dEpRVUZGYkVJc1JVRkJSVHRKUVVGRlJTeEpRVUZKTzBsQlFVVkhMRWxCUVVrN1NVRkJSVU03UlVGQlRTeERRVUZ0UWp0SlFVTm9SRHRKUVVOQlFTeE5RVUZOTEV0QlFVNUJMRTFCUVUwc1IwRkJTeXhIUVVGSExFVkJRVU1zUTBGQlF6dEpRVU5vUWl4TlFVRk5WeXhKUVVGSkxFZEJRVWNzU1VGQlFVMHNkVUpCUVdFc1JVRkJReXh0UWtGQmJVSXNSVUZCUlR0TlFVRkZiRUlzU1VGQlNUdE5RVUZGUXp0SlFVRk5MRU5CUVVVc1EwRkJRenRKUVVOcVJTeEpRVUZCYTBJc2EwSkJRVkVzUlVGQlF5eEpRVUZKTEVOQlFVTndReXhIUVVGSExFVkJRVVVzWjBKQlFXZENMRVZCUXpGQ0xFMUJRVTBzU1VGQlNTeERRVUZEY1VNc1dVRkJXU3hEUVVGRExFbEJRVUZETEdsQ1FVRlBMRVZCUVVOVUxFbEJRVWtzUlVGQlJTeE5RVUZOTEVOQlFVTXNSVUZCUlN4cFFrRkJhVUptTEVsQlFVa3NUVUZCVFN4RlFVRkZSaXhGUVVGRkxFTkJRVU1zUTBGQlF5eEZRVUZGTzBsQlJUTkdPMGxCUTBFc1RVRkJUVEpDTEU5QlFVOHNSMEZCUjFZc1NVRkJTU3hEUVVGRFZ5eFJRVUZSTEVOQlFVTXNRMEZCUXl4RFFVRkRPMGxCUTJoRExFbEJRVUZETEhsQ1FVRnJRaXhGUVVGRFJpeFBRVUZQTEVWQlFVVkhMRmRCUVZjc1EwRkJRenRKUVVONFEwZ3NUMEZCVHl4RFFVRkRTU3hQUVVGUExFTkJRVU12UWl4RlFVRkZMRWRCUVVkQkxFVkJRVVU3U1VGRGRrSXlRaXhQUVVGUExFTkJRVU5MTEU5QlFVOHNSMEZCUnl4TlFVRlhPMDFCUVVjc1NVRkJTU3hEUVVGRFdDeFZRVUZWTEVOQlFVTnlRaXhGUVVGRkxFTkJRVU03U1VGQlJTeERRVUZETzBsQlEzUkVMRTlCUVU5cFFpeEpRVUZKTzBWQlEyWTdSVUZGUVR0RlFVTkJMRTFCUVUxUkxGbEJRVmxCTEVOQlFVTkZMRTlCUVc5Q0xFVkJRVVZOTEVkQlFWY3NSVUZCUldwRExFVkJRVlU3U1VGRE5VUTdTVUZEUVN4TlFVRk5hME1zVVVGQlVTeEhRVUZITEUxQlFVMURMRXRCUVVzc1EwRkJRMFlzUjBGQlJ5eERRVUZETzBsQlEycERMRWxCUVVrc1EwRkJRME1zVVVGQlVTeERRVUZEUlN4RlFVRkZMRVZCUVVVc1RVRkJUU3hKUVVGSlF5eExRVUZMTEVOQlFVTXNkMEpCUVhkQ1NDeFJRVUZSTEVOQlFVTkVMRWRCUVVjc1MwRkJTME1zVVVGQlVTeERRVUZEU1N4VlFVRlZMRVZCUVVVc1EwRkJRenRKUVVOcVIxZ3NUMEZCVHl4RFFVRkRXU3hUUVVGVExFZEJRVWNzVFVGQlRVd3NVVUZCVVN4RFFVRkRUU3hKUVVGSkxFVkJRVVU3U1VGRmVrTTdTVUZEUVdJc1QwRkJUeXhEUVVGRFl5eG5Ra0ZCWjBJc1EwRkJReXhQUVVGUExFTkJRVU1zUTBGQlEwTXNUMEZCVHl4RFFVRkRReXhMUVVGTExFbEJRVWM3VFVGRE9VTXNUVUZCVFRORExFVkJRVVVzUjBGQlJ6SkRMRXRCUVVzc1EwRkJRME1zV1VGQldTeERRVUZETEVsQlFVa3NRMEZCUXp0TlFVTnVReXhKUVVGQlF5eHpRa0ZCWlN4RlFVRkROME1zUlVGQlJTeERRVUZETzAxQlEyNUNNa01zUzBGQlN5eERRVUZEUnl4bFFVRmxMRU5CUVVNc1NVRkJTU3hEUVVGRE8wMUJRek5DU0N4TFFVRkxMRU5CUVVOSkxGTkJRVk1zUTBGQlEwTXNSMEZCUnl4RFFVRkRhRVFzUlVGQlJTeERRVUZETzBsQlF6TkNMRU5CUVVNc1EwRkJRenRKUVVWR08wbEJRMEV5UWl4UFFVRlBMRU5CUVVOakxHZENRVUZuUWl4RFFVRkRMRmRCUVZjc1EwRkJReXhEUVVGRFF5eFBRVUZQTEVOQlFVTlBMRWRCUVVjc1NVRkJSenROUVVOb1JDeE5RVUZOUXl4TFFVRkxMRWRCUVVkRUxFZEJRVWNzUTBGQlEwd3NXVUZCV1N4RFFVRkRMRWxCUVVrc1EwRkJRenROUVVOd1F5eE5RVUZOVHl4TFFVRkxMRWRCUVVjc1IwRkJSMjVFTEVWQlFVVXNTVUZCU1d0RUxFdEJRVXNzUlVGQlJUdE5RVU01UWtRc1IwRkJSeXhEUVVGRFJ5eFpRVUZaTEVOQlFVTXNTVUZCU1N4RlFVRkZSQ3hMUVVGTExFTkJRVU03VFVGRE4wSjRRaXhQUVVGUExFTkJRVU5qTEdkQ1FVRm5RaXhEUVVGRExHVkJRV1ZUTEV0QlFVc3NTMEZCU3l4RFFVRkRMRU5CUVVOU0xFOUJRVThzUTBGQlExY3NSMEZCUnl4SlFVRkhPMUZCUVVkQkxFZEJRVWNzUTBGQlEwUXNXVUZCV1N4RFFVRkRMRTFCUVUwc1JVRkJSU3hSUVVGUlJDeExRVUZMTEVkQlFVY3NRMEZCUXp0TlFVRkZMRU5CUVVNc1EwRkJRenRKUVVOMlNDeERRVUZETEVOQlFVTTdSVUZEVGp0RlFVVkJPMFZCUTBFNVFpeFZRVUZWUVN4RFFVRkRja0lzUlVGQlZ6dEpRVU5zUWp0SlFVTkJMRWxCUVVselJDeFpRVUZ4UXp0SlFVTjZReXhMUVVGTExFMUJRVTF5UXl4SlFVRkpMRWxCUVVselF5eExRVUZMTEVOQlFVTkRMRWxCUVVrc1EwRkJReXhKUVVGSkxFTkJRVU5xUlN4aFFVRmhMRU5CUVVOeFF5eFJRVUZSTEVOQlFVTXNSVUZCUlR0TlFVTjRSQ3hKUVVGQlF5eDVRa0ZCYTBJc1JVRkJRMW9zU1VGQlNTeEZRVUZGWVN4WFFVRlhMRU5CUVVNN1RVRkRja01zU1VGQlNXSXNTVUZCU1N4RFFVRkRZeXhQUVVGUExFTkJRVU12UWl4RlFVRkZMRXRCUVV0QkxFVkJRVVVzUlVGQlJYTkVMRmxCUVZrc1IwRkJSM0pETEVsQlFVazdUVUZETDBOQkxFbEJRVWtzUTBGQlF6aENMRk5CUVZNc1EwRkJRMVVzVFVGQlRTeERRVUZETEdGQlFXRXNSVUZCUlhoRExFbEJRVWtzUTBGQlEyTXNUMEZCVHl4RFFVRkRMMElzUlVGQlJTeExRVUZMUVN4RlFVRkZMRU5CUVVNN1NVRkRhRVU3U1VGRFFTeEpRVUZKTEVOQlFVTnpSQ3haUVVGWkxFVkJRVVYwUkN4RlFVRkZMRWRCUVVjd1JDeFRRVUZUTzBsQlJXcERPMGxCUTBFc1NVRkJTU3hKUVVGSkxFTkJRVU53UXl4alFVRmpMRXRCUVV0MFFpeEZRVUZGTEVWQlFVVTdUVUZETlVJc1NVRkJTU3hEUVVGRFdpeEhRVUZITEVOQlFVTjFSU3hMUVVGTExFTkJRVU1zV1VGQldUTkVMRVZCUVVVc1ZVRkJWU3hKUVVGSkxFTkJRVU56UWl4alFVRmpMRWRCUVVjc1EwRkJRenROUVVNNVJDeEpRVUZKTEVOQlFVTkJMR05CUVdNc1IwRkJSM1JDTEVWQlFVVTdUVUZEZUVJc1NVRkJTU3hEUVVGRE5FUXNVVUZCVVN4SFFVRkhOVVFzUlVGQlJTeERRVUZETzBsQlEzWkNPMFZCUTBvN08wRkJRMGcyUkN4UFFVRkJMRU5CUVVFelJTeExRVUZCTEVkQlFVRkJMRXRCUVVFaUxDSnBaMjV2Y21WTWFYTjBJanBiWFgwPSIsIlwidXNlIHN0cmljdFwiO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5DbGllbnRDbGllbnRJRCA9IHZvaWQgMDtcbnZhciBfdXRpbHMgPSByZXF1aXJlKFwiLi4vLi4vdXRpbHMuanNcIik7XG52YXIgX3V0aWxzRG9tID0gcmVxdWlyZShcIi4vdXRpbHMtZG9tLmpzXCIpO1xudmFyIF9sb2dFcnJvciA9IHJlcXVpcmUoXCIuLi8uLi9sb2ctZXJyb3IuanNcIik7XG4vLyBIb21lYnJpZGdlIHBsdWdpbiBmb3IgSG9tZSBDb25uZWN0IGhvbWUgYXBwbGlhbmNlc1xuLy8gQ29weXJpZ2h0IMKpIDIwMjMtMjAyNiBBbGV4YW5kZXIgVGhvdWt5ZGlkZXNcblxuLy8gTWluaW11bSB0aW1lIGJldHdlZW4gZHVwbGljYXRlIHRvYXN0IG5vdGlmaWNhdGlvbnNcbmNvbnN0IFRPQVNUX0RFRFVQX1RJTUUgPSA1ICogX3V0aWxzLk1TO1xuLy8gVGhlIGN1cnJlbnQgSG9tZSBDb25uZWN0IGNsaWVudFxuY2xhc3MgQ2xpZW50Q2xpZW50SUQge1xuICAvLyBDcmVhdGUgYSBuZXcgSG9tZSBDb25uZWN0IGNsaWVudFxuICBjb25zdHJ1Y3Rvcihsb2csIGlwYykge1xuICAgIHRoaXMubG9nID0gbG9nO1xuICAgIHRoaXMuaXBjID0gaXBjO1xuICAgIHRoaXMuaXBjLm9uRXZlbnQoJ3N0YXR1cycsIHN0YXR1cyA9PiB7XG4gICAgICB0aGlzLm9uQ2xpZW50U3RhdHVzKHN0YXR1cyk7XG4gICAgfSk7XG4gIH1cbiAgLy8gVGhlIEhvbWUgQ29ubmVjdCBjbGllbnQgY29uZmlndXJhdGlvbiBoYXMgY2hhbmdlZFxuICBhc3luYyBzZXRDbGllbnQoY29uZmlnKSB7XG4gICAgY29uc3QgY2xpZW50Q29uZmlnID0gdGhpcy5wcmVwYXJlQ2xpZW50Q29uZmlnKGNvbmZpZyk7XG4gICAgaWYgKGNsaWVudENvbmZpZykge1xuICAgICAgLy8gVGVzdCB0aGUgY2xpZW50IGNvbmZpZ3VyYXRpb25cbiAgICAgIHRoaXMuY2xpZW50Q29uZmlnID0gY2xpZW50Q29uZmlnO1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3Qgc3RhdHVzID0gYXdhaXQgdGhpcy5pcGMucmVxdWVzdCgnL2NsaWVudGlkJywgY2xpZW50Q29uZmlnKTtcbiAgICAgICAgdGhpcy5vbkNsaWVudFN0YXR1cyhzdGF0dXMpO1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGNvbnN0IG1lc3NhZ2UgPSBlcnIgaW5zdGFuY2VvZiBFcnJvciA/IGVyci5tZXNzYWdlIDogU3RyaW5nKGVycik7XG4gICAgICAgIHRoaXMuc2hvd1RvYXN0KCdlcnJvcicsIGBVbmFibGUgdG8gYXR0ZW1wdCBhdXRob3Jpc2F0aW9uICR7bWVzc2FnZX1gKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gSWdub3JlIHRoZSBjbGllbnQgY29uZmlndXJhdGlvbiB1bnRpbCBpdCBpcyB2YWxpZFxuICAgICAgdGhpcy5jbGllbnRDb25maWcgPSB1bmRlZmluZWQ7XG4gICAgICB0aGlzLnNob3dQYW5lbCgpO1xuICAgICAgdGhpcy5vbkFwcGxpYW5jZXM/LigpO1xuICAgIH1cbiAgfVxuICAvLyBUZXN0IHdoZXRoZXIgdGhlIGNsaWVudCBjb25maWd1cmF0aW9uIGlzIGxpa2VseSB0byBiZSB2YWxpZFxuICBwcmVwYXJlQ2xpZW50Q29uZmlnKGNvbmZpZykge1xuICAgIGlmIChjb25maWcuZGVidWc/LmluY2x1ZGVzKCdNb2NrIEFwcGxpYW5jZXMnKSkge1xuICAgICAgLy8gTW9jayBhcHBsaWFuY2VzOyB1c2UgYW4gZW1wdHkgY2xpZW50aWQgdG8gbWF0Y2ggdGhlIHN0YXR1c1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4uY29uZmlnLFxuICAgICAgICBjbGllbnRpZDogJydcbiAgICAgIH07XG4gICAgfSBlbHNlIGlmIChjb25maWcuY2xpZW50aWQgIT09IHVuZGVmaW5lZCAmJiAvXlswLTlBLUZdezY0fSQvaS50ZXN0KGNvbmZpZy5jbGllbnRpZCkpIHtcbiAgICAgIC8vIFZpYWJsZSBjbGllbnRpZFxuICAgICAgcmV0dXJuIGNvbmZpZztcbiAgICB9XG4gIH1cbiAgLy8gSGFuZGxlIGV2ZW50cyBmcm9tIHRoZSBIb21lIENvbm5lY3QgY2xpZW50XG4gIG9uQ2xpZW50U3RhdHVzKHN0YXR1cykge1xuICAgIC8vIElnbm9yZSB0aGUgc3RhdHVzIGlmIG5vIGxvbmdlciBtb25pdG9yaW5nIHRoZSBjbGllbnRcbiAgICBpZiAodGhpcy5jbGllbnRDb25maWc/LmNsaWVudGlkICE9PSBzdGF0dXMuY2xpZW50aWQpIHJldHVybjtcbiAgICAvLyBVcGRhdGUgdGhlIGxpc3Qgb2YgYXBwbGlhbmNlc1xuICAgIHRoaXMub25BcHBsaWFuY2VzPy4oc3RhdHVzLmFwcGxpYW5jZXMpO1xuICAgIC8vIERpc3BsYXkgYW4gYXBwcm9wcmlhdGUgdG9hc3Qgbm90aWZpY2F0aW9uXG4gICAgc3dpdGNoIChzdGF0dXMuYXV0aG9yaXNhdGlvbj8uc3RhdGUpIHtcbiAgICAgIGNhc2UgJ3N1Y2Nlc3MnOlxuICAgICAgICB0aGlzLnNob3dUb2FzdCgnc3VjY2VzcycsICdTdWNjZXNzZnVsbHkgYXV0aG9yaXNlZCcpO1xuICAgICAgICB0aGlzLnNob3dQYW5lbCgpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3VzZXInOlxuICAgICAgICB0aGlzLnNob3dUb2FzdCgnaW5mbycsICdVc2VyIGF1dGhvcmlzYXRpb24gcmVxdWlyZWQnKTtcbiAgICAgICAgdGhpcy5zaG93VXNlckF1dGhvcmlzYXRpb24oc3RhdHVzLmF1dGhvcmlzYXRpb24pO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2ZhaWwnOlxuICAgICAgICB0aGlzLnNob3dUb2FzdCgnZXJyb3InLCAnQXV0aG9yaXNhdGlvbiBmYWlsZWQnKTtcbiAgICAgICAgdGhpcy5zaG93RmFpbChzdGF0dXMuYXV0aG9yaXNhdGlvbik7XG4gICAgICAgIHRoaXMub25GYWlsPy4oKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdidXN5JzpcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRoaXMuc2hvd1BhbmVsKCk7XG4gICAgfVxuICB9XG4gIC8vIFByb21wdCB0aGUgdXNlciB0byBhdXRob3Jpc2UgdGhlIGNsaWVudFxuICBzaG93VXNlckF1dGhvcmlzYXRpb24oYXV0aG9yaXNhdGlvbikge1xuICAgIC8vIFNldCB0aGUgbGluay9jb2RlXG4gICAgY29uc3QgbGluayA9ICgwLCBfdXRpbHNEb20uZ2V0RWxlbWVudEJ5SWQpKCdoYy1jbGllbnQtdXNlci1saW5rJyk7XG4gICAgbGluay5zZXRBdHRyaWJ1dGUoJ2hyZWYnLCBhdXRob3Jpc2F0aW9uLnVyaSk7XG4gICAgKDAsIF91dGlsc0RvbS5zZXRTbG90VGV4dCkoZG9jdW1lbnQsIHtcbiAgICAgICdoYy1jbGllbnQtdXNlci1jb2RlJzogYXV0aG9yaXNhdGlvbi5jb2RlXG4gICAgfSk7XG4gICAgLy8gRW5hYmxlIGdlbmVyYXRpb24gb2YgYSBuZXcgYXV0aG9yaXNhdGlvbiBjb2RlXG4gICAgKDAsIF91dGlsc0RvbS5nZXRFbGVtZW50QnlJZCkoJ2hjLWNsaWVudC11c2VyLXJldHJ5Jykub25jbGljayA9ICgpID0+IHtcbiAgICAgIHRoaXMucmV0cnlBdXRob3Jpc2F0aW9uKCk7XG4gICAgfTtcbiAgICAvLyBNYWtlIHRoZSBhdXRob3Jpc2F0aW9uIGxpbmsgdmlzaWJsZSAoYmVmb3JlIHRyaWdnZXJpbmcgdHJhbnNpdGlvbilcbiAgICB0aGlzLnNob3dQYW5lbCgnaGMtY2xpZW50LXVzZXInKTtcbiAgICAvLyBTdGFydCBhbmltYXRpbmcgdGhlIHByb2dyZXNzIGJhciBmb3IgdGhlIHRpbWUgdW50aWwgdGhlIGxpbmsgZXhwaXJlc1xuICAgIGNvbnN0IHByb2dyZXNzID0gKDAsIF91dGlsc0RvbS5nZXRFbGVtZW50QnlJZCkoJ2hjLWNsaWVudC11c2VyLXByb2dyZXNzJyk7XG4gICAgcHJvZ3Jlc3MuY2xhc3NMaXN0LnJlbW92ZSgnaGMtcHJvZ3Jlc3MtemVybycpO1xuICAgIGlmIChhdXRob3Jpc2F0aW9uLmV4cGlyZXMgIT09IG51bGwpIHtcbiAgICAgIHByb2dyZXNzLnN0eWxlLnRyYW5zaXRpb25EdXJhdGlvbiA9IGAke2F1dGhvcmlzYXRpb24uZXhwaXJlcyAtIERhdGUubm93KCl9bXNgO1xuICAgICAgdm9pZCBwcm9ncmVzcy5vZmZzZXRIZWlnaHQ7IC8vIChmb3JjZSBhIHJlZmxvdylcbiAgICAgIHByb2dyZXNzLmNsYXNzTGlzdC5hZGQoJ2hjLXByb2dyZXNzLXplcm8nKTtcbiAgICB9XG4gIH1cbiAgLy8gRGlzcGxheSB0aGUgcmVzdWx0IG9mIGEgZmFpbGVkIGF1dGhvcmlzYXRpb25cbiAgc2hvd0ZhaWwoYXV0aG9yaXNhdGlvbikge1xuICAgIC8vIERpc3BsYXkgdGhlIGVycm9yIG1lc3NhZ2VcbiAgICAoMCwgX3V0aWxzRG9tLmdldEVsZW1lbnRCeUlkKSgnaGMtY2xpZW50LWZhaWwtbWVzc2FnZScpLnRleHRDb250ZW50ID0gYXV0aG9yaXNhdGlvbi5tZXNzYWdlO1xuICAgIC8vIEluZGljYXRlIHdoZXRoZXIgdGhlIGF1dGhvcmlzYXRpb24gY2FuIGJlIHJldHJpZWRcbiAgICAoMCwgX3V0aWxzRG9tLmdldEVsZW1lbnRCeUlkKSgnaGMtY2xpZW50LWZhaWwtcmV0cnlhYmxlJykuaGlkZGVuID0gIWF1dGhvcmlzYXRpb24ucmV0cnlhYmxlO1xuICAgICgwLCBfdXRpbHNEb20uZ2V0RWxlbWVudEJ5SWQpKCdoYy1jbGllbnQtZmFpbC1yZXRyeScpLmhpZGRlbiA9ICFhdXRob3Jpc2F0aW9uLnJldHJ5YWJsZTtcbiAgICAoMCwgX3V0aWxzRG9tLmdldEVsZW1lbnRCeUlkKSgnaGMtY2xpZW50LWZhaWwtcmV0cnknKS5vbmNsaWNrID0gKCkgPT4ge1xuICAgICAgdGhpcy5yZXRyeUF1dGhvcmlzYXRpb24oKTtcbiAgICB9O1xuICAgIC8vIEFkZCBhbnkgaGVscCB0aGF0IGhhcyBiZWVuIHByb3ZpZGVkXG4gICAgaWYgKGF1dGhvcmlzYXRpb24uaGVscCkge1xuICAgICAgLy8gU2V0IHRleHQgYmxvY2tzXG4gICAgICBjb25zdCBzZXRUZXh0ID0gKGlkLCB0ZXh0KSA9PiB7XG4gICAgICAgICgwLCBfdXRpbHNEb20uZ2V0RWxlbWVudEJ5SWQpKGlkKS5yZXBsYWNlQ2hpbGRyZW4oLi4udGV4dC5tYXAocGFyYWdyYXBoID0+ICgwLCBfdXRpbHNEb20uY2xvbmVUZW1wbGF0ZSkoJ2hjLWNsaWVudC1mYWlsLXBhcmFncmFwaCcsIHtcbiAgICAgICAgICBwYXJhZ3JhcGhcbiAgICAgICAgfSkpKTtcbiAgICAgIH07XG4gICAgICBzZXRUZXh0KCdoYy1jbGllbnQtZmFpbC1wcmVzY3JpcHQnLCBhdXRob3Jpc2F0aW9uLmhlbHAucHJlc2NyaXB0KTtcbiAgICAgIHNldFRleHQoJ2hjLWNsaWVudC1mYWlsLXBvc3RzY3JpcHQnLCBhdXRob3Jpc2F0aW9uLmhlbHAucG9zdHNjcmlwdCk7XG4gICAgICAvLyBQcm92aWRlIGFkZGl0aW9uYWwgaGVscCBmb3IgY3JlYXRpbmcgb3IgbW9kaWZ5aW5nIHRoZSBhcHBsaWNhdGlvblxuICAgICAgY29uc3Qge1xuICAgICAgICBjbGllbnRcbiAgICAgIH0gPSBhdXRob3Jpc2F0aW9uLmhlbHA7XG4gICAgICBjb25zdCBsaW5rID0gKDAsIF91dGlsc0RvbS5nZXRFbGVtZW50QnlJZCkoJ2hjLWNsaWVudC1mYWlsLXVyaScpO1xuICAgICAgaWYgKGNsaWVudCkge1xuICAgICAgICAoMCwgX3V0aWxzRG9tLmdldEVsZW1lbnRCeUlkKSgnaGMtY2xpZW50LWZhaWwtY2xpZW50LXNldHRpbmdzJykucmVwbGFjZUNoaWxkcmVuKC4uLk9iamVjdC5lbnRyaWVzKGNsaWVudC5zZXR0aW5ncykubWFwKChba2V5LCB2YWx1ZV0pID0+ICgwLCBfdXRpbHNEb20uY2xvbmVUZW1wbGF0ZSkoJ2hjLWNsaWVudC1mYWlsLWNsaWVudC1zZXR0aW5nJywge1xuICAgICAgICAgIGtleSxcbiAgICAgICAgICB2YWx1ZVxuICAgICAgICB9KSkpO1xuICAgICAgICBsaW5rLnNldEF0dHJpYnV0ZSgnaHJlZicsIGNsaWVudC51cmkpO1xuICAgICAgICBsaW5rLnRleHRDb250ZW50ID0gY2xpZW50LmFjdGlvbiA9PT0gJ2NyZWF0ZScgPyAnQ3JlYXRlIGFwcGxpY2F0aW9uJyA6ICdNb2RpZnkgYXBwbGljYXRpb24nO1xuICAgICAgICBsaW5rLmhpZGRlbiA9IGZhbHNlO1xuICAgICAgICAoMCwgX3V0aWxzRG9tLmdldEVsZW1lbnRCeUlkKSgnaGMtY2xpZW50LWZhaWwtY2xpZW50JykuaGlkZGVuID0gZmFsc2U7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsaW5rLmhpZGRlbiA9IHRydWU7XG4gICAgICAgICgwLCBfdXRpbHNEb20uZ2V0RWxlbWVudEJ5SWQpKCdoYy1jbGllbnQtZmFpbC1jbGllbnQnKS5oaWRkZW4gPSB0cnVlO1xuICAgICAgfVxuICAgICAgLy8gTWFrZSB0aGUgZGV0YWlscyB2aXNpYmxlXG4gICAgICAoMCwgX3V0aWxzRG9tLmdldEVsZW1lbnRCeUlkKSgnaGMtY2xpZW50LWZhaWwtZGV0YWlsJykuaGlkZGVuID0gZmFsc2U7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIE90aGVyd2lzZSBoaWRlIHRoZSBkZXRhaWxzXG4gICAgICAoMCwgX3V0aWxzRG9tLmdldEVsZW1lbnRCeUlkKSgnaGMtY2xpZW50LWZhaWwtdXJpJykuaGlkZGVuID0gdHJ1ZTtcbiAgICAgICgwLCBfdXRpbHNEb20uZ2V0RWxlbWVudEJ5SWQpKCdoYy1jbGllbnQtZmFpbC1kZXRhaWwnKS5oaWRkZW4gPSB0cnVlO1xuICAgIH1cbiAgICAvLyBNYWtlIHRoZSBmYWlsdXJlIG1lc3NhZ2UgdmlzaWJsZVxuICAgIHRoaXMuc2hvd1BhbmVsKCdoYy1jbGllbnQtZmFpbCcpO1xuICB9XG4gIC8vIFRyaWdnZXIgYXV0aG9yaXNhdGlvbiByZXRyeVxuICByZXRyeUF1dGhvcmlzYXRpb24oKSB7XG4gICAgKDAsIF9sb2dFcnJvci5kZXRhY2hlZCkodGhpcy5sb2csICdSZXRyeSBhdXRob3Jpc2F0aW9uJywgYXN5bmMgKCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdGhpcy5pcGMucmVxdWVzdCgnL2NsaWVudGlkL3JldHJ5JywgbnVsbCk7XG4gICAgICAgIHRoaXMuc2hvd1RvYXN0KCdpbmZvJywgJ1JlcXVlc3RpbmcgbmV3IGF1dGhvcmlzYXRpb24gY29kZScpO1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGNvbnN0IG1lc3NhZ2UgPSBlcnIgaW5zdGFuY2VvZiBFcnJvciA/IGVyci5tZXNzYWdlIDogU3RyaW5nKGVycik7XG4gICAgICAgIHRoaXMuc2hvd1RvYXN0KCdlcnJvcicsIGBVbmFibGUgdG8gcmV0cnkgYXV0aG9yaXNhdGlvbjogJHttZXNzYWdlfWApO1xuICAgICAgfVxuICAgIH0pKCk7XG4gIH1cbiAgLy8gU2hvdyB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgYW5kIGhpZGUgYWxsIG90aGVyc1xuICBzaG93UGFuZWwoaWRTaG93KSB7XG4gICAgZm9yIChjb25zdCBpZCBvZiBbJ2hjLWNsaWVudC1mYWlsJywgJ2hjLWNsaWVudC11c2VyJ10pIHtcbiAgICAgICgwLCBfdXRpbHNEb20uZ2V0RWxlbWVudEJ5SWQpKGlkKS5oaWRkZW4gPSBpZCAhPT0gaWRTaG93O1xuICAgIH1cbiAgfVxuICAvLyBEaXNwbGF5IGEgdG9hc3Qgbm90aWZpY2F0aW9uXG4gIHNob3dUb2FzdChsZXZlbCwgbWVzc2FnZSkge1xuICAgIC8vIEF2b2lkIGR1cGxpY2F0ZSB0b2FzdCBub3RpZmljYXRpb25zXG4gICAgY29uc3Qga2V5ID0gYCR7bGV2ZWx9IC0gJHttZXNzYWdlfWA7XG4gICAgaWYgKHRoaXMubGFzdFRvYXN0ID09PSBrZXkpIHJldHVybjtcbiAgICB0aGlzLmxhc3RUb2FzdCA9IGtleTtcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGlmICh0aGlzLmxhc3RUb2FzdCA9PT0ga2V5KSB0aGlzLmxhc3RUb2FzdCA9IHVuZGVmaW5lZDtcbiAgICB9LCBUT0FTVF9ERURVUF9USU1FKTtcbiAgICAvLyBEaXNwbGF5IHRoZSB0b2FzdCBub3RpZmljYXRpb25cbiAgICB3aW5kb3cuaG9tZWJyaWRnZS50b2FzdFtsZXZlbF0obWVzc2FnZSwgJ0hvbWUgQ29ubmVjdCBDbGllbnQnKTtcbiAgfVxufVxuZXhwb3J0cy5DbGllbnRDbGllbnRJRCA9IENsaWVudENsaWVudElEO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ9dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p1WVcxbGN5STZXeUpmZFhScGJITWlMQ0p5WlhGMWFYSmxJaXdpWDNWMGFXeHpSRzl0SWl3aVgyeHZaMFZ5Y205eUlpd2lWRTlCVTFSZlJFVkVWVkJmVkVsTlJTSXNJazFUSWl3aVEyeHBaVzUwUTJ4cFpXNTBTVVFpTENKamIyNXpkSEoxWTNSdmNpSXNJbXh2WnlJc0ltbHdZeUlzSW05dVJYWmxiblFpTENKemRHRjBkWE1pTENKdmJrTnNhV1Z1ZEZOMFlYUjFjeUlzSW5ObGRFTnNhV1Z1ZENJc0ltTnZibVpwWnlJc0ltTnNhV1Z1ZEVOdmJtWnBaeUlzSW5CeVpYQmhjbVZEYkdsbGJuUkRiMjVtYVdjaUxDSnlaWEYxWlhOMElpd2laWEp5SWl3aWJXVnpjMkZuWlNJc0lrVnljbTl5SWl3aVUzUnlhVzVuSWl3aWMyaHZkMVJ2WVhOMElpd2lkVzVrWldacGJtVmtJaXdpYzJodmQxQmhibVZzSWl3aWIyNUJjSEJzYVdGdVkyVnpJaXdpWkdWaWRXY2lMQ0pwYm1Oc2RXUmxjeUlzSW1Oc2FXVnVkR2xrSWl3aWRHVnpkQ0lzSW1Gd2NHeHBZVzVqWlhNaUxDSmhkWFJvYjNKcGMyRjBhVzl1SWl3aWMzUmhkR1VpTENKemFHOTNWWE5sY2tGMWRHaHZjbWx6WVhScGIyNGlMQ0p6YUc5M1JtRnBiQ0lzSW05dVJtRnBiQ0lzSW14cGJtc2lMQ0puWlhSRmJHVnRaVzUwUW5sSlpDSXNJbk5sZEVGMGRISnBZblYwWlNJc0luVnlhU0lzSW5ObGRGTnNiM1JVWlhoMElpd2laRzlqZFcxbGJuUWlMQ0pqYjJSbElpd2liMjVqYkdsamF5SXNJbkpsZEhKNVFYVjBhRzl5YVhOaGRHbHZiaUlzSW5CeWIyZHlaWE56SWl3aVkyeGhjM05NYVhOMElpd2ljbVZ0YjNabElpd2laWGh3YVhKbGN5SXNJbk4wZVd4bElpd2lkSEpoYm5OcGRHbHZia1IxY21GMGFXOXVJaXdpUkdGMFpTSXNJbTV2ZHlJc0ltOW1abk5sZEVobGFXZG9kQ0lzSW1Ga1pDSXNJblJsZUhSRGIyNTBaVzUwSWl3aWFHbGtaR1Z1SWl3aWNtVjBjbmxoWW14bElpd2lhR1ZzY0NJc0luTmxkRlJsZUhRaUxDSnBaQ0lzSW5SbGVIUWlMQ0p5WlhCc1lXTmxRMmhwYkdSeVpXNGlMQ0p0WVhBaUxDSndZWEpoWjNKaGNHZ2lMQ0pqYkc5dVpWUmxiWEJzWVhSbElpd2ljSEpsYzJOeWFYQjBJaXdpY0c5emRITmpjbWx3ZENJc0ltTnNhV1Z1ZENJc0lrOWlhbVZqZENJc0ltVnVkSEpwWlhNaUxDSnpaWFIwYVc1bmN5SXNJbXRsZVNJc0luWmhiSFZsSWl3aVlXTjBhVzl1SWl3aVpHVjBZV05vWldRaUxDSnBaRk5vYjNjaUxDSnNaWFpsYkNJc0lteGhjM1JVYjJGemRDSXNJbk5sZEZScGJXVnZkWFFpTENKM2FXNWtiM2NpTENKb2IyMWxZbkpwWkdkbElpd2lkRzloYzNRaUxDSmxlSEJ2Y25SeklsMHNJbk52ZFhKalpYTWlPbHNpTGk0dkxpNHZMaTR2YzNKakwyaHZiV1ZpY21sa1oyVXRkV2t2Y0hWaWJHbGpMMk5zYVdWdWRDMWpiR2xsYm5ScFpDNTBjeUpkTENKemIzVnlZMlZ6UTI5dWRHVnVkQ0k2VzI1MWJHeGRMQ0p0WVhCd2FXNW5jeUk2SWpzN096czdPMEZCVTBFc1NVRkJRVUVzVFVGQlFTeEhRVUZCUXl4UFFVRkJPMEZCUlVFc1NVRkJRVU1zVTBGQlFTeEhRVUZCUkN4UFFVRkJPMEZCUlVFc1NVRkJRVVVzVTBGQlFTeEhRVUZCUml4UFFVRkJPMEZCWWtFN1FVRkRRVHM3UVVGalFUdEJRVU5CTEUxQlFVMUhMR2RDUVVGblFpeEhRVUZITEVOQlFVTXNSMEZCUjBNc1UwRkJSVHRCUVVVdlFqdEJRVU5OTEUxQlFVOURMR05CUVdNN1JVRlpka0k3UlVGRFFVTXNXVUZCY1VKRExFZEJRVmNzUlVGQlYwTXNSMEZCWXp0bFFVRndRMFFzUjBGQlJ6dGxRVUZ0UWtNc1IwRkJSenRKUVVNeFF5eEpRVUZKTEVOQlFVTkJMRWRCUVVjc1EwRkJRME1zVDBGQlR5eERRVUZETEZGQlFWRXNSVUZCUlVNc1RVRkJUU3hKUVVGSE8wMUJRVWNzU1VGQlNTeERRVUZEUXl4alFVRmpMRU5CUVVORUxFMUJRVTBzUTBGQlF6dEpRVUZGTEVOQlFVTXNRMEZCUXp0RlFVTXhSVHRGUVVWQk8wVkJRMEVzVFVGQlRVVXNVMEZCVTBFc1EwRkJRME1zVFVGQk5rSTdTVUZEZWtNc1RVRkJUVU1zV1VGQldTeEhRVUZITEVsQlFVa3NRMEZCUTBNc2JVSkJRVzFDTEVOQlFVTkdMRTFCUVUwc1EwRkJRenRKUVVOeVJDeEpRVUZKUXl4WlFVRlpMRVZCUVVVN1RVRkRaRHROUVVOQkxFbEJRVWtzUTBGQlEwRXNXVUZCV1N4SFFVRkhRU3haUVVGWk8wMUJRMmhETEVsQlFVazdVVUZEUVN4TlFVRk5TaXhOUVVGTkxFZEJRVWNzVFVGQlRTeEpRVUZKTEVOQlFVTkdMRWRCUVVjc1EwRkJRMUVzVDBGQlR5eERRVUZETEZkQlFWY3NSVUZCUlVZc1dVRkJXU3hEUVVGRE8xRkJRMmhGTEVsQlFVa3NRMEZCUTBnc1kwRkJZeXhEUVVGRFJDeE5RVUZOTEVOQlFVTTdUVUZETDBJc1EwRkJReXhEUVVGRExFOUJRVTlQTEVkQlFVY3NSVUZCUlR0UlFVTldMRTFCUVUxRExFOUJRVThzUjBGQlIwUXNSMEZCUnl4WlFVRlpSU3hMUVVGTExFZEJRVWRHTEVkQlFVY3NRMEZCUTBNc1QwRkJUeXhIUVVGSFJTeE5RVUZOTEVOQlFVTklMRWRCUVVjc1EwRkJRenRSUVVOb1JTeEpRVUZKTEVOQlFVTkpMRk5CUVZNc1EwRkJReXhQUVVGUExFVkJRVVVzYlVOQlFXMURTQ3hQUVVGUExFVkJRVVVzUTBGQlF6dE5RVU42UlR0SlFVTktMRU5CUVVNc1RVRkJUVHROUVVOSU8wMUJRMEVzU1VGQlNTeERRVUZEU2l4WlFVRlpMRWRCUVVkUkxGTkJRVk03VFVGRE4wSXNTVUZCU1N4RFFVRkRReXhUUVVGVExFVkJRVVU3VFVGRGFFSXNTVUZCU1N4RFFVRkRReXhaUVVGWkxFZEJRVVVzUTBGQlJUdEpRVU42UWp0RlFVTktPMFZCUlVFN1JVRkRRVlFzYlVKQlFXMUNRU3hEUVVGRFJpeE5RVUUyUWp0SlFVTTNReXhKUVVGSlFTeE5RVUZOTEVOQlFVTlpMRXRCUVVzc1JVRkJSVU1zVVVGQlVTeERRVUZETEdsQ1FVRnBRaXhEUVVGRExFVkJRVVU3VFVGRE0wTTdUVUZEUVN4UFFVRlBPMUZCUVVVc1IwRkJSMklzVFVGQlRUdFJRVUZGWXl4UlFVRlJMRVZCUVVVN1RVRkJSU3hEUVVGclFqdEpRVU4wUkN4RFFVRkRMRTFCUVUwc1NVRkJTV1FzVFVGQlRTeERRVUZEWXl4UlFVRlJMRXRCUVV0TUxGTkJRVk1zU1VGQlNTeHBRa0ZCYVVJc1EwRkJRMDBzU1VGQlNTeERRVUZEWml4TlFVRk5MRU5CUVVOakxGRkJRVkVzUTBGQlF5eEZRVUZGTzAxQlEycEdPMDFCUTBFc1QwRkJUMlFzVFVGQmMwSTdTVUZEYWtNN1JVRkRTanRGUVVWQk8wVkJRMEZHTEdOQlFXTkJMRU5CUVVORUxFMUJRWE5DTzBsQlEycERPMGxCUTBFc1NVRkJTU3hKUVVGSkxFTkJRVU5KTEZsQlFWa3NSVUZCUldFc1VVRkJVU3hMUVVGTGFrSXNUVUZCVFN4RFFVRkRhVUlzVVVGQlVTeEZRVUZGTzBsQlJYSkVPMGxCUTBFc1NVRkJTU3hEUVVGRFNDeFpRVUZaTEVkQlFVZGtMRTFCUVUwc1EwRkJRMjFDTEZWQlFWVXNRMEZCUXp0SlFVVjBRenRKUVVOQkxGRkJRVkZ1UWl4TlFVRk5MRU5CUVVOdlFpeGhRVUZoTEVWQlFVVkRMRXRCUVVzN1RVRkRia01zUzBGQlN5eFRRVUZUTzFGQlExWXNTVUZCU1N4RFFVRkRWaXhUUVVGVExFTkJRVU1zVTBGQlV5eEZRVUZGTEhsQ1FVRjVRaXhEUVVGRE8xRkJRM0JFTEVsQlFVa3NRMEZCUTBVc1UwRkJVeXhGUVVGRk8xRkJRMmhDTzAxQlEwb3NTMEZCU3l4TlFVRk5PMUZCUTFBc1NVRkJTU3hEUVVGRFJpeFRRVUZUTEVOQlFVTXNUVUZCVFN4RlFVRkZMRFpDUVVFMlFpeERRVUZETzFGQlEzSkVMRWxCUVVrc1EwRkJRMWNzY1VKQlFYRkNMRU5CUVVOMFFpeE5RVUZOTEVOQlFVTnZRaXhoUVVGaExFTkJRVU03VVVGRGFFUTdUVUZEU2l4TFFVRkxMRTFCUVUwN1VVRkRVQ3hKUVVGSkxFTkJRVU5VTEZOQlFWTXNRMEZCUXl4UFFVRlBMRVZCUVVVc2MwSkJRWE5DTEVOQlFVTTdVVUZETDBNc1NVRkJTU3hEUVVGRFdTeFJRVUZSTEVOQlFVTjJRaXhOUVVGTkxFTkJRVU52UWl4aFFVRmhMRU5CUVVNN1VVRkRia01zU1VGQlNTeERRVUZEU1N4TlFVRk5MRWRCUVVVc1EwRkJSVHRSUVVObU8wMUJRMG9zUzBGQlN5eE5RVUZOTzAxQlExZzdVVUZEU1N4SlFVRkpMRU5CUVVOWUxGTkJRVk1zUlVGQlJUdEpRVU53UWp0RlFVTktPMFZCUlVFN1JVRkRRVk1zY1VKQlFYRkNRU3hEUVVGRFJpeGhRVUZ6UXp0SlFVTjRSRHRKUVVOQkxFMUJRVTFMTEVsQlFVa3NSMEZCUnl4SlFVRkJReXgzUWtGQll5eEZRVUZETEhGQ1FVRnhRaXhEUVVGRE8wbEJRMnhFUkN4SlFVRkpMRU5CUVVORkxGbEJRVmtzUTBGQlF5eE5RVUZOTEVWQlFVVlFMR0ZCUVdFc1EwRkJRMUVzUjBGQlJ5eERRVUZETzBsQlF6VkRMRWxCUVVGRExIRkNRVUZYTEVWQlFVTkRMRkZCUVZFc1JVRkJSVHROUVVGRkxIRkNRVUZ4UWl4RlFVRkZWaXhoUVVGaExFTkJRVU5YTzBsQlFVa3NRMEZCUlN4RFFVRkRPMGxCUlhCRk8wbEJRMEVzU1VGQlFVd3NkMEpCUVdNc1JVRkJReXh6UWtGQmMwSXNRMEZCUXl4RFFVRkRUU3hQUVVGUExFZEJRVWNzVFVGQlZ6dE5RVUZITEVsQlFVa3NRMEZCUTBNc2EwSkJRV3RDTEVWQlFVVTdTVUZCUlN4RFFVRkRPMGxCUlROR08wbEJRMEVzU1VGQlNTeERRVUZEY0VJc1UwRkJVeXhEUVVGRExHZENRVUZuUWl4RFFVRkRPMGxCUldoRE8wbEJRMEVzVFVGQlRYRkNMRkZCUVZFc1IwRkJSeXhKUVVGQlVpeDNRa0ZCWXl4RlFVRkRMSGxDUVVGNVFpeERRVUZETzBsQlF6RkVVU3hSUVVGUkxFTkJRVU5ETEZOQlFWTXNRMEZCUTBNc1RVRkJUU3hEUVVGRExHdENRVUZyUWl4RFFVRkRPMGxCUXpkRExFbEJRVWxvUWl4aFFVRmhMRU5CUVVOcFFpeFBRVUZQTEV0QlFVc3NTVUZCU1N4RlFVRkZPMDFCUTJoRFNDeFJRVUZSTEVOQlFVTkpMRXRCUVVzc1EwRkJRME1zYTBKQlFXdENMRWRCUVVjc1IwRkJSMjVDTEdGQlFXRXNRMEZCUTJsQ0xFOUJRVThzUjBGQlIwY3NTVUZCU1N4RFFVRkRReXhIUVVGSExFVkJRVVVzU1VGQlNUdE5RVU0zUlN4TFFVRkxVQ3hSUVVGUkxFTkJRVU5STEZsQlFXRXNRMEZCUXl4RFFVRkRPMDFCUXpkQ1VpeFJRVUZSTEVOQlFVTkRMRk5CUVZNc1EwRkJRMUVzUjBGQlJ5eERRVUZETEd0Q1FVRnJRaXhEUVVGRE8wbEJRemxETzBWQlEwbzdSVUZGUVR0RlFVTkJjRUlzVVVGQlVVRXNRMEZCUTBnc1lVRkJkME03U1VGRE4wTTdTVUZEUVN4SlFVRkJUU3gzUWtGQll5eEZRVUZETEhkQ1FVRjNRaXhEUVVGRExFTkJRVU5yUWl4WFFVRlhMRWRCUVVkNFFpeGhRVUZoTEVOQlFVTmFMRTlCUVU4N1NVRkZOVVU3U1VGRFFTeEpRVUZCYTBJc2QwSkJRV01zUlVGQlF5d3dRa0ZCTUVJc1EwRkJReXhEUVVGRGJVSXNUVUZCVFN4SFFVRkhMRU5CUVVONlFpeGhRVUZoTEVOQlFVTXdRaXhUUVVGVE8wbEJRelZGTEVsQlFVRndRaXgzUWtGQll5eEZRVUZETEhOQ1FVRnpRaXhEUVVGRExFTkJRVXR0UWl4TlFVRk5MRWRCUVVjc1EwRkJRM3BDTEdGQlFXRXNRMEZCUXpCQ0xGTkJRVk03U1VGRE5VVXNTVUZCUVhCQ0xIZENRVUZqTEVWQlFVTXNjMEpCUVhOQ0xFTkJRVU1zUTBGQlEwMHNUMEZCVHl4SFFVRkhMRTFCUVZjN1RVRkJSeXhKUVVGSkxFTkJRVU5ETEd0Q1FVRnJRaXhGUVVGRk8wbEJRVVVzUTBGQlF6dEpRVVV6Ump0SlFVTkJMRWxCUVVsaUxHRkJRV0VzUTBGQlF6SkNMRWxCUVVrc1JVRkJSVHROUVVOd1FqdE5RVU5CTEUxQlFVMURMRTlCUVU4c1IwRkJSMEVzUTBGQlEwTXNSVUZCVlN4RlFVRkZReXhKUVVGakxFdEJRVlU3VVVGRGFrUXNTVUZCUVhoQ0xIZENRVUZqTEVWQlFVTjFRaXhGUVVGRkxFTkJRVU1zUTBGQlEwVXNaVUZCWlN4RFFVRkRMRWRCUVVkRUxFbEJRVWtzUTBGQlEwVXNSMEZCUnl4RFFVRkRReXhUUVVGVExFbEJRM0JFTEVsQlFVRkRMSFZDUVVGaExFVkJRVU1zTUVKQlFUQkNMRVZCUVVVN1ZVRkJSVVE3VVVGQlV5eERRVUZGTEVOQlFVVXNRMEZCUXl4RFFVRkRPMDFCUTI1RkxFTkJRVU03VFVGRFJFd3NUMEZCVHl4RFFVRkRMREJDUVVFd1FpeEZRVUZITlVJc1lVRkJZU3hEUVVGRE1rSXNTVUZCU1N4RFFVRkRVU3hUUVVGVExFTkJRVU03VFVGRGJFVlFMRTlCUVU4c1EwRkJReXd5UWtGQk1rSXNSVUZCUlRWQ0xHRkJRV0VzUTBGQlF6SkNMRWxCUVVrc1EwRkJRMU1zVlVGQlZTeERRVUZETzAxQlJXNUZPMDFCUTBFc1RVRkJUVHRSUVVGRlF6dE5RVUZOTEVOQlFVVXNSMEZCUjNKRExHRkJRV0VzUTBGQlF6SkNMRWxCUVVrN1RVRkRja01zVFVGQlRYUkNMRWxCUVVrc1IwRkJSeXhKUVVGQlF5eDNRa0ZCWXl4RlFVRkRMRzlDUVVGdlFpeERRVUZETzAxQlEycEVMRWxCUVVrclFpeE5RVUZOTEVWQlFVVTdVVUZEVWl4SlFVRkJMMElzZDBKQlFXTXNSVUZCUXl4blEwRkJaME1zUTBGQlF5eERRVUZEZVVJc1pVRkJaU3hEUVVNMVJDeEhRVUZIVHl4TlFVRk5MRU5CUVVORExFOUJRVThzUTBGQlEwWXNUVUZCVFN4RFFVRkRSeXhSUVVGUkxFTkJRVU1zUTBGQlExSXNSMEZCUnl4RFFVRkRMRU5CUVVNc1EwRkJRMU1zUjBGQlJ5eEZRVUZGUXl4TFFVRkxMRU5CUVVNc1MwRkRhRVFzU1VGQlFWSXNkVUpCUVdFc1JVRkJReXdyUWtGQkswSXNSVUZCUlR0VlFVRkZUeXhIUVVGSE8xVkJRVVZETzFGQlFVc3NRMEZCUlN4RFFVRkRMRU5CUVVNc1EwRkJRenRSUVVONFJYSkRMRWxCUVVrc1EwRkJRMFVzV1VGQldTeERRVUZETEUxQlFVMHNSVUZCUlRoQ0xFMUJRVTBzUTBGQlF6ZENMRWRCUVVjc1EwRkJRenRSUVVOeVEwZ3NTVUZCU1N4RFFVRkRiVUlzVjBGQlZ5eEhRVUZIWVN4TlFVRk5MRU5CUVVOTkxFMUJRVTBzUzBGQlN5eFJRVUZSTEVkQlFVY3NiMEpCUVc5Q0xFZEJRVWNzYjBKQlFXOUNPMUZCUXpOR2RFTXNTVUZCU1N4RFFVRkRiMElzVFVGQlRTeEhRVUZITEV0QlFVczdVVUZEYmtJc1NVRkJRVzVDTEhkQ1FVRmpMRVZCUVVNc2RVSkJRWFZDTEVOQlFVTXNRMEZCUTIxQ0xFMUJRVTBzUjBGQlJ5eExRVUZMTzAxQlF6RkVMRU5CUVVNc1RVRkJUVHRSUVVOSWNFSXNTVUZCU1N4RFFVRkRiMElzVFVGQlRTeEhRVUZITEVsQlFVazdVVUZEYkVJc1NVRkJRVzVDTEhkQ1FVRmpMRVZCUVVNc2RVSkJRWFZDTEVOQlFVTXNRMEZCUTIxQ0xFMUJRVTBzUjBGQlJ5eEpRVUZKTzAxQlEzcEVPMDFCUlVFN1RVRkRRU3hKUVVGQmJrSXNkMEpCUVdNc1JVRkJReXgxUWtGQmRVSXNRMEZCUXl4RFFVRkRiVUlzVFVGQlRTeEhRVUZITEV0QlFVczdTVUZETVVRc1EwRkJReXhOUVVGTk8wMUJRMGc3VFVGRFFTeEpRVUZCYmtJc2QwSkJRV01zUlVGQlF5eHZRa0ZCYjBJc1EwRkJReXhEUVVGSmJVSXNUVUZCVFN4SFFVRkhMRWxCUVVrN1RVRkRja1FzU1VGQlFXNUNMSGRDUVVGakxFVkJRVU1zZFVKQlFYVkNMRU5CUVVNc1EwRkJRMjFDTEUxQlFVMHNSMEZCUnl4SlFVRkpPMGxCUTNwRU8wbEJSVUU3U1VGRFFTeEpRVUZKTEVOQlFVTm9ReXhUUVVGVExFTkJRVU1zWjBKQlFXZENMRU5CUVVNN1JVRkRjRU03UlVGRlFUdEZRVU5CYjBJc2EwSkJRV3RDUVN4RFFVRkJPMGxCUTJRc1NVRkJRU3RDTEd0Q1FVRlJMRVZCUVVNc1NVRkJTU3hEUVVGRGJrVXNSMEZCUnl4RlFVRkZMSEZDUVVGeFFpeEZRVUZGTEZsQlFWYzdUVUZEYWtRc1NVRkJTVHRSUVVOQkxFMUJRVTBzU1VGQlNTeERRVUZEUXl4SFFVRkhMRU5CUVVOUkxFOUJRVThzUTBGQlF5eHBRa0ZCYVVJc1JVRkJSU3hKUVVGSkxFTkJRVU03VVVGREwwTXNTVUZCU1N4RFFVRkRTeXhUUVVGVExFTkJRVU1zVFVGQlRTeEZRVUZGTEcxRFFVRnRReXhEUVVGRE8wMUJReTlFTEVOQlFVTXNRMEZCUXl4UFFVRlBTaXhIUVVGSExFVkJRVVU3VVVGRFZpeE5RVUZOUXl4UFFVRlBMRWRCUVVkRUxFZEJRVWNzV1VGQldVVXNTMEZCU3l4SFFVRkhSaXhIUVVGSExFTkJRVU5ETEU5QlFVOHNSMEZCUjBVc1RVRkJUU3hEUVVGRFNDeEhRVUZITEVOQlFVTTdVVUZEYUVVc1NVRkJTU3hEUVVGRFNTeFRRVUZUTEVOQlFVTXNUMEZCVHl4RlFVRkZMR3REUVVGclEwZ3NUMEZCVHl4RlFVRkZMRU5CUVVNN1RVRkRlRVU3U1VGRFNpeERRVUZETEVOQlFVTXNSVUZCUlR0RlFVTlNPMFZCUlVFN1JVRkRRVXNzVTBGQlUwRXNRMEZCUTI5RUxFMUJRV1U3U1VGRGNrSXNTMEZCU3l4TlFVRk5hRUlzUlVGQlJTeEpRVUZKTEVOQlFVTXNaMEpCUVdkQ0xFVkJRVVVzWjBKQlFXZENMRU5CUVVNc1JVRkJSVHROUVVOdVJDeEpRVUZCZGtJc2QwSkJRV01zUlVGQlEzVkNMRVZCUVVVc1EwRkJReXhEUVVGRFNpeE5RVUZOTEVkQlFVZEpMRVZCUVVVc1MwRkJTMmRDTEUxQlFVMDdTVUZETjBNN1JVRkRTanRGUVVWQk8wVkJRMEYwUkN4VFFVRlRRU3hEUVVGRGRVUXNTMEZCY1VNc1JVRkJSVEZFTEU5QlFXVTdTVUZETlVRN1NVRkRRU3hOUVVGTmNVUXNSMEZCUnl4SFFVRkhMRWRCUVVkTExFdEJRVXNzVFVGQlRURkVMRTlCUVU4c1JVRkJSVHRKUVVOdVF5eEpRVUZKTEVsQlFVa3NRMEZCUXpKRUxGTkJRVk1zUzBGQlMwNHNSMEZCUnl4RlFVRkZPMGxCUXpWQ0xFbEJRVWtzUTBGQlEwMHNVMEZCVXl4SFFVRkhUaXhIUVVGSE8wbEJRM0JDVHl4VlFVRlZMRU5CUVVNc1RVRkJTenROUVVOYUxFbEJRVWtzU1VGQlNTeERRVUZEUkN4VFFVRlRMRXRCUVV0T0xFZEJRVWNzUlVGQlJTeEpRVUZKTEVOQlFVTk5MRk5CUVZNc1IwRkJSM1pFTEZOQlFWTTdTVUZETVVRc1EwRkJReXhGUVVGRmJrSXNaMEpCUVdkQ0xFTkJRVU03U1VGRmNFSTdTVUZEUVRSRkxFMUJRVTBzUTBGQlEwTXNWVUZCVlN4RFFVRkRReXhMUVVGTExFTkJRVU5NTEV0QlFVc3NRMEZCUXl4RFFVRkRNVVFzVDBGQlR5eEZRVUZGTEhGQ1FVRnhRaXhEUVVGRE8wVkJRMnhGT3p0QlFVTklaMFVzVDBGQlFTeERRVUZCTjBVc1kwRkJRU3hIUVVGQlFTeGpRVUZCSWl3aWFXZHViM0psVEdsemRDSTZXMTE5IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLkNsaWVudElQQyA9IHZvaWQgMDtcbnZhciBfbG9nRXJyb3IgPSByZXF1aXJlKFwiLi4vLi4vbG9nLWVycm9yLmpzXCIpO1xuLy8gSG9tZWJyaWRnZSBwbHVnaW4gZm9yIEhvbWUgQ29ubmVjdCBob21lIGFwcGxpYW5jZXNcbi8vIENvcHlyaWdodCDCqSAyMDIzLTIwMjYgQWxleGFuZGVyIFRob3VreWRpZGVzXG5cbi8vIENsaWVudC1zaWRlIElQQyBpbXBsZW1lbnRhdGlvblxuY2xhc3MgQ2xpZW50SVBDIHtcbiAgLy8gQ3JlYXRlIGEgbmV3IGNsaWVudCBJUEMgaW5zdGFuY2VcbiAgY29uc3RydWN0b3IobG9nKSB7XG4gICAgdGhpcy5sb2cgPSBsb2c7XG4gIH1cbiAgLy8gSXNzdWUgYSByZXF1ZXN0IHRvIHRoZSBzZXJ2ZXJcbiAgYXN5bmMgcmVxdWVzdChwYXRoLCBkYXRhKSB7XG4gICAgdHJ5IHtcbiAgICAgIHRoaXMubG9nLmRlYnVnKGByZXF1ZXN0KFwiJHtwYXRofVwiLCAlTylgLCBkYXRhKTtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHdpbmRvdy5ob21lYnJpZGdlLnJlcXVlc3QocGF0aCwgZGF0YSk7XG4gICAgICB0aGlzLmxvZy5kZWJ1ZyhgcmVxdWVzdChcIiR7cGF0aH1cIiwgJU8pID0+YCwgZGF0YSwgcmVzdWx0KTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICB0aGlzLmxvZy5lcnJvcihgcmVxdWVzdChcIiR7cGF0aH1cIiwgJU8pID0+YCwgZGF0YSwgZXJyKTtcbiAgICAgIHRocm93IGVycjtcbiAgICB9XG4gIH1cbiAgLy8gQWRkIGFuIGV2ZW50IGxpc3RlbmVyXG4gIG9uRXZlbnQoZXZlbnQsIGNhbGxiYWNrKSB7XG4gICAgd2luZG93LmhvbWVicmlkZ2UuYWRkRXZlbnRMaXN0ZW5lcihldmVudCwgKDAsIF9sb2dFcnJvci5kZXRhY2hlZCkodGhpcy5sb2csICdvbkV2ZW50JywgYXN5bmMgZXZ0ID0+IHtcbiAgICAgIGNvbnN0IGRhdGEgPSBldnQuZGF0YTtcbiAgICAgIGlmIChldmVudCAhPT0gJ2xvZycpIHRoaXMubG9nLmRlYnVnKGBvbkV2ZW50KFwiJHtldmVudH1cIikgPT4gY2FsbGJhY2tgLCBkYXRhKTtcbiAgICAgIGF3YWl0IGNhbGxiYWNrKGRhdGEpO1xuICAgIH0pKTtcbiAgfVxufVxuZXhwb3J0cy5DbGllbnRJUEMgPSBDbGllbnRJUEM7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldD11dGYtODtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnVZVzFsY3lJNld5SmZiRzluUlhKeWIzSWlMQ0p5WlhGMWFYSmxJaXdpUTJ4cFpXNTBTVkJESWl3aVkyOXVjM1J5ZFdOMGIzSWlMQ0pzYjJjaUxDSnlaWEYxWlhOMElpd2ljR0YwYUNJc0ltUmhkR0VpTENKa1pXSjFaeUlzSW5KbGMzVnNkQ0lzSW5kcGJtUnZkeUlzSW1odmJXVmljbWxrWjJVaUxDSmxjbklpTENKbGNuSnZjaUlzSW05dVJYWmxiblFpTENKbGRtVnVkQ0lzSW1OaGJHeGlZV05ySWl3aVlXUmtSWFpsYm5STWFYTjBaVzVsY2lJc0ltUmxkR0ZqYUdWa0lpd2laWFowSWl3aVpYaHdiM0owY3lKZExDSnpiM1Z5WTJWeklqcGJJaTR1THk0dUx5NHVMM055WXk5b2IyMWxZbkpwWkdkbExYVnBMM0IxWW14cFl5OWpiR2xsYm5RdGFYQmpMblJ6SWwwc0luTnZkWEpqWlhORGIyNTBaVzUwSWpwYmJuVnNiRjBzSW0xaGNIQnBibWR6SWpvaU96czdPenM3UVVGTlFTeEpRVUZCUVN4VFFVRkJMRWRCUVVGRExFOUJRVUU3UVVGT1FUdEJRVU5CT3p0QlFVOUJPMEZCUTAwc1RVRkJUME1zVTBGQlV6dEZRVVZzUWp0RlFVTkJReXhaUVVGeFFrTXNSMEZCVnp0bFFVRllRU3hIUVVGSE8wVkJRVmM3UlVGRmJrTTdSVUZEUVN4TlFVRk5ReXhQUVVGUFFTeERRVUV3UWtNc1NVRkJWU3hGUVVGRlF5eEpRVUY1UWp0SlFVTjRSU3hKUVVGSk8wMUJRMEVzU1VGQlNTeERRVUZEU0N4SFFVRkhMRU5CUVVOSkxFdEJRVXNzUTBGQlF5eFpRVUZaUml4SlFVRkpMRkZCUVZFc1JVRkJSVU1zU1VGQlNTeERRVUZETzAxQlF6bERMRTFCUVUxRkxFMUJRVTBzUjBGQldTeE5RVUZOUXl4TlFVRk5MRU5CUVVORExGVkJRVlVzUTBGQlEwNHNUMEZCVHl4RFFVRkRReXhKUVVGSkxFVkJRVVZETEVsQlFVa3NRMEZCUXp0TlFVTnVSU3hKUVVGSkxFTkJRVU5JTEVkQlFVY3NRMEZCUTBrc1MwRkJTeXhEUVVGRExGbEJRVmxHTEVsQlFVa3NWMEZCVnl4RlFVRkZReXhKUVVGSkxFVkJRVVZGTEUxQlFVMHNRMEZCUXp0TlFVTjZSQ3hQUVVGUFFTeE5RVUU0UWp0SlFVTjZReXhEUVVGRExFTkJRVU1zVDBGQlQwY3NSMEZCUnl4RlFVRkZPMDFCUTFZc1NVRkJTU3hEUVVGRFVpeEhRVUZITEVOQlFVTlRMRXRCUVVzc1EwRkJReXhaUVVGWlVDeEpRVUZKTEZkQlFWY3NSVUZCUlVNc1NVRkJTU3hGUVVGRlN5eEhRVUZITEVOQlFVTTdUVUZEZEVRc1RVRkJUVUVzUjBGQlJ6dEpRVU5pTzBWQlEwbzdSVUZGUVR0RlFVTkJSU3hQUVVGUFFTeERRVUUwUWtNc1MwRkJXU3hGUVVGRlF5eFJRVUVyUkR0SlFVTTFSMDRzVFVGQlRTeERRVUZEUXl4VlFVRlZMRU5CUVVOTkxHZENRVUZuUWl4RFFVRkRSaXhMUVVGTExFVkJRVVVzU1VGQlFVY3NhMEpCUVZFc1JVRkJReXhKUVVGSkxFTkJRVU5rTEVkQlFVY3NSVUZCUlN4VFFVRlRMRVZCUVVVc1RVRkJUMlVzUjBGQlJ5eEpRVUZKTzAxQlEyeEdMRTFCUVUxYUxFbEJRVWtzUjBGQlNWa3NSMEZCYlVRc1EwRkJRMW9zU1VGQlNUdE5RVU4wUlN4SlFVRkpVU3hMUVVGTExFdEJRVXNzUzBGQlN5eEZRVUZGTEVsQlFVa3NRMEZCUTFnc1IwRkJSeXhEUVVGRFNTeExRVUZMTEVOQlFVTXNXVUZCV1U4c1MwRkJTeXhuUWtGQlowSXNSVUZCUlZJc1NVRkJTU3hEUVVGRE8wMUJRelZGTEUxQlFVMVRMRkZCUVZFc1EwRkJRMVFzU1VGQlNTeERRVUZETzBsQlEzaENMRU5CUVVNc1EwRkJReXhEUVVGRE8wVkJRMUE3TzBGQlEwaGhMRTlCUVVFc1EwRkJRV3hDTEZOQlFVRXNSMEZCUVVFc1UwRkJRU0lzSW1sbmJtOXlaVXhwYzNRaU9sdGRmUT09IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciBfbG9nZ2VyID0gcmVxdWlyZShcIi4vbG9nZ2VyLmpzXCIpO1xudmFyIF9jb25maWcgPSByZXF1aXJlKFwiLi9jb25maWcuanNcIik7XG52YXIgX2NhcmRzID0gcmVxdWlyZShcIi4vY2FyZHMuanNcIik7XG52YXIgX2NsaWVudENsaWVudGlkID0gcmVxdWlyZShcIi4vY2xpZW50LWNsaWVudGlkLmpzXCIpO1xudmFyIF9mb3JtcyA9IHJlcXVpcmUoXCIuL2Zvcm1zLmpzXCIpO1xudmFyIF9jbGllbnRJcGMgPSByZXF1aXJlKFwiLi9jbGllbnQtaXBjLmpzXCIpO1xudmFyIF9hcGlTdGF0dXMgPSByZXF1aXJlKFwiLi9hcGktc3RhdHVzLmpzXCIpO1xuLy8gSG9tZWJyaWRnZSBwbHVnaW4gZm9yIEhvbWUgQ29ubmVjdCBob21lIGFwcGxpYW5jZXNcbi8vIENvcHlyaWdodCDCqSAyMDIzLTIwMjYgQWxleGFuZGVyIFRob3VreWRpZGVzXG5cbi8vIEEgSG9tZWJyaWRnZSBIb21lQ29ubmVjdCBjdXN0b20gVUkgY2xpZW50XG5jbGFzcyBDbGllbnQge1xuICAvLyBDcmVhdGUgYSBuZXcgY3VzdG9tIFVJIGNsaWVudFxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICAvLyBDcmVhdGUgYSBsb2NhbCBsb2dnZXIgYW5kIElQQyBjbGllbnRcbiAgICB0aGlzLmxvZyA9IG5ldyBfbG9nZ2VyLkNsaWVudExvZ2dlcigpO1xuICAgIHRoaXMubG9nLmRlYnVnKCdob21lYnJpZGdlLnBsdWdpbicsIHdpbmRvdy5ob21lYnJpZGdlLnBsdWdpbik7XG4gICAgdGhpcy5pcGMgPSBuZXcgX2NsaWVudElwYy5DbGllbnRJUEModGhpcy5sb2cpO1xuICAgIC8vIFdhaXQgZm9yIHRoZSBzZXJ2ZXIgYmVmb3JlIGNvbnRpbnVpbmcgaW5pdGlhbGlzYXRpb25cbiAgICB0aGlzLmlwYy5vbkV2ZW50KCdyZWFkeScsICgpID0+IHtcbiAgICAgIHRoaXMuc2VydmVyUmVhZHkoKTtcbiAgICB9KTtcbiAgfVxuICAvLyBUaGUgc2VydmVyIGlzIHJlYWR5IHNvIGZpbmlzaCBpbml0aWFsaXNpbmcgdGhlIGNsaWVudFxuICBzZXJ2ZXJSZWFkeSgpIHtcbiAgICAvLyBTdGFydCByZWNlaXZpbmcgKGltcG9ydGFudCkgbG9nIG1lc3NhZ2VzIGZyb20gdGhlIHNlcnZlclxuICAgIHRoaXMuc2VydmVyTG9nID0gbmV3IF9sb2dnZXIuU2VydmVyTG9nZ2VyKHRoaXMuaXBjLCBcIndhcm5cIiAvKiBMb2dMZXZlbC5XQVJOICovKTtcbiAgICAvLyBDcmVhdGUgYWxsIG9mIHRoZSByZXF1aXJlZCByZXNvdXJjZXNcbiAgICBjb25zdCBjb25maWcgPSBuZXcgX2NvbmZpZy5Db25maWcodGhpcy5sb2csIHRoaXMuaXBjKTtcbiAgICBjb25zdCBmb3JtcyA9IG5ldyBfZm9ybXMuRm9ybXModGhpcy5sb2csIHRoaXMuaXBjLCBjb25maWcpO1xuICAgIGNvbnN0IGNhcmRzID0gbmV3IF9jYXJkcy5DYXJkcyh0aGlzLmxvZyk7XG4gICAgY29uc3QgY2xpZW50ID0gbmV3IF9jbGllbnRDbGllbnRpZC5DbGllbnRDbGllbnRJRCh0aGlzLmxvZywgdGhpcy5pcGMpO1xuICAgIG5ldyBfYXBpU3RhdHVzLkFQSVN0YXR1cyh0aGlzLmxvZyk7XG4gICAgLy8gQ3JlYXRlIGNhcmRzIGZvciB0aGUgZ2xvYmFsIHNldHRpbmdzIGFuZCBlYWNoIGF2YWlsYWJsZSBhcHBsaWFuY2VcbiAgICBjYXJkcy5zZXROb25BcHBsaWFuY2VzKFt7XG4gICAgICBpZDogX2Zvcm1zLkZvcm1JZC5HbG9iYWwsXG4gICAgICBpY29uOiAnZ2xvYmFsJyxcbiAgICAgIG5hbWU6ICdHZW5lcmFsIFNldHRpbmdzJ1xuICAgIH1dKTtcbiAgICBjbGllbnQub25BcHBsaWFuY2VzID0gYXBwbGlhbmNlcyA9PiB7XG4gICAgICBjYXJkcy5zZXRBcHBsaWFuY2VzKGFwcGxpYW5jZXMgPz8gW10pO1xuICAgIH07XG4gICAgY2FyZHMub25TZWxlY3QgPSBpZCA9PiB7XG4gICAgICBmb3Jtcy5zaG93Rm9ybShpZCk7XG4gICAgfTtcbiAgICAvLyBBdHRlbXB0IHRvIGF1dGhvcmlzZSBhIGNsaWVudCB3aGVuIHRoZSBjb25maWd1cmF0aW9uIGNoYW5nZXNcbiAgICBjb25maWcub25HbG9iYWwgPSBjb25maWcgPT4gY2xpZW50LnNldENsaWVudChjb25maWcpO1xuICAgIGNsaWVudC5vbkZhaWwgPSAoKSA9PiB7XG4gICAgICBmb3Jtcy5zaG93Rm9ybShfZm9ybXMuRm9ybUlkLkdsb2JhbCk7XG4gICAgfTtcbiAgfVxufVxuLy8gQ3JlYXRlIGEgY3VzdG9tIFVJIGNsaWVudCBpbnN0YW5jZVxubmV3IENsaWVudCgpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ9dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p1WVcxbGN5STZXeUpmYkc5bloyVnlJaXdpY21WeGRXbHlaU0lzSWw5amIyNW1hV2NpTENKZlkyRnlaSE1pTENKZlkyeHBaVzUwUTJ4cFpXNTBhV1FpTENKZlptOXliWE1pTENKZlkyeHBaVzUwU1hCaklpd2lYMkZ3YVZOMFlYUjFjeUlzSWtOc2FXVnVkQ0lzSW1OdmJuTjBjblZqZEc5eUlpd2liRzluSWl3aVEyeHBaVzUwVEc5bloyVnlJaXdpWkdWaWRXY2lMQ0ozYVc1a2IzY2lMQ0pvYjIxbFluSnBaR2RsSWl3aWNHeDFaMmx1SWl3aWFYQmpJaXdpUTJ4cFpXNTBTVkJESWl3aWIyNUZkbVZ1ZENJc0luTmxjblpsY2xKbFlXUjVJaXdpYzJWeWRtVnlURzluSWl3aVUyVnlkbVZ5VEc5bloyVnlJaXdpWTI5dVptbG5JaXdpUTI5dVptbG5JaXdpWm05eWJYTWlMQ0pHYjNKdGN5SXNJbU5oY21Seklpd2lRMkZ5WkhNaUxDSmpiR2xsYm5RaUxDSkRiR2xsYm5SRGJHbGxiblJKUkNJc0lrRlFTVk4wWVhSMWN5SXNJbk5sZEU1dmJrRndjR3hwWVc1alpYTWlMQ0pwWkNJc0lrWnZjbTFKWkNJc0lrZHNiMkpoYkNJc0ltbGpiMjRpTENKdVlXMWxJaXdpYjI1QmNIQnNhV0Z1WTJWeklpd2lZWEJ3YkdsaGJtTmxjeUlzSW5ObGRFRndjR3hwWVc1alpYTWlMQ0p2YmxObGJHVmpkQ0lzSW5Ob2IzZEdiM0p0SWl3aWIyNUhiRzlpWVd3aUxDSnpaWFJEYkdsbGJuUWlMQ0p2YmtaaGFXd2lYU3dpYzI5MWNtTmxjeUk2V3lJdUxpOHVMaTh1TGk5emNtTXZhRzl0WldKeWFXUm5aUzExYVM5d2RXSnNhV012WTJ4cFpXNTBMblJ6SWwwc0luTnZkWEpqWlhORGIyNTBaVzUwSWpwYmJuVnNiRjBzSW0xaGNIQnBibWR6SWpvaU96dEJRVXRCTEVsQlFVRkJMRTlCUVVFc1IwRkJRVU1zVDBGQlFUdEJRVU5CTEVsQlFVRkRMRTlCUVVFc1IwRkJRVVFzVDBGQlFUdEJRVU5CTEVsQlFVRkZMRTFCUVVFc1IwRkJRVVlzVDBGQlFUdEJRVU5CTEVsQlFVRkhMR1ZCUVVFc1IwRkJRVWdzVDBGQlFUdEJRVU5CTEVsQlFVRkpMRTFCUVVFc1IwRkJRVW9zVDBGQlFUdEJRVU5CTEVsQlFVRkxMRlZCUVVFc1IwRkJRVXdzVDBGQlFUdEJRVU5CTEVsQlFVRk5MRlZCUVVFc1IwRkJRVTRzVDBGQlFUdEJRVmhCTzBGQlEwRTdPMEZCV1VFN1FVRkRRU3hOUVVGTlR5eE5RVUZOTzBWQlUxSTdSVUZEUVVNc1dVRkJRVHRKUVVOSk8wbEJRMEVzU1VGQlNTeERRVUZEUXl4SFFVRkhMRWRCUVVjc1NVRkJTVU1zYjBKQlFWa3NSVUZCUlR0SlFVTTNRaXhKUVVGSkxFTkJRVU5FTEVkQlFVY3NRMEZCUTBVc1MwRkJTeXhEUVVGRExHMUNRVUZ0UWl4RlFVRkZReXhOUVVGTkxFTkJRVU5ETEZWQlFWVXNRMEZCUTBNc1RVRkJUU3hEUVVGRE8wbEJRemRFTEVsQlFVa3NRMEZCUTBNc1IwRkJSeXhIUVVGSExFbEJRVWxETEc5Q1FVRlRMRU5CUVVNc1NVRkJTU3hEUVVGRFVDeEhRVUZITEVOQlFVTTdTVUZGYkVNN1NVRkRRU3hKUVVGSkxFTkJRVU5OTEVkQlFVY3NRMEZCUTBVc1QwRkJUeXhEUVVGRExFOUJRVThzUlVGQlJTeE5RVUZMTzAxQlFVY3NTVUZCU1N4RFFVRkRReXhYUVVGWExFVkJRVVU3U1VGQlJTeERRVUZETEVOQlFVTTdSVUZETlVRN1JVRkZRVHRGUVVOQlFTeFhRVUZYUVN4RFFVRkJPMGxCUTFBN1NVRkRRU3hKUVVGSkxFTkJRVU5ETEZOQlFWTXNSMEZCUnl4SlFVRkpReXh2UWtGQldTeERRVUZETEVsQlFVa3NRMEZCUTB3c1IwRkJSeXcyUWtGQlowSTdTVUZGTVVRN1NVRkRRU3hOUVVGTlRTeE5RVUZOTEVkQlFVY3NTVUZCU1VNc1kwRkJUU3hEUVVGRExFbEJRVWtzUTBGQlEySXNSMEZCUnl4RlFVRkZMRWxCUVVrc1EwRkJRMDBzUjBGQlJ5eERRVUZETzBsQlF6ZERMRTFCUVUxUkxFdEJRVXNzUjBGQlNTeEpRVUZKUXl4WlFVRkxMRU5CUVVNc1NVRkJTU3hEUVVGRFppeEhRVUZITEVWQlFVVXNTVUZCU1N4RFFVRkRUU3hIUVVGSExFVkJRVVZOTEUxQlFVMHNRMEZCUXp0SlFVTndSQ3hOUVVGTlNTeExRVUZMTEVkQlFVa3NTVUZCU1VNc1dVRkJTeXhEUVVGRExFbEJRVWtzUTBGQlEycENMRWRCUVVjc1EwRkJRenRKUVVOc1F5eE5RVUZOYTBJc1RVRkJUU3hIUVVGSExFbEJRVWxETERoQ1FVRmpMRU5CUVVNc1NVRkJTU3hEUVVGRGJrSXNSMEZCUnl4RlFVRkZMRWxCUVVrc1EwRkJRMDBzUjBGQlJ5eERRVUZETzBsQlEzSkVMRWxCUVVsakxHOUNRVUZUTEVOQlFVTXNTVUZCU1N4RFFVRkRjRUlzUjBGQlJ5eERRVUZETzBsQlJYWkNPMGxCUTBGblFpeExRVUZMTEVOQlFVTkxMR2RDUVVGblFpeERRVUZETEVOQlFVTTdUVUZCUlVNc1JVRkJSU3hGUVVGRlF5eGhRVUZOTEVOQlFVTkRMRTFCUVUwN1RVRkJSVU1zU1VGQlNTeEZRVUZGTEZGQlFWRTdUVUZCUlVNc1NVRkJTU3hGUVVGRk8wbEJRV3RDTEVOQlFVVXNRMEZCUXl4RFFVRkRPMGxCUTNwR1VpeE5RVUZOTEVOQlFVTlRMRmxCUVZrc1IwRkJTVU1zVlVGQlZTeEpRVUZYTzAxQlFVZGFMRXRCUVVzc1EwRkJRMkVzWVVGQllTeERRVUZEUkN4VlFVRlZMRWxCUVVrc1JVRkJSU3hEUVVGRE8wbEJRVVVzUTBGQlF6dEpRVU4yUmxvc1MwRkJTeXhEUVVGRFl5eFJRVUZSTEVkQlFWTlNMRVZCUVZjc1NVRkJWVHROUVVGSFVpeExRVUZMTEVOQlFVTnBRaXhSUVVGUkxFTkJRVU5VTEVWQlFVVXNRMEZCUXp0SlFVRkZMRU5CUVVNN1NVRkZjRVU3U1VGRFFWWXNUVUZCVFN4RFFVRkRiMElzVVVGQlVTeEhRVUZKY0VJc1RVRkJUU3hKUVVGdlFrMHNUVUZCVFN4RFFVRkRaU3hUUVVGVExFTkJRVU55UWl4TlFVRk5MRU5CUVVNN1NVRkRja1ZOTEUxQlFVMHNRMEZCUTJkQ0xFMUJRVTBzUjBGQlN5eE5RVUZwUWp0TlFVRkhjRUlzUzBGQlN5eERRVUZEYVVJc1VVRkJVU3hEUVVGRFVpeGhRVUZOTEVOQlFVTkRMRTFCUVUwc1EwRkJRenRKUVVGRkxFTkJRVU03UlVGRE1VVTdPMEZCUjBvN1FVRkRRU3hKUVVGSk1VSXNUVUZCVFN4RlFVRkZJaXdpYVdkdWIzSmxUR2x6ZENJNlcxMTkiLCJcInVzZSBzdHJpY3RcIjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuQ29uZmlnID0gdm9pZCAwO1xudmFyIF91dGlscyA9IHJlcXVpcmUoXCIuLi8uLi91dGlscy5qc1wiKTtcbnZhciBfdXRpbHNEb20gPSByZXF1aXJlKFwiLi91dGlscy1kb20uanNcIik7XG52YXIgX2NvbmZpZ1R5cGVzID0gcmVxdWlyZShcIi4uLy4uL3RpL2NvbmZpZy10eXBlcy5qc1wiKTtcbi8vIEhvbWVicmlkZ2UgcGx1Z2luIGZvciBIb21lIENvbm5lY3QgaG9tZSBhcHBsaWFuY2VzXG4vLyBDb3B5cmlnaHQgwqkgMjAyMy0yMDI2IEFsZXhhbmRlciBUaG91a3lkaWRlc1xuXG4vLyBUaGUgY3VycmVudCBwbHVnaW4gY29uZmlndXJhdGlvblxuY2xhc3MgQ29uZmlnIHtcbiAgLy8gQ3JlYXRlIGEgbmV3IGNvbmZpZ3VyYXRpb24gb2JqZWN0XG4gIGNvbnN0cnVjdG9yKGxvZywgaXBjKSB7XG4gICAgdGhpcy5sb2cgPSBsb2c7XG4gICAgdGhpcy5pcGMgPSBpcGM7XG4gICAgLy8gVGhlIGNvbmZpZ3VyYXRpb24gYmVpbmcgZWRpdGVkXG4gICAgdGhpcy5nbG9iYWwgPSB7fTtcbiAgICB0aGlzLmFwcGxpYW5jZXMgPSB7fTtcbiAgICB0aGlzLnJlYWR5UHJvbWlzZSA9IHRoaXMuZ2V0Q29uZmlnKCk7XG4gICAgdGhpcy5hY3RpdmVQcm9taXNlID0gdGhpcy5nZXRBY3RpdmVDb25maWcoKTtcbiAgfVxuICAvLyBSZXRyaWV2ZSBhbmQgcGFyc2UgdGhlIGNvbmZpZ3VyYXRpb24gdG8gYmUgZWRpdGVkXG4gIGFzeW5jIGdldENvbmZpZygpIHtcbiAgICAvLyBSZXRyaWV2ZSB0aGUgY3VycmVudCBwbHVnaW4gY29uZmlndXJhdGlvbiAoaWYgYW55KVxuICAgIGNvbnN0IGNvbmZpZ0FycmF5ID0gYXdhaXQgd2luZG93LmhvbWVicmlkZ2UuZ2V0UGx1Z2luQ29uZmlnKCk7XG4gICAgaWYgKGNvbmZpZ0FycmF5WzBdID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMubG9nLndhcm4oJ05vIHBsdWdpbiBjb25maWd1cmF0aW9uIGZvdW5kOyBjcmVhdGluZyBhIG5ldyBvbmUnKTtcbiAgICAgIHRoaXMuc2F2ZWRDb25maWcgPSB7XG4gICAgICAgIHBsYXRmb3JtOiB3aW5kb3cuaG9tZWJyaWRnZS5wbHVnaW4uZGlzcGxheU5hbWVcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICgxIDwgY29uZmlnQXJyYXkubGVuZ3RoKSB7XG4gICAgICAgIHRoaXMubG9nLmVycm9yKGBVc2luZyB0aGUgZmlyc3Qgb2YgJHsoMCwgX3V0aWxzLnBsdXJhbCkoY29uZmlnQXJyYXkubGVuZ3RoLCAncGx1Z2luIGNvbmZpZ3VyYXRpb24nKX1gLCBjb25maWdBcnJheSk7XG4gICAgICAgIHdpbmRvdy5ob21lYnJpZGdlLnRvYXN0LmVycm9yKCdPbmx5IGEgc2luZ2xlIHBsYXRmb3JtIGluc3RhbmNlIGlzIHN1cHBvcnRlZDsgdXNpbmcgdGhlIGZpcnN0JywgJ011bHRpcGxlIENvbmZpZ3VyYXRpb24gQmxvY2tzJyk7XG4gICAgICB9XG4gICAgICB0aGlzLnNhdmVkQ29uZmlnID0gY29uZmlnQXJyYXlbMF07XG4gICAgICBhd2FpdCB0aGlzLmNoZWNrSWZNb2RpZmllZCh0aGlzLnNhdmVkQ29uZmlnKTtcbiAgICB9XG4gICAgLy8gVHJlYXQgYWxsIHVuZXhwZWN0ZWQgcHJvcGVydGllcyBhcyBhcHBsaWFuY2UgY29uZmlndXJhdGlvbnNcbiAgICBjb25zdCBrZXlvZkNvbmZpZ1BsdWdpbiA9ICgwLCBfdXRpbHMua2V5b2ZDaGVja2VyKShfY29uZmlnVHlwZXMudHlwZVN1aXRlLCBfY29uZmlnVHlwZXMudHlwZVN1aXRlLkNvbmZpZ1BsdWdpbik7XG4gICAgY29uc3Qgc2VsZWN0ID0gcHJlZGljYXRlID0+IE9iamVjdC5mcm9tRW50cmllcyhPYmplY3QuZW50cmllcyh0aGlzLnNhdmVkQ29uZmlnID8/IHt9KS5maWx0ZXIocHJlZGljYXRlKSk7XG4gICAgdGhpcy5nbG9iYWwgPSBzZWxlY3QoKFtrZXldKSA9PiBrZXlvZkNvbmZpZ1BsdWdpbi5pbmNsdWRlcyhrZXkpKTtcbiAgICB0aGlzLmFwcGxpYW5jZXMgPSBzZWxlY3QoKFtrZXldKSA9PiAha2V5b2ZDb25maWdQbHVnaW4uaW5jbHVkZXMoa2V5KSk7XG4gICAgdGhpcy5sb2cuZGVidWcoJ2dldENvbmZpZygpIGdsb2JhbCAlTyBhcHBsaWFuY2VzICVPJywgdGhpcy5nbG9iYWwsIHRoaXMuYXBwbGlhbmNlcyk7XG4gICAgYXdhaXQgdGhpcy5vbkdsb2JhbD8uKHRoaXMuZ2xvYmFsKTtcbiAgfVxuICAvLyBSZXRyaWV2ZSB0aGUgbW9zdCByZWNlbnRseSB1c2VkIGNvbmZpZ3VyYXRpb25cbiAgYXN5bmMgZ2V0QWN0aXZlQ29uZmlnKCkge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5pcGMucmVxdWVzdCgnL2NvbmZpZycsIG51bGwpO1xuICAgIH0gY2F0Y2gge1xuICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgfVxuICAvLyBVcGRhdGUgdGhlIGhvbWVicmlkZ2UtdWkteCBjb3B5IG9mIHRoZSBjb25maWd1cmF0aW9uXG4gIGFzeW5jIHB1dENvbmZpZyhzYXZlID0gZmFsc2UpIHtcbiAgICAvLyBDb25zdHJ1Y3QgdGhlIGZ1bGwgY29uZmlndXJhdGlvblxuICAgIGNvbnN0IGNvbmZpZyA9IHtcbiAgICAgIC4uLnRoaXMuZ2xvYmFsLFxuICAgICAgLi4udGhpcy5hcHBsaWFuY2VzXG4gICAgfTtcbiAgICB0aGlzLmxvZy5kZWJ1ZyhgcHV0Q29uZmlnKCR7c2F2ZX0pJ31gLCBjb25maWcpO1xuICAgIC8vIEluZm9ybSBob21lYnJpZGdlLXVpLXggb2YgdGhlIG5ldyBjb25maWd1cmF0aW9uXG4gICAgYXdhaXQgd2luZG93LmhvbWVicmlkZ2UudXBkYXRlUGx1Z2luQ29uZmlnKFtjb25maWddKTtcbiAgICBpZiAoc2F2ZSkge1xuICAgICAgYXdhaXQgd2luZG93LmhvbWVicmlkZ2Uuc2F2ZVBsdWdpbkNvbmZpZygpO1xuICAgICAgdGhpcy5zYXZlZENvbmZpZyA9IGNvbmZpZztcbiAgICAgIHRoaXMubG9nLmluZm8oJ1BsdWdpbiBjb25maWd1cmF0aW9uIHNhdmVkJyk7XG4gICAgfVxuICAgIC8vIENoZWNrIHdoZXRoZXIgdGhlIGNvbmZpZ3VyYXRpb24gbWF0Y2hlcyB0aGUgYWN0aXZlIHBsdWdpblxuICAgIGF3YWl0IHRoaXMuY2hlY2tJZk1vZGlmaWVkKGNvbmZpZyk7XG4gIH1cbiAgLy8gQ29tcGFyZSB0d28gY29uZmlndXJhdGlvbiBvYmplY3RzXG4gIGRpZmZPYmplY3QodG8sIGZyb20sIGtleVByZWZpeCA9ICcnKSB7XG4gICAgY29uc3Qga2V5cyA9IFsuLi5PYmplY3Qua2V5cyh0byksIC4uLk9iamVjdC5rZXlzKGZyb20pXS5maWx0ZXIoKGtleSwgaW5kZXgsIHNlbGYpID0+IGluZGV4ID09PSBzZWxmLmluZGV4T2Yoa2V5KSAmJiBrZXkgIT09ICdfYnJpZGdlJyk7XG4gICAgY29uc3QgZGlmZiA9IFtdO1xuICAgIGZvciAoY29uc3Qga2V5IG9mIGtleXMpIHtcbiAgICAgIGNvbnN0IHZhbHVlVG8gPSB0b1trZXldO1xuICAgICAgY29uc3QgdmFsdWVGcm9tID0gZnJvbVtrZXldO1xuICAgICAgY29uc3Qga2V5TmFtZSA9IGAke2tleVByZWZpeH0uJHtrZXl9YDtcbiAgICAgIGNvbnN0IGlzT2JqZWN0ID0gdmFsdWUgPT4gdmFsdWUgIT09IHVuZGVmaW5lZCAmJiB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnO1xuICAgICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWVUbykgJiYgQXJyYXkuaXNBcnJheSh2YWx1ZUZyb20pKSBkaWZmLnB1c2goLi4udGhpcy5kaWZmQXJyYXkodmFsdWVUbywgdmFsdWVGcm9tLCBrZXlOYW1lKSk7ZWxzZSBpZiAoaXNPYmplY3QodmFsdWVUbykgJiYgaXNPYmplY3QodmFsdWVGcm9tKSkgZGlmZi5wdXNoKC4uLnRoaXMuZGlmZk9iamVjdCh2YWx1ZVRvLCB2YWx1ZUZyb20sIGtleU5hbWUpKTtlbHNlIGlmICh2YWx1ZVRvICE9PSB2YWx1ZUZyb20pIGRpZmYucHVzaCh7XG4gICAgICAgIGtleToga2V5TmFtZSxcbiAgICAgICAgZnJvbTogdmFsdWVGcm9tLFxuICAgICAgICB0bzogdmFsdWVUb1xuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBkaWZmO1xuICB9XG4gIC8vIENvbXBhcmUgdHdvIGNvbmZpZ3VyYXRpb24gYXJyYXlzXG4gIGRpZmZBcnJheSh0bywgZnJvbSwga2V5UHJlZml4ID0gJycpIHtcbiAgICBjb25zdCBpc1NpbXBsZSA9IGFycmF5ID0+IGFycmF5Lmxlbmd0aCAhPT0gMCAmJiB0eXBlb2YgYXJyYXlbMF0gIT09ICdvYmplY3QnO1xuICAgIGlmIChpc1NpbXBsZSh0bykgfHwgaXNTaW1wbGUoZnJvbSkpIHtcbiAgICAgIGlmICh0by5sZW5ndGggPT09IGZyb20ubGVuZ3RoICYmIHRvLmV2ZXJ5KCh2YWx1ZSwgaW5kZXgpID0+IHZhbHVlID09PSBmcm9tW2luZGV4XSkpIHJldHVybiBbXTtlbHNlIHJldHVybiBbe1xuICAgICAgICBrZXk6IGtleVByZWZpeCxcbiAgICAgICAgZnJvbSxcbiAgICAgICAgdG9cbiAgICAgIH1dO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5kaWZmT2JqZWN0KHRvLCBmcm9tLCBrZXlQcmVmaXgpO1xuICAgIH1cbiAgfVxuICAvLyBDaGVjayB3aGV0aGVyIHRoZSBjb25maWd1cmF0aW9uIGhhcyBiZWVuIG1vZGlmaWVkXG4gIGFzeW5jIGNoZWNrSWZNb2RpZmllZChjb25maWcpIHtcbiAgICAvLyBJZ25vcmUgY29tcGxldGVseSBuZXcvZW1wdHkgY29uZmlndXJhdGlvblxuICAgIGlmICghT2JqZWN0LmtleXMoY29uZmlnKS5sZW5ndGgpIHJldHVybjtcbiAgICAvLyBDb21wYXJlIHRoZSBjb25maWd1cmF0aW9uIHRvIHRoZSBhY3RpdmUgcGx1Z2luIGFuZCBzYXZlZCB2ZXJzaW9uc1xuICAgIGNvbnN0IGFjdGl2ZUNvbmZpZyA9IGF3YWl0IHRoaXMuYWN0aXZlUHJvbWlzZTtcbiAgICBjb25zdCBhY3RpdmVEaWZmID0gdGhpcy5kaWZmT2JqZWN0KGNvbmZpZywgYWN0aXZlQ29uZmlnKTtcbiAgICBjb25zdCBzYXZlZERpZmYgPSB0aGlzLmRpZmZPYmplY3QoY29uZmlnLCB0aGlzLnNhdmVkQ29uZmlnID8/IHt9KTtcbiAgICBpZiAoYWN0aXZlRGlmZi5sZW5ndGggfHwgc2F2ZWREaWZmLmxlbmd0aCkge1xuICAgICAgdGhpcy5sb2cuZGVidWcoJ2NoZWNrSWZNb2RpZmllZCglTykgYWN0aXZlICVPIHNhdmVkICVPJywgY29uZmlnLCBhY3RpdmVEaWZmLCBzYXZlZERpZmYpO1xuICAgIH1cbiAgICAvLyBIaWRlIG9yIHNob3cgdGhlIHJlc3RhcnQgcmVxdWlyZWQgbWVzc2FnZVxuICAgIHRoaXMuc2hvd1Jlc3RhcnRSZXF1aXJlZChhY3RpdmVEaWZmLCAwIDwgc2F2ZWREaWZmLmxlbmd0aCk7XG4gIH1cbiAgLy8gU2hvdyBvciBoaWRlIHRoZSByZXN0YXJ0IHJlcXVpcmVkIG1lc3NhZ2VcbiAgc2hvd1Jlc3RhcnRSZXF1aXJlZChjaGFuZ2VzLCBpc1Vuc2F2ZWQpIHtcbiAgICAvLyBTaG93IHRoZSBtZXNzYWdlIGlmIHRoZXJlIGFyZSBhbnkgZGlmZmVyZW5jZXNcbiAgICAoMCwgX3V0aWxzRG9tLmdldEVsZW1lbnRCeUlkKSgnaGMtbW9kaWZpZWQnKS5oaWRkZW4gPSBjaGFuZ2VzLmxlbmd0aCA9PT0gMCAmJiAhaXNVbnNhdmVkO1xuICAgICgwLCBfdXRpbHNEb20uZ2V0RWxlbWVudEJ5SWQpKCdoYy1tb2RpZmllZC1zYXZlZCcpLmhpZGRlbiA9IGlzVW5zYXZlZDtcbiAgICAoMCwgX3V0aWxzRG9tLmdldEVsZW1lbnRCeUlkKSgnaGMtbW9kaWZpZWQtdW5zYXZlZCcpLmhpZGRlbiA9ICFpc1Vuc2F2ZWQ7XG4gICAgLy8gRGlzcGxheSB0aGUgZGlmZlxuICAgIGNvbnN0IGZvcm1hdFZhbHVlID0gdmFsdWUgPT4gSlNPTi5zdHJpbmdpZnkodmFsdWUsIG51bGwsIDQpO1xuICAgICgwLCBfdXRpbHNEb20uZ2V0RWxlbWVudEJ5SWQpKCdoYy1tb2RpZmllZC1kaWZmJykucmVwbGFjZUNoaWxkcmVuKC4uLmNoYW5nZXMubWFwKGNoYW5nZSA9PiAoMCwgX3V0aWxzRG9tLmNsb25lVGVtcGxhdGUpKCdoYy1tb2RpZmllZC1kaWZmLWRlbHRhJywge1xuICAgICAga2V5OiBjaGFuZ2Uua2V5LFxuICAgICAgZnJvbTogZm9ybWF0VmFsdWUoY2hhbmdlLmZyb20pLFxuICAgICAgdG86IGZvcm1hdFZhbHVlKGNoYW5nZS50bylcbiAgICB9KSkpO1xuICB9XG4gIC8vIEdldCB0aGUgY3VycmVudCBnbG9iYWwgY29uZmlndXJhdGlvblxuICBhc3luYyBnZXRHbG9iYWwoKSB7XG4gICAgYXdhaXQgdGhpcy5yZWFkeVByb21pc2U7XG4gICAgcmV0dXJuIHRoaXMuZ2xvYmFsO1xuICB9XG4gIC8vIFNldCB1cGRhdGVkIGdsb2JhbCBjb25maWd1cmF0aW9uXG4gIGFzeW5jIHNldEdsb2JhbChjb25maWcpIHtcbiAgICBpZiAodGhpcy5kaWZmT2JqZWN0KGNvbmZpZywgYXdhaXQgdGhpcy5nZXRHbG9iYWwoKSkubGVuZ3RoKSB7XG4gICAgICB0aGlzLmxvZy5kZWJ1Zygnc2V0R2xvYmFsKCVPKScsIGNvbmZpZyk7XG4gICAgICB0aGlzLmdsb2JhbCA9IGNvbmZpZztcbiAgICAgIGF3YWl0IHRoaXMub25HbG9iYWw/Lihjb25maWcpO1xuICAgICAgYXdhaXQgdGhpcy5wdXRDb25maWcoKTtcbiAgICB9XG4gIH1cbiAgLy8gR2V0IHRoZSBjdXJyZW50IGNvbmZpZ3VyYXRpb24gZm9yIGEgc3BlY2lmaWMgYXBwbGlhbmNlXG4gIGFzeW5jIGdldEFwcGxpYW5jZShoYWlkKSB7XG4gICAgYXdhaXQgdGhpcy5yZWFkeVByb21pc2U7XG4gICAgcmV0dXJuIHRoaXMuYXBwbGlhbmNlc1toYWlkXSA/PyB7fTtcbiAgfVxuICAvLyBTZXQgdXBkYXRlZCBnbG9iYWwgY29uZmlndXJhdGlvblxuICBhc3luYyBzZXRBcHBsaWFuY2UoaGFpZCwgY29uZmlnKSB7XG4gICAgLy8gUGF0Y2gtdXAgdGhlIHByb2dyYW1zIGxpc3QgYmFzZWQgb24gdGhlIGFkZHByb2dyYW1zIHNldHRpbmdcbiAgICBzd2l0Y2ggKGNvbmZpZy5hZGRwcm9ncmFtcykge1xuICAgICAgY2FzZSAnbm9uZSc6XG4gICAgICAgIGNvbmZpZy5wcm9ncmFtcyA9IFtdO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2F1dG8nOlxuICAgICAgICBjb25maWcucHJvZ3JhbXMgPSB1bmRlZmluZWQ7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgICAvLyBVcGRhdGUgdGhlIGFwcGxpYW5jZSBjb25maWd1cmF0aW9uIGlmIGl0IGhhcyBjaGFuZ2VkXG4gICAgaWYgKHRoaXMuZGlmZk9iamVjdChjb25maWcsIGF3YWl0IHRoaXMuZ2V0QXBwbGlhbmNlKGhhaWQpKS5sZW5ndGgpIHtcbiAgICAgIHRoaXMubG9nLmRlYnVnKGBzZXRBcHBsaWFuY2UoXCIke2hhaWR9XCIsICVPKWAsIGNvbmZpZyk7XG4gICAgICB0aGlzLmFwcGxpYW5jZXNbaGFpZF0gPSBjb25maWc7XG4gICAgICBhd2FpdCB0aGlzLnB1dENvbmZpZygpO1xuICAgIH1cbiAgfVxufVxuZXhwb3J0cy5Db25maWcgPSBDb25maWc7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldD11dGYtODtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnVZVzFsY3lJNld5SmZkWFJwYkhNaUxDSnlaWEYxYVhKbElpd2lYM1YwYVd4elJHOXRJaXdpWDJOdmJtWnBaMVI1Y0dWeklpd2lRMjl1Wm1sbklpd2lZMjl1YzNSeWRXTjBiM0lpTENKc2IyY2lMQ0pwY0dNaUxDSm5iRzlpWVd3aUxDSmhjSEJzYVdGdVkyVnpJaXdpY21WaFpIbFFjbTl0YVhObElpd2laMlYwUTI5dVptbG5JaXdpWVdOMGFYWmxVSEp2YldselpTSXNJbWRsZEVGamRHbDJaVU52Ym1acFp5SXNJbU52Ym1acFowRnljbUY1SWl3aWQybHVaRzkzSWl3aWFHOXRaV0p5YVdSblpTSXNJbWRsZEZCc2RXZHBia052Ym1acFp5SXNJblZ1WkdWbWFXNWxaQ0lzSW5kaGNtNGlMQ0p6WVhabFpFTnZibVpwWnlJc0luQnNZWFJtYjNKdElpd2ljR3gxWjJsdUlpd2laR2x6Y0d4aGVVNWhiV1VpTENKc1pXNW5kR2dpTENKbGNuSnZjaUlzSW5Cc2RYSmhiQ0lzSW5SdllYTjBJaXdpWTJobFkydEpaazF2WkdsbWFXVmtJaXdpYTJWNWIyWkRiMjVtYVdkUWJIVm5hVzRpTENKclpYbHZaa05vWldOclpYSWlMQ0owZVhCbFUzVnBkR1VpTENKRGIyNW1hV2RRYkhWbmFXNGlMQ0p6Wld4bFkzUWlMQ0p3Y21Wa2FXTmhkR1VpTENKUFltcGxZM1FpTENKbWNtOXRSVzUwY21sbGN5SXNJbVZ1ZEhKcFpYTWlMQ0ptYVd4MFpYSWlMQ0pyWlhraUxDSnBibU5zZFdSbGN5SXNJbVJsWW5Wbklpd2liMjVIYkc5aVlXd2lMQ0p5WlhGMVpYTjBJaXdpY0hWMFEyOXVabWxuSWl3aWMyRjJaU0lzSW1OdmJtWnBaeUlzSW5Wd1pHRjBaVkJzZFdkcGJrTnZibVpwWnlJc0luTmhkbVZRYkhWbmFXNURiMjVtYVdjaUxDSnBibVp2SWl3aVpHbG1aazlpYW1WamRDSXNJblJ2SWl3aVpuSnZiU0lzSW10bGVWQnlaV1pwZUNJc0ltdGxlWE1pTENKcGJtUmxlQ0lzSW5ObGJHWWlMQ0pwYm1SbGVFOW1JaXdpWkdsbVppSXNJblpoYkhWbFZHOGlMQ0oyWVd4MVpVWnliMjBpTENKclpYbE9ZVzFsSWl3aWFYTlBZbXBsWTNRaUxDSjJZV3gxWlNJc0lrRnljbUY1SWl3aWFYTkJjbkpoZVNJc0luQjFjMmdpTENKa2FXWm1RWEp5WVhraUxDSnBjMU5wYlhCc1pTSXNJbUZ5Y21GNUlpd2laWFpsY25raUxDSmhZM1JwZG1WRGIyNW1hV2NpTENKaFkzUnBkbVZFYVdabUlpd2ljMkYyWldSRWFXWm1JaXdpYzJodmQxSmxjM1JoY25SU1pYRjFhWEpsWkNJc0ltTm9ZVzVuWlhNaUxDSnBjMVZ1YzJGMlpXUWlMQ0puWlhSRmJHVnRaVzUwUW5sSlpDSXNJbWhwWkdSbGJpSXNJbVp2Y20xaGRGWmhiSFZsSWl3aVNsTlBUaUlzSW5OMGNtbHVaMmxtZVNJc0luSmxjR3hoWTJWRGFHbHNaSEpsYmlJc0ltMWhjQ0lzSW1Ob1lXNW5aU0lzSW1Oc2IyNWxWR1Z0Y0d4aGRHVWlMQ0puWlhSSGJHOWlZV3dpTENKelpYUkhiRzlpWVd3aUxDSm5aWFJCY0hCc2FXRnVZMlVpTENKb1lXbGtJaXdpYzJWMFFYQndiR2xoYm1ObElpd2lZV1JrY0hKdlozSmhiWE1pTENKd2NtOW5jbUZ0Y3lJc0ltVjRjRzl5ZEhNaVhTd2ljMjkxY21ObGN5STZXeUl1TGk4dUxpOHVMaTl6Y21NdmFHOXRaV0p5YVdSblpTMTFhUzl3ZFdKc2FXTXZZMjl1Wm1sbkxuUnpJbDBzSW5OdmRYSmpaWE5EYjI1MFpXNTBJanBiYm5Wc2JGMHNJbTFoY0hCcGJtZHpJam9pT3pzN096czdRVUZQUVN4SlFVRkJRU3hOUVVGQkxFZEJRVUZETEU5QlFVRTdRVUZGUVN4SlFVRkJReXhUUVVGQkxFZEJRVUZFTEU5QlFVRTdRVUZEUVN4SlFVRkJSU3haUVVGQkxFZEJRVUZHTEU5QlFVRTdRVUZXUVR0QlFVTkJPenRCUVd0Q1FUdEJRVU5OTEUxQlFVOUhMRTFCUVUwN1JVRmpaanRGUVVOQlF5eFpRVUZ4UWtNc1IwRkJWeXhGUVVOWVF5eEhRVUZqTzBsQlJHUXNTMEZCUVVRc1IwRkJSeXhIUVVGSVFTeEhRVUZITzBsQlEwZ3NTMEZCUVVNc1IwRkJSeXhIUVVGSVFTeEhRVUZITzBsQldIaENPMGxCUTBFc1MwRkJRVU1zVFVGQlRTeEhRVUZyUXl4RlFVRkZPMGxCUXpGRExFdEJRVUZETEZWQlFWVXNSMEZCZVVJc1JVRkJSVHRKUVZWcVF5eEpRVUZKTEVOQlFVTkRMRmxCUVZrc1IwRkJTU3hKUVVGSkxFTkJRVU5ETEZOQlFWTXNSVUZCUlR0SlFVTnlReXhKUVVGSkxFTkJRVU5ETEdGQlFXRXNSMEZCUnl4SlFVRkpMRU5CUVVORExHVkJRV1VzUlVGQlJUdEZRVU12UXp0RlFVVkJPMFZCUTBFc1RVRkJUVVlzVTBGQlUwRXNRMEZCUVR0SlFVTllPMGxCUTBFc1RVRkJUVWNzVjBGQlZ5eEhRVUZITEUxQlFVMURMRTFCUVUwc1EwRkJRME1zVlVGQlZTeERRVUZEUXl4bFFVRmxMRVZCUVVVN1NVRkROMFFzU1VGQlNVZ3NWMEZCVnl4RFFVRkRMRU5CUVVNc1EwRkJReXhMUVVGTFNTeFRRVUZUTEVWQlFVVTdUVUZET1VJc1NVRkJTU3hEUVVGRFdpeEhRVUZITEVOQlFVTmhMRWxCUVVrc1EwRkJReXh0UkVGQmJVUXNRMEZCUXp0TlFVTnNSU3hKUVVGSkxFTkJRVU5ETEZkQlFWY3NSMEZCUnp0UlFVRkZReXhSUVVGUkxFVkJRVVZPTEUxQlFVMHNRMEZCUTBNc1ZVRkJWU3hEUVVGRFRTeE5RVUZOTEVOQlFVTkRPMDFCUVZjc1EwRkJSVHRKUVVONlJTeERRVUZETEUxQlFVMDdUVUZEU0N4SlFVRkpMRU5CUVVNc1IwRkJSMVFzVjBGQlZ5eERRVUZEVlN4TlFVRk5MRVZCUVVVN1VVRkRlRUlzU1VGQlNTeERRVUZEYkVJc1IwRkJSeXhEUVVGRGJVSXNTMEZCU3l4RFFVRkRMSE5DUVVGelFpeEpRVUZCUXl4aFFVRk5MRVZCUVVOYUxGZEJRVmNzUTBGQlExVXNUVUZCVFN4RlFVRkZMSE5DUVVGelFpeERRVUZETEVWQlFVVXNSVUZCUlZZc1YwRkJWeXhEUVVGRE8xRkJRM1pIUXl4TlFVRk5MRU5CUVVORExGVkJRVlVzUTBGQlExY3NTMEZCU3l4RFFVRkRSaXhMUVVGTExFTkJRVU1zSzBSQlFTdEVMRVZCUXk5RUxDdENRVUVyUWl4RFFVRkRPMDFCUTJ4Rk8wMUJRMEVzU1VGQlNTeERRVUZEVEN4WFFVRlhMRWRCUVVkT0xGZEJRVmNzUTBGQlF5eERRVUZETEVOQlFVTTdUVUZEYWtNc1RVRkJUU3hKUVVGSkxFTkJRVU5qTEdWQlFXVXNRMEZCUXl4SlFVRkpMRU5CUVVOU0xGZEJRVmNzUTBGQlF6dEpRVU5vUkR0SlFVVkJPMGxCUTBFc1RVRkJUVk1zYVVKQlFXbENMRWRCUVVjc1NVRkJRVU1zYlVKQlFWa3NSVUZCUTBNc2MwSkJRVk1zUlVGQlJVRXNjMEpCUVZNc1EwRkJRME1zV1VGQldTeERRVUZETzBsQlEzcEZMRTFCUVUxRExFMUJRVTBzUjBGQlNVTXNVMEZCZFVRc1NVRkRia1ZETEUxQlFVMHNRMEZCUTBNc1YwRkJWeXhEUVVGRFJDeE5RVUZOTEVOQlFVTkZMRTlCUVU4c1EwRkJReXhKUVVGSkxFTkJRVU5xUWl4WFFVRlhMRWxCUVVrc1JVRkJSU3hEUVVGRExFTkJRVU5yUWl4TlFVRk5MRU5CUVVOS0xGTkJRVk1zUTBGQlF5eERRVUZETzBsQlEyaEdMRWxCUVVrc1EwRkJRekZDTEUxQlFVMHNSMEZCVDNsQ0xFMUJRVTBzUTBGQlF5eERRVUZETEVOQlFVTk5MRWRCUVVjc1EwRkJReXhMUVVGTlZpeHBRa0ZCYVVJc1EwRkJRMWNzVVVGQlVTeERRVUZEUkN4SFFVRkhMRU5CUVVNc1EwRkJRenRKUVVOeVJTeEpRVUZKTEVOQlFVTTVRaXhWUVVGVkxFZEJRVWQzUWl4TlFVRk5MRU5CUVVNc1EwRkJReXhEUVVGRFRTeEhRVUZITEVOQlFVTXNTMEZCU3l4RFFVRkRWaXhwUWtGQmFVSXNRMEZCUTFjc1VVRkJVU3hEUVVGRFJDeEhRVUZITEVOQlFVTXNRMEZCY1VJN1NVRkRla1lzU1VGQlNTeERRVUZEYWtNc1IwRkJSeXhEUVVGRGJVTXNTMEZCU3l4RFFVRkRMSEZEUVVGeFF5eEZRVUZGTEVsQlFVa3NRMEZCUTJwRExFMUJRVTBzUlVGQlJTeEpRVUZKTEVOQlFVTkRMRlZCUVZVc1EwRkJRenRKUVVOdVJpeE5RVUZOTEVsQlFVa3NRMEZCUTJsRExGRkJRVkVzUjBGQlJ5eEpRVUZKTEVOQlFVTnNReXhOUVVGTkxFTkJRVU03UlVGRGRFTTdSVUZGUVR0RlFVTkJMRTFCUVUxTExHVkJRV1ZCTEVOQlFVRTdTVUZEYWtJc1NVRkJTVHROUVVOQkxFOUJRVThzVFVGQlRTeEpRVUZKTEVOQlFVTk9MRWRCUVVjc1EwRkJRMjlETEU5QlFVOHNRMEZCUXl4VFFVRlRMRVZCUVVVc1NVRkJTU3hEUVVGRE8wbEJRMnhFTEVOQlFVTXNRMEZCUXl4TlFVRk5PMDFCUTBvc1QwRkJUeXhGUVVGdlFqdEpRVU12UWp0RlFVTktPMFZCUlVFN1JVRkRRU3hOUVVGTlF5eFRRVUZUUVN4RFFVRkRReXhKUVVGSkxFZEJRVWNzUzBGQlN6dEpRVU40UWp0SlFVTkJMRTFCUVUxRExFMUJRVTBzUjBGQlJ6dE5RVUZGTEVkQlFVY3NTVUZCU1N4RFFVRkRkRU1zVFVGQlRUdE5RVUZGTEVkQlFVY3NTVUZCU1N4RFFVRkRRenRKUVVGVkxFTkJRVVU3U1VGRGNrUXNTVUZCU1N4RFFVRkRTQ3hIUVVGSExFTkJRVU50UXl4TFFVRkxMRU5CUVVNc1lVRkJZVWtzU1VGQlNTeExRVUZMTEVWQlFVVkRMRTFCUVUwc1EwRkJRenRKUVVVNVF6dEpRVU5CTEUxQlFVMHZRaXhOUVVGTkxFTkJRVU5ETEZWQlFWVXNRMEZCUXl0Q0xHdENRVUZyUWl4RFFVRkRMRU5CUVVORUxFMUJRVTBzUTBGQlF5eERRVUZETzBsQlEzQkVMRWxCUVVsRUxFbEJRVWtzUlVGQlJUdE5RVU5PTEUxQlFVMDVRaXhOUVVGTkxFTkJRVU5ETEZWQlFWVXNRMEZCUTJkRExHZENRVUZuUWl4RlFVRkZPMDFCUXpGRExFbEJRVWtzUTBGQlF6VkNMRmRCUVZjc1IwRkJSekJDTEUxQlFVMDdUVUZEZWtJc1NVRkJTU3hEUVVGRGVFTXNSMEZCUnl4RFFVRkRNa01zU1VGQlNTeERRVUZETERSQ1FVRTBRaXhEUVVGRE8wbEJReTlETzBsQlJVRTdTVUZEUVN4TlFVRk5MRWxCUVVrc1EwRkJRM0pDTEdWQlFXVXNRMEZCUTJ0Q0xFMUJRVTBzUTBGQlF6dEZRVU4wUXp0RlFVVkJPMFZCUTBGSkxGVkJRVlZCTEVOQlFVTkRMRVZCUVZVc1JVRkJSVU1zU1VGQldTeEZRVUZGUXl4VFFVRlRMRWRCUVVjc1JVRkJSVHRKUVVNdlF5eE5RVUZOUXl4SlFVRkpMRWRCUVVjc1EwRkJReXhIUVVGSGJrSXNUVUZCVFN4RFFVRkRiVUlzU1VGQlNTeERRVUZEU0N4RlFVRkZMRU5CUVVNc1JVRkJSU3hIUVVGSGFFSXNUVUZCVFN4RFFVRkRiVUlzU1VGQlNTeERRVUZEUml4SlFVRkpMRU5CUVVNc1EwRkJReXhEUVVOc1JHUXNUVUZCVFN4RFFVRkRMRU5CUVVORExFZEJRVWNzUlVGQlJXZENMRXRCUVVzc1JVRkJSVU1zU1VGQlNTeExRVUZMUkN4TFFVRkxMRXRCUVV0RExFbEJRVWtzUTBGQlEwTXNUMEZCVHl4RFFVRkRiRUlzUjBGQlJ5eERRVUZETEVsQlFVbEJMRWRCUVVjc1MwRkJTeXhUUVVGVExFTkJRVU03U1VGRGJrWXNUVUZCVFcxQ0xFbEJRVWtzUjBGQmEwSXNSVUZCUlR0SlFVTTVRaXhMUVVGTExFMUJRVTF1UWl4SFFVRkhMRWxCUVVsbExFbEJRVWtzUlVGQlJUdE5RVU53UWl4TlFVRk5TeXhQUVVGUExFZEJRVXRTTEVWQlFVVXNRMEZCUjFvc1IwRkJXU3hEUVVGRE8wMUJRM0JETEUxQlFVMXhRaXhUUVVGVExFZEJRVWRTTEVsQlFVa3NRMEZCUTJJc1IwRkJXU3hEUVVGRE8wMUJRM0JETEUxQlFVMXpRaXhQUVVGUExFZEJRVWNzUjBGQlIxSXNVMEZCVXl4SlFVRkpaQ3hIUVVGSExFVkJRVVU3VFVGRGNrTXNUVUZCVFhWQ0xGRkJRVkVzUjBGQlNVTXNTMEZCWXl4SlFVRmpRU3hMUVVGTExFdEJRVXMzUXl4VFFVRlRMRWxCUVVrc1QwRkJUelpETEV0QlFVc3NTMEZCU3l4UlFVRlJPMDFCUXpsR0xFbEJRVWxETEV0QlFVc3NRMEZCUTBNc1QwRkJUeXhEUVVGRFRpeFBRVUZQTEVOQlFVTXNTVUZCU1Vzc1MwRkJTeXhEUVVGRFF5eFBRVUZQTEVOQlFVTk1MRk5CUVZNc1EwRkJReXhGUVVGRlJpeEpRVUZKTEVOQlFVTlJMRWxCUVVrc1EwRkJReXhIUVVGSExFbEJRVWtzUTBGQlEwTXNVMEZCVXl4RFFVRkZVaXhQUVVGUExFVkJRVVZETEZOQlFWTXNSVUZCUlVNc1QwRkJUeXhEUVVGRExFTkJRVU1zUTBGQlF5eExRVU01Unl4SlFVRkpReXhSUVVGUkxFTkJRVU5JTEU5QlFVOHNRMEZCUXl4SlFVRkpSeXhSUVVGUkxFTkJRVU5HTEZOQlFWTXNRMEZCUXl4RlFVRlBSaXhKUVVGSkxFTkJRVU5STEVsQlFVa3NRMEZCUXl4SFFVRkhMRWxCUVVrc1EwRkJRMmhDTEZWQlFWVXNRMEZCUTFNc1QwRkJUeXhGUVVGRlF5eFRRVUZUTEVWQlFVVkRMRTlCUVU4c1EwRkJReXhEUVVGRExFTkJRVU1zUzBGRE9VY3NTVUZCU1VZc1QwRkJUeXhMUVVGTFF5eFRRVUZUTEVWQlFVVkdMRWxCUVVrc1EwRkJRMUVzU1VGQlNTeERRVUZETzFGQlFVVXpRaXhIUVVGSExFVkJRVVZ6UWl4UFFVRlBPMUZCUVVWVUxFbEJRVWtzUlVGQlJWRXNVMEZCVXp0UlFVRkZWQ3hGUVVGRkxFVkJRVVZSTzAxQlFVOHNRMEZCUlN4RFFVRkRPMGxCUXpkR08wbEJRMEVzVDBGQlQwUXNTVUZCU1R0RlFVTm1PMFZCUlVFN1JVRkRRVk1zVTBGQlUwRXNRMEZCUTJoQ0xFVkJRV0VzUlVGQlJVTXNTVUZCWlN4RlFVRkZReXhUUVVGVExFZEJRVWNzUlVGQlJUdEpRVU53UkN4TlFVRk5aU3hSUVVGUkxFZEJRVWxETEV0QlFXZENMRWxCUVdOQkxFdEJRVXNzUTBGQlF6ZERMRTFCUVUwc1MwRkJTeXhEUVVGRExFbEJRVWtzVDBGQlR6WkRMRXRCUVVzc1EwRkJReXhEUVVGRExFTkJRVU1zUzBGQlN5eFJRVUZSTzBsQlEyeEhMRWxCUVVsRUxGRkJRVkVzUTBGQlEycENMRVZCUVVVc1EwRkJReXhKUVVGSmFVSXNVVUZCVVN4RFFVRkRhRUlzU1VGQlNTeERRVUZETEVWQlFVVTdUVUZEYUVNc1NVRkJTVVFzUlVGQlJTeERRVUZETTBJc1RVRkJUU3hMUVVGTE5FSXNTVUZCU1N4RFFVRkROVUlzVFVGQlRTeEpRVUZKTWtJc1JVRkJSU3hEUVVGRGJVSXNTMEZCU3l4RFFVRkRMRU5CUVVOUUxFdEJRVXNzUlVGQlJWSXNTMEZCU3l4TFFVRkxVU3hMUVVGTExFdEJRVXRZTEVsQlFVa3NRMEZCUTBjc1MwRkJTeXhEUVVGRExFTkJRVU1zUlVGQlJTeFBRVUZQTEVWQlFVVXNRMEZCUXl4TFFVTjZSaXhQUVVGUExFTkJRVU03VVVGQlJXaENMRWRCUVVjc1JVRkJSV01zVTBGQlV6dFJRVUZGUkN4SlFVRkpPMUZCUVVWRU8wMUJRVVVzUTBGQlJTeERRVUZETzBsQlF6bERMRU5CUVVNc1RVRkJUVHROUVVOSUxFOUJRVThzU1VGQlNTeERRVUZEUkN4VlFVRlZMRU5CUVVORExFVkJRVVVzUlVGQlJVTXNTVUZCU1N4RlFVRkZReXhUUVVGVExFTkJRVU03U1VGREwwTTdSVUZEU2p0RlFVVkJPMFZCUTBFc1RVRkJUWHBDTEdWQlFXVkJMRU5CUVVOclFpeE5RVUZ2UWp0SlFVTjBRenRKUVVOQkxFbEJRVWtzUTBGQlExZ3NUVUZCVFN4RFFVRkRiVUlzU1VGQlNTeERRVUZEVWl4TlFVRk5MRU5CUVVNc1EwRkJRM1JDTEUxQlFVMHNSVUZCUlR0SlFVVnFRenRKUVVOQkxFMUJRVTByUXl4WlFVRlpMRWRCUVVjc1RVRkJUU3hKUVVGSkxFTkJRVU16UkN4aFFVRmhPMGxCUXpkRExFMUJRVTAwUkN4VlFVRlZMRWRCUVVjc1NVRkJTU3hEUVVGRGRFSXNWVUZCVlN4RFFVRkRTaXhOUVVGTkxFVkJRVVY1UWl4WlFVRlpMRU5CUVVNN1NVRkRlRVFzVFVGQlRVVXNVMEZCVXl4SFFVRkhMRWxCUVVrc1EwRkJRM1pDTEZWQlFWVXNRMEZCUTBvc1RVRkJUU3hGUVVGRkxFbEJRVWtzUTBGQlF6RkNMRmRCUVZjc1NVRkJTU3hGUVVGRkxFTkJRVU03U1VGRGFrVXNTVUZCU1c5RUxGVkJRVlVzUTBGQlEyaEVMRTFCUVUwc1NVRkJTV2xFTEZOQlFWTXNRMEZCUTJwRUxFMUJRVTBzUlVGQlJUdE5RVU4yUXl4SlFVRkpMRU5CUVVOc1FpeEhRVUZITEVOQlFVTnRReXhMUVVGTExFTkJRVU1zZDBOQlFYZERMRVZCUVVWTExFMUJRVTBzUlVGQlJUQkNMRlZCUVZVc1JVRkJSVU1zVTBGQlV5eERRVUZETzBsQlF6TkdPMGxCUlVFN1NVRkRRU3hKUVVGSkxFTkJRVU5ETEcxQ1FVRnRRaXhEUVVGRFJpeFZRVUZWTEVWQlFVVXNRMEZCUXl4SFFVRkhReXhUUVVGVExFTkJRVU5xUkN4TlFVRk5MRU5CUVVNN1JVRkRPVVE3UlVGRlFUdEZRVU5CYTBRc2JVSkJRVzFDUVN4RFFVRkRReXhQUVVGeFFpeEZRVUZGUXl4VFFVRnJRanRKUVVONlJEdEpRVU5CTEVsQlFVRkRMSGRDUVVGakxFVkJRVU1zWVVGQllTeERRVUZETEVOQlFVTkRMRTFCUVUwc1IwRkJSMGdzVDBGQlR5eERRVUZEYmtRc1RVRkJUU3hMUVVGTExFTkJRVU1zU1VGQlNTeERRVUZEYjBRc1UwRkJVenRKUVVONlJTeEpRVUZCUXl4M1FrRkJZeXhGUVVGRExHMUNRVUZ0UWl4RFFVRkRMRU5CUVVkRExFMUJRVTBzUjBGQlIwWXNVMEZCVXp0SlFVTjRSQ3hKUVVGQlF5eDNRa0ZCWXl4RlFVRkRMSEZDUVVGeFFpeERRVUZETEVOQlFVTkRMRTFCUVUwc1IwRkJSeXhEUVVGRFJpeFRRVUZUTzBsQlJYcEVPMGxCUTBFc1RVRkJUVWNzVjBGQlZ5eEhRVUZKYUVJc1MwRkJZeXhKUVVGaGFVSXNTVUZCU1N4RFFVRkRReXhUUVVGVExFTkJRVU5zUWl4TFFVRkxMRVZCUVVVc1NVRkJTU3hGUVVGRkxFTkJRVU1zUTBGQlF6dEpRVU01UlN4SlFVRkJZeXgzUWtGQll5eEZRVUZETEd0Q1FVRnJRaXhEUVVGRExFTkJRVU5MTEdWQlFXVXNRMEZCUXl4SFFVRkhVQ3hQUVVGUExFTkJRVU5STEVkQlFVY3NRMEZCUTBNc1RVRkJUU3hKUVVOd1JTeEpRVUZCUXl4MVFrRkJZU3hGUVVGRExIZENRVUYzUWl4RlFVRkZPMDFCUTNCRE9VTXNSMEZCUnl4RlFVRkxOa01zVFVGQlRTeERRVUZETjBNc1IwRkJSenROUVVOc1FtRXNTVUZCU1N4RlFVRkpNa0lzVjBGQlZ5eERRVUZEU3l4TlFVRk5MRU5CUVVOb1F5eEpRVUZKTEVOQlFVTTdUVUZEYUVORUxFVkJRVVVzUlVGQlRUUkNMRmRCUVZjc1EwRkJRMHNzVFVGQlRTeERRVUZEYWtNc1JVRkJSVHRMUVVOb1F5eERRVUZETEVOQlFVTXNRMEZCUXp0RlFVTmFPMFZCUlVFN1JVRkRRU3hOUVVGTmJVTXNVMEZCVTBFc1EwRkJRVHRKUVVOWUxFMUJRVTBzU1VGQlNTeERRVUZETlVVc1dVRkJXVHRKUVVOMlFpeFBRVUZQTEVsQlFVa3NRMEZCUTBZc1RVRkJUVHRGUVVOMFFqdEZRVVZCTzBWQlEwRXNUVUZCVFN0RkxGTkJRVk5CTEVOQlFVTjZReXhOUVVGdlFqdEpRVU5vUXl4SlFVRkpMRWxCUVVrc1EwRkJRMGtzVlVGQlZTeERRVUZEU2l4TlFVRk5MRVZCUVVVc1RVRkJUU3hKUVVGSkxFTkJRVU4zUXl4VFFVRlRMRVZCUVVVc1EwRkJReXhEUVVGRE9VUXNUVUZCVFN4RlFVRkZPMDFCUTNoRUxFbEJRVWtzUTBGQlEyeENMRWRCUVVjc1EwRkJRMjFETEV0QlFVc3NRMEZCUXl4bFFVRmxMRVZCUVVWTExFMUJRVTBzUTBGQlF6dE5RVU4yUXl4SlFVRkpMRU5CUVVOMFF5eE5RVUZOTEVkQlFVZHpReXhOUVVGTk8wMUJRM0JDTEUxQlFVMHNTVUZCU1N4RFFVRkRTaXhSUVVGUkxFZEJRVWRKTEUxQlFVMHNRMEZCUXp0TlFVTTNRaXhOUVVGTkxFbEJRVWtzUTBGQlEwWXNVMEZCVXl4RlFVRkZPMGxCUXpGQ08wVkJRMG83UlVGRlFUdEZRVU5CTEUxQlFVMDBReXhaUVVGWlFTeERRVUZEUXl4SlFVRlpPMGxCUXpOQ0xFMUJRVTBzU1VGQlNTeERRVUZETDBVc1dVRkJXVHRKUVVOMlFpeFBRVUZQTEVsQlFVa3NRMEZCUTBRc1ZVRkJWU3hEUVVGRFowWXNTVUZCU1N4RFFVRkRMRWxCUVVrc1JVRkJSVHRGUVVOMFF6dEZRVVZCTzBWQlEwRXNUVUZCVFVNc1dVRkJXVUVzUTBGQlEwUXNTVUZCV1N4RlFVRkZNME1zVFVGQmRVSTdTVUZEY0VRN1NVRkRRU3hSUVVGUlFTeE5RVUZOTEVOQlFVTTJReXhYUVVGWE8wMUJRekZDTEV0QlFVc3NUVUZCVFR0UlFVRkZOME1zVFVGQlRTeERRVUZET0VNc1VVRkJVU3hIUVVGSExFVkJRVVU3VVVGQlZ6dE5RVU0xUXl4TFFVRkxMRTFCUVUwN1VVRkJSVGxETEUxQlFVMHNRMEZCUXpoRExGRkJRVkVzUjBGQlJ6RkZMRk5CUVZNN1VVRkJTVHRKUVVNMVF6dEpRVVZCTzBsQlEwRXNTVUZCU1N4SlFVRkpMRU5CUVVOblF5eFZRVUZWTEVOQlFVTktMRTFCUVUwc1JVRkJSU3hOUVVGTkxFbEJRVWtzUTBGQlF6QkRMRmxCUVZrc1EwRkJRME1zU1VGQlNTeERRVUZETEVOQlFVTXNRMEZCUTJwRkxFMUJRVTBzUlVGQlJUdE5RVU12UkN4SlFVRkpMRU5CUVVOc1FpeEhRVUZITEVOQlFVTnRReXhMUVVGTExFTkJRVU1zYVVKQlFXbENaMFFzU1VGQlNTeFJRVUZSTEVWQlFVVXpReXhOUVVGTkxFTkJRVU03VFVGRGNrUXNTVUZCU1N4RFFVRkRja01zVlVGQlZTeERRVUZEWjBZc1NVRkJTU3hEUVVGRExFZEJRVWN6UXl4TlFVRk5PMDFCUXpsQ0xFMUJRVTBzU1VGQlNTeERRVUZEUml4VFFVRlRMRVZCUVVVN1NVRkRNVUk3UlVGRFNqczdRVUZEU0dsRUxFOUJRVUVzUTBGQlFYcEdMRTFCUVVFc1IwRkJRVUVzVFVGQlFTSXNJbWxuYm05eVpVeHBjM1FpT2x0ZGZRPT0iLCJcInVzZSBzdHJpY3RcIjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuVGVtcGxhdGVGb3JtID0gZXhwb3J0cy5HbG9iYWxGb3JtID0gZXhwb3J0cy5Gb3JtcyA9IGV4cG9ydHMuRm9ybUlkID0gZXhwb3J0cy5Gb3JtID0gZXhwb3J0cy5BcHBsaWFuY2VGb3JtID0gdm9pZCAwO1xudmFyIF91dGlsc0RvbSA9IHJlcXVpcmUoXCIuL3V0aWxzLWRvbS5qc1wiKTtcbnZhciBfbG9nRXJyb3IgPSByZXF1aXJlKFwiLi4vLi4vbG9nLWVycm9yLmpzXCIpO1xuLy8gSG9tZWJyaWRnZSBwbHVnaW4gZm9yIEhvbWUgQ29ubmVjdCBob21lIGFwcGxpYW5jZXNcbi8vIENvcHlyaWdodCDCqSAyMDIzLTIwMjYgQWxleGFuZGVyIFRob3VreWRpZGVzXG5cbi8vIEEgY29uZmlndXJhdGlvbiBmb3JtIGhhbmRsZXJcbmNsYXNzIEZvcm0ge1xuICAvLyBDcmVhdGUgYSBjb25maWd1cmF0aW9uIGZvcm1cbiAgY29uc3RydWN0b3IobG9nKSB7XG4gICAgdGhpcy5sb2cgPSBsb2c7XG4gIH1cbiAgLy8gUmV0cmlldmUgYW5kIGRpc3BsYXkgdGhlIGZvcm1cbiAgYXN5bmMgY3JlYXRlRm9ybSgpIHtcbiAgICAvLyBSZXRyaWV2ZSB0aGUgZm9ybSBzY2hlbWEgYW5kIGRhdGFcbiAgICBjb25zdCBzY2hlbWEgPSBhd2FpdCB0aGlzLmdldFNjaGVtYSgpO1xuICAgIGNvbnN0IGRhdGEgPSBhd2FpdCB0aGlzLmdldERhdGEoKTtcbiAgICAvLyBDcmVhdGUgdGhlIGZvcm0gKGFkZGluZyBoZWFkZXIgYW5kIGZvb3RlcilcbiAgICBjb25zdCBwYXRjaGVkU2NoZW1hID0gdGhpcy5wYXRjaFNjaGVtYShzY2hlbWEpO1xuICAgIHRoaXMubG9nLmRlYnVnKCdjcmVhdGVGb3JtJywgcGF0Y2hlZFNjaGVtYSwgZGF0YSk7XG4gICAgdGhpcy5mb3JtID0gd2luZG93LmhvbWVicmlkZ2UuY3JlYXRlRm9ybShwYXRjaGVkU2NoZW1hLCBkYXRhKTtcbiAgICAvLyBSZXR1cm4gYW55IGNoYW5nZXMgdG8gdGhlIGNvbmZpZ3VyYXRpb25cbiAgICB0aGlzLmZvcm0ub25DaGFuZ2UoY29uZmlnID0+IHRoaXMucHV0RGF0YShjb25maWcpKTtcbiAgfVxuICAvLyBIaWRlIHRoZSBmb3JtIChpbXBsaWNpdGx5IGNhbGxlZCBpZiBhIGRpZmZlcmVudCBmb3JtIGlzIGNyZWF0ZWQpXG4gIGRlc3Ryb3lGb3JtKCkge1xuICAgIHRoaXMuZm9ybT8uZW5kKCk7XG4gICAgdGhpcy5mb3JtID0gdW5kZWZpbmVkO1xuICB9XG4gIC8vIEFkZCBhIGhlYWRlciBhbmQgZm9vdGVyIHRvIHRoZSBzY2hlbWEgZm9ybVxuICBwYXRjaFNjaGVtYShzY2hlbWEpIHtcbiAgICBjb25zdCBmb3JtID0gWy4uLihzY2hlbWEuZm9ybSA/PyBbXSksIC4uLnRoaXMuZm9ybUZyb21UZW1wbGF0ZSgnaGMtZm9ybS1mb290ZXInKV07XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLnNjaGVtYSxcbiAgICAgIGZvcm1cbiAgICB9O1xuICB9XG4gIC8vIENyZWF0ZSBhIGZvcm0gaXRlbSBmcm9tIGEgdGVtcGxhdGVcbiAgZm9ybUZyb21UZW1wbGF0ZSguLi5hcmdzKSB7XG4gICAgY29uc3QgdGVtcGxhdGUgPSAoMCwgX3V0aWxzRG9tLmNsb25lVGVtcGxhdGUpKC4uLmFyZ3MpO1xuICAgIGNvbnN0IGFic1RlbXBsYXRlID0gKDAsIF91dGlsc0RvbS5lbGVtZW50V2l0aEFic29sdXRlUGF0aHMpKHRlbXBsYXRlKTtcbiAgICByZXR1cm4gdGhpcy5mb3JtRnJvbUhUTUwoYWJzVGVtcGxhdGUpO1xuICB9XG4gIC8vIENyZWF0ZSBhIGZvcm0gaXRlbSBmcm9tIGFuIEhUTUwgZWxlbWVudFxuICBmb3JtRnJvbUhUTUwoZWxlbWVudCkge1xuICAgIHJldHVybiBbe1xuICAgICAgdHlwZTogJ2hlbHAnLFxuICAgICAgaGVscHZhbHVlOiAoMCwgX3V0aWxzRG9tLmdldEhUTUwpKGVsZW1lbnQpXG4gICAgfV07XG4gIH1cbn1cbi8vIEEgZ2xvYmFsIGNvbmZpZ3VyYXRpb24gZm9ybSBoYW5kbGVyXG5leHBvcnRzLkZvcm0gPSBGb3JtO1xuY2xhc3MgR2xvYmFsRm9ybSBleHRlbmRzIEZvcm0ge1xuICBjb25zdHJ1Y3Rvcihsb2csIGlwYywgY29uZmlnKSB7XG4gICAgc3VwZXIobG9nKTtcbiAgICB0aGlzLmlwYyA9IGlwYztcbiAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZztcbiAgfVxuICBnZXRTY2hlbWEoKSB7XG4gICAgcmV0dXJuIHRoaXMuaXBjLnJlcXVlc3QoJy9zY2hlbWEvZ2xvYmFsJywgbnVsbCk7XG4gIH1cbiAgZ2V0RGF0YSgpIHtcbiAgICByZXR1cm4gdGhpcy5jb25maWcuZ2V0R2xvYmFsKCk7XG4gIH1cbiAgcHV0RGF0YShkYXRhKSB7XG4gICAgcmV0dXJuIHRoaXMuY29uZmlnLnNldEdsb2JhbChkYXRhKTtcbiAgfVxufVxuLy8gQW4gY29uZmlndXJhdGlvbiBmb3JtIGhhbmRsZXIgZm9yIGEgc3BlY2lmaWMgYXBwbGlhbmNlXG5leHBvcnRzLkdsb2JhbEZvcm0gPSBHbG9iYWxGb3JtO1xuY2xhc3MgQXBwbGlhbmNlRm9ybSBleHRlbmRzIEZvcm0ge1xuICBjb25zdHJ1Y3Rvcihsb2csIGlwYywgY29uZmlnLCBoYWlkKSB7XG4gICAgc3VwZXIobG9nKTtcbiAgICB0aGlzLmlwYyA9IGlwYztcbiAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZztcbiAgICB0aGlzLmhhaWQgPSBoYWlkO1xuICB9XG4gIGdldFNjaGVtYSgpIHtcbiAgICByZXR1cm4gdGhpcy5pcGMucmVxdWVzdCgnL3NjaGVtYS9hcHBsaWFuY2UnLCB0aGlzLmhhaWQpO1xuICB9XG4gIGdldERhdGEoKSB7XG4gICAgcmV0dXJuIHRoaXMuY29uZmlnLmdldEFwcGxpYW5jZSh0aGlzLmhhaWQpO1xuICB9XG4gIHB1dERhdGEoZGF0YSkge1xuICAgIHJldHVybiB0aGlzLmNvbmZpZy5zZXRBcHBsaWFuY2UodGhpcy5oYWlkLCBkYXRhKTtcbiAgfVxufVxuLy8gQSBwbGFjZWhvbGRlciBmb3JtIGhhbmRsZXJcbmV4cG9ydHMuQXBwbGlhbmNlRm9ybSA9IEFwcGxpYW5jZUZvcm07XG5jbGFzcyBUZW1wbGF0ZUZvcm0gZXh0ZW5kcyBGb3JtIHtcbiAgY29uc3RydWN0b3IobG9nLCAuLi5hcmdzKSB7XG4gICAgc3VwZXIobG9nKTtcbiAgICB0aGlzLmVsZW1lbnRBc0Zvcm0gPSB0aGlzLmZvcm1Gcm9tVGVtcGxhdGUoLi4uYXJncyk7XG4gIH1cbiAgLy8gQ3JlYXRlIGEgcGxhY2Vob2xkZXIgc2NoZW1hIHVzaW5nIHRoZSBzcGVjaWZpZWQgSFRNTCBlbGVtZW50XG4gIGFzeW5jIGdldFNjaGVtYSgpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHtcbiAgICAgIHNjaGVtYToge1xuICAgICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgICAgcHJvcGVydGllczoge31cbiAgICAgIH0sXG4gICAgICBmb3JtOiB0aGlzLmVsZW1lbnRBc0Zvcm1cbiAgICB9KTtcbiAgfVxuICBhc3luYyBnZXREYXRhKCkge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoe30pO1xuICB9XG4gIGFzeW5jIHB1dERhdGEoKSB7fVxufVxuLy8gSWRlbnRpZmllcnMgZm9yIHNwZWNpYWwgZm9ybXNcbmV4cG9ydHMuVGVtcGxhdGVGb3JtID0gVGVtcGxhdGVGb3JtO1xudmFyIEZvcm1JZDtcbihmdW5jdGlvbiAoRm9ybUlkKSB7XG4gIEZvcm1JZFtcIkdsb2JhbFwiXSA9IFwiZ2xvYmFsXCI7XG4gIEZvcm1JZFtcIlBsYWNlaG9sZGVyXCJdID0gXCJwbGFjZWhvbGRlclwiO1xuICBGb3JtSWRbXCJVbmF2YWlsYWJsZVwiXSA9IFwidW5hdmFpbGFibGVcIjtcbn0pKEZvcm1JZCB8fCAoZXhwb3J0cy5Gb3JtSWQgPSBGb3JtSWQgPSB7fSkpO1xuLy8gVHlwZSBndWFyZCB0byBjaGVjayB3aGV0aGVyIGEgc3RyaW5nIGlzIGEgc3BlY2lhbCBmb3JtIGlkZW50aWZpZXJcbmZ1bmN0aW9uIGlzRm9ybUlkKHZhbHVlKSB7XG4gIHJldHVybiBPYmplY3QudmFsdWVzKEZvcm1JZCkuaW5jbHVkZXModmFsdWUpO1xufVxuLy8gTWFuYWdlIHRoZSBjb25maWd1cmF0aW9uIGZvcm1zXG5jbGFzcyBGb3JtcyB7XG4gIC8vIENyZWF0ZSBhIG5ldyBmb3JtIG1hbmFnZXJcbiAgY29uc3RydWN0b3IobG9nLCBpcGMsIGNvbmZpZykge1xuICAgIHRoaXMubG9nID0gbG9nO1xuICAgIHRoaXMuaXBjID0gaXBjO1xuICAgIHRoaXMuY29uZmlnID0gY29uZmlnO1xuICAgIHRoaXMuc2hvd0Zvcm0oKTtcbiAgfVxuICAvLyBEaXNwbGF5IHRoZSBzcGVjaWZpZWQgZm9ybSAoZGVmYXVsdGluZyB0byB0aGUgcGxhY2Vob2xkZXIpXG4gIHNob3dGb3JtKGZvcm1JZCkge1xuICAgICgwLCBfbG9nRXJyb3IuZGV0YWNoZWQpKHRoaXMubG9nLCAnU2hvdyBmb3JtJywgYXN5bmMgKCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgLy8gVGhlIGZvcm1zIGFyZSByZXRyaWV2ZWQgZnJvbSB0aGUgc2VydmVyLCBzbyBkaXNwbGF5IGEgc3Bpbm5lclxuICAgICAgICB3aW5kb3cuaG9tZWJyaWRnZS5zaG93U3Bpbm5lcigpO1xuICAgICAgICAvLyBEaXNwbGF5IHRoZSByZXF1ZXN0ZWQgZm9ybSwgd2l0aCBmYWxsYmFjayB0byB0aGUgZXJyb3IgZm9ybVxuICAgICAgICB0cnkge1xuICAgICAgICAgIGF3YWl0IHRoaXMuY29uc3RydWN0QW5kU2hvd0Zvcm0oZm9ybUlkID8/IEZvcm1JZC5QbGFjZWhvbGRlcik7XG4gICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgIHRoaXMubG9nLndhcm4oJ0ZhaWxlZCB0byBkaXNwbGF5IGZvcm0nLCBmb3JtSWQsIGVycik7XG4gICAgICAgICAgYXdhaXQgdGhpcy5jb25zdHJ1Y3RBbmRTaG93Rm9ybShGb3JtSWQuVW5hdmFpbGFibGUpO1xuICAgICAgICB9XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICAvLyBFbnN1cmUgdGhhdCB0aGUgc3Bpbm5lciBpcyBhbHdheXMgaGlkZGVuXG4gICAgICAgIHdpbmRvdy5ob21lYnJpZGdlLmhpZGVTcGlubmVyKCk7XG4gICAgICB9XG4gICAgfSkoKTtcbiAgfVxuICAvLyBUcnkgdG8gY3JlYXRlIHRoZSByZXF1ZXN0ZWQgZm9ybSwgd2l0aCBmYWxsYmFjayB0byB0aGUgcGxhY2Vob2xkZXJcbiAgYXN5bmMgY29uc3RydWN0QW5kU2hvd0Zvcm0oZm9ybUlkKSB7XG4gICAgY29uc3QgZm9ybSA9IHRoaXMuY29uc3RydWN0Rm9ybShmb3JtSWQpO1xuICAgIGF3YWl0IGZvcm0uY3JlYXRlRm9ybSgpO1xuICAgIHRoaXMuY3VycmVudEZvcm0gPSBmb3JtO1xuICB9XG4gIC8vIENyZWF0ZSBhIHNwZWNpZmljIGZvcm1cbiAgY29uc3RydWN0Rm9ybShmb3JtSWQpIHtcbiAgICBpZiAoaXNGb3JtSWQoZm9ybUlkKSkge1xuICAgICAgc3dpdGNoIChmb3JtSWQpIHtcbiAgICAgICAgY2FzZSBGb3JtSWQuUGxhY2Vob2xkZXI6XG4gICAgICAgICAgcmV0dXJuIG5ldyBUZW1wbGF0ZUZvcm0odGhpcy5sb2csICdoYy1mb3JtLXBsYWNlaG9sZGVyJyk7XG4gICAgICAgIGNhc2UgRm9ybUlkLlVuYXZhaWxhYmxlOlxuICAgICAgICAgIHJldHVybiBuZXcgVGVtcGxhdGVGb3JtKHRoaXMubG9nLCAnaGMtZm9ybS11bmF2YWlsYWJsZScpO1xuICAgICAgICBjYXNlIEZvcm1JZC5HbG9iYWw6XG4gICAgICAgICAgcmV0dXJuIG5ldyBHbG9iYWxGb3JtKHRoaXMubG9nLCB0aGlzLmlwYywgdGhpcy5jb25maWcpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbmV3IEFwcGxpYW5jZUZvcm0odGhpcy5sb2csIHRoaXMuaXBjLCB0aGlzLmNvbmZpZywgZm9ybUlkKTtcbiAgICB9XG4gIH1cbn1cbmV4cG9ydHMuRm9ybXMgPSBGb3Jtcztcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRhdGE6YXBwbGljYXRpb24vanNvbjtjaGFyc2V0PXV0Zi04O2Jhc2U2NCxleUoyWlhKemFXOXVJam96TENKdVlXMWxjeUk2V3lKZmRYUnBiSE5FYjIwaUxDSnlaWEYxYVhKbElpd2lYMnh2WjBWeWNtOXlJaXdpUm05eWJTSXNJbU52Ym5OMGNuVmpkRzl5SWl3aWJHOW5JaXdpWTNKbFlYUmxSbTl5YlNJc0luTmphR1Z0WVNJc0ltZGxkRk5qYUdWdFlTSXNJbVJoZEdFaUxDSm5aWFJFWVhSaElpd2ljR0YwWTJobFpGTmphR1Z0WVNJc0luQmhkR05vVTJOb1pXMWhJaXdpWkdWaWRXY2lMQ0ptYjNKdElpd2lkMmx1Wkc5M0lpd2lhRzl0WldKeWFXUm5aU0lzSW05dVEyaGhibWRsSWl3aVkyOXVabWxuSWl3aWNIVjBSR0YwWVNJc0ltUmxjM1J5YjNsR2IzSnRJaXdpWlc1a0lpd2lkVzVrWldacGJtVmtJaXdpWm05eWJVWnliMjFVWlcxd2JHRjBaU0lzSW1GeVozTWlMQ0owWlcxd2JHRjBaU0lzSW1Oc2IyNWxWR1Z0Y0d4aGRHVWlMQ0poWW5OVVpXMXdiR0YwWlNJc0ltVnNaVzFsYm5SWGFYUm9RV0p6YjJ4MWRHVlFZWFJvY3lJc0ltWnZjbTFHY205dFNGUk5UQ0lzSW1Wc1pXMWxiblFpTENKMGVYQmxJaXdpYUdWc2NIWmhiSFZsSWl3aVoyVjBTRlJOVENJc0ltVjRjRzl5ZEhNaUxDSkhiRzlpWVd4R2IzSnRJaXdpYVhCaklpd2ljbVZ4ZFdWemRDSXNJbWRsZEVkc2IySmhiQ0lzSW5ObGRFZHNiMkpoYkNJc0lrRndjR3hwWVc1alpVWnZjbTBpTENKb1lXbGtJaXdpWjJWMFFYQndiR2xoYm1ObElpd2ljMlYwUVhCd2JHbGhibU5sSWl3aVZHVnRjR3hoZEdWR2IzSnRJaXdpWld4bGJXVnVkRUZ6Um05eWJTSXNJbEJ5YjIxcGMyVWlMQ0p5WlhOdmJIWmxJaXdpY0hKdmNHVnlkR2xsY3lJc0lrWnZjbTFKWkNJc0ltbHpSbTl5YlVsa0lpd2lkbUZzZFdVaUxDSlBZbXBsWTNRaUxDSjJZV3gxWlhNaUxDSnBibU5zZFdSbGN5SXNJa1p2Y20xeklpd2ljMmh2ZDBadmNtMGlMQ0ptYjNKdFNXUWlMQ0prWlhSaFkyaGxaQ0lzSW5Ob2IzZFRjR2x1Ym1WeUlpd2lZMjl1YzNSeWRXTjBRVzVrVTJodmQwWnZjbTBpTENKUWJHRmpaV2h2YkdSbGNpSXNJbVZ5Y2lJc0luZGhjbTRpTENKVmJtRjJZV2xzWVdKc1pTSXNJbWhwWkdWVGNHbHVibVZ5SWl3aVkyOXVjM1J5ZFdOMFJtOXliU0lzSW1OMWNuSmxiblJHYjNKdElpd2lSMnh2WW1Gc0lsMHNJbk52ZFhKalpYTWlPbHNpTGk0dkxpNHZMaTR2YzNKakwyaHZiV1ZpY21sa1oyVXRkV2t2Y0hWaWJHbGpMMlp2Y20xekxuUnpJbDBzSW5OdmRYSmpaWE5EYjI1MFpXNTBJanBiYm5Wc2JGMHNJbTFoY0hCcGJtZHpJam9pT3pzN096czdRVUZUUVN4SlFVRkJRU3hUUVVGQkxFZEJRVUZETEU5QlFVRTdRVUZEUVN4SlFVRkJReXhUUVVGQkxFZEJRVUZFTEU5QlFVRTdRVUZXUVR0QlFVTkJPenRCUVZkQk8wRkJRMDBzVFVGQlowSkZMRWxCUVVrN1JVRkxkRUk3UlVGRFFVTXNXVUZCY1VKRExFZEJRVmM3WlVGQldFRXNSMEZCUnp0RlFVRlhPMFZCVjI1RE8wVkJRMEVzVFVGQlRVTXNWVUZCVlVFc1EwRkJRVHRKUVVOYU8wbEJRMEVzVFVGQlRVTXNUVUZCVFN4SFFVRkhMRTFCUVUwc1NVRkJTU3hEUVVGRFF5eFRRVUZUTEVWQlFVVTdTVUZEY2tNc1RVRkJUVU1zU1VGQlNTeEhRVUZMTEUxQlFVMHNTVUZCU1N4RFFVRkRReXhQUVVGUExFVkJRVVU3U1VGRmJrTTdTVUZEUVN4TlFVRk5ReXhoUVVGaExFZEJRVWNzU1VGQlNTeERRVUZEUXl4WFFVRlhMRU5CUVVOTUxFMUJRVTBzUTBGQlF6dEpRVU01UXl4SlFVRkpMRU5CUVVOR0xFZEJRVWNzUTBGQlExRXNTMEZCU3l4RFFVRkRMRmxCUVZrc1JVRkJSVVlzWVVGQllTeEZRVUZGUml4SlFVRkpMRU5CUVVNN1NVRkRha1FzU1VGQlNTeERRVUZEU3l4SlFVRkpMRWRCUVVkRExFMUJRVTBzUTBGQlEwTXNWVUZCVlN4RFFVRkRWaXhWUVVGVkxFTkJRVU5MTEdGQlFXRXNSVUZCUlVZc1NVRkJTU3hEUVVGRE8wbEJSVGRFTzBsQlEwRXNTVUZCU1N4RFFVRkRTeXhKUVVGSkxFTkJRVU5ITEZGQlFWRXNRMEZCUTBNc1RVRkJUU3hKUVVGSkxFbEJRVWtzUTBGQlEwTXNUMEZCVHl4RFFVRkRSQ3hOUVVGTkxFTkJRVU1zUTBGQlF6dEZRVU4wUkR0RlFVVkJPMFZCUTBGRkxGZEJRVmRCTEVOQlFVRTdTVUZEVUN4SlFVRkpMRU5CUVVOT0xFbEJRVWtzUlVGQlJVOHNSMEZCUnl4RlFVRkZPMGxCUTJoQ0xFbEJRVWtzUTBGQlExQXNTVUZCU1N4SFFVRkhVU3hUUVVGVE8wVkJRM3BDTzBWQlJVRTdSVUZEUVZZc1YwRkJWMEVzUTBGQlEwd3NUVUZCZDBJN1NVRkRhRU1zVFVGQlRVOHNTVUZCU1N4SFFVRkhMRU5CUTFRc1NVRkJTVkFzVFVGQlRTeERRVUZEVHl4SlFVRkpMRWxCUVVrc1JVRkJSU3hEUVVGRExFVkJRM1JDTEVkQlFVY3NTVUZCU1N4RFFVRkRVeXhuUWtGQlowSXNRMEZCUXl4blFrRkJaMElzUTBGQlF5eERRVU0zUXp0SlFVTkVMRTlCUVU4N1RVRkJSU3hIUVVGSGFFSXNUVUZCVFR0TlFVRkZUenRKUVVGSkxFTkJRVVU3UlVGRE9VSTdSVUZGUVR0RlFVTkJVeXhuUWtGQlowSkJMRU5CUVVNc1IwRkJSME1zU1VGQmMwTTdTVUZEZEVRc1RVRkJUVU1zVVVGQlVTeEhRVUZITEVsQlFVRkRMSFZDUVVGaExFVkJRVU1zUjBGQlIwWXNTVUZCU1N4RFFVRkRPMGxCUTNaRExFMUJRVTFITEZkQlFWY3NSMEZCUnl4SlFVRkJReXhyUTBGQmQwSXNSVUZCUTBnc1VVRkJVU3hEUVVGRE8wbEJRM1JFTEU5QlFVOHNTVUZCU1N4RFFVRkRTU3haUVVGWkxFTkJRVU5HTEZkQlFWY3NRMEZCUXp0RlFVTjZRenRGUVVWQk8wVkJRMEZGTEZsQlFWbEJMRU5CUVVORExFOUJRV0U3U1VGRGRFSXNUMEZCVHl4RFFVRkRPMDFCUTBwRExFbEJRVWtzUlVGQlVTeE5RVUZOTzAxQlEyeENReXhUUVVGVExFVkJRVWNzU1VGQlFVTXNhVUpCUVU4c1JVRkJRMGdzVDBGQlR6dExRVU01UWl4RFFVRkRPMFZCUTA0N08wRkJSMG83UVVGQlFVa3NUMEZCUVN4RFFVRkJMMElzU1VGQlFTeEhRVUZCUVN4SlFVRkJPMEZCUTAwc1RVRkJUMmRETEZWQlFWY3NVMEZCVVdoRExFbEJRVWs3UlVGRGFFTkRMRmxCUVZsRExFZEJRVEJDTEVWQlEycENLMElzUjBGQmIwSXNSVUZEY0VKc1FpeE5RVUZwUWp0SlFVTnNReXhMUVVGTExFTkJRVU5pTEVkQlFVY3NRMEZCUXp0bFFVWlBLMElzUjBGQlJ6dHJRa0ZEU0d4Q0xFMUJRVTA3UlVGRk0wSTdSVUZGUVZZc1UwRkJVMEVzUTBGQlFUdEpRVUZ4UXl4UFFVRlBMRWxCUVVrc1EwRkJRelJDTEVkQlFVY3NRMEZCUTBNc1QwRkJUeXhEUVVGRExHZENRVUZuUWl4RlFVRkZMRWxCUVVrc1EwRkJRenRGUVVGRk8wVkJReTlHTTBJc1QwRkJUMEVzUTBGQlFUdEpRVUYxUXl4UFFVRlBMRWxCUVVrc1EwRkJRMUVzVFVGQlRTeERRVUZEYjBJc1UwRkJVeXhGUVVGRk8wVkJRVVU3UlVGRE9VVnVRaXhQUVVGUFFTeERRVUZEVml4SlFVRnJRanRKUVVGdlFpeFBRVUZQTEVsQlFVa3NRMEZCUTFNc1RVRkJUU3hEUVVGRGNVSXNVMEZCVXl4RFFVRkRPVUlzU1VGQmIwSXNRMEZCUXp0RlFVRkZPenRCUVVkMFJ6dEJRVUZCZVVJc1QwRkJRU3hEUVVGQlF5eFZRVUZCTEVkQlFVRkJMRlZCUVVFN1FVRkRUU3hOUVVGUFN5eGhRVUZqTEZOQlFWRnlReXhKUVVGSk8wVkJRMjVEUXl4WlFVRlpReXhIUVVFd1FpeEZRVU5xUWl0Q0xFZEJRVzlDTEVWQlEzQkNiRUlzVFVGQmFVSXNSVUZEYWtKMVFpeEpRVUZwUWp0SlFVTnNReXhMUVVGTExFTkJRVU53UXl4SFFVRkhMRU5CUVVNN1pVRklUeXRDTEVkQlFVYzdhMEpCUTBoc1FpeE5RVUZOTzJkQ1FVTk9kVUlzU1VGQlNUdEZRVVY2UWp0RlFVVkJha01zVTBGQlUwRXNRMEZCUVR0SlFVRnhReXhQUVVGUExFbEJRVWtzUTBGQlF6UkNMRWRCUVVjc1EwRkJRME1zVDBGQlR5eERRVUZETEcxQ1FVRnRRaXhGUVVGRkxFbEJRVWtzUTBGQlEwa3NTVUZCU1N4RFFVRkRPMFZCUVVVN1JVRkRka2N2UWl4UFFVRlBRU3hEUVVGQk8wbEJRWFZETEU5QlFVOHNTVUZCU1N4RFFVRkRVU3hOUVVGTkxFTkJRVU4zUWl4WlFVRlpMRU5CUVVNc1NVRkJTU3hEUVVGRFJDeEpRVUZKTEVOQlFVTTdSVUZCUlR0RlFVTXhSblJDTEU5QlFVOUJMRU5CUVVOV0xFbEJRV3RDTzBsQlFXOUNMRTlCUVU4c1NVRkJTU3hEUVVGRFV5eE5RVUZOTEVOQlFVTjVRaXhaUVVGWkxFTkJRVU1zU1VGQlNTeERRVUZEUml4SlFVRkpMRVZCUVVWb1F5eEpRVUZKTEVOQlFVTTdSVUZCUlRzN1FVRkhjRWM3UVVGQlFYbENMRTlCUVVFc1EwRkJRVTBzWVVGQlFTeEhRVUZCUVN4aFFVRkJPMEZCUTAwc1RVRkJUMGtzV1VGQllTeFRRVUZSZWtNc1NVRkJTVHRGUVVsc1EwTXNXVUZCV1VNc1IwRkJhMElzUlVGRGJFSXNSMEZCUjIxQ0xFbEJRWGxETzBsQlEzQkVMRXRCUVVzc1EwRkJRMjVDTEVkQlFVY3NRMEZCUXp0SlFVTldMRWxCUVVrc1EwRkJRM2RETEdGQlFXRXNSMEZCUnl4SlFVRkpMRU5CUVVOMFFpeG5Ra0ZCWjBJc1EwRkJReXhIUVVGSFF5eEpRVUZKTEVOQlFVTTdSVUZEZGtRN1JVRkZRVHRGUVVOQkxFMUJRVTFvUWl4VFFVRlRRU3hEUVVGQk8wbEJRMWdzVDBGQlQzTkRMRTlCUVU4c1EwRkJRME1zVDBGQlR5eERRVUZETzAxQlEyNUNlRU1zVFVGQlRTeEZRVUZGTzFGQlEwcDNRaXhKUVVGSkxFVkJRVVVzVVVGQlVUdFJRVU5rYVVJc1ZVRkJWU3hGUVVGRk8wOUJRMlk3VFVGRFJHeERMRWxCUVVrc1JVRkJTU3hKUVVGSkxFTkJRVU1yUWp0TFFVTm9RaXhEUVVGRE8wVkJRMDQ3UlVGRlFTeE5RVUZOYmtNc1QwRkJUMEVzUTBGQlFUdEpRVUUyUWl4UFFVRlBiME1zVDBGQlR5eERRVUZEUXl4UFFVRlBMRU5CUVVNc1JVRkJSU3hEUVVGRE8wVkJRVVU3UlVGRGRFVXNUVUZCVFRWQ0xFOUJRVTlCTEVOQlFVRXNSMEZCZVVNN08wRkJSekZFTzBGQlFVRmxMRTlCUVVFc1EwRkJRVlVzV1VGQlFTeEhRVUZCUVN4WlFVRkJPMEZCUTBFc1NVRkJXVXNzVFVGSldEdEJRVXBFTEZkQlFWbEJMRTFCUVUwN1JVRkRaRUVzVFVGQlFTeHhRa0ZCYzBJN1JVRkRkRUpCTEUxQlFVRXNLMEpCUVRKQ08wVkJRek5DUVN4TlFVRkJMQ3RDUVVFeVFqdEJRVU12UWl4RFFVRkRMRVZCU2xkQkxFMUJRVTBzUzBGQlFXWXNUMEZCUVN4RFFVRkJaU3hOUVVGQkxFZEJRVTVCTEUxQlFVMDdRVUZOYkVJN1FVRkRRU3hUUVVGVFF5eFJRVUZSUVN4RFFVRkRReXhMUVVGaE8wVkJRek5DTEU5QlFVOURMRTFCUVUwc1EwRkJRME1zVFVGQlRTeERRVUZEU2l4TlFVRk5MRU5CUVVNc1EwRkJRMHNzVVVGQlVTeERRVUZEU0N4TFFVRmxMRU5CUVVNN1FVRkRNVVE3UVVGRlFUdEJRVU5OTEUxQlFVOUpMRXRCUVVzN1JVRkxaRHRGUVVOQmJrUXNXVUZCY1VKRExFZEJRV2xDTEVWQlEycENLMElzUjBGQmIwSXNSVUZEY0VKc1FpeE5RVUZwUWp0bFFVWnFRbUlzUjBGQlJ6dGxRVU5JSzBJc1IwRkJSenRyUWtGRFNHeENMRTFCUVUwN1NVRkRka0lzU1VGQlNTeERRVUZEYzBNc1VVRkJVU3hGUVVGRk8wVkJRMjVDTzBWQlJVRTdSVUZEUVVFc1VVRkJVVUVzUTBGQlEwTXNUVUZCWlR0SlFVTndRaXhKUVVGQlF5eHJRa0ZCVVN4RlFVRkRMRWxCUVVrc1EwRkJRM0pFTEVkQlFVY3NSVUZCUlN4WFFVRlhMRVZCUVVVc1dVRkJWenROUVVOMlF5eEpRVUZKTzFGQlEwRTdVVUZEUVZVc1RVRkJUU3hEUVVGRFF5eFZRVUZWTEVOQlFVTXlReXhYUVVGWExFVkJRVVU3VVVGRkwwSTdVVUZEUVN4SlFVRkpPMVZCUTBFc1RVRkJUU3hKUVVGSkxFTkJRVU5ETEc5Q1FVRnZRaXhEUVVGRFNDeE5RVUZOTEVsQlFVbFNMRTFCUVUwc1EwRkJRMWtzVjBGQlZ5eERRVUZETzFGQlEycEZMRU5CUVVNc1EwRkJReXhQUVVGUFF5eEhRVUZITEVWQlFVVTdWVUZEVml4SlFVRkpMRU5CUVVONlJDeEhRVUZITEVOQlFVTXdSQ3hKUVVGSkxFTkJRVU1zZDBKQlFYZENMRVZCUVVWT0xFMUJRVTBzUlVGQlJVc3NSMEZCUnl4RFFVRkRPMVZCUTNCRUxFMUJRVTBzU1VGQlNTeERRVUZEUml4dlFrRkJiMElzUTBGQlExZ3NUVUZCVFN4RFFVRkRaU3hYUVVGWExFTkJRVU03VVVGRGRrUTdUVUZEU2l4RFFVRkRMRk5CUVZFN1VVRkRURHRSUVVOQmFrUXNUVUZCVFN4RFFVRkRReXhWUVVGVkxFTkJRVU5wUkN4WFFVRlhMRVZCUVVVN1RVRkRia003U1VGRFNpeERRVUZETEVOQlFVTXNSVUZCUlR0RlFVTlNPMFZCUlVFN1JVRkRRU3hOUVVGTlRDeHZRa0ZCYjBKQkxFTkJRVU5JTEUxQlFXTTdTVUZEY2tNc1RVRkJUVE5ETEVsQlFVa3NSMEZCUnl4SlFVRkpMRU5CUVVOdlJDeGhRVUZoTEVOQlFVTlVMRTFCUVUwc1EwRkJRenRKUVVOMlF5eE5RVUZOTTBNc1NVRkJTU3hEUVVGRFVpeFZRVUZWTEVWQlFVVTdTVUZEZGtJc1NVRkJTU3hEUVVGRE5rUXNWMEZCVnl4SFFVRkhja1FzU1VGQlNUdEZRVU16UWp0RlFVVkJPMFZCUTBGdlJDeGhRVUZoUVN4RFFVRkRWQ3hOUVVGak8wbEJRM2hDTEVsQlFVbFFMRkZCUVZFc1EwRkJRMDhzVFVGQlRTeERRVUZETEVWQlFVVTdUVUZEYkVJc1VVRkJVVUVzVFVGQlRUdFJRVU5rTEV0QlFVdFNMRTFCUVUwc1EwRkJRMWtzVjBGQlZ6dFZRVUZGTEU5QlFVOHNTVUZCU1dwQ0xGbEJRVmtzUTBGQlJTeEpRVUZKTEVOQlFVTjJReXhIUVVGSExFVkJRVVVzY1VKQlFYRkNMRU5CUVVNN1VVRkRiRVlzUzBGQlN6UkRMRTFCUVUwc1EwRkJRMlVzVjBGQlZ6dFZRVUZGTEU5QlFVOHNTVUZCU1hCQ0xGbEJRVmtzUTBGQlJTeEpRVUZKTEVOQlFVTjJReXhIUVVGSExFVkJRVVVzY1VKQlFYRkNMRU5CUVVNN1VVRkRiRVlzUzBGQlN6UkRMRTFCUVUwc1EwRkJRMjFDTEUxQlFVMDdWVUZCVHl4UFFVRlBMRWxCUVVscVF5eFZRVUZWTEVOQlFVa3NTVUZCU1N4RFFVRkRPVUlzUjBGQlJ5eEZRVUZGTEVsQlFVa3NRMEZCUXl0Q0xFZEJRVWNzUlVGQlJTeEpRVUZKTEVOQlFVTnNRaXhOUVVGTkxFTkJRVU03VFVGRGJFWTdTVUZEU2l4RFFVRkRMRTFCUVUwN1RVRkRTQ3hQUVVGUExFbEJRVWx6UWl4aFFVRmhMRU5CUVVNc1NVRkJTU3hEUVVGRGJrTXNSMEZCUnl4RlFVRkZMRWxCUVVrc1EwRkJReXRDTEVkQlFVY3NSVUZCUlN4SlFVRkpMRU5CUVVOc1FpeE5RVUZOTEVWQlFVVjFReXhOUVVGTkxFTkJRVU03U1VGRGNrVTdSVUZEU2pzN1FVRkRTSFpDTEU5QlFVRXNRMEZCUVhGQ0xFdEJRVUVzUjBGQlFVRXNTMEZCUVNJc0ltbG5ibTl5WlV4cGMzUWlPbHRkZlE9PSIsIlwidXNlIHN0cmljdFwiO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5TZXJ2ZXJMb2dnZXIgPSBleHBvcnRzLkNvbnNvbGVMb2dnZXIgPSBleHBvcnRzLkNsaWVudExvZ2dlciA9IHZvaWQgMDtcbi8vIEhvbWVicmlkZ2UgcGx1Z2luIGZvciBIb21lIENvbm5lY3QgaG9tZSBhcHBsaWFuY2VzXG4vLyBDb3B5cmlnaHQgwqkgMjAyMy0yMDI2IEFsZXhhbmRlciBUaG91a3lkaWRlc1xuLy8gUHJlZml4IGZvciBjbGllbnQgYW5kIHNlcnZlciBsb2cgbWVzc2FnZXNcbmNvbnN0IFBMVUdJTl9QUkVGSVggPSB3aW5kb3cuaG9tZWJyaWRnZS5wbHVnaW4uZGlzcGxheU5hbWUgPz8gd2luZG93LmhvbWVicmlkZ2UucGx1Z2luLm5hbWU7XG4vLyBBIGxvZ2dlciB0aGF0IHNlbmRzIG1lc3NhZ2VzIHRvIHRoZSBkZWJ1Z2dpbmcgY29uc29sZVxuY2xhc3MgQ29uc29sZUxvZ2dlciB7XG4gIC8vIENyZWF0ZSBhIG5ldyBjb25zb2xlIGxvZ2dlclxuICBjb25zdHJ1Y3RvcihwcmVmaXggPSAnJykge1xuICAgIHRoaXMucHJlZml4ID0gcHJlZml4O1xuICB9XG4gIC8vIFNpbXBsZSB3cmFwcGVycyB0byBsb2cgYSBtZXNzYWdlXG4gIGVycm9yKG1lc3NhZ2UsIC4uLnBhcmFtcykge1xuICAgIHRoaXMubG9nKFwiZXJyb3JcIiAvKiBMb2dMZXZlbC5FUlJPUiAqLywgbWVzc2FnZSwgLi4ucGFyYW1zKTtcbiAgfVxuICB3YXJuKG1lc3NhZ2UsIC4uLnBhcmFtcykge1xuICAgIHRoaXMubG9nKFwid2FyblwiIC8qIExvZ0xldmVsLldBUk4gKi8sIG1lc3NhZ2UsIC4uLnBhcmFtcyk7XG4gIH1cbiAgc3VjY2VzcyhtZXNzYWdlLCAuLi5wYXJhbXMpIHtcbiAgICB0aGlzLmxvZyhcInN1Y2Nlc3NcIiAvKiBMb2dMZXZlbC5TVUNDRVNTICovLCBtZXNzYWdlLCAuLi5wYXJhbXMpO1xuICB9XG4gIGluZm8obWVzc2FnZSwgLi4ucGFyYW1zKSB7XG4gICAgdGhpcy5sb2coXCJpbmZvXCIgLyogTG9nTGV2ZWwuSU5GTyAqLywgbWVzc2FnZSwgLi4ucGFyYW1zKTtcbiAgfVxuICBkZWJ1ZyhtZXNzYWdlLCAuLi5wYXJhbXMpIHtcbiAgICB0aGlzLmxvZyhcImRlYnVnXCIgLyogTG9nTGV2ZWwuREVCVUcgKi8sIG1lc3NhZ2UsIC4uLnBhcmFtcyk7XG4gIH1cbiAgLy8gTG9nIGEgbWVzc2FnZSBhdCB0aGUgc3BlY2lmaWVkIGxldmVsXG4gIGxvZyhsZXZlbCwgbWVzc2FnZSwgLi4ucGFyYW1zKSB7XG4gICAgLy8gQWRkIHRoZSBwcmVmaXggdG8gdGhlIG1lc3NhZ2VcbiAgICBpZiAodGhpcy5wcmVmaXgubGVuZ3RoKSBtZXNzYWdlID0gYFske3RoaXMucHJlZml4fV0gJHttZXNzYWdlfWA7XG4gICAgLy8gTG9nIHRoZSBtZXNzYWdlXG4gICAgc3dpdGNoIChsZXZlbCkge1xuICAgICAgY2FzZSBcImVycm9yXCIgLyogTG9nTGV2ZWwuRVJST1IgKi86XG4gICAgICAgIGNvbnNvbGUuZXJyb3IobWVzc2FnZSwgLi4ucGFyYW1zKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFwid2FyblwiIC8qIExvZ0xldmVsLldBUk4gKi86XG4gICAgICAgIGNvbnNvbGUud2FybihtZXNzYWdlLCAuLi5wYXJhbXMpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgXCJzdWNjZXNzXCIgLyogTG9nTGV2ZWwuU1VDQ0VTUyAqLzpcbiAgICAgICAgY29uc29sZS5pbmZvKG1lc3NhZ2UsIC4uLnBhcmFtcyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBcImluZm9cIiAvKiBMb2dMZXZlbC5JTkZPICovOlxuICAgICAgICBjb25zb2xlLmluZm8obWVzc2FnZSwgLi4ucGFyYW1zKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFwiZGVidWdcIiAvKiBMb2dMZXZlbC5ERUJVRyAqLzpcbiAgICAgICAgY29uc29sZS5kZWJ1ZyhtZXNzYWdlLCAuLi5wYXJhbXMpO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gIH1cbn1cbi8vIExvZ2dlciBmb3IgbG9jYWxseSBnZW5lcmF0ZWQgbWVzc2FnZXNcbmV4cG9ydHMuQ29uc29sZUxvZ2dlciA9IENvbnNvbGVMb2dnZXI7XG5jbGFzcyBDbGllbnRMb2dnZXIgZXh0ZW5kcyBDb25zb2xlTG9nZ2VyIHtcbiAgLy8gQ3JlYXRlIGEgbmV3IGNsaWVudCBsb2dnZXJcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoYCR7UExVR0lOX1BSRUZJWH0gY2xpZW50YCk7XG4gIH1cbn1cbi8vIExvZ2dlciB0aGF0IHJlY2VpdmVzIG1lc3NhZ2VzIGV2ZW50cyBmcm9tIHRoZSBzZXJ2ZXJcbmV4cG9ydHMuQ2xpZW50TG9nZ2VyID0gQ2xpZW50TG9nZ2VyO1xuY2xhc3MgU2VydmVyTG9nZ2VyIGV4dGVuZHMgQ29uc29sZUxvZ2dlciB7XG4gIC8vIENyZWF0ZSBhIG5ldyBzZXJ2ZXIgbG9nZ2VyXG4gIGNvbnN0cnVjdG9yKGlwYywgbWluTGV2ZWwpIHtcbiAgICBzdXBlcihgJHtQTFVHSU5fUFJFRklYfSBzZXJ2ZXJgKTtcbiAgICB0aGlzLmlwYyA9IGlwYztcbiAgICAvLyBTdGFydCByZWNlaXZpbmcgbG9nIGV2ZW50c1xuICAgIGlwYy5vbkV2ZW50KCdsb2cnLCBtZXNzYWdlcyA9PiB7XG4gICAgICB0aGlzLmxvZ01lc3NhZ2VzKG1lc3NhZ2VzKTtcbiAgICB9KTtcbiAgICBpcGMucmVxdWVzdCgnL2xvZycsIG1pbkxldmVsKS5jYXRjaCgoKSA9PiB7fSk7XG4gIH1cbiAgLy8gTG9nIG1lc3NhZ2VzIHJlY2VpdmVkIGZyb20gdGhlIHNlcnZlclxuICBsb2dNZXNzYWdlcyhtZXNzYWdlcykge1xuICAgIGZvciAoY29uc3Qge1xuICAgICAgbGV2ZWwsXG4gICAgICBtZXNzYWdlLFxuICAgICAgcGFyYW1zXG4gICAgfSBvZiBtZXNzYWdlcykgdGhpcy5sb2cobGV2ZWwsIG1lc3NhZ2UsIC4uLnBhcmFtcyk7XG4gIH1cbn1cbmV4cG9ydHMuU2VydmVyTG9nZ2VyID0gU2VydmVyTG9nZ2VyO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ9dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p1WVcxbGN5STZXeUpRVEZWSFNVNWZVRkpGUmtsWUlpd2lkMmx1Wkc5M0lpd2lhRzl0WldKeWFXUm5aU0lzSW5Cc2RXZHBiaUlzSW1ScGMzQnNZWGxPWVcxbElpd2libUZ0WlNJc0lrTnZibk52YkdWTWIyZG5aWElpTENKamIyNXpkSEoxWTNSdmNpSXNJbkJ5WldacGVDSXNJbVZ5Y205eUlpd2liV1Z6YzJGblpTSXNJbkJoY21GdGN5SXNJbXh2WnlJc0luZGhjbTRpTENKemRXTmpaWE56SWl3aWFXNW1ieUlzSW1SbFluVm5JaXdpYkdWMlpXd2lMQ0pzWlc1bmRHZ2lMQ0pqYjI1emIyeGxJaXdpWlhod2IzSjBjeUlzSWtOc2FXVnVkRXh2WjJkbGNpSXNJbE5sY25abGNreHZaMmRsY2lJc0ltbHdZeUlzSW0xcGJreGxkbVZzSWl3aWIyNUZkbVZ1ZENJc0ltMWxjM05oWjJWeklpd2liRzluVFdWemMyRm5aWE1pTENKeVpYRjFaWE4wSWl3aVkyRjBZMmdpWFN3aWMyOTFjbU5sY3lJNld5SXVMaTh1TGk4dUxpOXpjbU12YUc5dFpXSnlhV1JuWlMxMWFTOXdkV0pzYVdNdmJHOW5aMlZ5TG5SeklsMHNJbk52ZFhKalpYTkRiMjUwWlc1MElqcGJiblZzYkYwc0ltMWhjSEJwYm1keklqb2lPenM3T3pzN1FVRkJRVHRCUVVOQk8wRkJUMEU3UVVGRFFTeE5RVUZOUVN4aFFVRmhMRWRCUVVkRExFMUJRVTBzUTBGQlEwTXNWVUZCVlN4RFFVRkRReXhOUVVGTkxFTkJRVU5ETEZkQlFWY3NTVUZCU1Vnc1RVRkJUU3hEUVVGRFF5eFZRVUZWTEVOQlFVTkRMRTFCUVUwc1EwRkJRMFVzU1VGQlNUdEJRVVV6Ump0QlFVTk5MRTFCUVU5RExHRkJRV0U3UlVGRmRFSTdSVUZEUVVNc1dVRkJjVUpETEUxQlFVMHNSMEZCUnl4RlFVRkZPMnRDUVVGWVFTeE5RVUZOTzBWQlFWRTdSVUZGYmtNN1JVRkRRVU1zUzBGQlMwRXNRMEZCUjBNc1QwRkJaU3hGUVVGRkxFZEJRVWRETEUxQlFXbENPMGxCUVZVc1NVRkJTU3hEUVVGRFF5eEhRVUZITEN0Q1FVRnRRa1lzVDBGQlR5eEZRVUZGTEVkQlFVZERMRTFCUVUwc1EwRkJRenRGUVVGRk8wVkJRM1pIUlN4SlFVRkpRU3hEUVVGSlNDeFBRVUZsTEVWQlFVVXNSMEZCUjBNc1RVRkJhVUk3U1VGQlZTeEpRVUZKTEVOQlFVTkRMRWRCUVVjc05rSkJRVzFDUml4UFFVRlBMRVZCUVVVc1IwRkJSME1zVFVGQlRTeERRVUZETzBWQlFVVTdSVUZEZGtkSExFOUJRVTlCTEVOQlFVTktMRTlCUVdVc1JVRkJSU3hIUVVGSFF5eE5RVUZwUWp0SlFVRlZMRWxCUVVrc1EwRkJRME1zUjBGQlJ5eHRRMEZCYlVKR0xFOUJRVThzUlVGQlJTeEhRVUZIUXl4TlFVRk5MRU5CUVVNN1JVRkJSVHRGUVVOMlIwa3NTVUZCU1VFc1EwRkJTVXdzVDBGQlpTeEZRVUZGTEVkQlFVZERMRTFCUVdsQ08wbEJRVlVzU1VGQlNTeERRVUZEUXl4SFFVRkhMRFpDUVVGdFFrWXNUMEZCVHl4RlFVRkZMRWRCUVVkRExFMUJRVTBzUTBGQlF6dEZRVUZGTzBWQlEzWkhTeXhMUVVGTFFTeERRVUZIVGl4UFFVRmxMRVZCUVVVc1IwRkJSME1zVFVGQmFVSTdTVUZCVlN4SlFVRkpMRU5CUVVORExFZEJRVWNzSzBKQlFXMUNSaXhQUVVGUExFVkJRVVVzUjBGQlIwTXNUVUZCVFN4RFFVRkRPMFZCUVVVN1JVRkhka2M3UlVGRFFVTXNSMEZCUjBFc1EwRkJRMHNzUzBGQlpTeEZRVUZGVUN4UFFVRmxMRVZCUVVVc1IwRkJSME1zVFVGQmFVSTdTVUZEZEVRN1NVRkRRU3hKUVVGSkxFbEJRVWtzUTBGQlEwZ3NUVUZCVFN4RFFVRkRWU3hOUVVGTkxFVkJRVVZTTEU5QlFVOHNSMEZCUnl4SlFVRkpMRWxCUVVrc1EwRkJRMFlzVFVGQlRTeExRVUZMUlN4UFFVRlBMRVZCUVVVN1NVRkZMMFE3U1VGRFFTeFJRVUZSVHl4TFFVRkxPMDFCUTJJN1VVRkJkVUpGTEU5QlFVOHNRMEZCUTFZc1MwRkJTeXhEUVVGSFF5eFBRVUZQTEVWQlFVVXNSMEZCUjBNc1RVRkJUU3hEUVVGRE8xRkJRVVU3VFVGRE5VUTdVVUZCZFVKUkxFOUJRVThzUTBGQlEwNHNTVUZCU1N4RFFVRkpTQ3hQUVVGUExFVkJRVVVzUjBGQlIwTXNUVUZCVFN4RFFVRkRPMUZCUVVVN1RVRkROVVE3VVVGQmRVSlJMRTlCUVU4c1EwRkJRMG9zU1VGQlNTeERRVUZKVEN4UFFVRlBMRVZCUVVVc1IwRkJSME1zVFVGQlRTeERRVUZETzFGQlFVVTdUVUZETlVRN1VVRkJkVUpSTEU5QlFVOHNRMEZCUTBvc1NVRkJTU3hEUVVGSlRDeFBRVUZQTEVWQlFVVXNSMEZCUjBNc1RVRkJUU3hEUVVGRE8xRkJRVVU3VFVGRE5VUTdVVUZCZFVKUkxFOUJRVThzUTBGQlEwZ3NTMEZCU3l4RFFVRkhUaXhQUVVGUExFVkJRVVVzUjBGQlIwTXNUVUZCVFN4RFFVRkRPMUZCUVVVN1NVRkROVVE3UlVGRFNqczdRVUZKU2p0QlFVRkJVeXhQUVVGQkxFTkJRVUZrTEdGQlFVRXNSMEZCUVVFc1lVRkJRVHRCUVVOTkxFMUJRVTlsTEZsQlFXRXNVMEZCVVdZc1lVRkJZVHRGUVVVelF6dEZRVU5CUXl4WlFVRkJPMGxCUTBrc1MwRkJTeXhEUVVGRExFZEJRVWRRTEdGQlFXRXNVMEZCVXl4RFFVRkRPMFZCUTNCRE96dEJRVWRLTzBGQlFVRnZRaXhQUVVGQkxFTkJRVUZETEZsQlFVRXNSMEZCUVVFc1dVRkJRVHRCUVVOTkxFMUJRVTlETEZsQlFXRXNVMEZCVVdoQ0xHRkJRV0U3UlVGRk0wTTdSVUZEUVVNc1dVRkJjVUpuUWl4SFFVRmpMRVZCUVVWRExGRkJRV3RDTzBsQlEyNUVMRXRCUVVzc1EwRkJReXhIUVVGSGVFSXNZVUZCWVN4VFFVRlRMRU5CUVVNN1pVRkVablZDTEVkQlFVYzdTVUZIY0VJN1NVRkRRVUVzUjBGQlJ5eERRVUZEUlN4UFFVRlBMRU5CUVVNc1MwRkJTeXhGUVVGRlF5eFJRVUZSTEVsQlFVYzdUVUZCUnl4SlFVRkpMRU5CUVVORExGZEJRVmNzUTBGQlEwUXNVVUZCVVN4RFFVRkRPMGxCUVVVc1EwRkJReXhEUVVGRE8wbEJReTlFU0N4SFFVRkhMRU5CUVVOTExFOUJRVThzUTBGQlF5eE5RVUZOTEVWQlFVVktMRkZCUVZFc1EwRkJReXhEUVVGRFN5eExRVUZMTEVOQlFVTXNUVUZCU3l4RFFVRmxMRU5CUVVNc1EwRkJRenRGUVVNNVJEdEZRVVZCTzBWQlEwRkdMRmRCUVZkQkxFTkJRVU5FTEZGQlFUUkNPMGxCUTNCRExFdEJRVXNzVFVGQlRUdE5RVUZGVkN4TFFVRkxPMDFCUVVWUUxFOUJRVTg3VFVGQlJVTTdTVUZCVFN4RFFVRkZMRWxCUVVsbExGRkJRVkVzUlVGRE4wTXNTVUZCU1N4RFFVRkRaQ3hIUVVGSExFTkJRVU5MTEV0QlFVc3NSVUZCUlZBc1QwRkJUeXhGUVVGRkxFZEJRVWRETEUxQlFVMHNRMEZCUXp0RlFVTXpRenM3UVVGRFNGTXNUMEZCUVN4RFFVRkJSU3haUVVGQkxFZEJRVUZCTEZsQlFVRWlMQ0pwWjI1dmNtVk1hWE4wSWpwYlhYMD0iLCJcInVzZSBzdHJpY3RcIjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuY2xvbmVUZW1wbGF0ZSA9IGNsb25lVGVtcGxhdGU7XG5leHBvcnRzLmVsZW1lbnRXaXRoQWJzb2x1dGVQYXRocyA9IGVsZW1lbnRXaXRoQWJzb2x1dGVQYXRocztcbmV4cG9ydHMuZ2V0RWxlbWVudEJ5SWQgPSBnZXRFbGVtZW50QnlJZDtcbmV4cG9ydHMuZ2V0SFRNTCA9IGdldEhUTUw7XG5leHBvcnRzLmdldFNsb3QgPSBnZXRTbG90O1xuZXhwb3J0cy5zZXRTbG90VGV4dCA9IHNldFNsb3RUZXh0O1xudmFyIF9hc3NlcnQgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCJhc3NlcnRcIikpO1xudmFyIF91dGlscyA9IHJlcXVpcmUoXCIuLi8uLi91dGlscy5qc1wiKTtcbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoZSkgeyByZXR1cm4gZSAmJiBlLl9fZXNNb2R1bGUgPyBlIDogeyBkZWZhdWx0OiBlIH07IH1cbi8vIEhvbWVicmlkZ2UgcGx1Z2luIGZvciBIb21lIENvbm5lY3QgaG9tZSBhcHBsaWFuY2VzXG4vLyBDb3B5cmlnaHQgwqkgMjAyMy0yMDI2IEFsZXhhbmRlciBUaG91a3lkaWRlc1xuXG4vLyBHZXQgYW4gSFRNTCBlbGVtZW50IGJ5IGl0cyBcImlkXCIgYXR0cmlidXRlXG5mdW5jdGlvbiBnZXRFbGVtZW50QnlJZChlbGVtZW50SWQpIHtcbiAgY29uc3QgZWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGVsZW1lbnRJZCk7XG4gICgwLCBfdXRpbHMuYXNzZXJ0SXNJbnN0YW5jZU9mKShlbGVtZW50LCBIVE1MRWxlbWVudCk7XG4gIHJldHVybiBlbGVtZW50O1xufVxuLy8gR2V0IGFuIEhUTUwgZWxlbWVudCB1c2luZyBhIHNsb3QgbmFtZVxuZnVuY3Rpb24gZ2V0U2xvdCh3aXRoaW4sIHNsb3ROYW1lKSB7XG4gIGNvbnN0IHNsb3RzID0gd2l0aGluLnF1ZXJ5U2VsZWN0b3JBbGwoYFtzbG90PVwiJHtzbG90TmFtZX1cIl1gKTtcbiAgX2Fzc2VydC5kZWZhdWx0LmVxdWFsKHNsb3RzLmxlbmd0aCwgMSwgYEV4cGVjdGVkIGV4YWN0bHkgb25lIHNsb3Qgd2l0aCBuYW1lIFwiJHtzbG90TmFtZX1cImApO1xuICAoMCwgX3V0aWxzLmFzc2VydElzSW5zdGFuY2VPZikoc2xvdHNbMF0sIEhUTUxFbGVtZW50KTtcbiAgcmV0dXJuIHNsb3RzWzBdO1xufVxuLy8gU2V0IHRoZSB0ZXh0IGNvbnRlbnQgb2YgbXVsdGlwbGUgc2xvdCBlbGVtZW50c1xuZnVuY3Rpb24gc2V0U2xvdFRleHQod2l0aGluLCBzbG90VGV4dCkge1xuICBmb3IgKGNvbnN0IFtzbG90TmFtZSwgdGV4dF0gb2YgT2JqZWN0LmVudHJpZXMoc2xvdFRleHQpKSBnZXRTbG90KHdpdGhpbiwgc2xvdE5hbWUpLnRleHRDb250ZW50ID0gdGV4dDtcbn1cbi8vIENyZWF0ZSBhIGNvcHkgb2YgYSB0ZW1wbGF0ZSBlbGVtZW50XG5mdW5jdGlvbiBjbG9uZVRlbXBsYXRlKGVsZW1lbnRJZCwgc2xvdFRleHQpIHtcbiAgLy8gRmluZCB0aGUgdGVtcGxhdGUgZWxlbWVudFxuICBjb25zdCB0ZW1wbGF0ZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGVsZW1lbnRJZCk7XG4gICgwLCBfdXRpbHMuYXNzZXJ0SXNJbnN0YW5jZU9mKSh0ZW1wbGF0ZSwgSFRNTFRlbXBsYXRlRWxlbWVudCk7XG4gIC8vIENsb25lIHRoZSB0ZW1wbGF0ZSdzIGRvY3VtZW50LWZyYWdtZW50IGFuZCBzZXQgc2xvdCB2YWx1ZXNcbiAgY29uc3QgZG9jdW1lbnRGcmFnbWVudCA9IHRlbXBsYXRlLmNvbnRlbnQuY2xvbmVOb2RlKHRydWUpO1xuICAoMCwgX3V0aWxzLmFzc2VydElzSW5zdGFuY2VPZikoZG9jdW1lbnRGcmFnbWVudCwgRG9jdW1lbnRGcmFnbWVudCk7XG4gIGlmIChzbG90VGV4dCkgc2V0U2xvdFRleHQoZG9jdW1lbnRGcmFnbWVudCwgc2xvdFRleHQpO1xuICByZXR1cm4gZG9jdW1lbnRGcmFnbWVudDtcbn1cbi8vIE1ha2UgVVJJIHBhdGhzIGFic29sdXRlXG5mdW5jdGlvbiBlbGVtZW50V2l0aEFic29sdXRlUGF0aHMoZnJhZ21lbnQpIHtcbiAgZm9yIChjb25zdCBhdHRyaWJ1dGUgb2YgWydocmVmJywgJ3NyYyddKSB7XG4gICAgY29uc3QgZWxlbWVudHMgPSBmcmFnbWVudC5xdWVyeVNlbGVjdG9yQWxsKGBbJHthdHRyaWJ1dGV9XWApO1xuICAgIGZvciAoY29uc3QgZWxlbWVudCBvZiBBcnJheS5mcm9tKGVsZW1lbnRzKSkge1xuICAgICAgY29uc3QgcGF0aCA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKGF0dHJpYnV0ZSk7XG4gICAgICAoMCwgX3V0aWxzLmFzc2VydElzRGVmaW5lZCkocGF0aCk7XG4gICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZShhdHRyaWJ1dGUsIG5ldyBVUkwocGF0aCwgbG9jYXRpb24uaHJlZikuaHJlZik7XG4gICAgfVxuICB9XG4gIHJldHVybiBmcmFnbWVudDtcbn1cbi8vIE9idGFpbiB0aGUgSFRNTCBzZXJpYWxpemF0aW9uIG9mIGEgdGVtcGxhdGUgZWxlbWVudFxuZnVuY3Rpb24gZ2V0SFRNTChmcmFnbWVudCkge1xuICBjb25zdCBzZXJpYWxpemVyID0gbmV3IFhNTFNlcmlhbGl6ZXIoKTtcbiAgcmV0dXJuIHNlcmlhbGl6ZXIuc2VyaWFsaXplVG9TdHJpbmcoZnJhZ21lbnQpO1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ9dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p1WVcxbGN5STZXeUpmWVhOelpYSjBJaXdpWDJsdWRHVnliM0JTWlhGMWFYSmxSR1ZtWVhWc2RDSXNJbkpsY1hWcGNtVWlMQ0pmZFhScGJITWlMQ0psSWl3aVgxOWxjMDF2WkhWc1pTSXNJbVJsWm1GMWJIUWlMQ0puWlhSRmJHVnRaVzUwUW5sSlpDSXNJbVZzWlcxbGJuUkpaQ0lzSW1Wc1pXMWxiblFpTENKa2IyTjFiV1Z1ZENJc0ltRnpjMlZ5ZEVselNXNXpkR0Z1WTJWUFppSXNJa2hVVFV4RmJHVnRaVzUwSWl3aVoyVjBVMnh2ZENJc0luZHBkR2hwYmlJc0luTnNiM1JPWVcxbElpd2ljMnh2ZEhNaUxDSnhkV1Z5ZVZObGJHVmpkRzl5UVd4c0lpd2lZWE56WlhKMElpd2laWEYxWVd3aUxDSnNaVzVuZEdnaUxDSnpaWFJUYkc5MFZHVjRkQ0lzSW5Oc2IzUlVaWGgwSWl3aWRHVjRkQ0lzSWs5aWFtVmpkQ0lzSW1WdWRISnBaWE1pTENKMFpYaDBRMjl1ZEdWdWRDSXNJbU5zYjI1bFZHVnRjR3hoZEdVaUxDSjBaVzF3YkdGMFpTSXNJa2hVVFV4VVpXMXdiR0YwWlVWc1pXMWxiblFpTENKa2IyTjFiV1Z1ZEVaeVlXZHRaVzUwSWl3aVkyOXVkR1Z1ZENJc0ltTnNiMjVsVG05a1pTSXNJa1J2WTNWdFpXNTBSbkpoWjIxbGJuUWlMQ0psYkdWdFpXNTBWMmwwYUVGaWMyOXNkWFJsVUdGMGFITWlMQ0ptY21GbmJXVnVkQ0lzSW1GMGRISnBZblYwWlNJc0ltVnNaVzFsYm5Seklpd2lRWEp5WVhraUxDSm1jbTl0SWl3aWNHRjBhQ0lzSW1kbGRFRjBkSEpwWW5WMFpTSXNJbUZ6YzJWeWRFbHpSR1ZtYVc1bFpDSXNJbk5sZEVGMGRISnBZblYwWlNJc0lsVlNUQ0lzSW14dlkyRjBhVzl1SWl3aWFISmxaaUlzSW1kbGRFaFVUVXdpTENKelpYSnBZV3hwZW1WeUlpd2lXRTFNVTJWeWFXRnNhWHBsY2lJc0luTmxjbWxoYkdsNlpWUnZVM1J5YVc1bklsMHNJbk52ZFhKalpYTWlPbHNpTGk0dkxpNHZMaTR2YzNKakwyaHZiV1ZpY21sa1oyVXRkV2t2Y0hWaWJHbGpMM1YwYVd4ekxXUnZiUzUwY3lKZExDSnpiM1Z5WTJWelEyOXVkR1Z1ZENJNlcyNTFiR3hkTENKdFlYQndhVzVuY3lJNklqczdPenM3T3pzN096czdRVUZIUVN4SlFVRkJRU3hQUVVGQkxFZEJRVUZETEhOQ1FVRkJMRU5CUVVGRExFOUJRVUU3UVVGRlFTeEpRVUZCUXl4TlFVRkJMRWRCUVVGRUxFOUJRVUU3UVVGQmNVVXNVMEZCUVVRc2RVSkJRVUZITEVOQlFVRXNWMEZCUVVFc1EwRkJRU3hKUVVGQlFTeERRVUZCTEVOQlFVRkRMRlZCUVVFc1IwRkJRVVFzUTBGQlFTeExRVUZCUlN4UFFVRkJMRVZCUVVGR0xFTkJRVUU3UVVGTWNrVTdRVUZEUVRzN1FVRlhRVHRCUVVOTkxGTkJRVlZITEdOQlFXTkJMRU5CUVVORExGTkJRV2xDTzBWQlF6VkRMRTFCUVUxRExFOUJRVThzUjBGQlIwTXNVVUZCVVN4RFFVRkRTQ3hqUVVGakxFTkJRVU5ETEZOQlFWTXNRMEZCUXp0RlFVTnNSQ3hKUVVGQlJ5eDVRa0ZCYTBJc1JVRkJRMFlzVDBGQlR5eEZRVUZGUnl4WFFVRlhMRU5CUVVNN1JVRkRlRU1zVDBGQlQwZ3NUMEZCVHp0QlFVTnNRanRCUVVWQk8wRkJRMDBzVTBGQlZVa3NUMEZCVDBFc1EwRkJRME1zVFVGQmQwSXNSVUZCUlVNc1VVRkJaMEk3UlVGRE9VUXNUVUZCVFVNc1MwRkJTeXhIUVVGSFJpeE5RVUZOTEVOQlFVTkhMR2RDUVVGblFpeERRVUZETEZWQlFWVkdMRkZCUVZFc1NVRkJTU3hEUVVGRE8wVkJRemRFUnl4bFFVRk5MRU5CUVVORExFdEJRVXNzUTBGQlEwZ3NTMEZCU3l4RFFVRkRTU3hOUVVGTkxFVkJRVVVzUTBGQlF5eEZRVUZGTEhkRFFVRjNRMHdzVVVGQlVTeEhRVUZITEVOQlFVTTdSVUZEYkVZc1NVRkJRVW9zZVVKQlFXdENMRVZCUVVOTExFdEJRVXNzUTBGQlF5eERRVUZETEVOQlFVTXNSVUZCUlVvc1YwRkJWeXhEUVVGRE8wVkJRM3BETEU5QlFVOUpMRXRCUVVzc1EwRkJReXhEUVVGRExFTkJRVU03UVVGRGJrSTdRVUZGUVR0QlFVTk5MRk5CUVZWTExGZEJRVmRCTEVOQlFVTlFMRTFCUVhkQ0xFVkJRVVZSTEZGQlFXZERPMFZCUTJ4R0xFdEJRVXNzVFVGQlRTeERRVUZEVUN4UlFVRlJMRVZCUVVWUkxFbEJRVWtzUTBGQlF5eEpRVUZKUXl4TlFVRk5MRU5CUVVORExFOUJRVThzUTBGQlEwZ3NVVUZCVVN4RFFVRkRMRVZCUTI1RVZDeFBRVUZQTEVOQlFVTkRMRTFCUVUwc1JVRkJSVU1zVVVGQlVTeERRVUZETEVOQlFVTlhMRmRCUVZjc1IwRkJSMGdzU1VGQlNUdEJRVU53UkR0QlFVVkJPMEZCUTAwc1UwRkJWVWtzWVVGQllVRXNRMEZCUTI1Q0xGTkJRV2xDTEVWQlFVVmpMRkZCUVdsRE8wVkJRemxGTzBWQlEwRXNUVUZCVFUwc1VVRkJVU3hIUVVGSGJFSXNVVUZCVVN4RFFVRkRTQ3hqUVVGakxFTkJRVU5ETEZOQlFWTXNRMEZCUXp0RlFVTnVSQ3hKUVVGQlJ5eDVRa0ZCYTBJc1JVRkJRMmxDTEZGQlFWRXNSVUZCUlVNc2JVSkJRVzFDTEVOQlFVTTdSVUZGYWtRN1JVRkRRU3hOUVVGTlF5eG5Ra0ZCWjBJc1IwRkJSMFlzVVVGQlVTeERRVUZEUnl4UFFVRlBMRU5CUVVORExGTkJRVk1zUTBGQlF5eEpRVUZKTEVOQlFVTTdSVUZEZWtRc1NVRkJRWEpDTEhsQ1FVRnJRaXhGUVVGRGJVSXNaMEpCUVdkQ0xFVkJRVVZITEdkQ1FVRm5RaXhEUVVGRE8wVkJRM1JFTEVsQlFVbFlMRkZCUVZFc1JVRkJSVVFzVjBGQlZ5eERRVUZEVXl4blFrRkJaMElzUlVGQlJWSXNVVUZCVVN4RFFVRkRPMFZCUTNKRUxFOUJRVTlSTEdkQ1FVRm5RanRCUVVNelFqdEJRVVZCTzBGQlEwMHNVMEZCVlVrc2QwSkJRWGRDUVN4RFFVRm5RME1zVVVGQll6dEZRVU5zUml4TFFVRkxMRTFCUVUxRExGTkJRVk1zU1VGQlNTeERRVUZETEUxQlFVMHNSVUZCUlN4TFFVRkxMRU5CUVVNc1JVRkJSVHRKUVVOeVF5eE5RVUZOUXl4UlFVRlJMRWRCUVVkR0xGRkJRVkVzUTBGQlEyeENMR2RDUVVGblFpeERRVUZETEVsQlFVbHRRaXhUUVVGVExFZEJRVWNzUTBGQlF6dEpRVU0xUkN4TFFVRkxMRTFCUVUwelFpeFBRVUZQTEVsQlFVazJRaXhMUVVGTExFTkJRVU5ETEVsQlFVa3NRMEZCUTBZc1VVRkJVU3hEUVVGRExFVkJRVVU3VFVGRGVFTXNUVUZCVFVjc1NVRkJTU3hIUVVGSEwwSXNUMEZCVHl4RFFVRkRaME1zV1VGQldTeERRVUZEVEN4VFFVRlRMRU5CUVVNN1RVRkROVU1zU1VGQlFVMHNjMEpCUVdVc1JVRkJRMFlzU1VGQlNTeERRVUZETzAxQlEzSkNMMElzVDBGQlR5eERRVUZEYTBNc1dVRkJXU3hEUVVGRFVDeFRRVUZUTEVWQlFVVXNTVUZCU1ZFc1IwRkJSeXhEUVVGRFNpeEpRVUZKTEVWQlFVVkxMRkZCUVZFc1EwRkJRME1zU1VGQlNTeERRVUZETEVOQlFVTkJMRWxCUVVrc1EwRkJRenRKUVVOMFJUdEZRVU5LTzBWQlEwRXNUMEZCVDFnc1VVRkJVVHRCUVVOdVFqdEJRVVZCTzBGQlEwMHNVMEZCVlZrc1QwRkJUMEVzUTBGQlExb3NVVUZCWXp0RlFVTnNReXhOUVVGTllTeFZRVUZWTEVkQlFVY3NTVUZCU1VNc1lVRkJZU3hGUVVGRk8wVkJRM1JETEU5QlFVOUVMRlZCUVZVc1EwRkJRMFVzYVVKQlFXbENMRU5CUVVObUxGRkJRVkVzUTBGQlF6dEJRVU5xUkNJc0ltbG5ibTl5WlV4cGMzUWlPbHRkZlE9PSIsIlwidXNlIHN0cmljdFwiO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5kZXRhY2hlZCA9IGRldGFjaGVkO1xuZXhwb3J0cy5sb2dFcnJvciA9IGxvZ0Vycm9yO1xudmFyIF9hcGlFcnJvcnMgPSByZXF1aXJlKFwiLi9hcGktZXJyb3JzLmpzXCIpO1xuLy8gSG9tZWJyaWRnZSBwbHVnaW4gZm9yIEhvbWUgQ29ubmVjdCBob21lIGFwcGxpYW5jZXNcbi8vIENvcHlyaWdodCDCqSAyMDIzLTIwMjYgQWxleGFuZGVyIFRob3VreWRpZGVzXG5cbi8vIExvZyBhbiBlcnJvclxubGV0IGxhc3RMb2dnZWRFcnJvcjtcbmZ1bmN0aW9uIGxvZ0Vycm9yKGxvZywgd2hlbiwgZXJyKSB7XG4gIHRyeSB7XG4gICAgLy8gU3VwcHJlc3MgZHVwbGljYXRlIHJlcG9ydHNcbiAgICBpZiAobGFzdExvZ2dlZEVycm9yID09PSBlcnIpIHJldHVybiBlcnI7XG4gICAgbGFzdExvZ2dlZEVycm9yID0gZXJyO1xuICAgIC8vIExvZyB0aGUgdG9wLWxldmVsIGVycm9yIG1lc3NhZ2VcbiAgICBjb25zdCBtZXNzYWdlID0gZXJyIGluc3RhbmNlb2YgRXJyb3IgPyBgJHtlcnIubmFtZX06ICR7ZXJyLm1lc3NhZ2V9YCA6IFN0cmluZyhlcnIpO1xuICAgIGxvZy5lcnJvcihgWyR7d2hlbn1dICR7bWVzc2FnZX1gKTtcbiAgICBjb25zdCBwcmVmaXggPSAnICcucmVwZWF0KHdoZW4ubGVuZ3RoICsgMyk7XG4gICAgLy8gTG9nIHRoZSByZXF1ZXN0IGRldGFpbHMgZm9yIEFQSSBlcnJvcnNcbiAgICBpZiAoZXJyIGluc3RhbmNlb2YgX2FwaUVycm9ycy5BUElFcnJvcikge1xuICAgICAgbG9nLmVycm9yKGAke2Vyci5yZXF1ZXN0Lm1ldGhvZH0gJHtlcnIucmVxdWVzdC5wYXRofWApO1xuICAgIH1cbiAgICAvLyBMb2cgYW55IGhpc3Rvcnkgb2YgY2F1c2VzIG9yIHN1Yi1lcnJvcnNcbiAgICBsb2dTdWJFcnJvcnMobG9nLCBwcmVmaXgsIGVycik7XG4gICAgLy8gTG9nIGFueSBzdGFjayBiYWNrdHJhY2UgKGZvciB0aGUgdG9wLWxldmVsIGVycm9yIG9ubHkpXG4gICAgaWYgKGVyciBpbnN0YW5jZW9mIEVycm9yICYmIGVyci5zdGFjaykgbG9nLmRlYnVnKGVyci5zdGFjayk7XG4gIH0gY2F0Y2ggey8qIGVtcHR5ICovfVxuICByZXR1cm4gZXJyO1xufVxuLy8gVHJhcCBhbnkgZGV0YWNoZWQgcHJvbWlzZSByZWplY3Rpb25zXG5mdW5jdGlvbiBkZXRhY2hlZChsb2csIHdoZW4sIGZuKSB7XG4gIHJldHVybiAoLi4uYXJncykgPT4ge1xuICAgIGZuKC4uLmFyZ3MpPy5jYXRjaChlcnIgPT4gbG9nRXJyb3IobG9nLCB3aGVuLCBlcnIpKTtcbiAgfTtcbn1cbi8vIExvZyBhbnkgc3ViLWVycm9ycyAoY2F1c2VzIG9yIGFnZ3JlZ2F0ZXMpIG9mIGFuIGVycm9yLCBmb3JtYXR0ZWQgYXMgYSB0cmVlXG5mdW5jdGlvbiBsb2dTdWJFcnJvcnMobG9nLCBwcmVmaXgsIGVycikge1xuICAvLyBDb2xsZWN0IGFsbCBhZ2dyZWdhdGUgb3IgY2F1c2FsIGVycm9yc1xuICBjb25zdCBzdWJFcnJzID0gW107XG4gIGlmIChlcnIgaW5zdGFuY2VvZiBfYXBpRXJyb3JzLkFQSUVycm9yICYmIGVyci5lcnJDYXVzZSkgc3ViRXJycy5wdXNoKGVyci5lcnJDYXVzZSk7XG4gIGlmIChlcnIgaW5zdGFuY2VvZiBFcnJvciAmJiBlcnIuY2F1c2UpIHN1YkVycnMucHVzaChlcnIuY2F1c2UpO1xuICBpZiAoZXJyIGluc3RhbmNlb2YgQWdncmVnYXRlRXJyb3IgJiYgQXJyYXkuaXNBcnJheShlcnIuZXJyb3JzKSkgc3ViRXJycy5wdXNoKC4uLmVyci5lcnJvcnMpO1xuICAvLyBMb2cgdGhlIGNvbGxlY3RlZCBlcnJvcnMgZm9ybWF0dGVkIGFzIGEgdHJlZVxuICBzdWJFcnJzLmZvckVhY2goKHN1YkVyciwgaW5kZXgpID0+IHtcbiAgICBjb25zdCBzdWJQcmVmaXggPSBpbmRleCA8IHN1YkVycnMubGVuZ3RoIC0gMSA/IFsn4pSc4pSAJywgJ+KUgiAnXSA6IFsn4pSU4pSAJywgJyAgJ107XG4gICAgY29uc3QgbWVzc2FnZSA9IHN1YkVyciBpbnN0YW5jZW9mIEVycm9yID8gYCR7c3ViRXJyLm5hbWV9OiAke3N1YkVyci5tZXNzYWdlfWAgOiBTdHJpbmcoc3ViRXJyKTtcbiAgICBsb2cuZXJyb3IoYCR7cHJlZml4fSR7c3ViUHJlZml4WzBdfSAke21lc3NhZ2V9YCk7XG4gICAgbG9nU3ViRXJyb3JzKGxvZywgYCR7cHJlZml4fSR7c3ViUHJlZml4WzFdfSBgLCBzdWJFcnIpO1xuICB9KTtcbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRhdGE6YXBwbGljYXRpb24vanNvbjtjaGFyc2V0PXV0Zi04O2Jhc2U2NCxleUoyWlhKemFXOXVJam96TENKdVlXMWxjeUk2V3lKZllYQnBSWEp5YjNKeklpd2ljbVZ4ZFdseVpTSXNJbXhoYzNSTWIyZG5aV1JGY25KdmNpSXNJbXh2WjBWeWNtOXlJaXdpYkc5bklpd2lkMmhsYmlJc0ltVnljaUlzSW0xbGMzTmhaMlVpTENKRmNuSnZjaUlzSW01aGJXVWlMQ0pUZEhKcGJtY2lMQ0psY25KdmNpSXNJbkJ5WldacGVDSXNJbkpsY0dWaGRDSXNJbXhsYm1kMGFDSXNJa0ZRU1VWeWNtOXlJaXdpY21WeGRXVnpkQ0lzSW0xbGRHaHZaQ0lzSW5CaGRHZ2lMQ0pzYjJkVGRXSkZjbkp2Y25NaUxDSnpkR0ZqYXlJc0ltUmxZblZuSWl3aVpHVjBZV05vWldRaUxDSm1iaUlzSW1GeVozTWlMQ0pqWVhSamFDSXNJbk4xWWtWeWNuTWlMQ0psY25KRFlYVnpaU0lzSW5CMWMyZ2lMQ0pqWVhWelpTSXNJa0ZuWjNKbFoyRjBaVVZ5Y205eUlpd2lRWEp5WVhraUxDSnBjMEZ5Y21GNUlpd2laWEp5YjNKeklpd2labTl5UldGamFDSXNJbk4xWWtWeWNpSXNJbWx1WkdWNElpd2ljM1ZpVUhKbFptbDRJbDBzSW5OdmRYSmpaWE1pT2xzaUxpNHZjM0pqTDJ4dlp5MWxjbkp2Y2k1MGN5SmRMQ0p6YjNWeVkyVnpRMjl1ZEdWdWRDSTZXMjUxYkd4ZExDSnRZWEJ3YVc1bmN5STZJanM3T3pzN096dEJRVXRCTEVsQlFVRkJMRlZCUVVFc1IwRkJRVU1zVDBGQlFUdEJRVXhCTzBGQlEwRTdPMEZCVDBFN1FVRkRRU3hKUVVGSlF5eGxRVUYzUWp0QlFVTjBRaXhUUVVGVlF5eFJRVUZSUVN4RFFVRlBReXhIUVVGWExFVkJRVVZETEVsQlFWa3NSVUZCUlVNc1IwRkJVenRGUVVNdlJDeEpRVUZKTzBsQlEwRTdTVUZEUVN4SlFVRkpTaXhsUVVGbExFdEJRVXRKTEVkQlFVY3NSVUZCUlN4UFFVRlBRU3hIUVVGSE8wbEJRM1pEU2l4bFFVRmxMRWRCUVVkSkxFZEJRVWM3U1VGRmNrSTdTVUZEUVN4TlFVRk5ReXhQUVVGUExFZEJRVWRFTEVkQlFVY3NXVUZCV1VVc1MwRkJTeXhIUVVGSExFZEJRVWRHTEVkQlFVY3NRMEZCUTBjc1NVRkJTU3hMUVVGTFNDeEhRVUZITEVOQlFVTkRMRTlCUVU4c1JVRkJSU3hIUVVGSFJ5eE5RVUZOTEVOQlFVTktMRWRCUVVjc1EwRkJRenRKUVVOc1JrWXNSMEZCUnl4RFFVRkRUeXhMUVVGTExFTkJRVU1zU1VGQlNVNHNTVUZCU1N4TFFVRkxSU3hQUVVGUExFVkJRVVVzUTBGQlF6dEpRVU5xUXl4TlFVRk5TeXhOUVVGTkxFZEJRVWNzUjBGQlJ5eERRVUZEUXl4TlFVRk5MRU5CUVVOU0xFbEJRVWtzUTBGQlExTXNUVUZCVFN4SFFVRkhMRU5CUVVNc1EwRkJRenRKUVVVeFF6dEpRVU5CTEVsQlFVbFNMRWRCUVVjc1dVRkJXVk1zYlVKQlFWRXNSVUZCUlR0TlFVTjZRbGdzUjBGQlJ5eERRVUZEVHl4TFFVRkxMRU5CUVVNc1IwRkJSMHdzUjBGQlJ5eERRVUZEVlN4UFFVRlBMRU5CUVVORExFMUJRVTBzU1VGQlNWZ3NSMEZCUnl4RFFVRkRWU3hQUVVGUExFTkJRVU5GTEVsQlFVa3NSVUZCUlN4RFFVRkRPMGxCUXpGRU8wbEJSVUU3U1VGRFFVTXNXVUZCV1N4RFFVRkRaaXhIUVVGSExFVkJRVVZSTEUxQlFVMHNSVUZCUlU0c1IwRkJSeXhEUVVGRE8wbEJSVGxDTzBsQlEwRXNTVUZCU1VFc1IwRkJSeXhaUVVGWlJTeExRVUZMTEVsQlFVbEdMRWRCUVVjc1EwRkJRMk1zUzBGQlN5eEZRVUZGYUVJc1IwRkJSeXhEUVVGRGFVSXNTMEZCU3l4RFFVRkRaaXhIUVVGSExFTkJRVU5qTEV0QlFVc3NRMEZCUXp0RlFVTXZSQ3hEUVVGRExFTkJRVU1zVFVGQlRTeERRVUZGTzBWQlExWXNUMEZCVDJRc1IwRkJSenRCUVVOa08wRkJSVUU3UVVGRFRTeFRRVUZWWjBJc1VVRkJVVUVzUTBGRGNFSnNRaXhIUVVGakxFVkJRMlJETEVsQlFXTXNSVUZEWkd0Q0xFVkJRWFZETzBWQlJYWkRMRTlCUVU4c1EwRkJReXhIUVVGSFF5eEpRVUZWTEV0QlFVazdTVUZEY2tKRUxFVkJRVVVzUTBGQlF5eEhRVUZIUXl4SlFVRkpMRU5CUVVNc1JVRkJSVU1zUzBGQlN5eERRVUZGYmtJc1IwRkJXU3hKUVVGTFNDeFJRVUZSTEVOQlFVTkRMRWRCUVVjc1JVRkJSVU1zU1VGQlNTeEZRVUZGUXl4SFFVRkhMRU5CUVVNc1EwRkJRenRGUVVOc1JTeERRVUZETzBGQlEwdzdRVUZGUVR0QlFVTkJMRk5CUVZOaExGbEJRVmxCTEVOQlFVTm1MRWRCUVZjc1JVRkJSVkVzVFVGQll5eEZRVUZGVGl4SFFVRlpPMFZCUXpORU8wVkJRMEVzVFVGQlRXOUNMRTlCUVU4c1IwRkJZeXhGUVVGRk8wVkJRemRDTEVsQlFVbHdRaXhIUVVGSExGbEJRVmxUTEcxQ1FVRlJMRWxCUVVsVUxFZEJRVWNzUTBGQlEzRkNMRkZCUVZFc1JVRkJSVVFzVDBGQlR5eERRVUZEUlN4SlFVRkpMRU5CUVVOMFFpeEhRVUZITEVOQlFVTnhRaXhSUVVGUkxFTkJRVU03UlVGRGRrVXNTVUZCU1hKQ0xFZEJRVWNzV1VGQldVVXNTMEZCU3l4SlFVRkpSaXhIUVVGSExFTkJRVU4xUWl4TFFVRkxMRVZCUVVWSUxFOUJRVThzUTBGQlEwVXNTVUZCU1N4RFFVRkRkRUlzUjBGQlJ5eERRVUZEZFVJc1MwRkJTeXhEUVVGRE8wVkJRemxFTEVsQlFVbDJRaXhIUVVGSExGbEJRVmwzUWl4alFVRmpMRWxCUVVsRExFdEJRVXNzUTBGQlEwTXNUMEZCVHl4RFFVRkRNVUlzUjBGQlJ5eERRVUZETWtJc1RVRkJUU3hEUVVGRExFVkJRVVZRTEU5QlFVOHNRMEZCUTBVc1NVRkJTU3hEUVVGRExFZEJRVWwwUWl4SFFVRkhMRU5CUVVNeVFpeE5RVUZ2UWl4RFFVRkRPMFZCUlRGSE8wVkJRMEZRTEU5QlFVOHNRMEZCUTFFc1QwRkJUeXhEUVVGRExFTkJRVU5ETEUxQlFVMHNSVUZCUlVNc1MwRkJTeXhMUVVGSk8wbEJRemxDTEUxQlFVMURMRk5CUVZNc1IwRkJSMFFzUzBGQlN5eEhRVUZIVml4UFFVRlBMRU5CUVVOYUxFMUJRVTBzUjBGQlJ5eERRVUZETEVkQlFVY3NRMEZCUXl4SlFVRkpMRVZCUVVVc1NVRkJTU3hEUVVGRExFZEJRVWNzUTBGQlF5eEpRVUZKTEVWQlFVVXNTVUZCU1N4RFFVRkRPMGxCUXpGRkxFMUJRVTFRTEU5QlFVOHNSMEZCUnpSQ0xFMUJRVTBzV1VGQldUTkNMRXRCUVVzc1IwRkJSeXhIUVVGSE1rSXNUVUZCVFN4RFFVRkRNVUlzU1VGQlNTeExRVUZMTUVJc1RVRkJUU3hEUVVGRE5VSXNUMEZCVHl4RlFVRkZMRWRCUVVkSExFMUJRVTBzUTBGQlEzbENMRTFCUVUwc1EwRkJRenRKUVVNNVJpOUNMRWRCUVVjc1EwRkJRMDhzUzBGQlN5eERRVUZETEVkQlFVZERMRTFCUVUwc1IwRkJSM2xDTEZOQlFWTXNRMEZCUXl4RFFVRkRMRU5CUVVNc1NVRkJTVGxDTEU5QlFVOHNSVUZCUlN4RFFVRkRPMGxCUTJoRVdTeFpRVUZaTEVOQlFVTm1MRWRCUVVjc1JVRkJSU3hIUVVGSFVTeE5RVUZOTEVkQlFVZDVRaXhUUVVGVExFTkJRVU1zUTBGQlF5eERRVUZETEVkQlFVY3NSVUZCUlVZc1RVRkJUU3hEUVVGRE8wVkJRekZFTEVOQlFVTXNRMEZCUXp0QlFVTk9JaXdpYVdkdWIzSmxUR2x6ZENJNlcxMTkiLCJcInVzZSBzdHJpY3RcIjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IGV4cG9ydHMuU2NvcGUgPSBleHBvcnRzLlBlcnNpc3RBYnNvbHV0ZVRva2VucyA9IGV4cG9ydHMuRGV2aWNlQXV0aG9yaXNhdGlvblJlc3BvbnNlID0gZXhwb3J0cy5EZXZpY2VBdXRob3Jpc2F0aW9uUmVxdWVzdCA9IGV4cG9ydHMuRGV2aWNlQWNjZXNzVG9rZW5SZXNwb25zZSA9IGV4cG9ydHMuRGV2aWNlQWNjZXNzVG9rZW5SZXF1ZXN0ID0gZXhwb3J0cy5BdXRob3Jpc2F0aW9uU3RhdGUgPSBleHBvcnRzLkF1dGhvcmlzYXRpb25SZXNwb25zZSA9IGV4cG9ydHMuQXV0aG9yaXNhdGlvblJlcXVlc3QgPSBleHBvcnRzLkF1dGhvcmlzYXRpb25FcnJvciA9IGV4cG9ydHMuQWNjZXNzVG9rZW5SZXNwb25zZSA9IGV4cG9ydHMuQWNjZXNzVG9rZW5SZXF1ZXN0ID0gZXhwb3J0cy5BY2Nlc3NUb2tlblJlZnJlc2hSZXNwb25zZSA9IGV4cG9ydHMuQWNjZXNzVG9rZW5SZWZyZXNoUmVxdWVzdCA9IGV4cG9ydHMuQWJzb2x1dGVUb2tlbiA9IHZvaWQgMDtcbnZhciB0ID0gX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQocmVxdWlyZShcInRzLWludGVyZmFjZS1jaGVja2VyXCIpKTtcbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkKGUsIHQpIHsgaWYgKFwiZnVuY3Rpb25cIiA9PSB0eXBlb2YgV2Vha01hcCkgdmFyIHIgPSBuZXcgV2Vha01hcCgpLCBuID0gbmV3IFdlYWtNYXAoKTsgcmV0dXJuIChfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCA9IGZ1bmN0aW9uIChlLCB0KSB7IGlmICghdCAmJiBlICYmIGUuX19lc01vZHVsZSkgcmV0dXJuIGU7IHZhciBvLCBpLCBmID0geyBfX3Byb3RvX186IG51bGwsIGRlZmF1bHQ6IGUgfTsgaWYgKG51bGwgPT09IGUgfHwgXCJvYmplY3RcIiAhPSB0eXBlb2YgZSAmJiBcImZ1bmN0aW9uXCIgIT0gdHlwZW9mIGUpIHJldHVybiBmOyBpZiAobyA9IHQgPyBuIDogcikgeyBpZiAoby5oYXMoZSkpIHJldHVybiBvLmdldChlKTsgby5zZXQoZSwgZik7IH0gZm9yIChjb25zdCB0IGluIGUpIFwiZGVmYXVsdFwiICE9PSB0ICYmIHt9Lmhhc093blByb3BlcnR5LmNhbGwoZSwgdCkgJiYgKChpID0gKG8gPSBPYmplY3QuZGVmaW5lUHJvcGVydHkpICYmIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoZSwgdCkpICYmIChpLmdldCB8fCBpLnNldCkgPyBvKGYsIHQsIGkpIDogZlt0XSA9IGVbdF0pOyByZXR1cm4gZjsgfSkoZSwgdCk7IH1cbi8qKlxuICogVGhpcyBtb2R1bGUgd2FzIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IGB0cy1pbnRlcmZhY2UtYnVpbGRlcmBcbiAqL1xuXG4vLyB0c2xpbnQ6ZGlzYWJsZTpvYmplY3QtbGl0ZXJhbC1rZXktcXVvdGVzXG5jb25zdCBTY29wZSA9IGV4cG9ydHMuU2NvcGUgPSB0LnVuaW9uKHQubGl0KCdNb25pdG9yJyksIHQubGl0KCdDb250cm9sJyksIHQubGl0KCdTZXR0aW5ncycpLCB0LmxpdCgnSW1hZ2VzJyksIHQubGl0KCdBaXJDb25kaXRpb25lcicpLCB0LmxpdCgnQWlyQ29uZGl0aW9uZXItTW9uaXRvcicpLCB0LmxpdCgnQWlyQ29uZGl0aW9uZXItQ29udHJvbCcpLCB0LmxpdCgnQWlyQ29uZGl0aW9uZXItU2V0dGluZ3MnKSwgdC5saXQoJ0NsZWFuaW5nUm9ib3QnKSwgdC5saXQoJ0NsZWFuaW5nUm9ib3QtTW9uaXRvcicpLCB0LmxpdCgnQ2xlYW5pbmdSb2JvdC1Db250cm9sJyksIHQubGl0KCdDbGVhbmluZ1JvYm90LVNldHRpbmdzJyksIHQubGl0KCdDb2ZmZWVNYWtlcicpLCB0LmxpdCgnQ29mZmVlTWFrZXItTW9uaXRvcicpLCB0LmxpdCgnQ29mZmVlTWFrZXItQ29udHJvbCcpLCB0LmxpdCgnQ29mZmVlTWFrZXItU2V0dGluZ3MnKSwgdC5saXQoJ0Nvb2tQcm9jZXNzb3InKSwgdC5saXQoJ0Nvb2tQcm9jZXNzb3ItTW9uaXRvcicpLCB0LmxpdCgnQ29va1Byb2Nlc3Nvci1Db250cm9sJyksIHQubGl0KCdDb29rUHJvY2Vzc29yLVNldHRpbmdzJyksIHQubGl0KCdEaXNod2FzaGVyJyksIHQubGl0KCdEaXNod2FzaGVyLU1vbml0b3InKSwgdC5saXQoJ0Rpc2h3YXNoZXItQ29udHJvbCcpLCB0LmxpdCgnRGlzaHdhc2hlci1TZXR0aW5ncycpLCB0LmxpdCgnRHJ5ZXInKSwgdC5saXQoJ0RyeWVyLU1vbml0b3InKSwgdC5saXQoJ0RyeWVyLUNvbnRyb2wnKSwgdC5saXQoJ0RyeWVyLVNldHRpbmdzJyksIHQubGl0KCdGcmVlemVyJyksIHQubGl0KCdGcmVlemVyLU1vbml0b3InKSwgdC5saXQoJ0ZyZWV6ZXItQ29udHJvbCcpLCB0LmxpdCgnRnJlZXplci1TZXR0aW5ncycpLCB0LmxpdCgnRnJpZGdlRnJlZXplcicpLCB0LmxpdCgnRnJpZGdlRnJlZXplci1Nb25pdG9yJyksIHQubGl0KCdGcmlkZ2VGcmVlemVyLUNvbnRyb2wnKSwgdC5saXQoJ0ZyaWRnZUZyZWV6ZXItU2V0dGluZ3MnKSwgdC5saXQoJ0ZyaWRnZUZyZWV6ZXItSW1hZ2VzJyksIHQubGl0KCdIb2InKSwgdC5saXQoJ0hvYi1Nb25pdG9yJyksIHQubGl0KCdIb2ItQ29udHJvbCcpLCB0LmxpdCgnSG9iLVNldHRpbmdzJyksIHQubGl0KCdIb29kJyksIHQubGl0KCdIb29kLU1vbml0b3InKSwgdC5saXQoJ0hvb2QtQ29udHJvbCcpLCB0LmxpdCgnSG9vZC1TZXR0aW5ncycpLCB0LmxpdCgnTWljcm93YXZlJyksIHQubGl0KCdNaWNyb3dhdmUtTW9uaXRvcicpLCB0LmxpdCgnTWljcm93YXZlLUNvbnRyb2wnKSwgdC5saXQoJ01pY3Jvd2F2ZS1TZXR0aW5ncycpLCB0LmxpdCgnT3ZlbicpLCB0LmxpdCgnT3Zlbi1Nb25pdG9yJyksIHQubGl0KCdPdmVuLUNvbnRyb2wnKSwgdC5saXQoJ092ZW4tU2V0dGluZ3MnKSwgdC5saXQoJ1JlZnJpZ2VyYXRvcicpLCB0LmxpdCgnUmVmcmlnZXJhdG9yLU1vbml0b3InKSwgdC5saXQoJ1JlZnJpZ2VyYXRvci1Db250cm9sJyksIHQubGl0KCdSZWZyaWdlcmF0b3ItU2V0dGluZ3MnKSwgdC5saXQoJ1dhc2hlcicpLCB0LmxpdCgnV2FzaGVyLU1vbml0b3InKSwgdC5saXQoJ1dhc2hlci1Db250cm9sJyksIHQubGl0KCdXYXNoZXItU2V0dGluZ3MnKSwgdC5saXQoJ1dhc2hlckRyeWVyJyksIHQubGl0KCdXYXNoZXJEcnllci1Nb25pdG9yJyksIHQubGl0KCdXYXNoZXJEcnllci1Db250cm9sJyksIHQubGl0KCdXYXNoZXJEcnllci1TZXR0aW5ncycpLCB0LmxpdCgnV2luZUNvb2xlcicpLCB0LmxpdCgnV2luZUNvb2xlci1Nb25pdG9yJyksIHQubGl0KCdXaW5lQ29vbGVyLUNvbnRyb2wnKSwgdC5saXQoJ1dpbmVDb29sZXItU2V0dGluZ3MnKSk7XG5jb25zdCBBdXRob3Jpc2F0aW9uUmVxdWVzdCA9IGV4cG9ydHMuQXV0aG9yaXNhdGlvblJlcXVlc3QgPSB0LmlmYWNlKFtdLCB7XG4gIFwiY2xpZW50X2lkXCI6IFwic3RyaW5nXCIsXG4gIFwicmVkaXJlY3RfdXJpXCI6IHQub3B0KFwic3RyaW5nXCIpLFxuICBcInJlc3BvbnNlX3R5cGVcIjogdC5saXQoJ2NvZGUnKSxcbiAgXCJzY29wZVwiOiB0Lm9wdChcInN0cmluZ1wiKSxcbiAgXCJzdGF0ZVwiOiB0Lm9wdChcIkF1dGhvcmlzYXRpb25TdGF0ZVwiKSxcbiAgXCJub25jZVwiOiB0Lm9wdChcInN0cmluZ1wiKSxcbiAgXCJjb2RlX2NoYWxsZW5nZVwiOiB0Lm9wdChcInN0cmluZ1wiKSxcbiAgXCJjb2RlX2NoYWxsZW5nZV9tZXRob2RcIjogdC5vcHQodC51bmlvbih0LmxpdCgncGxhaW4nKSwgdC5saXQoJ1MyNTYnKSkpXG59KTtcbmNvbnN0IEF1dGhvcmlzYXRpb25TdGF0ZSA9IGV4cG9ydHMuQXV0aG9yaXNhdGlvblN0YXRlID0gdC51bmlvbihcInN0cmluZ1wiLCBcIm51bWJlclwiKTtcbmNvbnN0IEF1dGhvcmlzYXRpb25SZXNwb25zZSA9IGV4cG9ydHMuQXV0aG9yaXNhdGlvblJlc3BvbnNlID0gdC5pZmFjZShbXSwge1xuICBcImNvZGVcIjogXCJzdHJpbmdcIixcbiAgXCJncmFudF90eXBlXCI6IHQub3B0KHQubGl0KCdhdXRob3JpemF0aW9uX2NvZGUnKSksXG4gIFwic3RhdGVcIjogdC5vcHQoXCJBdXRob3Jpc2F0aW9uU3RhdGVcIilcbn0pO1xuY29uc3QgQWNjZXNzVG9rZW5SZXF1ZXN0ID0gZXhwb3J0cy5BY2Nlc3NUb2tlblJlcXVlc3QgPSB0LmlmYWNlKFtdLCB7XG4gIFwiY2xpZW50X2lkXCI6IFwic3RyaW5nXCIsXG4gIFwiY2xpZW50X3NlY3JldFwiOiB0Lm9wdChcInN0cmluZ1wiKSxcbiAgXCJyZWRpcmVjdF91cmlcIjogdC5vcHQoXCJzdHJpbmdcIiksXG4gIFwiZ3JhbnRfdHlwZVwiOiB0LmxpdCgnYXV0aG9yaXphdGlvbl9jb2RlJyksXG4gIFwiY29kZVwiOiBcInN0cmluZ1wiLFxuICBcImNvZGVfdmVyaWZpZXJcIjogdC5vcHQoXCJzdHJpbmdcIilcbn0pO1xuY29uc3QgQWNjZXNzVG9rZW5SZXNwb25zZSA9IGV4cG9ydHMuQWNjZXNzVG9rZW5SZXNwb25zZSA9IHQuaWZhY2UoW10sIHtcbiAgXCJpZF90b2tlblwiOiBcInN0cmluZ1wiLFxuICBcImFjY2Vzc190b2tlblwiOiBcInN0cmluZ1wiLFxuICBcImV4cGlyZXNfaW5cIjogXCJudW1iZXJcIixcbiAgXCJzY29wZVwiOiBcInN0cmluZ1wiLFxuICBcInJlZnJlc2hfdG9rZW5cIjogXCJzdHJpbmdcIixcbiAgXCJ0b2tlbl90eXBlXCI6IHQub3B0KHQubGl0KCdCZWFyZXInKSlcbn0pO1xuY29uc3QgRGV2aWNlQXV0aG9yaXNhdGlvblJlcXVlc3QgPSBleHBvcnRzLkRldmljZUF1dGhvcmlzYXRpb25SZXF1ZXN0ID0gdC5pZmFjZShbXSwge1xuICBcImNsaWVudF9pZFwiOiBcInN0cmluZ1wiLFxuICBcInNjb3BlXCI6IHQub3B0KFwic3RyaW5nXCIpXG59KTtcbmNvbnN0IERldmljZUF1dGhvcmlzYXRpb25SZXNwb25zZSA9IGV4cG9ydHMuRGV2aWNlQXV0aG9yaXNhdGlvblJlc3BvbnNlID0gdC5pZmFjZShbXSwge1xuICBcImRldmljZV9jb2RlXCI6IFwic3RyaW5nXCIsXG4gIFwidXNlcl9jb2RlXCI6IFwic3RyaW5nXCIsXG4gIFwidmVyaWZpY2F0aW9uX3VyaVwiOiBcInN0cmluZ1wiLFxuICBcInZlcmlmaWNhdGlvbl91cmlfY29tcGxldGVcIjogdC5vcHQoXCJzdHJpbmdcIiksXG4gIFwiZXhwaXJlc19pblwiOiB0Lm9wdChcIm51bWJlclwiKSxcbiAgXCJpbnRlcnZhbFwiOiB0Lm9wdChcIm51bWJlclwiKVxufSk7XG5jb25zdCBEZXZpY2VBY2Nlc3NUb2tlblJlcXVlc3QgPSBleHBvcnRzLkRldmljZUFjY2Vzc1Rva2VuUmVxdWVzdCA9IHQuaWZhY2UoW10sIHtcbiAgXCJncmFudF90eXBlXCI6IHQudW5pb24odC5saXQoJ3VybjppZXRmOnBhcmFtczpvYXV0aDpncmFudC10eXBlOmRldmljZV9jb2RlJyksIHQubGl0KCdkZXZpY2VfY29kZScpKSxcbiAgXCJkZXZpY2VfY29kZVwiOiBcInN0cmluZ1wiLFxuICBcImNsaWVudF9pZFwiOiBcInN0cmluZ1wiLFxuICBcImNsaWVudF9zZWNyZXRcIjogdC5vcHQoXCJzdHJpbmdcIilcbn0pO1xuY29uc3QgRGV2aWNlQWNjZXNzVG9rZW5SZXNwb25zZSA9IGV4cG9ydHMuRGV2aWNlQWNjZXNzVG9rZW5SZXNwb25zZSA9IHQuaWZhY2UoW10sIHtcbiAgXCJpZF90b2tlblwiOiBcInN0cmluZ1wiLFxuICBcImFjY2Vzc190b2tlblwiOiBcInN0cmluZ1wiLFxuICBcImV4cGlyZXNfaW5cIjogXCJudW1iZXJcIixcbiAgXCJzY29wZVwiOiBcInN0cmluZ1wiLFxuICBcInJlZnJlc2hfdG9rZW5cIjogXCJzdHJpbmdcIixcbiAgXCJ0b2tlbl90eXBlXCI6IHQub3B0KHQubGl0KCdCZWFyZXInKSlcbn0pO1xuY29uc3QgQWNjZXNzVG9rZW5SZWZyZXNoUmVxdWVzdCA9IGV4cG9ydHMuQWNjZXNzVG9rZW5SZWZyZXNoUmVxdWVzdCA9IHQuaWZhY2UoW10sIHtcbiAgXCJncmFudF90eXBlXCI6IHQubGl0KCdyZWZyZXNoX3Rva2VuJyksXG4gIFwicmVmcmVzaF90b2tlblwiOiBcInN0cmluZ1wiLFxuICBcImNsaWVudF9zZWNyZXRcIjogdC5vcHQoXCJzdHJpbmdcIiksXG4gIFwic2NvcGVcIjogdC5vcHQoXCJzdHJpbmdcIiksXG4gIFwiZXhwaXJlc19pblwiOiB0Lm9wdChcIm51bWJlclwiKVxufSk7XG5jb25zdCBBY2Nlc3NUb2tlblJlZnJlc2hSZXNwb25zZSA9IGV4cG9ydHMuQWNjZXNzVG9rZW5SZWZyZXNoUmVzcG9uc2UgPSB0LmlmYWNlKFtdLCB7XG4gIFwiaWRfdG9rZW5cIjogXCJzdHJpbmdcIixcbiAgXCJhY2Nlc3NfdG9rZW5cIjogXCJzdHJpbmdcIixcbiAgXCJleHBpcmVzX2luXCI6IFwibnVtYmVyXCIsXG4gIFwic2NvcGVcIjogXCJzdHJpbmdcIixcbiAgXCJyZWZyZXNoX3Rva2VuXCI6IFwic3RyaW5nXCIsXG4gIFwidG9rZW5fdHlwZVwiOiB0LmxpdCgnQmVhcmVyJylcbn0pO1xuY29uc3QgQWJzb2x1dGVUb2tlbiA9IGV4cG9ydHMuQWJzb2x1dGVUb2tlbiA9IHQuaWZhY2UoW10sIHtcbiAgXCJyZWZyZXNoVG9rZW5cIjogXCJzdHJpbmdcIixcbiAgXCJhY2Nlc3NUb2tlblwiOiBcInN0cmluZ1wiLFxuICBcImFjY2Vzc0V4cGlyZXNcIjogXCJudW1iZXJcIixcbiAgXCJzY29wZXNcIjogdC5hcnJheShcInN0cmluZ1wiKVxufSk7XG5jb25zdCBQZXJzaXN0QWJzb2x1dGVUb2tlbnMgPSBleHBvcnRzLlBlcnNpc3RBYnNvbHV0ZVRva2VucyA9IHQuaWZhY2UoW10sIHtcbiAgW3QuaW5kZXhLZXldOiBcIkFic29sdXRlVG9rZW5cIlxufSk7XG5jb25zdCBBdXRob3Jpc2F0aW9uRXJyb3IgPSBleHBvcnRzLkF1dGhvcmlzYXRpb25FcnJvciA9IHQuaWZhY2UoW10sIHtcbiAgXCJlcnJvclwiOiBcInN0cmluZ1wiLFxuICBcImVycm9yX2Rlc2NyaXB0aW9uXCI6IFwic3RyaW5nXCJcbn0pO1xuY29uc3QgZXhwb3J0ZWRUeXBlU3VpdGUgPSB7XG4gIFNjb3BlLFxuICBBdXRob3Jpc2F0aW9uUmVxdWVzdCxcbiAgQXV0aG9yaXNhdGlvblN0YXRlLFxuICBBdXRob3Jpc2F0aW9uUmVzcG9uc2UsXG4gIEFjY2Vzc1Rva2VuUmVxdWVzdCxcbiAgQWNjZXNzVG9rZW5SZXNwb25zZSxcbiAgRGV2aWNlQXV0aG9yaXNhdGlvblJlcXVlc3QsXG4gIERldmljZUF1dGhvcmlzYXRpb25SZXNwb25zZSxcbiAgRGV2aWNlQWNjZXNzVG9rZW5SZXF1ZXN0LFxuICBEZXZpY2VBY2Nlc3NUb2tlblJlc3BvbnNlLFxuICBBY2Nlc3NUb2tlblJlZnJlc2hSZXF1ZXN0LFxuICBBY2Nlc3NUb2tlblJlZnJlc2hSZXNwb25zZSxcbiAgQWJzb2x1dGVUb2tlbixcbiAgUGVyc2lzdEFic29sdXRlVG9rZW5zLFxuICBBdXRob3Jpc2F0aW9uRXJyb3Jcbn07XG52YXIgX2RlZmF1bHQgPSBleHBvcnRzLmRlZmF1bHQgPSBleHBvcnRlZFR5cGVTdWl0ZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRhdGE6YXBwbGljYXRpb24vanNvbjtjaGFyc2V0PXV0Zi04O2Jhc2U2NCxleUoyWlhKemFXOXVJam96TENKdVlXMWxjeUk2V3lKMElpd2lYMmx1ZEdWeWIzQlNaWEYxYVhKbFYybHNaR05oY21RaUxDSnlaWEYxYVhKbElpd2laU0lzSWxkbFlXdE5ZWEFpTENKeUlpd2liaUlzSWw5ZlpYTk5iMlIxYkdVaUxDSnZJaXdpYVNJc0ltWWlMQ0pmWDNCeWIzUnZYMThpTENKa1pXWmhkV3gwSWl3aWFHRnpJaXdpWjJWMElpd2ljMlYwSWl3aWFHRnpUM2R1VUhKdmNHVnlkSGtpTENKallXeHNJaXdpVDJKcVpXTjBJaXdpWkdWbWFXNWxVSEp2Y0dWeWRIa2lMQ0puWlhSUGQyNVFjbTl3WlhKMGVVUmxjMk55YVhCMGIzSWlMQ0pUWTI5d1pTSXNJbVY0Y0c5eWRITWlMQ0oxYm1sdmJpSXNJbXhwZENJc0lrRjFkR2h2Y21sellYUnBiMjVTWlhGMVpYTjBJaXdpYVdaaFkyVWlMQ0p2Y0hRaUxDSkJkWFJvYjNKcGMyRjBhVzl1VTNSaGRHVWlMQ0pCZFhSb2IzSnBjMkYwYVc5dVVtVnpjRzl1YzJVaUxDSkJZMk5sYzNOVWIydGxibEpsY1hWbGMzUWlMQ0pCWTJObGMzTlViMnRsYmxKbGMzQnZibk5sSWl3aVJHVjJhV05sUVhWMGFHOXlhWE5oZEdsdmJsSmxjWFZsYzNRaUxDSkVaWFpwWTJWQmRYUm9iM0pwYzJGMGFXOXVVbVZ6Y0c5dWMyVWlMQ0pFWlhacFkyVkJZMk5sYzNOVWIydGxibEpsY1hWbGMzUWlMQ0pFWlhacFkyVkJZMk5sYzNOVWIydGxibEpsYzNCdmJuTmxJaXdpUVdOalpYTnpWRzlyWlc1U1pXWnlaWE5vVW1WeGRXVnpkQ0lzSWtGalkyVnpjMVJ2YTJWdVVtVm1jbVZ6YUZKbGMzQnZibk5sSWl3aVFXSnpiMngxZEdWVWIydGxiaUlzSW1GeWNtRjVJaXdpVUdWeWMybHpkRUZpYzI5c2RYUmxWRzlyWlc1eklpd2lhVzVrWlhoTFpYa2lMQ0pCZFhSb2IzSnBjMkYwYVc5dVJYSnliM0lpTENKbGVIQnZjblJsWkZSNWNHVlRkV2wwWlNJc0lsOWtaV1poZFd4MElsMHNJbk52ZFhKalpYTWlPbHNpTGk0dkxpNHZjM0pqTDNScEwyRndhUzFoZFhSb0xYUjVjR1Z6TFhScExuUnpJbDBzSW5OdmRYSmpaWE5EYjI1MFpXNTBJanBiYm5Wc2JGMHNJbTFoY0hCcGJtZHpJam9pT3pzN096czdRVUZIUVN4SlFVRkJRU3hEUVVGQkxFZEJRVUZETEhWQ1FVRkJMRU5CUVVGRExFOUJRVUU3UVVGQk1FTXNVMEZCUVVRc2QwSkJRVUZGTEVOQlFVRXNSVUZCUVVnc1EwRkJRU3cyUWtGQlFVa3NUMEZCUVN4TlFVRkJReXhEUVVGQkxFOUJRVUZFTEU5QlFVRXNTVUZCUVVVc1EwRkJRU3hQUVVGQlJpeFBRVUZCTEZsQlFVRklMSFZDUVVGQkxGbEJRVUZCTEVOQlFVRkZMRU5CUVVFc1JVRkJRVWdzUTBGQlFTeFRRVUZCUVN4RFFVRkJMRWxCUVVGSExFTkJRVUVzU1VGQlFVRXNRMEZCUVN4RFFVRkJTU3hWUVVGQkxGTkJRVUZLTEVOQlFVRXNUVUZCUVVzc1EwRkJRU3hGUVVGQlF5eERRVUZCTEVWQlFVRkRMRU5CUVVFc1MwRkJRVU1zVTBGQlFTeFJRVUZCUXl4UFFVRkJMRVZCUVVGVUxFTkJRVUVzYVVKQlFVRkJMRU5CUVVFc2RVSkJRVUZCTEVOQlFVRXNlVUpCUVVGQkxFTkJRVUVzVTBGQlFVOHNRMEZCUVN4TlFVRkJSaXhEUVVGQkxFZEJRVUZTTEVOQlFVRXNSMEZCUVUwc1EwRkJRU3hIUVVGQlJDeERRVUZCTEZGQlFVRkhMRU5CUVVFc1EwRkJRVXNzUjBGQlFTeERRVUZCVml4RFFVRkJMRlZCUVVGTExFTkJRVUVzUTBGQlFVMHNSMEZCUVN4RFFVRkJXQ3hEUVVGQkxFZEJRVUZMTEVOQlFVRXNRMEZCUVU4c1IwRkJRU3hEUVVGQldpeERRVUZCTEVWQlFVRlBMRU5CUVVFc1owSkJRVUZXTEVOQlFVRXNTVUZCUVVjc1EwRkJRU3huUWtGQlFVZ3NRMEZCUVN4UFFVRkJaMElzWTBGQlFTeERRVUZCUXl4SlFVRkJMRU5CUVVGa0xFTkJRVUVzUlVGQlFVZ3NRMEZCUVN4UFFVRkJVeXhEUVVGQkxFbEJRVUZFTEVOQlFVRXNSMEZCUVZVc1RVRkJRU3hEUVVGQlF5eGpRVUZCTEV0QlFVRkVMRTFCUVVFc1EwRkJRVVVzZDBKQlFVRXNRMEZCUVdwQ0xFTkJRVUVzUlVGQlFVZ3NRMEZCUVN4UFFVRkJVeXhEUVVGQkxFTkJRVUZMTEVkQlFVRXNTVUZCUVV3c1EwRkJRU3hEUVVGQlRTeEhRVUZCTEVsQlFVRlFMRU5CUVVFc1EwRkJRVVVzUTBGQlFTeEZRVUZCVml4RFFVRkJMRVZCUVVGVExFTkJRVUVzU1VGQlFVTXNRMEZCUVN4RFFVRkJWaXhEUVVGQkxFbEJRVUZITEVOQlFVRXNRMEZCUVVnc1EwRkJRU3hYUVVGQlZTeERRVUZCTEV0QlFVRlFMRU5CUVVFc1JVRkJRVWdzUTBGQlFUdEJRVWd4UXpzN096dEJRVWxCTzBGQlJVOHNUVUZCVFhGQ0xFdEJRVXNzUjBGQlFVTXNUMEZCUVN4RFFVRkJSQ3hMUVVGQkxFZEJRVWR5UWl4RFFVRkRMRU5CUVVOMVFpeExRVUZMTEVOQlFVTjJRaXhEUVVGRExFTkJRVU4zUWl4SFFVRkhMRU5CUVVNc1UwRkJVeXhEUVVGRExFVkJRVVY0UWl4RFFVRkRMRU5CUVVOM1FpeEhRVUZITEVOQlFVTXNVMEZCVXl4RFFVRkRMRVZCUVVWNFFpeERRVUZETEVOQlFVTjNRaXhIUVVGSExFTkJRVU1zVlVGQlZTeERRVUZETEVWQlFVVjRRaXhEUVVGRExFTkJRVU4zUWl4SFFVRkhMRU5CUVVNc1VVRkJVU3hEUVVGRExFVkJRVVY0UWl4RFFVRkRMRU5CUVVOM1FpeEhRVUZITEVOQlFVTXNaMEpCUVdkQ0xFTkJRVU1zUlVGQlJYaENMRU5CUVVNc1EwRkJRM2RDTEVkQlFVY3NRMEZCUXl4M1FrRkJkMElzUTBGQlF5eEZRVUZGZUVJc1EwRkJReXhEUVVGRGQwSXNSMEZCUnl4RFFVRkRMSGRDUVVGM1FpeERRVUZETEVWQlFVVjRRaXhEUVVGRExFTkJRVU4zUWl4SFFVRkhMRU5CUVVNc2VVSkJRWGxDTEVOQlFVTXNSVUZCUlhoQ0xFTkJRVU1zUTBGQlEzZENMRWRCUVVjc1EwRkJReXhsUVVGbExFTkJRVU1zUlVGQlJYaENMRU5CUVVNc1EwRkJRM2RDTEVkQlFVY3NRMEZCUXl4MVFrRkJkVUlzUTBGQlF5eEZRVUZGZUVJc1EwRkJReXhEUVVGRGQwSXNSMEZCUnl4RFFVRkRMSFZDUVVGMVFpeERRVUZETEVWQlFVVjRRaXhEUVVGRExFTkJRVU4zUWl4SFFVRkhMRU5CUVVNc2QwSkJRWGRDTEVOQlFVTXNSVUZCUlhoQ0xFTkJRVU1zUTBGQlEzZENMRWRCUVVjc1EwRkJReXhoUVVGaExFTkJRVU1zUlVGQlJYaENMRU5CUVVNc1EwRkJRM2RDTEVkQlFVY3NRMEZCUXl4eFFrRkJjVUlzUTBGQlF5eEZRVUZGZUVJc1EwRkJReXhEUVVGRGQwSXNSMEZCUnl4RFFVRkRMSEZDUVVGeFFpeERRVUZETEVWQlFVVjRRaXhEUVVGRExFTkJRVU4zUWl4SFFVRkhMRU5CUVVNc2MwSkJRWE5DTEVOQlFVTXNSVUZCUlhoQ0xFTkJRVU1zUTBGQlEzZENMRWRCUVVjc1EwRkJReXhsUVVGbExFTkJRVU1zUlVGQlJYaENMRU5CUVVNc1EwRkJRM2RDTEVkQlFVY3NRMEZCUXl4MVFrRkJkVUlzUTBGQlF5eEZRVUZGZUVJc1EwRkJReXhEUVVGRGQwSXNSMEZCUnl4RFFVRkRMSFZDUVVGMVFpeERRVUZETEVWQlFVVjRRaXhEUVVGRExFTkJRVU4zUWl4SFFVRkhMRU5CUVVNc2QwSkJRWGRDTEVOQlFVTXNSVUZCUlhoQ0xFTkJRVU1zUTBGQlEzZENMRWRCUVVjc1EwRkJReXhaUVVGWkxFTkJRVU1zUlVGQlJYaENMRU5CUVVNc1EwRkJRM2RDTEVkQlFVY3NRMEZCUXl4dlFrRkJiMElzUTBGQlF5eEZRVUZGZUVJc1EwRkJReXhEUVVGRGQwSXNSMEZCUnl4RFFVRkRMRzlDUVVGdlFpeERRVUZETEVWQlFVVjRRaXhEUVVGRExFTkJRVU4zUWl4SFFVRkhMRU5CUVVNc2NVSkJRWEZDTEVOQlFVTXNSVUZCUlhoQ0xFTkJRVU1zUTBGQlEzZENMRWRCUVVjc1EwRkJReXhQUVVGUExFTkJRVU1zUlVGQlJYaENMRU5CUVVNc1EwRkJRM2RDTEVkQlFVY3NRMEZCUXl4bFFVRmxMRU5CUVVNc1JVRkJSWGhDTEVOQlFVTXNRMEZCUTNkQ0xFZEJRVWNzUTBGQlF5eGxRVUZsTEVOQlFVTXNSVUZCUlhoQ0xFTkJRVU1zUTBGQlEzZENMRWRCUVVjc1EwRkJReXhuUWtGQlowSXNRMEZCUXl4RlFVRkZlRUlzUTBGQlF5eERRVUZEZDBJc1IwRkJSeXhEUVVGRExGTkJRVk1zUTBGQlF5eEZRVUZGZUVJc1EwRkJReXhEUVVGRGQwSXNSMEZCUnl4RFFVRkRMR2xDUVVGcFFpeERRVUZETEVWQlFVVjRRaXhEUVVGRExFTkJRVU4zUWl4SFFVRkhMRU5CUVVNc2FVSkJRV2xDTEVOQlFVTXNSVUZCUlhoQ0xFTkJRVU1zUTBGQlEzZENMRWRCUVVjc1EwRkJReXhyUWtGQmEwSXNRMEZCUXl4RlFVRkZlRUlzUTBGQlF5eERRVUZEZDBJc1IwRkJSeXhEUVVGRExHVkJRV1VzUTBGQlF5eEZRVUZGZUVJc1EwRkJReXhEUVVGRGQwSXNSMEZCUnl4RFFVRkRMSFZDUVVGMVFpeERRVUZETEVWQlFVVjRRaXhEUVVGRExFTkJRVU4zUWl4SFFVRkhMRU5CUVVNc2RVSkJRWFZDTEVOQlFVTXNSVUZCUlhoQ0xFTkJRVU1zUTBGQlEzZENMRWRCUVVjc1EwRkJReXgzUWtGQmQwSXNRMEZCUXl4RlFVRkZlRUlzUTBGQlF5eERRVUZEZDBJc1IwRkJSeXhEUVVGRExITkNRVUZ6UWl4RFFVRkRMRVZCUVVWNFFpeERRVUZETEVOQlFVTjNRaXhIUVVGSExFTkJRVU1zUzBGQlN5eERRVUZETEVWQlFVVjRRaXhEUVVGRExFTkJRVU4zUWl4SFFVRkhMRU5CUVVNc1lVRkJZU3hEUVVGRExFVkJRVVY0UWl4RFFVRkRMRU5CUVVOM1FpeEhRVUZITEVOQlFVTXNZVUZCWVN4RFFVRkRMRVZCUVVWNFFpeERRVUZETEVOQlFVTjNRaXhIUVVGSExFTkJRVU1zWTBGQll5eERRVUZETEVWQlFVVjRRaXhEUVVGRExFTkJRVU4zUWl4SFFVRkhMRU5CUVVNc1RVRkJUU3hEUVVGRExFVkJRVVY0UWl4RFFVRkRMRU5CUVVOM1FpeEhRVUZITEVOQlFVTXNZMEZCWXl4RFFVRkRMRVZCUVVWNFFpeERRVUZETEVOQlFVTjNRaXhIUVVGSExFTkJRVU1zWTBGQll5eERRVUZETEVWQlFVVjRRaXhEUVVGRExFTkJRVU4zUWl4SFFVRkhMRU5CUVVNc1pVRkJaU3hEUVVGRExFVkJRVVY0UWl4RFFVRkRMRU5CUVVOM1FpeEhRVUZITEVOQlFVTXNWMEZCVnl4RFFVRkRMRVZCUVVWNFFpeERRVUZETEVOQlFVTjNRaXhIUVVGSExFTkJRVU1zYlVKQlFXMUNMRU5CUVVNc1JVRkJSWGhDTEVOQlFVTXNRMEZCUTNkQ0xFZEJRVWNzUTBGQlF5eHRRa0ZCYlVJc1EwRkJReXhGUVVGRmVFSXNRMEZCUXl4RFFVRkRkMElzUjBGQlJ5eERRVUZETEc5Q1FVRnZRaXhEUVVGRExFVkJRVVY0UWl4RFFVRkRMRU5CUVVOM1FpeEhRVUZITEVOQlFVTXNUVUZCVFN4RFFVRkRMRVZCUVVWNFFpeERRVUZETEVOQlFVTjNRaXhIUVVGSExFTkJRVU1zWTBGQll5eERRVUZETEVWQlFVVjRRaXhEUVVGRExFTkJRVU4zUWl4SFFVRkhMRU5CUVVNc1kwRkJZeXhEUVVGRExFVkJRVVY0UWl4RFFVRkRMRU5CUVVOM1FpeEhRVUZITEVOQlFVTXNaVUZCWlN4RFFVRkRMRVZCUVVWNFFpeERRVUZETEVOQlFVTjNRaXhIUVVGSExFTkJRVU1zWTBGQll5eERRVUZETEVWQlFVVjRRaXhEUVVGRExFTkJRVU4zUWl4SFFVRkhMRU5CUVVNc2MwSkJRWE5DTEVOQlFVTXNSVUZCUlhoQ0xFTkJRVU1zUTBGQlEzZENMRWRCUVVjc1EwRkJReXh6UWtGQmMwSXNRMEZCUXl4RlFVRkZlRUlzUTBGQlF5eERRVUZEZDBJc1IwRkJSeXhEUVVGRExIVkNRVUYxUWl4RFFVRkRMRVZCUVVWNFFpeERRVUZETEVOQlFVTjNRaXhIUVVGSExFTkJRVU1zVVVGQlVTeERRVUZETEVWQlFVVjRRaXhEUVVGRExFTkJRVU4zUWl4SFFVRkhMRU5CUVVNc1owSkJRV2RDTEVOQlFVTXNSVUZCUlhoQ0xFTkJRVU1zUTBGQlEzZENMRWRCUVVjc1EwRkJReXhuUWtGQlowSXNRMEZCUXl4RlFVRkZlRUlzUTBGQlF5eERRVUZEZDBJc1IwRkJSeXhEUVVGRExHbENRVUZwUWl4RFFVRkRMRVZCUVVWNFFpeERRVUZETEVOQlFVTjNRaXhIUVVGSExFTkJRVU1zWVVGQllTeERRVUZETEVWQlFVVjRRaXhEUVVGRExFTkJRVU4zUWl4SFFVRkhMRU5CUVVNc2NVSkJRWEZDTEVOQlFVTXNSVUZCUlhoQ0xFTkJRVU1zUTBGQlEzZENMRWRCUVVjc1EwRkJReXh4UWtGQmNVSXNRMEZCUXl4RlFVRkZlRUlzUTBGQlF5eERRVUZEZDBJc1IwRkJSeXhEUVVGRExITkNRVUZ6UWl4RFFVRkRMRVZCUVVWNFFpeERRVUZETEVOQlFVTjNRaXhIUVVGSExFTkJRVU1zV1VGQldTeERRVUZETEVWQlFVVjRRaXhEUVVGRExFTkJRVU4zUWl4SFFVRkhMRU5CUVVNc2IwSkJRVzlDTEVOQlFVTXNSVUZCUlhoQ0xFTkJRVU1zUTBGQlEzZENMRWRCUVVjc1EwRkJReXh2UWtGQmIwSXNRMEZCUXl4RlFVRkZlRUlzUTBGQlF5eERRVUZEZDBJc1IwRkJSeXhEUVVGRExIRkNRVUZ4UWl4RFFVRkRMRU5CUVVNN1FVRkZhSGhFTEUxQlFVMURMRzlDUVVGdlFpeEhRVUZCU0N4UFFVRkJMRU5CUVVGSExHOUNRVUZCTEVkQlFVZDZRaXhEUVVGRExFTkJRVU13UWl4TFFVRkxMRU5CUVVNc1JVRkJSU3hGUVVGRk8wVkJRemxETEZkQlFWY3NSVUZCUlN4UlFVRlJPMFZCUTNKQ0xHTkJRV01zUlVGQlJURkNMRU5CUVVNc1EwRkJRekpDTEVkQlFVY3NRMEZCUXl4UlFVRlJMRU5CUVVNN1JVRkRMMElzWlVGQlpTeEZRVUZGTTBJc1EwRkJReXhEUVVGRGQwSXNSMEZCUnl4RFFVRkRMRTFCUVUwc1EwRkJRenRGUVVNNVFpeFBRVUZQTEVWQlFVVjRRaXhEUVVGRExFTkJRVU15UWl4SFFVRkhMRU5CUVVNc1VVRkJVU3hEUVVGRE8wVkJRM2hDTEU5QlFVOHNSVUZCUlROQ0xFTkJRVU1zUTBGQlF6SkNMRWRCUVVjc1EwRkJReXh2UWtGQmIwSXNRMEZCUXp0RlFVTndReXhQUVVGUExFVkJRVVV6UWl4RFFVRkRMRU5CUVVNeVFpeEhRVUZITEVOQlFVTXNVVUZCVVN4RFFVRkRPMFZCUTNoQ0xHZENRVUZuUWl4RlFVRkZNMElzUTBGQlF5eERRVUZETWtJc1IwRkJSeXhEUVVGRExGRkJRVkVzUTBGQlF6dEZRVU5xUXl4MVFrRkJkVUlzUlVGQlJUTkNMRU5CUVVNc1EwRkJRekpDTEVkQlFVY3NRMEZCUXpOQ0xFTkJRVU1zUTBGQlEzVkNMRXRCUVVzc1EwRkJRM1pDTEVOQlFVTXNRMEZCUTNkQ0xFZEJRVWNzUTBGQlF5eFBRVUZQTEVOQlFVTXNSVUZCUlhoQ0xFTkJRVU1zUTBGQlEzZENMRWRCUVVjc1EwRkJReXhOUVVGTkxFTkJRVU1zUTBGQlF6dERRVU4wUlN4RFFVRkRPMEZCUlVzc1RVRkJUVWtzYTBKQlFXdENMRWRCUVVGT0xFOUJRVUVzUTBGQlFVMHNhMEpCUVVFc1IwRkJSelZDTEVOQlFVTXNRMEZCUTNWQ0xFdEJRVXNzUTBGQlF5eFJRVUZSTEVWQlFVVXNVVUZCVVN4RFFVRkRPMEZCUlhSRUxFMUJRVTFOTEhGQ1FVRnhRaXhIUVVGQlVDeFBRVUZCTEVOQlFVRlBMSEZDUVVGQkxFZEJRVWMzUWl4RFFVRkRMRU5CUVVNd1FpeExRVUZMTEVOQlFVTXNSVUZCUlN4RlFVRkZPMFZCUXk5RExFMUJRVTBzUlVGQlJTeFJRVUZSTzBWQlEyaENMRmxCUVZrc1JVRkJSVEZDTEVOQlFVTXNRMEZCUXpKQ0xFZEJRVWNzUTBGQlF6TkNMRU5CUVVNc1EwRkJRM2RDTEVkQlFVY3NRMEZCUXl4dlFrRkJiMElzUTBGQlF5eERRVUZETzBWQlEyaEVMRTlCUVU4c1JVRkJSWGhDTEVOQlFVTXNRMEZCUXpKQ0xFZEJRVWNzUTBGQlF5eHZRa0ZCYjBJN1EwRkRjRU1zUTBGQlF6dEJRVVZMTEUxQlFVMUhMR3RDUVVGclFpeEhRVUZCVWl4UFFVRkJMRU5CUVVGUkxHdENRVUZCTEVkQlFVYzVRaXhEUVVGRExFTkJRVU13UWl4TFFVRkxMRU5CUVVNc1JVRkJSU3hGUVVGRk8wVkJRelZETEZkQlFWY3NSVUZCUlN4UlFVRlJPMFZCUTNKQ0xHVkJRV1VzUlVGQlJURkNMRU5CUVVNc1EwRkJRekpDTEVkQlFVY3NRMEZCUXl4UlFVRlJMRU5CUVVNN1JVRkRhRU1zWTBGQll5eEZRVUZGTTBJc1EwRkJReXhEUVVGRE1rSXNSMEZCUnl4RFFVRkRMRkZCUVZFc1EwRkJRenRGUVVNdlFpeFpRVUZaTEVWQlFVVXpRaXhEUVVGRExFTkJRVU4zUWl4SFFVRkhMRU5CUVVNc2IwSkJRVzlDTEVOQlFVTTdSVUZEZWtNc1RVRkJUU3hGUVVGRkxGRkJRVkU3UlVGRGFFSXNaVUZCWlN4RlFVRkZlRUlzUTBGQlF5eERRVUZETWtJc1IwRkJSeXhEUVVGRExGRkJRVkU3UTBGRGFFTXNRMEZCUXp0QlFVVkxMRTFCUVUxSkxHMUNRVUZ0UWl4SFFVRkJWQ3hQUVVGQkxFTkJRVUZUTEcxQ1FVRkJMRWRCUVVjdlFpeERRVUZETEVOQlFVTXdRaXhMUVVGTExFTkJRVU1zUlVGQlJTeEZRVUZGTzBWQlF6ZERMRlZCUVZVc1JVRkJSU3hSUVVGUk8wVkJRM0JDTEdOQlFXTXNSVUZCUlN4UlFVRlJPMFZCUTNoQ0xGbEJRVmtzUlVGQlJTeFJRVUZSTzBWQlEzUkNMRTlCUVU4c1JVRkJSU3hSUVVGUk8wVkJRMnBDTEdWQlFXVXNSVUZCUlN4UlFVRlJPMFZCUTNwQ0xGbEJRVmtzUlVGQlJURkNMRU5CUVVNc1EwRkJRekpDTEVkQlFVY3NRMEZCUXpOQ0xFTkJRVU1zUTBGQlEzZENMRWRCUVVjc1EwRkJReXhSUVVGUkxFTkJRVU03UTBGRGNFTXNRMEZCUXp0QlFVVkxMRTFCUVUxUkxEQkNRVUV3UWl4SFFVRkJWaXhQUVVGQkxFTkJRVUZWTERCQ1FVRkJMRWRCUVVkb1F5eERRVUZETEVOQlFVTXdRaXhMUVVGTExFTkJRVU1zUlVGQlJTeEZRVUZGTzBWQlEzQkVMRmRCUVZjc1JVRkJSU3hSUVVGUk8wVkJRM0pDTEU5QlFVOHNSVUZCUlRGQ0xFTkJRVU1zUTBGQlF6SkNMRWRCUVVjc1EwRkJReXhSUVVGUk8wTkJRM2hDTEVOQlFVTTdRVUZGU3l4TlFVRk5UU3d5UWtGQk1rSXNSMEZCUVZnc1QwRkJRU3hEUVVGQlZ5d3lRa0ZCUVN4SFFVRkhha01zUTBGQlF5eERRVUZETUVJc1MwRkJTeXhEUVVGRExFVkJRVVVzUlVGQlJUdEZRVU55UkN4aFFVRmhMRVZCUVVVc1VVRkJVVHRGUVVOMlFpeFhRVUZYTEVWQlFVVXNVVUZCVVR0RlFVTnlRaXhyUWtGQmEwSXNSVUZCUlN4UlFVRlJPMFZCUXpWQ0xESkNRVUV5UWl4RlFVRkZNVUlzUTBGQlF5eERRVUZETWtJc1IwRkJSeXhEUVVGRExGRkJRVkVzUTBGQlF6dEZRVU0xUXl4WlFVRlpMRVZCUVVVelFpeERRVUZETEVOQlFVTXlRaXhIUVVGSExFTkJRVU1zVVVGQlVTeERRVUZETzBWQlF6ZENMRlZCUVZVc1JVRkJSVE5DTEVOQlFVTXNRMEZCUXpKQ0xFZEJRVWNzUTBGQlF5eFJRVUZSTzBOQlF6TkNMRU5CUVVNN1FVRkZTeXhOUVVGTlR5eDNRa0ZCZDBJc1IwRkJRVm9zVDBGQlFTeERRVUZCV1N4M1FrRkJRU3hIUVVGSGJFTXNRMEZCUXl4RFFVRkRNRUlzUzBGQlN5eERRVUZETEVWQlFVVXNSVUZCUlR0RlFVTnNSQ3haUVVGWkxFVkJRVVV4UWl4RFFVRkRMRU5CUVVOMVFpeExRVUZMTEVOQlFVTjJRaXhEUVVGRExFTkJRVU4zUWl4SFFVRkhMRU5CUVVNc09FTkJRVGhETEVOQlFVTXNSVUZCUlhoQ0xFTkJRVU1zUTBGQlEzZENMRWRCUVVjc1EwRkJReXhoUVVGaExFTkJRVU1zUTBGQlF6dEZRVU5zUnl4aFFVRmhMRVZCUVVVc1VVRkJVVHRGUVVOMlFpeFhRVUZYTEVWQlFVVXNVVUZCVVR0RlFVTnlRaXhsUVVGbExFVkJRVVY0UWl4RFFVRkRMRU5CUVVNeVFpeEhRVUZITEVOQlFVTXNVVUZCVVR0RFFVTm9ReXhEUVVGRE8wRkJSVXNzVFVGQlRWRXNlVUpCUVhsQ0xFZEJRVUZpTEU5QlFVRXNRMEZCUVdFc2VVSkJRVUVzUjBGQlIyNURMRU5CUVVNc1EwRkJRekJDTEV0QlFVc3NRMEZCUXl4RlFVRkZMRVZCUVVVN1JVRkRia1FzVlVGQlZTeEZRVUZGTEZGQlFWRTdSVUZEY0VJc1kwRkJZeXhGUVVGRkxGRkJRVkU3UlVGRGVFSXNXVUZCV1N4RlFVRkZMRkZCUVZFN1JVRkRkRUlzVDBGQlR5eEZRVUZGTEZGQlFWRTdSVUZEYWtJc1pVRkJaU3hGUVVGRkxGRkJRVkU3UlVGRGVrSXNXVUZCV1N4RlFVRkZNVUlzUTBGQlF5eERRVUZETWtJc1IwRkJSeXhEUVVGRE0wSXNRMEZCUXl4RFFVRkRkMElzUjBGQlJ5eERRVUZETEZGQlFWRXNRMEZCUXp0RFFVTndReXhEUVVGRE8wRkJSVXNzVFVGQlRWa3NlVUpCUVhsQ0xFZEJRVUZrTEU5QlFVRXNRMEZCUVdNc2VVSkJRVUVzUjBGQlIzQkRMRU5CUVVNc1EwRkJRekJDTEV0QlFVc3NRMEZCUXl4RlFVRkZMRVZCUVVVN1JVRkRia1FzV1VGQldTeEZRVUZGTVVJc1EwRkJReXhEUVVGRGQwSXNSMEZCUnl4RFFVRkRMR1ZCUVdVc1EwRkJRenRGUVVOd1F5eGxRVUZsTEVWQlFVVXNVVUZCVVR0RlFVTjZRaXhsUVVGbExFVkJRVVY0UWl4RFFVRkRMRU5CUVVNeVFpeEhRVUZITEVOQlFVTXNVVUZCVVN4RFFVRkRPMFZCUTJoRExFOUJRVThzUlVGQlJUTkNMRU5CUVVNc1EwRkJRekpDTEVkQlFVY3NRMEZCUXl4UlFVRlJMRU5CUVVNN1JVRkRlRUlzV1VGQldTeEZRVUZGTTBJc1EwRkJReXhEUVVGRE1rSXNSMEZCUnl4RFFVRkRMRkZCUVZFN1EwRkROMElzUTBGQlF6dEJRVVZMTEUxQlFVMVZMREJDUVVFd1FpeEhRVUZCWml4UFFVRkJMRU5CUVVGbExEQkNRVUZCTEVkQlFVZHlReXhEUVVGRExFTkJRVU13UWl4TFFVRkxMRU5CUVVNc1JVRkJSU3hGUVVGRk8wVkJRM0JFTEZWQlFWVXNSVUZCUlN4UlFVRlJPMFZCUTNCQ0xHTkJRV01zUlVGQlJTeFJRVUZSTzBWQlEzaENMRmxCUVZrc1JVRkJSU3hSUVVGUk8wVkJRM1JDTEU5QlFVOHNSVUZCUlN4UlFVRlJPMFZCUTJwQ0xHVkJRV1VzUlVGQlJTeFJRVUZSTzBWQlEzcENMRmxCUVZrc1JVRkJSVEZDTEVOQlFVTXNRMEZCUTNkQ0xFZEJRVWNzUTBGQlF5eFJRVUZSTzBOQlF6ZENMRU5CUVVNN1FVRkZTeXhOUVVGTll5eGhRVUZoTEVkQlFVRm9RaXhQUVVGQkxFTkJRVUZuUWl4aFFVRkJMRWRCUVVkMFF5eERRVUZETEVOQlFVTXdRaXhMUVVGTExFTkJRVU1zUlVGQlJTeEZRVUZGTzBWQlEzWkRMR05CUVdNc1JVRkJSU3hSUVVGUk8wVkJRM2hDTEdGQlFXRXNSVUZCUlN4UlFVRlJPMFZCUTNaQ0xHVkJRV1VzUlVGQlJTeFJRVUZSTzBWQlEzcENMRkZCUVZFc1JVRkJSVEZDTEVOQlFVTXNRMEZCUTNWRExFdEJRVXNzUTBGQlF5eFJRVUZSTzBOQlF6TkNMRU5CUVVNN1FVRkZTeXhOUVVGTlF5eHhRa0ZCY1VJc1IwRkJRV3hDTEU5QlFVRXNRMEZCUVd0Q0xIRkNRVUZCTEVkQlFVZDRReXhEUVVGRExFTkJRVU13UWl4TFFVRkxMRU5CUVVNc1JVRkJSU3hGUVVGRk8wVkJReTlETEVOQlFVTXhRaXhEUVVGRExFTkJRVU41UXl4UlFVRlJMRWRCUVVjN1EwRkRaaXhEUVVGRE8wRkJSVXNzVFVGQlRVTXNhMEpCUVd0Q0xFZEJRVUZ3UWl4UFFVRkJMRU5CUVVGdlFpeHJRa0ZCUVN4SFFVRkhNVU1zUTBGQlF5eERRVUZETUVJc1MwRkJTeXhEUVVGRExFVkJRVVVzUlVGQlJUdEZRVU0xUXl4UFFVRlBMRVZCUVVVc1VVRkJVVHRGUVVOcVFpeHRRa0ZCYlVJc1JVRkJSVHREUVVOMFFpeERRVUZETzBGQlJVWXNUVUZCVFdsQ0xHbENRVUZwUWl4SFFVRnBRanRGUVVOMFEzUkNMRXRCUVVzN1JVRkRURWtzYjBKQlFXOUNPMFZCUTNCQ1J5eHJRa0ZCYTBJN1JVRkRiRUpETEhGQ1FVRnhRanRGUVVOeVFrTXNhMEpCUVd0Q08wVkJRMnhDUXl4dFFrRkJiVUk3UlVGRGJrSkRMREJDUVVFd1FqdEZRVU14UWtNc01rSkJRVEpDTzBWQlF6TkNReXgzUWtGQmQwSTdSVUZEZUVKRExIbENRVUY1UWp0RlFVTjZRa01zZVVKQlFYbENPMFZCUTNwQ1F5d3dRa0ZCTUVJN1JVRkRNVUpETEdGQlFXRTdSVUZEWWtVc2NVSkJRWEZDTzBWQlEzSkNSVHREUVVORU8wRkJRVU1zU1VGQlFVVXNVVUZCUVN4SFFVRkJkRUlzVDBGQlFTeERRVUZCVml4UFFVRkJMRWRCUTJFclFpeHBRa0ZCYVVJaUxDSnBaMjV2Y21WTWFYTjBJanBiWFgwPSIsIlwidXNlIHN0cmljdFwiO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy50eXBlU3VpdGUgPSBleHBvcnRzLmRlZmF1bHQgPSBleHBvcnRzLmNoZWNrZXJzID0gdm9pZCAwO1xudmFyIF90c0ludGVyZmFjZUNoZWNrZXIgPSByZXF1aXJlKFwidHMtaW50ZXJmYWNlLWNoZWNrZXJcIik7XG52YXIgX2FwaUF1dGhUeXBlc1RpID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiLi9hcGktYXV0aC10eXBlcy10aS5qc1wiKSk7XG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KGUpIHsgcmV0dXJuIGUgJiYgZS5fX2VzTW9kdWxlID8gZSA6IHsgZGVmYXVsdDogZSB9OyB9XG4vLyBUaGlzIG1vZHVsZSB3YXMgYXV0b21hdGljYWxseSBnZW5lcmF0ZWQgYnkgbm9kZSB0cy1pbnRlcmZhY2UtcG9zdC50c1xuLy8gMjAyNi0wOC0yMVQwNjoyMDo1NC42MjZaXG5cbi8vIFR5cGUgZGVmaW5pdGlvbnNcbmNvbnN0IHR5cGVTdWl0ZSA9IGV4cG9ydHMudHlwZVN1aXRlID0gX2FwaUF1dGhUeXBlc1RpLmRlZmF1bHQ7XG4vLyBDaGVja2Vyc1xuY29uc3QgY2hlY2tlcnMgPSBleHBvcnRzLmNoZWNrZXJzID0gKDAsIF90c0ludGVyZmFjZUNoZWNrZXIuY3JlYXRlQ2hlY2tlcnMpKF9hcGlBdXRoVHlwZXNUaS5kZWZhdWx0KTtcbi8vIEV4cG9ydCB0aGUgY2hlY2tlcnMgYnkgZGVmYXVsdFxudmFyIF9kZWZhdWx0ID0gZXhwb3J0cy5kZWZhdWx0ID0gY2hlY2tlcnM7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldD11dGYtODtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnVZVzFsY3lJNld5SmZkSE5KYm5SbGNtWmhZMlZEYUdWamEyVnlJaXdpY21WeGRXbHlaU0lzSWw5aGNHbEJkWFJvVkhsd1pYTlVhU0lzSWw5cGJuUmxjbTl3VW1WeGRXbHlaVVJsWm1GMWJIUWlMQ0psSWl3aVgxOWxjMDF2WkhWc1pTSXNJbVJsWm1GMWJIUWlMQ0owZVhCbFUzVnBkR1VpTENKbGVIQnZjblJ6SWl3aVpYaHdiM0owWldSVWVYQmxVM1ZwZEdVaUxDSmphR1ZqYTJWeWN5SXNJbU55WldGMFpVTm9aV05yWlhKeklpd2lYMlJsWm1GMWJIUWlYU3dpYzI5MWNtTmxjeUk2V3lJdUxpOHVMaTl6Y21NdmRHa3ZZWEJwTFdGMWRHZ3RkSGx3WlhNdWRITWlYU3dpYzI5MWNtTmxjME52Ym5SbGJuUWlPbHR1ZFd4c1hTd2liV0Z3Y0dsdVozTWlPaUk3T3pzN096dEJRVWRCTEVsQlFVRkJMRzFDUVVGQkxFZEJRVUZETEU5QlFVRTdRVUZGUVN4SlFVRkJReXhsUVVGQkxFZEJRVUZETEhOQ1FVRkJMRU5CUVVGR0xFOUJRVUU3UVVGQmRVUXNVMEZCUVVVc2RVSkJRVUZETEVOQlFVRXNWMEZCUVVFc1EwRkJRU3hKUVVGQlFTeERRVUZCTEVOQlFVRkRMRlZCUVVFc1IwRkJRVVFzUTBGQlFTeExRVUZCUlN4UFFVRkJMRVZCUVVGR0xFTkJRVUU3UVVGTWRrUTdRVUZEUVRzN1FVRjVRa0U3UVVGRFR5eE5RVUZOUnl4VFFVRlRMRWRCUVVGRExFOUJRVUVzUTBGQlFVUXNVMEZCUVN4SFFVRkhSU3gxUWtGblFuaENPMEZCUlVRN1FVRkRUeXhOUVVGTlF5eFJRVUZSTEVkQlFVRkdMRTlCUVVFc1EwRkJRVVVzVVVGQlFTeEhRVUZITEVsQlFVRkRMR3REUVVGakxFVkJRVU5HTEhWQ1FVRnBRaXhEUVdkQ2RrUTdRVUZGUkR0QlFVRkJMRWxCUVVGSExGRkJRVUVzUjBGQlFVb3NUMEZCUVN4RFFVRkJSaXhQUVVGQkxFZEJRMlZKTEZGQlFWRWlMQ0pwWjI1dmNtVk1hWE4wSWpwYlhYMD0iLCJcInVzZSBzdHJpY3RcIjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IGV4cG9ydHMuVmFsdWUgPSBleHBvcnRzLlN0YXR1c2VzV3JhcHBlciA9IGV4cG9ydHMuU3RhdHVzV3JhcHBlciA9IGV4cG9ydHMuU3RhdHVzU3RyaW5nID0gZXhwb3J0cy5TdGF0dXNOdW1iZXIgPSBleHBvcnRzLlN0YXR1c0NvbW1vbiA9IGV4cG9ydHMuU3RhdHVzQm9vbGVhbiA9IGV4cG9ydHMuU3RhdHVzID0gZXhwb3J0cy5TZXR0aW5nc1dyYXBwZXIgPSBleHBvcnRzLlNldHRpbmdXcmFwcGVyID0gZXhwb3J0cy5TZXR0aW5nU3RyaW5nID0gZXhwb3J0cy5TZXR0aW5nTnVtYmVyID0gZXhwb3J0cy5TZXR0aW5nQ29tbW9uID0gZXhwb3J0cy5TZXR0aW5nQm9vbGVhbiA9IGV4cG9ydHMuU2V0dGluZyA9IGV4cG9ydHMuUHJvZ3JhbXNXcmFwcGVyID0gZXhwb3J0cy5Qcm9ncmFtcyA9IGV4cG9ydHMuUHJvZ3JhbVdyYXBwZXIgPSBleHBvcnRzLlByb2dyYW1QYXJ0aWFsID0gZXhwb3J0cy5Qcm9ncmFtTGlzdCA9IGV4cG9ydHMuUHJvZ3JhbUV4ZWN1dGlvbiA9IGV4cG9ydHMuUHJvZ3JhbURlZmluaXRpb25XcmFwcGVyID0gZXhwb3J0cy5Qcm9ncmFtRGVmaW5pdGlvbiA9IGV4cG9ydHMuUHJvZ3JhbUNvbnN0cmFpbnRzID0gZXhwb3J0cy5Qcm9ncmFtID0gZXhwb3J0cy5PcHRpb25zV3JhcHBlciA9IGV4cG9ydHMuT3B0aW9uV3JhcHBlciA9IGV4cG9ydHMuT3B0aW9uRGVmaW5pdGlvblN0cmluZyA9IGV4cG9ydHMuT3B0aW9uRGVmaW5pdGlvbk51bWJlciA9IGV4cG9ydHMuT3B0aW9uRGVmaW5pdGlvbkNvbW1vbiA9IGV4cG9ydHMuT3B0aW9uRGVmaW5pdGlvbkJvb2xlYW4gPSBleHBvcnRzLk9wdGlvbkRlZmluaXRpb24gPSBleHBvcnRzLk9wdGlvbkNvbnN0cmFpbnRzQ29tbW9uID0gZXhwb3J0cy5PcHRpb24gPSBleHBvcnRzLkltYWdlc1dyYXBwZXIgPSBleHBvcnRzLkltYWdlUXVhbGl0eSA9IGV4cG9ydHMuSW1hZ2UgPSBleHBvcnRzLkhvbWVBcHBsaWFuY2VzV3JhcHBlciA9IGV4cG9ydHMuSG9tZUFwcGxpYW5jZVdyYXBwZXIgPSBleHBvcnRzLkhvbWVBcHBsaWFuY2UgPSBleHBvcnRzLkV4ZWN1dGVDb21tYW5kV3JhcHBlciA9IGV4cG9ydHMuRXhlY3V0ZUNvbW1hbmQgPSBleHBvcnRzLkV2ZW50TGV2ZWwgPSBleHBvcnRzLkV2ZW50S2VlcEFsaXZlID0gZXhwb3J0cy5FdmVudEhhbmRsaW5nID0gZXhwb3J0cy5FdmVudERhdGEgPSBleHBvcnRzLkV2ZW50QXBwbGlhbmNlRGF0YSA9IGV4cG9ydHMuRXZlbnRBcHBsaWFuY2VDb25uZWN0aW9uID0gZXhwb3J0cy5FdmVudCA9IGV4cG9ydHMuRXJyb3JSZXNwb25zZSA9IGV4cG9ydHMuQ29uc3RyYWludHNTdHJpbmcgPSBleHBvcnRzLkNvbnN0cmFpbnRzTnVtYmVyID0gZXhwb3J0cy5Db25zdHJhaW50c0NvbW1vbiA9IGV4cG9ydHMuQ29uc3RyYWludHNCb29sZWFuID0gZXhwb3J0cy5Db25zdHJhaW50cyA9IGV4cG9ydHMuQ29tbWFuZHNXcmFwcGVyID0gZXhwb3J0cy5Db21tYW5kID0gZXhwb3J0cy5BY2Nlc3MgPSB2b2lkIDA7XG52YXIgdCA9IF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkKHJlcXVpcmUoXCJ0cy1pbnRlcmZhY2UtY2hlY2tlclwiKSk7XG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZChlLCB0KSB7IGlmIChcImZ1bmN0aW9uXCIgPT0gdHlwZW9mIFdlYWtNYXApIHZhciByID0gbmV3IFdlYWtNYXAoKSwgbiA9IG5ldyBXZWFrTWFwKCk7IHJldHVybiAoX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQgPSBmdW5jdGlvbiAoZSwgdCkgeyBpZiAoIXQgJiYgZSAmJiBlLl9fZXNNb2R1bGUpIHJldHVybiBlOyB2YXIgbywgaSwgZiA9IHsgX19wcm90b19fOiBudWxsLCBkZWZhdWx0OiBlIH07IGlmIChudWxsID09PSBlIHx8IFwib2JqZWN0XCIgIT0gdHlwZW9mIGUgJiYgXCJmdW5jdGlvblwiICE9IHR5cGVvZiBlKSByZXR1cm4gZjsgaWYgKG8gPSB0ID8gbiA6IHIpIHsgaWYgKG8uaGFzKGUpKSByZXR1cm4gby5nZXQoZSk7IG8uc2V0KGUsIGYpOyB9IGZvciAoY29uc3QgdCBpbiBlKSBcImRlZmF1bHRcIiAhPT0gdCAmJiB7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGUsIHQpICYmICgoaSA9IChvID0gT2JqZWN0LmRlZmluZVByb3BlcnR5KSAmJiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGUsIHQpKSAmJiAoaS5nZXQgfHwgaS5zZXQpID8gbyhmLCB0LCBpKSA6IGZbdF0gPSBlW3RdKTsgcmV0dXJuIGY7IH0pKGUsIHQpOyB9XG4vKipcbiAqIFRoaXMgbW9kdWxlIHdhcyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBieSBgdHMtaW50ZXJmYWNlLWJ1aWxkZXJgXG4gKi9cblxuLy8gdHNsaW50OmRpc2FibGU6b2JqZWN0LWxpdGVyYWwta2V5LXF1b3Rlc1xuY29uc3QgVmFsdWUgPSBleHBvcnRzLlZhbHVlID0gdC51bmlvbihcInN0cmluZ1wiLCBcIm51bWJlclwiLCBcImJvb2xlYW5cIik7XG5jb25zdCBDb25zdHJhaW50cyA9IGV4cG9ydHMuQ29uc3RyYWludHMgPSB0LnVuaW9uKFwiQ29uc3RyYWludHNTdHJpbmdcIiwgXCJDb25zdHJhaW50c051bWJlclwiLCBcIkNvbnN0cmFpbnRzQm9vbGVhblwiKTtcbmNvbnN0IENvbnN0cmFpbnRzU3RyaW5nID0gZXhwb3J0cy5Db25zdHJhaW50c1N0cmluZyA9IHQuaWZhY2UoW1wiQ29uc3RyYWludHNDb21tb25cIl0sIHtcbiAgXCJkZWZhdWx0XCI6IHQub3B0KFwic3RyaW5nXCIpLFxuICBcImFsbG93ZWR2YWx1ZXNcIjogdC5vcHQodC5hcnJheShcInN0cmluZ1wiKSksXG4gIFwiZGlzcGxheXZhbHVlc1wiOiB0Lm9wdCh0LmFycmF5KFwic3RyaW5nXCIpKVxufSk7XG5jb25zdCBDb25zdHJhaW50c051bWJlciA9IGV4cG9ydHMuQ29uc3RyYWludHNOdW1iZXIgPSB0LmlmYWNlKFtcIkNvbnN0cmFpbnRzQ29tbW9uXCJdLCB7XG4gIFwiZGVmYXVsdFwiOiB0Lm9wdChcIm51bWJlclwiKSxcbiAgXCJtaW5cIjogdC5vcHQoXCJudW1iZXJcIiksXG4gIFwibWF4XCI6IHQub3B0KFwibnVtYmVyXCIpLFxuICBcInN0ZXBzaXplXCI6IHQub3B0KFwibnVtYmVyXCIpXG59KTtcbmNvbnN0IENvbnN0cmFpbnRzQm9vbGVhbiA9IGV4cG9ydHMuQ29uc3RyYWludHNCb29sZWFuID0gdC5pZmFjZShbXCJDb25zdHJhaW50c0NvbW1vblwiXSwge1xuICBcImRlZmF1bHRcIjogdC5vcHQoXCJib29sZWFuXCIpXG59KTtcbmNvbnN0IENvbnN0cmFpbnRzQ29tbW9uID0gZXhwb3J0cy5Db25zdHJhaW50c0NvbW1vbiA9IHQuaWZhY2UoW10sIHtcbiAgXCJhY2Nlc3NcIjogdC5vcHQoXCJBY2Nlc3NcIilcbn0pO1xuY29uc3QgQWNjZXNzID0gZXhwb3J0cy5BY2Nlc3MgPSB0LnVuaW9uKHQubGl0KCdyZWFkJyksIHQubGl0KCdyZWFkV3JpdGUnKSk7XG5jb25zdCBFeGVjdXRlQ29tbWFuZFdyYXBwZXIgPSBleHBvcnRzLkV4ZWN1dGVDb21tYW5kV3JhcHBlciA9IHQuaWZhY2UoW10sIHtcbiAgXCJkYXRhXCI6IFwiRXhlY3V0ZUNvbW1hbmRcIlxufSk7XG5jb25zdCBFeGVjdXRlQ29tbWFuZCA9IGV4cG9ydHMuRXhlY3V0ZUNvbW1hbmQgPSB0LmlmYWNlKFtdLCB7XG4gIFwia2V5XCI6IFwic3RyaW5nXCIsXG4gIFwidmFsdWVcIjogdC5saXQodHJ1ZSlcbn0pO1xuY29uc3QgQ29tbWFuZHNXcmFwcGVyID0gZXhwb3J0cy5Db21tYW5kc1dyYXBwZXIgPSB0LmlmYWNlKFtdLCB7XG4gIFwiZGF0YVwiOiB0LmlmYWNlKFtdLCB7XG4gICAgXCJjb21tYW5kc1wiOiB0LmFycmF5KFwiQ29tbWFuZFwiKVxuICB9KVxufSk7XG5jb25zdCBDb21tYW5kID0gZXhwb3J0cy5Db21tYW5kID0gdC5pZmFjZShbXSwge1xuICBcImtleVwiOiBcInN0cmluZ1wiLFxuICBcIm5hbWVcIjogdC5vcHQoXCJzdHJpbmdcIiksXG4gIFwiZGVzY3JpcHRpb25cIjogdC5vcHQoXCJzdHJpbmdcIilcbn0pO1xuY29uc3QgRXZlbnQgPSBleHBvcnRzLkV2ZW50ID0gdC51bmlvbihcIkV2ZW50S2VlcEFsaXZlXCIsIFwiRXZlbnRBcHBsaWFuY2VDb25uZWN0aW9uXCIsIFwiRXZlbnRBcHBsaWFuY2VEYXRhXCIpO1xuY29uc3QgRXZlbnRLZWVwQWxpdmUgPSBleHBvcnRzLkV2ZW50S2VlcEFsaXZlID0gdC5pZmFjZShbXSwge1xuICBcImV2ZW50XCI6IHQubGl0KCdLRUVQLUFMSVZFJyksXG4gIFwiZGF0YVwiOiB0Lm9wdCh0LmxpdCgnJykpXG59KTtcbmNvbnN0IEV2ZW50QXBwbGlhbmNlQ29ubmVjdGlvbiA9IGV4cG9ydHMuRXZlbnRBcHBsaWFuY2VDb25uZWN0aW9uID0gdC5pZmFjZShbXSwge1xuICBcImV2ZW50XCI6IHQudW5pb24odC5saXQoJ0NPTk5FQ1RFRCcpLCB0LmxpdCgnRElTQ09OTkVDVEVEJyksIHQubGl0KCdQQUlSRUQnKSwgdC5saXQoJ0RFUEFJUkVEJykpLFxuICBcImlkXCI6IFwic3RyaW5nXCIsXG4gIFwiZGF0YVwiOiB0Lm9wdCh0LnVuaW9uKHQubGl0KCcnKSwgXCJFdmVudERhdGFcIikpXG59KTtcbmNvbnN0IEV2ZW50QXBwbGlhbmNlRGF0YSA9IGV4cG9ydHMuRXZlbnRBcHBsaWFuY2VEYXRhID0gdC5pZmFjZShbXSwge1xuICBcImV2ZW50XCI6IHQudW5pb24odC5saXQoJ1NUQVRVUycpLCB0LmxpdCgnRVZFTlQnKSwgdC5saXQoJ05PVElGWScpKSxcbiAgXCJpZFwiOiBcInN0cmluZ1wiLFxuICBcImRhdGFcIjogdC5pZmFjZShbXSwge1xuICAgIFwiaXRlbXNcIjogdC5hcnJheShcIkV2ZW50RGF0YVwiKSxcbiAgICBcImhhSWRcIjogdC5vcHQoXCJzdHJpbmdcIilcbiAgfSlcbn0pO1xuY29uc3QgRXZlbnREYXRhID0gZXhwb3J0cy5FdmVudERhdGEgPSB0LmlmYWNlKFtdLCB7XG4gIFwia2V5XCI6IFwic3RyaW5nXCIsXG4gIFwibmFtZVwiOiB0Lm9wdChcInN0cmluZ1wiKSxcbiAgXCJ1cmlcIjogdC5vcHQoXCJzdHJpbmdcIiksXG4gIFwidGltZXN0YW1wXCI6IHQudW5pb24oXCJudW1iZXJcIiwgXCJudWxsXCIpLFxuICBcImxldmVsXCI6IFwiRXZlbnRMZXZlbFwiLFxuICBcImhhbmRsaW5nXCI6IFwiRXZlbnRIYW5kbGluZ1wiLFxuICBcInZhbHVlXCI6IHQudW5pb24oXCJWYWx1ZVwiLCBcIm51bGxcIiksXG4gIFwiZGlzcGxheXZhbHVlXCI6IHQub3B0KFwic3RyaW5nXCIpLFxuICBcInVuaXRcIjogdC5vcHQoXCJzdHJpbmdcIiksXG4gIFwiaGFJZFwiOiB0Lm9wdChcInN0cmluZ1wiKVxufSk7XG5jb25zdCBFdmVudExldmVsID0gZXhwb3J0cy5FdmVudExldmVsID0gdC51bmlvbih0LmxpdCgnY3JpdGljYWwnKSwgdC5saXQoJ2FsZXJ0JyksIHQubGl0KCd3YXJuaW5nJyksIHQubGl0KCdoaW50JyksIHQubGl0KCdpbmZvJykpO1xuY29uc3QgRXZlbnRIYW5kbGluZyA9IGV4cG9ydHMuRXZlbnRIYW5kbGluZyA9IHQudW5pb24odC5saXQoJ25vbmUnKSwgdC5saXQoJ2Fja25vd2xlZGdlJyksIHQubGl0KCdkZWNpc2lvbicpKTtcbmNvbnN0IEhvbWVBcHBsaWFuY2VzV3JhcHBlciA9IGV4cG9ydHMuSG9tZUFwcGxpYW5jZXNXcmFwcGVyID0gdC5pZmFjZShbXSwge1xuICBcImRhdGFcIjogdC5pZmFjZShbXSwge1xuICAgIFwiaG9tZWFwcGxpYW5jZXNcIjogdC5hcnJheShcIkhvbWVBcHBsaWFuY2VcIilcbiAgfSlcbn0pO1xuY29uc3QgSG9tZUFwcGxpYW5jZVdyYXBwZXIgPSBleHBvcnRzLkhvbWVBcHBsaWFuY2VXcmFwcGVyID0gdC5pZmFjZShbXSwge1xuICBcImRhdGFcIjogXCJIb21lQXBwbGlhbmNlXCJcbn0pO1xuY29uc3QgSG9tZUFwcGxpYW5jZSA9IGV4cG9ydHMuSG9tZUFwcGxpYW5jZSA9IHQuaWZhY2UoW10sIHtcbiAgXCJoYUlkXCI6IFwic3RyaW5nXCIsXG4gIFwibmFtZVwiOiBcInN0cmluZ1wiLFxuICBcInR5cGVcIjogXCJzdHJpbmdcIixcbiAgXCJicmFuZFwiOiBcInN0cmluZ1wiLFxuICBcInZpYlwiOiBcInN0cmluZ1wiLFxuICBcImVudW1iZXJcIjogXCJzdHJpbmdcIixcbiAgXCJjb25uZWN0ZWRcIjogXCJib29sZWFuXCJcbn0pO1xuY29uc3QgSW1hZ2VzV3JhcHBlciA9IGV4cG9ydHMuSW1hZ2VzV3JhcHBlciA9IHQuaWZhY2UoW10sIHtcbiAgXCJkYXRhXCI6IHQuaWZhY2UoW10sIHtcbiAgICBcImltYWdlc1wiOiB0LmFycmF5KFwiSW1hZ2VcIilcbiAgfSlcbn0pO1xuY29uc3QgSW1hZ2UgPSBleHBvcnRzLkltYWdlID0gdC5pZmFjZShbXSwge1xuICBcImtleVwiOiBcInN0cmluZ1wiLFxuICBcIm5hbWVcIjogdC5vcHQoXCJzdHJpbmdcIiksXG4gIFwiaW1hZ2VrZXlcIjogXCJzdHJpbmdcIixcbiAgXCJwcmV2aWV3aW1hZ2VrZXlcIjogXCJzdHJpbmdcIixcbiAgXCJ0aW1lc3RhbXBcIjogXCJudW1iZXJcIixcbiAgXCJxdWFsaXR5XCI6IFwiSW1hZ2VRdWFsaXR5XCJcbn0pO1xuY29uc3QgSW1hZ2VRdWFsaXR5ID0gZXhwb3J0cy5JbWFnZVF1YWxpdHkgPSB0LnVuaW9uKHQubGl0KCdnb29kJyksIHQubGl0KCdiYWQnKSk7XG5jb25zdCBQcm9ncmFtc1dyYXBwZXIgPSBleHBvcnRzLlByb2dyYW1zV3JhcHBlciA9IHQuaWZhY2UoW10sIHtcbiAgXCJkYXRhXCI6IFwiUHJvZ3JhbXNcIlxufSk7XG5jb25zdCBQcm9ncmFtcyA9IGV4cG9ydHMuUHJvZ3JhbXMgPSB0LmlmYWNlKFtdLCB7XG4gIFwicHJvZ3JhbXNcIjogdC5hcnJheShcIlByb2dyYW1MaXN0XCIpLFxuICBcInNlbGVjdGVkXCI6IHQub3B0KFwiUHJvZ3JhbVBhcnRpYWxcIiksXG4gIFwiYWN0aXZlXCI6IHQub3B0KFwiUHJvZ3JhbVBhcnRpYWxcIilcbn0pO1xuY29uc3QgUHJvZ3JhbUxpc3QgPSBleHBvcnRzLlByb2dyYW1MaXN0ID0gdC5pZmFjZShbXSwge1xuICBcImtleVwiOiBcInN0cmluZ1wiLFxuICBcIm5hbWVcIjogdC5vcHQoXCJzdHJpbmdcIiksXG4gIFwiY29uc3RyYWludHNcIjogdC5vcHQoXCJQcm9ncmFtQ29uc3RyYWludHNcIilcbn0pO1xuY29uc3QgUHJvZ3JhbUNvbnN0cmFpbnRzID0gZXhwb3J0cy5Qcm9ncmFtQ29uc3RyYWludHMgPSB0LmlmYWNlKFtdLCB7XG4gIFwiYXZhaWxhYmxlXCI6IHQub3B0KFwiYm9vbGVhblwiKSxcbiAgXCJleGVjdXRpb25cIjogdC5vcHQoXCJQcm9ncmFtRXhlY3V0aW9uXCIpLFxuICBcImFjY2Vzc1wiOiB0Lm9wdChcIkFjY2Vzc1wiKVxufSk7XG5jb25zdCBQcm9ncmFtRXhlY3V0aW9uID0gZXhwb3J0cy5Qcm9ncmFtRXhlY3V0aW9uID0gdC51bmlvbih0LmxpdCgnbm9uZScpLCB0LmxpdCgnc2VsZWN0b25seScpLCB0LmxpdCgnc3RhcnRvbmx5JyksIHQubGl0KCdzZWxlY3RhbmRzdGFydCcpKTtcbmNvbnN0IFByb2dyYW1XcmFwcGVyID0gZXhwb3J0cy5Qcm9ncmFtV3JhcHBlciA9IHQuaWZhY2UoW10sIHtcbiAgXCJkYXRhXCI6IFwiUHJvZ3JhbVwiXG59KTtcbmNvbnN0IFByb2dyYW0gPSBleHBvcnRzLlByb2dyYW0gPSB0LmlmYWNlKFtcIlByb2dyYW1QYXJ0aWFsXCJdLCB7XG4gIFwia2V5XCI6IFwic3RyaW5nXCJcbn0pO1xuY29uc3QgUHJvZ3JhbVBhcnRpYWwgPSBleHBvcnRzLlByb2dyYW1QYXJ0aWFsID0gdC5pZmFjZShbXSwge1xuICBcImtleVwiOiB0Lm9wdChcInN0cmluZ1wiKSxcbiAgXCJuYW1lXCI6IHQub3B0KFwic3RyaW5nXCIpLFxuICBcIm9wdGlvbnNcIjogdC5vcHQodC5hcnJheShcIk9wdGlvblwiKSksXG4gIFwiY29uc3RyYWludHNcIjogdC5vcHQoXCJQcm9ncmFtQ29uc3RyYWludHNcIilcbn0pO1xuY29uc3QgUHJvZ3JhbURlZmluaXRpb25XcmFwcGVyID0gZXhwb3J0cy5Qcm9ncmFtRGVmaW5pdGlvbldyYXBwZXIgPSB0LmlmYWNlKFtdLCB7XG4gIFwiZGF0YVwiOiBcIlByb2dyYW1EZWZpbml0aW9uXCJcbn0pO1xuY29uc3QgUHJvZ3JhbURlZmluaXRpb24gPSBleHBvcnRzLlByb2dyYW1EZWZpbml0aW9uID0gdC5pZmFjZShbXSwge1xuICBcImtleVwiOiBcInN0cmluZ1wiLFxuICBcIm5hbWVcIjogdC5vcHQoXCJzdHJpbmdcIiksXG4gIFwib3B0aW9uc1wiOiB0Lm9wdCh0LmFycmF5KFwiT3B0aW9uRGVmaW5pdGlvblwiKSlcbn0pO1xuY29uc3QgT3B0aW9uRGVmaW5pdGlvbiA9IGV4cG9ydHMuT3B0aW9uRGVmaW5pdGlvbiA9IHQudW5pb24oXCJPcHRpb25EZWZpbml0aW9uU3RyaW5nXCIsIFwiT3B0aW9uRGVmaW5pdGlvbk51bWJlclwiLCBcIk9wdGlvbkRlZmluaXRpb25Cb29sZWFuXCIpO1xuY29uc3QgT3B0aW9uRGVmaW5pdGlvblN0cmluZyA9IGV4cG9ydHMuT3B0aW9uRGVmaW5pdGlvblN0cmluZyA9IHQuaWZhY2UoW1wiT3B0aW9uRGVmaW5pdGlvbkNvbW1vblwiXSwge1xuICBcInR5cGVcIjogdC51bmlvbih0LmxpdCgnU3RyaW5nJyksIFwic3RyaW5nXCIpLFxuICBcImNvbnN0cmFpbnRzXCI6IHQub3B0KHQuaW50ZXJzZWN0aW9uKFwiT3B0aW9uQ29uc3RyYWludHNDb21tb25cIiwgXCJDb25zdHJhaW50c1N0cmluZ1wiKSlcbn0pO1xuY29uc3QgT3B0aW9uRGVmaW5pdGlvbk51bWJlciA9IGV4cG9ydHMuT3B0aW9uRGVmaW5pdGlvbk51bWJlciA9IHQuaWZhY2UoW1wiT3B0aW9uRGVmaW5pdGlvbkNvbW1vblwiXSwge1xuICBcInR5cGVcIjogdC51bmlvbih0LmxpdCgnRG91YmxlJyksIHQubGl0KCdJbnQnKSksXG4gIFwiY29uc3RyYWludHNcIjogdC5vcHQodC5pbnRlcnNlY3Rpb24oXCJPcHRpb25Db25zdHJhaW50c0NvbW1vblwiLCBcIkNvbnN0cmFpbnRzTnVtYmVyXCIpKVxufSk7XG5jb25zdCBPcHRpb25EZWZpbml0aW9uQm9vbGVhbiA9IGV4cG9ydHMuT3B0aW9uRGVmaW5pdGlvbkJvb2xlYW4gPSB0LmlmYWNlKFtcIk9wdGlvbkRlZmluaXRpb25Db21tb25cIl0sIHtcbiAgXCJ0eXBlXCI6IHQubGl0KCdCb29sZWFuJyksXG4gIFwiY29uc3RyYWludHNcIjogdC5vcHQodC5pbnRlcnNlY3Rpb24oXCJPcHRpb25Db25zdHJhaW50c0NvbW1vblwiLCBcIkNvbnN0cmFpbnRzQm9vbGVhblwiKSlcbn0pO1xuY29uc3QgT3B0aW9uRGVmaW5pdGlvbkNvbW1vbiA9IGV4cG9ydHMuT3B0aW9uRGVmaW5pdGlvbkNvbW1vbiA9IHQuaWZhY2UoW10sIHtcbiAgXCJrZXlcIjogXCJzdHJpbmdcIixcbiAgXCJuYW1lXCI6IHQub3B0KFwic3RyaW5nXCIpLFxuICBcInVuaXRcIjogdC5vcHQoXCJzdHJpbmdcIilcbn0pO1xuY29uc3QgT3B0aW9uQ29uc3RyYWludHNDb21tb24gPSBleHBvcnRzLk9wdGlvbkNvbnN0cmFpbnRzQ29tbW9uID0gdC5pZmFjZShbXSwge1xuICBcImxpdmV1cGRhdGVcIjogdC5vcHQoXCJib29sZWFuXCIpXG59KTtcbmNvbnN0IE9wdGlvbnNXcmFwcGVyID0gZXhwb3J0cy5PcHRpb25zV3JhcHBlciA9IHQuaWZhY2UoW10sIHtcbiAgXCJkYXRhXCI6IHQuaWZhY2UoW10sIHtcbiAgICBcIm9wdGlvbnNcIjogdC5hcnJheShcIk9wdGlvblwiKVxuICB9KVxufSk7XG5jb25zdCBPcHRpb25XcmFwcGVyID0gZXhwb3J0cy5PcHRpb25XcmFwcGVyID0gdC5pZmFjZShbXSwge1xuICBcImRhdGFcIjogXCJPcHRpb25cIlxufSk7XG5jb25zdCBPcHRpb24gPSBleHBvcnRzLk9wdGlvbiA9IHQuaWZhY2UoW10sIHtcbiAgXCJrZXlcIjogXCJzdHJpbmdcIixcbiAgXCJuYW1lXCI6IHQub3B0KFwic3RyaW5nXCIpLFxuICBcInZhbHVlXCI6IFwiVmFsdWVcIixcbiAgXCJkaXNwbGF5dmFsdWVcIjogdC5vcHQoXCJzdHJpbmdcIiksXG4gIFwidW5pdFwiOiB0Lm9wdChcInN0cmluZ1wiKVxufSk7XG5jb25zdCBTZXR0aW5nc1dyYXBwZXIgPSBleHBvcnRzLlNldHRpbmdzV3JhcHBlciA9IHQuaWZhY2UoW10sIHtcbiAgXCJkYXRhXCI6IHQuaWZhY2UoW10sIHtcbiAgICBcInNldHRpbmdzXCI6IHQuYXJyYXkoXCJTZXR0aW5nXCIpXG4gIH0pXG59KTtcbmNvbnN0IFNldHRpbmdXcmFwcGVyID0gZXhwb3J0cy5TZXR0aW5nV3JhcHBlciA9IHQuaWZhY2UoW10sIHtcbiAgXCJkYXRhXCI6IFwiU2V0dGluZ1wiXG59KTtcbmNvbnN0IFNldHRpbmcgPSBleHBvcnRzLlNldHRpbmcgPSB0LnVuaW9uKFwiU2V0dGluZ1N0cmluZ1wiLCBcIlNldHRpbmdOdW1iZXJcIiwgXCJTZXR0aW5nQm9vbGVhblwiKTtcbmNvbnN0IFNldHRpbmdTdHJpbmcgPSBleHBvcnRzLlNldHRpbmdTdHJpbmcgPSB0LmlmYWNlKFtcIlNldHRpbmdDb21tb25cIl0sIHtcbiAgXCJ2YWx1ZVwiOiBcInN0cmluZ1wiLFxuICBcImNvbnN0cmFpbnRzXCI6IHQub3B0KFwiQ29uc3RyYWludHNTdHJpbmdcIilcbn0pO1xuY29uc3QgU2V0dGluZ051bWJlciA9IGV4cG9ydHMuU2V0dGluZ051bWJlciA9IHQuaWZhY2UoW1wiU2V0dGluZ0NvbW1vblwiXSwge1xuICBcInZhbHVlXCI6IFwibnVtYmVyXCIsXG4gIFwiY29uc3RyYWludHNcIjogdC5vcHQoXCJDb25zdHJhaW50c051bWJlclwiKVxufSk7XG5jb25zdCBTZXR0aW5nQm9vbGVhbiA9IGV4cG9ydHMuU2V0dGluZ0Jvb2xlYW4gPSB0LmlmYWNlKFtcIlNldHRpbmdDb21tb25cIl0sIHtcbiAgXCJ2YWx1ZVwiOiBcImJvb2xlYW5cIixcbiAgXCJjb25zdHJhaW50c1wiOiB0Lm9wdChcIkNvbnN0cmFpbnRzQm9vbGVhblwiKVxufSk7XG5jb25zdCBTZXR0aW5nQ29tbW9uID0gZXhwb3J0cy5TZXR0aW5nQ29tbW9uID0gdC5pZmFjZShbXSwge1xuICBcImtleVwiOiBcInN0cmluZ1wiLFxuICBcIm5hbWVcIjogdC5vcHQoXCJzdHJpbmdcIiksXG4gIFwidHlwZVwiOiB0Lm9wdChcInN0cmluZ1wiKSxcbiAgXCJkaXNwbGF5dmFsdWVcIjogdC5vcHQoXCJzdHJpbmdcIiksXG4gIFwidW5pdFwiOiB0Lm9wdChcInN0cmluZ1wiKVxufSk7XG5jb25zdCBTdGF0dXNlc1dyYXBwZXIgPSBleHBvcnRzLlN0YXR1c2VzV3JhcHBlciA9IHQuaWZhY2UoW10sIHtcbiAgXCJkYXRhXCI6IHQuaWZhY2UoW10sIHtcbiAgICBcInN0YXR1c1wiOiB0LmFycmF5KFwiU3RhdHVzXCIpXG4gIH0pXG59KTtcbmNvbnN0IFN0YXR1c1dyYXBwZXIgPSBleHBvcnRzLlN0YXR1c1dyYXBwZXIgPSB0LmlmYWNlKFtdLCB7XG4gIFwiZGF0YVwiOiBcIlN0YXR1c1wiXG59KTtcbmNvbnN0IFN0YXR1cyA9IGV4cG9ydHMuU3RhdHVzID0gdC51bmlvbihcIlN0YXR1c1N0cmluZ1wiLCBcIlN0YXR1c051bWJlclwiLCBcIlN0YXR1c0Jvb2xlYW5cIik7XG5jb25zdCBTdGF0dXNTdHJpbmcgPSBleHBvcnRzLlN0YXR1c1N0cmluZyA9IHQuaWZhY2UoW1wiU3RhdHVzQ29tbW9uXCJdLCB7XG4gIFwidmFsdWVcIjogXCJzdHJpbmdcIixcbiAgXCJjb25zdHJhaW50c1wiOiB0Lm9wdChcIkNvbnN0cmFpbnRzU3RyaW5nXCIpXG59KTtcbmNvbnN0IFN0YXR1c051bWJlciA9IGV4cG9ydHMuU3RhdHVzTnVtYmVyID0gdC5pZmFjZShbXCJTdGF0dXNDb21tb25cIl0sIHtcbiAgXCJ2YWx1ZVwiOiBcIm51bWJlclwiLFxuICBcImNvbnN0cmFpbnRzXCI6IHQub3B0KFwiQ29uc3RyYWludHNOdW1iZXJcIilcbn0pO1xuY29uc3QgU3RhdHVzQm9vbGVhbiA9IGV4cG9ydHMuU3RhdHVzQm9vbGVhbiA9IHQuaWZhY2UoW1wiU3RhdHVzQ29tbW9uXCJdLCB7XG4gIFwidmFsdWVcIjogXCJib29sZWFuXCIsXG4gIFwiY29uc3RyYWludHNcIjogdC5vcHQoXCJDb25zdHJhaW50c0Jvb2xlYW5cIilcbn0pO1xuY29uc3QgU3RhdHVzQ29tbW9uID0gZXhwb3J0cy5TdGF0dXNDb21tb24gPSB0LmlmYWNlKFtdLCB7XG4gIFwia2V5XCI6IFwic3RyaW5nXCIsXG4gIFwibmFtZVwiOiB0Lm9wdChcInN0cmluZ1wiKSxcbiAgXCJkaXNwbGF5dmFsdWVcIjogdC5vcHQoXCJzdHJpbmdcIiksXG4gIFwidW5pdFwiOiB0Lm9wdChcInN0cmluZ1wiKVxufSk7XG5jb25zdCBFcnJvclJlc3BvbnNlID0gZXhwb3J0cy5FcnJvclJlc3BvbnNlID0gdC5pZmFjZShbXSwge1xuICBcImVycm9yXCI6IHQuaWZhY2UoW10sIHtcbiAgICBcImtleVwiOiBcInN0cmluZ1wiLFxuICAgIFwiZGVzY3JpcHRpb25cIjogdC5vcHQoXCJzdHJpbmdcIiksXG4gICAgXCJkZXZlbG9wZXJNZXNzYWdlXCI6IHQub3B0KFwic3RyaW5nXCIpLFxuICAgIFwidmFsdWVcIjogdC5vcHQoXCJzdHJpbmdcIilcbiAgfSlcbn0pO1xuY29uc3QgZXhwb3J0ZWRUeXBlU3VpdGUgPSB7XG4gIFZhbHVlLFxuICBDb25zdHJhaW50cyxcbiAgQ29uc3RyYWludHNTdHJpbmcsXG4gIENvbnN0cmFpbnRzTnVtYmVyLFxuICBDb25zdHJhaW50c0Jvb2xlYW4sXG4gIENvbnN0cmFpbnRzQ29tbW9uLFxuICBBY2Nlc3MsXG4gIEV4ZWN1dGVDb21tYW5kV3JhcHBlcixcbiAgRXhlY3V0ZUNvbW1hbmQsXG4gIENvbW1hbmRzV3JhcHBlcixcbiAgQ29tbWFuZCxcbiAgRXZlbnQsXG4gIEV2ZW50S2VlcEFsaXZlLFxuICBFdmVudEFwcGxpYW5jZUNvbm5lY3Rpb24sXG4gIEV2ZW50QXBwbGlhbmNlRGF0YSxcbiAgRXZlbnREYXRhLFxuICBFdmVudExldmVsLFxuICBFdmVudEhhbmRsaW5nLFxuICBIb21lQXBwbGlhbmNlc1dyYXBwZXIsXG4gIEhvbWVBcHBsaWFuY2VXcmFwcGVyLFxuICBIb21lQXBwbGlhbmNlLFxuICBJbWFnZXNXcmFwcGVyLFxuICBJbWFnZSxcbiAgSW1hZ2VRdWFsaXR5LFxuICBQcm9ncmFtc1dyYXBwZXIsXG4gIFByb2dyYW1zLFxuICBQcm9ncmFtTGlzdCxcbiAgUHJvZ3JhbUNvbnN0cmFpbnRzLFxuICBQcm9ncmFtRXhlY3V0aW9uLFxuICBQcm9ncmFtV3JhcHBlcixcbiAgUHJvZ3JhbSxcbiAgUHJvZ3JhbVBhcnRpYWwsXG4gIFByb2dyYW1EZWZpbml0aW9uV3JhcHBlcixcbiAgUHJvZ3JhbURlZmluaXRpb24sXG4gIE9wdGlvbkRlZmluaXRpb24sXG4gIE9wdGlvbkRlZmluaXRpb25TdHJpbmcsXG4gIE9wdGlvbkRlZmluaXRpb25OdW1iZXIsXG4gIE9wdGlvbkRlZmluaXRpb25Cb29sZWFuLFxuICBPcHRpb25EZWZpbml0aW9uQ29tbW9uLFxuICBPcHRpb25Db25zdHJhaW50c0NvbW1vbixcbiAgT3B0aW9uc1dyYXBwZXIsXG4gIE9wdGlvbldyYXBwZXIsXG4gIE9wdGlvbixcbiAgU2V0dGluZ3NXcmFwcGVyLFxuICBTZXR0aW5nV3JhcHBlcixcbiAgU2V0dGluZyxcbiAgU2V0dGluZ1N0cmluZyxcbiAgU2V0dGluZ051bWJlcixcbiAgU2V0dGluZ0Jvb2xlYW4sXG4gIFNldHRpbmdDb21tb24sXG4gIFN0YXR1c2VzV3JhcHBlcixcbiAgU3RhdHVzV3JhcHBlcixcbiAgU3RhdHVzLFxuICBTdGF0dXNTdHJpbmcsXG4gIFN0YXR1c051bWJlcixcbiAgU3RhdHVzQm9vbGVhbixcbiAgU3RhdHVzQ29tbW9uLFxuICBFcnJvclJlc3BvbnNlXG59O1xudmFyIF9kZWZhdWx0ID0gZXhwb3J0cy5kZWZhdWx0ID0gZXhwb3J0ZWRUeXBlU3VpdGU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldD11dGYtODtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnVZVzFsY3lJNld5SjBJaXdpWDJsdWRHVnliM0JTWlhGMWFYSmxWMmxzWkdOaGNtUWlMQ0p5WlhGMWFYSmxJaXdpWlNJc0lsZGxZV3ROWVhBaUxDSnlJaXdpYmlJc0lsOWZaWE5OYjJSMWJHVWlMQ0p2SWl3aWFTSXNJbVlpTENKZlgzQnliM1J2WDE4aUxDSmtaV1poZFd4MElpd2lhR0Z6SWl3aVoyVjBJaXdpYzJWMElpd2lhR0Z6VDNkdVVISnZjR1Z5ZEhraUxDSmpZV3hzSWl3aVQySnFaV04wSWl3aVpHVm1hVzVsVUhKdmNHVnlkSGtpTENKblpYUlBkMjVRY205d1pYSjBlVVJsYzJOeWFYQjBiM0lpTENKV1lXeDFaU0lzSW1WNGNHOXlkSE1pTENKMWJtbHZiaUlzSWtOdmJuTjBjbUZwYm5Seklpd2lRMjl1YzNSeVlXbHVkSE5UZEhKcGJtY2lMQ0pwWm1GalpTSXNJbTl3ZENJc0ltRnljbUY1SWl3aVEyOXVjM1J5WVdsdWRITk9kVzFpWlhJaUxDSkRiMjV6ZEhKaGFXNTBjMEp2YjJ4bFlXNGlMQ0pEYjI1emRISmhhVzUwYzBOdmJXMXZiaUlzSWtGalkyVnpjeUlzSW14cGRDSXNJa1Y0WldOMWRHVkRiMjF0WVc1a1YzSmhjSEJsY2lJc0lrVjRaV04xZEdWRGIyMXRZVzVrSWl3aVEyOXRiV0Z1WkhOWGNtRndjR1Z5SWl3aVEyOXRiV0Z1WkNJc0lrVjJaVzUwSWl3aVJYWmxiblJMWldWd1FXeHBkbVVpTENKRmRtVnVkRUZ3Y0d4cFlXNWpaVU52Ym01bFkzUnBiMjRpTENKRmRtVnVkRUZ3Y0d4cFlXNWpaVVJoZEdFaUxDSkZkbVZ1ZEVSaGRHRWlMQ0pGZG1WdWRFeGxkbVZzSWl3aVJYWmxiblJJWVc1a2JHbHVaeUlzSWtodmJXVkJjSEJzYVdGdVkyVnpWM0poY0hCbGNpSXNJa2h2YldWQmNIQnNhV0Z1WTJWWGNtRndjR1Z5SWl3aVNHOXRaVUZ3Y0d4cFlXNWpaU0lzSWtsdFlXZGxjMWR5WVhCd1pYSWlMQ0pKYldGblpTSXNJa2x0WVdkbFVYVmhiR2wwZVNJc0lsQnliMmR5WVcxelYzSmhjSEJsY2lJc0lsQnliMmR5WVcxeklpd2lVSEp2WjNKaGJVeHBjM1FpTENKUWNtOW5jbUZ0UTI5dWMzUnlZV2x1ZEhNaUxDSlFjbTluY21GdFJYaGxZM1YwYVc5dUlpd2lVSEp2WjNKaGJWZHlZWEJ3WlhJaUxDSlFjbTluY21GdElpd2lVSEp2WjNKaGJWQmhjblJwWVd3aUxDSlFjbTluY21GdFJHVm1hVzVwZEdsdmJsZHlZWEJ3WlhJaUxDSlFjbTluY21GdFJHVm1hVzVwZEdsdmJpSXNJazl3ZEdsdmJrUmxabWx1YVhScGIyNGlMQ0pQY0hScGIyNUVaV1pwYm1sMGFXOXVVM1J5YVc1bklpd2lhVzUwWlhKelpXTjBhVzl1SWl3aVQzQjBhVzl1UkdWbWFXNXBkR2x2Yms1MWJXSmxjaUlzSWs5d2RHbHZia1JsWm1sdWFYUnBiMjVDYjI5c1pXRnVJaXdpVDNCMGFXOXVSR1ZtYVc1cGRHbHZia052YlcxdmJpSXNJazl3ZEdsdmJrTnZibk4wY21GcGJuUnpRMjl0Ylc5dUlpd2lUM0IwYVc5dWMxZHlZWEJ3WlhJaUxDSlBjSFJwYjI1WGNtRndjR1Z5SWl3aVQzQjBhVzl1SWl3aVUyVjBkR2x1WjNOWGNtRndjR1Z5SWl3aVUyVjBkR2x1WjFkeVlYQndaWElpTENKVFpYUjBhVzVuSWl3aVUyVjBkR2x1WjFOMGNtbHVaeUlzSWxObGRIUnBibWRPZFcxaVpYSWlMQ0pUWlhSMGFXNW5RbTl2YkdWaGJpSXNJbE5sZEhScGJtZERiMjF0YjI0aUxDSlRkR0YwZFhObGMxZHlZWEJ3WlhJaUxDSlRkR0YwZFhOWGNtRndjR1Z5SWl3aVUzUmhkSFZ6SWl3aVUzUmhkSFZ6VTNSeWFXNW5JaXdpVTNSaGRIVnpUblZ0WW1WeUlpd2lVM1JoZEhWelFtOXZiR1ZoYmlJc0lsTjBZWFIxYzBOdmJXMXZiaUlzSWtWeWNtOXlVbVZ6Y0c5dWMyVWlMQ0psZUhCdmNuUmxaRlI1Y0dWVGRXbDBaU0lzSWw5a1pXWmhkV3gwSWwwc0luTnZkWEpqWlhNaU9sc2lMaTR2TGk0dmMzSmpMM1JwTDJGd2FTMTBlWEJsY3kxMGFTNTBjeUpkTENKemIzVnlZMlZ6UTI5dWRHVnVkQ0k2VzI1MWJHeGRMQ0p0WVhCd2FXNW5jeUk2SWpzN096czdPMEZCUjBFc1NVRkJRVUVzUTBGQlFTeEhRVUZCUXl4MVFrRkJRU3hEUVVGQlF5eFBRVUZCTzBGQlFUQkRMRk5CUVVGRUxIZENRVUZCUlN4RFFVRkJMRVZCUVVGSUxFTkJRVUVzTmtKQlFVRkpMRTlCUVVFc1RVRkJRVU1zUTBGQlFTeFBRVUZCUkN4UFFVRkJMRWxCUVVGRkxFTkJRVUVzVDBGQlFVWXNUMEZCUVN4WlFVRkJTQ3gxUWtGQlFTeFpRVUZCUVN4RFFVRkJSU3hEUVVGQkxFVkJRVUZJTEVOQlFVRXNVMEZCUVVFc1EwRkJRU3hKUVVGQlJ5eERRVUZCTEVsQlFVRkJMRU5CUVVFc1EwRkJRVWtzVlVGQlFTeFRRVUZCU2l4RFFVRkJMRTFCUVVGTExFTkJRVUVzUlVGQlFVTXNRMEZCUVN4RlFVRkJReXhEUVVGQkxFdEJRVUZETEZOQlFVRXNVVUZCUVVNc1QwRkJRU3hGUVVGQlZDeERRVUZCTEdsQ1FVRkJRU3hEUVVGQkxIVkNRVUZCUVN4RFFVRkJMSGxDUVVGQlFTeERRVUZCTEZOQlFVRlBMRU5CUVVFc1RVRkJRVVlzUTBGQlFTeEhRVUZCVWl4RFFVRkJMRWRCUVVGTkxFTkJRVUVzUjBGQlFVUXNRMEZCUVN4UlFVRkJSeXhEUVVGQkxFTkJRVUZMTEVkQlFVRXNRMEZCUVZZc1EwRkJRU3hWUVVGQlN5eERRVUZCTEVOQlFVRk5MRWRCUVVFc1EwRkJRVmdzUTBGQlFTeEhRVUZCU3l4RFFVRkJMRU5CUVVGUExFZEJRVUVzUTBGQlFWb3NRMEZCUVN4RlFVRkJUeXhEUVVGQkxHZENRVUZCVml4RFFVRkJMRWxCUVVGSExFTkJRVUVzWjBKQlFVRklMRU5CUVVFc1QwRkJRV2RDTEdOQlFVRXNRMEZCUVVNc1NVRkJRU3hEUVVGQlpDeERRVUZCTEVWQlFVRklMRU5CUVVFc1QwRkJRVk1zUTBGQlFTeEpRVUZCUkN4RFFVRkJMRWRCUVVGVkxFMUJRVUVzUTBGQlFVTXNZMEZCUVN4TFFVRkJSQ3hOUVVGQkxFTkJRVUZGTEhkQ1FVRkJMRU5CUVVGcVFpeERRVUZCTEVWQlFVRklMRU5CUVVFc1QwRkJRVk1zUTBGQlFTeERRVUZCU3l4SFFVRkJMRWxCUVVGTUxFTkJRVUVzUTBGQlFVMHNSMEZCUVN4SlFVRkJVQ3hEUVVGQkxFTkJRVUZGTEVOQlFVRXNSVUZCUVZZc1EwRkJRU3hGUVVGQlV5eERRVUZCTEVsQlFVRkRMRU5CUVVFc1EwRkJRVllzUTBGQlFTeEpRVUZCUnl4RFFVRkJMRU5CUVVGSUxFTkJRVUVzVjBGQlFWVXNRMEZCUVN4TFFVRkJVQ3hEUVVGQkxFVkJRVUZJTEVOQlFVRTdRVUZJTVVNN096czdRVUZKUVR0QlFVVlBMRTFCUVUxeFFpeExRVUZMTEVkQlFVRkRMRTlCUVVFc1EwRkJRVVFzUzBGQlFTeEhRVUZIY2tJc1EwRkJReXhEUVVGRGRVSXNTMEZCU3l4RFFVRkRMRkZCUVZFc1JVRkJSU3hSUVVGUkxFVkJRVVVzVTBGQlV5eERRVUZETzBGQlJYQkVMRTFCUVUxRExGZEJRVmNzUjBGQlFVWXNUMEZCUVN4RFFVRkJSU3hYUVVGQkxFZEJRVWQ0UWl4RFFVRkRMRU5CUVVOMVFpeExRVUZMTEVOQlFVTXNiVUpCUVcxQ0xFVkJRVVVzYlVKQlFXMUNMRVZCUVVVc2IwSkJRVzlDTEVOQlFVTTdRVUZGTTBZc1RVRkJUVVVzYVVKQlFXbENMRWRCUVVGSUxFOUJRVUVzUTBGQlFVY3NhVUpCUVVFc1IwRkJSM3BDTEVOQlFVTXNRMEZCUXpCQ0xFdEJRVXNzUTBGQlF5eERRVUZETEcxQ1FVRnRRaXhEUVVGRExFVkJRVVU3UlVGRE9VUXNVMEZCVXl4RlFVRkZNVUlzUTBGQlF5eERRVUZETWtJc1IwRkJSeXhEUVVGRExGRkJRVkVzUTBGQlF6dEZRVU14UWl4bFFVRmxMRVZCUVVVelFpeERRVUZETEVOQlFVTXlRaXhIUVVGSExFTkJRVU16UWl4RFFVRkRMRU5CUVVNMFFpeExRVUZMTEVOQlFVTXNVVUZCVVN4RFFVRkRMRU5CUVVNN1JVRkRla01zWlVGQlpTeEZRVUZGTlVJc1EwRkJReXhEUVVGRE1rSXNSMEZCUnl4RFFVRkRNMElzUTBGQlF5eERRVUZETkVJc1MwRkJTeXhEUVVGRExGRkJRVkVzUTBGQlF6dERRVU42UXl4RFFVRkRPMEZCUlVzc1RVRkJUVU1zYVVKQlFXbENMRWRCUVVGUUxFOUJRVUVzUTBGQlFVOHNhVUpCUVVFc1IwRkJSemRDTEVOQlFVTXNRMEZCUXpCQ0xFdEJRVXNzUTBGQlF5eERRVUZETEcxQ1FVRnRRaXhEUVVGRExFVkJRVVU3UlVGRE9VUXNVMEZCVXl4RlFVRkZNVUlzUTBGQlF5eERRVUZETWtJc1IwRkJSeXhEUVVGRExGRkJRVkVzUTBGQlF6dEZRVU14UWl4TFFVRkxMRVZCUVVVelFpeERRVUZETEVOQlFVTXlRaXhIUVVGSExFTkJRVU1zVVVGQlVTeERRVUZETzBWQlEzUkNMRXRCUVVzc1JVRkJSVE5DTEVOQlFVTXNRMEZCUXpKQ0xFZEJRVWNzUTBGQlF5eFJRVUZSTEVOQlFVTTdSVUZEZEVJc1ZVRkJWU3hGUVVGRk0wSXNRMEZCUXl4RFFVRkRNa0lzUjBGQlJ5eERRVUZETEZGQlFWRTdRMEZETTBJc1EwRkJRenRCUVVWTExFMUJRVTFITEd0Q1FVRnJRaXhIUVVGQlVpeFBRVUZCTEVOQlFVRlJMR3RDUVVGQkxFZEJRVWM1UWl4RFFVRkRMRU5CUVVNd1FpeExRVUZMTEVOQlFVTXNRMEZCUXl4dFFrRkJiVUlzUTBGQlF5eEZRVUZGTzBWQlF5OUVMRk5CUVZNc1JVRkJSVEZDTEVOQlFVTXNRMEZCUXpKQ0xFZEJRVWNzUTBGQlF5eFRRVUZUTzBOQlF6TkNMRU5CUVVNN1FVRkZTeXhOUVVGTlNTeHBRa0ZCYVVJc1IwRkJRVlFzVDBGQlFTeERRVUZCVXl4cFFrRkJRU3hIUVVGSEwwSXNRMEZCUXl4RFFVRkRNRUlzUzBGQlN5eERRVUZETEVWQlFVVXNSVUZCUlR0RlFVTXpReXhSUVVGUkxFVkJRVVV4UWl4RFFVRkRMRU5CUVVNeVFpeEhRVUZITEVOQlFVTXNVVUZCVVR0RFFVTjZRaXhEUVVGRE8wRkJSVXNzVFVGQlRVc3NUVUZCVFN4SFFVRkJWaXhQUVVGQkxFTkJRVUZWTEUxQlFVRXNSMEZCUjJoRExFTkJRVU1zUTBGQlEzVkNMRXRCUVVzc1EwRkJRM1pDTEVOQlFVTXNRMEZCUTJsRExFZEJRVWNzUTBGQlF5eE5RVUZOTEVOQlFVTXNSVUZCUldwRExFTkJRVU1zUTBGQlEybERMRWRCUVVjc1EwRkJReXhYUVVGWExFTkJRVU1zUTBGQlF6dEJRVVY2UkN4TlFVRk5ReXh4UWtGQmNVSXNSMEZCUVZvc1QwRkJRU3hEUVVGQldTeHhRa0ZCUVN4SFFVRkhiRU1zUTBGQlF5eERRVUZETUVJc1MwRkJTeXhEUVVGRExFVkJRVVVzUlVGQlJUdEZRVU12UXl4TlFVRk5MRVZCUVVVN1EwRkRWQ3hEUVVGRE8wRkJSVXNzVFVGQlRWTXNZMEZCWXl4SFFVRkJZaXhQUVVGQkxFTkJRVUZoTEdOQlFVRXNSMEZCUjI1RExFTkJRVU1zUTBGQlF6QkNMRXRCUVVzc1EwRkJReXhGUVVGRkxFVkJRVVU3UlVGRGVFTXNTMEZCU3l4RlFVRkZMRkZCUVZFN1JVRkRaaXhQUVVGUExFVkJRVVV4UWl4RFFVRkRMRU5CUVVOcFF5eEhRVUZITEVOQlFVTXNTVUZCU1R0RFFVTndRaXhEUVVGRE8wRkJSVXNzVFVGQlRVY3NaVUZCWlN4SFFVRkJaQ3hQUVVGQkxFTkJRVUZqTEdWQlFVRXNSMEZCUjNCRExFTkJRVU1zUTBGQlF6QkNMRXRCUVVzc1EwRkJReXhGUVVGRkxFVkJRVVU3UlVGRGVrTXNUVUZCVFN4RlFVRkZNVUlzUTBGQlF5eERRVUZETUVJc1MwRkJTeXhEUVVGRExFVkJRVVVzUlVGQlJUdEpRVU5zUWl4VlFVRlZMRVZCUVVVeFFpeERRVUZETEVOQlFVTTBRaXhMUVVGTExFTkJRVU1zVTBGQlV6dEhRVU01UWp0RFFVTkdMRU5CUVVNN1FVRkZTeXhOUVVGTlV5eFBRVUZQTEVkQlFVRm1MRTlCUVVFc1EwRkJRV1VzVDBGQlFTeEhRVUZIY2tNc1EwRkJReXhEUVVGRE1FSXNTMEZCU3l4RFFVRkRMRVZCUVVVc1JVRkJSVHRGUVVOcVF5eExRVUZMTEVWQlFVVXNVVUZCVVR0RlFVTm1MRTFCUVUwc1JVRkJSVEZDTEVOQlFVTXNRMEZCUXpKQ0xFZEJRVWNzUTBGQlF5eFJRVUZSTEVOQlFVTTdSVUZEZGtJc1lVRkJZU3hGUVVGRk0wSXNRMEZCUXl4RFFVRkRNa0lzUjBGQlJ5eERRVUZETEZGQlFWRTdRMEZET1VJc1EwRkJRenRCUVVWTExFMUJRVTFYTEV0QlFVc3NSMEZCUVdoQ0xFOUJRVUVzUTBGQlFXZENMRXRCUVVFc1IwRkJSM1JETEVOQlFVTXNRMEZCUTNWQ0xFdEJRVXNzUTBGQlF5eG5Ra0ZCWjBJc1JVRkJSU3d3UWtGQk1FSXNSVUZCUlN4dlFrRkJiMElzUTBGQlF6dEJRVVY2Uml4TlFVRk5aMElzWTBGQll5eEhRVUZCYWtJc1QwRkJRU3hEUVVGQmFVSXNZMEZCUVN4SFFVRkhka01zUTBGQlF5eERRVUZETUVJc1MwRkJTeXhEUVVGRExFVkJRVVVzUlVGQlJUdEZRVU40UXl4UFFVRlBMRVZCUVVVeFFpeERRVUZETEVOQlFVTnBReXhIUVVGSExFTkJRVU1zV1VGQldTeERRVUZETzBWQlF6VkNMRTFCUVUwc1JVRkJSV3BETEVOQlFVTXNRMEZCUXpKQ0xFZEJRVWNzUTBGQlF6TkNMRU5CUVVNc1EwRkJRMmxETEVkQlFVY3NRMEZCUXl4RlFVRkZMRU5CUVVNN1EwRkRlRUlzUTBGQlF6dEJRVVZMTEUxQlFVMVBMSGRDUVVGM1FpeEhRVUZCYkVJc1QwRkJRU3hEUVVGQmEwSXNkMEpCUVVFc1IwRkJSM2hETEVOQlFVTXNRMEZCUXpCQ0xFdEJRVXNzUTBGQlF5eEZRVUZGTEVWQlFVVTdSVUZEYkVRc1QwRkJUeXhGUVVGRk1VSXNRMEZCUXl4RFFVRkRkVUlzUzBGQlN5eERRVUZEZGtJc1EwRkJReXhEUVVGRGFVTXNSMEZCUnl4RFFVRkRMRmRCUVZjc1EwRkJReXhGUVVGRmFrTXNRMEZCUXl4RFFVRkRhVU1zUjBGQlJ5eERRVUZETEdOQlFXTXNRMEZCUXl4RlFVRkZha01zUTBGQlF5eERRVUZEYVVNc1IwRkJSeXhEUVVGRExGRkJRVkVzUTBGQlF5eEZRVUZGYWtNc1EwRkJReXhEUVVGRGFVTXNSMEZCUnl4RFFVRkRMRlZCUVZVc1EwRkJReXhEUVVGRE8wVkJReTlHTEVsQlFVa3NSVUZCUlN4UlFVRlJPMFZCUTJRc1RVRkJUU3hGUVVGRmFrTXNRMEZCUXl4RFFVRkRNa0lzUjBGQlJ5eERRVUZETTBJc1EwRkJReXhEUVVGRGRVSXNTMEZCU3l4RFFVRkRka0lzUTBGQlF5eERRVUZEYVVNc1IwRkJSeXhEUVVGRExFVkJRVVVzUTBGQlF5eEZRVUZGTEZkQlFWY3NRMEZCUXp0RFFVTTVReXhEUVVGRE8wRkJSVXNzVFVGQlRWRXNhMEpCUVd0Q0xFZEJRVUZ1UWl4UFFVRkJMRU5CUVVGdFFpeHJRa0ZCUVN4SFFVRkhla01zUTBGQlF5eERRVUZETUVJc1MwRkJTeXhEUVVGRExFVkJRVVVzUlVGQlJUdEZRVU0xUXl4UFFVRlBMRVZCUVVVeFFpeERRVUZETEVOQlFVTjFRaXhMUVVGTExFTkJRVU4yUWl4RFFVRkRMRU5CUVVOcFF5eEhRVUZITEVOQlFVTXNVVUZCVVN4RFFVRkRMRVZCUVVWcVF5eERRVUZETEVOQlFVTnBReXhIUVVGSExFTkJRVU1zVDBGQlR5eERRVUZETEVWQlFVVnFReXhEUVVGRExFTkJRVU5wUXl4SFFVRkhMRU5CUVVNc1VVRkJVU3hEUVVGRExFTkJRVU03UlVGRGJFVXNTVUZCU1N4RlFVRkZMRkZCUVZFN1JVRkRaQ3hOUVVGTkxFVkJRVVZxUXl4RFFVRkRMRU5CUVVNd1FpeExRVUZMTEVOQlFVTXNSVUZCUlN4RlFVRkZPMGxCUTJ4Q0xFOUJRVThzUlVGQlJURkNMRU5CUVVNc1EwRkJRelJDTEV0QlFVc3NRMEZCUXl4WFFVRlhMRU5CUVVNN1NVRkROMElzVFVGQlRTeEZRVUZGTlVJc1EwRkJReXhEUVVGRE1rSXNSMEZCUnl4RFFVRkRMRkZCUVZFN1IwRkRka0k3UTBGRFJpeERRVUZETzBGQlJVc3NUVUZCVFdVc1UwRkJVeXhIUVVGQmNFSXNUMEZCUVN4RFFVRkJiMElzVTBGQlFTeEhRVUZITVVNc1EwRkJReXhEUVVGRE1FSXNTMEZCU3l4RFFVRkRMRVZCUVVVc1JVRkJSVHRGUVVOdVF5eExRVUZMTEVWQlFVVXNVVUZCVVR0RlFVTm1MRTFCUVUwc1JVRkJSVEZDTEVOQlFVTXNRMEZCUXpKQ0xFZEJRVWNzUTBGQlF5eFJRVUZSTEVOQlFVTTdSVUZEZGtJc1MwRkJTeXhGUVVGRk0wSXNRMEZCUXl4RFFVRkRNa0lzUjBGQlJ5eERRVUZETEZGQlFWRXNRMEZCUXp0RlFVTjBRaXhYUVVGWExFVkJRVVV6UWl4RFFVRkRMRU5CUVVOMVFpeExRVUZMTEVOQlFVTXNVVUZCVVN4RlFVRkZMRTFCUVUwc1EwRkJRenRGUVVOMFF5eFBRVUZQTEVWQlFVVXNXVUZCV1R0RlFVTnlRaXhWUVVGVkxFVkJRVVVzWlVGQlpUdEZRVU16UWl4UFFVRlBMRVZCUVVWMlFpeERRVUZETEVOQlFVTjFRaXhMUVVGTExFTkJRVU1zVDBGQlR5eEZRVUZGTEUxQlFVMHNRMEZCUXp0RlFVTnFReXhqUVVGakxFVkJRVVYyUWl4RFFVRkRMRU5CUVVNeVFpeEhRVUZITEVOQlFVTXNVVUZCVVN4RFFVRkRPMFZCUXk5Q0xFMUJRVTBzUlVGQlJUTkNMRU5CUVVNc1EwRkJRekpDTEVkQlFVY3NRMEZCUXl4UlFVRlJMRU5CUVVNN1JVRkRka0lzVFVGQlRTeEZRVUZGTTBJc1EwRkJReXhEUVVGRE1rSXNSMEZCUnl4RFFVRkRMRkZCUVZFN1EwRkRka0lzUTBGQlF6dEJRVVZMTEUxQlFVMW5RaXhWUVVGVkxFZEJRVUZ5UWl4UFFVRkJMRU5CUVVGeFFpeFZRVUZCTEVkQlFVY3pReXhEUVVGRExFTkJRVU4xUWl4TFFVRkxMRU5CUVVOMlFpeERRVUZETEVOQlFVTnBReXhIUVVGSExFTkJRVU1zVlVGQlZTeERRVUZETEVWQlFVVnFReXhEUVVGRExFTkJRVU5wUXl4SFFVRkhMRU5CUVVNc1QwRkJUeXhEUVVGRExFVkJRVVZxUXl4RFFVRkRMRU5CUVVOcFF5eEhRVUZITEVOQlFVTXNVMEZCVXl4RFFVRkRMRVZCUVVWcVF5eERRVUZETEVOQlFVTnBReXhIUVVGSExFTkJRVU1zVFVGQlRTeERRVUZETEVWQlFVVnFReXhEUVVGRExFTkJRVU5wUXl4SFFVRkhMRU5CUVVNc1RVRkJUU3hEUVVGRExFTkJRVU03UVVGRk4wY3NUVUZCVFZjc1lVRkJZU3hIUVVGQmRFSXNUMEZCUVN4RFFVRkJjMElzWVVGQlFTeEhRVUZITlVNc1EwRkJReXhEUVVGRGRVSXNTMEZCU3l4RFFVRkRka0lzUTBGQlF5eERRVUZEYVVNc1IwRkJSeXhEUVVGRExFMUJRVTBzUTBGQlF5eEZRVUZGYWtNc1EwRkJReXhEUVVGRGFVTXNSMEZCUnl4RFFVRkRMR0ZCUVdFc1EwRkJReXhGUVVGRmFrTXNRMEZCUXl4RFFVRkRhVU1zUjBGQlJ5eERRVUZETEZWQlFWVXNRMEZCUXl4RFFVRkRPMEZCUlhKR0xFMUJRVTFaTEhGQ1FVRnhRaXhIUVVGQmRrSXNUMEZCUVN4RFFVRkJkVUlzY1VKQlFVRXNSMEZCUnpkRExFTkJRVU1zUTBGQlF6QkNMRXRCUVVzc1EwRkJReXhGUVVGRkxFVkJRVVU3UlVGREwwTXNUVUZCVFN4RlFVRkZNVUlzUTBGQlF5eERRVUZETUVJc1MwRkJTeXhEUVVGRExFVkJRVVVzUlVGQlJUdEpRVU5zUWl4blFrRkJaMElzUlVGQlJURkNMRU5CUVVNc1EwRkJRelJDTEV0QlFVc3NRMEZCUXl4bFFVRmxPMGRCUXpGRE8wTkJRMFlzUTBGQlF6dEJRVVZMTEUxQlFVMXJRaXh2UWtGQmIwSXNSMEZCUVhoQ0xFOUJRVUVzUTBGQlFYZENMRzlDUVVGQkxFZEJRVWM1UXl4RFFVRkRMRU5CUVVNd1FpeExRVUZMTEVOQlFVTXNSVUZCUlN4RlFVRkZPMFZCUXpsRExFMUJRVTBzUlVGQlJUdERRVU5VTEVOQlFVTTdRVUZGU3l4TlFVRk5jVUlzWVVGQllTeEhRVUZCZWtJc1QwRkJRU3hEUVVGQmVVSXNZVUZCUVN4SFFVRkhMME1zUTBGQlF5eERRVUZETUVJc1MwRkJTeXhEUVVGRExFVkJRVVVzUlVGQlJUdEZRVU4yUXl4TlFVRk5MRVZCUVVVc1VVRkJVVHRGUVVOb1FpeE5RVUZOTEVWQlFVVXNVVUZCVVR0RlFVTm9RaXhOUVVGTkxFVkJRVVVzVVVGQlVUdEZRVU5vUWl4UFFVRlBMRVZCUVVVc1VVRkJVVHRGUVVOcVFpeExRVUZMTEVWQlFVVXNVVUZCVVR0RlFVTm1MRk5CUVZNc1JVRkJSU3hSUVVGUk8wVkJRMjVDTEZkQlFWY3NSVUZCUlR0RFFVTmtMRU5CUVVNN1FVRkZTeXhOUVVGTmMwSXNZVUZCWVN4SFFVRkJNVUlzVDBGQlFTeERRVUZCTUVJc1lVRkJRU3hIUVVGSGFFUXNRMEZCUXl4RFFVRkRNRUlzUzBGQlN5eERRVUZETEVWQlFVVXNSVUZCUlR0RlFVTjJReXhOUVVGTkxFVkJRVVV4UWl4RFFVRkRMRU5CUVVNd1FpeExRVUZMTEVOQlFVTXNSVUZCUlN4RlFVRkZPMGxCUTJ4Q0xGRkJRVkVzUlVGQlJURkNMRU5CUVVNc1EwRkJRelJDTEV0QlFVc3NRMEZCUXl4UFFVRlBPMGRCUXpGQ08wTkJRMFlzUTBGQlF6dEJRVVZMTEUxQlFVMXhRaXhMUVVGTExFZEJRVUV6UWl4UFFVRkJMRU5CUVVFeVFpeExRVUZCTEVkQlFVZHFSQ3hEUVVGRExFTkJRVU13UWl4TFFVRkxMRU5CUVVNc1JVRkJSU3hGUVVGRk8wVkJReTlDTEV0QlFVc3NSVUZCUlN4UlFVRlJPMFZCUTJZc1RVRkJUU3hGUVVGRk1VSXNRMEZCUXl4RFFVRkRNa0lzUjBGQlJ5eERRVUZETEZGQlFWRXNRMEZCUXp0RlFVTjJRaXhWUVVGVkxFVkJRVVVzVVVGQlVUdEZRVU53UWl4cFFrRkJhVUlzUlVGQlJTeFJRVUZSTzBWQlF6TkNMRmRCUVZjc1JVRkJSU3hSUVVGUk8wVkJRM0pDTEZOQlFWTXNSVUZCUlR0RFFVTmFMRU5CUVVNN1FVRkZTeXhOUVVGTmRVSXNXVUZCV1N4SFFVRkJOVUlzVDBGQlFTeERRVUZCTkVJc1dVRkJRU3hIUVVGSGJFUXNRMEZCUXl4RFFVRkRkVUlzUzBGQlN5eERRVUZEZGtJc1EwRkJReXhEUVVGRGFVTXNSMEZCUnl4RFFVRkRMRTFCUVUwc1EwRkJReXhGUVVGRmFrTXNRMEZCUXl4RFFVRkRhVU1zUjBGQlJ5eERRVUZETEV0QlFVc3NRMEZCUXl4RFFVRkRPMEZCUlhwRUxFMUJRVTFyUWl4bFFVRmxMRWRCUVVFM1FpeFBRVUZCTEVOQlFVRTJRaXhsUVVGQkxFZEJRVWR1UkN4RFFVRkRMRU5CUVVNd1FpeExRVUZMTEVOQlFVTXNSVUZCUlN4RlFVRkZPMFZCUTNwRExFMUJRVTBzUlVGQlJUdERRVU5VTEVOQlFVTTdRVUZGU3l4TlFVRk5NRUlzVVVGQlVTeEhRVUZCT1VJc1QwRkJRU3hEUVVGQk9FSXNVVUZCUVN4SFFVRkhjRVFzUTBGQlF5eERRVUZETUVJc1MwRkJTeXhEUVVGRExFVkJRVVVzUlVGQlJUdEZRVU5zUXl4VlFVRlZMRVZCUVVVeFFpeERRVUZETEVOQlFVTTBRaXhMUVVGTExFTkJRVU1zWVVGQllTeERRVUZETzBWQlEyeERMRlZCUVZVc1JVRkJSVFZDTEVOQlFVTXNRMEZCUXpKQ0xFZEJRVWNzUTBGQlF5eG5Ra0ZCWjBJc1EwRkJRenRGUVVOdVF5eFJRVUZSTEVWQlFVVXpRaXhEUVVGRExFTkJRVU15UWl4SFFVRkhMRU5CUVVNc1owSkJRV2RDTzBOQlEycERMRU5CUVVNN1FVRkZTeXhOUVVGTk1FSXNWMEZCVnl4SFFVRkJMMElzVDBGQlFTeERRVUZCSzBJc1YwRkJRU3hIUVVGSGNrUXNRMEZCUXl4RFFVRkRNRUlzUzBGQlN5eERRVUZETEVWQlFVVXNSVUZCUlR0RlFVTnlReXhMUVVGTExFVkJRVVVzVVVGQlVUdEZRVU5tTEUxQlFVMHNSVUZCUlRGQ0xFTkJRVU1zUTBGQlF6SkNMRWRCUVVjc1EwRkJReXhSUVVGUkxFTkJRVU03UlVGRGRrSXNZVUZCWVN4RlFVRkZNMElzUTBGQlF5eERRVUZETWtJc1IwRkJSeXhEUVVGRExHOUNRVUZ2UWp0RFFVTXhReXhEUVVGRE8wRkJSVXNzVFVGQlRUSkNMR3RDUVVGclFpeEhRVUZCYUVNc1QwRkJRU3hEUVVGQlowTXNhMEpCUVVFc1IwRkJSM1JFTEVOQlFVTXNRMEZCUXpCQ0xFdEJRVXNzUTBGQlF5eEZRVUZGTEVWQlFVVTdSVUZETlVNc1YwRkJWeXhGUVVGRk1VSXNRMEZCUXl4RFFVRkRNa0lzUjBGQlJ5eERRVUZETEZOQlFWTXNRMEZCUXp0RlFVTTNRaXhYUVVGWExFVkJRVVV6UWl4RFFVRkRMRU5CUVVNeVFpeEhRVUZITEVOQlFVTXNhMEpCUVd0Q0xFTkJRVU03UlVGRGRFTXNVVUZCVVN4RlFVRkZNMElzUTBGQlF5eERRVUZETWtJc1IwRkJSeXhEUVVGRExGRkJRVkU3UTBGRGVrSXNRMEZCUXp0QlFVVkxMRTFCUVUwMFFpeG5Ra0ZCWjBJc1IwRkJRV3BETEU5QlFVRXNRMEZCUVdsRExHZENRVUZCTEVkQlFVZDJSQ3hEUVVGRExFTkJRVU4xUWl4TFFVRkxMRU5CUVVOMlFpeERRVUZETEVOQlFVTnBReXhIUVVGSExFTkJRVU1zVFVGQlRTeERRVUZETEVWQlFVVnFReXhEUVVGRExFTkJRVU5wUXl4SFFVRkhMRU5CUVVNc1dVRkJXU3hEUVVGRExFVkJRVVZxUXl4RFFVRkRMRU5CUVVOcFF5eEhRVUZITEVOQlFVTXNWMEZCVnl4RFFVRkRMRVZCUVVWcVF5eERRVUZETEVOQlFVTnBReXhIUVVGSExFTkJRVU1zWjBKQlFXZENMRU5CUVVNc1EwRkJRenRCUVVWcVNDeE5RVUZOZFVJc1kwRkJZeXhIUVVGQmJFTXNUMEZCUVN4RFFVRkJhME1zWTBGQlFTeEhRVUZIZUVRc1EwRkJReXhEUVVGRE1FSXNTMEZCU3l4RFFVRkRMRVZCUVVVc1JVRkJSVHRGUVVONFF5eE5RVUZOTEVWQlFVVTdRMEZEVkN4RFFVRkRPMEZCUlVzc1RVRkJUU3RDTEU5QlFVOHNSMEZCUVc1RExFOUJRVUVzUTBGQlFXMURMRTlCUVVFc1IwRkJSM3BFTEVOQlFVTXNRMEZCUXpCQ0xFdEJRVXNzUTBGQlF5eERRVUZETEdkQ1FVRm5RaXhEUVVGRExFVkJRVVU3UlVGRGFrUXNTMEZCU3l4RlFVRkZPME5CUTFJc1EwRkJRenRCUVVWTExFMUJRVTFuUXl4alFVRmpMRWRCUVVGd1F5eFBRVUZCTEVOQlFVRnZReXhqUVVGQkxFZEJRVWN4UkN4RFFVRkRMRU5CUVVNd1FpeExRVUZMTEVOQlFVTXNSVUZCUlN4RlFVRkZPMFZCUTNoRExFdEJRVXNzUlVGQlJURkNMRU5CUVVNc1EwRkJRekpDTEVkQlFVY3NRMEZCUXl4UlFVRlJMRU5CUVVNN1JVRkRkRUlzVFVGQlRTeEZRVUZGTTBJc1EwRkJReXhEUVVGRE1rSXNSMEZCUnl4RFFVRkRMRkZCUVZFc1EwRkJRenRGUVVOMlFpeFRRVUZUTEVWQlFVVXpRaXhEUVVGRExFTkJRVU15UWl4SFFVRkhMRU5CUVVNelFpeERRVUZETEVOQlFVTTBRaXhMUVVGTExFTkJRVU1zVVVGQlVTeERRVUZETEVOQlFVTTdSVUZEYmtNc1lVRkJZU3hGUVVGRk5VSXNRMEZCUXl4RFFVRkRNa0lzUjBGQlJ5eERRVUZETEc5Q1FVRnZRanREUVVNeFF5eERRVUZETzBGQlJVc3NUVUZCVFdkRExIZENRVUYzUWl4SFFVRkJja01zVDBGQlFTeERRVUZCY1VNc2QwSkJRVUVzUjBGQlJ6TkVMRU5CUVVNc1EwRkJRekJDTEV0QlFVc3NRMEZCUXl4RlFVRkZMRVZCUVVVN1JVRkRiRVFzVFVGQlRTeEZRVUZGTzBOQlExUXNRMEZCUXp0QlFVVkxMRTFCUVUxclF5eHBRa0ZCYVVJc1IwRkJRWFJETEU5QlFVRXNRMEZCUVhORExHbENRVUZCTEVkQlFVYzFSQ3hEUVVGRExFTkJRVU13UWl4TFFVRkxMRU5CUVVNc1JVRkJSU3hGUVVGRk8wVkJRek5ETEV0QlFVc3NSVUZCUlN4UlFVRlJPMFZCUTJZc1RVRkJUU3hGUVVGRk1VSXNRMEZCUXl4RFFVRkRNa0lzUjBGQlJ5eERRVUZETEZGQlFWRXNRMEZCUXp0RlFVTjJRaXhUUVVGVExFVkJRVVV6UWl4RFFVRkRMRU5CUVVNeVFpeEhRVUZITEVOQlFVTXpRaXhEUVVGRExFTkJRVU0wUWl4TFFVRkxMRU5CUVVNc2EwSkJRV3RDTEVOQlFVTTdRMEZETjBNc1EwRkJRenRCUVVWTExFMUJRVTFwUXl4blFrRkJaMElzUjBGQlFYWkRMRTlCUVVFc1EwRkJRWFZETEdkQ1FVRkJMRWRCUVVjM1JDeERRVUZETEVOQlFVTjFRaXhMUVVGTExFTkJRVU1zZDBKQlFYZENMRVZCUVVVc2QwSkJRWGRDTEVWQlFVVXNlVUpCUVhsQ0xFTkJRVU03UVVGRkwwY3NUVUZCVFhWRExITkNRVUZ6UWl4SFFVRkJlRU1zVDBGQlFTeERRVUZCZDBNc2MwSkJRVUVzUjBGQlJ6bEVMRU5CUVVNc1EwRkJRekJDTEV0QlFVc3NRMEZCUXl4RFFVRkRMSGRDUVVGM1FpeERRVUZETEVWQlFVVTdSVUZEZUVVc1RVRkJUU3hGUVVGRk1VSXNRMEZCUXl4RFFVRkRkVUlzUzBGQlN5eERRVUZEZGtJc1EwRkJReXhEUVVGRGFVTXNSMEZCUnl4RFFVRkRMRkZCUVZFc1EwRkJReXhGUVVGRkxGRkJRVkVzUTBGQlF6dEZRVU14UXl4aFFVRmhMRVZCUVVWcVF5eERRVUZETEVOQlFVTXlRaXhIUVVGSExFTkJRVU16UWl4RFFVRkRMRU5CUVVNclJDeFpRVUZaTEVOQlFVTXNlVUpCUVhsQ0xFVkJRVVVzYlVKQlFXMUNMRU5CUVVNN1EwRkRjRVlzUTBGQlF6dEJRVVZMTEUxQlFVMURMSE5DUVVGelFpeEhRVUZCTVVNc1QwRkJRU3hEUVVGQk1FTXNjMEpCUVVFc1IwRkJSMmhGTEVOQlFVTXNRMEZCUXpCQ0xFdEJRVXNzUTBGQlF5eERRVUZETEhkQ1FVRjNRaXhEUVVGRExFVkJRVVU3UlVGRGVFVXNUVUZCVFN4RlFVRkZNVUlzUTBGQlF5eERRVUZEZFVJc1MwRkJTeXhEUVVGRGRrSXNRMEZCUXl4RFFVRkRhVU1zUjBGQlJ5eERRVUZETEZGQlFWRXNRMEZCUXl4RlFVRkZha01zUTBGQlF5eERRVUZEYVVNc1IwRkJSeXhEUVVGRExFdEJRVXNzUTBGQlF5eERRVUZETzBWQlF6bERMR0ZCUVdFc1JVRkJSV3BETEVOQlFVTXNRMEZCUXpKQ0xFZEJRVWNzUTBGQlF6TkNMRU5CUVVNc1EwRkJReXRFTEZsQlFWa3NRMEZCUXl4NVFrRkJlVUlzUlVGQlJTeHRRa0ZCYlVJc1EwRkJRenREUVVOd1JpeERRVUZETzBGQlJVc3NUVUZCVFVVc2RVSkJRWFZDTEVkQlFVRXpReXhQUVVGQkxFTkJRVUV5UXl4MVFrRkJRU3hIUVVGSGFrVXNRMEZCUXl4RFFVRkRNRUlzUzBGQlN5eERRVUZETEVOQlFVTXNkMEpCUVhkQ0xFTkJRVU1zUlVGQlJUdEZRVU42UlN4TlFVRk5MRVZCUVVVeFFpeERRVUZETEVOQlFVTnBReXhIUVVGSExFTkJRVU1zVTBGQlV5eERRVUZETzBWQlEzaENMR0ZCUVdFc1JVRkJSV3BETEVOQlFVTXNRMEZCUXpKQ0xFZEJRVWNzUTBGQlF6TkNMRU5CUVVNc1EwRkJReXRFTEZsQlFWa3NRMEZCUXl4NVFrRkJlVUlzUlVGQlJTeHZRa0ZCYjBJc1EwRkJRenREUVVOeVJpeERRVUZETzBGQlJVc3NUVUZCVFVjc2MwSkJRWE5DTEVkQlFVRTFReXhQUVVGQkxFTkJRVUUwUXl4elFrRkJRU3hIUVVGSGJFVXNRMEZCUXl4RFFVRkRNRUlzUzBGQlN5eERRVUZETEVWQlFVVXNSVUZCUlR0RlFVTm9SQ3hMUVVGTExFVkJRVVVzVVVGQlVUdEZRVU5tTEUxQlFVMHNSVUZCUlRGQ0xFTkJRVU1zUTBGQlF6SkNMRWRCUVVjc1EwRkJReXhSUVVGUkxFTkJRVU03UlVGRGRrSXNUVUZCVFN4RlFVRkZNMElzUTBGQlF5eERRVUZETWtJc1IwRkJSeXhEUVVGRExGRkJRVkU3UTBGRGRrSXNRMEZCUXp0QlFVVkxMRTFCUVUxM1F5eDFRa0ZCZFVJc1IwRkJRVGRETEU5QlFVRXNRMEZCUVRaRExIVkNRVUZCTEVkQlFVZHVSU3hEUVVGRExFTkJRVU13UWl4TFFVRkxMRU5CUVVNc1JVRkJSU3hGUVVGRk8wVkJRMnBFTEZsQlFWa3NSVUZCUlRGQ0xFTkJRVU1zUTBGQlF6SkNMRWRCUVVjc1EwRkJReXhUUVVGVE8wTkJRemxDTEVOQlFVTTdRVUZGU3l4TlFVRk5lVU1zWTBGQll5eEhRVUZCT1VNc1QwRkJRU3hEUVVGQk9FTXNZMEZCUVN4SFFVRkhjRVVzUTBGQlF5eERRVUZETUVJc1MwRkJTeXhEUVVGRExFVkJRVVVzUlVGQlJUdEZRVU40UXl4TlFVRk5MRVZCUVVVeFFpeERRVUZETEVOQlFVTXdRaXhMUVVGTExFTkJRVU1zUlVGQlJTeEZRVUZGTzBsQlEyeENMRk5CUVZNc1JVRkJSVEZDTEVOQlFVTXNRMEZCUXpSQ0xFdEJRVXNzUTBGQlF5eFJRVUZSTzBkQlF6VkNPME5CUTBZc1EwRkJRenRCUVVWTExFMUJRVTE1UXl4aFFVRmhMRWRCUVVFdlF5eFBRVUZCTEVOQlFVRXJReXhoUVVGQkxFZEJRVWR5UlN4RFFVRkRMRU5CUVVNd1FpeExRVUZMTEVOQlFVTXNSVUZCUlN4RlFVRkZPMFZCUTNaRExFMUJRVTBzUlVGQlJUdERRVU5VTEVOQlFVTTdRVUZGU3l4TlFVRk5ORU1zVFVGQlRTeEhRVUZCYUVRc1QwRkJRU3hEUVVGQlowUXNUVUZCUVN4SFFVRkhkRVVzUTBGQlF5eERRVUZETUVJc1MwRkJTeXhEUVVGRExFVkJRVVVzUlVGQlJUdEZRVU5vUXl4TFFVRkxMRVZCUVVVc1VVRkJVVHRGUVVObUxFMUJRVTBzUlVGQlJURkNMRU5CUVVNc1EwRkJRekpDTEVkQlFVY3NRMEZCUXl4UlFVRlJMRU5CUVVNN1JVRkRka0lzVDBGQlR5eEZRVUZGTEU5QlFVODdSVUZEYUVJc1kwRkJZeXhGUVVGRk0wSXNRMEZCUXl4RFFVRkRNa0lzUjBGQlJ5eERRVUZETEZGQlFWRXNRMEZCUXp0RlFVTXZRaXhOUVVGTkxFVkJRVVV6UWl4RFFVRkRMRU5CUVVNeVFpeEhRVUZITEVOQlFVTXNVVUZCVVR0RFFVTjJRaXhEUVVGRE8wRkJSVXNzVFVGQlRUUkRMR1ZCUVdVc1IwRkJRV3BFTEU5QlFVRXNRMEZCUVdsRUxHVkJRVUVzUjBGQlIzWkZMRU5CUVVNc1EwRkJRekJDTEV0QlFVc3NRMEZCUXl4RlFVRkZMRVZCUVVVN1JVRkRla01zVFVGQlRTeEZRVUZGTVVJc1EwRkJReXhEUVVGRE1FSXNTMEZCU3l4RFFVRkRMRVZCUVVVc1JVRkJSVHRKUVVOc1FpeFZRVUZWTEVWQlFVVXhRaXhEUVVGRExFTkJRVU0wUWl4TFFVRkxMRU5CUVVNc1UwRkJVenRIUVVNNVFqdERRVU5HTEVOQlFVTTdRVUZGU3l4TlFVRk5ORU1zWTBGQll5eEhRVUZCYkVRc1QwRkJRU3hEUVVGQmEwUXNZMEZCUVN4SFFVRkhlRVVzUTBGQlF5eERRVUZETUVJc1MwRkJTeXhEUVVGRExFVkJRVVVzUlVGQlJUdEZRVU40UXl4TlFVRk5MRVZCUVVVN1EwRkRWQ3hEUVVGRE8wRkJSVXNzVFVGQlRTdERMRTlCUVU4c1IwRkJRVzVFTEU5QlFVRXNRMEZCUVcxRUxFOUJRVUVzUjBGQlIzcEZMRU5CUVVNc1EwRkJRM1ZDTEV0QlFVc3NRMEZCUXl4bFFVRmxMRVZCUVVVc1pVRkJaU3hGUVVGRkxHZENRVUZuUWl4RFFVRkRPMEZCUlRORkxFMUJRVTF0UkN4aFFVRmhMRWRCUVVGd1JDeFBRVUZCTEVOQlFVRnZSQ3hoUVVGQkxFZEJRVWN4UlN4RFFVRkRMRU5CUVVNd1FpeExRVUZMTEVOQlFVTXNRMEZCUXl4bFFVRmxMRU5CUVVNc1JVRkJSVHRGUVVOMFJDeFBRVUZQTEVWQlFVVXNVVUZCVVR0RlFVTnFRaXhoUVVGaExFVkJRVVV4UWl4RFFVRkRMRU5CUVVNeVFpeEhRVUZITEVOQlFVTXNiVUpCUVcxQ08wTkJRM3BETEVOQlFVTTdRVUZGU3l4TlFVRk5aMFFzWVVGQllTeEhRVUZCY2tRc1QwRkJRU3hEUVVGQmNVUXNZVUZCUVN4SFFVRkhNMFVzUTBGQlF5eERRVUZETUVJc1MwRkJTeXhEUVVGRExFTkJRVU1zWlVGQlpTeERRVUZETEVWQlFVVTdSVUZEZEVRc1QwRkJUeXhGUVVGRkxGRkJRVkU3UlVGRGFrSXNZVUZCWVN4RlFVRkZNVUlzUTBGQlF5eERRVUZETWtJc1IwRkJSeXhEUVVGRExHMUNRVUZ0UWp0RFFVTjZReXhEUVVGRE8wRkJSVXNzVFVGQlRXbEVMR05CUVdNc1IwRkJRWFJFTEU5QlFVRXNRMEZCUVhORUxHTkJRVUVzUjBGQlJ6VkZMRU5CUVVNc1EwRkJRekJDTEV0QlFVc3NRMEZCUXl4RFFVRkRMR1ZCUVdVc1EwRkJReXhGUVVGRk8wVkJRM1pFTEU5QlFVOHNSVUZCUlN4VFFVRlRPMFZCUTJ4Q0xHRkJRV0VzUlVGQlJURkNMRU5CUVVNc1EwRkJRekpDTEVkQlFVY3NRMEZCUXl4dlFrRkJiMEk3UTBGRE1VTXNRMEZCUXp0QlFVVkxMRTFCUVUxclJDeGhRVUZoTEVkQlFVRjJSQ3hQUVVGQkxFTkJRVUYxUkN4aFFVRkJMRWRCUVVjM1JTeERRVUZETEVOQlFVTXdRaXhMUVVGTExFTkJRVU1zUlVGQlJTeEZRVUZGTzBWQlEzWkRMRXRCUVVzc1JVRkJSU3hSUVVGUk8wVkJRMllzVFVGQlRTeEZRVUZGTVVJc1EwRkJReXhEUVVGRE1rSXNSMEZCUnl4RFFVRkRMRkZCUVZFc1EwRkJRenRGUVVOMlFpeE5RVUZOTEVWQlFVVXpRaXhEUVVGRExFTkJRVU15UWl4SFFVRkhMRU5CUVVNc1VVRkJVU3hEUVVGRE8wVkJRM1pDTEdOQlFXTXNSVUZCUlROQ0xFTkJRVU1zUTBGQlF6SkNMRWRCUVVjc1EwRkJReXhSUVVGUkxFTkJRVU03UlVGREwwSXNUVUZCVFN4RlFVRkZNMElzUTBGQlF5eERRVUZETWtJc1IwRkJSeXhEUVVGRExGRkJRVkU3UTBGRGRrSXNRMEZCUXp0QlFVVkxMRTFCUVUxdFJDeGxRVUZsTEVkQlFVRjRSQ3hQUVVGQkxFTkJRVUYzUkN4bFFVRkJMRWRCUVVjNVJTeERRVUZETEVOQlFVTXdRaXhMUVVGTExFTkJRVU1zUlVGQlJTeEZRVUZGTzBWQlEzcERMRTFCUVUwc1JVRkJSVEZDTEVOQlFVTXNRMEZCUXpCQ0xFdEJRVXNzUTBGQlF5eEZRVUZGTEVWQlFVVTdTVUZEYkVJc1VVRkJVU3hGUVVGRk1VSXNRMEZCUXl4RFFVRkRORUlzUzBGQlN5eERRVUZETEZGQlFWRTdSMEZETTBJN1EwRkRSaXhEUVVGRE8wRkJSVXNzVFVGQlRXMUVMR0ZCUVdFc1IwRkJRWHBFTEU5QlFVRXNRMEZCUVhsRUxHRkJRVUVzUjBGQlJ5OUZMRU5CUVVNc1EwRkJRekJDTEV0QlFVc3NRMEZCUXl4RlFVRkZMRVZCUVVVN1JVRkRka01zVFVGQlRTeEZRVUZGTzBOQlExUXNRMEZCUXp0QlFVVkxMRTFCUVUxelJDeE5RVUZOTEVkQlFVRXhSQ3hQUVVGQkxFTkJRVUV3UkN4TlFVRkJMRWRCUVVkb1JpeERRVUZETEVOQlFVTjFRaXhMUVVGTExFTkJRVU1zWTBGQll5eEZRVUZGTEdOQlFXTXNSVUZCUlN4bFFVRmxMRU5CUVVNN1FVRkZka1VzVFVGQlRUQkVMRmxCUVZrc1IwRkJRVE5FTEU5QlFVRXNRMEZCUVRKRUxGbEJRVUVzUjBGQlIycEdMRU5CUVVNc1EwRkJRekJDTEV0QlFVc3NRMEZCUXl4RFFVRkRMR05CUVdNc1EwRkJReXhGUVVGRk8wVkJRM0JFTEU5QlFVOHNSVUZCUlN4UlFVRlJPMFZCUTJwQ0xHRkJRV0VzUlVGQlJURkNMRU5CUVVNc1EwRkJRekpDTEVkQlFVY3NRMEZCUXl4dFFrRkJiVUk3UTBGRGVrTXNRMEZCUXp0QlFVVkxMRTFCUVUxMVJDeFpRVUZaTEVkQlFVRTFSQ3hQUVVGQkxFTkJRVUUwUkN4WlFVRkJMRWRCUVVkc1JpeERRVUZETEVOQlFVTXdRaXhMUVVGTExFTkJRVU1zUTBGQlF5eGpRVUZqTEVOQlFVTXNSVUZCUlR0RlFVTndSQ3hQUVVGUExFVkJRVVVzVVVGQlVUdEZRVU5xUWl4aFFVRmhMRVZCUVVVeFFpeERRVUZETEVOQlFVTXlRaXhIUVVGSExFTkJRVU1zYlVKQlFXMUNPME5CUTNwRExFTkJRVU03UVVGRlN5eE5RVUZOZDBRc1lVRkJZU3hIUVVGQk4wUXNUMEZCUVN4RFFVRkJOa1FzWVVGQlFTeEhRVUZIYmtZc1EwRkJReXhEUVVGRE1FSXNTMEZCU3l4RFFVRkRMRU5CUVVNc1kwRkJZeXhEUVVGRExFVkJRVVU3UlVGRGNrUXNUMEZCVHl4RlFVRkZMRk5CUVZNN1JVRkRiRUlzWVVGQllTeEZRVUZGTVVJc1EwRkJReXhEUVVGRE1rSXNSMEZCUnl4RFFVRkRMRzlDUVVGdlFqdERRVU14UXl4RFFVRkRPMEZCUlVzc1RVRkJUWGxFTEZsQlFWa3NSMEZCUVRsRUxFOUJRVUVzUTBGQlFUaEVMRmxCUVVFc1IwRkJSM0JHTEVOQlFVTXNRMEZCUXpCQ0xFdEJRVXNzUTBGQlF5eEZRVUZGTEVWQlFVVTdSVUZEZEVNc1MwRkJTeXhGUVVGRkxGRkJRVkU3UlVGRFppeE5RVUZOTEVWQlFVVXhRaXhEUVVGRExFTkJRVU15UWl4SFFVRkhMRU5CUVVNc1VVRkJVU3hEUVVGRE8wVkJRM1pDTEdOQlFXTXNSVUZCUlROQ0xFTkJRVU1zUTBGQlF6SkNMRWRCUVVjc1EwRkJReXhSUVVGUkxFTkJRVU03UlVGREwwSXNUVUZCVFN4RlFVRkZNMElzUTBGQlF5eERRVUZETWtJc1IwRkJSeXhEUVVGRExGRkJRVkU3UTBGRGRrSXNRMEZCUXp0QlFVVkxMRTFCUVUwd1JDeGhRVUZoTEVkQlFVRXZSQ3hQUVVGQkxFTkJRVUVyUkN4aFFVRkJMRWRCUVVkeVJpeERRVUZETEVOQlFVTXdRaXhMUVVGTExFTkJRVU1zUlVGQlJTeEZRVUZGTzBWQlEzWkRMRTlCUVU4c1JVRkJSVEZDTEVOQlFVTXNRMEZCUXpCQ0xFdEJRVXNzUTBGQlF5eEZRVUZGTEVWQlFVVTdTVUZEYmtJc1MwRkJTeXhGUVVGRkxGRkJRVkU3U1VGRFppeGhRVUZoTEVWQlFVVXhRaXhEUVVGRExFTkJRVU15UWl4SFFVRkhMRU5CUVVNc1VVRkJVU3hEUVVGRE8wbEJRemxDTEd0Q1FVRnJRaXhGUVVGRk0wSXNRMEZCUXl4RFFVRkRNa0lzUjBGQlJ5eERRVUZETEZGQlFWRXNRMEZCUXp0SlFVTnVReXhQUVVGUExFVkJRVVV6UWl4RFFVRkRMRU5CUVVNeVFpeEhRVUZITEVOQlFVTXNVVUZCVVR0SFFVTjRRanREUVVOR0xFTkJRVU03UVVGRlJpeE5RVUZOTWtRc2FVSkJRV2xDTEVkQlFXbENPMFZCUTNSRGFrVXNTMEZCU3p0RlFVTk1SeXhYUVVGWE8wVkJRMWhETEdsQ1FVRnBRanRGUVVOcVFra3NhVUpCUVdsQ08wVkJRMnBDUXl4clFrRkJhMEk3UlVGRGJFSkRMR2xDUVVGcFFqdEZRVU5xUWtNc1RVRkJUVHRGUVVOT1JTeHhRa0ZCY1VJN1JVRkRja0pETEdOQlFXTTdSVUZEWkVNc1pVRkJaVHRGUVVObVF5eFBRVUZQTzBWQlExQkRMRXRCUVVzN1JVRkRURU1zWTBGQll6dEZRVU5rUXl4M1FrRkJkMEk3UlVGRGVFSkRMR3RDUVVGclFqdEZRVU5zUWtNc1UwRkJVenRGUVVOVVF5eFZRVUZWTzBWQlExWkRMR0ZCUVdFN1JVRkRZa01zY1VKQlFYRkNPMFZCUTNKQ1F5eHZRa0ZCYjBJN1JVRkRjRUpETEdGQlFXRTdSVUZEWWtNc1lVRkJZVHRGUVVOaVF5eExRVUZMTzBWQlEweERMRmxCUVZrN1JVRkRXa01zWlVGQlpUdEZRVU5tUXl4UlFVRlJPMFZCUTFKRExGZEJRVmM3UlVGRFdFTXNhMEpCUVd0Q08wVkJRMnhDUXl4blFrRkJaMEk3UlVGRGFFSkRMR05CUVdNN1JVRkRaRU1zVDBGQlR6dEZRVU5RUXl4alFVRmpPMFZCUTJSRExIZENRVUYzUWp0RlFVTjRRa01zYVVKQlFXbENPMFZCUTJwQ1F5eG5Ra0ZCWjBJN1JVRkRhRUpETEhOQ1FVRnpRanRGUVVOMFFrVXNjMEpCUVhOQ08wVkJRM1JDUXl4MVFrRkJkVUk3UlVGRGRrSkRMSE5DUVVGelFqdEZRVU4wUWtNc2RVSkJRWFZDTzBWQlEzWkNReXhqUVVGak8wVkJRMlJETEdGQlFXRTdSVUZEWWtNc1RVRkJUVHRGUVVOT1F5eGxRVUZsTzBWQlEyWkRMR05CUVdNN1JVRkRaRU1zVDBGQlR6dEZRVU5RUXl4aFFVRmhPMFZCUTJKRExHRkJRV0U3UlVGRFlrTXNZMEZCWXp0RlFVTmtReXhoUVVGaE8wVkJRMkpETEdWQlFXVTdSVUZEWmtNc1lVRkJZVHRGUVVOaVF5eE5RVUZOTzBWQlEwNURMRmxCUVZrN1JVRkRXa01zV1VGQldUdEZRVU5hUXl4aFFVRmhPMFZCUTJKRExGbEJRVms3UlVGRFdrTTdRMEZEUkR0QlFVRkRMRWxCUVVGRkxGRkJRVUVzUjBGQlFXcEZMRTlCUVVFc1EwRkJRVllzVDBGQlFTeEhRVU5oTUVVc2FVSkJRV2xDSWl3aWFXZHViM0psVEdsemRDSTZXMTE5IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLnR5cGVTdWl0ZSA9IGV4cG9ydHMuZGVmYXVsdCA9IGV4cG9ydHMuY2hlY2tlcnMgPSB2b2lkIDA7XG52YXIgX3RzSW50ZXJmYWNlQ2hlY2tlciA9IHJlcXVpcmUoXCJ0cy1pbnRlcmZhY2UtY2hlY2tlclwiKTtcbnZhciBfYXBpVHlwZXNUaSA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIi4vYXBpLXR5cGVzLXRpLmpzXCIpKTtcbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoZSkgeyByZXR1cm4gZSAmJiBlLl9fZXNNb2R1bGUgPyBlIDogeyBkZWZhdWx0OiBlIH07IH1cbi8vIFRoaXMgbW9kdWxlIHdhcyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBieSBub2RlIHRzLWludGVyZmFjZS1wb3N0LnRzXG4vLyAyMDI2LTA4LTIxVDA2OjIwOjU0LjYyN1pcblxuLy8gVHlwZSBkZWZpbml0aW9uc1xuY29uc3QgdHlwZVN1aXRlID0gZXhwb3J0cy50eXBlU3VpdGUgPSBfYXBpVHlwZXNUaS5kZWZhdWx0O1xuLy8gQ2hlY2tlcnNcbmNvbnN0IGNoZWNrZXJzID0gZXhwb3J0cy5jaGVja2VycyA9ICgwLCBfdHNJbnRlcmZhY2VDaGVja2VyLmNyZWF0ZUNoZWNrZXJzKShfYXBpVHlwZXNUaS5kZWZhdWx0KTtcbi8vIEV4cG9ydCB0aGUgY2hlY2tlcnMgYnkgZGVmYXVsdFxudmFyIF9kZWZhdWx0ID0gZXhwb3J0cy5kZWZhdWx0ID0gY2hlY2tlcnM7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldD11dGYtODtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnVZVzFsY3lJNld5SmZkSE5KYm5SbGNtWmhZMlZEYUdWamEyVnlJaXdpY21WeGRXbHlaU0lzSWw5aGNHbFVlWEJsYzFScElpd2lYMmx1ZEdWeWIzQlNaWEYxYVhKbFJHVm1ZWFZzZENJc0ltVWlMQ0pmWDJWelRXOWtkV3hsSWl3aVpHVm1ZWFZzZENJc0luUjVjR1ZUZFdsMFpTSXNJbVY0Y0c5eWRITWlMQ0psZUhCdmNuUmxaRlI1Y0dWVGRXbDBaU0lzSW1Ob1pXTnJaWEp6SWl3aVkzSmxZWFJsUTJobFkydGxjbk1pTENKZlpHVm1ZWFZzZENKZExDSnpiM1Z5WTJWeklqcGJJaTR1THk0dUwzTnlZeTkwYVM5aGNHa3RkSGx3WlhNdWRITWlYU3dpYzI5MWNtTmxjME52Ym5SbGJuUWlPbHR1ZFd4c1hTd2liV0Z3Y0dsdVozTWlPaUk3T3pzN096dEJRVWRCTEVsQlFVRkJMRzFDUVVGQkxFZEJRVUZETEU5QlFVRTdRVUZGUVN4SlFVRkJReXhYUVVGQkxFZEJRVUZETEhOQ1FVRkJMRU5CUVVGR0xFOUJRVUU3UVVGQmEwUXNVMEZCUVVVc2RVSkJRVUZETEVOQlFVRXNWMEZCUVVFc1EwRkJRU3hKUVVGQlFTeERRVUZCTEVOQlFVRkRMRlZCUVVFc1IwRkJRVVFzUTBGQlFTeExRVUZCUlN4UFFVRkJMRVZCUVVGR0xFTkJRVUU3UVVGTWJFUTdRVUZEUVRzN1FVRnZSVUU3UVVGRFR5eE5RVUZOUnl4VFFVRlRMRWRCUVVGRExFOUJRVUVzUTBGQlFVUXNVMEZCUVN4SFFVRkhSU3h0UWtFeVJIaENPMEZCUlVRN1FVRkRUeXhOUVVGTlF5eFJRVUZSTEVkQlFVRkdMRTlCUVVFc1EwRkJRVVVzVVVGQlFTeEhRVUZITEVsQlFVRkRMR3REUVVGakxFVkJRVU5HTEcxQ1FVRnBRaXhEUVRKRWRrUTdRVUZGUkR0QlFVRkJMRWxCUVVGSExGRkJRVUVzUjBGQlFVb3NUMEZCUVN4RFFVRkJSaXhQUVVGQkxFZEJRMlZKTEZGQlFWRWlMQ0pwWjI1dmNtVk1hWE4wSWpwYlhYMD0iLCJcInVzZSBzdHJpY3RcIjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IGV4cG9ydHMuRXhwZXJpbWVudGFsRmVhdHVyZXMgPSBleHBvcnRzLkRlYnVnRmVhdHVyZXMgPSBleHBvcnRzLkNvbmZpZ1BsdWdpbiA9IGV4cG9ydHMuQ29uZmlnQXBwbGlhbmNlcyA9IGV4cG9ydHMuQXBwbGlhbmNlUHJvZ3JhbU9wdGlvbnMgPSBleHBvcnRzLkFwcGxpYW5jZVByb2dyYW1Db25maWcgPSBleHBvcnRzLkFwcGxpYW5jZU5hbWVzUHJlZml4ID0gZXhwb3J0cy5BcHBsaWFuY2VGZWF0dXJlcyA9IGV4cG9ydHMuQXBwbGlhbmNlQ29uZmlnID0gZXhwb3J0cy5BZGRQcm9ncmFtc0NvbmZpZyA9IHZvaWQgMDtcbnZhciB0ID0gX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQocmVxdWlyZShcInRzLWludGVyZmFjZS1jaGVja2VyXCIpKTtcbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkKGUsIHQpIHsgaWYgKFwiZnVuY3Rpb25cIiA9PSB0eXBlb2YgV2Vha01hcCkgdmFyIHIgPSBuZXcgV2Vha01hcCgpLCBuID0gbmV3IFdlYWtNYXAoKTsgcmV0dXJuIChfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCA9IGZ1bmN0aW9uIChlLCB0KSB7IGlmICghdCAmJiBlICYmIGUuX19lc01vZHVsZSkgcmV0dXJuIGU7IHZhciBvLCBpLCBmID0geyBfX3Byb3RvX186IG51bGwsIGRlZmF1bHQ6IGUgfTsgaWYgKG51bGwgPT09IGUgfHwgXCJvYmplY3RcIiAhPSB0eXBlb2YgZSAmJiBcImZ1bmN0aW9uXCIgIT0gdHlwZW9mIGUpIHJldHVybiBmOyBpZiAobyA9IHQgPyBuIDogcikgeyBpZiAoby5oYXMoZSkpIHJldHVybiBvLmdldChlKTsgby5zZXQoZSwgZik7IH0gZm9yIChjb25zdCB0IGluIGUpIFwiZGVmYXVsdFwiICE9PSB0ICYmIHt9Lmhhc093blByb3BlcnR5LmNhbGwoZSwgdCkgJiYgKChpID0gKG8gPSBPYmplY3QuZGVmaW5lUHJvcGVydHkpICYmIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoZSwgdCkpICYmIChpLmdldCB8fCBpLnNldCkgPyBvKGYsIHQsIGkpIDogZlt0XSA9IGVbdF0pOyByZXR1cm4gZjsgfSkoZSwgdCk7IH1cbi8qKlxuICogVGhpcyBtb2R1bGUgd2FzIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IGB0cy1pbnRlcmZhY2UtYnVpbGRlcmBcbiAqL1xuXG4vLyB0c2xpbnQ6ZGlzYWJsZTpvYmplY3QtbGl0ZXJhbC1rZXktcXVvdGVzXG5jb25zdCBDb25maWdQbHVnaW4gPSBleHBvcnRzLkNvbmZpZ1BsdWdpbiA9IHQuaWZhY2UoW10sIHtcbiAgXCJwbGF0Zm9ybVwiOiBcInN0cmluZ1wiLFxuICBcIm5hbWVcIjogdC5vcHQoXCJzdHJpbmdcIiksXG4gIFwiY2xpZW50aWRcIjogXCJzdHJpbmdcIixcbiAgXCJjbGllbnRzZWNyZXRcIjogdC5vcHQoXCJzdHJpbmdcIiksXG4gIFwic2ltdWxhdG9yXCI6IHQub3B0KFwiYm9vbGVhblwiKSxcbiAgXCJjaGluYVwiOiB0Lm9wdChcImJvb2xlYW5cIiksXG4gIFwibGFuZ3VhZ2VcIjogdC5pZmFjZShbXSwge1xuICAgIFwiYXBpXCI6IFwic3RyaW5nXCJcbiAgfSksXG4gIFwiZXhwZXJpbWVudGFsXCI6IHQub3B0KHQuYXJyYXkoXCJFeHBlcmltZW50YWxGZWF0dXJlc1wiKSksXG4gIFwiZGVidWdcIjogdC5vcHQodC5hcnJheShcIkRlYnVnRmVhdHVyZXNcIikpXG59KTtcbmNvbnN0IEV4cGVyaW1lbnRhbEZlYXR1cmVzID0gZXhwb3J0cy5FeHBlcmltZW50YWxGZWF0dXJlcyA9IHQubGl0KCdEaXNjb25uZWN0ZWQgYXMgT2ZmJyk7XG5jb25zdCBEZWJ1Z0ZlYXR1cmVzID0gZXhwb3J0cy5EZWJ1Z0ZlYXR1cmVzID0gdC51bmlvbih0LmxpdCgnTG9nIEFQSSBIZWFkZXJzJyksIHQubGl0KCdMb2cgQVBJIEJvZGllcycpLCB0LmxpdCgnTG9nIEFwcGxpYW5jZSBJRHMnKSwgdC5saXQoJ0xvZyBEZWJ1ZyBhcyBJbmZvJyksIHQubGl0KCdNb2NrIEFwcGxpYW5jZXMnKSk7XG5jb25zdCBDb25maWdBcHBsaWFuY2VzID0gZXhwb3J0cy5Db25maWdBcHBsaWFuY2VzID0gdC5pZmFjZShbXSwge1xuICBbdC5pbmRleEtleV06IFwiQXBwbGlhbmNlQ29uZmlnXCJcbn0pO1xuY29uc3QgQWRkUHJvZ3JhbXNDb25maWcgPSBleHBvcnRzLkFkZFByb2dyYW1zQ29uZmlnID0gdC51bmlvbih0LmxpdCgnbm9uZScpLCB0LmxpdCgnYXV0bycpLCB0LmxpdCgnY3VzdG9tJykpO1xuY29uc3QgQXBwbGlhbmNlQ29uZmlnID0gZXhwb3J0cy5BcHBsaWFuY2VDb25maWcgPSB0LmlmYWNlKFtdLCB7XG4gIFwiZW5hYmxlZFwiOiB0Lm9wdChcImJvb2xlYW5cIiksXG4gIFwibmFtZXNcIjogdC5vcHQodC5pZmFjZShbXSwge1xuICAgIFwicHJlZml4XCI6IFwiQXBwbGlhbmNlTmFtZXNQcmVmaXhcIlxuICB9KSksXG4gIFwiZmVhdHVyZXNcIjogdC5vcHQoXCJBcHBsaWFuY2VGZWF0dXJlc1wiKSxcbiAgXCJhZGRwcm9ncmFtc1wiOiB0Lm9wdChcIkFkZFByb2dyYW1zQ29uZmlnXCIpLFxuICBcInByb2dyYW1zXCI6IHQub3B0KHQuYXJyYXkoXCJBcHBsaWFuY2VQcm9ncmFtQ29uZmlnXCIpKVxufSk7XG5jb25zdCBBcHBsaWFuY2VOYW1lc1ByZWZpeCA9IGV4cG9ydHMuQXBwbGlhbmNlTmFtZXNQcmVmaXggPSB0LmlmYWNlKFtdLCB7XG4gIFwicHJvZ3JhbXNcIjogdC5vcHQoXCJib29sZWFuXCIpLFxuICBcIm90aGVyXCI6IHQub3B0KFwiYm9vbGVhblwiKVxufSk7XG5jb25zdCBBcHBsaWFuY2VGZWF0dXJlcyA9IGV4cG9ydHMuQXBwbGlhbmNlRmVhdHVyZXMgPSB0LmlmYWNlKFtdLCB7XG4gIFt0LmluZGV4S2V5XTogXCJib29sZWFuXCJcbn0pO1xuY29uc3QgQXBwbGlhbmNlUHJvZ3JhbUNvbmZpZyA9IGV4cG9ydHMuQXBwbGlhbmNlUHJvZ3JhbUNvbmZpZyA9IHQuaWZhY2UoW10sIHtcbiAgXCJuYW1lXCI6IFwic3RyaW5nXCIsXG4gIFwia2V5XCI6IFwic3RyaW5nXCIsXG4gIFwic2VsZWN0b25seVwiOiB0Lm9wdChcImJvb2xlYW5cIiksXG4gIFwib3B0aW9uc1wiOiB0Lm9wdChcIkFwcGxpYW5jZVByb2dyYW1PcHRpb25zXCIpXG59KTtcbmNvbnN0IEFwcGxpYW5jZVByb2dyYW1PcHRpb25zID0gZXhwb3J0cy5BcHBsaWFuY2VQcm9ncmFtT3B0aW9ucyA9IHQuaWZhY2UoW10sIHtcbiAgW3QuaW5kZXhLZXldOiB0LnVuaW9uKFwic3RyaW5nXCIsIFwibnVtYmVyXCIsIFwiYm9vbGVhblwiKVxufSk7XG5jb25zdCBleHBvcnRlZFR5cGVTdWl0ZSA9IHtcbiAgQ29uZmlnUGx1Z2luLFxuICBFeHBlcmltZW50YWxGZWF0dXJlcyxcbiAgRGVidWdGZWF0dXJlcyxcbiAgQ29uZmlnQXBwbGlhbmNlcyxcbiAgQWRkUHJvZ3JhbXNDb25maWcsXG4gIEFwcGxpYW5jZUNvbmZpZyxcbiAgQXBwbGlhbmNlTmFtZXNQcmVmaXgsXG4gIEFwcGxpYW5jZUZlYXR1cmVzLFxuICBBcHBsaWFuY2VQcm9ncmFtQ29uZmlnLFxuICBBcHBsaWFuY2VQcm9ncmFtT3B0aW9uc1xufTtcbnZhciBfZGVmYXVsdCA9IGV4cG9ydHMuZGVmYXVsdCA9IGV4cG9ydGVkVHlwZVN1aXRlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ9dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p1WVcxbGN5STZXeUowSWl3aVgybHVkR1Z5YjNCU1pYRjFhWEpsVjJsc1pHTmhjbVFpTENKeVpYRjFhWEpsSWl3aVpTSXNJbGRsWVd0TllYQWlMQ0p5SWl3aWJpSXNJbDlmWlhOTmIyUjFiR1VpTENKdklpd2lhU0lzSW1ZaUxDSmZYM0J5YjNSdlgxOGlMQ0prWldaaGRXeDBJaXdpYUdGeklpd2laMlYwSWl3aWMyVjBJaXdpYUdGelQzZHVVSEp2Y0dWeWRIa2lMQ0pqWVd4c0lpd2lUMkpxWldOMElpd2laR1ZtYVc1bFVISnZjR1Z5ZEhraUxDSm5aWFJQZDI1UWNtOXdaWEowZVVSbGMyTnlhWEIwYjNJaUxDSkRiMjVtYVdkUWJIVm5hVzRpTENKbGVIQnZjblJ6SWl3aWFXWmhZMlVpTENKdmNIUWlMQ0poY25KaGVTSXNJa1Y0Y0dWeWFXMWxiblJoYkVabFlYUjFjbVZ6SWl3aWJHbDBJaXdpUkdWaWRXZEdaV0YwZFhKbGN5SXNJblZ1YVc5dUlpd2lRMjl1Wm1sblFYQndiR2xoYm1ObGN5SXNJbWx1WkdWNFMyVjVJaXdpUVdSa1VISnZaM0poYlhORGIyNW1hV2NpTENKQmNIQnNhV0Z1WTJWRGIyNW1hV2NpTENKQmNIQnNhV0Z1WTJWT1lXMWxjMUJ5WldacGVDSXNJa0Z3Y0d4cFlXNWpaVVpsWVhSMWNtVnpJaXdpUVhCd2JHbGhibU5sVUhKdlozSmhiVU52Ym1acFp5SXNJa0Z3Y0d4cFlXNWpaVkJ5YjJkeVlXMVBjSFJwYjI1eklpd2laWGh3YjNKMFpXUlVlWEJsVTNWcGRHVWlMQ0pmWkdWbVlYVnNkQ0pkTENKemIzVnlZMlZ6SWpwYklpNHVMeTR1TDNOeVl5OTBhUzlqYjI1bWFXY3RkSGx3WlhNdGRHa3VkSE1pWFN3aWMyOTFjbU5sYzBOdmJuUmxiblFpT2x0dWRXeHNYU3dpYldGd2NHbHVaM01pT2lJN096czdPenRCUVVkQkxFbEJRVUZCTEVOQlFVRXNSMEZCUVVNc2RVSkJRVUVzUTBGQlFVTXNUMEZCUVR0QlFVRXdReXhUUVVGQlJDeDNRa0ZCUVVVc1EwRkJRU3hGUVVGQlNDeERRVUZCTERaQ1FVRkJTU3hQUVVGQkxFMUJRVUZETEVOQlFVRXNUMEZCUVVRc1QwRkJRU3hKUVVGQlJTeERRVUZCTEU5QlFVRkdMRTlCUVVFc1dVRkJRVWdzZFVKQlFVRXNXVUZCUVVFc1EwRkJRVVVzUTBGQlFTeEZRVUZCU0N4RFFVRkJMRk5CUVVGQkxFTkJRVUVzU1VGQlFVY3NRMEZCUVN4SlFVRkJRU3hEUVVGQkxFTkJRVUZKTEZWQlFVRXNVMEZCUVVvc1EwRkJRU3hOUVVGQlN5eERRVUZCTEVWQlFVRkRMRU5CUVVFc1JVRkJRVU1zUTBGQlFTeExRVUZCUXl4VFFVRkJMRkZCUVVGRExFOUJRVUVzUlVGQlFWUXNRMEZCUVN4cFFrRkJRVUVzUTBGQlFTeDFRa0ZCUVVFc1EwRkJRU3g1UWtGQlFVRXNRMEZCUVN4VFFVRkJUeXhEUVVGQkxFMUJRVUZHTEVOQlFVRXNSMEZCUVZJc1EwRkJRU3hIUVVGQlRTeERRVUZCTEVkQlFVRkVMRU5CUVVFc1VVRkJRVWNzUTBGQlFTeERRVUZCU3l4SFFVRkJMRU5CUVVGV0xFTkJRVUVzVlVGQlFVc3NRMEZCUVN4RFFVRkJUU3hIUVVGQkxFTkJRVUZZTEVOQlFVRXNSMEZCUVVzc1EwRkJRU3hEUVVGQlR5eEhRVUZCTEVOQlFVRmFMRU5CUVVFc1JVRkJRVThzUTBGQlFTeG5Ra0ZCUVZZc1EwRkJRU3hKUVVGQlJ5eERRVUZCTEdkQ1FVRkJTQ3hEUVVGQkxFOUJRVUZuUWl4alFVRkJMRU5CUVVGRExFbEJRVUVzUTBGQlFXUXNRMEZCUVN4RlFVRkJTQ3hEUVVGQkxFOUJRVUZUTEVOQlFVRXNTVUZCUVVRc1EwRkJRU3hIUVVGQlZTeE5RVUZCTEVOQlFVRkRMR05CUVVFc1MwRkJRVVFzVFVGQlFTeERRVUZCUlN4M1FrRkJRU3hEUVVGQmFrSXNRMEZCUVN4RlFVRkJTQ3hEUVVGQkxFOUJRVUZUTEVOQlFVRXNRMEZCUVVzc1IwRkJRU3hKUVVGQlRDeERRVUZCTEVOQlFVRk5MRWRCUVVFc1NVRkJRVkFzUTBGQlFTeERRVUZCUlN4RFFVRkJMRVZCUVVGV0xFTkJRVUVzUlVGQlFWTXNRMEZCUVN4SlFVRkJReXhEUVVGQkxFTkJRVUZXTEVOQlFVRXNTVUZCUVVjc1EwRkJRU3hEUVVGQlNDeERRVUZCTEZkQlFVRlZMRU5CUVVFc1MwRkJRVkFzUTBGQlFTeEZRVUZCU0N4RFFVRkJPMEZCU0RGRE96czdPMEZCU1VFN1FVRkZUeXhOUVVGTmNVSXNXVUZCV1N4SFFVRkJReXhQUVVGQkxFTkJRVUZFTEZsQlFVRXNSMEZCUjNKQ0xFTkJRVU1zUTBGQlEzVkNMRXRCUVVzc1EwRkJReXhGUVVGRkxFVkJRVVU3UlVGRGRFTXNWVUZCVlN4RlFVRkZMRkZCUVZFN1JVRkRjRUlzVFVGQlRTeEZRVUZGZGtJc1EwRkJReXhEUVVGRGQwSXNSMEZCUnl4RFFVRkRMRkZCUVZFc1EwRkJRenRGUVVOMlFpeFZRVUZWTEVWQlFVVXNVVUZCVVR0RlFVTndRaXhqUVVGakxFVkJRVVY0UWl4RFFVRkRMRU5CUVVOM1FpeEhRVUZITEVOQlFVTXNVVUZCVVN4RFFVRkRPMFZCUXk5Q0xGZEJRVmNzUlVGQlJYaENMRU5CUVVNc1EwRkJRM2RDTEVkQlFVY3NRMEZCUXl4VFFVRlRMRU5CUVVNN1JVRkROMElzVDBGQlR5eEZRVUZGZUVJc1EwRkJReXhEUVVGRGQwSXNSMEZCUnl4RFFVRkRMRk5CUVZNc1EwRkJRenRGUVVONlFpeFZRVUZWTEVWQlFVVjRRaXhEUVVGRExFTkJRVU4xUWl4TFFVRkxMRU5CUVVNc1JVRkJSU3hGUVVGRk8wbEJRM1JDTEV0QlFVc3NSVUZCUlR0SFFVTlNMRU5CUVVNN1JVRkRSaXhqUVVGakxFVkJRVVYyUWl4RFFVRkRMRU5CUVVOM1FpeEhRVUZITEVOQlFVTjRRaXhEUVVGRExFTkJRVU41UWl4TFFVRkxMRU5CUVVNc2MwSkJRWE5DTEVOQlFVTXNRMEZCUXp0RlFVTjBSQ3hQUVVGUExFVkJRVVY2UWl4RFFVRkRMRU5CUVVOM1FpeEhRVUZITEVOQlFVTjRRaXhEUVVGRExFTkJRVU41UWl4TFFVRkxMRU5CUVVNc1pVRkJaU3hEUVVGRE8wTkJRM2hETEVOQlFVTTdRVUZGU3l4TlFVRk5ReXh2UWtGQmIwSXNSMEZCUVVvc1QwRkJRU3hEUVVGQlNTeHZRa0ZCUVN4SFFVRkhNVUlzUTBGQlF5eERRVUZETWtJc1IwRkJSeXhEUVVGRExIRkNRVUZ4UWl4RFFVRkRPMEZCUlhwRUxFMUJRVTFETEdGQlFXRXNSMEZCUVU0c1QwRkJRU3hEUVVGQlRTeGhRVUZCTEVkQlFVYzFRaXhEUVVGRExFTkJRVU0yUWl4TFFVRkxMRU5CUVVNM1FpeERRVUZETEVOQlFVTXlRaXhIUVVGSExFTkJRVU1zYVVKQlFXbENMRU5CUVVNc1JVRkJSVE5DTEVOQlFVTXNRMEZCUXpKQ0xFZEJRVWNzUTBGQlF5eG5Ra0ZCWjBJc1EwRkJReXhGUVVGRk0wSXNRMEZCUXl4RFFVRkRNa0lzUjBGQlJ5eERRVUZETEcxQ1FVRnRRaXhEUVVGRExFVkJRVVV6UWl4RFFVRkRMRU5CUVVNeVFpeEhRVUZITEVOQlFVTXNiVUpCUVcxQ0xFTkJRVU1zUlVGQlJUTkNMRU5CUVVNc1EwRkJRekpDTEVkQlFVY3NRMEZCUXl4cFFrRkJhVUlzUTBGQlF5eERRVUZETzBGQlJXeExMRTFCUVUxSExHZENRVUZuUWl4SFFVRkJVaXhQUVVGQkxFTkJRVUZSTEdkQ1FVRkJMRWRCUVVjNVFpeERRVUZETEVOQlFVTjFRaXhMUVVGTExFTkJRVU1zUlVGQlJTeEZRVUZGTzBWQlF6RkRMRU5CUVVOMlFpeERRVUZETEVOQlFVTXJRaXhSUVVGUkxFZEJRVWM3UTBGRFppeERRVUZETzBGQlJVc3NUVUZCVFVNc2FVSkJRV2xDTEVkQlFVRldMRTlCUVVFc1EwRkJRVlVzYVVKQlFVRXNSMEZCUjJoRExFTkJRVU1zUTBGQlF6WkNMRXRCUVVzc1EwRkJRemRDTEVOQlFVTXNRMEZCUXpKQ0xFZEJRVWNzUTBGQlF5eE5RVUZOTEVOQlFVTXNSVUZCUlROQ0xFTkJRVU1zUTBGQlF6SkNMRWRCUVVjc1EwRkJReXhOUVVGTkxFTkJRVU1zUlVGQlJUTkNMRU5CUVVNc1EwRkJRekpDTEVkQlFVY3NRMEZCUXl4UlFVRlJMRU5CUVVNc1EwRkJRenRCUVVWb1JpeE5RVUZOVFN4bFFVRmxMRWRCUVVGWUxFOUJRVUVzUTBGQlFWY3NaVUZCUVN4SFFVRkhha01zUTBGQlF5eERRVUZEZFVJc1MwRkJTeXhEUVVGRExFVkJRVVVzUlVGQlJUdEZRVU42UXl4VFFVRlRMRVZCUVVWMlFpeERRVUZETEVOQlFVTjNRaXhIUVVGSExFTkJRVU1zVTBGQlV5eERRVUZETzBWQlF6TkNMRTlCUVU4c1JVRkJSWGhDTEVOQlFVTXNRMEZCUTNkQ0xFZEJRVWNzUTBGQlEzaENMRU5CUVVNc1EwRkJRM1ZDTEV0QlFVc3NRMEZCUXl4RlFVRkZMRVZCUVVVN1NVRkRla0lzVVVGQlVTeEZRVUZGTzBkQlExZ3NRMEZCUXl4RFFVRkRPMFZCUTBnc1ZVRkJWU3hGUVVGRmRrSXNRMEZCUXl4RFFVRkRkMElzUjBGQlJ5eERRVUZETEcxQ1FVRnRRaXhEUVVGRE8wVkJRM1JETEdGQlFXRXNSVUZCUlhoQ0xFTkJRVU1zUTBGQlEzZENMRWRCUVVjc1EwRkJReXh0UWtGQmJVSXNRMEZCUXp0RlFVTjZReXhWUVVGVkxFVkJRVVY0UWl4RFFVRkRMRU5CUVVOM1FpeEhRVUZITEVOQlFVTjRRaXhEUVVGRExFTkJRVU41UWl4TFFVRkxMRU5CUVVNc2QwSkJRWGRDTEVOQlFVTTdRMEZEY0VRc1EwRkJRenRCUVVWTExFMUJRVTFUTEc5Q1FVRnZRaXhIUVVGQldpeFBRVUZCTEVOQlFVRlpMRzlDUVVGQkxFZEJRVWRzUXl4RFFVRkRMRU5CUVVOMVFpeExRVUZMTEVOQlFVTXNSVUZCUlN4RlFVRkZPMFZCUXpsRExGVkJRVlVzUlVGQlJYWkNMRU5CUVVNc1EwRkJRM2RDTEVkQlFVY3NRMEZCUXl4VFFVRlRMRU5CUVVNN1JVRkROVUlzVDBGQlR5eEZRVUZGZUVJc1EwRkJReXhEUVVGRGQwSXNSMEZCUnl4RFFVRkRMRk5CUVZNN1EwRkRla0lzUTBGQlF6dEJRVVZMTEUxQlFVMVhMR2xDUVVGcFFpeEhRVUZCWWl4UFFVRkJMRU5CUVVGaExHbENRVUZCTEVkQlFVZHVReXhEUVVGRExFTkJRVU4xUWl4TFFVRkxMRU5CUVVNc1JVRkJSU3hGUVVGRk8wVkJRek5ETEVOQlFVTjJRaXhEUVVGRExFTkJRVU1yUWl4UlFVRlJMRWRCUVVjN1EwRkRaaXhEUVVGRE8wRkJSVXNzVFVGQlRVc3NjMEpCUVhOQ0xFZEJRVUZrTEU5QlFVRXNRMEZCUVdNc2MwSkJRVUVzUjBGQlIzQkRMRU5CUVVNc1EwRkJRM1ZDTEV0QlFVc3NRMEZCUXl4RlFVRkZMRVZCUVVVN1JVRkRhRVFzVFVGQlRTeEZRVUZGTEZGQlFWRTdSVUZEYUVJc1MwRkJTeXhGUVVGRkxGRkJRVkU3UlVGRFppeFpRVUZaTEVWQlFVVjJRaXhEUVVGRExFTkJRVU4zUWl4SFFVRkhMRU5CUVVNc1UwRkJVeXhEUVVGRE8wVkJRemxDTEZOQlFWTXNSVUZCUlhoQ0xFTkJRVU1zUTBGQlEzZENMRWRCUVVjc1EwRkJReXg1UWtGQmVVSTdRMEZETTBNc1EwRkJRenRCUVVWTExFMUJRVTFoTEhWQ1FVRjFRaXhIUVVGQlppeFBRVUZCTEVOQlFVRmxMSFZDUVVGQkxFZEJRVWR5UXl4RFFVRkRMRU5CUVVOMVFpeExRVUZMTEVOQlFVTXNSVUZCUlN4RlFVRkZPMFZCUTJwRUxFTkJRVU4yUWl4RFFVRkRMRU5CUVVNclFpeFJRVUZSTEVkQlFVY3ZRaXhEUVVGRExFTkJRVU0yUWl4TFFVRkxMRU5CUVVNc1VVRkJVU3hGUVVGRkxGRkJRVkVzUlVGQlJTeFRRVUZUTzBOQlEzQkVMRU5CUVVNN1FVRkZSaXhOUVVGTlV5eHBRa0ZCYVVJc1IwRkJhVUk3UlVGRGRFTnFRaXhaUVVGWk8wVkJRMXBMTEc5Q1FVRnZRanRGUVVOd1FrVXNZVUZCWVR0RlFVTmlSU3huUWtGQlowSTdSVUZEYUVKRkxHbENRVUZwUWp0RlFVTnFRa01zWlVGQlpUdEZRVU5tUXl4dlFrRkJiMEk3UlVGRGNFSkRMR2xDUVVGcFFqdEZRVU5xUWtNc2MwSkJRWE5DTzBWQlEzUkNRenREUVVORU8wRkJRVU1zU1VGQlFVVXNVVUZCUVN4SFFVRkJha0lzVDBGQlFTeERRVUZCVml4UFFVRkJMRWRCUTJFd1FpeHBRa0ZCYVVJaUxDSnBaMjV2Y21WTWFYTjBJanBiWFgwPSIsIlwidXNlIHN0cmljdFwiO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy50eXBlU3VpdGUgPSBleHBvcnRzLmRlZmF1bHQgPSBleHBvcnRzLmNoZWNrZXJzID0gdm9pZCAwO1xudmFyIF90c0ludGVyZmFjZUNoZWNrZXIgPSByZXF1aXJlKFwidHMtaW50ZXJmYWNlLWNoZWNrZXJcIik7XG52YXIgX2NvbmZpZ1R5cGVzVGkgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL2NvbmZpZy10eXBlcy10aS5qc1wiKSk7XG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KGUpIHsgcmV0dXJuIGUgJiYgZS5fX2VzTW9kdWxlID8gZSA6IHsgZGVmYXVsdDogZSB9OyB9XG4vLyBUaGlzIG1vZHVsZSB3YXMgYXV0b21hdGljYWxseSBnZW5lcmF0ZWQgYnkgbm9kZSB0cy1pbnRlcmZhY2UtcG9zdC50c1xuLy8gMjAyNi0wOC0yMVQwNjoyMDo1NC42MjlaXG5cbi8vIFR5cGUgZGVmaW5pdGlvbnNcbmNvbnN0IHR5cGVTdWl0ZSA9IGV4cG9ydHMudHlwZVN1aXRlID0gX2NvbmZpZ1R5cGVzVGkuZGVmYXVsdDtcbi8vIENoZWNrZXJzXG5jb25zdCBjaGVja2VycyA9IGV4cG9ydHMuY2hlY2tlcnMgPSAoMCwgX3RzSW50ZXJmYWNlQ2hlY2tlci5jcmVhdGVDaGVja2VycykoX2NvbmZpZ1R5cGVzVGkuZGVmYXVsdCk7XG4vLyBFeHBvcnQgdGhlIGNoZWNrZXJzIGJ5IGRlZmF1bHRcbnZhciBfZGVmYXVsdCA9IGV4cG9ydHMuZGVmYXVsdCA9IGNoZWNrZXJzO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ9dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p1WVcxbGN5STZXeUpmZEhOSmJuUmxjbVpoWTJWRGFHVmphMlZ5SWl3aWNtVnhkV2x5WlNJc0lsOWpiMjVtYVdkVWVYQmxjMVJwSWl3aVgybHVkR1Z5YjNCU1pYRjFhWEpsUkdWbVlYVnNkQ0lzSW1VaUxDSmZYMlZ6VFc5a2RXeGxJaXdpWkdWbVlYVnNkQ0lzSW5SNWNHVlRkV2wwWlNJc0ltVjRjRzl5ZEhNaUxDSmxlSEJ2Y25SbFpGUjVjR1ZUZFdsMFpTSXNJbU5vWldOclpYSnpJaXdpWTNKbFlYUmxRMmhsWTJ0bGNuTWlMQ0pmWkdWbVlYVnNkQ0pkTENKemIzVnlZMlZ6SWpwYklpNHVMeTR1TDNOeVl5OTBhUzlqYjI1bWFXY3RkSGx3WlhNdWRITWlYU3dpYzI5MWNtTmxjME52Ym5SbGJuUWlPbHR1ZFd4c1hTd2liV0Z3Y0dsdVozTWlPaUk3T3pzN096dEJRVWRCTEVsQlFVRkJMRzFDUVVGQkxFZEJRVUZETEU5QlFVRTdRVUZGUVN4SlFVRkJReXhqUVVGQkxFZEJRVUZETEhOQ1FVRkJMRU5CUVVGR0xFOUJRVUU3UVVGQmNVUXNVMEZCUVVVc2RVSkJRVUZETEVOQlFVRXNWMEZCUVVFc1EwRkJRU3hKUVVGQlFTeERRVUZCTEVOQlFVRkRMRlZCUVVFc1IwRkJRVVFzUTBGQlFTeExRVUZCUlN4UFFVRkJMRVZCUVVGR0xFTkJRVUU3UVVGTWNrUTdRVUZEUVRzN1FVRnZRa0U3UVVGRFR5eE5RVUZOUnl4VFFVRlRMRWRCUVVGRExFOUJRVUVzUTBGQlFVUXNVMEZCUVN4SFFVRkhSU3h6UWtGWGVFSTdRVUZGUkR0QlFVTlBMRTFCUVUxRExGRkJRVkVzUjBGQlFVWXNUMEZCUVN4RFFVRkJSU3hSUVVGQkxFZEJRVWNzU1VGQlFVTXNhME5CUVdNc1JVRkJRMFlzYzBKQlFXbENMRU5CVjNaRU8wRkJSVVE3UVVGQlFTeEpRVUZCUnl4UlFVRkJMRWRCUVVGS0xFOUJRVUVzUTBGQlFVWXNUMEZCUVN4SFFVTmxTU3hSUVVGUklpd2lhV2R1YjNKbFRHbHpkQ0k2VzExOSIsIlwidXNlIHN0cmljdFwiO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5NUyA9IHZvaWQgMDtcbmV4cG9ydHMuYXNzZXJ0SXNCb29sZWFuID0gYXNzZXJ0SXNCb29sZWFuO1xuZXhwb3J0cy5hc3NlcnRJc0RlZmluZWQgPSBhc3NlcnRJc0RlZmluZWQ7XG5leHBvcnRzLmFzc2VydElzSW5zdGFuY2VPZiA9IGFzc2VydElzSW5zdGFuY2VPZjtcbmV4cG9ydHMuYXNzZXJ0SXNOdW1iZXIgPSBhc3NlcnRJc051bWJlcjtcbmV4cG9ydHMuYXNzZXJ0SXNTdHJpbmcgPSBhc3NlcnRJc1N0cmluZztcbmV4cG9ydHMuYXNzZXJ0SXNVbmRlZmluZWQgPSBhc3NlcnRJc1VuZGVmaW5lZDtcbmV4cG9ydHMuY29sdW1ucyA9IGNvbHVtbnM7XG5leHBvcnRzLmRlZXBNZXJnZSA9IGRlZXBNZXJnZTtcbmV4cG9ydHMuZm9ybWF0TGlzdCA9IGZvcm1hdExpc3Q7XG5leHBvcnRzLmZvcm1hdE1pbGxpc2Vjb25kcyA9IGZvcm1hdE1pbGxpc2Vjb25kcztcbmV4cG9ydHMuZm9ybWF0U2Vjb25kcyA9IGZvcm1hdFNlY29uZHM7XG5leHBvcnRzLmdldFZhbGlkYXRpb25UcmVlID0gZ2V0VmFsaWRhdGlvblRyZWU7XG5leHBvcnRzLmtleW9mQ2hlY2tlciA9IGtleW9mQ2hlY2tlcjtcbmV4cG9ydHMucGx1cmFsID0gcGx1cmFsO1xudmFyIF9hc3NlcnQgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCJhc3NlcnRcIikpO1xuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChlKSB7IHJldHVybiBlICYmIGUuX19lc01vZHVsZSA/IGUgOiB7IGRlZmF1bHQ6IGUgfTsgfVxuLy8gSG9tZWJyaWRnZSBwbHVnaW4gZm9yIEhvbWUgQ29ubmVjdCBob21lIGFwcGxpYW5jZXNcbi8vIENvcHlyaWdodCDCqSAyMDIzLTIwMjYgQWxleGFuZGVyIFRob3VreWRpZGVzXG5cbi8vIE1pbGxpc2Vjb25kcyBpbiBhIHNlY29uZFxuY29uc3QgTVMgPSBleHBvcnRzLk1TID0gMTAwMDtcbi8vIFR5cGUgYXNzZXJ0aW9uc1xuZnVuY3Rpb24gYXNzZXJ0SXNEZWZpbmVkKHZhbHVlKSB7XG4gIF9hc3NlcnQuZGVmYXVsdC5ub3RTdHJpY3RFcXVhbCh2YWx1ZSwgdW5kZWZpbmVkKTtcbiAgX2Fzc2VydC5kZWZhdWx0Lm5vdFN0cmljdEVxdWFsKHZhbHVlLCBudWxsKTtcbn1cbmZ1bmN0aW9uIGFzc2VydElzVW5kZWZpbmVkKHZhbHVlKSB7XG4gIF9hc3NlcnQuZGVmYXVsdC5zdHJpY3RFcXVhbCh2YWx1ZSwgdW5kZWZpbmVkKTtcbn1cbmZ1bmN0aW9uIGFzc2VydElzU3RyaW5nKHZhbHVlKSB7XG4gIF9hc3NlcnQuZGVmYXVsdC5zdHJpY3RFcXVhbCh0eXBlb2YgdmFsdWUsICdzdHJpbmcnKTtcbn1cbmZ1bmN0aW9uIGFzc2VydElzTnVtYmVyKHZhbHVlKSB7XG4gIF9hc3NlcnQuZGVmYXVsdC5zdHJpY3RFcXVhbCh0eXBlb2YgdmFsdWUsICdudW1iZXInKTtcbn1cbmZ1bmN0aW9uIGFzc2VydElzQm9vbGVhbih2YWx1ZSkge1xuICBfYXNzZXJ0LmRlZmF1bHQuc3RyaWN0RXF1YWwodHlwZW9mIHZhbHVlLCAnYm9vbGVhbicpO1xufVxuZnVuY3Rpb24gYXNzZXJ0SXNJbnN0YW5jZU9mKHZhbHVlLCB0eXBlKSB7XG4gICgwLCBfYXNzZXJ0LmRlZmF1bHQpKHZhbHVlIGluc3RhbmNlb2YgdHlwZSwgYE5vdCBhbiBpbnN0YW5jZSBvZiAke3R5cGUubmFtZX1gKTtcbn1cbi8vIEZvcm1hdCBhIG1pbGxpc2Vjb25kcyBkdXJhdGlvblxuZnVuY3Rpb24gZm9ybWF0TWlsbGlzZWNvbmRzKG1zLCBtYXhQYXJ0cyA9IDIpIHtcbiAgaWYgKG1zIDwgMSkgcmV0dXJuICduL2EnO1xuICAvLyBTcGxpdCB0aGUgZHVyYXRpb24gaW50byBjb21wb25lbnRzXG4gIGNvbnN0IGR1cmF0aW9uID0gW1snZGF5JywgTWF0aC5mbG9vcihtcyAvICgyNCAqIDYwICogNjAgKiBNUykpXSwgWydob3VyJywgTWF0aC5mbG9vcihtcyAvICg2MCAqIDYwICogTVMpKSAlIDI0XSwgWydtaW51dGUnLCBNYXRoLmZsb29yKG1zIC8gKDYwICogTVMpKSAlIDYwXSwgWydzZWNvbmQnLCBNYXRoLmZsb29yKG1zIC8gTVMpICUgNjBdLCBbJ21pbGxpc2Vjb25kJywgTWF0aC5mbG9vcihtcykgJSBNU11dO1xuICAvLyBSZW1vdmUgYW55IGxlYWRpbmcgemVybyBjb21wb25lbnRzXG4gIHdoaWxlIChkdXJhdGlvblswXT8uWzFdID09PSAwKSBkdXJhdGlvbi5zaGlmdCgpO1xuICAvLyBDb21iaW5lIHRoZSByZXF1aXJlZCBudW1iZXIgb2YgcmVtYWluaW5nIGNvbXBvbmVudHNcbiAgcmV0dXJuIGR1cmF0aW9uLnNsaWNlKDAsIG1heFBhcnRzKS5maWx0ZXIoKFtfa2V5LCB2YWx1ZV0pID0+IHZhbHVlICE9PSAwKS5tYXAoKFtrZXksIHZhbHVlXSkgPT4gcGx1cmFsKHZhbHVlLCBrZXkpKS5qb2luKCcgJyk7XG59XG4vLyBGb3JtYXQgYSBzZWNvbmRzIGR1cmF0aW9uXG5mdW5jdGlvbiBmb3JtYXRTZWNvbmRzKHNlY29uZHMsIG1heFBhcnRzID0gMikge1xuICByZXR1cm4gZm9ybWF0TWlsbGlzZWNvbmRzKHNlY29uZHMgKiAxMDAwLCBtYXhQYXJ0cyk7XG59XG4vLyBGb3JtYXQgYSBsaXN0ICh3aXRoIE94Zm9yZCBjb21tYSlcbmZ1bmN0aW9uIGZvcm1hdExpc3QoaXRlbXMpIHtcbiAgc3dpdGNoIChpdGVtcy5sZW5ndGgpIHtcbiAgICBjYXNlIDA6XG4gICAgICByZXR1cm4gJ24vYSc7XG4gICAgY2FzZSAxOlxuICAgICAgcmV0dXJuIGl0ZW1zWzBdID8/ICcnO1xuICAgIGNhc2UgMjpcbiAgICAgIHJldHVybiBgJHtpdGVtc1swXX0gYW5kICR7aXRlbXNbMV19YDtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIFsuLi5pdGVtcy5zbGljZSgwLCAtMSksIGBhbmQgJHtpdGVtc1tpdGVtcy5sZW5ndGggLSAxXX1gXS5qb2luKCcsICcpO1xuICB9XG59XG4vLyBGb3JtYXQgYSBjb3VudGVkIG5vdW4gKGhhbmRsaW5nIG1vc3QgcmVndWxhciBjYXNlcyBhdXRvbWF0aWNhbGx5KVxuZnVuY3Rpb24gcGx1cmFsKGNvdW50LCBub3VuLCBzaG93Q291bnQgPSB0cnVlKSB7XG4gIGNvbnN0IFtzaW5ndWxhciwgcGx1cmFsXSA9IEFycmF5LmlzQXJyYXkobm91bikgPyBub3VuIDogW25vdW4sICcnXTtcbiAgbm91biA9IGNvdW50ID09PSAxID8gc2luZ3VsYXIgOiBwbHVyYWw7XG4gIGlmICghbm91bikge1xuICAgIC8vIEFwcGx5IHJlZ3VsYXIgcnVsZXNcbiAgICBjb25zdCBydWxlcyA9IFtbJ29uJCcsICdhJywgMl0sXG4gICAgLy8gcGhlbm9tZW5vbi9waGVub21lbmEgY3JpdGVyaW9uL2NyaXRlcmlhXG4gICAgWyd1cyQnLCAnaScsIDFdLFxuICAgIC8vICAgICBjYWN0dXMvY2FjdGkgICAgICAgICBmb2N1cy9mb2NpXG4gICAgWydbXmFlaW91XXkkJywgJ2llcycsIDFdLFxuICAgIC8vICAgICAgICBjdHkvY2l0ZXMgICAgICAgICBwdXBweS9wdXBwaWVzXG4gICAgWycoY2h8aXN8b3xzfHNofHh8eikkJywgJ2VzJywgMF0sXG4gICAgLy8gICAgICAgaXJpcy9pcmlzZXMgICAgICAgIHRydXNzL3RydXNzZXNcbiAgICBbJycsICdzJywgMF0gLy8gICAgICAgIGNhdC9jYXRzICAgICAgICAgIGhvdXNlL2hvdXNlc1xuICAgIF07XG4gICAgY29uc3QgcnVsZSA9IHJ1bGVzLmZpbmQoKFtlbmRpbmddKSA9PiBuZXcgUmVnRXhwKGVuZGluZywgJ2knKS50ZXN0KHNpbmd1bGFyKSk7XG4gICAgYXNzZXJ0SXNEZWZpbmVkKHJ1bGUpO1xuICAgIGNvbnN0IG1hdGNoQ2FzZSA9IHMgPT4gc2luZ3VsYXIgPT09IHNpbmd1bGFyLnRvVXBwZXJDYXNlKCkgPyBzLnRvVXBwZXJDYXNlKCkgOiBzO1xuICAgIG5vdW4gPSBzaW5ndWxhci5zdWJzdHJpbmcoMCwgc2luZ3VsYXIubGVuZ3RoIC0gcnVsZVsyXSkuY29uY2F0KG1hdGNoQ2FzZShydWxlWzFdKSk7XG4gIH1cbiAgcmV0dXJuIHNob3dDb3VudCA/IGAke2NvdW50fSAke25vdW59YCA6IG5vdW47XG59XG4vLyBGb3JtYXQgc3RyaW5ncyBpbiBjb2x1bW5zXG5mdW5jdGlvbiBjb2x1bW5zKHJvd3MsIHNlcGFyYXRvciA9ICcgICcpIHtcbiAgLy8gRGV0ZXJtaW5lIHRoZSByZXF1aXJlZCBjb2x1bW4gd2lkdGhzXG4gIGNvbnN0IHdpZHRoID0gW107XG4gIHJvd3MuZm9yRWFjaChyb3cgPT4ge1xuICAgIHJvdy5mb3JFYWNoKCh2YWx1ZSwgaW5kZXgpID0+IHtcbiAgICAgIHdpZHRoW2luZGV4XSA9IE1hdGgubWF4KHdpZHRoW2luZGV4XSA/PyAwLCB2YWx1ZS5sZW5ndGgpO1xuICAgIH0pO1xuICB9KTtcbiAgd2lkdGguc3BsaWNlKC0xLCAxLCAwKTtcbiAgLy8gRm9ybWF0IHRoZSByb3dzXG4gIHJldHVybiByb3dzLm1hcChyb3cgPT4gcm93Lm1hcCgodmFsdWUsIGluZGV4KSA9PiB2YWx1ZS5wYWRFbmQod2lkdGhbaW5kZXhdID8/IDApKS5qb2luKHNlcGFyYXRvcikpO1xufVxuLy8gUmVjdXJzaXZlIG9iamVjdCBhc3NpZ25tZW50LCBza2lwcGluZyB1bmRlZmluZWQgdmFsdWVzXG5mdW5jdGlvbiBkZWVwTWVyZ2UoLi4ub2JqZWN0cykge1xuICBjb25zdCBpc09iamVjdCA9IHZhbHVlID0+IHZhbHVlICE9PSB1bmRlZmluZWQgJiYgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiAhQXJyYXkuaXNBcnJheSh2YWx1ZSk7XG4gIHJldHVybiBvYmplY3RzLnJlZHVjZSgoYWNjLCBvYmplY3QpID0+IHtcbiAgICBPYmplY3QuZW50cmllcyhvYmplY3QpLmZvckVhY2goKFtrZXksIHZhbHVlXSkgPT4ge1xuICAgICAgY29uc3QgYWNjVmFsdWUgPSBhY2Nba2V5XTtcbiAgICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSByZXR1cm47XG4gICAgICBpZiAoaXNPYmplY3QoYWNjVmFsdWUpICYmIGlzT2JqZWN0KHZhbHVlKSkgYWNjW2tleV0gPSBkZWVwTWVyZ2UoYWNjVmFsdWUsIHZhbHVlKTtlbHNlIGFjY1trZXldID0gdmFsdWU7XG4gICAgfSk7XG4gICAgcmV0dXJuIGFjYztcbiAgfSwge30pO1xufVxuLy8gQ29udmVydCBjaGVja2VyIHZhbGlkYXRpb24gZXJyb3IgaW50byBsaW5lcyBvZiB0ZXh0XG5mdW5jdGlvbiBnZXRWYWxpZGF0aW9uVHJlZShlcnJvcnMpIHtcbiAgY29uc3QgbGluZXMgPSBbXTtcbiAgZXJyb3JzLmZvckVhY2goKGVycm9yLCBpbmRleCkgPT4ge1xuICAgIGNvbnN0IHByZWZpeCA9IChhLCBiKSA9PiBpbmRleCA8IGVycm9ycy5sZW5ndGggLSAxID8gYSA6IGI7XG4gICAgbGluZXMucHVzaChgJHtwcmVmaXgoJ+KUnOKUgCAnLCAn4pSU4pSAICcpfSR7ZXJyb3IucGF0aH0gJHtlcnJvci5tZXNzYWdlfWApO1xuICAgIGlmIChlcnJvci5uZXN0ZWQpIHtcbiAgICAgIGNvbnN0IG5lc3RlZCA9IGdldFZhbGlkYXRpb25UcmVlKGVycm9yLm5lc3RlZCk7XG4gICAgICBsaW5lcy5wdXNoKC4uLm5lc3RlZC5tYXAobGluZSA9PiBgJHtwcmVmaXgoJ+KUgiAgJywgJyAgICcpfSAke2xpbmV9YCkpO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiBsaW5lcztcbn1cbi8vIEV4dHJhY3QgcHJvcGVydHkga2V5cyBvciB1bmlvbiBsaXRlcmFsIGZyb20gYSB0aS1pbnRlcmZhY2UtY2hlY2tlciB0eXBlXG5mdW5jdGlvbiBrZXlvZkNoZWNrZXIodHlwZVN1aXRlLCB0eXBlKSB7XG4gIGNvbnN0IGNoZWNrZXIgPSB0eXBlO1xuICAvLyBUSWZhY2VcbiAgY29uc3QgcHJvcHMgPSBbXTtcbiAgaWYgKGNoZWNrZXIucHJvcFNldCBpbnN0YW5jZW9mIFNldCkge1xuICAgIHByb3BzLnB1c2goLi4uY2hlY2tlci5wcm9wU2V0KTtcbiAgfVxuICBpZiAoQXJyYXkuaXNBcnJheShjaGVja2VyLmJhc2VzKSkge1xuICAgIGZvciAoY29uc3QgYmFzZSBvZiBjaGVja2VyLmJhc2VzKSB7XG4gICAgICBjb25zdCBiYXNlVHlwZSA9IHR5cGVTdWl0ZVtiYXNlXTtcbiAgICAgIGFzc2VydElzRGVmaW5lZChiYXNlVHlwZSk7XG4gICAgICBwcm9wcy5wdXNoKC4uLmtleW9mQ2hlY2tlcih0eXBlU3VpdGUsIGJhc2VUeXBlKSk7XG4gICAgfVxuICB9XG4gIC8vIFRVbmlvbiBvciBUSW50ZXJzZWN0aW9uXG4gIGlmIChBcnJheS5pc0FycmF5KGNoZWNrZXIudHR5cGVzKSkge1xuICAgIGZvciAoY29uc3QgdHR5cGUgb2YgY2hlY2tlci50dHlwZXMpIHByb3BzLnB1c2goLi4ua2V5b2ZDaGVja2VyKHR5cGVTdWl0ZSwgdHR5cGUpKTtcbiAgfVxuICAvLyBURW51bVxuICBpZiAoY2hlY2tlci52YWxpZFZhbHVlcyBpbnN0YW5jZW9mIFNldCkge1xuICAgIHByb3BzLnB1c2goLi4uY2hlY2tlci52YWxpZFZhbHVlcyk7XG4gIH1cbiAgaWYgKHR5cGVvZiBjaGVja2VyLnZhbHVlID09PSAnc3RyaW5nJykge1xuICAgIC8vIFRMaXRlcmFsXG4gICAgcHJvcHMucHVzaChjaGVja2VyLnZhbHVlKTtcbiAgfSBlbHNlIGlmICh0eXBlb2YgY2hlY2tlci5uYW1lID09PSAnc3RyaW5nJykge1xuICAgIC8vIFROYW1lXG4gICAgY29uc3QgbmFtZVR5cGUgPSB0eXBlU3VpdGVbY2hlY2tlci5uYW1lXTtcbiAgICBhc3NlcnRJc0RlZmluZWQobmFtZVR5cGUpO1xuICAgIHByb3BzLnB1c2goLi4ua2V5b2ZDaGVja2VyKHR5cGVTdWl0ZSwgbmFtZVR5cGUpKTtcbiAgfVxuICByZXR1cm4gcHJvcHM7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldD11dGYtODtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnVZVzFsY3lJNld5SmZZWE56WlhKMElpd2lYMmx1ZEdWeWIzQlNaWEYxYVhKbFJHVm1ZWFZzZENJc0luSmxjWFZwY21VaUxDSmxJaXdpWDE5bGMwMXZaSFZzWlNJc0ltUmxabUYxYkhRaUxDSk5VeUlzSW1WNGNHOXlkSE1pTENKaGMzTmxjblJKYzBSbFptbHVaV1FpTENKMllXeDFaU0lzSW1GemMyVnlkQ0lzSW01dmRGTjBjbWxqZEVWeGRXRnNJaXdpZFc1a1pXWnBibVZrSWl3aVlYTnpaWEowU1hOVmJtUmxabWx1WldRaUxDSnpkSEpwWTNSRmNYVmhiQ0lzSW1GemMyVnlkRWx6VTNSeWFXNW5JaXdpWVhOelpYSjBTWE5PZFcxaVpYSWlMQ0poYzNObGNuUkpjMEp2YjJ4bFlXNGlMQ0poYzNObGNuUkpjMGx1YzNSaGJtTmxUMllpTENKMGVYQmxJaXdpYm1GdFpTSXNJbVp2Y20xaGRFMXBiR3hwYzJWamIyNWtjeUlzSW0xeklpd2liV0Y0VUdGeWRITWlMQ0prZFhKaGRHbHZiaUlzSWsxaGRHZ2lMQ0ptYkc5dmNpSXNJbk5vYVdaMElpd2ljMnhwWTJVaUxDSm1hV3gwWlhJaUxDSmZhMlY1SWl3aWJXRndJaXdpYTJWNUlpd2ljR3gxY21Gc0lpd2lhbTlwYmlJc0ltWnZjbTFoZEZObFkyOXVaSE1pTENKelpXTnZibVJ6SWl3aVptOXliV0YwVEdsemRDSXNJbWwwWlcxeklpd2liR1Z1WjNSb0lpd2lZMjkxYm5RaUxDSnViM1Z1SWl3aWMyaHZkME52ZFc1MElpd2ljMmx1WjNWc1lYSWlMQ0pCY25KaGVTSXNJbWx6UVhKeVlYa2lMQ0p5ZFd4bGN5SXNJbkoxYkdVaUxDSm1hVzVrSWl3aVpXNWthVzVuSWl3aVVtVm5SWGh3SWl3aWRHVnpkQ0lzSW0xaGRHTm9RMkZ6WlNJc0luTWlMQ0owYjFWd2NHVnlRMkZ6WlNJc0luTjFZbk4wY21sdVp5SXNJbU52Ym1OaGRDSXNJbU52YkhWdGJuTWlMQ0p5YjNkeklpd2ljMlZ3WVhKaGRHOXlJaXdpZDJsa2RHZ2lMQ0ptYjNKRllXTm9JaXdpY205M0lpd2lhVzVrWlhnaUxDSnRZWGdpTENKemNHeHBZMlVpTENKd1lXUkZibVFpTENKa1pXVndUV1Z5WjJVaUxDSnZZbXBsWTNSeklpd2lhWE5QWW1wbFkzUWlMQ0p5WldSMVkyVWlMQ0poWTJNaUxDSnZZbXBsWTNRaUxDSlBZbXBsWTNRaUxDSmxiblJ5YVdWeklpd2lZV05qVm1Gc2RXVWlMQ0puWlhSV1lXeHBaR0YwYVc5dVZISmxaU0lzSW1WeWNtOXljeUlzSW14cGJtVnpJaXdpWlhKeWIzSWlMQ0p3Y21WbWFYZ2lMQ0poSWl3aVlpSXNJbkIxYzJnaUxDSndZWFJvSWl3aWJXVnpjMkZuWlNJc0ltNWxjM1JsWkNJc0lteHBibVVpTENKclpYbHZaa05vWldOclpYSWlMQ0owZVhCbFUzVnBkR1VpTENKamFHVmphMlZ5SWl3aWNISnZjSE1pTENKd2NtOXdVMlYwSWl3aVUyVjBJaXdpWW1GelpYTWlMQ0ppWVhObElpd2lZbUZ6WlZSNWNHVWlMQ0owZEhsd1pYTWlMQ0owZEhsd1pTSXNJblpoYkdsa1ZtRnNkV1Z6SWl3aWJtRnRaVlI1Y0dVaVhTd2ljMjkxY21ObGN5STZXeUl1TGk5emNtTXZkWFJwYkhNdWRITWlYU3dpYzI5MWNtTmxjME52Ym5SbGJuUWlPbHR1ZFd4c1hTd2liV0Z3Y0dsdVozTWlPaUk3T3pzN096czdPenM3T3pzN096czdPenM3TzBGQlIwRXNTVUZCUVVFc1QwRkJRU3hIUVVGQlF5eHpRa0ZCUVN4RFFVRkJReXhQUVVGQk8wRkJRVFJDTEZOQlFVRkVMSFZDUVVGQlJTeERRVUZCTEZkQlFVRkJMRU5CUVVFc1NVRkJRVUVzUTBGQlFTeERRVUZCUXl4VlFVRkJMRWRCUVVGRUxFTkJRVUVzUzBGQlFVVXNUMEZCUVN4RlFVRkJSaXhEUVVGQk8wRkJTRFZDTzBGQlEwRTdPMEZCUzBFN1FVRkRUeXhOUVVGTlJ5eEZRVUZGTEVkQlFVRkRMRTlCUVVFc1EwRkJRVVFzUlVGQlFTeEhRVUZITEVsQlFVazdRVUZqZEVJN1FVRkRUU3hUUVVGVlJTeGxRVUZsUVN4RFFVRlBReXhMUVVGWE8wVkJRemREUXl4bFFVRk5MRU5CUVVORExHTkJRV01zUTBGQlEwWXNTMEZCU3l4RlFVRkZSeXhUUVVGVExFTkJRVU03UlVGRGRrTkdMR1ZCUVUwc1EwRkJRME1zWTBGQll5eERRVUZEUml4TFFVRkxMRVZCUVVVc1NVRkJTU3hEUVVGRE8wRkJRM1JETzBGQlEwMHNVMEZCVlVrc2FVSkJRV2xDUVN4RFFVRkRTaXhMUVVGak8wVkJRelZEUXl4bFFVRk5MRU5CUVVOSkxGZEJRVmNzUTBGQlEwd3NTMEZCU3l4RlFVRkZSeXhUUVVGVExFTkJRVU03UVVGRGVFTTdRVUZEVFN4VFFVRlZSeXhqUVVGalFTeERRVUZEVGl4TFFVRmpPMFZCUTNwRFF5eGxRVUZOTEVOQlFVTkpMRmRCUVZjc1EwRkJReXhQUVVGUFRDeExRVUZMTEVWQlFVVXNVVUZCVVN4RFFVRkRPMEZCUXpsRE8wRkJRMDBzVTBGQlZVOHNZMEZCWTBFc1EwRkJRMUFzUzBGQll6dEZRVU42UTBNc1pVRkJUU3hEUVVGRFNTeFhRVUZYTEVOQlFVTXNUMEZCVDB3c1MwRkJTeXhGUVVGRkxGRkJRVkVzUTBGQlF6dEJRVU01UXp0QlFVTk5MRk5CUVZWUkxHVkJRV1ZCTEVOQlFVTlNMRXRCUVdNN1JVRkRNVU5ETEdWQlFVMHNRMEZCUTBrc1YwRkJWeXhEUVVGRExFOUJRVTlNTEV0QlFVc3NSVUZCUlN4VFFVRlRMRU5CUVVNN1FVRkRMME03UVVGRFRTeFRRVUZWVXl4clFrRkJhMEpCTEVOQlFYTkNWQ3hMUVVGakxFVkJRVVZWTEVsQlFYVkNPMFZCUXpOR0xFbEJRVUZVTEdWQlFVMHNSVUZCUTBRc1MwRkJTeXhaUVVGWlZTeEpRVUZKTEVWQlFVVXNjMEpCUVhOQ1FTeEpRVUZKTEVOQlFVTkRMRWxCUVVrc1JVRkJSU3hEUVVGRE8wRkJRM0JGTzBGQlJVRTdRVUZEVFN4VFFVRlZReXhyUWtGQmEwSkJMRU5CUVVORExFVkJRVlVzUlVGQlJVTXNVVUZCVVN4SFFVRkhMRU5CUVVNN1JVRkRka1FzU1VGQlNVUXNSVUZCUlN4SFFVRkhMRU5CUVVNc1JVRkJSU3hQUVVGUExFdEJRVXM3UlVGRmVFSTdSVUZEUVN4TlFVRk5SU3hSUVVGUkxFZEJRWFZDTEVOQlEycERMRU5CUVVNc1MwRkJTeXhGUVVGVlF5eEpRVUZKTEVOQlFVTkRMRXRCUVVzc1EwRkJRMG9zUlVGQlJTeEpRVUZKTEVWQlFVVXNSMEZCUnl4RlFVRkZMRWRCUVVjc1JVRkJSU3hIUVVGSGFFSXNSVUZCUlN4RFFVRkRMRU5CUVVNc1EwRkJUU3hGUVVNeFJDeERRVUZETEUxQlFVMHNSVUZCVTIxQ0xFbEJRVWtzUTBGQlEwTXNTMEZCU3l4RFFVRkRTaXhGUVVGRkxFbEJRVk1zUlVGQlJTeEhRVUZITEVWQlFVVXNSMEZCUjJoQ0xFVkJRVVVzUTBGQlF5eERRVUZETEVkQlFVY3NSVUZCUlN4RFFVRkRMRVZCUXpGRUxFTkJRVU1zVVVGQlVTeEZRVUZQYlVJc1NVRkJTU3hEUVVGRFF5eExRVUZMTEVOQlFVTktMRVZCUVVVc1NVRkJZeXhGUVVGRkxFZEJRVWRvUWl4RlFVRkZMRU5CUVVNc1EwRkJReXhIUVVGSExFVkJRVVVzUTBGQlF5eEZRVU14UkN4RFFVRkRMRkZCUVZFc1JVRkJUMjFDTEVsQlFVa3NRMEZCUTBNc1MwRkJTeXhEUVVGRFNpeEZRVUZGTEVkQlFXMUNhRUlzUlVGQlJTeERRVUZGTEVkQlFVY3NSVUZCUlN4RFFVRkRMRVZCUXpGRUxFTkJRVU1zWVVGQllTeEZRVUZGYlVJc1NVRkJTU3hEUVVGRFF5eExRVUZMTEVOQlFVTktMRVZCUVVVc1EwRkJkVUlzUjBGQlIyaENMRVZCUVVVc1EwRkJReXhEUVVNM1JEdEZRVVZFTzBWQlEwRXNUMEZCVDJ0Q0xGRkJRVkVzUTBGQlF5eERRVUZETEVOQlFVTXNSMEZCUnl4RFFVRkRMRU5CUVVNc1MwRkJTeXhEUVVGRExFVkJRVVZCTEZGQlFWRXNRMEZCUTBjc1MwRkJTeXhGUVVGRk8wVkJSUzlETzBWQlEwRXNUMEZCVDBnc1VVRkJVU3hEUVVGRFNTeExRVUZMTEVOQlFVTXNRMEZCUXl4RlFVRkZUQ3hSUVVGUkxFTkJRVU1zUTBGRE4wSk5MRTFCUVUwc1EwRkJReXhEUVVGRExFTkJRVU5ETEVsQlFVa3NSVUZCUlhKQ0xFdEJRVXNzUTBGQlF5eExRVUZMUVN4TFFVRkxMRXRCUVVzc1EwRkJReXhEUVVGRExFTkJRM1JEYzBJc1IwRkJSeXhEUVVGRExFTkJRVU1zUTBGQlEwTXNSMEZCUnl4RlFVRkZka0lzUzBGQlN5eERRVUZETEV0QlFVdDNRaXhOUVVGTkxFTkJRVU40UWl4TFFVRkxMRVZCUVVWMVFpeEhRVUZITEVOQlFVTXNRMEZCUXl4RFFVTjZRMFVzU1VGQlNTeERRVUZETEVkQlFVY3NRMEZCUXp0QlFVTnNRanRCUVVWQk8wRkJRMDBzVTBGQlZVTXNZVUZCWVVFc1EwRkJRME1zVDBGQlpTeEZRVUZGWWl4UlFVRlJMRWRCUVVjc1EwRkJRenRGUVVOMlJDeFBRVUZQUml4clFrRkJhMElzUTBGQlEyVXNUMEZCVHl4SFFVRkhMRWxCUVVrc1JVRkJSV0lzVVVGQlVTeERRVUZETzBGQlEzWkVPMEZCUlVFN1FVRkRUU3hUUVVGVll5eFZRVUZWUVN4RFFVRkRReXhMUVVGbE8wVkJRM1JETEZGQlFWRkJMRXRCUVVzc1EwRkJRME1zVFVGQlRUdEpRVU53UWl4TFFVRkxMRU5CUVVNN1RVRkJUU3hQUVVGUExFdEJRVXM3U1VGRGVFSXNTMEZCU3l4RFFVRkRPMDFCUVUwc1QwRkJUMFFzUzBGQlN5eERRVUZETEVOQlFVTXNRMEZCUXl4SlFVRkpMRVZCUVVVN1NVRkRha01zUzBGQlN5eERRVUZETzAxQlFVMHNUMEZCVHl4SFFVRkhRU3hMUVVGTExFTkJRVU1zUTBGQlF5eERRVUZETEZGQlFWRkJMRXRCUVVzc1EwRkJReXhEUVVGRExFTkJRVU1zUlVGQlJUdEpRVU5vUkR0TlFVRlpMRTlCUVU4c1EwRkJReXhIUVVGSFFTeExRVUZMTEVOQlFVTldMRXRCUVVzc1EwRkJReXhEUVVGRExFVkJRVVVzUTBGQlF5eERRVUZETEVOQlFVTXNSVUZCUlN4UFFVRlBWU3hMUVVGTExFTkJRVU5CTEV0QlFVc3NRMEZCUTBNc1RVRkJUU3hIUVVGSExFTkJRVU1zUTBGQlF5eEZRVUZGTEVOQlFVTXNRMEZCUTB3c1NVRkJTU3hEUVVGRExFbEJRVWtzUTBGQlF6dEZRVU4yUmp0QlFVTktPMEZCUlVFN1FVRkRUU3hUUVVGVlJDeE5RVUZOUVN4RFFVRkRUeXhMUVVGaExFVkJRVVZETEVsQlFTdENMRVZCUVVWRExGTkJRVk1zUjBGQlJ5eEpRVUZKTzBWQlEyNUdMRTFCUVUwc1EwRkJRME1zVVVGQlVTeEZRVUZGVml4TlFVRk5MRU5CUVVNc1IwRkJSMWNzUzBGQlN5eERRVUZEUXl4UFFVRlBMRU5CUVVOS0xFbEJRVWtzUTBGQlF5eEhRVUZIUVN4SlFVRkpMRWRCUVVjc1EwRkJRMEVzU1VGQlNTeEZRVUZGTEVWQlFVVXNRMEZCUXp0RlFVTnNSVUVzU1VGQlNTeEhRVUZIUkN4TFFVRkxMRXRCUVVzc1EwRkJReXhIUVVGSFJ5eFJRVUZSTEVkQlFVZFdMRTFCUVUwN1JVRkRkRU1zU1VGQlNTeERRVUZEVVN4SlFVRkpMRVZCUVVVN1NVRkRVRHRKUVVOQkxFMUJRVTFMTEV0QlFVc3NSMEZCSzBJc1EwRkRkRU1zUTBGQlF5eExRVUZMTEVWQlFXdENMRWRCUVVjc1JVRkJTU3hEUVVGRExFTkJRVU03U1VGQlJUdEpRVU51UXl4RFFVRkRMRXRCUVVzc1JVRkJhMElzUjBGQlJ5eEZRVUZKTEVOQlFVTXNRMEZCUXp0SlFVRkZPMGxCUTI1RExFTkJRVU1zV1VGQldTeEZRVUZYTEV0QlFVc3NSVUZCUlN4RFFVRkRMRU5CUVVNN1NVRkJSVHRKUVVOdVF5eERRVUZETEhGQ1FVRnhRaXhGUVVGRkxFbEJRVWtzUlVGQlJ5eERRVUZETEVOQlFVTTdTVUZCUlR0SlFVTnVReXhEUVVGRExFVkJRVVVzUlVGQmNVSXNSMEZCUnl4RlFVRkpMRU5CUVVNc1EwRkJReXhEUVVGRk8wbEJRVUVzUTBGRGRFTTdTVUZEUkN4TlFVRk5ReXhKUVVGSkxFZEJRVWRFTEV0QlFVc3NRMEZCUTBVc1NVRkJTU3hEUVVGRExFTkJRVU1zUTBGQlEwTXNUVUZCVFN4RFFVRkRMRXRCUVVzc1NVRkJTVU1zVFVGQlRTeERRVUZEUkN4TlFVRk5MRVZCUVVVc1IwRkJSeXhEUVVGRExFTkJRVU5GTEVsQlFVa3NRMEZCUTFJc1VVRkJVU3hEUVVGRExFTkJRVU03U1VGRE4wVnVReXhsUVVGbExFTkJRVU4xUXl4SlFVRkpMRU5CUVVNN1NVRkRja0lzVFVGQlRVc3NVMEZCVXl4SFFVRkpReXhEUVVGVExFbEJRV0ZXTEZGQlFWRXNTMEZCUzBFc1VVRkJVU3hEUVVGRFZ5eFhRVUZYTEVWQlFVVXNSMEZCUjBRc1EwRkJReXhEUVVGRFF5eFhRVUZYTEVWQlFVVXNSMEZCUjBRc1EwRkJRenRKUVVOc1Ixb3NTVUZCU1N4SFFVRkhSU3hSUVVGUkxFTkJRVU5aTEZOQlFWTXNRMEZCUXl4RFFVRkRMRVZCUVVWYUxGRkJRVkVzUTBGQlEwb3NUVUZCVFN4SFFVRkhVU3hKUVVGSkxFTkJRVU1zUTBGQlF5eERRVUZETEVOQlFVTXNRMEZCUTFNc1RVRkJUU3hEUVVGRFNpeFRRVUZUTEVOQlFVTk1MRWxCUVVrc1EwRkJReXhEUVVGRExFTkJRVU1zUTBGQlF5eERRVUZETzBWQlEzUkdPMFZCUTBFc1QwRkJUMHdzVTBGQlV5eEhRVUZITEVkQlFVZEdMRXRCUVVzc1NVRkJTVU1zU1VGQlNTeEZRVUZGTEVkQlFVZEJMRWxCUVVrN1FVRkRhRVE3UVVGRlFUdEJRVU5OTEZOQlFWVm5RaXhQUVVGUFFTeERRVUZEUXl4SlFVRm5RaXhGUVVGRlF5eFRRVUZUTEVkQlFVY3NTVUZCU1R0RlFVTjBSRHRGUVVOQkxFMUJRVTFETEV0QlFVc3NSMEZCWVN4RlFVRkZPMFZCUXpGQ1JpeEpRVUZKTEVOQlFVTkhMRTlCUVU4c1EwRkJRME1zUjBGQlJ5eEpRVUZITzBsQlEyWkJMRWRCUVVjc1EwRkJRMFFzVDBGQlR5eERRVUZETEVOQlFVTndSQ3hMUVVGTExFVkJRVVZ6UkN4TFFVRkxMRXRCUVVrN1RVRkRla0pJTEV0QlFVc3NRMEZCUTBjc1MwRkJTeXhEUVVGRExFZEJRVWQwUXl4SlFVRkpMRU5CUVVOMVF5eEhRVUZITEVOQlFVTktMRXRCUVVzc1EwRkJRMGNzUzBGQlN5eERRVUZETEVsQlFVa3NRMEZCUXl4RlFVRkZkRVFzUzBGQlN5eERRVUZET0VJc1RVRkJUU3hEUVVGRE8wbEJRelZFTEVOQlFVTXNRMEZCUXp0RlFVTk9MRU5CUVVNc1EwRkJRenRGUVVOR2NVSXNTMEZCU3l4RFFVRkRTeXhOUVVGTkxFTkJRVU1zUTBGQlF5eERRVUZETEVWQlFVVXNRMEZCUXl4RlFVRkZMRU5CUVVNc1EwRkJRenRGUVVWMFFqdEZRVU5CTEU5QlFVOVFMRWxCUVVrc1EwRkJRek5DTEVkQlFVY3NRMEZCUXl0Q0xFZEJRVWNzU1VGQlNVRXNSMEZCUnl4RFFVRkRMMElzUjBGQlJ5eERRVUZETEVOQlFVTjBRaXhMUVVGTExFVkJRVVZ6UkN4TFFVRkxMRXRCUVV0MFJDeExRVUZMTEVOQlFVTjVSQ3hOUVVGTkxFTkJRVU5PTEV0QlFVc3NRMEZCUTBjc1MwRkJTeXhEUVVGRExFbEJRVWtzUTBGQlF5eERRVUZETEVOQlFVTXNRMEZCUXpkQ0xFbEJRVWtzUTBGQlEzbENMRk5CUVZNc1EwRkJReXhEUVVGRE8wRkJRM1JITzBGQlJVRTdRVUZEVFN4VFFVRlZVU3hUUVVGVFFTeERRVUZ6UWl4SFFVRkhReXhQUVVGdFF6dEZRVU5xUml4TlFVRk5ReXhSUVVGUkxFZEJRVWsxUkN4TFFVRmpMRWxCUXpWQ1FTeExRVUZMTEV0QlFVdEhMRk5CUVZNc1NVRkJTU3hQUVVGUFNDeExRVUZMTEV0QlFVc3NVVUZCVVN4SlFVRkpMRU5CUVVOdFF5eExRVUZMTEVOQlFVTkRMRTlCUVU4c1EwRkJRM0JETEV0QlFVc3NRMEZCUXp0RlFVTTNSU3hQUVVGUE1rUXNUMEZCVHl4RFFVRkRSU3hOUVVGTkxFTkJRVU1zUTBGQlEwTXNSMEZCTkVJc1JVRkJSVU1zVFVGQll5eExRVUZKTzBsQlEyNUZReXhOUVVGTkxFTkJRVU5ETEU5QlFVOHNRMEZCUTBZc1RVRkJUU3hEUVVGRExFTkJRVU5ZTEU5QlFVOHNRMEZCUXl4RFFVRkRMRU5CUVVNM1FpeEhRVUZITEVWQlFVVjJRaXhMUVVGTExFTkJRVU1zUzBGQlNUdE5RVU0xUXl4TlFVRk5hMFVzVVVGQlVTeEhRVUZIU2l4SFFVRkhMRU5CUVVOMlF5eEhRVUZITEVOQlFVTTdUVUZEZWtJc1NVRkJTWFpDTEV0QlFVc3NTMEZCUzBjc1UwRkJVeXhGUVVGRk8wMUJRM3BDTEVsQlFVbDVSQ3hSUVVGUkxFTkJRVU5OTEZGQlFWRXNRMEZCUXl4SlFVRkpUaXhSUVVGUkxFTkJRVU0xUkN4TFFVRkxMRU5CUVVNc1JVRkJSVGhFTEVkQlFVY3NRMEZCUTNaRExFZEJRVWNzUTBGQlF5eEhRVUZIYlVNc1UwRkJVeXhEUVVGRFVTeFJRVUZSTEVWQlFVVnNSU3hMUVVGTExFTkJRVU1zUTBGQlF5eExRVU0xUlRoRUxFZEJRVWNzUTBGQlEzWkRMRWRCUVVjc1EwRkJReXhIUVVGSGRrSXNTMEZCU3p0SlFVTjZRaXhEUVVGRExFTkJRVU03U1VGRFJpeFBRVUZQT0VRc1IwRkJSenRGUVVOa0xFTkJRVU1zUlVGQlJTeEZRVUZGTEVOQlFWTTdRVUZEYkVJN1FVRlJRVHRCUVVOTkxGTkJRVlZMTEdsQ1FVRnBRa0VzUTBGQlEwTXNUVUZCYzBJN1JVRkRjRVFzVFVGQlRVTXNTMEZCU3l4SFFVRmhMRVZCUVVVN1JVRkRNVUpFTEUxQlFVMHNRMEZCUTJoQ0xFOUJRVThzUTBGQlF5eERRVUZEYTBJc1MwRkJTeXhGUVVGRmFFSXNTMEZCU3l4TFFVRkpPMGxCUXpWQ0xFMUJRVTFwUWl4TlFVRk5MRWRCUVVkQkxFTkJRVU5ETEVOQlFWTXNSVUZCUlVNc1EwRkJVeXhMUVVGaGJrSXNTMEZCU3l4SFFVRkhZeXhOUVVGTkxFTkJRVU4wUXl4TlFVRk5MRWRCUVVjc1EwRkJReXhIUVVGSE1FTXNRMEZCUXl4SFFVRkhReXhEUVVGRE8wbEJRMnhHU2l4TFFVRkxMRU5CUVVOTExFbEJRVWtzUTBGQlF5eEhRVUZIU0N4TlFVRk5MRU5CUVVNc1MwRkJTeXhGUVVGRkxFdEJRVXNzUTBGQlF5eEhRVUZIUkN4TFFVRkxMRU5CUVVOTExFbEJRVWtzU1VGQlNVd3NTMEZCU3l4RFFVRkRUU3hQUVVGUExFVkJRVVVzUTBGQlF6dEpRVU51UlN4SlFVRkpUaXhMUVVGTExFTkJRVU5QTEUxQlFVMHNSVUZCUlR0TlFVTmtMRTFCUVUxQkxFMUJRVTBzUjBGQlIxWXNhVUpCUVdsQ0xFTkJRVU5ITEV0QlFVc3NRMEZCUTA4c1RVRkJUU3hEUVVGRE8wMUJRemxEVWl4TFFVRkxMRU5CUVVOTExFbEJRVWtzUTBGQlF5eEhRVUZIUnl4TlFVRk5MRU5CUVVOMlJDeEhRVUZITEVOQlFVTjNSQ3hKUVVGSkxFbEJRVWtzUjBGQlIxQXNUVUZCVFN4RFFVRkRMRXRCUVVzc1JVRkJSU3hMUVVGTExFTkJRVU1zU1VGQlNVOHNTVUZCU1N4RlFVRkZMRU5CUVVNc1EwRkJRenRKUVVONFJUdEZRVU5LTEVOQlFVTXNRMEZCUXp0RlFVTkdMRTlCUVU5VUxFdEJRVXM3UVVGRGFFSTdRVUZGUVR0QlFVTk5MRk5CUVZWVkxGbEJRVmxCTEVOQlFVTkRMRk5CUVhGQ0xFVkJRVVYwUlN4SlFVRlhPMFZCUXpORUxFMUJRVTExUlN4UFFVRlBMRWRCUVVkMlJTeEpRVTltTzBWQlJVUTdSVUZEUVN4TlFVRk5kMFVzUzBGQlN5eEhRVUZITEVWQlFVVTdSVUZEYUVJc1NVRkJTVVFzVDBGQlR5eERRVUZEUlN4UFFVRlBMRmxCUVZsRExFZEJRVWNzUlVGQlJUdEpRVU5vUTBZc1MwRkJTeXhEUVVGRFVpeEpRVUZKTEVOQlFVTXNSMEZCUjA4c1QwRkJUeXhEUVVGRFJTeFBRVUZQTEVOQlFVTTdSVUZEYkVNN1JVRkRRU3hKUVVGSmFFUXNTMEZCU3l4RFFVRkRReXhQUVVGUExFTkJRVU0yUXl4UFFVRlBMRU5CUVVOSkxFdEJRVXNzUTBGQlF5eEZRVUZGTzBsQlF6bENMRXRCUVVzc1RVRkJUVU1zU1VGQlNTeEpRVUZKVEN4UFFVRlBMRU5CUVVOSkxFdEJRVXNzUlVGQlJUdE5RVU01UWl4TlFVRk5SU3hSUVVGUkxFZEJRVWRRTEZOQlFWTXNRMEZCUTAwc1NVRkJTU3hEUVVGRE8wMUJRMmhEZGtZc1pVRkJaU3hEUVVGRGQwWXNVVUZCVVN4RFFVRkRPMDFCUTNwQ1RDeExRVUZMTEVOQlFVTlNMRWxCUVVrc1EwRkJReXhIUVVGSFN5eFpRVUZaTEVOQlFVTkRMRk5CUVZNc1JVRkJSVThzVVVGQlVTeERRVUZETEVOQlFVTTdTVUZEY0VRN1JVRkRTanRGUVVWQk8wVkJRMEVzU1VGQlNYQkVMRXRCUVVzc1EwRkJRME1zVDBGQlR5eERRVUZETmtNc1QwRkJUeXhEUVVGRFR5eE5RVUZOTEVOQlFVTXNSVUZCUlR0SlFVTXZRaXhMUVVGTExFMUJRVTFETEV0QlFVc3NTVUZCU1ZJc1QwRkJUeXhEUVVGRFR5eE5RVUZOTEVWQlF6bENUaXhMUVVGTExFTkJRVU5TTEVsQlFVa3NRMEZCUXl4SFFVRkhTeXhaUVVGWkxFTkJRVU5ETEZOQlFWTXNSVUZCUlZNc1MwRkJTeXhEUVVGRExFTkJRVU03UlVGRGNrUTdSVUZGUVR0RlFVTkJMRWxCUVVsU0xFOUJRVThzUTBGQlExTXNWMEZCVnl4WlFVRlpUaXhIUVVGSExFVkJRVVU3U1VGRGNFTkdMRXRCUVVzc1EwRkJRMUlzU1VGQlNTeERRVUZETEVkQlFVZFBMRTlCUVU4c1EwRkJRMU1zVjBGQlZ5eERRVUZETzBWQlEzUkRPMFZCUlVFc1NVRkJTU3hQUVVGUFZDeFBRVUZQTEVOQlFVTnFSaXhMUVVGTExFdEJRVXNzVVVGQlVTeEZRVUZGTzBsQlEyNURPMGxCUTBGclJpeExRVUZMTEVOQlFVTlNMRWxCUVVrc1EwRkJRMDhzVDBGQlR5eERRVUZEYWtZc1MwRkJTeXhEUVVGRE8wVkJRemRDTEVOQlFVTXNUVUZCVFN4SlFVRkpMRTlCUVU5cFJpeFBRVUZQTEVOQlFVTjBSU3hKUVVGSkxFdEJRVXNzVVVGQlVTeEZRVUZGTzBsQlEzcERPMGxCUTBFc1RVRkJUV2RHTEZGQlFWRXNSMEZCUjFnc1UwRkJVeXhEUVVGRFF5eFBRVUZQTEVOQlFVTjBSU3hKUVVGSkxFTkJRVU03U1VGRGVFTmFMR1ZCUVdVc1EwRkJRelJHTEZGQlFWRXNRMEZCUXp0SlFVTjZRbFFzUzBGQlN5eERRVUZEVWl4SlFVRkpMRU5CUVVNc1IwRkJSMHNzV1VGQldTeERRVUZEUXl4VFFVRlRMRVZCUVVWWExGRkJRVkVzUTBGQlF5eERRVUZETzBWQlEzQkVPMFZCUlVFc1QwRkJUMVFzUzBGQlN6dEJRVU5vUWlJc0ltbG5ibTl5WlV4cGMzUWlPbHRkZlE9PSIsIid1c2Ugc3RyaWN0JztcblxudmFyIG9iamVjdEFzc2lnbiA9IHJlcXVpcmUoJ29iamVjdC5hc3NpZ24vcG9seWZpbGwnKSgpO1xuXG4vLyBjb21wYXJlIGFuZCBpc0J1ZmZlciB0YWtlbiBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9mZXJvc3MvYnVmZmVyL2Jsb2IvNjgwZTllNWU0ODhmMjJhYWMyNzU5OWE1N2RjODQ0YTYzMTU5MjhkZC9pbmRleC5qc1xuLy8gb3JpZ2luYWwgbm90aWNlOlxuXG4vKiFcbiAqIFRoZSBidWZmZXIgbW9kdWxlIGZyb20gbm9kZS5qcywgZm9yIHRoZSBicm93c2VyLlxuICpcbiAqIEBhdXRob3IgICBGZXJvc3MgQWJvdWtoYWRpamVoIDxmZXJvc3NAZmVyb3NzLm9yZz4gPGh0dHA6Ly9mZXJvc3Mub3JnPlxuICogQGxpY2Vuc2UgIE1JVFxuICovXG5mdW5jdGlvbiBjb21wYXJlKGEsIGIpIHtcbiAgaWYgKGEgPT09IGIpIHtcbiAgICByZXR1cm4gMDtcbiAgfVxuXG4gIHZhciB4ID0gYS5sZW5ndGg7XG4gIHZhciB5ID0gYi5sZW5ndGg7XG5cbiAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IE1hdGgubWluKHgsIHkpOyBpIDwgbGVuOyArK2kpIHtcbiAgICBpZiAoYVtpXSAhPT0gYltpXSkge1xuICAgICAgeCA9IGFbaV07XG4gICAgICB5ID0gYltpXTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIGlmICh4IDwgeSkge1xuICAgIHJldHVybiAtMTtcbiAgfVxuICBpZiAoeSA8IHgpIHtcbiAgICByZXR1cm4gMTtcbiAgfVxuICByZXR1cm4gMDtcbn1cbmZ1bmN0aW9uIGlzQnVmZmVyKGIpIHtcbiAgaWYgKGdsb2JhbC5CdWZmZXIgJiYgdHlwZW9mIGdsb2JhbC5CdWZmZXIuaXNCdWZmZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gZ2xvYmFsLkJ1ZmZlci5pc0J1ZmZlcihiKTtcbiAgfVxuICByZXR1cm4gISEoYiAhPSBudWxsICYmIGIuX2lzQnVmZmVyKTtcbn1cblxuLy8gYmFzZWQgb24gbm9kZSBhc3NlcnQsIG9yaWdpbmFsIG5vdGljZTpcbi8vIE5COiBUaGUgVVJMIHRvIHRoZSBDb21tb25KUyBzcGVjIGlzIGtlcHQganVzdCBmb3IgdHJhZGl0aW9uLlxuLy8gICAgIG5vZGUtYXNzZXJ0IGhhcyBldm9sdmVkIGEgbG90IHNpbmNlIHRoZW4sIGJvdGggaW4gQVBJIGFuZCBiZWhhdmlvci5cblxuLy8gaHR0cDovL3dpa2kuY29tbW9uanMub3JnL3dpa2kvVW5pdF9UZXN0aW5nLzEuMFxuLy9cbi8vIFRISVMgSVMgTk9UIFRFU1RFRCBOT1IgTElLRUxZIFRPIFdPUksgT1VUU0lERSBWOCFcbi8vXG4vLyBPcmlnaW5hbGx5IGZyb20gbmFyd2hhbC5qcyAoaHR0cDovL25hcndoYWxqcy5vcmcpXG4vLyBDb3B5cmlnaHQgKGMpIDIwMDkgVGhvbWFzIFJvYmluc29uIDwyODBub3J0aC5jb20+XG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxuLy8gb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgJ1NvZnR3YXJlJyksIHRvXG4vLyBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZVxuLy8gcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yXG4vLyBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xuLy8gZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpblxuLy8gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICdBUyBJUycsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1Jcbi8vIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuLy8gRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG4vLyBBVVRIT1JTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTlxuLy8gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTlxuLy8gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbnZhciB1dGlsID0gcmVxdWlyZSgndXRpbC8nKTtcbnZhciBoYXNPd24gPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xudmFyIHBTbGljZSA9IEFycmF5LnByb3RvdHlwZS5zbGljZTtcbnZhciBmdW5jdGlvbnNIYXZlTmFtZXMgPSAoZnVuY3Rpb24gKCkge1xuICByZXR1cm4gZnVuY3Rpb24gZm9vKCkge30ubmFtZSA9PT0gJ2Zvbyc7XG59KCkpO1xuZnVuY3Rpb24gcFRvU3RyaW5nIChvYmopIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvYmopO1xufVxuZnVuY3Rpb24gaXNWaWV3KGFycmJ1Zikge1xuICBpZiAoaXNCdWZmZXIoYXJyYnVmKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAodHlwZW9mIGdsb2JhbC5BcnJheUJ1ZmZlciAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAodHlwZW9mIEFycmF5QnVmZmVyLmlzVmlldyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBBcnJheUJ1ZmZlci5pc1ZpZXcoYXJyYnVmKTtcbiAgfVxuICBpZiAoIWFycmJ1Zikge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAoYXJyYnVmIGluc3RhbmNlb2YgRGF0YVZpZXcpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICBpZiAoYXJyYnVmLmJ1ZmZlciAmJiBhcnJidWYuYnVmZmVyIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG4vLyAxLiBUaGUgYXNzZXJ0IG1vZHVsZSBwcm92aWRlcyBmdW5jdGlvbnMgdGhhdCB0aHJvd1xuLy8gQXNzZXJ0aW9uRXJyb3IncyB3aGVuIHBhcnRpY3VsYXIgY29uZGl0aW9ucyBhcmUgbm90IG1ldC4gVGhlXG4vLyBhc3NlcnQgbW9kdWxlIG11c3QgY29uZm9ybSB0byB0aGUgZm9sbG93aW5nIGludGVyZmFjZS5cblxudmFyIGFzc2VydCA9IG1vZHVsZS5leHBvcnRzID0gb2s7XG5cbi8vIDIuIFRoZSBBc3NlcnRpb25FcnJvciBpcyBkZWZpbmVkIGluIGFzc2VydC5cbi8vIG5ldyBhc3NlcnQuQXNzZXJ0aW9uRXJyb3IoeyBtZXNzYWdlOiBtZXNzYWdlLFxuLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjdHVhbDogYWN0dWFsLFxuLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkOiBleHBlY3RlZCB9KVxuXG52YXIgcmVnZXggPSAvXFxzKmZ1bmN0aW9uXFxzKyhbXlxcKFxcc10qKVxccyovO1xuLy8gYmFzZWQgb24gaHR0cHM6Ly9naXRodWIuY29tL2xqaGFyYi9mdW5jdGlvbi5wcm90b3R5cGUubmFtZS9ibG9iL2FkZWVlZWM4YmZjYzYwNjhiMTg3ZDdkOWZiM2Q1YmIxZDNhMzA4OTkvaW1wbGVtZW50YXRpb24uanNcbmZ1bmN0aW9uIGdldE5hbWUoZnVuYykge1xuICBpZiAoIXV0aWwuaXNGdW5jdGlvbihmdW5jKSkge1xuICAgIHJldHVybjtcbiAgfVxuICBpZiAoZnVuY3Rpb25zSGF2ZU5hbWVzKSB7XG4gICAgcmV0dXJuIGZ1bmMubmFtZTtcbiAgfVxuICB2YXIgc3RyID0gZnVuYy50b1N0cmluZygpO1xuICB2YXIgbWF0Y2ggPSBzdHIubWF0Y2gocmVnZXgpO1xuICByZXR1cm4gbWF0Y2ggJiYgbWF0Y2hbMV07XG59XG5hc3NlcnQuQXNzZXJ0aW9uRXJyb3IgPSBmdW5jdGlvbiBBc3NlcnRpb25FcnJvcihvcHRpb25zKSB7XG4gIHRoaXMubmFtZSA9ICdBc3NlcnRpb25FcnJvcic7XG4gIHRoaXMuYWN0dWFsID0gb3B0aW9ucy5hY3R1YWw7XG4gIHRoaXMuZXhwZWN0ZWQgPSBvcHRpb25zLmV4cGVjdGVkO1xuICB0aGlzLm9wZXJhdG9yID0gb3B0aW9ucy5vcGVyYXRvcjtcbiAgaWYgKG9wdGlvbnMubWVzc2FnZSkge1xuICAgIHRoaXMubWVzc2FnZSA9IG9wdGlvbnMubWVzc2FnZTtcbiAgICB0aGlzLmdlbmVyYXRlZE1lc3NhZ2UgPSBmYWxzZTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLm1lc3NhZ2UgPSBnZXRNZXNzYWdlKHRoaXMpO1xuICAgIHRoaXMuZ2VuZXJhdGVkTWVzc2FnZSA9IHRydWU7XG4gIH1cbiAgdmFyIHN0YWNrU3RhcnRGdW5jdGlvbiA9IG9wdGlvbnMuc3RhY2tTdGFydEZ1bmN0aW9uIHx8IGZhaWw7XG4gIGlmIChFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSkge1xuICAgIEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKHRoaXMsIHN0YWNrU3RhcnRGdW5jdGlvbik7XG4gIH0gZWxzZSB7XG4gICAgLy8gbm9uIHY4IGJyb3dzZXJzIHNvIHdlIGNhbiBoYXZlIGEgc3RhY2t0cmFjZVxuICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoKTtcbiAgICBpZiAoZXJyLnN0YWNrKSB7XG4gICAgICB2YXIgb3V0ID0gZXJyLnN0YWNrO1xuXG4gICAgICAvLyB0cnkgdG8gc3RyaXAgdXNlbGVzcyBmcmFtZXNcbiAgICAgIHZhciBmbl9uYW1lID0gZ2V0TmFtZShzdGFja1N0YXJ0RnVuY3Rpb24pO1xuICAgICAgdmFyIGlkeCA9IG91dC5pbmRleE9mKCdcXG4nICsgZm5fbmFtZSk7XG4gICAgICBpZiAoaWR4ID49IDApIHtcbiAgICAgICAgLy8gb25jZSB3ZSBoYXZlIGxvY2F0ZWQgdGhlIGZ1bmN0aW9uIGZyYW1lXG4gICAgICAgIC8vIHdlIG5lZWQgdG8gc3RyaXAgb3V0IGV2ZXJ5dGhpbmcgYmVmb3JlIGl0IChhbmQgaXRzIGxpbmUpXG4gICAgICAgIHZhciBuZXh0X2xpbmUgPSBvdXQuaW5kZXhPZignXFxuJywgaWR4ICsgMSk7XG4gICAgICAgIG91dCA9IG91dC5zdWJzdHJpbmcobmV4dF9saW5lICsgMSk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuc3RhY2sgPSBvdXQ7XG4gICAgfVxuICB9XG59O1xuXG4vLyBhc3NlcnQuQXNzZXJ0aW9uRXJyb3IgaW5zdGFuY2VvZiBFcnJvclxudXRpbC5pbmhlcml0cyhhc3NlcnQuQXNzZXJ0aW9uRXJyb3IsIEVycm9yKTtcblxuZnVuY3Rpb24gdHJ1bmNhdGUocywgbikge1xuICBpZiAodHlwZW9mIHMgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIHMubGVuZ3RoIDwgbiA/IHMgOiBzLnNsaWNlKDAsIG4pO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBzO1xuICB9XG59XG5mdW5jdGlvbiBpbnNwZWN0KHNvbWV0aGluZykge1xuICBpZiAoZnVuY3Rpb25zSGF2ZU5hbWVzIHx8ICF1dGlsLmlzRnVuY3Rpb24oc29tZXRoaW5nKSkge1xuICAgIHJldHVybiB1dGlsLmluc3BlY3Qoc29tZXRoaW5nKTtcbiAgfVxuICB2YXIgcmF3bmFtZSA9IGdldE5hbWUoc29tZXRoaW5nKTtcbiAgdmFyIG5hbWUgPSByYXduYW1lID8gJzogJyArIHJhd25hbWUgOiAnJztcbiAgcmV0dXJuICdbRnVuY3Rpb24nICsgIG5hbWUgKyAnXSc7XG59XG5mdW5jdGlvbiBnZXRNZXNzYWdlKHNlbGYpIHtcbiAgcmV0dXJuIHRydW5jYXRlKGluc3BlY3Qoc2VsZi5hY3R1YWwpLCAxMjgpICsgJyAnICtcbiAgICAgICAgIHNlbGYub3BlcmF0b3IgKyAnICcgK1xuICAgICAgICAgdHJ1bmNhdGUoaW5zcGVjdChzZWxmLmV4cGVjdGVkKSwgMTI4KTtcbn1cblxuLy8gQXQgcHJlc2VudCBvbmx5IHRoZSB0aHJlZSBrZXlzIG1lbnRpb25lZCBhYm92ZSBhcmUgdXNlZCBhbmRcbi8vIHVuZGVyc3Rvb2QgYnkgdGhlIHNwZWMuIEltcGxlbWVudGF0aW9ucyBvciBzdWIgbW9kdWxlcyBjYW4gcGFzc1xuLy8gb3RoZXIga2V5cyB0byB0aGUgQXNzZXJ0aW9uRXJyb3IncyBjb25zdHJ1Y3RvciAtIHRoZXkgd2lsbCBiZVxuLy8gaWdub3JlZC5cblxuLy8gMy4gQWxsIG9mIHRoZSBmb2xsb3dpbmcgZnVuY3Rpb25zIG11c3QgdGhyb3cgYW4gQXNzZXJ0aW9uRXJyb3Jcbi8vIHdoZW4gYSBjb3JyZXNwb25kaW5nIGNvbmRpdGlvbiBpcyBub3QgbWV0LCB3aXRoIGEgbWVzc2FnZSB0aGF0XG4vLyBtYXkgYmUgdW5kZWZpbmVkIGlmIG5vdCBwcm92aWRlZC4gIEFsbCBhc3NlcnRpb24gbWV0aG9kcyBwcm92aWRlXG4vLyBib3RoIHRoZSBhY3R1YWwgYW5kIGV4cGVjdGVkIHZhbHVlcyB0byB0aGUgYXNzZXJ0aW9uIGVycm9yIGZvclxuLy8gZGlzcGxheSBwdXJwb3Nlcy5cblxuZnVuY3Rpb24gZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCBvcGVyYXRvciwgc3RhY2tTdGFydEZ1bmN0aW9uKSB7XG4gIHRocm93IG5ldyBhc3NlcnQuQXNzZXJ0aW9uRXJyb3Ioe1xuICAgIG1lc3NhZ2U6IG1lc3NhZ2UsXG4gICAgYWN0dWFsOiBhY3R1YWwsXG4gICAgZXhwZWN0ZWQ6IGV4cGVjdGVkLFxuICAgIG9wZXJhdG9yOiBvcGVyYXRvcixcbiAgICBzdGFja1N0YXJ0RnVuY3Rpb246IHN0YWNrU3RhcnRGdW5jdGlvblxuICB9KTtcbn1cblxuLy8gRVhURU5TSU9OISBhbGxvd3MgZm9yIHdlbGwgYmVoYXZlZCBlcnJvcnMgZGVmaW5lZCBlbHNld2hlcmUuXG5hc3NlcnQuZmFpbCA9IGZhaWw7XG5cbi8vIDQuIFB1cmUgYXNzZXJ0aW9uIHRlc3RzIHdoZXRoZXIgYSB2YWx1ZSBpcyB0cnV0aHksIGFzIGRldGVybWluZWRcbi8vIGJ5ICEhZ3VhcmQuXG4vLyBhc3NlcnQub2soZ3VhcmQsIG1lc3NhZ2Vfb3B0KTtcbi8vIFRoaXMgc3RhdGVtZW50IGlzIGVxdWl2YWxlbnQgdG8gYXNzZXJ0LmVxdWFsKHRydWUsICEhZ3VhcmQsXG4vLyBtZXNzYWdlX29wdCk7LiBUbyB0ZXN0IHN0cmljdGx5IGZvciB0aGUgdmFsdWUgdHJ1ZSwgdXNlXG4vLyBhc3NlcnQuc3RyaWN0RXF1YWwodHJ1ZSwgZ3VhcmQsIG1lc3NhZ2Vfb3B0KTsuXG5cbmZ1bmN0aW9uIG9rKHZhbHVlLCBtZXNzYWdlKSB7XG4gIGlmICghdmFsdWUpIGZhaWwodmFsdWUsIHRydWUsIG1lc3NhZ2UsICc9PScsIGFzc2VydC5vayk7XG59XG5hc3NlcnQub2sgPSBvaztcblxuLy8gNS4gVGhlIGVxdWFsaXR5IGFzc2VydGlvbiB0ZXN0cyBzaGFsbG93LCBjb2VyY2l2ZSBlcXVhbGl0eSB3aXRoXG4vLyA9PS5cbi8vIGFzc2VydC5lcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlX29wdCk7XG5cbmFzc2VydC5lcXVhbCA9IGZ1bmN0aW9uIGVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UpIHtcbiAgaWYgKGFjdHVhbCAhPSBleHBlY3RlZCkgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCAnPT0nLCBhc3NlcnQuZXF1YWwpO1xufTtcblxuLy8gNi4gVGhlIG5vbi1lcXVhbGl0eSBhc3NlcnRpb24gdGVzdHMgZm9yIHdoZXRoZXIgdHdvIG9iamVjdHMgYXJlIG5vdCBlcXVhbFxuLy8gd2l0aCAhPSBhc3NlcnQubm90RXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZV9vcHQpO1xuXG5hc3NlcnQubm90RXF1YWwgPSBmdW5jdGlvbiBub3RFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlKSB7XG4gIGlmIChhY3R1YWwgPT0gZXhwZWN0ZWQpIHtcbiAgICBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UsICchPScsIGFzc2VydC5ub3RFcXVhbCk7XG4gIH1cbn07XG5cbi8vIDcuIFRoZSBlcXVpdmFsZW5jZSBhc3NlcnRpb24gdGVzdHMgYSBkZWVwIGVxdWFsaXR5IHJlbGF0aW9uLlxuLy8gYXNzZXJ0LmRlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlX29wdCk7XG5cbmFzc2VydC5kZWVwRXF1YWwgPSBmdW5jdGlvbiBkZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuICBpZiAoIV9kZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgZmFsc2UpKSB7XG4gICAgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCAnZGVlcEVxdWFsJywgYXNzZXJ0LmRlZXBFcXVhbCk7XG4gIH1cbn07XG5cbmFzc2VydC5kZWVwU3RyaWN0RXF1YWwgPSBmdW5jdGlvbiBkZWVwU3RyaWN0RXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuICBpZiAoIV9kZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgdHJ1ZSkpIHtcbiAgICBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UsICdkZWVwU3RyaWN0RXF1YWwnLCBhc3NlcnQuZGVlcFN0cmljdEVxdWFsKTtcbiAgfVxufTtcblxuZnVuY3Rpb24gX2RlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBzdHJpY3QsIG1lbW9zKSB7XG4gIC8vIDcuMS4gQWxsIGlkZW50aWNhbCB2YWx1ZXMgYXJlIGVxdWl2YWxlbnQsIGFzIGRldGVybWluZWQgYnkgPT09LlxuICBpZiAoYWN0dWFsID09PSBleHBlY3RlZCkge1xuICAgIHJldHVybiB0cnVlO1xuICB9IGVsc2UgaWYgKGlzQnVmZmVyKGFjdHVhbCkgJiYgaXNCdWZmZXIoZXhwZWN0ZWQpKSB7XG4gICAgcmV0dXJuIGNvbXBhcmUoYWN0dWFsLCBleHBlY3RlZCkgPT09IDA7XG5cbiAgLy8gNy4yLiBJZiB0aGUgZXhwZWN0ZWQgdmFsdWUgaXMgYSBEYXRlIG9iamVjdCwgdGhlIGFjdHVhbCB2YWx1ZSBpc1xuICAvLyBlcXVpdmFsZW50IGlmIGl0IGlzIGFsc28gYSBEYXRlIG9iamVjdCB0aGF0IHJlZmVycyB0byB0aGUgc2FtZSB0aW1lLlxuICB9IGVsc2UgaWYgKHV0aWwuaXNEYXRlKGFjdHVhbCkgJiYgdXRpbC5pc0RhdGUoZXhwZWN0ZWQpKSB7XG4gICAgcmV0dXJuIGFjdHVhbC5nZXRUaW1lKCkgPT09IGV4cGVjdGVkLmdldFRpbWUoKTtcblxuICAvLyA3LjMgSWYgdGhlIGV4cGVjdGVkIHZhbHVlIGlzIGEgUmVnRXhwIG9iamVjdCwgdGhlIGFjdHVhbCB2YWx1ZSBpc1xuICAvLyBlcXVpdmFsZW50IGlmIGl0IGlzIGFsc28gYSBSZWdFeHAgb2JqZWN0IHdpdGggdGhlIHNhbWUgc291cmNlIGFuZFxuICAvLyBwcm9wZXJ0aWVzIChgZ2xvYmFsYCwgYG11bHRpbGluZWAsIGBsYXN0SW5kZXhgLCBgaWdub3JlQ2FzZWApLlxuICB9IGVsc2UgaWYgKHV0aWwuaXNSZWdFeHAoYWN0dWFsKSAmJiB1dGlsLmlzUmVnRXhwKGV4cGVjdGVkKSkge1xuICAgIHJldHVybiBhY3R1YWwuc291cmNlID09PSBleHBlY3RlZC5zb3VyY2UgJiZcbiAgICAgICAgICAgYWN0dWFsLmdsb2JhbCA9PT0gZXhwZWN0ZWQuZ2xvYmFsICYmXG4gICAgICAgICAgIGFjdHVhbC5tdWx0aWxpbmUgPT09IGV4cGVjdGVkLm11bHRpbGluZSAmJlxuICAgICAgICAgICBhY3R1YWwubGFzdEluZGV4ID09PSBleHBlY3RlZC5sYXN0SW5kZXggJiZcbiAgICAgICAgICAgYWN0dWFsLmlnbm9yZUNhc2UgPT09IGV4cGVjdGVkLmlnbm9yZUNhc2U7XG5cbiAgLy8gNy40LiBPdGhlciBwYWlycyB0aGF0IGRvIG5vdCBib3RoIHBhc3MgdHlwZW9mIHZhbHVlID09ICdvYmplY3QnLFxuICAvLyBlcXVpdmFsZW5jZSBpcyBkZXRlcm1pbmVkIGJ5ID09LlxuICB9IGVsc2UgaWYgKChhY3R1YWwgPT09IG51bGwgfHwgdHlwZW9mIGFjdHVhbCAhPT0gJ29iamVjdCcpICYmXG4gICAgICAgICAgICAgKGV4cGVjdGVkID09PSBudWxsIHx8IHR5cGVvZiBleHBlY3RlZCAhPT0gJ29iamVjdCcpKSB7XG4gICAgcmV0dXJuIHN0cmljdCA/IGFjdHVhbCA9PT0gZXhwZWN0ZWQgOiBhY3R1YWwgPT0gZXhwZWN0ZWQ7XG5cbiAgLy8gSWYgYm90aCB2YWx1ZXMgYXJlIGluc3RhbmNlcyBvZiB0eXBlZCBhcnJheXMsIHdyYXAgdGhlaXIgdW5kZXJseWluZ1xuICAvLyBBcnJheUJ1ZmZlcnMgaW4gYSBCdWZmZXIgZWFjaCB0byBpbmNyZWFzZSBwZXJmb3JtYW5jZVxuICAvLyBUaGlzIG9wdGltaXphdGlvbiByZXF1aXJlcyB0aGUgYXJyYXlzIHRvIGhhdmUgdGhlIHNhbWUgdHlwZSBhcyBjaGVja2VkIGJ5XG4gIC8vIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcgKGFrYSBwVG9TdHJpbmcpLiBOZXZlciBwZXJmb3JtIGJpbmFyeVxuICAvLyBjb21wYXJpc29ucyBmb3IgRmxvYXQqQXJyYXlzLCB0aG91Z2gsIHNpbmNlIGUuZy4gKzAgPT09IC0wIGJ1dCB0aGVpclxuICAvLyBiaXQgcGF0dGVybnMgYXJlIG5vdCBpZGVudGljYWwuXG4gIH0gZWxzZSBpZiAoaXNWaWV3KGFjdHVhbCkgJiYgaXNWaWV3KGV4cGVjdGVkKSAmJlxuICAgICAgICAgICAgIHBUb1N0cmluZyhhY3R1YWwpID09PSBwVG9TdHJpbmcoZXhwZWN0ZWQpICYmXG4gICAgICAgICAgICAgIShhY3R1YWwgaW5zdGFuY2VvZiBGbG9hdDMyQXJyYXkgfHxcbiAgICAgICAgICAgICAgIGFjdHVhbCBpbnN0YW5jZW9mIEZsb2F0NjRBcnJheSkpIHtcbiAgICByZXR1cm4gY29tcGFyZShuZXcgVWludDhBcnJheShhY3R1YWwuYnVmZmVyKSxcbiAgICAgICAgICAgICAgICAgICBuZXcgVWludDhBcnJheShleHBlY3RlZC5idWZmZXIpKSA9PT0gMDtcblxuICAvLyA3LjUgRm9yIGFsbCBvdGhlciBPYmplY3QgcGFpcnMsIGluY2x1ZGluZyBBcnJheSBvYmplY3RzLCBlcXVpdmFsZW5jZSBpc1xuICAvLyBkZXRlcm1pbmVkIGJ5IGhhdmluZyB0aGUgc2FtZSBudW1iZXIgb2Ygb3duZWQgcHJvcGVydGllcyAoYXMgdmVyaWZpZWRcbiAgLy8gd2l0aCBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwpLCB0aGUgc2FtZSBzZXQgb2Yga2V5c1xuICAvLyAoYWx0aG91Z2ggbm90IG5lY2Vzc2FyaWx5IHRoZSBzYW1lIG9yZGVyKSwgZXF1aXZhbGVudCB2YWx1ZXMgZm9yIGV2ZXJ5XG4gIC8vIGNvcnJlc3BvbmRpbmcga2V5LCBhbmQgYW4gaWRlbnRpY2FsICdwcm90b3R5cGUnIHByb3BlcnR5LiBOb3RlOiB0aGlzXG4gIC8vIGFjY291bnRzIGZvciBib3RoIG5hbWVkIGFuZCBpbmRleGVkIHByb3BlcnRpZXMgb24gQXJyYXlzLlxuICB9IGVsc2UgaWYgKGlzQnVmZmVyKGFjdHVhbCkgIT09IGlzQnVmZmVyKGV4cGVjdGVkKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfSBlbHNlIHtcbiAgICBtZW1vcyA9IG1lbW9zIHx8IHthY3R1YWw6IFtdLCBleHBlY3RlZDogW119O1xuXG4gICAgdmFyIGFjdHVhbEluZGV4ID0gbWVtb3MuYWN0dWFsLmluZGV4T2YoYWN0dWFsKTtcbiAgICBpZiAoYWN0dWFsSW5kZXggIT09IC0xKSB7XG4gICAgICBpZiAoYWN0dWFsSW5kZXggPT09IG1lbW9zLmV4cGVjdGVkLmluZGV4T2YoZXhwZWN0ZWQpKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIG1lbW9zLmFjdHVhbC5wdXNoKGFjdHVhbCk7XG4gICAgbWVtb3MuZXhwZWN0ZWQucHVzaChleHBlY3RlZCk7XG5cbiAgICByZXR1cm4gb2JqRXF1aXYoYWN0dWFsLCBleHBlY3RlZCwgc3RyaWN0LCBtZW1vcyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gaXNBcmd1bWVudHMob2JqZWN0KSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwob2JqZWN0KSA9PSAnW29iamVjdCBBcmd1bWVudHNdJztcbn1cblxuZnVuY3Rpb24gb2JqRXF1aXYoYSwgYiwgc3RyaWN0LCBhY3R1YWxWaXNpdGVkT2JqZWN0cykge1xuICBpZiAoYSA9PT0gbnVsbCB8fCBhID09PSB1bmRlZmluZWQgfHwgYiA9PT0gbnVsbCB8fCBiID09PSB1bmRlZmluZWQpXG4gICAgcmV0dXJuIGZhbHNlO1xuICAvLyBpZiBvbmUgaXMgYSBwcmltaXRpdmUsIHRoZSBvdGhlciBtdXN0IGJlIHNhbWVcbiAgaWYgKHV0aWwuaXNQcmltaXRpdmUoYSkgfHwgdXRpbC5pc1ByaW1pdGl2ZShiKSlcbiAgICByZXR1cm4gYSA9PT0gYjtcbiAgaWYgKHN0cmljdCAmJiBPYmplY3QuZ2V0UHJvdG90eXBlT2YoYSkgIT09IE9iamVjdC5nZXRQcm90b3R5cGVPZihiKSlcbiAgICByZXR1cm4gZmFsc2U7XG4gIHZhciBhSXNBcmdzID0gaXNBcmd1bWVudHMoYSk7XG4gIHZhciBiSXNBcmdzID0gaXNBcmd1bWVudHMoYik7XG4gIGlmICgoYUlzQXJncyAmJiAhYklzQXJncykgfHwgKCFhSXNBcmdzICYmIGJJc0FyZ3MpKVxuICAgIHJldHVybiBmYWxzZTtcbiAgaWYgKGFJc0FyZ3MpIHtcbiAgICBhID0gcFNsaWNlLmNhbGwoYSk7XG4gICAgYiA9IHBTbGljZS5jYWxsKGIpO1xuICAgIHJldHVybiBfZGVlcEVxdWFsKGEsIGIsIHN0cmljdCk7XG4gIH1cbiAgdmFyIGthID0gb2JqZWN0S2V5cyhhKTtcbiAgdmFyIGtiID0gb2JqZWN0S2V5cyhiKTtcbiAgdmFyIGtleSwgaTtcbiAgLy8gaGF2aW5nIHRoZSBzYW1lIG51bWJlciBvZiBvd25lZCBwcm9wZXJ0aWVzIChrZXlzIGluY29ycG9yYXRlc1xuICAvLyBoYXNPd25Qcm9wZXJ0eSlcbiAgaWYgKGthLmxlbmd0aCAhPT0ga2IubGVuZ3RoKVxuICAgIHJldHVybiBmYWxzZTtcbiAgLy90aGUgc2FtZSBzZXQgb2Yga2V5cyAoYWx0aG91Z2ggbm90IG5lY2Vzc2FyaWx5IHRoZSBzYW1lIG9yZGVyKSxcbiAga2Euc29ydCgpO1xuICBrYi5zb3J0KCk7XG4gIC8vfn5+Y2hlYXAga2V5IHRlc3RcbiAgZm9yIChpID0ga2EubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICBpZiAoa2FbaV0gIT09IGtiW2ldKVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIC8vZXF1aXZhbGVudCB2YWx1ZXMgZm9yIGV2ZXJ5IGNvcnJlc3BvbmRpbmcga2V5LCBhbmRcbiAgLy9+fn5wb3NzaWJseSBleHBlbnNpdmUgZGVlcCB0ZXN0XG4gIGZvciAoaSA9IGthLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAga2V5ID0ga2FbaV07XG4gICAgaWYgKCFfZGVlcEVxdWFsKGFba2V5XSwgYltrZXldLCBzdHJpY3QsIGFjdHVhbFZpc2l0ZWRPYmplY3RzKSlcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxuLy8gOC4gVGhlIG5vbi1lcXVpdmFsZW5jZSBhc3NlcnRpb24gdGVzdHMgZm9yIGFueSBkZWVwIGluZXF1YWxpdHkuXG4vLyBhc3NlcnQubm90RGVlcEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2Vfb3B0KTtcblxuYXNzZXJ0Lm5vdERlZXBFcXVhbCA9IGZ1bmN0aW9uIG5vdERlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlKSB7XG4gIGlmIChfZGVlcEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIGZhbHNlKSkge1xuICAgIGZhaWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSwgJ25vdERlZXBFcXVhbCcsIGFzc2VydC5ub3REZWVwRXF1YWwpO1xuICB9XG59O1xuXG5hc3NlcnQubm90RGVlcFN0cmljdEVxdWFsID0gbm90RGVlcFN0cmljdEVxdWFsO1xuZnVuY3Rpb24gbm90RGVlcFN0cmljdEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UpIHtcbiAgaWYgKF9kZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgdHJ1ZSkpIHtcbiAgICBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UsICdub3REZWVwU3RyaWN0RXF1YWwnLCBub3REZWVwU3RyaWN0RXF1YWwpO1xuICB9XG59XG5cblxuLy8gOS4gVGhlIHN0cmljdCBlcXVhbGl0eSBhc3NlcnRpb24gdGVzdHMgc3RyaWN0IGVxdWFsaXR5LCBhcyBkZXRlcm1pbmVkIGJ5ID09PS5cbi8vIGFzc2VydC5zdHJpY3RFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlX29wdCk7XG5cbmFzc2VydC5zdHJpY3RFcXVhbCA9IGZ1bmN0aW9uIHN0cmljdEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UpIHtcbiAgaWYgKGFjdHVhbCAhPT0gZXhwZWN0ZWQpIHtcbiAgICBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UsICc9PT0nLCBhc3NlcnQuc3RyaWN0RXF1YWwpO1xuICB9XG59O1xuXG4vLyAxMC4gVGhlIHN0cmljdCBub24tZXF1YWxpdHkgYXNzZXJ0aW9uIHRlc3RzIGZvciBzdHJpY3QgaW5lcXVhbGl0eSwgYXNcbi8vIGRldGVybWluZWQgYnkgIT09LiAgYXNzZXJ0Lm5vdFN0cmljdEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2Vfb3B0KTtcblxuYXNzZXJ0Lm5vdFN0cmljdEVxdWFsID0gZnVuY3Rpb24gbm90U3RyaWN0RXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuICBpZiAoYWN0dWFsID09PSBleHBlY3RlZCkge1xuICAgIGZhaWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSwgJyE9PScsIGFzc2VydC5ub3RTdHJpY3RFcXVhbCk7XG4gIH1cbn07XG5cbmZ1bmN0aW9uIGV4cGVjdGVkRXhjZXB0aW9uKGFjdHVhbCwgZXhwZWN0ZWQpIHtcbiAgaWYgKCFhY3R1YWwgfHwgIWV4cGVjdGVkKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaWYgKE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChleHBlY3RlZCkgPT0gJ1tvYmplY3QgUmVnRXhwXScpIHtcbiAgICByZXR1cm4gZXhwZWN0ZWQudGVzdChhY3R1YWwpO1xuICB9XG5cbiAgdHJ5IHtcbiAgICBpZiAoYWN0dWFsIGluc3RhbmNlb2YgZXhwZWN0ZWQpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfSBjYXRjaCAoZSkge1xuICAgIC8vIElnbm9yZS4gIFRoZSBpbnN0YW5jZW9mIGNoZWNrIGRvZXNuJ3Qgd29yayBmb3IgYXJyb3cgZnVuY3Rpb25zLlxuICB9XG5cbiAgaWYgKEVycm9yLmlzUHJvdG90eXBlT2YoZXhwZWN0ZWQpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcmV0dXJuIGV4cGVjdGVkLmNhbGwoe30sIGFjdHVhbCkgPT09IHRydWU7XG59XG5cbmZ1bmN0aW9uIF90cnlCbG9jayhibG9jaykge1xuICB2YXIgZXJyb3I7XG4gIHRyeSB7XG4gICAgYmxvY2soKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIGVycm9yID0gZTtcbiAgfVxuICByZXR1cm4gZXJyb3I7XG59XG5cbmZ1bmN0aW9uIF90aHJvd3Moc2hvdWxkVGhyb3csIGJsb2NrLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuICB2YXIgYWN0dWFsO1xuXG4gIGlmICh0eXBlb2YgYmxvY2sgIT09ICdmdW5jdGlvbicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImJsb2NrXCIgYXJndW1lbnQgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gIH1cblxuICBpZiAodHlwZW9mIGV4cGVjdGVkID09PSAnc3RyaW5nJykge1xuICAgIG1lc3NhZ2UgPSBleHBlY3RlZDtcbiAgICBleHBlY3RlZCA9IG51bGw7XG4gIH1cblxuICBhY3R1YWwgPSBfdHJ5QmxvY2soYmxvY2spO1xuXG4gIG1lc3NhZ2UgPSAoZXhwZWN0ZWQgJiYgZXhwZWN0ZWQubmFtZSA/ICcgKCcgKyBleHBlY3RlZC5uYW1lICsgJykuJyA6ICcuJykgK1xuICAgICAgICAgICAgKG1lc3NhZ2UgPyAnICcgKyBtZXNzYWdlIDogJy4nKTtcblxuICBpZiAoc2hvdWxkVGhyb3cgJiYgIWFjdHVhbCkge1xuICAgIGZhaWwoYWN0dWFsLCBleHBlY3RlZCwgJ01pc3NpbmcgZXhwZWN0ZWQgZXhjZXB0aW9uJyArIG1lc3NhZ2UpO1xuICB9XG5cbiAgdmFyIHVzZXJQcm92aWRlZE1lc3NhZ2UgPSB0eXBlb2YgbWVzc2FnZSA9PT0gJ3N0cmluZyc7XG4gIHZhciBpc1Vud2FudGVkRXhjZXB0aW9uID0gIXNob3VsZFRocm93ICYmIHV0aWwuaXNFcnJvcihhY3R1YWwpO1xuICB2YXIgaXNVbmV4cGVjdGVkRXhjZXB0aW9uID0gIXNob3VsZFRocm93ICYmIGFjdHVhbCAmJiAhZXhwZWN0ZWQ7XG5cbiAgaWYgKChpc1Vud2FudGVkRXhjZXB0aW9uICYmXG4gICAgICB1c2VyUHJvdmlkZWRNZXNzYWdlICYmXG4gICAgICBleHBlY3RlZEV4Y2VwdGlvbihhY3R1YWwsIGV4cGVjdGVkKSkgfHxcbiAgICAgIGlzVW5leHBlY3RlZEV4Y2VwdGlvbikge1xuICAgIGZhaWwoYWN0dWFsLCBleHBlY3RlZCwgJ0dvdCB1bndhbnRlZCBleGNlcHRpb24nICsgbWVzc2FnZSk7XG4gIH1cblxuICBpZiAoKHNob3VsZFRocm93ICYmIGFjdHVhbCAmJiBleHBlY3RlZCAmJlxuICAgICAgIWV4cGVjdGVkRXhjZXB0aW9uKGFjdHVhbCwgZXhwZWN0ZWQpKSB8fCAoIXNob3VsZFRocm93ICYmIGFjdHVhbCkpIHtcbiAgICB0aHJvdyBhY3R1YWw7XG4gIH1cbn1cblxuLy8gMTEuIEV4cGVjdGVkIHRvIHRocm93IGFuIGVycm9yOlxuLy8gYXNzZXJ0LnRocm93cyhibG9jaywgRXJyb3Jfb3B0LCBtZXNzYWdlX29wdCk7XG5cbmFzc2VydC50aHJvd3MgPSBmdW5jdGlvbihibG9jaywgLypvcHRpb25hbCovZXJyb3IsIC8qb3B0aW9uYWwqL21lc3NhZ2UpIHtcbiAgX3Rocm93cyh0cnVlLCBibG9jaywgZXJyb3IsIG1lc3NhZ2UpO1xufTtcblxuLy8gRVhURU5TSU9OISBUaGlzIGlzIGFubm95aW5nIHRvIHdyaXRlIG91dHNpZGUgdGhpcyBtb2R1bGUuXG5hc3NlcnQuZG9lc05vdFRocm93ID0gZnVuY3Rpb24oYmxvY2ssIC8qb3B0aW9uYWwqL2Vycm9yLCAvKm9wdGlvbmFsKi9tZXNzYWdlKSB7XG4gIF90aHJvd3MoZmFsc2UsIGJsb2NrLCBlcnJvciwgbWVzc2FnZSk7XG59O1xuXG5hc3NlcnQuaWZFcnJvciA9IGZ1bmN0aW9uKGVycikgeyBpZiAoZXJyKSB0aHJvdyBlcnI7IH07XG5cbi8vIEV4cG9zZSBhIHN0cmljdCBvbmx5IHZhcmlhbnQgb2YgYXNzZXJ0XG5mdW5jdGlvbiBzdHJpY3QodmFsdWUsIG1lc3NhZ2UpIHtcbiAgaWYgKCF2YWx1ZSkgZmFpbCh2YWx1ZSwgdHJ1ZSwgbWVzc2FnZSwgJz09Jywgc3RyaWN0KTtcbn1cbmFzc2VydC5zdHJpY3QgPSBvYmplY3RBc3NpZ24oc3RyaWN0LCBhc3NlcnQsIHtcbiAgZXF1YWw6IGFzc2VydC5zdHJpY3RFcXVhbCxcbiAgZGVlcEVxdWFsOiBhc3NlcnQuZGVlcFN0cmljdEVxdWFsLFxuICBub3RFcXVhbDogYXNzZXJ0Lm5vdFN0cmljdEVxdWFsLFxuICBub3REZWVwRXF1YWw6IGFzc2VydC5ub3REZWVwU3RyaWN0RXF1YWxcbn0pO1xuYXNzZXJ0LnN0cmljdC5zdHJpY3QgPSBhc3NlcnQuc3RyaWN0O1xuXG52YXIgb2JqZWN0S2V5cyA9IE9iamVjdC5rZXlzIHx8IGZ1bmN0aW9uIChvYmopIHtcbiAgdmFyIGtleXMgPSBbXTtcbiAgZm9yICh2YXIga2V5IGluIG9iaikge1xuICAgIGlmIChoYXNPd24uY2FsbChvYmosIGtleSkpIGtleXMucHVzaChrZXkpO1xuICB9XG4gIHJldHVybiBrZXlzO1xufTtcbiIsImlmICh0eXBlb2YgT2JqZWN0LmNyZWF0ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAvLyBpbXBsZW1lbnRhdGlvbiBmcm9tIHN0YW5kYXJkIG5vZGUuanMgJ3V0aWwnIG1vZHVsZVxuICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGluaGVyaXRzKGN0b3IsIHN1cGVyQ3Rvcikge1xuICAgIGN0b3Iuc3VwZXJfID0gc3VwZXJDdG9yXG4gICAgY3Rvci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ3Rvci5wcm90b3R5cGUsIHtcbiAgICAgIGNvbnN0cnVjdG9yOiB7XG4gICAgICAgIHZhbHVlOiBjdG9yLFxuICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgICAgfVxuICAgIH0pO1xuICB9O1xufSBlbHNlIHtcbiAgLy8gb2xkIHNjaG9vbCBzaGltIGZvciBvbGQgYnJvd3NlcnNcbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpbmhlcml0cyhjdG9yLCBzdXBlckN0b3IpIHtcbiAgICBjdG9yLnN1cGVyXyA9IHN1cGVyQ3RvclxuICAgIHZhciBUZW1wQ3RvciA9IGZ1bmN0aW9uICgpIHt9XG4gICAgVGVtcEN0b3IucHJvdG90eXBlID0gc3VwZXJDdG9yLnByb3RvdHlwZVxuICAgIGN0b3IucHJvdG90eXBlID0gbmV3IFRlbXBDdG9yKClcbiAgICBjdG9yLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IGN0b3JcbiAgfVxufVxuIiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpc0J1ZmZlcihhcmcpIHtcbiAgcmV0dXJuIGFyZyAmJiB0eXBlb2YgYXJnID09PSAnb2JqZWN0J1xuICAgICYmIHR5cGVvZiBhcmcuY29weSA9PT0gJ2Z1bmN0aW9uJ1xuICAgICYmIHR5cGVvZiBhcmcuZmlsbCA9PT0gJ2Z1bmN0aW9uJ1xuICAgICYmIHR5cGVvZiBhcmcucmVhZFVJbnQ4ID09PSAnZnVuY3Rpb24nO1xufSIsIi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG52YXIgZm9ybWF0UmVnRXhwID0gLyVbc2RqJV0vZztcbmV4cG9ydHMuZm9ybWF0ID0gZnVuY3Rpb24oZikge1xuICBpZiAoIWlzU3RyaW5nKGYpKSB7XG4gICAgdmFyIG9iamVjdHMgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgb2JqZWN0cy5wdXNoKGluc3BlY3QoYXJndW1lbnRzW2ldKSk7XG4gICAgfVxuICAgIHJldHVybiBvYmplY3RzLmpvaW4oJyAnKTtcbiAgfVxuXG4gIHZhciBpID0gMTtcbiAgdmFyIGFyZ3MgPSBhcmd1bWVudHM7XG4gIHZhciBsZW4gPSBhcmdzLmxlbmd0aDtcbiAgdmFyIHN0ciA9IFN0cmluZyhmKS5yZXBsYWNlKGZvcm1hdFJlZ0V4cCwgZnVuY3Rpb24oeCkge1xuICAgIGlmICh4ID09PSAnJSUnKSByZXR1cm4gJyUnO1xuICAgIGlmIChpID49IGxlbikgcmV0dXJuIHg7XG4gICAgc3dpdGNoICh4KSB7XG4gICAgICBjYXNlICclcyc6IHJldHVybiBTdHJpbmcoYXJnc1tpKytdKTtcbiAgICAgIGNhc2UgJyVkJzogcmV0dXJuIE51bWJlcihhcmdzW2krK10pO1xuICAgICAgY2FzZSAnJWonOlxuICAgICAgICB0cnkge1xuICAgICAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShhcmdzW2krK10pO1xuICAgICAgICB9IGNhdGNoIChfKSB7XG4gICAgICAgICAgcmV0dXJuICdbQ2lyY3VsYXJdJztcbiAgICAgICAgfVxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIHg7XG4gICAgfVxuICB9KTtcbiAgZm9yICh2YXIgeCA9IGFyZ3NbaV07IGkgPCBsZW47IHggPSBhcmdzWysraV0pIHtcbiAgICBpZiAoaXNOdWxsKHgpIHx8ICFpc09iamVjdCh4KSkge1xuICAgICAgc3RyICs9ICcgJyArIHg7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0ciArPSAnICcgKyBpbnNwZWN0KHgpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gc3RyO1xufTtcblxuXG4vLyBNYXJrIHRoYXQgYSBtZXRob2Qgc2hvdWxkIG5vdCBiZSB1c2VkLlxuLy8gUmV0dXJucyBhIG1vZGlmaWVkIGZ1bmN0aW9uIHdoaWNoIHdhcm5zIG9uY2UgYnkgZGVmYXVsdC5cbi8vIElmIC0tbm8tZGVwcmVjYXRpb24gaXMgc2V0LCB0aGVuIGl0IGlzIGEgbm8tb3AuXG5leHBvcnRzLmRlcHJlY2F0ZSA9IGZ1bmN0aW9uKGZuLCBtc2cpIHtcbiAgLy8gQWxsb3cgZm9yIGRlcHJlY2F0aW5nIHRoaW5ncyBpbiB0aGUgcHJvY2VzcyBvZiBzdGFydGluZyB1cC5cbiAgaWYgKGlzVW5kZWZpbmVkKGdsb2JhbC5wcm9jZXNzKSkge1xuICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBleHBvcnRzLmRlcHJlY2F0ZShmbiwgbXNnKS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH07XG4gIH1cblxuICBpZiAocHJvY2Vzcy5ub0RlcHJlY2F0aW9uID09PSB0cnVlKSB7XG4gICAgcmV0dXJuIGZuO1xuICB9XG5cbiAgdmFyIHdhcm5lZCA9IGZhbHNlO1xuICBmdW5jdGlvbiBkZXByZWNhdGVkKCkge1xuICAgIGlmICghd2FybmVkKSB7XG4gICAgICBpZiAocHJvY2Vzcy50aHJvd0RlcHJlY2F0aW9uKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihtc2cpO1xuICAgICAgfSBlbHNlIGlmIChwcm9jZXNzLnRyYWNlRGVwcmVjYXRpb24pIHtcbiAgICAgICAgY29uc29sZS50cmFjZShtc2cpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihtc2cpO1xuICAgICAgfVxuICAgICAgd2FybmVkID0gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gIH1cblxuICByZXR1cm4gZGVwcmVjYXRlZDtcbn07XG5cblxudmFyIGRlYnVncyA9IHt9O1xudmFyIGRlYnVnRW52aXJvbjtcbmV4cG9ydHMuZGVidWdsb2cgPSBmdW5jdGlvbihzZXQpIHtcbiAgaWYgKGlzVW5kZWZpbmVkKGRlYnVnRW52aXJvbikpXG4gICAgZGVidWdFbnZpcm9uID0gcHJvY2Vzcy5lbnYuTk9ERV9ERUJVRyB8fCAnJztcbiAgc2V0ID0gc2V0LnRvVXBwZXJDYXNlKCk7XG4gIGlmICghZGVidWdzW3NldF0pIHtcbiAgICBpZiAobmV3IFJlZ0V4cCgnXFxcXGInICsgc2V0ICsgJ1xcXFxiJywgJ2knKS50ZXN0KGRlYnVnRW52aXJvbikpIHtcbiAgICAgIHZhciBwaWQgPSBwcm9jZXNzLnBpZDtcbiAgICAgIGRlYnVnc1tzZXRdID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBtc2cgPSBleHBvcnRzLmZvcm1hdC5hcHBseShleHBvcnRzLCBhcmd1bWVudHMpO1xuICAgICAgICBjb25zb2xlLmVycm9yKCclcyAlZDogJXMnLCBzZXQsIHBpZCwgbXNnKTtcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIGRlYnVnc1tzZXRdID0gZnVuY3Rpb24oKSB7fTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGRlYnVnc1tzZXRdO1xufTtcblxuXG4vKipcbiAqIEVjaG9zIHRoZSB2YWx1ZSBvZiBhIHZhbHVlLiBUcnlzIHRvIHByaW50IHRoZSB2YWx1ZSBvdXRcbiAqIGluIHRoZSBiZXN0IHdheSBwb3NzaWJsZSBnaXZlbiB0aGUgZGlmZmVyZW50IHR5cGVzLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmogVGhlIG9iamVjdCB0byBwcmludCBvdXQuXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0cyBPcHRpb25hbCBvcHRpb25zIG9iamVjdCB0aGF0IGFsdGVycyB0aGUgb3V0cHV0LlxuICovXG4vKiBsZWdhY3k6IG9iaiwgc2hvd0hpZGRlbiwgZGVwdGgsIGNvbG9ycyovXG5mdW5jdGlvbiBpbnNwZWN0KG9iaiwgb3B0cykge1xuICAvLyBkZWZhdWx0IG9wdGlvbnNcbiAgdmFyIGN0eCA9IHtcbiAgICBzZWVuOiBbXSxcbiAgICBzdHlsaXplOiBzdHlsaXplTm9Db2xvclxuICB9O1xuICAvLyBsZWdhY3kuLi5cbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPj0gMykgY3R4LmRlcHRoID0gYXJndW1lbnRzWzJdO1xuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+PSA0KSBjdHguY29sb3JzID0gYXJndW1lbnRzWzNdO1xuICBpZiAoaXNCb29sZWFuKG9wdHMpKSB7XG4gICAgLy8gbGVnYWN5Li4uXG4gICAgY3R4LnNob3dIaWRkZW4gPSBvcHRzO1xuICB9IGVsc2UgaWYgKG9wdHMpIHtcbiAgICAvLyBnb3QgYW4gXCJvcHRpb25zXCIgb2JqZWN0XG4gICAgZXhwb3J0cy5fZXh0ZW5kKGN0eCwgb3B0cyk7XG4gIH1cbiAgLy8gc2V0IGRlZmF1bHQgb3B0aW9uc1xuICBpZiAoaXNVbmRlZmluZWQoY3R4LnNob3dIaWRkZW4pKSBjdHguc2hvd0hpZGRlbiA9IGZhbHNlO1xuICBpZiAoaXNVbmRlZmluZWQoY3R4LmRlcHRoKSkgY3R4LmRlcHRoID0gMjtcbiAgaWYgKGlzVW5kZWZpbmVkKGN0eC5jb2xvcnMpKSBjdHguY29sb3JzID0gZmFsc2U7XG4gIGlmIChpc1VuZGVmaW5lZChjdHguY3VzdG9tSW5zcGVjdCkpIGN0eC5jdXN0b21JbnNwZWN0ID0gdHJ1ZTtcbiAgaWYgKGN0eC5jb2xvcnMpIGN0eC5zdHlsaXplID0gc3R5bGl6ZVdpdGhDb2xvcjtcbiAgcmV0dXJuIGZvcm1hdFZhbHVlKGN0eCwgb2JqLCBjdHguZGVwdGgpO1xufVxuZXhwb3J0cy5pbnNwZWN0ID0gaW5zcGVjdDtcblxuXG4vLyBodHRwOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0FOU0lfZXNjYXBlX2NvZGUjZ3JhcGhpY3Ncbmluc3BlY3QuY29sb3JzID0ge1xuICAnYm9sZCcgOiBbMSwgMjJdLFxuICAnaXRhbGljJyA6IFszLCAyM10sXG4gICd1bmRlcmxpbmUnIDogWzQsIDI0XSxcbiAgJ2ludmVyc2UnIDogWzcsIDI3XSxcbiAgJ3doaXRlJyA6IFszNywgMzldLFxuICAnZ3JleScgOiBbOTAsIDM5XSxcbiAgJ2JsYWNrJyA6IFszMCwgMzldLFxuICAnYmx1ZScgOiBbMzQsIDM5XSxcbiAgJ2N5YW4nIDogWzM2LCAzOV0sXG4gICdncmVlbicgOiBbMzIsIDM5XSxcbiAgJ21hZ2VudGEnIDogWzM1LCAzOV0sXG4gICdyZWQnIDogWzMxLCAzOV0sXG4gICd5ZWxsb3cnIDogWzMzLCAzOV1cbn07XG5cbi8vIERvbid0IHVzZSAnYmx1ZScgbm90IHZpc2libGUgb24gY21kLmV4ZVxuaW5zcGVjdC5zdHlsZXMgPSB7XG4gICdzcGVjaWFsJzogJ2N5YW4nLFxuICAnbnVtYmVyJzogJ3llbGxvdycsXG4gICdib29sZWFuJzogJ3llbGxvdycsXG4gICd1bmRlZmluZWQnOiAnZ3JleScsXG4gICdudWxsJzogJ2JvbGQnLFxuICAnc3RyaW5nJzogJ2dyZWVuJyxcbiAgJ2RhdGUnOiAnbWFnZW50YScsXG4gIC8vIFwibmFtZVwiOiBpbnRlbnRpb25hbGx5IG5vdCBzdHlsaW5nXG4gICdyZWdleHAnOiAncmVkJ1xufTtcblxuXG5mdW5jdGlvbiBzdHlsaXplV2l0aENvbG9yKHN0ciwgc3R5bGVUeXBlKSB7XG4gIHZhciBzdHlsZSA9IGluc3BlY3Quc3R5bGVzW3N0eWxlVHlwZV07XG5cbiAgaWYgKHN0eWxlKSB7XG4gICAgcmV0dXJuICdcXHUwMDFiWycgKyBpbnNwZWN0LmNvbG9yc1tzdHlsZV1bMF0gKyAnbScgKyBzdHIgK1xuICAgICAgICAgICAnXFx1MDAxYlsnICsgaW5zcGVjdC5jb2xvcnNbc3R5bGVdWzFdICsgJ20nO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBzdHI7XG4gIH1cbn1cblxuXG5mdW5jdGlvbiBzdHlsaXplTm9Db2xvcihzdHIsIHN0eWxlVHlwZSkge1xuICByZXR1cm4gc3RyO1xufVxuXG5cbmZ1bmN0aW9uIGFycmF5VG9IYXNoKGFycmF5KSB7XG4gIHZhciBoYXNoID0ge307XG5cbiAgYXJyYXkuZm9yRWFjaChmdW5jdGlvbih2YWwsIGlkeCkge1xuICAgIGhhc2hbdmFsXSA9IHRydWU7XG4gIH0pO1xuXG4gIHJldHVybiBoYXNoO1xufVxuXG5cbmZ1bmN0aW9uIGZvcm1hdFZhbHVlKGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcykge1xuICAvLyBQcm92aWRlIGEgaG9vayBmb3IgdXNlci1zcGVjaWZpZWQgaW5zcGVjdCBmdW5jdGlvbnMuXG4gIC8vIENoZWNrIHRoYXQgdmFsdWUgaXMgYW4gb2JqZWN0IHdpdGggYW4gaW5zcGVjdCBmdW5jdGlvbiBvbiBpdFxuICBpZiAoY3R4LmN1c3RvbUluc3BlY3QgJiZcbiAgICAgIHZhbHVlICYmXG4gICAgICBpc0Z1bmN0aW9uKHZhbHVlLmluc3BlY3QpICYmXG4gICAgICAvLyBGaWx0ZXIgb3V0IHRoZSB1dGlsIG1vZHVsZSwgaXQncyBpbnNwZWN0IGZ1bmN0aW9uIGlzIHNwZWNpYWxcbiAgICAgIHZhbHVlLmluc3BlY3QgIT09IGV4cG9ydHMuaW5zcGVjdCAmJlxuICAgICAgLy8gQWxzbyBmaWx0ZXIgb3V0IGFueSBwcm90b3R5cGUgb2JqZWN0cyB1c2luZyB0aGUgY2lyY3VsYXIgY2hlY2suXG4gICAgICAhKHZhbHVlLmNvbnN0cnVjdG9yICYmIHZhbHVlLmNvbnN0cnVjdG9yLnByb3RvdHlwZSA9PT0gdmFsdWUpKSB7XG4gICAgdmFyIHJldCA9IHZhbHVlLmluc3BlY3QocmVjdXJzZVRpbWVzLCBjdHgpO1xuICAgIGlmICghaXNTdHJpbmcocmV0KSkge1xuICAgICAgcmV0ID0gZm9ybWF0VmFsdWUoY3R4LCByZXQsIHJlY3Vyc2VUaW1lcyk7XG4gICAgfVxuICAgIHJldHVybiByZXQ7XG4gIH1cblxuICAvLyBQcmltaXRpdmUgdHlwZXMgY2Fubm90IGhhdmUgcHJvcGVydGllc1xuICB2YXIgcHJpbWl0aXZlID0gZm9ybWF0UHJpbWl0aXZlKGN0eCwgdmFsdWUpO1xuICBpZiAocHJpbWl0aXZlKSB7XG4gICAgcmV0dXJuIHByaW1pdGl2ZTtcbiAgfVxuXG4gIC8vIExvb2sgdXAgdGhlIGtleXMgb2YgdGhlIG9iamVjdC5cbiAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyh2YWx1ZSk7XG4gIHZhciB2aXNpYmxlS2V5cyA9IGFycmF5VG9IYXNoKGtleXMpO1xuXG4gIGlmIChjdHguc2hvd0hpZGRlbikge1xuICAgIGtleXMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh2YWx1ZSk7XG4gIH1cblxuICAvLyBJRSBkb2Vzbid0IG1ha2UgZXJyb3IgZmllbGRzIG5vbi1lbnVtZXJhYmxlXG4gIC8vIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9pZS9kd3c1MnNidCh2PXZzLjk0KS5hc3B4XG4gIGlmIChpc0Vycm9yKHZhbHVlKVxuICAgICAgJiYgKGtleXMuaW5kZXhPZignbWVzc2FnZScpID49IDAgfHwga2V5cy5pbmRleE9mKCdkZXNjcmlwdGlvbicpID49IDApKSB7XG4gICAgcmV0dXJuIGZvcm1hdEVycm9yKHZhbHVlKTtcbiAgfVxuXG4gIC8vIFNvbWUgdHlwZSBvZiBvYmplY3Qgd2l0aG91dCBwcm9wZXJ0aWVzIGNhbiBiZSBzaG9ydGN1dHRlZC5cbiAgaWYgKGtleXMubGVuZ3RoID09PSAwKSB7XG4gICAgaWYgKGlzRnVuY3Rpb24odmFsdWUpKSB7XG4gICAgICB2YXIgbmFtZSA9IHZhbHVlLm5hbWUgPyAnOiAnICsgdmFsdWUubmFtZSA6ICcnO1xuICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKCdbRnVuY3Rpb24nICsgbmFtZSArICddJywgJ3NwZWNpYWwnKTtcbiAgICB9XG4gICAgaWYgKGlzUmVnRXhwKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKFJlZ0V4cC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSksICdyZWdleHAnKTtcbiAgICB9XG4gICAgaWYgKGlzRGF0ZSh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBjdHguc3R5bGl6ZShEYXRlLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKSwgJ2RhdGUnKTtcbiAgICB9XG4gICAgaWYgKGlzRXJyb3IodmFsdWUpKSB7XG4gICAgICByZXR1cm4gZm9ybWF0RXJyb3IodmFsdWUpO1xuICAgIH1cbiAgfVxuXG4gIHZhciBiYXNlID0gJycsIGFycmF5ID0gZmFsc2UsIGJyYWNlcyA9IFsneycsICd9J107XG5cbiAgLy8gTWFrZSBBcnJheSBzYXkgdGhhdCB0aGV5IGFyZSBBcnJheVxuICBpZiAoaXNBcnJheSh2YWx1ZSkpIHtcbiAgICBhcnJheSA9IHRydWU7XG4gICAgYnJhY2VzID0gWydbJywgJ10nXTtcbiAgfVxuXG4gIC8vIE1ha2UgZnVuY3Rpb25zIHNheSB0aGF0IHRoZXkgYXJlIGZ1bmN0aW9uc1xuICBpZiAoaXNGdW5jdGlvbih2YWx1ZSkpIHtcbiAgICB2YXIgbiA9IHZhbHVlLm5hbWUgPyAnOiAnICsgdmFsdWUubmFtZSA6ICcnO1xuICAgIGJhc2UgPSAnIFtGdW5jdGlvbicgKyBuICsgJ10nO1xuICB9XG5cbiAgLy8gTWFrZSBSZWdFeHBzIHNheSB0aGF0IHRoZXkgYXJlIFJlZ0V4cHNcbiAgaWYgKGlzUmVnRXhwKHZhbHVlKSkge1xuICAgIGJhc2UgPSAnICcgKyBSZWdFeHAucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpO1xuICB9XG5cbiAgLy8gTWFrZSBkYXRlcyB3aXRoIHByb3BlcnRpZXMgZmlyc3Qgc2F5IHRoZSBkYXRlXG4gIGlmIChpc0RhdGUodmFsdWUpKSB7XG4gICAgYmFzZSA9ICcgJyArIERhdGUucHJvdG90eXBlLnRvVVRDU3RyaW5nLmNhbGwodmFsdWUpO1xuICB9XG5cbiAgLy8gTWFrZSBlcnJvciB3aXRoIG1lc3NhZ2UgZmlyc3Qgc2F5IHRoZSBlcnJvclxuICBpZiAoaXNFcnJvcih2YWx1ZSkpIHtcbiAgICBiYXNlID0gJyAnICsgZm9ybWF0RXJyb3IodmFsdWUpO1xuICB9XG5cbiAgaWYgKGtleXMubGVuZ3RoID09PSAwICYmICghYXJyYXkgfHwgdmFsdWUubGVuZ3RoID09IDApKSB7XG4gICAgcmV0dXJuIGJyYWNlc1swXSArIGJhc2UgKyBicmFjZXNbMV07XG4gIH1cblxuICBpZiAocmVjdXJzZVRpbWVzIDwgMCkge1xuICAgIGlmIChpc1JlZ0V4cCh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBjdHguc3R5bGl6ZShSZWdFeHAucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpLCAncmVnZXhwJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBjdHguc3R5bGl6ZSgnW09iamVjdF0nLCAnc3BlY2lhbCcpO1xuICAgIH1cbiAgfVxuXG4gIGN0eC5zZWVuLnB1c2godmFsdWUpO1xuXG4gIHZhciBvdXRwdXQ7XG4gIGlmIChhcnJheSkge1xuICAgIG91dHB1dCA9IGZvcm1hdEFycmF5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsIGtleXMpO1xuICB9IGVsc2Uge1xuICAgIG91dHB1dCA9IGtleXMubWFwKGZ1bmN0aW9uKGtleSkge1xuICAgICAgcmV0dXJuIGZvcm1hdFByb3BlcnR5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsIGtleSwgYXJyYXkpO1xuICAgIH0pO1xuICB9XG5cbiAgY3R4LnNlZW4ucG9wKCk7XG5cbiAgcmV0dXJuIHJlZHVjZVRvU2luZ2xlU3RyaW5nKG91dHB1dCwgYmFzZSwgYnJhY2VzKTtcbn1cblxuXG5mdW5jdGlvbiBmb3JtYXRQcmltaXRpdmUoY3R4LCB2YWx1ZSkge1xuICBpZiAoaXNVbmRlZmluZWQodmFsdWUpKVxuICAgIHJldHVybiBjdHguc3R5bGl6ZSgndW5kZWZpbmVkJywgJ3VuZGVmaW5lZCcpO1xuICBpZiAoaXNTdHJpbmcodmFsdWUpKSB7XG4gICAgdmFyIHNpbXBsZSA9ICdcXCcnICsgSlNPTi5zdHJpbmdpZnkodmFsdWUpLnJlcGxhY2UoL15cInxcIiQvZywgJycpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAucmVwbGFjZSgvJy9nLCBcIlxcXFwnXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAucmVwbGFjZSgvXFxcXFwiL2csICdcIicpICsgJ1xcJyc7XG4gICAgcmV0dXJuIGN0eC5zdHlsaXplKHNpbXBsZSwgJ3N0cmluZycpO1xuICB9XG4gIGlmIChpc051bWJlcih2YWx1ZSkpXG4gICAgcmV0dXJuIGN0eC5zdHlsaXplKCcnICsgdmFsdWUsICdudW1iZXInKTtcbiAgaWYgKGlzQm9vbGVhbih2YWx1ZSkpXG4gICAgcmV0dXJuIGN0eC5zdHlsaXplKCcnICsgdmFsdWUsICdib29sZWFuJyk7XG4gIC8vIEZvciBzb21lIHJlYXNvbiB0eXBlb2YgbnVsbCBpcyBcIm9iamVjdFwiLCBzbyBzcGVjaWFsIGNhc2UgaGVyZS5cbiAgaWYgKGlzTnVsbCh2YWx1ZSkpXG4gICAgcmV0dXJuIGN0eC5zdHlsaXplKCdudWxsJywgJ251bGwnKTtcbn1cblxuXG5mdW5jdGlvbiBmb3JtYXRFcnJvcih2YWx1ZSkge1xuICByZXR1cm4gJ1snICsgRXJyb3IucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpICsgJ10nO1xufVxuXG5cbmZ1bmN0aW9uIGZvcm1hdEFycmF5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsIGtleXMpIHtcbiAgdmFyIG91dHB1dCA9IFtdO1xuICBmb3IgKHZhciBpID0gMCwgbCA9IHZhbHVlLmxlbmd0aDsgaSA8IGw7ICsraSkge1xuICAgIGlmIChoYXNPd25Qcm9wZXJ0eSh2YWx1ZSwgU3RyaW5nKGkpKSkge1xuICAgICAgb3V0cHV0LnB1c2goZm9ybWF0UHJvcGVydHkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cyxcbiAgICAgICAgICBTdHJpbmcoaSksIHRydWUpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgb3V0cHV0LnB1c2goJycpO1xuICAgIH1cbiAgfVxuICBrZXlzLmZvckVhY2goZnVuY3Rpb24oa2V5KSB7XG4gICAgaWYgKCFrZXkubWF0Y2goL15cXGQrJC8pKSB7XG4gICAgICBvdXRwdXQucHVzaChmb3JtYXRQcm9wZXJ0eShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLFxuICAgICAgICAgIGtleSwgdHJ1ZSkpO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiBvdXRwdXQ7XG59XG5cblxuZnVuY3Rpb24gZm9ybWF0UHJvcGVydHkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cywga2V5LCBhcnJheSkge1xuICB2YXIgbmFtZSwgc3RyLCBkZXNjO1xuICBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih2YWx1ZSwga2V5KSB8fCB7IHZhbHVlOiB2YWx1ZVtrZXldIH07XG4gIGlmIChkZXNjLmdldCkge1xuICAgIGlmIChkZXNjLnNldCkge1xuICAgICAgc3RyID0gY3R4LnN0eWxpemUoJ1tHZXR0ZXIvU2V0dGVyXScsICdzcGVjaWFsJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0ciA9IGN0eC5zdHlsaXplKCdbR2V0dGVyXScsICdzcGVjaWFsJyk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGlmIChkZXNjLnNldCkge1xuICAgICAgc3RyID0gY3R4LnN0eWxpemUoJ1tTZXR0ZXJdJywgJ3NwZWNpYWwnKTtcbiAgICB9XG4gIH1cbiAgaWYgKCFoYXNPd25Qcm9wZXJ0eSh2aXNpYmxlS2V5cywga2V5KSkge1xuICAgIG5hbWUgPSAnWycgKyBrZXkgKyAnXSc7XG4gIH1cbiAgaWYgKCFzdHIpIHtcbiAgICBpZiAoY3R4LnNlZW4uaW5kZXhPZihkZXNjLnZhbHVlKSA8IDApIHtcbiAgICAgIGlmIChpc051bGwocmVjdXJzZVRpbWVzKSkge1xuICAgICAgICBzdHIgPSBmb3JtYXRWYWx1ZShjdHgsIGRlc2MudmFsdWUsIG51bGwpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3RyID0gZm9ybWF0VmFsdWUoY3R4LCBkZXNjLnZhbHVlLCByZWN1cnNlVGltZXMgLSAxKTtcbiAgICAgIH1cbiAgICAgIGlmIChzdHIuaW5kZXhPZignXFxuJykgPiAtMSkge1xuICAgICAgICBpZiAoYXJyYXkpIHtcbiAgICAgICAgICBzdHIgPSBzdHIuc3BsaXQoJ1xcbicpLm1hcChmdW5jdGlvbihsaW5lKSB7XG4gICAgICAgICAgICByZXR1cm4gJyAgJyArIGxpbmU7XG4gICAgICAgICAgfSkuam9pbignXFxuJykuc3Vic3RyKDIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHN0ciA9ICdcXG4nICsgc3RyLnNwbGl0KCdcXG4nKS5tYXAoZnVuY3Rpb24obGluZSkge1xuICAgICAgICAgICAgcmV0dXJuICcgICAnICsgbGluZTtcbiAgICAgICAgICB9KS5qb2luKCdcXG4nKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBzdHIgPSBjdHguc3R5bGl6ZSgnW0NpcmN1bGFyXScsICdzcGVjaWFsJyk7XG4gICAgfVxuICB9XG4gIGlmIChpc1VuZGVmaW5lZChuYW1lKSkge1xuICAgIGlmIChhcnJheSAmJiBrZXkubWF0Y2goL15cXGQrJC8pKSB7XG4gICAgICByZXR1cm4gc3RyO1xuICAgIH1cbiAgICBuYW1lID0gSlNPTi5zdHJpbmdpZnkoJycgKyBrZXkpO1xuICAgIGlmIChuYW1lLm1hdGNoKC9eXCIoW2EtekEtWl9dW2EtekEtWl8wLTldKilcIiQvKSkge1xuICAgICAgbmFtZSA9IG5hbWUuc3Vic3RyKDEsIG5hbWUubGVuZ3RoIC0gMik7XG4gICAgICBuYW1lID0gY3R4LnN0eWxpemUobmFtZSwgJ25hbWUnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbmFtZSA9IG5hbWUucmVwbGFjZSgvJy9nLCBcIlxcXFwnXCIpXG4gICAgICAgICAgICAgICAgIC5yZXBsYWNlKC9cXFxcXCIvZywgJ1wiJylcbiAgICAgICAgICAgICAgICAgLnJlcGxhY2UoLyheXCJ8XCIkKS9nLCBcIidcIik7XG4gICAgICBuYW1lID0gY3R4LnN0eWxpemUobmFtZSwgJ3N0cmluZycpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBuYW1lICsgJzogJyArIHN0cjtcbn1cblxuXG5mdW5jdGlvbiByZWR1Y2VUb1NpbmdsZVN0cmluZyhvdXRwdXQsIGJhc2UsIGJyYWNlcykge1xuICB2YXIgbnVtTGluZXNFc3QgPSAwO1xuICB2YXIgbGVuZ3RoID0gb3V0cHV0LnJlZHVjZShmdW5jdGlvbihwcmV2LCBjdXIpIHtcbiAgICBudW1MaW5lc0VzdCsrO1xuICAgIGlmIChjdXIuaW5kZXhPZignXFxuJykgPj0gMCkgbnVtTGluZXNFc3QrKztcbiAgICByZXR1cm4gcHJldiArIGN1ci5yZXBsYWNlKC9cXHUwMDFiXFxbXFxkXFxkP20vZywgJycpLmxlbmd0aCArIDE7XG4gIH0sIDApO1xuXG4gIGlmIChsZW5ndGggPiA2MCkge1xuICAgIHJldHVybiBicmFjZXNbMF0gK1xuICAgICAgICAgICAoYmFzZSA9PT0gJycgPyAnJyA6IGJhc2UgKyAnXFxuICcpICtcbiAgICAgICAgICAgJyAnICtcbiAgICAgICAgICAgb3V0cHV0LmpvaW4oJyxcXG4gICcpICtcbiAgICAgICAgICAgJyAnICtcbiAgICAgICAgICAgYnJhY2VzWzFdO1xuICB9XG5cbiAgcmV0dXJuIGJyYWNlc1swXSArIGJhc2UgKyAnICcgKyBvdXRwdXQuam9pbignLCAnKSArICcgJyArIGJyYWNlc1sxXTtcbn1cblxuXG4vLyBOT1RFOiBUaGVzZSB0eXBlIGNoZWNraW5nIGZ1bmN0aW9ucyBpbnRlbnRpb25hbGx5IGRvbid0IHVzZSBgaW5zdGFuY2VvZmBcbi8vIGJlY2F1c2UgaXQgaXMgZnJhZ2lsZSBhbmQgY2FuIGJlIGVhc2lseSBmYWtlZCB3aXRoIGBPYmplY3QuY3JlYXRlKClgLlxuZnVuY3Rpb24gaXNBcnJheShhcikge1xuICByZXR1cm4gQXJyYXkuaXNBcnJheShhcik7XG59XG5leHBvcnRzLmlzQXJyYXkgPSBpc0FycmF5O1xuXG5mdW5jdGlvbiBpc0Jvb2xlYW4oYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnYm9vbGVhbic7XG59XG5leHBvcnRzLmlzQm9vbGVhbiA9IGlzQm9vbGVhbjtcblxuZnVuY3Rpb24gaXNOdWxsKGFyZykge1xuICByZXR1cm4gYXJnID09PSBudWxsO1xufVxuZXhwb3J0cy5pc051bGwgPSBpc051bGw7XG5cbmZ1bmN0aW9uIGlzTnVsbE9yVW5kZWZpbmVkKGFyZykge1xuICByZXR1cm4gYXJnID09IG51bGw7XG59XG5leHBvcnRzLmlzTnVsbE9yVW5kZWZpbmVkID0gaXNOdWxsT3JVbmRlZmluZWQ7XG5cbmZ1bmN0aW9uIGlzTnVtYmVyKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ251bWJlcic7XG59XG5leHBvcnRzLmlzTnVtYmVyID0gaXNOdW1iZXI7XG5cbmZ1bmN0aW9uIGlzU3RyaW5nKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ3N0cmluZyc7XG59XG5leHBvcnRzLmlzU3RyaW5nID0gaXNTdHJpbmc7XG5cbmZ1bmN0aW9uIGlzU3ltYm9sKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ3N5bWJvbCc7XG59XG5leHBvcnRzLmlzU3ltYm9sID0gaXNTeW1ib2w7XG5cbmZ1bmN0aW9uIGlzVW5kZWZpbmVkKGFyZykge1xuICByZXR1cm4gYXJnID09PSB2b2lkIDA7XG59XG5leHBvcnRzLmlzVW5kZWZpbmVkID0gaXNVbmRlZmluZWQ7XG5cbmZ1bmN0aW9uIGlzUmVnRXhwKHJlKSB7XG4gIHJldHVybiBpc09iamVjdChyZSkgJiYgb2JqZWN0VG9TdHJpbmcocmUpID09PSAnW29iamVjdCBSZWdFeHBdJztcbn1cbmV4cG9ydHMuaXNSZWdFeHAgPSBpc1JlZ0V4cDtcblxuZnVuY3Rpb24gaXNPYmplY3QoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnb2JqZWN0JyAmJiBhcmcgIT09IG51bGw7XG59XG5leHBvcnRzLmlzT2JqZWN0ID0gaXNPYmplY3Q7XG5cbmZ1bmN0aW9uIGlzRGF0ZShkKSB7XG4gIHJldHVybiBpc09iamVjdChkKSAmJiBvYmplY3RUb1N0cmluZyhkKSA9PT0gJ1tvYmplY3QgRGF0ZV0nO1xufVxuZXhwb3J0cy5pc0RhdGUgPSBpc0RhdGU7XG5cbmZ1bmN0aW9uIGlzRXJyb3IoZSkge1xuICByZXR1cm4gaXNPYmplY3QoZSkgJiZcbiAgICAgIChvYmplY3RUb1N0cmluZyhlKSA9PT0gJ1tvYmplY3QgRXJyb3JdJyB8fCBlIGluc3RhbmNlb2YgRXJyb3IpO1xufVxuZXhwb3J0cy5pc0Vycm9yID0gaXNFcnJvcjtcblxuZnVuY3Rpb24gaXNGdW5jdGlvbihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdmdW5jdGlvbic7XG59XG5leHBvcnRzLmlzRnVuY3Rpb24gPSBpc0Z1bmN0aW9uO1xuXG5mdW5jdGlvbiBpc1ByaW1pdGl2ZShhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gbnVsbCB8fFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ2Jvb2xlYW4nIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnbnVtYmVyJyB8fFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ3N0cmluZycgfHxcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICdzeW1ib2wnIHx8ICAvLyBFUzYgc3ltYm9sXG4gICAgICAgICB0eXBlb2YgYXJnID09PSAndW5kZWZpbmVkJztcbn1cbmV4cG9ydHMuaXNQcmltaXRpdmUgPSBpc1ByaW1pdGl2ZTtcblxuZXhwb3J0cy5pc0J1ZmZlciA9IHJlcXVpcmUoJy4vc3VwcG9ydC9pc0J1ZmZlcicpO1xuXG5mdW5jdGlvbiBvYmplY3RUb1N0cmluZyhvKSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobyk7XG59XG5cblxuZnVuY3Rpb24gcGFkKG4pIHtcbiAgcmV0dXJuIG4gPCAxMCA/ICcwJyArIG4udG9TdHJpbmcoMTApIDogbi50b1N0cmluZygxMCk7XG59XG5cblxudmFyIG1vbnRocyA9IFsnSmFuJywgJ0ZlYicsICdNYXInLCAnQXByJywgJ01heScsICdKdW4nLCAnSnVsJywgJ0F1ZycsICdTZXAnLFxuICAgICAgICAgICAgICAnT2N0JywgJ05vdicsICdEZWMnXTtcblxuLy8gMjYgRmViIDE2OjE5OjM0XG5mdW5jdGlvbiB0aW1lc3RhbXAoKSB7XG4gIHZhciBkID0gbmV3IERhdGUoKTtcbiAgdmFyIHRpbWUgPSBbcGFkKGQuZ2V0SG91cnMoKSksXG4gICAgICAgICAgICAgIHBhZChkLmdldE1pbnV0ZXMoKSksXG4gICAgICAgICAgICAgIHBhZChkLmdldFNlY29uZHMoKSldLmpvaW4oJzonKTtcbiAgcmV0dXJuIFtkLmdldERhdGUoKSwgbW9udGhzW2QuZ2V0TW9udGgoKV0sIHRpbWVdLmpvaW4oJyAnKTtcbn1cblxuXG4vLyBsb2cgaXMganVzdCBhIHRoaW4gd3JhcHBlciB0byBjb25zb2xlLmxvZyB0aGF0IHByZXBlbmRzIGEgdGltZXN0YW1wXG5leHBvcnRzLmxvZyA9IGZ1bmN0aW9uKCkge1xuICBjb25zb2xlLmxvZygnJXMgLSAlcycsIHRpbWVzdGFtcCgpLCBleHBvcnRzLmZvcm1hdC5hcHBseShleHBvcnRzLCBhcmd1bWVudHMpKTtcbn07XG5cblxuLyoqXG4gKiBJbmhlcml0IHRoZSBwcm90b3R5cGUgbWV0aG9kcyBmcm9tIG9uZSBjb25zdHJ1Y3RvciBpbnRvIGFub3RoZXIuXG4gKlxuICogVGhlIEZ1bmN0aW9uLnByb3RvdHlwZS5pbmhlcml0cyBmcm9tIGxhbmcuanMgcmV3cml0dGVuIGFzIGEgc3RhbmRhbG9uZVxuICogZnVuY3Rpb24gKG5vdCBvbiBGdW5jdGlvbi5wcm90b3R5cGUpLiBOT1RFOiBJZiB0aGlzIGZpbGUgaXMgdG8gYmUgbG9hZGVkXG4gKiBkdXJpbmcgYm9vdHN0cmFwcGluZyB0aGlzIGZ1bmN0aW9uIG5lZWRzIHRvIGJlIHJld3JpdHRlbiB1c2luZyBzb21lIG5hdGl2ZVxuICogZnVuY3Rpb25zIGFzIHByb3RvdHlwZSBzZXR1cCB1c2luZyBub3JtYWwgSmF2YVNjcmlwdCBkb2VzIG5vdCB3b3JrIGFzXG4gKiBleHBlY3RlZCBkdXJpbmcgYm9vdHN0cmFwcGluZyAoc2VlIG1pcnJvci5qcyBpbiByMTE0OTAzKS5cbiAqXG4gKiBAcGFyYW0ge2Z1bmN0aW9ufSBjdG9yIENvbnN0cnVjdG9yIGZ1bmN0aW9uIHdoaWNoIG5lZWRzIHRvIGluaGVyaXQgdGhlXG4gKiAgICAgcHJvdG90eXBlLlxuICogQHBhcmFtIHtmdW5jdGlvbn0gc3VwZXJDdG9yIENvbnN0cnVjdG9yIGZ1bmN0aW9uIHRvIGluaGVyaXQgcHJvdG90eXBlIGZyb20uXG4gKi9cbmV4cG9ydHMuaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xuXG5leHBvcnRzLl9leHRlbmQgPSBmdW5jdGlvbihvcmlnaW4sIGFkZCkge1xuICAvLyBEb24ndCBkbyBhbnl0aGluZyBpZiBhZGQgaXNuJ3QgYW4gb2JqZWN0XG4gIGlmICghYWRkIHx8ICFpc09iamVjdChhZGQpKSByZXR1cm4gb3JpZ2luO1xuXG4gIHZhciBrZXlzID0gT2JqZWN0LmtleXMoYWRkKTtcbiAgdmFyIGkgPSBrZXlzLmxlbmd0aDtcbiAgd2hpbGUgKGktLSkge1xuICAgIG9yaWdpbltrZXlzW2ldXSA9IGFkZFtrZXlzW2ldXTtcbiAgfVxuICByZXR1cm4gb3JpZ2luO1xufTtcblxuZnVuY3Rpb24gaGFzT3duUHJvcGVydHkob2JqLCBwcm9wKSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBwcm9wKTtcbn1cbiIsIid1c2Ugc3RyaWN0J1xuXG5leHBvcnRzLmJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoXG5leHBvcnRzLnRvQnl0ZUFycmF5ID0gdG9CeXRlQXJyYXlcbmV4cG9ydHMuZnJvbUJ5dGVBcnJheSA9IGZyb21CeXRlQXJyYXlcblxudmFyIGxvb2t1cCA9IFtdXG52YXIgcmV2TG9va3VwID0gW11cbnZhciBBcnIgPSB0eXBlb2YgVWludDhBcnJheSAhPT0gJ3VuZGVmaW5lZCcgPyBVaW50OEFycmF5IDogQXJyYXlcblxudmFyIGNvZGUgPSAnQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLydcbmZvciAodmFyIGkgPSAwLCBsZW4gPSBjb2RlLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XG4gIGxvb2t1cFtpXSA9IGNvZGVbaV1cbiAgcmV2TG9va3VwW2NvZGUuY2hhckNvZGVBdChpKV0gPSBpXG59XG5cbi8vIFN1cHBvcnQgZGVjb2RpbmcgVVJMLXNhZmUgYmFzZTY0IHN0cmluZ3MsIGFzIE5vZGUuanMgZG9lcy5cbi8vIFNlZTogaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQmFzZTY0I1VSTF9hcHBsaWNhdGlvbnNcbnJldkxvb2t1cFsnLScuY2hhckNvZGVBdCgwKV0gPSA2MlxucmV2TG9va3VwWydfJy5jaGFyQ29kZUF0KDApXSA9IDYzXG5cbmZ1bmN0aW9uIGdldExlbnMgKGI2NCkge1xuICB2YXIgbGVuID0gYjY0Lmxlbmd0aFxuXG4gIGlmIChsZW4gJSA0ID4gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBzdHJpbmcuIExlbmd0aCBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgNCcpXG4gIH1cblxuICAvLyBUcmltIG9mZiBleHRyYSBieXRlcyBhZnRlciBwbGFjZWhvbGRlciBieXRlcyBhcmUgZm91bmRcbiAgLy8gU2VlOiBodHRwczovL2dpdGh1Yi5jb20vYmVhdGdhbW1pdC9iYXNlNjQtanMvaXNzdWVzLzQyXG4gIHZhciB2YWxpZExlbiA9IGI2NC5pbmRleE9mKCc9JylcbiAgaWYgKHZhbGlkTGVuID09PSAtMSkgdmFsaWRMZW4gPSBsZW5cblxuICB2YXIgcGxhY2VIb2xkZXJzTGVuID0gdmFsaWRMZW4gPT09IGxlblxuICAgID8gMFxuICAgIDogNCAtICh2YWxpZExlbiAlIDQpXG5cbiAgcmV0dXJuIFt2YWxpZExlbiwgcGxhY2VIb2xkZXJzTGVuXVxufVxuXG4vLyBiYXNlNjQgaXMgNC8zICsgdXAgdG8gdHdvIGNoYXJhY3RlcnMgb2YgdGhlIG9yaWdpbmFsIGRhdGFcbmZ1bmN0aW9uIGJ5dGVMZW5ndGggKGI2NCkge1xuICB2YXIgbGVucyA9IGdldExlbnMoYjY0KVxuICB2YXIgdmFsaWRMZW4gPSBsZW5zWzBdXG4gIHZhciBwbGFjZUhvbGRlcnNMZW4gPSBsZW5zWzFdXG4gIHJldHVybiAoKHZhbGlkTGVuICsgcGxhY2VIb2xkZXJzTGVuKSAqIDMgLyA0KSAtIHBsYWNlSG9sZGVyc0xlblxufVxuXG5mdW5jdGlvbiBfYnl0ZUxlbmd0aCAoYjY0LCB2YWxpZExlbiwgcGxhY2VIb2xkZXJzTGVuKSB7XG4gIHJldHVybiAoKHZhbGlkTGVuICsgcGxhY2VIb2xkZXJzTGVuKSAqIDMgLyA0KSAtIHBsYWNlSG9sZGVyc0xlblxufVxuXG5mdW5jdGlvbiB0b0J5dGVBcnJheSAoYjY0KSB7XG4gIHZhciB0bXBcbiAgdmFyIGxlbnMgPSBnZXRMZW5zKGI2NClcbiAgdmFyIHZhbGlkTGVuID0gbGVuc1swXVxuICB2YXIgcGxhY2VIb2xkZXJzTGVuID0gbGVuc1sxXVxuXG4gIHZhciBhcnIgPSBuZXcgQXJyKF9ieXRlTGVuZ3RoKGI2NCwgdmFsaWRMZW4sIHBsYWNlSG9sZGVyc0xlbikpXG5cbiAgdmFyIGN1ckJ5dGUgPSAwXG5cbiAgLy8gaWYgdGhlcmUgYXJlIHBsYWNlaG9sZGVycywgb25seSBnZXQgdXAgdG8gdGhlIGxhc3QgY29tcGxldGUgNCBjaGFyc1xuICB2YXIgbGVuID0gcGxhY2VIb2xkZXJzTGVuID4gMFxuICAgID8gdmFsaWRMZW4gLSA0XG4gICAgOiB2YWxpZExlblxuXG4gIHZhciBpXG4gIGZvciAoaSA9IDA7IGkgPCBsZW47IGkgKz0gNCkge1xuICAgIHRtcCA9XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkpXSA8PCAxOCkgfFxuICAgICAgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpICsgMSldIDw8IDEyKSB8XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkgKyAyKV0gPDwgNikgfFxuICAgICAgcmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkgKyAzKV1cbiAgICBhcnJbY3VyQnl0ZSsrXSA9ICh0bXAgPj4gMTYpICYgMHhGRlxuICAgIGFycltjdXJCeXRlKytdID0gKHRtcCA+PiA4KSAmIDB4RkZcbiAgICBhcnJbY3VyQnl0ZSsrXSA9IHRtcCAmIDB4RkZcbiAgfVxuXG4gIGlmIChwbGFjZUhvbGRlcnNMZW4gPT09IDIpIHtcbiAgICB0bXAgPVxuICAgICAgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpKV0gPDwgMikgfFxuICAgICAgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpICsgMSldID4+IDQpXG4gICAgYXJyW2N1ckJ5dGUrK10gPSB0bXAgJiAweEZGXG4gIH1cblxuICBpZiAocGxhY2VIb2xkZXJzTGVuID09PSAxKSB7XG4gICAgdG1wID1cbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSldIDw8IDEwKSB8XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkgKyAxKV0gPDwgNCkgfFxuICAgICAgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpICsgMildID4+IDIpXG4gICAgYXJyW2N1ckJ5dGUrK10gPSAodG1wID4+IDgpICYgMHhGRlxuICAgIGFycltjdXJCeXRlKytdID0gdG1wICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIGFyclxufVxuXG5mdW5jdGlvbiB0cmlwbGV0VG9CYXNlNjQgKG51bSkge1xuICByZXR1cm4gbG9va3VwW251bSA+PiAxOCAmIDB4M0ZdICtcbiAgICBsb29rdXBbbnVtID4+IDEyICYgMHgzRl0gK1xuICAgIGxvb2t1cFtudW0gPj4gNiAmIDB4M0ZdICtcbiAgICBsb29rdXBbbnVtICYgMHgzRl1cbn1cblxuZnVuY3Rpb24gZW5jb2RlQ2h1bmsgKHVpbnQ4LCBzdGFydCwgZW5kKSB7XG4gIHZhciB0bXBcbiAgdmFyIG91dHB1dCA9IFtdXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgaSArPSAzKSB7XG4gICAgdG1wID1cbiAgICAgICgodWludDhbaV0gPDwgMTYpICYgMHhGRjAwMDApICtcbiAgICAgICgodWludDhbaSArIDFdIDw8IDgpICYgMHhGRjAwKSArXG4gICAgICAodWludDhbaSArIDJdICYgMHhGRilcbiAgICBvdXRwdXQucHVzaCh0cmlwbGV0VG9CYXNlNjQodG1wKSlcbiAgfVxuICByZXR1cm4gb3V0cHV0LmpvaW4oJycpXG59XG5cbmZ1bmN0aW9uIGZyb21CeXRlQXJyYXkgKHVpbnQ4KSB7XG4gIHZhciB0bXBcbiAgdmFyIGxlbiA9IHVpbnQ4Lmxlbmd0aFxuICB2YXIgZXh0cmFCeXRlcyA9IGxlbiAlIDMgLy8gaWYgd2UgaGF2ZSAxIGJ5dGUgbGVmdCwgcGFkIDIgYnl0ZXNcbiAgdmFyIHBhcnRzID0gW11cbiAgdmFyIG1heENodW5rTGVuZ3RoID0gMTYzODMgLy8gbXVzdCBiZSBtdWx0aXBsZSBvZiAzXG5cbiAgLy8gZ28gdGhyb3VnaCB0aGUgYXJyYXkgZXZlcnkgdGhyZWUgYnl0ZXMsIHdlJ2xsIGRlYWwgd2l0aCB0cmFpbGluZyBzdHVmZiBsYXRlclxuICBmb3IgKHZhciBpID0gMCwgbGVuMiA9IGxlbiAtIGV4dHJhQnl0ZXM7IGkgPCBsZW4yOyBpICs9IG1heENodW5rTGVuZ3RoKSB7XG4gICAgcGFydHMucHVzaChlbmNvZGVDaHVuayh1aW50OCwgaSwgKGkgKyBtYXhDaHVua0xlbmd0aCkgPiBsZW4yID8gbGVuMiA6IChpICsgbWF4Q2h1bmtMZW5ndGgpKSlcbiAgfVxuXG4gIC8vIHBhZCB0aGUgZW5kIHdpdGggemVyb3MsIGJ1dCBtYWtlIHN1cmUgdG8gbm90IGZvcmdldCB0aGUgZXh0cmEgYnl0ZXNcbiAgaWYgKGV4dHJhQnl0ZXMgPT09IDEpIHtcbiAgICB0bXAgPSB1aW50OFtsZW4gLSAxXVxuICAgIHBhcnRzLnB1c2goXG4gICAgICBsb29rdXBbdG1wID4+IDJdICtcbiAgICAgIGxvb2t1cFsodG1wIDw8IDQpICYgMHgzRl0gK1xuICAgICAgJz09J1xuICAgIClcbiAgfSBlbHNlIGlmIChleHRyYUJ5dGVzID09PSAyKSB7XG4gICAgdG1wID0gKHVpbnQ4W2xlbiAtIDJdIDw8IDgpICsgdWludDhbbGVuIC0gMV1cbiAgICBwYXJ0cy5wdXNoKFxuICAgICAgbG9va3VwW3RtcCA+PiAxMF0gK1xuICAgICAgbG9va3VwWyh0bXAgPj4gNCkgJiAweDNGXSArXG4gICAgICBsb29rdXBbKHRtcCA8PCAyKSAmIDB4M0ZdICtcbiAgICAgICc9J1xuICAgIClcbiAgfVxuXG4gIHJldHVybiBwYXJ0cy5qb2luKCcnKVxufVxuIiwiIiwiLyohXG4gKiBUaGUgYnVmZmVyIG1vZHVsZSBmcm9tIG5vZGUuanMsIGZvciB0aGUgYnJvd3Nlci5cbiAqXG4gKiBAYXV0aG9yICAgRmVyb3NzIEFib3VraGFkaWplaCA8aHR0cHM6Ly9mZXJvc3Mub3JnPlxuICogQGxpY2Vuc2UgIE1JVFxuICovXG4vKiBlc2xpbnQtZGlzYWJsZSBuby1wcm90byAqL1xuXG4ndXNlIHN0cmljdCdcblxudmFyIGJhc2U2NCA9IHJlcXVpcmUoJ2Jhc2U2NC1qcycpXG52YXIgaWVlZTc1NCA9IHJlcXVpcmUoJ2llZWU3NTQnKVxuXG5leHBvcnRzLkJ1ZmZlciA9IEJ1ZmZlclxuZXhwb3J0cy5TbG93QnVmZmVyID0gU2xvd0J1ZmZlclxuZXhwb3J0cy5JTlNQRUNUX01BWF9CWVRFUyA9IDUwXG5cbnZhciBLX01BWF9MRU5HVEggPSAweDdmZmZmZmZmXG5leHBvcnRzLmtNYXhMZW5ndGggPSBLX01BWF9MRU5HVEhcblxuLyoqXG4gKiBJZiBgQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlRgOlxuICogICA9PT0gdHJ1ZSAgICBVc2UgVWludDhBcnJheSBpbXBsZW1lbnRhdGlvbiAoZmFzdGVzdClcbiAqICAgPT09IGZhbHNlICAgUHJpbnQgd2FybmluZyBhbmQgcmVjb21tZW5kIHVzaW5nIGBidWZmZXJgIHY0Lnggd2hpY2ggaGFzIGFuIE9iamVjdFxuICogICAgICAgICAgICAgICBpbXBsZW1lbnRhdGlvbiAobW9zdCBjb21wYXRpYmxlLCBldmVuIElFNilcbiAqXG4gKiBCcm93c2VycyB0aGF0IHN1cHBvcnQgdHlwZWQgYXJyYXlzIGFyZSBJRSAxMCssIEZpcmVmb3ggNCssIENocm9tZSA3KywgU2FmYXJpIDUuMSssXG4gKiBPcGVyYSAxMS42KywgaU9TIDQuMisuXG4gKlxuICogV2UgcmVwb3J0IHRoYXQgdGhlIGJyb3dzZXIgZG9lcyBub3Qgc3VwcG9ydCB0eXBlZCBhcnJheXMgaWYgdGhlIGFyZSBub3Qgc3ViY2xhc3NhYmxlXG4gKiB1c2luZyBfX3Byb3RvX18uIEZpcmVmb3ggNC0yOSBsYWNrcyBzdXBwb3J0IGZvciBhZGRpbmcgbmV3IHByb3BlcnRpZXMgdG8gYFVpbnQ4QXJyYXlgXG4gKiAoU2VlOiBodHRwczovL2J1Z3ppbGxhLm1vemlsbGEub3JnL3Nob3dfYnVnLmNnaT9pZD02OTU0MzgpLiBJRSAxMCBsYWNrcyBzdXBwb3J0XG4gKiBmb3IgX19wcm90b19fIGFuZCBoYXMgYSBidWdneSB0eXBlZCBhcnJheSBpbXBsZW1lbnRhdGlvbi5cbiAqL1xuQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQgPSB0eXBlZEFycmF5U3VwcG9ydCgpXG5cbmlmICghQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQgJiYgdHlwZW9mIGNvbnNvbGUgIT09ICd1bmRlZmluZWQnICYmXG4gICAgdHlwZW9mIGNvbnNvbGUuZXJyb3IgPT09ICdmdW5jdGlvbicpIHtcbiAgY29uc29sZS5lcnJvcihcbiAgICAnVGhpcyBicm93c2VyIGxhY2tzIHR5cGVkIGFycmF5IChVaW50OEFycmF5KSBzdXBwb3J0IHdoaWNoIGlzIHJlcXVpcmVkIGJ5ICcgK1xuICAgICdgYnVmZmVyYCB2NS54LiBVc2UgYGJ1ZmZlcmAgdjQueCBpZiB5b3UgcmVxdWlyZSBvbGQgYnJvd3NlciBzdXBwb3J0LidcbiAgKVxufVxuXG5mdW5jdGlvbiB0eXBlZEFycmF5U3VwcG9ydCAoKSB7XG4gIC8vIENhbiB0eXBlZCBhcnJheSBpbnN0YW5jZXMgY2FuIGJlIGF1Z21lbnRlZD9cbiAgdHJ5IHtcbiAgICB2YXIgYXJyID0gbmV3IFVpbnQ4QXJyYXkoMSlcbiAgICBhcnIuX19wcm90b19fID0geyBfX3Byb3RvX186IFVpbnQ4QXJyYXkucHJvdG90eXBlLCBmb286IGZ1bmN0aW9uICgpIHsgcmV0dXJuIDQyIH0gfVxuICAgIHJldHVybiBhcnIuZm9vKCkgPT09IDQyXG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxufVxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoQnVmZmVyLnByb3RvdHlwZSwgJ3BhcmVudCcsIHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKCFCdWZmZXIuaXNCdWZmZXIodGhpcykpIHJldHVybiB1bmRlZmluZWRcbiAgICByZXR1cm4gdGhpcy5idWZmZXJcbiAgfVxufSlcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KEJ1ZmZlci5wcm90b3R5cGUsICdvZmZzZXQnLCB7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIGlmICghQnVmZmVyLmlzQnVmZmVyKHRoaXMpKSByZXR1cm4gdW5kZWZpbmVkXG4gICAgcmV0dXJuIHRoaXMuYnl0ZU9mZnNldFxuICB9XG59KVxuXG5mdW5jdGlvbiBjcmVhdGVCdWZmZXIgKGxlbmd0aCkge1xuICBpZiAobGVuZ3RoID4gS19NQVhfTEVOR1RIKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1RoZSB2YWx1ZSBcIicgKyBsZW5ndGggKyAnXCIgaXMgaW52YWxpZCBmb3Igb3B0aW9uIFwic2l6ZVwiJylcbiAgfVxuICAvLyBSZXR1cm4gYW4gYXVnbWVudGVkIGBVaW50OEFycmF5YCBpbnN0YW5jZVxuICB2YXIgYnVmID0gbmV3IFVpbnQ4QXJyYXkobGVuZ3RoKVxuICBidWYuX19wcm90b19fID0gQnVmZmVyLnByb3RvdHlwZVxuICByZXR1cm4gYnVmXG59XG5cbi8qKlxuICogVGhlIEJ1ZmZlciBjb25zdHJ1Y3RvciByZXR1cm5zIGluc3RhbmNlcyBvZiBgVWludDhBcnJheWAgdGhhdCBoYXZlIHRoZWlyXG4gKiBwcm90b3R5cGUgY2hhbmdlZCB0byBgQnVmZmVyLnByb3RvdHlwZWAuIEZ1cnRoZXJtb3JlLCBgQnVmZmVyYCBpcyBhIHN1YmNsYXNzIG9mXG4gKiBgVWludDhBcnJheWAsIHNvIHRoZSByZXR1cm5lZCBpbnN0YW5jZXMgd2lsbCBoYXZlIGFsbCB0aGUgbm9kZSBgQnVmZmVyYCBtZXRob2RzXG4gKiBhbmQgdGhlIGBVaW50OEFycmF5YCBtZXRob2RzLiBTcXVhcmUgYnJhY2tldCBub3RhdGlvbiB3b3JrcyBhcyBleHBlY3RlZCAtLSBpdFxuICogcmV0dXJucyBhIHNpbmdsZSBvY3RldC5cbiAqXG4gKiBUaGUgYFVpbnQ4QXJyYXlgIHByb3RvdHlwZSByZW1haW5zIHVubW9kaWZpZWQuXG4gKi9cblxuZnVuY3Rpb24gQnVmZmVyIChhcmcsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aCkge1xuICAvLyBDb21tb24gY2FzZS5cbiAgaWYgKHR5cGVvZiBhcmcgPT09ICdudW1iZXInKSB7XG4gICAgaWYgKHR5cGVvZiBlbmNvZGluZ09yT2Zmc2V0ID09PSAnc3RyaW5nJykge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgICAgJ1RoZSBcInN0cmluZ1wiIGFyZ3VtZW50IG11c3QgYmUgb2YgdHlwZSBzdHJpbmcuIFJlY2VpdmVkIHR5cGUgbnVtYmVyJ1xuICAgICAgKVxuICAgIH1cbiAgICByZXR1cm4gYWxsb2NVbnNhZmUoYXJnKVxuICB9XG4gIHJldHVybiBmcm9tKGFyZywgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKVxufVxuXG4vLyBGaXggc3ViYXJyYXkoKSBpbiBFUzIwMTYuIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL2Zlcm9zcy9idWZmZXIvcHVsbC85N1xuaWYgKHR5cGVvZiBTeW1ib2wgIT09ICd1bmRlZmluZWQnICYmIFN5bWJvbC5zcGVjaWVzICE9IG51bGwgJiZcbiAgICBCdWZmZXJbU3ltYm9sLnNwZWNpZXNdID09PSBCdWZmZXIpIHtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEJ1ZmZlciwgU3ltYm9sLnNwZWNpZXMsIHtcbiAgICB2YWx1ZTogbnVsbCxcbiAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgd3JpdGFibGU6IGZhbHNlXG4gIH0pXG59XG5cbkJ1ZmZlci5wb29sU2l6ZSA9IDgxOTIgLy8gbm90IHVzZWQgYnkgdGhpcyBpbXBsZW1lbnRhdGlvblxuXG5mdW5jdGlvbiBmcm9tICh2YWx1ZSwgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKSB7XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIGZyb21TdHJpbmcodmFsdWUsIGVuY29kaW5nT3JPZmZzZXQpXG4gIH1cblxuICBpZiAoQXJyYXlCdWZmZXIuaXNWaWV3KHZhbHVlKSkge1xuICAgIHJldHVybiBmcm9tQXJyYXlMaWtlKHZhbHVlKVxuICB9XG5cbiAgaWYgKHZhbHVlID09IG51bGwpIHtcbiAgICB0aHJvdyBUeXBlRXJyb3IoXG4gICAgICAnVGhlIGZpcnN0IGFyZ3VtZW50IG11c3QgYmUgb25lIG9mIHR5cGUgc3RyaW5nLCBCdWZmZXIsIEFycmF5QnVmZmVyLCBBcnJheSwgJyArXG4gICAgICAnb3IgQXJyYXktbGlrZSBPYmplY3QuIFJlY2VpdmVkIHR5cGUgJyArICh0eXBlb2YgdmFsdWUpXG4gICAgKVxuICB9XG5cbiAgaWYgKGlzSW5zdGFuY2UodmFsdWUsIEFycmF5QnVmZmVyKSB8fFxuICAgICAgKHZhbHVlICYmIGlzSW5zdGFuY2UodmFsdWUuYnVmZmVyLCBBcnJheUJ1ZmZlcikpKSB7XG4gICAgcmV0dXJuIGZyb21BcnJheUJ1ZmZlcih2YWx1ZSwgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKVxuICB9XG5cbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgJ1RoZSBcInZhbHVlXCIgYXJndW1lbnQgbXVzdCBub3QgYmUgb2YgdHlwZSBudW1iZXIuIFJlY2VpdmVkIHR5cGUgbnVtYmVyJ1xuICAgIClcbiAgfVxuXG4gIHZhciB2YWx1ZU9mID0gdmFsdWUudmFsdWVPZiAmJiB2YWx1ZS52YWx1ZU9mKClcbiAgaWYgKHZhbHVlT2YgIT0gbnVsbCAmJiB2YWx1ZU9mICE9PSB2YWx1ZSkge1xuICAgIHJldHVybiBCdWZmZXIuZnJvbSh2YWx1ZU9mLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpXG4gIH1cblxuICB2YXIgYiA9IGZyb21PYmplY3QodmFsdWUpXG4gIGlmIChiKSByZXR1cm4gYlxuXG4gIGlmICh0eXBlb2YgU3ltYm9sICE9PSAndW5kZWZpbmVkJyAmJiBTeW1ib2wudG9QcmltaXRpdmUgIT0gbnVsbCAmJlxuICAgICAgdHlwZW9mIHZhbHVlW1N5bWJvbC50b1ByaW1pdGl2ZV0gPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gQnVmZmVyLmZyb20oXG4gICAgICB2YWx1ZVtTeW1ib2wudG9QcmltaXRpdmVdKCdzdHJpbmcnKSwgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoXG4gICAgKVxuICB9XG5cbiAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAnVGhlIGZpcnN0IGFyZ3VtZW50IG11c3QgYmUgb25lIG9mIHR5cGUgc3RyaW5nLCBCdWZmZXIsIEFycmF5QnVmZmVyLCBBcnJheSwgJyArXG4gICAgJ29yIEFycmF5LWxpa2UgT2JqZWN0LiBSZWNlaXZlZCB0eXBlICcgKyAodHlwZW9mIHZhbHVlKVxuICApXG59XG5cbi8qKlxuICogRnVuY3Rpb25hbGx5IGVxdWl2YWxlbnQgdG8gQnVmZmVyKGFyZywgZW5jb2RpbmcpIGJ1dCB0aHJvd3MgYSBUeXBlRXJyb3JcbiAqIGlmIHZhbHVlIGlzIGEgbnVtYmVyLlxuICogQnVmZmVyLmZyb20oc3RyWywgZW5jb2RpbmddKVxuICogQnVmZmVyLmZyb20oYXJyYXkpXG4gKiBCdWZmZXIuZnJvbShidWZmZXIpXG4gKiBCdWZmZXIuZnJvbShhcnJheUJ1ZmZlclssIGJ5dGVPZmZzZXRbLCBsZW5ndGhdXSlcbiAqKi9cbkJ1ZmZlci5mcm9tID0gZnVuY3Rpb24gKHZhbHVlLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGZyb20odmFsdWUsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aClcbn1cblxuLy8gTm90ZTogQ2hhbmdlIHByb3RvdHlwZSAqYWZ0ZXIqIEJ1ZmZlci5mcm9tIGlzIGRlZmluZWQgdG8gd29ya2Fyb3VuZCBDaHJvbWUgYnVnOlxuLy8gaHR0cHM6Ly9naXRodWIuY29tL2Zlcm9zcy9idWZmZXIvcHVsbC8xNDhcbkJ1ZmZlci5wcm90b3R5cGUuX19wcm90b19fID0gVWludDhBcnJheS5wcm90b3R5cGVcbkJ1ZmZlci5fX3Byb3RvX18gPSBVaW50OEFycmF5XG5cbmZ1bmN0aW9uIGFzc2VydFNpemUgKHNpemUpIHtcbiAgaWYgKHR5cGVvZiBzaXplICE9PSAnbnVtYmVyJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wic2l6ZVwiIGFyZ3VtZW50IG11c3QgYmUgb2YgdHlwZSBudW1iZXInKVxuICB9IGVsc2UgaWYgKHNpemUgPCAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1RoZSB2YWx1ZSBcIicgKyBzaXplICsgJ1wiIGlzIGludmFsaWQgZm9yIG9wdGlvbiBcInNpemVcIicpXG4gIH1cbn1cblxuZnVuY3Rpb24gYWxsb2MgKHNpemUsIGZpbGwsIGVuY29kaW5nKSB7XG4gIGFzc2VydFNpemUoc2l6ZSlcbiAgaWYgKHNpemUgPD0gMCkge1xuICAgIHJldHVybiBjcmVhdGVCdWZmZXIoc2l6ZSlcbiAgfVxuICBpZiAoZmlsbCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgLy8gT25seSBwYXkgYXR0ZW50aW9uIHRvIGVuY29kaW5nIGlmIGl0J3MgYSBzdHJpbmcuIFRoaXNcbiAgICAvLyBwcmV2ZW50cyBhY2NpZGVudGFsbHkgc2VuZGluZyBpbiBhIG51bWJlciB0aGF0IHdvdWxkXG4gICAgLy8gYmUgaW50ZXJwcmV0dGVkIGFzIGEgc3RhcnQgb2Zmc2V0LlxuICAgIHJldHVybiB0eXBlb2YgZW5jb2RpbmcgPT09ICdzdHJpbmcnXG4gICAgICA/IGNyZWF0ZUJ1ZmZlcihzaXplKS5maWxsKGZpbGwsIGVuY29kaW5nKVxuICAgICAgOiBjcmVhdGVCdWZmZXIoc2l6ZSkuZmlsbChmaWxsKVxuICB9XG4gIHJldHVybiBjcmVhdGVCdWZmZXIoc2l6ZSlcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IGZpbGxlZCBCdWZmZXIgaW5zdGFuY2UuXG4gKiBhbGxvYyhzaXplWywgZmlsbFssIGVuY29kaW5nXV0pXG4gKiovXG5CdWZmZXIuYWxsb2MgPSBmdW5jdGlvbiAoc2l6ZSwgZmlsbCwgZW5jb2RpbmcpIHtcbiAgcmV0dXJuIGFsbG9jKHNpemUsIGZpbGwsIGVuY29kaW5nKVxufVxuXG5mdW5jdGlvbiBhbGxvY1Vuc2FmZSAoc2l6ZSkge1xuICBhc3NlcnRTaXplKHNpemUpXG4gIHJldHVybiBjcmVhdGVCdWZmZXIoc2l6ZSA8IDAgPyAwIDogY2hlY2tlZChzaXplKSB8IDApXG59XG5cbi8qKlxuICogRXF1aXZhbGVudCB0byBCdWZmZXIobnVtKSwgYnkgZGVmYXVsdCBjcmVhdGVzIGEgbm9uLXplcm8tZmlsbGVkIEJ1ZmZlciBpbnN0YW5jZS5cbiAqICovXG5CdWZmZXIuYWxsb2NVbnNhZmUgPSBmdW5jdGlvbiAoc2l6ZSkge1xuICByZXR1cm4gYWxsb2NVbnNhZmUoc2l6ZSlcbn1cbi8qKlxuICogRXF1aXZhbGVudCB0byBTbG93QnVmZmVyKG51bSksIGJ5IGRlZmF1bHQgY3JlYXRlcyBhIG5vbi16ZXJvLWZpbGxlZCBCdWZmZXIgaW5zdGFuY2UuXG4gKi9cbkJ1ZmZlci5hbGxvY1Vuc2FmZVNsb3cgPSBmdW5jdGlvbiAoc2l6ZSkge1xuICByZXR1cm4gYWxsb2NVbnNhZmUoc2l6ZSlcbn1cblxuZnVuY3Rpb24gZnJvbVN0cmluZyAoc3RyaW5nLCBlbmNvZGluZykge1xuICBpZiAodHlwZW9mIGVuY29kaW5nICE9PSAnc3RyaW5nJyB8fCBlbmNvZGluZyA9PT0gJycpIHtcbiAgICBlbmNvZGluZyA9ICd1dGY4J1xuICB9XG5cbiAgaWYgKCFCdWZmZXIuaXNFbmNvZGluZyhlbmNvZGluZykpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpXG4gIH1cblxuICB2YXIgbGVuZ3RoID0gYnl0ZUxlbmd0aChzdHJpbmcsIGVuY29kaW5nKSB8IDBcbiAgdmFyIGJ1ZiA9IGNyZWF0ZUJ1ZmZlcihsZW5ndGgpXG5cbiAgdmFyIGFjdHVhbCA9IGJ1Zi53cml0ZShzdHJpbmcsIGVuY29kaW5nKVxuXG4gIGlmIChhY3R1YWwgIT09IGxlbmd0aCkge1xuICAgIC8vIFdyaXRpbmcgYSBoZXggc3RyaW5nLCBmb3IgZXhhbXBsZSwgdGhhdCBjb250YWlucyBpbnZhbGlkIGNoYXJhY3RlcnMgd2lsbFxuICAgIC8vIGNhdXNlIGV2ZXJ5dGhpbmcgYWZ0ZXIgdGhlIGZpcnN0IGludmFsaWQgY2hhcmFjdGVyIHRvIGJlIGlnbm9yZWQuIChlLmcuXG4gICAgLy8gJ2FieHhjZCcgd2lsbCBiZSB0cmVhdGVkIGFzICdhYicpXG4gICAgYnVmID0gYnVmLnNsaWNlKDAsIGFjdHVhbClcbiAgfVxuXG4gIHJldHVybiBidWZcbn1cblxuZnVuY3Rpb24gZnJvbUFycmF5TGlrZSAoYXJyYXkpIHtcbiAgdmFyIGxlbmd0aCA9IGFycmF5Lmxlbmd0aCA8IDAgPyAwIDogY2hlY2tlZChhcnJheS5sZW5ndGgpIHwgMFxuICB2YXIgYnVmID0gY3JlYXRlQnVmZmVyKGxlbmd0aClcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gMSkge1xuICAgIGJ1ZltpXSA9IGFycmF5W2ldICYgMjU1XG4gIH1cbiAgcmV0dXJuIGJ1ZlxufVxuXG5mdW5jdGlvbiBmcm9tQXJyYXlCdWZmZXIgKGFycmF5LCBieXRlT2Zmc2V0LCBsZW5ndGgpIHtcbiAgaWYgKGJ5dGVPZmZzZXQgPCAwIHx8IGFycmF5LmJ5dGVMZW5ndGggPCBieXRlT2Zmc2V0KSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1wib2Zmc2V0XCIgaXMgb3V0c2lkZSBvZiBidWZmZXIgYm91bmRzJylcbiAgfVxuXG4gIGlmIChhcnJheS5ieXRlTGVuZ3RoIDwgYnl0ZU9mZnNldCArIChsZW5ndGggfHwgMCkpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignXCJsZW5ndGhcIiBpcyBvdXRzaWRlIG9mIGJ1ZmZlciBib3VuZHMnKVxuICB9XG5cbiAgdmFyIGJ1ZlxuICBpZiAoYnl0ZU9mZnNldCA9PT0gdW5kZWZpbmVkICYmIGxlbmd0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgYnVmID0gbmV3IFVpbnQ4QXJyYXkoYXJyYXkpXG4gIH0gZWxzZSBpZiAobGVuZ3RoID09PSB1bmRlZmluZWQpIHtcbiAgICBidWYgPSBuZXcgVWludDhBcnJheShhcnJheSwgYnl0ZU9mZnNldClcbiAgfSBlbHNlIHtcbiAgICBidWYgPSBuZXcgVWludDhBcnJheShhcnJheSwgYnl0ZU9mZnNldCwgbGVuZ3RoKVxuICB9XG5cbiAgLy8gUmV0dXJuIGFuIGF1Z21lbnRlZCBgVWludDhBcnJheWAgaW5zdGFuY2VcbiAgYnVmLl9fcHJvdG9fXyA9IEJ1ZmZlci5wcm90b3R5cGVcbiAgcmV0dXJuIGJ1ZlxufVxuXG5mdW5jdGlvbiBmcm9tT2JqZWN0IChvYmopIHtcbiAgaWYgKEJ1ZmZlci5pc0J1ZmZlcihvYmopKSB7XG4gICAgdmFyIGxlbiA9IGNoZWNrZWQob2JqLmxlbmd0aCkgfCAwXG4gICAgdmFyIGJ1ZiA9IGNyZWF0ZUJ1ZmZlcihsZW4pXG5cbiAgICBpZiAoYnVmLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIGJ1ZlxuICAgIH1cblxuICAgIG9iai5jb3B5KGJ1ZiwgMCwgMCwgbGVuKVxuICAgIHJldHVybiBidWZcbiAgfVxuXG4gIGlmIChvYmoubGVuZ3RoICE9PSB1bmRlZmluZWQpIHtcbiAgICBpZiAodHlwZW9mIG9iai5sZW5ndGggIT09ICdudW1iZXInIHx8IG51bWJlcklzTmFOKG9iai5sZW5ndGgpKSB7XG4gICAgICByZXR1cm4gY3JlYXRlQnVmZmVyKDApXG4gICAgfVxuICAgIHJldHVybiBmcm9tQXJyYXlMaWtlKG9iailcbiAgfVxuXG4gIGlmIChvYmoudHlwZSA9PT0gJ0J1ZmZlcicgJiYgQXJyYXkuaXNBcnJheShvYmouZGF0YSkpIHtcbiAgICByZXR1cm4gZnJvbUFycmF5TGlrZShvYmouZGF0YSlcbiAgfVxufVxuXG5mdW5jdGlvbiBjaGVja2VkIChsZW5ndGgpIHtcbiAgLy8gTm90ZTogY2Fubm90IHVzZSBgbGVuZ3RoIDwgS19NQVhfTEVOR1RIYCBoZXJlIGJlY2F1c2UgdGhhdCBmYWlscyB3aGVuXG4gIC8vIGxlbmd0aCBpcyBOYU4gKHdoaWNoIGlzIG90aGVyd2lzZSBjb2VyY2VkIHRvIHplcm8uKVxuICBpZiAobGVuZ3RoID49IEtfTUFYX0xFTkdUSCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdBdHRlbXB0IHRvIGFsbG9jYXRlIEJ1ZmZlciBsYXJnZXIgdGhhbiBtYXhpbXVtICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICdzaXplOiAweCcgKyBLX01BWF9MRU5HVEgudG9TdHJpbmcoMTYpICsgJyBieXRlcycpXG4gIH1cbiAgcmV0dXJuIGxlbmd0aCB8IDBcbn1cblxuZnVuY3Rpb24gU2xvd0J1ZmZlciAobGVuZ3RoKSB7XG4gIGlmICgrbGVuZ3RoICE9IGxlbmd0aCkgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIGVxZXFlcVxuICAgIGxlbmd0aCA9IDBcbiAgfVxuICByZXR1cm4gQnVmZmVyLmFsbG9jKCtsZW5ndGgpXG59XG5cbkJ1ZmZlci5pc0J1ZmZlciA9IGZ1bmN0aW9uIGlzQnVmZmVyIChiKSB7XG4gIHJldHVybiBiICE9IG51bGwgJiYgYi5faXNCdWZmZXIgPT09IHRydWUgJiZcbiAgICBiICE9PSBCdWZmZXIucHJvdG90eXBlIC8vIHNvIEJ1ZmZlci5pc0J1ZmZlcihCdWZmZXIucHJvdG90eXBlKSB3aWxsIGJlIGZhbHNlXG59XG5cbkJ1ZmZlci5jb21wYXJlID0gZnVuY3Rpb24gY29tcGFyZSAoYSwgYikge1xuICBpZiAoaXNJbnN0YW5jZShhLCBVaW50OEFycmF5KSkgYSA9IEJ1ZmZlci5mcm9tKGEsIGEub2Zmc2V0LCBhLmJ5dGVMZW5ndGgpXG4gIGlmIChpc0luc3RhbmNlKGIsIFVpbnQ4QXJyYXkpKSBiID0gQnVmZmVyLmZyb20oYiwgYi5vZmZzZXQsIGIuYnl0ZUxlbmd0aClcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYSkgfHwgIUJ1ZmZlci5pc0J1ZmZlcihiKSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICAnVGhlIFwiYnVmMVwiLCBcImJ1ZjJcIiBhcmd1bWVudHMgbXVzdCBiZSBvbmUgb2YgdHlwZSBCdWZmZXIgb3IgVWludDhBcnJheSdcbiAgICApXG4gIH1cblxuICBpZiAoYSA9PT0gYikgcmV0dXJuIDBcblxuICB2YXIgeCA9IGEubGVuZ3RoXG4gIHZhciB5ID0gYi5sZW5ndGhcblxuICBmb3IgKHZhciBpID0gMCwgbGVuID0gTWF0aC5taW4oeCwgeSk7IGkgPCBsZW47ICsraSkge1xuICAgIGlmIChhW2ldICE9PSBiW2ldKSB7XG4gICAgICB4ID0gYVtpXVxuICAgICAgeSA9IGJbaV1cbiAgICAgIGJyZWFrXG4gICAgfVxuICB9XG5cbiAgaWYgKHggPCB5KSByZXR1cm4gLTFcbiAgaWYgKHkgPCB4KSByZXR1cm4gMVxuICByZXR1cm4gMFxufVxuXG5CdWZmZXIuaXNFbmNvZGluZyA9IGZ1bmN0aW9uIGlzRW5jb2RpbmcgKGVuY29kaW5nKSB7XG4gIHN3aXRjaCAoU3RyaW5nKGVuY29kaW5nKS50b0xvd2VyQ2FzZSgpKSB7XG4gICAgY2FzZSAnaGV4JzpcbiAgICBjYXNlICd1dGY4JzpcbiAgICBjYXNlICd1dGYtOCc6XG4gICAgY2FzZSAnYXNjaWknOlxuICAgIGNhc2UgJ2xhdGluMSc6XG4gICAgY2FzZSAnYmluYXJ5JzpcbiAgICBjYXNlICdiYXNlNjQnOlxuICAgIGNhc2UgJ3VjczInOlxuICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICBjYXNlICd1dGYxNmxlJzpcbiAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICByZXR1cm4gdHJ1ZVxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gZmFsc2VcbiAgfVxufVxuXG5CdWZmZXIuY29uY2F0ID0gZnVuY3Rpb24gY29uY2F0IChsaXN0LCBsZW5ndGgpIHtcbiAgaWYgKCFBcnJheS5pc0FycmF5KGxpc3QpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJsaXN0XCIgYXJndW1lbnQgbXVzdCBiZSBhbiBBcnJheSBvZiBCdWZmZXJzJylcbiAgfVxuXG4gIGlmIChsaXN0Lmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBCdWZmZXIuYWxsb2MoMClcbiAgfVxuXG4gIHZhciBpXG4gIGlmIChsZW5ndGggPT09IHVuZGVmaW5lZCkge1xuICAgIGxlbmd0aCA9IDBcbiAgICBmb3IgKGkgPSAwOyBpIDwgbGlzdC5sZW5ndGg7ICsraSkge1xuICAgICAgbGVuZ3RoICs9IGxpc3RbaV0ubGVuZ3RoXG4gICAgfVxuICB9XG5cbiAgdmFyIGJ1ZmZlciA9IEJ1ZmZlci5hbGxvY1Vuc2FmZShsZW5ndGgpXG4gIHZhciBwb3MgPSAwXG4gIGZvciAoaSA9IDA7IGkgPCBsaXN0Lmxlbmd0aDsgKytpKSB7XG4gICAgdmFyIGJ1ZiA9IGxpc3RbaV1cbiAgICBpZiAoaXNJbnN0YW5jZShidWYsIFVpbnQ4QXJyYXkpKSB7XG4gICAgICBidWYgPSBCdWZmZXIuZnJvbShidWYpXG4gICAgfVxuICAgIGlmICghQnVmZmVyLmlzQnVmZmVyKGJ1ZikpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wibGlzdFwiIGFyZ3VtZW50IG11c3QgYmUgYW4gQXJyYXkgb2YgQnVmZmVycycpXG4gICAgfVxuICAgIGJ1Zi5jb3B5KGJ1ZmZlciwgcG9zKVxuICAgIHBvcyArPSBidWYubGVuZ3RoXG4gIH1cbiAgcmV0dXJuIGJ1ZmZlclxufVxuXG5mdW5jdGlvbiBieXRlTGVuZ3RoIChzdHJpbmcsIGVuY29kaW5nKSB7XG4gIGlmIChCdWZmZXIuaXNCdWZmZXIoc3RyaW5nKSkge1xuICAgIHJldHVybiBzdHJpbmcubGVuZ3RoXG4gIH1cbiAgaWYgKEFycmF5QnVmZmVyLmlzVmlldyhzdHJpbmcpIHx8IGlzSW5zdGFuY2Uoc3RyaW5nLCBBcnJheUJ1ZmZlcikpIHtcbiAgICByZXR1cm4gc3RyaW5nLmJ5dGVMZW5ndGhcbiAgfVxuICBpZiAodHlwZW9mIHN0cmluZyAhPT0gJ3N0cmluZycpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgJ1RoZSBcInN0cmluZ1wiIGFyZ3VtZW50IG11c3QgYmUgb25lIG9mIHR5cGUgc3RyaW5nLCBCdWZmZXIsIG9yIEFycmF5QnVmZmVyLiAnICtcbiAgICAgICdSZWNlaXZlZCB0eXBlICcgKyB0eXBlb2Ygc3RyaW5nXG4gICAgKVxuICB9XG5cbiAgdmFyIGxlbiA9IHN0cmluZy5sZW5ndGhcbiAgdmFyIG11c3RNYXRjaCA9IChhcmd1bWVudHMubGVuZ3RoID4gMiAmJiBhcmd1bWVudHNbMl0gPT09IHRydWUpXG4gIGlmICghbXVzdE1hdGNoICYmIGxlbiA9PT0gMCkgcmV0dXJuIDBcblxuICAvLyBVc2UgYSBmb3IgbG9vcCB0byBhdm9pZCByZWN1cnNpb25cbiAgdmFyIGxvd2VyZWRDYXNlID0gZmFsc2VcbiAgZm9yICg7Oykge1xuICAgIHN3aXRjaCAoZW5jb2RpbmcpIHtcbiAgICAgIGNhc2UgJ2FzY2lpJzpcbiAgICAgIGNhc2UgJ2xhdGluMSc6XG4gICAgICBjYXNlICdiaW5hcnknOlxuICAgICAgICByZXR1cm4gbGVuXG4gICAgICBjYXNlICd1dGY4JzpcbiAgICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgICAgcmV0dXJuIHV0ZjhUb0J5dGVzKHN0cmluZykubGVuZ3RoXG4gICAgICBjYXNlICd1Y3MyJzpcbiAgICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgICByZXR1cm4gbGVuICogMlxuICAgICAgY2FzZSAnaGV4JzpcbiAgICAgICAgcmV0dXJuIGxlbiA+Pj4gMVxuICAgICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgICAgcmV0dXJuIGJhc2U2NFRvQnl0ZXMoc3RyaW5nKS5sZW5ndGhcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmIChsb3dlcmVkQ2FzZSkge1xuICAgICAgICAgIHJldHVybiBtdXN0TWF0Y2ggPyAtMSA6IHV0ZjhUb0J5dGVzKHN0cmluZykubGVuZ3RoIC8vIGFzc3VtZSB1dGY4XG4gICAgICAgIH1cbiAgICAgICAgZW5jb2RpbmcgPSAoJycgKyBlbmNvZGluZykudG9Mb3dlckNhc2UoKVxuICAgICAgICBsb3dlcmVkQ2FzZSA9IHRydWVcbiAgICB9XG4gIH1cbn1cbkJ1ZmZlci5ieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aFxuXG5mdW5jdGlvbiBzbG93VG9TdHJpbmcgKGVuY29kaW5nLCBzdGFydCwgZW5kKSB7XG4gIHZhciBsb3dlcmVkQ2FzZSA9IGZhbHNlXG5cbiAgLy8gTm8gbmVlZCB0byB2ZXJpZnkgdGhhdCBcInRoaXMubGVuZ3RoIDw9IE1BWF9VSU5UMzJcIiBzaW5jZSBpdCdzIGEgcmVhZC1vbmx5XG4gIC8vIHByb3BlcnR5IG9mIGEgdHlwZWQgYXJyYXkuXG5cbiAgLy8gVGhpcyBiZWhhdmVzIG5laXRoZXIgbGlrZSBTdHJpbmcgbm9yIFVpbnQ4QXJyYXkgaW4gdGhhdCB3ZSBzZXQgc3RhcnQvZW5kXG4gIC8vIHRvIHRoZWlyIHVwcGVyL2xvd2VyIGJvdW5kcyBpZiB0aGUgdmFsdWUgcGFzc2VkIGlzIG91dCBvZiByYW5nZS5cbiAgLy8gdW5kZWZpbmVkIGlzIGhhbmRsZWQgc3BlY2lhbGx5IGFzIHBlciBFQ01BLTI2MiA2dGggRWRpdGlvbixcbiAgLy8gU2VjdGlvbiAxMy4zLjMuNyBSdW50aW1lIFNlbWFudGljczogS2V5ZWRCaW5kaW5nSW5pdGlhbGl6YXRpb24uXG4gIGlmIChzdGFydCA9PT0gdW5kZWZpbmVkIHx8IHN0YXJ0IDwgMCkge1xuICAgIHN0YXJ0ID0gMFxuICB9XG4gIC8vIFJldHVybiBlYXJseSBpZiBzdGFydCA+IHRoaXMubGVuZ3RoLiBEb25lIGhlcmUgdG8gcHJldmVudCBwb3RlbnRpYWwgdWludDMyXG4gIC8vIGNvZXJjaW9uIGZhaWwgYmVsb3cuXG4gIGlmIChzdGFydCA+IHRoaXMubGVuZ3RoKSB7XG4gICAgcmV0dXJuICcnXG4gIH1cblxuICBpZiAoZW5kID09PSB1bmRlZmluZWQgfHwgZW5kID4gdGhpcy5sZW5ndGgpIHtcbiAgICBlbmQgPSB0aGlzLmxlbmd0aFxuICB9XG5cbiAgaWYgKGVuZCA8PSAwKSB7XG4gICAgcmV0dXJuICcnXG4gIH1cblxuICAvLyBGb3JjZSBjb2Vyc2lvbiB0byB1aW50MzIuIFRoaXMgd2lsbCBhbHNvIGNvZXJjZSBmYWxzZXkvTmFOIHZhbHVlcyB0byAwLlxuICBlbmQgPj4+PSAwXG4gIHN0YXJ0ID4+Pj0gMFxuXG4gIGlmIChlbmQgPD0gc3RhcnQpIHtcbiAgICByZXR1cm4gJydcbiAgfVxuXG4gIGlmICghZW5jb2RpbmcpIGVuY29kaW5nID0gJ3V0ZjgnXG5cbiAgd2hpbGUgKHRydWUpIHtcbiAgICBzd2l0Y2ggKGVuY29kaW5nKSB7XG4gICAgICBjYXNlICdoZXgnOlxuICAgICAgICByZXR1cm4gaGV4U2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAndXRmOCc6XG4gICAgICBjYXNlICd1dGYtOCc6XG4gICAgICAgIHJldHVybiB1dGY4U2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAnYXNjaWknOlxuICAgICAgICByZXR1cm4gYXNjaWlTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICdsYXRpbjEnOlxuICAgICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgICAgcmV0dXJuIGxhdGluMVNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICAgIHJldHVybiBiYXNlNjRTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICd1Y3MyJzpcbiAgICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgICByZXR1cm4gdXRmMTZsZVNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmIChsb3dlcmVkQ2FzZSkgdGhyb3cgbmV3IFR5cGVFcnJvcignVW5rbm93biBlbmNvZGluZzogJyArIGVuY29kaW5nKVxuICAgICAgICBlbmNvZGluZyA9IChlbmNvZGluZyArICcnKS50b0xvd2VyQ2FzZSgpXG4gICAgICAgIGxvd2VyZWRDYXNlID0gdHJ1ZVxuICAgIH1cbiAgfVxufVxuXG4vLyBUaGlzIHByb3BlcnR5IGlzIHVzZWQgYnkgYEJ1ZmZlci5pc0J1ZmZlcmAgKGFuZCB0aGUgYGlzLWJ1ZmZlcmAgbnBtIHBhY2thZ2UpXG4vLyB0byBkZXRlY3QgYSBCdWZmZXIgaW5zdGFuY2UuIEl0J3Mgbm90IHBvc3NpYmxlIHRvIHVzZSBgaW5zdGFuY2VvZiBCdWZmZXJgXG4vLyByZWxpYWJseSBpbiBhIGJyb3dzZXJpZnkgY29udGV4dCBiZWNhdXNlIHRoZXJlIGNvdWxkIGJlIG11bHRpcGxlIGRpZmZlcmVudFxuLy8gY29waWVzIG9mIHRoZSAnYnVmZmVyJyBwYWNrYWdlIGluIHVzZS4gVGhpcyBtZXRob2Qgd29ya3MgZXZlbiBmb3IgQnVmZmVyXG4vLyBpbnN0YW5jZXMgdGhhdCB3ZXJlIGNyZWF0ZWQgZnJvbSBhbm90aGVyIGNvcHkgb2YgdGhlIGBidWZmZXJgIHBhY2thZ2UuXG4vLyBTZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9mZXJvc3MvYnVmZmVyL2lzc3Vlcy8xNTRcbkJ1ZmZlci5wcm90b3R5cGUuX2lzQnVmZmVyID0gdHJ1ZVxuXG5mdW5jdGlvbiBzd2FwIChiLCBuLCBtKSB7XG4gIHZhciBpID0gYltuXVxuICBiW25dID0gYlttXVxuICBiW21dID0gaVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnN3YXAxNiA9IGZ1bmN0aW9uIHN3YXAxNiAoKSB7XG4gIHZhciBsZW4gPSB0aGlzLmxlbmd0aFxuICBpZiAobGVuICUgMiAhPT0gMCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdCdWZmZXIgc2l6ZSBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgMTYtYml0cycpXG4gIH1cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkgKz0gMikge1xuICAgIHN3YXAodGhpcywgaSwgaSArIDEpXG4gIH1cbiAgcmV0dXJuIHRoaXNcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5zd2FwMzIgPSBmdW5jdGlvbiBzd2FwMzIgKCkge1xuICB2YXIgbGVuID0gdGhpcy5sZW5ndGhcbiAgaWYgKGxlbiAlIDQgIT09IDApIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignQnVmZmVyIHNpemUgbXVzdCBiZSBhIG11bHRpcGxlIG9mIDMyLWJpdHMnKVxuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpICs9IDQpIHtcbiAgICBzd2FwKHRoaXMsIGksIGkgKyAzKVxuICAgIHN3YXAodGhpcywgaSArIDEsIGkgKyAyKVxuICB9XG4gIHJldHVybiB0aGlzXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuc3dhcDY0ID0gZnVuY3Rpb24gc3dhcDY0ICgpIHtcbiAgdmFyIGxlbiA9IHRoaXMubGVuZ3RoXG4gIGlmIChsZW4gJSA4ICE9PSAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0J1ZmZlciBzaXplIG11c3QgYmUgYSBtdWx0aXBsZSBvZiA2NC1iaXRzJylcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSArPSA4KSB7XG4gICAgc3dhcCh0aGlzLCBpLCBpICsgNylcbiAgICBzd2FwKHRoaXMsIGkgKyAxLCBpICsgNilcbiAgICBzd2FwKHRoaXMsIGkgKyAyLCBpICsgNSlcbiAgICBzd2FwKHRoaXMsIGkgKyAzLCBpICsgNClcbiAgfVxuICByZXR1cm4gdGhpc1xufVxuXG5CdWZmZXIucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gdG9TdHJpbmcgKCkge1xuICB2YXIgbGVuZ3RoID0gdGhpcy5sZW5ndGhcbiAgaWYgKGxlbmd0aCA9PT0gMCkgcmV0dXJuICcnXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSByZXR1cm4gdXRmOFNsaWNlKHRoaXMsIDAsIGxlbmd0aClcbiAgcmV0dXJuIHNsb3dUb1N0cmluZy5hcHBseSh0aGlzLCBhcmd1bWVudHMpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUudG9Mb2NhbGVTdHJpbmcgPSBCdWZmZXIucHJvdG90eXBlLnRvU3RyaW5nXG5cbkJ1ZmZlci5wcm90b3R5cGUuZXF1YWxzID0gZnVuY3Rpb24gZXF1YWxzIChiKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudCBtdXN0IGJlIGEgQnVmZmVyJylcbiAgaWYgKHRoaXMgPT09IGIpIHJldHVybiB0cnVlXG4gIHJldHVybiBCdWZmZXIuY29tcGFyZSh0aGlzLCBiKSA9PT0gMFxufVxuXG5CdWZmZXIucHJvdG90eXBlLmluc3BlY3QgPSBmdW5jdGlvbiBpbnNwZWN0ICgpIHtcbiAgdmFyIHN0ciA9ICcnXG4gIHZhciBtYXggPSBleHBvcnRzLklOU1BFQ1RfTUFYX0JZVEVTXG4gIHN0ciA9IHRoaXMudG9TdHJpbmcoJ2hleCcsIDAsIG1heCkucmVwbGFjZSgvKC57Mn0pL2csICckMSAnKS50cmltKClcbiAgaWYgKHRoaXMubGVuZ3RoID4gbWF4KSBzdHIgKz0gJyAuLi4gJ1xuICByZXR1cm4gJzxCdWZmZXIgJyArIHN0ciArICc+J1xufVxuXG5CdWZmZXIucHJvdG90eXBlLmNvbXBhcmUgPSBmdW5jdGlvbiBjb21wYXJlICh0YXJnZXQsIHN0YXJ0LCBlbmQsIHRoaXNTdGFydCwgdGhpc0VuZCkge1xuICBpZiAoaXNJbnN0YW5jZSh0YXJnZXQsIFVpbnQ4QXJyYXkpKSB7XG4gICAgdGFyZ2V0ID0gQnVmZmVyLmZyb20odGFyZ2V0LCB0YXJnZXQub2Zmc2V0LCB0YXJnZXQuYnl0ZUxlbmd0aClcbiAgfVxuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcih0YXJnZXQpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgICdUaGUgXCJ0YXJnZXRcIiBhcmd1bWVudCBtdXN0IGJlIG9uZSBvZiB0eXBlIEJ1ZmZlciBvciBVaW50OEFycmF5LiAnICtcbiAgICAgICdSZWNlaXZlZCB0eXBlICcgKyAodHlwZW9mIHRhcmdldClcbiAgICApXG4gIH1cblxuICBpZiAoc3RhcnQgPT09IHVuZGVmaW5lZCkge1xuICAgIHN0YXJ0ID0gMFxuICB9XG4gIGlmIChlbmQgPT09IHVuZGVmaW5lZCkge1xuICAgIGVuZCA9IHRhcmdldCA/IHRhcmdldC5sZW5ndGggOiAwXG4gIH1cbiAgaWYgKHRoaXNTdGFydCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgdGhpc1N0YXJ0ID0gMFxuICB9XG4gIGlmICh0aGlzRW5kID09PSB1bmRlZmluZWQpIHtcbiAgICB0aGlzRW5kID0gdGhpcy5sZW5ndGhcbiAgfVxuXG4gIGlmIChzdGFydCA8IDAgfHwgZW5kID4gdGFyZ2V0Lmxlbmd0aCB8fCB0aGlzU3RhcnQgPCAwIHx8IHRoaXNFbmQgPiB0aGlzLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdvdXQgb2YgcmFuZ2UgaW5kZXgnKVxuICB9XG5cbiAgaWYgKHRoaXNTdGFydCA+PSB0aGlzRW5kICYmIHN0YXJ0ID49IGVuZCkge1xuICAgIHJldHVybiAwXG4gIH1cbiAgaWYgKHRoaXNTdGFydCA+PSB0aGlzRW5kKSB7XG4gICAgcmV0dXJuIC0xXG4gIH1cbiAgaWYgKHN0YXJ0ID49IGVuZCkge1xuICAgIHJldHVybiAxXG4gIH1cblxuICBzdGFydCA+Pj49IDBcbiAgZW5kID4+Pj0gMFxuICB0aGlzU3RhcnQgPj4+PSAwXG4gIHRoaXNFbmQgPj4+PSAwXG5cbiAgaWYgKHRoaXMgPT09IHRhcmdldCkgcmV0dXJuIDBcblxuICB2YXIgeCA9IHRoaXNFbmQgLSB0aGlzU3RhcnRcbiAgdmFyIHkgPSBlbmQgLSBzdGFydFxuICB2YXIgbGVuID0gTWF0aC5taW4oeCwgeSlcblxuICB2YXIgdGhpc0NvcHkgPSB0aGlzLnNsaWNlKHRoaXNTdGFydCwgdGhpc0VuZClcbiAgdmFyIHRhcmdldENvcHkgPSB0YXJnZXQuc2xpY2Uoc3RhcnQsIGVuZClcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKSB7XG4gICAgaWYgKHRoaXNDb3B5W2ldICE9PSB0YXJnZXRDb3B5W2ldKSB7XG4gICAgICB4ID0gdGhpc0NvcHlbaV1cbiAgICAgIHkgPSB0YXJnZXRDb3B5W2ldXG4gICAgICBicmVha1xuICAgIH1cbiAgfVxuXG4gIGlmICh4IDwgeSkgcmV0dXJuIC0xXG4gIGlmICh5IDwgeCkgcmV0dXJuIDFcbiAgcmV0dXJuIDBcbn1cblxuLy8gRmluZHMgZWl0aGVyIHRoZSBmaXJzdCBpbmRleCBvZiBgdmFsYCBpbiBgYnVmZmVyYCBhdCBvZmZzZXQgPj0gYGJ5dGVPZmZzZXRgLFxuLy8gT1IgdGhlIGxhc3QgaW5kZXggb2YgYHZhbGAgaW4gYGJ1ZmZlcmAgYXQgb2Zmc2V0IDw9IGBieXRlT2Zmc2V0YC5cbi8vXG4vLyBBcmd1bWVudHM6XG4vLyAtIGJ1ZmZlciAtIGEgQnVmZmVyIHRvIHNlYXJjaFxuLy8gLSB2YWwgLSBhIHN0cmluZywgQnVmZmVyLCBvciBudW1iZXJcbi8vIC0gYnl0ZU9mZnNldCAtIGFuIGluZGV4IGludG8gYGJ1ZmZlcmA7IHdpbGwgYmUgY2xhbXBlZCB0byBhbiBpbnQzMlxuLy8gLSBlbmNvZGluZyAtIGFuIG9wdGlvbmFsIGVuY29kaW5nLCByZWxldmFudCBpcyB2YWwgaXMgYSBzdHJpbmdcbi8vIC0gZGlyIC0gdHJ1ZSBmb3IgaW5kZXhPZiwgZmFsc2UgZm9yIGxhc3RJbmRleE9mXG5mdW5jdGlvbiBiaWRpcmVjdGlvbmFsSW5kZXhPZiAoYnVmZmVyLCB2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nLCBkaXIpIHtcbiAgLy8gRW1wdHkgYnVmZmVyIG1lYW5zIG5vIG1hdGNoXG4gIGlmIChidWZmZXIubGVuZ3RoID09PSAwKSByZXR1cm4gLTFcblxuICAvLyBOb3JtYWxpemUgYnl0ZU9mZnNldFxuICBpZiAodHlwZW9mIGJ5dGVPZmZzZXQgPT09ICdzdHJpbmcnKSB7XG4gICAgZW5jb2RpbmcgPSBieXRlT2Zmc2V0XG4gICAgYnl0ZU9mZnNldCA9IDBcbiAgfSBlbHNlIGlmIChieXRlT2Zmc2V0ID4gMHg3ZmZmZmZmZikge1xuICAgIGJ5dGVPZmZzZXQgPSAweDdmZmZmZmZmXG4gIH0gZWxzZSBpZiAoYnl0ZU9mZnNldCA8IC0weDgwMDAwMDAwKSB7XG4gICAgYnl0ZU9mZnNldCA9IC0weDgwMDAwMDAwXG4gIH1cbiAgYnl0ZU9mZnNldCA9ICtieXRlT2Zmc2V0IC8vIENvZXJjZSB0byBOdW1iZXIuXG4gIGlmIChudW1iZXJJc05hTihieXRlT2Zmc2V0KSkge1xuICAgIC8vIGJ5dGVPZmZzZXQ6IGl0IGl0J3MgdW5kZWZpbmVkLCBudWxsLCBOYU4sIFwiZm9vXCIsIGV0Yywgc2VhcmNoIHdob2xlIGJ1ZmZlclxuICAgIGJ5dGVPZmZzZXQgPSBkaXIgPyAwIDogKGJ1ZmZlci5sZW5ndGggLSAxKVxuICB9XG5cbiAgLy8gTm9ybWFsaXplIGJ5dGVPZmZzZXQ6IG5lZ2F0aXZlIG9mZnNldHMgc3RhcnQgZnJvbSB0aGUgZW5kIG9mIHRoZSBidWZmZXJcbiAgaWYgKGJ5dGVPZmZzZXQgPCAwKSBieXRlT2Zmc2V0ID0gYnVmZmVyLmxlbmd0aCArIGJ5dGVPZmZzZXRcbiAgaWYgKGJ5dGVPZmZzZXQgPj0gYnVmZmVyLmxlbmd0aCkge1xuICAgIGlmIChkaXIpIHJldHVybiAtMVxuICAgIGVsc2UgYnl0ZU9mZnNldCA9IGJ1ZmZlci5sZW5ndGggLSAxXG4gIH0gZWxzZSBpZiAoYnl0ZU9mZnNldCA8IDApIHtcbiAgICBpZiAoZGlyKSBieXRlT2Zmc2V0ID0gMFxuICAgIGVsc2UgcmV0dXJuIC0xXG4gIH1cblxuICAvLyBOb3JtYWxpemUgdmFsXG4gIGlmICh0eXBlb2YgdmFsID09PSAnc3RyaW5nJykge1xuICAgIHZhbCA9IEJ1ZmZlci5mcm9tKHZhbCwgZW5jb2RpbmcpXG4gIH1cblxuICAvLyBGaW5hbGx5LCBzZWFyY2ggZWl0aGVyIGluZGV4T2YgKGlmIGRpciBpcyB0cnVlKSBvciBsYXN0SW5kZXhPZlxuICBpZiAoQnVmZmVyLmlzQnVmZmVyKHZhbCkpIHtcbiAgICAvLyBTcGVjaWFsIGNhc2U6IGxvb2tpbmcgZm9yIGVtcHR5IHN0cmluZy9idWZmZXIgYWx3YXlzIGZhaWxzXG4gICAgaWYgKHZhbC5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiAtMVxuICAgIH1cbiAgICByZXR1cm4gYXJyYXlJbmRleE9mKGJ1ZmZlciwgdmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgZGlyKVxuICB9IGVsc2UgaWYgKHR5cGVvZiB2YWwgPT09ICdudW1iZXInKSB7XG4gICAgdmFsID0gdmFsICYgMHhGRiAvLyBTZWFyY2ggZm9yIGEgYnl0ZSB2YWx1ZSBbMC0yNTVdXG4gICAgaWYgKHR5cGVvZiBVaW50OEFycmF5LnByb3RvdHlwZS5pbmRleE9mID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBpZiAoZGlyKSB7XG4gICAgICAgIHJldHVybiBVaW50OEFycmF5LnByb3RvdHlwZS5pbmRleE9mLmNhbGwoYnVmZmVyLCB2YWwsIGJ5dGVPZmZzZXQpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gVWludDhBcnJheS5wcm90b3R5cGUubGFzdEluZGV4T2YuY2FsbChidWZmZXIsIHZhbCwgYnl0ZU9mZnNldClcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGFycmF5SW5kZXhPZihidWZmZXIsIFsgdmFsIF0sIGJ5dGVPZmZzZXQsIGVuY29kaW5nLCBkaXIpXG4gIH1cblxuICB0aHJvdyBuZXcgVHlwZUVycm9yKCd2YWwgbXVzdCBiZSBzdHJpbmcsIG51bWJlciBvciBCdWZmZXInKVxufVxuXG5mdW5jdGlvbiBhcnJheUluZGV4T2YgKGFyciwgdmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgZGlyKSB7XG4gIHZhciBpbmRleFNpemUgPSAxXG4gIHZhciBhcnJMZW5ndGggPSBhcnIubGVuZ3RoXG4gIHZhciB2YWxMZW5ndGggPSB2YWwubGVuZ3RoXG5cbiAgaWYgKGVuY29kaW5nICE9PSB1bmRlZmluZWQpIHtcbiAgICBlbmNvZGluZyA9IFN0cmluZyhlbmNvZGluZykudG9Mb3dlckNhc2UoKVxuICAgIGlmIChlbmNvZGluZyA9PT0gJ3VjczInIHx8IGVuY29kaW5nID09PSAndWNzLTInIHx8XG4gICAgICAgIGVuY29kaW5nID09PSAndXRmMTZsZScgfHwgZW5jb2RpbmcgPT09ICd1dGYtMTZsZScpIHtcbiAgICAgIGlmIChhcnIubGVuZ3RoIDwgMiB8fCB2YWwubGVuZ3RoIDwgMikge1xuICAgICAgICByZXR1cm4gLTFcbiAgICAgIH1cbiAgICAgIGluZGV4U2l6ZSA9IDJcbiAgICAgIGFyckxlbmd0aCAvPSAyXG4gICAgICB2YWxMZW5ndGggLz0gMlxuICAgICAgYnl0ZU9mZnNldCAvPSAyXG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gcmVhZCAoYnVmLCBpKSB7XG4gICAgaWYgKGluZGV4U2l6ZSA9PT0gMSkge1xuICAgICAgcmV0dXJuIGJ1ZltpXVxuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gYnVmLnJlYWRVSW50MTZCRShpICogaW5kZXhTaXplKVxuICAgIH1cbiAgfVxuXG4gIHZhciBpXG4gIGlmIChkaXIpIHtcbiAgICB2YXIgZm91bmRJbmRleCA9IC0xXG4gICAgZm9yIChpID0gYnl0ZU9mZnNldDsgaSA8IGFyckxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAocmVhZChhcnIsIGkpID09PSByZWFkKHZhbCwgZm91bmRJbmRleCA9PT0gLTEgPyAwIDogaSAtIGZvdW5kSW5kZXgpKSB7XG4gICAgICAgIGlmIChmb3VuZEluZGV4ID09PSAtMSkgZm91bmRJbmRleCA9IGlcbiAgICAgICAgaWYgKGkgLSBmb3VuZEluZGV4ICsgMSA9PT0gdmFsTGVuZ3RoKSByZXR1cm4gZm91bmRJbmRleCAqIGluZGV4U2l6ZVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGZvdW5kSW5kZXggIT09IC0xKSBpIC09IGkgLSBmb3VuZEluZGV4XG4gICAgICAgIGZvdW5kSW5kZXggPSAtMVxuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBpZiAoYnl0ZU9mZnNldCArIHZhbExlbmd0aCA+IGFyckxlbmd0aCkgYnl0ZU9mZnNldCA9IGFyckxlbmd0aCAtIHZhbExlbmd0aFxuICAgIGZvciAoaSA9IGJ5dGVPZmZzZXQ7IGkgPj0gMDsgaS0tKSB7XG4gICAgICB2YXIgZm91bmQgPSB0cnVlXG4gICAgICBmb3IgKHZhciBqID0gMDsgaiA8IHZhbExlbmd0aDsgaisrKSB7XG4gICAgICAgIGlmIChyZWFkKGFyciwgaSArIGopICE9PSByZWFkKHZhbCwgaikpIHtcbiAgICAgICAgICBmb3VuZCA9IGZhbHNlXG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGZvdW5kKSByZXR1cm4gaVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiAtMVxufVxuXG5CdWZmZXIucHJvdG90eXBlLmluY2x1ZGVzID0gZnVuY3Rpb24gaW5jbHVkZXMgKHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcpIHtcbiAgcmV0dXJuIHRoaXMuaW5kZXhPZih2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nKSAhPT0gLTFcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5pbmRleE9mID0gZnVuY3Rpb24gaW5kZXhPZiAodmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZykge1xuICByZXR1cm4gYmlkaXJlY3Rpb25hbEluZGV4T2YodGhpcywgdmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgdHJ1ZSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5sYXN0SW5kZXhPZiA9IGZ1bmN0aW9uIGxhc3RJbmRleE9mICh2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nKSB7XG4gIHJldHVybiBiaWRpcmVjdGlvbmFsSW5kZXhPZih0aGlzLCB2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nLCBmYWxzZSlcbn1cblxuZnVuY3Rpb24gaGV4V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICBvZmZzZXQgPSBOdW1iZXIob2Zmc2V0KSB8fCAwXG4gIHZhciByZW1haW5pbmcgPSBidWYubGVuZ3RoIC0gb2Zmc2V0XG4gIGlmICghbGVuZ3RoKSB7XG4gICAgbGVuZ3RoID0gcmVtYWluaW5nXG4gIH0gZWxzZSB7XG4gICAgbGVuZ3RoID0gTnVtYmVyKGxlbmd0aClcbiAgICBpZiAobGVuZ3RoID4gcmVtYWluaW5nKSB7XG4gICAgICBsZW5ndGggPSByZW1haW5pbmdcbiAgICB9XG4gIH1cblxuICB2YXIgc3RyTGVuID0gc3RyaW5nLmxlbmd0aFxuXG4gIGlmIChsZW5ndGggPiBzdHJMZW4gLyAyKSB7XG4gICAgbGVuZ3RoID0gc3RyTGVuIC8gMlxuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHtcbiAgICB2YXIgcGFyc2VkID0gcGFyc2VJbnQoc3RyaW5nLnN1YnN0cihpICogMiwgMiksIDE2KVxuICAgIGlmIChudW1iZXJJc05hTihwYXJzZWQpKSByZXR1cm4gaVxuICAgIGJ1ZltvZmZzZXQgKyBpXSA9IHBhcnNlZFxuICB9XG4gIHJldHVybiBpXG59XG5cbmZ1bmN0aW9uIHV0ZjhXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBibGl0QnVmZmVyKHV0ZjhUb0J5dGVzKHN0cmluZywgYnVmLmxlbmd0aCAtIG9mZnNldCksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIGFzY2lpV3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYmxpdEJ1ZmZlcihhc2NpaVRvQnl0ZXMoc3RyaW5nKSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gbGF0aW4xV3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYXNjaWlXcml0ZShidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIGJhc2U2NFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGJsaXRCdWZmZXIoYmFzZTY0VG9CeXRlcyhzdHJpbmcpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5mdW5jdGlvbiB1Y3MyV3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYmxpdEJ1ZmZlcih1dGYxNmxlVG9CeXRlcyhzdHJpbmcsIGJ1Zi5sZW5ndGggLSBvZmZzZXQpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24gd3JpdGUgKHN0cmluZywgb2Zmc2V0LCBsZW5ndGgsIGVuY29kaW5nKSB7XG4gIC8vIEJ1ZmZlciN3cml0ZShzdHJpbmcpXG4gIGlmIChvZmZzZXQgPT09IHVuZGVmaW5lZCkge1xuICAgIGVuY29kaW5nID0gJ3V0ZjgnXG4gICAgbGVuZ3RoID0gdGhpcy5sZW5ndGhcbiAgICBvZmZzZXQgPSAwXG4gIC8vIEJ1ZmZlciN3cml0ZShzdHJpbmcsIGVuY29kaW5nKVxuICB9IGVsc2UgaWYgKGxlbmd0aCA9PT0gdW5kZWZpbmVkICYmIHR5cGVvZiBvZmZzZXQgPT09ICdzdHJpbmcnKSB7XG4gICAgZW5jb2RpbmcgPSBvZmZzZXRcbiAgICBsZW5ndGggPSB0aGlzLmxlbmd0aFxuICAgIG9mZnNldCA9IDBcbiAgLy8gQnVmZmVyI3dyaXRlKHN0cmluZywgb2Zmc2V0WywgbGVuZ3RoXVssIGVuY29kaW5nXSlcbiAgfSBlbHNlIGlmIChpc0Zpbml0ZShvZmZzZXQpKSB7XG4gICAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gICAgaWYgKGlzRmluaXRlKGxlbmd0aCkpIHtcbiAgICAgIGxlbmd0aCA9IGxlbmd0aCA+Pj4gMFxuICAgICAgaWYgKGVuY29kaW5nID09PSB1bmRlZmluZWQpIGVuY29kaW5nID0gJ3V0ZjgnXG4gICAgfSBlbHNlIHtcbiAgICAgIGVuY29kaW5nID0gbGVuZ3RoXG4gICAgICBsZW5ndGggPSB1bmRlZmluZWRcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgJ0J1ZmZlci53cml0ZShzdHJpbmcsIGVuY29kaW5nLCBvZmZzZXRbLCBsZW5ndGhdKSBpcyBubyBsb25nZXIgc3VwcG9ydGVkJ1xuICAgIClcbiAgfVxuXG4gIHZhciByZW1haW5pbmcgPSB0aGlzLmxlbmd0aCAtIG9mZnNldFxuICBpZiAobGVuZ3RoID09PSB1bmRlZmluZWQgfHwgbGVuZ3RoID4gcmVtYWluaW5nKSBsZW5ndGggPSByZW1haW5pbmdcblxuICBpZiAoKHN0cmluZy5sZW5ndGggPiAwICYmIChsZW5ndGggPCAwIHx8IG9mZnNldCA8IDApKSB8fCBvZmZzZXQgPiB0aGlzLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdBdHRlbXB0IHRvIHdyaXRlIG91dHNpZGUgYnVmZmVyIGJvdW5kcycpXG4gIH1cblxuICBpZiAoIWVuY29kaW5nKSBlbmNvZGluZyA9ICd1dGY4J1xuXG4gIHZhciBsb3dlcmVkQ2FzZSA9IGZhbHNlXG4gIGZvciAoOzspIHtcbiAgICBzd2l0Y2ggKGVuY29kaW5nKSB7XG4gICAgICBjYXNlICdoZXgnOlxuICAgICAgICByZXR1cm4gaGV4V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAndXRmOCc6XG4gICAgICBjYXNlICd1dGYtOCc6XG4gICAgICAgIHJldHVybiB1dGY4V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAnYXNjaWknOlxuICAgICAgICByZXR1cm4gYXNjaWlXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICdsYXRpbjEnOlxuICAgICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgICAgcmV0dXJuIGxhdGluMVdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICAgIC8vIFdhcm5pbmc6IG1heExlbmd0aCBub3QgdGFrZW4gaW50byBhY2NvdW50IGluIGJhc2U2NFdyaXRlXG4gICAgICAgIHJldHVybiBiYXNlNjRXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICd1Y3MyJzpcbiAgICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgICByZXR1cm4gdWNzMldyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmIChsb3dlcmVkQ2FzZSkgdGhyb3cgbmV3IFR5cGVFcnJvcignVW5rbm93biBlbmNvZGluZzogJyArIGVuY29kaW5nKVxuICAgICAgICBlbmNvZGluZyA9ICgnJyArIGVuY29kaW5nKS50b0xvd2VyQ2FzZSgpXG4gICAgICAgIGxvd2VyZWRDYXNlID0gdHJ1ZVxuICAgIH1cbiAgfVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTiAoKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogJ0J1ZmZlcicsXG4gICAgZGF0YTogQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwodGhpcy5fYXJyIHx8IHRoaXMsIDApXG4gIH1cbn1cblxuZnVuY3Rpb24gYmFzZTY0U2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICBpZiAoc3RhcnQgPT09IDAgJiYgZW5kID09PSBidWYubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGJhc2U2NC5mcm9tQnl0ZUFycmF5KGJ1ZilcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gYmFzZTY0LmZyb21CeXRlQXJyYXkoYnVmLnNsaWNlKHN0YXJ0LCBlbmQpKVxuICB9XG59XG5cbmZ1bmN0aW9uIHV0ZjhTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIGVuZCA9IE1hdGgubWluKGJ1Zi5sZW5ndGgsIGVuZClcbiAgdmFyIHJlcyA9IFtdXG5cbiAgdmFyIGkgPSBzdGFydFxuICB3aGlsZSAoaSA8IGVuZCkge1xuICAgIHZhciBmaXJzdEJ5dGUgPSBidWZbaV1cbiAgICB2YXIgY29kZVBvaW50ID0gbnVsbFxuICAgIHZhciBieXRlc1BlclNlcXVlbmNlID0gKGZpcnN0Qnl0ZSA+IDB4RUYpID8gNFxuICAgICAgOiAoZmlyc3RCeXRlID4gMHhERikgPyAzXG4gICAgICAgIDogKGZpcnN0Qnl0ZSA+IDB4QkYpID8gMlxuICAgICAgICAgIDogMVxuXG4gICAgaWYgKGkgKyBieXRlc1BlclNlcXVlbmNlIDw9IGVuZCkge1xuICAgICAgdmFyIHNlY29uZEJ5dGUsIHRoaXJkQnl0ZSwgZm91cnRoQnl0ZSwgdGVtcENvZGVQb2ludFxuXG4gICAgICBzd2l0Y2ggKGJ5dGVzUGVyU2VxdWVuY2UpIHtcbiAgICAgICAgY2FzZSAxOlxuICAgICAgICAgIGlmIChmaXJzdEJ5dGUgPCAweDgwKSB7XG4gICAgICAgICAgICBjb2RlUG9pbnQgPSBmaXJzdEJ5dGVcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSAyOlxuICAgICAgICAgIHNlY29uZEJ5dGUgPSBidWZbaSArIDFdXG4gICAgICAgICAgaWYgKChzZWNvbmRCeXRlICYgMHhDMCkgPT09IDB4ODApIHtcbiAgICAgICAgICAgIHRlbXBDb2RlUG9pbnQgPSAoZmlyc3RCeXRlICYgMHgxRikgPDwgMHg2IHwgKHNlY29uZEJ5dGUgJiAweDNGKVxuICAgICAgICAgICAgaWYgKHRlbXBDb2RlUG9pbnQgPiAweDdGKSB7XG4gICAgICAgICAgICAgIGNvZGVQb2ludCA9IHRlbXBDb2RlUG9pbnRcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSAzOlxuICAgICAgICAgIHNlY29uZEJ5dGUgPSBidWZbaSArIDFdXG4gICAgICAgICAgdGhpcmRCeXRlID0gYnVmW2kgKyAyXVxuICAgICAgICAgIGlmICgoc2Vjb25kQnl0ZSAmIDB4QzApID09PSAweDgwICYmICh0aGlyZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCkge1xuICAgICAgICAgICAgdGVtcENvZGVQb2ludCA9IChmaXJzdEJ5dGUgJiAweEYpIDw8IDB4QyB8IChzZWNvbmRCeXRlICYgMHgzRikgPDwgMHg2IHwgKHRoaXJkQnl0ZSAmIDB4M0YpXG4gICAgICAgICAgICBpZiAodGVtcENvZGVQb2ludCA+IDB4N0ZGICYmICh0ZW1wQ29kZVBvaW50IDwgMHhEODAwIHx8IHRlbXBDb2RlUG9pbnQgPiAweERGRkYpKSB7XG4gICAgICAgICAgICAgIGNvZGVQb2ludCA9IHRlbXBDb2RlUG9pbnRcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSA0OlxuICAgICAgICAgIHNlY29uZEJ5dGUgPSBidWZbaSArIDFdXG4gICAgICAgICAgdGhpcmRCeXRlID0gYnVmW2kgKyAyXVxuICAgICAgICAgIGZvdXJ0aEJ5dGUgPSBidWZbaSArIDNdXG4gICAgICAgICAgaWYgKChzZWNvbmRCeXRlICYgMHhDMCkgPT09IDB4ODAgJiYgKHRoaXJkQnl0ZSAmIDB4QzApID09PSAweDgwICYmIChmb3VydGhCeXRlICYgMHhDMCkgPT09IDB4ODApIHtcbiAgICAgICAgICAgIHRlbXBDb2RlUG9pbnQgPSAoZmlyc3RCeXRlICYgMHhGKSA8PCAweDEyIHwgKHNlY29uZEJ5dGUgJiAweDNGKSA8PCAweEMgfCAodGhpcmRCeXRlICYgMHgzRikgPDwgMHg2IHwgKGZvdXJ0aEJ5dGUgJiAweDNGKVxuICAgICAgICAgICAgaWYgKHRlbXBDb2RlUG9pbnQgPiAweEZGRkYgJiYgdGVtcENvZGVQb2ludCA8IDB4MTEwMDAwKSB7XG4gICAgICAgICAgICAgIGNvZGVQb2ludCA9IHRlbXBDb2RlUG9pbnRcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGNvZGVQb2ludCA9PT0gbnVsbCkge1xuICAgICAgLy8gd2UgZGlkIG5vdCBnZW5lcmF0ZSBhIHZhbGlkIGNvZGVQb2ludCBzbyBpbnNlcnQgYVxuICAgICAgLy8gcmVwbGFjZW1lbnQgY2hhciAoVStGRkZEKSBhbmQgYWR2YW5jZSBvbmx5IDEgYnl0ZVxuICAgICAgY29kZVBvaW50ID0gMHhGRkZEXG4gICAgICBieXRlc1BlclNlcXVlbmNlID0gMVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50ID4gMHhGRkZGKSB7XG4gICAgICAvLyBlbmNvZGUgdG8gdXRmMTYgKHN1cnJvZ2F0ZSBwYWlyIGRhbmNlKVxuICAgICAgY29kZVBvaW50IC09IDB4MTAwMDBcbiAgICAgIHJlcy5wdXNoKGNvZGVQb2ludCA+Pj4gMTAgJiAweDNGRiB8IDB4RDgwMClcbiAgICAgIGNvZGVQb2ludCA9IDB4REMwMCB8IGNvZGVQb2ludCAmIDB4M0ZGXG4gICAgfVxuXG4gICAgcmVzLnB1c2goY29kZVBvaW50KVxuICAgIGkgKz0gYnl0ZXNQZXJTZXF1ZW5jZVxuICB9XG5cbiAgcmV0dXJuIGRlY29kZUNvZGVQb2ludHNBcnJheShyZXMpXG59XG5cbi8vIEJhc2VkIG9uIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9hLzIyNzQ3MjcyLzY4MDc0MiwgdGhlIGJyb3dzZXIgd2l0aFxuLy8gdGhlIGxvd2VzdCBsaW1pdCBpcyBDaHJvbWUsIHdpdGggMHgxMDAwMCBhcmdzLlxuLy8gV2UgZ28gMSBtYWduaXR1ZGUgbGVzcywgZm9yIHNhZmV0eVxudmFyIE1BWF9BUkdVTUVOVFNfTEVOR1RIID0gMHgxMDAwXG5cbmZ1bmN0aW9uIGRlY29kZUNvZGVQb2ludHNBcnJheSAoY29kZVBvaW50cykge1xuICB2YXIgbGVuID0gY29kZVBvaW50cy5sZW5ndGhcbiAgaWYgKGxlbiA8PSBNQVhfQVJHVU1FTlRTX0xFTkdUSCkge1xuICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KFN0cmluZywgY29kZVBvaW50cykgLy8gYXZvaWQgZXh0cmEgc2xpY2UoKVxuICB9XG5cbiAgLy8gRGVjb2RlIGluIGNodW5rcyB0byBhdm9pZCBcImNhbGwgc3RhY2sgc2l6ZSBleGNlZWRlZFwiLlxuICB2YXIgcmVzID0gJydcbiAgdmFyIGkgPSAwXG4gIHdoaWxlIChpIDwgbGVuKSB7XG4gICAgcmVzICs9IFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoXG4gICAgICBTdHJpbmcsXG4gICAgICBjb2RlUG9pbnRzLnNsaWNlKGksIGkgKz0gTUFYX0FSR1VNRU5UU19MRU5HVEgpXG4gICAgKVxuICB9XG4gIHJldHVybiByZXNcbn1cblxuZnVuY3Rpb24gYXNjaWlTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciByZXQgPSAnJ1xuICBlbmQgPSBNYXRoLm1pbihidWYubGVuZ3RoLCBlbmQpXG5cbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyArK2kpIHtcbiAgICByZXQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShidWZbaV0gJiAweDdGKVxuICB9XG4gIHJldHVybiByZXRcbn1cblxuZnVuY3Rpb24gbGF0aW4xU2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgcmV0ID0gJydcbiAgZW5kID0gTWF0aC5taW4oYnVmLmxlbmd0aCwgZW5kKVxuXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgKytpKSB7XG4gICAgcmV0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYnVmW2ldKVxuICB9XG4gIHJldHVybiByZXRcbn1cblxuZnVuY3Rpb24gaGV4U2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgbGVuID0gYnVmLmxlbmd0aFxuXG4gIGlmICghc3RhcnQgfHwgc3RhcnQgPCAwKSBzdGFydCA9IDBcbiAgaWYgKCFlbmQgfHwgZW5kIDwgMCB8fCBlbmQgPiBsZW4pIGVuZCA9IGxlblxuXG4gIHZhciBvdXQgPSAnJ1xuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7ICsraSkge1xuICAgIG91dCArPSB0b0hleChidWZbaV0pXG4gIH1cbiAgcmV0dXJuIG91dFxufVxuXG5mdW5jdGlvbiB1dGYxNmxlU2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgYnl0ZXMgPSBidWYuc2xpY2Uoc3RhcnQsIGVuZClcbiAgdmFyIHJlcyA9ICcnXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYnl0ZXMubGVuZ3RoOyBpICs9IDIpIHtcbiAgICByZXMgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShieXRlc1tpXSArIChieXRlc1tpICsgMV0gKiAyNTYpKVxuICB9XG4gIHJldHVybiByZXNcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5zbGljZSA9IGZ1bmN0aW9uIHNsaWNlIChzdGFydCwgZW5kKSB7XG4gIHZhciBsZW4gPSB0aGlzLmxlbmd0aFxuICBzdGFydCA9IH5+c3RhcnRcbiAgZW5kID0gZW5kID09PSB1bmRlZmluZWQgPyBsZW4gOiB+fmVuZFxuXG4gIGlmIChzdGFydCA8IDApIHtcbiAgICBzdGFydCArPSBsZW5cbiAgICBpZiAoc3RhcnQgPCAwKSBzdGFydCA9IDBcbiAgfSBlbHNlIGlmIChzdGFydCA+IGxlbikge1xuICAgIHN0YXJ0ID0gbGVuXG4gIH1cblxuICBpZiAoZW5kIDwgMCkge1xuICAgIGVuZCArPSBsZW5cbiAgICBpZiAoZW5kIDwgMCkgZW5kID0gMFxuICB9IGVsc2UgaWYgKGVuZCA+IGxlbikge1xuICAgIGVuZCA9IGxlblxuICB9XG5cbiAgaWYgKGVuZCA8IHN0YXJ0KSBlbmQgPSBzdGFydFxuXG4gIHZhciBuZXdCdWYgPSB0aGlzLnN1YmFycmF5KHN0YXJ0LCBlbmQpXG4gIC8vIFJldHVybiBhbiBhdWdtZW50ZWQgYFVpbnQ4QXJyYXlgIGluc3RhbmNlXG4gIG5ld0J1Zi5fX3Byb3RvX18gPSBCdWZmZXIucHJvdG90eXBlXG4gIHJldHVybiBuZXdCdWZcbn1cblxuLypcbiAqIE5lZWQgdG8gbWFrZSBzdXJlIHRoYXQgYnVmZmVyIGlzbid0IHRyeWluZyB0byB3cml0ZSBvdXQgb2YgYm91bmRzLlxuICovXG5mdW5jdGlvbiBjaGVja09mZnNldCAob2Zmc2V0LCBleHQsIGxlbmd0aCkge1xuICBpZiAoKG9mZnNldCAlIDEpICE9PSAwIHx8IG9mZnNldCA8IDApIHRocm93IG5ldyBSYW5nZUVycm9yKCdvZmZzZXQgaXMgbm90IHVpbnQnKVxuICBpZiAob2Zmc2V0ICsgZXh0ID4gbGVuZ3RoKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignVHJ5aW5nIHRvIGFjY2VzcyBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnRMRSA9IGZ1bmN0aW9uIHJlYWRVSW50TEUgKG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgYnl0ZUxlbmd0aCwgdGhpcy5sZW5ndGgpXG5cbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0XVxuICB2YXIgbXVsID0gMVxuICB2YXIgaSA9IDBcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyBpXSAqIG11bFxuICB9XG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50QkUgPSBmdW5jdGlvbiByZWFkVUludEJFIChvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcbiAgfVxuXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldCArIC0tYnl0ZUxlbmd0aF1cbiAgdmFyIG11bCA9IDFcbiAgd2hpbGUgKGJ5dGVMZW5ndGggPiAwICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgLS1ieXRlTGVuZ3RoXSAqIG11bFxuICB9XG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50OCA9IGZ1bmN0aW9uIHJlYWRVSW50OCAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAxLCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIHRoaXNbb2Zmc2V0XVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MTZMRSA9IGZ1bmN0aW9uIHJlYWRVSW50MTZMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAyLCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIHRoaXNbb2Zmc2V0XSB8ICh0aGlzW29mZnNldCArIDFdIDw8IDgpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQxNkJFID0gZnVuY3Rpb24gcmVhZFVJbnQxNkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSA8PCA4KSB8IHRoaXNbb2Zmc2V0ICsgMV1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDMyTEUgPSBmdW5jdGlvbiByZWFkVUludDMyTEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICgodGhpc1tvZmZzZXRdKSB8XG4gICAgICAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KSB8XG4gICAgICAodGhpc1tvZmZzZXQgKyAyXSA8PCAxNikpICtcbiAgICAgICh0aGlzW29mZnNldCArIDNdICogMHgxMDAwMDAwKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MzJCRSA9IGZ1bmN0aW9uIHJlYWRVSW50MzJCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSAqIDB4MTAwMDAwMCkgK1xuICAgICgodGhpc1tvZmZzZXQgKyAxXSA8PCAxNikgfFxuICAgICh0aGlzW29mZnNldCArIDJdIDw8IDgpIHxcbiAgICB0aGlzW29mZnNldCArIDNdKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnRMRSA9IGZ1bmN0aW9uIHJlYWRJbnRMRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcblxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXRdXG4gIHZhciBtdWwgPSAxXG4gIHZhciBpID0gMFxuICB3aGlsZSAoKytpIDwgYnl0ZUxlbmd0aCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHZhbCArPSB0aGlzW29mZnNldCArIGldICogbXVsXG4gIH1cbiAgbXVsICo9IDB4ODBcblxuICBpZiAodmFsID49IG11bCkgdmFsIC09IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50QkUgPSBmdW5jdGlvbiByZWFkSW50QkUgKG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgYnl0ZUxlbmd0aCwgdGhpcy5sZW5ndGgpXG5cbiAgdmFyIGkgPSBieXRlTGVuZ3RoXG4gIHZhciBtdWwgPSAxXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldCArIC0taV1cbiAgd2hpbGUgKGkgPiAwICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgLS1pXSAqIG11bFxuICB9XG4gIG11bCAqPSAweDgwXG5cbiAgaWYgKHZhbCA+PSBtdWwpIHZhbCAtPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aClcblxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDggPSBmdW5jdGlvbiByZWFkSW50OCAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAxLCB0aGlzLmxlbmd0aClcbiAgaWYgKCEodGhpc1tvZmZzZXRdICYgMHg4MCkpIHJldHVybiAodGhpc1tvZmZzZXRdKVxuICByZXR1cm4gKCgweGZmIC0gdGhpc1tvZmZzZXRdICsgMSkgKiAtMSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MTZMRSA9IGZ1bmN0aW9uIHJlYWRJbnQxNkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXRdIHwgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgOClcbiAgcmV0dXJuICh2YWwgJiAweDgwMDApID8gdmFsIHwgMHhGRkZGMDAwMCA6IHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQxNkJFID0gZnVuY3Rpb24gcmVhZEludDE2QkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldCArIDFdIHwgKHRoaXNbb2Zmc2V0XSA8PCA4KVxuICByZXR1cm4gKHZhbCAmIDB4ODAwMCkgPyB2YWwgfCAweEZGRkYwMDAwIDogdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDMyTEUgPSBmdW5jdGlvbiByZWFkSW50MzJMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSkgfFxuICAgICh0aGlzW29mZnNldCArIDFdIDw8IDgpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAyXSA8PCAxNikgfFxuICAgICh0aGlzW29mZnNldCArIDNdIDw8IDI0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQzMkJFID0gZnVuY3Rpb24gcmVhZEludDMyQkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICh0aGlzW29mZnNldF0gPDwgMjQpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAxXSA8PCAxNikgfFxuICAgICh0aGlzW29mZnNldCArIDJdIDw8IDgpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAzXSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRmxvYXRMRSA9IGZ1bmN0aW9uIHJlYWRGbG9hdExFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gaWVlZTc1NC5yZWFkKHRoaXMsIG9mZnNldCwgdHJ1ZSwgMjMsIDQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEZsb2F0QkUgPSBmdW5jdGlvbiByZWFkRmxvYXRCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIGZhbHNlLCAyMywgNClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRG91YmxlTEUgPSBmdW5jdGlvbiByZWFkRG91YmxlTEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgOCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCB0cnVlLCA1MiwgOClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRG91YmxlQkUgPSBmdW5jdGlvbiByZWFkRG91YmxlQkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgOCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCBmYWxzZSwgNTIsIDgpXG59XG5cbmZ1bmN0aW9uIGNoZWNrSW50IChidWYsIHZhbHVlLCBvZmZzZXQsIGV4dCwgbWF4LCBtaW4pIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYnVmKSkgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJidWZmZXJcIiBhcmd1bWVudCBtdXN0IGJlIGEgQnVmZmVyIGluc3RhbmNlJylcbiAgaWYgKHZhbHVlID4gbWF4IHx8IHZhbHVlIDwgbWluKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignXCJ2YWx1ZVwiIGFyZ3VtZW50IGlzIG91dCBvZiBib3VuZHMnKVxuICBpZiAob2Zmc2V0ICsgZXh0ID4gYnVmLmxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0luZGV4IG91dCBvZiByYW5nZScpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50TEUgPSBmdW5jdGlvbiB3cml0ZVVJbnRMRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICB2YXIgbWF4Qnl0ZXMgPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aCkgLSAxXG4gICAgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbWF4Qnl0ZXMsIDApXG4gIH1cblxuICB2YXIgbXVsID0gMVxuICB2YXIgaSA9IDBcbiAgdGhpc1tvZmZzZXRdID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdGhpc1tvZmZzZXQgKyBpXSA9ICh2YWx1ZSAvIG11bCkgJiAweEZGXG4gIH1cblxuICByZXR1cm4gb2Zmc2V0ICsgYnl0ZUxlbmd0aFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludEJFID0gZnVuY3Rpb24gd3JpdGVVSW50QkUgKHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgdmFyIG1heEJ5dGVzID0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpIC0gMVxuICAgIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG1heEJ5dGVzLCAwKVxuICB9XG5cbiAgdmFyIGkgPSBieXRlTGVuZ3RoIC0gMVxuICB2YXIgbXVsID0gMVxuICB0aGlzW29mZnNldCArIGldID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgtLWkgPj0gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAodmFsdWUgLyBtdWwpICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQ4ID0gZnVuY3Rpb24gd3JpdGVVSW50OCAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDEsIDB4ZmYsIDApXG4gIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIHJldHVybiBvZmZzZXQgKyAxXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MTZMRSA9IGZ1bmN0aW9uIHdyaXRlVUludDE2TEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAyLCAweGZmZmYsIDApXG4gIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MTZCRSA9IGZ1bmN0aW9uIHdyaXRlVUludDE2QkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAyLCAweGZmZmYsIDApXG4gIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gOClcbiAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MzJMRSA9IGZ1bmN0aW9uIHdyaXRlVUludDMyTEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCA0LCAweGZmZmZmZmZmLCAwKVxuICB0aGlzW29mZnNldCArIDNdID0gKHZhbHVlID4+PiAyNClcbiAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MzJCRSA9IGZ1bmN0aW9uIHdyaXRlVUludDMyQkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCA0LCAweGZmZmZmZmZmLCAwKVxuICB0aGlzW29mZnNldF0gPSAodmFsdWUgPj4+IDI0KVxuICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiAxNilcbiAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gOClcbiAgdGhpc1tvZmZzZXQgKyAzXSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnRMRSA9IGZ1bmN0aW9uIHdyaXRlSW50TEUgKHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgdmFyIGxpbWl0ID0gTWF0aC5wb3coMiwgKDggKiBieXRlTGVuZ3RoKSAtIDEpXG5cbiAgICBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBsaW1pdCAtIDEsIC1saW1pdClcbiAgfVxuXG4gIHZhciBpID0gMFxuICB2YXIgbXVsID0gMVxuICB2YXIgc3ViID0gMFxuICB0aGlzW29mZnNldF0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICBpZiAodmFsdWUgPCAwICYmIHN1YiA9PT0gMCAmJiB0aGlzW29mZnNldCArIGkgLSAxXSAhPT0gMCkge1xuICAgICAgc3ViID0gMVxuICAgIH1cbiAgICB0aGlzW29mZnNldCArIGldID0gKCh2YWx1ZSAvIG11bCkgPj4gMCkgLSBzdWIgJiAweEZGXG4gIH1cblxuICByZXR1cm4gb2Zmc2V0ICsgYnl0ZUxlbmd0aFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50QkUgPSBmdW5jdGlvbiB3cml0ZUludEJFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIHZhciBsaW1pdCA9IE1hdGgucG93KDIsICg4ICogYnl0ZUxlbmd0aCkgLSAxKVxuXG4gICAgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbGltaXQgLSAxLCAtbGltaXQpXG4gIH1cblxuICB2YXIgaSA9IGJ5dGVMZW5ndGggLSAxXG4gIHZhciBtdWwgPSAxXG4gIHZhciBzdWIgPSAwXG4gIHRoaXNbb2Zmc2V0ICsgaV0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKC0taSA+PSAwICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgaWYgKHZhbHVlIDwgMCAmJiBzdWIgPT09IDAgJiYgdGhpc1tvZmZzZXQgKyBpICsgMV0gIT09IDApIHtcbiAgICAgIHN1YiA9IDFcbiAgICB9XG4gICAgdGhpc1tvZmZzZXQgKyBpXSA9ICgodmFsdWUgLyBtdWwpID4+IDApIC0gc3ViICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDggPSBmdW5jdGlvbiB3cml0ZUludDggKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAxLCAweDdmLCAtMHg4MClcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmICsgdmFsdWUgKyAxXG4gIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIHJldHVybiBvZmZzZXQgKyAxXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQxNkxFID0gZnVuY3Rpb24gd3JpdGVJbnQxNkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMiwgMHg3ZmZmLCAtMHg4MDAwKVxuICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICByZXR1cm4gb2Zmc2V0ICsgMlxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MTZCRSA9IGZ1bmN0aW9uIHdyaXRlSW50MTZCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4N2ZmZiwgLTB4ODAwMClcbiAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiA4KVxuICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlICYgMHhmZilcbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDMyTEUgPSBmdW5jdGlvbiB3cml0ZUludDMyTEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCA0LCAweDdmZmZmZmZmLCAtMHg4MDAwMDAwMClcbiAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gOClcbiAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gIHRoaXNbb2Zmc2V0ICsgM10gPSAodmFsdWUgPj4+IDI0KVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MzJCRSA9IGZ1bmN0aW9uIHdyaXRlSW50MzJCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4N2ZmZmZmZmYsIC0weDgwMDAwMDAwKVxuICBpZiAodmFsdWUgPCAwKSB2YWx1ZSA9IDB4ZmZmZmZmZmYgKyB2YWx1ZSArIDFcbiAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiAyNClcbiAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gIHRoaXNbb2Zmc2V0ICsgMl0gPSAodmFsdWUgPj4+IDgpXG4gIHRoaXNbb2Zmc2V0ICsgM10gPSAodmFsdWUgJiAweGZmKVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5mdW5jdGlvbiBjaGVja0lFRUU3NTQgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgZXh0LCBtYXgsIG1pbikge1xuICBpZiAob2Zmc2V0ICsgZXh0ID4gYnVmLmxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0luZGV4IG91dCBvZiByYW5nZScpXG4gIGlmIChvZmZzZXQgPCAwKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignSW5kZXggb3V0IG9mIHJhbmdlJylcbn1cblxuZnVuY3Rpb24gd3JpdGVGbG9hdCAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgY2hlY2tJRUVFNzU0KGJ1ZiwgdmFsdWUsIG9mZnNldCwgNCwgMy40MDI4MjM0NjYzODUyODg2ZSszOCwgLTMuNDAyODIzNDY2Mzg1Mjg4NmUrMzgpXG4gIH1cbiAgaWVlZTc1NC53cml0ZShidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgMjMsIDQpXG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVGbG9hdExFID0gZnVuY3Rpb24gd3JpdGVGbG9hdExFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVGbG9hdCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUZsb2F0QkUgPSBmdW5jdGlvbiB3cml0ZUZsb2F0QkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiB3cml0ZUZsb2F0KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydClcbn1cblxuZnVuY3Rpb24gd3JpdGVEb3VibGUgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGNoZWNrSUVFRTc1NChidWYsIHZhbHVlLCBvZmZzZXQsIDgsIDEuNzk3NjkzMTM0ODYyMzE1N0UrMzA4LCAtMS43OTc2OTMxMzQ4NjIzMTU3RSszMDgpXG4gIH1cbiAgaWVlZTc1NC53cml0ZShidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgNTIsIDgpXG4gIHJldHVybiBvZmZzZXQgKyA4XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVEb3VibGVMRSA9IGZ1bmN0aW9uIHdyaXRlRG91YmxlTEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiB3cml0ZURvdWJsZSh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZURvdWJsZUJFID0gZnVuY3Rpb24gd3JpdGVEb3VibGVCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHdyaXRlRG91YmxlKHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydClcbn1cblxuLy8gY29weSh0YXJnZXRCdWZmZXIsIHRhcmdldFN0YXJ0PTAsIHNvdXJjZVN0YXJ0PTAsIHNvdXJjZUVuZD1idWZmZXIubGVuZ3RoKVxuQnVmZmVyLnByb3RvdHlwZS5jb3B5ID0gZnVuY3Rpb24gY29weSAodGFyZ2V0LCB0YXJnZXRTdGFydCwgc3RhcnQsIGVuZCkge1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcih0YXJnZXQpKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdhcmd1bWVudCBzaG91bGQgYmUgYSBCdWZmZXInKVxuICBpZiAoIXN0YXJ0KSBzdGFydCA9IDBcbiAgaWYgKCFlbmQgJiYgZW5kICE9PSAwKSBlbmQgPSB0aGlzLmxlbmd0aFxuICBpZiAodGFyZ2V0U3RhcnQgPj0gdGFyZ2V0Lmxlbmd0aCkgdGFyZ2V0U3RhcnQgPSB0YXJnZXQubGVuZ3RoXG4gIGlmICghdGFyZ2V0U3RhcnQpIHRhcmdldFN0YXJ0ID0gMFxuICBpZiAoZW5kID4gMCAmJiBlbmQgPCBzdGFydCkgZW5kID0gc3RhcnRcblxuICAvLyBDb3B5IDAgYnl0ZXM7IHdlJ3JlIGRvbmVcbiAgaWYgKGVuZCA9PT0gc3RhcnQpIHJldHVybiAwXG4gIGlmICh0YXJnZXQubGVuZ3RoID09PSAwIHx8IHRoaXMubGVuZ3RoID09PSAwKSByZXR1cm4gMFxuXG4gIC8vIEZhdGFsIGVycm9yIGNvbmRpdGlvbnNcbiAgaWYgKHRhcmdldFN0YXJ0IDwgMCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCd0YXJnZXRTdGFydCBvdXQgb2YgYm91bmRzJylcbiAgfVxuICBpZiAoc3RhcnQgPCAwIHx8IHN0YXJ0ID49IHRoaXMubGVuZ3RoKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignSW5kZXggb3V0IG9mIHJhbmdlJylcbiAgaWYgKGVuZCA8IDApIHRocm93IG5ldyBSYW5nZUVycm9yKCdzb3VyY2VFbmQgb3V0IG9mIGJvdW5kcycpXG5cbiAgLy8gQXJlIHdlIG9vYj9cbiAgaWYgKGVuZCA+IHRoaXMubGVuZ3RoKSBlbmQgPSB0aGlzLmxlbmd0aFxuICBpZiAodGFyZ2V0Lmxlbmd0aCAtIHRhcmdldFN0YXJ0IDwgZW5kIC0gc3RhcnQpIHtcbiAgICBlbmQgPSB0YXJnZXQubGVuZ3RoIC0gdGFyZ2V0U3RhcnQgKyBzdGFydFxuICB9XG5cbiAgdmFyIGxlbiA9IGVuZCAtIHN0YXJ0XG5cbiAgaWYgKHRoaXMgPT09IHRhcmdldCAmJiB0eXBlb2YgVWludDhBcnJheS5wcm90b3R5cGUuY29weVdpdGhpbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIC8vIFVzZSBidWlsdC1pbiB3aGVuIGF2YWlsYWJsZSwgbWlzc2luZyBmcm9tIElFMTFcbiAgICB0aGlzLmNvcHlXaXRoaW4odGFyZ2V0U3RhcnQsIHN0YXJ0LCBlbmQpXG4gIH0gZWxzZSBpZiAodGhpcyA9PT0gdGFyZ2V0ICYmIHN0YXJ0IDwgdGFyZ2V0U3RhcnQgJiYgdGFyZ2V0U3RhcnQgPCBlbmQpIHtcbiAgICAvLyBkZXNjZW5kaW5nIGNvcHkgZnJvbSBlbmRcbiAgICBmb3IgKHZhciBpID0gbGVuIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgIHRhcmdldFtpICsgdGFyZ2V0U3RhcnRdID0gdGhpc1tpICsgc3RhcnRdXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIFVpbnQ4QXJyYXkucHJvdG90eXBlLnNldC5jYWxsKFxuICAgICAgdGFyZ2V0LFxuICAgICAgdGhpcy5zdWJhcnJheShzdGFydCwgZW5kKSxcbiAgICAgIHRhcmdldFN0YXJ0XG4gICAgKVxuICB9XG5cbiAgcmV0dXJuIGxlblxufVxuXG4vLyBVc2FnZTpcbi8vICAgIGJ1ZmZlci5maWxsKG51bWJlclssIG9mZnNldFssIGVuZF1dKVxuLy8gICAgYnVmZmVyLmZpbGwoYnVmZmVyWywgb2Zmc2V0WywgZW5kXV0pXG4vLyAgICBidWZmZXIuZmlsbChzdHJpbmdbLCBvZmZzZXRbLCBlbmRdXVssIGVuY29kaW5nXSlcbkJ1ZmZlci5wcm90b3R5cGUuZmlsbCA9IGZ1bmN0aW9uIGZpbGwgKHZhbCwgc3RhcnQsIGVuZCwgZW5jb2RpbmcpIHtcbiAgLy8gSGFuZGxlIHN0cmluZyBjYXNlczpcbiAgaWYgKHR5cGVvZiB2YWwgPT09ICdzdHJpbmcnKSB7XG4gICAgaWYgKHR5cGVvZiBzdGFydCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGVuY29kaW5nID0gc3RhcnRcbiAgICAgIHN0YXJ0ID0gMFxuICAgICAgZW5kID0gdGhpcy5sZW5ndGhcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBlbmQgPT09ICdzdHJpbmcnKSB7XG4gICAgICBlbmNvZGluZyA9IGVuZFxuICAgICAgZW5kID0gdGhpcy5sZW5ndGhcbiAgICB9XG4gICAgaWYgKGVuY29kaW5nICE9PSB1bmRlZmluZWQgJiYgdHlwZW9mIGVuY29kaW5nICE9PSAnc3RyaW5nJykge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignZW5jb2RpbmcgbXVzdCBiZSBhIHN0cmluZycpXG4gICAgfVxuICAgIGlmICh0eXBlb2YgZW5jb2RpbmcgPT09ICdzdHJpbmcnICYmICFCdWZmZXIuaXNFbmNvZGluZyhlbmNvZGluZykpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmNvZGluZylcbiAgICB9XG4gICAgaWYgKHZhbC5sZW5ndGggPT09IDEpIHtcbiAgICAgIHZhciBjb2RlID0gdmFsLmNoYXJDb2RlQXQoMClcbiAgICAgIGlmICgoZW5jb2RpbmcgPT09ICd1dGY4JyAmJiBjb2RlIDwgMTI4KSB8fFxuICAgICAgICAgIGVuY29kaW5nID09PSAnbGF0aW4xJykge1xuICAgICAgICAvLyBGYXN0IHBhdGg6IElmIGB2YWxgIGZpdHMgaW50byBhIHNpbmdsZSBieXRlLCB1c2UgdGhhdCBudW1lcmljIHZhbHVlLlxuICAgICAgICB2YWwgPSBjb2RlXG4gICAgICB9XG4gICAgfVxuICB9IGVsc2UgaWYgKHR5cGVvZiB2YWwgPT09ICdudW1iZXInKSB7XG4gICAgdmFsID0gdmFsICYgMjU1XG4gIH1cblxuICAvLyBJbnZhbGlkIHJhbmdlcyBhcmUgbm90IHNldCB0byBhIGRlZmF1bHQsIHNvIGNhbiByYW5nZSBjaGVjayBlYXJseS5cbiAgaWYgKHN0YXJ0IDwgMCB8fCB0aGlzLmxlbmd0aCA8IHN0YXJ0IHx8IHRoaXMubGVuZ3RoIDwgZW5kKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ091dCBvZiByYW5nZSBpbmRleCcpXG4gIH1cblxuICBpZiAoZW5kIDw9IHN0YXJ0KSB7XG4gICAgcmV0dXJuIHRoaXNcbiAgfVxuXG4gIHN0YXJ0ID0gc3RhcnQgPj4+IDBcbiAgZW5kID0gZW5kID09PSB1bmRlZmluZWQgPyB0aGlzLmxlbmd0aCA6IGVuZCA+Pj4gMFxuXG4gIGlmICghdmFsKSB2YWwgPSAwXG5cbiAgdmFyIGlcbiAgaWYgKHR5cGVvZiB2YWwgPT09ICdudW1iZXInKSB7XG4gICAgZm9yIChpID0gc3RhcnQ7IGkgPCBlbmQ7ICsraSkge1xuICAgICAgdGhpc1tpXSA9IHZhbFxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB2YXIgYnl0ZXMgPSBCdWZmZXIuaXNCdWZmZXIodmFsKVxuICAgICAgPyB2YWxcbiAgICAgIDogQnVmZmVyLmZyb20odmFsLCBlbmNvZGluZylcbiAgICB2YXIgbGVuID0gYnl0ZXMubGVuZ3RoXG4gICAgaWYgKGxlbiA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhlIHZhbHVlIFwiJyArIHZhbCArXG4gICAgICAgICdcIiBpcyBpbnZhbGlkIGZvciBhcmd1bWVudCBcInZhbHVlXCInKVxuICAgIH1cbiAgICBmb3IgKGkgPSAwOyBpIDwgZW5kIC0gc3RhcnQ7ICsraSkge1xuICAgICAgdGhpc1tpICsgc3RhcnRdID0gYnl0ZXNbaSAlIGxlbl1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGhpc1xufVxuXG4vLyBIRUxQRVIgRlVOQ1RJT05TXG4vLyA9PT09PT09PT09PT09PT09XG5cbnZhciBJTlZBTElEX0JBU0U2NF9SRSA9IC9bXisvMC05QS1aYS16LV9dL2dcblxuZnVuY3Rpb24gYmFzZTY0Y2xlYW4gKHN0cikge1xuICAvLyBOb2RlIHRha2VzIGVxdWFsIHNpZ25zIGFzIGVuZCBvZiB0aGUgQmFzZTY0IGVuY29kaW5nXG4gIHN0ciA9IHN0ci5zcGxpdCgnPScpWzBdXG4gIC8vIE5vZGUgc3RyaXBzIG91dCBpbnZhbGlkIGNoYXJhY3RlcnMgbGlrZSBcXG4gYW5kIFxcdCBmcm9tIHRoZSBzdHJpbmcsIGJhc2U2NC1qcyBkb2VzIG5vdFxuICBzdHIgPSBzdHIudHJpbSgpLnJlcGxhY2UoSU5WQUxJRF9CQVNFNjRfUkUsICcnKVxuICAvLyBOb2RlIGNvbnZlcnRzIHN0cmluZ3Mgd2l0aCBsZW5ndGggPCAyIHRvICcnXG4gIGlmIChzdHIubGVuZ3RoIDwgMikgcmV0dXJuICcnXG4gIC8vIE5vZGUgYWxsb3dzIGZvciBub24tcGFkZGVkIGJhc2U2NCBzdHJpbmdzIChtaXNzaW5nIHRyYWlsaW5nID09PSksIGJhc2U2NC1qcyBkb2VzIG5vdFxuICB3aGlsZSAoc3RyLmxlbmd0aCAlIDQgIT09IDApIHtcbiAgICBzdHIgPSBzdHIgKyAnPSdcbiAgfVxuICByZXR1cm4gc3RyXG59XG5cbmZ1bmN0aW9uIHRvSGV4IChuKSB7XG4gIGlmIChuIDwgMTYpIHJldHVybiAnMCcgKyBuLnRvU3RyaW5nKDE2KVxuICByZXR1cm4gbi50b1N0cmluZygxNilcbn1cblxuZnVuY3Rpb24gdXRmOFRvQnl0ZXMgKHN0cmluZywgdW5pdHMpIHtcbiAgdW5pdHMgPSB1bml0cyB8fCBJbmZpbml0eVxuICB2YXIgY29kZVBvaW50XG4gIHZhciBsZW5ndGggPSBzdHJpbmcubGVuZ3RoXG4gIHZhciBsZWFkU3Vycm9nYXRlID0gbnVsbFxuICB2YXIgYnl0ZXMgPSBbXVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHtcbiAgICBjb2RlUG9pbnQgPSBzdHJpbmcuY2hhckNvZGVBdChpKVxuXG4gICAgLy8gaXMgc3Vycm9nYXRlIGNvbXBvbmVudFxuICAgIGlmIChjb2RlUG9pbnQgPiAweEQ3RkYgJiYgY29kZVBvaW50IDwgMHhFMDAwKSB7XG4gICAgICAvLyBsYXN0IGNoYXIgd2FzIGEgbGVhZFxuICAgICAgaWYgKCFsZWFkU3Vycm9nYXRlKSB7XG4gICAgICAgIC8vIG5vIGxlYWQgeWV0XG4gICAgICAgIGlmIChjb2RlUG9pbnQgPiAweERCRkYpIHtcbiAgICAgICAgICAvLyB1bmV4cGVjdGVkIHRyYWlsXG4gICAgICAgICAgaWYgKCh1bml0cyAtPSAzKSA+IC0xKSBieXRlcy5wdXNoKDB4RUYsIDB4QkYsIDB4QkQpXG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfSBlbHNlIGlmIChpICsgMSA9PT0gbGVuZ3RoKSB7XG4gICAgICAgICAgLy8gdW5wYWlyZWQgbGVhZFxuICAgICAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH1cblxuICAgICAgICAvLyB2YWxpZCBsZWFkXG4gICAgICAgIGxlYWRTdXJyb2dhdGUgPSBjb2RlUG9pbnRcblxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICAvLyAyIGxlYWRzIGluIGEgcm93XG4gICAgICBpZiAoY29kZVBvaW50IDwgMHhEQzAwKSB7XG4gICAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgICAgICBsZWFkU3Vycm9nYXRlID0gY29kZVBvaW50XG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIC8vIHZhbGlkIHN1cnJvZ2F0ZSBwYWlyXG4gICAgICBjb2RlUG9pbnQgPSAobGVhZFN1cnJvZ2F0ZSAtIDB4RDgwMCA8PCAxMCB8IGNvZGVQb2ludCAtIDB4REMwMCkgKyAweDEwMDAwXG4gICAgfSBlbHNlIGlmIChsZWFkU3Vycm9nYXRlKSB7XG4gICAgICAvLyB2YWxpZCBibXAgY2hhciwgYnV0IGxhc3QgY2hhciB3YXMgYSBsZWFkXG4gICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICB9XG5cbiAgICBsZWFkU3Vycm9nYXRlID0gbnVsbFxuXG4gICAgLy8gZW5jb2RlIHV0ZjhcbiAgICBpZiAoY29kZVBvaW50IDwgMHg4MCkge1xuICAgICAgaWYgKCh1bml0cyAtPSAxKSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKGNvZGVQb2ludClcbiAgICB9IGVsc2UgaWYgKGNvZGVQb2ludCA8IDB4ODAwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDIpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goXG4gICAgICAgIGNvZGVQb2ludCA+PiAweDYgfCAweEMwLFxuICAgICAgICBjb2RlUG9pbnQgJiAweDNGIHwgMHg4MFxuICAgICAgKVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50IDwgMHgxMDAwMCkge1xuICAgICAgaWYgKCh1bml0cyAtPSAzKSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHhDIHwgMHhFMCxcbiAgICAgICAgY29kZVBvaW50ID4+IDB4NiAmIDB4M0YgfCAweDgwLFxuICAgICAgICBjb2RlUG9pbnQgJiAweDNGIHwgMHg4MFxuICAgICAgKVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50IDwgMHgxMTAwMDApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gNCkgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChcbiAgICAgICAgY29kZVBvaW50ID4+IDB4MTIgfCAweEYwLFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHhDICYgMHgzRiB8IDB4ODAsXG4gICAgICAgIGNvZGVQb2ludCA+PiAweDYgJiAweDNGIHwgMHg4MCxcbiAgICAgICAgY29kZVBvaW50ICYgMHgzRiB8IDB4ODBcbiAgICAgIClcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGNvZGUgcG9pbnQnKVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBieXRlc1xufVxuXG5mdW5jdGlvbiBhc2NpaVRvQnl0ZXMgKHN0cikge1xuICB2YXIgYnl0ZUFycmF5ID0gW11cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyArK2kpIHtcbiAgICAvLyBOb2RlJ3MgY29kZSBzZWVtcyB0byBiZSBkb2luZyB0aGlzIGFuZCBub3QgJiAweDdGLi5cbiAgICBieXRlQXJyYXkucHVzaChzdHIuY2hhckNvZGVBdChpKSAmIDB4RkYpXG4gIH1cbiAgcmV0dXJuIGJ5dGVBcnJheVxufVxuXG5mdW5jdGlvbiB1dGYxNmxlVG9CeXRlcyAoc3RyLCB1bml0cykge1xuICB2YXIgYywgaGksIGxvXG4gIHZhciBieXRlQXJyYXkgPSBbXVxuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0ci5sZW5ndGg7ICsraSkge1xuICAgIGlmICgodW5pdHMgLT0gMikgPCAwKSBicmVha1xuXG4gICAgYyA9IHN0ci5jaGFyQ29kZUF0KGkpXG4gICAgaGkgPSBjID4+IDhcbiAgICBsbyA9IGMgJSAyNTZcbiAgICBieXRlQXJyYXkucHVzaChsbylcbiAgICBieXRlQXJyYXkucHVzaChoaSlcbiAgfVxuXG4gIHJldHVybiBieXRlQXJyYXlcbn1cblxuZnVuY3Rpb24gYmFzZTY0VG9CeXRlcyAoc3RyKSB7XG4gIHJldHVybiBiYXNlNjQudG9CeXRlQXJyYXkoYmFzZTY0Y2xlYW4oc3RyKSlcbn1cblxuZnVuY3Rpb24gYmxpdEJ1ZmZlciAoc3JjLCBkc3QsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHtcbiAgICBpZiAoKGkgKyBvZmZzZXQgPj0gZHN0Lmxlbmd0aCkgfHwgKGkgPj0gc3JjLmxlbmd0aCkpIGJyZWFrXG4gICAgZHN0W2kgKyBvZmZzZXRdID0gc3JjW2ldXG4gIH1cbiAgcmV0dXJuIGlcbn1cblxuLy8gQXJyYXlCdWZmZXIgb3IgVWludDhBcnJheSBvYmplY3RzIGZyb20gb3RoZXIgY29udGV4dHMgKGkuZS4gaWZyYW1lcykgZG8gbm90IHBhc3Ncbi8vIHRoZSBgaW5zdGFuY2VvZmAgY2hlY2sgYnV0IHRoZXkgc2hvdWxkIGJlIHRyZWF0ZWQgYXMgb2YgdGhhdCB0eXBlLlxuLy8gU2VlOiBodHRwczovL2dpdGh1Yi5jb20vZmVyb3NzL2J1ZmZlci9pc3N1ZXMvMTY2XG5mdW5jdGlvbiBpc0luc3RhbmNlIChvYmosIHR5cGUpIHtcbiAgcmV0dXJuIG9iaiBpbnN0YW5jZW9mIHR5cGUgfHxcbiAgICAob2JqICE9IG51bGwgJiYgb2JqLmNvbnN0cnVjdG9yICE9IG51bGwgJiYgb2JqLmNvbnN0cnVjdG9yLm5hbWUgIT0gbnVsbCAmJlxuICAgICAgb2JqLmNvbnN0cnVjdG9yLm5hbWUgPT09IHR5cGUubmFtZSlcbn1cbmZ1bmN0aW9uIG51bWJlcklzTmFOIChvYmopIHtcbiAgLy8gRm9yIElFMTEgc3VwcG9ydFxuICByZXR1cm4gb2JqICE9PSBvYmogLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1zZWxmLWNvbXBhcmVcbn1cbiIsIm1vZHVsZS5leHBvcnRzID0ge1xuICBcIjEwMFwiOiBcIkNvbnRpbnVlXCIsXG4gIFwiMTAxXCI6IFwiU3dpdGNoaW5nIFByb3RvY29sc1wiLFxuICBcIjEwMlwiOiBcIlByb2Nlc3NpbmdcIixcbiAgXCIyMDBcIjogXCJPS1wiLFxuICBcIjIwMVwiOiBcIkNyZWF0ZWRcIixcbiAgXCIyMDJcIjogXCJBY2NlcHRlZFwiLFxuICBcIjIwM1wiOiBcIk5vbi1BdXRob3JpdGF0aXZlIEluZm9ybWF0aW9uXCIsXG4gIFwiMjA0XCI6IFwiTm8gQ29udGVudFwiLFxuICBcIjIwNVwiOiBcIlJlc2V0IENvbnRlbnRcIixcbiAgXCIyMDZcIjogXCJQYXJ0aWFsIENvbnRlbnRcIixcbiAgXCIyMDdcIjogXCJNdWx0aS1TdGF0dXNcIixcbiAgXCIyMDhcIjogXCJBbHJlYWR5IFJlcG9ydGVkXCIsXG4gIFwiMjI2XCI6IFwiSU0gVXNlZFwiLFxuICBcIjMwMFwiOiBcIk11bHRpcGxlIENob2ljZXNcIixcbiAgXCIzMDFcIjogXCJNb3ZlZCBQZXJtYW5lbnRseVwiLFxuICBcIjMwMlwiOiBcIkZvdW5kXCIsXG4gIFwiMzAzXCI6IFwiU2VlIE90aGVyXCIsXG4gIFwiMzA0XCI6IFwiTm90IE1vZGlmaWVkXCIsXG4gIFwiMzA1XCI6IFwiVXNlIFByb3h5XCIsXG4gIFwiMzA3XCI6IFwiVGVtcG9yYXJ5IFJlZGlyZWN0XCIsXG4gIFwiMzA4XCI6IFwiUGVybWFuZW50IFJlZGlyZWN0XCIsXG4gIFwiNDAwXCI6IFwiQmFkIFJlcXVlc3RcIixcbiAgXCI0MDFcIjogXCJVbmF1dGhvcml6ZWRcIixcbiAgXCI0MDJcIjogXCJQYXltZW50IFJlcXVpcmVkXCIsXG4gIFwiNDAzXCI6IFwiRm9yYmlkZGVuXCIsXG4gIFwiNDA0XCI6IFwiTm90IEZvdW5kXCIsXG4gIFwiNDA1XCI6IFwiTWV0aG9kIE5vdCBBbGxvd2VkXCIsXG4gIFwiNDA2XCI6IFwiTm90IEFjY2VwdGFibGVcIixcbiAgXCI0MDdcIjogXCJQcm94eSBBdXRoZW50aWNhdGlvbiBSZXF1aXJlZFwiLFxuICBcIjQwOFwiOiBcIlJlcXVlc3QgVGltZW91dFwiLFxuICBcIjQwOVwiOiBcIkNvbmZsaWN0XCIsXG4gIFwiNDEwXCI6IFwiR29uZVwiLFxuICBcIjQxMVwiOiBcIkxlbmd0aCBSZXF1aXJlZFwiLFxuICBcIjQxMlwiOiBcIlByZWNvbmRpdGlvbiBGYWlsZWRcIixcbiAgXCI0MTNcIjogXCJQYXlsb2FkIFRvbyBMYXJnZVwiLFxuICBcIjQxNFwiOiBcIlVSSSBUb28gTG9uZ1wiLFxuICBcIjQxNVwiOiBcIlVuc3VwcG9ydGVkIE1lZGlhIFR5cGVcIixcbiAgXCI0MTZcIjogXCJSYW5nZSBOb3QgU2F0aXNmaWFibGVcIixcbiAgXCI0MTdcIjogXCJFeHBlY3RhdGlvbiBGYWlsZWRcIixcbiAgXCI0MThcIjogXCJJJ20gYSB0ZWFwb3RcIixcbiAgXCI0MjFcIjogXCJNaXNkaXJlY3RlZCBSZXF1ZXN0XCIsXG4gIFwiNDIyXCI6IFwiVW5wcm9jZXNzYWJsZSBFbnRpdHlcIixcbiAgXCI0MjNcIjogXCJMb2NrZWRcIixcbiAgXCI0MjRcIjogXCJGYWlsZWQgRGVwZW5kZW5jeVwiLFxuICBcIjQyNVwiOiBcIlVub3JkZXJlZCBDb2xsZWN0aW9uXCIsXG4gIFwiNDI2XCI6IFwiVXBncmFkZSBSZXF1aXJlZFwiLFxuICBcIjQyOFwiOiBcIlByZWNvbmRpdGlvbiBSZXF1aXJlZFwiLFxuICBcIjQyOVwiOiBcIlRvbyBNYW55IFJlcXVlc3RzXCIsXG4gIFwiNDMxXCI6IFwiUmVxdWVzdCBIZWFkZXIgRmllbGRzIFRvbyBMYXJnZVwiLFxuICBcIjQ1MVwiOiBcIlVuYXZhaWxhYmxlIEZvciBMZWdhbCBSZWFzb25zXCIsXG4gIFwiNTAwXCI6IFwiSW50ZXJuYWwgU2VydmVyIEVycm9yXCIsXG4gIFwiNTAxXCI6IFwiTm90IEltcGxlbWVudGVkXCIsXG4gIFwiNTAyXCI6IFwiQmFkIEdhdGV3YXlcIixcbiAgXCI1MDNcIjogXCJTZXJ2aWNlIFVuYXZhaWxhYmxlXCIsXG4gIFwiNTA0XCI6IFwiR2F0ZXdheSBUaW1lb3V0XCIsXG4gIFwiNTA1XCI6IFwiSFRUUCBWZXJzaW9uIE5vdCBTdXBwb3J0ZWRcIixcbiAgXCI1MDZcIjogXCJWYXJpYW50IEFsc28gTmVnb3RpYXRlc1wiLFxuICBcIjUwN1wiOiBcIkluc3VmZmljaWVudCBTdG9yYWdlXCIsXG4gIFwiNTA4XCI6IFwiTG9vcCBEZXRlY3RlZFwiLFxuICBcIjUwOVwiOiBcIkJhbmR3aWR0aCBMaW1pdCBFeGNlZWRlZFwiLFxuICBcIjUxMFwiOiBcIk5vdCBFeHRlbmRlZFwiLFxuICBcIjUxMVwiOiBcIk5ldHdvcmsgQXV0aGVudGljYXRpb24gUmVxdWlyZWRcIlxufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYmluZCA9IHJlcXVpcmUoJ2Z1bmN0aW9uLWJpbmQnKTtcblxudmFyICRhcHBseSA9IHJlcXVpcmUoJy4vZnVuY3Rpb25BcHBseScpO1xudmFyICRjYWxsID0gcmVxdWlyZSgnLi9mdW5jdGlvbkNhbGwnKTtcbnZhciAkcmVmbGVjdEFwcGx5ID0gcmVxdWlyZSgnLi9yZWZsZWN0QXBwbHknKTtcblxuLyoqIEB0eXBlIHtpbXBvcnQoJy4vYWN0dWFsQXBwbHknKX0gKi9cbm1vZHVsZS5leHBvcnRzID0gJHJlZmxlY3RBcHBseSB8fCBiaW5kLmNhbGwoJGNhbGwsICRhcHBseSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKiBAdHlwZSB7aW1wb3J0KCcuL2Z1bmN0aW9uQXBwbHknKX0gKi9cbm1vZHVsZS5leHBvcnRzID0gRnVuY3Rpb24ucHJvdG90eXBlLmFwcGx5O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKiogQHR5cGUge2ltcG9ydCgnLi9mdW5jdGlvbkNhbGwnKX0gKi9cbm1vZHVsZS5leHBvcnRzID0gRnVuY3Rpb24ucHJvdG90eXBlLmNhbGw7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBiaW5kID0gcmVxdWlyZSgnZnVuY3Rpb24tYmluZCcpO1xudmFyICRUeXBlRXJyb3IgPSByZXF1aXJlKCdlcy1lcnJvcnMvdHlwZScpO1xuXG52YXIgJGNhbGwgPSByZXF1aXJlKCcuL2Z1bmN0aW9uQ2FsbCcpO1xudmFyICRhY3R1YWxBcHBseSA9IHJlcXVpcmUoJy4vYWN0dWFsQXBwbHknKTtcblxuLyoqIEB0eXBlIHsoYXJnczogW0Z1bmN0aW9uLCB0aGlzQXJnPzogdW5rbm93biwgLi4uYXJnczogdW5rbm93bltdXSkgPT4gRnVuY3Rpb259IFRPRE8gRklYTUUsIGZpbmQgYSB3YXkgdG8gdXNlIGltcG9ydCgnLicpICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGNhbGxCaW5kQmFzaWMoYXJncykge1xuXHRpZiAoYXJncy5sZW5ndGggPCAxIHx8IHR5cGVvZiBhcmdzWzBdICE9PSAnZnVuY3Rpb24nKSB7XG5cdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ2EgZnVuY3Rpb24gaXMgcmVxdWlyZWQnKTtcblx0fVxuXHRyZXR1cm4gJGFjdHVhbEFwcGx5KGJpbmQsICRjYWxsLCBhcmdzKTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKiBAdHlwZSB7aW1wb3J0KCcuL3JlZmxlY3RBcHBseScpfSAqL1xubW9kdWxlLmV4cG9ydHMgPSB0eXBlb2YgUmVmbGVjdCAhPT0gJ3VuZGVmaW5lZCcgJiYgUmVmbGVjdCAmJiBSZWZsZWN0LmFwcGx5O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xuXG52YXIgY2FsbEJpbmRCYXNpYyA9IHJlcXVpcmUoJ2NhbGwtYmluZC1hcHBseS1oZWxwZXJzJyk7XG5cbi8qKiBAdHlwZSB7KHRoaXNBcmc6IHN0cmluZywgc2VhcmNoU3RyaW5nOiBzdHJpbmcsIHBvc2l0aW9uPzogbnVtYmVyKSA9PiBudW1iZXJ9ICovXG52YXIgJGluZGV4T2YgPSBjYWxsQmluZEJhc2ljKFtHZXRJbnRyaW5zaWMoJyVTdHJpbmcucHJvdG90eXBlLmluZGV4T2YlJyldKTtcblxuLyoqIEB0eXBlIHtpbXBvcnQoJy4nKX0gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gY2FsbEJvdW5kSW50cmluc2ljKG5hbWUsIGFsbG93TWlzc2luZykge1xuXHQvKiBlc2xpbnQgbm8tZXh0cmEtcGFyZW5zOiAwICovXG5cblx0dmFyIGludHJpbnNpYyA9IC8qKiBAdHlwZSB7KHRoaXM6IHVua25vd24sIC4uLmFyZ3M6IHVua25vd25bXSkgPT4gdW5rbm93bn0gKi8gKEdldEludHJpbnNpYyhuYW1lLCAhIWFsbG93TWlzc2luZykpO1xuXHRpZiAodHlwZW9mIGludHJpbnNpYyA9PT0gJ2Z1bmN0aW9uJyAmJiAkaW5kZXhPZihuYW1lLCAnLnByb3RvdHlwZS4nKSA+IC0xKSB7XG5cdFx0cmV0dXJuIGNhbGxCaW5kQmFzaWMoLyoqIEB0eXBlIHtjb25zdH0gKi8gKFtpbnRyaW5zaWNdKSk7XG5cdH1cblx0cmV0dXJuIGludHJpbnNpYztcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBjYWxsQmluZCA9IHJlcXVpcmUoJ2NhbGwtYmluZC1hcHBseS1oZWxwZXJzJyk7XG52YXIgZ09QRCA9IHJlcXVpcmUoJ2dvcGQnKTtcblxudmFyIGhhc1Byb3RvQWNjZXNzb3I7XG50cnkge1xuXHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tZXh0cmEtcGFyZW5zLCBuby1wcm90b1xuXHRoYXNQcm90b0FjY2Vzc29yID0gLyoqIEB0eXBlIHt7IF9fcHJvdG9fXz86IHR5cGVvZiBBcnJheS5wcm90b3R5cGUgfX0gKi8gKFtdKS5fX3Byb3RvX18gPT09IEFycmF5LnByb3RvdHlwZTtcbn0gY2F0Y2ggKGUpIHtcblx0aWYgKCFlIHx8IHR5cGVvZiBlICE9PSAnb2JqZWN0JyB8fCAhKCdjb2RlJyBpbiBlKSB8fCBlLmNvZGUgIT09ICdFUlJfUFJPVE9fQUNDRVNTJykge1xuXHRcdHRocm93IGU7XG5cdH1cbn1cblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWV4dHJhLXBhcmVuc1xudmFyIGRlc2MgPSAhIWhhc1Byb3RvQWNjZXNzb3IgJiYgZ09QRCAmJiBnT1BEKE9iamVjdC5wcm90b3R5cGUsIC8qKiBAdHlwZSB7a2V5b2YgdHlwZW9mIE9iamVjdC5wcm90b3R5cGV9ICovICgnX19wcm90b19fJykpO1xuXG52YXIgJE9iamVjdCA9IE9iamVjdDtcbnZhciAkZ2V0UHJvdG90eXBlT2YgPSAkT2JqZWN0LmdldFByb3RvdHlwZU9mO1xuXG4vKiogQHR5cGUge2ltcG9ydCgnLi9nZXQnKX0gKi9cbm1vZHVsZS5leHBvcnRzID0gZGVzYyAmJiB0eXBlb2YgZGVzYy5nZXQgPT09ICdmdW5jdGlvbidcblx0PyBjYWxsQmluZChbZGVzYy5nZXRdKVxuXHQ6IHR5cGVvZiAkZ2V0UHJvdG90eXBlT2YgPT09ICdmdW5jdGlvbidcblx0XHQ/IC8qKiBAdHlwZSB7aW1wb3J0KCcuL2dldCcpfSAqLyBmdW5jdGlvbiBnZXREdW5kZXIodmFsdWUpIHtcblx0XHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBlcWVxZXFcblx0XHRcdHJldHVybiAkZ2V0UHJvdG90eXBlT2YodmFsdWUgPT0gbnVsbCA/IHZhbHVlIDogJE9iamVjdCh2YWx1ZSkpO1xuXHRcdH1cblx0XHQ6IGZhbHNlO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKiogQHR5cGUge2ltcG9ydCgnLicpfSAqL1xudmFyICRkZWZpbmVQcm9wZXJ0eSA9IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSB8fCBmYWxzZTtcbmlmICgkZGVmaW5lUHJvcGVydHkpIHtcblx0dHJ5IHtcblx0XHQkZGVmaW5lUHJvcGVydHkoe30sICdhJywgeyB2YWx1ZTogMSB9KTtcblx0fSBjYXRjaCAoZSkge1xuXHRcdC8vIElFIDggaGFzIGEgYnJva2VuIGRlZmluZVByb3BlcnR5XG5cdFx0JGRlZmluZVByb3BlcnR5ID0gZmFsc2U7XG5cdH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSAkZGVmaW5lUHJvcGVydHk7XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKiBAdHlwZSB7aW1wb3J0KCcuL2V2YWwnKX0gKi9cbm1vZHVsZS5leHBvcnRzID0gRXZhbEVycm9yO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKiogQHR5cGUge2ltcG9ydCgnLicpfSAqL1xubW9kdWxlLmV4cG9ydHMgPSBFcnJvcjtcbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqIEB0eXBlIHtpbXBvcnQoJy4vcmFuZ2UnKX0gKi9cbm1vZHVsZS5leHBvcnRzID0gUmFuZ2VFcnJvcjtcbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqIEB0eXBlIHtpbXBvcnQoJy4vcmVmJyl9ICovXG5tb2R1bGUuZXhwb3J0cyA9IFJlZmVyZW5jZUVycm9yO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKiogQHR5cGUge2ltcG9ydCgnLi9zeW50YXgnKX0gKi9cbm1vZHVsZS5leHBvcnRzID0gU3ludGF4RXJyb3I7XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKiBAdHlwZSB7aW1wb3J0KCcuL3R5cGUnKX0gKi9cbm1vZHVsZS5leHBvcnRzID0gVHlwZUVycm9yO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKiogQHR5cGUge2ltcG9ydCgnLi91cmknKX0gKi9cbm1vZHVsZS5leHBvcnRzID0gVVJJRXJyb3I7XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKiBAdHlwZSB7aW1wb3J0KCcuJyl9ICovXG5tb2R1bGUuZXhwb3J0cyA9IE9iamVjdDtcbiIsIi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBSID0gdHlwZW9mIFJlZmxlY3QgPT09ICdvYmplY3QnID8gUmVmbGVjdCA6IG51bGxcbnZhciBSZWZsZWN0QXBwbHkgPSBSICYmIHR5cGVvZiBSLmFwcGx5ID09PSAnZnVuY3Rpb24nXG4gID8gUi5hcHBseVxuICA6IGZ1bmN0aW9uIFJlZmxlY3RBcHBseSh0YXJnZXQsIHJlY2VpdmVyLCBhcmdzKSB7XG4gICAgcmV0dXJuIEZ1bmN0aW9uLnByb3RvdHlwZS5hcHBseS5jYWxsKHRhcmdldCwgcmVjZWl2ZXIsIGFyZ3MpO1xuICB9XG5cbnZhciBSZWZsZWN0T3duS2V5c1xuaWYgKFIgJiYgdHlwZW9mIFIub3duS2V5cyA9PT0gJ2Z1bmN0aW9uJykge1xuICBSZWZsZWN0T3duS2V5cyA9IFIub3duS2V5c1xufSBlbHNlIGlmIChPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKSB7XG4gIFJlZmxlY3RPd25LZXlzID0gZnVuY3Rpb24gUmVmbGVjdE93bktleXModGFyZ2V0KSB7XG4gICAgcmV0dXJuIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHRhcmdldClcbiAgICAgIC5jb25jYXQoT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyh0YXJnZXQpKTtcbiAgfTtcbn0gZWxzZSB7XG4gIFJlZmxlY3RPd25LZXlzID0gZnVuY3Rpb24gUmVmbGVjdE93bktleXModGFyZ2V0KSB7XG4gICAgcmV0dXJuIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHRhcmdldCk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIFByb2Nlc3NFbWl0V2FybmluZyh3YXJuaW5nKSB7XG4gIGlmIChjb25zb2xlICYmIGNvbnNvbGUud2FybikgY29uc29sZS53YXJuKHdhcm5pbmcpO1xufVxuXG52YXIgTnVtYmVySXNOYU4gPSBOdW1iZXIuaXNOYU4gfHwgZnVuY3Rpb24gTnVtYmVySXNOYU4odmFsdWUpIHtcbiAgcmV0dXJuIHZhbHVlICE9PSB2YWx1ZTtcbn1cblxuZnVuY3Rpb24gRXZlbnRFbWl0dGVyKCkge1xuICBFdmVudEVtaXR0ZXIuaW5pdC5jYWxsKHRoaXMpO1xufVxubW9kdWxlLmV4cG9ydHMgPSBFdmVudEVtaXR0ZXI7XG5tb2R1bGUuZXhwb3J0cy5vbmNlID0gb25jZTtcblxuLy8gQmFja3dhcmRzLWNvbXBhdCB3aXRoIG5vZGUgMC4xMC54XG5FdmVudEVtaXR0ZXIuRXZlbnRFbWl0dGVyID0gRXZlbnRFbWl0dGVyO1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLl9ldmVudHMgPSB1bmRlZmluZWQ7XG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLl9ldmVudHNDb3VudCA9IDA7XG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLl9tYXhMaXN0ZW5lcnMgPSB1bmRlZmluZWQ7XG5cbi8vIEJ5IGRlZmF1bHQgRXZlbnRFbWl0dGVycyB3aWxsIHByaW50IGEgd2FybmluZyBpZiBtb3JlIHRoYW4gMTAgbGlzdGVuZXJzIGFyZVxuLy8gYWRkZWQgdG8gaXQuIFRoaXMgaXMgYSB1c2VmdWwgZGVmYXVsdCB3aGljaCBoZWxwcyBmaW5kaW5nIG1lbW9yeSBsZWFrcy5cbnZhciBkZWZhdWx0TWF4TGlzdGVuZXJzID0gMTA7XG5cbmZ1bmN0aW9uIGNoZWNrTGlzdGVuZXIobGlzdGVuZXIpIHtcbiAgaWYgKHR5cGVvZiBsaXN0ZW5lciAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBcImxpc3RlbmVyXCIgYXJndW1lbnQgbXVzdCBiZSBvZiB0eXBlIEZ1bmN0aW9uLiBSZWNlaXZlZCB0eXBlICcgKyB0eXBlb2YgbGlzdGVuZXIpO1xuICB9XG59XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShFdmVudEVtaXR0ZXIsICdkZWZhdWx0TWF4TGlzdGVuZXJzJywge1xuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBkZWZhdWx0TWF4TGlzdGVuZXJzO1xuICB9LFxuICBzZXQ6IGZ1bmN0aW9uKGFyZykge1xuICAgIGlmICh0eXBlb2YgYXJnICE9PSAnbnVtYmVyJyB8fCBhcmcgPCAwIHx8IE51bWJlcklzTmFOKGFyZykpIHtcbiAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdUaGUgdmFsdWUgb2YgXCJkZWZhdWx0TWF4TGlzdGVuZXJzXCIgaXMgb3V0IG9mIHJhbmdlLiBJdCBtdXN0IGJlIGEgbm9uLW5lZ2F0aXZlIG51bWJlci4gUmVjZWl2ZWQgJyArIGFyZyArICcuJyk7XG4gICAgfVxuICAgIGRlZmF1bHRNYXhMaXN0ZW5lcnMgPSBhcmc7XG4gIH1cbn0pO1xuXG5FdmVudEVtaXR0ZXIuaW5pdCA9IGZ1bmN0aW9uKCkge1xuXG4gIGlmICh0aGlzLl9ldmVudHMgPT09IHVuZGVmaW5lZCB8fFxuICAgICAgdGhpcy5fZXZlbnRzID09PSBPYmplY3QuZ2V0UHJvdG90eXBlT2YodGhpcykuX2V2ZW50cykge1xuICAgIHRoaXMuX2V2ZW50cyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgdGhpcy5fZXZlbnRzQ291bnQgPSAwO1xuICB9XG5cbiAgdGhpcy5fbWF4TGlzdGVuZXJzID0gdGhpcy5fbWF4TGlzdGVuZXJzIHx8IHVuZGVmaW5lZDtcbn07XG5cbi8vIE9idmlvdXNseSBub3QgYWxsIEVtaXR0ZXJzIHNob3VsZCBiZSBsaW1pdGVkIHRvIDEwLiBUaGlzIGZ1bmN0aW9uIGFsbG93c1xuLy8gdGhhdCB0byBiZSBpbmNyZWFzZWQuIFNldCB0byB6ZXJvIGZvciB1bmxpbWl0ZWQuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnNldE1heExpc3RlbmVycyA9IGZ1bmN0aW9uIHNldE1heExpc3RlbmVycyhuKSB7XG4gIGlmICh0eXBlb2YgbiAhPT0gJ251bWJlcicgfHwgbiA8IDAgfHwgTnVtYmVySXNOYU4obikpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignVGhlIHZhbHVlIG9mIFwiblwiIGlzIG91dCBvZiByYW5nZS4gSXQgbXVzdCBiZSBhIG5vbi1uZWdhdGl2ZSBudW1iZXIuIFJlY2VpdmVkICcgKyBuICsgJy4nKTtcbiAgfVxuICB0aGlzLl9tYXhMaXN0ZW5lcnMgPSBuO1xuICByZXR1cm4gdGhpcztcbn07XG5cbmZ1bmN0aW9uIF9nZXRNYXhMaXN0ZW5lcnModGhhdCkge1xuICBpZiAodGhhdC5fbWF4TGlzdGVuZXJzID09PSB1bmRlZmluZWQpXG4gICAgcmV0dXJuIEV2ZW50RW1pdHRlci5kZWZhdWx0TWF4TGlzdGVuZXJzO1xuICByZXR1cm4gdGhhdC5fbWF4TGlzdGVuZXJzO1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmdldE1heExpc3RlbmVycyA9IGZ1bmN0aW9uIGdldE1heExpc3RlbmVycygpIHtcbiAgcmV0dXJuIF9nZXRNYXhMaXN0ZW5lcnModGhpcyk7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmVtaXQgPSBmdW5jdGlvbiBlbWl0KHR5cGUpIHtcbiAgdmFyIGFyZ3MgPSBbXTtcbiAgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIGFyZ3MucHVzaChhcmd1bWVudHNbaV0pO1xuICB2YXIgZG9FcnJvciA9ICh0eXBlID09PSAnZXJyb3InKTtcblxuICB2YXIgZXZlbnRzID0gdGhpcy5fZXZlbnRzO1xuICBpZiAoZXZlbnRzICE9PSB1bmRlZmluZWQpXG4gICAgZG9FcnJvciA9IChkb0Vycm9yICYmIGV2ZW50cy5lcnJvciA9PT0gdW5kZWZpbmVkKTtcbiAgZWxzZSBpZiAoIWRvRXJyb3IpXG4gICAgcmV0dXJuIGZhbHNlO1xuXG4gIC8vIElmIHRoZXJlIGlzIG5vICdlcnJvcicgZXZlbnQgbGlzdGVuZXIgdGhlbiB0aHJvdy5cbiAgaWYgKGRvRXJyb3IpIHtcbiAgICB2YXIgZXI7XG4gICAgaWYgKGFyZ3MubGVuZ3RoID4gMClcbiAgICAgIGVyID0gYXJnc1swXTtcbiAgICBpZiAoZXIgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgLy8gTm90ZTogVGhlIGNvbW1lbnRzIG9uIHRoZSBgdGhyb3dgIGxpbmVzIGFyZSBpbnRlbnRpb25hbCwgdGhleSBzaG93XG4gICAgICAvLyB1cCBpbiBOb2RlJ3Mgb3V0cHV0IGlmIHRoaXMgcmVzdWx0cyBpbiBhbiB1bmhhbmRsZWQgZXhjZXB0aW9uLlxuICAgICAgdGhyb3cgZXI7IC8vIFVuaGFuZGxlZCAnZXJyb3InIGV2ZW50XG4gICAgfVxuICAgIC8vIEF0IGxlYXN0IGdpdmUgc29tZSBraW5kIG9mIGNvbnRleHQgdG8gdGhlIHVzZXJcbiAgICB2YXIgZXJyID0gbmV3IEVycm9yKCdVbmhhbmRsZWQgZXJyb3IuJyArIChlciA/ICcgKCcgKyBlci5tZXNzYWdlICsgJyknIDogJycpKTtcbiAgICBlcnIuY29udGV4dCA9IGVyO1xuICAgIHRocm93IGVycjsgLy8gVW5oYW5kbGVkICdlcnJvcicgZXZlbnRcbiAgfVxuXG4gIHZhciBoYW5kbGVyID0gZXZlbnRzW3R5cGVdO1xuXG4gIGlmIChoYW5kbGVyID09PSB1bmRlZmluZWQpXG4gICAgcmV0dXJuIGZhbHNlO1xuXG4gIGlmICh0eXBlb2YgaGFuZGxlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIFJlZmxlY3RBcHBseShoYW5kbGVyLCB0aGlzLCBhcmdzKTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgbGVuID0gaGFuZGxlci5sZW5ndGg7XG4gICAgdmFyIGxpc3RlbmVycyA9IGFycmF5Q2xvbmUoaGFuZGxlciwgbGVuKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKVxuICAgICAgUmVmbGVjdEFwcGx5KGxpc3RlbmVyc1tpXSwgdGhpcywgYXJncyk7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn07XG5cbmZ1bmN0aW9uIF9hZGRMaXN0ZW5lcih0YXJnZXQsIHR5cGUsIGxpc3RlbmVyLCBwcmVwZW5kKSB7XG4gIHZhciBtO1xuICB2YXIgZXZlbnRzO1xuICB2YXIgZXhpc3Rpbmc7XG5cbiAgY2hlY2tMaXN0ZW5lcihsaXN0ZW5lcik7XG5cbiAgZXZlbnRzID0gdGFyZ2V0Ll9ldmVudHM7XG4gIGlmIChldmVudHMgPT09IHVuZGVmaW5lZCkge1xuICAgIGV2ZW50cyA9IHRhcmdldC5fZXZlbnRzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICB0YXJnZXQuX2V2ZW50c0NvdW50ID0gMDtcbiAgfSBlbHNlIHtcbiAgICAvLyBUbyBhdm9pZCByZWN1cnNpb24gaW4gdGhlIGNhc2UgdGhhdCB0eXBlID09PSBcIm5ld0xpc3RlbmVyXCIhIEJlZm9yZVxuICAgIC8vIGFkZGluZyBpdCB0byB0aGUgbGlzdGVuZXJzLCBmaXJzdCBlbWl0IFwibmV3TGlzdGVuZXJcIi5cbiAgICBpZiAoZXZlbnRzLm5ld0xpc3RlbmVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRhcmdldC5lbWl0KCduZXdMaXN0ZW5lcicsIHR5cGUsXG4gICAgICAgICAgICAgICAgICBsaXN0ZW5lci5saXN0ZW5lciA/IGxpc3RlbmVyLmxpc3RlbmVyIDogbGlzdGVuZXIpO1xuXG4gICAgICAvLyBSZS1hc3NpZ24gYGV2ZW50c2AgYmVjYXVzZSBhIG5ld0xpc3RlbmVyIGhhbmRsZXIgY291bGQgaGF2ZSBjYXVzZWQgdGhlXG4gICAgICAvLyB0aGlzLl9ldmVudHMgdG8gYmUgYXNzaWduZWQgdG8gYSBuZXcgb2JqZWN0XG4gICAgICBldmVudHMgPSB0YXJnZXQuX2V2ZW50cztcbiAgICB9XG4gICAgZXhpc3RpbmcgPSBldmVudHNbdHlwZV07XG4gIH1cblxuICBpZiAoZXhpc3RpbmcgPT09IHVuZGVmaW5lZCkge1xuICAgIC8vIE9wdGltaXplIHRoZSBjYXNlIG9mIG9uZSBsaXN0ZW5lci4gRG9uJ3QgbmVlZCB0aGUgZXh0cmEgYXJyYXkgb2JqZWN0LlxuICAgIGV4aXN0aW5nID0gZXZlbnRzW3R5cGVdID0gbGlzdGVuZXI7XG4gICAgKyt0YXJnZXQuX2V2ZW50c0NvdW50O1xuICB9IGVsc2Uge1xuICAgIGlmICh0eXBlb2YgZXhpc3RpbmcgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIC8vIEFkZGluZyB0aGUgc2Vjb25kIGVsZW1lbnQsIG5lZWQgdG8gY2hhbmdlIHRvIGFycmF5LlxuICAgICAgZXhpc3RpbmcgPSBldmVudHNbdHlwZV0gPVxuICAgICAgICBwcmVwZW5kID8gW2xpc3RlbmVyLCBleGlzdGluZ10gOiBbZXhpc3RpbmcsIGxpc3RlbmVyXTtcbiAgICAgIC8vIElmIHdlJ3ZlIGFscmVhZHkgZ290IGFuIGFycmF5LCBqdXN0IGFwcGVuZC5cbiAgICB9IGVsc2UgaWYgKHByZXBlbmQpIHtcbiAgICAgIGV4aXN0aW5nLnVuc2hpZnQobGlzdGVuZXIpO1xuICAgIH0gZWxzZSB7XG4gICAgICBleGlzdGluZy5wdXNoKGxpc3RlbmVyKTtcbiAgICB9XG5cbiAgICAvLyBDaGVjayBmb3IgbGlzdGVuZXIgbGVha1xuICAgIG0gPSBfZ2V0TWF4TGlzdGVuZXJzKHRhcmdldCk7XG4gICAgaWYgKG0gPiAwICYmIGV4aXN0aW5nLmxlbmd0aCA+IG0gJiYgIWV4aXN0aW5nLndhcm5lZCkge1xuICAgICAgZXhpc3Rpbmcud2FybmVkID0gdHJ1ZTtcbiAgICAgIC8vIE5vIGVycm9yIGNvZGUgZm9yIHRoaXMgc2luY2UgaXQgaXMgYSBXYXJuaW5nXG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcmVzdHJpY3RlZC1zeW50YXhcbiAgICAgIHZhciB3ID0gbmV3IEVycm9yKCdQb3NzaWJsZSBFdmVudEVtaXR0ZXIgbWVtb3J5IGxlYWsgZGV0ZWN0ZWQuICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICBleGlzdGluZy5sZW5ndGggKyAnICcgKyBTdHJpbmcodHlwZSkgKyAnIGxpc3RlbmVycyAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgJ2FkZGVkLiBVc2UgZW1pdHRlci5zZXRNYXhMaXN0ZW5lcnMoKSB0byAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgJ2luY3JlYXNlIGxpbWl0Jyk7XG4gICAgICB3Lm5hbWUgPSAnTWF4TGlzdGVuZXJzRXhjZWVkZWRXYXJuaW5nJztcbiAgICAgIHcuZW1pdHRlciA9IHRhcmdldDtcbiAgICAgIHcudHlwZSA9IHR5cGU7XG4gICAgICB3LmNvdW50ID0gZXhpc3RpbmcubGVuZ3RoO1xuICAgICAgUHJvY2Vzc0VtaXRXYXJuaW5nKHcpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0YXJnZXQ7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuYWRkTGlzdGVuZXIgPSBmdW5jdGlvbiBhZGRMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcikge1xuICByZXR1cm4gX2FkZExpc3RlbmVyKHRoaXMsIHR5cGUsIGxpc3RlbmVyLCBmYWxzZSk7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLm9uID0gRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5hZGRMaXN0ZW5lcjtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5wcmVwZW5kTGlzdGVuZXIgPVxuICAgIGZ1bmN0aW9uIHByZXBlbmRMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcikge1xuICAgICAgcmV0dXJuIF9hZGRMaXN0ZW5lcih0aGlzLCB0eXBlLCBsaXN0ZW5lciwgdHJ1ZSk7XG4gICAgfTtcblxuZnVuY3Rpb24gb25jZVdyYXBwZXIoKSB7XG4gIGlmICghdGhpcy5maXJlZCkge1xuICAgIHRoaXMudGFyZ2V0LnJlbW92ZUxpc3RlbmVyKHRoaXMudHlwZSwgdGhpcy53cmFwRm4pO1xuICAgIHRoaXMuZmlyZWQgPSB0cnVlO1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKVxuICAgICAgcmV0dXJuIHRoaXMubGlzdGVuZXIuY2FsbCh0aGlzLnRhcmdldCk7XG4gICAgcmV0dXJuIHRoaXMubGlzdGVuZXIuYXBwbHkodGhpcy50YXJnZXQsIGFyZ3VtZW50cyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gX29uY2VXcmFwKHRhcmdldCwgdHlwZSwgbGlzdGVuZXIpIHtcbiAgdmFyIHN0YXRlID0geyBmaXJlZDogZmFsc2UsIHdyYXBGbjogdW5kZWZpbmVkLCB0YXJnZXQ6IHRhcmdldCwgdHlwZTogdHlwZSwgbGlzdGVuZXI6IGxpc3RlbmVyIH07XG4gIHZhciB3cmFwcGVkID0gb25jZVdyYXBwZXIuYmluZChzdGF0ZSk7XG4gIHdyYXBwZWQubGlzdGVuZXIgPSBsaXN0ZW5lcjtcbiAgc3RhdGUud3JhcEZuID0gd3JhcHBlZDtcbiAgcmV0dXJuIHdyYXBwZWQ7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub25jZSA9IGZ1bmN0aW9uIG9uY2UodHlwZSwgbGlzdGVuZXIpIHtcbiAgY2hlY2tMaXN0ZW5lcihsaXN0ZW5lcik7XG4gIHRoaXMub24odHlwZSwgX29uY2VXcmFwKHRoaXMsIHR5cGUsIGxpc3RlbmVyKSk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5wcmVwZW5kT25jZUxpc3RlbmVyID1cbiAgICBmdW5jdGlvbiBwcmVwZW5kT25jZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVyKSB7XG4gICAgICBjaGVja0xpc3RlbmVyKGxpc3RlbmVyKTtcbiAgICAgIHRoaXMucHJlcGVuZExpc3RlbmVyKHR5cGUsIF9vbmNlV3JhcCh0aGlzLCB0eXBlLCBsaXN0ZW5lcikpO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuLy8gRW1pdHMgYSAncmVtb3ZlTGlzdGVuZXInIGV2ZW50IGlmIGFuZCBvbmx5IGlmIHRoZSBsaXN0ZW5lciB3YXMgcmVtb3ZlZC5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucmVtb3ZlTGlzdGVuZXIgPVxuICAgIGZ1bmN0aW9uIHJlbW92ZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVyKSB7XG4gICAgICB2YXIgbGlzdCwgZXZlbnRzLCBwb3NpdGlvbiwgaSwgb3JpZ2luYWxMaXN0ZW5lcjtcblxuICAgICAgY2hlY2tMaXN0ZW5lcihsaXN0ZW5lcik7XG5cbiAgICAgIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcbiAgICAgIGlmIChldmVudHMgPT09IHVuZGVmaW5lZClcbiAgICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICAgIGxpc3QgPSBldmVudHNbdHlwZV07XG4gICAgICBpZiAobGlzdCA9PT0gdW5kZWZpbmVkKVxuICAgICAgICByZXR1cm4gdGhpcztcblxuICAgICAgaWYgKGxpc3QgPT09IGxpc3RlbmVyIHx8IGxpc3QubGlzdGVuZXIgPT09IGxpc3RlbmVyKSB7XG4gICAgICAgIGlmICgtLXRoaXMuX2V2ZW50c0NvdW50ID09PSAwKVxuICAgICAgICAgIHRoaXMuX2V2ZW50cyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIGRlbGV0ZSBldmVudHNbdHlwZV07XG4gICAgICAgICAgaWYgKGV2ZW50cy5yZW1vdmVMaXN0ZW5lcilcbiAgICAgICAgICAgIHRoaXMuZW1pdCgncmVtb3ZlTGlzdGVuZXInLCB0eXBlLCBsaXN0Lmxpc3RlbmVyIHx8IGxpc3RlbmVyKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgbGlzdCAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBwb3NpdGlvbiA9IC0xO1xuXG4gICAgICAgIGZvciAoaSA9IGxpc3QubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICBpZiAobGlzdFtpXSA9PT0gbGlzdGVuZXIgfHwgbGlzdFtpXS5saXN0ZW5lciA9PT0gbGlzdGVuZXIpIHtcbiAgICAgICAgICAgIG9yaWdpbmFsTGlzdGVuZXIgPSBsaXN0W2ldLmxpc3RlbmVyO1xuICAgICAgICAgICAgcG9zaXRpb24gPSBpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBvc2l0aW9uIDwgMClcbiAgICAgICAgICByZXR1cm4gdGhpcztcblxuICAgICAgICBpZiAocG9zaXRpb24gPT09IDApXG4gICAgICAgICAgbGlzdC5zaGlmdCgpO1xuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBzcGxpY2VPbmUobGlzdCwgcG9zaXRpb24pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGxpc3QubGVuZ3RoID09PSAxKVxuICAgICAgICAgIGV2ZW50c1t0eXBlXSA9IGxpc3RbMF07XG5cbiAgICAgICAgaWYgKGV2ZW50cy5yZW1vdmVMaXN0ZW5lciAhPT0gdW5kZWZpbmVkKVxuICAgICAgICAgIHRoaXMuZW1pdCgncmVtb3ZlTGlzdGVuZXInLCB0eXBlLCBvcmlnaW5hbExpc3RlbmVyIHx8IGxpc3RlbmVyKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vZmYgPSBFdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUxpc3RlbmVyO1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUFsbExpc3RlbmVycyA9XG4gICAgZnVuY3Rpb24gcmVtb3ZlQWxsTGlzdGVuZXJzKHR5cGUpIHtcbiAgICAgIHZhciBsaXN0ZW5lcnMsIGV2ZW50cywgaTtcblxuICAgICAgZXZlbnRzID0gdGhpcy5fZXZlbnRzO1xuICAgICAgaWYgKGV2ZW50cyA9PT0gdW5kZWZpbmVkKVxuICAgICAgICByZXR1cm4gdGhpcztcblxuICAgICAgLy8gbm90IGxpc3RlbmluZyBmb3IgcmVtb3ZlTGlzdGVuZXIsIG5vIG5lZWQgdG8gZW1pdFxuICAgICAgaWYgKGV2ZW50cy5yZW1vdmVMaXN0ZW5lciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgdGhpcy5fZXZlbnRzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICAgICAgICB0aGlzLl9ldmVudHNDb3VudCA9IDA7XG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnRzW3R5cGVdICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBpZiAoLS10aGlzLl9ldmVudHNDb3VudCA9PT0gMClcbiAgICAgICAgICAgIHRoaXMuX2V2ZW50cyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgICAgICAgZWxzZVxuICAgICAgICAgICAgZGVsZXRlIGV2ZW50c1t0eXBlXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cblxuICAgICAgLy8gZW1pdCByZW1vdmVMaXN0ZW5lciBmb3IgYWxsIGxpc3RlbmVycyBvbiBhbGwgZXZlbnRzXG4gICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKGV2ZW50cyk7XG4gICAgICAgIHZhciBrZXk7XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAga2V5ID0ga2V5c1tpXTtcbiAgICAgICAgICBpZiAoa2V5ID09PSAncmVtb3ZlTGlzdGVuZXInKSBjb250aW51ZTtcbiAgICAgICAgICB0aGlzLnJlbW92ZUFsbExpc3RlbmVycyhrZXkpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucmVtb3ZlQWxsTGlzdGVuZXJzKCdyZW1vdmVMaXN0ZW5lcicpO1xuICAgICAgICB0aGlzLl9ldmVudHMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgICAgICB0aGlzLl9ldmVudHNDb3VudCA9IDA7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuXG4gICAgICBsaXN0ZW5lcnMgPSBldmVudHNbdHlwZV07XG5cbiAgICAgIGlmICh0eXBlb2YgbGlzdGVuZXJzID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIodHlwZSwgbGlzdGVuZXJzKTtcbiAgICAgIH0gZWxzZSBpZiAobGlzdGVuZXJzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgLy8gTElGTyBvcmRlclxuICAgICAgICBmb3IgKGkgPSBsaXN0ZW5lcnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVyc1tpXSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuZnVuY3Rpb24gX2xpc3RlbmVycyh0YXJnZXQsIHR5cGUsIHVud3JhcCkge1xuICB2YXIgZXZlbnRzID0gdGFyZ2V0Ll9ldmVudHM7XG5cbiAgaWYgKGV2ZW50cyA9PT0gdW5kZWZpbmVkKVxuICAgIHJldHVybiBbXTtcblxuICB2YXIgZXZsaXN0ZW5lciA9IGV2ZW50c1t0eXBlXTtcbiAgaWYgKGV2bGlzdGVuZXIgPT09IHVuZGVmaW5lZClcbiAgICByZXR1cm4gW107XG5cbiAgaWYgKHR5cGVvZiBldmxpc3RlbmVyID09PSAnZnVuY3Rpb24nKVxuICAgIHJldHVybiB1bndyYXAgPyBbZXZsaXN0ZW5lci5saXN0ZW5lciB8fCBldmxpc3RlbmVyXSA6IFtldmxpc3RlbmVyXTtcblxuICByZXR1cm4gdW53cmFwID9cbiAgICB1bndyYXBMaXN0ZW5lcnMoZXZsaXN0ZW5lcikgOiBhcnJheUNsb25lKGV2bGlzdGVuZXIsIGV2bGlzdGVuZXIubGVuZ3RoKTtcbn1cblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5saXN0ZW5lcnMgPSBmdW5jdGlvbiBsaXN0ZW5lcnModHlwZSkge1xuICByZXR1cm4gX2xpc3RlbmVycyh0aGlzLCB0eXBlLCB0cnVlKTtcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucmF3TGlzdGVuZXJzID0gZnVuY3Rpb24gcmF3TGlzdGVuZXJzKHR5cGUpIHtcbiAgcmV0dXJuIF9saXN0ZW5lcnModGhpcywgdHlwZSwgZmFsc2UpO1xufTtcblxuRXZlbnRFbWl0dGVyLmxpc3RlbmVyQ291bnQgPSBmdW5jdGlvbihlbWl0dGVyLCB0eXBlKSB7XG4gIGlmICh0eXBlb2YgZW1pdHRlci5saXN0ZW5lckNvdW50ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuIGVtaXR0ZXIubGlzdGVuZXJDb3VudCh0eXBlKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gbGlzdGVuZXJDb3VudC5jYWxsKGVtaXR0ZXIsIHR5cGUpO1xuICB9XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmxpc3RlbmVyQ291bnQgPSBsaXN0ZW5lckNvdW50O1xuZnVuY3Rpb24gbGlzdGVuZXJDb3VudCh0eXBlKSB7XG4gIHZhciBldmVudHMgPSB0aGlzLl9ldmVudHM7XG5cbiAgaWYgKGV2ZW50cyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgdmFyIGV2bGlzdGVuZXIgPSBldmVudHNbdHlwZV07XG5cbiAgICBpZiAodHlwZW9mIGV2bGlzdGVuZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHJldHVybiAxO1xuICAgIH0gZWxzZSBpZiAoZXZsaXN0ZW5lciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gZXZsaXN0ZW5lci5sZW5ndGg7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIDA7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuZXZlbnROYW1lcyA9IGZ1bmN0aW9uIGV2ZW50TmFtZXMoKSB7XG4gIHJldHVybiB0aGlzLl9ldmVudHNDb3VudCA+IDAgPyBSZWZsZWN0T3duS2V5cyh0aGlzLl9ldmVudHMpIDogW107XG59O1xuXG5mdW5jdGlvbiBhcnJheUNsb25lKGFyciwgbikge1xuICB2YXIgY29weSA9IG5ldyBBcnJheShuKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBuOyArK2kpXG4gICAgY29weVtpXSA9IGFycltpXTtcbiAgcmV0dXJuIGNvcHk7XG59XG5cbmZ1bmN0aW9uIHNwbGljZU9uZShsaXN0LCBpbmRleCkge1xuICBmb3IgKDsgaW5kZXggKyAxIDwgbGlzdC5sZW5ndGg7IGluZGV4KyspXG4gICAgbGlzdFtpbmRleF0gPSBsaXN0W2luZGV4ICsgMV07XG4gIGxpc3QucG9wKCk7XG59XG5cbmZ1bmN0aW9uIHVud3JhcExpc3RlbmVycyhhcnIpIHtcbiAgdmFyIHJldCA9IG5ldyBBcnJheShhcnIubGVuZ3RoKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCByZXQubGVuZ3RoOyArK2kpIHtcbiAgICByZXRbaV0gPSBhcnJbaV0ubGlzdGVuZXIgfHwgYXJyW2ldO1xuICB9XG4gIHJldHVybiByZXQ7XG59XG5cbmZ1bmN0aW9uIG9uY2UoZW1pdHRlciwgbmFtZSkge1xuICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgIGZ1bmN0aW9uIGVycm9yTGlzdGVuZXIoZXJyKSB7XG4gICAgICBlbWl0dGVyLnJlbW92ZUxpc3RlbmVyKG5hbWUsIHJlc29sdmVyKTtcbiAgICAgIHJlamVjdChlcnIpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHJlc29sdmVyKCkge1xuICAgICAgaWYgKHR5cGVvZiBlbWl0dGVyLnJlbW92ZUxpc3RlbmVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGVtaXR0ZXIucmVtb3ZlTGlzdGVuZXIoJ2Vycm9yJywgZXJyb3JMaXN0ZW5lcik7XG4gICAgICB9XG4gICAgICByZXNvbHZlKFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzKSk7XG4gICAgfTtcblxuICAgIGV2ZW50VGFyZ2V0QWdub3N0aWNBZGRMaXN0ZW5lcihlbWl0dGVyLCBuYW1lLCByZXNvbHZlciwgeyBvbmNlOiB0cnVlIH0pO1xuICAgIGlmIChuYW1lICE9PSAnZXJyb3InKSB7XG4gICAgICBhZGRFcnJvckhhbmRsZXJJZkV2ZW50RW1pdHRlcihlbWl0dGVyLCBlcnJvckxpc3RlbmVyLCB7IG9uY2U6IHRydWUgfSk7XG4gICAgfVxuICB9KTtcbn1cblxuZnVuY3Rpb24gYWRkRXJyb3JIYW5kbGVySWZFdmVudEVtaXR0ZXIoZW1pdHRlciwgaGFuZGxlciwgZmxhZ3MpIHtcbiAgaWYgKHR5cGVvZiBlbWl0dGVyLm9uID09PSAnZnVuY3Rpb24nKSB7XG4gICAgZXZlbnRUYXJnZXRBZ25vc3RpY0FkZExpc3RlbmVyKGVtaXR0ZXIsICdlcnJvcicsIGhhbmRsZXIsIGZsYWdzKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBldmVudFRhcmdldEFnbm9zdGljQWRkTGlzdGVuZXIoZW1pdHRlciwgbmFtZSwgbGlzdGVuZXIsIGZsYWdzKSB7XG4gIGlmICh0eXBlb2YgZW1pdHRlci5vbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGlmIChmbGFncy5vbmNlKSB7XG4gICAgICBlbWl0dGVyLm9uY2UobmFtZSwgbGlzdGVuZXIpO1xuICAgIH0gZWxzZSB7XG4gICAgICBlbWl0dGVyLm9uKG5hbWUsIGxpc3RlbmVyKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAodHlwZW9mIGVtaXR0ZXIuYWRkRXZlbnRMaXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIC8vIEV2ZW50VGFyZ2V0IGRvZXMgbm90IGhhdmUgYGVycm9yYCBldmVudCBzZW1hbnRpY3MgbGlrZSBOb2RlXG4gICAgLy8gRXZlbnRFbWl0dGVycywgd2UgZG8gbm90IGxpc3RlbiBmb3IgYGVycm9yYCBldmVudHMgaGVyZS5cbiAgICBlbWl0dGVyLmFkZEV2ZW50TGlzdGVuZXIobmFtZSwgZnVuY3Rpb24gd3JhcExpc3RlbmVyKGFyZykge1xuICAgICAgLy8gSUUgZG9lcyBub3QgaGF2ZSBidWlsdGluIGB7IG9uY2U6IHRydWUgfWAgc3VwcG9ydCBzbyB3ZVxuICAgICAgLy8gaGF2ZSB0byBkbyBpdCBtYW51YWxseS5cbiAgICAgIGlmIChmbGFncy5vbmNlKSB7XG4gICAgICAgIGVtaXR0ZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcihuYW1lLCB3cmFwTGlzdGVuZXIpO1xuICAgICAgfVxuICAgICAgbGlzdGVuZXIoYXJnKTtcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgXCJlbWl0dGVyXCIgYXJndW1lbnQgbXVzdCBiZSBvZiB0eXBlIEV2ZW50RW1pdHRlci4gUmVjZWl2ZWQgdHlwZSAnICsgdHlwZW9mIGVtaXR0ZXIpO1xuICB9XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qIGVzbGludCBuby1pbnZhbGlkLXRoaXM6IDEgKi9cblxudmFyIEVSUk9SX01FU1NBR0UgPSAnRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQgY2FsbGVkIG9uIGluY29tcGF0aWJsZSAnO1xudmFyIHRvU3RyID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZztcbnZhciBtYXggPSBNYXRoLm1heDtcbnZhciBmdW5jVHlwZSA9ICdbb2JqZWN0IEZ1bmN0aW9uXSc7XG5cbnZhciBjb25jYXR0eSA9IGZ1bmN0aW9uIGNvbmNhdHR5KGEsIGIpIHtcbiAgICB2YXIgYXJyID0gW107XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGEubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgYXJyW2ldID0gYVtpXTtcbiAgICB9XG4gICAgZm9yICh2YXIgaiA9IDA7IGogPCBiLmxlbmd0aDsgaiArPSAxKSB7XG4gICAgICAgIGFycltqICsgYS5sZW5ndGhdID0gYltqXTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXJyO1xufTtcblxudmFyIHNsaWN5ID0gZnVuY3Rpb24gc2xpY3koYXJyTGlrZSwgb2Zmc2V0KSB7XG4gICAgdmFyIGFyciA9IFtdO1xuICAgIGZvciAodmFyIGkgPSBvZmZzZXQgfHwgMCwgaiA9IDA7IGkgPCBhcnJMaWtlLmxlbmd0aDsgaSArPSAxLCBqICs9IDEpIHtcbiAgICAgICAgYXJyW2pdID0gYXJyTGlrZVtpXTtcbiAgICB9XG4gICAgcmV0dXJuIGFycjtcbn07XG5cbnZhciBqb2lueSA9IGZ1bmN0aW9uIChhcnIsIGpvaW5lcikge1xuICAgIHZhciBzdHIgPSAnJztcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICBzdHIgKz0gYXJyW2ldO1xuICAgICAgICBpZiAoaSArIDEgPCBhcnIubGVuZ3RoKSB7XG4gICAgICAgICAgICBzdHIgKz0gam9pbmVyO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBzdHI7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGJpbmQodGhhdCkge1xuICAgIHZhciB0YXJnZXQgPSB0aGlzO1xuICAgIGlmICh0eXBlb2YgdGFyZ2V0ICE9PSAnZnVuY3Rpb24nIHx8IHRvU3RyLmFwcGx5KHRhcmdldCkgIT09IGZ1bmNUeXBlKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoRVJST1JfTUVTU0FHRSArIHRhcmdldCk7XG4gICAgfVxuICAgIHZhciBhcmdzID0gc2xpY3koYXJndW1lbnRzLCAxKTtcblxuICAgIHZhciBib3VuZDtcbiAgICB2YXIgYmluZGVyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAodGhpcyBpbnN0YW5jZW9mIGJvdW5kKSB7XG4gICAgICAgICAgICB2YXIgcmVzdWx0ID0gdGFyZ2V0LmFwcGx5KFxuICAgICAgICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgICAgICAgY29uY2F0dHkoYXJncywgYXJndW1lbnRzKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGlmIChPYmplY3QocmVzdWx0KSA9PT0gcmVzdWx0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0YXJnZXQuYXBwbHkoXG4gICAgICAgICAgICB0aGF0LFxuICAgICAgICAgICAgY29uY2F0dHkoYXJncywgYXJndW1lbnRzKVxuICAgICAgICApO1xuXG4gICAgfTtcblxuICAgIHZhciBib3VuZExlbmd0aCA9IG1heCgwLCB0YXJnZXQubGVuZ3RoIC0gYXJncy5sZW5ndGgpO1xuICAgIHZhciBib3VuZEFyZ3MgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJvdW5kTGVuZ3RoOyBpKyspIHtcbiAgICAgICAgYm91bmRBcmdzW2ldID0gJyQnICsgaTtcbiAgICB9XG5cbiAgICBib3VuZCA9IEZ1bmN0aW9uKCdiaW5kZXInLCAncmV0dXJuIGZ1bmN0aW9uICgnICsgam9pbnkoYm91bmRBcmdzLCAnLCcpICsgJyl7IHJldHVybiBiaW5kZXIuYXBwbHkodGhpcyxhcmd1bWVudHMpOyB9JykoYmluZGVyKTtcblxuICAgIGlmICh0YXJnZXQucHJvdG90eXBlKSB7XG4gICAgICAgIHZhciBFbXB0eSA9IGZ1bmN0aW9uIEVtcHR5KCkge307XG4gICAgICAgIEVtcHR5LnByb3RvdHlwZSA9IHRhcmdldC5wcm90b3R5cGU7XG4gICAgICAgIGJvdW5kLnByb3RvdHlwZSA9IG5ldyBFbXB0eSgpO1xuICAgICAgICBFbXB0eS5wcm90b3R5cGUgPSBudWxsO1xuICAgIH1cblxuICAgIHJldHVybiBib3VuZDtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBpbXBsZW1lbnRhdGlvbiA9IHJlcXVpcmUoJy4vaW1wbGVtZW50YXRpb24nKTtcblxubW9kdWxlLmV4cG9ydHMgPSBGdW5jdGlvbi5wcm90b3R5cGUuYmluZCB8fCBpbXBsZW1lbnRhdGlvbjtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHVuZGVmaW5lZDtcblxudmFyICRPYmplY3QgPSByZXF1aXJlKCdlcy1vYmplY3QtYXRvbXMnKTtcblxudmFyICRFcnJvciA9IHJlcXVpcmUoJ2VzLWVycm9ycycpO1xudmFyICRFdmFsRXJyb3IgPSByZXF1aXJlKCdlcy1lcnJvcnMvZXZhbCcpO1xudmFyICRSYW5nZUVycm9yID0gcmVxdWlyZSgnZXMtZXJyb3JzL3JhbmdlJyk7XG52YXIgJFJlZmVyZW5jZUVycm9yID0gcmVxdWlyZSgnZXMtZXJyb3JzL3JlZicpO1xudmFyICRTeW50YXhFcnJvciA9IHJlcXVpcmUoJ2VzLWVycm9ycy9zeW50YXgnKTtcbnZhciAkVHlwZUVycm9yID0gcmVxdWlyZSgnZXMtZXJyb3JzL3R5cGUnKTtcbnZhciAkVVJJRXJyb3IgPSByZXF1aXJlKCdlcy1lcnJvcnMvdXJpJyk7XG5cbnZhciBhYnMgPSByZXF1aXJlKCdtYXRoLWludHJpbnNpY3MvYWJzJyk7XG52YXIgZmxvb3IgPSByZXF1aXJlKCdtYXRoLWludHJpbnNpY3MvZmxvb3InKTtcbnZhciBtYXggPSByZXF1aXJlKCdtYXRoLWludHJpbnNpY3MvbWF4Jyk7XG52YXIgbWluID0gcmVxdWlyZSgnbWF0aC1pbnRyaW5zaWNzL21pbicpO1xudmFyIHBvdyA9IHJlcXVpcmUoJ21hdGgtaW50cmluc2ljcy9wb3cnKTtcbnZhciByb3VuZCA9IHJlcXVpcmUoJ21hdGgtaW50cmluc2ljcy9yb3VuZCcpO1xudmFyIHNpZ24gPSByZXF1aXJlKCdtYXRoLWludHJpbnNpY3Mvc2lnbicpO1xuXG52YXIgJEZ1bmN0aW9uID0gRnVuY3Rpb247XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjb25zaXN0ZW50LXJldHVyblxudmFyIGdldEV2YWxsZWRDb25zdHJ1Y3RvciA9IGZ1bmN0aW9uIChleHByZXNzaW9uU3ludGF4KSB7XG5cdHRyeSB7XG5cdFx0cmV0dXJuICRGdW5jdGlvbignXCJ1c2Ugc3RyaWN0XCI7IHJldHVybiAoJyArIGV4cHJlc3Npb25TeW50YXggKyAnKS5jb25zdHJ1Y3RvcjsnKSgpO1xuXHR9IGNhdGNoIChlKSB7fVxufTtcblxudmFyICRnT1BEID0gcmVxdWlyZSgnZ29wZCcpO1xudmFyICRkZWZpbmVQcm9wZXJ0eSA9IHJlcXVpcmUoJ2VzLWRlZmluZS1wcm9wZXJ0eScpO1xuXG52YXIgdGhyb3dUeXBlRXJyb3IgPSBmdW5jdGlvbiAoKSB7XG5cdHRocm93IG5ldyAkVHlwZUVycm9yKCk7XG59O1xudmFyIFRocm93VHlwZUVycm9yID0gJGdPUERcblx0PyAoZnVuY3Rpb24gKCkge1xuXHRcdHRyeSB7XG5cdFx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLWV4cHJlc3Npb25zLCBuby1jYWxsZXIsIG5vLXJlc3RyaWN0ZWQtcHJvcGVydGllc1xuXHRcdFx0YXJndW1lbnRzLmNhbGxlZTsgLy8gSUUgOCBkb2VzIG5vdCB0aHJvdyBoZXJlXG5cdFx0XHRyZXR1cm4gdGhyb3dUeXBlRXJyb3I7XG5cdFx0fSBjYXRjaCAoY2FsbGVlVGhyb3dzKSB7XG5cdFx0XHR0cnkge1xuXHRcdFx0XHQvLyBJRSA4IHRocm93cyBvbiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGFyZ3VtZW50cywgJycpXG5cdFx0XHRcdHJldHVybiAkZ09QRChhcmd1bWVudHMsICdjYWxsZWUnKS5nZXQ7XG5cdFx0XHR9IGNhdGNoIChnT1BEdGhyb3dzKSB7XG5cdFx0XHRcdHJldHVybiB0aHJvd1R5cGVFcnJvcjtcblx0XHRcdH1cblx0XHR9XG5cdH0oKSlcblx0OiB0aHJvd1R5cGVFcnJvcjtcblxudmFyIGhhc1N5bWJvbHMgPSByZXF1aXJlKCdoYXMtc3ltYm9scycpKCk7XG5cbnZhciBnZXRQcm90byA9IHJlcXVpcmUoJ2dldC1wcm90bycpO1xudmFyICRPYmplY3RHUE8gPSByZXF1aXJlKCdnZXQtcHJvdG8vT2JqZWN0LmdldFByb3RvdHlwZU9mJyk7XG52YXIgJFJlZmxlY3RHUE8gPSByZXF1aXJlKCdnZXQtcHJvdG8vUmVmbGVjdC5nZXRQcm90b3R5cGVPZicpO1xuXG52YXIgJGFwcGx5ID0gcmVxdWlyZSgnY2FsbC1iaW5kLWFwcGx5LWhlbHBlcnMvZnVuY3Rpb25BcHBseScpO1xudmFyICRjYWxsID0gcmVxdWlyZSgnY2FsbC1iaW5kLWFwcGx5LWhlbHBlcnMvZnVuY3Rpb25DYWxsJyk7XG5cbnZhciBuZWVkc0V2YWwgPSB7fTtcblxudmFyIFR5cGVkQXJyYXkgPSB0eXBlb2YgVWludDhBcnJheSA9PT0gJ3VuZGVmaW5lZCcgfHwgIWdldFByb3RvID8gdW5kZWZpbmVkIDogZ2V0UHJvdG8oVWludDhBcnJheSk7XG5cbnZhciBJTlRSSU5TSUNTID0ge1xuXHRfX3Byb3RvX186IG51bGwsXG5cdCclQWdncmVnYXRlRXJyb3IlJzogdHlwZW9mIEFnZ3JlZ2F0ZUVycm9yID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IEFnZ3JlZ2F0ZUVycm9yLFxuXHQnJUFycmF5JSc6IEFycmF5LFxuXHQnJUFycmF5QnVmZmVyJSc6IHR5cGVvZiBBcnJheUJ1ZmZlciA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBBcnJheUJ1ZmZlcixcblx0JyVBcnJheUl0ZXJhdG9yUHJvdG90eXBlJSc6IGhhc1N5bWJvbHMgJiYgZ2V0UHJvdG8gPyBnZXRQcm90byhbXVtTeW1ib2wuaXRlcmF0b3JdKCkpIDogdW5kZWZpbmVkLFxuXHQnJUFzeW5jRnJvbVN5bmNJdGVyYXRvclByb3RvdHlwZSUnOiB1bmRlZmluZWQsXG5cdCclQXN5bmNGdW5jdGlvbiUnOiBuZWVkc0V2YWwsXG5cdCclQXN5bmNHZW5lcmF0b3IlJzogbmVlZHNFdmFsLFxuXHQnJUFzeW5jR2VuZXJhdG9yRnVuY3Rpb24lJzogbmVlZHNFdmFsLFxuXHQnJUFzeW5jSXRlcmF0b3JQcm90b3R5cGUlJzogbmVlZHNFdmFsLFxuXHQnJUF0b21pY3MlJzogdHlwZW9mIEF0b21pY3MgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogQXRvbWljcyxcblx0JyVCaWdJbnQlJzogdHlwZW9mIEJpZ0ludCA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBCaWdJbnQsXG5cdCclQmlnSW50NjRBcnJheSUnOiB0eXBlb2YgQmlnSW50NjRBcnJheSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBCaWdJbnQ2NEFycmF5LFxuXHQnJUJpZ1VpbnQ2NEFycmF5JSc6IHR5cGVvZiBCaWdVaW50NjRBcnJheSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBCaWdVaW50NjRBcnJheSxcblx0JyVCb29sZWFuJSc6IEJvb2xlYW4sXG5cdCclRGF0YVZpZXclJzogdHlwZW9mIERhdGFWaWV3ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IERhdGFWaWV3LFxuXHQnJURhdGUlJzogRGF0ZSxcblx0JyVkZWNvZGVVUkklJzogZGVjb2RlVVJJLFxuXHQnJWRlY29kZVVSSUNvbXBvbmVudCUnOiBkZWNvZGVVUklDb21wb25lbnQsXG5cdCclZW5jb2RlVVJJJSc6IGVuY29kZVVSSSxcblx0JyVlbmNvZGVVUklDb21wb25lbnQlJzogZW5jb2RlVVJJQ29tcG9uZW50LFxuXHQnJUVycm9yJSc6ICRFcnJvcixcblx0JyVldmFsJSc6IGV2YWwsIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tZXZhbFxuXHQnJUV2YWxFcnJvciUnOiAkRXZhbEVycm9yLFxuXHQnJUZsb2F0MTZBcnJheSUnOiB0eXBlb2YgRmxvYXQxNkFycmF5ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IEZsb2F0MTZBcnJheSxcblx0JyVGbG9hdDMyQXJyYXklJzogdHlwZW9mIEZsb2F0MzJBcnJheSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBGbG9hdDMyQXJyYXksXG5cdCclRmxvYXQ2NEFycmF5JSc6IHR5cGVvZiBGbG9hdDY0QXJyYXkgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogRmxvYXQ2NEFycmF5LFxuXHQnJUZpbmFsaXphdGlvblJlZ2lzdHJ5JSc6IHR5cGVvZiBGaW5hbGl6YXRpb25SZWdpc3RyeSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBGaW5hbGl6YXRpb25SZWdpc3RyeSxcblx0JyVGdW5jdGlvbiUnOiAkRnVuY3Rpb24sXG5cdCclR2VuZXJhdG9yRnVuY3Rpb24lJzogbmVlZHNFdmFsLFxuXHQnJUludDhBcnJheSUnOiB0eXBlb2YgSW50OEFycmF5ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IEludDhBcnJheSxcblx0JyVJbnQxNkFycmF5JSc6IHR5cGVvZiBJbnQxNkFycmF5ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IEludDE2QXJyYXksXG5cdCclSW50MzJBcnJheSUnOiB0eXBlb2YgSW50MzJBcnJheSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBJbnQzMkFycmF5LFxuXHQnJWlzRmluaXRlJSc6IGlzRmluaXRlLFxuXHQnJWlzTmFOJSc6IGlzTmFOLFxuXHQnJUl0ZXJhdG9yUHJvdG90eXBlJSc6IGhhc1N5bWJvbHMgJiYgZ2V0UHJvdG8gPyBnZXRQcm90byhnZXRQcm90byhbXVtTeW1ib2wuaXRlcmF0b3JdKCkpKSA6IHVuZGVmaW5lZCxcblx0JyVKU09OJSc6IHR5cGVvZiBKU09OID09PSAnb2JqZWN0JyA/IEpTT04gOiB1bmRlZmluZWQsXG5cdCclTWFwJSc6IHR5cGVvZiBNYXAgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogTWFwLFxuXHQnJU1hcEl0ZXJhdG9yUHJvdG90eXBlJSc6IHR5cGVvZiBNYXAgPT09ICd1bmRlZmluZWQnIHx8ICFoYXNTeW1ib2xzIHx8ICFnZXRQcm90byA/IHVuZGVmaW5lZCA6IGdldFByb3RvKG5ldyBNYXAoKVtTeW1ib2wuaXRlcmF0b3JdKCkpLFxuXHQnJU1hdGglJzogTWF0aCxcblx0JyVOdW1iZXIlJzogTnVtYmVyLFxuXHQnJU9iamVjdCUnOiAkT2JqZWN0LFxuXHQnJU9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IlJzogJGdPUEQsXG5cdCclcGFyc2VGbG9hdCUnOiBwYXJzZUZsb2F0LFxuXHQnJXBhcnNlSW50JSc6IHBhcnNlSW50LFxuXHQnJVByb21pc2UlJzogdHlwZW9mIFByb21pc2UgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogUHJvbWlzZSxcblx0JyVQcm94eSUnOiB0eXBlb2YgUHJveHkgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogUHJveHksXG5cdCclUmFuZ2VFcnJvciUnOiAkUmFuZ2VFcnJvcixcblx0JyVSZWZlcmVuY2VFcnJvciUnOiAkUmVmZXJlbmNlRXJyb3IsXG5cdCclUmVmbGVjdCUnOiB0eXBlb2YgUmVmbGVjdCA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBSZWZsZWN0LFxuXHQnJVJlZ0V4cCUnOiBSZWdFeHAsXG5cdCclU2V0JSc6IHR5cGVvZiBTZXQgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogU2V0LFxuXHQnJVNldEl0ZXJhdG9yUHJvdG90eXBlJSc6IHR5cGVvZiBTZXQgPT09ICd1bmRlZmluZWQnIHx8ICFoYXNTeW1ib2xzIHx8ICFnZXRQcm90byA/IHVuZGVmaW5lZCA6IGdldFByb3RvKG5ldyBTZXQoKVtTeW1ib2wuaXRlcmF0b3JdKCkpLFxuXHQnJVNoYXJlZEFycmF5QnVmZmVyJSc6IHR5cGVvZiBTaGFyZWRBcnJheUJ1ZmZlciA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBTaGFyZWRBcnJheUJ1ZmZlcixcblx0JyVTdHJpbmclJzogU3RyaW5nLFxuXHQnJVN0cmluZ0l0ZXJhdG9yUHJvdG90eXBlJSc6IGhhc1N5bWJvbHMgJiYgZ2V0UHJvdG8gPyBnZXRQcm90bygnJ1tTeW1ib2wuaXRlcmF0b3JdKCkpIDogdW5kZWZpbmVkLFxuXHQnJVN5bWJvbCUnOiBoYXNTeW1ib2xzID8gU3ltYm9sIDogdW5kZWZpbmVkLFxuXHQnJVN5bnRheEVycm9yJSc6ICRTeW50YXhFcnJvcixcblx0JyVUaHJvd1R5cGVFcnJvciUnOiBUaHJvd1R5cGVFcnJvcixcblx0JyVUeXBlZEFycmF5JSc6IFR5cGVkQXJyYXksXG5cdCclVHlwZUVycm9yJSc6ICRUeXBlRXJyb3IsXG5cdCclVWludDhBcnJheSUnOiB0eXBlb2YgVWludDhBcnJheSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBVaW50OEFycmF5LFxuXHQnJVVpbnQ4Q2xhbXBlZEFycmF5JSc6IHR5cGVvZiBVaW50OENsYW1wZWRBcnJheSA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBVaW50OENsYW1wZWRBcnJheSxcblx0JyVVaW50MTZBcnJheSUnOiB0eXBlb2YgVWludDE2QXJyYXkgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogVWludDE2QXJyYXksXG5cdCclVWludDMyQXJyYXklJzogdHlwZW9mIFVpbnQzMkFycmF5ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IFVpbnQzMkFycmF5LFxuXHQnJVVSSUVycm9yJSc6ICRVUklFcnJvcixcblx0JyVXZWFrTWFwJSc6IHR5cGVvZiBXZWFrTWFwID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IFdlYWtNYXAsXG5cdCclV2Vha1JlZiUnOiB0eXBlb2YgV2Vha1JlZiA9PT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBXZWFrUmVmLFxuXHQnJVdlYWtTZXQlJzogdHlwZW9mIFdlYWtTZXQgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogV2Vha1NldCxcblxuXHQnJUZ1bmN0aW9uLnByb3RvdHlwZS5jYWxsJSc6ICRjYWxsLFxuXHQnJUZ1bmN0aW9uLnByb3RvdHlwZS5hcHBseSUnOiAkYXBwbHksXG5cdCclT2JqZWN0LmRlZmluZVByb3BlcnR5JSc6ICRkZWZpbmVQcm9wZXJ0eSxcblx0JyVPYmplY3QuZ2V0UHJvdG90eXBlT2YlJzogJE9iamVjdEdQTyxcblx0JyVNYXRoLmFicyUnOiBhYnMsXG5cdCclTWF0aC5mbG9vciUnOiBmbG9vcixcblx0JyVNYXRoLm1heCUnOiBtYXgsXG5cdCclTWF0aC5taW4lJzogbWluLFxuXHQnJU1hdGgucG93JSc6IHBvdyxcblx0JyVNYXRoLnJvdW5kJSc6IHJvdW5kLFxuXHQnJU1hdGguc2lnbiUnOiBzaWduLFxuXHQnJVJlZmxlY3QuZ2V0UHJvdG90eXBlT2YlJzogJFJlZmxlY3RHUE9cbn07XG5cbmlmIChnZXRQcm90bykge1xuXHR0cnkge1xuXHRcdG51bGwuZXJyb3I7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW51c2VkLWV4cHJlc3Npb25zXG5cdH0gY2F0Y2ggKGUpIHtcblx0XHQvLyBodHRwczovL2dpdGh1Yi5jb20vdGMzOS9wcm9wb3NhbC1zaGFkb3dyZWFsbS9wdWxsLzM4NCNpc3N1ZWNvbW1lbnQtMTM2NDI2NDIyOVxuXHRcdHZhciBlcnJvclByb3RvID0gZ2V0UHJvdG8oZ2V0UHJvdG8oZSkpO1xuXHRcdElOVFJJTlNJQ1NbJyVFcnJvci5wcm90b3R5cGUlJ10gPSBlcnJvclByb3RvO1xuXHR9XG59XG5cbnZhciBkb0V2YWwgPSBmdW5jdGlvbiBkb0V2YWwobmFtZSkge1xuXHR2YXIgdmFsdWU7XG5cdGlmIChuYW1lID09PSAnJUFzeW5jRnVuY3Rpb24lJykge1xuXHRcdHZhbHVlID0gZ2V0RXZhbGxlZENvbnN0cnVjdG9yKCdhc3luYyBmdW5jdGlvbiAoKSB7fScpO1xuXHR9IGVsc2UgaWYgKG5hbWUgPT09ICclR2VuZXJhdG9yRnVuY3Rpb24lJykge1xuXHRcdHZhbHVlID0gZ2V0RXZhbGxlZENvbnN0cnVjdG9yKCdmdW5jdGlvbiogKCkge30nKTtcblx0fSBlbHNlIGlmIChuYW1lID09PSAnJUFzeW5jR2VuZXJhdG9yRnVuY3Rpb24lJykge1xuXHRcdHZhbHVlID0gZ2V0RXZhbGxlZENvbnN0cnVjdG9yKCdhc3luYyBmdW5jdGlvbiogKCkge30nKTtcblx0fSBlbHNlIGlmIChuYW1lID09PSAnJUFzeW5jR2VuZXJhdG9yJScpIHtcblx0XHR2YXIgZm4gPSBkb0V2YWwoJyVBc3luY0dlbmVyYXRvckZ1bmN0aW9uJScpO1xuXHRcdGlmIChmbikge1xuXHRcdFx0dmFsdWUgPSBmbi5wcm90b3R5cGU7XG5cdFx0fVxuXHR9IGVsc2UgaWYgKG5hbWUgPT09ICclQXN5bmNJdGVyYXRvclByb3RvdHlwZSUnKSB7XG5cdFx0dmFyIGdlbiA9IGRvRXZhbCgnJUFzeW5jR2VuZXJhdG9yJScpO1xuXHRcdGlmIChnZW4gJiYgZ2V0UHJvdG8pIHtcblx0XHRcdHZhbHVlID0gZ2V0UHJvdG8oZ2VuLnByb3RvdHlwZSk7XG5cdFx0fVxuXHR9XG5cblx0SU5UUklOU0lDU1tuYW1lXSA9IHZhbHVlO1xuXG5cdHJldHVybiB2YWx1ZTtcbn07XG5cbnZhciBMRUdBQ1lfQUxJQVNFUyA9IHtcblx0X19wcm90b19fOiBudWxsLFxuXHQnJUFycmF5QnVmZmVyUHJvdG90eXBlJSc6IFsnQXJyYXlCdWZmZXInLCAncHJvdG90eXBlJ10sXG5cdCclQXJyYXlQcm90b3R5cGUlJzogWydBcnJheScsICdwcm90b3R5cGUnXSxcblx0JyVBcnJheVByb3RvX2VudHJpZXMlJzogWydBcnJheScsICdwcm90b3R5cGUnLCAnZW50cmllcyddLFxuXHQnJUFycmF5UHJvdG9fZm9yRWFjaCUnOiBbJ0FycmF5JywgJ3Byb3RvdHlwZScsICdmb3JFYWNoJ10sXG5cdCclQXJyYXlQcm90b19rZXlzJSc6IFsnQXJyYXknLCAncHJvdG90eXBlJywgJ2tleXMnXSxcblx0JyVBcnJheVByb3RvX3ZhbHVlcyUnOiBbJ0FycmF5JywgJ3Byb3RvdHlwZScsICd2YWx1ZXMnXSxcblx0JyVBc3luY0Z1bmN0aW9uUHJvdG90eXBlJSc6IFsnQXN5bmNGdW5jdGlvbicsICdwcm90b3R5cGUnXSxcblx0JyVBc3luY0dlbmVyYXRvciUnOiBbJ0FzeW5jR2VuZXJhdG9yRnVuY3Rpb24nLCAncHJvdG90eXBlJ10sXG5cdCclQXN5bmNHZW5lcmF0b3JQcm90b3R5cGUlJzogWydBc3luY0dlbmVyYXRvckZ1bmN0aW9uJywgJ3Byb3RvdHlwZScsICdwcm90b3R5cGUnXSxcblx0JyVCb29sZWFuUHJvdG90eXBlJSc6IFsnQm9vbGVhbicsICdwcm90b3R5cGUnXSxcblx0JyVEYXRhVmlld1Byb3RvdHlwZSUnOiBbJ0RhdGFWaWV3JywgJ3Byb3RvdHlwZSddLFxuXHQnJURhdGVQcm90b3R5cGUlJzogWydEYXRlJywgJ3Byb3RvdHlwZSddLFxuXHQnJUVycm9yUHJvdG90eXBlJSc6IFsnRXJyb3InLCAncHJvdG90eXBlJ10sXG5cdCclRXZhbEVycm9yUHJvdG90eXBlJSc6IFsnRXZhbEVycm9yJywgJ3Byb3RvdHlwZSddLFxuXHQnJUZsb2F0MzJBcnJheVByb3RvdHlwZSUnOiBbJ0Zsb2F0MzJBcnJheScsICdwcm90b3R5cGUnXSxcblx0JyVGbG9hdDY0QXJyYXlQcm90b3R5cGUlJzogWydGbG9hdDY0QXJyYXknLCAncHJvdG90eXBlJ10sXG5cdCclRnVuY3Rpb25Qcm90b3R5cGUlJzogWydGdW5jdGlvbicsICdwcm90b3R5cGUnXSxcblx0JyVHZW5lcmF0b3IlJzogWydHZW5lcmF0b3JGdW5jdGlvbicsICdwcm90b3R5cGUnXSxcblx0JyVHZW5lcmF0b3JQcm90b3R5cGUlJzogWydHZW5lcmF0b3JGdW5jdGlvbicsICdwcm90b3R5cGUnLCAncHJvdG90eXBlJ10sXG5cdCclSW50OEFycmF5UHJvdG90eXBlJSc6IFsnSW50OEFycmF5JywgJ3Byb3RvdHlwZSddLFxuXHQnJUludDE2QXJyYXlQcm90b3R5cGUlJzogWydJbnQxNkFycmF5JywgJ3Byb3RvdHlwZSddLFxuXHQnJUludDMyQXJyYXlQcm90b3R5cGUlJzogWydJbnQzMkFycmF5JywgJ3Byb3RvdHlwZSddLFxuXHQnJUpTT05QYXJzZSUnOiBbJ0pTT04nLCAncGFyc2UnXSxcblx0JyVKU09OU3RyaW5naWZ5JSc6IFsnSlNPTicsICdzdHJpbmdpZnknXSxcblx0JyVNYXBQcm90b3R5cGUlJzogWydNYXAnLCAncHJvdG90eXBlJ10sXG5cdCclTnVtYmVyUHJvdG90eXBlJSc6IFsnTnVtYmVyJywgJ3Byb3RvdHlwZSddLFxuXHQnJU9iamVjdFByb3RvdHlwZSUnOiBbJ09iamVjdCcsICdwcm90b3R5cGUnXSxcblx0JyVPYmpQcm90b190b1N0cmluZyUnOiBbJ09iamVjdCcsICdwcm90b3R5cGUnLCAndG9TdHJpbmcnXSxcblx0JyVPYmpQcm90b192YWx1ZU9mJSc6IFsnT2JqZWN0JywgJ3Byb3RvdHlwZScsICd2YWx1ZU9mJ10sXG5cdCclUHJvbWlzZVByb3RvdHlwZSUnOiBbJ1Byb21pc2UnLCAncHJvdG90eXBlJ10sXG5cdCclUHJvbWlzZVByb3RvX3RoZW4lJzogWydQcm9taXNlJywgJ3Byb3RvdHlwZScsICd0aGVuJ10sXG5cdCclUHJvbWlzZV9hbGwlJzogWydQcm9taXNlJywgJ2FsbCddLFxuXHQnJVByb21pc2VfcmVqZWN0JSc6IFsnUHJvbWlzZScsICdyZWplY3QnXSxcblx0JyVQcm9taXNlX3Jlc29sdmUlJzogWydQcm9taXNlJywgJ3Jlc29sdmUnXSxcblx0JyVSYW5nZUVycm9yUHJvdG90eXBlJSc6IFsnUmFuZ2VFcnJvcicsICdwcm90b3R5cGUnXSxcblx0JyVSZWZlcmVuY2VFcnJvclByb3RvdHlwZSUnOiBbJ1JlZmVyZW5jZUVycm9yJywgJ3Byb3RvdHlwZSddLFxuXHQnJVJlZ0V4cFByb3RvdHlwZSUnOiBbJ1JlZ0V4cCcsICdwcm90b3R5cGUnXSxcblx0JyVTZXRQcm90b3R5cGUlJzogWydTZXQnLCAncHJvdG90eXBlJ10sXG5cdCclU2hhcmVkQXJyYXlCdWZmZXJQcm90b3R5cGUlJzogWydTaGFyZWRBcnJheUJ1ZmZlcicsICdwcm90b3R5cGUnXSxcblx0JyVTdHJpbmdQcm90b3R5cGUlJzogWydTdHJpbmcnLCAncHJvdG90eXBlJ10sXG5cdCclU3ltYm9sUHJvdG90eXBlJSc6IFsnU3ltYm9sJywgJ3Byb3RvdHlwZSddLFxuXHQnJVN5bnRheEVycm9yUHJvdG90eXBlJSc6IFsnU3ludGF4RXJyb3InLCAncHJvdG90eXBlJ10sXG5cdCclVHlwZWRBcnJheVByb3RvdHlwZSUnOiBbJ1R5cGVkQXJyYXknLCAncHJvdG90eXBlJ10sXG5cdCclVHlwZUVycm9yUHJvdG90eXBlJSc6IFsnVHlwZUVycm9yJywgJ3Byb3RvdHlwZSddLFxuXHQnJVVpbnQ4QXJyYXlQcm90b3R5cGUlJzogWydVaW50OEFycmF5JywgJ3Byb3RvdHlwZSddLFxuXHQnJVVpbnQ4Q2xhbXBlZEFycmF5UHJvdG90eXBlJSc6IFsnVWludDhDbGFtcGVkQXJyYXknLCAncHJvdG90eXBlJ10sXG5cdCclVWludDE2QXJyYXlQcm90b3R5cGUlJzogWydVaW50MTZBcnJheScsICdwcm90b3R5cGUnXSxcblx0JyVVaW50MzJBcnJheVByb3RvdHlwZSUnOiBbJ1VpbnQzMkFycmF5JywgJ3Byb3RvdHlwZSddLFxuXHQnJVVSSUVycm9yUHJvdG90eXBlJSc6IFsnVVJJRXJyb3InLCAncHJvdG90eXBlJ10sXG5cdCclV2Vha01hcFByb3RvdHlwZSUnOiBbJ1dlYWtNYXAnLCAncHJvdG90eXBlJ10sXG5cdCclV2Vha1NldFByb3RvdHlwZSUnOiBbJ1dlYWtTZXQnLCAncHJvdG90eXBlJ11cbn07XG5cbnZhciBiaW5kID0gcmVxdWlyZSgnZnVuY3Rpb24tYmluZCcpO1xudmFyIGhhc093biA9IHJlcXVpcmUoJ2hhc293bicpO1xudmFyICRjb25jYXQgPSBiaW5kLmNhbGwoJGNhbGwsIEFycmF5LnByb3RvdHlwZS5jb25jYXQpO1xudmFyICRzcGxpY2VBcHBseSA9IGJpbmQuY2FsbCgkYXBwbHksIEFycmF5LnByb3RvdHlwZS5zcGxpY2UpO1xudmFyICRyZXBsYWNlID0gYmluZC5jYWxsKCRjYWxsLCBTdHJpbmcucHJvdG90eXBlLnJlcGxhY2UpO1xudmFyICRzdHJTbGljZSA9IGJpbmQuY2FsbCgkY2FsbCwgU3RyaW5nLnByb3RvdHlwZS5zbGljZSk7XG52YXIgJGV4ZWMgPSBiaW5kLmNhbGwoJGNhbGwsIFJlZ0V4cC5wcm90b3R5cGUuZXhlYyk7XG5cbi8qIGFkYXB0ZWQgZnJvbSBodHRwczovL2dpdGh1Yi5jb20vbG9kYXNoL2xvZGFzaC9ibG9iLzQuMTcuMTUvZGlzdC9sb2Rhc2guanMjTDY3MzUtTDY3NDQgKi9cbnZhciByZVByb3BOYW1lID0gL1teJS5bXFxdXSt8XFxbKD86KC0/XFxkKyg/OlxcLlxcZCspPyl8KFtcIiddKSgoPzooPyFcXDIpW15cXFxcXXxcXFxcLikqPylcXDIpXFxdfCg/PSg/OlxcLnxcXFtcXF0pKD86XFwufFxcW1xcXXwlJCkpL2c7XG52YXIgcmVFc2NhcGVDaGFyID0gL1xcXFwoXFxcXCk/L2c7IC8qKiBVc2VkIHRvIG1hdGNoIGJhY2tzbGFzaGVzIGluIHByb3BlcnR5IHBhdGhzLiAqL1xudmFyIHN0cmluZ1RvUGF0aCA9IGZ1bmN0aW9uIHN0cmluZ1RvUGF0aChzdHJpbmcpIHtcblx0dmFyIGZpcnN0ID0gJHN0clNsaWNlKHN0cmluZywgMCwgMSk7XG5cdHZhciBsYXN0ID0gJHN0clNsaWNlKHN0cmluZywgLTEpO1xuXHRpZiAoZmlyc3QgPT09ICclJyAmJiBsYXN0ICE9PSAnJScpIHtcblx0XHR0aHJvdyBuZXcgJFN5bnRheEVycm9yKCdpbnZhbGlkIGludHJpbnNpYyBzeW50YXgsIGV4cGVjdGVkIGNsb3NpbmcgYCVgJyk7XG5cdH0gZWxzZSBpZiAobGFzdCA9PT0gJyUnICYmIGZpcnN0ICE9PSAnJScpIHtcblx0XHR0aHJvdyBuZXcgJFN5bnRheEVycm9yKCdpbnZhbGlkIGludHJpbnNpYyBzeW50YXgsIGV4cGVjdGVkIG9wZW5pbmcgYCVgJyk7XG5cdH1cblx0dmFyIHJlc3VsdCA9IFtdO1xuXHQkcmVwbGFjZShzdHJpbmcsIHJlUHJvcE5hbWUsIGZ1bmN0aW9uIChtYXRjaCwgbnVtYmVyLCBxdW90ZSwgc3ViU3RyaW5nKSB7XG5cdFx0cmVzdWx0W3Jlc3VsdC5sZW5ndGhdID0gcXVvdGUgPyAkcmVwbGFjZShzdWJTdHJpbmcsIHJlRXNjYXBlQ2hhciwgJyQxJykgOiBudW1iZXIgfHwgbWF0Y2g7XG5cdH0pO1xuXHRyZXR1cm4gcmVzdWx0O1xufTtcbi8qIGVuZCBhZGFwdGF0aW9uICovXG5cbnZhciBnZXRCYXNlSW50cmluc2ljID0gZnVuY3Rpb24gZ2V0QmFzZUludHJpbnNpYyhuYW1lLCBhbGxvd01pc3NpbmcpIHtcblx0dmFyIGludHJpbnNpY05hbWUgPSBuYW1lO1xuXHR2YXIgYWxpYXM7XG5cdGlmIChoYXNPd24oTEVHQUNZX0FMSUFTRVMsIGludHJpbnNpY05hbWUpKSB7XG5cdFx0YWxpYXMgPSBMRUdBQ1lfQUxJQVNFU1tpbnRyaW5zaWNOYW1lXTtcblx0XHRpbnRyaW5zaWNOYW1lID0gJyUnICsgYWxpYXNbMF0gKyAnJSc7XG5cdH1cblxuXHRpZiAoaGFzT3duKElOVFJJTlNJQ1MsIGludHJpbnNpY05hbWUpKSB7XG5cdFx0dmFyIHZhbHVlID0gSU5UUklOU0lDU1tpbnRyaW5zaWNOYW1lXTtcblx0XHRpZiAodmFsdWUgPT09IG5lZWRzRXZhbCkge1xuXHRcdFx0dmFsdWUgPSBkb0V2YWwoaW50cmluc2ljTmFtZSk7XG5cdFx0fVxuXHRcdGlmICh0eXBlb2YgdmFsdWUgPT09ICd1bmRlZmluZWQnICYmICFhbGxvd01pc3NpbmcpIHtcblx0XHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdpbnRyaW5zaWMgJyArIG5hbWUgKyAnIGV4aXN0cywgYnV0IGlzIG5vdCBhdmFpbGFibGUuIFBsZWFzZSBmaWxlIGFuIGlzc3VlIScpO1xuXHRcdH1cblxuXHRcdHJldHVybiB7XG5cdFx0XHRhbGlhczogYWxpYXMsXG5cdFx0XHRuYW1lOiBpbnRyaW5zaWNOYW1lLFxuXHRcdFx0dmFsdWU6IHZhbHVlXG5cdFx0fTtcblx0fVxuXG5cdHRocm93IG5ldyAkU3ludGF4RXJyb3IoJ2ludHJpbnNpYyAnICsgbmFtZSArICcgZG9lcyBub3QgZXhpc3QhJyk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIEdldEludHJpbnNpYyhuYW1lLCBhbGxvd01pc3NpbmcpIHtcblx0aWYgKHR5cGVvZiBuYW1lICE9PSAnc3RyaW5nJyB8fCBuYW1lLmxlbmd0aCA9PT0gMCkge1xuXHRcdHRocm93IG5ldyAkVHlwZUVycm9yKCdpbnRyaW5zaWMgbmFtZSBtdXN0IGJlIGEgbm9uLWVtcHR5IHN0cmluZycpO1xuXHR9XG5cdGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSAmJiB0eXBlb2YgYWxsb3dNaXNzaW5nICE9PSAnYm9vbGVhbicpIHtcblx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignXCJhbGxvd01pc3NpbmdcIiBhcmd1bWVudCBtdXN0IGJlIGEgYm9vbGVhbicpO1xuXHR9XG5cblx0aWYgKCRleGVjKC9eJT9bXiVdKiU/JC8sIG5hbWUpID09PSBudWxsKSB7XG5cdFx0dGhyb3cgbmV3ICRTeW50YXhFcnJvcignYCVgIG1heSBub3QgYmUgcHJlc2VudCBhbnl3aGVyZSBidXQgYXQgdGhlIGJlZ2lubmluZyBhbmQgZW5kIG9mIHRoZSBpbnRyaW5zaWMgbmFtZScpO1xuXHR9XG5cdHZhciBwYXJ0cyA9IHN0cmluZ1RvUGF0aChuYW1lKTtcblx0dmFyIGludHJpbnNpY0Jhc2VOYW1lID0gcGFydHMubGVuZ3RoID4gMCA/IHBhcnRzWzBdIDogJyc7XG5cblx0dmFyIGludHJpbnNpYyA9IGdldEJhc2VJbnRyaW5zaWMoJyUnICsgaW50cmluc2ljQmFzZU5hbWUgKyAnJScsIGFsbG93TWlzc2luZyk7XG5cdHZhciBpbnRyaW5zaWNSZWFsTmFtZSA9IGludHJpbnNpYy5uYW1lO1xuXHR2YXIgdmFsdWUgPSBpbnRyaW5zaWMudmFsdWU7XG5cdHZhciBza2lwRnVydGhlckNhY2hpbmcgPSBmYWxzZTtcblxuXHR2YXIgYWxpYXMgPSBpbnRyaW5zaWMuYWxpYXM7XG5cdGlmIChhbGlhcykge1xuXHRcdGludHJpbnNpY0Jhc2VOYW1lID0gYWxpYXNbMF07XG5cdFx0JHNwbGljZUFwcGx5KHBhcnRzLCAkY29uY2F0KFswLCAxXSwgYWxpYXMpKTtcblx0fVxuXG5cdGZvciAodmFyIGkgPSAxLCBpc093biA9IHRydWU7IGkgPCBwYXJ0cy5sZW5ndGg7IGkgKz0gMSkge1xuXHRcdHZhciBwYXJ0ID0gcGFydHNbaV07XG5cdFx0dmFyIGZpcnN0ID0gJHN0clNsaWNlKHBhcnQsIDAsIDEpO1xuXHRcdHZhciBsYXN0ID0gJHN0clNsaWNlKHBhcnQsIC0xKTtcblx0XHRpZiAoXG5cdFx0XHQoXG5cdFx0XHRcdChmaXJzdCA9PT0gJ1wiJyB8fCBmaXJzdCA9PT0gXCInXCIgfHwgZmlyc3QgPT09ICdgJylcblx0XHRcdFx0fHwgKGxhc3QgPT09ICdcIicgfHwgbGFzdCA9PT0gXCInXCIgfHwgbGFzdCA9PT0gJ2AnKVxuXHRcdFx0KVxuXHRcdFx0JiYgZmlyc3QgIT09IGxhc3Rcblx0XHQpIHtcblx0XHRcdHRocm93IG5ldyAkU3ludGF4RXJyb3IoJ3Byb3BlcnR5IG5hbWVzIHdpdGggcXVvdGVzIG11c3QgaGF2ZSBtYXRjaGluZyBxdW90ZXMnKTtcblx0XHR9XG5cdFx0aWYgKHBhcnQgPT09ICdjb25zdHJ1Y3RvcicgfHwgIWlzT3duKSB7XG5cdFx0XHRza2lwRnVydGhlckNhY2hpbmcgPSB0cnVlO1xuXHRcdH1cblxuXHRcdGludHJpbnNpY0Jhc2VOYW1lICs9ICcuJyArIHBhcnQ7XG5cdFx0aW50cmluc2ljUmVhbE5hbWUgPSAnJScgKyBpbnRyaW5zaWNCYXNlTmFtZSArICclJztcblxuXHRcdGlmIChoYXNPd24oSU5UUklOU0lDUywgaW50cmluc2ljUmVhbE5hbWUpKSB7XG5cdFx0XHR2YWx1ZSA9IElOVFJJTlNJQ1NbaW50cmluc2ljUmVhbE5hbWVdO1xuXHRcdH0gZWxzZSBpZiAodmFsdWUgIT0gbnVsbCkge1xuXHRcdFx0aWYgKCEocGFydCBpbiB2YWx1ZSkpIHtcblx0XHRcdFx0aWYgKCFhbGxvd01pc3NpbmcpIHtcblx0XHRcdFx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignYmFzZSBpbnRyaW5zaWMgZm9yICcgKyBuYW1lICsgJyBleGlzdHMsIGJ1dCB0aGUgcHJvcGVydHkgaXMgbm90IGF2YWlsYWJsZS4nKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gdm9pZCB1bmRlZmluZWQ7XG5cdFx0XHR9XG5cdFx0XHRpZiAoJGdPUEQgJiYgKGkgKyAxKSA+PSBwYXJ0cy5sZW5ndGgpIHtcblx0XHRcdFx0dmFyIGRlc2MgPSAkZ09QRCh2YWx1ZSwgcGFydCk7XG5cdFx0XHRcdGlzT3duID0gISFkZXNjO1xuXG5cdFx0XHRcdC8vIEJ5IGNvbnZlbnRpb24sIHdoZW4gYSBkYXRhIHByb3BlcnR5IGlzIGNvbnZlcnRlZCB0byBhbiBhY2Nlc3NvclxuXHRcdFx0XHQvLyBwcm9wZXJ0eSB0byBlbXVsYXRlIGEgZGF0YSBwcm9wZXJ0eSB0aGF0IGRvZXMgbm90IHN1ZmZlciBmcm9tXG5cdFx0XHRcdC8vIHRoZSBvdmVycmlkZSBtaXN0YWtlLCB0aGF0IGFjY2Vzc29yJ3MgZ2V0dGVyIGlzIG1hcmtlZCB3aXRoXG5cdFx0XHRcdC8vIGFuIGBvcmlnaW5hbFZhbHVlYCBwcm9wZXJ0eS4gSGVyZSwgd2hlbiB3ZSBkZXRlY3QgdGhpcywgd2Vcblx0XHRcdFx0Ly8gdXBob2xkIHRoZSBpbGx1c2lvbiBieSBwcmV0ZW5kaW5nIHRvIHNlZSB0aGF0IG9yaWdpbmFsIGRhdGFcblx0XHRcdFx0Ly8gcHJvcGVydHksIGkuZS4sIHJldHVybmluZyB0aGUgdmFsdWUgcmF0aGVyIHRoYW4gdGhlIGdldHRlclxuXHRcdFx0XHQvLyBpdHNlbGYuXG5cdFx0XHRcdGlmIChpc093biAmJiAnZ2V0JyBpbiBkZXNjICYmICEoJ29yaWdpbmFsVmFsdWUnIGluIGRlc2MuZ2V0KSkge1xuXHRcdFx0XHRcdHZhbHVlID0gZGVzYy5nZXQ7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0dmFsdWUgPSB2YWx1ZVtwYXJ0XTtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0aXNPd24gPSBoYXNPd24odmFsdWUsIHBhcnQpO1xuXHRcdFx0XHR2YWx1ZSA9IHZhbHVlW3BhcnRdO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoaXNPd24gJiYgIXNraXBGdXJ0aGVyQ2FjaGluZykge1xuXHRcdFx0XHRJTlRSSU5TSUNTW2ludHJpbnNpY1JlYWxOYW1lXSA9IHZhbHVlO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXHRyZXR1cm4gdmFsdWU7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgJE9iamVjdCA9IHJlcXVpcmUoJ2VzLW9iamVjdC1hdG9tcycpO1xuXG4vKiogQHR5cGUge2ltcG9ydCgnLi9PYmplY3QuZ2V0UHJvdG90eXBlT2YnKX0gKi9cbm1vZHVsZS5leHBvcnRzID0gJE9iamVjdC5nZXRQcm90b3R5cGVPZiB8fCBudWxsO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKiogQHR5cGUge2ltcG9ydCgnLi9SZWZsZWN0LmdldFByb3RvdHlwZU9mJyl9ICovXG5tb2R1bGUuZXhwb3J0cyA9ICh0eXBlb2YgUmVmbGVjdCAhPT0gJ3VuZGVmaW5lZCcgJiYgUmVmbGVjdC5nZXRQcm90b3R5cGVPZikgfHwgbnVsbDtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHJlZmxlY3RHZXRQcm90byA9IHJlcXVpcmUoJy4vUmVmbGVjdC5nZXRQcm90b3R5cGVPZicpO1xudmFyIG9yaWdpbmFsR2V0UHJvdG8gPSByZXF1aXJlKCcuL09iamVjdC5nZXRQcm90b3R5cGVPZicpO1xuXG52YXIgZ2V0RHVuZGVyUHJvdG8gPSByZXF1aXJlKCdkdW5kZXItcHJvdG8vZ2V0Jyk7XG5cbi8qKiBAdHlwZSB7aW1wb3J0KCcuJyl9ICovXG5tb2R1bGUuZXhwb3J0cyA9IHJlZmxlY3RHZXRQcm90b1xuXHQ/IGZ1bmN0aW9uIGdldFByb3RvKE8pIHtcblx0XHQvLyBAdHMtZXhwZWN0LWVycm9yIFRTIGNhbid0IG5hcnJvdyBpbnNpZGUgYSBjbG9zdXJlLCBmb3Igc29tZSByZWFzb25cblx0XHRyZXR1cm4gcmVmbGVjdEdldFByb3RvKE8pO1xuXHR9XG5cdDogb3JpZ2luYWxHZXRQcm90b1xuXHRcdD8gZnVuY3Rpb24gZ2V0UHJvdG8oTykge1xuXHRcdFx0aWYgKCFPIHx8ICh0eXBlb2YgTyAhPT0gJ29iamVjdCcgJiYgdHlwZW9mIE8gIT09ICdmdW5jdGlvbicpKSB7XG5cdFx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ2dldFByb3RvOiBub3QgYW4gb2JqZWN0Jyk7XG5cdFx0XHR9XG5cdFx0XHQvLyBAdHMtZXhwZWN0LWVycm9yIFRTIGNhbid0IG5hcnJvdyBpbnNpZGUgYSBjbG9zdXJlLCBmb3Igc29tZSByZWFzb25cblx0XHRcdHJldHVybiBvcmlnaW5hbEdldFByb3RvKE8pO1xuXHRcdH1cblx0XHQ6IGdldER1bmRlclByb3RvXG5cdFx0XHQ/IGZ1bmN0aW9uIGdldFByb3RvKE8pIHtcblx0XHRcdFx0Ly8gQHRzLWV4cGVjdC1lcnJvciBUUyBjYW4ndCBuYXJyb3cgaW5zaWRlIGEgY2xvc3VyZSwgZm9yIHNvbWUgcmVhc29uXG5cdFx0XHRcdHJldHVybiBnZXREdW5kZXJQcm90byhPKTtcblx0XHRcdH1cblx0XHRcdDogbnVsbDtcbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqIEB0eXBlIHtpbXBvcnQoJy4vZ09QRCcpfSAqL1xubW9kdWxlLmV4cG9ydHMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKiogQHR5cGUge2ltcG9ydCgnLicpfSAqL1xudmFyICRnT1BEID0gcmVxdWlyZSgnLi9nT1BEJyk7XG5cbmlmICgkZ09QRCkge1xuXHR0cnkge1xuXHRcdCRnT1BEKFtdLCAnbGVuZ3RoJyk7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHQvLyBJRSA4IGhhcyBhIGJyb2tlbiBnT1BEXG5cdFx0JGdPUEQgPSBudWxsO1xuXHR9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gJGdPUEQ7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBvcmlnU3ltYm9sID0gdHlwZW9mIFN5bWJvbCAhPT0gJ3VuZGVmaW5lZCcgJiYgU3ltYm9sO1xudmFyIGhhc1N5bWJvbFNoYW0gPSByZXF1aXJlKCcuL3NoYW1zJyk7XG5cbi8qKiBAdHlwZSB7aW1wb3J0KCcuJyl9ICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGhhc05hdGl2ZVN5bWJvbHMoKSB7XG5cdGlmICh0eXBlb2Ygb3JpZ1N5bWJvbCAhPT0gJ2Z1bmN0aW9uJykgeyByZXR1cm4gZmFsc2U7IH1cblx0aWYgKHR5cGVvZiBTeW1ib2wgIT09ICdmdW5jdGlvbicpIHsgcmV0dXJuIGZhbHNlOyB9XG5cdGlmICh0eXBlb2Ygb3JpZ1N5bWJvbCgnZm9vJykgIT09ICdzeW1ib2wnKSB7IHJldHVybiBmYWxzZTsgfVxuXHRpZiAodHlwZW9mIFN5bWJvbCgnYmFyJykgIT09ICdzeW1ib2wnKSB7IHJldHVybiBmYWxzZTsgfVxuXG5cdHJldHVybiBoYXNTeW1ib2xTaGFtKCk7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKiogQHR5cGUge2ltcG9ydCgnLi9zaGFtcycpfSAqL1xuLyogZXNsaW50IGNvbXBsZXhpdHk6IFsyLCAxOF0sIG1heC1zdGF0ZW1lbnRzOiBbMiwgMzNdICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGhhc1N5bWJvbHMoKSB7XG5cdGlmICh0eXBlb2YgU3ltYm9sICE9PSAnZnVuY3Rpb24nIHx8IHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzICE9PSAnZnVuY3Rpb24nKSB7IHJldHVybiBmYWxzZTsgfVxuXHRpZiAodHlwZW9mIFN5bWJvbC5pdGVyYXRvciA9PT0gJ3N5bWJvbCcpIHsgcmV0dXJuIHRydWU7IH1cblxuXHQvKiogQHR5cGUge3sgW2sgaW4gc3ltYm9sXT86IHVua25vd24gfX0gKi9cblx0dmFyIG9iaiA9IHt9O1xuXHR2YXIgc3ltID0gU3ltYm9sKCd0ZXN0Jyk7XG5cdHZhciBzeW1PYmogPSBPYmplY3Qoc3ltKTtcblx0aWYgKHR5cGVvZiBzeW0gPT09ICdzdHJpbmcnKSB7IHJldHVybiBmYWxzZTsgfVxuXG5cdGlmIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoc3ltKSAhPT0gJ1tvYmplY3QgU3ltYm9sXScpIHsgcmV0dXJuIGZhbHNlOyB9XG5cdGlmIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoc3ltT2JqKSAhPT0gJ1tvYmplY3QgU3ltYm9sXScpIHsgcmV0dXJuIGZhbHNlOyB9XG5cblx0Ly8gdGVtcCBkaXNhYmxlZCBwZXIgaHR0cHM6Ly9naXRodWIuY29tL2xqaGFyYi9vYmplY3QuYXNzaWduL2lzc3Vlcy8xN1xuXHQvLyBpZiAoc3ltIGluc3RhbmNlb2YgU3ltYm9sKSB7IHJldHVybiBmYWxzZTsgfVxuXHQvLyB0ZW1wIGRpc2FibGVkIHBlciBodHRwczovL2dpdGh1Yi5jb20vV2ViUmVmbGVjdGlvbi9nZXQtb3duLXByb3BlcnR5LXN5bWJvbHMvaXNzdWVzLzRcblx0Ly8gaWYgKCEoc3ltT2JqIGluc3RhbmNlb2YgU3ltYm9sKSkgeyByZXR1cm4gZmFsc2U7IH1cblxuXHQvLyBpZiAodHlwZW9mIFN5bWJvbC5wcm90b3R5cGUudG9TdHJpbmcgIT09ICdmdW5jdGlvbicpIHsgcmV0dXJuIGZhbHNlOyB9XG5cdC8vIGlmIChTdHJpbmcoc3ltKSAhPT0gU3ltYm9sLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHN5bSkpIHsgcmV0dXJuIGZhbHNlOyB9XG5cblx0dmFyIHN5bVZhbCA9IDQyO1xuXHRvYmpbc3ltXSA9IHN5bVZhbDtcblx0Zm9yICh2YXIgXyBpbiBvYmopIHsgcmV0dXJuIGZhbHNlOyB9IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tcmVzdHJpY3RlZC1zeW50YXgsIG5vLXVucmVhY2hhYmxlLWxvb3Bcblx0aWYgKHR5cGVvZiBPYmplY3Qua2V5cyA9PT0gJ2Z1bmN0aW9uJyAmJiBPYmplY3Qua2V5cyhvYmopLmxlbmd0aCAhPT0gMCkgeyByZXR1cm4gZmFsc2U7IH1cblxuXHRpZiAodHlwZW9mIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzID09PSAnZnVuY3Rpb24nICYmIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKG9iaikubGVuZ3RoICE9PSAwKSB7IHJldHVybiBmYWxzZTsgfVxuXG5cdHZhciBzeW1zID0gT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhvYmopO1xuXHRpZiAoc3ltcy5sZW5ndGggIT09IDEgfHwgc3ltc1swXSAhPT0gc3ltKSB7IHJldHVybiBmYWxzZTsgfVxuXG5cdGlmICghT2JqZWN0LnByb3RvdHlwZS5wcm9wZXJ0eUlzRW51bWVyYWJsZS5jYWxsKG9iaiwgc3ltKSkgeyByZXR1cm4gZmFsc2U7IH1cblxuXHRpZiAodHlwZW9mIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IgPT09ICdmdW5jdGlvbicpIHtcblx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tZXh0cmEtcGFyZW5zXG5cdFx0dmFyIGRlc2NyaXB0b3IgPSAvKiogQHR5cGUge1Byb3BlcnR5RGVzY3JpcHRvcn0gKi8gKE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Iob2JqLCBzeW0pKTtcblx0XHRpZiAoZGVzY3JpcHRvci52YWx1ZSAhPT0gc3ltVmFsIHx8IGRlc2NyaXB0b3IuZW51bWVyYWJsZSAhPT0gdHJ1ZSkgeyByZXR1cm4gZmFsc2U7IH1cblx0fVxuXG5cdHJldHVybiB0cnVlO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGNhbGwgPSBGdW5jdGlvbi5wcm90b3R5cGUuY2FsbDtcbnZhciAkaGFzT3duID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcbnZhciBiaW5kID0gcmVxdWlyZSgnZnVuY3Rpb24tYmluZCcpO1xuXG4vKiogQHR5cGUge2ltcG9ydCgnLicpfSAqL1xubW9kdWxlLmV4cG9ydHMgPSBiaW5kLmNhbGwoY2FsbCwgJGhhc093bik7XG4iLCIvKiEgaWVlZTc1NC4gQlNELTMtQ2xhdXNlIExpY2Vuc2UuIEZlcm9zcyBBYm91a2hhZGlqZWggPGh0dHBzOi8vZmVyb3NzLm9yZy9vcGVuc291cmNlPiAqL1xuZXhwb3J0cy5yZWFkID0gZnVuY3Rpb24gKGJ1ZmZlciwgb2Zmc2V0LCBpc0xFLCBtTGVuLCBuQnl0ZXMpIHtcbiAgdmFyIGUsIG1cbiAgdmFyIGVMZW4gPSAobkJ5dGVzICogOCkgLSBtTGVuIC0gMVxuICB2YXIgZU1heCA9ICgxIDw8IGVMZW4pIC0gMVxuICB2YXIgZUJpYXMgPSBlTWF4ID4+IDFcbiAgdmFyIG5CaXRzID0gLTdcbiAgdmFyIGkgPSBpc0xFID8gKG5CeXRlcyAtIDEpIDogMFxuICB2YXIgZCA9IGlzTEUgPyAtMSA6IDFcbiAgdmFyIHMgPSBidWZmZXJbb2Zmc2V0ICsgaV1cblxuICBpICs9IGRcblxuICBlID0gcyAmICgoMSA8PCAoLW5CaXRzKSkgLSAxKVxuICBzID4+PSAoLW5CaXRzKVxuICBuQml0cyArPSBlTGVuXG4gIGZvciAoOyBuQml0cyA+IDA7IGUgPSAoZSAqIDI1NikgKyBidWZmZXJbb2Zmc2V0ICsgaV0sIGkgKz0gZCwgbkJpdHMgLT0gOCkge31cblxuICBtID0gZSAmICgoMSA8PCAoLW5CaXRzKSkgLSAxKVxuICBlID4+PSAoLW5CaXRzKVxuICBuQml0cyArPSBtTGVuXG4gIGZvciAoOyBuQml0cyA+IDA7IG0gPSAobSAqIDI1NikgKyBidWZmZXJbb2Zmc2V0ICsgaV0sIGkgKz0gZCwgbkJpdHMgLT0gOCkge31cblxuICBpZiAoZSA9PT0gMCkge1xuICAgIGUgPSAxIC0gZUJpYXNcbiAgfSBlbHNlIGlmIChlID09PSBlTWF4KSB7XG4gICAgcmV0dXJuIG0gPyBOYU4gOiAoKHMgPyAtMSA6IDEpICogSW5maW5pdHkpXG4gIH0gZWxzZSB7XG4gICAgbSA9IG0gKyBNYXRoLnBvdygyLCBtTGVuKVxuICAgIGUgPSBlIC0gZUJpYXNcbiAgfVxuICByZXR1cm4gKHMgPyAtMSA6IDEpICogbSAqIE1hdGgucG93KDIsIGUgLSBtTGVuKVxufVxuXG5leHBvcnRzLndyaXRlID0gZnVuY3Rpb24gKGJ1ZmZlciwgdmFsdWUsIG9mZnNldCwgaXNMRSwgbUxlbiwgbkJ5dGVzKSB7XG4gIHZhciBlLCBtLCBjXG4gIHZhciBlTGVuID0gKG5CeXRlcyAqIDgpIC0gbUxlbiAtIDFcbiAgdmFyIGVNYXggPSAoMSA8PCBlTGVuKSAtIDFcbiAgdmFyIGVCaWFzID0gZU1heCA+PiAxXG4gIHZhciBydCA9IChtTGVuID09PSAyMyA/IE1hdGgucG93KDIsIC0yNCkgLSBNYXRoLnBvdygyLCAtNzcpIDogMClcbiAgdmFyIGkgPSBpc0xFID8gMCA6IChuQnl0ZXMgLSAxKVxuICB2YXIgZCA9IGlzTEUgPyAxIDogLTFcbiAgdmFyIHMgPSB2YWx1ZSA8IDAgfHwgKHZhbHVlID09PSAwICYmIDEgLyB2YWx1ZSA8IDApID8gMSA6IDBcblxuICB2YWx1ZSA9IE1hdGguYWJzKHZhbHVlKVxuXG4gIGlmIChpc05hTih2YWx1ZSkgfHwgdmFsdWUgPT09IEluZmluaXR5KSB7XG4gICAgbSA9IGlzTmFOKHZhbHVlKSA/IDEgOiAwXG4gICAgZSA9IGVNYXhcbiAgfSBlbHNlIHtcbiAgICBlID0gTWF0aC5mbG9vcihNYXRoLmxvZyh2YWx1ZSkgLyBNYXRoLkxOMilcbiAgICBpZiAodmFsdWUgKiAoYyA9IE1hdGgucG93KDIsIC1lKSkgPCAxKSB7XG4gICAgICBlLS1cbiAgICAgIGMgKj0gMlxuICAgIH1cbiAgICBpZiAoZSArIGVCaWFzID49IDEpIHtcbiAgICAgIHZhbHVlICs9IHJ0IC8gY1xuICAgIH0gZWxzZSB7XG4gICAgICB2YWx1ZSArPSBydCAqIE1hdGgucG93KDIsIDEgLSBlQmlhcylcbiAgICB9XG4gICAgaWYgKHZhbHVlICogYyA+PSAyKSB7XG4gICAgICBlKytcbiAgICAgIGMgLz0gMlxuICAgIH1cblxuICAgIGlmIChlICsgZUJpYXMgPj0gZU1heCkge1xuICAgICAgbSA9IDBcbiAgICAgIGUgPSBlTWF4XG4gICAgfSBlbHNlIGlmIChlICsgZUJpYXMgPj0gMSkge1xuICAgICAgbSA9ICgodmFsdWUgKiBjKSAtIDEpICogTWF0aC5wb3coMiwgbUxlbilcbiAgICAgIGUgPSBlICsgZUJpYXNcbiAgICB9IGVsc2Uge1xuICAgICAgbSA9IHZhbHVlICogTWF0aC5wb3coMiwgZUJpYXMgLSAxKSAqIE1hdGgucG93KDIsIG1MZW4pXG4gICAgICBlID0gMFxuICAgIH1cbiAgfVxuXG4gIGZvciAoOyBtTGVuID49IDg7IGJ1ZmZlcltvZmZzZXQgKyBpXSA9IG0gJiAweGZmLCBpICs9IGQsIG0gLz0gMjU2LCBtTGVuIC09IDgpIHt9XG5cbiAgZSA9IChlIDw8IG1MZW4pIHwgbVxuICBlTGVuICs9IG1MZW5cbiAgZm9yICg7IGVMZW4gPiAwOyBidWZmZXJbb2Zmc2V0ICsgaV0gPSBlICYgMHhmZiwgaSArPSBkLCBlIC89IDI1NiwgZUxlbiAtPSA4KSB7fVxuXG4gIGJ1ZmZlcltvZmZzZXQgKyBpIC0gZF0gfD0gcyAqIDEyOFxufVxuIiwiaWYgKHR5cGVvZiBPYmplY3QuY3JlYXRlID09PSAnZnVuY3Rpb24nKSB7XG4gIC8vIGltcGxlbWVudGF0aW9uIGZyb20gc3RhbmRhcmQgbm9kZS5qcyAndXRpbCcgbW9kdWxlXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgaWYgKHN1cGVyQ3Rvcikge1xuICAgICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICAgIGN0b3IucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckN0b3IucHJvdG90eXBlLCB7XG4gICAgICAgIGNvbnN0cnVjdG9yOiB7XG4gICAgICAgICAgdmFsdWU6IGN0b3IsXG4gICAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgfVxuICB9O1xufSBlbHNlIHtcbiAgLy8gb2xkIHNjaG9vbCBzaGltIGZvciBvbGQgYnJvd3NlcnNcbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpbmhlcml0cyhjdG9yLCBzdXBlckN0b3IpIHtcbiAgICBpZiAoc3VwZXJDdG9yKSB7XG4gICAgICBjdG9yLnN1cGVyXyA9IHN1cGVyQ3RvclxuICAgICAgdmFyIFRlbXBDdG9yID0gZnVuY3Rpb24gKCkge31cbiAgICAgIFRlbXBDdG9yLnByb3RvdHlwZSA9IHN1cGVyQ3Rvci5wcm90b3R5cGVcbiAgICAgIGN0b3IucHJvdG90eXBlID0gbmV3IFRlbXBDdG9yKClcbiAgICAgIGN0b3IucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gY3RvclxuICAgIH1cbiAgfVxufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKiogQHR5cGUge2ltcG9ydCgnLi9hYnMnKX0gKi9cbm1vZHVsZS5leHBvcnRzID0gTWF0aC5hYnM7XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKiBAdHlwZSB7aW1wb3J0KCcuL2Zsb29yJyl9ICovXG5tb2R1bGUuZXhwb3J0cyA9IE1hdGguZmxvb3I7XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKiBAdHlwZSB7aW1wb3J0KCcuL2lzTmFOJyl9ICovXG5tb2R1bGUuZXhwb3J0cyA9IE51bWJlci5pc05hTiB8fCBmdW5jdGlvbiBpc05hTihhKSB7XG5cdHJldHVybiBhICE9PSBhO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqIEB0eXBlIHtpbXBvcnQoJy4vbWF4Jyl9ICovXG5tb2R1bGUuZXhwb3J0cyA9IE1hdGgubWF4O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKiogQHR5cGUge2ltcG9ydCgnLi9taW4nKX0gKi9cbm1vZHVsZS5leHBvcnRzID0gTWF0aC5taW47XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKiBAdHlwZSB7aW1wb3J0KCcuL3BvdycpfSAqL1xubW9kdWxlLmV4cG9ydHMgPSBNYXRoLnBvdztcbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqIEB0eXBlIHtpbXBvcnQoJy4vcm91bmQnKX0gKi9cbm1vZHVsZS5leHBvcnRzID0gTWF0aC5yb3VuZDtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyICRpc05hTiA9IHJlcXVpcmUoJy4vaXNOYU4nKTtcblxuLyoqIEB0eXBlIHtpbXBvcnQoJy4vc2lnbicpfSAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBzaWduKG51bWJlcikge1xuXHRpZiAoJGlzTmFOKG51bWJlcikgfHwgbnVtYmVyID09PSAwKSB7XG5cdFx0cmV0dXJuIG51bWJlcjtcblx0fVxuXHRyZXR1cm4gbnVtYmVyIDwgMCA/IC0xIDogKzE7XG59O1xuIiwidmFyIGhhc01hcCA9IHR5cGVvZiBNYXAgPT09ICdmdW5jdGlvbicgJiYgTWFwLnByb3RvdHlwZTtcbnZhciBtYXBTaXplRGVzY3JpcHRvciA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IgJiYgaGFzTWFwID8gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihNYXAucHJvdG90eXBlLCAnc2l6ZScpIDogbnVsbDtcbnZhciBtYXBTaXplID0gaGFzTWFwICYmIG1hcFNpemVEZXNjcmlwdG9yICYmIHR5cGVvZiBtYXBTaXplRGVzY3JpcHRvci5nZXQgPT09ICdmdW5jdGlvbicgPyBtYXBTaXplRGVzY3JpcHRvci5nZXQgOiBudWxsO1xudmFyIG1hcEZvckVhY2ggPSBoYXNNYXAgJiYgTWFwLnByb3RvdHlwZS5mb3JFYWNoO1xudmFyIGhhc1NldCA9IHR5cGVvZiBTZXQgPT09ICdmdW5jdGlvbicgJiYgU2V0LnByb3RvdHlwZTtcbnZhciBzZXRTaXplRGVzY3JpcHRvciA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IgJiYgaGFzU2V0ID8gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihTZXQucHJvdG90eXBlLCAnc2l6ZScpIDogbnVsbDtcbnZhciBzZXRTaXplID0gaGFzU2V0ICYmIHNldFNpemVEZXNjcmlwdG9yICYmIHR5cGVvZiBzZXRTaXplRGVzY3JpcHRvci5nZXQgPT09ICdmdW5jdGlvbicgPyBzZXRTaXplRGVzY3JpcHRvci5nZXQgOiBudWxsO1xudmFyIHNldEZvckVhY2ggPSBoYXNTZXQgJiYgU2V0LnByb3RvdHlwZS5mb3JFYWNoO1xudmFyIGhhc1dlYWtNYXAgPSB0eXBlb2YgV2Vha01hcCA9PT0gJ2Z1bmN0aW9uJyAmJiBXZWFrTWFwLnByb3RvdHlwZTtcbnZhciB3ZWFrTWFwSGFzID0gaGFzV2Vha01hcCA/IFdlYWtNYXAucHJvdG90eXBlLmhhcyA6IG51bGw7XG52YXIgaGFzV2Vha1NldCA9IHR5cGVvZiBXZWFrU2V0ID09PSAnZnVuY3Rpb24nICYmIFdlYWtTZXQucHJvdG90eXBlO1xudmFyIHdlYWtTZXRIYXMgPSBoYXNXZWFrU2V0ID8gV2Vha1NldC5wcm90b3R5cGUuaGFzIDogbnVsbDtcbnZhciBoYXNXZWFrUmVmID0gdHlwZW9mIFdlYWtSZWYgPT09ICdmdW5jdGlvbicgJiYgV2Vha1JlZi5wcm90b3R5cGU7XG52YXIgd2Vha1JlZkRlcmVmID0gaGFzV2Vha1JlZiA/IFdlYWtSZWYucHJvdG90eXBlLmRlcmVmIDogbnVsbDtcbnZhciBib29sZWFuVmFsdWVPZiA9IEJvb2xlYW4ucHJvdG90eXBlLnZhbHVlT2Y7XG52YXIgb2JqZWN0VG9TdHJpbmcgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xudmFyIGZ1bmN0aW9uVG9TdHJpbmcgPSBGdW5jdGlvbi5wcm90b3R5cGUudG9TdHJpbmc7XG52YXIgJG1hdGNoID0gU3RyaW5nLnByb3RvdHlwZS5tYXRjaDtcbnZhciAkc2xpY2UgPSBTdHJpbmcucHJvdG90eXBlLnNsaWNlO1xudmFyICRyZXBsYWNlID0gU3RyaW5nLnByb3RvdHlwZS5yZXBsYWNlO1xudmFyICR0b1VwcGVyQ2FzZSA9IFN0cmluZy5wcm90b3R5cGUudG9VcHBlckNhc2U7XG52YXIgJHRvTG93ZXJDYXNlID0gU3RyaW5nLnByb3RvdHlwZS50b0xvd2VyQ2FzZTtcbnZhciAkdGVzdCA9IFJlZ0V4cC5wcm90b3R5cGUudGVzdDtcbnZhciAkY29uY2F0ID0gQXJyYXkucHJvdG90eXBlLmNvbmNhdDtcbnZhciAkam9pbiA9IEFycmF5LnByb3RvdHlwZS5qb2luO1xudmFyICRhcnJTbGljZSA9IEFycmF5LnByb3RvdHlwZS5zbGljZTtcbnZhciAkZmxvb3IgPSBNYXRoLmZsb29yO1xudmFyIGJpZ0ludFZhbHVlT2YgPSB0eXBlb2YgQmlnSW50ID09PSAnZnVuY3Rpb24nID8gQmlnSW50LnByb3RvdHlwZS52YWx1ZU9mIDogbnVsbDtcbnZhciBnT1BTID0gT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scztcbnZhciBzeW1Ub1N0cmluZyA9IHR5cGVvZiBTeW1ib2wgPT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIFN5bWJvbC5pdGVyYXRvciA9PT0gJ3N5bWJvbCcgPyBTeW1ib2wucHJvdG90eXBlLnRvU3RyaW5nIDogbnVsbDtcbnZhciBoYXNTaGFtbWVkU3ltYm9scyA9IHR5cGVvZiBTeW1ib2wgPT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIFN5bWJvbC5pdGVyYXRvciA9PT0gJ29iamVjdCc7XG4vLyBpZSwgYGhhcy10b3N0cmluZ3RhZy9zaGFtc1xudmFyIHRvU3RyaW5nVGFnID0gdHlwZW9mIFN5bWJvbCA9PT0gJ2Z1bmN0aW9uJyAmJiBTeW1ib2wudG9TdHJpbmdUYWcgJiYgKHR5cGVvZiBTeW1ib2wudG9TdHJpbmdUYWcgPT09IGhhc1NoYW1tZWRTeW1ib2xzID8gJ29iamVjdCcgOiAnc3ltYm9sJylcbiAgICA/IFN5bWJvbC50b1N0cmluZ1RhZ1xuICAgIDogbnVsbDtcbnZhciBpc0VudW1lcmFibGUgPSBPYmplY3QucHJvdG90eXBlLnByb3BlcnR5SXNFbnVtZXJhYmxlO1xuXG52YXIgZ1BPID0gKHR5cGVvZiBSZWZsZWN0ID09PSAnZnVuY3Rpb24nID8gUmVmbGVjdC5nZXRQcm90b3R5cGVPZiA6IE9iamVjdC5nZXRQcm90b3R5cGVPZikgfHwgKFxuICAgIFtdLl9fcHJvdG9fXyA9PT0gQXJyYXkucHJvdG90eXBlIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tcHJvdG9cbiAgICAgICAgPyBmdW5jdGlvbiAoTykge1xuICAgICAgICAgICAgcmV0dXJuIE8uX19wcm90b19fOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXByb3RvXG4gICAgICAgIH1cbiAgICAgICAgOiBudWxsXG4pO1xuXG5mdW5jdGlvbiBhZGROdW1lcmljU2VwYXJhdG9yKG51bSwgc3RyKSB7XG4gICAgaWYgKFxuICAgICAgICBudW0gPT09IEluZmluaXR5XG4gICAgICAgIHx8IG51bSA9PT0gLUluZmluaXR5XG4gICAgICAgIHx8IG51bSAhPT0gbnVtXG4gICAgICAgIHx8IChudW0gJiYgbnVtID4gLTEwMDAgJiYgbnVtIDwgMTAwMClcbiAgICAgICAgfHwgJHRlc3QuY2FsbCgvZS8sIHN0cilcbiAgICApIHtcbiAgICAgICAgcmV0dXJuIHN0cjtcbiAgICB9XG4gICAgdmFyIHNlcFJlZ2V4ID0gL1swLTldKD89KD86WzAtOV17M30pKyg/IVswLTldKSkvZztcbiAgICBpZiAodHlwZW9mIG51bSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgdmFyIGludCA9IG51bSA8IDAgPyAtJGZsb29yKC1udW0pIDogJGZsb29yKG51bSk7IC8vIHRydW5jKG51bSlcbiAgICAgICAgaWYgKGludCAhPT0gbnVtKSB7XG4gICAgICAgICAgICB2YXIgaW50U3RyID0gU3RyaW5nKGludCk7XG4gICAgICAgICAgICB2YXIgZGVjID0gJHNsaWNlLmNhbGwoc3RyLCBpbnRTdHIubGVuZ3RoICsgMSk7XG4gICAgICAgICAgICByZXR1cm4gJHJlcGxhY2UuY2FsbChpbnRTdHIsIHNlcFJlZ2V4LCAnJCZfJykgKyAnLicgKyAkcmVwbGFjZS5jYWxsKCRyZXBsYWNlLmNhbGwoZGVjLCAvKFswLTldezN9KS9nLCAnJCZfJyksIC9fJC8sICcnKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gJHJlcGxhY2UuY2FsbChzdHIsIHNlcFJlZ2V4LCAnJCZfJyk7XG59XG5cbnZhciB1dGlsSW5zcGVjdCA9IHJlcXVpcmUoJy4vdXRpbC5pbnNwZWN0Jyk7XG52YXIgaW5zcGVjdEN1c3RvbSA9IHV0aWxJbnNwZWN0LmN1c3RvbTtcbnZhciBpbnNwZWN0U3ltYm9sID0gaXNTeW1ib2woaW5zcGVjdEN1c3RvbSkgPyBpbnNwZWN0Q3VzdG9tIDogbnVsbDtcblxudmFyIHF1b3RlcyA9IHtcbiAgICBfX3Byb3RvX186IG51bGwsXG4gICAgJ2RvdWJsZSc6ICdcIicsXG4gICAgc2luZ2xlOiBcIidcIlxufTtcbnZhciBxdW90ZVJFcyA9IHtcbiAgICBfX3Byb3RvX186IG51bGwsXG4gICAgJ2RvdWJsZSc6IC8oW1wiXFxcXF0pL2csXG4gICAgc2luZ2xlOiAvKFsnXFxcXF0pL2dcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5zcGVjdF8ob2JqLCBvcHRpb25zLCBkZXB0aCwgc2Vlbikge1xuICAgIHZhciBvcHRzID0gb3B0aW9ucyB8fCB7fTtcblxuICAgIGlmIChoYXMob3B0cywgJ3F1b3RlU3R5bGUnKSAmJiAhaGFzKHF1b3Rlcywgb3B0cy5xdW90ZVN0eWxlKSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdvcHRpb24gXCJxdW90ZVN0eWxlXCIgbXVzdCBiZSBcInNpbmdsZVwiIG9yIFwiZG91YmxlXCInKTtcbiAgICB9XG4gICAgaWYgKFxuICAgICAgICBoYXMob3B0cywgJ21heFN0cmluZ0xlbmd0aCcpICYmICh0eXBlb2Ygb3B0cy5tYXhTdHJpbmdMZW5ndGggPT09ICdudW1iZXInXG4gICAgICAgICAgICA/IG9wdHMubWF4U3RyaW5nTGVuZ3RoIDwgMCAmJiBvcHRzLm1heFN0cmluZ0xlbmd0aCAhPT0gSW5maW5pdHlcbiAgICAgICAgICAgIDogb3B0cy5tYXhTdHJpbmdMZW5ndGggIT09IG51bGxcbiAgICAgICAgKVxuICAgICkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdvcHRpb24gXCJtYXhTdHJpbmdMZW5ndGhcIiwgaWYgcHJvdmlkZWQsIG11c3QgYmUgYSBwb3NpdGl2ZSBpbnRlZ2VyLCBJbmZpbml0eSwgb3IgYG51bGxgJyk7XG4gICAgfVxuICAgIHZhciBjdXN0b21JbnNwZWN0ID0gaGFzKG9wdHMsICdjdXN0b21JbnNwZWN0JykgPyBvcHRzLmN1c3RvbUluc3BlY3QgOiB0cnVlO1xuICAgIGlmICh0eXBlb2YgY3VzdG9tSW5zcGVjdCAhPT0gJ2Jvb2xlYW4nICYmIGN1c3RvbUluc3BlY3QgIT09ICdzeW1ib2wnKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ29wdGlvbiBcImN1c3RvbUluc3BlY3RcIiwgaWYgcHJvdmlkZWQsIG11c3QgYmUgYHRydWVgLCBgZmFsc2VgLCBvciBgXFwnc3ltYm9sXFwnYCcpO1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgICAgaGFzKG9wdHMsICdpbmRlbnQnKVxuICAgICAgICAmJiBvcHRzLmluZGVudCAhPT0gbnVsbFxuICAgICAgICAmJiBvcHRzLmluZGVudCAhPT0gJ1xcdCdcbiAgICAgICAgJiYgIShwYXJzZUludChvcHRzLmluZGVudCwgMTApID09PSBvcHRzLmluZGVudCAmJiBvcHRzLmluZGVudCA+IDApXG4gICAgKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ29wdGlvbiBcImluZGVudFwiIG11c3QgYmUgXCJcXFxcdFwiLCBhbiBpbnRlZ2VyID4gMCwgb3IgYG51bGxgJyk7XG4gICAgfVxuICAgIGlmIChoYXMob3B0cywgJ251bWVyaWNTZXBhcmF0b3InKSAmJiB0eXBlb2Ygb3B0cy5udW1lcmljU2VwYXJhdG9yICE9PSAnYm9vbGVhbicpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignb3B0aW9uIFwibnVtZXJpY1NlcGFyYXRvclwiLCBpZiBwcm92aWRlZCwgbXVzdCBiZSBgdHJ1ZWAgb3IgYGZhbHNlYCcpO1xuICAgIH1cbiAgICB2YXIgbnVtZXJpY1NlcGFyYXRvciA9IG9wdHMubnVtZXJpY1NlcGFyYXRvcjtcblxuICAgIGlmICh0eXBlb2Ygb2JqID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICByZXR1cm4gJ3VuZGVmaW5lZCc7XG4gICAgfVxuICAgIGlmIChvYmogPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuICdudWxsJztcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBvYmogPT09ICdib29sZWFuJykge1xuICAgICAgICByZXR1cm4gb2JqID8gJ3RydWUnIDogJ2ZhbHNlJztcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIG9iaiA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgcmV0dXJuIGluc3BlY3RTdHJpbmcob2JqLCBvcHRzKTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBvYmogPT09ICdudW1iZXInKSB7XG4gICAgICAgIGlmIChvYmogPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiBJbmZpbml0eSAvIG9iaiA+IDAgPyAnMCcgOiAnLTAnO1xuICAgICAgICB9XG4gICAgICAgIHZhciBzdHIgPSBTdHJpbmcob2JqKTtcbiAgICAgICAgcmV0dXJuIG51bWVyaWNTZXBhcmF0b3IgPyBhZGROdW1lcmljU2VwYXJhdG9yKG9iaiwgc3RyKSA6IHN0cjtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBvYmogPT09ICdiaWdpbnQnKSB7XG4gICAgICAgIHZhciBiaWdJbnRTdHIgPSBTdHJpbmcob2JqKSArICduJztcbiAgICAgICAgcmV0dXJuIG51bWVyaWNTZXBhcmF0b3IgPyBhZGROdW1lcmljU2VwYXJhdG9yKG9iaiwgYmlnSW50U3RyKSA6IGJpZ0ludFN0cjtcbiAgICB9XG5cbiAgICB2YXIgbWF4RGVwdGggPSB0eXBlb2Ygb3B0cy5kZXB0aCA9PT0gJ3VuZGVmaW5lZCcgPyA1IDogb3B0cy5kZXB0aDtcbiAgICBpZiAodHlwZW9mIGRlcHRoID09PSAndW5kZWZpbmVkJykgeyBkZXB0aCA9IDA7IH1cbiAgICBpZiAoZGVwdGggPj0gbWF4RGVwdGggJiYgbWF4RGVwdGggPiAwICYmIHR5cGVvZiBvYmogPT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBpc0FycmF5KG9iaikgPyAnW0FycmF5XScgOiAnW09iamVjdF0nO1xuICAgIH1cblxuICAgIHZhciBpbmRlbnQgPSBnZXRJbmRlbnQob3B0cywgZGVwdGgpO1xuXG4gICAgaWYgKHR5cGVvZiBzZWVuID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICBzZWVuID0gW107XG4gICAgfSBlbHNlIGlmIChpbmRleE9mKHNlZW4sIG9iaikgPj0gMCkge1xuICAgICAgICByZXR1cm4gJ1tDaXJjdWxhcl0nO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGluc3BlY3QodmFsdWUsIGZyb20sIG5vSW5kZW50KSB7XG4gICAgICAgIGlmIChmcm9tKSB7XG4gICAgICAgICAgICBzZWVuID0gJGFyclNsaWNlLmNhbGwoc2Vlbik7XG4gICAgICAgICAgICBzZWVuLnB1c2goZnJvbSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG5vSW5kZW50KSB7XG4gICAgICAgICAgICB2YXIgbmV3T3B0cyA9IHtcbiAgICAgICAgICAgICAgICBkZXB0aDogb3B0cy5kZXB0aFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGlmIChoYXMob3B0cywgJ3F1b3RlU3R5bGUnKSkge1xuICAgICAgICAgICAgICAgIG5ld09wdHMucXVvdGVTdHlsZSA9IG9wdHMucXVvdGVTdHlsZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBpbnNwZWN0Xyh2YWx1ZSwgbmV3T3B0cywgZGVwdGggKyAxLCBzZWVuKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaW5zcGVjdF8odmFsdWUsIG9wdHMsIGRlcHRoICsgMSwgc2Vlbik7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBvYmogPT09ICdmdW5jdGlvbicgJiYgIWlzUmVnRXhwKG9iaikpIHsgLy8gaW4gb2xkZXIgZW5naW5lcywgcmVnZXhlcyBhcmUgY2FsbGFibGVcbiAgICAgICAgdmFyIG5hbWUgPSBuYW1lT2Yob2JqKTtcbiAgICAgICAgdmFyIGtleXMgPSBhcnJPYmpLZXlzKG9iaiwgaW5zcGVjdCk7XG4gICAgICAgIHJldHVybiAnW0Z1bmN0aW9uJyArIChuYW1lID8gJzogJyArIG5hbWUgOiAnIChhbm9ueW1vdXMpJykgKyAnXScgKyAoa2V5cy5sZW5ndGggPiAwID8gJyB7ICcgKyAkam9pbi5jYWxsKGtleXMsICcsICcpICsgJyB9JyA6ICcnKTtcbiAgICB9XG4gICAgaWYgKGlzU3ltYm9sKG9iaikpIHtcbiAgICAgICAgdmFyIHN5bVN0cmluZyA9IGhhc1NoYW1tZWRTeW1ib2xzID8gJHJlcGxhY2UuY2FsbChTdHJpbmcob2JqKSwgL14oU3ltYm9sXFwoLipcXCkpX1teKV0qJC8sICckMScpIDogc3ltVG9TdHJpbmcuY2FsbChvYmopO1xuICAgICAgICByZXR1cm4gdHlwZW9mIG9iaiA9PT0gJ29iamVjdCcgJiYgIWhhc1NoYW1tZWRTeW1ib2xzID8gbWFya0JveGVkKHN5bVN0cmluZykgOiBzeW1TdHJpbmc7XG4gICAgfVxuICAgIGlmIChpc0VsZW1lbnQob2JqKSkge1xuICAgICAgICB2YXIgcyA9ICc8JyArICR0b0xvd2VyQ2FzZS5jYWxsKFN0cmluZyhvYmoubm9kZU5hbWUpKTtcbiAgICAgICAgdmFyIGF0dHJzID0gb2JqLmF0dHJpYnV0ZXMgfHwgW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXR0cnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHMgKz0gJyAnICsgYXR0cnNbaV0ubmFtZSArICc9JyArIHdyYXBRdW90ZXMocXVvdGUoYXR0cnNbaV0udmFsdWUpLCAnZG91YmxlJywgb3B0cyk7XG4gICAgICAgIH1cbiAgICAgICAgcyArPSAnPic7XG4gICAgICAgIGlmIChvYmouY2hpbGROb2RlcyAmJiBvYmouY2hpbGROb2Rlcy5sZW5ndGgpIHsgcyArPSAnLi4uJzsgfVxuICAgICAgICBzICs9ICc8LycgKyAkdG9Mb3dlckNhc2UuY2FsbChTdHJpbmcob2JqLm5vZGVOYW1lKSkgKyAnPic7XG4gICAgICAgIHJldHVybiBzO1xuICAgIH1cbiAgICBpZiAoaXNBcnJheShvYmopKSB7XG4gICAgICAgIGlmIChvYmoubGVuZ3RoID09PSAwKSB7IHJldHVybiAnW10nOyB9XG4gICAgICAgIHZhciB4cyA9IGFyck9iaktleXMob2JqLCBpbnNwZWN0KTtcbiAgICAgICAgaWYgKGluZGVudCAmJiAhc2luZ2xlTGluZVZhbHVlcyh4cykpIHtcbiAgICAgICAgICAgIHJldHVybiAnWycgKyBpbmRlbnRlZEpvaW4oeHMsIGluZGVudCkgKyAnXSc7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuICdbICcgKyAkam9pbi5jYWxsKHhzLCAnLCAnKSArICcgXSc7XG4gICAgfVxuICAgIGlmIChpc0Vycm9yKG9iaikpIHtcbiAgICAgICAgdmFyIHBhcnRzID0gYXJyT2JqS2V5cyhvYmosIGluc3BlY3QpO1xuICAgICAgICBpZiAoISgnY2F1c2UnIGluIEVycm9yLnByb3RvdHlwZSkgJiYgJ2NhdXNlJyBpbiBvYmogJiYgIWlzRW51bWVyYWJsZS5jYWxsKG9iaiwgJ2NhdXNlJykpIHtcbiAgICAgICAgICAgIHJldHVybiAneyBbJyArIFN0cmluZyhvYmopICsgJ10gJyArICRqb2luLmNhbGwoJGNvbmNhdC5jYWxsKCdbY2F1c2VdOiAnICsgaW5zcGVjdChvYmouY2F1c2UpLCBwYXJ0cyksICcsICcpICsgJyB9JztcbiAgICAgICAgfVxuICAgICAgICBpZiAocGFydHMubGVuZ3RoID09PSAwKSB7IHJldHVybiAnWycgKyBTdHJpbmcob2JqKSArICddJzsgfVxuICAgICAgICByZXR1cm4gJ3sgWycgKyBTdHJpbmcob2JqKSArICddICcgKyAkam9pbi5jYWxsKHBhcnRzLCAnLCAnKSArICcgfSc7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJiBjdXN0b21JbnNwZWN0KSB7XG4gICAgICAgIGlmIChpbnNwZWN0U3ltYm9sICYmIHR5cGVvZiBvYmpbaW5zcGVjdFN5bWJvbF0gPT09ICdmdW5jdGlvbicgJiYgdXRpbEluc3BlY3QpIHtcbiAgICAgICAgICAgIHJldHVybiB1dGlsSW5zcGVjdChvYmosIHsgZGVwdGg6IG1heERlcHRoIC0gZGVwdGggfSk7XG4gICAgICAgIH0gZWxzZSBpZiAoY3VzdG9tSW5zcGVjdCAhPT0gJ3N5bWJvbCcgJiYgdHlwZW9mIG9iai5pbnNwZWN0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICByZXR1cm4gb2JqLmluc3BlY3QoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAoaXNNYXAob2JqKSkge1xuICAgICAgICB2YXIgbWFwUGFydHMgPSBbXTtcbiAgICAgICAgaWYgKG1hcEZvckVhY2gpIHtcbiAgICAgICAgICAgIG1hcEZvckVhY2guY2FsbChvYmosIGZ1bmN0aW9uICh2YWx1ZSwga2V5KSB7XG4gICAgICAgICAgICAgICAgbWFwUGFydHMucHVzaChpbnNwZWN0KGtleSwgb2JqLCB0cnVlKSArICcgPT4gJyArIGluc3BlY3QodmFsdWUsIG9iaikpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNvbGxlY3Rpb25PZignTWFwJywgbWFwU2l6ZS5jYWxsKG9iaiksIG1hcFBhcnRzLCBpbmRlbnQpO1xuICAgIH1cbiAgICBpZiAoaXNTZXQob2JqKSkge1xuICAgICAgICB2YXIgc2V0UGFydHMgPSBbXTtcbiAgICAgICAgaWYgKHNldEZvckVhY2gpIHtcbiAgICAgICAgICAgIHNldEZvckVhY2guY2FsbChvYmosIGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHNldFBhcnRzLnB1c2goaW5zcGVjdCh2YWx1ZSwgb2JqKSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY29sbGVjdGlvbk9mKCdTZXQnLCBzZXRTaXplLmNhbGwob2JqKSwgc2V0UGFydHMsIGluZGVudCk7XG4gICAgfVxuICAgIGlmIChpc1dlYWtNYXAob2JqKSkge1xuICAgICAgICByZXR1cm4gd2Vha0NvbGxlY3Rpb25PZignV2Vha01hcCcpO1xuICAgIH1cbiAgICBpZiAoaXNXZWFrU2V0KG9iaikpIHtcbiAgICAgICAgcmV0dXJuIHdlYWtDb2xsZWN0aW9uT2YoJ1dlYWtTZXQnKTtcbiAgICB9XG4gICAgaWYgKGlzV2Vha1JlZihvYmopKSB7XG4gICAgICAgIHJldHVybiB3ZWFrQ29sbGVjdGlvbk9mKCdXZWFrUmVmJyk7XG4gICAgfVxuICAgIGlmIChpc051bWJlcihvYmopKSB7XG4gICAgICAgIHJldHVybiBtYXJrQm94ZWQoaW5zcGVjdChOdW1iZXIob2JqKSkpO1xuICAgIH1cbiAgICBpZiAoaXNCaWdJbnQob2JqKSkge1xuICAgICAgICByZXR1cm4gbWFya0JveGVkKGluc3BlY3QoYmlnSW50VmFsdWVPZi5jYWxsKG9iaikpKTtcbiAgICB9XG4gICAgaWYgKGlzQm9vbGVhbihvYmopKSB7XG4gICAgICAgIHJldHVybiBtYXJrQm94ZWQoYm9vbGVhblZhbHVlT2YuY2FsbChvYmopKTtcbiAgICB9XG4gICAgaWYgKGlzU3RyaW5nKG9iaikpIHtcbiAgICAgICAgcmV0dXJuIG1hcmtCb3hlZChpbnNwZWN0KFN0cmluZyhvYmopKSk7XG4gICAgfVxuICAgIC8vIG5vdGU6IGluIElFIDgsIHNvbWV0aW1lcyBgZ2xvYmFsICE9PSB3aW5kb3dgIGJ1dCBib3RoIGFyZSB0aGUgcHJvdG90eXBlcyBvZiBlYWNoIG90aGVyXG4gICAgLyogZXNsaW50LWVudiBicm93c2VyICovXG4gICAgaWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnICYmIG9iaiA9PT0gd2luZG93KSB7XG4gICAgICAgIHJldHVybiAneyBbb2JqZWN0IFdpbmRvd10gfSc7XG4gICAgfVxuICAgIGlmIChcbiAgICAgICAgKHR5cGVvZiBnbG9iYWxUaGlzICE9PSAndW5kZWZpbmVkJyAmJiBvYmogPT09IGdsb2JhbFRoaXMpXG4gICAgICAgIHx8ICh0eXBlb2YgZ2xvYmFsICE9PSAndW5kZWZpbmVkJyAmJiBvYmogPT09IGdsb2JhbClcbiAgICApIHtcbiAgICAgICAgcmV0dXJuICd7IFtvYmplY3QgZ2xvYmFsVGhpc10gfSc7XG4gICAgfVxuICAgIGlmICghaXNEYXRlKG9iaikgJiYgIWlzUmVnRXhwKG9iaikpIHtcbiAgICAgICAgdmFyIHlzID0gYXJyT2JqS2V5cyhvYmosIGluc3BlY3QpO1xuICAgICAgICB2YXIgaXNQbGFpbk9iamVjdCA9IGdQTyA/IGdQTyhvYmopID09PSBPYmplY3QucHJvdG90eXBlIDogb2JqIGluc3RhbmNlb2YgT2JqZWN0IHx8IG9iai5jb25zdHJ1Y3RvciA9PT0gT2JqZWN0O1xuICAgICAgICB2YXIgcHJvdG9UYWcgPSBvYmogaW5zdGFuY2VvZiBPYmplY3QgPyAnJyA6ICdudWxsIHByb3RvdHlwZSc7XG4gICAgICAgIHZhciBzdHJpbmdUYWcgPSAhaXNQbGFpbk9iamVjdCAmJiB0b1N0cmluZ1RhZyAmJiBPYmplY3Qob2JqKSA9PT0gb2JqICYmIHRvU3RyaW5nVGFnIGluIG9iaiA/ICRzbGljZS5jYWxsKHRvU3RyKG9iaiksIDgsIC0xKSA6IHByb3RvVGFnID8gJ09iamVjdCcgOiAnJztcbiAgICAgICAgdmFyIGNvbnN0cnVjdG9yVGFnID0gaXNQbGFpbk9iamVjdCB8fCB0eXBlb2Ygb2JqLmNvbnN0cnVjdG9yICE9PSAnZnVuY3Rpb24nID8gJycgOiBvYmouY29uc3RydWN0b3IubmFtZSA/IG9iai5jb25zdHJ1Y3Rvci5uYW1lICsgJyAnIDogJyc7XG4gICAgICAgIHZhciB0YWcgPSBjb25zdHJ1Y3RvclRhZyArIChzdHJpbmdUYWcgfHwgcHJvdG9UYWcgPyAnWycgKyAkam9pbi5jYWxsKCRjb25jYXQuY2FsbChbXSwgc3RyaW5nVGFnIHx8IFtdLCBwcm90b1RhZyB8fCBbXSksICc6ICcpICsgJ10gJyA6ICcnKTtcbiAgICAgICAgaWYgKHlzLmxlbmd0aCA9PT0gMCkgeyByZXR1cm4gdGFnICsgJ3t9JzsgfVxuICAgICAgICBpZiAoaW5kZW50KSB7XG4gICAgICAgICAgICByZXR1cm4gdGFnICsgJ3snICsgaW5kZW50ZWRKb2luKHlzLCBpbmRlbnQpICsgJ30nO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0YWcgKyAneyAnICsgJGpvaW4uY2FsbCh5cywgJywgJykgKyAnIH0nO1xuICAgIH1cbiAgICByZXR1cm4gU3RyaW5nKG9iaik7XG59O1xuXG5mdW5jdGlvbiB3cmFwUXVvdGVzKHMsIGRlZmF1bHRTdHlsZSwgb3B0cykge1xuICAgIHZhciBzdHlsZSA9IG9wdHMucXVvdGVTdHlsZSB8fCBkZWZhdWx0U3R5bGU7XG4gICAgdmFyIHF1b3RlQ2hhciA9IHF1b3Rlc1tzdHlsZV07XG4gICAgcmV0dXJuIHF1b3RlQ2hhciArIHMgKyBxdW90ZUNoYXI7XG59XG5cbmZ1bmN0aW9uIHF1b3RlKHMpIHtcbiAgICByZXR1cm4gJHJlcGxhY2UuY2FsbChTdHJpbmcocyksIC9cIi9nLCAnJnF1b3Q7Jyk7XG59XG5cbmZ1bmN0aW9uIGNhblRydXN0VG9TdHJpbmcob2JqKSB7XG4gICAgcmV0dXJuICF0b1N0cmluZ1RhZyB8fCAhKHR5cGVvZiBvYmogPT09ICdvYmplY3QnICYmICh0b1N0cmluZ1RhZyBpbiBvYmogfHwgdHlwZW9mIG9ialt0b1N0cmluZ1RhZ10gIT09ICd1bmRlZmluZWQnKSk7XG59XG5mdW5jdGlvbiBpc0FycmF5KG9iaikgeyByZXR1cm4gdG9TdHIob2JqKSA9PT0gJ1tvYmplY3QgQXJyYXldJyAmJiBjYW5UcnVzdFRvU3RyaW5nKG9iaik7IH1cbmZ1bmN0aW9uIGlzRGF0ZShvYmopIHsgcmV0dXJuIHRvU3RyKG9iaikgPT09ICdbb2JqZWN0IERhdGVdJyAmJiBjYW5UcnVzdFRvU3RyaW5nKG9iaik7IH1cbmZ1bmN0aW9uIGlzUmVnRXhwKG9iaikgeyByZXR1cm4gdG9TdHIob2JqKSA9PT0gJ1tvYmplY3QgUmVnRXhwXScgJiYgY2FuVHJ1c3RUb1N0cmluZyhvYmopOyB9XG5mdW5jdGlvbiBpc0Vycm9yKG9iaikgeyByZXR1cm4gdG9TdHIob2JqKSA9PT0gJ1tvYmplY3QgRXJyb3JdJyAmJiBjYW5UcnVzdFRvU3RyaW5nKG9iaik7IH1cbmZ1bmN0aW9uIGlzU3RyaW5nKG9iaikgeyByZXR1cm4gdG9TdHIob2JqKSA9PT0gJ1tvYmplY3QgU3RyaW5nXScgJiYgY2FuVHJ1c3RUb1N0cmluZyhvYmopOyB9XG5mdW5jdGlvbiBpc051bWJlcihvYmopIHsgcmV0dXJuIHRvU3RyKG9iaikgPT09ICdbb2JqZWN0IE51bWJlcl0nICYmIGNhblRydXN0VG9TdHJpbmcob2JqKTsgfVxuZnVuY3Rpb24gaXNCb29sZWFuKG9iaikgeyByZXR1cm4gdG9TdHIob2JqKSA9PT0gJ1tvYmplY3QgQm9vbGVhbl0nICYmIGNhblRydXN0VG9TdHJpbmcob2JqKTsgfVxuXG4vLyBTeW1ib2wgYW5kIEJpZ0ludCBkbyBoYXZlIFN5bWJvbC50b1N0cmluZ1RhZyBieSBzcGVjLCBzbyB0aGF0IGNhbid0IGJlIHVzZWQgdG8gZWxpbWluYXRlIGZhbHNlIHBvc2l0aXZlc1xuZnVuY3Rpb24gaXNTeW1ib2wob2JqKSB7XG4gICAgaWYgKGhhc1NoYW1tZWRTeW1ib2xzKSB7XG4gICAgICAgIHJldHVybiBvYmogJiYgdHlwZW9mIG9iaiA9PT0gJ29iamVjdCcgJiYgb2JqIGluc3RhbmNlb2YgU3ltYm9sO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIG9iaiA9PT0gJ3N5bWJvbCcpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGlmICghb2JqIHx8IHR5cGVvZiBvYmogIT09ICdvYmplY3QnIHx8ICFzeW1Ub1N0cmluZykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIHN5bVRvU3RyaW5nLmNhbGwob2JqKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCAoZSkge31cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGlzQmlnSW50KG9iaikge1xuICAgIGlmICghb2JqIHx8IHR5cGVvZiBvYmogIT09ICdvYmplY3QnIHx8ICFiaWdJbnRWYWx1ZU9mKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgYmlnSW50VmFsdWVPZi5jYWxsKG9iaik7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gY2F0Y2ggKGUpIHt9XG4gICAgcmV0dXJuIGZhbHNlO1xufVxuXG52YXIgaGFzT3duID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eSB8fCBmdW5jdGlvbiAoa2V5KSB7IHJldHVybiBrZXkgaW4gdGhpczsgfTtcbmZ1bmN0aW9uIGhhcyhvYmosIGtleSkge1xuICAgIHJldHVybiBoYXNPd24uY2FsbChvYmosIGtleSk7XG59XG5cbmZ1bmN0aW9uIHRvU3RyKG9iaikge1xuICAgIHJldHVybiBvYmplY3RUb1N0cmluZy5jYWxsKG9iaik7XG59XG5cbmZ1bmN0aW9uIG5hbWVPZihmKSB7XG4gICAgaWYgKGYubmFtZSkgeyByZXR1cm4gZi5uYW1lOyB9XG4gICAgdmFyIG0gPSAkbWF0Y2guY2FsbChmdW5jdGlvblRvU3RyaW5nLmNhbGwoZiksIC9eZnVuY3Rpb25cXHMqKFtcXHckXSspLyk7XG4gICAgaWYgKG0pIHsgcmV0dXJuIG1bMV07IH1cbiAgICByZXR1cm4gbnVsbDtcbn1cblxuZnVuY3Rpb24gaW5kZXhPZih4cywgeCkge1xuICAgIGlmICh4cy5pbmRleE9mKSB7IHJldHVybiB4cy5pbmRleE9mKHgpOyB9XG4gICAgZm9yICh2YXIgaSA9IDAsIGwgPSB4cy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgaWYgKHhzW2ldID09PSB4KSB7IHJldHVybiBpOyB9XG4gICAgfVxuICAgIHJldHVybiAtMTtcbn1cblxuZnVuY3Rpb24gaXNNYXAoeCkge1xuICAgIGlmICghbWFwU2l6ZSB8fCAheCB8fCB0eXBlb2YgeCAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICBtYXBTaXplLmNhbGwoeCk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBzZXRTaXplLmNhbGwoeCk7XG4gICAgICAgIH0gY2F0Y2ggKHMpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB4IGluc3RhbmNlb2YgTWFwOyAvLyBjb3JlLWpzIHdvcmthcm91bmQsIHByZS12Mi41LjBcbiAgICB9IGNhdGNoIChlKSB7fVxuICAgIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gaXNXZWFrTWFwKHgpIHtcbiAgICBpZiAoIXdlYWtNYXBIYXMgfHwgIXggfHwgdHlwZW9mIHggIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgd2Vha01hcEhhcy5jYWxsKHgsIHdlYWtNYXBIYXMpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgd2Vha1NldEhhcy5jYWxsKHgsIHdlYWtTZXRIYXMpO1xuICAgICAgICB9IGNhdGNoIChzKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geCBpbnN0YW5jZW9mIFdlYWtNYXA7IC8vIGNvcmUtanMgd29ya2Fyb3VuZCwgcHJlLXYyLjUuMFxuICAgIH0gY2F0Y2ggKGUpIHt9XG4gICAgcmV0dXJuIGZhbHNlO1xufVxuXG5mdW5jdGlvbiBpc1dlYWtSZWYoeCkge1xuICAgIGlmICghd2Vha1JlZkRlcmVmIHx8ICF4IHx8IHR5cGVvZiB4ICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIHdlYWtSZWZEZXJlZi5jYWxsKHgpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIChlKSB7fVxuICAgIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gaXNTZXQoeCkge1xuICAgIGlmICghc2V0U2l6ZSB8fCAheCB8fCB0eXBlb2YgeCAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICBzZXRTaXplLmNhbGwoeCk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBtYXBTaXplLmNhbGwoeCk7XG4gICAgICAgIH0gY2F0Y2ggKG0pIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB4IGluc3RhbmNlb2YgU2V0OyAvLyBjb3JlLWpzIHdvcmthcm91bmQsIHByZS12Mi41LjBcbiAgICB9IGNhdGNoIChlKSB7fVxuICAgIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gaXNXZWFrU2V0KHgpIHtcbiAgICBpZiAoIXdlYWtTZXRIYXMgfHwgIXggfHwgdHlwZW9mIHggIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgd2Vha1NldEhhcy5jYWxsKHgsIHdlYWtTZXRIYXMpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgd2Vha01hcEhhcy5jYWxsKHgsIHdlYWtNYXBIYXMpO1xuICAgICAgICB9IGNhdGNoIChzKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geCBpbnN0YW5jZW9mIFdlYWtTZXQ7IC8vIGNvcmUtanMgd29ya2Fyb3VuZCwgcHJlLXYyLjUuMFxuICAgIH0gY2F0Y2ggKGUpIHt9XG4gICAgcmV0dXJuIGZhbHNlO1xufVxuXG5mdW5jdGlvbiBpc0VsZW1lbnQoeCkge1xuICAgIGlmICgheCB8fCB0eXBlb2YgeCAhPT0gJ29iamVjdCcpIHsgcmV0dXJuIGZhbHNlOyB9XG4gICAgaWYgKHR5cGVvZiBIVE1MRWxlbWVudCAhPT0gJ3VuZGVmaW5lZCcgJiYgeCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gdHlwZW9mIHgubm9kZU5hbWUgPT09ICdzdHJpbmcnICYmIHR5cGVvZiB4LmdldEF0dHJpYnV0ZSA9PT0gJ2Z1bmN0aW9uJztcbn1cblxuZnVuY3Rpb24gaW5zcGVjdFN0cmluZyhzdHIsIG9wdHMpIHtcbiAgICBpZiAoc3RyLmxlbmd0aCA+IG9wdHMubWF4U3RyaW5nTGVuZ3RoKSB7XG4gICAgICAgIHZhciByZW1haW5pbmcgPSBzdHIubGVuZ3RoIC0gb3B0cy5tYXhTdHJpbmdMZW5ndGg7XG4gICAgICAgIHZhciB0cmFpbGVyID0gJy4uLiAnICsgcmVtYWluaW5nICsgJyBtb3JlIGNoYXJhY3RlcicgKyAocmVtYWluaW5nID4gMSA/ICdzJyA6ICcnKTtcbiAgICAgICAgcmV0dXJuIGluc3BlY3RTdHJpbmcoJHNsaWNlLmNhbGwoc3RyLCAwLCBvcHRzLm1heFN0cmluZ0xlbmd0aCksIG9wdHMpICsgdHJhaWxlcjtcbiAgICB9XG4gICAgdmFyIHF1b3RlUkUgPSBxdW90ZVJFc1tvcHRzLnF1b3RlU3R5bGUgfHwgJ3NpbmdsZSddO1xuICAgIHF1b3RlUkUubGFzdEluZGV4ID0gMDtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29udHJvbC1yZWdleFxuICAgIHZhciBzID0gJHJlcGxhY2UuY2FsbCgkcmVwbGFjZS5jYWxsKHN0ciwgcXVvdGVSRSwgJ1xcXFwkMScpLCAvW1xceDAwLVxceDFmXS9nLCBsb3dieXRlKTtcbiAgICByZXR1cm4gd3JhcFF1b3RlcyhzLCAnc2luZ2xlJywgb3B0cyk7XG59XG5cbmZ1bmN0aW9uIGxvd2J5dGUoYykge1xuICAgIHZhciBuID0gYy5jaGFyQ29kZUF0KDApO1xuICAgIHZhciB4ID0ge1xuICAgICAgICA4OiAnYicsXG4gICAgICAgIDk6ICd0JyxcbiAgICAgICAgMTA6ICduJyxcbiAgICAgICAgMTI6ICdmJyxcbiAgICAgICAgMTM6ICdyJ1xuICAgIH1bbl07XG4gICAgaWYgKHgpIHsgcmV0dXJuICdcXFxcJyArIHg7IH1cbiAgICByZXR1cm4gJ1xcXFx4JyArIChuIDwgMHgxMCA/ICcwJyA6ICcnKSArICR0b1VwcGVyQ2FzZS5jYWxsKG4udG9TdHJpbmcoMTYpKTtcbn1cblxuZnVuY3Rpb24gbWFya0JveGVkKHN0cikge1xuICAgIHJldHVybiAnT2JqZWN0KCcgKyBzdHIgKyAnKSc7XG59XG5cbmZ1bmN0aW9uIHdlYWtDb2xsZWN0aW9uT2YodHlwZSkge1xuICAgIHJldHVybiB0eXBlICsgJyB7ID8gfSc7XG59XG5cbmZ1bmN0aW9uIGNvbGxlY3Rpb25PZih0eXBlLCBzaXplLCBlbnRyaWVzLCBpbmRlbnQpIHtcbiAgICB2YXIgam9pbmVkRW50cmllcyA9IGluZGVudCA/IGluZGVudGVkSm9pbihlbnRyaWVzLCBpbmRlbnQpIDogJGpvaW4uY2FsbChlbnRyaWVzLCAnLCAnKTtcbiAgICByZXR1cm4gdHlwZSArICcgKCcgKyBzaXplICsgJykgeycgKyBqb2luZWRFbnRyaWVzICsgJ30nO1xufVxuXG5mdW5jdGlvbiBzaW5nbGVMaW5lVmFsdWVzKHhzKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB4cy5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoaW5kZXhPZih4c1tpXSwgJ1xcbicpID49IDApIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gZ2V0SW5kZW50KG9wdHMsIGRlcHRoKSB7XG4gICAgdmFyIGJhc2VJbmRlbnQ7XG4gICAgaWYgKG9wdHMuaW5kZW50ID09PSAnXFx0Jykge1xuICAgICAgICBiYXNlSW5kZW50ID0gJ1xcdCc7XG4gICAgfSBlbHNlIGlmICh0eXBlb2Ygb3B0cy5pbmRlbnQgPT09ICdudW1iZXInICYmIG9wdHMuaW5kZW50ID4gMCkge1xuICAgICAgICBiYXNlSW5kZW50ID0gJGpvaW4uY2FsbChBcnJheShvcHRzLmluZGVudCArIDEpLCAnICcpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICBiYXNlOiBiYXNlSW5kZW50LFxuICAgICAgICBwcmV2OiAkam9pbi5jYWxsKEFycmF5KGRlcHRoICsgMSksIGJhc2VJbmRlbnQpXG4gICAgfTtcbn1cblxuZnVuY3Rpb24gaW5kZW50ZWRKb2luKHhzLCBpbmRlbnQpIHtcbiAgICBpZiAoeHMubGVuZ3RoID09PSAwKSB7IHJldHVybiAnJzsgfVxuICAgIHZhciBsaW5lSm9pbmVyID0gJ1xcbicgKyBpbmRlbnQucHJldiArIGluZGVudC5iYXNlO1xuICAgIHJldHVybiBsaW5lSm9pbmVyICsgJGpvaW4uY2FsbCh4cywgJywnICsgbGluZUpvaW5lcikgKyAnXFxuJyArIGluZGVudC5wcmV2O1xufVxuXG5mdW5jdGlvbiBhcnJPYmpLZXlzKG9iaiwgaW5zcGVjdCkge1xuICAgIHZhciBpc0FyciA9IGlzQXJyYXkob2JqKTtcbiAgICB2YXIgeHMgPSBbXTtcbiAgICBpZiAoaXNBcnIpIHtcbiAgICAgICAgeHMubGVuZ3RoID0gb2JqLmxlbmd0aDtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmoubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHhzW2ldID0gaGFzKG9iaiwgaSkgPyBpbnNwZWN0KG9ialtpXSwgb2JqKSA6ICcnO1xuICAgICAgICB9XG4gICAgfVxuICAgIHZhciBzeW1zID0gdHlwZW9mIGdPUFMgPT09ICdmdW5jdGlvbicgPyBnT1BTKG9iaikgOiBbXTtcbiAgICB2YXIgc3ltTWFwO1xuICAgIGlmIChoYXNTaGFtbWVkU3ltYm9scykge1xuICAgICAgICBzeW1NYXAgPSB7fTtcbiAgICAgICAgZm9yICh2YXIgayA9IDA7IGsgPCBzeW1zLmxlbmd0aDsgaysrKSB7XG4gICAgICAgICAgICBzeW1NYXBbJyQnICsgc3ltc1trXV0gPSBzeW1zW2tdO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZm9yICh2YXIga2V5IGluIG9iaikgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXJlc3RyaWN0ZWQtc3ludGF4XG4gICAgICAgIGlmICghaGFzKG9iaiwga2V5KSkgeyBjb250aW51ZTsgfSAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXJlc3RyaWN0ZWQtc3ludGF4LCBuby1jb250aW51ZVxuICAgICAgICBpZiAoaXNBcnIgJiYgU3RyaW5nKE51bWJlcihrZXkpKSA9PT0ga2V5ICYmIGtleSA8IG9iai5sZW5ndGgpIHsgY29udGludWU7IH0gLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1yZXN0cmljdGVkLXN5bnRheCwgbm8tY29udGludWVcbiAgICAgICAgaWYgKGhhc1NoYW1tZWRTeW1ib2xzICYmIHN5bU1hcFsnJCcgKyBrZXldIGluc3RhbmNlb2YgU3ltYm9sKSB7XG4gICAgICAgICAgICAvLyB0aGlzIGlzIHRvIHByZXZlbnQgc2hhbW1lZCBTeW1ib2xzLCB3aGljaCBhcmUgc3RvcmVkIGFzIHN0cmluZ3MsIGZyb20gYmVpbmcgaW5jbHVkZWQgaW4gdGhlIHN0cmluZyBrZXkgc2VjdGlvblxuICAgICAgICAgICAgY29udGludWU7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tcmVzdHJpY3RlZC1zeW50YXgsIG5vLWNvbnRpbnVlXG4gICAgICAgIH0gZWxzZSBpZiAoJHRlc3QuY2FsbCgvW15cXHckXS8sIGtleSkpIHtcbiAgICAgICAgICAgIHhzLnB1c2goaW5zcGVjdChrZXksIG9iaikgKyAnOiAnICsgaW5zcGVjdChvYmpba2V5XSwgb2JqKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB4cy5wdXNoKGtleSArICc6ICcgKyBpbnNwZWN0KG9ialtrZXldLCBvYmopKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAodHlwZW9mIGdPUFMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBzeW1zLmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgICBpZiAoaXNFbnVtZXJhYmxlLmNhbGwob2JqLCBzeW1zW2pdKSkge1xuICAgICAgICAgICAgICAgIHhzLnB1c2goJ1snICsgaW5zcGVjdChzeW1zW2pdKSArICddOiAnICsgaW5zcGVjdChvYmpbc3ltc1tqXV0sIG9iaikpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB4cztcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGtleXNTaGltO1xuaWYgKCFPYmplY3Qua2V5cykge1xuXHQvLyBtb2RpZmllZCBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9lcy1zaGltcy9lczUtc2hpbVxuXHR2YXIgaGFzID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcblx0dmFyIHRvU3RyID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZztcblx0dmFyIGlzQXJncyA9IHJlcXVpcmUoJy4vaXNBcmd1bWVudHMnKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBnbG9iYWwtcmVxdWlyZVxuXHR2YXIgaXNFbnVtZXJhYmxlID0gT2JqZWN0LnByb3RvdHlwZS5wcm9wZXJ0eUlzRW51bWVyYWJsZTtcblx0dmFyIGhhc0RvbnRFbnVtQnVnID0gIWlzRW51bWVyYWJsZS5jYWxsKHsgdG9TdHJpbmc6IG51bGwgfSwgJ3RvU3RyaW5nJyk7XG5cdHZhciBoYXNQcm90b0VudW1CdWcgPSBpc0VudW1lcmFibGUuY2FsbChmdW5jdGlvbiAoKSB7fSwgJ3Byb3RvdHlwZScpO1xuXHR2YXIgZG9udEVudW1zID0gW1xuXHRcdCd0b1N0cmluZycsXG5cdFx0J3RvTG9jYWxlU3RyaW5nJyxcblx0XHQndmFsdWVPZicsXG5cdFx0J2hhc093blByb3BlcnR5Jyxcblx0XHQnaXNQcm90b3R5cGVPZicsXG5cdFx0J3Byb3BlcnR5SXNFbnVtZXJhYmxlJyxcblx0XHQnY29uc3RydWN0b3InXG5cdF07XG5cdHZhciBlcXVhbHNDb25zdHJ1Y3RvclByb3RvdHlwZSA9IGZ1bmN0aW9uIChvKSB7XG5cdFx0dmFyIGN0b3IgPSBvLmNvbnN0cnVjdG9yO1xuXHRcdHJldHVybiBjdG9yICYmIGN0b3IucHJvdG90eXBlID09PSBvO1xuXHR9O1xuXHR2YXIgZXhjbHVkZWRLZXlzID0ge1xuXHRcdCRhcHBsaWNhdGlvbkNhY2hlOiB0cnVlLFxuXHRcdCRjb25zb2xlOiB0cnVlLFxuXHRcdCRleHRlcm5hbDogdHJ1ZSxcblx0XHQkZnJhbWU6IHRydWUsXG5cdFx0JGZyYW1lRWxlbWVudDogdHJ1ZSxcblx0XHQkZnJhbWVzOiB0cnVlLFxuXHRcdCRpbm5lckhlaWdodDogdHJ1ZSxcblx0XHQkaW5uZXJXaWR0aDogdHJ1ZSxcblx0XHQkb25tb3pmdWxsc2NyZWVuY2hhbmdlOiB0cnVlLFxuXHRcdCRvbm1vemZ1bGxzY3JlZW5lcnJvcjogdHJ1ZSxcblx0XHQkb3V0ZXJIZWlnaHQ6IHRydWUsXG5cdFx0JG91dGVyV2lkdGg6IHRydWUsXG5cdFx0JHBhZ2VYT2Zmc2V0OiB0cnVlLFxuXHRcdCRwYWdlWU9mZnNldDogdHJ1ZSxcblx0XHQkcGFyZW50OiB0cnVlLFxuXHRcdCRzY3JvbGxMZWZ0OiB0cnVlLFxuXHRcdCRzY3JvbGxUb3A6IHRydWUsXG5cdFx0JHNjcm9sbFg6IHRydWUsXG5cdFx0JHNjcm9sbFk6IHRydWUsXG5cdFx0JHNlbGY6IHRydWUsXG5cdFx0JHdlYmtpdEluZGV4ZWREQjogdHJ1ZSxcblx0XHQkd2Via2l0U3RvcmFnZUluZm86IHRydWUsXG5cdFx0JHdpbmRvdzogdHJ1ZVxuXHR9O1xuXHR2YXIgaGFzQXV0b21hdGlvbkVxdWFsaXR5QnVnID0gKGZ1bmN0aW9uICgpIHtcblx0XHQvKiBnbG9iYWwgd2luZG93ICovXG5cdFx0aWYgKHR5cGVvZiB3aW5kb3cgPT09ICd1bmRlZmluZWQnKSB7IHJldHVybiBmYWxzZTsgfVxuXHRcdGZvciAodmFyIGsgaW4gd2luZG93KSB7XG5cdFx0XHR0cnkge1xuXHRcdFx0XHRpZiAoIWV4Y2x1ZGVkS2V5c1snJCcgKyBrXSAmJiBoYXMuY2FsbCh3aW5kb3csIGspICYmIHdpbmRvd1trXSAhPT0gbnVsbCAmJiB0eXBlb2Ygd2luZG93W2tdID09PSAnb2JqZWN0Jykge1xuXHRcdFx0XHRcdHRyeSB7XG5cdFx0XHRcdFx0XHRlcXVhbHNDb25zdHJ1Y3RvclByb3RvdHlwZSh3aW5kb3dba10pO1xuXHRcdFx0XHRcdH0gY2F0Y2ggKGUpIHtcblx0XHRcdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fSBjYXRjaCAoZSkge1xuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9KCkpO1xuXHR2YXIgZXF1YWxzQ29uc3RydWN0b3JQcm90b3R5cGVJZk5vdEJ1Z2d5ID0gZnVuY3Rpb24gKG8pIHtcblx0XHQvKiBnbG9iYWwgd2luZG93ICovXG5cdFx0aWYgKHR5cGVvZiB3aW5kb3cgPT09ICd1bmRlZmluZWQnIHx8ICFoYXNBdXRvbWF0aW9uRXF1YWxpdHlCdWcpIHtcblx0XHRcdHJldHVybiBlcXVhbHNDb25zdHJ1Y3RvclByb3RvdHlwZShvKTtcblx0XHR9XG5cdFx0dHJ5IHtcblx0XHRcdHJldHVybiBlcXVhbHNDb25zdHJ1Y3RvclByb3RvdHlwZShvKTtcblx0XHR9IGNhdGNoIChlKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXHR9O1xuXG5cdGtleXNTaGltID0gZnVuY3Rpb24ga2V5cyhvYmplY3QpIHtcblx0XHR2YXIgaXNPYmplY3QgPSBvYmplY3QgIT09IG51bGwgJiYgdHlwZW9mIG9iamVjdCA9PT0gJ29iamVjdCc7XG5cdFx0dmFyIGlzRnVuY3Rpb24gPSB0b1N0ci5jYWxsKG9iamVjdCkgPT09ICdbb2JqZWN0IEZ1bmN0aW9uXSc7XG5cdFx0dmFyIGlzQXJndW1lbnRzID0gaXNBcmdzKG9iamVjdCk7XG5cdFx0dmFyIGlzU3RyaW5nID0gaXNPYmplY3QgJiYgdG9TdHIuY2FsbChvYmplY3QpID09PSAnW29iamVjdCBTdHJpbmddJztcblx0XHR2YXIgdGhlS2V5cyA9IFtdO1xuXG5cdFx0aWYgKCFpc09iamVjdCAmJiAhaXNGdW5jdGlvbiAmJiAhaXNBcmd1bWVudHMpIHtcblx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ09iamVjdC5rZXlzIGNhbGxlZCBvbiBhIG5vbi1vYmplY3QnKTtcblx0XHR9XG5cblx0XHR2YXIgc2tpcFByb3RvID0gaGFzUHJvdG9FbnVtQnVnICYmIGlzRnVuY3Rpb247XG5cdFx0aWYgKGlzU3RyaW5nICYmIG9iamVjdC5sZW5ndGggPiAwICYmICFoYXMuY2FsbChvYmplY3QsIDApKSB7XG5cdFx0XHRmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5sZW5ndGg7ICsraSkge1xuXHRcdFx0XHR0aGVLZXlzLnB1c2goU3RyaW5nKGkpKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAoaXNBcmd1bWVudHMgJiYgb2JqZWN0Lmxlbmd0aCA+IDApIHtcblx0XHRcdGZvciAodmFyIGogPSAwOyBqIDwgb2JqZWN0Lmxlbmd0aDsgKytqKSB7XG5cdFx0XHRcdHRoZUtleXMucHVzaChTdHJpbmcoaikpO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHRmb3IgKHZhciBuYW1lIGluIG9iamVjdCkge1xuXHRcdFx0XHRpZiAoIShza2lwUHJvdG8gJiYgbmFtZSA9PT0gJ3Byb3RvdHlwZScpICYmIGhhcy5jYWxsKG9iamVjdCwgbmFtZSkpIHtcblx0XHRcdFx0XHR0aGVLZXlzLnB1c2goU3RyaW5nKG5hbWUpKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGlmIChoYXNEb250RW51bUJ1Zykge1xuXHRcdFx0dmFyIHNraXBDb25zdHJ1Y3RvciA9IGVxdWFsc0NvbnN0cnVjdG9yUHJvdG90eXBlSWZOb3RCdWdneShvYmplY3QpO1xuXG5cdFx0XHRmb3IgKHZhciBrID0gMDsgayA8IGRvbnRFbnVtcy5sZW5ndGg7ICsraykge1xuXHRcdFx0XHRpZiAoIShza2lwQ29uc3RydWN0b3IgJiYgZG9udEVudW1zW2tdID09PSAnY29uc3RydWN0b3InKSAmJiBoYXMuY2FsbChvYmplY3QsIGRvbnRFbnVtc1trXSkpIHtcblx0XHRcdFx0XHR0aGVLZXlzLnB1c2goZG9udEVudW1zW2tdKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gdGhlS2V5cztcblx0fTtcbn1cbm1vZHVsZS5leHBvcnRzID0ga2V5c1NoaW07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBzbGljZSA9IEFycmF5LnByb3RvdHlwZS5zbGljZTtcbnZhciBpc0FyZ3MgPSByZXF1aXJlKCcuL2lzQXJndW1lbnRzJyk7XG5cbnZhciBvcmlnS2V5cyA9IE9iamVjdC5rZXlzO1xudmFyIGtleXNTaGltID0gb3JpZ0tleXMgPyBmdW5jdGlvbiBrZXlzKG8pIHsgcmV0dXJuIG9yaWdLZXlzKG8pOyB9IDogcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbicpO1xuXG52YXIgb3JpZ2luYWxLZXlzID0gT2JqZWN0LmtleXM7XG5cbmtleXNTaGltLnNoaW0gPSBmdW5jdGlvbiBzaGltT2JqZWN0S2V5cygpIHtcblx0aWYgKE9iamVjdC5rZXlzKSB7XG5cdFx0dmFyIGtleXNXb3Jrc1dpdGhBcmd1bWVudHMgPSAoZnVuY3Rpb24gKCkge1xuXHRcdFx0Ly8gU2FmYXJpIDUuMCBidWdcblx0XHRcdHZhciBhcmdzID0gT2JqZWN0LmtleXMoYXJndW1lbnRzKTtcblx0XHRcdHJldHVybiBhcmdzICYmIGFyZ3MubGVuZ3RoID09PSBhcmd1bWVudHMubGVuZ3RoO1xuXHRcdH0oMSwgMikpO1xuXHRcdGlmICgha2V5c1dvcmtzV2l0aEFyZ3VtZW50cykge1xuXHRcdFx0T2JqZWN0LmtleXMgPSBmdW5jdGlvbiBrZXlzKG9iamVjdCkgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIGZ1bmMtbmFtZS1tYXRjaGluZ1xuXHRcdFx0XHRpZiAoaXNBcmdzKG9iamVjdCkpIHtcblx0XHRcdFx0XHRyZXR1cm4gb3JpZ2luYWxLZXlzKHNsaWNlLmNhbGwob2JqZWN0KSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIG9yaWdpbmFsS2V5cyhvYmplY3QpO1xuXHRcdFx0fTtcblx0XHR9XG5cdH0gZWxzZSB7XG5cdFx0T2JqZWN0LmtleXMgPSBrZXlzU2hpbTtcblx0fVxuXHRyZXR1cm4gT2JqZWN0LmtleXMgfHwga2V5c1NoaW07XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGtleXNTaGltO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdG9TdHIgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGlzQXJndW1lbnRzKHZhbHVlKSB7XG5cdHZhciBzdHIgPSB0b1N0ci5jYWxsKHZhbHVlKTtcblx0dmFyIGlzQXJncyA9IHN0ciA9PT0gJ1tvYmplY3QgQXJndW1lbnRzXSc7XG5cdGlmICghaXNBcmdzKSB7XG5cdFx0aXNBcmdzID0gc3RyICE9PSAnW29iamVjdCBBcnJheV0nICYmXG5cdFx0XHR2YWx1ZSAhPT0gbnVsbCAmJlxuXHRcdFx0dHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJlxuXHRcdFx0dHlwZW9mIHZhbHVlLmxlbmd0aCA9PT0gJ251bWJlcicgJiZcblx0XHRcdHZhbHVlLmxlbmd0aCA+PSAwICYmXG5cdFx0XHR0b1N0ci5jYWxsKHZhbHVlLmNhbGxlZSkgPT09ICdbb2JqZWN0IEZ1bmN0aW9uXSc7XG5cdH1cblx0cmV0dXJuIGlzQXJncztcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbi8vIG1vZGlmaWVkIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL2VzLXNoaW1zL2VzNi1zaGltXG52YXIgb2JqZWN0S2V5cyA9IHJlcXVpcmUoJ29iamVjdC1rZXlzJyk7XG52YXIgaGFzU3ltYm9scyA9IHJlcXVpcmUoJ2hhcy1zeW1ib2xzL3NoYW1zJykoKTtcbnZhciBjYWxsQm91bmQgPSByZXF1aXJlKCdjYWxsLWJvdW5kJyk7XG52YXIgJE9iamVjdCA9IHJlcXVpcmUoJ2VzLW9iamVjdC1hdG9tcycpO1xudmFyICRwdXNoID0gY2FsbEJvdW5kKCdBcnJheS5wcm90b3R5cGUucHVzaCcpO1xudmFyICRwcm9wSXNFbnVtZXJhYmxlID0gY2FsbEJvdW5kKCdPYmplY3QucHJvdG90eXBlLnByb3BlcnR5SXNFbnVtZXJhYmxlJyk7XG52YXIgb3JpZ2luYWxHZXRTeW1ib2xzID0gaGFzU3ltYm9scyA/ICRPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzIDogbnVsbDtcblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVudXNlZC12YXJzXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGFzc2lnbih0YXJnZXQsIHNvdXJjZTEpIHtcblx0aWYgKHRhcmdldCA9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ3RhcmdldCBtdXN0IGJlIGFuIG9iamVjdCcpOyB9XG5cdHZhciB0byA9ICRPYmplY3QodGFyZ2V0KTsgLy8gc3RlcCAxXG5cdGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAxKSB7XG5cdFx0cmV0dXJuIHRvOyAvLyBzdGVwIDJcblx0fVxuXHRmb3IgKHZhciBzID0gMTsgcyA8IGFyZ3VtZW50cy5sZW5ndGg7ICsrcykge1xuXHRcdHZhciBmcm9tID0gJE9iamVjdChhcmd1bWVudHNbc10pOyAvLyBzdGVwIDMuYS5pXG5cblx0XHQvLyBzdGVwIDMuYS5paTpcblx0XHR2YXIga2V5cyA9IG9iamVjdEtleXMoZnJvbSk7XG5cdFx0dmFyIGdldFN5bWJvbHMgPSBoYXNTeW1ib2xzICYmICgkT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyB8fCBvcmlnaW5hbEdldFN5bWJvbHMpO1xuXHRcdGlmIChnZXRTeW1ib2xzKSB7XG5cdFx0XHR2YXIgc3ltcyA9IGdldFN5bWJvbHMoZnJvbSk7XG5cdFx0XHRmb3IgKHZhciBqID0gMDsgaiA8IHN5bXMubGVuZ3RoOyArK2opIHtcblx0XHRcdFx0dmFyIGtleSA9IHN5bXNbal07XG5cdFx0XHRcdGlmICgkcHJvcElzRW51bWVyYWJsZShmcm9tLCBrZXkpKSB7XG5cdFx0XHRcdFx0JHB1c2goa2V5cywga2V5KTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIHN0ZXAgMy5hLmlpaTpcblx0XHRmb3IgKHZhciBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpIHtcblx0XHRcdHZhciBuZXh0S2V5ID0ga2V5c1tpXTtcblx0XHRcdGlmICgkcHJvcElzRW51bWVyYWJsZShmcm9tLCBuZXh0S2V5KSkgeyAvLyBzdGVwIDMuYS5paWkuMlxuXHRcdFx0XHR2YXIgcHJvcFZhbHVlID0gZnJvbVtuZXh0S2V5XTsgLy8gc3RlcCAzLmEuaWlpLjIuYVxuXHRcdFx0XHR0b1tuZXh0S2V5XSA9IHByb3BWYWx1ZTsgLy8gc3RlcCAzLmEuaWlpLjIuYlxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHJldHVybiB0bzsgLy8gc3RlcCA0XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgaW1wbGVtZW50YXRpb24gPSByZXF1aXJlKCcuL2ltcGxlbWVudGF0aW9uJyk7XG5cbnZhciBsYWNrc1Byb3BlckVudW1lcmF0aW9uT3JkZXIgPSBmdW5jdGlvbiAoKSB7XG5cdGlmICghT2JqZWN0LmFzc2lnbikge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXHQvKlxuXHQgKiB2OCwgc3BlY2lmaWNhbGx5IGluIG5vZGUgNC54LCBoYXMgYSBidWcgd2l0aCBpbmNvcnJlY3QgcHJvcGVydHkgZW51bWVyYXRpb24gb3JkZXJcblx0ICogbm90ZTogdGhpcyBkb2VzIG5vdCBkZXRlY3QgdGhlIGJ1ZyB1bmxlc3MgdGhlcmUncyAyMCBjaGFyYWN0ZXJzXG5cdCAqL1xuXHR2YXIgc3RyID0gJ2FiY2RlZmdoaWprbG1ub3BxcnN0Jztcblx0dmFyIGxldHRlcnMgPSBzdHIuc3BsaXQoJycpO1xuXHR2YXIgbWFwID0ge307XG5cdGZvciAodmFyIGkgPSAwOyBpIDwgbGV0dGVycy5sZW5ndGg7ICsraSkge1xuXHRcdG1hcFtsZXR0ZXJzW2ldXSA9IGxldHRlcnNbaV07XG5cdH1cblx0dmFyIG9iaiA9IE9iamVjdC5hc3NpZ24oe30sIG1hcCk7XG5cdHZhciBhY3R1YWwgPSAnJztcblx0Zm9yICh2YXIgayBpbiBvYmopIHtcblx0XHRhY3R1YWwgKz0gaztcblx0fVxuXHRyZXR1cm4gc3RyICE9PSBhY3R1YWw7XG59O1xuXG52YXIgYXNzaWduSGFzUGVuZGluZ0V4Y2VwdGlvbnMgPSBmdW5jdGlvbiAoKSB7XG5cdGlmICghT2JqZWN0LmFzc2lnbiB8fCAhT2JqZWN0LnByZXZlbnRFeHRlbnNpb25zKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cdC8qXG5cdCAqIEZpcmVmb3ggMzcgc3RpbGwgaGFzIFwicGVuZGluZyBleGNlcHRpb25cIiBsb2dpYyBpbiBpdHMgT2JqZWN0LmFzc2lnbiBpbXBsZW1lbnRhdGlvbixcblx0ICogd2hpY2ggaXMgNzIlIHNsb3dlciB0aGFuIG91ciBzaGltLCBhbmQgRmlyZWZveCA0MCdzIG5hdGl2ZSBpbXBsZW1lbnRhdGlvbi5cblx0ICovXG5cdHZhciB0aHJvd2VyID0gT2JqZWN0LnByZXZlbnRFeHRlbnNpb25zKHsgMTogMiB9KTtcblx0dHJ5IHtcblx0XHRPYmplY3QuYXNzaWduKHRocm93ZXIsICd4eScpO1xuXHR9IGNhdGNoIChlKSB7XG5cdFx0cmV0dXJuIHRocm93ZXJbMV0gPT09ICd5Jztcblx0fVxuXHRyZXR1cm4gZmFsc2U7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGdldFBvbHlmaWxsKCkge1xuXHRpZiAoIU9iamVjdC5hc3NpZ24pIHtcblx0XHRyZXR1cm4gaW1wbGVtZW50YXRpb247XG5cdH1cblx0aWYgKGxhY2tzUHJvcGVyRW51bWVyYXRpb25PcmRlcigpKSB7XG5cdFx0cmV0dXJuIGltcGxlbWVudGF0aW9uO1xuXHR9XG5cdGlmIChhc3NpZ25IYXNQZW5kaW5nRXhjZXB0aW9ucygpKSB7XG5cdFx0cmV0dXJuIGltcGxlbWVudGF0aW9uO1xuXHR9XG5cdHJldHVybiBPYmplY3QuYXNzaWduO1xufTtcbiIsIi8vIHNoaW0gZm9yIHVzaW5nIHByb2Nlc3MgaW4gYnJvd3NlclxudmFyIHByb2Nlc3MgPSBtb2R1bGUuZXhwb3J0cyA9IHt9O1xuXG4vLyBjYWNoZWQgZnJvbSB3aGF0ZXZlciBnbG9iYWwgaXMgcHJlc2VudCBzbyB0aGF0IHRlc3QgcnVubmVycyB0aGF0IHN0dWIgaXRcbi8vIGRvbid0IGJyZWFrIHRoaW5ncy4gIEJ1dCB3ZSBuZWVkIHRvIHdyYXAgaXQgaW4gYSB0cnkgY2F0Y2ggaW4gY2FzZSBpdCBpc1xuLy8gd3JhcHBlZCBpbiBzdHJpY3QgbW9kZSBjb2RlIHdoaWNoIGRvZXNuJ3QgZGVmaW5lIGFueSBnbG9iYWxzLiAgSXQncyBpbnNpZGUgYVxuLy8gZnVuY3Rpb24gYmVjYXVzZSB0cnkvY2F0Y2hlcyBkZW9wdGltaXplIGluIGNlcnRhaW4gZW5naW5lcy5cblxudmFyIGNhY2hlZFNldFRpbWVvdXQ7XG52YXIgY2FjaGVkQ2xlYXJUaW1lb3V0O1xuXG5mdW5jdGlvbiBkZWZhdWx0U2V0VGltb3V0KCkge1xuICAgIHRocm93IG5ldyBFcnJvcignc2V0VGltZW91dCBoYXMgbm90IGJlZW4gZGVmaW5lZCcpO1xufVxuZnVuY3Rpb24gZGVmYXVsdENsZWFyVGltZW91dCAoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdjbGVhclRpbWVvdXQgaGFzIG5vdCBiZWVuIGRlZmluZWQnKTtcbn1cbihmdW5jdGlvbiAoKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgaWYgKHR5cGVvZiBzZXRUaW1lb3V0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBjYWNoZWRTZXRUaW1lb3V0ID0gc2V0VGltZW91dDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNhY2hlZFNldFRpbWVvdXQgPSBkZWZhdWx0U2V0VGltb3V0O1xuICAgICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBjYWNoZWRTZXRUaW1lb3V0ID0gZGVmYXVsdFNldFRpbW91dDtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgaWYgKHR5cGVvZiBjbGVhclRpbWVvdXQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIGNhY2hlZENsZWFyVGltZW91dCA9IGNsZWFyVGltZW91dDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNhY2hlZENsZWFyVGltZW91dCA9IGRlZmF1bHRDbGVhclRpbWVvdXQ7XG4gICAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGNhY2hlZENsZWFyVGltZW91dCA9IGRlZmF1bHRDbGVhclRpbWVvdXQ7XG4gICAgfVxufSAoKSlcbmZ1bmN0aW9uIHJ1blRpbWVvdXQoZnVuKSB7XG4gICAgaWYgKGNhY2hlZFNldFRpbWVvdXQgPT09IHNldFRpbWVvdXQpIHtcbiAgICAgICAgLy9ub3JtYWwgZW52aXJvbWVudHMgaW4gc2FuZSBzaXR1YXRpb25zXG4gICAgICAgIHJldHVybiBzZXRUaW1lb3V0KGZ1biwgMCk7XG4gICAgfVxuICAgIC8vIGlmIHNldFRpbWVvdXQgd2Fzbid0IGF2YWlsYWJsZSBidXQgd2FzIGxhdHRlciBkZWZpbmVkXG4gICAgaWYgKChjYWNoZWRTZXRUaW1lb3V0ID09PSBkZWZhdWx0U2V0VGltb3V0IHx8ICFjYWNoZWRTZXRUaW1lb3V0KSAmJiBzZXRUaW1lb3V0KSB7XG4gICAgICAgIGNhY2hlZFNldFRpbWVvdXQgPSBzZXRUaW1lb3V0O1xuICAgICAgICByZXR1cm4gc2V0VGltZW91dChmdW4sIDApO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICAvLyB3aGVuIHdoZW4gc29tZWJvZHkgaGFzIHNjcmV3ZWQgd2l0aCBzZXRUaW1lb3V0IGJ1dCBubyBJLkUuIG1hZGRuZXNzXG4gICAgICAgIHJldHVybiBjYWNoZWRTZXRUaW1lb3V0KGZ1biwgMCk7XG4gICAgfSBjYXRjaChlKXtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vIFdoZW4gd2UgYXJlIGluIEkuRS4gYnV0IHRoZSBzY3JpcHQgaGFzIGJlZW4gZXZhbGVkIHNvIEkuRS4gZG9lc24ndCB0cnVzdCB0aGUgZ2xvYmFsIG9iamVjdCB3aGVuIGNhbGxlZCBub3JtYWxseVxuICAgICAgICAgICAgcmV0dXJuIGNhY2hlZFNldFRpbWVvdXQuY2FsbChudWxsLCBmdW4sIDApO1xuICAgICAgICB9IGNhdGNoKGUpe1xuICAgICAgICAgICAgLy8gc2FtZSBhcyBhYm92ZSBidXQgd2hlbiBpdCdzIGEgdmVyc2lvbiBvZiBJLkUuIHRoYXQgbXVzdCBoYXZlIHRoZSBnbG9iYWwgb2JqZWN0IGZvciAndGhpcycsIGhvcGZ1bGx5IG91ciBjb250ZXh0IGNvcnJlY3Qgb3RoZXJ3aXNlIGl0IHdpbGwgdGhyb3cgYSBnbG9iYWwgZXJyb3JcbiAgICAgICAgICAgIHJldHVybiBjYWNoZWRTZXRUaW1lb3V0LmNhbGwodGhpcywgZnVuLCAwKTtcbiAgICAgICAgfVxuICAgIH1cblxuXG59XG5mdW5jdGlvbiBydW5DbGVhclRpbWVvdXQobWFya2VyKSB7XG4gICAgaWYgKGNhY2hlZENsZWFyVGltZW91dCA9PT0gY2xlYXJUaW1lb3V0KSB7XG4gICAgICAgIC8vbm9ybWFsIGVudmlyb21lbnRzIGluIHNhbmUgc2l0dWF0aW9uc1xuICAgICAgICByZXR1cm4gY2xlYXJUaW1lb3V0KG1hcmtlcik7XG4gICAgfVxuICAgIC8vIGlmIGNsZWFyVGltZW91dCB3YXNuJ3QgYXZhaWxhYmxlIGJ1dCB3YXMgbGF0dGVyIGRlZmluZWRcbiAgICBpZiAoKGNhY2hlZENsZWFyVGltZW91dCA9PT0gZGVmYXVsdENsZWFyVGltZW91dCB8fCAhY2FjaGVkQ2xlYXJUaW1lb3V0KSAmJiBjbGVhclRpbWVvdXQpIHtcbiAgICAgICAgY2FjaGVkQ2xlYXJUaW1lb3V0ID0gY2xlYXJUaW1lb3V0O1xuICAgICAgICByZXR1cm4gY2xlYXJUaW1lb3V0KG1hcmtlcik7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIC8vIHdoZW4gd2hlbiBzb21lYm9keSBoYXMgc2NyZXdlZCB3aXRoIHNldFRpbWVvdXQgYnV0IG5vIEkuRS4gbWFkZG5lc3NcbiAgICAgICAgcmV0dXJuIGNhY2hlZENsZWFyVGltZW91dChtYXJrZXIpO1xuICAgIH0gY2F0Y2ggKGUpe1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gV2hlbiB3ZSBhcmUgaW4gSS5FLiBidXQgdGhlIHNjcmlwdCBoYXMgYmVlbiBldmFsZWQgc28gSS5FLiBkb2Vzbid0ICB0cnVzdCB0aGUgZ2xvYmFsIG9iamVjdCB3aGVuIGNhbGxlZCBub3JtYWxseVxuICAgICAgICAgICAgcmV0dXJuIGNhY2hlZENsZWFyVGltZW91dC5jYWxsKG51bGwsIG1hcmtlcik7XG4gICAgICAgIH0gY2F0Y2ggKGUpe1xuICAgICAgICAgICAgLy8gc2FtZSBhcyBhYm92ZSBidXQgd2hlbiBpdCdzIGEgdmVyc2lvbiBvZiBJLkUuIHRoYXQgbXVzdCBoYXZlIHRoZSBnbG9iYWwgb2JqZWN0IGZvciAndGhpcycsIGhvcGZ1bGx5IG91ciBjb250ZXh0IGNvcnJlY3Qgb3RoZXJ3aXNlIGl0IHdpbGwgdGhyb3cgYSBnbG9iYWwgZXJyb3IuXG4gICAgICAgICAgICAvLyBTb21lIHZlcnNpb25zIG9mIEkuRS4gaGF2ZSBkaWZmZXJlbnQgcnVsZXMgZm9yIGNsZWFyVGltZW91dCB2cyBzZXRUaW1lb3V0XG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkQ2xlYXJUaW1lb3V0LmNhbGwodGhpcywgbWFya2VyKTtcbiAgICAgICAgfVxuICAgIH1cblxuXG5cbn1cbnZhciBxdWV1ZSA9IFtdO1xudmFyIGRyYWluaW5nID0gZmFsc2U7XG52YXIgY3VycmVudFF1ZXVlO1xudmFyIHF1ZXVlSW5kZXggPSAtMTtcblxuZnVuY3Rpb24gY2xlYW5VcE5leHRUaWNrKCkge1xuICAgIGlmICghZHJhaW5pbmcgfHwgIWN1cnJlbnRRdWV1ZSkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGRyYWluaW5nID0gZmFsc2U7XG4gICAgaWYgKGN1cnJlbnRRdWV1ZS5sZW5ndGgpIHtcbiAgICAgICAgcXVldWUgPSBjdXJyZW50UXVldWUuY29uY2F0KHF1ZXVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBxdWV1ZUluZGV4ID0gLTE7XG4gICAgfVxuICAgIGlmIChxdWV1ZS5sZW5ndGgpIHtcbiAgICAgICAgZHJhaW5RdWV1ZSgpO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gZHJhaW5RdWV1ZSgpIHtcbiAgICBpZiAoZHJhaW5pbmcpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB2YXIgdGltZW91dCA9IHJ1blRpbWVvdXQoY2xlYW5VcE5leHRUaWNrKTtcbiAgICBkcmFpbmluZyA9IHRydWU7XG5cbiAgICB2YXIgbGVuID0gcXVldWUubGVuZ3RoO1xuICAgIHdoaWxlKGxlbikge1xuICAgICAgICBjdXJyZW50UXVldWUgPSBxdWV1ZTtcbiAgICAgICAgcXVldWUgPSBbXTtcbiAgICAgICAgd2hpbGUgKCsrcXVldWVJbmRleCA8IGxlbikge1xuICAgICAgICAgICAgaWYgKGN1cnJlbnRRdWV1ZSkge1xuICAgICAgICAgICAgICAgIGN1cnJlbnRRdWV1ZVtxdWV1ZUluZGV4XS5ydW4oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBxdWV1ZUluZGV4ID0gLTE7XG4gICAgICAgIGxlbiA9IHF1ZXVlLmxlbmd0aDtcbiAgICB9XG4gICAgY3VycmVudFF1ZXVlID0gbnVsbDtcbiAgICBkcmFpbmluZyA9IGZhbHNlO1xuICAgIHJ1bkNsZWFyVGltZW91dCh0aW1lb3V0KTtcbn1cblxucHJvY2Vzcy5uZXh0VGljayA9IGZ1bmN0aW9uIChmdW4pIHtcbiAgICB2YXIgYXJncyA9IG5ldyBBcnJheShhcmd1bWVudHMubGVuZ3RoIC0gMSk7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBhcmdzW2kgLSAxXSA9IGFyZ3VtZW50c1tpXTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBxdWV1ZS5wdXNoKG5ldyBJdGVtKGZ1biwgYXJncykpO1xuICAgIGlmIChxdWV1ZS5sZW5ndGggPT09IDEgJiYgIWRyYWluaW5nKSB7XG4gICAgICAgIHJ1blRpbWVvdXQoZHJhaW5RdWV1ZSk7XG4gICAgfVxufTtcblxuLy8gdjggbGlrZXMgcHJlZGljdGlibGUgb2JqZWN0c1xuZnVuY3Rpb24gSXRlbShmdW4sIGFycmF5KSB7XG4gICAgdGhpcy5mdW4gPSBmdW47XG4gICAgdGhpcy5hcnJheSA9IGFycmF5O1xufVxuSXRlbS5wcm90b3R5cGUucnVuID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuZnVuLmFwcGx5KG51bGwsIHRoaXMuYXJyYXkpO1xufTtcbnByb2Nlc3MudGl0bGUgPSAnYnJvd3Nlcic7XG5wcm9jZXNzLmJyb3dzZXIgPSB0cnVlO1xucHJvY2Vzcy5lbnYgPSB7fTtcbnByb2Nlc3MuYXJndiA9IFtdO1xucHJvY2Vzcy52ZXJzaW9uID0gJyc7IC8vIGVtcHR5IHN0cmluZyB0byBhdm9pZCByZWdleHAgaXNzdWVzXG5wcm9jZXNzLnZlcnNpb25zID0ge307XG5cbmZ1bmN0aW9uIG5vb3AoKSB7fVxuXG5wcm9jZXNzLm9uID0gbm9vcDtcbnByb2Nlc3MuYWRkTGlzdGVuZXIgPSBub29wO1xucHJvY2Vzcy5vbmNlID0gbm9vcDtcbnByb2Nlc3Mub2ZmID0gbm9vcDtcbnByb2Nlc3MucmVtb3ZlTGlzdGVuZXIgPSBub29wO1xucHJvY2Vzcy5yZW1vdmVBbGxMaXN0ZW5lcnMgPSBub29wO1xucHJvY2Vzcy5lbWl0ID0gbm9vcDtcbnByb2Nlc3MucHJlcGVuZExpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3MucHJlcGVuZE9uY2VMaXN0ZW5lciA9IG5vb3A7XG5cbnByb2Nlc3MubGlzdGVuZXJzID0gZnVuY3Rpb24gKG5hbWUpIHsgcmV0dXJuIFtdIH1cblxucHJvY2Vzcy5iaW5kaW5nID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3Byb2Nlc3MuYmluZGluZyBpcyBub3Qgc3VwcG9ydGVkJyk7XG59O1xuXG5wcm9jZXNzLmN3ZCA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuICcvJyB9O1xucHJvY2Vzcy5jaGRpciA9IGZ1bmN0aW9uIChkaXIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3Byb2Nlc3MuY2hkaXIgaXMgbm90IHN1cHBvcnRlZCcpO1xufTtcbnByb2Nlc3MudW1hc2sgPSBmdW5jdGlvbigpIHsgcmV0dXJuIDA7IH07XG4iLCIvKiEgaHR0cHM6Ly9tdGhzLmJlL3B1bnljb2RlIHYxLjQuMSBieSBAbWF0aGlhcyAqL1xuOyhmdW5jdGlvbihyb290KSB7XG5cblx0LyoqIERldGVjdCBmcmVlIHZhcmlhYmxlcyAqL1xuXHR2YXIgZnJlZUV4cG9ydHMgPSB0eXBlb2YgZXhwb3J0cyA9PSAnb2JqZWN0JyAmJiBleHBvcnRzICYmXG5cdFx0IWV4cG9ydHMubm9kZVR5cGUgJiYgZXhwb3J0cztcblx0dmFyIGZyZWVNb2R1bGUgPSB0eXBlb2YgbW9kdWxlID09ICdvYmplY3QnICYmIG1vZHVsZSAmJlxuXHRcdCFtb2R1bGUubm9kZVR5cGUgJiYgbW9kdWxlO1xuXHR2YXIgZnJlZUdsb2JhbCA9IHR5cGVvZiBnbG9iYWwgPT0gJ29iamVjdCcgJiYgZ2xvYmFsO1xuXHRpZiAoXG5cdFx0ZnJlZUdsb2JhbC5nbG9iYWwgPT09IGZyZWVHbG9iYWwgfHxcblx0XHRmcmVlR2xvYmFsLndpbmRvdyA9PT0gZnJlZUdsb2JhbCB8fFxuXHRcdGZyZWVHbG9iYWwuc2VsZiA9PT0gZnJlZUdsb2JhbFxuXHQpIHtcblx0XHRyb290ID0gZnJlZUdsb2JhbDtcblx0fVxuXG5cdC8qKlxuXHQgKiBUaGUgYHB1bnljb2RlYCBvYmplY3QuXG5cdCAqIEBuYW1lIHB1bnljb2RlXG5cdCAqIEB0eXBlIE9iamVjdFxuXHQgKi9cblx0dmFyIHB1bnljb2RlLFxuXG5cdC8qKiBIaWdoZXN0IHBvc2l0aXZlIHNpZ25lZCAzMi1iaXQgZmxvYXQgdmFsdWUgKi9cblx0bWF4SW50ID0gMjE0NzQ4MzY0NywgLy8gYWthLiAweDdGRkZGRkZGIG9yIDJeMzEtMVxuXG5cdC8qKiBCb290c3RyaW5nIHBhcmFtZXRlcnMgKi9cblx0YmFzZSA9IDM2LFxuXHR0TWluID0gMSxcblx0dE1heCA9IDI2LFxuXHRza2V3ID0gMzgsXG5cdGRhbXAgPSA3MDAsXG5cdGluaXRpYWxCaWFzID0gNzIsXG5cdGluaXRpYWxOID0gMTI4LCAvLyAweDgwXG5cdGRlbGltaXRlciA9ICctJywgLy8gJ1xceDJEJ1xuXG5cdC8qKiBSZWd1bGFyIGV4cHJlc3Npb25zICovXG5cdHJlZ2V4UHVueWNvZGUgPSAvXnhuLS0vLFxuXHRyZWdleE5vbkFTQ0lJID0gL1teXFx4MjAtXFx4N0VdLywgLy8gdW5wcmludGFibGUgQVNDSUkgY2hhcnMgKyBub24tQVNDSUkgY2hhcnNcblx0cmVnZXhTZXBhcmF0b3JzID0gL1tcXHgyRVxcdTMwMDJcXHVGRjBFXFx1RkY2MV0vZywgLy8gUkZDIDM0OTAgc2VwYXJhdG9yc1xuXG5cdC8qKiBFcnJvciBtZXNzYWdlcyAqL1xuXHRlcnJvcnMgPSB7XG5cdFx0J292ZXJmbG93JzogJ092ZXJmbG93OiBpbnB1dCBuZWVkcyB3aWRlciBpbnRlZ2VycyB0byBwcm9jZXNzJyxcblx0XHQnbm90LWJhc2ljJzogJ0lsbGVnYWwgaW5wdXQgPj0gMHg4MCAobm90IGEgYmFzaWMgY29kZSBwb2ludCknLFxuXHRcdCdpbnZhbGlkLWlucHV0JzogJ0ludmFsaWQgaW5wdXQnXG5cdH0sXG5cblx0LyoqIENvbnZlbmllbmNlIHNob3J0Y3V0cyAqL1xuXHRiYXNlTWludXNUTWluID0gYmFzZSAtIHRNaW4sXG5cdGZsb29yID0gTWF0aC5mbG9vcixcblx0c3RyaW5nRnJvbUNoYXJDb2RlID0gU3RyaW5nLmZyb21DaGFyQ29kZSxcblxuXHQvKiogVGVtcG9yYXJ5IHZhcmlhYmxlICovXG5cdGtleTtcblxuXHQvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuXHQvKipcblx0ICogQSBnZW5lcmljIGVycm9yIHV0aWxpdHkgZnVuY3Rpb24uXG5cdCAqIEBwcml2YXRlXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlIFRoZSBlcnJvciB0eXBlLlxuXHQgKiBAcmV0dXJucyB7RXJyb3J9IFRocm93cyBhIGBSYW5nZUVycm9yYCB3aXRoIHRoZSBhcHBsaWNhYmxlIGVycm9yIG1lc3NhZ2UuXG5cdCAqL1xuXHRmdW5jdGlvbiBlcnJvcih0eXBlKSB7XG5cdFx0dGhyb3cgbmV3IFJhbmdlRXJyb3IoZXJyb3JzW3R5cGVdKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBIGdlbmVyaWMgYEFycmF5I21hcGAgdXRpbGl0eSBmdW5jdGlvbi5cblx0ICogQHByaXZhdGVcblx0ICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cblx0ICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgVGhlIGZ1bmN0aW9uIHRoYXQgZ2V0cyBjYWxsZWQgZm9yIGV2ZXJ5IGFycmF5XG5cdCAqIGl0ZW0uXG5cdCAqIEByZXR1cm5zIHtBcnJheX0gQSBuZXcgYXJyYXkgb2YgdmFsdWVzIHJldHVybmVkIGJ5IHRoZSBjYWxsYmFjayBmdW5jdGlvbi5cblx0ICovXG5cdGZ1bmN0aW9uIG1hcChhcnJheSwgZm4pIHtcblx0XHR2YXIgbGVuZ3RoID0gYXJyYXkubGVuZ3RoO1xuXHRcdHZhciByZXN1bHQgPSBbXTtcblx0XHR3aGlsZSAobGVuZ3RoLS0pIHtcblx0XHRcdHJlc3VsdFtsZW5ndGhdID0gZm4oYXJyYXlbbGVuZ3RoXSk7XG5cdFx0fVxuXHRcdHJldHVybiByZXN1bHQ7XG5cdH1cblxuXHQvKipcblx0ICogQSBzaW1wbGUgYEFycmF5I21hcGAtbGlrZSB3cmFwcGVyIHRvIHdvcmsgd2l0aCBkb21haW4gbmFtZSBzdHJpbmdzIG9yIGVtYWlsXG5cdCAqIGFkZHJlc3Nlcy5cblx0ICogQHByaXZhdGVcblx0ICogQHBhcmFtIHtTdHJpbmd9IGRvbWFpbiBUaGUgZG9tYWluIG5hbWUgb3IgZW1haWwgYWRkcmVzcy5cblx0ICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgVGhlIGZ1bmN0aW9uIHRoYXQgZ2V0cyBjYWxsZWQgZm9yIGV2ZXJ5XG5cdCAqIGNoYXJhY3Rlci5cblx0ICogQHJldHVybnMge0FycmF5fSBBIG5ldyBzdHJpbmcgb2YgY2hhcmFjdGVycyByZXR1cm5lZCBieSB0aGUgY2FsbGJhY2tcblx0ICogZnVuY3Rpb24uXG5cdCAqL1xuXHRmdW5jdGlvbiBtYXBEb21haW4oc3RyaW5nLCBmbikge1xuXHRcdHZhciBwYXJ0cyA9IHN0cmluZy5zcGxpdCgnQCcpO1xuXHRcdHZhciByZXN1bHQgPSAnJztcblx0XHRpZiAocGFydHMubGVuZ3RoID4gMSkge1xuXHRcdFx0Ly8gSW4gZW1haWwgYWRkcmVzc2VzLCBvbmx5IHRoZSBkb21haW4gbmFtZSBzaG91bGQgYmUgcHVueWNvZGVkLiBMZWF2ZVxuXHRcdFx0Ly8gdGhlIGxvY2FsIHBhcnQgKGkuZS4gZXZlcnl0aGluZyB1cCB0byBgQGApIGludGFjdC5cblx0XHRcdHJlc3VsdCA9IHBhcnRzWzBdICsgJ0AnO1xuXHRcdFx0c3RyaW5nID0gcGFydHNbMV07XG5cdFx0fVxuXHRcdC8vIEF2b2lkIGBzcGxpdChyZWdleClgIGZvciBJRTggY29tcGF0aWJpbGl0eS4gU2VlICMxNy5cblx0XHRzdHJpbmcgPSBzdHJpbmcucmVwbGFjZShyZWdleFNlcGFyYXRvcnMsICdcXHgyRScpO1xuXHRcdHZhciBsYWJlbHMgPSBzdHJpbmcuc3BsaXQoJy4nKTtcblx0XHR2YXIgZW5jb2RlZCA9IG1hcChsYWJlbHMsIGZuKS5qb2luKCcuJyk7XG5cdFx0cmV0dXJuIHJlc3VsdCArIGVuY29kZWQ7XG5cdH1cblxuXHQvKipcblx0ICogQ3JlYXRlcyBhbiBhcnJheSBjb250YWluaW5nIHRoZSBudW1lcmljIGNvZGUgcG9pbnRzIG9mIGVhY2ggVW5pY29kZVxuXHQgKiBjaGFyYWN0ZXIgaW4gdGhlIHN0cmluZy4gV2hpbGUgSmF2YVNjcmlwdCB1c2VzIFVDUy0yIGludGVybmFsbHksXG5cdCAqIHRoaXMgZnVuY3Rpb24gd2lsbCBjb252ZXJ0IGEgcGFpciBvZiBzdXJyb2dhdGUgaGFsdmVzIChlYWNoIG9mIHdoaWNoXG5cdCAqIFVDUy0yIGV4cG9zZXMgYXMgc2VwYXJhdGUgY2hhcmFjdGVycykgaW50byBhIHNpbmdsZSBjb2RlIHBvaW50LFxuXHQgKiBtYXRjaGluZyBVVEYtMTYuXG5cdCAqIEBzZWUgYHB1bnljb2RlLnVjczIuZW5jb2RlYFxuXHQgKiBAc2VlIDxodHRwczovL21hdGhpYXNieW5lbnMuYmUvbm90ZXMvamF2YXNjcmlwdC1lbmNvZGluZz5cblx0ICogQG1lbWJlck9mIHB1bnljb2RlLnVjczJcblx0ICogQG5hbWUgZGVjb2RlXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBzdHJpbmcgVGhlIFVuaWNvZGUgaW5wdXQgc3RyaW5nIChVQ1MtMikuXG5cdCAqIEByZXR1cm5zIHtBcnJheX0gVGhlIG5ldyBhcnJheSBvZiBjb2RlIHBvaW50cy5cblx0ICovXG5cdGZ1bmN0aW9uIHVjczJkZWNvZGUoc3RyaW5nKSB7XG5cdFx0dmFyIG91dHB1dCA9IFtdLFxuXHRcdCAgICBjb3VudGVyID0gMCxcblx0XHQgICAgbGVuZ3RoID0gc3RyaW5nLmxlbmd0aCxcblx0XHQgICAgdmFsdWUsXG5cdFx0ICAgIGV4dHJhO1xuXHRcdHdoaWxlIChjb3VudGVyIDwgbGVuZ3RoKSB7XG5cdFx0XHR2YWx1ZSA9IHN0cmluZy5jaGFyQ29kZUF0KGNvdW50ZXIrKyk7XG5cdFx0XHRpZiAodmFsdWUgPj0gMHhEODAwICYmIHZhbHVlIDw9IDB4REJGRiAmJiBjb3VudGVyIDwgbGVuZ3RoKSB7XG5cdFx0XHRcdC8vIGhpZ2ggc3Vycm9nYXRlLCBhbmQgdGhlcmUgaXMgYSBuZXh0IGNoYXJhY3RlclxuXHRcdFx0XHRleHRyYSA9IHN0cmluZy5jaGFyQ29kZUF0KGNvdW50ZXIrKyk7XG5cdFx0XHRcdGlmICgoZXh0cmEgJiAweEZDMDApID09IDB4REMwMCkgeyAvLyBsb3cgc3Vycm9nYXRlXG5cdFx0XHRcdFx0b3V0cHV0LnB1c2goKCh2YWx1ZSAmIDB4M0ZGKSA8PCAxMCkgKyAoZXh0cmEgJiAweDNGRikgKyAweDEwMDAwKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHQvLyB1bm1hdGNoZWQgc3Vycm9nYXRlOyBvbmx5IGFwcGVuZCB0aGlzIGNvZGUgdW5pdCwgaW4gY2FzZSB0aGUgbmV4dFxuXHRcdFx0XHRcdC8vIGNvZGUgdW5pdCBpcyB0aGUgaGlnaCBzdXJyb2dhdGUgb2YgYSBzdXJyb2dhdGUgcGFpclxuXHRcdFx0XHRcdG91dHB1dC5wdXNoKHZhbHVlKTtcblx0XHRcdFx0XHRjb3VudGVyLS07XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdG91dHB1dC5wdXNoKHZhbHVlKTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIG91dHB1dDtcblx0fVxuXG5cdC8qKlxuXHQgKiBDcmVhdGVzIGEgc3RyaW5nIGJhc2VkIG9uIGFuIGFycmF5IG9mIG51bWVyaWMgY29kZSBwb2ludHMuXG5cdCAqIEBzZWUgYHB1bnljb2RlLnVjczIuZGVjb2RlYFxuXHQgKiBAbWVtYmVyT2YgcHVueWNvZGUudWNzMlxuXHQgKiBAbmFtZSBlbmNvZGVcblx0ICogQHBhcmFtIHtBcnJheX0gY29kZVBvaW50cyBUaGUgYXJyYXkgb2YgbnVtZXJpYyBjb2RlIHBvaW50cy5cblx0ICogQHJldHVybnMge1N0cmluZ30gVGhlIG5ldyBVbmljb2RlIHN0cmluZyAoVUNTLTIpLlxuXHQgKi9cblx0ZnVuY3Rpb24gdWNzMmVuY29kZShhcnJheSkge1xuXHRcdHJldHVybiBtYXAoYXJyYXksIGZ1bmN0aW9uKHZhbHVlKSB7XG5cdFx0XHR2YXIgb3V0cHV0ID0gJyc7XG5cdFx0XHRpZiAodmFsdWUgPiAweEZGRkYpIHtcblx0XHRcdFx0dmFsdWUgLT0gMHgxMDAwMDtcblx0XHRcdFx0b3V0cHV0ICs9IHN0cmluZ0Zyb21DaGFyQ29kZSh2YWx1ZSA+Pj4gMTAgJiAweDNGRiB8IDB4RDgwMCk7XG5cdFx0XHRcdHZhbHVlID0gMHhEQzAwIHwgdmFsdWUgJiAweDNGRjtcblx0XHRcdH1cblx0XHRcdG91dHB1dCArPSBzdHJpbmdGcm9tQ2hhckNvZGUodmFsdWUpO1xuXHRcdFx0cmV0dXJuIG91dHB1dDtcblx0XHR9KS5qb2luKCcnKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDb252ZXJ0cyBhIGJhc2ljIGNvZGUgcG9pbnQgaW50byBhIGRpZ2l0L2ludGVnZXIuXG5cdCAqIEBzZWUgYGRpZ2l0VG9CYXNpYygpYFxuXHQgKiBAcHJpdmF0ZVxuXHQgKiBAcGFyYW0ge051bWJlcn0gY29kZVBvaW50IFRoZSBiYXNpYyBudW1lcmljIGNvZGUgcG9pbnQgdmFsdWUuXG5cdCAqIEByZXR1cm5zIHtOdW1iZXJ9IFRoZSBudW1lcmljIHZhbHVlIG9mIGEgYmFzaWMgY29kZSBwb2ludCAoZm9yIHVzZSBpblxuXHQgKiByZXByZXNlbnRpbmcgaW50ZWdlcnMpIGluIHRoZSByYW5nZSBgMGAgdG8gYGJhc2UgLSAxYCwgb3IgYGJhc2VgIGlmXG5cdCAqIHRoZSBjb2RlIHBvaW50IGRvZXMgbm90IHJlcHJlc2VudCBhIHZhbHVlLlxuXHQgKi9cblx0ZnVuY3Rpb24gYmFzaWNUb0RpZ2l0KGNvZGVQb2ludCkge1xuXHRcdGlmIChjb2RlUG9pbnQgLSA0OCA8IDEwKSB7XG5cdFx0XHRyZXR1cm4gY29kZVBvaW50IC0gMjI7XG5cdFx0fVxuXHRcdGlmIChjb2RlUG9pbnQgLSA2NSA8IDI2KSB7XG5cdFx0XHRyZXR1cm4gY29kZVBvaW50IC0gNjU7XG5cdFx0fVxuXHRcdGlmIChjb2RlUG9pbnQgLSA5NyA8IDI2KSB7XG5cdFx0XHRyZXR1cm4gY29kZVBvaW50IC0gOTc7XG5cdFx0fVxuXHRcdHJldHVybiBiYXNlO1xuXHR9XG5cblx0LyoqXG5cdCAqIENvbnZlcnRzIGEgZGlnaXQvaW50ZWdlciBpbnRvIGEgYmFzaWMgY29kZSBwb2ludC5cblx0ICogQHNlZSBgYmFzaWNUb0RpZ2l0KClgXG5cdCAqIEBwcml2YXRlXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSBkaWdpdCBUaGUgbnVtZXJpYyB2YWx1ZSBvZiBhIGJhc2ljIGNvZGUgcG9pbnQuXG5cdCAqIEByZXR1cm5zIHtOdW1iZXJ9IFRoZSBiYXNpYyBjb2RlIHBvaW50IHdob3NlIHZhbHVlICh3aGVuIHVzZWQgZm9yXG5cdCAqIHJlcHJlc2VudGluZyBpbnRlZ2VycykgaXMgYGRpZ2l0YCwgd2hpY2ggbmVlZHMgdG8gYmUgaW4gdGhlIHJhbmdlXG5cdCAqIGAwYCB0byBgYmFzZSAtIDFgLiBJZiBgZmxhZ2AgaXMgbm9uLXplcm8sIHRoZSB1cHBlcmNhc2UgZm9ybSBpc1xuXHQgKiB1c2VkOyBlbHNlLCB0aGUgbG93ZXJjYXNlIGZvcm0gaXMgdXNlZC4gVGhlIGJlaGF2aW9yIGlzIHVuZGVmaW5lZFxuXHQgKiBpZiBgZmxhZ2AgaXMgbm9uLXplcm8gYW5kIGBkaWdpdGAgaGFzIG5vIHVwcGVyY2FzZSBmb3JtLlxuXHQgKi9cblx0ZnVuY3Rpb24gZGlnaXRUb0Jhc2ljKGRpZ2l0LCBmbGFnKSB7XG5cdFx0Ly8gIDAuLjI1IG1hcCB0byBBU0NJSSBhLi56IG9yIEEuLlpcblx0XHQvLyAyNi4uMzUgbWFwIHRvIEFTQ0lJIDAuLjlcblx0XHRyZXR1cm4gZGlnaXQgKyAyMiArIDc1ICogKGRpZ2l0IDwgMjYpIC0gKChmbGFnICE9IDApIDw8IDUpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEJpYXMgYWRhcHRhdGlvbiBmdW5jdGlvbiBhcyBwZXIgc2VjdGlvbiAzLjQgb2YgUkZDIDM0OTIuXG5cdCAqIGh0dHBzOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmMzNDkyI3NlY3Rpb24tMy40XG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuXHRmdW5jdGlvbiBhZGFwdChkZWx0YSwgbnVtUG9pbnRzLCBmaXJzdFRpbWUpIHtcblx0XHR2YXIgayA9IDA7XG5cdFx0ZGVsdGEgPSBmaXJzdFRpbWUgPyBmbG9vcihkZWx0YSAvIGRhbXApIDogZGVsdGEgPj4gMTtcblx0XHRkZWx0YSArPSBmbG9vcihkZWx0YSAvIG51bVBvaW50cyk7XG5cdFx0Zm9yICgvKiBubyBpbml0aWFsaXphdGlvbiAqLzsgZGVsdGEgPiBiYXNlTWludXNUTWluICogdE1heCA+PiAxOyBrICs9IGJhc2UpIHtcblx0XHRcdGRlbHRhID0gZmxvb3IoZGVsdGEgLyBiYXNlTWludXNUTWluKTtcblx0XHR9XG5cdFx0cmV0dXJuIGZsb29yKGsgKyAoYmFzZU1pbnVzVE1pbiArIDEpICogZGVsdGEgLyAoZGVsdGEgKyBza2V3KSk7XG5cdH1cblxuXHQvKipcblx0ICogQ29udmVydHMgYSBQdW55Y29kZSBzdHJpbmcgb2YgQVNDSUktb25seSBzeW1ib2xzIHRvIGEgc3RyaW5nIG9mIFVuaWNvZGVcblx0ICogc3ltYm9scy5cblx0ICogQG1lbWJlck9mIHB1bnljb2RlXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dCBUaGUgUHVueWNvZGUgc3RyaW5nIG9mIEFTQ0lJLW9ubHkgc3ltYm9scy5cblx0ICogQHJldHVybnMge1N0cmluZ30gVGhlIHJlc3VsdGluZyBzdHJpbmcgb2YgVW5pY29kZSBzeW1ib2xzLlxuXHQgKi9cblx0ZnVuY3Rpb24gZGVjb2RlKGlucHV0KSB7XG5cdFx0Ly8gRG9uJ3QgdXNlIFVDUy0yXG5cdFx0dmFyIG91dHB1dCA9IFtdLFxuXHRcdCAgICBpbnB1dExlbmd0aCA9IGlucHV0Lmxlbmd0aCxcblx0XHQgICAgb3V0LFxuXHRcdCAgICBpID0gMCxcblx0XHQgICAgbiA9IGluaXRpYWxOLFxuXHRcdCAgICBiaWFzID0gaW5pdGlhbEJpYXMsXG5cdFx0ICAgIGJhc2ljLFxuXHRcdCAgICBqLFxuXHRcdCAgICBpbmRleCxcblx0XHQgICAgb2xkaSxcblx0XHQgICAgdyxcblx0XHQgICAgayxcblx0XHQgICAgZGlnaXQsXG5cdFx0ICAgIHQsXG5cdFx0ICAgIC8qKiBDYWNoZWQgY2FsY3VsYXRpb24gcmVzdWx0cyAqL1xuXHRcdCAgICBiYXNlTWludXNUO1xuXG5cdFx0Ly8gSGFuZGxlIHRoZSBiYXNpYyBjb2RlIHBvaW50czogbGV0IGBiYXNpY2AgYmUgdGhlIG51bWJlciBvZiBpbnB1dCBjb2RlXG5cdFx0Ly8gcG9pbnRzIGJlZm9yZSB0aGUgbGFzdCBkZWxpbWl0ZXIsIG9yIGAwYCBpZiB0aGVyZSBpcyBub25lLCB0aGVuIGNvcHlcblx0XHQvLyB0aGUgZmlyc3QgYmFzaWMgY29kZSBwb2ludHMgdG8gdGhlIG91dHB1dC5cblxuXHRcdGJhc2ljID0gaW5wdXQubGFzdEluZGV4T2YoZGVsaW1pdGVyKTtcblx0XHRpZiAoYmFzaWMgPCAwKSB7XG5cdFx0XHRiYXNpYyA9IDA7XG5cdFx0fVxuXG5cdFx0Zm9yIChqID0gMDsgaiA8IGJhc2ljOyArK2opIHtcblx0XHRcdC8vIGlmIGl0J3Mgbm90IGEgYmFzaWMgY29kZSBwb2ludFxuXHRcdFx0aWYgKGlucHV0LmNoYXJDb2RlQXQoaikgPj0gMHg4MCkge1xuXHRcdFx0XHRlcnJvcignbm90LWJhc2ljJyk7XG5cdFx0XHR9XG5cdFx0XHRvdXRwdXQucHVzaChpbnB1dC5jaGFyQ29kZUF0KGopKTtcblx0XHR9XG5cblx0XHQvLyBNYWluIGRlY29kaW5nIGxvb3A6IHN0YXJ0IGp1c3QgYWZ0ZXIgdGhlIGxhc3QgZGVsaW1pdGVyIGlmIGFueSBiYXNpYyBjb2RlXG5cdFx0Ly8gcG9pbnRzIHdlcmUgY29waWVkOyBzdGFydCBhdCB0aGUgYmVnaW5uaW5nIG90aGVyd2lzZS5cblxuXHRcdGZvciAoaW5kZXggPSBiYXNpYyA+IDAgPyBiYXNpYyArIDEgOiAwOyBpbmRleCA8IGlucHV0TGVuZ3RoOyAvKiBubyBmaW5hbCBleHByZXNzaW9uICovKSB7XG5cblx0XHRcdC8vIGBpbmRleGAgaXMgdGhlIGluZGV4IG9mIHRoZSBuZXh0IGNoYXJhY3RlciB0byBiZSBjb25zdW1lZC5cblx0XHRcdC8vIERlY29kZSBhIGdlbmVyYWxpemVkIHZhcmlhYmxlLWxlbmd0aCBpbnRlZ2VyIGludG8gYGRlbHRhYCxcblx0XHRcdC8vIHdoaWNoIGdldHMgYWRkZWQgdG8gYGlgLiBUaGUgb3ZlcmZsb3cgY2hlY2tpbmcgaXMgZWFzaWVyXG5cdFx0XHQvLyBpZiB3ZSBpbmNyZWFzZSBgaWAgYXMgd2UgZ28sIHRoZW4gc3VidHJhY3Qgb2ZmIGl0cyBzdGFydGluZ1xuXHRcdFx0Ly8gdmFsdWUgYXQgdGhlIGVuZCB0byBvYnRhaW4gYGRlbHRhYC5cblx0XHRcdGZvciAob2xkaSA9IGksIHcgPSAxLCBrID0gYmFzZTsgLyogbm8gY29uZGl0aW9uICovOyBrICs9IGJhc2UpIHtcblxuXHRcdFx0XHRpZiAoaW5kZXggPj0gaW5wdXRMZW5ndGgpIHtcblx0XHRcdFx0XHRlcnJvcignaW52YWxpZC1pbnB1dCcpO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0ZGlnaXQgPSBiYXNpY1RvRGlnaXQoaW5wdXQuY2hhckNvZGVBdChpbmRleCsrKSk7XG5cblx0XHRcdFx0aWYgKGRpZ2l0ID49IGJhc2UgfHwgZGlnaXQgPiBmbG9vcigobWF4SW50IC0gaSkgLyB3KSkge1xuXHRcdFx0XHRcdGVycm9yKCdvdmVyZmxvdycpO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0aSArPSBkaWdpdCAqIHc7XG5cdFx0XHRcdHQgPSBrIDw9IGJpYXMgPyB0TWluIDogKGsgPj0gYmlhcyArIHRNYXggPyB0TWF4IDogayAtIGJpYXMpO1xuXG5cdFx0XHRcdGlmIChkaWdpdCA8IHQpIHtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGJhc2VNaW51c1QgPSBiYXNlIC0gdDtcblx0XHRcdFx0aWYgKHcgPiBmbG9vcihtYXhJbnQgLyBiYXNlTWludXNUKSkge1xuXHRcdFx0XHRcdGVycm9yKCdvdmVyZmxvdycpO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0dyAqPSBiYXNlTWludXNUO1xuXG5cdFx0XHR9XG5cblx0XHRcdG91dCA9IG91dHB1dC5sZW5ndGggKyAxO1xuXHRcdFx0YmlhcyA9IGFkYXB0KGkgLSBvbGRpLCBvdXQsIG9sZGkgPT0gMCk7XG5cblx0XHRcdC8vIGBpYCB3YXMgc3VwcG9zZWQgdG8gd3JhcCBhcm91bmQgZnJvbSBgb3V0YCB0byBgMGAsXG5cdFx0XHQvLyBpbmNyZW1lbnRpbmcgYG5gIGVhY2ggdGltZSwgc28gd2UnbGwgZml4IHRoYXQgbm93OlxuXHRcdFx0aWYgKGZsb29yKGkgLyBvdXQpID4gbWF4SW50IC0gbikge1xuXHRcdFx0XHRlcnJvcignb3ZlcmZsb3cnKTtcblx0XHRcdH1cblxuXHRcdFx0biArPSBmbG9vcihpIC8gb3V0KTtcblx0XHRcdGkgJT0gb3V0O1xuXG5cdFx0XHQvLyBJbnNlcnQgYG5gIGF0IHBvc2l0aW9uIGBpYCBvZiB0aGUgb3V0cHV0XG5cdFx0XHRvdXRwdXQuc3BsaWNlKGkrKywgMCwgbik7XG5cblx0XHR9XG5cblx0XHRyZXR1cm4gdWNzMmVuY29kZShvdXRwdXQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIENvbnZlcnRzIGEgc3RyaW5nIG9mIFVuaWNvZGUgc3ltYm9scyAoZS5nLiBhIGRvbWFpbiBuYW1lIGxhYmVsKSB0byBhXG5cdCAqIFB1bnljb2RlIHN0cmluZyBvZiBBU0NJSS1vbmx5IHN5bWJvbHMuXG5cdCAqIEBtZW1iZXJPZiBwdW55Y29kZVxuXHQgKiBAcGFyYW0ge1N0cmluZ30gaW5wdXQgVGhlIHN0cmluZyBvZiBVbmljb2RlIHN5bWJvbHMuXG5cdCAqIEByZXR1cm5zIHtTdHJpbmd9IFRoZSByZXN1bHRpbmcgUHVueWNvZGUgc3RyaW5nIG9mIEFTQ0lJLW9ubHkgc3ltYm9scy5cblx0ICovXG5cdGZ1bmN0aW9uIGVuY29kZShpbnB1dCkge1xuXHRcdHZhciBuLFxuXHRcdCAgICBkZWx0YSxcblx0XHQgICAgaGFuZGxlZENQQ291bnQsXG5cdFx0ICAgIGJhc2ljTGVuZ3RoLFxuXHRcdCAgICBiaWFzLFxuXHRcdCAgICBqLFxuXHRcdCAgICBtLFxuXHRcdCAgICBxLFxuXHRcdCAgICBrLFxuXHRcdCAgICB0LFxuXHRcdCAgICBjdXJyZW50VmFsdWUsXG5cdFx0ICAgIG91dHB1dCA9IFtdLFxuXHRcdCAgICAvKiogYGlucHV0TGVuZ3RoYCB3aWxsIGhvbGQgdGhlIG51bWJlciBvZiBjb2RlIHBvaW50cyBpbiBgaW5wdXRgLiAqL1xuXHRcdCAgICBpbnB1dExlbmd0aCxcblx0XHQgICAgLyoqIENhY2hlZCBjYWxjdWxhdGlvbiByZXN1bHRzICovXG5cdFx0ICAgIGhhbmRsZWRDUENvdW50UGx1c09uZSxcblx0XHQgICAgYmFzZU1pbnVzVCxcblx0XHQgICAgcU1pbnVzVDtcblxuXHRcdC8vIENvbnZlcnQgdGhlIGlucHV0IGluIFVDUy0yIHRvIFVuaWNvZGVcblx0XHRpbnB1dCA9IHVjczJkZWNvZGUoaW5wdXQpO1xuXG5cdFx0Ly8gQ2FjaGUgdGhlIGxlbmd0aFxuXHRcdGlucHV0TGVuZ3RoID0gaW5wdXQubGVuZ3RoO1xuXG5cdFx0Ly8gSW5pdGlhbGl6ZSB0aGUgc3RhdGVcblx0XHRuID0gaW5pdGlhbE47XG5cdFx0ZGVsdGEgPSAwO1xuXHRcdGJpYXMgPSBpbml0aWFsQmlhcztcblxuXHRcdC8vIEhhbmRsZSB0aGUgYmFzaWMgY29kZSBwb2ludHNcblx0XHRmb3IgKGogPSAwOyBqIDwgaW5wdXRMZW5ndGg7ICsraikge1xuXHRcdFx0Y3VycmVudFZhbHVlID0gaW5wdXRbal07XG5cdFx0XHRpZiAoY3VycmVudFZhbHVlIDwgMHg4MCkge1xuXHRcdFx0XHRvdXRwdXQucHVzaChzdHJpbmdGcm9tQ2hhckNvZGUoY3VycmVudFZhbHVlKSk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0aGFuZGxlZENQQ291bnQgPSBiYXNpY0xlbmd0aCA9IG91dHB1dC5sZW5ndGg7XG5cblx0XHQvLyBgaGFuZGxlZENQQ291bnRgIGlzIHRoZSBudW1iZXIgb2YgY29kZSBwb2ludHMgdGhhdCBoYXZlIGJlZW4gaGFuZGxlZDtcblx0XHQvLyBgYmFzaWNMZW5ndGhgIGlzIHRoZSBudW1iZXIgb2YgYmFzaWMgY29kZSBwb2ludHMuXG5cblx0XHQvLyBGaW5pc2ggdGhlIGJhc2ljIHN0cmluZyAtIGlmIGl0IGlzIG5vdCBlbXB0eSAtIHdpdGggYSBkZWxpbWl0ZXJcblx0XHRpZiAoYmFzaWNMZW5ndGgpIHtcblx0XHRcdG91dHB1dC5wdXNoKGRlbGltaXRlcik7XG5cdFx0fVxuXG5cdFx0Ly8gTWFpbiBlbmNvZGluZyBsb29wOlxuXHRcdHdoaWxlIChoYW5kbGVkQ1BDb3VudCA8IGlucHV0TGVuZ3RoKSB7XG5cblx0XHRcdC8vIEFsbCBub24tYmFzaWMgY29kZSBwb2ludHMgPCBuIGhhdmUgYmVlbiBoYW5kbGVkIGFscmVhZHkuIEZpbmQgdGhlIG5leHRcblx0XHRcdC8vIGxhcmdlciBvbmU6XG5cdFx0XHRmb3IgKG0gPSBtYXhJbnQsIGogPSAwOyBqIDwgaW5wdXRMZW5ndGg7ICsraikge1xuXHRcdFx0XHRjdXJyZW50VmFsdWUgPSBpbnB1dFtqXTtcblx0XHRcdFx0aWYgKGN1cnJlbnRWYWx1ZSA+PSBuICYmIGN1cnJlbnRWYWx1ZSA8IG0pIHtcblx0XHRcdFx0XHRtID0gY3VycmVudFZhbHVlO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIEluY3JlYXNlIGBkZWx0YWAgZW5vdWdoIHRvIGFkdmFuY2UgdGhlIGRlY29kZXIncyA8bixpPiBzdGF0ZSB0byA8bSwwPixcblx0XHRcdC8vIGJ1dCBndWFyZCBhZ2FpbnN0IG92ZXJmbG93XG5cdFx0XHRoYW5kbGVkQ1BDb3VudFBsdXNPbmUgPSBoYW5kbGVkQ1BDb3VudCArIDE7XG5cdFx0XHRpZiAobSAtIG4gPiBmbG9vcigobWF4SW50IC0gZGVsdGEpIC8gaGFuZGxlZENQQ291bnRQbHVzT25lKSkge1xuXHRcdFx0XHRlcnJvcignb3ZlcmZsb3cnKTtcblx0XHRcdH1cblxuXHRcdFx0ZGVsdGEgKz0gKG0gLSBuKSAqIGhhbmRsZWRDUENvdW50UGx1c09uZTtcblx0XHRcdG4gPSBtO1xuXG5cdFx0XHRmb3IgKGogPSAwOyBqIDwgaW5wdXRMZW5ndGg7ICsraikge1xuXHRcdFx0XHRjdXJyZW50VmFsdWUgPSBpbnB1dFtqXTtcblxuXHRcdFx0XHRpZiAoY3VycmVudFZhbHVlIDwgbiAmJiArK2RlbHRhID4gbWF4SW50KSB7XG5cdFx0XHRcdFx0ZXJyb3IoJ292ZXJmbG93Jyk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpZiAoY3VycmVudFZhbHVlID09IG4pIHtcblx0XHRcdFx0XHQvLyBSZXByZXNlbnQgZGVsdGEgYXMgYSBnZW5lcmFsaXplZCB2YXJpYWJsZS1sZW5ndGggaW50ZWdlclxuXHRcdFx0XHRcdGZvciAocSA9IGRlbHRhLCBrID0gYmFzZTsgLyogbm8gY29uZGl0aW9uICovOyBrICs9IGJhc2UpIHtcblx0XHRcdFx0XHRcdHQgPSBrIDw9IGJpYXMgPyB0TWluIDogKGsgPj0gYmlhcyArIHRNYXggPyB0TWF4IDogayAtIGJpYXMpO1xuXHRcdFx0XHRcdFx0aWYgKHEgPCB0KSB7XG5cdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0cU1pbnVzVCA9IHEgLSB0O1xuXHRcdFx0XHRcdFx0YmFzZU1pbnVzVCA9IGJhc2UgLSB0O1xuXHRcdFx0XHRcdFx0b3V0cHV0LnB1c2goXG5cdFx0XHRcdFx0XHRcdHN0cmluZ0Zyb21DaGFyQ29kZShkaWdpdFRvQmFzaWModCArIHFNaW51c1QgJSBiYXNlTWludXNULCAwKSlcblx0XHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0XHRxID0gZmxvb3IocU1pbnVzVCAvIGJhc2VNaW51c1QpO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdG91dHB1dC5wdXNoKHN0cmluZ0Zyb21DaGFyQ29kZShkaWdpdFRvQmFzaWMocSwgMCkpKTtcblx0XHRcdFx0XHRiaWFzID0gYWRhcHQoZGVsdGEsIGhhbmRsZWRDUENvdW50UGx1c09uZSwgaGFuZGxlZENQQ291bnQgPT0gYmFzaWNMZW5ndGgpO1xuXHRcdFx0XHRcdGRlbHRhID0gMDtcblx0XHRcdFx0XHQrK2hhbmRsZWRDUENvdW50O1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdCsrZGVsdGE7XG5cdFx0XHQrK247XG5cblx0XHR9XG5cdFx0cmV0dXJuIG91dHB1dC5qb2luKCcnKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDb252ZXJ0cyBhIFB1bnljb2RlIHN0cmluZyByZXByZXNlbnRpbmcgYSBkb21haW4gbmFtZSBvciBhbiBlbWFpbCBhZGRyZXNzXG5cdCAqIHRvIFVuaWNvZGUuIE9ubHkgdGhlIFB1bnljb2RlZCBwYXJ0cyBvZiB0aGUgaW5wdXQgd2lsbCBiZSBjb252ZXJ0ZWQsIGkuZS5cblx0ICogaXQgZG9lc24ndCBtYXR0ZXIgaWYgeW91IGNhbGwgaXQgb24gYSBzdHJpbmcgdGhhdCBoYXMgYWxyZWFkeSBiZWVuXG5cdCAqIGNvbnZlcnRlZCB0byBVbmljb2RlLlxuXHQgKiBAbWVtYmVyT2YgcHVueWNvZGVcblx0ICogQHBhcmFtIHtTdHJpbmd9IGlucHV0IFRoZSBQdW55Y29kZWQgZG9tYWluIG5hbWUgb3IgZW1haWwgYWRkcmVzcyB0b1xuXHQgKiBjb252ZXJ0IHRvIFVuaWNvZGUuXG5cdCAqIEByZXR1cm5zIHtTdHJpbmd9IFRoZSBVbmljb2RlIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBnaXZlbiBQdW55Y29kZVxuXHQgKiBzdHJpbmcuXG5cdCAqL1xuXHRmdW5jdGlvbiB0b1VuaWNvZGUoaW5wdXQpIHtcblx0XHRyZXR1cm4gbWFwRG9tYWluKGlucHV0LCBmdW5jdGlvbihzdHJpbmcpIHtcblx0XHRcdHJldHVybiByZWdleFB1bnljb2RlLnRlc3Qoc3RyaW5nKVxuXHRcdFx0XHQ/IGRlY29kZShzdHJpbmcuc2xpY2UoNCkudG9Mb3dlckNhc2UoKSlcblx0XHRcdFx0OiBzdHJpbmc7XG5cdFx0fSk7XG5cdH1cblxuXHQvKipcblx0ICogQ29udmVydHMgYSBVbmljb2RlIHN0cmluZyByZXByZXNlbnRpbmcgYSBkb21haW4gbmFtZSBvciBhbiBlbWFpbCBhZGRyZXNzIHRvXG5cdCAqIFB1bnljb2RlLiBPbmx5IHRoZSBub24tQVNDSUkgcGFydHMgb2YgdGhlIGRvbWFpbiBuYW1lIHdpbGwgYmUgY29udmVydGVkLFxuXHQgKiBpLmUuIGl0IGRvZXNuJ3QgbWF0dGVyIGlmIHlvdSBjYWxsIGl0IHdpdGggYSBkb21haW4gdGhhdCdzIGFscmVhZHkgaW5cblx0ICogQVNDSUkuXG5cdCAqIEBtZW1iZXJPZiBwdW55Y29kZVxuXHQgKiBAcGFyYW0ge1N0cmluZ30gaW5wdXQgVGhlIGRvbWFpbiBuYW1lIG9yIGVtYWlsIGFkZHJlc3MgdG8gY29udmVydCwgYXMgYVxuXHQgKiBVbmljb2RlIHN0cmluZy5cblx0ICogQHJldHVybnMge1N0cmluZ30gVGhlIFB1bnljb2RlIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBnaXZlbiBkb21haW4gbmFtZSBvclxuXHQgKiBlbWFpbCBhZGRyZXNzLlxuXHQgKi9cblx0ZnVuY3Rpb24gdG9BU0NJSShpbnB1dCkge1xuXHRcdHJldHVybiBtYXBEb21haW4oaW5wdXQsIGZ1bmN0aW9uKHN0cmluZykge1xuXHRcdFx0cmV0dXJuIHJlZ2V4Tm9uQVNDSUkudGVzdChzdHJpbmcpXG5cdFx0XHRcdD8gJ3huLS0nICsgZW5jb2RlKHN0cmluZylcblx0XHRcdFx0OiBzdHJpbmc7XG5cdFx0fSk7XG5cdH1cblxuXHQvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuXHQvKiogRGVmaW5lIHRoZSBwdWJsaWMgQVBJICovXG5cdHB1bnljb2RlID0ge1xuXHRcdC8qKlxuXHRcdCAqIEEgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgY3VycmVudCBQdW55Y29kZS5qcyB2ZXJzaW9uIG51bWJlci5cblx0XHQgKiBAbWVtYmVyT2YgcHVueWNvZGVcblx0XHQgKiBAdHlwZSBTdHJpbmdcblx0XHQgKi9cblx0XHQndmVyc2lvbic6ICcxLjQuMScsXG5cdFx0LyoqXG5cdFx0ICogQW4gb2JqZWN0IG9mIG1ldGhvZHMgdG8gY29udmVydCBmcm9tIEphdmFTY3JpcHQncyBpbnRlcm5hbCBjaGFyYWN0ZXJcblx0XHQgKiByZXByZXNlbnRhdGlvbiAoVUNTLTIpIHRvIFVuaWNvZGUgY29kZSBwb2ludHMsIGFuZCBiYWNrLlxuXHRcdCAqIEBzZWUgPGh0dHBzOi8vbWF0aGlhc2J5bmVucy5iZS9ub3Rlcy9qYXZhc2NyaXB0LWVuY29kaW5nPlxuXHRcdCAqIEBtZW1iZXJPZiBwdW55Y29kZVxuXHRcdCAqIEB0eXBlIE9iamVjdFxuXHRcdCAqL1xuXHRcdCd1Y3MyJzoge1xuXHRcdFx0J2RlY29kZSc6IHVjczJkZWNvZGUsXG5cdFx0XHQnZW5jb2RlJzogdWNzMmVuY29kZVxuXHRcdH0sXG5cdFx0J2RlY29kZSc6IGRlY29kZSxcblx0XHQnZW5jb2RlJzogZW5jb2RlLFxuXHRcdCd0b0FTQ0lJJzogdG9BU0NJSSxcblx0XHQndG9Vbmljb2RlJzogdG9Vbmljb2RlXG5cdH07XG5cblx0LyoqIEV4cG9zZSBgcHVueWNvZGVgICovXG5cdC8vIFNvbWUgQU1EIGJ1aWxkIG9wdGltaXplcnMsIGxpa2Ugci5qcywgY2hlY2sgZm9yIHNwZWNpZmljIGNvbmRpdGlvbiBwYXR0ZXJuc1xuXHQvLyBsaWtlIHRoZSBmb2xsb3dpbmc6XG5cdGlmIChcblx0XHR0eXBlb2YgZGVmaW5lID09ICdmdW5jdGlvbicgJiZcblx0XHR0eXBlb2YgZGVmaW5lLmFtZCA9PSAnb2JqZWN0JyAmJlxuXHRcdGRlZmluZS5hbWRcblx0KSB7XG5cdFx0ZGVmaW5lKCdwdW55Y29kZScsIGZ1bmN0aW9uKCkge1xuXHRcdFx0cmV0dXJuIHB1bnljb2RlO1xuXHRcdH0pO1xuXHR9IGVsc2UgaWYgKGZyZWVFeHBvcnRzICYmIGZyZWVNb2R1bGUpIHtcblx0XHRpZiAobW9kdWxlLmV4cG9ydHMgPT0gZnJlZUV4cG9ydHMpIHtcblx0XHRcdC8vIGluIE5vZGUuanMsIGlvLmpzLCBvciBSaW5nb0pTIHYwLjguMCtcblx0XHRcdGZyZWVNb2R1bGUuZXhwb3J0cyA9IHB1bnljb2RlO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHQvLyBpbiBOYXJ3aGFsIG9yIFJpbmdvSlMgdjAuNy4wLVxuXHRcdFx0Zm9yIChrZXkgaW4gcHVueWNvZGUpIHtcblx0XHRcdFx0cHVueWNvZGUuaGFzT3duUHJvcGVydHkoa2V5KSAmJiAoZnJlZUV4cG9ydHNba2V5XSA9IHB1bnljb2RlW2tleV0pO1xuXHRcdFx0fVxuXHRcdH1cblx0fSBlbHNlIHtcblx0XHQvLyBpbiBSaGlubyBvciBhIHdlYiBicm93c2VyXG5cdFx0cm9vdC5wdW55Y29kZSA9IHB1bnljb2RlO1xuXHR9XG5cbn0odGhpcykpO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgcmVwbGFjZSA9IFN0cmluZy5wcm90b3R5cGUucmVwbGFjZTtcbnZhciBwZXJjZW50VHdlbnRpZXMgPSAvJTIwL2c7XG5cbnZhciBGb3JtYXQgPSB7XG4gICAgUkZDMTczODogJ1JGQzE3MzgnLFxuICAgIFJGQzM5ODY6ICdSRkMzOTg2J1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gICAgJ2RlZmF1bHQnOiBGb3JtYXQuUkZDMzk4NixcbiAgICBmb3JtYXR0ZXJzOiB7XG4gICAgICAgIFJGQzE3Mzg6IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAgICAgcmV0dXJuIHJlcGxhY2UuY2FsbCh2YWx1ZSwgcGVyY2VudFR3ZW50aWVzLCAnKycpO1xuICAgICAgICB9LFxuICAgICAgICBSRkMzOTg2OiBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICAgIHJldHVybiBTdHJpbmcodmFsdWUpO1xuICAgICAgICB9XG4gICAgfSxcbiAgICBSRkMxNzM4OiBGb3JtYXQuUkZDMTczOCxcbiAgICBSRkMzOTg2OiBGb3JtYXQuUkZDMzk4NlxufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHN0cmluZ2lmeSA9IHJlcXVpcmUoJy4vc3RyaW5naWZ5Jyk7XG52YXIgcGFyc2UgPSByZXF1aXJlKCcuL3BhcnNlJyk7XG52YXIgZm9ybWF0cyA9IHJlcXVpcmUoJy4vZm9ybWF0cycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgICBmb3JtYXRzOiBmb3JtYXRzLFxuICAgIHBhcnNlOiBwYXJzZSxcbiAgICBzdHJpbmdpZnk6IHN0cmluZ2lmeVxufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi91dGlscycpO1xuXG52YXIgaGFzID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcbnZhciBpc0FycmF5ID0gQXJyYXkuaXNBcnJheTtcblxudmFyIGRlZmF1bHRzID0ge1xuICAgIGFsbG93RG90czogZmFsc2UsXG4gICAgYWxsb3dFbXB0eUFycmF5czogZmFsc2UsXG4gICAgYWxsb3dQcm90b3R5cGVzOiBmYWxzZSxcbiAgICBhbGxvd1NwYXJzZTogZmFsc2UsXG4gICAgYXJyYXlMaW1pdDogMjAsXG4gICAgY2hhcnNldDogJ3V0Zi04JyxcbiAgICBjaGFyc2V0U2VudGluZWw6IGZhbHNlLFxuICAgIGNvbW1hOiBmYWxzZSxcbiAgICBkZWNvZGVEb3RJbktleXM6IGZhbHNlLFxuICAgIGRlY29kZXI6IHV0aWxzLmRlY29kZSxcbiAgICBkZWxpbWl0ZXI6ICcmJyxcbiAgICBkZXB0aDogNSxcbiAgICBkdXBsaWNhdGVzOiAnY29tYmluZScsXG4gICAgaWdub3JlUXVlcnlQcmVmaXg6IGZhbHNlLFxuICAgIGludGVycHJldE51bWVyaWNFbnRpdGllczogZmFsc2UsXG4gICAgcGFyYW1ldGVyTGltaXQ6IDEwMDAsXG4gICAgcGFyc2VBcnJheXM6IHRydWUsXG4gICAgcGxhaW5PYmplY3RzOiBmYWxzZSxcbiAgICBzdHJpY3REZXB0aDogZmFsc2UsXG4gICAgc3RyaWN0TWVyZ2U6IHRydWUsXG4gICAgc3RyaWN0TnVsbEhhbmRsaW5nOiBmYWxzZSxcbiAgICB0aHJvd09uTGltaXRFeGNlZWRlZDogZmFsc2Vcbn07XG5cbnZhciBpbnRlcnByZXROdW1lcmljRW50aXRpZXMgPSBmdW5jdGlvbiAoc3RyKSB7XG4gICAgcmV0dXJuIHN0ci5yZXBsYWNlKC8mIyhcXGQrKTsvZywgZnVuY3Rpb24gKCQwLCBudW1iZXJTdHIpIHtcbiAgICAgICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUocGFyc2VJbnQobnVtYmVyU3RyLCAxMCkpO1xuICAgIH0pO1xufTtcblxudmFyIHBhcnNlQXJyYXlWYWx1ZSA9IGZ1bmN0aW9uICh2YWwsIG9wdGlvbnMsIGN1cnJlbnRBcnJheUxlbmd0aCwgaXNGbGF0QXJyYXlWYWx1ZSkge1xuICAgIGlmICh2YWwgJiYgdHlwZW9mIHZhbCA9PT0gJ3N0cmluZycgJiYgb3B0aW9ucy5jb21tYSAmJiB2YWwuaW5kZXhPZignLCcpID4gLTEpIHtcbiAgICAgICAgaWYgKGlzRmxhdEFycmF5VmFsdWUgJiYgb3B0aW9ucy50aHJvd09uTGltaXRFeGNlZWRlZCkge1xuICAgICAgICAgICAgdmFyIGNvbW1hQ291bnQgPSAwO1xuICAgICAgICAgICAgdmFyIGNvbW1hSW5kZXggPSB2YWwuaW5kZXhPZignLCcpO1xuICAgICAgICAgICAgd2hpbGUgKGNvbW1hSW5kZXggPiAtMSkge1xuICAgICAgICAgICAgICAgIGNvbW1hQ291bnQgKz0gMTtcbiAgICAgICAgICAgICAgICBpZiAoY29tbWFDb3VudCA+PSBvcHRpb25zLmFycmF5TGltaXQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0FycmF5IGxpbWl0IGV4Y2VlZGVkLiBPbmx5ICcgKyBvcHRpb25zLmFycmF5TGltaXQgKyAnIGVsZW1lbnQnICsgKG9wdGlvbnMuYXJyYXlMaW1pdCA9PT0gMSA/ICcnIDogJ3MnKSArICcgYWxsb3dlZCBpbiBhbiBhcnJheS4nKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29tbWFJbmRleCA9IHZhbC5pbmRleE9mKCcsJywgY29tbWFJbmRleCArIDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB2YWwuc3BsaXQoJywnKTtcbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucy50aHJvd09uTGltaXRFeGNlZWRlZCAmJiBjdXJyZW50QXJyYXlMZW5ndGggPj0gb3B0aW9ucy5hcnJheUxpbWl0KSB7XG4gICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdBcnJheSBsaW1pdCBleGNlZWRlZC4gT25seSAnICsgb3B0aW9ucy5hcnJheUxpbWl0ICsgJyBlbGVtZW50JyArIChvcHRpb25zLmFycmF5TGltaXQgPT09IDEgPyAnJyA6ICdzJykgKyAnIGFsbG93ZWQgaW4gYW4gYXJyYXkuJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbDtcbn07XG5cbi8vIFRoaXMgaXMgd2hhdCBicm93c2VycyB3aWxsIHN1Ym1pdCB3aGVuIHRoZSDinJMgY2hhcmFjdGVyIG9jY3VycyBpbiBhblxuLy8gYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkIGJvZHkgYW5kIHRoZSBlbmNvZGluZyBvZiB0aGUgcGFnZSBjb250YWluaW5nXG4vLyB0aGUgZm9ybSBpcyBpc28tODg1OS0xLCBvciB3aGVuIHRoZSBzdWJtaXR0ZWQgZm9ybSBoYXMgYW4gYWNjZXB0LWNoYXJzZXRcbi8vIGF0dHJpYnV0ZSBvZiBpc28tODg1OS0xLiBQcmVzdW1hYmx5IGFsc28gd2l0aCBvdGhlciBjaGFyc2V0cyB0aGF0IGRvIG5vdCBjb250YWluXG4vLyB0aGUg4pyTIGNoYXJhY3Rlciwgc3VjaCBhcyB1cy1hc2NpaS5cbnZhciBpc29TZW50aW5lbCA9ICd1dGY4PSUyNiUyMzEwMDAzJTNCJzsgLy8gZW5jb2RlVVJJQ29tcG9uZW50KCcmIzEwMDAzOycpXG5cbi8vIFRoZXNlIGFyZSB0aGUgcGVyY2VudC1lbmNvZGVkIHV0Zi04IG9jdGV0cyByZXByZXNlbnRpbmcgYSBjaGVja21hcmssIGluZGljYXRpbmcgdGhhdCB0aGUgcmVxdWVzdCBhY3R1YWxseSBpcyB1dGYtOCBlbmNvZGVkLlxudmFyIGNoYXJzZXRTZW50aW5lbCA9ICd1dGY4PSVFMiU5QyU5Myc7IC8vIGVuY29kZVVSSUNvbXBvbmVudCgn4pyTJylcblxudmFyIHBhcnNlVmFsdWVzID0gZnVuY3Rpb24gcGFyc2VRdWVyeVN0cmluZ1ZhbHVlcyhzdHIsIG9wdGlvbnMpIHtcbiAgICB2YXIgb2JqID0geyBfX3Byb3RvX186IG51bGwgfTtcblxuICAgIHZhciBjbGVhblN0ciA9IG9wdGlvbnMuaWdub3JlUXVlcnlQcmVmaXggPyBzdHIucmVwbGFjZSgvXlxcPy8sICcnKSA6IHN0cjtcbiAgICBjbGVhblN0ciA9IGNsZWFuU3RyLnJlcGxhY2UoLyU1Qi9naSwgJ1snKS5yZXBsYWNlKC8lNUQvZ2ksICddJyk7XG5cbiAgICB2YXIgbGltaXQgPSBvcHRpb25zLnBhcmFtZXRlckxpbWl0ID09PSBJbmZpbml0eSA/IHZvaWQgdW5kZWZpbmVkIDogb3B0aW9ucy5wYXJhbWV0ZXJMaW1pdDtcbiAgICB2YXIgcGFydHMgPSBjbGVhblN0ci5zcGxpdChcbiAgICAgICAgb3B0aW9ucy5kZWxpbWl0ZXIsXG4gICAgICAgIG9wdGlvbnMudGhyb3dPbkxpbWl0RXhjZWVkZWQgJiYgdHlwZW9mIGxpbWl0ICE9PSAndW5kZWZpbmVkJyA/IGxpbWl0ICsgMSA6IGxpbWl0XG4gICAgKTtcblxuICAgIGlmIChvcHRpb25zLnRocm93T25MaW1pdEV4Y2VlZGVkICYmIHR5cGVvZiBsaW1pdCAhPT0gJ3VuZGVmaW5lZCcgJiYgcGFydHMubGVuZ3RoID4gbGltaXQpIHtcbiAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1BhcmFtZXRlciBsaW1pdCBleGNlZWRlZC4gT25seSAnICsgbGltaXQgKyAnIHBhcmFtZXRlcicgKyAobGltaXQgPT09IDEgPyAnJyA6ICdzJykgKyAnIGFsbG93ZWQuJyk7XG4gICAgfVxuXG4gICAgdmFyIHNraXBJbmRleCA9IC0xOyAvLyBLZWVwIHRyYWNrIG9mIHdoZXJlIHRoZSB1dGY4IHNlbnRpbmVsIHdhcyBmb3VuZFxuICAgIHZhciBpO1xuXG4gICAgdmFyIGNoYXJzZXQgPSBvcHRpb25zLmNoYXJzZXQ7XG4gICAgaWYgKG9wdGlvbnMuY2hhcnNldFNlbnRpbmVsKSB7XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBwYXJ0cy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgaWYgKHBhcnRzW2ldLmluZGV4T2YoJ3V0Zjg9JykgPT09IDApIHtcbiAgICAgICAgICAgICAgICBpZiAocGFydHNbaV0gPT09IGNoYXJzZXRTZW50aW5lbCkge1xuICAgICAgICAgICAgICAgICAgICBjaGFyc2V0ID0gJ3V0Zi04JztcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHBhcnRzW2ldID09PSBpc29TZW50aW5lbCkge1xuICAgICAgICAgICAgICAgICAgICBjaGFyc2V0ID0gJ2lzby04ODU5LTEnO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBza2lwSW5kZXggPSBpO1xuICAgICAgICAgICAgICAgIGkgPSBwYXJ0cy5sZW5ndGg7IC8vIFRoZSBlc2xpbnQgc2V0dGluZ3MgZG8gbm90IGFsbG93IGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZm9yIChpID0gMDsgaSA8IHBhcnRzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIGlmIChpID09PSBza2lwSW5kZXgpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIHZhciBwYXJ0ID0gcGFydHNbaV07XG5cbiAgICAgICAgdmFyIGJyYWNrZXRFcXVhbHNQb3MgPSBwYXJ0LmluZGV4T2YoJ109Jyk7XG4gICAgICAgIHZhciBwb3MgPSBicmFja2V0RXF1YWxzUG9zID09PSAtMSA/IHBhcnQuaW5kZXhPZignPScpIDogYnJhY2tldEVxdWFsc1BvcyArIDE7XG5cbiAgICAgICAgdmFyIGtleTtcbiAgICAgICAgdmFyIHZhbDtcbiAgICAgICAgaWYgKHBvcyA9PT0gLTEpIHtcbiAgICAgICAgICAgIGtleSA9IG9wdGlvbnMuZGVjb2RlcihwYXJ0LCBkZWZhdWx0cy5kZWNvZGVyLCBjaGFyc2V0LCAna2V5Jyk7XG4gICAgICAgICAgICB2YWwgPSBvcHRpb25zLnN0cmljdE51bGxIYW5kbGluZyA/IG51bGwgOiAnJztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGtleSA9IG9wdGlvbnMuZGVjb2RlcihwYXJ0LnNsaWNlKDAsIHBvcyksIGRlZmF1bHRzLmRlY29kZXIsIGNoYXJzZXQsICdrZXknKTtcblxuICAgICAgICAgICAgaWYgKGtleSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHZhbCA9IHV0aWxzLm1heWJlTWFwKFxuICAgICAgICAgICAgICAgICAgICBwYXJzZUFycmF5VmFsdWUoXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXJ0LnNsaWNlKHBvcyArIDEpLFxuICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGlzQXJyYXkob2JqW2tleV0pID8gb2JqW2tleV0ubGVuZ3RoIDogMCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcnQuaW5kZXhPZignW109JykgPT09IC0xXG4gICAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIChlbmNvZGVkVmFsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gb3B0aW9ucy5kZWNvZGVyKGVuY29kZWRWYWwsIGRlZmF1bHRzLmRlY29kZXIsIGNoYXJzZXQsICd2YWx1ZScpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh2YWwgJiYgb3B0aW9ucy5pbnRlcnByZXROdW1lcmljRW50aXRpZXMgJiYgY2hhcnNldCA9PT0gJ2lzby04ODU5LTEnKSB7XG4gICAgICAgICAgICB2YWwgPSBpbnRlcnByZXROdW1lcmljRW50aXRpZXMoU3RyaW5nKHZhbCkpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBhcnQuaW5kZXhPZignW109JykgPiAtMSkge1xuICAgICAgICAgICAgdmFsID0gaXNBcnJheSh2YWwpID8gW3ZhbF0gOiB2YWw7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAob3B0aW9ucy5jb21tYSAmJiBpc0FycmF5KHZhbCkgJiYgdmFsLmxlbmd0aCA+IG9wdGlvbnMuYXJyYXlMaW1pdCkge1xuICAgICAgICAgICAgdmFsID0gdXRpbHMuY29tYmluZShbXSwgdmFsLCBvcHRpb25zLmFycmF5TGltaXQsIG9wdGlvbnMucGxhaW5PYmplY3RzLCBvcHRpb25zLnRocm93T25MaW1pdEV4Y2VlZGVkKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChrZXkgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHZhciBleGlzdGluZyA9IGhhcy5jYWxsKG9iaiwga2V5KTtcbiAgICAgICAgICAgIGlmIChleGlzdGluZyAmJiAob3B0aW9ucy5kdXBsaWNhdGVzID09PSAnY29tYmluZScgfHwgcGFydC5pbmRleE9mKCdbXT0nKSA+IC0xKSkge1xuICAgICAgICAgICAgICAgIG9ialtrZXldID0gdXRpbHMuY29tYmluZShcbiAgICAgICAgICAgICAgICAgICAgb2JqW2tleV0sXG4gICAgICAgICAgICAgICAgICAgIHZhbCxcbiAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5hcnJheUxpbWl0LFxuICAgICAgICAgICAgICAgICAgICBvcHRpb25zLnBsYWluT2JqZWN0cyxcbiAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy50aHJvd09uTGltaXRFeGNlZWRlZFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKCFleGlzdGluZyB8fCBvcHRpb25zLmR1cGxpY2F0ZXMgPT09ICdsYXN0Jykge1xuICAgICAgICAgICAgICAgIG9ialtrZXldID0gdmFsO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG9iajtcbn07XG5cbnZhciBwYXJzZU9iamVjdCA9IGZ1bmN0aW9uIChjaGFpbiwgdmFsLCBvcHRpb25zLCB2YWx1ZXNQYXJzZWQpIHtcbiAgICB2YXIgY3VycmVudEFycmF5TGVuZ3RoID0gMDtcbiAgICBpZiAoY2hhaW4ubGVuZ3RoID4gMCAmJiBjaGFpbltjaGFpbi5sZW5ndGggLSAxXSA9PT0gJ1tdJykge1xuICAgICAgICB2YXIgcGFyZW50S2V5ID0gY2hhaW4uc2xpY2UoMCwgLTEpLmpvaW4oJycpO1xuICAgICAgICBjdXJyZW50QXJyYXlMZW5ndGggPSBBcnJheS5pc0FycmF5KHZhbCkgJiYgdmFsW3BhcmVudEtleV0gPyB2YWxbcGFyZW50S2V5XS5sZW5ndGggOiAwO1xuICAgIH1cblxuICAgIHZhciBsZWFmID0gdmFsdWVzUGFyc2VkID8gdmFsIDogcGFyc2VBcnJheVZhbHVlKHZhbCwgb3B0aW9ucywgY3VycmVudEFycmF5TGVuZ3RoKTtcblxuICAgIGZvciAodmFyIGkgPSBjaGFpbi5sZW5ndGggLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgICB2YXIgb2JqO1xuICAgICAgICB2YXIgcm9vdCA9IGNoYWluW2ldO1xuXG4gICAgICAgIGlmIChyb290ID09PSAnW10nICYmIG9wdGlvbnMucGFyc2VBcnJheXMpIHtcbiAgICAgICAgICAgIGlmICh1dGlscy5pc092ZXJmbG93KGxlYWYpKSB7XG4gICAgICAgICAgICAgICAgLy8gbGVhZiBpcyBhbHJlYWR5IGFuIG92ZXJmbG93IG9iamVjdCwgcHJlc2VydmUgaXRcbiAgICAgICAgICAgICAgICBvYmogPSBsZWFmO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBvYmogPSBvcHRpb25zLmFsbG93RW1wdHlBcnJheXMgJiYgKGxlYWYgPT09ICcnIHx8IChvcHRpb25zLnN0cmljdE51bGxIYW5kbGluZyAmJiBsZWFmID09PSBudWxsKSlcbiAgICAgICAgICAgICAgICAgICAgPyBbXVxuICAgICAgICAgICAgICAgICAgICA6IHV0aWxzLmNvbWJpbmUoXG4gICAgICAgICAgICAgICAgICAgICAgICBbXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGxlYWYsXG4gICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLmFycmF5TGltaXQsXG4gICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLnBsYWluT2JqZWN0cyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMudGhyb3dPbkxpbWl0RXhjZWVkZWRcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG9iaiA9IG9wdGlvbnMucGxhaW5PYmplY3RzID8geyBfX3Byb3RvX186IG51bGwgfSA6IHt9O1xuICAgICAgICAgICAgdmFyIGNsZWFuUm9vdCA9IHJvb3QuY2hhckF0KDApID09PSAnWycgJiYgcm9vdC5jaGFyQXQocm9vdC5sZW5ndGggLSAxKSA9PT0gJ10nID8gcm9vdC5zbGljZSgxLCAtMSkgOiByb290O1xuICAgICAgICAgICAgdmFyIGRlY29kZWRSb290ID0gb3B0aW9ucy5kZWNvZGVEb3RJbktleXMgPyBjbGVhblJvb3QucmVwbGFjZSgvJTJFL2csICcuJykgOiBjbGVhblJvb3Q7XG4gICAgICAgICAgICB2YXIgaW5kZXggPSBwYXJzZUludChkZWNvZGVkUm9vdCwgMTApO1xuICAgICAgICAgICAgdmFyIGlzVmFsaWRBcnJheUluZGV4ID0gIWlzTmFOKGluZGV4KVxuICAgICAgICAgICAgICAgICYmIHJvb3QgIT09IGRlY29kZWRSb290XG4gICAgICAgICAgICAgICAgJiYgU3RyaW5nKGluZGV4KSA9PT0gZGVjb2RlZFJvb3RcbiAgICAgICAgICAgICAgICAmJiBpbmRleCA+PSAwXG4gICAgICAgICAgICAgICAgJiYgb3B0aW9ucy5wYXJzZUFycmF5cztcbiAgICAgICAgICAgIGlmICghb3B0aW9ucy5wYXJzZUFycmF5cyAmJiBkZWNvZGVkUm9vdCA9PT0gJycpIHtcbiAgICAgICAgICAgICAgICBvYmogPSB7IDA6IGxlYWYgfTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNWYWxpZEFycmF5SW5kZXggJiYgaW5kZXggPCBvcHRpb25zLmFycmF5TGltaXQpIHtcbiAgICAgICAgICAgICAgICBvYmogPSBbXTtcbiAgICAgICAgICAgICAgICBvYmpbaW5kZXhdID0gbGVhZjtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNWYWxpZEFycmF5SW5kZXggJiYgb3B0aW9ucy50aHJvd09uTGltaXRFeGNlZWRlZCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdBcnJheSBsaW1pdCBleGNlZWRlZC4gT25seSAnICsgb3B0aW9ucy5hcnJheUxpbWl0ICsgJyBlbGVtZW50JyArIChvcHRpb25zLmFycmF5TGltaXQgPT09IDEgPyAnJyA6ICdzJykgKyAnIGFsbG93ZWQgaW4gYW4gYXJyYXkuJyk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGlzVmFsaWRBcnJheUluZGV4KSB7XG4gICAgICAgICAgICAgICAgb2JqW2luZGV4XSA9IGxlYWY7XG4gICAgICAgICAgICAgICAgdXRpbHMubWFya092ZXJmbG93KG9iaiwgaW5kZXgpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChkZWNvZGVkUm9vdCAhPT0gJ19fcHJvdG9fXycpIHtcbiAgICAgICAgICAgICAgICBvYmpbZGVjb2RlZFJvb3RdID0gbGVhZjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGxlYWYgPSBvYmo7XG4gICAgfVxuXG4gICAgcmV0dXJuIGxlYWY7XG59O1xuXG4vLyBTcGxpdCBhIGtleSBsaWtlIFwiYVtiXVtjW11dXCIgaW50byBbJ2EnLCAnW2JdJywgJ1tjW11dJ10gd2hpbGUgcHJlc2VydmluZ1xuLy8gcXMgcGFyc2Ugc2VtYW50aWNzIGZvciBkZXB0aC9wcm90b3R5cGUgZ3VhcmRzLlxudmFyIHNwbGl0S2V5SW50b1NlZ21lbnRzID0gZnVuY3Rpb24gc3BsaXRLZXlJbnRvU2VnbWVudHMob3JpZ2luYWxLZXksIG9wdGlvbnMpIHtcbiAgICB2YXIga2V5ID0gb3B0aW9ucy5hbGxvd0RvdHMgPyBvcmlnaW5hbEtleS5yZXBsYWNlKC9cXC4oW14uW10rKS9nLCAnWyQxXScpIDogb3JpZ2luYWxLZXk7XG5cbiAgICAvLyBkZXB0aCA8PSAwIGtlZXBzIHRoZSB3aG9sZSBrZXkgYXMgb25lIHNlZ21lbnRcbiAgICBpZiAob3B0aW9ucy5kZXB0aCA8PSAwKSB7XG4gICAgICAgIGlmICghb3B0aW9ucy5wbGFpbk9iamVjdHMgJiYgaGFzLmNhbGwoT2JqZWN0LnByb3RvdHlwZSwga2V5KSkge1xuICAgICAgICAgICAgaWYgKCFvcHRpb25zLmFsbG93UHJvdG90eXBlcykge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBba2V5XTtcbiAgICB9XG5cbiAgICB2YXIgc2VnbWVudHMgPSBbXTtcblxuICAgIC8vIHBhcmVudCBiZWZvcmUgdGhlIGZpcnN0ICdbJyAobWF5IGJlIGVtcHR5IGlmIGtleSBzdGFydHMgd2l0aCAnWycpXG4gICAgdmFyIGZpcnN0ID0ga2V5LmluZGV4T2YoJ1snKTtcbiAgICB2YXIgcGFyZW50ID0gZmlyc3QgPj0gMCA/IGtleS5zbGljZSgwLCBmaXJzdCkgOiBrZXk7XG4gICAgaWYgKHBhcmVudCkge1xuICAgICAgICBpZiAoIW9wdGlvbnMucGxhaW5PYmplY3RzICYmIGhhcy5jYWxsKE9iamVjdC5wcm90b3R5cGUsIHBhcmVudCkpIHtcbiAgICAgICAgICAgIGlmICghb3B0aW9ucy5hbGxvd1Byb3RvdHlwZXMpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBzZWdtZW50c1tzZWdtZW50cy5sZW5ndGhdID0gcGFyZW50O1xuICAgIH1cblxuICAgIHZhciBuID0ga2V5Lmxlbmd0aDtcbiAgICB2YXIgb3BlbiA9IGZpcnN0O1xuICAgIHZhciBjb2xsZWN0ZWQgPSAwO1xuXG4gICAgd2hpbGUgKG9wZW4gPj0gMCAmJiBjb2xsZWN0ZWQgPCBvcHRpb25zLmRlcHRoKSB7XG4gICAgICAgIHZhciBsZXZlbCA9IDE7XG4gICAgICAgIHZhciBpID0gb3BlbiArIDE7XG4gICAgICAgIHZhciBjbG9zZSA9IC0xO1xuXG4gICAgICAgIC8vIGJhbGFuY2UgbmVzdGVkICdbJyBhbmQgJ10nIGluc2lkZSB0aGlzIGJyYWNrZXQgZ3JvdXAgdXNpbmcgYSBuZXN0aW5nIGxldmVsIGNvdW50ZXJcbiAgICAgICAgd2hpbGUgKGkgPCBuICYmIGNsb3NlIDwgMCkge1xuICAgICAgICAgICAgdmFyIGN1ID0ga2V5LmNoYXJDb2RlQXQoaSk7XG4gICAgICAgICAgICBpZiAoY3UgPT09IDB4NUIpIHsgLy8gJ1snXG4gICAgICAgICAgICAgICAgbGV2ZWwgKz0gMTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoY3UgPT09IDB4NUQpIHsgLy8gJ10nXG4gICAgICAgICAgICAgICAgbGV2ZWwgLT0gMTtcbiAgICAgICAgICAgICAgICBpZiAobGV2ZWwgPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgY2xvc2UgPSBpOyAvLyBmb3VuZCBtYXRjaGluZyBjbG9zZTsgbG9vcCB3aWxsIGV4aXQgYnkgY29uZGl0aW9uXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaSArPSAxO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGNsb3NlIDwgMCkge1xuICAgICAgICAgICAgLy8gVW50ZXJtaW5hdGVkIGdyb3VwOiB3cmFwIHRoZSByYXcgcmVtYWluZGVyIGluIG9uZSBicmFja2V0IHBhaXIgc28gaXQgc3RheXNcbiAgICAgICAgICAgIC8vIGEgc2luZ2xlIGxpdGVyYWwgc2VnbWVudCAoZS5nLiBcIltbXWJcIiAtPiBcIltbXWJdXCIpOyB3ZSBkbyBub3QgaW5mZXIgbWlzc2luZyAnXScuXG4gICAgICAgICAgICBzZWdtZW50c1tzZWdtZW50cy5sZW5ndGhdID0gJ1snICsga2V5LnNsaWNlKG9wZW4pICsgJ10nO1xuICAgICAgICAgICAgcmV0dXJuIHNlZ21lbnRzO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHNlZyA9IGtleS5zbGljZShvcGVuLCBjbG9zZSArIDEpO1xuICAgICAgICAvLyBwcm90b3R5cGUgZ3VhcmQgZm9yIHRoZSBjb250ZW50IG9mIHRoaXMgZ3JvdXBcbiAgICAgICAgdmFyIGNvbnRlbnQgPSBzZWcuc2xpY2UoMSwgLTEpO1xuICAgICAgICBpZiAoIW9wdGlvbnMucGxhaW5PYmplY3RzICYmIGhhcy5jYWxsKE9iamVjdC5wcm90b3R5cGUsIGNvbnRlbnQpICYmICFvcHRpb25zLmFsbG93UHJvdG90eXBlcykge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgc2VnbWVudHNbc2VnbWVudHMubGVuZ3RoXSA9IHNlZztcbiAgICAgICAgY29sbGVjdGVkICs9IDE7XG5cbiAgICAgICAgLy8gZmluZCB0aGUgbmV4dCAnWycgYWZ0ZXIgdGhpcyBiYWxhbmNlZCBncm91cFxuICAgICAgICBvcGVuID0ga2V5LmluZGV4T2YoJ1snLCBjbG9zZSArIDEpO1xuICAgIH1cblxuICAgIGlmIChvcGVuID49IDApIHtcbiAgICAgICAgaWYgKG9wdGlvbnMuc3RyaWN0RGVwdGggPT09IHRydWUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdJbnB1dCBkZXB0aCBleGNlZWRlZCBkZXB0aCBvcHRpb24gb2YgJyArIG9wdGlvbnMuZGVwdGggKyAnIGFuZCBzdHJpY3REZXB0aCBpcyB0cnVlJyk7XG4gICAgICAgIH1cblxuICAgICAgICBzZWdtZW50c1tzZWdtZW50cy5sZW5ndGhdID0gJ1snICsga2V5LnNsaWNlKG9wZW4pICsgJ10nO1xuICAgIH1cblxuICAgIHJldHVybiBzZWdtZW50cztcbn07XG5cbnZhciBwYXJzZUtleXMgPSBmdW5jdGlvbiBwYXJzZVF1ZXJ5U3RyaW5nS2V5cyhnaXZlbktleSwgdmFsLCBvcHRpb25zLCB2YWx1ZXNQYXJzZWQpIHtcbiAgICBpZiAoIWdpdmVuS2V5KSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIga2V5cyA9IHNwbGl0S2V5SW50b1NlZ21lbnRzKGdpdmVuS2V5LCBvcHRpb25zKTtcblxuICAgIGlmICgha2V5cykge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgcmV0dXJuIHBhcnNlT2JqZWN0KGtleXMsIHZhbCwgb3B0aW9ucywgdmFsdWVzUGFyc2VkKTtcbn07XG5cbnZhciBub3JtYWxpemVQYXJzZU9wdGlvbnMgPSBmdW5jdGlvbiBub3JtYWxpemVQYXJzZU9wdGlvbnMob3B0cykge1xuICAgIGlmICghb3B0cykge1xuICAgICAgICByZXR1cm4gZGVmYXVsdHM7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBvcHRzLmFsbG93RW1wdHlBcnJheXMgIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiBvcHRzLmFsbG93RW1wdHlBcnJheXMgIT09ICdib29sZWFuJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdgYWxsb3dFbXB0eUFycmF5c2Agb3B0aW9uIGNhbiBvbmx5IGJlIGB0cnVlYCBvciBgZmFsc2VgLCB3aGVuIHByb3ZpZGVkJyk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBvcHRzLmRlY29kZURvdEluS2V5cyAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIG9wdHMuZGVjb2RlRG90SW5LZXlzICE9PSAnYm9vbGVhbicpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignYGRlY29kZURvdEluS2V5c2Agb3B0aW9uIGNhbiBvbmx5IGJlIGB0cnVlYCBvciBgZmFsc2VgLCB3aGVuIHByb3ZpZGVkJyk7XG4gICAgfVxuXG4gICAgaWYgKG9wdHMuZGVjb2RlciAhPT0gbnVsbCAmJiB0eXBlb2Ygb3B0cy5kZWNvZGVyICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2Ygb3B0cy5kZWNvZGVyICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0RlY29kZXIgaGFzIHRvIGJlIGEgZnVuY3Rpb24uJyk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBvcHRzLmNoYXJzZXQgIT09ICd1bmRlZmluZWQnICYmIG9wdHMuY2hhcnNldCAhPT0gJ3V0Zi04JyAmJiBvcHRzLmNoYXJzZXQgIT09ICdpc28tODg1OS0xJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgY2hhcnNldCBvcHRpb24gbXVzdCBiZSBlaXRoZXIgdXRmLTgsIGlzby04ODU5LTEsIG9yIHVuZGVmaW5lZCcpO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2Ygb3B0cy50aHJvd09uTGltaXRFeGNlZWRlZCAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIG9wdHMudGhyb3dPbkxpbWl0RXhjZWVkZWQgIT09ICdib29sZWFuJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdgdGhyb3dPbkxpbWl0RXhjZWVkZWRgIG9wdGlvbiBtdXN0IGJlIGEgYm9vbGVhbicpO1xuICAgIH1cblxuICAgIHZhciBjaGFyc2V0ID0gdHlwZW9mIG9wdHMuY2hhcnNldCA9PT0gJ3VuZGVmaW5lZCcgPyBkZWZhdWx0cy5jaGFyc2V0IDogb3B0cy5jaGFyc2V0O1xuXG4gICAgdmFyIGR1cGxpY2F0ZXMgPSB0eXBlb2Ygb3B0cy5kdXBsaWNhdGVzID09PSAndW5kZWZpbmVkJyA/IGRlZmF1bHRzLmR1cGxpY2F0ZXMgOiBvcHRzLmR1cGxpY2F0ZXM7XG5cbiAgICBpZiAoZHVwbGljYXRlcyAhPT0gJ2NvbWJpbmUnICYmIGR1cGxpY2F0ZXMgIT09ICdmaXJzdCcgJiYgZHVwbGljYXRlcyAhPT0gJ2xhc3QnKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBkdXBsaWNhdGVzIG9wdGlvbiBtdXN0IGJlIGVpdGhlciBjb21iaW5lLCBmaXJzdCwgb3IgbGFzdCcpO1xuICAgIH1cblxuICAgIHZhciBhbGxvd0RvdHMgPSB0eXBlb2Ygb3B0cy5hbGxvd0RvdHMgPT09ICd1bmRlZmluZWQnID8gb3B0cy5kZWNvZGVEb3RJbktleXMgPT09IHRydWUgPyB0cnVlIDogZGVmYXVsdHMuYWxsb3dEb3RzIDogISFvcHRzLmFsbG93RG90cztcblxuICAgIHJldHVybiB7XG4gICAgICAgIGFsbG93RG90czogYWxsb3dEb3RzLFxuICAgICAgICBhbGxvd0VtcHR5QXJyYXlzOiB0eXBlb2Ygb3B0cy5hbGxvd0VtcHR5QXJyYXlzID09PSAnYm9vbGVhbicgPyAhIW9wdHMuYWxsb3dFbXB0eUFycmF5cyA6IGRlZmF1bHRzLmFsbG93RW1wdHlBcnJheXMsXG4gICAgICAgIGFsbG93UHJvdG90eXBlczogdHlwZW9mIG9wdHMuYWxsb3dQcm90b3R5cGVzID09PSAnYm9vbGVhbicgPyBvcHRzLmFsbG93UHJvdG90eXBlcyA6IGRlZmF1bHRzLmFsbG93UHJvdG90eXBlcyxcbiAgICAgICAgYWxsb3dTcGFyc2U6IHR5cGVvZiBvcHRzLmFsbG93U3BhcnNlID09PSAnYm9vbGVhbicgPyBvcHRzLmFsbG93U3BhcnNlIDogZGVmYXVsdHMuYWxsb3dTcGFyc2UsXG4gICAgICAgIGFycmF5TGltaXQ6IHR5cGVvZiBvcHRzLmFycmF5TGltaXQgPT09ICdudW1iZXInID8gb3B0cy5hcnJheUxpbWl0IDogZGVmYXVsdHMuYXJyYXlMaW1pdCxcbiAgICAgICAgY2hhcnNldDogY2hhcnNldCxcbiAgICAgICAgY2hhcnNldFNlbnRpbmVsOiB0eXBlb2Ygb3B0cy5jaGFyc2V0U2VudGluZWwgPT09ICdib29sZWFuJyA/IG9wdHMuY2hhcnNldFNlbnRpbmVsIDogZGVmYXVsdHMuY2hhcnNldFNlbnRpbmVsLFxuICAgICAgICBjb21tYTogdHlwZW9mIG9wdHMuY29tbWEgPT09ICdib29sZWFuJyA/IG9wdHMuY29tbWEgOiBkZWZhdWx0cy5jb21tYSxcbiAgICAgICAgZGVjb2RlRG90SW5LZXlzOiB0eXBlb2Ygb3B0cy5kZWNvZGVEb3RJbktleXMgPT09ICdib29sZWFuJyA/IG9wdHMuZGVjb2RlRG90SW5LZXlzIDogZGVmYXVsdHMuZGVjb2RlRG90SW5LZXlzLFxuICAgICAgICBkZWNvZGVyOiB0eXBlb2Ygb3B0cy5kZWNvZGVyID09PSAnZnVuY3Rpb24nID8gb3B0cy5kZWNvZGVyIDogZGVmYXVsdHMuZGVjb2RlcixcbiAgICAgICAgZGVsaW1pdGVyOiB0eXBlb2Ygb3B0cy5kZWxpbWl0ZXIgPT09ICdzdHJpbmcnIHx8IHV0aWxzLmlzUmVnRXhwKG9wdHMuZGVsaW1pdGVyKSA/IG9wdHMuZGVsaW1pdGVyIDogZGVmYXVsdHMuZGVsaW1pdGVyLFxuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8taW1wbGljaXQtY29lcmNpb24sIG5vLWV4dHJhLXBhcmVuc1xuICAgICAgICBkZXB0aDogKHR5cGVvZiBvcHRzLmRlcHRoID09PSAnbnVtYmVyJyB8fCBvcHRzLmRlcHRoID09PSBmYWxzZSkgPyArb3B0cy5kZXB0aCA6IGRlZmF1bHRzLmRlcHRoLFxuICAgICAgICBkdXBsaWNhdGVzOiBkdXBsaWNhdGVzLFxuICAgICAgICBpZ25vcmVRdWVyeVByZWZpeDogb3B0cy5pZ25vcmVRdWVyeVByZWZpeCA9PT0gdHJ1ZSxcbiAgICAgICAgaW50ZXJwcmV0TnVtZXJpY0VudGl0aWVzOiB0eXBlb2Ygb3B0cy5pbnRlcnByZXROdW1lcmljRW50aXRpZXMgPT09ICdib29sZWFuJyA/IG9wdHMuaW50ZXJwcmV0TnVtZXJpY0VudGl0aWVzIDogZGVmYXVsdHMuaW50ZXJwcmV0TnVtZXJpY0VudGl0aWVzLFxuICAgICAgICBwYXJhbWV0ZXJMaW1pdDogdHlwZW9mIG9wdHMucGFyYW1ldGVyTGltaXQgPT09ICdudW1iZXInID8gb3B0cy5wYXJhbWV0ZXJMaW1pdCA6IGRlZmF1bHRzLnBhcmFtZXRlckxpbWl0LFxuICAgICAgICBwYXJzZUFycmF5czogb3B0cy5wYXJzZUFycmF5cyAhPT0gZmFsc2UsXG4gICAgICAgIHBsYWluT2JqZWN0czogdHlwZW9mIG9wdHMucGxhaW5PYmplY3RzID09PSAnYm9vbGVhbicgPyBvcHRzLnBsYWluT2JqZWN0cyA6IGRlZmF1bHRzLnBsYWluT2JqZWN0cyxcbiAgICAgICAgc3RyaWN0RGVwdGg6IHR5cGVvZiBvcHRzLnN0cmljdERlcHRoID09PSAnYm9vbGVhbicgPyAhIW9wdHMuc3RyaWN0RGVwdGggOiBkZWZhdWx0cy5zdHJpY3REZXB0aCxcbiAgICAgICAgc3RyaWN0TWVyZ2U6IHR5cGVvZiBvcHRzLnN0cmljdE1lcmdlID09PSAnYm9vbGVhbicgPyAhIW9wdHMuc3RyaWN0TWVyZ2UgOiBkZWZhdWx0cy5zdHJpY3RNZXJnZSxcbiAgICAgICAgc3RyaWN0TnVsbEhhbmRsaW5nOiB0eXBlb2Ygb3B0cy5zdHJpY3ROdWxsSGFuZGxpbmcgPT09ICdib29sZWFuJyA/IG9wdHMuc3RyaWN0TnVsbEhhbmRsaW5nIDogZGVmYXVsdHMuc3RyaWN0TnVsbEhhbmRsaW5nLFxuICAgICAgICB0aHJvd09uTGltaXRFeGNlZWRlZDogdHlwZW9mIG9wdHMudGhyb3dPbkxpbWl0RXhjZWVkZWQgPT09ICdib29sZWFuJyA/IG9wdHMudGhyb3dPbkxpbWl0RXhjZWVkZWQgOiBmYWxzZVxuICAgIH07XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChzdHIsIG9wdHMpIHtcbiAgICB2YXIgb3B0aW9ucyA9IG5vcm1hbGl6ZVBhcnNlT3B0aW9ucyhvcHRzKTtcblxuICAgIGlmIChzdHIgPT09ICcnIHx8IHN0ciA9PT0gbnVsbCB8fCB0eXBlb2Ygc3RyID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICByZXR1cm4gb3B0aW9ucy5wbGFpbk9iamVjdHMgPyB7IF9fcHJvdG9fXzogbnVsbCB9IDoge307XG4gICAgfVxuXG4gICAgdmFyIHRlbXBPYmogPSB0eXBlb2Ygc3RyID09PSAnc3RyaW5nJyA/IHBhcnNlVmFsdWVzKHN0ciwgb3B0aW9ucykgOiBzdHI7XG4gICAgdmFyIG9iaiA9IG9wdGlvbnMucGxhaW5PYmplY3RzID8geyBfX3Byb3RvX186IG51bGwgfSA6IHt9O1xuXG4gICAgLy8gSXRlcmF0ZSBvdmVyIHRoZSBrZXlzIGFuZCBzZXR1cCB0aGUgbmV3IG9iamVjdFxuXG4gICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyh0ZW1wT2JqKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgdmFyIGtleSA9IGtleXNbaV07XG4gICAgICAgIHZhciBuZXdPYmogPSBwYXJzZUtleXMoa2V5LCB0ZW1wT2JqW2tleV0sIG9wdGlvbnMsIHR5cGVvZiBzdHIgPT09ICdzdHJpbmcnKTtcbiAgICAgICAgb2JqID0gdXRpbHMubWVyZ2Uob2JqLCBuZXdPYmosIG9wdGlvbnMpO1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zLmFsbG93U3BhcnNlID09PSB0cnVlKSB7XG4gICAgICAgIHJldHVybiBvYmo7XG4gICAgfVxuXG4gICAgcmV0dXJuIHV0aWxzLmNvbXBhY3Qob2JqKTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBnZXRTaWRlQ2hhbm5lbCA9IHJlcXVpcmUoJ3NpZGUtY2hhbm5lbCcpO1xudmFyIHV0aWxzID0gcmVxdWlyZSgnLi91dGlscycpO1xudmFyIGZvcm1hdHMgPSByZXF1aXJlKCcuL2Zvcm1hdHMnKTtcbnZhciBoYXMgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuXG52YXIgYXJyYXlQcmVmaXhHZW5lcmF0b3JzID0ge1xuICAgIGJyYWNrZXRzOiBmdW5jdGlvbiBicmFja2V0cyhwcmVmaXgpIHtcbiAgICAgICAgcmV0dXJuIHByZWZpeCArICdbXSc7XG4gICAgfSxcbiAgICBjb21tYTogJ2NvbW1hJyxcbiAgICBpbmRpY2VzOiBmdW5jdGlvbiBpbmRpY2VzKHByZWZpeCwga2V5KSB7XG4gICAgICAgIHJldHVybiBwcmVmaXggKyAnWycgKyBrZXkgKyAnXSc7XG4gICAgfSxcbiAgICByZXBlYXQ6IGZ1bmN0aW9uIHJlcGVhdChwcmVmaXgpIHtcbiAgICAgICAgcmV0dXJuIHByZWZpeDtcbiAgICB9XG59O1xuXG52YXIgaXNBcnJheSA9IEFycmF5LmlzQXJyYXk7XG52YXIgcHVzaCA9IEFycmF5LnByb3RvdHlwZS5wdXNoO1xudmFyIHB1c2hUb0FycmF5ID0gZnVuY3Rpb24gKGFyciwgdmFsdWVPckFycmF5KSB7XG4gICAgcHVzaC5hcHBseShhcnIsIGlzQXJyYXkodmFsdWVPckFycmF5KSA/IHZhbHVlT3JBcnJheSA6IFt2YWx1ZU9yQXJyYXldKTtcbn07XG5cbnZhciB0b0lTTyA9IERhdGUucHJvdG90eXBlLnRvSVNPU3RyaW5nO1xuXG52YXIgZGVmYXVsdEZvcm1hdCA9IGZvcm1hdHNbJ2RlZmF1bHQnXTtcbnZhciBkZWZhdWx0cyA9IHtcbiAgICBhZGRRdWVyeVByZWZpeDogZmFsc2UsXG4gICAgYWxsb3dEb3RzOiBmYWxzZSxcbiAgICBhbGxvd0VtcHR5QXJyYXlzOiBmYWxzZSxcbiAgICBhcnJheUZvcm1hdDogJ2luZGljZXMnLFxuICAgIGNoYXJzZXQ6ICd1dGYtOCcsXG4gICAgY2hhcnNldFNlbnRpbmVsOiBmYWxzZSxcbiAgICBjb21tYVJvdW5kVHJpcDogZmFsc2UsXG4gICAgZGVsaW1pdGVyOiAnJicsXG4gICAgZW5jb2RlOiB0cnVlLFxuICAgIGVuY29kZURvdEluS2V5czogZmFsc2UsXG4gICAgZW5jb2RlcjogdXRpbHMuZW5jb2RlLFxuICAgIGVuY29kZVZhbHVlc09ubHk6IGZhbHNlLFxuICAgIGZpbHRlcjogdm9pZCB1bmRlZmluZWQsXG4gICAgZm9ybWF0OiBkZWZhdWx0Rm9ybWF0LFxuICAgIGZvcm1hdHRlcjogZm9ybWF0cy5mb3JtYXR0ZXJzW2RlZmF1bHRGb3JtYXRdLFxuICAgIC8vIGRlcHJlY2F0ZWRcbiAgICBpbmRpY2VzOiBmYWxzZSxcbiAgICBzZXJpYWxpemVEYXRlOiBmdW5jdGlvbiBzZXJpYWxpemVEYXRlKGRhdGUpIHtcbiAgICAgICAgcmV0dXJuIHRvSVNPLmNhbGwoZGF0ZSk7XG4gICAgfSxcbiAgICBza2lwTnVsbHM6IGZhbHNlLFxuICAgIHN0cmljdE51bGxIYW5kbGluZzogZmFsc2Vcbn07XG5cbnZhciBpc05vbk51bGxpc2hQcmltaXRpdmUgPSBmdW5jdGlvbiBpc05vbk51bGxpc2hQcmltaXRpdmUodikge1xuICAgIHJldHVybiB0eXBlb2YgdiA9PT0gJ3N0cmluZydcbiAgICAgICAgfHwgdHlwZW9mIHYgPT09ICdudW1iZXInXG4gICAgICAgIHx8IHR5cGVvZiB2ID09PSAnYm9vbGVhbidcbiAgICAgICAgfHwgdHlwZW9mIHYgPT09ICdzeW1ib2wnXG4gICAgICAgIHx8IHR5cGVvZiB2ID09PSAnYmlnaW50Jztcbn07XG5cbnZhciBzZW50aW5lbCA9IHt9O1xuXG52YXIgc3RyaW5naWZ5ID0gZnVuY3Rpb24gc3RyaW5naWZ5KFxuICAgIG9iamVjdCxcbiAgICBwcmVmaXgsXG4gICAgZ2VuZXJhdGVBcnJheVByZWZpeCxcbiAgICBjb21tYVJvdW5kVHJpcCxcbiAgICBhbGxvd0VtcHR5QXJyYXlzLFxuICAgIHN0cmljdE51bGxIYW5kbGluZyxcbiAgICBza2lwTnVsbHMsXG4gICAgZW5jb2RlRG90SW5LZXlzLFxuICAgIGVuY29kZXIsXG4gICAgZmlsdGVyLFxuICAgIHNvcnQsXG4gICAgYWxsb3dEb3RzLFxuICAgIHNlcmlhbGl6ZURhdGUsXG4gICAgZm9ybWF0LFxuICAgIGZvcm1hdHRlcixcbiAgICBlbmNvZGVWYWx1ZXNPbmx5LFxuICAgIGNoYXJzZXQsXG4gICAgc2lkZUNoYW5uZWxcbikge1xuICAgIHZhciBvYmogPSBvYmplY3Q7XG5cbiAgICB2YXIgdG1wU2MgPSBzaWRlQ2hhbm5lbDtcbiAgICB2YXIgc3RlcCA9IDA7XG4gICAgdmFyIGZpbmRGbGFnID0gZmFsc2U7XG4gICAgd2hpbGUgKCh0bXBTYyA9IHRtcFNjLmdldChzZW50aW5lbCkpICE9PSB2b2lkIHVuZGVmaW5lZCAmJiAhZmluZEZsYWcpIHtcbiAgICAgICAgLy8gV2hlcmUgb2JqZWN0IGxhc3QgYXBwZWFyZWQgaW4gdGhlIHJlZiB0cmVlXG4gICAgICAgIHZhciBwb3MgPSB0bXBTYy5nZXQob2JqZWN0KTtcbiAgICAgICAgc3RlcCArPSAxO1xuICAgICAgICBpZiAodHlwZW9mIHBvcyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIGlmIChwb3MgPT09IHN0ZXApIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignQ3ljbGljIG9iamVjdCB2YWx1ZScpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBmaW5kRmxhZyA9IHRydWU7IC8vIEJyZWFrIHdoaWxlXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiB0bXBTYy5nZXQoc2VudGluZWwpID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgc3RlcCA9IDA7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGZpbHRlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBvYmogPSBmaWx0ZXIocHJlZml4LCBvYmopO1xuICAgIH0gZWxzZSBpZiAob2JqIGluc3RhbmNlb2YgRGF0ZSkge1xuICAgICAgICBvYmogPSBzZXJpYWxpemVEYXRlKG9iaik7XG4gICAgfSBlbHNlIGlmIChnZW5lcmF0ZUFycmF5UHJlZml4ID09PSAnY29tbWEnICYmIGlzQXJyYXkob2JqKSkge1xuICAgICAgICBvYmogPSB1dGlscy5tYXliZU1hcChvYmosIGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgRGF0ZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBzZXJpYWxpemVEYXRlKHZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKG9iaiA9PT0gbnVsbCkge1xuICAgICAgICBpZiAoc3RyaWN0TnVsbEhhbmRsaW5nKSB7XG4gICAgICAgICAgICByZXR1cm4gZm9ybWF0dGVyKGVuY29kZXIgJiYgIWVuY29kZVZhbHVlc09ubHkgPyBlbmNvZGVyKHByZWZpeCwgZGVmYXVsdHMuZW5jb2RlciwgY2hhcnNldCwgJ2tleScsIGZvcm1hdCkgOiBwcmVmaXgpO1xuICAgICAgICB9XG5cbiAgICAgICAgb2JqID0gJyc7XG4gICAgfVxuXG4gICAgaWYgKGlzTm9uTnVsbGlzaFByaW1pdGl2ZShvYmopIHx8IHV0aWxzLmlzQnVmZmVyKG9iaikpIHtcbiAgICAgICAgaWYgKGVuY29kZXIpIHtcbiAgICAgICAgICAgIHZhciBrZXlWYWx1ZSA9IGVuY29kZVZhbHVlc09ubHkgPyBwcmVmaXggOiBlbmNvZGVyKHByZWZpeCwgZGVmYXVsdHMuZW5jb2RlciwgY2hhcnNldCwgJ2tleScsIGZvcm1hdCk7XG4gICAgICAgICAgICByZXR1cm4gW2Zvcm1hdHRlcihrZXlWYWx1ZSkgKyAnPScgKyBmb3JtYXR0ZXIoZW5jb2RlcihvYmosIGRlZmF1bHRzLmVuY29kZXIsIGNoYXJzZXQsICd2YWx1ZScsIGZvcm1hdCkpXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gW2Zvcm1hdHRlcihwcmVmaXgpICsgJz0nICsgZm9ybWF0dGVyKFN0cmluZyhvYmopKV07XG4gICAgfVxuXG4gICAgdmFyIHZhbHVlcyA9IFtdO1xuXG4gICAgaWYgKHR5cGVvZiBvYmogPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZXM7XG4gICAgfVxuXG4gICAgdmFyIG9iaktleXM7XG4gICAgaWYgKGdlbmVyYXRlQXJyYXlQcmVmaXggPT09ICdjb21tYScgJiYgaXNBcnJheShvYmopKSB7XG4gICAgICAgIC8vIHdlIG5lZWQgdG8gam9pbiBlbGVtZW50cyBpblxuICAgICAgICBpZiAoZW5jb2RlVmFsdWVzT25seSAmJiBlbmNvZGVyKSB7XG4gICAgICAgICAgICBvYmogPSB1dGlscy5tYXliZU1hcChvYmosIGZ1bmN0aW9uICh2KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHYgPT0gbnVsbCA/IHYgOiBlbmNvZGVyKHYpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgb2JqS2V5cyA9IFt7IHZhbHVlOiBvYmoubGVuZ3RoID4gMCA/IG9iai5qb2luKCcsJykgfHwgbnVsbCA6IHZvaWQgdW5kZWZpbmVkIH1dO1xuICAgIH0gZWxzZSBpZiAoaXNBcnJheShmaWx0ZXIpKSB7XG4gICAgICAgIG9iaktleXMgPSBmaWx0ZXI7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhvYmopO1xuICAgICAgICBvYmpLZXlzID0gc29ydCA/IGtleXMuc29ydChzb3J0KSA6IGtleXM7XG4gICAgfVxuXG4gICAgdmFyIGVuY29kZWRQcmVmaXggPSBlbmNvZGVEb3RJbktleXMgPyBTdHJpbmcocHJlZml4KS5yZXBsYWNlKC9cXC4vZywgJyUyRScpIDogU3RyaW5nKHByZWZpeCk7XG5cbiAgICB2YXIgYWRqdXN0ZWRQcmVmaXggPSBjb21tYVJvdW5kVHJpcCAmJiBpc0FycmF5KG9iaikgJiYgb2JqLmxlbmd0aCA9PT0gMSA/IGVuY29kZWRQcmVmaXggKyAnW10nIDogZW5jb2RlZFByZWZpeDtcblxuICAgIGlmIChhbGxvd0VtcHR5QXJyYXlzICYmIGlzQXJyYXkob2JqKSAmJiBvYmoubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJldHVybiBhZGp1c3RlZFByZWZpeCArICdbXSc7XG4gICAgfVxuXG4gICAgZm9yICh2YXIgaiA9IDA7IGogPCBvYmpLZXlzLmxlbmd0aDsgKytqKSB7XG4gICAgICAgIHZhciBrZXkgPSBvYmpLZXlzW2pdO1xuICAgICAgICB2YXIgdmFsdWUgPSB0eXBlb2Yga2V5ID09PSAnb2JqZWN0JyAmJiBrZXkgJiYgdHlwZW9mIGtleS52YWx1ZSAhPT0gJ3VuZGVmaW5lZCdcbiAgICAgICAgICAgID8ga2V5LnZhbHVlXG4gICAgICAgICAgICA6IG9ialtrZXldO1xuXG4gICAgICAgIGlmIChza2lwTnVsbHMgJiYgdmFsdWUgPT09IG51bGwpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGVuY29kZWRLZXkgPSBhbGxvd0RvdHMgJiYgZW5jb2RlRG90SW5LZXlzID8gU3RyaW5nKGtleSkucmVwbGFjZSgvXFwuL2csICclMkUnKSA6IFN0cmluZyhrZXkpO1xuICAgICAgICB2YXIga2V5UHJlZml4ID0gaXNBcnJheShvYmopXG4gICAgICAgICAgICA/IHR5cGVvZiBnZW5lcmF0ZUFycmF5UHJlZml4ID09PSAnZnVuY3Rpb24nID8gZ2VuZXJhdGVBcnJheVByZWZpeChhZGp1c3RlZFByZWZpeCwgZW5jb2RlZEtleSkgOiBhZGp1c3RlZFByZWZpeFxuICAgICAgICAgICAgOiBhZGp1c3RlZFByZWZpeCArIChhbGxvd0RvdHMgPyAnLicgKyBlbmNvZGVkS2V5IDogJ1snICsgZW5jb2RlZEtleSArICddJyk7XG5cbiAgICAgICAgc2lkZUNoYW5uZWwuc2V0KG9iamVjdCwgc3RlcCk7XG4gICAgICAgIHZhciB2YWx1ZVNpZGVDaGFubmVsID0gZ2V0U2lkZUNoYW5uZWwoKTtcbiAgICAgICAgdmFsdWVTaWRlQ2hhbm5lbC5zZXQoc2VudGluZWwsIHNpZGVDaGFubmVsKTtcbiAgICAgICAgcHVzaFRvQXJyYXkodmFsdWVzLCBzdHJpbmdpZnkoXG4gICAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICAgIGtleVByZWZpeCxcbiAgICAgICAgICAgIGdlbmVyYXRlQXJyYXlQcmVmaXgsXG4gICAgICAgICAgICBjb21tYVJvdW5kVHJpcCxcbiAgICAgICAgICAgIGFsbG93RW1wdHlBcnJheXMsXG4gICAgICAgICAgICBzdHJpY3ROdWxsSGFuZGxpbmcsXG4gICAgICAgICAgICBza2lwTnVsbHMsXG4gICAgICAgICAgICBlbmNvZGVEb3RJbktleXMsXG4gICAgICAgICAgICBnZW5lcmF0ZUFycmF5UHJlZml4ID09PSAnY29tbWEnICYmIGVuY29kZVZhbHVlc09ubHkgJiYgaXNBcnJheShvYmopID8gbnVsbCA6IGVuY29kZXIsXG4gICAgICAgICAgICBmaWx0ZXIsXG4gICAgICAgICAgICBzb3J0LFxuICAgICAgICAgICAgYWxsb3dEb3RzLFxuICAgICAgICAgICAgc2VyaWFsaXplRGF0ZSxcbiAgICAgICAgICAgIGZvcm1hdCxcbiAgICAgICAgICAgIGZvcm1hdHRlcixcbiAgICAgICAgICAgIGVuY29kZVZhbHVlc09ubHksXG4gICAgICAgICAgICBjaGFyc2V0LFxuICAgICAgICAgICAgdmFsdWVTaWRlQ2hhbm5lbFxuICAgICAgICApKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdmFsdWVzO1xufTtcblxudmFyIG5vcm1hbGl6ZVN0cmluZ2lmeU9wdGlvbnMgPSBmdW5jdGlvbiBub3JtYWxpemVTdHJpbmdpZnlPcHRpb25zKG9wdHMpIHtcbiAgICBpZiAoIW9wdHMpIHtcbiAgICAgICAgcmV0dXJuIGRlZmF1bHRzO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2Ygb3B0cy5hbGxvd0VtcHR5QXJyYXlzICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2Ygb3B0cy5hbGxvd0VtcHR5QXJyYXlzICE9PSAnYm9vbGVhbicpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignYGFsbG93RW1wdHlBcnJheXNgIG9wdGlvbiBjYW4gb25seSBiZSBgdHJ1ZWAgb3IgYGZhbHNlYCwgd2hlbiBwcm92aWRlZCcpO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2Ygb3B0cy5lbmNvZGVEb3RJbktleXMgIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiBvcHRzLmVuY29kZURvdEluS2V5cyAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2BlbmNvZGVEb3RJbktleXNgIG9wdGlvbiBjYW4gb25seSBiZSBgdHJ1ZWAgb3IgYGZhbHNlYCwgd2hlbiBwcm92aWRlZCcpO1xuICAgIH1cblxuICAgIGlmIChvcHRzLmVuY29kZXIgIT09IG51bGwgJiYgdHlwZW9mIG9wdHMuZW5jb2RlciAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIG9wdHMuZW5jb2RlciAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdFbmNvZGVyIGhhcyB0byBiZSBhIGZ1bmN0aW9uLicpO1xuICAgIH1cblxuICAgIHZhciBjaGFyc2V0ID0gb3B0cy5jaGFyc2V0IHx8IGRlZmF1bHRzLmNoYXJzZXQ7XG4gICAgaWYgKHR5cGVvZiBvcHRzLmNoYXJzZXQgIT09ICd1bmRlZmluZWQnICYmIG9wdHMuY2hhcnNldCAhPT0gJ3V0Zi04JyAmJiBvcHRzLmNoYXJzZXQgIT09ICdpc28tODg1OS0xJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgY2hhcnNldCBvcHRpb24gbXVzdCBiZSBlaXRoZXIgdXRmLTgsIGlzby04ODU5LTEsIG9yIHVuZGVmaW5lZCcpO1xuICAgIH1cblxuICAgIHZhciBmb3JtYXQgPSBmb3JtYXRzWydkZWZhdWx0J107XG4gICAgaWYgKHR5cGVvZiBvcHRzLmZvcm1hdCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgaWYgKCFoYXMuY2FsbChmb3JtYXRzLmZvcm1hdHRlcnMsIG9wdHMuZm9ybWF0KSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVW5rbm93biBmb3JtYXQgb3B0aW9uIHByb3ZpZGVkLicpO1xuICAgICAgICB9XG4gICAgICAgIGZvcm1hdCA9IG9wdHMuZm9ybWF0O1xuICAgIH1cbiAgICB2YXIgZm9ybWF0dGVyID0gZm9ybWF0cy5mb3JtYXR0ZXJzW2Zvcm1hdF07XG5cbiAgICB2YXIgZmlsdGVyID0gZGVmYXVsdHMuZmlsdGVyO1xuICAgIGlmICh0eXBlb2Ygb3B0cy5maWx0ZXIgPT09ICdmdW5jdGlvbicgfHwgaXNBcnJheShvcHRzLmZpbHRlcikpIHtcbiAgICAgICAgZmlsdGVyID0gb3B0cy5maWx0ZXI7XG4gICAgfVxuXG4gICAgdmFyIGFycmF5Rm9ybWF0O1xuICAgIGlmIChvcHRzLmFycmF5Rm9ybWF0IGluIGFycmF5UHJlZml4R2VuZXJhdG9ycykge1xuICAgICAgICBhcnJheUZvcm1hdCA9IG9wdHMuYXJyYXlGb3JtYXQ7XG4gICAgfSBlbHNlIGlmICgnaW5kaWNlcycgaW4gb3B0cykge1xuICAgICAgICBhcnJheUZvcm1hdCA9IG9wdHMuaW5kaWNlcyA/ICdpbmRpY2VzJyA6ICdyZXBlYXQnO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGFycmF5Rm9ybWF0ID0gZGVmYXVsdHMuYXJyYXlGb3JtYXQ7XG4gICAgfVxuXG4gICAgaWYgKCdjb21tYVJvdW5kVHJpcCcgaW4gb3B0cyAmJiB0eXBlb2Ygb3B0cy5jb21tYVJvdW5kVHJpcCAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2Bjb21tYVJvdW5kVHJpcGAgbXVzdCBiZSBhIGJvb2xlYW4sIG9yIGFic2VudCcpO1xuICAgIH1cblxuICAgIHZhciBhbGxvd0RvdHMgPSB0eXBlb2Ygb3B0cy5hbGxvd0RvdHMgPT09ICd1bmRlZmluZWQnID8gb3B0cy5lbmNvZGVEb3RJbktleXMgPT09IHRydWUgPyB0cnVlIDogZGVmYXVsdHMuYWxsb3dEb3RzIDogISFvcHRzLmFsbG93RG90cztcblxuICAgIHJldHVybiB7XG4gICAgICAgIGFkZFF1ZXJ5UHJlZml4OiB0eXBlb2Ygb3B0cy5hZGRRdWVyeVByZWZpeCA9PT0gJ2Jvb2xlYW4nID8gb3B0cy5hZGRRdWVyeVByZWZpeCA6IGRlZmF1bHRzLmFkZFF1ZXJ5UHJlZml4LFxuICAgICAgICBhbGxvd0RvdHM6IGFsbG93RG90cyxcbiAgICAgICAgYWxsb3dFbXB0eUFycmF5czogdHlwZW9mIG9wdHMuYWxsb3dFbXB0eUFycmF5cyA9PT0gJ2Jvb2xlYW4nID8gISFvcHRzLmFsbG93RW1wdHlBcnJheXMgOiBkZWZhdWx0cy5hbGxvd0VtcHR5QXJyYXlzLFxuICAgICAgICBhcnJheUZvcm1hdDogYXJyYXlGb3JtYXQsXG4gICAgICAgIGNoYXJzZXQ6IGNoYXJzZXQsXG4gICAgICAgIGNoYXJzZXRTZW50aW5lbDogdHlwZW9mIG9wdHMuY2hhcnNldFNlbnRpbmVsID09PSAnYm9vbGVhbicgPyBvcHRzLmNoYXJzZXRTZW50aW5lbCA6IGRlZmF1bHRzLmNoYXJzZXRTZW50aW5lbCxcbiAgICAgICAgY29tbWFSb3VuZFRyaXA6ICEhb3B0cy5jb21tYVJvdW5kVHJpcCxcbiAgICAgICAgZGVsaW1pdGVyOiB0eXBlb2Ygb3B0cy5kZWxpbWl0ZXIgPT09ICd1bmRlZmluZWQnID8gZGVmYXVsdHMuZGVsaW1pdGVyIDogb3B0cy5kZWxpbWl0ZXIsXG4gICAgICAgIGVuY29kZTogdHlwZW9mIG9wdHMuZW5jb2RlID09PSAnYm9vbGVhbicgPyBvcHRzLmVuY29kZSA6IGRlZmF1bHRzLmVuY29kZSxcbiAgICAgICAgZW5jb2RlRG90SW5LZXlzOiB0eXBlb2Ygb3B0cy5lbmNvZGVEb3RJbktleXMgPT09ICdib29sZWFuJyA/IG9wdHMuZW5jb2RlRG90SW5LZXlzIDogZGVmYXVsdHMuZW5jb2RlRG90SW5LZXlzLFxuICAgICAgICBlbmNvZGVyOiB0eXBlb2Ygb3B0cy5lbmNvZGVyID09PSAnZnVuY3Rpb24nID8gb3B0cy5lbmNvZGVyIDogZGVmYXVsdHMuZW5jb2RlcixcbiAgICAgICAgZW5jb2RlVmFsdWVzT25seTogdHlwZW9mIG9wdHMuZW5jb2RlVmFsdWVzT25seSA9PT0gJ2Jvb2xlYW4nID8gb3B0cy5lbmNvZGVWYWx1ZXNPbmx5IDogZGVmYXVsdHMuZW5jb2RlVmFsdWVzT25seSxcbiAgICAgICAgZmlsdGVyOiBmaWx0ZXIsXG4gICAgICAgIGZvcm1hdDogZm9ybWF0LFxuICAgICAgICBmb3JtYXR0ZXI6IGZvcm1hdHRlcixcbiAgICAgICAgc2VyaWFsaXplRGF0ZTogdHlwZW9mIG9wdHMuc2VyaWFsaXplRGF0ZSA9PT0gJ2Z1bmN0aW9uJyA/IG9wdHMuc2VyaWFsaXplRGF0ZSA6IGRlZmF1bHRzLnNlcmlhbGl6ZURhdGUsXG4gICAgICAgIHNraXBOdWxsczogdHlwZW9mIG9wdHMuc2tpcE51bGxzID09PSAnYm9vbGVhbicgPyBvcHRzLnNraXBOdWxscyA6IGRlZmF1bHRzLnNraXBOdWxscyxcbiAgICAgICAgc29ydDogdHlwZW9mIG9wdHMuc29ydCA9PT0gJ2Z1bmN0aW9uJyA/IG9wdHMuc29ydCA6IG51bGwsXG4gICAgICAgIHN0cmljdE51bGxIYW5kbGluZzogdHlwZW9mIG9wdHMuc3RyaWN0TnVsbEhhbmRsaW5nID09PSAnYm9vbGVhbicgPyBvcHRzLnN0cmljdE51bGxIYW5kbGluZyA6IGRlZmF1bHRzLnN0cmljdE51bGxIYW5kbGluZ1xuICAgIH07XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChvYmplY3QsIG9wdHMpIHtcbiAgICB2YXIgb2JqID0gb2JqZWN0O1xuICAgIHZhciBvcHRpb25zID0gbm9ybWFsaXplU3RyaW5naWZ5T3B0aW9ucyhvcHRzKTtcblxuICAgIHZhciBvYmpLZXlzO1xuICAgIHZhciBmaWx0ZXI7XG5cbiAgICBpZiAodHlwZW9mIG9wdGlvbnMuZmlsdGVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGZpbHRlciA9IG9wdGlvbnMuZmlsdGVyO1xuICAgICAgICBvYmogPSBmaWx0ZXIoJycsIG9iaik7XG4gICAgfSBlbHNlIGlmIChpc0FycmF5KG9wdGlvbnMuZmlsdGVyKSkge1xuICAgICAgICBmaWx0ZXIgPSBvcHRpb25zLmZpbHRlcjtcbiAgICAgICAgb2JqS2V5cyA9IGZpbHRlcjtcbiAgICB9XG5cbiAgICB2YXIga2V5cyA9IFtdO1xuXG4gICAgaWYgKHR5cGVvZiBvYmogIT09ICdvYmplY3QnIHx8IG9iaiA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gJyc7XG4gICAgfVxuXG4gICAgdmFyIGdlbmVyYXRlQXJyYXlQcmVmaXggPSBhcnJheVByZWZpeEdlbmVyYXRvcnNbb3B0aW9ucy5hcnJheUZvcm1hdF07XG4gICAgdmFyIGNvbW1hUm91bmRUcmlwID0gZ2VuZXJhdGVBcnJheVByZWZpeCA9PT0gJ2NvbW1hJyAmJiBvcHRpb25zLmNvbW1hUm91bmRUcmlwO1xuXG4gICAgaWYgKCFvYmpLZXlzKSB7XG4gICAgICAgIG9iaktleXMgPSBPYmplY3Qua2V5cyhvYmopO1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zLnNvcnQpIHtcbiAgICAgICAgb2JqS2V5cy5zb3J0KG9wdGlvbnMuc29ydCk7XG4gICAgfVxuXG4gICAgdmFyIHNpZGVDaGFubmVsID0gZ2V0U2lkZUNoYW5uZWwoKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iaktleXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgdmFyIGtleSA9IG9iaktleXNbaV07XG5cbiAgICAgICAgaWYgKHR5cGVvZiBrZXkgPT09ICd1bmRlZmluZWQnIHx8IGtleSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgdmFsdWUgPSBvYmpba2V5XTtcblxuICAgICAgICBpZiAob3B0aW9ucy5za2lwTnVsbHMgJiYgdmFsdWUgPT09IG51bGwpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIHB1c2hUb0FycmF5KGtleXMsIHN0cmluZ2lmeShcbiAgICAgICAgICAgIHZhbHVlLFxuICAgICAgICAgICAga2V5LFxuICAgICAgICAgICAgZ2VuZXJhdGVBcnJheVByZWZpeCxcbiAgICAgICAgICAgIGNvbW1hUm91bmRUcmlwLFxuICAgICAgICAgICAgb3B0aW9ucy5hbGxvd0VtcHR5QXJyYXlzLFxuICAgICAgICAgICAgb3B0aW9ucy5zdHJpY3ROdWxsSGFuZGxpbmcsXG4gICAgICAgICAgICBvcHRpb25zLnNraXBOdWxscyxcbiAgICAgICAgICAgIG9wdGlvbnMuZW5jb2RlRG90SW5LZXlzLFxuICAgICAgICAgICAgb3B0aW9ucy5lbmNvZGUgPyBvcHRpb25zLmVuY29kZXIgOiBudWxsLFxuICAgICAgICAgICAgb3B0aW9ucy5maWx0ZXIsXG4gICAgICAgICAgICBvcHRpb25zLnNvcnQsXG4gICAgICAgICAgICBvcHRpb25zLmFsbG93RG90cyxcbiAgICAgICAgICAgIG9wdGlvbnMuc2VyaWFsaXplRGF0ZSxcbiAgICAgICAgICAgIG9wdGlvbnMuZm9ybWF0LFxuICAgICAgICAgICAgb3B0aW9ucy5mb3JtYXR0ZXIsXG4gICAgICAgICAgICBvcHRpb25zLmVuY29kZVZhbHVlc09ubHksXG4gICAgICAgICAgICBvcHRpb25zLmNoYXJzZXQsXG4gICAgICAgICAgICBzaWRlQ2hhbm5lbFxuICAgICAgICApKTtcbiAgICB9XG5cbiAgICB2YXIgam9pbmVkID0ga2V5cy5qb2luKG9wdGlvbnMuZGVsaW1pdGVyKTtcbiAgICB2YXIgcHJlZml4ID0gb3B0aW9ucy5hZGRRdWVyeVByZWZpeCA9PT0gdHJ1ZSA/ICc/JyA6ICcnO1xuXG4gICAgaWYgKG9wdGlvbnMuY2hhcnNldFNlbnRpbmVsKSB7XG4gICAgICAgIGlmIChvcHRpb25zLmNoYXJzZXQgPT09ICdpc28tODg1OS0xJykge1xuICAgICAgICAgICAgLy8gZW5jb2RlVVJJQ29tcG9uZW50KCcmIzEwMDAzOycpLCB0aGUgXCJudW1lcmljIGVudGl0eVwiIHJlcHJlc2VudGF0aW9uIG9mIGEgY2hlY2ttYXJrXG4gICAgICAgICAgICBwcmVmaXggKz0gJ3V0Zjg9JTI2JTIzMTAwMDMlM0InICsgb3B0aW9ucy5kZWxpbWl0ZXI7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBlbmNvZGVVUklDb21wb25lbnQoJ+KckycpXG4gICAgICAgICAgICBwcmVmaXggKz0gJ3V0Zjg9JUUyJTlDJTkzJyArIG9wdGlvbnMuZGVsaW1pdGVyO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGpvaW5lZC5sZW5ndGggPiAwID8gcHJlZml4ICsgam9pbmVkIDogJyc7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgZm9ybWF0cyA9IHJlcXVpcmUoJy4vZm9ybWF0cycpO1xudmFyIGdldFNpZGVDaGFubmVsID0gcmVxdWlyZSgnc2lkZS1jaGFubmVsJyk7XG52YXIgZGVmaW5lUHJvcGVydHkgPSByZXF1aXJlKCdlcy1kZWZpbmUtcHJvcGVydHknKTtcblxudmFyIGhhcyA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG52YXIgaXNBcnJheSA9IEFycmF5LmlzQXJyYXk7XG5cbi8vIFRyYWNrIG9iamVjdHMgY3JlYXRlZCBmcm9tIGFycmF5TGltaXQgb3ZlcmZsb3cgdXNpbmcgc2lkZS1jaGFubmVsXG4vLyBTdG9yZXMgdGhlIGN1cnJlbnQgbWF4IG51bWVyaWMgaW5kZXggZm9yIE8oMSkgbG9va3VwXG52YXIgb3ZlcmZsb3dDaGFubmVsID0gZ2V0U2lkZUNoYW5uZWwoKTtcblxudmFyIG1hcmtPdmVyZmxvdyA9IGZ1bmN0aW9uIG1hcmtPdmVyZmxvdyhvYmosIG1heEluZGV4KSB7XG4gICAgb3ZlcmZsb3dDaGFubmVsLnNldChvYmosIG1heEluZGV4KTtcbiAgICByZXR1cm4gb2JqO1xufTtcblxudmFyIGlzT3ZlcmZsb3cgPSBmdW5jdGlvbiBpc092ZXJmbG93KG9iaikge1xuICAgIHJldHVybiBvdmVyZmxvd0NoYW5uZWwuaGFzKG9iaik7XG59O1xuXG52YXIgZ2V0TWF4SW5kZXggPSBmdW5jdGlvbiBnZXRNYXhJbmRleChvYmopIHtcbiAgICByZXR1cm4gb3ZlcmZsb3dDaGFubmVsLmdldChvYmopO1xufTtcblxudmFyIHNldE1heEluZGV4ID0gZnVuY3Rpb24gc2V0TWF4SW5kZXgob2JqLCBtYXhJbmRleCkge1xuICAgIG92ZXJmbG93Q2hhbm5lbC5zZXQob2JqLCBtYXhJbmRleCk7XG59O1xuXG52YXIgaGV4VGFibGUgPSAoZnVuY3Rpb24gKCkge1xuICAgIHZhciBhcnJheSA9IFtdO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgMjU2OyArK2kpIHtcbiAgICAgICAgYXJyYXlbYXJyYXkubGVuZ3RoXSA9ICclJyArICgoaSA8IDE2ID8gJzAnIDogJycpICsgaS50b1N0cmluZygxNikpLnRvVXBwZXJDYXNlKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGFycmF5O1xufSgpKTtcblxudmFyIGNvbXBhY3RRdWV1ZSA9IGZ1bmN0aW9uIGNvbXBhY3RRdWV1ZShxdWV1ZSkge1xuICAgIHdoaWxlIChxdWV1ZS5sZW5ndGggPiAxKSB7XG4gICAgICAgIHZhciBpdGVtID0gcXVldWUucG9wKCk7XG4gICAgICAgIHZhciBvYmogPSBpdGVtLm9ialtpdGVtLnByb3BdO1xuXG4gICAgICAgIGlmIChpc0FycmF5KG9iaikpIHtcbiAgICAgICAgICAgIHZhciBjb21wYWN0ZWQgPSBbXTtcblxuICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBvYmoubGVuZ3RoOyArK2opIHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG9ialtqXSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgY29tcGFjdGVkW2NvbXBhY3RlZC5sZW5ndGhdID0gb2JqW2pdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaXRlbS5vYmpbaXRlbS5wcm9wXSA9IGNvbXBhY3RlZDtcbiAgICAgICAgfVxuICAgIH1cbn07XG5cbnZhciBhcnJheVRvT2JqZWN0ID0gZnVuY3Rpb24gYXJyYXlUb09iamVjdChzb3VyY2UsIG9wdGlvbnMpIHtcbiAgICB2YXIgb2JqID0gb3B0aW9ucyAmJiBvcHRpb25zLnBsYWluT2JqZWN0cyA/IHsgX19wcm90b19fOiBudWxsIH0gOiB7fTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNvdXJjZS5sZW5ndGg7ICsraSkge1xuICAgICAgICBpZiAodHlwZW9mIHNvdXJjZVtpXSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIG9ialtpXSA9IHNvdXJjZVtpXTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBvYmo7XG59O1xuXG52YXIgc2V0UHJvcGVydHkgPSBmdW5jdGlvbiBzZXRQcm9wZXJ0eShvYmosIGtleSwgdmFsdWUpIHtcbiAgICBpZiAoa2V5ID09PSAnX19wcm90b19fJyAmJiBkZWZpbmVQcm9wZXJ0eSkge1xuICAgICAgICBkZWZpbmVQcm9wZXJ0eShvYmosIGtleSwge1xuICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIHZhbHVlOiB2YWx1ZSxcbiAgICAgICAgICAgIHdyaXRhYmxlOiB0cnVlXG4gICAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIG9ialtrZXldID0gdmFsdWU7XG4gICAgfVxufTtcblxudmFyIG1lcmdlID0gZnVuY3Rpb24gbWVyZ2UodGFyZ2V0LCBzb3VyY2UsIG9wdGlvbnMpIHtcbiAgICAvKiBlc2xpbnQgbm8tcGFyYW0tcmVhc3NpZ246IDAgKi9cbiAgICBpZiAoIXNvdXJjZSkge1xuICAgICAgICByZXR1cm4gdGFyZ2V0O1xuICAgIH1cblxuICAgIGlmICh0eXBlb2Ygc291cmNlICE9PSAnb2JqZWN0JyAmJiB0eXBlb2Ygc291cmNlICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGlmIChpc0FycmF5KHRhcmdldCkpIHtcbiAgICAgICAgICAgIHZhciBuZXh0SW5kZXggPSB0YXJnZXQubGVuZ3RoO1xuICAgICAgICAgICAgaWYgKG9wdGlvbnMgJiYgdHlwZW9mIG9wdGlvbnMuYXJyYXlMaW1pdCA9PT0gJ251bWJlcicgJiYgbmV4dEluZGV4ID49IG9wdGlvbnMuYXJyYXlMaW1pdCkge1xuICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLnRocm93T25MaW1pdEV4Y2VlZGVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdBcnJheSBsaW1pdCBleGNlZWRlZC4gT25seSAnICsgb3B0aW9ucy5hcnJheUxpbWl0ICsgJyBlbGVtZW50JyArIChvcHRpb25zLmFycmF5TGltaXQgPT09IDEgPyAnJyA6ICdzJykgKyAnIGFsbG93ZWQgaW4gYW4gYXJyYXkuJyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBtYXJrT3ZlcmZsb3coYXJyYXlUb09iamVjdCh0YXJnZXQuY29uY2F0KHNvdXJjZSksIG9wdGlvbnMpLCBuZXh0SW5kZXgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGFyZ2V0W25leHRJbmRleF0gPSBzb3VyY2U7XG4gICAgICAgIH0gZWxzZSBpZiAodGFyZ2V0ICYmIHR5cGVvZiB0YXJnZXQgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICBpZiAoaXNPdmVyZmxvdyh0YXJnZXQpKSB7XG4gICAgICAgICAgICAgICAgLy8gQWRkIGF0IG5leHQgbnVtZXJpYyBpbmRleCBmb3Igb3ZlcmZsb3cgb2JqZWN0c1xuICAgICAgICAgICAgICAgIHZhciBuZXdJbmRleCA9IGdldE1heEluZGV4KHRhcmdldCkgKyAxO1xuICAgICAgICAgICAgICAgIHRhcmdldFtuZXdJbmRleF0gPSBzb3VyY2U7XG4gICAgICAgICAgICAgICAgc2V0TWF4SW5kZXgodGFyZ2V0LCBuZXdJbmRleCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy5zdHJpY3RNZXJnZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBbdGFyZ2V0LCBzb3VyY2VdO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgICAgICAgICAob3B0aW9ucyAmJiAob3B0aW9ucy5wbGFpbk9iamVjdHMgfHwgb3B0aW9ucy5hbGxvd1Byb3RvdHlwZXMpKVxuICAgICAgICAgICAgICAgIHx8ICFoYXMuY2FsbChPYmplY3QucHJvdG90eXBlLCBzb3VyY2UpXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICB0YXJnZXRbc291cmNlXSA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gW3RhcmdldCwgc291cmNlXTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0YXJnZXQ7XG4gICAgfVxuXG4gICAgaWYgKCF0YXJnZXQgfHwgdHlwZW9mIHRhcmdldCAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgaWYgKGlzT3ZlcmZsb3coc291cmNlKSkge1xuICAgICAgICAgICAgLy8gQ3JlYXRlIG5ldyBvYmplY3Qgd2l0aCB0YXJnZXQgYXQgMCwgc291cmNlIHZhbHVlcyBzaGlmdGVkIGJ5IDFcbiAgICAgICAgICAgIHZhciBzb3VyY2VLZXlzID0gT2JqZWN0LmtleXMoc291cmNlKTtcbiAgICAgICAgICAgIHZhciByZXN1bHQgPSBvcHRpb25zICYmIG9wdGlvbnMucGxhaW5PYmplY3RzXG4gICAgICAgICAgICAgICAgPyB7IF9fcHJvdG9fXzogbnVsbCwgMDogdGFyZ2V0IH1cbiAgICAgICAgICAgICAgICA6IHsgMDogdGFyZ2V0IH07XG4gICAgICAgICAgICBmb3IgKHZhciBtID0gMDsgbSA8IHNvdXJjZUtleXMubGVuZ3RoOyBtKyspIHtcbiAgICAgICAgICAgICAgICB2YXIgb2xkS2V5ID0gcGFyc2VJbnQoc291cmNlS2V5c1ttXSwgMTApO1xuICAgICAgICAgICAgICAgIHJlc3VsdFtvbGRLZXkgKyAxXSA9IHNvdXJjZVtzb3VyY2VLZXlzW21dXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBtYXJrT3ZlcmZsb3cocmVzdWx0LCBnZXRNYXhJbmRleChzb3VyY2UpICsgMSk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGNvbWJpbmVkID0gW3RhcmdldF0uY29uY2F0KHNvdXJjZSk7XG4gICAgICAgIGlmIChvcHRpb25zICYmIHR5cGVvZiBvcHRpb25zLmFycmF5TGltaXQgPT09ICdudW1iZXInICYmIGNvbWJpbmVkLmxlbmd0aCA+IG9wdGlvbnMuYXJyYXlMaW1pdCkge1xuICAgICAgICAgICAgaWYgKG9wdGlvbnMudGhyb3dPbkxpbWl0RXhjZWVkZWQpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignQXJyYXkgbGltaXQgZXhjZWVkZWQuIE9ubHkgJyArIG9wdGlvbnMuYXJyYXlMaW1pdCArICcgZWxlbWVudCcgKyAob3B0aW9ucy5hcnJheUxpbWl0ID09PSAxID8gJycgOiAncycpICsgJyBhbGxvd2VkIGluIGFuIGFycmF5LicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG1hcmtPdmVyZmxvdyhhcnJheVRvT2JqZWN0KGNvbWJpbmVkLCBvcHRpb25zKSwgY29tYmluZWQubGVuZ3RoIC0gMSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNvbWJpbmVkO1xuICAgIH1cblxuICAgIHZhciBtZXJnZVRhcmdldCA9IHRhcmdldDtcbiAgICBpZiAoaXNBcnJheSh0YXJnZXQpICYmICFpc0FycmF5KHNvdXJjZSkpIHtcbiAgICAgICAgbWVyZ2VUYXJnZXQgPSBhcnJheVRvT2JqZWN0KHRhcmdldCwgb3B0aW9ucyk7XG4gICAgfVxuXG4gICAgaWYgKGlzQXJyYXkodGFyZ2V0KSAmJiBpc0FycmF5KHNvdXJjZSkpIHtcbiAgICAgICAgc291cmNlLmZvckVhY2goZnVuY3Rpb24gKGl0ZW0sIGkpIHtcbiAgICAgICAgICAgIGlmIChoYXMuY2FsbCh0YXJnZXQsIGkpKSB7XG4gICAgICAgICAgICAgICAgdmFyIHRhcmdldEl0ZW0gPSB0YXJnZXRbaV07XG4gICAgICAgICAgICAgICAgaWYgKHRhcmdldEl0ZW0gJiYgdHlwZW9mIHRhcmdldEl0ZW0gPT09ICdvYmplY3QnICYmIGl0ZW0gJiYgdHlwZW9mIGl0ZW0gPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICAgICAgICAgIHRhcmdldFtpXSA9IG1lcmdlKHRhcmdldEl0ZW0sIGl0ZW0sIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRhcmdldFt0YXJnZXQubGVuZ3RoXSA9IGl0ZW07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0YXJnZXRbaV0gPSBpdGVtO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKG9wdGlvbnMgJiYgdHlwZW9mIG9wdGlvbnMuYXJyYXlMaW1pdCA9PT0gJ251bWJlcicgJiYgdGFyZ2V0Lmxlbmd0aCA+IG9wdGlvbnMuYXJyYXlMaW1pdCkge1xuICAgICAgICAgICAgaWYgKG9wdGlvbnMudGhyb3dPbkxpbWl0RXhjZWVkZWQpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignQXJyYXkgbGltaXQgZXhjZWVkZWQuIE9ubHkgJyArIG9wdGlvbnMuYXJyYXlMaW1pdCArICcgZWxlbWVudCcgKyAob3B0aW9ucy5hcnJheUxpbWl0ID09PSAxID8gJycgOiAncycpICsgJyBhbGxvd2VkIGluIGFuIGFycmF5LicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG1hcmtPdmVyZmxvdyhhcnJheVRvT2JqZWN0KHRhcmdldCwgb3B0aW9ucyksIHRhcmdldC5sZW5ndGggLSAxKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGFyZ2V0O1xuICAgIH1cblxuICAgIHJldHVybiBPYmplY3Qua2V5cyhzb3VyY2UpLnJlZHVjZShmdW5jdGlvbiAoYWNjLCBrZXkpIHtcbiAgICAgICAgdmFyIHZhbHVlID0gc291cmNlW2tleV07XG5cbiAgICAgICAgaWYgKGhhcy5jYWxsKGFjYywga2V5KSkge1xuICAgICAgICAgICAgc2V0UHJvcGVydHkoYWNjLCBrZXksIG1lcmdlKGFjY1trZXldLCB2YWx1ZSwgb3B0aW9ucykpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc2V0UHJvcGVydHkoYWNjLCBrZXksIHZhbHVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpc092ZXJmbG93KHNvdXJjZSkgJiYgIWlzT3ZlcmZsb3coYWNjKSkge1xuICAgICAgICAgICAgbWFya092ZXJmbG93KGFjYywgZ2V0TWF4SW5kZXgoc291cmNlKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzT3ZlcmZsb3coYWNjKSkge1xuICAgICAgICAgICAgdmFyIGtleU51bSA9IHBhcnNlSW50KGtleSwgMTApO1xuICAgICAgICAgICAgaWYgKFN0cmluZyhrZXlOdW0pID09PSBrZXkgJiYga2V5TnVtID49IDAgJiYga2V5TnVtID4gZ2V0TWF4SW5kZXgoYWNjKSkge1xuICAgICAgICAgICAgICAgIHNldE1heEluZGV4KGFjYywga2V5TnVtKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhY2M7XG4gICAgfSwgbWVyZ2VUYXJnZXQpO1xufTtcblxudmFyIGFzc2lnbiA9IGZ1bmN0aW9uIGFzc2lnblNpbmdsZVNvdXJjZSh0YXJnZXQsIHNvdXJjZSkge1xuICAgIHJldHVybiBPYmplY3Qua2V5cyhzb3VyY2UpLnJlZHVjZShmdW5jdGlvbiAoYWNjLCBrZXkpIHtcbiAgICAgICAgc2V0UHJvcGVydHkoYWNjLCBrZXksIHNvdXJjZVtrZXldKTtcbiAgICAgICAgcmV0dXJuIGFjYztcbiAgICB9LCB0YXJnZXQpO1xufTtcblxudmFyIGRlY29kZSA9IGZ1bmN0aW9uIChzdHIsIGRlZmF1bHREZWNvZGVyLCBjaGFyc2V0KSB7XG4gICAgdmFyIHN0cldpdGhvdXRQbHVzID0gc3RyLnJlcGxhY2UoL1xcKy9nLCAnICcpO1xuICAgIGlmIChjaGFyc2V0ID09PSAnaXNvLTg4NTktMScpIHtcbiAgICAgICAgLy8gdW5lc2NhcGUgbmV2ZXIgdGhyb3dzLCBubyB0cnkuLi5jYXRjaCBuZWVkZWQ6XG4gICAgICAgIHJldHVybiBzdHJXaXRob3V0UGx1cy5yZXBsYWNlKC8lWzAtOWEtZl17Mn0vZ2ksIHVuZXNjYXBlKTtcbiAgICB9XG4gICAgLy8gdXRmLThcbiAgICB0cnkge1xuICAgICAgICByZXR1cm4gZGVjb2RlVVJJQ29tcG9uZW50KHN0cldpdGhvdXRQbHVzKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHJldHVybiBzdHJXaXRob3V0UGx1cztcbiAgICB9XG59O1xuXG52YXIgbGltaXQgPSAxMDI0O1xuXG4vKiBlc2xpbnQgb3BlcmF0b3ItbGluZWJyZWFrOiBbMiwgXCJiZWZvcmVcIl0gKi9cblxudmFyIGVuY29kZSA9IGZ1bmN0aW9uIGVuY29kZShzdHIsIGRlZmF1bHRFbmNvZGVyLCBjaGFyc2V0LCBraW5kLCBmb3JtYXQpIHtcbiAgICAvLyBUaGlzIGNvZGUgd2FzIG9yaWdpbmFsbHkgd3JpdHRlbiBieSBCcmlhbiBXaGl0ZSAobXNjZGV4KSBmb3IgdGhlIGlvLmpzIGNvcmUgcXVlcnlzdHJpbmcgbGlicmFyeS5cbiAgICAvLyBJdCBoYXMgYmVlbiBhZGFwdGVkIGhlcmUgZm9yIHN0cmljdGVyIGFkaGVyZW5jZSB0byBSRkMgMzk4NlxuICAgIGlmIChzdHIubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJldHVybiBzdHI7XG4gICAgfVxuXG4gICAgdmFyIHN0cmluZyA9IHN0cjtcbiAgICBpZiAodHlwZW9mIHN0ciA9PT0gJ3N5bWJvbCcpIHtcbiAgICAgICAgc3RyaW5nID0gU3ltYm9sLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHN0cik7XG4gICAgfSBlbHNlIGlmICh0eXBlb2Ygc3RyICE9PSAnc3RyaW5nJykge1xuICAgICAgICBzdHJpbmcgPSBTdHJpbmcoc3RyKTtcbiAgICB9XG5cbiAgICBpZiAoY2hhcnNldCA9PT0gJ2lzby04ODU5LTEnKSB7XG4gICAgICAgIHJldHVybiBlc2NhcGUoc3RyaW5nKS5yZXBsYWNlKC8ldVswLTlhLWZdezR9L2dpLCBmdW5jdGlvbiAoJDApIHtcbiAgICAgICAgICAgIHJldHVybiAnJTI2JTIzJyArIHBhcnNlSW50KCQwLnNsaWNlKDIpLCAxNikgKyAnJTNCJztcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgdmFyIG91dCA9ICcnO1xuICAgIGZvciAodmFyIGogPSAwOyBqIDwgc3RyaW5nLmxlbmd0aDsgaiArPSBsaW1pdCkge1xuICAgICAgICB2YXIgc2VnbWVudCA9IHN0cmluZy5sZW5ndGggPj0gbGltaXQgPyBzdHJpbmcuc2xpY2UoaiwgaiArIGxpbWl0KSA6IHN0cmluZztcbiAgICAgICAgaWYgKGogKyBsaW1pdCA8IHN0cmluZy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHZhciBsYXN0ID0gc2VnbWVudC5jaGFyQ29kZUF0KHNlZ21lbnQubGVuZ3RoIC0gMSk7XG4gICAgICAgICAgICBpZiAobGFzdCA+PSAweEQ4MDAgJiYgbGFzdCA8PSAweERCRkYpIHtcbiAgICAgICAgICAgICAgICBzZWdtZW50ID0gc2VnbWVudC5zbGljZSgwLCAtMSk7XG4gICAgICAgICAgICAgICAgaiAtPSAxO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHZhciBhcnIgPSBbXTtcblxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNlZ21lbnQubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgIHZhciBjID0gc2VnbWVudC5jaGFyQ29kZUF0KGkpO1xuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgIGMgPT09IDB4MkQgLy8gLVxuICAgICAgICAgICAgICAgIHx8IGMgPT09IDB4MkUgLy8gLlxuICAgICAgICAgICAgICAgIHx8IGMgPT09IDB4NUYgLy8gX1xuICAgICAgICAgICAgICAgIHx8IGMgPT09IDB4N0UgLy8gflxuICAgICAgICAgICAgICAgIHx8IChjID49IDB4MzAgJiYgYyA8PSAweDM5KSAvLyAwLTlcbiAgICAgICAgICAgICAgICB8fCAoYyA+PSAweDQxICYmIGMgPD0gMHg1QSkgLy8gYS16XG4gICAgICAgICAgICAgICAgfHwgKGMgPj0gMHg2MSAmJiBjIDw9IDB4N0EpIC8vIEEtWlxuICAgICAgICAgICAgICAgIHx8IChmb3JtYXQgPT09IGZvcm1hdHMuUkZDMTczOCAmJiAoYyA9PT0gMHgyOCB8fCBjID09PSAweDI5KSkgLy8gKCApXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICBhcnJbYXJyLmxlbmd0aF0gPSBzZWdtZW50LmNoYXJBdChpKTtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGMgPCAweDgwKSB7XG4gICAgICAgICAgICAgICAgYXJyW2Fyci5sZW5ndGhdID0gaGV4VGFibGVbY107XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChjIDwgMHg4MDApIHtcbiAgICAgICAgICAgICAgICBhcnJbYXJyLmxlbmd0aF0gPSBoZXhUYWJsZVsweEMwIHwgKGMgPj4gNildXG4gICAgICAgICAgICAgICAgICAgICsgaGV4VGFibGVbMHg4MCB8IChjICYgMHgzRildO1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoYyA8IDB4RDgwMCB8fCBjID49IDB4RTAwMCkge1xuICAgICAgICAgICAgICAgIGFyclthcnIubGVuZ3RoXSA9IGhleFRhYmxlWzB4RTAgfCAoYyA+PiAxMildXG4gICAgICAgICAgICAgICAgICAgICsgaGV4VGFibGVbMHg4MCB8ICgoYyA+PiA2KSAmIDB4M0YpXVxuICAgICAgICAgICAgICAgICAgICArIGhleFRhYmxlWzB4ODAgfCAoYyAmIDB4M0YpXTtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaSArPSAxO1xuICAgICAgICAgICAgYyA9IDB4MTAwMDAgKyAoKChjICYgMHgzRkYpIDw8IDEwKSB8IChzZWdtZW50LmNoYXJDb2RlQXQoaSkgJiAweDNGRikpO1xuXG4gICAgICAgICAgICBhcnJbYXJyLmxlbmd0aF0gPSBoZXhUYWJsZVsweEYwIHwgKGMgPj4gMTgpXVxuICAgICAgICAgICAgICAgICsgaGV4VGFibGVbMHg4MCB8ICgoYyA+PiAxMikgJiAweDNGKV1cbiAgICAgICAgICAgICAgICArIGhleFRhYmxlWzB4ODAgfCAoKGMgPj4gNikgJiAweDNGKV1cbiAgICAgICAgICAgICAgICArIGhleFRhYmxlWzB4ODAgfCAoYyAmIDB4M0YpXTtcbiAgICAgICAgfVxuXG4gICAgICAgIG91dCArPSBhcnIuam9pbignJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG91dDtcbn07XG5cbnZhciBjb21wYWN0ID0gZnVuY3Rpb24gY29tcGFjdCh2YWx1ZSkge1xuICAgIHZhciBxdWV1ZSA9IFt7IG9iajogeyBvOiB2YWx1ZSB9LCBwcm9wOiAnbycgfV07XG4gICAgdmFyIHJlZnMgPSBnZXRTaWRlQ2hhbm5lbCgpO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBxdWV1ZS5sZW5ndGg7ICsraSkge1xuICAgICAgICB2YXIgaXRlbSA9IHF1ZXVlW2ldO1xuICAgICAgICB2YXIgb2JqID0gaXRlbS5vYmpbaXRlbS5wcm9wXTtcblxuICAgICAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKG9iaik7XG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwga2V5cy5sZW5ndGg7ICsraikge1xuICAgICAgICAgICAgdmFyIGtleSA9IGtleXNbal07XG4gICAgICAgICAgICB2YXIgdmFsID0gb2JqW2tleV07XG4gICAgICAgICAgICBpZiAodHlwZW9mIHZhbCA9PT0gJ29iamVjdCcgJiYgdmFsICE9PSBudWxsICYmICFyZWZzLmhhcyh2YWwpKSB7XG4gICAgICAgICAgICAgICAgcXVldWVbcXVldWUubGVuZ3RoXSA9IHsgb2JqOiBvYmosIHByb3A6IGtleSB9O1xuICAgICAgICAgICAgICAgIHJlZnMuc2V0KHZhbCwgdHJ1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjb21wYWN0UXVldWUocXVldWUpO1xuXG4gICAgcmV0dXJuIHZhbHVlO1xufTtcblxudmFyIGlzUmVnRXhwID0gZnVuY3Rpb24gaXNSZWdFeHAob2JqKSB7XG4gICAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvYmopID09PSAnW29iamVjdCBSZWdFeHBdJztcbn07XG5cbnZhciBpc0J1ZmZlciA9IGZ1bmN0aW9uIGlzQnVmZmVyKG9iaikge1xuICAgIGlmICghb2JqIHx8IHR5cGVvZiBvYmogIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICByZXR1cm4gISEob2JqLmNvbnN0cnVjdG9yICYmIG9iai5jb25zdHJ1Y3Rvci5pc0J1ZmZlciAmJiBvYmouY29uc3RydWN0b3IuaXNCdWZmZXIob2JqKSk7XG59O1xuXG52YXIgY29tYmluZSA9IGZ1bmN0aW9uIGNvbWJpbmUoYSwgYiwgYXJyYXlMaW1pdCwgcGxhaW5PYmplY3RzLCB0aHJvd09uTGltaXRFeGNlZWRlZCkge1xuICAgIC8vIElmICdhJyBpcyBhbHJlYWR5IGFuIG92ZXJmbG93IG9iamVjdCwgYWRkIHRvIGl0XG4gICAgaWYgKGlzT3ZlcmZsb3coYSkpIHtcbiAgICAgICAgaWYgKHRocm93T25MaW1pdEV4Y2VlZGVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignQXJyYXkgbGltaXQgZXhjZWVkZWQuIE9ubHkgJyArIGFycmF5TGltaXQgKyAnIGVsZW1lbnQnICsgKGFycmF5TGltaXQgPT09IDEgPyAnJyA6ICdzJykgKyAnIGFsbG93ZWQgaW4gYW4gYXJyYXkuJyk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIG5ld0luZGV4ID0gZ2V0TWF4SW5kZXgoYSkgKyAxO1xuICAgICAgICBhW25ld0luZGV4XSA9IGI7XG4gICAgICAgIHNldE1heEluZGV4KGEsIG5ld0luZGV4KTtcbiAgICAgICAgcmV0dXJuIGE7XG4gICAgfVxuXG4gICAgdmFyIHJlc3VsdCA9IFtdLmNvbmNhdChhLCBiKTtcbiAgICBpZiAocmVzdWx0Lmxlbmd0aCA+IGFycmF5TGltaXQpIHtcbiAgICAgICAgaWYgKHRocm93T25MaW1pdEV4Y2VlZGVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignQXJyYXkgbGltaXQgZXhjZWVkZWQuIE9ubHkgJyArIGFycmF5TGltaXQgKyAnIGVsZW1lbnQnICsgKGFycmF5TGltaXQgPT09IDEgPyAnJyA6ICdzJykgKyAnIGFsbG93ZWQgaW4gYW4gYXJyYXkuJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1hcmtPdmVyZmxvdyhhcnJheVRvT2JqZWN0KHJlc3VsdCwgeyBwbGFpbk9iamVjdHM6IHBsYWluT2JqZWN0cyB9KSwgcmVzdWx0Lmxlbmd0aCAtIDEpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xufTtcblxudmFyIG1heWJlTWFwID0gZnVuY3Rpb24gbWF5YmVNYXAodmFsLCBmbikge1xuICAgIGlmIChpc0FycmF5KHZhbCkpIHtcbiAgICAgICAgdmFyIG1hcHBlZCA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHZhbC5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgbWFwcGVkW21hcHBlZC5sZW5ndGhdID0gZm4odmFsW2ldKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWFwcGVkO1xuICAgIH1cbiAgICByZXR1cm4gZm4odmFsKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICAgIGFycmF5VG9PYmplY3Q6IGFycmF5VG9PYmplY3QsXG4gICAgYXNzaWduOiBhc3NpZ24sXG4gICAgY29tYmluZTogY29tYmluZSxcbiAgICBjb21wYWN0OiBjb21wYWN0LFxuICAgIGRlY29kZTogZGVjb2RlLFxuICAgIGVuY29kZTogZW5jb2RlLFxuICAgIGlzQnVmZmVyOiBpc0J1ZmZlcixcbiAgICBpc092ZXJmbG93OiBpc092ZXJmbG93LFxuICAgIGlzUmVnRXhwOiBpc1JlZ0V4cCxcbiAgICBtYXJrT3ZlcmZsb3c6IG1hcmtPdmVyZmxvdyxcbiAgICBtYXliZU1hcDogbWF5YmVNYXAsXG4gICAgbWVyZ2U6IG1lcmdlXG59O1xuIiwiLyohIHNhZmUtYnVmZmVyLiBNSVQgTGljZW5zZS4gRmVyb3NzIEFib3VraGFkaWplaCA8aHR0cHM6Ly9mZXJvc3Mub3JnL29wZW5zb3VyY2U+ICovXG4vKiBlc2xpbnQtZGlzYWJsZSBub2RlL25vLWRlcHJlY2F0ZWQtYXBpICovXG52YXIgYnVmZmVyID0gcmVxdWlyZSgnYnVmZmVyJylcbnZhciBCdWZmZXIgPSBidWZmZXIuQnVmZmVyXG5cbi8vIGFsdGVybmF0aXZlIHRvIHVzaW5nIE9iamVjdC5rZXlzIGZvciBvbGQgYnJvd3NlcnNcbmZ1bmN0aW9uIGNvcHlQcm9wcyAoc3JjLCBkc3QpIHtcbiAgZm9yICh2YXIga2V5IGluIHNyYykge1xuICAgIGRzdFtrZXldID0gc3JjW2tleV1cbiAgfVxufVxuaWYgKEJ1ZmZlci5mcm9tICYmIEJ1ZmZlci5hbGxvYyAmJiBCdWZmZXIuYWxsb2NVbnNhZmUgJiYgQnVmZmVyLmFsbG9jVW5zYWZlU2xvdykge1xuICBtb2R1bGUuZXhwb3J0cyA9IGJ1ZmZlclxufSBlbHNlIHtcbiAgLy8gQ29weSBwcm9wZXJ0aWVzIGZyb20gcmVxdWlyZSgnYnVmZmVyJylcbiAgY29weVByb3BzKGJ1ZmZlciwgZXhwb3J0cylcbiAgZXhwb3J0cy5CdWZmZXIgPSBTYWZlQnVmZmVyXG59XG5cbmZ1bmN0aW9uIFNhZmVCdWZmZXIgKGFyZywgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBCdWZmZXIoYXJnLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpXG59XG5cblNhZmVCdWZmZXIucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShCdWZmZXIucHJvdG90eXBlKVxuXG4vLyBDb3B5IHN0YXRpYyBtZXRob2RzIGZyb20gQnVmZmVyXG5jb3B5UHJvcHMoQnVmZmVyLCBTYWZlQnVmZmVyKVxuXG5TYWZlQnVmZmVyLmZyb20gPSBmdW5jdGlvbiAoYXJnLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpIHtcbiAgaWYgKHR5cGVvZiBhcmcgPT09ICdudW1iZXInKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQXJndW1lbnQgbXVzdCBub3QgYmUgYSBudW1iZXInKVxuICB9XG4gIHJldHVybiBCdWZmZXIoYXJnLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpXG59XG5cblNhZmVCdWZmZXIuYWxsb2MgPSBmdW5jdGlvbiAoc2l6ZSwgZmlsbCwgZW5jb2RpbmcpIHtcbiAgaWYgKHR5cGVvZiBzaXplICE9PSAnbnVtYmVyJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50IG11c3QgYmUgYSBudW1iZXInKVxuICB9XG4gIHZhciBidWYgPSBCdWZmZXIoc2l6ZSlcbiAgaWYgKGZpbGwgIT09IHVuZGVmaW5lZCkge1xuICAgIGlmICh0eXBlb2YgZW5jb2RpbmcgPT09ICdzdHJpbmcnKSB7XG4gICAgICBidWYuZmlsbChmaWxsLCBlbmNvZGluZylcbiAgICB9IGVsc2Uge1xuICAgICAgYnVmLmZpbGwoZmlsbClcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgYnVmLmZpbGwoMClcbiAgfVxuICByZXR1cm4gYnVmXG59XG5cblNhZmVCdWZmZXIuYWxsb2NVbnNhZmUgPSBmdW5jdGlvbiAoc2l6ZSkge1xuICBpZiAodHlwZW9mIHNpemUgIT09ICdudW1iZXInKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQXJndW1lbnQgbXVzdCBiZSBhIG51bWJlcicpXG4gIH1cbiAgcmV0dXJuIEJ1ZmZlcihzaXplKVxufVxuXG5TYWZlQnVmZmVyLmFsbG9jVW5zYWZlU2xvdyA9IGZ1bmN0aW9uIChzaXplKSB7XG4gIGlmICh0eXBlb2Ygc2l6ZSAhPT0gJ251bWJlcicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudCBtdXN0IGJlIGEgbnVtYmVyJylcbiAgfVxuICByZXR1cm4gYnVmZmVyLlNsb3dCdWZmZXIoc2l6ZSlcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGluc3BlY3QgPSByZXF1aXJlKCdvYmplY3QtaW5zcGVjdCcpO1xuXG52YXIgJFR5cGVFcnJvciA9IHJlcXVpcmUoJ2VzLWVycm9ycy90eXBlJyk7XG5cbi8qXG4qIFRoaXMgZnVuY3Rpb24gdHJhdmVyc2VzIHRoZSBsaXN0IHJldHVybmluZyB0aGUgbm9kZSBjb3JyZXNwb25kaW5nIHRvIHRoZSBnaXZlbiBrZXkuXG4qXG4qIFRoYXQgbm9kZSBpcyBhbHNvIG1vdmVkIHRvIHRoZSBoZWFkIG9mIHRoZSBsaXN0LCBzbyB0aGF0IGlmIGl0J3MgYWNjZXNzZWQgYWdhaW4gd2UgZG9uJ3QgbmVlZCB0byB0cmF2ZXJzZSB0aGUgd2hvbGUgbGlzdC5cbiogQnkgZG9pbmcgc28sIGFsbCB0aGUgcmVjZW50bHkgdXNlZCBub2RlcyBjYW4gYmUgYWNjZXNzZWQgcmVsYXRpdmVseSBxdWlja2x5LlxuKi9cbi8qKiBAdHlwZSB7aW1wb3J0KCcuL2xpc3QuZC50cycpLmxpc3RHZXROb2RlfSAqL1xuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGNvbnNpc3RlbnQtcmV0dXJuXG52YXIgbGlzdEdldE5vZGUgPSBmdW5jdGlvbiAobGlzdCwga2V5LCBpc0RlbGV0ZSkge1xuXHQvKiogQHR5cGUge3R5cGVvZiBsaXN0IHwgTm9uTnVsbGFibGU8KHR5cGVvZiBsaXN0KVsnbmV4dCddPn0gKi9cblx0dmFyIHByZXYgPSBsaXN0O1xuXHQvKiogQHR5cGUgeyh0eXBlb2YgbGlzdClbJ25leHQnXX0gKi9cblx0dmFyIGN1cnI7XG5cdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBlcWVxZXFcblx0Zm9yICg7IChjdXJyID0gcHJldi5uZXh0KSAhPSBudWxsOyBwcmV2ID0gY3Vycikge1xuXHRcdGlmIChjdXJyLmtleSA9PT0ga2V5KSB7XG5cdFx0XHRwcmV2Lm5leHQgPSBjdXJyLm5leHQ7XG5cdFx0XHRpZiAoIWlzRGVsZXRlKSB7XG5cdFx0XHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1leHRyYS1wYXJlbnNcblx0XHRcdFx0Y3Vyci5uZXh0ID0gLyoqIEB0eXBlIHtOb25OdWxsYWJsZTx0eXBlb2YgbGlzdC5uZXh0Pn0gKi8gKGxpc3QubmV4dCk7XG5cdFx0XHRcdGxpc3QubmV4dCA9IGN1cnI7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tcGFyYW0tcmVhc3NpZ25cblx0XHRcdH1cblx0XHRcdHJldHVybiBjdXJyO1xuXHRcdH1cblx0fVxufTtcblxuLyoqIEB0eXBlIHtpbXBvcnQoJy4vbGlzdC5kLnRzJykubGlzdEdldH0gKi9cbnZhciBsaXN0R2V0ID0gZnVuY3Rpb24gKG9iamVjdHMsIGtleSkge1xuXHRpZiAoIW9iamVjdHMpIHtcblx0XHRyZXR1cm4gdm9pZCB1bmRlZmluZWQ7XG5cdH1cblx0dmFyIG5vZGUgPSBsaXN0R2V0Tm9kZShvYmplY3RzLCBrZXkpO1xuXHRyZXR1cm4gbm9kZSAmJiBub2RlLnZhbHVlO1xufTtcbi8qKiBAdHlwZSB7aW1wb3J0KCcuL2xpc3QuZC50cycpLmxpc3RTZXR9ICovXG52YXIgbGlzdFNldCA9IGZ1bmN0aW9uIChvYmplY3RzLCBrZXksIHZhbHVlKSB7XG5cdHZhciBub2RlID0gbGlzdEdldE5vZGUob2JqZWN0cywga2V5KTtcblx0aWYgKG5vZGUpIHtcblx0XHRub2RlLnZhbHVlID0gdmFsdWU7XG5cdH0gZWxzZSB7XG5cdFx0Ly8gUHJlcGVuZCB0aGUgbmV3IG5vZGUgdG8gdGhlIGJlZ2lubmluZyBvZiB0aGUgbGlzdFxuXHRcdG9iamVjdHMubmV4dCA9IC8qKiBAdHlwZSB7aW1wb3J0KCcuL2xpc3QuZC50cycpLkxpc3ROb2RlPHR5cGVvZiB2YWx1ZSwgdHlwZW9mIGtleT59ICovICh7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tcGFyYW0tcmVhc3NpZ24sIG5vLWV4dHJhLXBhcmVuc1xuXHRcdFx0a2V5OiBrZXksXG5cdFx0XHRuZXh0OiBvYmplY3RzLm5leHQsXG5cdFx0XHR2YWx1ZTogdmFsdWVcblx0XHR9KTtcblx0fVxufTtcbi8qKiBAdHlwZSB7aW1wb3J0KCcuL2xpc3QuZC50cycpLmxpc3RIYXN9ICovXG52YXIgbGlzdEhhcyA9IGZ1bmN0aW9uIChvYmplY3RzLCBrZXkpIHtcblx0aWYgKCFvYmplY3RzKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cdHJldHVybiAhIWxpc3RHZXROb2RlKG9iamVjdHMsIGtleSk7XG59O1xuLyoqIEB0eXBlIHtpbXBvcnQoJy4vbGlzdC5kLnRzJykubGlzdERlbGV0ZX0gKi9cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjb25zaXN0ZW50LXJldHVyblxudmFyIGxpc3REZWxldGUgPSBmdW5jdGlvbiAob2JqZWN0cywga2V5KSB7XG5cdGlmIChvYmplY3RzKSB7XG5cdFx0cmV0dXJuIGxpc3RHZXROb2RlKG9iamVjdHMsIGtleSwgdHJ1ZSk7XG5cdH1cbn07XG5cbi8qKiBAdHlwZSB7aW1wb3J0KCcuJyl9ICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGdldFNpZGVDaGFubmVsTGlzdCgpIHtcblx0LyoqIEB0eXBlZGVmIHtSZXR1cm5UeXBlPHR5cGVvZiBnZXRTaWRlQ2hhbm5lbExpc3Q+fSBDaGFubmVsICovXG5cdC8qKiBAdHlwZWRlZiB7UGFyYW1ldGVyczxDaGFubmVsWydnZXQnXT5bMF19IEsgKi9cblx0LyoqIEB0eXBlZGVmIHtQYXJhbWV0ZXJzPENoYW5uZWxbJ3NldCddPlsxXX0gViAqL1xuXG5cdC8qKiBAdHlwZSB7aW1wb3J0KCcuL2xpc3QuZC50cycpLlJvb3ROb2RlPFYsIEs+IHwgdW5kZWZpbmVkfSAqLyB2YXIgJG87XG5cblx0LyoqIEB0eXBlIHtDaGFubmVsfSAqL1xuXHR2YXIgY2hhbm5lbCA9IHtcblx0XHRhc3NlcnQ6IGZ1bmN0aW9uIChrZXkpIHtcblx0XHRcdGlmICghY2hhbm5lbC5oYXMoa2V5KSkge1xuXHRcdFx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignU2lkZSBjaGFubmVsIGRvZXMgbm90IGNvbnRhaW4gJyArIGluc3BlY3Qoa2V5KSk7XG5cdFx0XHR9XG5cdFx0fSxcblx0XHQnZGVsZXRlJzogZnVuY3Rpb24gKGtleSkge1xuXHRcdFx0dmFyIGRlbGV0ZWROb2RlID0gbGlzdERlbGV0ZSgkbywga2V5KTtcblx0XHRcdGlmIChkZWxldGVkTm9kZSAmJiAkbyAmJiAhJG8ubmV4dCkge1xuXHRcdFx0XHQkbyA9IHZvaWQgdW5kZWZpbmVkO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuICEhZGVsZXRlZE5vZGU7XG5cdFx0fSxcblx0XHRnZXQ6IGZ1bmN0aW9uIChrZXkpIHtcblx0XHRcdHJldHVybiBsaXN0R2V0KCRvLCBrZXkpO1xuXHRcdH0sXG5cdFx0aGFzOiBmdW5jdGlvbiAoa2V5KSB7XG5cdFx0XHRyZXR1cm4gbGlzdEhhcygkbywga2V5KTtcblx0XHR9LFxuXHRcdHNldDogZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcblx0XHRcdGlmICghJG8pIHtcblx0XHRcdFx0Ly8gSW5pdGlhbGl6ZSB0aGUgbGlua2VkIGxpc3QgYXMgYW4gZW1wdHkgbm9kZSwgc28gdGhhdCB3ZSBkb24ndCBoYXZlIHRvIHNwZWNpYWwtY2FzZSBoYW5kbGluZyBvZiB0aGUgZmlyc3Qgbm9kZTogd2UgY2FuIGFsd2F5cyByZWZlciB0byBpdCBhcyAocHJldmlvdXMgbm9kZSkubmV4dCwgaW5zdGVhZCBvZiBzb21ldGhpbmcgbGlrZSAobGlzdCkuaGVhZFxuXHRcdFx0XHQkbyA9IHtcblx0XHRcdFx0XHRuZXh0OiB2b2lkIHVuZGVmaW5lZFxuXHRcdFx0XHR9O1xuXHRcdFx0fVxuXHRcdFx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWV4dHJhLXBhcmVuc1xuXHRcdFx0bGlzdFNldCgvKiogQHR5cGUge05vbk51bGxhYmxlPHR5cGVvZiAkbz59ICovICgkbyksIGtleSwgdmFsdWUpO1xuXHRcdH1cblx0fTtcblx0cmV0dXJuIGNoYW5uZWw7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2V0SW50cmluc2ljID0gcmVxdWlyZSgnZ2V0LWludHJpbnNpYycpO1xudmFyIGNhbGxCb3VuZCA9IHJlcXVpcmUoJ2NhbGwtYm91bmQnKTtcbnZhciBpbnNwZWN0ID0gcmVxdWlyZSgnb2JqZWN0LWluc3BlY3QnKTtcblxudmFyICRUeXBlRXJyb3IgPSByZXF1aXJlKCdlcy1lcnJvcnMvdHlwZScpO1xudmFyICRNYXAgPSBHZXRJbnRyaW5zaWMoJyVNYXAlJywgdHJ1ZSk7XG5cbi8qKiBAdHlwZSB7PEssIFY+KHRoaXNBcmc6IE1hcDxLLCBWPiwga2V5OiBLKSA9PiBWfSAqL1xudmFyICRtYXBHZXQgPSBjYWxsQm91bmQoJ01hcC5wcm90b3R5cGUuZ2V0JywgdHJ1ZSk7XG4vKiogQHR5cGUgezxLLCBWPih0aGlzQXJnOiBNYXA8SywgVj4sIGtleTogSywgdmFsdWU6IFYpID0+IHZvaWR9ICovXG52YXIgJG1hcFNldCA9IGNhbGxCb3VuZCgnTWFwLnByb3RvdHlwZS5zZXQnLCB0cnVlKTtcbi8qKiBAdHlwZSB7PEssIFY+KHRoaXNBcmc6IE1hcDxLLCBWPiwga2V5OiBLKSA9PiBib29sZWFufSAqL1xudmFyICRtYXBIYXMgPSBjYWxsQm91bmQoJ01hcC5wcm90b3R5cGUuaGFzJywgdHJ1ZSk7XG4vKiogQHR5cGUgezxLLCBWPih0aGlzQXJnOiBNYXA8SywgVj4sIGtleTogSykgPT4gYm9vbGVhbn0gKi9cbnZhciAkbWFwRGVsZXRlID0gY2FsbEJvdW5kKCdNYXAucHJvdG90eXBlLmRlbGV0ZScsIHRydWUpO1xuLyoqIEB0eXBlIHs8SywgVj4odGhpc0FyZzogTWFwPEssIFY+KSA9PiBudW1iZXJ9ICovXG52YXIgJG1hcFNpemUgPSBjYWxsQm91bmQoJ01hcC5wcm90b3R5cGUuc2l6ZScsIHRydWUpO1xuXG4vKiogQHR5cGUge2ltcG9ydCgnLicpfSAqL1xubW9kdWxlLmV4cG9ydHMgPSAhISRNYXAgJiYgLyoqIEB0eXBlIHtFeGNsdWRlPGltcG9ydCgnLicpLCBmYWxzZT59ICovIGZ1bmN0aW9uIGdldFNpZGVDaGFubmVsTWFwKCkge1xuXHQvKiogQHR5cGVkZWYge1JldHVyblR5cGU8dHlwZW9mIGdldFNpZGVDaGFubmVsTWFwPn0gQ2hhbm5lbCAqL1xuXHQvKiogQHR5cGVkZWYge1BhcmFtZXRlcnM8Q2hhbm5lbFsnZ2V0J10+WzBdfSBLICovXG5cdC8qKiBAdHlwZWRlZiB7UGFyYW1ldGVyczxDaGFubmVsWydzZXQnXT5bMV19IFYgKi9cblxuXHQvKiogQHR5cGUge01hcDxLLCBWPiB8IHVuZGVmaW5lZH0gKi8gdmFyICRtO1xuXG5cdC8qKiBAdHlwZSB7Q2hhbm5lbH0gKi9cblx0dmFyIGNoYW5uZWwgPSB7XG5cdFx0YXNzZXJ0OiBmdW5jdGlvbiAoa2V5KSB7XG5cdFx0XHRpZiAoIWNoYW5uZWwuaGFzKGtleSkpIHtcblx0XHRcdFx0dGhyb3cgbmV3ICRUeXBlRXJyb3IoJ1NpZGUgY2hhbm5lbCBkb2VzIG5vdCBjb250YWluICcgKyBpbnNwZWN0KGtleSkpO1xuXHRcdFx0fVxuXHRcdH0sXG5cdFx0J2RlbGV0ZSc6IGZ1bmN0aW9uIChrZXkpIHtcblx0XHRcdGlmICgkbSkge1xuXHRcdFx0XHR2YXIgcmVzdWx0ID0gJG1hcERlbGV0ZSgkbSwga2V5KTtcblx0XHRcdFx0aWYgKCRtYXBTaXplKCRtKSA9PT0gMCkge1xuXHRcdFx0XHRcdCRtID0gdm9pZCB1bmRlZmluZWQ7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHRcdH1cblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9LFxuXHRcdGdldDogZnVuY3Rpb24gKGtleSkgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIGNvbnNpc3RlbnQtcmV0dXJuXG5cdFx0XHRpZiAoJG0pIHtcblx0XHRcdFx0cmV0dXJuICRtYXBHZXQoJG0sIGtleSk7XG5cdFx0XHR9XG5cdFx0fSxcblx0XHRoYXM6IGZ1bmN0aW9uIChrZXkpIHtcblx0XHRcdGlmICgkbSkge1xuXHRcdFx0XHRyZXR1cm4gJG1hcEhhcygkbSwga2V5KTtcblx0XHRcdH1cblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9LFxuXHRcdHNldDogZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcblx0XHRcdGlmICghJG0pIHtcblx0XHRcdFx0Ly8gQHRzLWV4cGVjdC1lcnJvciBUUyBjYW4ndCBoYW5kbGUgbmFycm93aW5nIGEgdmFyaWFibGUgaW5zaWRlIGEgY2xvc3VyZVxuXHRcdFx0XHQkbSA9IG5ldyAkTWFwKCk7XG5cdFx0XHR9XG5cdFx0XHQkbWFwU2V0KCRtLCBrZXksIHZhbHVlKTtcblx0XHR9XG5cdH07XG5cblx0Ly8gQHRzLWV4cGVjdC1lcnJvciBUT0RPOiBmaWd1cmUgb3V0IHdoeSBUUyBpcyBlcnJvcmluZyBoZXJlXG5cdHJldHVybiBjaGFubmVsO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIEdldEludHJpbnNpYyA9IHJlcXVpcmUoJ2dldC1pbnRyaW5zaWMnKTtcbnZhciBjYWxsQm91bmQgPSByZXF1aXJlKCdjYWxsLWJvdW5kJyk7XG52YXIgaW5zcGVjdCA9IHJlcXVpcmUoJ29iamVjdC1pbnNwZWN0Jyk7XG52YXIgZ2V0U2lkZUNoYW5uZWxNYXAgPSByZXF1aXJlKCdzaWRlLWNoYW5uZWwtbWFwJyk7XG5cbnZhciAkVHlwZUVycm9yID0gcmVxdWlyZSgnZXMtZXJyb3JzL3R5cGUnKTtcbnZhciAkV2Vha01hcCA9IEdldEludHJpbnNpYygnJVdlYWtNYXAlJywgdHJ1ZSk7XG5cbi8qKiBAdHlwZSB7PEsgZXh0ZW5kcyBvYmplY3QsIFY+KHRoaXNBcmc6IFdlYWtNYXA8SywgVj4sIGtleTogSykgPT4gVn0gKi9cbnZhciAkd2Vha01hcEdldCA9IGNhbGxCb3VuZCgnV2Vha01hcC5wcm90b3R5cGUuZ2V0JywgdHJ1ZSk7XG4vKiogQHR5cGUgezxLIGV4dGVuZHMgb2JqZWN0LCBWPih0aGlzQXJnOiBXZWFrTWFwPEssIFY+LCBrZXk6IEssIHZhbHVlOiBWKSA9PiB2b2lkfSAqL1xudmFyICR3ZWFrTWFwU2V0ID0gY2FsbEJvdW5kKCdXZWFrTWFwLnByb3RvdHlwZS5zZXQnLCB0cnVlKTtcbi8qKiBAdHlwZSB7PEsgZXh0ZW5kcyBvYmplY3QsIFY+KHRoaXNBcmc6IFdlYWtNYXA8SywgVj4sIGtleTogSykgPT4gYm9vbGVhbn0gKi9cbnZhciAkd2Vha01hcEhhcyA9IGNhbGxCb3VuZCgnV2Vha01hcC5wcm90b3R5cGUuaGFzJywgdHJ1ZSk7XG4vKiogQHR5cGUgezxLIGV4dGVuZHMgb2JqZWN0LCBWPih0aGlzQXJnOiBXZWFrTWFwPEssIFY+LCBrZXk6IEspID0+IGJvb2xlYW59ICovXG52YXIgJHdlYWtNYXBEZWxldGUgPSBjYWxsQm91bmQoJ1dlYWtNYXAucHJvdG90eXBlLmRlbGV0ZScsIHRydWUpO1xuXG4vKiogQHR5cGUge2ltcG9ydCgnLicpfSAqL1xubW9kdWxlLmV4cG9ydHMgPSAkV2Vha01hcFxuXHQ/IC8qKiBAdHlwZSB7RXhjbHVkZTxpbXBvcnQoJy4nKSwgZmFsc2U+fSAqLyBmdW5jdGlvbiBnZXRTaWRlQ2hhbm5lbFdlYWtNYXAoKSB7XG5cdFx0LyoqIEB0eXBlZGVmIHtSZXR1cm5UeXBlPHR5cGVvZiBnZXRTaWRlQ2hhbm5lbFdlYWtNYXA+fSBDaGFubmVsICovXG5cdFx0LyoqIEB0eXBlZGVmIHtQYXJhbWV0ZXJzPENoYW5uZWxbJ2dldCddPlswXX0gSyAqL1xuXHRcdC8qKiBAdHlwZWRlZiB7UGFyYW1ldGVyczxDaGFubmVsWydzZXQnXT5bMV19IFYgKi9cblxuXHRcdC8qKiBAdHlwZSB7V2Vha01hcDxLICYgb2JqZWN0LCBWPiB8IHVuZGVmaW5lZH0gKi8gdmFyICR3bTtcblx0XHQvKiogQHR5cGUge0NoYW5uZWwgfCB1bmRlZmluZWR9ICovIHZhciAkbTtcblxuXHRcdC8qKiBAdHlwZSB7Q2hhbm5lbH0gKi9cblx0XHR2YXIgY2hhbm5lbCA9IHtcblx0XHRcdGFzc2VydDogZnVuY3Rpb24gKGtleSkge1xuXHRcdFx0XHRpZiAoIWNoYW5uZWwuaGFzKGtleSkpIHtcblx0XHRcdFx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignU2lkZSBjaGFubmVsIGRvZXMgbm90IGNvbnRhaW4gJyArIGluc3BlY3Qoa2V5KSk7XG5cdFx0XHRcdH1cblx0XHRcdH0sXG5cdFx0XHQnZGVsZXRlJzogZnVuY3Rpb24gKGtleSkge1xuXHRcdFx0XHRpZiAoJFdlYWtNYXAgJiYga2V5ICYmICh0eXBlb2Yga2V5ID09PSAnb2JqZWN0JyB8fCB0eXBlb2Yga2V5ID09PSAnZnVuY3Rpb24nKSkge1xuXHRcdFx0XHRcdGlmICgkd20pIHtcblx0XHRcdFx0XHRcdHJldHVybiAkd2Vha01hcERlbGV0ZSgkd20sIGtleSk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9IGVsc2UgaWYgKGdldFNpZGVDaGFubmVsTWFwKSB7XG5cdFx0XHRcdFx0aWYgKCRtKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gJG1bJ2RlbGV0ZSddKGtleSk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH0sXG5cdFx0XHRnZXQ6IGZ1bmN0aW9uIChrZXkpIHtcblx0XHRcdFx0aWYgKCRXZWFrTWFwICYmIGtleSAmJiAodHlwZW9mIGtleSA9PT0gJ29iamVjdCcgfHwgdHlwZW9mIGtleSA9PT0gJ2Z1bmN0aW9uJykpIHtcblx0XHRcdFx0XHRpZiAoJHdtKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gJHdlYWtNYXBHZXQoJHdtLCBrZXkpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gJG0gJiYgJG0uZ2V0KGtleSk7XG5cdFx0XHR9LFxuXHRcdFx0aGFzOiBmdW5jdGlvbiAoa2V5KSB7XG5cdFx0XHRcdGlmICgkV2Vha01hcCAmJiBrZXkgJiYgKHR5cGVvZiBrZXkgPT09ICdvYmplY3QnIHx8IHR5cGVvZiBrZXkgPT09ICdmdW5jdGlvbicpKSB7XG5cdFx0XHRcdFx0aWYgKCR3bSkge1xuXHRcdFx0XHRcdFx0cmV0dXJuICR3ZWFrTWFwSGFzKCR3bSwga2V5KTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuICEhJG0gJiYgJG0uaGFzKGtleSk7XG5cdFx0XHR9LFxuXHRcdFx0c2V0OiBmdW5jdGlvbiAoa2V5LCB2YWx1ZSkge1xuXHRcdFx0XHRpZiAoJFdlYWtNYXAgJiYga2V5ICYmICh0eXBlb2Yga2V5ID09PSAnb2JqZWN0JyB8fCB0eXBlb2Yga2V5ID09PSAnZnVuY3Rpb24nKSkge1xuXHRcdFx0XHRcdGlmICghJHdtKSB7XG5cdFx0XHRcdFx0XHQkd20gPSBuZXcgJFdlYWtNYXAoKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0JHdlYWtNYXBTZXQoJHdtLCBrZXksIHZhbHVlKTtcblx0XHRcdFx0fSBlbHNlIGlmIChnZXRTaWRlQ2hhbm5lbE1hcCkge1xuXHRcdFx0XHRcdGlmICghJG0pIHtcblx0XHRcdFx0XHRcdCRtID0gZ2V0U2lkZUNoYW5uZWxNYXAoKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWV4dHJhLXBhcmVuc1xuXHRcdFx0XHRcdC8qKiBAdHlwZSB7Tm9uTnVsbGFibGU8dHlwZW9mICRtPn0gKi8gKCRtKS5zZXQoa2V5LCB2YWx1ZSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9O1xuXG5cdFx0Ly8gQHRzLWV4cGVjdC1lcnJvciBUT0RPOiBmaWd1cmUgb3V0IHdoeSB0aGlzIGlzIGVycm9yaW5nXG5cdFx0cmV0dXJuIGNoYW5uZWw7XG5cdH1cblx0OiBnZXRTaWRlQ2hhbm5lbE1hcDtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyICRUeXBlRXJyb3IgPSByZXF1aXJlKCdlcy1lcnJvcnMvdHlwZScpO1xudmFyIGluc3BlY3QgPSByZXF1aXJlKCdvYmplY3QtaW5zcGVjdCcpO1xudmFyIGdldFNpZGVDaGFubmVsTGlzdCA9IHJlcXVpcmUoJ3NpZGUtY2hhbm5lbC1saXN0Jyk7XG52YXIgZ2V0U2lkZUNoYW5uZWxNYXAgPSByZXF1aXJlKCdzaWRlLWNoYW5uZWwtbWFwJyk7XG52YXIgZ2V0U2lkZUNoYW5uZWxXZWFrTWFwID0gcmVxdWlyZSgnc2lkZS1jaGFubmVsLXdlYWttYXAnKTtcblxudmFyIG1ha2VDaGFubmVsID0gZ2V0U2lkZUNoYW5uZWxXZWFrTWFwIHx8IGdldFNpZGVDaGFubmVsTWFwIHx8IGdldFNpZGVDaGFubmVsTGlzdDtcblxuLyoqIEB0eXBlIHtpbXBvcnQoJy4nKX0gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gZ2V0U2lkZUNoYW5uZWwoKSB7XG5cdC8qKiBAdHlwZWRlZiB7UmV0dXJuVHlwZTx0eXBlb2YgZ2V0U2lkZUNoYW5uZWw+fSBDaGFubmVsICovXG5cblx0LyoqIEB0eXBlIHtDaGFubmVsIHwgdW5kZWZpbmVkfSAqLyB2YXIgJGNoYW5uZWxEYXRhO1xuXG5cdC8qKiBAdHlwZSB7Q2hhbm5lbH0gKi9cblx0dmFyIGNoYW5uZWwgPSB7XG5cdFx0YXNzZXJ0OiBmdW5jdGlvbiAoa2V5KSB7XG5cdFx0XHRpZiAoIWNoYW5uZWwuaGFzKGtleSkpIHtcblx0XHRcdFx0dmFyIGtleURlc2MgPSBrZXkgJiYgT2JqZWN0KGtleSkgPT09IGtleVxuXHRcdFx0XHRcdD8gJ3RoZSBnaXZlbiBvYmplY3Qga2V5J1xuXHRcdFx0XHRcdDogaW5zcGVjdChrZXkpO1xuXHRcdFx0XHR0aHJvdyBuZXcgJFR5cGVFcnJvcignU2lkZSBjaGFubmVsIGRvZXMgbm90IGNvbnRhaW4gJyArIGtleURlc2MpO1xuXHRcdFx0fVxuXHRcdH0sXG5cdFx0J2RlbGV0ZSc6IGZ1bmN0aW9uIChrZXkpIHtcblx0XHRcdHJldHVybiAhISRjaGFubmVsRGF0YSAmJiAkY2hhbm5lbERhdGFbJ2RlbGV0ZSddKGtleSk7XG5cdFx0fSxcblx0XHRnZXQ6IGZ1bmN0aW9uIChrZXkpIHtcblx0XHRcdHJldHVybiAkY2hhbm5lbERhdGEgJiYgJGNoYW5uZWxEYXRhLmdldChrZXkpO1xuXHRcdH0sXG5cdFx0aGFzOiBmdW5jdGlvbiAoa2V5KSB7XG5cdFx0XHRyZXR1cm4gISEkY2hhbm5lbERhdGEgJiYgJGNoYW5uZWxEYXRhLmhhcyhrZXkpO1xuXHRcdH0sXG5cdFx0c2V0OiBmdW5jdGlvbiAoa2V5LCB2YWx1ZSkge1xuXHRcdFx0aWYgKCEkY2hhbm5lbERhdGEpIHtcblx0XHRcdFx0JGNoYW5uZWxEYXRhID0gbWFrZUNoYW5uZWwoKTtcblx0XHRcdH1cblxuXHRcdFx0JGNoYW5uZWxEYXRhLnNldChrZXksIHZhbHVlKTtcblx0XHR9XG5cdH07XG5cblx0cmV0dXJuIGNoYW5uZWw7XG59O1xuIiwidmFyIENsaWVudFJlcXVlc3QgPSByZXF1aXJlKCcuL2xpYi9yZXF1ZXN0JylcbnZhciByZXNwb25zZSA9IHJlcXVpcmUoJy4vbGliL3Jlc3BvbnNlJylcbnZhciBleHRlbmQgPSByZXF1aXJlKCd4dGVuZCcpXG52YXIgc3RhdHVzQ29kZXMgPSByZXF1aXJlKCdidWlsdGluLXN0YXR1cy1jb2RlcycpXG52YXIgdXJsID0gcmVxdWlyZSgndXJsJylcblxudmFyIGh0dHAgPSBleHBvcnRzXG5cbmh0dHAucmVxdWVzdCA9IGZ1bmN0aW9uIChvcHRzLCBjYikge1xuXHRpZiAodHlwZW9mIG9wdHMgPT09ICdzdHJpbmcnKVxuXHRcdG9wdHMgPSB1cmwucGFyc2Uob3B0cylcblx0ZWxzZVxuXHRcdG9wdHMgPSBleHRlbmQob3B0cylcblxuXHQvLyBOb3JtYWxseSwgdGhlIHBhZ2UgaXMgbG9hZGVkIGZyb20gaHR0cCBvciBodHRwcywgc28gbm90IHNwZWNpZnlpbmcgYSBwcm90b2NvbFxuXHQvLyB3aWxsIHJlc3VsdCBpbiBhICh2YWxpZCkgcHJvdG9jb2wtcmVsYXRpdmUgdXJsLiBIb3dldmVyLCB0aGlzIHdvbid0IHdvcmsgaWZcblx0Ly8gdGhlIHByb3RvY29sIGlzIHNvbWV0aGluZyBlbHNlLCBsaWtlICdmaWxlOidcblx0dmFyIGRlZmF1bHRQcm90b2NvbCA9IGdsb2JhbC5sb2NhdGlvbi5wcm90b2NvbC5zZWFyY2goL15odHRwcz86JC8pID09PSAtMSA/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