@sfgrp/svg-detailer
Version:
A dependency free javascript library for annotating images, with results exportable as SVG elements.
1,303 lines • 82.6 kB
JavaScript
var st = Object.defineProperty;
var it = (s, t, i) => t in s ? st(s, t, { enumerable: !0, configurable: !0, writable: !0, value: i }) : s[t] = i;
var D = (s, t, i) => (it(s, typeof t != "symbol" ? t + "" : t, i), i);
const S = {
ARROWS_SPECS: "arrowspecs",
COLOR: "colorselect",
FONT_SIZE: "fontsize",
JSON: "json",
LOCK: "lock",
MODE: "mode",
NEWLINE: "newline",
RESET: "reset",
UNLOCK: "unlock",
ZOOM: "zoom",
ZOOM_IN: "zoomin",
ZOOM_OUT: "zoomout"
}, a = {
ARROW: "arrow",
CIRCLE: "circle",
CLEAR: "clear",
CUBIC: "cubic",
DRAW: "draw",
ELLIPSE: "ellipse",
LINE: "line",
MOVE: "move",
POLYGON: "polygon",
POLYLINE: "polyline",
QUADRATIC: "quadratic",
RECTANGLE: "rect",
TEXT: "text",
ERASER: "eraser"
}, C = {
ALT: "Alt",
ARROW_DOWN: "ArrowDown",
ARROW_LEFT: "ArrowLeft",
ARROW_RIGHT: "ArrowRigt",
ARROW_UP: "ArrowUp",
BACKSPACE: "Backspace",
CAPS_LOCK: "CapsLock",
CONTROL: "Control",
DELETE: "Delete",
ENTER: "Enter",
ESC: "Escape",
META_LEFT: "MetaLeft",
META_RIGHT: "MetaRight",
SHIFT_LEFT: "ShiftLeft",
SHIFT_RIGHT: "ShiftRight",
SPACE: "Space",
TAB: "Tab",
B: "KeyB",
T: "KeyT"
}, rt = {
61: "=",
106: "*",
107: "+",
109: "-",
110: ".",
111: "/",
173: "-",
186: ";",
187: "=",
188: ",",
189: "-",
190: ".",
191: "/",
192: "`",
219: "[",
220: "\\",
221: "]",
222: "'"
}, w = {
"`": "~",
1: "!",
2: "@",
3: "#",
4: "$",
5: "%",
6: "^",
7: "&",
8: "*",
9: "(",
0: ")",
"-": "_",
"=": "+",
";": ":",
"'": '"',
"[": "{",
"]": "}",
",": "<",
".": ">",
"/": "?",
"\\": "|"
}, b = {
CIRCLE: "circle",
CUBIC: "cubic",
ELLIPSE: "ellipse",
GROUP: "g",
IMAGE: "image",
LINE: "line",
PATH: "path",
POLYGON: "polygon",
POLYLINE: "polyline",
QUADRATIC: "quadratic",
RECT: "rect",
SVG: "svg",
TEXT: "text"
};
function P(s, t = {}) {
const i = document.createElement(s);
return Object.entries(t).forEach(([e, r]) => {
i.setAttribute(e, r);
}), i;
}
function v({
label: s,
attr: t = {},
event: i = {}
}) {
const e = Object.entries(i), r = P("input", {
type: "text",
...t
});
if (e.forEach(([n, u]) => {
r.addEventListener(n, u);
}), s) {
const n = P("label");
return n.innerHTML = s, n.appendChild(r), n;
} else
return r;
}
function nt(s) {
const t = P("span", { innerHTML: "Arrowhead: " }), i = v({ label: "Close", attr: { type: "checkbox" }, event: { change: (u) => s.apiArrowClosed(u.target.value) } }), e = v({ label: "Fixed", attr: { type: "checkbox" }, event: { change: (u) => s.apiArrowFixed(u.target.value) } }), r = v({
label: "Length",
attr: {
type: "number",
value: 50,
style: "width: 4em"
},
event: {
change: (u) => s.configuration.arrowheadLength = u.target.value
}
}), n = v({
label: "Percent",
attr: {
type: "number",
value: 10,
min: 5,
step: 1,
max: 30,
style: "width: 4em"
},
event: {
change: (u) => s.configuration.arrowPercent = u.target.value
}
});
return t.innerHTML = "Arrowhead: ", t.appendChild(i), t.appendChild(e), t.appendChild(r), t.appendChild(n), t;
}
function at(s) {
return v({
label: "Select color: ",
attr: {
type: "color",
value: "#000000"
},
event: {
change: (i) => {
s.apiStroke(i.target.value);
}
}
});
}
function ut(s) {
return v({
label: " Font Size: ",
attr: {
type: "number",
min: 5,
step: 5,
max: 300,
style: "width: 4em",
value: s.configuration.fontSize
},
event: {
input: (i) => {
s.configuration.fontSize = i.target.value;
}
}
});
}
function ot(s) {
const t = P("span"), i = P("textarea", { rows: 5 }), e = v({
attr: {
type: "button",
value: "Extract SVG"
},
event: {
click: () => i.innerHTML = s.apiShowSVG(!0)
}
}), r = v({
attr: {
type: "button",
value: "Plain SVG"
},
event: {
click: () => i.innerHTML = s.apiShowSVG(!1)
}
}), n = v({
attr: {
type: "button",
value: "Bare SVG"
},
event: {
click: () => i.innerHTML = s.apiBareSVG()
}
}), u = v({
attr: {
type: "button",
value: "JSON SVG"
},
event: {
click: () => i.innerHTML = JSON.stringify(s.apiJsonSVG())
}
});
return t.appendChild(e), t.appendChild(r), t.appendChild(n), t.appendChild(u), t.appendChild(P("br")), t.appendChild(i), t;
}
function lt(s) {
const { containerElement: t } = s;
if (t.attributes["data-buttons"]) {
const i = JSON.parse(
t.attributes["data-buttons"].value
).buttons, e = P("div");
t.parentElement.appendChild(e), i.forEach((r) => {
const n = r.function;
let u;
switch (n) {
case a.CLEAR:
case a.POLYGON:
case a.POLYLINE:
case a.LINE:
case a.ARROW:
case a.RECTANGLE:
case a.CIRCLE:
case a.ELLIPSE:
case a.QUADRATIC:
case a.CUBIC:
case a.DRAW:
case a.TEXT:
case a.MOVE:
case a.ERASER:
case S.RESET:
u = v({
attr: {
type: "button",
value: r.value || n.charAt(0).toUpperCase() + n.slice(1)
},
event: {
click: () => {
s.apiSetMode(n);
}
}
});
break;
case S.MODE:
u = P("span", { id: "mode " });
break;
case S.ZOOM:
u = P("span", { id: "zoom" }), u.innerHTML = "Zoom: ----";
break;
case S.ZOOM_IN:
u = v({
attr: {
type: "button",
value: "Zoom IN"
},
event: {
click: (l) => {
l.target.blur(), s.apiZoomIn();
}
}
});
break;
case S.ZOOM_OUT:
u = v({
attr: {
type: "button",
value: "Zoom OUT"
},
event: {
click: () => {
s.apiZoomOut();
}
}
});
break;
case S.FONT_SIZE:
u = ut(s);
break;
case S.NEWLINE:
u = P("br");
break;
case S.COLOR:
u = at(s);
break;
case S.ARROWS_SPECS:
u = nt(s);
break;
case S.JSON:
u = ot(s);
break;
}
u && e.appendChild(u);
});
}
}
class ht {
constructor() {
D(this, "events", {});
}
on(t, i) {
return typeof this.events[t] != "object" && (this.events[t] = []), this.events[t].push(i), () => this.removeListener(t, i);
}
removeListener(t, i) {
if (typeof this.events[t] != "object")
return;
const e = this.events[t].indexOf(i);
e > -1 && this.events[t].splice(e, 1);
}
removeAllListeners() {
Object.keys(this.events).forEach(
(t) => this.events[t].splice(0, this.events[t].length)
);
}
emit(t, ...i) {
typeof this.events[t] == "object" && [...this.events[t]].forEach((e) => e.apply(this, i));
}
once(t, i) {
const e = this.on(t, (...r) => {
e(), i.apply(this, r);
});
return e;
}
}
function ct(s, { stroke: t, strokeWidth: i, fill: e, fillOpacity: r, strokeOpacity: n, strokeLinecap: u }) {
const l = document.createElementNS("http://www.w3.org/2000/svg", s);
return l.setAttributeNS(null, "stroke", t), l.setAttributeNS(null, "stroke-width", i), l.setAttributeNS(null, "stroke-opacity", n), l.setAttributeNS(null, "fill", e), l.setAttributeNS(null, "fill-opacity", r), l.setAttributeNS(null, "stroke-linecap", u), l;
}
function dt(s) {
switch (s) {
case b.POLYLINE:
return {
points: 1
};
case b.POLYGON:
return {
points: 1
};
case b.RECT:
return {
x: 0,
y: 0,
width: 1,
height: 1
};
case b.LINE:
return {
x1: 0,
y1: 0,
x2: 1,
y2: 1
};
case b.CIRCLE:
return {
cx: 0,
cy: 0,
r: 1
};
case b.ELLIPSE:
return {
cx: 0,
cy: 0,
rx: 1,
ry: 1
};
case b.PATH:
return {
x1: 0,
y1: 0,
xc1: 1,
yc1: 1,
xc2: 1,
yc2: 1,
x2: 0,
y2: 0
};
case b.TEXT:
return {
x: 0,
y: 0
};
}
}
const pt = /Mac/.test(navigator.platform);
function U({ x: s, y: t, mode: i, attributes: e }) {
const r = document.createElementNS("http://www.w3.org/2000/svg", b.GROUP), n = ct(b.LINE, e);
return r.setAttributeNS(null, "class", i), n.setAttributeNS(null, "x1", s.toFixed(4)), n.setAttributeNS(null, "y1", t.toFixed(4)), n.setAttributeNS(null, "x2", s.toFixed(4)), n.setAttributeNS(null, "y2", t.toFixed(4)), r.appendChild(n), {
group: r,
element: n
};
}
class d extends ht {
constructor(t, i = {}) {
super(), this.containerElement = t, this.configuration = {
arrowClosed: !1,
arrowFixed: !1,
arrowPercent: 10,
// default arrow head size 10 percent of arrow length in pixels
arrowheadLength: 50,
fontSize: 50,
fontFamily: "Verdana",
stroke: "#000000",
strokeWidth: 1,
strokeOpacity: 0.9,
fill: "",
fillOpacity: 0,
strokeLinecap: "round",
baseZoom: 0,
// calculated from svg and image attributes
maxZoom: 4,
zoomDelta: 0.02,
// this can be altered to discriminate legacy firefox dommousescroll event
debugLog: !1,
...i
}, this.state = {
mousePosition: {
x: 0,
y: 0
},
mousePositionStart: {
x: 0,
y: 0
},
xC: 0,
yC: 0,
zoom: 0,
currentKey: void 0,
currentGroup: void 0,
currentElement: void 0,
currentSVGPoints: [],
currentBubble: void 0,
bubbleRadius: void 0,
baseBubbleRadius: 6,
waitElement: !1,
svgInProgress: !1,
svgLayer: void 0,
svgImage: void 0,
cWidth: 0,
cHeight: 0,
groupIdCount: 0,
capsLock: !1,
text: "_",
cursorMode: a.MOVE
}, this.state.cWidth = parseInt(
i.width || t.attributes["data-width"].value
), this.state.cHeight = parseInt(
i.height || t.attributes["data-height"].value
), this.handleMouseEnterFunction = this.mouseEnterFunction.bind(this), this.handleMouseLeaveFunction = this.mouseLeaveFunction.bind(this), this.handleMouseClickFunction = this.mouseClickFunction.bind(this), this.handleKeyHandler = this.keyHandler.bind(this), this.handleKeyUpHandler = this.keyUpHandler.bind(this);
const e = document.createElementNS(
"http://www.w3.org/2000/svg",
"svg"
);
e.setAttributeNS(null, "id", "svgLayer"), e.setAttribute("xmlns", "http://www.w3.org/2000/svg"), e.setAttribute("xmlns:xlink", "http://www.w3.org/1999/xlink"), e.setAttributeNS(null, "version", "1.1"), e.setAttributeNS(null, "style", "position: inherit;"), e.setAttributeNS(null, "width", this.state.cWidth), e.setAttributeNS(null, "height", this.state.cHeight), this.containerElement.appendChild(e), this.state.svgLayer = e;
let r = document.createElementNS(
"http://www.w3.org/2000/svg",
b.GROUP
);
this.xlt = r, e.appendChild(r), this.state.currentSVGPoints = [];
const n = i.imageSrc || t.attributes["data-image"].value;
if (!n)
throw "Missing image src";
this.loadImage(n), i.svg && this.apiLoadSVG(i.svg), lt(this), document.addEventListener("keydown", this.handleKeyHandler), document.addEventListener("keyup", this.handleKeyUpHandler), this.updateCursorMode(a.MOVE), this.renderFunction = this.updateSvgByElement, this.touchSupported = "ontouchstart" in document.documentElement, this.containerID = t, this.state.mousePosition = { x: 0, y: 0 }, this.touchSupported || this.state.svgLayer.addEventListener(
"dblclick",
this.doubleClickHandler.bind(this)
), this.state.svgLayer.addEventListener(
"mousedown",
this.onSvgMouseDown.bind(this)
), this.state.svgLayer.addEventListener(
"mouseup",
this.onSvgMouseUp.bind(this)
), this.state.svgLayer.addEventListener(
"mousemove",
this.onSvgMouseMove.bind(this)
);
}
loadImage(t) {
this.state.svgImage = new Image(), this.state.svgImage.src = t, this.state.svgImage.onload = () => {
this.state.xC = 0, this.state.yC = 0;
var i = this.state.cWidth / this.state.cHeight, e = this.state.svgImage.width / this.state.svgImage.height;
(i >= 1 && e >= 1 || i <= 1 && e <= 1) && e <= i || e <= 1 && i >= 1 ? this.configuration.baseZoom = this.state.svgLayer.height.baseVal.value / this.state.svgImage.height : this.configuration.baseZoom = this.state.svgLayer.width.baseVal.value / this.state.svgImage.width, this.state.bubbleRadius = (this.state.baseBubbleRadius / this.configuration.baseZoom).toString(), this.state.mousePosition.x = this.configuration.baseZoom * this.state.svgImage.width / 2, this.state.mousePosition.y = this.configuration.baseZoom * this.state.svgImage.height / 2, this.xlt.setAttributeNS(null, "id", "xlt"), this.xlt.setAttributeNS(
null,
"transform",
"translate(0,0) scale(" + parseFloat(this.configuration.baseZoom) + ")"
);
const r = document.createElementNS(
"http://www.w3.org/2000/svg",
b.IMAGE
);
r.setAttributeNS(null, "id", "xltImage"), r.setAttributeNS(null, "x", "0"), r.setAttributeNS(null, "y", "0"), r.setAttributeNS(
null,
"width",
this.state.svgImage.width.toString()
), r.setAttributeNS(
null,
"height",
this.state.svgImage.height.toString()
), r.setAttributeNS(null, "preserveAspectRatio", "none"), r.setAttributeNS(
"http://www.w3.org/1999/xlink",
"href",
this.state.svgImage.src
), this.zoom_trans(0, 0, this.configuration.baseZoom), this.xltImage = r, this.xlt.prepend(r);
};
}
get currentMouseX() {
return (this.state.mousePosition.x - this.state.xC) / this.state.zoom;
}
get currentMouseY() {
return (this.state.mousePosition.y - this.state.yC) / this.state.zoom;
}
setCursorMode(t) {
this.state.cursorMode = t, this.emit("changemode", {
mode: this.state.cursorMode
});
}
updateCursorMode(t) {
this.state.currentElement && (this.checkLeftoverElement(), this.clearEditElement(this.state.currentGroup)), this.setCursorMode(t), this.state.cursorMode !== a.MOVE && (this.state.cursorMode, a.TEXT, t == a.CLEAR && (this.clearLastGroup(), this.state.cursorMode = a.MOVE), t == S.RESET && (this.setZoom(this.configuration.baseZoom), this.state.cursorMode = a.MOVE), this.state.waitElement = !0), this.state.svgInProgress = !1;
}
exitEditPoint(t) {
for (; t.childElementCount > 1 && t.lastChild.tagName == b.GROUP; )
t.lastChild.remove();
this.state.svgInProgress = !1, this.state.currentBubble = null, this.updateCursorMode(a.MOVE), this.setElementMouseEnterLeave(t);
}
getIDcount() {
return this.state.groupIdCount += 1, this.state.groupIdCount;
}
zoom_trans(t, i, e) {
const r = `translate(${t.toString()}, ${i.toString()}) scale(${e.toString()})`;
this.state.zoom = e, this.state.xC = t, this.state.yC = i, this.xlt.attributes.transform.value = r;
}
zoomIn(t) {
const { zoomDelta: i, maxZoom: e } = this.configuration;
if (this.state.zoom < e) {
let r = this.state.zoom * (1 + (t || i));
r > e && (r = e), this.setZoom(r);
}
}
zoomOut(t) {
const { baseZoom: i, zoomDelta: e } = this.configuration;
if (this.state.zoom > i / 3) {
const r = this.state.zoom / (1 + (t || e));
this.setZoom(r);
}
}
setZoom(t) {
this.state.xC = this.state.mousePosition.x - (this.state.mousePosition.x - this.state.xC) * t / this.state.zoom, this.state.yC = this.state.mousePosition.y - (this.state.mousePosition.y - this.state.yC) * t / this.state.zoom, this.zoom_trans(this.state.xC, this.state.yC, t), this.state.zoom = t, this.state.bubbleRadius = (this.state.baseBubbleRadius / this.state.zoom).toString();
}
setStroke(t) {
this.configuration.stroke = t;
}
apiFontSize(t) {
x(t) && (this.configuration.fontSize = t);
}
apiFontFamily(t) {
this.configuration.fontFamily = t;
}
apiArrowClosed(t) {
this.arrowClosed = t;
}
apiArrowFixed(t) {
this.arrowFixed = t;
}
apiArrowLength(t) {
x(t) && (this.configuration.arrowheadLength = t);
}
apiArrowPercent(t) {
x(t) && (this.configuration.arrowPercent = t);
}
apiStroke(t) {
this.setStroke(t);
}
apiClearAll() {
this.state.groupIdCount = 0, [...this.xlt.querySelectorAll("g")].forEach((i) => i.remove());
}
apiStrokeWidth(t) {
x(t) && (this.configuration.strokeWidth = t);
}
apiStrokeOpacity(t) {
t >= 0 && t <= 1 && (this.configuration.strokeOpacity = t);
}
apiStrokeLinecap(t) {
this.configuration.strokeLinecap = t;
}
apiFill(t) {
this.configuration.fill = t;
}
apiFillOpacity(t) {
t >= 0 && t <= 1 && (this.configuration.fillOpacity = t.toString());
}
apiZoomIn(t) {
this.zoomIn(t);
}
apiZoomOut(t) {
this.zoomOut(t);
}
apiSetZoom(t) {
this.setZoom(t);
}
apiDeleteLast() {
this.clearLastGroup();
}
apiDeleteHover(t) {
t && this.clearThisGroup(t);
}
apiShowSVG(t) {
return K(t, { svgLayer: this.state.svgLayer }).outerHTML;
}
apiBareSVG(t = !0) {
return Ct(t, { svgLayer: this.state.svgLayer }).outerHTML;
}
apiJsonSVG(t) {
const i = K(!1, {
svgLayer: this.state.svgLayer,
...t
}).firstChild;
return i.removeAttribute("id"), i.removeAttribute("transform"), {
data: {
type: "svg",
attributes: i.outerHTML
}
};
}
apiRemoveGroup(t) {
[...this.xlt.querySelectorAll(`#${t}`)].forEach((e) => this.removeShape(e));
}
apiRemoveLayer(t) {
[...this.xlt.querySelectorAll(`[layer-id="${t}"]`)].forEach((e) => this.removeShape(e));
}
removeShape(t) {
t.remove();
}
lockShape(t) {
const i = t.querySelector(".bubbles");
this.removeGroupEvents(t), i == null || i.remove(), t.setAttribute("locked", "true");
}
unlockShape(t) {
this.setElementMouseEnterLeave(t), t.matches(":hover") && this.handleMouseEnterFunction({ target: t }), t.setAttribute("locked", "false");
}
unlockLayer(t) {
[
...this.xlt.querySelectorAll(`[layer-id="${t}"][locked="true"]`)
].forEach((e) => this.unlockShape(e));
}
unlockGroup(t) {
[
...this.xlt.querySelectorAll(`#${t}[locked="true"]`)
].forEach((e) => this.unlockShape(e));
}
lockLayer(t) {
[
...this.xlt.querySelectorAll(`[layer-id="${t}"][locked="false"]`)
].forEach((e) => this.lockShape(e));
}
lockGroup(t) {
[
...this.xlt.querySelectorAll(`#${t}[locked="false"]`)
].forEach((e) => this.lockShape(e));
}
apiLockLayer(t) {
t && this.lockLayer(t);
}
apiLockGroup(t) {
t && this.lockGroup(t);
}
apiUnlockGroup(t) {
t && this.unlockGroup(t);
}
apiUnlockLayer(t) {
t && this.unlockLayer(t);
}
apiLoadSVG(t, {
replace: i = !1,
layerId: e = Math.random().toString(36).substring(2, 8),
lock: r = !0,
shapeClass: n = void 0,
fill: u = void 0
} = {}) {
const l = document.createElementNS(
"http://www.w3.org/2000/svg",
b.SVG
);
l.innerHTML = t;
const o = [...l.querySelector(b.GROUP).querySelectorAll(b.GROUP)];
return i && this.xlt.querySelectorAll(b.GROUP).forEach((f) => f.remove()), o.forEach((h) => {
const f = h.firstChild;
h.setAttribute("id", `g${this.getIDcount()}`), h.setAttribute("layer-id", e), h.setAttribute("locked", r), n && f.classList.add(n), u && (f.setAttribute("fill", u), f.setAttribute("fill-opacity", 1)), r || this.setElementMouseEnterLeave(h), this.xlt.appendChild(h);
}), {
layerId: e
};
}
}
function _(s, t) {
s.setAttributeNS(
null,
"points",
t[0][0].toFixed(4).toString() + "," + t[0][1].toFixed(4).toString() + " " + t[0][0].toFixed(4).toString() + "," + t[0][1].toFixed(4).toString() + " "
);
}
d.prototype.onSvgMouseDown = function() {
var i;
if (this.updateMousePosition(event), this.state.svgInProgress && this.state.svgInProgress !== this.state.cursorMode) {
this.state.svgInProgress !== "SHIFT" && (this.state.svgInProgress = this.state.cursorMode);
return;
}
if (((i = this.state.currentGroup) == null ? void 0 : i.childElementCount) > 1 && this.state.cursorMode != a.TEXT)
return this.clearEditElement(this.state.currentGroup), !1;
const [s, t] = [this.currentMouseX, this.currentMouseY];
if (this.state.currentSVGPoints[0] = [s, t], this.state.cursorMode == a.POLYGON)
if (this.state.svgInProgress == !1) {
this.state.currentSVGPoints[0] = [this.currentMouseX, this.currentMouseY];
let e = document.createElementNS("http://www.w3.org/2000/svg", "g"), r = "g" + this.getIDcount().toString();
e.setAttributeNS(null, "id", r), e.setAttributeNS(null, "class", this.state.cursorMode), this.state.currentGroup = e, this.xlt.appendChild(e);
let n = E({
tag: a.POLYLINE,
attributes: this.getSVGAttributes()
});
e.appendChild(n), this.state.currentElement = e.children[0], _(n, this.state.currentSVGPoints), this.state.svgInProgress = this.state.cursorMode;
} else {
this.updateMousePosition(event);
let e = this.state.currentElement.attributes.points.value, r = this.currentMouseX.toFixed(4).toString() + "," + this.currentMouseY.toFixed(4).toString() + " ";
this.state.currentElement.attributes.points.value = e.concat(r);
}
if (this.state.cursorMode == a.POLYLINE)
if (this.state.svgInProgress == !1) {
this.state.currentSVGPoints[0] = [this.currentMouseX, this.currentMouseY];
let e = document.createElementNS("http://www.w3.org/2000/svg", "g");
this.state.currentGroup = e;
let r = "g" + this.getIDcount().toString();
e.setAttributeNS(null, "id", r), e.setAttributeNS(null, "class", this.state.cursorMode), this.xlt.appendChild(e);
let n = E({
tag: a.POLYLINE,
attributes: this.getSVGAttributes()
});
e.appendChild(n), this.state.currentElement = e.children[0], n.setAttributeNS(null, "stroke-linecap", "round"), _(n, this.state.currentSVGPoints), this.state.svgInProgress = this.state.cursorMode;
} else {
this.updateMousePosition(event);
let e = this.state.currentElement.attributes.points.value, r = this.currentMouseX.toFixed(4).toString() + "," + this.currentMouseY.toFixed(4).toString() + " ";
this.state.currentElement.attributes.points.value = e.concat(r);
}
if (this.state.cursorMode == a.RECTANGLE && this.state.svgInProgress == !1) {
this.state.currentSVGPoints[0] = [this.currentMouseX, this.currentMouseY], this.state.mousePositionStart.x = this.currentMouseX, this.state.mousePositionStart.y = this.currentMouseY;
let e = document.createElementNS("http://www.w3.org/2000/svg", "g"), r = "g" + this.getIDcount().toString();
e.setAttributeNS(null, "id", r), e.setAttributeNS(null, "class", this.state.cursorMode), this.xlt.appendChild(e);
let n = E({
tag: b.RECT,
attributes: this.getSVGAttributes()
});
e.appendChild(n), this.state.currentGroup = e, this.state.currentElement = e.children[0], n.setAttributeNS(
null,
"x",
this.state.currentSVGPoints[0][0].toFixed(4)
), n.setAttributeNS(
null,
"y",
this.state.currentSVGPoints[0][1].toFixed(4)
), n.setAttributeNS(null, "width", 1), n.setAttributeNS(null, "height", 1), this.state.svgInProgress = this.state.cursorMode;
}
if (this.state.cursorMode == a.LINE)
if (this.state.svgInProgress == !1) {
this.state.svgInProgress = this.state.cursorMode;
const { element: e, group: r } = U({
x: s,
y: t,
mode: this.state.cursorMode,
attributes: this.configuration
});
r.setAttributeNS(null, "id", "g" + this.getIDcount().toString()), this.xlt.appendChild(r), this.state.currentElement = e, this.state.currentGroup = r;
} else
this.state.svgInProgress = !1, this.setElementMouseEnterLeave(this.state.currentElement);
if (this.state.cursorMode == a.ARROW)
if (this.state.svgInProgress == !1) {
const { element: e, group: r } = U({
x: s,
y: t,
mode: this.state.cursorMode,
attributes: this.configuration
});
this.state.svgInProgress = this.state.cursorMode, r.setAttributeNS(null, "id", "g" + this.getIDcount().toString()), this.xlt.appendChild(r), this.state.currentElement = e, this.state.currentGroup = r;
} else
this.state.svgInProgress = !1, this.setElementMouseEnterLeave(this.state.currentElement);
if (this.state.cursorMode == a.CIRCLE && this.state.svgInProgress == !1) {
this.state.currentGroup != null && this.clearEditElement(this.state.currentGroup), this.state.currentSVGPoints[0] = [this.currentMouseX, this.currentMouseY];
let e = document.createElementNS("http://www.w3.org/2000/svg", "g"), r = "g" + this.getIDcount().toString();
e.setAttributeNS(null, "id", r), e.setAttributeNS(null, "class", this.state.cursorMode), this.xlt.appendChild(e);
let n = E({
tag: b.CIRCLE,
attributes: this.getSVGAttributes()
});
e.appendChild(n), this.state.currentGroup = e, this.state.currentElement = e.children[0], n.setAttributeNS(
null,
"cx",
this.state.currentSVGPoints[0][0].toFixed(4)
), n.setAttributeNS(
null,
"cy",
this.state.currentSVGPoints[0][1].toFixed(4)
), n.setAttributeNS(null, "r", 1), this.state.svgInProgress = this.state.cursorMode;
}
if (this.state.cursorMode == a.ELLIPSE)
if (this.state.svgInProgress == !1) {
this.state.currentSVGPoints[0] = [this.currentMouseX, this.currentMouseY];
let e = document.createElementNS("http://www.w3.org/2000/svg", "g");
this.state.currentGroup = e;
let r = "g" + this.getIDcount().toString();
e.setAttributeNS(null, "id", r), e.setAttributeNS(null, "class", this.state.cursorMode), this.xlt.appendChild(e);
let n = E({
tag: a.ELLIPSE,
attributes: this.getSVGAttributes()
});
e.appendChild(n), this.state.currentElement = e.children[0], n.setAttributeNS(
null,
"cx",
this.state.currentSVGPoints[0][0].toFixed(4)
), n.setAttributeNS(
null,
"cy",
this.state.currentSVGPoints[0][1].toFixed(4)
), n.setAttributeNS(null, "rx", 1), n.setAttributeNS(null, "ry", 1), this.state.svgInProgress = this.state.cursorMode;
} else
this.state.svgInProgress = !1, this.setElementMouseEnterLeave(this.state.currentElement);
if (this.state.cursorMode == a.DRAW)
if (this.state.svgInProgress == !1) {
this.state.currentSVGPoints[0] = [this.currentMouseX, this.currentMouseY];
let e = document.createElementNS("http://www.w3.org/2000/svg", "g");
this.state.currentGroup = e;
let r = "g" + this.getIDcount().toString();
e.setAttributeNS(null, "id", r), e.setAttributeNS(null, "class", this.state.cursorMode), this.xlt.appendChild(e);
let n = E({
tag: a.POLYLINE,
attributes: this.getSVGAttributes()
});
e.appendChild(n), this.state.currentElement = e.children[0], n.setAttributeNS(
null,
"points",
this.state.currentSVGPoints[0][0].toFixed(4).toString() + "," + this.state.currentSVGPoints[0][1].toFixed(4).toString() + " "
), this.state.svgInProgress = this.state.cursorMode;
} else
this.state.svgInProgress = !1, bt(this.state.currentElement, {
strokeWidth: this.configuration.strokeWidth
});
if (this.state.cursorMode == a.CUBIC || this.state.cursorMode == a.QUADRATIC)
if (this.state.svgInProgress == !1) {
this.state.currentSVGPoints[0] = [this.currentMouseX, this.currentMouseY];
let e = document.createElementNS("http://www.w3.org/2000/svg", "g");
this.state.currentGroup = e;
let r = "g" + this.getIDcount().toString();
e.setAttributeNS(null, "id", r), e.setAttributeNS(null, "class", this.state.cursorMode), this.xlt.appendChild(e);
let n = E({
tag: b.PATH,
attributes: this.getSVGAttributes()
});
e.appendChild(n), this.state.currentElement = e.children[0];
let u = this.state.currentSVGPoints[0][0], l = this.state.currentSVGPoints[0][1];
n.setAttributeNS(
null,
"d",
this.getCurvePath(
u,
l,
u,
l,
u,
l,
u,
l
)
), this.state.svgInProgress = this.state.cursorMode;
} else
this.state.svgInProgress = !1, this.setElementMouseEnterLeave(this.state.currentElement);
if (this.state.cursorMode == a.TEXT) {
let e;
if (this.state.currentElement && this.finishTextGroup(), this.state.svgInProgress == !1) {
this.state.currentSVGPoints[0] = [this.currentMouseX, this.currentMouseY], e = document.createElementNS("http://www.w3.org/2000/svg", "g"), this.state.currentGroup = e;
let r = "g" + this.getIDcount().toString();
e.setAttributeNS(null, "id", r), e.setAttributeNS(null, "class", this.state.cursorMode), this.xlt.appendChild(e);
let n;
n = document.createElementNS("http://www.w3.org/2000/svg", "text"), e.appendChild(n), this.state.currentElement = e.children[0], n.setAttributeNS(null, "stroke", this.configuration.stroke), n.setAttributeNS(null, "stroke-width", "1"), n.setAttributeNS(null, "stroke-opacity", "1.0"), n.setAttributeNS(
null,
"x",
this.state.currentSVGPoints[0][0].toFixed(4)
), n.setAttributeNS(
null,
"y",
this.state.currentSVGPoints[0][1].toFixed(4)
), n.setAttributeNS(
null,
"style",
"font-family: " + this.configuration.fontFamily + "; fill: " + this.configuration.stroke.toString() + ";"
), n.setAttributeNS(null, "font-size", this.configuration.fontSize), n.innerHTML = "_", this.state.svgInProgress = "text";
}
}
return this.state.cursorMode == a.MOVE && (this.state.svgInProgress || (this.state.svgInProgress = this.state.cursorMode)), this.state.waitElement = !1, event.preventDefault() && !1;
};
function I(s, t) {
return parseInt(s) + ", " + parseInt(t);
}
function y(s, t) {
return I(s, t) + " ";
}
d.prototype.getSVGAttributes = function() {
return {
stroke: this.configuration.stroke,
"stroke-width": this.configuration.strokeWidth,
"stroke-opacity": this.configuration.strokeOpacity,
fill: this.configuration.fill,
"fill-opacity": this.configuration.fillOpacity,
"stroke-linecap": this.configuration.strokeLinecap
};
};
d.prototype.getCurvePath = function(s, t, i, e, r, n, u, l) {
return this.state.cursorMode == a.CUBIC ? "M " + I(s, t) + " C " + y(i, e) + y(r, n) + I(u, l) : "M " + I(s, t) + " Q " + y(i, e) + I(u, l);
};
function q(s) {
let t = s.replace(/,/g, "").split(" "), i = 0, e = [];
for (let r = 0; r < t.length; r++)
x(t[r]) && (e[i] = t[r], i++);
return e;
}
function Q(s) {
return y(s[0], s[1]) + " " + y(s[2], s[3]) + " " + y(s[4], s[5]) + " " + y(s[6], s[7]);
}
function E({ tag: s, attributes: t }) {
const i = document.createElementNS("http://www.w3.org/2000/svg", s);
return Object.entries(t).forEach(([e, r]) => {
i.setAttributeNS(null, e, r);
}), i;
}
function bt(s, { strokeWidth: t }) {
return s.setAttributeNS(
null,
"onmouseover",
"this.attributes['stroke-width'].value = '" + 1.5 * t + "';"
), s.setAttributeNS(
null,
"onmouseout",
"this.attributes['stroke-width'].value = " + t + ";"
), s;
}
d.prototype.mouseEnterFunction = function(s) {
var r, n, u;
let t = ((r = this.state.currentGroup) == null ? void 0 : r.id) || "null", i = ((n = this.state.currentElement) == null ? void 0 : n.tagName) || "null", e = ((u = this.state.currentElement) == null ? void 0 : u.parentElement.id) || "null";
m(
this.configuration.debugLog,
"mouseenter eventTarget=" + s.target.id + " thisGroup=" + t + " thisElement=" + i + " parent=" + e + " " + this.state.cursorMode + " "
), this.setEditElement(s.target);
};
d.prototype.mouseLeaveFunction = function(s) {
var r, n, u;
let t = ((r = this.state.currentGroup) == null ? void 0 : r.id) || "null", i = ((n = this.state.currentElement) == null ? void 0 : n.tagName) || "null", e = ((u = this.state.currentElement) == null ? void 0 : u.parentElement.id) || "null";
m(
this.configuration.debugLog,
"mouseleave eventTarget=" + s.target.id + " thisGroup=" + t + " thisElement=" + i + " parent=" + e + " " + this.state.cursorMode + " "
), this.clearEditElement(s.target);
};
d.prototype.removeGroupEvents = function(s) {
s.removeEventListener("mouseenter", this.handleMouseEnterFunction), s.removeEventListener("mouseleave", this.handleMouseLeaveFunction), s.removeEventListener("click", this.handleMouseClickFunction);
};
d.prototype.addGroupEvents = function(s) {
s.addEventListener("mouseenter", this.handleMouseEnterFunction), s.addEventListener("mouseleave", this.handleMouseLeaveFunction), s.addEventListener("click", this.handleMouseClickFunction);
};
d.prototype.setElementMouseEnterLeave = function(s) {
return (s == null || s == null) && (s = null), this.removeGroupEvents(s), this.addGroupEvents(s), s;
};
d.prototype.mouseClickFunction = function(s) {
const t = s.target.parentElement;
switch (this.state.cursorMode) {
case a.ERASER:
this.emit("erase", t), this.removeShape(t);
}
};
d.prototype.setEditElement = function(s) {
if (ft(this.state.currentGroup, {
group: s,
waitElement: this.state.waitElement,
svgInProgress: this.state.svgInProgress
})) {
m(
this.configuration.debugLog,
"Element conflict: " + s.attributes.class.value
);
return;
}
if (m(this.configuration.debugLog, "setEditElement no conflict"), this.state.currentGroup == null) {
let i = "thisGroup is NULL";
this.state.currentElement && (i += ", thisElement = " + this.state.currentElement.toString()), m(
this.configuration.debugLog,
s.attributes.class.value + " " + i
), this.state.currentGroup = s;
}
s.firstChild && (s.firstChild.tagName != b.PATH ? s.attributes.class ? this.state.cursorMode = s.attributes.class.value : this.state.cursorMode = s.firstChild.tagName : (this.state.cursorMode = a.CUBIC, s.firstChild.attributes.d.value.indexOf("C ") == -1 && (this.state.cursorMode = a.QUADRATIC))), this.state.svgInProgress = !1, s.childNodes.length > 1 && s.lastChild.tagName == b.GROUP && this.clearEditElement(s);
const t = this.createBubbleGroup(s);
s.appendChild(t), m(
this.configuration.debugLog,
"setEditElement " + s.id + " " + s.attributes.class.value
);
};
d.prototype.clearEditElement = function(s) {
var i;
let t = ((i = this.state.currentGroup) == null ? void 0 : i.id) || "null";
if (m(
this.configuration.debugLog,
"clearEditElement: svgInProgress=" + this.state.svgInProgress + ", group=" + (s == null ? void 0 : s.id) + ", thisGroup=" + t
), this.state.svgInProgress != "SHIFT") {
if (!s) {
m(
this.configuration.debugLog,
"clearEditElement: group argument null"
);
return;
}
if (this.state.waitElement) {
m(this.configuration.debugLog, "clearEditElement: waitElement");
return;
}
if (this.state.currentGroup && t != s.id) {
m(this.configuration.debugLog, "clearEditElement: group conflict");
return;
}
s.childNodes.length > 1 && (s.lastChild.tagName == a.CIRCLE || s.lastChild.tagName == "g" ? (s.lastChild.remove(), this.state.currentBubble = null, this.state.cursorMode = a.MOVE, this.state.svgInProgress = !1, this.state.currentElement = null, this.state.currentGroup = null) : s.firstChild.tagName == b.TEXT && this.state.svgInProgress == a.TEXT && this.finishTextGroup()), this.setElementMouseEnterLeave(s), this.setCursorMode(a.MOVE), this.state.svgInProgress = !1, this.state.currentElement = null, this.state.currentGroup = null;
}
};
function ft(s, { group: t, waitElement: i, svgInProgress: e, debugLog: r }) {
if (i)
return m(r, "checkElementConflict1: waitElement = " + i), !0;
if (!e)
return m(
r,
"checkElementConflict2: svgInProgress=" + e + "thisGroup=" + t.id
), !1;
if (e == "SHIFT")
return m(
r,
"checkElementConflict3: svgInProgress=" + e + "thisGroup=" + t.id
), s.id != t.id;
if (e != t.firstChild.tagName)
return !0;
if (s != t)
return m(
r,
"checkElementConflict5: svgInProgress=" + e + ", thisGroup=" + s.id + ", group=" + t.id + ", group element=" + t.firstChild.tagName
), !0;
}
d.prototype.setShiftElement = function(s) {
this.state.currentGroup || (this.state.currentGroup = s.parentNode.parentNode), this.state.currentElement = this.state.currentGroup.firstChild, this.state.currentBubble = this.state.currentGroup.children[1].children.shift, this.state.cursorMode = this.state.currentElement.tagName, this.state.currentGroup.attributes.class && (this.state.cursorMode = this.state.currentGroup.attributes.class.value);
let t = this.state.currentGroup.lastChild.childElementCount;
for (let i = t; i > 1; i--)
this.state.currentGroup.lastChild.lastChild.remove();
this.state.currentGroup.removeEventListener(
"mouseenter",
this.handleMouseEnterFunction
), this.state.currentGroup.removeEventListener(
"mouseleave",
this.handleMouseLeaveFunction
), this.state.svgInProgress = "SHIFT", m(
this.configuration.debugLog,
"svgInProgress = SHIFT, this.state.cursorMode = " + this.state.cursorMode
);
};
d.prototype.setSizeElement = function(s, t) {
const i = s.parentNode.parentNode;
if (this.state.currentGroup = i, this.state.currentElement = i.firstChild, this.state.currentBubble = i.lastChild.firstChild, this.state.cursorMode = this.state.currentElement.tagName, this.state.currentElement.tagName === b.RECT && (this.state.mousePositionStart.x = this.state.currentElement.attributes.x.value, this.state.mousePositionStart.y = this.state.currentElement.attributes.y.value), this.state.cursorMode === a.CIRCLE || this.state.cursorMode === a.ELLIPSE) {
const e = i.lastChild.childElementCount;
for (let r = e; r > 0; r--)
i.lastChild.lastChild.remove();
}
this.state.svgInProgress = "SIZE", m(
this.configuration.debugLog,
"svgInProgress = SIZE, this.state.cursorMode = " + this.state.cursorMode + " " + this.state.currentElement.tagName
), i.removeEventListener("mouseenter", this.handleMouseEnterFunction), i.removeEventListener("mouseleave", this.handleMouseLeaveFunction);
};
d.prototype.setPointElement = function(s) {
const t = s.parentNode.parentNode;
this.state.currentBubble = s, this.state.currentGroup = t, this.state.currentElement = t.firstChild, parseInt(s.id) == s.parentNode.childElementCount - 1 && (this.state.currentBubble = s), s.parentNode.lastChild.tagName == b.GROUP && s.parentNode.lastChild.remove(), this.state.currentGroup.attributes.class ? this.state.cursorMode = this.state.currentGroup.attributes.class.value : this.state.cursorMode = this.state.currentElement.tagName, t.removeEventListener("mouseenter", this.handleMouseEnterFunction), t.removeEventListener("mouseleave", this.handleMouseLeaveFunction), this.state.svgInProgress = "POINT";
};
d.prototype.setNewPointElement = function(s) {
const t = s.parentNode.parentNode.parentNode;
this.state.currentBubble = s, this.state.currentGroup = t, this.state.currentElement = t.firstChild, parseInt(s.id) == s.parentNode.childElementCount - 1 && (this.state.currentBubble = s), this.state.cursorMode = this.state.currentElement.tagName, t.removeEventListener("mouseenter", this.handleMouseEnterFunction), t.removeEventListener("mouseleave", this.handleMouseLeaveFunction), this.state.currentElement.attributes.points.value = mt(
this.state.currentElement,
this.state.currentBubble
), this.state.currentBubble.id = (parseInt(this.state.currentBubble.id) + 1).toString(), this.state.svgInProgress = "NEW";
};
function mt(s, t) {
const { cx: i, cy: e } = t.attributes, r = parseInt(t.id), n = i.value + "," + e.value, u = s.attributes.points.value.trim().split(" ");
let l = "";
for (let p = 0; p < u.length; p++)
l += u[p] + " ", p == r && (l += n + " ");
return l;
}
d.prototype.createBubbleForCircle = function(s, { cx: t, cy: i, r: e }) {
return s.setAttributeNS(null, "class", "bubbles"), s.appendChild(this.createShiftBubble(t, i, "shift")), s.appendChild(this.createSizeBubble(e + t, i, "E")), s.appendChild(this.createSizeBubble(t, e + i, "S")), s.appendChild(this.createSizeBubble(t - e, i, "W")), s.appendChild(this.createSizeBubble(t, i - e, "N")), s;
};
d.prototype.createBubbleForEllipse = function(s, { cx: t, cy: i, rx: e, ry: r }) {
return s.appendChild(this.createShiftBubble(t, i, "shift")), s.appendChild(
this.createSizeBubble(t + e * 0.707, i + r * 0.707, "SE")
), s.appendChild(
this.createSizeBubble(t + e * 0.707, i - r * 0.707, "NE")
), s.appendChild(
this.createSizeBubble(t - e * 0.707, i - r * 0.707, "NW")
), s.appendChild(
this.createSizeBubble(t - e * 0.707, i + r * 0.707, "SW")
), s;
};
d.prototype.createBubbleForRectangle = function(s, { x: t, y: i, width: e, height: r }) {
return s.appendChild(this.createShiftBubble(t, i, "shift")), s.appendChild(this.createSizeBubble(t + e, i + r)), s;
};
d.prototype.createBubbleForLine = function(s, { x1: t, y1: i, x2: e, y2: r }) {
return s.appendChild(
this.createShiftBubble((e + t) / 2, (r + i) / 2, "shift")
), s.appendChild(this.createPointBubble(t, i, "x1-y1")), s.appendChild(this.createPointBubble(e, r, "x2-y2")), s;
};
d.prototype.createBubbleForPath = function(s, t) {
let i = t.attributes.d.value, e = i.indexOf("Q ") > 0, r = q(i);
e && (r[6] = r[4], r[7] = r[5], r[4] = r[2], r[5] = r[3]);
let n, u;
return e ? (n = parseFloat(r[0]) + parseFloat(r[2]) + parseFloat(r[6]), u = parseFloat(r[1]) + parseFloat(r[3]) + parseFloat(r[7]), n = (n / 3).toFixed(4), u = (u / 3).toFixed(4)) : (n = parseFloat(r[0]) + parseFloat(r[2]) + parseFloat(r[4]) + parseFloat(r[6]), u = parseFloat(r[1]) + parseFloat(r[3]) + parseFloat(r[5]) + parseFloat(r[7]), n = (n / 4).toFixed(4), u = (u / 4).toFixed(4)), s.appendChild(
gt({
coords: r,
attributes: this.getSVGAttributes()
})
), s.appendChild(this.createShiftBubble(n, u, "shift")), s.appendChild(
W({
x1: r[0],
y1: r[1],
x2: r[2],
y2: r[3],
id: "l1",
attributes: this.getSVGAttributes()
})
), s.appendChild(
W({
x1: r[4],
y1: r[5],
x2: r[6],
y2: r[7],
id: "l2",
attributes: this.getSVGAttributes()
})
), s.appendChild(
this.createCurveBubble(r[0], r[1], "p1")
), s.appendChild(
this.createCurveBubble(r[6], r[7], "p2")
), s.appendChild(
this.createCurveBubble(r[2], r[3], "c1")
), e || s.appendChild(
this.createCurveBubble(r[4], r[5], "c2")
), s;
};
d.prototype.createBubbleForPolyline = function(s, t) {
const e = t.attributes.points.value.trim().split(" "), r = e[0].split(",");
let n = parseFloat(r[0]), u = parseFloat(r[1]), l, p, o = 0, h = 0, f;
for (let c = 0; c < e.length; c++)
o += n, h += u, c < e.length - 1 && (f = e[c + 1].split(","), l = parseFloat(f[0]), p = parseFloat(f[1]), n = l, u = p);
n = o / e.length, u = h / e.length, s.appendChild(this.createShiftBubble(n, u, "shift"));
const g = document.createElementNS(
"http://www.w3.org/2000/svg",
b.GROUP
);
n = parseFloat(r[0]), u = parseFloat(r[1]);
for (let c = 0; c < e.length; c++)
s.appendChild(this.createPointBubble(n, u, c.toString())), c < e.length - 1 && (f = e[c + 1].split(","), l = parseFloat(f[0]), p = parseFloat(f[1]), g.appendChild(
this.createNewPointBubble(
0.5 * (n + l),
0.5 * (u + p),
c.toString() + ".5"
)
), n = l, u = p);
if (t.tagName == a.POLYGON) {
const [c, M] = e[0].split(","), F = (e.length - 1).toString() + ".5";
n = parseFloat(c), u = parseFloat(M), g.appendChild(
this.createNewPointBubble(0.5 * (n + l), 0.5 * (u + p), F)
);
}
return s.appendChild(g), s;
};
d.prototype.createBubbleForText = function(s, { x: t, y: i }) {
return s.appendChild(this.createShiftBubble(t, i, "shift")), s;
};
d.prototype.createBubbleGroup = function(s) {
s || m(
this.configuration.debugLog,
"group arg null, thisGroup=" + this.state.currentGroup
);
const t = s.firstChild, i = dt(t.tagName), e = document.createElementNS(
"http://www.w3.org/2000/svg",
b.GROUP
);
if (e.classList.add("bubbles"), t.tagName !== b.PATH)
for (let r in i)
i[r] = Et(t, r);
switch (t.tagName) {
case b.CIRCLE:
return this.createBubbleForCircle(e, i);
case b.ELLIPSE:
return this.createBubbleForEllipse(e, i);
case b.RECT:
return this.createBubbleForRectangle(e, i);
case b.LINE:
return this.createBubbleForLine(e, i);
case b.PATH:
return this.createBubbleForPath(e, t);
case a.POLYGON:
case a.POLYLINE:
return this.createBubbleForPolyline(e, t);
case b.TEXT:
return this.createBubbleForText(e, i);
}
};
d.prototype.createShiftBubble = function(s, t, i) {
const e = this.createBubbleStub(s, t);
return e.setAttributeNS(null, "r", this.state.bubbleRadius * 1.25), e.setAttributeNS(null, "stroke", "#004477"), e.setAttributeNS(null, "fill-opacity", "1.0"), e.addEventListener("mousedown", () => {
this.setShiftElement(e);
}), e.addEventListener("mouseup", () => {
this.setElementMouseEnterLeave(e);
}), e.setAttributeNS(null, "style", "cursor:move;"), e.setAttributeNS(null, "id", i), e;
};
d.prototype.createSizeBubble = function(s, t, i) {
let e = this.createBubbleStub(s, t);
return e.setAttributeNS(null, "fill-opacity", "0.6"), e.addEventListener("mousedown", (r) => {
this.setSizeElement(e, r);
}), e.setAttributeNS(null, "id", i), e;
};
d.prototype.createPointBubble = function(s, t, i) {
const e = this.createBubbleStub(s, t);
return e.setAttributeNS(null, "fill-opacity", "0.6"), e.setAttributeNS(null, "id", i), e.addEventListener("mousedown", () => {
this.setPointElement(e);
}), e;
};
d.prototype.createNewPointBubble = function(s, t, i) {
const e = this.createBubbleStub(s, t);
return e.setAttributeNS(null, "r", this.state.bubbleRadius * 0.8), e.setAttributeNS(null, "stroke", "#555555"), e.setAttributeNS(null, "stroke-opacity", "0.6"), e.setAttributeNS(null, "fill-opacity", "0.4"), e.addEventListener("mousedown", () => {
this.setNewPointElement(e);
}), e.setAttributeNS(null, "id", i), e;
};
d.prototype.createCurveBubble = function(s, t, i) {
const e = this.createBubbleStub(s, t);
return e.setAttributeNS(null, "stroke", "#333333"), e.setAttributeNS(null, "stroke-opacity", "0.6"), e.setAttributeNS(null, "fill-opacity", "0.8"), e.addEventListener("mousedown", () => {
this.setPointElement(e);
}), e.setAttributeNS(null, "id", i), e;
};
function W({ x1: s, y1: t, x2: i, y2: e, id: r, attributes: n }) {
const u = E({ tag: a.LINE, attributes: n });
return u.setAttributeNS(null, "x1", s), u.setAttributeNS(null, "y1", t), u.setAttributeNS(null, "x2", i), u.setAttributeNS(null, "y2", e), u.setAttributeNS(null, "id", r), u.setAttributeNS(null, "stroke-width", "1"), u;
}
function gt({ coords: s, attributes: t }) {
const i = E({ tag: a.POLYLINE, attributes: t });
return i.setAttributeNS(null, "id", "poly"), i.setAttributeNS(null, "points", Q(s)), i.setAttributeNS(null, "stroke-opacity", "0.0"), i;
}
d.prototype.createBubbleStub = function(s, t) {
const i = E({
tag: a.CIRCLE,
attributes: this.getSVGAttributes()
});
return isNaN(s) && alert("offsetX: " + s.toString()), isNaN(t) && alert("offsetY: " + t.toString()), i.setAttributeNS(null, "cx", s), i.setAttributeNS(null, "cy", t), i.setAttributeNS(null, "r", this.state.bubbleRadius), i.setAttributeNS(null, "fill", "#FFFFFF"), i.setAttributeNS(null, "stroke", "#222222"), i.setAttributeNS(null, "stroke-width", this.state.bubbleRadius * 0.25), i;
};
function Et(s, t) {
return parseFloat(parseFloat(s.attributes[t].value).toFixed(1));
}
function x(s) {
return !isNaN(parseFloat(s)) && isFinite(s);
}
d.prototype.onSvgMouseMove = function(s) {
return this.renderFunction(s), s.preventDefault(), !1;
};
function vt(s, t, i, e) {
return Math.sqrt(Math.pow(s - i, 2) + Math.pow(t - e, 2));
}
d.prototype._getMousePosition = function(s) {
const t = this.containerElement.getBoundingClientRect();
return {
x: s.clientX - t.left,
y: s.clientY - t.top
};
};
d.prototype.updateMousePosition = function(s) {
const t = this.touchSupported ? s.originalEvent.touches[0] : s;
this.state.mousePosition = this._getMousePosition(t);
};
d.prototype.updateSvgByElement = function(s) {
if (this.state.cursorMode != a.MOVE) {
if (this.state.cursorMode === a.POLYGON || this.state.cursorMode === a.POLYLINE && this.state.svgInProgress === a.POLYGON) {
if (this.state.svgInProgress == !1)
return;
if (this.updateMousePosition(s), this.state.svgInProgress == "SHIFT") {
let t = this.state.currentElement.attributes.points.value.trim(), i = t.split(" ");
if (this.state.currentBubble != null) {
let e = parseFloat(this.state.currentBubble.attributes.cx.value), r = parseFloat(this.state.currentBubble.attributes.cy.value), n = this.currentMouse