kepler.gl
Version:
kepler.gl is a webgl based application to visualize large scale location data in the browser
648 lines (621 loc) • 83.6 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.copyTable = copyTable;
exports.copyTableAndUpdate = copyTableAndUpdate;
exports["default"] = void 0;
exports.findPointFieldPairs = findPointFieldPairs;
exports.getFieldValueAccessor = getFieldValueAccessor;
exports.maybeToDate = maybeToDate;
exports.pinTableColumns = pinTableColumns;
exports.sortDatasetByColumn = sortDatasetByColumn;
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _console = _interopRequireDefault(require("global/console"));
var _d3Array = require("d3-array");
var _constants = require("@kepler.gl/constants");
var _gpuFilterUtils = require("./gpu-filter-utils");
var _utils = require("@kepler.gl/utils");
var _commonUtils = require("@kepler.gl/common-utils");
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
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; } // SPDX-License-Identifier: MIT
// Copyright contributors to the kepler.gl project
// TODO isolate layer type, depends on @kepler.gl/layers
// Unique identifier of each field
var FID_KEY = 'name';
function maybeToDate(isTime, fieldIdx, format, dc,
// An object with row index or a materialized row array (for materialized hover info from trip layer)
d) {
if (isTime) {
return (0, _utils.timeToUnixMilli)(Array.isArray(d) ? d[fieldIdx] : dc.valueAt(d.index, fieldIdx), format);
}
return Array.isArray(d) ? d[fieldIdx] : dc.valueAt(d.index, fieldIdx);
}
var KeplerTable = /*#__PURE__*/function () {
function KeplerTable(_ref) {
var info = _ref.info,
color = _ref.color,
metadata = _ref.metadata,
_ref$supportedFilterT = _ref.supportedFilterTypes,
supportedFilterTypes = _ref$supportedFilterT === void 0 ? null : _ref$supportedFilterT,
_ref$disableDataOpera = _ref.disableDataOperation,
disableDataOperation = _ref$disableDataOpera === void 0 ? false : _ref$disableDataOpera;
(0, _classCallCheck2["default"])(this, KeplerTable);
(0, _defineProperty2["default"])(this, "id", void 0);
(0, _defineProperty2["default"])(this, "type", void 0);
(0, _defineProperty2["default"])(this, "label", void 0);
(0, _defineProperty2["default"])(this, "color", void 0);
// fields and data
(0, _defineProperty2["default"])(this, "fields", []);
(0, _defineProperty2["default"])(this, "dataContainer", void 0);
(0, _defineProperty2["default"])(this, "allIndexes", []);
(0, _defineProperty2["default"])(this, "filteredIndex", []);
(0, _defineProperty2["default"])(this, "filteredIdxCPU", void 0);
(0, _defineProperty2["default"])(this, "filteredIndexForDomain", []);
(0, _defineProperty2["default"])(this, "fieldPairs", []);
(0, _defineProperty2["default"])(this, "gpuFilter", void 0);
(0, _defineProperty2["default"])(this, "filterRecord", void 0);
(0, _defineProperty2["default"])(this, "filterRecordCPU", void 0);
(0, _defineProperty2["default"])(this, "changedFilters", void 0);
// table-injected metadata
(0, _defineProperty2["default"])(this, "sortColumn", void 0);
(0, _defineProperty2["default"])(this, "sortOrder", void 0);
(0, _defineProperty2["default"])(this, "pinnedColumns", void 0);
(0, _defineProperty2["default"])(this, "supportedFilterTypes", void 0);
(0, _defineProperty2["default"])(this, "disableDataOperation", void 0);
// table-injected metadata
(0, _defineProperty2["default"])(this, "metadata", void 0);
(0, _defineProperty2["default"])(this, "getFileProcessor", void 0);
// TODO - what to do if validation fails? Can kepler handle exceptions?
// const validatedData = validateInputData(data);
// if (!validatedData) {
// return this;
// }
var datasetInfo = _objectSpread({
id: (0, _commonUtils.generateHashId)(4),
label: 'new dataset',
type: ''
}, info);
var defaultMetadata = {
id: datasetInfo.id,
// @ts-ignore
format: datasetInfo.format || '',
label: datasetInfo.label || ''
};
this.id = datasetInfo.id;
this.type = datasetInfo.type;
this.label = datasetInfo.label;
this.color = color;
this.metadata = _objectSpread(_objectSpread({}, defaultMetadata), metadata);
this.supportedFilterTypes = supportedFilterTypes;
this.disableDataOperation = disableDataOperation;
this.dataContainer = (0, _utils.createDataContainer)([]);
this.gpuFilter = (0, _gpuFilterUtils.getGpuFilterProps)([], this.id, [], undefined);
}
return (0, _createClass2["default"])(KeplerTable, [{
key: "importData",
value: function () {
var _importData = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee(_ref2) {
var data, dataContainerData, inputDataFormat, dataContainer, fields, allIndexes;
return _regenerator["default"].wrap(function _callee$(_context) {
while (1) switch (_context.prev = _context.next) {
case 0:
data = _ref2.data;
dataContainerData = data.cols ? data.cols : data.rows;
inputDataFormat = data.cols ? _utils.DataForm.COLS_ARRAY : _utils.DataForm.ROWS_ARRAY;
dataContainer = (0, _utils.createDataContainer)(dataContainerData, {
fields: data.fields,
arrowTable: data.arrowTable,
inputDataFormat: inputDataFormat
});
fields = data.fields.map(function (f, i) {
return _objectSpread(_objectSpread({}, f), {}, {
fieldIdx: i,
id: f.name,
displayName: f.displayName || f.name,
analyzerType: f.analyzerType || _constants.ALL_FIELD_TYPES.string,
format: f.format || '',
valueAccessor: getFieldValueAccessor(f, i, dataContainer)
});
});
allIndexes = dataContainer.getPlainIndex();
this.dataContainer = dataContainer;
this.allIndexes = allIndexes;
this.filteredIndex = allIndexes;
this.filteredIndexForDomain = allIndexes;
this.fieldPairs = findPointFieldPairs(fields);
// @ts-expect-error Make sure that fields satisfies F extends Field
this.fields = fields;
this.gpuFilter = (0, _gpuFilterUtils.getGpuFilterProps)([], this.id, fields, undefined);
case 13:
case "end":
return _context.stop();
}
}, _callee, this);
}));
function importData(_x) {
return _importData.apply(this, arguments);
}
return importData;
}()
/**
* update table with new data
* @param data - new data e.g. the arrow data with new batches loaded
*/
}, {
key: "update",
value: (function () {
var _update = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee2(data) {
var _ref3, _data$arrowTable, _this$dataContainer$u, _this$dataContainer;
var dataContainerData;
return _regenerator["default"].wrap(function _callee2$(_context2) {
while (1) switch (_context2.prev = _context2.next) {
case 0:
dataContainerData = (_ref3 = (_data$arrowTable = data.arrowTable) !== null && _data$arrowTable !== void 0 ? _data$arrowTable : data.cols) !== null && _ref3 !== void 0 ? _ref3 : data.rows;
(_this$dataContainer$u = (_this$dataContainer = this.dataContainer).update) === null || _this$dataContainer$u === void 0 || _this$dataContainer$u.call(_this$dataContainer, dataContainerData);
this.allIndexes = this.dataContainer.getPlainIndex();
this.filteredIndex = this.allIndexes;
this.filteredIndexForDomain = this.allIndexes;
return _context2.abrupt("return", this);
case 6:
case "end":
return _context2.stop();
}
}, _callee2, this);
}));
function update(_x2) {
return _update.apply(this, arguments);
}
return update;
}())
}, {
key: "length",
get: function get() {
return this.dataContainer.numRows();
}
/**
* Get field
* @param columnName
*/
}, {
key: "getColumnField",
value: function getColumnField(columnName) {
var field = this.fields.find(function (fd) {
return fd[FID_KEY] === columnName;
});
this._assetField(columnName, field);
return field;
}
/**
* Get fieldIdx
* @param columnName
*/
}, {
key: "getColumnFieldIdx",
value: function getColumnFieldIdx(columnName) {
var fieldIdx = this.fields.findIndex(function (fd) {
return fd[FID_KEY] === columnName;
});
this._assetField(columnName, Boolean(fieldIdx > -1));
return fieldIdx;
}
/**
* Get displayFormat
* @param columnName
*/
}, {
key: "getColumnDisplayFormat",
value: function getColumnDisplayFormat(columnName) {
var field = this.fields.find(function (fd) {
return fd[FID_KEY] === columnName;
});
this._assetField(columnName, field);
return field === null || field === void 0 ? void 0 : field.displayFormat;
}
/**
* Get the value of a cell
*/
}, {
key: "getValue",
value: function getValue(columnName, rowIdx) {
var field = this.getColumnField(columnName);
return field ? field.valueAccessor({
index: rowIdx
}) : null;
}
/**
* Updates existing field with a new object
* @param fieldIdx
* @param newField
*/
}, {
key: "updateColumnField",
value: function updateColumnField(fieldIdx, newField) {
this.fields = Object.assign((0, _toConsumableArray2["default"])(this.fields), (0, _defineProperty2["default"])({}, fieldIdx, newField));
}
/**
* Update dataset color by custom color
* @param newColor
*/
}, {
key: "updateTableColor",
value: function updateTableColor(newColor) {
this.color = newColor;
}
/**
* Save filterProps to field and retrieve it
* @param columnName
*/
}, {
key: "getColumnFilterProps",
value: function getColumnFilterProps(columnName) {
var fieldIdx = this.getColumnFieldIdx(columnName);
if (fieldIdx < 0) {
return null;
}
var field = this.fields[fieldIdx];
if (Object.prototype.hasOwnProperty.call(field, 'filterProps')) {
return field.filterProps;
}
var fieldDomain = this.getColumnFilterDomain(field);
if (!fieldDomain) {
return null;
}
var filterProps = (0, _utils.getFilterProps)(field, fieldDomain);
var newField = _objectSpread(_objectSpread({}, field), {}, {
filterProps: filterProps
});
this.updateColumnField(fieldIdx, newField);
return filterProps;
}
/**
* Apply filters to dataset, return the filtered dataset with updated `gpuFilter`, `filterRecord`, `filteredIndex`, `filteredIndexForDomain`
* @param filters
* @param layers
* @param opt
*/
}, {
key: "filterTable",
value: function filterTable(filters, layers, opt) {
var _this = this;
var dataContainer = this.dataContainer,
dataId = this.id,
oldFilterRecord = this.filterRecord,
fields = this.fields;
// if there is no filters
var filterRecord = (0, _utils.getFilterRecord)(dataId, filters, opt || {});
this.filterRecord = filterRecord;
this.gpuFilter = (0, _gpuFilterUtils.getGpuFilterProps)(filters, dataId, fields, this.gpuFilter);
this.changedFilters = (0, _utils.diffFilters)(filterRecord, oldFilterRecord);
if (!filters.length) {
this.filteredIndex = this.allIndexes;
this.filteredIndexForDomain = this.allIndexes;
return this;
}
// generate 2 sets of filter result
// filteredIndex used to calculate layer data
// filteredIndexForDomain used to calculate layer Domain
var shouldCalDomain = Boolean(this.changedFilters.dynamicDomain);
var shouldCalIndex = Boolean(this.changedFilters.cpu);
var filterResult = {};
if (shouldCalDomain || shouldCalIndex) {
var dynamicDomainFilters = shouldCalDomain ? filterRecord.dynamicDomain : null;
var cpuFilters = shouldCalIndex ? filterRecord.cpu : null;
var filterFuncs = filters.reduce(function (acc, filter) {
var fieldIndex = (0, _gpuFilterUtils.getDatasetFieldIndexForFilter)(_this.id, filter);
var field = fieldIndex !== -1 ? fields[fieldIndex] : null;
return _objectSpread(_objectSpread({}, acc), {}, (0, _defineProperty2["default"])({}, filter.id, (0, _utils.getFilterFunction)(field, _this.id, filter, layers, dataContainer)));
}, {});
filterResult = (0, _utils.filterDataByFilterTypes)({
dynamicDomainFilters: dynamicDomainFilters,
cpuFilters: cpuFilters,
filterFuncs: filterFuncs
}, dataContainer);
}
this.filteredIndex = filterResult.filteredIndex || this.filteredIndex;
this.filteredIndexForDomain = filterResult.filteredIndexForDomain || this.filteredIndexForDomain;
return this;
}
/**
* Apply filters to a dataset all on CPU, assign to `filteredIdxCPU`, `filterRecordCPU`
* @param filters
* @param layers
*/
}, {
key: "filterTableCPU",
value: function filterTableCPU(filters, layers) {
var opt = {
cpuOnly: true,
ignoreDomain: true
};
// no filter
if (!filters.length) {
this.filteredIdxCPU = this.allIndexes;
this.filterRecordCPU = (0, _utils.getFilterRecord)(this.id, filters, opt);
return this;
}
// no gpu filter
if (!filters.find(function (f) {
return f.gpu;
})) {
this.filteredIdxCPU = this.filteredIndex;
this.filterRecordCPU = (0, _utils.getFilterRecord)(this.id, filters, opt);
return this;
}
// make a copy for cpu filtering
var copied = copyTable(this);
copied.filterRecord = this.filterRecordCPU;
copied.filteredIndex = this.filteredIdxCPU || [];
var filtered = copied.filterTable(filters, layers, opt);
this.filteredIdxCPU = filtered.filteredIndex;
this.filterRecordCPU = filtered.filterRecord;
return this;
}
/**
* Calculate field domain based on field type and data
* for Filter
*/
}, {
key: "getColumnFilterDomain",
value: function getColumnFilterDomain(field) {
var dataContainer = this.dataContainer;
var valueAccessor = field.valueAccessor;
var domain;
switch (field.type) {
case _constants.ALL_FIELD_TYPES.real:
case _constants.ALL_FIELD_TYPES.integer:
// calculate domain and step
return (0, _utils.getNumericFieldDomain)(dataContainer, valueAccessor);
case _constants.ALL_FIELD_TYPES["boolean"]:
return {
domain: [true, false]
};
case _constants.ALL_FIELD_TYPES.string:
case _constants.ALL_FIELD_TYPES.h3:
case _constants.ALL_FIELD_TYPES.date:
domain = (0, _utils.getOrdinalDomain)(dataContainer, valueAccessor);
return {
domain: domain
};
case _constants.ALL_FIELD_TYPES.timestamp:
return (0, _utils.getTimestampFieldDomain)(dataContainer, valueAccessor);
default:
return {
domain: (0, _utils.getOrdinalDomain)(dataContainer, valueAccessor)
};
}
}
/**
* Get the domain of this column based on scale type
*/
}, {
key: "getColumnLayerDomain",
value: function getColumnLayerDomain(field, scaleType) {
var dataContainer = this.dataContainer,
filteredIndexForDomain = this.filteredIndexForDomain;
if (!_constants.SCALE_TYPES[scaleType]) {
_console["default"].error("scale type ".concat(scaleType, " not supported"));
return null;
}
var valueAccessor = field.valueAccessor;
var indexValueAccessor = function indexValueAccessor(i) {
return valueAccessor({
index: i
});
};
var sortFunction = (0, _utils.getSortingFunction)(field.type);
switch (scaleType) {
case _constants.SCALE_TYPES.ordinal:
case _constants.SCALE_TYPES.customOrdinal:
case _constants.SCALE_TYPES.point:
// do not recalculate ordinal domain based on filtered data
// don't need to update ordinal domain every time
return (0, _utils.getOrdinalDomain)(dataContainer, valueAccessor);
case _constants.SCALE_TYPES.quantile:
return (0, _utils.getQuantileDomain)(filteredIndexForDomain, indexValueAccessor, sortFunction);
case _constants.SCALE_TYPES.log:
return (0, _utils.getLogDomain)(filteredIndexForDomain, indexValueAccessor);
case _constants.SCALE_TYPES.quantize:
case _constants.SCALE_TYPES.linear:
case _constants.SCALE_TYPES.sqrt:
case _constants.SCALE_TYPES.custom:
default:
return (0, _utils.getLinearDomain)(filteredIndexForDomain, indexValueAccessor);
}
}
/**
* Get a sample of rows to calculate layer boundaries
*/
// getSampleData(rows)
/**
* Parse cell value based on column type and return a string representation
* Value the field value, type the field type
*/
// parseFieldValue(value, type)
// sortDatasetByColumn()
/**
* Assert whether field exist
* @param fieldName
* @param condition
*/
}, {
key: "_assetField",
value: function _assetField(fieldName, condition) {
if (!condition) {
_console["default"].error("".concat(fieldName, " doesnt exist in dataset ").concat(this.id));
}
}
}]);
}();
// HELPER FUNCTIONS (MAINLY EXPORTED FOR TEST...)
// have to double excape
var specialCharacterSet = "[#_&@\\.\\-\\ ]";
function foundMatchingFields(re, suffixPair, allNames, fieldName) {
var partnerIdx = allNames.findIndex(function (d) {
return d === fieldName.replace(re, function (match) {
return match.replace(suffixPair[0], suffixPair[1]);
});
});
var altIdx = -1;
if (partnerIdx > -1) {
// if found partner, go on and look for altitude
_constants.ALTITUDE_FIELDS.some(function (alt) {
altIdx = allNames.findIndex(function (d) {
return d === fieldName.replace(re, function (match) {
return match.replace(suffixPair[0], alt);
});
});
return altIdx > -1;
});
}
return {
partnerIdx: partnerIdx,
altIdx: altIdx
};
}
/**
* Find point fields pairs from fields
*
* @param fields
* @returns found point fields
*/
function findPointFieldPairs(fields) {
var allNames = fields.map(function (f) {
return f.name.toLowerCase();
});
// get list of all fields with matching suffixes
var acc = [];
return allNames.reduce(function (carry, fieldName, idx) {
// This search for pairs will early exit if found.
var _iterator = _createForOfIteratorHelper(_constants.TRIP_POINT_FIELDS),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var suffixPair = _step.value;
// match first suffix
// (^|[#_&@\.\-\ ])lat([#_&@\.\-\ ]|$)
var re = new RegExp("(^|".concat(specialCharacterSet, ")").concat(suffixPair[0], "(").concat(specialCharacterSet, "|$)"));
if (re.test(fieldName)) {
var _foundMatchingFields = foundMatchingFields(re, suffixPair, allNames, fieldName),
partnerIdx = _foundMatchingFields.partnerIdx,
altIdx = _foundMatchingFields.altIdx;
if (partnerIdx > -1) {
var trimName = fieldName.replace(re, '').trim();
carry.push({
defaultName: trimName || 'point',
pair: _objectSpread({
lat: {
fieldIdx: idx,
value: fields[idx].name
},
lng: {
fieldIdx: partnerIdx,
value: fields[partnerIdx].name
}
}, altIdx > -1 ? {
altitude: {
fieldIdx: altIdx,
value: fields[altIdx].name
}
} : {}),
suffix: suffixPair
});
return carry;
}
}
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
return carry;
}, acc);
}
/**
*
* @param dataset
* @param column
* @param mode
* @type
*/
function sortDatasetByColumn(dataset, column, mode) {
var allIndexes = dataset.allIndexes,
fields = dataset.fields,
dataContainer = dataset.dataContainer;
var fieldIndex = fields.findIndex(function (f) {
return f.name === column;
});
if (fieldIndex < 0) {
return dataset;
}
var sortBy = _constants.SORT_ORDER[mode || ''] || _constants.SORT_ORDER.ASCENDING;
if (sortBy === _constants.SORT_ORDER.UNSORT) {
dataset.sortColumn = {};
dataset.sortOrder = null;
return dataset;
}
var sortFunction = sortBy === _constants.SORT_ORDER.ASCENDING ? _d3Array.ascending : _d3Array.descending;
var sortOrder = allIndexes.slice().sort(function (a, b) {
var value1 = dataContainer.valueAt(a, fieldIndex);
var value2 = dataContainer.valueAt(b, fieldIndex);
if (!(0, _commonUtils.notNullorUndefined)(value1) && (0, _commonUtils.notNullorUndefined)(value2)) {
return 1;
} else if ((0, _commonUtils.notNullorUndefined)(value1) && !(0, _commonUtils.notNullorUndefined)(value2)) {
return -1;
}
return sortFunction(value1, value2);
});
dataset.sortColumn = (0, _defineProperty2["default"])({}, column, sortBy);
dataset.sortOrder = sortOrder;
return dataset;
}
function pinTableColumns(dataset, column) {
var field = dataset.getColumnField(column);
if (!field) {
return dataset;
}
var pinnedColumns;
if (Array.isArray(dataset.pinnedColumns) && dataset.pinnedColumns.includes(field.name)) {
// unpin it
pinnedColumns = dataset.pinnedColumns.filter(function (co) {
return co !== field.name;
});
} else {
pinnedColumns = (dataset.pinnedColumns || []).concat(field.name);
}
// @ts-ignore
return copyTableAndUpdate(dataset, {
pinnedColumns: pinnedColumns
});
}
function copyTable(original) {
return Object.assign(Object.create(Object.getPrototypeOf(original)), original);
}
/**
* @type
* @returns
*/
function copyTableAndUpdate(original) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
return Object.entries(options).reduce(function (acc, entry) {
acc[entry[0]] = entry[1];
return acc;
}, copyTable(original));
}
function getFieldValueAccessor(f, i, dc) {
return maybeToDate.bind(null,
// is time
f.type === _constants.ALL_FIELD_TYPES.timestamp, i, f.format || '', dc);
}
var _default = exports["default"] = KeplerTable;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfY29uc29sZSIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJyZXF1aXJlIiwiX2QzQXJyYXkiLCJfY29uc3RhbnRzIiwiX2dwdUZpbHRlclV0aWxzIiwiX3V0aWxzIiwiX2NvbW1vblV0aWxzIiwiX2NyZWF0ZUZvck9mSXRlcmF0b3JIZWxwZXIiLCJyIiwiZSIsInQiLCJTeW1ib2wiLCJpdGVyYXRvciIsIkFycmF5IiwiaXNBcnJheSIsIl91bnN1cHBvcnRlZEl0ZXJhYmxlVG9BcnJheSIsImxlbmd0aCIsIl9uIiwiRiIsInMiLCJuIiwiZG9uZSIsInZhbHVlIiwiZiIsIlR5cGVFcnJvciIsIm8iLCJhIiwidSIsImNhbGwiLCJuZXh0IiwiX2FycmF5TGlrZVRvQXJyYXkiLCJ0b1N0cmluZyIsInNsaWNlIiwiY29uc3RydWN0b3IiLCJuYW1lIiwiZnJvbSIsInRlc3QiLCJvd25LZXlzIiwiT2JqZWN0Iiwia2V5cyIsImdldE93blByb3BlcnR5U3ltYm9scyIsImZpbHRlciIsImdldE93blByb3BlcnR5RGVzY3JpcHRvciIsImVudW1lcmFibGUiLCJwdXNoIiwiYXBwbHkiLCJfb2JqZWN0U3ByZWFkIiwiYXJndW1lbnRzIiwiZm9yRWFjaCIsIl9kZWZpbmVQcm9wZXJ0eTIiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzIiwiZGVmaW5lUHJvcGVydGllcyIsImRlZmluZVByb3BlcnR5IiwiRklEX0tFWSIsIm1heWJlVG9EYXRlIiwiaXNUaW1lIiwiZmllbGRJZHgiLCJmb3JtYXQiLCJkYyIsImQiLCJ0aW1lVG9Vbml4TWlsbGkiLCJ2YWx1ZUF0IiwiaW5kZXgiLCJLZXBsZXJUYWJsZSIsIl9yZWYiLCJpbmZvIiwiY29sb3IiLCJtZXRhZGF0YSIsIl9yZWYkc3VwcG9ydGVkRmlsdGVyVCIsInN1cHBvcnRlZEZpbHRlclR5cGVzIiwiX3JlZiRkaXNhYmxlRGF0YU9wZXJhIiwiZGlzYWJsZURhdGFPcGVyYXRpb24iLCJfY2xhc3NDYWxsQ2hlY2syIiwiZGF0YXNldEluZm8iLCJpZCIsImdlbmVyYXRlSGFzaElkIiwibGFiZWwiLCJ0eXBlIiwiZGVmYXVsdE1ldGFkYXRhIiwiZGF0YUNvbnRhaW5lciIsImNyZWF0ZURhdGFDb250YWluZXIiLCJncHVGaWx0ZXIiLCJnZXRHcHVGaWx0ZXJQcm9wcyIsInVuZGVmaW5lZCIsIl9jcmVhdGVDbGFzczIiLCJrZXkiLCJfaW1wb3J0RGF0YSIsIl9hc3luY1RvR2VuZXJhdG9yMiIsIl9yZWdlbmVyYXRvciIsIm1hcmsiLCJfY2FsbGVlIiwiX3JlZjIiLCJkYXRhIiwiZGF0YUNvbnRhaW5lckRhdGEiLCJpbnB1dERhdGFGb3JtYXQiLCJmaWVsZHMiLCJhbGxJbmRleGVzIiwid3JhcCIsIl9jYWxsZWUkIiwiX2NvbnRleHQiLCJwcmV2IiwiY29scyIsInJvd3MiLCJEYXRhRm9ybSIsIkNPTFNfQVJSQVkiLCJST1dTX0FSUkFZIiwiYXJyb3dUYWJsZSIsIm1hcCIsImkiLCJkaXNwbGF5TmFtZSIsImFuYWx5emVyVHlwZSIsIkFMTF9GSUVMRF9UWVBFUyIsInN0cmluZyIsInZhbHVlQWNjZXNzb3IiLCJnZXRGaWVsZFZhbHVlQWNjZXNzb3IiLCJnZXRQbGFpbkluZGV4IiwiZmlsdGVyZWRJbmRleCIsImZpbHRlcmVkSW5kZXhGb3JEb21haW4iLCJmaWVsZFBhaXJzIiwiZmluZFBvaW50RmllbGRQYWlycyIsInN0b3AiLCJpbXBvcnREYXRhIiwiX3giLCJfdXBkYXRlIiwiX2NhbGxlZTIiLCJfcmVmMyIsIl9kYXRhJGFycm93VGFibGUiLCJfdGhpcyRkYXRhQ29udGFpbmVyJHUiLCJfdGhpcyRkYXRhQ29udGFpbmVyIiwiX2NhbGxlZTIkIiwiX2NvbnRleHQyIiwidXBkYXRlIiwiYWJydXB0IiwiX3gyIiwiZ2V0IiwibnVtUm93cyIsImdldENvbHVtbkZpZWxkIiwiY29sdW1uTmFtZSIsImZpZWxkIiwiZmluZCIsImZkIiwiX2Fzc2V0RmllbGQiLCJnZXRDb2x1bW5GaWVsZElkeCIsImZpbmRJbmRleCIsIkJvb2xlYW4iLCJnZXRDb2x1bW5EaXNwbGF5Rm9ybWF0IiwiZGlzcGxheUZvcm1hdCIsImdldFZhbHVlIiwicm93SWR4IiwidXBkYXRlQ29sdW1uRmllbGQiLCJuZXdGaWVsZCIsImFzc2lnbiIsIl90b0NvbnN1bWFibGVBcnJheTIiLCJ1cGRhdGVUYWJsZUNvbG9yIiwibmV3Q29sb3IiLCJnZXRDb2x1bW5GaWx0ZXJQcm9wcyIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiZmlsdGVyUHJvcHMiLCJmaWVsZERvbWFpbiIsImdldENvbHVtbkZpbHRlckRvbWFpbiIsImdldEZpbHRlclByb3BzIiwiZmlsdGVyVGFibGUiLCJmaWx0ZXJzIiwibGF5ZXJzIiwib3B0IiwiX3RoaXMiLCJkYXRhSWQiLCJvbGRGaWx0ZXJSZWNvcmQiLCJmaWx0ZXJSZWNvcmQiLCJnZXRGaWx0ZXJSZWNvcmQiLCJjaGFuZ2VkRmlsdGVycyIsImRpZmZGaWx0ZXJzIiwic2hvdWxkQ2FsRG9tYWluIiwiZHluYW1pY0RvbWFpbiIsInNob3VsZENhbEluZGV4IiwiY3B1IiwiZmlsdGVyUmVzdWx0IiwiZHluYW1pY0RvbWFpbkZpbHRlcnMiLCJjcHVGaWx0ZXJzIiwiZmlsdGVyRnVuY3MiLCJyZWR1Y2UiLCJhY2MiLCJmaWVsZEluZGV4IiwiZ2V0RGF0YXNldEZpZWxkSW5kZXhGb3JGaWx0ZXIiLCJnZXRGaWx0ZXJGdW5jdGlvbiIsImZpbHRlckRhdGFCeUZpbHRlclR5cGVzIiwiZmlsdGVyVGFibGVDUFUiLCJjcHVPbmx5IiwiaWdub3JlRG9tYWluIiwiZmlsdGVyZWRJZHhDUFUiLCJmaWx0ZXJSZWNvcmRDUFUiLCJncHUiLCJjb3BpZWQiLCJjb3B5VGFibGUiLCJmaWx0ZXJlZCIsImRvbWFpbiIsInJlYWwiLCJpbnRlZ2VyIiwiZ2V0TnVtZXJpY0ZpZWxkRG9tYWluIiwiaDMiLCJkYXRlIiwiZ2V0T3JkaW5hbERvbWFpbiIsInRpbWVzdGFtcCIsImdldFRpbWVzdGFtcEZpZWxkRG9tYWluIiwiZ2V0Q29sdW1uTGF5ZXJEb21haW4iLCJzY2FsZVR5cGUiLCJTQ0FMRV9UWVBFUyIsIkNvbnNvbGUiLCJlcnJvciIsImNvbmNhdCIsImluZGV4VmFsdWVBY2Nlc3NvciIsInNvcnRGdW5jdGlvbiIsImdldFNvcnRpbmdGdW5jdGlvbiIsIm9yZGluYWwiLCJjdXN0b21PcmRpbmFsIiwicG9pbnQiLCJxdWFudGlsZSIsImdldFF1YW50aWxlRG9tYWluIiwibG9nIiwiZ2V0TG9nRG9tYWluIiwicXVhbnRpemUiLCJsaW5lYXIiLCJzcXJ0IiwiY3VzdG9tIiwiZ2V0TGluZWFyRG9tYWluIiwiZmllbGROYW1lIiwiY29uZGl0aW9uIiwic3BlY2lhbENoYXJhY3RlclNldCIsImZvdW5kTWF0Y2hpbmdGaWVsZHMiLCJyZSIsInN1ZmZpeFBhaXIiLCJhbGxOYW1lcyIsInBhcnRuZXJJZHgiLCJyZXBsYWNlIiwibWF0Y2giLCJhbHRJZHgiLCJBTFRJVFVERV9GSUVMRFMiLCJzb21lIiwiYWx0IiwidG9Mb3dlckNhc2UiLCJjYXJyeSIsImlkeCIsIl9pdGVyYXRvciIsIlRSSVBfUE9JTlRfRklFTERTIiwiX3N0ZXAiLCJSZWdFeHAiLCJfZm91bmRNYXRjaGluZ0ZpZWxkcyIsInRyaW1OYW1lIiwidHJpbSIsImRlZmF1bHROYW1lIiwicGFpciIsImxhdCIsImxuZyIsImFsdGl0dWRlIiwic3VmZml4IiwiZXJyIiwic29ydERhdGFzZXRCeUNvbHVtbiIsImRhdGFzZXQiLCJjb2x1bW4iLCJtb2RlIiwic29ydEJ5IiwiU09SVF9PUkRFUiIsIkFTQ0VORElORyIsIlVOU09SVCIsInNvcnRDb2x1bW4iLCJzb3J0T3JkZXIiLCJhc2NlbmRpbmciLCJkZXNjZW5kaW5nIiwic29ydCIsImIiLCJ2YWx1ZTEiLCJ2YWx1ZTIiLCJub3ROdWxsb3JVbmRlZmluZWQiLCJwaW5UYWJsZUNvbHVtbnMiLCJwaW5uZWRDb2x1bW5zIiwiaW5jbHVkZXMiLCJjbyIsImNvcHlUYWJsZUFuZFVwZGF0ZSIsIm9yaWdpbmFsIiwiY3JlYXRlIiwiZ2V0UHJvdG90eXBlT2YiLCJvcHRpb25zIiwiZW50cmllcyIsImVudHJ5IiwiYmluZCIsIl9kZWZhdWx0IiwiZXhwb3J0cyJdLCJzb3VyY2VzIjpbIi4uL3NyYy9rZXBsZXItdGFibGUudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IE1JVFxuLy8gQ29weXJpZ2h0IGNvbnRyaWJ1dG9ycyB0byB0aGUga2VwbGVyLmdsIHByb2plY3RcblxuaW1wb3J0IENvbnNvbGUgZnJvbSAnZ2xvYmFsL2NvbnNvbGUnO1xuaW1wb3J0IHthc2NlbmRpbmcsIGRlc2NlbmRpbmd9IGZyb20gJ2QzLWFycmF5JztcblxuaW1wb3J0IHtcbiAgVFJJUF9QT0lOVF9GSUVMRFMsXG4gIFNPUlRfT1JERVIsXG4gIEFMTF9GSUVMRF9UWVBFUyxcbiAgQUxUSVRVREVfRklFTERTLFxuICBTQ0FMRV9UWVBFU1xufSBmcm9tICdAa2VwbGVyLmdsL2NvbnN0YW50cyc7XG5pbXBvcnQge1xuICBSR0JDb2xvcixcbiAgRmllbGQsXG4gIEZpZWxkUGFpcixcbiAgRmllbGREb21haW4sXG4gIEZpbHRlcixcbiAgUHJvdG9EYXRhc2V0LFxuICBGaWx0ZXJSZWNvcmQsXG4gIEZpbHRlckRhdGFzZXRPcHQsXG4gIFJhbmdlRmllbGREb21haW4sXG4gIFNlbGVjdEZpZWxkRG9tYWluLFxuICBNdWx0aVNlbGVjdEZpZWxkRG9tYWluLFxuICBUaW1lUmFuZ2VGaWVsZERvbWFpblxufSBmcm9tICdAa2VwbGVyLmdsL3R5cGVzJztcblxuaW1wb3J0IHtnZXRHcHVGaWx0ZXJQcm9wcywgZ2V0RGF0YXNldEZpZWxkSW5kZXhGb3JGaWx0ZXJ9IGZyb20gJy4vZ3B1LWZpbHRlci11dGlscyc7XG5cbmltcG9ydCB7XG4gIGdldFNvcnRpbmdGdW5jdGlvbixcbiAgdGltZVRvVW5peE1pbGxpLFxuICBjcmVhdGVEYXRhQ29udGFpbmVyLFxuICBEYXRhRm9ybSxcbiAgZGlmZkZpbHRlcnMsXG4gIGZpbHRlckRhdGFCeUZpbHRlclR5cGVzLFxuICBGaWx0ZXJSZXN1bHQsXG4gIGdldEZpbHRlckZ1bmN0aW9uLFxuICBnZXRGaWx0ZXJQcm9wcyxcbiAgZ2V0RmlsdGVyUmVjb3JkLFxuICBnZXROdW1lcmljRmllbGREb21haW4sXG4gIGdldFRpbWVzdGFtcEZpZWxkRG9tYWluLFxuICBnZXRMaW5lYXJEb21haW4sXG4gIGdldExvZ0RvbWFpbixcbiAgZ2V0T3JkaW5hbERvbWFpbixcbiAgZ2V0UXVhbnRpbGVEb21haW4sXG4gIERhdGFDb250YWluZXJJbnRlcmZhY2UsXG4gIEZpbHRlckNoYW5nZWRcbn0gZnJvbSAnQGtlcGxlci5nbC91dGlscyc7XG5pbXBvcnQge2dlbmVyYXRlSGFzaElkLCBub3ROdWxsb3JVbmRlZmluZWR9IGZyb20gJ0BrZXBsZXIuZ2wvY29tbW9uLXV0aWxzJztcblxuLy8gVE9ETyBpc29sYXRlIGxheWVyIHR5cGUsIGRlcGVuZHMgb24gQGtlcGxlci5nbC9sYXllcnNcbnR5cGUgTGF5ZXIgPSBhbnk7XG5cbmV4cG9ydCB0eXBlIEdwdUZpbHRlciA9IHtcbiAgZmlsdGVyUmFuZ2U6IG51bWJlcltdW107XG4gIGZpbHRlclZhbHVlVXBkYXRlVHJpZ2dlcnM6IHtcbiAgICBbaWQ6IHN0cmluZ106IHtuYW1lOiBzdHJpbmc7IGRvbWFpbjA6IG51bWJlcn0gfCBudWxsO1xuICB9O1xuICBmaWx0ZXJWYWx1ZUFjY2Vzc29yOiAoXG4gICAgZGM6IERhdGFDb250YWluZXJJbnRlcmZhY2VcbiAgKSA9PiAoXG4gICAgZ2V0SW5kZXg/OiAoYW55KSA9PiBudW1iZXIsXG4gICAgZ2V0RGF0YT86IChkY186IERhdGFDb250YWluZXJJbnRlcmZhY2UsIGQ6IGFueSwgZmllbGRJbmRleDogbnVtYmVyKSA9PiBhbnlcbiAgKSA9PiAoZDogYW55LCBvYmplY3RJbmZvPzoge2luZGV4OiBudW1iZXJ9KSA9PiAobnVtYmVyIHwgbnVtYmVyW10pW107XG59O1xuXG5leHBvcnQgdHlwZSBGaWx0ZXJQcm9wcyA9XG4gIHwgTnVtZXJpY0ZpZWxkRmlsdGVyUHJvcHNcbiAgfCBCb29sZWFuRmllbGRGaWx0ZXJQcm9wc1xuICB8IFN0cmluZ0ZpZWxkRmlsdGVyUHJvcHNcbiAgfCBUaW1lRmllbGRGaWx0ZXJQcm9wcztcblxuZXhwb3J0IHR5cGUgTnVtZXJpY0ZpZWxkRmlsdGVyUHJvcHMgPSBSYW5nZUZpZWxkRG9tYWluICYge1xuICB2YWx1ZTogW251bWJlciwgbnVtYmVyXTtcbiAgdHlwZTogc3RyaW5nO1xuICB0eXBlT3B0aW9uczogc3RyaW5nW107XG4gIGdwdTogYm9vbGVhbjtcbiAgY29sdW1uU3RhdHM/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xufTtcbmV4cG9ydCB0eXBlIEJvb2xlYW5GaWVsZEZpbHRlclByb3BzID0gU2VsZWN0RmllbGREb21haW4gJiB7XG4gIHR5cGU6IHN0cmluZztcbiAgdmFsdWU6IGJvb2xlYW47XG4gIGdwdTogYm9vbGVhbjtcbiAgY29sdW1uU3RhdHM/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xufTtcbmV4cG9ydCB0eXBlIFN0cmluZ0ZpZWxkRmlsdGVyUHJvcHMgPSBNdWx0aVNlbGVjdEZpZWxkRG9tYWluICYge1xuICB0eXBlOiBzdHJpbmc7XG4gIHZhbHVlOiBzdHJpbmdbXTtcbiAgZ3B1OiBib29sZWFuO1xuICBjb2x1bW5TdGF0cz86IFJlY29yZDxzdHJpbmcsIGFueT47XG59O1xuZXhwb3J0IHR5cGUgVGltZUZpZWxkRmlsdGVyUHJvcHMgPSBUaW1lUmFuZ2VGaWVsZERvbWFpbiAmIHtcbiAgdHlwZTogc3RyaW5nO1xuICB2aWV3OiBGaWx0ZXJbJ3ZpZXcnXTtcbiAgZml4ZWREb21haW46IGJvb2xlYW47XG4gIHZhbHVlOiBudW1iZXJbXTtcbiAgZ3B1OiBib29sZWFuO1xuICBjb2x1bW5TdGF0cz86IFJlY29yZDxzdHJpbmcsIGFueT47XG59O1xuXG4vLyBVbmlxdWUgaWRlbnRpZmllciBvZiBlYWNoIGZpZWxkXG5jb25zdCBGSURfS0VZID0gJ25hbWUnO1xuXG5leHBvcnQgZnVuY3Rpb24gbWF5YmVUb0RhdGUoXG4gIGlzVGltZTogYm9vbGVhbixcbiAgZmllbGRJZHg6IG51bWJlcixcbiAgZm9ybWF0OiBzdHJpbmcsXG4gIGRjOiBEYXRhQ29udGFpbmVySW50ZXJmYWNlLFxuICAvLyBBbiBvYmplY3Qgd2l0aCByb3cgaW5kZXggb3IgYSBtYXRlcmlhbGl6ZWQgcm93IGFycmF5IChmb3IgbWF0ZXJpYWxpemVkIGhvdmVyIGluZm8gZnJvbSB0cmlwIGxheWVyKVxuICBkOiB7aW5kZXg6IG51bWJlcn0gfCBhbnlbXVxuKSB7XG4gIGlmIChpc1RpbWUpIHtcbiAgICByZXR1cm4gdGltZVRvVW5peE1pbGxpKEFycmF5LmlzQXJyYXkoZCkgPyBkW2ZpZWxkSWR4XSA6IGRjLnZhbHVlQXQoZC5pbmRleCwgZmllbGRJZHgpLCBmb3JtYXQpO1xuICB9XG5cbiAgcmV0dXJuIEFycmF5LmlzQXJyYXkoZCkgPyBkW2ZpZWxkSWR4XSA6IGRjLnZhbHVlQXQoZC5pbmRleCwgZmllbGRJZHgpO1xufVxuXG5jbGFzcyBLZXBsZXJUYWJsZTxGIGV4dGVuZHMgRmllbGQgPSBGaWVsZD4ge1xuICByZWFkb25seSBpZDogc3RyaW5nO1xuXG4gIHR5cGU/OiBzdHJpbmc7XG4gIGxhYmVsOiBzdHJpbmc7XG4gIGNvbG9yOiBSR0JDb2xvcjtcblxuICAvLyBmaWVsZHMgYW5kIGRhdGFcbiAgZmllbGRzOiBGW10gPSBbXTtcblxuICBkYXRhQ29udGFpbmVyOiBEYXRhQ29udGFpbmVySW50ZXJmYWNlO1xuXG4gIGFsbEluZGV4ZXM6IG51bWJlcltdID0gW107XG4gIGZpbHRlcmVkSW5kZXg6IG51bWJlcltdID0gW107XG4gIGZpbHRlcmVkSWR4Q1BVPzogbnVtYmVyW107XG4gIGZpbHRlcmVkSW5kZXhGb3JEb21haW46IG51bWJlcltdID0gW107XG4gIGZpZWxkUGFpcnM6IEZpZWxkUGFpcltdID0gW107XG4gIGdwdUZpbHRlcjogR3B1RmlsdGVyO1xuICBmaWx0ZXJSZWNvcmQ/OiBGaWx0ZXJSZWNvcmQ7XG4gIGZpbHRlclJlY29yZENQVT86IEZpbHRlclJlY29yZDtcbiAgY2hhbmdlZEZpbHRlcnM/OiBGaWx0ZXJDaGFuZ2VkO1xuXG4gIC8vIHRhYmxlLWluamVjdGVkIG1ldGFkYXRhXG4gIHNvcnRDb2x1bW4/OiB7XG4gICAgLy8gY29sdW1uIG5hbWU6IHNvcnRlZCBpZHhcbiAgICBba2V5OiBzdHJpbmddOiBzdHJpbmc7IC8vIEFTQ0VORElORyB8IERFU0NFTkRJTkcgfCBVTlNPUlRcbiAgfTtcbiAgc29ydE9yZGVyPzogbnVtYmVyW10gfCBudWxsO1xuXG4gIHBpbm5lZENvbHVtbnM/OiBzdHJpbmdbXTtcbiAgc3VwcG9ydGVkRmlsdGVyVHlwZXM/OiBzdHJpbmdbXSB8IG51bGw7XG4gIGRpc2FibGVEYXRhT3BlcmF0aW9uPzogYm9vbGVhbjtcblxuICAvLyB0YWJsZS1pbmplY3RlZCBtZXRhZGF0YVxuICBtZXRhZGF0YTogUmVjb3JkPHN0cmluZywgYW55PjtcblxuICBnZXRGaWxlUHJvY2Vzc29yPzogKGRhdGE6IGFueSwgaW5wdXRGb3JtYXQ/OiBzdHJpbmcpID0+IHtkYXRhOiBhbnk7IGZvcm1hdDogc3RyaW5nfTtcblxuICBjb25zdHJ1Y3Rvcih7XG4gICAgaW5mbyxcbiAgICBjb2xvcixcbiAgICBtZXRhZGF0YSxcbiAgICBzdXBwb3J0ZWRGaWx0ZXJUeXBlcyA9IG51bGwsXG4gICAgZGlzYWJsZURhdGFPcGVyYXRpb24gPSBmYWxzZVxuICB9OiB7XG4gICAgaW5mbz86IFByb3RvRGF0YXNldFsnaW5mbyddO1xuICAgIGNvbG9yOiBSR0JDb2xvcjtcbiAgICBtZXRhZGF0YT86IFByb3RvRGF0YXNldFsnbWV0YWRhdGEnXTtcbiAgICBzdXBwb3J0ZWRGaWx0ZXJUeXBlcz86IFByb3RvRGF0YXNldFsnc3VwcG9ydGVkRmlsdGVyVHlwZXMnXTtcbiAgICBkaXNhYmxlRGF0YU9wZXJhdGlvbj86IFByb3RvRGF0YXNldFsnZGlzYWJsZURhdGFPcGVyYXRpb24nXTtcbiAgfSkge1xuICAgIC8vIFRPRE8gLSB3aGF0IHRvIGRvIGlmIHZhbGlkYXRpb24gZmFpbHM/IENhbiBrZXBsZXIgaGFuZGxlIGV4Y2VwdGlvbnM/XG4gICAgLy8gY29uc3QgdmFsaWRhdGVkRGF0YSA9IHZhbGlkYXRlSW5wdXREYXRhKGRhdGEpO1xuICAgIC8vIGlmICghdmFsaWRhdGVkRGF0YSkge1xuICAgIC8vICAgcmV0dXJuIHRoaXM7XG4gICAgLy8gfVxuXG4gICAgY29uc3QgZGF0YXNldEluZm8gPSB7XG4gICAgICBpZDogZ2VuZXJhdGVIYXNoSWQoNCksXG4gICAgICBsYWJlbDogJ25ldyBkYXRhc2V0JyxcbiAgICAgIHR5cGU6ICcnLFxuICAgICAgLi4uaW5mb1xuICAgIH07XG5cbiAgICBjb25zdCBkZWZhdWx0TWV0YWRhdGEgPSB7XG4gICAgICBpZDogZGF0YXNldEluZm8uaWQsXG4gICAgICAvLyBAdHMtaWdub3JlXG4gICAgICBmb3JtYXQ6IGRhdGFzZXRJbmZvLmZvcm1hdCB8fCAnJyxcbiAgICAgIGxhYmVsOiBkYXRhc2V0SW5mby5sYWJlbCB8fCAnJ1xuICAgIH07XG5cbiAgICB0aGlzLmlkID0gZGF0YXNldEluZm8uaWQ7XG4gICAgdGhpcy50eXBlID0gZGF0YXNldEluZm8udHlwZTtcbiAgICB0aGlzLmxhYmVsID0gZGF0YXNldEluZm8ubGFiZWw7XG4gICAgdGhpcy5jb2xvciA9IGNvbG9yO1xuICAgIHRoaXMubWV0YWRhdGEgPSB7XG4gICAgICAuLi5kZWZhdWx0TWV0YWRhdGEsXG4gICAgICAuLi5tZXRhZGF0YVxuICAgIH07XG5cbiAgICB0aGlzLnN1cHBvcnRlZEZpbHRlclR5cGVzID0gc3VwcG9ydGVkRmlsdGVyVHlwZXM7XG4gICAgdGhpcy5kaXNhYmxlRGF0YU9wZXJhdGlvbiA9IGRpc2FibGVEYXRhT3BlcmF0aW9uO1xuXG4gICAgdGhpcy5kYXRhQ29udGFpbmVyID0gY3JlYXRlRGF0YUNvbnRhaW5lcihbXSk7XG4gICAgdGhpcy5ncHVGaWx0ZXIgPSBnZXRHcHVGaWx0ZXJQcm9wcyhbXSwgdGhpcy5pZCwgW10sIHVuZGVmaW5lZCk7XG4gIH1cblxuICBhc3luYyBpbXBvcnREYXRhKHtkYXRhfToge2RhdGE6IFByb3RvRGF0YXNldFsnZGF0YSddfSkge1xuICAgIGNvbnN0IGRhdGFDb250YWluZXJEYXRhID0gZGF0YS5jb2xzID8gZGF0YS5jb2xzIDogZGF0YS5yb3dzO1xuICAgIGNvbnN0IGlucHV0RGF0YUZvcm1hdCA9IGRhdGEuY29scyA/IERhdGFGb3JtLkNPTFNfQVJSQVkgOiBEYXRhRm9ybS5ST1dTX0FSUkFZO1xuXG4gICAgY29uc3QgZGF0YUNvbnRhaW5lciA9IGNyZWF0ZURhdGFDb250YWluZXIoZGF0YUNvbnRhaW5lckRhdGEsIHtcbiAgICAgIGZpZWxkczogZGF0YS5maWVsZHMsXG4gICAgICBhcnJvd1RhYmxlOiBkYXRhLmFycm93VGFibGUsXG4gICAgICBpbnB1dERhdGFGb3JtYXRcbiAgICB9KTtcblxuICAgIGNvbnN0IGZpZWxkczogRmllbGRbXSA9IGRhdGEuZmllbGRzLm1hcCgoZiwgaSkgPT4gKHtcbiAgICAgIC4uLmYsXG4gICAgICBmaWVsZElkeDogaSxcbiAgICAgIGlkOiBmLm5hbWUsXG4gICAgICBkaXNwbGF5TmFtZTogZi5kaXNwbGF5TmFtZSB8fCBmLm5hbWUsXG4gICAgICBhbmFseXplclR5cGU6IGYuYW5hbHl6ZXJUeXBlIHx8IEFMTF9GSUVMRF9UWVBFUy5zdHJpbmcsXG4gICAgICBmb3JtYXQ6IGYuZm9ybWF0IHx8ICcnLFxuICAgICAgdmFsdWVBY2Nlc3NvcjogZ2V0RmllbGRWYWx1ZUFjY2Vzc29yKGYsIGksIGRhdGFDb250YWluZXIpXG4gICAgfSkpO1xuXG4gICAgY29uc3QgYWxsSW5kZXhlcyA9IGRhdGFDb250YWluZXIuZ2V0UGxhaW5JbmRleCgpO1xuICAgIHRoaXMuZGF0YUNvbnRhaW5lciA9IGRhdGFDb250YWluZXI7XG4gICAgdGhpcy5hbGxJbmRleGVzID0gYWxsSW5kZXhlcztcbiAgICB0aGlzLmZpbHRlcmVkSW5kZXggPSBhbGxJbmRleGVzO1xuICAgIHRoaXMuZmlsdGVyZWRJbmRleEZvckRvbWFpbiA9IGFsbEluZGV4ZXM7XG4gICAgdGhpcy5maWVsZFBhaXJzID0gZmluZFBvaW50RmllbGRQYWlycyhmaWVsZHMpO1xuICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgTWFrZSBzdXJlIHRoYXQgZmllbGRzIHNhdGlzZmllcyBGIGV4dGVuZHMgRmllbGRcbiAgICB0aGlzLmZpZWxkcyA9IGZpZWxkcztcbiAgICB0aGlzLmdwdUZpbHRlciA9IGdldEdwdUZpbHRlclByb3BzKFtdLCB0aGlzLmlkLCBmaWVsZHMsIHVuZGVmaW5lZCk7XG4gIH1cblxuICAvKipcbiAgICogdXBkYXRlIHRhYmxlIHdpdGggbmV3IGRhdGFcbiAgICogQHBhcmFtIGRhdGEgLSBuZXcgZGF0YSBlLmcuIHRoZSBhcnJvdyBkYXRhIHdpdGggbmV3IGJhdGNoZXMgbG9hZGVkXG4gICAqL1xuICBhc3luYyB1cGRhdGUoZGF0YTogUHJvdG9EYXRhc2V0WydkYXRhJ10pIHtcbiAgICBjb25zdCBkYXRhQ29udGFpbmVyRGF0YSA9IGRhdGEuYXJyb3dUYWJsZSA/PyBkYXRhLmNvbHMgPz8gZGF0YS5yb3dzO1xuICAgIHRoaXMuZGF0YUNvbnRhaW5lci51cGRhdGU/LihkYXRhQ29udGFpbmVyRGF0YSk7XG4gICAgdGhpcy5hbGxJbmRleGVzID0gdGhpcy5kYXRhQ29udGFpbmVyLmdldFBsYWluSW5kZXgoKTtcbiAgICB0aGlzLmZpbHRlcmVkSW5kZXggPSB0aGlzLmFsbEluZGV4ZXM7XG4gICAgdGhpcy5maWx0ZXJlZEluZGV4Rm9yRG9tYWluID0gdGhpcy5hbGxJbmRleGVzO1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBnZXQgbGVuZ3RoKCkge1xuICAgIHJldHVybiB0aGlzLmRhdGFDb250YWluZXIubnVtUm93cygpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBmaWVsZFxuICAgKiBAcGFyYW0gY29sdW1uTmFtZVxuICAgKi9cbiAgZ2V0Q29sdW1uRmllbGQoY29sdW1uTmFtZTogc3RyaW5nKTogRiB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgZmllbGQgPSB0aGlzLmZpZWxkcy5maW5kKGZkID0+IGZkW0ZJRF9LRVldID09PSBjb2x1bW5OYW1lKTtcbiAgICB0aGlzLl9hc3NldEZpZWxkKGNvbHVtbk5hbWUsIGZpZWxkKTtcbiAgICByZXR1cm4gZmllbGQ7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGZpZWxkSWR4XG4gICAqIEBwYXJhbSBjb2x1bW5OYW1lXG4gICAqL1xuICBnZXRDb2x1bW5GaWVsZElkeChjb2x1bW5OYW1lOiBzdHJpbmcpOiBudW1iZXIge1xuICAgIGNvbnN0IGZpZWxkSWR4ID0gdGhpcy5maWVsZHMuZmluZEluZGV4KGZkID0+IGZkW0ZJRF9LRVldID09PSBjb2x1bW5OYW1lKTtcbiAgICB0aGlzLl9hc3NldEZpZWxkKGNvbHVtbk5hbWUsIEJvb2xlYW4oZmllbGRJZHggPiAtMSkpO1xuICAgIHJldHVybiBmaWVsZElkeDtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgZGlzcGxheUZvcm1hdFxuICAgKiBAcGFyYW0gY29sdW1uTmFtZVxuICAgKi9cbiAgZ2V0Q29sdW1uRGlzcGxheUZvcm1hdChjb2x1bW5OYW1lKSB7XG4gICAgY29uc3QgZmllbGQgPSB0aGlzLmZpZWxkcy5maW5kKGZkID0+IGZkW0ZJRF9LRVldID09PSBjb2x1bW5OYW1lKTtcbiAgICB0aGlzLl9hc3NldEZpZWxkKGNvbHVtbk5hbWUsIGZpZWxkKTtcbiAgICByZXR1cm4gZmllbGQ/LmRpc3BsYXlGb3JtYXQ7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSB2YWx1ZSBvZiBhIGNlbGxcbiAgICovXG4gIGdldFZhbHVlKGNvbHVtbk5hbWU6IHN0cmluZywgcm93SWR4OiBudW1iZXIpOiBhbnkge1xuICAgIGNvbnN0IGZpZWxkID0gdGhpcy5nZXRDb2x1bW5GaWVsZChjb2x1bW5OYW1lKTtcbiAgICByZXR1cm4gZmllbGQgPyBmaWVsZC52YWx1ZUFjY2Vzc29yKHtpbmRleDogcm93SWR4fSkgOiBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZXMgZXhpc3RpbmcgZmllbGQgd2l0aCBhIG5ldyBvYmplY3RcbiAgICogQHBhcmFtIGZpZWxkSWR4XG4gICAqIEBwYXJhbSBuZXdGaWVsZFxuICAgKi9cbiAgdXBkYXRlQ29sdW1uRmllbGQoZmllbGRJZHg6IG51bWJlciwgbmV3RmllbGQ6IEYpOiB2b2lkIHtcbiAgICB0aGlzLmZpZWxkcyA9IE9iamVjdC5hc3NpZ24oWy4uLnRoaXMuZmllbGRzXSwge1tmaWVsZElkeF06IG5ld0ZpZWxkfSk7XG4gIH1cblxuICAvKipcbiAgICogVXBkYXRlIGRhdGFzZXQgY29sb3IgYnkgY3VzdG9tIGNvbG9yXG4gICAqIEBwYXJhbSBuZXdDb2xvclxuICAgKi9cbiAgdXBkYXRlVGFibGVDb2xvcihuZXdDb2xvcjogUkdCQ29sb3IpOiB2b2lkIHtcbiAgICB0aGlzLmNvbG9yID0gbmV3Q29sb3I7XG4gIH1cblxuICAvKipcbiAgICogU2F2ZSBmaWx0ZXJQcm9wcyB0byBmaWVsZCBhbmQgcmV0cmlldmUgaXRcbiAgICogQHBhcmFtIGNvbHVtbk5hbWVcbiAgICovXG4gIGdldENvbHVtbkZpbHRlclByb3BzKGNvbHVtbk5hbWU6IHN0cmluZyk6IEZbJ2ZpbHRlclByb3BzJ10gfCBudWxsIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBmaWVsZElkeCA9IHRoaXMuZ2V0Q29sdW1uRmllbGRJZHgoY29sdW1uTmFtZSk7XG4gICAgaWYgKGZpZWxkSWR4IDwgMCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIGNvbnN0IGZpZWxkID0gdGhpcy5maWVsZHNbZmllbGRJZHhdO1xuICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoZmllbGQsICdmaWx0ZXJQcm9wcycpKSB7XG4gICAgICByZXR1cm4gZmllbGQuZmlsdGVyUHJvcHM7XG4gICAgfVxuXG4gICAgY29uc3QgZmllbGREb21haW4gPSB0aGlzLmdldENvbHVtbkZpbHRlckRvbWFpbihmaWVsZCk7XG4gICAgaWYgKCFmaWVsZERvbWFpbikge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgY29uc3QgZmlsdGVyUHJvcHMgPSBnZXRGaWx0ZXJQcm9wcyhmaWVsZCwgZmllbGREb21haW4pO1xuICAgIGNvbnN0IG5ld0ZpZWxkID0ge1xuICAgICAgLi4uZmllbGQsXG4gICAgICBmaWx0ZXJQcm9wc1xuICAgIH07XG5cbiAgICB0aGlzLnVwZGF0ZUNvbHVtbkZpZWxkKGZpZWxkSWR4LCBuZXdGaWVsZCk7XG5cbiAgICByZXR1cm4gZmlsdGVyUHJvcHM7XG4gIH1cblxuICAvKipcbiAgICogQXBwbHkgZmlsdGVycyB0byBkYXRhc2V0LCByZXR1cm4gdGhlIGZpbHRlcmVkIGRhdGFzZXQgd2l0aCB1cGRhdGVkIGBncHVGaWx0ZXJgLCBgZmlsdGVyUmVjb3JkYCwgYGZpbHRlcmVkSW5kZXhgLCBgZmlsdGVyZWRJbmRleEZvckRvbWFpbmBcbiAgICogQHBhcmFtIGZpbHRlcnNcbiAgICogQHBhcmFtIGxheWVyc1xuICAgKiBAcGFyYW0gb3B0XG4gICAqL1xuICBmaWx0ZXJUYWJsZShmaWx0ZXJzOiBGaWx0ZXJbXSwgbGF5ZXJzOiBMYXllcltdLCBvcHQ/OiBGaWx0ZXJEYXRhc2V0T3B0KTogS2VwbGVyVGFibGU8RmllbGQ+IHtcbiAgICBjb25zdCB7ZGF0YUNvbnRhaW5lciwgaWQ6IGRhdGFJZCwgZmlsdGVyUmVjb3JkOiBvbGRGaWx0ZXJSZWNvcmQsIGZpZWxkc30gPSB0aGlzO1xuXG4gICAgLy8gaWYgdGhlcmUgaXMgbm8gZmlsdGVyc1xuICAgIGNvbnN0IGZpbHRlclJlY29yZCA9IGdldEZpbHRlclJlY29yZChkYXRhSWQsIGZpbHRlcnMsIG9wdCB8fCB7fSk7XG5cbiAgICB0aGlzLmZpbHRlclJlY29yZCA9IGZpbHRlclJlY29yZDtcbiAgICB0aGlzLmdwdUZpbHRlciA9IGdldEdwdUZpbHRlclByb3BzKGZpbHRlcnMsIGRhdGFJZCwgZmllbGRzLCB0aGlzLmdwdUZpbHRlcik7XG5cbiAgICB0aGlzLmNoYW5nZWRGaWx0ZXJzID0gZGlmZkZpbHRlcnMoZmlsdGVyUmVjb3JkLCBvbGRGaWx0ZXJSZWNvcmQpO1xuXG4gICAgaWYgKCFmaWx0ZXJzLmxlbmd0aCkge1xuICAgICAgdGhpcy5maWx0ZXJlZEluZGV4ID0gdGhpcy5hbGxJbmRleGVzO1xuICAgICAgdGhpcy5maWx0ZXJlZEluZGV4Rm9yRG9tYWluID0gdGhpcy5hbGxJbmRleGVzO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLy8gZ2VuZXJhdGUgMiBzZXRzIG9mIGZpbHRlciByZXN1bHRcbiAgICAvLyBmaWx0ZXJlZEluZGV4IHVzZWQgdG8gY2FsY3VsYXRlIGxheWVyIGRhdGFcbiAgICAvLyBmaWx0ZXJlZEluZGV4Rm9yRG9tYWluIHVzZWQgdG8gY2FsY3VsYXRlIGxheWVyIERvbWFpblxuICAgIGNvbnN0IHNob3VsZENhbERvbWFpbiA9IEJvb2xlYW4odGhpcy5jaGFuZ2VkRmlsdGVycy5keW5hbWljRG9tYWluKTtcbiAgICBjb25zdCBzaG91bGRDYWxJbmRleCA9IEJvb2xlYW4odGhpcy5jaGFuZ2VkRmlsdGVycy5jcHUpO1xuXG4gICAgbGV0IGZpbHRlclJlc3VsdDogRmlsdGVyUmVzdWx0ID0ge307XG4gICAgaWYgKHNob3VsZENhbERvbWFpbiB8fCBzaG91bGRDYWxJbmRleCkge1xuICAgICAgY29uc3QgZHluYW1pY0RvbWFpbkZpbHRlcnMgPSBzaG91bGRDYWxEb21haW4gPyBmaWx0ZXJSZWNvcmQuZHluYW1pY0RvbWFpbiA6IG51bGw7XG4gICAgICBjb25zdCBjcHVGaWx0ZXJzID0gc2hvdWxkQ2FsSW5kZXggPyBmaWx0ZXJSZWNvcmQuY3B1IDogbnVsbDtcblxuICAgICAgY29uc3QgZmlsdGVyRnVuY3MgPSBmaWx0ZXJzLnJlZHVjZSgoYWNjLCBmaWx0ZXIpID0+IHtcbiAgICAgICAgY29uc3QgZmllbGRJbmRleCA9IGdldERhdGFzZXRGaWVsZEluZGV4Rm9yRmlsdGVyKHRoaXMuaWQsIGZpbHRlcik7XG4gICAgICAgIGNvbnN0IGZpZWxkID0gZmllbGRJbmRleCAhPT0gLTEgPyBmaWVsZHNbZmllbGRJbmRleF0gOiBudWxsO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgLi4uYWNjLFxuICAgICAgICAgIFtmaWx0ZXIuaWRdOiBnZXRGaWx0ZXJGdW5jdGlvbihmaWVsZCwgdGhpcy5pZCwgZmlsdGVyLCBsYXllcnMsIGRhdGFDb250YWluZXIpXG4gICAgICAgIH07XG4gICAgICB9LCB7fSk7XG5cbiAgICAgIGZpbHRlclJlc3VsdCA9IGZpbHRlckRhdGFCeUZpbHRlclR5cGVzKFxuICAgICAgICB7ZHluYW1pY0RvbWFpbkZpbHRlcnMsIGNwdUZpbHRlcnMsIGZpbHRlckZ1bmNzfSxcbiAgICAgICAgZGF0YUNvbnRhaW5lclxuICAgICAgKTtcbiAgICB9XG5cbiAgICB0aGlzLmZpbHRlcmVkSW5kZXggPSBmaWx0ZXJSZXN1bHQuZmlsdGVyZWRJbmRleCB8fCB0aGlzLmZpbHRlcmVkSW5kZXg7XG4gICAgdGhpcy5maWx0ZXJlZEluZGV4Rm9yRG9tYWluID1cbiAgICAgIGZpbHRlclJlc3VsdC5maWx0ZXJlZEluZGV4Rm9yRG9tYWluIHx8IHRoaXMuZmlsdGVyZWRJbmRleEZvckRvbWFpbjtcblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEFwcGx5IGZpbHRlcnMgdG8gYSBkYXRhc2V0IGFsbCBvbiBDUFUsIGFzc2lnbiB0byBgZmlsdGVyZWRJZHhDUFVgLCBgZmlsdGVyUmVjb3JkQ1BVYFxuICAgKiBAcGFyYW0gZmlsdGVyc1xuICAgKiBAcGFyYW0gbGF5ZXJzXG4gICAqL1xuICBmaWx0ZXJUYWJsZUNQVShmaWx0ZXJzOiBGaWx0ZXJbXSwgbGF5ZXJzOiBMYXllcltdKTogS2VwbGVyVGFibGU8RmllbGQ+IHtcbiAgICBjb25zdCBvcHQgPSB7XG4gICAgICBjcHVPbmx5OiB0cnVlLFxuICAgICAgaWdub3JlRG9tYWluOiB0cnVlXG4gICAgfTtcblxuICAgIC8vIG5vIGZpbHRlclxuICAgIGlmICghZmlsdGVycy5sZW5ndGgpIHtcbiAgICAgIHRoaXMuZmlsdGVyZWRJZHhDUFUgPSB0aGlzLmFsbEluZGV4ZXM7XG4gICAgICB0aGlzLmZpbHRlclJlY29yZENQVSA9IGdldEZpbHRlclJlY29yZCh0aGlzLmlkLCBmaWx0ZXJzLCBvcHQpO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLy8gbm8gZ3B1IGZpbHRlclxuICAgIGlmICghZmlsdGVycy5maW5kKGYgPT4gZi5ncHUpKSB7XG4gICAgICB0aGlzLmZpbHRlcmVkSWR4Q1BVID0gdGhpcy5maWx0ZXJlZEluZGV4O1xuICAgICAgdGhpcy5maWx0ZXJSZWNvcmRDUFUgPSBnZXRGaWx0ZXJSZWNvcmQodGhpcy5pZCwgZmlsdGVycywgb3B0KTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8vIG1ha2UgYSBjb3B5IGZvciBjcHUgZmlsdGVyaW5nXG4gICAgY29uc3QgY29waWVkID0gY29weVRhYmxlKHRoaXMpO1xuXG4gICAgY29waWVkLmZpbHRlclJlY29yZCA9IHRoaXMuZmlsdGVyUmVjb3JkQ1BVO1xuICAgIGNvcGllZC5maWx0ZXJlZEluZGV4ID0gdGhpcy5maWx0ZXJlZElkeENQVSB8fCBbXTtcblxuICAgIGNvbnN0IGZpbHRlcmVkID0gY29waWVkLmZpbHRlclRhYmxlKGZpbHRlcnMsIGxheWVycywgb3B0KTtcblxuICAgIHRoaXMuZmlsdGVyZWRJZHhDUFUgPSBmaWx0ZXJlZC5maWx0ZXJlZEluZGV4O1xuICAgIHRoaXMuZmlsdGVyUmVjb3JkQ1BVID0gZmlsdGVyZWQuZmlsdGVyUmVjb3JkO1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogQ2FsY3VsYXRlIGZpZWxkIGRvbWFpbiBiYXNlZCBvbiBmaWVsZCB0eXBlIGFuZCBkYXRhXG4gICAqIGZvciBGaWx0ZXJcbiAgICovXG4gIGdldENvbHVtbkZpbHRlckRvbWFpbihmaWVsZDogRik6IEZpZWxkRG9tYWluIHtcbiAgICBjb25zdCB7ZGF0YUNvbnRhaW5lcn0gPSB0aGlzO1xuICAgIGNvbnN0IHt2YWx1ZUFjY2Vzc29yfSA9IGZpZWxkO1xuXG4gICAgbGV0IGRvbWFpbjtcblxuICAgIHN3aXRjaCAoZmllbGQudHlwZSkge1xuICAgICAgY2FzZSBBTExfRklFTERfVFlQRVMucmVhbDpcbiAgICAgIGNhc2UgQUxMX0ZJRUxEX1RZUEVTLmludGVnZXI6XG4gICAgICAgIC8vIGNhbGN1bGF0ZSBkb21haW4gYW5kIHN0ZXBcbiAgICAgICAgcmV0dXJuIGdldE51bWVyaWNGaWVsZERvbWFpbihkYXRhQ29udGFpbmVyLCB2YWx1ZUFjY2Vzc29yKTtcblxuICAgICAgY2FzZSBBTExfRklFTERfVFlQRVMuYm9vbGVhbjpcbiAgICAgICAgcmV0dXJuIHtkb21haW46IFt0cnVlLCBmYWxzZV19O1xuXG4gICAgICBjYXNlIEFMTF9GSUVMRF9UWVBFUy5zdHJpbmc6XG4gICAgICBjYXNlIEFMTF9GSUVMRF9UWVBFUy5oMzpcbiAgICAgIGNhc2UgQUxMX0ZJRUxEX1RZUEVTLmRhdGU6XG4gICAgICAgIGRvbWFpbiA9IGdldE9yZGluYWxEb21haW4oZGF0YUNvbnRhaW5lciwgdmFsdWVBY2Nlc3Nvcik7XG4gICAgICAgIHJldHVybiB7ZG9tYWlufTtcblxuICAgICAgY2FzZSBBTExfRklFTERfVFlQRVMudGltZXN0YW1wOlxuICAgICAgICByZXR1cm4gZ2V0VGltZXN0YW1wRmllbGREb21haW4oZGF0YUNvbnRhaW5lciwgdmFsdWVBY2Nlc3Nvcik7XG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiB7ZG9tYWluOiBnZXRPcmRpbmFsRG9tYWluKGRhdGFDb250YWluZXIsIHZhbHVlQWNjZXNzb3IpfTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogIEdldCB0aGUgZG9tYWluIG9mIHRoaXMgY29sdW1uIGJhc2VkIG9uIHNjYWxlIHR5cGVcbiAgICovXG4gIGdldENvbHVtbkxheWVyRG9tYWluKGZpZWxkOiBGLCBzY2FsZVR5cGU6IHN0cmluZyk6IG51bWJlcltdIHwgc3RyaW5nW10gfCBbbnVtYmVyLCBudW1iZXJdIHwgbnVsbCB7XG4gICAgY29uc3Qge2RhdGFDb250YWluZXIsIGZpbHRlcmVkSW5kZXhGb3JEb21haW59ID0gdGhpcztcblxuICAgIGlmICghU0NBTEVfVFlQRVNbc2NhbGVUeXBlXSkge1xuICAgICAgQ29uc29sZS5lcnJvcihgc2NhbGUgdHlwZSAke3NjYWxlVHlwZX0gbm90IHN1cHBvcnRlZGApO1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgY29uc3Qge3ZhbHVlQWNjZXNzb3J9ID0gZmllbGQ7XG4gICAgY29uc3QgaW5kZXhWYWx1ZUFjY2Vzc29yID0gaSA9PiB2YWx1ZUFjY2Vzc29yKHtpbmRleDogaX0pO1xuICAgIGNvbnN0IHNvcnRGdW5jdGlvbiA9IGdldFNvcnRpbmdGdW5jdGlvbihmaWVsZC50eXBlKTtcblxuICAgIHN3aXRjaCAoc2NhbGVUeXBlKSB7XG4gICAgICBjYXNlIFNDQUxFX1RZUEVTLm9yZGluYWw6XG4gICAgICBjYXNlIFNDQUxFX1RZUEVTLmN1c3RvbU9yZGluYWw6XG4gICAgICBjYXNlIFNDQUxFX1RZUEVTLnBvaW50OlxuICAgICAgICAvLyBkbyBub3QgcmVjYWxjdWxhdGUgb3JkaW5hbCBkb21haW4gYmFzZWQgb24gZmlsdGVyZWQgZGF0YVxuICAgICAgICAvLyBkb24ndCBuZWVkIHRvIHVwZGF0ZSBvcmRpbmFsIGRvbWFpbiBldmVyeSB0aW1lXG4gICAgICAgIHJldHVybiBnZXRPcmRpbmFsRG9tYWluKGRhdGFDb250YWluZXIsIHZhbHVlQWNjZXNzb3IpO1xuXG4gICAgICBjYXNlIFNDQUxFX1RZUEVTLnF1YW50aWxlOlxuICAgICAgICByZXR1cm4gZ2V0UXVhbnRpbGVEb21haW4oZmlsdGVyZWRJbmRleEZvckRvbWFpbiwgaW5kZXhWYWx1ZUFjY2Vzc29yLCBzb3J0RnVuY3Rpb24pO1xuXG4gICAgICBjYXNlIFNDQUxFX1RZUEVTLmxvZzpcbiAgICAgICAgcmV0dXJuIGdldExvZ0RvbWFpbihmaWx0ZXJlZEluZGV4Rm9yRG9tYWluLCBpbmRleFZhbHVlQWNjZXNzb3IpO1xuXG4gICAgICBjYXNlIFNDQUxFX1RZUEVTLnF1YW50aXplOlxuICAgICAgY2FzZSBTQ0FMRV9UWVBFUy5saW5