Free javascript Hosting


compass.js

Uploaded on Dec 05 2021 19:16 by keyurjain21

(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else if(typeof exports === 'object')
exports["Compass"] = factory();
else
root["Compass"] = factory();
})(window, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ }
/******/ };
/******/
/******/ // define __esModule on exports
/******/ __webpack_require__.r = function(exports) {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/
/******/ // create a fake namespace object
/******/ // mode & 1: value is a module id, require it
/******/ // mode & 2: merge all properties of value into the ns
/******/ // mode & 4: return value when already ns object
/******/ // mode & 8|1: behave like require
/******/ __webpack_require__.t = function(value, mode) {
/******/ if(mode & 1) value = __webpack_require__(value);
/******/ if(mode & 8) return value;
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ var ns = Object.create(null);
/******/ __webpack_require__.r(ns);
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/ return ns;
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = "./src/index.js");
/******/ })
/************************************************************************/
/******/ ({

/***/ "./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js!./src/Compass/Compass.scss":
/*!***************************************************************************************************************!*\
!*** ./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js!./src/Compass/Compass.scss ***!
\***************************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// Imports
var ___CSS_LOADER_API_IMPORT___ = __webpack_require__(/*! ../../node_modules/css-loader/dist/runtime/api.js */ "./node_modules/css-loader/dist/runtime/api.js");
exports = ___CSS_LOADER_API_IMPORT___(false);
// Module
exports.push([module.i, "#emoji__compass {\n width: 32px;\n height: 32px;\n position: fixed;\n top: 0.5rem;\n left: 0.5rem;\n background-color: white;\n border-radius: 2px;\n box-shadow: 1px 1px 8px rgba(0, 0, 0, 0.25); }\n", ""]);
// Exports
module.exports = exports;


/***/ }),

/***/ "./node_modules/css-loader/dist/runtime/api.js":
/*!*****************************************************!*\
!*** ./node_modules/css-loader/dist/runtime/api.js ***!
\*****************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
// css base code, injected by the css-loader
// eslint-disable-next-line func-names
module.exports = function (useSourceMap) {
var list = []; // return the list of modules as css string

list.toString = function toString() {
return this.map(function (item) {
var content = cssWithMappingToString(item, useSourceMap);

if (item[2]) {
return "@media ".concat(item[2], " {").concat(content, "}");
}

return content;
}).join('');
}; // import a list of modules into the list
// eslint-disable-next-line func-names


list.i = function (modules, mediaQuery, dedupe) {
if (typeof modules === 'string') {
// eslint-disable-next-line no-param-reassign
modules = [[null, modules, '']];
}

var alreadyImportedModules = {};

if (dedupe) {
for (var i = 0; i < this.length; i++) {
// eslint-disable-next-line prefer-destructuring
var id = this[i][0];

if (id != null) {
alreadyImportedModules[id] = true;
}
}
}

for (var _i = 0; _i < modules.length; _i++) {
var item = [].concat(modules[_i]);

if (dedupe && alreadyImportedModules[item[0]]) {
// eslint-disable-next-line no-continue
continue;
}

if (mediaQuery) {
if (!item[2]) {
item[2] = mediaQuery;
} else {
item[2] = "".concat(mediaQuery, " and ").concat(item[2]);
}
}

list.push(item);
}
};

return list;
};

function cssWithMappingToString(item, useSourceMap) {
var content = item[1] || ''; // eslint-disable-next-line prefer-destructuring

var cssMapping = item[3];

if (!cssMapping) {
return content;
}

if (useSourceMap && typeof btoa === 'function') {
var sourceMapping = toComment(cssMapping);
var sourceURLs = cssMapping.sources.map(function (source) {
return "/*# sourceURL=".concat(cssMapping.sourceRoot || '').concat(source, " */");
});
return [content].concat(sourceURLs).concat([sourceMapping]).join('\n');
}

return [content].join('\n');
} // Adapted from convert-source-map (MIT)


function toComment(sourceMap) {
// eslint-disable-next-line no-undef
var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap))));
var data = "sourceMappingURL=data:application/json;charset=utf-8;base64,".concat(base64);
return "/*# ".concat(data, " */");
}

/***/ }),

/***/ "./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js":
/*!****************************************************************************!*\
!*** ./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js ***!
\****************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var isOldIE = function isOldIE() {
var memo;
return function memorize() {
if (typeof memo === 'undefined') {
// Test for IE <= 9 as proposed by Browserhacks
// @see http://browserhacks.com/#hack-e71d8692f65334173fee715c222cb805
// Tests for existence of standard globals is to allow style-loader
// to operate correctly into non-standard environments
// @see https://github.com/webpack-contrib/style-loader/issues/177
memo = Boolean(window && document && document.all && !window.atob);
}

return memo;
};
}();

var getTarget = function getTarget() {
var memo = {};
return function memorize(target) {
if (typeof memo[target] === 'undefined') {
var styleTarget = document.querySelector(target); // Special case to return head of iframe instead of iframe itself

if (window.HTMLIFrameElement && styleTarget instanceof window.HTMLIFrameElement) {
try {
// This will throw an exception if access to iframe is blocked
// due to cross-origin restrictions
styleTarget = styleTarget.contentDocument.head;
} catch (e) {
// istanbul ignore next
styleTarget = null;
}
}

memo[target] = styleTarget;
}

return memo[target];
};
}();

var stylesInDom = [];

function getIndexByIdentifier(identifier) {
var result = -1;

for (var i = 0; i < stylesInDom.length; i++) {
if (stylesInDom[i].identifier === identifier) {
result = i;
break;
}
}

return result;
}

function modulesToDom(list, options) {
var idCountMap = {};
var identifiers = [];

for (var i = 0; i < list.length; i++) {
var item = list[i];
var id = options.base ? item[0] + options.base : item[0];
var count = idCountMap[id] || 0;
var identifier = "".concat(id, " ").concat(count);
idCountMap[id] = count + 1;
var index = getIndexByIdentifier(identifier);
var obj = {
css: item[1],
media: item[2],
sourceMap: item[3]
};

if (index !== -1) {
stylesInDom[index].references++;
stylesInDom[index].updater(obj);
} else {
stylesInDom.push({
identifier: identifier,
updater: addStyle(obj, options),
references: 1
});
}

identifiers.push(identifier);
}

return identifiers;
}

function insertStyleElement(options) {
var style = document.createElement('style');
var attributes = options.attributes || {};

if (typeof attributes.nonce === 'undefined') {
var nonce = true ? __webpack_require__.nc : undefined;

if (nonce) {
attributes.nonce = nonce;
}
}

Object.keys(attributes).forEach(function (key) {
style.setAttribute(key, attributes[key]);
});

if (typeof options.insert === 'function') {
options.insert(style);
} else {
var target = getTarget(options.insert || 'head');

if (!target) {
throw new Error("Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.");
}

target.appendChild(style);
}

return style;
}

function removeStyleElement(style) {
// istanbul ignore if
if (style.parentNode === null) {
return false;
}

style.parentNode.removeChild(style);
}
/* istanbul ignore next */


var replaceText = function replaceText() {
var textStore = [];
return function replace(index, replacement) {
textStore[index] = replacement;
return textStore.filter(Boolean).join('\n');
};
}();

function applyToSingletonTag(style, index, remove, obj) {
var css = remove ? '' : obj.media ? "@media ".concat(obj.media, " {").concat(obj.css, "}") : obj.css; // For old IE

/* istanbul ignore if */

if (style.styleSheet) {
style.styleSheet.cssText = replaceText(index, css);
} else {
var cssNode = document.createTextNode(css);
var childNodes = style.childNodes;

if (childNodes[index]) {
style.removeChild(childNodes[index]);
}

if (childNodes.length) {
style.insertBefore(cssNode, childNodes[index]);
} else {
style.appendChild(cssNode);
}
}
}

function applyToTag(style, options, obj) {
var css = obj.css;
var media = obj.media;
var sourceMap = obj.sourceMap;

if (media) {
style.setAttribute('media', media);
} else {
style.removeAttribute('media');
}

if (sourceMap && btoa) {
css += "\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))), " */");
} // For old IE

/* istanbul ignore if */


if (style.styleSheet) {
style.styleSheet.cssText = css;
} else {
while (style.firstChild) {
style.removeChild(style.firstChild);
}

style.appendChild(document.createTextNode(css));
}
}

var singleton = null;
var singletonCounter = 0;

function addStyle(obj, options) {
var style;
var update;
var remove;

if (options.singleton) {
var styleIndex = singletonCounter++;
style = singleton || (singleton = insertStyleElement(options));
update = applyToSingletonTag.bind(null, style, styleIndex, false);
remove = applyToSingletonTag.bind(null, style, styleIndex, true);
} else {
style = insertStyleElement(options);
update = applyToTag.bind(null, style, options);

remove = function remove() {
removeStyleElement(style);
};
}

update(obj);
return function updateStyle(newObj) {
if (newObj) {
if (newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap) {
return;
}

update(obj = newObj);
} else {
remove();
}
};
}

module.exports = function (list, options) {
options = options || {}; // Force single-tag solution on IE6-9, which has a hard limit on the # of <style>
// tags it will allow on a page

if (!options.singleton && typeof options.singleton !== 'boolean') {
options.singleton = isOldIE();
}

list = list || [];
var lastIdentifiers = modulesToDom(list, options);
return function update(newList) {
newList = newList || [];

if (Object.prototype.toString.call(newList) !== '[object Array]') {
return;
}

for (var i = 0; i < lastIdentifiers.length; i++) {
var identifier = lastIdentifiers[i];
var index = getIndexByIdentifier(identifier);
stylesInDom[index].references--;
}

var newLastIdentifiers = modulesToDom(newList, options);

for (var _i = 0; _i < lastIdentifiers.length; _i++) {
var _identifier = lastIdentifiers[_i];

var _index = getIndexByIdentifier(_identifier);

if (stylesInDom[_index].references === 0) {
stylesInDom[_index].updater();

stylesInDom.splice(_index, 1);
}
}

lastIdentifiers = newLastIdentifiers;
};
};

/***/ }),

/***/ "./src/Compass/Compass.js":
/*!********************************!*\
!*** ./src/Compass/Compass.js ***!
\********************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

const emojiCompass = __webpack_require__(/*! ../assets/1F9ED.svg */ "./src/assets/1F9ED.svg");
__webpack_require__(/*! ./Compass.scss */ "./src/Compass/Compass.scss");

const DEFAULTS = {
emojiCompass: emojiCompass,
};

class Compass {
/**
* The compass class is a utility for creating a javascript compass
* with no external dependencies. You can create a compass that
* points north from your location or points towards a specified
* latitude and longitude coordinate. Regardless of where you turn
* the compass will point towards the specified direction.
*
* @class
*/
constructor() {
this.heading = 0;
this.deviceAngleDelta = 0;
this.position = null;
this.button = null;
this.debug = true;

this.geolocationID = null;
this.permissionGranted = false;
}

/**
* initialized the compass - returns a promise or can invoke a callback
* @param {callback} callback - callback to be called after the .start() function is done
*/
init(callback = undefined) {
if (callback) {
this.callCallback(this.start(), callback);
} else {
return this.start();
}
}

/**
* Initializes the device orientation and watches the user position by default
* @async
* @function start
*
*/
async start() {
try {
await this.watchPosition();

if (this.debug === true) {
this.createButton();
this.button.addEventListener(
"click",
this.triggerDeviceOrientationPermissions()
);
document.body.appendChild(this.button);
}
// NOTE: if debug is false, the expectation is that you handle the
// the device orientation handling permissions on your own.

return true;
} catch (err) {
alert(err);
}
}

/**
* creates a button to trigger the device orientation permissions
*
* function
* @name createButton
*/
createButton() {
const div = document.createElement("div");
div.innerHTML += emojiCompass;
this.button = div.querySelector("#emoji__compass");
}

/**
* triggers the device orientation permissions
* @function
* @name triggerDeviceOrientationPermissions
*/
triggerDeviceOrientationPermissions() {
return async (evt) => {
try {
await this.allowOrientationPermissions();
if (this.debug === true) {
this.button.style.display = "none";
}
} catch (err) {
alert(err);
}
};
}

/**
* Asks the user to allow permissions to get orientation
*
* @async
* @name allowOrientationPermissions
*/
async allowOrientationPermissions() {
if (typeof window.DeviceOrientationEvent.requestPermission === "function") {
const permission = await window.DeviceOrientationEvent.requestPermission();
alert(permission);
if (permission == "granted") {
this.permissionGranted = true;
window.addEventListener(
"deviceorientation",
this.deviceOrientationHandler.bind(this),
true
);
return true;
} else {
throw new Error("no device orientation permissions!");
}
} else {
if (window.DeviceOrientationEvent) {
this.permissionGranted = true;
alert("device orientation permission granted");
window.addEventListener(
"deviceorientation",
this.deviceOrientationHandler.bind(this),
true
);
return true;
} else {
alert("no device orientation support");
}
}
}

/**
* This is where my nose points - and seeing as my nose
* is attached to my head, this is where my head
* (and thus my machine) is pointing relative to North.
* NOTE: requires that this.position is set
*
* @function getHeading
*/
getHeading(
origin = {
lat: this.position.coords.latitude,
lng: this.position.coords.longitude,
},
north = { lat: 90, lng: this.position.coords.longitude }
) {
this.heading = 360 - this.getBearingToNorth(origin, north);
return this.heading;
}

/**
* This is the angle between the location of an object,
* machine or destination and my heading.
*
* @param {Object} origin - {lat, lng}
* @param {Object} destination - {lat, lng}
*/
getBearing(origin, destination) {
return (
this.calculateAngle(
origin.lat,
origin.lng,
destination.lat,
destination.lng
) *
(180 / Math.PI)
);
}

/**
* get the angle between your heading and north
* the default is true north vs. magnetic north
*
* @function
* @param {object} origin - {lat, lng}
* @param {object} north - {lat, lng}
*/
getBearingToNorth(
origin = {
lat: this.position.coords.latitude,
lng: this.position.coords.longitude,
},
north = { lat: 90, lng: this.position.coords.longitude }
) {
return this.getBearingToDestination(origin, north);
}

/**
* Get the bearings towards the destination
*
* @param {object} origin - {lat, lng}
* @param {object} destination - {lat, lng}
*/
getBearingToDestination(
origin = {
lat: this.position.coords.latitude,
lng: this.position.coords.longitude,
},
destination
) {
const angleToDestination = this.getBearing(origin, destination);
return this.deviceAngleDelta + angleToDestination;
}

/**
* Handles changes created by the device orientation changes
* assumes that the phone is in a portrait mode, with the display up
* towards the sky as if you were holding an actual compass
*
* @callback
* @param {object} evt - the event object of the device orientation
*/
deviceOrientationHandler(evt) {
if (evt.webkitCompassHeading)
//iphone
this.deviceAngleDelta = 360 - evt.webkitCompassHeading;
else if (evt.alpha)
//android
this.deviceAngleDelta = evt.alpha;
else {
console.log("compass direction not found");
}

// console.log(this.deviceAngleDelta)
this.deviceAngleDelta = Math.round(this.deviceAngleDelta);
}

/**
* get the position of the user
*
* @async
* @function
*/
getPosition() {
return new Promise((resolve, reject) => {
navigator.geolocation.getCurrentPosition((position) => {
if (position) {
resolve(position);
} else {
reject("no position found");
}
});
});
}

/**
* watches the geolocation of the user
*
* @async
* @function
*/
watchPosition() {
return new Promise((resolve, reject) => {
this.geolocationID = navigator.geolocation.watchPosition((position) => {
if (position) {
this.position = position;
// console.log(
// this.position.coords.latitude,
// this.position.coords.longitude
// );
resolve(position);
} else {
reject("no position found");
}
});
});
}

/**
* Stops watching the user location
*
* @function
*/
stopTracking() {
navigator.geolocation.clearWatch(this.geolocationID);
console.log("stopped tracking location");
}

/**
* Calculates the angle given a latitude and longitude position
*
* @function
* @param {number} userLat - user latitude
* @param {number} userLon - user longitude
* @param {number} desiredLat - desired latitude
* @param {number} desiredLon - desired longitude
*/
calculateAngle(userLat, userLon, desiredLat, desiredLon) {
return Math.atan2(desiredLon - userLon, desiredLat - userLat);
}

/**
* Helper function that allows calling a callback from an promise function
*
* @param {promise} promise
* @param {callback} callback
*/
callCallback(promise, callback) {
if (callback) {
promise
.then((result) => {
callback(undefined, result);
return result;
})
.catch((error) => {
callback(error);
return error;
});
}
return promise;
}
}

module.exports = Compass;


/***/ }),

/***/ "./src/Compass/Compass.scss":
/*!**********************************!*\
!*** ./src/Compass/Compass.scss ***!
\**********************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var api = __webpack_require__(/*! ../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js */ "./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js");
var content = __webpack_require__(/*! !../../node_modules/css-loader/dist/cjs.js!../../node_modules/sass-loader/dist/cjs.js!./Compass.scss */ "./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js!./src/Compass/Compass.scss");

content = content.__esModule ? content.default : content;

if (typeof content === 'string') {
content = [[module.i, content, '']];
}

var options = {};

options.insert = "head";
options.singleton = false;

var update = api(content, options);



module.exports = content.locals || {};

/***/ }),

/***/ "./src/assets/1F9ED.svg":
/*!******************************!*\
!*** ./src/assets/1F9ED.svg ***!
\******************************/
/*! no static exports found */
/***/ (function(module, exports) {

module.exports = "<svg id=\"emoji__compass\" viewBox=\"0 0 72 72\" xmlns=\"http://www.w3.org/2000/svg\"><g id=\"line-supplement\"><polyline points=\"33.2 33.2 48 24 38.8 38.8\"></polyline></g><g id=\"line\"><circle cx=\"36\" cy=\"36\" r=\"24\" fill=\"none\" stroke=\"#000\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"></circle><polyline fill=\"none\" stroke=\"#000\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" points=\"33.2 33.2 24 48 38.8 38.8\"></polyline><polyline fill=\"none\" stroke=\"#000\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" points=\"33.2 33.2 48 24 38.8 38.8\"></polyline><line x1=\"36\" x2=\"36\" y1=\"21\" y2=\"16\" fill=\"none\" stroke=\"#000\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"></line><line x1=\"36\" x2=\"36\" y1=\"56\" y2=\"51\" fill=\"none\" stroke=\"#000\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"></line><line x1=\"51\" x2=\"56\" y1=\"36\" y2=\"36\" fill=\"none\" stroke=\"#000\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"></line><line x1=\"16\" x2=\"21\" y1=\"36\" y2=\"36\" fill=\"none\" stroke=\"#000\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"></line></g></svg>"

/***/ }),

/***/ "./src/index.js":
/*!**********************!*\
!*** ./src/index.js ***!
\**********************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

const c = __webpack_require__(/*! ./Compass/Compass.js */ "./src/Compass/Compass.js");
module.exports = c;

/***/ })

/******/ });
});
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9Db21wYXNzL3dlYnBhY2svdW5pdmVyc2FsTW9kdWxlRGVmaW5pdGlvbiIsIndlYnBhY2s6Ly9Db21wYXNzL3dlYnBhY2svYm9vdHN0cmFwIiwid2VicGFjazovL0NvbXBhc3MvLi9zcmMvQ29tcGFzcy9Db21wYXNzLnNjc3MiLCJ3ZWJwYWNrOi8vQ29tcGFzcy8uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvcnVudGltZS9hcGkuanMiLCJ3ZWJwYWNrOi8vQ29tcGFzcy8uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL2luamVjdFN0eWxlc0ludG9TdHlsZVRhZy5qcyIsIndlYnBhY2s6Ly9Db21wYXNzLy4vc3JjL0NvbXBhc3MvQ29tcGFzcy5qcyIsIndlYnBhY2s6Ly9Db21wYXNzLy4vc3JjL0NvbXBhc3MvQ29tcGFzcy5zY3NzP2Y0YWIiLCJ3ZWJwYWNrOi8vQ29tcGFzcy8uL3NyYy9hc3NldHMvMUY5RUQuc3ZnIiwid2VicGFjazovL0NvbXBhc3MvLi9zcmMvaW5kZXguanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNELE87UUNWQTtRQUNBOztRQUVBO1FBQ0E7O1FBRUE7UUFDQTtRQUNBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7O1FBRUE7UUFDQTs7UUFFQTtRQUNBOztRQUVBO1FBQ0E7UUFDQTs7O1FBR0E7UUFDQTs7UUFFQTtRQUNBOztRQUVBO1FBQ0E7UUFDQTtRQUNBLDBDQUEwQyxnQ0FBZ0M7UUFDMUU7UUFDQTs7UUFFQTtRQUNBO1FBQ0E7UUFDQSx3REFBd0Qsa0JBQWtCO1FBQzFFO1FBQ0EsaURBQWlELGNBQWM7UUFDL0Q7O1FBRUE7UUFDQTtRQUNBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7UUFDQTtRQUNBLHlDQUF5QyxpQ0FBaUM7UUFD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Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsT0FBTztBQUNQLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhLE9BQU87QUFDcEIsYUFBYSxPQUFPO0FBQ3BCLGFBQWEsT0FBTztBQUNwQixhQUFhLE9BQU87QUFDcEI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsYUFBYSxRQUFRO0FBQ3JCLGFBQWEsU0FBUztBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7Ozs7Ozs7Ozs7OztBQzVUQSxVQUFVLG1CQUFPLENBQUMsc0pBQTJFO0FBQzdGLDBCQUEwQixtQkFBTyxDQUFDLHFOQUF1Rzs7QUFFekk7O0FBRUE7QUFDQSwwQkFBMEIsUUFBUztBQUNuQzs7QUFFQTs7QUFFQTtBQUNBOztBQUVBOzs7O0FBSUEsc0M7Ozs7Ozs7Ozs7O0FDbEJBLDR3Qzs7Ozs7Ozs7Ozs7QUNBQSxVQUFVLG1CQUFPLENBQUMsc0RBQXNCO0FBQ3hDLG1CIiwiZmlsZSI6ImNvbXBhc3MuanMiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gd2VicGFja1VuaXZlcnNhbE1vZHVsZURlZmluaXRpb24ocm9vdCwgZmFjdG9yeSkge1xuXHRpZih0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcpXG5cdFx0bW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KCk7XG5cdGVsc2UgaWYodHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kKVxuXHRcdGRlZmluZShbXSwgZmFjdG9yeSk7XG5cdGVsc2UgaWYodHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnKVxuXHRcdGV4cG9ydHNbXCJDb21wYXNzXCJdID0gZmFjdG9yeSgpO1xuXHRlbHNlXG5cdFx0cm9vdFtcIkNvbXBhc3NcIl0gPSBmYWN0b3J5KCk7XG59KSh3aW5kb3csIGZ1bmN0aW9uKCkge1xucmV0dXJuICIsIiBcdC8vIFRoZSBtb2R1bGUgY2FjaGVcbiBcdHZhciBpbnN0YWxsZWRNb2R1bGVzID0ge307XG5cbiBcdC8vIFRoZSByZXF1aXJlIGZ1bmN0aW9uXG4gXHRmdW5jdGlvbiBfX3dlYnBhY2tfcmVxdWlyZV9fKG1vZHVsZUlkKSB7XG5cbiBcdFx0Ly8gQ2hlY2sgaWYgbW9kdWxlIGlzIGluIGNhY2hlXG4gXHRcdGlmKGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdKSB7XG4gXHRcdFx0cmV0dXJuIGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdLmV4cG9ydHM7XG4gXHRcdH1cbiBcdFx0Ly8gQ3JlYXRlIGEgbmV3IG1vZHVsZSAoYW5kIHB1dCBpdCBpbnRvIHRoZSBjYWNoZSlcbiBcdFx0dmFyIG1vZHVsZSA9IGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdID0ge1xuIFx0XHRcdGk6IG1vZHVsZUlkLFxuIFx0XHRcdGw6IGZhbHNlLFxuIFx0XHRcdGV4cG9ydHM6IHt9XG4gXHRcdH07XG5cbiBcdFx0Ly8gRXhlY3V0ZSB0aGUgbW9kdWxlIGZ1bmN0aW9uXG4gXHRcdG1vZHVsZXNbbW9kdWxlSWRdLmNhbGwobW9kdWxlLmV4cG9ydHMsIG1vZHVsZSwgbW9kdWxlLmV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pO1xuXG4gXHRcdC8vIEZsYWcgdGhlIG1vZHVsZSBhcyBsb2FkZWRcbiBcdFx0bW9kdWxlLmwgPSB0cnVlO1xuXG4gXHRcdC8vIFJldHVybiB0aGUgZXhwb3J0cyBvZiB0aGUgbW9kdWxlXG4gXHRcdHJldHVybiBtb2R1bGUuZXhwb3J0cztcbiBcdH1cblxuXG4gXHQvLyBleHBvc2UgdGhlIG1vZHVsZXMgb2JqZWN0IChfX3dlYnBhY2tfbW9kdWxlc19fKVxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5tID0gbW9kdWxlcztcblxuIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGUgY2FjaGVcbiBcdF9fd2VicGFja19yZXF1aXJlX18uYyA9IGluc3RhbGxlZE1vZHVsZXM7XG5cbiBcdC8vIGRlZmluZSBnZXR0ZXIgZnVuY3Rpb24gZm9yIGhhcm1vbnkgZXhwb3J0c1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5kID0gZnVuY3Rpb24oZXhwb3J0cywgbmFtZSwgZ2V0dGVyKSB7XG4gXHRcdGlmKCFfX3dlYnBhY2tfcmVxdWlyZV9fLm8oZXhwb3J0cywgbmFtZSkpIHtcbiBcdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgbmFtZSwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGdldHRlciB9KTtcbiBcdFx0fVxuIFx0fTtcblxuIFx0Ly8gZGVmaW5lIF9fZXNNb2R1bGUgb24gZXhwb3J0c1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5yID0gZnVuY3Rpb24oZXhwb3J0cykge1xuIFx0XHRpZih0eXBlb2YgU3ltYm9sICE9PSAndW5kZWZpbmVkJyAmJiBTeW1ib2wudG9TdHJpbmdUYWcpIHtcbiBcdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgU3ltYm9sLnRvU3RyaW5nVGFnLCB7IHZhbHVlOiAnTW9kdWxlJyB9KTtcbiBcdFx0fVxuIFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ19fZXNNb2R1bGUnLCB7IHZhbHVlOiB0cnVlIH0pO1xuIFx0fTtcblxuIFx0Ly8gY3JlYXRlIGEgZmFrZSBuYW1lc3BhY2Ugb2JqZWN0XG4gXHQvLyBtb2RlICYgMTogdmFsdWUgaXMgYSBtb2R1bGUgaWQsIHJlcXVpcmUgaXRcbiBcdC8vIG1vZGUgJiAyOiBtZXJnZSBhbGwgcHJvcGVydGllcyBvZiB2YWx1ZSBpbnRvIHRoZSBuc1xuIFx0Ly8gbW9kZSAmIDQ6IHJldHVybiB2YWx1ZSB3aGVuIGFscmVhZHkgbnMgb2JqZWN0XG4gXHQvLyBtb2RlICYgOHwxOiBiZWhhdmUgbGlrZSByZXF1aXJlXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLnQgPSBmdW5jdGlvbih2YWx1ZSwgbW9kZSkge1xuIFx0XHRpZihtb2RlICYgMSkgdmFsdWUgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKHZhbHVlKTtcbiBcdFx0aWYobW9kZSAmIDgpIHJldHVybiB2YWx1ZTtcbiBcdFx0aWYoKG1vZGUgJiA0KSAmJiB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIHZhbHVlICYmIHZhbHVlLl9fZXNNb2R1bGUpIHJldHVybiB2YWx1ZTtcbiBcdFx0dmFyIG5zID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiBcdFx0X193ZWJwYWNrX3JlcXVpcmVfXy5yKG5zKTtcbiBcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KG5zLCAnZGVmYXVsdCcsIHsgZW51bWVyYWJsZTogdHJ1ZSwgdmFsdWU6IHZhbHVlIH0pO1xuIFx0XHRpZihtb2RlICYgMiAmJiB0eXBlb2YgdmFsdWUgIT0gJ3N0cmluZycpIGZvcih2YXIga2V5IGluIHZhbHVlKSBfX3dlYnBhY2tfcmVxdWlyZV9fLmQobnMsIGtleSwgZnVuY3Rpb24oa2V5KSB7IHJldHVybiB2YWx1ZVtrZXldOyB9LmJpbmQobnVsbCwga2V5KSk7XG4gXHRcdHJldHVybiBucztcbiBcdH07XG5cbiBcdC8vIGdldERlZmF1bHRFeHBvcnQgZnVuY3Rpb24gZm9yIGNvbXBhdGliaWxpdHkgd2l0aCBub24taGFybW9ueSBtb2R1bGVzXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm4gPSBmdW5jdGlvbihtb2R1bGUpIHtcbiBcdFx0dmFyIGdldHRlciA9IG1vZHVsZSAmJiBtb2R1bGUuX19lc01vZHVsZSA/XG4gXHRcdFx0ZnVuY3Rpb24gZ2V0RGVmYXVsdCgpIHsgcmV0dXJuIG1vZHVsZVsnZGVmYXVsdCddOyB9IDpcbiBcdFx0XHRmdW5jdGlvbiBnZXRNb2R1bGVFeHBvcnRzKCkgeyByZXR1cm4gbW9kdWxlOyB9O1xuIFx0XHRfX3dlYnBhY2tfcmVxdWlyZV9fLmQoZ2V0dGVyLCAnYScsIGdldHRlcik7XG4gXHRcdHJldHVybiBnZXR0ZXI7XG4gXHR9O1xuXG4gXHQvLyBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGxcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubyA9IGZ1bmN0aW9uKG9iamVjdCwgcHJvcGVydHkpIHsgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIHByb3BlcnR5KTsgfTtcblxuIFx0Ly8gX193ZWJwYWNrX3B1YmxpY19wYXRoX19cbiBcdF9fd2VicGFja19yZXF1aXJlX18ucCA9IFwiXCI7XG5cblxuIFx0Ly8gTG9hZCBlbnRyeSBtb2R1bGUgYW5kIHJldHVybiBleHBvcnRzXG4gXHRyZXR1cm4gX193ZWJwYWNrX3JlcXVpcmVfXyhfX3dlYnBhY2tfcmVxdWlyZV9fLnMgPSBcIi4vc3JjL2luZGV4LmpzXCIpO1xuIiwiLy8gSW1wb3J0c1xudmFyIF9fX0NTU19MT0FERVJfQVBJX0lNUE9SVF9fXyA9IHJlcXVpcmUoXCIuLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9kaXN0L3J1bnRpbWUvYXBpLmpzXCIpO1xuZXhwb3J0cyA9IF9fX0NTU19MT0FERVJfQVBJX0lNUE9SVF9fXyhmYWxzZSk7XG4vLyBNb2R1bGVcbmV4cG9ydHMucHVzaChbbW9kdWxlLmlkLCBcIiNlbW9qaV9fY29tcGFzcyB7XFxuICB3aWR0aDogMzJweDtcXG4gIGhlaWdodDogMzJweDtcXG4gIHBvc2l0aW9uOiBmaXhlZDtcXG4gIHRvcDogMC41cmVtO1xcbiAgbGVmdDogMC41cmVtO1xcbiAgYmFja2dyb3VuZC1jb2xvcjogd2hpdGU7XFxuICBib3JkZXItcmFkaXVzOiAycHg7XFxuICBib3gtc2hhZG93OiAxcHggMXB4IDhweCByZ2JhKDAsIDAsIDAsIDAuMjUpOyB9XFxuXCIsIFwiXCJdKTtcbi8vIEV4cG9ydHNcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0cztcbiIsIlwidXNlIHN0cmljdFwiO1xuXG4vKlxuICBNSVQgTGljZW5zZSBodHRwOi8vd3d3Lm9wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL21pdC1saWNlbnNlLnBocFxuICBBdXRob3IgVG9iaWFzIEtvcHBlcnMgQHNva3JhXG4qL1xuLy8gY3NzIGJhc2UgY29kZSwgaW5qZWN0ZWQgYnkgdGhlIGNzcy1sb2FkZXJcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBmdW5jLW5hbWVzXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICh1c2VTb3VyY2VNYXApIHtcbiAgdmFyIGxpc3QgPSBbXTsgLy8gcmV0dXJuIHRoZSBsaXN0IG9mIG1vZHVsZXMgYXMgY3NzIHN0cmluZ1xuXG4gIGxpc3QudG9TdHJpbmcgPSBmdW5jdGlvbiB0b1N0cmluZygpIHtcbiAgICByZXR1cm4gdGhpcy5tYXAoZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgIHZhciBjb250ZW50ID0gY3NzV2l0aE1hcHBpbmdUb1N0cmluZyhpdGVtLCB1c2VTb3VyY2VNYXApO1xuXG4gICAgICBpZiAoaXRlbVsyXSkge1xuICAgICAgICByZXR1cm4gXCJAbWVkaWEgXCIuY29uY2F0KGl0ZW1bMl0sIFwiIHtcIikuY29uY2F0KGNvbnRlbnQsIFwifVwiKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGNvbnRlbnQ7XG4gICAgfSkuam9pbignJyk7XG4gIH07IC8vIGltcG9ydCBhIGxpc3Qgb2YgbW9kdWxlcyBpbnRvIHRoZSBsaXN0XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBmdW5jLW5hbWVzXG5cblxuICBsaXN0LmkgPSBmdW5jdGlvbiAobW9kdWxlcywgbWVkaWFRdWVyeSwgZGVkdXBlKSB7XG4gICAgaWYgKHR5cGVvZiBtb2R1bGVzID09PSAnc3RyaW5nJykge1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXBhcmFtLXJlYXNzaWduXG4gICAgICBtb2R1bGVzID0gW1tudWxsLCBtb2R1bGVzLCAnJ11dO1xuICAgIH1cblxuICAgIHZhciBhbHJlYWR5SW1wb3J0ZWRNb2R1bGVzID0ge307XG5cbiAgICBpZiAoZGVkdXBlKSB7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHByZWZlci1kZXN0cnVjdHVyaW5nXG4gICAgICAgIHZhciBpZCA9IHRoaXNbaV1bMF07XG5cbiAgICAgICAgaWYgKGlkICE9IG51bGwpIHtcbiAgICAgICAgICBhbHJlYWR5SW1wb3J0ZWRNb2R1bGVzW2lkXSA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBmb3IgKHZhciBfaSA9IDA7IF9pIDwgbW9kdWxlcy5sZW5ndGg7IF9pKyspIHtcbiAgICAgIHZhciBpdGVtID0gW10uY29uY2F0KG1vZHVsZXNbX2ldKTtcblxuICAgICAgaWYgKGRlZHVwZSAmJiBhbHJlYWR5SW1wb3J0ZWRNb2R1bGVzW2l0ZW1bMF1dKSB7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb250aW51ZVxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKG1lZGlhUXVlcnkpIHtcbiAgICAgICAgaWYgKCFpdGVtWzJdKSB7XG4gICAgICAgICAgaXRlbVsyXSA9IG1lZGlhUXVlcnk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaXRlbVsyXSA9IFwiXCIuY29uY2F0KG1lZGlhUXVlcnksIFwiIGFuZCBcIikuY29uY2F0KGl0ZW1bMl0pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGxpc3QucHVzaChpdGVtKTtcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIGxpc3Q7XG59O1xuXG5mdW5jdGlvbiBjc3NXaXRoTWFwcGluZ1RvU3RyaW5nKGl0ZW0sIHVzZVNvdXJjZU1hcCkge1xuICB2YXIgY29udGVudCA9IGl0ZW1bMV0gfHwgJyc7IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBwcmVmZXItZGVzdHJ1Y3R1cmluZ1xuXG4gIHZhciBjc3NNYXBwaW5nID0gaXRlbVszXTtcblxuICBpZiAoIWNzc01hcHBpbmcpIHtcbiAgICByZXR1cm4gY29udGVudDtcbiAgfVxuXG4gIGlmICh1c2VTb3VyY2VNYXAgJiYgdHlwZW9mIGJ0b2EgPT09ICdmdW5jdGlvbicpIHtcbiAgICB2YXIgc291cmNlTWFwcGluZyA9IHRvQ29tbWVudChjc3NNYXBwaW5nKTtcbiAgICB2YXIgc291cmNlVVJMcyA9IGNzc01hcHBpbmcuc291cmNlcy5tYXAoZnVuY3Rpb24gKHNvdXJjZSkge1xuICAgICAgcmV0dXJuIFwiLyojIHNvdXJjZVVSTD1cIi5jb25jYXQoY3NzTWFwcGluZy5zb3VyY2VSb290IHx8ICcnKS5jb25jYXQoc291cmNlLCBcIiAqL1wiKTtcbiAgICB9KTtcbiAgICByZXR1cm4gW2NvbnRlbnRdLmNvbmNhdChzb3VyY2VVUkxzKS5jb25jYXQoW3NvdXJjZU1hcHBpbmddKS5qb2luKCdcXG4nKTtcbiAgfVxuXG4gIHJldHVybiBbY29udGVudF0uam9pbignXFxuJyk7XG59IC8vIEFkYXB0ZWQgZnJvbSBjb252ZXJ0LXNvdXJjZS1tYXAgKE1JVClcblxuXG5mdW5jdGlvbiB0b0NvbW1lbnQoc291cmNlTWFwKSB7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bmRlZlxuICB2YXIgYmFzZTY0ID0gYnRvYSh1bmVzY2FwZShlbmNvZGVVUklDb21wb25lbnQoSlNPTi5zdHJpbmdpZnkoc291cmNlTWFwKSkpKTtcbiAgdmFyIGRhdGEgPSBcInNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ9dXRmLTg7YmFzZTY0LFwiLmNvbmNhdChiYXNlNjQpO1xuICByZXR1cm4gXCIvKiMgXCIuY29uY2F0KGRhdGEsIFwiICovXCIpO1xufSIsIlwidXNlIHN0cmljdFwiO1xuXG52YXIgaXNPbGRJRSA9IGZ1bmN0aW9uIGlzT2xkSUUoKSB7XG4gIHZhciBtZW1vO1xuICByZXR1cm4gZnVuY3Rpb24gbWVtb3JpemUoKSB7XG4gICAgaWYgKHR5cGVvZiBtZW1vID09PSAndW5kZWZpbmVkJykge1xuICAgICAgLy8gVGVzdCBmb3IgSUUgPD0gOSBhcyBwcm9wb3NlZCBieSBCcm93c2VyaGFja3NcbiAgICAgIC8vIEBzZWUgaHR0cDovL2Jyb3dzZXJoYWNrcy5jb20vI2hhY2stZTcxZDg2OTJmNjUzMzQxNzNmZWU3MTVjMjIyY2I4MDVcbiAgICAgIC8vIFRlc3RzIGZvciBleGlzdGVuY2Ugb2Ygc3RhbmRhcmQgZ2xvYmFscyBpcyB0byBhbGxvdyBzdHlsZS1sb2FkZXJcbiAgICAgIC8vIHRvIG9wZXJhdGUgY29ycmVjdGx5IGludG8gbm9uLXN0YW5kYXJkIGVudmlyb25tZW50c1xuICAgICAgLy8gQHNlZSBodHRwczovL2dpdGh1Yi5jb20vd2VicGFjay1jb250cmliL3N0eWxlLWxvYWRlci9pc3N1ZXMvMTc3XG4gICAgICBtZW1vID0gQm9vbGVhbih3aW5kb3cgJiYgZG9jdW1lbnQgJiYgZG9jdW1lbnQuYWxsICYmICF3aW5kb3cuYXRvYik7XG4gICAgfVxuXG4gICAgcmV0dXJuIG1lbW87XG4gIH07XG59KCk7XG5cbnZhciBnZXRUYXJnZXQgPSBmdW5jdGlvbiBnZXRUYXJnZXQoKSB7XG4gIHZhciBtZW1vID0ge307XG4gIHJldHVybiBmdW5jdGlvbiBtZW1vcml6ZSh0YXJnZXQpIHtcbiAgICBpZiAodHlwZW9mIG1lbW9bdGFyZ2V0XSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHZhciBzdHlsZVRhcmdldCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGFyZ2V0KTsgLy8gU3BlY2lhbCBjYXNlIHRvIHJldHVybiBoZWFkIG9mIGlmcmFtZSBpbnN0ZWFkIG9mIGlmcmFtZSBpdHNlbGZcblxuICAgICAgaWYgKHdpbmRvdy5IVE1MSUZyYW1lRWxlbWVudCAmJiBzdHlsZVRhcmdldCBpbnN0YW5jZW9mIHdpbmRvdy5IVE1MSUZyYW1lRWxlbWVudCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIC8vIFRoaXMgd2lsbCB0aHJvdyBhbiBleGNlcHRpb24gaWYgYWNjZXNzIHRvIGlmcmFtZSBpcyBibG9ja2VkXG4gICAgICAgICAgLy8gZHVlIHRvIGNyb3NzLW9yaWdpbiByZXN0cmljdGlvbnNcbiAgICAgICAgICBzdHlsZVRhcmdldCA9IHN0eWxlVGFyZ2V0LmNvbnRlbnREb2N1bWVudC5oZWFkO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgLy8gaXN0YW5idWwgaWdub3JlIG5leHRcbiAgICAgICAgICBzdHlsZVRhcmdldCA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgbWVtb1t0YXJnZXRdID0gc3R5bGVUYXJnZXQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIG1lbW9bdGFyZ2V0XTtcbiAgfTtcbn0oKTtcblxudmFyIHN0eWxlc0luRG9tID0gW107XG5cbmZ1bmN0aW9uIGdldEluZGV4QnlJZGVudGlmaWVyKGlkZW50aWZpZXIpIHtcbiAgdmFyIHJlc3VsdCA9IC0xO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc3R5bGVzSW5Eb20ubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoc3R5bGVzSW5Eb21baV0uaWRlbnRpZmllciA9PT0gaWRlbnRpZmllcikge1xuICAgICAgcmVzdWx0ID0gaTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmZ1bmN0aW9uIG1vZHVsZXNUb0RvbShsaXN0LCBvcHRpb25zKSB7XG4gIHZhciBpZENvdW50TWFwID0ge307XG4gIHZhciBpZGVudGlmaWVycyA9IFtdO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGlzdC5sZW5ndGg7IGkrKykge1xuICAgIHZhciBpdGVtID0gbGlzdFtpXTtcbiAgICB2YXIgaWQgPSBvcHRpb25zLmJhc2UgPyBpdGVtWzBdICsgb3B0aW9ucy5iYXNlIDogaXRlbVswXTtcbiAgICB2YXIgY291bnQgPSBpZENvdW50TWFwW2lkXSB8fCAwO1xuICAgIHZhciBpZGVudGlmaWVyID0gXCJcIi5jb25jYXQoaWQsIFwiIFwiKS5jb25jYXQoY291bnQpO1xuICAgIGlkQ291bnRNYXBbaWRdID0gY291bnQgKyAxO1xuICAgIHZhciBpbmRleCA9IGdldEluZGV4QnlJZGVudGlmaWVyKGlkZW50aWZpZXIpO1xuICAgIHZhciBvYmogPSB7XG4gICAgICBjc3M6IGl0ZW1bMV0sXG4gICAgICBtZWRpYTogaXRlbVsyXSxcbiAgICAgIHNvdXJjZU1hcDogaXRlbVszXVxuICAgIH07XG5cbiAgICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgICBzdHlsZXNJbkRvbVtpbmRleF0ucmVmZXJlbmNlcysrO1xuICAgICAgc3R5bGVzSW5Eb21baW5kZXhdLnVwZGF0ZXIob2JqKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc3R5bGVzSW5Eb20ucHVzaCh7XG4gICAgICAgIGlkZW50aWZpZXI6IGlkZW50aWZpZXIsXG4gICAgICAgIHVwZGF0ZXI6IGFkZFN0eWxlKG9iaiwgb3B0aW9ucyksXG4gICAgICAgIHJlZmVyZW5jZXM6IDFcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlkZW50aWZpZXJzLnB1c2goaWRlbnRpZmllcik7XG4gIH1cblxuICByZXR1cm4gaWRlbnRpZmllcnM7XG59XG5cbmZ1bmN0aW9uIGluc2VydFN0eWxlRWxlbWVudChvcHRpb25zKSB7XG4gIHZhciBzdHlsZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3N0eWxlJyk7XG4gIHZhciBhdHRyaWJ1dGVzID0gb3B0aW9ucy5hdHRyaWJ1dGVzIHx8IHt9O1xuXG4gIGlmICh0eXBlb2YgYXR0cmlidXRlcy5ub25jZSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICB2YXIgbm9uY2UgPSB0eXBlb2YgX193ZWJwYWNrX25vbmNlX18gIT09ICd1bmRlZmluZWQnID8gX193ZWJwYWNrX25vbmNlX18gOiBudWxsO1xuXG4gICAgaWYgKG5vbmNlKSB7XG4gICAgICBhdHRyaWJ1dGVzLm5vbmNlID0gbm9uY2U7XG4gICAgfVxuICB9XG5cbiAgT2JqZWN0LmtleXMoYXR0cmlidXRlcykuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gICAgc3R5bGUuc2V0QXR0cmlidXRlKGtleSwgYXR0cmlidXRlc1trZXldKTtcbiAgfSk7XG5cbiAgaWYgKHR5cGVvZiBvcHRpb25zLmluc2VydCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIG9wdGlvbnMuaW5zZXJ0KHN0eWxlKTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgdGFyZ2V0ID0gZ2V0VGFyZ2V0KG9wdGlvbnMuaW5zZXJ0IHx8ICdoZWFkJyk7XG5cbiAgICBpZiAoIXRhcmdldCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ291bGRuJ3QgZmluZCBhIHN0eWxlIHRhcmdldC4gVGhpcyBwcm9iYWJseSBtZWFucyB0aGF0IHRoZSB2YWx1ZSBmb3IgdGhlICdpbnNlcnQnIHBhcmFtZXRlciBpcyBpbnZhbGlkLlwiKTtcbiAgICB9XG5cbiAgICB0YXJnZXQuYXBwZW5kQ2hpbGQoc3R5bGUpO1xuICB9XG5cbiAgcmV0dXJuIHN0eWxlO1xufVxuXG5mdW5jdGlvbiByZW1vdmVTdHlsZUVsZW1lbnQoc3R5bGUpIHtcbiAgLy8gaXN0YW5idWwgaWdub3JlIGlmXG4gIGlmIChzdHlsZS5wYXJlbnROb2RlID09PSBudWxsKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgc3R5bGUucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChzdHlsZSk7XG59XG4vKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAgKi9cblxuXG52YXIgcmVwbGFjZVRleHQgPSBmdW5jdGlvbiByZXBsYWNlVGV4dCgpIHtcbiAgdmFyIHRleHRTdG9yZSA9IFtdO1xuICByZXR1cm4gZnVuY3Rpb24gcmVwbGFjZShpbmRleCwgcmVwbGFjZW1lbnQpIHtcbiAgICB0ZXh0U3RvcmVbaW5kZXhdID0gcmVwbGFjZW1lbnQ7XG4gICAgcmV0dXJuIHRleHRTdG9yZS5maWx0ZXIoQm9vbGVhbikuam9pbignXFxuJyk7XG4gIH07XG59KCk7XG5cbmZ1bmN0aW9uIGFwcGx5VG9TaW5nbGV0b25UYWcoc3R5bGUsIGluZGV4LCByZW1vdmUsIG9iaikge1xuICB2YXIgY3NzID0gcmVtb3ZlID8gJycgOiBvYmoubWVkaWEgPyBcIkBtZWRpYSBcIi5jb25jYXQob2JqLm1lZGlhLCBcIiB7XCIpLmNvbmNhdChvYmouY3NzLCBcIn1cIikgOiBvYmouY3NzOyAvLyBGb3Igb2xkIElFXG5cbiAgLyogaXN0YW5idWwgaWdub3JlIGlmICAqL1xuXG4gIGlmIChzdHlsZS5zdHlsZVNoZWV0KSB7XG4gICAgc3R5bGUuc3R5bGVTaGVldC5jc3NUZXh0ID0gcmVwbGFjZVRleHQoaW5kZXgsIGNzcyk7XG4gIH0gZWxzZSB7XG4gICAgdmFyIGNzc05vZGUgPSBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShjc3MpO1xuICAgIHZhciBjaGlsZE5vZGVzID0gc3R5bGUuY2hpbGROb2RlcztcblxuICAgIGlmIChjaGlsZE5vZGVzW2luZGV4XSkge1xuICAgICAgc3R5bGUucmVtb3ZlQ2hpbGQoY2hpbGROb2Rlc1tpbmRleF0pO1xuICAgIH1cblxuICAgIGlmIChjaGlsZE5vZGVzLmxlbmd0aCkge1xuICAgICAgc3R5bGUuaW5zZXJ0QmVmb3JlKGNzc05vZGUsIGNoaWxkTm9kZXNbaW5kZXhdKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc3R5bGUuYXBwZW5kQ2hpbGQoY3NzTm9kZSk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGFwcGx5VG9UYWcoc3R5bGUsIG9wdGlvbnMsIG9iaikge1xuICB2YXIgY3NzID0gb2JqLmNzcztcbiAgdmFyIG1lZGlhID0gb2JqLm1lZGlhO1xuICB2YXIgc291cmNlTWFwID0gb2JqLnNvdXJjZU1hcDtcblxuICBpZiAobWVkaWEpIHtcbiAgICBzdHlsZS5zZXRBdHRyaWJ1dGUoJ21lZGlhJywgbWVkaWEpO1xuICB9IGVsc2Uge1xuICAgIHN0eWxlLnJlbW92ZUF0dHJpYnV0ZSgnbWVkaWEnKTtcbiAgfVxuXG4gIGlmIChzb3VyY2VNYXAgJiYgYnRvYSkge1xuICAgIGNzcyArPSBcIlxcbi8qIyBzb3VyY2VNYXBwaW5nVVJMPWRhdGE6YXBwbGljYXRpb24vanNvbjtiYXNlNjQsXCIuY29uY2F0KGJ0b2EodW5lc2NhcGUoZW5jb2RlVVJJQ29tcG9uZW50KEpTT04uc3RyaW5naWZ5KHNvdXJjZU1hcCkpKSksIFwiICovXCIpO1xuICB9IC8vIEZvciBvbGQgSUVcblxuICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgICovXG5cblxuICBpZiAoc3R5bGUuc3R5bGVTaGVldCkge1xuICAgIHN0eWxlLnN0eWxlU2hlZXQuY3NzVGV4dCA9IGNzcztcbiAgfSBlbHNlIHtcbiAgICB3aGlsZSAoc3R5bGUuZmlyc3RDaGlsZCkge1xuICAgICAgc3R5bGUucmVtb3ZlQ2hpbGQoc3R5bGUuZmlyc3RDaGlsZCk7XG4gICAgfVxuXG4gICAgc3R5bGUuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoY3NzKSk7XG4gIH1cbn1cblxudmFyIHNpbmdsZXRvbiA9IG51bGw7XG52YXIgc2luZ2xldG9uQ291bnRlciA9IDA7XG5cbmZ1bmN0aW9uIGFkZFN0eWxlKG9iaiwgb3B0aW9ucykge1xuICB2YXIgc3R5bGU7XG4gIHZhciB1cGRhdGU7XG4gIHZhciByZW1vdmU7XG5cbiAgaWYgKG9wdGlvbnMuc2luZ2xldG9uKSB7XG4gICAgdmFyIHN0eWxlSW5kZXggPSBzaW5nbGV0b25Db3VudGVyKys7XG4gICAgc3R5bGUgPSBzaW5nbGV0b24gfHwgKHNpbmdsZXRvbiA9IGluc2VydFN0eWxlRWxlbWVudChvcHRpb25zKSk7XG4gICAgdXBkYXRlID0gYXBwbHlUb1NpbmdsZXRvblRhZy5iaW5kKG51bGwsIHN0eWxlLCBzdHlsZUluZGV4LCBmYWxzZSk7XG4gICAgcmVtb3ZlID0gYXBwbHlUb1NpbmdsZXRvblRhZy5iaW5kKG51bGwsIHN0eWxlLCBzdHlsZUluZGV4LCB0cnVlKTtcbiAgfSBlbHNlIHtcbiAgICBzdHlsZSA9IGluc2VydFN0eWxlRWxlbWVudChvcHRpb25zKTtcbiAgICB1cGRhdGUgPSBhcHBseVRvVGFnLmJpbmQobnVsbCwgc3R5bGUsIG9wdGlvbnMpO1xuXG4gICAgcmVtb3ZlID0gZnVuY3Rpb24gcmVtb3ZlKCkge1xuICAgICAgcmVtb3ZlU3R5bGVFbGVtZW50KHN0eWxlKTtcbiAgICB9O1xuICB9XG5cbiAgdXBkYXRlKG9iaik7XG4gIHJldHVybiBmdW5jdGlvbiB1cGRhdGVTdHlsZShuZXdPYmopIHtcbiAgICBpZiAobmV3T2JqKSB7XG4gICAgICBpZiAobmV3T2JqLmNzcyA9PT0gb2JqLmNzcyAmJiBuZXdPYmoubWVkaWEgPT09IG9iai5tZWRpYSAmJiBuZXdPYmouc291cmNlTWFwID09PSBvYmouc291cmNlTWFwKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdXBkYXRlKG9iaiA9IG5ld09iaik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlbW92ZSgpO1xuICAgIH1cbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAobGlzdCwgb3B0aW9ucykge1xuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTsgLy8gRm9yY2Ugc2luZ2xlLXRhZyBzb2x1dGlvbiBvbiBJRTYtOSwgd2hpY2ggaGFzIGEgaGFyZCBsaW1pdCBvbiB0aGUgIyBvZiA8c3R5bGU+XG4gIC8vIHRhZ3MgaXQgd2lsbCBhbGxvdyBvbiBhIHBhZ2VcblxuICBpZiAoIW9wdGlvbnMuc2luZ2xldG9uICYmIHR5cGVvZiBvcHRpb25zLnNpbmdsZXRvbiAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgb3B0aW9ucy5zaW5nbGV0b24gPSBpc09sZElFKCk7XG4gIH1cblxuICBsaXN0ID0gbGlzdCB8fCBbXTtcbiAgdmFyIGxhc3RJZGVudGlmaWVycyA9IG1vZHVsZXNUb0RvbShsaXN0LCBvcHRpb25zKTtcbiAgcmV0dXJuIGZ1bmN0aW9uIHVwZGF0ZShuZXdMaXN0KSB7XG4gICAgbmV3TGlzdCA9IG5ld0xpc3QgfHwgW107XG5cbiAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG5ld0xpc3QpICE9PSAnW29iamVjdCBBcnJheV0nKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsYXN0SWRlbnRpZmllcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBpZGVudGlmaWVyID0gbGFzdElkZW50aWZpZXJzW2ldO1xuICAgICAgdmFyIGluZGV4ID0gZ2V0SW5kZXhCeUlkZW50aWZpZXIoaWRlbnRpZmllcik7XG4gICAgICBzdHlsZXNJbkRvbVtpbmRleF0ucmVmZXJlbmNlcy0tO1xuICAgIH1cblxuICAgIHZhciBuZXdMYXN0SWRlbnRpZmllcnMgPSBtb2R1bGVzVG9Eb20obmV3TGlzdCwgb3B0aW9ucyk7XG5cbiAgICBmb3IgKHZhciBfaSA9IDA7IF9pIDwgbGFzdElkZW50aWZpZXJzLmxlbmd0aDsgX2krKykge1xuICAgICAgdmFyIF9pZGVudGlmaWVyID0gbGFzdElkZW50aWZpZXJzW19pXTtcblxuICAgICAgdmFyIF9pbmRleCA9IGdldEluZGV4QnlJZGVudGlmaWVyKF9pZGVudGlmaWVyKTtcblxuICAgICAgaWYgKHN0eWxlc0luRG9tW19pbmRleF0ucmVmZXJlbmNlcyA9PT0gMCkge1xuICAgICAgICBzdHlsZXNJbkRvbVtfaW5kZXhdLnVwZGF0ZXIoKTtcblxuICAgICAgICBzdHlsZXNJbkRvbS5zcGxpY2UoX2luZGV4LCAxKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBsYXN0SWRlbnRpZmllcnMgPSBuZXdMYXN0SWRlbnRpZmllcnM7XG4gIH07XG59OyIsImNvbnN0IGVtb2ppQ29tcGFzcyA9IHJlcXVpcmUoXCIuLi9hc3NldHMvMUY5RUQuc3ZnXCIpO1xucmVxdWlyZShcIi4vQ29tcGFzcy5zY3NzXCIpO1xuXG5jb25zdCBERUZBVUxUUyA9IHtcbiAgZW1vamlDb21wYXNzOiBlbW9qaUNvbXBhc3MsXG59O1xuXG5jbGFzcyBDb21wYXNzIHtcbiAgLyoqXG4gICAqIFRoZSBjb21wYXNzIGNsYXNzIGlzIGEgdXRpbGl0eSBmb3IgY3JlYXRpbmcgYSBqYXZhc2NyaXB0IGNvbXBhc3NcbiAgICogd2l0aCBubyBleHRlcm5hbCBkZXBlbmRlbmNpZXMuIFlvdSBjYW4gY3JlYXRlIGEgY29tcGFzcyB0aGF0XG4gICAqIHBvaW50cyBub3J0aCBmcm9tIHlvdXIgbG9jYXRpb24gb3IgcG9pbnRzIHRvd2FyZHMgYSBzcGVjaWZpZWRcbiAgICogbGF0aXR1ZGUgYW5kIGxvbmdpdHVkZSBjb29yZGluYXRlLiBSZWdhcmRsZXNzIG9mIHdoZXJlIHlvdSB0dXJuXG4gICAqIHRoZSBjb21wYXNzIHdpbGwgcG9pbnQgdG93YXJkcyB0aGUgc3BlY2lmaWVkIGRpcmVjdGlvbi5cbiAgICpcbiAgICogQGNsYXNzXG4gICAqL1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLmhlYWRpbmcgPSAwO1xuICAgIHRoaXMuZGV2aWNlQW5nbGVEZWx0YSA9IDA7XG4gICAgdGhpcy5wb3NpdGlvbiA9IG51bGw7XG4gICAgdGhpcy5idXR0b24gPSBudWxsO1xuICAgIHRoaXMuZGVidWcgPSB0cnVlO1xuXG4gICAgdGhpcy5nZW9sb2NhdGlvbklEID0gbnVsbDtcbiAgICB0aGlzLnBlcm1pc3Npb25HcmFudGVkID0gZmFsc2U7XG4gIH1cblxuICAvKipcbiAgICogaW5pdGlhbGl6ZWQgdGhlIGNvbXBhc3MgLSByZXR1cm5zIGEgcHJvbWlzZSBvciBjYW4gaW52b2tlIGEgY2FsbGJhY2tcbiAgICogQHBhcmFtIHtjYWxsYmFja30gY2FsbGJhY2sgLSBjYWxsYmFjayB0byBiZSBjYWxsZWQgYWZ0ZXIgdGhlIC5zdGFydCgpIGZ1bmN0aW9uIGlzIGRvbmVcbiAgICovXG4gIGluaXQoY2FsbGJhY2sgPSB1bmRlZmluZWQpIHtcbiAgICBpZiAoY2FsbGJhY2spIHtcbiAgICAgIHRoaXMuY2FsbENhbGxiYWNrKHRoaXMuc3RhcnQoKSwgY2FsbGJhY2spO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5zdGFydCgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBJbml0aWFsaXplcyB0aGUgZGV2aWNlIG9yaWVudGF0aW9uIGFuZCB3YXRjaGVzIHRoZSB1c2VyIHBvc2l0aW9uIGJ5IGRlZmF1bHRcbiAgICogQGFzeW5jXG4gICAqIEBmdW5jdGlvbiBzdGFydFxuICAgKlxuICAgKi9cbiAgYXN5bmMgc3RhcnQoKSB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMud2F0Y2hQb3NpdGlvbigpO1xuXG4gICAgICBpZiAodGhpcy5kZWJ1ZyA9PT0gdHJ1ZSkge1xuICAgICAgICB0aGlzLmNyZWF0ZUJ1dHRvbigpO1xuICAgICAgICB0aGlzLmJ1dHRvbi5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICAgIFwiY2xpY2tcIixcbiAgICAgICAgICB0aGlzLnRyaWdnZXJEZXZpY2VPcmllbnRhdGlvblBlcm1pc3Npb25zKClcbiAgICAgICAgKTtcbiAgICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZCh0aGlzLmJ1dHRvbik7XG4gICAgICB9XG4gICAgICAvLyBOT1RFOiBpZiBkZWJ1ZyBpcyBmYWxzZSwgdGhlIGV4cGVjdGF0aW9uIGlzIHRoYXQgeW91IGhhbmRsZSB0aGVcbiAgICAgIC8vIHRoZSBkZXZpY2Ugb3JpZW50YXRpb24gaGFuZGxpbmcgcGVybWlzc2lvbnMgb24geW91ciBvd24uXG5cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgYWxlcnQoZXJyKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogY3JlYXRlcyBhIGJ1dHRvbiB0byB0cmlnZ2VyIHRoZSBkZXZpY2Ugb3JpZW50YXRpb24gcGVybWlzc2lvbnNcbiAgICpcbiAgICogZnVuY3Rpb25cbiAgICogQG5hbWUgY3JlYXRlQnV0dG9uXG4gICAqL1xuICBjcmVhdGVCdXR0b24oKSB7XG4gICAgY29uc3QgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICBkaXYuaW5uZXJIVE1MICs9IGVtb2ppQ29tcGFzcztcbiAgICB0aGlzLmJ1dHRvbiA9IGRpdi5xdWVyeVNlbGVjdG9yKFwiI2Vtb2ppX19jb21wYXNzXCIpO1xuICB9XG5cbiAgLyoqXG4gICAqIHRyaWdnZXJzIHRoZSBkZXZpY2Ugb3JpZW50YXRpb24gcGVybWlzc2lvbnNcbiAgICogQGZ1bmN0aW9uXG4gICAqIEBuYW1lIHRyaWdnZXJEZXZpY2VPcmllbnRhdGlvblBlcm1pc3Npb25zXG4gICAqL1xuICB0cmlnZ2VyRGV2aWNlT3JpZW50YXRpb25QZXJtaXNzaW9ucygpIHtcbiAgICByZXR1cm4gYXN5bmMgKGV2dCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdGhpcy5hbGxvd09yaWVudGF0aW9uUGVybWlzc2lvbnMoKTtcbiAgICAgICAgaWYgKHRoaXMuZGVidWcgPT09IHRydWUpIHtcbiAgICAgICAgICB0aGlzLmJ1dHRvbi5zdHlsZS5kaXNwbGF5ID0gXCJub25lXCI7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBhbGVydChlcnIpO1xuICAgICAgfVxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQXNrcyB0aGUgdXNlciB0byBhbGxvdyBwZXJtaXNzaW9ucyB0byBnZXQgb3JpZW50YXRpb25cbiAgICpcbiAgICogQGFzeW5jXG4gICAqIEBuYW1lIGFsbG93T3JpZW50YXRpb25QZXJtaXNzaW9uc1xuICAgKi9cbiAgYXN5bmMgYWxsb3dPcmllbnRhdGlvblBlcm1pc3Npb25zKCkge1xuICAgIGlmICh0eXBlb2Ygd2luZG93LkRldmljZU9yaWVudGF0aW9uRXZlbnQucmVxdWVzdFBlcm1pc3Npb24gPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgY29uc3QgcGVybWlzc2lvbiA9IGF3YWl0IHdpbmRvdy5EZXZpY2VPcmllbnRhdGlvbkV2ZW50LnJlcXVlc3RQZXJtaXNzaW9uKCk7XG4gICAgICBhbGVydChwZXJtaXNzaW9uKTtcbiAgICAgIGlmIChwZXJtaXNzaW9uID09IFwiZ3JhbnRlZFwiKSB7XG4gICAgICAgIHRoaXMucGVybWlzc2lvbkdyYW50ZWQgPSB0cnVlO1xuICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgICBcImRldmljZW9yaWVudGF0aW9uXCIsXG4gICAgICAgICAgdGhpcy5kZXZpY2VPcmllbnRhdGlvbkhhbmRsZXIuYmluZCh0aGlzKSxcbiAgICAgICAgICB0cnVlXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwibm8gZGV2aWNlIG9yaWVudGF0aW9uIHBlcm1pc3Npb25zIVwiKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHdpbmRvdy5EZXZpY2VPcmllbnRhdGlvbkV2ZW50KSB7XG4gICAgICAgIHRoaXMucGVybWlzc2lvbkdyYW50ZWQgPSB0cnVlO1xuICAgICAgICBhbGVydChcImRldmljZSBvcmllbnRhdGlvbiBwZXJtaXNzaW9uIGdyYW50ZWRcIik7XG4gICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICAgIFwiZGV2aWNlb3JpZW50YXRpb25cIixcbiAgICAgICAgICB0aGlzLmRldmljZU9yaWVudGF0aW9uSGFuZGxlci5iaW5kKHRoaXMpLFxuICAgICAgICAgIHRydWVcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhbGVydChcIm5vIGRldmljZSBvcmllbnRhdGlvbiBzdXBwb3J0XCIpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBUaGlzIGlzIHdoZXJlIG15IG5vc2UgcG9pbnRzIC0gYW5kIHNlZWluZyBhcyBteSBub3NlXG4gICAqIGlzIGF0dGFjaGVkIHRvIG15IGhlYWQsIHRoaXMgaXMgd2hlcmUgbXkgaGVhZFxuICAgKiAoYW5kIHRodXMgbXkgbWFjaGluZSkgaXMgcG9pbnRpbmcgcmVsYXRpdmUgdG8gTm9ydGguXG4gICAqIE5PVEU6IHJlcXVpcmVzIHRoYXQgdGhpcy5wb3NpdGlvbiBpcyBzZXRcbiAgICpcbiAgICogQGZ1bmN0aW9uIGdldEhlYWRpbmdcbiAgICovXG4gIGdldEhlYWRpbmcoXG4gICAgb3JpZ2luID0ge1xuICAgICAgbGF0OiB0aGlzLnBvc2l0aW9uLmNvb3Jkcy5sYXRpdHVkZSxcbiAgICAgIGxuZzogdGhpcy5wb3NpdGlvbi5jb29yZHMubG9uZ2l0dWRlLFxuICAgIH0sXG4gICAgbm9ydGggPSB7IGxhdDogOTAsIGxuZzogdGhpcy5wb3NpdGlvbi5jb29yZHMubG9uZ2l0dWRlIH1cbiAgKSB7XG4gICAgdGhpcy5oZWFkaW5nID0gMzYwIC0gdGhpcy5nZXRCZWFyaW5nVG9Ob3J0aChvcmlnaW4sIG5vcnRoKTtcbiAgICByZXR1cm4gdGhpcy5oZWFkaW5nO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoaXMgaXMgdGhlIGFuZ2xlIGJldHdlZW4gdGhlIGxvY2F0aW9uIG9mIGFuIG9iamVjdCxcbiAgICogbWFjaGluZSBvciBkZXN0aW5hdGlvbiBhbmQgbXkgaGVhZGluZy5cbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IG9yaWdpbiAtIHtsYXQsIGxuZ31cbiAgICogQHBhcmFtIHtPYmplY3R9IGRlc3RpbmF0aW9uIC0ge2xhdCwgbG5nfVxuICAgKi9cbiAgZ2V0QmVhcmluZyhvcmlnaW4sIGRlc3RpbmF0aW9uKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIHRoaXMuY2FsY3VsYXRlQW5nbGUoXG4gICAgICAgIG9yaWdpbi5sYXQsXG4gICAgICAgIG9yaWdpbi5sbmcsXG4gICAgICAgIGRlc3RpbmF0aW9uLmxhdCxcbiAgICAgICAgZGVzdGluYXRpb24ubG5nXG4gICAgICApICpcbiAgICAgICgxODAgLyBNYXRoLlBJKVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogZ2V0IHRoZSBhbmdsZSBiZXR3ZWVuIHlvdXIgaGVhZGluZyBhbmQgbm9ydGhcbiAgICogdGhlIGRlZmF1bHQgaXMgdHJ1ZSBub3J0aCB2cy4gbWFnbmV0aWMgbm9ydGhcbiAgICpcbiAgICogQGZ1bmN0aW9uXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBvcmlnaW4gLSB7bGF0LCBsbmd9XG4gICAqIEBwYXJhbSB7b2JqZWN0fSBub3J0aCAtIHtsYXQsIGxuZ31cbiAgICovXG4gIGdldEJlYXJpbmdUb05vcnRoKFxuICAgIG9yaWdpbiA9IHtcbiAgICAgIGxhdDogdGhpcy5wb3NpdGlvbi5jb29yZHMubGF0aXR1ZGUsXG4gICAgICBsbmc6IHRoaXMucG9zaXRpb24uY29vcmRzLmxvbmdpdHVkZSxcbiAgICB9LFxuICAgIG5vcnRoID0geyBsYXQ6IDkwLCBsbmc6IHRoaXMucG9zaXRpb24uY29vcmRzLmxvbmdpdHVkZSB9XG4gICkge1xuICAgIHJldHVybiB0aGlzLmdldEJlYXJpbmdUb0Rlc3RpbmF0aW9uKG9yaWdpbiwgbm9ydGgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgYmVhcmluZ3MgdG93YXJkcyB0aGUgZGVzdGluYXRpb25cbiAgICpcbiAgICogQHBhcmFtIHtvYmplY3R9IG9yaWdpbiAtIHtsYXQsIGxuZ31cbiAgICogQHBhcmFtIHtvYmplY3R9IGRlc3RpbmF0aW9uIC0ge2xhdCwgbG5nfVxuICAgKi9cbiAgZ2V0QmVhcmluZ1RvRGVzdGluYXRpb24oXG4gICAgb3JpZ2luID0ge1xuICAgICAgbGF0OiB0aGlzLnBvc2l0aW9uLmNvb3Jkcy5sYXRpdHVkZSxcbiAgICAgIGxuZzogdGhpcy5wb3NpdGlvbi5jb29yZHMubG9uZ2l0dWRlLFxuICAgIH0sXG4gICAgZGVzdGluYXRpb25cbiAgKSB7XG4gICAgY29uc3QgYW5nbGVUb0Rlc3RpbmF0aW9uID0gdGhpcy5nZXRCZWFyaW5nKG9yaWdpbiwgZGVzdGluYXRpb24pO1xuICAgIHJldHVybiB0aGlzLmRldmljZUFuZ2xlRGVsdGEgKyBhbmdsZVRvRGVzdGluYXRpb247XG4gIH1cblxuICAvKipcbiAgICogSGFuZGxlcyBjaGFuZ2VzIGNyZWF0ZWQgYnkgdGhlIGRldmljZSBvcmllbnRhdGlvbiBjaGFuZ2VzXG4gICAqIGFzc3VtZXMgdGhhdCB0aGUgcGhvbmUgaXMgaW4gYSBwb3J0cmFpdCBtb2RlLCB3aXRoIHRoZSBkaXNwbGF5IHVwXG4gICAqIHRvd2FyZHMgdGhlIHNreSBhcyBpZiB5b3Ugd2VyZSBob2xkaW5nIGFuIGFjdHVhbCBjb21wYXNzXG4gICAqXG4gICAqIEBjYWxsYmFja1xuICAgKiBAcGFyYW0ge29iamVjdH0gZXZ0IC0gdGhlIGV2ZW50IG9iamVjdCBvZiB0aGUgZGV2aWNlIG9yaWVudGF0aW9uXG4gICAqL1xuICBkZXZpY2VPcmllbnRhdGlvbkhhbmRsZXIoZXZ0KSB7XG4gICAgaWYgKGV2dC53ZWJraXRDb21wYXNzSGVhZGluZylcbiAgICAgIC8vaXBob25lXG4gICAgICB0aGlzLmRldmljZUFuZ2xlRGVsdGEgPSAzNjAgLSBldnQud2Via2l0Q29tcGFzc0hlYWRpbmc7XG4gICAgZWxzZSBpZiAoZXZ0LmFscGhhKVxuICAgICAgLy9hbmRyb2lkXG4gICAgICB0aGlzLmRldmljZUFuZ2xlRGVsdGEgPSBldnQuYWxwaGE7XG4gICAgZWxzZSB7XG4gICAgICBjb25zb2xlLmxvZyhcImNvbXBhc3MgZGlyZWN0aW9uIG5vdCBmb3VuZFwiKTtcbiAgICB9XG5cbiAgICAvLyBjb25zb2xlLmxvZyh0aGlzLmRldmljZUFuZ2xlRGVsdGEpXG4gICAgdGhpcy5kZXZpY2VBbmdsZURlbHRhID0gTWF0aC5yb3VuZCh0aGlzLmRldmljZUFuZ2xlRGVsdGEpO1xuICB9XG5cbiAgLyoqXG4gICAqIGdldCB0aGUgcG9zaXRpb24gb2YgdGhlIHVzZXJcbiAgICpcbiAgICogQGFzeW5jXG4gICAqIEBmdW5jdGlvblxuICAgKi9cbiAgZ2V0UG9zaXRpb24oKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIG5hdmlnYXRvci5nZW9sb2NhdGlvbi5nZXRDdXJyZW50UG9zaXRpb24oKHBvc2l0aW9uKSA9PiB7XG4gICAgICAgIGlmIChwb3NpdGlvbikge1xuICAgICAgICAgIHJlc29sdmUocG9zaXRpb24pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJlamVjdChcIm5vIHBvc2l0aW9uIGZvdW5kXCIpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiB3YXRjaGVzIHRoZSBnZW9sb2NhdGlvbiBvZiB0aGUgdXNlclxuICAgKlxuICAgKiBAYXN5bmNcbiAgICogQGZ1bmN0aW9uXG4gICAqL1xuICB3YXRjaFBvc2l0aW9uKCkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmdlb2xvY2F0aW9uSUQgPSBuYXZpZ2F0b3IuZ2VvbG9jYXRpb24ud2F0Y2hQb3NpdGlvbigocG9zaXRpb24pID0+IHtcbiAgICAgICAgaWYgKHBvc2l0aW9uKSB7XG4gICAgICAgICAgdGhpcy5wb3NpdGlvbiA9IHBvc2l0aW9uO1xuICAgICAgICAgIC8vIGNvbnNvbGUubG9nKFxuICAgICAgICAgIC8vICAgdGhpcy5wb3NpdGlvbi5jb29yZHMubGF0aXR1ZGUsXG4gICAgICAgICAgLy8gICB0aGlzLnBvc2l0aW9uLmNvb3Jkcy5sb25naXR1ZGVcbiAgICAgICAgICAvLyApO1xuICAgICAgICAgIHJlc29sdmUocG9zaXRpb24pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJlamVjdChcIm5vIHBvc2l0aW9uIGZvdW5kXCIpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdG9wcyB3YXRjaGluZyB0aGUgdXNlciBsb2NhdGlvblxuICAgKlxuICAgKiBAZnVuY3Rpb25cbiAgICovXG4gIHN0b3BUcmFja2luZygpIHtcbiAgICBuYXZpZ2F0b3IuZ2VvbG9jYXRpb24uY2xlYXJXYXRjaCh0aGlzLmdlb2xvY2F0aW9uSUQpO1xuICAgIGNvbnNvbGUubG9nKFwic3RvcHBlZCB0cmFja2luZyBsb2NhdGlvblwiKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxjdWxhdGVzIHRoZSBhbmdsZSBnaXZlbiBhIGxhdGl0dWRlIGFuZCBsb25naXR1ZGUgcG9zaXRpb25cbiAgICpcbiAgICogQGZ1bmN0aW9uXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB1c2VyTGF0IC0gdXNlciBsYXRpdHVkZVxuICAgKiBAcGFyYW0ge251bWJlcn0gdXNlckxvbiAtIHVzZXIgbG9uZ2l0dWRlXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBkZXNpcmVkTGF0IC0gZGVzaXJlZCBsYXRpdHVkZVxuICAgKiBAcGFyYW0ge251bWJlcn0gZGVzaXJlZExvbiAtIGRlc2lyZWQgbG9uZ2l0dWRlXG4gICAqL1xuICBjYWxjdWxhdGVBbmdsZSh1c2VyTGF0LCB1c2VyTG9uLCBkZXNpcmVkTGF0LCBkZXNpcmVkTG9uKSB7XG4gICAgcmV0dXJuIE1hdGguYXRhbjIoZGVzaXJlZExvbiAtIHVzZXJMb24sIGRlc2lyZWRMYXQgLSB1c2VyTGF0KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBIZWxwZXIgZnVuY3Rpb24gdGhhdCBhbGxvd3MgY2FsbGluZyBhIGNhbGxiYWNrIGZyb20gYW4gcHJvbWlzZSBmdW5jdGlvblxuICAgKlxuICAgKiBAcGFyYW0ge3Byb21pc2V9IHByb21pc2VcbiAgICogQHBhcmFtIHtjYWxsYmFja30gY2FsbGJhY2tcbiAgICovXG4gIGNhbGxDYWxsYmFjayhwcm9taXNlLCBjYWxsYmFjaykge1xuICAgIGlmIChjYWxsYmFjaykge1xuICAgICAgcHJvbWlzZVxuICAgICAgICAudGhlbigocmVzdWx0KSA9PiB7XG4gICAgICAgICAgY2FsbGJhY2sodW5kZWZpbmVkLCByZXN1bHQpO1xuICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICBjYWxsYmFjayhlcnJvcik7XG4gICAgICAgICAgcmV0dXJuIGVycm9yO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHByb21pc2U7XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBDb21wYXNzO1xuIiwidmFyIGFwaSA9IHJlcXVpcmUoXCIhLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvaW5qZWN0U3R5bGVzSW50b1N0eWxlVGFnLmpzXCIpO1xuICAgICAgICAgICAgdmFyIGNvbnRlbnQgPSByZXF1aXJlKFwiISEuLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9kaXN0L2Nqcy5qcyEuLi8uLi9ub2RlX21vZHVsZXMvc2Fzcy1sb2FkZXIvZGlzdC9janMuanMhLi9Db21wYXNzLnNjc3NcIik7XG5cbiAgICAgICAgICAgIGNvbnRlbnQgPSBjb250ZW50Ll9fZXNNb2R1bGUgPyBjb250ZW50LmRlZmF1bHQgOiBjb250ZW50O1xuXG4gICAgICAgICAgICBpZiAodHlwZW9mIGNvbnRlbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgIGNvbnRlbnQgPSBbW21vZHVsZS5pZCwgY29udGVudCwgJyddXTtcbiAgICAgICAgICAgIH1cblxudmFyIG9wdGlvbnMgPSB7fTtcblxub3B0aW9ucy5pbnNlcnQgPSBcImhlYWRcIjtcbm9wdGlvbnMuc2luZ2xldG9uID0gZmFsc2U7XG5cbnZhciB1cGRhdGUgPSBhcGkoY29udGVudCwgb3B0aW9ucyk7XG5cblxuXG5tb2R1bGUuZXhwb3J0cyA9IGNvbnRlbnQubG9jYWxzIHx8IHt9OyIsIm1vZHVsZS5leHBvcnRzID0gXCI8c3ZnIGlkPVxcXCJlbW9qaV9fY29tcGFzc1xcXCIgdmlld0JveD1cXFwiMCAwIDcyIDcyXFxcIiB4bWxucz1cXFwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcXFwiPjxnIGlkPVxcXCJsaW5lLXN1cHBsZW1lbnRcXFwiPjxwb2x5bGluZSBwb2ludHM9XFxcIjMzLjIgMzMuMiA0OCAyNCAzOC44IDM4LjhcXFwiPjwvcG9seWxpbmU+PC9nPjxnIGlkPVxcXCJsaW5lXFxcIj48Y2lyY2xlIGN4PVxcXCIzNlxcXCIgY3k9XFxcIjM2XFxcIiByPVxcXCIyNFxcXCIgZmlsbD1cXFwibm9uZVxcXCIgc3Ryb2tlPVxcXCIjMDAwXFxcIiBzdHJva2UtbGluZWNhcD1cXFwicm91bmRcXFwiIHN0cm9rZS1saW5lam9pbj1cXFwicm91bmRcXFwiIHN0cm9rZS13aWR0aD1cXFwiMlxcXCI+PC9jaXJjbGU+PHBvbHlsaW5lIGZpbGw9XFxcIm5vbmVcXFwiIHN0cm9rZT1cXFwiIzAwMFxcXCIgc3Ryb2tlLWxpbmVjYXA9XFxcInJvdW5kXFxcIiBzdHJva2UtbGluZWpvaW49XFxcInJvdW5kXFxcIiBzdHJva2Utd2lkdGg9XFxcIjJcXFwiIHBvaW50cz1cXFwiMzMuMiAzMy4yIDI0IDQ4IDM4LjggMzguOFxcXCI+PC9wb2x5bGluZT48cG9seWxpbmUgZmlsbD1cXFwibm9uZVxcXCIgc3Ryb2tlPVxcXCIjMDAwXFxcIiBzdHJva2UtbGluZWNhcD1cXFwicm91bmRcXFwiIHN0cm9rZS1saW5lam9pbj1cXFwicm91bmRcXFwiIHN0cm9rZS13aWR0aD1cXFwiMlxcXCIgcG9pbnRzPVxcXCIzMy4yIDMzLjIgNDggMjQgMzguOCAzOC44XFxcIj48L3BvbHlsaW5lPjxsaW5lIHgxPVxcXCIzNlxcXCIgeDI9XFxcIjM2XFxcIiB5MT1cXFwiMjFcXFwiIHkyPVxcXCIxNlxcXCIgZmlsbD1cXFwibm9uZVxcXCIgc3Ryb2tlPVxcXCIjMDAwXFxcIiBzdHJva2UtbGluZWNhcD1cXFwicm91bmRcXFwiIHN0cm9rZS1saW5lam9pbj1cXFwicm91bmRcXFwiIHN0cm9rZS13aWR0aD1cXFwiMlxcXCI+PC9saW5lPjxsaW5lIHgxPVxcXCIzNlxcXCIgeDI9XFxcIjM2XFxcIiB5MT1cXFwiNTZcXFwiIHkyPVxcXCI1MVxcXCIgZmlsbD1cXFwibm9uZVxcXCIgc3Ryb2tlPVxcXCIjMDAwXFxcIiBzdHJva2UtbGluZWNhcD1cXFwicm91bmRcXFwiIHN0cm9rZS1saW5lam9pbj1cXFwicm91bmRcXFwiIHN0cm9rZS13aWR0aD1cXFwiMlxcXCI+PC9saW5lPjxsaW5lIHgxPVxcXCI1MVxcXCIgeDI9XFxcIjU2XFxcIiB5MT1cXFwiMzZcXFwiIHkyPVxcXCIzNlxcXCIgZmlsbD1cXFwibm9uZVxcXCIgc3Ryb2tlPVxcXCIjMDAwXFxcIiBzdHJva2UtbGluZWNhcD1cXFwicm91bmRcXFwiIHN0cm9rZS1saW5lam9pbj1cXFwicm91bmRcXFwiIHN0cm9rZS13aWR0aD1cXFwiMlxcXCI+PC9saW5lPjxsaW5lIHgxPVxcXCIxNlxcXCIgeDI9XFxcIjIxXFxcIiB5MT1cXFwiMzZcXFwiIHkyPVxcXCIzNlxcXCIgZmlsbD1cXFwibm9uZVxcXCIgc3Ryb2tlPVxcXCIjMDAwXFxcIiBzdHJva2UtbGluZWNhcD1cXFwicm91bmRcXFwiIHN0cm9rZS1saW5lam9pbj1cXFwicm91bmRcXFwiIHN0cm9rZS13aWR0aD1cXFwiMlxcXCI+PC9saW5lPjwvZz48L3N2Zz5cIiIsImNvbnN0IGMgPSByZXF1aXJlKCcuL0NvbXBhc3MvQ29tcGFzcy5qcycpO1xubW9kdWxlLmV4cG9ydHMgPSBjOyJdLCJzb3VyY2VSb290IjoiIn0=

Back to list