kepler.gl.geoiq
Version:
kepler.gl is a webgl based application to visualize large scale location data in the browser
261 lines (212 loc) • 35.5 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _typeof = require("@babel/runtime/helpers/typeof");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized"));
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 _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _taggedTemplateLiteral2 = _interopRequireDefault(require("@babel/runtime/helpers/taggedTemplateLiteral"));
var _react = _interopRequireWildcard(require("react"));
var _propTypes = _interopRequireDefault(require("prop-types"));
var _classnames = _interopRequireDefault(require("classnames"));
var _styledComponents = _interopRequireDefault(require("styled-components"));
var _reactMapGl = _interopRequireDefault(require("react-map-gl"));
var _styledComponents2 = require("../common/styled-components");
var _mediaBreakpoints = require("../../styles/media-breakpoints");
var _mapboxUtils = require("../../utils/map-style-utils/mapbox-utils");
var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7, _templateObject8, _templateObject9, _templateObject10;
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
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 MapH = 190;
var MapW = 264;
var ErrorMsg = {
styleError: 'Failed to load map style, make sure it is published. For private style, paste in your access token.'
};
var InstructionPanel = _styledComponents["default"].div(_templateObject || (_templateObject = (0, _taggedTemplateLiteral2["default"])(["\n display: flex;\n flex-direction: column;\n justify-content: space-around;\n font-size: 12px;\n\n .modal-section:first-child {\n margin-top: 24px;\n ", ";\n }\n\n input {\n margin-right: 8px;\n }\n"])), _mediaBreakpoints.media.palm(_templateObject2 || (_templateObject2 = (0, _taggedTemplateLiteral2["default"])(["\n margin-top: 0;\n "]))));
var StyledModalSection = _styledComponents["default"].div(_templateObject3 || (_templateObject3 = (0, _taggedTemplateLiteral2["default"])(["\n margin-bottom: 32px;\n\n .modal-section-title {\n font-weight: 500;\n }\n .modal-section-subtitle {\n color: ", ";\n }\n\n input {\n margin-top: 8px;\n }\n\n ", ";\n ", ";\n"])), function (props) {
return props.theme.subtextColorLT;
}, _mediaBreakpoints.media.portable(_templateObject4 || (_templateObject4 = (0, _taggedTemplateLiteral2["default"])(["\n margin-bottom: 24px;\n "]))), _mediaBreakpoints.media.palm(_templateObject5 || (_templateObject5 = (0, _taggedTemplateLiteral2["default"])(["\n margin-bottom: 16px;\n "]))));
var PreviewMap = _styledComponents["default"].div(_templateObject6 || (_templateObject6 = (0, _taggedTemplateLiteral2["default"])(["\n align-items: center;\n display: flex;\n flex-direction: column;\n justify-content: center;\n margin-left: 116px;\n flex-shrink: 0;\n\n .preview-title {\n font-weight: 500;\n font-size: 10px;\n padding: 8px 0px;\n }\n\n .preview-title.error {\n color: ", ";\n }\n\n ", ";\n\n ", ";\n"])), function (props) {
return props.theme.errorColor;
}, _mediaBreakpoints.media.portable(_templateObject7 || (_templateObject7 = (0, _taggedTemplateLiteral2["default"])(["\n margin-left: 32px;\n "]))), _mediaBreakpoints.media.palm(_templateObject8 || (_templateObject8 = (0, _taggedTemplateLiteral2["default"])(["\n margin-left: unset;\n .preview-title {\n margin-top: 0px;\n }\n "]))));
var StyledPreviewImage = _styledComponents["default"].div(_templateObject9 || (_templateObject9 = (0, _taggedTemplateLiteral2["default"])(["\n background: ", ";\n border-radius: 4px;\n box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.18);\n width: ", "px;\n height: ", "px;\n position: relative;\n\n .preview-image-placeholder {\n position: absolute;\n top: 0;\n left: 0;\n }\n\n .preview-image-spinner {\n position: absolute;\n left: calc(50% - 25px);\n top: calc(50% - 25px);\n }\n"])), function (props) {
return props.theme.modalImagePlaceHolder;
}, MapW, MapH);
var InlineLink = _styledComponents["default"].a(_templateObject10 || (_templateObject10 = (0, _taggedTemplateLiteral2["default"])(["\n font-weight: 500;\n\n :hover {\n cursor: pointer;\n }\n"])));
var AddMapStyleModal = /*#__PURE__*/function (_Component) {
(0, _inherits2["default"])(AddMapStyleModal, _Component);
var _super = _createSuper(AddMapStyleModal);
function AddMapStyleModal() {
var _this;
(0, _classCallCheck2["default"])(this, AddMapStyleModal);
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
_this = _super.call.apply(_super, [this].concat(args));
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "state", {
reRenderKey: 0
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "loadMapStyleJson", function (style) {
_this.props.loadCustomMapStyle({
style: style,
error: false
});
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "loadMapStyleError", function () {
_this.props.loadCustomMapStyle({
error: true
});
});
return _this;
}
(0, _createClass2["default"])(AddMapStyleModal, [{
key: "componentWillReceiveProps",
value: function componentWillReceiveProps(nextProps) {
if (this.props.inputStyle.accessToken !== nextProps.inputStyle.accessToken) {
// toke has changed
// ReactMapGl doesn't re-create map when token has changed
// here we force the map to update
this.setState({
reRenderKey: this.state.reRenderKey + 1
});
}
}
}, {
key: "componentDidUpdate",
value: function componentDidUpdate(prevProps) {
var _this2 = this;
var map = this.mapRef && this.mapRef.getMap();
if (map && this._map !== map) {
this._map = map;
map.on('style.load', function () {
var style = map.getStyle();
_this2.loadMapStyleJson(style);
});
map.on('error', function () {
_this2.loadMapStyleError();
});
}
}
}, {
key: "render",
value: function render() {
var _this3 = this;
var _this$props = this.props,
inputStyle = _this$props.inputStyle,
mapState = _this$props.mapState,
mapboxApiUrl = _this$props.mapboxApiUrl;
var mapboxApiAccessToken = inputStyle.accessToken || this.props.mapboxApiAccessToken;
var mapProps = _objectSpread(_objectSpread({}, mapState), {}, {
mapboxApiUrl: mapboxApiUrl,
mapboxApiAccessToken: mapboxApiAccessToken,
preserveDrawingBuffer: true,
transformRequest: _mapboxUtils.transformRequest
});
return (/*#__PURE__*/_react["default"].createElement("div", {
className: "add-map-style-modal"
}, /*#__PURE__*/_react["default"].createElement(_styledComponents2.StyledModalContent, null, /*#__PURE__*/_react["default"].createElement(InstructionPanel, null, /*#__PURE__*/_react["default"].createElement(StyledModalSection, {
className: "modal-section"
}, /*#__PURE__*/_react["default"].createElement("div", {
className: "modal-section-title"
}, "1. Publish your style at mapbox or provide access token"), /*#__PURE__*/_react["default"].createElement("div", {
className: "modal-section-subtitle"
}, "You can create your own map style at", /*#__PURE__*/_react["default"].createElement(InlineLink, {
target: "_blank",
href: "https://www.mapbox.com/studio/styles/"
}, ' ', "mapbox"), ' ', "and", /*#__PURE__*/_react["default"].createElement(InlineLink, {
target: "_blank",
href: "https://www.mapbox.com/help/studio-manual-publish/"
}, ' ', "publish"), ' ', "it."), /*#__PURE__*/_react["default"].createElement("div", {
className: "modal-section-subtitle"
}, "To use private style, paste your", /*#__PURE__*/_react["default"].createElement(InlineLink, {
target: "_blank",
href: "https://www.mapbox.com/help/how-access-tokens-work/"
}, ' ', "access token"), ' ', "here. *geoiq is a on-premises application, data stays in your server.."), /*#__PURE__*/_react["default"].createElement(_styledComponents2.InputLight, {
type: "text",
value: inputStyle.accessToken || '',
onChange: function onChange(_ref) {
var value = _ref.target.value;
return _this3.props.inputMapStyle({
accessToken: value
});
},
placeholder: "e.g. pk.abcdefg.xxxxxx"
})), /*#__PURE__*/_react["default"].createElement(StyledModalSection, {
className: "modal-section"
}, /*#__PURE__*/_react["default"].createElement("div", {
className: "modal-section-title"
}, "2. Paste style url"), /*#__PURE__*/_react["default"].createElement("div", {
className: "modal-section-subtitle"
}, "What is a", /*#__PURE__*/_react["default"].createElement(InlineLink, {
target: "_blank",
href: "https://www.mapbox.com/help/studio-manual-publish/#style-url"
}, ' ', "style URL")), /*#__PURE__*/_react["default"].createElement(_styledComponents2.InputLight, {
type: "text",
value: inputStyle.url || '',
onChange: function onChange(_ref2) {
var value = _ref2.target.value;
return _this3.props.inputMapStyle({
url: value
});
},
placeholder: "e.g. mapbox://styles/uberdataviz/abcdefghijklmnopq"
})), /*#__PURE__*/_react["default"].createElement(StyledModalSection, {
className: "modal-section"
}, /*#__PURE__*/_react["default"].createElement("div", {
className: "modal-section-title"
}, "3. Name your style"), /*#__PURE__*/_react["default"].createElement(_styledComponents2.InputLight, {
type: "text",
value: inputStyle.label || '',
onChange: function onChange(_ref3) {
var value = _ref3.target.value;
return _this3.props.inputMapStyle({
label: value
});
}
}))), /*#__PURE__*/_react["default"].createElement(PreviewMap, null, /*#__PURE__*/_react["default"].createElement("div", {
className: (0, _classnames["default"])('preview-title', {
error: inputStyle.error
})
}, inputStyle.error ? ErrorMsg.styleError : inputStyle.style && inputStyle.style.name || ''), /*#__PURE__*/_react["default"].createElement(StyledPreviewImage, {
className: "preview-image"
}, !inputStyle.isValid ? /*#__PURE__*/_react["default"].createElement("div", {
className: "preview-image-spinner"
}) : /*#__PURE__*/_react["default"].createElement(_styledComponents2.StyledMapContainer, null, /*#__PURE__*/_react["default"].createElement(_reactMapGl["default"], (0, _extends2["default"])({}, mapProps, {
ref: function ref(el) {
_this3.mapRef = el;
},
key: this.state.reRenderKey,
width: MapW,
height: MapH,
mapStyle: inputStyle.url
})))))))
);
}
}]);
return AddMapStyleModal;
}(_react.Component);
(0, _defineProperty2["default"])(AddMapStyleModal, "propTypes", {
inputMapStyle: _propTypes["default"].func.isRequired,
inputStyle: _propTypes["default"].object.isRequired,
loadCustomMapStyle: _propTypes["default"].func.isRequired,
mapboxApiAccessToken: _propTypes["default"].string.isRequired,
mapboxApiUrl: _propTypes["default"].string.isRequired,
mapState: _propTypes["default"].object.isRequired
});
var AddMapStyleModalFactory = function AddMapStyleModalFactory() {
return AddMapStyleModal;
};
var _default = exports["default"] = AddMapStyleModalFactory;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jb21wb25lbnRzL21vZGFscy9hZGQtbWFwLXN0eWxlLW1vZGFsLmpzIl0sIm5hbWVzIjpbIk1hcEgiLCJNYXBXIiwiRXJyb3JNc2ciLCJzdHlsZUVycm9yIiwiSW5zdHJ1Y3Rpb25QYW5lbCIsInN0eWxlZCIsImRpdiIsIm1lZGlhIiwicGFsbSIsIlN0eWxlZE1vZGFsU2VjdGlvbiIsInByb3BzIiwidGhlbWUiLCJzdWJ0ZXh0Q29sb3JMVCIsInBvcnRhYmxlIiwiUHJldmlld01hcCIsImVycm9yQ29sb3IiLCJTdHlsZWRQcmV2aWV3SW1hZ2UiLCJtb2RhbEltYWdlUGxhY2VIb2xkZXIiLCJJbmxpbmVMaW5rIiwiYSIsIkFkZE1hcFN0eWxlTW9kYWwiLCJyZVJlbmRlcktleSIsInN0eWxlIiwibG9hZEN1c3RvbU1hcFN0eWxlIiwiZXJyb3IiLCJuZXh0UHJvcHMiLCJpbnB1dFN0eWxlIiwiYWNjZXNzVG9rZW4iLCJzZXRTdGF0ZSIsInN0YXRlIiwicHJldlByb3BzIiwibWFwIiwibWFwUmVmIiwiZ2V0TWFwIiwiX21hcCIsIm9uIiwiZ2V0U3R5bGUiLCJsb2FkTWFwU3R5bGVKc29uIiwibG9hZE1hcFN0eWxlRXJyb3IiLCJtYXBTdGF0ZSIsIm1hcGJveEFwaVVybCIsIm1hcGJveEFwaUFjY2Vzc1Rva2VuIiwibWFwUHJvcHMiLCJwcmVzZXJ2ZURyYXdpbmdCdWZmZXIiLCJ0cmFuc2Zvcm1SZXF1ZXN0IiwidmFsdWUiLCJ0YXJnZXQiLCJpbnB1dE1hcFN0eWxlIiwidXJsIiwibGFiZWwiLCJuYW1lIiwiaXNWYWxpZCIsImVsIiwiQ29tcG9uZW50IiwiUHJvcFR5cGVzIiwiZnVuYyIsImlzUmVxdWlyZWQiLCJvYmplY3QiLCJzdHJpbmciLCJBZGRNYXBTdHlsZU1vZGFsRmFjdG9yeSJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFvQkE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBS0E7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LFVBTGQ7QUFNakJqQixFQUFBQSxRQUFRLEVBQUVlLHNCQUFVRyxNQUFWLENBQWlCRDtBQU5WLEM7O0FBZ0xyQixJQUFNRyx1QkFBdUIsR0FBRyxTQUExQkEsdUJBQTBCO0FBQUEsU0FBTXZDLGdCQUFOO0FBQUEsQ0FBaEM7O29DQUNldUMsdUIiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgKGMpIDIwMjMgVWJlciBUZWNobm9sb2dpZXMsIEluYy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG4vLyBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0byBkZWFsXG4vLyBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzXG4vLyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsXG4vLyBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbi8vIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW5cbi8vIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1Jcbi8vIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuLy8gRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG4vLyBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXG4vLyBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLFxuLy8gT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTlxuLy8gVEhFIFNPRlRXQVJFLlxuXG5pbXBvcnQgUmVhY3QsIHtDb21wb25lbnR9IGZyb20gJ3JlYWN0JztcbmltcG9ydCBQcm9wVHlwZXMgZnJvbSAncHJvcC10eXBlcyc7XG5pbXBvcnQgY2xhc3NuYW1lcyBmcm9tICdjbGFzc25hbWVzJztcbmltcG9ydCBzdHlsZWQgZnJvbSAnc3R5bGVkLWNvbXBvbmVudHMnO1xuaW1wb3J0IE1hcGJveEdMTWFwIGZyb20gJ3JlYWN0LW1hcC1nbCc7XG5pbXBvcnQge1xuICBTdHlsZWRNb2RhbENvbnRlbnQsXG4gIElucHV0TGlnaHQsXG4gIFN0eWxlZE1hcENvbnRhaW5lclxufSBmcm9tICdjb21wb25lbnRzL2NvbW1vbi9zdHlsZWQtY29tcG9uZW50cyc7XG5pbXBvcnQge21lZGlhfSBmcm9tICdzdHlsZXMvbWVkaWEtYnJlYWtwb2ludHMnO1xuXG4vLyBVdGlsc1xuaW1wb3J0IHt0cmFuc2Zvcm1SZXF1ZXN0fSBmcm9tICd1dGlscy9tYXAtc3R5bGUtdXRpbHMvbWFwYm94LXV0aWxzJztcblxuY29uc3QgTWFwSCA9IDE5MDtcbmNvbnN0IE1hcFcgPSAyNjQ7XG5jb25zdCBFcnJvck1zZyA9IHtcbiAgc3R5bGVFcnJvcjpcbiAgICAnRmFpbGVkIHRvIGxvYWQgbWFwIHN0eWxlLCBtYWtlIHN1cmUgaXQgaXMgcHVibGlzaGVkLiBGb3IgcHJpdmF0ZSBzdHlsZSwgcGFzdGUgaW4geW91ciBhY2Nlc3MgdG9rZW4uJ1xufTtcblxuY29uc3QgSW5zdHJ1Y3Rpb25QYW5lbCA9IHN0eWxlZC5kaXZgXG4gIGRpc3BsYXk6IGZsZXg7XG4gIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gIGp1c3RpZnktY29udGVudDogc3BhY2UtYXJvdW5kO1xuICBmb250LXNpemU6IDEycHg7XG5cbiAgLm1vZGFsLXNlY3Rpb246Zmlyc3QtY2hpbGQge1xuICAgIG1hcmdpbi10b3A6IDI0cHg7XG4gICAgJHttZWRpYS5wYWxtYFxuICAgICAgbWFyZ2luLXRvcDogMDtcbiAgICBgfTtcbiAgfVxuXG4gIGlucHV0IHtcbiAgICBtYXJnaW4tcmlnaHQ6IDhweDtcbiAgfVxuYDtcblxuY29uc3QgU3R5bGVkTW9kYWxTZWN0aW9uID0gc3R5bGVkLmRpdmBcbiAgbWFyZ2luLWJvdHRvbTogMzJweDtcblxuICAubW9kYWwtc2VjdGlvbi10aXRsZSB7XG4gICAgZm9udC13ZWlnaHQ6IDUwMDtcbiAgfVxuICAubW9kYWwtc2VjdGlvbi1zdWJ0aXRsZSB7XG4gICAgY29sb3I6ICR7cHJvcHMgPT4gcHJvcHMudGhlbWUuc3VidGV4dENvbG9yTFR9O1xuICB9XG5cbiAgaW5wdXQge1xuICAgIG1hcmdpbi10b3A6IDhweDtcbiAgfVxuXG4gICR7bWVkaWEucG9ydGFibGVgXG4gICAgbWFyZ2luLWJvdHRvbTogMjRweDtcbiAgYH07XG4gICR7bWVkaWEucGFsbWBcbiAgICBtYXJnaW4tYm90dG9tOiAxNnB4O1xuICBgfTtcbmA7XG5cbmNvbnN0IFByZXZpZXdNYXAgPSBzdHlsZWQuZGl2YFxuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICBkaXNwbGF5OiBmbGV4O1xuICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcbiAgbWFyZ2luLWxlZnQ6IDExNnB4O1xuICBmbGV4LXNocmluazogMDtcblxuICAucHJldmlldy10aXRsZSB7XG4gICAgZm9udC13ZWlnaHQ6IDUwMDtcbiAgICBmb250LXNpemU6IDEwcHg7XG4gICAgcGFkZGluZzogOHB4IDBweDtcbiAgfVxuXG4gIC5wcmV2aWV3LXRpdGxlLmVycm9yIHtcbiAgICBjb2xvcjogJHtwcm9wcyA9PiBwcm9wcy50aGVtZS5lcnJvckNvbG9yfTtcbiAgfVxuXG4gICR7bWVkaWEucG9ydGFibGVgXG4gICAgbWFyZ2luLWxlZnQ6IDMycHg7XG4gIGB9O1xuXG4gICR7bWVkaWEucGFsbWBcbiAgICBtYXJnaW4tbGVmdDogdW5zZXQ7XG4gICAgLnByZXZpZXctdGl0bGUge1xuICAgICAgbWFyZ2luLXRvcDogMHB4O1xuICAgIH1cbiAgYH07XG5gO1xuXG5jb25zdCBTdHlsZWRQcmV2aWV3SW1hZ2UgPSBzdHlsZWQuZGl2YFxuICBiYWNrZ3JvdW5kOiAke3Byb3BzID0+IHByb3BzLnRoZW1lLm1vZGFsSW1hZ2VQbGFjZUhvbGRlcn07XG4gIGJvcmRlci1yYWRpdXM6IDRweDtcbiAgYm94LXNoYWRvdzogMCA4cHggMTZweCAwIHJnYmEoMCwgMCwgMCwgMC4xOCk7XG4gIHdpZHRoOiAke01hcFd9cHg7XG4gIGhlaWdodDogJHtNYXBIfXB4O1xuICBwb3NpdGlvbjogcmVsYXRpdmU7XG5cbiAgLnByZXZpZXctaW1hZ2UtcGxhY2Vob2xkZXIge1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICB0b3A6IDA7XG4gICAgbGVmdDogMDtcbiAgfVxuXG4gIC5wcmV2aWV3LWltYWdlLXNwaW5uZXIge1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICBsZWZ0OiBjYWxjKDUwJSAtIDI1cHgpO1xuICAgIHRvcDogY2FsYyg1MCUgLSAyNXB4KTtcbiAgfVxuYDtcblxuY29uc3QgSW5saW5lTGluayA9IHN0eWxlZC5hYFxuICBmb250LXdlaWdodDogNTAwO1xuXG4gIDpob3ZlciB7XG4gICAgY3Vyc29yOiBwb2ludGVyO1xuICB9XG5gO1xuXG5jbGFzcyBBZGRNYXBTdHlsZU1vZGFsIGV4dGVuZHMgQ29tcG9uZW50IHtcbiAgc3RhdGljIHByb3BUeXBlcyA9IHtcbiAgICBpbnB1dE1hcFN0eWxlOiBQcm9wVHlwZXMuZnVuYy5pc1JlcXVpcmVkLFxuICAgIGlucHV0U3R5bGU6IFByb3BUeXBlcy5vYmplY3QuaXNSZXF1aXJlZCxcbiAgICBsb2FkQ3VzdG9tTWFwU3R5bGU6IFByb3BUeXBlcy5mdW5jLmlzUmVxdWlyZWQsXG4gICAgbWFwYm94QXBpQWNjZXNzVG9rZW46IFByb3BUeXBlcy5zdHJpbmcuaXNSZXF1aXJlZCxcbiAgICBtYXBib3hBcGlVcmw6IFByb3BUeXBlcy5zdHJpbmcuaXNSZXF1aXJlZCxcbiAgICBtYXBTdGF0ZTogUHJvcFR5cGVzLm9iamVjdC5pc1JlcXVpcmVkXG4gIH07XG5cbiAgc3RhdGUgPSB7XG4gICAgcmVSZW5kZXJLZXk6IDBcbiAgfTtcblxuICBjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzKG5leHRQcm9wcykge1xuICAgIGlmIChcbiAgICAgIHRoaXMucHJvcHMuaW5wdXRTdHlsZS5hY2Nlc3NUb2tlbiAhPT0gbmV4dFByb3BzLmlucHV0U3R5bGUuYWNjZXNzVG9rZW5cbiAgICApIHtcbiAgICAgIC8vIHRva2UgaGFzIGNoYW5nZWRcbiAgICAgIC8vIFJlYWN0TWFwR2wgZG9lc24ndCByZS1jcmVhdGUgbWFwIHdoZW4gdG9rZW4gaGFzIGNoYW5nZWRcbiAgICAgIC8vIGhlcmUgd2UgZm9yY2UgdGhlIG1hcCB0byB1cGRhdGVcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICByZVJlbmRlcktleTogdGhpcy5zdGF0ZS5yZVJlbmRlcktleSArIDFcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGNvbXBvbmVudERpZFVwZGF0ZShwcmV2UHJvcHMpIHtcbiAgICBjb25zdCBtYXAgPSB0aGlzLm1hcFJlZiAmJiB0aGlzLm1hcFJlZi5nZXRNYXAoKTtcbiAgICBpZiAobWFwICYmIHRoaXMuX21hcCAhPT0gbWFwKSB7XG4gICAgICB0aGlzLl9tYXAgPSBtYXA7XG5cbiAgICAgIG1hcC5vbignc3R5bGUubG9hZCcsICgpID0+IHtcbiAgICAgICAgY29uc3Qgc3R5bGUgPSBtYXAuZ2V0U3R5bGUoKTtcbiAgICAgICAgdGhpcy5sb2FkTWFwU3R5bGVKc29uKHN0eWxlKTtcbiAgICAgIH0pO1xuXG4gICAgICBtYXAub24oJ2Vycm9yJywgKCkgPT4ge1xuICAgICAgICB0aGlzLmxvYWRNYXBTdHlsZUVycm9yKCk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBsb2FkTWFwU3R5bGVKc29uID0gc3R5bGUgPT4ge1xuICAgIHRoaXMucHJvcHMubG9hZEN1c3RvbU1hcFN0eWxlKHtzdHlsZSwgZXJyb3I6IGZhbHNlfSk7XG4gIH07XG5cbiAgbG9hZE1hcFN0eWxlRXJyb3IgPSAoKSA9PiB7XG4gICAgdGhpcy5wcm9wcy5sb2FkQ3VzdG9tTWFwU3R5bGUoe2Vycm9yOiB0cnVlfSk7XG4gIH07XG5cbiAgcmVuZGVyKCkge1xuICAgIGNvbnN0IHtpbnB1dFN0eWxlLCBtYXBTdGF0ZSwgbWFwYm94QXBpVXJsfSA9IHRoaXMucHJvcHM7XG5cbiAgICBjb25zdCBtYXBib3hBcGlBY2Nlc3NUb2tlbiA9XG4gICAgICBpbnB1dFN0eWxlLmFjY2Vzc1Rva2VuIHx8IHRoaXMucHJvcHMubWFwYm94QXBpQWNjZXNzVG9rZW47XG4gICAgY29uc3QgbWFwUHJvcHMgPSB7XG4gICAgICAuLi5tYXBTdGF0ZSxcbiAgICAgIG1hcGJveEFwaVVybCxcbiAgICAgIG1hcGJveEFwaUFjY2Vzc1Rva2VuLFxuICAgICAgcHJlc2VydmVEcmF3aW5nQnVmZmVyOiB0cnVlLFxuICAgICAgdHJhbnNmb3JtUmVxdWVzdFxuICAgIH07XG5cbiAgICByZXR1cm4gKFxuICAgICAgPGRpdiBjbGFzc05hbWU9XCJhZGQtbWFwLXN0eWxlLW1vZGFsXCI+XG4gICAgICAgIDxTdHlsZWRNb2RhbENvbnRlbnQ+XG4gICAgICAgICAgPEluc3RydWN0aW9uUGFuZWw+XG4gICAgICAgICAgICA8U3R5bGVkTW9kYWxTZWN0aW9uIGNsYXNzTmFtZT1cIm1vZGFsLXNlY3Rpb25cIj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJtb2RhbC1zZWN0aW9uLXRpdGxlXCI+XG4gICAgICAgICAgICAgICAgMS4gUHVibGlzaCB5b3VyIHN0eWxlIGF0IG1hcGJveCBvciBwcm92aWRlIGFjY2VzcyB0b2tlblxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJtb2RhbC1zZWN0aW9uLXN1YnRpdGxlXCI+XG4gICAgICAgICAgICAgICAgWW91IGNhbiBjcmVhdGUgeW91ciBvd24gbWFwIHN0eWxlIGF0XG4gICAgICAgICAgICAgICAgPElubGluZUxpbmtcbiAgICAgICAgICAgICAgICAgIHRhcmdldD1cIl9ibGFua1wiXG4gICAgICAgICAgICAgICAgICBocmVmPVwiaHR0cHM6Ly93d3cubWFwYm94LmNvbS9zdHVkaW8vc3R5bGVzL1wiXG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgeycgJ31cbiAgICAgICAgICAgICAgICAgIG1hcGJveFxuICAgICAgICAgICAgICAgIDwvSW5saW5lTGluaz57JyAnfVxuICAgICAgICAgICAgICAgIGFuZFxuICAgICAgICAgICAgICAgIDxJbmxpbmVMaW5rXG4gICAgICAgICAgICAgICAgICB0YXJnZXQ9XCJfYmxhbmtcIlxuICAgICAgICAgICAgICAgICAgaHJlZj1cImh0dHBzOi8vd3d3Lm1hcGJveC5jb20vaGVscC9zdHVkaW8tbWFudWFsLXB1Ymxpc2gvXCJcbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICB7JyAnfVxuICAgICAgICAgICAgICAgICAgcHVibGlzaFxuICAgICAgICAgICAgICAgIDwvSW5saW5lTGluaz57JyAnfVxuICAgICAgICAgICAgICAgIGl0LlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJtb2RhbC1zZWN0aW9uLXN1YnRpdGxlXCI+XG4gICAgICAgICAgICAgICAgVG8gdXNlIHByaXZhdGUgc3R5bGUsIHBhc3RlIHlvdXJcbiAgICAgICAgICAgICAgICA8SW5saW5lTGlua1xuICAgICAgICAgICAgICAgICAgdGFyZ2V0PVwiX2JsYW5rXCJcbiAgICAgICAgICAgICAgICAgIGhyZWY9XCJodHRwczovL3d3dy5tYXBib3guY29tL2hlbHAvaG93LWFjY2Vzcy10b2tlbnMtd29yay9cIlxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgIHsnICd9XG4gICAgICAgICAgICAgICAgICBhY2Nlc3MgdG9rZW5cbiAgICAgICAgICAgICAgICA8L0lubGluZUxpbms+eycgJ31cbiAgICAgICAgICAgICAgICBoZXJlLiAqZ2VvaXEgaXMgYSBvbi1wcmVtaXNlcyBhcHBsaWNhdGlvbiwgZGF0YSBzdGF5cyBpbiB5b3VyXG4gICAgICAgICAgICAgICAgc2VydmVyLi5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDxJbnB1dExpZ2h0XG4gICAgICAgICAgICAgICAgdHlwZT1cInRleHRcIlxuICAgICAgICAgICAgICAgIHZhbHVlPXtpbnB1dFN0eWxlLmFjY2Vzc1Rva2VuIHx8ICcnfVxuICAgICAgICAgICAgICAgIG9uQ2hhbmdlPXsoe3RhcmdldDoge3ZhbHVlfX0pID0+XG4gICAgICAgICAgICAgICAgICB0aGlzLnByb3BzLmlucHV0TWFwU3R5bGUoe2FjY2Vzc1Rva2VuOiB2YWx1ZX0pXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiZS5nLiBway5hYmNkZWZnLnh4eHh4eFwiXG4gICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICA8L1N0eWxlZE1vZGFsU2VjdGlvbj5cbiAgICAgICAgICAgIDxTdHlsZWRNb2RhbFNlY3Rpb24gY2xhc3NOYW1lPVwibW9kYWwtc2VjdGlvblwiPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cIm1vZGFsLXNlY3Rpb24tdGl0bGVcIj4yLiBQYXN0ZSBzdHlsZSB1cmw8L2Rpdj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJtb2RhbC1zZWN0aW9uLXN1YnRpdGxlXCI+XG4gICAgICAgICAgICAgICAgV2hhdCBpcyBhXG4gICAgICAgICAgICAgICAgPElubGluZUxpbmtcbiAgICAgICAgICAgICAgICAgIHRhcmdldD1cIl9ibGFua1wiXG4gICAgICAgICAgICAgICAgICBocmVmPVwiaHR0cHM6Ly93d3cubWFwYm94LmNvbS9oZWxwL3N0dWRpby1tYW51YWwtcHVibGlzaC8jc3R5bGUtdXJsXCJcbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICB7JyAnfVxuICAgICAgICAgICAgICAgICAgc3R5bGUgVVJMXG4gICAgICAgICAgICAgICAgPC9JbmxpbmVMaW5rPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPElucHV0TGlnaHRcbiAgICAgICAgICAgICAgICB0eXBlPVwidGV4dFwiXG4gICAgICAgICAgICAgICAgdmFsdWU9e2lucHV0U3R5bGUudXJsIHx8ICcnfVxuICAgICAgICAgICAgICAgIG9uQ2hhbmdlPXsoe3RhcmdldDoge3ZhbHVlfX0pID0+XG4gICAgICAgICAgICAgICAgICB0aGlzLnByb3BzLmlucHV0TWFwU3R5bGUoe3VybDogdmFsdWV9KVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cImUuZy4gbWFwYm94Oi8vc3R5bGVzL3ViZXJkYXRhdml6L2FiY2RlZmdoaWprbG1ub3BxXCJcbiAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgIDwvU3R5bGVkTW9kYWxTZWN0aW9uPlxuICAgICAgICAgICAgPFN0eWxlZE1vZGFsU2VjdGlvbiBjbGFzc05hbWU9XCJtb2RhbC1zZWN0aW9uXCI+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwibW9kYWwtc2VjdGlvbi10aXRsZVwiPjMuIE5hbWUgeW91ciBzdHlsZTwvZGl2PlxuICAgICAgICAgICAgICA8SW5wdXRMaWdodFxuICAgICAgICAgICAgICAgIHR5cGU9XCJ0ZXh0XCJcbiAgICAgICAgICAgICAgICB2YWx1ZT17aW5wdXRTdHlsZS5sYWJlbCB8fCAnJ31cbiAgICAgICAgICAgICAgICBvbkNoYW5nZT17KHt0YXJnZXQ6IHt2YWx1ZX19KSA9PlxuICAgICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5pbnB1dE1hcFN0eWxlKHtsYWJlbDogdmFsdWV9KVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgIDwvU3R5bGVkTW9kYWxTZWN0aW9uPlxuICAgICAgICAgIDwvSW5zdHJ1Y3Rpb25QYW5lbD5cbiAgICAgICAgICA8UHJldmlld01hcD5cbiAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgY2xhc3NOYW1lPXtjbGFzc25hbWVzKCdwcmV2aWV3LXRpdGxlJywge2Vycm9yOiBpbnB1dFN0eWxlLmVycm9yfSl9XG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIHtpbnB1dFN0eWxlLmVycm9yXG4gICAgICAgICAgICAgICAgPyBFcnJvck1zZy5zdHlsZUVycm9yXG4gICAgICAgICAgICAgICAgOiAoaW5wdXRTdHlsZS5zdHlsZSAmJiBpbnB1dFN0eWxlLnN0eWxlLm5hbWUpIHx8ICcnfVxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8U3R5bGVkUHJldmlld0ltYWdlIGNsYXNzTmFtZT1cInByZXZpZXctaW1hZ2VcIj5cbiAgICAgICAgICAgICAgeyFpbnB1dFN0eWxlLmlzVmFsaWQgPyAoXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJwcmV2aWV3LWltYWdlLXNwaW5uZXJcIiAvPlxuICAgICAgICAgICAgICApIDogKFxuICAgICAgICAgICAgICAgIDxTdHlsZWRNYXBDb250YWluZXI+XG4gICAgICAgICAgICAgICAgICA8TWFwYm94R0xNYXBcbiAgICAgICAgICAgICAgICAgICAgey4uLm1hcFByb3BzfVxuICAgICAgICAgICAgICAgICAgICByZWY9e2VsID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLm1hcFJlZiA9IGVsO1xuICAgICAgICAgICAgICAgICAgICB9fVxuICAgICAgICAgICAgICAgICAgICBrZXk9e3RoaXMuc3RhdGUucmVSZW5kZXJLZXl9XG4gICAgICAgICAgICAgICAgICAgIHdpZHRoPXtNYXBXfVxuICAgICAgICAgICAgICAgICAgICBoZWlnaHQ9e01hcEh9XG4gICAgICAgICAgICAgICAgICAgIG1hcFN0eWxlPXtpbnB1dFN0eWxlLnVybH1cbiAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgPC9TdHlsZWRNYXBDb250YWluZXI+XG4gICAgICAgICAgICAgICl9XG4gICAgICAgICAgICA8L1N0eWxlZFByZXZpZXdJbWFnZT5cbiAgICAgICAgICA8L1ByZXZpZXdNYXA+XG4gICAgICAgIDwvU3R5bGVkTW9kYWxDb250ZW50PlxuICAgICAgPC9kaXY+XG4gICAgKTtcbiAgfVxufVxuXG5jb25zdCBBZGRNYXBTdHlsZU1vZGFsRmFjdG9yeSA9ICgpID0+IEFkZE1hcFN0eWxlTW9kYWw7XG5leHBvcnQgZGVmYXVsdCBBZGRNYXBTdHlsZU1vZGFsRmFjdG9yeTtcbiJdfQ==