kepler.gl.geoiq
Version:
kepler.gl is a webgl based application to visualize large scale location data in the browser
551 lines (462 loc) • 62.6 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
var _window = _interopRequireDefault(require("global/window"));
var _document = _interopRequireDefault(require("global/document"));
var _console = _interopRequireDefault(require("global/console"));
var _miniSvgDataUri = _interopRequireDefault(require("mini-svg-data-uri"));
var _userFeedbacks = require("../constants/user-feedbacks");
var _domUtils = require("./dom-utils");
// Copyright (c) 2023 Uber Technologies, Inc.
//
// 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.
/**
* This file is copied from https://github.com/tsayen/dom-to-image
* Modified by heshan0131 to allow loading external stylesheets and inline webfonts
*/
var inliner = newInliner();
var fontFaces = newFontFaces();
var images = newImages(); // Default impl options
var defaultOptions = {
// Default is to fail on error, no placeholder
imagePlaceholder: undefined,
// Default cache bust is false, it will use the cache
cacheBust: false
};
var domtoimage = {
toSvg: toSvg,
toPng: toPng,
toJpeg: toJpeg,
toBlob: toBlob,
toPixelData: toPixelData,
impl: {
fontFaces: fontFaces,
images: images,
inliner: inliner,
options: {}
}
};
/**
* @param {Node} node - The DOM Node object to render
* @param {Object} options - Rendering options
* @param {Function} options.filter - Should return true if passed node should be included in the output
* (excluding node means excluding it's children as well). Not called on the root node.
* @param {String} options.bgcolor - color for the background, any valid CSS color value.
* @param {Number} options.width - width to be applied to node before rendering.
* @param {Number} options.height - height to be applied to node before rendering.
* @param {Object} options.style - an object whose properties to be copied to node's style before rendering.
* @param {Number} options.quality - a Number between 0 and 1 indicating image quality (applicable to JPEG only),
defaults to 1.0.
* @param {String} options.imagePlaceholder - dataURL to use as a placeholder for failed images, default behaviour is to fail fast on images we can't fetch
* @param {Boolean} options.cacheBust - set to true to cache bust by appending the time to the request url
* @return {Promise} - A promise that is fulfilled with a SVG image data URL
* */
function toSvg(node, options) {
options = options || {};
copyOptions(options);
return Promise.resolve(node).then(function (nd) {
return cloneNode(nd, options.filter, true);
}).then(embedFonts).then(inlineImages).then(applyOptions).then(function (clone) {
return makeSvgDataUri(clone, options.width || (0, _domUtils.getWidth)(node), options.height || (0, _domUtils.getHeight)(node));
});
function applyOptions(clone) {
if (options.bgcolor) clone.style.backgroundColor = options.bgcolor;
if (options.width) clone.style.width = "".concat(options.width, "px");
if (options.height) clone.style.height = "".concat(options.height, "px");
if (options.style) Object.keys(options.style).forEach(function (property) {
clone.style[property] = options.style[property];
});
return clone;
}
}
/**
* @param {Node} node - The DOM Node object to render
* @param {Object} options - Rendering options, @see {@link toSvg}
* @return {Promise} - A promise that is fulfilled with a Uint8Array containing RGBA pixel data.
* */
function toPixelData(node, options) {
return draw(node, options || {}).then(function (canvas) {
return canvas.getContext('2d').getImageData(0, 0, (0, _domUtils.getWidth)(node), (0, _domUtils.getHeight)(node)).data;
});
}
/**
* @param {Node} node - The DOM Node object to render
* @param {Object} options - Rendering options, @see {@link toSvg}
* @return {Promise} - A promise that is fulfilled with a PNG image data URL
* */
function toPng(node, options) {
return draw(node, options || {}).then(function (canvas) {
return canvas.toDataURL();
});
}
/**
* @param {Node} node - The DOM Node object to render
* @param {Object} options - Rendering options, @see {@link toSvg}
* @return {Promise} - A promise that is fulfilled with a JPEG image data URL
* */
function toJpeg(node, options) {
options = options || {};
return draw(node, options).then(function (canvas) {
return canvas.toDataURL('image/jpeg', options.quality || 1.0);
});
}
/**
* @param {Node} node - The DOM Node object to render
* @param {Object} options - Rendering options, @see {@link toSvg}
* @return {Promise} - A promise that is fulfilled with a PNG image blob
* */
function toBlob(node, options) {
return draw(node, options || {}).then(_domUtils.canvasToBlob);
}
function copyOptions(options) {
// Copy options to impl options for use in impl
if (typeof options.imagePlaceholder === 'undefined') {
domtoimage.impl.options.imagePlaceholder = defaultOptions.imagePlaceholder;
} else {
domtoimage.impl.options.imagePlaceholder = options.imagePlaceholder;
}
if (typeof options.cacheBust === 'undefined') {
domtoimage.impl.options.cacheBust = defaultOptions.cacheBust;
} else {
domtoimage.impl.options.cacheBust = options.cacheBust;
}
}
function draw(domNode, options) {
return toSvg(domNode, options).then(_domUtils.makeImage).then((0, _domUtils.delay)(100)).then(function (image) {
var canvas = newCanvas(domNode);
canvas.getContext('2d').drawImage(image, 0, 0);
return canvas;
});
function newCanvas(dNode) {
var canvas = _document["default"].createElement('canvas');
canvas.width = options.width || (0, _domUtils.getWidth)(dNode);
canvas.height = options.height || (0, _domUtils.getHeight)(dNode);
if (options.bgcolor) {
var ctx = canvas.getContext('2d');
ctx.fillStyle = options.bgcolor;
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
return canvas;
}
}
function cloneNode(node, filter, root) {
if (!root && filter && !filter(node)) {
return Promise.resolve();
}
return Promise.resolve(node).then(makeNodeCopy).then(function (clone) {
return cloneChildren(node, clone, filter);
}).then(function (clone) {
return (0, _domUtils.processClone)(node, clone);
});
function makeNodeCopy(nd) {
if (nd instanceof _window["default"].HTMLCanvasElement) {
return (0, _domUtils.makeImage)(nd.toDataURL());
}
return nd.cloneNode(false);
}
function cloneChildrenInOrder(parent, arrChildren, flt) {
var done = Promise.resolve();
arrChildren.forEach(function (child) {
done = done.then(function () {
return cloneNode(child, flt);
}).then(function (childClone) {
if (childClone) {
parent.appendChild(childClone);
}
});
});
return done;
}
function cloneChildren(original, clone, flt) {
var children = original.childNodes;
if (children.length === 0) {
return Promise.resolve(clone);
}
return cloneChildrenInOrder(clone, (0, _domUtils.asArray)(children), flt).then(function () {
return clone;
});
}
}
function embedFonts(node) {
return fontFaces.resolveAll().then(function (cssText) {
var styleNode = _document["default"].createElement('style');
node.appendChild(styleNode);
styleNode.appendChild(_document["default"].createTextNode(cssText));
return node;
});
}
function inlineImages(node) {
return images.inlineAll(node).then(function () {
return node;
});
}
function makeSvgDataUri(node, width, height) {
return Promise.resolve(node).then(function (nd) {
nd.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml');
var serializedString = new _window["default"].XMLSerializer().serializeToString(nd);
var xhtml = (0, _domUtils.escapeXhtml)(serializedString);
var foreignObject = "<foreignObject x=\"0\" y=\"0\" width=\"100%\" height=\"100%\">".concat(xhtml, "</foreignObject>");
var svgStr = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"".concat(width, "\" height=\"").concat(height, "\">").concat(foreignObject, "</svg>"); // Optimizing SVGs in data URIs
// see https://codepen.io/tigt/post/optimizing-svgs-in-data-uris
// the best way of encoding SVG in a data: URI is data:image/svg+xml,[actual data].
// We don’t need the ;charset=utf-8 parameter because the given SVG is ASCII.
return (0, _miniSvgDataUri["default"])(svgStr);
});
}
function newInliner() {
var URL_REGEX = /url\(['"]?([^'"]+?)['"]?\)/g;
return {
inlineAll: inlineAll,
shouldProcess: shouldProcess,
impl: {
readUrls: readUrls,
inline: inline
}
};
function shouldProcess(string) {
return string.search(URL_REGEX) !== -1;
}
function readUrls(string) {
var result = [];
var match;
while ((match = URL_REGEX.exec(string)) !== null) {
result.push(match[1]);
}
return result.filter(function (url) {
return !(0, _domUtils.isDataUrl)(url);
});
}
function urlAsRegex(url0) {
return new RegExp("(url\\(['\"]?)(".concat((0, _domUtils.escape)(url0), ")(['\"]?\\))"), 'g');
}
function inline(string, url, baseUrl, get) {
return Promise.resolve(url).then(function (ul) {
return baseUrl ? (0, _domUtils.resolveUrl)(ul, baseUrl) : ul;
}).then(function (ul) {
return typeof get === 'function' ? get(ul) : (0, _domUtils.getAndEncode)(ul, domtoimage.impl.options);
}).then(function (data) {
return (0, _domUtils.dataAsUrl)(data, (0, _domUtils.mimeType)(url));
}).then(function (dataUrl) {
return string.replace(urlAsRegex(url), "$1".concat(dataUrl, "$3"));
});
}
function inlineAll(string, baseUrl, get) {
if (!shouldProcess(string) || (0, _domUtils.isSrcAsDataUrl)(string)) {
return Promise.resolve(string);
}
return Promise.resolve(string).then(readUrls).then(function (urls) {
var done = Promise.resolve(string);
urls.forEach(function (url) {
done = done.then(function (str) {
return inline(str, url, baseUrl, get);
});
});
return done;
});
}
}
function newFontFaces() {
return {
resolveAll: resolveAll,
impl: {
readAll: readAll
}
};
function resolveAll() {
return readAll(_document["default"]).then(function (webFonts) {
return Promise.all(webFonts.map(function (webFont) {
return webFont.resolve();
}));
}).then(function (cssStrings) {
return cssStrings.join('\n');
});
}
function readAll() {
return Promise.resolve((0, _domUtils.asArray)(_document["default"].styleSheets)).then(loadExternalStyleSheets).then(getCssRules).then(selectWebFontRules).then(function (rules) {
return rules.map(newWebFont);
});
function selectWebFontRules(cssRules) {
return cssRules.filter(function (rule) {
return rule.type === _window["default"].CSSRule.FONT_FACE_RULE;
}).filter(function (rule) {
return inliner.shouldProcess(rule.style.getPropertyValue('src'));
});
}
function loadExternalStyleSheets(styleSheets) {
return Promise.all(styleSheets.map(function (sheet) {
if (sheet.href) {
// cloudfont doesn't have allow origin header properly set
// error response will remain in cache
var cache = sheet.href.includes('uber-fonts') ? 'no-cache' : 'default';
return _window["default"].fetch(sheet.href, {
credentials: 'omit',
cache: cache
}).then(function (response) {
return response.text();
}).then(setBaseHref(sheet.href)).then(toStyleSheet)["catch"](function (err) {
// Handle any error that occurred in any of the previous
// promises in the chain. stylesheet failed to load should not stop
// the process, hence result in only a warning, instead of reject
_console["default"].warn(_userFeedbacks.IMAGE_EXPORT_ERRORS.styleSheet, sheet.href);
_console["default"].log(err);
return;
});
}
return Promise.resolve(sheet);
}));
function setBaseHref(base) {
base = base.split('/');
base.pop();
base = base.join('/');
function addBaseHrefToUrl(match, p1) {
var url = /^http/i.test(p1) ? p1 : concatAndResolveUrl(base, p1);
return "url('".concat(url, "')");
} // Source: http://stackoverflow.com/a/2676231/3786856
function concatAndResolveUrl(url, concat) {
var url1 = url.split('/');
var url2 = concat.split('/');
var url3 = [];
for (var i = 0, l = url1.length; i < l; i++) {
if (url1[i] === '..') {
url3.pop();
} else if (url1[i] !== '.') {
url3.push(url1[i]);
}
}
for (var _i2 = 0, _l2 = url2.length; _i2 < _l2; _i2++) {
if (url2[_i2] === '..') {
url3.pop();
} else if (url2[_i2] !== '.') {
url3.push(url2[_i2]);
}
}
return url3.join('/');
}
return function (text) {
return (0, _domUtils.isSrcAsDataUrl)(text) ? text : text.replace(/url\(['"]?([^'"]+?)['"]?\)/g, addBaseHrefToUrl);
};
}
function toStyleSheet(text) {
var doc = _document["default"].implementation.createHTMLDocument('');
var styleElement = _document["default"].createElement('style');
styleElement.textContent = text;
doc.body.appendChild(styleElement);
return styleElement.sheet;
}
}
function getCssRules(styleSheets) {
var cssRules = [];
styleSheets.forEach(function (sheet) {
// try...catch because browser may not able to enumerate rules for cross-domain sheets
if (!sheet) {
return;
}
var rules;
try {
rules = sheet.rules || sheet.cssRules;
} catch (e) {
_console["default"].log("'Can't read the css rules of: ".concat(sheet.href), e);
return;
}
if (rules && (0, _typeof2["default"])(rules) === 'object') {
try {
(0, _domUtils.asArray)(rules || []).forEach(cssRules.push.bind(cssRules));
} catch (e) {
_console["default"].log("Error while reading CSS rules from ".concat(sheet.href), e);
return;
}
} else {
_console["default"].log('getCssRules can not find cssRules');
return;
}
});
return cssRules;
}
function newWebFont(webFontRule) {
return {
resolve: function resolve() {
var baseUrl = (webFontRule.parentStyleSheet || {}).href;
return inliner.inlineAll(webFontRule.cssText, baseUrl);
},
src: function src() {
return webFontRule.style.getPropertyValue('src');
}
};
}
}
}
function newImages() {
return {
inlineAll: inlineAll,
impl: {
newImage: newImage
}
};
function newImage(element) {
function inline(get) {
if (element.src) {
return Promise.resolve();
}
return Promise.resolve(element.src).then(function (ul) {
return typeof get === 'function' ? get(ul) : (0, _domUtils.getAndEncode)(ul, domtoimage.impl.options);
}).then(function (data) {
return (0, _domUtils.dataAsUrl)(data, (0, _domUtils.mimeType)(element.src));
}).then(function (dataUrl) {
return new Promise(function (resolve, reject) {
element.onload = resolve;
element.onerror = reject;
element.src = dataUrl;
});
});
}
return {
inline: inline
};
}
function inlineAll(node) {
if (!(node instanceof Element)) {
return Promise.resolve(node);
}
return inlineBackground(node).then(function () {
if (node instanceof HTMLImageElement) {
return newImage(node).inline();
}
return Promise.all((0, _domUtils.asArray)(node.childNodes).map(function (child) {
return inlineAll(child);
}));
});
function inlineBackground(nd) {
var background = nd.style.getPropertyValue('background');
if (!background) {
return Promise.resolve(nd);
}
return inliner.inlineAll(background).then(function (inlined) {
nd.style.setProperty('background', inlined, nd.style.getPropertyPriority('background'));
}).then(function () {
return nd;
});
}
}
}
var _default = exports["default"] = domtoimage;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlscy9kb20tdG8taW1hZ2UuanMiXSwibmFtZXMiOlsiaW5saW5lciIsIm5ld0lubGluZXIiLCJmb250RmFjZXMiLCJuZXdGb250RmFjZXMiLCJpbWFnZXMiLCJuZXdJbWFnZXMiLCJkZWZhdWx0T3B0aW9ucyIsImltYWdlUGxhY2Vob2xkZXIiLCJ1bmRlZmluZWQiLCJjYWNoZUJ1c3QiLCJkb210b2ltYWdlIiwidG9TdmciLCJ0b1BuZyIsInRvSnBlZyIsInRvQmxvYiIsInRvUGl4ZWxEYXRhIiwiaW1wbCIsIm9wdGlvbnMiLCJub2RlIiwiY29weU9wdGlvbnMiLCJQcm9taXNlIiwicmVzb2x2ZSIsInRoZW4iLCJuZCIsImNsb25lTm9kZSIsImZpbHRlciIsImVtYmVkRm9udHMiLCJpbmxpbmVJbWFnZXMiLCJhcHBseU9wdGlvbnMiLCJjbG9uZSIsIm1ha2VTdmdEYXRhVXJpIiwid2lkdGgiLCJoZWlnaHQiLCJiZ2NvbG9yIiwic3R5bGUiLCJiYWNrZ3JvdW5kQ29sb3IiLCJPYmplY3QiLCJrZXlzIiwiZm9yRWFjaCIsInByb3BlcnR5IiwiZHJhdyIsImNhbnZhcyIsImdldENvbnRleHQiLCJnZXRJbWFnZURhdGEiLCJkYXRhIiwidG9EYXRhVVJMIiwicXVhbGl0eSIsImNhbnZhc1RvQmxvYiIsImRvbU5vZGUiLCJtYWtlSW1hZ2UiLCJpbWFnZSIsIm5ld0NhbnZhcyIsImRyYXdJbWFnZSIsImROb2RlIiwiZG9jdW1lbnQiLCJjcmVhdGVFbGVtZW50IiwiY3R4IiwiZmlsbFN0eWxlIiwiZmlsbFJlY3QiLCJyb290IiwibWFrZU5vZGVDb3B5IiwiY2xvbmVDaGlsZHJlbiIsIndpbmRvdyIsIkhUTUxDYW52YXNFbGVtZW50IiwiY2xvbmVDaGlsZHJlbkluT3JkZXIiLCJwYXJlbnQiLCJhcnJDaGlsZHJlbiIsImZsdCIsImRvbmUiLCJjaGlsZCIsImNoaWxkQ2xvbmUiLCJhcHBlbmRDaGlsZCIsIm9yaWdpbmFsIiwiY2hpbGRyZW4iLCJjaGlsZE5vZGVzIiwibGVuZ3RoIiwicmVzb2x2ZUFsbCIsImNzc1RleHQiLCJzdHlsZU5vZGUiLCJjcmVhdGVUZXh0Tm9kZSIsImlubGluZUFsbCIsInNldEF0dHJpYnV0ZSIsInNlcmlhbGl6ZWRTdHJpbmciLCJYTUxTZXJpYWxpemVyIiwic2VyaWFsaXplVG9TdHJpbmciLCJ4aHRtbCIsImZvcmVpZ25PYmplY3QiLCJzdmdTdHIiLCJVUkxfUkVHRVgiLCJzaG91bGRQcm9jZXNzIiwicmVhZFVybHMiLCJpbmxpbmUiLCJzdHJpbmciLCJzZWFyY2giLCJyZXN1bHQiLCJtYXRjaCIsImV4ZWMiLCJwdXNoIiwidXJsIiwidXJsQXNSZWdleCIsInVybDAiLCJSZWdFeHAiLCJiYXNlVXJsIiwiZ2V0IiwidWwiLCJkYXRhVXJsIiwicmVwbGFjZSIsInVybHMiLCJzdHIiLCJyZWFkQWxsIiwid2ViRm9udHMiLCJhbGwiLCJtYXAiLCJ3ZWJGb250IiwiY3NzU3RyaW5ncyIsImpvaW4iLCJzdHlsZVNoZWV0cyIsImxvYWRFeHRlcm5hbFN0eWxlU2hlZXRzIiwiZ2V0Q3NzUnVsZXMiLCJzZWxlY3RXZWJGb250UnVsZXMiLCJydWxlcyIsIm5ld1dlYkZvbnQiLCJjc3NSdWxlcyIsInJ1bGUiLCJ0eXBlIiwiQ1NTUnVsZSIsIkZPTlRfRkFDRV9SVUxFIiwiZ2V0UHJvcGVydHlWYWx1ZSIsInNoZWV0IiwiaHJlZiIsImNhY2hlIiwiaW5jbHVkZXMiLCJmZXRjaCIsImNyZWRlbnRpYWxzIiwicmVzcG9uc2UiLCJ0ZXh0Iiwic2V0QmFzZUhyZWYiLCJ0b1N0eWxlU2hlZXQiLCJlcnIiLCJjb25zb2xlIiwid2FybiIsIklNQUdFX0VYUE9SVF9FUlJPUlMiLCJzdHlsZVNoZWV0IiwibG9nIiwiYmFzZSIsInNwbGl0IiwicG9wIiwiYWRkQmFzZUhyZWZUb1VybCIsInAxIiwidGVzdCIsImNvbmNhdEFuZFJlc29sdmVVcmwiLCJjb25jYXQiLCJ1cmwxIiwidXJsMiIsInVybDMiLCJpIiwibCIsImRvYyIsImltcGxlbWVudGF0aW9uIiwiY3JlYXRlSFRNTERvY3VtZW50Iiwic3R5bGVFbGVtZW50IiwidGV4dENvbnRlbnQiLCJib2R5IiwiZSIsImJpbmQiLCJ3ZWJGb250UnVsZSIsInBhcmVudFN0eWxlU2hlZXQiLCJzcmMiLCJuZXdJbWFnZSIsImVsZW1lbnQiLCJyZWplY3QiLCJvbmxvYWQiLCJvbmVycm9yIiwiRWxlbWVudCIsImlubGluZUJhY2tncm91bmQiLCJIVE1MSW1hZ2VFbGVtZW50IiwiYmFja2dyb3VuZCIsImlubGluZWQiLCJzZXRQcm9wZXJ0eSIsImdldFByb3BlcnR5UHJpb3JpdHkiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7O0FBeUJBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQTlCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7OztBQTRCQSxJQUFNQSxPQUFPLEdBQUdDLFVBQVUsRUFBMUI7QUFDQSxJQUFNQyxTQUFTLEdBQUdDLFlBQVksRUFBOUI7QUFDQSxJQUFNQyxNQUFNLEdBQUdDLFNBQVMsRUFBeEIsQyxDQUNBOztBQUNBLElBQU1DLGNBQWMsR0FBRztBQUNyQjtBQUNBQyxFQUFBQSxnQkFBZ0IsRUFBRUMsU0FGRztBQUdyQjtBQUNBQyxFQUFBQSxTQUFTLEVBQUU7QUFKVSxDQUF2QjtBQU9BLElBQU1DLFVBQVUsR0FBRztBQUNqQkMsRUFBQUEsS0FBSyxFQUFMQSxLQURpQjtBQUVqQkMsRUFBQUEsS0FBSyxFQUFMQSxLQUZpQjtBQUdqQkMsRUFBQUEsTUFBTSxFQUFOQSxNQUhpQjtBQUlqQkMsRUFBQUEsTUFBTSxFQUFOQSxNQUppQjtBQUtqQkMsRUFBQUEsV0FBVyxFQUFYQSxXQUxpQjtBQU1qQkMsRUFBQUEsSUFBSSxFQUFFO0FBQ0pkLElBQUFBLFNBQVMsRUFBVEEsU0FESTtBQUVKRSxJQUFBQSxNQUFNLEVBQU5BLE1BRkk7QUFHSkosSUFBQUEs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Q2YsZUFBTzVKLE9BQU8sQ0FBQ0MsT0FBUixDQUFnQkUsRUFBaEIsQ0FBUDtBQUNEOztBQUVELGFBQU92QixPQUFPLENBQ1hnRixTQURJLENBQ01nRyxVQUROLEVBRUoxSixJQUZJLENBRUMsVUFBQTJKLE9BQU8sRUFBSTtBQUNmMUosUUFBQUEsRUFBRSxDQUFDVyxLQUFILENBQVNnSixXQUFULENBQ0UsWUFERixFQUVFRCxPQUZGLEVBR0UxSixFQUFFLENBQUNXLEtBQUgsQ0FBU2lKLG1CQUFULENBQTZCLFlBQTdCLENBSEY7QUFLRCxPQVJJLEVBU0o3SixJQVRJLENBU0M7QUFBQSxlQUFNQyxFQUFOO0FBQUEsT0FURCxDQUFQO0FBVUQ7QUFDRjtBQUNGOztvQ0FFY2IsVSIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAoYykgMjAyMyBVYmVyIFRlY2hub2xvZ2llcywgSW5jLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbi8vIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksIHRvIGRlYWxcbi8vIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHNcbi8vIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGxcbi8vIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xuLy8gZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpblxuLy8gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuLy8gSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4vLyBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcbi8vIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbi8vIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sXG4vLyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOXG4vLyBUSEUgU09GVFdBUkUuXG5cbi8qKlxuICogVGhpcyBmaWxlIGlzIGNvcGllZCBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS90c2F5ZW4vZG9tLXRvLWltYWdlXG4gKiBNb2RpZmllZCBieSBoZXNoYW4wMTMxIHRvIGFsbG93IGxvYWRpbmcgZXh0ZXJuYWwgc3R5bGVzaGVldHMgYW5kIGlubGluZSB3ZWJmb250c1xuICovXG5cbmltcG9ydCB3aW5kb3cgZnJvbSAnZ2xvYmFsL3dpbmRvdyc7XG5pbXBvcnQgZG9jdW1lbnQgZnJvbSAnZ2xvYmFsL2RvY3VtZW50JztcbmltcG9ydCBjb25zb2xlIGZyb20gJ2dsb2JhbC9jb25zb2xlJztcbmltcG9ydCBzdmdUb01pbmlEYXRhVVJJIGZyb20gJ21pbmktc3ZnLWRhdGEtdXJpJztcbmltcG9ydCB7SU1BR0VfRVhQT1JUX0VSUk9SU30gZnJvbSAnY29uc3RhbnRzL3VzZXItZmVlZGJhY2tzJztcbmltcG9ydCB7XG4gIGNhbnZhc1RvQmxvYixcbiAgZXNjYXBlLFxuICBlc2NhcGVYaHRtbCxcbiAgZGVsYXksXG4gIHByb2Nlc3NDbG9uZSxcbiAgYXNBcnJheSxcbiAgbWFrZUltYWdlLFxuICBtaW1lVHlwZSxcbiAgZGF0YUFzVXJsLFxuICBpc0RhdGFVcmwsXG4gIGlzU3JjQXNEYXRhVXJsLFxuICByZXNvbHZlVXJsLFxuICBnZXRXaWR0aCxcbiAgZ2V0SGVpZ2h0LFxuICBnZXRBbmRFbmNvZGVcbn0gZnJvbSAnLi9kb20tdXRpbHMnO1xuXG5jb25zdCBpbmxpbmVyID0gbmV3SW5saW5lcigpO1xuY29uc3QgZm9udEZhY2VzID0gbmV3Rm9udEZhY2VzKCk7XG5jb25zdCBpbWFnZXMgPSBuZXdJbWFnZXMoKTtcbi8vIERlZmF1bHQgaW1wbCBvcHRpb25zXG5jb25zdCBkZWZhdWx0T3B0aW9ucyA9IHtcbiAgLy8gRGVmYXVsdCBpcyB0byBmYWlsIG9uIGVycm9yLCBubyBwbGFjZWhvbGRlclxuICBpbWFnZVBsYWNlaG9sZGVyOiB1bmRlZmluZWQsXG4gIC8vIERlZmF1bHQgY2FjaGUgYnVzdCBpcyBmYWxzZSwgaXQgd2lsbCB1c2UgdGhlIGNhY2hlXG4gIGNhY2hlQnVzdDogZmFsc2Vcbn07XG5cbmNvbnN0IGRvbXRvaW1hZ2UgPSB7XG4gIHRvU3ZnLFxuICB0b1BuZyxcbiAgdG9KcGVnLFxuICB0b0Jsb2IsXG4gIHRvUGl4ZWxEYXRhLFxuICBpbXBsOiB7XG4gICAgZm9udEZhY2VzLFxuICAgIGltYWdlcyxcbiAgICBpbmxpbmVyLFxuICAgIG9wdGlvbnM6IHt9XG4gIH1cbn07XG5cbi8qKlxuICAgKiBAcGFyYW0ge05vZGV9IG5vZGUgLSBUaGUgRE9NIE5vZGUgb2JqZWN0IHRvIHJlbmRlclxuICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyAtIFJlbmRlcmluZyBvcHRpb25zXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IG9wdGlvbnMuZmlsdGVyIC0gU2hvdWxkIHJldHVybiB0cnVlIGlmIHBhc3NlZCBub2RlIHNob3VsZCBiZSBpbmNsdWRlZCBpbiB0aGUgb3V0cHV0XG4gICAqICAgICAgICAgIChleGNsdWRpbmcgbm9kZSBtZWFucyBleGNsdWRpbmcgaXQncyBjaGlsZHJlbiBhcyB3ZWxsKS4gTm90IGNhbGxlZCBvbiB0aGUgcm9vdCBub2RlLlxuICAgKiBAcGFyYW0ge1N0cmluZ30gb3B0aW9ucy5iZ2NvbG9yIC0gY29sb3IgZm9yIHRoZSBiYWNrZ3JvdW5kLCBhbnkgdmFsaWQgQ1NTIGNvbG9yIHZhbHVlLlxuICAgKiBAcGFyYW0ge051bWJlcn0gb3B0aW9ucy53aWR0aCAtIHdpZHRoIHRvIGJlIGFwcGxpZWQgdG8gbm9kZSBiZWZvcmUgcmVuZGVyaW5nLlxuICAgKiBAcGFyYW0ge051bWJlcn0gb3B0aW9ucy5oZWlnaHQgLSBoZWlnaHQgdG8gYmUgYXBwbGllZCB0byBub2RlIGJlZm9yZSByZW5kZXJpbmcuXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zLnN0eWxlIC0gYW4gb2JqZWN0IHdob3NlIHByb3BlcnRpZXMgdG8gYmUgY29waWVkIHRvIG5vZGUncyBzdHlsZSBiZWZvcmUgcmVuZGVyaW5nLlxuICAgKiBAcGFyYW0ge051bWJlcn0gb3B0aW9ucy5xdWFsaXR5IC0gYSBOdW1iZXIgYmV0d2VlbiAwIGFuZCAxIGluZGljYXRpbmcgaW1hZ2UgcXVhbGl0eSAoYXBwbGljYWJsZSB0byBKUEVHIG9ubHkpLFxuICAgICAgICAgICAgICBkZWZhdWx0cyB0byAxLjAuXG4gICAgKiBAcGFyYW0ge1N0cmluZ30gb3B0aW9ucy5pbWFnZVBsYWNlaG9sZGVyIC0gZGF0YVVSTCB0byB1c2UgYXMgYSBwbGFjZWhvbGRlciBmb3IgZmFpbGVkIGltYWdlcywgZGVmYXVsdCBiZWhhdmlvdXIgaXMgdG8gZmFpbCBmYXN0IG9uIGltYWdlcyB3ZSBjYW4ndCBmZXRjaFxuICAgICogQHBhcmFtIHtCb29sZWFufSBvcHRpb25zLmNhY2hlQnVzdCAtIHNldCB0byB0cnVlIHRvIGNhY2hlIGJ1c3QgYnkgYXBwZW5kaW5nIHRoZSB0aW1lIHRvIHRoZSByZXF1ZXN0IHVybFxuICAgICogQHJldHVybiB7UHJvbWlzZX0gLSBBIHByb21pc2UgdGhhdCBpcyBmdWxmaWxsZWQgd2l0aCBhIFNWRyBpbWFnZSBkYXRhIFVSTFxuICAgICogKi9cbmZ1bmN0aW9uIHRvU3ZnKG5vZGUsIG9wdGlvbnMpIHtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIGNvcHlPcHRpb25zKG9wdGlvbnMpO1xuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKG5vZGUpXG4gICAgLnRoZW4obmQgPT4gY2xvbmVOb2RlKG5kLCBvcHRpb25zLmZpbHRlciwgdHJ1ZSkpXG4gICAgLnRoZW4oZW1iZWRGb250cylcbiAgICAudGhlbihpbmxpbmVJbWFnZXMpXG4gICAgLnRoZW4oYXBwbHlPcHRpb25zKVxuICAgIC50aGVuKGNsb25lID0+XG4gICAgICBtYWtlU3ZnRGF0YVVyaShcbiAgICAgICAgY2xvbmUsXG4gICAgICAgIG9wdGlvbnMud2lkdGggfHwgZ2V0V2lkdGgobm9kZSksXG4gICAgICAgIG9wdGlvbnMuaGVpZ2h0IHx8IGdldEhlaWdodChub2RlKVxuICAgICAgKVxuICAgICk7XG5cbiAgZnVuY3Rpb24gYXBwbHlPcHRpb25zKGNsb25lKSB7XG4gICAgaWYgKG9wdGlvbnMuYmdjb2xvcikgY2xvbmUuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gb3B0aW9ucy5iZ2NvbG9yO1xuXG4gICAgaWYgKG9wdGlvbnMud2lkdGgpIGNsb25lLnN0eWxlLndpZHRoID0gYCR7b3B0aW9ucy53aWR0aH1weGA7XG4gICAgaWYgKG9wdGlvbnMuaGVpZ2h0KSBjbG9uZS5zdHlsZS5oZWlnaHQgPSBgJHtvcHRpb25zLmhlaWdodH1weGA7XG5cbiAgICBpZiAob3B0aW9ucy5zdHlsZSlcbiAgICAgIE9iamVjdC5rZXlzKG9wdGlvbnMuc3R5bGUpLmZvckVhY2goKHByb3BlcnR5KSA9PiB7XG4gICAgICAgIGNsb25lLnN0eWxlW3Byb3BlcnR5XSA9IG9wdGlvbnMuc3R5bGVbcHJvcGVydHldO1xuICAgICAgfSk7XG5cbiAgICByZXR1cm4gY2xvbmU7XG4gIH1cbn1cblxuLyoqXG4gKiBAcGFyYW0ge05vZGV9IG5vZGUgLSBUaGUgRE9NIE5vZGUgb2JqZWN0IHRvIHJlbmRlclxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgLSBSZW5kZXJpbmcgb3B0aW9ucywgQHNlZSB7QGxpbmsgdG9Tdmd9XG4gKiBAcmV0dXJuIHtQcm9taXNlfSAtIEEgcHJvbWlzZSB0aGF0IGlzIGZ1bGZpbGxlZCB3aXRoIGEgVWludDhBcnJheSBjb250YWluaW5nIFJHQkEgcGl4ZWwgZGF0YS5cbiAqICovXG5mdW5jdGlvbiB0b1BpeGVsRGF0YShub2RlLCBvcHRpb25zKSB7XG4gIHJldHVybiBkcmF3KG5vZGUsIG9wdGlvbnMgfHwge30pLnRoZW4oY2FudmFzID0+XG4gICAgY2FudmFzXG4gICAgICAuZ2V0Q29udGV4dCgnMmQnKVxuICAgICAgLmdldEltYWdlRGF0YSgwLCAwLCBnZXRXaWR0aChub2RlKSwgZ2V0SGVpZ2h0KG5vZGUpKS5kYXRhXG4gICk7XG59XG5cbi8qKlxuICogQHBhcmFtIHtOb2RlfSBub2RlIC0gVGhlIERPTSBOb2RlIG9iamVjdCB0byByZW5kZXJcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIC0gUmVuZGVyaW5nIG9wdGlvbnMsIEBzZWUge0BsaW5rIHRvU3ZnfVxuICogQHJldHVybiB7UHJvbWlzZX0gLSBBIHByb21pc2UgdGhhdCBpcyBmdWxmaWxsZWQgd2l0aCBhIFBORyBpbWFnZSBkYXRhIFVSTFxuICogKi9cbmZ1bmN0aW9uIHRvUG5nKG5vZGUsIG9wdGlvbnMpIHtcbiAgcmV0dXJuIGRyYXcobm9kZSwgb3B0aW9ucyB8fCB7fSkudGhlbihjYW52YXMgPT4gY2FudmFzLnRvRGF0YVVSTCgpKTtcbn1cblxuLyoqXG4gKiBAcGFyYW0ge05vZGV9IG5vZGUgLSBUaGUgRE9NIE5vZGUgb2JqZWN0IHRvIHJlbmRlclxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgLSBSZW5kZXJpbmcgb3B0aW9ucywgQHNlZSB7QGxpbmsgdG9Tdmd9XG4gKiBAcmV0dXJuIHtQcm9taXNlfSAtIEEgcHJvbWlzZSB0aGF0IGlzIGZ1bGZpbGxlZCB3aXRoIGEgSlBFRyBpbWFnZSBkYXRhIFVSTFxuICogKi9cbmZ1bmN0aW9uIHRvSnBlZyhub2RlLCBvcHRpb25zKSB7XG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuICByZXR1cm4gZHJhdyhub2RlLCBvcHRpb25zKS50aGVuKGNhbnZhcyA9PiBjYW52YXMudG9EYXRhVVJMKCdpbWFnZS9qcGVnJywgb3B0aW9ucy5xdWFsaXR5IHx8IDEuMCkpO1xufVxuXG4vKipcbiAqIEBwYXJhbSB7Tm9kZX0gbm9kZSAtIFRoZSBET00gTm9kZSBvYmplY3QgdG8gcmVuZGVyXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyAtIFJlbmRlcmluZyBvcHRpb25zLCBAc2VlIHtAbGluayB0b1N2Z31cbiAqIEByZXR1cm4ge1Byb21pc2V9IC0gQSBwcm9taXNlIHRoYXQgaXMgZnVsZmlsbGVkIHdpdGggYSBQTkcgaW1hZ2UgYmxvYlxuICogKi9cbmZ1bmN0aW9uIHRvQmxvYihub2RlLCBvcHRpb25zKSB7XG4gIHJldHVybiBkcmF3KG5vZGUsIG9wdGlvbnMgfHwge30pLnRoZW4oY2FudmFzVG9CbG9iKTtcbn1cblxuZnVuY3Rpb24gY29weU9wdGlvbnMob3B0aW9ucykge1xuICAvLyBDb3B5IG9wdGlvbnMgdG8gaW1wbCBvcHRpb25zIGZvciB1c2UgaW4gaW1wbFxuICBpZiAodHlwZW9mIG9wdGlvbnMuaW1hZ2VQbGFjZWhvbGRlciA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBkb210b2ltYWdlLmltcGwub3B0aW9ucy5pbWFnZVBsYWNlaG9sZGVyID1cbiAgICAgIGRlZmF1bHRPcHRpb25zLmltYWdlUGxhY2Vob2xkZXI7XG4gIH0gZWxzZSB7XG4gICAgZG9tdG9pbWFnZS5pbXBsLm9wdGlvbnMuaW1hZ2VQbGFjZWhvbGRlciA9IG9wdGlvbnMuaW1hZ2VQbGFjZWhvbGRlcjtcbiAgfVxuXG4gIGlmICh0eXBlb2Ygb3B0aW9ucy5jYWNoZUJ1c3QgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgZG9tdG9pbWFnZS5pbXBsLm9wdGlvbnMuY2FjaGVCdXN0ID0gZGVmYXVsdE9wdGlvbnMuY2FjaGVCdXN0O1xuICB9IGVsc2Uge1xuICAgIGRvbXRvaW1hZ2UuaW1wbC5vcHRpb25zLmNhY2hlQnVzdCA9IG9wdGlvbnMuY2FjaGVCdXN0O1xuICB9XG59XG5cbmZ1bmN0aW9uIGRyYXcoZG9tTm9kZSwgb3B0aW9ucykge1xuICByZXR1cm4gdG9TdmcoZG9tTm9kZSwgb3B0aW9ucylcbiAgICAudGhlbihtYWtlSW1hZ2UpXG4gICAgLnRoZW4oZGVsYXkoMTAwKSlcbiAgICAudGhlbihpbWFnZSA9PiB7XG4gICAgICBjb25zdCBjYW52YXMgPSBuZXdDYW52YXMoZG9tTm9kZSk7XG4gICAgICBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKS5kcmF3SW1hZ2UoaW1hZ2UsIDAsIDApO1xuICAgICAgcmV0dXJuIGNhbnZhcztcbiAgICB9KTtcblxuICBmdW5jdGlvbiBuZXdDYW52YXMoZE5vZGUpIHtcbiAgICBjb25zdCBjYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKTtcbiAgICBjYW52YXMud2lkdGggPSBvcHRpb25zLndpZHRoIHx8IGdldFdpZHRoKGROb2RlKTtcbiAgICBjYW52YXMuaGVpZ2h0ID0gb3B0aW9ucy5oZWlnaHQgfHwgZ2V0SGVpZ2h0KGROb2RlKTtcblxuICAgIGlmIChvcHRpb25zLmJnY29sb3IpIHtcbiAgICAgIGNvbnN0IGN0eCA9IGNhbnZhcy5nZXRDb250ZXh0KCcyZCcpO1xuICAgICAgY3R4LmZpbGxTdHlsZSA9IG9wdGlvbnMuYmdjb2xvcjtcbiAgICAgIGN0eC5maWxsUmVjdCgwLCAwLCBjYW52YXMud2lkdGgsIGNhbnZhcy5oZWlnaHQpO1xuICAgIH1cblxuICAgIHJldHVybiBjYW52YXM7XG4gIH1cbn1cblxuZnVuY3Rpb24gY2xvbmVOb2RlKG5vZGUsIGZpbHRlciwgcm9vdCkge1xuICBpZiAoIXJvb3QgJiYgZmlsdGVyICYmICFmaWx0ZXIobm9kZSkpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cblxuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKG5vZGUpXG4gICAgLnRoZW4obWFrZU5vZGVDb3B5KVxuICAgIC50aGVuKGNsb25lID0+IGNsb25lQ2hpbGRyZW4obm9kZSwgY2xvbmUsIGZpbHRlcikpXG4gICAgLnRoZW4oY2xvbmUgPT4gcHJvY2Vzc0Nsb25lKG5vZGUsIGNsb25lKSk7XG5cbiAgZnVuY3Rpb24gbWFrZU5vZGVDb3B5KG5kKSB7XG4gICAgaWYgKG5kIGluc3RhbmNlb2Ygd2luZG93LkhUTUxDYW52YXNFbGVtZW50KSB7XG4gICAgICByZXR1cm4gbWFrZUltYWdlKG5kLnRvRGF0YVVSTCgpKTtcbiAgICB9XG4gICAgcmV0dXJuIG5kLmNsb25lTm9kZShmYWxzZSk7XG4gIH1cblxuICBmdW5jdGlvbiBjbG9uZUNoaWxkcmVuSW5PcmRlcihwYXJlbnQsIGFyckNoaWxkcmVuLCBmbHQpIHtcbiAgICBsZXQgZG9uZSA9IFByb21pc2UucmVzb2x2ZSgpO1xuICAgIGFyckNoaWxkcmVu