leaflet-labeled-circle
Version:
Special type of SVG marker with a label inside and draggable around the anchor point
1,076 lines (884 loc) • 78.3 kB
JavaScript
(function(){function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}return e})()({1:[function(require,module,exports){
'use strict';
/**
* Leaflet SVG circle marker with detachable and draggable label and text
*
* @author Alexander Milevski <info@w8r.name>
* @license MIT
* @preserve
*/
module.exports = require('./src/marker');
},{"./src/marker":9}],2:[function(require,module,exports){
require('./src/SVG');
require('./src/SVG.VML');
require('./src/Canvas');
require('./src/Path.Transform');
require('./src/Path.Drag');
module.exports = L.Path.Drag;
},{"./src/Canvas":3,"./src/Path.Drag":4,"./src/Path.Transform":5,"./src/SVG":7,"./src/SVG.VML":6}],3:[function(require,module,exports){
function TRUE_FN () { return true; }
L.Canvas.include({
/**
* Do nothing
* @param {L.Path} layer
*/
_resetTransformPath: function(layer) {
if (!this._containerCopy) return;
delete this._containerCopy;
if (layer._containsPoint_) {
layer._containsPoint = layer._containsPoint_;
delete layer._containsPoint_;
this._requestRedraw(layer);
}
},
/**
* Algorithm outline:
*
* 1. pre-transform - clear the path out of the canvas, copy canvas state
* 2. at every frame:
* 2.1. save
* 2.2. redraw the canvas from saved one
* 2.3. transform
* 2.4. draw path
* 2.5. restore
* 3. Repeat
*
* @param {L.Path} layer
* @param {Array.<Number>} matrix
*/
transformPath: function(layer, matrix) {
var copy = this._containerCopy;
var ctx = this._ctx, copyCtx;
var m = L.Browser.retina ? 2 : 1;
var bounds = this._bounds;
var size = bounds.getSize();
var pos = bounds.min;
if (!copy) { // get copy of all rendered layers
copy = this._containerCopy = document.createElement('canvas');
copyCtx = copy.getContext('2d');
// document.body.appendChild(copy);
copy.width = m * size.x;
copy.height = m * size.y;
this._removePath(layer);
this._redraw();
copyCtx.translate(m * bounds.min.x, m * bounds.min.y);
copyCtx.drawImage(this._container, 0, 0);
this._initPath(layer);
// avoid flickering because of the 'mouseover's
layer._containsPoint_ = layer._containsPoint;
layer._containsPoint = TRUE_FN;
}
ctx.save();
ctx.clearRect(pos.x, pos.y, size.x * m, size.y * m);
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.restore();
ctx.save();
ctx.drawImage(this._containerCopy, 0, 0, size.x, size.y);
ctx.transform.apply(ctx, matrix);
// now draw one layer only
this._drawing = true;
layer._updatePath();
this._drawing = false;
ctx.restore();
}
});
},{}],4:[function(require,module,exports){
var END = {
mousedown: 'mouseup',
touchstart: 'touchend',
pointerdown: 'touchend',
MSPointerDown: 'touchend'
};
var MOVE = {
mousedown: 'mousemove',
touchstart: 'touchmove',
pointerdown: 'touchmove',
MSPointerDown: 'touchmove'
};
function distance(a, b) {
var dx = a.x - b.x, dy = a.y - b.y;
return Math.sqrt(dx * dx + dy * dy);
}
/**
* Drag handler
* @class L.Path.Drag
* @extends {L.Handler}
*/
L.Handler.PathDrag = L.Handler.extend( /** @lends L.Path.Drag.prototype */ {
statics: {
DRAGGING_CLS: 'leaflet-path-draggable',
},
/**
* @param {L.Path} path
* @constructor
*/
initialize: function(path) {
/**
* @type {L.Path}
*/
this._path = path;
/**
* @type {Array.<Number>}
*/
this._matrix = null;
/**
* @type {L.Point}
*/
this._startPoint = null;
/**
* @type {L.Point}
*/
this._dragStartPoint = null;
/**
* @type {Boolean}
*/
this._mapDraggingWasEnabled = false;
},
/**
* Enable dragging
*/
addHooks: function() {
this._path.on('mousedown', this._onDragStart, this);
this._path.options.className = this._path.options.className ?
(this._path.options.className + ' ' + L.Handler.PathDrag.DRAGGING_CLS) :
L.Handler.PathDrag.DRAGGING_CLS;
if (this._path._path) {
L.DomUtil.addClass(this._path._path, L.Handler.PathDrag.DRAGGING_CLS);
}
},
/**
* Disable dragging
*/
removeHooks: function() {
this._path.off('mousedown', this._onDragStart, this);
this._path.options.className = this._path.options.className
.replace(new RegExp('\\s+' + L.Handler.PathDrag.DRAGGING_CLS), '');
if (this._path._path) {
L.DomUtil.removeClass(this._path._path, L.Handler.PathDrag.DRAGGING_CLS);
}
},
/**
* @return {Boolean}
*/
moved: function() {
return this._path._dragMoved;
},
/**
* Start drag
* @param {L.MouseEvent} evt
*/
_onDragStart: function(evt) {
var eventType = evt.originalEvent._simulated ? 'touchstart' : evt.originalEvent.type;
this._mapDraggingWasEnabled = false;
this._startPoint = evt.containerPoint.clone();
this._dragStartPoint = evt.containerPoint.clone();
this._matrix = [1, 0, 0, 1, 0, 0];
L.DomEvent.stop(evt.originalEvent);
L.DomUtil.addClass(this._path._renderer._container, 'leaflet-interactive');
L.DomEvent
.on(document, MOVE[eventType], this._onDrag, this)
.on(document, END[eventType], this._onDragEnd, this);
if (this._path._map.dragging.enabled()) {
// I guess it's required because mousdown gets simulated with a delay
//this._path._map.dragging._draggable._onUp(evt);
this._path._map.dragging.disable();
this._mapDraggingWasEnabled = true;
}
this._path._dragMoved = false;
if (this._path._popup) { // that might be a case on touch devices as well
this._path._popup._close();
}
this._replaceCoordGetters(evt);
},
/**
* Dragging
* @param {L.MouseEvent} evt
*/
_onDrag: function(evt) {
L.DomEvent.stop(evt);
var first = (evt.touches && evt.touches.length >= 1 ? evt.touches[0] : evt);
var containerPoint = this._path._map.mouseEventToContainerPoint(first);
// skip taps
if (evt.type === 'touchmove' && !this._path._dragMoved) {
var totalMouseDragDistance = this._dragStartPoint.distanceTo(containerPoint);
if (totalMouseDragDistance <= this._path._map.options.tapTolerance) {
return;
}
}
var x = containerPoint.x;
var y = containerPoint.y;
var dx = x - this._startPoint.x;
var dy = y - this._startPoint.y;
// Send events only if point was moved
if (dx || dy) {
if (!this._path._dragMoved) {
this._path._dragMoved = true;
this._path.fire('dragstart', evt);
// we don't want that to happen on click
this._path.bringToFront();
}
this._matrix[4] += dx;
this._matrix[5] += dy;
this._startPoint.x = x;
this._startPoint.y = y;
this._path.fire('predrag', evt);
this._path._transform(this._matrix);
this._path.fire('drag', evt);
}
},
/**
* Dragging stopped, apply
* @param {L.MouseEvent} evt
*/
_onDragEnd: function(evt) {
var containerPoint = this._path._map.mouseEventToContainerPoint(evt);
var moved = this.moved();
// apply matrix
if (moved) {
this._transformPoints(this._matrix);
this._path._updatePath();
this._path._project();
this._path._transform(null);
L.DomEvent.stop(evt);
}
L.DomEvent.off(document, 'mousemove touchmove', this._onDrag, this);
L.DomEvent.off(document, 'mouseup touchend', this._onDragEnd, this);
this._restoreCoordGetters();
// consistency
if (moved) {
this._path.fire('dragend', {
distance: distance(this._dragStartPoint, containerPoint)
});
// hack for skipping the click in canvas-rendered layers
var contains = this._path._containsPoint;
this._path._containsPoint = L.Util.falseFn;
L.Util.requestAnimFrame(function() {
L.DomEvent.skipped({ type: 'click' });
this._path._containsPoint = contains;
}, this);
}
this._matrix = null;
this._startPoint = null;
this._dragStartPoint = null;
this._path._dragMoved = false;
if (this._mapDraggingWasEnabled) {
if (moved) L.DomEvent.fakeStop({ type: 'click' });
this._path._map.dragging.enable();
}
},
/**
* Applies transformation, does it in one sweep for performance,
* so don't be surprised about the code repetition.
*
* [ x ] [ a b tx ] [ x ] [ a * x + b * y + tx ]
* [ y ] = [ c d ty ] [ y ] = [ c * x + d * y + ty ]
*
* @param {Array.<Number>} matrix
*/
_transformPoints: function(matrix, dest) {
var path = this._path;
var i, len, latlng;
var px = L.point(matrix[4], matrix[5]);
var crs = path._map.options.crs;
var transformation = crs.transformation;
var scale = crs.scale(path._map.getZoom());
var projection = crs.projection;
var diff = transformation.untransform(px, scale)
.subtract(transformation.untransform(L.point(0, 0), scale));
var applyTransform = !dest;
path._bounds = new L.LatLngBounds();
// console.time('transform');
// all shifts are in-place
if (path._point) { // L.Circle
dest = projection.unproject(
projection.project(path._latlng)._add(diff));
if (applyTransform) {
path._latlng = dest;
path._point._add(px);
}
} else if (path._rings || path._parts) { // everything else
var rings = path._rings || path._parts;
var latlngs = path._latlngs;
dest = dest || latlngs;
if (!L.Util.isArray(latlngs[0])) { // polyline
latlngs = [latlngs];
dest = [dest];
}
for (i = 0, len = rings.length; i < len; i++) {
dest[i] = dest[i] || [];
for (var j = 0, jj = rings[i].length; j < jj; j++) {
latlng = latlngs[i][j];
dest[i][j] = projection
.unproject(projection.project(latlng)._add(diff));
if (applyTransform) {
path._bounds.extend(latlngs[i][j]);
rings[i][j]._add(px);
}
}
}
}
return dest;
// console.timeEnd('transform');
},
/**
* If you want to read the latlngs during the drag - your right,
* but they have to be transformed
*/
_replaceCoordGetters: function() {
if (this._path.getLatLng) { // Circle, CircleMarker
this._path.getLatLng_ = this._path.getLatLng;
this._path.getLatLng = L.Util.bind(function() {
return this.dragging._transformPoints(this.dragging._matrix, {});
}, this._path);
} else if (this._path.getLatLngs) {
this._path.getLatLngs_ = this._path.getLatLngs;
this._path.getLatLngs = L.Util.bind(function() {
return this.dragging._transformPoints(this.dragging._matrix, []);
}, this._path);
}
},
/**
* Put back the getters
*/
_restoreCoordGetters: function() {
if (this._path.getLatLng_) {
this._path.getLatLng = this._path.getLatLng_;
delete this._path.getLatLng_;
} else if (this._path.getLatLngs_) {
this._path.getLatLngs = this._path.getLatLngs_;
delete this._path.getLatLngs_;
}
}
});
/**
* @param {L.Path} layer
* @return {L.Path}
*/
L.Handler.PathDrag.makeDraggable = function(layer) {
layer.dragging = new L.Handler.PathDrag(layer);
return layer;
};
/**
* Also expose as a method
* @return {L.Path}
*/
L.Path.prototype.makeDraggable = function() {
return L.Handler.PathDrag.makeDraggable(this);
};
L.Path.addInitHook(function() {
if (this.options.draggable) {
// ensure interactive
this.options.interactive = true;
if (this.dragging) {
this.dragging.enable();
} else {
L.Handler.PathDrag.makeDraggable(this);
this.dragging.enable();
}
} else if (this.dragging) {
this.dragging.disable();
}
});
},{}],5:[function(require,module,exports){
/**
* Leaflet vector features drag functionality
* @author Alexander Milevski <info@w8r.name>
* @preserve
*/
/**
* Matrix transform path for SVG/VML
* Renderer-independent
*/
L.Path.include({
/**
* Applies matrix transformation to SVG
* @param {Array.<Number>?} matrix
*/
_transform: function(matrix) {
if (this._renderer) {
if (matrix) {
this._renderer.transformPath(this, matrix);
} else {
// reset transform matrix
this._renderer._resetTransformPath(this);
this._update();
}
}
return this;
},
/**
* Check if the feature was dragged, that'll supress the click event
* on mouseup. That fixes popups for example
*
* @param {MouseEvent} e
*/
_onMouseClick: function(e) {
if ((this.dragging && this.dragging.moved()) ||
(this._map.dragging && this._map.dragging.moved())) {
return;
}
this._fireMouseEvent(e);
}
});
},{}],6:[function(require,module,exports){
L.SVG.include(!L.Browser.vml ? {} : {
/**
* Reset transform matrix
*/
_resetTransformPath: function(layer) {
if (layer._skew) {
// super important! workaround for a 'jumping' glitch:
// disable transform before removing it
layer._skew.on = false;
layer._path.removeChild(layer._skew);
layer._skew = null;
}
},
/**
* Applies matrix transformation to VML
* @param {L.Path} layer
* @param {Array.<Number>} matrix
*/
transformPath: function(layer, matrix) {
var skew = layer._skew;
if (!skew) {
skew = L.SVG.create('skew');
layer._path.appendChild(skew);
skew.style.behavior = 'url(#default#VML)';
layer._skew = skew;
}
// handle skew/translate separately, cause it's broken
var mt = matrix[0].toFixed(8) + ' ' + matrix[1].toFixed(8) + ' ' +
matrix[2].toFixed(8) + ' ' + matrix[3].toFixed(8) + ' 0 0';
var offset = Math.floor(matrix[4]).toFixed() + ', ' +
Math.floor(matrix[5]).toFixed() + '';
var s = this._path.style;
var l = parseFloat(s.left);
var t = parseFloat(s.top);
var w = parseFloat(s.width);
var h = parseFloat(s.height);
if (isNaN(l)) l = 0;
if (isNaN(t)) t = 0;
if (isNaN(w) || !w) w = 1;
if (isNaN(h) || !h) h = 1;
var origin = (-l / w - 0.5).toFixed(8) + ' ' + (-t / h - 0.5).toFixed(8);
skew.on = 'f';
skew.matrix = mt;
skew.origin = origin;
skew.offset = offset;
skew.on = true;
}
});
},{}],7:[function(require,module,exports){
L.SVG.include({
/**
* Reset transform matrix
*/
_resetTransformPath: function(layer) {
layer._path.setAttributeNS(null, 'transform', '');
},
/**
* Applies matrix transformation to SVG
* @param {L.Path} layer
* @param {Array.<Number>} matrix
*/
transformPath: function(layer, matrix) {
layer._path.setAttributeNS(null, 'transform',
'matrix(' + matrix.join(' ') + ')');
}
});
},{}],8:[function(require,module,exports){
(function (global){
"use strict";
var L = typeof window !== "undefined" ? window['L'] : typeof global !== "undefined" ? global['L'] : null;
var Circle = L.CircleMarker.extend({
options: {
textStyle: {
color: '#fff',
fontSize: 12,
fontWeight: 300
},
shiftY: 7
},
/**
* @class LabeledCircle
* @constructor
* @extends {L.CircleMarker}
* @param {String} text
* @param {L.LatLng} latlng
* @param {Object=} options
*/
initialize: function initialize(text, latlng, options) {
/**
* @type {String}
*/
this._text = text;
/**
* @type {SVGTextElement}
*/
this._textElement = null;
/**
* @type {TextNode}
*/
this._textNode = null;
/**
* @type {Object|Null}
*/
this._textLayer = null;
L.CircleMarker.prototype.initialize.call(this, latlng, options);
},
/**
* @param {String} text
* @return {LabeledCircle}
*/
setText: function setText(text) {
this._text = text;
if (this._textNode) {
this._textElement.removeChild(this._textNode);
}
this._textNode = document.createTextNode(this._text);
this._textElement.appendChild(this._textNode);
return this;
},
/**
* @return {String}
*/
getText: function getText() {
return this._text;
},
/**
* Also bring text to front
* @override
*/
bringToFront: function bringToFront() {
L.CircleMarker.prototype.bringToFront.call(this);
this._groupTextToPath();
},
/**
* @override
*/
bringToBack: function bringToBack() {
L.CircleMarker.prototype.bringToBack.call(this);
this._groupTextToPath();
},
/**
* Put text in the right position in the dom
*/
_groupTextToPath: function _groupTextToPath() {
var path = this._path;
var textElement = this._textElement;
var next = path.nextSibling;
var parent = path.parentNode;
if (textElement && parent) {
if (next && next !== textElement) {
parent.insertBefore(textElement, next);
} else {
parent.appendChild(textElement);
}
}
},
/**
* Position the text in container
*/
_updatePath: function _updatePath() {
L.CircleMarker.prototype._updatePath.call(this);
this._updateTextPosition();
},
/**
* @override
*/
_transform: function _transform(matrix) {
L.CircleMarker.prototype._transform.call(this, matrix);
// wrap textElement with a fake layer for renderer
// to be able to transform it
this._textLayer = this._textLayer || { _path: this._textElement };
if (matrix) {
this._renderer.transformPath(this._textLayer, matrix);
} else {
this._renderer._resetTransformPath(this._textLayer);
this._updateTextPosition();
this._textLayer = null;
}
},
/**
* @param {L.Map} map
* @return {LabeledCircle}
*/
onAdd: function onAdd(map) {
L.CircleMarker.prototype.onAdd.call(this, map);
this._initText();
this._updateTextPosition();
this.setStyle({});
return this;
},
/**
* Create and insert text
*/
_initText: function _initText() {
this._textElement = L.SVG.create('text');
this.setText(this._text);
this._renderer._rootGroup.appendChild(this._textElement);
},
/**
* Calculate position for text
*/
_updateTextPosition: function _updateTextPosition() {
var textElement = this._textElement;
if (textElement) {
var bbox = textElement.getBBox();
var textPosition = this._point.subtract(L.point(bbox.width, -bbox.height + this.options.shiftY).divideBy(2));
textElement.setAttribute('x', textPosition.x);
textElement.setAttribute('y', textPosition.y);
this._groupTextToPath();
}
},
/**
* Set text style
*/
setStyle: function setStyle(style) {
L.CircleMarker.prototype.setStyle.call(this, style);
if (this._textElement) {
var styles = this.options.textStyle;
for (var prop in styles) {
if (styles.hasOwnProperty(prop)) {
var styleProp = prop;
if (prop === 'color') {
styleProp = 'stroke';
}
this._textElement.style[styleProp] = styles[prop];
}
}
}
},
/**
* Remove text
*/
onRemove: function onRemove(map) {
if (this._textElement) {
if (this._textElement.parentNode) {
this._textElement.parentNode.removeChild(this._textElement);
}
this._textElement = null;
this._textNode = null;
this._textLayer = null;
}
return L.CircleMarker.prototype.onRemove.call(this, map);
}
});
module.exports = L.TextCircle = Circle;
L.textCircle = function (text, latlng, options) {
return new Circle(text, latlng, options);
};
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{}],9:[function(require,module,exports){
(function (global){
"use strict";
var L = typeof window !== "undefined" ? window['L'] : typeof global !== "undefined" ? global['L'] : null;
var Circle = require('./circle');
require('leaflet-path-drag');
var LabeledMarker = L.FeatureGroup.extend({
options: {
/**
* @param {LabeledMarker} marker
* @param {Object} feature
* @return {String}
*/
getLabelText: function getLabelText(marker, feature) {
return feature.properties.text;
},
/**
* @param {LabeledMarker} marker
* @param {Object} feature
* @param {L.LatLng} latlng
* @return {L.LatLng}
*/
getLabelPosition: function getLabelPosition(marker, feature, latlng) {
return feature.properties.labelPosition ? L.latLng(feature.properties.labelPosition.slice().reverse()) : latlng;
},
labelPositionKey: 'labelPosition',
markerOptions: {
color: '#f00',
fillOpacity: 0.75,
draggable: true,
radius: 15
},
anchorOptions: {
color: '#00f',
radius: 3
},
lineOptions: {
color: '#f00',
dashArray: [2, 6],
lineCap: 'square',
weight: 2
}
},
/**
* @class LabeledMarker
* @constructor
* @extends {L.FeatureGroup}
*
* @param {L.LatLng} latlng
* @param {Object=} feature
* @param {Object=} options
*/
initialize: function initialize(latlng, feature, options) {
L.Util.setOptions(this, options);
/**
* @type {Object}
*/
this.feature = feature || {
type: 'Feature',
properties: {},
geometry: {
'type': 'Point'
}
};
/**
* @type {L.LatLng}
*/
this._latlng = latlng;
/**
* @type {CircleLabel}
*/
this._marker = null;
/**
* @type {L.CircleMarker}
*/
this._anchor = null;
/**
* @type {L.Polyline}
*/
this._line = null;
/**
* @type {L.Point}
*/
this._initialDistance = null;
this._createLayers();
L.LayerGroup.prototype.initialize.call(this, [this._anchor, this._line, this._marker]);
},
/**
* @return {L.LatLng}
*/
getLabelPosition: function getLabelPosition() {
return this._marker.getLatLng();
},
/**
* @return {L.LatLng}
*/
getLatLng: function getLatLng() {
return this._latlng;
},
/**
* Serialize
* @return {Object}
*/
toGeoJSON: function toGeoJSON(geometryCollection) {
var feature = L.GeoJSON.getFeature(this, {
type: 'Point',
coordinates: L.GeoJSON.latLngToCoords(this._anchor.getLatLng())
});
feature.properties[this.options.labelPositionKey] = L.GeoJSON.latLngToCoords(this._marker.getLatLng());
feature.properties.text = this._marker.getText();
return geometryCollection ? L.LabeledCircleMarker.toGeometryCollection(feature, this.options.labelPositionKey) : feature;
},
/**
* @param {String} text
* @return {LabeledMarker}
*/
setText: function setText(text) {
this._marker.setText(text);
return this;
},
/**
* Creates anchor, line and label
*/
_createLayers: function _createLayers() {
var opts = this.options;
var pos = opts.getLabelPosition(this, this.feature, this._latlng);
var text = opts.getLabelText(this, this.feature);
if ('draggable' in opts) {
opts.markerOptions.draggable = opts.draggable;
}
this._marker = new Circle(text, pos, L.Util.extend({
interactive: this.options.interactive
}, LabeledMarker.prototype.options.markerOptions, opts.markerOptions)).on('drag', this._onMarkerDrag, this).on('dragstart', this._onMarkerDragStart, this).on('dragend', this._onMarkerDragEnd, this);
this._anchor = new L.CircleMarker(this._latlng, L.Util.extend({}, LabeledMarker.prototype.options.anchorOptions, opts.anchorOptions));
this._line = new L.Polyline([this._latlng, this._marker.getLatLng()], L.Util.extend({}, LabeledMarker.prototype.options.lineOptions, opts.lineOptions));
},
/**
* Store shift to be precise while dragging
* @param {Event} evt
*/
_onMarkerDragStart: function _onMarkerDragStart(evt) {
this._initialDistance = L.DomEvent.getMousePosition(evt).subtract(this._map.latLngToContainerPoint(this._marker.getLatLng()));
this.fire('label:' + evt.type, evt);
//L.Util.requestAnimFrame(this._marker.bringToFront, this._marker);
},
/**
* Line dragging
* @param {DragEvent} evt
*/
_onMarkerDrag: function _onMarkerDrag(evt) {
var latlng = this._map.containerPointToLatLng(L.DomEvent.getMousePosition(evt)._subtract(this._initialDistance));
this._line.setLatLngs([latlng, this._latlng]);
this.fire('label:' + evt.type, evt);
},
_onMarkerDragEnd: function _onMarkerDragEnd(evt) {
this._line.setLatLngs([this._marker.getLatLng(), this._latlng]);
this.fire('label:' + evt.type, evt);
},
enableDragging: function enableDragging() {
if (this._marker.dragging) this._marker.dragging.enable();
return this;
},
disableDragging: function disableDragging() {
if (this._marker.dragging) this._marker.dragging.disable();
return this;
}
});
/**
* @param {Object} feature
* @param {String=} key
* @return {Object}
*/
function toGeometryCollection(feature, key) {
key = key || 'labelPosition';
var anchorPos = feature.geometry.coordinates.slice();
var labelPos = feature.properties[key];
if (!labelPos) throw new Error('No label position set');
labelPos = labelPos.slice();
var geometries = [{
type: 'Point',
coordinates: anchorPos
}, {
type: 'LineString',
coordinates: [anchorPos.slice(), labelPos]
}, {
type: 'Point',
coordinates: labelPos.slice()
}, {
type: 'Point',
coordinates: labelPos.slice()
}];
return {
type: 'Feature',
properties: L.Util.extend({}, feature.properties, {
geometriesTypes: ['anchor', 'connection', 'label', 'textbox']
}),
bbox: feature.bbox,
geometry: {
type: 'GeometryCollection',
geometries: geometries
}
};
}
LabeledMarker.toGeometryCollection = toGeometryCollection;
L.LabeledCircleMarker = LabeledMarker;
L.labeledCircleMarker = function (latlng, feature, options) {
return new LabeledMarker(latlng, feature, options);
};
module.exports = LabeledMarker;
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"./circle":8,"leaflet-path-drag":2}]},{},[1])
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJpbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9sZWFmbGV0LXBhdGgtZHJhZy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9sZWFmbGV0LXBhdGgtZHJhZy9zcmMvQ2FudmFzLmpzIiwibm9kZV9tb2R1bGVzL2xlYWZsZXQtcGF0aC1kcmFnL3NyYy9QYXRoLkRyYWcuanMiLCJub2RlX21vZHVsZXMvbGVhZmxldC1wYXRoLWRyYWcvc3JjL1BhdGguVHJhbnNmb3JtLmpzIiwibm9kZV9tb2R1bGVzL2xlYWZsZXQtcGF0aC1kcmFnL3NyYy9TVkcuVk1MLmpzIiwibm9kZV9tb2R1bGVzL2xlYWZsZXQtcGF0aC1kcmFnL3NyYy9TVkcuanMiLCJzcmMvY2lyY2xlLmpzIiwic3JjL21hcmtlci5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7O0FDQUE7Ozs7Ozs7QUFPQSxPQUFPLE9BQVAsR0FBaUIsUUFBUSxjQUFSLENBQWpCOzs7QUNQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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VTtBQUNSLFlBQU0sb0JBREU7QUFFUixrQkFBWTtBQUZKO0FBTkwsR0FBUDtBQVdEOztBQUVELGNBQWMsb0JBQWQsR0FBcUMsb0JBQXJDOztBQUVBLEVBQUUsbUJBQUYsR0FBd0IsYUFBeEI7QUFDQSxFQUFFLG1CQUFGLEdBQXdCLFVBQUMsTUFBRCxFQUFTLE9BQVQsRUFBa0IsT0FBbEIsRUFBOEI7QUFDcEQsU0FBTyxJQUFJLGFBQUosQ0FBa0IsTUFBbEIsRUFBMEIsT0FBMUIsRUFBbUMsT0FBbkMsQ0FBUDtBQUNELENBRkQ7O0FBSUEsT0FBTyxPQUFQLEdBQWlCLGFBQWpCIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24oKXtmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dmFyIGY9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKTt0aHJvdyBmLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsZn12YXIgbD1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwobC5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxsLGwuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc31yZXR1cm4gZX0pKCkiLCIvKipcbiAqIExlYWZsZXQgU1ZHIGNpcmNsZSBtYXJrZXIgd2l0aCBkZXRhY2hhYmxlIGFuZCBkcmFnZ2FibGUgbGFiZWwgYW5kIHRleHRcbiAqXG4gKiBAYXV0aG9yIEFsZXhhbmRlciBNaWxldnNraSA8aW5mb0B3OHIubmFtZT5cbiAqIEBsaWNlbnNlIE1JVFxuICogQHByZXNlcnZlXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9zcmMvbWFya2VyJyk7XG4iLCJyZXF1aXJlKCcuL3NyYy9TVkcnKTtcbnJlcXVpcmUoJy4vc3JjL1NWRy5WTUwnKTtcbnJlcXVpcmUoJy4vc3JjL0NhbnZhcycpO1xucmVxdWlyZSgnLi9zcmMvUGF0aC5UcmFuc2Zvcm0nKTtcbnJlcXVpcmUoJy4vc3JjL1BhdGguRHJhZycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IEwuUGF0aC5EcmFnO1xuIiwiZnVuY3Rpb24gVFJVRV9GTiAoKSB7IHJldHVybiB0cnVlOyB9XG5cbkwuQ2FudmFzLmluY2x1ZGUoe1xuXG4gIC8qKlxuICAgKiBEbyBub3RoaW5nXG4gICAqIEBwYXJhbSAge0wuUGF0aH0gbGF5ZXJcbiAgICovXG4gIF9yZXNldFRyYW5zZm9ybVBhdGg6IGZ1bmN0aW9uKGxheWVyKSB7XG4gICAgaWYgKCF0aGlzLl9jb250YWluZXJDb3B5KSByZXR1cm47XG5cbiAgICBkZWxldGUgdGhpcy5fY29udGFpbmVyQ29weTtcblxuICAgIGlmIChsYXllci5fY29udGFpbnNQb2ludF8pIHtcbiAgICAgIGxheWVyLl9jb250YWluc1BvaW50ID0gbGF5ZXIuX2NvbnRhaW5zUG9pbnRfO1xuICAgICAgZGVsZXRlIGxheWVyLl9jb250YWluc1BvaW50XztcblxuICAgICAgdGhpcy5fcmVxdWVzdFJlZHJhdyhsYXllcik7XG4gICAgfVxuICB9LFxuXG5cbiAgLyoqXG4gICAqIEFsZ29yaXRobSBvdXRsaW5lOlxuICAgKlxuICAgKiAxLiBwcmUtdHJhbnNmb3JtIC0gY2xlYXIgdGhlIHBhdGggb3V0IG9mIHRoZSBjYW52YXMsIGNvcHkgY2FudmFzIHN0YXRlXG4gICAqIDIuIGF0IGV2ZXJ5IGZyYW1lOlxuICAgKiAgICAyLjEuIHNhdmVcbiAgICogICAgMi4yLiByZWRyYXcgdGhlIGNhbnZhcyBmcm9tIHNhdmVkIG9uZVxuICAgKiAgICAyLjMuIHRyYW5zZm9ybVxuICAgKiAgICAyLjQuIGRyYXcgcGF0aFxuICAgKiAgICAyLjUuIHJlc3RvcmVcbiAgICogMy4gUmVwZWF0XG4gICAqXG4gICAqIEBwYXJhbSAge0wuUGF0aH0gICAgICAgICBsYXllclxuICAgKiBAcGFyYW0gIHtBcnJheS48TnVtYmVyPn0gbWF0cml4XG4gICAqL1xuICB0cmFuc2Zvcm1QYXRoOiBmdW5jdGlvbihsYXllciwgbWF0cml4KSB7XG4gICAgdmFyIGNvcHkgICA9IHRoaXMuX2NvbnRhaW5lckNvcHk7XG4gICAgdmFyIGN0eCAgICA9IHRoaXMuX2N0eCwgY29weUN0eDtcbiAgICB2YXIgbSAgICAgID0gTC5Ccm93c2VyLnJldGluYSA/IDIgOiAxO1xuICAgIHZhciBib3VuZHMgPSB0aGlzLl9ib3VuZHM7XG4gICAgdmFyIHNpemUgICA9IGJvdW5kcy5nZXRTaXplKCk7XG4gICAgdmFyIHBvcyAgICA9IGJvdW5kcy5taW47XG5cbiAgICBpZiAoIWNvcHkpIHsgLy8gZ2V0IGNvcHkgb2YgYWxsIHJlbmRlcmVkIGxheWVyc1xuICAgICAgY29weSA9IHRoaXMuX2NvbnRhaW5lckNvcHkgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKTtcbiAgICAgIGNvcHlDdHggPSBjb3B5LmdldENvbnRleHQoJzJkJyk7XG4gICAgICAvLyBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGNvcHkpO1xuXG4gICAgICBjb3B5LndpZHRoICA9IG0gKiBzaXplLng7XG4gICAgICBjb3B5LmhlaWdodCA9IG0gKiBzaXplLnk7XG5cbiAgICAgIHRoaXMuX3JlbW92ZVBhdGgobGF5ZXIpO1xuICAgICAgdGhpcy5fcmVkcmF3KCk7XG5cbiAgICAgIGNvcHlDdHgudHJhbnNsYXRlKG0gKiBib3VuZHMubWluLngsIG0gKiBib3VuZHMubWluLnkpO1xuICAgICAgY29weUN0eC5kcmF3SW1hZ2UodGhpcy5fY29udGFpbmVyLCAwLCAwKTtcbiAgICAgIHRoaXMuX2luaXRQYXRoKGxheWVyKTtcblxuICAgICAgLy8gYXZvaWQgZmxpY2tlcmluZyBiZWNhdXNlIG9mIHRoZSAnbW91c2VvdmVyJ3NcbiAgICAgIGxheWVyLl9jb250YWluc1BvaW50XyA9IGxheWVyLl9jb250YWluc1BvaW50O1xuICAgICAgbGF5ZXIuX2NvbnRhaW5zUG9pbnQgID0gVFJVRV9GTjtcbiAgICB9XG5cbiAgICBjdHguc2F2ZSgpO1xuICAgIGN0eC5jbGVhclJlY3QocG9zLngsIHBvcy55LCBzaXplLnggKiBtLCBzaXplLnkgKiBtKTtcbiAgICBjdHguc2V0VHJhbnNmb3JtKDEsIDAsIDAsIDEsIDAsIDApO1xuICAgIGN0eC5yZXN0b3JlKCk7XG4gICAgY3R4LnNhdmUoKTtcblxuICAgIGN0eC5kcmF3SW1hZ2UodGhpcy5fY29udGFpbmVyQ29weSwgMCwgMCwgc2l6ZS54LCBzaXplLnkpO1xuICAgIGN0eC50cmFuc2Zvcm0uYXBwbHkoY3R4LCBtYXRyaXgpO1xuXG4gICAgLy8gbm93IGRyYXcgb25lIGxheWVyIG9ubHlcbiAgICB0aGlzLl9kcmF3aW5nID0gdHJ1ZTtcbiAgICBsYXllci5fdXBkYXRlUGF0aCgpO1xuICAgIHRoaXMuX2RyYXdpbmcgPSBmYWxzZTtcblxuICAgIGN0eC5yZXN0b3JlKCk7XG4gIH1cblxufSk7XG4iLCJ2YXIgRU5EID0ge1xuICBtb3VzZWRvd246ICAgICAnbW91c2V1cCcsXG4gIHRvdWNoc3RhcnQ6ICAgICd0b3VjaGVuZCcsXG4gIHBvaW50ZXJkb3duOiAgICd0b3VjaGVuZCcsXG4gIE1TUG9pbnRlckRvd246ICd0b3VjaGVuZCdcbn07XG5cbnZhciBNT1ZFID0ge1xuICBtb3VzZWRvd246ICAgICAnbW91c2Vtb3ZlJyxcbiAgdG91Y2hzdGFydDogICAgJ3RvdWNobW92ZScsXG4gIHBvaW50ZXJkb3duOiAgICd0b3VjaG1vdmUnLFxuICBNU1BvaW50ZXJEb3duOiAndG91Y2htb3ZlJ1xufTtcblxuZnVuY3Rpb24gZGlzdGFuY2UoYSwgYikge1xuICB2YXIgZHggPSBhLnggLSBiLngsIGR5ID0gYS55IC0gYi55O1xuICByZXR1cm4gTWF0aC5zcXJ0KGR4ICogZHggKyBkeSAqIGR5KTtcbn1cblxuLyoqXG4gKiBEcmFnIGhhbmRsZXJcbiAqIEBjbGFzcyBMLlBhdGguRHJhZ1xuICogQGV4dGVuZHMge0wuSGFuZGxlcn1cbiAqL1xuTC5IYW5kbGVyLlBhdGhEcmFnID0gTC5IYW5kbGVyLmV4dGVuZCggLyoqIEBsZW5kcyAgTC5QYXRoLkRyYWcucHJvdG90eXBlICovIHtcblxuICBzdGF0aWNzOiB7XG4gICAgRFJBR0dJTkdfQ0xTOiAnbGVhZmxldC1wYXRoLWRyYWdnYWJsZScsXG4gIH0sXG5cblxuICAvKipcbiAgICogQHBhcmFtICB7TC5QYXRofSBwYXRoXG4gICAqIEBjb25zdHJ1Y3RvclxuICAgKi9cbiAgaW5pdGlhbGl6ZTogZnVuY3Rpb24ocGF0aCkge1xuXG4gICAgLyoqXG4gICAgICogQHR5cGUge0wuUGF0aH1cbiAgICAgKi9cbiAgICB0aGlzLl9wYXRoID0gcGF0aDtcblxuICAgIC8qKlxuICAgICAqIEB0eXBlIHtBcnJheS48TnVtYmVyPn1cbiAgICAgKi9cbiAgICB0aGlzLl9tYXRyaXggPSBudWxsO1xuXG4gICAgLyoqXG4gICAgICogQHR5cGUge0wuUG9pbnR9XG4gICAgICovXG4gICAgdGhpcy5fc3RhcnRQb2ludCA9IG51bGw7XG5cbiAgICAvKipcbiAgICAgKiBAdHlwZSB7TC5Qb2ludH1cbiAgICAgKi9cbiAgICB0aGlzLl9kcmFnU3RhcnRQb2ludCA9IG51bGw7XG5cbiAgICAvKipcbiAgICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICB0aGlzLl9tYXBEcmFnZ2luZ1dhc0VuYWJsZWQgPSBmYWxzZTtcblxuICB9LFxuXG4gIC8qKlxuICAgKiBFbmFibGUgZHJhZ2dpbmdcbiAgICovXG4gIGFkZEhvb2tzOiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl9wYXRoLm9uKCdtb3VzZWRvd24nLCB0aGlzLl9vbkRyYWdTdGFydCwgdGhpcyk7XG5cbiAgICB0aGlzLl9wYXRoLm9wdGlvbnMuY2xhc3NOYW1lID0gdGhpcy5fcGF0aC5vcHRpb25zLmNsYXNzTmFtZSA/XG4gICAgICAgICh0aGlzLl9wYXRoLm9wdGlvbnMuY2xhc3NOYW1lICsgJyAnICsgTC5IYW5kbGVyLlBhdGhEcmFnLkRSQUdHSU5HX0NMUykgOlxuICAgICAgICAgTC5IYW5kbGVyLlBhdGhEcmFnLkRSQUdHSU5HX0NMUztcblxuICAgIGlmICh0aGlzLl9wYXRoLl9wYXRoKSB7XG4gICAgICBMLkRvbVV0aWwuYWRkQ2xhc3ModGhpcy5fcGF0aC5fcGF0aCwgTC5IYW5kbGVyLlBhdGhEcmFnLkRSQUdHSU5HX0NMUyk7XG4gICAgfVxuICB9LFxuXG4gIC8qKlxuICAgKiBEaXNhYmxlIGRyYWdnaW5nXG4gICAqL1xuICByZW1vdmVIb29rczogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5fcGF0aC5vZmYoJ21vdXNlZG93bicsIHRoaXMuX29uRHJhZ1N0YXJ0LCB0aGlzKTtcblxuICAgIHRoaXMuX3BhdGgub3B0aW9ucy5jbGFzc05hbWUgPSB0aGlzLl9wYXRoLm9wdGlvbnMuY2xhc3NOYW1lXG4gICAgICAucmVwbGFjZShuZXcgUmVnRXhwKCdcXFxccysnICsgTC5IYW5kbGVyLlBhdGhEcmFnLkRSQUdHSU5HX0NMUyksICcnKTtcbiAgICBpZiAodGhpcy5fcGF0aC5fcGF0aCkge1xuICAgICAgTC5Eb21VdGlsLnJlbW92ZUNsYXNzKHRoaXMuX3BhdGguX3BhdGgsIEwuSGFuZGxlci5QYXRoRHJhZy5EUkFHR0lOR19DTFMpO1xuICAgIH1cbiAgfSxcblxuICAvKipcbiAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICovXG4gIG1vdmVkOiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy5fcGF0aC5fZHJhZ01vdmVkO1xuICB9LFxuXG4gIC8qKlxuICAgKiBTdGFydCBkcmFnXG4gICAqIEBwYXJhbSAge0wuTW91c2VFdmVudH0gZXZ0XG4gICAqL1xuICBfb25EcmFnU3RhcnQ6IGZ1bmN0aW9uKGV2dCkge1xuICAgIHZhciBldmVudFR5cGUgPSBldnQub3JpZ2luYWxFdmVudC5fc2ltdWxhdGVkID8gJ3RvdWNoc3RhcnQnIDogZXZ0Lm9yaWdpbmFsRXZlbnQudHlwZTtcblxuICAgIHRoaXMuX21hcERyYWdnaW5nV2FzRW5hYmxlZCA9IGZhbHNlO1xuICAgIHRoaXMuX3N0YXJ0UG9pbnQgPSBldnQuY29udGFpbmVyUG9pbnQuY2xvbmUoKTtcbiAgICB0aGlzLl9kcmFnU3RhcnRQb2ludCA9IGV2dC5jb250YWluZXJQb2ludC5jbG9uZSgpO1xuICAgIHRoaXMuX21hdHJpeCA9IFsxLCAwLCAwLCAxLCAwLCAwXTtcbiAgICBMLkRvbUV2ZW50LnN0b3AoZXZ0Lm9yaWdpbmFsRXZlbnQpO1xuXG4gICAgTC5Eb21VdGls