kepler.gl.geoiq
Version:
kepler.gl is a webgl based application to visualize large scale location data in the browser
383 lines (330 loc) • 40 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.tripVisConfigs = exports.geoJsonRequiredColumns = exports.featureResolver = exports.featureAccessor = exports["default"] = void 0;
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _get2 = _interopRequireDefault(require("@babel/runtime/helpers/get"));
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
var _lodash = _interopRequireDefault(require("lodash.memoize"));
var _lodash2 = _interopRequireDefault(require("lodash.uniq"));
var _baseLayer = _interopRequireDefault(require("../base-layer"));
var _deck = require("deck.gl");
var _defaultSettings = require("../../constants/default-settings");
var _tripLayerIcon = _interopRequireDefault(require("./trip-layer-icon"));
var _geojsonUtils = require("../geojson-layer/geojson-utils");
var _tripUtils = require("./trip-utils");
var _colorUtils = require("../../utils/color-utils");
var _tripInfoModal = _interopRequireDefault(require("./trip-info-modal"));
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2["default"])(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2["default"])(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2["default"])(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2["default"])(this, result); }; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
var tripVisConfigs = exports.tripVisConfigs = {
opacity: 'opacity',
thickness: {
type: 'number',
defaultValue: 0.5,
label: 'Stroke Width',
isRanged: false,
range: [0, 100],
step: 0.1,
group: 'stroke',
property: 'thickness'
},
colorRange: 'colorRange',
trailLength: 'trailLength',
sizeRange: 'strokeWidthRange'
};
var geoJsonRequiredColumns = exports.geoJsonRequiredColumns = ['geojson'];
var featureAccessor = exports.featureAccessor = function featureAccessor(_ref) {
var geojson = _ref.geojson;
return function (d) {
return d[geojson.fieldIdx];
};
};
var featureResolver = exports.featureResolver = function featureResolver(_ref2) {
var geojson = _ref2.geojson;
return geojson.fieldIdx;
};
var TripLayer = exports["default"] = /*#__PURE__*/function (_Layer) {
(0, _inherits2["default"])(TripLayer, _Layer);
var _super = _createSuper(TripLayer);
function TripLayer(props) {
var _this;
(0, _classCallCheck2["default"])(this, TripLayer);
_this = _super.call(this, props);
_this.dataToFeature = [];
_this.dataToTimeStamp = [];
_this.registerVisConfig(tripVisConfigs);
_this.getFeature = (0, _lodash["default"])(featureAccessor, featureResolver);
_this._layerInfoModal = (0, _tripInfoModal["default"])();
return _this;
}
(0, _createClass2["default"])(TripLayer, [{
key: "type",
get: function get() {
return 'trip';
}
}, {
key: "name",
get: function get() {
return 'Trip';
}
}, {
key: "layerIcon",
get: function get() {
return _tripLayerIcon["default"];
}
}, {
key: "requiredLayerColumns",
get: function get() {
return geoJsonRequiredColumns;
}
}, {
key: "visualChannels",
get: function get() {
return _objectSpread(_objectSpread({}, (0, _get2["default"])((0, _getPrototypeOf2["default"])(TripLayer.prototype), "visualChannels", this)), {}, {
size: _objectSpread(_objectSpread({}, (0, _get2["default"])((0, _getPrototypeOf2["default"])(TripLayer.prototype), "visualChannels", this).size), {}, {
property: 'stroke',
condition: function condition(config) {
return config.visConfig.stroked;
}
})
});
}
}, {
key: "animationDomain",
get: function get() {
return this.config.animation.domain;
}
}, {
key: "layerInfoModal",
get: function get() {
return {
id: 'iconInfo',
template: this._layerInfoModal,
modalProps: {
title: 'How to enable trip animation'
}
};
}
}, {
key: "getPositionAccessor",
value: function getPositionAccessor() {
return this.getFeature(this.config.columns);
}
}, {
key: "getDefaultLayerConfig",
value: function getDefaultLayerConfig(props) {
return _objectSpread(_objectSpread({}, (0, _get2["default"])((0, _getPrototypeOf2["default"])(TripLayer.prototype), "getDefaultLayerConfig", this).call(this, props)), {}, {
animation: {
enabled: true,
domain: null
}
});
}
}, {
key: "getHoverData",
value: function getHoverData(object, allData) {
// index of allData is saved to feature.properties
return allData[object.properties.index];
} // TODO: fix complexity
/* eslint-disable complexity */
}, {
key: "formatLayerData",
value: function formatLayerData(_, allData, filteredIndex, oldLayerData) {
var _this2 = this;
var opt = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
// to-do: parse segment from allData
var _this$config = this.config,
colorScale = _this$config.colorScale,
colorField = _this$config.colorField,
colorDomain = _this$config.colorDomain,
color = _this$config.color,
sizeScale = _this$config.sizeScale,
sizeDomain = _this$config.sizeDomain,
sizeField = _this$config.sizeField,
visConfig = _this$config.visConfig;
var stroked = visConfig.stroked,
colorRange = visConfig.colorRange,
sizeRange = visConfig.sizeRange;
var getFeature = this.getPositionAccessor(this.config.column); // geojson feature are object, if doesn't exists
// create it and save to layer
if (!oldLayerData || oldLayerData.getFeature !== getFeature) {
this.updateLayerMeta(allData, getFeature);
}
var geojsonData;
if (oldLayerData && oldLayerData.data && opt.sameData && oldLayerData.getFeature === getFeature) {
// no need to create a new array of data
// use updateTriggers to selectively re-calculate attributes
geojsonData = oldLayerData.data;
} else {
// filteredIndex is a reference of index in allData which can map to feature
geojsonData = filteredIndex.map(function (i) {
return _this2.dataToFeature[i];
}).filter(function (d) {
return d && d.geometry.type === 'LineString';
});
} // color
var cScale = colorField && this.getVisChannelScale(colorScale, colorDomain, colorRange.colors.map(_colorUtils.hexToRgb)); // calculate stroke scale - if stroked = true
var sScale = sizeField && stroked && this.getVisChannelScale(sizeScale, sizeDomain, sizeRange);
return {
data: geojsonData,
getPath: function getPath(d) {
return d.geometry.coordinates;
},
getTimestamps: function getTimestamps(d) {
return _this2.dataToTimeStamp[d.properties.index];
},
getColor: function getColor(d) {
return cScale ? _this2.getEncodedChannelValue(cScale, allData[d.properties.index], colorField) : d.properties.fillColor || color;
},
getWidth: function getWidth(d) {
return sScale ? _this2.getEncodedChannelValue(sScale, allData[d.properties.index], sizeField, 0) : d.properties.lineWidth || 1;
}
};
}
/* eslint-enable complexity */
}, {
key: "updateAnimationDomain",
value: function updateAnimationDomain(domain) {
this.updateLayerConfig({
animation: _objectSpread(_objectSpread({}, this.config.animation), {}, {
domain: domain
})
});
}
}, {
key: "updateLayerMeta",
value: function updateLayerMeta(allData) {
var getFeature = this.getPositionAccessor();
if (getFeature === this.meta.getFeature) {
// TODO: revisit this after gpu filtering
return;
}
this.dataToFeature = (0, _geojsonUtils.getGeojsonDataMaps)(allData, getFeature);
var _parseTripGeoJsonTime = (0, _tripUtils.parseTripGeoJsonTimestamp)(this.dataToFeature),
dataToTimeStamp = _parseTripGeoJsonTime.dataToTimeStamp,
animationDomain = _parseTripGeoJsonTime.animationDomain;
this.dataToTimeStamp = dataToTimeStamp;
this.updateAnimationDomain(animationDomain); // get bounds from features
var bounds = (0, _geojsonUtils.getGeojsonBounds)(this.dataToFeature); // keep a record of what type of geometry the collection has
var featureTypes = (0, _geojsonUtils.getGeojsonFeatureTypes)(this.dataToFeature);
this.updateMeta({
bounds: bounds,
featureTypes: featureTypes,
getFeature: getFeature
});
}
}, {
key: "setInitialLayerConfig",
value: function setInitialLayerConfig(allData) {
this.updateLayerMeta(allData);
return this;
}
}, {
key: "renderLayer",
value: function renderLayer(_ref3) {
var data = _ref3.data,
idx = _ref3.idx,
mapState = _ref3.mapState,
animationConfig = _ref3.animationConfig;
var visConfig = this.config.visConfig;
var zoomFactor = this.getZoomFactor(mapState);
var updateTriggers = {
getColor: {
color: this.config.color,
colorField: this.config.colorField,
colorRange: visConfig.colorRange,
colorScale: this.config.colorScale
},
getWidth: {
sizeField: this.config.sizeField,
sizeRange: visConfig.sizeRange
},
getTimestamps: {
columns: this.config.columns,
domain0: animationConfig.domain[0]
}
};
return [new _deck.TripsLayer({
id: this.id,
idx: idx,
data: data.data,
getPath: data.getPath,
getColor: data.getColor,
getTimestamps: function getTimestamps(d) {
return data.getTimestamps(d).map(function (ts) {
return ts - animationConfig.domain[0];
});
},
opacity: this.config.visConfig.opacity,
widthScale: this.config.visConfig.thickness * zoomFactor * 8,
highlightColor: this.config.highlightColor,
getWidth: data.getWidth,
rounded: true,
pickable: true,
autoHighlight: true,
parameters: {
depthTest: mapState.dragRotate,
depthMask: false
},
trailLength: visConfig.trailLength * 1000,
currentTime: animationConfig.currentTime - animationConfig.domain[0],
updateTriggers: updateTriggers
})];
}
}], [{
key: "findDefaultLayerProps",
value: function findDefaultLayerProps(_ref4, foundLayers) {
var _this3 = this;
var label = _ref4.label,
_ref4$fields = _ref4.fields,
fields = _ref4$fields === void 0 ? [] : _ref4$fields,
_ref4$allData = _ref4.allData,
allData = _ref4$allData === void 0 ? [] : _ref4$allData,
id = _ref4.id;
var geojsonColumns = fields.filter(function (f) {
return f.type === 'geojson';
}).map(function (f) {
return f.name;
});
var defaultColumns = {
geojson: (0, _lodash2["default"])([].concat((0, _toConsumableArray2["default"])(_defaultSettings.GEOJSON_FIELDS.geojson), (0, _toConsumableArray2["default"])(geojsonColumns)))
};
var geoJsonColumns = this.findDefaultColumnField(defaultColumns, fields);
var tripColumns = (geoJsonColumns || []).filter(function (col) {
return (0, _tripUtils.isTripGeoJsonField)(allData, fields[col.geojson.fieldIdx]);
});
if (!tripColumns.length) {
return {
props: []
};
}
return {
props: tripColumns.map(function (columns) {
return {
label: typeof label === 'string' && label.replace(/\.[^/.]+$/, '') || _this3.type,
columns: columns,
isVisible: true
};
}),
// if a geojson layer is created from this column, delete it
foundLayers: foundLayers.filter(function (prop) {
return prop.type !== 'geojson' || prop.dataId !== id || !tripColumns.find(function (c) {
return prop.columns.geojson.name === c.geojson.name;
});
})
};
}
}]);
return TripLayer;
}(_baseLayer["default"]);
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9sYXllcnMvdHJpcC1sYXllci90cmlwLWxheWVyLmpzIl0sIm5hbWVzIjpbInRyaXBWaXNDb25maWdzIiwib3BhY2l0eSIsInRoaWNrbmVzcyIsInR5cGUiLCJkZWZhdWx0VmFsdWUiLCJsYWJlbCIsImlzUmFuZ2VkIiwicmFuZ2UiLCJzdGVwIiwiZ3JvdXAiLCJwcm9wZXJ0eSIsImNvbG9yUmFuZ2UiLCJ0cmFpbExlbmd0aCIsInNpemVSYW5nZSIsImdlb0pzb25SZXF1aXJlZENvbHVtbnMiLCJmZWF0dXJlQWNjZXNzb3IiLCJnZW9qc29uIiwiZCIsImZpZWxkSWR4IiwiZmVhdHVyZVJlc29sdmVyIiwiVHJpcExheWVyIiwicHJvcHMiLCJkYXRhVG9GZWF0dXJlIiwiZGF0YVRvVGltZVN0YW1wIiwicmVnaXN0ZXJWaXNDb25maWciLCJnZXRGZWF0dXJlIiwiX2xheWVySW5mb01vZGFsIiwiVHJpcExheWVySWNvbiIsInNpemUiLCJjb25kaXRpb24iLCJjb25maWciLCJ2aXNDb25maWciLCJzdHJva2VkIiwiYW5pbWF0aW9uIiwiZG9tYWluIiwiaWQiLCJ0ZW1wbGF0ZSIsIm1vZGFsUHJvcHMiLCJ0aXRsZSIsImNvbHVtbnMiLCJlbmFibGVkIiwib2JqZWN0IiwiYWxsRGF0YSIsInByb3BlcnRpZXMiLCJpbmRleCIsIl8iLCJmaWx0ZXJlZEluZGV4Iiwib2xkTGF5ZXJEYXRhIiwib3B0IiwiY29sb3JTY2FsZSIsImNvbG9yRmllbGQiLCJjb2xvckRvbWFpbiIsImNvbG9yIiwic2l6ZVNjYWxlIiwic2l6ZURvbWFpbiIsInNpemVGaWVsZCIsImdldFBvc2l0aW9uQWNjZXNzb3IiLCJjb2x1bW4iLCJ1cGRhdGVMYXllck1ldGEiLCJnZW9qc29uRGF0YSIsImRhdGEiLCJzYW1lRGF0YSIsIm1hcCIsImkiLCJmaWx0ZXIiLCJnZW9tZXRyeSIsImNTY2FsZSIsImdldFZpc0NoYW5uZWxTY2FsZSIsImNvbG9ycyIsImhleFRvUmdiIiwic1NjYWxlIiwiZ2V0UGF0aCIsImNvb3JkaW5hdGVzIiwiZ2V0VGltZXN0YW1wcyIsImdldENvbG9yIiwiZ2V0RW5jb2RlZENoYW5uZWxWYWx1ZSIsImZpbGxDb2xvciIsImdldFdpZHRoIiwibGluZVdpZHRoIiwidXBkYXRlTGF5ZXJDb25maWciLCJtZXRhIiwiYW5pbWF0aW9uRG9tYWluIiwidXBkYXRlQW5pbWF0aW9uRG9tYWluIiwiYm91bmRzIiwiZmVhdHVyZVR5cGVzIiwidXBkYXRlTWV0YSIsImlkeCIsIm1hcFN0YXRlIiwiYW5pbWF0aW9uQ29uZmlnIiwiem9vbUZhY3RvciIsImdldFpvb21GYWN0b3IiLCJ1cGRhdGVUcmlnZ2VycyIsImRvbWFpbjAiLCJEZWNrR0xUcmlwc0xheWVyIiwidHMiLCJ3aWR0aFNjYWxlIiwiaGlnaGxpZ2h0Q29sb3IiLCJyb3VuZGVkIiwicGlja2FibGUiLCJhdXRvSGlnaGxpZ2h0IiwicGFyYW1ldGVycyIsImRlcHRoVGVzdCIsImRyYWdSb3RhdGUiLCJkZXB0aE1hc2siLCJjdXJyZW50VGltZSIsImZvdW5kTGF5ZXJzIiwiZmllbGRzIiwiZ2VvanNvbkNvbHVtbnMiLCJmIiwibmFtZSIsImRlZmF1bHRDb2x1bW5zIiwiR0VPSlNPTl9GSUVMRFMiLCJnZW9Kc29uQ29sdW1ucyIsImZpbmREZWZhdWx0Q29sdW1uRmllbGQiLCJ0cmlwQ29sdW1ucyIsImNvbCIsImxlbmd0aCIsInJlcGxhY2UiLCJpc1Zpc2libGUiLCJwcm9wIiwiZGF0YUlkIiwiZmluZCIsImMiLCJMYXllciJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQW9CQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFFQTs7QUFDQTs7QUFFQTs7QUFNQTs7QUFLQTs7QUFDQTs7Ozs7Ozs7OztBQUVPLElBQU1BLGNBQWMsNEJBQUc7QUFDNUJDLEVBQUFBLE9BQU8sRUFBRSxTQURtQjtBQUU1QkMsRUFBQUEsU0FBUyxFQUFFO0FBQ1RDLElBQUFBLElBQUksRUFBRSxRQURHO0FBRVRDLElBQUFB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Q3BELEdBQVosQ0FBZ0IsVUFBQXZCLE9BQU87QUFBQSxpQkFBSztBQUNqQ2xDLFlBQUFBLEtBQUssRUFDRixPQUFPQSxLQUFQLEtBQWlCLFFBQWpCLElBQTZCQSxLQUFLLENBQUNnSCxPQUFOLENBQWMsV0FBZCxFQUEyQixFQUEzQixDQUE5QixJQUNBLE1BQUksQ0FBQ2xILElBSDBCO0FBSWpDb0MsWUFBQUEsT0FBTyxFQUFQQSxPQUppQztBQUtqQytFLFlBQUFBLFNBQVMsRUFBRTtBQUxzQixXQUFMO0FBQUEsU0FBdkIsQ0FERjtBQVNMO0FBQ0FiLFFBQUFBLFdBQVcsRUFBRUEsV0FBVyxDQUFDekMsTUFBWixDQUNYLFVBQUF1RCxJQUFJO0FBQUEsaUJBQ0ZBLElBQUksQ0FBQ3BILElBQUwsS0FBYyxTQUFkLElBQ0FvSCxJQUFJLENBQUNDLE1BQUwsS0FBZ0JyRixFQURoQixJQUVBLENBQUMrRSxXQUFXLENBQUNPLElBQVosQ0FBaUIsVUFBQUMsQ0FBQztBQUFBLG1CQUFJSCxJQUFJLENBQUNoRixPQUFMLENBQWF2QixPQUFiLENBQXFCNkYsSUFBckIsS0FBOEJhLENBQUMsQ0FBQzFHLE9BQUYsQ0FBVTZGLElBQTVDO0FBQUEsV0FBbEIsQ0FIQztBQUFBLFNBRE87QUFWUixPQUFQO0FBaUJEOzs7RUE3Rm9DYyxxQiIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAoYykgMjAyMyBVYmVyIFRlY2hub2xvZ2llcywgSW5jLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbi8vIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksIHRvIGRlYWxcbi8vIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHNcbi8vIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGxcbi8vIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xuLy8gZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpblxuLy8gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuLy8gSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4vLyBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcbi8vIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbi8vIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sXG4vLyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOXG4vLyBUSEUgU09GVFdBUkUuXG5cbmltcG9ydCBtZW1vaXplIGZyb20gJ2xvZGFzaC5tZW1vaXplJztcbmltcG9ydCB1bmlxIGZyb20gJ2xvZGFzaC51bmlxJztcbmltcG9ydCBMYXllciBmcm9tICcuLi9iYXNlLWxheWVyJztcbmltcG9ydCB7VHJpcHNMYXllciBhcyBEZWNrR0xUcmlwc0xheWVyfSBmcm9tICdkZWNrLmdsJztcblxuaW1wb3J0IHtHRU9KU09OX0ZJRUxEU30gZnJvbSAnY29uc3RhbnRzL2RlZmF1bHQtc2V0dGluZ3MnO1xuaW1wb3J0IFRyaXBMYXllckljb24gZnJvbSAnLi90cmlwLWxheWVyLWljb24nO1xuXG5pbXBvcnQge1xuICBnZXRHZW9qc29uRGF0YU1hcHMsXG4gIGdldEdlb2pzb25Cb3VuZHMsXG4gIGdldEdlb2pzb25GZWF0dXJlVHlwZXNcbn0gZnJvbSAnbGF5ZXJzL2dlb2pzb24tbGF5ZXIvZ2VvanNvbi11dGlscyc7XG5cbmltcG9ydCB7XG4gIGlzVHJpcEdlb0pzb25GaWVsZCxcbiAgcGFyc2VUcmlwR2VvSnNvblRpbWVzdGFtcFxufSBmcm9tICcuL3RyaXAtdXRpbHMnO1xuXG5pbXBvcnQge2hleFRvUmdifSBmcm9tICd1dGlscy9jb2xvci11dGlscyc7XG5pbXBvcnQgVHJpcEluZm9Nb2RhbEZhY3RvcnkgZnJvbSAnLi90cmlwLWluZm8tbW9kYWwnO1xuXG5leHBvcnQgY29uc3QgdHJpcFZpc0NvbmZpZ3MgPSB7XG4gIG9wYWNpdHk6ICdvcGFjaXR5JyxcbiAgdGhpY2tuZXNzOiB7XG4gICAgdHlwZTogJ251bWJlcicsXG4gICAgZGVmYXVsdFZhbHVlOiAwLjUsXG4gICAgbGFiZWw6ICdTdHJva2UgV2lkdGgnLFxuICAgIGlzUmFuZ2VkOiBmYWxzZSxcbiAgICByYW5nZTogWzAsIDEwMF0sXG4gICAgc3RlcDogMC4xLFxuICAgIGdyb3VwOiAnc3Ryb2tlJyxcbiAgICBwcm9wZXJ0eTogJ3RoaWNrbmVzcydcbiAgfSxcbiAgY29sb3JSYW5nZTogJ2NvbG9yUmFuZ2UnLFxuICB0cmFpbExlbmd0aDogJ3RyYWlsTGVuZ3RoJyxcbiAgc2l6ZVJhbmdlOiAnc3Ryb2tlV2lkdGhSYW5nZSdcbn07XG5cbmV4cG9ydCBjb25zdCBnZW9Kc29uUmVxdWlyZWRDb2x1bW5zID0gWydnZW9qc29uJ107XG5leHBvcnQgY29uc3QgZmVhdHVyZUFjY2Vzc29yID0gKHtnZW9qc29ufSkgPT4gZCA9PiBkW2dlb2pzb24uZmllbGRJZHhdO1xuZXhwb3J0IGNvbnN0IGZlYXR1cmVSZXNvbHZlciA9ICh7Z2VvanNvbn0pID0+IGdlb2pzb24uZmllbGRJZHg7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFRyaXBMYXllciBleHRlbmRzIExheWVyIHtcbiAgY29uc3RydWN0b3IocHJvcHMpIHtcbiAgICBzdXBlcihwcm9wcyk7XG5cbiAgICB0aGlzLmRhdGFUb0ZlYXR1cmUgPSBbXTtcbiAgICB0aGlzLmRhdGFUb1RpbWVTdGFtcCA9IFtdO1xuICAgIHRoaXMucmVnaXN0ZXJWaXNDb25maWcodHJpcFZpc0NvbmZpZ3MpO1xuICAgIHRoaXMuZ2V0RmVhdHVyZSA9IG1lbW9pemUoZmVhdHVyZUFjY2Vzc29yLCBmZWF0dXJlUmVzb2x2ZXIpO1xuICAgIHRoaXMuX2xheWVySW5mb01vZGFsID0gVHJpcEluZm9Nb2RhbEZhY3RvcnkoKTtcbiAgfVxuXG4gIGdldCB0eXBlKCkge1xuICAgIHJldHVybiAndHJpcCc7XG4gIH1cblxuICBnZXQgbmFtZSgpIHtcbiAgICByZXR1cm4gJ1RyaXAnO1xuICB9XG5cbiAgZ2V0IGxheWVySWNvbigpIHtcbiAgICByZXR1cm4gVHJpcExheWVySWNvbjtcbiAgfVxuXG4gIGdldCByZXF1aXJlZExheWVyQ29sdW1ucygpIHtcbiAgICByZXR1cm4gZ2VvSnNvblJlcXVpcmVkQ29sdW1ucztcbiAgfVxuXG4gIGdldCB2aXN1YWxDaGFubmVscygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgLi4uc3VwZXIudmlzdWFsQ2hhbm5lbHMsXG5cbiAgICAgIHNpemU6IHtcbiAgICAgICAgLi4uc3VwZXIudmlzdWFsQ2hhbm5lbHMuc2l6ZSxcbiAgICAgICAgcHJvcGVydHk6ICdzdHJva2UnLFxuICAgICAgICBjb25kaXRpb246IGNvbmZpZyA9PiBjb25maWcudmlzQ29uZmlnLnN0cm9rZWRcbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgZ2V0IGFuaW1hdGlvbkRvbWFpbigpIHtcbiAgICByZXR1cm4gdGhpcy5jb25maWcuYW5pbWF0aW9uLmRvbWFpbjtcbiAgfVxuXG4gIGdldCBsYXllckluZm9Nb2RhbCgpIHtcbiAgICByZXR1cm4ge1xuICAgICAgaWQ6ICdpY29uSW5mbycsXG4gICAgICB0ZW1wbGF0ZTogdGhpcy5fbGF5ZXJJbmZvTW9kYWwsXG4gICAgICBtb2RhbFByb3BzOiB7XG4gICAgICAgIHRpdGxlOiAnSG93IHRvIGVuYWJsZSB0cmlwIGFuaW1hdGlvbidcbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgZ2V0UG9zaXRpb25BY2Nlc3NvcigpIHtcbiAgICByZXR1cm4gdGhpcy5nZXRGZWF0dXJlKHRoaXMuY29uZmlnLmNvbHVtbnMpO1xuICB9XG5cbiAgc3RhdGljIGZpbmREZWZhdWx0TGF5ZXJQcm9wcyh7bGFiZWwsIGZpZWxkcyA9IFtdLCBhbGxEYXRhID0gW10sIGlkfSwgZm91bmRMYXllcnMpIHtcbiAgICBjb25zdCBnZW9qc29uQ29sdW1ucyA9IGZpZWxkc1xuICAgICAgLmZpbHRlcihmID0+IGYudHlwZSA9PT0gJ2dlb2pzb24nKVxuICAgICAgLm1hcChmID0+IGYubmFtZSk7XG5cbiAgICBjb25zdCBkZWZhdWx0Q29sdW1ucyA9IHtcbiAgICAgIGdlb2pzb246IHVuaXEoWy4uLkdFT0pTT05fRklFTERTLmdlb2pzb24sIC4uLmdlb2pzb25Db2x1bW5zXSlcbiAgICB9O1xuXG4gICAgY29uc3QgZ2VvSnNvbkNvbHVtbnMgPSB0aGlzLmZpbmREZWZhdWx0Q29sdW1uRmllbGQoZGVmYXVsdENvbHVtbnMsIGZpZWxkcyk7XG5cbiAgICBjb25zdCB0cmlwQ29sdW1ucyA9IChnZW9Kc29uQ29sdW1ucyB8fCBbXSkuZmlsdGVyKGNvbCA9PlxuICAgICAgaXNUcmlwR2VvSnNvbkZpZWxkKGFsbERhdGEsIGZpZWxkc1tjb2wuZ2VvanNvbi5maWVsZElkeF0pXG4gICAgKTtcblxuICAgIGlmICghdHJpcENvbHVtbnMubGVuZ3RoKSB7XG4gICAgICByZXR1cm4ge3Byb3BzOiBbXX07XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIHByb3BzOiB0cmlwQ29sdW1ucy5tYXAoY29sdW1ucyA9PiAoe1xuICAgICAgICBsYWJlbDpcbiAgICAgICAgICAodHlwZW9mIGxhYmVsID09PSAnc3RyaW5nJyAmJiBsYWJlbC5yZXBsYWNlKC9cXC5bXi8uXSskLywgJycpKSB8fFxuICAgICAgICAgIHRoaXMudHlwZSxcbiAgICAgICAgY29sdW1ucyxcbiAgICAgICAgaXNWaXNpYmxlOiB0cnVlXG4gICAgICB9KSksXG5cbiAgICAgIC8vIGlmIGEgZ2VvanNvbiBsYXllciBpcyBjcmVhdGVkIGZyb20gdGhpcyBjb2x1bW4sIGRlbGV0ZSBpdFxuICAgICAgZm91bmRMYXllcnM6IGZvdW5kTGF5ZXJzLmZpbHRlcihcbiAgICAgICAgcHJvcCA9PlxuICAgICAgICAgIHByb3AudHlwZSAhPT0gJ2dlb2pzb24nIHx8XG4gICAgICAgICAgcHJvcC5kYXRhSWQgIT09IGlkIHx8XG4gICAgICAgICAgIXRyaXBDb2x1bW5zLmZpbmQoYyA9PiBwcm9wLmNvbHVtbnMuZ2VvanNvbi5uYW1lID09PSBjLmdlb2pzb24ubmFtZSlcbiAgICAgIClcbiAgICB9O1xuICB9XG5cbiAgZ2V0RGVmYXVsdExheWVyQ29uZmlnKHByb3BzKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLnN1cGVyLmdldERlZmF1bHRMYXllckNvbmZpZyhwcm9wcyksXG4gICAgICBhbmltYXRpb246IHtcbiAgICAgICAgZW5hYmxlZDogdHJ1ZSxcbiAgICAgICAgZG9tYWluOiBudWxsXG4gICAgICB9XG4gICAgfTtcbiAgfVxuXG4gIGdldEhvdmVyRGF0YShvYmplY3QsIGFsbERhdGEpIHtcbiAgICAvLyBpbmRleCBvZiBhbGxEYXRhIGlzIHNhdmVkIHRvIGZlYXR1cmUucHJvcGVydGllc1xuICAgIHJldHVybiBhbGxEYXRhW29iamVjdC5wcm9wZXJ0aWVzLmluZGV4XTtcbiAgfVxuXG4gIC8vIFRPRE86IGZpeCBjb21wbGV4aXR5XG4gIC8qIGVzbGludC1kaXNhYmxlIGNvbXBsZXhpdHkgKi9cbiAgZm9ybWF0TGF5ZXJEYXRhKF8sIGFsbERhdGEsIGZpbHRlcmVkSW5kZXgsIG9sZExheWVyRGF0YSwgb3B0ID0ge30pIHtcbiAgICAvLyB0by1kbzogcGFyc2Ugc2VnbWVudCBmcm9tIGFsbERhdGFcbiAgICBjb25zdCB7XG4gICAgICBjb2xvclNjYWxlLFxuICAgICAgY29sb3JGaWVsZCxcbiAgICAgIGNvbG9yRG9tYWluLFxuICAgICAgY29sb3IsXG4gICAgICBzaXplU2NhbGUsXG4gICAgICBzaXplRG9tYWluLFxuICAgICAgc2l6ZUZpZWxkLFxuICAgICAgdmlzQ29uZmlnXG4gICAgfSA9IHRoaXMuY29uZmlnO1xuXG4gICAgY29uc3Qge3N0cm9rZWQsIGNvbG9yUmFuZ2UsIHNpemVSYW5nZX0gPSB2aXNDb25maWc7XG5cbiAgICBjb25zdCBnZXRGZWF0dXJlID0gdGhpcy5nZXRQb3NpdGlvbkFjY2Vzc29yKHRoaXMuY29uZmlnLmNvbHVtbik7XG5cbiAgICAvLyBnZW9qc29uIGZlYXR1cmUgYXJlIG9iamVjdCwgaWYgZG9lc24ndCBleGlzdHNcbiAgICAvLyBjcmVhdGUgaXQgYW5kIHNhdmUgdG8gbGF5ZXJcbiAgICBpZiAoIW9sZExheWVyRGF0YSB8fCBvbGRMYXllckRhdGEuZ2V0RmVhdHVyZSAhPT0gZ2V0RmVhdHVyZSkge1xuICAgICAgdGhpcy51cGRhdGVMYXllck1ldGEoYWxsRGF0YSwgZ2V0RmVhdHVyZSk7XG4gICAgfVxuXG4gICAgbGV0IGdlb2pzb25EYXRhO1xuXG4gICAgaWYgKFxuICAgICAgb2xkTGF5ZXJEYXRhICYmXG4gICAgICBvbGRMYXllckRhdGEuZGF0YSAmJlxuICAgICAgb3B0LnNhbWVEYXRhICYmXG4gICAgICBvbGRMYXllckRhdGEuZ2V0RmVhdHVyZSA9PT0gZ2V0RmVhdHVyZVxuICAgICkge1xuICAgICAgLy8gbm8gbmVlZCB0byBjcmVhdGUgYSBuZXcgYXJyYXkgb2YgZGF0YVxuICAgICAgLy8gdXNlIHVwZGF0ZVRyaWdnZXJzIHRvIHNlbGVjdGl2ZWx5IHJlLWNhbGN1bGF0ZSBhdHRyaWJ1dGVzXG4gICAgICBnZW9qc29uRGF0YSA9IG9sZExheWVyRGF0YS5kYXRhO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBmaWx0ZXJlZEluZGV4IGlzIGEgcmVmZXJlbmNlIG9mIGluZGV4IGluIGFsbERhdGEgd2hpY2ggY2FuIG1hcCB0byBmZWF0dXJlXG4gICAgICBnZW9qc29uRGF0YSA9IGZpbHRlcmVkSW5kZXhcbiAgICAgICAgLm1hcChpID0+IHRoaXMuZGF0YVRvRmVhdHVyZVtpXSlcbiAgICAgICAgLmZpbHRlcihkID0+IGQgJiYgZC5nZW9tZXRyeS50eXBlID09PSAnTGluZVN0cmluZycpO1xuICAgIH1cblxuICAgIC8vIGNvbG9yXG4gICAgY29uc3QgY1NjYWxlID1cbiAgICAgIGNvbG9yRmllbGQgJiZcbiAgICAgIHRoaXMuZ2V0VmlzQ2hhbm5lbFNjYWxlKFxuICAgICAgICBjb2xvclNjYWxlLFxuICAgICAgICBjb2xvckRvbWFpbixcbiAgICAgICAgY29sb3JSYW5nZS5jb2xvcnMubWFwKGhleFRvUmdiKVxuICAgICAgKTtcblxuICAgIC8vIGNhbGN1bGF0ZSBzdHJva2Ugc2NhbGUgLSBpZiBzdHJva2VkID0gdHJ1ZVxuICAgIGNvbnN0IHNTY2FsZSA9XG4gICAgICBzaXplRmllbGQgJiZcbiAgICAgIHN0cm9rZWQgJiZcbiAgICAgIHRoaXMuZ2V0VmlzQ2hhbm5lbFNjYWxlKHNpemVTY2FsZSwgc2l6ZURvbWFpbiwgc2l6ZVJhbmdlKTtcblxuICAgIHJldHVybiB7XG4gICAgICBkYXRhOiBnZW9qc29uRGF0YSxcbiAgICAgIGdldFBhdGg6IGQgPT4gZC5nZW9tZXRyeS5jb29yZGluYXRlcyxcbiAgICAgIGdldFRpbWVzdGFtcHM6IGQgPT4gdGhpcy5kYXRhVG9UaW1lU3RhbXBbZC5wcm9wZXJ0aWVzLmluZGV4XSxcbiAgICAgIGdldENvbG9yOiBkID0+XG4gICAgICAgIGNTY2FsZVxuICAgICAgICAgID8gdGhpcy5nZXRFbmNvZGVkQ2hhbm5lbFZhbHVlKFxuICAgICAgICAgICAgICBjU2NhbGUsXG4gICAgICAgICAgICAgIGFsbERhdGFbZC5wcm9wZXJ0aWVzLmluZGV4XSxcbiAgICAgICAgICAgICAgY29sb3JGaWVsZFxuICAgICAgICAgICAgKVxuICAgICAgICAgIDogZC5wcm9wZXJ0aWVzLmZpbGxDb2xvciB8fCBjb2xvcixcbiAgICAgIGdldFdpZHRoOiBkID0+XG4gICAgICAgIHNTY2FsZVxuICAgICAgICAgID8gdGhpcy5nZXRFbmNvZGVkQ2hhbm5lbFZhbHVlKFxuICAgICAgICAgICAgICBzU2NhbGUsXG4gICAgICAgICAgICAgIGFsbERhdGFbZC5wcm9wZXJ0aWVzLmluZGV4XSxcbiAgICAgICAgICAgICAgc2l6ZUZpZWxkLFxuICAgICAgICAgICAgICAwXG4gICAgICAgICAgICApXG4gICAgICAgICAgOiBkLnByb3BlcnRpZXMubGluZVdpZHRoIHx8IDFcbiAgICB9O1xuICB9XG4gIC8qIGVzbGludC1lbmFibGUgY29tcGxleGl0eSAqL1xuXG4gIHVwZGF0ZUFuaW1hdGlvbkRvbWFpbihkb21haW4pIHtcbiAgICB0aGlzLnVwZGF0ZUxheWVyQ29uZmlnKHtcbiAgICAgIGFuaW1hdGlvbjoge1xuICAgICAgICAuLi50aGlzLmNvbmZpZy5hbmltYXRpb24sXG4gICAgICAgIGRvbWFpblxuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgdXBkYXRlTGF5ZXJNZXRhKGFsbERhdGEpIHtcbiAgICBjb25zdCBnZXRGZWF0dXJlID0gdGhpcy5nZXRQb3NpdGlvbkFjY2Vzc29yKCk7XG4gICAgaWYgKGdldEZlYXR1cmUgPT09IHRoaXMubWV0YS5nZXRGZWF0dXJlKSB7XG4gICAgICAvLyBUT0RPOiByZXZpc2l0IHRoaXMgYWZ0ZXIgZ3B1IGZpbHRlcmluZ1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuZGF0YVRvRmVhdHVyZSA9IGdldEdlb2pzb25EYXRhTWFwcyhhbGxEYXRhLCBnZXRGZWF0dXJlKTtcblxuICAgIGNvbnN0IHtkYXRhVG9UaW1lU3RhbXAsIGFuaW1hdGlvbkRvbWFpbn0gPVxuICAgICAgcGFyc2VUcmlwR2VvSnNvblRpbWVzdGFtcCh0aGlzLmRhdGFUb0ZlYXR1cmUpO1xuXG4gICAgdGhpcy5kYXRhVG9UaW1lU3RhbXAgPSBkYXRhVG9UaW1lU3RhbXA7XG4gICAgdGhpcy51cGRhdGVBbmltYXRpb25Eb21haW4oYW5pbWF0aW9uRG9tYWluKTtcblxuICAgIC8vIGdldCBib3VuZHMgZnJvbSBmZWF0dXJlc1xuICAgIGNvbnN0IGJvdW5kcyA9IGdldEdlb2pzb25Cb3VuZHModGhpcy5kYXRhVG9GZWF0dXJlKTtcblxuICAgIC8vIGtlZXAgYSByZWNvcmQgb2Ygd2hhdCB0eXBlIG9mIGdlb21ldHJ5IHRoZSBjb2xsZWN0aW9uIGhhc1xuICAgIGNvbnN0IGZlYXR1cmVUeXBlcyA9IGdldEdlb2pzb25GZWF0dXJlVHlwZXModGhpcy5kYXRhVG9GZWF0dXJlKTtcblxuICAgIHRoaXMudXBkYXRlTWV0YSh7Ym91bmRzLCBmZWF0dXJlVHlwZXMsIGdldEZlYXR1cmV9KTtcbiAgfVxuXG4gIHNldEluaXRpYWxMYXllckNvbmZpZyhhbGxEYXRhKSB7XG4gICAgdGhpcy51cGRhdGVMYXllck1ldGEoYWxsRGF0YSk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICByZW5kZXJMYXllcih7ZGF0YSwgaWR4LCBtYXBTdGF0ZSwgYW5pbWF0aW9uQ29uZmlnfSkge1xuICAgIGNvbnN0IHt2aXNDb25maWd9ID0gdGhpcy5jb25maWc7XG4gICAgY29uc3Qgem9vbUZhY3RvciA9IHRoaXMuZ2V0Wm9vbUZhY3RvcihtYXBTdGF0ZSk7XG5cbiAgICBjb25zdCB1cGRhdGVUcmlnZ2VycyA9IHtcbiAgICAgIGdldENvbG9yOiB7XG4gICAgICAgIGNvbG9yOiB0aGlzLmNvbmZpZy5jb2xvcixcbiAgICAgICAgY29sb3JGaWVsZDogdGhpcy5jb25maWcuY29sb3JGaWVsZCxcbiAgICAgICAgY29sb3JSYW5nZTogdmlzQ29uZmlnLmNvbG9yUmFuZ2UsXG4gICAgICAgIGNvbG9yU2NhbGU6IHRoaXMuY29uZmlnLmNvbG9yU2NhbGVcbiAgICAgIH0sXG4gICAgICBnZXRXaWR0aDoge1xuICAgICAgICBzaXplRmllbGQ6IHRoaXMuY29uZmlnLnNpemVGaWVsZCxcbiAgICAgICAgc2l6ZVJhbmdlOiB2aXNDb25maWcuc2l6ZVJhbmdlXG4gICAgICB9LFxuICAgICAgZ2V0VGltZXN0YW1wczoge1xuICAgICAgICBjb2x1bW5zOiB0aGlzLmNvbmZpZy5jb2x1bW5zLFxuICAgICAgICBkb21haW4wOiBhbmltYXRpb25Db25maWcuZG9tYWluWzBdXG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBbXG4gICAgICBuZXcgRGVja0dMVHJpcHNMYXllcih7XG4gICAgICAgIGlkOiB0aGlzLmlkLFxuICAgICAgICBpZHgsXG4gICAgICAgIGRhdGE6IGRhdGEuZGF0YSxcbiAgICAgICAgZ2V0UGF0aDogZGF0YS5nZXRQYXRoLFxuICAgICAgICBnZXRDb2xvcjogZGF0YS5nZXRDb2xvcixcbiAgICAgICAgZ2V0VGltZXN0YW1wczogZCA9PlxuICAgICAgICAgIGRhdGEuZ2V0VGltZXN0YW1wcyhkKS5tYXAodHMgPT4gdHMgLSBhbmltYXRpb25Db25maWcuZG9tYWluWzBdKSxcbiAgICAgICAgb3BhY2l0eTogdGhpcy5jb25maWcudmlzQ29uZmlnLm9wYWNpdHksXG4gICAgICAgIHdpZHRoU2NhbGU6IHRoaXMuY29uZmlnLnZpc0NvbmZpZy50aGlja25lc3MgKiB6b29tRmFjdG9yICogOCxcbiAgICAgICAgaGlnaGxpZ2h0Q29sb3I6IHRoaXMuY29uZmlnLmhpZ2hsaWdodENvbG9yLFxuXG4gICAgICAgIGdldFdpZHRoOiBkYXRhLmdldFdpZHRoLFxuICAgICAgICByb3VuZGVkOiB0cnVlLFxuICAgICAgICBwaWNrYWJsZTogdHJ1ZSxcbiAgICAgICAgYXV0b0hpZ2hsaWdodDogdHJ1ZSxcbiAgICAgICAgcGFyYW1ldGVyczoge1xuICAgICAgICAgIGRlcHRoVGVzdDogbWFwU3RhdGUuZHJhZ1JvdGF0ZSxcbiAgICAgICAgICBkZXB0aE1hc2s6IGZhbHNlXG4gICAgICAgIH0sXG4gICAgICAgIHRyYWlsTGVuZ3RoOiB2aXNDb25maWcudHJhaWxMZW5ndGggKiAxMDAwLFxuICAgICAgICBjdXJyZW50VGltZTogYW5pbWF0aW9uQ29uZmlnLmN1cnJlbnRUaW1lIC0gYW5pbWF0aW9uQ29uZmlnLmRvbWFpblswXSxcbiAgICAgICAgdXBkYXRlVHJpZ2dlcnNcbiAgICAgIH0pXG4gICAgXTtcbiAgfVxufVxuIl19