diff --git a/capsule-prototype/css/flatten_timeline.css b/capsule-prototype/css/flatten_timeline.css
index 175b8c9e1b57e12cdfc9957b3d907cea1ab4e921..e63df9e9ff915f75ab5693dbe541a88a593f316d 100644
--- a/capsule-prototype/css/flatten_timeline.css
+++ b/capsule-prototype/css/flatten_timeline.css
@@ -9,7 +9,6 @@
 }
 
 #flattentimeline.drag  {
-	/*background: rgba(2,212,255,.5);*/
 	box-shadow: 0 0 20px 20px rgba(63,223,255,.45) inset;
 }
 
@@ -24,16 +23,10 @@
 
 #flattentimeline_main_title {
 	font-weight: 200;
-	/*height: 40px;*/
 	line-height: 20px;
 	padding: 10px 0;
 	text-align: center;
-	/*background: #2C3032;*/
-	/*background: #2C3033;*/
-	/*background: #57A5AF;*/
 	background: #EC8960;
-	/*background-image: -webkit-linear-gradient(left, #EC8960 0%, #57A5AF 100%);*/
-	/*background-image: -webkit-linear-gradient(left, #94CA6F 0%, #B495CC 100%);*/
 	text-transform: uppercase;
 	color: rgba(255,255,255,1);
 	font-size: 18px;
@@ -69,18 +62,15 @@
 	cursor: pointer;
 	width: 100%;
 	display: none;
-	/*border-radius: 2px;*/
 }
 
 
 .flattentimeline_highlightitem {
 	position: relative;
-	/*height: 150px;*/
 	height: auto;
 	color: white;
 	margin: 3px 0px 0px 0px;
 	cursor: pointer;
-	/*background: rgba(255,255,255,.15);  */
 	width: 100%;
 	text-align: center;
 	padding: 2px 0 3px 0;
@@ -92,8 +82,6 @@
 	-moz-background-size: cover;
 	-o-background-size: cover;
 	background-size: cover;
-
-	/*display:block;*/
 }
 
 
@@ -116,15 +104,11 @@
 	background-size: cover;
 	text-align: left;
 	overflow: hidden;
-
-	/*border-radius: 3px;
-	/*mix-blend-mode: overlay;*/
 }
 
 .flattentimeline_title, .flattentimeline_subtitle, .flattentimeline_counter {
 	top: 0px;
 	left: 0px;
-	/*position: absolute; */
 	background-position: center center;
 	background-repeat: no-repeat;
 	text-align: left;
@@ -165,33 +149,11 @@
 	opacity: .5;
 }
 
-/*.flattentimeline_highlightitem .flattentimeline_image {
-width: 170px;
-height: 60px;
-margin: 15px 15px 5px 15px;
-border-radius: 2px;
-background-color: #fff;
-display: inline-block;
-float: left;
-background-position: center center;
-}  */
-
-/*.flattentimeline_color {
-top: 0px;
-height: 100%;
-}*/
+
 .flattentimeline_opacifiant, .flattentimeline_bar {
 	background-color: rgba(0, 0, 0, 0.75);
 	height: 3px;
 	top: 37px;
-
-	/* box-shadow: 0px 0px 1px 1px rgba(20,46,51,.25);
-	/*	mix-blend-mode: luminosity;  */
-
-	/*  mix-blend-mode: multiply;
-	/*  height: 40px;
-	top: 0px;
-	opacity: .25;  */
 }
 
 .flattentimeline_highlightitem .flattentimeline_bar, .flattentimeline_highlightitem  .flattentimeline_opacifiant  {
@@ -203,16 +165,9 @@ height: 100%;
 	font-weight: 400;
 	font-size: 10px;
 	line-height: 39px;
-	/* color: rgba(255,255,255,.5); */
 
-	/*width: 55%; */
-	/*max-width: 132px;*/
 	text-overflow: ellipsis;
 	white-space: nowrap;
-	/*overflow: hidden;*/
-
-	/*color: #0C2D33; */
-	/*mix-blend-mode: screen;      */
 }
 
 .flattentimeline_highlightitem .flattentimeline_title {
@@ -221,7 +176,7 @@ height: 100%;
 	font-size: 12px;
 	text-transform: uppercase;
 	padding: 20px 0 20px 0;
-	color: #FFF;/*rgba(255,255,255,1);*/
+	color: #FFF;
 	font-weight: 600;
 }
 
@@ -250,7 +205,6 @@ height: 100%;
 
 	display: inline-block;
 	font-style: italic;
-	/*text-transform: uppercase; */
 }
 
 .flattentimeline_highlightitem .flattentimeline_author {
@@ -267,25 +221,9 @@ height: 100%;
 	height: 20px;
 	display: none;
 }
-/*.flattentimeline_type {
-top: 14px;
-left: 6px;
-width: 26px;
-height: 26px;
-background-position: center center;
-background-repeat: no-repeat;
-opacity: .5;
-}*/
-/*.flattentimeline_type {
-width:10px; height:10px;
-border-radius:10px;
-float:right;
-margin:20px 15px 20px 0;
-}*/
 .flattentimeline_type {
 	width: 20px;
 	height: 20px;
-	/*border-radius: 20px; */
 	float: right;
 	background-position: center center;
 	background-repeat: no-repeat;
@@ -328,8 +266,7 @@ margin:20px 15px 20px 0;
 }
 
 .flattentimeline_bar {
-	/*width: 0%;*/
-	background-color: #26292B;	/*#2DCAE1;*/
+	background-color: #26292B;
 	opacity: 1;
 }
 
diff --git a/capsule-prototype/css/left_menu.css b/capsule-prototype/css/left_menu.css
index f446c47a25229708ec624a274cbedc2e5b37cb79..e0532dad820ab7a9238ae3d268eb552afb461d78 100644
--- a/capsule-prototype/css/left_menu.css
+++ b/capsule-prototype/css/left_menu.css
@@ -49,55 +49,3 @@
 #left_menu_item_preview::before { content: url('images/icn-menu-preview.png'); }
 #left_menu_item_settings::before { content: url('images/icn-menu-settings.png'); }
 
-/*
-
-.left_menu_item:hover { background: rgba(0,0,0,.1); }
-
-.left_menu_item.selected { background: rgba(0,0,0,.15); }
-
-.left_menu_item:first-child { margin-bottom: 10px; }
-
-.left_menu_item_icn { width:40px; height:40px; }
-
-#left_menu_item_icn_presets { background:url("images/icn-menu-presets.png"); }
-
-#left_menu_item_icn_horizontal { background:url("images/icn-menu-horizontal.png"); }
-
-#left_menu_item_icn_vertical { background:url("images/icn-menu-vertical.png"); }
-
-#left_menu_item_icn_groups { background:url("images/icn-menu-groups.png"); }
-
-#left_menu_item_icn_colors { background:url("images/icn-menu-colors.png"); }
-
-#left_menu_item_icn_filter { background:url("images/icn-menu-filter.png"); }
-
-#left_menu_item_icn_highlight { background:url("images/icn-menu-highlight.png"); }
-
-#left_menu_item_icn_search { background:url("images/icn-menu-search.png"); }
-
-#left_menu_item_icn_keywords { background:url("images/icn-menu-keywords.png"); }
-
-#left_menu_item_icn_mosaic { background:url("images/icn-menu-mosaic.png"); }
-
-#left_menu_item_icn_preview { background:url("images/icn-menu-preview.png"); }
-
-#left_menu_item_icn_settings { background:url("images/icn-menu-settings.png"); }
-
-.left_menu_item_title {
-	height:20px;
-	line-height:20px;
-}
-
-#left_menu .break {
-	width:40px; height:1px;
-	background:rgba(255,255,255,.2);
-	margin:5px 20px;
-}
-
-#left_menu_item_btn_addfile {
-	background: red;
-	opacity: 0;
-	cursor: pointer !important;
-}
-
-*/
diff --git a/capsule-prototype/css/online-theme.css b/capsule-prototype/css/online-theme.css
index f547888fc28d2124335961222ed40a63b141b2ec..23729264454a47a2e0da9fd87b662e44d651a9d7 100644
--- a/capsule-prototype/css/online-theme.css
+++ b/capsule-prototype/css/online-theme.css
@@ -27,8 +27,6 @@ html, body {
 	font-family: 'OpenSans';
 	font-weight: 400;
 	font-size: 12px;
-	/*background-color: white;
-	background-color: #061619; */
 	background: #142E33;
 	-webkit-touch-callout: none;
 	-webkit-user-select: none;
@@ -72,7 +70,6 @@ html, body {
 }
 
 .empty, .empty#popupAuthor, .empty#popupLink {
-	/*font-style: italic; */
 	color: rgba(255,255,255,.25);
 	text-decoration: none !important;
 	display: none;
@@ -80,8 +77,6 @@ html, body {
 
 .separationHDark {
 	height: 1px;
-	/*background: rgba(0,0,0,.25);
-	/*background: rgba(255,255,255,.1);  */
 	border-bottom: 1px solid rgba(0,0,0,.1);
 	margin: 1vh 0 0vh 0;
 	width: 100%;
@@ -117,10 +112,6 @@ html, body {
 	font-weight: 500 !important;
 }
 
-.vjs-mouse-display {
-	/*z-index: 1 !important; */
-}
-
 .editmode {
 	display:none !important;
 	width:0 !important;
@@ -130,10 +121,6 @@ html, body {
 	#watermark {
 		display: none;
 	}
-	/*#projectInfoBtn {
-	position: absolute;
-	display: none;
-	}*/
 }
 
 @media screen and (max-width: 1000px) {
@@ -150,29 +137,6 @@ html, body {
 	#watermark:hover {
 		opacity: 1;
 	}
-
-	/*#projectInfoBtn {
-	width: 30px;
-	height: 30px;
-	background: #FFF;
-	position: absolute;
-	z-index: 100000;
-	top: 20px;
-	left: 20px;
-	opacity: .25;
-	border-radius: 200px;
-	font-family: serif;
-	font-style: italic;
-	font-weight: bold;
-	color: #000;
-	font-size: 24px;
-	text-align: center;
-	line-height: 30px;
-	cursor: pointer;
-	}
-	#projectInfoBtn:hover {
-	opacity: .5;
-	}*/
 }
 
 #projectInfoBtn {
@@ -215,7 +179,3 @@ html, body {
 #openFullScreen:hover {
 	opacity: 1;
 }
-
-.displayMode {
-	/* display: none;   */
-}
diff --git a/capsule-prototype/css/popup.css b/capsule-prototype/css/popup.css
index 4745b30853c38dd61a1df3aedf94e6e159929a25..baea1c74f1b9dcb4b9e696a84661e0bbda25e4b7 100644
--- a/capsule-prototype/css/popup.css
+++ b/capsule-prototype/css/popup.css
@@ -62,26 +62,13 @@
 	z-index: 10000000;    	
 	text-align: center;
 	display: none;
-	top: 0px;
+	top: 0;
 }
 
 #popupAlertSpace {
 	z-index: 100000000;
 }
 
-/*#popupSettings {
-width: 40vw;
-margin-top: 25vh;
-padding: 5vh 0 6vh 0;
-border-radius: 2px;
-box-shadow: 0 5px 25px #000;
-font-weight: 400;
-font-size: 1vw;
-display: inline-block;
-text-align: center;
-background: var(--rk-greyblue);
-}    */
-
 #popupSettings {
 	margin-top: 15vh;
 	border-radius: 2px;
@@ -127,7 +114,6 @@ background: var(--rk-greyblue);
 	margin: 1vh 0 1vh 0;
 	line-height: 1.2em;
 	padding: 1.2em 2.4em 1.2em 2.4em;
-	padding: 1.2em 0;
 	width: 9vw;
 	border-radius: 3px;
 	border: 1px solid rgba(255,255,255,.15);
@@ -135,7 +121,7 @@ background: var(--rk-greyblue);
 }
 
 .popupSettingsBtn:hover {
-	background: rgba(255,255,255,.05);/*rgba(20,46,51,.75);/*rgba(20,46,51,.75);  */
+	background: rgba(255,255,255,.05);
 	color: #fff;
 }
 
@@ -177,7 +163,6 @@ background: var(--rk-greyblue);
 
 .popupSettingsInput {
 	width: 23vw;
-	display: inline-block;
 	margin-bottom: 1vh;
 	font-size: .9em;
 	line-height: 1.2em;
@@ -203,13 +188,9 @@ background: var(--rk-greyblue);
 	font-size: 1.2em;
 }
 
-#popupSettingsCredits, #popupSettingsCreationDate {
-}
-
 #popupAlert {
 	width: 46vw;
-	background: #142E33;/*rgb(50,50,50); */
-	/*margin: 20vh 0 0 0;  */
+	background: #142E33;
 	padding: 5vh 2vw;
 	border-radius: 3px;
 	box-shadow: 0 5px 25px #000;
@@ -225,12 +206,12 @@ background: var(--rk-greyblue);
 	font-weight: 200;
 }
 
-#popupAlertInput, #popupAlertTextarea {
-	background: rgba(0,0,0,.05);/*gba(255,255,255,.15);*/
-	box-shadow: 0 1px 3px rgba(0,0,0,.2) inset;
+#popupAlertInput, #popupAlertTextarea, #popupAddLinkInput {
+	background: rgba(0, 0, 0, .05);
+	box-shadow: 0 1px 3px rgba(0, 0, 0, .2) inset;
 	border: 0;
 	border-radius: 3px;
-	color: rgba(255,255,255,.85);
+	color: rgba(255, 255, 255, .85);
 	width: 30vw;
 
 	display: inline-block;
@@ -239,10 +220,11 @@ background: var(--rk-greyblue);
 	font-size: 0.9em;
 	cursor: pointer;
 	padding-bottom: 0;
+}
 
+#popupAlertInput, #popupAlertTextarea {
 	line-height: 1.4em;
 	padding: 2vh 1vw;
-
 	margin: 3vh 0 1.5vh 0;
 }
 
@@ -253,20 +235,15 @@ background: var(--rk-greyblue);
 
 .popupAlertButton, .popupAddLinkButton, .popupSettingsButton {
 	width: 9vw;
-
 	font-weight: 400;
-	/*  color: rgba(255,255,255,.75);  */
 	font-size: 0.7em;
 	line-height: 1.2em;
-
 	cursor: pointer;
 	text-transform: uppercase;
 	text-align: center;
 	display: inline-block;
-	/*   border: 1px solid rgba(255,255,255,.15); */
 	border-radius: 3px;
 	padding: 1.1em 0;
-
 	color: rgba(255,255,255,.5);
 	background: rgba(255,255,255,.15);
 	box-shadow: 0 1px 3px rgba(0,0,0,.1);
@@ -285,24 +262,16 @@ background: var(--rk-greyblue);
 }
 
 #popupAddLink {
-
 	width: 40vw;
-	/*background: rgb(102,202,138);
-	/*background: rgb(100,100,100);*/
 	margin-top: 25vh;
 	padding: 5vh 0 6vh 0;
-	/*left: 20%;
-	position: absolute;  */
-border-radius: 2px;
-/*border: 2px solid #333;*/
-box-shadow: 0 5px 25px #000;
-font-weight: 400;
-font-size: 1vw;
-display: inline-block;
-text-align: center;
-background: var(--rk-greyblue);
-/*background-image: -webkit-linear-gradient(right bottom,  rgb(20,46,51) 0%, #475457 150%);
-/*box-shadow: 0px 0px 2px 3px rgba(255,255,255,.1) inset;  */
+	border-radius: 2px;
+	box-shadow: 0 5px 25px #000;
+	font-weight: 400;
+	font-size: 1vw;
+	display: inline-block;
+	text-align: center;
+	background: var(--rk-greyblue);
 
 }
 
@@ -317,22 +286,8 @@ background: var(--rk-greyblue);
 }
 
 #popupAddLinkInput {
-	background: rgba(0,0,0,.05);/*gba(255,255,255,.15);*/
-	box-shadow: 0 1px 3px rgba(0,0,0,.2) inset;
-	border: 0;
-	border-radius: 3px;
-	color: rgba(255,255,255,.85);
-	width: 30vw;
-	display: inline-block;
-
-	font-weight: 200;
-	font-size: 0.9em;
-	cursor: pointer;
-	padding-bottom: 0;
-
 	line-height: 1.2em;
 	padding: 1.0em 1vw;
-
 	margin: 2vh 0 1.5vh 0;
 }
 
@@ -410,7 +365,7 @@ background: var(--rk-greyblue);
 	box-shadow: 0 1px 3px rgba(0,0,0,.35);
 }
 
-#closePopupEdit {
+#closePopupEdit, #closePopupMosaic {
 	width: 40px;
 	height: 40px;
 	font-weight: 200;
@@ -421,22 +376,15 @@ background: var(--rk-greyblue);
 	cursor: pointer;
 	border-radius: 3px;
 	position: fixed;
+}
+
+#closePopupEdit {
 	top: 15vh;
 	right: 25.5vw;
 	z-index: 110;
 }
 
 #closePopupMosaic {
-	width: 40px;
-	height: 40px;
-	font-weight: 200;
-	color: rgba(255,255,255,.25);
-	font-size: 30px;
-	text-align: center;
-	line-height: 40px;
-	cursor: pointer;
-	border-radius: 3px;
-	position: fixed;
 	top: 2vh;
 	right: 34vw;
 	z-index: 110;
@@ -519,7 +467,6 @@ background: var(--rk-greyblue);
 }
 
 #popupTC:hover {
-	/*background: rgba(255,255,255,.25);*/
 	background: rgba(255,255,255,.1);
 }
 
@@ -537,8 +484,6 @@ background: var(--rk-greyblue);
 	line-height: 1.2em;
 	margin-bottom: 5%;
 	font-weight: 200;
-	/*background: rgba(0,0,0,.05);  */
-	/*background: rgba(255,255,255,.05); */
 	background: none;
 	border: 1px solid #000;
 	padding: 1vh 0;
@@ -547,7 +492,7 @@ background: var(--rk-greyblue);
 }
 
 .popupTCeditfield {
-	background: rgba(0,0,0,.25);/*gba(255,255,255,.15);*/
+	background: rgba(0,0,0,.25);
 	box-shadow: 0 1px 3px rgba(0,0,0,.5) inset;
 	border: 0;
 	border-radius: 3px;
@@ -586,7 +531,6 @@ background: var(--rk-greyblue);
 	font-size: 0.9em;
 	padding: 0;
 	margin: 0 0 2vh 0;
-	/*font-style: italic; */
 }
 
 #popupLegendeInput {
@@ -640,44 +584,33 @@ background: var(--rk-greyblue);
 
 #popupSetHighlight {
 	font-weight: 400;
-	color: rgba(0,0,0,.75);/*#142E33;*/
+	color: rgba(0,0,0,.75);
 	font-size: 0.75em;
 	cursor: pointer;
 	text-transform: uppercase;
 	text-align: center;
 	margin: -3vh 2vh 2vh 2vh;
 	line-height: 2.0em;
-	/*background: rgba(255,255,255,.1);
-	/*background: rgba(0,0,0,.1);  */
 	padding: .8em 1.8em .8em 1.8em;
 	border-radius: 2px 0 0 0;
 }
 
 #popupSetHighlight.selected {
-	/*color: rgba(255,255,255,.75);
-	background: rgba(0,0,0,.15);        */
-/* background: rgba(255,255,255,.15);   */
 color: #FFF;
 }
 
-#popupSetHighlight:hover {
-	/*background: rgba(0,0,0,.25);
-	color: #FFF;   */
-/*background: rgba(255,255,255,.2);  */
+#popupSetHighlight:hover, #editAnnotationPic:hover, #linkToOriginalImage:hover {
 color: rgba(255,255,255,.25);  /*#142E33;  */
 }
 
 #popupSetHighlight.selected:hover {
-	/*color: rgba(255,255,255,.75);
-	background: rgba(0,0,0,.15);        */
-/*background: rgba(255,255,255,.25);    */
 color: rgba(255,255,255,.75);   /*#FFF; */
 }
 
 
-#popupEditSupprimer {
+#popupEditSupprimer, #editAnnotationPic, #linkToOriginalImage {
 	font-weight: 400;
-	color: rgba(255,255,255,.75);/*#142E33;/*#FFF;/*rgba(255,255,255,.5); */
+	color: rgba(255,255,255,.75);
 	font-size: 0.6em;
 	cursor: pointer;
 	text-transform: uppercase;
@@ -686,18 +619,15 @@ color: rgba(255,255,255,.75);   /*#FFF; */
 	bottom: 0;
 	margin: 2vh 0 1vh 0;
 	line-height: 1.2em;
-	/*background: #142E33;/*rgba(20,46,51,.8);/*rgba(0,0,0,.2);   */
-	/*background-image: -webkit-linear-gradient(top, rgba(255,255,255,.25) 0%, rgba(255,255,255,.10) 100%);   */
 	padding: 1.2em 2.4em 1.2em 2.4em;
 	padding: 1.2em 0;
 	width: 9vw;
 	border-radius: 3px;
 	border: 1px solid rgba(255,255,255,.15);
-	/*border-bottom: 1px solid #142E33;   */
 }
 
 #popupEditSupprimer:hover {
-	background: rgba(255,255,255,.05);/*rgba(20,46,51,.75);/*rgba(20,46,51,.75);  */
+	background: rgba(255,255,255,.05);
 	color: #fff
 }
 
@@ -733,40 +663,7 @@ color: rgba(255,255,255,.75);   /*#FFF; */
 	}
 }
 
-
-@media screen and (max-width: 1000px) {
-	#popupEdit {
-		margin-top: 5vh;
-		font-size: 2.4vw;
-	}
-	#popupLeft {
-		width: 30vw;
-		min-height: 60vh;
-		padding: 5vh 0 3vh 0;
-	}
-	#popupRight {
-		width: 56vw;
-		min-height: 60vh;
-		padding: 5vh 3vw 4vh 3vw;
-	}
-	#popupImg {
-		max-width: 25vw;
-		max-height: 25vw;
-	}
-	#closePopupEdit {
-		top: 5vh;
-		right: 4vw;
-		z-index: 110;
-	}
-	.popupRightItem {
-		width: 56vw;
-		margin-bottom: 2vh;
-		font-size: 1em;
-		line-height: 1.2em;
-	}
-}
-
-#paste_modal {
+#paste_modal, #edit_pic_modal {
 	align-items: center;
 	position: absolute;
 	margin: 10%;
@@ -790,6 +687,17 @@ color: rgba(255,255,255,.75);   /*#FFF; */
 	display: none;
 }
 
+#edit_pic_modal {
+  z-index: 10000001;
+  background-color: transparent;
+  box-shadow: none;
+}
+
+#edit_pic_modal img {
+  width: 100%;
+  height: auto;
+}
+
 #paste_modal h1 {
 	margin: 5px;
 	padding: 5px;
diff --git a/capsule-prototype/index.html b/capsule-prototype/index.html
index f4ae664e6ab7ae848316e30f4bca7711b0347904..8caea838f292055c6eb52b4b1c8e6fc9cab53aad 100644
--- a/capsule-prototype/index.html
+++ b/capsule-prototype/index.html
@@ -48,23 +48,14 @@
 	<script language="javascript" type='text/javascript' src="../shared/js/libs/video-js/formats/vjs.vimeo.js"></script>
 
 	<script defer type="javascript" type="text/javascript" src="../shared/js/all.js"></script>
-	<!--
-	<script language="javascript" type='text/javascript' src="../shared/js/libs/video-js/formats/vjs.dailymotion.js"></script>
-	-->
-
-	<!--
-	<script language="javascript" type='text/javascript' src="../shared/js/libs/video-js/plugins/rangeslider.min.js"></script>
-	<link        rel="stylesheet" type="text/css"       href="../shared/js/libs/video-js/plugins/rangeslider.min.css" />
-	<script language="javascript" type='text/javascript' src="../shared/js/libs/video-js/plugins/annotator.min.js"></script>
-	<link        rel="stylesheet" type="text/css"       href="../shared/js/libs/video-js/plugins/annotator.min.css" />
-	<script language="javascript" type='text/javascript' src="../shared/js/libs/video-js/plugins/ova.min.js"></script>
-	<link        rel="stylesheet" type="text/css"       href="../shared/js/libs/video-js/plugins/ova.min.css"/>
-	-->
 	<script language="javascript" type='text/javascript' src="../shared/js/libs/video-js/plugins/videojs.markers.js"></script>
 	<link        rel="stylesheet" type="text/css"       href="../shared/js/libs/video-js/plugins/videojs.markers.css"/>
 	<script language="javascript" type='text/javascript' src="../shared/js/libs/video-js/plugins/videojs.caption.js"></script>
 	<link        rel="stylesheet" type="text/css"       href="../shared/js/libs/video-js/plugins/videojs.caption.css"/>
 
+  <script language="javascript" type='text/javascript' src="../shared/js/libs/markerjs2/markerjs2.js"></script>
+  <script language="javascript" type='text/javascript' src="../shared/js/libs/markerjslive/markerjs-live.js"></script>
+
 	<script>
 		videojs.options.flash.swf = "video-js/video-js.swf";
 	</script>
@@ -76,15 +67,7 @@
 
 <div id='container'>
 	<div id="ruban"></div>
-	<!-- <div id="popupFormSpace">
-         <div id="popupForm">
-             <div id="popupFormMessage"></div>
-             <div class="popupFormButton" id="popupFormButtonCancel">Cancel</div>
-             <input class="popupFormButton" id="popupFormButtonUpload" type="submit" value="Upload" name="submit">
-         </div>
-     </div>     -->
 	<a class="displayMode" id="watermarkBox" href="javascript:window.app.rekall.Rekall('openUrl', 'home')" title="Open in MemoRekall" target="_parent"><img id="watermark" src="../shared/css/images/watermark.png" /></a>
-	<!--<a class="displayMode" id="openFullScreenBox" href="http://www.memorekall.fr" alt="Open in MemoRekall" target="_blank"><img id="openFullScreen" src="../shared/css/images/expand.png" /></a>-->
 	<div class="displayMode" id="projectInfoBtn" title="Project informations">i</div>
 	<div id="popupAlertSpace">
 		<div id="popupAlert">
@@ -131,10 +114,6 @@
 					<div class="popupSettingsBtn editmode" id="popupSettingsBtnDownloadXml">Download XML</div>
 					<div class="popupSettingsBtn editmode" id="popupSettingsBtnDelete">Delete project</div>
 					<a class="popupSettingsA" href="http://www.memorekall.com" target="_blank">www.memorekall.com</a>
-
-					<!-- 	<input id="popupSettingsShare" type="text" value="http://projects.rekall.com/monprojet" placeHolder=""/>
-                         <textarea id="popupSettingsEmbed" type="text"></textarea>
-                         <div id="popupSettingsDownloadXml">Download project XML</div>     -->
 				</td>
 			</tr>
 		</table>
@@ -147,8 +126,9 @@
 					<div class="popupLeftItem" id="popupImgBox">
 						<img id="popupImg" src="file/rekall_cache/568261E53001FA741A069C684C6E25E7571006E8-45972424CDE1275C6FDD9DD7D52216C878F04AB8.jpg"/>
 						<div class="popupLeftItem" id="popupType"></div>
+            <div class='popupLeftItem' id='editAnnotationPic'></div>
+            <div class='popupLeftItem' id='linkToOriginalImage'>open original image</div>
 					</div>
-					<!--<div class="popupRightItem separationHDark editmode"></div>-->
 					<div class="editmode" id="popupEditSupprimer">Delete file</div>
 				</td>
 				<td id="popupRight">
@@ -172,8 +152,6 @@
 						<span class="popupTClabel">end</span>
 						<input class="popupTCeditfield" id="popupTCoutMin" maxlength="2" type="text" value=""/>&nbsp;:&nbsp;<input class="popupTCeditfield" id="popupTCoutSec" maxlength="2" type="text" value=""/>
 						&nbsp;&nbsp;&nbsp;&nbsp;<div class="nowTCbtn" id="nowTCout">now</div> / <div class="nowTCbtn" id="eovTCout">end of video</div>
-						<!--<div class="TCvalidBtn" id="TCvalidModif">&check;</div>
-                        <div class="TCvalidBtn" id="TCinvalidModif">&cross;</div> -->
 					</div>
 
 					<div class="popupRightItem" id="popupLegende" title="Comment"></div>
@@ -227,12 +205,16 @@
 		</div>
 	</div>
 
+  <div id='edit_pic_modal' class='flex-col'>
+    <img id='annotation_img_edit' />
+  </div>
+
   <div id='left_menu' class='flex-col editmode left_menu'>
     <div class='flex-col'>
-    <a id='btn_home' class='left_menu_item flex-col' href='javascript:window.app.rekall.Rekall('openUrl', 'home')'><i class='fas fa-home fa-3x left_menu_item_icn'></i>Go back to my capsules</a>
+    <a id='btn_home' class='left_menu_item flex-col' href="javascript:window.app.rekall.Rekall('openUrl', 'home')"><i class='fas fa-home fa-3x left_menu_item_icn'></i>Go back to my capsules</a>
       <div id='left_menu_item_preview' class='left_menu_item flex-col'>preview</div>
     </div>
-    <div class='flex-col'>
+    <div id='left_menu_controls' class='flex-col'>
       <ul class='btns_add_annotation flex-col'>
         <input type='checkbox' id='inp_add_annotation_dropdown' class='dropdown_control' />
         <li class='dropdown_content left_menu_item' id='btn_add_note'>note</li>
@@ -267,43 +249,6 @@
     <div id='left_menu_item_settings' class='left_menu_item flex-col'>settings</div>
   </div>
 
-	<!--
-	<div id='left_menu' class='flex-col editmode'>
-		<div class='top'>
-			<a class="left_menu_item dropable" href="javascript:window.app.rekall.Rekall('openUrl', 'home')">
-				<i class="fas fa-home fa-3x left_menu_item_icn"></i>
-				<p>Go back to my capsules</p>
-			</a>
-			<div class="left_menu_item dropable" id="left_menu_item_settings" title="Settings">
-				<div class="left_menu_item_icn" id="left_menu_item_icn_settings"></div>
-				<div class="left_menu_item_title">Settings</div>
-			</div>
-			<div class="left_menu_item dropable" id="left_menu_item_preview" title="Preview">
-				<div class="left_menu_item_icn" id="left_menu_item_icn_preview"></div>
-				<div class="left_menu_item_title">Preview</div>
-			</div>
-		</div>
-		<div class='bottom'>
-			<div class="left_menu_item dropable" id="left_menu_item_addlink" title="AddLink">
-				<div class="left_menu_item_icn" id="left_menu_item_icn_addlink"></div>
-				<div class="left_menu_item_title">Add Link</div>
-			</div>
-			<div class="left_menu_item dropable" id="left_menu_item_addnote" title="AddNote">
-				<div class="left_menu_item_icn" id="left_menu_item_icn_addnote"></div>
-				<div class="left_menu_item_title">Add Note</div>
-			</div>
-			<div class="left_menu_item dropable" id="left_menu_item_pastefile" title="PasteFile">
-				<div class="left_menu_item_icn" id="left_menu_item_icn_pastefile"></div>
-				<div class="left_menu_item_title">Paste File</div>
-			</div>
-			<div class="left_menu_item dropable" id="left_menu_item_addfile" title="AddFile">
-				<div class="left_menu_item_icn" id="left_menu_item_icn_addfile"></div>
-				<div class="left_menu_item_title">Add File</div>
-			</div>
-		</div>
-	</div>
-	-->
-
 	<div id='tabs' class='flex flex-col'>
 
 		<div id='tab_selector' class='flex-row flex-center editmode'>
@@ -320,10 +265,6 @@
 		<div id='video_tab' class='flex flex-row'>
 			<video id="video" class="video-js vjs-default-skin vjs-big-play-centered">
 				<p class="vjs-no-js">Your browser is not compatible with HTML5. Please upgrade!</p>
-				<!--
-                <track kind="captions"  src="demo.captions.vtt" srclang="en" label="English"></track>
-                <track kind="subtitles" src="demo.captions.vtt" srclang="en" label="English"></track>
-                -->
 			</video>
 			<div id='flattentimeline' class='flex-col'>
 				<div id="flattentimeline_highlight"></div>
diff --git a/capsule-prototype/js/libs/markerjs2/LICENSE b/capsule-prototype/js/libs/markerjs2/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..0709c250e344a56c87fba438c93f08892238b939
--- /dev/null
+++ b/capsule-prototype/js/libs/markerjs2/LICENSE
@@ -0,0 +1,25 @@
+marker.js 2 Linkware License
+
+Copyright (c) 2020 Alan Mendelevich
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+1. The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+2. Link back to the Software website displayed during operation of the Software
+or an equivalent prominent public attribution must be retained. Alternative 
+commercial licenses can be obtained to remove this clause.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/capsule-prototype/js/libs/markerjs2/README.md b/capsule-prototype/js/libs/markerjs2/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..5d49cbc794927ea0606522dafb8371c4ae4b3949
--- /dev/null
+++ b/capsule-prototype/js/libs/markerjs2/README.md
@@ -0,0 +1,61 @@
+# marker.js 2 &mdash; Add image annotation to your web apps
+
+marker.js 2 is a JavaScript browser library to enable image annotation in your web applications. Add marker.js 2 to your web app and instantly enable users to annotate and mark up images. You can save, share or otherwise process the results.
+
+> For a more detailed "Getting started" and other docs and tutorials, please refer to the [official documentation](https://markerjs.com/docs).
+
+## Installation
+
+```
+npm install markerjs2
+```
+
+or 
+
+```
+yarn add markerjs2
+```
+
+## Usage
+
+To add image annotation to your web application follow these 3 easy steps:
+
+1. Create an instance of `markerjs2.MarkerArea` by passing a target image reference to the constructor.
+2. Set an event handler for `render` event.
+3. Call the `show()` method.
+
+Here's a simple example:
+
+```js
+// skip this line if you are importing markerjs2 into the global space via the script tag
+import * as markerjs2 from 'markerjs2';
+
+// create an instance of MarkerArea and pass the target image reference as a parameter
+let markerArea = new markerjs2.MarkerArea(document.getElementById('myimg'));
+
+// register an event listener for when user clicks OK/save in the marker.js UI
+markerArea.addEventListener('render', event => {
+  // we are setting the markup result to replace our original image on the page
+  // but you can set a different image or upload it to your server
+  document.getElementById('myimg').src = event.dataUrl;
+});
+
+// finally, call the show() method and marker.js UI opens
+markerArea.show();
+```
+
+## Demos
+Check out [marker.js 2 demos](https://markerjs.com/demos) for various usage examples.
+
+## More docs and tutorials
+For a more detailed "Getting started" and other docs and tutorials, please refer to 
+the [official documentation](https://markerjs.com/docs).
+
+## Credits
+
+marker.js 2 is using icons from [Material Design Icons](https://materialdesignicons.com/) for its toolbar.
+
+## License
+Linkware (see [LICENSE](https://github.com/ailon/markerjs2/blob/master/LICENSE) for details) - the UI displays a small link back to the marker.js 2 website which should be retained.
+
+Alternative licenses are available through the [marker.js 2 website](https://markerjs.com).
\ No newline at end of file
diff --git a/capsule-prototype/js/libs/markerjs2/markerjs2.d.ts b/capsule-prototype/js/libs/markerjs2/markerjs2.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..cb82e2f56a4b5df177a11d128f9d4c78e813df59
--- /dev/null
+++ b/capsule-prototype/js/libs/markerjs2/markerjs2.d.ts
@@ -0,0 +1,3284 @@
+/**
+ * Describes point objects used internally in marker.js 2.
+ */
+interface IPoint {
+    x: number;
+    y: number;
+}
+
+/**
+ * Base class for all toolbox property panels.
+ */
+declare abstract class ToolboxPanel {
+    /**
+     * Panel name/title.
+     */
+    title: string;
+    /**
+     * Panel button icon as an SVG markup.
+     */
+    icon: string;
+    /**
+     * Create panel with supplied title and icon.
+     * @param title - panel name (used for accessibility)
+     * @param icon - panel button icon (SVG image markup)
+     */
+    constructor(title: string, icon?: string);
+    /**
+     * Returns toolbox panel UI.
+     */
+    abstract getUi(): HTMLDivElement;
+}
+
+/**
+ * Represents marker's state (status) in time.
+ */
+declare type MarkerState = 'new' | 'creating' | 'select' | 'move' | 'resize' | 'rotate' | 'edit';
+/**
+ * Represents marker's state used to save and restore state continue annotation in the future.
+ */
+interface MarkerBaseState {
+    /**
+     * Marker's type name.
+     */
+    typeName: string;
+    /**
+     * Current editing state/status.
+     */
+    state: MarkerState;
+    /**
+     * Additional information about the marker.
+     *
+     * @since 2.10.0
+     */
+    notes?: string;
+}
+
+/**
+ * Represents a list of colors.
+ */
+declare type ColorSet = string[];
+/**
+ * marker.js 2 display mode - `inline` or `popup`.
+ */
+declare type DisplayMode = 'inline' | 'popup';
+/**
+ * Default settings for marker.js 2 markers.
+ */
+declare class Settings {
+    /**
+     * List of colors used in color pickers.
+     */
+    defaultColorSet: ColorSet;
+    /**
+     * Default foreground color.
+     */
+    defaultColor: string;
+    /**
+     * Default fill color.
+     */
+    defaultFillColor: string;
+    /**
+     * Default stroke color for markers with background (eg. {@link CalloutMarker}).
+     */
+    defaultStrokeColor: string;
+    /**
+     * Default highlighter color.
+     */
+    defaultHighlightColor: string;
+    /**
+     * Default stroke (line) width.
+     */
+    defaultStrokeWidth: number;
+    /**
+     * Default line dash array
+     */
+    defaultStrokeDasharray: string;
+    /**
+     * Default opacity (alpha) of the {@link HighlightMarker} (and other highlighters).
+     */
+    defaultHighlightOpacity: number;
+    /**
+     * Default font family for text-based markers (eg. {@link TextMarker} and {@link CalloutMarker}).
+     *
+     */
+    defaultFontFamily: string;
+    /**
+     * Stroke (line) width options.
+     */
+    defaultStrokeWidths: number[];
+    /**
+     * Stroke dash array options.
+     */
+    defaultStrokeDasharrays: string[];
+    /**
+     * Opacity options.
+     */
+    defaultOpacitySteps: number[];
+    /**
+     * Default display mode.
+     */
+    displayMode: DisplayMode;
+    /**
+     * Font family options.
+     */
+    defaultFontFamilies: string[];
+    /**
+     * Margin in pixels between marker.js popup UI and window borders.
+     */
+    popupMargin: number;
+    /**
+     * Create a new Freehand marker for every stroke.
+     */
+    newFreehandMarkerOnPointerUp: boolean;
+    /**
+     * If set to true, when colors on a marker are changed
+     * it changes the default color for other markers as well.
+     *
+     * @since 2.7.0
+     */
+    defaultColorsFollowCurrentColors: boolean;
+    /**
+     * Increase this setting for smoother FreehandMarker lines.
+     * Note that it will also take more space when you save the state.
+     *
+     * @since 2.20.0
+     */
+    freehandPixelRatio: number;
+}
+
+/**
+ * Base class for all available and custom marker types.
+ *
+ * All markers used with marker.js 2 should be descendants of this class.
+ */
+declare class MarkerBase {
+    /**
+     * String type name of the marker type.
+     *
+     * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.
+     */
+    static typeName: string;
+    /**
+     * Instance property returning marker's type name.
+     *
+     * @since 2.16.0
+     */
+    get typeName(): string;
+    protected _container: SVGGElement;
+    /**
+     * SVG container object holding the marker's visual.
+     */
+    get container(): SVGGElement;
+    protected _overlayContainer: HTMLDivElement;
+    /**
+     * HTML container that can be used to render overlay objects while the marker is active.
+     *
+     * For example, this is used for the text editing layer while editing text in the {@see TextMarker}.
+     */
+    get overlayContainer(): HTMLDivElement;
+    protected _state: MarkerState;
+    /**
+     * Current marker state.
+     *
+     * Both MarkerArea and the marker itself can react differently to different events based on what state the marker is in.
+     */
+    get state(): MarkerState;
+    protected globalSettings: Settings;
+    /**
+     * Additional information about the marker
+     */
+    notes?: string;
+    /**
+     * Returns the list of toolbox panels for this marker type.
+     */
+    get toolboxPanels(): ToolboxPanel[];
+    /**
+     * Marker type title (display name) used for accessibility and other attributes.
+     */
+    static title: string;
+    /**
+     * SVG icon markup displayed on toolbar buttons.
+     */
+    static icon: string;
+    /**
+     * Method called when marker creation is finished.
+     */
+    onMarkerCreated: (marker: MarkerBase) => void;
+    /**
+     * Method to call when foreground color changes.
+     */
+    onColorChanged?: (color: string) => void;
+    /**
+     * Method to call when background/fill color changes.
+     */
+    onFillColorChanged?: (color: string) => void;
+    /**
+     * Creates a new marker.
+     *
+     * @param container - SVG container to hold marker's visual.
+     * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.
+     * @param settings - settings object containing default markers settings.
+     */
+    constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings);
+    /**
+     * Returns true if passed SVG element belongs to the marker. False otherwise.
+     *
+     * @param el - target element.
+     */
+    ownsTarget(el: EventTarget): boolean;
+    /**
+     * Is this marker selected?
+     *
+     * @since 2.16.0
+     */
+    protected _isSelected: boolean;
+    /**
+     * Returns true if the marker is currently selected
+     *
+     * @since 2.16.0
+     */
+    get isSelected(): boolean;
+    /**
+     * Selects this marker and displays appropriate selected marker UI.
+     */
+    select(): void;
+    /**
+     * Deselects this marker and hides selected marker UI.
+     */
+    deselect(): void;
+    /**
+     * Handles pointer (mouse, touch, stylus, etc.) down event.
+     *
+     * @param point - event coordinates.
+     * @param target - direct event target element.
+     */
+    pointerDown(point: IPoint, target?: EventTarget): void;
+    /**
+     * Handles pointer (mouse, touch, stylus, etc.) double click event.
+     *
+     * @param point - event coordinates.
+     * @param target - direct event target element.
+     */
+    dblClick(point: IPoint, target?: EventTarget): void;
+    /**
+     * Handles marker manipulation (move, resize, rotate, etc.).
+     *
+     * @param point - event coordinates.
+     */
+    manipulate(point: IPoint): void;
+    /**
+     * Handles pointer (mouse, touch, stylus, etc.) up event.
+     *
+     * @param point - event coordinates.
+     */
+    pointerUp(point: IPoint): void;
+    /**
+     * Disposes the marker and clean's up.
+     */
+    dispose(): void;
+    protected addMarkerVisualToContainer(element: SVGElement): void;
+    /**
+     * Returns current marker state that can be restored in the future.
+     */
+    getState(): MarkerBaseState;
+    /**
+     * Restores previously saved marker state.
+     *
+     * @param state - previously saved state.
+     */
+    restoreState(state: MarkerBaseState): void;
+    /**
+     * Scales marker. Used after the image resize.
+     *
+     * @param scaleX - horizontal scale
+     * @param scaleY - vertical scale
+     */
+    scale(scaleX: number, scaleY: number): void;
+    /**
+     * Called by a marker when its foreground color changes.
+     * @param color
+     */
+    protected colorChanged(color: string): void;
+    /**
+     * Called by a marker when its background/fill color changes.
+     * @param color
+     */
+    protected fillColorChanged(color: string): void;
+}
+
+/**
+ * Describes a MarkerArea state object used to save and restore marker.js state between sessions.
+ */
+interface MarkerAreaState {
+    /**
+     * Editing canvas width.
+     */
+    width: number;
+    /**
+     * Editing canvas height.
+     */
+    height: number;
+    /**
+     * States of individual markers.
+     */
+    markers: MarkerBaseState[];
+}
+
+/**
+ * Describes customizable marker.js UI settings.
+ */
+interface IStyleSettings {
+    /**
+     * Background color for the editor canvas when in popup mode.
+     */
+    canvasBackgroundColor?: string;
+    /**
+     * Background color of the toolbar block.
+     */
+    toolbarBackgroundColor?: string;
+    /**
+     * Background color of toolbar buttons on hover.
+     */
+    toolbarBackgroundHoverColor?: string;
+    /**
+     * Foreground color of toolbar icons.
+     */
+    toolbarColor?: string;
+    /**
+     * Base height of the toolbar block in pixels.
+     */
+    toolbarHeight?: number;
+    /**
+     * If set to true, the toolbar is hidden.
+     */
+    hideToolbar?: boolean;
+    /**
+     * If set to true, the toolbox is hidden.
+     */
+    hideToolbox?: boolean;
+    /**
+     * Is undo button visible?
+     *
+     * @since 2.6.0
+     */
+    undoButtonVisible?: boolean;
+    /**
+     * Is redo button visible?
+     *
+     * @since 2.6.0
+     */
+    redoButtonVisible?: boolean;
+    /**
+     * Is notes button visible?
+     *
+     * @since 2.10.0
+     */
+    notesButtonVisible?: boolean;
+    /**
+     * Is zoom button visible?
+     *
+     * @since 2.12.0
+     */
+    zoomButtonVisible?: boolean;
+    /**
+     * Is zoom out button visible?
+     *
+     * @since 2.13.0
+     */
+    zoomOutButtonVisible?: boolean;
+    /**
+     * Is clear button visible?
+     *
+     * @since 2.15.0
+     */
+    clearButtonVisible?: boolean;
+    /**
+     * Are render and close buttons visible?
+     *
+     * @since 2.18.0
+     */
+    resultButtonBlockVisible?: boolean;
+    /**
+     * Background color of the toolbox (property panel) block.
+     */
+    toolboxBackgroundColor?: string;
+    /**
+     * Foreground color of toolbox buttons and objects.
+     */
+    toolboxColor?: string;
+    /**
+     * Accent color for selected toolbox objects.
+     */
+    toolboxAccentColor?: string;
+    /**
+     * Custom icon color for the select (pointer) toolbar button
+     */
+    selectButtonColor?: string;
+    /**
+     * Custom icon color for the delete toolbar button
+     */
+    deleteButtonColor?: string;
+    /**
+     * Custom icon color for the OK (render) toolbar button
+     */
+    okButtonColor?: string;
+    /**
+     * Custom icon color for the close (cancel) toolbar button
+     */
+    closeButtonColor?: string;
+    /**
+     * CSS class name defining the visual style of the toolbar block.
+     *
+     * _Note_: should only be used for colors and similar styles. Changing layout-related styles here can break the UI.
+     */
+    toolbarStyleColorsClassName?: string;
+    /**
+     * CSS class name defining the visual style of the toolbar overflow block.
+     * Displayed when markers don't fit in the main toolbar block.
+     *
+     * _Note_: should only be used for colors and similar styles. Changing layout-related styles here can break the UI.
+     */
+    toolbarOverflowBlockStyleColorsClassName?: string;
+    /**
+     * CSS class name defining the visual style of the toolbar buttons.
+     *
+     * _Note_: should only be used for colors and similar styles. Changing layout-related styles here can break the UI.
+     */
+    toolbarButtonStyleColorsClassName?: string;
+    /**
+     * CSS class name defining the visual style of the active (selected) toolbar button.
+     *
+     * _Note_: should only be used for colors and similar styles. Changing layout-related styles here can break the UI.
+     */
+    toolbarActiveButtonStyleColorsClassName?: string;
+    /**
+     * CSS class name defining the visual style of the toolbox (property panel) block.
+     *
+     * _Note_: should only be used for colors and similar styles. Changing layout-related styles here can break the UI.
+     */
+    toolboxStyleColorsClassName?: string;
+    /**
+     * CSS class name defining the visual style of the toolbox buttons.
+     *
+     * _Note_: should only be used for colors and similar styles. Changing layout-related styles here can break the UI.
+     */
+    toolboxButtonStyleColorsClassName?: string;
+    /**
+     * CSS class name defining the visual style of the active (selected) toolbox button.
+     *
+     * _Note_: should only be used for colors and similar styles. Changing layout-related styles here can break the UI.
+     */
+    toolboxActiveButtonStyleColorsClassName?: string;
+    /**
+     * CSS class name defining the visual style of the panel containing toolbox buttons.
+     * That is the top level panel with buttons switching active toolbox panels.
+     *
+     * _Note_: should only be used for colors and similar styles. Changing layout-related styles here can break the UI.
+     */
+    toolboxButtonRowStyleColorsClassName?: string;
+    /**
+     * CSS class name defining the visual style of the panel containing specific toolbox properties.
+     * This is the popup panel that opens when a toolbox button is pressed.
+     *
+     * _Note_: should only be used for colors and similar styles. Changing layout-related styles here can break the UI.
+     */
+    toolboxPanelRowStyleColorsClassName?: string;
+    /**
+     * CSS class name defining the visual style of the note editing text area.
+     *
+     * @since 2.10.0
+     */
+    notesAreaStyleClassName?: string;
+    /**
+     * Position logo in the free version on the bottom left or right of the marker area. Default - left.
+     *
+     * @since 2.14.0
+     */
+    logoPosition?: 'left' | 'right';
+    /**
+     * zIndex for the marker.js UI.
+     *
+     * Defaults to 5 in inline mode and 1000 in popup mode.
+     *
+     * @since 2.15.0
+     */
+    zIndex?: string;
+}
+
+declare class MarkerAreaEvent {
+    markerArea: MarkerArea;
+    cancelable: boolean;
+    private _defaultPrevented;
+    get defaultPrevented(): boolean;
+    preventDefault(): void;
+    constructor(markerArea: MarkerArea, cancelable?: boolean);
+}
+declare class MarkerAreaRenderEvent extends MarkerAreaEvent {
+    dataUrl: string;
+    state: MarkerAreaState;
+    constructor(markerArea: MarkerArea, dataUrl: string, state: MarkerAreaState);
+}
+declare class MarkerEvent extends MarkerAreaEvent {
+    marker?: MarkerBase;
+    constructor(markerArea: MarkerArea, marker?: MarkerBase, cancelable?: boolean);
+}
+/**
+ * General MarkerArea event handler type.
+ */
+declare type MarkerAreaEventHandler = (event: MarkerAreaEvent) => void;
+/**
+ * MarkerArea render event handler type.
+ */
+declare type MarkerAreaRenderEventHandler = (event: MarkerAreaRenderEvent) => void;
+/**
+ * Marker event handler type.
+ */
+declare type MarkerEventHandler = (event: MarkerEvent) => void;
+/**
+ * Describes a repository of MarkerArea event handlers.
+ */
+interface IEventListenerRepository {
+    /**
+     * Event handlers for the `render` event.
+     */
+    render: MarkerAreaRenderEventHandler[];
+    /**
+     * Event handlers for the `beforeclose` event.
+     */
+    beforeclose: MarkerAreaEventHandler[];
+    /**
+     * Event handlers for the `close` event.
+     */
+    close: MarkerAreaEventHandler[];
+    /**
+     * Event handlers for the `show` event.
+     */
+    show: MarkerAreaEventHandler[];
+    /**
+     * Event handlers for the `restorestate` event.
+     */
+    restorestate: MarkerAreaEventHandler[];
+    /**
+     * Event handlers for the `markerselect` event.
+     */
+    markerselect: MarkerEventHandler[];
+    /**
+     * Event handlers for the `markerdeselect` event.
+     */
+    markerdeselect: MarkerEventHandler[];
+    /**
+     * Event handlers for the `markercreating` event.
+     */
+    markercreating: MarkerEventHandler[];
+    /**
+     * Event handlers for the `markercreated` event.
+     */
+    markercreate: MarkerEventHandler[];
+    /**
+     * Event handlers for the `markerbeforedelete` event.
+     */
+    markerbeforedelete: MarkerEventHandler[];
+    /**
+     * Event handlers for the `markerdelete` event.
+     */
+    markerdelete: MarkerEventHandler[];
+    /**
+     * Event handlers for the `focus` event.
+     *
+     * @since 2.19.0
+     */
+    focus: MarkerAreaEventHandler[];
+    /**
+     * Event handlers for the `blur` event.
+     *
+     * @since 2.19.0
+     */
+    blur: MarkerAreaEventHandler[];
+}
+/**
+ * Event handler type for a specific event type.
+ */
+declare type EventHandler<T extends keyof IEventListenerRepository> = T extends 'markerselect' ? MarkerEventHandler : T extends 'markerdeselect' ? MarkerEventHandler : T extends 'markercreating' ? MarkerEventHandler : T extends 'markercreate' ? MarkerEventHandler : T extends 'markerbeforedelete' ? MarkerEventHandler : T extends 'markerdelete' ? MarkerEventHandler : T extends 'render' ? MarkerAreaRenderEventHandler : MarkerAreaEventHandler;
+/**
+ * Event handler repository.
+ */
+declare class EventListenerRepository implements IEventListenerRepository {
+    /**
+     * Event handlers for the `render` event.
+     */
+    render: MarkerAreaRenderEventHandler[];
+    /**
+     * Event handlers for the `beforeclose` event.
+     */
+    beforeclose: MarkerAreaEventHandler[];
+    /**
+     * Event handlers for the `close` event.
+     */
+    close: MarkerAreaEventHandler[];
+    /**
+     * Event handlers for the `show` event.
+     */
+    show: MarkerAreaEventHandler[];
+    /**
+     * Event handlers for the `restorestate` event.
+     */
+    restorestate: MarkerAreaEventHandler[];
+    /**
+     * Event handlers for the `markerselect` event.
+     */
+    markerselect: MarkerEventHandler[];
+    /**
+     * Event handlers for the `markerdeselect` event.
+     */
+    markerdeselect: MarkerEventHandler[];
+    /**
+     * Event handlers for the `markercreating` event.
+     */
+    markercreating: MarkerEventHandler[];
+    /**
+     * Event handlers for the `markercreate` event.
+     */
+    markercreate: MarkerEventHandler[];
+    /**
+     * Event handlers for the `markerbeforedelete` event.
+     */
+    markerbeforedelete: MarkerEventHandler[];
+    /**
+     * Event handlers for the `markerdelete` event.
+     */
+    markerdelete: MarkerEventHandler[];
+    /**
+     * Event handlers for the `focus` event.
+     *
+     * @since 2.19.0
+     */
+    focus: MarkerAreaEventHandler[];
+    /**
+     * Event handlers for the `blur` event.
+     *
+     * @since 2.19.0
+     */
+    blur: MarkerAreaEventHandler[];
+    /**
+     * Add an event handler for a specific event type.
+     * @param eventType - event type.
+     * @param handler - function to handle the event.
+     */
+    addEventListener<T extends keyof IEventListenerRepository>(eventType: T, handler: EventHandler<T>): void;
+    /**
+     * Remove an event handler for a specific event type.
+     * @param eventType - event type.
+     * @param handler - function currently handling the event.
+     */
+    removeEventListener<T extends keyof IEventListenerRepository>(eventType: T, handler: EventHandler<T>): void;
+}
+
+/**
+ * Identifier for marker type when setting {@linkcode availableMarkerTypes}.
+ * Marker type can be set as either a string or a marker type reference.
+ */
+declare type MarkerTypeIdentifier = string | typeof MarkerBase;
+/**
+ * Event handler type for {@linkcode MarkerArea} `render` event.
+ */
+declare type RenderEventHandler = (dataURL: string, state?: MarkerAreaState) => void;
+/**
+ * Event handler type for {@linkcode MarkerArea} `close` event.
+ */
+declare type CloseEventHandler = () => void;
+/**
+ * MarkerArea is the main class of marker.js 2. It controls the behavior and appearance of the library.
+ *
+ * The simplest marker.js 2 usage scenario looks something like this:
+ *
+ * ```typescript
+ * import * as markerjs2 from 'markerjs2';
+ * // create an instance of MarkerArea and pass the target image reference as a parameter
+ * let markerArea = new markerjs2.MarkerArea(document.getElementById('myimg'));
+ *
+ * // register an event listener for when user clicks OK/save in the marker.js UI
+ * markerArea.addEventListener('render', event => {
+ *   // we are setting the markup result to replace our original image on the page
+ *   // but you can set a different image or upload it to your server
+ *   document.getElementById('myimg').src = event.dataUrl;
+ * });
+ *
+ * // finally, call the show() method and marker.js UI opens
+ * markerArea.show();
+ * ```
+ */
+declare class MarkerArea {
+    private target;
+    private targetObserver;
+    private width;
+    private height;
+    private imageWidth;
+    private imageHeight;
+    private left;
+    private top;
+    private windowHeight;
+    private markerImage;
+    private markerImageHolder;
+    private defs;
+    private coverDiv;
+    private uiDiv;
+    private contentDiv;
+    private editorCanvas;
+    private editingTarget;
+    private overlayContainer;
+    private touchPoints;
+    private logoUI;
+    /**
+     * `targetRoot` is used to set an alternative positioning root for the marker.js UI.
+     *
+     * This is useful in cases when your target image is positioned, say, inside a div with `position: relative;`
+     *
+     * ```typescript
+     * // set targetRoot to a specific div instead of document.body
+     * markerArea.targetRoot = document.getElementById('myRootElement');
+     * ```
+     *
+     * @default document.body
+     */
+    targetRoot: HTMLElement;
+    /**
+     * Returns a list of all built-in marker types for use with {@linkcode availableMarkerTypes}
+     *
+     * @readonly
+     */
+    get ALL_MARKER_TYPES(): typeof MarkerBase[];
+    /**
+     * Returns a list of default set of built-in marker types.
+     * Used when {@linkcode availableMarkerTypes} isn't set explicitly.
+     *
+     * @readonly
+     */
+    get DEFAULT_MARKER_TYPES(): typeof MarkerBase[];
+    /**
+     * Returns a short list of essential built-in marker types for use with {@linkcode availableMarkerTypes}
+     *
+     * @readonly
+     */
+    get BASIC_MARKER_TYPES(): typeof MarkerBase[];
+    private _availableMarkerTypes;
+    /**
+     * Gets or sets a list of marker types avaiable to the user in the toolbar.
+     * The types can be passed as either type reference or a string type name.
+     *
+     * ```typescript
+     * this.markerArea1.availableMarkerTypes = ['CalloutMarker', ...this.markerArea1.BASIC_MARKER_TYPES];
+     * ```
+     *
+     * @default {@linkcode DEFAULT_MARKER_TYPES}
+     */
+    get availableMarkerTypes(): MarkerTypeIdentifier[];
+    set availableMarkerTypes(value: MarkerTypeIdentifier[]);
+    private toolbar;
+    private toolbox;
+    private mode;
+    private currentMarker?;
+    private markers;
+    private isDragging;
+    private bodyOverflowState;
+    private scrollYState;
+    private scrollXState;
+    private renderEventListeners;
+    private closeEventListeners;
+    settings: Settings;
+    uiStyleSettings: IStyleSettings;
+    private _isOpen;
+    /**
+     * Returns `true` when MarkerArea is open and `false` otherwise.
+     *
+     * @readonly
+     */
+    get isOpen(): boolean;
+    private undoRedoManager;
+    /**
+     * When set to true resulting image will be rendered at the natural (original) resolution
+     * of the target image. Otherwise (default), screen dimensions of the image are used.
+     *
+     * @default false (use screen dimensions)
+     */
+    renderAtNaturalSize: boolean;
+    /**
+     * Type of image for the rendering result. Eg. `image/png` (default) or `image/jpeg`.
+     *
+     * @default `image/png`
+     */
+    renderImageType: string;
+    /**
+     * When rendering engine/format supports it (jpeg, for exmample),
+     * sets the rendering quality for the resulting image.
+     *
+     * In case of `image/jpeg` the value should be between 0 (worst quality) and 1 (best quality).
+     */
+    renderImageQuality?: number;
+    /**
+     * When set to `true`, will render only the marker layer without the original image.
+     * This could be useful when you want to non-destructively overlay markers on top of the original image.
+     *
+     * Note that in order for the markers layer to have a transparent background {@linkcode renderImageType}
+     * should be set to a format supporting transparency, such as `image/png`.
+     *
+     * @default false
+     */
+    renderMarkersOnly: boolean;
+    /**
+     * When set and {@linkcode renderAtNaturalSize} is `false` sets the width of the rendered image.
+     *
+     * Both `renderWidth` and `renderHeight` have to be set for this to take effect.
+     */
+    renderWidth?: number;
+    /**
+     * When set and {@linkcode renderAtNaturalSize} is `false` sets the height of the rendered image.
+     *
+     * Both `renderWidth` and `renderHeight` have to be set for this to take effect.
+     */
+    renderHeight?: number;
+    /**
+     * If a canvas is specified here, then marker.js will render the output to this canvas
+     * in addition to generating an image.
+     *
+     * @since 2.14.0
+     */
+    renderTarget?: HTMLCanvasElement;
+    /**
+     * Pressing zoom button iterates through values in this array.
+     *
+     * @since 2.12.0
+     */
+    zoomSteps: number[];
+    private _zoomLevel;
+    /**
+     * Gets current zoom level.
+     *
+     * @since 2.12.0
+     */
+    get zoomLevel(): number;
+    /**
+     * Sets current zoom level.
+     *
+     * @since 2.12.0
+     */
+    set zoomLevel(value: number);
+    /**
+     * Creates a new MarkerArea for the specified target image.
+     *
+     * ```typescript
+     * // create an instance of MarkerArea and pass the target image (or other HTML element) reference as a parameter
+     * let markerArea = new markerjs2.MarkerArea(document.getElementById('myimg'));
+     * ```
+     *
+     * When `target` is not an image object the output is limited to "markers only" (@linkcode renderMarkersOnly)
+     * and "popup" mode won't work properly as the target object stays in it's original position and, unlike images,
+     * is not copied.
+     *
+     * @param target image object to mark up.
+     */
+    constructor(target: HTMLImageElement | HTMLElement);
+    private open;
+    /**
+     * Initializes the MarkerArea and opens the UI.
+     */
+    show(): void;
+    /**
+     * Renders the annotation result.
+     *
+     * Normally, you should use {@linkcode addEventListener} method to set a listener for the `render` event
+     * rather than calling this method directly.
+     */
+    render(): Promise<string>;
+    /**
+     * Closes the MarkerArea UI.
+     */
+    close(suppressBeforeClose?: boolean): void;
+    /**
+     * Adds one or more markers to the toolbar.
+     *
+     * @param markers - one or more marker types to be added.
+     */
+    addMarkersToToolbar(...markers: typeof MarkerBase[]): void;
+    /**
+     * Add a `render` event listener which is called when user clicks on the OK/save button
+     * in the toolbar.
+     *
+     * ```typescript
+     * // register an event listener for when user clicks OK/save in the marker.js UI
+     * markerArea.addRenderEventListener(dataUrl => {
+     *   // we are setting the markup result to replace our original image on the page
+     *   // but you can set a different image or upload it to your server
+     *   document.getElementById('myimg').src = dataUrl;
+     * });
+     * ```
+     *
+     * This is where you place your code to save a resulting image and/or MarkerAreaState.
+     *
+     * @param listener - a method handling rendering results
+     *
+     * @see {@link MarkerAreaState}
+     * @deprecated use `addEventListener('render', ...)` instead.
+     */
+    addRenderEventListener(listener: RenderEventHandler): void;
+    /**
+     * Remove a `render` event handler.
+     *
+     * @param listener - previously registered `render` event handler.
+     * @deprecated use `removeEventListener('render', ...)` instead.
+     */
+    removeRenderEventListener(listener: RenderEventHandler): void;
+    /**
+     * Add a `close` event handler to perform actions in your code after the user
+     * clicks on the close button (without saving).
+     *
+     * @param listener - close event listener
+     * @deprecated use `addEventListener('close', ...)` instead.
+     */
+    addCloseEventListener(listener: CloseEventHandler): void;
+    /**
+     * Remove a `close` event handler.
+     *
+     * @param listener - previously registered `close` event handler.
+     * @deprecated use `removeEventListener('close', ...)` instead.
+     */
+    removeCloseEventListener(listener: CloseEventHandler): void;
+    private setupResizeObserver;
+    private onPopupTargetResize;
+    private setWindowHeight;
+    private resize;
+    private scaleMarkers;
+    private setEditingTarget;
+    private setTopLeft;
+    private initMarkerCanvas;
+    /**
+     * Adds "defs" element to the marker SVG element.
+     * Useful for using custom fonts and potentially other scenarios.
+     *
+     * @param {(...(string | Node)[])} nodes
+     * @see Documentation article on adding custom fonts for an example
+     */
+    addDefs(...nodes: (string | Node)[]): void;
+    private initOverlay;
+    private positionMarkerImage;
+    private attachEvents;
+    private attachWindowEvents;
+    private detachEvents;
+    private detachWindowEvents;
+    /**
+     * NOTE:
+     *
+     * before removing or modifying this method please consider supporting marker.js
+     * by visiting https://markerjs.com/#price for details
+     *
+     * thank you!
+     */
+    private addLogo;
+    private positionLogo;
+    private overrideOverflow;
+    private restoreOverflow;
+    private showUI;
+    private closeUI;
+    private removeMarker;
+    private switchToSelectMode;
+    private toolbarButtonClicked;
+    /**
+     * Removes currently selected marker.
+     */
+    deleteSelectedMarker(): void;
+    /**
+     * Removes all markers.
+     *
+     * @since 2.15.0
+     */
+    clear(): void;
+    private notesArea?;
+    private get isNotesAreaOpen();
+    private showNotesEditor;
+    private hideNotesEditor;
+    private selectLastMarker;
+    private addUndoStep;
+    /**
+     * Undo last action.
+     *
+     * @since 2.6.0
+     */
+    undo(): void;
+    /**
+     * Redo previously undone action.
+     *
+     * @since 2.6.0
+     */
+    redo(): void;
+    /**
+     * Iterate zoom steps (@linkcode zoomSteps).
+     * Next zoom level is selected or returns to the first zoom level restarting the sequence.
+     *
+     * @since 2.12.0
+     */
+    stepZoom(): void;
+    private prevPanPoint;
+    private panTo;
+    /**
+     * Initiates markup rendering.
+     *
+     * Get results by adding a render event listener via {@linkcode addRenderEventListener}.
+     */
+    startRenderAndClose(): Promise<void>;
+    /**
+     * Returns the complete state for the MarkerArea that can be preserved and used
+     * to continue annotation next time.
+     *
+     * @param deselectCurrentMarker - when `true` is passed, currently selected marker will be deselected before getting the state.
+     */
+    getState(deselectCurrentMarker?: boolean): MarkerAreaState;
+    /**
+     * Restores MarkerArea state to continue previous annotation session.
+     *
+     * **IMPORTANT**: call `restoreState()` __after__ you've opened the MarkerArea with {@linkcode show}.
+     *
+     * ```typescript
+     * this.markerArea1.show();
+     * if (this.currentState) {
+     *   this.markerArea1.restoreState(this.currentState);
+     * }
+     * ```
+     *
+     * @param state - previously saved state object.
+     */
+    restoreState(state: MarkerAreaState): void;
+    private addNewMarker;
+    /**
+     * Initiate new marker creation.
+     *
+     * marker.js switches to marker creation mode for the marker type specified
+     * and users can draw a new marker like they would by pressing a corresponding
+     * toolbar button.
+     *
+     * This example initiates creation of a `FrameMarker`:
+     * ```typescript
+     * this.markerArea1.createNewMarker(FrameMarker);
+     * ```
+     *
+     * @param markerType
+     */
+    createNewMarker(markerType: typeof MarkerBase | string): void;
+    private markerCreated;
+    private colorChanged;
+    private fillColorChanged;
+    /**
+     * Sets the currently selected marker or deselects it if no parameter passed.
+     *
+     * @param marker marker to select. Deselects current marker if undefined.
+     */
+    setCurrentMarker(marker?: MarkerBase): void;
+    private onPointerDown;
+    private onDblClick;
+    private onPointerMove;
+    private onPointerUp;
+    private onPointerOut;
+    private onKeyUp;
+    private clientToLocalCoordinates;
+    private onWindowResize;
+    private positionUI;
+    /**
+     * Add license key.
+     *
+     * This is a proxy method for {@linkcode Activator.addKey()}.
+     *
+     * @param key - commercial license key.
+     */
+    addLicenseKey(key: string): void;
+    private eventListeners;
+    /**
+     * Adds an event listener for one of the marker.js Live events.
+     *
+     * @param eventType - type of the event.
+     * @param handler - function handling the event.
+     *
+     * @since 2.16.0
+     */
+    addEventListener<T extends keyof IEventListenerRepository>(eventType: T, handler: EventHandler<T>): void;
+    /**
+     * Removes an event listener for one of the marker.js Live events.
+     *
+     * @param eventType - type of the event.
+     * @param handler - function currently handling the event.
+     *
+     * @since 2.16.0
+     */
+    removeEventListener<T extends keyof IEventListenerRepository>(eventType: T, handler: EventHandler<T>): void;
+    private _silentRenderMode;
+    /**
+     * Renders previously saved state without user intervention.
+     *
+     * The rendered image is returned to the `render` event handlers (as in the regular interactive process).
+     * Rendering options set on `MarkerArea` are respected.
+     *
+     * @param state state to render
+     *
+     * @since 2.17.0
+     */
+    renderState(state: MarkerAreaState): void;
+    private _isFocused;
+    /**
+     * Returns true when this MarkerArea is focused.
+     *
+     * @since 2.19.0
+     */
+    get isFocused(): boolean;
+    private _previousCurrentMarker?;
+    /**
+     * Focuses the MarkerArea to receive all input from the window.
+     *
+     * Is called automatically when user clicks inside of the marker area. Call manually to set focus explicitly.
+     *
+     * @since 2.19.0
+     */
+    focus(): void;
+    /**
+     * Tells MarkerArea to stop reacting to input outside of the immediate marker image.
+     *
+     * Call `focus()` to re-enable.
+     *
+     * @since 2.19.0
+     */
+    blur(): void;
+}
+
+/**
+ * Manages commercial marker.js 2 licenses.
+ */
+declare class Activator {
+    private static key;
+    /**
+     * Add a license key
+     * @param key license key sent to you after purchase.
+     */
+    static addKey(key: string): void;
+    /**
+     * Returns true if the copy of marker.js is commercially licensed.
+     */
+    static get isLicensed(): boolean;
+}
+
+/**
+ * Utility class to simplify SVG operations.
+ */
+declare class SvgHelper {
+    /**
+     * Creates SVG "defs".
+     */
+    static createDefs(): SVGDefsElement;
+    /**
+     * Sets attributes on an arbitrary SVG element
+     * @param el - target SVG element.
+     * @param attributes - set of name-value attribute pairs.
+     */
+    static setAttributes(el: SVGElement, attributes: Array<[string, string]>): void;
+    /**
+     * Creates an SVG rectangle with the specified width and height.
+     * @param width
+     * @param height
+     * @param attributes - additional attributes.
+     */
+    static createRect(width: number | string, height: number | string, attributes?: Array<[string, string]>): SVGRectElement;
+    /**
+     * Creates an SVG line with specified end-point coordinates.
+     * @param x1
+     * @param y1
+     * @param x2
+     * @param y2
+     * @param attributes - additional attributes.
+     */
+    static createLine(x1: number | string, y1: number | string, x2: number | string, y2: number | string, attributes?: Array<[string, string]>): SVGLineElement;
+    /**
+     * Creates an SVG polygon with specified points.
+     * @param points - points as string.
+     * @param attributes - additional attributes.
+     */
+    static createPolygon(points: string, attributes?: Array<[string, string]>): SVGPolygonElement;
+    /**
+     * Creates an SVG circle with the specified radius.
+     * @param radius
+     * @param attributes - additional attributes.
+     */
+    static createCircle(radius: number, attributes?: Array<[string, string]>): SVGCircleElement;
+    /**
+     * Creates an SVG ellipse with the specified horizontal and vertical radii.
+     * @param rx
+     * @param ry
+     * @param attributes - additional attributes.
+     */
+    static createEllipse(rx: number, ry: number, attributes?: Array<[string, string]>): SVGEllipseElement;
+    /**
+     * Creates an SVG group.
+     * @param attributes - additional attributes.
+     */
+    static createGroup(attributes?: Array<[string, string]>): SVGGElement;
+    /**
+     * Creates an SVG transform.
+     */
+    static createTransform(): SVGTransform;
+    /**
+     * Creates an SVG marker.
+     * @param id
+     * @param orient
+     * @param markerWidth
+     * @param markerHeight
+     * @param refX
+     * @param refY
+     * @param markerElement
+     */
+    static createMarker(id: string, orient: string, markerWidth: number | string, markerHeight: number | string, refX: number | string, refY: number | string, markerElement: SVGGraphicsElement): SVGMarkerElement;
+    /**
+     * Creaes an SVG text element.
+     * @param attributes - additional attributes.
+     */
+    static createText(attributes?: Array<[string, string]>): SVGTextElement;
+    /**
+     * Creates an SVG TSpan.
+     * @param text - inner text.
+     * @param attributes - additional attributes.
+     */
+    static createTSpan(text: string, attributes?: Array<[string, string]>): SVGTSpanElement;
+    /**
+     * Creates an SVG image element.
+     * @param attributes - additional attributes.
+     */
+    static createImage(attributes?: Array<[string, string]>): SVGImageElement;
+    /**
+     * Creates an SVG point with the specified coordinates.
+     * @param x
+     * @param y
+     */
+    static createPoint(x: number, y: number): SVGPoint;
+    /**
+     * Creates an SVG path with the specified shape (d).
+     * @param d - path shape
+     * @param attributes - additional attributes.
+     */
+    static createPath(d: string, attributes?: Array<[string, string]>): SVGPathElement;
+}
+
+/**
+ * Simple utility CSS-in-JS implementation.
+ */
+declare class Style {
+    /**
+     * Prefix used for all internally created CSS classes.
+     */
+    static CLASS_PREFIX: string;
+    private static classes;
+    private static rules;
+    private static styleSheet?;
+    /**
+     * For cases when you need to add the stylesheet to anything
+     * other than document.head (default), set this property
+     * befor calling `MarkerArea.show()`.
+     *
+     * Example: here we set the rendering/placement root (targetRoot)
+     * to the `shadowRoot` of a web componet and set `styleSheetRoot`
+     * to the same value as well.
+     *
+     * ```javascript
+     * const markerArea = new markerjs2.MarkerArea(target);
+     * markerArea.targetRoot = this.shadowRoot;
+     * markerjs2.Style.styleSheetRoot = this.shadowRoot;
+     * markerArea.show();
+     * ```
+     *
+     * Known issue/limitation:
+     * you can't use marker.js 2 in both main and Shadow DOM
+     * on the same page.
+     */
+    static styleSheetRoot: HTMLElement;
+    /**
+     * Returns default UI styles.
+     */
+    static get defaultSettings(): IStyleSettings;
+    /**
+     * Holds current UI styles.
+     */
+    static settings: IStyleSettings;
+    /**
+     * Returns global fade-in animation class name.
+     */
+    static get fadeInAnimationClassName(): string;
+    /**
+     * Returns global fade-out animation class name.
+     */
+    static get fadeOutAnimationClassName(): string;
+    /**
+     * Adds a CSS class declaration.
+     * @param styleClass - class to add.
+     */
+    static addClass(styleClass: StyleClass): StyleClass;
+    /**
+     * Add arbitrary CSS rule
+     * @param styleRule - CSS rule to add.
+     */
+    static addRule(styleRule: StyleRule): void;
+    private static addStyleSheet;
+    static removeStyleSheet(): void;
+}
+/**
+ * Represents an arbitrary CSS rule.
+ */
+declare class StyleRule {
+    /**
+     * CSS selector.
+     */
+    selector: string;
+    /**
+     * Style declaration for the rule.
+     */
+    style: string;
+    /**
+     * Creates an arbitrary CSS rule using the selector and style rules.
+     * @param selector - CSS selector
+     * @param style - styles to apply
+     */
+    constructor(selector: string, style: string);
+}
+/**
+ * Represents a CSS class.
+ */
+declare class StyleClass {
+    /**
+     * CSS style rules for the class.
+     */
+    style: string;
+    private _localName;
+    /**
+     * Returns fully qualified CSS class name.
+     */
+    get name(): string;
+    /**
+     * Creates a CSS class declaration based on supplied (local) name and style rules.
+     * @param name - local CSS class name (will be prefixed with the marker.js prefix).
+     * @param style - style declarations.
+     */
+    constructor(name: string, style: string);
+}
+
+/**
+ * Represents a simplified version of the SVGMatrix.
+ */
+interface ITransformMatrix {
+    a: number;
+    b: number;
+    c: number;
+    d: number;
+    e: number;
+    f: number;
+}
+/**
+ * A utility class to transform between SVGMatrix and its simplified representation.
+ */
+declare class TransformMatrix {
+    static toITransformMatrix(matrix: SVGMatrix): ITransformMatrix;
+    static toSVGMatrix(currentMatrix: SVGMatrix, newMatrix: ITransformMatrix): SVGMatrix;
+}
+
+/**
+ * Represents available arrow types.
+ *
+ * - `both` - arrow tips on both sides.
+ * - `start` - arrow tip on the starting point of line.
+ * - `end` - arrow tip on the ending point of line.
+ * - `none` - no arrow tips.
+ */
+declare type ArrowType = 'both' | 'start' | 'end' | 'none';
+/**
+ * Handler for arrow type change event.
+ */
+declare type ArrowTypeChangeHandler = (newType: ArrowType) => void;
+/**
+ * Arrow type selection panel.
+ */
+declare class ArrowTypePanel extends ToolboxPanel {
+    private currentType?;
+    private typeBoxes;
+    /**
+     * Event handler for the arrow type change event.
+     */
+    onArrowTypeChanged?: ArrowTypeChangeHandler;
+    /**
+     * Creates an ArrowTypePanel.
+     * @param title - panel title.
+     * @param currentType - currently set arrow type.
+     * @param icon - panel button icon (SVG image markup).
+     */
+    constructor(title: string, currentType?: ArrowType, icon?: string);
+    /**
+     * Returns panel UI.
+     */
+    getUi(): HTMLDivElement;
+    private setCurrentType;
+}
+
+/**
+ * Handler type for the color change event.
+ */
+declare type ColorChangeHandler = (newColor: string) => void;
+/**
+ * Color picker panel.
+ */
+declare class ColorPickerPanel extends ToolboxPanel {
+    colors: string[];
+    private currentColor?;
+    private addTransparent;
+    private colorBoxes;
+    /**
+     * Color change event handler.
+     */
+    onColorChanged?: ColorChangeHandler;
+    /**
+     * Creates a color picker panel.
+     * @param title - panel title.
+     * @param colors - available colors.
+     * @param currentColor - currently selected color.
+     * @param icon - panel button icon (SVG imager markup).
+     */
+    constructor(title: string, colors: string[], currentColor?: string, icon?: string);
+    /**
+     * Returns panel UI.
+     */
+    getUi(): HTMLDivElement;
+    private getColorBox;
+    private setCurrentColor;
+}
+
+/**
+ * Font change event handler type.
+ */
+declare type FontChangeHandler = (newFont: string) => void;
+/**
+ * Font family selection toolbox panel.
+ */
+declare class FontFamilyPanel extends ToolboxPanel {
+    private fonts;
+    private currentFont?;
+    private fontBoxes;
+    /**
+     * Handler for the font family change event.
+     */
+    onFontChanged?: FontChangeHandler;
+    /**
+     * Creates a font family toolbox panel.
+     * @param title - panel title.
+     * @param fonts - available font families.
+     * @param currentFont - currently selected font family.
+     * @param icon - panel button icon (SVG image markup).
+     */
+    constructor(title: string, fonts: string[], currentFont?: string, icon?: string);
+    /**
+     * Returns panel UI.
+     */
+    getUi(): HTMLDivElement;
+    private setCurrentFont;
+}
+
+/**
+ * Line style change event handler type.
+ */
+declare type StyleChangeHandler = (newStyle: string) => void;
+/**
+ * Line style (solid, dashed, etc.) toolbox panel.
+ */
+declare class LineStylePanel extends ToolboxPanel {
+    private styles;
+    private currentStyle?;
+    private styleBoxes;
+    /**
+     * Handler for the style change event.
+     */
+    onStyleChanged?: StyleChangeHandler;
+    /**
+     * Creates a line style toolbox panel.
+     * @param title - panel title
+     * @param styles - available line styles (dash array).
+     * @param currentStyle - currently selected style.
+     * @param icon - panel button icon (SVG image markup).
+     */
+    constructor(title: string, styles: string[], currentStyle?: string, icon?: string);
+    /**
+     * Returns panel UI.
+     */
+    getUi(): HTMLDivElement;
+    private setCurrentStyle;
+}
+
+/**
+ * Line width change event handler type.
+ */
+declare type WidthChangeHandler = (newWidth: number) => void;
+/**
+ * Line width toolbox panel.
+ */
+declare class LineWidthPanel extends ToolboxPanel {
+    private widths;
+    private currentWidth?;
+    private widthBoxes;
+    /**
+     * Line width change event handler.
+     */
+    onWidthChanged?: WidthChangeHandler;
+    /**
+     * Creates a line width toolbox panel.
+     * @param title - panel title.
+     * @param widths - available widths.
+     * @param currentWidth - currently set width.
+     * @param icon - toolbox panel icon (SVG image markup).
+     */
+    constructor(title: string, widths: number[], currentWidth?: number, icon?: string);
+    /**
+     * Returns panel UI.
+     */
+    getUi(): HTMLDivElement;
+    private setCurrentWidth;
+}
+
+/**
+ * Opacity chage event handler type.
+ */
+declare type OpacityChangeHandler = (newOpacity: number) => void;
+/**
+ * Opacity panel.
+ */
+declare class OpacityPanel extends ToolboxPanel {
+    private opacities;
+    private currentOpacity?;
+    private opacityBoxes;
+    /**
+     * Opacity change event handler.
+     */
+    onOpacityChanged?: OpacityChangeHandler;
+    /**
+     * Creates an opacity panel.
+     * @param title - panel title.
+     * @param opacities - available opacities.
+     * @param currentOpacity - current opacity.
+     * @param icon - toolbox panel button (SVG image markup).
+     */
+    constructor(title: string, opacities: number[], currentOpacity?: number, icon?: string);
+    /**
+     * Returns panel UI.
+     */
+    getUi(): HTMLDivElement;
+    private setCurrentOpacity;
+}
+
+/**
+ * Represents a single resize-manipulation grip used in marker's manipulation controls.
+ */
+declare class ResizeGrip {
+    /**
+     * Grip's visual element.
+     */
+    visual: SVGGraphicsElement;
+    /**
+     * Grip's size (raduis).
+     */
+    readonly GRIP_SIZE = 10;
+    /**
+     * Creates a new grip.
+     */
+    constructor();
+    /**
+     * Returns true if passed SVG element belongs to the grip. False otherwise.
+     *
+     * @param el - target element.
+     */
+    ownsTarget(el: EventTarget): boolean;
+}
+
+/**
+ * Represents base state for line-style markers.
+ */
+interface LinearMarkerBaseState extends MarkerBaseState {
+    /**
+     * x coordinate for the first end-point.
+     */
+    x1: number;
+    /**
+     * y coordinate for the first end-point.
+     */
+    y1: number;
+    /**
+     * x coordinate for the second end-point.
+     */
+    x2: number;
+    /**
+     * y coordinate for the second end-point.
+     */
+    y2: number;
+}
+
+/**
+ * LinearMarkerBase is a base class for all line-type markers (Line, Arrow, Measurement Tool, etc.).
+ */
+declare class LinearMarkerBase extends MarkerBase {
+    /**
+     * x coordinate of the first end-point
+     */
+    protected x1: number;
+    /**
+     * y coordinate of the first end-point
+     */
+    protected y1: number;
+    /**
+     * x coordinate of the second end-point
+     */
+    protected x2: number;
+    /**
+     * y coordinate of the second end-point
+     */
+    protected y2: number;
+    /**
+     * Default line length when marker is created with a simple click (without dragging).
+     */
+    protected defaultLength: number;
+    /**
+     * Pointer coordinates at the satart of move or resize.
+     */
+    protected manipulationStartX: number;
+    protected manipulationStartY: number;
+    private manipulationStartX1;
+    private manipulationStartY1;
+    private manipulationStartX2;
+    private manipulationStartY2;
+    /**
+     * Marker's main visual.
+     */
+    protected visual: SVGGraphicsElement;
+    /**
+     * Container for control elements.
+     */
+    protected controlBox: SVGGElement;
+    /**
+     * First manipulation grip
+     */
+    protected grip1: ResizeGrip;
+    /**
+     * Second manipulation grip.
+     */
+    protected grip2: ResizeGrip;
+    /**
+     * Active manipulation grip.
+     */
+    protected activeGrip: ResizeGrip;
+    /**
+     * Creates a LineMarkerBase object.
+     *
+     * @param container - SVG container to hold marker's visual.
+     * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.
+     * @param settings - settings object containing default markers settings.
+     */
+    constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings);
+    /**
+     * Returns true if passed SVG element belongs to the marker. False otherwise.
+     *
+     * @param el - target element.
+     */
+    ownsTarget(el: EventTarget): boolean;
+    /**
+     * Handles pointer (mouse, touch, stylus, etc.) down event.
+     *
+     * @param point - event coordinates.
+     * @param target - direct event target element.
+     */
+    pointerDown(point: IPoint, target?: EventTarget): void;
+    /**
+     * Handles pointer (mouse, touch, stylus, etc.) up event.
+     *
+     * @param point - event coordinates.
+     * @param target - direct event target element.
+     */
+    pointerUp(point: IPoint): void;
+    /**
+     * When implemented adjusts marker visual after manipulation when needed.
+     */
+    protected adjustVisual(): void;
+    /**
+     * Handles marker manipulation (move, resize, rotate, etc.).
+     *
+     * @param point - event coordinates.
+     */
+    manipulate(point: IPoint): void;
+    /**
+     * Resizes the line marker.
+     * @param point - current manipulation coordinates.
+     */
+    protected resize(point: IPoint): void;
+    /**
+     * Displays marker's controls.
+     */
+    select(): void;
+    /**
+     * Hides marker's controls.
+     */
+    deselect(): void;
+    /**
+     * Creates control box for manipulation controls.
+     */
+    protected setupControlBox(): void;
+    private adjustControlBox;
+    /**
+     * Adds control grips to control box.
+     */
+    protected addControlGrips(): void;
+    /**
+     * Creates manipulation grip.
+     * @returns - manipulation grip.
+     */
+    protected createGrip(): ResizeGrip;
+    /**
+     * Updates manipulation grip layout.
+     */
+    protected positionGrips(): void;
+    /**
+     * Positions manipulation grip.
+     * @param grip - grip to position
+     * @param x - new X coordinate
+     * @param y - new Y coordinate
+     */
+    protected positionGrip(grip: SVGGraphicsElement, x: number, y: number): void;
+    /**
+     * Returns marker's state.
+     */
+    getState(): LinearMarkerBaseState;
+    /**
+     * Restores marker's state to the previously saved one.
+     * @param state - previously saved state.
+     */
+    restoreState(state: MarkerBaseState): void;
+    /**
+     * Scales marker. Used after the image resize.
+     *
+     * @param scaleX - horizontal scale
+     * @param scaleY - vertical scale
+     */
+    scale(scaleX: number, scaleY: number): void;
+}
+
+/**
+ * Represents a state snapshot of a RectangularBoxMarkerBase.
+ */
+interface RectangularBoxMarkerBaseState extends MarkerBaseState {
+    /**
+     * x coordinate of the top-left corner.
+     */
+    left: number;
+    /**
+     * y coordinate of the top-left corner.
+     */
+    top: number;
+    /**
+     * Marker's width.
+     */
+    width: number;
+    /**
+     * Marker's height.
+     */
+    height: number;
+    /**
+     * Marker's rotation angle.
+     */
+    rotationAngle: number;
+    /**
+     * Transformation matrix for the marker's visual.
+     */
+    visualTransformMatrix: ITransformMatrix;
+    /**
+     * Transofrmation matrix for the marker's container.
+     */
+    containerTransformMatrix: ITransformMatrix;
+}
+
+/**
+ * RectangularBoxMarkerBase is a base class for all marker's with rectangular controls such as all rectangle markers,
+ * text and callout markers.
+ *
+ * It creates and manages the rectangular control box and related resize, move, and rotate manipulations.
+ */
+declare class RectangularBoxMarkerBase extends MarkerBase {
+    /**
+     * x coordinate of the top-left corner.
+     */
+    protected left: number;
+    /**
+     * y coordinate of the top-left corner.
+     */
+    protected top: number;
+    /**
+     * Marker width.
+     */
+    protected width: number;
+    /**
+     * Marker height.
+     */
+    protected height: number;
+    /**
+     * The default marker size when the marker is created with a click (without dragging).
+     */
+    protected defaultSize: IPoint;
+    /**
+     * x coordinate of the top-left corner at the start of manipulation.
+     */
+    protected manipulationStartLeft: number;
+    /**
+     * y coordinate of the top-left corner at the start of manipulation.
+     */
+    protected manipulationStartTop: number;
+    /**
+     * Width at the start of manipulation.
+     */
+    protected manipulationStartWidth: number;
+    /**
+     * Height at the start of manipulation.
+     */
+    protected manipulationStartHeight: number;
+    /**
+     * x coordinate of the pointer at the start of manipulation.
+     */
+    protected manipulationStartX: number;
+    /**
+     * y coordinate of the pointer at the start of manipulation.
+     */
+    protected manipulationStartY: number;
+    /**
+     * Pointer's horizontal distance from the top left corner.
+     */
+    protected offsetX: number;
+    /**
+     * Pointer's vertical distance from the top left corner.
+     */
+    protected offsetY: number;
+    /**
+     * Marker's rotation angle.
+     */
+    protected rotationAngle: number;
+    /**
+     * x coordinate of the marker's center.
+     */
+    protected get centerX(): number;
+    /**
+     * y coordinate of the marker's center.
+     */
+    protected get centerY(): number;
+    private _visual;
+    /**
+     * Container for the marker's visual.
+     */
+    protected get visual(): SVGGraphicsElement;
+    protected set visual(value: SVGGraphicsElement);
+    /**
+     * Container for the marker's editing controls.
+     */
+    protected controlBox: SVGGElement;
+    private readonly CB_DISTANCE;
+    private controlRect;
+    private rotatorGripLine;
+    private controlGrips;
+    private rotatorGrip;
+    private activeGrip;
+    /**
+     * Creates a new marker.
+     *
+     * @param container - SVG container to hold marker's visual.
+     * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.
+     * @param settings - settings object containing default markers settings.
+     */
+    constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings);
+    /**
+     * Returns true if passed SVG element belongs to the marker. False otherwise.
+     *
+     * @param el - target element.
+     */
+    ownsTarget(el: EventTarget): boolean;
+    /**
+     * Handles pointer (mouse, touch, stylus, etc.) down event.
+     *
+     * @param point - event coordinates.
+     * @param target - direct event target element.
+     */
+    pointerDown(point: IPoint, target?: EventTarget): void;
+    /**
+     * Handles pointer (mouse, touch, stylus, etc.) up event.
+     *
+     * @param point - event coordinates.
+     * @param target - direct event target element.
+     */
+    pointerUp(point: IPoint): void;
+    /**
+     * Moves visual to the specified coordinates.
+     * @param point - coordinates of the new top-left corner of the visual.
+     */
+    protected moveVisual(point: IPoint): void;
+    /**
+     * Handles marker manipulation (move, resize, rotate, etc.).
+     *
+     * @param point - event coordinates.
+     */
+    manipulate(point: IPoint): void;
+    /**
+     * Resizes the marker based on pointer coordinates and context.
+     * @param point - pointer coordinates.
+     */
+    protected resize(point: IPoint): void;
+    /**
+     * Sets control box size and location.
+     */
+    protected setSize(): void;
+    private rotate;
+    private applyRotation;
+    /**
+     * Returns point coordinates based on the actual screen coordinates and marker's rotation.
+     * @param point - original pointer coordinates
+     */
+    protected rotatePoint(point: IPoint): IPoint;
+    /**
+     * Returns original point coordinates based on coordinates with rotation applied.
+     * @param point - rotated point coordinates.
+     */
+    protected unrotatePoint(point: IPoint): IPoint;
+    /**
+     * Displays marker's controls.
+     */
+    select(): void;
+    /**
+     * Hides marker's controls.
+     */
+    deselect(): void;
+    private setupControlBox;
+    private adjustControlBox;
+    private addControlGrips;
+    private createGrip;
+    private positionGrips;
+    private positionGrip;
+    /**
+     * Hides marker's editing controls.
+     */
+    protected hideControlBox(): void;
+    /**
+     * Shows marker's editing controls.
+     */
+    protected showControlBox(): void;
+    /**
+     * Returns marker's state.
+     */
+    getState(): RectangularBoxMarkerBaseState;
+    /**
+     * Restores marker's state to the previously saved one.
+     * @param state - previously saved state.
+     */
+    restoreState(state: MarkerBaseState): void;
+    /**
+     * Scales marker. Used after the image resize.
+     *
+     * @param scaleX - horizontal scale
+     * @param scaleY - vertical scale
+     */
+    scale(scaleX: number, scaleY: number): void;
+}
+
+/**
+ * Represents RectangleMarker's state.
+ */
+interface RectangleMarkerState extends RectangularBoxMarkerBaseState {
+    /**
+     * Rectangle fill color.
+     */
+    fillColor: string;
+    /**
+     * Rectangle border stroke (line) color.
+     */
+    strokeColor: string;
+    /**
+     * Rectange border width.
+     */
+    strokeWidth: number;
+    /**
+     * Rectange border dash array.
+     */
+    strokeDasharray: string;
+    /**
+     * Rectangle opacity (alpha). 0 to 1.
+     */
+    opacity: number;
+}
+
+/**
+ * RecatngleMarker is a base class for all rectangular markers (Frame, Cover, Highlight, etc.)
+ */
+declare abstract class RectangleMarker extends RectangularBoxMarkerBase {
+    /**
+     * String type name of the marker type.
+     *
+     * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.
+     */
+    static title: string;
+    /**
+     * Recangle fill color.
+     */
+    protected fillColor: string;
+    /**
+     * Rectangle stroke color.
+     */
+    protected strokeColor: string;
+    /**
+     * Rectangle border stroke width.
+     */
+    protected strokeWidth: number;
+    /**
+     * Rectangle border stroke dash array.
+     */
+    protected strokeDasharray: string;
+    /**
+     * Rectangle opacity (alpha). 0 to 1.
+     */
+    protected opacity: number;
+    /**
+     * Creates a new marker.
+     *
+     * @param container - SVG container to hold marker's visual.
+     * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.
+     * @param settings - settings object containing default markers settings.
+     */
+    constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings);
+    /**
+     * Returns true if passed SVG element belongs to the marker. False otherwise.
+     *
+     * @param el - target element.
+     */
+    ownsTarget(el: EventTarget): boolean;
+    /**
+     * Creates the marker's rectangle visual.
+     */
+    protected createVisual(): void;
+    /**
+     * Handles pointer (mouse, touch, stylus, etc.) down event.
+     *
+     * @param point - event coordinates.
+     * @param target - direct event target element.
+     */
+    pointerDown(point: IPoint, target?: EventTarget): void;
+    /**
+     * Handles marker manipulation (move, resize, rotate, etc.).
+     *
+     * @param point - event coordinates.
+     */
+    manipulate(point: IPoint): void;
+    /**
+     * Resizes the marker based on the pointer coordinates.
+     * @param point - current pointer coordinates.
+     */
+    protected resize(point: IPoint): void;
+    /**
+     * Sets visual's width and height attributes based on marker's width and height.
+     */
+    protected setSize(): void;
+    /**
+     * Handles pointer (mouse, touch, stylus, etc.) up event.
+     *
+     * @param point - event coordinates.
+     * @param target - direct event target element.
+     */
+    pointerUp(point: IPoint): void;
+    /**
+     * Sets rectangle's border stroke color.
+     * @param color - color as string
+     */
+    protected setStrokeColor(color: string): void;
+    /**
+     * Sets rectangle's fill color.
+     * @param color - color as string
+     */
+    protected setFillColor(color: string): void;
+    /**
+     * Sets rectangle's border stroke (line) width.
+     * @param color - color as string
+     */
+    protected setStrokeWidth(width: number): void;
+    /**
+     * Sets rectangle's border stroke dash array.
+     * @param color - color as string
+     */
+    protected setStrokeDasharray(dashes: string): void;
+    /**
+     * Returns current marker state that can be restored in the future.
+     */
+    getState(): RectangleMarkerState;
+    /**
+     * Restores previously saved marker state.
+     *
+     * @param state - previously saved state.
+     */
+    restoreState(state: MarkerBaseState): void;
+    /**
+     * Scales marker. Used after the image resize.
+     *
+     * @param scaleX - horizontal scale
+     * @param scaleY - vertical scale
+     */
+    scale(scaleX: number, scaleY: number): void;
+}
+
+/**
+ * RectangularBoxMarkerGrips is a set of resize/rotation grips for a rectangular marker.
+ */
+declare class RectangularBoxMarkerGrips {
+    /**
+     * Top-left grip.
+     */
+    topLeft: ResizeGrip;
+    /**
+     * Top-center grip.
+     */
+    topCenter: ResizeGrip;
+    /**
+     * Top-right grip.
+     */
+    topRight: ResizeGrip;
+    /**
+     * Center-left grip.
+     */
+    centerLeft: ResizeGrip;
+    /**
+     * Center-right grip.
+     */
+    centerRight: ResizeGrip;
+    /**
+     * Bottom-left grip.
+     */
+    bottomLeft: ResizeGrip;
+    /**
+     * Bottom-center grip.
+     */
+    bottomCenter: ResizeGrip;
+    /**
+     * Bottom-right grip.
+     */
+    bottomRight: ResizeGrip;
+    /**
+     * Creates a new marker grip set.
+     */
+    constructor();
+    /**
+     * Returns a marker grip owning the specified visual.
+     * @param gripVisual - visual for owner to be determined.
+     */
+    findGripByVisual(gripVisual: EventTarget): ResizeGrip | undefined;
+}
+
+/**
+ * Represents state of a {@link LineMarker}.
+ */
+interface LineMarkerState extends LinearMarkerBaseState {
+    /**
+     * Line color.
+     */
+    strokeColor: string;
+    /**
+     * Line width.
+     */
+    strokeWidth: number;
+    /**
+     * Line dash array.
+     */
+    strokeDasharray: string;
+}
+
+declare class LineMarker extends LinearMarkerBase {
+    /**
+     * String type name of the marker type.
+     *
+     * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.
+     */
+    static typeName: string;
+    /**
+     * Marker type title (display name) used for accessibility and other attributes.
+     */
+    static title: string;
+    /**
+     * SVG icon markup displayed on toolbar buttons.
+     */
+    static icon: string;
+    /**
+     * Invisible wider line to make selection easier/possible.
+     */
+    protected selectorLine: SVGLineElement;
+    /**
+     * Visible marker line.
+     */
+    protected visibleLine: SVGLineElement;
+    /**
+     * Line color.
+     */
+    protected strokeColor: string;
+    /**
+     * Line width.
+     */
+    protected strokeWidth: number;
+    /**
+     * Line dash array.
+     */
+    protected strokeDasharray: string;
+    /**
+     * Color pickar panel for line color.
+     */
+    protected strokePanel: ColorPickerPanel;
+    /**
+     * Line width toolbox panel.
+     */
+    protected strokeWidthPanel: LineWidthPanel;
+    /**
+     * Line dash array toolbox panel.
+     */
+    protected strokeStylePanel: LineStylePanel;
+    /**
+     * Creates a new marker.
+     *
+     * @param container - SVG container to hold marker's visual.
+     * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.
+     * @param settings - settings object containing default markers settings.
+     */
+    constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings);
+    /**
+     * Returns true if passed SVG element belongs to the marker. False otherwise.
+     *
+     * @param el - target element.
+     */
+    ownsTarget(el: EventTarget): boolean;
+    private createVisual;
+    /**
+     * Handles pointer (mouse, touch, stylus, etc.) down event.
+     *
+     * @param point - event coordinates.
+     * @param target - direct event target element.
+     */
+    pointerDown(point: IPoint, target?: EventTarget): void;
+    /**
+     * Adjusts visual after manipulation.
+     */
+    protected adjustVisual(): void;
+    /**
+     * Sets line color.
+     * @param color - new color.
+     */
+    protected setStrokeColor(color: string): void;
+    /**
+     * Sets line width.
+     * @param width - new width.
+     */
+    protected setStrokeWidth(width: number): void;
+    /**
+     * Sets line dash array.
+     * @param dashes - new dash array.
+     */
+    protected setStrokeDasharray(dashes: string): void;
+    /**
+     * Returns the list of toolbox panels for this marker type.
+     */
+    get toolboxPanels(): ToolboxPanel[];
+    /**
+     * Returns current marker state that can be restored in the future.
+     */
+    getState(): LineMarkerState;
+    /**
+     * Restores previously saved marker state.
+     *
+     * @param state - previously saved state.
+     */
+    restoreState(state: MarkerBaseState): void;
+}
+
+/**
+ * Represents arrow marker state.
+ */
+interface ArrowMarkerState extends LineMarkerState {
+    /**
+     * Type of arrow.
+     */
+    arrowType: ArrowType;
+}
+
+/**
+ * Represents an arrow marker.
+ */
+declare class ArrowMarker extends LineMarker {
+    /**
+     * String type name of the marker type.
+     *
+     * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.
+     */
+    static typeName: string;
+    /**
+     * Marker type title (display name) used for accessibility and other attributes.
+     */
+    static title: string;
+    /**
+     * SVG icon markup displayed on toolbar buttons.
+     */
+    static icon: string;
+    private arrow1;
+    private arrow2;
+    private arrowType;
+    private arrowBaseHeight;
+    private arrowBaseWidth;
+    /**
+     * Toolbox panel for arrow type selection.
+     */
+    protected arrowTypePanel: ArrowTypePanel;
+    /**
+     * Creates a new marker.
+     *
+     * @param container - SVG container to hold marker's visual.
+     * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.
+     * @param settings - settings object containing default markers settings.
+     */
+    constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings);
+    /**
+     * Returns true if passed SVG element belongs to the marker. False otherwise.
+     *
+     * @param el - target element.
+     */
+    ownsTarget(el: EventTarget): boolean;
+    private getArrowPoints;
+    private createTips;
+    /**
+     * Handles pointer (mouse, touch, stylus, etc.) down event.
+     *
+     * @param point - event coordinates.
+     * @param target - direct event target element.
+     */
+    pointerDown(point: IPoint, target?: EventTarget): void;
+    /**
+     * Adjusts marker visual after manipulation.
+     */
+    protected adjustVisual(): void;
+    private setArrowType;
+    /**
+     * Returns the list of toolbox panels for this marker type.
+     */
+    get toolboxPanels(): ToolboxPanel[];
+    /**
+     * Returns current marker state that can be restored in the future.
+     */
+    getState(): ArrowMarkerState;
+    /**
+     * Restores previously saved marker state.
+     *
+     * @param state - previously saved state.
+     */
+    restoreState(state: MarkerBaseState): void;
+}
+
+interface TextMarkerState extends RectangularBoxMarkerBaseState {
+    color: string;
+    fontFamily: string;
+    padding: number;
+    text: string;
+}
+
+declare class TextMarker extends RectangularBoxMarkerBase {
+    /**
+     * String type name of the marker type.
+     *
+     * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.
+     */
+    static typeName: string;
+    /**
+     * Marker type title (display name) used for accessibility and other attributes.
+     */
+    static title: string;
+    /**
+     * SVG icon markup displayed on toolbar buttons.
+     */
+    static icon: string;
+    /**
+     * Text color.
+     */
+    protected color: string;
+    /**
+     * Text's font family.
+     */
+    protected fontFamily: string;
+    /**
+     * Padding inside of the marker's bounding box in percents.
+     */
+    protected padding: number;
+    /**
+     * Text color picker toolbox panel.
+     */
+    protected colorPanel: ColorPickerPanel;
+    /**
+     * Text font family toolbox panel.
+     */
+    protected fontFamilyPanel: FontFamilyPanel;
+    private readonly DEFAULT_TEXT;
+    private text;
+    /**
+     * Visual text element.
+     */
+    protected textElement: SVGTextElement;
+    /**
+     * Text background rectangle.
+     */
+    protected bgRectangle: SVGRectElement;
+    /**
+     * Div element for the text editor container.
+     */
+    protected textEditDiv: HTMLDivElement;
+    /**
+     * Editable text element.
+     */
+    protected textEditor: HTMLDivElement;
+    private isMoved;
+    private pointerDownPoint;
+    private pointerDownTimestamp;
+    /**
+     * Creates a new marker.
+     *
+     * @param container - SVG container to hold marker's visual.
+     * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.
+     * @param settings - settings object containing default markers settings.
+     */
+    constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings);
+    /**
+     * Returns true if passed SVG element belongs to the marker. False otherwise.
+     *
+     * @param el - target element.
+     */
+    ownsTarget(el: EventTarget): boolean;
+    /**
+     * Creates text marker visual.
+     */
+    protected createVisual(): void;
+    /**
+     * Handles pointer (mouse, touch, stylus, etc.) down event.
+     *
+     * @param point - event coordinates.
+     * @param target - direct event target element.
+     */
+    pointerDown(point: IPoint, target?: EventTarget): void;
+    private renderText;
+    private getTextScale;
+    private getTextPosition;
+    private sizeText;
+    /**
+     * Handles marker manipulation (move, resize, rotate, etc.).
+     *
+     * @param point - event coordinates.
+     */
+    manipulate(point: IPoint): void;
+    /**
+     * Resize marker based on current pointer coordinates and context.
+     * @param point
+     */
+    protected resize(point: IPoint): void;
+    /**
+     * Sets size of marker elements after manipulation.
+     */
+    protected setSize(): void;
+    /**
+     * Handles pointer (mouse, touch, stylus, etc.) up event.
+     *
+     * @param point - event coordinates.
+     */
+    pointerUp(point: IPoint): void;
+    private showTextEditor;
+    private positionTextEditor;
+    private textEditDivClicked;
+    /**
+     * Deselects this marker, renders text (if necessary), and hides selected marker UI.
+     */
+    deselect(): void;
+    /**
+     * Opens text editor on double-click.
+     * @param point
+     * @param target
+     */
+    dblClick(point: IPoint, target?: EventTarget): void;
+    /**
+     * Sets text color.
+     * @param color - new text color.
+     */
+    protected setColor(color: string): void;
+    /**
+     * Sets font family.
+     * @param font - new font family.
+     */
+    protected setFont(font: string): void;
+    /**
+     * Hides marker visual.
+     */
+    protected hideVisual(): void;
+    /**
+     * Shows marker visual.
+     */
+    protected showVisual(): void;
+    /**
+     * Returns the list of toolbox panels for this marker type.
+     */
+    get toolboxPanels(): ToolboxPanel[];
+    /**
+     * Returns current marker state that can be restored in the future.
+     */
+    getState(): TextMarkerState;
+    /**
+     * Restores previously saved marker state.
+     *
+     * @param state - previously saved state.
+     */
+    restoreState(state: MarkerBaseState): void;
+    /**
+     * Scales marker. Used after the image resize.
+     *
+     * @param scaleX - horizontal scale
+     * @param scaleY - vertical scale
+     */
+    scale(scaleX: number, scaleY: number): void;
+}
+
+/**
+ * Represents the state of a CalloutMarker.
+ */
+interface CalloutMarkerState extends TextMarkerState {
+    /**
+     * Background (fill) color.
+     */
+    bgColor: string;
+    /**
+     * Position of the callout tip.
+     */
+    tipPosition: IPoint;
+}
+
+declare class CalloutMarker extends TextMarker {
+    /**
+     * String type name of the marker type.
+     *
+     * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.
+     */
+    static typeName: string;
+    /**
+     * Marker type title (display name) used for accessibility and other attributes.
+     */
+    static title: string;
+    /**
+     * SVG icon markup displayed on toolbar buttons.
+     */
+    static icon: string;
+    private bgColor;
+    /**
+     * Color picker toolbox panel for the background (fill) color.
+     */
+    protected bgColorPanel: ColorPickerPanel;
+    private tipPosition;
+    private tipBase1Position;
+    private tipBase2Position;
+    private tip;
+    private tipGrip;
+    private tipMoving;
+    /**
+     * Creates a new marker.
+     *
+     * @param container - SVG container to hold marker's visual.
+     * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.
+     * @param settings - settings object containing default markers settings.
+     */
+    constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings);
+    /**
+     * Returns true if passed SVG element belongs to the marker. False otherwise.
+     *
+     * @param el - target element.
+     */
+    ownsTarget(el: EventTarget): boolean;
+    private createTip;
+    /**
+     * Handles pointer (mouse, touch, stylus, etc.) down event.
+     *
+     * @param point - event coordinates.
+     * @param target - direct event target element.
+     */
+    pointerDown(point: IPoint, target?: EventTarget): void;
+    /**
+     * Handles pointer (mouse, touch, stylus, etc.) up event.
+     *
+     * @param point - event coordinates.
+     */
+    pointerUp(point: IPoint): void;
+    /**
+     * Handles marker manipulation (move, resize, rotate, etc.).
+     *
+     * @param point - event coordinates.
+     */
+    manipulate(point: IPoint): void;
+    /**
+     * Sets marker's background/fill color.
+     * @param color - new background color.
+     */
+    protected setBgColor(color: string): void;
+    private getTipPoints;
+    private setTipPoints;
+    /**
+     * Resize marker based on current pointer coordinates and context.
+     * @param point
+     */
+    protected resize(point: IPoint): void;
+    private positionTip;
+    /**
+     * Returns the list of toolbox panels for this marker type.
+     */
+    get toolboxPanels(): ToolboxPanel[];
+    /**
+     * Selects this marker and displays appropriate selected marker UI.
+     */
+    select(): void;
+    /**
+     * Returns current marker state that can be restored in the future.
+     */
+    getState(): CalloutMarkerState;
+    /**
+     * Restores previously saved marker state.
+     *
+     * @param state - previously saved state.
+     */
+    restoreState(state: MarkerBaseState): void;
+    /**
+     * Scales marker. Used after the image resize.
+     *
+     * @param scaleX - horizontal scale
+     * @param scaleY - vertical scale
+     */
+    scale(scaleX: number, scaleY: number): void;
+}
+
+declare class CoverMarker extends RectangleMarker {
+    /**
+     * String type name of the marker type.
+     *
+     * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.
+     */
+    static typeName: string;
+    /**
+     * Marker type title (display name) used for accessibility and other attributes.
+     */
+    static title: string;
+    /**
+     * SVG icon markup displayed on toolbar buttons.
+     */
+    static icon: string;
+    /**
+     * Color picker panel for the background color.
+     */
+    protected fillPanel: ColorPickerPanel;
+    /**
+     * Creates a new marker.
+     *
+     * @param container - SVG container to hold marker's visual.
+     * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.
+     * @param settings - settings object containing default markers settings.
+     */
+    constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings);
+    /**
+     * Returns the list of toolbox panels for this marker type.
+     */
+    get toolboxPanels(): ToolboxPanel[];
+    /**
+     * Returns current marker state that can be restored in the future.
+     */
+    getState(): RectangleMarkerState;
+}
+
+/**
+ * Represents state of a {@link CurveMarker}.
+ */
+interface CurveMarkerState extends LinearMarkerBaseState {
+    /**
+     * Line color.
+     */
+    strokeColor: string;
+    /**
+     * Line width.
+     */
+    strokeWidth: number;
+    /**
+     * Line dash array.
+     */
+    strokeDasharray: string;
+    curveX: number;
+    curveY: number;
+}
+
+declare class CurveMarker extends LinearMarkerBase {
+    /**
+     * String type name of the marker type.
+     *
+     * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.
+     */
+    static typeName: string;
+    /**
+     * Marker type title (display name) used for accessibility and other attributes.
+     */
+    static title: string;
+    /**
+     * SVG icon markup displayed on toolbar buttons.
+     */
+    static icon: string;
+    /**
+     * Invisible wider curve to make selection easier/possible.
+     */
+    protected selectorCurve: SVGPathElement;
+    /**
+     * Visible marker curve.
+     */
+    protected visibleCurve: SVGPathElement;
+    /**
+     * Line color.
+     */
+    protected strokeColor: string;
+    /**
+     * Line width.
+     */
+    protected strokeWidth: number;
+    /**
+     * Line dash array.
+     */
+    protected strokeDasharray: string;
+    /**
+     * Color picker panel for line color.
+     */
+    protected strokePanel: ColorPickerPanel;
+    /**
+     * Line width toolbox panel.
+     */
+    protected strokeWidthPanel: LineWidthPanel;
+    /**
+     * Line dash array toolbox panel.
+     */
+    protected strokeStylePanel: LineStylePanel;
+    private curveGrip;
+    private curveX;
+    private curveY;
+    private manipulationStartCurveX;
+    private manipulationStartCurveY;
+    private curveControlLine1;
+    private curveControlLine2;
+    /**
+     * Creates a new marker.
+     *
+     * @param container - SVG container to hold marker's visual.
+     * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.
+     * @param settings - settings object containing default markers settings.
+     */
+    constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings);
+    /**
+     * Returns true if passed SVG element belongs to the marker. False otherwise.
+     *
+     * @param el - target element.
+     */
+    ownsTarget(el: EventTarget): boolean;
+    private getPathD;
+    private createVisual;
+    /**
+     * Handles pointer (mouse, touch, stylus, etc.) down event.
+     *
+     * @param point - event coordinates.
+     * @param target - direct event target element.
+     */
+    pointerDown(point: IPoint, target?: EventTarget): void;
+    /**
+     * Adjusts visual after manipulation.
+     */
+    protected adjustVisual(): void;
+    /**
+     * Sets manipulation grips up.
+     */
+    protected setupControlBox(): void;
+    /**
+     * Add manipulation grips to the control box.
+     */
+    protected addControlGrips(): void;
+    /**
+     * Positions manipulation grips.
+     */
+    protected positionGrips(): void;
+    /**
+     * Moves or resizes the marker.
+     * @param point event coordinates
+     */
+    manipulate(point: IPoint): void;
+    /**
+     * Resizes the marker.
+     * @param point event coordinates.
+     */
+    protected resize(point: IPoint): void;
+    /**
+     * Sets line color.
+     * @param color - new color.
+     */
+    protected setStrokeColor(color: string): void;
+    /**
+     * Sets line width.
+     * @param width - new width.
+     */
+    protected setStrokeWidth(width: number): void;
+    /**
+     * Sets line dash array.
+     * @param dashes - new dash array.
+     */
+    protected setStrokeDasharray(dashes: string): void;
+    /**
+     * Scales marker. Used after the image resize.
+     *
+     * @param scaleX - horizontal scale
+     * @param scaleY - vertical scale
+     */
+    scale(scaleX: number, scaleY: number): void;
+    /**
+     * Returns the list of toolbox panels for this marker type.
+     */
+    get toolboxPanels(): ToolboxPanel[];
+    /**
+     * Returns current marker state that can be restored in the future.
+     */
+    getState(): CurveMarkerState;
+    /**
+     * Restores previously saved marker state.
+     *
+     * @param state - previously saved state.
+     */
+    restoreState(state: MarkerBaseState): void;
+}
+
+declare class EllipseMarker extends RectangularBoxMarkerBase {
+    /**
+     * String type name of the marker type.
+     *
+     * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.
+     */
+    static typeName: string;
+    /**
+     * Marker type title (display name) used for accessibility and other attributes.
+     */
+    static title: string;
+    /**
+     * SVG icon markup displayed on toolbar buttons.
+     */
+    static icon: string;
+    /**
+     * Ellipse fill color.
+     */
+    protected fillColor: string;
+    /**
+     * Ellipse border color.
+     */
+    protected strokeColor: string;
+    /**
+     * Ellipse border line width.
+     */
+    protected strokeWidth: number;
+    /**
+     * Ellipse border dash array.
+     */
+    protected strokeDasharray: string;
+    /**
+     * Ellipse opacity (0..1).
+     */
+    protected opacity: number;
+    protected strokePanel: ColorPickerPanel;
+    protected fillPanel: ColorPickerPanel;
+    protected strokeWidthPanel: LineWidthPanel;
+    protected strokeStylePanel: LineStylePanel;
+    protected opacityPanel: OpacityPanel;
+    /**
+     * Creates a new marker.
+     *
+     * @param container - SVG container to hold marker's visual.
+     * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.
+     * @param settings - settings object containing default markers settings.
+     */
+    constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings);
+    /**
+     * Returns true if passed SVG element belongs to the marker. False otherwise.
+     *
+     * @param el - target element.
+     */
+    ownsTarget(el: EventTarget): boolean;
+    /**
+     * Creates marker visual.
+     */
+    protected createVisual(): void;
+    /**
+     * Handles pointer (mouse, touch, stylus, etc.) down event.
+     *
+     * @param point - event coordinates.
+     * @param target - direct event target element.
+     */
+    pointerDown(point: IPoint, target?: EventTarget): void;
+    /**
+     * Handles marker manipulation (move, resize, rotate, etc.).
+     *
+     * @param point - event coordinates.
+     */
+    manipulate(point: IPoint): void;
+    /**
+     * Resize marker based on current pointer coordinates and context.
+     * @param point
+     */
+    protected resize(point: IPoint): void;
+    /**
+     * Sets marker's visual size after manipulation.
+     */
+    protected setSize(): void;
+    /**
+     * Handles pointer (mouse, touch, stylus, etc.) up event.
+     *
+     * @param point - event coordinates.
+     */
+    pointerUp(point: IPoint): void;
+    /**
+     * Sets marker's line color.
+     * @param color - new line color.
+     */
+    protected setStrokeColor(color: string): void;
+    /**
+     * Sets marker's fill (background) color.
+     * @param color - new fill color.
+     */
+    protected setFillColor(color: string): void;
+    /**
+     * Sets marker's line width.
+     * @param width - new line width
+     */
+    protected setStrokeWidth(width: number): void;
+    /**
+     * Sets marker's border dash array.
+     * @param dashes - new dash array.
+     */
+    protected setStrokeDasharray(dashes: string): void;
+    /**
+     * Sets marker's opacity.
+     * @param opacity - new opacity value (0..1).
+     */
+    protected setOpacity(opacity: number): void;
+    /**
+     * Returns the list of toolbox panels for this marker type.
+     */
+    get toolboxPanels(): ToolboxPanel[];
+    /**
+     * Returns current marker state that can be restored in the future.
+     */
+    getState(): RectangleMarkerState;
+    /**
+     * Restores previously saved marker state.
+     *
+     * @param state - previously saved state.
+     */
+    restoreState(state: MarkerBaseState): void;
+    /**
+     * Scales marker. Used after the image resize.
+     *
+     * @param scaleX - horizontal scale
+     * @param scaleY - vertical scale
+     */
+    scale(scaleX: number, scaleY: number): void;
+}
+
+declare class EllipseFrameMarker extends EllipseMarker {
+    /**
+     * String type name of the marker type.
+     *
+     * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.
+     */
+    static typeName: string;
+    /**
+     * Marker type title (display name) used for accessibility and other attributes.
+     */
+    static title: string;
+    /**
+     * SVG icon markup displayed on toolbar buttons.
+     */
+    static icon: string;
+    /**
+     * Creates a new marker.
+     *
+     * @param container - SVG container to hold marker's visual.
+     * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.
+     * @param settings - settings object containing default markers settings.
+     */
+    constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings);
+    /**
+     * Returns the list of toolbox panels for this marker type.
+     */
+    get toolboxPanels(): ToolboxPanel[];
+    /**
+     * Returns current marker state that can be restored in the future.
+     */
+    getState(): RectangleMarkerState;
+}
+
+declare class FrameMarker extends RectangleMarker {
+    /**
+     * String type name of the marker type.
+     *
+     * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.
+     */
+    static typeName: string;
+    /**
+     * Marker type title (display name) used for accessibility and other attributes.
+     */
+    static title: string;
+    /**
+     * SVG icon markup displayed on toolbar buttons.
+     */
+    static icon: string;
+    private strokePanel;
+    private strokeWidthPanel;
+    private strokeStylePanel;
+    /**
+     * Creates a new marker.
+     *
+     * @param container - SVG container to hold marker's visual.
+     * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.
+     * @param settings - settings object containing default markers settings.
+     */
+    constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings);
+    /**
+     * Returns the list of toolbox panels for this marker type.
+     */
+    get toolboxPanels(): ToolboxPanel[];
+    /**
+     * Returns current marker state that can be restored in the future.
+     */
+    getState(): RectangleMarkerState;
+}
+
+/**
+ * Represents state of the {@link FreehandMarker}.
+ */
+interface FreehandMarkerState extends RectangularBoxMarkerBaseState {
+    /**
+     * URL of the drawing image.
+     */
+    drawingImgUrl: string;
+}
+
+declare class FreehandMarker extends RectangularBoxMarkerBase {
+    /**
+     * String type name of the marker type.
+     *
+     * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.
+     */
+    static typeName: string;
+    /**
+     * Marker type title (display name) used for accessibility and other attributes.
+     */
+    static title: string;
+    /**
+     * SVG icon markup displayed on toolbar buttons.
+     */
+    static icon: string;
+    /**
+     * Marker color.
+     */
+    protected color: string;
+    /**
+     * Marker's stroke width.
+     */
+    protected lineWidth: number;
+    private colorPanel;
+    private lineWidthPanel;
+    private canvasElement;
+    private canvasContext;
+    private drawingImage;
+    private drawingImgUrl;
+    private drawing;
+    private pixelRatio;
+    /**
+     * Creates a new marker.
+     *
+     * @param container - SVG container to hold marker's visual.
+     * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.
+     * @param settings - settings object containing default markers settings.
+     */
+    constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings);
+    /**
+     * Returns true if passed SVG element belongs to the marker. False otherwise.
+     *
+     * @param el - target element.
+     */
+    ownsTarget(el: EventTarget): boolean;
+    private createVisual;
+    /**
+     * Handles pointer (mouse, touch, stylus, etc.) down event.
+     *
+     * @param point - event coordinates.
+     * @param target - direct event target element.
+     */
+    pointerDown(point: IPoint, target?: EventTarget): void;
+    /**
+     * Handles marker manipulation (move, resize, rotate, etc.).
+     *
+     * @param point - event coordinates.
+     */
+    manipulate(point: IPoint): void;
+    /**
+     * Resize marker based on current pointer coordinates and context.
+     * @param point
+     */
+    protected resize(point: IPoint): void;
+    /**
+     * Handles pointer (mouse, touch, stylus, etc.) up event.
+     *
+     * @param point - event coordinates.
+     */
+    pointerUp(point: IPoint): void;
+    private addCanvas;
+    /**
+     * Selects this marker and displays appropriate selected marker UI.
+     */
+    select(): void;
+    /**
+     * Deselects this marker and hides selected marker UI.
+     */
+    deselect(): void;
+    private finishCreation;
+    private setDrawingImage;
+    /**
+     * Sets marker drawing color.
+     * @param color - new color.
+     */
+    protected setColor(color: string): void;
+    /**
+     * Sets line width.
+     * @param width - new line width
+     */
+    protected setLineWidth(width: number): void;
+    /**
+     * Returns the list of toolbox panels for this marker type.
+     */
+    get toolboxPanels(): ToolboxPanel[];
+    /**
+     * Returns current marker state that can be restored in the future.
+     */
+    getState(): FreehandMarkerState;
+    /**
+     * Restores previously saved marker state.
+     *
+     * @param state - previously saved state.
+     */
+    restoreState(state: MarkerBaseState): void;
+    /**
+     * Scales marker. Used after the image resize.
+     *
+     * @param scaleX - horizontal scale
+     * @param scaleY - vertical scale
+     */
+    scale(scaleX: number, scaleY: number): void;
+}
+
+declare class HighlightMarker extends CoverMarker {
+    /**
+     * String type name of the marker type.
+     *
+     * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.
+     */
+    static typeName: string;
+    /**
+     * Marker type title (display name) used for accessibility and other attributes.
+     */
+    static title: string;
+    /**
+     * SVG icon markup displayed on toolbar buttons.
+     */
+    static icon: string;
+    protected opacityPanel: OpacityPanel;
+    /**
+     * Creates a new marker.
+     *
+     * @param container - SVG container to hold marker's visual.
+     * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.
+     * @param settings - settings object containing default markers settings.
+     */
+    constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings);
+    /**
+     * Sets marker's opacity (0..1).
+     * @param opacity - new opacity value.
+     */
+    protected setOpacity(opacity: number): void;
+    /**
+     * Returns the list of toolbox panels for this marker type.
+     */
+    get toolboxPanels(): ToolboxPanel[];
+    /**
+     * Returns current marker state that can be restored in the future.
+     */
+    getState(): RectangleMarkerState;
+}
+
+declare class MeasurementMarker extends LineMarker {
+    /**
+     * String type name of the marker type.
+     *
+     * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.
+     */
+    static typeName: string;
+    /**
+     * Marker type title (display name) used for accessibility and other attributes.
+     */
+    static title: string;
+    /**
+     * SVG icon markup displayed on toolbar buttons.
+     */
+    static icon: string;
+    private tip1;
+    private tip2;
+    private get tipLength();
+    /**
+     * Creates a new marker.
+     *
+     * @param container - SVG container to hold marker's visual.
+     * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.
+     * @param settings - settings object containing default markers settings.
+     */
+    constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings);
+    /**
+     * Returns true if passed SVG element belongs to the marker. False otherwise.
+     *
+     * @param el - target element.
+     */
+    ownsTarget(el: EventTarget): boolean;
+    private createTips;
+    /**
+     * Handles pointer (mouse, touch, stylus, etc.) down event.
+     *
+     * @param point - event coordinates.
+     * @param target - direct event target element.
+     */
+    pointerDown(point: IPoint, target?: EventTarget): void;
+    /**
+     * Adjusts marker visual after manipulation.
+     */
+    protected adjustVisual(): void;
+    /**
+     * Returns the list of toolbox panels for this marker type.
+     */
+    get toolboxPanels(): ToolboxPanel[];
+    /**
+     * Returns current marker state that can be restored in the future.
+     */
+    getState(): LineMarkerState;
+    /**
+     * Restores previously saved marker state.
+     *
+     * @param state - previously saved state.
+     */
+    restoreState(state: MarkerBaseState): void;
+}
+
+export { Activator, ArrowMarker, ArrowMarkerState, ArrowType, ArrowTypeChangeHandler, ArrowTypePanel, CalloutMarker, CalloutMarkerState, ColorChangeHandler, ColorPickerPanel, ColorSet, CoverMarker, CurveMarker, CurveMarkerState, DisplayMode, EllipseFrameMarker, EllipseMarker, EventHandler, EventListenerRepository, FontChangeHandler, FontFamilyPanel, FrameMarker, FreehandMarker, FreehandMarkerState, HighlightMarker, IEventListenerRepository, IPoint, IStyleSettings, ITransformMatrix, LineMarker, LineMarkerState, LineStylePanel, LineWidthPanel, LinearMarkerBase, LinearMarkerBaseState, MarkerArea, MarkerAreaEvent, MarkerAreaEventHandler, MarkerAreaRenderEvent, MarkerAreaRenderEventHandler, MarkerAreaState, MarkerBase, MarkerBaseState, MarkerEvent, MarkerEventHandler, MeasurementMarker, OpacityChangeHandler, OpacityPanel, RectangleMarker, RectangleMarkerState, RectangularBoxMarkerBase, RectangularBoxMarkerBaseState, RectangularBoxMarkerGrips, ResizeGrip, Settings, Style, StyleChangeHandler, StyleClass, SvgHelper, TextMarker, TextMarkerState, ToolboxPanel, TransformMatrix, WidthChangeHandler };
diff --git a/capsule-prototype/js/libs/markerjs2/markerjs2.esm.js b/capsule-prototype/js/libs/markerjs2/markerjs2.esm.js
new file mode 100644
index 0000000000000000000000000000000000000000..d2a26cc651e2f135d10b90d6e402e52fbe332f4d
--- /dev/null
+++ b/capsule-prototype/js/libs/markerjs2/markerjs2.esm.js
@@ -0,0 +1,16 @@
+/*! *****************************************************************************
+Copyright (c) Microsoft Corporation.
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+***************************************************************************** */
+var t=function(e,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])})(e,i)};function e(e,i){function o(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(o.prototype=i.prototype,new o)}function i(t,e,i,o){return new(i||(i=Promise))((function(s,r){function n(t){try{h(o.next(t))}catch(t){r(t)}}function a(t){try{h(o.throw(t))}catch(t){r(t)}}function h(t){var e;t.done?s(t.value):(e=t.value,e instanceof i?e:new i((function(t){t(e)}))).then(n,a)}h((o=o.apply(t,e||[])).next())}))}function o(t,e){var i,o,s,r,n={label:0,sent:function(){if(1&s[0])throw s[1];return s[1]},trys:[],ops:[]};return r={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(r[Symbol.iterator]=function(){return this}),r;function a(r){return function(a){return function(r){if(i)throw new TypeError("Generator is already executing.");for(;n;)try{if(i=1,o&&(s=2&r[0]?o.return:r[0]?o.throw||((s=o.return)&&s.call(o),0):o.next)&&!(s=s.call(o,r[1])).done)return s;switch(o=0,s&&(r=[2&r[0],s.value]),r[0]){case 0:case 1:s=r;break;case 4:return n.label++,{value:r[1],done:!1};case 5:n.label++,o=r[1],r=[0];continue;case 7:r=n.ops.pop(),n.trys.pop();continue;default:if(!(s=n.trys,(s=s.length>0&&s[s.length-1])||6!==r[0]&&2!==r[0])){n=0;continue}if(3===r[0]&&(!s||r[1]>s[0]&&r[1]<s[3])){n.label=r[1];break}if(6===r[0]&&n.label<s[1]){n.label=s[1],s=r;break}if(s&&n.label<s[2]){n.label=s[2],n.ops.push(r);break}s[2]&&n.ops.pop(),n.trys.pop();continue}r=e.call(t,n)}catch(t){r=[6,t],o=0}finally{i=s=0}if(5&r[0])throw r[1];return{value:r[0]?r[1]:void 0,done:!0}}([r,a])}}}function s(){for(var t=0,e=0,i=arguments.length;e<i;e++)t+=arguments[e].length;var o=Array(t),s=0;for(e=0;e<i;e++)for(var r=arguments[e],n=0,a=r.length;n<a;n++,s++)o[s]=r[n];return o}var r=function(){function t(){}return t.createDefs=function(){return document.createElementNS("http://www.w3.org/2000/svg","defs")},t.setAttributes=function(t,e){for(var i=0,o=e;i<o.length;i++){var s=o[i],r=s[0],n=s[1];t.setAttribute(r,n)}},t.createRect=function(e,i,o){var s=document.createElementNS("http://www.w3.org/2000/svg","rect");return s.setAttribute("width",e.toString()),s.setAttribute("height",i.toString()),o&&t.setAttributes(s,o),s},t.createLine=function(e,i,o,s,r){var n=document.createElementNS("http://www.w3.org/2000/svg","line");return n.setAttribute("x1",e.toString()),n.setAttribute("y1",i.toString()),n.setAttribute("x2",o.toString()),n.setAttribute("y2",s.toString()),r&&t.setAttributes(n,r),n},t.createPolygon=function(e,i){var o=document.createElementNS("http://www.w3.org/2000/svg","polygon");return o.setAttribute("points",e),i&&t.setAttributes(o,i),o},t.createCircle=function(e,i){var o=document.createElementNS("http://www.w3.org/2000/svg","circle");return o.setAttribute("cx",(e/2).toString()),o.setAttribute("cy",(e/2).toString()),o.setAttribute("r",e.toString()),i&&t.setAttributes(o,i),o},t.createEllipse=function(e,i,o){var s=document.createElementNS("http://www.w3.org/2000/svg","ellipse");return s.setAttribute("cx",(e/2).toString()),s.setAttribute("cy",(i/2).toString()),s.setAttribute("rx",(e/2).toString()),s.setAttribute("ry",(i/2).toString()),o&&t.setAttributes(s,o),s},t.createGroup=function(e){var i=document.createElementNS("http://www.w3.org/2000/svg","g");return e&&t.setAttributes(i,e),i},t.createTransform=function(){return document.createElementNS("http://www.w3.org/2000/svg","svg").createSVGTransform()},t.createMarker=function(e,i,o,s,r,n,a){var h=document.createElementNS("http://www.w3.org/2000/svg","marker");return t.setAttributes(h,[["id",e],["orient",i],["markerWidth",o.toString()],["markerHeight",s.toString()],["refX",r.toString()],["refY",n.toString()]]),h.appendChild(a),h},t.createText=function(e){var i=document.createElementNS("http://www.w3.org/2000/svg","text");return i.setAttribute("x","0"),i.setAttribute("y","0"),e&&t.setAttributes(i,e),i},t.createTSpan=function(e,i){var o=document.createElementNS("http://www.w3.org/2000/svg","tspan");return o.textContent=e,i&&t.setAttributes(o,i),o},t.createImage=function(e){var i=document.createElementNS("http://www.w3.org/2000/svg","image");return e&&t.setAttributes(i,e),i},t.createPoint=function(t,e){var i=document.createElementNS("http://www.w3.org/2000/svg","svg").createSVGPoint();return i.x=t,i.y=e,i},t.createPath=function(e,i){var o=document.createElementNS("http://www.w3.org/2000/svg","path");return o.setAttribute("d",e),i&&t.setAttributes(o,i),o},t}(),n=function(){function t(){}return t.addKey=function(e){t.key=e},Object.defineProperty(t,"isLicensed",{get:function(){return!!t.key&&new RegExp(/^MJS2-[A-Z][0-9]{3}-[A-Z][0-9]{3}-[0-9]{4}$/,"i").test(t.key)},enumerable:!1,configurable:!0}),t}(),a=function(){function t(){this.naturalSize=!1,this.imageType="image/png",this.markersOnly=!1}return t.prototype.rasterize=function(t,e,i){var o=this;return new Promise((function(s){var r=void 0!==i?i:document.createElement("canvas");null===t&&(o.markersOnly=!0,o.naturalSize=!1);var n=document.createElementNS("http://www.w3.org/2000/svg","svg");n.setAttribute("xmlns","http://www.w3.org/2000/svg"),n.setAttribute("width",e.width.baseVal.valueAsString),n.setAttribute("height",e.height.baseVal.valueAsString),n.setAttribute("viewBox","0 0 "+e.viewBox.baseVal.width.toString()+" "+e.viewBox.baseVal.height.toString()),n.innerHTML=e.innerHTML,!0===o.naturalSize?(n.width.baseVal.value=t.naturalWidth,n.height.baseVal.value=t.naturalHeight):void 0!==o.width&&void 0!==o.height&&(n.width.baseVal.value=o.width,n.height.baseVal.value=o.height),r.width=n.width.baseVal.value,r.height=n.height.baseVal.value;var a=n.outerHTML,h=r.getContext("2d");!0!==o.markersOnly&&h.drawImage(t,0,0,r.width,r.height);var l=window.URL,p=new Image(r.width,r.height);p.setAttribute("crossOrigin","anonymous");var c=new Blob([a],{type:"image/svg+xml"}),u=l.createObjectURL(c);p.onload=function(){h.drawImage(p,0,0),l.revokeObjectURL(u);var t=r.toDataURL(o.imageType,o.imageQuality);s(t)},p.src=u}))},t}(),h=function(){function t(){}return Object.defineProperty(t,"defaultSettings",{get:function(){return{canvasBackgroundColor:"#ffffff",toolbarBackgroundColor:"#111111",toolbarBackgroundHoverColor:"#333333",toolbarColor:"#eeeeee",toolbarHeight:40,toolboxColor:"#eeeeee",toolboxAccentColor:"#3080c3",undoButtonVisible:!0,redoButtonVisible:!1,zoomButtonVisible:!1,zoomOutButtonVisible:!1,clearButtonVisible:!1,resultButtonBlockVisible:!0,logoPosition:"left"}},enumerable:!1,configurable:!0}),Object.defineProperty(t,"fadeInAnimationClassName",{get:function(){return t.CLASS_PREFIX+"fade_in"},enumerable:!1,configurable:!0}),Object.defineProperty(t,"fadeOutAnimationClassName",{get:function(){return t.CLASS_PREFIX+"fade_out"},enumerable:!1,configurable:!0}),t.addClass=function(e){return void 0===t.styleSheet&&t.addStyleSheet(),t.classes.push(e),t.styleSheet.sheet.insertRule("."+e.name+" {"+e.style+"}",t.styleSheet.sheet.cssRules.length),e},t.addRule=function(e){void 0===t.styleSheet&&t.addStyleSheet(),t.rules.push(e),t.styleSheet.sheet.insertRule(e.selector+" {"+e.style+"}",t.styleSheet.sheet.cssRules.length)},t.addStyleSheet=function(){var e;t.styleSheet=document.createElement("style"),(null!==(e=t.styleSheetRoot)&&void 0!==e?e:document.head).appendChild(t.styleSheet),t.addRule(new l("."+t.CLASS_PREFIX+" h3","font-family: sans-serif")),t.addRule(new l("@keyframes "+t.CLASS_PREFIX+"_fade_in_animation_frames","\n        from {\n          opacity: 0;\n        }\n        to {\n          opacity: 1;\n        }\n    ")),t.addRule(new l("@keyframes "+t.CLASS_PREFIX+"_fade_out_animation_frames","\n        from {\n          opacity: 1;\n        }\n        to {\n          opacity: 0;\n        }\n    ")),t.addClass(new p("fade_in","\n      animation-duration: 0.3s;\n      animation-name: "+t.CLASS_PREFIX+"_fade_in_animation_frames;\n    ")),t.addClass(new p("fade_out","\n      animation-duration: 0.3s;\n      animation-name: "+t.CLASS_PREFIX+"_fade_out_animation_frames;\n    "))},t.removeStyleSheet=function(){var e;t.styleSheet&&((null!==(e=t.styleSheetRoot)&&void 0!==e?e:document.head).removeChild(t.styleSheet),t.styleSheet=void 0)},t.CLASS_PREFIX="__markerjs2_",t.classes=[],t.rules=[],t.settings=t.defaultSettings,t}(),l=function(t,e){this.selector=t,this.style=e},p=function(){function t(t,e){this._localName=t,this.style=e}return Object.defineProperty(t.prototype,"name",{get:function(){return""+h.CLASS_PREFIX+this._localName},enumerable:!1,configurable:!0}),t}(),c=function(){function t(t,e,i,o){this.buttons=[],this.markerButtons=[],this.buttonClickListeners=[],this.markerjsContainer=t,this.displayMode=e,this.markerItems=i,this.uiStyleSettings=o,this.addStyles(),this.adjustLayout=this.adjustLayout.bind(this),this.overflowButtonClicked=this.overflowButtonClicked.bind(this),this.setCurrentMarker=this.setCurrentMarker.bind(this)}return t.prototype.show=function(t){var e=this;this.uiContainer=document.createElement("div"),this.uiContainer.style.visibility=t,this.uiContainer.className=this.toolbarStyleClass.name+" "+h.fadeInAnimationClassName+" "+(this.uiStyleSettings.toolbarStyleColorsClassName?this.uiStyleSettings.toolbarStyleColorsClassName:this.toolbarStyleColorsClass.name);var i=document.createElement("div");i.className=this.toolbarBlockStyleClass.name,i.style.whiteSpace="nowrap",this.uiContainer.appendChild(i),this.addActionButton(i,'<svg viewBox="0 0 24 24"><path d="M10.07 14.27a.997.997 0 011.33.48l2.3 4.99 1.8-.85-2.31-4.98c-.24-.5-.02-1.1.48-1.33l.28-.08 2.3-.45L8 5.12V15.9l1.82-1.47.25-.16m3.57 7.7a.99.99 0 01-1.33-.47l-2.18-4.74-2.51 2.02c-.17.14-.38.22-.62.22a1 1 0 01-1-1V3a1 1 0 011-1c.24 0 .47.09.64.23l.01-.01 11.49 9.64a1.001 1.001 0 01-.44 1.75l-3.16.62 2.2 4.73c.26.5.02 1.09-.48 1.32l-3.62 1.69z"/></svg>',"select"),this.addActionButton(i,'<svg viewBox="0 0 24 24"><path d="M9 3v1H4v2h1v13a2 2 0 002 2h10a2 2 0 002-2V6h1V4h-5V3H9M7 6h10v13H7V6m2 2v9h2V8H9m4 0v9h2V8h-2z"/></svg>',"delete"),this.uiStyleSettings.clearButtonVisible&&this.addActionButton(i,'<svg viewBox="0 0 24 24"><path d="M19.36 2.72l1.42 1.42-5.72 5.71c1.07 1.54 1.22 3.39.32 4.59L9.06 8.12c1.2-.9 3.05-.75 4.59.32l5.71-5.72M5.93 17.57c-2.01-2.01-3.24-4.41-3.58-6.65l4.88-2.09 7.44 7.44-2.09 4.88c-2.24-.34-4.64-1.57-6.65-3.58z"/></svg>',"clear"),this.uiStyleSettings.undoButtonVisible&&this.addActionButton(i,'<svg viewBox="0 0 24 24"><path d="M12.5 8c-2.65 0-5.05 1-6.9 2.6L2 7v9h9l-3.62-3.62c1.39-1.16 3.16-1.88 5.12-1.88 3.54 0 6.55 2.31 7.6 5.5l2.37-.78C21.08 11.03 17.15 8 12.5 8z"/></svg>',"undo"),this.uiStyleSettings.redoButtonVisible&&this.addActionButton(i,'<svg viewBox="0 0 24 24"><path d="M18.4 10.6C16.55 9 14.15 8 11.5 8c-4.65 0-8.58 3.03-9.96 7.22L3.9 16a8.002 8.002 0 017.6-5.5c1.95 0 3.73.72 5.12 1.88L13 16h9V7l-3.6 3.6z"/></svg>',"redo"),this.uiStyleSettings.zoomButtonVisible&&this.addActionButton(i,'<svg viewBox="0 0 24 24"><path d="M15.5 14l5 5-1.5 1.5-5-5v-.79l-.27-.28A6.471 6.471 0 019.5 16 6.5 6.5 0 013 9.5 6.5 6.5 0 019.5 3 6.5 6.5 0 0116 9.5c0 1.61-.59 3.09-1.57 4.23l.28.27h.79m-6 0C12 14 14 12 14 9.5S12 5 9.5 5 5 7 5 9.5 7 14 9.5 14m2.5-4h-2v2H9v-2H7V9h2V7h1v2h2v1z"/></svg>',"zoom"),this.uiStyleSettings.zoomButtonVisible&&this.uiStyleSettings.zoomOutButtonVisible&&this.addActionButton(i,'<svg viewBox="0 0 24 24"><path d="M15.5 14h-.79l-.28-.27A6.471 6.471 0 0016 9.5 6.5 6.5 0 009.5 3 6.5 6.5 0 003 9.5 6.5 6.5 0 009.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 5 1.5-1.5-5-5m-6 0C7 14 5 12 5 9.5S7 5 9.5 5 14 7 14 9.5 12 14 9.5 14M7 9h5v1H7V9z"/></svg>',"zoom-out"),this.uiStyleSettings.notesButtonVisible&&this.addActionButton(i,'<svg viewBox="0 0 24 24"><path d="M18.13 12l1.26-1.26c.44-.44 1-.68 1.61-.74V9l-6-6H5c-1.11 0-2 .89-2 2v14a2 2 0 002 2h6v-1.87l.13-.13H5V5h7v7h6.13M14 4.5l5.5 5.5H14V4.5m5.13 9.33l2.04 2.04L15.04 22H13v-2.04l6.13-6.13m3.72.36l-.98.98-2.04-2.04.98-.98c.19-.2.52-.2.72 0l1.32 1.32c.2.2.2.53 0 .72z"/></svg>',"notes"),this.markerButtonBlock=document.createElement("div"),this.markerButtonBlock.className=this.toolbarBlockStyleClass.name,this.markerButtonBlock.style.flexGrow="2",this.markerButtonBlock.style.textAlign="center",this.uiContainer.appendChild(this.markerButtonBlock),this.markerButtonOverflowBlock=document.createElement("div"),this.markerButtonOverflowBlock.className=this.toolbarOverflowBlockStyleClass.name+" "+(this.uiStyleSettings.toolbarOverflowBlockStyleColorsClassName?this.uiStyleSettings.toolbarOverflowBlockStyleColorsClassName:this.toolbarOverflowBlockStyleColorsClass.name),this.markerButtonOverflowBlock.style.display="none",this.uiContainer.appendChild(this.markerButtonOverflowBlock),this.markerItems&&(this.markerItems.forEach((function(t){var i=document.createElement("div");i.className=""+e.toolbarButtonStyleClass.name,i.setAttribute("data-type-name",t.typeName),i.innerHTML=t.icon,i.addEventListener("click",(function(){e.markerToolbarButtonClicked(i,t)})),e.buttons.push(i),e.markerButtons.push(i)})),this.overflowButton=document.createElement("div"),this.overflowButton.className=this.toolbarButtonStyleClass.name+" "+(this.uiStyleSettings.toolbarButtonStyleColorsClassName?this.uiStyleSettings.toolbarButtonStyleColorsClassName:this.toolbarButtonStyleColorsClass.name),this.overflowButton.innerHTML='<svg viewBox="0 0 24 24"><path d="M12 16a2 2 0 012 2 2 2 0 01-2 2 2 2 0 01-2-2 2 2 0 012-2m0-6a2 2 0 012 2 2 2 0 01-2 2 2 2 0 01-2-2 2 2 0 012-2m0-6a2 2 0 012 2 2 2 0 01-2 2 2 2 0 01-2-2 2 2 0 012-2z"/></svg>',this.overflowButton.addEventListener("click",this.overflowButtonClicked),this.markerButtonBlock.appendChild(this.overflowButton));var o=document.createElement("div");o.className=this.toolbarBlockStyleClass.name,o.style.whiteSpace="nowrap",o.style.display=!1!==this.uiStyleSettings.resultButtonBlockVisible?"":"none",this.uiContainer.appendChild(o),this.addActionButton(o,'<svg viewBox="0 0 24 24"><path d="M9 20.42l-6.21-6.21 2.83-2.83L9 14.77l9.88-9.89 2.83 2.83L9 20.42z"/></svg>',"render"),this.addActionButton(o,'<svg viewBox="0 0 24 24"><path d="M20 6.91L17.09 4 12 9.09 6.91 4 4 6.91 9.09 12 4 17.09 6.91 20 12 14.91 17.09 20 20 17.09 14.91 12 20 6.91z"/></svg>',"close"),this.markerjsContainer.appendChild(this.uiContainer),this.setSelectMode(),this.setCurrentMarker(),this.adjustLayout()},t.prototype.addButtonClickListener=function(t){this.buttonClickListeners.push(t)},t.prototype.removeButtonClickListener=function(t){this.buttonClickListeners.indexOf(t)>-1&&this.buttonClickListeners.splice(this.buttonClickListeners.indexOf(t),1)},t.prototype.setSelectMode=function(){this.resetButtonStyles(),this.setActiveButton(this.buttons[0])},t.prototype.adjustLayout=function(){if(this.markerButtons&&this.markerButtons.length>0){var t=Math.floor(this.markerButtonBlock.clientWidth/this.uiStyleSettings.toolbarHeight)-1;this.markerButtonBlock.innerHTML="",this.markerButtonOverflowBlock.innerHTML="";for(var e=0;e<this.markerButtons.length;e++)e<t||e===t&&this.markerButtons.length-1===t?this.markerButtonBlock.appendChild(this.markerButtons[e]):(e===t&&this.markerButtonBlock.appendChild(this.overflowButton),this.markerButtonOverflowBlock.appendChild(this.markerButtons[e]))}},t.prototype.overflowButtonClicked=function(){"none"!==this.markerButtonOverflowBlock.style.display?(this.markerButtonOverflowBlock.className=this.markerButtonOverflowBlock.className.replace(h.fadeInAnimationClassName,""),this.markerButtonOverflowBlock.style.display="none"):(this.markerButtonOverflowBlock.className+=" "+h.fadeInAnimationClassName,this.markerButtonOverflowBlock.style.top=this.uiContainer.offsetTop+this.overflowButton.offsetHeight+"px",this.markerButtonOverflowBlock.style.right=this.uiContainer.offsetWidth-this.overflowButton.offsetLeft-this.overflowButton.offsetWidth+2*this.uiContainer.offsetLeft+"px",this.markerButtonOverflowBlock.style.display="inline-block")},t.prototype.resetButtonStyles=function(){var t=this;this.buttons.forEach((function(e){e.className=e.className.replace(t.uiStyleSettings.toolbarButtonStyleColorsClassName?t.uiStyleSettings.toolbarButtonStyleColorsClassName:t.toolbarButtonStyleColorsClass.name,"").trim(),e.className=e.className.replace(t.uiStyleSettings.toolbarActiveButtonStyleColorsClassName?t.uiStyleSettings.toolbarActiveButtonStyleColorsClassName:t.toolbarActiveButtonStyleColorsClass.name,"").trim(),e.className+=" "+(t.uiStyleSettings.toolbarButtonStyleColorsClassName?t.uiStyleSettings.toolbarButtonStyleColorsClassName:t.toolbarButtonStyleColorsClass.name)}))},t.prototype.addActionButton=function(t,e,i){var o=this,s=document.createElement("div");switch(s.className=""+this.toolbarButtonStyleClass.name,s.innerHTML=e,s.setAttribute("data-action",i),s.addEventListener("click",(function(){o.actionToolbarButtonClicked(s,i)})),i){case"select":s.style.fill=this.uiStyleSettings.selectButtonColor;break;case"delete":case"clear":s.style.fill=this.uiStyleSettings.deleteButtonColor;break;case"undo":case"redo":s.style.fill=this.uiStyleSettings.selectButtonColor;break;case"render":s.style.fill=this.uiStyleSettings.okButtonColor;break;case"close":s.style.fill=this.uiStyleSettings.closeButtonColor}t.appendChild(s),this.buttons.push(s)},t.prototype.addStyles=function(){this.toolbarStyleClass=h.addClass(new p("toolbar","\n      width: 100%;\n      flex-shrink: 0;\n      display: flex;\n      flex-direction: row;\n      justify-content: space-between;      \n      height: "+this.uiStyleSettings.toolbarHeight+"px;\n      box-sizing: content-box;\n      "+("inline"===this.displayMode?"border-top-left-radius: "+Math.round(this.uiStyleSettings.toolbarHeight/10)+"px;":"")+"\n      "+("inline"===this.displayMode?"border-top-right-radius: "+Math.round(this.uiStyleSettings.toolbarHeight/10)+"px;":"")+"\n      overflow: hidden;\n    ")),this.toolbarStyleColorsClass=h.addClass(new p("toolbar_colors","\n      background-color: "+this.uiStyleSettings.toolbarBackgroundColor+";\n      box-shadow: 0px 3px rgba(33, 33, 33, 0.1);\n    ")),this.toolbarBlockStyleClass=h.addClass(new p("toolbar-block","\n        display: inline-block;\n        box-sizing: content-box;\n    ")),this.toolbarOverflowBlockStyleClass=h.addClass(new p("toolbar-overflow-block","\n        position: absolute;\n        top: "+this.uiStyleSettings.toolbarHeight+"px;\n        max-width: "+2*this.uiStyleSettings.toolbarHeight+"px;\n        z-index: 10;\n        box-sizing: content-box;\n      ")),this.toolbarOverflowBlockStyleColorsClass=h.addClass(new p("toolbar-overflow-block_colors","\n        background-color: "+this.uiStyleSettings.toolbarBackgroundColor+";\n      "));var t=this.uiStyleSettings.toolbarHeight/4;this.toolbarButtonStyleClass=h.addClass(new p("toolbar_button","\n      display: inline-block;\n      width: "+(this.uiStyleSettings.toolbarHeight-2*t)+"px;\n      height: "+(this.uiStyleSettings.toolbarHeight-2*t)+"px;\n      padding: "+t+"px;\n      box-sizing: content-box;\n    ")),this.toolbarButtonStyleColorsClass=h.addClass(new p("toolbar_button_colors","\n      fill: "+this.uiStyleSettings.toolbarColor+";\n    ")),this.toolbarActiveButtonStyleColorsClass=h.addClass(new p("toolbar_active_button","\n      fill: "+this.uiStyleSettings.toolbarColor+";\n      background-color: "+this.uiStyleSettings.toolbarBackgroundHoverColor+"\n    ")),h.addRule(new l("."+this.toolbarButtonStyleClass.name+" svg","\n      height: "+this.uiStyleSettings.toolbarHeight/2+"px;\n    ")),h.addRule(new l("."+this.toolbarButtonStyleColorsClass.name+":hover","\n        background-color: "+this.uiStyleSettings.toolbarBackgroundHoverColor+"\n    "))},t.prototype.markerToolbarButtonClicked=function(t,e){this.setActiveButton(t),this.buttonClickListeners&&this.buttonClickListeners.length>0&&this.buttonClickListeners.forEach((function(t){return t("marker",e)})),this.markerButtonOverflowBlock.style.display="none"},t.prototype.actionToolbarButtonClicked=function(t,e){this.buttonClickListeners&&this.buttonClickListeners.length>0&&this.buttonClickListeners.forEach((function(t){return t("action",e)})),this.markerButtonOverflowBlock.style.display="none",this.setActiveButton(this.buttons[0])},t.prototype.setActiveButton=function(t){this.resetButtonStyles(),t.className=t.className.replace(this.uiStyleSettings.toolbarButtonStyleColorsClassName?this.uiStyleSettings.toolbarButtonStyleColorsClassName:this.toolbarButtonStyleColorsClass.name,"").trim(),t.className+=" "+(this.uiStyleSettings.toolbarActiveButtonStyleColorsClassName?this.uiStyleSettings.toolbarActiveButtonStyleColorsClassName:this.toolbarActiveButtonStyleColorsClass.name)},t.prototype.setActiveMarkerButton=function(t){var e=this.markerButtons.find((function(e){return e.getAttribute("data-type-name")===t}));e&&this.setActiveButton(e)},t.prototype.setCurrentMarker=function(t){var e=this;this.currentMarker=t,this.buttons.filter((function(t){return/delete|notes/.test(t.getAttribute("data-action"))})).forEach((function(t){void 0===e.currentMarker?(t.style.fillOpacity="0.4",t.style.pointerEvents="none"):(t.style.fillOpacity="1",t.style.pointerEvents="all")}))},t}(),u=function(){function t(t,e,i){this.panels=[],this.panelButtons=[],this.markerjsContainer=t,this.displayMode=e,this.uiStyleSettings=i,this.panelButtonClick=this.panelButtonClick.bind(this),this.addStyles()}return t.prototype.addStyles=function(){var t;this.toolboxStyleClass=h.addClass(new p("toolbox","\n      width: 100%;\n      flex-shrink: 0;\n      display: flex;\n      flex-direction: column;\n      font-family: sans-serif;\n      "+("popup"===this.displayMode?"height:"+2.5*this.uiStyleSettings.toolbarHeight+"px;":"")+"\n      box-sizing: content-box;\n      "+("popup"===this.displayMode?"background-color: "+this.uiStyleSettings.canvasBackgroundColor+";":"")+"\n      "+("inline"===this.displayMode?"border-bottom-left-radius: "+Math.round(this.uiStyleSettings.toolbarHeight/10)+"px;":"")+"\n      "+("inline"===this.displayMode?"border-bottom-right-radius: "+Math.round(this.uiStyleSettings.toolbarHeight/10)+"px;":"")+"\n      overflow: hidden;\n    ")),this.toolboxStyleColorsClass=h.addClass(new p("toolbox_colors","\n      color: "+this.uiStyleSettings.toolboxColor+";\n    "));var e=this.uiStyleSettings.toolbarHeight/4;this.toolboxButtonRowStyleClass=h.addClass(new p("toolbox-button-row","\n      display: flex;\n      cursor: default;\n      box-sizing: content-box;\n    ")),this.toolboxButtonRowStyleColorsClass=h.addClass(new p("toolbox-button-row_colors","\n      background-color: "+this.uiStyleSettings.toolbarBackgroundColor+";\n    ")),this.toolboxPanelRowStyleClass=h.addClass(new p("toolbox-panel-row","\n      display: flex;\n      "+("inline"===this.displayMode?"position: absolute;":"")+"\n      "+("inline"===this.displayMode?"bottom: "+this.uiStyleSettings.toolbarHeight+"px;":"")+"\n      cursor: default;\n      height: "+1.5*this.uiStyleSettings.toolbarHeight+"px;\n      "+("inline"===this.displayMode?"width: 100%;":"")+"\n      box-sizing: content-box;\n    ")),this.toolboxPanelRowStyleColorsClass=h.addClass(new p("toolbox-panel-row_colors","\n      background-color: "+(null!==(t=this.uiStyleSettings.toolboxBackgroundColor)&&void 0!==t?t:this.uiStyleSettings.toolbarBackgroundHoverColor)+";\n    ")),this.toolboxButtonStyleClass=h.addClass(new p("toolbox_button","\n      display: inline-block;\n      width: "+(this.uiStyleSettings.toolbarHeight-2*e)+"px;\n      height: "+(this.uiStyleSettings.toolbarHeight-2*e)+"px;\n      padding: "+e+"px;\n      box-sizing: content-box;\n    ")),this.toolboxButtonStyleColorsClass=h.addClass(new p("toolbox-button_colors","\n      fill: "+this.uiStyleSettings.toolbarColor+";\n    ")),this.toolboxActiveButtonStyleColorsClass=h.addClass(new p("toolbox-active-button_colors","\n      background-color: "+this.uiStyleSettings.toolbarBackgroundHoverColor+";\n      fill: "+this.uiStyleSettings.toolbarColor+";\n    ")),h.addRule(new l("."+this.toolboxButtonStyleColorsClass.name+":hover","\n        background-color: "+this.uiStyleSettings.toolbarBackgroundHoverColor+"\n    ")),h.addRule(new l("."+this.toolboxButtonStyleClass.name+" svg","\n      height: "+this.uiStyleSettings.toolbarHeight/2+"px;\n    "))},t.prototype.show=function(t){var e;this.uiContainer=document.createElement("div"),this.uiContainer.style.visibility=t,this.uiContainer.className=this.toolboxStyleClass.name+" "+(null!==(e=this.uiStyleSettings.toolboxStyleColorsClassName)&&void 0!==e?e:this.toolboxStyleColorsClass.name),this.markerjsContainer.appendChild(this.uiContainer)},t.prototype.setPanelButtons=function(t){var e,i,o=this;this.panels=t,void 0!==this.uiContainer&&(this.uiContainer.innerHTML="",this.panelRow=document.createElement("div"),this.panelRow.className=this.toolboxPanelRowStyleClass.name+" "+(null!==(e=this.uiStyleSettings.toolboxPanelRowStyleColorsClassName)&&void 0!==e?e:this.toolboxPanelRowStyleColorsClass.name),this.uiContainer.appendChild(this.panelRow),this.buttonRow=document.createElement("div"),this.buttonRow.className=this.toolboxButtonRowStyleClass.name+" "+(null!==(i=this.uiStyleSettings.toolboxButtonRowStyleColorsClassName)&&void 0!==i?i:this.toolboxButtonRowStyleColorsClass.name)+" ",this.uiContainer.appendChild(this.buttonRow),this.panelButtons.splice(0),this.panels.forEach((function(t){var e,i=document.createElement("div");i.className=o.toolboxButtonStyleClass.name+" "+(null!==(e=o.uiStyleSettings.toolboxButtonStyleColorsClassName)&&void 0!==e?e:o.toolboxButtonStyleColorsClass.name),i.innerHTML=t.icon,i.title=t.title,i.addEventListener("click",(function(){o.panelButtonClick(t)})),o.panelButtons.push(i),o.buttonRow.appendChild(i)})),"inline"===this.displayMode?this.panelRow.style.display="none":this.panelRow.style.visibility="hidden")},t.prototype.panelButtonClick=function(t){var e=this,i=-1;if(t!==this.activePanel){i=this.panels.indexOf(t),this.panelRow.innerHTML="";var o=t.getUi();o.style.margin=this.uiStyleSettings.toolbarHeight/4+"px",this.panelRow.appendChild(o),this.panelRow.style.display="flex",this.panelRow.style.visibility="visible",this.panelRow.className=this.panelRow.className.replace(h.fadeOutAnimationClassName,""),this.panelRow.className+=" "+h.fadeInAnimationClassName,this.activePanel=t}else this.activePanel=void 0,this.panelRow.className=this.panelRow.className.replace(h.fadeInAnimationClassName,""),this.panelRow.className+=" "+h.fadeOutAnimationClassName,setTimeout((function(){"inline"===e.displayMode?e.panelRow.style.display="none":e.panelRow.style.visibility="hidden"}),200);this.panelButtons.forEach((function(t,o){var s,r;t.className=e.toolboxButtonStyleClass.name+" "+(o===i?""+(null!==(s=e.uiStyleSettings.toolboxActiveButtonStyleColorsClassName)&&void 0!==s?s:e.toolboxActiveButtonStyleColorsClass.name):""+(null!==(r=e.uiStyleSettings.toolboxButtonStyleColorsClassName)&&void 0!==r?r:e.toolboxButtonStyleColorsClass.name))}))},t}(),d=function(t,e){this.title=t,this.icon=e},y=function(t){function i(e,i,o,s){var r=t.call(this,e,s||'<svg viewBox="0 0 24 24"><path d="M17.5 12a1.5 1.5 0 01-1.5-1.5A1.5 1.5 0 0117.5 9a1.5 1.5 0 011.5 1.5 1.5 1.5 0 01-1.5 1.5m-3-4A1.5 1.5 0 0113 6.5 1.5 1.5 0 0114.5 5 1.5 1.5 0 0116 6.5 1.5 1.5 0 0114.5 8m-5 0A1.5 1.5 0 018 6.5 1.5 1.5 0 019.5 5 1.5 1.5 0 0111 6.5 1.5 1.5 0 019.5 8m-3 4A1.5 1.5 0 015 10.5 1.5 1.5 0 016.5 9 1.5 1.5 0 018 10.5 1.5 1.5 0 016.5 12M12 3a9 9 0 00-9 9 9 9 0 009 9 1.5 1.5 0 001.5-1.5c0-.39-.15-.74-.39-1-.23-.27-.38-.62-.38-1a1.5 1.5 0 011.5-1.5H16a5 5 0 005-5c0-4.42-4.03-8-9-8z"/></svg>')||this;return r.colors=[],r.addTransparent=!1,r.colorBoxes=[],r.colors=i,r.currentColor=o,r.setCurrentColor=r.setCurrentColor.bind(r),r.getColorBox=r.getColorBox.bind(r),r}return e(i,t),i.prototype.getUi=function(){var t=this,e=document.createElement("div");return e.style.overflow="hidden",e.style.whiteSpace="nowrap",this.colors.forEach((function(i){var o=t.getColorBox(i);e.appendChild(o),t.colorBoxes.push(o)})),e},i.prototype.getColorBox=function(t){var e=this,i=h.settings.toolbarHeight/4,o=h.settings.toolbarHeight-i,s=document.createElement("div");s.style.display="inline-block",s.style.boxSizing="content-box",s.style.width=o-2+"px",s.style.height=o-2+"px",s.style.padding="1px",s.style.marginRight="2px",s.style.marginBottom="2px",s.style.borderWidth="2px",s.style.borderStyle="solid",s.style.borderRadius=(o+2)/2+"px",s.style.borderColor=t===this.currentColor?h.settings.toolboxAccentColor:"transparent",s.addEventListener("click",(function(){e.setCurrentColor(t,s)}));var r=document.createElement("div");return r.style.display="inline-block",r.style.width=o-2+"px",r.style.height=o-2+"px",r.style.backgroundColor=t,r.style.borderRadius=o/2+"px","transparent"===t&&(r.style.fill=h.settings.toolboxAccentColor,r.innerHTML='<svg viewBox="0 0 24 24">\n        <path d="M2,5.27L3.28,4L20,20.72L18.73,22L15.65,18.92C14.5,19.3 13.28,19.5 12,19.5C7,19.5 2.73,16.39 1,12C1.69,10.24 2.79,8.69 4.19,7.46L2,5.27M12,9A3,3 0 0,1 15,12C15,12.35 14.94,12.69 14.83,13L11,9.17C11.31,9.06 11.65,9 12,9M12,4.5C17,4.5 21.27,7.61 23,12C22.18,14.08 20.79,15.88 19,17.19L17.58,15.76C18.94,14.82 20.06,13.54 20.82,12C19.17,8.64 15.76,6.5 12,6.5C10.91,6.5 9.84,6.68 8.84,7L7.3,5.47C8.74,4.85 10.33,4.5 12,4.5M3.18,12C4.83,15.36 8.24,17.5 12,17.5C12.69,17.5 13.37,17.43 14,17.29L11.72,15C10.29,14.85 9.15,13.71 9,12.28L5.6,8.87C4.61,9.72 3.78,10.78 3.18,12Z" />\n      </svg>'),s.appendChild(r),s},i.prototype.setCurrentColor=function(t,e){this.currentColor=t,this.colorBoxes.forEach((function(t){t.style.borderColor=t===e?h.settings.toolboxAccentColor:"transparent"})),this.onColorChanged&&this.onColorChanged(t)},i}(d),g=function(){function t(t,e,i){this._state="new",this._isSelected=!1,this._container=t,this._overlayContainer=e,this.globalSettings=i}return Object.defineProperty(t.prototype,"typeName",{get:function(){return Object.getPrototypeOf(this).constructor.typeName},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"container",{get:function(){return this._container},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"overlayContainer",{get:function(){return this._overlayContainer},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"state",{get:function(){return this._state},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"toolboxPanels",{get:function(){return[]},enumerable:!1,configurable:!0}),t.prototype.ownsTarget=function(t){return!1},Object.defineProperty(t.prototype,"isSelected",{get:function(){return this._isSelected},enumerable:!1,configurable:!0}),t.prototype.select=function(){this.container.style.cursor="move",this._isSelected=!0},t.prototype.deselect=function(){this.container.style.cursor="default",this._isSelected=!1},t.prototype.pointerDown=function(t,e){},t.prototype.dblClick=function(t,e){},t.prototype.manipulate=function(t){},t.prototype.pointerUp=function(t){},t.prototype.dispose=function(){},t.prototype.addMarkerVisualToContainer=function(t){this.container.childNodes.length>0?this.container.insertBefore(t,this.container.childNodes[0]):this.container.appendChild(t)},t.prototype.getState=function(){return{typeName:t.typeName,state:this.state,notes:this.notes}},t.prototype.restoreState=function(t){this._state=t.state,this.notes=t.notes},t.prototype.scale=function(t,e){},t.prototype.colorChanged=function(t){this.onColorChanged&&this.onColorChanged(t)},t.prototype.fillColorChanged=function(t){this.onFillColorChanged&&this.onFillColorChanged(t)},t.typeName="MarkerBase",t}(),f=function(){function t(){this.findGripByVisual=this.findGripByVisual.bind(this)}return t.prototype.findGripByVisual=function(t){return this.topLeft.ownsTarget(t)?this.topLeft:this.topCenter.ownsTarget(t)?this.topCenter:this.topRight.ownsTarget(t)?this.topRight:this.centerLeft.ownsTarget(t)?this.centerLeft:this.centerRight.ownsTarget(t)?this.centerRight:this.bottomLeft.ownsTarget(t)?this.bottomLeft:this.bottomCenter.ownsTarget(t)?this.bottomCenter:this.bottomRight.ownsTarget(t)?this.bottomRight:void 0},t}(),v=function(){function t(){this.GRIP_SIZE=10,this.visual=r.createGroup(),this.visual.appendChild(r.createCircle(1.5*this.GRIP_SIZE,[["fill","transparent"]])),this.visual.appendChild(r.createCircle(this.GRIP_SIZE,[["fill","#cccccc"],["fill-opacity","0.7"],["stroke","#333333"],["stroke-width","2"],["stroke-opacity","0.7"]]))}return t.prototype.ownsTarget=function(t){return t===this.visual||t===this.visual.childNodes[0]||t===this.visual.childNodes[1]},t}(),m=function(){function t(){}return t.toITransformMatrix=function(t){return{a:t.a,b:t.b,c:t.c,d:t.d,e:t.e,f:t.f}},t.toSVGMatrix=function(t,e){return t.a=e.a,t.b=e.b,t.c=e.c,t.d=e.d,t.e=e.e,t.f=e.f,t},t}(),C=function(t){function i(e,i,o){var s=t.call(this,e,i,o)||this;return s.left=0,s.top=0,s.width=0,s.height=0,s.defaultSize={x:50,y:20},s.offsetX=0,s.offsetY=0,s.rotationAngle=0,s.CB_DISTANCE=10,s.container.transform.baseVal.appendItem(r.createTransform()),s.setupControlBox(),s}return e(i,t),Object.defineProperty(i.prototype,"centerX",{get:function(){return this.left+this.width/2},enumerable:!1,configurable:!0}),Object.defineProperty(i.prototype,"centerY",{get:function(){return this.top+this.height/2},enumerable:!1,configurable:!0}),Object.defineProperty(i.prototype,"visual",{get:function(){return this._visual},set:function(t){this._visual=t;var e=r.createTransform();this._visual.transform.baseVal.appendItem(e)},enumerable:!1,configurable:!0}),i.prototype.ownsTarget=function(e){return!!t.prototype.ownsTarget.call(this,e)||!(void 0===this.controlGrips.findGripByVisual(e)&&!this.rotatorGrip.ownsTarget(e))},i.prototype.pointerDown=function(e,i){t.prototype.pointerDown.call(this,e,i),"new"===this.state&&(this.left=e.x,this.top=e.y),this.manipulationStartLeft=this.left,this.manipulationStartTop=this.top,this.manipulationStartWidth=this.width,this.manipulationStartHeight=this.height;var o=this.unrotatePoint(e);if(this.manipulationStartX=o.x,this.manipulationStartY=o.y,this.offsetX=o.x-this.left,this.offsetY=o.y-this.top,"new"!==this.state)if(this.select(),this.activeGrip=this.controlGrips.findGripByVisual(i),void 0!==this.activeGrip)this._state="resize";else if(this.rotatorGrip.ownsTarget(i)){this.activeGrip=this.rotatorGrip;var s=this.rotatePoint({x:this.centerX,y:this.centerY});this.left=s.x-this.width/2,this.top=s.y-this.height/2,this.moveVisual({x:this.left,y:this.top});var r=this.container.transform.baseVal.getItem(0);r.setRotate(this.rotationAngle,this.centerX,this.centerY),this.container.transform.baseVal.replaceItem(r,0),this.adjustControlBox(),this._state="rotate"}else this._state="move"},i.prototype.pointerUp=function(e){var i=this.state;t.prototype.pointerUp.call(this,e),"creating"===this.state&&this.width<10&&this.height<10?(this.width=this.defaultSize.x,this.height=this.defaultSize.y):this.manipulate(e),this._state="select","creating"===i&&this.onMarkerCreated&&this.onMarkerCreated(this)},i.prototype.moveVisual=function(t){this.visual.style.transform="translate("+t.x+"px, "+t.y+"px)"},i.prototype.manipulate=function(t){var e=this.unrotatePoint(t);"creating"===this.state?this.resize(t):"move"===this.state?(this.left=this.manipulationStartLeft+(e.x-this.manipulationStartLeft)-this.offsetX,this.top=this.manipulationStartTop+(e.y-this.manipulationStartTop)-this.offsetY,this.moveVisual({x:this.left,y:this.top}),this.adjustControlBox()):"resize"===this.state?this.resize(e):"rotate"===this.state&&this.rotate(t)},i.prototype.resize=function(t){var e=this.manipulationStartLeft,i=this.manipulationStartWidth,o=this.manipulationStartTop,s=this.manipulationStartHeight;switch(this.activeGrip){case this.controlGrips.bottomLeft:case this.controlGrips.centerLeft:case this.controlGrips.topLeft:e=this.manipulationStartLeft+t.x-this.manipulationStartX,i=this.manipulationStartWidth+this.manipulationStartLeft-e;break;case this.controlGrips.bottomRight:case this.controlGrips.centerRight:case this.controlGrips.topRight:case void 0:i=this.manipulationStartWidth+t.x-this.manipulationStartX}switch(this.activeGrip){case this.controlGrips.topCenter:case this.controlGrips.topLeft:case this.controlGrips.topRight:o=this.manipulationStartTop+t.y-this.manipulationStartY,s=this.manipulationStartHeight+this.manipulationStartTop-o;break;case this.controlGrips.bottomCenter:case this.controlGrips.bottomLeft:case this.controlGrips.bottomRight:case void 0:s=this.manipulationStartHeight+t.y-this.manipulationStartY}i>=0?(this.left=e,this.width=i):(this.left=e+i,this.width=-i),s>=0?(this.top=o,this.height=s):(this.top=o+s,this.height=-s),this.setSize()},i.prototype.setSize=function(){this.moveVisual({x:this.left,y:this.top}),this.adjustControlBox()},i.prototype.rotate=function(t){if(Math.abs(t.x-this.centerX)>.1){var e=Math.sign(t.x-this.centerX);this.rotationAngle=180*Math.atan((t.y-this.centerY)/(t.x-this.centerX))/Math.PI+90*e,this.applyRotation()}},i.prototype.applyRotation=function(){var t=this.container.transform.baseVal.getItem(0);t.setRotate(this.rotationAngle,this.centerX,this.centerY),this.container.transform.baseVal.replaceItem(t,0)},i.prototype.rotatePoint=function(t){if(0===this.rotationAngle)return t;var e=this.container.getCTM(),i=r.createPoint(t.x,t.y);return{x:(i=i.matrixTransform(e)).x,y:i.y}},i.prototype.unrotatePoint=function(t){if(0===this.rotationAngle)return t;var e=this.container.getCTM();e=e.inverse();var i=r.createPoint(t.x,t.y);return{x:(i=i.matrixTransform(e)).x,y:i.y}},i.prototype.select=function(){t.prototype.select.call(this),this.adjustControlBox(),this.controlBox.style.display=""},i.prototype.deselect=function(){t.prototype.deselect.call(this),this.controlBox.style.display="none"},i.prototype.setupControlBox=function(){this.controlBox=r.createGroup();var t=r.createTransform();t.setTranslate(-this.CB_DISTANCE/2,-this.CB_DISTANCE/2),this.controlBox.transform.baseVal.appendItem(t),this.container.appendChild(this.controlBox),this.controlRect=r.createRect(this.width+this.CB_DISTANCE,this.height+this.CB_DISTANCE,[["stroke","black"],["stroke-width","1"],["stroke-opacity","0.5"],["stroke-dasharray","3, 2"],["fill","transparent"],["pointer-events","none"]]),this.controlBox.appendChild(this.controlRect),this.rotatorGripLine=r.createLine((this.width+2*this.CB_DISTANCE)/2,this.top-this.CB_DISTANCE,(this.width+2*this.CB_DISTANCE)/2,this.top-3*this.CB_DISTANCE,[["stroke","black"],["stroke-width","1"],["stroke-opacity","0.5"],["stroke-dasharray","3, 2"]]),this.controlBox.appendChild(this.rotatorGripLine),this.controlGrips=new f,this.addControlGrips(),this.controlBox.style.display="none"},i.prototype.adjustControlBox=function(){var t=this.controlBox.transform.baseVal.getItem(0);t.setTranslate(this.left-this.CB_DISTANCE/2,this.top-this.CB_DISTANCE/2),this.controlBox.transform.baseVal.replaceItem(t,0),this.controlRect.setAttribute("width",(this.width+this.CB_DISTANCE).toString()),this.controlRect.setAttribute("height",(this.height+this.CB_DISTANCE).toString()),this.rotatorGripLine.setAttribute("x1",((this.width+this.CB_DISTANCE)/2).toString()),this.rotatorGripLine.setAttribute("y1",(-this.CB_DISTANCE/2).toString()),this.rotatorGripLine.setAttribute("x2",((this.width+this.CB_DISTANCE)/2).toString()),this.rotatorGripLine.setAttribute("y2",(3*-this.CB_DISTANCE).toString()),this.positionGrips()},i.prototype.addControlGrips=function(){this.controlGrips.topLeft=this.createGrip(),this.controlGrips.topCenter=this.createGrip(),this.controlGrips.topRight=this.createGrip(),this.controlGrips.centerLeft=this.createGrip(),this.controlGrips.centerRight=this.createGrip(),this.controlGrips.bottomLeft=this.createGrip(),this.controlGrips.bottomCenter=this.createGrip(),this.controlGrips.bottomRight=this.createGrip(),this.rotatorGrip=this.createGrip(),this.positionGrips()},i.prototype.createGrip=function(){var t=new v;return t.visual.transform.baseVal.appendItem(r.createTransform()),this.controlBox.appendChild(t.visual),t},i.prototype.positionGrips=function(){var t=this.controlGrips.topLeft.GRIP_SIZE,e=-t/2,i=e,o=(this.width+this.CB_DISTANCE)/2-t/2,s=(this.height+this.CB_DISTANCE)/2-t/2,r=this.height+this.CB_DISTANCE-t/2,n=this.width+this.CB_DISTANCE-t/2;this.positionGrip(this.controlGrips.topLeft.visual,e,i),this.positionGrip(this.controlGrips.topCenter.visual,o,i),this.positionGrip(this.controlGrips.topRight.visual,n,i),this.positionGrip(this.controlGrips.centerLeft.visual,e,s),this.positionGrip(this.controlGrips.centerRight.visual,n,s),this.positionGrip(this.controlGrips.bottomLeft.visual,e,r),this.positionGrip(this.controlGrips.bottomCenter.visual,o,r),this.positionGrip(this.controlGrips.bottomRight.visual,n,r),this.positionGrip(this.rotatorGrip.visual,o,i-3*this.CB_DISTANCE)},i.prototype.positionGrip=function(t,e,i){var o=t.transform.baseVal.getItem(0);o.setTranslate(e,i),t.transform.baseVal.replaceItem(o,0)},i.prototype.hideControlBox=function(){this.controlBox.style.display="none"},i.prototype.showControlBox=function(){this.controlBox.style.display=""},i.prototype.getState=function(){return Object.assign({left:this.left,top:this.top,width:this.width,height:this.height,rotationAngle:this.rotationAngle,visualTransformMatrix:m.toITransformMatrix(this.visual.transform.baseVal.getItem(0).matrix),containerTransformMatrix:m.toITransformMatrix(this.container.transform.baseVal.getItem(0).matrix)},t.prototype.getState.call(this))},i.prototype.restoreState=function(e){t.prototype.restoreState.call(this,e);var i=e;this.left=i.left,this.top=i.top,this.width=i.width,this.height=i.height,this.rotationAngle=i.rotationAngle,this.visual.transform.baseVal.getItem(0).setMatrix(m.toSVGMatrix(this.visual.transform.baseVal.getItem(0).matrix,i.visualTransformMatrix)),this.container.transform.baseVal.getItem(0).setMatrix(m.toSVGMatrix(this.container.transform.baseVal.getItem(0).matrix,i.containerTransformMatrix))},i.prototype.scale=function(e,i){t.prototype.scale.call(this,e,i);var o=this.rotatePoint({x:this.left,y:this.top}),s=this.unrotatePoint({x:o.x*e,y:o.y*i});this.left=s.x,this.top=s.y,this.width=this.width*e,this.height=this.height*i,this.adjustControlBox()},i}(g),b=function(t){function i(e,i,o){var s=t.call(this,e,i,o)||this;return s.fillColor="transparent",s.strokeColor="transparent",s.strokeWidth=0,s.strokeDasharray="",s.opacity=1,s.setStrokeColor=s.setStrokeColor.bind(s),s.setFillColor=s.setFillColor.bind(s),s.setStrokeWidth=s.setStrokeWidth.bind(s),s.setStrokeDasharray=s.setStrokeDasharray.bind(s),s.createVisual=s.createVisual.bind(s),s}return e(i,t),i.prototype.ownsTarget=function(e){return!(!t.prototype.ownsTarget.call(this,e)&&e!==this.visual)},i.prototype.createVisual=function(){this.visual=r.createRect(1,1,[["fill",this.fillColor],["stroke",this.strokeColor],["stroke-width",this.strokeWidth.toString()],["stroke-dasharray",this.strokeDasharray],["opacity",this.opacity.toString()]]),this.addMarkerVisualToContainer(this.visual)},i.prototype.pointerDown=function(e,i){t.prototype.pointerDown.call(this,e,i),"new"===this.state&&(this.createVisual(),this.moveVisual(e),this._state="creating")},i.prototype.manipulate=function(e){t.prototype.manipulate.call(this,e)},i.prototype.resize=function(e){t.prototype.resize.call(this,e),this.setSize()},i.prototype.setSize=function(){t.prototype.setSize.call(this),r.setAttributes(this.visual,[["width",this.width.toString()],["height",this.height.toString()]])},i.prototype.pointerUp=function(e){t.prototype.pointerUp.call(this,e),this.setSize()},i.prototype.setStrokeColor=function(t){this.strokeColor=t,this.visual&&r.setAttributes(this.visual,[["stroke",this.strokeColor]]),this.colorChanged(t)},i.prototype.setFillColor=function(t){this.fillColor=t,this.visual&&r.setAttributes(this.visual,[["fill",this.fillColor]])},i.prototype.setStrokeWidth=function(t){this.strokeWidth=t,this.visual&&r.setAttributes(this.visual,[["stroke-width",this.strokeWidth.toString()]])},i.prototype.setStrokeDasharray=function(t){this.strokeDasharray=t,this.visual&&r.setAttributes(this.visual,[["stroke-dasharray",this.strokeDasharray]])},i.prototype.getState=function(){return Object.assign({fillColor:this.fillColor,strokeColor:this.strokeColor,strokeWidth:this.strokeWidth,strokeDasharray:this.strokeDasharray,opacity:this.opacity},t.prototype.getState.call(this))},i.prototype.restoreState=function(e){var i=e;this.fillColor=i.fillColor,this.strokeColor=i.strokeColor,this.strokeWidth=i.strokeWidth,this.strokeDasharray=i.strokeDasharray,this.opacity=i.opacity,this.createVisual(),t.prototype.restoreState.call(this,e),this.setSize()},i.prototype.scale=function(e,i){t.prototype.scale.call(this,e,i),this.setSize()},i.title="Rectangle marker",i}(C),S=function(t){function i(e,i,o,s){var r=t.call(this,e,s||'<svg viewBox="0 0 24 24"><path d="M3 17h18v-2H3v2m0 3h18v-1H3v1m0-7h18v-3H3v3m0-9v4h18V4H3z"/></svg>')||this;return r.widths=[],r.widthBoxes=[],r.widths=i,r.currentWidth=o,r.setCurrentWidth=r.setCurrentWidth.bind(r),r}return e(i,t),i.prototype.getUi=function(){var t=this,e=document.createElement("div");return e.style.display="flex",e.style.overflow="hidden",e.style.flexGrow="2",this.widths.forEach((function(i){var o=document.createElement("div");o.style.display="flex",o.style.flexGrow="2",o.style.alignItems="center",o.style.justifyContent="space-between",o.style.padding="5px",o.style.borderWidth="2px",o.style.borderStyle="solid",o.style.borderColor=i===t.currentWidth?h.settings.toolboxAccentColor:"transparent",o.addEventListener("click",(function(){t.setCurrentWidth(i,o)})),e.appendChild(o);var s=document.createElement("div");s.innerText=i.toString(),s.style.marginRight="5px",o.appendChild(s);var r=document.createElement("div");r.style.minHeight="20px",r.style.flexGrow="2",r.style.display="flex",r.style.alignItems="center";var n=document.createElement("hr");n.style.minWidth="20px",n.style.border="0px",n.style.borderTop=i+"px solid "+h.settings.toolboxColor,n.style.flexGrow="2",r.appendChild(n),o.appendChild(r),t.widthBoxes.push(o)})),e},i.prototype.setCurrentWidth=function(t,e){this.currentWidth=t,this.widthBoxes.forEach((function(t){t.style.borderColor=t===e?h.settings.toolboxAccentColor:"transparent"})),this.onWidthChanged&&this.onWidthChanged(this.currentWidth)},i}(d),k=function(t){function i(e,i,o,s){var r=t.call(this,e,s||'<svg viewBox="0 0 24 24"><path d="M3 16h5v-2H3v2m6.5 0h5v-2h-5v2m6.5 0h5v-2h-5v2M3 20h2v-2H3v2m4 0h2v-2H7v2m4 0h2v-2h-2v2m4 0h2v-2h-2v2m4 0h2v-2h-2v2M3 12h8v-2H3v2m10 0h8v-2h-8v2M3 4v4h18V4H3z"/></svg>')||this;return r.styles=[],r.styleBoxes=[],r.styles=i,r.currentStyle=o,r.setCurrentStyle=r.setCurrentStyle.bind(r),r}return e(i,t),i.prototype.getUi=function(){var t=this,e=document.createElement("div");return e.style.display="flex",e.style.overflow="hidden",e.style.flexGrow="2",this.styles.forEach((function(i){var o=document.createElement("div");o.style.display="flex",o.style.alignItems="center",o.style.justifyContent="space-between",o.style.padding="5px",o.style.borderWidth="2px",o.style.borderStyle="solid",o.style.overflow="hidden",o.style.maxWidth=100/t.styles.length-5+"%",o.style.borderColor=i===t.currentStyle?h.settings.toolboxAccentColor:"transparent",o.addEventListener("click",(function(){t.setCurrentStyle(i,o)})),e.appendChild(o);var s=document.createElement("div");s.style.minHeight="20px",s.style.flexGrow="2",s.style.overflow="hidden";var r='<svg width="100" height="20">\n      <line x1="0" y1="10" x2="100" y2="10" stroke="'+h.settings.toolboxColor+'" stroke-width="3" '+(""!==i?'stroke-dasharray="'+i+'"':"")+" />\n  </svg>";s.innerHTML=r,o.appendChild(s),t.styleBoxes.push(o)})),e},i.prototype.setCurrentStyle=function(t,e){this.currentStyle=t,this.styleBoxes.forEach((function(t){t.style.borderColor=t===e?h.settings.toolboxAccentColor:"transparent"})),this.onStyleChanged&&this.onStyleChanged(this.currentStyle)},i}(d),w=function(t){function i(e,i,o){var s=t.call(this,e,i,o)||this;return s.strokeColor=o.defaultColor,s.strokeWidth=o.defaultStrokeWidth,s.strokeDasharray=o.defaultStrokeDasharray,s.strokePanel=new y("Line color",o.defaultColorSet,o.defaultColor),s.strokePanel.onColorChanged=s.setStrokeColor,s.strokeWidthPanel=new S("Line width",o.defaultStrokeWidths,o.defaultStrokeWidth),s.strokeWidthPanel.onWidthChanged=s.setStrokeWidth,s.strokeStylePanel=new k("Line style",o.defaultStrokeDasharrays,o.defaultStrokeDasharray),s.strokeStylePanel.onStyleChanged=s.setStrokeDasharray,s}return e(i,t),Object.defineProperty(i.prototype,"toolboxPanels",{get:function(){return[this.strokePanel,this.strokeWidthPanel,this.strokeStylePanel]},enumerable:!1,configurable:!0}),i.prototype.getState=function(){var e=t.prototype.getState.call(this);return e.typeName=i.typeName,e},i.typeName="FrameMarker",i.title="Frame marker",i.icon='<svg viewBox="0 0 24 24"><path d="M4 6v13h16V6H4m14 11H6V8h12v9z"/></svg>',i}(b),x=function(){this.defaultColorSet=["#EF4444","#10B981","#2563EB","#FFFF00","#7C3AED","#F472B6","#000000","#FFFFFF"],this.defaultColor=this.defaultColorSet[0],this.defaultFillColor=this.defaultColorSet[0],this.defaultStrokeColor=this.defaultColorSet[7],this.defaultHighlightColor=this.defaultColorSet[3],this.defaultStrokeWidth=3,this.defaultStrokeDasharray="",this.defaultHighlightOpacity=.5,this.defaultFontFamily="Helvetica, Arial, sans-serif",this.defaultStrokeWidths=[1,2,3,5,10],this.defaultStrokeDasharrays=["","3","12 3","9 6 3 6"],this.defaultOpacitySteps=[.1,.25,.5,.75,1],this.displayMode="inline",this.defaultFontFamilies=['Times, "Times New Roman", serif',"Helvetica, Arial, sans-serif",'Courier, "Courier New", monospace',"cursive","fantasy"],this.popupMargin=30,this.newFreehandMarkerOnPointerUp=!1,this.defaultColorsFollowCurrentColors=!1,this.freehandPixelRatio=1},B=function(t){function i(e,i,o){var s=t.call(this,e,i,o)||this;return s.x1=0,s.y1=0,s.x2=0,s.y2=0,s.defaultLength=50,s.manipulationStartX=0,s.manipulationStartY=0,s.manipulationStartX1=0,s.manipulationStartY1=0,s.manipulationStartX2=0,s.manipulationStartY2=0,s.setupControlBox(),s}return e(i,t),i.prototype.ownsTarget=function(e){return!!t.prototype.ownsTarget.call(this,e)||!(!this.grip1.ownsTarget(e)&&!this.grip2.ownsTarget(e))},i.prototype.pointerDown=function(e,i){t.prototype.pointerDown.call(this,e,i),this.manipulationStartX=e.x,this.manipulationStartY=e.y,"new"===this.state&&(this.x1=e.x,this.y1=e.y,this.x2=e.x,this.y2=e.y),this.manipulationStartX1=this.x1,this.manipulationStartY1=this.y1,this.manipulationStartX2=this.x2,this.manipulationStartY2=this.y2,"new"!==this.state&&(this.select(),this.grip1.ownsTarget(i)?this.activeGrip=this.grip1:this.grip2.ownsTarget(i)?this.activeGrip=this.grip2:this.activeGrip=void 0,this.activeGrip?this._state="resize":this._state="move")},i.prototype.pointerUp=function(e){var i=this.state;t.prototype.pointerUp.call(this,e),"creating"===this.state&&Math.abs(this.x1-this.x2)<10&&Math.abs(this.y1-this.y2)<10?(this.x2=this.x1+this.defaultLength,this.adjustVisual(),this.adjustControlBox()):this.manipulate(e),this._state="select","creating"===i&&this.onMarkerCreated&&this.onMarkerCreated(this)},i.prototype.adjustVisual=function(){},i.prototype.manipulate=function(t){"creating"===this.state?this.resize(t):"move"===this.state?(this.x1=this.manipulationStartX1+t.x-this.manipulationStartX,this.y1=this.manipulationStartY1+t.y-this.manipulationStartY,this.x2=this.manipulationStartX2+t.x-this.manipulationStartX,this.y2=this.manipulationStartY2+t.y-this.manipulationStartY,this.adjustVisual(),this.adjustControlBox()):"resize"===this.state&&this.resize(t)},i.prototype.resize=function(t){switch(this.activeGrip){case this.grip1:this.x1=t.x,this.y1=t.y;break;case this.grip2:case void 0:this.x2=t.x,this.y2=t.y}this.adjustVisual(),this.adjustControlBox()},i.prototype.select=function(){t.prototype.select.call(this),this.adjustControlBox(),this.controlBox.style.display=""},i.prototype.deselect=function(){t.prototype.deselect.call(this),this.controlBox.style.display="none"},i.prototype.setupControlBox=function(){this.controlBox=r.createGroup(),this.container.appendChild(this.controlBox),this.addControlGrips(),this.controlBox.style.display="none"},i.prototype.adjustControlBox=function(){this.positionGrips()},i.prototype.addControlGrips=function(){this.grip1=this.createGrip(),this.grip2=this.createGrip(),this.positionGrips()},i.prototype.createGrip=function(){var t=new v;return t.visual.transform.baseVal.appendItem(r.createTransform()),this.controlBox.appendChild(t.visual),t},i.prototype.positionGrips=function(){var t=this.grip1.GRIP_SIZE;this.positionGrip(this.grip1.visual,this.x1-t/2,this.y1-t/2),this.positionGrip(this.grip2.visual,this.x2-t/2,this.y2-t/2)},i.prototype.positionGrip=function(t,e,i){var o=t.transform.baseVal.getItem(0);o.setTranslate(e,i),t.transform.baseVal.replaceItem(o,0)},i.prototype.getState=function(){return Object.assign({x1:this.x1,y1:this.y1,x2:this.x2,y2:this.y2},t.prototype.getState.call(this))},i.prototype.restoreState=function(e){t.prototype.restoreState.call(this,e);var i=e;this.x1=i.x1,this.y1=i.y1,this.x2=i.x2,this.y2=i.y2},i.prototype.scale=function(e,i){t.prototype.scale.call(this,e,i),this.x1=this.x1*e,this.y1=this.y1*i,this.x2=this.x2*e,this.y2=this.y2*i,this.adjustVisual(),this.adjustControlBox()},i}(g),M=function(t){function i(e,i,o){var s=t.call(this,e,i,o)||this;return s.strokeColor="transparent",s.strokeWidth=0,s.strokeDasharray="",s.setStrokeColor=s.setStrokeColor.bind(s),s.setStrokeWidth=s.setStrokeWidth.bind(s),s.setStrokeDasharray=s.setStrokeDasharray.bind(s),s.strokeColor=o.defaultColor,s.strokeWidth=o.defaultStrokeWidth,s.strokeDasharray=o.defaultStrokeDasharray,s.strokePanel=new y("Line color",o.defaultColorSet,o.defaultColor),s.strokePanel.onColorChanged=s.setStrokeColor,s.strokeWidthPanel=new S("Line width",o.defaultStrokeWidths,o.defaultStrokeWidth),s.strokeWidthPanel.onWidthChanged=s.setStrokeWidth,s.strokeStylePanel=new k("Line style",o.defaultStrokeDasharrays,o.defaultStrokeDasharray),s.strokeStylePanel.onStyleChanged=s.setStrokeDasharray,s}return e(i,t),i.prototype.ownsTarget=function(e){return!(!t.prototype.ownsTarget.call(this,e)&&e!==this.visual&&e!==this.selectorLine&&e!==this.visibleLine)},i.prototype.createVisual=function(){this.visual=r.createGroup(),this.selectorLine=r.createLine(this.x1,this.y1,this.x2,this.y2,[["stroke","transparent"],["stroke-width",(this.strokeWidth+10).toString()]]),this.visibleLine=r.createLine(this.x1,this.y1,this.x2,this.y2,[["stroke",this.strokeColor],["stroke-width",this.strokeWidth.toString()]]),this.visual.appendChild(this.selectorLine),this.visual.appendChild(this.visibleLine),this.addMarkerVisualToContainer(this.visual)},i.prototype.pointerDown=function(e,i){t.prototype.pointerDown.call(this,e,i),"new"===this.state&&(this.createVisual(),this.adjustVisual(),this._state="creating")},i.prototype.adjustVisual=function(){this.selectorLine&&this.visibleLine&&(this.selectorLine.setAttribute("x1",this.x1.toString()),this.selectorLine.setAttribute("y1",this.y1.toString()),this.selectorLine.setAttribute("x2",this.x2.toString()),this.selectorLine.setAttribute("y2",this.y2.toString()),this.visibleLine.setAttribute("x1",this.x1.toString()),this.visibleLine.setAttribute("y1",this.y1.toString()),this.visibleLine.setAttribute("x2",this.x2.toString()),this.visibleLine.setAttribute("y2",this.y2.toString()),r.setAttributes(this.visibleLine,[["stroke",this.strokeColor]]),r.setAttributes(this.visibleLine,[["stroke-width",this.strokeWidth.toString()]]),r.setAttributes(this.visibleLine,[["stroke-dasharray",this.strokeDasharray.toString()]]))},i.prototype.setStrokeColor=function(t){this.strokeColor=t,this.adjustVisual(),this.colorChanged(t)},i.prototype.setStrokeWidth=function(t){this.strokeWidth=t,this.adjustVisual()},i.prototype.setStrokeDasharray=function(t){this.strokeDasharray=t,this.adjustVisual()},Object.defineProperty(i.prototype,"toolboxPanels",{get:function(){return[this.strokePanel,this.strokeWidthPanel,this.strokeStylePanel]},enumerable:!1,configurable:!0}),i.prototype.getState=function(){var e=Object.assign({strokeColor:this.strokeColor,strokeWidth:this.strokeWidth,strokeDasharray:this.strokeDasharray},t.prototype.getState.call(this));return e.typeName=i.typeName,e},i.prototype.restoreState=function(e){t.prototype.restoreState.call(this,e);var i=e;this.strokeColor=i.strokeColor,this.strokeWidth=i.strokeWidth,this.strokeDasharray=i.strokeDasharray,this.createVisual(),this.adjustVisual()},i.typeName="LineMarker",i.title="Line marker",i.icon='<svg viewBox="0 0 24 24"><path d="M19 13H5v-2h14v2z"/></svg>',i}(B),E=function(t){function i(e,i,o,s){var r=t.call(this,e,s||'<svg viewBox="0 0 24 24"><path d="M17 8h3v12h1v1h-4v-1h1v-3h-4l-1.5 3H14v1h-4v-1h1l6-12m1 1l-3.5 7H18V9M5 3h5c1.11 0 2 .89 2 2v11H9v-5H6v5H3V5c0-1.11.89-2 2-2m1 2v4h3V5H6z"/></svg>')||this;return r.fonts=[],r.fontBoxes=[],r.fonts=i,r.currentFont=o,r.setCurrentFont=r.setCurrentFont.bind(r),r}return e(i,t),i.prototype.getUi=function(){var t=this,e=document.createElement("div");return e.style.overflow="hidden",e.style.flexGrow="2",this.fonts.forEach((function(i){var o=document.createElement("div");o.style.display="inline-block",o.style.alignItems="center",o.style.justifyContent="space-between",o.style.padding="5px",o.style.borderWidth="2px",o.style.borderStyle="solid",o.style.overflow="hidden",o.style.maxWidth=100/t.fonts.length-5+"%",o.style.borderColor=i===t.currentFont?h.settings.toolboxAccentColor:"transparent",o.addEventListener("click",(function(){t.setCurrentFont(i,o)})),e.appendChild(o);var s=document.createElement("div");s.style.display="flex",s.style.minHeight="20px",s.style.flexGrow="2",s.style.fontFamily=i,s.style.overflow="hidden";var r=document.createElement("div");r.style.whiteSpace="nowrap",r.style.overflow="hidden",r.style.textOverflow="ellipsis",r.innerHTML="The quick brown fox jumps over the lazy dog",s.appendChild(r),o.appendChild(s),t.fontBoxes.push(o)})),e},i.prototype.setCurrentFont=function(t,e){this.currentFont=t,this.fontBoxes.forEach((function(t){t.style.borderColor=t===e?h.settings.toolboxAccentColor:"transparent"})),this.onFontChanged&&this.onFontChanged(this.currentFont)},i}(d),P=function(t){function i(e,i,o){var s=t.call(this,e,i,o)||this;return s.color="transparent",s.padding=5,s.DEFAULT_TEXT="your text here",s.text=s.DEFAULT_TEXT,s.isMoved=!1,s.color=o.defaultColor,s.fontFamily=o.defaultFontFamily,s.defaultSize={x:100,y:30},s.setColor=s.setColor.bind(s),s.setFont=s.setFont.bind(s),s.renderText=s.renderText.bind(s),s.sizeText=s.sizeText.bind(s),s.textEditDivClicked=s.textEditDivClicked.bind(s),s.showTextEditor=s.showTextEditor.bind(s),s.setSize=s.setSize.bind(s),s.positionTextEditor=s.positionTextEditor.bind(s),s.colorPanel=new y("Color",o.defaultColorSet,o.defaultColor),s.colorPanel.onColorChanged=s.setColor,s.fontFamilyPanel=new E("Font",o.defaultFontFamilies,o.defaultFontFamily),s.fontFamilyPanel.onFontChanged=s.setFont,s}return e(i,t),i.prototype.ownsTarget=function(e){if(t.prototype.ownsTarget.call(this,e)||e===this.visual||e===this.textElement||e===this.bgRectangle)return!0;var i=!1;return this.textElement.childNodes.forEach((function(t){t===e&&(i=!0)})),i},i.prototype.createVisual=function(){this.visual=r.createGroup(),this.bgRectangle=r.createRect(1,1,[["fill","transparent"]]),this.visual.appendChild(this.bgRectangle),this.textElement=r.createText([["fill",this.color],["font-family",this.fontFamily],["font-size","16px"],["x","0"],["y","0"]]),this.textElement.transform.baseVal.appendItem(r.createTransform()),this.textElement.transform.baseVal.appendItem(r.createTransform()),this.visual.appendChild(this.textElement),this.addMarkerVisualToContainer(this.visual),this.renderText()},i.prototype.pointerDown=function(e,i){t.prototype.pointerDown.call(this,e,i),this.isMoved=!1,this.pointerDownPoint=e,this.pointerDownTimestamp=Date.now(),"new"===this.state&&(this.createVisual(),this.moveVisual(e),this._state="creating")},i.prototype.renderText=function(){var t=this;if(this.textElement){for(;this.textElement.lastChild;)this.textElement.removeChild(this.textElement.lastChild);this.text.split(/\r\n|[\n\v\f\r\x85\u2028\u2029]/).forEach((function(e){t.textElement.appendChild(r.createTSpan(""===e.trim()?" ":e.trim(),[["x","0"],["dy","1.2em"]]))})),setTimeout(this.sizeText,10)}},i.prototype.getTextScale=function(){var t=this.textElement.getBBox(),e=1;if(t.width>0&&t.height>0){var i=(1*this.width-this.width*this.padding*2/100)/t.width,o=(1*this.height-this.height*this.padding*2/100)/t.height;e=Math.min(i,o)}return e},i.prototype.getTextPosition=function(t){var e=this.textElement.getBBox(),i=0,o=0;return e.width>0&&e.height>0&&(i=(this.width-e.width*t)/2,o=this.height/2-e.height*t/2),{x:i,y:o}},i.prototype.sizeText=function(){var t=this.textElement.getBBox(),e=this.getTextScale(),i=this.getTextPosition(e);i.y-=t.y*e,navigator.userAgent.indexOf("Edge/")>-1?this.textElement.style.transform="translate("+i.x+"px, "+i.y+"px) scale("+e+", "+e+")":(this.textElement.transform.baseVal.getItem(0).setTranslate(i.x,i.y),this.textElement.transform.baseVal.getItem(1).setScale(e,e))},i.prototype.manipulate=function(e){t.prototype.manipulate.call(this,e),void 0!==this.pointerDownPoint&&(this.isMoved=Math.abs(e.x-this.pointerDownPoint.x)>5||Math.abs(e.y-this.pointerDownPoint.y)>5)},i.prototype.resize=function(e){t.prototype.resize.call(this,e),this.isMoved=!0,this.setSize(),this.sizeText()},i.prototype.setSize=function(){t.prototype.setSize.call(this),this.visual&&this.bgRectangle&&(r.setAttributes(this.visual,[["width",this.width.toString()],["height",this.height.toString()]]),r.setAttributes(this.bgRectangle,[["width",this.width.toString()],["height",this.height.toString()]]))},i.prototype.pointerUp=function(e){var i=this.state;t.prototype.pointerUp.call(this,e),this.setSize(),("creating"===i||!this.isMoved&&Date.now()-this.pointerDownTimestamp>500)&&this.showTextEditor(),this.pointerDownPoint=void 0},i.prototype.showTextEditor=function(){var t=this;this._state="edit",this.overlayContainer.innerHTML="",this.textEditDiv=document.createElement("div"),this.textEditDiv.style.flexGrow="2",this.textEditDiv.style.alignItems="center",this.textEditDiv.style.justifyContent="center",this.textEditDiv.style.pointerEvents="auto",this.textEditDiv.style.overflow="hidden",this.textEditor=document.createElement("div"),this.textEditor.style.position="absolute",this.textEditor.style.fontFamily=this.fontFamily,this.textEditor.style.lineHeight="1em",this.textEditor.innerText=this.text,this.textEditor.contentEditable="true",this.textEditor.style.color=this.color,this.textEditor.style.whiteSpace="pre",this.positionTextEditor(),this.textEditor.addEventListener("pointerup",(function(t){t.stopPropagation()})),this.textEditor.addEventListener("input",(function(){for(var e=Number.parseFloat(t.textEditor.style.fontSize);t.textEditor.clientWidth>=Number.parseInt(t.textEditor.style.maxWidth)&&e>.9;)e-=.1,t.textEditor.style.fontSize=Math.max(e,.9)+"em"})),this.textEditor.addEventListener("keyup",(function(t){t.cancelBubble=!0})),this.textEditor.addEventListener("paste",(function(t){if(t.clipboardData){var e=t.clipboardData.getData("text"),i=window.getSelection();if(!i.rangeCount)return!1;i.deleteFromDocument(),i.getRangeAt(0).insertNode(document.createTextNode(e)),t.preventDefault()}})),this.textEditDiv.addEventListener("pointerup",(function(){t.textEditDivClicked(t.textEditor.innerText)})),this.textEditDiv.appendChild(this.textEditor),this.overlayContainer.appendChild(this.textEditDiv),this.hideVisual(),this.textEditor.focus(),document.execCommand("selectAll")},i.prototype.positionTextEditor=function(){if("edit"===this.state)if(void 0===this.textEditor)this.showTextEditor();else{this.textElement.style.display="";var t=this.getTextScale(),e=this.rotatePoint({x:this.left+this.width/2,y:this.top+this.height/2}),i=this.textElement.getBBox(),o={x:i.width*t,y:i.height*t};e.x-=o.x/2,e.y-=o.y/2,this.textEditor.style.top=e.y+"px",this.textEditor.style.left=e.x+"px",this.textEditor.style.maxWidth=this.overlayContainer.offsetWidth-e.x+"px",this.textEditor.style.fontSize=Math.max(16*t,12)+"px",this.textElement.style.display="none"}},i.prototype.textEditDivClicked=function(t){this.text=t.trim(),this.overlayContainer.innerHTML="",this.renderText(),this.showVisual()},i.prototype.deselect=function(){"edit"===this.state&&this.textEditDivClicked(this.textEditor.innerText),t.prototype.deselect.call(this)},i.prototype.dblClick=function(e,i){t.prototype.dblClick.call(this,e,i),this.showTextEditor()},i.prototype.setColor=function(t){this.textElement&&r.setAttributes(this.textElement,[["fill",t]]),this.color=t,this.textEditor&&(this.textEditor.style.color=this.color),this.colorChanged(t)},i.prototype.setFont=function(t){this.textElement&&r.setAttributes(this.textElement,[["font-family",t]]),this.fontFamily=t,this.textEditor&&(this.textEditor.style.fontFamily=this.fontFamily),this.renderText()},i.prototype.hideVisual=function(){this.textElement.style.display="none",this.hideControlBox()},i.prototype.showVisual=function(){"edit"===this.state&&(this._state="select"),this.textElement.style.display="",this.showControlBox()},Object.defineProperty(i.prototype,"toolboxPanels",{get:function(){return[this.colorPanel,this.fontFamilyPanel]},enumerable:!1,configurable:!0}),i.prototype.getState=function(){var e=Object.assign({color:this.color,fontFamily:this.fontFamily,padding:this.padding,text:this.text},t.prototype.getState.call(this));return e.typeName=i.typeName,e},i.prototype.restoreState=function(e){var i=e;this.color=i.color,this.fontFamily=i.fontFamily,this.padding=i.padding,this.text=i.text,this.createVisual(),t.prototype.restoreState.call(this,e),this.setSize()},i.prototype.scale=function(e,i){t.prototype.scale.call(this,e,i),this.setSize(),this.sizeText(),this.positionTextEditor()},i.typeName="TextMarker",i.title="Text marker",i.icon='<svg viewBox="0 0 24 24"><path d="M9.6 14L12 7.7l2.4 6.3M11 5L5.5 19h2.2l1.1-3H15l1.1 3h2.2L13 5h-2z"/></svg>',i}(C),T=function(t){function i(e,i,o){var s=t.call(this,e,i,o)||this;return s.color="transparent",s.lineWidth=3,s.drawing=!1,s.pixelRatio=1,s.color=o.defaultColor,s.lineWidth=o.defaultStrokeWidth,s.pixelRatio=o.freehandPixelRatio,s.setColor=s.setColor.bind(s),s.addCanvas=s.addCanvas.bind(s),s.finishCreation=s.finishCreation.bind(s),s.setLineWidth=s.setLineWidth.bind(s),s.colorPanel=new y("Color",o.defaultColorSet,o.defaultColor),s.colorPanel.onColorChanged=s.setColor,s.lineWidthPanel=new S("Line width",o.defaultStrokeWidths,o.defaultStrokeWidth),s.lineWidthPanel.onWidthChanged=s.setLineWidth,s}return e(i,t),i.prototype.ownsTarget=function(e){return!(!t.prototype.ownsTarget.call(this,e)&&e!==this.visual&&e!==this.drawingImage)},i.prototype.createVisual=function(){this.visual=r.createGroup(),this.drawingImage=r.createImage(),this.visual.appendChild(this.drawingImage);var t=r.createTransform();this.visual.transform.baseVal.appendItem(t),this.addMarkerVisualToContainer(this.visual)},i.prototype.pointerDown=function(e,i){"new"===this.state&&(this.addCanvas(),this.createVisual(),this._state="creating"),"creating"===this.state?(this.canvasContext.strokeStyle=this.color,this.canvasContext.lineWidth=this.lineWidth,this.canvasContext.beginPath(),this.canvasContext.moveTo(e.x,e.y),this.drawing=!0):t.prototype.pointerDown.call(this,e,i)},i.prototype.manipulate=function(e){"creating"===this.state?this.drawing&&(this.canvasContext.lineTo(e.x,e.y),this.canvasContext.stroke()):t.prototype.manipulate.call(this,e)},i.prototype.resize=function(e){t.prototype.resize.call(this,e),r.setAttributes(this.visual,[["width",this.width.toString()],["height",this.height.toString()]]),r.setAttributes(this.drawingImage,[["width",this.width.toString()],["height",this.height.toString()]])},i.prototype.pointerUp=function(e){"creating"===this._state?this.drawing&&(this.canvasContext.closePath(),this.drawing=!1,this.globalSettings.newFreehandMarkerOnPointerUp&&this.finishCreation()):t.prototype.pointerUp.call(this,e)},i.prototype.addCanvas=function(){this.overlayContainer.innerHTML="",this.canvasElement=document.createElement("canvas"),this.canvasElement.width=this.overlayContainer.clientWidth*this.pixelRatio,this.canvasElement.height=this.overlayContainer.clientHeight*this.pixelRatio,this.canvasContext=this.canvasElement.getContext("2d"),this.canvasContext.scale(this.pixelRatio,this.pixelRatio),this.overlayContainer.appendChild(this.canvasElement)},i.prototype.select=function(){"creating"===this.state&&this.finishCreation(),t.prototype.select.call(this)},i.prototype.deselect=function(){"creating"===this.state&&this.finishCreation(),t.prototype.deselect.call(this)},i.prototype.finishCreation=function(){for(var t=this.canvasContext.getImageData(0,0,this.canvasElement.width,this.canvasElement.height),e=[this.canvasElement.width+1,this.canvasElement.height+1,-1,-1],i=e[0],o=e[1],s=e[2],r=e[3],n=!1,a=0;a<this.canvasElement.height;a++)for(var h=0;h<this.canvasElement.width;h++){t.data[a*this.canvasElement.width*4+4*h+3]>0&&(n=!0,a<o&&(o=a),h<i&&(i=h),a>r&&(r=a),h>s&&(s=h))}if(n){this.left=i/this.pixelRatio,this.top=o/this.pixelRatio,this.width=(s-i)/this.pixelRatio,this.height=(r-o)/this.pixelRatio;var l=document.createElement("canvas");l.width=s-i,l.height=r-o,l.getContext("2d").putImageData(this.canvasContext.getImageData(i,o,s-i,r-o),0,0),this.drawingImgUrl=l.toDataURL("image/png"),this.setDrawingImage(),this._state="select",this.onMarkerCreated&&this.onMarkerCreated(this)}this.overlayContainer.innerHTML=""},i.prototype.setDrawingImage=function(){r.setAttributes(this.drawingImage,[["width",this.width.toString()],["height",this.height.toString()]]),r.setAttributes(this.drawingImage,[["href",this.drawingImgUrl]]),this.moveVisual({x:this.left,y:this.top})},i.prototype.setColor=function(t){this.color=t,this.colorChanged(t)},i.prototype.setLineWidth=function(t){this.lineWidth=t},Object.defineProperty(i.prototype,"toolboxPanels",{get:function(){return"new"===this.state||"creating"===this.state?[this.colorPanel,this.lineWidthPanel]:[]},enumerable:!1,configurable:!0}),i.prototype.getState=function(){var e=Object.assign({drawingImgUrl:this.drawingImgUrl},t.prototype.getState.call(this));return e.typeName=i.typeName,e},i.prototype.restoreState=function(e){this.createVisual(),t.prototype.restoreState.call(this,e),this.drawingImgUrl=e.drawingImgUrl,this.setDrawingImage()},i.prototype.scale=function(e,i){t.prototype.scale.call(this,e,i),this.setDrawingImage()},i.typeName="FreehandMarker",i.title="Freehand marker",i.icon='<svg viewBox="0 0 24 24"><path d="M9.75 20.85c1.78-.7 1.39-2.63.49-3.85-.89-1.25-2.12-2.11-3.36-2.94A9.817 9.817 0 014.54 12c-.28-.33-.85-.94-.27-1.06.59-.12 1.61.46 2.13.68.91.38 1.81.82 2.65 1.34l1.01-1.7C8.5 10.23 6.5 9.32 4.64 9.05c-1.06-.16-2.18.06-2.54 1.21-.32.99.19 1.99.77 2.77 1.37 1.83 3.5 2.71 5.09 4.29.34.33.75.72.95 1.18.21.44.16.47-.31.47-1.24 0-2.79-.97-3.8-1.61l-1.01 1.7c1.53.94 4.09 2.41 5.96 1.79m11.09-15.6c.22-.22.22-.58 0-.79l-1.3-1.3a.562.562 0 00-.78 0l-1.02 1.02 2.08 2.08M11 10.92V13h2.08l6.15-6.15-2.08-2.08L11 10.92z"/></svg>',i}(C),L=function(t){function i(e,i,o){var s=t.call(this,e,o||'<svg viewBox="0 0 24 24"><path d="M8 14v4l-6-6 6-6v4h8V6l6 6-6 6v-4H8z"/></svg>')||this;return s.typeBoxes=[],s.currentType=i,s.setCurrentType=s.setCurrentType.bind(s),s}return e(i,t),i.prototype.getUi=function(){var t=this,e=document.createElement("div");e.style.display="flex",e.style.overflow="hidden",e.style.flexGrow="2";for(var i=function(i){var s="both";switch(i){case 0:s="both";break;case 1:s="start";break;case 2:s="end";break;case 3:s="none"}var r=document.createElement("div");if(r.style.display="flex",r.style.flexGrow="2",r.style.alignItems="center",r.style.justifyContent="space-between",r.style.padding="5px",r.style.borderWidth="2px",r.style.borderStyle="solid",r.style.borderColor=s===o.currentType?h.settings.toolboxAccentColor:"transparent",r.addEventListener("click",(function(){t.setCurrentType(s,r)})),e.appendChild(r),"both"===s||"start"===s){var n=document.createElement("div");n.style.display="flex",n.style.alignItems="center",n.style.minHeight="20px",n.innerHTML='<svg viewBox="0 0 10 10" width="10" height="10" xmlns="http://www.w3.org/2000/svg">\n          <polygon points="0,5 10,0 10,10" fill="'+h.settings.toolboxColor+'" />\n        </svg>',n.style.marginLeft="5px",r.appendChild(n)}var a=document.createElement("div");a.style.display="flex",a.style.alignItems="center",a.style.minHeight="20px",a.style.flexGrow="2";var l=document.createElement("hr");if(l.style.minWidth="20px",l.style.border="0px",l.style.borderTop="3px solid "+h.settings.toolboxColor,l.style.flexGrow="2",a.appendChild(l),r.appendChild(a),"both"===s||"end"===s){var p=document.createElement("div");p.style.display="flex",p.style.alignItems="center",p.style.minHeight="20px",p.innerHTML='<svg viewBox="0 0 10 10" width="10" height="10" xmlns="http://www.w3.org/2000/svg">\n          <polygon points="0,0 10,5 0,10" fill="'+h.settings.toolboxColor+'" />\n        </svg>',p.style.marginRight="5px",r.appendChild(p)}o.typeBoxes.push(r)},o=this,s=0;s<4;s++)i(s);return e},i.prototype.setCurrentType=function(t,e){this.currentType=t,this.typeBoxes.forEach((function(t){t.style.borderColor=t===e?h.settings.toolboxAccentColor:"transparent"})),this.onArrowTypeChanged&&this.onArrowTypeChanged(this.currentType)},i}(d),A=function(t){function i(e,i,o){var s=t.call(this,e,i,o)||this;return s.arrowType="end",s.arrowBaseHeight=10,s.arrowBaseWidth=10,s.getArrowPoints=s.getArrowPoints.bind(s),s.setArrowType=s.setArrowType.bind(s),s.arrowTypePanel=new L("Arrow type","end"),s.arrowTypePanel.onArrowTypeChanged=s.setArrowType,s}return e(i,t),i.prototype.ownsTarget=function(e){return!(!t.prototype.ownsTarget.call(this,e)&&e!==this.arrow1&&e!==this.arrow2)},i.prototype.getArrowPoints=function(t,e){var i=this.arrowBaseWidth+2*this.strokeWidth,o=this.arrowBaseHeight+2*this.strokeWidth;return t-i/2+","+(e+o/2)+" "+t+","+(e-o/2)+" "+(t+i/2)+","+(e+o/2)},i.prototype.createTips=function(){this.arrow1=r.createPolygon(this.getArrowPoints(this.x1,this.y1),[["fill",this.strokeColor]]),this.arrow1.transform.baseVal.appendItem(r.createTransform()),this.visual.appendChild(this.arrow1),this.arrow2=r.createPolygon(this.getArrowPoints(this.x2,this.y2),[["fill",this.strokeColor]]),this.arrow2.transform.baseVal.appendItem(r.createTransform()),this.visual.appendChild(this.arrow2)},i.prototype.pointerDown=function(e,i){t.prototype.pointerDown.call(this,e,i),"creating"===this.state&&this.createTips()},i.prototype.adjustVisual=function(){if(t.prototype.adjustVisual.call(this),this.arrow1&&this.arrow2&&(this.arrow1.style.display="both"===this.arrowType||"start"===this.arrowType?"":"none",this.arrow2.style.display="both"===this.arrowType||"end"===this.arrowType?"":"none",r.setAttributes(this.arrow1,[["points",this.getArrowPoints(this.x1,this.y1)],["fill",this.strokeColor]]),r.setAttributes(this.arrow2,[["points",this.getArrowPoints(this.x2,this.y2)],["fill",this.strokeColor]]),Math.abs(this.x1-this.x2)>.1)){var e=180*Math.atan((this.y2-this.y1)/(this.x2-this.x1))/Math.PI+90*Math.sign(this.x1-this.x2),i=this.arrow1.transform.baseVal.getItem(0);i.setRotate(e,this.x1,this.y1),this.arrow1.transform.baseVal.replaceItem(i,0);var o=this.arrow2.transform.baseVal.getItem(0);o.setRotate(e+180,this.x2,this.y2),this.arrow2.transform.baseVal.replaceItem(o,0)}},i.prototype.setArrowType=function(t){this.arrowType=t,this.adjustVisual()},Object.defineProperty(i.prototype,"toolboxPanels",{get:function(){return[this.strokePanel,this.strokeWidthPanel,this.strokeStylePanel,this.arrowTypePanel]},enumerable:!1,configurable:!0}),i.prototype.getState=function(){var e=Object.assign({arrowType:this.arrowType},t.prototype.getState.call(this));return e.typeName=i.typeName,e},i.prototype.restoreState=function(e){t.prototype.restoreState.call(this,e);var i=e;this.arrowType=i.arrowType,this.createTips(),this.adjustVisual()},i.typeName="ArrowMarker",i.title="Arrow marker",i.icon='<svg viewBox="0 0 24 24"><path d="M19 6.41L17.59 5 7 15.59V9H5v10h10v-2H8.41L19 6.41z"/></svg>',i}(M),D=function(t){function i(e,i,o){var s=t.call(this,e,i,o)||this;return s.fillColor=o.defaultFillColor,s.strokeWidth=0,s.fillPanel=new y("Color",o.defaultColorSet,o.defaultFillColor),s.fillPanel.onColorChanged=s.setFillColor,s}return e(i,t),Object.defineProperty(i.prototype,"toolboxPanels",{get:function(){return[this.fillPanel]},enumerable:!1,configurable:!0}),i.prototype.getState=function(){var e=t.prototype.getState.call(this);return e.typeName=i.typeName,e},i.typeName="CoverMarker",i.title="Cover marker",i.icon='<svg viewBox="0 0 24 24"><path d="M4 6v13h16V6H4z"/></svg>',i}(b),I=function(t){function i(e,i,o,s){var r=t.call(this,e,s||'<svg viewBox="0 0 24 24"><path d="M17.66 8L12 2.35 6.34 8A8.02 8.02 0 004 13.64c0 2 .78 4.11 2.34 5.67a7.99 7.99 0 0011.32 0c1.56-1.56 2.34-3.67 2.34-5.67S19.22 9.56 17.66 8M6 14c0-2 .62-3.27 1.76-4.4L12 5.27l4.24 4.38C17.38 10.77 18 12 18 14H6z"/></svg>')||this;return r.opacities=[],r.opacityBoxes=[],r.opacities=i,r.currentOpacity=o,r.setCurrentOpacity=r.setCurrentOpacity.bind(r),r}return e(i,t),i.prototype.getUi=function(){var t=this,e=document.createElement("div");return e.style.display="flex",e.style.overflow="hidden",e.style.flexGrow="2",e.style.justifyContent="space-between",this.opacities.forEach((function(i){var o=document.createElement("div");o.style.display="flex",o.style.alignItems="center",o.style.justifyContent="center",o.style.padding="5px",o.style.borderWidth="2px",o.style.borderStyle="solid",o.style.borderColor=i===t.currentOpacity?h.settings.toolboxAccentColor:"transparent",o.addEventListener("click",(function(){t.setCurrentOpacity(i,o)})),e.appendChild(o);var s=document.createElement("div");s.innerText=100*i+"%",o.appendChild(s),t.opacityBoxes.push(o)})),e},i.prototype.setCurrentOpacity=function(t,e){this.currentOpacity=t,this.opacityBoxes.forEach((function(t){t.style.borderColor=t===e?h.settings.toolboxAccentColor:"transparent"})),this.onOpacityChanged&&this.onOpacityChanged(this.currentOpacity)},i}(d),W=function(t){function i(e,i,o){var s=t.call(this,e,i,o)||this;return s.setOpacity=s.setOpacity.bind(s),s.fillColor=o.defaultHighlightColor,s.strokeWidth=0,s.opacity=o.defaultHighlightOpacity,s.fillPanel=new y("Color",o.defaultColorSet,s.fillColor),s.fillPanel.onColorChanged=s.setFillColor,s.opacityPanel=new I("Opacity",o.defaultOpacitySteps,s.opacity),s.opacityPanel.onOpacityChanged=s.setOpacity,s}return e(i,t),i.prototype.setOpacity=function(t){this.opacity=t,this.visual&&r.setAttributes(this.visual,[["opacity",this.opacity.toString()]])},Object.defineProperty(i.prototype,"toolboxPanels",{get:function(){return[this.fillPanel,this.opacityPanel]},enumerable:!1,configurable:!0}),i.prototype.getState=function(){var e=t.prototype.getState.call(this);return e.typeName=i.typeName,e},i.typeName="HighlightMarker",i.title="Highlight marker",i.icon='<svg viewBox="0 0 24 24"><path d="M18.5 1.15c-.53 0-1.04.19-1.43.58l-5.81 5.82 5.65 5.65 5.82-5.81c.77-.78.77-2.04 0-2.83l-2.84-2.83c-.39-.39-.89-.58-1.39-.58M10.3 8.5l-5.96 5.96c-.78.78-.78 2.04.02 2.85C3.14 18.54 1.9 19.77.67 21h5.66l.86-.86c.78.76 2.03.75 2.81-.02l5.95-5.96"/></svg>',i}(D),H='<svg viewBox="0 0 24 24"><path d="M19 11.5s-2 2.17-2 3.5a2 2 0 002 2 2 2 0 002-2c0-1.33-2-3.5-2-3.5M5.21 10L10 5.21 14.79 10m1.77-1.06L7.62 0 6.21 1.41l2.38 2.38-5.15 5.15c-.59.56-.59 1.53 0 2.12l5.5 5.5c.29.29.68.44 1.06.44s.77-.15 1.06-.44l5.5-5.5c.59-.59.59-1.56 0-2.12z"/></svg>',N=function(t){function i(e,i,o){var s=t.call(this,e,i,o)||this;return s.bgColor="transparent",s.tipPosition={x:0,y:0},s.tipBase1Position={x:0,y:0},s.tipBase2Position={x:0,y:0},s.tipMoving=!1,s.color=o.defaultStrokeColor,s.bgColor=o.defaultFillColor,s.fontFamily=o.defaultFontFamily,s.defaultSize={x:100,y:30},s.setBgColor=s.setBgColor.bind(s),s.getTipPoints=s.getTipPoints.bind(s),s.positionTip=s.positionTip.bind(s),s.setTipPoints=s.setTipPoints.bind(s),s.colorPanel=new y("Text color",o.defaultColorSet,s.color,'<svg viewBox="0 0 24 24"><path d="M9.62 12L12 5.67 14.37 12M11 3L5.5 17h2.25l1.12-3h6.25l1.13 3h2.25L13 3h-2z"/></svg>'),s.colorPanel.onColorChanged=s.setColor,s.bgColorPanel=new y("Fill color",o.defaultColorSet,s.bgColor,H),s.bgColorPanel.onColorChanged=s.setBgColor,s.fontFamilyPanel=new E("Font",o.defaultFontFamilies,o.defaultFontFamily),s.fontFamilyPanel.onFontChanged=s.setFont,s.tipGrip=new v,s.tipGrip.visual.transform.baseVal.appendItem(r.createTransform()),s.controlBox.appendChild(s.tipGrip.visual),s}return e(i,t),i.prototype.ownsTarget=function(e){return t.prototype.ownsTarget.call(this,e)||this.tipGrip.ownsTarget(e)||this.tip===e},i.prototype.createTip=function(){r.setAttributes(this.bgRectangle,[["fill",this.bgColor],["rx","10px"]]),this.tip=r.createPolygon(this.getTipPoints(),[["fill",this.bgColor]]),this.visual.appendChild(this.tip)},i.prototype.pointerDown=function(e,i){"new"===this.state&&t.prototype.pointerDown.call(this,e,i),"creating"===this.state?this.createTip():this.tipGrip.ownsTarget(i)?(this.manipulationStartLeft=this.left,this.manipulationStartTop=this.top,this.tipMoving=!0):t.prototype.pointerDown.call(this,e,i)},i.prototype.pointerUp=function(e){if(this.tipMoving)this.tipMoving=!1;else{var i="creating"===this.state;t.prototype.pointerUp.call(this,e),this.setTipPoints(i),this.positionTip()}},i.prototype.manipulate=function(e){if(this.tipMoving){var i=this.unrotatePoint(e);this.tipPosition={x:i.x-this.manipulationStartLeft,y:i.y-this.manipulationStartTop},this.positionTip()}else t.prototype.manipulate.call(this,e)},i.prototype.setBgColor=function(t){this.bgRectangle&&this.tip&&(r.setAttributes(this.bgRectangle,[["fill",t]]),r.setAttributes(this.tip,[["fill",t]])),this.bgColor=t,this.fillColorChanged(t)},i.prototype.getTipPoints=function(){return this.setTipPoints("creating"===this.state),this.tipBase1Position.x+","+this.tipBase1Position.y+" "+this.tipBase2Position.x+","+this.tipBase2Position.y+" "+this.tipPosition.x+","+this.tipPosition.y},i.prototype.setTipPoints=function(t){void 0===t&&(t=!1);var e=Math.min(this.height/2,15),i=this.height/5;t&&(this.tipPosition={x:e+i/2,y:this.height+20});var o=Math.atan(this.height/2/(this.width/2));if(this.tipPosition.x<this.width/2&&this.tipPosition.y<this.height/2)o<Math.atan((this.height/2-this.tipPosition.y)/(this.width/2-this.tipPosition.x))?(i=this.width/5,e=Math.min(this.width/2,15),this.tipBase1Position={x:e,y:0},this.tipBase2Position={x:e+i,y:0}):(this.tipBase1Position={x:0,y:e},this.tipBase2Position={x:0,y:e+i});else if(this.tipPosition.x>=this.width/2&&this.tipPosition.y<this.height/2){o<Math.atan((this.height/2-this.tipPosition.y)/(this.tipPosition.x-this.width/2))?(i=this.width/5,e=Math.min(this.width/2,15),this.tipBase1Position={x:this.width-e-i,y:0},this.tipBase2Position={x:this.width-e,y:0}):(this.tipBase1Position={x:this.width,y:e},this.tipBase2Position={x:this.width,y:e+i})}else if(this.tipPosition.x>=this.width/2&&this.tipPosition.y>=this.height/2){o<Math.atan((this.tipPosition.y-this.height/2)/(this.tipPosition.x-this.width/2))?(i=this.width/5,e=Math.min(this.width/2,15),this.tipBase1Position={x:this.width-e-i,y:this.height},this.tipBase2Position={x:this.width-e,y:this.height}):(this.tipBase1Position={x:this.width,y:this.height-e-i},this.tipBase2Position={x:this.width,y:this.height-e})}else{o<Math.atan((this.tipPosition.y-this.height/2)/(this.width/2-this.tipPosition.x))?(i=this.width/5,e=Math.min(this.width/2,15),this.tipBase1Position={x:e,y:this.height},this.tipBase2Position={x:e+i,y:this.height}):(this.tipBase1Position={x:0,y:this.height-e},this.tipBase2Position={x:0,y:this.height-e-i})}},i.prototype.resize=function(e){t.prototype.resize.call(this,e),this.positionTip()},i.prototype.positionTip=function(){r.setAttributes(this.tip,[["points",this.getTipPoints()]]);var t=this.tipGrip.visual.transform.baseVal.getItem(0);t.setTranslate(this.tipPosition.x,this.tipPosition.y),this.tipGrip.visual.transform.baseVal.replaceItem(t,0)},Object.defineProperty(i.prototype,"toolboxPanels",{get:function(){return[this.colorPanel,this.bgColorPanel,this.fontFamilyPanel]},enumerable:!1,configurable:!0}),i.prototype.select=function(){this.positionTip(),t.prototype.select.call(this)},i.prototype.getState=function(){var e=Object.assign({bgColor:this.bgColor,tipPosition:this.tipPosition},t.prototype.getState.call(this));return e.typeName=i.typeName,e},i.prototype.restoreState=function(e){var i=e;this.bgColor=i.bgColor,this.tipPosition=i.tipPosition,t.prototype.restoreState.call(this,e),this.createTip(),this.setTipPoints()},i.prototype.scale=function(e,i){t.prototype.scale.call(this,e,i),this.tipPosition={x:this.tipPosition.x*e,y:this.tipPosition.y*i},this.positionTip()},i.typeName="CalloutMarker",i.title="Callout marker",i.icon='<svg viewBox="0 0 24 24"><path d="M4 2h16a2 2 0 012 2v12a2 2 0 01-2 2h-4l-4 4-4-4H4a2 2 0 01-2-2V4a2 2 0 012-2m0 2v12h4.83L12 19.17 15.17 16H20V4H4m2 3h12v2H6V7m0 4h10v2H6v-2z"/></svg>',i}(P),R=function(t){function i(e,i,o){var r=t.call(this,e,i,o)||this;return r.fillColor="transparent",r.strokeColor="transparent",r.strokeWidth=0,r.strokeDasharray="",r.opacity=1,r.strokeColor=o.defaultColor,r.strokeWidth=o.defaultStrokeWidth,r.strokeDasharray=o.defaultStrokeDasharray,r.fillColor=o.defaultFillColor,r.setStrokeColor=r.setStrokeColor.bind(r),r.setFillColor=r.setFillColor.bind(r),r.setStrokeWidth=r.setStrokeWidth.bind(r),r.setStrokeDasharray=r.setStrokeDasharray.bind(r),r.setOpacity=r.setOpacity.bind(r),r.createVisual=r.createVisual.bind(r),r.strokePanel=new y("Line color",s(o.defaultColorSet,["transparent"]),o.defaultColor),r.strokePanel.onColorChanged=r.setStrokeColor,r.fillPanel=new y("Fill color",s(o.defaultColorSet,["transparent"]),r.fillColor,H),r.fillPanel.onColorChanged=r.setFillColor,r.strokeWidthPanel=new S("Line width",o.defaultStrokeWidths,o.defaultStrokeWidth),r.strokeWidthPanel.onWidthChanged=r.setStrokeWidth,r.strokeStylePanel=new k("Line style",o.defaultStrokeDasharrays,o.defaultStrokeDasharray),r.strokeStylePanel.onStyleChanged=r.setStrokeDasharray,r.opacityPanel=new I("Opacity",o.defaultOpacitySteps,r.opacity),r.opacityPanel.onOpacityChanged=r.setOpacity,r}return e(i,t),i.prototype.ownsTarget=function(e){return!(!t.prototype.ownsTarget.call(this,e)&&e!==this.visual)},i.prototype.createVisual=function(){this.visual=r.createEllipse(this.width/2,this.height/2,[["fill",this.fillColor],["stroke",this.strokeColor],["stroke-width",this.strokeWidth.toString()],["stroke-dasharray",this.strokeDasharray],["opacity",this.opacity.toString()]]),this.addMarkerVisualToContainer(this.visual)},i.prototype.pointerDown=function(e,i){t.prototype.pointerDown.call(this,e,i),"new"===this.state&&(this.createVisual(),this.moveVisual(e),this._state="creating")},i.prototype.manipulate=function(e){t.prototype.manipulate.call(this,e)},i.prototype.resize=function(e){t.prototype.resize.call(this,e),this.setSize()},i.prototype.setSize=function(){t.prototype.setSize.call(this),r.setAttributes(this.visual,[["cx",(this.width/2).toString()],["cy",(this.height/2).toString()],["rx",(this.width/2).toString()],["ry",(this.height/2).toString()]])},i.prototype.pointerUp=function(e){t.prototype.pointerUp.call(this,e),this.setSize()},i.prototype.setStrokeColor=function(t){this.strokeColor=t,this.visual&&r.setAttributes(this.visual,[["stroke",this.strokeColor]]),this.colorChanged(t)},i.prototype.setFillColor=function(t){this.fillColor=t,this.visual&&r.setAttributes(this.visual,[["fill",this.fillColor]]),this.fillColorChanged(t)},i.prototype.setStrokeWidth=function(t){this.strokeWidth=t,this.visual&&r.setAttributes(this.visual,[["stroke-width",this.strokeWidth.toString()]])},i.prototype.setStrokeDasharray=function(t){this.strokeDasharray=t,this.visual&&r.setAttributes(this.visual,[["stroke-dasharray",this.strokeDasharray]])},i.prototype.setOpacity=function(t){this.opacity=t,this.visual&&r.setAttributes(this.visual,[["opacity",this.opacity.toString()]])},Object.defineProperty(i.prototype,"toolboxPanels",{get:function(){return[this.strokePanel,this.fillPanel,this.strokeWidthPanel,this.strokeStylePanel,this.opacityPanel]},enumerable:!1,configurable:!0}),i.prototype.getState=function(){var e=Object.assign({fillColor:this.fillColor,strokeColor:this.strokeColor,strokeWidth:this.strokeWidth,strokeDasharray:this.strokeDasharray,opacity:this.opacity},t.prototype.getState.call(this));return e.typeName=i.typeName,e},i.prototype.restoreState=function(e){var i=e;this.fillColor=i.fillColor,this.strokeColor=i.strokeColor,this.strokeWidth=i.strokeWidth,this.strokeDasharray=i.strokeDasharray,this.opacity=i.opacity,this.createVisual(),t.prototype.restoreState.call(this,e),this.setSize()},i.prototype.scale=function(e,i){t.prototype.scale.call(this,e,i),this.setSize()},i.typeName="EllipseMarker",i.title="Ellipse marker",i.icon='<svg viewBox="0 0 24 24"><path d="M12 4C6.5 4 2 7.58 2 12s4.5 8 10 8 10-3.58 10-8-4.5-8-10-8z"/></svg>',i}(C),O=function(t){function i(e,i,o){return t.call(this,e,i,o)||this}return e(i,t),Object.defineProperty(i.prototype,"tipLength",{get:function(){return 10+3*this.strokeWidth},enumerable:!1,configurable:!0}),i.prototype.ownsTarget=function(e){return!(!t.prototype.ownsTarget.call(this,e)&&e!==this.tip1&&e!==this.tip2)},i.prototype.createTips=function(){this.tip1=r.createLine(this.x1-this.tipLength/2,this.y1,this.x1+this.tipLength/2,this.y1,[["stroke",this.strokeColor],["stroke-width",this.strokeWidth.toString()]]),this.tip1.transform.baseVal.appendItem(r.createTransform()),this.visual.appendChild(this.tip1),this.tip2=r.createLine(this.x2-this.tipLength/2,this.y2,this.x2+this.tipLength/2,this.y2,[["stroke",this.strokeColor],["stroke-width",this.strokeWidth.toString()]]),this.tip2.transform.baseVal.appendItem(r.createTransform()),this.visual.appendChild(this.tip2)},i.prototype.pointerDown=function(e,i){t.prototype.pointerDown.call(this,e,i),"creating"===this.state&&this.createTips()},i.prototype.adjustVisual=function(){if(t.prototype.adjustVisual.call(this),this.tip1&&this.tip2&&(r.setAttributes(this.tip1,[["x1",(this.x1-this.tipLength/2).toString()],["y1",this.y1.toString()],["x2",(this.x1+this.tipLength/2).toString()],["y2",this.y1.toString()],["stroke",this.strokeColor],["stroke-width",this.strokeWidth.toString()]]),r.setAttributes(this.tip2,[["x1",(this.x2-this.tipLength/2).toString()],["y1",this.y2.toString()],["x2",(this.x2+this.tipLength/2).toString()],["y2",this.y2.toString()],["stroke",this.strokeColor],["stroke-width",this.strokeWidth.toString()]]),Math.abs(this.x1-this.x2)>.1)){var e=180*Math.atan((this.y2-this.y1)/(this.x2-this.x1))/Math.PI+90*Math.sign(this.x1-this.x2),i=this.tip1.transform.baseVal.getItem(0);i.setRotate(e,this.x1,this.y1),this.tip1.transform.baseVal.replaceItem(i,0);var o=this.tip2.transform.baseVal.getItem(0);o.setRotate(e+180,this.x2,this.y2),this.tip2.transform.baseVal.replaceItem(o,0)}},Object.defineProperty(i.prototype,"toolboxPanels",{get:function(){return[this.strokePanel,this.strokeWidthPanel,this.strokeStylePanel]},enumerable:!1,configurable:!0}),i.prototype.getState=function(){var e=t.prototype.getState.call(this);return e.typeName=i.typeName,e},i.prototype.restoreState=function(e){t.prototype.restoreState.call(this,e),this.createTips(),this.adjustVisual()},i.typeName="MeasurementMarker",i.title="Measurement marker",i.icon='<svg viewBox="0 0 24 24"><path d="M1.39 18.36l1.77-1.76L4.58 18l1.06-1.05-1.42-1.41 1.42-1.42 2.47 2.48 1.06-1.06-2.47-2.48 1.41-1.41 1.42 1.41L10.59 12l-1.42-1.41 1.42-1.42 2.47 2.48 1.06-1.06-2.47-2.48 1.41-1.41 1.41 1.41 1.07-1.06-1.42-1.41 1.42-1.42L18 6.7l1.07-1.06-2.47-2.48 1.76-1.77 4.25 4.25L5.64 22.61l-4.25-4.25z"/></svg>',i}(M),z=function(t){function i(e,i,o){var s=t.call(this,e,i,o)||this;return s.strokePanel.colors=o.defaultColorSet,s.fillColor="transparent",s}return e(i,t),Object.defineProperty(i.prototype,"toolboxPanels",{get:function(){return[this.strokePanel,this.strokeWidthPanel,this.strokeStylePanel]},enumerable:!1,configurable:!0}),i.prototype.getState=function(){var e=t.prototype.getState.call(this);return e.typeName=i.typeName,e},i.typeName="EllipseFrameMarker",i.title="Ellipse frame marker",i.icon='<svg viewBox="0 0 24 24"><path d="M12 6c4.41 0 8 2.69 8 6s-3.59 6-8 6-8-2.69-8-6 3.59-6 8-6m0-2C6.5 4 2 7.58 2 12s4.5 8 10 8 10-3.58 10-8-4.5-8-10-8z"/></svg>',i}(R),V=function(){function t(){this.undoStack=[],this.redoStack=[]}return Object.defineProperty(t.prototype,"isUndoPossible",{get:function(){return this.undoStack.length>0},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"isRedoPossible",{get:function(){return this.redoStack.length>0},enumerable:!1,configurable:!0}),t.prototype.addUndoStep=function(t){0!==this.undoStack.length&&JSON.stringify(this.undoStack[this.undoStack.length-1])===JSON.stringify(t)||(this.undoStack.push(t),JSON.stringify(this.lastRedoStep)!==JSON.stringify(t)&&this.redoStack.splice(0,this.redoStack.length))},t.prototype.undo=function(){if(this.undoStack.length>1){var t=this.undoStack.pop();return void 0!==t&&this.redoStack.push(t),this.undoStack.length>0?this.undoStack[this.undoStack.length-1]:void 0}},t.prototype.redo=function(){return this.lastRedoStep=this.redoStack.pop(),this.lastRedoStep},t}(),_=function(t){function i(e,i,o){var s=t.call(this,e,i,o)||this;return s.strokeColor="transparent",s.strokeWidth=0,s.strokeDasharray="",s.curveX=0,s.curveY=0,s.manipulationStartCurveX=0,s.manipulationStartCurveY=0,s.setStrokeColor=s.setStrokeColor.bind(s),s.setStrokeWidth=s.setStrokeWidth.bind(s),s.setStrokeDasharray=s.setStrokeDasharray.bind(s),s.positionGrips=s.positionGrips.bind(s),s.addControlGrips=s.addControlGrips.bind(s),s.adjustVisual=s.adjustVisual.bind(s),s.setupControlBox=s.setupControlBox.bind(s),s.resize=s.resize.bind(s),s.strokeColor=o.defaultColor,s.strokeWidth=o.defaultStrokeWidth,s.strokeDasharray=o.defaultStrokeDasharray,s.strokePanel=new y("Line color",o.defaultColorSet,o.defaultColor),s.strokePanel.onColorChanged=s.setStrokeColor,s.strokeWidthPanel=new S("Line width",o.defaultStrokeWidths,o.defaultStrokeWidth),s.strokeWidthPanel.onWidthChanged=s.setStrokeWidth,s.strokeStylePanel=new k("Line style",o.defaultStrokeDasharrays,o.defaultStrokeDasharray),s.strokeStylePanel.onStyleChanged=s.setStrokeDasharray,s}return e(i,t),i.prototype.ownsTarget=function(e){return!(!t.prototype.ownsTarget.call(this,e)&&e!==this.visual&&e!==this.selectorCurve&&e!==this.visibleCurve&&!this.curveGrip.ownsTarget(e))},i.prototype.getPathD=function(){return"M "+this.x1+" "+this.y1+" Q "+this.curveX+" "+this.curveY+", "+this.x2+" "+this.y2},i.prototype.createVisual=function(){this.visual=r.createGroup(),this.selectorCurve=r.createPath(this.getPathD(),[["stroke","transparent"],["stroke-width",(this.strokeWidth+10).toString()],["fill","transparent"]]),this.visibleCurve=r.createPath(this.getPathD(),[["stroke",this.strokeColor],["stroke-width",this.strokeWidth.toString()],["fill","transparent"]]),this.visual.appendChild(this.selectorCurve),this.visual.appendChild(this.visibleCurve),this.addMarkerVisualToContainer(this.visual)},i.prototype.pointerDown=function(e,i){t.prototype.pointerDown.call(this,e,i),this.manipulationStartCurveX=this.curveX,this.manipulationStartCurveY=this.curveY,"new"===this.state&&(this.curveX=e.x,this.curveY=e.y),"new"===this.state?(this.createVisual(),this.adjustVisual(),this._state="creating"):this.curveGrip.ownsTarget(i)&&(this.activeGrip=this.curveGrip,this._state="resize")},i.prototype.adjustVisual=function(){this.selectorCurve&&this.visibleCurve&&(this.selectorCurve.setAttribute("d",this.getPathD()),this.visibleCurve.setAttribute("d",this.getPathD()),r.setAttributes(this.visibleCurve,[["stroke",this.strokeColor]]),r.setAttributes(this.visibleCurve,[["stroke-width",this.strokeWidth.toString()]]),r.setAttributes(this.visibleCurve,[["stroke-dasharray",this.strokeDasharray.toString()]]))},i.prototype.setupControlBox=function(){t.prototype.setupControlBox.call(this),this.curveControlLine1=r.createLine(this.x1,this.y1,this.curveX,this.curveY,[["stroke","black"],["stroke-width","1"],["stroke-opacity","0.5"],["stroke-dasharray","3, 2"]]),this.curveControlLine2=r.createLine(this.x2,this.y2,this.curveX,this.curveY,[["stroke","black"],["stroke-width","1"],["stroke-opacity","0.5"],["stroke-dasharray","3, 2"]]),this.controlBox.insertBefore(this.curveControlLine1,this.controlBox.firstChild),this.controlBox.insertBefore(this.curveControlLine2,this.controlBox.firstChild)},i.prototype.addControlGrips=function(){this.curveGrip=this.createGrip(),this.curveX=0,this.curveY=0,t.prototype.addControlGrips.call(this)},i.prototype.positionGrips=function(){t.prototype.positionGrips.call(this);var e=this.curveGrip.GRIP_SIZE;this.positionGrip(this.curveGrip.visual,this.curveX-e/2,this.curveY-e/2),this.curveControlLine1&&this.curveControlLine2&&(this.curveControlLine1.setAttribute("x1",this.x1.toString()),this.curveControlLine1.setAttribute("y1",this.y1.toString()),this.curveControlLine1.setAttribute("x2",this.curveX.toString()),this.curveControlLine1.setAttribute("y2",this.curveY.toString()),this.curveControlLine2.setAttribute("x1",this.x2.toString()),this.curveControlLine2.setAttribute("y1",this.y2.toString()),this.curveControlLine2.setAttribute("x2",this.curveX.toString()),this.curveControlLine2.setAttribute("y2",this.curveY.toString()))},i.prototype.manipulate=function(e){"move"===this.state&&(this.curveX=this.manipulationStartCurveX+e.x-this.manipulationStartX,this.curveY=this.manipulationStartCurveY+e.y-this.manipulationStartY),t.prototype.manipulate.call(this,e)},i.prototype.resize=function(e){this.activeGrip===this.curveGrip&&(this.curveX=e.x,this.curveY=e.y),t.prototype.resize.call(this,e),"creating"===this.state&&(this.curveX=this.x1+(this.x2-this.x1)/2,this.curveY=this.y1+(this.y2-this.y1)/2)},i.prototype.setStrokeColor=function(t){this.strokeColor=t,this.adjustVisual(),this.colorChanged(t)},i.prototype.setStrokeWidth=function(t){this.strokeWidth=t,this.adjustVisual()},i.prototype.setStrokeDasharray=function(t){this.strokeDasharray=t,this.adjustVisual()},i.prototype.scale=function(e,i){this.curveX=this.curveX*e,this.curveY=this.curveY*i,t.prototype.scale.call(this,e,i)},Object.defineProperty(i.prototype,"toolboxPanels",{get:function(){return[this.strokePanel,this.strokeWidthPanel,this.strokeStylePanel]},enumerable:!1,configurable:!0}),i.prototype.getState=function(){var e=Object.assign({strokeColor:this.strokeColor,strokeWidth:this.strokeWidth,strokeDasharray:this.strokeDasharray,curveX:this.curveX,curveY:this.curveY},t.prototype.getState.call(this));return e.typeName=i.typeName,e},i.prototype.restoreState=function(e){t.prototype.restoreState.call(this,e);var i=e;this.strokeColor=i.strokeColor,this.strokeWidth=i.strokeWidth,this.strokeDasharray=i.strokeDasharray,this.curveX=i.curveX,this.curveY=i.curveY,this.createVisual(),this.adjustVisual()},i.typeName="CurveMarker",i.title="Curve marker",i.icon='<svg viewBox="0 0 24 24"><path d="M18.5 2A1.5 1.5 0 0120 3.5 1.5 1.5 0 0118.5 5c-.23 0-.45-.05-.65-.15l-3.69 3.7.34.45c2.19-1.26 4.76-2 7.5-2l1 .03v2.01L22 9c-2.58 0-5 .75-7 2.04A3.96 3.96 0 0111.04 15C9.75 17 9 19.42 9 22l.04 1H7.03L7 22c0-2.74.74-5.31 2-7.5l-.45-.34-3.7 3.69c.1.2.15.42.15.65A1.5 1.5 0 013.5 20 1.5 1.5 0 012 18.5 1.5 1.5 0 013.5 17c.23 0 .45.05.65.15l3.69-3.7C7.31 12.78 7 11.92 7 11a4 4 0 014-4c.92 0 1.78.31 2.45.84l3.7-3.69c-.1-.2-.15-.42-.15-.65A1.5 1.5 0 0118.5 2M11 9a2 2 0 00-2 2 2 2 0 002 2 2 2 0 002-2 2 2 0 00-2-2z"/></svg>',i}(B),G=function(){function t(t,e){void 0===e&&(e=!1),this.cancelable=!1,this._defaultPrevented=!1,this.markerArea=t,this.cancelable=e}return Object.defineProperty(t.prototype,"defaultPrevented",{get:function(){return this._defaultPrevented},enumerable:!1,configurable:!0}),t.prototype.preventDefault=function(){this._defaultPrevented=!0},t}(),F=function(t){function i(e,i,o){var s=t.call(this,e,!1)||this;return s.dataUrl=i,s.state=o,s}return e(i,t),i}(G),j=function(t){function i(e,i,o){void 0===o&&(o=!1);var s=t.call(this,e,o)||this;return s.marker=i,s}return e(i,t),i}(G),U=function(){function t(){this.render=[],this.beforeclose=[],this.close=[],this.show=[],this.restorestate=[],this.markerselect=[],this.markerdeselect=[],this.markercreating=[],this.markercreate=[],this.markerbeforedelete=[],this.markerdelete=[],this.focus=[],this.blur=[]}return t.prototype.addEventListener=function(t,e){this[t].push(e)},t.prototype.removeEventListener=function(t,e){var i=this[t].indexOf(e);i>-1&&this[t].splice(i,1)},t}(),X=function(){function t(t){this.touchPoints=0,this._availableMarkerTypes=this.DEFAULT_MARKER_TYPES,this.mode="select",this.markers=[],this.isDragging=!1,this.renderEventListeners=[],this.closeEventListeners=[],this.settings=new x,this._isOpen=!1,this.undoRedoManager=new V,this.renderAtNaturalSize=!1,this.renderImageType="image/png",this.renderMarkersOnly=!1,this.zoomSteps=[1,1.5,2,4],this._zoomLevel=1,this.prevPanPoint={x:0,y:0},this.eventListeners=new U,this._silentRenderMode=!1,this._isFocused=!1,h.settings=h.defaultSettings,this.uiStyleSettings=h.settings,this.target=t,this.targetRoot=document.body,this.width=t.clientWidth,this.height=t.clientHeight,h.removeStyleSheet(),this.open=this.open.bind(this),this.setTopLeft=this.setTopLeft.bind(this),this.toolbarButtonClicked=this.toolbarButtonClicked.bind(this),this.createNewMarker=this.createNewMarker.bind(this),this.addNewMarker=this.addNewMarker.bind(this),this.markerCreated=this.markerCreated.bind(this),this.setCurrentMarker=this.setCurrentMarker.bind(this),this.onPointerDown=this.onPointerDown.bind(this),this.onDblClick=this.onDblClick.bind(this),this.onPointerMove=this.onPointerMove.bind(this),this.onPointerUp=this.onPointerUp.bind(this),this.onPointerOut=this.onPointerOut.bind(this),this.onKeyUp=this.onKeyUp.bind(this),this.overrideOverflow=this.overrideOverflow.bind(this),this.restoreOverflow=this.restoreOverflow.bind(this),this.close=this.close.bind(this),this.closeUI=this.closeUI.bind(this),this.addCloseEventListener=this.addCloseEventListener.bind(this),this.removeCloseEventListener=this.removeCloseEventListener.bind(this),this.addRenderEventListener=this.addRenderEventListener.bind(this),this.removeRenderEventListener=this.removeRenderEventListener.bind(this),this.clientToLocalCoordinates=this.clientToLocalCoordinates.bind(this),this.onWindowResize=this.onWindowResize.bind(this),this.deleteSelectedMarker=this.deleteSelectedMarker.bind(this),this.setWindowHeight=this.setWindowHeight.bind(this),this.removeMarker=this.removeMarker.bind(this),this.colorChanged=this.colorChanged.bind(this),this.fillColorChanged=this.fillColorChanged.bind(this),this.onPopupTargetResize=this.onPopupTargetResize.bind(this),this.showNotesEditor=this.showNotesEditor.bind(this),this.hideNotesEditor=this.hideNotesEditor.bind(this),this.stepZoom=this.stepZoom.bind(this),this.focus=this.focus.bind(this),this.blur=this.blur.bind(this)}return Object.defineProperty(t.prototype,"ALL_MARKER_TYPES",{get:function(){return[w,T,A,P,z,R,W,N,O,D,M,_]},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"DEFAULT_MARKER_TYPES",{get:function(){return[w,T,A,P,R,W,N]},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"BASIC_MARKER_TYPES",{get:function(){return[w,T,A,P,W]},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"availableMarkerTypes",{get:function(){return this._availableMarkerTypes},set:function(t){var e=this;this._availableMarkerTypes.splice(0),t.forEach((function(t){if("string"==typeof t){var i=e.ALL_MARKER_TYPES.find((function(e){return e.typeName===t}));void 0!==i&&e._availableMarkerTypes.push(i)}else e._availableMarkerTypes.push(t)}))},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"isOpen",{get:function(){return this._isOpen},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"zoomLevel",{get:function(){return this._zoomLevel},set:function(t){this._zoomLevel=t,this.editorCanvas&&this.contentDiv&&(this.editorCanvas.style.transform="scale("+this._zoomLevel+")",this.contentDiv.scrollTo({left:(this.editorCanvas.clientWidth*this._zoomLevel-this.contentDiv.clientWidth)/2,top:(this.editorCanvas.clientHeight*this._zoomLevel-this.contentDiv.clientHeight)/2}))},enumerable:!1,configurable:!0}),t.prototype.open=function(){this.setupResizeObserver(),this.setEditingTarget(),this.setTopLeft(),this.initMarkerCanvas(),this.initOverlay(),this.attachEvents(),"popup"===this.settings.displayMode&&this.onPopupTargetResize(),n.isLicensed||this.addLogo(),this._isOpen=!0,this._isFocused=!0},t.prototype.show=function(){var t=this;this.setWindowHeight(),this.showUI(),this.open(),this.eventListeners.show.forEach((function(e){return e(new G(t))}))},t.prototype.render=function(){return i(this,void 0,void 0,(function(){var t;return o(this,(function(e){switch(e.label){case 0:return this.setCurrentMarker(),(t=new a).naturalSize=this.renderAtNaturalSize,t.imageType=this.renderImageType,t.imageQuality=this.renderImageQuality,t.markersOnly=this.renderMarkersOnly,t.width=this.renderWidth,t.height=this.renderHeight,[4,t.rasterize(this.target instanceof HTMLImageElement?this.target:null,this.markerImage,this.renderTarget)];case 1:return e.sent(),[4,t.rasterize(this.target instanceof HTMLImageElement?this.target:null,this.markerImage,this.renderTarget)];case 2:return[2,e.sent()]}}))}))},t.prototype.close=function(t){var e=this;if(void 0===t&&(t=!1),this.isOpen){var i=!1;t||this.eventListeners.beforeclose.forEach((function(t){var o=new G(e,!0);t(o),o.defaultPrevented&&(i=!0)})),i||(this.coverDiv&&this.closeUI(),this.targetObserver&&this.targetObserver.unobserve(this.target),"popup"===this.settings.displayMode&&window.removeEventListener("resize",this.setWindowHeight),this.eventListeners.close.forEach((function(t){return t(new G(e))})),this.detachEvents(),this._isOpen=!1)}},t.prototype.addMarkersToToolbar=function(){for(var t,e=[],i=0;i<arguments.length;i++)e[i]=arguments[i];(t=this._availableMarkerTypes).push.apply(t,e)},t.prototype.addRenderEventListener=function(t){this.addEventListener("render",(function(e){t(e.dataUrl,e.state)}))},t.prototype.removeRenderEventListener=function(t){},t.prototype.addCloseEventListener=function(t){this.addEventListener("close",(function(){t()}))},t.prototype.removeCloseEventListener=function(t){},t.prototype.setupResizeObserver=function(){var t=this;"inline"===this.settings.displayMode?window.ResizeObserver&&(this.targetObserver=new ResizeObserver((function(){t.resize(t.target.clientWidth,t.target.clientHeight)})),this.targetObserver.observe(this.target)):"popup"===this.settings.displayMode&&(window.ResizeObserver&&(this.targetObserver=new ResizeObserver((function(){return t.onPopupTargetResize()})),this.targetObserver.observe(this.editorCanvas)),window.addEventListener("resize",this.setWindowHeight))},t.prototype.onPopupTargetResize=function(){var t=1*this.target.clientWidth/this.target.clientHeight,e=this.editorCanvas.clientWidth/t>this.editorCanvas.clientHeight?this.editorCanvas.clientHeight*t:this.editorCanvas.clientWidth,i=e<this.editorCanvas.clientWidth?this.editorCanvas.clientHeight:this.editorCanvas.clientWidth/t;this.resize(e,i)},t.prototype.setWindowHeight=function(){this.windowHeight=window.innerHeight},t.prototype.resize=function(t,e){var i=t/this.imageWidth,o=e/this.imageHeight;this.imageWidth=Math.round(t),this.imageHeight=Math.round(e),this.target instanceof HTMLImageElement&&this.editingTarget instanceof HTMLImageElement&&(this.editingTarget.src=this.target.src),this.editingTarget.width=this.imageWidth,this.editingTarget.height=this.imageHeight,this.editingTarget.style.width=this.imageWidth+"px",this.editingTarget.style.height=this.imageHeight+"px",this.markerImage.setAttribute("width",this.imageWidth.toString()),this.markerImage.setAttribute("height",this.imageHeight.toString()),this.markerImage.setAttribute("viewBox","0 0 "+this.imageWidth.toString()+" "+this.imageHeight.toString()),this.markerImageHolder.style.width=this.imageWidth+"px",this.markerImageHolder.style.height=this.imageHeight+"px",this.overlayContainer.style.width=this.imageWidth+"px",this.overlayContainer.style.height=this.imageHeight+"px","popup"!==this.settings.displayMode?this.coverDiv.style.width=this.imageWidth.toString()+"px":(this.setTopLeft(),this.positionMarkerImage()),void 0!==this.toolbar&&this.toolbar.adjustLayout(),this.positionLogo(),this.scaleMarkers(i,o)},t.prototype.scaleMarkers=function(t,e){var i;this.currentMarker&&this.currentMarker instanceof P||(i=this.currentMarker,this.setCurrentMarker()),this.markers.forEach((function(i){return i.scale(t,e)})),void 0!==i&&this.setCurrentMarker(i)},t.prototype.setEditingTarget=function(){this.imageWidth=Math.round(this.target.clientWidth),this.imageHeight=Math.round(this.target.clientHeight),this.target instanceof HTMLImageElement&&this.editingTarget instanceof HTMLImageElement&&(this.editingTarget.src=this.target.src),this.editingTarget.width=this.imageWidth,this.editingTarget.height=this.imageHeight,this.editingTarget.style.width=this.imageWidth+"px",this.editingTarget.style.height=this.imageHeight+"px"},t.prototype.setTopLeft=function(){var t=this.editingTarget.getBoundingClientRect(),e=this.editorCanvas.getBoundingClientRect();this.left=t.left-e.left,this.top=t.top-e.top},t.prototype.initMarkerCanvas=function(){this.markerImageHolder=document.createElement("div"),this.markerImageHolder.style.setProperty("touch-action","pinch-zoom"),this.markerImage=document.createElementNS("http://www.w3.org/2000/svg","svg"),this.markerImage.setAttribute("xmlns","http://www.w3.org/2000/svg"),this.markerImage.setAttribute("width",this.imageWidth.toString()),this.markerImage.setAttribute("height",this.imageHeight.toString()),this.markerImage.setAttribute("viewBox","0 0 "+this.imageWidth.toString()+" "+this.imageHeight.toString()),this.markerImage.style.pointerEvents="auto",this.markerImageHolder.style.position="absolute",this.markerImageHolder.style.width=this.imageWidth+"px",this.markerImageHolder.style.height=this.imageHeight+"px",this.markerImageHolder.style.transformOrigin="top left",this.positionMarkerImage(),this.markerImageHolder.appendChild(this.markerImage),this.editorCanvas.appendChild(this.markerImageHolder)},t.prototype.addDefs=function(){for(var t,e=[],i=0;i<arguments.length;i++)e[i]=arguments[i];this.defs=r.createDefs(),this.markerImage.insertBefore(this.defs,this.markerImage.firstChild),(t=this.defs).append.apply(t,e)},t.prototype.initOverlay=function(){this.overlayContainer=document.createElement("div"),this.overlayContainer.style.position="absolute",this.overlayContainer.style.left="0px",this.overlayContainer.style.top="0px",this.overlayContainer.style.width=this.imageWidth+"px",this.overlayContainer.style.height=this.imageHeight+"px",this.overlayContainer.style.display="flex",this.markerImageHolder.appendChild(this.overlayContainer)},t.prototype.positionMarkerImage=function(){this.markerImageHolder.style.top=this.top/this.zoomLevel+"px",this.markerImageHolder.style.left=this.left/this.zoomLevel+"px"},t.prototype.attachEvents=function(){this.markerImage.addEventListener("pointerdown",this.onPointerDown),this.markerImage.addEventListener("dblclick",this.onDblClick),this.attachWindowEvents()},t.prototype.attachWindowEvents=function(){window.addEventListener("pointermove",this.onPointerMove),window.addEventListener("pointerup",this.onPointerUp),window.addEventListener("pointercancel",this.onPointerOut),window.addEventListener("pointerout",this.onPointerOut),window.addEventListener("pointerleave",this.onPointerUp),window.addEventListener("resize",this.onWindowResize),window.addEventListener("keyup",this.onKeyUp)},t.prototype.detachEvents=function(){this.markerImage.removeEventListener("pointerdown",this.onPointerDown),this.markerImage.removeEventListener("dblclick",this.onDblClick),this.detachWindowEvents()},t.prototype.detachWindowEvents=function(){window.removeEventListener("pointermove",this.onPointerMove),window.removeEventListener("pointerup",this.onPointerUp),window.removeEventListener("pointercancel",this.onPointerOut),window.removeEventListener("pointerout",this.onPointerOut),window.removeEventListener("pointerleave",this.onPointerUp),window.removeEventListener("resize",this.onWindowResize),window.removeEventListener("keyup",this.onKeyUp)},t.prototype.addLogo=function(){this.logoUI=document.createElement("div"),this.logoUI.style.display="inline-block",this.logoUI.style.margin="0px",this.logoUI.style.padding="0px",this.logoUI.style.fill="#333333";var t=document.createElement("a");t.href="https://markerjs.com/",t.target="_blank",t.innerHTML='<svg viewBox="0 0 112 96" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414"><path fill="#e5f20d" fill-opacity=".647" d="M0 40.386h111.96V95.62H0z"/><path d="M93.61 61.452c0 .987-.328 1.831-.987 2.53-.657.7-1.52 1.048-2.591 1.048-1.481 0-2.222-.74-2.222-2.22 0-16.617-.533-29.347-1.604-38.192-1.068-8.842-2.92-13.265-5.552-13.265-4.443 0-10.94 15.509-19.497 46.52v.124c0 .987-.328 1.831-.987 2.53-.657.7-1.52 1.048-2.592 1.048-1.48 0-2.22-.74-2.22-2.22 0-3.29.165-8.392.493-15.302.33-7.732.494-13.82.494-18.262 0-6.17-.186-10.55-.556-13.142-.37-2.591-1.172-3.887-2.406-3.887-2.796 0-6.333 5.12-10.612 15.363C38.494 34.367 34.01 46.44 29.32 60.34l-1.11 3.209a5.714 5.714 0 01-1.42 2.097c-.617.578-1.295.864-2.036.864-.987 0-1.644-.081-1.974-.247-.328-.162-.533-.656-.617-1.48-.41-4.03-.74-9.418-.987-16.165-.163-1.728-.329-4.566-.494-8.515-.822-13.901-1.562-23.3-2.221-28.196-.657-4.893-.987-7.628-.987-8.205 0-.657.33-1.44.987-2.345.659-.903 1.276-1.357 1.85-1.357 1.319 0 2.387.947 3.21 2.838.411.906.863 4.526 1.357 10.859.493 6.335.905 14.19 1.233 23.568l.617 18.88c4.527-13.983 9.216-26.673 14.068-38.068C45.65 6.686 50.093.988 54.123.988c2.715 0 4.566 1.974 5.553 5.923.987 3.949 1.481 9.667 1.481 17.152 0 3.949-.081 9.625-.247 17.029l-.123 5.676c3.373-11.762 6.725-21.634 10.057-29.615 3.331-7.979 6.685-11.97 10.056-11.97 8.475 0 12.71 18.757 12.71 56.269z" fill-rule="nonzero"/></svg>',t.title="Powered by marker.js",t.style.display="grid",t.style.alignItems="center",t.style.justifyItems="center",t.style.padding="3px",t.style.width="20px",t.style.height="20px",this.logoUI.appendChild(t),this.editorCanvas.appendChild(this.logoUI),this.logoUI.style.position="absolute",this.logoUI.style.pointerEvents="all",this.positionLogo()},t.prototype.positionLogo=function(){this.logoUI&&("right"!==this.uiStyleSettings.logoPosition?this.logoUI.style.left=this.markerImageHolder.offsetLeft+10+"px":this.logoUI.style.left=this.markerImageHolder.offsetLeft+this.markerImageHolder.offsetWidth-this.logoUI.clientWidth-10+"px",this.logoUI.style.top=this.markerImageHolder.offsetTop+this.markerImageHolder.offsetHeight-this.logoUI.clientHeight-10+"px")},t.prototype.overrideOverflow=function(){this.scrollXState=window.scrollX,this.scrollYState=window.scrollY,this.bodyOverflowState=document.body.style.overflow,window.scroll({top:0,left:0}),document.body.style.overflow="hidden"},t.prototype.restoreOverflow=function(){document.body.style.overflow=this.bodyOverflowState,window.scroll({top:this.scrollYState,left:this.scrollXState})},t.prototype.showUI=function(){switch("popup"===this.settings.displayMode&&this.overrideOverflow(),this.coverDiv=document.createElement("div"),this.coverDiv.style.visibility=this._silentRenderMode?"hidden":"visible",this.coverDiv.className=h.CLASS_PREFIX,this.coverDiv.style.fontSize="16px",this.coverDiv.style.userSelect="none",this.settings.displayMode){case"inline":this.coverDiv.style.position="absolute";var t=this.target.getClientRects().item(0).y>h.settings.toolbarHeight?this.target.offsetTop-h.settings.toolbarHeight:0;this.coverDiv.style.top=t+"px",this.coverDiv.style.left=this.target.offsetLeft.toString()+"px",this.coverDiv.style.width=this.target.offsetWidth.toString()+"px",this.coverDiv.style.zIndex=void 0!==this.uiStyleSettings.zIndex?this.uiStyleSettings.zIndex:"5";break;case"popup":this.coverDiv.style.position="absolute",this.coverDiv.style.top="0px",this.coverDiv.style.left="0px",this.coverDiv.style.width="100vw",this.coverDiv.style.height=window.innerHeight+"px",this.coverDiv.style.backgroundColor="rgba(0, 0, 0, 0.75)",this.coverDiv.style.zIndex=void 0!==this.uiStyleSettings.zIndex?this.uiStyleSettings.zIndex:"1000",this.coverDiv.style.display="flex"}this.targetRoot.appendChild(this.coverDiv),this.uiDiv=document.createElement("div"),this.uiDiv.style.display="flex",this.uiDiv.style.flexDirection="column",this.uiDiv.style.flexGrow="2",this.uiDiv.style.margin="popup"===this.settings.displayMode?this.settings.popupMargin+"px":"0px",this.uiDiv.style.border="0px",this.coverDiv.appendChild(this.uiDiv),this.toolbar=new c(this.uiDiv,this.settings.displayMode,this._availableMarkerTypes,this.uiStyleSettings),this.toolbar.addButtonClickListener(this.toolbarButtonClicked),this.toolbar.show(this._silentRenderMode||this.uiStyleSettings.hideToolbar?"hidden":"visible"),this.contentDiv=document.createElement("div"),this.contentDiv.style.display="flex",this.contentDiv.style.flexDirection="row",this.contentDiv.style.flexGrow="2",this.contentDiv.style.flexShrink="1","popup"===this.settings.displayMode&&(this.contentDiv.style.backgroundColor=this.uiStyleSettings.canvasBackgroundColor,this.contentDiv.style.maxHeight=this.windowHeight-2*this.settings.popupMargin-3.5*this.uiStyleSettings.toolbarHeight+"px",this.contentDiv.style.maxWidth="calc(100vw - "+2*this.settings.popupMargin+"px)"),this.contentDiv.style.overflow="auto",this.uiDiv.appendChild(this.contentDiv),this.editorCanvas=document.createElement("div"),this.editorCanvas.style.flexGrow="2",this.editorCanvas.style.flexShrink="1",this.editorCanvas.style.position="relative",this.editorCanvas.style.overflow="hidden",this.editorCanvas.style.display="flex","popup"===this.settings.displayMode&&(this.editorCanvas.style.alignItems="center",this.editorCanvas.style.justifyContent="center"),this.editorCanvas.style.pointerEvents="none",this.editorCanvas.style.transformOrigin="left top",this.editorCanvas.style.transform="scale("+this.zoomLevel+")",this.contentDiv.appendChild(this.editorCanvas),this.editingTarget=this.target instanceof HTMLImageElement?document.createElement("img"):document.createElement("canvas"),this.target.getClientRects().item(0).y<h.settings.toolbarHeight&&(this.editingTarget.style.marginTop=this.target.offsetTop-h.settings.toolbarHeight+"px"),this.editorCanvas.appendChild(this.editingTarget),this.toolbox=new u(this.uiDiv,this.settings.displayMode,this.uiStyleSettings),this.toolbox.show(this._silentRenderMode||this.uiStyleSettings.hideToolbox?"hidden":"visible")},t.prototype.closeUI=function(){"popup"===this.settings.displayMode&&this.restoreOverflow(),this.targetRoot.removeChild(this.coverDiv)},t.prototype.removeMarker=function(t){this.markerImage.removeChild(t.container),this.markers.indexOf(t)>-1&&this.markers.splice(this.markers.indexOf(t),1),t.dispose()},t.prototype.switchToSelectMode=function(){this.mode="select",this.hideNotesEditor(),void 0!==this.currentMarker&&("new"!==this.currentMarker.state?this.currentMarker.select():(this.removeMarker(this.currentMarker),this.setCurrentMarker(),this.markerImage.style.cursor="default"),this.addUndoStep())},t.prototype.toolbarButtonClicked=function(t,e){if("marker"===t&&void 0!==e)this.createNewMarker(e);else if("action"===t)switch(e){case"select":this.switchToSelectMode();break;case"delete":this.deleteSelectedMarker();break;case"clear":this.clear();break;case"undo":this.switchToSelectMode(),this.addUndoStep(),this.undo();break;case"redo":this.switchToSelectMode(),this.redo();break;case"zoom":this.stepZoom();break;case"zoom-out":this.zoomLevel=1;break;case"notes":void 0===this.notesArea?(this.switchToSelectMode(),this.zoomLevel=1,this.showNotesEditor()):this.switchToSelectMode();break;case"close":this.close();break;case"render":this.switchToSelectMode(),this.startRenderAndClose()}},t.prototype.deleteSelectedMarker=function(){var t=this;if(void 0!==this.currentMarker){var e=!1;if(this.eventListeners.markerbeforedelete.forEach((function(i){var o=new j(t,t.currentMarker,!0);i(o),o.defaultPrevented&&(e=!0)})),!e){var i=this.currentMarker;this.currentMarker.dispose(),this.markerImage.removeChild(this.currentMarker.container),this.markers.splice(this.markers.indexOf(this.currentMarker),1),this.setCurrentMarker(),this.addUndoStep(),this.eventListeners.markerdelete.forEach((function(e){return e(new j(t,i))}))}}},t.prototype.clear=function(){this.setCurrentMarker();for(var t=this.markers.length-1;t>=0;t--)this.setCurrentMarker(this.markers[t]),this.currentMarker.dispose(),this.markerImage.removeChild(this.currentMarker.container),this.markers.splice(this.markers.indexOf(this.currentMarker),1);this.addUndoStep()},Object.defineProperty(t.prototype,"isNotesAreaOpen",{get:function(){return void 0!==this.notesArea},enumerable:!1,configurable:!0}),t.prototype.showNotesEditor=function(){var t;void 0!==this.currentMarker&&(this.overlayContainer.innerHTML="",this.notesArea=document.createElement("textarea"),this.notesArea.className=this.uiStyleSettings.notesAreaStyleClassName,this.notesArea.style.pointerEvents="auto",this.notesArea.style.alignSelf="stretch",this.notesArea.style.width="100%",this.notesArea.style.margin=this.uiStyleSettings.toolbarHeight/4+"px",this.notesArea.value=null!==(t=this.currentMarker.notes)&&void 0!==t?t:"",this.overlayContainer.appendChild(this.notesArea))},t.prototype.hideNotesEditor=function(){this.isNotesAreaOpen&&(void 0!==this.currentMarker&&(this.currentMarker.notes=""!==this.notesArea.value.trim()?this.notesArea.value:void 0),this.overlayContainer.removeChild(this.notesArea),this.notesArea=void 0)},t.prototype.selectLastMarker=function(){this.markers.length>0&&this.setCurrentMarker(this.markers[this.markers.length-1])},t.prototype.addUndoStep=function(){void 0!==this.currentMarker&&"edit"===this.currentMarker.state||this.undoRedoManager.addUndoStep(this.getState())},t.prototype.undo=function(){var t=this.undoRedoManager.undo();void 0!==t&&(this.restoreState(t),this.selectLastMarker())},t.prototype.redo=function(){var t=this.undoRedoManager.redo();void 0!==t&&(this.restoreState(t),this.selectLastMarker())},t.prototype.stepZoom=function(){var t=this.zoomSteps.indexOf(this.zoomLevel);this.zoomLevel=t<this.zoomSteps.length-1?this.zoomSteps[t+1]:this.zoomSteps[0]},t.prototype.panTo=function(t){this.contentDiv.scrollBy({left:this.prevPanPoint.x-t.x,top:this.prevPanPoint.y-t.y}),this.prevPanPoint=t},t.prototype.startRenderAndClose=function(){return i(this,void 0,void 0,(function(){var t,e,i=this;return o(this,(function(o){switch(o.label){case 0:return[4,this.render()];case 1:return t=o.sent(),e=this.getState(),this.eventListeners.render.forEach((function(o){return o(new F(i,t,e))})),this.close(!0),[2]}}))}))},t.prototype.getState=function(t){!0===t&&this.setCurrentMarker();var e={width:this.imageWidth,height:this.imageHeight,markers:[]};return this.markers.forEach((function(t){return e.markers.push(t.getState())})),e},t.prototype.restoreState=function(t){var e=this;for(this.markers.splice(0);this.markerImage.lastChild;)this.markerImage.removeChild(this.markerImage.lastChild);t.markers.forEach((function(t){var i=e._availableMarkerTypes.find((function(e){return e.typeName===t.typeName}));if(void 0!==i){var o=e.addNewMarker(i);o.restoreState(t),e.markers.push(o)}})),t.width&&t.height&&(t.width!==this.imageWidth||t.height!==this.imageHeight)&&this.scaleMarkers(this.imageWidth/t.width,this.imageHeight/t.height),this.eventListeners.restorestate.forEach((function(t){return t(new G(e))}))},t.prototype.addNewMarker=function(t){var e=r.createGroup();return this.markerImage.appendChild(e),new t(e,this.overlayContainer,this.settings)},t.prototype.createNewMarker=function(t){var e,i=this;(e="string"==typeof t?this._availableMarkerTypes.find((function(e){return e.typeName===t})):t)&&(this.setCurrentMarker(),this.currentMarker=this.addNewMarker(e),this.currentMarker.onMarkerCreated=this.markerCreated,this.currentMarker.onColorChanged=this.colorChanged,this.currentMarker.onFillColorChanged=this.fillColorChanged,this.markerImage.style.cursor="crosshair",this.toolbar.setActiveMarkerButton(e.typeName),this.toolbox.setPanelButtons(this.currentMarker.toolboxPanels),this.eventListeners.markercreating.forEach((function(t){return t(new j(i,i.currentMarker))})))},t.prototype.markerCreated=function(t){var e=this;this.mode="select",this.markerImage.style.cursor="default",this.markers.push(t),this.setCurrentMarker(t),t instanceof T&&this.settings.newFreehandMarkerOnPointerUp?this.createNewMarker(T):this.toolbar.setSelectMode(),this.addUndoStep(),this.eventListeners.markercreate.forEach((function(t){return t(new j(e,e.currentMarker))}))},t.prototype.colorChanged=function(t){this.settings.defaultColorsFollowCurrentColors&&(this.settings.defaultColor=t,this.settings.defaultStrokeColor=t)},t.prototype.fillColorChanged=function(t){this.settings.defaultColorsFollowCurrentColors&&(this.settings.defaultFillColor=t)},t.prototype.setCurrentMarker=function(t){var e=this;this.currentMarker!==t&&void 0!==this.currentMarker&&(this.currentMarker.deselect(),this.toolbar.setCurrentMarker(),this.toolbox.setPanelButtons([]),this.eventListeners.markerdeselect.forEach((function(t){return t(new j(e,e.currentMarker))}))),this.currentMarker=t,void 0===this.currentMarker||this.currentMarker.isSelected||(this.currentMarker.select(),this.toolbar.setCurrentMarker(this.currentMarker),this.toolbox.setPanelButtons(this.currentMarker.toolboxPanels),this.eventListeners.markerselect.forEach((function(t){return t(new j(e,e.currentMarker))})))},t.prototype.onPointerDown=function(t){if(this._isFocused||this.focus(),this.touchPoints++,1===this.touchPoints||"touch"!==t.pointerType)if(void 0===this.currentMarker||"new"!==this.currentMarker.state&&"creating"!==this.currentMarker.state){if("select"===this.mode){var e=this.markers.find((function(e){return e.ownsTarget(t.target)}));void 0!==e?(this.setCurrentMarker(e),this.isDragging=!0,this.currentMarker.pointerDown(this.clientToLocalCoordinates(t.clientX,t.clientY),t.target)):(this.setCurrentMarker(),this.isDragging=!0,this.prevPanPoint={x:t.clientX,y:t.clientY})}}else this.isDragging=!0,this.currentMarker.pointerDown(this.clientToLocalCoordinates(t.clientX,t.clientY))},t.prototype.onDblClick=function(t){if(this._isFocused||this.focus(),"select"===this.mode){var e=this.markers.find((function(e){return e.ownsTarget(t.target)}));void 0!==e&&e!==this.currentMarker&&this.setCurrentMarker(e),void 0!==this.currentMarker?this.currentMarker.dblClick(this.clientToLocalCoordinates(t.clientX,t.clientY),t.target):this.setCurrentMarker()}},t.prototype.onPointerMove=function(t){1!==this.touchPoints&&"touch"===t.pointerType||(void 0!==this.currentMarker||this.isDragging)&&(void 0!==this.currentMarker&&"edit"===this.currentMarker.state||t.preventDefault(),void 0!==this.currentMarker?this.currentMarker.manipulate(this.clientToLocalCoordinates(t.clientX,t.clientY)):this.zoomLevel>1&&this.panTo({x:t.clientX,y:t.clientY}))},t.prototype.onPointerUp=function(t){this.touchPoints>0&&this.touchPoints--,0===this.touchPoints&&this.isDragging&&void 0!==this.currentMarker&&this.currentMarker.pointerUp(this.clientToLocalCoordinates(t.clientX,t.clientY)),this.isDragging=!1,this.addUndoStep()},t.prototype.onPointerOut=function(){this.touchPoints>0&&this.touchPoints--},t.prototype.onKeyUp=function(t){void 0===this.currentMarker||void 0!==this.notesArea||"Delete"!==t.key&&"Backspace"!==t.key||this.deleteSelectedMarker()},t.prototype.clientToLocalCoordinates=function(t,e){var i=this.markerImage.getBoundingClientRect();return{x:(t-i.left)/this.zoomLevel,y:(e-i.top)/this.zoomLevel}},t.prototype.onWindowResize=function(){this.positionUI()},t.prototype.positionUI=function(){switch(this.setTopLeft(),this.settings.displayMode){case"inline":var t=this.target.offsetTop>h.settings.toolbarHeight?this.target.offsetTop-h.settings.toolbarHeight:0;this.coverDiv.style.top=t+"px",this.coverDiv.style.left=this.target.offsetLeft.toString()+"px";break;case"popup":this.coverDiv.style.top="0px",this.coverDiv.style.left="0px",this.coverDiv.style.width="100vw",this.coverDiv.style.height=this.windowHeight+"px",this.contentDiv.style.maxHeight=this.windowHeight-2*this.settings.popupMargin-3.5*this.uiStyleSettings.toolbarHeight+"px"}this.positionMarkerImage(),this.positionLogo()},t.prototype.addLicenseKey=function(t){n.addKey(t)},t.prototype.addEventListener=function(t,e){this.eventListeners.addEventListener(t,e)},t.prototype.removeEventListener=function(t,e){this.eventListeners.removeEventListener(t,e)},t.prototype.renderState=function(t){this._silentRenderMode=!0,this.settings.displayMode="inline",this.isOpen||this.show(),this.restoreState(t),this.startRenderAndClose(),this._silentRenderMode=!1},Object.defineProperty(t.prototype,"isFocused",{get:function(){return this._isFocused},enumerable:!1,configurable:!0}),t.prototype.focus=function(){var t=this;this._isFocused||(this.attachWindowEvents(),this._isFocused=!0,void 0!==this._previousCurrentMarker&&this.setCurrentMarker(this._previousCurrentMarker),this.eventListeners.focus.forEach((function(e){return e(new G(t))})))},t.prototype.blur=function(){var t=this;this._isFocused&&(this.detachWindowEvents(),this._isFocused=!1,this._previousCurrentMarker=this.currentMarker,this.setCurrentMarker(),this.eventListeners.blur.forEach((function(e){return e(new G(t))})))},t}();export{n as Activator,A as ArrowMarker,L as ArrowTypePanel,N as CalloutMarker,y as ColorPickerPanel,D as CoverMarker,_ as CurveMarker,z as EllipseFrameMarker,R as EllipseMarker,U as EventListenerRepository,E as FontFamilyPanel,w as FrameMarker,T as FreehandMarker,W as HighlightMarker,M as LineMarker,k as LineStylePanel,S as LineWidthPanel,B as LinearMarkerBase,X as MarkerArea,G as MarkerAreaEvent,F as MarkerAreaRenderEvent,g as MarkerBase,j as MarkerEvent,O as MeasurementMarker,I as OpacityPanel,b as RectangleMarker,C as RectangularBoxMarkerBase,f as RectangularBoxMarkerGrips,v as ResizeGrip,x as Settings,h as Style,p as StyleClass,r as SvgHelper,P as TextMarker,d as ToolboxPanel,m as TransformMatrix};
+//# sourceMappingURL=markerjs2.esm.js.map
diff --git a/capsule-prototype/js/libs/markerjs2/markerjs2.esm.js.map b/capsule-prototype/js/libs/markerjs2/markerjs2.esm.js.map
new file mode 100644
index 0000000000000000000000000000000000000000..23f4da5ce28cbfcaef0fdbdde1f516c1add8fa5b
--- /dev/null
+++ b/capsule-prototype/js/libs/markerjs2/markerjs2.esm.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"markerjs2.esm.js","sources":["../node_modules/tslib/tslib.es6.js","../src/core/SvgHelper.ts","../src/core/Activator.ts","../src/core/Renderer.ts","../src/core/Style.ts","../src/ui/Toolbar.ts","../src/ui/Toolbox.ts","../src/ui/ToolboxPanel.ts","../src/ui/toolbox-panels/ColorPickerPanel.ts","../src/core/MarkerBase.ts","../src/markers/RectangularBoxMarkerGrips.ts","../src/markers/ResizeGrip.ts","../src/core/TransformMatrix.ts","../src/markers/RectangularBoxMarkerBase.ts","../src/markers/RectangleMarker.ts","../src/ui/toolbox-panels/LineWidthPanel.ts","../src/ui/toolbox-panels/LineStylePanel.ts","../src/markers/frame-marker/FrameMarker.ts","../src/core/Settings.ts","../src/markers/LinearMarkerBase.ts","../src/markers/line-marker/LineMarker.ts","../src/ui/toolbox-panels/FontFamilyPanel.ts","../src/markers/text-marker/TextMarker.ts","../src/markers/freehand-marker/FreehandMarker.ts","../src/ui/toolbox-panels/ArrowTypePanel.ts","../src/markers/arrow-marker/ArrowMarker.ts","../src/markers/cover-marker/CoverMarker.ts","../src/ui/toolbox-panels/OpacityPanel.ts","../src/markers/highlight-marker/HighlightMarker.ts","../src/markers/callout-marker/CalloutMarker.ts","../src/markers/ellipse-marker/EllipseMarker.ts","../src/markers/measurement-marker/MeasurementMarker.ts","../src/markers/ellipse-frame-marker/EllipseFrameMarker.ts","../src/core/UndoRedoManager.ts","../src/markers/curve-marker/CurveMarker.ts","../src/core/Events.ts","../src/MarkerArea.ts"],"sourcesContent":["/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n    extendStatics = Object.setPrototypeOf ||\r\n        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n        function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n    return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n    extendStatics(d, b);\r\n    function __() { this.constructor = d; }\r\n    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n    __assign = Object.assign || function __assign(t) {\r\n        for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n            s = arguments[i];\r\n            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n        }\r\n        return t;\r\n    }\r\n    return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n    var t = {};\r\n    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n        t[p] = s[p];\r\n    if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n            if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n                t[p[i]] = s[p[i]];\r\n        }\r\n    return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n    if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n    return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n    return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n    if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n    return new (P || (P = Promise))(function (resolve, reject) {\r\n        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n        function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n        step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n    });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n    return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n    function verb(n) { return function (v) { return step([n, v]); }; }\r\n    function step(op) {\r\n        if (f) throw new TypeError(\"Generator is already executing.\");\r\n        while (_) try {\r\n            if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n            if (y = 0, t) op = [op[0] & 2, t.value];\r\n            switch (op[0]) {\r\n                case 0: case 1: t = op; break;\r\n                case 4: _.label++; return { value: op[1], done: false };\r\n                case 5: _.label++; y = op[1]; op = [0]; continue;\r\n                case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n                default:\r\n                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n                    if (t[2]) _.ops.pop();\r\n                    _.trys.pop(); continue;\r\n            }\r\n            op = body.call(thisArg, _);\r\n        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n    }\r\n}\r\n\r\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\r\n    if (k2 === undefined) k2 = k;\r\n    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\r\n}) : (function(o, m, k, k2) {\r\n    if (k2 === undefined) k2 = k;\r\n    o[k2] = m[k];\r\n});\r\n\r\nexport function __exportStar(m, o) {\r\n    for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n}\r\n\r\nexport function __values(o) {\r\n    var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n    if (m) return m.call(o);\r\n    if (o && typeof o.length === \"number\") return {\r\n        next: function () {\r\n            if (o && i >= o.length) o = void 0;\r\n            return { value: o && o[i++], done: !o };\r\n        }\r\n    };\r\n    throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n    var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n    if (!m) return o;\r\n    var i = m.call(o), r, ar = [], e;\r\n    try {\r\n        while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n    }\r\n    catch (error) { e = { error: error }; }\r\n    finally {\r\n        try {\r\n            if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n        }\r\n        finally { if (e) throw e.error; }\r\n    }\r\n    return ar;\r\n}\r\n\r\nexport function __spread() {\r\n    for (var ar = [], i = 0; i < arguments.length; i++)\r\n        ar = ar.concat(__read(arguments[i]));\r\n    return ar;\r\n}\r\n\r\nexport function __spreadArrays() {\r\n    for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n    for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n        for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n            r[k] = a[j];\r\n    return r;\r\n};\r\n\r\nexport function __await(v) {\r\n    return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n    if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n    var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n    return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n    function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n    function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n    function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n    function fulfill(value) { resume(\"next\", value); }\r\n    function reject(value) { resume(\"throw\", value); }\r\n    function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n    var i, p;\r\n    return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n    function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n    if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n    var m = o[Symbol.asyncIterator], i;\r\n    return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n    function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n    function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n    if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n    return cooked;\r\n};\r\n\r\nvar __setModuleDefault = Object.create ? (function(o, v) {\r\n    Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n    o[\"default\"] = v;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n    if (mod && mod.__esModule) return mod;\r\n    var result = {};\r\n    if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n    __setModuleDefault(result, mod);\r\n    return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n    return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, privateMap) {\r\n    if (!privateMap.has(receiver)) {\r\n        throw new TypeError(\"attempted to get private field on non-instance\");\r\n    }\r\n    return privateMap.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, privateMap, value) {\r\n    if (!privateMap.has(receiver)) {\r\n        throw new TypeError(\"attempted to set private field on non-instance\");\r\n    }\r\n    privateMap.set(receiver, value);\r\n    return value;\r\n}\r\n","/**\n * Utility class to simplify SVG operations.\n */\nexport class SvgHelper {\n  /**\n   * Creates SVG \"defs\".\n   */\n  public static createDefs(): SVGDefsElement {\n    const defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');\n\n    return defs;\n  }\n\n  /**\n   * Sets attributes on an arbitrary SVG element\n   * @param el - target SVG element.\n   * @param attributes - set of name-value attribute pairs.\n   */\n  public static setAttributes(\n    el: SVGElement,\n    attributes: Array<[string, string]>\n  ): void {\n    for (const [attr, value] of attributes) {\n      el.setAttribute(attr, value);\n    }\n  }\n\n  /**\n   * Creates an SVG rectangle with the specified width and height.\n   * @param width \n   * @param height \n   * @param attributes - additional attributes.\n   */\n  public static createRect(\n    width: number | string,\n    height: number | string,\n    attributes?: Array<[string, string]>\n  ): SVGRectElement {\n    const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');\n\n    rect.setAttribute('width', width.toString());\n    rect.setAttribute('height', height.toString());\n    if (attributes) {\n      SvgHelper.setAttributes(rect, attributes);\n    }\n\n    return rect;\n  }\n\n  /**\n   * Creates an SVG line with specified end-point coordinates.\n   * @param x1 \n   * @param y1 \n   * @param x2 \n   * @param y2 \n   * @param attributes - additional attributes.\n   */\n  public static createLine(\n    x1: number | string,\n    y1: number | string,\n    x2: number | string,\n    y2: number | string,\n    attributes?: Array<[string, string]>\n  ): SVGLineElement {\n    const line = document.createElementNS('http://www.w3.org/2000/svg', 'line');\n\n    line.setAttribute('x1', x1.toString());\n    line.setAttribute('y1', y1.toString());\n    line.setAttribute('x2', x2.toString());\n    line.setAttribute('y2', y2.toString());\n    if (attributes) {\n      SvgHelper.setAttributes(line, attributes);\n    }\n\n    return line;\n  }\n\n  /**\n   * Creates an SVG polygon with specified points.\n   * @param points - points as string.\n   * @param attributes - additional attributes.\n   */\n  public static createPolygon(\n    points: string,\n    attributes?: Array<[string, string]>\n  ): SVGPolygonElement {\n    const polygon = document.createElementNS(\n      'http://www.w3.org/2000/svg',\n      'polygon'\n    );\n\n    polygon.setAttribute('points', points);\n    if (attributes) {\n      SvgHelper.setAttributes(polygon, attributes);\n    }\n\n    return polygon;\n  }\n\n  /**\n   * Creates an SVG circle with the specified radius.\n   * @param radius \n   * @param attributes - additional attributes.\n   */\n  public static createCircle(\n    radius: number,\n    attributes?: Array<[string, string]>\n  ): SVGCircleElement {\n    const circle = document.createElementNS(\n      'http://www.w3.org/2000/svg',\n      'circle'\n    );\n\n    circle.setAttribute('cx', (radius / 2).toString());\n    circle.setAttribute('cy', (radius / 2).toString());\n    circle.setAttribute('r', radius.toString());\n    if (attributes) {\n      SvgHelper.setAttributes(circle, attributes);\n    }\n\n    return circle;\n  }\n\n  /**\n   * Creates an SVG ellipse with the specified horizontal and vertical radii.\n   * @param rx \n   * @param ry \n   * @param attributes - additional attributes.\n   */\n  public static createEllipse(\n    rx: number,\n    ry: number,\n    attributes?: Array<[string, string]>\n  ): SVGEllipseElement {\n    const ellipse = document.createElementNS(\n      'http://www.w3.org/2000/svg',\n      'ellipse'\n    );\n\n    ellipse.setAttribute('cx', (rx / 2).toString());\n    ellipse.setAttribute('cy', (ry / 2).toString());\n    ellipse.setAttribute('rx', (rx / 2).toString());\n    ellipse.setAttribute('ry', (ry / 2).toString());\n    if (attributes) {\n      SvgHelper.setAttributes(ellipse, attributes);\n    }\n\n    return ellipse;\n  }\n\n  /**\n   * Creates an SVG group.\n   * @param attributes - additional attributes.\n   */\n  public static createGroup(attributes?: Array<[string, string]>): SVGGElement {\n    const g = document.createElementNS('http://www.w3.org/2000/svg', 'g');\n    if (attributes) {\n      SvgHelper.setAttributes(g, attributes);\n    }\n    return g;\n  }\n\n  /**\n   * Creates an SVG transform.\n   */\n  public static createTransform(): SVGTransform {\n    const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n\n    return svg.createSVGTransform();\n  }\n\n  /**\n   * Creates an SVG marker.\n   * @param id \n   * @param orient \n   * @param markerWidth \n   * @param markerHeight \n   * @param refX \n   * @param refY \n   * @param markerElement \n   */\n  public static createMarker(\n    id: string,\n    orient: string,\n    markerWidth: number | string,\n    markerHeight: number | string,\n    refX: number | string,\n    refY: number | string,\n    markerElement: SVGGraphicsElement\n  ): SVGMarkerElement {\n    const marker = document.createElementNS(\n      'http://www.w3.org/2000/svg',\n      'marker'\n    );\n    SvgHelper.setAttributes(marker, [\n      ['id', id],\n      ['orient', orient],\n      ['markerWidth', markerWidth.toString()],\n      ['markerHeight', markerHeight.toString()],\n      ['refX', refX.toString()],\n      ['refY', refY.toString()],\n    ]);\n\n    marker.appendChild(markerElement);\n\n    return marker;\n  }\n\n  /**\n   * Creaes an SVG text element.\n   * @param attributes - additional attributes.\n   */\n  public static createText(\n    attributes?: Array<[string, string]>\n  ): SVGTextElement {\n    const text = document.createElementNS('http://www.w3.org/2000/svg', 'text');\n    text.setAttribute('x', '0');\n    text.setAttribute('y', '0');\n\n    if (attributes) {\n      SvgHelper.setAttributes(text, attributes);\n    }\n\n    return text;\n  }\n\n  /**\n   * Creates an SVG TSpan.\n   * @param text - inner text.\n   * @param attributes - additional attributes.\n   */\n  public static createTSpan(\n    text: string,\n    attributes?: Array<[string, string]>\n  ): SVGTSpanElement {\n    const tspan = document.createElementNS(\n      'http://www.w3.org/2000/svg',\n      'tspan'\n    );\n    tspan.textContent = text;\n\n    if (attributes) {\n      SvgHelper.setAttributes(tspan, attributes);\n    }\n\n    return tspan;\n  }\n\n  /**\n   * Creates an SVG image element.\n   * @param attributes - additional attributes.\n   */\n  public static createImage(\n    attributes?: Array<[string, string]>\n  ): SVGImageElement {\n    const image = document.createElementNS(\n      'http://www.w3.org/2000/svg',\n      'image'\n    );\n\n    if (attributes) {\n      SvgHelper.setAttributes(image, attributes);\n    }\n\n    return image;\n  }\n\n  /**\n   * Creates an SVG point with the specified coordinates.\n   * @param x \n   * @param y \n   */\n  public static createPoint(      \n    x: number,\n    y: number\n  ): SVGPoint {\n      const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n      const svgPoint = svg.createSVGPoint();\n      svgPoint.x = x;\n      svgPoint.y = y;\n  \n      return svgPoint;\n  }\n\n  /**\n   * Creates an SVG path with the specified shape (d).\n   * @param d - path shape\n   * @param attributes - additional attributes.\n   */\n   public static createPath(\n    d: string,\n    attributes?: Array<[string, string]>\n  ): SVGPathElement {\n    const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');\n\n    path.setAttribute('d', d);\n    if (attributes) {\n      SvgHelper.setAttributes(path, attributes);\n    }\n\n    return path;\n  }\n}\n","/**\n * Manages commercial marker.js 2 licenses.\n */\nexport class Activator {\n  private static key: string;\n\n  /**\n   * Add a license key\n   * @param key license key sent to you after purchase.\n   */\n  public static addKey(key: string): void {\n    Activator.key = key;\n  }\n\n  /**\n   * Returns true if the copy of marker.js is commercially licensed.\n   */\n  public static get isLicensed(): boolean {\n    // NOTE:\n    // before removing or modifying this please consider supporting marker.js\n    // by visiting https://markerjs.com/ for details\n    // thank you!\n    if (Activator.key) {\n      const keyRegex = new RegExp(/^MJS2-[A-Z][0-9]{3}-[A-Z][0-9]{3}-[0-9]{4}$/, 'i');\n      return keyRegex.test(Activator.key);\n    } else {\n      return false;\n    }\n  }\n}\n","/**\n * Renders the original image and markup to a flat raster image.\n */\nexport class Renderer {\n    /**\n     * Whether the image should be rendered at the original (natural) target image size.\n     */\n    public naturalSize = false; \n    /**\n     * Rendered image type (`image/png`, `image/jpeg`, etc.).\n     */\n    public imageType = 'image/png';\n    /**\n     * For formats that support it, specifies rendering quality.\n     * \n     * In the case of `image/jpeg` you can specify a value between 0 and 1 (lowest to highest quality).\n     *\n     * @type {number} - image rendering quality (0..1)\n     */\n    public imageQuality?: number;\n    /**\n     * When set to true, only the marker layer without the original image will be rendered.\n     */\n    public markersOnly = false;\n\n    /**\n     * When set and {@linkcode naturalSize} is `false` sets the width of the rendered image.\n     * \n     * Both `width` and `height` have to be set for this to take effect.\n     */\n    public width?: number;\n    /**\n     * When set and {@linkcode naturalSize} is `false` sets the height of the rendered image.\n     * \n     * Both `width` and `height` have to be set for this to take effect.\n     */\n    public height?: number;\n\n\n    /**\n     * Initiates rendering of the result image and returns a promise which when resolved\n     * contains a data URL for the rendered image.\n     * \n     * @param target - target (underlying original) image\n     * @param markerImage - marker layer\n     */\n    public rasterize(\n        target: HTMLImageElement, \n        markerImage: SVGSVGElement,\n        targetCanvas?: HTMLCanvasElement \n    ): Promise<string> {\n        return new Promise<string>((resolve) => {\n            const canvas = targetCanvas !== undefined ? targetCanvas : document.createElement(\"canvas\");\n\n            if (target === null) {\n                this.markersOnly = true;\n                this.naturalSize = false;\n            }\n\n            const markerImageCopy = document.createElementNS(\n            'http://www.w3.org/2000/svg',\n            'svg'\n            );\n            markerImageCopy.setAttribute('xmlns', 'http://www.w3.org/2000/svg');\n            markerImageCopy.setAttribute('width', markerImage.width.baseVal.valueAsString);\n            markerImageCopy.setAttribute(\n              'height',\n              markerImage.height.baseVal.valueAsString\n            );\n            markerImageCopy.setAttribute(\n              'viewBox',\n              '0 0 ' +\n                markerImage.viewBox.baseVal.width.toString() +\n                ' ' +\n                markerImage.viewBox.baseVal.height.toString()\n            );            \n            markerImageCopy.innerHTML = markerImage.innerHTML;\n\n            if (this.naturalSize === true) {\n                // scale to full image size\n                markerImageCopy.width.baseVal.value = target.naturalWidth;\n                markerImageCopy.height.baseVal.value = target.naturalHeight;\n            } else if (this.width !== undefined && this.height !== undefined) {\n                // scale to specific dimensions\n                markerImageCopy.width.baseVal.value = this.width;\n                markerImageCopy.height.baseVal.value = this.height;\n            }\n    \n            canvas.width = markerImageCopy.width.baseVal.value;\n            canvas.height = markerImageCopy.height.baseVal.value;\n    \n            const data = markerImageCopy.outerHTML;\n\n            const ctx = canvas.getContext(\"2d\");\n            if (this.markersOnly !== true) { \n                ctx.drawImage(target, 0, 0, canvas.width, canvas.height);\n            }\n    \n            const DOMURL = window.URL; // || window.webkitURL || window;\n    \n            const img = new Image(canvas.width, canvas.height);\n            img.setAttribute(\"crossOrigin\", \"anonymous\");\n    \n            const blob = new Blob([data], { type: \"image/svg+xml\" });\n    \n            const url = DOMURL.createObjectURL(blob);\n    \n            img.onload = () => {\n                ctx.drawImage(img, 0, 0);\n                DOMURL.revokeObjectURL(url);\n    \n                const result = canvas.toDataURL(this.imageType, this.imageQuality);\n                resolve(result);\n            };\n    \n            img.src = url;\n        });\n    }\n}\n","import { IStyleSettings } from './IStyleSettings';\n\n/**\n * Simple utility CSS-in-JS implementation.\n */\nexport class Style {\n  /**\n   * Prefix used for all internally created CSS classes.\n   */\n  public static CLASS_PREFIX = '__markerjs2_';\n\n  private static classes: StyleClass[] = [];\n  private static rules: StyleRule[] = [];\n  private static styleSheet?: HTMLStyleElement;\n\n  /**\n   * For cases when you need to add the stylesheet to anything\n   * other than document.head (default), set this property\n   * befor calling `MarkerArea.show()`.\n   *\n   * Example: here we set the rendering/placement root (targetRoot)\n   * to the `shadowRoot` of a web componet and set `styleSheetRoot`\n   * to the same value as well.\n   *\n   * ```javascript\n   * const markerArea = new markerjs2.MarkerArea(target);\n   * markerArea.targetRoot = this.shadowRoot;\n   * markerjs2.Style.styleSheetRoot = this.shadowRoot;\n   * markerArea.show();\n   * ```\n   *\n   * Known issue/limitation:\n   * you can't use marker.js 2 in both main and Shadow DOM\n   * on the same page.\n   */\n  public static styleSheetRoot: HTMLElement;\n\n  /**\n   * Returns default UI styles.\n   */\n  public static get defaultSettings(): IStyleSettings {\n    return {\n      canvasBackgroundColor: '#ffffff',\n      toolbarBackgroundColor: '#111111',\n      toolbarBackgroundHoverColor: '#333333',\n      toolbarColor: '#eeeeee',\n      toolbarHeight: 40,\n      // toolboxBackgroundColor: '#2a2a2a',\n      toolboxColor: '#eeeeee',\n      toolboxAccentColor: '#3080c3',\n      undoButtonVisible: true,\n      redoButtonVisible: false,\n      zoomButtonVisible: false,\n      zoomOutButtonVisible: false,\n      clearButtonVisible: false,\n      resultButtonBlockVisible: true,\n      logoPosition: 'left',\n    };\n  }\n\n  /**\n   * Holds current UI styles.\n   */\n  public static settings: IStyleSettings = Style.defaultSettings;\n\n  /**\n   * Returns global fade-in animation class name.\n   */\n  public static get fadeInAnimationClassName(): string {\n    return `${Style.CLASS_PREFIX}fade_in`;\n  }\n  /**\n   * Returns global fade-out animation class name.\n   */\n  public static get fadeOutAnimationClassName(): string {\n    return `${Style.CLASS_PREFIX}fade_out`;\n  }\n\n  /**\n   * Adds a CSS class declaration.\n   * @param styleClass - class to add.\n   */\n  public static addClass(styleClass: StyleClass): StyleClass {\n    if (Style.styleSheet === undefined) {\n      Style.addStyleSheet();\n    }\n    Style.classes.push(styleClass);\n    // Style.styleSheet.sheet.addRule('.' + styleClass.name, styleClass.style);\n    Style.styleSheet.sheet.insertRule(\n      `.${styleClass.name} {${styleClass.style}}`,\n      Style.styleSheet.sheet.cssRules.length\n    );\n    return styleClass;\n  }\n\n  /**\n   * Add arbitrary CSS rule\n   * @param styleRule - CSS rule to add.\n   */\n  public static addRule(styleRule: StyleRule): void {\n    if (Style.styleSheet === undefined) {\n      Style.addStyleSheet();\n    }\n    Style.rules.push(styleRule);\n    // Style.styleSheet.sheet.addRule(styleRule.selector, styleRule.style); // crashes in Edge\n    Style.styleSheet.sheet.insertRule(\n      `${styleRule.selector} {${styleRule.style}}`,\n      Style.styleSheet.sheet.cssRules.length\n    );\n  }\n\n  private static addStyleSheet() {\n    Style.styleSheet = document.createElement('style');\n    (Style.styleSheetRoot ?? document.head).appendChild(Style.styleSheet);\n\n    // add global rules\n    Style.addRule(\n      new StyleRule(`.${Style.CLASS_PREFIX} h3`, 'font-family: sans-serif')\n    );\n\n    Style.addRule(\n      new StyleRule(\n        `@keyframes ${Style.CLASS_PREFIX}_fade_in_animation_frames`,\n        `\n        from {\n          opacity: 0;\n        }\n        to {\n          opacity: 1;\n        }\n    `\n      )\n    );\n    Style.addRule(\n      new StyleRule(\n        `@keyframes ${Style.CLASS_PREFIX}_fade_out_animation_frames`,\n        `\n        from {\n          opacity: 1;\n        }\n        to {\n          opacity: 0;\n        }\n    `\n      )\n    );\n\n    Style.addClass(\n      new StyleClass(\n        'fade_in',\n        `\n      animation-duration: 0.3s;\n      animation-name: ${Style.CLASS_PREFIX}_fade_in_animation_frames;\n    `\n      )\n    );\n    Style.addClass(\n      new StyleClass(\n        'fade_out',\n        `\n      animation-duration: 0.3s;\n      animation-name: ${Style.CLASS_PREFIX}_fade_out_animation_frames;\n    `\n      )\n    );\n  }\n\n  public static removeStyleSheet(): void {\n    if (Style.styleSheet) {\n      (Style.styleSheetRoot ?? document.head).removeChild(Style.styleSheet);\n      Style.styleSheet = undefined;\n    }\n  }\n}\n\n/**\n * Represents an arbitrary CSS rule.\n */\nexport class StyleRule {\n  /**\n   * CSS selector.\n   */\n  public selector: string;\n  /**\n   * Style declaration for the rule.\n   */\n  public style: string;\n  /**\n   * Creates an arbitrary CSS rule using the selector and style rules.\n   * @param selector - CSS selector\n   * @param style - styles to apply\n   */\n  constructor(selector: string, style: string) {\n    this.selector = selector;\n    this.style = style;\n  }\n}\n\n/**\n * Represents a CSS class.\n */\nexport class StyleClass {\n  /**\n   * CSS style rules for the class.\n   */\n  public style: string;\n\n  private _localName: string;\n  /**\n   * Returns fully qualified CSS class name.\n   */\n  public get name(): string {\n    return `${Style.CLASS_PREFIX}${this._localName}`;\n  }\n\n  /**\n   * Creates a CSS class declaration based on supplied (local) name and style rules.\n   * @param name - local CSS class name (will be prefixed with the marker.js prefix).\n   * @param style - style declarations.\n   */\n  constructor(name: string, style: string) {\n    this._localName = name;\n    this.style = style;\n  }\n}\n","import { MarkerBase } from './../core/MarkerBase';\nimport { Style, StyleClass, StyleRule } from './../core/Style';\n\nimport CursorIcon from './toolbar-core-icons/cursor.svg';\nimport DeleteIcon from './toolbar-core-icons/delete.svg';\nimport ClearIcon from './toolbar-core-icons/clear.svg';\nimport CheckIcon from './toolbar-core-icons/check.svg';\nimport CloseIcon from './toolbar-core-icons/close.svg';\nimport OverflowIcon from './toolbar-core-icons/overflow.svg';\nimport UndoIcon from './toolbar-core-icons/undo.svg';\nimport RedoIcon from './toolbar-core-icons/redo.svg';\nimport NotesIcon from './toolbar-core-icons/notes.svg';\nimport ZoomIcon from './toolbar-core-icons/zoom.svg';\nimport ZoomOutIcon from './toolbar-core-icons/zoom-out.svg';\nimport { IStyleSettings } from '../core/IStyleSettings';\nimport { DisplayMode } from '../core/Settings';\n\n/**\n * Toolbar button type:\n * - `action` for non-marker buttons like select, delete, etc.\n * - `marker` for marker type buttons.\n */\nexport type ToolbarButtonType = 'action' | 'marker';\n\n/**\n * Click handler type for toolbar button click events.\n */\nexport type ToolbarButtonClickHandler = (\n  buttonType: ToolbarButtonType,\n  value?: typeof MarkerBase | string\n) => void;\n\n/**\n * Toolbar represents the main toolbar of the marker.js 2 interface.\n */\nexport class Toolbar {\n  private markerItems: typeof MarkerBase[];\n\n  private buttons: HTMLDivElement[] = [];\n  private markerButtons: HTMLDivElement[] = [];\n  private overflowButton: HTMLDivElement;\n\n  private markerjsContainer: HTMLDivElement;\n  private displayMode: DisplayMode;\n  private uiContainer: HTMLDivElement;\n\n  private toolbarStyleClass: StyleClass;\n  private toolbarStyleColorsClass: StyleClass;\n  private toolbarBlockStyleClass: StyleClass;\n  private toolbarOverflowBlockStyleClass: StyleClass;\n  private toolbarOverflowBlockStyleColorsClass: StyleClass;\n  private toolbarButtonStyleClass: StyleClass;\n  private toolbarButtonStyleColorsClass: StyleClass;\n  private toolbarActiveButtonStyleColorsClass: StyleClass;\n\n  private markerButtonBlock: HTMLDivElement;\n  private markerButtonOverflowBlock: HTMLDivElement;\n\n  private buttonClickListeners: ToolbarButtonClickHandler[] = [];\n\n  private uiStyleSettings: IStyleSettings;\n\n  private currentMarker?: MarkerBase;\n\n  /**\n   * Creates the main marker.js toolbar.\n   * @param markerjsContainer - container for the toolbar in the marker.js UI.\n   * @param displayMode - marker.js display mode (`inline` or `popup`).\n   * @param markerItems - available marker types.\n   * @param uiStyleSettings - settings for styling the tooblar ui.\n   */\n  constructor(\n    markerjsContainer: HTMLDivElement,\n    displayMode: DisplayMode,\n    markerItems: typeof MarkerBase[],\n    uiStyleSettings: IStyleSettings\n  ) {\n    this.markerjsContainer = markerjsContainer;\n    this.displayMode = displayMode;\n    this.markerItems = markerItems;\n    this.uiStyleSettings = uiStyleSettings;\n    this.addStyles();\n\n    this.adjustLayout = this.adjustLayout.bind(this);\n    this.overflowButtonClicked = this.overflowButtonClicked.bind(this);\n    this.setCurrentMarker = this.setCurrentMarker.bind(this);\n  }\n\n  /**\n   * Creates and displays the toolbar UI.\n   */\n  public show(visiblity: string): void {\n    this.uiContainer = document.createElement('div');\n    this.uiContainer.style.visibility = visiblity;\n    this.uiContainer.className = `${this.toolbarStyleClass.name} ${\n      Style.fadeInAnimationClassName\n    } ${\n      this.uiStyleSettings.toolbarStyleColorsClassName\n        ? this.uiStyleSettings.toolbarStyleColorsClassName\n        : this.toolbarStyleColorsClass.name\n    }`;\n\n    const actionButtonBlock = document.createElement('div');\n    actionButtonBlock.className = this.toolbarBlockStyleClass.name;\n    actionButtonBlock.style.whiteSpace = 'nowrap';\n    this.uiContainer.appendChild(actionButtonBlock);\n\n    this.addActionButton(actionButtonBlock, CursorIcon, 'select');\n    this.addActionButton(actionButtonBlock, DeleteIcon, 'delete');\n    if (this.uiStyleSettings.clearButtonVisible) {\n      this.addActionButton(actionButtonBlock, ClearIcon, 'clear');\n    }\n    if (this.uiStyleSettings.undoButtonVisible) {\n      this.addActionButton(actionButtonBlock, UndoIcon, 'undo');\n    }\n    if (this.uiStyleSettings.redoButtonVisible) {\n      this.addActionButton(actionButtonBlock, RedoIcon, 'redo');\n    }\n    if (this.uiStyleSettings.zoomButtonVisible) {\n      this.addActionButton(actionButtonBlock, ZoomIcon, 'zoom');\n    }\n    if (\n      this.uiStyleSettings.zoomButtonVisible &&\n      this.uiStyleSettings.zoomOutButtonVisible\n    ) {\n      this.addActionButton(actionButtonBlock, ZoomOutIcon, 'zoom-out');\n    }\n    if (this.uiStyleSettings.notesButtonVisible) {\n      this.addActionButton(actionButtonBlock, NotesIcon, 'notes');\n    }\n\n    this.markerButtonBlock = document.createElement('div');\n    this.markerButtonBlock.className = this.toolbarBlockStyleClass.name;\n    this.markerButtonBlock.style.flexGrow = '2';\n    this.markerButtonBlock.style.textAlign = 'center';\n    this.uiContainer.appendChild(this.markerButtonBlock);\n\n    this.markerButtonOverflowBlock = document.createElement('div');\n    this.markerButtonOverflowBlock.className = `${\n      this.toolbarOverflowBlockStyleClass.name\n    } ${\n      this.uiStyleSettings.toolbarOverflowBlockStyleColorsClassName\n        ? this.uiStyleSettings.toolbarOverflowBlockStyleColorsClassName\n        : this.toolbarOverflowBlockStyleColorsClass.name\n    }`;\n    this.markerButtonOverflowBlock.style.display = 'none';\n    this.uiContainer.appendChild(this.markerButtonOverflowBlock);\n\n    if (this.markerItems) {\n      this.markerItems.forEach((mi) => {\n        const buttonContainer = document.createElement('div');\n        buttonContainer.className = `${this.toolbarButtonStyleClass.name}`;\n        buttonContainer.setAttribute('data-type-name', mi.typeName);\n        //  ${\n        //   this.uiStyleSettings.toolbarButtonStyleColorsClassName ?\n        //   this.uiStyleSettings.toolbarButtonStyleColorsClassName : this.toolbarButtonStyleColorsClass.name}`;\n        buttonContainer.innerHTML = mi.icon;\n        buttonContainer.addEventListener('click', () => {\n          this.markerToolbarButtonClicked(buttonContainer, mi);\n        });\n        //this.markerButtonBlock.appendChild(buttonContainer);\n        this.buttons.push(buttonContainer);\n        this.markerButtons.push(buttonContainer);\n      });\n      this.overflowButton = document.createElement('div');\n      this.overflowButton.className = `${this.toolbarButtonStyleClass.name} ${\n        this.uiStyleSettings.toolbarButtonStyleColorsClassName\n          ? this.uiStyleSettings.toolbarButtonStyleColorsClassName\n          : this.toolbarButtonStyleColorsClass.name\n      }`;\n      this.overflowButton.innerHTML = OverflowIcon;\n      this.overflowButton.addEventListener('click', this.overflowButtonClicked);\n      this.markerButtonBlock.appendChild(this.overflowButton);\n    }\n\n    const resultButtonBlock = document.createElement('div');\n    resultButtonBlock.className = this.toolbarBlockStyleClass.name;\n    resultButtonBlock.style.whiteSpace = 'nowrap';\n    resultButtonBlock.style.display =\n      this.uiStyleSettings.resultButtonBlockVisible !== false ? '' : 'none';\n    this.uiContainer.appendChild(resultButtonBlock);\n\n    this.addActionButton(resultButtonBlock, CheckIcon, 'render');\n    this.addActionButton(resultButtonBlock, CloseIcon, 'close');\n\n    this.markerjsContainer.appendChild(this.uiContainer);\n    this.setSelectMode();\n\n    this.setCurrentMarker();\n\n    this.adjustLayout();\n    // setTimeout(this.adjustLayout, 10);\n  }\n\n  /**\n   * Add a listener to the toolbar button click event.\n   * @param listener\n   */\n  public addButtonClickListener(listener: ToolbarButtonClickHandler): void {\n    this.buttonClickListeners.push(listener);\n  }\n\n  /**\n   * Remove a listener for the toolbar button click event.\n   * @param listener\n   */\n  public removeButtonClickListener(listener: ToolbarButtonClickHandler): void {\n    if (this.buttonClickListeners.indexOf(listener) > -1) {\n      this.buttonClickListeners.splice(\n        this.buttonClickListeners.indexOf(listener),\n        1\n      );\n    }\n  }\n\n  /**\n   * Switch toolbar to the `select` mode.\n   */\n  public setSelectMode(): void {\n    this.resetButtonStyles();\n    this.setActiveButton(this.buttons[0]);\n  }\n\n  /**\n   * Adjusts toolbar layout.\n   */\n  public adjustLayout(): void {\n    if (this.markerButtons && this.markerButtons.length > 0) {\n      const numberToFit =\n        Math.floor(\n          this.markerButtonBlock.clientWidth /\n            this.uiStyleSettings.toolbarHeight\n        ) - 1;\n      this.markerButtonBlock.innerHTML = '';\n      this.markerButtonOverflowBlock.innerHTML = '';\n      for (\n        let buttonIndex = 0;\n        buttonIndex < this.markerButtons.length;\n        buttonIndex++\n      ) {\n        if (\n          buttonIndex < numberToFit ||\n          (buttonIndex === numberToFit &&\n            this.markerButtons.length - 1 === numberToFit)\n        ) {\n          this.markerButtonBlock.appendChild(this.markerButtons[buttonIndex]);\n        } else {\n          if (buttonIndex === numberToFit) {\n            this.markerButtonBlock.appendChild(this.overflowButton);\n          }\n          this.markerButtonOverflowBlock.appendChild(\n            this.markerButtons[buttonIndex]\n          );\n        }\n      }\n    }\n  }\n\n  private overflowButtonClicked() {\n    if (this.markerButtonOverflowBlock.style.display !== 'none') {\n      this.markerButtonOverflowBlock.className = this.markerButtonOverflowBlock.className.replace(\n        Style.fadeInAnimationClassName,\n        ''\n      );\n      this.markerButtonOverflowBlock.style.display = 'none';\n    } else {\n      this.markerButtonOverflowBlock.className += ` ${Style.fadeInAnimationClassName}`;\n      this.markerButtonOverflowBlock.style.top = `${\n        this.uiContainer.offsetTop + this.overflowButton.offsetHeight\n      }px`;\n      this.markerButtonOverflowBlock.style.right = `${\n        this.uiContainer.offsetWidth -\n        this.overflowButton.offsetLeft -\n        this.overflowButton.offsetWidth +\n        this.uiContainer.offsetLeft * 2\n      }px`;\n      this.markerButtonOverflowBlock.style.display = 'inline-block';\n    }\n  }\n\n  private resetButtonStyles() {\n    this.buttons.forEach((button) => {\n      button.className = button.className\n        .replace(\n          this.uiStyleSettings.toolbarButtonStyleColorsClassName\n            ? this.uiStyleSettings.toolbarButtonStyleColorsClassName\n            : this.toolbarButtonStyleColorsClass.name,\n          ''\n        )\n        .trim();\n      button.className = button.className\n        .replace(\n          this.uiStyleSettings.toolbarActiveButtonStyleColorsClassName\n            ? this.uiStyleSettings.toolbarActiveButtonStyleColorsClassName\n            : this.toolbarActiveButtonStyleColorsClass.name,\n          ''\n        )\n        .trim();\n      button.className += ` ${\n        this.uiStyleSettings.toolbarButtonStyleColorsClassName\n          ? this.uiStyleSettings.toolbarButtonStyleColorsClassName\n          : this.toolbarButtonStyleColorsClass.name\n      }`;\n    });\n  }\n\n  private addActionButton(\n    container: HTMLDivElement,\n    icon: string,\n    value: string\n  ) {\n    const actionButton = document.createElement('div');\n    actionButton.className = `${this.toolbarButtonStyleClass.name}`;\n    //  ${\n    //   this.uiStyleSettings.toolbarButtonStyleColorsClassName ?\n    //   this.uiStyleSettings.toolbarButtonStyleColorsClassName : this.toolbarButtonStyleColorsClass.name}`;\n    actionButton.innerHTML = icon;\n    actionButton.setAttribute('data-action', value);\n    actionButton.addEventListener('click', () => {\n      this.actionToolbarButtonClicked(actionButton, value);\n    });\n    switch (value) {\n      case 'select':\n        actionButton.style.fill = this.uiStyleSettings.selectButtonColor;\n        break;\n      case 'delete':\n      case 'clear':\n        actionButton.style.fill = this.uiStyleSettings.deleteButtonColor;\n        break;\n      case 'undo':\n        actionButton.style.fill = this.uiStyleSettings.selectButtonColor;\n        break;\n      case 'redo':\n        actionButton.style.fill = this.uiStyleSettings.selectButtonColor;\n        break;\n      case 'render':\n        actionButton.style.fill = this.uiStyleSettings.okButtonColor;\n        break;\n      case 'close':\n        actionButton.style.fill = this.uiStyleSettings.closeButtonColor;\n        break;\n    }\n\n    container.appendChild(actionButton);\n    this.buttons.push(actionButton);\n  }\n\n  private addStyles() {\n    this.toolbarStyleClass = Style.addClass(\n      new StyleClass(\n        'toolbar',\n        `\n      width: 100%;\n      flex-shrink: 0;\n      display: flex;\n      flex-direction: row;\n      justify-content: space-between;      \n      height: ${this.uiStyleSettings.toolbarHeight}px;\n      box-sizing: content-box;\n      ${\n        this.displayMode === 'inline'\n          ? `border-top-left-radius: ${Math.round(\n              this.uiStyleSettings.toolbarHeight / 10\n            )}px;`\n          : ''\n      }\n      ${\n        this.displayMode === 'inline'\n          ? `border-top-right-radius: ${Math.round(\n              this.uiStyleSettings.toolbarHeight / 10\n            )}px;`\n          : ''\n      }\n      overflow: hidden;\n    `\n      )\n    );\n\n    this.toolbarStyleColorsClass = Style.addClass(\n      new StyleClass(\n        'toolbar_colors',\n        `\n      background-color: ${this.uiStyleSettings.toolbarBackgroundColor};\n      box-shadow: 0px 3px rgba(33, 33, 33, 0.1);\n    `\n      )\n    );\n\n    this.toolbarBlockStyleClass = Style.addClass(\n      new StyleClass(\n        'toolbar-block',\n        `\n        display: inline-block;\n        box-sizing: content-box;\n    `\n      )\n    );\n\n    this.toolbarOverflowBlockStyleClass = Style.addClass(\n      new StyleClass(\n        'toolbar-overflow-block',\n        `\n        position: absolute;\n        top: ${this.uiStyleSettings.toolbarHeight}px;\n        max-width: ${this.uiStyleSettings.toolbarHeight * 2}px;\n        z-index: 10;\n        box-sizing: content-box;\n      `\n      )\n    );\n    this.toolbarOverflowBlockStyleColorsClass = Style.addClass(\n      new StyleClass(\n        'toolbar-overflow-block_colors',\n        `\n        background-color: ${this.uiStyleSettings.toolbarBackgroundColor};\n      `\n      )\n    );\n\n    const buttonPadding = this.uiStyleSettings.toolbarHeight / 4;\n    this.toolbarButtonStyleClass = Style.addClass(\n      new StyleClass(\n        'toolbar_button',\n        `\n      display: inline-block;\n      width: ${this.uiStyleSettings.toolbarHeight - buttonPadding * 2}px;\n      height: ${this.uiStyleSettings.toolbarHeight - buttonPadding * 2}px;\n      padding: ${buttonPadding}px;\n      box-sizing: content-box;\n    `\n      )\n    );\n    this.toolbarButtonStyleColorsClass = Style.addClass(\n      new StyleClass(\n        'toolbar_button_colors',\n        `\n      fill: ${this.uiStyleSettings.toolbarColor};\n    `\n      )\n    );\n\n    this.toolbarActiveButtonStyleColorsClass = Style.addClass(\n      new StyleClass(\n        'toolbar_active_button',\n        `\n      fill: ${this.uiStyleSettings.toolbarColor};\n      background-color: ${this.uiStyleSettings.toolbarBackgroundHoverColor}\n    `\n      )\n    );\n\n    Style.addRule(\n      new StyleRule(\n        `.${this.toolbarButtonStyleClass.name} svg`,\n        `\n      height: ${this.uiStyleSettings.toolbarHeight / 2}px;\n    `\n      )\n    );\n\n    Style.addRule(\n      new StyleRule(\n        `.${this.toolbarButtonStyleColorsClass.name}:hover`,\n        `\n        background-color: ${this.uiStyleSettings.toolbarBackgroundHoverColor}\n    `\n      )\n    );\n  }\n\n  private markerToolbarButtonClicked(\n    button: HTMLDivElement,\n    markerType: typeof MarkerBase\n  ) {\n    this.setActiveButton(button);\n    if (this.buttonClickListeners && this.buttonClickListeners.length > 0) {\n      this.buttonClickListeners.forEach((listener) =>\n        listener('marker', markerType)\n      );\n    }\n    this.markerButtonOverflowBlock.style.display = 'none';\n  }\n\n  private actionToolbarButtonClicked(button: HTMLDivElement, action: string) {\n    if (this.buttonClickListeners && this.buttonClickListeners.length > 0) {\n      this.buttonClickListeners.forEach((listener) =>\n        listener('action', action)\n      );\n    }\n    this.markerButtonOverflowBlock.style.display = 'none';\n    this.setActiveButton(this.buttons[0]);\n  }\n\n  private setActiveButton(button: HTMLDivElement) {\n    this.resetButtonStyles();\n    button.className = button.className\n      .replace(\n        this.uiStyleSettings.toolbarButtonStyleColorsClassName\n          ? this.uiStyleSettings.toolbarButtonStyleColorsClassName\n          : this.toolbarButtonStyleColorsClass.name,\n        ''\n      )\n      .trim();\n    button.className += ` ${\n      this.uiStyleSettings.toolbarActiveButtonStyleColorsClassName\n        ? this.uiStyleSettings.toolbarActiveButtonStyleColorsClassName\n        : this.toolbarActiveButtonStyleColorsClass.name\n    }`;\n  }\n\n  /**\n   * Selects toolbar button for a specified marker type.\n   * @param typeName Marker type name\n   *\n   * @since 2.17.0\n   */\n  public setActiveMarkerButton(typeName: string): void {\n    const activeBtn = this.markerButtons.find(\n      (btn) => btn.getAttribute('data-type-name') === typeName\n    );\n    if (activeBtn) {\n      this.setActiveButton(activeBtn);\n    }\n  }\n\n  /**\n   * Sets current marker and enables/disables action buttons accordingly.\n   * @param marker\n   */\n  public setCurrentMarker(marker?: MarkerBase): void {\n    this.currentMarker = marker;\n    const activeMarkerButtons = this.buttons.filter((btn) =>\n      /delete|notes/.test(btn.getAttribute('data-action'))\n    );\n    activeMarkerButtons.forEach((btn) => {\n      if (this.currentMarker === undefined) {\n        btn.style.fillOpacity = '0.4';\n        btn.style.pointerEvents = 'none';\n      } else {\n        btn.style.fillOpacity = '1';\n        btn.style.pointerEvents = 'all';\n      }\n    });\n  }\n}\n","import { ToolboxPanel } from './ToolboxPanel';\nimport { Style, StyleClass, StyleRule } from './../core/Style';\nimport { DisplayMode } from '../core/Settings';\nimport { IStyleSettings } from '../core/IStyleSettings';\n\n/**\n * Represents the contextual toolbox for the selected marker type.\n */\nexport class Toolbox {\n  private panels: ToolboxPanel[] = [];\n  private activePanel: ToolboxPanel;\n  private panelButtons: HTMLDivElement[] = [];\n\n  private markerjsContainer: HTMLDivElement;\n  private displayMode: DisplayMode;\n  private uiContainer: HTMLDivElement;\n  private buttonRow: HTMLDivElement;\n  private panelRow: HTMLDivElement;\n\n  private toolboxStyleClass: StyleClass;\n  private toolboxStyleColorsClass: StyleClass;\n  private toolboxButtonStyleClass: StyleClass;\n  private toolboxButtonStyleColorsClass: StyleClass;\n  private toolboxActiveButtonStyleColorsClass: StyleClass;\n  private toolboxButtonRowStyleClass: StyleClass;\n  private toolboxButtonRowStyleColorsClass: StyleClass;\n  private toolboxPanelRowStyleClass: StyleClass;\n  private toolboxPanelRowStyleColorsClass: StyleClass;\n\n  private uiStyleSettings: IStyleSettings;\n  \n  private addStyles() {\n    this.toolboxStyleClass = Style.addClass(\n      new StyleClass(\n        'toolbox',\n        `\n      width: 100%;\n      flex-shrink: 0;\n      display: flex;\n      flex-direction: column;\n      font-family: sans-serif;\n      ${this.displayMode === 'popup' ? 'height:' + this.uiStyleSettings.toolbarHeight * 2.5 + 'px;' : ''}\n      box-sizing: content-box;\n      ${this.displayMode === 'popup' ? `background-color: ${this.uiStyleSettings.canvasBackgroundColor};` : ''}\n      ${this.displayMode === 'inline' ? `border-bottom-left-radius: ${Math.round(this.uiStyleSettings.toolbarHeight/10)}px;` : ''}\n      ${this.displayMode === 'inline' ? `border-bottom-right-radius: ${Math.round(this.uiStyleSettings.toolbarHeight/10)}px;` : ''}\n      overflow: hidden;\n    `\n      )\n    );\n    this.toolboxStyleColorsClass = Style.addClass(\n      new StyleClass(\n        'toolbox_colors',\n        `\n      color: ${this.uiStyleSettings.toolboxColor};\n    `\n      )\n    );\n\n    const buttonPadding = this.uiStyleSettings.toolbarHeight / 4;\n    this.toolboxButtonRowStyleClass = Style.addClass(new StyleClass('toolbox-button-row', `\n      display: flex;\n      cursor: default;\n      box-sizing: content-box;\n    `));\n    this.toolboxButtonRowStyleColorsClass = Style.addClass(new StyleClass('toolbox-button-row_colors', `\n      background-color: ${this.uiStyleSettings.toolbarBackgroundColor};\n    `));\n\n    this.toolboxPanelRowStyleClass = Style.addClass(new StyleClass('toolbox-panel-row', `\n      display: flex;\n      ${this.displayMode === 'inline' ? 'position: absolute;' : '' }\n      ${this.displayMode === 'inline' ? 'bottom: ' + this.uiStyleSettings.toolbarHeight + 'px;' : '' }\n      cursor: default;\n      height: ${this.uiStyleSettings.toolbarHeight * 1.5}px;\n      ${this.displayMode === 'inline' ? 'width: 100%;' : ''}\n      box-sizing: content-box;\n    `));\n    this.toolboxPanelRowStyleColorsClass = Style.addClass(new StyleClass('toolbox-panel-row_colors', `\n      background-color: ${this.uiStyleSettings.toolboxBackgroundColor ?? this.uiStyleSettings.toolbarBackgroundHoverColor};\n    `));\n\n    this.toolboxButtonStyleClass = Style.addClass(new StyleClass('toolbox_button', `\n      display: inline-block;\n      width: ${this.uiStyleSettings.toolbarHeight - buttonPadding * 2}px;\n      height: ${this.uiStyleSettings.toolbarHeight - buttonPadding * 2}px;\n      padding: ${buttonPadding}px;\n      box-sizing: content-box;\n    `));\n    this.toolboxButtonStyleColorsClass = Style.addClass(new StyleClass('toolbox-button_colors', `\n      fill: ${this.uiStyleSettings.toolbarColor};\n    `));\n\n    this.toolboxActiveButtonStyleColorsClass = Style.addClass(new StyleClass('toolbox-active-button_colors', `\n      background-color: ${this.uiStyleSettings.toolbarBackgroundHoverColor};\n      fill: ${this.uiStyleSettings.toolbarColor};\n    `));\n\n    Style.addRule(\n      new StyleRule(\n        `.${this.toolboxButtonStyleColorsClass.name}:hover`,\n        `\n        background-color: ${this.uiStyleSettings.toolbarBackgroundHoverColor}\n    `\n      )\n    );\n\n    Style.addRule(\n      new StyleRule(\n        `.${this.toolboxButtonStyleClass.name} svg`,\n        `\n      height: ${this.uiStyleSettings.toolbarHeight / 2}px;\n    `\n      )\n    );\n\n  }\n\n  /**\n   * Creates the toolbox object\n   * @param markerjsContainer - container for the toolbox in marker.js UI.\n   * @param displayMode - marker.js display mode (`inline` or `popup`).\n   * @param uiStyleSettings - settings for styling the toolbox elements.\n   */\n  constructor(markerjsContainer: HTMLDivElement, displayMode: DisplayMode, uiStyleSettings: IStyleSettings) {\n    this.markerjsContainer = markerjsContainer;\n    this.displayMode = displayMode;\n    this.uiStyleSettings = uiStyleSettings;\n\n    this.panelButtonClick = this.panelButtonClick.bind(this);\n\n    this.addStyles();\n  }\n\n  /**\n   * Creates and displays the main toolbox UI.\n   */\n  public show(visiblity: string): void {\n    this.uiContainer = document.createElement('div');\n    this.uiContainer.style.visibility = visiblity;\n    this.uiContainer.className = `${this.toolboxStyleClass.name} ${\n      this.uiStyleSettings.toolboxStyleColorsClassName ?? this.toolboxStyleColorsClass.name}`;\n\n    this.markerjsContainer.appendChild(this.uiContainer);\n  }\n\n  /**\n   * Creaes buttons for the top-level toolbox panel.\n   * @param panels - available panels.\n   */\n  public setPanelButtons(panels: ToolboxPanel[]): void {\n    this.panels = panels;\n    if (this.uiContainer !== undefined) {\n      this.uiContainer.innerHTML = '';\n\n      this.panelRow = document.createElement('div');\n      this.panelRow.className = `${this.toolboxPanelRowStyleClass.name} ${\n        this.uiStyleSettings.toolboxPanelRowStyleColorsClassName ?? this.toolboxPanelRowStyleColorsClass.name}`;\n      this.uiContainer.appendChild(this.panelRow);\n      this.buttonRow = document.createElement('div');\n      this.buttonRow.className = `${this.toolboxButtonRowStyleClass.name} ${\n        this.uiStyleSettings.toolboxButtonRowStyleColorsClassName ?? this.toolboxButtonRowStyleColorsClass.name} `;\n      this.uiContainer.appendChild(this.buttonRow);\n\n      this.panelButtons.splice(0);\n\n      this.panels.forEach(panel => {\n        const panelBtnDiv = document.createElement('div');\n        panelBtnDiv.className = `${this.toolboxButtonStyleClass.name} ${\n          this.uiStyleSettings.toolboxButtonStyleColorsClassName ?? this.toolboxButtonStyleColorsClass.name}`;\n        panelBtnDiv.innerHTML = panel.icon;\n        panelBtnDiv.title = panel.title;\n        panelBtnDiv.addEventListener('click', () => {\n          this.panelButtonClick(panel);\n        })\n        this.panelButtons.push(panelBtnDiv);\n        this.buttonRow.appendChild(panelBtnDiv);\n      });\n      if (this.displayMode === 'inline') {\n        this.panelRow.style.display = 'none';\n      } else {\n        this.panelRow.style.visibility = 'hidden';\n      }\n    }\n    // if (this.displayMode === 'popup' && this.panels.length > 0) {\n    //   // this.showPanel(this.activePanel ? this.activePanel : this.panels[0]);\n    //   this.panelButtonClick(this.panels[0]);\n    // }\n  }\n\n  private panelButtonClick(panel: ToolboxPanel) {\n    let panelIndex = -1; \n    if (panel !== this.activePanel) {\n      panelIndex = this.panels.indexOf(panel);\n      this.panelRow.innerHTML = '';\n      const panelUI = panel.getUi();\n      panelUI.style.margin = `${this.uiStyleSettings.toolbarHeight / 4}px`;\n      this.panelRow.appendChild(panelUI);\n      this.panelRow.style.display = 'flex';\n      this.panelRow.style.visibility = 'visible';\n      this.panelRow.className = this.panelRow.className.replace(Style.fadeOutAnimationClassName, '');\n      this.panelRow.className += ` ${Style.fadeInAnimationClassName}`;\n      this.activePanel = panel;\n    } else {\n      this.activePanel = undefined;\n      // hide panel\n      this.panelRow.className = this.panelRow.className.replace(Style.fadeInAnimationClassName, '');\n      this.panelRow.className += ` ${Style.fadeOutAnimationClassName}`;\n      setTimeout(() => {\n        if (this.displayMode === 'inline') {\n          this.panelRow.style.display = 'none';\n        } else {\n          this.panelRow.style.visibility = 'hidden';\n        }\n      }, 200);\n    }\n    this.panelButtons.forEach((pb, index) => {\n      pb.className = `${this.toolboxButtonStyleClass.name} ` +\n        (index === panelIndex\n          ? `${this.uiStyleSettings.toolboxActiveButtonStyleColorsClassName ?? this.toolboxActiveButtonStyleColorsClass.name}`\n          :  `${this.uiStyleSettings.toolboxButtonStyleColorsClassName ?? this.toolboxButtonStyleColorsClass.name}`);\n    });\n  }\n\n}\n","/**\n * Base class for all toolbox property panels.\n */\nexport abstract class ToolboxPanel {\n  /**\n   * Panel name/title.\n   */\n  public title: string;\n  /**\n   * Panel button icon as an SVG markup.\n   */\n  public icon: string;\n  /**\n   * Create panel with supplied title and icon.\n   * @param title - panel name (used for accessibility)\n   * @param icon - panel button icon (SVG image markup)\n   */\n  constructor(title: string, icon?: string) {\n    this.title = title;\n    this.icon = icon;\n  }\n  /**\n   * Returns toolbox panel UI.\n   */\n  public abstract getUi(): HTMLDivElement;\n}\n","import { Style } from '../../core/Style';\nimport { ToolboxPanel } from '../ToolboxPanel';\nimport Icon from './color-picker-panel-icon.svg';\n\n/**\n * Handler type for the color change event.\n */\nexport type ColorChangeHandler = (newColor: string) => void;\n\n/**\n * Color picker panel.\n */\nexport class ColorPickerPanel extends ToolboxPanel {\n  public colors: string[] = [];\n  private currentColor?: string;\n  private addTransparent = false;\n\n  private colorBoxes: HTMLDivElement[] = [];\n\n  /**\n   * Color change event handler.\n   */\n  public onColorChanged?: ColorChangeHandler;\n\n  /**\n   * Creates a color picker panel.\n   * @param title - panel title.\n   * @param colors - available colors.\n   * @param currentColor - currently selected color.\n   * @param icon - panel button icon (SVG imager markup).\n   */\n  constructor(title: string, colors: string[], currentColor?: string, icon?: string) {\n    super(title, icon ? icon : Icon);\n    this.colors = colors;\n    this.currentColor = currentColor;\n\n    this.setCurrentColor = this.setCurrentColor.bind(this);\n    this.getColorBox = this.getColorBox.bind(this);\n  }\n\n  /**\n   * Returns panel UI.\n   */\n  public getUi(): HTMLDivElement {\n    const panelDiv = document.createElement('div');\n    panelDiv.style.overflow = 'hidden';\n    panelDiv.style.whiteSpace = 'nowrap';\n    this.colors.forEach((color) => {\n      const colorBoxContainer = this.getColorBox(color);\n      panelDiv.appendChild(colorBoxContainer);\n      this.colorBoxes.push(colorBoxContainer);\n    });\n    return panelDiv;\n  }\n\n  private getColorBox(color): HTMLDivElement {\n    const buttonPadding = Style.settings.toolbarHeight / 4;\n    const buttonHeight = Style.settings.toolbarHeight - buttonPadding;\n\n    const colorBoxContainer = document.createElement('div');\n    colorBoxContainer.style.display = 'inline-block';\n    colorBoxContainer.style.boxSizing = 'content-box';\n    colorBoxContainer.style.width = `${buttonHeight - 2}px`;\n    colorBoxContainer.style.height = `${buttonHeight - 2}px`;\n    colorBoxContainer.style.padding = '1px';\n    colorBoxContainer.style.marginRight = '2px';\n    colorBoxContainer.style.marginBottom = '2px';\n    colorBoxContainer.style.borderWidth = '2px';\n    colorBoxContainer.style.borderStyle = 'solid';\n    colorBoxContainer.style.borderRadius = `${(buttonHeight + 2)/2}px`\n    colorBoxContainer.style.borderColor =\n      color === this.currentColor ? Style.settings.toolboxAccentColor : 'transparent';\n\n    colorBoxContainer.addEventListener('click', () => {\n      this.setCurrentColor(color, colorBoxContainer);\n    })\n\n    const colorBox = document.createElement('div');\n    colorBox.style.display = 'inline-block';\n    colorBox.style.width = `${buttonHeight - 2}px`;\n    colorBox.style.height = `${buttonHeight - 2}px`;\n    colorBox.style.backgroundColor = color;\n    colorBox.style.borderRadius = `${buttonHeight/2}px`;\n    if (color === 'transparent') {\n      colorBox.style.fill = Style.settings.toolboxAccentColor;\n      colorBox.innerHTML = `<svg viewBox=\"0 0 24 24\">\n        <path d=\"M2,5.27L3.28,4L20,20.72L18.73,22L15.65,18.92C14.5,19.3 13.28,19.5 12,19.5C7,19.5 2.73,16.39 1,12C1.69,10.24 2.79,8.69 4.19,7.46L2,5.27M12,9A3,3 0 0,1 15,12C15,12.35 14.94,12.69 14.83,13L11,9.17C11.31,9.06 11.65,9 12,9M12,4.5C17,4.5 21.27,7.61 23,12C22.18,14.08 20.79,15.88 19,17.19L17.58,15.76C18.94,14.82 20.06,13.54 20.82,12C19.17,8.64 15.76,6.5 12,6.5C10.91,6.5 9.84,6.68 8.84,7L7.3,5.47C8.74,4.85 10.33,4.5 12,4.5M3.18,12C4.83,15.36 8.24,17.5 12,17.5C12.69,17.5 13.37,17.43 14,17.29L11.72,15C10.29,14.85 9.15,13.71 9,12.28L5.6,8.87C4.61,9.72 3.78,10.78 3.18,12Z\" />\n      </svg>`;\n    }\n\n    colorBoxContainer.appendChild(colorBox);\n\n    return colorBoxContainer;\n  }\n\n  private setCurrentColor(color: string, target: HTMLDivElement) {\n    this.currentColor = color;\n\n    this.colorBoxes.forEach(box => {\n      box.style.borderColor = box === target ? Style.settings.toolboxAccentColor : 'transparent';\n    });\n\n    if (this.onColorChanged) {\n      this.onColorChanged(color);\n    }\n  }\n}\n","import { IPoint } from './IPoint';\nimport { ToolboxPanel } from '../ui/ToolboxPanel';\nimport { MarkerBaseState, MarkerState } from './MarkerBaseState';\nimport { Settings } from './Settings';\n\n/**\n * Base class for all available and custom marker types.\n * \n * All markers used with marker.js 2 should be descendants of this class.\n */\nexport class MarkerBase {\n  /**\n   * String type name of the marker type. \n   * \n   * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static typeName = 'MarkerBase';\n\n  /**\n   * Instance property returning marker's type name.\n   * \n   * @since 2.16.0\n   */\n  public get typeName(): string {\n    return Object.getPrototypeOf(this).constructor.typeName;\n  }\n\n  protected _container: SVGGElement;\n  /**\n   * SVG container object holding the marker's visual.\n   */\n  public get container(): SVGGElement {\n    return this._container;\n  }\n  protected _overlayContainer: HTMLDivElement;\n  /**\n   * HTML container that can be used to render overlay objects while the marker is active.\n   * \n   * For example, this is used for the text editing layer while editing text in the {@see TextMarker}.\n   */\n  public get overlayContainer(): HTMLDivElement {\n    return this._overlayContainer;\n  }\n  protected _state: MarkerState = 'new';\n  /**\n   * Current marker state.\n   *\n   * Both MarkerArea and the marker itself can react differently to different events based on what state the marker is in.\n   */\n  public get state(): MarkerState {\n    return this._state;\n  }\n  protected globalSettings: Settings;\n\n  /**\n   * Additional information about the marker\n   */\n  public notes?: string;\n\n  /**\n   * Returns the list of toolbox panels for this marker type.\n   */\n  public get toolboxPanels(): ToolboxPanel[] {\n    return [];\n  }\n\n  /**\n   * Marker type title (display name) used for accessibility and other attributes.\n   */\n  public static title: string;\n\n  /**\n   * SVG icon markup displayed on toolbar buttons.\n   */\n  public static icon: string;\n\n  /**\n   * Method called when marker creation is finished.\n   */\n  public onMarkerCreated: (marker: MarkerBase) => void;\n\n  /**\n   * Method to call when foreground color changes.\n   */\n  public onColorChanged?: (color: string) => void;\n  /**\n   * Method to call when background/fill color changes.\n   */\n  public onFillColorChanged?: (color: string) => void;\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.\n   * @param settings - settings object containing default markers settings.\n   */\n  constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings) {\n    this._container = container;\n    this._overlayContainer = overlayContainer;\n    this.globalSettings = settings;\n  }\n\n  /**\n   * Returns true if passed SVG element belongs to the marker. False otherwise.\n   * \n   * @param el - target element.\n   */\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars\n  public ownsTarget(el: EventTarget): boolean {\n    return false;\n  }\n\n  /**\n   * Is this marker selected?\n   * \n   * @since 2.16.0\n   */\n  protected _isSelected = false;\n\n  /**\n   * Returns true if the marker is currently selected\n   * \n   * @since 2.16.0\n   */\n  public get isSelected(): boolean {\n    return this._isSelected;\n  }\n\n  /**\n   * Selects this marker and displays appropriate selected marker UI.\n   */\n  public select(): void {\n    this.container.style.cursor = 'move';\n    this._isSelected = true;\n  }\n\n  /**\n   * Deselects this marker and hides selected marker UI.\n   */\n  public deselect(): void {\n    this.container.style.cursor = 'default';\n    this._isSelected = false;\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) down event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function\n  public pointerDown(point: IPoint, target?: EventTarget):void {}\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) double click event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function\n  public dblClick(point: IPoint, target?: EventTarget):void {}\n\n  /**\n   * Handles marker manipulation (move, resize, rotate, etc.).\n   * \n   * @param point - event coordinates.\n   */\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function\n  public manipulate(point: IPoint):void {}\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) up event.\n   * \n   * @param point - event coordinates.\n   */\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function\n  public pointerUp(point: IPoint):void {}\n\n  /**\n   * Disposes the marker and clean's up.\n   */\n  // eslint-disable-next-line @typescript-eslint/no-empty-function\n  public dispose(): void {}\n\n  protected addMarkerVisualToContainer(element: SVGElement): void {\n    if (this.container.childNodes.length > 0) {\n      this.container.insertBefore(element, this.container.childNodes[0]);\n    } else {\n      this.container.appendChild(element);\n    }\n  }\n\n  /**\n   * Returns current marker state that can be restored in the future.\n   */\n  public getState(): MarkerBaseState {\n    return { \n      typeName: MarkerBase.typeName, \n      state: this.state,\n      notes: this.notes\n    };\n  }\n\n  /**\n   * Restores previously saved marker state.\n   * \n   * @param state - previously saved state.\n   */\n  public restoreState(state: MarkerBaseState): void {\n    this._state = state.state;\n    this.notes = state.notes;\n  }\n\n  /**\n   * Scales marker. Used after the image resize.\n   * \n   * @param scaleX - horizontal scale\n   * @param scaleY - vertical scale\n   */\n  // eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars\n  public scale(scaleX: number, scaleY: number): void {}\n\n  /**\n   * Called by a marker when its foreground color changes.\n   * @param color \n   */\n  protected colorChanged(color: string): void {\n    if (this.onColorChanged) {\n      this.onColorChanged(color);\n    }\n  }\n  /**\n   * Called by a marker when its background/fill color changes.\n   * @param color \n   */\n  protected fillColorChanged(color: string): void {\n    if (this.onFillColorChanged) {\n      this.onFillColorChanged(color);\n    }\n  }\n}\n","import { ResizeGrip } from './ResizeGrip';\n\n/**\n * RectangularBoxMarkerGrips is a set of resize/rotation grips for a rectangular marker.\n */\nexport class RectangularBoxMarkerGrips {\n  /**\n   * Top-left grip.\n   */\n  public topLeft: ResizeGrip;\n  /**\n   * Top-center grip.\n   */\n  public topCenter: ResizeGrip;\n  /**\n   * Top-right grip.\n   */\n  public topRight: ResizeGrip;\n  /**\n   * Center-left grip.\n   */\n  public centerLeft: ResizeGrip;\n  /**\n   * Center-right grip.\n   */\n  public centerRight: ResizeGrip;\n  /**\n   * Bottom-left grip.\n   */\n  public bottomLeft: ResizeGrip;\n  /**\n   * Bottom-center grip.\n   */\n  public bottomCenter: ResizeGrip;\n  /**\n   * Bottom-right grip.\n   */\n  public bottomRight: ResizeGrip;\n\n  /**\n   * Creates a new marker grip set.\n   */\n  constructor() {\n    this.findGripByVisual = this.findGripByVisual.bind(this);\n  }\n\n  /**\n   * Returns a marker grip owning the specified visual.\n   * @param gripVisual - visual for owner to be determined.\n   */\n  public findGripByVisual(\n    gripVisual: EventTarget\n  ): ResizeGrip | undefined {\n      if (this.topLeft.ownsTarget(gripVisual)) {\n        return this.topLeft;\n      } else if (this.topCenter.ownsTarget(gripVisual)) {\n        return this.topCenter;\n      } else if (this.topRight.ownsTarget(gripVisual)) {\n        return this.topRight;\n      } else if (this.centerLeft.ownsTarget(gripVisual)) {\n        return this.centerLeft;\n      } else if (this.centerRight.ownsTarget(gripVisual)) {\n        return this.centerRight;\n      } else if (this.bottomLeft.ownsTarget(gripVisual)) {\n        return this.bottomLeft;\n      } else if (this.bottomCenter.ownsTarget(gripVisual)) {\n        return this.bottomCenter;\n      } else if (this.bottomRight.ownsTarget(gripVisual)) {\n        return this.bottomRight;\n      } else {\n        return undefined;\n      }\n  }\n}\n","import { SvgHelper } from '../core/SvgHelper';\n\n/**\n * Represents a single resize-manipulation grip used in marker's manipulation controls.\n */\nexport class ResizeGrip {\n  /**\n   * Grip's visual element.\n   */\n  public visual: SVGGraphicsElement;\n\n  /**\n   * Grip's size (raduis).\n   */\n  public readonly GRIP_SIZE = 10;\n\n  /**\n   * Creates a new grip.\n   */\n  constructor() {\n    this.visual = SvgHelper.createGroup();\n    this.visual.appendChild(\n      SvgHelper.createCircle(this.GRIP_SIZE * 1.5, [['fill', 'transparent']])\n    );\n    this.visual.appendChild(\n      SvgHelper.createCircle(this.GRIP_SIZE, [\n        ['fill', '#cccccc'],\n        ['fill-opacity', '0.7'],\n        ['stroke', '#333333'],\n        ['stroke-width', '2'],\n        ['stroke-opacity', '0.7']\n      ])\n    );\n  }\n\n  /**\n   * Returns true if passed SVG element belongs to the grip. False otherwise.\n   * \n   * @param el - target element.\n   */\n  public ownsTarget(el: EventTarget): boolean {\n    if (\n      el === this.visual ||\n      el === this.visual.childNodes[0] ||\n      el === this.visual.childNodes[1]\n    ) {\n      return true;\n    } else {\n      return false;\n    }\n  }\n}\n","/**\n * Represents a simplified version of the SVGMatrix.\n */\nexport interface ITransformMatrix {\n  a: number;\n  b: number;\n  c: number;\n  d: number;\n  e: number;\n  f: number;\n}\n\n/**\n * A utility class to transform between SVGMatrix and its simplified representation.\n */\nexport class TransformMatrix {\n  public static toITransformMatrix(matrix: SVGMatrix): ITransformMatrix {\n    return {\n      a: matrix.a,\n      b: matrix.b,\n      c: matrix.c,\n      d: matrix.d,\n      e: matrix.e,\n      f: matrix.f\n    }\n  }\n  public static toSVGMatrix(currentMatrix: SVGMatrix, newMatrix: ITransformMatrix): SVGMatrix {\n    currentMatrix.a = newMatrix.a;\n    currentMatrix.b = newMatrix.b;\n    currentMatrix.c = newMatrix.c;\n    currentMatrix.d = newMatrix.d;\n    currentMatrix.e = newMatrix.e;\n    currentMatrix.f = newMatrix.f;\n    return currentMatrix;\n  }\n}","import { MarkerBase } from '../core/MarkerBase';\n\nimport { IPoint } from '../core/IPoint';\nimport { SvgHelper } from '../core/SvgHelper';\n\nimport { RectangularBoxMarkerGrips } from './RectangularBoxMarkerGrips';\nimport { ResizeGrip } from './ResizeGrip';\nimport { Settings } from '../core/Settings';\nimport { RectangularBoxMarkerBaseState } from './RectangularBoxMarkerBaseState';\nimport { MarkerBaseState } from '../core/MarkerBaseState';\nimport { TransformMatrix } from '../core/TransformMatrix';\n\n/**\n * RectangularBoxMarkerBase is a base class for all marker's with rectangular controls such as all rectangle markers,\n * text and callout markers.\n * \n * It creates and manages the rectangular control box and related resize, move, and rotate manipulations.\n */\nexport class RectangularBoxMarkerBase extends MarkerBase {\n  /**\n   * x coordinate of the top-left corner.\n   */\n  protected left = 0;\n  /**\n   * y coordinate of the top-left corner.\n   */\n  protected top = 0;\n  /**\n   * Marker width.\n   */\n  protected width = 0;\n  /**\n   * Marker height.\n   */\n  protected height = 0;\n\n  /**\n   * The default marker size when the marker is created with a click (without dragging).\n   */\n  protected defaultSize: IPoint = {x: 50, y: 20};\n\n  /**\n   * x coordinate of the top-left corner at the start of manipulation.\n   */\n  protected manipulationStartLeft: number;\n  /**\n   * y coordinate of the top-left corner at the start of manipulation.\n   */\n  protected manipulationStartTop: number;\n  /**\n   * Width at the start of manipulation.\n   */\n  protected manipulationStartWidth: number;\n  /**\n   * Height at the start of manipulation.\n   */\n  protected manipulationStartHeight: number;\n\n  /**\n   * x coordinate of the pointer at the start of manipulation.\n   */\n  protected manipulationStartX: number;\n  /**\n   * y coordinate of the pointer at the start of manipulation.\n   */\n  protected manipulationStartY: number;\n\n  /**\n   * Pointer's horizontal distance from the top left corner.\n   */\n  protected offsetX = 0;\n  /**\n   * Pointer's vertical distance from the top left corner.\n   */\n  protected offsetY = 0;\n\n  /**\n   * Marker's rotation angle.\n   */\n  protected rotationAngle = 0;\n\n  /**\n   * x coordinate of the marker's center.\n   */\n  protected get centerX(): number {\n    return this.left + this.width / 2;\n  }\n  /**\n   * y coordinate of the marker's center.\n   */\n  protected get centerY(): number {\n    return this.top + this.height / 2;\n  }\n\n  private _visual: SVGGraphicsElement;\n  /**\n   * Container for the marker's visual.\n   */\n  protected get visual(): SVGGraphicsElement {\n    return this._visual;\n  }\n  protected set visual(value: SVGGraphicsElement) {\n    this._visual = value;\n    const translate = SvgHelper.createTransform();\n    this._visual.transform.baseVal.appendItem(translate);\n  }\n\n  /**\n   * Container for the marker's editing controls.\n   */\n  protected controlBox: SVGGElement;\n  private readonly CB_DISTANCE: number = 10;\n  private controlRect: SVGRectElement;\n  private rotatorGripLine: SVGLineElement;\n\n  private controlGrips: RectangularBoxMarkerGrips;\n  private rotatorGrip: ResizeGrip;\n  private activeGrip: ResizeGrip;\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.\n   * @param settings - settings object containing default markers settings.\n   */\n  constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings) {\n    super(container, overlayContainer, settings);\n\n    // add rotation transform\n    this.container.transform.baseVal.appendItem(SvgHelper.createTransform());\n\n    this.setupControlBox();\n  }\n\n  /**\n   * Returns true if passed SVG element belongs to the marker. False otherwise.\n   * \n   * @param el - target element.\n   */\n  public ownsTarget(el: EventTarget): boolean {\n    if (super.ownsTarget(el)) {\n      return true;\n    } else if (\n      this.controlGrips.findGripByVisual(el) !== undefined ||\n      this.rotatorGrip.ownsTarget(el)\n    ) {\n      return true;\n    } else {\n      return false;\n    }\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) down event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerDown(point: IPoint, target?: EventTarget): void {\n    super.pointerDown(point, target);\n\n    if (this.state === 'new') {\n      this.left = point.x;\n      this.top = point.y;\n    }\n\n    this.manipulationStartLeft = this.left;\n    this.manipulationStartTop = this.top;\n    this.manipulationStartWidth = this.width;\n    this.manipulationStartHeight = this.height;\n\n    const rotatedPoint = this.unrotatePoint(point);\n    this.manipulationStartX = rotatedPoint.x;\n    this.manipulationStartY = rotatedPoint.y;\n\n    this.offsetX = rotatedPoint.x - this.left;\n    this.offsetY = rotatedPoint.y - this.top;\n\n    if (this.state !== 'new') {\n      this.select();\n      this.activeGrip = this.controlGrips.findGripByVisual(target as SVGGraphicsElement);\n      if (this.activeGrip !== undefined) {\n        this._state = 'resize';\n      } else if (this.rotatorGrip.ownsTarget(target)) {\n        this.activeGrip = this.rotatorGrip;\n\n        const rotatedCenter = this.rotatePoint({x: this.centerX, y: this.centerY});\n        this.left = rotatedCenter.x - this.width / 2;\n        this.top = rotatedCenter.y - this.height / 2;\n        this.moveVisual({ x: this.left, y: this.top });\n\n        const rotate = this.container.transform.baseVal.getItem(0);\n        rotate.setRotate(this.rotationAngle, this.centerX, this.centerY);\n        this.container.transform.baseVal.replaceItem(rotate, 0);\n\n        this.adjustControlBox();\n\n        this._state = 'rotate';\n      } else {\n        this._state = 'move';\n      }\n    }\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) up event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerUp(point: IPoint): void {\n    const inState = this.state;\n    super.pointerUp(point);\n    if (this.state === 'creating' && this.width < 10 && this.height < 10) {\n      this.width = this.defaultSize.x;\n      this.height = this.defaultSize.y;\n    } else {\n      this.manipulate(point);\n    }\n    this._state = 'select';\n    if (inState === 'creating' && this.onMarkerCreated) {\n      this.onMarkerCreated(this);\n    }\n  }\n\n  /**\n   * Moves visual to the specified coordinates.\n   * @param point - coordinates of the new top-left corner of the visual.\n   */\n  protected moveVisual(point: IPoint): void {\n    this.visual.style.transform = `translate(${point.x}px, ${point.y}px)`;\n    // const translate = this.visual.transform.baseVal.getItem(0);\n    // translate.setTranslate(point.x, point.y);\n    // this.visual.transform.baseVal.replaceItem(translate, 0);\n  }\n\n  /**\n   * Handles marker manipulation (move, resize, rotate, etc.).\n   * \n   * @param point - event coordinates.\n   */\n  public manipulate(point: IPoint): void {\n    const rotatedPoint = this.unrotatePoint(point);\n\n    if (this.state === 'creating') {\n      this.resize(point);\n    } else if (this.state === 'move') {\n      this.left =\n        this.manipulationStartLeft +\n        (rotatedPoint.x - this.manipulationStartLeft) -\n        this.offsetX;\n      this.top =\n        this.manipulationStartTop +\n        (rotatedPoint.y - this.manipulationStartTop) -\n        this.offsetY;\n      this.moveVisual({x: this.left, y: this.top});\n      this.adjustControlBox();\n    } else if (this.state === 'resize') {\n      this.resize(rotatedPoint);\n    } else if (this.state === 'rotate') {\n      this.rotate(point);\n    }\n  }\n\n  /**\n   * Resizes the marker based on pointer coordinates and context.\n   * @param point - pointer coordinates.\n   */\n  protected resize(point: IPoint): void {\n    let newX = this.manipulationStartLeft;\n    let newWidth = this.manipulationStartWidth;\n    let newY = this.manipulationStartTop;\n    let newHeight = this.manipulationStartHeight;\n\n    switch(this.activeGrip) {\n      case this.controlGrips.bottomLeft:\n      case this.controlGrips.centerLeft:\n      case this.controlGrips.topLeft:\n        newX = this.manipulationStartLeft + point.x - this.manipulationStartX;\n        newWidth = this.manipulationStartWidth + this.manipulationStartLeft - newX;\n        break; \n      case this.controlGrips.bottomRight:\n      case this.controlGrips.centerRight:\n      case this.controlGrips.topRight:\n      case undefined:\n        newWidth = this.manipulationStartWidth + point.x - this.manipulationStartX;\n        break; \n    }\n\n    switch(this.activeGrip) {\n      case this.controlGrips.topCenter:\n      case this.controlGrips.topLeft:\n      case this.controlGrips.topRight:\n        newY = this.manipulationStartTop + point.y - this.manipulationStartY;\n        newHeight = this.manipulationStartHeight + this.manipulationStartTop - newY;\n        break; \n      case this.controlGrips.bottomCenter:\n      case this.controlGrips.bottomLeft:\n      case this.controlGrips.bottomRight:\n      case undefined:\n        newHeight = this.manipulationStartHeight + point.y - this.manipulationStartY;\n        break; \n    }\n\n    if (newWidth >= 0) {\n      this.left = newX;\n      this.width = newWidth;\n    } else {\n      this.left = newX + newWidth;\n      this.width = -newWidth;\n    }\n    if (newHeight >= 0) {\n      this.top = newY;\n      this.height = newHeight;\n    } else {\n      this.top = newY + newHeight;\n      this.height = -newHeight;\n    }\n\n    this.setSize();\n  }\n\n  /**\n   * Sets control box size and location.\n   */\n  protected setSize(): void {\n    this.moveVisual({x: this.left, y: this.top});\n    this.adjustControlBox();\n  }\n\n  private rotate(point: IPoint) {\n    // avoid glitch when crossing the 0 rotation point\n    if (Math.abs(point.x - this.centerX) > 0.1) {\n      const sign = Math.sign(point.x - this.centerX);\n      this.rotationAngle =\n        (Math.atan((point.y - this.centerY) / (point.x - this.centerX)) * 180) /\n          Math.PI +\n        90 * sign;\n      this.applyRotation();\n    }\n  }\n\n  private applyRotation() {\n    const rotate = this.container.transform.baseVal.getItem(0);\n    rotate.setRotate(this.rotationAngle, this.centerX, this.centerY);\n    this.container.transform.baseVal.replaceItem(rotate, 0);\n  }\n\n  /**\n   * Returns point coordinates based on the actual screen coordinates and marker's rotation.\n   * @param point - original pointer coordinates\n   */\n  protected rotatePoint(point: IPoint): IPoint {\n    if (this.rotationAngle === 0) {\n      return point;\n    }\n    \n    const matrix = this.container.getCTM();\n    let svgPoint = SvgHelper.createPoint(point.x, point.y);\n    svgPoint = svgPoint.matrixTransform(matrix);\n\n    const result = { x: svgPoint.x, y: svgPoint.y };\n\n    return result;\n  }\n\n  /**\n   * Returns original point coordinates based on coordinates with rotation applied.\n   * @param point - rotated point coordinates.\n   */\n  protected unrotatePoint(point: IPoint): IPoint {\n    if (this.rotationAngle === 0) {\n      return point;\n    }\n    \n    let matrix = this.container.getCTM();\n    matrix = matrix.inverse();\n    let svgPoint = SvgHelper.createPoint(point.x, point.y);\n    svgPoint = svgPoint.matrixTransform(matrix);\n\n    const result = { x: svgPoint.x, y: svgPoint.y };\n\n    return result;\n  }\n\n  /**\n   * Displays marker's controls.\n   */\n  public select(): void {\n    super.select();\n    this.adjustControlBox();\n    this.controlBox.style.display = '';\n  }\n\n  /**\n   * Hides marker's controls.\n   */\n  public deselect(): void {\n    super.deselect();\n    this.controlBox.style.display = 'none';\n  }\n\n  private setupControlBox() {\n    this.controlBox = SvgHelper.createGroup();\n    const translate = SvgHelper.createTransform();\n    translate.setTranslate(-this.CB_DISTANCE / 2, -this.CB_DISTANCE / 2);\n    this.controlBox.transform.baseVal.appendItem(translate);\n\n    this.container.appendChild(this.controlBox);\n\n    this.controlRect = SvgHelper.createRect(\n      this.width + this.CB_DISTANCE,\n      this.height + this.CB_DISTANCE,\n      [\n        ['stroke', 'black'],\n        ['stroke-width', '1'],\n        ['stroke-opacity', '0.5'],\n        ['stroke-dasharray', '3, 2'],\n        ['fill', 'transparent'],\n        ['pointer-events', 'none']\n      ]\n    );\n\n    this.controlBox.appendChild(this.controlRect);\n\n    this.rotatorGripLine = SvgHelper.createLine(\n      (this.width + this.CB_DISTANCE * 2) / 2,\n      this.top - this.CB_DISTANCE,\n      (this.width + this.CB_DISTANCE * 2) / 2,\n      this.top - this.CB_DISTANCE * 3,\n      [\n        ['stroke', 'black'],\n        ['stroke-width', '1'],\n        ['stroke-opacity', '0.5'],\n        ['stroke-dasharray', '3, 2'],\n      ]\n    );\n\n    this.controlBox.appendChild(this.rotatorGripLine);\n\n    this.controlGrips = new RectangularBoxMarkerGrips();\n    this.addControlGrips();\n\n    this.controlBox.style.display = 'none';\n  }\n\n  private adjustControlBox() {\n    const translate = this.controlBox.transform.baseVal.getItem(0);\n    translate.setTranslate(\n      this.left - this.CB_DISTANCE / 2,\n      this.top - this.CB_DISTANCE / 2\n    );\n    this.controlBox.transform.baseVal.replaceItem(translate, 0);\n    this.controlRect.setAttribute(\n      'width',\n      (this.width + this.CB_DISTANCE).toString()\n    );\n    this.controlRect.setAttribute(\n      'height',\n      (this.height + this.CB_DISTANCE).toString()\n    );\n    this.rotatorGripLine.setAttribute(\n      'x1',\n      ((this.width + this.CB_DISTANCE) / 2).toString()\n    );\n    this.rotatorGripLine.setAttribute('y1', (-this.CB_DISTANCE / 2).toString());\n    this.rotatorGripLine.setAttribute(\n      'x2',\n      ((this.width + this.CB_DISTANCE) / 2).toString()\n    );\n    this.rotatorGripLine.setAttribute('y2', (-this.CB_DISTANCE * 3).toString());\n    this.positionGrips();\n  }\n\n  private addControlGrips() {\n    this.controlGrips.topLeft = this.createGrip();\n    this.controlGrips.topCenter = this.createGrip();\n    this.controlGrips.topRight = this.createGrip();\n    this.controlGrips.centerLeft = this.createGrip();\n    this.controlGrips.centerRight = this.createGrip();\n    this.controlGrips.bottomLeft = this.createGrip();\n    this.controlGrips.bottomCenter = this.createGrip();\n    this.controlGrips.bottomRight = this.createGrip();\n\n    this.rotatorGrip = this.createGrip();\n\n    this.positionGrips();\n  }\n\n  private createGrip(): ResizeGrip {\n    const grip = new ResizeGrip();\n    grip.visual.transform.baseVal.appendItem(SvgHelper.createTransform());\n    this.controlBox.appendChild(grip.visual);\n\n    return grip;\n  }\n\n  private positionGrips() {\n    const gripSize = this.controlGrips.topLeft.GRIP_SIZE;\n\n    const left = -gripSize / 2;\n    const top = left;\n    const cx = (this.width + this.CB_DISTANCE) / 2 - gripSize / 2;\n    const cy = (this.height + this.CB_DISTANCE) / 2 - gripSize / 2;\n    const bottom = this.height + this.CB_DISTANCE - gripSize / 2;\n    const right = this.width + this.CB_DISTANCE - gripSize / 2;\n\n    this.positionGrip(this.controlGrips.topLeft.visual, left, top);\n    this.positionGrip(this.controlGrips.topCenter.visual, cx, top);\n    this.positionGrip(this.controlGrips.topRight.visual, right, top);\n    this.positionGrip(this.controlGrips.centerLeft.visual, left, cy);\n    this.positionGrip(this.controlGrips.centerRight.visual, right, cy);\n    this.positionGrip(this.controlGrips.bottomLeft.visual, left, bottom);\n    this.positionGrip(this.controlGrips.bottomCenter.visual, cx, bottom);\n    this.positionGrip(this.controlGrips.bottomRight.visual, right, bottom);\n\n    this.positionGrip(this.rotatorGrip.visual, cx, top - this.CB_DISTANCE * 3);\n  }\n\n  private positionGrip(grip: SVGGraphicsElement, x: number, y: number) {\n    const translate = grip.transform.baseVal.getItem(0);\n    translate.setTranslate(x, y);\n    grip.transform.baseVal.replaceItem(translate, 0);\n  }\n\n  /**\n   * Hides marker's editing controls.\n   */\n  protected hideControlBox(): void {\n    this.controlBox.style.display = 'none';\n  }\n  /**\n   * Shows marker's editing controls.\n   */\n  protected showControlBox(): void {\n    this.controlBox.style.display = '';\n  }\n\n  /**\n   * Returns marker's state.\n   */\n  public getState(): RectangularBoxMarkerBaseState {\n    const result: RectangularBoxMarkerBaseState = Object.assign({\n      left: this.left,\n      top: this.top,\n      width: this.width,\n      height: this.height,\n      rotationAngle: this.rotationAngle,\n      visualTransformMatrix: TransformMatrix.toITransformMatrix(this.visual.transform.baseVal.getItem(0).matrix),\n      containerTransformMatrix: TransformMatrix.toITransformMatrix(this.container.transform.baseVal.getItem(0).matrix)\n    },\n    super.getState());\n\n    return result;\n  }\n\n  /**\n   * Restores marker's state to the previously saved one.\n   * @param state - previously saved state.\n   */\n  public restoreState(state: MarkerBaseState): void {\n    super.restoreState(state);\n    const rbmState = state as RectangularBoxMarkerBaseState;\n    this.left = rbmState.left;\n    this.top = rbmState.top;\n    this.width = rbmState.width;\n    this.height = rbmState.height;\n    this.rotationAngle = rbmState.rotationAngle;\n    this.visual.transform.baseVal.getItem(0).setMatrix(\n      TransformMatrix.toSVGMatrix(this.visual.transform.baseVal.getItem(0).matrix, rbmState.visualTransformMatrix)\n    );\n    this.container.transform.baseVal.getItem(0).setMatrix(\n      TransformMatrix.toSVGMatrix(this.container.transform.baseVal.getItem(0).matrix, rbmState.containerTransformMatrix)\n    );\n    // this.moveVisual({x: this.left, y: this.top});\n    // this.applyRotation();\n  }\n\n  /**\n   * Scales marker. Used after the image resize.\n   * \n   * @param scaleX - horizontal scale\n   * @param scaleY - vertical scale\n   */\n  public scale(scaleX: number, scaleY: number): void {\n    super.scale(scaleX, scaleY);\n\n    const rPoint = this.rotatePoint({x: this.left, y: this.top});\n    const point = this.unrotatePoint({x: rPoint.x * scaleX, y: rPoint.y * scaleY});\n\n    this.left = point.x;\n    this.top = point.y;\n    this.width = this.width * scaleX;\n    this.height = this.height * scaleY;\n\n    this.adjustControlBox();\n  }\n\n}\n","import { IPoint } from '../core/IPoint';\nimport { SvgHelper } from '../core/SvgHelper';\nimport { RectangularBoxMarkerBase } from './RectangularBoxMarkerBase';\nimport { Settings } from '../core/Settings';\nimport { RectangleMarkerState } from './RectangleMarkerState';\nimport { MarkerBaseState } from '../core/MarkerBaseState';\n\n/**\n * RecatngleMarker is a base class for all rectangular markers (Frame, Cover, Highlight, etc.)\n */\nexport abstract class RectangleMarker extends RectangularBoxMarkerBase {\n  /**\n   * String type name of the marker type. \n   * \n   * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static title = 'Rectangle marker';\n\n  /**\n   * Recangle fill color.\n   */\n  protected fillColor = 'transparent';\n  /**\n   * Rectangle stroke color.\n   */\n  protected strokeColor = 'transparent';\n  /**\n   * Rectangle border stroke width.\n   */\n  protected strokeWidth = 0;\n  /**\n   * Rectangle border stroke dash array.\n   */\n  protected strokeDasharray = '';\n  /**\n   * Rectangle opacity (alpha). 0 to 1.\n   */\n  protected opacity = 1;\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.\n   * @param settings - settings object containing default markers settings.\n   */\n  constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings) {\n    super(container, overlayContainer, settings);\n\n    this.setStrokeColor = this.setStrokeColor.bind(this);\n    this.setFillColor = this.setFillColor.bind(this);\n    this.setStrokeWidth = this.setStrokeWidth.bind(this);\n    this.setStrokeDasharray = this.setStrokeDasharray.bind(this);\n    this.createVisual = this.createVisual.bind(this);\n  }\n\n  /**\n   * Returns true if passed SVG element belongs to the marker. False otherwise.\n   * \n   * @param el - target element.\n   */\n  public ownsTarget(el: EventTarget): boolean {\n    if (super.ownsTarget(el) || el === this.visual) {\n      return true;\n    } else {\n      return false;\n    }\n  }\n\n  /**\n   * Creates the marker's rectangle visual.\n   */\n  protected createVisual(): void {\n    this.visual = SvgHelper.createRect(1, 1, [\n      ['fill', this.fillColor],\n      ['stroke', this.strokeColor],\n      ['stroke-width', this.strokeWidth.toString()],\n      ['stroke-dasharray', this.strokeDasharray],\n      ['opacity', this.opacity.toString()]\n    ]);\n    this.addMarkerVisualToContainer(this.visual);\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) down event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerDown(point: IPoint, target?: EventTarget): void {\n    super.pointerDown(point, target);\n    if (this.state === 'new') {\n      this.createVisual();\n\n      this.moveVisual(point);\n\n      this._state = 'creating';\n    }\n  }\n\n  /**\n   * Handles marker manipulation (move, resize, rotate, etc.).\n   * \n   * @param point - event coordinates.\n   */\n  public manipulate(point: IPoint): void {\n    super.manipulate(point);\n  }\n\n  /**\n   * Resizes the marker based on the pointer coordinates.\n   * @param point - current pointer coordinates.\n   */\n  protected resize(point: IPoint): void {\n    super.resize(point);\n    this.setSize();\n  }\n\n  /**\n   * Sets visual's width and height attributes based on marker's width and height.\n   */\n  protected setSize(): void {\n    super.setSize();\n    SvgHelper.setAttributes(this.visual, [\n      ['width', this.width.toString()],\n      ['height', this.height.toString()],\n    ]);\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) up event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerUp(point: IPoint): void {\n    super.pointerUp(point);\n    this.setSize();\n  }\n\n  /**\n   * Sets rectangle's border stroke color.\n   * @param color - color as string\n   */\n  protected setStrokeColor(color: string): void {\n    this.strokeColor = color;\n    if (this.visual) {\n      SvgHelper.setAttributes(this.visual, [['stroke', this.strokeColor]]);\n    }\n    this.colorChanged(color);\n  }\n  /**\n   * Sets rectangle's fill color.\n   * @param color - color as string\n   */\n  protected setFillColor(color: string): void {\n    this.fillColor = color;\n    if (this.visual) {\n      SvgHelper.setAttributes(this.visual, [['fill', this.fillColor]]);\n    }\n  }\n  /**\n   * Sets rectangle's border stroke (line) width.\n   * @param color - color as string\n   */\n  protected setStrokeWidth(width: number): void {\n    this.strokeWidth = width;\n    if (this.visual) {\n      SvgHelper.setAttributes(this.visual, [['stroke-width', this.strokeWidth.toString()]]);\n    }\n  }\n  /**\n   * Sets rectangle's border stroke dash array.\n   * @param color - color as string\n   */\n  protected setStrokeDasharray(dashes: string): void {\n    this.strokeDasharray = dashes;\n    if (this.visual) {\n      SvgHelper.setAttributes(this.visual, [['stroke-dasharray', this.strokeDasharray]]);\n    }\n  }\n\n  /**\n   * Returns current marker state that can be restored in the future.\n   */\n  public getState(): RectangleMarkerState {\n    const result: RectangleMarkerState = Object.assign({\n      fillColor: this.fillColor,\n      strokeColor: this.strokeColor,\n      strokeWidth: this.strokeWidth,\n      strokeDasharray: this.strokeDasharray,\n      opacity: this.opacity\n    }, super.getState());\n\n    return result;\n  }\n\n  /**\n   * Restores previously saved marker state.\n   * \n   * @param state - previously saved state.\n   */\n  public restoreState(state: MarkerBaseState): void {\n    const rectState = state as RectangleMarkerState;\n    this.fillColor = rectState.fillColor;\n    this.strokeColor = rectState.strokeColor;\n    this.strokeWidth = rectState.strokeWidth;\n    this.strokeDasharray = rectState.strokeDasharray;\n    this.opacity = rectState.opacity;\n\n    this.createVisual();\n    super.restoreState(state);\n    this.setSize();\n  }\n\n  /**\n   * Scales marker. Used after the image resize.\n   * \n   * @param scaleX - horizontal scale\n   * @param scaleY - vertical scale\n   */\n  public scale(scaleX: number, scaleY: number): void {\n    super.scale(scaleX, scaleY);\n\n    this.setSize();\n  }\n\n}\n","import { Style } from '../../core/Style';\nimport { ToolboxPanel } from '../ToolboxPanel';\nimport Icon from './line-width-panel-icon.svg';\n\n/**\n * Line width change event handler type.\n */\nexport type WidthChangeHandler = (newWidth: number) => void;\n\n/**\n * Line width toolbox panel.\n */\nexport class LineWidthPanel extends ToolboxPanel {\n  private widths: number[] = [];\n  private currentWidth?: number;\n\n  private widthBoxes: HTMLDivElement[] = [];\n\n  /**\n   * Line width change event handler.\n   */\n  public onWidthChanged?: WidthChangeHandler;\n\n  /**\n   * Creates a line width toolbox panel.\n   * @param title - panel title.\n   * @param widths - available widths.\n   * @param currentWidth - currently set width.\n   * @param icon - toolbox panel icon (SVG image markup).\n   */\n  constructor(title: string, widths: number[], currentWidth?: number, icon?: string) {\n    super(title, icon ? icon : Icon);\n    this.widths = widths;\n    this.currentWidth = currentWidth;\n\n    this.setCurrentWidth = this.setCurrentWidth.bind(this);\n  }\n\n  /**\n   * Returns panel UI.\n   */\n  public getUi(): HTMLDivElement {\n    const panelDiv = document.createElement('div');\n    panelDiv.style.display = 'flex';\n    panelDiv.style.overflow = 'hidden';\n    panelDiv.style.flexGrow = '2';\n    this.widths.forEach((lineWidth) => {\n      const widthBoxContainer = document.createElement('div');\n      widthBoxContainer.style.display = 'flex';\n      widthBoxContainer.style.flexGrow = '2';\n      widthBoxContainer.style.alignItems = 'center';\n      widthBoxContainer.style.justifyContent = 'space-between';\n      widthBoxContainer.style.padding = '5px';\n      widthBoxContainer.style.borderWidth = '2px';\n      widthBoxContainer.style.borderStyle = 'solid';\n      widthBoxContainer.style.borderColor =\n        lineWidth === this.currentWidth ? Style.settings.toolboxAccentColor : 'transparent';\n\n      widthBoxContainer.addEventListener('click', () => {\n        this.setCurrentWidth(lineWidth, widthBoxContainer);\n      })\n      panelDiv.appendChild(widthBoxContainer);\n\n      const label = document.createElement('div');\n      label.innerText = lineWidth.toString();\n      label.style.marginRight = '5px';\n      widthBoxContainer.appendChild(label);\n\n      const widthBox = document.createElement('div');\n      widthBox.style.minHeight = '20px';\n      widthBox.style.flexGrow = '2';\n      widthBox.style.display = 'flex';\n      widthBox.style.alignItems = 'center';\n\n      const hr = document.createElement('hr');\n      hr.style.minWidth = '20px';\n      hr.style.border = '0px';\n      hr.style.borderTop = `${lineWidth}px solid ${Style.settings.toolboxColor}`;\n      hr.style.flexGrow = '2';\n      widthBox.appendChild(hr);\n\n      // widthBox.innerHTML = `<svg viewBox=\"0 0 140 20\" width=\"140\" height=\"20\" xmlns=\"http://www.w3.org/2000/svg\">\n      //   <line x1=\"0\" y1=\"10\" x2=\"140\" y2=\"10\" stroke=\"${Style.settings.toolboxColor}\" stroke-width=\"${lineWidth}\" />\n      // </svg>`;\n\n      widthBoxContainer.appendChild(widthBox);\n\n      this.widthBoxes.push(widthBoxContainer);\n    });\n    return panelDiv;\n  }\n\n  private setCurrentWidth(newWidth: number, target: HTMLDivElement) {\n    this.currentWidth = newWidth;\n\n    this.widthBoxes.forEach(box => {\n      box.style.borderColor = box === target ? Style.settings.toolboxAccentColor : 'transparent';\n    });\n\n    if (this.onWidthChanged) {\n      this.onWidthChanged(this.currentWidth);\n    }\n  }\n}\n","import { Style } from '../../core/Style';\nimport { ToolboxPanel } from '../ToolboxPanel';\nimport Icon from './line-style-panel-icon.svg';\n\n/**\n * Line style change event handler type.\n */\nexport type StyleChangeHandler = (newStyle: string) => void;\n\n/**\n * Line style (solid, dashed, etc.) toolbox panel.\n */\nexport class LineStylePanel extends ToolboxPanel {\n  private styles: string[] = [];\n  private currentStyle?: string;\n\n  private styleBoxes: HTMLDivElement[] = [];\n\n  /**\n   * Handler for the style change event.\n   */\n  public onStyleChanged?: StyleChangeHandler;\n\n  /**\n   * Creates a line style toolbox panel.\n   * @param title - panel title\n   * @param styles - available line styles (dash array).\n   * @param currentStyle - currently selected style.\n   * @param icon - panel button icon (SVG image markup).\n   */\n  constructor(title: string, styles: string[], currentStyle?: string, icon?: string) {\n    super(title, icon ? icon : Icon);\n    this.styles = styles;\n    this.currentStyle = currentStyle;\n\n    this.setCurrentStyle = this.setCurrentStyle.bind(this);\n  }\n\n  /**\n   * Returns panel UI.\n   */\n  public getUi(): HTMLDivElement {\n    const panelDiv = document.createElement('div');\n    panelDiv.style.display = 'flex';\n    panelDiv.style.overflow = 'hidden';\n    panelDiv.style.flexGrow = '2';\n    this.styles.forEach((lineStyle) => {\n      const styleBoxContainer = document.createElement('div');\n      styleBoxContainer.style.display = 'flex'; //'inline-block';\n      styleBoxContainer.style.alignItems = 'center';\n      styleBoxContainer.style.justifyContent = 'space-between';\n      styleBoxContainer.style.padding = '5px';\n      styleBoxContainer.style.borderWidth = '2px';\n      styleBoxContainer.style.borderStyle = 'solid';\n      styleBoxContainer.style.overflow = 'hidden';\n      styleBoxContainer.style.maxWidth = `${100 / this.styles.length - 5}%`;\n      styleBoxContainer.style.borderColor =\n        lineStyle === this.currentStyle ? Style.settings.toolboxAccentColor : 'transparent';\n\n      styleBoxContainer.addEventListener('click', () => {\n        this.setCurrentStyle(lineStyle, styleBoxContainer);\n      })\n      panelDiv.appendChild(styleBoxContainer);\n\n      const styleBox = document.createElement('div');\n      styleBox.style.minHeight = '20px';\n      styleBox.style.flexGrow = '2';\n      styleBox.style.overflow = 'hidden';\n\n      const styleSample = `<svg width=\"100\" height=\"20\">\n      <line x1=\"0\" y1=\"10\" x2=\"100\" y2=\"10\" stroke=\"${\n        Style.settings.toolboxColor}\" stroke-width=\"3\" ${\n          lineStyle !== '' ? 'stroke-dasharray=\"' + lineStyle + '\"' : ''} />\n  </svg>`;\n\n      styleBox.innerHTML = styleSample;\n\n      styleBoxContainer.appendChild(styleBox);\n\n      this.styleBoxes.push(styleBoxContainer);\n    });\n    return panelDiv;\n  }\n\n  private setCurrentStyle(newStyle: string, target: HTMLDivElement) {\n    this.currentStyle = newStyle;\n\n    this.styleBoxes.forEach(box => {\n      box.style.borderColor = box === target ? Style.settings.toolboxAccentColor : 'transparent';\n    });\n\n    if (this.onStyleChanged) {\n      this.onStyleChanged(this.currentStyle);\n    }\n  }\n}\n","import Icon from './frame-marker-icon.svg';\nimport { ToolboxPanel } from '../../ui/ToolboxPanel';\nimport { ColorPickerPanel } from '../../ui/toolbox-panels/ColorPickerPanel';\nimport { Settings } from '../../core/Settings';\nimport { RectangleMarker } from '../RectangleMarker';\nimport { LineWidthPanel } from '../../ui/toolbox-panels/LineWidthPanel';\nimport { LineStylePanel } from '../../ui/toolbox-panels/LineStylePanel';\nimport { RectangleMarkerState } from '../RectangleMarkerState';\n\nexport class FrameMarker extends RectangleMarker {\n  /**\n   * String type name of the marker type. \n   * \n   * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static typeName = 'FrameMarker';\n  \n  /**\n   * Marker type title (display name) used for accessibility and other attributes.\n   */\n  public static title = 'Frame marker';\n  /**\n   * SVG icon markup displayed on toolbar buttons.\n   */\n  public static icon = Icon;\n\n  private strokePanel: ColorPickerPanel;\n  private strokeWidthPanel: LineWidthPanel;\n  private strokeStylePanel: LineStylePanel;\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.\n   * @param settings - settings object containing default markers settings.\n   */\n  constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings) {\n    super(container, overlayContainer, settings);\n\n    this.strokeColor = settings.defaultColor;\n    this.strokeWidth = settings.defaultStrokeWidth;\n    this.strokeDasharray = settings.defaultStrokeDasharray;\n\n    this.strokePanel = new ColorPickerPanel(\n      'Line color',\n      settings.defaultColorSet,\n      settings.defaultColor\n    );\n    this.strokePanel.onColorChanged = this.setStrokeColor;\n\n    this.strokeWidthPanel = new LineWidthPanel(\n      'Line width',\n      settings.defaultStrokeWidths,\n      settings.defaultStrokeWidth\n    );\n    this.strokeWidthPanel.onWidthChanged = this.setStrokeWidth;\n\n    this.strokeStylePanel = new LineStylePanel(\n      'Line style',\n      settings.defaultStrokeDasharrays,\n      settings.defaultStrokeDasharray\n    );\n    this.strokeStylePanel.onStyleChanged = this.setStrokeDasharray;\n  }\n\n  /**\n   * Returns the list of toolbox panels for this marker type.\n   */\n  public get toolboxPanels(): ToolboxPanel[] {\n    return [this.strokePanel, this.strokeWidthPanel, this.strokeStylePanel];\n  }\n\n  /**\n   * Returns current marker state that can be restored in the future.\n   */\n  public getState(): RectangleMarkerState {\n    const result = super.getState();\n    result.typeName = FrameMarker.typeName;\n    return result;\n  }\n}\n","/**\n * Represents a list of colors.\n */\nexport type ColorSet = string[];\n\n/**\n * marker.js 2 display mode - `inline` or `popup`.\n */\nexport type DisplayMode = 'inline' | 'popup';\n\n/**\n * Default settings for marker.js 2 markers.\n */\nexport class Settings {\n  /**\n   * List of colors used in color pickers.\n   */\n  public defaultColorSet: ColorSet = [\n    '#EF4444', // red\n    '#10B981', // green\n    '#2563EB', // blue\n    '#FFFF00', // yellow\n    '#7C3AED', // purple\n    '#F472B6', // pink\n    '#000000', // black\n    '#FFFFFF' //white\n  ];\n\n  /**\n   * Default foreground color.\n   */\n  public defaultColor = this.defaultColorSet[0];\n  /**\n   * Default fill color.\n   */\n  public defaultFillColor = this.defaultColorSet[0];\n  /**\n   * Default stroke color for markers with background (eg. {@link CalloutMarker}).\n   */\n  public defaultStrokeColor = this.defaultColorSet[7];\n  /**\n   * Default highlighter color.\n   */\n  public defaultHighlightColor = this.defaultColorSet[3];\n  /**\n   * Default stroke (line) width.\n   */\n  public defaultStrokeWidth = 3;\n  /**\n   * Default line dash array\n   */\n  public defaultStrokeDasharray = '';\n  /**\n   * Default opacity (alpha) of the {@link HighlightMarker} (and other highlighters).\n   */\n  public defaultHighlightOpacity = 0.5;\n  /**\n   * Default font family for text-based markers (eg. {@link TextMarker} and {@link CalloutMarker}).\n   *\n   */\n  public defaultFontFamily = 'Helvetica, Arial, sans-serif';\n\n  /**\n   * Stroke (line) width options.\n   */\n  public defaultStrokeWidths = [1, 2, 3, 5, 10];\n  \n  /**\n   * Stroke dash array options.\n   */\n  public defaultStrokeDasharrays = ['', '3', '12 3', '9 6 3 6'];\n\n  /**\n   * Opacity options.\n   */\n  public defaultOpacitySteps = [0.1, 0.25, 0.5, 0.75, 1];\n\n  /**\n   * Default display mode.\n   */\n  public displayMode: DisplayMode = 'inline';\n\n  /**\n   * Font family options.\n   */\n  public defaultFontFamilies = [\n    'Times, \"Times New Roman\", serif',\n    'Helvetica, Arial, sans-serif',\n    'Courier, \"Courier New\", monospace',\n    'cursive',\n    'fantasy'\n  ];\n\n  /**\n   * Margin in pixels between marker.js popup UI and window borders.\n   */\n  public popupMargin = 30;\n\n  /**\n   * Create a new Freehand marker for every stroke.\n   */\n  public newFreehandMarkerOnPointerUp = false;\n\n  /**\n   * If set to true, when colors on a marker are changed \n   * it changes the default color for other markers as well.\n   * \n   * @since 2.7.0\n   */\n  public defaultColorsFollowCurrentColors = false;\n\n  /**\n   * Increase this setting for smoother FreehandMarker lines.\n   * Note that it will also take more space when you save the state.\n   *\n   * @since 2.20.0\n   */\n  public freehandPixelRatio = 1;\n}\n","import { MarkerBase } from '../core/MarkerBase';\n\nimport { IPoint } from '../core/IPoint';\nimport { SvgHelper } from '../core/SvgHelper';\n\nimport { ResizeGrip } from './ResizeGrip';\nimport { Settings } from '../core/Settings';\nimport { LinearMarkerBaseState } from './LinearMarkerBaseState';\nimport { MarkerBaseState } from '../core/MarkerBaseState';\n\n/**\n * LinearMarkerBase is a base class for all line-type markers (Line, Arrow, Measurement Tool, etc.).\n */\nexport class LinearMarkerBase extends MarkerBase {\n  /**\n   * x coordinate of the first end-point\n   */\n  protected x1 = 0;\n  /**\n   * y coordinate of the first end-point\n   */\n  protected y1 = 0;\n  /**\n   * x coordinate of the second end-point\n   */\n  protected x2 = 0;\n  /**\n   * y coordinate of the second end-point\n   */\n  protected y2 = 0;\n\n  /**\n   * Default line length when marker is created with a simple click (without dragging).\n   */\n  protected defaultLength = 50;\n\n  /**\n   * Pointer coordinates at the satart of move or resize.\n   */\n  protected manipulationStartX = 0;\n  protected manipulationStartY = 0;\n\n  private manipulationStartX1 = 0;\n  private manipulationStartY1 = 0;\n  private manipulationStartX2 = 0;\n  private manipulationStartY2 = 0;\n\n  /**\n   * Marker's main visual.\n   */\n  protected visual: SVGGraphicsElement;\n\n  /**\n   * Container for control elements.\n   */\n  protected controlBox: SVGGElement;\n\n  /**\n   * First manipulation grip\n   */\n  protected grip1: ResizeGrip;\n  /**\n   * Second manipulation grip.\n   */\n  protected grip2: ResizeGrip;\n  /**\n   * Active manipulation grip.\n   */\n  protected activeGrip: ResizeGrip;\n\n  /**\n   * Creates a LineMarkerBase object.\n   * \n   * @param container - SVG container to hold marker's visual.\n   * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.\n   * @param settings - settings object containing default markers settings.\n   */\n  constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings) {\n    super(container, overlayContainer, settings);\n\n    this.setupControlBox();\n  }\n\n  /**\n   * Returns true if passed SVG element belongs to the marker. False otherwise.\n   * \n   * @param el - target element.\n   */\n  public ownsTarget(el: EventTarget): boolean {\n    if (super.ownsTarget(el)) {\n      return true;\n    } else if (\n      this.grip1.ownsTarget(el) || this.grip2.ownsTarget(el)\n    ) {\n      return true;\n    } else {\n      return false;\n    }\n  }\n\n  \n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) down event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerDown(point: IPoint, target?: EventTarget): void {\n    super.pointerDown(point, target);\n\n    this.manipulationStartX = point.x;\n    this.manipulationStartY = point.y;\n\n    if (this.state === 'new') {\n      this.x1 = point.x;\n      this.y1 = point.y;\n      this.x2 = point.x;\n      this.y2 = point.y;\n    }\n\n    this.manipulationStartX1 = this.x1;\n    this.manipulationStartY1 = this.y1;\n    this.manipulationStartX2 = this.x2;\n    this.manipulationStartY2 = this.y2;\n\n    if (this.state !== 'new') {\n      this.select();\n      if (this.grip1.ownsTarget(target)) {\n        this.activeGrip = this.grip1;\n      } else if (this.grip2.ownsTarget(target)) {\n        this.activeGrip = this.grip2;\n      } else {\n        this.activeGrip = undefined;\n      }\n\n      if (this.activeGrip) {\n        this._state = 'resize';\n      } else {\n        this._state = 'move';\n      }\n    }\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) up event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerUp(point: IPoint): void {\n    const inState = this.state;\n    super.pointerUp(point);\n    if (this.state === 'creating' && Math.abs(this.x1 - this.x2) < 10 && Math.abs(this.y1 - this.y2) < 10) {\n      this.x2 = this.x1 + this.defaultLength;\n      this.adjustVisual();\n      this.adjustControlBox()\n    } else {\n      this.manipulate(point);\n    }\n    this._state = 'select';\n    if (inState === 'creating' && this.onMarkerCreated) {\n      this.onMarkerCreated(this);\n    }\n  }\n\n  /**\n   * When implemented adjusts marker visual after manipulation when needed.\n   */\n  // eslint-disable-next-line @typescript-eslint/no-empty-function\n  protected adjustVisual(): void {}\n\n  /**\n   * Handles marker manipulation (move, resize, rotate, etc.).\n   * \n   * @param point - event coordinates.\n   */\n  public manipulate(point: IPoint): void {\n    if (this.state === 'creating') {\n      this.resize(point);\n    } else if (this.state === 'move') {\n      this.x1 = this.manipulationStartX1 + point.x - this.manipulationStartX;\n      this.y1 = this.manipulationStartY1 + point.y - this.manipulationStartY;\n      this.x2 = this.manipulationStartX2 + point.x - this.manipulationStartX;\n      this.y2 = this.manipulationStartY2 + point.y - this.manipulationStartY;\n      this.adjustVisual();\n      this.adjustControlBox();\n    } else if (this.state === 'resize') {\n      this.resize(point);\n    }\n  }\n\n  /**\n   * Resizes the line marker.\n   * @param point - current manipulation coordinates.\n   */\n  protected resize(point: IPoint): void {\n    switch(this.activeGrip) {\n      case this.grip1:\n        this.x1 = point.x;\n        this.y1 = point.y;\n        break; \n      case this.grip2:\n      case undefined:\n        this.x2 = point.x;\n        this.y2 = point.y;\n        break; \n    }\n    this.adjustVisual();\n    this.adjustControlBox();\n  }\n\n  /**\n   * Displays marker's controls.\n   */\n  public select(): void {\n    super.select();\n    this.adjustControlBox();\n    this.controlBox.style.display = '';\n  }\n\n  /**\n   * Hides marker's controls.\n   */\n  public deselect(): void {\n    super.deselect();\n    this.controlBox.style.display = 'none';\n  }\n\n  /**\n   * Creates control box for manipulation controls.\n   */\n  protected setupControlBox(): void {\n    this.controlBox = SvgHelper.createGroup();\n    this.container.appendChild(this.controlBox);\n\n    this.addControlGrips();\n\n    this.controlBox.style.display = 'none';\n  }\n\n  private adjustControlBox() {\n    this.positionGrips();\n  }\n\n  /**\n   * Adds control grips to control box.\n   */\n  protected addControlGrips(): void {\n    this.grip1 = this.createGrip();\n    this.grip2 = this.createGrip();\n\n    this.positionGrips();\n  }\n\n  /**\n   * Creates manipulation grip.\n   * @returns - manipulation grip.\n   */\n  protected createGrip(): ResizeGrip {\n    const grip = new ResizeGrip();\n    grip.visual.transform.baseVal.appendItem(SvgHelper.createTransform());\n    this.controlBox.appendChild(grip.visual);\n\n    return grip;\n  }\n\n  /**\n   * Updates manipulation grip layout.\n   */\n  protected positionGrips(): void {\n    const gripSize = this.grip1.GRIP_SIZE;\n\n    this.positionGrip(this.grip1.visual, this.x1 - gripSize / 2, this.y1 - gripSize / 2);\n    this.positionGrip(this.grip2.visual, this.x2 - gripSize / 2, this.y2 - gripSize / 2);\n  }\n\n  /**\n   * Positions manipulation grip.\n   * @param grip - grip to position\n   * @param x - new X coordinate\n   * @param y - new Y coordinate\n   */\n  protected positionGrip(grip: SVGGraphicsElement, x: number, y: number): void {\n    const translate = grip.transform.baseVal.getItem(0);\n    translate.setTranslate(x, y);\n    grip.transform.baseVal.replaceItem(translate, 0);\n  }\n\n  /**\n   * Returns marker's state.\n   */\n  public getState(): LinearMarkerBaseState {\n    const result: LinearMarkerBaseState = Object.assign({\n      x1: this.x1,\n      y1: this.y1,\n      x2: this.x2,\n      y2: this.y2\n    }, super.getState());\n\n    return result;\n  }\n\n  /**\n   * Restores marker's state to the previously saved one.\n   * @param state - previously saved state.\n   */\n  public restoreState(state: MarkerBaseState): void {\n    super.restoreState(state);\n    const lmbState = state as LinearMarkerBaseState;\n    this.x1 = lmbState.x1;\n    this.y1 = lmbState.y1;\n    this.x2 = lmbState.x2;\n    this.y2 = lmbState.y2;\n  }\n\n  /**\n   * Scales marker. Used after the image resize.\n   * \n   * @param scaleX - horizontal scale\n   * @param scaleY - vertical scale\n   */\n  public scale(scaleX: number, scaleY: number): void {\n    super.scale(scaleX, scaleY);\n\n    this.x1 = this.x1 * scaleX;\n    this.y1 = this.y1 * scaleY;\n    this.x2 = this.x2 * scaleX;\n    this.y2 = this.y2 * scaleY;\n\n    this.adjustVisual();\n    this.adjustControlBox();\n  }\n}\n","import { IPoint } from '../../core/IPoint';\nimport { SvgHelper } from '../../core/SvgHelper';\nimport { Settings } from '../../core/Settings';\nimport { LinearMarkerBase } from '../LinearMarkerBase';\nimport Icon from './line-marker-icon.svg';\nimport { ColorPickerPanel } from '../../ui/toolbox-panels/ColorPickerPanel';\nimport { ToolboxPanel } from '../../ui/ToolboxPanel';\nimport { LineWidthPanel } from '../../ui/toolbox-panels/LineWidthPanel';\nimport { LineStylePanel } from '../../ui/toolbox-panels/LineStylePanel';\nimport { LineMarkerState } from './LineMarkerState';\nimport { MarkerBaseState } from '../../core/MarkerBaseState';\n\nexport class LineMarker extends LinearMarkerBase {\n  /**\n   * String type name of the marker type. \n   * \n   * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static typeName = 'LineMarker';\n  \n  /**\n   * Marker type title (display name) used for accessibility and other attributes.\n   */\n  public static title = 'Line marker';\n  /**\n   * SVG icon markup displayed on toolbar buttons.\n   */\n  public static icon = Icon;\n\n  /**\n   * Invisible wider line to make selection easier/possible.\n   */\n  protected selectorLine: SVGLineElement;\n  /**\n   * Visible marker line.\n   */\n  protected visibleLine: SVGLineElement;\n\n  /**\n   * Line color.\n   */\n  protected strokeColor = 'transparent';\n  /**\n   * Line width.\n   */\n  protected strokeWidth = 0;\n  /**\n   * Line dash array.\n   */\n  protected strokeDasharray = '';\n\n  /**\n   * Color pickar panel for line color.\n   */\n  protected strokePanel: ColorPickerPanel;\n  /**\n   * Line width toolbox panel.\n   */\n  protected strokeWidthPanel: LineWidthPanel;\n  /**\n   * Line dash array toolbox panel.\n   */\n  protected strokeStylePanel: LineStylePanel;\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.\n   * @param settings - settings object containing default markers settings.\n   */\n  constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings) {\n    super(container, overlayContainer, settings);\n\n    this.setStrokeColor = this.setStrokeColor.bind(this);\n    this.setStrokeWidth = this.setStrokeWidth.bind(this);\n    this.setStrokeDasharray = this.setStrokeDasharray.bind(this);\n\n    this.strokeColor = settings.defaultColor;\n    this.strokeWidth = settings.defaultStrokeWidth;\n    this.strokeDasharray = settings.defaultStrokeDasharray;\n\n    this.strokePanel = new ColorPickerPanel(\n      'Line color',\n      settings.defaultColorSet,\n      settings.defaultColor\n    );\n    this.strokePanel.onColorChanged = this.setStrokeColor;\n\n    this.strokeWidthPanel = new LineWidthPanel(\n      'Line width',\n      settings.defaultStrokeWidths,\n      settings.defaultStrokeWidth\n    );\n    this.strokeWidthPanel.onWidthChanged = this.setStrokeWidth;\n\n    this.strokeStylePanel = new LineStylePanel(\n      'Line style',\n      settings.defaultStrokeDasharrays,\n      settings.defaultStrokeDasharray\n    );\n    this.strokeStylePanel.onStyleChanged = this.setStrokeDasharray;\n  }\n\n  /**\n   * Returns true if passed SVG element belongs to the marker. False otherwise.\n   * \n   * @param el - target element.\n   */\n  public ownsTarget(el: EventTarget): boolean {\n    if (\n      super.ownsTarget(el) ||\n      el === this.visual ||\n      el === this.selectorLine ||\n      el === this.visibleLine\n    ) {\n      return true;\n    } else {\n      return false;\n    }\n  }\n\n  private createVisual() {\n    this.visual = SvgHelper.createGroup();\n    this.selectorLine = SvgHelper.createLine(\n      this.x1,\n      this.y1,\n      this.x2,\n      this.y2,\n      [\n        ['stroke', 'transparent'],\n        ['stroke-width', (this.strokeWidth + 10).toString()],\n      ]\n    );\n    this.visibleLine = SvgHelper.createLine(\n      this.x1,\n      this.y1,\n      this.x2,\n      this.y2,\n      [\n        ['stroke', this.strokeColor],\n        ['stroke-width', this.strokeWidth.toString()],\n      ]\n    );\n    this.visual.appendChild(this.selectorLine);\n    this.visual.appendChild(this.visibleLine);\n\n    this.addMarkerVisualToContainer(this.visual);\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) down event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerDown(point: IPoint, target?: EventTarget): void {\n    super.pointerDown(point, target);\n    if (this.state === 'new') {\n      this.createVisual();\n      this.adjustVisual();\n\n      this._state = 'creating';\n    }\n  }\n\n  /**\n   * Adjusts visual after manipulation.\n   */\n  protected adjustVisual(): void {\n    if (this.selectorLine && this.visibleLine) {\n      this.selectorLine.setAttribute('x1', this.x1.toString());\n      this.selectorLine.setAttribute('y1', this.y1.toString());\n      this.selectorLine.setAttribute('x2', this.x2.toString());\n      this.selectorLine.setAttribute('y2', this.y2.toString());\n\n      this.visibleLine.setAttribute('x1', this.x1.toString());\n      this.visibleLine.setAttribute('y1', this.y1.toString());\n      this.visibleLine.setAttribute('x2', this.x2.toString());\n      this.visibleLine.setAttribute('y2', this.y2.toString());\n\n      SvgHelper.setAttributes(this.visibleLine, [['stroke', this.strokeColor]]);\n      SvgHelper.setAttributes(this.visibleLine, [['stroke-width', this.strokeWidth.toString()]]);\n      SvgHelper.setAttributes(this.visibleLine, [['stroke-dasharray', this.strokeDasharray.toString()]]);\n    }\n  }\n\n  /**\n   * Sets line color.\n   * @param color - new color.\n   */\n  protected setStrokeColor(color: string): void {\n    this.strokeColor = color;\n    this.adjustVisual();\n    this.colorChanged(color);\n  }\n  /**\n   * Sets line width.\n   * @param width - new width.\n   */\n  protected setStrokeWidth(width: number): void {\n    this.strokeWidth = width\n    this.adjustVisual();\n  }\n\n  /**\n   * Sets line dash array.\n   * @param dashes - new dash array.\n   */\n  protected setStrokeDasharray(dashes: string): void {\n    this.strokeDasharray = dashes;\n    this.adjustVisual();\n  }\n\n  /**\n   * Returns the list of toolbox panels for this marker type.\n   */\n  public get toolboxPanels(): ToolboxPanel[] {\n    return [this.strokePanel, this.strokeWidthPanel, this.strokeStylePanel];\n  }\n\n  /**\n   * Returns current marker state that can be restored in the future.\n   */\n  public getState(): LineMarkerState {\n    const result: LineMarkerState = Object.assign({\n      strokeColor: this.strokeColor,\n      strokeWidth: this.strokeWidth,\n      strokeDasharray: this.strokeDasharray\n    }, super.getState());\n    result.typeName = LineMarker.typeName;\n\n    return result;\n  }\n\n  /**\n   * Restores previously saved marker state.\n   * \n   * @param state - previously saved state.\n   */\n  public restoreState(state: MarkerBaseState): void {\n    super.restoreState(state);\n\n    const lmState = state as LineMarkerState;\n    this.strokeColor = lmState.strokeColor;\n    this.strokeWidth = lmState.strokeWidth;\n    this.strokeDasharray = lmState.strokeDasharray;\n\n    this.createVisual();\n    this.adjustVisual();\n  }\n}\n","import { Style } from '../../core/Style';\nimport { ToolboxPanel } from '../ToolboxPanel';\nimport Icon from './font-family-panel-icon.svg';\n\n/**\n * Font change event handler type.\n */\nexport type FontChangeHandler = (newFont: string) => void;\n\n/**\n * Font family selection toolbox panel.\n */\nexport class FontFamilyPanel extends ToolboxPanel {\n  private fonts: string[] = [];\n  private currentFont?: string;\n\n  private fontBoxes: HTMLDivElement[] = [];\n\n  /**\n   * Handler for the font family change event.\n   */\n  public onFontChanged?: FontChangeHandler;\n\n  /**\n   * Creates a font family toolbox panel.\n   * @param title - panel title.\n   * @param fonts - available font families.\n   * @param currentFont - currently selected font family.\n   * @param icon - panel button icon (SVG image markup).\n   */\n  constructor(title: string, fonts: string[], currentFont?: string, icon?: string) {\n    super(title, icon ? icon : Icon);\n    this.fonts = fonts;\n    this.currentFont = currentFont;\n\n    this.setCurrentFont = this.setCurrentFont.bind(this);\n  }\n\n  /**\n   * Returns panel UI.\n   */\n  public getUi(): HTMLDivElement {\n    const panelDiv = document.createElement('div');\n    // panelDiv.style.display = 'flex';\n    panelDiv.style.overflow = 'hidden';\n    panelDiv.style.flexGrow = '2';\n    this.fonts.forEach((font) => {\n      const fontBoxContainer = document.createElement('div');\n      fontBoxContainer.style.display = 'inline-block';\n      // fontBoxContainer.style.flexGrow = '2';\n      fontBoxContainer.style.alignItems = 'center';\n      fontBoxContainer.style.justifyContent = 'space-between';\n      fontBoxContainer.style.padding = '5px';\n      fontBoxContainer.style.borderWidth = '2px';\n      fontBoxContainer.style.borderStyle = 'solid';\n      fontBoxContainer.style.overflow = 'hidden';\n      fontBoxContainer.style.maxWidth = `${100 / this.fonts.length - 5}%`;\n      fontBoxContainer.style.borderColor =\n        font === this.currentFont ? Style.settings.toolboxAccentColor : 'transparent';\n\n      fontBoxContainer.addEventListener('click', () => {\n        this.setCurrentFont(font, fontBoxContainer);\n      })\n      panelDiv.appendChild(fontBoxContainer);\n\n      const fontBox = document.createElement('div');\n      fontBox.style.display = 'flex';\n      fontBox.style.minHeight = '20px';\n      fontBox.style.flexGrow = '2';\n      fontBox.style.fontFamily = font;\n      fontBox.style.overflow = 'hidden';\n\n      const fontLabel = document.createElement('div');\n      fontLabel.style.whiteSpace = 'nowrap';\n      fontLabel.style.overflow = 'hidden';\n      fontLabel.style.textOverflow = 'ellipsis';\n      fontLabel.innerHTML = 'The quick brown fox jumps over the lazy dog';\n\n      fontBox.appendChild(fontLabel);\n\n      fontBoxContainer.appendChild(fontBox);\n\n      this.fontBoxes.push(fontBoxContainer);\n    });\n    return panelDiv;\n  }\n\n  private setCurrentFont(newFont: string, target: HTMLDivElement) {\n    this.currentFont = newFont;\n\n    this.fontBoxes.forEach(box => {\n      box.style.borderColor = box === target ? Style.settings.toolboxAccentColor : 'transparent';\n    });\n\n    if (this.onFontChanged) {\n      this.onFontChanged(this.currentFont);\n    }\n  }\n}\n","import { IPoint } from '../../core/IPoint';\nimport { SvgHelper } from '../../core/SvgHelper';\nimport { RectangularBoxMarkerBase } from '../RectangularBoxMarkerBase';\nimport { Settings } from '../../core/Settings';\nimport Icon from './text-marker-icon.svg';\nimport { ColorPickerPanel } from '../../ui/toolbox-panels/ColorPickerPanel';\nimport { ToolboxPanel } from '../../ui/ToolboxPanel';\nimport { FontFamilyPanel } from '../../ui/toolbox-panels/FontFamilyPanel';\nimport { TextMarkerState } from './TextMarkerState';\nimport { MarkerBaseState } from '../../core/MarkerBaseState';\n\nexport class TextMarker extends RectangularBoxMarkerBase {\n  /**\n   * String type name of the marker type.\n   *\n   * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static typeName = 'TextMarker';\n\n  /**\n   * Marker type title (display name) used for accessibility and other attributes.\n   */\n  public static title = 'Text marker';\n  /**\n   * SVG icon markup displayed on toolbar buttons.\n   */\n  public static icon = Icon;\n\n  /**\n   * Text color.\n   */\n  protected color = 'transparent';\n  /**\n   * Text's font family.\n   */\n  protected fontFamily: string;\n  /**\n   * Padding inside of the marker's bounding box in percents.\n   */\n  protected padding = 5;\n\n  /**\n   * Text color picker toolbox panel.\n   */\n  protected colorPanel: ColorPickerPanel;\n  /**\n   * Text font family toolbox panel.\n   */\n  protected fontFamilyPanel: FontFamilyPanel;\n\n  private readonly DEFAULT_TEXT = 'your text here';\n  private text: string = this.DEFAULT_TEXT;\n  /**\n   * Visual text element.\n   */\n  protected textElement: SVGTextElement;\n  /**\n   * Text background rectangle.\n   */\n  protected bgRectangle: SVGRectElement;\n  /**\n   * Div element for the text editor container.\n   */\n  protected textEditDiv: HTMLDivElement;\n  /**\n   * Editable text element.\n   */\n  protected textEditor: HTMLDivElement;\n\n  private isMoved = false;\n  private pointerDownPoint: IPoint;\n  private pointerDownTimestamp: number;\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.\n   * @param settings - settings object containing default markers settings.\n   */\n  constructor(\n    container: SVGGElement,\n    overlayContainer: HTMLDivElement,\n    settings: Settings\n  ) {\n    super(container, overlayContainer, settings);\n\n    this.color = settings.defaultColor;\n    this.fontFamily = settings.defaultFontFamily;\n\n    this.defaultSize = { x: 100, y: 30 };\n\n    this.setColor = this.setColor.bind(this);\n    this.setFont = this.setFont.bind(this);\n    this.renderText = this.renderText.bind(this);\n    this.sizeText = this.sizeText.bind(this);\n    this.textEditDivClicked = this.textEditDivClicked.bind(this);\n    this.showTextEditor = this.showTextEditor.bind(this);\n    this.setSize = this.setSize.bind(this);\n    this.positionTextEditor = this.positionTextEditor.bind(this);\n\n    this.colorPanel = new ColorPickerPanel(\n      'Color',\n      settings.defaultColorSet,\n      settings.defaultColor\n    );\n    this.colorPanel.onColorChanged = this.setColor;\n\n    this.fontFamilyPanel = new FontFamilyPanel(\n      'Font',\n      settings.defaultFontFamilies,\n      settings.defaultFontFamily\n    );\n    this.fontFamilyPanel.onFontChanged = this.setFont;\n  }\n\n  /**\n   * Returns true if passed SVG element belongs to the marker. False otherwise.\n   *\n   * @param el - target element.\n   */\n  public ownsTarget(el: EventTarget): boolean {\n    if (\n      super.ownsTarget(el) ||\n      el === this.visual ||\n      el === this.textElement ||\n      el === this.bgRectangle\n    ) {\n      return true;\n    } else {\n      let found = false;\n      this.textElement.childNodes.forEach((span) => {\n        if (span === el) {\n          found = true;\n        }\n      });\n      return found;\n    }\n  }\n\n  /**\n   * Creates text marker visual.\n   */\n  protected createVisual(): void {\n    this.visual = SvgHelper.createGroup();\n\n    this.bgRectangle = SvgHelper.createRect(1, 1, [['fill', 'transparent']]);\n    this.visual.appendChild(this.bgRectangle);\n\n    this.textElement = SvgHelper.createText([\n      ['fill', this.color],\n      ['font-family', this.fontFamily],\n      ['font-size', '16px'],\n      ['x', '0'],\n      ['y', '0'],\n    ]);\n    this.textElement.transform.baseVal.appendItem(SvgHelper.createTransform()); // translate transorm\n    this.textElement.transform.baseVal.appendItem(SvgHelper.createTransform()); // scale transorm\n\n    this.visual.appendChild(this.textElement);\n\n    this.addMarkerVisualToContainer(this.visual);\n    this.renderText();\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) down event.\n   *\n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerDown(point: IPoint, target?: EventTarget): void {\n    super.pointerDown(point, target);\n\n    this.isMoved = false;\n    this.pointerDownPoint = point;\n    this.pointerDownTimestamp = Date.now();\n\n    if (this.state === 'new') {\n      this.createVisual();\n      this.moveVisual(point);\n      this._state = 'creating';\n    }\n  }\n\n  private renderText() {\n    const LINE_SIZE = '1.2em';\n\n    if (this.textElement) {\n      while (this.textElement.lastChild) {\n        this.textElement.removeChild(this.textElement.lastChild);\n      }\n\n      const lines = this.text.split(/\\r\\n|[\\n\\v\\f\\r\\x85\\u2028\\u2029]/);\n      lines.forEach((line) => {\n        this.textElement.appendChild(\n          SvgHelper.createTSpan(\n            // workaround for swallowed empty lines\n            line.trim() === '' ? ' ' : line.trim(), [\n            ['x', '0'],\n            ['dy', LINE_SIZE],\n          ])\n        );\n      });\n\n      setTimeout(this.sizeText, 10);\n    }\n  }\n\n  private getTextScale(): number {\n    const textSize = this.textElement.getBBox();\n    let scale = 1.0;\n    if (textSize.width > 0 && textSize.height > 0) {\n      const xScale =\n        (this.width * 1.0 - (this.width * this.padding * 2) / 100) /\n        textSize.width;\n      const yScale =\n        (this.height * 1.0 - (this.height * this.padding * 2) / 100) /\n        textSize.height;\n      scale = Math.min(xScale, yScale);\n    }\n    return scale;\n  }\n\n  private getTextPosition(scale: number): IPoint {\n    const textSize = this.textElement.getBBox();\n    let x = 0;\n    let y = 0;\n    if (textSize.width > 0 && textSize.height > 0) {\n      x = (this.width - textSize.width * scale) / 2;\n      y = this.height / 2 - (textSize.height * scale) / 2;\n    }\n    return { x: x, y: y };\n  }\n\n  private sizeText() {\n    const textBBox = this.textElement.getBBox();\n    const scale = this.getTextScale();\n    const position = this.getTextPosition(scale);\n    position.y -= textBBox.y * scale; // workaround adjustment for text not being placed at y=0\n\n    if (navigator.userAgent.indexOf('Edge/') > -1) {\n      // workaround for legacy Edge as transforms don't work otherwise but this way it doesn't work in Safari\n      this.textElement.style.transform = `translate(${position.x}px, ${position.y}px) scale(${scale}, ${scale})`;\n    } else {\n      this.textElement.transform.baseVal\n        .getItem(0)\n        .setTranslate(position.x, position.y);\n      this.textElement.transform.baseVal.getItem(1).setScale(scale, scale);\n    }\n  }\n\n  /**\n   * Handles marker manipulation (move, resize, rotate, etc.).\n   *\n   * @param point - event coordinates.\n   */\n  public manipulate(point: IPoint): void {\n    super.manipulate(point);\n    if (this.pointerDownPoint !== undefined) {\n      this.isMoved =\n        Math.abs(point.x - this.pointerDownPoint.x) > 5 ||\n        Math.abs(point.y - this.pointerDownPoint.y) > 5;\n    }\n  }\n\n  /**\n   * Resize marker based on current pointer coordinates and context.\n   * @param point\n   */\n  protected resize(point: IPoint): void {\n    super.resize(point);\n    this.isMoved = true;\n    this.setSize();\n    this.sizeText();\n  }\n\n  /**\n   * Sets size of marker elements after manipulation.\n   */\n  protected setSize(): void {\n    super.setSize();\n    if (this.visual && this.bgRectangle) {\n      SvgHelper.setAttributes(this.visual, [\n        ['width', this.width.toString()],\n        ['height', this.height.toString()],\n      ]);\n      SvgHelper.setAttributes(this.bgRectangle, [\n        ['width', this.width.toString()],\n        ['height', this.height.toString()],\n      ]);\n    }\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) up event.\n   *\n   * @param point - event coordinates.\n   */\n  public pointerUp(point: IPoint): void {\n    const inState = this.state;\n    super.pointerUp(point);\n    this.setSize();\n    if (\n      inState === 'creating' ||\n      (!this.isMoved && Date.now() - this.pointerDownTimestamp > 500)\n    ) {\n      this.showTextEditor();\n    }\n    this.pointerDownPoint = undefined;\n  }\n\n  private showTextEditor() {\n    this._state = 'edit';\n    this.overlayContainer.innerHTML = '';\n\n    this.textEditDiv = document.createElement('div');\n    // textEditDiv.style.display = 'flex';\n    this.textEditDiv.style.flexGrow = '2';\n    //textEditDiv.style.backgroundColor = 'rgb(0,0,0,0.7)';\n    this.textEditDiv.style.alignItems = 'center';\n    this.textEditDiv.style.justifyContent = 'center';\n    this.textEditDiv.style.pointerEvents = 'auto';\n    this.textEditDiv.style.overflow = 'hidden';\n\n    this.textEditor = document.createElement('div');\n    this.textEditor.style.position = 'absolute';\n    this.textEditor.style.fontFamily = this.fontFamily;\n    this.textEditor.style.lineHeight = '1em';\n    this.textEditor.innerText = this.text;\n    this.textEditor.contentEditable = 'true';\n    this.textEditor.style.color = this.color;\n    this.textEditor.style.whiteSpace = 'pre';\n    this.positionTextEditor();\n    this.textEditor.addEventListener('pointerup', (ev) => {\n      ev.stopPropagation();\n    });\n    this.textEditor.addEventListener('input', () => {\n      let fontSize = Number.parseFloat(this.textEditor.style.fontSize);\n      while (\n        this.textEditor.clientWidth >=\n          Number.parseInt(this.textEditor.style.maxWidth) &&\n        fontSize > 0.9\n      ) {\n        fontSize -= 0.1;\n        this.textEditor.style.fontSize = `${Math.max(fontSize, 0.9)}em`;\n      }\n    });\n    this.textEditor.addEventListener('keyup', (ev) => {\n      ev.cancelBubble = true;\n    });\n    this.textEditor.addEventListener('paste', (ev) => {\n      if (ev.clipboardData) {\n        // paste plain text\n        const content = ev.clipboardData.getData('text');\n        const selection = window.getSelection();\n        if (!selection.rangeCount) return false;\n        selection.deleteFromDocument();\n        selection.getRangeAt(0).insertNode(document.createTextNode(content));\n        ev.preventDefault();\n      }\n    });\n\n    this.textEditDiv.addEventListener('pointerup', () => {\n      this.textEditDivClicked(this.textEditor.innerText);\n    });\n    this.textEditDiv.appendChild(this.textEditor);\n    this.overlayContainer.appendChild(this.textEditDiv);\n\n    this.hideVisual();\n\n    this.textEditor.focus();\n    document.execCommand('selectAll');\n  }\n\n  private positionTextEditor() {\n    if (this.state === 'edit') {\n      if (this.textEditor === undefined) {\n        this.showTextEditor();\n      } else {\n        this.textElement.style.display = '';\n        const textScale = this.getTextScale();\n        // const textPosition = this.getTextPosition(textScale);\n        const rPosition = this.rotatePoint({\n          x: this.left + this.width / 2,\n          y: this.top + this.height / 2,\n        });\n        const textSize = this.textElement.getBBox();\n        const rWH = {\n          x: textSize.width * textScale,\n          y: textSize.height * textScale,\n        };\n        rPosition.x -= rWH.x / 2;\n        rPosition.y -= rWH.y / 2;\n\n        this.textEditor.style.top = `${rPosition.y}px`;\n        this.textEditor.style.left = `${rPosition.x}px`;\n        this.textEditor.style.maxWidth = `${\n          this.overlayContainer.offsetWidth - rPosition.x\n        }px`;\n        this.textEditor.style.fontSize = `${Math.max(16 * textScale, 12)}px`;\n        this.textElement.style.display = 'none';\n      }\n    }\n  }\n\n  private textEditDivClicked(text: string) {\n    this.text = text.trim();\n    this.overlayContainer.innerHTML = '';\n    this.renderText();\n    this.showVisual();\n  }\n\n  /**\n   * Deselects this marker, renders text (if necessary), and hides selected marker UI.\n   */\n  public deselect(): void {\n    if (this.state === 'edit') {\n      this.textEditDivClicked(this.textEditor.innerText);\n    }\n    super.deselect();\n  }\n\n  /**\n   * Opens text editor on double-click.\n   * @param point\n   * @param target\n   */\n  public dblClick(point: IPoint, target?: EventTarget): void {\n    super.dblClick(point, target);\n\n    this.showTextEditor();\n  }\n\n  /**\n   * Sets text color.\n   * @param color - new text color.\n   */\n  protected setColor(color: string): void {\n    if (this.textElement) {\n      SvgHelper.setAttributes(this.textElement, [['fill', color]]);\n    }\n    this.color = color;\n    if (this.textEditor) {\n      this.textEditor.style.color = this.color;\n    }\n    this.colorChanged(color);\n  }\n\n  /**\n   * Sets font family.\n   * @param font - new font family.\n   */\n  protected setFont(font: string): void {\n    if (this.textElement) {\n      SvgHelper.setAttributes(this.textElement, [['font-family', font]]);\n    }\n    this.fontFamily = font;\n    if (this.textEditor) {\n      this.textEditor.style.fontFamily = this.fontFamily;\n    }\n    this.renderText();\n  }\n\n  /**\n   * Hides marker visual.\n   */\n  protected hideVisual(): void {\n    this.textElement.style.display = 'none';\n    this.hideControlBox();\n  }\n  /**\n   * Shows marker visual.\n   */\n  protected showVisual(): void {\n    if (this.state === 'edit') {\n      this._state = 'select';\n    }\n    this.textElement.style.display = '';\n    this.showControlBox();\n  }\n\n  /**\n   * Returns the list of toolbox panels for this marker type.\n   */\n  public get toolboxPanels(): ToolboxPanel[] {\n    return [this.colorPanel, this.fontFamilyPanel];\n  }\n\n  /**\n   * Returns current marker state that can be restored in the future.\n   */\n  public getState(): TextMarkerState {\n    const result: TextMarkerState = Object.assign(\n      {\n        color: this.color,\n        fontFamily: this.fontFamily,\n        padding: this.padding,\n        text: this.text,\n      },\n      super.getState()\n    );\n    result.typeName = TextMarker.typeName;\n\n    return result;\n  }\n\n  /**\n   * Restores previously saved marker state.\n   *\n   * @param state - previously saved state.\n   */\n  public restoreState(state: MarkerBaseState): void {\n    const textState = state as TextMarkerState;\n    this.color = textState.color;\n    this.fontFamily = textState.fontFamily;\n    this.padding = textState.padding;\n    this.text = textState.text;\n\n    this.createVisual();\n    super.restoreState(state);\n    this.setSize();\n  }\n\n  /**\n   * Scales marker. Used after the image resize.\n   *\n   * @param scaleX - horizontal scale\n   * @param scaleY - vertical scale\n   */\n  public scale(scaleX: number, scaleY: number): void {\n    super.scale(scaleX, scaleY);\n\n    this.setSize();\n    this.sizeText();\n    this.positionTextEditor();\n  }\n}\n","import { IPoint } from '../../core/IPoint';\nimport { SvgHelper } from '../../core/SvgHelper';\nimport { RectangularBoxMarkerBase } from '../RectangularBoxMarkerBase';\nimport { Settings } from '../../core/Settings';\nimport Icon from './freehand-marker-icon.svg';\nimport { ColorPickerPanel } from '../../ui/toolbox-panels/ColorPickerPanel';\nimport { ToolboxPanel } from '../../ui/ToolboxPanel';\nimport { FreehandMarkerState } from './FreehandMarkerState';\nimport { MarkerBaseState } from '../../core/MarkerBaseState';\nimport { LineWidthPanel } from '../../ui/toolbox-panels/LineWidthPanel';\n\n\nexport class FreehandMarker extends RectangularBoxMarkerBase {\n  /**\n   * String type name of the marker type. \n   * \n   * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static typeName = 'FreehandMarker';\n\n  /**\n   * Marker type title (display name) used for accessibility and other attributes.\n   */\n  public static title = 'Freehand marker';\n  /**\n   * SVG icon markup displayed on toolbar buttons.\n   */\n  public static icon = Icon;\n\n  /**\n   * Marker color.\n   */\n  protected color = 'transparent';\n  /**\n   * Marker's stroke width.\n   */\n  protected lineWidth = 3;\n\n  private colorPanel: ColorPickerPanel;\n  private lineWidthPanel: LineWidthPanel;\n\n\n  private canvasElement: HTMLCanvasElement;\n  private canvasContext: CanvasRenderingContext2D;\n\n  private drawingImage: SVGImageElement;\n  private drawingImgUrl: string;\n\n  private drawing = false;\n\n  private pixelRatio = 1;\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.\n   * @param settings - settings object containing default markers settings.\n   */\n  constructor(\n    container: SVGGElement,\n    overlayContainer: HTMLDivElement,\n    settings: Settings\n  ) {\n    super(container, overlayContainer, settings);\n\n    this.color = settings.defaultColor;\n    this.lineWidth = settings.defaultStrokeWidth;\n    this.pixelRatio = settings.freehandPixelRatio;\n\n    this.setColor = this.setColor.bind(this);\n    this.addCanvas = this.addCanvas.bind(this);\n    this.finishCreation = this.finishCreation.bind(this);\n    this.setLineWidth = this.setLineWidth.bind(this);\n\n    this.colorPanel = new ColorPickerPanel(\n      'Color',\n      settings.defaultColorSet,\n      settings.defaultColor\n    );\n    this.colorPanel.onColorChanged = this.setColor;\n\n    this.lineWidthPanel = new LineWidthPanel(\n      'Line width',\n      settings.defaultStrokeWidths,\n      settings.defaultStrokeWidth\n    );\n    this.lineWidthPanel.onWidthChanged = this.setLineWidth;\n\n  }\n\n  /**\n   * Returns true if passed SVG element belongs to the marker. False otherwise.\n   * \n   * @param el - target element.\n   */\n  public ownsTarget(el: EventTarget): boolean {\n    if (\n      super.ownsTarget(el) ||\n      el === this.visual ||\n      el === this.drawingImage\n    ) {\n      return true;\n    } else {\n      return false;\n    }\n  }\n\n  private createVisual() {\n    this.visual = SvgHelper.createGroup();\n    this.drawingImage = SvgHelper.createImage();\n    this.visual.appendChild(this.drawingImage);\n\n    const translate = SvgHelper.createTransform();\n    this.visual.transform.baseVal.appendItem(translate);\n    this.addMarkerVisualToContainer(this.visual);\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) down event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerDown(point: IPoint, target?: EventTarget): void {\n    if (this.state === 'new') {\n      this.addCanvas();\n\n      this.createVisual();\n\n      this._state = 'creating';\n    }\n\n    if (this.state === 'creating') {\n      this.canvasContext.strokeStyle = this.color;\n      this.canvasContext.lineWidth = this.lineWidth;\n      this.canvasContext.beginPath();\n      this.canvasContext.moveTo(point.x, point.y);\n      this.drawing = true;\n    } else {\n      super.pointerDown(point, target);\n    }\n  }\n\n  /**\n   * Handles marker manipulation (move, resize, rotate, etc.).\n   * \n   * @param point - event coordinates.\n   */\n  public manipulate(point: IPoint): void {\n    if (this.state === 'creating') {\n      if (this.drawing) {\n        this.canvasContext.lineTo(point.x, point.y);\n        this.canvasContext.stroke();\n      }\n    } else {\n      super.manipulate(point);\n    }\n  }\n\n  /**\n   * Resize marker based on current pointer coordinates and context.\n   * @param point \n   */\n  protected resize(point: IPoint): void {\n    super.resize(point);\n    SvgHelper.setAttributes(this.visual, [\n      ['width', this.width.toString()],\n      ['height', this.height.toString()],\n    ]);\n    SvgHelper.setAttributes(this.drawingImage, [\n      ['width', this.width.toString()],\n      ['height', this.height.toString()],\n    ]);\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) up event.\n   * \n   * @param point - event coordinates.\n   */\n  public pointerUp(point: IPoint): void {\n    if (this._state === 'creating') {\n      if (this.drawing) {\n        this.canvasContext.closePath();\n        this.drawing = false;\n        if (this.globalSettings.newFreehandMarkerOnPointerUp) {\n          this.finishCreation();\n        }\n      }\n    } else {\n      super.pointerUp(point);\n    }\n  }\n\n  private addCanvas() {\n    this.overlayContainer.innerHTML = '';\n\n    this.canvasElement = document.createElement('canvas');\n    this.canvasElement.width = this.overlayContainer.clientWidth * this.pixelRatio;\n    this.canvasElement.height = this.overlayContainer.clientHeight * this.pixelRatio;\n    this.canvasContext = this.canvasElement.getContext('2d');\n    this.canvasContext.scale(this.pixelRatio, this.pixelRatio);\n    this.overlayContainer.appendChild(this.canvasElement);\n  }\n\n  /**\n   * Selects this marker and displays appropriate selected marker UI.\n   */\n  public select(): void {\n    if (this.state === 'creating') {\n      this.finishCreation();\n    }\n    super.select();\n  }\n\n  /**\n   * Deselects this marker and hides selected marker UI.\n   */\n  public deselect(): void {\n    if (this.state === 'creating') {\n      this.finishCreation();\n    }\n    super.deselect();\n  }\n\n  private finishCreation() {\n    const imgData = this.canvasContext.getImageData(\n      0,\n      0,\n      this.canvasElement.width,\n      this.canvasElement.height\n    );\n\n    let [startX, startY, endX, endY] = [\n      this.canvasElement.width + 1,\n      this.canvasElement.height + 1,\n      -1,\n      -1,\n    ];\n    let containsData = false;\n    for (let row = 0; row < this.canvasElement.height; row++) {\n      for (let col = 0; col < this.canvasElement.width; col++) {\n        const pixAlpha =\n          imgData.data[row * this.canvasElement.width * 4 + col * 4 + 3];\n        if (pixAlpha > 0) {\n          containsData = true;\n          if (row < startY) {\n            startY = row;\n          }\n          if (col < startX) {\n            startX = col;\n          }\n          if (row > endY) {\n            endY = row;\n          }\n          if (col > endX) {\n            endX = col;\n          }\n        }\n      }\n    }\n\n    if (containsData) {\n      this.left = startX / this.pixelRatio;\n      this.top = startY / this.pixelRatio;\n      this.width = (endX - startX) / this.pixelRatio;\n      this.height = (endY - startY) / this.pixelRatio;\n\n      const tmpCanvas = document.createElement('canvas');\n      tmpCanvas.width = endX - startX;\n      tmpCanvas.height = endY - startY;\n      const tmpCtx = tmpCanvas.getContext('2d');\n      tmpCtx.putImageData(\n        this.canvasContext.getImageData(\n          startX,\n          startY,\n          endX - startX,\n          endY - startY\n        ),\n        0,\n        0\n      );\n\n      this.drawingImgUrl = tmpCanvas.toDataURL('image/png');\n      this.setDrawingImage();\n\n      this._state = 'select';\n      if (this.onMarkerCreated) {\n        this.onMarkerCreated(this);\n      }\n    }\n    this.overlayContainer.innerHTML = '';\n  }\n\n  private setDrawingImage() {\n    SvgHelper.setAttributes(this.drawingImage, [\n      ['width', this.width.toString()],\n      ['height', this.height.toString()],\n    ]);\n    SvgHelper.setAttributes(this.drawingImage, [['href', this.drawingImgUrl]]);\n    this.moveVisual({ x: this.left, y: this.top });\n  }\n\n  /**\n   * Sets marker drawing color.\n   * @param color - new color.\n   */\n  protected setColor(color: string): void {\n    this.color = color;\n    this.colorChanged(color);\n  }\n\n  /**\n   * Sets line width.\n   * @param width - new line width\n   */\n   protected setLineWidth(width: number): void {\n    this.lineWidth = width;\n  }\n\n\n  /**\n   * Returns the list of toolbox panels for this marker type.\n   */\n  public get toolboxPanels(): ToolboxPanel[] {\n    if (this.state === 'new' || this.state === 'creating') {\n      return [this.colorPanel, this.lineWidthPanel];\n    } else {\n      return [];\n    }\n  }\n\n  /**\n   * Returns current marker state that can be restored in the future.\n   */\n  public getState(): FreehandMarkerState {\n    const result: FreehandMarkerState = Object.assign({\n      drawingImgUrl: this.drawingImgUrl\n    }, super.getState());\n    result.typeName = FreehandMarker.typeName;\n\n    return result;\n  }\n\n  /**\n   * Restores previously saved marker state.\n   * \n   * @param state - previously saved state.\n   */\n  public restoreState(state: MarkerBaseState): void {\n    this.createVisual();\n    super.restoreState(state);\n    this.drawingImgUrl = (state as FreehandMarkerState).drawingImgUrl;\n    this.setDrawingImage();\n  }\n\n  /**\n   * Scales marker. Used after the image resize.\n   * \n   * @param scaleX - horizontal scale\n   * @param scaleY - vertical scale\n   */\n  public scale(scaleX: number, scaleY: number): void {\n    super.scale(scaleX, scaleY);\n\n    this.setDrawingImage();\n  }\n\n}\n","import { Style } from '../../core/Style';\nimport { ToolboxPanel } from '../ToolboxPanel';\nimport Icon from './arrow-type-panel-icon.svg';\n\n/**\n * Represents available arrow types.\n * \n * - `both` - arrow tips on both sides.\n * - `start` - arrow tip on the starting point of line.\n * - `end` - arrow tip on the ending point of line.\n * - `none` - no arrow tips.\n */\nexport type ArrowType = 'both' | 'start' | 'end' | 'none';\n/**\n * Handler for arrow type change event.\n */\nexport type ArrowTypeChangeHandler = (newType: ArrowType) => void;\n\n/**\n * Arrow type selection panel.\n */\nexport class ArrowTypePanel extends ToolboxPanel {\n  private currentType?: ArrowType;\n\n  private typeBoxes: HTMLDivElement[] = [];\n\n  /**\n   * Event handler for the arrow type change event.\n   */\n  public onArrowTypeChanged?: ArrowTypeChangeHandler;\n\n  /**\n   * Creates an ArrowTypePanel.\n   * @param title - panel title.\n   * @param currentType - currently set arrow type.\n   * @param icon - panel button icon (SVG image markup).\n   */\n  constructor(title: string, currentType?: ArrowType, icon?: string) {\n    super(title, icon ? icon : Icon);\n    this.currentType = currentType;\n\n    this.setCurrentType = this.setCurrentType.bind(this);\n  }\n\n  /**\n   * Returns panel UI.\n   */\n  public getUi(): HTMLDivElement {\n    const panelDiv = document.createElement('div');\n    panelDiv.style.display = 'flex';\n    panelDiv.style.overflow = 'hidden';\n    panelDiv.style.flexGrow = '2';\n    for (let ti = 0; ti < 4; ti++) {\n      let arrowType: ArrowType = 'both';\n      switch(ti) {\n        case 0:\n          arrowType = 'both';\n          break;\n        case 1:\n          arrowType = 'start';\n          break;\n        case 2:\n          arrowType = 'end';\n          break;\n        case 3:\n          arrowType = 'none';\n          break;\n      }\n      const typeBoxContainer = document.createElement('div');\n      typeBoxContainer.style.display = 'flex';\n      typeBoxContainer.style.flexGrow = '2';\n      typeBoxContainer.style.alignItems = 'center';\n      typeBoxContainer.style.justifyContent = 'space-between';\n      typeBoxContainer.style.padding = '5px';\n      typeBoxContainer.style.borderWidth = '2px';\n      typeBoxContainer.style.borderStyle = 'solid';\n      typeBoxContainer.style.borderColor =\n        arrowType === this.currentType ? Style.settings.toolboxAccentColor : 'transparent';\n\n      typeBoxContainer.addEventListener('click', () => {\n        this.setCurrentType(arrowType, typeBoxContainer);\n      })\n      panelDiv.appendChild(typeBoxContainer);\n\n      if (arrowType === 'both' || arrowType === 'start') {\n        const leftTip = document.createElement('div');\n        leftTip.style.display = 'flex';\n        leftTip.style.alignItems = 'center';\n        leftTip.style.minHeight = '20px';\n        leftTip.innerHTML = `<svg viewBox=\"0 0 10 10\" width=\"10\" height=\"10\" xmlns=\"http://www.w3.org/2000/svg\">\n          <polygon points=\"0,5 10,0 10,10\" fill=\"${Style.settings.toolboxColor}\" />\n        </svg>`;\n        leftTip.style.marginLeft = '5px';\n        typeBoxContainer.appendChild(leftTip);\n      }\n\n      const lineBox = document.createElement('div');\n      lineBox.style.display = 'flex';\n      lineBox.style.alignItems = 'center';\n      lineBox.style.minHeight = '20px';\n      lineBox.style.flexGrow = '2';\n\n      const hr = document.createElement('hr');\n      hr.style.minWidth = '20px';\n      hr.style.border = '0px';\n      hr.style.borderTop = `3px solid ${Style.settings.toolboxColor}`;\n      hr.style.flexGrow = '2';\n      lineBox.appendChild(hr);\n\n      typeBoxContainer.appendChild(lineBox);\n\n      if (arrowType === 'both' || arrowType === 'end') {\n        const rightTip = document.createElement('div');\n        rightTip.style.display = 'flex';\n        rightTip.style.alignItems = 'center';\n        rightTip.style.minHeight = '20px';\n        rightTip.innerHTML = `<svg viewBox=\"0 0 10 10\" width=\"10\" height=\"10\" xmlns=\"http://www.w3.org/2000/svg\">\n          <polygon points=\"0,0 10,5 0,10\" fill=\"${Style.settings.toolboxColor}\" />\n        </svg>`;\n        rightTip.style.marginRight = '5px';\n        typeBoxContainer.appendChild(rightTip);\n      }\n\n      this.typeBoxes.push(typeBoxContainer);\n    }\n    return panelDiv;\n  }\n\n  private setCurrentType(newType: ArrowType, target: HTMLDivElement) {\n    this.currentType = newType;\n\n    this.typeBoxes.forEach(box => {\n      box.style.borderColor = box === target ? Style.settings.toolboxAccentColor : 'transparent';\n    });\n\n    if (this.onArrowTypeChanged) {\n      this.onArrowTypeChanged(this.currentType);\n    }\n  }\n}\n","import { IPoint } from '../../core/IPoint';\nimport { SvgHelper } from '../../core/SvgHelper';\nimport { Settings } from '../../core/Settings';\nimport Icon from './arrow-marker-icon.svg';\nimport { ToolboxPanel } from '../../ui/ToolboxPanel';\nimport { LineMarker } from '../line-marker/LineMarker';\nimport { ArrowType, ArrowTypePanel } from '../../ui/toolbox-panels/ArrowTypePanel';\nimport { ArrowMarkerState } from './ArrowMarkerState';\nimport { MarkerBaseState } from '../../core/MarkerBaseState';\n\n/**\n * Represents an arrow marker.\n */\nexport class ArrowMarker extends LineMarker {\n  /**\n   * String type name of the marker type. \n   * \n   * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static typeName = 'ArrowMarker';\n\n  /**\n   * Marker type title (display name) used for accessibility and other attributes.\n   */\n  public static title = 'Arrow marker';\n  /**\n   * SVG icon markup displayed on toolbar buttons.\n   */\n  public static icon = Icon;\n\n  private arrow1: SVGPolygonElement;\n  private arrow2: SVGPolygonElement;\n\n  private arrowType: ArrowType = 'end';\n\n  private arrowBaseHeight = 10;\n  private arrowBaseWidth = 10;\n\n  /**\n   * Toolbox panel for arrow type selection.\n   */\n  protected arrowTypePanel: ArrowTypePanel;\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.\n   * @param settings - settings object containing default markers settings.\n   */\n  constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings) {\n    super(container, overlayContainer, settings);\n\n    this.getArrowPoints = this.getArrowPoints.bind(this);\n    this.setArrowType = this.setArrowType.bind(this);\n\n    this.arrowTypePanel = new ArrowTypePanel('Arrow type', 'end');\n    this.arrowTypePanel.onArrowTypeChanged = this.setArrowType;\n  }\n\n  /**\n   * Returns true if passed SVG element belongs to the marker. False otherwise.\n   * \n   * @param el - target element.\n   */\n  public ownsTarget(el: EventTarget): boolean {\n    if (\n      super.ownsTarget(el) ||\n      el === this.arrow1 || el === this.arrow2\n    ) {\n      return true;\n    } else {\n      return false;\n    }\n  }\n\n  private getArrowPoints(offsetX: number, offsetY: number): string {\n    const width = this.arrowBaseWidth + this.strokeWidth * 2;\n    const height = this.arrowBaseHeight + this.strokeWidth * 2;\n    return `${offsetX - width / 2},${\n      offsetY + height / 2\n    } ${offsetX},${offsetY - height / 2} ${\n      offsetX + width / 2},${offsetY + height / 2}`;\n  }\n\n  private createTips() {\n    this.arrow1 = SvgHelper.createPolygon(this.getArrowPoints(this.x1, this.y1), [['fill', this.strokeColor]]);\n    this.arrow1.transform.baseVal.appendItem(SvgHelper.createTransform());\n    this.visual.appendChild(this.arrow1);\n\n    this.arrow2 = SvgHelper.createPolygon(this.getArrowPoints(this.x2, this.y2), [['fill', this.strokeColor]]);\n    this.arrow2.transform.baseVal.appendItem(SvgHelper.createTransform());\n    this.visual.appendChild(this.arrow2);\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) down event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerDown(point: IPoint, target?: EventTarget): void {\n    super.pointerDown(point, target);\n    if (this.state === 'creating') {\n      this.createTips();\n    }\n  }\n\n  /**\n   * Adjusts marker visual after manipulation.\n   */\n  protected adjustVisual(): void {\n    super.adjustVisual();\n\n    if (this.arrow1 && this.arrow2) {\n      this.arrow1.style.display = (this.arrowType === 'both' || this.arrowType === 'start') ? '' : 'none';\n      this.arrow2.style.display = (this.arrowType === 'both' || this.arrowType === 'end') ? '' : 'none';\n\n      SvgHelper.setAttributes(this.arrow1, [\n        ['points', this.getArrowPoints(this.x1, this.y1)],\n        ['fill', this.strokeColor]\n      ]);\n      SvgHelper.setAttributes(this.arrow2, [\n        ['points', this.getArrowPoints(this.x2, this.y2)],\n        ['fill', this.strokeColor]\n      ]);\n\n      if (Math.abs(this.x1 - this.x2) > 0.1) {\n        const lineAngle1 =\n          (Math.atan((this.y2 - this.y1) / (this.x2 - this.x1)) * 180) / Math.PI + 90 * Math.sign(this.x1 - this.x2);\n\n        const a1transform = this.arrow1.transform.baseVal.getItem(0);\n        a1transform.setRotate(lineAngle1, this.x1, this.y1);\n        this.arrow1.transform.baseVal.replaceItem(a1transform, 0);\n\n        const a2transform = this.arrow2.transform.baseVal.getItem(0);\n        a2transform.setRotate(lineAngle1 + 180, this.x2, this.y2);\n        this.arrow2.transform.baseVal.replaceItem(a2transform, 0);\n      }\n    }\n  }\n\n  private setArrowType(arrowType: ArrowType) {\n    this.arrowType = arrowType;\n    this.adjustVisual();\n  }\n\n  /**\n   * Returns the list of toolbox panels for this marker type.\n   */\n  public get toolboxPanels(): ToolboxPanel[] {\n    return [this.strokePanel, this.strokeWidthPanel, this.strokeStylePanel, this.arrowTypePanel];\n  }\n\n  /**\n   * Returns current marker state that can be restored in the future.\n   */\n  public getState(): ArrowMarkerState {\n    const result: ArrowMarkerState = Object.assign({\n      arrowType: this.arrowType\n    }, super.getState());\n    result.typeName = ArrowMarker.typeName;\n\n    return result;\n  }\n\n  /**\n   * Restores previously saved marker state.\n   * \n   * @param state - previously saved state.\n   */\n  public restoreState(state: MarkerBaseState): void {\n    super.restoreState(state);\n\n    const amState = state as ArrowMarkerState;\n    this.arrowType = amState.arrowType;\n\n    this.createTips();\n    this.adjustVisual();\n  }\n\n}\n","import Icon from './cover-marker-icon.svg';\nimport { ToolboxPanel } from '../../ui/ToolboxPanel';\nimport { ColorPickerPanel } from '../../ui/toolbox-panels/ColorPickerPanel';\nimport { Settings } from '../../core/Settings';\nimport { RectangleMarker } from '../RectangleMarker';\nimport { RectangleMarkerState } from '../RectangleMarkerState';\n\nexport class CoverMarker extends RectangleMarker {\n  /**\n   * String type name of the marker type. \n   * \n   * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static typeName = 'CoverMarker';\n\n  /**\n   * Marker type title (display name) used for accessibility and other attributes.\n   */\n  public static title = 'Cover marker';\n  /**\n   * SVG icon markup displayed on toolbar buttons.\n   */\n  public static icon = Icon;\n\n  /**\n   * Color picker panel for the background color.\n   */\n  protected fillPanel: ColorPickerPanel;\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.\n   * @param settings - settings object containing default markers settings.\n   */\n  constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings) {\n    super(container, overlayContainer, settings);\n\n    this.fillColor = settings.defaultFillColor;\n    this.strokeWidth = 0;\n\n    this.fillPanel = new ColorPickerPanel(\n      'Color',\n      settings.defaultColorSet,\n      settings.defaultFillColor\n    );\n    this.fillPanel.onColorChanged = this.setFillColor;\n  }\n\n  /**\n   * Returns the list of toolbox panels for this marker type.\n   */\n  public get toolboxPanels(): ToolboxPanel[] {\n    return [this.fillPanel];\n  }\n\n  /**\n   * Returns current marker state that can be restored in the future.\n   */\n  public getState(): RectangleMarkerState {\n    const result = super.getState();\n    result.typeName = CoverMarker.typeName;\n    return result;\n  }\n}\n","import { Style } from '../../core/Style';\nimport { ToolboxPanel } from '../ToolboxPanel';\nimport Icon from './opacity-panel-icon.svg';\n\n/**\n * Opacity chage event handler type.\n */\nexport type OpacityChangeHandler = (newOpacity: number) => void;\n\n/**\n * Opacity panel.\n */\nexport class OpacityPanel extends ToolboxPanel {\n  private opacities: number[] = [];\n  private currentOpacity?: number;\n\n  private opacityBoxes: HTMLDivElement[] = [];\n\n  /**\n   * Opacity change event handler.\n   */\n  public onOpacityChanged?: OpacityChangeHandler;\n\n  /**\n   * Creates an opacity panel.\n   * @param title - panel title.\n   * @param opacities - available opacities.\n   * @param currentOpacity - current opacity.\n   * @param icon - toolbox panel button (SVG image markup).\n   */\n  constructor(title: string, opacities: number[], currentOpacity?: number, icon?: string) {\n    super(title, icon ? icon : Icon);\n    this.opacities = opacities;\n    this.currentOpacity = currentOpacity;\n\n    this.setCurrentOpacity = this.setCurrentOpacity.bind(this);\n  }\n\n  /**\n   * Returns panel UI.\n   */\n  public getUi(): HTMLDivElement {\n    const panelDiv = document.createElement('div');\n    panelDiv.style.display = 'flex';\n    panelDiv.style.overflow = 'hidden';\n    panelDiv.style.flexGrow = '2';\n    panelDiv.style.justifyContent = 'space-between';\n    this.opacities.forEach((opacity) => {\n      const opacityBoxContainer = document.createElement('div');\n      opacityBoxContainer.style.display = 'flex';\n      //opacityBoxContainer.style.flexGrow = '2';\n      opacityBoxContainer.style.alignItems = 'center';\n      opacityBoxContainer.style.justifyContent = 'center';\n      opacityBoxContainer.style.padding = '5px';\n      opacityBoxContainer.style.borderWidth = '2px';\n      opacityBoxContainer.style.borderStyle = 'solid';\n      opacityBoxContainer.style.borderColor =\n        opacity === this.currentOpacity ? Style.settings.toolboxAccentColor : 'transparent';\n\n      opacityBoxContainer.addEventListener('click', () => {\n        this.setCurrentOpacity(opacity, opacityBoxContainer);\n      })\n      panelDiv.appendChild(opacityBoxContainer);\n\n      const label = document.createElement('div');\n      label.innerText = `${(opacity * 100)}%`;\n      opacityBoxContainer.appendChild(label);\n\n      this.opacityBoxes.push(opacityBoxContainer);\n    });\n    return panelDiv;\n  }\n\n  private setCurrentOpacity(newWidth: number, target: HTMLDivElement) {\n    this.currentOpacity = newWidth;\n\n    this.opacityBoxes.forEach(box => {\n      box.style.borderColor = box === target ? Style.settings.toolboxAccentColor : 'transparent';\n    });\n\n    if (this.onOpacityChanged) {\n      this.onOpacityChanged(this.currentOpacity);\n    }\n  }\n}\n","import Icon from './highlight-marker-icon.svg';\nimport { ToolboxPanel } from '../../ui/ToolboxPanel';\nimport { ColorPickerPanel } from '../../ui/toolbox-panels/ColorPickerPanel';\nimport { Settings } from '../../core/Settings';\nimport { CoverMarker } from '../cover-marker/CoverMarker';\nimport { OpacityPanel } from '../../ui/toolbox-panels/OpacityPanel';\nimport { SvgHelper } from '../../core/SvgHelper';\nimport { RectangleMarkerState } from '../RectangleMarkerState';\n\nexport class HighlightMarker extends CoverMarker {\n  /**\n   * String type name of the marker type. \n   * \n   * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static typeName = 'HighlightMarker';\n  /**\n   * Marker type title (display name) used for accessibility and other attributes.\n   */\n  public static title = 'Highlight marker';\n  /**\n   * SVG icon markup displayed on toolbar buttons.\n   */\n  public static icon = Icon;\n\n  protected opacityPanel: OpacityPanel;\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.\n   * @param settings - settings object containing default markers settings.\n   */\n  constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings) {\n    super(container, overlayContainer, settings);\n\n    this.setOpacity = this.setOpacity.bind(this);\n\n    this.fillColor = settings.defaultHighlightColor;\n    this.strokeWidth = 0;\n    this.opacity = settings.defaultHighlightOpacity;\n\n    this.fillPanel = new ColorPickerPanel(\n      'Color',\n      settings.defaultColorSet,\n      this.fillColor\n    );\n    this.fillPanel.onColorChanged = this.setFillColor;\n\n    this.opacityPanel = new OpacityPanel(\n      'Opacity',\n      settings.defaultOpacitySteps,\n      this.opacity\n    );\n    this.opacityPanel.onOpacityChanged = this.setOpacity;\n  }\n\n  /**\n   * Sets marker's opacity (0..1).\n   * @param opacity - new opacity value.\n   */\n  protected setOpacity(opacity: number): void {\n    this.opacity = opacity;\n    if (this.visual) {\n      SvgHelper.setAttributes(this.visual, [['opacity', this.opacity.toString()]]);\n    }\n  }\n\n  /**\n   * Returns the list of toolbox panels for this marker type.\n   */\n  public get toolboxPanels(): ToolboxPanel[] {\n    return [this.fillPanel, this.opacityPanel];\n  }\n\n  /**\n   * Returns current marker state that can be restored in the future.\n   */\n  public getState(): RectangleMarkerState {\n    const result = super.getState();\n    result.typeName = HighlightMarker.typeName;\n    return result;\n  }\n}\n","import { IPoint } from '../../core/IPoint';\nimport { SvgHelper } from '../../core/SvgHelper';\nimport { Settings } from '../../core/Settings';\nimport Icon from './callout-marker-icon.svg';\nimport TextColorIcon from '../../ui/toolbox-panels/text-color-icon.svg';\nimport FillColorIcon from '../../ui/toolbox-panels/fill-color-icon.svg';\nimport { ColorPickerPanel } from '../../ui/toolbox-panels/ColorPickerPanel';\nimport { ToolboxPanel } from '../../ui/ToolboxPanel';\nimport { FontFamilyPanel } from '../../ui/toolbox-panels/FontFamilyPanel';\nimport { TextMarker } from '../text-marker/TextMarker';\nimport { ResizeGrip } from '../ResizeGrip';\nimport { CalloutMarkerState } from './CalloutMarkerState';\nimport { MarkerBaseState } from '../../core/MarkerBaseState';\n\nexport class CalloutMarker extends TextMarker {\n  /**\n   * String type name of the marker type. \n   * \n   * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static typeName = 'CalloutMarker';\n\n  /**\n   * Marker type title (display name) used for accessibility and other attributes.\n   */\n  public static title = 'Callout marker';\n  /**\n   * SVG icon markup displayed on toolbar buttons.\n   */\n  public static icon = Icon;\n\n  private bgColor = 'transparent';\n  /**\n   * Color picker toolbox panel for the background (fill) color.\n   */\n  protected bgColorPanel: ColorPickerPanel;\n\n  private tipPosition: IPoint = { x: 0, y: 0 };\n  private tipBase1Position: IPoint = { x: 0, y: 0 };\n  private tipBase2Position: IPoint = { x: 0, y: 0 };\n  private tip: SVGPolygonElement;\n  private tipGrip: ResizeGrip;\n  private tipMoving = false;\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.\n   * @param settings - settings object containing default markers settings.\n   */\n  constructor(\n    container: SVGGElement,\n    overlayContainer: HTMLDivElement,\n    settings: Settings\n  ) {\n    super(container, overlayContainer, settings);\n\n    this.color = settings.defaultStrokeColor;\n    this.bgColor = settings.defaultFillColor;\n    this.fontFamily = settings.defaultFontFamily;\n\n    this.defaultSize = { x: 100, y: 30 };\n\n    this.setBgColor = this.setBgColor.bind(this);\n    this.getTipPoints = this.getTipPoints.bind(this);\n    this.positionTip = this.positionTip.bind(this);\n    this.setTipPoints = this.setTipPoints.bind(this);\n\n    this.colorPanel = new ColorPickerPanel(\n      'Text color',\n      settings.defaultColorSet,\n      this.color,\n      TextColorIcon\n    );\n    this.colorPanel.onColorChanged = this.setColor;\n\n    this.bgColorPanel = new ColorPickerPanel(\n      'Fill color',\n      settings.defaultColorSet,\n      this.bgColor,\n      FillColorIcon\n    );\n    this.bgColorPanel.onColorChanged = this.setBgColor;\n\n    this.fontFamilyPanel = new FontFamilyPanel(\n      'Font',\n      settings.defaultFontFamilies,\n      settings.defaultFontFamily\n    );\n    this.fontFamilyPanel.onFontChanged = this.setFont;\n\n    this.tipGrip = new ResizeGrip();\n    this.tipGrip.visual.transform.baseVal.appendItem(\n      SvgHelper.createTransform()\n    );\n    this.controlBox.appendChild(this.tipGrip.visual);\n  }\n\n  /**\n   * Returns true if passed SVG element belongs to the marker. False otherwise.\n   * \n   * @param el - target element.\n   */\n  public ownsTarget(el: EventTarget): boolean {\n    return (\n      super.ownsTarget(el) || this.tipGrip.ownsTarget(el) || this.tip === el\n    );\n  }\n\n  private createTip() {\n    SvgHelper.setAttributes(this.bgRectangle, [\n      ['fill', this.bgColor],\n      ['rx', '10px'],\n    ]);\n\n    this.tip = SvgHelper.createPolygon(this.getTipPoints(), [\n      ['fill', this.bgColor],\n    ]);\n    this.visual.appendChild(this.tip);\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) down event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerDown(point: IPoint, target?: EventTarget): void {\n    if (this.state === 'new') {\n      super.pointerDown(point, target);\n    }\n\n    if (this.state === 'creating') {\n      this.createTip();\n    } else if (this.tipGrip.ownsTarget(target)) {\n      this.manipulationStartLeft = this.left;\n      this.manipulationStartTop = this.top;\n      this.tipMoving = true;\n    } else {\n      super.pointerDown(point, target);\n    }\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) up event.\n   * \n   * @param point - event coordinates.\n   */\n  public pointerUp(point: IPoint): void {\n    if (this.tipMoving) {\n      this.tipMoving = false;\n    } else {\n      const isCreating = this.state === 'creating';\n      super.pointerUp(point);\n      this.setTipPoints(isCreating);\n      this.positionTip();\n    }\n  }\n\n  /**\n   * Handles marker manipulation (move, resize, rotate, etc.).\n   * \n   * @param point - event coordinates.\n   */\n  public manipulate(point: IPoint): void {\n    if (this.tipMoving) {\n      const rotatedPoint = this.unrotatePoint(point);\n      this.tipPosition = {\n        x: rotatedPoint.x - this.manipulationStartLeft,\n        y: rotatedPoint.y - this.manipulationStartTop,\n      };\n      this.positionTip();\n    } else {\n      super.manipulate(point);\n    }\n  }\n\n  /**\n   * Sets marker's background/fill color.\n   * @param color - new background color.\n   */\n  protected setBgColor(color: string): void {\n    if (this.bgRectangle && this.tip) {\n      SvgHelper.setAttributes(this.bgRectangle, [['fill', color]]);\n      SvgHelper.setAttributes(this.tip, [['fill', color]]);\n    }\n    this.bgColor = color;\n    this.fillColorChanged(color);\n  }\n\n  private getTipPoints(): string {\n    this.setTipPoints(this.state === 'creating');\n    return `${this.tipBase1Position.x},${this.tipBase1Position.y\n      } ${this.tipBase2Position.x},${this.tipBase2Position.y\n      } ${this.tipPosition.x},${this.tipPosition.y}`;\n  }\n\n  private setTipPoints(isCreating = false) {\n    let offset = Math.min(this.height / 2, 15);\n    let baseWidth = this.height / 5;\n    if (isCreating) {\n      this.tipPosition = { x: offset + baseWidth / 2, y: this.height + 20 };\n    }\n\n    const cornerAngle = Math.atan((this.height / 2) / (this.width / 2));\n    if (this.tipPosition.x < this.width / 2 && this.tipPosition.y < this.height / 2) {\n      // top left\n      const tipAngle = Math.atan((this.height / 2 - this.tipPosition.y) / (this.width / 2 - this.tipPosition.x));\n      if (cornerAngle < tipAngle) {\n        baseWidth = this.width / 5;\n        offset = Math.min(this.width / 2, 15);\n        this.tipBase1Position = { x: offset, y: 0 };\n        this.tipBase2Position = { x: offset + baseWidth, y: 0 };\n      } else {\n        this.tipBase1Position = { x: 0, y: offset };\n        this.tipBase2Position = { x: 0, y: offset + baseWidth };\n      }\n    } else if (this.tipPosition.x >= this.width / 2 && this.tipPosition.y < this.height / 2) {\n      // top right\n      const tipAngle = Math.atan((this.height / 2 - this.tipPosition.y) / (this.tipPosition.x - this.width / 2));\n      if (cornerAngle < tipAngle) {\n        baseWidth = this.width / 5;\n        offset = Math.min(this.width / 2, 15);\n        this.tipBase1Position = { x: this.width - offset - baseWidth, y: 0 };\n        this.tipBase2Position = { x: this.width - offset, y: 0 };\n      } else {\n        this.tipBase1Position = { x: this.width, y: offset };\n        this.tipBase2Position = { x: this.width, y: offset + baseWidth };\n      }\n    } else if (this.tipPosition.x >= this.width / 2 && this.tipPosition.y >= this.height / 2) {\n      // bottom right\n      const tipAngle = Math.atan((this.tipPosition.y - this.height / 2) / (this.tipPosition.x - this.width / 2));\n      if (cornerAngle < tipAngle) {\n        baseWidth = this.width / 5;\n        offset = Math.min(this.width / 2, 15);\n        this.tipBase1Position = { x: this.width - offset - baseWidth, y: this.height };\n        this.tipBase2Position = { x: this.width - offset, y: this.height };\n      } else {\n        this.tipBase1Position = { x: this.width, y: this.height - offset - baseWidth };\n        this.tipBase2Position = { x: this.width, y: this.height - offset };\n      }\n    } else {\n      // bottom left\n      const tipAngle = Math.atan((this.tipPosition.y - this.height / 2) / (this.width / 2 - this.tipPosition.x));\n      if (cornerAngle < tipAngle) {\n        baseWidth = this.width / 5;\n        offset = Math.min(this.width / 2, 15);\n        this.tipBase1Position = { x: offset, y: this.height };\n        this.tipBase2Position = { x: offset + baseWidth, y: this.height };\n      } else {\n        this.tipBase1Position = { x: 0, y: this.height - offset };\n        this.tipBase2Position = { x: 0, y: this.height - offset - baseWidth };\n      }\n    }\n  }\n\n  /**\n   * Resize marker based on current pointer coordinates and context.\n   * @param point \n   */\n  protected resize(point: IPoint): void {\n    super.resize(point);\n    this.positionTip();\n  }\n\n  private positionTip() {\n    SvgHelper.setAttributes(this.tip, [['points', this.getTipPoints()]]);\n    const translate = this.tipGrip.visual.transform.baseVal.getItem(0);\n    translate.setTranslate(this.tipPosition.x, this.tipPosition.y);\n    this.tipGrip.visual.transform.baseVal.replaceItem(translate, 0);\n  }\n\n  /**\n   * Returns the list of toolbox panels for this marker type.\n   */\n  public get toolboxPanels(): ToolboxPanel[] {\n    return [this.colorPanel, this.bgColorPanel, this.fontFamilyPanel];\n  }\n\n  /**\n   * Selects this marker and displays appropriate selected marker UI.\n   */\n  public select(): void {\n    this.positionTip();\n    super.select();\n  }\n\n  /**\n   * Returns current marker state that can be restored in the future.\n   */\n  public getState(): CalloutMarkerState {\n    const result: CalloutMarkerState = Object.assign({\n      bgColor: this.bgColor,\n      tipPosition: this.tipPosition\n    }, super.getState());\n    result.typeName = CalloutMarker.typeName;\n\n    return result;\n  }\n\n  /**\n   * Restores previously saved marker state.\n   * \n   * @param state - previously saved state.\n   */\n  public restoreState(state: MarkerBaseState): void {\n    const calloutState = state as CalloutMarkerState;\n    this.bgColor = calloutState.bgColor;\n    this.tipPosition = calloutState.tipPosition;\n\n    super.restoreState(state);\n    this.createTip();\n    this.setTipPoints();\n  }\n\n  /**\n   * Scales marker. Used after the image resize.\n   * \n   * @param scaleX - horizontal scale\n   * @param scaleY - vertical scale\n   */\n  public scale(scaleX: number, scaleY: number): void {\n    super.scale(scaleX, scaleY);\n\n    this.tipPosition = {x: this.tipPosition.x * scaleX, y: this.tipPosition.y * scaleY};\n\n    this.positionTip();\n  }\n}\n","import Icon from './ellipse-marker-icon.svg';\nimport { IPoint } from '../../core/IPoint';\nimport { SvgHelper } from '../../core/SvgHelper';\nimport { RectangularBoxMarkerBase } from '../RectangularBoxMarkerBase';\nimport { Settings } from '../../core/Settings';\nimport { RectangleMarkerState } from '../RectangleMarkerState';\nimport { MarkerBaseState } from '../../core/MarkerBaseState';\nimport { ColorPickerPanel } from '../../ui/toolbox-panels/ColorPickerPanel';\nimport { LineWidthPanel } from '../../ui/toolbox-panels/LineWidthPanel';\nimport { LineStylePanel } from '../../ui/toolbox-panels/LineStylePanel';\nimport { ToolboxPanel } from '../../ui/ToolboxPanel';\nimport FillColorIcon from '../../ui/toolbox-panels/fill-color-icon.svg';\nimport { OpacityPanel } from '../../ui/toolbox-panels/OpacityPanel';\n\nexport class EllipseMarker extends RectangularBoxMarkerBase {\n  /**\n   * String type name of the marker type. \n   * \n   * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static typeName = 'EllipseMarker';\n  /**\n   * Marker type title (display name) used for accessibility and other attributes.\n   */\n  public static title = 'Ellipse marker';\n  /**\n   * SVG icon markup displayed on toolbar buttons.\n   */\n  public static icon = Icon;\n\n  /**\n   * Ellipse fill color.\n   */\n  protected fillColor = 'transparent';\n  /**\n   * Ellipse border color.\n   */\n  protected strokeColor = 'transparent';\n  /**\n   * Ellipse border line width.\n   */\n  protected strokeWidth = 0;\n  /**\n   * Ellipse border dash array.\n   */\n  protected strokeDasharray = '';\n  /**\n   * Ellipse opacity (0..1).\n   */\n  protected opacity = 1;\n\n  protected strokePanel: ColorPickerPanel;\n  protected fillPanel: ColorPickerPanel;\n  protected strokeWidthPanel: LineWidthPanel;\n  protected strokeStylePanel: LineStylePanel;\n  protected opacityPanel: OpacityPanel;\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.\n   * @param settings - settings object containing default markers settings.\n   */\n  constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings) {\n    super(container, overlayContainer, settings);\n\n    this.strokeColor = settings.defaultColor;\n    this.strokeWidth = settings.defaultStrokeWidth;\n    this.strokeDasharray = settings.defaultStrokeDasharray;\n    this.fillColor = settings.defaultFillColor;\n\n    this.setStrokeColor = this.setStrokeColor.bind(this);\n    this.setFillColor = this.setFillColor.bind(this);\n    this.setStrokeWidth = this.setStrokeWidth.bind(this);\n    this.setStrokeDasharray = this.setStrokeDasharray.bind(this);\n    this.setOpacity = this.setOpacity.bind(this);\n    this.createVisual = this.createVisual.bind(this);\n\n    this.strokePanel = new ColorPickerPanel(\n      'Line color',\n      [...settings.defaultColorSet, 'transparent'],\n      settings.defaultColor\n    );\n    this.strokePanel.onColorChanged = this.setStrokeColor;\n\n    this.fillPanel = new ColorPickerPanel(\n      'Fill color',\n      [...settings.defaultColorSet, 'transparent'],\n      this.fillColor,\n      FillColorIcon\n    );\n    this.fillPanel.onColorChanged = this.setFillColor;\n\n    this.strokeWidthPanel = new LineWidthPanel(\n      'Line width',\n      settings.defaultStrokeWidths,\n      settings.defaultStrokeWidth\n    );\n    this.strokeWidthPanel.onWidthChanged = this.setStrokeWidth;\n\n    this.strokeStylePanel = new LineStylePanel(\n      'Line style',\n      settings.defaultStrokeDasharrays,\n      settings.defaultStrokeDasharray\n    );\n    this.strokeStylePanel.onStyleChanged = this.setStrokeDasharray;\n\n    this.opacityPanel = new OpacityPanel(\n      'Opacity',\n      settings.defaultOpacitySteps,\n      this.opacity\n    );\n    this.opacityPanel.onOpacityChanged = this.setOpacity;\n  }\n\n  /**\n   * Returns true if passed SVG element belongs to the marker. False otherwise.\n   * \n   * @param el - target element.\n   */\n  public ownsTarget(el: EventTarget): boolean {\n    if (super.ownsTarget(el) || el === this.visual) {\n      return true;\n    } else {\n      return false;\n    }\n  }\n\n  /**\n   * Creates marker visual.\n   */\n  protected createVisual(): void {\n    this.visual = SvgHelper.createEllipse(this.width / 2, this.height / 2, [\n      ['fill', this.fillColor],\n      ['stroke', this.strokeColor],\n      ['stroke-width', this.strokeWidth.toString()],\n      ['stroke-dasharray', this.strokeDasharray],\n      ['opacity', this.opacity.toString()]\n    ]);\n    this.addMarkerVisualToContainer(this.visual);\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) down event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerDown(point: IPoint, target?: EventTarget): void {\n    super.pointerDown(point, target);\n    if (this.state === 'new') {\n      this.createVisual();\n\n      this.moveVisual(point);\n\n      this._state = 'creating';\n    }\n  }\n\n  /**\n   * Handles marker manipulation (move, resize, rotate, etc.).\n   * \n   * @param point - event coordinates.\n   */\n  public manipulate(point: IPoint): void {\n    super.manipulate(point);\n  }\n\n  /**\n   * Resize marker based on current pointer coordinates and context.\n   * @param point \n   */\n  protected resize(point: IPoint): void {\n    super.resize(point);\n    this.setSize();\n  }\n\n  /**\n   * Sets marker's visual size after manipulation.\n   */\n  protected setSize(): void {\n    super.setSize();\n    SvgHelper.setAttributes(this.visual, [\n      ['cx', (this.width / 2).toString()],\n      ['cy', (this.height / 2).toString()],\n      ['rx', (this.width / 2).toString()],\n      ['ry', (this.height / 2).toString()],\n    ]);\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) up event.\n   * \n   * @param point - event coordinates.\n   */\n  public pointerUp(point: IPoint): void {\n    super.pointerUp(point);\n    this.setSize();\n  }\n\n  /**\n   * Sets marker's line color.\n   * @param color - new line color.\n   */\n  protected setStrokeColor(color: string): void {\n    this.strokeColor = color;\n    if (this.visual) {\n      SvgHelper.setAttributes(this.visual, [['stroke', this.strokeColor]]);\n    }\n    this.colorChanged(color);\n  }\n  /**\n   * Sets marker's fill (background) color.\n   * @param color - new fill color.\n   */\n  protected setFillColor(color: string): void {\n    this.fillColor = color;\n    if (this.visual) {\n      SvgHelper.setAttributes(this.visual, [['fill', this.fillColor]]);\n    }\n    this.fillColorChanged(color);\n  }\n  /**\n   * Sets marker's line width.\n   * @param width - new line width\n   */\n  protected setStrokeWidth(width: number): void {\n    this.strokeWidth = width;\n    if (this.visual) {\n      SvgHelper.setAttributes(this.visual, [['stroke-width', this.strokeWidth.toString()]]);\n    }\n  }\n  /**\n   * Sets marker's border dash array.\n   * @param dashes - new dash array.\n   */\n  protected setStrokeDasharray(dashes: string): void {\n    this.strokeDasharray = dashes;\n    if (this.visual) {\n      SvgHelper.setAttributes(this.visual, [['stroke-dasharray', this.strokeDasharray]]);\n    }\n  }\n  /**\n   * Sets marker's opacity.\n   * @param opacity - new opacity value (0..1).\n   */\n  protected setOpacity(opacity: number): void {\n    this.opacity = opacity;\n    if (this.visual) {\n      SvgHelper.setAttributes(this.visual, [['opacity', this.opacity.toString()]]);\n    }\n  }\n\n  /**\n   * Returns the list of toolbox panels for this marker type.\n   */\n  public get toolboxPanels(): ToolboxPanel[] {\n    return [this.strokePanel, this.fillPanel, this.strokeWidthPanel, this.strokeStylePanel, this.opacityPanel];\n  }\n\n  /**\n   * Returns current marker state that can be restored in the future.\n   */\n  public getState(): RectangleMarkerState {\n    const result: RectangleMarkerState = Object.assign({\n      fillColor: this.fillColor,\n      strokeColor: this.strokeColor,\n      strokeWidth: this.strokeWidth,\n      strokeDasharray: this.strokeDasharray,\n      opacity: this.opacity\n    }, super.getState());\n    result.typeName = EllipseMarker.typeName;\n\n    return result;\n  }\n\n  /**\n   * Restores previously saved marker state.\n   * \n   * @param state - previously saved state.\n   */\n  public restoreState(state: MarkerBaseState): void {\n    const rectState = state as RectangleMarkerState;\n    this.fillColor = rectState.fillColor;\n    this.strokeColor = rectState.strokeColor;\n    this.strokeWidth = rectState.strokeWidth;\n    this.strokeDasharray = rectState.strokeDasharray;\n    this.opacity = rectState.opacity;\n\n    this.createVisual();\n    super.restoreState(state);\n    this.setSize();\n  }\n\n  /**\n   * Scales marker. Used after the image resize.\n   * \n   * @param scaleX - horizontal scale\n   * @param scaleY - vertical scale\n   */\n  public scale(scaleX: number, scaleY: number): void {\n    super.scale(scaleX, scaleY);\n\n    this.setSize();\n  }\n}\n","import { IPoint } from '../../core/IPoint';\nimport { SvgHelper } from '../../core/SvgHelper';\nimport { Settings } from '../../core/Settings';\nimport Icon from './measurement-marker-icon.svg';\nimport { ToolboxPanel } from '../../ui/ToolboxPanel';\nimport { LineMarker } from '../line-marker/LineMarker';\nimport { MarkerBaseState } from '../../core/MarkerBaseState';\nimport { LineMarkerState } from '../line-marker/LineMarkerState';\n\nexport class MeasurementMarker extends LineMarker {\n  /**\n   * String type name of the marker type. \n   * \n   * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static typeName = 'MeasurementMarker';\n\n  /**\n   * Marker type title (display name) used for accessibility and other attributes.\n   */\n  public static title = 'Measurement marker';\n  /**\n   * SVG icon markup displayed on toolbar buttons.\n   */\n  public static icon = Icon;\n\n  private tip1: SVGLineElement;\n  private tip2: SVGLineElement;\n\n  private get tipLength(): number {\n    return 10 + this.strokeWidth * 3;\n  }\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.\n   * @param settings - settings object containing default markers settings.\n   */\n  constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings) {\n    super(container, overlayContainer, settings);\n  }\n\n  /**\n   * Returns true if passed SVG element belongs to the marker. False otherwise.\n   * \n   * @param el - target element.\n   */\n  public ownsTarget(el: EventTarget): boolean {\n    if (\n      super.ownsTarget(el) ||\n      el === this.tip1 || el === this.tip2\n    ) {\n      return true;\n    } else {\n      return false;\n    }\n  }\n\n  private createTips() {\n    this.tip1 = SvgHelper.createLine(\n      this.x1 - this.tipLength / 2, \n      this.y1, \n      this.x1 + this.tipLength / 2, \n      this.y1, \n      [\n        ['stroke', this.strokeColor],\n        ['stroke-width', this.strokeWidth.toString()]\n      ]);\n    this.tip1.transform.baseVal.appendItem(SvgHelper.createTransform());\n    this.visual.appendChild(this.tip1);\n\n    this.tip2 = SvgHelper.createLine(\n      this.x2 - this.tipLength / 2, \n      this.y2, \n      this.x2 + this.tipLength / 2, \n      this.y2, \n      [\n        ['stroke', this.strokeColor],\n        ['stroke-width', this.strokeWidth.toString()]\n      ]);\n    this.tip2.transform.baseVal.appendItem(SvgHelper.createTransform());\n    this.visual.appendChild(this.tip2);\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) down event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerDown(point: IPoint, target?: EventTarget): void {\n    super.pointerDown(point, target);\n    if (this.state === 'creating') {\n      this.createTips();\n    }\n  }\n\n  /**\n   * Adjusts marker visual after manipulation.\n   */\n  protected adjustVisual(): void {\n    super.adjustVisual();\n\n    if (this.tip1 && this.tip2) {\n\n      SvgHelper.setAttributes(this.tip1,[\n        ['x1', (this.x1 - this.tipLength / 2).toString()], \n        ['y1', this.y1.toString()], \n        ['x2', (this.x1 + this.tipLength / 2).toString()], \n        ['y2', this.y1.toString()], \n        ['stroke', this.strokeColor],\n        ['stroke-width', this.strokeWidth.toString()]\n      ]);\n      SvgHelper.setAttributes(this.tip2,[\n        ['x1', (this.x2 - this.tipLength / 2).toString()], \n        ['y1', this.y2.toString()], \n        ['x2', (this.x2 + this.tipLength / 2).toString()], \n        ['y2', this.y2.toString()], \n        ['stroke', this.strokeColor],\n        ['stroke-width', this.strokeWidth.toString()]\n      ]);\n\n      if (Math.abs(this.x1 - this.x2) > 0.1) {\n        const lineAngle1 =\n          (Math.atan((this.y2 - this.y1) / (this.x2 - this.x1)) * 180) / Math.PI + 90 * Math.sign(this.x1 - this.x2);\n\n        const a1transform = this.tip1.transform.baseVal.getItem(0);\n        a1transform.setRotate(lineAngle1, this.x1, this.y1);\n        this.tip1.transform.baseVal.replaceItem(a1transform, 0);\n\n        const a2transform = this.tip2.transform.baseVal.getItem(0);\n        a2transform.setRotate(lineAngle1 + 180, this.x2, this.y2);\n        this.tip2.transform.baseVal.replaceItem(a2transform, 0);\n      }\n    }\n  }\n\n  /**\n   * Returns the list of toolbox panels for this marker type.\n   */\n  public get toolboxPanels(): ToolboxPanel[] {\n    return [this.strokePanel, this.strokeWidthPanel, this.strokeStylePanel];\n  }\n\n  /**\n   * Returns current marker state that can be restored in the future.\n   */\n  public getState(): LineMarkerState {\n    const result =super.getState();\n    result.typeName = MeasurementMarker.typeName;\n\n    return result;\n  }\n\n  /**\n   * Restores previously saved marker state.\n   * \n   * @param state - previously saved state.\n   */\n  public restoreState(state: MarkerBaseState): void {\n    super.restoreState(state);\n\n    this.createTips();\n    this.adjustVisual();\n  }\n}\n","import Icon from './ellipse-frame-marker-icon.svg';\nimport { Settings } from '../../core/Settings';\nimport { RectangleMarkerState } from '../RectangleMarkerState';\nimport { ToolboxPanel } from '../../ui/ToolboxPanel';\nimport { EllipseMarker } from '../ellipse-marker/EllipseMarker';\n\nexport class EllipseFrameMarker extends EllipseMarker {\n  /**\n   * String type name of the marker type. \n   * \n   * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static typeName = 'EllipseFrameMarker';\n  /**\n   * Marker type title (display name) used for accessibility and other attributes.\n   */\n  public static title = 'Ellipse frame marker';\n  /**\n   * SVG icon markup displayed on toolbar buttons.\n   */\n  public static icon = Icon;\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.\n   * @param settings - settings object containing default markers settings.\n   */\n  constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings) {\n    super(container, overlayContainer, settings);\n\n    // reset colors so 'transparent' is excluded\n    this.strokePanel.colors= settings.defaultColorSet;\n\n    this.fillColor = 'transparent';\n  }\n\n  /**\n   * Returns the list of toolbox panels for this marker type.\n   */\n  public get toolboxPanels(): ToolboxPanel[] {\n    return [this.strokePanel, this.strokeWidthPanel, this.strokeStylePanel];\n  }\n\n  /**\n   * Returns current marker state that can be restored in the future.\n   */\n  public getState(): RectangleMarkerState {\n    const result = super.getState();\n    result.typeName = EllipseFrameMarker.typeName;\n    return result;\n  }\n}\n","/**\n * Manages undo and redo stacks.\n */\nexport class UndoRedoManager<T> {\n  private undoStack: T[] = [];\n  private redoStack: T[] = [];\n\n  private lastRedoStep: T;\n\n  /**\n   * Returns true if there are items in the undo stack.\n   */\n  public get isUndoPossible(): boolean {\n    return this.undoStack.length > 0;\n  }\n\n  /**\n   * Returns true if there are items in the redo stack.\n   */\n  public get isRedoPossible(): boolean {\n    return this.redoStack.length > 0;\n  }\n\n  /**\n   * Adds a step to the undo stack.\n   * @param stepData data representing a state.\n   */\n  public addUndoStep(stepData: T): void {\n    if (\n      this.undoStack.length === 0 ||\n      JSON.stringify(this.undoStack[this.undoStack.length - 1]) !==\n        JSON.stringify(stepData)\n    ) {\n        this.undoStack.push(stepData);\n        if (JSON.stringify(this.lastRedoStep) !== JSON.stringify(stepData)) {\n          this.redoStack.splice(0, this.redoStack.length);\n        }\n    }\n  }\n\n  /**\n   * Returns data for the previous step in the undo stack and adds last step to the redo stack.\n   * @returns \n   */\n  public undo(): T | undefined {\n    if (this.undoStack.length > 1) {\n      const lastStep = this.undoStack.pop();\n      if (lastStep !== undefined) {\n        this.redoStack.push(lastStep);\n      }\n      return this.undoStack.length > 0 ? this.undoStack[this.undoStack.length - 1] : undefined;\n    }\n  }\n\n  /**\n   * Returns most recent item in the redo stack.\n   * @returns \n   */\n  public redo(): T | undefined {\n    this.lastRedoStep = this.redoStack.pop();\n    return this.lastRedoStep;\n  }\n}\n","import { IPoint } from '../../core/IPoint';\nimport { SvgHelper } from '../../core/SvgHelper';\nimport { Settings } from '../../core/Settings';\nimport { LinearMarkerBase } from '../LinearMarkerBase';\nimport Icon from './curve-marker-icon.svg';\nimport { ColorPickerPanel } from '../../ui/toolbox-panels/ColorPickerPanel';\nimport { ToolboxPanel } from '../../ui/ToolboxPanel';\nimport { LineWidthPanel } from '../../ui/toolbox-panels/LineWidthPanel';\nimport { LineStylePanel } from '../../ui/toolbox-panels/LineStylePanel';\nimport { CurveMarkerState } from './CurveMarkerState';\nimport { MarkerBaseState } from '../../core/MarkerBaseState';\nimport { ResizeGrip } from '../ResizeGrip';\n\nexport class CurveMarker extends LinearMarkerBase {\n  /**\n   * String type name of the marker type. \n   * \n   * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static typeName = 'CurveMarker';\n  \n  /**\n   * Marker type title (display name) used for accessibility and other attributes.\n   */\n  public static title = 'Curve marker';\n  /**\n   * SVG icon markup displayed on toolbar buttons.\n   */\n  public static icon = Icon;\n\n  /**\n   * Invisible wider curve to make selection easier/possible.\n   */\n  protected selectorCurve: SVGPathElement;\n  /**\n   * Visible marker curve.\n   */\n  protected visibleCurve: SVGPathElement;\n\n  /**\n   * Line color.\n   */\n  protected strokeColor = 'transparent';\n  /**\n   * Line width.\n   */\n  protected strokeWidth = 0;\n  /**\n   * Line dash array.\n   */\n  protected strokeDasharray = '';\n\n  /**\n   * Color picker panel for line color.\n   */\n  protected strokePanel: ColorPickerPanel;\n  /**\n   * Line width toolbox panel.\n   */\n  protected strokeWidthPanel: LineWidthPanel;\n  /**\n   * Line dash array toolbox panel.\n   */\n  protected strokeStylePanel: LineStylePanel;\n\n  private curveGrip: ResizeGrip;\n  private curveX = 0;\n  private curveY = 0;\n\n  private manipulationStartCurveX = 0;\n  private manipulationStartCurveY = 0;\n\n  private curveControlLine1: SVGLineElement;\n  private curveControlLine2: SVGLineElement;\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.\n   * @param settings - settings object containing default markers settings.\n   */\n  constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings) {\n    super(container, overlayContainer, settings);\n\n    this.setStrokeColor = this.setStrokeColor.bind(this);\n    this.setStrokeWidth = this.setStrokeWidth.bind(this);\n    this.setStrokeDasharray = this.setStrokeDasharray.bind(this);\n    this.positionGrips = this.positionGrips.bind(this);\n    this.addControlGrips = this.addControlGrips.bind(this);\n    this.adjustVisual = this.adjustVisual.bind(this);\n    this.setupControlBox = this.setupControlBox.bind(this);\n    this.resize = this.resize.bind(this);\n\n    this.strokeColor = settings.defaultColor;\n    this.strokeWidth = settings.defaultStrokeWidth;\n    this.strokeDasharray = settings.defaultStrokeDasharray;\n\n    this.strokePanel = new ColorPickerPanel(\n      'Line color',\n      settings.defaultColorSet,\n      settings.defaultColor\n    );\n    this.strokePanel.onColorChanged = this.setStrokeColor;\n\n    this.strokeWidthPanel = new LineWidthPanel(\n      'Line width',\n      settings.defaultStrokeWidths,\n      settings.defaultStrokeWidth\n    );\n    this.strokeWidthPanel.onWidthChanged = this.setStrokeWidth;\n\n    this.strokeStylePanel = new LineStylePanel(\n      'Line style',\n      settings.defaultStrokeDasharrays,\n      settings.defaultStrokeDasharray\n    );\n    this.strokeStylePanel.onStyleChanged = this.setStrokeDasharray;\n  }\n\n  /**\n   * Returns true if passed SVG element belongs to the marker. False otherwise.\n   * \n   * @param el - target element.\n   */\n  public ownsTarget(el: EventTarget): boolean {\n    if (\n      super.ownsTarget(el) ||\n      el === this.visual ||\n      el === this.selectorCurve ||\n      el === this.visibleCurve ||\n      this.curveGrip.ownsTarget(el)\n    ) {\n      return true;\n    } else {\n      return false;\n    }\n  }\n\n  private getPathD(): string {\n    const result = `M ${this.x1} ${this.y1} Q ${this.curveX} ${this.curveY}, ${this.x2} ${this.y2}`;\n    return result;\n  }\n\n  private createVisual() {\n    this.visual = SvgHelper.createGroup();\n    this.selectorCurve = SvgHelper.createPath(\n      this.getPathD(),\n      [\n        ['stroke', 'transparent'],\n        ['stroke-width', (this.strokeWidth + 10).toString()],\n        ['fill', 'transparent'],\n      ]\n    );\n    this.visibleCurve = SvgHelper.createPath(\n      this.getPathD(),\n      [\n        ['stroke', this.strokeColor],\n        ['stroke-width', this.strokeWidth.toString()],\n        ['fill', 'transparent'],\n      ]\n    );\n    this.visual.appendChild(this.selectorCurve);\n    this.visual.appendChild(this.visibleCurve);\n\n    this.addMarkerVisualToContainer(this.visual);\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) down event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerDown(point: IPoint, target?: EventTarget): void {\n    super.pointerDown(point, target);\n\n    this.manipulationStartCurveX = this.curveX;\n    this.manipulationStartCurveY = this.curveY;\n    if (this.state === 'new') {\n      this.curveX = point.x;\n      this.curveY = point.y;\n    }\n\n    if (this.state === 'new') {\n      this.createVisual();\n      this.adjustVisual();\n\n      this._state = 'creating';\n    } else if (this.curveGrip.ownsTarget(target)) {\n      this.activeGrip = this.curveGrip;\n      this._state = 'resize';\n    }\n  }\n\n  /**\n   * Adjusts visual after manipulation.\n   */\n  protected adjustVisual(): void {\n    if (this.selectorCurve && this.visibleCurve) {\n      this.selectorCurve.setAttribute('d', this.getPathD());\n\n      this.visibleCurve.setAttribute('d', this.getPathD());\n\n      SvgHelper.setAttributes(this.visibleCurve, [['stroke', this.strokeColor]]);\n      SvgHelper.setAttributes(this.visibleCurve, [['stroke-width', this.strokeWidth.toString()]]);\n      SvgHelper.setAttributes(this.visibleCurve, [['stroke-dasharray', this.strokeDasharray.toString()]]);\n    }\n  }\n\n  /**\n   * Sets manipulation grips up.\n   */\n  protected setupControlBox(): void {\n    super.setupControlBox();\n    this.curveControlLine1 = SvgHelper.createLine(\n      this.x1,\n      this.y1,\n      this.curveX,\n      this.curveY,\n      [\n        ['stroke', 'black'],\n        ['stroke-width', '1'],\n        ['stroke-opacity', '0.5'],\n        ['stroke-dasharray', '3, 2'],\n      ]\n    );\n    this.curveControlLine2 = SvgHelper.createLine(\n      this.x2,\n      this.y2,\n      this.curveX,\n      this.curveY,\n      [\n        ['stroke', 'black'],\n        ['stroke-width', '1'],\n        ['stroke-opacity', '0.5'],\n        ['stroke-dasharray', '3, 2'],\n      ]\n    );\n\n    this.controlBox.insertBefore(this.curveControlLine1, this.controlBox.firstChild);\n    this.controlBox.insertBefore(this.curveControlLine2, this.controlBox.firstChild);\n  }\n\n  /**\n   * Add manipulation grips to the control box.\n   */\n  protected addControlGrips(): void {\n    this.curveGrip = this.createGrip();\n    this.curveX = 0;\n    this.curveY = 0;\n    super.addControlGrips();\n  }\n\n  /**\n   * Positions manipulation grips.\n   */\n  protected positionGrips(): void {\n    super.positionGrips();\n    const gripSize = this.curveGrip.GRIP_SIZE;\n    this.positionGrip(this.curveGrip.visual, this.curveX - gripSize / 2, this.curveY - gripSize / 2);\n\n    if (this.curveControlLine1 && this.curveControlLine2) {\n      this.curveControlLine1.setAttribute('x1', this.x1.toString());\n      this.curveControlLine1.setAttribute('y1', this.y1.toString());\n      this.curveControlLine1.setAttribute('x2', this.curveX.toString());\n      this.curveControlLine1.setAttribute('y2', this.curveY.toString());\n\n      this.curveControlLine2.setAttribute('x1', this.x2.toString());\n      this.curveControlLine2.setAttribute('y1', this.y2.toString());\n      this.curveControlLine2.setAttribute('x2', this.curveX.toString());\n      this.curveControlLine2.setAttribute('y2', this.curveY.toString());\n    }\n  }\n\n  /**\n   * Moves or resizes the marker.\n   * @param point event coordinates\n   */\n  public manipulate(point: IPoint): void {\n    if (this.state === 'move') {\n      this.curveX = this.manipulationStartCurveX + point.x - this.manipulationStartX;\n      this.curveY = this.manipulationStartCurveY + point.y - this.manipulationStartY;\n    }\n    super.manipulate(point);\n  }\n\n  /**\n   * Resizes the marker.\n   * @param point event coordinates.\n   */\n  protected resize(point: IPoint): void {\n    if (this.activeGrip === this.curveGrip) {\n      this.curveX = point.x;\n      this.curveY = point.y;\n    }\n    super.resize(point);\n    if (this.state === 'creating') {\n      this.curveX = this.x1 + (this.x2 - this.x1) / 2;\n      this.curveY = this.y1 + (this.y2 - this.y1) / 2;\n    }\n  }\n\n  /**\n   * Sets line color.\n   * @param color - new color.\n   */\n  protected setStrokeColor(color: string): void {\n    this.strokeColor = color;\n    this.adjustVisual();\n    this.colorChanged(color);\n  }\n  /**\n   * Sets line width.\n   * @param width - new width.\n   */\n  protected setStrokeWidth(width: number): void {\n    this.strokeWidth = width\n    this.adjustVisual();\n  }\n\n  /**\n   * Sets line dash array.\n   * @param dashes - new dash array.\n   */\n  protected setStrokeDasharray(dashes: string): void {\n    this.strokeDasharray = dashes;\n    this.adjustVisual();\n  }\n\n  /**\n   * Scales marker. Used after the image resize.\n   * \n   * @param scaleX - horizontal scale\n   * @param scaleY - vertical scale\n   */\n  public scale(scaleX: number, scaleY: number): void {\n    this.curveX = this.curveX * scaleX;\n    this.curveY = this.curveY * scaleY;\n    super.scale(scaleX, scaleY);\n  }\n\n\n  /**\n   * Returns the list of toolbox panels for this marker type.\n   */\n  public get toolboxPanels(): ToolboxPanel[] {\n    return [this.strokePanel, this.strokeWidthPanel, this.strokeStylePanel];\n  }\n\n  /**\n   * Returns current marker state that can be restored in the future.\n   */\n  public getState(): CurveMarkerState {\n    const result: CurveMarkerState = Object.assign({\n      strokeColor: this.strokeColor,\n      strokeWidth: this.strokeWidth,\n      strokeDasharray: this.strokeDasharray,\n      curveX: this.curveX,\n      curveY: this.curveY\n    }, super.getState());\n    result.typeName = CurveMarker.typeName;\n\n    return result;\n  }\n\n  /**\n   * Restores previously saved marker state.\n   * \n   * @param state - previously saved state.\n   */\n  public restoreState(state: MarkerBaseState): void {\n    super.restoreState(state);\n\n    const lmState = state as CurveMarkerState;\n    this.strokeColor = lmState.strokeColor;\n    this.strokeWidth = lmState.strokeWidth;\n    this.strokeDasharray = lmState.strokeDasharray;\n    this.curveX = lmState.curveX;\n    this.curveY = lmState.curveY;\n\n    this.createVisual();\n    this.adjustVisual();\n  }\n}\n","import { MarkerArea } from '../MarkerArea';\nimport { MarkerAreaState } from '../MarkerAreaState';\nimport { MarkerBase } from './MarkerBase';\n\nexport class MarkerAreaEvent {\n  public markerArea: MarkerArea;\n  public cancelable = false;\n\n  private _defaultPrevented = false;\n  public get defaultPrevented(): boolean {\n    return this._defaultPrevented;\n  }\n\n  public preventDefault(): void {\n    this._defaultPrevented = true;\n  }\n\n  constructor(markerArea: MarkerArea, cancelable = false) {\n    this.markerArea = markerArea;\n    this.cancelable = cancelable;\n  }\n}\n\nexport class MarkerAreaRenderEvent extends MarkerAreaEvent {\n  public dataUrl: string;\n  public state: MarkerAreaState;\n\n  constructor(markerArea: MarkerArea, dataUrl: string, state: MarkerAreaState) {\n    super(markerArea, false);\n    this.dataUrl = dataUrl;\n    this.state = state;\n  }\n}\n\n\nexport class MarkerEvent extends MarkerAreaEvent {\n  public marker?: MarkerBase;\n\n  constructor(markerArea: MarkerArea, marker?: MarkerBase, cancelable = false) {\n    super(markerArea, cancelable);\n    this.marker = marker;\n  }\n}\n\n/**\n * General MarkerArea event handler type.\n */\nexport type MarkerAreaEventHandler = (event: MarkerAreaEvent) => void;\n\n/**\n * MarkerArea render event handler type.\n */\nexport type MarkerAreaRenderEventHandler = (event: MarkerAreaRenderEvent) => void;\n\n/**\n * Marker event handler type.\n */\nexport type MarkerEventHandler = (event: MarkerEvent) => void;\n\n/**\n * Describes a repository of MarkerArea event handlers.\n */\nexport interface IEventListenerRepository {\n  /**\n   * Event handlers for the `render` event.\n   */\n  render: MarkerAreaRenderEventHandler[];\n  /**\n   * Event handlers for the `beforeclose` event.\n   */\n  beforeclose: MarkerAreaEventHandler[];\n  /**\n   * Event handlers for the `close` event.\n   */\n  close: MarkerAreaEventHandler[];\n  /**\n   * Event handlers for the `show` event.\n   */\n  show: MarkerAreaEventHandler[];\n  /**\n   * Event handlers for the `restorestate` event.\n   */\n  restorestate: MarkerAreaEventHandler[];\n  /**\n   * Event handlers for the `markerselect` event.\n   */\n  markerselect: MarkerEventHandler[];\n  /**\n   * Event handlers for the `markerdeselect` event.\n   */\n  markerdeselect: MarkerEventHandler[];\n  /**\n   * Event handlers for the `markercreating` event.\n   */\n  markercreating: MarkerEventHandler[];\n  /**\n   * Event handlers for the `markercreated` event.\n   */\n  markercreate: MarkerEventHandler[];\n  /**\n   * Event handlers for the `markerbeforedelete` event.\n   */\n  markerbeforedelete: MarkerEventHandler[];\n  /**\n   * Event handlers for the `markerdelete` event.\n   */\n  markerdelete: MarkerEventHandler[];\n  /**\n   * Event handlers for the `focus` event.\n   * \n   * @since 2.19.0\n   */\n  focus: MarkerAreaEventHandler[];\n  /**\n   * Event handlers for the `blur` event.\n   * \n   * @since 2.19.0\n   */\n  blur: MarkerAreaEventHandler[];\n}\n\n/**\n * Event handler type for a specific event type.\n */\nexport type EventHandler<\n  T extends keyof IEventListenerRepository\n> = T extends 'markerselect'\n  ? MarkerEventHandler\n  : T extends 'markerdeselect'\n  ? MarkerEventHandler\n  : T extends 'markercreating'\n  ? MarkerEventHandler\n  : T extends 'markercreate'\n  ? MarkerEventHandler\n  : T extends 'markerbeforedelete'\n  ? MarkerEventHandler\n  : T extends 'markerdelete'\n  ? MarkerEventHandler\n  : T extends 'render'\n  ? MarkerAreaRenderEventHandler\n  : MarkerAreaEventHandler;\n\n/**\n * Event handler repository.\n */\nexport class EventListenerRepository implements IEventListenerRepository {\n  /**\n   * Event handlers for the `render` event.\n   */\n  render: MarkerAreaRenderEventHandler[] = [];\n  /**\n   * Event handlers for the `beforeclose` event.\n   */\n  beforeclose: MarkerAreaEventHandler[] = [];\n  /**\n   * Event handlers for the `close` event.\n   */\n  close: MarkerAreaEventHandler[] = [];\n  /**\n   * Event handlers for the `show` event.\n   */\n  show: MarkerAreaEventHandler[] = [];\n  /**\n   * Event handlers for the `restorestate` event.\n   */\n  restorestate: MarkerAreaEventHandler[] = [];\n  /**\n   * Event handlers for the `markerselect` event.\n   */\n  markerselect: MarkerEventHandler[] = [];\n  /**\n   * Event handlers for the `markerdeselect` event.\n   */\n  markerdeselect: MarkerEventHandler[] = [];\n  /**\n   * Event handlers for the `markercreating` event.\n   */\n  markercreating: MarkerEventHandler[] = [];\n  /**\n   * Event handlers for the `markercreate` event.\n   */\n  markercreate: MarkerEventHandler[] = [];\n  /**\n   * Event handlers for the `markerbeforedelete` event.\n   */\n  markerbeforedelete: MarkerEventHandler[] = [];\n  /**\n   * Event handlers for the `markerdelete` event.\n   */\n  markerdelete: MarkerEventHandler[] = [];\n  /**\n   * Event handlers for the `focus` event.\n   * \n   * @since 2.19.0\n   */\n  focus: MarkerAreaEventHandler[] = [];\n  /**\n   * Event handlers for the `blur` event.\n   * \n   * @since 2.19.0\n   */\n  blur: MarkerAreaEventHandler[] = [];\n\n\n  /**\n   * Add an event handler for a specific event type.\n   * @param eventType - event type.\n   * @param handler - function to handle the event.\n   */\n  public addEventListener<T extends keyof IEventListenerRepository>(\n    eventType: T,\n    handler: EventHandler<T>\n  ): void {\n    (<Array<EventHandler<T>>>this[eventType]).push(handler);\n  }\n\n  /**\n   * Remove an event handler for a specific event type.\n   * @param eventType - event type.\n   * @param handler - function currently handling the event.\n   */\n  public removeEventListener<T extends keyof IEventListenerRepository>(\n    eventType: T,\n    handler: EventHandler<T>\n  ): void {\n    const index = (<Array<EventHandler<T>>>this[eventType]).indexOf(handler);\n    if (index > -1) {\n      (<Array<EventHandler<T>>>this[eventType]).splice(index, 1);\n    }\n  }\n}\n","import { SvgHelper } from './core/SvgHelper';\nimport { Activator } from './core/Activator';\nimport { Renderer } from './core/Renderer';\n\nimport Logo from './assets/markerjs-logo-m.svg';\nimport { MarkerBase } from './core/MarkerBase';\nimport { Toolbar, ToolbarButtonType } from './ui/Toolbar';\nimport { Toolbox } from './ui/Toolbox';\nimport { FrameMarker } from './markers/frame-marker/FrameMarker';\nimport { Settings } from './core/Settings';\nimport { Style } from './core/Style';\nimport { LineMarker } from './markers/line-marker/LineMarker';\nimport { TextMarker } from './markers/text-marker/TextMarker';\nimport { FreehandMarker } from './markers/freehand-marker/FreehandMarker';\nimport { ArrowMarker } from './markers/arrow-marker/ArrowMarker';\nimport { CoverMarker } from './markers/cover-marker/CoverMarker';\nimport { HighlightMarker } from './markers/highlight-marker/HighlightMarker';\nimport { CalloutMarker } from './markers/callout-marker/CalloutMarker';\nimport { MarkerAreaState } from './MarkerAreaState';\nimport { EllipseMarker } from './markers/ellipse-marker/EllipseMarker';\nimport { IStyleSettings } from './core/IStyleSettings';\nimport { MeasurementMarker } from './markers/measurement-marker/MeasurementMarker';\nimport { IPoint } from './core/IPoint';\nimport { EllipseFrameMarker } from './markers/ellipse-frame-marker/EllipseFrameMarker';\nimport { UndoRedoManager } from './core/UndoRedoManager';\nimport { CurveMarker } from './markers/curve-marker/CurveMarker';\nimport { EventHandler, EventListenerRepository, IEventListenerRepository, MarkerAreaEvent, MarkerAreaRenderEvent, MarkerEvent } from './core/Events';\n\n/**\n * @ignore\n */\nexport type MarkerAreaMode = 'select' | 'create' | 'delete';\n\n/**\n * Identifier for marker type when setting {@linkcode availableMarkerTypes}.\n * Marker type can be set as either a string or a marker type reference.\n */\nexport type MarkerTypeIdentifier = string | typeof MarkerBase;\n\n/**\n * Event handler type for {@linkcode MarkerArea} `render` event.\n */\nexport type RenderEventHandler = (\n  dataURL: string,\n  state?: MarkerAreaState\n) => void;\n/**\n * Event handler type for {@linkcode MarkerArea} `close` event.\n */\nexport type CloseEventHandler = () => void;\n\n/**\n * MarkerArea is the main class of marker.js 2. It controls the behavior and appearance of the library.\n *\n * The simplest marker.js 2 usage scenario looks something like this:\n *\n * ```typescript\n * import * as markerjs2 from 'markerjs2';\n * // create an instance of MarkerArea and pass the target image reference as a parameter\n * let markerArea = new markerjs2.MarkerArea(document.getElementById('myimg'));\n *\n * // register an event listener for when user clicks OK/save in the marker.js UI\n * markerArea.addEventListener('render', event => {\n *   // we are setting the markup result to replace our original image on the page\n *   // but you can set a different image or upload it to your server\n *   document.getElementById('myimg').src = event.dataUrl;\n * });\n *\n * // finally, call the show() method and marker.js UI opens\n * markerArea.show();\n * ```\n */\nexport class MarkerArea {\n  private target: HTMLImageElement | HTMLElement;\n  private targetObserver: ResizeObserver;\n\n  private width: number;\n  private height: number;\n  private imageWidth: number;\n  private imageHeight: number;\n  private left: number;\n  private top: number;\n  private windowHeight: number;\n\n  private markerImage: SVGSVGElement;\n  private markerImageHolder: HTMLDivElement;\n  private defs: SVGDefsElement;\n\n  private coverDiv: HTMLDivElement;\n  private uiDiv: HTMLDivElement;\n  private contentDiv: HTMLDivElement;\n  private editorCanvas: HTMLDivElement;\n  private editingTarget: HTMLImageElement | HTMLCanvasElement;\n  private overlayContainer: HTMLDivElement;\n\n  private touchPoints = 0;\n\n  private logoUI: HTMLElement;\n\n  /**\n   * `targetRoot` is used to set an alternative positioning root for the marker.js UI.\n   *\n   * This is useful in cases when your target image is positioned, say, inside a div with `position: relative;`\n   *\n   * ```typescript\n   * // set targetRoot to a specific div instead of document.body\n   * markerArea.targetRoot = document.getElementById('myRootElement');\n   * ```\n   *\n   * @default document.body\n   */\n  public targetRoot: HTMLElement;\n\n  /**\n   * Returns a list of all built-in marker types for use with {@linkcode availableMarkerTypes}\n   *\n   * @readonly\n   */\n  public get ALL_MARKER_TYPES(): typeof MarkerBase[] {\n    return [\n      FrameMarker,\n      FreehandMarker,\n      ArrowMarker,\n      TextMarker,\n      EllipseFrameMarker,\n      EllipseMarker,\n      HighlightMarker,\n      CalloutMarker,\n      MeasurementMarker,\n      CoverMarker,\n      LineMarker,\n      CurveMarker,\n    ];\n  }\n\n  /**\n   * Returns a list of default set of built-in marker types.\n   * Used when {@linkcode availableMarkerTypes} isn't set explicitly.\n   *\n   * @readonly\n   */\n  public get DEFAULT_MARKER_TYPES(): typeof MarkerBase[] {\n    return [\n      FrameMarker,\n      FreehandMarker,\n      ArrowMarker,\n      TextMarker,\n      EllipseMarker,\n      HighlightMarker,\n      CalloutMarker,\n    ];\n  }\n\n  /**\n   * Returns a short list of essential built-in marker types for use with {@linkcode availableMarkerTypes}\n   *\n   * @readonly\n   */\n  public get BASIC_MARKER_TYPES(): typeof MarkerBase[] {\n    return [\n      FrameMarker,\n      FreehandMarker,\n      ArrowMarker,\n      TextMarker,\n      HighlightMarker,\n    ];\n  }\n\n  private _availableMarkerTypes: typeof MarkerBase[] = this\n    .DEFAULT_MARKER_TYPES;\n\n  /**\n   * Gets or sets a list of marker types avaiable to the user in the toolbar.\n   * The types can be passed as either type reference or a string type name.\n   *\n   * ```typescript\n   * this.markerArea1.availableMarkerTypes = ['CalloutMarker', ...this.markerArea1.BASIC_MARKER_TYPES];\n   * ```\n   *\n   * @default {@linkcode DEFAULT_MARKER_TYPES}\n   */\n  public get availableMarkerTypes(): MarkerTypeIdentifier[] {\n    return this._availableMarkerTypes;\n  }\n\n  public set availableMarkerTypes(value: MarkerTypeIdentifier[]) {\n    this._availableMarkerTypes.splice(0);\n    value.forEach((mt) => {\n      if (typeof mt === 'string') {\n        const typeType = this.ALL_MARKER_TYPES.find(\n          (allT) => allT.typeName === mt\n        );\n        if (typeType !== undefined) {\n          this._availableMarkerTypes.push(typeType);\n        }\n      } else {\n        this._availableMarkerTypes.push(mt);\n      }\n    });\n  }\n\n  private toolbar: Toolbar;\n  private toolbox: Toolbox;\n\n  private mode: MarkerAreaMode = 'select';\n\n  private currentMarker?: MarkerBase;\n  private markers: MarkerBase[] = [];\n\n  private isDragging = false;\n\n  // for preserving orginal window state before opening the editor\n  private bodyOverflowState: string;\n  private scrollYState: number;\n  private scrollXState: number;\n\n  private renderEventListeners: RenderEventHandler[] = [];\n  private closeEventListeners: CloseEventHandler[] = [];\n\n  public settings: Settings = new Settings();\n  public uiStyleSettings: IStyleSettings;\n\n  private _isOpen = false;\n  /**\n   * Returns `true` when MarkerArea is open and `false` otherwise.\n   *\n   * @readonly\n   */\n  public get isOpen(): boolean {\n    return this._isOpen;\n  }\n\n  private undoRedoManager: UndoRedoManager<\n    MarkerAreaState\n  > = new UndoRedoManager<MarkerAreaState>();\n\n  /**\n   * When set to true resulting image will be rendered at the natural (original) resolution\n   * of the target image. Otherwise (default), screen dimensions of the image are used.\n   *\n   * @default false (use screen dimensions)\n   */\n  public renderAtNaturalSize = false;\n  /**\n   * Type of image for the rendering result. Eg. `image/png` (default) or `image/jpeg`.\n   *\n   * @default `image/png`\n   */\n  public renderImageType = 'image/png';\n  /**\n   * When rendering engine/format supports it (jpeg, for exmample),\n   * sets the rendering quality for the resulting image.\n   *\n   * In case of `image/jpeg` the value should be between 0 (worst quality) and 1 (best quality).\n   */\n  public renderImageQuality?: number;\n  /**\n   * When set to `true`, will render only the marker layer without the original image.\n   * This could be useful when you want to non-destructively overlay markers on top of the original image.\n   *\n   * Note that in order for the markers layer to have a transparent background {@linkcode renderImageType}\n   * should be set to a format supporting transparency, such as `image/png`.\n   *\n   * @default false\n   */\n  public renderMarkersOnly = false;\n\n  /**\n   * When set and {@linkcode renderAtNaturalSize} is `false` sets the width of the rendered image.\n   *\n   * Both `renderWidth` and `renderHeight` have to be set for this to take effect.\n   */\n  public renderWidth?: number;\n  /**\n   * When set and {@linkcode renderAtNaturalSize} is `false` sets the height of the rendered image.\n   *\n   * Both `renderWidth` and `renderHeight` have to be set for this to take effect.\n   */\n  public renderHeight?: number;\n\n  /**\n   * If a canvas is specified here, then marker.js will render the output to this canvas\n   * in addition to generating an image.\n   *\n   * @since 2.14.0\n   */\n  public renderTarget?: HTMLCanvasElement;\n\n  /**\n   * Pressing zoom button iterates through values in this array.\n   *\n   * @since 2.12.0\n   */\n  public zoomSteps = [1, 1.5, 2, 4];\n  private _zoomLevel = 1;\n  /**\n   * Gets current zoom level.\n   *\n   * @since 2.12.0\n   */\n  public get zoomLevel(): number {\n    return this._zoomLevel;\n  }\n  /**\n   * Sets current zoom level.\n   *\n   * @since 2.12.0\n   */\n  public set zoomLevel(value: number) {\n    this._zoomLevel = value;\n    if (this.editorCanvas && this.contentDiv) {\n      this.editorCanvas.style.transform = `scale(${this._zoomLevel})`;\n      this.contentDiv.scrollTo({\n        left:\n          (this.editorCanvas.clientWidth * this._zoomLevel -\n            this.contentDiv.clientWidth) /\n          2,\n        top:\n          (this.editorCanvas.clientHeight * this._zoomLevel -\n            this.contentDiv.clientHeight) /\n          2,\n      });\n    }\n  }\n\n  /**\n   * Creates a new MarkerArea for the specified target image.\n   *\n   * ```typescript\n   * // create an instance of MarkerArea and pass the target image (or other HTML element) reference as a parameter\n   * let markerArea = new markerjs2.MarkerArea(document.getElementById('myimg'));\n   * ```\n   *\n   * When `target` is not an image object the output is limited to \"markers only\" (@linkcode renderMarkersOnly)\n   * and \"popup\" mode won't work properly as the target object stays in it's original position and, unlike images,\n   * is not copied.\n   *\n   * @param target image object to mark up.\n   */\n  constructor(target: HTMLImageElement | HTMLElement) {\n    Style.settings = Style.defaultSettings;\n    this.uiStyleSettings = Style.settings;\n\n    this.target = target;\n    this.targetRoot = document.body;\n\n    this.width = target.clientWidth;\n    this.height = target.clientHeight;\n\n    Style.removeStyleSheet();\n\n    this.open = this.open.bind(this);\n    this.setTopLeft = this.setTopLeft.bind(this);\n\n    this.toolbarButtonClicked = this.toolbarButtonClicked.bind(this);\n    this.createNewMarker = this.createNewMarker.bind(this);\n    this.addNewMarker = this.addNewMarker.bind(this);\n    this.markerCreated = this.markerCreated.bind(this);\n    this.setCurrentMarker = this.setCurrentMarker.bind(this);\n    this.onPointerDown = this.onPointerDown.bind(this);\n    this.onDblClick = this.onDblClick.bind(this);\n    this.onPointerMove = this.onPointerMove.bind(this);\n    this.onPointerUp = this.onPointerUp.bind(this);\n    this.onPointerOut = this.onPointerOut.bind(this);\n    this.onKeyUp = this.onKeyUp.bind(this);\n    this.overrideOverflow = this.overrideOverflow.bind(this);\n    this.restoreOverflow = this.restoreOverflow.bind(this);\n    this.close = this.close.bind(this);\n    this.closeUI = this.closeUI.bind(this);\n    this.addCloseEventListener = this.addCloseEventListener.bind(this);\n    this.removeCloseEventListener = this.removeCloseEventListener.bind(this);\n    this.addRenderEventListener = this.addRenderEventListener.bind(this);\n    this.removeRenderEventListener = this.removeRenderEventListener.bind(this);\n    this.clientToLocalCoordinates = this.clientToLocalCoordinates.bind(this);\n    this.onWindowResize = this.onWindowResize.bind(this);\n    this.deleteSelectedMarker = this.deleteSelectedMarker.bind(this);\n    this.setWindowHeight = this.setWindowHeight.bind(this);\n    this.removeMarker = this.removeMarker.bind(this);\n    this.colorChanged = this.colorChanged.bind(this);\n    this.fillColorChanged = this.fillColorChanged.bind(this);\n    this.onPopupTargetResize = this.onPopupTargetResize.bind(this);\n    this.showNotesEditor = this.showNotesEditor.bind(this);\n    this.hideNotesEditor = this.hideNotesEditor.bind(this);\n    this.stepZoom = this.stepZoom.bind(this);\n    this.focus = this.focus.bind(this);\n    this.blur = this.blur.bind(this);\n  }\n\n  private open(): void {\n    this.setupResizeObserver();\n    this.setEditingTarget();\n    this.setTopLeft();\n    this.initMarkerCanvas();\n    this.initOverlay();\n    this.attachEvents();\n    if (this.settings.displayMode === 'popup') {\n      this.onPopupTargetResize();\n    }\n\n    if (!Activator.isLicensed) {\n      // NOTE:\n      // before removing this call please consider supporting marker.js\n      // by visiting https://markerjs.com/ for details\n      // thank you!\n      this.addLogo();\n    }\n\n    this._isOpen = true;\n    this._isFocused = true;\n  }\n\n  /**\n   * Initializes the MarkerArea and opens the UI.\n   */\n  public show(): void {\n    this.setWindowHeight();\n    this.showUI();\n    this.open();\n    this.eventListeners['show'].forEach(listener => listener(new MarkerAreaEvent(this)));\n  }\n\n  /**\n   * Renders the annotation result.\n   *\n   * Normally, you should use {@linkcode addEventListener} method to set a listener for the `render` event\n   * rather than calling this method directly.\n   */\n  public async render(): Promise<string> {\n    this.setCurrentMarker();\n\n    const renderer = new Renderer();\n    renderer.naturalSize = this.renderAtNaturalSize;\n    renderer.imageType = this.renderImageType;\n    renderer.imageQuality = this.renderImageQuality;\n    renderer.markersOnly = this.renderMarkersOnly;\n    renderer.width = this.renderWidth;\n    renderer.height = this.renderHeight;\n\n    // workaround for an issue in Safari where FreeHand marker\n    // is not rendered on the first try for some reason\n    await renderer.rasterize(\n      this.target instanceof HTMLImageElement ? this.target : null,\n      this.markerImage,\n      this.renderTarget\n    );\n\n    return await renderer.rasterize(\n      this.target instanceof HTMLImageElement ? this.target : null,\n      this.markerImage,\n      this.renderTarget\n    );\n  }\n\n  /**\n   * Closes the MarkerArea UI.\n   */\n  public close(suppressBeforeClose = false): void {\n    if (this.isOpen) {\n      let cancel = false;\n\n      if (!suppressBeforeClose) {\n        this.eventListeners['beforeclose'].forEach(listener => {\n          const ev = new MarkerAreaEvent(this, true);\n          listener(ev);\n          if (ev.defaultPrevented) {\n            cancel = true;\n          }\n        });\n      }\n      \n      if (!cancel) {\n        if (this.coverDiv) {\n          this.closeUI();\n        }\n        if (this.targetObserver) {\n          this.targetObserver.unobserve(this.target);\n        }\n        if (this.settings.displayMode === 'popup') {\n          window.removeEventListener('resize', this.setWindowHeight);\n        }\n        //this.closeEventListeners.forEach((listener) => listener());\n        this.eventListeners['close'].forEach(listener => listener(new MarkerAreaEvent(this)));\n        this.detachEvents();\n        this._isOpen = false;\n      }\n    }\n  }\n\n  /**\n   * Adds one or more markers to the toolbar.\n   *\n   * @param markers - one or more marker types to be added.\n   */\n  public addMarkersToToolbar(...markers: typeof MarkerBase[]): void {\n    this._availableMarkerTypes.push(...markers);\n  }\n\n  /**\n   * Add a `render` event listener which is called when user clicks on the OK/save button\n   * in the toolbar.\n   *\n   * ```typescript\n   * // register an event listener for when user clicks OK/save in the marker.js UI\n   * markerArea.addRenderEventListener(dataUrl => {\n   *   // we are setting the markup result to replace our original image on the page\n   *   // but you can set a different image or upload it to your server\n   *   document.getElementById('myimg').src = dataUrl;\n   * });\n   * ```\n   *\n   * This is where you place your code to save a resulting image and/or MarkerAreaState.\n   *\n   * @param listener - a method handling rendering results\n   *\n   * @see {@link MarkerAreaState}\n   * @deprecated use `addEventListener('render', ...)` instead.\n   */\n  public addRenderEventListener(listener: RenderEventHandler): void {\n    //this.renderEventListeners.push(listener);\n    this.addEventListener('render', (event: MarkerAreaRenderEvent) => {\n      listener(event.dataUrl, event.state);\n    });\n  }\n\n  /**\n   * Remove a `render` event handler.\n   *\n   * @param listener - previously registered `render` event handler.\n   * @deprecated use `removeEventListener('render', ...)` instead.\n   */\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars\n  public removeRenderEventListener(listener: RenderEventHandler): void {\n    // if (this.renderEventListeners.indexOf(listener) > -1) {\n    //   this.renderEventListeners.splice(\n    //     this.renderEventListeners.indexOf(listener),\n    //     1\n    //   );\n    // }\n  }\n\n  /**\n   * Add a `close` event handler to perform actions in your code after the user\n   * clicks on the close button (without saving).\n   *\n   * @param listener - close event listener\n   * @deprecated use `addEventListener('close', ...)` instead.\n   */\n  public addCloseEventListener(listener: CloseEventHandler): void {\n    //this.closeEventListeners.push(listener);\n    this.addEventListener('close', () => {\n      listener();\n    });\n  }\n\n  /**\n   * Remove a `close` event handler.\n   *\n   * @param listener - previously registered `close` event handler.\n   * @deprecated use `removeEventListener('close', ...)` instead.\n   */\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars\n  public removeCloseEventListener(listener: CloseEventHandler): void {\n    // if (this.closeEventListeners.indexOf(listener) > -1) {\n    //   this.closeEventListeners.splice(\n    //     this.closeEventListeners.indexOf(listener),\n    //     1\n    //   );\n    // }\n  }\n\n  private setupResizeObserver() {\n    if (this.settings.displayMode === 'inline') {\n      if (window.ResizeObserver) {\n        this.targetObserver = new ResizeObserver(() => {\n          this.resize(this.target.clientWidth, this.target.clientHeight);\n        });\n        this.targetObserver.observe(this.target);\n      }\n    } else if (this.settings.displayMode === 'popup') {\n      if (window.ResizeObserver) {\n        this.targetObserver = new ResizeObserver(() =>\n          this.onPopupTargetResize()\n        );\n        this.targetObserver.observe(this.editorCanvas);\n      }\n      window.addEventListener('resize', this.setWindowHeight);\n    }\n  }\n\n  private onPopupTargetResize() {\n    const ratio = (1.0 * this.target.clientWidth) / this.target.clientHeight;\n    const newWidth =\n      this.editorCanvas.clientWidth / ratio > this.editorCanvas.clientHeight\n        ? this.editorCanvas.clientHeight * ratio\n        : this.editorCanvas.clientWidth;\n    const newHeight =\n      newWidth < this.editorCanvas.clientWidth\n        ? this.editorCanvas.clientHeight\n        : this.editorCanvas.clientWidth / ratio;\n    this.resize(newWidth, newHeight);\n  }\n\n  private setWindowHeight() {\n    this.windowHeight = window.innerHeight;\n  }\n\n  private resize(newWidth: number, newHeight: number) {\n    const scaleX = newWidth / this.imageWidth;\n    const scaleY = newHeight / this.imageHeight;\n\n    this.imageWidth = Math.round(newWidth);\n    this.imageHeight = Math.round(newHeight);\n    if (\n      this.target instanceof HTMLImageElement &&\n      this.editingTarget instanceof HTMLImageElement\n    ) {\n      this.editingTarget.src = this.target.src;\n    }\n    this.editingTarget.width = this.imageWidth;\n    this.editingTarget.height = this.imageHeight;\n    this.editingTarget.style.width = `${this.imageWidth}px`;\n    this.editingTarget.style.height = `${this.imageHeight}px`;\n\n    this.markerImage.setAttribute('width', this.imageWidth.toString());\n    this.markerImage.setAttribute('height', this.imageHeight.toString());\n    this.markerImage.setAttribute(\n      'viewBox',\n      '0 0 ' + this.imageWidth.toString() + ' ' + this.imageHeight.toString()\n    );\n\n    this.markerImageHolder.style.width = `${this.imageWidth}px`;\n    this.markerImageHolder.style.height = `${this.imageHeight}px`;\n\n    this.overlayContainer.style.width = `${this.imageWidth}px`;\n    this.overlayContainer.style.height = `${this.imageHeight}px`;\n\n    if (this.settings.displayMode !== 'popup') {\n      this.coverDiv.style.width = `${this.imageWidth.toString()}px`;\n    } else {\n      this.setTopLeft();\n      this.positionMarkerImage();\n    }\n\n    if (this.toolbar !== undefined) {\n      this.toolbar.adjustLayout();\n    }\n\n    this.positionLogo();\n\n    this.scaleMarkers(scaleX, scaleY);\n  }\n\n  private scaleMarkers(scaleX: number, scaleY: number) {\n    let preScaleSelectedMarker: MarkerBase;\n    if (!(this.currentMarker && this.currentMarker instanceof TextMarker)) {\n      preScaleSelectedMarker = this.currentMarker;\n      this.setCurrentMarker();\n    }\n    this.markers.forEach((marker) => marker.scale(scaleX, scaleY));\n    if (preScaleSelectedMarker !== undefined) {\n      this.setCurrentMarker(preScaleSelectedMarker);\n    }\n  }\n\n  private setEditingTarget() {\n    this.imageWidth = Math.round(this.target.clientWidth);\n    this.imageHeight = Math.round(this.target.clientHeight);\n    if (\n      this.target instanceof HTMLImageElement &&\n      this.editingTarget instanceof HTMLImageElement\n    ) {\n      this.editingTarget.src = this.target.src;\n    }\n    this.editingTarget.width = this.imageWidth;\n    this.editingTarget.height = this.imageHeight;\n    this.editingTarget.style.width = `${this.imageWidth}px`;\n    this.editingTarget.style.height = `${this.imageHeight}px`;\n  }\n\n  private setTopLeft() {\n    const targetRect = this.editingTarget.getBoundingClientRect();\n    const bodyRect = this.editorCanvas.getBoundingClientRect();\n    this.left = targetRect.left - bodyRect.left;\n    this.top = targetRect.top - bodyRect.top;\n  }\n\n  private initMarkerCanvas(): void {\n    this.markerImageHolder = document.createElement('div');\n    this.markerImageHolder.style.setProperty('touch-action', 'pinch-zoom');\n\n    this.markerImage = document.createElementNS(\n      'http://www.w3.org/2000/svg',\n      'svg'\n    );\n    this.markerImage.setAttribute('xmlns', 'http://www.w3.org/2000/svg');\n    this.markerImage.setAttribute('width', this.imageWidth.toString());\n    this.markerImage.setAttribute('height', this.imageHeight.toString());\n    this.markerImage.setAttribute(\n      'viewBox',\n      '0 0 ' + this.imageWidth.toString() + ' ' + this.imageHeight.toString()\n    );\n    this.markerImage.style.pointerEvents = 'auto';\n\n    this.markerImageHolder.style.position = 'absolute';\n    this.markerImageHolder.style.width = `${this.imageWidth}px`;\n    this.markerImageHolder.style.height = `${this.imageHeight}px`;\n    this.markerImageHolder.style.transformOrigin = 'top left';\n    this.positionMarkerImage();\n\n    this.markerImageHolder.appendChild(this.markerImage);\n\n    this.editorCanvas.appendChild(this.markerImageHolder);\n  }\n\n  /**\n   * Adds \"defs\" element to the marker SVG element. \n   * Useful for using custom fonts and potentially other scenarios.\n   *\n   * @param {(...(string | Node)[])} nodes\n   * @see Documentation article on adding custom fonts for an example\n   */\n  public addDefs(...nodes: (string | Node)[]): void {\n    this.defs = SvgHelper.createDefs();\n    this.markerImage.insertBefore(this.defs, this.markerImage.firstChild);\n\n    this.defs.append(...nodes);\n  }\n\n  private initOverlay(): void {\n    this.overlayContainer = document.createElement('div');\n    this.overlayContainer.style.position = 'absolute';\n    this.overlayContainer.style.left = '0px';\n    this.overlayContainer.style.top = '0px';\n    this.overlayContainer.style.width = `${this.imageWidth}px`;\n    this.overlayContainer.style.height = `${this.imageHeight}px`;\n    this.overlayContainer.style.display = 'flex';\n    this.markerImageHolder.appendChild(this.overlayContainer);\n  }\n\n  private positionMarkerImage() {\n    this.markerImageHolder.style.top = this.top / this.zoomLevel + 'px';\n    this.markerImageHolder.style.left = this.left / this.zoomLevel + 'px';\n  }\n\n  private attachEvents() {\n    this.markerImage.addEventListener('pointerdown', this.onPointerDown);\n    this.markerImage.addEventListener('dblclick', this.onDblClick);\n    this.attachWindowEvents();\n  }\n\n  private attachWindowEvents() {\n    window.addEventListener('pointermove', this.onPointerMove);\n    window.addEventListener('pointerup', this.onPointerUp);\n    window.addEventListener('pointercancel', this.onPointerOut);\n    window.addEventListener('pointerout', this.onPointerOut);\n    window.addEventListener('pointerleave', this.onPointerUp);\n    window.addEventListener('resize', this.onWindowResize);\n    window.addEventListener('keyup', this.onKeyUp);\n  }\n\n  private detachEvents() {\n    this.markerImage.removeEventListener('pointerdown', this.onPointerDown);\n    this.markerImage.removeEventListener('dblclick', this.onDblClick);\n    this.detachWindowEvents();\n  }\n\n  private detachWindowEvents() {\n    window.removeEventListener('pointermove', this.onPointerMove);\n    window.removeEventListener('pointerup', this.onPointerUp);\n    window.removeEventListener('pointercancel', this.onPointerOut);\n    window.removeEventListener('pointerout', this.onPointerOut);\n    window.removeEventListener('pointerleave', this.onPointerUp);\n    window.removeEventListener('resize', this.onWindowResize);\n    window.removeEventListener('keyup', this.onKeyUp);\n  }\n\n  /**\n   * NOTE:\n   *\n   * before removing or modifying this method please consider supporting marker.js\n   * by visiting https://markerjs.com/#price for details\n   *\n   * thank you!\n   */\n  private addLogo() {\n    this.logoUI = document.createElement('div');\n    this.logoUI.style.display = 'inline-block';\n    this.logoUI.style.margin = '0px';\n    this.logoUI.style.padding = '0px';\n    this.logoUI.style.fill = '#333333';\n\n    const link = document.createElement('a');\n    link.href = 'https://markerjs.com/';\n    link.target = '_blank';\n    link.innerHTML = Logo;\n    link.title = 'Powered by marker.js';\n\n    link.style.display = 'grid';\n    link.style.alignItems = 'center';\n    link.style.justifyItems = 'center';\n    link.style.padding = '3px';\n    link.style.width = '20px';\n    link.style.height = '20px';\n\n    this.logoUI.appendChild(link);\n\n    this.editorCanvas.appendChild(this.logoUI);\n\n    this.logoUI.style.position = 'absolute';\n    this.logoUI.style.pointerEvents = 'all';\n    this.positionLogo();\n  }\n\n  private positionLogo() {\n    if (this.logoUI) {\n      if (this.uiStyleSettings.logoPosition !== 'right') {\n        this.logoUI.style.left = `${this.markerImageHolder.offsetLeft + 10}px`;\n      } else {\n        this.logoUI.style.left = `${\n          this.markerImageHolder.offsetLeft +\n          this.markerImageHolder.offsetWidth -\n          this.logoUI.clientWidth -\n          10\n        }px`;\n      }\n      this.logoUI.style.top = `${\n        this.markerImageHolder.offsetTop +\n        this.markerImageHolder.offsetHeight -\n        this.logoUI.clientHeight -\n        10\n      }px`;\n    }\n  }\n\n  private overrideOverflow() {\n    // backup current state of scrolling and overflow\n    this.scrollXState = window.scrollX;\n    this.scrollYState = window.scrollY;\n    this.bodyOverflowState = document.body.style.overflow;\n\n    window.scroll({ top: 0, left: 0 });\n    document.body.style.overflow = 'hidden';\n  }\n\n  private restoreOverflow() {\n    document.body.style.overflow = this.bodyOverflowState;\n    window.scroll({ top: this.scrollYState, left: this.scrollXState });\n  }\n\n  private showUI(): void {\n    if (this.settings.displayMode === 'popup') {\n      this.overrideOverflow();\n    }\n\n    this.coverDiv = document.createElement('div');\n    // prevent UI from blinking when just rendering state\n    this.coverDiv.style.visibility = this._silentRenderMode ? 'hidden' : 'visible';\n    this.coverDiv.className = Style.CLASS_PREFIX;\n    // hardcode font size so nothing inside is affected by higher up settings\n    this.coverDiv.style.fontSize = '16px';\n    this.coverDiv.style.userSelect = 'none';\n\n    switch (this.settings.displayMode) {\n      case 'inline': {\n        this.coverDiv.style.position = 'absolute';\n        const coverTop =\n          this.target.getClientRects().item(0).y > Style.settings.toolbarHeight\n            ? this.target.offsetTop - Style.settings.toolbarHeight\n            : 0;\n        this.coverDiv.style.top = `${coverTop}px`;\n        this.coverDiv.style.left = `${this.target.offsetLeft.toString()}px`;\n        this.coverDiv.style.width = `${this.target.offsetWidth.toString()}px`;\n        //this.coverDiv.style.height = `${this.target.offsetHeight.toString()}px`;\n        this.coverDiv.style.zIndex =\n          this.uiStyleSettings.zIndex !== undefined\n            ? this.uiStyleSettings.zIndex\n            : '5';\n        // flex causes the ui to stretch when toolbox has wider nowrap panels\n        //this.coverDiv.style.display = 'flex';\n        break;\n      }\n      case 'popup': {\n        this.coverDiv.style.position = 'absolute';\n        this.coverDiv.style.top = '0px';\n        this.coverDiv.style.left = '0px';\n        this.coverDiv.style.width = '100vw';\n        this.coverDiv.style.height = `${window.innerHeight}px`;\n        this.coverDiv.style.backgroundColor = 'rgba(0, 0, 0, 0.75)';\n        this.coverDiv.style.zIndex =\n          this.uiStyleSettings.zIndex !== undefined\n            ? this.uiStyleSettings.zIndex\n            : '1000';\n        this.coverDiv.style.display = 'flex';\n        // this.coverDiv.style.overflow = 'auto';\n      }\n    }\n    this.targetRoot.appendChild(this.coverDiv);\n\n    this.uiDiv = document.createElement('div');\n    this.uiDiv.style.display = 'flex';\n    this.uiDiv.style.flexDirection = 'column';\n    this.uiDiv.style.flexGrow = '2';\n    this.uiDiv.style.margin =\n      this.settings.displayMode === 'popup'\n        ? `${this.settings.popupMargin}px`\n        : '0px';\n    this.uiDiv.style.border = '0px';\n    // this.uiDiv.style.overflow = 'hidden';\n    //this.uiDiv.style.backgroundColor = '#ffffff';\n    this.coverDiv.appendChild(this.uiDiv);\n\n    this.toolbar = new Toolbar(\n      this.uiDiv,\n      this.settings.displayMode,\n      this._availableMarkerTypes,\n      this.uiStyleSettings\n    );\n    this.toolbar.addButtonClickListener(this.toolbarButtonClicked);\n    this.toolbar.show((this._silentRenderMode || this.uiStyleSettings.hideToolbar) ? 'hidden' : 'visible');\n\n    this.contentDiv = document.createElement('div');\n    this.contentDiv.style.display = 'flex';\n    this.contentDiv.style.flexDirection = 'row';\n    this.contentDiv.style.flexGrow = '2';\n    this.contentDiv.style.flexShrink = '1';\n    if (this.settings.displayMode === 'popup') {\n      this.contentDiv.style.backgroundColor = this.uiStyleSettings.canvasBackgroundColor;\n      this.contentDiv.style.maxHeight = `${\n        this.windowHeight -\n        this.settings.popupMargin * 2 -\n        this.uiStyleSettings.toolbarHeight * 3.5\n      }px`;\n      // this.contentDiv.style.maxHeight = `calc(100vh - ${\n      //   this.settings.popupMargin * 2 + this.uiStyleSettings.toolbarHeight * 3.5}px)`;\n      this.contentDiv.style.maxWidth = `calc(100vw - ${\n        this.settings.popupMargin * 2\n      }px)`;\n    }\n    this.contentDiv.style.overflow = 'auto';\n    this.uiDiv.appendChild(this.contentDiv);\n\n    this.editorCanvas = document.createElement('div');\n    this.editorCanvas.style.flexGrow = '2';\n    this.editorCanvas.style.flexShrink = '1';\n    this.editorCanvas.style.position = 'relative';\n    this.editorCanvas.style.overflow = 'hidden';\n    this.editorCanvas.style.display = 'flex';\n    if (this.settings.displayMode === 'popup') {\n      this.editorCanvas.style.alignItems = 'center';\n      this.editorCanvas.style.justifyContent = 'center';\n    }\n    this.editorCanvas.style.pointerEvents = 'none';\n    this.editorCanvas.style.transformOrigin = 'left top';\n    this.editorCanvas.style.transform = `scale(${this.zoomLevel})`;\n    this.contentDiv.appendChild(this.editorCanvas);\n\n    this.editingTarget =\n      this.target instanceof HTMLImageElement\n        ? document.createElement('img')\n        : document.createElement('canvas');\n    if (this.target.getClientRects().item(0).y < Style.settings.toolbarHeight) {\n      this.editingTarget.style.marginTop = `${\n        this.target.offsetTop - Style.settings.toolbarHeight\n      }px`;\n    }\n    this.editorCanvas.appendChild(this.editingTarget);\n\n    this.toolbox = new Toolbox(\n      this.uiDiv,\n      this.settings.displayMode,\n      this.uiStyleSettings\n    );\n    this.toolbox.show((this._silentRenderMode || this.uiStyleSettings.hideToolbox) ? 'hidden' : 'visible');\n  }\n\n  private closeUI() {\n    if (this.settings.displayMode === 'popup') {\n      this.restoreOverflow();\n    }\n    // @todo better cleanup\n    this.targetRoot.removeChild(this.coverDiv);\n  }\n\n  private removeMarker(marker: MarkerBase) {\n    this.markerImage.removeChild(marker.container);\n    if (this.markers.indexOf(marker) > -1) {\n      this.markers.splice(this.markers.indexOf(marker), 1);\n    }\n    marker.dispose();\n  }\n\n  private switchToSelectMode() {\n    this.mode = 'select';\n    this.hideNotesEditor();\n    if (this.currentMarker !== undefined) {\n      if (this.currentMarker.state !== 'new') {\n        this.currentMarker.select();\n      } else {\n        this.removeMarker(this.currentMarker);\n        this.setCurrentMarker();\n        this.markerImage.style.cursor = 'default';\n      }\n      this.addUndoStep();\n    }\n  }\n\n  private toolbarButtonClicked(\n    buttonType: ToolbarButtonType,\n    value?: typeof MarkerBase | string\n  ) {\n    if (buttonType === 'marker' && value !== undefined) {\n      this.createNewMarker(<typeof MarkerBase>value);\n    } else if (buttonType === 'action') {\n      switch (value) {\n        case 'select': {\n          this.switchToSelectMode();\n          break;\n        }\n        case 'delete': {\n          this.deleteSelectedMarker();\n          break;\n        }\n        case 'clear': {\n          this.clear();\n          break;\n        }\n        case 'undo': {\n          this.switchToSelectMode();\n          this.addUndoStep();\n          this.undo();\n          break;\n        }\n        case 'redo': {\n          this.switchToSelectMode();\n          this.redo();\n          break;\n        }\n        case 'zoom': {\n          this.stepZoom();\n          break;\n        }\n        case 'zoom-out': {\n          this.zoomLevel = 1;\n          break;\n        }\n        case 'notes': {\n          if (this.notesArea === undefined) {\n            this.switchToSelectMode();\n            this.zoomLevel = 1;\n            this.showNotesEditor();\n          } else {\n            this.switchToSelectMode();\n          }\n          break;\n        }\n        case 'close': {\n          this.close();\n          break;\n        }\n        case 'render': {\n          this.switchToSelectMode();\n          this.startRenderAndClose();\n          break;\n        }\n      }\n    }\n  }\n\n  /**\n   * Removes currently selected marker.\n   */\n  public deleteSelectedMarker(): void {\n    if (this.currentMarker !== undefined) {\n      let cancel = false;\n\n      this.eventListeners['markerbeforedelete'].forEach(listener => {\n        const ev = new MarkerEvent(this, this.currentMarker, true);\n        listener(ev);\n        if (ev.defaultPrevented) {\n          cancel = true;\n        }\n      });\n      \n      if (!cancel) {\n        const marker = this.currentMarker;\n        this.currentMarker.dispose();\n        this.markerImage.removeChild(this.currentMarker.container);\n        this.markers.splice(this.markers.indexOf(this.currentMarker), 1);\n        this.setCurrentMarker();\n        this.addUndoStep();\n        this.eventListeners['markerdelete'].forEach(listener => listener(new MarkerEvent(this, marker)));\n      }\n    }\n  }\n\n  /**\n   * Removes all markers.\n   * \n   * @since 2.15.0\n   */\n  public clear(): void {\n    this.setCurrentMarker();\n    for (let i = this.markers.length - 1; i >= 0; i--) {\n      this.setCurrentMarker(this.markers[i]);\n      this.currentMarker.dispose();\n      this.markerImage.removeChild(this.currentMarker.container);\n      this.markers.splice(this.markers.indexOf(this.currentMarker), 1);\n    }\n    this.addUndoStep();\n  }\n\n  private notesArea?: HTMLTextAreaElement;\n  private get isNotesAreaOpen(): boolean {\n    return this.notesArea !== undefined;\n  }\n\n  private showNotesEditor() {\n    if (this.currentMarker !== undefined) {\n      this.overlayContainer.innerHTML = '';\n      this.notesArea = document.createElement('textarea');\n      this.notesArea.className = this.uiStyleSettings.notesAreaStyleClassName;\n      this.notesArea.style.pointerEvents = 'auto';\n      this.notesArea.style.alignSelf = 'stretch';\n      this.notesArea.style.width = '100%';\n      this.notesArea.style.margin = `${\n        this.uiStyleSettings.toolbarHeight / 4\n      }px`;\n      this.notesArea.value = this.currentMarker.notes ?? '';\n      this.overlayContainer.appendChild(this.notesArea);\n    }\n  }\n  private hideNotesEditor() {\n    if (this.isNotesAreaOpen) {\n      if (this.currentMarker !== undefined) {\n        this.currentMarker.notes =\n          this.notesArea.value.trim() !== '' ? this.notesArea.value : undefined;\n      }\n      this.overlayContainer.removeChild(this.notesArea);\n      this.notesArea = undefined;\n    }\n  }\n\n  private selectLastMarker() {\n    if (this.markers.length > 0) {\n      this.setCurrentMarker(this.markers[this.markers.length - 1]);\n    }\n  }\n\n  private addUndoStep() {\n    if (\n      this.currentMarker === undefined ||\n      this.currentMarker.state !== 'edit'\n    ) {\n      this.undoRedoManager.addUndoStep(this.getState());\n    }\n  }\n\n  /**\n   * Undo last action.\n   *\n   * @since 2.6.0\n   */\n  public undo(): void {\n    const stepData = this.undoRedoManager.undo();\n    if (stepData !== undefined) {\n      this.restoreState(stepData);\n      this.selectLastMarker();\n    }\n  }\n\n  /**\n   * Redo previously undone action.\n   *\n   * @since 2.6.0\n   */\n  public redo(): void {\n    const stepData = this.undoRedoManager.redo();\n    if (stepData !== undefined) {\n      this.restoreState(stepData);\n      this.selectLastMarker();\n    }\n  }\n\n  /**\n   * Iterate zoom steps (@linkcode zoomSteps).\n   * Next zoom level is selected or returns to the first zoom level restarting the sequence.\n   *\n   * @since 2.12.0\n   */\n  public stepZoom(): void {\n    const zoomStepIndex = this.zoomSteps.indexOf(this.zoomLevel);\n    this.zoomLevel =\n      zoomStepIndex < this.zoomSteps.length - 1\n        ? this.zoomSteps[zoomStepIndex + 1]\n        : this.zoomSteps[0];\n  }\n\n  private prevPanPoint: IPoint = { x: 0, y: 0 };\n  private panTo(point: IPoint) {\n    this.contentDiv.scrollBy({\n      left: this.prevPanPoint.x - point.x,\n      top: this.prevPanPoint.y - point.y,\n    });\n    this.prevPanPoint = point;\n  }\n\n  /**\n   * Initiates markup rendering.\n   *\n   * Get results by adding a render event listener via {@linkcode addRenderEventListener}.\n   */\n  public async startRenderAndClose(): Promise<void> {\n    const result = await this.render();\n    const state = this.getState();\n    //this.renderEventListeners.forEach((listener) => listener(result, state));\n    this.eventListeners['render'].forEach(listener => listener(new MarkerAreaRenderEvent(this, result, state)));\n    this.close(true);\n  }\n\n  /**\n   * Returns the complete state for the MarkerArea that can be preserved and used\n   * to continue annotation next time.\n   *\n   * @param deselectCurrentMarker - when `true` is passed, currently selected marker will be deselected before getting the state.\n   */\n  public getState(deselectCurrentMarker?: boolean): MarkerAreaState {\n    if (deselectCurrentMarker === true) {\n      this.setCurrentMarker();\n    }\n    const result: MarkerAreaState = {\n      width: this.imageWidth,\n      height: this.imageHeight,\n      markers: [],\n    };\n    this.markers.forEach((marker) => result.markers.push(marker.getState()));\n    return result;\n  }\n\n  /**\n   * Restores MarkerArea state to continue previous annotation session.\n   *\n   * **IMPORTANT**: call `restoreState()` __after__ you've opened the MarkerArea with {@linkcode show}.\n   *\n   * ```typescript\n   * this.markerArea1.show();\n   * if (this.currentState) {\n   *   this.markerArea1.restoreState(this.currentState);\n   * }\n   * ```\n   *\n   * @param state - previously saved state object.\n   */\n  public restoreState(state: MarkerAreaState): void {\n    this.markers.splice(0);\n    while (this.markerImage.lastChild) {\n      this.markerImage.removeChild(this.markerImage.lastChild);\n    }\n    \n    state.markers.forEach((markerState) => {\n      const markerType = this._availableMarkerTypes.find(\n        (mType) => mType.typeName === markerState.typeName\n      );\n      if (markerType !== undefined) {\n        const marker = this.addNewMarker(markerType);\n        marker.restoreState(markerState);\n        this.markers.push(marker);\n      }\n    });\n    if (\n      state.width &&\n      state.height &&\n      (state.width !== this.imageWidth || state.height !== this.imageHeight)\n    ) {\n      this.scaleMarkers(\n        this.imageWidth / state.width,\n        this.imageHeight / state.height\n      );\n    }\n    this.eventListeners['restorestate'].forEach(listener => listener(new MarkerAreaEvent(this)));\n  }\n\n  private addNewMarker(markerType: typeof MarkerBase): MarkerBase {\n    const g = SvgHelper.createGroup();\n    this.markerImage.appendChild(g);\n\n    return new markerType(g, this.overlayContainer, this.settings);\n  }\n\n  /**\n   * Initiate new marker creation.\n   *\n   * marker.js switches to marker creation mode for the marker type specified\n   * and users can draw a new marker like they would by pressing a corresponding\n   * toolbar button.\n   *\n   * This example initiates creation of a `FrameMarker`:\n   * ```typescript\n   * this.markerArea1.createNewMarker(FrameMarker);\n   * ```\n   *\n   * @param markerType\n   */\n  public createNewMarker(markerType: typeof MarkerBase | string): void {\n    let mType: typeof MarkerBase;\n\n    if (typeof markerType === 'string') {\n      mType = this._availableMarkerTypes.find(\n        (mt) => mt.typeName === markerType\n      );\n    } else {\n      mType = markerType;\n    }\n\n    if (mType) {\n      this.setCurrentMarker();\n      this.currentMarker = this.addNewMarker(mType);\n      this.currentMarker.onMarkerCreated = this.markerCreated;\n      this.currentMarker.onColorChanged = this.colorChanged;\n      this.currentMarker.onFillColorChanged = this.fillColorChanged;\n      this.markerImage.style.cursor = 'crosshair';\n      this.toolbar.setActiveMarkerButton(mType.typeName);\n      this.toolbox.setPanelButtons(this.currentMarker.toolboxPanels);\n      this.eventListeners['markercreating'].forEach(listener => listener(new MarkerEvent(this, this.currentMarker)));\n    }\n  }\n\n  private markerCreated(marker: MarkerBase) {\n    this.mode = 'select';\n    this.markerImage.style.cursor = 'default';\n    this.markers.push(marker);\n    this.setCurrentMarker(marker);\n    if (\n      marker instanceof FreehandMarker &&\n      this.settings.newFreehandMarkerOnPointerUp\n    ) {\n      this.createNewMarker(FreehandMarker);\n    } else {\n      this.toolbar.setSelectMode();\n    }\n    this.addUndoStep();\n    this.eventListeners['markercreate'].forEach(listener => listener(new MarkerEvent(this, this.currentMarker)));\n  }\n\n  private colorChanged(color: string): void {\n    if (this.settings.defaultColorsFollowCurrentColors) {\n      this.settings.defaultColor = color;\n      this.settings.defaultStrokeColor = color;\n    }\n  }\n  private fillColorChanged(color: string): void {\n    if (this.settings.defaultColorsFollowCurrentColors) {\n      this.settings.defaultFillColor = color;\n    }\n  }\n\n  /**\n   * Sets the currently selected marker or deselects it if no parameter passed.\n   *\n   * @param marker marker to select. Deselects current marker if undefined.\n   */\n  public setCurrentMarker(marker?: MarkerBase): void {\n    if (this.currentMarker !== marker) { // no need to deselect if not changed\n      if (this.currentMarker !== undefined) {\n        this.currentMarker.deselect();\n        this.toolbar.setCurrentMarker();\n        this.toolbox.setPanelButtons([]);\n        this.eventListeners['markerdeselect'].forEach(listener => listener(new MarkerEvent(this, this.currentMarker)));\n      }\n    }\n    this.currentMarker = marker;\n    if (this.currentMarker !== undefined && !this.currentMarker.isSelected) {\n      this.currentMarker.select();\n      this.toolbar.setCurrentMarker(this.currentMarker);\n      this.toolbox.setPanelButtons(this.currentMarker.toolboxPanels);\n      this.eventListeners['markerselect'].forEach(listener => listener(new MarkerEvent(this, this.currentMarker)));\n    }\n  }\n\n  private onPointerDown(ev: PointerEvent) {\n    if (!this._isFocused) {\n      this.focus();\n    }\n\n    this.touchPoints++;\n    if (this.touchPoints === 1 || ev.pointerType !== 'touch') {\n      if (\n        this.currentMarker !== undefined &&\n        (this.currentMarker.state === 'new' ||\n          this.currentMarker.state === 'creating')\n      ) {\n        this.isDragging = true;\n        this.currentMarker.pointerDown(\n          this.clientToLocalCoordinates(ev.clientX, ev.clientY)\n        );\n      } else if (this.mode === 'select') {\n        const hitMarker = this.markers.find((m) => m.ownsTarget(ev.target));\n        if (hitMarker !== undefined) {\n          this.setCurrentMarker(hitMarker);\n          this.isDragging = true;\n          this.currentMarker.pointerDown(\n            this.clientToLocalCoordinates(ev.clientX, ev.clientY),\n            ev.target\n          );\n        } else {\n          this.setCurrentMarker();\n          this.isDragging = true;\n          this.prevPanPoint = { x: ev.clientX, y: ev.clientY };\n        }\n      }\n    }\n  }\n\n  private onDblClick(ev: PointerEvent) {\n    if (!this._isFocused) {\n      this.focus();\n    }\n\n    if (this.mode === 'select') {\n      const hitMarker = this.markers.find((m) => m.ownsTarget(ev.target));\n      if (hitMarker !== undefined && hitMarker !== this.currentMarker) {\n        this.setCurrentMarker(hitMarker);\n      }\n      if (this.currentMarker !== undefined) {\n        this.currentMarker.dblClick(\n          this.clientToLocalCoordinates(ev.clientX, ev.clientY),\n          ev.target\n        );\n      } else {\n        this.setCurrentMarker();\n      }\n    }\n  }\n\n  private onPointerMove(ev: PointerEvent) {\n    if (this.touchPoints === 1 || ev.pointerType !== 'touch') {\n      if (this.currentMarker !== undefined || this.isDragging) {\n        // don't swallow the event when editing text markers\n        if (\n          this.currentMarker === undefined ||\n          this.currentMarker.state !== 'edit'\n        ) {\n          ev.preventDefault();\n        }\n\n        if (this.currentMarker !== undefined) {\n          this.currentMarker.manipulate(\n            this.clientToLocalCoordinates(ev.clientX, ev.clientY)\n          );\n        } else if (this.zoomLevel > 1) {\n          this.panTo({ x: ev.clientX, y: ev.clientY });\n        }\n      }\n    }\n  }\n  private onPointerUp(ev: PointerEvent) {\n    if (this.touchPoints > 0) {\n      this.touchPoints--;\n    }\n    if (this.touchPoints === 0) {\n      if (this.isDragging && this.currentMarker !== undefined) {\n        this.currentMarker.pointerUp(\n          this.clientToLocalCoordinates(ev.clientX, ev.clientY)\n        );\n      }\n    }\n    this.isDragging = false;\n    this.addUndoStep();\n  }\n\n  private onPointerOut(/*ev: PointerEvent*/) {\n    if (this.touchPoints > 0) {\n      this.touchPoints--;\n    }\n  }\n\n  private onKeyUp(ev: KeyboardEvent) {\n    if (\n      this.currentMarker !== undefined &&\n      this.notesArea === undefined &&\n      (ev.key === 'Delete' || ev.key === 'Backspace')\n    ) {\n      this.deleteSelectedMarker();\n      // this.setCurrentMarker();\n      // this.markerImage.style.cursor = 'default';\n      // this.addUndoStep();\n    }\n  }\n\n  private clientToLocalCoordinates(x: number, y: number): IPoint {\n    const clientRect = this.markerImage.getBoundingClientRect();\n    return {\n      x: (x - clientRect.left) / this.zoomLevel,\n      y: (y - clientRect.top) / this.zoomLevel,\n    };\n  }\n\n  private onWindowResize() {\n    this.positionUI();\n  }\n\n  private positionUI() {\n    this.setTopLeft();\n    switch (this.settings.displayMode) {\n      case 'inline': {\n        const coverTop =\n          this.target.offsetTop > Style.settings.toolbarHeight\n            ? this.target.offsetTop - Style.settings.toolbarHeight\n            : 0;\n        this.coverDiv.style.top = `${coverTop}px`;\n        this.coverDiv.style.left = `${this.target.offsetLeft.toString()}px`;\n        break;\n      }\n      case 'popup': {\n        this.coverDiv.style.top = '0px';\n        this.coverDiv.style.left = '0px';\n        this.coverDiv.style.width = '100vw';\n        this.coverDiv.style.height = `${this.windowHeight}px`;\n        this.contentDiv.style.maxHeight = `${\n          this.windowHeight -\n          this.settings.popupMargin * 2 -\n          this.uiStyleSettings.toolbarHeight * 3.5\n        }px`;\n      }\n    }\n    this.positionMarkerImage();\n    this.positionLogo();\n  }\n\n  /**\n   * Add license key.\n   *\n   * This is a proxy method for {@linkcode Activator.addKey()}.\n   *\n   * @param key - commercial license key.\n   */\n  public addLicenseKey(key: string): void {\n    Activator.addKey(key);\n  }\n\n  private eventListeners = new EventListenerRepository();\n  /**\n   * Adds an event listener for one of the marker.js Live events.\n   * \n   * @param eventType - type of the event.\n   * @param handler - function handling the event.\n   * \n   * @since 2.16.0\n   */\n  public addEventListener<T extends keyof IEventListenerRepository>(\n    eventType: T,\n    handler: EventHandler<T>\n  ): void {\n    this.eventListeners.addEventListener(eventType, handler);\n  }\n\n  /**\n   * Removes an event listener for one of the marker.js Live events.\n   * \n   * @param eventType - type of the event.\n   * @param handler - function currently handling the event.\n   * \n   * @since 2.16.0\n   */\n  public removeEventListener<T extends keyof IEventListenerRepository>(\n    eventType: T,\n    handler: EventHandler<T>\n  ): void {\n    this.eventListeners.removeEventListener(eventType, handler);\n  }\n\n\n  private _silentRenderMode = false;\n  /**\n   * Renders previously saved state without user intervention.\n   * \n   * The rendered image is returned to the `render` event handlers (as in the regular interactive process).\n   * Rendering options set on `MarkerArea` are respected.\n   * \n   * @param state state to render\n   * \n   * @since 2.17.0\n   */\n  public renderState(state: MarkerAreaState): void {\n    this._silentRenderMode = true;\n    this.settings.displayMode = 'inline';\n    if (!this.isOpen) {\n      this.show();\n    }\n    this.restoreState(state);\n    this.startRenderAndClose();\n    this._silentRenderMode = false;\n  }\n\n  private _isFocused = false;\n  /**\n   * Returns true when this MarkerArea is focused.\n   * \n   * @since 2.19.0\n   */\n  public get isFocused(): boolean {\n    return this._isFocused;\n  }\n\n  private _previousCurrentMarker?: MarkerBase;\n\n  /**\n   * Focuses the MarkerArea to receive all input from the window.\n   * \n   * Is called automatically when user clicks inside of the marker area. Call manually to set focus explicitly.\n   * \n   * @since 2.19.0\n   */\n  public focus(): void {\n    if (!this._isFocused) {\n      this.attachWindowEvents();\n      this._isFocused = true;\n      if (this._previousCurrentMarker !== undefined) {\n        this.setCurrentMarker(this._previousCurrentMarker);\n      }\n      this.eventListeners['focus'].forEach(listener => listener(new MarkerAreaEvent(this)));\n    }\n  }\n\n  /**\n   * Tells MarkerArea to stop reacting to input outside of the immediate marker image.\n   * \n   * Call `focus()` to re-enable.\n   * \n   * @since 2.19.0\n   */\n  public blur(): void {\n    if (this._isFocused) {\n      this.detachWindowEvents();\n      this._isFocused = false;\n      this._previousCurrentMarker = this.currentMarker;\n      this.setCurrentMarker();\n      this.eventListeners['blur'].forEach(listener => listener(new MarkerAreaEvent(this)));\n    }\n  }\n\n}\n"],"names":["extendStatics","d","b","Object","setPrototypeOf","__proto__","Array","p","prototype","hasOwnProperty","call","__extends","__","this","constructor","create","__awaiter","thisArg","_arguments","P","generator","Promise","resolve","reject","fulfilled","value","step","next","e","rejected","result","done","then","apply","__generator","body","f","y","t","g","_","label","sent","trys","ops","verb","throw","return","Symbol","iterator","n","v","op","TypeError","pop","length","push","__spreadArrays","s","i","il","arguments","r","k","a","j","jl","SvgHelper","document","createElementNS","el","attributes","attributes_1","_i","_a","attr","setAttribute","width","height","rect","toString","setAttributes","x1","y1","x2","y2","line","points","polygon","radius","circle","rx","ry","ellipse","createSVGTransform","id","orient","markerWidth","markerHeight","refX","refY","markerElement","marker","appendChild","text","tspan","textContent","image","x","svgPoint","createSVGPoint","path","Activator","key","RegExp","test","Renderer","target","markerImage","targetCanvas","canvas","undefined","createElement","_this","markersOnly","naturalSize","markerImageCopy","baseVal","valueAsString","viewBox","innerHTML","naturalWidth","naturalHeight","data","outerHTML","ctx","getContext","drawImage","DOMURL","window","URL","img","Image","blob","Blob","type","url","createObjectURL","onload","revokeObjectURL","toDataURL","imageType","imageQuality","src","Style","canvasBackgroundColor","toolbarBackgroundColor","toolbarBackgroundHoverColor","toolbarColor","toolbarHeight","toolboxColor","toolboxAccentColor","undoButtonVisible","redoButtonVisible","zoomButtonVisible","zoomOutButtonVisible","clearButtonVisible","resultButtonBlockVisible","logoPosition","CLASS_PREFIX","styleClass","styleSheet","addStyleSheet","classes","sheet","insertRule","name","style","cssRules","styleRule","rules","selector","styleSheetRoot","head","addRule","StyleRule","addClass","StyleClass","removeChild","defaultSettings","_localName","markerjsContainer","displayMode","markerItems","uiStyleSettings","addStyles","adjustLayout","bind","overflowButtonClicked","setCurrentMarker","Toolbar","visiblity","uiContainer","visibility","className","toolbarStyleClass","fadeInAnimationClassName","toolbarStyleColorsClassName","toolbarStyleColorsClass","actionButtonBlock","toolbarBlockStyleClass","whiteSpace","addActionButton","notesButtonVisible","markerButtonBlock","flexGrow","textAlign","markerButtonOverflowBlock","toolbarOverflowBlockStyleClass","toolbarOverflowBlockStyleColorsClassName","toolbarOverflowBlockStyleColorsClass","display","forEach","mi","buttonContainer","toolbarButtonStyleClass","typeName","icon","addEventListener","markerToolbarButtonClicked","buttons","markerButtons","overflowButton","toolbarButtonStyleColorsClassName","toolbarButtonStyleColorsClass","resultButtonBlock","setSelectMode","listener","buttonClickListeners","indexOf","splice","resetButtonStyles","setActiveButton","numberToFit","Math","floor","clientWidth","buttonIndex","replace","top","offsetTop","offsetHeight","right","offsetWidth","offsetLeft","button","trim","toolbarActiveButtonStyleColorsClassName","toolbarActiveButtonStyleColorsClass","container","actionButton","actionToolbarButtonClicked","fill","selectButtonColor","deleteButtonColor","okButtonColor","closeButtonColor","round","buttonPadding","markerType","action","activeBtn","find","btn","getAttribute","currentMarker","filter","fillOpacity","pointerEvents","panelButtonClick","Toolbox","toolboxStyleClass","toolboxStyleColorsClass","toolboxButtonRowStyleClass","toolboxButtonRowStyleColorsClass","toolboxPanelRowStyleClass","toolboxPanelRowStyleColorsClass","toolboxBackgroundColor","toolboxButtonStyleClass","toolboxButtonStyleColorsClass","toolboxActiveButtonStyleColorsClass","toolboxStyleColorsClassName","panels","panelRow","toolboxPanelRowStyleColorsClassName","buttonRow","toolboxButtonRowStyleColorsClassName","panelButtons","panel","panelBtnDiv","toolboxButtonStyleColorsClassName","title","panelIndex","activePanel","panelUI","getUi","margin","fadeOutAnimationClassName","setTimeout","pb","index","toolboxActiveButtonStyleColorsClassName","colors","currentColor","_super","setCurrentColor","getColorBox","ColorPickerPanel","panelDiv","overflow","color","colorBoxContainer","colorBoxes","settings","buttonHeight","boxSizing","padding","marginRight","marginBottom","borderWidth","borderStyle","borderRadius","borderColor","colorBox","backgroundColor","box","onColorChanged","ToolboxPanel","overlayContainer","_container","_overlayContainer","globalSettings","MarkerBase","getPrototypeOf","_state","_isSelected","cursor","point","element","childNodes","insertBefore","state","notes","scaleX","scaleY","onFillColorChanged","findGripByVisual","RectangularBoxMarkerGrips","gripVisual","topLeft","ownsTarget","topCenter","topRight","centerLeft","centerRight","bottomLeft","bottomCenter","bottomRight","visual","createGroup","createCircle","GRIP_SIZE","ResizeGrip","TransformMatrix","matrix","c","currentMatrix","newMatrix","transform","appendItem","createTransform","setupControlBox","RectangularBoxMarkerBase","left","_visual","translate","controlGrips","rotatorGrip","pointerDown","manipulationStartLeft","manipulationStartTop","manipulationStartWidth","manipulationStartHeight","rotatedPoint","unrotatePoint","manipulationStartX","manipulationStartY","offsetX","offsetY","select","activeGrip","rotatedCenter","rotatePoint","centerX","centerY","moveVisual","rotate","getItem","setRotate","rotationAngle","replaceItem","adjustControlBox","inState","pointerUp","defaultSize","manipulate","onMarkerCreated","resize","newX","newWidth","newY","newHeight","setSize","abs","sign","atan","PI","applyRotation","getCTM","createPoint","matrixTransform","inverse","controlBox","deselect","setTranslate","CB_DISTANCE","controlRect","createRect","rotatorGripLine","createLine","addControlGrips","positionGrips","createGrip","grip","gripSize","cx","cy","bottom","positionGrip","assign","visualTransformMatrix","toITransformMatrix","containerTransformMatrix","getState","restoreState","rbmState","setMatrix","toSVGMatrix","scale","rPoint","setStrokeColor","setFillColor","setStrokeWidth","setStrokeDasharray","createVisual","RectangleMarker","fillColor","strokeColor","strokeWidth","strokeDasharray","opacity","addMarkerVisualToContainer","colorChanged","dashes","rectState","widths","currentWidth","setCurrentWidth","LineWidthPanel","lineWidth","widthBoxContainer","alignItems","justifyContent","innerText","widthBox","minHeight","hr","minWidth","border","borderTop","widthBoxes","onWidthChanged","styles","currentStyle","setCurrentStyle","LineStylePanel","lineStyle","styleBoxContainer","maxWidth","styleBox","styleSample","styleBoxes","newStyle","onStyleChanged","defaultColor","defaultStrokeWidth","defaultStrokeDasharray","strokePanel","defaultColorSet","strokeWidthPanel","defaultStrokeWidths","strokeStylePanel","defaultStrokeDasharrays","FrameMarker","LinearMarkerBase","grip1","grip2","manipulationStartX1","manipulationStartY1","manipulationStartX2","manipulationStartY2","defaultLength","adjustVisual","lmbState","LineMarker","selectorLine","visibleLine","lmState","fonts","currentFont","setCurrentFont","FontFamilyPanel","font","fontBoxContainer","fontBox","fontFamily","fontLabel","textOverflow","fontBoxes","newFont","onFontChanged","DEFAULT_TEXT","defaultFontFamily","setColor","setFont","renderText","sizeText","textEditDivClicked","showTextEditor","positionTextEditor","colorPanel","fontFamilyPanel","defaultFontFamilies","TextMarker","textElement","bgRectangle","found_1","span","createText","isMoved","pointerDownPoint","pointerDownTimestamp","Date","now","lastChild","split","createTSpan","textSize","getBBox","xScale","yScale","min","textBBox","getTextScale","position","getTextPosition","navigator","userAgent","setScale","textEditDiv","textEditor","lineHeight","contentEditable","ev","stopPropagation","fontSize","Number","parseFloat","parseInt","max","cancelBubble","clipboardData","content","getData","selection","getSelection","rangeCount","deleteFromDocument","getRangeAt","insertNode","createTextNode","preventDefault","hideVisual","focus","execCommand","textScale","rPosition","rWH","showVisual","dblClick","hideControlBox","showControlBox","textState","pixelRatio","freehandPixelRatio","addCanvas","finishCreation","setLineWidth","lineWidthPanel","FreehandMarker","drawingImage","createImage","canvasContext","strokeStyle","beginPath","moveTo","drawing","lineTo","stroke","closePath","newFreehandMarkerOnPointerUp","canvasElement","clientHeight","imgData","getImageData","startX","startY","endX","endY","containsData","row","col","tmpCanvas","putImageData","drawingImgUrl","setDrawingImage","currentType","setCurrentType","ArrowTypePanel","ti","arrowType","typeBoxContainer","this_1","leftTip","marginLeft","lineBox","rightTip","typeBoxes","newType","onArrowTypeChanged","getArrowPoints","setArrowType","arrowTypePanel","ArrowMarker","arrow1","arrow2","arrowBaseWidth","arrowBaseHeight","createPolygon","createTips","lineAngle1","a1transform","a2transform","amState","defaultFillColor","fillPanel","CoverMarker","opacities","currentOpacity","setCurrentOpacity","OpacityPanel","opacityBoxContainer","opacityBoxes","onOpacityChanged","setOpacity","defaultHighlightColor","defaultHighlightOpacity","opacityPanel","defaultOpacitySteps","HighlightMarker","defaultStrokeColor","bgColor","setBgColor","getTipPoints","positionTip","setTipPoints","bgColorPanel","FillColorIcon","tipGrip","CalloutMarker","tip","createTip","tipMoving","isCreating","tipPosition","fillColorChanged","tipBase1Position","tipBase2Position","offset","baseWidth","cornerAngle","calloutState","EllipseMarker","createEllipse","MeasurementMarker","tip1","tip2","tipLength","EllipseFrameMarker","UndoRedoManager","undoStack","redoStack","stepData","JSON","stringify","lastRedoStep","lastStep","CurveMarker","selectorCurve","visibleCurve","curveGrip","curveX","curveY","createPath","getPathD","manipulationStartCurveX","manipulationStartCurveY","curveControlLine1","curveControlLine2","firstChild","markerArea","cancelable","MarkerAreaEvent","_defaultPrevented","dataUrl","EventListenerRepository","eventType","handler","DEFAULT_MARKER_TYPES","Settings","targetRoot","removeStyleSheet","open","setTopLeft","toolbarButtonClicked","createNewMarker","addNewMarker","markerCreated","onPointerDown","onDblClick","onPointerMove","onPointerUp","onPointerOut","onKeyUp","overrideOverflow","restoreOverflow","close","closeUI","addCloseEventListener","removeCloseEventListener","addRenderEventListener","removeRenderEventListener","clientToLocalCoordinates","onWindowResize","deleteSelectedMarker","setWindowHeight","removeMarker","onPopupTargetResize","showNotesEditor","hideNotesEditor","stepZoom","blur","MarkerArea","_availableMarkerTypes","mt","typeType","ALL_MARKER_TYPES","allT","_isOpen","_zoomLevel","editorCanvas","contentDiv","scrollTo","setupResizeObserver","setEditingTarget","initMarkerCanvas","initOverlay","attachEvents","isLicensed","addLogo","_isFocused","showUI","eventListeners","renderer","renderAtNaturalSize","renderImageType","renderImageQuality","renderMarkersOnly","renderWidth","renderHeight","rasterize","HTMLImageElement","renderTarget","suppressBeforeClose","isOpen","cancel_1","defaultPrevented","coverDiv","targetObserver","unobserve","removeEventListener","detachEvents","markers","event","ResizeObserver","observe","ratio","windowHeight","innerHeight","imageWidth","imageHeight","editingTarget","markerImageHolder","positionMarkerImage","toolbar","positionLogo","scaleMarkers","preScaleSelectedMarker","targetRect","getBoundingClientRect","bodyRect","setProperty","transformOrigin","nodes","defs","createDefs","append","zoomLevel","attachWindowEvents","detachWindowEvents","logoUI","link","href","justifyItems","scrollXState","scrollX","scrollYState","scrollY","bodyOverflowState","scroll","_silentRenderMode","userSelect","coverTop","getClientRects","item","zIndex","uiDiv","flexDirection","popupMargin","addButtonClickListener","show","hideToolbar","flexShrink","maxHeight","marginTop","toolbox","hideToolbox","dispose","mode","addUndoStep","buttonType","switchToSelectMode","clear","undo","redo","notesArea","startRenderAndClose","cancel_2","MarkerEvent","marker_1","notesAreaStyleClassName","alignSelf","isNotesAreaOpen","undoRedoManager","selectLastMarker","zoomStepIndex","zoomSteps","scrollBy","prevPanPoint","render","MarkerAreaRenderEvent","deselectCurrentMarker","markerState","mType","setActiveMarkerButton","setPanelButtons","toolboxPanels","defaultColorsFollowCurrentColors","isSelected","touchPoints","pointerType","hitMarker","m","isDragging","clientX","clientY","panTo","clientRect","positionUI","addKey","_previousCurrentMarker"],"mappings":"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"}
\ No newline at end of file
diff --git a/capsule-prototype/js/libs/markerjs2/markerjs2.js b/capsule-prototype/js/libs/markerjs2/markerjs2.js
new file mode 100644
index 0000000000000000000000000000000000000000..1af98f56955b25317c6271976e3c335009bfb0b8
--- /dev/null
+++ b/capsule-prototype/js/libs/markerjs2/markerjs2.js
@@ -0,0 +1,16 @@
+!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).markerjs2={})}(this,(function(t){"use strict";
+/*! *****************************************************************************
+    Copyright (c) Microsoft Corporation.
+
+    Permission to use, copy, modify, and/or distribute this software for any
+    purpose with or without fee is hereby granted.
+
+    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+    REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+    AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+    INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+    LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+    OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+    PERFORMANCE OF THIS SOFTWARE.
+    ***************************************************************************** */var e=function(t,i){return(e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])})(t,i)};function i(t,i){function o(){this.constructor=t}e(t,i),t.prototype=null===i?Object.create(i):(o.prototype=i.prototype,new o)}function o(t,e,i,o){return new(i||(i=Promise))((function(s,r){function n(t){try{h(o.next(t))}catch(t){r(t)}}function a(t){try{h(o.throw(t))}catch(t){r(t)}}function h(t){var e;t.done?s(t.value):(e=t.value,e instanceof i?e:new i((function(t){t(e)}))).then(n,a)}h((o=o.apply(t,e||[])).next())}))}function s(t,e){var i,o,s,r,n={label:0,sent:function(){if(1&s[0])throw s[1];return s[1]},trys:[],ops:[]};return r={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(r[Symbol.iterator]=function(){return this}),r;function a(r){return function(a){return function(r){if(i)throw new TypeError("Generator is already executing.");for(;n;)try{if(i=1,o&&(s=2&r[0]?o.return:r[0]?o.throw||((s=o.return)&&s.call(o),0):o.next)&&!(s=s.call(o,r[1])).done)return s;switch(o=0,s&&(r=[2&r[0],s.value]),r[0]){case 0:case 1:s=r;break;case 4:return n.label++,{value:r[1],done:!1};case 5:n.label++,o=r[1],r=[0];continue;case 7:r=n.ops.pop(),n.trys.pop();continue;default:if(!(s=n.trys,(s=s.length>0&&s[s.length-1])||6!==r[0]&&2!==r[0])){n=0;continue}if(3===r[0]&&(!s||r[1]>s[0]&&r[1]<s[3])){n.label=r[1];break}if(6===r[0]&&n.label<s[1]){n.label=s[1],s=r;break}if(s&&n.label<s[2]){n.label=s[2],n.ops.push(r);break}s[2]&&n.ops.pop(),n.trys.pop();continue}r=e.call(t,n)}catch(t){r=[6,t],o=0}finally{i=s=0}if(5&r[0])throw r[1];return{value:r[0]?r[1]:void 0,done:!0}}([r,a])}}}function r(){for(var t=0,e=0,i=arguments.length;e<i;e++)t+=arguments[e].length;var o=Array(t),s=0;for(e=0;e<i;e++)for(var r=arguments[e],n=0,a=r.length;n<a;n++,s++)o[s]=r[n];return o}var n=function(){function t(){}return t.createDefs=function(){return document.createElementNS("http://www.w3.org/2000/svg","defs")},t.setAttributes=function(t,e){for(var i=0,o=e;i<o.length;i++){var s=o[i],r=s[0],n=s[1];t.setAttribute(r,n)}},t.createRect=function(e,i,o){var s=document.createElementNS("http://www.w3.org/2000/svg","rect");return s.setAttribute("width",e.toString()),s.setAttribute("height",i.toString()),o&&t.setAttributes(s,o),s},t.createLine=function(e,i,o,s,r){var n=document.createElementNS("http://www.w3.org/2000/svg","line");return n.setAttribute("x1",e.toString()),n.setAttribute("y1",i.toString()),n.setAttribute("x2",o.toString()),n.setAttribute("y2",s.toString()),r&&t.setAttributes(n,r),n},t.createPolygon=function(e,i){var o=document.createElementNS("http://www.w3.org/2000/svg","polygon");return o.setAttribute("points",e),i&&t.setAttributes(o,i),o},t.createCircle=function(e,i){var o=document.createElementNS("http://www.w3.org/2000/svg","circle");return o.setAttribute("cx",(e/2).toString()),o.setAttribute("cy",(e/2).toString()),o.setAttribute("r",e.toString()),i&&t.setAttributes(o,i),o},t.createEllipse=function(e,i,o){var s=document.createElementNS("http://www.w3.org/2000/svg","ellipse");return s.setAttribute("cx",(e/2).toString()),s.setAttribute("cy",(i/2).toString()),s.setAttribute("rx",(e/2).toString()),s.setAttribute("ry",(i/2).toString()),o&&t.setAttributes(s,o),s},t.createGroup=function(e){var i=document.createElementNS("http://www.w3.org/2000/svg","g");return e&&t.setAttributes(i,e),i},t.createTransform=function(){return document.createElementNS("http://www.w3.org/2000/svg","svg").createSVGTransform()},t.createMarker=function(e,i,o,s,r,n,a){var h=document.createElementNS("http://www.w3.org/2000/svg","marker");return t.setAttributes(h,[["id",e],["orient",i],["markerWidth",o.toString()],["markerHeight",s.toString()],["refX",r.toString()],["refY",n.toString()]]),h.appendChild(a),h},t.createText=function(e){var i=document.createElementNS("http://www.w3.org/2000/svg","text");return i.setAttribute("x","0"),i.setAttribute("y","0"),e&&t.setAttributes(i,e),i},t.createTSpan=function(e,i){var o=document.createElementNS("http://www.w3.org/2000/svg","tspan");return o.textContent=e,i&&t.setAttributes(o,i),o},t.createImage=function(e){var i=document.createElementNS("http://www.w3.org/2000/svg","image");return e&&t.setAttributes(i,e),i},t.createPoint=function(t,e){var i=document.createElementNS("http://www.w3.org/2000/svg","svg").createSVGPoint();return i.x=t,i.y=e,i},t.createPath=function(e,i){var o=document.createElementNS("http://www.w3.org/2000/svg","path");return o.setAttribute("d",e),i&&t.setAttributes(o,i),o},t}(),a=function(){function t(){}return t.addKey=function(e){t.key=e},Object.defineProperty(t,"isLicensed",{get:function(){return!!t.key&&new RegExp(/^MJS2-[A-Z][0-9]{3}-[A-Z][0-9]{3}-[0-9]{4}$/,"i").test(t.key)},enumerable:!1,configurable:!0}),t}(),h=function(){function t(){this.naturalSize=!1,this.imageType="image/png",this.markersOnly=!1}return t.prototype.rasterize=function(t,e,i){var o=this;return new Promise((function(s){var r=void 0!==i?i:document.createElement("canvas");null===t&&(o.markersOnly=!0,o.naturalSize=!1);var n=document.createElementNS("http://www.w3.org/2000/svg","svg");n.setAttribute("xmlns","http://www.w3.org/2000/svg"),n.setAttribute("width",e.width.baseVal.valueAsString),n.setAttribute("height",e.height.baseVal.valueAsString),n.setAttribute("viewBox","0 0 "+e.viewBox.baseVal.width.toString()+" "+e.viewBox.baseVal.height.toString()),n.innerHTML=e.innerHTML,!0===o.naturalSize?(n.width.baseVal.value=t.naturalWidth,n.height.baseVal.value=t.naturalHeight):void 0!==o.width&&void 0!==o.height&&(n.width.baseVal.value=o.width,n.height.baseVal.value=o.height),r.width=n.width.baseVal.value,r.height=n.height.baseVal.value;var a=n.outerHTML,h=r.getContext("2d");!0!==o.markersOnly&&h.drawImage(t,0,0,r.width,r.height);var l=window.URL,p=new Image(r.width,r.height);p.setAttribute("crossOrigin","anonymous");var c=new Blob([a],{type:"image/svg+xml"}),u=l.createObjectURL(c);p.onload=function(){h.drawImage(p,0,0),l.revokeObjectURL(u);var t=r.toDataURL(o.imageType,o.imageQuality);s(t)},p.src=u}))},t}(),l=function(){function t(){}return Object.defineProperty(t,"defaultSettings",{get:function(){return{canvasBackgroundColor:"#ffffff",toolbarBackgroundColor:"#111111",toolbarBackgroundHoverColor:"#333333",toolbarColor:"#eeeeee",toolbarHeight:40,toolboxColor:"#eeeeee",toolboxAccentColor:"#3080c3",undoButtonVisible:!0,redoButtonVisible:!1,zoomButtonVisible:!1,zoomOutButtonVisible:!1,clearButtonVisible:!1,resultButtonBlockVisible:!0,logoPosition:"left"}},enumerable:!1,configurable:!0}),Object.defineProperty(t,"fadeInAnimationClassName",{get:function(){return t.CLASS_PREFIX+"fade_in"},enumerable:!1,configurable:!0}),Object.defineProperty(t,"fadeOutAnimationClassName",{get:function(){return t.CLASS_PREFIX+"fade_out"},enumerable:!1,configurable:!0}),t.addClass=function(e){return void 0===t.styleSheet&&t.addStyleSheet(),t.classes.push(e),t.styleSheet.sheet.insertRule("."+e.name+" {"+e.style+"}",t.styleSheet.sheet.cssRules.length),e},t.addRule=function(e){void 0===t.styleSheet&&t.addStyleSheet(),t.rules.push(e),t.styleSheet.sheet.insertRule(e.selector+" {"+e.style+"}",t.styleSheet.sheet.cssRules.length)},t.addStyleSheet=function(){var e;t.styleSheet=document.createElement("style"),(null!==(e=t.styleSheetRoot)&&void 0!==e?e:document.head).appendChild(t.styleSheet),t.addRule(new p("."+t.CLASS_PREFIX+" h3","font-family: sans-serif")),t.addRule(new p("@keyframes "+t.CLASS_PREFIX+"_fade_in_animation_frames","\n        from {\n          opacity: 0;\n        }\n        to {\n          opacity: 1;\n        }\n    ")),t.addRule(new p("@keyframes "+t.CLASS_PREFIX+"_fade_out_animation_frames","\n        from {\n          opacity: 1;\n        }\n        to {\n          opacity: 0;\n        }\n    ")),t.addClass(new c("fade_in","\n      animation-duration: 0.3s;\n      animation-name: "+t.CLASS_PREFIX+"_fade_in_animation_frames;\n    ")),t.addClass(new c("fade_out","\n      animation-duration: 0.3s;\n      animation-name: "+t.CLASS_PREFIX+"_fade_out_animation_frames;\n    "))},t.removeStyleSheet=function(){var e;t.styleSheet&&((null!==(e=t.styleSheetRoot)&&void 0!==e?e:document.head).removeChild(t.styleSheet),t.styleSheet=void 0)},t.CLASS_PREFIX="__markerjs2_",t.classes=[],t.rules=[],t.settings=t.defaultSettings,t}(),p=function(t,e){this.selector=t,this.style=e},c=function(){function t(t,e){this._localName=t,this.style=e}return Object.defineProperty(t.prototype,"name",{get:function(){return""+l.CLASS_PREFIX+this._localName},enumerable:!1,configurable:!0}),t}(),u=function(){function t(t,e,i,o){this.buttons=[],this.markerButtons=[],this.buttonClickListeners=[],this.markerjsContainer=t,this.displayMode=e,this.markerItems=i,this.uiStyleSettings=o,this.addStyles(),this.adjustLayout=this.adjustLayout.bind(this),this.overflowButtonClicked=this.overflowButtonClicked.bind(this),this.setCurrentMarker=this.setCurrentMarker.bind(this)}return t.prototype.show=function(t){var e=this;this.uiContainer=document.createElement("div"),this.uiContainer.style.visibility=t,this.uiContainer.className=this.toolbarStyleClass.name+" "+l.fadeInAnimationClassName+" "+(this.uiStyleSettings.toolbarStyleColorsClassName?this.uiStyleSettings.toolbarStyleColorsClassName:this.toolbarStyleColorsClass.name);var i=document.createElement("div");i.className=this.toolbarBlockStyleClass.name,i.style.whiteSpace="nowrap",this.uiContainer.appendChild(i),this.addActionButton(i,'<svg viewBox="0 0 24 24"><path d="M10.07 14.27a.997.997 0 011.33.48l2.3 4.99 1.8-.85-2.31-4.98c-.24-.5-.02-1.1.48-1.33l.28-.08 2.3-.45L8 5.12V15.9l1.82-1.47.25-.16m3.57 7.7a.99.99 0 01-1.33-.47l-2.18-4.74-2.51 2.02c-.17.14-.38.22-.62.22a1 1 0 01-1-1V3a1 1 0 011-1c.24 0 .47.09.64.23l.01-.01 11.49 9.64a1.001 1.001 0 01-.44 1.75l-3.16.62 2.2 4.73c.26.5.02 1.09-.48 1.32l-3.62 1.69z"/></svg>',"select"),this.addActionButton(i,'<svg viewBox="0 0 24 24"><path d="M9 3v1H4v2h1v13a2 2 0 002 2h10a2 2 0 002-2V6h1V4h-5V3H9M7 6h10v13H7V6m2 2v9h2V8H9m4 0v9h2V8h-2z"/></svg>',"delete"),this.uiStyleSettings.clearButtonVisible&&this.addActionButton(i,'<svg viewBox="0 0 24 24"><path d="M19.36 2.72l1.42 1.42-5.72 5.71c1.07 1.54 1.22 3.39.32 4.59L9.06 8.12c1.2-.9 3.05-.75 4.59.32l5.71-5.72M5.93 17.57c-2.01-2.01-3.24-4.41-3.58-6.65l4.88-2.09 7.44 7.44-2.09 4.88c-2.24-.34-4.64-1.57-6.65-3.58z"/></svg>',"clear"),this.uiStyleSettings.undoButtonVisible&&this.addActionButton(i,'<svg viewBox="0 0 24 24"><path d="M12.5 8c-2.65 0-5.05 1-6.9 2.6L2 7v9h9l-3.62-3.62c1.39-1.16 3.16-1.88 5.12-1.88 3.54 0 6.55 2.31 7.6 5.5l2.37-.78C21.08 11.03 17.15 8 12.5 8z"/></svg>',"undo"),this.uiStyleSettings.redoButtonVisible&&this.addActionButton(i,'<svg viewBox="0 0 24 24"><path d="M18.4 10.6C16.55 9 14.15 8 11.5 8c-4.65 0-8.58 3.03-9.96 7.22L3.9 16a8.002 8.002 0 017.6-5.5c1.95 0 3.73.72 5.12 1.88L13 16h9V7l-3.6 3.6z"/></svg>',"redo"),this.uiStyleSettings.zoomButtonVisible&&this.addActionButton(i,'<svg viewBox="0 0 24 24"><path d="M15.5 14l5 5-1.5 1.5-5-5v-.79l-.27-.28A6.471 6.471 0 019.5 16 6.5 6.5 0 013 9.5 6.5 6.5 0 019.5 3 6.5 6.5 0 0116 9.5c0 1.61-.59 3.09-1.57 4.23l.28.27h.79m-6 0C12 14 14 12 14 9.5S12 5 9.5 5 5 7 5 9.5 7 14 9.5 14m2.5-4h-2v2H9v-2H7V9h2V7h1v2h2v1z"/></svg>',"zoom"),this.uiStyleSettings.zoomButtonVisible&&this.uiStyleSettings.zoomOutButtonVisible&&this.addActionButton(i,'<svg viewBox="0 0 24 24"><path d="M15.5 14h-.79l-.28-.27A6.471 6.471 0 0016 9.5 6.5 6.5 0 009.5 3 6.5 6.5 0 003 9.5 6.5 6.5 0 009.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 5 1.5-1.5-5-5m-6 0C7 14 5 12 5 9.5S7 5 9.5 5 14 7 14 9.5 12 14 9.5 14M7 9h5v1H7V9z"/></svg>',"zoom-out"),this.uiStyleSettings.notesButtonVisible&&this.addActionButton(i,'<svg viewBox="0 0 24 24"><path d="M18.13 12l1.26-1.26c.44-.44 1-.68 1.61-.74V9l-6-6H5c-1.11 0-2 .89-2 2v14a2 2 0 002 2h6v-1.87l.13-.13H5V5h7v7h6.13M14 4.5l5.5 5.5H14V4.5m5.13 9.33l2.04 2.04L15.04 22H13v-2.04l6.13-6.13m3.72.36l-.98.98-2.04-2.04.98-.98c.19-.2.52-.2.72 0l1.32 1.32c.2.2.2.53 0 .72z"/></svg>',"notes"),this.markerButtonBlock=document.createElement("div"),this.markerButtonBlock.className=this.toolbarBlockStyleClass.name,this.markerButtonBlock.style.flexGrow="2",this.markerButtonBlock.style.textAlign="center",this.uiContainer.appendChild(this.markerButtonBlock),this.markerButtonOverflowBlock=document.createElement("div"),this.markerButtonOverflowBlock.className=this.toolbarOverflowBlockStyleClass.name+" "+(this.uiStyleSettings.toolbarOverflowBlockStyleColorsClassName?this.uiStyleSettings.toolbarOverflowBlockStyleColorsClassName:this.toolbarOverflowBlockStyleColorsClass.name),this.markerButtonOverflowBlock.style.display="none",this.uiContainer.appendChild(this.markerButtonOverflowBlock),this.markerItems&&(this.markerItems.forEach((function(t){var i=document.createElement("div");i.className=""+e.toolbarButtonStyleClass.name,i.setAttribute("data-type-name",t.typeName),i.innerHTML=t.icon,i.addEventListener("click",(function(){e.markerToolbarButtonClicked(i,t)})),e.buttons.push(i),e.markerButtons.push(i)})),this.overflowButton=document.createElement("div"),this.overflowButton.className=this.toolbarButtonStyleClass.name+" "+(this.uiStyleSettings.toolbarButtonStyleColorsClassName?this.uiStyleSettings.toolbarButtonStyleColorsClassName:this.toolbarButtonStyleColorsClass.name),this.overflowButton.innerHTML='<svg viewBox="0 0 24 24"><path d="M12 16a2 2 0 012 2 2 2 0 01-2 2 2 2 0 01-2-2 2 2 0 012-2m0-6a2 2 0 012 2 2 2 0 01-2 2 2 2 0 01-2-2 2 2 0 012-2m0-6a2 2 0 012 2 2 2 0 01-2 2 2 2 0 01-2-2 2 2 0 012-2z"/></svg>',this.overflowButton.addEventListener("click",this.overflowButtonClicked),this.markerButtonBlock.appendChild(this.overflowButton));var o=document.createElement("div");o.className=this.toolbarBlockStyleClass.name,o.style.whiteSpace="nowrap",o.style.display=!1!==this.uiStyleSettings.resultButtonBlockVisible?"":"none",this.uiContainer.appendChild(o),this.addActionButton(o,'<svg viewBox="0 0 24 24"><path d="M9 20.42l-6.21-6.21 2.83-2.83L9 14.77l9.88-9.89 2.83 2.83L9 20.42z"/></svg>',"render"),this.addActionButton(o,'<svg viewBox="0 0 24 24"><path d="M20 6.91L17.09 4 12 9.09 6.91 4 4 6.91 9.09 12 4 17.09 6.91 20 12 14.91 17.09 20 20 17.09 14.91 12 20 6.91z"/></svg>',"close"),this.markerjsContainer.appendChild(this.uiContainer),this.setSelectMode(),this.setCurrentMarker(),this.adjustLayout()},t.prototype.addButtonClickListener=function(t){this.buttonClickListeners.push(t)},t.prototype.removeButtonClickListener=function(t){this.buttonClickListeners.indexOf(t)>-1&&this.buttonClickListeners.splice(this.buttonClickListeners.indexOf(t),1)},t.prototype.setSelectMode=function(){this.resetButtonStyles(),this.setActiveButton(this.buttons[0])},t.prototype.adjustLayout=function(){if(this.markerButtons&&this.markerButtons.length>0){var t=Math.floor(this.markerButtonBlock.clientWidth/this.uiStyleSettings.toolbarHeight)-1;this.markerButtonBlock.innerHTML="",this.markerButtonOverflowBlock.innerHTML="";for(var e=0;e<this.markerButtons.length;e++)e<t||e===t&&this.markerButtons.length-1===t?this.markerButtonBlock.appendChild(this.markerButtons[e]):(e===t&&this.markerButtonBlock.appendChild(this.overflowButton),this.markerButtonOverflowBlock.appendChild(this.markerButtons[e]))}},t.prototype.overflowButtonClicked=function(){"none"!==this.markerButtonOverflowBlock.style.display?(this.markerButtonOverflowBlock.className=this.markerButtonOverflowBlock.className.replace(l.fadeInAnimationClassName,""),this.markerButtonOverflowBlock.style.display="none"):(this.markerButtonOverflowBlock.className+=" "+l.fadeInAnimationClassName,this.markerButtonOverflowBlock.style.top=this.uiContainer.offsetTop+this.overflowButton.offsetHeight+"px",this.markerButtonOverflowBlock.style.right=this.uiContainer.offsetWidth-this.overflowButton.offsetLeft-this.overflowButton.offsetWidth+2*this.uiContainer.offsetLeft+"px",this.markerButtonOverflowBlock.style.display="inline-block")},t.prototype.resetButtonStyles=function(){var t=this;this.buttons.forEach((function(e){e.className=e.className.replace(t.uiStyleSettings.toolbarButtonStyleColorsClassName?t.uiStyleSettings.toolbarButtonStyleColorsClassName:t.toolbarButtonStyleColorsClass.name,"").trim(),e.className=e.className.replace(t.uiStyleSettings.toolbarActiveButtonStyleColorsClassName?t.uiStyleSettings.toolbarActiveButtonStyleColorsClassName:t.toolbarActiveButtonStyleColorsClass.name,"").trim(),e.className+=" "+(t.uiStyleSettings.toolbarButtonStyleColorsClassName?t.uiStyleSettings.toolbarButtonStyleColorsClassName:t.toolbarButtonStyleColorsClass.name)}))},t.prototype.addActionButton=function(t,e,i){var o=this,s=document.createElement("div");switch(s.className=""+this.toolbarButtonStyleClass.name,s.innerHTML=e,s.setAttribute("data-action",i),s.addEventListener("click",(function(){o.actionToolbarButtonClicked(s,i)})),i){case"select":s.style.fill=this.uiStyleSettings.selectButtonColor;break;case"delete":case"clear":s.style.fill=this.uiStyleSettings.deleteButtonColor;break;case"undo":case"redo":s.style.fill=this.uiStyleSettings.selectButtonColor;break;case"render":s.style.fill=this.uiStyleSettings.okButtonColor;break;case"close":s.style.fill=this.uiStyleSettings.closeButtonColor}t.appendChild(s),this.buttons.push(s)},t.prototype.addStyles=function(){this.toolbarStyleClass=l.addClass(new c("toolbar","\n      width: 100%;\n      flex-shrink: 0;\n      display: flex;\n      flex-direction: row;\n      justify-content: space-between;      \n      height: "+this.uiStyleSettings.toolbarHeight+"px;\n      box-sizing: content-box;\n      "+("inline"===this.displayMode?"border-top-left-radius: "+Math.round(this.uiStyleSettings.toolbarHeight/10)+"px;":"")+"\n      "+("inline"===this.displayMode?"border-top-right-radius: "+Math.round(this.uiStyleSettings.toolbarHeight/10)+"px;":"")+"\n      overflow: hidden;\n    ")),this.toolbarStyleColorsClass=l.addClass(new c("toolbar_colors","\n      background-color: "+this.uiStyleSettings.toolbarBackgroundColor+";\n      box-shadow: 0px 3px rgba(33, 33, 33, 0.1);\n    ")),this.toolbarBlockStyleClass=l.addClass(new c("toolbar-block","\n        display: inline-block;\n        box-sizing: content-box;\n    ")),this.toolbarOverflowBlockStyleClass=l.addClass(new c("toolbar-overflow-block","\n        position: absolute;\n        top: "+this.uiStyleSettings.toolbarHeight+"px;\n        max-width: "+2*this.uiStyleSettings.toolbarHeight+"px;\n        z-index: 10;\n        box-sizing: content-box;\n      ")),this.toolbarOverflowBlockStyleColorsClass=l.addClass(new c("toolbar-overflow-block_colors","\n        background-color: "+this.uiStyleSettings.toolbarBackgroundColor+";\n      "));var t=this.uiStyleSettings.toolbarHeight/4;this.toolbarButtonStyleClass=l.addClass(new c("toolbar_button","\n      display: inline-block;\n      width: "+(this.uiStyleSettings.toolbarHeight-2*t)+"px;\n      height: "+(this.uiStyleSettings.toolbarHeight-2*t)+"px;\n      padding: "+t+"px;\n      box-sizing: content-box;\n    ")),this.toolbarButtonStyleColorsClass=l.addClass(new c("toolbar_button_colors","\n      fill: "+this.uiStyleSettings.toolbarColor+";\n    ")),this.toolbarActiveButtonStyleColorsClass=l.addClass(new c("toolbar_active_button","\n      fill: "+this.uiStyleSettings.toolbarColor+";\n      background-color: "+this.uiStyleSettings.toolbarBackgroundHoverColor+"\n    ")),l.addRule(new p("."+this.toolbarButtonStyleClass.name+" svg","\n      height: "+this.uiStyleSettings.toolbarHeight/2+"px;\n    ")),l.addRule(new p("."+this.toolbarButtonStyleColorsClass.name+":hover","\n        background-color: "+this.uiStyleSettings.toolbarBackgroundHoverColor+"\n    "))},t.prototype.markerToolbarButtonClicked=function(t,e){this.setActiveButton(t),this.buttonClickListeners&&this.buttonClickListeners.length>0&&this.buttonClickListeners.forEach((function(t){return t("marker",e)})),this.markerButtonOverflowBlock.style.display="none"},t.prototype.actionToolbarButtonClicked=function(t,e){this.buttonClickListeners&&this.buttonClickListeners.length>0&&this.buttonClickListeners.forEach((function(t){return t("action",e)})),this.markerButtonOverflowBlock.style.display="none",this.setActiveButton(this.buttons[0])},t.prototype.setActiveButton=function(t){this.resetButtonStyles(),t.className=t.className.replace(this.uiStyleSettings.toolbarButtonStyleColorsClassName?this.uiStyleSettings.toolbarButtonStyleColorsClassName:this.toolbarButtonStyleColorsClass.name,"").trim(),t.className+=" "+(this.uiStyleSettings.toolbarActiveButtonStyleColorsClassName?this.uiStyleSettings.toolbarActiveButtonStyleColorsClassName:this.toolbarActiveButtonStyleColorsClass.name)},t.prototype.setActiveMarkerButton=function(t){var e=this.markerButtons.find((function(e){return e.getAttribute("data-type-name")===t}));e&&this.setActiveButton(e)},t.prototype.setCurrentMarker=function(t){var e=this;this.currentMarker=t,this.buttons.filter((function(t){return/delete|notes/.test(t.getAttribute("data-action"))})).forEach((function(t){void 0===e.currentMarker?(t.style.fillOpacity="0.4",t.style.pointerEvents="none"):(t.style.fillOpacity="1",t.style.pointerEvents="all")}))},t}(),d=function(){function t(t,e,i){this.panels=[],this.panelButtons=[],this.markerjsContainer=t,this.displayMode=e,this.uiStyleSettings=i,this.panelButtonClick=this.panelButtonClick.bind(this),this.addStyles()}return t.prototype.addStyles=function(){var t;this.toolboxStyleClass=l.addClass(new c("toolbox","\n      width: 100%;\n      flex-shrink: 0;\n      display: flex;\n      flex-direction: column;\n      font-family: sans-serif;\n      "+("popup"===this.displayMode?"height:"+2.5*this.uiStyleSettings.toolbarHeight+"px;":"")+"\n      box-sizing: content-box;\n      "+("popup"===this.displayMode?"background-color: "+this.uiStyleSettings.canvasBackgroundColor+";":"")+"\n      "+("inline"===this.displayMode?"border-bottom-left-radius: "+Math.round(this.uiStyleSettings.toolbarHeight/10)+"px;":"")+"\n      "+("inline"===this.displayMode?"border-bottom-right-radius: "+Math.round(this.uiStyleSettings.toolbarHeight/10)+"px;":"")+"\n      overflow: hidden;\n    ")),this.toolboxStyleColorsClass=l.addClass(new c("toolbox_colors","\n      color: "+this.uiStyleSettings.toolboxColor+";\n    "));var e=this.uiStyleSettings.toolbarHeight/4;this.toolboxButtonRowStyleClass=l.addClass(new c("toolbox-button-row","\n      display: flex;\n      cursor: default;\n      box-sizing: content-box;\n    ")),this.toolboxButtonRowStyleColorsClass=l.addClass(new c("toolbox-button-row_colors","\n      background-color: "+this.uiStyleSettings.toolbarBackgroundColor+";\n    ")),this.toolboxPanelRowStyleClass=l.addClass(new c("toolbox-panel-row","\n      display: flex;\n      "+("inline"===this.displayMode?"position: absolute;":"")+"\n      "+("inline"===this.displayMode?"bottom: "+this.uiStyleSettings.toolbarHeight+"px;":"")+"\n      cursor: default;\n      height: "+1.5*this.uiStyleSettings.toolbarHeight+"px;\n      "+("inline"===this.displayMode?"width: 100%;":"")+"\n      box-sizing: content-box;\n    ")),this.toolboxPanelRowStyleColorsClass=l.addClass(new c("toolbox-panel-row_colors","\n      background-color: "+(null!==(t=this.uiStyleSettings.toolboxBackgroundColor)&&void 0!==t?t:this.uiStyleSettings.toolbarBackgroundHoverColor)+";\n    ")),this.toolboxButtonStyleClass=l.addClass(new c("toolbox_button","\n      display: inline-block;\n      width: "+(this.uiStyleSettings.toolbarHeight-2*e)+"px;\n      height: "+(this.uiStyleSettings.toolbarHeight-2*e)+"px;\n      padding: "+e+"px;\n      box-sizing: content-box;\n    ")),this.toolboxButtonStyleColorsClass=l.addClass(new c("toolbox-button_colors","\n      fill: "+this.uiStyleSettings.toolbarColor+";\n    ")),this.toolboxActiveButtonStyleColorsClass=l.addClass(new c("toolbox-active-button_colors","\n      background-color: "+this.uiStyleSettings.toolbarBackgroundHoverColor+";\n      fill: "+this.uiStyleSettings.toolbarColor+";\n    ")),l.addRule(new p("."+this.toolboxButtonStyleColorsClass.name+":hover","\n        background-color: "+this.uiStyleSettings.toolbarBackgroundHoverColor+"\n    ")),l.addRule(new p("."+this.toolboxButtonStyleClass.name+" svg","\n      height: "+this.uiStyleSettings.toolbarHeight/2+"px;\n    "))},t.prototype.show=function(t){var e;this.uiContainer=document.createElement("div"),this.uiContainer.style.visibility=t,this.uiContainer.className=this.toolboxStyleClass.name+" "+(null!==(e=this.uiStyleSettings.toolboxStyleColorsClassName)&&void 0!==e?e:this.toolboxStyleColorsClass.name),this.markerjsContainer.appendChild(this.uiContainer)},t.prototype.setPanelButtons=function(t){var e,i,o=this;this.panels=t,void 0!==this.uiContainer&&(this.uiContainer.innerHTML="",this.panelRow=document.createElement("div"),this.panelRow.className=this.toolboxPanelRowStyleClass.name+" "+(null!==(e=this.uiStyleSettings.toolboxPanelRowStyleColorsClassName)&&void 0!==e?e:this.toolboxPanelRowStyleColorsClass.name),this.uiContainer.appendChild(this.panelRow),this.buttonRow=document.createElement("div"),this.buttonRow.className=this.toolboxButtonRowStyleClass.name+" "+(null!==(i=this.uiStyleSettings.toolboxButtonRowStyleColorsClassName)&&void 0!==i?i:this.toolboxButtonRowStyleColorsClass.name)+" ",this.uiContainer.appendChild(this.buttonRow),this.panelButtons.splice(0),this.panels.forEach((function(t){var e,i=document.createElement("div");i.className=o.toolboxButtonStyleClass.name+" "+(null!==(e=o.uiStyleSettings.toolboxButtonStyleColorsClassName)&&void 0!==e?e:o.toolboxButtonStyleColorsClass.name),i.innerHTML=t.icon,i.title=t.title,i.addEventListener("click",(function(){o.panelButtonClick(t)})),o.panelButtons.push(i),o.buttonRow.appendChild(i)})),"inline"===this.displayMode?this.panelRow.style.display="none":this.panelRow.style.visibility="hidden")},t.prototype.panelButtonClick=function(t){var e=this,i=-1;if(t!==this.activePanel){i=this.panels.indexOf(t),this.panelRow.innerHTML="";var o=t.getUi();o.style.margin=this.uiStyleSettings.toolbarHeight/4+"px",this.panelRow.appendChild(o),this.panelRow.style.display="flex",this.panelRow.style.visibility="visible",this.panelRow.className=this.panelRow.className.replace(l.fadeOutAnimationClassName,""),this.panelRow.className+=" "+l.fadeInAnimationClassName,this.activePanel=t}else this.activePanel=void 0,this.panelRow.className=this.panelRow.className.replace(l.fadeInAnimationClassName,""),this.panelRow.className+=" "+l.fadeOutAnimationClassName,setTimeout((function(){"inline"===e.displayMode?e.panelRow.style.display="none":e.panelRow.style.visibility="hidden"}),200);this.panelButtons.forEach((function(t,o){var s,r;t.className=e.toolboxButtonStyleClass.name+" "+(o===i?""+(null!==(s=e.uiStyleSettings.toolboxActiveButtonStyleColorsClassName)&&void 0!==s?s:e.toolboxActiveButtonStyleColorsClass.name):""+(null!==(r=e.uiStyleSettings.toolboxButtonStyleColorsClassName)&&void 0!==r?r:e.toolboxButtonStyleColorsClass.name))}))},t}(),y=function(t,e){this.title=t,this.icon=e},g=function(t){function e(e,i,o,s){var r=t.call(this,e,s||'<svg viewBox="0 0 24 24"><path d="M17.5 12a1.5 1.5 0 01-1.5-1.5A1.5 1.5 0 0117.5 9a1.5 1.5 0 011.5 1.5 1.5 1.5 0 01-1.5 1.5m-3-4A1.5 1.5 0 0113 6.5 1.5 1.5 0 0114.5 5 1.5 1.5 0 0116 6.5 1.5 1.5 0 0114.5 8m-5 0A1.5 1.5 0 018 6.5 1.5 1.5 0 019.5 5 1.5 1.5 0 0111 6.5 1.5 1.5 0 019.5 8m-3 4A1.5 1.5 0 015 10.5 1.5 1.5 0 016.5 9 1.5 1.5 0 018 10.5 1.5 1.5 0 016.5 12M12 3a9 9 0 00-9 9 9 9 0 009 9 1.5 1.5 0 001.5-1.5c0-.39-.15-.74-.39-1-.23-.27-.38-.62-.38-1a1.5 1.5 0 011.5-1.5H16a5 5 0 005-5c0-4.42-4.03-8-9-8z"/></svg>')||this;return r.colors=[],r.addTransparent=!1,r.colorBoxes=[],r.colors=i,r.currentColor=o,r.setCurrentColor=r.setCurrentColor.bind(r),r.getColorBox=r.getColorBox.bind(r),r}return i(e,t),e.prototype.getUi=function(){var t=this,e=document.createElement("div");return e.style.overflow="hidden",e.style.whiteSpace="nowrap",this.colors.forEach((function(i){var o=t.getColorBox(i);e.appendChild(o),t.colorBoxes.push(o)})),e},e.prototype.getColorBox=function(t){var e=this,i=l.settings.toolbarHeight/4,o=l.settings.toolbarHeight-i,s=document.createElement("div");s.style.display="inline-block",s.style.boxSizing="content-box",s.style.width=o-2+"px",s.style.height=o-2+"px",s.style.padding="1px",s.style.marginRight="2px",s.style.marginBottom="2px",s.style.borderWidth="2px",s.style.borderStyle="solid",s.style.borderRadius=(o+2)/2+"px",s.style.borderColor=t===this.currentColor?l.settings.toolboxAccentColor:"transparent",s.addEventListener("click",(function(){e.setCurrentColor(t,s)}));var r=document.createElement("div");return r.style.display="inline-block",r.style.width=o-2+"px",r.style.height=o-2+"px",r.style.backgroundColor=t,r.style.borderRadius=o/2+"px","transparent"===t&&(r.style.fill=l.settings.toolboxAccentColor,r.innerHTML='<svg viewBox="0 0 24 24">\n        <path d="M2,5.27L3.28,4L20,20.72L18.73,22L15.65,18.92C14.5,19.3 13.28,19.5 12,19.5C7,19.5 2.73,16.39 1,12C1.69,10.24 2.79,8.69 4.19,7.46L2,5.27M12,9A3,3 0 0,1 15,12C15,12.35 14.94,12.69 14.83,13L11,9.17C11.31,9.06 11.65,9 12,9M12,4.5C17,4.5 21.27,7.61 23,12C22.18,14.08 20.79,15.88 19,17.19L17.58,15.76C18.94,14.82 20.06,13.54 20.82,12C19.17,8.64 15.76,6.5 12,6.5C10.91,6.5 9.84,6.68 8.84,7L7.3,5.47C8.74,4.85 10.33,4.5 12,4.5M3.18,12C4.83,15.36 8.24,17.5 12,17.5C12.69,17.5 13.37,17.43 14,17.29L11.72,15C10.29,14.85 9.15,13.71 9,12.28L5.6,8.87C4.61,9.72 3.78,10.78 3.18,12Z" />\n      </svg>'),s.appendChild(r),s},e.prototype.setCurrentColor=function(t,e){this.currentColor=t,this.colorBoxes.forEach((function(t){t.style.borderColor=t===e?l.settings.toolboxAccentColor:"transparent"})),this.onColorChanged&&this.onColorChanged(t)},e}(y),f=function(){function t(t,e,i){this._state="new",this._isSelected=!1,this._container=t,this._overlayContainer=e,this.globalSettings=i}return Object.defineProperty(t.prototype,"typeName",{get:function(){return Object.getPrototypeOf(this).constructor.typeName},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"container",{get:function(){return this._container},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"overlayContainer",{get:function(){return this._overlayContainer},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"state",{get:function(){return this._state},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"toolboxPanels",{get:function(){return[]},enumerable:!1,configurable:!0}),t.prototype.ownsTarget=function(t){return!1},Object.defineProperty(t.prototype,"isSelected",{get:function(){return this._isSelected},enumerable:!1,configurable:!0}),t.prototype.select=function(){this.container.style.cursor="move",this._isSelected=!0},t.prototype.deselect=function(){this.container.style.cursor="default",this._isSelected=!1},t.prototype.pointerDown=function(t,e){},t.prototype.dblClick=function(t,e){},t.prototype.manipulate=function(t){},t.prototype.pointerUp=function(t){},t.prototype.dispose=function(){},t.prototype.addMarkerVisualToContainer=function(t){this.container.childNodes.length>0?this.container.insertBefore(t,this.container.childNodes[0]):this.container.appendChild(t)},t.prototype.getState=function(){return{typeName:t.typeName,state:this.state,notes:this.notes}},t.prototype.restoreState=function(t){this._state=t.state,this.notes=t.notes},t.prototype.scale=function(t,e){},t.prototype.colorChanged=function(t){this.onColorChanged&&this.onColorChanged(t)},t.prototype.fillColorChanged=function(t){this.onFillColorChanged&&this.onFillColorChanged(t)},t.typeName="MarkerBase",t}(),v=function(){function t(){this.findGripByVisual=this.findGripByVisual.bind(this)}return t.prototype.findGripByVisual=function(t){return this.topLeft.ownsTarget(t)?this.topLeft:this.topCenter.ownsTarget(t)?this.topCenter:this.topRight.ownsTarget(t)?this.topRight:this.centerLeft.ownsTarget(t)?this.centerLeft:this.centerRight.ownsTarget(t)?this.centerRight:this.bottomLeft.ownsTarget(t)?this.bottomLeft:this.bottomCenter.ownsTarget(t)?this.bottomCenter:this.bottomRight.ownsTarget(t)?this.bottomRight:void 0},t}(),m=function(){function t(){this.GRIP_SIZE=10,this.visual=n.createGroup(),this.visual.appendChild(n.createCircle(1.5*this.GRIP_SIZE,[["fill","transparent"]])),this.visual.appendChild(n.createCircle(this.GRIP_SIZE,[["fill","#cccccc"],["fill-opacity","0.7"],["stroke","#333333"],["stroke-width","2"],["stroke-opacity","0.7"]]))}return t.prototype.ownsTarget=function(t){return t===this.visual||t===this.visual.childNodes[0]||t===this.visual.childNodes[1]},t}(),C=function(){function t(){}return t.toITransformMatrix=function(t){return{a:t.a,b:t.b,c:t.c,d:t.d,e:t.e,f:t.f}},t.toSVGMatrix=function(t,e){return t.a=e.a,t.b=e.b,t.c=e.c,t.d=e.d,t.e=e.e,t.f=e.f,t},t}(),b=function(t){function e(e,i,o){var s=t.call(this,e,i,o)||this;return s.left=0,s.top=0,s.width=0,s.height=0,s.defaultSize={x:50,y:20},s.offsetX=0,s.offsetY=0,s.rotationAngle=0,s.CB_DISTANCE=10,s.container.transform.baseVal.appendItem(n.createTransform()),s.setupControlBox(),s}return i(e,t),Object.defineProperty(e.prototype,"centerX",{get:function(){return this.left+this.width/2},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"centerY",{get:function(){return this.top+this.height/2},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"visual",{get:function(){return this._visual},set:function(t){this._visual=t;var e=n.createTransform();this._visual.transform.baseVal.appendItem(e)},enumerable:!1,configurable:!0}),e.prototype.ownsTarget=function(e){return!!t.prototype.ownsTarget.call(this,e)||!(void 0===this.controlGrips.findGripByVisual(e)&&!this.rotatorGrip.ownsTarget(e))},e.prototype.pointerDown=function(e,i){t.prototype.pointerDown.call(this,e,i),"new"===this.state&&(this.left=e.x,this.top=e.y),this.manipulationStartLeft=this.left,this.manipulationStartTop=this.top,this.manipulationStartWidth=this.width,this.manipulationStartHeight=this.height;var o=this.unrotatePoint(e);if(this.manipulationStartX=o.x,this.manipulationStartY=o.y,this.offsetX=o.x-this.left,this.offsetY=o.y-this.top,"new"!==this.state)if(this.select(),this.activeGrip=this.controlGrips.findGripByVisual(i),void 0!==this.activeGrip)this._state="resize";else if(this.rotatorGrip.ownsTarget(i)){this.activeGrip=this.rotatorGrip;var s=this.rotatePoint({x:this.centerX,y:this.centerY});this.left=s.x-this.width/2,this.top=s.y-this.height/2,this.moveVisual({x:this.left,y:this.top});var r=this.container.transform.baseVal.getItem(0);r.setRotate(this.rotationAngle,this.centerX,this.centerY),this.container.transform.baseVal.replaceItem(r,0),this.adjustControlBox(),this._state="rotate"}else this._state="move"},e.prototype.pointerUp=function(e){var i=this.state;t.prototype.pointerUp.call(this,e),"creating"===this.state&&this.width<10&&this.height<10?(this.width=this.defaultSize.x,this.height=this.defaultSize.y):this.manipulate(e),this._state="select","creating"===i&&this.onMarkerCreated&&this.onMarkerCreated(this)},e.prototype.moveVisual=function(t){this.visual.style.transform="translate("+t.x+"px, "+t.y+"px)"},e.prototype.manipulate=function(t){var e=this.unrotatePoint(t);"creating"===this.state?this.resize(t):"move"===this.state?(this.left=this.manipulationStartLeft+(e.x-this.manipulationStartLeft)-this.offsetX,this.top=this.manipulationStartTop+(e.y-this.manipulationStartTop)-this.offsetY,this.moveVisual({x:this.left,y:this.top}),this.adjustControlBox()):"resize"===this.state?this.resize(e):"rotate"===this.state&&this.rotate(t)},e.prototype.resize=function(t){var e=this.manipulationStartLeft,i=this.manipulationStartWidth,o=this.manipulationStartTop,s=this.manipulationStartHeight;switch(this.activeGrip){case this.controlGrips.bottomLeft:case this.controlGrips.centerLeft:case this.controlGrips.topLeft:e=this.manipulationStartLeft+t.x-this.manipulationStartX,i=this.manipulationStartWidth+this.manipulationStartLeft-e;break;case this.controlGrips.bottomRight:case this.controlGrips.centerRight:case this.controlGrips.topRight:case void 0:i=this.manipulationStartWidth+t.x-this.manipulationStartX}switch(this.activeGrip){case this.controlGrips.topCenter:case this.controlGrips.topLeft:case this.controlGrips.topRight:o=this.manipulationStartTop+t.y-this.manipulationStartY,s=this.manipulationStartHeight+this.manipulationStartTop-o;break;case this.controlGrips.bottomCenter:case this.controlGrips.bottomLeft:case this.controlGrips.bottomRight:case void 0:s=this.manipulationStartHeight+t.y-this.manipulationStartY}i>=0?(this.left=e,this.width=i):(this.left=e+i,this.width=-i),s>=0?(this.top=o,this.height=s):(this.top=o+s,this.height=-s),this.setSize()},e.prototype.setSize=function(){this.moveVisual({x:this.left,y:this.top}),this.adjustControlBox()},e.prototype.rotate=function(t){if(Math.abs(t.x-this.centerX)>.1){var e=Math.sign(t.x-this.centerX);this.rotationAngle=180*Math.atan((t.y-this.centerY)/(t.x-this.centerX))/Math.PI+90*e,this.applyRotation()}},e.prototype.applyRotation=function(){var t=this.container.transform.baseVal.getItem(0);t.setRotate(this.rotationAngle,this.centerX,this.centerY),this.container.transform.baseVal.replaceItem(t,0)},e.prototype.rotatePoint=function(t){if(0===this.rotationAngle)return t;var e=this.container.getCTM(),i=n.createPoint(t.x,t.y);return{x:(i=i.matrixTransform(e)).x,y:i.y}},e.prototype.unrotatePoint=function(t){if(0===this.rotationAngle)return t;var e=this.container.getCTM();e=e.inverse();var i=n.createPoint(t.x,t.y);return{x:(i=i.matrixTransform(e)).x,y:i.y}},e.prototype.select=function(){t.prototype.select.call(this),this.adjustControlBox(),this.controlBox.style.display=""},e.prototype.deselect=function(){t.prototype.deselect.call(this),this.controlBox.style.display="none"},e.prototype.setupControlBox=function(){this.controlBox=n.createGroup();var t=n.createTransform();t.setTranslate(-this.CB_DISTANCE/2,-this.CB_DISTANCE/2),this.controlBox.transform.baseVal.appendItem(t),this.container.appendChild(this.controlBox),this.controlRect=n.createRect(this.width+this.CB_DISTANCE,this.height+this.CB_DISTANCE,[["stroke","black"],["stroke-width","1"],["stroke-opacity","0.5"],["stroke-dasharray","3, 2"],["fill","transparent"],["pointer-events","none"]]),this.controlBox.appendChild(this.controlRect),this.rotatorGripLine=n.createLine((this.width+2*this.CB_DISTANCE)/2,this.top-this.CB_DISTANCE,(this.width+2*this.CB_DISTANCE)/2,this.top-3*this.CB_DISTANCE,[["stroke","black"],["stroke-width","1"],["stroke-opacity","0.5"],["stroke-dasharray","3, 2"]]),this.controlBox.appendChild(this.rotatorGripLine),this.controlGrips=new v,this.addControlGrips(),this.controlBox.style.display="none"},e.prototype.adjustControlBox=function(){var t=this.controlBox.transform.baseVal.getItem(0);t.setTranslate(this.left-this.CB_DISTANCE/2,this.top-this.CB_DISTANCE/2),this.controlBox.transform.baseVal.replaceItem(t,0),this.controlRect.setAttribute("width",(this.width+this.CB_DISTANCE).toString()),this.controlRect.setAttribute("height",(this.height+this.CB_DISTANCE).toString()),this.rotatorGripLine.setAttribute("x1",((this.width+this.CB_DISTANCE)/2).toString()),this.rotatorGripLine.setAttribute("y1",(-this.CB_DISTANCE/2).toString()),this.rotatorGripLine.setAttribute("x2",((this.width+this.CB_DISTANCE)/2).toString()),this.rotatorGripLine.setAttribute("y2",(3*-this.CB_DISTANCE).toString()),this.positionGrips()},e.prototype.addControlGrips=function(){this.controlGrips.topLeft=this.createGrip(),this.controlGrips.topCenter=this.createGrip(),this.controlGrips.topRight=this.createGrip(),this.controlGrips.centerLeft=this.createGrip(),this.controlGrips.centerRight=this.createGrip(),this.controlGrips.bottomLeft=this.createGrip(),this.controlGrips.bottomCenter=this.createGrip(),this.controlGrips.bottomRight=this.createGrip(),this.rotatorGrip=this.createGrip(),this.positionGrips()},e.prototype.createGrip=function(){var t=new m;return t.visual.transform.baseVal.appendItem(n.createTransform()),this.controlBox.appendChild(t.visual),t},e.prototype.positionGrips=function(){var t=this.controlGrips.topLeft.GRIP_SIZE,e=-t/2,i=e,o=(this.width+this.CB_DISTANCE)/2-t/2,s=(this.height+this.CB_DISTANCE)/2-t/2,r=this.height+this.CB_DISTANCE-t/2,n=this.width+this.CB_DISTANCE-t/2;this.positionGrip(this.controlGrips.topLeft.visual,e,i),this.positionGrip(this.controlGrips.topCenter.visual,o,i),this.positionGrip(this.controlGrips.topRight.visual,n,i),this.positionGrip(this.controlGrips.centerLeft.visual,e,s),this.positionGrip(this.controlGrips.centerRight.visual,n,s),this.positionGrip(this.controlGrips.bottomLeft.visual,e,r),this.positionGrip(this.controlGrips.bottomCenter.visual,o,r),this.positionGrip(this.controlGrips.bottomRight.visual,n,r),this.positionGrip(this.rotatorGrip.visual,o,i-3*this.CB_DISTANCE)},e.prototype.positionGrip=function(t,e,i){var o=t.transform.baseVal.getItem(0);o.setTranslate(e,i),t.transform.baseVal.replaceItem(o,0)},e.prototype.hideControlBox=function(){this.controlBox.style.display="none"},e.prototype.showControlBox=function(){this.controlBox.style.display=""},e.prototype.getState=function(){return Object.assign({left:this.left,top:this.top,width:this.width,height:this.height,rotationAngle:this.rotationAngle,visualTransformMatrix:C.toITransformMatrix(this.visual.transform.baseVal.getItem(0).matrix),containerTransformMatrix:C.toITransformMatrix(this.container.transform.baseVal.getItem(0).matrix)},t.prototype.getState.call(this))},e.prototype.restoreState=function(e){t.prototype.restoreState.call(this,e);var i=e;this.left=i.left,this.top=i.top,this.width=i.width,this.height=i.height,this.rotationAngle=i.rotationAngle,this.visual.transform.baseVal.getItem(0).setMatrix(C.toSVGMatrix(this.visual.transform.baseVal.getItem(0).matrix,i.visualTransformMatrix)),this.container.transform.baseVal.getItem(0).setMatrix(C.toSVGMatrix(this.container.transform.baseVal.getItem(0).matrix,i.containerTransformMatrix))},e.prototype.scale=function(e,i){t.prototype.scale.call(this,e,i);var o=this.rotatePoint({x:this.left,y:this.top}),s=this.unrotatePoint({x:o.x*e,y:o.y*i});this.left=s.x,this.top=s.y,this.width=this.width*e,this.height=this.height*i,this.adjustControlBox()},e}(f),k=function(t){function e(e,i,o){var s=t.call(this,e,i,o)||this;return s.fillColor="transparent",s.strokeColor="transparent",s.strokeWidth=0,s.strokeDasharray="",s.opacity=1,s.setStrokeColor=s.setStrokeColor.bind(s),s.setFillColor=s.setFillColor.bind(s),s.setStrokeWidth=s.setStrokeWidth.bind(s),s.setStrokeDasharray=s.setStrokeDasharray.bind(s),s.createVisual=s.createVisual.bind(s),s}return i(e,t),e.prototype.ownsTarget=function(e){return!(!t.prototype.ownsTarget.call(this,e)&&e!==this.visual)},e.prototype.createVisual=function(){this.visual=n.createRect(1,1,[["fill",this.fillColor],["stroke",this.strokeColor],["stroke-width",this.strokeWidth.toString()],["stroke-dasharray",this.strokeDasharray],["opacity",this.opacity.toString()]]),this.addMarkerVisualToContainer(this.visual)},e.prototype.pointerDown=function(e,i){t.prototype.pointerDown.call(this,e,i),"new"===this.state&&(this.createVisual(),this.moveVisual(e),this._state="creating")},e.prototype.manipulate=function(e){t.prototype.manipulate.call(this,e)},e.prototype.resize=function(e){t.prototype.resize.call(this,e),this.setSize()},e.prototype.setSize=function(){t.prototype.setSize.call(this),n.setAttributes(this.visual,[["width",this.width.toString()],["height",this.height.toString()]])},e.prototype.pointerUp=function(e){t.prototype.pointerUp.call(this,e),this.setSize()},e.prototype.setStrokeColor=function(t){this.strokeColor=t,this.visual&&n.setAttributes(this.visual,[["stroke",this.strokeColor]]),this.colorChanged(t)},e.prototype.setFillColor=function(t){this.fillColor=t,this.visual&&n.setAttributes(this.visual,[["fill",this.fillColor]])},e.prototype.setStrokeWidth=function(t){this.strokeWidth=t,this.visual&&n.setAttributes(this.visual,[["stroke-width",this.strokeWidth.toString()]])},e.prototype.setStrokeDasharray=function(t){this.strokeDasharray=t,this.visual&&n.setAttributes(this.visual,[["stroke-dasharray",this.strokeDasharray]])},e.prototype.getState=function(){return Object.assign({fillColor:this.fillColor,strokeColor:this.strokeColor,strokeWidth:this.strokeWidth,strokeDasharray:this.strokeDasharray,opacity:this.opacity},t.prototype.getState.call(this))},e.prototype.restoreState=function(e){var i=e;this.fillColor=i.fillColor,this.strokeColor=i.strokeColor,this.strokeWidth=i.strokeWidth,this.strokeDasharray=i.strokeDasharray,this.opacity=i.opacity,this.createVisual(),t.prototype.restoreState.call(this,e),this.setSize()},e.prototype.scale=function(e,i){t.prototype.scale.call(this,e,i),this.setSize()},e.title="Rectangle marker",e}(b),S=function(t){function e(e,i,o,s){var r=t.call(this,e,s||'<svg viewBox="0 0 24 24"><path d="M3 17h18v-2H3v2m0 3h18v-1H3v1m0-7h18v-3H3v3m0-9v4h18V4H3z"/></svg>')||this;return r.widths=[],r.widthBoxes=[],r.widths=i,r.currentWidth=o,r.setCurrentWidth=r.setCurrentWidth.bind(r),r}return i(e,t),e.prototype.getUi=function(){var t=this,e=document.createElement("div");return e.style.display="flex",e.style.overflow="hidden",e.style.flexGrow="2",this.widths.forEach((function(i){var o=document.createElement("div");o.style.display="flex",o.style.flexGrow="2",o.style.alignItems="center",o.style.justifyContent="space-between",o.style.padding="5px",o.style.borderWidth="2px",o.style.borderStyle="solid",o.style.borderColor=i===t.currentWidth?l.settings.toolboxAccentColor:"transparent",o.addEventListener("click",(function(){t.setCurrentWidth(i,o)})),e.appendChild(o);var s=document.createElement("div");s.innerText=i.toString(),s.style.marginRight="5px",o.appendChild(s);var r=document.createElement("div");r.style.minHeight="20px",r.style.flexGrow="2",r.style.display="flex",r.style.alignItems="center";var n=document.createElement("hr");n.style.minWidth="20px",n.style.border="0px",n.style.borderTop=i+"px solid "+l.settings.toolboxColor,n.style.flexGrow="2",r.appendChild(n),o.appendChild(r),t.widthBoxes.push(o)})),e},e.prototype.setCurrentWidth=function(t,e){this.currentWidth=t,this.widthBoxes.forEach((function(t){t.style.borderColor=t===e?l.settings.toolboxAccentColor:"transparent"})),this.onWidthChanged&&this.onWidthChanged(this.currentWidth)},e}(y),w=function(t){function e(e,i,o,s){var r=t.call(this,e,s||'<svg viewBox="0 0 24 24"><path d="M3 16h5v-2H3v2m6.5 0h5v-2h-5v2m6.5 0h5v-2h-5v2M3 20h2v-2H3v2m4 0h2v-2H7v2m4 0h2v-2h-2v2m4 0h2v-2h-2v2m4 0h2v-2h-2v2M3 12h8v-2H3v2m10 0h8v-2h-8v2M3 4v4h18V4H3z"/></svg>')||this;return r.styles=[],r.styleBoxes=[],r.styles=i,r.currentStyle=o,r.setCurrentStyle=r.setCurrentStyle.bind(r),r}return i(e,t),e.prototype.getUi=function(){var t=this,e=document.createElement("div");return e.style.display="flex",e.style.overflow="hidden",e.style.flexGrow="2",this.styles.forEach((function(i){var o=document.createElement("div");o.style.display="flex",o.style.alignItems="center",o.style.justifyContent="space-between",o.style.padding="5px",o.style.borderWidth="2px",o.style.borderStyle="solid",o.style.overflow="hidden",o.style.maxWidth=100/t.styles.length-5+"%",o.style.borderColor=i===t.currentStyle?l.settings.toolboxAccentColor:"transparent",o.addEventListener("click",(function(){t.setCurrentStyle(i,o)})),e.appendChild(o);var s=document.createElement("div");s.style.minHeight="20px",s.style.flexGrow="2",s.style.overflow="hidden";var r='<svg width="100" height="20">\n      <line x1="0" y1="10" x2="100" y2="10" stroke="'+l.settings.toolboxColor+'" stroke-width="3" '+(""!==i?'stroke-dasharray="'+i+'"':"")+" />\n  </svg>";s.innerHTML=r,o.appendChild(s),t.styleBoxes.push(o)})),e},e.prototype.setCurrentStyle=function(t,e){this.currentStyle=t,this.styleBoxes.forEach((function(t){t.style.borderColor=t===e?l.settings.toolboxAccentColor:"transparent"})),this.onStyleChanged&&this.onStyleChanged(this.currentStyle)},e}(y),x=function(t){function e(e,i,o){var s=t.call(this,e,i,o)||this;return s.strokeColor=o.defaultColor,s.strokeWidth=o.defaultStrokeWidth,s.strokeDasharray=o.defaultStrokeDasharray,s.strokePanel=new g("Line color",o.defaultColorSet,o.defaultColor),s.strokePanel.onColorChanged=s.setStrokeColor,s.strokeWidthPanel=new S("Line width",o.defaultStrokeWidths,o.defaultStrokeWidth),s.strokeWidthPanel.onWidthChanged=s.setStrokeWidth,s.strokeStylePanel=new w("Line style",o.defaultStrokeDasharrays,o.defaultStrokeDasharray),s.strokeStylePanel.onStyleChanged=s.setStrokeDasharray,s}return i(e,t),Object.defineProperty(e.prototype,"toolboxPanels",{get:function(){return[this.strokePanel,this.strokeWidthPanel,this.strokeStylePanel]},enumerable:!1,configurable:!0}),e.prototype.getState=function(){var i=t.prototype.getState.call(this);return i.typeName=e.typeName,i},e.typeName="FrameMarker",e.title="Frame marker",e.icon='<svg viewBox="0 0 24 24"><path d="M4 6v13h16V6H4m14 11H6V8h12v9z"/></svg>',e}(k),B=function(){this.defaultColorSet=["#EF4444","#10B981","#2563EB","#FFFF00","#7C3AED","#F472B6","#000000","#FFFFFF"],this.defaultColor=this.defaultColorSet[0],this.defaultFillColor=this.defaultColorSet[0],this.defaultStrokeColor=this.defaultColorSet[7],this.defaultHighlightColor=this.defaultColorSet[3],this.defaultStrokeWidth=3,this.defaultStrokeDasharray="",this.defaultHighlightOpacity=.5,this.defaultFontFamily="Helvetica, Arial, sans-serif",this.defaultStrokeWidths=[1,2,3,5,10],this.defaultStrokeDasharrays=["","3","12 3","9 6 3 6"],this.defaultOpacitySteps=[.1,.25,.5,.75,1],this.displayMode="inline",this.defaultFontFamilies=['Times, "Times New Roman", serif',"Helvetica, Arial, sans-serif",'Courier, "Courier New", monospace',"cursive","fantasy"],this.popupMargin=30,this.newFreehandMarkerOnPointerUp=!1,this.defaultColorsFollowCurrentColors=!1,this.freehandPixelRatio=1},M=function(t){function e(e,i,o){var s=t.call(this,e,i,o)||this;return s.x1=0,s.y1=0,s.x2=0,s.y2=0,s.defaultLength=50,s.manipulationStartX=0,s.manipulationStartY=0,s.manipulationStartX1=0,s.manipulationStartY1=0,s.manipulationStartX2=0,s.manipulationStartY2=0,s.setupControlBox(),s}return i(e,t),e.prototype.ownsTarget=function(e){return!!t.prototype.ownsTarget.call(this,e)||!(!this.grip1.ownsTarget(e)&&!this.grip2.ownsTarget(e))},e.prototype.pointerDown=function(e,i){t.prototype.pointerDown.call(this,e,i),this.manipulationStartX=e.x,this.manipulationStartY=e.y,"new"===this.state&&(this.x1=e.x,this.y1=e.y,this.x2=e.x,this.y2=e.y),this.manipulationStartX1=this.x1,this.manipulationStartY1=this.y1,this.manipulationStartX2=this.x2,this.manipulationStartY2=this.y2,"new"!==this.state&&(this.select(),this.grip1.ownsTarget(i)?this.activeGrip=this.grip1:this.grip2.ownsTarget(i)?this.activeGrip=this.grip2:this.activeGrip=void 0,this.activeGrip?this._state="resize":this._state="move")},e.prototype.pointerUp=function(e){var i=this.state;t.prototype.pointerUp.call(this,e),"creating"===this.state&&Math.abs(this.x1-this.x2)<10&&Math.abs(this.y1-this.y2)<10?(this.x2=this.x1+this.defaultLength,this.adjustVisual(),this.adjustControlBox()):this.manipulate(e),this._state="select","creating"===i&&this.onMarkerCreated&&this.onMarkerCreated(this)},e.prototype.adjustVisual=function(){},e.prototype.manipulate=function(t){"creating"===this.state?this.resize(t):"move"===this.state?(this.x1=this.manipulationStartX1+t.x-this.manipulationStartX,this.y1=this.manipulationStartY1+t.y-this.manipulationStartY,this.x2=this.manipulationStartX2+t.x-this.manipulationStartX,this.y2=this.manipulationStartY2+t.y-this.manipulationStartY,this.adjustVisual(),this.adjustControlBox()):"resize"===this.state&&this.resize(t)},e.prototype.resize=function(t){switch(this.activeGrip){case this.grip1:this.x1=t.x,this.y1=t.y;break;case this.grip2:case void 0:this.x2=t.x,this.y2=t.y}this.adjustVisual(),this.adjustControlBox()},e.prototype.select=function(){t.prototype.select.call(this),this.adjustControlBox(),this.controlBox.style.display=""},e.prototype.deselect=function(){t.prototype.deselect.call(this),this.controlBox.style.display="none"},e.prototype.setupControlBox=function(){this.controlBox=n.createGroup(),this.container.appendChild(this.controlBox),this.addControlGrips(),this.controlBox.style.display="none"},e.prototype.adjustControlBox=function(){this.positionGrips()},e.prototype.addControlGrips=function(){this.grip1=this.createGrip(),this.grip2=this.createGrip(),this.positionGrips()},e.prototype.createGrip=function(){var t=new m;return t.visual.transform.baseVal.appendItem(n.createTransform()),this.controlBox.appendChild(t.visual),t},e.prototype.positionGrips=function(){var t=this.grip1.GRIP_SIZE;this.positionGrip(this.grip1.visual,this.x1-t/2,this.y1-t/2),this.positionGrip(this.grip2.visual,this.x2-t/2,this.y2-t/2)},e.prototype.positionGrip=function(t,e,i){var o=t.transform.baseVal.getItem(0);o.setTranslate(e,i),t.transform.baseVal.replaceItem(o,0)},e.prototype.getState=function(){return Object.assign({x1:this.x1,y1:this.y1,x2:this.x2,y2:this.y2},t.prototype.getState.call(this))},e.prototype.restoreState=function(e){t.prototype.restoreState.call(this,e);var i=e;this.x1=i.x1,this.y1=i.y1,this.x2=i.x2,this.y2=i.y2},e.prototype.scale=function(e,i){t.prototype.scale.call(this,e,i),this.x1=this.x1*e,this.y1=this.y1*i,this.x2=this.x2*e,this.y2=this.y2*i,this.adjustVisual(),this.adjustControlBox()},e}(f),E=function(t){function e(e,i,o){var s=t.call(this,e,i,o)||this;return s.strokeColor="transparent",s.strokeWidth=0,s.strokeDasharray="",s.setStrokeColor=s.setStrokeColor.bind(s),s.setStrokeWidth=s.setStrokeWidth.bind(s),s.setStrokeDasharray=s.setStrokeDasharray.bind(s),s.strokeColor=o.defaultColor,s.strokeWidth=o.defaultStrokeWidth,s.strokeDasharray=o.defaultStrokeDasharray,s.strokePanel=new g("Line color",o.defaultColorSet,o.defaultColor),s.strokePanel.onColorChanged=s.setStrokeColor,s.strokeWidthPanel=new S("Line width",o.defaultStrokeWidths,o.defaultStrokeWidth),s.strokeWidthPanel.onWidthChanged=s.setStrokeWidth,s.strokeStylePanel=new w("Line style",o.defaultStrokeDasharrays,o.defaultStrokeDasharray),s.strokeStylePanel.onStyleChanged=s.setStrokeDasharray,s}return i(e,t),e.prototype.ownsTarget=function(e){return!(!t.prototype.ownsTarget.call(this,e)&&e!==this.visual&&e!==this.selectorLine&&e!==this.visibleLine)},e.prototype.createVisual=function(){this.visual=n.createGroup(),this.selectorLine=n.createLine(this.x1,this.y1,this.x2,this.y2,[["stroke","transparent"],["stroke-width",(this.strokeWidth+10).toString()]]),this.visibleLine=n.createLine(this.x1,this.y1,this.x2,this.y2,[["stroke",this.strokeColor],["stroke-width",this.strokeWidth.toString()]]),this.visual.appendChild(this.selectorLine),this.visual.appendChild(this.visibleLine),this.addMarkerVisualToContainer(this.visual)},e.prototype.pointerDown=function(e,i){t.prototype.pointerDown.call(this,e,i),"new"===this.state&&(this.createVisual(),this.adjustVisual(),this._state="creating")},e.prototype.adjustVisual=function(){this.selectorLine&&this.visibleLine&&(this.selectorLine.setAttribute("x1",this.x1.toString()),this.selectorLine.setAttribute("y1",this.y1.toString()),this.selectorLine.setAttribute("x2",this.x2.toString()),this.selectorLine.setAttribute("y2",this.y2.toString()),this.visibleLine.setAttribute("x1",this.x1.toString()),this.visibleLine.setAttribute("y1",this.y1.toString()),this.visibleLine.setAttribute("x2",this.x2.toString()),this.visibleLine.setAttribute("y2",this.y2.toString()),n.setAttributes(this.visibleLine,[["stroke",this.strokeColor]]),n.setAttributes(this.visibleLine,[["stroke-width",this.strokeWidth.toString()]]),n.setAttributes(this.visibleLine,[["stroke-dasharray",this.strokeDasharray.toString()]]))},e.prototype.setStrokeColor=function(t){this.strokeColor=t,this.adjustVisual(),this.colorChanged(t)},e.prototype.setStrokeWidth=function(t){this.strokeWidth=t,this.adjustVisual()},e.prototype.setStrokeDasharray=function(t){this.strokeDasharray=t,this.adjustVisual()},Object.defineProperty(e.prototype,"toolboxPanels",{get:function(){return[this.strokePanel,this.strokeWidthPanel,this.strokeStylePanel]},enumerable:!1,configurable:!0}),e.prototype.getState=function(){var i=Object.assign({strokeColor:this.strokeColor,strokeWidth:this.strokeWidth,strokeDasharray:this.strokeDasharray},t.prototype.getState.call(this));return i.typeName=e.typeName,i},e.prototype.restoreState=function(e){t.prototype.restoreState.call(this,e);var i=e;this.strokeColor=i.strokeColor,this.strokeWidth=i.strokeWidth,this.strokeDasharray=i.strokeDasharray,this.createVisual(),this.adjustVisual()},e.typeName="LineMarker",e.title="Line marker",e.icon='<svg viewBox="0 0 24 24"><path d="M19 13H5v-2h14v2z"/></svg>',e}(M),P=function(t){function e(e,i,o,s){var r=t.call(this,e,s||'<svg viewBox="0 0 24 24"><path d="M17 8h3v12h1v1h-4v-1h1v-3h-4l-1.5 3H14v1h-4v-1h1l6-12m1 1l-3.5 7H18V9M5 3h5c1.11 0 2 .89 2 2v11H9v-5H6v5H3V5c0-1.11.89-2 2-2m1 2v4h3V5H6z"/></svg>')||this;return r.fonts=[],r.fontBoxes=[],r.fonts=i,r.currentFont=o,r.setCurrentFont=r.setCurrentFont.bind(r),r}return i(e,t),e.prototype.getUi=function(){var t=this,e=document.createElement("div");return e.style.overflow="hidden",e.style.flexGrow="2",this.fonts.forEach((function(i){var o=document.createElement("div");o.style.display="inline-block",o.style.alignItems="center",o.style.justifyContent="space-between",o.style.padding="5px",o.style.borderWidth="2px",o.style.borderStyle="solid",o.style.overflow="hidden",o.style.maxWidth=100/t.fonts.length-5+"%",o.style.borderColor=i===t.currentFont?l.settings.toolboxAccentColor:"transparent",o.addEventListener("click",(function(){t.setCurrentFont(i,o)})),e.appendChild(o);var s=document.createElement("div");s.style.display="flex",s.style.minHeight="20px",s.style.flexGrow="2",s.style.fontFamily=i,s.style.overflow="hidden";var r=document.createElement("div");r.style.whiteSpace="nowrap",r.style.overflow="hidden",r.style.textOverflow="ellipsis",r.innerHTML="The quick brown fox jumps over the lazy dog",s.appendChild(r),o.appendChild(s),t.fontBoxes.push(o)})),e},e.prototype.setCurrentFont=function(t,e){this.currentFont=t,this.fontBoxes.forEach((function(t){t.style.borderColor=t===e?l.settings.toolboxAccentColor:"transparent"})),this.onFontChanged&&this.onFontChanged(this.currentFont)},e}(y),T=function(t){function e(e,i,o){var s=t.call(this,e,i,o)||this;return s.color="transparent",s.padding=5,s.DEFAULT_TEXT="your text here",s.text=s.DEFAULT_TEXT,s.isMoved=!1,s.color=o.defaultColor,s.fontFamily=o.defaultFontFamily,s.defaultSize={x:100,y:30},s.setColor=s.setColor.bind(s),s.setFont=s.setFont.bind(s),s.renderText=s.renderText.bind(s),s.sizeText=s.sizeText.bind(s),s.textEditDivClicked=s.textEditDivClicked.bind(s),s.showTextEditor=s.showTextEditor.bind(s),s.setSize=s.setSize.bind(s),s.positionTextEditor=s.positionTextEditor.bind(s),s.colorPanel=new g("Color",o.defaultColorSet,o.defaultColor),s.colorPanel.onColorChanged=s.setColor,s.fontFamilyPanel=new P("Font",o.defaultFontFamilies,o.defaultFontFamily),s.fontFamilyPanel.onFontChanged=s.setFont,s}return i(e,t),e.prototype.ownsTarget=function(e){if(t.prototype.ownsTarget.call(this,e)||e===this.visual||e===this.textElement||e===this.bgRectangle)return!0;var i=!1;return this.textElement.childNodes.forEach((function(t){t===e&&(i=!0)})),i},e.prototype.createVisual=function(){this.visual=n.createGroup(),this.bgRectangle=n.createRect(1,1,[["fill","transparent"]]),this.visual.appendChild(this.bgRectangle),this.textElement=n.createText([["fill",this.color],["font-family",this.fontFamily],["font-size","16px"],["x","0"],["y","0"]]),this.textElement.transform.baseVal.appendItem(n.createTransform()),this.textElement.transform.baseVal.appendItem(n.createTransform()),this.visual.appendChild(this.textElement),this.addMarkerVisualToContainer(this.visual),this.renderText()},e.prototype.pointerDown=function(e,i){t.prototype.pointerDown.call(this,e,i),this.isMoved=!1,this.pointerDownPoint=e,this.pointerDownTimestamp=Date.now(),"new"===this.state&&(this.createVisual(),this.moveVisual(e),this._state="creating")},e.prototype.renderText=function(){var t=this;if(this.textElement){for(;this.textElement.lastChild;)this.textElement.removeChild(this.textElement.lastChild);this.text.split(/\r\n|[\n\v\f\r\x85\u2028\u2029]/).forEach((function(e){t.textElement.appendChild(n.createTSpan(""===e.trim()?" ":e.trim(),[["x","0"],["dy","1.2em"]]))})),setTimeout(this.sizeText,10)}},e.prototype.getTextScale=function(){var t=this.textElement.getBBox(),e=1;if(t.width>0&&t.height>0){var i=(1*this.width-this.width*this.padding*2/100)/t.width,o=(1*this.height-this.height*this.padding*2/100)/t.height;e=Math.min(i,o)}return e},e.prototype.getTextPosition=function(t){var e=this.textElement.getBBox(),i=0,o=0;return e.width>0&&e.height>0&&(i=(this.width-e.width*t)/2,o=this.height/2-e.height*t/2),{x:i,y:o}},e.prototype.sizeText=function(){var t=this.textElement.getBBox(),e=this.getTextScale(),i=this.getTextPosition(e);i.y-=t.y*e,navigator.userAgent.indexOf("Edge/")>-1?this.textElement.style.transform="translate("+i.x+"px, "+i.y+"px) scale("+e+", "+e+")":(this.textElement.transform.baseVal.getItem(0).setTranslate(i.x,i.y),this.textElement.transform.baseVal.getItem(1).setScale(e,e))},e.prototype.manipulate=function(e){t.prototype.manipulate.call(this,e),void 0!==this.pointerDownPoint&&(this.isMoved=Math.abs(e.x-this.pointerDownPoint.x)>5||Math.abs(e.y-this.pointerDownPoint.y)>5)},e.prototype.resize=function(e){t.prototype.resize.call(this,e),this.isMoved=!0,this.setSize(),this.sizeText()},e.prototype.setSize=function(){t.prototype.setSize.call(this),this.visual&&this.bgRectangle&&(n.setAttributes(this.visual,[["width",this.width.toString()],["height",this.height.toString()]]),n.setAttributes(this.bgRectangle,[["width",this.width.toString()],["height",this.height.toString()]]))},e.prototype.pointerUp=function(e){var i=this.state;t.prototype.pointerUp.call(this,e),this.setSize(),("creating"===i||!this.isMoved&&Date.now()-this.pointerDownTimestamp>500)&&this.showTextEditor(),this.pointerDownPoint=void 0},e.prototype.showTextEditor=function(){var t=this;this._state="edit",this.overlayContainer.innerHTML="",this.textEditDiv=document.createElement("div"),this.textEditDiv.style.flexGrow="2",this.textEditDiv.style.alignItems="center",this.textEditDiv.style.justifyContent="center",this.textEditDiv.style.pointerEvents="auto",this.textEditDiv.style.overflow="hidden",this.textEditor=document.createElement("div"),this.textEditor.style.position="absolute",this.textEditor.style.fontFamily=this.fontFamily,this.textEditor.style.lineHeight="1em",this.textEditor.innerText=this.text,this.textEditor.contentEditable="true",this.textEditor.style.color=this.color,this.textEditor.style.whiteSpace="pre",this.positionTextEditor(),this.textEditor.addEventListener("pointerup",(function(t){t.stopPropagation()})),this.textEditor.addEventListener("input",(function(){for(var e=Number.parseFloat(t.textEditor.style.fontSize);t.textEditor.clientWidth>=Number.parseInt(t.textEditor.style.maxWidth)&&e>.9;)e-=.1,t.textEditor.style.fontSize=Math.max(e,.9)+"em"})),this.textEditor.addEventListener("keyup",(function(t){t.cancelBubble=!0})),this.textEditor.addEventListener("paste",(function(t){if(t.clipboardData){var e=t.clipboardData.getData("text"),i=window.getSelection();if(!i.rangeCount)return!1;i.deleteFromDocument(),i.getRangeAt(0).insertNode(document.createTextNode(e)),t.preventDefault()}})),this.textEditDiv.addEventListener("pointerup",(function(){t.textEditDivClicked(t.textEditor.innerText)})),this.textEditDiv.appendChild(this.textEditor),this.overlayContainer.appendChild(this.textEditDiv),this.hideVisual(),this.textEditor.focus(),document.execCommand("selectAll")},e.prototype.positionTextEditor=function(){if("edit"===this.state)if(void 0===this.textEditor)this.showTextEditor();else{this.textElement.style.display="";var t=this.getTextScale(),e=this.rotatePoint({x:this.left+this.width/2,y:this.top+this.height/2}),i=this.textElement.getBBox(),o={x:i.width*t,y:i.height*t};e.x-=o.x/2,e.y-=o.y/2,this.textEditor.style.top=e.y+"px",this.textEditor.style.left=e.x+"px",this.textEditor.style.maxWidth=this.overlayContainer.offsetWidth-e.x+"px",this.textEditor.style.fontSize=Math.max(16*t,12)+"px",this.textElement.style.display="none"}},e.prototype.textEditDivClicked=function(t){this.text=t.trim(),this.overlayContainer.innerHTML="",this.renderText(),this.showVisual()},e.prototype.deselect=function(){"edit"===this.state&&this.textEditDivClicked(this.textEditor.innerText),t.prototype.deselect.call(this)},e.prototype.dblClick=function(e,i){t.prototype.dblClick.call(this,e,i),this.showTextEditor()},e.prototype.setColor=function(t){this.textElement&&n.setAttributes(this.textElement,[["fill",t]]),this.color=t,this.textEditor&&(this.textEditor.style.color=this.color),this.colorChanged(t)},e.prototype.setFont=function(t){this.textElement&&n.setAttributes(this.textElement,[["font-family",t]]),this.fontFamily=t,this.textEditor&&(this.textEditor.style.fontFamily=this.fontFamily),this.renderText()},e.prototype.hideVisual=function(){this.textElement.style.display="none",this.hideControlBox()},e.prototype.showVisual=function(){"edit"===this.state&&(this._state="select"),this.textElement.style.display="",this.showControlBox()},Object.defineProperty(e.prototype,"toolboxPanels",{get:function(){return[this.colorPanel,this.fontFamilyPanel]},enumerable:!1,configurable:!0}),e.prototype.getState=function(){var i=Object.assign({color:this.color,fontFamily:this.fontFamily,padding:this.padding,text:this.text},t.prototype.getState.call(this));return i.typeName=e.typeName,i},e.prototype.restoreState=function(e){var i=e;this.color=i.color,this.fontFamily=i.fontFamily,this.padding=i.padding,this.text=i.text,this.createVisual(),t.prototype.restoreState.call(this,e),this.setSize()},e.prototype.scale=function(e,i){t.prototype.scale.call(this,e,i),this.setSize(),this.sizeText(),this.positionTextEditor()},e.typeName="TextMarker",e.title="Text marker",e.icon='<svg viewBox="0 0 24 24"><path d="M9.6 14L12 7.7l2.4 6.3M11 5L5.5 19h2.2l1.1-3H15l1.1 3h2.2L13 5h-2z"/></svg>',e}(b),L=function(t){function e(e,i,o){var s=t.call(this,e,i,o)||this;return s.color="transparent",s.lineWidth=3,s.drawing=!1,s.pixelRatio=1,s.color=o.defaultColor,s.lineWidth=o.defaultStrokeWidth,s.pixelRatio=o.freehandPixelRatio,s.setColor=s.setColor.bind(s),s.addCanvas=s.addCanvas.bind(s),s.finishCreation=s.finishCreation.bind(s),s.setLineWidth=s.setLineWidth.bind(s),s.colorPanel=new g("Color",o.defaultColorSet,o.defaultColor),s.colorPanel.onColorChanged=s.setColor,s.lineWidthPanel=new S("Line width",o.defaultStrokeWidths,o.defaultStrokeWidth),s.lineWidthPanel.onWidthChanged=s.setLineWidth,s}return i(e,t),e.prototype.ownsTarget=function(e){return!(!t.prototype.ownsTarget.call(this,e)&&e!==this.visual&&e!==this.drawingImage)},e.prototype.createVisual=function(){this.visual=n.createGroup(),this.drawingImage=n.createImage(),this.visual.appendChild(this.drawingImage);var t=n.createTransform();this.visual.transform.baseVal.appendItem(t),this.addMarkerVisualToContainer(this.visual)},e.prototype.pointerDown=function(e,i){"new"===this.state&&(this.addCanvas(),this.createVisual(),this._state="creating"),"creating"===this.state?(this.canvasContext.strokeStyle=this.color,this.canvasContext.lineWidth=this.lineWidth,this.canvasContext.beginPath(),this.canvasContext.moveTo(e.x,e.y),this.drawing=!0):t.prototype.pointerDown.call(this,e,i)},e.prototype.manipulate=function(e){"creating"===this.state?this.drawing&&(this.canvasContext.lineTo(e.x,e.y),this.canvasContext.stroke()):t.prototype.manipulate.call(this,e)},e.prototype.resize=function(e){t.prototype.resize.call(this,e),n.setAttributes(this.visual,[["width",this.width.toString()],["height",this.height.toString()]]),n.setAttributes(this.drawingImage,[["width",this.width.toString()],["height",this.height.toString()]])},e.prototype.pointerUp=function(e){"creating"===this._state?this.drawing&&(this.canvasContext.closePath(),this.drawing=!1,this.globalSettings.newFreehandMarkerOnPointerUp&&this.finishCreation()):t.prototype.pointerUp.call(this,e)},e.prototype.addCanvas=function(){this.overlayContainer.innerHTML="",this.canvasElement=document.createElement("canvas"),this.canvasElement.width=this.overlayContainer.clientWidth*this.pixelRatio,this.canvasElement.height=this.overlayContainer.clientHeight*this.pixelRatio,this.canvasContext=this.canvasElement.getContext("2d"),this.canvasContext.scale(this.pixelRatio,this.pixelRatio),this.overlayContainer.appendChild(this.canvasElement)},e.prototype.select=function(){"creating"===this.state&&this.finishCreation(),t.prototype.select.call(this)},e.prototype.deselect=function(){"creating"===this.state&&this.finishCreation(),t.prototype.deselect.call(this)},e.prototype.finishCreation=function(){for(var t=this.canvasContext.getImageData(0,0,this.canvasElement.width,this.canvasElement.height),e=[this.canvasElement.width+1,this.canvasElement.height+1,-1,-1],i=e[0],o=e[1],s=e[2],r=e[3],n=!1,a=0;a<this.canvasElement.height;a++)for(var h=0;h<this.canvasElement.width;h++){t.data[a*this.canvasElement.width*4+4*h+3]>0&&(n=!0,a<o&&(o=a),h<i&&(i=h),a>r&&(r=a),h>s&&(s=h))}if(n){this.left=i/this.pixelRatio,this.top=o/this.pixelRatio,this.width=(s-i)/this.pixelRatio,this.height=(r-o)/this.pixelRatio;var l=document.createElement("canvas");l.width=s-i,l.height=r-o,l.getContext("2d").putImageData(this.canvasContext.getImageData(i,o,s-i,r-o),0,0),this.drawingImgUrl=l.toDataURL("image/png"),this.setDrawingImage(),this._state="select",this.onMarkerCreated&&this.onMarkerCreated(this)}this.overlayContainer.innerHTML=""},e.prototype.setDrawingImage=function(){n.setAttributes(this.drawingImage,[["width",this.width.toString()],["height",this.height.toString()]]),n.setAttributes(this.drawingImage,[["href",this.drawingImgUrl]]),this.moveVisual({x:this.left,y:this.top})},e.prototype.setColor=function(t){this.color=t,this.colorChanged(t)},e.prototype.setLineWidth=function(t){this.lineWidth=t},Object.defineProperty(e.prototype,"toolboxPanels",{get:function(){return"new"===this.state||"creating"===this.state?[this.colorPanel,this.lineWidthPanel]:[]},enumerable:!1,configurable:!0}),e.prototype.getState=function(){var i=Object.assign({drawingImgUrl:this.drawingImgUrl},t.prototype.getState.call(this));return i.typeName=e.typeName,i},e.prototype.restoreState=function(e){this.createVisual(),t.prototype.restoreState.call(this,e),this.drawingImgUrl=e.drawingImgUrl,this.setDrawingImage()},e.prototype.scale=function(e,i){t.prototype.scale.call(this,e,i),this.setDrawingImage()},e.typeName="FreehandMarker",e.title="Freehand marker",e.icon='<svg viewBox="0 0 24 24"><path d="M9.75 20.85c1.78-.7 1.39-2.63.49-3.85-.89-1.25-2.12-2.11-3.36-2.94A9.817 9.817 0 014.54 12c-.28-.33-.85-.94-.27-1.06.59-.12 1.61.46 2.13.68.91.38 1.81.82 2.65 1.34l1.01-1.7C8.5 10.23 6.5 9.32 4.64 9.05c-1.06-.16-2.18.06-2.54 1.21-.32.99.19 1.99.77 2.77 1.37 1.83 3.5 2.71 5.09 4.29.34.33.75.72.95 1.18.21.44.16.47-.31.47-1.24 0-2.79-.97-3.8-1.61l-1.01 1.7c1.53.94 4.09 2.41 5.96 1.79m11.09-15.6c.22-.22.22-.58 0-.79l-1.3-1.3a.562.562 0 00-.78 0l-1.02 1.02 2.08 2.08M11 10.92V13h2.08l6.15-6.15-2.08-2.08L11 10.92z"/></svg>',e}(b),A=function(t){function e(e,i,o){var s=t.call(this,e,o||'<svg viewBox="0 0 24 24"><path d="M8 14v4l-6-6 6-6v4h8V6l6 6-6 6v-4H8z"/></svg>')||this;return s.typeBoxes=[],s.currentType=i,s.setCurrentType=s.setCurrentType.bind(s),s}return i(e,t),e.prototype.getUi=function(){var t=this,e=document.createElement("div");e.style.display="flex",e.style.overflow="hidden",e.style.flexGrow="2";for(var i=function(i){var s="both";switch(i){case 0:s="both";break;case 1:s="start";break;case 2:s="end";break;case 3:s="none"}var r=document.createElement("div");if(r.style.display="flex",r.style.flexGrow="2",r.style.alignItems="center",r.style.justifyContent="space-between",r.style.padding="5px",r.style.borderWidth="2px",r.style.borderStyle="solid",r.style.borderColor=s===o.currentType?l.settings.toolboxAccentColor:"transparent",r.addEventListener("click",(function(){t.setCurrentType(s,r)})),e.appendChild(r),"both"===s||"start"===s){var n=document.createElement("div");n.style.display="flex",n.style.alignItems="center",n.style.minHeight="20px",n.innerHTML='<svg viewBox="0 0 10 10" width="10" height="10" xmlns="http://www.w3.org/2000/svg">\n          <polygon points="0,5 10,0 10,10" fill="'+l.settings.toolboxColor+'" />\n        </svg>',n.style.marginLeft="5px",r.appendChild(n)}var a=document.createElement("div");a.style.display="flex",a.style.alignItems="center",a.style.minHeight="20px",a.style.flexGrow="2";var h=document.createElement("hr");if(h.style.minWidth="20px",h.style.border="0px",h.style.borderTop="3px solid "+l.settings.toolboxColor,h.style.flexGrow="2",a.appendChild(h),r.appendChild(a),"both"===s||"end"===s){var p=document.createElement("div");p.style.display="flex",p.style.alignItems="center",p.style.minHeight="20px",p.innerHTML='<svg viewBox="0 0 10 10" width="10" height="10" xmlns="http://www.w3.org/2000/svg">\n          <polygon points="0,0 10,5 0,10" fill="'+l.settings.toolboxColor+'" />\n        </svg>',p.style.marginRight="5px",r.appendChild(p)}o.typeBoxes.push(r)},o=this,s=0;s<4;s++)i(s);return e},e.prototype.setCurrentType=function(t,e){this.currentType=t,this.typeBoxes.forEach((function(t){t.style.borderColor=t===e?l.settings.toolboxAccentColor:"transparent"})),this.onArrowTypeChanged&&this.onArrowTypeChanged(this.currentType)},e}(y),D=function(t){function e(e,i,o){var s=t.call(this,e,i,o)||this;return s.arrowType="end",s.arrowBaseHeight=10,s.arrowBaseWidth=10,s.getArrowPoints=s.getArrowPoints.bind(s),s.setArrowType=s.setArrowType.bind(s),s.arrowTypePanel=new A("Arrow type","end"),s.arrowTypePanel.onArrowTypeChanged=s.setArrowType,s}return i(e,t),e.prototype.ownsTarget=function(e){return!(!t.prototype.ownsTarget.call(this,e)&&e!==this.arrow1&&e!==this.arrow2)},e.prototype.getArrowPoints=function(t,e){var i=this.arrowBaseWidth+2*this.strokeWidth,o=this.arrowBaseHeight+2*this.strokeWidth;return t-i/2+","+(e+o/2)+" "+t+","+(e-o/2)+" "+(t+i/2)+","+(e+o/2)},e.prototype.createTips=function(){this.arrow1=n.createPolygon(this.getArrowPoints(this.x1,this.y1),[["fill",this.strokeColor]]),this.arrow1.transform.baseVal.appendItem(n.createTransform()),this.visual.appendChild(this.arrow1),this.arrow2=n.createPolygon(this.getArrowPoints(this.x2,this.y2),[["fill",this.strokeColor]]),this.arrow2.transform.baseVal.appendItem(n.createTransform()),this.visual.appendChild(this.arrow2)},e.prototype.pointerDown=function(e,i){t.prototype.pointerDown.call(this,e,i),"creating"===this.state&&this.createTips()},e.prototype.adjustVisual=function(){if(t.prototype.adjustVisual.call(this),this.arrow1&&this.arrow2&&(this.arrow1.style.display="both"===this.arrowType||"start"===this.arrowType?"":"none",this.arrow2.style.display="both"===this.arrowType||"end"===this.arrowType?"":"none",n.setAttributes(this.arrow1,[["points",this.getArrowPoints(this.x1,this.y1)],["fill",this.strokeColor]]),n.setAttributes(this.arrow2,[["points",this.getArrowPoints(this.x2,this.y2)],["fill",this.strokeColor]]),Math.abs(this.x1-this.x2)>.1)){var e=180*Math.atan((this.y2-this.y1)/(this.x2-this.x1))/Math.PI+90*Math.sign(this.x1-this.x2),i=this.arrow1.transform.baseVal.getItem(0);i.setRotate(e,this.x1,this.y1),this.arrow1.transform.baseVal.replaceItem(i,0);var o=this.arrow2.transform.baseVal.getItem(0);o.setRotate(e+180,this.x2,this.y2),this.arrow2.transform.baseVal.replaceItem(o,0)}},e.prototype.setArrowType=function(t){this.arrowType=t,this.adjustVisual()},Object.defineProperty(e.prototype,"toolboxPanels",{get:function(){return[this.strokePanel,this.strokeWidthPanel,this.strokeStylePanel,this.arrowTypePanel]},enumerable:!1,configurable:!0}),e.prototype.getState=function(){var i=Object.assign({arrowType:this.arrowType},t.prototype.getState.call(this));return i.typeName=e.typeName,i},e.prototype.restoreState=function(e){t.prototype.restoreState.call(this,e);var i=e;this.arrowType=i.arrowType,this.createTips(),this.adjustVisual()},e.typeName="ArrowMarker",e.title="Arrow marker",e.icon='<svg viewBox="0 0 24 24"><path d="M19 6.41L17.59 5 7 15.59V9H5v10h10v-2H8.41L19 6.41z"/></svg>',e}(E),I=function(t){function e(e,i,o){var s=t.call(this,e,i,o)||this;return s.fillColor=o.defaultFillColor,s.strokeWidth=0,s.fillPanel=new g("Color",o.defaultColorSet,o.defaultFillColor),s.fillPanel.onColorChanged=s.setFillColor,s}return i(e,t),Object.defineProperty(e.prototype,"toolboxPanels",{get:function(){return[this.fillPanel]},enumerable:!1,configurable:!0}),e.prototype.getState=function(){var i=t.prototype.getState.call(this);return i.typeName=e.typeName,i},e.typeName="CoverMarker",e.title="Cover marker",e.icon='<svg viewBox="0 0 24 24"><path d="M4 6v13h16V6H4z"/></svg>',e}(k),W=function(t){function e(e,i,o,s){var r=t.call(this,e,s||'<svg viewBox="0 0 24 24"><path d="M17.66 8L12 2.35 6.34 8A8.02 8.02 0 004 13.64c0 2 .78 4.11 2.34 5.67a7.99 7.99 0 0011.32 0c1.56-1.56 2.34-3.67 2.34-5.67S19.22 9.56 17.66 8M6 14c0-2 .62-3.27 1.76-4.4L12 5.27l4.24 4.38C17.38 10.77 18 12 18 14H6z"/></svg>')||this;return r.opacities=[],r.opacityBoxes=[],r.opacities=i,r.currentOpacity=o,r.setCurrentOpacity=r.setCurrentOpacity.bind(r),r}return i(e,t),e.prototype.getUi=function(){var t=this,e=document.createElement("div");return e.style.display="flex",e.style.overflow="hidden",e.style.flexGrow="2",e.style.justifyContent="space-between",this.opacities.forEach((function(i){var o=document.createElement("div");o.style.display="flex",o.style.alignItems="center",o.style.justifyContent="center",o.style.padding="5px",o.style.borderWidth="2px",o.style.borderStyle="solid",o.style.borderColor=i===t.currentOpacity?l.settings.toolboxAccentColor:"transparent",o.addEventListener("click",(function(){t.setCurrentOpacity(i,o)})),e.appendChild(o);var s=document.createElement("div");s.innerText=100*i+"%",o.appendChild(s),t.opacityBoxes.push(o)})),e},e.prototype.setCurrentOpacity=function(t,e){this.currentOpacity=t,this.opacityBoxes.forEach((function(t){t.style.borderColor=t===e?l.settings.toolboxAccentColor:"transparent"})),this.onOpacityChanged&&this.onOpacityChanged(this.currentOpacity)},e}(y),H=function(t){function e(e,i,o){var s=t.call(this,e,i,o)||this;return s.setOpacity=s.setOpacity.bind(s),s.fillColor=o.defaultHighlightColor,s.strokeWidth=0,s.opacity=o.defaultHighlightOpacity,s.fillPanel=new g("Color",o.defaultColorSet,s.fillColor),s.fillPanel.onColorChanged=s.setFillColor,s.opacityPanel=new W("Opacity",o.defaultOpacitySteps,s.opacity),s.opacityPanel.onOpacityChanged=s.setOpacity,s}return i(e,t),e.prototype.setOpacity=function(t){this.opacity=t,this.visual&&n.setAttributes(this.visual,[["opacity",this.opacity.toString()]])},Object.defineProperty(e.prototype,"toolboxPanels",{get:function(){return[this.fillPanel,this.opacityPanel]},enumerable:!1,configurable:!0}),e.prototype.getState=function(){var i=t.prototype.getState.call(this);return i.typeName=e.typeName,i},e.typeName="HighlightMarker",e.title="Highlight marker",e.icon='<svg viewBox="0 0 24 24"><path d="M18.5 1.15c-.53 0-1.04.19-1.43.58l-5.81 5.82 5.65 5.65 5.82-5.81c.77-.78.77-2.04 0-2.83l-2.84-2.83c-.39-.39-.89-.58-1.39-.58M10.3 8.5l-5.96 5.96c-.78.78-.78 2.04.02 2.85C3.14 18.54 1.9 19.77.67 21h5.66l.86-.86c.78.76 2.03.75 2.81-.02l5.95-5.96"/></svg>',e}(I),R='<svg viewBox="0 0 24 24"><path d="M19 11.5s-2 2.17-2 3.5a2 2 0 002 2 2 2 0 002-2c0-1.33-2-3.5-2-3.5M5.21 10L10 5.21 14.79 10m1.77-1.06L7.62 0 6.21 1.41l2.38 2.38-5.15 5.15c-.59.56-.59 1.53 0 2.12l5.5 5.5c.29.29.68.44 1.06.44s.77-.15 1.06-.44l5.5-5.5c.59-.59.59-1.56 0-2.12z"/></svg>',N=function(t){function e(e,i,o){var s=t.call(this,e,i,o)||this;return s.bgColor="transparent",s.tipPosition={x:0,y:0},s.tipBase1Position={x:0,y:0},s.tipBase2Position={x:0,y:0},s.tipMoving=!1,s.color=o.defaultStrokeColor,s.bgColor=o.defaultFillColor,s.fontFamily=o.defaultFontFamily,s.defaultSize={x:100,y:30},s.setBgColor=s.setBgColor.bind(s),s.getTipPoints=s.getTipPoints.bind(s),s.positionTip=s.positionTip.bind(s),s.setTipPoints=s.setTipPoints.bind(s),s.colorPanel=new g("Text color",o.defaultColorSet,s.color,'<svg viewBox="0 0 24 24"><path d="M9.62 12L12 5.67 14.37 12M11 3L5.5 17h2.25l1.12-3h6.25l1.13 3h2.25L13 3h-2z"/></svg>'),s.colorPanel.onColorChanged=s.setColor,s.bgColorPanel=new g("Fill color",o.defaultColorSet,s.bgColor,R),s.bgColorPanel.onColorChanged=s.setBgColor,s.fontFamilyPanel=new P("Font",o.defaultFontFamilies,o.defaultFontFamily),s.fontFamilyPanel.onFontChanged=s.setFont,s.tipGrip=new m,s.tipGrip.visual.transform.baseVal.appendItem(n.createTransform()),s.controlBox.appendChild(s.tipGrip.visual),s}return i(e,t),e.prototype.ownsTarget=function(e){return t.prototype.ownsTarget.call(this,e)||this.tipGrip.ownsTarget(e)||this.tip===e},e.prototype.createTip=function(){n.setAttributes(this.bgRectangle,[["fill",this.bgColor],["rx","10px"]]),this.tip=n.createPolygon(this.getTipPoints(),[["fill",this.bgColor]]),this.visual.appendChild(this.tip)},e.prototype.pointerDown=function(e,i){"new"===this.state&&t.prototype.pointerDown.call(this,e,i),"creating"===this.state?this.createTip():this.tipGrip.ownsTarget(i)?(this.manipulationStartLeft=this.left,this.manipulationStartTop=this.top,this.tipMoving=!0):t.prototype.pointerDown.call(this,e,i)},e.prototype.pointerUp=function(e){if(this.tipMoving)this.tipMoving=!1;else{var i="creating"===this.state;t.prototype.pointerUp.call(this,e),this.setTipPoints(i),this.positionTip()}},e.prototype.manipulate=function(e){if(this.tipMoving){var i=this.unrotatePoint(e);this.tipPosition={x:i.x-this.manipulationStartLeft,y:i.y-this.manipulationStartTop},this.positionTip()}else t.prototype.manipulate.call(this,e)},e.prototype.setBgColor=function(t){this.bgRectangle&&this.tip&&(n.setAttributes(this.bgRectangle,[["fill",t]]),n.setAttributes(this.tip,[["fill",t]])),this.bgColor=t,this.fillColorChanged(t)},e.prototype.getTipPoints=function(){return this.setTipPoints("creating"===this.state),this.tipBase1Position.x+","+this.tipBase1Position.y+" "+this.tipBase2Position.x+","+this.tipBase2Position.y+" "+this.tipPosition.x+","+this.tipPosition.y},e.prototype.setTipPoints=function(t){void 0===t&&(t=!1);var e=Math.min(this.height/2,15),i=this.height/5;t&&(this.tipPosition={x:e+i/2,y:this.height+20});var o=Math.atan(this.height/2/(this.width/2));if(this.tipPosition.x<this.width/2&&this.tipPosition.y<this.height/2)o<Math.atan((this.height/2-this.tipPosition.y)/(this.width/2-this.tipPosition.x))?(i=this.width/5,e=Math.min(this.width/2,15),this.tipBase1Position={x:e,y:0},this.tipBase2Position={x:e+i,y:0}):(this.tipBase1Position={x:0,y:e},this.tipBase2Position={x:0,y:e+i});else if(this.tipPosition.x>=this.width/2&&this.tipPosition.y<this.height/2){o<Math.atan((this.height/2-this.tipPosition.y)/(this.tipPosition.x-this.width/2))?(i=this.width/5,e=Math.min(this.width/2,15),this.tipBase1Position={x:this.width-e-i,y:0},this.tipBase2Position={x:this.width-e,y:0}):(this.tipBase1Position={x:this.width,y:e},this.tipBase2Position={x:this.width,y:e+i})}else if(this.tipPosition.x>=this.width/2&&this.tipPosition.y>=this.height/2){o<Math.atan((this.tipPosition.y-this.height/2)/(this.tipPosition.x-this.width/2))?(i=this.width/5,e=Math.min(this.width/2,15),this.tipBase1Position={x:this.width-e-i,y:this.height},this.tipBase2Position={x:this.width-e,y:this.height}):(this.tipBase1Position={x:this.width,y:this.height-e-i},this.tipBase2Position={x:this.width,y:this.height-e})}else{o<Math.atan((this.tipPosition.y-this.height/2)/(this.width/2-this.tipPosition.x))?(i=this.width/5,e=Math.min(this.width/2,15),this.tipBase1Position={x:e,y:this.height},this.tipBase2Position={x:e+i,y:this.height}):(this.tipBase1Position={x:0,y:this.height-e},this.tipBase2Position={x:0,y:this.height-e-i})}},e.prototype.resize=function(e){t.prototype.resize.call(this,e),this.positionTip()},e.prototype.positionTip=function(){n.setAttributes(this.tip,[["points",this.getTipPoints()]]);var t=this.tipGrip.visual.transform.baseVal.getItem(0);t.setTranslate(this.tipPosition.x,this.tipPosition.y),this.tipGrip.visual.transform.baseVal.replaceItem(t,0)},Object.defineProperty(e.prototype,"toolboxPanels",{get:function(){return[this.colorPanel,this.bgColorPanel,this.fontFamilyPanel]},enumerable:!1,configurable:!0}),e.prototype.select=function(){this.positionTip(),t.prototype.select.call(this)},e.prototype.getState=function(){var i=Object.assign({bgColor:this.bgColor,tipPosition:this.tipPosition},t.prototype.getState.call(this));return i.typeName=e.typeName,i},e.prototype.restoreState=function(e){var i=e;this.bgColor=i.bgColor,this.tipPosition=i.tipPosition,t.prototype.restoreState.call(this,e),this.createTip(),this.setTipPoints()},e.prototype.scale=function(e,i){t.prototype.scale.call(this,e,i),this.tipPosition={x:this.tipPosition.x*e,y:this.tipPosition.y*i},this.positionTip()},e.typeName="CalloutMarker",e.title="Callout marker",e.icon='<svg viewBox="0 0 24 24"><path d="M4 2h16a2 2 0 012 2v12a2 2 0 01-2 2h-4l-4 4-4-4H4a2 2 0 01-2-2V4a2 2 0 012-2m0 2v12h4.83L12 19.17 15.17 16H20V4H4m2 3h12v2H6V7m0 4h10v2H6v-2z"/></svg>',e}(T),O=function(t){function e(e,i,o){var s=t.call(this,e,i,o)||this;return s.fillColor="transparent",s.strokeColor="transparent",s.strokeWidth=0,s.strokeDasharray="",s.opacity=1,s.strokeColor=o.defaultColor,s.strokeWidth=o.defaultStrokeWidth,s.strokeDasharray=o.defaultStrokeDasharray,s.fillColor=o.defaultFillColor,s.setStrokeColor=s.setStrokeColor.bind(s),s.setFillColor=s.setFillColor.bind(s),s.setStrokeWidth=s.setStrokeWidth.bind(s),s.setStrokeDasharray=s.setStrokeDasharray.bind(s),s.setOpacity=s.setOpacity.bind(s),s.createVisual=s.createVisual.bind(s),s.strokePanel=new g("Line color",r(o.defaultColorSet,["transparent"]),o.defaultColor),s.strokePanel.onColorChanged=s.setStrokeColor,s.fillPanel=new g("Fill color",r(o.defaultColorSet,["transparent"]),s.fillColor,R),s.fillPanel.onColorChanged=s.setFillColor,s.strokeWidthPanel=new S("Line width",o.defaultStrokeWidths,o.defaultStrokeWidth),s.strokeWidthPanel.onWidthChanged=s.setStrokeWidth,s.strokeStylePanel=new w("Line style",o.defaultStrokeDasharrays,o.defaultStrokeDasharray),s.strokeStylePanel.onStyleChanged=s.setStrokeDasharray,s.opacityPanel=new W("Opacity",o.defaultOpacitySteps,s.opacity),s.opacityPanel.onOpacityChanged=s.setOpacity,s}return i(e,t),e.prototype.ownsTarget=function(e){return!(!t.prototype.ownsTarget.call(this,e)&&e!==this.visual)},e.prototype.createVisual=function(){this.visual=n.createEllipse(this.width/2,this.height/2,[["fill",this.fillColor],["stroke",this.strokeColor],["stroke-width",this.strokeWidth.toString()],["stroke-dasharray",this.strokeDasharray],["opacity",this.opacity.toString()]]),this.addMarkerVisualToContainer(this.visual)},e.prototype.pointerDown=function(e,i){t.prototype.pointerDown.call(this,e,i),"new"===this.state&&(this.createVisual(),this.moveVisual(e),this._state="creating")},e.prototype.manipulate=function(e){t.prototype.manipulate.call(this,e)},e.prototype.resize=function(e){t.prototype.resize.call(this,e),this.setSize()},e.prototype.setSize=function(){t.prototype.setSize.call(this),n.setAttributes(this.visual,[["cx",(this.width/2).toString()],["cy",(this.height/2).toString()],["rx",(this.width/2).toString()],["ry",(this.height/2).toString()]])},e.prototype.pointerUp=function(e){t.prototype.pointerUp.call(this,e),this.setSize()},e.prototype.setStrokeColor=function(t){this.strokeColor=t,this.visual&&n.setAttributes(this.visual,[["stroke",this.strokeColor]]),this.colorChanged(t)},e.prototype.setFillColor=function(t){this.fillColor=t,this.visual&&n.setAttributes(this.visual,[["fill",this.fillColor]]),this.fillColorChanged(t)},e.prototype.setStrokeWidth=function(t){this.strokeWidth=t,this.visual&&n.setAttributes(this.visual,[["stroke-width",this.strokeWidth.toString()]])},e.prototype.setStrokeDasharray=function(t){this.strokeDasharray=t,this.visual&&n.setAttributes(this.visual,[["stroke-dasharray",this.strokeDasharray]])},e.prototype.setOpacity=function(t){this.opacity=t,this.visual&&n.setAttributes(this.visual,[["opacity",this.opacity.toString()]])},Object.defineProperty(e.prototype,"toolboxPanels",{get:function(){return[this.strokePanel,this.fillPanel,this.strokeWidthPanel,this.strokeStylePanel,this.opacityPanel]},enumerable:!1,configurable:!0}),e.prototype.getState=function(){var i=Object.assign({fillColor:this.fillColor,strokeColor:this.strokeColor,strokeWidth:this.strokeWidth,strokeDasharray:this.strokeDasharray,opacity:this.opacity},t.prototype.getState.call(this));return i.typeName=e.typeName,i},e.prototype.restoreState=function(e){var i=e;this.fillColor=i.fillColor,this.strokeColor=i.strokeColor,this.strokeWidth=i.strokeWidth,this.strokeDasharray=i.strokeDasharray,this.opacity=i.opacity,this.createVisual(),t.prototype.restoreState.call(this,e),this.setSize()},e.prototype.scale=function(e,i){t.prototype.scale.call(this,e,i),this.setSize()},e.typeName="EllipseMarker",e.title="Ellipse marker",e.icon='<svg viewBox="0 0 24 24"><path d="M12 4C6.5 4 2 7.58 2 12s4.5 8 10 8 10-3.58 10-8-4.5-8-10-8z"/></svg>',e}(b),z=function(t){function e(e,i,o){return t.call(this,e,i,o)||this}return i(e,t),Object.defineProperty(e.prototype,"tipLength",{get:function(){return 10+3*this.strokeWidth},enumerable:!1,configurable:!0}),e.prototype.ownsTarget=function(e){return!(!t.prototype.ownsTarget.call(this,e)&&e!==this.tip1&&e!==this.tip2)},e.prototype.createTips=function(){this.tip1=n.createLine(this.x1-this.tipLength/2,this.y1,this.x1+this.tipLength/2,this.y1,[["stroke",this.strokeColor],["stroke-width",this.strokeWidth.toString()]]),this.tip1.transform.baseVal.appendItem(n.createTransform()),this.visual.appendChild(this.tip1),this.tip2=n.createLine(this.x2-this.tipLength/2,this.y2,this.x2+this.tipLength/2,this.y2,[["stroke",this.strokeColor],["stroke-width",this.strokeWidth.toString()]]),this.tip2.transform.baseVal.appendItem(n.createTransform()),this.visual.appendChild(this.tip2)},e.prototype.pointerDown=function(e,i){t.prototype.pointerDown.call(this,e,i),"creating"===this.state&&this.createTips()},e.prototype.adjustVisual=function(){if(t.prototype.adjustVisual.call(this),this.tip1&&this.tip2&&(n.setAttributes(this.tip1,[["x1",(this.x1-this.tipLength/2).toString()],["y1",this.y1.toString()],["x2",(this.x1+this.tipLength/2).toString()],["y2",this.y1.toString()],["stroke",this.strokeColor],["stroke-width",this.strokeWidth.toString()]]),n.setAttributes(this.tip2,[["x1",(this.x2-this.tipLength/2).toString()],["y1",this.y2.toString()],["x2",(this.x2+this.tipLength/2).toString()],["y2",this.y2.toString()],["stroke",this.strokeColor],["stroke-width",this.strokeWidth.toString()]]),Math.abs(this.x1-this.x2)>.1)){var e=180*Math.atan((this.y2-this.y1)/(this.x2-this.x1))/Math.PI+90*Math.sign(this.x1-this.x2),i=this.tip1.transform.baseVal.getItem(0);i.setRotate(e,this.x1,this.y1),this.tip1.transform.baseVal.replaceItem(i,0);var o=this.tip2.transform.baseVal.getItem(0);o.setRotate(e+180,this.x2,this.y2),this.tip2.transform.baseVal.replaceItem(o,0)}},Object.defineProperty(e.prototype,"toolboxPanels",{get:function(){return[this.strokePanel,this.strokeWidthPanel,this.strokeStylePanel]},enumerable:!1,configurable:!0}),e.prototype.getState=function(){var i=t.prototype.getState.call(this);return i.typeName=e.typeName,i},e.prototype.restoreState=function(e){t.prototype.restoreState.call(this,e),this.createTips(),this.adjustVisual()},e.typeName="MeasurementMarker",e.title="Measurement marker",e.icon='<svg viewBox="0 0 24 24"><path d="M1.39 18.36l1.77-1.76L4.58 18l1.06-1.05-1.42-1.41 1.42-1.42 2.47 2.48 1.06-1.06-2.47-2.48 1.41-1.41 1.42 1.41L10.59 12l-1.42-1.41 1.42-1.42 2.47 2.48 1.06-1.06-2.47-2.48 1.41-1.41 1.41 1.41 1.07-1.06-1.42-1.41 1.42-1.42L18 6.7l1.07-1.06-2.47-2.48 1.76-1.77 4.25 4.25L5.64 22.61l-4.25-4.25z"/></svg>',e}(E),V=function(t){function e(e,i,o){var s=t.call(this,e,i,o)||this;return s.strokePanel.colors=o.defaultColorSet,s.fillColor="transparent",s}return i(e,t),Object.defineProperty(e.prototype,"toolboxPanels",{get:function(){return[this.strokePanel,this.strokeWidthPanel,this.strokeStylePanel]},enumerable:!1,configurable:!0}),e.prototype.getState=function(){var i=t.prototype.getState.call(this);return i.typeName=e.typeName,i},e.typeName="EllipseFrameMarker",e.title="Ellipse frame marker",e.icon='<svg viewBox="0 0 24 24"><path d="M12 6c4.41 0 8 2.69 8 6s-3.59 6-8 6-8-2.69-8-6 3.59-6 8-6m0-2C6.5 4 2 7.58 2 12s4.5 8 10 8 10-3.58 10-8-4.5-8-10-8z"/></svg>',e}(O),_=function(){function t(){this.undoStack=[],this.redoStack=[]}return Object.defineProperty(t.prototype,"isUndoPossible",{get:function(){return this.undoStack.length>0},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"isRedoPossible",{get:function(){return this.redoStack.length>0},enumerable:!1,configurable:!0}),t.prototype.addUndoStep=function(t){0!==this.undoStack.length&&JSON.stringify(this.undoStack[this.undoStack.length-1])===JSON.stringify(t)||(this.undoStack.push(t),JSON.stringify(this.lastRedoStep)!==JSON.stringify(t)&&this.redoStack.splice(0,this.redoStack.length))},t.prototype.undo=function(){if(this.undoStack.length>1){var t=this.undoStack.pop();return void 0!==t&&this.redoStack.push(t),this.undoStack.length>0?this.undoStack[this.undoStack.length-1]:void 0}},t.prototype.redo=function(){return this.lastRedoStep=this.redoStack.pop(),this.lastRedoStep},t}(),G=function(t){function e(e,i,o){var s=t.call(this,e,i,o)||this;return s.strokeColor="transparent",s.strokeWidth=0,s.strokeDasharray="",s.curveX=0,s.curveY=0,s.manipulationStartCurveX=0,s.manipulationStartCurveY=0,s.setStrokeColor=s.setStrokeColor.bind(s),s.setStrokeWidth=s.setStrokeWidth.bind(s),s.setStrokeDasharray=s.setStrokeDasharray.bind(s),s.positionGrips=s.positionGrips.bind(s),s.addControlGrips=s.addControlGrips.bind(s),s.adjustVisual=s.adjustVisual.bind(s),s.setupControlBox=s.setupControlBox.bind(s),s.resize=s.resize.bind(s),s.strokeColor=o.defaultColor,s.strokeWidth=o.defaultStrokeWidth,s.strokeDasharray=o.defaultStrokeDasharray,s.strokePanel=new g("Line color",o.defaultColorSet,o.defaultColor),s.strokePanel.onColorChanged=s.setStrokeColor,s.strokeWidthPanel=new S("Line width",o.defaultStrokeWidths,o.defaultStrokeWidth),s.strokeWidthPanel.onWidthChanged=s.setStrokeWidth,s.strokeStylePanel=new w("Line style",o.defaultStrokeDasharrays,o.defaultStrokeDasharray),s.strokeStylePanel.onStyleChanged=s.setStrokeDasharray,s}return i(e,t),e.prototype.ownsTarget=function(e){return!(!t.prototype.ownsTarget.call(this,e)&&e!==this.visual&&e!==this.selectorCurve&&e!==this.visibleCurve&&!this.curveGrip.ownsTarget(e))},e.prototype.getPathD=function(){return"M "+this.x1+" "+this.y1+" Q "+this.curveX+" "+this.curveY+", "+this.x2+" "+this.y2},e.prototype.createVisual=function(){this.visual=n.createGroup(),this.selectorCurve=n.createPath(this.getPathD(),[["stroke","transparent"],["stroke-width",(this.strokeWidth+10).toString()],["fill","transparent"]]),this.visibleCurve=n.createPath(this.getPathD(),[["stroke",this.strokeColor],["stroke-width",this.strokeWidth.toString()],["fill","transparent"]]),this.visual.appendChild(this.selectorCurve),this.visual.appendChild(this.visibleCurve),this.addMarkerVisualToContainer(this.visual)},e.prototype.pointerDown=function(e,i){t.prototype.pointerDown.call(this,e,i),this.manipulationStartCurveX=this.curveX,this.manipulationStartCurveY=this.curveY,"new"===this.state&&(this.curveX=e.x,this.curveY=e.y),"new"===this.state?(this.createVisual(),this.adjustVisual(),this._state="creating"):this.curveGrip.ownsTarget(i)&&(this.activeGrip=this.curveGrip,this._state="resize")},e.prototype.adjustVisual=function(){this.selectorCurve&&this.visibleCurve&&(this.selectorCurve.setAttribute("d",this.getPathD()),this.visibleCurve.setAttribute("d",this.getPathD()),n.setAttributes(this.visibleCurve,[["stroke",this.strokeColor]]),n.setAttributes(this.visibleCurve,[["stroke-width",this.strokeWidth.toString()]]),n.setAttributes(this.visibleCurve,[["stroke-dasharray",this.strokeDasharray.toString()]]))},e.prototype.setupControlBox=function(){t.prototype.setupControlBox.call(this),this.curveControlLine1=n.createLine(this.x1,this.y1,this.curveX,this.curveY,[["stroke","black"],["stroke-width","1"],["stroke-opacity","0.5"],["stroke-dasharray","3, 2"]]),this.curveControlLine2=n.createLine(this.x2,this.y2,this.curveX,this.curveY,[["stroke","black"],["stroke-width","1"],["stroke-opacity","0.5"],["stroke-dasharray","3, 2"]]),this.controlBox.insertBefore(this.curveControlLine1,this.controlBox.firstChild),this.controlBox.insertBefore(this.curveControlLine2,this.controlBox.firstChild)},e.prototype.addControlGrips=function(){this.curveGrip=this.createGrip(),this.curveX=0,this.curveY=0,t.prototype.addControlGrips.call(this)},e.prototype.positionGrips=function(){t.prototype.positionGrips.call(this);var e=this.curveGrip.GRIP_SIZE;this.positionGrip(this.curveGrip.visual,this.curveX-e/2,this.curveY-e/2),this.curveControlLine1&&this.curveControlLine2&&(this.curveControlLine1.setAttribute("x1",this.x1.toString()),this.curveControlLine1.setAttribute("y1",this.y1.toString()),this.curveControlLine1.setAttribute("x2",this.curveX.toString()),this.curveControlLine1.setAttribute("y2",this.curveY.toString()),this.curveControlLine2.setAttribute("x1",this.x2.toString()),this.curveControlLine2.setAttribute("y1",this.y2.toString()),this.curveControlLine2.setAttribute("x2",this.curveX.toString()),this.curveControlLine2.setAttribute("y2",this.curveY.toString()))},e.prototype.manipulate=function(e){"move"===this.state&&(this.curveX=this.manipulationStartCurveX+e.x-this.manipulationStartX,this.curveY=this.manipulationStartCurveY+e.y-this.manipulationStartY),t.prototype.manipulate.call(this,e)},e.prototype.resize=function(e){this.activeGrip===this.curveGrip&&(this.curveX=e.x,this.curveY=e.y),t.prototype.resize.call(this,e),"creating"===this.state&&(this.curveX=this.x1+(this.x2-this.x1)/2,this.curveY=this.y1+(this.y2-this.y1)/2)},e.prototype.setStrokeColor=function(t){this.strokeColor=t,this.adjustVisual(),this.colorChanged(t)},e.prototype.setStrokeWidth=function(t){this.strokeWidth=t,this.adjustVisual()},e.prototype.setStrokeDasharray=function(t){this.strokeDasharray=t,this.adjustVisual()},e.prototype.scale=function(e,i){this.curveX=this.curveX*e,this.curveY=this.curveY*i,t.prototype.scale.call(this,e,i)},Object.defineProperty(e.prototype,"toolboxPanels",{get:function(){return[this.strokePanel,this.strokeWidthPanel,this.strokeStylePanel]},enumerable:!1,configurable:!0}),e.prototype.getState=function(){var i=Object.assign({strokeColor:this.strokeColor,strokeWidth:this.strokeWidth,strokeDasharray:this.strokeDasharray,curveX:this.curveX,curveY:this.curveY},t.prototype.getState.call(this));return i.typeName=e.typeName,i},e.prototype.restoreState=function(e){t.prototype.restoreState.call(this,e);var i=e;this.strokeColor=i.strokeColor,this.strokeWidth=i.strokeWidth,this.strokeDasharray=i.strokeDasharray,this.curveX=i.curveX,this.curveY=i.curveY,this.createVisual(),this.adjustVisual()},e.typeName="CurveMarker",e.title="Curve marker",e.icon='<svg viewBox="0 0 24 24"><path d="M18.5 2A1.5 1.5 0 0120 3.5 1.5 1.5 0 0118.5 5c-.23 0-.45-.05-.65-.15l-3.69 3.7.34.45c2.19-1.26 4.76-2 7.5-2l1 .03v2.01L22 9c-2.58 0-5 .75-7 2.04A3.96 3.96 0 0111.04 15C9.75 17 9 19.42 9 22l.04 1H7.03L7 22c0-2.74.74-5.31 2-7.5l-.45-.34-3.7 3.69c.1.2.15.42.15.65A1.5 1.5 0 013.5 20 1.5 1.5 0 012 18.5 1.5 1.5 0 013.5 17c.23 0 .45.05.65.15l3.69-3.7C7.31 12.78 7 11.92 7 11a4 4 0 014-4c.92 0 1.78.31 2.45.84l3.7-3.69c-.1-.2-.15-.42-.15-.65A1.5 1.5 0 0118.5 2M11 9a2 2 0 00-2 2 2 2 0 002 2 2 2 0 002-2 2 2 0 00-2-2z"/></svg>',e}(M),F=function(){function t(t,e){void 0===e&&(e=!1),this.cancelable=!1,this._defaultPrevented=!1,this.markerArea=t,this.cancelable=e}return Object.defineProperty(t.prototype,"defaultPrevented",{get:function(){return this._defaultPrevented},enumerable:!1,configurable:!0}),t.prototype.preventDefault=function(){this._defaultPrevented=!0},t}(),j=function(t){function e(e,i,o){var s=t.call(this,e,!1)||this;return s.dataUrl=i,s.state=o,s}return i(e,t),e}(F),U=function(t){function e(e,i,o){void 0===o&&(o=!1);var s=t.call(this,e,o)||this;return s.marker=i,s}return i(e,t),e}(F),X=function(){function t(){this.render=[],this.beforeclose=[],this.close=[],this.show=[],this.restorestate=[],this.markerselect=[],this.markerdeselect=[],this.markercreating=[],this.markercreate=[],this.markerbeforedelete=[],this.markerdelete=[],this.focus=[],this.blur=[]}return t.prototype.addEventListener=function(t,e){this[t].push(e)},t.prototype.removeEventListener=function(t,e){var i=this[t].indexOf(e);i>-1&&this[t].splice(i,1)},t}(),Y=function(){function t(t){this.touchPoints=0,this._availableMarkerTypes=this.DEFAULT_MARKER_TYPES,this.mode="select",this.markers=[],this.isDragging=!1,this.renderEventListeners=[],this.closeEventListeners=[],this.settings=new B,this._isOpen=!1,this.undoRedoManager=new _,this.renderAtNaturalSize=!1,this.renderImageType="image/png",this.renderMarkersOnly=!1,this.zoomSteps=[1,1.5,2,4],this._zoomLevel=1,this.prevPanPoint={x:0,y:0},this.eventListeners=new X,this._silentRenderMode=!1,this._isFocused=!1,l.settings=l.defaultSettings,this.uiStyleSettings=l.settings,this.target=t,this.targetRoot=document.body,this.width=t.clientWidth,this.height=t.clientHeight,l.removeStyleSheet(),this.open=this.open.bind(this),this.setTopLeft=this.setTopLeft.bind(this),this.toolbarButtonClicked=this.toolbarButtonClicked.bind(this),this.createNewMarker=this.createNewMarker.bind(this),this.addNewMarker=this.addNewMarker.bind(this),this.markerCreated=this.markerCreated.bind(this),this.setCurrentMarker=this.setCurrentMarker.bind(this),this.onPointerDown=this.onPointerDown.bind(this),this.onDblClick=this.onDblClick.bind(this),this.onPointerMove=this.onPointerMove.bind(this),this.onPointerUp=this.onPointerUp.bind(this),this.onPointerOut=this.onPointerOut.bind(this),this.onKeyUp=this.onKeyUp.bind(this),this.overrideOverflow=this.overrideOverflow.bind(this),this.restoreOverflow=this.restoreOverflow.bind(this),this.close=this.close.bind(this),this.closeUI=this.closeUI.bind(this),this.addCloseEventListener=this.addCloseEventListener.bind(this),this.removeCloseEventListener=this.removeCloseEventListener.bind(this),this.addRenderEventListener=this.addRenderEventListener.bind(this),this.removeRenderEventListener=this.removeRenderEventListener.bind(this),this.clientToLocalCoordinates=this.clientToLocalCoordinates.bind(this),this.onWindowResize=this.onWindowResize.bind(this),this.deleteSelectedMarker=this.deleteSelectedMarker.bind(this),this.setWindowHeight=this.setWindowHeight.bind(this),this.removeMarker=this.removeMarker.bind(this),this.colorChanged=this.colorChanged.bind(this),this.fillColorChanged=this.fillColorChanged.bind(this),this.onPopupTargetResize=this.onPopupTargetResize.bind(this),this.showNotesEditor=this.showNotesEditor.bind(this),this.hideNotesEditor=this.hideNotesEditor.bind(this),this.stepZoom=this.stepZoom.bind(this),this.focus=this.focus.bind(this),this.blur=this.blur.bind(this)}return Object.defineProperty(t.prototype,"ALL_MARKER_TYPES",{get:function(){return[x,L,D,T,V,O,H,N,z,I,E,G]},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"DEFAULT_MARKER_TYPES",{get:function(){return[x,L,D,T,O,H,N]},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"BASIC_MARKER_TYPES",{get:function(){return[x,L,D,T,H]},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"availableMarkerTypes",{get:function(){return this._availableMarkerTypes},set:function(t){var e=this;this._availableMarkerTypes.splice(0),t.forEach((function(t){if("string"==typeof t){var i=e.ALL_MARKER_TYPES.find((function(e){return e.typeName===t}));void 0!==i&&e._availableMarkerTypes.push(i)}else e._availableMarkerTypes.push(t)}))},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"isOpen",{get:function(){return this._isOpen},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"zoomLevel",{get:function(){return this._zoomLevel},set:function(t){this._zoomLevel=t,this.editorCanvas&&this.contentDiv&&(this.editorCanvas.style.transform="scale("+this._zoomLevel+")",this.contentDiv.scrollTo({left:(this.editorCanvas.clientWidth*this._zoomLevel-this.contentDiv.clientWidth)/2,top:(this.editorCanvas.clientHeight*this._zoomLevel-this.contentDiv.clientHeight)/2}))},enumerable:!1,configurable:!0}),t.prototype.open=function(){this.setupResizeObserver(),this.setEditingTarget(),this.setTopLeft(),this.initMarkerCanvas(),this.initOverlay(),this.attachEvents(),"popup"===this.settings.displayMode&&this.onPopupTargetResize(),a.isLicensed||this.addLogo(),this._isOpen=!0,this._isFocused=!0},t.prototype.show=function(){var t=this;this.setWindowHeight(),this.showUI(),this.open(),this.eventListeners.show.forEach((function(e){return e(new F(t))}))},t.prototype.render=function(){return o(this,void 0,void 0,(function(){var t;return s(this,(function(e){switch(e.label){case 0:return this.setCurrentMarker(),(t=new h).naturalSize=this.renderAtNaturalSize,t.imageType=this.renderImageType,t.imageQuality=this.renderImageQuality,t.markersOnly=this.renderMarkersOnly,t.width=this.renderWidth,t.height=this.renderHeight,[4,t.rasterize(this.target instanceof HTMLImageElement?this.target:null,this.markerImage,this.renderTarget)];case 1:return e.sent(),[4,t.rasterize(this.target instanceof HTMLImageElement?this.target:null,this.markerImage,this.renderTarget)];case 2:return[2,e.sent()]}}))}))},t.prototype.close=function(t){var e=this;if(void 0===t&&(t=!1),this.isOpen){var i=!1;t||this.eventListeners.beforeclose.forEach((function(t){var o=new F(e,!0);t(o),o.defaultPrevented&&(i=!0)})),i||(this.coverDiv&&this.closeUI(),this.targetObserver&&this.targetObserver.unobserve(this.target),"popup"===this.settings.displayMode&&window.removeEventListener("resize",this.setWindowHeight),this.eventListeners.close.forEach((function(t){return t(new F(e))})),this.detachEvents(),this._isOpen=!1)}},t.prototype.addMarkersToToolbar=function(){for(var t,e=[],i=0;i<arguments.length;i++)e[i]=arguments[i];(t=this._availableMarkerTypes).push.apply(t,e)},t.prototype.addRenderEventListener=function(t){this.addEventListener("render",(function(e){t(e.dataUrl,e.state)}))},t.prototype.removeRenderEventListener=function(t){},t.prototype.addCloseEventListener=function(t){this.addEventListener("close",(function(){t()}))},t.prototype.removeCloseEventListener=function(t){},t.prototype.setupResizeObserver=function(){var t=this;"inline"===this.settings.displayMode?window.ResizeObserver&&(this.targetObserver=new ResizeObserver((function(){t.resize(t.target.clientWidth,t.target.clientHeight)})),this.targetObserver.observe(this.target)):"popup"===this.settings.displayMode&&(window.ResizeObserver&&(this.targetObserver=new ResizeObserver((function(){return t.onPopupTargetResize()})),this.targetObserver.observe(this.editorCanvas)),window.addEventListener("resize",this.setWindowHeight))},t.prototype.onPopupTargetResize=function(){var t=1*this.target.clientWidth/this.target.clientHeight,e=this.editorCanvas.clientWidth/t>this.editorCanvas.clientHeight?this.editorCanvas.clientHeight*t:this.editorCanvas.clientWidth,i=e<this.editorCanvas.clientWidth?this.editorCanvas.clientHeight:this.editorCanvas.clientWidth/t;this.resize(e,i)},t.prototype.setWindowHeight=function(){this.windowHeight=window.innerHeight},t.prototype.resize=function(t,e){var i=t/this.imageWidth,o=e/this.imageHeight;this.imageWidth=Math.round(t),this.imageHeight=Math.round(e),this.target instanceof HTMLImageElement&&this.editingTarget instanceof HTMLImageElement&&(this.editingTarget.src=this.target.src),this.editingTarget.width=this.imageWidth,this.editingTarget.height=this.imageHeight,this.editingTarget.style.width=this.imageWidth+"px",this.editingTarget.style.height=this.imageHeight+"px",this.markerImage.setAttribute("width",this.imageWidth.toString()),this.markerImage.setAttribute("height",this.imageHeight.toString()),this.markerImage.setAttribute("viewBox","0 0 "+this.imageWidth.toString()+" "+this.imageHeight.toString()),this.markerImageHolder.style.width=this.imageWidth+"px",this.markerImageHolder.style.height=this.imageHeight+"px",this.overlayContainer.style.width=this.imageWidth+"px",this.overlayContainer.style.height=this.imageHeight+"px","popup"!==this.settings.displayMode?this.coverDiv.style.width=this.imageWidth.toString()+"px":(this.setTopLeft(),this.positionMarkerImage()),void 0!==this.toolbar&&this.toolbar.adjustLayout(),this.positionLogo(),this.scaleMarkers(i,o)},t.prototype.scaleMarkers=function(t,e){var i;this.currentMarker&&this.currentMarker instanceof T||(i=this.currentMarker,this.setCurrentMarker()),this.markers.forEach((function(i){return i.scale(t,e)})),void 0!==i&&this.setCurrentMarker(i)},t.prototype.setEditingTarget=function(){this.imageWidth=Math.round(this.target.clientWidth),this.imageHeight=Math.round(this.target.clientHeight),this.target instanceof HTMLImageElement&&this.editingTarget instanceof HTMLImageElement&&(this.editingTarget.src=this.target.src),this.editingTarget.width=this.imageWidth,this.editingTarget.height=this.imageHeight,this.editingTarget.style.width=this.imageWidth+"px",this.editingTarget.style.height=this.imageHeight+"px"},t.prototype.setTopLeft=function(){var t=this.editingTarget.getBoundingClientRect(),e=this.editorCanvas.getBoundingClientRect();this.left=t.left-e.left,this.top=t.top-e.top},t.prototype.initMarkerCanvas=function(){this.markerImageHolder=document.createElement("div"),this.markerImageHolder.style.setProperty("touch-action","pinch-zoom"),this.markerImage=document.createElementNS("http://www.w3.org/2000/svg","svg"),this.markerImage.setAttribute("xmlns","http://www.w3.org/2000/svg"),this.markerImage.setAttribute("width",this.imageWidth.toString()),this.markerImage.setAttribute("height",this.imageHeight.toString()),this.markerImage.setAttribute("viewBox","0 0 "+this.imageWidth.toString()+" "+this.imageHeight.toString()),this.markerImage.style.pointerEvents="auto",this.markerImageHolder.style.position="absolute",this.markerImageHolder.style.width=this.imageWidth+"px",this.markerImageHolder.style.height=this.imageHeight+"px",this.markerImageHolder.style.transformOrigin="top left",this.positionMarkerImage(),this.markerImageHolder.appendChild(this.markerImage),this.editorCanvas.appendChild(this.markerImageHolder)},t.prototype.addDefs=function(){for(var t,e=[],i=0;i<arguments.length;i++)e[i]=arguments[i];this.defs=n.createDefs(),this.markerImage.insertBefore(this.defs,this.markerImage.firstChild),(t=this.defs).append.apply(t,e)},t.prototype.initOverlay=function(){this.overlayContainer=document.createElement("div"),this.overlayContainer.style.position="absolute",this.overlayContainer.style.left="0px",this.overlayContainer.style.top="0px",this.overlayContainer.style.width=this.imageWidth+"px",this.overlayContainer.style.height=this.imageHeight+"px",this.overlayContainer.style.display="flex",this.markerImageHolder.appendChild(this.overlayContainer)},t.prototype.positionMarkerImage=function(){this.markerImageHolder.style.top=this.top/this.zoomLevel+"px",this.markerImageHolder.style.left=this.left/this.zoomLevel+"px"},t.prototype.attachEvents=function(){this.markerImage.addEventListener("pointerdown",this.onPointerDown),this.markerImage.addEventListener("dblclick",this.onDblClick),this.attachWindowEvents()},t.prototype.attachWindowEvents=function(){window.addEventListener("pointermove",this.onPointerMove),window.addEventListener("pointerup",this.onPointerUp),window.addEventListener("pointercancel",this.onPointerOut),window.addEventListener("pointerout",this.onPointerOut),window.addEventListener("pointerleave",this.onPointerUp),window.addEventListener("resize",this.onWindowResize),window.addEventListener("keyup",this.onKeyUp)},t.prototype.detachEvents=function(){this.markerImage.removeEventListener("pointerdown",this.onPointerDown),this.markerImage.removeEventListener("dblclick",this.onDblClick),this.detachWindowEvents()},t.prototype.detachWindowEvents=function(){window.removeEventListener("pointermove",this.onPointerMove),window.removeEventListener("pointerup",this.onPointerUp),window.removeEventListener("pointercancel",this.onPointerOut),window.removeEventListener("pointerout",this.onPointerOut),window.removeEventListener("pointerleave",this.onPointerUp),window.removeEventListener("resize",this.onWindowResize),window.removeEventListener("keyup",this.onKeyUp)},t.prototype.addLogo=function(){this.logoUI=document.createElement("div"),this.logoUI.style.display="inline-block",this.logoUI.style.margin="0px",this.logoUI.style.padding="0px",this.logoUI.style.fill="#333333";var t=document.createElement("a");t.href="https://markerjs.com/",t.target="_blank",t.innerHTML='<svg viewBox="0 0 112 96" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414"><path fill="#e5f20d" fill-opacity=".647" d="M0 40.386h111.96V95.62H0z"/><path d="M93.61 61.452c0 .987-.328 1.831-.987 2.53-.657.7-1.52 1.048-2.591 1.048-1.481 0-2.222-.74-2.222-2.22 0-16.617-.533-29.347-1.604-38.192-1.068-8.842-2.92-13.265-5.552-13.265-4.443 0-10.94 15.509-19.497 46.52v.124c0 .987-.328 1.831-.987 2.53-.657.7-1.52 1.048-2.592 1.048-1.48 0-2.22-.74-2.22-2.22 0-3.29.165-8.392.493-15.302.33-7.732.494-13.82.494-18.262 0-6.17-.186-10.55-.556-13.142-.37-2.591-1.172-3.887-2.406-3.887-2.796 0-6.333 5.12-10.612 15.363C38.494 34.367 34.01 46.44 29.32 60.34l-1.11 3.209a5.714 5.714 0 01-1.42 2.097c-.617.578-1.295.864-2.036.864-.987 0-1.644-.081-1.974-.247-.328-.162-.533-.656-.617-1.48-.41-4.03-.74-9.418-.987-16.165-.163-1.728-.329-4.566-.494-8.515-.822-13.901-1.562-23.3-2.221-28.196-.657-4.893-.987-7.628-.987-8.205 0-.657.33-1.44.987-2.345.659-.903 1.276-1.357 1.85-1.357 1.319 0 2.387.947 3.21 2.838.411.906.863 4.526 1.357 10.859.493 6.335.905 14.19 1.233 23.568l.617 18.88c4.527-13.983 9.216-26.673 14.068-38.068C45.65 6.686 50.093.988 54.123.988c2.715 0 4.566 1.974 5.553 5.923.987 3.949 1.481 9.667 1.481 17.152 0 3.949-.081 9.625-.247 17.029l-.123 5.676c3.373-11.762 6.725-21.634 10.057-29.615 3.331-7.979 6.685-11.97 10.056-11.97 8.475 0 12.71 18.757 12.71 56.269z" fill-rule="nonzero"/></svg>',t.title="Powered by marker.js",t.style.display="grid",t.style.alignItems="center",t.style.justifyItems="center",t.style.padding="3px",t.style.width="20px",t.style.height="20px",this.logoUI.appendChild(t),this.editorCanvas.appendChild(this.logoUI),this.logoUI.style.position="absolute",this.logoUI.style.pointerEvents="all",this.positionLogo()},t.prototype.positionLogo=function(){this.logoUI&&("right"!==this.uiStyleSettings.logoPosition?this.logoUI.style.left=this.markerImageHolder.offsetLeft+10+"px":this.logoUI.style.left=this.markerImageHolder.offsetLeft+this.markerImageHolder.offsetWidth-this.logoUI.clientWidth-10+"px",this.logoUI.style.top=this.markerImageHolder.offsetTop+this.markerImageHolder.offsetHeight-this.logoUI.clientHeight-10+"px")},t.prototype.overrideOverflow=function(){this.scrollXState=window.scrollX,this.scrollYState=window.scrollY,this.bodyOverflowState=document.body.style.overflow,window.scroll({top:0,left:0}),document.body.style.overflow="hidden"},t.prototype.restoreOverflow=function(){document.body.style.overflow=this.bodyOverflowState,window.scroll({top:this.scrollYState,left:this.scrollXState})},t.prototype.showUI=function(){switch("popup"===this.settings.displayMode&&this.overrideOverflow(),this.coverDiv=document.createElement("div"),this.coverDiv.style.visibility=this._silentRenderMode?"hidden":"visible",this.coverDiv.className=l.CLASS_PREFIX,this.coverDiv.style.fontSize="16px",this.coverDiv.style.userSelect="none",this.settings.displayMode){case"inline":this.coverDiv.style.position="absolute";var t=this.target.getClientRects().item(0).y>l.settings.toolbarHeight?this.target.offsetTop-l.settings.toolbarHeight:0;this.coverDiv.style.top=t+"px",this.coverDiv.style.left=this.target.offsetLeft.toString()+"px",this.coverDiv.style.width=this.target.offsetWidth.toString()+"px",this.coverDiv.style.zIndex=void 0!==this.uiStyleSettings.zIndex?this.uiStyleSettings.zIndex:"5";break;case"popup":this.coverDiv.style.position="absolute",this.coverDiv.style.top="0px",this.coverDiv.style.left="0px",this.coverDiv.style.width="100vw",this.coverDiv.style.height=window.innerHeight+"px",this.coverDiv.style.backgroundColor="rgba(0, 0, 0, 0.75)",this.coverDiv.style.zIndex=void 0!==this.uiStyleSettings.zIndex?this.uiStyleSettings.zIndex:"1000",this.coverDiv.style.display="flex"}this.targetRoot.appendChild(this.coverDiv),this.uiDiv=document.createElement("div"),this.uiDiv.style.display="flex",this.uiDiv.style.flexDirection="column",this.uiDiv.style.flexGrow="2",this.uiDiv.style.margin="popup"===this.settings.displayMode?this.settings.popupMargin+"px":"0px",this.uiDiv.style.border="0px",this.coverDiv.appendChild(this.uiDiv),this.toolbar=new u(this.uiDiv,this.settings.displayMode,this._availableMarkerTypes,this.uiStyleSettings),this.toolbar.addButtonClickListener(this.toolbarButtonClicked),this.toolbar.show(this._silentRenderMode||this.uiStyleSettings.hideToolbar?"hidden":"visible"),this.contentDiv=document.createElement("div"),this.contentDiv.style.display="flex",this.contentDiv.style.flexDirection="row",this.contentDiv.style.flexGrow="2",this.contentDiv.style.flexShrink="1","popup"===this.settings.displayMode&&(this.contentDiv.style.backgroundColor=this.uiStyleSettings.canvasBackgroundColor,this.contentDiv.style.maxHeight=this.windowHeight-2*this.settings.popupMargin-3.5*this.uiStyleSettings.toolbarHeight+"px",this.contentDiv.style.maxWidth="calc(100vw - "+2*this.settings.popupMargin+"px)"),this.contentDiv.style.overflow="auto",this.uiDiv.appendChild(this.contentDiv),this.editorCanvas=document.createElement("div"),this.editorCanvas.style.flexGrow="2",this.editorCanvas.style.flexShrink="1",this.editorCanvas.style.position="relative",this.editorCanvas.style.overflow="hidden",this.editorCanvas.style.display="flex","popup"===this.settings.displayMode&&(this.editorCanvas.style.alignItems="center",this.editorCanvas.style.justifyContent="center"),this.editorCanvas.style.pointerEvents="none",this.editorCanvas.style.transformOrigin="left top",this.editorCanvas.style.transform="scale("+this.zoomLevel+")",this.contentDiv.appendChild(this.editorCanvas),this.editingTarget=this.target instanceof HTMLImageElement?document.createElement("img"):document.createElement("canvas"),this.target.getClientRects().item(0).y<l.settings.toolbarHeight&&(this.editingTarget.style.marginTop=this.target.offsetTop-l.settings.toolbarHeight+"px"),this.editorCanvas.appendChild(this.editingTarget),this.toolbox=new d(this.uiDiv,this.settings.displayMode,this.uiStyleSettings),this.toolbox.show(this._silentRenderMode||this.uiStyleSettings.hideToolbox?"hidden":"visible")},t.prototype.closeUI=function(){"popup"===this.settings.displayMode&&this.restoreOverflow(),this.targetRoot.removeChild(this.coverDiv)},t.prototype.removeMarker=function(t){this.markerImage.removeChild(t.container),this.markers.indexOf(t)>-1&&this.markers.splice(this.markers.indexOf(t),1),t.dispose()},t.prototype.switchToSelectMode=function(){this.mode="select",this.hideNotesEditor(),void 0!==this.currentMarker&&("new"!==this.currentMarker.state?this.currentMarker.select():(this.removeMarker(this.currentMarker),this.setCurrentMarker(),this.markerImage.style.cursor="default"),this.addUndoStep())},t.prototype.toolbarButtonClicked=function(t,e){if("marker"===t&&void 0!==e)this.createNewMarker(e);else if("action"===t)switch(e){case"select":this.switchToSelectMode();break;case"delete":this.deleteSelectedMarker();break;case"clear":this.clear();break;case"undo":this.switchToSelectMode(),this.addUndoStep(),this.undo();break;case"redo":this.switchToSelectMode(),this.redo();break;case"zoom":this.stepZoom();break;case"zoom-out":this.zoomLevel=1;break;case"notes":void 0===this.notesArea?(this.switchToSelectMode(),this.zoomLevel=1,this.showNotesEditor()):this.switchToSelectMode();break;case"close":this.close();break;case"render":this.switchToSelectMode(),this.startRenderAndClose()}},t.prototype.deleteSelectedMarker=function(){var t=this;if(void 0!==this.currentMarker){var e=!1;if(this.eventListeners.markerbeforedelete.forEach((function(i){var o=new U(t,t.currentMarker,!0);i(o),o.defaultPrevented&&(e=!0)})),!e){var i=this.currentMarker;this.currentMarker.dispose(),this.markerImage.removeChild(this.currentMarker.container),this.markers.splice(this.markers.indexOf(this.currentMarker),1),this.setCurrentMarker(),this.addUndoStep(),this.eventListeners.markerdelete.forEach((function(e){return e(new U(t,i))}))}}},t.prototype.clear=function(){this.setCurrentMarker();for(var t=this.markers.length-1;t>=0;t--)this.setCurrentMarker(this.markers[t]),this.currentMarker.dispose(),this.markerImage.removeChild(this.currentMarker.container),this.markers.splice(this.markers.indexOf(this.currentMarker),1);this.addUndoStep()},Object.defineProperty(t.prototype,"isNotesAreaOpen",{get:function(){return void 0!==this.notesArea},enumerable:!1,configurable:!0}),t.prototype.showNotesEditor=function(){var t;void 0!==this.currentMarker&&(this.overlayContainer.innerHTML="",this.notesArea=document.createElement("textarea"),this.notesArea.className=this.uiStyleSettings.notesAreaStyleClassName,this.notesArea.style.pointerEvents="auto",this.notesArea.style.alignSelf="stretch",this.notesArea.style.width="100%",this.notesArea.style.margin=this.uiStyleSettings.toolbarHeight/4+"px",this.notesArea.value=null!==(t=this.currentMarker.notes)&&void 0!==t?t:"",this.overlayContainer.appendChild(this.notesArea))},t.prototype.hideNotesEditor=function(){this.isNotesAreaOpen&&(void 0!==this.currentMarker&&(this.currentMarker.notes=""!==this.notesArea.value.trim()?this.notesArea.value:void 0),this.overlayContainer.removeChild(this.notesArea),this.notesArea=void 0)},t.prototype.selectLastMarker=function(){this.markers.length>0&&this.setCurrentMarker(this.markers[this.markers.length-1])},t.prototype.addUndoStep=function(){void 0!==this.currentMarker&&"edit"===this.currentMarker.state||this.undoRedoManager.addUndoStep(this.getState())},t.prototype.undo=function(){var t=this.undoRedoManager.undo();void 0!==t&&(this.restoreState(t),this.selectLastMarker())},t.prototype.redo=function(){var t=this.undoRedoManager.redo();void 0!==t&&(this.restoreState(t),this.selectLastMarker())},t.prototype.stepZoom=function(){var t=this.zoomSteps.indexOf(this.zoomLevel);this.zoomLevel=t<this.zoomSteps.length-1?this.zoomSteps[t+1]:this.zoomSteps[0]},t.prototype.panTo=function(t){this.contentDiv.scrollBy({left:this.prevPanPoint.x-t.x,top:this.prevPanPoint.y-t.y}),this.prevPanPoint=t},t.prototype.startRenderAndClose=function(){return o(this,void 0,void 0,(function(){var t,e,i=this;return s(this,(function(o){switch(o.label){case 0:return[4,this.render()];case 1:return t=o.sent(),e=this.getState(),this.eventListeners.render.forEach((function(o){return o(new j(i,t,e))})),this.close(!0),[2]}}))}))},t.prototype.getState=function(t){!0===t&&this.setCurrentMarker();var e={width:this.imageWidth,height:this.imageHeight,markers:[]};return this.markers.forEach((function(t){return e.markers.push(t.getState())})),e},t.prototype.restoreState=function(t){var e=this;for(this.markers.splice(0);this.markerImage.lastChild;)this.markerImage.removeChild(this.markerImage.lastChild);t.markers.forEach((function(t){var i=e._availableMarkerTypes.find((function(e){return e.typeName===t.typeName}));if(void 0!==i){var o=e.addNewMarker(i);o.restoreState(t),e.markers.push(o)}})),t.width&&t.height&&(t.width!==this.imageWidth||t.height!==this.imageHeight)&&this.scaleMarkers(this.imageWidth/t.width,this.imageHeight/t.height),this.eventListeners.restorestate.forEach((function(t){return t(new F(e))}))},t.prototype.addNewMarker=function(t){var e=n.createGroup();return this.markerImage.appendChild(e),new t(e,this.overlayContainer,this.settings)},t.prototype.createNewMarker=function(t){var e,i=this;(e="string"==typeof t?this._availableMarkerTypes.find((function(e){return e.typeName===t})):t)&&(this.setCurrentMarker(),this.currentMarker=this.addNewMarker(e),this.currentMarker.onMarkerCreated=this.markerCreated,this.currentMarker.onColorChanged=this.colorChanged,this.currentMarker.onFillColorChanged=this.fillColorChanged,this.markerImage.style.cursor="crosshair",this.toolbar.setActiveMarkerButton(e.typeName),this.toolbox.setPanelButtons(this.currentMarker.toolboxPanels),this.eventListeners.markercreating.forEach((function(t){return t(new U(i,i.currentMarker))})))},t.prototype.markerCreated=function(t){var e=this;this.mode="select",this.markerImage.style.cursor="default",this.markers.push(t),this.setCurrentMarker(t),t instanceof L&&this.settings.newFreehandMarkerOnPointerUp?this.createNewMarker(L):this.toolbar.setSelectMode(),this.addUndoStep(),this.eventListeners.markercreate.forEach((function(t){return t(new U(e,e.currentMarker))}))},t.prototype.colorChanged=function(t){this.settings.defaultColorsFollowCurrentColors&&(this.settings.defaultColor=t,this.settings.defaultStrokeColor=t)},t.prototype.fillColorChanged=function(t){this.settings.defaultColorsFollowCurrentColors&&(this.settings.defaultFillColor=t)},t.prototype.setCurrentMarker=function(t){var e=this;this.currentMarker!==t&&void 0!==this.currentMarker&&(this.currentMarker.deselect(),this.toolbar.setCurrentMarker(),this.toolbox.setPanelButtons([]),this.eventListeners.markerdeselect.forEach((function(t){return t(new U(e,e.currentMarker))}))),this.currentMarker=t,void 0===this.currentMarker||this.currentMarker.isSelected||(this.currentMarker.select(),this.toolbar.setCurrentMarker(this.currentMarker),this.toolbox.setPanelButtons(this.currentMarker.toolboxPanels),this.eventListeners.markerselect.forEach((function(t){return t(new U(e,e.currentMarker))})))},t.prototype.onPointerDown=function(t){if(this._isFocused||this.focus(),this.touchPoints++,1===this.touchPoints||"touch"!==t.pointerType)if(void 0===this.currentMarker||"new"!==this.currentMarker.state&&"creating"!==this.currentMarker.state){if("select"===this.mode){var e=this.markers.find((function(e){return e.ownsTarget(t.target)}));void 0!==e?(this.setCurrentMarker(e),this.isDragging=!0,this.currentMarker.pointerDown(this.clientToLocalCoordinates(t.clientX,t.clientY),t.target)):(this.setCurrentMarker(),this.isDragging=!0,this.prevPanPoint={x:t.clientX,y:t.clientY})}}else this.isDragging=!0,this.currentMarker.pointerDown(this.clientToLocalCoordinates(t.clientX,t.clientY))},t.prototype.onDblClick=function(t){if(this._isFocused||this.focus(),"select"===this.mode){var e=this.markers.find((function(e){return e.ownsTarget(t.target)}));void 0!==e&&e!==this.currentMarker&&this.setCurrentMarker(e),void 0!==this.currentMarker?this.currentMarker.dblClick(this.clientToLocalCoordinates(t.clientX,t.clientY),t.target):this.setCurrentMarker()}},t.prototype.onPointerMove=function(t){1!==this.touchPoints&&"touch"===t.pointerType||(void 0!==this.currentMarker||this.isDragging)&&(void 0!==this.currentMarker&&"edit"===this.currentMarker.state||t.preventDefault(),void 0!==this.currentMarker?this.currentMarker.manipulate(this.clientToLocalCoordinates(t.clientX,t.clientY)):this.zoomLevel>1&&this.panTo({x:t.clientX,y:t.clientY}))},t.prototype.onPointerUp=function(t){this.touchPoints>0&&this.touchPoints--,0===this.touchPoints&&this.isDragging&&void 0!==this.currentMarker&&this.currentMarker.pointerUp(this.clientToLocalCoordinates(t.clientX,t.clientY)),this.isDragging=!1,this.addUndoStep()},t.prototype.onPointerOut=function(){this.touchPoints>0&&this.touchPoints--},t.prototype.onKeyUp=function(t){void 0===this.currentMarker||void 0!==this.notesArea||"Delete"!==t.key&&"Backspace"!==t.key||this.deleteSelectedMarker()},t.prototype.clientToLocalCoordinates=function(t,e){var i=this.markerImage.getBoundingClientRect();return{x:(t-i.left)/this.zoomLevel,y:(e-i.top)/this.zoomLevel}},t.prototype.onWindowResize=function(){this.positionUI()},t.prototype.positionUI=function(){switch(this.setTopLeft(),this.settings.displayMode){case"inline":var t=this.target.offsetTop>l.settings.toolbarHeight?this.target.offsetTop-l.settings.toolbarHeight:0;this.coverDiv.style.top=t+"px",this.coverDiv.style.left=this.target.offsetLeft.toString()+"px";break;case"popup":this.coverDiv.style.top="0px",this.coverDiv.style.left="0px",this.coverDiv.style.width="100vw",this.coverDiv.style.height=this.windowHeight+"px",this.contentDiv.style.maxHeight=this.windowHeight-2*this.settings.popupMargin-3.5*this.uiStyleSettings.toolbarHeight+"px"}this.positionMarkerImage(),this.positionLogo()},t.prototype.addLicenseKey=function(t){a.addKey(t)},t.prototype.addEventListener=function(t,e){this.eventListeners.addEventListener(t,e)},t.prototype.removeEventListener=function(t,e){this.eventListeners.removeEventListener(t,e)},t.prototype.renderState=function(t){this._silentRenderMode=!0,this.settings.displayMode="inline",this.isOpen||this.show(),this.restoreState(t),this.startRenderAndClose(),this._silentRenderMode=!1},Object.defineProperty(t.prototype,"isFocused",{get:function(){return this._isFocused},enumerable:!1,configurable:!0}),t.prototype.focus=function(){var t=this;this._isFocused||(this.attachWindowEvents(),this._isFocused=!0,void 0!==this._previousCurrentMarker&&this.setCurrentMarker(this._previousCurrentMarker),this.eventListeners.focus.forEach((function(e){return e(new F(t))})))},t.prototype.blur=function(){var t=this;this._isFocused&&(this.detachWindowEvents(),this._isFocused=!1,this._previousCurrentMarker=this.currentMarker,this.setCurrentMarker(),this.eventListeners.blur.forEach((function(e){return e(new F(t))})))},t}();t.Activator=a,t.ArrowMarker=D,t.ArrowTypePanel=A,t.CalloutMarker=N,t.ColorPickerPanel=g,t.CoverMarker=I,t.CurveMarker=G,t.EllipseFrameMarker=V,t.EllipseMarker=O,t.EventListenerRepository=X,t.FontFamilyPanel=P,t.FrameMarker=x,t.FreehandMarker=L,t.HighlightMarker=H,t.LineMarker=E,t.LineStylePanel=w,t.LineWidthPanel=S,t.LinearMarkerBase=M,t.MarkerArea=Y,t.MarkerAreaEvent=F,t.MarkerAreaRenderEvent=j,t.MarkerBase=f,t.MarkerEvent=U,t.MeasurementMarker=z,t.OpacityPanel=W,t.RectangleMarker=k,t.RectangularBoxMarkerBase=b,t.RectangularBoxMarkerGrips=v,t.ResizeGrip=m,t.Settings=B,t.Style=l,t.StyleClass=c,t.SvgHelper=n,t.TextMarker=T,t.ToolboxPanel=y,t.TransformMatrix=C,Object.defineProperty(t,"__esModule",{value:!0})}));
+//# sourceMappingURL=markerjs2.js.map
diff --git a/capsule-prototype/js/libs/markerjs2/markerjs2.js.map b/capsule-prototype/js/libs/markerjs2/markerjs2.js.map
new file mode 100644
index 0000000000000000000000000000000000000000..a1c2a1762059abb0d1c4596cee90ad89398a57c1
--- /dev/null
+++ b/capsule-prototype/js/libs/markerjs2/markerjs2.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"markerjs2.js","sources":["../node_modules/tslib/tslib.es6.js","../src/core/SvgHelper.ts","../src/core/Activator.ts","../src/core/Renderer.ts","../src/core/Style.ts","../src/ui/Toolbar.ts","../src/ui/Toolbox.ts","../src/ui/ToolboxPanel.ts","../src/ui/toolbox-panels/ColorPickerPanel.ts","../src/core/MarkerBase.ts","../src/markers/RectangularBoxMarkerGrips.ts","../src/markers/ResizeGrip.ts","../src/core/TransformMatrix.ts","../src/markers/RectangularBoxMarkerBase.ts","../src/markers/RectangleMarker.ts","../src/ui/toolbox-panels/LineWidthPanel.ts","../src/ui/toolbox-panels/LineStylePanel.ts","../src/markers/frame-marker/FrameMarker.ts","../src/core/Settings.ts","../src/markers/LinearMarkerBase.ts","../src/markers/line-marker/LineMarker.ts","../src/ui/toolbox-panels/FontFamilyPanel.ts","../src/markers/text-marker/TextMarker.ts","../src/markers/freehand-marker/FreehandMarker.ts","../src/ui/toolbox-panels/ArrowTypePanel.ts","../src/markers/arrow-marker/ArrowMarker.ts","../src/markers/cover-marker/CoverMarker.ts","../src/ui/toolbox-panels/OpacityPanel.ts","../src/markers/highlight-marker/HighlightMarker.ts","../src/markers/callout-marker/CalloutMarker.ts","../src/markers/ellipse-marker/EllipseMarker.ts","../src/markers/measurement-marker/MeasurementMarker.ts","../src/markers/ellipse-frame-marker/EllipseFrameMarker.ts","../src/core/UndoRedoManager.ts","../src/markers/curve-marker/CurveMarker.ts","../src/core/Events.ts","../src/MarkerArea.ts"],"sourcesContent":["/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n    extendStatics = Object.setPrototypeOf ||\r\n        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n        function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n    return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n    extendStatics(d, b);\r\n    function __() { this.constructor = d; }\r\n    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n    __assign = Object.assign || function __assign(t) {\r\n        for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n            s = arguments[i];\r\n            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n        }\r\n        return t;\r\n    }\r\n    return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n    var t = {};\r\n    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n        t[p] = s[p];\r\n    if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n            if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n                t[p[i]] = s[p[i]];\r\n        }\r\n    return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n    if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n    return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n    return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n    if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n    return new (P || (P = Promise))(function (resolve, reject) {\r\n        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n        function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n        step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n    });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n    return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n    function verb(n) { return function (v) { return step([n, v]); }; }\r\n    function step(op) {\r\n        if (f) throw new TypeError(\"Generator is already executing.\");\r\n        while (_) try {\r\n            if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n            if (y = 0, t) op = [op[0] & 2, t.value];\r\n            switch (op[0]) {\r\n                case 0: case 1: t = op; break;\r\n                case 4: _.label++; return { value: op[1], done: false };\r\n                case 5: _.label++; y = op[1]; op = [0]; continue;\r\n                case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n                default:\r\n                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n                    if (t[2]) _.ops.pop();\r\n                    _.trys.pop(); continue;\r\n            }\r\n            op = body.call(thisArg, _);\r\n        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n    }\r\n}\r\n\r\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\r\n    if (k2 === undefined) k2 = k;\r\n    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\r\n}) : (function(o, m, k, k2) {\r\n    if (k2 === undefined) k2 = k;\r\n    o[k2] = m[k];\r\n});\r\n\r\nexport function __exportStar(m, o) {\r\n    for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n}\r\n\r\nexport function __values(o) {\r\n    var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n    if (m) return m.call(o);\r\n    if (o && typeof o.length === \"number\") return {\r\n        next: function () {\r\n            if (o && i >= o.length) o = void 0;\r\n            return { value: o && o[i++], done: !o };\r\n        }\r\n    };\r\n    throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n    var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n    if (!m) return o;\r\n    var i = m.call(o), r, ar = [], e;\r\n    try {\r\n        while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n    }\r\n    catch (error) { e = { error: error }; }\r\n    finally {\r\n        try {\r\n            if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n        }\r\n        finally { if (e) throw e.error; }\r\n    }\r\n    return ar;\r\n}\r\n\r\nexport function __spread() {\r\n    for (var ar = [], i = 0; i < arguments.length; i++)\r\n        ar = ar.concat(__read(arguments[i]));\r\n    return ar;\r\n}\r\n\r\nexport function __spreadArrays() {\r\n    for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n    for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n        for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n            r[k] = a[j];\r\n    return r;\r\n};\r\n\r\nexport function __await(v) {\r\n    return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n    if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n    var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n    return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n    function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n    function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n    function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n    function fulfill(value) { resume(\"next\", value); }\r\n    function reject(value) { resume(\"throw\", value); }\r\n    function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n    var i, p;\r\n    return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n    function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n    if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n    var m = o[Symbol.asyncIterator], i;\r\n    return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n    function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n    function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n    if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n    return cooked;\r\n};\r\n\r\nvar __setModuleDefault = Object.create ? (function(o, v) {\r\n    Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n    o[\"default\"] = v;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n    if (mod && mod.__esModule) return mod;\r\n    var result = {};\r\n    if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n    __setModuleDefault(result, mod);\r\n    return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n    return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, privateMap) {\r\n    if (!privateMap.has(receiver)) {\r\n        throw new TypeError(\"attempted to get private field on non-instance\");\r\n    }\r\n    return privateMap.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, privateMap, value) {\r\n    if (!privateMap.has(receiver)) {\r\n        throw new TypeError(\"attempted to set private field on non-instance\");\r\n    }\r\n    privateMap.set(receiver, value);\r\n    return value;\r\n}\r\n","/**\n * Utility class to simplify SVG operations.\n */\nexport class SvgHelper {\n  /**\n   * Creates SVG \"defs\".\n   */\n  public static createDefs(): SVGDefsElement {\n    const defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');\n\n    return defs;\n  }\n\n  /**\n   * Sets attributes on an arbitrary SVG element\n   * @param el - target SVG element.\n   * @param attributes - set of name-value attribute pairs.\n   */\n  public static setAttributes(\n    el: SVGElement,\n    attributes: Array<[string, string]>\n  ): void {\n    for (const [attr, value] of attributes) {\n      el.setAttribute(attr, value);\n    }\n  }\n\n  /**\n   * Creates an SVG rectangle with the specified width and height.\n   * @param width \n   * @param height \n   * @param attributes - additional attributes.\n   */\n  public static createRect(\n    width: number | string,\n    height: number | string,\n    attributes?: Array<[string, string]>\n  ): SVGRectElement {\n    const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');\n\n    rect.setAttribute('width', width.toString());\n    rect.setAttribute('height', height.toString());\n    if (attributes) {\n      SvgHelper.setAttributes(rect, attributes);\n    }\n\n    return rect;\n  }\n\n  /**\n   * Creates an SVG line with specified end-point coordinates.\n   * @param x1 \n   * @param y1 \n   * @param x2 \n   * @param y2 \n   * @param attributes - additional attributes.\n   */\n  public static createLine(\n    x1: number | string,\n    y1: number | string,\n    x2: number | string,\n    y2: number | string,\n    attributes?: Array<[string, string]>\n  ): SVGLineElement {\n    const line = document.createElementNS('http://www.w3.org/2000/svg', 'line');\n\n    line.setAttribute('x1', x1.toString());\n    line.setAttribute('y1', y1.toString());\n    line.setAttribute('x2', x2.toString());\n    line.setAttribute('y2', y2.toString());\n    if (attributes) {\n      SvgHelper.setAttributes(line, attributes);\n    }\n\n    return line;\n  }\n\n  /**\n   * Creates an SVG polygon with specified points.\n   * @param points - points as string.\n   * @param attributes - additional attributes.\n   */\n  public static createPolygon(\n    points: string,\n    attributes?: Array<[string, string]>\n  ): SVGPolygonElement {\n    const polygon = document.createElementNS(\n      'http://www.w3.org/2000/svg',\n      'polygon'\n    );\n\n    polygon.setAttribute('points', points);\n    if (attributes) {\n      SvgHelper.setAttributes(polygon, attributes);\n    }\n\n    return polygon;\n  }\n\n  /**\n   * Creates an SVG circle with the specified radius.\n   * @param radius \n   * @param attributes - additional attributes.\n   */\n  public static createCircle(\n    radius: number,\n    attributes?: Array<[string, string]>\n  ): SVGCircleElement {\n    const circle = document.createElementNS(\n      'http://www.w3.org/2000/svg',\n      'circle'\n    );\n\n    circle.setAttribute('cx', (radius / 2).toString());\n    circle.setAttribute('cy', (radius / 2).toString());\n    circle.setAttribute('r', radius.toString());\n    if (attributes) {\n      SvgHelper.setAttributes(circle, attributes);\n    }\n\n    return circle;\n  }\n\n  /**\n   * Creates an SVG ellipse with the specified horizontal and vertical radii.\n   * @param rx \n   * @param ry \n   * @param attributes - additional attributes.\n   */\n  public static createEllipse(\n    rx: number,\n    ry: number,\n    attributes?: Array<[string, string]>\n  ): SVGEllipseElement {\n    const ellipse = document.createElementNS(\n      'http://www.w3.org/2000/svg',\n      'ellipse'\n    );\n\n    ellipse.setAttribute('cx', (rx / 2).toString());\n    ellipse.setAttribute('cy', (ry / 2).toString());\n    ellipse.setAttribute('rx', (rx / 2).toString());\n    ellipse.setAttribute('ry', (ry / 2).toString());\n    if (attributes) {\n      SvgHelper.setAttributes(ellipse, attributes);\n    }\n\n    return ellipse;\n  }\n\n  /**\n   * Creates an SVG group.\n   * @param attributes - additional attributes.\n   */\n  public static createGroup(attributes?: Array<[string, string]>): SVGGElement {\n    const g = document.createElementNS('http://www.w3.org/2000/svg', 'g');\n    if (attributes) {\n      SvgHelper.setAttributes(g, attributes);\n    }\n    return g;\n  }\n\n  /**\n   * Creates an SVG transform.\n   */\n  public static createTransform(): SVGTransform {\n    const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n\n    return svg.createSVGTransform();\n  }\n\n  /**\n   * Creates an SVG marker.\n   * @param id \n   * @param orient \n   * @param markerWidth \n   * @param markerHeight \n   * @param refX \n   * @param refY \n   * @param markerElement \n   */\n  public static createMarker(\n    id: string,\n    orient: string,\n    markerWidth: number | string,\n    markerHeight: number | string,\n    refX: number | string,\n    refY: number | string,\n    markerElement: SVGGraphicsElement\n  ): SVGMarkerElement {\n    const marker = document.createElementNS(\n      'http://www.w3.org/2000/svg',\n      'marker'\n    );\n    SvgHelper.setAttributes(marker, [\n      ['id', id],\n      ['orient', orient],\n      ['markerWidth', markerWidth.toString()],\n      ['markerHeight', markerHeight.toString()],\n      ['refX', refX.toString()],\n      ['refY', refY.toString()],\n    ]);\n\n    marker.appendChild(markerElement);\n\n    return marker;\n  }\n\n  /**\n   * Creaes an SVG text element.\n   * @param attributes - additional attributes.\n   */\n  public static createText(\n    attributes?: Array<[string, string]>\n  ): SVGTextElement {\n    const text = document.createElementNS('http://www.w3.org/2000/svg', 'text');\n    text.setAttribute('x', '0');\n    text.setAttribute('y', '0');\n\n    if (attributes) {\n      SvgHelper.setAttributes(text, attributes);\n    }\n\n    return text;\n  }\n\n  /**\n   * Creates an SVG TSpan.\n   * @param text - inner text.\n   * @param attributes - additional attributes.\n   */\n  public static createTSpan(\n    text: string,\n    attributes?: Array<[string, string]>\n  ): SVGTSpanElement {\n    const tspan = document.createElementNS(\n      'http://www.w3.org/2000/svg',\n      'tspan'\n    );\n    tspan.textContent = text;\n\n    if (attributes) {\n      SvgHelper.setAttributes(tspan, attributes);\n    }\n\n    return tspan;\n  }\n\n  /**\n   * Creates an SVG image element.\n   * @param attributes - additional attributes.\n   */\n  public static createImage(\n    attributes?: Array<[string, string]>\n  ): SVGImageElement {\n    const image = document.createElementNS(\n      'http://www.w3.org/2000/svg',\n      'image'\n    );\n\n    if (attributes) {\n      SvgHelper.setAttributes(image, attributes);\n    }\n\n    return image;\n  }\n\n  /**\n   * Creates an SVG point with the specified coordinates.\n   * @param x \n   * @param y \n   */\n  public static createPoint(      \n    x: number,\n    y: number\n  ): SVGPoint {\n      const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n      const svgPoint = svg.createSVGPoint();\n      svgPoint.x = x;\n      svgPoint.y = y;\n  \n      return svgPoint;\n  }\n\n  /**\n   * Creates an SVG path with the specified shape (d).\n   * @param d - path shape\n   * @param attributes - additional attributes.\n   */\n   public static createPath(\n    d: string,\n    attributes?: Array<[string, string]>\n  ): SVGPathElement {\n    const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');\n\n    path.setAttribute('d', d);\n    if (attributes) {\n      SvgHelper.setAttributes(path, attributes);\n    }\n\n    return path;\n  }\n}\n","/**\n * Manages commercial marker.js 2 licenses.\n */\nexport class Activator {\n  private static key: string;\n\n  /**\n   * Add a license key\n   * @param key license key sent to you after purchase.\n   */\n  public static addKey(key: string): void {\n    Activator.key = key;\n  }\n\n  /**\n   * Returns true if the copy of marker.js is commercially licensed.\n   */\n  public static get isLicensed(): boolean {\n    // NOTE:\n    // before removing or modifying this please consider supporting marker.js\n    // by visiting https://markerjs.com/ for details\n    // thank you!\n    if (Activator.key) {\n      const keyRegex = new RegExp(/^MJS2-[A-Z][0-9]{3}-[A-Z][0-9]{3}-[0-9]{4}$/, 'i');\n      return keyRegex.test(Activator.key);\n    } else {\n      return false;\n    }\n  }\n}\n","/**\n * Renders the original image and markup to a flat raster image.\n */\nexport class Renderer {\n    /**\n     * Whether the image should be rendered at the original (natural) target image size.\n     */\n    public naturalSize = false; \n    /**\n     * Rendered image type (`image/png`, `image/jpeg`, etc.).\n     */\n    public imageType = 'image/png';\n    /**\n     * For formats that support it, specifies rendering quality.\n     * \n     * In the case of `image/jpeg` you can specify a value between 0 and 1 (lowest to highest quality).\n     *\n     * @type {number} - image rendering quality (0..1)\n     */\n    public imageQuality?: number;\n    /**\n     * When set to true, only the marker layer without the original image will be rendered.\n     */\n    public markersOnly = false;\n\n    /**\n     * When set and {@linkcode naturalSize} is `false` sets the width of the rendered image.\n     * \n     * Both `width` and `height` have to be set for this to take effect.\n     */\n    public width?: number;\n    /**\n     * When set and {@linkcode naturalSize} is `false` sets the height of the rendered image.\n     * \n     * Both `width` and `height` have to be set for this to take effect.\n     */\n    public height?: number;\n\n\n    /**\n     * Initiates rendering of the result image and returns a promise which when resolved\n     * contains a data URL for the rendered image.\n     * \n     * @param target - target (underlying original) image\n     * @param markerImage - marker layer\n     */\n    public rasterize(\n        target: HTMLImageElement, \n        markerImage: SVGSVGElement,\n        targetCanvas?: HTMLCanvasElement \n    ): Promise<string> {\n        return new Promise<string>((resolve) => {\n            const canvas = targetCanvas !== undefined ? targetCanvas : document.createElement(\"canvas\");\n\n            if (target === null) {\n                this.markersOnly = true;\n                this.naturalSize = false;\n            }\n\n            const markerImageCopy = document.createElementNS(\n            'http://www.w3.org/2000/svg',\n            'svg'\n            );\n            markerImageCopy.setAttribute('xmlns', 'http://www.w3.org/2000/svg');\n            markerImageCopy.setAttribute('width', markerImage.width.baseVal.valueAsString);\n            markerImageCopy.setAttribute(\n              'height',\n              markerImage.height.baseVal.valueAsString\n            );\n            markerImageCopy.setAttribute(\n              'viewBox',\n              '0 0 ' +\n                markerImage.viewBox.baseVal.width.toString() +\n                ' ' +\n                markerImage.viewBox.baseVal.height.toString()\n            );            \n            markerImageCopy.innerHTML = markerImage.innerHTML;\n\n            if (this.naturalSize === true) {\n                // scale to full image size\n                markerImageCopy.width.baseVal.value = target.naturalWidth;\n                markerImageCopy.height.baseVal.value = target.naturalHeight;\n            } else if (this.width !== undefined && this.height !== undefined) {\n                // scale to specific dimensions\n                markerImageCopy.width.baseVal.value = this.width;\n                markerImageCopy.height.baseVal.value = this.height;\n            }\n    \n            canvas.width = markerImageCopy.width.baseVal.value;\n            canvas.height = markerImageCopy.height.baseVal.value;\n    \n            const data = markerImageCopy.outerHTML;\n\n            const ctx = canvas.getContext(\"2d\");\n            if (this.markersOnly !== true) { \n                ctx.drawImage(target, 0, 0, canvas.width, canvas.height);\n            }\n    \n            const DOMURL = window.URL; // || window.webkitURL || window;\n    \n            const img = new Image(canvas.width, canvas.height);\n            img.setAttribute(\"crossOrigin\", \"anonymous\");\n    \n            const blob = new Blob([data], { type: \"image/svg+xml\" });\n    \n            const url = DOMURL.createObjectURL(blob);\n    \n            img.onload = () => {\n                ctx.drawImage(img, 0, 0);\n                DOMURL.revokeObjectURL(url);\n    \n                const result = canvas.toDataURL(this.imageType, this.imageQuality);\n                resolve(result);\n            };\n    \n            img.src = url;\n        });\n    }\n}\n","import { IStyleSettings } from './IStyleSettings';\n\n/**\n * Simple utility CSS-in-JS implementation.\n */\nexport class Style {\n  /**\n   * Prefix used for all internally created CSS classes.\n   */\n  public static CLASS_PREFIX = '__markerjs2_';\n\n  private static classes: StyleClass[] = [];\n  private static rules: StyleRule[] = [];\n  private static styleSheet?: HTMLStyleElement;\n\n  /**\n   * For cases when you need to add the stylesheet to anything\n   * other than document.head (default), set this property\n   * befor calling `MarkerArea.show()`.\n   *\n   * Example: here we set the rendering/placement root (targetRoot)\n   * to the `shadowRoot` of a web componet and set `styleSheetRoot`\n   * to the same value as well.\n   *\n   * ```javascript\n   * const markerArea = new markerjs2.MarkerArea(target);\n   * markerArea.targetRoot = this.shadowRoot;\n   * markerjs2.Style.styleSheetRoot = this.shadowRoot;\n   * markerArea.show();\n   * ```\n   *\n   * Known issue/limitation:\n   * you can't use marker.js 2 in both main and Shadow DOM\n   * on the same page.\n   */\n  public static styleSheetRoot: HTMLElement;\n\n  /**\n   * Returns default UI styles.\n   */\n  public static get defaultSettings(): IStyleSettings {\n    return {\n      canvasBackgroundColor: '#ffffff',\n      toolbarBackgroundColor: '#111111',\n      toolbarBackgroundHoverColor: '#333333',\n      toolbarColor: '#eeeeee',\n      toolbarHeight: 40,\n      // toolboxBackgroundColor: '#2a2a2a',\n      toolboxColor: '#eeeeee',\n      toolboxAccentColor: '#3080c3',\n      undoButtonVisible: true,\n      redoButtonVisible: false,\n      zoomButtonVisible: false,\n      zoomOutButtonVisible: false,\n      clearButtonVisible: false,\n      resultButtonBlockVisible: true,\n      logoPosition: 'left',\n    };\n  }\n\n  /**\n   * Holds current UI styles.\n   */\n  public static settings: IStyleSettings = Style.defaultSettings;\n\n  /**\n   * Returns global fade-in animation class name.\n   */\n  public static get fadeInAnimationClassName(): string {\n    return `${Style.CLASS_PREFIX}fade_in`;\n  }\n  /**\n   * Returns global fade-out animation class name.\n   */\n  public static get fadeOutAnimationClassName(): string {\n    return `${Style.CLASS_PREFIX}fade_out`;\n  }\n\n  /**\n   * Adds a CSS class declaration.\n   * @param styleClass - class to add.\n   */\n  public static addClass(styleClass: StyleClass): StyleClass {\n    if (Style.styleSheet === undefined) {\n      Style.addStyleSheet();\n    }\n    Style.classes.push(styleClass);\n    // Style.styleSheet.sheet.addRule('.' + styleClass.name, styleClass.style);\n    Style.styleSheet.sheet.insertRule(\n      `.${styleClass.name} {${styleClass.style}}`,\n      Style.styleSheet.sheet.cssRules.length\n    );\n    return styleClass;\n  }\n\n  /**\n   * Add arbitrary CSS rule\n   * @param styleRule - CSS rule to add.\n   */\n  public static addRule(styleRule: StyleRule): void {\n    if (Style.styleSheet === undefined) {\n      Style.addStyleSheet();\n    }\n    Style.rules.push(styleRule);\n    // Style.styleSheet.sheet.addRule(styleRule.selector, styleRule.style); // crashes in Edge\n    Style.styleSheet.sheet.insertRule(\n      `${styleRule.selector} {${styleRule.style}}`,\n      Style.styleSheet.sheet.cssRules.length\n    );\n  }\n\n  private static addStyleSheet() {\n    Style.styleSheet = document.createElement('style');\n    (Style.styleSheetRoot ?? document.head).appendChild(Style.styleSheet);\n\n    // add global rules\n    Style.addRule(\n      new StyleRule(`.${Style.CLASS_PREFIX} h3`, 'font-family: sans-serif')\n    );\n\n    Style.addRule(\n      new StyleRule(\n        `@keyframes ${Style.CLASS_PREFIX}_fade_in_animation_frames`,\n        `\n        from {\n          opacity: 0;\n        }\n        to {\n          opacity: 1;\n        }\n    `\n      )\n    );\n    Style.addRule(\n      new StyleRule(\n        `@keyframes ${Style.CLASS_PREFIX}_fade_out_animation_frames`,\n        `\n        from {\n          opacity: 1;\n        }\n        to {\n          opacity: 0;\n        }\n    `\n      )\n    );\n\n    Style.addClass(\n      new StyleClass(\n        'fade_in',\n        `\n      animation-duration: 0.3s;\n      animation-name: ${Style.CLASS_PREFIX}_fade_in_animation_frames;\n    `\n      )\n    );\n    Style.addClass(\n      new StyleClass(\n        'fade_out',\n        `\n      animation-duration: 0.3s;\n      animation-name: ${Style.CLASS_PREFIX}_fade_out_animation_frames;\n    `\n      )\n    );\n  }\n\n  public static removeStyleSheet(): void {\n    if (Style.styleSheet) {\n      (Style.styleSheetRoot ?? document.head).removeChild(Style.styleSheet);\n      Style.styleSheet = undefined;\n    }\n  }\n}\n\n/**\n * Represents an arbitrary CSS rule.\n */\nexport class StyleRule {\n  /**\n   * CSS selector.\n   */\n  public selector: string;\n  /**\n   * Style declaration for the rule.\n   */\n  public style: string;\n  /**\n   * Creates an arbitrary CSS rule using the selector and style rules.\n   * @param selector - CSS selector\n   * @param style - styles to apply\n   */\n  constructor(selector: string, style: string) {\n    this.selector = selector;\n    this.style = style;\n  }\n}\n\n/**\n * Represents a CSS class.\n */\nexport class StyleClass {\n  /**\n   * CSS style rules for the class.\n   */\n  public style: string;\n\n  private _localName: string;\n  /**\n   * Returns fully qualified CSS class name.\n   */\n  public get name(): string {\n    return `${Style.CLASS_PREFIX}${this._localName}`;\n  }\n\n  /**\n   * Creates a CSS class declaration based on supplied (local) name and style rules.\n   * @param name - local CSS class name (will be prefixed with the marker.js prefix).\n   * @param style - style declarations.\n   */\n  constructor(name: string, style: string) {\n    this._localName = name;\n    this.style = style;\n  }\n}\n","import { MarkerBase } from './../core/MarkerBase';\nimport { Style, StyleClass, StyleRule } from './../core/Style';\n\nimport CursorIcon from './toolbar-core-icons/cursor.svg';\nimport DeleteIcon from './toolbar-core-icons/delete.svg';\nimport ClearIcon from './toolbar-core-icons/clear.svg';\nimport CheckIcon from './toolbar-core-icons/check.svg';\nimport CloseIcon from './toolbar-core-icons/close.svg';\nimport OverflowIcon from './toolbar-core-icons/overflow.svg';\nimport UndoIcon from './toolbar-core-icons/undo.svg';\nimport RedoIcon from './toolbar-core-icons/redo.svg';\nimport NotesIcon from './toolbar-core-icons/notes.svg';\nimport ZoomIcon from './toolbar-core-icons/zoom.svg';\nimport ZoomOutIcon from './toolbar-core-icons/zoom-out.svg';\nimport { IStyleSettings } from '../core/IStyleSettings';\nimport { DisplayMode } from '../core/Settings';\n\n/**\n * Toolbar button type:\n * - `action` for non-marker buttons like select, delete, etc.\n * - `marker` for marker type buttons.\n */\nexport type ToolbarButtonType = 'action' | 'marker';\n\n/**\n * Click handler type for toolbar button click events.\n */\nexport type ToolbarButtonClickHandler = (\n  buttonType: ToolbarButtonType,\n  value?: typeof MarkerBase | string\n) => void;\n\n/**\n * Toolbar represents the main toolbar of the marker.js 2 interface.\n */\nexport class Toolbar {\n  private markerItems: typeof MarkerBase[];\n\n  private buttons: HTMLDivElement[] = [];\n  private markerButtons: HTMLDivElement[] = [];\n  private overflowButton: HTMLDivElement;\n\n  private markerjsContainer: HTMLDivElement;\n  private displayMode: DisplayMode;\n  private uiContainer: HTMLDivElement;\n\n  private toolbarStyleClass: StyleClass;\n  private toolbarStyleColorsClass: StyleClass;\n  private toolbarBlockStyleClass: StyleClass;\n  private toolbarOverflowBlockStyleClass: StyleClass;\n  private toolbarOverflowBlockStyleColorsClass: StyleClass;\n  private toolbarButtonStyleClass: StyleClass;\n  private toolbarButtonStyleColorsClass: StyleClass;\n  private toolbarActiveButtonStyleColorsClass: StyleClass;\n\n  private markerButtonBlock: HTMLDivElement;\n  private markerButtonOverflowBlock: HTMLDivElement;\n\n  private buttonClickListeners: ToolbarButtonClickHandler[] = [];\n\n  private uiStyleSettings: IStyleSettings;\n\n  private currentMarker?: MarkerBase;\n\n  /**\n   * Creates the main marker.js toolbar.\n   * @param markerjsContainer - container for the toolbar in the marker.js UI.\n   * @param displayMode - marker.js display mode (`inline` or `popup`).\n   * @param markerItems - available marker types.\n   * @param uiStyleSettings - settings for styling the tooblar ui.\n   */\n  constructor(\n    markerjsContainer: HTMLDivElement,\n    displayMode: DisplayMode,\n    markerItems: typeof MarkerBase[],\n    uiStyleSettings: IStyleSettings\n  ) {\n    this.markerjsContainer = markerjsContainer;\n    this.displayMode = displayMode;\n    this.markerItems = markerItems;\n    this.uiStyleSettings = uiStyleSettings;\n    this.addStyles();\n\n    this.adjustLayout = this.adjustLayout.bind(this);\n    this.overflowButtonClicked = this.overflowButtonClicked.bind(this);\n    this.setCurrentMarker = this.setCurrentMarker.bind(this);\n  }\n\n  /**\n   * Creates and displays the toolbar UI.\n   */\n  public show(visiblity: string): void {\n    this.uiContainer = document.createElement('div');\n    this.uiContainer.style.visibility = visiblity;\n    this.uiContainer.className = `${this.toolbarStyleClass.name} ${\n      Style.fadeInAnimationClassName\n    } ${\n      this.uiStyleSettings.toolbarStyleColorsClassName\n        ? this.uiStyleSettings.toolbarStyleColorsClassName\n        : this.toolbarStyleColorsClass.name\n    }`;\n\n    const actionButtonBlock = document.createElement('div');\n    actionButtonBlock.className = this.toolbarBlockStyleClass.name;\n    actionButtonBlock.style.whiteSpace = 'nowrap';\n    this.uiContainer.appendChild(actionButtonBlock);\n\n    this.addActionButton(actionButtonBlock, CursorIcon, 'select');\n    this.addActionButton(actionButtonBlock, DeleteIcon, 'delete');\n    if (this.uiStyleSettings.clearButtonVisible) {\n      this.addActionButton(actionButtonBlock, ClearIcon, 'clear');\n    }\n    if (this.uiStyleSettings.undoButtonVisible) {\n      this.addActionButton(actionButtonBlock, UndoIcon, 'undo');\n    }\n    if (this.uiStyleSettings.redoButtonVisible) {\n      this.addActionButton(actionButtonBlock, RedoIcon, 'redo');\n    }\n    if (this.uiStyleSettings.zoomButtonVisible) {\n      this.addActionButton(actionButtonBlock, ZoomIcon, 'zoom');\n    }\n    if (\n      this.uiStyleSettings.zoomButtonVisible &&\n      this.uiStyleSettings.zoomOutButtonVisible\n    ) {\n      this.addActionButton(actionButtonBlock, ZoomOutIcon, 'zoom-out');\n    }\n    if (this.uiStyleSettings.notesButtonVisible) {\n      this.addActionButton(actionButtonBlock, NotesIcon, 'notes');\n    }\n\n    this.markerButtonBlock = document.createElement('div');\n    this.markerButtonBlock.className = this.toolbarBlockStyleClass.name;\n    this.markerButtonBlock.style.flexGrow = '2';\n    this.markerButtonBlock.style.textAlign = 'center';\n    this.uiContainer.appendChild(this.markerButtonBlock);\n\n    this.markerButtonOverflowBlock = document.createElement('div');\n    this.markerButtonOverflowBlock.className = `${\n      this.toolbarOverflowBlockStyleClass.name\n    } ${\n      this.uiStyleSettings.toolbarOverflowBlockStyleColorsClassName\n        ? this.uiStyleSettings.toolbarOverflowBlockStyleColorsClassName\n        : this.toolbarOverflowBlockStyleColorsClass.name\n    }`;\n    this.markerButtonOverflowBlock.style.display = 'none';\n    this.uiContainer.appendChild(this.markerButtonOverflowBlock);\n\n    if (this.markerItems) {\n      this.markerItems.forEach((mi) => {\n        const buttonContainer = document.createElement('div');\n        buttonContainer.className = `${this.toolbarButtonStyleClass.name}`;\n        buttonContainer.setAttribute('data-type-name', mi.typeName);\n        //  ${\n        //   this.uiStyleSettings.toolbarButtonStyleColorsClassName ?\n        //   this.uiStyleSettings.toolbarButtonStyleColorsClassName : this.toolbarButtonStyleColorsClass.name}`;\n        buttonContainer.innerHTML = mi.icon;\n        buttonContainer.addEventListener('click', () => {\n          this.markerToolbarButtonClicked(buttonContainer, mi);\n        });\n        //this.markerButtonBlock.appendChild(buttonContainer);\n        this.buttons.push(buttonContainer);\n        this.markerButtons.push(buttonContainer);\n      });\n      this.overflowButton = document.createElement('div');\n      this.overflowButton.className = `${this.toolbarButtonStyleClass.name} ${\n        this.uiStyleSettings.toolbarButtonStyleColorsClassName\n          ? this.uiStyleSettings.toolbarButtonStyleColorsClassName\n          : this.toolbarButtonStyleColorsClass.name\n      }`;\n      this.overflowButton.innerHTML = OverflowIcon;\n      this.overflowButton.addEventListener('click', this.overflowButtonClicked);\n      this.markerButtonBlock.appendChild(this.overflowButton);\n    }\n\n    const resultButtonBlock = document.createElement('div');\n    resultButtonBlock.className = this.toolbarBlockStyleClass.name;\n    resultButtonBlock.style.whiteSpace = 'nowrap';\n    resultButtonBlock.style.display =\n      this.uiStyleSettings.resultButtonBlockVisible !== false ? '' : 'none';\n    this.uiContainer.appendChild(resultButtonBlock);\n\n    this.addActionButton(resultButtonBlock, CheckIcon, 'render');\n    this.addActionButton(resultButtonBlock, CloseIcon, 'close');\n\n    this.markerjsContainer.appendChild(this.uiContainer);\n    this.setSelectMode();\n\n    this.setCurrentMarker();\n\n    this.adjustLayout();\n    // setTimeout(this.adjustLayout, 10);\n  }\n\n  /**\n   * Add a listener to the toolbar button click event.\n   * @param listener\n   */\n  public addButtonClickListener(listener: ToolbarButtonClickHandler): void {\n    this.buttonClickListeners.push(listener);\n  }\n\n  /**\n   * Remove a listener for the toolbar button click event.\n   * @param listener\n   */\n  public removeButtonClickListener(listener: ToolbarButtonClickHandler): void {\n    if (this.buttonClickListeners.indexOf(listener) > -1) {\n      this.buttonClickListeners.splice(\n        this.buttonClickListeners.indexOf(listener),\n        1\n      );\n    }\n  }\n\n  /**\n   * Switch toolbar to the `select` mode.\n   */\n  public setSelectMode(): void {\n    this.resetButtonStyles();\n    this.setActiveButton(this.buttons[0]);\n  }\n\n  /**\n   * Adjusts toolbar layout.\n   */\n  public adjustLayout(): void {\n    if (this.markerButtons && this.markerButtons.length > 0) {\n      const numberToFit =\n        Math.floor(\n          this.markerButtonBlock.clientWidth /\n            this.uiStyleSettings.toolbarHeight\n        ) - 1;\n      this.markerButtonBlock.innerHTML = '';\n      this.markerButtonOverflowBlock.innerHTML = '';\n      for (\n        let buttonIndex = 0;\n        buttonIndex < this.markerButtons.length;\n        buttonIndex++\n      ) {\n        if (\n          buttonIndex < numberToFit ||\n          (buttonIndex === numberToFit &&\n            this.markerButtons.length - 1 === numberToFit)\n        ) {\n          this.markerButtonBlock.appendChild(this.markerButtons[buttonIndex]);\n        } else {\n          if (buttonIndex === numberToFit) {\n            this.markerButtonBlock.appendChild(this.overflowButton);\n          }\n          this.markerButtonOverflowBlock.appendChild(\n            this.markerButtons[buttonIndex]\n          );\n        }\n      }\n    }\n  }\n\n  private overflowButtonClicked() {\n    if (this.markerButtonOverflowBlock.style.display !== 'none') {\n      this.markerButtonOverflowBlock.className = this.markerButtonOverflowBlock.className.replace(\n        Style.fadeInAnimationClassName,\n        ''\n      );\n      this.markerButtonOverflowBlock.style.display = 'none';\n    } else {\n      this.markerButtonOverflowBlock.className += ` ${Style.fadeInAnimationClassName}`;\n      this.markerButtonOverflowBlock.style.top = `${\n        this.uiContainer.offsetTop + this.overflowButton.offsetHeight\n      }px`;\n      this.markerButtonOverflowBlock.style.right = `${\n        this.uiContainer.offsetWidth -\n        this.overflowButton.offsetLeft -\n        this.overflowButton.offsetWidth +\n        this.uiContainer.offsetLeft * 2\n      }px`;\n      this.markerButtonOverflowBlock.style.display = 'inline-block';\n    }\n  }\n\n  private resetButtonStyles() {\n    this.buttons.forEach((button) => {\n      button.className = button.className\n        .replace(\n          this.uiStyleSettings.toolbarButtonStyleColorsClassName\n            ? this.uiStyleSettings.toolbarButtonStyleColorsClassName\n            : this.toolbarButtonStyleColorsClass.name,\n          ''\n        )\n        .trim();\n      button.className = button.className\n        .replace(\n          this.uiStyleSettings.toolbarActiveButtonStyleColorsClassName\n            ? this.uiStyleSettings.toolbarActiveButtonStyleColorsClassName\n            : this.toolbarActiveButtonStyleColorsClass.name,\n          ''\n        )\n        .trim();\n      button.className += ` ${\n        this.uiStyleSettings.toolbarButtonStyleColorsClassName\n          ? this.uiStyleSettings.toolbarButtonStyleColorsClassName\n          : this.toolbarButtonStyleColorsClass.name\n      }`;\n    });\n  }\n\n  private addActionButton(\n    container: HTMLDivElement,\n    icon: string,\n    value: string\n  ) {\n    const actionButton = document.createElement('div');\n    actionButton.className = `${this.toolbarButtonStyleClass.name}`;\n    //  ${\n    //   this.uiStyleSettings.toolbarButtonStyleColorsClassName ?\n    //   this.uiStyleSettings.toolbarButtonStyleColorsClassName : this.toolbarButtonStyleColorsClass.name}`;\n    actionButton.innerHTML = icon;\n    actionButton.setAttribute('data-action', value);\n    actionButton.addEventListener('click', () => {\n      this.actionToolbarButtonClicked(actionButton, value);\n    });\n    switch (value) {\n      case 'select':\n        actionButton.style.fill = this.uiStyleSettings.selectButtonColor;\n        break;\n      case 'delete':\n      case 'clear':\n        actionButton.style.fill = this.uiStyleSettings.deleteButtonColor;\n        break;\n      case 'undo':\n        actionButton.style.fill = this.uiStyleSettings.selectButtonColor;\n        break;\n      case 'redo':\n        actionButton.style.fill = this.uiStyleSettings.selectButtonColor;\n        break;\n      case 'render':\n        actionButton.style.fill = this.uiStyleSettings.okButtonColor;\n        break;\n      case 'close':\n        actionButton.style.fill = this.uiStyleSettings.closeButtonColor;\n        break;\n    }\n\n    container.appendChild(actionButton);\n    this.buttons.push(actionButton);\n  }\n\n  private addStyles() {\n    this.toolbarStyleClass = Style.addClass(\n      new StyleClass(\n        'toolbar',\n        `\n      width: 100%;\n      flex-shrink: 0;\n      display: flex;\n      flex-direction: row;\n      justify-content: space-between;      \n      height: ${this.uiStyleSettings.toolbarHeight}px;\n      box-sizing: content-box;\n      ${\n        this.displayMode === 'inline'\n          ? `border-top-left-radius: ${Math.round(\n              this.uiStyleSettings.toolbarHeight / 10\n            )}px;`\n          : ''\n      }\n      ${\n        this.displayMode === 'inline'\n          ? `border-top-right-radius: ${Math.round(\n              this.uiStyleSettings.toolbarHeight / 10\n            )}px;`\n          : ''\n      }\n      overflow: hidden;\n    `\n      )\n    );\n\n    this.toolbarStyleColorsClass = Style.addClass(\n      new StyleClass(\n        'toolbar_colors',\n        `\n      background-color: ${this.uiStyleSettings.toolbarBackgroundColor};\n      box-shadow: 0px 3px rgba(33, 33, 33, 0.1);\n    `\n      )\n    );\n\n    this.toolbarBlockStyleClass = Style.addClass(\n      new StyleClass(\n        'toolbar-block',\n        `\n        display: inline-block;\n        box-sizing: content-box;\n    `\n      )\n    );\n\n    this.toolbarOverflowBlockStyleClass = Style.addClass(\n      new StyleClass(\n        'toolbar-overflow-block',\n        `\n        position: absolute;\n        top: ${this.uiStyleSettings.toolbarHeight}px;\n        max-width: ${this.uiStyleSettings.toolbarHeight * 2}px;\n        z-index: 10;\n        box-sizing: content-box;\n      `\n      )\n    );\n    this.toolbarOverflowBlockStyleColorsClass = Style.addClass(\n      new StyleClass(\n        'toolbar-overflow-block_colors',\n        `\n        background-color: ${this.uiStyleSettings.toolbarBackgroundColor};\n      `\n      )\n    );\n\n    const buttonPadding = this.uiStyleSettings.toolbarHeight / 4;\n    this.toolbarButtonStyleClass = Style.addClass(\n      new StyleClass(\n        'toolbar_button',\n        `\n      display: inline-block;\n      width: ${this.uiStyleSettings.toolbarHeight - buttonPadding * 2}px;\n      height: ${this.uiStyleSettings.toolbarHeight - buttonPadding * 2}px;\n      padding: ${buttonPadding}px;\n      box-sizing: content-box;\n    `\n      )\n    );\n    this.toolbarButtonStyleColorsClass = Style.addClass(\n      new StyleClass(\n        'toolbar_button_colors',\n        `\n      fill: ${this.uiStyleSettings.toolbarColor};\n    `\n      )\n    );\n\n    this.toolbarActiveButtonStyleColorsClass = Style.addClass(\n      new StyleClass(\n        'toolbar_active_button',\n        `\n      fill: ${this.uiStyleSettings.toolbarColor};\n      background-color: ${this.uiStyleSettings.toolbarBackgroundHoverColor}\n    `\n      )\n    );\n\n    Style.addRule(\n      new StyleRule(\n        `.${this.toolbarButtonStyleClass.name} svg`,\n        `\n      height: ${this.uiStyleSettings.toolbarHeight / 2}px;\n    `\n      )\n    );\n\n    Style.addRule(\n      new StyleRule(\n        `.${this.toolbarButtonStyleColorsClass.name}:hover`,\n        `\n        background-color: ${this.uiStyleSettings.toolbarBackgroundHoverColor}\n    `\n      )\n    );\n  }\n\n  private markerToolbarButtonClicked(\n    button: HTMLDivElement,\n    markerType: typeof MarkerBase\n  ) {\n    this.setActiveButton(button);\n    if (this.buttonClickListeners && this.buttonClickListeners.length > 0) {\n      this.buttonClickListeners.forEach((listener) =>\n        listener('marker', markerType)\n      );\n    }\n    this.markerButtonOverflowBlock.style.display = 'none';\n  }\n\n  private actionToolbarButtonClicked(button: HTMLDivElement, action: string) {\n    if (this.buttonClickListeners && this.buttonClickListeners.length > 0) {\n      this.buttonClickListeners.forEach((listener) =>\n        listener('action', action)\n      );\n    }\n    this.markerButtonOverflowBlock.style.display = 'none';\n    this.setActiveButton(this.buttons[0]);\n  }\n\n  private setActiveButton(button: HTMLDivElement) {\n    this.resetButtonStyles();\n    button.className = button.className\n      .replace(\n        this.uiStyleSettings.toolbarButtonStyleColorsClassName\n          ? this.uiStyleSettings.toolbarButtonStyleColorsClassName\n          : this.toolbarButtonStyleColorsClass.name,\n        ''\n      )\n      .trim();\n    button.className += ` ${\n      this.uiStyleSettings.toolbarActiveButtonStyleColorsClassName\n        ? this.uiStyleSettings.toolbarActiveButtonStyleColorsClassName\n        : this.toolbarActiveButtonStyleColorsClass.name\n    }`;\n  }\n\n  /**\n   * Selects toolbar button for a specified marker type.\n   * @param typeName Marker type name\n   *\n   * @since 2.17.0\n   */\n  public setActiveMarkerButton(typeName: string): void {\n    const activeBtn = this.markerButtons.find(\n      (btn) => btn.getAttribute('data-type-name') === typeName\n    );\n    if (activeBtn) {\n      this.setActiveButton(activeBtn);\n    }\n  }\n\n  /**\n   * Sets current marker and enables/disables action buttons accordingly.\n   * @param marker\n   */\n  public setCurrentMarker(marker?: MarkerBase): void {\n    this.currentMarker = marker;\n    const activeMarkerButtons = this.buttons.filter((btn) =>\n      /delete|notes/.test(btn.getAttribute('data-action'))\n    );\n    activeMarkerButtons.forEach((btn) => {\n      if (this.currentMarker === undefined) {\n        btn.style.fillOpacity = '0.4';\n        btn.style.pointerEvents = 'none';\n      } else {\n        btn.style.fillOpacity = '1';\n        btn.style.pointerEvents = 'all';\n      }\n    });\n  }\n}\n","import { ToolboxPanel } from './ToolboxPanel';\nimport { Style, StyleClass, StyleRule } from './../core/Style';\nimport { DisplayMode } from '../core/Settings';\nimport { IStyleSettings } from '../core/IStyleSettings';\n\n/**\n * Represents the contextual toolbox for the selected marker type.\n */\nexport class Toolbox {\n  private panels: ToolboxPanel[] = [];\n  private activePanel: ToolboxPanel;\n  private panelButtons: HTMLDivElement[] = [];\n\n  private markerjsContainer: HTMLDivElement;\n  private displayMode: DisplayMode;\n  private uiContainer: HTMLDivElement;\n  private buttonRow: HTMLDivElement;\n  private panelRow: HTMLDivElement;\n\n  private toolboxStyleClass: StyleClass;\n  private toolboxStyleColorsClass: StyleClass;\n  private toolboxButtonStyleClass: StyleClass;\n  private toolboxButtonStyleColorsClass: StyleClass;\n  private toolboxActiveButtonStyleColorsClass: StyleClass;\n  private toolboxButtonRowStyleClass: StyleClass;\n  private toolboxButtonRowStyleColorsClass: StyleClass;\n  private toolboxPanelRowStyleClass: StyleClass;\n  private toolboxPanelRowStyleColorsClass: StyleClass;\n\n  private uiStyleSettings: IStyleSettings;\n  \n  private addStyles() {\n    this.toolboxStyleClass = Style.addClass(\n      new StyleClass(\n        'toolbox',\n        `\n      width: 100%;\n      flex-shrink: 0;\n      display: flex;\n      flex-direction: column;\n      font-family: sans-serif;\n      ${this.displayMode === 'popup' ? 'height:' + this.uiStyleSettings.toolbarHeight * 2.5 + 'px;' : ''}\n      box-sizing: content-box;\n      ${this.displayMode === 'popup' ? `background-color: ${this.uiStyleSettings.canvasBackgroundColor};` : ''}\n      ${this.displayMode === 'inline' ? `border-bottom-left-radius: ${Math.round(this.uiStyleSettings.toolbarHeight/10)}px;` : ''}\n      ${this.displayMode === 'inline' ? `border-bottom-right-radius: ${Math.round(this.uiStyleSettings.toolbarHeight/10)}px;` : ''}\n      overflow: hidden;\n    `\n      )\n    );\n    this.toolboxStyleColorsClass = Style.addClass(\n      new StyleClass(\n        'toolbox_colors',\n        `\n      color: ${this.uiStyleSettings.toolboxColor};\n    `\n      )\n    );\n\n    const buttonPadding = this.uiStyleSettings.toolbarHeight / 4;\n    this.toolboxButtonRowStyleClass = Style.addClass(new StyleClass('toolbox-button-row', `\n      display: flex;\n      cursor: default;\n      box-sizing: content-box;\n    `));\n    this.toolboxButtonRowStyleColorsClass = Style.addClass(new StyleClass('toolbox-button-row_colors', `\n      background-color: ${this.uiStyleSettings.toolbarBackgroundColor};\n    `));\n\n    this.toolboxPanelRowStyleClass = Style.addClass(new StyleClass('toolbox-panel-row', `\n      display: flex;\n      ${this.displayMode === 'inline' ? 'position: absolute;' : '' }\n      ${this.displayMode === 'inline' ? 'bottom: ' + this.uiStyleSettings.toolbarHeight + 'px;' : '' }\n      cursor: default;\n      height: ${this.uiStyleSettings.toolbarHeight * 1.5}px;\n      ${this.displayMode === 'inline' ? 'width: 100%;' : ''}\n      box-sizing: content-box;\n    `));\n    this.toolboxPanelRowStyleColorsClass = Style.addClass(new StyleClass('toolbox-panel-row_colors', `\n      background-color: ${this.uiStyleSettings.toolboxBackgroundColor ?? this.uiStyleSettings.toolbarBackgroundHoverColor};\n    `));\n\n    this.toolboxButtonStyleClass = Style.addClass(new StyleClass('toolbox_button', `\n      display: inline-block;\n      width: ${this.uiStyleSettings.toolbarHeight - buttonPadding * 2}px;\n      height: ${this.uiStyleSettings.toolbarHeight - buttonPadding * 2}px;\n      padding: ${buttonPadding}px;\n      box-sizing: content-box;\n    `));\n    this.toolboxButtonStyleColorsClass = Style.addClass(new StyleClass('toolbox-button_colors', `\n      fill: ${this.uiStyleSettings.toolbarColor};\n    `));\n\n    this.toolboxActiveButtonStyleColorsClass = Style.addClass(new StyleClass('toolbox-active-button_colors', `\n      background-color: ${this.uiStyleSettings.toolbarBackgroundHoverColor};\n      fill: ${this.uiStyleSettings.toolbarColor};\n    `));\n\n    Style.addRule(\n      new StyleRule(\n        `.${this.toolboxButtonStyleColorsClass.name}:hover`,\n        `\n        background-color: ${this.uiStyleSettings.toolbarBackgroundHoverColor}\n    `\n      )\n    );\n\n    Style.addRule(\n      new StyleRule(\n        `.${this.toolboxButtonStyleClass.name} svg`,\n        `\n      height: ${this.uiStyleSettings.toolbarHeight / 2}px;\n    `\n      )\n    );\n\n  }\n\n  /**\n   * Creates the toolbox object\n   * @param markerjsContainer - container for the toolbox in marker.js UI.\n   * @param displayMode - marker.js display mode (`inline` or `popup`).\n   * @param uiStyleSettings - settings for styling the toolbox elements.\n   */\n  constructor(markerjsContainer: HTMLDivElement, displayMode: DisplayMode, uiStyleSettings: IStyleSettings) {\n    this.markerjsContainer = markerjsContainer;\n    this.displayMode = displayMode;\n    this.uiStyleSettings = uiStyleSettings;\n\n    this.panelButtonClick = this.panelButtonClick.bind(this);\n\n    this.addStyles();\n  }\n\n  /**\n   * Creates and displays the main toolbox UI.\n   */\n  public show(visiblity: string): void {\n    this.uiContainer = document.createElement('div');\n    this.uiContainer.style.visibility = visiblity;\n    this.uiContainer.className = `${this.toolboxStyleClass.name} ${\n      this.uiStyleSettings.toolboxStyleColorsClassName ?? this.toolboxStyleColorsClass.name}`;\n\n    this.markerjsContainer.appendChild(this.uiContainer);\n  }\n\n  /**\n   * Creaes buttons for the top-level toolbox panel.\n   * @param panels - available panels.\n   */\n  public setPanelButtons(panels: ToolboxPanel[]): void {\n    this.panels = panels;\n    if (this.uiContainer !== undefined) {\n      this.uiContainer.innerHTML = '';\n\n      this.panelRow = document.createElement('div');\n      this.panelRow.className = `${this.toolboxPanelRowStyleClass.name} ${\n        this.uiStyleSettings.toolboxPanelRowStyleColorsClassName ?? this.toolboxPanelRowStyleColorsClass.name}`;\n      this.uiContainer.appendChild(this.panelRow);\n      this.buttonRow = document.createElement('div');\n      this.buttonRow.className = `${this.toolboxButtonRowStyleClass.name} ${\n        this.uiStyleSettings.toolboxButtonRowStyleColorsClassName ?? this.toolboxButtonRowStyleColorsClass.name} `;\n      this.uiContainer.appendChild(this.buttonRow);\n\n      this.panelButtons.splice(0);\n\n      this.panels.forEach(panel => {\n        const panelBtnDiv = document.createElement('div');\n        panelBtnDiv.className = `${this.toolboxButtonStyleClass.name} ${\n          this.uiStyleSettings.toolboxButtonStyleColorsClassName ?? this.toolboxButtonStyleColorsClass.name}`;\n        panelBtnDiv.innerHTML = panel.icon;\n        panelBtnDiv.title = panel.title;\n        panelBtnDiv.addEventListener('click', () => {\n          this.panelButtonClick(panel);\n        })\n        this.panelButtons.push(panelBtnDiv);\n        this.buttonRow.appendChild(panelBtnDiv);\n      });\n      if (this.displayMode === 'inline') {\n        this.panelRow.style.display = 'none';\n      } else {\n        this.panelRow.style.visibility = 'hidden';\n      }\n    }\n    // if (this.displayMode === 'popup' && this.panels.length > 0) {\n    //   // this.showPanel(this.activePanel ? this.activePanel : this.panels[0]);\n    //   this.panelButtonClick(this.panels[0]);\n    // }\n  }\n\n  private panelButtonClick(panel: ToolboxPanel) {\n    let panelIndex = -1; \n    if (panel !== this.activePanel) {\n      panelIndex = this.panels.indexOf(panel);\n      this.panelRow.innerHTML = '';\n      const panelUI = panel.getUi();\n      panelUI.style.margin = `${this.uiStyleSettings.toolbarHeight / 4}px`;\n      this.panelRow.appendChild(panelUI);\n      this.panelRow.style.display = 'flex';\n      this.panelRow.style.visibility = 'visible';\n      this.panelRow.className = this.panelRow.className.replace(Style.fadeOutAnimationClassName, '');\n      this.panelRow.className += ` ${Style.fadeInAnimationClassName}`;\n      this.activePanel = panel;\n    } else {\n      this.activePanel = undefined;\n      // hide panel\n      this.panelRow.className = this.panelRow.className.replace(Style.fadeInAnimationClassName, '');\n      this.panelRow.className += ` ${Style.fadeOutAnimationClassName}`;\n      setTimeout(() => {\n        if (this.displayMode === 'inline') {\n          this.panelRow.style.display = 'none';\n        } else {\n          this.panelRow.style.visibility = 'hidden';\n        }\n      }, 200);\n    }\n    this.panelButtons.forEach((pb, index) => {\n      pb.className = `${this.toolboxButtonStyleClass.name} ` +\n        (index === panelIndex\n          ? `${this.uiStyleSettings.toolboxActiveButtonStyleColorsClassName ?? this.toolboxActiveButtonStyleColorsClass.name}`\n          :  `${this.uiStyleSettings.toolboxButtonStyleColorsClassName ?? this.toolboxButtonStyleColorsClass.name}`);\n    });\n  }\n\n}\n","/**\n * Base class for all toolbox property panels.\n */\nexport abstract class ToolboxPanel {\n  /**\n   * Panel name/title.\n   */\n  public title: string;\n  /**\n   * Panel button icon as an SVG markup.\n   */\n  public icon: string;\n  /**\n   * Create panel with supplied title and icon.\n   * @param title - panel name (used for accessibility)\n   * @param icon - panel button icon (SVG image markup)\n   */\n  constructor(title: string, icon?: string) {\n    this.title = title;\n    this.icon = icon;\n  }\n  /**\n   * Returns toolbox panel UI.\n   */\n  public abstract getUi(): HTMLDivElement;\n}\n","import { Style } from '../../core/Style';\nimport { ToolboxPanel } from '../ToolboxPanel';\nimport Icon from './color-picker-panel-icon.svg';\n\n/**\n * Handler type for the color change event.\n */\nexport type ColorChangeHandler = (newColor: string) => void;\n\n/**\n * Color picker panel.\n */\nexport class ColorPickerPanel extends ToolboxPanel {\n  public colors: string[] = [];\n  private currentColor?: string;\n  private addTransparent = false;\n\n  private colorBoxes: HTMLDivElement[] = [];\n\n  /**\n   * Color change event handler.\n   */\n  public onColorChanged?: ColorChangeHandler;\n\n  /**\n   * Creates a color picker panel.\n   * @param title - panel title.\n   * @param colors - available colors.\n   * @param currentColor - currently selected color.\n   * @param icon - panel button icon (SVG imager markup).\n   */\n  constructor(title: string, colors: string[], currentColor?: string, icon?: string) {\n    super(title, icon ? icon : Icon);\n    this.colors = colors;\n    this.currentColor = currentColor;\n\n    this.setCurrentColor = this.setCurrentColor.bind(this);\n    this.getColorBox = this.getColorBox.bind(this);\n  }\n\n  /**\n   * Returns panel UI.\n   */\n  public getUi(): HTMLDivElement {\n    const panelDiv = document.createElement('div');\n    panelDiv.style.overflow = 'hidden';\n    panelDiv.style.whiteSpace = 'nowrap';\n    this.colors.forEach((color) => {\n      const colorBoxContainer = this.getColorBox(color);\n      panelDiv.appendChild(colorBoxContainer);\n      this.colorBoxes.push(colorBoxContainer);\n    });\n    return panelDiv;\n  }\n\n  private getColorBox(color): HTMLDivElement {\n    const buttonPadding = Style.settings.toolbarHeight / 4;\n    const buttonHeight = Style.settings.toolbarHeight - buttonPadding;\n\n    const colorBoxContainer = document.createElement('div');\n    colorBoxContainer.style.display = 'inline-block';\n    colorBoxContainer.style.boxSizing = 'content-box';\n    colorBoxContainer.style.width = `${buttonHeight - 2}px`;\n    colorBoxContainer.style.height = `${buttonHeight - 2}px`;\n    colorBoxContainer.style.padding = '1px';\n    colorBoxContainer.style.marginRight = '2px';\n    colorBoxContainer.style.marginBottom = '2px';\n    colorBoxContainer.style.borderWidth = '2px';\n    colorBoxContainer.style.borderStyle = 'solid';\n    colorBoxContainer.style.borderRadius = `${(buttonHeight + 2)/2}px`\n    colorBoxContainer.style.borderColor =\n      color === this.currentColor ? Style.settings.toolboxAccentColor : 'transparent';\n\n    colorBoxContainer.addEventListener('click', () => {\n      this.setCurrentColor(color, colorBoxContainer);\n    })\n\n    const colorBox = document.createElement('div');\n    colorBox.style.display = 'inline-block';\n    colorBox.style.width = `${buttonHeight - 2}px`;\n    colorBox.style.height = `${buttonHeight - 2}px`;\n    colorBox.style.backgroundColor = color;\n    colorBox.style.borderRadius = `${buttonHeight/2}px`;\n    if (color === 'transparent') {\n      colorBox.style.fill = Style.settings.toolboxAccentColor;\n      colorBox.innerHTML = `<svg viewBox=\"0 0 24 24\">\n        <path d=\"M2,5.27L3.28,4L20,20.72L18.73,22L15.65,18.92C14.5,19.3 13.28,19.5 12,19.5C7,19.5 2.73,16.39 1,12C1.69,10.24 2.79,8.69 4.19,7.46L2,5.27M12,9A3,3 0 0,1 15,12C15,12.35 14.94,12.69 14.83,13L11,9.17C11.31,9.06 11.65,9 12,9M12,4.5C17,4.5 21.27,7.61 23,12C22.18,14.08 20.79,15.88 19,17.19L17.58,15.76C18.94,14.82 20.06,13.54 20.82,12C19.17,8.64 15.76,6.5 12,6.5C10.91,6.5 9.84,6.68 8.84,7L7.3,5.47C8.74,4.85 10.33,4.5 12,4.5M3.18,12C4.83,15.36 8.24,17.5 12,17.5C12.69,17.5 13.37,17.43 14,17.29L11.72,15C10.29,14.85 9.15,13.71 9,12.28L5.6,8.87C4.61,9.72 3.78,10.78 3.18,12Z\" />\n      </svg>`;\n    }\n\n    colorBoxContainer.appendChild(colorBox);\n\n    return colorBoxContainer;\n  }\n\n  private setCurrentColor(color: string, target: HTMLDivElement) {\n    this.currentColor = color;\n\n    this.colorBoxes.forEach(box => {\n      box.style.borderColor = box === target ? Style.settings.toolboxAccentColor : 'transparent';\n    });\n\n    if (this.onColorChanged) {\n      this.onColorChanged(color);\n    }\n  }\n}\n","import { IPoint } from './IPoint';\nimport { ToolboxPanel } from '../ui/ToolboxPanel';\nimport { MarkerBaseState, MarkerState } from './MarkerBaseState';\nimport { Settings } from './Settings';\n\n/**\n * Base class for all available and custom marker types.\n * \n * All markers used with marker.js 2 should be descendants of this class.\n */\nexport class MarkerBase {\n  /**\n   * String type name of the marker type. \n   * \n   * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static typeName = 'MarkerBase';\n\n  /**\n   * Instance property returning marker's type name.\n   * \n   * @since 2.16.0\n   */\n  public get typeName(): string {\n    return Object.getPrototypeOf(this).constructor.typeName;\n  }\n\n  protected _container: SVGGElement;\n  /**\n   * SVG container object holding the marker's visual.\n   */\n  public get container(): SVGGElement {\n    return this._container;\n  }\n  protected _overlayContainer: HTMLDivElement;\n  /**\n   * HTML container that can be used to render overlay objects while the marker is active.\n   * \n   * For example, this is used for the text editing layer while editing text in the {@see TextMarker}.\n   */\n  public get overlayContainer(): HTMLDivElement {\n    return this._overlayContainer;\n  }\n  protected _state: MarkerState = 'new';\n  /**\n   * Current marker state.\n   *\n   * Both MarkerArea and the marker itself can react differently to different events based on what state the marker is in.\n   */\n  public get state(): MarkerState {\n    return this._state;\n  }\n  protected globalSettings: Settings;\n\n  /**\n   * Additional information about the marker\n   */\n  public notes?: string;\n\n  /**\n   * Returns the list of toolbox panels for this marker type.\n   */\n  public get toolboxPanels(): ToolboxPanel[] {\n    return [];\n  }\n\n  /**\n   * Marker type title (display name) used for accessibility and other attributes.\n   */\n  public static title: string;\n\n  /**\n   * SVG icon markup displayed on toolbar buttons.\n   */\n  public static icon: string;\n\n  /**\n   * Method called when marker creation is finished.\n   */\n  public onMarkerCreated: (marker: MarkerBase) => void;\n\n  /**\n   * Method to call when foreground color changes.\n   */\n  public onColorChanged?: (color: string) => void;\n  /**\n   * Method to call when background/fill color changes.\n   */\n  public onFillColorChanged?: (color: string) => void;\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.\n   * @param settings - settings object containing default markers settings.\n   */\n  constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings) {\n    this._container = container;\n    this._overlayContainer = overlayContainer;\n    this.globalSettings = settings;\n  }\n\n  /**\n   * Returns true if passed SVG element belongs to the marker. False otherwise.\n   * \n   * @param el - target element.\n   */\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars\n  public ownsTarget(el: EventTarget): boolean {\n    return false;\n  }\n\n  /**\n   * Is this marker selected?\n   * \n   * @since 2.16.0\n   */\n  protected _isSelected = false;\n\n  /**\n   * Returns true if the marker is currently selected\n   * \n   * @since 2.16.0\n   */\n  public get isSelected(): boolean {\n    return this._isSelected;\n  }\n\n  /**\n   * Selects this marker and displays appropriate selected marker UI.\n   */\n  public select(): void {\n    this.container.style.cursor = 'move';\n    this._isSelected = true;\n  }\n\n  /**\n   * Deselects this marker and hides selected marker UI.\n   */\n  public deselect(): void {\n    this.container.style.cursor = 'default';\n    this._isSelected = false;\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) down event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function\n  public pointerDown(point: IPoint, target?: EventTarget):void {}\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) double click event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function\n  public dblClick(point: IPoint, target?: EventTarget):void {}\n\n  /**\n   * Handles marker manipulation (move, resize, rotate, etc.).\n   * \n   * @param point - event coordinates.\n   */\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function\n  public manipulate(point: IPoint):void {}\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) up event.\n   * \n   * @param point - event coordinates.\n   */\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function\n  public pointerUp(point: IPoint):void {}\n\n  /**\n   * Disposes the marker and clean's up.\n   */\n  // eslint-disable-next-line @typescript-eslint/no-empty-function\n  public dispose(): void {}\n\n  protected addMarkerVisualToContainer(element: SVGElement): void {\n    if (this.container.childNodes.length > 0) {\n      this.container.insertBefore(element, this.container.childNodes[0]);\n    } else {\n      this.container.appendChild(element);\n    }\n  }\n\n  /**\n   * Returns current marker state that can be restored in the future.\n   */\n  public getState(): MarkerBaseState {\n    return { \n      typeName: MarkerBase.typeName, \n      state: this.state,\n      notes: this.notes\n    };\n  }\n\n  /**\n   * Restores previously saved marker state.\n   * \n   * @param state - previously saved state.\n   */\n  public restoreState(state: MarkerBaseState): void {\n    this._state = state.state;\n    this.notes = state.notes;\n  }\n\n  /**\n   * Scales marker. Used after the image resize.\n   * \n   * @param scaleX - horizontal scale\n   * @param scaleY - vertical scale\n   */\n  // eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars\n  public scale(scaleX: number, scaleY: number): void {}\n\n  /**\n   * Called by a marker when its foreground color changes.\n   * @param color \n   */\n  protected colorChanged(color: string): void {\n    if (this.onColorChanged) {\n      this.onColorChanged(color);\n    }\n  }\n  /**\n   * Called by a marker when its background/fill color changes.\n   * @param color \n   */\n  protected fillColorChanged(color: string): void {\n    if (this.onFillColorChanged) {\n      this.onFillColorChanged(color);\n    }\n  }\n}\n","import { ResizeGrip } from './ResizeGrip';\n\n/**\n * RectangularBoxMarkerGrips is a set of resize/rotation grips for a rectangular marker.\n */\nexport class RectangularBoxMarkerGrips {\n  /**\n   * Top-left grip.\n   */\n  public topLeft: ResizeGrip;\n  /**\n   * Top-center grip.\n   */\n  public topCenter: ResizeGrip;\n  /**\n   * Top-right grip.\n   */\n  public topRight: ResizeGrip;\n  /**\n   * Center-left grip.\n   */\n  public centerLeft: ResizeGrip;\n  /**\n   * Center-right grip.\n   */\n  public centerRight: ResizeGrip;\n  /**\n   * Bottom-left grip.\n   */\n  public bottomLeft: ResizeGrip;\n  /**\n   * Bottom-center grip.\n   */\n  public bottomCenter: ResizeGrip;\n  /**\n   * Bottom-right grip.\n   */\n  public bottomRight: ResizeGrip;\n\n  /**\n   * Creates a new marker grip set.\n   */\n  constructor() {\n    this.findGripByVisual = this.findGripByVisual.bind(this);\n  }\n\n  /**\n   * Returns a marker grip owning the specified visual.\n   * @param gripVisual - visual for owner to be determined.\n   */\n  public findGripByVisual(\n    gripVisual: EventTarget\n  ): ResizeGrip | undefined {\n      if (this.topLeft.ownsTarget(gripVisual)) {\n        return this.topLeft;\n      } else if (this.topCenter.ownsTarget(gripVisual)) {\n        return this.topCenter;\n      } else if (this.topRight.ownsTarget(gripVisual)) {\n        return this.topRight;\n      } else if (this.centerLeft.ownsTarget(gripVisual)) {\n        return this.centerLeft;\n      } else if (this.centerRight.ownsTarget(gripVisual)) {\n        return this.centerRight;\n      } else if (this.bottomLeft.ownsTarget(gripVisual)) {\n        return this.bottomLeft;\n      } else if (this.bottomCenter.ownsTarget(gripVisual)) {\n        return this.bottomCenter;\n      } else if (this.bottomRight.ownsTarget(gripVisual)) {\n        return this.bottomRight;\n      } else {\n        return undefined;\n      }\n  }\n}\n","import { SvgHelper } from '../core/SvgHelper';\n\n/**\n * Represents a single resize-manipulation grip used in marker's manipulation controls.\n */\nexport class ResizeGrip {\n  /**\n   * Grip's visual element.\n   */\n  public visual: SVGGraphicsElement;\n\n  /**\n   * Grip's size (raduis).\n   */\n  public readonly GRIP_SIZE = 10;\n\n  /**\n   * Creates a new grip.\n   */\n  constructor() {\n    this.visual = SvgHelper.createGroup();\n    this.visual.appendChild(\n      SvgHelper.createCircle(this.GRIP_SIZE * 1.5, [['fill', 'transparent']])\n    );\n    this.visual.appendChild(\n      SvgHelper.createCircle(this.GRIP_SIZE, [\n        ['fill', '#cccccc'],\n        ['fill-opacity', '0.7'],\n        ['stroke', '#333333'],\n        ['stroke-width', '2'],\n        ['stroke-opacity', '0.7']\n      ])\n    );\n  }\n\n  /**\n   * Returns true if passed SVG element belongs to the grip. False otherwise.\n   * \n   * @param el - target element.\n   */\n  public ownsTarget(el: EventTarget): boolean {\n    if (\n      el === this.visual ||\n      el === this.visual.childNodes[0] ||\n      el === this.visual.childNodes[1]\n    ) {\n      return true;\n    } else {\n      return false;\n    }\n  }\n}\n","/**\n * Represents a simplified version of the SVGMatrix.\n */\nexport interface ITransformMatrix {\n  a: number;\n  b: number;\n  c: number;\n  d: number;\n  e: number;\n  f: number;\n}\n\n/**\n * A utility class to transform between SVGMatrix and its simplified representation.\n */\nexport class TransformMatrix {\n  public static toITransformMatrix(matrix: SVGMatrix): ITransformMatrix {\n    return {\n      a: matrix.a,\n      b: matrix.b,\n      c: matrix.c,\n      d: matrix.d,\n      e: matrix.e,\n      f: matrix.f\n    }\n  }\n  public static toSVGMatrix(currentMatrix: SVGMatrix, newMatrix: ITransformMatrix): SVGMatrix {\n    currentMatrix.a = newMatrix.a;\n    currentMatrix.b = newMatrix.b;\n    currentMatrix.c = newMatrix.c;\n    currentMatrix.d = newMatrix.d;\n    currentMatrix.e = newMatrix.e;\n    currentMatrix.f = newMatrix.f;\n    return currentMatrix;\n  }\n}","import { MarkerBase } from '../core/MarkerBase';\n\nimport { IPoint } from '../core/IPoint';\nimport { SvgHelper } from '../core/SvgHelper';\n\nimport { RectangularBoxMarkerGrips } from './RectangularBoxMarkerGrips';\nimport { ResizeGrip } from './ResizeGrip';\nimport { Settings } from '../core/Settings';\nimport { RectangularBoxMarkerBaseState } from './RectangularBoxMarkerBaseState';\nimport { MarkerBaseState } from '../core/MarkerBaseState';\nimport { TransformMatrix } from '../core/TransformMatrix';\n\n/**\n * RectangularBoxMarkerBase is a base class for all marker's with rectangular controls such as all rectangle markers,\n * text and callout markers.\n * \n * It creates and manages the rectangular control box and related resize, move, and rotate manipulations.\n */\nexport class RectangularBoxMarkerBase extends MarkerBase {\n  /**\n   * x coordinate of the top-left corner.\n   */\n  protected left = 0;\n  /**\n   * y coordinate of the top-left corner.\n   */\n  protected top = 0;\n  /**\n   * Marker width.\n   */\n  protected width = 0;\n  /**\n   * Marker height.\n   */\n  protected height = 0;\n\n  /**\n   * The default marker size when the marker is created with a click (without dragging).\n   */\n  protected defaultSize: IPoint = {x: 50, y: 20};\n\n  /**\n   * x coordinate of the top-left corner at the start of manipulation.\n   */\n  protected manipulationStartLeft: number;\n  /**\n   * y coordinate of the top-left corner at the start of manipulation.\n   */\n  protected manipulationStartTop: number;\n  /**\n   * Width at the start of manipulation.\n   */\n  protected manipulationStartWidth: number;\n  /**\n   * Height at the start of manipulation.\n   */\n  protected manipulationStartHeight: number;\n\n  /**\n   * x coordinate of the pointer at the start of manipulation.\n   */\n  protected manipulationStartX: number;\n  /**\n   * y coordinate of the pointer at the start of manipulation.\n   */\n  protected manipulationStartY: number;\n\n  /**\n   * Pointer's horizontal distance from the top left corner.\n   */\n  protected offsetX = 0;\n  /**\n   * Pointer's vertical distance from the top left corner.\n   */\n  protected offsetY = 0;\n\n  /**\n   * Marker's rotation angle.\n   */\n  protected rotationAngle = 0;\n\n  /**\n   * x coordinate of the marker's center.\n   */\n  protected get centerX(): number {\n    return this.left + this.width / 2;\n  }\n  /**\n   * y coordinate of the marker's center.\n   */\n  protected get centerY(): number {\n    return this.top + this.height / 2;\n  }\n\n  private _visual: SVGGraphicsElement;\n  /**\n   * Container for the marker's visual.\n   */\n  protected get visual(): SVGGraphicsElement {\n    return this._visual;\n  }\n  protected set visual(value: SVGGraphicsElement) {\n    this._visual = value;\n    const translate = SvgHelper.createTransform();\n    this._visual.transform.baseVal.appendItem(translate);\n  }\n\n  /**\n   * Container for the marker's editing controls.\n   */\n  protected controlBox: SVGGElement;\n  private readonly CB_DISTANCE: number = 10;\n  private controlRect: SVGRectElement;\n  private rotatorGripLine: SVGLineElement;\n\n  private controlGrips: RectangularBoxMarkerGrips;\n  private rotatorGrip: ResizeGrip;\n  private activeGrip: ResizeGrip;\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.\n   * @param settings - settings object containing default markers settings.\n   */\n  constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings) {\n    super(container, overlayContainer, settings);\n\n    // add rotation transform\n    this.container.transform.baseVal.appendItem(SvgHelper.createTransform());\n\n    this.setupControlBox();\n  }\n\n  /**\n   * Returns true if passed SVG element belongs to the marker. False otherwise.\n   * \n   * @param el - target element.\n   */\n  public ownsTarget(el: EventTarget): boolean {\n    if (super.ownsTarget(el)) {\n      return true;\n    } else if (\n      this.controlGrips.findGripByVisual(el) !== undefined ||\n      this.rotatorGrip.ownsTarget(el)\n    ) {\n      return true;\n    } else {\n      return false;\n    }\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) down event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerDown(point: IPoint, target?: EventTarget): void {\n    super.pointerDown(point, target);\n\n    if (this.state === 'new') {\n      this.left = point.x;\n      this.top = point.y;\n    }\n\n    this.manipulationStartLeft = this.left;\n    this.manipulationStartTop = this.top;\n    this.manipulationStartWidth = this.width;\n    this.manipulationStartHeight = this.height;\n\n    const rotatedPoint = this.unrotatePoint(point);\n    this.manipulationStartX = rotatedPoint.x;\n    this.manipulationStartY = rotatedPoint.y;\n\n    this.offsetX = rotatedPoint.x - this.left;\n    this.offsetY = rotatedPoint.y - this.top;\n\n    if (this.state !== 'new') {\n      this.select();\n      this.activeGrip = this.controlGrips.findGripByVisual(target as SVGGraphicsElement);\n      if (this.activeGrip !== undefined) {\n        this._state = 'resize';\n      } else if (this.rotatorGrip.ownsTarget(target)) {\n        this.activeGrip = this.rotatorGrip;\n\n        const rotatedCenter = this.rotatePoint({x: this.centerX, y: this.centerY});\n        this.left = rotatedCenter.x - this.width / 2;\n        this.top = rotatedCenter.y - this.height / 2;\n        this.moveVisual({ x: this.left, y: this.top });\n\n        const rotate = this.container.transform.baseVal.getItem(0);\n        rotate.setRotate(this.rotationAngle, this.centerX, this.centerY);\n        this.container.transform.baseVal.replaceItem(rotate, 0);\n\n        this.adjustControlBox();\n\n        this._state = 'rotate';\n      } else {\n        this._state = 'move';\n      }\n    }\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) up event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerUp(point: IPoint): void {\n    const inState = this.state;\n    super.pointerUp(point);\n    if (this.state === 'creating' && this.width < 10 && this.height < 10) {\n      this.width = this.defaultSize.x;\n      this.height = this.defaultSize.y;\n    } else {\n      this.manipulate(point);\n    }\n    this._state = 'select';\n    if (inState === 'creating' && this.onMarkerCreated) {\n      this.onMarkerCreated(this);\n    }\n  }\n\n  /**\n   * Moves visual to the specified coordinates.\n   * @param point - coordinates of the new top-left corner of the visual.\n   */\n  protected moveVisual(point: IPoint): void {\n    this.visual.style.transform = `translate(${point.x}px, ${point.y}px)`;\n    // const translate = this.visual.transform.baseVal.getItem(0);\n    // translate.setTranslate(point.x, point.y);\n    // this.visual.transform.baseVal.replaceItem(translate, 0);\n  }\n\n  /**\n   * Handles marker manipulation (move, resize, rotate, etc.).\n   * \n   * @param point - event coordinates.\n   */\n  public manipulate(point: IPoint): void {\n    const rotatedPoint = this.unrotatePoint(point);\n\n    if (this.state === 'creating') {\n      this.resize(point);\n    } else if (this.state === 'move') {\n      this.left =\n        this.manipulationStartLeft +\n        (rotatedPoint.x - this.manipulationStartLeft) -\n        this.offsetX;\n      this.top =\n        this.manipulationStartTop +\n        (rotatedPoint.y - this.manipulationStartTop) -\n        this.offsetY;\n      this.moveVisual({x: this.left, y: this.top});\n      this.adjustControlBox();\n    } else if (this.state === 'resize') {\n      this.resize(rotatedPoint);\n    } else if (this.state === 'rotate') {\n      this.rotate(point);\n    }\n  }\n\n  /**\n   * Resizes the marker based on pointer coordinates and context.\n   * @param point - pointer coordinates.\n   */\n  protected resize(point: IPoint): void {\n    let newX = this.manipulationStartLeft;\n    let newWidth = this.manipulationStartWidth;\n    let newY = this.manipulationStartTop;\n    let newHeight = this.manipulationStartHeight;\n\n    switch(this.activeGrip) {\n      case this.controlGrips.bottomLeft:\n      case this.controlGrips.centerLeft:\n      case this.controlGrips.topLeft:\n        newX = this.manipulationStartLeft + point.x - this.manipulationStartX;\n        newWidth = this.manipulationStartWidth + this.manipulationStartLeft - newX;\n        break; \n      case this.controlGrips.bottomRight:\n      case this.controlGrips.centerRight:\n      case this.controlGrips.topRight:\n      case undefined:\n        newWidth = this.manipulationStartWidth + point.x - this.manipulationStartX;\n        break; \n    }\n\n    switch(this.activeGrip) {\n      case this.controlGrips.topCenter:\n      case this.controlGrips.topLeft:\n      case this.controlGrips.topRight:\n        newY = this.manipulationStartTop + point.y - this.manipulationStartY;\n        newHeight = this.manipulationStartHeight + this.manipulationStartTop - newY;\n        break; \n      case this.controlGrips.bottomCenter:\n      case this.controlGrips.bottomLeft:\n      case this.controlGrips.bottomRight:\n      case undefined:\n        newHeight = this.manipulationStartHeight + point.y - this.manipulationStartY;\n        break; \n    }\n\n    if (newWidth >= 0) {\n      this.left = newX;\n      this.width = newWidth;\n    } else {\n      this.left = newX + newWidth;\n      this.width = -newWidth;\n    }\n    if (newHeight >= 0) {\n      this.top = newY;\n      this.height = newHeight;\n    } else {\n      this.top = newY + newHeight;\n      this.height = -newHeight;\n    }\n\n    this.setSize();\n  }\n\n  /**\n   * Sets control box size and location.\n   */\n  protected setSize(): void {\n    this.moveVisual({x: this.left, y: this.top});\n    this.adjustControlBox();\n  }\n\n  private rotate(point: IPoint) {\n    // avoid glitch when crossing the 0 rotation point\n    if (Math.abs(point.x - this.centerX) > 0.1) {\n      const sign = Math.sign(point.x - this.centerX);\n      this.rotationAngle =\n        (Math.atan((point.y - this.centerY) / (point.x - this.centerX)) * 180) /\n          Math.PI +\n        90 * sign;\n      this.applyRotation();\n    }\n  }\n\n  private applyRotation() {\n    const rotate = this.container.transform.baseVal.getItem(0);\n    rotate.setRotate(this.rotationAngle, this.centerX, this.centerY);\n    this.container.transform.baseVal.replaceItem(rotate, 0);\n  }\n\n  /**\n   * Returns point coordinates based on the actual screen coordinates and marker's rotation.\n   * @param point - original pointer coordinates\n   */\n  protected rotatePoint(point: IPoint): IPoint {\n    if (this.rotationAngle === 0) {\n      return point;\n    }\n    \n    const matrix = this.container.getCTM();\n    let svgPoint = SvgHelper.createPoint(point.x, point.y);\n    svgPoint = svgPoint.matrixTransform(matrix);\n\n    const result = { x: svgPoint.x, y: svgPoint.y };\n\n    return result;\n  }\n\n  /**\n   * Returns original point coordinates based on coordinates with rotation applied.\n   * @param point - rotated point coordinates.\n   */\n  protected unrotatePoint(point: IPoint): IPoint {\n    if (this.rotationAngle === 0) {\n      return point;\n    }\n    \n    let matrix = this.container.getCTM();\n    matrix = matrix.inverse();\n    let svgPoint = SvgHelper.createPoint(point.x, point.y);\n    svgPoint = svgPoint.matrixTransform(matrix);\n\n    const result = { x: svgPoint.x, y: svgPoint.y };\n\n    return result;\n  }\n\n  /**\n   * Displays marker's controls.\n   */\n  public select(): void {\n    super.select();\n    this.adjustControlBox();\n    this.controlBox.style.display = '';\n  }\n\n  /**\n   * Hides marker's controls.\n   */\n  public deselect(): void {\n    super.deselect();\n    this.controlBox.style.display = 'none';\n  }\n\n  private setupControlBox() {\n    this.controlBox = SvgHelper.createGroup();\n    const translate = SvgHelper.createTransform();\n    translate.setTranslate(-this.CB_DISTANCE / 2, -this.CB_DISTANCE / 2);\n    this.controlBox.transform.baseVal.appendItem(translate);\n\n    this.container.appendChild(this.controlBox);\n\n    this.controlRect = SvgHelper.createRect(\n      this.width + this.CB_DISTANCE,\n      this.height + this.CB_DISTANCE,\n      [\n        ['stroke', 'black'],\n        ['stroke-width', '1'],\n        ['stroke-opacity', '0.5'],\n        ['stroke-dasharray', '3, 2'],\n        ['fill', 'transparent'],\n        ['pointer-events', 'none']\n      ]\n    );\n\n    this.controlBox.appendChild(this.controlRect);\n\n    this.rotatorGripLine = SvgHelper.createLine(\n      (this.width + this.CB_DISTANCE * 2) / 2,\n      this.top - this.CB_DISTANCE,\n      (this.width + this.CB_DISTANCE * 2) / 2,\n      this.top - this.CB_DISTANCE * 3,\n      [\n        ['stroke', 'black'],\n        ['stroke-width', '1'],\n        ['stroke-opacity', '0.5'],\n        ['stroke-dasharray', '3, 2'],\n      ]\n    );\n\n    this.controlBox.appendChild(this.rotatorGripLine);\n\n    this.controlGrips = new RectangularBoxMarkerGrips();\n    this.addControlGrips();\n\n    this.controlBox.style.display = 'none';\n  }\n\n  private adjustControlBox() {\n    const translate = this.controlBox.transform.baseVal.getItem(0);\n    translate.setTranslate(\n      this.left - this.CB_DISTANCE / 2,\n      this.top - this.CB_DISTANCE / 2\n    );\n    this.controlBox.transform.baseVal.replaceItem(translate, 0);\n    this.controlRect.setAttribute(\n      'width',\n      (this.width + this.CB_DISTANCE).toString()\n    );\n    this.controlRect.setAttribute(\n      'height',\n      (this.height + this.CB_DISTANCE).toString()\n    );\n    this.rotatorGripLine.setAttribute(\n      'x1',\n      ((this.width + this.CB_DISTANCE) / 2).toString()\n    );\n    this.rotatorGripLine.setAttribute('y1', (-this.CB_DISTANCE / 2).toString());\n    this.rotatorGripLine.setAttribute(\n      'x2',\n      ((this.width + this.CB_DISTANCE) / 2).toString()\n    );\n    this.rotatorGripLine.setAttribute('y2', (-this.CB_DISTANCE * 3).toString());\n    this.positionGrips();\n  }\n\n  private addControlGrips() {\n    this.controlGrips.topLeft = this.createGrip();\n    this.controlGrips.topCenter = this.createGrip();\n    this.controlGrips.topRight = this.createGrip();\n    this.controlGrips.centerLeft = this.createGrip();\n    this.controlGrips.centerRight = this.createGrip();\n    this.controlGrips.bottomLeft = this.createGrip();\n    this.controlGrips.bottomCenter = this.createGrip();\n    this.controlGrips.bottomRight = this.createGrip();\n\n    this.rotatorGrip = this.createGrip();\n\n    this.positionGrips();\n  }\n\n  private createGrip(): ResizeGrip {\n    const grip = new ResizeGrip();\n    grip.visual.transform.baseVal.appendItem(SvgHelper.createTransform());\n    this.controlBox.appendChild(grip.visual);\n\n    return grip;\n  }\n\n  private positionGrips() {\n    const gripSize = this.controlGrips.topLeft.GRIP_SIZE;\n\n    const left = -gripSize / 2;\n    const top = left;\n    const cx = (this.width + this.CB_DISTANCE) / 2 - gripSize / 2;\n    const cy = (this.height + this.CB_DISTANCE) / 2 - gripSize / 2;\n    const bottom = this.height + this.CB_DISTANCE - gripSize / 2;\n    const right = this.width + this.CB_DISTANCE - gripSize / 2;\n\n    this.positionGrip(this.controlGrips.topLeft.visual, left, top);\n    this.positionGrip(this.controlGrips.topCenter.visual, cx, top);\n    this.positionGrip(this.controlGrips.topRight.visual, right, top);\n    this.positionGrip(this.controlGrips.centerLeft.visual, left, cy);\n    this.positionGrip(this.controlGrips.centerRight.visual, right, cy);\n    this.positionGrip(this.controlGrips.bottomLeft.visual, left, bottom);\n    this.positionGrip(this.controlGrips.bottomCenter.visual, cx, bottom);\n    this.positionGrip(this.controlGrips.bottomRight.visual, right, bottom);\n\n    this.positionGrip(this.rotatorGrip.visual, cx, top - this.CB_DISTANCE * 3);\n  }\n\n  private positionGrip(grip: SVGGraphicsElement, x: number, y: number) {\n    const translate = grip.transform.baseVal.getItem(0);\n    translate.setTranslate(x, y);\n    grip.transform.baseVal.replaceItem(translate, 0);\n  }\n\n  /**\n   * Hides marker's editing controls.\n   */\n  protected hideControlBox(): void {\n    this.controlBox.style.display = 'none';\n  }\n  /**\n   * Shows marker's editing controls.\n   */\n  protected showControlBox(): void {\n    this.controlBox.style.display = '';\n  }\n\n  /**\n   * Returns marker's state.\n   */\n  public getState(): RectangularBoxMarkerBaseState {\n    const result: RectangularBoxMarkerBaseState = Object.assign({\n      left: this.left,\n      top: this.top,\n      width: this.width,\n      height: this.height,\n      rotationAngle: this.rotationAngle,\n      visualTransformMatrix: TransformMatrix.toITransformMatrix(this.visual.transform.baseVal.getItem(0).matrix),\n      containerTransformMatrix: TransformMatrix.toITransformMatrix(this.container.transform.baseVal.getItem(0).matrix)\n    },\n    super.getState());\n\n    return result;\n  }\n\n  /**\n   * Restores marker's state to the previously saved one.\n   * @param state - previously saved state.\n   */\n  public restoreState(state: MarkerBaseState): void {\n    super.restoreState(state);\n    const rbmState = state as RectangularBoxMarkerBaseState;\n    this.left = rbmState.left;\n    this.top = rbmState.top;\n    this.width = rbmState.width;\n    this.height = rbmState.height;\n    this.rotationAngle = rbmState.rotationAngle;\n    this.visual.transform.baseVal.getItem(0).setMatrix(\n      TransformMatrix.toSVGMatrix(this.visual.transform.baseVal.getItem(0).matrix, rbmState.visualTransformMatrix)\n    );\n    this.container.transform.baseVal.getItem(0).setMatrix(\n      TransformMatrix.toSVGMatrix(this.container.transform.baseVal.getItem(0).matrix, rbmState.containerTransformMatrix)\n    );\n    // this.moveVisual({x: this.left, y: this.top});\n    // this.applyRotation();\n  }\n\n  /**\n   * Scales marker. Used after the image resize.\n   * \n   * @param scaleX - horizontal scale\n   * @param scaleY - vertical scale\n   */\n  public scale(scaleX: number, scaleY: number): void {\n    super.scale(scaleX, scaleY);\n\n    const rPoint = this.rotatePoint({x: this.left, y: this.top});\n    const point = this.unrotatePoint({x: rPoint.x * scaleX, y: rPoint.y * scaleY});\n\n    this.left = point.x;\n    this.top = point.y;\n    this.width = this.width * scaleX;\n    this.height = this.height * scaleY;\n\n    this.adjustControlBox();\n  }\n\n}\n","import { IPoint } from '../core/IPoint';\nimport { SvgHelper } from '../core/SvgHelper';\nimport { RectangularBoxMarkerBase } from './RectangularBoxMarkerBase';\nimport { Settings } from '../core/Settings';\nimport { RectangleMarkerState } from './RectangleMarkerState';\nimport { MarkerBaseState } from '../core/MarkerBaseState';\n\n/**\n * RecatngleMarker is a base class for all rectangular markers (Frame, Cover, Highlight, etc.)\n */\nexport abstract class RectangleMarker extends RectangularBoxMarkerBase {\n  /**\n   * String type name of the marker type. \n   * \n   * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static title = 'Rectangle marker';\n\n  /**\n   * Recangle fill color.\n   */\n  protected fillColor = 'transparent';\n  /**\n   * Rectangle stroke color.\n   */\n  protected strokeColor = 'transparent';\n  /**\n   * Rectangle border stroke width.\n   */\n  protected strokeWidth = 0;\n  /**\n   * Rectangle border stroke dash array.\n   */\n  protected strokeDasharray = '';\n  /**\n   * Rectangle opacity (alpha). 0 to 1.\n   */\n  protected opacity = 1;\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.\n   * @param settings - settings object containing default markers settings.\n   */\n  constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings) {\n    super(container, overlayContainer, settings);\n\n    this.setStrokeColor = this.setStrokeColor.bind(this);\n    this.setFillColor = this.setFillColor.bind(this);\n    this.setStrokeWidth = this.setStrokeWidth.bind(this);\n    this.setStrokeDasharray = this.setStrokeDasharray.bind(this);\n    this.createVisual = this.createVisual.bind(this);\n  }\n\n  /**\n   * Returns true if passed SVG element belongs to the marker. False otherwise.\n   * \n   * @param el - target element.\n   */\n  public ownsTarget(el: EventTarget): boolean {\n    if (super.ownsTarget(el) || el === this.visual) {\n      return true;\n    } else {\n      return false;\n    }\n  }\n\n  /**\n   * Creates the marker's rectangle visual.\n   */\n  protected createVisual(): void {\n    this.visual = SvgHelper.createRect(1, 1, [\n      ['fill', this.fillColor],\n      ['stroke', this.strokeColor],\n      ['stroke-width', this.strokeWidth.toString()],\n      ['stroke-dasharray', this.strokeDasharray],\n      ['opacity', this.opacity.toString()]\n    ]);\n    this.addMarkerVisualToContainer(this.visual);\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) down event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerDown(point: IPoint, target?: EventTarget): void {\n    super.pointerDown(point, target);\n    if (this.state === 'new') {\n      this.createVisual();\n\n      this.moveVisual(point);\n\n      this._state = 'creating';\n    }\n  }\n\n  /**\n   * Handles marker manipulation (move, resize, rotate, etc.).\n   * \n   * @param point - event coordinates.\n   */\n  public manipulate(point: IPoint): void {\n    super.manipulate(point);\n  }\n\n  /**\n   * Resizes the marker based on the pointer coordinates.\n   * @param point - current pointer coordinates.\n   */\n  protected resize(point: IPoint): void {\n    super.resize(point);\n    this.setSize();\n  }\n\n  /**\n   * Sets visual's width and height attributes based on marker's width and height.\n   */\n  protected setSize(): void {\n    super.setSize();\n    SvgHelper.setAttributes(this.visual, [\n      ['width', this.width.toString()],\n      ['height', this.height.toString()],\n    ]);\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) up event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerUp(point: IPoint): void {\n    super.pointerUp(point);\n    this.setSize();\n  }\n\n  /**\n   * Sets rectangle's border stroke color.\n   * @param color - color as string\n   */\n  protected setStrokeColor(color: string): void {\n    this.strokeColor = color;\n    if (this.visual) {\n      SvgHelper.setAttributes(this.visual, [['stroke', this.strokeColor]]);\n    }\n    this.colorChanged(color);\n  }\n  /**\n   * Sets rectangle's fill color.\n   * @param color - color as string\n   */\n  protected setFillColor(color: string): void {\n    this.fillColor = color;\n    if (this.visual) {\n      SvgHelper.setAttributes(this.visual, [['fill', this.fillColor]]);\n    }\n  }\n  /**\n   * Sets rectangle's border stroke (line) width.\n   * @param color - color as string\n   */\n  protected setStrokeWidth(width: number): void {\n    this.strokeWidth = width;\n    if (this.visual) {\n      SvgHelper.setAttributes(this.visual, [['stroke-width', this.strokeWidth.toString()]]);\n    }\n  }\n  /**\n   * Sets rectangle's border stroke dash array.\n   * @param color - color as string\n   */\n  protected setStrokeDasharray(dashes: string): void {\n    this.strokeDasharray = dashes;\n    if (this.visual) {\n      SvgHelper.setAttributes(this.visual, [['stroke-dasharray', this.strokeDasharray]]);\n    }\n  }\n\n  /**\n   * Returns current marker state that can be restored in the future.\n   */\n  public getState(): RectangleMarkerState {\n    const result: RectangleMarkerState = Object.assign({\n      fillColor: this.fillColor,\n      strokeColor: this.strokeColor,\n      strokeWidth: this.strokeWidth,\n      strokeDasharray: this.strokeDasharray,\n      opacity: this.opacity\n    }, super.getState());\n\n    return result;\n  }\n\n  /**\n   * Restores previously saved marker state.\n   * \n   * @param state - previously saved state.\n   */\n  public restoreState(state: MarkerBaseState): void {\n    const rectState = state as RectangleMarkerState;\n    this.fillColor = rectState.fillColor;\n    this.strokeColor = rectState.strokeColor;\n    this.strokeWidth = rectState.strokeWidth;\n    this.strokeDasharray = rectState.strokeDasharray;\n    this.opacity = rectState.opacity;\n\n    this.createVisual();\n    super.restoreState(state);\n    this.setSize();\n  }\n\n  /**\n   * Scales marker. Used after the image resize.\n   * \n   * @param scaleX - horizontal scale\n   * @param scaleY - vertical scale\n   */\n  public scale(scaleX: number, scaleY: number): void {\n    super.scale(scaleX, scaleY);\n\n    this.setSize();\n  }\n\n}\n","import { Style } from '../../core/Style';\nimport { ToolboxPanel } from '../ToolboxPanel';\nimport Icon from './line-width-panel-icon.svg';\n\n/**\n * Line width change event handler type.\n */\nexport type WidthChangeHandler = (newWidth: number) => void;\n\n/**\n * Line width toolbox panel.\n */\nexport class LineWidthPanel extends ToolboxPanel {\n  private widths: number[] = [];\n  private currentWidth?: number;\n\n  private widthBoxes: HTMLDivElement[] = [];\n\n  /**\n   * Line width change event handler.\n   */\n  public onWidthChanged?: WidthChangeHandler;\n\n  /**\n   * Creates a line width toolbox panel.\n   * @param title - panel title.\n   * @param widths - available widths.\n   * @param currentWidth - currently set width.\n   * @param icon - toolbox panel icon (SVG image markup).\n   */\n  constructor(title: string, widths: number[], currentWidth?: number, icon?: string) {\n    super(title, icon ? icon : Icon);\n    this.widths = widths;\n    this.currentWidth = currentWidth;\n\n    this.setCurrentWidth = this.setCurrentWidth.bind(this);\n  }\n\n  /**\n   * Returns panel UI.\n   */\n  public getUi(): HTMLDivElement {\n    const panelDiv = document.createElement('div');\n    panelDiv.style.display = 'flex';\n    panelDiv.style.overflow = 'hidden';\n    panelDiv.style.flexGrow = '2';\n    this.widths.forEach((lineWidth) => {\n      const widthBoxContainer = document.createElement('div');\n      widthBoxContainer.style.display = 'flex';\n      widthBoxContainer.style.flexGrow = '2';\n      widthBoxContainer.style.alignItems = 'center';\n      widthBoxContainer.style.justifyContent = 'space-between';\n      widthBoxContainer.style.padding = '5px';\n      widthBoxContainer.style.borderWidth = '2px';\n      widthBoxContainer.style.borderStyle = 'solid';\n      widthBoxContainer.style.borderColor =\n        lineWidth === this.currentWidth ? Style.settings.toolboxAccentColor : 'transparent';\n\n      widthBoxContainer.addEventListener('click', () => {\n        this.setCurrentWidth(lineWidth, widthBoxContainer);\n      })\n      panelDiv.appendChild(widthBoxContainer);\n\n      const label = document.createElement('div');\n      label.innerText = lineWidth.toString();\n      label.style.marginRight = '5px';\n      widthBoxContainer.appendChild(label);\n\n      const widthBox = document.createElement('div');\n      widthBox.style.minHeight = '20px';\n      widthBox.style.flexGrow = '2';\n      widthBox.style.display = 'flex';\n      widthBox.style.alignItems = 'center';\n\n      const hr = document.createElement('hr');\n      hr.style.minWidth = '20px';\n      hr.style.border = '0px';\n      hr.style.borderTop = `${lineWidth}px solid ${Style.settings.toolboxColor}`;\n      hr.style.flexGrow = '2';\n      widthBox.appendChild(hr);\n\n      // widthBox.innerHTML = `<svg viewBox=\"0 0 140 20\" width=\"140\" height=\"20\" xmlns=\"http://www.w3.org/2000/svg\">\n      //   <line x1=\"0\" y1=\"10\" x2=\"140\" y2=\"10\" stroke=\"${Style.settings.toolboxColor}\" stroke-width=\"${lineWidth}\" />\n      // </svg>`;\n\n      widthBoxContainer.appendChild(widthBox);\n\n      this.widthBoxes.push(widthBoxContainer);\n    });\n    return panelDiv;\n  }\n\n  private setCurrentWidth(newWidth: number, target: HTMLDivElement) {\n    this.currentWidth = newWidth;\n\n    this.widthBoxes.forEach(box => {\n      box.style.borderColor = box === target ? Style.settings.toolboxAccentColor : 'transparent';\n    });\n\n    if (this.onWidthChanged) {\n      this.onWidthChanged(this.currentWidth);\n    }\n  }\n}\n","import { Style } from '../../core/Style';\nimport { ToolboxPanel } from '../ToolboxPanel';\nimport Icon from './line-style-panel-icon.svg';\n\n/**\n * Line style change event handler type.\n */\nexport type StyleChangeHandler = (newStyle: string) => void;\n\n/**\n * Line style (solid, dashed, etc.) toolbox panel.\n */\nexport class LineStylePanel extends ToolboxPanel {\n  private styles: string[] = [];\n  private currentStyle?: string;\n\n  private styleBoxes: HTMLDivElement[] = [];\n\n  /**\n   * Handler for the style change event.\n   */\n  public onStyleChanged?: StyleChangeHandler;\n\n  /**\n   * Creates a line style toolbox panel.\n   * @param title - panel title\n   * @param styles - available line styles (dash array).\n   * @param currentStyle - currently selected style.\n   * @param icon - panel button icon (SVG image markup).\n   */\n  constructor(title: string, styles: string[], currentStyle?: string, icon?: string) {\n    super(title, icon ? icon : Icon);\n    this.styles = styles;\n    this.currentStyle = currentStyle;\n\n    this.setCurrentStyle = this.setCurrentStyle.bind(this);\n  }\n\n  /**\n   * Returns panel UI.\n   */\n  public getUi(): HTMLDivElement {\n    const panelDiv = document.createElement('div');\n    panelDiv.style.display = 'flex';\n    panelDiv.style.overflow = 'hidden';\n    panelDiv.style.flexGrow = '2';\n    this.styles.forEach((lineStyle) => {\n      const styleBoxContainer = document.createElement('div');\n      styleBoxContainer.style.display = 'flex'; //'inline-block';\n      styleBoxContainer.style.alignItems = 'center';\n      styleBoxContainer.style.justifyContent = 'space-between';\n      styleBoxContainer.style.padding = '5px';\n      styleBoxContainer.style.borderWidth = '2px';\n      styleBoxContainer.style.borderStyle = 'solid';\n      styleBoxContainer.style.overflow = 'hidden';\n      styleBoxContainer.style.maxWidth = `${100 / this.styles.length - 5}%`;\n      styleBoxContainer.style.borderColor =\n        lineStyle === this.currentStyle ? Style.settings.toolboxAccentColor : 'transparent';\n\n      styleBoxContainer.addEventListener('click', () => {\n        this.setCurrentStyle(lineStyle, styleBoxContainer);\n      })\n      panelDiv.appendChild(styleBoxContainer);\n\n      const styleBox = document.createElement('div');\n      styleBox.style.minHeight = '20px';\n      styleBox.style.flexGrow = '2';\n      styleBox.style.overflow = 'hidden';\n\n      const styleSample = `<svg width=\"100\" height=\"20\">\n      <line x1=\"0\" y1=\"10\" x2=\"100\" y2=\"10\" stroke=\"${\n        Style.settings.toolboxColor}\" stroke-width=\"3\" ${\n          lineStyle !== '' ? 'stroke-dasharray=\"' + lineStyle + '\"' : ''} />\n  </svg>`;\n\n      styleBox.innerHTML = styleSample;\n\n      styleBoxContainer.appendChild(styleBox);\n\n      this.styleBoxes.push(styleBoxContainer);\n    });\n    return panelDiv;\n  }\n\n  private setCurrentStyle(newStyle: string, target: HTMLDivElement) {\n    this.currentStyle = newStyle;\n\n    this.styleBoxes.forEach(box => {\n      box.style.borderColor = box === target ? Style.settings.toolboxAccentColor : 'transparent';\n    });\n\n    if (this.onStyleChanged) {\n      this.onStyleChanged(this.currentStyle);\n    }\n  }\n}\n","import Icon from './frame-marker-icon.svg';\nimport { ToolboxPanel } from '../../ui/ToolboxPanel';\nimport { ColorPickerPanel } from '../../ui/toolbox-panels/ColorPickerPanel';\nimport { Settings } from '../../core/Settings';\nimport { RectangleMarker } from '../RectangleMarker';\nimport { LineWidthPanel } from '../../ui/toolbox-panels/LineWidthPanel';\nimport { LineStylePanel } from '../../ui/toolbox-panels/LineStylePanel';\nimport { RectangleMarkerState } from '../RectangleMarkerState';\n\nexport class FrameMarker extends RectangleMarker {\n  /**\n   * String type name of the marker type. \n   * \n   * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static typeName = 'FrameMarker';\n  \n  /**\n   * Marker type title (display name) used for accessibility and other attributes.\n   */\n  public static title = 'Frame marker';\n  /**\n   * SVG icon markup displayed on toolbar buttons.\n   */\n  public static icon = Icon;\n\n  private strokePanel: ColorPickerPanel;\n  private strokeWidthPanel: LineWidthPanel;\n  private strokeStylePanel: LineStylePanel;\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.\n   * @param settings - settings object containing default markers settings.\n   */\n  constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings) {\n    super(container, overlayContainer, settings);\n\n    this.strokeColor = settings.defaultColor;\n    this.strokeWidth = settings.defaultStrokeWidth;\n    this.strokeDasharray = settings.defaultStrokeDasharray;\n\n    this.strokePanel = new ColorPickerPanel(\n      'Line color',\n      settings.defaultColorSet,\n      settings.defaultColor\n    );\n    this.strokePanel.onColorChanged = this.setStrokeColor;\n\n    this.strokeWidthPanel = new LineWidthPanel(\n      'Line width',\n      settings.defaultStrokeWidths,\n      settings.defaultStrokeWidth\n    );\n    this.strokeWidthPanel.onWidthChanged = this.setStrokeWidth;\n\n    this.strokeStylePanel = new LineStylePanel(\n      'Line style',\n      settings.defaultStrokeDasharrays,\n      settings.defaultStrokeDasharray\n    );\n    this.strokeStylePanel.onStyleChanged = this.setStrokeDasharray;\n  }\n\n  /**\n   * Returns the list of toolbox panels for this marker type.\n   */\n  public get toolboxPanels(): ToolboxPanel[] {\n    return [this.strokePanel, this.strokeWidthPanel, this.strokeStylePanel];\n  }\n\n  /**\n   * Returns current marker state that can be restored in the future.\n   */\n  public getState(): RectangleMarkerState {\n    const result = super.getState();\n    result.typeName = FrameMarker.typeName;\n    return result;\n  }\n}\n","/**\n * Represents a list of colors.\n */\nexport type ColorSet = string[];\n\n/**\n * marker.js 2 display mode - `inline` or `popup`.\n */\nexport type DisplayMode = 'inline' | 'popup';\n\n/**\n * Default settings for marker.js 2 markers.\n */\nexport class Settings {\n  /**\n   * List of colors used in color pickers.\n   */\n  public defaultColorSet: ColorSet = [\n    '#EF4444', // red\n    '#10B981', // green\n    '#2563EB', // blue\n    '#FFFF00', // yellow\n    '#7C3AED', // purple\n    '#F472B6', // pink\n    '#000000', // black\n    '#FFFFFF' //white\n  ];\n\n  /**\n   * Default foreground color.\n   */\n  public defaultColor = this.defaultColorSet[0];\n  /**\n   * Default fill color.\n   */\n  public defaultFillColor = this.defaultColorSet[0];\n  /**\n   * Default stroke color for markers with background (eg. {@link CalloutMarker}).\n   */\n  public defaultStrokeColor = this.defaultColorSet[7];\n  /**\n   * Default highlighter color.\n   */\n  public defaultHighlightColor = this.defaultColorSet[3];\n  /**\n   * Default stroke (line) width.\n   */\n  public defaultStrokeWidth = 3;\n  /**\n   * Default line dash array\n   */\n  public defaultStrokeDasharray = '';\n  /**\n   * Default opacity (alpha) of the {@link HighlightMarker} (and other highlighters).\n   */\n  public defaultHighlightOpacity = 0.5;\n  /**\n   * Default font family for text-based markers (eg. {@link TextMarker} and {@link CalloutMarker}).\n   *\n   */\n  public defaultFontFamily = 'Helvetica, Arial, sans-serif';\n\n  /**\n   * Stroke (line) width options.\n   */\n  public defaultStrokeWidths = [1, 2, 3, 5, 10];\n  \n  /**\n   * Stroke dash array options.\n   */\n  public defaultStrokeDasharrays = ['', '3', '12 3', '9 6 3 6'];\n\n  /**\n   * Opacity options.\n   */\n  public defaultOpacitySteps = [0.1, 0.25, 0.5, 0.75, 1];\n\n  /**\n   * Default display mode.\n   */\n  public displayMode: DisplayMode = 'inline';\n\n  /**\n   * Font family options.\n   */\n  public defaultFontFamilies = [\n    'Times, \"Times New Roman\", serif',\n    'Helvetica, Arial, sans-serif',\n    'Courier, \"Courier New\", monospace',\n    'cursive',\n    'fantasy'\n  ];\n\n  /**\n   * Margin in pixels between marker.js popup UI and window borders.\n   */\n  public popupMargin = 30;\n\n  /**\n   * Create a new Freehand marker for every stroke.\n   */\n  public newFreehandMarkerOnPointerUp = false;\n\n  /**\n   * If set to true, when colors on a marker are changed \n   * it changes the default color for other markers as well.\n   * \n   * @since 2.7.0\n   */\n  public defaultColorsFollowCurrentColors = false;\n\n  /**\n   * Increase this setting for smoother FreehandMarker lines.\n   * Note that it will also take more space when you save the state.\n   *\n   * @since 2.20.0\n   */\n  public freehandPixelRatio = 1;\n}\n","import { MarkerBase } from '../core/MarkerBase';\n\nimport { IPoint } from '../core/IPoint';\nimport { SvgHelper } from '../core/SvgHelper';\n\nimport { ResizeGrip } from './ResizeGrip';\nimport { Settings } from '../core/Settings';\nimport { LinearMarkerBaseState } from './LinearMarkerBaseState';\nimport { MarkerBaseState } from '../core/MarkerBaseState';\n\n/**\n * LinearMarkerBase is a base class for all line-type markers (Line, Arrow, Measurement Tool, etc.).\n */\nexport class LinearMarkerBase extends MarkerBase {\n  /**\n   * x coordinate of the first end-point\n   */\n  protected x1 = 0;\n  /**\n   * y coordinate of the first end-point\n   */\n  protected y1 = 0;\n  /**\n   * x coordinate of the second end-point\n   */\n  protected x2 = 0;\n  /**\n   * y coordinate of the second end-point\n   */\n  protected y2 = 0;\n\n  /**\n   * Default line length when marker is created with a simple click (without dragging).\n   */\n  protected defaultLength = 50;\n\n  /**\n   * Pointer coordinates at the satart of move or resize.\n   */\n  protected manipulationStartX = 0;\n  protected manipulationStartY = 0;\n\n  private manipulationStartX1 = 0;\n  private manipulationStartY1 = 0;\n  private manipulationStartX2 = 0;\n  private manipulationStartY2 = 0;\n\n  /**\n   * Marker's main visual.\n   */\n  protected visual: SVGGraphicsElement;\n\n  /**\n   * Container for control elements.\n   */\n  protected controlBox: SVGGElement;\n\n  /**\n   * First manipulation grip\n   */\n  protected grip1: ResizeGrip;\n  /**\n   * Second manipulation grip.\n   */\n  protected grip2: ResizeGrip;\n  /**\n   * Active manipulation grip.\n   */\n  protected activeGrip: ResizeGrip;\n\n  /**\n   * Creates a LineMarkerBase object.\n   * \n   * @param container - SVG container to hold marker's visual.\n   * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.\n   * @param settings - settings object containing default markers settings.\n   */\n  constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings) {\n    super(container, overlayContainer, settings);\n\n    this.setupControlBox();\n  }\n\n  /**\n   * Returns true if passed SVG element belongs to the marker. False otherwise.\n   * \n   * @param el - target element.\n   */\n  public ownsTarget(el: EventTarget): boolean {\n    if (super.ownsTarget(el)) {\n      return true;\n    } else if (\n      this.grip1.ownsTarget(el) || this.grip2.ownsTarget(el)\n    ) {\n      return true;\n    } else {\n      return false;\n    }\n  }\n\n  \n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) down event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerDown(point: IPoint, target?: EventTarget): void {\n    super.pointerDown(point, target);\n\n    this.manipulationStartX = point.x;\n    this.manipulationStartY = point.y;\n\n    if (this.state === 'new') {\n      this.x1 = point.x;\n      this.y1 = point.y;\n      this.x2 = point.x;\n      this.y2 = point.y;\n    }\n\n    this.manipulationStartX1 = this.x1;\n    this.manipulationStartY1 = this.y1;\n    this.manipulationStartX2 = this.x2;\n    this.manipulationStartY2 = this.y2;\n\n    if (this.state !== 'new') {\n      this.select();\n      if (this.grip1.ownsTarget(target)) {\n        this.activeGrip = this.grip1;\n      } else if (this.grip2.ownsTarget(target)) {\n        this.activeGrip = this.grip2;\n      } else {\n        this.activeGrip = undefined;\n      }\n\n      if (this.activeGrip) {\n        this._state = 'resize';\n      } else {\n        this._state = 'move';\n      }\n    }\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) up event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerUp(point: IPoint): void {\n    const inState = this.state;\n    super.pointerUp(point);\n    if (this.state === 'creating' && Math.abs(this.x1 - this.x2) < 10 && Math.abs(this.y1 - this.y2) < 10) {\n      this.x2 = this.x1 + this.defaultLength;\n      this.adjustVisual();\n      this.adjustControlBox()\n    } else {\n      this.manipulate(point);\n    }\n    this._state = 'select';\n    if (inState === 'creating' && this.onMarkerCreated) {\n      this.onMarkerCreated(this);\n    }\n  }\n\n  /**\n   * When implemented adjusts marker visual after manipulation when needed.\n   */\n  // eslint-disable-next-line @typescript-eslint/no-empty-function\n  protected adjustVisual(): void {}\n\n  /**\n   * Handles marker manipulation (move, resize, rotate, etc.).\n   * \n   * @param point - event coordinates.\n   */\n  public manipulate(point: IPoint): void {\n    if (this.state === 'creating') {\n      this.resize(point);\n    } else if (this.state === 'move') {\n      this.x1 = this.manipulationStartX1 + point.x - this.manipulationStartX;\n      this.y1 = this.manipulationStartY1 + point.y - this.manipulationStartY;\n      this.x2 = this.manipulationStartX2 + point.x - this.manipulationStartX;\n      this.y2 = this.manipulationStartY2 + point.y - this.manipulationStartY;\n      this.adjustVisual();\n      this.adjustControlBox();\n    } else if (this.state === 'resize') {\n      this.resize(point);\n    }\n  }\n\n  /**\n   * Resizes the line marker.\n   * @param point - current manipulation coordinates.\n   */\n  protected resize(point: IPoint): void {\n    switch(this.activeGrip) {\n      case this.grip1:\n        this.x1 = point.x;\n        this.y1 = point.y;\n        break; \n      case this.grip2:\n      case undefined:\n        this.x2 = point.x;\n        this.y2 = point.y;\n        break; \n    }\n    this.adjustVisual();\n    this.adjustControlBox();\n  }\n\n  /**\n   * Displays marker's controls.\n   */\n  public select(): void {\n    super.select();\n    this.adjustControlBox();\n    this.controlBox.style.display = '';\n  }\n\n  /**\n   * Hides marker's controls.\n   */\n  public deselect(): void {\n    super.deselect();\n    this.controlBox.style.display = 'none';\n  }\n\n  /**\n   * Creates control box for manipulation controls.\n   */\n  protected setupControlBox(): void {\n    this.controlBox = SvgHelper.createGroup();\n    this.container.appendChild(this.controlBox);\n\n    this.addControlGrips();\n\n    this.controlBox.style.display = 'none';\n  }\n\n  private adjustControlBox() {\n    this.positionGrips();\n  }\n\n  /**\n   * Adds control grips to control box.\n   */\n  protected addControlGrips(): void {\n    this.grip1 = this.createGrip();\n    this.grip2 = this.createGrip();\n\n    this.positionGrips();\n  }\n\n  /**\n   * Creates manipulation grip.\n   * @returns - manipulation grip.\n   */\n  protected createGrip(): ResizeGrip {\n    const grip = new ResizeGrip();\n    grip.visual.transform.baseVal.appendItem(SvgHelper.createTransform());\n    this.controlBox.appendChild(grip.visual);\n\n    return grip;\n  }\n\n  /**\n   * Updates manipulation grip layout.\n   */\n  protected positionGrips(): void {\n    const gripSize = this.grip1.GRIP_SIZE;\n\n    this.positionGrip(this.grip1.visual, this.x1 - gripSize / 2, this.y1 - gripSize / 2);\n    this.positionGrip(this.grip2.visual, this.x2 - gripSize / 2, this.y2 - gripSize / 2);\n  }\n\n  /**\n   * Positions manipulation grip.\n   * @param grip - grip to position\n   * @param x - new X coordinate\n   * @param y - new Y coordinate\n   */\n  protected positionGrip(grip: SVGGraphicsElement, x: number, y: number): void {\n    const translate = grip.transform.baseVal.getItem(0);\n    translate.setTranslate(x, y);\n    grip.transform.baseVal.replaceItem(translate, 0);\n  }\n\n  /**\n   * Returns marker's state.\n   */\n  public getState(): LinearMarkerBaseState {\n    const result: LinearMarkerBaseState = Object.assign({\n      x1: this.x1,\n      y1: this.y1,\n      x2: this.x2,\n      y2: this.y2\n    }, super.getState());\n\n    return result;\n  }\n\n  /**\n   * Restores marker's state to the previously saved one.\n   * @param state - previously saved state.\n   */\n  public restoreState(state: MarkerBaseState): void {\n    super.restoreState(state);\n    const lmbState = state as LinearMarkerBaseState;\n    this.x1 = lmbState.x1;\n    this.y1 = lmbState.y1;\n    this.x2 = lmbState.x2;\n    this.y2 = lmbState.y2;\n  }\n\n  /**\n   * Scales marker. Used after the image resize.\n   * \n   * @param scaleX - horizontal scale\n   * @param scaleY - vertical scale\n   */\n  public scale(scaleX: number, scaleY: number): void {\n    super.scale(scaleX, scaleY);\n\n    this.x1 = this.x1 * scaleX;\n    this.y1 = this.y1 * scaleY;\n    this.x2 = this.x2 * scaleX;\n    this.y2 = this.y2 * scaleY;\n\n    this.adjustVisual();\n    this.adjustControlBox();\n  }\n}\n","import { IPoint } from '../../core/IPoint';\nimport { SvgHelper } from '../../core/SvgHelper';\nimport { Settings } from '../../core/Settings';\nimport { LinearMarkerBase } from '../LinearMarkerBase';\nimport Icon from './line-marker-icon.svg';\nimport { ColorPickerPanel } from '../../ui/toolbox-panels/ColorPickerPanel';\nimport { ToolboxPanel } from '../../ui/ToolboxPanel';\nimport { LineWidthPanel } from '../../ui/toolbox-panels/LineWidthPanel';\nimport { LineStylePanel } from '../../ui/toolbox-panels/LineStylePanel';\nimport { LineMarkerState } from './LineMarkerState';\nimport { MarkerBaseState } from '../../core/MarkerBaseState';\n\nexport class LineMarker extends LinearMarkerBase {\n  /**\n   * String type name of the marker type. \n   * \n   * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static typeName = 'LineMarker';\n  \n  /**\n   * Marker type title (display name) used for accessibility and other attributes.\n   */\n  public static title = 'Line marker';\n  /**\n   * SVG icon markup displayed on toolbar buttons.\n   */\n  public static icon = Icon;\n\n  /**\n   * Invisible wider line to make selection easier/possible.\n   */\n  protected selectorLine: SVGLineElement;\n  /**\n   * Visible marker line.\n   */\n  protected visibleLine: SVGLineElement;\n\n  /**\n   * Line color.\n   */\n  protected strokeColor = 'transparent';\n  /**\n   * Line width.\n   */\n  protected strokeWidth = 0;\n  /**\n   * Line dash array.\n   */\n  protected strokeDasharray = '';\n\n  /**\n   * Color pickar panel for line color.\n   */\n  protected strokePanel: ColorPickerPanel;\n  /**\n   * Line width toolbox panel.\n   */\n  protected strokeWidthPanel: LineWidthPanel;\n  /**\n   * Line dash array toolbox panel.\n   */\n  protected strokeStylePanel: LineStylePanel;\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.\n   * @param settings - settings object containing default markers settings.\n   */\n  constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings) {\n    super(container, overlayContainer, settings);\n\n    this.setStrokeColor = this.setStrokeColor.bind(this);\n    this.setStrokeWidth = this.setStrokeWidth.bind(this);\n    this.setStrokeDasharray = this.setStrokeDasharray.bind(this);\n\n    this.strokeColor = settings.defaultColor;\n    this.strokeWidth = settings.defaultStrokeWidth;\n    this.strokeDasharray = settings.defaultStrokeDasharray;\n\n    this.strokePanel = new ColorPickerPanel(\n      'Line color',\n      settings.defaultColorSet,\n      settings.defaultColor\n    );\n    this.strokePanel.onColorChanged = this.setStrokeColor;\n\n    this.strokeWidthPanel = new LineWidthPanel(\n      'Line width',\n      settings.defaultStrokeWidths,\n      settings.defaultStrokeWidth\n    );\n    this.strokeWidthPanel.onWidthChanged = this.setStrokeWidth;\n\n    this.strokeStylePanel = new LineStylePanel(\n      'Line style',\n      settings.defaultStrokeDasharrays,\n      settings.defaultStrokeDasharray\n    );\n    this.strokeStylePanel.onStyleChanged = this.setStrokeDasharray;\n  }\n\n  /**\n   * Returns true if passed SVG element belongs to the marker. False otherwise.\n   * \n   * @param el - target element.\n   */\n  public ownsTarget(el: EventTarget): boolean {\n    if (\n      super.ownsTarget(el) ||\n      el === this.visual ||\n      el === this.selectorLine ||\n      el === this.visibleLine\n    ) {\n      return true;\n    } else {\n      return false;\n    }\n  }\n\n  private createVisual() {\n    this.visual = SvgHelper.createGroup();\n    this.selectorLine = SvgHelper.createLine(\n      this.x1,\n      this.y1,\n      this.x2,\n      this.y2,\n      [\n        ['stroke', 'transparent'],\n        ['stroke-width', (this.strokeWidth + 10).toString()],\n      ]\n    );\n    this.visibleLine = SvgHelper.createLine(\n      this.x1,\n      this.y1,\n      this.x2,\n      this.y2,\n      [\n        ['stroke', this.strokeColor],\n        ['stroke-width', this.strokeWidth.toString()],\n      ]\n    );\n    this.visual.appendChild(this.selectorLine);\n    this.visual.appendChild(this.visibleLine);\n\n    this.addMarkerVisualToContainer(this.visual);\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) down event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerDown(point: IPoint, target?: EventTarget): void {\n    super.pointerDown(point, target);\n    if (this.state === 'new') {\n      this.createVisual();\n      this.adjustVisual();\n\n      this._state = 'creating';\n    }\n  }\n\n  /**\n   * Adjusts visual after manipulation.\n   */\n  protected adjustVisual(): void {\n    if (this.selectorLine && this.visibleLine) {\n      this.selectorLine.setAttribute('x1', this.x1.toString());\n      this.selectorLine.setAttribute('y1', this.y1.toString());\n      this.selectorLine.setAttribute('x2', this.x2.toString());\n      this.selectorLine.setAttribute('y2', this.y2.toString());\n\n      this.visibleLine.setAttribute('x1', this.x1.toString());\n      this.visibleLine.setAttribute('y1', this.y1.toString());\n      this.visibleLine.setAttribute('x2', this.x2.toString());\n      this.visibleLine.setAttribute('y2', this.y2.toString());\n\n      SvgHelper.setAttributes(this.visibleLine, [['stroke', this.strokeColor]]);\n      SvgHelper.setAttributes(this.visibleLine, [['stroke-width', this.strokeWidth.toString()]]);\n      SvgHelper.setAttributes(this.visibleLine, [['stroke-dasharray', this.strokeDasharray.toString()]]);\n    }\n  }\n\n  /**\n   * Sets line color.\n   * @param color - new color.\n   */\n  protected setStrokeColor(color: string): void {\n    this.strokeColor = color;\n    this.adjustVisual();\n    this.colorChanged(color);\n  }\n  /**\n   * Sets line width.\n   * @param width - new width.\n   */\n  protected setStrokeWidth(width: number): void {\n    this.strokeWidth = width\n    this.adjustVisual();\n  }\n\n  /**\n   * Sets line dash array.\n   * @param dashes - new dash array.\n   */\n  protected setStrokeDasharray(dashes: string): void {\n    this.strokeDasharray = dashes;\n    this.adjustVisual();\n  }\n\n  /**\n   * Returns the list of toolbox panels for this marker type.\n   */\n  public get toolboxPanels(): ToolboxPanel[] {\n    return [this.strokePanel, this.strokeWidthPanel, this.strokeStylePanel];\n  }\n\n  /**\n   * Returns current marker state that can be restored in the future.\n   */\n  public getState(): LineMarkerState {\n    const result: LineMarkerState = Object.assign({\n      strokeColor: this.strokeColor,\n      strokeWidth: this.strokeWidth,\n      strokeDasharray: this.strokeDasharray\n    }, super.getState());\n    result.typeName = LineMarker.typeName;\n\n    return result;\n  }\n\n  /**\n   * Restores previously saved marker state.\n   * \n   * @param state - previously saved state.\n   */\n  public restoreState(state: MarkerBaseState): void {\n    super.restoreState(state);\n\n    const lmState = state as LineMarkerState;\n    this.strokeColor = lmState.strokeColor;\n    this.strokeWidth = lmState.strokeWidth;\n    this.strokeDasharray = lmState.strokeDasharray;\n\n    this.createVisual();\n    this.adjustVisual();\n  }\n}\n","import { Style } from '../../core/Style';\nimport { ToolboxPanel } from '../ToolboxPanel';\nimport Icon from './font-family-panel-icon.svg';\n\n/**\n * Font change event handler type.\n */\nexport type FontChangeHandler = (newFont: string) => void;\n\n/**\n * Font family selection toolbox panel.\n */\nexport class FontFamilyPanel extends ToolboxPanel {\n  private fonts: string[] = [];\n  private currentFont?: string;\n\n  private fontBoxes: HTMLDivElement[] = [];\n\n  /**\n   * Handler for the font family change event.\n   */\n  public onFontChanged?: FontChangeHandler;\n\n  /**\n   * Creates a font family toolbox panel.\n   * @param title - panel title.\n   * @param fonts - available font families.\n   * @param currentFont - currently selected font family.\n   * @param icon - panel button icon (SVG image markup).\n   */\n  constructor(title: string, fonts: string[], currentFont?: string, icon?: string) {\n    super(title, icon ? icon : Icon);\n    this.fonts = fonts;\n    this.currentFont = currentFont;\n\n    this.setCurrentFont = this.setCurrentFont.bind(this);\n  }\n\n  /**\n   * Returns panel UI.\n   */\n  public getUi(): HTMLDivElement {\n    const panelDiv = document.createElement('div');\n    // panelDiv.style.display = 'flex';\n    panelDiv.style.overflow = 'hidden';\n    panelDiv.style.flexGrow = '2';\n    this.fonts.forEach((font) => {\n      const fontBoxContainer = document.createElement('div');\n      fontBoxContainer.style.display = 'inline-block';\n      // fontBoxContainer.style.flexGrow = '2';\n      fontBoxContainer.style.alignItems = 'center';\n      fontBoxContainer.style.justifyContent = 'space-between';\n      fontBoxContainer.style.padding = '5px';\n      fontBoxContainer.style.borderWidth = '2px';\n      fontBoxContainer.style.borderStyle = 'solid';\n      fontBoxContainer.style.overflow = 'hidden';\n      fontBoxContainer.style.maxWidth = `${100 / this.fonts.length - 5}%`;\n      fontBoxContainer.style.borderColor =\n        font === this.currentFont ? Style.settings.toolboxAccentColor : 'transparent';\n\n      fontBoxContainer.addEventListener('click', () => {\n        this.setCurrentFont(font, fontBoxContainer);\n      })\n      panelDiv.appendChild(fontBoxContainer);\n\n      const fontBox = document.createElement('div');\n      fontBox.style.display = 'flex';\n      fontBox.style.minHeight = '20px';\n      fontBox.style.flexGrow = '2';\n      fontBox.style.fontFamily = font;\n      fontBox.style.overflow = 'hidden';\n\n      const fontLabel = document.createElement('div');\n      fontLabel.style.whiteSpace = 'nowrap';\n      fontLabel.style.overflow = 'hidden';\n      fontLabel.style.textOverflow = 'ellipsis';\n      fontLabel.innerHTML = 'The quick brown fox jumps over the lazy dog';\n\n      fontBox.appendChild(fontLabel);\n\n      fontBoxContainer.appendChild(fontBox);\n\n      this.fontBoxes.push(fontBoxContainer);\n    });\n    return panelDiv;\n  }\n\n  private setCurrentFont(newFont: string, target: HTMLDivElement) {\n    this.currentFont = newFont;\n\n    this.fontBoxes.forEach(box => {\n      box.style.borderColor = box === target ? Style.settings.toolboxAccentColor : 'transparent';\n    });\n\n    if (this.onFontChanged) {\n      this.onFontChanged(this.currentFont);\n    }\n  }\n}\n","import { IPoint } from '../../core/IPoint';\nimport { SvgHelper } from '../../core/SvgHelper';\nimport { RectangularBoxMarkerBase } from '../RectangularBoxMarkerBase';\nimport { Settings } from '../../core/Settings';\nimport Icon from './text-marker-icon.svg';\nimport { ColorPickerPanel } from '../../ui/toolbox-panels/ColorPickerPanel';\nimport { ToolboxPanel } from '../../ui/ToolboxPanel';\nimport { FontFamilyPanel } from '../../ui/toolbox-panels/FontFamilyPanel';\nimport { TextMarkerState } from './TextMarkerState';\nimport { MarkerBaseState } from '../../core/MarkerBaseState';\n\nexport class TextMarker extends RectangularBoxMarkerBase {\n  /**\n   * String type name of the marker type.\n   *\n   * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static typeName = 'TextMarker';\n\n  /**\n   * Marker type title (display name) used for accessibility and other attributes.\n   */\n  public static title = 'Text marker';\n  /**\n   * SVG icon markup displayed on toolbar buttons.\n   */\n  public static icon = Icon;\n\n  /**\n   * Text color.\n   */\n  protected color = 'transparent';\n  /**\n   * Text's font family.\n   */\n  protected fontFamily: string;\n  /**\n   * Padding inside of the marker's bounding box in percents.\n   */\n  protected padding = 5;\n\n  /**\n   * Text color picker toolbox panel.\n   */\n  protected colorPanel: ColorPickerPanel;\n  /**\n   * Text font family toolbox panel.\n   */\n  protected fontFamilyPanel: FontFamilyPanel;\n\n  private readonly DEFAULT_TEXT = 'your text here';\n  private text: string = this.DEFAULT_TEXT;\n  /**\n   * Visual text element.\n   */\n  protected textElement: SVGTextElement;\n  /**\n   * Text background rectangle.\n   */\n  protected bgRectangle: SVGRectElement;\n  /**\n   * Div element for the text editor container.\n   */\n  protected textEditDiv: HTMLDivElement;\n  /**\n   * Editable text element.\n   */\n  protected textEditor: HTMLDivElement;\n\n  private isMoved = false;\n  private pointerDownPoint: IPoint;\n  private pointerDownTimestamp: number;\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.\n   * @param settings - settings object containing default markers settings.\n   */\n  constructor(\n    container: SVGGElement,\n    overlayContainer: HTMLDivElement,\n    settings: Settings\n  ) {\n    super(container, overlayContainer, settings);\n\n    this.color = settings.defaultColor;\n    this.fontFamily = settings.defaultFontFamily;\n\n    this.defaultSize = { x: 100, y: 30 };\n\n    this.setColor = this.setColor.bind(this);\n    this.setFont = this.setFont.bind(this);\n    this.renderText = this.renderText.bind(this);\n    this.sizeText = this.sizeText.bind(this);\n    this.textEditDivClicked = this.textEditDivClicked.bind(this);\n    this.showTextEditor = this.showTextEditor.bind(this);\n    this.setSize = this.setSize.bind(this);\n    this.positionTextEditor = this.positionTextEditor.bind(this);\n\n    this.colorPanel = new ColorPickerPanel(\n      'Color',\n      settings.defaultColorSet,\n      settings.defaultColor\n    );\n    this.colorPanel.onColorChanged = this.setColor;\n\n    this.fontFamilyPanel = new FontFamilyPanel(\n      'Font',\n      settings.defaultFontFamilies,\n      settings.defaultFontFamily\n    );\n    this.fontFamilyPanel.onFontChanged = this.setFont;\n  }\n\n  /**\n   * Returns true if passed SVG element belongs to the marker. False otherwise.\n   *\n   * @param el - target element.\n   */\n  public ownsTarget(el: EventTarget): boolean {\n    if (\n      super.ownsTarget(el) ||\n      el === this.visual ||\n      el === this.textElement ||\n      el === this.bgRectangle\n    ) {\n      return true;\n    } else {\n      let found = false;\n      this.textElement.childNodes.forEach((span) => {\n        if (span === el) {\n          found = true;\n        }\n      });\n      return found;\n    }\n  }\n\n  /**\n   * Creates text marker visual.\n   */\n  protected createVisual(): void {\n    this.visual = SvgHelper.createGroup();\n\n    this.bgRectangle = SvgHelper.createRect(1, 1, [['fill', 'transparent']]);\n    this.visual.appendChild(this.bgRectangle);\n\n    this.textElement = SvgHelper.createText([\n      ['fill', this.color],\n      ['font-family', this.fontFamily],\n      ['font-size', '16px'],\n      ['x', '0'],\n      ['y', '0'],\n    ]);\n    this.textElement.transform.baseVal.appendItem(SvgHelper.createTransform()); // translate transorm\n    this.textElement.transform.baseVal.appendItem(SvgHelper.createTransform()); // scale transorm\n\n    this.visual.appendChild(this.textElement);\n\n    this.addMarkerVisualToContainer(this.visual);\n    this.renderText();\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) down event.\n   *\n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerDown(point: IPoint, target?: EventTarget): void {\n    super.pointerDown(point, target);\n\n    this.isMoved = false;\n    this.pointerDownPoint = point;\n    this.pointerDownTimestamp = Date.now();\n\n    if (this.state === 'new') {\n      this.createVisual();\n      this.moveVisual(point);\n      this._state = 'creating';\n    }\n  }\n\n  private renderText() {\n    const LINE_SIZE = '1.2em';\n\n    if (this.textElement) {\n      while (this.textElement.lastChild) {\n        this.textElement.removeChild(this.textElement.lastChild);\n      }\n\n      const lines = this.text.split(/\\r\\n|[\\n\\v\\f\\r\\x85\\u2028\\u2029]/);\n      lines.forEach((line) => {\n        this.textElement.appendChild(\n          SvgHelper.createTSpan(\n            // workaround for swallowed empty lines\n            line.trim() === '' ? ' ' : line.trim(), [\n            ['x', '0'],\n            ['dy', LINE_SIZE],\n          ])\n        );\n      });\n\n      setTimeout(this.sizeText, 10);\n    }\n  }\n\n  private getTextScale(): number {\n    const textSize = this.textElement.getBBox();\n    let scale = 1.0;\n    if (textSize.width > 0 && textSize.height > 0) {\n      const xScale =\n        (this.width * 1.0 - (this.width * this.padding * 2) / 100) /\n        textSize.width;\n      const yScale =\n        (this.height * 1.0 - (this.height * this.padding * 2) / 100) /\n        textSize.height;\n      scale = Math.min(xScale, yScale);\n    }\n    return scale;\n  }\n\n  private getTextPosition(scale: number): IPoint {\n    const textSize = this.textElement.getBBox();\n    let x = 0;\n    let y = 0;\n    if (textSize.width > 0 && textSize.height > 0) {\n      x = (this.width - textSize.width * scale) / 2;\n      y = this.height / 2 - (textSize.height * scale) / 2;\n    }\n    return { x: x, y: y };\n  }\n\n  private sizeText() {\n    const textBBox = this.textElement.getBBox();\n    const scale = this.getTextScale();\n    const position = this.getTextPosition(scale);\n    position.y -= textBBox.y * scale; // workaround adjustment for text not being placed at y=0\n\n    if (navigator.userAgent.indexOf('Edge/') > -1) {\n      // workaround for legacy Edge as transforms don't work otherwise but this way it doesn't work in Safari\n      this.textElement.style.transform = `translate(${position.x}px, ${position.y}px) scale(${scale}, ${scale})`;\n    } else {\n      this.textElement.transform.baseVal\n        .getItem(0)\n        .setTranslate(position.x, position.y);\n      this.textElement.transform.baseVal.getItem(1).setScale(scale, scale);\n    }\n  }\n\n  /**\n   * Handles marker manipulation (move, resize, rotate, etc.).\n   *\n   * @param point - event coordinates.\n   */\n  public manipulate(point: IPoint): void {\n    super.manipulate(point);\n    if (this.pointerDownPoint !== undefined) {\n      this.isMoved =\n        Math.abs(point.x - this.pointerDownPoint.x) > 5 ||\n        Math.abs(point.y - this.pointerDownPoint.y) > 5;\n    }\n  }\n\n  /**\n   * Resize marker based on current pointer coordinates and context.\n   * @param point\n   */\n  protected resize(point: IPoint): void {\n    super.resize(point);\n    this.isMoved = true;\n    this.setSize();\n    this.sizeText();\n  }\n\n  /**\n   * Sets size of marker elements after manipulation.\n   */\n  protected setSize(): void {\n    super.setSize();\n    if (this.visual && this.bgRectangle) {\n      SvgHelper.setAttributes(this.visual, [\n        ['width', this.width.toString()],\n        ['height', this.height.toString()],\n      ]);\n      SvgHelper.setAttributes(this.bgRectangle, [\n        ['width', this.width.toString()],\n        ['height', this.height.toString()],\n      ]);\n    }\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) up event.\n   *\n   * @param point - event coordinates.\n   */\n  public pointerUp(point: IPoint): void {\n    const inState = this.state;\n    super.pointerUp(point);\n    this.setSize();\n    if (\n      inState === 'creating' ||\n      (!this.isMoved && Date.now() - this.pointerDownTimestamp > 500)\n    ) {\n      this.showTextEditor();\n    }\n    this.pointerDownPoint = undefined;\n  }\n\n  private showTextEditor() {\n    this._state = 'edit';\n    this.overlayContainer.innerHTML = '';\n\n    this.textEditDiv = document.createElement('div');\n    // textEditDiv.style.display = 'flex';\n    this.textEditDiv.style.flexGrow = '2';\n    //textEditDiv.style.backgroundColor = 'rgb(0,0,0,0.7)';\n    this.textEditDiv.style.alignItems = 'center';\n    this.textEditDiv.style.justifyContent = 'center';\n    this.textEditDiv.style.pointerEvents = 'auto';\n    this.textEditDiv.style.overflow = 'hidden';\n\n    this.textEditor = document.createElement('div');\n    this.textEditor.style.position = 'absolute';\n    this.textEditor.style.fontFamily = this.fontFamily;\n    this.textEditor.style.lineHeight = '1em';\n    this.textEditor.innerText = this.text;\n    this.textEditor.contentEditable = 'true';\n    this.textEditor.style.color = this.color;\n    this.textEditor.style.whiteSpace = 'pre';\n    this.positionTextEditor();\n    this.textEditor.addEventListener('pointerup', (ev) => {\n      ev.stopPropagation();\n    });\n    this.textEditor.addEventListener('input', () => {\n      let fontSize = Number.parseFloat(this.textEditor.style.fontSize);\n      while (\n        this.textEditor.clientWidth >=\n          Number.parseInt(this.textEditor.style.maxWidth) &&\n        fontSize > 0.9\n      ) {\n        fontSize -= 0.1;\n        this.textEditor.style.fontSize = `${Math.max(fontSize, 0.9)}em`;\n      }\n    });\n    this.textEditor.addEventListener('keyup', (ev) => {\n      ev.cancelBubble = true;\n    });\n    this.textEditor.addEventListener('paste', (ev) => {\n      if (ev.clipboardData) {\n        // paste plain text\n        const content = ev.clipboardData.getData('text');\n        const selection = window.getSelection();\n        if (!selection.rangeCount) return false;\n        selection.deleteFromDocument();\n        selection.getRangeAt(0).insertNode(document.createTextNode(content));\n        ev.preventDefault();\n      }\n    });\n\n    this.textEditDiv.addEventListener('pointerup', () => {\n      this.textEditDivClicked(this.textEditor.innerText);\n    });\n    this.textEditDiv.appendChild(this.textEditor);\n    this.overlayContainer.appendChild(this.textEditDiv);\n\n    this.hideVisual();\n\n    this.textEditor.focus();\n    document.execCommand('selectAll');\n  }\n\n  private positionTextEditor() {\n    if (this.state === 'edit') {\n      if (this.textEditor === undefined) {\n        this.showTextEditor();\n      } else {\n        this.textElement.style.display = '';\n        const textScale = this.getTextScale();\n        // const textPosition = this.getTextPosition(textScale);\n        const rPosition = this.rotatePoint({\n          x: this.left + this.width / 2,\n          y: this.top + this.height / 2,\n        });\n        const textSize = this.textElement.getBBox();\n        const rWH = {\n          x: textSize.width * textScale,\n          y: textSize.height * textScale,\n        };\n        rPosition.x -= rWH.x / 2;\n        rPosition.y -= rWH.y / 2;\n\n        this.textEditor.style.top = `${rPosition.y}px`;\n        this.textEditor.style.left = `${rPosition.x}px`;\n        this.textEditor.style.maxWidth = `${\n          this.overlayContainer.offsetWidth - rPosition.x\n        }px`;\n        this.textEditor.style.fontSize = `${Math.max(16 * textScale, 12)}px`;\n        this.textElement.style.display = 'none';\n      }\n    }\n  }\n\n  private textEditDivClicked(text: string) {\n    this.text = text.trim();\n    this.overlayContainer.innerHTML = '';\n    this.renderText();\n    this.showVisual();\n  }\n\n  /**\n   * Deselects this marker, renders text (if necessary), and hides selected marker UI.\n   */\n  public deselect(): void {\n    if (this.state === 'edit') {\n      this.textEditDivClicked(this.textEditor.innerText);\n    }\n    super.deselect();\n  }\n\n  /**\n   * Opens text editor on double-click.\n   * @param point\n   * @param target\n   */\n  public dblClick(point: IPoint, target?: EventTarget): void {\n    super.dblClick(point, target);\n\n    this.showTextEditor();\n  }\n\n  /**\n   * Sets text color.\n   * @param color - new text color.\n   */\n  protected setColor(color: string): void {\n    if (this.textElement) {\n      SvgHelper.setAttributes(this.textElement, [['fill', color]]);\n    }\n    this.color = color;\n    if (this.textEditor) {\n      this.textEditor.style.color = this.color;\n    }\n    this.colorChanged(color);\n  }\n\n  /**\n   * Sets font family.\n   * @param font - new font family.\n   */\n  protected setFont(font: string): void {\n    if (this.textElement) {\n      SvgHelper.setAttributes(this.textElement, [['font-family', font]]);\n    }\n    this.fontFamily = font;\n    if (this.textEditor) {\n      this.textEditor.style.fontFamily = this.fontFamily;\n    }\n    this.renderText();\n  }\n\n  /**\n   * Hides marker visual.\n   */\n  protected hideVisual(): void {\n    this.textElement.style.display = 'none';\n    this.hideControlBox();\n  }\n  /**\n   * Shows marker visual.\n   */\n  protected showVisual(): void {\n    if (this.state === 'edit') {\n      this._state = 'select';\n    }\n    this.textElement.style.display = '';\n    this.showControlBox();\n  }\n\n  /**\n   * Returns the list of toolbox panels for this marker type.\n   */\n  public get toolboxPanels(): ToolboxPanel[] {\n    return [this.colorPanel, this.fontFamilyPanel];\n  }\n\n  /**\n   * Returns current marker state that can be restored in the future.\n   */\n  public getState(): TextMarkerState {\n    const result: TextMarkerState = Object.assign(\n      {\n        color: this.color,\n        fontFamily: this.fontFamily,\n        padding: this.padding,\n        text: this.text,\n      },\n      super.getState()\n    );\n    result.typeName = TextMarker.typeName;\n\n    return result;\n  }\n\n  /**\n   * Restores previously saved marker state.\n   *\n   * @param state - previously saved state.\n   */\n  public restoreState(state: MarkerBaseState): void {\n    const textState = state as TextMarkerState;\n    this.color = textState.color;\n    this.fontFamily = textState.fontFamily;\n    this.padding = textState.padding;\n    this.text = textState.text;\n\n    this.createVisual();\n    super.restoreState(state);\n    this.setSize();\n  }\n\n  /**\n   * Scales marker. Used after the image resize.\n   *\n   * @param scaleX - horizontal scale\n   * @param scaleY - vertical scale\n   */\n  public scale(scaleX: number, scaleY: number): void {\n    super.scale(scaleX, scaleY);\n\n    this.setSize();\n    this.sizeText();\n    this.positionTextEditor();\n  }\n}\n","import { IPoint } from '../../core/IPoint';\nimport { SvgHelper } from '../../core/SvgHelper';\nimport { RectangularBoxMarkerBase } from '../RectangularBoxMarkerBase';\nimport { Settings } from '../../core/Settings';\nimport Icon from './freehand-marker-icon.svg';\nimport { ColorPickerPanel } from '../../ui/toolbox-panels/ColorPickerPanel';\nimport { ToolboxPanel } from '../../ui/ToolboxPanel';\nimport { FreehandMarkerState } from './FreehandMarkerState';\nimport { MarkerBaseState } from '../../core/MarkerBaseState';\nimport { LineWidthPanel } from '../../ui/toolbox-panels/LineWidthPanel';\n\n\nexport class FreehandMarker extends RectangularBoxMarkerBase {\n  /**\n   * String type name of the marker type. \n   * \n   * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static typeName = 'FreehandMarker';\n\n  /**\n   * Marker type title (display name) used for accessibility and other attributes.\n   */\n  public static title = 'Freehand marker';\n  /**\n   * SVG icon markup displayed on toolbar buttons.\n   */\n  public static icon = Icon;\n\n  /**\n   * Marker color.\n   */\n  protected color = 'transparent';\n  /**\n   * Marker's stroke width.\n   */\n  protected lineWidth = 3;\n\n  private colorPanel: ColorPickerPanel;\n  private lineWidthPanel: LineWidthPanel;\n\n\n  private canvasElement: HTMLCanvasElement;\n  private canvasContext: CanvasRenderingContext2D;\n\n  private drawingImage: SVGImageElement;\n  private drawingImgUrl: string;\n\n  private drawing = false;\n\n  private pixelRatio = 1;\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.\n   * @param settings - settings object containing default markers settings.\n   */\n  constructor(\n    container: SVGGElement,\n    overlayContainer: HTMLDivElement,\n    settings: Settings\n  ) {\n    super(container, overlayContainer, settings);\n\n    this.color = settings.defaultColor;\n    this.lineWidth = settings.defaultStrokeWidth;\n    this.pixelRatio = settings.freehandPixelRatio;\n\n    this.setColor = this.setColor.bind(this);\n    this.addCanvas = this.addCanvas.bind(this);\n    this.finishCreation = this.finishCreation.bind(this);\n    this.setLineWidth = this.setLineWidth.bind(this);\n\n    this.colorPanel = new ColorPickerPanel(\n      'Color',\n      settings.defaultColorSet,\n      settings.defaultColor\n    );\n    this.colorPanel.onColorChanged = this.setColor;\n\n    this.lineWidthPanel = new LineWidthPanel(\n      'Line width',\n      settings.defaultStrokeWidths,\n      settings.defaultStrokeWidth\n    );\n    this.lineWidthPanel.onWidthChanged = this.setLineWidth;\n\n  }\n\n  /**\n   * Returns true if passed SVG element belongs to the marker. False otherwise.\n   * \n   * @param el - target element.\n   */\n  public ownsTarget(el: EventTarget): boolean {\n    if (\n      super.ownsTarget(el) ||\n      el === this.visual ||\n      el === this.drawingImage\n    ) {\n      return true;\n    } else {\n      return false;\n    }\n  }\n\n  private createVisual() {\n    this.visual = SvgHelper.createGroup();\n    this.drawingImage = SvgHelper.createImage();\n    this.visual.appendChild(this.drawingImage);\n\n    const translate = SvgHelper.createTransform();\n    this.visual.transform.baseVal.appendItem(translate);\n    this.addMarkerVisualToContainer(this.visual);\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) down event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerDown(point: IPoint, target?: EventTarget): void {\n    if (this.state === 'new') {\n      this.addCanvas();\n\n      this.createVisual();\n\n      this._state = 'creating';\n    }\n\n    if (this.state === 'creating') {\n      this.canvasContext.strokeStyle = this.color;\n      this.canvasContext.lineWidth = this.lineWidth;\n      this.canvasContext.beginPath();\n      this.canvasContext.moveTo(point.x, point.y);\n      this.drawing = true;\n    } else {\n      super.pointerDown(point, target);\n    }\n  }\n\n  /**\n   * Handles marker manipulation (move, resize, rotate, etc.).\n   * \n   * @param point - event coordinates.\n   */\n  public manipulate(point: IPoint): void {\n    if (this.state === 'creating') {\n      if (this.drawing) {\n        this.canvasContext.lineTo(point.x, point.y);\n        this.canvasContext.stroke();\n      }\n    } else {\n      super.manipulate(point);\n    }\n  }\n\n  /**\n   * Resize marker based on current pointer coordinates and context.\n   * @param point \n   */\n  protected resize(point: IPoint): void {\n    super.resize(point);\n    SvgHelper.setAttributes(this.visual, [\n      ['width', this.width.toString()],\n      ['height', this.height.toString()],\n    ]);\n    SvgHelper.setAttributes(this.drawingImage, [\n      ['width', this.width.toString()],\n      ['height', this.height.toString()],\n    ]);\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) up event.\n   * \n   * @param point - event coordinates.\n   */\n  public pointerUp(point: IPoint): void {\n    if (this._state === 'creating') {\n      if (this.drawing) {\n        this.canvasContext.closePath();\n        this.drawing = false;\n        if (this.globalSettings.newFreehandMarkerOnPointerUp) {\n          this.finishCreation();\n        }\n      }\n    } else {\n      super.pointerUp(point);\n    }\n  }\n\n  private addCanvas() {\n    this.overlayContainer.innerHTML = '';\n\n    this.canvasElement = document.createElement('canvas');\n    this.canvasElement.width = this.overlayContainer.clientWidth * this.pixelRatio;\n    this.canvasElement.height = this.overlayContainer.clientHeight * this.pixelRatio;\n    this.canvasContext = this.canvasElement.getContext('2d');\n    this.canvasContext.scale(this.pixelRatio, this.pixelRatio);\n    this.overlayContainer.appendChild(this.canvasElement);\n  }\n\n  /**\n   * Selects this marker and displays appropriate selected marker UI.\n   */\n  public select(): void {\n    if (this.state === 'creating') {\n      this.finishCreation();\n    }\n    super.select();\n  }\n\n  /**\n   * Deselects this marker and hides selected marker UI.\n   */\n  public deselect(): void {\n    if (this.state === 'creating') {\n      this.finishCreation();\n    }\n    super.deselect();\n  }\n\n  private finishCreation() {\n    const imgData = this.canvasContext.getImageData(\n      0,\n      0,\n      this.canvasElement.width,\n      this.canvasElement.height\n    );\n\n    let [startX, startY, endX, endY] = [\n      this.canvasElement.width + 1,\n      this.canvasElement.height + 1,\n      -1,\n      -1,\n    ];\n    let containsData = false;\n    for (let row = 0; row < this.canvasElement.height; row++) {\n      for (let col = 0; col < this.canvasElement.width; col++) {\n        const pixAlpha =\n          imgData.data[row * this.canvasElement.width * 4 + col * 4 + 3];\n        if (pixAlpha > 0) {\n          containsData = true;\n          if (row < startY) {\n            startY = row;\n          }\n          if (col < startX) {\n            startX = col;\n          }\n          if (row > endY) {\n            endY = row;\n          }\n          if (col > endX) {\n            endX = col;\n          }\n        }\n      }\n    }\n\n    if (containsData) {\n      this.left = startX / this.pixelRatio;\n      this.top = startY / this.pixelRatio;\n      this.width = (endX - startX) / this.pixelRatio;\n      this.height = (endY - startY) / this.pixelRatio;\n\n      const tmpCanvas = document.createElement('canvas');\n      tmpCanvas.width = endX - startX;\n      tmpCanvas.height = endY - startY;\n      const tmpCtx = tmpCanvas.getContext('2d');\n      tmpCtx.putImageData(\n        this.canvasContext.getImageData(\n          startX,\n          startY,\n          endX - startX,\n          endY - startY\n        ),\n        0,\n        0\n      );\n\n      this.drawingImgUrl = tmpCanvas.toDataURL('image/png');\n      this.setDrawingImage();\n\n      this._state = 'select';\n      if (this.onMarkerCreated) {\n        this.onMarkerCreated(this);\n      }\n    }\n    this.overlayContainer.innerHTML = '';\n  }\n\n  private setDrawingImage() {\n    SvgHelper.setAttributes(this.drawingImage, [\n      ['width', this.width.toString()],\n      ['height', this.height.toString()],\n    ]);\n    SvgHelper.setAttributes(this.drawingImage, [['href', this.drawingImgUrl]]);\n    this.moveVisual({ x: this.left, y: this.top });\n  }\n\n  /**\n   * Sets marker drawing color.\n   * @param color - new color.\n   */\n  protected setColor(color: string): void {\n    this.color = color;\n    this.colorChanged(color);\n  }\n\n  /**\n   * Sets line width.\n   * @param width - new line width\n   */\n   protected setLineWidth(width: number): void {\n    this.lineWidth = width;\n  }\n\n\n  /**\n   * Returns the list of toolbox panels for this marker type.\n   */\n  public get toolboxPanels(): ToolboxPanel[] {\n    if (this.state === 'new' || this.state === 'creating') {\n      return [this.colorPanel, this.lineWidthPanel];\n    } else {\n      return [];\n    }\n  }\n\n  /**\n   * Returns current marker state that can be restored in the future.\n   */\n  public getState(): FreehandMarkerState {\n    const result: FreehandMarkerState = Object.assign({\n      drawingImgUrl: this.drawingImgUrl\n    }, super.getState());\n    result.typeName = FreehandMarker.typeName;\n\n    return result;\n  }\n\n  /**\n   * Restores previously saved marker state.\n   * \n   * @param state - previously saved state.\n   */\n  public restoreState(state: MarkerBaseState): void {\n    this.createVisual();\n    super.restoreState(state);\n    this.drawingImgUrl = (state as FreehandMarkerState).drawingImgUrl;\n    this.setDrawingImage();\n  }\n\n  /**\n   * Scales marker. Used after the image resize.\n   * \n   * @param scaleX - horizontal scale\n   * @param scaleY - vertical scale\n   */\n  public scale(scaleX: number, scaleY: number): void {\n    super.scale(scaleX, scaleY);\n\n    this.setDrawingImage();\n  }\n\n}\n","import { Style } from '../../core/Style';\nimport { ToolboxPanel } from '../ToolboxPanel';\nimport Icon from './arrow-type-panel-icon.svg';\n\n/**\n * Represents available arrow types.\n * \n * - `both` - arrow tips on both sides.\n * - `start` - arrow tip on the starting point of line.\n * - `end` - arrow tip on the ending point of line.\n * - `none` - no arrow tips.\n */\nexport type ArrowType = 'both' | 'start' | 'end' | 'none';\n/**\n * Handler for arrow type change event.\n */\nexport type ArrowTypeChangeHandler = (newType: ArrowType) => void;\n\n/**\n * Arrow type selection panel.\n */\nexport class ArrowTypePanel extends ToolboxPanel {\n  private currentType?: ArrowType;\n\n  private typeBoxes: HTMLDivElement[] = [];\n\n  /**\n   * Event handler for the arrow type change event.\n   */\n  public onArrowTypeChanged?: ArrowTypeChangeHandler;\n\n  /**\n   * Creates an ArrowTypePanel.\n   * @param title - panel title.\n   * @param currentType - currently set arrow type.\n   * @param icon - panel button icon (SVG image markup).\n   */\n  constructor(title: string, currentType?: ArrowType, icon?: string) {\n    super(title, icon ? icon : Icon);\n    this.currentType = currentType;\n\n    this.setCurrentType = this.setCurrentType.bind(this);\n  }\n\n  /**\n   * Returns panel UI.\n   */\n  public getUi(): HTMLDivElement {\n    const panelDiv = document.createElement('div');\n    panelDiv.style.display = 'flex';\n    panelDiv.style.overflow = 'hidden';\n    panelDiv.style.flexGrow = '2';\n    for (let ti = 0; ti < 4; ti++) {\n      let arrowType: ArrowType = 'both';\n      switch(ti) {\n        case 0:\n          arrowType = 'both';\n          break;\n        case 1:\n          arrowType = 'start';\n          break;\n        case 2:\n          arrowType = 'end';\n          break;\n        case 3:\n          arrowType = 'none';\n          break;\n      }\n      const typeBoxContainer = document.createElement('div');\n      typeBoxContainer.style.display = 'flex';\n      typeBoxContainer.style.flexGrow = '2';\n      typeBoxContainer.style.alignItems = 'center';\n      typeBoxContainer.style.justifyContent = 'space-between';\n      typeBoxContainer.style.padding = '5px';\n      typeBoxContainer.style.borderWidth = '2px';\n      typeBoxContainer.style.borderStyle = 'solid';\n      typeBoxContainer.style.borderColor =\n        arrowType === this.currentType ? Style.settings.toolboxAccentColor : 'transparent';\n\n      typeBoxContainer.addEventListener('click', () => {\n        this.setCurrentType(arrowType, typeBoxContainer);\n      })\n      panelDiv.appendChild(typeBoxContainer);\n\n      if (arrowType === 'both' || arrowType === 'start') {\n        const leftTip = document.createElement('div');\n        leftTip.style.display = 'flex';\n        leftTip.style.alignItems = 'center';\n        leftTip.style.minHeight = '20px';\n        leftTip.innerHTML = `<svg viewBox=\"0 0 10 10\" width=\"10\" height=\"10\" xmlns=\"http://www.w3.org/2000/svg\">\n          <polygon points=\"0,5 10,0 10,10\" fill=\"${Style.settings.toolboxColor}\" />\n        </svg>`;\n        leftTip.style.marginLeft = '5px';\n        typeBoxContainer.appendChild(leftTip);\n      }\n\n      const lineBox = document.createElement('div');\n      lineBox.style.display = 'flex';\n      lineBox.style.alignItems = 'center';\n      lineBox.style.minHeight = '20px';\n      lineBox.style.flexGrow = '2';\n\n      const hr = document.createElement('hr');\n      hr.style.minWidth = '20px';\n      hr.style.border = '0px';\n      hr.style.borderTop = `3px solid ${Style.settings.toolboxColor}`;\n      hr.style.flexGrow = '2';\n      lineBox.appendChild(hr);\n\n      typeBoxContainer.appendChild(lineBox);\n\n      if (arrowType === 'both' || arrowType === 'end') {\n        const rightTip = document.createElement('div');\n        rightTip.style.display = 'flex';\n        rightTip.style.alignItems = 'center';\n        rightTip.style.minHeight = '20px';\n        rightTip.innerHTML = `<svg viewBox=\"0 0 10 10\" width=\"10\" height=\"10\" xmlns=\"http://www.w3.org/2000/svg\">\n          <polygon points=\"0,0 10,5 0,10\" fill=\"${Style.settings.toolboxColor}\" />\n        </svg>`;\n        rightTip.style.marginRight = '5px';\n        typeBoxContainer.appendChild(rightTip);\n      }\n\n      this.typeBoxes.push(typeBoxContainer);\n    }\n    return panelDiv;\n  }\n\n  private setCurrentType(newType: ArrowType, target: HTMLDivElement) {\n    this.currentType = newType;\n\n    this.typeBoxes.forEach(box => {\n      box.style.borderColor = box === target ? Style.settings.toolboxAccentColor : 'transparent';\n    });\n\n    if (this.onArrowTypeChanged) {\n      this.onArrowTypeChanged(this.currentType);\n    }\n  }\n}\n","import { IPoint } from '../../core/IPoint';\nimport { SvgHelper } from '../../core/SvgHelper';\nimport { Settings } from '../../core/Settings';\nimport Icon from './arrow-marker-icon.svg';\nimport { ToolboxPanel } from '../../ui/ToolboxPanel';\nimport { LineMarker } from '../line-marker/LineMarker';\nimport { ArrowType, ArrowTypePanel } from '../../ui/toolbox-panels/ArrowTypePanel';\nimport { ArrowMarkerState } from './ArrowMarkerState';\nimport { MarkerBaseState } from '../../core/MarkerBaseState';\n\n/**\n * Represents an arrow marker.\n */\nexport class ArrowMarker extends LineMarker {\n  /**\n   * String type name of the marker type. \n   * \n   * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static typeName = 'ArrowMarker';\n\n  /**\n   * Marker type title (display name) used for accessibility and other attributes.\n   */\n  public static title = 'Arrow marker';\n  /**\n   * SVG icon markup displayed on toolbar buttons.\n   */\n  public static icon = Icon;\n\n  private arrow1: SVGPolygonElement;\n  private arrow2: SVGPolygonElement;\n\n  private arrowType: ArrowType = 'end';\n\n  private arrowBaseHeight = 10;\n  private arrowBaseWidth = 10;\n\n  /**\n   * Toolbox panel for arrow type selection.\n   */\n  protected arrowTypePanel: ArrowTypePanel;\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.\n   * @param settings - settings object containing default markers settings.\n   */\n  constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings) {\n    super(container, overlayContainer, settings);\n\n    this.getArrowPoints = this.getArrowPoints.bind(this);\n    this.setArrowType = this.setArrowType.bind(this);\n\n    this.arrowTypePanel = new ArrowTypePanel('Arrow type', 'end');\n    this.arrowTypePanel.onArrowTypeChanged = this.setArrowType;\n  }\n\n  /**\n   * Returns true if passed SVG element belongs to the marker. False otherwise.\n   * \n   * @param el - target element.\n   */\n  public ownsTarget(el: EventTarget): boolean {\n    if (\n      super.ownsTarget(el) ||\n      el === this.arrow1 || el === this.arrow2\n    ) {\n      return true;\n    } else {\n      return false;\n    }\n  }\n\n  private getArrowPoints(offsetX: number, offsetY: number): string {\n    const width = this.arrowBaseWidth + this.strokeWidth * 2;\n    const height = this.arrowBaseHeight + this.strokeWidth * 2;\n    return `${offsetX - width / 2},${\n      offsetY + height / 2\n    } ${offsetX},${offsetY - height / 2} ${\n      offsetX + width / 2},${offsetY + height / 2}`;\n  }\n\n  private createTips() {\n    this.arrow1 = SvgHelper.createPolygon(this.getArrowPoints(this.x1, this.y1), [['fill', this.strokeColor]]);\n    this.arrow1.transform.baseVal.appendItem(SvgHelper.createTransform());\n    this.visual.appendChild(this.arrow1);\n\n    this.arrow2 = SvgHelper.createPolygon(this.getArrowPoints(this.x2, this.y2), [['fill', this.strokeColor]]);\n    this.arrow2.transform.baseVal.appendItem(SvgHelper.createTransform());\n    this.visual.appendChild(this.arrow2);\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) down event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerDown(point: IPoint, target?: EventTarget): void {\n    super.pointerDown(point, target);\n    if (this.state === 'creating') {\n      this.createTips();\n    }\n  }\n\n  /**\n   * Adjusts marker visual after manipulation.\n   */\n  protected adjustVisual(): void {\n    super.adjustVisual();\n\n    if (this.arrow1 && this.arrow2) {\n      this.arrow1.style.display = (this.arrowType === 'both' || this.arrowType === 'start') ? '' : 'none';\n      this.arrow2.style.display = (this.arrowType === 'both' || this.arrowType === 'end') ? '' : 'none';\n\n      SvgHelper.setAttributes(this.arrow1, [\n        ['points', this.getArrowPoints(this.x1, this.y1)],\n        ['fill', this.strokeColor]\n      ]);\n      SvgHelper.setAttributes(this.arrow2, [\n        ['points', this.getArrowPoints(this.x2, this.y2)],\n        ['fill', this.strokeColor]\n      ]);\n\n      if (Math.abs(this.x1 - this.x2) > 0.1) {\n        const lineAngle1 =\n          (Math.atan((this.y2 - this.y1) / (this.x2 - this.x1)) * 180) / Math.PI + 90 * Math.sign(this.x1 - this.x2);\n\n        const a1transform = this.arrow1.transform.baseVal.getItem(0);\n        a1transform.setRotate(lineAngle1, this.x1, this.y1);\n        this.arrow1.transform.baseVal.replaceItem(a1transform, 0);\n\n        const a2transform = this.arrow2.transform.baseVal.getItem(0);\n        a2transform.setRotate(lineAngle1 + 180, this.x2, this.y2);\n        this.arrow2.transform.baseVal.replaceItem(a2transform, 0);\n      }\n    }\n  }\n\n  private setArrowType(arrowType: ArrowType) {\n    this.arrowType = arrowType;\n    this.adjustVisual();\n  }\n\n  /**\n   * Returns the list of toolbox panels for this marker type.\n   */\n  public get toolboxPanels(): ToolboxPanel[] {\n    return [this.strokePanel, this.strokeWidthPanel, this.strokeStylePanel, this.arrowTypePanel];\n  }\n\n  /**\n   * Returns current marker state that can be restored in the future.\n   */\n  public getState(): ArrowMarkerState {\n    const result: ArrowMarkerState = Object.assign({\n      arrowType: this.arrowType\n    }, super.getState());\n    result.typeName = ArrowMarker.typeName;\n\n    return result;\n  }\n\n  /**\n   * Restores previously saved marker state.\n   * \n   * @param state - previously saved state.\n   */\n  public restoreState(state: MarkerBaseState): void {\n    super.restoreState(state);\n\n    const amState = state as ArrowMarkerState;\n    this.arrowType = amState.arrowType;\n\n    this.createTips();\n    this.adjustVisual();\n  }\n\n}\n","import Icon from './cover-marker-icon.svg';\nimport { ToolboxPanel } from '../../ui/ToolboxPanel';\nimport { ColorPickerPanel } from '../../ui/toolbox-panels/ColorPickerPanel';\nimport { Settings } from '../../core/Settings';\nimport { RectangleMarker } from '../RectangleMarker';\nimport { RectangleMarkerState } from '../RectangleMarkerState';\n\nexport class CoverMarker extends RectangleMarker {\n  /**\n   * String type name of the marker type. \n   * \n   * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static typeName = 'CoverMarker';\n\n  /**\n   * Marker type title (display name) used for accessibility and other attributes.\n   */\n  public static title = 'Cover marker';\n  /**\n   * SVG icon markup displayed on toolbar buttons.\n   */\n  public static icon = Icon;\n\n  /**\n   * Color picker panel for the background color.\n   */\n  protected fillPanel: ColorPickerPanel;\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.\n   * @param settings - settings object containing default markers settings.\n   */\n  constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings) {\n    super(container, overlayContainer, settings);\n\n    this.fillColor = settings.defaultFillColor;\n    this.strokeWidth = 0;\n\n    this.fillPanel = new ColorPickerPanel(\n      'Color',\n      settings.defaultColorSet,\n      settings.defaultFillColor\n    );\n    this.fillPanel.onColorChanged = this.setFillColor;\n  }\n\n  /**\n   * Returns the list of toolbox panels for this marker type.\n   */\n  public get toolboxPanels(): ToolboxPanel[] {\n    return [this.fillPanel];\n  }\n\n  /**\n   * Returns current marker state that can be restored in the future.\n   */\n  public getState(): RectangleMarkerState {\n    const result = super.getState();\n    result.typeName = CoverMarker.typeName;\n    return result;\n  }\n}\n","import { Style } from '../../core/Style';\nimport { ToolboxPanel } from '../ToolboxPanel';\nimport Icon from './opacity-panel-icon.svg';\n\n/**\n * Opacity chage event handler type.\n */\nexport type OpacityChangeHandler = (newOpacity: number) => void;\n\n/**\n * Opacity panel.\n */\nexport class OpacityPanel extends ToolboxPanel {\n  private opacities: number[] = [];\n  private currentOpacity?: number;\n\n  private opacityBoxes: HTMLDivElement[] = [];\n\n  /**\n   * Opacity change event handler.\n   */\n  public onOpacityChanged?: OpacityChangeHandler;\n\n  /**\n   * Creates an opacity panel.\n   * @param title - panel title.\n   * @param opacities - available opacities.\n   * @param currentOpacity - current opacity.\n   * @param icon - toolbox panel button (SVG image markup).\n   */\n  constructor(title: string, opacities: number[], currentOpacity?: number, icon?: string) {\n    super(title, icon ? icon : Icon);\n    this.opacities = opacities;\n    this.currentOpacity = currentOpacity;\n\n    this.setCurrentOpacity = this.setCurrentOpacity.bind(this);\n  }\n\n  /**\n   * Returns panel UI.\n   */\n  public getUi(): HTMLDivElement {\n    const panelDiv = document.createElement('div');\n    panelDiv.style.display = 'flex';\n    panelDiv.style.overflow = 'hidden';\n    panelDiv.style.flexGrow = '2';\n    panelDiv.style.justifyContent = 'space-between';\n    this.opacities.forEach((opacity) => {\n      const opacityBoxContainer = document.createElement('div');\n      opacityBoxContainer.style.display = 'flex';\n      //opacityBoxContainer.style.flexGrow = '2';\n      opacityBoxContainer.style.alignItems = 'center';\n      opacityBoxContainer.style.justifyContent = 'center';\n      opacityBoxContainer.style.padding = '5px';\n      opacityBoxContainer.style.borderWidth = '2px';\n      opacityBoxContainer.style.borderStyle = 'solid';\n      opacityBoxContainer.style.borderColor =\n        opacity === this.currentOpacity ? Style.settings.toolboxAccentColor : 'transparent';\n\n      opacityBoxContainer.addEventListener('click', () => {\n        this.setCurrentOpacity(opacity, opacityBoxContainer);\n      })\n      panelDiv.appendChild(opacityBoxContainer);\n\n      const label = document.createElement('div');\n      label.innerText = `${(opacity * 100)}%`;\n      opacityBoxContainer.appendChild(label);\n\n      this.opacityBoxes.push(opacityBoxContainer);\n    });\n    return panelDiv;\n  }\n\n  private setCurrentOpacity(newWidth: number, target: HTMLDivElement) {\n    this.currentOpacity = newWidth;\n\n    this.opacityBoxes.forEach(box => {\n      box.style.borderColor = box === target ? Style.settings.toolboxAccentColor : 'transparent';\n    });\n\n    if (this.onOpacityChanged) {\n      this.onOpacityChanged(this.currentOpacity);\n    }\n  }\n}\n","import Icon from './highlight-marker-icon.svg';\nimport { ToolboxPanel } from '../../ui/ToolboxPanel';\nimport { ColorPickerPanel } from '../../ui/toolbox-panels/ColorPickerPanel';\nimport { Settings } from '../../core/Settings';\nimport { CoverMarker } from '../cover-marker/CoverMarker';\nimport { OpacityPanel } from '../../ui/toolbox-panels/OpacityPanel';\nimport { SvgHelper } from '../../core/SvgHelper';\nimport { RectangleMarkerState } from '../RectangleMarkerState';\n\nexport class HighlightMarker extends CoverMarker {\n  /**\n   * String type name of the marker type. \n   * \n   * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static typeName = 'HighlightMarker';\n  /**\n   * Marker type title (display name) used for accessibility and other attributes.\n   */\n  public static title = 'Highlight marker';\n  /**\n   * SVG icon markup displayed on toolbar buttons.\n   */\n  public static icon = Icon;\n\n  protected opacityPanel: OpacityPanel;\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.\n   * @param settings - settings object containing default markers settings.\n   */\n  constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings) {\n    super(container, overlayContainer, settings);\n\n    this.setOpacity = this.setOpacity.bind(this);\n\n    this.fillColor = settings.defaultHighlightColor;\n    this.strokeWidth = 0;\n    this.opacity = settings.defaultHighlightOpacity;\n\n    this.fillPanel = new ColorPickerPanel(\n      'Color',\n      settings.defaultColorSet,\n      this.fillColor\n    );\n    this.fillPanel.onColorChanged = this.setFillColor;\n\n    this.opacityPanel = new OpacityPanel(\n      'Opacity',\n      settings.defaultOpacitySteps,\n      this.opacity\n    );\n    this.opacityPanel.onOpacityChanged = this.setOpacity;\n  }\n\n  /**\n   * Sets marker's opacity (0..1).\n   * @param opacity - new opacity value.\n   */\n  protected setOpacity(opacity: number): void {\n    this.opacity = opacity;\n    if (this.visual) {\n      SvgHelper.setAttributes(this.visual, [['opacity', this.opacity.toString()]]);\n    }\n  }\n\n  /**\n   * Returns the list of toolbox panels for this marker type.\n   */\n  public get toolboxPanels(): ToolboxPanel[] {\n    return [this.fillPanel, this.opacityPanel];\n  }\n\n  /**\n   * Returns current marker state that can be restored in the future.\n   */\n  public getState(): RectangleMarkerState {\n    const result = super.getState();\n    result.typeName = HighlightMarker.typeName;\n    return result;\n  }\n}\n","import { IPoint } from '../../core/IPoint';\nimport { SvgHelper } from '../../core/SvgHelper';\nimport { Settings } from '../../core/Settings';\nimport Icon from './callout-marker-icon.svg';\nimport TextColorIcon from '../../ui/toolbox-panels/text-color-icon.svg';\nimport FillColorIcon from '../../ui/toolbox-panels/fill-color-icon.svg';\nimport { ColorPickerPanel } from '../../ui/toolbox-panels/ColorPickerPanel';\nimport { ToolboxPanel } from '../../ui/ToolboxPanel';\nimport { FontFamilyPanel } from '../../ui/toolbox-panels/FontFamilyPanel';\nimport { TextMarker } from '../text-marker/TextMarker';\nimport { ResizeGrip } from '../ResizeGrip';\nimport { CalloutMarkerState } from './CalloutMarkerState';\nimport { MarkerBaseState } from '../../core/MarkerBaseState';\n\nexport class CalloutMarker extends TextMarker {\n  /**\n   * String type name of the marker type. \n   * \n   * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static typeName = 'CalloutMarker';\n\n  /**\n   * Marker type title (display name) used for accessibility and other attributes.\n   */\n  public static title = 'Callout marker';\n  /**\n   * SVG icon markup displayed on toolbar buttons.\n   */\n  public static icon = Icon;\n\n  private bgColor = 'transparent';\n  /**\n   * Color picker toolbox panel for the background (fill) color.\n   */\n  protected bgColorPanel: ColorPickerPanel;\n\n  private tipPosition: IPoint = { x: 0, y: 0 };\n  private tipBase1Position: IPoint = { x: 0, y: 0 };\n  private tipBase2Position: IPoint = { x: 0, y: 0 };\n  private tip: SVGPolygonElement;\n  private tipGrip: ResizeGrip;\n  private tipMoving = false;\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.\n   * @param settings - settings object containing default markers settings.\n   */\n  constructor(\n    container: SVGGElement,\n    overlayContainer: HTMLDivElement,\n    settings: Settings\n  ) {\n    super(container, overlayContainer, settings);\n\n    this.color = settings.defaultStrokeColor;\n    this.bgColor = settings.defaultFillColor;\n    this.fontFamily = settings.defaultFontFamily;\n\n    this.defaultSize = { x: 100, y: 30 };\n\n    this.setBgColor = this.setBgColor.bind(this);\n    this.getTipPoints = this.getTipPoints.bind(this);\n    this.positionTip = this.positionTip.bind(this);\n    this.setTipPoints = this.setTipPoints.bind(this);\n\n    this.colorPanel = new ColorPickerPanel(\n      'Text color',\n      settings.defaultColorSet,\n      this.color,\n      TextColorIcon\n    );\n    this.colorPanel.onColorChanged = this.setColor;\n\n    this.bgColorPanel = new ColorPickerPanel(\n      'Fill color',\n      settings.defaultColorSet,\n      this.bgColor,\n      FillColorIcon\n    );\n    this.bgColorPanel.onColorChanged = this.setBgColor;\n\n    this.fontFamilyPanel = new FontFamilyPanel(\n      'Font',\n      settings.defaultFontFamilies,\n      settings.defaultFontFamily\n    );\n    this.fontFamilyPanel.onFontChanged = this.setFont;\n\n    this.tipGrip = new ResizeGrip();\n    this.tipGrip.visual.transform.baseVal.appendItem(\n      SvgHelper.createTransform()\n    );\n    this.controlBox.appendChild(this.tipGrip.visual);\n  }\n\n  /**\n   * Returns true if passed SVG element belongs to the marker. False otherwise.\n   * \n   * @param el - target element.\n   */\n  public ownsTarget(el: EventTarget): boolean {\n    return (\n      super.ownsTarget(el) || this.tipGrip.ownsTarget(el) || this.tip === el\n    );\n  }\n\n  private createTip() {\n    SvgHelper.setAttributes(this.bgRectangle, [\n      ['fill', this.bgColor],\n      ['rx', '10px'],\n    ]);\n\n    this.tip = SvgHelper.createPolygon(this.getTipPoints(), [\n      ['fill', this.bgColor],\n    ]);\n    this.visual.appendChild(this.tip);\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) down event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerDown(point: IPoint, target?: EventTarget): void {\n    if (this.state === 'new') {\n      super.pointerDown(point, target);\n    }\n\n    if (this.state === 'creating') {\n      this.createTip();\n    } else if (this.tipGrip.ownsTarget(target)) {\n      this.manipulationStartLeft = this.left;\n      this.manipulationStartTop = this.top;\n      this.tipMoving = true;\n    } else {\n      super.pointerDown(point, target);\n    }\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) up event.\n   * \n   * @param point - event coordinates.\n   */\n  public pointerUp(point: IPoint): void {\n    if (this.tipMoving) {\n      this.tipMoving = false;\n    } else {\n      const isCreating = this.state === 'creating';\n      super.pointerUp(point);\n      this.setTipPoints(isCreating);\n      this.positionTip();\n    }\n  }\n\n  /**\n   * Handles marker manipulation (move, resize, rotate, etc.).\n   * \n   * @param point - event coordinates.\n   */\n  public manipulate(point: IPoint): void {\n    if (this.tipMoving) {\n      const rotatedPoint = this.unrotatePoint(point);\n      this.tipPosition = {\n        x: rotatedPoint.x - this.manipulationStartLeft,\n        y: rotatedPoint.y - this.manipulationStartTop,\n      };\n      this.positionTip();\n    } else {\n      super.manipulate(point);\n    }\n  }\n\n  /**\n   * Sets marker's background/fill color.\n   * @param color - new background color.\n   */\n  protected setBgColor(color: string): void {\n    if (this.bgRectangle && this.tip) {\n      SvgHelper.setAttributes(this.bgRectangle, [['fill', color]]);\n      SvgHelper.setAttributes(this.tip, [['fill', color]]);\n    }\n    this.bgColor = color;\n    this.fillColorChanged(color);\n  }\n\n  private getTipPoints(): string {\n    this.setTipPoints(this.state === 'creating');\n    return `${this.tipBase1Position.x},${this.tipBase1Position.y\n      } ${this.tipBase2Position.x},${this.tipBase2Position.y\n      } ${this.tipPosition.x},${this.tipPosition.y}`;\n  }\n\n  private setTipPoints(isCreating = false) {\n    let offset = Math.min(this.height / 2, 15);\n    let baseWidth = this.height / 5;\n    if (isCreating) {\n      this.tipPosition = { x: offset + baseWidth / 2, y: this.height + 20 };\n    }\n\n    const cornerAngle = Math.atan((this.height / 2) / (this.width / 2));\n    if (this.tipPosition.x < this.width / 2 && this.tipPosition.y < this.height / 2) {\n      // top left\n      const tipAngle = Math.atan((this.height / 2 - this.tipPosition.y) / (this.width / 2 - this.tipPosition.x));\n      if (cornerAngle < tipAngle) {\n        baseWidth = this.width / 5;\n        offset = Math.min(this.width / 2, 15);\n        this.tipBase1Position = { x: offset, y: 0 };\n        this.tipBase2Position = { x: offset + baseWidth, y: 0 };\n      } else {\n        this.tipBase1Position = { x: 0, y: offset };\n        this.tipBase2Position = { x: 0, y: offset + baseWidth };\n      }\n    } else if (this.tipPosition.x >= this.width / 2 && this.tipPosition.y < this.height / 2) {\n      // top right\n      const tipAngle = Math.atan((this.height / 2 - this.tipPosition.y) / (this.tipPosition.x - this.width / 2));\n      if (cornerAngle < tipAngle) {\n        baseWidth = this.width / 5;\n        offset = Math.min(this.width / 2, 15);\n        this.tipBase1Position = { x: this.width - offset - baseWidth, y: 0 };\n        this.tipBase2Position = { x: this.width - offset, y: 0 };\n      } else {\n        this.tipBase1Position = { x: this.width, y: offset };\n        this.tipBase2Position = { x: this.width, y: offset + baseWidth };\n      }\n    } else if (this.tipPosition.x >= this.width / 2 && this.tipPosition.y >= this.height / 2) {\n      // bottom right\n      const tipAngle = Math.atan((this.tipPosition.y - this.height / 2) / (this.tipPosition.x - this.width / 2));\n      if (cornerAngle < tipAngle) {\n        baseWidth = this.width / 5;\n        offset = Math.min(this.width / 2, 15);\n        this.tipBase1Position = { x: this.width - offset - baseWidth, y: this.height };\n        this.tipBase2Position = { x: this.width - offset, y: this.height };\n      } else {\n        this.tipBase1Position = { x: this.width, y: this.height - offset - baseWidth };\n        this.tipBase2Position = { x: this.width, y: this.height - offset };\n      }\n    } else {\n      // bottom left\n      const tipAngle = Math.atan((this.tipPosition.y - this.height / 2) / (this.width / 2 - this.tipPosition.x));\n      if (cornerAngle < tipAngle) {\n        baseWidth = this.width / 5;\n        offset = Math.min(this.width / 2, 15);\n        this.tipBase1Position = { x: offset, y: this.height };\n        this.tipBase2Position = { x: offset + baseWidth, y: this.height };\n      } else {\n        this.tipBase1Position = { x: 0, y: this.height - offset };\n        this.tipBase2Position = { x: 0, y: this.height - offset - baseWidth };\n      }\n    }\n  }\n\n  /**\n   * Resize marker based on current pointer coordinates and context.\n   * @param point \n   */\n  protected resize(point: IPoint): void {\n    super.resize(point);\n    this.positionTip();\n  }\n\n  private positionTip() {\n    SvgHelper.setAttributes(this.tip, [['points', this.getTipPoints()]]);\n    const translate = this.tipGrip.visual.transform.baseVal.getItem(0);\n    translate.setTranslate(this.tipPosition.x, this.tipPosition.y);\n    this.tipGrip.visual.transform.baseVal.replaceItem(translate, 0);\n  }\n\n  /**\n   * Returns the list of toolbox panels for this marker type.\n   */\n  public get toolboxPanels(): ToolboxPanel[] {\n    return [this.colorPanel, this.bgColorPanel, this.fontFamilyPanel];\n  }\n\n  /**\n   * Selects this marker and displays appropriate selected marker UI.\n   */\n  public select(): void {\n    this.positionTip();\n    super.select();\n  }\n\n  /**\n   * Returns current marker state that can be restored in the future.\n   */\n  public getState(): CalloutMarkerState {\n    const result: CalloutMarkerState = Object.assign({\n      bgColor: this.bgColor,\n      tipPosition: this.tipPosition\n    }, super.getState());\n    result.typeName = CalloutMarker.typeName;\n\n    return result;\n  }\n\n  /**\n   * Restores previously saved marker state.\n   * \n   * @param state - previously saved state.\n   */\n  public restoreState(state: MarkerBaseState): void {\n    const calloutState = state as CalloutMarkerState;\n    this.bgColor = calloutState.bgColor;\n    this.tipPosition = calloutState.tipPosition;\n\n    super.restoreState(state);\n    this.createTip();\n    this.setTipPoints();\n  }\n\n  /**\n   * Scales marker. Used after the image resize.\n   * \n   * @param scaleX - horizontal scale\n   * @param scaleY - vertical scale\n   */\n  public scale(scaleX: number, scaleY: number): void {\n    super.scale(scaleX, scaleY);\n\n    this.tipPosition = {x: this.tipPosition.x * scaleX, y: this.tipPosition.y * scaleY};\n\n    this.positionTip();\n  }\n}\n","import Icon from './ellipse-marker-icon.svg';\nimport { IPoint } from '../../core/IPoint';\nimport { SvgHelper } from '../../core/SvgHelper';\nimport { RectangularBoxMarkerBase } from '../RectangularBoxMarkerBase';\nimport { Settings } from '../../core/Settings';\nimport { RectangleMarkerState } from '../RectangleMarkerState';\nimport { MarkerBaseState } from '../../core/MarkerBaseState';\nimport { ColorPickerPanel } from '../../ui/toolbox-panels/ColorPickerPanel';\nimport { LineWidthPanel } from '../../ui/toolbox-panels/LineWidthPanel';\nimport { LineStylePanel } from '../../ui/toolbox-panels/LineStylePanel';\nimport { ToolboxPanel } from '../../ui/ToolboxPanel';\nimport FillColorIcon from '../../ui/toolbox-panels/fill-color-icon.svg';\nimport { OpacityPanel } from '../../ui/toolbox-panels/OpacityPanel';\n\nexport class EllipseMarker extends RectangularBoxMarkerBase {\n  /**\n   * String type name of the marker type. \n   * \n   * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static typeName = 'EllipseMarker';\n  /**\n   * Marker type title (display name) used for accessibility and other attributes.\n   */\n  public static title = 'Ellipse marker';\n  /**\n   * SVG icon markup displayed on toolbar buttons.\n   */\n  public static icon = Icon;\n\n  /**\n   * Ellipse fill color.\n   */\n  protected fillColor = 'transparent';\n  /**\n   * Ellipse border color.\n   */\n  protected strokeColor = 'transparent';\n  /**\n   * Ellipse border line width.\n   */\n  protected strokeWidth = 0;\n  /**\n   * Ellipse border dash array.\n   */\n  protected strokeDasharray = '';\n  /**\n   * Ellipse opacity (0..1).\n   */\n  protected opacity = 1;\n\n  protected strokePanel: ColorPickerPanel;\n  protected fillPanel: ColorPickerPanel;\n  protected strokeWidthPanel: LineWidthPanel;\n  protected strokeStylePanel: LineStylePanel;\n  protected opacityPanel: OpacityPanel;\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.\n   * @param settings - settings object containing default markers settings.\n   */\n  constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings) {\n    super(container, overlayContainer, settings);\n\n    this.strokeColor = settings.defaultColor;\n    this.strokeWidth = settings.defaultStrokeWidth;\n    this.strokeDasharray = settings.defaultStrokeDasharray;\n    this.fillColor = settings.defaultFillColor;\n\n    this.setStrokeColor = this.setStrokeColor.bind(this);\n    this.setFillColor = this.setFillColor.bind(this);\n    this.setStrokeWidth = this.setStrokeWidth.bind(this);\n    this.setStrokeDasharray = this.setStrokeDasharray.bind(this);\n    this.setOpacity = this.setOpacity.bind(this);\n    this.createVisual = this.createVisual.bind(this);\n\n    this.strokePanel = new ColorPickerPanel(\n      'Line color',\n      [...settings.defaultColorSet, 'transparent'],\n      settings.defaultColor\n    );\n    this.strokePanel.onColorChanged = this.setStrokeColor;\n\n    this.fillPanel = new ColorPickerPanel(\n      'Fill color',\n      [...settings.defaultColorSet, 'transparent'],\n      this.fillColor,\n      FillColorIcon\n    );\n    this.fillPanel.onColorChanged = this.setFillColor;\n\n    this.strokeWidthPanel = new LineWidthPanel(\n      'Line width',\n      settings.defaultStrokeWidths,\n      settings.defaultStrokeWidth\n    );\n    this.strokeWidthPanel.onWidthChanged = this.setStrokeWidth;\n\n    this.strokeStylePanel = new LineStylePanel(\n      'Line style',\n      settings.defaultStrokeDasharrays,\n      settings.defaultStrokeDasharray\n    );\n    this.strokeStylePanel.onStyleChanged = this.setStrokeDasharray;\n\n    this.opacityPanel = new OpacityPanel(\n      'Opacity',\n      settings.defaultOpacitySteps,\n      this.opacity\n    );\n    this.opacityPanel.onOpacityChanged = this.setOpacity;\n  }\n\n  /**\n   * Returns true if passed SVG element belongs to the marker. False otherwise.\n   * \n   * @param el - target element.\n   */\n  public ownsTarget(el: EventTarget): boolean {\n    if (super.ownsTarget(el) || el === this.visual) {\n      return true;\n    } else {\n      return false;\n    }\n  }\n\n  /**\n   * Creates marker visual.\n   */\n  protected createVisual(): void {\n    this.visual = SvgHelper.createEllipse(this.width / 2, this.height / 2, [\n      ['fill', this.fillColor],\n      ['stroke', this.strokeColor],\n      ['stroke-width', this.strokeWidth.toString()],\n      ['stroke-dasharray', this.strokeDasharray],\n      ['opacity', this.opacity.toString()]\n    ]);\n    this.addMarkerVisualToContainer(this.visual);\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) down event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerDown(point: IPoint, target?: EventTarget): void {\n    super.pointerDown(point, target);\n    if (this.state === 'new') {\n      this.createVisual();\n\n      this.moveVisual(point);\n\n      this._state = 'creating';\n    }\n  }\n\n  /**\n   * Handles marker manipulation (move, resize, rotate, etc.).\n   * \n   * @param point - event coordinates.\n   */\n  public manipulate(point: IPoint): void {\n    super.manipulate(point);\n  }\n\n  /**\n   * Resize marker based on current pointer coordinates and context.\n   * @param point \n   */\n  protected resize(point: IPoint): void {\n    super.resize(point);\n    this.setSize();\n  }\n\n  /**\n   * Sets marker's visual size after manipulation.\n   */\n  protected setSize(): void {\n    super.setSize();\n    SvgHelper.setAttributes(this.visual, [\n      ['cx', (this.width / 2).toString()],\n      ['cy', (this.height / 2).toString()],\n      ['rx', (this.width / 2).toString()],\n      ['ry', (this.height / 2).toString()],\n    ]);\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) up event.\n   * \n   * @param point - event coordinates.\n   */\n  public pointerUp(point: IPoint): void {\n    super.pointerUp(point);\n    this.setSize();\n  }\n\n  /**\n   * Sets marker's line color.\n   * @param color - new line color.\n   */\n  protected setStrokeColor(color: string): void {\n    this.strokeColor = color;\n    if (this.visual) {\n      SvgHelper.setAttributes(this.visual, [['stroke', this.strokeColor]]);\n    }\n    this.colorChanged(color);\n  }\n  /**\n   * Sets marker's fill (background) color.\n   * @param color - new fill color.\n   */\n  protected setFillColor(color: string): void {\n    this.fillColor = color;\n    if (this.visual) {\n      SvgHelper.setAttributes(this.visual, [['fill', this.fillColor]]);\n    }\n    this.fillColorChanged(color);\n  }\n  /**\n   * Sets marker's line width.\n   * @param width - new line width\n   */\n  protected setStrokeWidth(width: number): void {\n    this.strokeWidth = width;\n    if (this.visual) {\n      SvgHelper.setAttributes(this.visual, [['stroke-width', this.strokeWidth.toString()]]);\n    }\n  }\n  /**\n   * Sets marker's border dash array.\n   * @param dashes - new dash array.\n   */\n  protected setStrokeDasharray(dashes: string): void {\n    this.strokeDasharray = dashes;\n    if (this.visual) {\n      SvgHelper.setAttributes(this.visual, [['stroke-dasharray', this.strokeDasharray]]);\n    }\n  }\n  /**\n   * Sets marker's opacity.\n   * @param opacity - new opacity value (0..1).\n   */\n  protected setOpacity(opacity: number): void {\n    this.opacity = opacity;\n    if (this.visual) {\n      SvgHelper.setAttributes(this.visual, [['opacity', this.opacity.toString()]]);\n    }\n  }\n\n  /**\n   * Returns the list of toolbox panels for this marker type.\n   */\n  public get toolboxPanels(): ToolboxPanel[] {\n    return [this.strokePanel, this.fillPanel, this.strokeWidthPanel, this.strokeStylePanel, this.opacityPanel];\n  }\n\n  /**\n   * Returns current marker state that can be restored in the future.\n   */\n  public getState(): RectangleMarkerState {\n    const result: RectangleMarkerState = Object.assign({\n      fillColor: this.fillColor,\n      strokeColor: this.strokeColor,\n      strokeWidth: this.strokeWidth,\n      strokeDasharray: this.strokeDasharray,\n      opacity: this.opacity\n    }, super.getState());\n    result.typeName = EllipseMarker.typeName;\n\n    return result;\n  }\n\n  /**\n   * Restores previously saved marker state.\n   * \n   * @param state - previously saved state.\n   */\n  public restoreState(state: MarkerBaseState): void {\n    const rectState = state as RectangleMarkerState;\n    this.fillColor = rectState.fillColor;\n    this.strokeColor = rectState.strokeColor;\n    this.strokeWidth = rectState.strokeWidth;\n    this.strokeDasharray = rectState.strokeDasharray;\n    this.opacity = rectState.opacity;\n\n    this.createVisual();\n    super.restoreState(state);\n    this.setSize();\n  }\n\n  /**\n   * Scales marker. Used after the image resize.\n   * \n   * @param scaleX - horizontal scale\n   * @param scaleY - vertical scale\n   */\n  public scale(scaleX: number, scaleY: number): void {\n    super.scale(scaleX, scaleY);\n\n    this.setSize();\n  }\n}\n","import { IPoint } from '../../core/IPoint';\nimport { SvgHelper } from '../../core/SvgHelper';\nimport { Settings } from '../../core/Settings';\nimport Icon from './measurement-marker-icon.svg';\nimport { ToolboxPanel } from '../../ui/ToolboxPanel';\nimport { LineMarker } from '../line-marker/LineMarker';\nimport { MarkerBaseState } from '../../core/MarkerBaseState';\nimport { LineMarkerState } from '../line-marker/LineMarkerState';\n\nexport class MeasurementMarker extends LineMarker {\n  /**\n   * String type name of the marker type. \n   * \n   * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static typeName = 'MeasurementMarker';\n\n  /**\n   * Marker type title (display name) used for accessibility and other attributes.\n   */\n  public static title = 'Measurement marker';\n  /**\n   * SVG icon markup displayed on toolbar buttons.\n   */\n  public static icon = Icon;\n\n  private tip1: SVGLineElement;\n  private tip2: SVGLineElement;\n\n  private get tipLength(): number {\n    return 10 + this.strokeWidth * 3;\n  }\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.\n   * @param settings - settings object containing default markers settings.\n   */\n  constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings) {\n    super(container, overlayContainer, settings);\n  }\n\n  /**\n   * Returns true if passed SVG element belongs to the marker. False otherwise.\n   * \n   * @param el - target element.\n   */\n  public ownsTarget(el: EventTarget): boolean {\n    if (\n      super.ownsTarget(el) ||\n      el === this.tip1 || el === this.tip2\n    ) {\n      return true;\n    } else {\n      return false;\n    }\n  }\n\n  private createTips() {\n    this.tip1 = SvgHelper.createLine(\n      this.x1 - this.tipLength / 2, \n      this.y1, \n      this.x1 + this.tipLength / 2, \n      this.y1, \n      [\n        ['stroke', this.strokeColor],\n        ['stroke-width', this.strokeWidth.toString()]\n      ]);\n    this.tip1.transform.baseVal.appendItem(SvgHelper.createTransform());\n    this.visual.appendChild(this.tip1);\n\n    this.tip2 = SvgHelper.createLine(\n      this.x2 - this.tipLength / 2, \n      this.y2, \n      this.x2 + this.tipLength / 2, \n      this.y2, \n      [\n        ['stroke', this.strokeColor],\n        ['stroke-width', this.strokeWidth.toString()]\n      ]);\n    this.tip2.transform.baseVal.appendItem(SvgHelper.createTransform());\n    this.visual.appendChild(this.tip2);\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) down event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerDown(point: IPoint, target?: EventTarget): void {\n    super.pointerDown(point, target);\n    if (this.state === 'creating') {\n      this.createTips();\n    }\n  }\n\n  /**\n   * Adjusts marker visual after manipulation.\n   */\n  protected adjustVisual(): void {\n    super.adjustVisual();\n\n    if (this.tip1 && this.tip2) {\n\n      SvgHelper.setAttributes(this.tip1,[\n        ['x1', (this.x1 - this.tipLength / 2).toString()], \n        ['y1', this.y1.toString()], \n        ['x2', (this.x1 + this.tipLength / 2).toString()], \n        ['y2', this.y1.toString()], \n        ['stroke', this.strokeColor],\n        ['stroke-width', this.strokeWidth.toString()]\n      ]);\n      SvgHelper.setAttributes(this.tip2,[\n        ['x1', (this.x2 - this.tipLength / 2).toString()], \n        ['y1', this.y2.toString()], \n        ['x2', (this.x2 + this.tipLength / 2).toString()], \n        ['y2', this.y2.toString()], \n        ['stroke', this.strokeColor],\n        ['stroke-width', this.strokeWidth.toString()]\n      ]);\n\n      if (Math.abs(this.x1 - this.x2) > 0.1) {\n        const lineAngle1 =\n          (Math.atan((this.y2 - this.y1) / (this.x2 - this.x1)) * 180) / Math.PI + 90 * Math.sign(this.x1 - this.x2);\n\n        const a1transform = this.tip1.transform.baseVal.getItem(0);\n        a1transform.setRotate(lineAngle1, this.x1, this.y1);\n        this.tip1.transform.baseVal.replaceItem(a1transform, 0);\n\n        const a2transform = this.tip2.transform.baseVal.getItem(0);\n        a2transform.setRotate(lineAngle1 + 180, this.x2, this.y2);\n        this.tip2.transform.baseVal.replaceItem(a2transform, 0);\n      }\n    }\n  }\n\n  /**\n   * Returns the list of toolbox panels for this marker type.\n   */\n  public get toolboxPanels(): ToolboxPanel[] {\n    return [this.strokePanel, this.strokeWidthPanel, this.strokeStylePanel];\n  }\n\n  /**\n   * Returns current marker state that can be restored in the future.\n   */\n  public getState(): LineMarkerState {\n    const result =super.getState();\n    result.typeName = MeasurementMarker.typeName;\n\n    return result;\n  }\n\n  /**\n   * Restores previously saved marker state.\n   * \n   * @param state - previously saved state.\n   */\n  public restoreState(state: MarkerBaseState): void {\n    super.restoreState(state);\n\n    this.createTips();\n    this.adjustVisual();\n  }\n}\n","import Icon from './ellipse-frame-marker-icon.svg';\nimport { Settings } from '../../core/Settings';\nimport { RectangleMarkerState } from '../RectangleMarkerState';\nimport { ToolboxPanel } from '../../ui/ToolboxPanel';\nimport { EllipseMarker } from '../ellipse-marker/EllipseMarker';\n\nexport class EllipseFrameMarker extends EllipseMarker {\n  /**\n   * String type name of the marker type. \n   * \n   * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static typeName = 'EllipseFrameMarker';\n  /**\n   * Marker type title (display name) used for accessibility and other attributes.\n   */\n  public static title = 'Ellipse frame marker';\n  /**\n   * SVG icon markup displayed on toolbar buttons.\n   */\n  public static icon = Icon;\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.\n   * @param settings - settings object containing default markers settings.\n   */\n  constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings) {\n    super(container, overlayContainer, settings);\n\n    // reset colors so 'transparent' is excluded\n    this.strokePanel.colors= settings.defaultColorSet;\n\n    this.fillColor = 'transparent';\n  }\n\n  /**\n   * Returns the list of toolbox panels for this marker type.\n   */\n  public get toolboxPanels(): ToolboxPanel[] {\n    return [this.strokePanel, this.strokeWidthPanel, this.strokeStylePanel];\n  }\n\n  /**\n   * Returns current marker state that can be restored in the future.\n   */\n  public getState(): RectangleMarkerState {\n    const result = super.getState();\n    result.typeName = EllipseFrameMarker.typeName;\n    return result;\n  }\n}\n","/**\n * Manages undo and redo stacks.\n */\nexport class UndoRedoManager<T> {\n  private undoStack: T[] = [];\n  private redoStack: T[] = [];\n\n  private lastRedoStep: T;\n\n  /**\n   * Returns true if there are items in the undo stack.\n   */\n  public get isUndoPossible(): boolean {\n    return this.undoStack.length > 0;\n  }\n\n  /**\n   * Returns true if there are items in the redo stack.\n   */\n  public get isRedoPossible(): boolean {\n    return this.redoStack.length > 0;\n  }\n\n  /**\n   * Adds a step to the undo stack.\n   * @param stepData data representing a state.\n   */\n  public addUndoStep(stepData: T): void {\n    if (\n      this.undoStack.length === 0 ||\n      JSON.stringify(this.undoStack[this.undoStack.length - 1]) !==\n        JSON.stringify(stepData)\n    ) {\n        this.undoStack.push(stepData);\n        if (JSON.stringify(this.lastRedoStep) !== JSON.stringify(stepData)) {\n          this.redoStack.splice(0, this.redoStack.length);\n        }\n    }\n  }\n\n  /**\n   * Returns data for the previous step in the undo stack and adds last step to the redo stack.\n   * @returns \n   */\n  public undo(): T | undefined {\n    if (this.undoStack.length > 1) {\n      const lastStep = this.undoStack.pop();\n      if (lastStep !== undefined) {\n        this.redoStack.push(lastStep);\n      }\n      return this.undoStack.length > 0 ? this.undoStack[this.undoStack.length - 1] : undefined;\n    }\n  }\n\n  /**\n   * Returns most recent item in the redo stack.\n   * @returns \n   */\n  public redo(): T | undefined {\n    this.lastRedoStep = this.redoStack.pop();\n    return this.lastRedoStep;\n  }\n}\n","import { IPoint } from '../../core/IPoint';\nimport { SvgHelper } from '../../core/SvgHelper';\nimport { Settings } from '../../core/Settings';\nimport { LinearMarkerBase } from '../LinearMarkerBase';\nimport Icon from './curve-marker-icon.svg';\nimport { ColorPickerPanel } from '../../ui/toolbox-panels/ColorPickerPanel';\nimport { ToolboxPanel } from '../../ui/ToolboxPanel';\nimport { LineWidthPanel } from '../../ui/toolbox-panels/LineWidthPanel';\nimport { LineStylePanel } from '../../ui/toolbox-panels/LineStylePanel';\nimport { CurveMarkerState } from './CurveMarkerState';\nimport { MarkerBaseState } from '../../core/MarkerBaseState';\nimport { ResizeGrip } from '../ResizeGrip';\n\nexport class CurveMarker extends LinearMarkerBase {\n  /**\n   * String type name of the marker type. \n   * \n   * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static typeName = 'CurveMarker';\n  \n  /**\n   * Marker type title (display name) used for accessibility and other attributes.\n   */\n  public static title = 'Curve marker';\n  /**\n   * SVG icon markup displayed on toolbar buttons.\n   */\n  public static icon = Icon;\n\n  /**\n   * Invisible wider curve to make selection easier/possible.\n   */\n  protected selectorCurve: SVGPathElement;\n  /**\n   * Visible marker curve.\n   */\n  protected visibleCurve: SVGPathElement;\n\n  /**\n   * Line color.\n   */\n  protected strokeColor = 'transparent';\n  /**\n   * Line width.\n   */\n  protected strokeWidth = 0;\n  /**\n   * Line dash array.\n   */\n  protected strokeDasharray = '';\n\n  /**\n   * Color picker panel for line color.\n   */\n  protected strokePanel: ColorPickerPanel;\n  /**\n   * Line width toolbox panel.\n   */\n  protected strokeWidthPanel: LineWidthPanel;\n  /**\n   * Line dash array toolbox panel.\n   */\n  protected strokeStylePanel: LineStylePanel;\n\n  private curveGrip: ResizeGrip;\n  private curveX = 0;\n  private curveY = 0;\n\n  private manipulationStartCurveX = 0;\n  private manipulationStartCurveY = 0;\n\n  private curveControlLine1: SVGLineElement;\n  private curveControlLine2: SVGLineElement;\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.\n   * @param settings - settings object containing default markers settings.\n   */\n  constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings) {\n    super(container, overlayContainer, settings);\n\n    this.setStrokeColor = this.setStrokeColor.bind(this);\n    this.setStrokeWidth = this.setStrokeWidth.bind(this);\n    this.setStrokeDasharray = this.setStrokeDasharray.bind(this);\n    this.positionGrips = this.positionGrips.bind(this);\n    this.addControlGrips = this.addControlGrips.bind(this);\n    this.adjustVisual = this.adjustVisual.bind(this);\n    this.setupControlBox = this.setupControlBox.bind(this);\n    this.resize = this.resize.bind(this);\n\n    this.strokeColor = settings.defaultColor;\n    this.strokeWidth = settings.defaultStrokeWidth;\n    this.strokeDasharray = settings.defaultStrokeDasharray;\n\n    this.strokePanel = new ColorPickerPanel(\n      'Line color',\n      settings.defaultColorSet,\n      settings.defaultColor\n    );\n    this.strokePanel.onColorChanged = this.setStrokeColor;\n\n    this.strokeWidthPanel = new LineWidthPanel(\n      'Line width',\n      settings.defaultStrokeWidths,\n      settings.defaultStrokeWidth\n    );\n    this.strokeWidthPanel.onWidthChanged = this.setStrokeWidth;\n\n    this.strokeStylePanel = new LineStylePanel(\n      'Line style',\n      settings.defaultStrokeDasharrays,\n      settings.defaultStrokeDasharray\n    );\n    this.strokeStylePanel.onStyleChanged = this.setStrokeDasharray;\n  }\n\n  /**\n   * Returns true if passed SVG element belongs to the marker. False otherwise.\n   * \n   * @param el - target element.\n   */\n  public ownsTarget(el: EventTarget): boolean {\n    if (\n      super.ownsTarget(el) ||\n      el === this.visual ||\n      el === this.selectorCurve ||\n      el === this.visibleCurve ||\n      this.curveGrip.ownsTarget(el)\n    ) {\n      return true;\n    } else {\n      return false;\n    }\n  }\n\n  private getPathD(): string {\n    const result = `M ${this.x1} ${this.y1} Q ${this.curveX} ${this.curveY}, ${this.x2} ${this.y2}`;\n    return result;\n  }\n\n  private createVisual() {\n    this.visual = SvgHelper.createGroup();\n    this.selectorCurve = SvgHelper.createPath(\n      this.getPathD(),\n      [\n        ['stroke', 'transparent'],\n        ['stroke-width', (this.strokeWidth + 10).toString()],\n        ['fill', 'transparent'],\n      ]\n    );\n    this.visibleCurve = SvgHelper.createPath(\n      this.getPathD(),\n      [\n        ['stroke', this.strokeColor],\n        ['stroke-width', this.strokeWidth.toString()],\n        ['fill', 'transparent'],\n      ]\n    );\n    this.visual.appendChild(this.selectorCurve);\n    this.visual.appendChild(this.visibleCurve);\n\n    this.addMarkerVisualToContainer(this.visual);\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) down event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerDown(point: IPoint, target?: EventTarget): void {\n    super.pointerDown(point, target);\n\n    this.manipulationStartCurveX = this.curveX;\n    this.manipulationStartCurveY = this.curveY;\n    if (this.state === 'new') {\n      this.curveX = point.x;\n      this.curveY = point.y;\n    }\n\n    if (this.state === 'new') {\n      this.createVisual();\n      this.adjustVisual();\n\n      this._state = 'creating';\n    } else if (this.curveGrip.ownsTarget(target)) {\n      this.activeGrip = this.curveGrip;\n      this._state = 'resize';\n    }\n  }\n\n  /**\n   * Adjusts visual after manipulation.\n   */\n  protected adjustVisual(): void {\n    if (this.selectorCurve && this.visibleCurve) {\n      this.selectorCurve.setAttribute('d', this.getPathD());\n\n      this.visibleCurve.setAttribute('d', this.getPathD());\n\n      SvgHelper.setAttributes(this.visibleCurve, [['stroke', this.strokeColor]]);\n      SvgHelper.setAttributes(this.visibleCurve, [['stroke-width', this.strokeWidth.toString()]]);\n      SvgHelper.setAttributes(this.visibleCurve, [['stroke-dasharray', this.strokeDasharray.toString()]]);\n    }\n  }\n\n  /**\n   * Sets manipulation grips up.\n   */\n  protected setupControlBox(): void {\n    super.setupControlBox();\n    this.curveControlLine1 = SvgHelper.createLine(\n      this.x1,\n      this.y1,\n      this.curveX,\n      this.curveY,\n      [\n        ['stroke', 'black'],\n        ['stroke-width', '1'],\n        ['stroke-opacity', '0.5'],\n        ['stroke-dasharray', '3, 2'],\n      ]\n    );\n    this.curveControlLine2 = SvgHelper.createLine(\n      this.x2,\n      this.y2,\n      this.curveX,\n      this.curveY,\n      [\n        ['stroke', 'black'],\n        ['stroke-width', '1'],\n        ['stroke-opacity', '0.5'],\n        ['stroke-dasharray', '3, 2'],\n      ]\n    );\n\n    this.controlBox.insertBefore(this.curveControlLine1, this.controlBox.firstChild);\n    this.controlBox.insertBefore(this.curveControlLine2, this.controlBox.firstChild);\n  }\n\n  /**\n   * Add manipulation grips to the control box.\n   */\n  protected addControlGrips(): void {\n    this.curveGrip = this.createGrip();\n    this.curveX = 0;\n    this.curveY = 0;\n    super.addControlGrips();\n  }\n\n  /**\n   * Positions manipulation grips.\n   */\n  protected positionGrips(): void {\n    super.positionGrips();\n    const gripSize = this.curveGrip.GRIP_SIZE;\n    this.positionGrip(this.curveGrip.visual, this.curveX - gripSize / 2, this.curveY - gripSize / 2);\n\n    if (this.curveControlLine1 && this.curveControlLine2) {\n      this.curveControlLine1.setAttribute('x1', this.x1.toString());\n      this.curveControlLine1.setAttribute('y1', this.y1.toString());\n      this.curveControlLine1.setAttribute('x2', this.curveX.toString());\n      this.curveControlLine1.setAttribute('y2', this.curveY.toString());\n\n      this.curveControlLine2.setAttribute('x1', this.x2.toString());\n      this.curveControlLine2.setAttribute('y1', this.y2.toString());\n      this.curveControlLine2.setAttribute('x2', this.curveX.toString());\n      this.curveControlLine2.setAttribute('y2', this.curveY.toString());\n    }\n  }\n\n  /**\n   * Moves or resizes the marker.\n   * @param point event coordinates\n   */\n  public manipulate(point: IPoint): void {\n    if (this.state === 'move') {\n      this.curveX = this.manipulationStartCurveX + point.x - this.manipulationStartX;\n      this.curveY = this.manipulationStartCurveY + point.y - this.manipulationStartY;\n    }\n    super.manipulate(point);\n  }\n\n  /**\n   * Resizes the marker.\n   * @param point event coordinates.\n   */\n  protected resize(point: IPoint): void {\n    if (this.activeGrip === this.curveGrip) {\n      this.curveX = point.x;\n      this.curveY = point.y;\n    }\n    super.resize(point);\n    if (this.state === 'creating') {\n      this.curveX = this.x1 + (this.x2 - this.x1) / 2;\n      this.curveY = this.y1 + (this.y2 - this.y1) / 2;\n    }\n  }\n\n  /**\n   * Sets line color.\n   * @param color - new color.\n   */\n  protected setStrokeColor(color: string): void {\n    this.strokeColor = color;\n    this.adjustVisual();\n    this.colorChanged(color);\n  }\n  /**\n   * Sets line width.\n   * @param width - new width.\n   */\n  protected setStrokeWidth(width: number): void {\n    this.strokeWidth = width\n    this.adjustVisual();\n  }\n\n  /**\n   * Sets line dash array.\n   * @param dashes - new dash array.\n   */\n  protected setStrokeDasharray(dashes: string): void {\n    this.strokeDasharray = dashes;\n    this.adjustVisual();\n  }\n\n  /**\n   * Scales marker. Used after the image resize.\n   * \n   * @param scaleX - horizontal scale\n   * @param scaleY - vertical scale\n   */\n  public scale(scaleX: number, scaleY: number): void {\n    this.curveX = this.curveX * scaleX;\n    this.curveY = this.curveY * scaleY;\n    super.scale(scaleX, scaleY);\n  }\n\n\n  /**\n   * Returns the list of toolbox panels for this marker type.\n   */\n  public get toolboxPanels(): ToolboxPanel[] {\n    return [this.strokePanel, this.strokeWidthPanel, this.strokeStylePanel];\n  }\n\n  /**\n   * Returns current marker state that can be restored in the future.\n   */\n  public getState(): CurveMarkerState {\n    const result: CurveMarkerState = Object.assign({\n      strokeColor: this.strokeColor,\n      strokeWidth: this.strokeWidth,\n      strokeDasharray: this.strokeDasharray,\n      curveX: this.curveX,\n      curveY: this.curveY\n    }, super.getState());\n    result.typeName = CurveMarker.typeName;\n\n    return result;\n  }\n\n  /**\n   * Restores previously saved marker state.\n   * \n   * @param state - previously saved state.\n   */\n  public restoreState(state: MarkerBaseState): void {\n    super.restoreState(state);\n\n    const lmState = state as CurveMarkerState;\n    this.strokeColor = lmState.strokeColor;\n    this.strokeWidth = lmState.strokeWidth;\n    this.strokeDasharray = lmState.strokeDasharray;\n    this.curveX = lmState.curveX;\n    this.curveY = lmState.curveY;\n\n    this.createVisual();\n    this.adjustVisual();\n  }\n}\n","import { MarkerArea } from '../MarkerArea';\nimport { MarkerAreaState } from '../MarkerAreaState';\nimport { MarkerBase } from './MarkerBase';\n\nexport class MarkerAreaEvent {\n  public markerArea: MarkerArea;\n  public cancelable = false;\n\n  private _defaultPrevented = false;\n  public get defaultPrevented(): boolean {\n    return this._defaultPrevented;\n  }\n\n  public preventDefault(): void {\n    this._defaultPrevented = true;\n  }\n\n  constructor(markerArea: MarkerArea, cancelable = false) {\n    this.markerArea = markerArea;\n    this.cancelable = cancelable;\n  }\n}\n\nexport class MarkerAreaRenderEvent extends MarkerAreaEvent {\n  public dataUrl: string;\n  public state: MarkerAreaState;\n\n  constructor(markerArea: MarkerArea, dataUrl: string, state: MarkerAreaState) {\n    super(markerArea, false);\n    this.dataUrl = dataUrl;\n    this.state = state;\n  }\n}\n\n\nexport class MarkerEvent extends MarkerAreaEvent {\n  public marker?: MarkerBase;\n\n  constructor(markerArea: MarkerArea, marker?: MarkerBase, cancelable = false) {\n    super(markerArea, cancelable);\n    this.marker = marker;\n  }\n}\n\n/**\n * General MarkerArea event handler type.\n */\nexport type MarkerAreaEventHandler = (event: MarkerAreaEvent) => void;\n\n/**\n * MarkerArea render event handler type.\n */\nexport type MarkerAreaRenderEventHandler = (event: MarkerAreaRenderEvent) => void;\n\n/**\n * Marker event handler type.\n */\nexport type MarkerEventHandler = (event: MarkerEvent) => void;\n\n/**\n * Describes a repository of MarkerArea event handlers.\n */\nexport interface IEventListenerRepository {\n  /**\n   * Event handlers for the `render` event.\n   */\n  render: MarkerAreaRenderEventHandler[];\n  /**\n   * Event handlers for the `beforeclose` event.\n   */\n  beforeclose: MarkerAreaEventHandler[];\n  /**\n   * Event handlers for the `close` event.\n   */\n  close: MarkerAreaEventHandler[];\n  /**\n   * Event handlers for the `show` event.\n   */\n  show: MarkerAreaEventHandler[];\n  /**\n   * Event handlers for the `restorestate` event.\n   */\n  restorestate: MarkerAreaEventHandler[];\n  /**\n   * Event handlers for the `markerselect` event.\n   */\n  markerselect: MarkerEventHandler[];\n  /**\n   * Event handlers for the `markerdeselect` event.\n   */\n  markerdeselect: MarkerEventHandler[];\n  /**\n   * Event handlers for the `markercreating` event.\n   */\n  markercreating: MarkerEventHandler[];\n  /**\n   * Event handlers for the `markercreated` event.\n   */\n  markercreate: MarkerEventHandler[];\n  /**\n   * Event handlers for the `markerbeforedelete` event.\n   */\n  markerbeforedelete: MarkerEventHandler[];\n  /**\n   * Event handlers for the `markerdelete` event.\n   */\n  markerdelete: MarkerEventHandler[];\n  /**\n   * Event handlers for the `focus` event.\n   * \n   * @since 2.19.0\n   */\n  focus: MarkerAreaEventHandler[];\n  /**\n   * Event handlers for the `blur` event.\n   * \n   * @since 2.19.0\n   */\n  blur: MarkerAreaEventHandler[];\n}\n\n/**\n * Event handler type for a specific event type.\n */\nexport type EventHandler<\n  T extends keyof IEventListenerRepository\n> = T extends 'markerselect'\n  ? MarkerEventHandler\n  : T extends 'markerdeselect'\n  ? MarkerEventHandler\n  : T extends 'markercreating'\n  ? MarkerEventHandler\n  : T extends 'markercreate'\n  ? MarkerEventHandler\n  : T extends 'markerbeforedelete'\n  ? MarkerEventHandler\n  : T extends 'markerdelete'\n  ? MarkerEventHandler\n  : T extends 'render'\n  ? MarkerAreaRenderEventHandler\n  : MarkerAreaEventHandler;\n\n/**\n * Event handler repository.\n */\nexport class EventListenerRepository implements IEventListenerRepository {\n  /**\n   * Event handlers for the `render` event.\n   */\n  render: MarkerAreaRenderEventHandler[] = [];\n  /**\n   * Event handlers for the `beforeclose` event.\n   */\n  beforeclose: MarkerAreaEventHandler[] = [];\n  /**\n   * Event handlers for the `close` event.\n   */\n  close: MarkerAreaEventHandler[] = [];\n  /**\n   * Event handlers for the `show` event.\n   */\n  show: MarkerAreaEventHandler[] = [];\n  /**\n   * Event handlers for the `restorestate` event.\n   */\n  restorestate: MarkerAreaEventHandler[] = [];\n  /**\n   * Event handlers for the `markerselect` event.\n   */\n  markerselect: MarkerEventHandler[] = [];\n  /**\n   * Event handlers for the `markerdeselect` event.\n   */\n  markerdeselect: MarkerEventHandler[] = [];\n  /**\n   * Event handlers for the `markercreating` event.\n   */\n  markercreating: MarkerEventHandler[] = [];\n  /**\n   * Event handlers for the `markercreate` event.\n   */\n  markercreate: MarkerEventHandler[] = [];\n  /**\n   * Event handlers for the `markerbeforedelete` event.\n   */\n  markerbeforedelete: MarkerEventHandler[] = [];\n  /**\n   * Event handlers for the `markerdelete` event.\n   */\n  markerdelete: MarkerEventHandler[] = [];\n  /**\n   * Event handlers for the `focus` event.\n   * \n   * @since 2.19.0\n   */\n  focus: MarkerAreaEventHandler[] = [];\n  /**\n   * Event handlers for the `blur` event.\n   * \n   * @since 2.19.0\n   */\n  blur: MarkerAreaEventHandler[] = [];\n\n\n  /**\n   * Add an event handler for a specific event type.\n   * @param eventType - event type.\n   * @param handler - function to handle the event.\n   */\n  public addEventListener<T extends keyof IEventListenerRepository>(\n    eventType: T,\n    handler: EventHandler<T>\n  ): void {\n    (<Array<EventHandler<T>>>this[eventType]).push(handler);\n  }\n\n  /**\n   * Remove an event handler for a specific event type.\n   * @param eventType - event type.\n   * @param handler - function currently handling the event.\n   */\n  public removeEventListener<T extends keyof IEventListenerRepository>(\n    eventType: T,\n    handler: EventHandler<T>\n  ): void {\n    const index = (<Array<EventHandler<T>>>this[eventType]).indexOf(handler);\n    if (index > -1) {\n      (<Array<EventHandler<T>>>this[eventType]).splice(index, 1);\n    }\n  }\n}\n","import { SvgHelper } from './core/SvgHelper';\nimport { Activator } from './core/Activator';\nimport { Renderer } from './core/Renderer';\n\nimport Logo from './assets/markerjs-logo-m.svg';\nimport { MarkerBase } from './core/MarkerBase';\nimport { Toolbar, ToolbarButtonType } from './ui/Toolbar';\nimport { Toolbox } from './ui/Toolbox';\nimport { FrameMarker } from './markers/frame-marker/FrameMarker';\nimport { Settings } from './core/Settings';\nimport { Style } from './core/Style';\nimport { LineMarker } from './markers/line-marker/LineMarker';\nimport { TextMarker } from './markers/text-marker/TextMarker';\nimport { FreehandMarker } from './markers/freehand-marker/FreehandMarker';\nimport { ArrowMarker } from './markers/arrow-marker/ArrowMarker';\nimport { CoverMarker } from './markers/cover-marker/CoverMarker';\nimport { HighlightMarker } from './markers/highlight-marker/HighlightMarker';\nimport { CalloutMarker } from './markers/callout-marker/CalloutMarker';\nimport { MarkerAreaState } from './MarkerAreaState';\nimport { EllipseMarker } from './markers/ellipse-marker/EllipseMarker';\nimport { IStyleSettings } from './core/IStyleSettings';\nimport { MeasurementMarker } from './markers/measurement-marker/MeasurementMarker';\nimport { IPoint } from './core/IPoint';\nimport { EllipseFrameMarker } from './markers/ellipse-frame-marker/EllipseFrameMarker';\nimport { UndoRedoManager } from './core/UndoRedoManager';\nimport { CurveMarker } from './markers/curve-marker/CurveMarker';\nimport { EventHandler, EventListenerRepository, IEventListenerRepository, MarkerAreaEvent, MarkerAreaRenderEvent, MarkerEvent } from './core/Events';\n\n/**\n * @ignore\n */\nexport type MarkerAreaMode = 'select' | 'create' | 'delete';\n\n/**\n * Identifier for marker type when setting {@linkcode availableMarkerTypes}.\n * Marker type can be set as either a string or a marker type reference.\n */\nexport type MarkerTypeIdentifier = string | typeof MarkerBase;\n\n/**\n * Event handler type for {@linkcode MarkerArea} `render` event.\n */\nexport type RenderEventHandler = (\n  dataURL: string,\n  state?: MarkerAreaState\n) => void;\n/**\n * Event handler type for {@linkcode MarkerArea} `close` event.\n */\nexport type CloseEventHandler = () => void;\n\n/**\n * MarkerArea is the main class of marker.js 2. It controls the behavior and appearance of the library.\n *\n * The simplest marker.js 2 usage scenario looks something like this:\n *\n * ```typescript\n * import * as markerjs2 from 'markerjs2';\n * // create an instance of MarkerArea and pass the target image reference as a parameter\n * let markerArea = new markerjs2.MarkerArea(document.getElementById('myimg'));\n *\n * // register an event listener for when user clicks OK/save in the marker.js UI\n * markerArea.addEventListener('render', event => {\n *   // we are setting the markup result to replace our original image on the page\n *   // but you can set a different image or upload it to your server\n *   document.getElementById('myimg').src = event.dataUrl;\n * });\n *\n * // finally, call the show() method and marker.js UI opens\n * markerArea.show();\n * ```\n */\nexport class MarkerArea {\n  private target: HTMLImageElement | HTMLElement;\n  private targetObserver: ResizeObserver;\n\n  private width: number;\n  private height: number;\n  private imageWidth: number;\n  private imageHeight: number;\n  private left: number;\n  private top: number;\n  private windowHeight: number;\n\n  private markerImage: SVGSVGElement;\n  private markerImageHolder: HTMLDivElement;\n  private defs: SVGDefsElement;\n\n  private coverDiv: HTMLDivElement;\n  private uiDiv: HTMLDivElement;\n  private contentDiv: HTMLDivElement;\n  private editorCanvas: HTMLDivElement;\n  private editingTarget: HTMLImageElement | HTMLCanvasElement;\n  private overlayContainer: HTMLDivElement;\n\n  private touchPoints = 0;\n\n  private logoUI: HTMLElement;\n\n  /**\n   * `targetRoot` is used to set an alternative positioning root for the marker.js UI.\n   *\n   * This is useful in cases when your target image is positioned, say, inside a div with `position: relative;`\n   *\n   * ```typescript\n   * // set targetRoot to a specific div instead of document.body\n   * markerArea.targetRoot = document.getElementById('myRootElement');\n   * ```\n   *\n   * @default document.body\n   */\n  public targetRoot: HTMLElement;\n\n  /**\n   * Returns a list of all built-in marker types for use with {@linkcode availableMarkerTypes}\n   *\n   * @readonly\n   */\n  public get ALL_MARKER_TYPES(): typeof MarkerBase[] {\n    return [\n      FrameMarker,\n      FreehandMarker,\n      ArrowMarker,\n      TextMarker,\n      EllipseFrameMarker,\n      EllipseMarker,\n      HighlightMarker,\n      CalloutMarker,\n      MeasurementMarker,\n      CoverMarker,\n      LineMarker,\n      CurveMarker,\n    ];\n  }\n\n  /**\n   * Returns a list of default set of built-in marker types.\n   * Used when {@linkcode availableMarkerTypes} isn't set explicitly.\n   *\n   * @readonly\n   */\n  public get DEFAULT_MARKER_TYPES(): typeof MarkerBase[] {\n    return [\n      FrameMarker,\n      FreehandMarker,\n      ArrowMarker,\n      TextMarker,\n      EllipseMarker,\n      HighlightMarker,\n      CalloutMarker,\n    ];\n  }\n\n  /**\n   * Returns a short list of essential built-in marker types for use with {@linkcode availableMarkerTypes}\n   *\n   * @readonly\n   */\n  public get BASIC_MARKER_TYPES(): typeof MarkerBase[] {\n    return [\n      FrameMarker,\n      FreehandMarker,\n      ArrowMarker,\n      TextMarker,\n      HighlightMarker,\n    ];\n  }\n\n  private _availableMarkerTypes: typeof MarkerBase[] = this\n    .DEFAULT_MARKER_TYPES;\n\n  /**\n   * Gets or sets a list of marker types avaiable to the user in the toolbar.\n   * The types can be passed as either type reference or a string type name.\n   *\n   * ```typescript\n   * this.markerArea1.availableMarkerTypes = ['CalloutMarker', ...this.markerArea1.BASIC_MARKER_TYPES];\n   * ```\n   *\n   * @default {@linkcode DEFAULT_MARKER_TYPES}\n   */\n  public get availableMarkerTypes(): MarkerTypeIdentifier[] {\n    return this._availableMarkerTypes;\n  }\n\n  public set availableMarkerTypes(value: MarkerTypeIdentifier[]) {\n    this._availableMarkerTypes.splice(0);\n    value.forEach((mt) => {\n      if (typeof mt === 'string') {\n        const typeType = this.ALL_MARKER_TYPES.find(\n          (allT) => allT.typeName === mt\n        );\n        if (typeType !== undefined) {\n          this._availableMarkerTypes.push(typeType);\n        }\n      } else {\n        this._availableMarkerTypes.push(mt);\n      }\n    });\n  }\n\n  private toolbar: Toolbar;\n  private toolbox: Toolbox;\n\n  private mode: MarkerAreaMode = 'select';\n\n  private currentMarker?: MarkerBase;\n  private markers: MarkerBase[] = [];\n\n  private isDragging = false;\n\n  // for preserving orginal window state before opening the editor\n  private bodyOverflowState: string;\n  private scrollYState: number;\n  private scrollXState: number;\n\n  private renderEventListeners: RenderEventHandler[] = [];\n  private closeEventListeners: CloseEventHandler[] = [];\n\n  public settings: Settings = new Settings();\n  public uiStyleSettings: IStyleSettings;\n\n  private _isOpen = false;\n  /**\n   * Returns `true` when MarkerArea is open and `false` otherwise.\n   *\n   * @readonly\n   */\n  public get isOpen(): boolean {\n    return this._isOpen;\n  }\n\n  private undoRedoManager: UndoRedoManager<\n    MarkerAreaState\n  > = new UndoRedoManager<MarkerAreaState>();\n\n  /**\n   * When set to true resulting image will be rendered at the natural (original) resolution\n   * of the target image. Otherwise (default), screen dimensions of the image are used.\n   *\n   * @default false (use screen dimensions)\n   */\n  public renderAtNaturalSize = false;\n  /**\n   * Type of image for the rendering result. Eg. `image/png` (default) or `image/jpeg`.\n   *\n   * @default `image/png`\n   */\n  public renderImageType = 'image/png';\n  /**\n   * When rendering engine/format supports it (jpeg, for exmample),\n   * sets the rendering quality for the resulting image.\n   *\n   * In case of `image/jpeg` the value should be between 0 (worst quality) and 1 (best quality).\n   */\n  public renderImageQuality?: number;\n  /**\n   * When set to `true`, will render only the marker layer without the original image.\n   * This could be useful when you want to non-destructively overlay markers on top of the original image.\n   *\n   * Note that in order for the markers layer to have a transparent background {@linkcode renderImageType}\n   * should be set to a format supporting transparency, such as `image/png`.\n   *\n   * @default false\n   */\n  public renderMarkersOnly = false;\n\n  /**\n   * When set and {@linkcode renderAtNaturalSize} is `false` sets the width of the rendered image.\n   *\n   * Both `renderWidth` and `renderHeight` have to be set for this to take effect.\n   */\n  public renderWidth?: number;\n  /**\n   * When set and {@linkcode renderAtNaturalSize} is `false` sets the height of the rendered image.\n   *\n   * Both `renderWidth` and `renderHeight` have to be set for this to take effect.\n   */\n  public renderHeight?: number;\n\n  /**\n   * If a canvas is specified here, then marker.js will render the output to this canvas\n   * in addition to generating an image.\n   *\n   * @since 2.14.0\n   */\n  public renderTarget?: HTMLCanvasElement;\n\n  /**\n   * Pressing zoom button iterates through values in this array.\n   *\n   * @since 2.12.0\n   */\n  public zoomSteps = [1, 1.5, 2, 4];\n  private _zoomLevel = 1;\n  /**\n   * Gets current zoom level.\n   *\n   * @since 2.12.0\n   */\n  public get zoomLevel(): number {\n    return this._zoomLevel;\n  }\n  /**\n   * Sets current zoom level.\n   *\n   * @since 2.12.0\n   */\n  public set zoomLevel(value: number) {\n    this._zoomLevel = value;\n    if (this.editorCanvas && this.contentDiv) {\n      this.editorCanvas.style.transform = `scale(${this._zoomLevel})`;\n      this.contentDiv.scrollTo({\n        left:\n          (this.editorCanvas.clientWidth * this._zoomLevel -\n            this.contentDiv.clientWidth) /\n          2,\n        top:\n          (this.editorCanvas.clientHeight * this._zoomLevel -\n            this.contentDiv.clientHeight) /\n          2,\n      });\n    }\n  }\n\n  /**\n   * Creates a new MarkerArea for the specified target image.\n   *\n   * ```typescript\n   * // create an instance of MarkerArea and pass the target image (or other HTML element) reference as a parameter\n   * let markerArea = new markerjs2.MarkerArea(document.getElementById('myimg'));\n   * ```\n   *\n   * When `target` is not an image object the output is limited to \"markers only\" (@linkcode renderMarkersOnly)\n   * and \"popup\" mode won't work properly as the target object stays in it's original position and, unlike images,\n   * is not copied.\n   *\n   * @param target image object to mark up.\n   */\n  constructor(target: HTMLImageElement | HTMLElement) {\n    Style.settings = Style.defaultSettings;\n    this.uiStyleSettings = Style.settings;\n\n    this.target = target;\n    this.targetRoot = document.body;\n\n    this.width = target.clientWidth;\n    this.height = target.clientHeight;\n\n    Style.removeStyleSheet();\n\n    this.open = this.open.bind(this);\n    this.setTopLeft = this.setTopLeft.bind(this);\n\n    this.toolbarButtonClicked = this.toolbarButtonClicked.bind(this);\n    this.createNewMarker = this.createNewMarker.bind(this);\n    this.addNewMarker = this.addNewMarker.bind(this);\n    this.markerCreated = this.markerCreated.bind(this);\n    this.setCurrentMarker = this.setCurrentMarker.bind(this);\n    this.onPointerDown = this.onPointerDown.bind(this);\n    this.onDblClick = this.onDblClick.bind(this);\n    this.onPointerMove = this.onPointerMove.bind(this);\n    this.onPointerUp = this.onPointerUp.bind(this);\n    this.onPointerOut = this.onPointerOut.bind(this);\n    this.onKeyUp = this.onKeyUp.bind(this);\n    this.overrideOverflow = this.overrideOverflow.bind(this);\n    this.restoreOverflow = this.restoreOverflow.bind(this);\n    this.close = this.close.bind(this);\n    this.closeUI = this.closeUI.bind(this);\n    this.addCloseEventListener = this.addCloseEventListener.bind(this);\n    this.removeCloseEventListener = this.removeCloseEventListener.bind(this);\n    this.addRenderEventListener = this.addRenderEventListener.bind(this);\n    this.removeRenderEventListener = this.removeRenderEventListener.bind(this);\n    this.clientToLocalCoordinates = this.clientToLocalCoordinates.bind(this);\n    this.onWindowResize = this.onWindowResize.bind(this);\n    this.deleteSelectedMarker = this.deleteSelectedMarker.bind(this);\n    this.setWindowHeight = this.setWindowHeight.bind(this);\n    this.removeMarker = this.removeMarker.bind(this);\n    this.colorChanged = this.colorChanged.bind(this);\n    this.fillColorChanged = this.fillColorChanged.bind(this);\n    this.onPopupTargetResize = this.onPopupTargetResize.bind(this);\n    this.showNotesEditor = this.showNotesEditor.bind(this);\n    this.hideNotesEditor = this.hideNotesEditor.bind(this);\n    this.stepZoom = this.stepZoom.bind(this);\n    this.focus = this.focus.bind(this);\n    this.blur = this.blur.bind(this);\n  }\n\n  private open(): void {\n    this.setupResizeObserver();\n    this.setEditingTarget();\n    this.setTopLeft();\n    this.initMarkerCanvas();\n    this.initOverlay();\n    this.attachEvents();\n    if (this.settings.displayMode === 'popup') {\n      this.onPopupTargetResize();\n    }\n\n    if (!Activator.isLicensed) {\n      // NOTE:\n      // before removing this call please consider supporting marker.js\n      // by visiting https://markerjs.com/ for details\n      // thank you!\n      this.addLogo();\n    }\n\n    this._isOpen = true;\n    this._isFocused = true;\n  }\n\n  /**\n   * Initializes the MarkerArea and opens the UI.\n   */\n  public show(): void {\n    this.setWindowHeight();\n    this.showUI();\n    this.open();\n    this.eventListeners['show'].forEach(listener => listener(new MarkerAreaEvent(this)));\n  }\n\n  /**\n   * Renders the annotation result.\n   *\n   * Normally, you should use {@linkcode addEventListener} method to set a listener for the `render` event\n   * rather than calling this method directly.\n   */\n  public async render(): Promise<string> {\n    this.setCurrentMarker();\n\n    const renderer = new Renderer();\n    renderer.naturalSize = this.renderAtNaturalSize;\n    renderer.imageType = this.renderImageType;\n    renderer.imageQuality = this.renderImageQuality;\n    renderer.markersOnly = this.renderMarkersOnly;\n    renderer.width = this.renderWidth;\n    renderer.height = this.renderHeight;\n\n    // workaround for an issue in Safari where FreeHand marker\n    // is not rendered on the first try for some reason\n    await renderer.rasterize(\n      this.target instanceof HTMLImageElement ? this.target : null,\n      this.markerImage,\n      this.renderTarget\n    );\n\n    return await renderer.rasterize(\n      this.target instanceof HTMLImageElement ? this.target : null,\n      this.markerImage,\n      this.renderTarget\n    );\n  }\n\n  /**\n   * Closes the MarkerArea UI.\n   */\n  public close(suppressBeforeClose = false): void {\n    if (this.isOpen) {\n      let cancel = false;\n\n      if (!suppressBeforeClose) {\n        this.eventListeners['beforeclose'].forEach(listener => {\n          const ev = new MarkerAreaEvent(this, true);\n          listener(ev);\n          if (ev.defaultPrevented) {\n            cancel = true;\n          }\n        });\n      }\n      \n      if (!cancel) {\n        if (this.coverDiv) {\n          this.closeUI();\n        }\n        if (this.targetObserver) {\n          this.targetObserver.unobserve(this.target);\n        }\n        if (this.settings.displayMode === 'popup') {\n          window.removeEventListener('resize', this.setWindowHeight);\n        }\n        //this.closeEventListeners.forEach((listener) => listener());\n        this.eventListeners['close'].forEach(listener => listener(new MarkerAreaEvent(this)));\n        this.detachEvents();\n        this._isOpen = false;\n      }\n    }\n  }\n\n  /**\n   * Adds one or more markers to the toolbar.\n   *\n   * @param markers - one or more marker types to be added.\n   */\n  public addMarkersToToolbar(...markers: typeof MarkerBase[]): void {\n    this._availableMarkerTypes.push(...markers);\n  }\n\n  /**\n   * Add a `render` event listener which is called when user clicks on the OK/save button\n   * in the toolbar.\n   *\n   * ```typescript\n   * // register an event listener for when user clicks OK/save in the marker.js UI\n   * markerArea.addRenderEventListener(dataUrl => {\n   *   // we are setting the markup result to replace our original image on the page\n   *   // but you can set a different image or upload it to your server\n   *   document.getElementById('myimg').src = dataUrl;\n   * });\n   * ```\n   *\n   * This is where you place your code to save a resulting image and/or MarkerAreaState.\n   *\n   * @param listener - a method handling rendering results\n   *\n   * @see {@link MarkerAreaState}\n   * @deprecated use `addEventListener('render', ...)` instead.\n   */\n  public addRenderEventListener(listener: RenderEventHandler): void {\n    //this.renderEventListeners.push(listener);\n    this.addEventListener('render', (event: MarkerAreaRenderEvent) => {\n      listener(event.dataUrl, event.state);\n    });\n  }\n\n  /**\n   * Remove a `render` event handler.\n   *\n   * @param listener - previously registered `render` event handler.\n   * @deprecated use `removeEventListener('render', ...)` instead.\n   */\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars\n  public removeRenderEventListener(listener: RenderEventHandler): void {\n    // if (this.renderEventListeners.indexOf(listener) > -1) {\n    //   this.renderEventListeners.splice(\n    //     this.renderEventListeners.indexOf(listener),\n    //     1\n    //   );\n    // }\n  }\n\n  /**\n   * Add a `close` event handler to perform actions in your code after the user\n   * clicks on the close button (without saving).\n   *\n   * @param listener - close event listener\n   * @deprecated use `addEventListener('close', ...)` instead.\n   */\n  public addCloseEventListener(listener: CloseEventHandler): void {\n    //this.closeEventListeners.push(listener);\n    this.addEventListener('close', () => {\n      listener();\n    });\n  }\n\n  /**\n   * Remove a `close` event handler.\n   *\n   * @param listener - previously registered `close` event handler.\n   * @deprecated use `removeEventListener('close', ...)` instead.\n   */\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars\n  public removeCloseEventListener(listener: CloseEventHandler): void {\n    // if (this.closeEventListeners.indexOf(listener) > -1) {\n    //   this.closeEventListeners.splice(\n    //     this.closeEventListeners.indexOf(listener),\n    //     1\n    //   );\n    // }\n  }\n\n  private setupResizeObserver() {\n    if (this.settings.displayMode === 'inline') {\n      if (window.ResizeObserver) {\n        this.targetObserver = new ResizeObserver(() => {\n          this.resize(this.target.clientWidth, this.target.clientHeight);\n        });\n        this.targetObserver.observe(this.target);\n      }\n    } else if (this.settings.displayMode === 'popup') {\n      if (window.ResizeObserver) {\n        this.targetObserver = new ResizeObserver(() =>\n          this.onPopupTargetResize()\n        );\n        this.targetObserver.observe(this.editorCanvas);\n      }\n      window.addEventListener('resize', this.setWindowHeight);\n    }\n  }\n\n  private onPopupTargetResize() {\n    const ratio = (1.0 * this.target.clientWidth) / this.target.clientHeight;\n    const newWidth =\n      this.editorCanvas.clientWidth / ratio > this.editorCanvas.clientHeight\n        ? this.editorCanvas.clientHeight * ratio\n        : this.editorCanvas.clientWidth;\n    const newHeight =\n      newWidth < this.editorCanvas.clientWidth\n        ? this.editorCanvas.clientHeight\n        : this.editorCanvas.clientWidth / ratio;\n    this.resize(newWidth, newHeight);\n  }\n\n  private setWindowHeight() {\n    this.windowHeight = window.innerHeight;\n  }\n\n  private resize(newWidth: number, newHeight: number) {\n    const scaleX = newWidth / this.imageWidth;\n    const scaleY = newHeight / this.imageHeight;\n\n    this.imageWidth = Math.round(newWidth);\n    this.imageHeight = Math.round(newHeight);\n    if (\n      this.target instanceof HTMLImageElement &&\n      this.editingTarget instanceof HTMLImageElement\n    ) {\n      this.editingTarget.src = this.target.src;\n    }\n    this.editingTarget.width = this.imageWidth;\n    this.editingTarget.height = this.imageHeight;\n    this.editingTarget.style.width = `${this.imageWidth}px`;\n    this.editingTarget.style.height = `${this.imageHeight}px`;\n\n    this.markerImage.setAttribute('width', this.imageWidth.toString());\n    this.markerImage.setAttribute('height', this.imageHeight.toString());\n    this.markerImage.setAttribute(\n      'viewBox',\n      '0 0 ' + this.imageWidth.toString() + ' ' + this.imageHeight.toString()\n    );\n\n    this.markerImageHolder.style.width = `${this.imageWidth}px`;\n    this.markerImageHolder.style.height = `${this.imageHeight}px`;\n\n    this.overlayContainer.style.width = `${this.imageWidth}px`;\n    this.overlayContainer.style.height = `${this.imageHeight}px`;\n\n    if (this.settings.displayMode !== 'popup') {\n      this.coverDiv.style.width = `${this.imageWidth.toString()}px`;\n    } else {\n      this.setTopLeft();\n      this.positionMarkerImage();\n    }\n\n    if (this.toolbar !== undefined) {\n      this.toolbar.adjustLayout();\n    }\n\n    this.positionLogo();\n\n    this.scaleMarkers(scaleX, scaleY);\n  }\n\n  private scaleMarkers(scaleX: number, scaleY: number) {\n    let preScaleSelectedMarker: MarkerBase;\n    if (!(this.currentMarker && this.currentMarker instanceof TextMarker)) {\n      preScaleSelectedMarker = this.currentMarker;\n      this.setCurrentMarker();\n    }\n    this.markers.forEach((marker) => marker.scale(scaleX, scaleY));\n    if (preScaleSelectedMarker !== undefined) {\n      this.setCurrentMarker(preScaleSelectedMarker);\n    }\n  }\n\n  private setEditingTarget() {\n    this.imageWidth = Math.round(this.target.clientWidth);\n    this.imageHeight = Math.round(this.target.clientHeight);\n    if (\n      this.target instanceof HTMLImageElement &&\n      this.editingTarget instanceof HTMLImageElement\n    ) {\n      this.editingTarget.src = this.target.src;\n    }\n    this.editingTarget.width = this.imageWidth;\n    this.editingTarget.height = this.imageHeight;\n    this.editingTarget.style.width = `${this.imageWidth}px`;\n    this.editingTarget.style.height = `${this.imageHeight}px`;\n  }\n\n  private setTopLeft() {\n    const targetRect = this.editingTarget.getBoundingClientRect();\n    const bodyRect = this.editorCanvas.getBoundingClientRect();\n    this.left = targetRect.left - bodyRect.left;\n    this.top = targetRect.top - bodyRect.top;\n  }\n\n  private initMarkerCanvas(): void {\n    this.markerImageHolder = document.createElement('div');\n    this.markerImageHolder.style.setProperty('touch-action', 'pinch-zoom');\n\n    this.markerImage = document.createElementNS(\n      'http://www.w3.org/2000/svg',\n      'svg'\n    );\n    this.markerImage.setAttribute('xmlns', 'http://www.w3.org/2000/svg');\n    this.markerImage.setAttribute('width', this.imageWidth.toString());\n    this.markerImage.setAttribute('height', this.imageHeight.toString());\n    this.markerImage.setAttribute(\n      'viewBox',\n      '0 0 ' + this.imageWidth.toString() + ' ' + this.imageHeight.toString()\n    );\n    this.markerImage.style.pointerEvents = 'auto';\n\n    this.markerImageHolder.style.position = 'absolute';\n    this.markerImageHolder.style.width = `${this.imageWidth}px`;\n    this.markerImageHolder.style.height = `${this.imageHeight}px`;\n    this.markerImageHolder.style.transformOrigin = 'top left';\n    this.positionMarkerImage();\n\n    this.markerImageHolder.appendChild(this.markerImage);\n\n    this.editorCanvas.appendChild(this.markerImageHolder);\n  }\n\n  /**\n   * Adds \"defs\" element to the marker SVG element. \n   * Useful for using custom fonts and potentially other scenarios.\n   *\n   * @param {(...(string | Node)[])} nodes\n   * @see Documentation article on adding custom fonts for an example\n   */\n  public addDefs(...nodes: (string | Node)[]): void {\n    this.defs = SvgHelper.createDefs();\n    this.markerImage.insertBefore(this.defs, this.markerImage.firstChild);\n\n    this.defs.append(...nodes);\n  }\n\n  private initOverlay(): void {\n    this.overlayContainer = document.createElement('div');\n    this.overlayContainer.style.position = 'absolute';\n    this.overlayContainer.style.left = '0px';\n    this.overlayContainer.style.top = '0px';\n    this.overlayContainer.style.width = `${this.imageWidth}px`;\n    this.overlayContainer.style.height = `${this.imageHeight}px`;\n    this.overlayContainer.style.display = 'flex';\n    this.markerImageHolder.appendChild(this.overlayContainer);\n  }\n\n  private positionMarkerImage() {\n    this.markerImageHolder.style.top = this.top / this.zoomLevel + 'px';\n    this.markerImageHolder.style.left = this.left / this.zoomLevel + 'px';\n  }\n\n  private attachEvents() {\n    this.markerImage.addEventListener('pointerdown', this.onPointerDown);\n    this.markerImage.addEventListener('dblclick', this.onDblClick);\n    this.attachWindowEvents();\n  }\n\n  private attachWindowEvents() {\n    window.addEventListener('pointermove', this.onPointerMove);\n    window.addEventListener('pointerup', this.onPointerUp);\n    window.addEventListener('pointercancel', this.onPointerOut);\n    window.addEventListener('pointerout', this.onPointerOut);\n    window.addEventListener('pointerleave', this.onPointerUp);\n    window.addEventListener('resize', this.onWindowResize);\n    window.addEventListener('keyup', this.onKeyUp);\n  }\n\n  private detachEvents() {\n    this.markerImage.removeEventListener('pointerdown', this.onPointerDown);\n    this.markerImage.removeEventListener('dblclick', this.onDblClick);\n    this.detachWindowEvents();\n  }\n\n  private detachWindowEvents() {\n    window.removeEventListener('pointermove', this.onPointerMove);\n    window.removeEventListener('pointerup', this.onPointerUp);\n    window.removeEventListener('pointercancel', this.onPointerOut);\n    window.removeEventListener('pointerout', this.onPointerOut);\n    window.removeEventListener('pointerleave', this.onPointerUp);\n    window.removeEventListener('resize', this.onWindowResize);\n    window.removeEventListener('keyup', this.onKeyUp);\n  }\n\n  /**\n   * NOTE:\n   *\n   * before removing or modifying this method please consider supporting marker.js\n   * by visiting https://markerjs.com/#price for details\n   *\n   * thank you!\n   */\n  private addLogo() {\n    this.logoUI = document.createElement('div');\n    this.logoUI.style.display = 'inline-block';\n    this.logoUI.style.margin = '0px';\n    this.logoUI.style.padding = '0px';\n    this.logoUI.style.fill = '#333333';\n\n    const link = document.createElement('a');\n    link.href = 'https://markerjs.com/';\n    link.target = '_blank';\n    link.innerHTML = Logo;\n    link.title = 'Powered by marker.js';\n\n    link.style.display = 'grid';\n    link.style.alignItems = 'center';\n    link.style.justifyItems = 'center';\n    link.style.padding = '3px';\n    link.style.width = '20px';\n    link.style.height = '20px';\n\n    this.logoUI.appendChild(link);\n\n    this.editorCanvas.appendChild(this.logoUI);\n\n    this.logoUI.style.position = 'absolute';\n    this.logoUI.style.pointerEvents = 'all';\n    this.positionLogo();\n  }\n\n  private positionLogo() {\n    if (this.logoUI) {\n      if (this.uiStyleSettings.logoPosition !== 'right') {\n        this.logoUI.style.left = `${this.markerImageHolder.offsetLeft + 10}px`;\n      } else {\n        this.logoUI.style.left = `${\n          this.markerImageHolder.offsetLeft +\n          this.markerImageHolder.offsetWidth -\n          this.logoUI.clientWidth -\n          10\n        }px`;\n      }\n      this.logoUI.style.top = `${\n        this.markerImageHolder.offsetTop +\n        this.markerImageHolder.offsetHeight -\n        this.logoUI.clientHeight -\n        10\n      }px`;\n    }\n  }\n\n  private overrideOverflow() {\n    // backup current state of scrolling and overflow\n    this.scrollXState = window.scrollX;\n    this.scrollYState = window.scrollY;\n    this.bodyOverflowState = document.body.style.overflow;\n\n    window.scroll({ top: 0, left: 0 });\n    document.body.style.overflow = 'hidden';\n  }\n\n  private restoreOverflow() {\n    document.body.style.overflow = this.bodyOverflowState;\n    window.scroll({ top: this.scrollYState, left: this.scrollXState });\n  }\n\n  private showUI(): void {\n    if (this.settings.displayMode === 'popup') {\n      this.overrideOverflow();\n    }\n\n    this.coverDiv = document.createElement('div');\n    // prevent UI from blinking when just rendering state\n    this.coverDiv.style.visibility = this._silentRenderMode ? 'hidden' : 'visible';\n    this.coverDiv.className = Style.CLASS_PREFIX;\n    // hardcode font size so nothing inside is affected by higher up settings\n    this.coverDiv.style.fontSize = '16px';\n    this.coverDiv.style.userSelect = 'none';\n\n    switch (this.settings.displayMode) {\n      case 'inline': {\n        this.coverDiv.style.position = 'absolute';\n        const coverTop =\n          this.target.getClientRects().item(0).y > Style.settings.toolbarHeight\n            ? this.target.offsetTop - Style.settings.toolbarHeight\n            : 0;\n        this.coverDiv.style.top = `${coverTop}px`;\n        this.coverDiv.style.left = `${this.target.offsetLeft.toString()}px`;\n        this.coverDiv.style.width = `${this.target.offsetWidth.toString()}px`;\n        //this.coverDiv.style.height = `${this.target.offsetHeight.toString()}px`;\n        this.coverDiv.style.zIndex =\n          this.uiStyleSettings.zIndex !== undefined\n            ? this.uiStyleSettings.zIndex\n            : '5';\n        // flex causes the ui to stretch when toolbox has wider nowrap panels\n        //this.coverDiv.style.display = 'flex';\n        break;\n      }\n      case 'popup': {\n        this.coverDiv.style.position = 'absolute';\n        this.coverDiv.style.top = '0px';\n        this.coverDiv.style.left = '0px';\n        this.coverDiv.style.width = '100vw';\n        this.coverDiv.style.height = `${window.innerHeight}px`;\n        this.coverDiv.style.backgroundColor = 'rgba(0, 0, 0, 0.75)';\n        this.coverDiv.style.zIndex =\n          this.uiStyleSettings.zIndex !== undefined\n            ? this.uiStyleSettings.zIndex\n            : '1000';\n        this.coverDiv.style.display = 'flex';\n        // this.coverDiv.style.overflow = 'auto';\n      }\n    }\n    this.targetRoot.appendChild(this.coverDiv);\n\n    this.uiDiv = document.createElement('div');\n    this.uiDiv.style.display = 'flex';\n    this.uiDiv.style.flexDirection = 'column';\n    this.uiDiv.style.flexGrow = '2';\n    this.uiDiv.style.margin =\n      this.settings.displayMode === 'popup'\n        ? `${this.settings.popupMargin}px`\n        : '0px';\n    this.uiDiv.style.border = '0px';\n    // this.uiDiv.style.overflow = 'hidden';\n    //this.uiDiv.style.backgroundColor = '#ffffff';\n    this.coverDiv.appendChild(this.uiDiv);\n\n    this.toolbar = new Toolbar(\n      this.uiDiv,\n      this.settings.displayMode,\n      this._availableMarkerTypes,\n      this.uiStyleSettings\n    );\n    this.toolbar.addButtonClickListener(this.toolbarButtonClicked);\n    this.toolbar.show((this._silentRenderMode || this.uiStyleSettings.hideToolbar) ? 'hidden' : 'visible');\n\n    this.contentDiv = document.createElement('div');\n    this.contentDiv.style.display = 'flex';\n    this.contentDiv.style.flexDirection = 'row';\n    this.contentDiv.style.flexGrow = '2';\n    this.contentDiv.style.flexShrink = '1';\n    if (this.settings.displayMode === 'popup') {\n      this.contentDiv.style.backgroundColor = this.uiStyleSettings.canvasBackgroundColor;\n      this.contentDiv.style.maxHeight = `${\n        this.windowHeight -\n        this.settings.popupMargin * 2 -\n        this.uiStyleSettings.toolbarHeight * 3.5\n      }px`;\n      // this.contentDiv.style.maxHeight = `calc(100vh - ${\n      //   this.settings.popupMargin * 2 + this.uiStyleSettings.toolbarHeight * 3.5}px)`;\n      this.contentDiv.style.maxWidth = `calc(100vw - ${\n        this.settings.popupMargin * 2\n      }px)`;\n    }\n    this.contentDiv.style.overflow = 'auto';\n    this.uiDiv.appendChild(this.contentDiv);\n\n    this.editorCanvas = document.createElement('div');\n    this.editorCanvas.style.flexGrow = '2';\n    this.editorCanvas.style.flexShrink = '1';\n    this.editorCanvas.style.position = 'relative';\n    this.editorCanvas.style.overflow = 'hidden';\n    this.editorCanvas.style.display = 'flex';\n    if (this.settings.displayMode === 'popup') {\n      this.editorCanvas.style.alignItems = 'center';\n      this.editorCanvas.style.justifyContent = 'center';\n    }\n    this.editorCanvas.style.pointerEvents = 'none';\n    this.editorCanvas.style.transformOrigin = 'left top';\n    this.editorCanvas.style.transform = `scale(${this.zoomLevel})`;\n    this.contentDiv.appendChild(this.editorCanvas);\n\n    this.editingTarget =\n      this.target instanceof HTMLImageElement\n        ? document.createElement('img')\n        : document.createElement('canvas');\n    if (this.target.getClientRects().item(0).y < Style.settings.toolbarHeight) {\n      this.editingTarget.style.marginTop = `${\n        this.target.offsetTop - Style.settings.toolbarHeight\n      }px`;\n    }\n    this.editorCanvas.appendChild(this.editingTarget);\n\n    this.toolbox = new Toolbox(\n      this.uiDiv,\n      this.settings.displayMode,\n      this.uiStyleSettings\n    );\n    this.toolbox.show((this._silentRenderMode || this.uiStyleSettings.hideToolbox) ? 'hidden' : 'visible');\n  }\n\n  private closeUI() {\n    if (this.settings.displayMode === 'popup') {\n      this.restoreOverflow();\n    }\n    // @todo better cleanup\n    this.targetRoot.removeChild(this.coverDiv);\n  }\n\n  private removeMarker(marker: MarkerBase) {\n    this.markerImage.removeChild(marker.container);\n    if (this.markers.indexOf(marker) > -1) {\n      this.markers.splice(this.markers.indexOf(marker), 1);\n    }\n    marker.dispose();\n  }\n\n  private switchToSelectMode() {\n    this.mode = 'select';\n    this.hideNotesEditor();\n    if (this.currentMarker !== undefined) {\n      if (this.currentMarker.state !== 'new') {\n        this.currentMarker.select();\n      } else {\n        this.removeMarker(this.currentMarker);\n        this.setCurrentMarker();\n        this.markerImage.style.cursor = 'default';\n      }\n      this.addUndoStep();\n    }\n  }\n\n  private toolbarButtonClicked(\n    buttonType: ToolbarButtonType,\n    value?: typeof MarkerBase | string\n  ) {\n    if (buttonType === 'marker' && value !== undefined) {\n      this.createNewMarker(<typeof MarkerBase>value);\n    } else if (buttonType === 'action') {\n      switch (value) {\n        case 'select': {\n          this.switchToSelectMode();\n          break;\n        }\n        case 'delete': {\n          this.deleteSelectedMarker();\n          break;\n        }\n        case 'clear': {\n          this.clear();\n          break;\n        }\n        case 'undo': {\n          this.switchToSelectMode();\n          this.addUndoStep();\n          this.undo();\n          break;\n        }\n        case 'redo': {\n          this.switchToSelectMode();\n          this.redo();\n          break;\n        }\n        case 'zoom': {\n          this.stepZoom();\n          break;\n        }\n        case 'zoom-out': {\n          this.zoomLevel = 1;\n          break;\n        }\n        case 'notes': {\n          if (this.notesArea === undefined) {\n            this.switchToSelectMode();\n            this.zoomLevel = 1;\n            this.showNotesEditor();\n          } else {\n            this.switchToSelectMode();\n          }\n          break;\n        }\n        case 'close': {\n          this.close();\n          break;\n        }\n        case 'render': {\n          this.switchToSelectMode();\n          this.startRenderAndClose();\n          break;\n        }\n      }\n    }\n  }\n\n  /**\n   * Removes currently selected marker.\n   */\n  public deleteSelectedMarker(): void {\n    if (this.currentMarker !== undefined) {\n      let cancel = false;\n\n      this.eventListeners['markerbeforedelete'].forEach(listener => {\n        const ev = new MarkerEvent(this, this.currentMarker, true);\n        listener(ev);\n        if (ev.defaultPrevented) {\n          cancel = true;\n        }\n      });\n      \n      if (!cancel) {\n        const marker = this.currentMarker;\n        this.currentMarker.dispose();\n        this.markerImage.removeChild(this.currentMarker.container);\n        this.markers.splice(this.markers.indexOf(this.currentMarker), 1);\n        this.setCurrentMarker();\n        this.addUndoStep();\n        this.eventListeners['markerdelete'].forEach(listener => listener(new MarkerEvent(this, marker)));\n      }\n    }\n  }\n\n  /**\n   * Removes all markers.\n   * \n   * @since 2.15.0\n   */\n  public clear(): void {\n    this.setCurrentMarker();\n    for (let i = this.markers.length - 1; i >= 0; i--) {\n      this.setCurrentMarker(this.markers[i]);\n      this.currentMarker.dispose();\n      this.markerImage.removeChild(this.currentMarker.container);\n      this.markers.splice(this.markers.indexOf(this.currentMarker), 1);\n    }\n    this.addUndoStep();\n  }\n\n  private notesArea?: HTMLTextAreaElement;\n  private get isNotesAreaOpen(): boolean {\n    return this.notesArea !== undefined;\n  }\n\n  private showNotesEditor() {\n    if (this.currentMarker !== undefined) {\n      this.overlayContainer.innerHTML = '';\n      this.notesArea = document.createElement('textarea');\n      this.notesArea.className = this.uiStyleSettings.notesAreaStyleClassName;\n      this.notesArea.style.pointerEvents = 'auto';\n      this.notesArea.style.alignSelf = 'stretch';\n      this.notesArea.style.width = '100%';\n      this.notesArea.style.margin = `${\n        this.uiStyleSettings.toolbarHeight / 4\n      }px`;\n      this.notesArea.value = this.currentMarker.notes ?? '';\n      this.overlayContainer.appendChild(this.notesArea);\n    }\n  }\n  private hideNotesEditor() {\n    if (this.isNotesAreaOpen) {\n      if (this.currentMarker !== undefined) {\n        this.currentMarker.notes =\n          this.notesArea.value.trim() !== '' ? this.notesArea.value : undefined;\n      }\n      this.overlayContainer.removeChild(this.notesArea);\n      this.notesArea = undefined;\n    }\n  }\n\n  private selectLastMarker() {\n    if (this.markers.length > 0) {\n      this.setCurrentMarker(this.markers[this.markers.length - 1]);\n    }\n  }\n\n  private addUndoStep() {\n    if (\n      this.currentMarker === undefined ||\n      this.currentMarker.state !== 'edit'\n    ) {\n      this.undoRedoManager.addUndoStep(this.getState());\n    }\n  }\n\n  /**\n   * Undo last action.\n   *\n   * @since 2.6.0\n   */\n  public undo(): void {\n    const stepData = this.undoRedoManager.undo();\n    if (stepData !== undefined) {\n      this.restoreState(stepData);\n      this.selectLastMarker();\n    }\n  }\n\n  /**\n   * Redo previously undone action.\n   *\n   * @since 2.6.0\n   */\n  public redo(): void {\n    const stepData = this.undoRedoManager.redo();\n    if (stepData !== undefined) {\n      this.restoreState(stepData);\n      this.selectLastMarker();\n    }\n  }\n\n  /**\n   * Iterate zoom steps (@linkcode zoomSteps).\n   * Next zoom level is selected or returns to the first zoom level restarting the sequence.\n   *\n   * @since 2.12.0\n   */\n  public stepZoom(): void {\n    const zoomStepIndex = this.zoomSteps.indexOf(this.zoomLevel);\n    this.zoomLevel =\n      zoomStepIndex < this.zoomSteps.length - 1\n        ? this.zoomSteps[zoomStepIndex + 1]\n        : this.zoomSteps[0];\n  }\n\n  private prevPanPoint: IPoint = { x: 0, y: 0 };\n  private panTo(point: IPoint) {\n    this.contentDiv.scrollBy({\n      left: this.prevPanPoint.x - point.x,\n      top: this.prevPanPoint.y - point.y,\n    });\n    this.prevPanPoint = point;\n  }\n\n  /**\n   * Initiates markup rendering.\n   *\n   * Get results by adding a render event listener via {@linkcode addRenderEventListener}.\n   */\n  public async startRenderAndClose(): Promise<void> {\n    const result = await this.render();\n    const state = this.getState();\n    //this.renderEventListeners.forEach((listener) => listener(result, state));\n    this.eventListeners['render'].forEach(listener => listener(new MarkerAreaRenderEvent(this, result, state)));\n    this.close(true);\n  }\n\n  /**\n   * Returns the complete state for the MarkerArea that can be preserved and used\n   * to continue annotation next time.\n   *\n   * @param deselectCurrentMarker - when `true` is passed, currently selected marker will be deselected before getting the state.\n   */\n  public getState(deselectCurrentMarker?: boolean): MarkerAreaState {\n    if (deselectCurrentMarker === true) {\n      this.setCurrentMarker();\n    }\n    const result: MarkerAreaState = {\n      width: this.imageWidth,\n      height: this.imageHeight,\n      markers: [],\n    };\n    this.markers.forEach((marker) => result.markers.push(marker.getState()));\n    return result;\n  }\n\n  /**\n   * Restores MarkerArea state to continue previous annotation session.\n   *\n   * **IMPORTANT**: call `restoreState()` __after__ you've opened the MarkerArea with {@linkcode show}.\n   *\n   * ```typescript\n   * this.markerArea1.show();\n   * if (this.currentState) {\n   *   this.markerArea1.restoreState(this.currentState);\n   * }\n   * ```\n   *\n   * @param state - previously saved state object.\n   */\n  public restoreState(state: MarkerAreaState): void {\n    this.markers.splice(0);\n    while (this.markerImage.lastChild) {\n      this.markerImage.removeChild(this.markerImage.lastChild);\n    }\n    \n    state.markers.forEach((markerState) => {\n      const markerType = this._availableMarkerTypes.find(\n        (mType) => mType.typeName === markerState.typeName\n      );\n      if (markerType !== undefined) {\n        const marker = this.addNewMarker(markerType);\n        marker.restoreState(markerState);\n        this.markers.push(marker);\n      }\n    });\n    if (\n      state.width &&\n      state.height &&\n      (state.width !== this.imageWidth || state.height !== this.imageHeight)\n    ) {\n      this.scaleMarkers(\n        this.imageWidth / state.width,\n        this.imageHeight / state.height\n      );\n    }\n    this.eventListeners['restorestate'].forEach(listener => listener(new MarkerAreaEvent(this)));\n  }\n\n  private addNewMarker(markerType: typeof MarkerBase): MarkerBase {\n    const g = SvgHelper.createGroup();\n    this.markerImage.appendChild(g);\n\n    return new markerType(g, this.overlayContainer, this.settings);\n  }\n\n  /**\n   * Initiate new marker creation.\n   *\n   * marker.js switches to marker creation mode for the marker type specified\n   * and users can draw a new marker like they would by pressing a corresponding\n   * toolbar button.\n   *\n   * This example initiates creation of a `FrameMarker`:\n   * ```typescript\n   * this.markerArea1.createNewMarker(FrameMarker);\n   * ```\n   *\n   * @param markerType\n   */\n  public createNewMarker(markerType: typeof MarkerBase | string): void {\n    let mType: typeof MarkerBase;\n\n    if (typeof markerType === 'string') {\n      mType = this._availableMarkerTypes.find(\n        (mt) => mt.typeName === markerType\n      );\n    } else {\n      mType = markerType;\n    }\n\n    if (mType) {\n      this.setCurrentMarker();\n      this.currentMarker = this.addNewMarker(mType);\n      this.currentMarker.onMarkerCreated = this.markerCreated;\n      this.currentMarker.onColorChanged = this.colorChanged;\n      this.currentMarker.onFillColorChanged = this.fillColorChanged;\n      this.markerImage.style.cursor = 'crosshair';\n      this.toolbar.setActiveMarkerButton(mType.typeName);\n      this.toolbox.setPanelButtons(this.currentMarker.toolboxPanels);\n      this.eventListeners['markercreating'].forEach(listener => listener(new MarkerEvent(this, this.currentMarker)));\n    }\n  }\n\n  private markerCreated(marker: MarkerBase) {\n    this.mode = 'select';\n    this.markerImage.style.cursor = 'default';\n    this.markers.push(marker);\n    this.setCurrentMarker(marker);\n    if (\n      marker instanceof FreehandMarker &&\n      this.settings.newFreehandMarkerOnPointerUp\n    ) {\n      this.createNewMarker(FreehandMarker);\n    } else {\n      this.toolbar.setSelectMode();\n    }\n    this.addUndoStep();\n    this.eventListeners['markercreate'].forEach(listener => listener(new MarkerEvent(this, this.currentMarker)));\n  }\n\n  private colorChanged(color: string): void {\n    if (this.settings.defaultColorsFollowCurrentColors) {\n      this.settings.defaultColor = color;\n      this.settings.defaultStrokeColor = color;\n    }\n  }\n  private fillColorChanged(color: string): void {\n    if (this.settings.defaultColorsFollowCurrentColors) {\n      this.settings.defaultFillColor = color;\n    }\n  }\n\n  /**\n   * Sets the currently selected marker or deselects it if no parameter passed.\n   *\n   * @param marker marker to select. Deselects current marker if undefined.\n   */\n  public setCurrentMarker(marker?: MarkerBase): void {\n    if (this.currentMarker !== marker) { // no need to deselect if not changed\n      if (this.currentMarker !== undefined) {\n        this.currentMarker.deselect();\n        this.toolbar.setCurrentMarker();\n        this.toolbox.setPanelButtons([]);\n        this.eventListeners['markerdeselect'].forEach(listener => listener(new MarkerEvent(this, this.currentMarker)));\n      }\n    }\n    this.currentMarker = marker;\n    if (this.currentMarker !== undefined && !this.currentMarker.isSelected) {\n      this.currentMarker.select();\n      this.toolbar.setCurrentMarker(this.currentMarker);\n      this.toolbox.setPanelButtons(this.currentMarker.toolboxPanels);\n      this.eventListeners['markerselect'].forEach(listener => listener(new MarkerEvent(this, this.currentMarker)));\n    }\n  }\n\n  private onPointerDown(ev: PointerEvent) {\n    if (!this._isFocused) {\n      this.focus();\n    }\n\n    this.touchPoints++;\n    if (this.touchPoints === 1 || ev.pointerType !== 'touch') {\n      if (\n        this.currentMarker !== undefined &&\n        (this.currentMarker.state === 'new' ||\n          this.currentMarker.state === 'creating')\n      ) {\n        this.isDragging = true;\n        this.currentMarker.pointerDown(\n          this.clientToLocalCoordinates(ev.clientX, ev.clientY)\n        );\n      } else if (this.mode === 'select') {\n        const hitMarker = this.markers.find((m) => m.ownsTarget(ev.target));\n        if (hitMarker !== undefined) {\n          this.setCurrentMarker(hitMarker);\n          this.isDragging = true;\n          this.currentMarker.pointerDown(\n            this.clientToLocalCoordinates(ev.clientX, ev.clientY),\n            ev.target\n          );\n        } else {\n          this.setCurrentMarker();\n          this.isDragging = true;\n          this.prevPanPoint = { x: ev.clientX, y: ev.clientY };\n        }\n      }\n    }\n  }\n\n  private onDblClick(ev: PointerEvent) {\n    if (!this._isFocused) {\n      this.focus();\n    }\n\n    if (this.mode === 'select') {\n      const hitMarker = this.markers.find((m) => m.ownsTarget(ev.target));\n      if (hitMarker !== undefined && hitMarker !== this.currentMarker) {\n        this.setCurrentMarker(hitMarker);\n      }\n      if (this.currentMarker !== undefined) {\n        this.currentMarker.dblClick(\n          this.clientToLocalCoordinates(ev.clientX, ev.clientY),\n          ev.target\n        );\n      } else {\n        this.setCurrentMarker();\n      }\n    }\n  }\n\n  private onPointerMove(ev: PointerEvent) {\n    if (this.touchPoints === 1 || ev.pointerType !== 'touch') {\n      if (this.currentMarker !== undefined || this.isDragging) {\n        // don't swallow the event when editing text markers\n        if (\n          this.currentMarker === undefined ||\n          this.currentMarker.state !== 'edit'\n        ) {\n          ev.preventDefault();\n        }\n\n        if (this.currentMarker !== undefined) {\n          this.currentMarker.manipulate(\n            this.clientToLocalCoordinates(ev.clientX, ev.clientY)\n          );\n        } else if (this.zoomLevel > 1) {\n          this.panTo({ x: ev.clientX, y: ev.clientY });\n        }\n      }\n    }\n  }\n  private onPointerUp(ev: PointerEvent) {\n    if (this.touchPoints > 0) {\n      this.touchPoints--;\n    }\n    if (this.touchPoints === 0) {\n      if (this.isDragging && this.currentMarker !== undefined) {\n        this.currentMarker.pointerUp(\n          this.clientToLocalCoordinates(ev.clientX, ev.clientY)\n        );\n      }\n    }\n    this.isDragging = false;\n    this.addUndoStep();\n  }\n\n  private onPointerOut(/*ev: PointerEvent*/) {\n    if (this.touchPoints > 0) {\n      this.touchPoints--;\n    }\n  }\n\n  private onKeyUp(ev: KeyboardEvent) {\n    if (\n      this.currentMarker !== undefined &&\n      this.notesArea === undefined &&\n      (ev.key === 'Delete' || ev.key === 'Backspace')\n    ) {\n      this.deleteSelectedMarker();\n      // this.setCurrentMarker();\n      // this.markerImage.style.cursor = 'default';\n      // this.addUndoStep();\n    }\n  }\n\n  private clientToLocalCoordinates(x: number, y: number): IPoint {\n    const clientRect = this.markerImage.getBoundingClientRect();\n    return {\n      x: (x - clientRect.left) / this.zoomLevel,\n      y: (y - clientRect.top) / this.zoomLevel,\n    };\n  }\n\n  private onWindowResize() {\n    this.positionUI();\n  }\n\n  private positionUI() {\n    this.setTopLeft();\n    switch (this.settings.displayMode) {\n      case 'inline': {\n        const coverTop =\n          this.target.offsetTop > Style.settings.toolbarHeight\n            ? this.target.offsetTop - Style.settings.toolbarHeight\n            : 0;\n        this.coverDiv.style.top = `${coverTop}px`;\n        this.coverDiv.style.left = `${this.target.offsetLeft.toString()}px`;\n        break;\n      }\n      case 'popup': {\n        this.coverDiv.style.top = '0px';\n        this.coverDiv.style.left = '0px';\n        this.coverDiv.style.width = '100vw';\n        this.coverDiv.style.height = `${this.windowHeight}px`;\n        this.contentDiv.style.maxHeight = `${\n          this.windowHeight -\n          this.settings.popupMargin * 2 -\n          this.uiStyleSettings.toolbarHeight * 3.5\n        }px`;\n      }\n    }\n    this.positionMarkerImage();\n    this.positionLogo();\n  }\n\n  /**\n   * Add license key.\n   *\n   * This is a proxy method for {@linkcode Activator.addKey()}.\n   *\n   * @param key - commercial license key.\n   */\n  public addLicenseKey(key: string): void {\n    Activator.addKey(key);\n  }\n\n  private eventListeners = new EventListenerRepository();\n  /**\n   * Adds an event listener for one of the marker.js Live events.\n   * \n   * @param eventType - type of the event.\n   * @param handler - function handling the event.\n   * \n   * @since 2.16.0\n   */\n  public addEventListener<T extends keyof IEventListenerRepository>(\n    eventType: T,\n    handler: EventHandler<T>\n  ): void {\n    this.eventListeners.addEventListener(eventType, handler);\n  }\n\n  /**\n   * Removes an event listener for one of the marker.js Live events.\n   * \n   * @param eventType - type of the event.\n   * @param handler - function currently handling the event.\n   * \n   * @since 2.16.0\n   */\n  public removeEventListener<T extends keyof IEventListenerRepository>(\n    eventType: T,\n    handler: EventHandler<T>\n  ): void {\n    this.eventListeners.removeEventListener(eventType, handler);\n  }\n\n\n  private _silentRenderMode = false;\n  /**\n   * Renders previously saved state without user intervention.\n   * \n   * The rendered image is returned to the `render` event handlers (as in the regular interactive process).\n   * Rendering options set on `MarkerArea` are respected.\n   * \n   * @param state state to render\n   * \n   * @since 2.17.0\n   */\n  public renderState(state: MarkerAreaState): void {\n    this._silentRenderMode = true;\n    this.settings.displayMode = 'inline';\n    if (!this.isOpen) {\n      this.show();\n    }\n    this.restoreState(state);\n    this.startRenderAndClose();\n    this._silentRenderMode = false;\n  }\n\n  private _isFocused = false;\n  /**\n   * Returns true when this MarkerArea is focused.\n   * \n   * @since 2.19.0\n   */\n  public get isFocused(): boolean {\n    return this._isFocused;\n  }\n\n  private _previousCurrentMarker?: MarkerBase;\n\n  /**\n   * Focuses the MarkerArea to receive all input from the window.\n   * \n   * Is called automatically when user clicks inside of the marker area. Call manually to set focus explicitly.\n   * \n   * @since 2.19.0\n   */\n  public focus(): void {\n    if (!this._isFocused) {\n      this.attachWindowEvents();\n      this._isFocused = true;\n      if (this._previousCurrentMarker !== undefined) {\n        this.setCurrentMarker(this._previousCurrentMarker);\n      }\n      this.eventListeners['focus'].forEach(listener => listener(new MarkerAreaEvent(this)));\n    }\n  }\n\n  /**\n   * Tells MarkerArea to stop reacting to input outside of the immediate marker image.\n   * \n   * Call `focus()` to re-enable.\n   * \n   * @since 2.19.0\n   */\n  public blur(): void {\n    if (this._isFocused) {\n      this.detachWindowEvents();\n      this._isFocused = false;\n      this._previousCurrentMarker = this.currentMarker;\n      this.setCurrentMarker();\n      this.eventListeners['blur'].forEach(listener => listener(new MarkerAreaEvent(this)));\n    }\n  }\n\n}\n"],"names":["extendStatics","d","b","Object","setPrototypeOf","__proto__","Array","p","prototype","hasOwnProperty","call","__extends","__","this","constructor","create","__awaiter","thisArg","_arguments","P","generator","Promise","resolve","reject","fulfilled","value","step","next","e","rejected","result","done","then","apply","__generator","body","f","y","t","g","_","label","sent","trys","ops","verb","throw","return","Symbol","iterator","n","v","op","TypeError","pop","length","push","__spreadArrays","s","i","il","arguments","r","k","a","j","jl","SvgHelper","document","createElementNS","el","attributes","attributes_1","_i","_a","attr","setAttribute","width","height","rect","toString","setAttributes","x1","y1","x2","y2","line","points","polygon","radius","circle","rx","ry","ellipse","createSVGTransform","id","orient","markerWidth","markerHeight","refX","refY","markerElement","marker","appendChild","text","tspan","textContent","image","x","svgPoint","createSVGPoint","path","Activator","key","RegExp","test","Renderer","target","markerImage","targetCanvas","canvas","undefined","createElement","_this","markersOnly","naturalSize","markerImageCopy","baseVal","valueAsString","viewBox","innerHTML","naturalWidth","naturalHeight","data","outerHTML","ctx","getContext","drawImage","DOMURL","window","URL","img","Image","blob","Blob","type","url","createObjectURL","onload","revokeObjectURL","toDataURL","imageType","imageQuality","src","Style","canvasBackgroundColor","toolbarBackgroundColor","toolbarBackgroundHoverColor","toolbarColor","toolbarHeight","toolboxColor","toolboxAccentColor","undoButtonVisible","redoButtonVisible","zoomButtonVisible","zoomOutButtonVisible","clearButtonVisible","resultButtonBlockVisible","logoPosition","CLASS_PREFIX","styleClass","styleSheet","addStyleSheet","classes","sheet","insertRule","name","style","cssRules","styleRule","rules","selector","styleSheetRoot","head","addRule","StyleRule","addClass","StyleClass","removeChild","defaultSettings","_localName","markerjsContainer","displayMode","markerItems","uiStyleSettings","addStyles","adjustLayout","bind","overflowButtonClicked","setCurrentMarker","Toolbar","visiblity","uiContainer","visibility","className","toolbarStyleClass","fadeInAnimationClassName","toolbarStyleColorsClassName","toolbarStyleColorsClass","actionButtonBlock","toolbarBlockStyleClass","whiteSpace","addActionButton","notesButtonVisible","markerButtonBlock","flexGrow","textAlign","markerButtonOverflowBlock","toolbarOverflowBlockStyleClass","toolbarOverflowBlockStyleColorsClassName","toolbarOverflowBlockStyleColorsClass","display","forEach","mi","buttonContainer","toolbarButtonStyleClass","typeName","icon","addEventListener","markerToolbarButtonClicked","buttons","markerButtons","overflowButton","toolbarButtonStyleColorsClassName","toolbarButtonStyleColorsClass","resultButtonBlock","setSelectMode","listener","buttonClickListeners","indexOf","splice","resetButtonStyles","setActiveButton","numberToFit","Math","floor","clientWidth","buttonIndex","replace","top","offsetTop","offsetHeight","right","offsetWidth","offsetLeft","button","trim","toolbarActiveButtonStyleColorsClassName","toolbarActiveButtonStyleColorsClass","container","actionButton","actionToolbarButtonClicked","fill","selectButtonColor","deleteButtonColor","okButtonColor","closeButtonColor","round","buttonPadding","markerType","action","activeBtn","find","btn","getAttribute","currentMarker","filter","fillOpacity","pointerEvents","panelButtonClick","Toolbox","toolboxStyleClass","toolboxStyleColorsClass","toolboxButtonRowStyleClass","toolboxButtonRowStyleColorsClass","toolboxPanelRowStyleClass","toolboxPanelRowStyleColorsClass","toolboxBackgroundColor","toolboxButtonStyleClass","toolboxButtonStyleColorsClass","toolboxActiveButtonStyleColorsClass","toolboxStyleColorsClassName","panels","panelRow","toolboxPanelRowStyleColorsClassName","buttonRow","toolboxButtonRowStyleColorsClassName","panelButtons","panel","panelBtnDiv","toolboxButtonStyleColorsClassName","title","panelIndex","activePanel","panelUI","getUi","margin","fadeOutAnimationClassName","setTimeout","pb","index","toolboxActiveButtonStyleColorsClassName","colors","currentColor","_super","setCurrentColor","getColorBox","ColorPickerPanel","panelDiv","overflow","color","colorBoxContainer","colorBoxes","settings","buttonHeight","boxSizing","padding","marginRight","marginBottom","borderWidth","borderStyle","borderRadius","borderColor","colorBox","backgroundColor","box","onColorChanged","ToolboxPanel","overlayContainer","_container","_overlayContainer","globalSettings","MarkerBase","getPrototypeOf","_state","_isSelected","cursor","point","element","childNodes","insertBefore","state","notes","scaleX","scaleY","onFillColorChanged","findGripByVisual","RectangularBoxMarkerGrips","gripVisual","topLeft","ownsTarget","topCenter","topRight","centerLeft","centerRight","bottomLeft","bottomCenter","bottomRight","visual","createGroup","createCircle","GRIP_SIZE","ResizeGrip","TransformMatrix","matrix","c","currentMatrix","newMatrix","transform","appendItem","createTransform","setupControlBox","RectangularBoxMarkerBase","left","_visual","translate","controlGrips","rotatorGrip","pointerDown","manipulationStartLeft","manipulationStartTop","manipulationStartWidth","manipulationStartHeight","rotatedPoint","unrotatePoint","manipulationStartX","manipulationStartY","offsetX","offsetY","select","activeGrip","rotatedCenter","rotatePoint","centerX","centerY","moveVisual","rotate","getItem","setRotate","rotationAngle","replaceItem","adjustControlBox","inState","pointerUp","defaultSize","manipulate","onMarkerCreated","resize","newX","newWidth","newY","newHeight","setSize","abs","sign","atan","PI","applyRotation","getCTM","createPoint","matrixTransform","inverse","controlBox","deselect","setTranslate","CB_DISTANCE","controlRect","createRect","rotatorGripLine","createLine","addControlGrips","positionGrips","createGrip","grip","gripSize","cx","cy","bottom","positionGrip","assign","visualTransformMatrix","toITransformMatrix","containerTransformMatrix","getState","restoreState","rbmState","setMatrix","toSVGMatrix","scale","rPoint","setStrokeColor","setFillColor","setStrokeWidth","setStrokeDasharray","createVisual","RectangleMarker","fillColor","strokeColor","strokeWidth","strokeDasharray","opacity","addMarkerVisualToContainer","colorChanged","dashes","rectState","widths","currentWidth","setCurrentWidth","LineWidthPanel","lineWidth","widthBoxContainer","alignItems","justifyContent","innerText","widthBox","minHeight","hr","minWidth","border","borderTop","widthBoxes","onWidthChanged","styles","currentStyle","setCurrentStyle","LineStylePanel","lineStyle","styleBoxContainer","maxWidth","styleBox","styleSample","styleBoxes","newStyle","onStyleChanged","defaultColor","defaultStrokeWidth","defaultStrokeDasharray","strokePanel","defaultColorSet","strokeWidthPanel","defaultStrokeWidths","strokeStylePanel","defaultStrokeDasharrays","FrameMarker","LinearMarkerBase","grip1","grip2","manipulationStartX1","manipulationStartY1","manipulationStartX2","manipulationStartY2","defaultLength","adjustVisual","lmbState","LineMarker","selectorLine","visibleLine","lmState","fonts","currentFont","setCurrentFont","FontFamilyPanel","font","fontBoxContainer","fontBox","fontFamily","fontLabel","textOverflow","fontBoxes","newFont","onFontChanged","DEFAULT_TEXT","defaultFontFamily","setColor","setFont","renderText","sizeText","textEditDivClicked","showTextEditor","positionTextEditor","colorPanel","fontFamilyPanel","defaultFontFamilies","TextMarker","textElement","bgRectangle","found_1","span","createText","isMoved","pointerDownPoint","pointerDownTimestamp","Date","now","lastChild","split","createTSpan","textSize","getBBox","xScale","yScale","min","textBBox","getTextScale","position","getTextPosition","navigator","userAgent","setScale","textEditDiv","textEditor","lineHeight","contentEditable","ev","stopPropagation","fontSize","Number","parseFloat","parseInt","max","cancelBubble","clipboardData","content","getData","selection","getSelection","rangeCount","deleteFromDocument","getRangeAt","insertNode","createTextNode","preventDefault","hideVisual","focus","execCommand","textScale","rPosition","rWH","showVisual","dblClick","hideControlBox","showControlBox","textState","pixelRatio","freehandPixelRatio","addCanvas","finishCreation","setLineWidth","lineWidthPanel","FreehandMarker","drawingImage","createImage","canvasContext","strokeStyle","beginPath","moveTo","drawing","lineTo","stroke","closePath","newFreehandMarkerOnPointerUp","canvasElement","clientHeight","imgData","getImageData","startX","startY","endX","endY","containsData","row","col","tmpCanvas","putImageData","drawingImgUrl","setDrawingImage","currentType","setCurrentType","ArrowTypePanel","ti","arrowType","typeBoxContainer","this_1","leftTip","marginLeft","lineBox","rightTip","typeBoxes","newType","onArrowTypeChanged","getArrowPoints","setArrowType","arrowTypePanel","ArrowMarker","arrow1","arrow2","arrowBaseWidth","arrowBaseHeight","createPolygon","createTips","lineAngle1","a1transform","a2transform","amState","defaultFillColor","fillPanel","CoverMarker","opacities","currentOpacity","setCurrentOpacity","OpacityPanel","opacityBoxContainer","opacityBoxes","onOpacityChanged","setOpacity","defaultHighlightColor","defaultHighlightOpacity","opacityPanel","defaultOpacitySteps","HighlightMarker","defaultStrokeColor","bgColor","setBgColor","getTipPoints","positionTip","setTipPoints","bgColorPanel","FillColorIcon","tipGrip","CalloutMarker","tip","createTip","tipMoving","isCreating","tipPosition","fillColorChanged","tipBase1Position","tipBase2Position","offset","baseWidth","cornerAngle","calloutState","EllipseMarker","createEllipse","MeasurementMarker","tip1","tip2","tipLength","EllipseFrameMarker","UndoRedoManager","undoStack","redoStack","stepData","JSON","stringify","lastRedoStep","lastStep","CurveMarker","selectorCurve","visibleCurve","curveGrip","curveX","curveY","createPath","getPathD","manipulationStartCurveX","manipulationStartCurveY","curveControlLine1","curveControlLine2","firstChild","markerArea","cancelable","MarkerAreaEvent","_defaultPrevented","dataUrl","EventListenerRepository","eventType","handler","DEFAULT_MARKER_TYPES","Settings","targetRoot","removeStyleSheet","open","setTopLeft","toolbarButtonClicked","createNewMarker","addNewMarker","markerCreated","onPointerDown","onDblClick","onPointerMove","onPointerUp","onPointerOut","onKeyUp","overrideOverflow","restoreOverflow","close","closeUI","addCloseEventListener","removeCloseEventListener","addRenderEventListener","removeRenderEventListener","clientToLocalCoordinates","onWindowResize","deleteSelectedMarker","setWindowHeight","removeMarker","onPopupTargetResize","showNotesEditor","hideNotesEditor","stepZoom","blur","MarkerArea","_availableMarkerTypes","mt","typeType","ALL_MARKER_TYPES","allT","_isOpen","_zoomLevel","editorCanvas","contentDiv","scrollTo","setupResizeObserver","setEditingTarget","initMarkerCanvas","initOverlay","attachEvents","isLicensed","addLogo","_isFocused","showUI","eventListeners","renderer","renderAtNaturalSize","renderImageType","renderImageQuality","renderMarkersOnly","renderWidth","renderHeight","rasterize","HTMLImageElement","renderTarget","suppressBeforeClose","isOpen","cancel_1","defaultPrevented","coverDiv","targetObserver","unobserve","removeEventListener","detachEvents","markers","event","ResizeObserver","observe","ratio","windowHeight","innerHeight","imageWidth","imageHeight","editingTarget","markerImageHolder","positionMarkerImage","toolbar","positionLogo","scaleMarkers","preScaleSelectedMarker","targetRect","getBoundingClientRect","bodyRect","setProperty","transformOrigin","nodes","defs","createDefs","append","zoomLevel","attachWindowEvents","detachWindowEvents","logoUI","link","href","justifyItems","scrollXState","scrollX","scrollYState","scrollY","bodyOverflowState","scroll","_silentRenderMode","userSelect","coverTop","getClientRects","item","zIndex","uiDiv","flexDirection","popupMargin","addButtonClickListener","show","hideToolbar","flexShrink","maxHeight","marginTop","toolbox","hideToolbox","dispose","mode","addUndoStep","buttonType","switchToSelectMode","clear","undo","redo","notesArea","startRenderAndClose","cancel_2","MarkerEvent","marker_1","notesAreaStyleClassName","alignSelf","isNotesAreaOpen","undoRedoManager","selectLastMarker","zoomStepIndex","zoomSteps","scrollBy","prevPanPoint","render","MarkerAreaRenderEvent","deselectCurrentMarker","markerState","mType","setActiveMarkerButton","setPanelButtons","toolboxPanels","defaultColorsFollowCurrentColors","isSelected","touchPoints","pointerType","hitMarker","m","isDragging","clientX","clientY","panTo","clientRect","positionUI","addKey","_previousCurrentMarker"],"mappings":"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"}
\ No newline at end of file
diff --git a/capsule-prototype/js/libs/markerjs2/package.json b/capsule-prototype/js/libs/markerjs2/package.json
new file mode 100644
index 0000000000000000000000000000000000000000..049cb47aec1d37537049e1233f6ec5f0e8805f40
--- /dev/null
+++ b/capsule-prototype/js/libs/markerjs2/package.json
@@ -0,0 +1,26 @@
+{
+  "name": "markerjs2",
+  "version": "2.21.0",
+  "description": "JavaScript image annotation",
+  "main": "markerjs2.js",
+  "module": "markerjs2.esm.js",
+  "types": "markerjs2.d.ts",
+  "author": "Alan Mendelevich",
+  "license": "SEE LICENSE IN LICENSE",
+  "scripts": {},
+  "repository": {
+    "type": "git",
+    "url": "https://github.com/ailon/markerjs2"
+  },
+  "keywords": [
+    "annotate",
+    "mark",
+    "highlight",
+    "image",
+    "photo",
+    "graphics",
+    "javascript",
+    "typescript",
+    "comment"
+  ]
+}
diff --git a/capsule-prototype/js/libs/markerjslive/LICENSE b/capsule-prototype/js/libs/markerjslive/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..4fc7c89983b467ec6f739cb40085c00f55f97752
--- /dev/null
+++ b/capsule-prototype/js/libs/markerjslive/LICENSE
@@ -0,0 +1,25 @@
+marker.js Live Linkware License
+
+Copyright (c) 2020 Alan Mendelevich
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+1. The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+2. Link back to the Software website displayed during operation of the Software
+or an equivalent prominent public attribution must be retained. Alternative 
+commercial licenses can be obtained to remove this clause.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/capsule-prototype/js/libs/markerjslive/README.md b/capsule-prototype/js/libs/markerjslive/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..72e0adb692ee57373b5a089a91916ee37a59246c
--- /dev/null
+++ b/capsule-prototype/js/libs/markerjslive/README.md
@@ -0,0 +1,61 @@
+# marker.js Live &mdash; Display interactive image annotations
+
+**[marker.js Live]** is a JavaScript library for overlaying dynamic interactive annotations on top of images. 
+
+[marker.js Live] is a companion library for [marker.js 2]. While **marker.js 2** enables users to annotate images it produces both a static representation of the annotated image as well as a configuration dataset for future editing of the annotations. [marker.js Live] takes that configuration and displays it dynamically on top of original (untouched) images. This enables responsiveness, interactivity, and other use-cases beyond what static annotations could ever offer.
+
+**marker.js Live** is extensible and enables you to pick and choose the [plugins](https://markerjs.com/docs/markerjs-live/plugins) to add just the functionality you need for your project.
+
+## Installation
+
+```
+npm install markerjs-live
+```
+
+or 
+
+```
+yarn add markerjs-live
+```
+
+## Usage
+
+To display dynamic image annotations in your project, first, annotate your images using [marker.js 2], grab the "state" configuration of the annotations, and then follow these 2 easy steps:
+
+1. Create an instance of `mjslive.MarkerView` passing a target image reference to the constructor.
+2. Call its `show()` method passing your annotation configuration (marker.js 2 state) to it.
+
+That's it!
+
+Here's a simple example:
+
+```js
+// skip this line if you are importing marker.js Live into the global space via the script tag
+import * as mjslive from 'markerjs-live';
+
+// create an instance of MarkerView and pass the target image reference as a parameter
+const markerView = new mjslive.MarkerView(target);
+
+// call the show() method and pass your annotation configuration (created with marker.js 2) as a parameter
+markerView.show(markerState);
+```
+
+Obviously, there's much more [marker.js Live] can do: use the range of events to add your own custom functionality based on lifecycle and interactions, or just utilize the pre-made plugins to extend the core features, or create your own plugins and share them with the community.
+
+For these and other uses please refer to the [marker.js Live documentation](https://markerjs.com/docs/markerjs-live/getting-started).
+
+## Demos
+Check out [marker.js Live demos](https://markerjs.com/demos/markerjs-live/all-defaults/) for various usage examples.
+
+## More docs and tutorials
+For a more detailed "Getting started" and other docs and tutorials, please refer to 
+the [official documentation](https://markerjs.com/docs/markerjs-live/getting-started).
+
+
+## License
+Linkware (see [LICENSE](https://github.com/ailon/markerjs-live/blob/master/LICENSE) for details) - the UI displays a small link back to the marker.js website which should be retained.
+
+Alternative licenses are available through the [marker.js website](https://markerjs.com).
+
+[marker.js Live]: https://markerjs.com/products/markerjs-live
+[marker.js 2]: https://markerjs.com/products/markerjs
diff --git a/capsule-prototype/js/libs/markerjslive/markerjs-live.d.ts b/capsule-prototype/js/libs/markerjslive/markerjs-live.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ee0207223e921350b68d068d668e5f16935c550f
--- /dev/null
+++ b/capsule-prototype/js/libs/markerjslive/markerjs-live.d.ts
@@ -0,0 +1,1898 @@
+/**
+ * Describes point objects used internally in marker.js.
+ */
+interface IPoint {
+    x: number;
+    y: number;
+}
+
+/**
+ * Represents marker's state (status) in time.
+ */
+declare type MarkerState = 'new' | 'creating' | 'select' | 'move' | 'resize' | 'rotate' | 'edit';
+/**
+ * Represents marker's state used to save and restore state continue annotation in the future.
+ */
+interface MarkerBaseState {
+    /**
+     * Marker's type name.
+     */
+    typeName: string;
+    /**
+     * Current editing state/status.
+     */
+    state: MarkerState;
+    /**
+     * Additional information about the marker.
+     */
+    notes?: string;
+}
+
+/**
+ * Base class for all available and custom marker types.
+ *
+ * All markers used with marker.js Live should be descendants of this class.
+ */
+declare class MarkerBase {
+    /**
+     * String type name of the marker type.
+     *
+     * Used when adding {@link MarkerView.availableMarkerTypes} via a string and to save and restore state.
+     */
+    static typeName: string;
+    protected _outerContainer: SVGGElement;
+    /**
+     * Outer SVG group container not manipulated or transformed by the marker itself in any way
+     */
+    get outerContainer(): SVGGElement;
+    protected _container: SVGGElement;
+    /**
+     * SVG container object holding the marker's visual.
+     */
+    get container(): SVGGElement;
+    /**
+     * Additional information about the marker
+     */
+    notes?: string;
+    /**
+     * Marker type title (display name) used for accessibility and other attributes.
+     */
+    static title: string;
+    /**
+     * Method called when marker creation is finished.
+     */
+    onMarkerCreated: (marker: MarkerBase) => void;
+    /**
+     * Creates a new marker.
+     *
+     * @param container - SVG container to hold marker's visual.
+     */
+    constructor(container: SVGGElement);
+    /**
+     * Returns true if passed SVG element belongs to the marker. False otherwise.
+     *
+     * @param el - target element.
+     */
+    ownsTarget(el: EventTarget): boolean;
+    /**
+     * Selects this marker.
+     */
+    select(): void;
+    /**
+     * Deselects this marker.
+     */
+    deselect(): void;
+    /**
+     * Handles pointer (mouse, touch, stylus, etc.) down event.
+     *
+     * @param point - event coordinates.
+     * @param target - direct event target element.
+     */
+    pointerDown(point: IPoint, target?: EventTarget): void;
+    /**
+     * Handles pointer (mouse, touch, stylus, etc.) double click event.
+     *
+     * @param point - event coordinates.
+     * @param target - direct event target element.
+     */
+    dblClick(point: IPoint, target?: EventTarget): void;
+    /**
+     * Handles pointer (mouse, touch, stylus, etc.) up event.
+     *
+     * @param point - event coordinates.
+     */
+    pointerUp(point: IPoint): void;
+    /**
+     * Disposes the marker and clean's up.
+     */
+    dispose(): void;
+    /**
+     * Adds marker's root visual element to the container group.
+     * @param element - marker's visual element.
+     */
+    protected addMarkerVisualToContainer(element: SVGElement): void;
+    /**
+     * Restores previously saved marker state.
+     *
+     * @param state - previously saved state.
+     */
+    restoreState(state: MarkerBaseState): void;
+    /**
+     * Scales marker. Used after the image resize.
+     *
+     * @param scaleX - horizontal scale
+     * @param scaleY - vertical scale
+     */
+    scale(scaleX: number, scaleY: number): void;
+}
+
+/**
+ * Describes a MarkerArea state object used to save and restore marker.js state between sessions.
+ */
+interface MarkerAreaState {
+    /**
+     * Editing canvas width.
+     */
+    width: number;
+    /**
+     * Editing canvas height.
+     */
+    height: number;
+    /**
+     * States of individual markers.
+     */
+    markers: MarkerBaseState[];
+}
+
+/**
+ * Simple utility CSS-in-JS implementation.
+ */
+declare class StyleManager {
+    private _classNamePrefixBase;
+    /**
+     * Static CSS class name used for the wrapper element.
+     */
+    get classNamePrefixBase(): string;
+    private _classNamePrefix;
+    /**
+     * Prefix used for all internally created CSS classes.
+     */
+    get classNamePrefix(): string;
+    private classes;
+    private rules;
+    private styleSheet?;
+    /**
+     * For cases when you need to add the stylesheet to anything
+     * other than document.head (default), set this property
+     * before calling `show()`.
+     */
+    styleSheetRoot: HTMLElement;
+    /**
+     * Initializes a new style manager.
+     * @param instanceNo - instance id.
+     */
+    constructor(instanceNo: number);
+    /**
+     * Adds a CSS class declaration.
+     * @param styleClass - class to add.
+     */
+    addClass(styleClass: StyleClass): StyleClass;
+    /**
+     * Add arbitrary CSS rule
+     * @param styleRule - CSS rule to add.
+     */
+    addRule(styleRule: StyleRule): void;
+    private addStyleSheet;
+    removeStyleSheet(): void;
+}
+/**
+ * Represents an arbitrary CSS rule.
+ */
+declare class StyleRule {
+    /**
+     * CSS selector.
+     */
+    selector: string;
+    /**
+     * Style declaration for the rule.
+     */
+    style: string;
+    /**
+     * Creates an arbitrary CSS rule using the selector and style rules.
+     * @param selector - CSS selector
+     * @param style - styles to apply
+     */
+    constructor(selector: string, style: string);
+}
+/**
+ * Represents a CSS class.
+ */
+declare class StyleClass {
+    /**
+     * CSS style rules for the class.
+     */
+    style: string;
+    /**
+     * Class name without the global prefix.
+     */
+    localName: string;
+    /**
+     * Fully qualified CSS class name.
+     */
+    name: string;
+    /**
+     * Creates a CSS class declaration based on supplied (local) name and style rules.
+     * @param name - local CSS class name (will be prefixed with the marker.js prefix).
+     * @param style - style declarations.
+     */
+    constructor(name: string, style: string);
+}
+
+/**
+ * General MarkerView event handler type.
+ */
+declare type MarkerViewEventHandler = (markerView: MarkerView) => void;
+/**
+ * Marker event handler type.
+ */
+declare type MarkerEventHandler = (markerView: MarkerView, marker?: MarkerBase) => void;
+/**
+ * Pointer related marker event handler type.
+ */
+declare type PointerEventHandler = (markerView: MarkerView, event: PointerEvent, marker?: MarkerBase) => void;
+/**
+ * Describes a repository of MarkerView event handlers.
+ */
+interface IEventListenerRepository {
+    /**
+     * Event handlers for the `create` event.
+     */
+    create: MarkerViewEventHandler[];
+    /**
+     * Event handlers for the `close` event.
+     */
+    close: MarkerViewEventHandler[];
+    /**
+     * Event handlers for the `load` event.
+     */
+    load: MarkerViewEventHandler[];
+    /**
+     * Event handlers for the `select` event.
+     */
+    select: MarkerEventHandler[];
+    /**
+     * Event handlers for the `over` event.
+     */
+    over: MarkerEventHandler[];
+    /**
+     * Event handlers for the `pointerdown` event.
+     */
+    pointerdown: PointerEventHandler[];
+    /**
+     * Event handlers for the `pointermove` event.
+     */
+    pointermove: PointerEventHandler[];
+    /**
+     * Event handlers for the `pointerup` event.
+     */
+    pointerup: PointerEventHandler[];
+    /**
+     * Event handlers for the `pointerenter` event.
+     */
+    pointerenter: PointerEventHandler[];
+    /**
+     * Event handlers for the `pointerleave` event.
+     */
+    pointerleave: PointerEventHandler[];
+}
+/**
+ * Event handler type for a specific event type.
+ */
+declare type EventHandler<T extends keyof IEventListenerRepository> = T extends 'select' ? MarkerEventHandler : T extends 'over' ? MarkerEventHandler : T extends 'pointerdown' ? PointerEventHandler : T extends 'pointermove' ? PointerEventHandler : T extends 'pointerup' ? PointerEventHandler : T extends 'pointerenter' ? PointerEventHandler : T extends 'pointerleave' ? PointerEventHandler : MarkerViewEventHandler;
+/**
+ * Event handler repository.
+ */
+declare class EventListenerRepository implements IEventListenerRepository {
+    /**
+     * Event handlers for the `create` event.
+     */
+    create: MarkerViewEventHandler[];
+    /**
+     * Event handlers for the `close` event.
+     */
+    close: MarkerViewEventHandler[];
+    /**
+     * Event handlers for the `load` event.
+     */
+    load: MarkerViewEventHandler[];
+    /**
+     * Event handlers for the `select` event.
+     */
+    select: MarkerEventHandler[];
+    /**
+     * Event handlers for the `over` event.
+     */
+    over: MarkerEventHandler[];
+    /**
+     * Event handlers for the `pointerdown` event.
+     */
+    pointerdown: PointerEventHandler[];
+    /**
+     * Event handlers for the `pointermove` event.
+     */
+    pointermove: PointerEventHandler[];
+    /**
+     * Event handlers for the `pointerup` event.
+     */
+    pointerup: PointerEventHandler[];
+    /**
+     * Event handlers for the `pointerenter` event.
+     */
+    pointerenter: PointerEventHandler[];
+    /**
+     * Event handlers for the `pointerleave` event.
+     */
+    pointerleave: PointerEventHandler[];
+    /**
+     * Add an event handler for a specific event type.
+     * @param eventType - event type.
+     * @param handler - function to handle the event.
+     */
+    addEventListener<T extends keyof IEventListenerRepository>(eventType: T, handler: EventHandler<T>): void;
+    /**
+     * Remove an event handler for a specific event type.
+     * @param eventType - event type.
+     * @param handler - function currently handling the event.
+     */
+    removeEventListener<T extends keyof IEventListenerRepository>(eventType: T, handler: EventHandler<T>): void;
+}
+
+interface IMarkerViewPlugin {
+    init: (markerView: MarkerView) => void;
+}
+
+/**
+ * MarkerViews is the main class of marker.js Live. It controls the core behavior of the library.
+ *
+ * The simplest marker.js Live usage scenario looks something like this:
+ *
+ * ```typescript
+ * // skip this line if you are importing marker.js Live into the global space via the script tag
+ * import * as mjslive from 'markerjs-live';
+ *
+ * // create an instance of MarkerView and pass the target image reference as a parameter
+ * const markerView = new mjslive.MarkerView(target);
+ *
+ * // call the show() method and pass your annotation configuration (created with marker.js 2) as a parameter
+ * markerView.show(markerState);
+ * ```
+ */
+declare class MarkerView {
+    private target;
+    private targetObserver;
+    private imageWidth;
+    private imageHeight;
+    private left;
+    private top;
+    markerImage: SVGSVGElement;
+    private markerImageHolder;
+    private defs;
+    private coverDiv;
+    private uiDiv;
+    private contentDiv;
+    private editorCanvas;
+    private editingTarget;
+    private overlayContainer;
+    private touchPoints;
+    private logoUI;
+    private static instanceCounter;
+    private _instanceNo;
+    /**
+     * Instance id of this instance
+     */
+    get instanceNo(): number;
+    /**
+     * Manage style releated settings via the `styles` property.
+     */
+    styles: StyleManager;
+    /**
+     * Marker types supported by this instance.
+     * You can remove some types to limit the markers displayed.
+     */
+    availableMarkerTypes: typeof MarkerBase[];
+    /**
+     * `targetRoot` is used to set an alternative positioning root.
+     *
+     * This is useful in cases when your target image is positioned, say, inside a div with `position: relative;`
+     *
+     * ```typescript
+     * // set targetRoot to a specific div instead of document.body
+     * markerView.targetRoot = document.getElementById('myRootElement');
+     * ```
+     *
+     * @default document.body
+     */
+    targetRoot: HTMLElement;
+    private currentMarker?;
+    private hoveredMarker?;
+    /**
+     * The list of all markers displayed.
+     */
+    markers: MarkerBase[];
+    private isDragging;
+    private _isOpen;
+    /**
+     * Returns `true` when MarkerView is open and `false` otherwise.
+     *
+     * @readonly
+     */
+    get isOpen(): boolean;
+    private plugins;
+    /**
+     * The suffix of the CSS class name of the marker container (SVG group) element.
+     */
+    readonly MARKER_CONTAINER_CLASS_SUFFIX = "marker-container";
+    /**
+     * Creates a new MarkerView for the specified target image.
+     *
+     * ```typescript
+     * // create an instance of MarkerView and pass the target image reference as a parameter
+     * let markerView = new mjslive.MarkerView(document.getElementById('myimg'));
+     * ```
+     *
+     * @param target image object to be overlayed with markers.
+     */
+    constructor(target: HTMLElement);
+    private open;
+    /**
+     * Initializes the MarkerView and show the markers.
+     *
+     * @param state - marker configuration created with marker.js 2.
+     */
+    show(state: MarkerAreaState): void;
+    /**
+     * Closes the MarkerView.
+     */
+    close(): void;
+    private setupResizeObserver;
+    private resize;
+    private scaleMarkers;
+    private setEditingTarget;
+    private setTopLeft;
+    private initMarkerCanvas;
+    private initOverlay;
+    private positionMarkerImage;
+    private attachEvents;
+    /**
+     * NOTE:
+     *
+     * before removing or modifying this method please consider supporting marker.js
+     * by visiting https://markerjs.com/#price for details
+     *
+     * thank you!
+     */
+    private addLogo;
+    private positionLogo;
+    private showUI;
+    private closeUI;
+    private removeMarker;
+    /**
+     * Uses the state created with marker.js 2 to display the markers.
+     *
+     * @param state - previously saved marker.js 2 state object.
+     */
+    private restoreState;
+    private addNewMarker;
+    /**
+     * Sets the currently selected marker or deselects it if no parameter passed.
+     *
+     * @param marker marker to select. Deselects current marker if undefined.
+     */
+    setCurrentMarker(marker?: MarkerBase): void;
+    private onPointerDown;
+    private onDblClick;
+    private isPointerIn;
+    private onPointerMove;
+    private onPointerUp;
+    private onKeyUp;
+    private clientToLocalCoordinates;
+    private onWindowResize;
+    private positionUI;
+    private eventListeners;
+    /**
+     * Adds an event listener for one of the marker.js Live events.
+     *
+     * @param eventType - type of the event.
+     * @param handler - function handling the event.
+     */
+    addEventListener<T extends keyof IEventListenerRepository>(eventType: T, handler: EventHandler<T>): void;
+    /**
+     * Removes an event listener for one of the marker.js Live events.
+     *
+     * @param eventType - type of the event.
+     * @param handler - function currently handling the event.
+     */
+    removeEventListener<T extends keyof IEventListenerRepository>(eventType: T, handler: EventHandler<T>): void;
+    /**
+     * Adds a plugin to the plugin array.
+     * @param plugin
+     */
+    addPlugin(plugin: IMarkerViewPlugin): void;
+    /**
+     * Removes a plugin from the plugin array.
+     * @param plugin
+     */
+    removePlugin(plugin: IMarkerViewPlugin): void;
+}
+
+/**
+ * Manages commercial marker.js Live licenses.
+ */
+declare class Activator {
+    private static key;
+    /**
+     * Add a license key
+     * @param key license key sent to you after purchase.
+     */
+    static addKey(key: string): void;
+    /**
+     * Returns true if the copy of marker.js Live is commercially licensed.
+     */
+    static get isLicensed(): boolean;
+}
+
+/**
+ * Utility class to simplify SVG operations.
+ */
+declare class SvgHelper {
+    /**
+     * Creates SVG "defs".
+     */
+    static createDefs(): SVGDefsElement;
+    /**
+     * Creates SVG stylesheet.
+     */
+    static createStylesheet(): SVGStyleElement;
+    /**
+     * Sets attributes on an arbitrary SVG element
+     * @param el - target SVG element.
+     * @param attributes - set of name-value attribute pairs.
+     */
+    static setAttributes(el: SVGElement, attributes: Array<[string, string]>): void;
+    /**
+     * Creates an SVG rectangle with the specified width and height.
+     * @param width
+     * @param height
+     * @param attributes - additional attributes.
+     */
+    static createRect(width: number | string, height: number | string, attributes?: Array<[string, string]>): SVGRectElement;
+    /**
+     * Creates an SVG line with specified end-point coordinates.
+     * @param x1
+     * @param y1
+     * @param x2
+     * @param y2
+     * @param attributes - additional attributes.
+     */
+    static createLine(x1: number | string, y1: number | string, x2: number | string, y2: number | string, attributes?: Array<[string, string]>): SVGLineElement;
+    /**
+     * Creates an SVG polygon with specified points.
+     * @param points - points as string.
+     * @param attributes - additional attributes.
+     */
+    static createPolygon(points: string, attributes?: Array<[string, string]>): SVGPolygonElement;
+    /**
+     * Creates an SVG circle with the specified radius.
+     * @param radius
+     * @param attributes - additional attributes.
+     */
+    static createCircle(radius: number, attributes?: Array<[string, string]>): SVGCircleElement;
+    /**
+     * Creates an SVG ellipse with the specified horizontal and vertical radii.
+     * @param rx
+     * @param ry
+     * @param attributes - additional attributes.
+     */
+    static createEllipse(rx: number, ry: number, attributes?: Array<[string, string]>): SVGEllipseElement;
+    /**
+     * Creates an SVG group.
+     * @param attributes - additional attributes.
+     */
+    static createGroup(attributes?: Array<[string, string]>): SVGGElement;
+    /**
+     * Creates an SVG transform.
+     */
+    static createTransform(): SVGTransform;
+    /**
+     * Creates an SVG marker.
+     * @param id
+     * @param orient
+     * @param markerWidth
+     * @param markerHeight
+     * @param refX
+     * @param refY
+     * @param markerElement
+     */
+    static createMarker(id: string, orient: string, markerWidth: number | string, markerHeight: number | string, refX: number | string, refY: number | string, markerElement: SVGGraphicsElement): SVGMarkerElement;
+    /**
+     * Creaes an SVG text element.
+     * @param attributes - additional attributes.
+     */
+    static createText(attributes?: Array<[string, string]>): SVGTextElement;
+    /**
+     * Creates an SVG TSpan.
+     * @param text - inner text.
+     * @param attributes - additional attributes.
+     */
+    static createTSpan(text: string, attributes?: Array<[string, string]>): SVGTSpanElement;
+    /**
+     * Creates an SVG image element.
+     * @param attributes - additional attributes.
+     */
+    static createImage(attributes?: Array<[string, string]>): SVGImageElement;
+    /**
+     * Creates an SVG point with the specified coordinates.
+     * @param x
+     * @param y
+     */
+    static createPoint(x: number, y: number): SVGPoint;
+    /**
+     * Creates an SVG path with the specified shape (d).
+     * @param d - path shape
+     * @param attributes - additional attributes.
+     */
+    static createPath(d: string, attributes?: Array<[string, string]>): SVGPathElement;
+}
+
+/**
+ * Represents a simplified version of the SVGMatrix.
+ */
+interface ITransformMatrix {
+    a: number;
+    b: number;
+    c: number;
+    d: number;
+    e: number;
+    f: number;
+}
+/**
+ * A utility class to transform between SVGMatrix and its simplified representation.
+ */
+declare class TransformMatrix {
+    static toITransformMatrix(matrix: SVGMatrix): ITransformMatrix;
+    static toSVGMatrix(currentMatrix: SVGMatrix, newMatrix: ITransformMatrix): SVGMatrix;
+}
+
+/**
+ * LinearMarkerBase is a base class for all line-type markers (Line, Arrow, Measurement Tool, etc.).
+ */
+declare class LinearMarkerBase extends MarkerBase {
+    /**
+     * x coordinate of the first end-point
+     */
+    protected x1: number;
+    /**
+     * y coordinate of the first end-point
+     */
+    protected y1: number;
+    /**
+     * x coordinate of the second end-point
+     */
+    protected x2: number;
+    /**
+     * y coordinate of the second end-point
+     */
+    protected y2: number;
+    /**
+     * Default line length when marker is created with a simple click (without dragging).
+     */
+    protected defaultLength: number;
+    /**
+     * Marker's main visual.
+     */
+    protected visual: SVGGraphicsElement;
+    /**
+     * Creates a LineMarkerBase object.
+     *
+     * @param container - SVG container to hold marker's visual.
+     */
+    constructor(container: SVGGElement);
+    /**
+     * Returns true if passed SVG element belongs to the marker. False otherwise.
+     *
+     * @param el - target element.
+     */
+    ownsTarget(el: EventTarget): boolean;
+    /**
+     * Handles pointer (mouse, touch, stylus, etc.) down event.
+     *
+     * @param point - event coordinates.
+     * @param target - direct event target element.
+     */
+    pointerDown(point: IPoint, target?: EventTarget): void;
+    /**
+     * Handles pointer (mouse, touch, stylus, etc.) up event.
+     *
+     * @param point - event coordinates.
+     * @param target - direct event target element.
+     */
+    pointerUp(point: IPoint): void;
+    /**
+     * When implemented adjusts marker visual after manipulation when needed.
+     */
+    protected adjustVisual(): void;
+    /**
+     * Resizes the line marker.
+     * @param point - current manipulation coordinates.
+     */
+    protected resize(point: IPoint): void;
+    /**
+     * Displays marker's controls.
+     */
+    select(): void;
+    /**
+     * Hides marker's controls.
+     */
+    deselect(): void;
+    /**
+     * Restores marker's state to the previously saved one.
+     * @param state - previously saved state.
+     */
+    restoreState(state: MarkerBaseState): void;
+    /**
+     * Scales marker. Used after the image resize.
+     *
+     * @param scaleX - horizontal scale
+     * @param scaleY - vertical scale
+     */
+    scale(scaleX: number, scaleY: number): void;
+}
+
+/**
+ * Represents base state for line-style markers.
+ */
+interface LinearMarkerBaseState extends MarkerBaseState {
+    /**
+     * x coordinate for the first end-point.
+     */
+    x1: number;
+    /**
+     * y coordinate for the first end-point.
+     */
+    y1: number;
+    /**
+     * x coordinate for the second end-point.
+     */
+    x2: number;
+    /**
+     * y coordinate for the second end-point.
+     */
+    y2: number;
+}
+
+/**
+ * RectangularBoxMarkerBase is a base class for all marker's with rectangular controls such as all rectangle markers,
+ * text and callout markers.
+ *
+ * It creates and manages the rectangular control box and related resize, move, and rotate manipulations.
+ */
+declare class RectangularBoxMarkerBase extends MarkerBase {
+    /**
+     * x coordinate of the top-left corner.
+     */
+    protected left: number;
+    /**
+     * y coordinate of the top-left corner.
+     */
+    protected top: number;
+    /**
+     * Marker width.
+     */
+    protected width: number;
+    /**
+     * Marker height.
+     */
+    protected height: number;
+    /**
+     * The default marker size when the marker is created with a click (without dragging).
+     */
+    protected defaultSize: IPoint;
+    /**
+     * x coordinate of the top-left corner at the start of manipulation.
+     */
+    protected manipulationStartLeft: number;
+    /**
+     * y coordinate of the top-left corner at the start of manipulation.
+     */
+    protected manipulationStartTop: number;
+    /**
+     * Width at the start of manipulation.
+     */
+    protected manipulationStartWidth: number;
+    /**
+     * Height at the start of manipulation.
+     */
+    protected manipulationStartHeight: number;
+    /**
+     * x coordinate of the pointer at the start of manipulation.
+     */
+    protected manipulationStartX: number;
+    /**
+     * y coordinate of the pointer at the start of manipulation.
+     */
+    protected manipulationStartY: number;
+    /**
+     * Pointer's horizontal distance from the top left corner.
+     */
+    protected offsetX: number;
+    /**
+     * Pointer's vertical distance from the top left corner.
+     */
+    protected offsetY: number;
+    /**
+     * Marker's rotation angle.
+     */
+    protected rotationAngle: number;
+    /**
+     * x coordinate of the marker's center.
+     */
+    protected get centerX(): number;
+    /**
+     * y coordinate of the marker's center.
+     */
+    protected get centerY(): number;
+    private _visual;
+    /**
+     * Container for the marker's visual.
+     */
+    protected get visual(): SVGGraphicsElement;
+    protected set visual(value: SVGGraphicsElement);
+    /**
+     * Creates a new marker.
+     *
+     * @param container - SVG container to hold marker's visual.
+     */
+    constructor(container: SVGGElement);
+    /**
+     * Returns true if passed SVG element belongs to the marker. False otherwise.
+     *
+     * @param el - target element.
+     */
+    ownsTarget(el: EventTarget): boolean;
+    /**
+     * Handles pointer (mouse, touch, stylus, etc.) down event.
+     *
+     * @param point - event coordinates.
+     * @param target - direct event target element.
+     */
+    pointerDown(point: IPoint, target?: EventTarget): void;
+    /**
+     * Handles pointer (mouse, touch, stylus, etc.) up event.
+     *
+     * @param point - event coordinates.
+     * @param target - direct event target element.
+     */
+    pointerUp(point: IPoint): void;
+    /**
+     * Moves visual to the specified coordinates.
+     * @param point - coordinates of the new top-left corner of the visual.
+     */
+    protected moveVisual(point: IPoint): void;
+    /**
+     * Resizes the marker based on pointer coordinates and context.
+     * @param point - pointer coordinates.
+     */
+    protected resize(point: IPoint): void;
+    /**
+     * Sets control box size and location.
+     */
+    protected setSize(): void;
+    private rotate;
+    private applyRotation;
+    /**
+     * Returns point coordinates based on the actual screen coordinates and marker's rotation.
+     * @param point - original pointer coordinates
+     */
+    protected rotatePoint(point: IPoint): IPoint;
+    /**
+     * Returns original point coordinates based on coordinates with rotation applied.
+     * @param point - rotated point coordinates.
+     */
+    protected unrotatePoint(point: IPoint): IPoint;
+    /**
+     * Displays marker's controls.
+     */
+    select(): void;
+    /**
+     * Hides marker's controls.
+     */
+    deselect(): void;
+    /**
+     * Restores marker's state to the previously saved one.
+     * @param state - previously saved state.
+     */
+    restoreState(state: MarkerBaseState): void;
+    /**
+     * Scales marker. Used after the image resize.
+     *
+     * @param scaleX - horizontal scale
+     * @param scaleY - vertical scale
+     */
+    scale(scaleX: number, scaleY: number): void;
+}
+
+/**
+ * RecatngleMarker is a base class for all rectangular markers (Frame, Cover, Highlight, etc.)
+ */
+declare abstract class RectangleMarker extends RectangularBoxMarkerBase {
+    /**
+     * String type name of the marker type.
+     *
+     * Used when adding {@link MarkerView.availableMarkerTypes} via a string and to save and restore state.
+     */
+    static title: string;
+    /**
+     * Recangle fill color.
+     */
+    protected fillColor: string;
+    /**
+     * Rectangle stroke color.
+     */
+    protected strokeColor: string;
+    /**
+     * Rectangle border stroke width.
+     */
+    protected strokeWidth: number;
+    /**
+     * Rectangle border stroke dash array.
+     */
+    protected strokeDasharray: string;
+    /**
+     * Rectangle opacity (alpha). 0 to 1.
+     */
+    protected opacity: number;
+    /**
+     * Creates a new marker.
+     *
+     * @param container - SVG container to hold marker's visual.
+     */
+    constructor(container: SVGGElement);
+    /**
+     * Returns true if passed SVG element belongs to the marker. False otherwise.
+     *
+     * @param el - target element.
+     */
+    ownsTarget(el: EventTarget): boolean;
+    /**
+     * Creates the marker's rectangle visual.
+     */
+    protected createVisual(): void;
+    /**
+     * Handles pointer (mouse, touch, stylus, etc.) down event.
+     *
+     * @param point - event coordinates.
+     * @param target - direct event target element.
+     */
+    pointerDown(point: IPoint, target?: EventTarget): void;
+    /**
+     * Resizes the marker based on the pointer coordinates.
+     * @param point - current pointer coordinates.
+     */
+    protected resize(point: IPoint): void;
+    /**
+     * Sets visual's width and height attributes based on marker's width and height.
+     */
+    protected setSize(): void;
+    /**
+     * Handles pointer (mouse, touch, stylus, etc.) up event.
+     *
+     * @param point - event coordinates.
+     * @param target - direct event target element.
+     */
+    pointerUp(point: IPoint): void;
+    /**
+     * Sets rectangle's border stroke color.
+     * @param color - color as string
+     */
+    protected setStrokeColor(color: string): void;
+    /**
+     * Sets rectangle's fill color.
+     * @param color - color as string
+     */
+    protected setFillColor(color: string): void;
+    /**
+     * Sets rectangle's border stroke (line) width.
+     * @param color - color as string
+     */
+    protected setStrokeWidth(width: number): void;
+    /**
+     * Sets rectangle's border stroke dash array.
+     * @param color - color as string
+     */
+    protected setStrokeDasharray(dashes: string): void;
+    /**
+     * Restores previously saved marker state.
+     *
+     * @param state - previously saved state.
+     */
+    restoreState(state: MarkerBaseState): void;
+    /**
+     * Scales marker. Used after the image resize.
+     *
+     * @param scaleX - horizontal scale
+     * @param scaleY - vertical scale
+     */
+    scale(scaleX: number, scaleY: number): void;
+}
+
+/**
+ * Represents a state snapshot of a RectangularBoxMarkerBase.
+ */
+interface RectangularBoxMarkerBaseState extends MarkerBaseState {
+    /**
+     * x coordinate of the top-left corner.
+     */
+    left: number;
+    /**
+     * y coordinate of the top-left corner.
+     */
+    top: number;
+    /**
+     * Marker's width.
+     */
+    width: number;
+    /**
+     * Marker's height.
+     */
+    height: number;
+    /**
+     * Marker's rotation angle.
+     */
+    rotationAngle: number;
+    /**
+     * Transformation matrix for the marker's visual.
+     */
+    visualTransformMatrix: ITransformMatrix;
+    /**
+     * Transofrmation matrix for the marker's container.
+     */
+    containerTransformMatrix: ITransformMatrix;
+}
+
+/**
+ * Represents RectangleMarker's state.
+ */
+interface RectangleMarkerState extends RectangularBoxMarkerBaseState {
+    /**
+     * Rectangle fill color.
+     */
+    fillColor: string;
+    /**
+     * Rectangle border stroke (line) color.
+     */
+    strokeColor: string;
+    /**
+     * Rectange border width.
+     */
+    strokeWidth: number;
+    /**
+     * Rectange border dash array.
+     */
+    strokeDasharray: string;
+    /**
+     * Rectangle opacity (alpha). 0 to 1.
+     */
+    opacity: number;
+}
+
+declare class LineMarker extends LinearMarkerBase {
+    /**
+     * String type name of the marker type.
+     *
+     * Used when adding {@link MarkerView.availableMarkerTypes} via a string and to save and restore state.
+     */
+    static typeName: string;
+    /**
+     * Marker type title (display name) used for accessibility and other attributes.
+     */
+    static title: string;
+    /**
+     * Invisible wider line to make selection easier/possible.
+     */
+    protected selectorLine: SVGLineElement;
+    /**
+     * Visible marker line.
+     */
+    protected visibleLine: SVGLineElement;
+    /**
+     * Line color.
+     */
+    protected strokeColor: string;
+    /**
+     * Line width.
+     */
+    protected strokeWidth: number;
+    /**
+     * Line dash array.
+     */
+    protected strokeDasharray: string;
+    /**
+     * Creates a new marker.
+     *
+     * @param container - SVG container to hold marker's visual.
+     */
+    constructor(container: SVGGElement);
+    /**
+     * Returns true if passed SVG element belongs to the marker. False otherwise.
+     *
+     * @param el - target element.
+     */
+    ownsTarget(el: EventTarget): boolean;
+    private createVisual;
+    /**
+     * Handles pointer (mouse, touch, stylus, etc.) down event.
+     *
+     * @param point - event coordinates.
+     * @param target - direct event target element.
+     */
+    pointerDown(point: IPoint, target?: EventTarget): void;
+    /**
+     * Adjusts visual after manipulation.
+     */
+    protected adjustVisual(): void;
+    /**
+     * Sets line color.
+     * @param color - new color.
+     */
+    protected setStrokeColor(color: string): void;
+    /**
+     * Sets line width.
+     * @param width - new width.
+     */
+    protected setStrokeWidth(width: number): void;
+    /**
+     * Sets line dash array.
+     * @param dashes - new dash array.
+     */
+    protected setStrokeDasharray(dashes: string): void;
+    /**
+     * Restores previously saved marker state.
+     *
+     * @param state - previously saved state.
+     */
+    restoreState(state: MarkerBaseState): void;
+}
+
+/**
+ * Represents an arrow marker.
+ */
+declare class ArrowMarker extends LineMarker {
+    /**
+     * String type name of the marker type.
+     *
+     * Used when adding {@link MarkerView.availableMarkerTypes} via a string and to save and restore state.
+     */
+    static typeName: string;
+    /**
+     * Marker type title (display name) used for accessibility and other attributes.
+     */
+    static title: string;
+    private arrow1;
+    private arrow2;
+    private arrowType;
+    private arrowBaseHeight;
+    private arrowBaseWidth;
+    /**
+     * Creates a new marker.
+     *
+     * @param container - SVG container to hold marker's visual.
+     */
+    constructor(container: SVGGElement);
+    /**
+     * Returns true if passed SVG element belongs to the marker. False otherwise.
+     *
+     * @param el - target element.
+     */
+    ownsTarget(el: EventTarget): boolean;
+    private getArrowPoints;
+    private createTips;
+    /**
+     * Handles pointer (mouse, touch, stylus, etc.) down event.
+     *
+     * @param point - event coordinates.
+     * @param target - direct event target element.
+     */
+    pointerDown(point: IPoint, target?: EventTarget): void;
+    /**
+     * Adjusts marker visual after manipulation.
+     */
+    protected adjustVisual(): void;
+    private setArrowType;
+    /**
+     * Restores previously saved marker state.
+     *
+     * @param state - previously saved state.
+     */
+    restoreState(state: MarkerBaseState): void;
+}
+
+/**
+ * Represents state of a {@link LineMarker}.
+ */
+interface LineMarkerState extends LinearMarkerBaseState {
+    /**
+     * Line color.
+     */
+    strokeColor: string;
+    /**
+     * Line width.
+     */
+    strokeWidth: number;
+    /**
+     * Line dash array.
+     */
+    strokeDasharray: string;
+}
+
+declare type ArrowType = 'both' | 'start' | 'end' | 'none';
+/**
+ * Represents arrow marker state.
+ */
+interface ArrowMarkerState extends LineMarkerState {
+    /**
+     * Type of arrow.
+     */
+    arrowType: ArrowType;
+}
+
+declare class TextMarker extends RectangularBoxMarkerBase {
+    /**
+     * String type name of the marker type.
+     *
+     * Used when adding {@link MarkerView.availableMarkerTypes} via a string and to save and restore state.
+     */
+    static typeName: string;
+    /**
+     * Marker type title (display name) used for accessibility and other attributes.
+     */
+    static title: string;
+    /**
+     * Text color.
+     */
+    protected color: string;
+    /**
+     * Text's font family.
+     */
+    protected fontFamily: string;
+    /**
+     * Padding inside of the marker's bounding box in percents.
+     */
+    protected padding: number;
+    private text;
+    /**
+     * Visual text element.
+     */
+    protected textElement: SVGTextElement;
+    /**
+     * Text background rectangle.
+     */
+    protected bgRectangle: SVGRectElement;
+    private pointerDownPoint;
+    /**
+     * Creates a new marker.
+     *
+     * @param container - SVG container to hold marker's visual.
+     */
+    constructor(container: SVGGElement);
+    /**
+     * Returns true if passed SVG element belongs to the marker. False otherwise.
+     *
+     * @param el - target element.
+     */
+    ownsTarget(el: EventTarget): boolean;
+    /**
+     * Creates text marker visual.
+     */
+    protected createVisual(): void;
+    /**
+     * Handles pointer (mouse, touch, stylus, etc.) down event.
+     *
+     * @param point - event coordinates.
+     * @param target - direct event target element.
+     */
+    pointerDown(point: IPoint, target?: EventTarget): void;
+    private renderText;
+    private getTextScale;
+    private getTextPosition;
+    private sizeText;
+    /**
+     * Resize marker based on current pointer coordinates and context.
+     * @param point
+     */
+    protected resize(point: IPoint): void;
+    /**
+     * Sets size of marker elements after manipulation.
+     */
+    protected setSize(): void;
+    /**
+     * Handles pointer (mouse, touch, stylus, etc.) up event.
+     *
+     * @param point - event coordinates.
+     */
+    pointerUp(point: IPoint): void;
+    /**
+     * Deselects this marker, renders text (if necessary), and hides selected marker UI.
+     */
+    deselect(): void;
+    /**
+     * Opens text editor on double-click.
+     * @param point
+     * @param target
+     */
+    dblClick(point: IPoint, target?: EventTarget): void;
+    /**
+     * Sets text color.
+     * @param color - new text color.
+     */
+    protected setColor(color: string): void;
+    /**
+     * Sets font family.
+     * @param font - new font family.
+     */
+    protected setFont(font: string): void;
+    /**
+     * Restores previously saved marker state.
+     *
+     * @param state - previously saved state.
+     */
+    restoreState(state: MarkerBaseState): void;
+    /**
+     * Scales marker. Used after the image resize.
+     *
+     * @param scaleX - horizontal scale
+     * @param scaleY - vertical scale
+     */
+    scale(scaleX: number, scaleY: number): void;
+}
+
+declare class CalloutMarker extends TextMarker {
+    /**
+     * String type name of the marker type.
+     *
+     * Used when adding {@link MarkerView.availableMarkerTypes} via a string and to save and restore state.
+     */
+    static typeName: string;
+    /**
+     * Marker type title (display name) used for accessibility and other attributes.
+     */
+    static title: string;
+    private bgColor;
+    private tipPosition;
+    private tipBase1Position;
+    private tipBase2Position;
+    private tip;
+    /**
+     * Creates a new marker.
+     *
+     * @param container - SVG container to hold marker's visual.
+     */
+    constructor(container: SVGGElement);
+    /**
+     * Returns true if passed SVG element belongs to the marker. False otherwise.
+     *
+     * @param el - target element.
+     */
+    ownsTarget(el: EventTarget): boolean;
+    private createTip;
+    /**
+     * Handles pointer (mouse, touch, stylus, etc.) down event.
+     *
+     * @param point - event coordinates.
+     * @param target - direct event target element.
+     */
+    pointerDown(point: IPoint, target?: EventTarget): void;
+    /**
+     * Handles pointer (mouse, touch, stylus, etc.) up event.
+     *
+     * @param point - event coordinates.
+     */
+    pointerUp(point: IPoint): void;
+    /**
+     * Sets marker's background/fill color.
+     * @param color - new background color.
+     */
+    protected setBgColor(color: string): void;
+    private getTipPoints;
+    private setTipPoints;
+    /**
+     * Resize marker based on current pointer coordinates and context.
+     * @param point
+     */
+    protected resize(point: IPoint): void;
+    private positionTip;
+    /**
+     * Selects this marker and displays appropriate selected marker UI.
+     */
+    select(): void;
+    /**
+     * Restores previously saved marker state.
+     *
+     * @param state - previously saved state.
+     */
+    restoreState(state: MarkerBaseState): void;
+    /**
+     * Scales marker. Used after the image resize.
+     *
+     * @param scaleX - horizontal scale
+     * @param scaleY - vertical scale
+     */
+    scale(scaleX: number, scaleY: number): void;
+}
+
+/**
+ * TextMarker state
+ */
+interface TextMarkerState extends RectangularBoxMarkerBaseState {
+    /**
+     * Font color.
+     */
+    color: string;
+    /**
+     * Font family.
+     */
+    fontFamily: string;
+    /**
+     * Padding inside the control's rectangle.
+     */
+    padding: number;
+    /**
+     * Marker's text content.
+     */
+    text: string;
+}
+
+/**
+ * Represents the state of a CalloutMarker.
+ */
+interface CalloutMarkerState extends TextMarkerState {
+    /**
+     * Background (fill) color.
+     */
+    bgColor: string;
+    /**
+     * Position of the callout tip.
+     */
+    tipPosition: IPoint;
+}
+
+declare class CoverMarker extends RectangleMarker {
+    /**
+     * String type name of the marker type.
+     *
+     * Used when adding {@link MarkerView.availableMarkerTypes} via a string and to save and restore state.
+     */
+    static typeName: string;
+    /**
+     * Marker type title (display name) used for accessibility and other attributes.
+     */
+    static title: string;
+    /**
+     * Creates a new marker.
+     *
+     * @param container - SVG container to hold marker's visual.
+     */
+    constructor(container: SVGGElement);
+}
+
+declare class EllipseMarker extends RectangularBoxMarkerBase {
+    /**
+     * String type name of the marker type.
+     *
+     * Used when adding {@link MarkerView.availableMarkerTypes} via a string and to save and restore state.
+     */
+    static typeName: string;
+    /**
+     * Marker type title (display name) used for accessibility and other attributes.
+     */
+    static title: string;
+    /**
+     * Ellipse fill color.
+     */
+    protected fillColor: string;
+    /**
+     * Ellipse border color.
+     */
+    protected strokeColor: string;
+    /**
+     * Ellipse border line width.
+     */
+    protected strokeWidth: number;
+    /**
+     * Ellipse border dash array.
+     */
+    protected strokeDasharray: string;
+    /**
+     * Ellipse opacity (0..1).
+     */
+    protected opacity: number;
+    /**
+     * Creates a new marker.
+     *
+     * @param container - SVG container to hold marker's visual.
+     */
+    constructor(container: SVGGElement);
+    /**
+     * Returns true if passed SVG element belongs to the marker. False otherwise.
+     *
+     * @param el - target element.
+     */
+    ownsTarget(el: EventTarget): boolean;
+    /**
+     * Creates marker visual.
+     */
+    protected createVisual(): void;
+    /**
+     * Handles pointer (mouse, touch, stylus, etc.) down event.
+     *
+     * @param point - event coordinates.
+     * @param target - direct event target element.
+     */
+    pointerDown(point: IPoint, target?: EventTarget): void;
+    /**
+     * Resize marker based on current pointer coordinates and context.
+     * @param point
+     */
+    protected resize(point: IPoint): void;
+    /**
+     * Sets marker's visual size after manipulation.
+     */
+    protected setSize(): void;
+    /**
+     * Handles pointer (mouse, touch, stylus, etc.) up event.
+     *
+     * @param point - event coordinates.
+     */
+    pointerUp(point: IPoint): void;
+    /**
+     * Sets marker's line color.
+     * @param color - new line color.
+     */
+    protected setStrokeColor(color: string): void;
+    /**
+     * Sets marker's fill (background) color.
+     * @param color - new fill color.
+     */
+    protected setFillColor(color: string): void;
+    /**
+     * Sets marker's line width.
+     * @param width - new line width
+     */
+    protected setStrokeWidth(width: number): void;
+    /**
+     * Sets marker's border dash array.
+     * @param dashes - new dash array.
+     */
+    protected setStrokeDasharray(dashes: string): void;
+    /**
+     * Sets marker's opacity.
+     * @param opacity - new opacity value (0..1).
+     */
+    protected setOpacity(opacity: number): void;
+    /**
+     * Restores previously saved marker state.
+     *
+     * @param state - previously saved state.
+     */
+    restoreState(state: MarkerBaseState): void;
+    /**
+     * Scales marker. Used after the image resize.
+     *
+     * @param scaleX - horizontal scale
+     * @param scaleY - vertical scale
+     */
+    scale(scaleX: number, scaleY: number): void;
+}
+
+declare class EllipseFrameMarker extends EllipseMarker {
+    /**
+     * String type name of the marker type.
+     *
+     * Used when adding {@link MarkerView.availableMarkerTypes} via a string and to save and restore state.
+     */
+    static typeName: string;
+    /**
+     * Marker type title (display name) used for accessibility and other attributes.
+     */
+    static title: string;
+    /**
+     * Creates a new marker.
+     *
+     * @param container - SVG container to hold marker's visual.
+     */
+    constructor(container: SVGGElement);
+}
+
+declare class FrameMarker extends RectangleMarker {
+    /**
+     * String type name of the marker type.
+     *
+     * Used when adding {@link MarkerView.availableMarkerTypes} via a string and to save and restore state.
+     */
+    static typeName: string;
+    /**
+     * Marker type title (display name) used for accessibility and other attributes.
+     */
+    static title: string;
+    /**
+     * Creates a new marker.
+     *
+     * @param container - SVG container to hold marker's visual.
+     */
+    constructor(container: SVGGElement);
+}
+
+declare class FreehandMarker extends RectangularBoxMarkerBase {
+    /**
+     * String type name of the marker type.
+     *
+     * Used when adding {@link MarkerView.availableMarkerTypes} via a string and to save and restore state.
+     */
+    static typeName: string;
+    /**
+     * Marker type title (display name) used for accessibility and other attributes.
+     */
+    static title: string;
+    /**
+     * Marker color.
+     */
+    protected color: string;
+    /**
+     * Marker's stroke width.
+     */
+    protected lineWidth: number;
+    private drawingImage;
+    private drawingImgUrl;
+    /**
+     * Creates a new marker.
+     *
+     * @param container - SVG container to hold marker's visual.
+     */
+    constructor(container: SVGGElement);
+    /**
+     * Returns true if passed SVG element belongs to the marker. False otherwise.
+     *
+     * @param el - target element.
+     */
+    ownsTarget(el: EventTarget): boolean;
+    private createVisual;
+    /**
+     * Handles pointer (mouse, touch, stylus, etc.) down event.
+     *
+     * @param point - event coordinates.
+     * @param target - direct event target element.
+     */
+    pointerDown(point: IPoint, target?: EventTarget): void;
+    /**
+     * Resize marker based on current pointer coordinates and context.
+     * @param point
+     */
+    protected resize(point: IPoint): void;
+    /**
+     * Handles pointer (mouse, touch, stylus, etc.) up event.
+     *
+     * @param point - event coordinates.
+     */
+    pointerUp(point: IPoint): void;
+    /**
+     * Selects this marker and displays appropriate selected marker UI.
+     */
+    select(): void;
+    /**
+     * Deselects this marker and hides selected marker UI.
+     */
+    deselect(): void;
+    private setDrawingImage;
+    /**
+     * Restores previously saved marker state.
+     *
+     * @param state - previously saved state.
+     */
+    restoreState(state: MarkerBaseState): void;
+    /**
+     * Scales marker. Used after the image resize.
+     *
+     * @param scaleX - horizontal scale
+     * @param scaleY - vertical scale
+     */
+    scale(scaleX: number, scaleY: number): void;
+}
+
+/**
+ * Represents state of the {@link FreehandMarker}.
+ */
+interface FreehandMarkerState extends RectangularBoxMarkerBaseState {
+    /**
+     * URL of the drawing image.
+     */
+    drawingImgUrl: string;
+}
+
+declare class HighlightMarker extends CoverMarker {
+    /**
+     * String type name of the marker type.
+     *
+     * Used when adding {@link MarkerView.availableMarkerTypes} via a string and to save and restore state.
+     */
+    static typeName: string;
+    /**
+     * Marker type title (display name) used for accessibility and other attributes.
+     */
+    static title: string;
+    /**
+     * Creates a new marker.
+     *
+     * @param container - SVG container to hold marker's visual.
+     */
+    constructor(container: SVGGElement);
+    /**
+     * Sets marker's opacity (0..1).
+     * @param opacity - new opacity value.
+     */
+    protected setOpacity(opacity: number): void;
+}
+
+declare class MeasurementMarker extends LineMarker {
+    /**
+     * String type name of the marker type.
+     *
+     * Used when adding {@link MarkerView.availableMarkerTypes} via a string and to save and restore state.
+     */
+    static typeName: string;
+    /**
+     * Marker type title (display name) used for accessibility and other attributes.
+     */
+    static title: string;
+    private tip1;
+    private tip2;
+    private get tipLength();
+    /**
+     * Creates a new marker.
+     *
+     * @param container - SVG container to hold marker's visual.
+     */
+    constructor(container: SVGGElement);
+    /**
+     * Returns true if passed SVG element belongs to the marker. False otherwise.
+     *
+     * @param el - target element.
+     */
+    ownsTarget(el: EventTarget): boolean;
+    private createTips;
+    /**
+     * Handles pointer (mouse, touch, stylus, etc.) down event.
+     *
+     * @param point - event coordinates.
+     * @param target - direct event target element.
+     */
+    pointerDown(point: IPoint, target?: EventTarget): void;
+    /**
+     * Adjusts marker visual after manipulation.
+     */
+    protected adjustVisual(): void;
+    /**
+     * Restores previously saved marker state.
+     *
+     * @param state - previously saved state.
+     */
+    restoreState(state: MarkerBaseState): void;
+}
+
+declare class CurveMarker extends LinearMarkerBase {
+    /**
+     * String type name of the marker type.
+     *
+     * Used when adding {@link MarkerView.availableMarkerTypes} via a string and to save and restore state.
+     */
+    static typeName: string;
+    /**
+     * Marker type title (display name) used for accessibility and other attributes.
+     */
+    static title: string;
+    /**
+     * Invisible wider curve to make selection easier/possible.
+     */
+    protected selectorCurve: SVGPathElement;
+    /**
+     * Visible marker curve.
+     */
+    protected visibleCurve: SVGPathElement;
+    /**
+     * Line color.
+     */
+    protected strokeColor: string;
+    /**
+     * Line width.
+     */
+    protected strokeWidth: number;
+    /**
+     * Line dash array.
+     */
+    protected strokeDasharray: string;
+    private curveX;
+    private curveY;
+    /**
+     * Creates a new marker.
+     *
+     * @param container - SVG container to hold marker's visual.
+     */
+    constructor(container: SVGGElement);
+    /**
+     * Returns true if passed SVG element belongs to the marker. False otherwise.
+     *
+     * @param el - target element.
+     */
+    ownsTarget(el: EventTarget): boolean;
+    private getPathD;
+    private createVisual;
+    /**
+     * Handles pointer (mouse, touch, stylus, etc.) down event.
+     *
+     * @param point - event coordinates.
+     * @param target - direct event target element.
+     */
+    pointerDown(point: IPoint, target?: EventTarget): void;
+    /**
+     * Adjusts visual after manipulation.
+     */
+    protected adjustVisual(): void;
+    /**
+     * Sets line color.
+     * @param color - new color.
+     */
+    protected setStrokeColor(color: string): void;
+    /**
+     * Sets line width.
+     * @param width - new width.
+     */
+    protected setStrokeWidth(width: number): void;
+    /**
+     * Sets line dash array.
+     * @param dashes - new dash array.
+     */
+    protected setStrokeDasharray(dashes: string): void;
+    /**
+     * Scales marker. Used after the image resize.
+     *
+     * @param scaleX - horizontal scale
+     * @param scaleY - vertical scale
+     */
+    scale(scaleX: number, scaleY: number): void;
+    /**
+     * Restores previously saved marker state.
+     *
+     * @param state - previously saved state.
+     */
+    restoreState(state: MarkerBaseState): void;
+}
+
+/**
+ * Represents state of a {@link CurveMarker}.
+ */
+interface CurveMarkerState extends LinearMarkerBaseState {
+    /**
+     * Line color.
+     */
+    strokeColor: string;
+    /**
+     * Line width.
+     */
+    strokeWidth: number;
+    /**
+     * Line dash array.
+     */
+    strokeDasharray: string;
+    curveX: number;
+    curveY: number;
+}
+
+export { Activator, ArrowMarker, ArrowMarkerState, CalloutMarker, CalloutMarkerState, CoverMarker, CurveMarker, CurveMarkerState, EllipseFrameMarker, EllipseMarker, EventHandler, EventListenerRepository, FrameMarker, FreehandMarker, FreehandMarkerState, HighlightMarker, IEventListenerRepository, IMarkerViewPlugin, IPoint, ITransformMatrix, LineMarker, LineMarkerState, LinearMarkerBase, LinearMarkerBaseState, MarkerAreaState, MarkerBase, MarkerBaseState, MarkerEventHandler, MarkerView, MarkerViewEventHandler, MeasurementMarker, PointerEventHandler, RectangleMarker, RectangleMarkerState, RectangularBoxMarkerBase, RectangularBoxMarkerBaseState, StyleClass, StyleManager, StyleRule, SvgHelper, TextMarker, TextMarkerState, TransformMatrix };
diff --git a/capsule-prototype/js/libs/markerjslive/markerjs-live.esm.js b/capsule-prototype/js/libs/markerjslive/markerjs-live.esm.js
new file mode 100644
index 0000000000000000000000000000000000000000..6f1492ba7736d9bb3779940b8aee643cbdfb57d6
--- /dev/null
+++ b/capsule-prototype/js/libs/markerjslive/markerjs-live.esm.js
@@ -0,0 +1,2 @@
+var t=function(){function t(){}return t.createDefs=function(){return document.createElementNS("http://www.w3.org/2000/svg","defs")},t.createStylesheet=function(){var t=document.createElementNS("http://www.w3.org/2000/svg","style");return t.setAttribute("type","text/css"),t},t.setAttributes=function(t,e){for(var i=0,s=e;i<s.length;i++){var r=s[i],o=r[0],n=r[1];t.setAttribute(o,n)}},t.createRect=function(e,i,s){var r=document.createElementNS("http://www.w3.org/2000/svg","rect");return r.setAttribute("width",e.toString()),r.setAttribute("height",i.toString()),s&&t.setAttributes(r,s),r},t.createLine=function(e,i,s,r,o){var n=document.createElementNS("http://www.w3.org/2000/svg","line");return n.setAttribute("x1",e.toString()),n.setAttribute("y1",i.toString()),n.setAttribute("x2",s.toString()),n.setAttribute("y2",r.toString()),o&&t.setAttributes(n,o),n},t.createPolygon=function(e,i){var s=document.createElementNS("http://www.w3.org/2000/svg","polygon");return s.setAttribute("points",e),i&&t.setAttributes(s,i),s},t.createCircle=function(e,i){var s=document.createElementNS("http://www.w3.org/2000/svg","circle");return s.setAttribute("cx",(e/2).toString()),s.setAttribute("cy",(e/2).toString()),s.setAttribute("r",e.toString()),i&&t.setAttributes(s,i),s},t.createEllipse=function(e,i,s){var r=document.createElementNS("http://www.w3.org/2000/svg","ellipse");return r.setAttribute("cx",(e/2).toString()),r.setAttribute("cy",(i/2).toString()),r.setAttribute("rx",(e/2).toString()),r.setAttribute("ry",(i/2).toString()),s&&t.setAttributes(r,s),r},t.createGroup=function(e){var i=document.createElementNS("http://www.w3.org/2000/svg","g");return e&&t.setAttributes(i,e),i},t.createTransform=function(){return document.createElementNS("http://www.w3.org/2000/svg","svg").createSVGTransform()},t.createMarker=function(e,i,s,r,o,n,h){var a=document.createElementNS("http://www.w3.org/2000/svg","marker");return t.setAttributes(a,[["id",e],["orient",i],["markerWidth",s.toString()],["markerHeight",r.toString()],["refX",o.toString()],["refY",n.toString()]]),a.appendChild(h),a},t.createText=function(e){var i=document.createElementNS("http://www.w3.org/2000/svg","text");return i.setAttribute("x","0"),i.setAttribute("y","0"),e&&t.setAttributes(i,e),i},t.createTSpan=function(e,i){var s=document.createElementNS("http://www.w3.org/2000/svg","tspan");return s.textContent=e,i&&t.setAttributes(s,i),s},t.createImage=function(e){var i=document.createElementNS("http://www.w3.org/2000/svg","image");return e&&t.setAttributes(i,e),i},t.createPoint=function(t,e){var i=document.createElementNS("http://www.w3.org/2000/svg","svg").createSVGPoint();return i.x=t,i.y=e,i},t.createPath=function(e,i){var s=document.createElementNS("http://www.w3.org/2000/svg","path");return s.setAttribute("d",e),i&&t.setAttributes(s,i),s},t}(),e=function(){function t(){}return t.addKey=function(e){t.key=e},Object.defineProperty(t,"isLicensed",{get:function(){return!!t.key&&new RegExp(/^MJSL-[A-Z][0-9]{3}-[A-Z][0-9]{3}-[0-9]{4}$/,"i").test(t.key)},enumerable:!1,configurable:!0}),t}(),i=function(t,e){return(i=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])})(t,e)};function s(t,e){function s(){this.constructor=t}i(t,e),t.prototype=null===e?Object.create(e):(s.prototype=e.prototype,new s)}var r=function(){function e(e){this._outerContainer=e;var i=t.createGroup();this._outerContainer.appendChild(i),this._container=i}return Object.defineProperty(e.prototype,"outerContainer",{get:function(){return this._outerContainer},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"container",{get:function(){return this._container},enumerable:!1,configurable:!0}),e.prototype.ownsTarget=function(t){return!1},e.prototype.select=function(){},e.prototype.deselect=function(){},e.prototype.pointerDown=function(t,e){},e.prototype.dblClick=function(t,e){},e.prototype.pointerUp=function(t){},e.prototype.dispose=function(){},e.prototype.addMarkerVisualToContainer=function(t){this.container.childNodes.length>0?this.container.insertBefore(t,this.container.childNodes[0]):this.container.appendChild(t)},e.prototype.restoreState=function(t){this.notes=t.notes},e.prototype.scale=function(t,e){},e.typeName="MarkerBase",e}(),o=function(){function t(){}return t.toITransformMatrix=function(t){return{a:t.a,b:t.b,c:t.c,d:t.d,e:t.e,f:t.f}},t.toSVGMatrix=function(t,e){return t.a=e.a,t.b=e.b,t.c=e.c,t.d=e.d,t.e=e.e,t.f=e.f,t},t}(),n=function(e){function i(i){var s=e.call(this,i)||this;return s.left=0,s.top=0,s.width=0,s.height=0,s.defaultSize={x:50,y:20},s.offsetX=0,s.offsetY=0,s.rotationAngle=0,s.container.transform.baseVal.appendItem(t.createTransform()),s}return s(i,e),Object.defineProperty(i.prototype,"centerX",{get:function(){return this.left+this.width/2},enumerable:!1,configurable:!0}),Object.defineProperty(i.prototype,"centerY",{get:function(){return this.top+this.height/2},enumerable:!1,configurable:!0}),Object.defineProperty(i.prototype,"visual",{get:function(){return this._visual},set:function(e){this._visual=e;var i=t.createTransform();this._visual.transform.baseVal.appendItem(i)},enumerable:!1,configurable:!0}),i.prototype.ownsTarget=function(t){return!!e.prototype.ownsTarget.call(this,t)},i.prototype.pointerDown=function(t,i){e.prototype.pointerDown.call(this,t,i),this.select()},i.prototype.pointerUp=function(t){e.prototype.pointerUp.call(this,t)},i.prototype.moveVisual=function(t){this.visual.style.transform="translate("+t.x+"px, "+t.y+"px)"},i.prototype.resize=function(t){this.setSize()},i.prototype.setSize=function(){this.moveVisual({x:this.left,y:this.top})},i.prototype.rotate=function(t){if(Math.abs(t.x-this.centerX)>.1){var e=Math.sign(t.x-this.centerX);this.rotationAngle=180*Math.atan((t.y-this.centerY)/(t.x-this.centerX))/Math.PI+90*e,this.applyRotation()}},i.prototype.applyRotation=function(){var t=this.container.transform.baseVal.getItem(0);t.setRotate(this.rotationAngle,this.centerX,this.centerY),this.container.transform.baseVal.replaceItem(t,0)},i.prototype.rotatePoint=function(e){if(0===this.rotationAngle)return e;var i=this.container.getCTM(),s=t.createPoint(e.x,e.y);return{x:(s=s.matrixTransform(i)).x,y:s.y}},i.prototype.unrotatePoint=function(e){if(0===this.rotationAngle)return e;var i=this.container.getCTM();i=i.inverse();var s=t.createPoint(e.x,e.y);return{x:(s=s.matrixTransform(i)).x,y:s.y}},i.prototype.select=function(){e.prototype.select.call(this)},i.prototype.deselect=function(){e.prototype.deselect.call(this)},i.prototype.restoreState=function(t){e.prototype.restoreState.call(this,t);var i=t;this.left=i.left,this.top=i.top,this.width=i.width,this.height=i.height,this.rotationAngle=i.rotationAngle,this.visual.transform.baseVal.getItem(0).setMatrix(o.toSVGMatrix(this.visual.transform.baseVal.getItem(0).matrix,i.visualTransformMatrix)),this.container.transform.baseVal.getItem(0).setMatrix(o.toSVGMatrix(this.container.transform.baseVal.getItem(0).matrix,i.containerTransformMatrix))},i.prototype.scale=function(t,i){e.prototype.scale.call(this,t,i);var s=this.rotatePoint({x:this.left,y:this.top}),r=this.unrotatePoint({x:s.x*t,y:s.y*i});this.left=r.x,this.top=r.y,this.width=this.width*t,this.height=this.height*i},i}(r),h=function(e){function i(t){var i=e.call(this,t)||this;return i.fillColor="transparent",i.strokeColor="transparent",i.strokeWidth=0,i.strokeDasharray="",i.opacity=1,i.setStrokeColor=i.setStrokeColor.bind(i),i.setFillColor=i.setFillColor.bind(i),i.setStrokeWidth=i.setStrokeWidth.bind(i),i.setStrokeDasharray=i.setStrokeDasharray.bind(i),i.createVisual=i.createVisual.bind(i),i}return s(i,e),i.prototype.ownsTarget=function(t){return!(!e.prototype.ownsTarget.call(this,t)&&t!==this.visual)},i.prototype.createVisual=function(){this.visual=t.createRect(1,1,[["fill",this.fillColor],["stroke",this.strokeColor],["stroke-width",this.strokeWidth.toString()],["stroke-dasharray",this.strokeDasharray],["opacity",this.opacity.toString()]]),this.addMarkerVisualToContainer(this.visual)},i.prototype.pointerDown=function(t,i){e.prototype.pointerDown.call(this,t,i)},i.prototype.resize=function(t){e.prototype.resize.call(this,t),this.setSize()},i.prototype.setSize=function(){e.prototype.setSize.call(this),t.setAttributes(this.visual,[["width",this.width.toString()],["height",this.height.toString()]])},i.prototype.pointerUp=function(t){e.prototype.pointerUp.call(this,t),this.setSize()},i.prototype.setStrokeColor=function(e){this.strokeColor=e,this.visual&&t.setAttributes(this.visual,[["stroke",this.strokeColor]])},i.prototype.setFillColor=function(e){this.fillColor=e,this.visual&&t.setAttributes(this.visual,[["fill",this.fillColor]])},i.prototype.setStrokeWidth=function(e){this.strokeWidth=e,this.visual&&t.setAttributes(this.visual,[["stroke-width",this.strokeWidth.toString()]])},i.prototype.setStrokeDasharray=function(e){this.strokeDasharray=e,this.visual&&t.setAttributes(this.visual,[["stroke-dasharray",this.strokeDasharray]])},i.prototype.restoreState=function(t){var i=t;this.fillColor=i.fillColor,this.strokeColor=i.strokeColor,this.strokeWidth=i.strokeWidth,this.strokeDasharray=i.strokeDasharray,this.opacity=i.opacity,this.createVisual(),e.prototype.restoreState.call(this,t),this.setSize()},i.prototype.scale=function(t,i){e.prototype.scale.call(this,t,i),this.setSize()},i.title="Rectangle marker",i}(n),a=function(t){function e(e){return t.call(this,e)||this}return s(e,t),e.typeName="FrameMarker",e.title="Frame marker",e}(h),l=function(t){function e(e){var i=t.call(this,e)||this;return i.x1=0,i.y1=0,i.x2=0,i.y2=0,i.defaultLength=50,i}return s(e,t),e.prototype.ownsTarget=function(e){return!!t.prototype.ownsTarget.call(this,e)},e.prototype.pointerDown=function(e,i){t.prototype.pointerDown.call(this,e,i)},e.prototype.pointerUp=function(e){t.prototype.pointerUp.call(this,e)},e.prototype.adjustVisual=function(){},e.prototype.resize=function(t){this.adjustVisual()},e.prototype.select=function(){t.prototype.select.call(this)},e.prototype.deselect=function(){t.prototype.deselect.call(this)},e.prototype.restoreState=function(e){t.prototype.restoreState.call(this,e);var i=e;this.x1=i.x1,this.y1=i.y1,this.x2=i.x2,this.y2=i.y2},e.prototype.scale=function(e,i){t.prototype.scale.call(this,e,i),this.x1=this.x1*e,this.y1=this.y1*i,this.x2=this.x2*e,this.y2=this.y2*i,this.adjustVisual()},e}(r),p=function(e){function i(t){var i=e.call(this,t)||this;return i.strokeColor="transparent",i.strokeWidth=0,i.strokeDasharray="",i.setStrokeColor=i.setStrokeColor.bind(i),i.setStrokeWidth=i.setStrokeWidth.bind(i),i.setStrokeDasharray=i.setStrokeDasharray.bind(i),i}return s(i,e),i.prototype.ownsTarget=function(t){return!(!e.prototype.ownsTarget.call(this,t)&&t!==this.visual&&t!==this.selectorLine&&t!==this.visibleLine)},i.prototype.createVisual=function(){this.visual=t.createGroup(),this.selectorLine=t.createLine(this.x1,this.y1,this.x2,this.y2,[["stroke","transparent"],["stroke-width",(this.strokeWidth+10).toString()]]),this.visibleLine=t.createLine(this.x1,this.y1,this.x2,this.y2,[["stroke",this.strokeColor],["stroke-width",this.strokeWidth.toString()]]),this.visual.appendChild(this.selectorLine),this.visual.appendChild(this.visibleLine),this.addMarkerVisualToContainer(this.visual)},i.prototype.pointerDown=function(t,i){e.prototype.pointerDown.call(this,t,i)},i.prototype.adjustVisual=function(){this.selectorLine.setAttribute("x1",this.x1.toString()),this.selectorLine.setAttribute("y1",this.y1.toString()),this.selectorLine.setAttribute("x2",this.x2.toString()),this.selectorLine.setAttribute("y2",this.y2.toString()),this.visibleLine.setAttribute("x1",this.x1.toString()),this.visibleLine.setAttribute("y1",this.y1.toString()),this.visibleLine.setAttribute("x2",this.x2.toString()),this.visibleLine.setAttribute("y2",this.y2.toString()),t.setAttributes(this.visibleLine,[["stroke",this.strokeColor]]),t.setAttributes(this.visibleLine,[["stroke-width",this.strokeWidth.toString()]]),t.setAttributes(this.visibleLine,[["stroke-dasharray",this.strokeDasharray.toString()]])},i.prototype.setStrokeColor=function(t){this.strokeColor=t,this.adjustVisual()},i.prototype.setStrokeWidth=function(t){this.strokeWidth=t,this.adjustVisual()},i.prototype.setStrokeDasharray=function(t){this.strokeDasharray=t,this.adjustVisual()},i.prototype.restoreState=function(t){e.prototype.restoreState.call(this,t);var i=t;this.strokeColor=i.strokeColor,this.strokeWidth=i.strokeWidth,this.strokeDasharray=i.strokeDasharray,this.createVisual(),this.adjustVisual()},i.typeName="LineMarker",i.title="Line marker",i}(l),c=function(e){function i(t){var i=e.call(this,t)||this;return i.color="transparent",i.padding=5,i.text="",i.defaultSize={x:100,y:30},i.setColor=i.setColor.bind(i),i.setFont=i.setFont.bind(i),i.renderText=i.renderText.bind(i),i.sizeText=i.sizeText.bind(i),i.setSize=i.setSize.bind(i),i}return s(i,e),i.prototype.ownsTarget=function(t){if(e.prototype.ownsTarget.call(this,t)||t===this.visual||t===this.textElement||t===this.bgRectangle)return!0;var i=!1;return this.textElement.childNodes.forEach((function(e){e===t&&(i=!0)})),i},i.prototype.createVisual=function(){this.visual=t.createGroup(),this.bgRectangle=t.createRect(1,1,[["fill","transparent"]]),this.visual.appendChild(this.bgRectangle),this.textElement=t.createText([["fill",this.color],["font-family",this.fontFamily],["font-size","16px"],["x","0"],["y","0"]]),this.textElement.transform.baseVal.appendItem(t.createTransform()),this.textElement.transform.baseVal.appendItem(t.createTransform()),this.visual.appendChild(this.textElement),this.addMarkerVisualToContainer(this.visual),this.renderText()},i.prototype.pointerDown=function(t,i){e.prototype.pointerDown.call(this,t,i),this.pointerDownPoint=t},i.prototype.renderText=function(){for(var e=this;this.textElement.lastChild;)this.textElement.removeChild(this.textElement.lastChild);this.text.split(/\r\n|[\n\v\f\r\x85\u2028\u2029]/).forEach((function(i){e.textElement.appendChild(t.createTSpan(""===i.trim()?" ":i.trim(),[["x","0"],["dy","1.2em"]]))})),setTimeout(this.sizeText,10)},i.prototype.getTextScale=function(){var t=this.textElement.getBBox(),e=1;if(t.width>0&&t.height>0){var i=(1*this.width-this.width*this.padding*2/100)/t.width,s=(1*this.height-this.height*this.padding*2/100)/t.height;e=Math.min(i,s)}return e},i.prototype.getTextPosition=function(t){var e=this.textElement.getBBox(),i=0,s=0;return e.width>0&&e.height>0&&(i=(this.width-e.width*t)/2,s=this.height/2-e.height*t/2),{x:i,y:s}},i.prototype.sizeText=function(){var t=this.textElement.getBBox(),e=this.getTextScale(),i=this.getTextPosition(e);i.y-=t.y*e,navigator.userAgent.indexOf("Edge/")>-1?this.textElement.style.transform="translate("+i.x+"px, "+i.y+"px) scale("+e+", "+e+")":(this.textElement.transform.baseVal.getItem(0).setTranslate(i.x,i.y),this.textElement.transform.baseVal.getItem(1).setScale(e,e))},i.prototype.resize=function(t){e.prototype.resize.call(this,t),this.setSize(),this.sizeText()},i.prototype.setSize=function(){e.prototype.setSize.call(this),t.setAttributes(this.visual,[["width",this.width.toString()],["height",this.height.toString()]]),t.setAttributes(this.bgRectangle,[["width",this.width.toString()],["height",this.height.toString()]])},i.prototype.pointerUp=function(t){e.prototype.pointerUp.call(this,t),this.setSize()},i.prototype.deselect=function(){e.prototype.deselect.call(this)},i.prototype.dblClick=function(t,i){e.prototype.dblClick.call(this,t,i)},i.prototype.setColor=function(e){t.setAttributes(this.textElement,[["fill",e]]),this.color=e},i.prototype.setFont=function(e){t.setAttributes(this.textElement,[["font-family",e]]),this.fontFamily=e,this.renderText()},i.prototype.restoreState=function(t){var i=t;this.color=i.color,this.fontFamily=i.fontFamily,this.padding=i.padding,this.text=i.text,this.createVisual(),e.prototype.restoreState.call(this,t),this.setSize()},i.prototype.scale=function(t,i){e.prototype.scale.call(this,t,i),this.setSize(),this.sizeText()},i.typeName="TextMarker",i.title="Text marker",i}(n),u=function(e){function i(t){var i=e.call(this,t)||this;return i.color="transparent",i.lineWidth=3,i}return s(i,e),i.prototype.ownsTarget=function(t){return!(!e.prototype.ownsTarget.call(this,t)&&t!==this.visual&&t!==this.drawingImage)},i.prototype.createVisual=function(){this.visual=t.createGroup(),this.drawingImage=t.createImage(),this.visual.appendChild(this.drawingImage);var e=t.createTransform();this.visual.transform.baseVal.appendItem(e),this.addMarkerVisualToContainer(this.visual)},i.prototype.pointerDown=function(t,i){e.prototype.pointerDown.call(this,t,i)},i.prototype.resize=function(i){e.prototype.resize.call(this,i),t.setAttributes(this.visual,[["width",this.width.toString()],["height",this.height.toString()]]),t.setAttributes(this.drawingImage,[["width",this.width.toString()],["height",this.height.toString()]])},i.prototype.pointerUp=function(t){e.prototype.pointerUp.call(this,t)},i.prototype.select=function(){e.prototype.select.call(this)},i.prototype.deselect=function(){e.prototype.deselect.call(this)},i.prototype.setDrawingImage=function(){t.setAttributes(this.drawingImage,[["width",this.width.toString()],["height",this.height.toString()]]),t.setAttributes(this.drawingImage,[["href",this.drawingImgUrl]]),this.moveVisual({x:this.left,y:this.top})},i.prototype.restoreState=function(t){this.createVisual(),e.prototype.restoreState.call(this,t),this.drawingImgUrl=t.drawingImgUrl,this.setDrawingImage()},i.prototype.scale=function(t,i){e.prototype.scale.call(this,t,i),this.setDrawingImage()},i.typeName="FreehandMarker",i.title="Freehand marker",i}(n),d=function(e){function i(t){var i=e.call(this,t)||this;return i.arrowType="end",i.arrowBaseHeight=10,i.arrowBaseWidth=10,i.getArrowPoints=i.getArrowPoints.bind(i),i.setArrowType=i.setArrowType.bind(i),i}return s(i,e),i.prototype.ownsTarget=function(t){return!(!e.prototype.ownsTarget.call(this,t)&&t!==this.arrow1&&t!==this.arrow2)},i.prototype.getArrowPoints=function(t,e){var i=this.arrowBaseWidth+2*this.strokeWidth,s=this.arrowBaseHeight+2*this.strokeWidth;return t-i/2+","+(e+s/2)+" "+t+","+(e-s/2)+" "+(t+i/2)+","+(e+s/2)},i.prototype.createTips=function(){this.arrow1=t.createPolygon(this.getArrowPoints(this.x1,this.y1),[["fill",this.strokeColor]]),this.arrow1.transform.baseVal.appendItem(t.createTransform()),this.visual.appendChild(this.arrow1),this.arrow2=t.createPolygon(this.getArrowPoints(this.x2,this.y2),[["fill",this.strokeColor]]),this.arrow2.transform.baseVal.appendItem(t.createTransform()),this.visual.appendChild(this.arrow2)},i.prototype.pointerDown=function(t,i){e.prototype.pointerDown.call(this,t,i)},i.prototype.adjustVisual=function(){if(e.prototype.adjustVisual.call(this),this.arrow1&&this.arrow2&&(this.arrow1.style.display="both"===this.arrowType||"start"===this.arrowType?"":"none",this.arrow2.style.display="both"===this.arrowType||"end"===this.arrowType?"":"none",t.setAttributes(this.arrow1,[["points",this.getArrowPoints(this.x1,this.y1)],["fill",this.strokeColor]]),t.setAttributes(this.arrow2,[["points",this.getArrowPoints(this.x2,this.y2)],["fill",this.strokeColor]]),Math.abs(this.x1-this.x2)>.1)){var i=180*Math.atan((this.y2-this.y1)/(this.x2-this.x1))/Math.PI+90*Math.sign(this.x1-this.x2),s=this.arrow1.transform.baseVal.getItem(0);s.setRotate(i,this.x1,this.y1),this.arrow1.transform.baseVal.replaceItem(s,0);var r=this.arrow2.transform.baseVal.getItem(0);r.setRotate(i+180,this.x2,this.y2),this.arrow2.transform.baseVal.replaceItem(r,0)}},i.prototype.setArrowType=function(t){this.arrowType=t,this.adjustVisual()},i.prototype.restoreState=function(t){e.prototype.restoreState.call(this,t);var i=t;this.arrowType=i.arrowType,this.createTips(),this.adjustVisual()},i.typeName="ArrowMarker",i.title="Arrow marker",i}(p),y=function(t){function e(e){var i=t.call(this,e)||this;return i.strokeWidth=0,i}return s(e,t),e.typeName="CoverMarker",e.title="Cover marker",e}(h),g=function(e){function i(t){var i=e.call(this,t)||this;return i.setOpacity=i.setOpacity.bind(i),i.strokeWidth=0,i}return s(i,e),i.prototype.setOpacity=function(e){this.opacity=e,this.visual&&t.setAttributes(this.visual,[["opacity",this.opacity.toString()]])},i.typeName="HighlightMarker",i.title="Highlight marker",i}(y),f=function(e){function i(t){var i=e.call(this,t)||this;return i.bgColor="transparent",i.tipPosition={x:0,y:0},i.tipBase1Position={x:0,y:0},i.tipBase2Position={x:0,y:0},i.defaultSize={x:100,y:30},i.setBgColor=i.setBgColor.bind(i),i.getTipPoints=i.getTipPoints.bind(i),i.positionTip=i.positionTip.bind(i),i.setTipPoints=i.setTipPoints.bind(i),i}return s(i,e),i.prototype.ownsTarget=function(t){return e.prototype.ownsTarget.call(this,t)||this.tip===t},i.prototype.createTip=function(){t.setAttributes(this.bgRectangle,[["fill",this.bgColor],["rx","10px"]]),this.tip=t.createPolygon(this.getTipPoints(),[["fill",this.bgColor]]),this.visual.appendChild(this.tip)},i.prototype.pointerDown=function(t,i){e.prototype.pointerDown.call(this,t,i)},i.prototype.pointerUp=function(t){e.prototype.pointerUp.call(this,t)},i.prototype.setBgColor=function(e){t.setAttributes(this.bgRectangle,[["fill",e]]),t.setAttributes(this.tip,[["fill",e]]),this.bgColor=e},i.prototype.getTipPoints=function(){return this.setTipPoints(),this.tipBase1Position.x+","+this.tipBase1Position.y+" "+this.tipBase2Position.x+","+this.tipBase2Position.y+" "+this.tipPosition.x+","+this.tipPosition.y},i.prototype.setTipPoints=function(t){void 0===t&&(t=!1);var e=Math.min(this.height/2,15),i=this.height/5;t&&(this.tipPosition={x:e+i/2,y:this.height+20});var s=Math.atan(this.height/2/(this.width/2));if(this.tipPosition.x<this.width/2&&this.tipPosition.y<this.height/2)s<Math.atan((this.height/2-this.tipPosition.y)/(this.width/2-this.tipPosition.x))?(i=this.width/5,e=Math.min(this.width/2,15),this.tipBase1Position={x:e,y:0},this.tipBase2Position={x:e+i,y:0}):(this.tipBase1Position={x:0,y:e},this.tipBase2Position={x:0,y:e+i});else if(this.tipPosition.x>=this.width/2&&this.tipPosition.y<this.height/2){s<Math.atan((this.height/2-this.tipPosition.y)/(this.tipPosition.x-this.width/2))?(i=this.width/5,e=Math.min(this.width/2,15),this.tipBase1Position={x:this.width-e-i,y:0},this.tipBase2Position={x:this.width-e,y:0}):(this.tipBase1Position={x:this.width,y:e},this.tipBase2Position={x:this.width,y:e+i})}else if(this.tipPosition.x>=this.width/2&&this.tipPosition.y>=this.height/2){s<Math.atan((this.tipPosition.y-this.height/2)/(this.tipPosition.x-this.width/2))?(i=this.width/5,e=Math.min(this.width/2,15),this.tipBase1Position={x:this.width-e-i,y:this.height},this.tipBase2Position={x:this.width-e,y:this.height}):(this.tipBase1Position={x:this.width,y:this.height-e-i},this.tipBase2Position={x:this.width,y:this.height-e})}else{s<Math.atan((this.tipPosition.y-this.height/2)/(this.width/2-this.tipPosition.x))?(i=this.width/5,e=Math.min(this.width/2,15),this.tipBase1Position={x:e,y:this.height},this.tipBase2Position={x:e+i,y:this.height}):(this.tipBase1Position={x:0,y:this.height-e},this.tipBase2Position={x:0,y:this.height-e-i})}},i.prototype.resize=function(t){e.prototype.resize.call(this,t),this.positionTip()},i.prototype.positionTip=function(){t.setAttributes(this.tip,[["points",this.getTipPoints()]])},i.prototype.select=function(){this.positionTip(),e.prototype.select.call(this)},i.prototype.restoreState=function(t){var i=t;this.bgColor=i.bgColor,this.tipPosition=i.tipPosition,e.prototype.restoreState.call(this,t),this.createTip(),this.setTipPoints()},i.prototype.scale=function(t,i){e.prototype.scale.call(this,t,i),this.tipPosition={x:this.tipPosition.x*t,y:this.tipPosition.y*i},this.positionTip()},i.typeName="CalloutMarker",i.title="Callout marker",i}(c),v=function(e){function i(t){var i=e.call(this,t)||this;return i.fillColor="transparent",i.strokeColor="transparent",i.strokeWidth=0,i.strokeDasharray="",i.opacity=1,i.setStrokeColor=i.setStrokeColor.bind(i),i.setFillColor=i.setFillColor.bind(i),i.setStrokeWidth=i.setStrokeWidth.bind(i),i.setStrokeDasharray=i.setStrokeDasharray.bind(i),i.setOpacity=i.setOpacity.bind(i),i.createVisual=i.createVisual.bind(i),i}return s(i,e),i.prototype.ownsTarget=function(t){return!(!e.prototype.ownsTarget.call(this,t)&&t!==this.visual)},i.prototype.createVisual=function(){this.visual=t.createEllipse(this.width/2,this.height/2,[["fill",this.fillColor],["stroke",this.strokeColor],["stroke-width",this.strokeWidth.toString()],["stroke-dasharray",this.strokeDasharray],["opacity",this.opacity.toString()]]),this.addMarkerVisualToContainer(this.visual)},i.prototype.pointerDown=function(t,i){e.prototype.pointerDown.call(this,t,i)},i.prototype.resize=function(t){e.prototype.resize.call(this,t),this.setSize()},i.prototype.setSize=function(){e.prototype.setSize.call(this),t.setAttributes(this.visual,[["cx",(this.width/2).toString()],["cy",(this.height/2).toString()],["rx",(this.width/2).toString()],["ry",(this.height/2).toString()]])},i.prototype.pointerUp=function(t){e.prototype.pointerUp.call(this,t),this.setSize()},i.prototype.setStrokeColor=function(e){this.strokeColor=e,this.visual&&t.setAttributes(this.visual,[["stroke",this.strokeColor]])},i.prototype.setFillColor=function(e){this.fillColor=e,this.visual&&t.setAttributes(this.visual,[["fill",this.fillColor]])},i.prototype.setStrokeWidth=function(e){this.strokeWidth=e,this.visual&&t.setAttributes(this.visual,[["stroke-width",this.strokeWidth.toString()]])},i.prototype.setStrokeDasharray=function(e){this.strokeDasharray=e,this.visual&&t.setAttributes(this.visual,[["stroke-dasharray",this.strokeDasharray]])},i.prototype.setOpacity=function(e){this.opacity=e,this.visual&&t.setAttributes(this.visual,[["opacity",this.opacity.toString()]])},i.prototype.restoreState=function(t){var i=t;this.fillColor=i.fillColor,this.strokeColor=i.strokeColor,this.strokeWidth=i.strokeWidth,this.strokeDasharray=i.strokeDasharray,this.opacity=i.opacity,this.createVisual(),e.prototype.restoreState.call(this,t),this.setSize()},i.prototype.scale=function(t,i){e.prototype.scale.call(this,t,i),this.setSize()},i.typeName="EllipseMarker",i.title="Ellipse marker",i}(n),m=function(e){function i(t){return e.call(this,t)||this}return s(i,e),Object.defineProperty(i.prototype,"tipLength",{get:function(){return 10+3*this.strokeWidth},enumerable:!1,configurable:!0}),i.prototype.ownsTarget=function(t){return!(!e.prototype.ownsTarget.call(this,t)&&t!==this.tip1&&t!==this.tip2)},i.prototype.createTips=function(){this.tip1=t.createLine(this.x1-this.tipLength/2,this.y1,this.x1+this.tipLength/2,this.y1,[["stroke",this.strokeColor],["stroke-width",this.strokeWidth.toString()]]),this.tip1.transform.baseVal.appendItem(t.createTransform()),this.visual.appendChild(this.tip1),this.tip2=t.createLine(this.x2-this.tipLength/2,this.y2,this.x2+this.tipLength/2,this.y2,[["stroke",this.strokeColor],["stroke-width",this.strokeWidth.toString()]]),this.tip2.transform.baseVal.appendItem(t.createTransform()),this.visual.appendChild(this.tip2)},i.prototype.pointerDown=function(t,i){e.prototype.pointerDown.call(this,t,i)},i.prototype.adjustVisual=function(){if(e.prototype.adjustVisual.call(this),this.tip1&&this.tip2&&(t.setAttributes(this.tip1,[["x1",(this.x1-this.tipLength/2).toString()],["y1",this.y1.toString()],["x2",(this.x1+this.tipLength/2).toString()],["y2",this.y1.toString()],["stroke",this.strokeColor],["stroke-width",this.strokeWidth.toString()]]),t.setAttributes(this.tip2,[["x1",(this.x2-this.tipLength/2).toString()],["y1",this.y2.toString()],["x2",(this.x2+this.tipLength/2).toString()],["y2",this.y2.toString()],["stroke",this.strokeColor],["stroke-width",this.strokeWidth.toString()]]),Math.abs(this.x1-this.x2)>.1)){var i=180*Math.atan((this.y2-this.y1)/(this.x2-this.x1))/Math.PI+90*Math.sign(this.x1-this.x2),s=this.tip1.transform.baseVal.getItem(0);s.setRotate(i,this.x1,this.y1),this.tip1.transform.baseVal.replaceItem(s,0);var r=this.tip2.transform.baseVal.getItem(0);r.setRotate(i+180,this.x2,this.y2),this.tip2.transform.baseVal.replaceItem(r,0)}},i.prototype.restoreState=function(t){e.prototype.restoreState.call(this,t),this.createTips(),this.adjustVisual()},i.typeName="MeasurementMarker",i.title="Measurement marker",i}(p),k=function(t){function e(e){var i=t.call(this,e)||this;return i.fillColor="transparent",i}return s(e,t),e.typeName="EllipseFrameMarker",e.title="Ellipse frame marker",e}(v),w=function(e){function i(t){var i=e.call(this,t)||this;return i.strokeColor="transparent",i.strokeWidth=0,i.strokeDasharray="",i.curveX=0,i.curveY=0,i.setStrokeColor=i.setStrokeColor.bind(i),i.setStrokeWidth=i.setStrokeWidth.bind(i),i.setStrokeDasharray=i.setStrokeDasharray.bind(i),i.adjustVisual=i.adjustVisual.bind(i),i.resize=i.resize.bind(i),i}return s(i,e),i.prototype.ownsTarget=function(t){return!(!e.prototype.ownsTarget.call(this,t)&&t!==this.visual&&t!==this.selectorCurve&&t!==this.visibleCurve)},i.prototype.getPathD=function(){return"M "+this.x1+" "+this.y1+" Q "+this.curveX+" "+this.curveY+", "+this.x2+" "+this.y2},i.prototype.createVisual=function(){this.visual=t.createGroup(),this.selectorCurve=t.createPath(this.getPathD(),[["stroke","transparent"],["stroke-width",(this.strokeWidth+10).toString()],["fill","transparent"]]),this.visibleCurve=t.createPath(this.getPathD(),[["stroke",this.strokeColor],["stroke-width",this.strokeWidth.toString()],["fill","transparent"]]),this.visual.appendChild(this.selectorCurve),this.visual.appendChild(this.visibleCurve),this.addMarkerVisualToContainer(this.visual)},i.prototype.pointerDown=function(t,i){e.prototype.pointerDown.call(this,t,i)},i.prototype.adjustVisual=function(){this.selectorCurve.setAttribute("d",this.getPathD()),this.visibleCurve.setAttribute("d",this.getPathD()),t.setAttributes(this.visibleCurve,[["stroke",this.strokeColor]]),t.setAttributes(this.visibleCurve,[["stroke-width",this.strokeWidth.toString()]]),t.setAttributes(this.visibleCurve,[["stroke-dasharray",this.strokeDasharray.toString()]])},i.prototype.setStrokeColor=function(t){this.strokeColor=t,this.adjustVisual()},i.prototype.setStrokeWidth=function(t){this.strokeWidth=t,this.adjustVisual()},i.prototype.setStrokeDasharray=function(t){this.strokeDasharray=t,this.adjustVisual()},i.prototype.scale=function(t,i){this.curveX=this.curveX*t,this.curveY=this.curveY*i,e.prototype.scale.call(this,t,i)},i.prototype.restoreState=function(t){e.prototype.restoreState.call(this,t);var i=t;this.strokeColor=i.strokeColor,this.strokeWidth=i.strokeWidth,this.strokeDasharray=i.strokeDasharray,this.curveX=i.curveX,this.curveY=i.curveY,this.createVisual(),this.adjustVisual()},i.typeName="CurveMarker",i.title="Curve marker",i}(l),b=function(){function t(t){this._classNamePrefixBase="__markerjslive_",this.classes=[],this.rules=[],this._classNamePrefix=this._classNamePrefixBase+"_"+t+"_"}return Object.defineProperty(t.prototype,"classNamePrefixBase",{get:function(){return this._classNamePrefixBase},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"classNamePrefix",{get:function(){return this._classNamePrefix},enumerable:!1,configurable:!0}),t.prototype.addClass=function(t){return void 0===this.styleSheet&&this.addStyleSheet(),t.name=""+this.classNamePrefix+t.localName,this.classes.push(t),this.styleSheet.sheet.insertRule("."+t.name+" {"+t.style+"}",this.styleSheet.sheet.cssRules.length),t},t.prototype.addRule=function(t){void 0===this.styleSheet&&this.addStyleSheet(),this.rules.push(t),this.styleSheet.sheet.insertRule(t.selector+" {"+t.style+"}",this.styleSheet.sheet.cssRules.length)},t.prototype.addStyleSheet=function(){var t;this.styleSheet=document.createElement("style"),(null!==(t=this.styleSheetRoot)&&void 0!==t?t:document.head).appendChild(this.styleSheet)},t.prototype.removeStyleSheet=function(){var t;this.styleSheet&&((null!==(t=this.styleSheetRoot)&&void 0!==t?t:document.head).removeChild(this.styleSheet),this.styleSheet=void 0)},t}(),x=function(t,e){this.selector=t,this.style=e},S=function(t,e){this.localName=t,this.style=e},C=function(){function t(){this.create=[],this.close=[],this.load=[],this.select=[],this.over=[],this.pointerdown=[],this.pointermove=[],this.pointerup=[],this.pointerenter=[],this.pointerleave=[]}return t.prototype.addEventListener=function(t,e){this[t].push(e)},t.prototype.removeEventListener=function(t,e){var i=this[t].indexOf(e);i>-1&&this[t].splice(i,1)},t}(),P=function(){function i(t){this.touchPoints=0,this.availableMarkerTypes=[a,u,d,c,k,v,g,f,m,y,p,w],this.markers=[],this.isDragging=!1,this._isOpen=!1,this.plugins=[],this.MARKER_CONTAINER_CLASS_SUFFIX="marker-container",this.isPointerIn=!1,this.eventListeners=new C,this._instanceNo=i.instanceCounter++,this.styles=new b(this.instanceNo),this.target=t,this.targetRoot=document.body,this.open=this.open.bind(this),this.setTopLeft=this.setTopLeft.bind(this),this.addNewMarker=this.addNewMarker.bind(this),this.setCurrentMarker=this.setCurrentMarker.bind(this),this.onPointerDown=this.onPointerDown.bind(this),this.onDblClick=this.onDblClick.bind(this),this.onPointerMove=this.onPointerMove.bind(this),this.onPointerUp=this.onPointerUp.bind(this),this.onKeyUp=this.onKeyUp.bind(this),this.close=this.close.bind(this),this.closeUI=this.closeUI.bind(this),this.clientToLocalCoordinates=this.clientToLocalCoordinates.bind(this),this.onWindowResize=this.onWindowResize.bind(this),this.removeMarker=this.removeMarker.bind(this)}return Object.defineProperty(i.prototype,"instanceNo",{get:function(){return this._instanceNo},enumerable:!1,configurable:!0}),Object.defineProperty(i.prototype,"isOpen",{get:function(){return this._isOpen},enumerable:!1,configurable:!0}),i.prototype.open=function(){this.setupResizeObserver(),this.setEditingTarget(),this.setTopLeft(),this.initMarkerCanvas(),this.initOverlay(),this.attachEvents(),e.isLicensed||this.addLogo(),this._isOpen=!0},i.prototype.show=function(t){var e=this;this.showUI(),this.open(),this.plugins.forEach((function(t){return t.init(e)})),this.eventListeners.create.forEach((function(t){return t(e)})),this.restoreState(t),this.eventListeners.load.forEach((function(t){return t(e)}))},i.prototype.close=function(){var t=this;this.isOpen&&(this.coverDiv&&this.closeUI(),this.targetObserver&&this.targetObserver.unobserve(this.target),this._isOpen=!1,this.eventListeners.close.forEach((function(e){return e(t)})))},i.prototype.setupResizeObserver=function(){var t=this;window.ResizeObserver&&(this.targetObserver=new ResizeObserver((function(){t.resize(t.target.clientWidth,t.target.clientHeight)})),this.targetObserver.observe(this.target))},i.prototype.resize=function(t,e){var i=t/this.imageWidth,s=e/this.imageHeight;this.imageWidth=Math.round(t),this.imageHeight=Math.round(e),this.editingTarget.width=this.imageWidth,this.editingTarget.height=this.imageHeight,this.editingTarget.style.width=this.imageWidth+"px",this.editingTarget.style.height=this.imageHeight+"px",this.markerImage.setAttribute("width",this.imageWidth.toString()),this.markerImage.setAttribute("height",this.imageHeight.toString()),this.markerImage.setAttribute("viewBox","0 0 "+this.imageWidth.toString()+" "+this.imageHeight.toString()),this.markerImageHolder.style.width=this.imageWidth+"px",this.markerImageHolder.style.height=this.imageHeight+"px",this.overlayContainer.style.width=this.imageWidth+"px",this.overlayContainer.style.height=this.imageHeight+"px",this.coverDiv.style.width=this.imageWidth.toString()+"px",this.positionLogo(),this.scaleMarkers(i,s)},i.prototype.scaleMarkers=function(t,e){var i;this.currentMarker&&this.currentMarker instanceof c||(i=this.currentMarker,this.setCurrentMarker()),this.markers.forEach((function(i){return i.scale(t,e)})),void 0!==i&&this.setCurrentMarker(i)},i.prototype.setEditingTarget=function(){this.imageWidth=Math.round(this.target.clientWidth),this.imageHeight=Math.round(this.target.clientHeight),this.editingTarget.width=this.imageWidth,this.editingTarget.height=this.imageHeight,this.editingTarget.style.width=this.imageWidth+"px",this.editingTarget.style.height=this.imageHeight+"px"},i.prototype.setTopLeft=function(){var t=this.editingTarget.getBoundingClientRect(),e=this.editorCanvas.getBoundingClientRect();this.left=t.left-e.left,this.top=t.top-e.top},i.prototype.initMarkerCanvas=function(){this.markerImageHolder=document.createElement("div"),this.markerImageHolder.style.setProperty("touch-action","pinch-zoom"),this.markerImage=document.createElementNS("http://www.w3.org/2000/svg","svg"),this.markerImage.setAttribute("xmlns","http://www.w3.org/2000/svg"),this.markerImage.setAttribute("width",this.imageWidth.toString()),this.markerImage.setAttribute("height",this.imageHeight.toString()),this.markerImage.setAttribute("viewBox","0 0 "+this.imageWidth.toString()+" "+this.imageHeight.toString()),this.markerImage.style.pointerEvents="auto",this.markerImageHolder.style.position="absolute",this.markerImageHolder.style.width=this.imageWidth+"px",this.markerImageHolder.style.height=this.imageHeight+"px",this.markerImageHolder.style.transformOrigin="top left",this.positionMarkerImage(),this.defs=t.createDefs(),this.markerImage.appendChild(this.defs),this.markerImageHolder.appendChild(this.markerImage),this.editorCanvas.appendChild(this.markerImageHolder)},i.prototype.initOverlay=function(){this.overlayContainer=document.createElement("div"),this.overlayContainer.style.position="absolute",this.overlayContainer.style.left="0px",this.overlayContainer.style.top="0px",this.overlayContainer.style.width=this.imageWidth+"px",this.overlayContainer.style.height=this.imageHeight+"px",this.overlayContainer.style.display="flex",this.markerImageHolder.appendChild(this.overlayContainer)},i.prototype.positionMarkerImage=function(){this.markerImageHolder.style.top=this.top+"px",this.markerImageHolder.style.left=this.left+"px"},i.prototype.attachEvents=function(){var t=this;this.markerImage.addEventListener("pointerdown",this.onPointerDown),this.markerImage.addEventListener("dblclick",this.onDblClick),window.addEventListener("pointermove",this.onPointerMove),window.addEventListener("pointerup",this.onPointerUp),window.addEventListener("pointercancel",(function(){t.touchPoints>0&&t.touchPoints--})),window.addEventListener("pointerout",(function(){t.touchPoints>0&&t.touchPoints--})),window.addEventListener("pointerleave",this.onPointerUp),window.addEventListener("resize",this.onWindowResize),window.addEventListener("keyup",this.onKeyUp)},i.prototype.addLogo=function(){this.logoUI=document.createElement("div"),this.logoUI.style.display="inline-block",this.logoUI.style.margin="0px",this.logoUI.style.padding="0px",this.logoUI.style.fill="#333333";var t=document.createElement("a");t.href="https://markerjs.com/",t.target="_blank",t.innerHTML='<svg viewBox="0 0 112 96" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414"><path fill="#e5f20d" fill-opacity=".647" d="M0 40.386h111.96V95.62H0z"/><path d="M93.61 61.452c0 .987-.328 1.831-.987 2.53-.657.7-1.52 1.048-2.591 1.048-1.481 0-2.222-.74-2.222-2.22 0-16.617-.533-29.347-1.604-38.192-1.068-8.842-2.92-13.265-5.552-13.265-4.443 0-10.94 15.509-19.497 46.52v.124c0 .987-.328 1.831-.987 2.53-.657.7-1.52 1.048-2.592 1.048-1.48 0-2.22-.74-2.22-2.22 0-3.29.165-8.392.493-15.302.33-7.732.494-13.82.494-18.262 0-6.17-.186-10.55-.556-13.142-.37-2.591-1.172-3.887-2.406-3.887-2.796 0-6.333 5.12-10.612 15.363C38.494 34.367 34.01 46.44 29.32 60.34l-1.11 3.209a5.714 5.714 0 01-1.42 2.097c-.617.578-1.295.864-2.036.864-.987 0-1.644-.081-1.974-.247-.328-.162-.533-.656-.617-1.48-.41-4.03-.74-9.418-.987-16.165-.163-1.728-.329-4.566-.494-8.515-.822-13.901-1.562-23.3-2.221-28.196-.657-4.893-.987-7.628-.987-8.205 0-.657.33-1.44.987-2.345.659-.903 1.276-1.357 1.85-1.357 1.319 0 2.387.947 3.21 2.838.411.906.863 4.526 1.357 10.859.493 6.335.905 14.19 1.233 23.568l.617 18.88c4.527-13.983 9.216-26.673 14.068-38.068C45.65 6.686 50.093.988 54.123.988c2.715 0 4.566 1.974 5.553 5.923.987 3.949 1.481 9.667 1.481 17.152 0 3.949-.081 9.625-.247 17.029l-.123 5.676c3.373-11.762 6.725-21.634 10.057-29.615 3.331-7.979 6.685-11.97 10.056-11.97 8.475 0 12.71 18.757 12.71 56.269z" fill-rule="nonzero"/></svg>',t.title="Powered by marker.js",t.style.display="grid",t.style.alignItems="center",t.style.justifyItems="center",t.style.padding="3px",t.style.width="20px",t.style.height="20px",this.logoUI.appendChild(t),this.editorCanvas.appendChild(this.logoUI),this.logoUI.style.position="absolute",this.logoUI.style.pointerEvents="all",this.positionLogo()},i.prototype.positionLogo=function(){this.logoUI&&(this.logoUI.style.left=this.markerImageHolder.offsetLeft+10+"px",this.logoUI.style.top=this.markerImageHolder.offsetTop+this.markerImageHolder.offsetHeight-this.logoUI.clientHeight-10+"px")},i.prototype.showUI=function(){this.coverDiv=document.createElement("div"),this.coverDiv.className=this.styles.classNamePrefixBase+" "+this.styles.classNamePrefix,this.coverDiv.style.fontSize="16px",this.coverDiv.style.userSelect="none",this.coverDiv.style.position="absolute",this.coverDiv.style.top=this.target.offsetTop.toString()+"px",this.coverDiv.style.left=this.target.offsetLeft.toString()+"px",this.coverDiv.style.width=this.target.offsetWidth.toString()+"px",this.coverDiv.style.zIndex="5",this.targetRoot.appendChild(this.coverDiv),this.uiDiv=document.createElement("div"),this.uiDiv.style.display="flex",this.uiDiv.style.flexDirection="column",this.uiDiv.style.flexGrow="2",this.uiDiv.style.margin="0px",this.uiDiv.style.border="0px",this.coverDiv.appendChild(this.uiDiv),this.contentDiv=document.createElement("div"),this.contentDiv.style.display="flex",this.contentDiv.style.flexDirection="row",this.contentDiv.style.flexGrow="2",this.contentDiv.style.flexShrink="1",this.uiDiv.appendChild(this.contentDiv),this.editorCanvas=document.createElement("div"),this.editorCanvas.style.flexGrow="2",this.editorCanvas.style.flexShrink="1",this.editorCanvas.style.position="relative",this.editorCanvas.style.overflow="hidden",this.editorCanvas.style.display="flex",this.editorCanvas.style.pointerEvents="none",this.contentDiv.appendChild(this.editorCanvas),this.editingTarget=document.createElement("canvas"),this.editorCanvas.appendChild(this.editingTarget)},i.prototype.closeUI=function(){this.targetRoot.removeChild(this.coverDiv)},i.prototype.removeMarker=function(t){this.markerImage.removeChild(t.container),this.markers.indexOf(t)>-1&&this.markers.splice(this.markers.indexOf(t),1),t.dispose()},i.prototype.restoreState=function(t){var e=this;for(this.markers.splice(0);this.markerImage.lastChild;)this.markerImage.removeChild(this.markerImage.lastChild);t.markers.forEach((function(t){var i=e.availableMarkerTypes.find((function(e){return e.typeName===t.typeName}));if(void 0!==i){var s=e.addNewMarker(i);s.restoreState(t),e.markers.push(s)}})),t.width&&t.height&&(t.width!==this.imageWidth||t.height!==this.imageHeight)&&this.scaleMarkers(this.imageWidth/t.width,this.imageHeight/t.height)},i.prototype.addNewMarker=function(e){var i=t.createGroup();return i.setAttribute("class",""+this.styles.classNamePrefix+this.MARKER_CONTAINER_CLASS_SUFFIX),this.markerImage.appendChild(i),new e(i)},i.prototype.setCurrentMarker=function(t){var e=this,i=this.currentMarker!==t;void 0!==this.currentMarker&&this.currentMarker.deselect(),this.currentMarker=t,void 0!==this.currentMarker&&this.currentMarker.select(),i&&this.eventListeners.select.forEach((function(i){return i(e,t)}))},i.prototype.onPointerDown=function(t){var e=this;if(this.touchPoints++,1===this.touchPoints||"touch"!==t.pointerType){var i=this.markers.find((function(e){return e.ownsTarget(t.target)}));void 0!==i?(this.setCurrentMarker(i),this.isDragging=!0,this.currentMarker.pointerDown(this.clientToLocalCoordinates(t.clientX,t.clientY),t.target)):this.setCurrentMarker(),this.eventListeners.pointerdown.length>0&&this.eventListeners.pointerdown.forEach((function(s){return s(e,t,i)}))}},i.prototype.onDblClick=function(t){var e=this.markers.find((function(e){return e.ownsTarget(t.target)}));void 0!==e&&e!==this.currentMarker&&this.setCurrentMarker(e),void 0!==this.currentMarker?this.currentMarker.dblClick(this.clientToLocalCoordinates(t.clientX,t.clientY),t.target):this.setCurrentMarker()},i.prototype.onPointerMove=function(t){var e=this;if(1!==this.touchPoints&&"touch"===t.pointerType||(void 0!==this.currentMarker||this.isDragging)&&t.preventDefault(),this.eventListeners.over.length>0||this.eventListeners.pointermove.length>0){var i=this.markers.find((function(e){return e.ownsTarget(t.target)}));i!==this.hoveredMarker&&(this.hoveredMarker=i,this.eventListeners.over.forEach((function(t){return t(e,e.hoveredMarker)}))),this.eventListeners.pointermove.forEach((function(s){return s(e,t,i)})),this.isPointerIn||void 0===i&&this.markerImage!==t.target||(this.isPointerIn=!0,this.eventListeners.pointerenter.forEach((function(s){return s(e,t,i)}))),this.isPointerIn&&void 0===i&&this.markerImage!==t.target&&(this.isPointerIn=!1,this.eventListeners.pointerleave.forEach((function(s){return s(e,t,i)})))}},i.prototype.onPointerUp=function(t){var e=this;if(this.touchPoints>0&&this.touchPoints--,0===this.touchPoints&&this.isDragging&&void 0!==this.currentMarker&&this.currentMarker.pointerUp(this.clientToLocalCoordinates(t.clientX,t.clientY)),this.isDragging=!1,this.eventListeners.pointerup.length>0){var i=this.markers.find((function(e){return e.ownsTarget(t.target)}));this.eventListeners.pointerup.forEach((function(s){return s(e,t,i)}))}},i.prototype.onKeyUp=function(t){void 0===this.currentMarker||"Delete"!==t.key&&"Backspace"!==t.key||(this.removeMarker(this.currentMarker),this.setCurrentMarker(),this.markerImage.style.cursor="default")},i.prototype.clientToLocalCoordinates=function(t,e){var i=this.markerImage.getBoundingClientRect();return{x:t-i.left,y:e-i.top}},i.prototype.onWindowResize=function(){this.positionUI()},i.prototype.positionUI=function(){this.setTopLeft(),this.coverDiv.style.top=this.target.offsetTop.toString()+"px",this.coverDiv.style.left=this.target.offsetLeft.toString()+"px",this.positionMarkerImage(),this.positionLogo()},i.prototype.addEventListener=function(t,e){this.eventListeners.addEventListener(t,e)},i.prototype.removeEventListener=function(t,e){this.eventListeners.removeEventListener(t,e)},i.prototype.addPlugin=function(t){this.plugins.push(t)},i.prototype.removePlugin=function(t){var e=this.plugins.indexOf(t);e>=0&&this.plugins.splice(e,1)},i.instanceCounter=0,i}();export{e as Activator,d as ArrowMarker,f as CalloutMarker,y as CoverMarker,w as CurveMarker,k as EllipseFrameMarker,v as EllipseMarker,C as EventListenerRepository,a as FrameMarker,u as FreehandMarker,g as HighlightMarker,p as LineMarker,l as LinearMarkerBase,r as MarkerBase,P as MarkerView,m as MeasurementMarker,h as RectangleMarker,n as RectangularBoxMarkerBase,S as StyleClass,b as StyleManager,x as StyleRule,t as SvgHelper,c as TextMarker,o as TransformMatrix};
+//# sourceMappingURL=markerjs-live.esm.js.map
diff --git a/capsule-prototype/js/libs/markerjslive/markerjs-live.esm.js.map b/capsule-prototype/js/libs/markerjslive/markerjs-live.esm.js.map
new file mode 100644
index 0000000000000000000000000000000000000000..d3c0fc108248a035d0231ef4d5d3c571be9a6754
--- /dev/null
+++ b/capsule-prototype/js/libs/markerjslive/markerjs-live.esm.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"markerjs-live.esm.js","sources":["../src/core/SvgHelper.ts","../src/core/Activator.ts","../node_modules/tslib/tslib.es6.js","../src/core/MarkerBase.ts","../src/core/TransformMatrix.ts","../src/markers/RectangularBoxMarkerBase.ts","../src/markers/RectangleMarker.ts","../src/markers/frame-marker/FrameMarker.ts","../src/markers/LinearMarkerBase.ts","../src/markers/line-marker/LineMarker.ts","../src/markers/text-marker/TextMarker.ts","../src/markers/freehand-marker/FreehandMarker.ts","../src/markers/arrow-marker/ArrowMarker.ts","../src/markers/cover-marker/CoverMarker.ts","../src/markers/highlight-marker/HighlightMarker.ts","../src/markers/callout-marker/CalloutMarker.ts","../src/markers/ellipse-marker/EllipseMarker.ts","../src/markers/measurement-marker/MeasurementMarker.ts","../src/markers/ellipse-frame-marker/EllipseFrameMarker.ts","../src/markers/curve-marker/CurveMarker.ts","../src/core/Style.ts","../src/core/Events.ts","../src/MarkerView.ts"],"sourcesContent":["/**\n * Utility class to simplify SVG operations.\n */\nexport class SvgHelper {\n  /**\n   * Creates SVG \"defs\".\n   */\n  public static createDefs(): SVGDefsElement {\n    const defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');\n\n    return defs;\n  }\n\n  /**\n   * Creates SVG stylesheet.\n   */\n  public static createStylesheet(): SVGStyleElement {\n    const stylesheet = document.createElementNS('http://www.w3.org/2000/svg', 'style');\n    stylesheet.setAttribute('type', 'text/css');\n\n    return stylesheet;\n  }\n\n  /**\n   * Sets attributes on an arbitrary SVG element\n   * @param el - target SVG element.\n   * @param attributes - set of name-value attribute pairs.\n   */\n  public static setAttributes(\n    el: SVGElement,\n    attributes: Array<[string, string]>\n  ): void {\n    for (const [attr, value] of attributes) {\n      el.setAttribute(attr, value);\n    }\n  }\n\n  /**\n   * Creates an SVG rectangle with the specified width and height.\n   * @param width \n   * @param height \n   * @param attributes - additional attributes.\n   */\n  public static createRect(\n    width: number | string,\n    height: number | string,\n    attributes?: Array<[string, string]>\n  ): SVGRectElement {\n    const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');\n\n    rect.setAttribute('width', width.toString());\n    rect.setAttribute('height', height.toString());\n    if (attributes) {\n      SvgHelper.setAttributes(rect, attributes);\n    }\n\n    return rect;\n  }\n\n  /**\n   * Creates an SVG line with specified end-point coordinates.\n   * @param x1 \n   * @param y1 \n   * @param x2 \n   * @param y2 \n   * @param attributes - additional attributes.\n   */\n  public static createLine(\n    x1: number | string,\n    y1: number | string,\n    x2: number | string,\n    y2: number | string,\n    attributes?: Array<[string, string]>\n  ): SVGLineElement {\n    const line = document.createElementNS('http://www.w3.org/2000/svg', 'line');\n\n    line.setAttribute('x1', x1.toString());\n    line.setAttribute('y1', y1.toString());\n    line.setAttribute('x2', x2.toString());\n    line.setAttribute('y2', y2.toString());\n    if (attributes) {\n      SvgHelper.setAttributes(line, attributes);\n    }\n\n    return line;\n  }\n\n  /**\n   * Creates an SVG polygon with specified points.\n   * @param points - points as string.\n   * @param attributes - additional attributes.\n   */\n  public static createPolygon(\n    points: string,\n    attributes?: Array<[string, string]>\n  ): SVGPolygonElement {\n    const polygon = document.createElementNS(\n      'http://www.w3.org/2000/svg',\n      'polygon'\n    );\n\n    polygon.setAttribute('points', points);\n    if (attributes) {\n      SvgHelper.setAttributes(polygon, attributes);\n    }\n\n    return polygon;\n  }\n\n  /**\n   * Creates an SVG circle with the specified radius.\n   * @param radius \n   * @param attributes - additional attributes.\n   */\n  public static createCircle(\n    radius: number,\n    attributes?: Array<[string, string]>\n  ): SVGCircleElement {\n    const circle = document.createElementNS(\n      'http://www.w3.org/2000/svg',\n      'circle'\n    );\n\n    circle.setAttribute('cx', (radius / 2).toString());\n    circle.setAttribute('cy', (radius / 2).toString());\n    circle.setAttribute('r', radius.toString());\n    if (attributes) {\n      SvgHelper.setAttributes(circle, attributes);\n    }\n\n    return circle;\n  }\n\n  /**\n   * Creates an SVG ellipse with the specified horizontal and vertical radii.\n   * @param rx \n   * @param ry \n   * @param attributes - additional attributes.\n   */\n  public static createEllipse(\n    rx: number,\n    ry: number,\n    attributes?: Array<[string, string]>\n  ): SVGEllipseElement {\n    const ellipse = document.createElementNS(\n      'http://www.w3.org/2000/svg',\n      'ellipse'\n    );\n\n    ellipse.setAttribute('cx', (rx / 2).toString());\n    ellipse.setAttribute('cy', (ry / 2).toString());\n    ellipse.setAttribute('rx', (rx / 2).toString());\n    ellipse.setAttribute('ry', (ry / 2).toString());\n    if (attributes) {\n      SvgHelper.setAttributes(ellipse, attributes);\n    }\n\n    return ellipse;\n  }\n\n  /**\n   * Creates an SVG group.\n   * @param attributes - additional attributes.\n   */\n  public static createGroup(attributes?: Array<[string, string]>): SVGGElement {\n    const g = document.createElementNS('http://www.w3.org/2000/svg', 'g');\n    if (attributes) {\n      SvgHelper.setAttributes(g, attributes);\n    }\n    return g;\n  }\n\n  /**\n   * Creates an SVG transform.\n   */\n  public static createTransform(): SVGTransform {\n    const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n\n    return svg.createSVGTransform();\n  }\n\n  /**\n   * Creates an SVG marker.\n   * @param id \n   * @param orient \n   * @param markerWidth \n   * @param markerHeight \n   * @param refX \n   * @param refY \n   * @param markerElement \n   */\n  public static createMarker(\n    id: string,\n    orient: string,\n    markerWidth: number | string,\n    markerHeight: number | string,\n    refX: number | string,\n    refY: number | string,\n    markerElement: SVGGraphicsElement\n  ): SVGMarkerElement {\n    const marker = document.createElementNS(\n      'http://www.w3.org/2000/svg',\n      'marker'\n    );\n    SvgHelper.setAttributes(marker, [\n      ['id', id],\n      ['orient', orient],\n      ['markerWidth', markerWidth.toString()],\n      ['markerHeight', markerHeight.toString()],\n      ['refX', refX.toString()],\n      ['refY', refY.toString()],\n    ]);\n\n    marker.appendChild(markerElement);\n\n    return marker;\n  }\n\n  /**\n   * Creaes an SVG text element.\n   * @param attributes - additional attributes.\n   */\n  public static createText(\n    attributes?: Array<[string, string]>\n  ): SVGTextElement {\n    const text = document.createElementNS('http://www.w3.org/2000/svg', 'text');\n    text.setAttribute('x', '0');\n    text.setAttribute('y', '0');\n\n    if (attributes) {\n      SvgHelper.setAttributes(text, attributes);\n    }\n\n    return text;\n  }\n\n  /**\n   * Creates an SVG TSpan.\n   * @param text - inner text.\n   * @param attributes - additional attributes.\n   */\n  public static createTSpan(\n    text: string,\n    attributes?: Array<[string, string]>\n  ): SVGTSpanElement {\n    const tspan = document.createElementNS(\n      'http://www.w3.org/2000/svg',\n      'tspan'\n    );\n    tspan.textContent = text;\n\n    if (attributes) {\n      SvgHelper.setAttributes(tspan, attributes);\n    }\n\n    return tspan;\n  }\n\n  /**\n   * Creates an SVG image element.\n   * @param attributes - additional attributes.\n   */\n  public static createImage(\n    attributes?: Array<[string, string]>\n  ): SVGImageElement {\n    const image = document.createElementNS(\n      'http://www.w3.org/2000/svg',\n      'image'\n    );\n\n    if (attributes) {\n      SvgHelper.setAttributes(image, attributes);\n    }\n\n    return image;\n  }\n\n  /**\n   * Creates an SVG point with the specified coordinates.\n   * @param x \n   * @param y \n   */\n  public static createPoint(      \n    x: number,\n    y: number\n  ): SVGPoint {\n      const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n      const svgPoint = svg.createSVGPoint();\n      svgPoint.x = x;\n      svgPoint.y = y;\n  \n      return svgPoint;\n  }\n\n  /**\n   * Creates an SVG path with the specified shape (d).\n   * @param d - path shape\n   * @param attributes - additional attributes.\n   */\n   public static createPath(\n    d: string,\n    attributes?: Array<[string, string]>\n  ): SVGPathElement {\n    const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');\n\n    path.setAttribute('d', d);\n    if (attributes) {\n      SvgHelper.setAttributes(path, attributes);\n    }\n\n    return path;\n  }\n}\n","/**\n * Manages commercial marker.js Live licenses.\n */\nexport class Activator {\n  private static key: string;\n\n  /**\n   * Add a license key\n   * @param key license key sent to you after purchase.\n   */\n  public static addKey(key: string): void {\n    Activator.key = key;\n  }\n\n  /**\n   * Returns true if the copy of marker.js Live is commercially licensed.\n   */\n  public static get isLicensed(): boolean {\n    // NOTE:\n    // before removing or modifying this please consider supporting marker.js\n    // by visiting https://markerjs.com/ for details\n    // thank you!\n    if (Activator.key) {\n      const keyRegex = new RegExp(/^MJSL-[A-Z][0-9]{3}-[A-Z][0-9]{3}-[0-9]{4}$/, 'i');\n      return keyRegex.test(Activator.key);\n    } else {\n      return false;\n    }\n  }\n}\n","/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n    extendStatics = Object.setPrototypeOf ||\r\n        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n        function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n    return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n    extendStatics(d, b);\r\n    function __() { this.constructor = d; }\r\n    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n    __assign = Object.assign || function __assign(t) {\r\n        for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n            s = arguments[i];\r\n            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n        }\r\n        return t;\r\n    }\r\n    return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n    var t = {};\r\n    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n        t[p] = s[p];\r\n    if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n            if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n                t[p[i]] = s[p[i]];\r\n        }\r\n    return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n    if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n    return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n    return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n    if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n    return new (P || (P = Promise))(function (resolve, reject) {\r\n        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n        function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n        step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n    });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n    return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n    function verb(n) { return function (v) { return step([n, v]); }; }\r\n    function step(op) {\r\n        if (f) throw new TypeError(\"Generator is already executing.\");\r\n        while (_) try {\r\n            if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n            if (y = 0, t) op = [op[0] & 2, t.value];\r\n            switch (op[0]) {\r\n                case 0: case 1: t = op; break;\r\n                case 4: _.label++; return { value: op[1], done: false };\r\n                case 5: _.label++; y = op[1]; op = [0]; continue;\r\n                case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n                default:\r\n                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n                    if (t[2]) _.ops.pop();\r\n                    _.trys.pop(); continue;\r\n            }\r\n            op = body.call(thisArg, _);\r\n        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n    }\r\n}\r\n\r\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\r\n    if (k2 === undefined) k2 = k;\r\n    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\r\n}) : (function(o, m, k, k2) {\r\n    if (k2 === undefined) k2 = k;\r\n    o[k2] = m[k];\r\n});\r\n\r\nexport function __exportStar(m, o) {\r\n    for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n}\r\n\r\nexport function __values(o) {\r\n    var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n    if (m) return m.call(o);\r\n    if (o && typeof o.length === \"number\") return {\r\n        next: function () {\r\n            if (o && i >= o.length) o = void 0;\r\n            return { value: o && o[i++], done: !o };\r\n        }\r\n    };\r\n    throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n    var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n    if (!m) return o;\r\n    var i = m.call(o), r, ar = [], e;\r\n    try {\r\n        while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n    }\r\n    catch (error) { e = { error: error }; }\r\n    finally {\r\n        try {\r\n            if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n        }\r\n        finally { if (e) throw e.error; }\r\n    }\r\n    return ar;\r\n}\r\n\r\nexport function __spread() {\r\n    for (var ar = [], i = 0; i < arguments.length; i++)\r\n        ar = ar.concat(__read(arguments[i]));\r\n    return ar;\r\n}\r\n\r\nexport function __spreadArrays() {\r\n    for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n    for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n        for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n            r[k] = a[j];\r\n    return r;\r\n};\r\n\r\nexport function __await(v) {\r\n    return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n    if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n    var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n    return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n    function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n    function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n    function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n    function fulfill(value) { resume(\"next\", value); }\r\n    function reject(value) { resume(\"throw\", value); }\r\n    function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n    var i, p;\r\n    return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n    function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n    if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n    var m = o[Symbol.asyncIterator], i;\r\n    return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n    function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n    function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n    if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n    return cooked;\r\n};\r\n\r\nvar __setModuleDefault = Object.create ? (function(o, v) {\r\n    Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n    o[\"default\"] = v;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n    if (mod && mod.__esModule) return mod;\r\n    var result = {};\r\n    if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n    __setModuleDefault(result, mod);\r\n    return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n    return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, privateMap) {\r\n    if (!privateMap.has(receiver)) {\r\n        throw new TypeError(\"attempted to get private field on non-instance\");\r\n    }\r\n    return privateMap.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, privateMap, value) {\r\n    if (!privateMap.has(receiver)) {\r\n        throw new TypeError(\"attempted to set private field on non-instance\");\r\n    }\r\n    privateMap.set(receiver, value);\r\n    return value;\r\n}\r\n","import { SvgHelper } from './SvgHelper';\nimport { IPoint } from './IPoint';\nimport { MarkerBaseState } from './MarkerBaseState';\n\n/**\n * Base class for all available and custom marker types.\n * \n * All markers used with marker.js Live should be descendants of this class.\n */\nexport class MarkerBase {\n  /**\n   * String type name of the marker type. \n   * \n   * Used when adding {@link MarkerView.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static typeName = 'MarkerBase';\n\n  protected _outerContainer: SVGGElement;\n  /**\n   * Outer SVG group container not manipulated or transformed by the marker itself in any way\n   */\n  public get outerContainer(): SVGGElement {\n    return this._outerContainer;\n  }\n\n  protected _container: SVGGElement;\n  /**\n   * SVG container object holding the marker's visual.\n   */\n  public get container(): SVGGElement {\n    return this._container;\n  }\n\n  /**\n   * Additional information about the marker\n   */\n  public notes?: string;\n\n  /**\n   * Marker type title (display name) used for accessibility and other attributes.\n   */\n  public static title: string;\n\n  /**\n   * Method called when marker creation is finished.\n   */\n  public onMarkerCreated: (marker: MarkerBase) => void;\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   */\n  constructor(container: SVGGElement) {\n    this._outerContainer = container;\n    const innerContainer = SvgHelper.createGroup();\n    this._outerContainer.appendChild(innerContainer);\n    this._container = innerContainer;\n  }\n\n  /**\n   * Returns true if passed SVG element belongs to the marker. False otherwise.\n   * \n   * @param el - target element.\n   */\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars\n  public ownsTarget(el: EventTarget): boolean {\n    return false;\n  }\n\n  /**\n   * Selects this marker.\n   */\n  // eslint-disable-next-line @typescript-eslint/no-empty-function\n  public select(): void {}\n\n  /**\n   * Deselects this marker.\n   */\n  // eslint-disable-next-line @typescript-eslint/no-empty-function\n  public deselect(): void {}\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) down event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function\n  public pointerDown(point: IPoint, target?: EventTarget):void {}\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) double click event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function\n  public dblClick(point: IPoint, target?: EventTarget):void {}\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) up event.\n   * \n   * @param point - event coordinates.\n   */\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function\n  public pointerUp(point: IPoint):void {}\n\n  /**\n   * Disposes the marker and clean's up.\n   */\n  // eslint-disable-next-line @typescript-eslint/no-empty-function\n  public dispose(): void {}\n\n  /**\n   * Adds marker's root visual element to the container group.\n   * @param element - marker's visual element.\n   */\n  protected addMarkerVisualToContainer(element: SVGElement): void {\n    if (this.container.childNodes.length > 0) {\n      this.container.insertBefore(element, this.container.childNodes[0]);\n    } else {\n      this.container.appendChild(element);\n    }\n  }\n\n  /**\n   * Restores previously saved marker state.\n   * \n   * @param state - previously saved state.\n   */\n  public restoreState(state: MarkerBaseState): void {\n    this.notes = state.notes;\n  }\n\n  /**\n   * Scales marker. Used after the image resize.\n   * \n   * @param scaleX - horizontal scale\n   * @param scaleY - vertical scale\n   */\n  // eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars\n  public scale(scaleX: number, scaleY: number): void {}\n}\n","/**\n * Represents a simplified version of the SVGMatrix.\n */\nexport interface ITransformMatrix {\n  a: number;\n  b: number;\n  c: number;\n  d: number;\n  e: number;\n  f: number;\n}\n\n/**\n * A utility class to transform between SVGMatrix and its simplified representation.\n */\nexport class TransformMatrix {\n  public static toITransformMatrix(matrix: SVGMatrix): ITransformMatrix {\n    return {\n      a: matrix.a,\n      b: matrix.b,\n      c: matrix.c,\n      d: matrix.d,\n      e: matrix.e,\n      f: matrix.f\n    }\n  }\n  public static toSVGMatrix(currentMatrix: SVGMatrix, newMatrix: ITransformMatrix): SVGMatrix {\n    currentMatrix.a = newMatrix.a;\n    currentMatrix.b = newMatrix.b;\n    currentMatrix.c = newMatrix.c;\n    currentMatrix.d = newMatrix.d;\n    currentMatrix.e = newMatrix.e;\n    currentMatrix.f = newMatrix.f;\n    return currentMatrix;\n  }\n}","import { MarkerBase } from '../core/MarkerBase';\n\nimport { IPoint } from '../core/IPoint';\nimport { SvgHelper } from '../core/SvgHelper';\n\nimport { RectangularBoxMarkerBaseState } from './RectangularBoxMarkerBaseState';\nimport { MarkerBaseState } from '../core/MarkerBaseState';\nimport { TransformMatrix } from '../core/TransformMatrix';\n\n/**\n * RectangularBoxMarkerBase is a base class for all marker's with rectangular controls such as all rectangle markers,\n * text and callout markers.\n * \n * It creates and manages the rectangular control box and related resize, move, and rotate manipulations.\n */\nexport class RectangularBoxMarkerBase extends MarkerBase {\n  /**\n   * x coordinate of the top-left corner.\n   */\n  protected left = 0;\n  /**\n   * y coordinate of the top-left corner.\n   */\n  protected top = 0;\n  /**\n   * Marker width.\n   */\n  protected width = 0;\n  /**\n   * Marker height.\n   */\n  protected height = 0;\n\n  /**\n   * The default marker size when the marker is created with a click (without dragging).\n   */\n  protected defaultSize: IPoint = {x: 50, y: 20};\n\n  /**\n   * x coordinate of the top-left corner at the start of manipulation.\n   */\n  protected manipulationStartLeft: number;\n  /**\n   * y coordinate of the top-left corner at the start of manipulation.\n   */\n  protected manipulationStartTop: number;\n  /**\n   * Width at the start of manipulation.\n   */\n  protected manipulationStartWidth: number;\n  /**\n   * Height at the start of manipulation.\n   */\n  protected manipulationStartHeight: number;\n\n  /**\n   * x coordinate of the pointer at the start of manipulation.\n   */\n  protected manipulationStartX: number;\n  /**\n   * y coordinate of the pointer at the start of manipulation.\n   */\n  protected manipulationStartY: number;\n\n  /**\n   * Pointer's horizontal distance from the top left corner.\n   */\n  protected offsetX = 0;\n  /**\n   * Pointer's vertical distance from the top left corner.\n   */\n  protected offsetY = 0;\n\n  /**\n   * Marker's rotation angle.\n   */\n  protected rotationAngle = 0;\n\n  /**\n   * x coordinate of the marker's center.\n   */\n  protected get centerX(): number {\n    return this.left + this.width / 2;\n  }\n  /**\n   * y coordinate of the marker's center.\n   */\n  protected get centerY(): number {\n    return this.top + this.height / 2;\n  }\n\n  private _visual: SVGGraphicsElement;\n  /**\n   * Container for the marker's visual.\n   */\n  protected get visual(): SVGGraphicsElement {\n    return this._visual;\n  }\n  protected set visual(value: SVGGraphicsElement) {\n    this._visual = value;\n    const translate = SvgHelper.createTransform();\n    this._visual.transform.baseVal.appendItem(translate);\n  }\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   */\n  constructor(container: SVGGElement) {\n    super(container);\n\n    // add rotation transform\n    this.container.transform.baseVal.appendItem(SvgHelper.createTransform());\n  }\n\n  /**\n   * Returns true if passed SVG element belongs to the marker. False otherwise.\n   * \n   * @param el - target element.\n   */\n  public ownsTarget(el: EventTarget): boolean {\n    if (super.ownsTarget(el)) {\n      return true;\n    } else {\n      return false;\n    }\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) down event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerDown(point: IPoint, target?: EventTarget): void {\n    super.pointerDown(point, target);\n\n    this.select();\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) up event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerUp(point: IPoint): void {\n    super.pointerUp(point);\n  }\n\n  /**\n   * Moves visual to the specified coordinates.\n   * @param point - coordinates of the new top-left corner of the visual.\n   */\n  protected moveVisual(point: IPoint): void {\n    this.visual.style.transform = `translate(${point.x}px, ${point.y}px)`;\n    // const translate = this.visual.transform.baseVal.getItem(0);\n    // translate.setTranslate(point.x, point.y);\n    // this.visual.transform.baseVal.replaceItem(translate, 0);\n  }\n\n  /**\n   * Resizes the marker based on pointer coordinates and context.\n   * @param point - pointer coordinates.\n   */\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars\n  protected resize(point: IPoint): void {\n    this.setSize();\n  }\n\n  /**\n   * Sets control box size and location.\n   */\n  protected setSize(): void {\n    this.moveVisual({x: this.left, y: this.top});\n  }\n\n  private rotate(point: IPoint) {\n    // avoid glitch when crossing the 0 rotation point\n    if (Math.abs(point.x - this.centerX) > 0.1) {\n      const sign = Math.sign(point.x - this.centerX);\n      this.rotationAngle =\n        (Math.atan((point.y - this.centerY) / (point.x - this.centerX)) * 180) /\n          Math.PI +\n        90 * sign;\n      this.applyRotation();\n    }\n  }\n\n  private applyRotation() {\n    const rotate = this.container.transform.baseVal.getItem(0);\n    rotate.setRotate(this.rotationAngle, this.centerX, this.centerY);\n    this.container.transform.baseVal.replaceItem(rotate, 0);\n  }\n\n  /**\n   * Returns point coordinates based on the actual screen coordinates and marker's rotation.\n   * @param point - original pointer coordinates\n   */\n  protected rotatePoint(point: IPoint): IPoint {\n    if (this.rotationAngle === 0) {\n      return point;\n    }\n    \n    const matrix = this.container.getCTM();\n    let svgPoint = SvgHelper.createPoint(point.x, point.y);\n    svgPoint = svgPoint.matrixTransform(matrix);\n\n    const result = { x: svgPoint.x, y: svgPoint.y };\n\n    return result;\n  }\n\n  /**\n   * Returns original point coordinates based on coordinates with rotation applied.\n   * @param point - rotated point coordinates.\n   */\n  protected unrotatePoint(point: IPoint): IPoint {\n    if (this.rotationAngle === 0) {\n      return point;\n    }\n    \n    let matrix = this.container.getCTM();\n    matrix = matrix.inverse();\n    let svgPoint = SvgHelper.createPoint(point.x, point.y);\n    svgPoint = svgPoint.matrixTransform(matrix);\n\n    const result = { x: svgPoint.x, y: svgPoint.y };\n\n    return result;\n  }\n\n  /**\n   * Displays marker's controls.\n   */\n  public select(): void {\n    super.select();\n  }\n\n  /**\n   * Hides marker's controls.\n   */\n  public deselect(): void {\n    super.deselect();\n  }\n\n  /**\n   * Restores marker's state to the previously saved one.\n   * @param state - previously saved state.\n   */\n  public restoreState(state: MarkerBaseState): void {\n    super.restoreState(state);\n    const rbmState = state as RectangularBoxMarkerBaseState;\n    this.left = rbmState.left;\n    this.top = rbmState.top;\n    this.width = rbmState.width;\n    this.height = rbmState.height;\n    this.rotationAngle = rbmState.rotationAngle;\n    this.visual.transform.baseVal.getItem(0).setMatrix(\n      TransformMatrix.toSVGMatrix(this.visual.transform.baseVal.getItem(0).matrix, rbmState.visualTransformMatrix)\n    );\n    this.container.transform.baseVal.getItem(0).setMatrix(\n      TransformMatrix.toSVGMatrix(this.container.transform.baseVal.getItem(0).matrix, rbmState.containerTransformMatrix)\n    );\n    // this.moveVisual({x: this.left, y: this.top});\n    // this.applyRotation();\n  }\n\n  /**\n   * Scales marker. Used after the image resize.\n   * \n   * @param scaleX - horizontal scale\n   * @param scaleY - vertical scale\n   */\n  public scale(scaleX: number, scaleY: number): void {\n    super.scale(scaleX, scaleY);\n\n    const rPoint = this.rotatePoint({x: this.left, y: this.top});\n    const point = this.unrotatePoint({x: rPoint.x * scaleX, y: rPoint.y * scaleY});\n\n    this.left = point.x;\n    this.top = point.y;\n    this.width = this.width * scaleX;\n    this.height = this.height * scaleY;\n  }\n\n}\n","import { IPoint } from '../core/IPoint';\nimport { SvgHelper } from '../core/SvgHelper';\nimport { RectangularBoxMarkerBase } from './RectangularBoxMarkerBase';\nimport { RectangleMarkerState } from './RectangleMarkerState';\nimport { MarkerBaseState } from '../core/MarkerBaseState';\n\n/**\n * RecatngleMarker is a base class for all rectangular markers (Frame, Cover, Highlight, etc.)\n */\nexport abstract class RectangleMarker extends RectangularBoxMarkerBase {\n  /**\n   * String type name of the marker type. \n   * \n   * Used when adding {@link MarkerView.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static title = 'Rectangle marker';\n\n  /**\n   * Recangle fill color.\n   */\n  protected fillColor = 'transparent';\n  /**\n   * Rectangle stroke color.\n   */\n  protected strokeColor = 'transparent';\n  /**\n   * Rectangle border stroke width.\n   */\n  protected strokeWidth = 0;\n  /**\n   * Rectangle border stroke dash array.\n   */\n  protected strokeDasharray = '';\n  /**\n   * Rectangle opacity (alpha). 0 to 1.\n   */\n  protected opacity = 1;\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   */\n  constructor(container: SVGGElement) {\n    super(container);\n\n    this.setStrokeColor = this.setStrokeColor.bind(this);\n    this.setFillColor = this.setFillColor.bind(this);\n    this.setStrokeWidth = this.setStrokeWidth.bind(this);\n    this.setStrokeDasharray = this.setStrokeDasharray.bind(this);\n    this.createVisual = this.createVisual.bind(this);\n  }\n\n  /**\n   * Returns true if passed SVG element belongs to the marker. False otherwise.\n   * \n   * @param el - target element.\n   */\n  public ownsTarget(el: EventTarget): boolean {\n    if (super.ownsTarget(el) || el === this.visual) {\n      return true;\n    } else {\n      return false;\n    }\n  }\n\n  /**\n   * Creates the marker's rectangle visual.\n   */\n  protected createVisual(): void {\n    this.visual = SvgHelper.createRect(1, 1, [\n      ['fill', this.fillColor],\n      ['stroke', this.strokeColor],\n      ['stroke-width', this.strokeWidth.toString()],\n      ['stroke-dasharray', this.strokeDasharray],\n      ['opacity', this.opacity.toString()]\n    ]);\n    this.addMarkerVisualToContainer(this.visual);\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) down event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerDown(point: IPoint, target?: EventTarget): void {\n    super.pointerDown(point, target);\n  }\n\n  /**\n   * Resizes the marker based on the pointer coordinates.\n   * @param point - current pointer coordinates.\n   */\n  protected resize(point: IPoint): void {\n    super.resize(point);\n    this.setSize();\n  }\n\n  /**\n   * Sets visual's width and height attributes based on marker's width and height.\n   */\n  protected setSize(): void {\n    super.setSize();\n    SvgHelper.setAttributes(this.visual, [\n      ['width', this.width.toString()],\n      ['height', this.height.toString()],\n    ]);\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) up event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerUp(point: IPoint): void {\n    super.pointerUp(point);\n    this.setSize();\n  }\n\n  /**\n   * Sets rectangle's border stroke color.\n   * @param color - color as string\n   */\n  protected setStrokeColor(color: string): void {\n    this.strokeColor = color;\n    if (this.visual) {\n      SvgHelper.setAttributes(this.visual, [['stroke', this.strokeColor]]);\n    }\n  }\n  /**\n   * Sets rectangle's fill color.\n   * @param color - color as string\n   */\n  protected setFillColor(color: string): void {\n    this.fillColor = color;\n    if (this.visual) {\n      SvgHelper.setAttributes(this.visual, [['fill', this.fillColor]]);\n    }\n  }\n  /**\n   * Sets rectangle's border stroke (line) width.\n   * @param color - color as string\n   */\n  protected setStrokeWidth(width: number): void {\n    this.strokeWidth = width;\n    if (this.visual) {\n      SvgHelper.setAttributes(this.visual, [['stroke-width', this.strokeWidth.toString()]]);\n    }\n  }\n  /**\n   * Sets rectangle's border stroke dash array.\n   * @param color - color as string\n   */\n  protected setStrokeDasharray(dashes: string): void {\n    this.strokeDasharray = dashes;\n    if (this.visual) {\n      SvgHelper.setAttributes(this.visual, [['stroke-dasharray', this.strokeDasharray]]);\n    }\n  }\n\n  /**\n   * Restores previously saved marker state.\n   * \n   * @param state - previously saved state.\n   */\n  public restoreState(state: MarkerBaseState): void {\n    const rectState = state as RectangleMarkerState;\n    this.fillColor = rectState.fillColor;\n    this.strokeColor = rectState.strokeColor;\n    this.strokeWidth = rectState.strokeWidth;\n    this.strokeDasharray = rectState.strokeDasharray;\n    this.opacity = rectState.opacity;\n\n    this.createVisual();\n    super.restoreState(state);\n    this.setSize();\n  }\n\n  /**\n   * Scales marker. Used after the image resize.\n   * \n   * @param scaleX - horizontal scale\n   * @param scaleY - vertical scale\n   */\n  public scale(scaleX: number, scaleY: number): void {\n    super.scale(scaleX, scaleY);\n\n    this.setSize();\n  }\n}\n","import { RectangleMarker } from '../RectangleMarker';\n\nexport class FrameMarker extends RectangleMarker {\n  /**\n   * String type name of the marker type. \n   * \n   * Used when adding {@link MarkerView.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static typeName = 'FrameMarker';\n  \n  /**\n   * Marker type title (display name) used for accessibility and other attributes.\n   */\n  public static title = 'Frame marker';\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   */\n  constructor(container: SVGGElement) {\n    super(container);\n  }\n}\n","import { MarkerBase } from '../core/MarkerBase';\n\nimport { IPoint } from '../core/IPoint';\n\nimport { LinearMarkerBaseState } from './LinearMarkerBaseState';\nimport { MarkerBaseState } from '../core/MarkerBaseState';\n\n/**\n * LinearMarkerBase is a base class for all line-type markers (Line, Arrow, Measurement Tool, etc.).\n */\nexport class LinearMarkerBase extends MarkerBase {\n  /**\n   * x coordinate of the first end-point\n   */\n  protected x1 = 0;\n  /**\n   * y coordinate of the first end-point\n   */\n  protected y1 = 0;\n  /**\n   * x coordinate of the second end-point\n   */\n  protected x2 = 0;\n  /**\n   * y coordinate of the second end-point\n   */\n  protected y2 = 0;\n\n  /**\n   * Default line length when marker is created with a simple click (without dragging).\n   */\n  protected defaultLength = 50;\n\n  /**\n   * Marker's main visual.\n   */\n  protected visual: SVGGraphicsElement;\n\n  /**\n   * Creates a LineMarkerBase object.\n   * \n   * @param container - SVG container to hold marker's visual.\n   */\n  constructor(container: SVGGElement) {\n    super(container);\n  }\n\n  /**\n   * Returns true if passed SVG element belongs to the marker. False otherwise.\n   * \n   * @param el - target element.\n   */\n  public ownsTarget(el: EventTarget): boolean {\n    if (super.ownsTarget(el)) {\n      return true;\n    } else {\n      return false;\n    }\n  }\n\n  \n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) down event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerDown(point: IPoint, target?: EventTarget): void {\n    super.pointerDown(point, target);\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) up event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerUp(point: IPoint): void {\n    super.pointerUp(point);\n  }\n\n  /**\n   * When implemented adjusts marker visual after manipulation when needed.\n   */\n  // eslint-disable-next-line @typescript-eslint/no-empty-function\n  protected adjustVisual(): void {}\n\n  /**\n   * Resizes the line marker.\n   * @param point - current manipulation coordinates.\n   */\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars\n  protected resize(point: IPoint): void {\n    this.adjustVisual();\n  }\n\n  /**\n   * Displays marker's controls.\n   */\n  public select(): void {\n    super.select();\n  }\n\n  /**\n   * Hides marker's controls.\n   */\n  public deselect(): void {\n    super.deselect();\n  }\n\n  /**\n   * Restores marker's state to the previously saved one.\n   * @param state - previously saved state.\n   */\n  public restoreState(state: MarkerBaseState): void {\n    super.restoreState(state);\n    const lmbState = state as LinearMarkerBaseState;\n    this.x1 = lmbState.x1;\n    this.y1 = lmbState.y1;\n    this.x2 = lmbState.x2;\n    this.y2 = lmbState.y2;\n  }\n\n  /**\n   * Scales marker. Used after the image resize.\n   * \n   * @param scaleX - horizontal scale\n   * @param scaleY - vertical scale\n   */\n  public scale(scaleX: number, scaleY: number): void {\n    super.scale(scaleX, scaleY);\n\n    this.x1 = this.x1 * scaleX;\n    this.y1 = this.y1 * scaleY;\n    this.x2 = this.x2 * scaleX;\n    this.y2 = this.y2 * scaleY;\n\n    this.adjustVisual();\n  }\n}\n","import { IPoint } from '../../core/IPoint';\nimport { SvgHelper } from '../../core/SvgHelper';\nimport { LinearMarkerBase } from '../LinearMarkerBase';\nimport { LineMarkerState } from './LineMarkerState';\nimport { MarkerBaseState } from '../../core/MarkerBaseState';\n\nexport class LineMarker extends LinearMarkerBase {\n  /**\n   * String type name of the marker type. \n   * \n   * Used when adding {@link MarkerView.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static typeName = 'LineMarker';\n  \n  /**\n   * Marker type title (display name) used for accessibility and other attributes.\n   */\n  public static title = 'Line marker';\n\n  /**\n   * Invisible wider line to make selection easier/possible.\n   */\n  protected selectorLine: SVGLineElement;\n  /**\n   * Visible marker line.\n   */\n  protected visibleLine: SVGLineElement;\n\n  /**\n   * Line color.\n   */\n  protected strokeColor = 'transparent';\n  /**\n   * Line width.\n   */\n  protected strokeWidth = 0;\n  /**\n   * Line dash array.\n   */\n  protected strokeDasharray = '';\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   */\n  constructor(container: SVGGElement) {\n    super(container);\n\n    this.setStrokeColor = this.setStrokeColor.bind(this);\n    this.setStrokeWidth = this.setStrokeWidth.bind(this);\n    this.setStrokeDasharray = this.setStrokeDasharray.bind(this);\n  }\n\n  /**\n   * Returns true if passed SVG element belongs to the marker. False otherwise.\n   * \n   * @param el - target element.\n   */\n  public ownsTarget(el: EventTarget): boolean {\n    if (\n      super.ownsTarget(el) ||\n      el === this.visual ||\n      el === this.selectorLine ||\n      el === this.visibleLine\n    ) {\n      return true;\n    } else {\n      return false;\n    }\n  }\n\n  private createVisual() {\n    this.visual = SvgHelper.createGroup();\n    this.selectorLine = SvgHelper.createLine(\n      this.x1,\n      this.y1,\n      this.x2,\n      this.y2,\n      [\n        ['stroke', 'transparent'],\n        ['stroke-width', (this.strokeWidth + 10).toString()],\n      ]\n    );\n    this.visibleLine = SvgHelper.createLine(\n      this.x1,\n      this.y1,\n      this.x2,\n      this.y2,\n      [\n        ['stroke', this.strokeColor],\n        ['stroke-width', this.strokeWidth.toString()],\n      ]\n    );\n    this.visual.appendChild(this.selectorLine);\n    this.visual.appendChild(this.visibleLine);\n\n    this.addMarkerVisualToContainer(this.visual);\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) down event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerDown(point: IPoint, target?: EventTarget): void {\n    super.pointerDown(point, target);\n  }\n\n  /**\n   * Adjusts visual after manipulation.\n   */\n  protected adjustVisual(): void {\n    this.selectorLine.setAttribute('x1', this.x1.toString());\n    this.selectorLine.setAttribute('y1', this.y1.toString());\n    this.selectorLine.setAttribute('x2', this.x2.toString());\n    this.selectorLine.setAttribute('y2', this.y2.toString());\n\n    this.visibleLine.setAttribute('x1', this.x1.toString());\n    this.visibleLine.setAttribute('y1', this.y1.toString());\n    this.visibleLine.setAttribute('x2', this.x2.toString());\n    this.visibleLine.setAttribute('y2', this.y2.toString());\n\n    SvgHelper.setAttributes(this.visibleLine, [['stroke', this.strokeColor]]);\n    SvgHelper.setAttributes(this.visibleLine, [['stroke-width', this.strokeWidth.toString()]]);\n    SvgHelper.setAttributes(this.visibleLine, [['stroke-dasharray', this.strokeDasharray.toString()]]);\n  }\n\n  /**\n   * Sets line color.\n   * @param color - new color.\n   */\n  protected setStrokeColor(color: string): void {\n    this.strokeColor = color;\n    this.adjustVisual();\n  }\n  /**\n   * Sets line width.\n   * @param width - new width.\n   */\n  protected setStrokeWidth(width: number): void {\n    this.strokeWidth = width\n    this.adjustVisual();\n  }\n\n  /**\n   * Sets line dash array.\n   * @param dashes - new dash array.\n   */\n  protected setStrokeDasharray(dashes: string): void {\n    this.strokeDasharray = dashes;\n    this.adjustVisual();\n  }\n\n  /**\n   * Restores previously saved marker state.\n   * \n   * @param state - previously saved state.\n   */\n  public restoreState(state: MarkerBaseState): void {\n    super.restoreState(state);\n\n    const lmState = state as LineMarkerState;\n    this.strokeColor = lmState.strokeColor;\n    this.strokeWidth = lmState.strokeWidth;\n    this.strokeDasharray = lmState.strokeDasharray;\n\n    this.createVisual();\n    this.adjustVisual();\n  }\n}\n","import { IPoint } from '../../core/IPoint';\nimport { SvgHelper } from '../../core/SvgHelper';\nimport { RectangularBoxMarkerBase } from '../RectangularBoxMarkerBase';\nimport { TextMarkerState } from './TextMarkerState';\nimport { MarkerBaseState } from '../../core/MarkerBaseState';\n\nexport class TextMarker extends RectangularBoxMarkerBase {\n  /**\n   * String type name of the marker type.\n   *\n   * Used when adding {@link MarkerView.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static typeName = 'TextMarker';\n\n  /**\n   * Marker type title (display name) used for accessibility and other attributes.\n   */\n  public static title = 'Text marker';\n\n  /**\n   * Text color.\n   */\n  protected color = 'transparent';\n  /**\n   * Text's font family.\n   */\n  protected fontFamily: string;\n  /**\n   * Padding inside of the marker's bounding box in percents.\n   */\n  protected padding = 5;\n\n  private text = '';\n  /**\n   * Visual text element.\n   */\n  protected textElement: SVGTextElement;\n  /**\n   * Text background rectangle.\n   */\n  protected bgRectangle: SVGRectElement;\n\n  private pointerDownPoint: IPoint;\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   */\n  constructor(container: SVGGElement) {\n    super(container);\n\n    this.defaultSize = { x: 100, y: 30 };\n\n    this.setColor = this.setColor.bind(this);\n    this.setFont = this.setFont.bind(this);\n    this.renderText = this.renderText.bind(this);\n    this.sizeText = this.sizeText.bind(this);\n    this.setSize = this.setSize.bind(this);\n  }\n\n  /**\n   * Returns true if passed SVG element belongs to the marker. False otherwise.\n   *\n   * @param el - target element.\n   */\n  public ownsTarget(el: EventTarget): boolean {\n    if (\n      super.ownsTarget(el) ||\n      el === this.visual ||\n      el === this.textElement ||\n      el === this.bgRectangle\n    ) {\n      return true;\n    } else {\n      let found = false;\n      this.textElement.childNodes.forEach((span) => {\n        if (span === el) {\n          found = true;\n        }\n      });\n      return found;\n    }\n  }\n\n  /**\n   * Creates text marker visual.\n   */\n  protected createVisual(): void {\n    this.visual = SvgHelper.createGroup();\n\n    this.bgRectangle = SvgHelper.createRect(1, 1, [['fill', 'transparent']]);\n    this.visual.appendChild(this.bgRectangle);\n\n    this.textElement = SvgHelper.createText([\n      ['fill', this.color],\n      ['font-family', this.fontFamily],\n      ['font-size', '16px'],\n      ['x', '0'],\n      ['y', '0'],\n    ]);\n    this.textElement.transform.baseVal.appendItem(SvgHelper.createTransform()); // translate transorm\n    this.textElement.transform.baseVal.appendItem(SvgHelper.createTransform()); // scale transorm\n\n    this.visual.appendChild(this.textElement);\n\n    this.addMarkerVisualToContainer(this.visual);\n    this.renderText();\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) down event.\n   *\n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerDown(point: IPoint, target?: EventTarget): void {\n    super.pointerDown(point, target);\n\n    this.pointerDownPoint = point;\n  }\n\n  private renderText() {\n    const LINE_SIZE = '1.2em';\n\n    while (this.textElement.lastChild) {\n      this.textElement.removeChild(this.textElement.lastChild);\n    }\n\n    const lines = this.text.split(/\\r\\n|[\\n\\v\\f\\r\\x85\\u2028\\u2029]/);\n    lines.forEach((line) => {\n      this.textElement.appendChild(\n        SvgHelper.createTSpan(\n          // workaround for swallowed empty lines\n          line.trim() === '' ? ' ' : line.trim(),\n          [\n            ['x', '0'],\n            ['dy', LINE_SIZE],\n          ]\n        )\n      );\n    });\n\n    setTimeout(this.sizeText, 10);\n  }\n\n  private getTextScale(): number {\n    const textSize = this.textElement.getBBox();\n    let scale = 1.0;\n    if (textSize.width > 0 && textSize.height > 0) {\n      const xScale =\n        (this.width * 1.0 - (this.width * this.padding * 2) / 100) /\n        textSize.width;\n      const yScale =\n        (this.height * 1.0 - (this.height * this.padding * 2) / 100) /\n        textSize.height;\n      scale = Math.min(xScale, yScale);\n    }\n    return scale;\n  }\n\n  private getTextPosition(scale: number): IPoint {\n    const textSize = this.textElement.getBBox();\n    let x = 0;\n    let y = 0;\n    if (textSize.width > 0 && textSize.height > 0) {\n      x = (this.width - textSize.width * scale) / 2;\n      y = this.height / 2 - (textSize.height * scale) / 2;\n    }\n    return { x: x, y: y };\n  }\n\n  private sizeText() {\n    const textBBox = this.textElement.getBBox();\n    const scale = this.getTextScale();\n    const position = this.getTextPosition(scale);\n    position.y -= textBBox.y * scale; // workaround adjustment for text not being placed at y=0\n\n    if (navigator.userAgent.indexOf('Edge/') > -1) {\n      // workaround for legacy Edge as transforms don't work otherwise but this way it doesn't work in Safari\n      this.textElement.style.transform = `translate(${position.x}px, ${position.y}px) scale(${scale}, ${scale})`;\n    } else {\n      this.textElement.transform.baseVal\n        .getItem(0)\n        .setTranslate(position.x, position.y);\n      this.textElement.transform.baseVal.getItem(1).setScale(scale, scale);\n    }\n  }\n\n  /**\n   * Resize marker based on current pointer coordinates and context.\n   * @param point\n   */\n  protected resize(point: IPoint): void {\n    super.resize(point);\n    this.setSize();\n    this.sizeText();\n  }\n\n  /**\n   * Sets size of marker elements after manipulation.\n   */\n  protected setSize(): void {\n    super.setSize();\n    SvgHelper.setAttributes(this.visual, [\n      ['width', this.width.toString()],\n      ['height', this.height.toString()],\n    ]);\n    SvgHelper.setAttributes(this.bgRectangle, [\n      ['width', this.width.toString()],\n      ['height', this.height.toString()],\n    ]);\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) up event.\n   *\n   * @param point - event coordinates.\n   */\n  public pointerUp(point: IPoint): void {\n    super.pointerUp(point);\n    this.setSize();\n  }\n\n  /**\n   * Deselects this marker, renders text (if necessary), and hides selected marker UI.\n   */\n  public deselect(): void {\n    super.deselect();\n  }\n\n  /**\n   * Opens text editor on double-click.\n   * @param point\n   * @param target\n   */\n  public dblClick(point: IPoint, target?: EventTarget): void {\n    super.dblClick(point, target);\n  }\n\n  /**\n   * Sets text color.\n   * @param color - new text color.\n   */\n  protected setColor(color: string): void {\n    SvgHelper.setAttributes(this.textElement, [['fill', color]]);\n    this.color = color;\n  }\n\n  /**\n   * Sets font family.\n   * @param font - new font family.\n   */\n  protected setFont(font: string): void {\n    SvgHelper.setAttributes(this.textElement, [['font-family', font]]);\n    this.fontFamily = font;\n    this.renderText();\n  }\n\n  /**\n   * Restores previously saved marker state.\n   *\n   * @param state - previously saved state.\n   */\n  public restoreState(state: MarkerBaseState): void {\n    const textState = state as TextMarkerState;\n    this.color = textState.color;\n    this.fontFamily = textState.fontFamily;\n    this.padding = textState.padding;\n    this.text = textState.text;\n\n    this.createVisual();\n    super.restoreState(state);\n    this.setSize();\n  }\n\n  /**\n   * Scales marker. Used after the image resize.\n   *\n   * @param scaleX - horizontal scale\n   * @param scaleY - vertical scale\n   */\n  public scale(scaleX: number, scaleY: number): void {\n    super.scale(scaleX, scaleY);\n\n    this.setSize();\n    this.sizeText();\n  }\n}\n","import { IPoint } from '../../core/IPoint';\nimport { SvgHelper } from '../../core/SvgHelper';\nimport { RectangularBoxMarkerBase } from '../RectangularBoxMarkerBase';\nimport { FreehandMarkerState } from './FreehandMarkerState';\nimport { MarkerBaseState } from '../../core/MarkerBaseState';\n\nexport class FreehandMarker extends RectangularBoxMarkerBase {\n  /**\n   * String type name of the marker type.\n   *\n   * Used when adding {@link MarkerView.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static typeName = 'FreehandMarker';\n\n  /**\n   * Marker type title (display name) used for accessibility and other attributes.\n   */\n  public static title = 'Freehand marker';\n\n  /**\n   * Marker color.\n   */\n  protected color = 'transparent';\n  /**\n   * Marker's stroke width.\n   */\n  protected lineWidth = 3;\n\n  private drawingImage: SVGImageElement;\n  private drawingImgUrl: string;\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   */\n  constructor(container: SVGGElement) {\n    super(container);\n  }\n\n  /**\n   * Returns true if passed SVG element belongs to the marker. False otherwise.\n   *\n   * @param el - target element.\n   */\n  public ownsTarget(el: EventTarget): boolean {\n    if (\n      super.ownsTarget(el) ||\n      el === this.visual ||\n      el === this.drawingImage\n    ) {\n      return true;\n    } else {\n      return false;\n    }\n  }\n\n  private createVisual() {\n    this.visual = SvgHelper.createGroup();\n    this.drawingImage = SvgHelper.createImage();\n    this.visual.appendChild(this.drawingImage);\n\n    const translate = SvgHelper.createTransform();\n    this.visual.transform.baseVal.appendItem(translate);\n    this.addMarkerVisualToContainer(this.visual);\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) down event.\n   *\n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerDown(point: IPoint, target?: EventTarget): void {\n    super.pointerDown(point, target);\n  }\n\n  /**\n   * Resize marker based on current pointer coordinates and context.\n   * @param point\n   */\n  protected resize(point: IPoint): void {\n    super.resize(point);\n    SvgHelper.setAttributes(this.visual, [\n      ['width', this.width.toString()],\n      ['height', this.height.toString()],\n    ]);\n    SvgHelper.setAttributes(this.drawingImage, [\n      ['width', this.width.toString()],\n      ['height', this.height.toString()],\n    ]);\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) up event.\n   *\n   * @param point - event coordinates.\n   */\n  public pointerUp(point: IPoint): void {\n    super.pointerUp(point);\n  }\n\n  /**\n   * Selects this marker and displays appropriate selected marker UI.\n   */\n  public select(): void {\n    super.select();\n  }\n\n  /**\n   * Deselects this marker and hides selected marker UI.\n   */\n  public deselect(): void {\n    super.deselect();\n  }\n\n  private setDrawingImage() {\n    SvgHelper.setAttributes(this.drawingImage, [\n      ['width', this.width.toString()],\n      ['height', this.height.toString()],\n    ]);\n    SvgHelper.setAttributes(this.drawingImage, [['href', this.drawingImgUrl]]);\n    this.moveVisual({ x: this.left, y: this.top });\n  }\n\n  /**\n   * Restores previously saved marker state.\n   *\n   * @param state - previously saved state.\n   */\n  public restoreState(state: MarkerBaseState): void {\n    this.createVisual();\n    super.restoreState(state);\n    this.drawingImgUrl = (state as FreehandMarkerState).drawingImgUrl;\n    this.setDrawingImage();\n  }\n\n  /**\n   * Scales marker. Used after the image resize.\n   *\n   * @param scaleX - horizontal scale\n   * @param scaleY - vertical scale\n   */\n  public scale(scaleX: number, scaleY: number): void {\n    super.scale(scaleX, scaleY);\n\n    this.setDrawingImage();\n  }\n}\n","import { IPoint } from '../../core/IPoint';\nimport { SvgHelper } from '../../core/SvgHelper';\nimport { LineMarker } from '../line-marker/LineMarker';\nimport { ArrowMarkerState, ArrowType } from './ArrowMarkerState';\nimport { MarkerBaseState } from '../../core/MarkerBaseState';\n\n/**\n * Represents an arrow marker.\n */\nexport class ArrowMarker extends LineMarker {\n  /**\n   * String type name of the marker type. \n   * \n   * Used when adding {@link MarkerView.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static typeName = 'ArrowMarker';\n\n  /**\n   * Marker type title (display name) used for accessibility and other attributes.\n   */\n  public static title = 'Arrow marker';\n\n  private arrow1: SVGPolygonElement;\n  private arrow2: SVGPolygonElement;\n\n  private arrowType: ArrowType = 'end';\n\n  private arrowBaseHeight = 10;\n  private arrowBaseWidth = 10;\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   */\n  constructor(container: SVGGElement) {\n    super(container);\n\n    this.getArrowPoints = this.getArrowPoints.bind(this);\n    this.setArrowType = this.setArrowType.bind(this);\n  }\n\n  /**\n   * Returns true if passed SVG element belongs to the marker. False otherwise.\n   * \n   * @param el - target element.\n   */\n  public ownsTarget(el: EventTarget): boolean {\n    if (\n      super.ownsTarget(el) ||\n      el === this.arrow1 || el === this.arrow2\n    ) {\n      return true;\n    } else {\n      return false;\n    }\n  }\n\n  private getArrowPoints(offsetX: number, offsetY: number): string {\n    const width = this.arrowBaseWidth + this.strokeWidth * 2;\n    const height = this.arrowBaseHeight + this.strokeWidth * 2;\n    return `${offsetX - width / 2},${\n      offsetY + height / 2\n    } ${offsetX},${offsetY - height / 2} ${\n      offsetX + width / 2},${offsetY + height / 2}`;\n  }\n\n  private createTips() {\n    this.arrow1 = SvgHelper.createPolygon(this.getArrowPoints(this.x1, this.y1), [['fill', this.strokeColor]]);\n    this.arrow1.transform.baseVal.appendItem(SvgHelper.createTransform());\n    this.visual.appendChild(this.arrow1);\n\n    this.arrow2 = SvgHelper.createPolygon(this.getArrowPoints(this.x2, this.y2), [['fill', this.strokeColor]]);\n    this.arrow2.transform.baseVal.appendItem(SvgHelper.createTransform());\n    this.visual.appendChild(this.arrow2);\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) down event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerDown(point: IPoint, target?: EventTarget): void {\n    super.pointerDown(point, target);\n  }\n\n  /**\n   * Adjusts marker visual after manipulation.\n   */\n  protected adjustVisual(): void {\n    super.adjustVisual();\n\n    if (this.arrow1 && this.arrow2) {\n      this.arrow1.style.display = (this.arrowType === 'both' || this.arrowType === 'start') ? '' : 'none';\n      this.arrow2.style.display = (this.arrowType === 'both' || this.arrowType === 'end') ? '' : 'none';\n\n      SvgHelper.setAttributes(this.arrow1, [\n        ['points', this.getArrowPoints(this.x1, this.y1)],\n        ['fill', this.strokeColor]\n      ]);\n      SvgHelper.setAttributes(this.arrow2, [\n        ['points', this.getArrowPoints(this.x2, this.y2)],\n        ['fill', this.strokeColor]\n      ]);\n\n      if (Math.abs(this.x1 - this.x2) > 0.1) {\n        const lineAngle1 =\n          (Math.atan((this.y2 - this.y1) / (this.x2 - this.x1)) * 180) / Math.PI + 90 * Math.sign(this.x1 - this.x2);\n\n        const a1transform = this.arrow1.transform.baseVal.getItem(0);\n        a1transform.setRotate(lineAngle1, this.x1, this.y1);\n        this.arrow1.transform.baseVal.replaceItem(a1transform, 0);\n\n        const a2transform = this.arrow2.transform.baseVal.getItem(0);\n        a2transform.setRotate(lineAngle1 + 180, this.x2, this.y2);\n        this.arrow2.transform.baseVal.replaceItem(a2transform, 0);\n      }\n    }\n  }\n\n  private setArrowType(arrowType: ArrowType) {\n    this.arrowType = arrowType;\n    this.adjustVisual();\n  }\n\n  /**\n   * Restores previously saved marker state.\n   * \n   * @param state - previously saved state.\n   */\n  public restoreState(state: MarkerBaseState): void {\n    super.restoreState(state);\n\n    const amState = state as ArrowMarkerState;\n    this.arrowType = amState.arrowType;\n\n    this.createTips();\n    this.adjustVisual();\n  }\n\n}\n","import { RectangleMarker } from '../RectangleMarker';\n\nexport class CoverMarker extends RectangleMarker {\n  /**\n   * String type name of the marker type. \n   * \n   * Used when adding {@link MarkerView.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static typeName = 'CoverMarker';\n\n  /**\n   * Marker type title (display name) used for accessibility and other attributes.\n   */\n  public static title = 'Cover marker';\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   */\n  constructor(container: SVGGElement) {\n    super(container);\n\n    this.strokeWidth = 0;\n  }\n}\n","import { CoverMarker } from '../cover-marker/CoverMarker';\nimport { SvgHelper } from '../../core/SvgHelper';\n\nexport class HighlightMarker extends CoverMarker {\n  /**\n   * String type name of the marker type. \n   * \n   * Used when adding {@link MarkerView.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static typeName = 'HighlightMarker';\n  /**\n   * Marker type title (display name) used for accessibility and other attributes.\n   */\n  public static title = 'Highlight marker';\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   */\n  constructor(container: SVGGElement) {\n    super(container);\n\n    this.setOpacity = this.setOpacity.bind(this);\n\n    this.strokeWidth = 0;\n  }\n\n  /**\n   * Sets marker's opacity (0..1).\n   * @param opacity - new opacity value.\n   */\n  protected setOpacity(opacity: number): void {\n    this.opacity = opacity;\n    if (this.visual) {\n      SvgHelper.setAttributes(this.visual, [['opacity', this.opacity.toString()]]);\n    }\n  }\n}\n","import { IPoint } from '../../core/IPoint';\nimport { SvgHelper } from '../../core/SvgHelper';\nimport { TextMarker } from '../text-marker/TextMarker';\nimport { CalloutMarkerState } from './CalloutMarkerState';\nimport { MarkerBaseState } from '../../core/MarkerBaseState';\n\nexport class CalloutMarker extends TextMarker {\n  /**\n   * String type name of the marker type.\n   *\n   * Used when adding {@link MarkerView.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static typeName = 'CalloutMarker';\n\n  /**\n   * Marker type title (display name) used for accessibility and other attributes.\n   */\n  public static title = 'Callout marker';\n\n  private bgColor = 'transparent';\n\n  private tipPosition: IPoint = { x: 0, y: 0 };\n  private tipBase1Position: IPoint = { x: 0, y: 0 };\n  private tipBase2Position: IPoint = { x: 0, y: 0 };\n  private tip: SVGPolygonElement;\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   */\n  constructor(container: SVGGElement) {\n    super(container);\n\n    this.defaultSize = { x: 100, y: 30 };\n\n    this.setBgColor = this.setBgColor.bind(this);\n    this.getTipPoints = this.getTipPoints.bind(this);\n    this.positionTip = this.positionTip.bind(this);\n    this.setTipPoints = this.setTipPoints.bind(this);\n  }\n\n  /**\n   * Returns true if passed SVG element belongs to the marker. False otherwise.\n   *\n   * @param el - target element.\n   */\n  public ownsTarget(el: EventTarget): boolean {\n    return super.ownsTarget(el) || this.tip === el;\n  }\n\n  private createTip() {\n    SvgHelper.setAttributes(this.bgRectangle, [\n      ['fill', this.bgColor],\n      ['rx', '10px'],\n    ]);\n\n    this.tip = SvgHelper.createPolygon(this.getTipPoints(), [\n      ['fill', this.bgColor],\n    ]);\n    this.visual.appendChild(this.tip);\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) down event.\n   *\n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerDown(point: IPoint, target?: EventTarget): void {\n    super.pointerDown(point, target);\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) up event.\n   *\n   * @param point - event coordinates.\n   */\n  public pointerUp(point: IPoint): void {\n    super.pointerUp(point);\n  }\n\n  /**\n   * Sets marker's background/fill color.\n   * @param color - new background color.\n   */\n  protected setBgColor(color: string): void {\n    SvgHelper.setAttributes(this.bgRectangle, [['fill', color]]);\n    SvgHelper.setAttributes(this.tip, [['fill', color]]);\n    this.bgColor = color;\n  }\n\n  private getTipPoints(): string {\n    this.setTipPoints();\n    return `${this.tipBase1Position.x},${this.tipBase1Position.y} ${this.tipBase2Position.x},${this.tipBase2Position.y} ${this.tipPosition.x},${this.tipPosition.y}`;\n  }\n\n  private setTipPoints(isCreating = false) {\n    let offset = Math.min(this.height / 2, 15);\n    let baseWidth = this.height / 5;\n    if (isCreating) {\n      this.tipPosition = { x: offset + baseWidth / 2, y: this.height + 20 };\n    }\n\n    const cornerAngle = Math.atan(this.height / 2 / (this.width / 2));\n    if (\n      this.tipPosition.x < this.width / 2 &&\n      this.tipPosition.y < this.height / 2\n    ) {\n      // top left\n      const tipAngle = Math.atan(\n        (this.height / 2 - this.tipPosition.y) /\n          (this.width / 2 - this.tipPosition.x)\n      );\n      if (cornerAngle < tipAngle) {\n        baseWidth = this.width / 5;\n        offset = Math.min(this.width / 2, 15);\n        this.tipBase1Position = { x: offset, y: 0 };\n        this.tipBase2Position = { x: offset + baseWidth, y: 0 };\n      } else {\n        this.tipBase1Position = { x: 0, y: offset };\n        this.tipBase2Position = { x: 0, y: offset + baseWidth };\n      }\n    } else if (\n      this.tipPosition.x >= this.width / 2 &&\n      this.tipPosition.y < this.height / 2\n    ) {\n      // top right\n      const tipAngle = Math.atan(\n        (this.height / 2 - this.tipPosition.y) /\n          (this.tipPosition.x - this.width / 2)\n      );\n      if (cornerAngle < tipAngle) {\n        baseWidth = this.width / 5;\n        offset = Math.min(this.width / 2, 15);\n        this.tipBase1Position = { x: this.width - offset - baseWidth, y: 0 };\n        this.tipBase2Position = { x: this.width - offset, y: 0 };\n      } else {\n        this.tipBase1Position = { x: this.width, y: offset };\n        this.tipBase2Position = { x: this.width, y: offset + baseWidth };\n      }\n    } else if (\n      this.tipPosition.x >= this.width / 2 &&\n      this.tipPosition.y >= this.height / 2\n    ) {\n      // bottom right\n      const tipAngle = Math.atan(\n        (this.tipPosition.y - this.height / 2) /\n          (this.tipPosition.x - this.width / 2)\n      );\n      if (cornerAngle < tipAngle) {\n        baseWidth = this.width / 5;\n        offset = Math.min(this.width / 2, 15);\n        this.tipBase1Position = {\n          x: this.width - offset - baseWidth,\n          y: this.height,\n        };\n        this.tipBase2Position = { x: this.width - offset, y: this.height };\n      } else {\n        this.tipBase1Position = {\n          x: this.width,\n          y: this.height - offset - baseWidth,\n        };\n        this.tipBase2Position = { x: this.width, y: this.height - offset };\n      }\n    } else {\n      // bottom left\n      const tipAngle = Math.atan(\n        (this.tipPosition.y - this.height / 2) /\n          (this.width / 2 - this.tipPosition.x)\n      );\n      if (cornerAngle < tipAngle) {\n        baseWidth = this.width / 5;\n        offset = Math.min(this.width / 2, 15);\n        this.tipBase1Position = { x: offset, y: this.height };\n        this.tipBase2Position = { x: offset + baseWidth, y: this.height };\n      } else {\n        this.tipBase1Position = { x: 0, y: this.height - offset };\n        this.tipBase2Position = { x: 0, y: this.height - offset - baseWidth };\n      }\n    }\n  }\n\n  /**\n   * Resize marker based on current pointer coordinates and context.\n   * @param point\n   */\n  protected resize(point: IPoint): void {\n    super.resize(point);\n    this.positionTip();\n  }\n\n  private positionTip() {\n    SvgHelper.setAttributes(this.tip, [['points', this.getTipPoints()]]);\n  }\n\n  /**\n   * Selects this marker and displays appropriate selected marker UI.\n   */\n  public select(): void {\n    this.positionTip();\n    super.select();\n  }\n\n  /**\n   * Restores previously saved marker state.\n   *\n   * @param state - previously saved state.\n   */\n  public restoreState(state: MarkerBaseState): void {\n    const calloutState = state as CalloutMarkerState;\n    this.bgColor = calloutState.bgColor;\n    this.tipPosition = calloutState.tipPosition;\n\n    super.restoreState(state);\n    this.createTip();\n    this.setTipPoints();\n  }\n\n  /**\n   * Scales marker. Used after the image resize.\n   *\n   * @param scaleX - horizontal scale\n   * @param scaleY - vertical scale\n   */\n  public scale(scaleX: number, scaleY: number): void {\n    super.scale(scaleX, scaleY);\n\n    this.tipPosition = {\n      x: this.tipPosition.x * scaleX,\n      y: this.tipPosition.y * scaleY,\n    };\n\n    this.positionTip();\n  }\n}\n","import { IPoint } from '../../core/IPoint';\nimport { SvgHelper } from '../../core/SvgHelper';\nimport { RectangularBoxMarkerBase } from '../RectangularBoxMarkerBase';\nimport { RectangleMarkerState } from '../RectangleMarkerState';\nimport { MarkerBaseState } from '../../core/MarkerBaseState';\n\nexport class EllipseMarker extends RectangularBoxMarkerBase {\n  /**\n   * String type name of the marker type. \n   * \n   * Used when adding {@link MarkerView.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static typeName = 'EllipseMarker';\n  /**\n   * Marker type title (display name) used for accessibility and other attributes.\n   */\n  public static title = 'Ellipse marker';\n\n  /**\n   * Ellipse fill color.\n   */\n  protected fillColor = 'transparent';\n  /**\n   * Ellipse border color.\n   */\n  protected strokeColor = 'transparent';\n  /**\n   * Ellipse border line width.\n   */\n  protected strokeWidth = 0;\n  /**\n   * Ellipse border dash array.\n   */\n  protected strokeDasharray = '';\n  /**\n   * Ellipse opacity (0..1).\n   */\n  protected opacity = 1;\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   */\n  constructor(container: SVGGElement) {\n    super(container);\n\n    this.setStrokeColor = this.setStrokeColor.bind(this);\n    this.setFillColor = this.setFillColor.bind(this);\n    this.setStrokeWidth = this.setStrokeWidth.bind(this);\n    this.setStrokeDasharray = this.setStrokeDasharray.bind(this);\n    this.setOpacity = this.setOpacity.bind(this);\n    this.createVisual = this.createVisual.bind(this);\n  }\n\n  /**\n   * Returns true if passed SVG element belongs to the marker. False otherwise.\n   * \n   * @param el - target element.\n   */\n  public ownsTarget(el: EventTarget): boolean {\n    if (super.ownsTarget(el) || el === this.visual) {\n      return true;\n    } else {\n      return false;\n    }\n  }\n\n  /**\n   * Creates marker visual.\n   */\n  protected createVisual(): void {\n    this.visual = SvgHelper.createEllipse(this.width / 2, this.height / 2, [\n      ['fill', this.fillColor],\n      ['stroke', this.strokeColor],\n      ['stroke-width', this.strokeWidth.toString()],\n      ['stroke-dasharray', this.strokeDasharray],\n      ['opacity', this.opacity.toString()]\n    ]);\n    this.addMarkerVisualToContainer(this.visual);\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) down event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerDown(point: IPoint, target?: EventTarget): void {\n    super.pointerDown(point, target);\n  }\n\n  /**\n   * Resize marker based on current pointer coordinates and context.\n   * @param point \n   */\n  protected resize(point: IPoint): void {\n    super.resize(point);\n    this.setSize();\n  }\n\n  /**\n   * Sets marker's visual size after manipulation.\n   */\n  protected setSize(): void {\n    super.setSize();\n    SvgHelper.setAttributes(this.visual, [\n      ['cx', (this.width / 2).toString()],\n      ['cy', (this.height / 2).toString()],\n      ['rx', (this.width / 2).toString()],\n      ['ry', (this.height / 2).toString()],\n    ]);\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) up event.\n   * \n   * @param point - event coordinates.\n   */\n  public pointerUp(point: IPoint): void {\n    super.pointerUp(point);\n    this.setSize();\n  }\n\n  /**\n   * Sets marker's line color.\n   * @param color - new line color.\n   */\n  protected setStrokeColor(color: string): void {\n    this.strokeColor = color;\n    if (this.visual) {\n      SvgHelper.setAttributes(this.visual, [['stroke', this.strokeColor]]);\n    }\n  }\n  /**\n   * Sets marker's fill (background) color.\n   * @param color - new fill color.\n   */\n  protected setFillColor(color: string): void {\n    this.fillColor = color;\n    if (this.visual) {\n      SvgHelper.setAttributes(this.visual, [['fill', this.fillColor]]);\n    }\n  }\n  /**\n   * Sets marker's line width.\n   * @param width - new line width\n   */\n  protected setStrokeWidth(width: number): void {\n    this.strokeWidth = width;\n    if (this.visual) {\n      SvgHelper.setAttributes(this.visual, [['stroke-width', this.strokeWidth.toString()]]);\n    }\n  }\n  /**\n   * Sets marker's border dash array.\n   * @param dashes - new dash array.\n   */\n  protected setStrokeDasharray(dashes: string): void {\n    this.strokeDasharray = dashes;\n    if (this.visual) {\n      SvgHelper.setAttributes(this.visual, [['stroke-dasharray', this.strokeDasharray]]);\n    }\n  }\n  /**\n   * Sets marker's opacity.\n   * @param opacity - new opacity value (0..1).\n   */\n  protected setOpacity(opacity: number): void {\n    this.opacity = opacity;\n    if (this.visual) {\n      SvgHelper.setAttributes(this.visual, [['opacity', this.opacity.toString()]]);\n    }\n  }\n\n  /**\n   * Restores previously saved marker state.\n   * \n   * @param state - previously saved state.\n   */\n  public restoreState(state: MarkerBaseState): void {\n    const rectState = state as RectangleMarkerState;\n    this.fillColor = rectState.fillColor;\n    this.strokeColor = rectState.strokeColor;\n    this.strokeWidth = rectState.strokeWidth;\n    this.strokeDasharray = rectState.strokeDasharray;\n    this.opacity = rectState.opacity;\n\n    this.createVisual();\n    super.restoreState(state);\n    this.setSize();\n  }\n\n  /**\n   * Scales marker. Used after the image resize.\n   * \n   * @param scaleX - horizontal scale\n   * @param scaleY - vertical scale\n   */\n  public scale(scaleX: number, scaleY: number): void {\n    super.scale(scaleX, scaleY);\n\n    this.setSize();\n  }\n}\n","import { IPoint } from '../../core/IPoint';\nimport { SvgHelper } from '../../core/SvgHelper';\nimport { LineMarker } from '../line-marker/LineMarker';\nimport { MarkerBaseState } from '../../core/MarkerBaseState';\n\nexport class MeasurementMarker extends LineMarker {\n  /**\n   * String type name of the marker type. \n   * \n   * Used when adding {@link MarkerView.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static typeName = 'MeasurementMarker';\n\n  /**\n   * Marker type title (display name) used for accessibility and other attributes.\n   */\n  public static title = 'Measurement marker';\n\n  private tip1: SVGLineElement;\n  private tip2: SVGLineElement;\n\n  private get tipLength(): number {\n    return 10 + this.strokeWidth * 3;\n  }\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   */\n  constructor(container: SVGGElement) {\n    super(container);\n  }\n\n  /**\n   * Returns true if passed SVG element belongs to the marker. False otherwise.\n   * \n   * @param el - target element.\n   */\n  public ownsTarget(el: EventTarget): boolean {\n    if (\n      super.ownsTarget(el) ||\n      el === this.tip1 || el === this.tip2\n    ) {\n      return true;\n    } else {\n      return false;\n    }\n  }\n\n  private createTips() {\n    this.tip1 = SvgHelper.createLine(\n      this.x1 - this.tipLength / 2, \n      this.y1, \n      this.x1 + this.tipLength / 2, \n      this.y1, \n      [\n        ['stroke', this.strokeColor],\n        ['stroke-width', this.strokeWidth.toString()]\n      ]);\n    this.tip1.transform.baseVal.appendItem(SvgHelper.createTransform());\n    this.visual.appendChild(this.tip1);\n\n    this.tip2 = SvgHelper.createLine(\n      this.x2 - this.tipLength / 2, \n      this.y2, \n      this.x2 + this.tipLength / 2, \n      this.y2, \n      [\n        ['stroke', this.strokeColor],\n        ['stroke-width', this.strokeWidth.toString()]\n      ]);\n    this.tip2.transform.baseVal.appendItem(SvgHelper.createTransform());\n    this.visual.appendChild(this.tip2);\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) down event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerDown(point: IPoint, target?: EventTarget): void {\n    super.pointerDown(point, target);\n  }\n\n  /**\n   * Adjusts marker visual after manipulation.\n   */\n  protected adjustVisual(): void {\n    super.adjustVisual();\n\n    if (this.tip1 && this.tip2) {\n\n      SvgHelper.setAttributes(this.tip1,[\n        ['x1', (this.x1 - this.tipLength / 2).toString()], \n        ['y1', this.y1.toString()], \n        ['x2', (this.x1 + this.tipLength / 2).toString()], \n        ['y2', this.y1.toString()], \n        ['stroke', this.strokeColor],\n        ['stroke-width', this.strokeWidth.toString()]\n      ]);\n      SvgHelper.setAttributes(this.tip2,[\n        ['x1', (this.x2 - this.tipLength / 2).toString()], \n        ['y1', this.y2.toString()], \n        ['x2', (this.x2 + this.tipLength / 2).toString()], \n        ['y2', this.y2.toString()], \n        ['stroke', this.strokeColor],\n        ['stroke-width', this.strokeWidth.toString()]\n      ]);\n\n      if (Math.abs(this.x1 - this.x2) > 0.1) {\n        const lineAngle1 =\n          (Math.atan((this.y2 - this.y1) / (this.x2 - this.x1)) * 180) / Math.PI + 90 * Math.sign(this.x1 - this.x2);\n\n        const a1transform = this.tip1.transform.baseVal.getItem(0);\n        a1transform.setRotate(lineAngle1, this.x1, this.y1);\n        this.tip1.transform.baseVal.replaceItem(a1transform, 0);\n\n        const a2transform = this.tip2.transform.baseVal.getItem(0);\n        a2transform.setRotate(lineAngle1 + 180, this.x2, this.y2);\n        this.tip2.transform.baseVal.replaceItem(a2transform, 0);\n      }\n    }\n  }\n\n  /**\n   * Restores previously saved marker state.\n   * \n   * @param state - previously saved state.\n   */\n  public restoreState(state: MarkerBaseState): void {\n    super.restoreState(state);\n\n    this.createTips();\n    this.adjustVisual();\n  }\n}\n","import { EllipseMarker } from '../ellipse-marker/EllipseMarker';\n\nexport class EllipseFrameMarker extends EllipseMarker {\n  /**\n   * String type name of the marker type. \n   * \n   * Used when adding {@link MarkerView.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static typeName = 'EllipseFrameMarker';\n  /**\n   * Marker type title (display name) used for accessibility and other attributes.\n   */\n  public static title = 'Ellipse frame marker';\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   */\n  constructor(container: SVGGElement) {\n    super(container);\n\n    this.fillColor = 'transparent';\n  }\n}\n","import { IPoint } from '../../core/IPoint';\nimport { SvgHelper } from '../../core/SvgHelper';\nimport { LinearMarkerBase } from '../LinearMarkerBase';\nimport { CurveMarkerState } from './CurveMarkerState';\nimport { MarkerBaseState } from '../../core/MarkerBaseState';\n\nexport class CurveMarker extends LinearMarkerBase {\n  /**\n   * String type name of the marker type. \n   * \n   * Used when adding {@link MarkerView.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static typeName = 'CurveMarker';\n  \n  /**\n   * Marker type title (display name) used for accessibility and other attributes.\n   */\n  public static title = 'Curve marker';\n  /**\n   * Invisible wider curve to make selection easier/possible.\n   */\n  protected selectorCurve: SVGPathElement;\n  /**\n   * Visible marker curve.\n   */\n  protected visibleCurve: SVGPathElement;\n\n  /**\n   * Line color.\n   */\n  protected strokeColor = 'transparent';\n  /**\n   * Line width.\n   */\n  protected strokeWidth = 0;\n  /**\n   * Line dash array.\n   */\n  protected strokeDasharray = '';\n\n  private curveX = 0;\n  private curveY = 0;\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   */\n  constructor(container: SVGGElement) {\n    super(container);\n\n    this.setStrokeColor = this.setStrokeColor.bind(this);\n    this.setStrokeWidth = this.setStrokeWidth.bind(this);\n    this.setStrokeDasharray = this.setStrokeDasharray.bind(this);\n    this.adjustVisual = this.adjustVisual.bind(this);\n    this.resize = this.resize.bind(this);\n  }\n\n  /**\n   * Returns true if passed SVG element belongs to the marker. False otherwise.\n   * \n   * @param el - target element.\n   */\n  public ownsTarget(el: EventTarget): boolean {\n    if (\n      super.ownsTarget(el) ||\n      el === this.visual ||\n      el === this.selectorCurve ||\n      el === this.visibleCurve\n    ) {\n      return true;\n    } else {\n      return false;\n    }\n  }\n\n  private getPathD(): string {\n    const result = `M ${this.x1} ${this.y1} Q ${this.curveX} ${this.curveY}, ${this.x2} ${this.y2}`;\n    return result;\n  }\n\n  private createVisual() {\n    this.visual = SvgHelper.createGroup();\n    this.selectorCurve = SvgHelper.createPath(\n      this.getPathD(),\n      [\n        ['stroke', 'transparent'],\n        ['stroke-width', (this.strokeWidth + 10).toString()],\n        ['fill', 'transparent'],\n      ]\n    );\n    this.visibleCurve = SvgHelper.createPath(\n      this.getPathD(),\n      [\n        ['stroke', this.strokeColor],\n        ['stroke-width', this.strokeWidth.toString()],\n        ['fill', 'transparent'],\n      ]\n    );\n    this.visual.appendChild(this.selectorCurve);\n    this.visual.appendChild(this.visibleCurve);\n\n    this.addMarkerVisualToContainer(this.visual);\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) down event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerDown(point: IPoint, target?: EventTarget): void {\n    super.pointerDown(point, target);\n  }\n\n  /**\n   * Adjusts visual after manipulation.\n   */\n  protected adjustVisual(): void {\n    this.selectorCurve.setAttribute('d', this.getPathD());\n\n    this.visibleCurve.setAttribute('d', this.getPathD());\n\n    SvgHelper.setAttributes(this.visibleCurve, [['stroke', this.strokeColor]]);\n    SvgHelper.setAttributes(this.visibleCurve, [['stroke-width', this.strokeWidth.toString()]]);\n    SvgHelper.setAttributes(this.visibleCurve, [['stroke-dasharray', this.strokeDasharray.toString()]]);\n  }\n\n  /**\n   * Sets line color.\n   * @param color - new color.\n   */\n  protected setStrokeColor(color: string): void {\n    this.strokeColor = color;\n    this.adjustVisual();\n  }\n  /**\n   * Sets line width.\n   * @param width - new width.\n   */\n  protected setStrokeWidth(width: number): void {\n    this.strokeWidth = width\n    this.adjustVisual();\n  }\n\n  /**\n   * Sets line dash array.\n   * @param dashes - new dash array.\n   */\n  protected setStrokeDasharray(dashes: string): void {\n    this.strokeDasharray = dashes;\n    this.adjustVisual();\n  }\n\n  /**\n   * Scales marker. Used after the image resize.\n   * \n   * @param scaleX - horizontal scale\n   * @param scaleY - vertical scale\n   */\n   public scale(scaleX: number, scaleY: number): void {\n    this.curveX = this.curveX * scaleX;\n    this.curveY = this.curveY * scaleY;\n    super.scale(scaleX, scaleY);\n  }\n\n  /**\n   * Restores previously saved marker state.\n   * \n   * @param state - previously saved state.\n   */\n  public restoreState(state: MarkerBaseState): void {\n    super.restoreState(state);\n\n    const lmState = state as CurveMarkerState;\n    this.strokeColor = lmState.strokeColor;\n    this.strokeWidth = lmState.strokeWidth;\n    this.strokeDasharray = lmState.strokeDasharray;\n    this.curveX = lmState.curveX;\n    this.curveY = lmState.curveY;\n\n    this.createVisual();\n    this.adjustVisual();\n  }\n}\n","/**\n * Simple utility CSS-in-JS implementation.\n */\nexport class StyleManager {\n\n  private _classNamePrefixBase = '__markerjslive_';\n  /**\n   * Static CSS class name used for the wrapper element.\n   */\n   public get classNamePrefixBase(): string {\n    return this._classNamePrefixBase;\n  }\n\n  private _classNamePrefix: string;\n  /**\n   * Prefix used for all internally created CSS classes.\n   */\n  public get classNamePrefix(): string {\n    return this._classNamePrefix;\n  }\n\n  private classes: StyleClass[] = [];\n  private rules: StyleRule[] = [];\n  private styleSheet?: HTMLStyleElement;\n\n  /**\n   * For cases when you need to add the stylesheet to anything\n   * other than document.head (default), set this property\n   * before calling `show()`.\n   */\n  public styleSheetRoot: HTMLElement;\n\n  /**\n   * Initializes a new style manager.\n   * @param instanceNo - instance id.\n   */\n  constructor(instanceNo: number) {\n    this._classNamePrefix = `${this._classNamePrefixBase}_${instanceNo}_`;\n  }\n\n  /**\n   * Adds a CSS class declaration.\n   * @param styleClass - class to add.\n   */\n  public addClass(styleClass: StyleClass): StyleClass {\n    if (this.styleSheet === undefined) {\n      this.addStyleSheet();\n    }\n    styleClass.name = `${this.classNamePrefix}${styleClass.localName}`;\n    this.classes.push(styleClass);\n    this.styleSheet.sheet.insertRule(\n      `.${styleClass.name} {${styleClass.style}}`,\n      this.styleSheet.sheet.cssRules.length\n    );\n    return styleClass;\n  }\n\n  /**\n   * Add arbitrary CSS rule\n   * @param styleRule - CSS rule to add.\n   */\n  public addRule(styleRule: StyleRule): void {\n    if (this.styleSheet === undefined) {\n      this.addStyleSheet();\n    }\n    this.rules.push(styleRule);\n    // this.styleSheet.sheet.addRule(styleRule.selector, styleRule.style); // crashes in legacy Edge\n    this.styleSheet.sheet.insertRule(\n      `${styleRule.selector} {${styleRule.style}}`,\n      this.styleSheet.sheet.cssRules.length\n    );\n  }\n\n  private addStyleSheet() {\n    this.styleSheet = document.createElement('style');\n    (this.styleSheetRoot ?? document.head).appendChild(this.styleSheet);\n  }\n\n  public removeStyleSheet(): void {\n    if (this.styleSheet) {\n      (this.styleSheetRoot ?? document.head).removeChild(this.styleSheet);\n      this.styleSheet = undefined;\n    }\n  }\n}\n\n/**\n * Represents an arbitrary CSS rule.\n */\nexport class StyleRule {\n  /**\n   * CSS selector.\n   */\n  public selector: string;\n  /**\n   * Style declaration for the rule.\n   */\n  public style: string;\n  /**\n   * Creates an arbitrary CSS rule using the selector and style rules.\n   * @param selector - CSS selector\n   * @param style - styles to apply\n   */\n  constructor(selector: string, style: string) {\n    this.selector = selector;\n    this.style = style; \n  }\n}\n\n/**\n * Represents a CSS class.\n */\nexport class StyleClass {\n  /**\n   * CSS style rules for the class.\n   */\n  public style: string;\n  \n  /**\n   * Class name without the global prefix.\n   */\n  public localName: string;\n  /**\n   * Fully qualified CSS class name.\n   */\n  public name: string;\n\n  /**\n   * Creates a CSS class declaration based on supplied (local) name and style rules.\n   * @param name - local CSS class name (will be prefixed with the marker.js prefix).\n   * @param style - style declarations.\n   */\n  constructor(name: string, style: string) {\n    this.localName = name;\n    this.style = style; \n  }\n}\n","import { MarkerView } from '../MarkerView';\nimport { MarkerBase } from './MarkerBase';\n\n/**\n * General MarkerView event handler type.\n */\nexport type MarkerViewEventHandler = (markerView: MarkerView) => void;\n\n/**\n * Marker event handler type.\n */\nexport type MarkerEventHandler = (\n  markerView: MarkerView,\n  marker?: MarkerBase\n) => void;\n\n/**\n * Pointer related marker event handler type.\n */\nexport type PointerEventHandler = (\n  markerView: MarkerView,\n  event: PointerEvent,\n  marker?: MarkerBase\n) => void;\n\n/**\n * Describes a repository of MarkerView event handlers.\n */\nexport interface IEventListenerRepository {\n  /**\n   * Event handlers for the `create` event.\n   */\n  create: MarkerViewEventHandler[];\n  /**\n   * Event handlers for the `close` event.\n   */\n  close: MarkerViewEventHandler[];\n  /**\n   * Event handlers for the `load` event.\n   */\n  load: MarkerViewEventHandler[];\n  /**\n   * Event handlers for the `select` event.\n   */\n  select: MarkerEventHandler[];\n  /**\n   * Event handlers for the `over` event.\n   */\n  over: MarkerEventHandler[];\n  /**\n   * Event handlers for the `pointerdown` event.\n   */\n  pointerdown: PointerEventHandler[];\n  /**\n   * Event handlers for the `pointermove` event.\n   */\n  pointermove: PointerEventHandler[];\n  /**\n   * Event handlers for the `pointerup` event.\n   */\n  pointerup: PointerEventHandler[];\n  /**\n   * Event handlers for the `pointerenter` event.\n   */\n  pointerenter: PointerEventHandler[];\n  /**\n   * Event handlers for the `pointerleave` event.\n   */\n  pointerleave: PointerEventHandler[];\n}\n\n/**\n * Event handler type for a specific event type.\n */\nexport type EventHandler<\n  T extends keyof IEventListenerRepository\n> = T extends 'select'\n  ? MarkerEventHandler\n  : T extends 'over'\n  ? MarkerEventHandler\n  : T extends 'pointerdown'\n  ? PointerEventHandler\n  : T extends 'pointermove'\n  ? PointerEventHandler\n  : T extends 'pointerup'\n  ? PointerEventHandler\n  : T extends 'pointerenter'\n  ? PointerEventHandler\n  : T extends 'pointerleave'\n  ? PointerEventHandler\n  : MarkerViewEventHandler;\n\n/**\n * Event handler repository.\n */\nexport class EventListenerRepository implements IEventListenerRepository {\n  /**\n   * Event handlers for the `create` event.\n   */\n  create: MarkerViewEventHandler[] = [];\n  /**\n   * Event handlers for the `close` event.\n   */\n  close: MarkerViewEventHandler[] = [];\n  /**\n   * Event handlers for the `load` event.\n   */\n  load: MarkerViewEventHandler[] = [];\n  /**\n   * Event handlers for the `select` event.\n   */\n  select: MarkerEventHandler[] = [];\n  /**\n   * Event handlers for the `over` event.\n   */\n  over: MarkerEventHandler[] = [];\n  /**\n   * Event handlers for the `pointerdown` event.\n   */\n  pointerdown: PointerEventHandler[] = [];\n  /**\n   * Event handlers for the `pointermove` event.\n   */\n  pointermove: PointerEventHandler[] = [];\n  /**\n   * Event handlers for the `pointerup` event.\n   */\n  pointerup: PointerEventHandler[] = [];\n  /**\n   * Event handlers for the `pointerenter` event.\n   */\n  pointerenter: PointerEventHandler[] = [];\n  /**\n   * Event handlers for the `pointerleave` event.\n   */\n  pointerleave: PointerEventHandler[] = [];\n\n  /**\n   * Add an event handler for a specific event type.\n   * @param eventType - event type.\n   * @param handler - function to handle the event.\n   */\n  public addEventListener<T extends keyof IEventListenerRepository>(\n    eventType: T,\n    handler: EventHandler<T>\n  ): void {\n    (<Array<EventHandler<T>>>this[eventType]).push(handler);\n  }\n\n  /**\n   * Remove an event handler for a specific event type.\n   * @param eventType - event type.\n   * @param handler - function currently handling the event.\n   */\n  public removeEventListener<T extends keyof IEventListenerRepository>(\n    eventType: T,\n    handler: EventHandler<T>\n  ): void {\n    const index = (<Array<EventHandler<T>>>this[eventType]).indexOf(handler);\n    if (index > -1) {\n      (<Array<EventHandler<T>>>this[eventType]).splice(index, 1);\n    }\n  }\n}\n","import { SvgHelper } from './core/SvgHelper';\nimport { Activator } from './core/Activator';\n\nimport Logo from './assets/markerjs-logo-m.svg';\n\nimport { MarkerBase } from './core/MarkerBase';\nimport { FrameMarker } from './markers/frame-marker/FrameMarker';\nimport { LineMarker } from './markers/line-marker/LineMarker';\nimport { TextMarker } from './markers/text-marker/TextMarker';\nimport { FreehandMarker } from './markers/freehand-marker/FreehandMarker';\nimport { ArrowMarker } from './markers/arrow-marker/ArrowMarker';\nimport { CoverMarker } from './markers/cover-marker/CoverMarker';\nimport { HighlightMarker } from './markers/highlight-marker/HighlightMarker';\nimport { CalloutMarker } from './markers/callout-marker/CalloutMarker';\nimport { EllipseMarker } from './markers/ellipse-marker/EllipseMarker';\nimport { MeasurementMarker } from './markers/measurement-marker/MeasurementMarker';\nimport { EllipseFrameMarker } from './markers/ellipse-frame-marker/EllipseFrameMarker';\nimport { CurveMarker } from './markers/curve-marker/CurveMarker';\n\nimport { MarkerAreaState } from './MarkerAreaState';\nimport { IPoint } from './core/IPoint';\n\nimport { StyleManager } from './core/Style';\nimport {\n  EventHandler,\n  EventListenerRepository,\n  IEventListenerRepository,\n} from './core/Events';\nimport { IMarkerViewPlugin } from './core/MarkerViewPlugin';\n\n/**\n * MarkerViews is the main class of marker.js Live. It controls the core behavior of the library.\n *\n * The simplest marker.js Live usage scenario looks something like this:\n *\n * ```typescript\n * // skip this line if you are importing marker.js Live into the global space via the script tag\n * import * as mjslive from 'markerjs-live';\n *\n * // create an instance of MarkerView and pass the target image reference as a parameter\n * const markerView = new mjslive.MarkerView(target);\n *\n * // call the show() method and pass your annotation configuration (created with marker.js 2) as a parameter\n * markerView.show(markerState);\n * ```\n */\nexport class MarkerView {\n  private target: HTMLElement;\n  private targetObserver: ResizeObserver;\n\n  private imageWidth: number;\n  private imageHeight: number;\n  private left: number;\n  private top: number;\n\n  public markerImage: SVGSVGElement;\n  private markerImageHolder: HTMLDivElement;\n  private defs: SVGDefsElement;\n\n  private coverDiv: HTMLDivElement;\n  private uiDiv: HTMLDivElement;\n  private contentDiv: HTMLDivElement;\n  private editorCanvas: HTMLDivElement;\n  private editingTarget: HTMLCanvasElement;\n  private overlayContainer: HTMLDivElement;\n\n  private touchPoints = 0;\n\n  private logoUI: HTMLElement;\n\n  private static instanceCounter = 0;\n  private _instanceNo: number;\n  /**\n   * Instance id of this instance\n   */\n  public get instanceNo(): number {\n    return this._instanceNo;\n  }\n\n  /**\n   * Manage style releated settings via the `styles` property.\n   */\n  public styles: StyleManager;\n\n  /**\n   * Marker types supported by this instance. \n   * You can remove some types to limit the markers displayed.\n   */\n  public availableMarkerTypes: typeof MarkerBase[] = [\n    FrameMarker,\n    FreehandMarker,\n    ArrowMarker,\n    TextMarker,\n    EllipseFrameMarker,\n    EllipseMarker,\n    HighlightMarker,\n    CalloutMarker,\n    MeasurementMarker,\n    CoverMarker,\n    LineMarker,\n    CurveMarker\n  ];\n\n  /**\n   * `targetRoot` is used to set an alternative positioning root.\n   *\n   * This is useful in cases when your target image is positioned, say, inside a div with `position: relative;`\n   *\n   * ```typescript\n   * // set targetRoot to a specific div instead of document.body\n   * markerView.targetRoot = document.getElementById('myRootElement');\n   * ```\n   *\n   * @default document.body\n   */\n  public targetRoot: HTMLElement;\n\n  private currentMarker?: MarkerBase;\n  private hoveredMarker?: MarkerBase;\n  /**\n   * The list of all markers displayed.\n   */\n  public markers: MarkerBase[] = [];\n\n  private isDragging = false;\n\n  private _isOpen = false;\n  /**\n   * Returns `true` when MarkerView is open and `false` otherwise.\n   *\n   * @readonly\n   */\n  public get isOpen(): boolean {\n    return this._isOpen;\n  }\n\n  private plugins: IMarkerViewPlugin[] = [];\n\n  /**\n   * The suffix of the CSS class name of the marker container (SVG group) element.\n   */\n  public readonly MARKER_CONTAINER_CLASS_SUFFIX = 'marker-container';\n\n  /**\n   * Creates a new MarkerView for the specified target image.\n   *\n   * ```typescript\n   * // create an instance of MarkerView and pass the target image reference as a parameter\n   * let markerView = new mjslive.MarkerView(document.getElementById('myimg'));\n   * ```\n   *\n   * @param target image object to be overlayed with markers.\n   */\n  constructor(target: HTMLElement) {\n    this._instanceNo = MarkerView.instanceCounter++;\n\n    this.styles = new StyleManager(this.instanceNo);\n\n    this.target = target;\n    this.targetRoot = document.body;\n\n    this.open = this.open.bind(this);\n    this.setTopLeft = this.setTopLeft.bind(this);\n\n    this.addNewMarker = this.addNewMarker.bind(this);\n    this.setCurrentMarker = this.setCurrentMarker.bind(this);\n    this.onPointerDown = this.onPointerDown.bind(this);\n    this.onDblClick = this.onDblClick.bind(this);\n    this.onPointerMove = this.onPointerMove.bind(this);\n    this.onPointerUp = this.onPointerUp.bind(this);\n    this.onKeyUp = this.onKeyUp.bind(this);\n    this.close = this.close.bind(this);\n    this.closeUI = this.closeUI.bind(this);\n    this.clientToLocalCoordinates = this.clientToLocalCoordinates.bind(this);\n    this.onWindowResize = this.onWindowResize.bind(this);\n    this.removeMarker = this.removeMarker.bind(this);\n  }\n\n  private open(): void {\n    this.setupResizeObserver();\n    this.setEditingTarget();\n    this.setTopLeft();\n    this.initMarkerCanvas();\n    this.initOverlay();\n    this.attachEvents();\n\n    if (!Activator.isLicensed) {\n      // NOTE:\n      // before removing this call please consider supporting marker.js\n      // by visiting https://markerjs.com/ for details\n      // thank you!\n      this.addLogo();\n    }\n\n    this._isOpen = true;\n  }\n\n  /**\n   * Initializes the MarkerView and show the markers.\n   * \n   * @param state - marker configuration created with marker.js 2.\n   */\n  public show(state: MarkerAreaState): void {\n    this.showUI();\n    this.open();\n    \n    this.plugins.forEach(plugin => plugin.init(this));\n    \n    this.eventListeners['create'].forEach((created) => created(this));\n\n    this.restoreState(state);\n\n    this.eventListeners['load'].forEach((loaded) => loaded(this));\n  }\n\n  /**\n   * Closes the MarkerView.\n   */\n  public close(): void {\n    if (this.isOpen) {\n      if (this.coverDiv) {\n        this.closeUI();\n      }\n      if (this.targetObserver) {\n        this.targetObserver.unobserve(this.target);\n      }\n      this._isOpen = false;\n\n      this.eventListeners['close'].forEach(closed => closed(this));\n    }\n  }\n\n  private setupResizeObserver() {\n    if (window.ResizeObserver) {\n      this.targetObserver = new ResizeObserver(() => {\n        this.resize(this.target.clientWidth, this.target.clientHeight);\n      });\n      this.targetObserver.observe(this.target);\n    }\n  }\n\n  private resize(newWidth: number, newHeight: number) {\n    const scaleX = newWidth / this.imageWidth;\n    const scaleY = newHeight / this.imageHeight;\n\n    this.imageWidth = Math.round(newWidth);\n    this.imageHeight = Math.round(newHeight);\n    // this.editingTarget.src = this.target.src;\n    this.editingTarget.width = this.imageWidth;\n    this.editingTarget.height = this.imageHeight;\n    this.editingTarget.style.width = `${this.imageWidth}px`;\n    this.editingTarget.style.height = `${this.imageHeight}px`;\n\n    this.markerImage.setAttribute('width', this.imageWidth.toString());\n    this.markerImage.setAttribute('height', this.imageHeight.toString());\n    this.markerImage.setAttribute(\n      'viewBox',\n      '0 0 ' + this.imageWidth.toString() + ' ' + this.imageHeight.toString()\n    );\n\n    this.markerImageHolder.style.width = `${this.imageWidth}px`;\n    this.markerImageHolder.style.height = `${this.imageHeight}px`;\n\n    this.overlayContainer.style.width = `${this.imageWidth}px`;\n    this.overlayContainer.style.height = `${this.imageHeight}px`;\n\n    this.coverDiv.style.width = `${this.imageWidth.toString()}px`;\n\n    this.positionLogo();\n\n    this.scaleMarkers(scaleX, scaleY);\n  }\n\n  private scaleMarkers(scaleX: number, scaleY: number) {\n    let preScaleSelectedMarker: MarkerBase;\n    if (!(this.currentMarker && this.currentMarker instanceof TextMarker)) {\n      preScaleSelectedMarker = this.currentMarker;\n      this.setCurrentMarker();\n    }\n    this.markers.forEach((marker) => marker.scale(scaleX, scaleY));\n    if (preScaleSelectedMarker !== undefined) {\n      this.setCurrentMarker(preScaleSelectedMarker);\n    }\n  }\n\n  private setEditingTarget() {\n    this.imageWidth = Math.round(this.target.clientWidth);\n    this.imageHeight = Math.round(this.target.clientHeight);\n    // this.editingTarget.src = this.target.src;\n    this.editingTarget.width = this.imageWidth;\n    this.editingTarget.height = this.imageHeight;\n    this.editingTarget.style.width = `${this.imageWidth}px`;\n    this.editingTarget.style.height = `${this.imageHeight}px`;\n  }\n\n  private setTopLeft() {\n    const targetRect = this.editingTarget.getBoundingClientRect();\n    const bodyRect = this.editorCanvas.getBoundingClientRect();\n    this.left = targetRect.left - bodyRect.left;\n    this.top = targetRect.top - bodyRect.top;\n  }\n\n  private initMarkerCanvas(): void {\n    this.markerImageHolder = document.createElement('div');\n    this.markerImageHolder.style.setProperty('touch-action', 'pinch-zoom');\n\n    this.markerImage = document.createElementNS(\n      'http://www.w3.org/2000/svg',\n      'svg'\n    );\n    this.markerImage.setAttribute('xmlns', 'http://www.w3.org/2000/svg');\n    this.markerImage.setAttribute('width', this.imageWidth.toString());\n    this.markerImage.setAttribute('height', this.imageHeight.toString());\n    this.markerImage.setAttribute(\n      'viewBox',\n      '0 0 ' + this.imageWidth.toString() + ' ' + this.imageHeight.toString()\n    );\n    this.markerImage.style.pointerEvents = 'auto';\n\n    this.markerImageHolder.style.position = 'absolute';\n    this.markerImageHolder.style.width = `${this.imageWidth}px`;\n    this.markerImageHolder.style.height = `${this.imageHeight}px`;\n    this.markerImageHolder.style.transformOrigin = 'top left';\n    this.positionMarkerImage();\n\n    this.defs = SvgHelper.createDefs();\n    this.markerImage.appendChild(this.defs);\n\n    this.markerImageHolder.appendChild(this.markerImage);\n\n    this.editorCanvas.appendChild(this.markerImageHolder);\n  }\n\n  private initOverlay(): void {\n    this.overlayContainer = document.createElement('div');\n    this.overlayContainer.style.position = 'absolute';\n    this.overlayContainer.style.left = '0px';\n    this.overlayContainer.style.top = '0px';\n    this.overlayContainer.style.width = `${this.imageWidth}px`;\n    this.overlayContainer.style.height = `${this.imageHeight}px`;\n    this.overlayContainer.style.display = 'flex';\n    this.markerImageHolder.appendChild(this.overlayContainer);\n  }\n\n  private positionMarkerImage() {\n    this.markerImageHolder.style.top = this.top + 'px';\n    this.markerImageHolder.style.left = this.left + 'px';\n  }\n\n  private attachEvents() {\n    this.markerImage.addEventListener('pointerdown', this.onPointerDown);\n    this.markerImage.addEventListener('dblclick', this.onDblClick);\n    window.addEventListener('pointermove', this.onPointerMove);\n    window.addEventListener('pointerup', this.onPointerUp);\n    window.addEventListener('pointercancel', () => {\n      if (this.touchPoints > 0) {\n        this.touchPoints--;\n      }\n    });\n    window.addEventListener('pointerout', () => {\n      if (this.touchPoints > 0) {\n        this.touchPoints--;\n      }\n    });\n    window.addEventListener('pointerleave', this.onPointerUp);\n    window.addEventListener('resize', this.onWindowResize);\n    window.addEventListener('keyup', this.onKeyUp);\n  }\n\n  /**\n   * NOTE:\n   *\n   * before removing or modifying this method please consider supporting marker.js\n   * by visiting https://markerjs.com/#price for details\n   *\n   * thank you!\n   */\n  private addLogo() {\n    this.logoUI = document.createElement('div');\n    this.logoUI.style.display = 'inline-block';\n    this.logoUI.style.margin = '0px';\n    this.logoUI.style.padding = '0px';\n    this.logoUI.style.fill = '#333333';\n\n    const link = document.createElement('a');\n    link.href = 'https://markerjs.com/';\n    link.target = '_blank';\n    link.innerHTML = Logo;\n    link.title = 'Powered by marker.js';\n\n    link.style.display = 'grid';\n    link.style.alignItems = 'center';\n    link.style.justifyItems = 'center';\n    link.style.padding = '3px';\n    link.style.width = '20px';\n    link.style.height = '20px';\n\n    this.logoUI.appendChild(link);\n\n    this.editorCanvas.appendChild(this.logoUI);\n\n    this.logoUI.style.position = 'absolute';\n    this.logoUI.style.pointerEvents = 'all';\n    this.positionLogo();\n  }\n\n  private positionLogo() {\n    if (this.logoUI) {\n      this.logoUI.style.left = `${this.markerImageHolder.offsetLeft + 10}px`;\n      this.logoUI.style.top = `${\n        this.markerImageHolder.offsetTop +\n        this.markerImageHolder.offsetHeight -\n        this.logoUI.clientHeight -\n        10\n      }px`;\n    }\n  }\n\n  private showUI(): void {\n    this.coverDiv = document.createElement('div');\n    this.coverDiv.className = `${this.styles.classNamePrefixBase} ${this.styles.classNamePrefix}`;\n    // hardcode font size so nothing inside is affected by higher up settings\n    this.coverDiv.style.fontSize = '16px';\n    this.coverDiv.style.userSelect = 'none';\n    this.coverDiv.style.position = 'absolute';\n    this.coverDiv.style.top = `${this.target.offsetTop.toString()}px`;\n    this.coverDiv.style.left = `${this.target.offsetLeft.toString()}px`;\n    this.coverDiv.style.width = `${this.target.offsetWidth.toString()}px`;\n    //this.coverDiv.style.height = `${this.target.offsetHeight.toString()}px`;\n    this.coverDiv.style.zIndex = '5';\n    // flex causes the ui to stretch when toolbox has wider nowrap panels\n    //this.coverDiv.style.display = 'flex';\n    this.targetRoot.appendChild(this.coverDiv);\n\n    this.uiDiv = document.createElement('div');\n    this.uiDiv.style.display = 'flex';\n    this.uiDiv.style.flexDirection = 'column';\n    this.uiDiv.style.flexGrow = '2';\n    this.uiDiv.style.margin = '0px';\n    this.uiDiv.style.border = '0px';\n    // this.uiDiv.style.overflow = 'hidden';\n    //this.uiDiv.style.backgroundColor = '#ffffff';\n    this.coverDiv.appendChild(this.uiDiv);\n\n    this.contentDiv = document.createElement('div');\n    this.contentDiv.style.display = 'flex';\n    this.contentDiv.style.flexDirection = 'row';\n    this.contentDiv.style.flexGrow = '2';\n    this.contentDiv.style.flexShrink = '1';\n    this.uiDiv.appendChild(this.contentDiv);\n\n    this.editorCanvas = document.createElement('div');\n    this.editorCanvas.style.flexGrow = '2';\n    this.editorCanvas.style.flexShrink = '1';\n    this.editorCanvas.style.position = 'relative';\n    this.editorCanvas.style.overflow = 'hidden';\n    this.editorCanvas.style.display = 'flex';\n    this.editorCanvas.style.pointerEvents = 'none';\n    this.contentDiv.appendChild(this.editorCanvas);\n\n    this.editingTarget = document.createElement('canvas');\n    this.editorCanvas.appendChild(this.editingTarget);\n  }\n\n  private closeUI() {\n    // @todo better cleanup\n    this.targetRoot.removeChild(this.coverDiv);\n  }\n\n  private removeMarker(marker: MarkerBase) {\n    this.markerImage.removeChild(marker.container);\n    if (this.markers.indexOf(marker) > -1) {\n      this.markers.splice(this.markers.indexOf(marker), 1);\n    }\n    marker.dispose();\n  }\n\n  /**\n   * Uses the state created with marker.js 2 to display the markers.\n   *\n   * @param state - previously saved marker.js 2 state object.\n   */\n  private restoreState(state: MarkerAreaState): void {\n    this.markers.splice(0);\n    while (this.markerImage.lastChild) {\n      this.markerImage.removeChild(this.markerImage.lastChild);\n    }\n    state.markers.forEach((markerState) => {\n      const markerType = this.availableMarkerTypes.find(\n        (mType) => mType.typeName === markerState.typeName\n      );\n      if (markerType !== undefined) {\n        const marker = this.addNewMarker(markerType);\n        marker.restoreState(markerState);\n        this.markers.push(marker);\n      }\n    });\n    if (\n      state.width &&\n      state.height &&\n      (state.width !== this.imageWidth || state.height !== this.imageHeight)\n    ) {\n      this.scaleMarkers(\n        this.imageWidth / state.width,\n        this.imageHeight / state.height\n      );\n    }\n  }\n\n  private addNewMarker(markerType: typeof MarkerBase): MarkerBase {\n    const g = SvgHelper.createGroup();\n    g.setAttribute('class', `${this.styles.classNamePrefix}${this.MARKER_CONTAINER_CLASS_SUFFIX}`);\n    this.markerImage.appendChild(g);\n\n    return new markerType(g);\n  }\n\n  /**\n   * Sets the currently selected marker or deselects it if no parameter passed.\n   *\n   * @param marker marker to select. Deselects current marker if undefined.\n   */\n  public setCurrentMarker(marker?: MarkerBase): void {\n    const currentChanged = this.currentMarker !== marker;\n\n    if (this.currentMarker !== undefined) {\n      this.currentMarker.deselect();\n    }\n    this.currentMarker = marker;\n    if (this.currentMarker !== undefined) {\n      this.currentMarker.select();\n    }\n\n    if (currentChanged) {\n      this.eventListeners['select'].forEach((selected) =>\n        selected(this, marker)\n      );\n    }\n  }\n\n  private onPointerDown(ev: PointerEvent) {\n    this.touchPoints++;\n    if (this.touchPoints === 1 || ev.pointerType !== 'touch') {\n      const hitMarker = this.markers.find((m) => m.ownsTarget(ev.target));\n      if (hitMarker !== undefined) {\n        this.setCurrentMarker(hitMarker);\n        this.isDragging = true;\n        this.currentMarker.pointerDown(\n          this.clientToLocalCoordinates(ev.clientX, ev.clientY),\n          ev.target\n        );\n      } else {\n        this.setCurrentMarker();\n      }\n\n      if (this.eventListeners['pointerdown'].length > 0) {\n        this.eventListeners['pointerdown'].forEach((pointerDownHandler) =>\n          pointerDownHandler(this, ev, hitMarker)\n        );\n      }\n    }\n  }\n\n  private onDblClick(ev: PointerEvent) {\n    const hitMarker = this.markers.find((m) => m.ownsTarget(ev.target));\n    if (hitMarker !== undefined && hitMarker !== this.currentMarker) {\n      this.setCurrentMarker(hitMarker);\n    }\n    if (this.currentMarker !== undefined) {\n      this.currentMarker.dblClick(\n        this.clientToLocalCoordinates(ev.clientX, ev.clientY),\n        ev.target\n      );\n    } else {\n      this.setCurrentMarker();\n    }\n  }\n\n  private isPointerIn = false;\n  private onPointerMove(ev: PointerEvent) {\n    if (this.touchPoints === 1 || ev.pointerType !== 'touch') {\n      if (this.currentMarker !== undefined || this.isDragging) {\n        ev.preventDefault();\n      }\n    }\n\n    if (\n      this.eventListeners['over'].length > 0 ||\n      this.eventListeners['pointermove'].length > 0\n    ) {\n      const hitMarker = this.markers.find((m) => m.ownsTarget(ev.target));\n      if (hitMarker !== this.hoveredMarker) {\n        this.hoveredMarker = hitMarker;\n        this.eventListeners['over'].forEach((overHandler) =>\n          overHandler(this, this.hoveredMarker)\n        );\n      }\n\n      this.eventListeners['pointermove'].forEach((pointerMoveHandler) =>\n        pointerMoveHandler(this, ev, hitMarker)\n      );\n\n      if (!this.isPointerIn && (hitMarker !== undefined || this.markerImage === ev.target)) {\n        this.isPointerIn = true;\n        this.eventListeners['pointerenter'].forEach((pointerEnterHandler) =>\n          pointerEnterHandler(this, ev, hitMarker)\n        );\n      }\n\n      if (this.isPointerIn && hitMarker === undefined && this.markerImage !== ev.target) {\n        this.isPointerIn = false;\n        this.eventListeners['pointerleave'].forEach((pointerLeaveHandler) =>\n          pointerLeaveHandler(this, ev, hitMarker)\n        );\n      }\n    }\n  }\n\n  private onPointerUp(ev: PointerEvent) {\n    if (this.touchPoints > 0) {\n      this.touchPoints--;\n    }\n    if (this.touchPoints === 0) {\n      if (this.isDragging && this.currentMarker !== undefined) {\n        this.currentMarker.pointerUp(\n          this.clientToLocalCoordinates(ev.clientX, ev.clientY)\n        );\n      }\n    }\n    this.isDragging = false;\n\n    if (this.eventListeners['pointerup'].length > 0) {\n      const hitMarker = this.markers.find((m) => m.ownsTarget(ev.target));\n      this.eventListeners['pointerup'].forEach((pointerUpHandler) =>\n        pointerUpHandler(this, ev, hitMarker)\n      );\n    }\n\n  }\n\n  private onKeyUp(ev: KeyboardEvent) {\n    if (\n      this.currentMarker !== undefined &&\n      (ev.key === 'Delete' || ev.key === 'Backspace')\n    ) {\n      this.removeMarker(this.currentMarker);\n      this.setCurrentMarker();\n      this.markerImage.style.cursor = 'default';\n    }\n  }\n\n  private clientToLocalCoordinates(x: number, y: number): IPoint {\n    const clientRect = this.markerImage.getBoundingClientRect();\n    return { x: x - clientRect.left, y: y - clientRect.top };\n  }\n\n  private onWindowResize() {\n    this.positionUI();\n  }\n\n  private positionUI() {\n    this.setTopLeft();\n    this.coverDiv.style.top = `${this.target.offsetTop.toString()}px`;\n    this.coverDiv.style.left = `${this.target.offsetLeft.toString()}px`;\n    this.positionMarkerImage();\n    this.positionLogo();\n  }\n\n  private eventListeners = new EventListenerRepository();\n  /**\n   * Adds an event listener for one of the marker.js Live events.\n   * \n   * @param eventType - type of the event.\n   * @param handler - function handling the event.\n   */\n  public addEventListener<T extends keyof IEventListenerRepository>(\n    eventType: T,\n    handler: EventHandler<T>\n  ): void {\n    this.eventListeners.addEventListener(eventType, handler);\n  }\n\n  /**\n   * Removes an event listener for one of the marker.js Live events.\n   * \n   * @param eventType - type of the event.\n   * @param handler - function currently handling the event.\n   */\n  public removeEventListener<T extends keyof IEventListenerRepository>(\n    eventType: T,\n    handler: EventHandler<T>\n  ): void {\n    this.eventListeners.removeEventListener(eventType, handler);\n  }\n\n  /**\n   * Adds a plugin to the plugin array.\n   * @param plugin \n   */\n  public addPlugin(plugin: IMarkerViewPlugin): void {\n    this.plugins.push(plugin);\n  }\n  \n  /**\n   * Removes a plugin from the plugin array.\n   * @param plugin \n   */\n  public removePlugin(plugin: IMarkerViewPlugin): void {\n    const pluginIndex = this.plugins.indexOf(plugin);\n    if (pluginIndex >= 0) {\n      this.plugins.splice(pluginIndex, 1);\n    }\n  }\n}\n"],"names":["SvgHelper","document","createElementNS","stylesheet","setAttribute","el","attributes","attributes_1","_i","_a","attr","value","width","height","rect","toString","setAttributes","x1","y1","x2","y2","line","points","polygon","radius","circle","rx","ry","ellipse","g","createSVGTransform","id","orient","markerWidth","markerHeight","refX","refY","markerElement","marker","appendChild","text","tspan","textContent","image","x","y","svgPoint","createSVGPoint","d","path","Activator","key","Object","RegExp","test","extendStatics","b","setPrototypeOf","__proto__","Array","p","prototype","hasOwnProperty","call","__extends","__","this","constructor","create","container","_outerContainer","innerContainer","createGroup","_container","MarkerBase","point","target","element","childNodes","length","insertBefore","state","notes","scaleX","scaleY","TransformMatrix","matrix","a","c","e","f","currentMatrix","newMatrix","_super","_this","transform","baseVal","appendItem","createTransform","RectangularBoxMarkerBase","left","top","_visual","translate","ownsTarget","pointerDown","select","pointerUp","visual","style","setSize","moveVisual","Math","abs","centerX","sign","rotationAngle","atan","centerY","PI","applyRotation","rotate","getItem","setRotate","replaceItem","getCTM","createPoint","matrixTransform","inverse","deselect","restoreState","rbmState","setMatrix","toSVGMatrix","visualTransformMatrix","containerTransformMatrix","scale","rPoint","rotatePoint","unrotatePoint","setStrokeColor","bind","setFillColor","setStrokeWidth","setStrokeDasharray","createVisual","RectangleMarker","createRect","fillColor","strokeColor","strokeWidth","strokeDasharray","opacity","addMarkerVisualToContainer","resize","color","dashes","rectState","FrameMarker","LinearMarkerBase","adjustVisual","lmbState","LineMarker","selectorLine","visibleLine","createLine","lmState","defaultSize","setColor","setFont","renderText","sizeText","TextMarker","textElement","bgRectangle","found_1","forEach","span","createText","fontFamily","pointerDownPoint","lastChild","removeChild","split","createTSpan","trim","setTimeout","textSize","getBBox","xScale","padding","yScale","min","textBBox","getTextScale","position","getTextPosition","navigator","userAgent","indexOf","setTranslate","setScale","dblClick","font","textState","FreehandMarker","drawingImage","createImage","drawingImgUrl","setDrawingImage","getArrowPoints","setArrowType","ArrowMarker","arrow1","arrow2","offsetX","offsetY","arrowBaseWidth","arrowBaseHeight","createPolygon","display","arrowType","lineAngle1","a1transform","a2transform","amState","createTips","CoverMarker","setOpacity","HighlightMarker","setBgColor","getTipPoints","positionTip","setTipPoints","CalloutMarker","tip","bgColor","tipBase1Position","tipBase2Position","tipPosition","isCreating","offset","baseWidth","cornerAngle","calloutState","createTip","EllipseMarker","createEllipse","MeasurementMarker","tip1","tip2","tipLength","EllipseFrameMarker","CurveMarker","selectorCurve","visibleCurve","curveX","curveY","createPath","getPathD","instanceNo","_classNamePrefix","_classNamePrefixBase","StyleManager","styleClass","undefined","styleSheet","addStyleSheet","name","classNamePrefix","localName","classes","push","sheet","insertRule","cssRules","styleRule","rules","selector","createElement","styleSheetRoot","head","EventListenerRepository","eventType","handler","index","splice","_instanceNo","MarkerView","instanceCounter","styles","targetRoot","body","open","setTopLeft","addNewMarker","setCurrentMarker","onPointerDown","onDblClick","onPointerMove","onPointerUp","onKeyUp","close","closeUI","clientToLocalCoordinates","onWindowResize","removeMarker","_isOpen","setupResizeObserver","setEditingTarget","initMarkerCanvas","initOverlay","attachEvents","isLicensed","addLogo","showUI","plugins","plugin","init","eventListeners","created","loaded","isOpen","coverDiv","targetObserver","unobserve","closed","window","ResizeObserver","clientWidth","clientHeight","observe","newWidth","newHeight","imageWidth","imageHeight","round","editingTarget","markerImage","markerImageHolder","overlayContainer","positionLogo","scaleMarkers","preScaleSelectedMarker","currentMarker","markers","targetRect","getBoundingClientRect","bodyRect","editorCanvas","setProperty","pointerEvents","transformOrigin","positionMarkerImage","defs","createDefs","addEventListener","touchPoints","logoUI","margin","fill","link","href","innerHTML","title","alignItems","justifyItems","offsetLeft","offsetTop","offsetHeight","className","classNamePrefixBase","fontSize","userSelect","offsetWidth","zIndex","uiDiv","flexDirection","flexGrow","border","contentDiv","flexShrink","overflow","dispose","markerState","markerType","availableMarkerTypes","find","mType","typeName","MARKER_CONTAINER_CLASS_SUFFIX","currentChanged","selected","ev","pointerType","hitMarker_1","m","isDragging","clientX","clientY","pointerDownHandler","hitMarker","preventDefault","hitMarker_2","hoveredMarker","overHandler","pointerMoveHandler","isPointerIn","pointerEnterHandler","pointerLeaveHandler","hitMarker_3","pointerUpHandler","cursor","clientRect","positionUI","removeEventListener","pluginIndex"],"mappings":"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"}
\ No newline at end of file
diff --git a/capsule-prototype/js/libs/markerjslive/markerjs-live.js b/capsule-prototype/js/libs/markerjslive/markerjs-live.js
new file mode 100644
index 0000000000000000000000000000000000000000..b2a0c082a4b01daec8258c413ecb4dddd782118e
--- /dev/null
+++ b/capsule-prototype/js/libs/markerjslive/markerjs-live.js
@@ -0,0 +1,2 @@
+!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).mjslive={})}(this,(function(t){"use strict";var e=function(){function t(){}return t.createDefs=function(){return document.createElementNS("http://www.w3.org/2000/svg","defs")},t.createStylesheet=function(){var t=document.createElementNS("http://www.w3.org/2000/svg","style");return t.setAttribute("type","text/css"),t},t.setAttributes=function(t,e){for(var i=0,s=e;i<s.length;i++){var r=s[i],o=r[0],n=r[1];t.setAttribute(o,n)}},t.createRect=function(e,i,s){var r=document.createElementNS("http://www.w3.org/2000/svg","rect");return r.setAttribute("width",e.toString()),r.setAttribute("height",i.toString()),s&&t.setAttributes(r,s),r},t.createLine=function(e,i,s,r,o){var n=document.createElementNS("http://www.w3.org/2000/svg","line");return n.setAttribute("x1",e.toString()),n.setAttribute("y1",i.toString()),n.setAttribute("x2",s.toString()),n.setAttribute("y2",r.toString()),o&&t.setAttributes(n,o),n},t.createPolygon=function(e,i){var s=document.createElementNS("http://www.w3.org/2000/svg","polygon");return s.setAttribute("points",e),i&&t.setAttributes(s,i),s},t.createCircle=function(e,i){var s=document.createElementNS("http://www.w3.org/2000/svg","circle");return s.setAttribute("cx",(e/2).toString()),s.setAttribute("cy",(e/2).toString()),s.setAttribute("r",e.toString()),i&&t.setAttributes(s,i),s},t.createEllipse=function(e,i,s){var r=document.createElementNS("http://www.w3.org/2000/svg","ellipse");return r.setAttribute("cx",(e/2).toString()),r.setAttribute("cy",(i/2).toString()),r.setAttribute("rx",(e/2).toString()),r.setAttribute("ry",(i/2).toString()),s&&t.setAttributes(r,s),r},t.createGroup=function(e){var i=document.createElementNS("http://www.w3.org/2000/svg","g");return e&&t.setAttributes(i,e),i},t.createTransform=function(){return document.createElementNS("http://www.w3.org/2000/svg","svg").createSVGTransform()},t.createMarker=function(e,i,s,r,o,n,h){var a=document.createElementNS("http://www.w3.org/2000/svg","marker");return t.setAttributes(a,[["id",e],["orient",i],["markerWidth",s.toString()],["markerHeight",r.toString()],["refX",o.toString()],["refY",n.toString()]]),a.appendChild(h),a},t.createText=function(e){var i=document.createElementNS("http://www.w3.org/2000/svg","text");return i.setAttribute("x","0"),i.setAttribute("y","0"),e&&t.setAttributes(i,e),i},t.createTSpan=function(e,i){var s=document.createElementNS("http://www.w3.org/2000/svg","tspan");return s.textContent=e,i&&t.setAttributes(s,i),s},t.createImage=function(e){var i=document.createElementNS("http://www.w3.org/2000/svg","image");return e&&t.setAttributes(i,e),i},t.createPoint=function(t,e){var i=document.createElementNS("http://www.w3.org/2000/svg","svg").createSVGPoint();return i.x=t,i.y=e,i},t.createPath=function(e,i){var s=document.createElementNS("http://www.w3.org/2000/svg","path");return s.setAttribute("d",e),i&&t.setAttributes(s,i),s},t}(),i=function(){function t(){}return t.addKey=function(e){t.key=e},Object.defineProperty(t,"isLicensed",{get:function(){return!!t.key&&new RegExp(/^MJSL-[A-Z][0-9]{3}-[A-Z][0-9]{3}-[0-9]{4}$/,"i").test(t.key)},enumerable:!1,configurable:!0}),t}(),s=function(t,e){return(s=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])})(t,e)};function r(t,e){function i(){this.constructor=t}s(t,e),t.prototype=null===e?Object.create(e):(i.prototype=e.prototype,new i)}var o=function(){function t(t){this._outerContainer=t;var i=e.createGroup();this._outerContainer.appendChild(i),this._container=i}return Object.defineProperty(t.prototype,"outerContainer",{get:function(){return this._outerContainer},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"container",{get:function(){return this._container},enumerable:!1,configurable:!0}),t.prototype.ownsTarget=function(t){return!1},t.prototype.select=function(){},t.prototype.deselect=function(){},t.prototype.pointerDown=function(t,e){},t.prototype.dblClick=function(t,e){},t.prototype.pointerUp=function(t){},t.prototype.dispose=function(){},t.prototype.addMarkerVisualToContainer=function(t){this.container.childNodes.length>0?this.container.insertBefore(t,this.container.childNodes[0]):this.container.appendChild(t)},t.prototype.restoreState=function(t){this.notes=t.notes},t.prototype.scale=function(t,e){},t.typeName="MarkerBase",t}(),n=function(){function t(){}return t.toITransformMatrix=function(t){return{a:t.a,b:t.b,c:t.c,d:t.d,e:t.e,f:t.f}},t.toSVGMatrix=function(t,e){return t.a=e.a,t.b=e.b,t.c=e.c,t.d=e.d,t.e=e.e,t.f=e.f,t},t}(),h=function(t){function i(i){var s=t.call(this,i)||this;return s.left=0,s.top=0,s.width=0,s.height=0,s.defaultSize={x:50,y:20},s.offsetX=0,s.offsetY=0,s.rotationAngle=0,s.container.transform.baseVal.appendItem(e.createTransform()),s}return r(i,t),Object.defineProperty(i.prototype,"centerX",{get:function(){return this.left+this.width/2},enumerable:!1,configurable:!0}),Object.defineProperty(i.prototype,"centerY",{get:function(){return this.top+this.height/2},enumerable:!1,configurable:!0}),Object.defineProperty(i.prototype,"visual",{get:function(){return this._visual},set:function(t){this._visual=t;var i=e.createTransform();this._visual.transform.baseVal.appendItem(i)},enumerable:!1,configurable:!0}),i.prototype.ownsTarget=function(e){return!!t.prototype.ownsTarget.call(this,e)},i.prototype.pointerDown=function(e,i){t.prototype.pointerDown.call(this,e,i),this.select()},i.prototype.pointerUp=function(e){t.prototype.pointerUp.call(this,e)},i.prototype.moveVisual=function(t){this.visual.style.transform="translate("+t.x+"px, "+t.y+"px)"},i.prototype.resize=function(t){this.setSize()},i.prototype.setSize=function(){this.moveVisual({x:this.left,y:this.top})},i.prototype.rotate=function(t){if(Math.abs(t.x-this.centerX)>.1){var e=Math.sign(t.x-this.centerX);this.rotationAngle=180*Math.atan((t.y-this.centerY)/(t.x-this.centerX))/Math.PI+90*e,this.applyRotation()}},i.prototype.applyRotation=function(){var t=this.container.transform.baseVal.getItem(0);t.setRotate(this.rotationAngle,this.centerX,this.centerY),this.container.transform.baseVal.replaceItem(t,0)},i.prototype.rotatePoint=function(t){if(0===this.rotationAngle)return t;var i=this.container.getCTM(),s=e.createPoint(t.x,t.y);return{x:(s=s.matrixTransform(i)).x,y:s.y}},i.prototype.unrotatePoint=function(t){if(0===this.rotationAngle)return t;var i=this.container.getCTM();i=i.inverse();var s=e.createPoint(t.x,t.y);return{x:(s=s.matrixTransform(i)).x,y:s.y}},i.prototype.select=function(){t.prototype.select.call(this)},i.prototype.deselect=function(){t.prototype.deselect.call(this)},i.prototype.restoreState=function(e){t.prototype.restoreState.call(this,e);var i=e;this.left=i.left,this.top=i.top,this.width=i.width,this.height=i.height,this.rotationAngle=i.rotationAngle,this.visual.transform.baseVal.getItem(0).setMatrix(n.toSVGMatrix(this.visual.transform.baseVal.getItem(0).matrix,i.visualTransformMatrix)),this.container.transform.baseVal.getItem(0).setMatrix(n.toSVGMatrix(this.container.transform.baseVal.getItem(0).matrix,i.containerTransformMatrix))},i.prototype.scale=function(e,i){t.prototype.scale.call(this,e,i);var s=this.rotatePoint({x:this.left,y:this.top}),r=this.unrotatePoint({x:s.x*e,y:s.y*i});this.left=r.x,this.top=r.y,this.width=this.width*e,this.height=this.height*i},i}(o),a=function(t){function i(e){var i=t.call(this,e)||this;return i.fillColor="transparent",i.strokeColor="transparent",i.strokeWidth=0,i.strokeDasharray="",i.opacity=1,i.setStrokeColor=i.setStrokeColor.bind(i),i.setFillColor=i.setFillColor.bind(i),i.setStrokeWidth=i.setStrokeWidth.bind(i),i.setStrokeDasharray=i.setStrokeDasharray.bind(i),i.createVisual=i.createVisual.bind(i),i}return r(i,t),i.prototype.ownsTarget=function(e){return!(!t.prototype.ownsTarget.call(this,e)&&e!==this.visual)},i.prototype.createVisual=function(){this.visual=e.createRect(1,1,[["fill",this.fillColor],["stroke",this.strokeColor],["stroke-width",this.strokeWidth.toString()],["stroke-dasharray",this.strokeDasharray],["opacity",this.opacity.toString()]]),this.addMarkerVisualToContainer(this.visual)},i.prototype.pointerDown=function(e,i){t.prototype.pointerDown.call(this,e,i)},i.prototype.resize=function(e){t.prototype.resize.call(this,e),this.setSize()},i.prototype.setSize=function(){t.prototype.setSize.call(this),e.setAttributes(this.visual,[["width",this.width.toString()],["height",this.height.toString()]])},i.prototype.pointerUp=function(e){t.prototype.pointerUp.call(this,e),this.setSize()},i.prototype.setStrokeColor=function(t){this.strokeColor=t,this.visual&&e.setAttributes(this.visual,[["stroke",this.strokeColor]])},i.prototype.setFillColor=function(t){this.fillColor=t,this.visual&&e.setAttributes(this.visual,[["fill",this.fillColor]])},i.prototype.setStrokeWidth=function(t){this.strokeWidth=t,this.visual&&e.setAttributes(this.visual,[["stroke-width",this.strokeWidth.toString()]])},i.prototype.setStrokeDasharray=function(t){this.strokeDasharray=t,this.visual&&e.setAttributes(this.visual,[["stroke-dasharray",this.strokeDasharray]])},i.prototype.restoreState=function(e){var i=e;this.fillColor=i.fillColor,this.strokeColor=i.strokeColor,this.strokeWidth=i.strokeWidth,this.strokeDasharray=i.strokeDasharray,this.opacity=i.opacity,this.createVisual(),t.prototype.restoreState.call(this,e),this.setSize()},i.prototype.scale=function(e,i){t.prototype.scale.call(this,e,i),this.setSize()},i.title="Rectangle marker",i}(h),l=function(t){function e(e){return t.call(this,e)||this}return r(e,t),e.typeName="FrameMarker",e.title="Frame marker",e}(a),p=function(t){function e(e){var i=t.call(this,e)||this;return i.x1=0,i.y1=0,i.x2=0,i.y2=0,i.defaultLength=50,i}return r(e,t),e.prototype.ownsTarget=function(e){return!!t.prototype.ownsTarget.call(this,e)},e.prototype.pointerDown=function(e,i){t.prototype.pointerDown.call(this,e,i)},e.prototype.pointerUp=function(e){t.prototype.pointerUp.call(this,e)},e.prototype.adjustVisual=function(){},e.prototype.resize=function(t){this.adjustVisual()},e.prototype.select=function(){t.prototype.select.call(this)},e.prototype.deselect=function(){t.prototype.deselect.call(this)},e.prototype.restoreState=function(e){t.prototype.restoreState.call(this,e);var i=e;this.x1=i.x1,this.y1=i.y1,this.x2=i.x2,this.y2=i.y2},e.prototype.scale=function(e,i){t.prototype.scale.call(this,e,i),this.x1=this.x1*e,this.y1=this.y1*i,this.x2=this.x2*e,this.y2=this.y2*i,this.adjustVisual()},e}(o),c=function(t){function i(e){var i=t.call(this,e)||this;return i.strokeColor="transparent",i.strokeWidth=0,i.strokeDasharray="",i.setStrokeColor=i.setStrokeColor.bind(i),i.setStrokeWidth=i.setStrokeWidth.bind(i),i.setStrokeDasharray=i.setStrokeDasharray.bind(i),i}return r(i,t),i.prototype.ownsTarget=function(e){return!(!t.prototype.ownsTarget.call(this,e)&&e!==this.visual&&e!==this.selectorLine&&e!==this.visibleLine)},i.prototype.createVisual=function(){this.visual=e.createGroup(),this.selectorLine=e.createLine(this.x1,this.y1,this.x2,this.y2,[["stroke","transparent"],["stroke-width",(this.strokeWidth+10).toString()]]),this.visibleLine=e.createLine(this.x1,this.y1,this.x2,this.y2,[["stroke",this.strokeColor],["stroke-width",this.strokeWidth.toString()]]),this.visual.appendChild(this.selectorLine),this.visual.appendChild(this.visibleLine),this.addMarkerVisualToContainer(this.visual)},i.prototype.pointerDown=function(e,i){t.prototype.pointerDown.call(this,e,i)},i.prototype.adjustVisual=function(){this.selectorLine.setAttribute("x1",this.x1.toString()),this.selectorLine.setAttribute("y1",this.y1.toString()),this.selectorLine.setAttribute("x2",this.x2.toString()),this.selectorLine.setAttribute("y2",this.y2.toString()),this.visibleLine.setAttribute("x1",this.x1.toString()),this.visibleLine.setAttribute("y1",this.y1.toString()),this.visibleLine.setAttribute("x2",this.x2.toString()),this.visibleLine.setAttribute("y2",this.y2.toString()),e.setAttributes(this.visibleLine,[["stroke",this.strokeColor]]),e.setAttributes(this.visibleLine,[["stroke-width",this.strokeWidth.toString()]]),e.setAttributes(this.visibleLine,[["stroke-dasharray",this.strokeDasharray.toString()]])},i.prototype.setStrokeColor=function(t){this.strokeColor=t,this.adjustVisual()},i.prototype.setStrokeWidth=function(t){this.strokeWidth=t,this.adjustVisual()},i.prototype.setStrokeDasharray=function(t){this.strokeDasharray=t,this.adjustVisual()},i.prototype.restoreState=function(e){t.prototype.restoreState.call(this,e);var i=e;this.strokeColor=i.strokeColor,this.strokeWidth=i.strokeWidth,this.strokeDasharray=i.strokeDasharray,this.createVisual(),this.adjustVisual()},i.typeName="LineMarker",i.title="Line marker",i}(p),u=function(t){function i(e){var i=t.call(this,e)||this;return i.color="transparent",i.padding=5,i.text="",i.defaultSize={x:100,y:30},i.setColor=i.setColor.bind(i),i.setFont=i.setFont.bind(i),i.renderText=i.renderText.bind(i),i.sizeText=i.sizeText.bind(i),i.setSize=i.setSize.bind(i),i}return r(i,t),i.prototype.ownsTarget=function(e){if(t.prototype.ownsTarget.call(this,e)||e===this.visual||e===this.textElement||e===this.bgRectangle)return!0;var i=!1;return this.textElement.childNodes.forEach((function(t){t===e&&(i=!0)})),i},i.prototype.createVisual=function(){this.visual=e.createGroup(),this.bgRectangle=e.createRect(1,1,[["fill","transparent"]]),this.visual.appendChild(this.bgRectangle),this.textElement=e.createText([["fill",this.color],["font-family",this.fontFamily],["font-size","16px"],["x","0"],["y","0"]]),this.textElement.transform.baseVal.appendItem(e.createTransform()),this.textElement.transform.baseVal.appendItem(e.createTransform()),this.visual.appendChild(this.textElement),this.addMarkerVisualToContainer(this.visual),this.renderText()},i.prototype.pointerDown=function(e,i){t.prototype.pointerDown.call(this,e,i),this.pointerDownPoint=e},i.prototype.renderText=function(){for(var t=this;this.textElement.lastChild;)this.textElement.removeChild(this.textElement.lastChild);this.text.split(/\r\n|[\n\v\f\r\x85\u2028\u2029]/).forEach((function(i){t.textElement.appendChild(e.createTSpan(""===i.trim()?" ":i.trim(),[["x","0"],["dy","1.2em"]]))})),setTimeout(this.sizeText,10)},i.prototype.getTextScale=function(){var t=this.textElement.getBBox(),e=1;if(t.width>0&&t.height>0){var i=(1*this.width-this.width*this.padding*2/100)/t.width,s=(1*this.height-this.height*this.padding*2/100)/t.height;e=Math.min(i,s)}return e},i.prototype.getTextPosition=function(t){var e=this.textElement.getBBox(),i=0,s=0;return e.width>0&&e.height>0&&(i=(this.width-e.width*t)/2,s=this.height/2-e.height*t/2),{x:i,y:s}},i.prototype.sizeText=function(){var t=this.textElement.getBBox(),e=this.getTextScale(),i=this.getTextPosition(e);i.y-=t.y*e,navigator.userAgent.indexOf("Edge/")>-1?this.textElement.style.transform="translate("+i.x+"px, "+i.y+"px) scale("+e+", "+e+")":(this.textElement.transform.baseVal.getItem(0).setTranslate(i.x,i.y),this.textElement.transform.baseVal.getItem(1).setScale(e,e))},i.prototype.resize=function(e){t.prototype.resize.call(this,e),this.setSize(),this.sizeText()},i.prototype.setSize=function(){t.prototype.setSize.call(this),e.setAttributes(this.visual,[["width",this.width.toString()],["height",this.height.toString()]]),e.setAttributes(this.bgRectangle,[["width",this.width.toString()],["height",this.height.toString()]])},i.prototype.pointerUp=function(e){t.prototype.pointerUp.call(this,e),this.setSize()},i.prototype.deselect=function(){t.prototype.deselect.call(this)},i.prototype.dblClick=function(e,i){t.prototype.dblClick.call(this,e,i)},i.prototype.setColor=function(t){e.setAttributes(this.textElement,[["fill",t]]),this.color=t},i.prototype.setFont=function(t){e.setAttributes(this.textElement,[["font-family",t]]),this.fontFamily=t,this.renderText()},i.prototype.restoreState=function(e){var i=e;this.color=i.color,this.fontFamily=i.fontFamily,this.padding=i.padding,this.text=i.text,this.createVisual(),t.prototype.restoreState.call(this,e),this.setSize()},i.prototype.scale=function(e,i){t.prototype.scale.call(this,e,i),this.setSize(),this.sizeText()},i.typeName="TextMarker",i.title="Text marker",i}(h),d=function(t){function i(e){var i=t.call(this,e)||this;return i.color="transparent",i.lineWidth=3,i}return r(i,t),i.prototype.ownsTarget=function(e){return!(!t.prototype.ownsTarget.call(this,e)&&e!==this.visual&&e!==this.drawingImage)},i.prototype.createVisual=function(){this.visual=e.createGroup(),this.drawingImage=e.createImage(),this.visual.appendChild(this.drawingImage);var t=e.createTransform();this.visual.transform.baseVal.appendItem(t),this.addMarkerVisualToContainer(this.visual)},i.prototype.pointerDown=function(e,i){t.prototype.pointerDown.call(this,e,i)},i.prototype.resize=function(i){t.prototype.resize.call(this,i),e.setAttributes(this.visual,[["width",this.width.toString()],["height",this.height.toString()]]),e.setAttributes(this.drawingImage,[["width",this.width.toString()],["height",this.height.toString()]])},i.prototype.pointerUp=function(e){t.prototype.pointerUp.call(this,e)},i.prototype.select=function(){t.prototype.select.call(this)},i.prototype.deselect=function(){t.prototype.deselect.call(this)},i.prototype.setDrawingImage=function(){e.setAttributes(this.drawingImage,[["width",this.width.toString()],["height",this.height.toString()]]),e.setAttributes(this.drawingImage,[["href",this.drawingImgUrl]]),this.moveVisual({x:this.left,y:this.top})},i.prototype.restoreState=function(e){this.createVisual(),t.prototype.restoreState.call(this,e),this.drawingImgUrl=e.drawingImgUrl,this.setDrawingImage()},i.prototype.scale=function(e,i){t.prototype.scale.call(this,e,i),this.setDrawingImage()},i.typeName="FreehandMarker",i.title="Freehand marker",i}(h),y=function(t){function i(e){var i=t.call(this,e)||this;return i.arrowType="end",i.arrowBaseHeight=10,i.arrowBaseWidth=10,i.getArrowPoints=i.getArrowPoints.bind(i),i.setArrowType=i.setArrowType.bind(i),i}return r(i,t),i.prototype.ownsTarget=function(e){return!(!t.prototype.ownsTarget.call(this,e)&&e!==this.arrow1&&e!==this.arrow2)},i.prototype.getArrowPoints=function(t,e){var i=this.arrowBaseWidth+2*this.strokeWidth,s=this.arrowBaseHeight+2*this.strokeWidth;return t-i/2+","+(e+s/2)+" "+t+","+(e-s/2)+" "+(t+i/2)+","+(e+s/2)},i.prototype.createTips=function(){this.arrow1=e.createPolygon(this.getArrowPoints(this.x1,this.y1),[["fill",this.strokeColor]]),this.arrow1.transform.baseVal.appendItem(e.createTransform()),this.visual.appendChild(this.arrow1),this.arrow2=e.createPolygon(this.getArrowPoints(this.x2,this.y2),[["fill",this.strokeColor]]),this.arrow2.transform.baseVal.appendItem(e.createTransform()),this.visual.appendChild(this.arrow2)},i.prototype.pointerDown=function(e,i){t.prototype.pointerDown.call(this,e,i)},i.prototype.adjustVisual=function(){if(t.prototype.adjustVisual.call(this),this.arrow1&&this.arrow2&&(this.arrow1.style.display="both"===this.arrowType||"start"===this.arrowType?"":"none",this.arrow2.style.display="both"===this.arrowType||"end"===this.arrowType?"":"none",e.setAttributes(this.arrow1,[["points",this.getArrowPoints(this.x1,this.y1)],["fill",this.strokeColor]]),e.setAttributes(this.arrow2,[["points",this.getArrowPoints(this.x2,this.y2)],["fill",this.strokeColor]]),Math.abs(this.x1-this.x2)>.1)){var i=180*Math.atan((this.y2-this.y1)/(this.x2-this.x1))/Math.PI+90*Math.sign(this.x1-this.x2),s=this.arrow1.transform.baseVal.getItem(0);s.setRotate(i,this.x1,this.y1),this.arrow1.transform.baseVal.replaceItem(s,0);var r=this.arrow2.transform.baseVal.getItem(0);r.setRotate(i+180,this.x2,this.y2),this.arrow2.transform.baseVal.replaceItem(r,0)}},i.prototype.setArrowType=function(t){this.arrowType=t,this.adjustVisual()},i.prototype.restoreState=function(e){t.prototype.restoreState.call(this,e);var i=e;this.arrowType=i.arrowType,this.createTips(),this.adjustVisual()},i.typeName="ArrowMarker",i.title="Arrow marker",i}(c),g=function(t){function e(e){var i=t.call(this,e)||this;return i.strokeWidth=0,i}return r(e,t),e.typeName="CoverMarker",e.title="Cover marker",e}(a),f=function(t){function i(e){var i=t.call(this,e)||this;return i.setOpacity=i.setOpacity.bind(i),i.strokeWidth=0,i}return r(i,t),i.prototype.setOpacity=function(t){this.opacity=t,this.visual&&e.setAttributes(this.visual,[["opacity",this.opacity.toString()]])},i.typeName="HighlightMarker",i.title="Highlight marker",i}(g),v=function(t){function i(e){var i=t.call(this,e)||this;return i.bgColor="transparent",i.tipPosition={x:0,y:0},i.tipBase1Position={x:0,y:0},i.tipBase2Position={x:0,y:0},i.defaultSize={x:100,y:30},i.setBgColor=i.setBgColor.bind(i),i.getTipPoints=i.getTipPoints.bind(i),i.positionTip=i.positionTip.bind(i),i.setTipPoints=i.setTipPoints.bind(i),i}return r(i,t),i.prototype.ownsTarget=function(e){return t.prototype.ownsTarget.call(this,e)||this.tip===e},i.prototype.createTip=function(){e.setAttributes(this.bgRectangle,[["fill",this.bgColor],["rx","10px"]]),this.tip=e.createPolygon(this.getTipPoints(),[["fill",this.bgColor]]),this.visual.appendChild(this.tip)},i.prototype.pointerDown=function(e,i){t.prototype.pointerDown.call(this,e,i)},i.prototype.pointerUp=function(e){t.prototype.pointerUp.call(this,e)},i.prototype.setBgColor=function(t){e.setAttributes(this.bgRectangle,[["fill",t]]),e.setAttributes(this.tip,[["fill",t]]),this.bgColor=t},i.prototype.getTipPoints=function(){return this.setTipPoints(),this.tipBase1Position.x+","+this.tipBase1Position.y+" "+this.tipBase2Position.x+","+this.tipBase2Position.y+" "+this.tipPosition.x+","+this.tipPosition.y},i.prototype.setTipPoints=function(t){void 0===t&&(t=!1);var e=Math.min(this.height/2,15),i=this.height/5;t&&(this.tipPosition={x:e+i/2,y:this.height+20});var s=Math.atan(this.height/2/(this.width/2));if(this.tipPosition.x<this.width/2&&this.tipPosition.y<this.height/2)s<Math.atan((this.height/2-this.tipPosition.y)/(this.width/2-this.tipPosition.x))?(i=this.width/5,e=Math.min(this.width/2,15),this.tipBase1Position={x:e,y:0},this.tipBase2Position={x:e+i,y:0}):(this.tipBase1Position={x:0,y:e},this.tipBase2Position={x:0,y:e+i});else if(this.tipPosition.x>=this.width/2&&this.tipPosition.y<this.height/2){s<Math.atan((this.height/2-this.tipPosition.y)/(this.tipPosition.x-this.width/2))?(i=this.width/5,e=Math.min(this.width/2,15),this.tipBase1Position={x:this.width-e-i,y:0},this.tipBase2Position={x:this.width-e,y:0}):(this.tipBase1Position={x:this.width,y:e},this.tipBase2Position={x:this.width,y:e+i})}else if(this.tipPosition.x>=this.width/2&&this.tipPosition.y>=this.height/2){s<Math.atan((this.tipPosition.y-this.height/2)/(this.tipPosition.x-this.width/2))?(i=this.width/5,e=Math.min(this.width/2,15),this.tipBase1Position={x:this.width-e-i,y:this.height},this.tipBase2Position={x:this.width-e,y:this.height}):(this.tipBase1Position={x:this.width,y:this.height-e-i},this.tipBase2Position={x:this.width,y:this.height-e})}else{s<Math.atan((this.tipPosition.y-this.height/2)/(this.width/2-this.tipPosition.x))?(i=this.width/5,e=Math.min(this.width/2,15),this.tipBase1Position={x:e,y:this.height},this.tipBase2Position={x:e+i,y:this.height}):(this.tipBase1Position={x:0,y:this.height-e},this.tipBase2Position={x:0,y:this.height-e-i})}},i.prototype.resize=function(e){t.prototype.resize.call(this,e),this.positionTip()},i.prototype.positionTip=function(){e.setAttributes(this.tip,[["points",this.getTipPoints()]])},i.prototype.select=function(){this.positionTip(),t.prototype.select.call(this)},i.prototype.restoreState=function(e){var i=e;this.bgColor=i.bgColor,this.tipPosition=i.tipPosition,t.prototype.restoreState.call(this,e),this.createTip(),this.setTipPoints()},i.prototype.scale=function(e,i){t.prototype.scale.call(this,e,i),this.tipPosition={x:this.tipPosition.x*e,y:this.tipPosition.y*i},this.positionTip()},i.typeName="CalloutMarker",i.title="Callout marker",i}(u),m=function(t){function i(e){var i=t.call(this,e)||this;return i.fillColor="transparent",i.strokeColor="transparent",i.strokeWidth=0,i.strokeDasharray="",i.opacity=1,i.setStrokeColor=i.setStrokeColor.bind(i),i.setFillColor=i.setFillColor.bind(i),i.setStrokeWidth=i.setStrokeWidth.bind(i),i.setStrokeDasharray=i.setStrokeDasharray.bind(i),i.setOpacity=i.setOpacity.bind(i),i.createVisual=i.createVisual.bind(i),i}return r(i,t),i.prototype.ownsTarget=function(e){return!(!t.prototype.ownsTarget.call(this,e)&&e!==this.visual)},i.prototype.createVisual=function(){this.visual=e.createEllipse(this.width/2,this.height/2,[["fill",this.fillColor],["stroke",this.strokeColor],["stroke-width",this.strokeWidth.toString()],["stroke-dasharray",this.strokeDasharray],["opacity",this.opacity.toString()]]),this.addMarkerVisualToContainer(this.visual)},i.prototype.pointerDown=function(e,i){t.prototype.pointerDown.call(this,e,i)},i.prototype.resize=function(e){t.prototype.resize.call(this,e),this.setSize()},i.prototype.setSize=function(){t.prototype.setSize.call(this),e.setAttributes(this.visual,[["cx",(this.width/2).toString()],["cy",(this.height/2).toString()],["rx",(this.width/2).toString()],["ry",(this.height/2).toString()]])},i.prototype.pointerUp=function(e){t.prototype.pointerUp.call(this,e),this.setSize()},i.prototype.setStrokeColor=function(t){this.strokeColor=t,this.visual&&e.setAttributes(this.visual,[["stroke",this.strokeColor]])},i.prototype.setFillColor=function(t){this.fillColor=t,this.visual&&e.setAttributes(this.visual,[["fill",this.fillColor]])},i.prototype.setStrokeWidth=function(t){this.strokeWidth=t,this.visual&&e.setAttributes(this.visual,[["stroke-width",this.strokeWidth.toString()]])},i.prototype.setStrokeDasharray=function(t){this.strokeDasharray=t,this.visual&&e.setAttributes(this.visual,[["stroke-dasharray",this.strokeDasharray]])},i.prototype.setOpacity=function(t){this.opacity=t,this.visual&&e.setAttributes(this.visual,[["opacity",this.opacity.toString()]])},i.prototype.restoreState=function(e){var i=e;this.fillColor=i.fillColor,this.strokeColor=i.strokeColor,this.strokeWidth=i.strokeWidth,this.strokeDasharray=i.strokeDasharray,this.opacity=i.opacity,this.createVisual(),t.prototype.restoreState.call(this,e),this.setSize()},i.prototype.scale=function(e,i){t.prototype.scale.call(this,e,i),this.setSize()},i.typeName="EllipseMarker",i.title="Ellipse marker",i}(h),k=function(t){function i(e){return t.call(this,e)||this}return r(i,t),Object.defineProperty(i.prototype,"tipLength",{get:function(){return 10+3*this.strokeWidth},enumerable:!1,configurable:!0}),i.prototype.ownsTarget=function(e){return!(!t.prototype.ownsTarget.call(this,e)&&e!==this.tip1&&e!==this.tip2)},i.prototype.createTips=function(){this.tip1=e.createLine(this.x1-this.tipLength/2,this.y1,this.x1+this.tipLength/2,this.y1,[["stroke",this.strokeColor],["stroke-width",this.strokeWidth.toString()]]),this.tip1.transform.baseVal.appendItem(e.createTransform()),this.visual.appendChild(this.tip1),this.tip2=e.createLine(this.x2-this.tipLength/2,this.y2,this.x2+this.tipLength/2,this.y2,[["stroke",this.strokeColor],["stroke-width",this.strokeWidth.toString()]]),this.tip2.transform.baseVal.appendItem(e.createTransform()),this.visual.appendChild(this.tip2)},i.prototype.pointerDown=function(e,i){t.prototype.pointerDown.call(this,e,i)},i.prototype.adjustVisual=function(){if(t.prototype.adjustVisual.call(this),this.tip1&&this.tip2&&(e.setAttributes(this.tip1,[["x1",(this.x1-this.tipLength/2).toString()],["y1",this.y1.toString()],["x2",(this.x1+this.tipLength/2).toString()],["y2",this.y1.toString()],["stroke",this.strokeColor],["stroke-width",this.strokeWidth.toString()]]),e.setAttributes(this.tip2,[["x1",(this.x2-this.tipLength/2).toString()],["y1",this.y2.toString()],["x2",(this.x2+this.tipLength/2).toString()],["y2",this.y2.toString()],["stroke",this.strokeColor],["stroke-width",this.strokeWidth.toString()]]),Math.abs(this.x1-this.x2)>.1)){var i=180*Math.atan((this.y2-this.y1)/(this.x2-this.x1))/Math.PI+90*Math.sign(this.x1-this.x2),s=this.tip1.transform.baseVal.getItem(0);s.setRotate(i,this.x1,this.y1),this.tip1.transform.baseVal.replaceItem(s,0);var r=this.tip2.transform.baseVal.getItem(0);r.setRotate(i+180,this.x2,this.y2),this.tip2.transform.baseVal.replaceItem(r,0)}},i.prototype.restoreState=function(e){t.prototype.restoreState.call(this,e),this.createTips(),this.adjustVisual()},i.typeName="MeasurementMarker",i.title="Measurement marker",i}(c),w=function(t){function e(e){var i=t.call(this,e)||this;return i.fillColor="transparent",i}return r(e,t),e.typeName="EllipseFrameMarker",e.title="Ellipse frame marker",e}(m),b=function(t){function i(e){var i=t.call(this,e)||this;return i.strokeColor="transparent",i.strokeWidth=0,i.strokeDasharray="",i.curveX=0,i.curveY=0,i.setStrokeColor=i.setStrokeColor.bind(i),i.setStrokeWidth=i.setStrokeWidth.bind(i),i.setStrokeDasharray=i.setStrokeDasharray.bind(i),i.adjustVisual=i.adjustVisual.bind(i),i.resize=i.resize.bind(i),i}return r(i,t),i.prototype.ownsTarget=function(e){return!(!t.prototype.ownsTarget.call(this,e)&&e!==this.visual&&e!==this.selectorCurve&&e!==this.visibleCurve)},i.prototype.getPathD=function(){return"M "+this.x1+" "+this.y1+" Q "+this.curveX+" "+this.curveY+", "+this.x2+" "+this.y2},i.prototype.createVisual=function(){this.visual=e.createGroup(),this.selectorCurve=e.createPath(this.getPathD(),[["stroke","transparent"],["stroke-width",(this.strokeWidth+10).toString()],["fill","transparent"]]),this.visibleCurve=e.createPath(this.getPathD(),[["stroke",this.strokeColor],["stroke-width",this.strokeWidth.toString()],["fill","transparent"]]),this.visual.appendChild(this.selectorCurve),this.visual.appendChild(this.visibleCurve),this.addMarkerVisualToContainer(this.visual)},i.prototype.pointerDown=function(e,i){t.prototype.pointerDown.call(this,e,i)},i.prototype.adjustVisual=function(){this.selectorCurve.setAttribute("d",this.getPathD()),this.visibleCurve.setAttribute("d",this.getPathD()),e.setAttributes(this.visibleCurve,[["stroke",this.strokeColor]]),e.setAttributes(this.visibleCurve,[["stroke-width",this.strokeWidth.toString()]]),e.setAttributes(this.visibleCurve,[["stroke-dasharray",this.strokeDasharray.toString()]])},i.prototype.setStrokeColor=function(t){this.strokeColor=t,this.adjustVisual()},i.prototype.setStrokeWidth=function(t){this.strokeWidth=t,this.adjustVisual()},i.prototype.setStrokeDasharray=function(t){this.strokeDasharray=t,this.adjustVisual()},i.prototype.scale=function(e,i){this.curveX=this.curveX*e,this.curveY=this.curveY*i,t.prototype.scale.call(this,e,i)},i.prototype.restoreState=function(e){t.prototype.restoreState.call(this,e);var i=e;this.strokeColor=i.strokeColor,this.strokeWidth=i.strokeWidth,this.strokeDasharray=i.strokeDasharray,this.curveX=i.curveX,this.curveY=i.curveY,this.createVisual(),this.adjustVisual()},i.typeName="CurveMarker",i.title="Curve marker",i}(p),x=function(){function t(t){this._classNamePrefixBase="__markerjslive_",this.classes=[],this.rules=[],this._classNamePrefix=this._classNamePrefixBase+"_"+t+"_"}return Object.defineProperty(t.prototype,"classNamePrefixBase",{get:function(){return this._classNamePrefixBase},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"classNamePrefix",{get:function(){return this._classNamePrefix},enumerable:!1,configurable:!0}),t.prototype.addClass=function(t){return void 0===this.styleSheet&&this.addStyleSheet(),t.name=""+this.classNamePrefix+t.localName,this.classes.push(t),this.styleSheet.sheet.insertRule("."+t.name+" {"+t.style+"}",this.styleSheet.sheet.cssRules.length),t},t.prototype.addRule=function(t){void 0===this.styleSheet&&this.addStyleSheet(),this.rules.push(t),this.styleSheet.sheet.insertRule(t.selector+" {"+t.style+"}",this.styleSheet.sheet.cssRules.length)},t.prototype.addStyleSheet=function(){var t;this.styleSheet=document.createElement("style"),(null!==(t=this.styleSheetRoot)&&void 0!==t?t:document.head).appendChild(this.styleSheet)},t.prototype.removeStyleSheet=function(){var t;this.styleSheet&&((null!==(t=this.styleSheetRoot)&&void 0!==t?t:document.head).removeChild(this.styleSheet),this.styleSheet=void 0)},t}(),S=function(t,e){this.selector=t,this.style=e},C=function(t,e){this.localName=t,this.style=e},P=function(){function t(){this.create=[],this.close=[],this.load=[],this.select=[],this.over=[],this.pointerdown=[],this.pointermove=[],this.pointerup=[],this.pointerenter=[],this.pointerleave=[]}return t.prototype.addEventListener=function(t,e){this[t].push(e)},t.prototype.removeEventListener=function(t,e){var i=this[t].indexOf(e);i>-1&&this[t].splice(i,1)},t}(),T=function(){function t(e){this.touchPoints=0,this.availableMarkerTypes=[l,d,y,u,w,m,f,v,k,g,c,b],this.markers=[],this.isDragging=!1,this._isOpen=!1,this.plugins=[],this.MARKER_CONTAINER_CLASS_SUFFIX="marker-container",this.isPointerIn=!1,this.eventListeners=new P,this._instanceNo=t.instanceCounter++,this.styles=new x(this.instanceNo),this.target=e,this.targetRoot=document.body,this.open=this.open.bind(this),this.setTopLeft=this.setTopLeft.bind(this),this.addNewMarker=this.addNewMarker.bind(this),this.setCurrentMarker=this.setCurrentMarker.bind(this),this.onPointerDown=this.onPointerDown.bind(this),this.onDblClick=this.onDblClick.bind(this),this.onPointerMove=this.onPointerMove.bind(this),this.onPointerUp=this.onPointerUp.bind(this),this.onKeyUp=this.onKeyUp.bind(this),this.close=this.close.bind(this),this.closeUI=this.closeUI.bind(this),this.clientToLocalCoordinates=this.clientToLocalCoordinates.bind(this),this.onWindowResize=this.onWindowResize.bind(this),this.removeMarker=this.removeMarker.bind(this)}return Object.defineProperty(t.prototype,"instanceNo",{get:function(){return this._instanceNo},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"isOpen",{get:function(){return this._isOpen},enumerable:!1,configurable:!0}),t.prototype.open=function(){this.setupResizeObserver(),this.setEditingTarget(),this.setTopLeft(),this.initMarkerCanvas(),this.initOverlay(),this.attachEvents(),i.isLicensed||this.addLogo(),this._isOpen=!0},t.prototype.show=function(t){var e=this;this.showUI(),this.open(),this.plugins.forEach((function(t){return t.init(e)})),this.eventListeners.create.forEach((function(t){return t(e)})),this.restoreState(t),this.eventListeners.load.forEach((function(t){return t(e)}))},t.prototype.close=function(){var t=this;this.isOpen&&(this.coverDiv&&this.closeUI(),this.targetObserver&&this.targetObserver.unobserve(this.target),this._isOpen=!1,this.eventListeners.close.forEach((function(e){return e(t)})))},t.prototype.setupResizeObserver=function(){var t=this;window.ResizeObserver&&(this.targetObserver=new ResizeObserver((function(){t.resize(t.target.clientWidth,t.target.clientHeight)})),this.targetObserver.observe(this.target))},t.prototype.resize=function(t,e){var i=t/this.imageWidth,s=e/this.imageHeight;this.imageWidth=Math.round(t),this.imageHeight=Math.round(e),this.editingTarget.width=this.imageWidth,this.editingTarget.height=this.imageHeight,this.editingTarget.style.width=this.imageWidth+"px",this.editingTarget.style.height=this.imageHeight+"px",this.markerImage.setAttribute("width",this.imageWidth.toString()),this.markerImage.setAttribute("height",this.imageHeight.toString()),this.markerImage.setAttribute("viewBox","0 0 "+this.imageWidth.toString()+" "+this.imageHeight.toString()),this.markerImageHolder.style.width=this.imageWidth+"px",this.markerImageHolder.style.height=this.imageHeight+"px",this.overlayContainer.style.width=this.imageWidth+"px",this.overlayContainer.style.height=this.imageHeight+"px",this.coverDiv.style.width=this.imageWidth.toString()+"px",this.positionLogo(),this.scaleMarkers(i,s)},t.prototype.scaleMarkers=function(t,e){var i;this.currentMarker&&this.currentMarker instanceof u||(i=this.currentMarker,this.setCurrentMarker()),this.markers.forEach((function(i){return i.scale(t,e)})),void 0!==i&&this.setCurrentMarker(i)},t.prototype.setEditingTarget=function(){this.imageWidth=Math.round(this.target.clientWidth),this.imageHeight=Math.round(this.target.clientHeight),this.editingTarget.width=this.imageWidth,this.editingTarget.height=this.imageHeight,this.editingTarget.style.width=this.imageWidth+"px",this.editingTarget.style.height=this.imageHeight+"px"},t.prototype.setTopLeft=function(){var t=this.editingTarget.getBoundingClientRect(),e=this.editorCanvas.getBoundingClientRect();this.left=t.left-e.left,this.top=t.top-e.top},t.prototype.initMarkerCanvas=function(){this.markerImageHolder=document.createElement("div"),this.markerImageHolder.style.setProperty("touch-action","pinch-zoom"),this.markerImage=document.createElementNS("http://www.w3.org/2000/svg","svg"),this.markerImage.setAttribute("xmlns","http://www.w3.org/2000/svg"),this.markerImage.setAttribute("width",this.imageWidth.toString()),this.markerImage.setAttribute("height",this.imageHeight.toString()),this.markerImage.setAttribute("viewBox","0 0 "+this.imageWidth.toString()+" "+this.imageHeight.toString()),this.markerImage.style.pointerEvents="auto",this.markerImageHolder.style.position="absolute",this.markerImageHolder.style.width=this.imageWidth+"px",this.markerImageHolder.style.height=this.imageHeight+"px",this.markerImageHolder.style.transformOrigin="top left",this.positionMarkerImage(),this.defs=e.createDefs(),this.markerImage.appendChild(this.defs),this.markerImageHolder.appendChild(this.markerImage),this.editorCanvas.appendChild(this.markerImageHolder)},t.prototype.initOverlay=function(){this.overlayContainer=document.createElement("div"),this.overlayContainer.style.position="absolute",this.overlayContainer.style.left="0px",this.overlayContainer.style.top="0px",this.overlayContainer.style.width=this.imageWidth+"px",this.overlayContainer.style.height=this.imageHeight+"px",this.overlayContainer.style.display="flex",this.markerImageHolder.appendChild(this.overlayContainer)},t.prototype.positionMarkerImage=function(){this.markerImageHolder.style.top=this.top+"px",this.markerImageHolder.style.left=this.left+"px"},t.prototype.attachEvents=function(){var t=this;this.markerImage.addEventListener("pointerdown",this.onPointerDown),this.markerImage.addEventListener("dblclick",this.onDblClick),window.addEventListener("pointermove",this.onPointerMove),window.addEventListener("pointerup",this.onPointerUp),window.addEventListener("pointercancel",(function(){t.touchPoints>0&&t.touchPoints--})),window.addEventListener("pointerout",(function(){t.touchPoints>0&&t.touchPoints--})),window.addEventListener("pointerleave",this.onPointerUp),window.addEventListener("resize",this.onWindowResize),window.addEventListener("keyup",this.onKeyUp)},t.prototype.addLogo=function(){this.logoUI=document.createElement("div"),this.logoUI.style.display="inline-block",this.logoUI.style.margin="0px",this.logoUI.style.padding="0px",this.logoUI.style.fill="#333333";var t=document.createElement("a");t.href="https://markerjs.com/",t.target="_blank",t.innerHTML='<svg viewBox="0 0 112 96" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414"><path fill="#e5f20d" fill-opacity=".647" d="M0 40.386h111.96V95.62H0z"/><path d="M93.61 61.452c0 .987-.328 1.831-.987 2.53-.657.7-1.52 1.048-2.591 1.048-1.481 0-2.222-.74-2.222-2.22 0-16.617-.533-29.347-1.604-38.192-1.068-8.842-2.92-13.265-5.552-13.265-4.443 0-10.94 15.509-19.497 46.52v.124c0 .987-.328 1.831-.987 2.53-.657.7-1.52 1.048-2.592 1.048-1.48 0-2.22-.74-2.22-2.22 0-3.29.165-8.392.493-15.302.33-7.732.494-13.82.494-18.262 0-6.17-.186-10.55-.556-13.142-.37-2.591-1.172-3.887-2.406-3.887-2.796 0-6.333 5.12-10.612 15.363C38.494 34.367 34.01 46.44 29.32 60.34l-1.11 3.209a5.714 5.714 0 01-1.42 2.097c-.617.578-1.295.864-2.036.864-.987 0-1.644-.081-1.974-.247-.328-.162-.533-.656-.617-1.48-.41-4.03-.74-9.418-.987-16.165-.163-1.728-.329-4.566-.494-8.515-.822-13.901-1.562-23.3-2.221-28.196-.657-4.893-.987-7.628-.987-8.205 0-.657.33-1.44.987-2.345.659-.903 1.276-1.357 1.85-1.357 1.319 0 2.387.947 3.21 2.838.411.906.863 4.526 1.357 10.859.493 6.335.905 14.19 1.233 23.568l.617 18.88c4.527-13.983 9.216-26.673 14.068-38.068C45.65 6.686 50.093.988 54.123.988c2.715 0 4.566 1.974 5.553 5.923.987 3.949 1.481 9.667 1.481 17.152 0 3.949-.081 9.625-.247 17.029l-.123 5.676c3.373-11.762 6.725-21.634 10.057-29.615 3.331-7.979 6.685-11.97 10.056-11.97 8.475 0 12.71 18.757 12.71 56.269z" fill-rule="nonzero"/></svg>',t.title="Powered by marker.js",t.style.display="grid",t.style.alignItems="center",t.style.justifyItems="center",t.style.padding="3px",t.style.width="20px",t.style.height="20px",this.logoUI.appendChild(t),this.editorCanvas.appendChild(this.logoUI),this.logoUI.style.position="absolute",this.logoUI.style.pointerEvents="all",this.positionLogo()},t.prototype.positionLogo=function(){this.logoUI&&(this.logoUI.style.left=this.markerImageHolder.offsetLeft+10+"px",this.logoUI.style.top=this.markerImageHolder.offsetTop+this.markerImageHolder.offsetHeight-this.logoUI.clientHeight-10+"px")},t.prototype.showUI=function(){this.coverDiv=document.createElement("div"),this.coverDiv.className=this.styles.classNamePrefixBase+" "+this.styles.classNamePrefix,this.coverDiv.style.fontSize="16px",this.coverDiv.style.userSelect="none",this.coverDiv.style.position="absolute",this.coverDiv.style.top=this.target.offsetTop.toString()+"px",this.coverDiv.style.left=this.target.offsetLeft.toString()+"px",this.coverDiv.style.width=this.target.offsetWidth.toString()+"px",this.coverDiv.style.zIndex="5",this.targetRoot.appendChild(this.coverDiv),this.uiDiv=document.createElement("div"),this.uiDiv.style.display="flex",this.uiDiv.style.flexDirection="column",this.uiDiv.style.flexGrow="2",this.uiDiv.style.margin="0px",this.uiDiv.style.border="0px",this.coverDiv.appendChild(this.uiDiv),this.contentDiv=document.createElement("div"),this.contentDiv.style.display="flex",this.contentDiv.style.flexDirection="row",this.contentDiv.style.flexGrow="2",this.contentDiv.style.flexShrink="1",this.uiDiv.appendChild(this.contentDiv),this.editorCanvas=document.createElement("div"),this.editorCanvas.style.flexGrow="2",this.editorCanvas.style.flexShrink="1",this.editorCanvas.style.position="relative",this.editorCanvas.style.overflow="hidden",this.editorCanvas.style.display="flex",this.editorCanvas.style.pointerEvents="none",this.contentDiv.appendChild(this.editorCanvas),this.editingTarget=document.createElement("canvas"),this.editorCanvas.appendChild(this.editingTarget)},t.prototype.closeUI=function(){this.targetRoot.removeChild(this.coverDiv)},t.prototype.removeMarker=function(t){this.markerImage.removeChild(t.container),this.markers.indexOf(t)>-1&&this.markers.splice(this.markers.indexOf(t),1),t.dispose()},t.prototype.restoreState=function(t){var e=this;for(this.markers.splice(0);this.markerImage.lastChild;)this.markerImage.removeChild(this.markerImage.lastChild);t.markers.forEach((function(t){var i=e.availableMarkerTypes.find((function(e){return e.typeName===t.typeName}));if(void 0!==i){var s=e.addNewMarker(i);s.restoreState(t),e.markers.push(s)}})),t.width&&t.height&&(t.width!==this.imageWidth||t.height!==this.imageHeight)&&this.scaleMarkers(this.imageWidth/t.width,this.imageHeight/t.height)},t.prototype.addNewMarker=function(t){var i=e.createGroup();return i.setAttribute("class",""+this.styles.classNamePrefix+this.MARKER_CONTAINER_CLASS_SUFFIX),this.markerImage.appendChild(i),new t(i)},t.prototype.setCurrentMarker=function(t){var e=this,i=this.currentMarker!==t;void 0!==this.currentMarker&&this.currentMarker.deselect(),this.currentMarker=t,void 0!==this.currentMarker&&this.currentMarker.select(),i&&this.eventListeners.select.forEach((function(i){return i(e,t)}))},t.prototype.onPointerDown=function(t){var e=this;if(this.touchPoints++,1===this.touchPoints||"touch"!==t.pointerType){var i=this.markers.find((function(e){return e.ownsTarget(t.target)}));void 0!==i?(this.setCurrentMarker(i),this.isDragging=!0,this.currentMarker.pointerDown(this.clientToLocalCoordinates(t.clientX,t.clientY),t.target)):this.setCurrentMarker(),this.eventListeners.pointerdown.length>0&&this.eventListeners.pointerdown.forEach((function(s){return s(e,t,i)}))}},t.prototype.onDblClick=function(t){var e=this.markers.find((function(e){return e.ownsTarget(t.target)}));void 0!==e&&e!==this.currentMarker&&this.setCurrentMarker(e),void 0!==this.currentMarker?this.currentMarker.dblClick(this.clientToLocalCoordinates(t.clientX,t.clientY),t.target):this.setCurrentMarker()},t.prototype.onPointerMove=function(t){var e=this;if(1!==this.touchPoints&&"touch"===t.pointerType||(void 0!==this.currentMarker||this.isDragging)&&t.preventDefault(),this.eventListeners.over.length>0||this.eventListeners.pointermove.length>0){var i=this.markers.find((function(e){return e.ownsTarget(t.target)}));i!==this.hoveredMarker&&(this.hoveredMarker=i,this.eventListeners.over.forEach((function(t){return t(e,e.hoveredMarker)}))),this.eventListeners.pointermove.forEach((function(s){return s(e,t,i)})),this.isPointerIn||void 0===i&&this.markerImage!==t.target||(this.isPointerIn=!0,this.eventListeners.pointerenter.forEach((function(s){return s(e,t,i)}))),this.isPointerIn&&void 0===i&&this.markerImage!==t.target&&(this.isPointerIn=!1,this.eventListeners.pointerleave.forEach((function(s){return s(e,t,i)})))}},t.prototype.onPointerUp=function(t){var e=this;if(this.touchPoints>0&&this.touchPoints--,0===this.touchPoints&&this.isDragging&&void 0!==this.currentMarker&&this.currentMarker.pointerUp(this.clientToLocalCoordinates(t.clientX,t.clientY)),this.isDragging=!1,this.eventListeners.pointerup.length>0){var i=this.markers.find((function(e){return e.ownsTarget(t.target)}));this.eventListeners.pointerup.forEach((function(s){return s(e,t,i)}))}},t.prototype.onKeyUp=function(t){void 0===this.currentMarker||"Delete"!==t.key&&"Backspace"!==t.key||(this.removeMarker(this.currentMarker),this.setCurrentMarker(),this.markerImage.style.cursor="default")},t.prototype.clientToLocalCoordinates=function(t,e){var i=this.markerImage.getBoundingClientRect();return{x:t-i.left,y:e-i.top}},t.prototype.onWindowResize=function(){this.positionUI()},t.prototype.positionUI=function(){this.setTopLeft(),this.coverDiv.style.top=this.target.offsetTop.toString()+"px",this.coverDiv.style.left=this.target.offsetLeft.toString()+"px",this.positionMarkerImage(),this.positionLogo()},t.prototype.addEventListener=function(t,e){this.eventListeners.addEventListener(t,e)},t.prototype.removeEventListener=function(t,e){this.eventListeners.removeEventListener(t,e)},t.prototype.addPlugin=function(t){this.plugins.push(t)},t.prototype.removePlugin=function(t){var e=this.plugins.indexOf(t);e>=0&&this.plugins.splice(e,1)},t.instanceCounter=0,t}();t.Activator=i,t.ArrowMarker=y,t.CalloutMarker=v,t.CoverMarker=g,t.CurveMarker=b,t.EllipseFrameMarker=w,t.EllipseMarker=m,t.EventListenerRepository=P,t.FrameMarker=l,t.FreehandMarker=d,t.HighlightMarker=f,t.LineMarker=c,t.LinearMarkerBase=p,t.MarkerBase=o,t.MarkerView=T,t.MeasurementMarker=k,t.RectangleMarker=a,t.RectangularBoxMarkerBase=h,t.StyleClass=C,t.StyleManager=x,t.StyleRule=S,t.SvgHelper=e,t.TextMarker=u,t.TransformMatrix=n,Object.defineProperty(t,"__esModule",{value:!0})}));
+//# sourceMappingURL=markerjs-live.js.map
diff --git a/capsule-prototype/js/libs/markerjslive/markerjs-live.js.map b/capsule-prototype/js/libs/markerjslive/markerjs-live.js.map
new file mode 100644
index 0000000000000000000000000000000000000000..9b1af2842071afe0723bd6810968cf3a7de123f9
--- /dev/null
+++ b/capsule-prototype/js/libs/markerjslive/markerjs-live.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"markerjs-live.js","sources":["../src/core/SvgHelper.ts","../src/core/Activator.ts","../node_modules/tslib/tslib.es6.js","../src/core/MarkerBase.ts","../src/core/TransformMatrix.ts","../src/markers/RectangularBoxMarkerBase.ts","../src/markers/RectangleMarker.ts","../src/markers/frame-marker/FrameMarker.ts","../src/markers/LinearMarkerBase.ts","../src/markers/line-marker/LineMarker.ts","../src/markers/text-marker/TextMarker.ts","../src/markers/freehand-marker/FreehandMarker.ts","../src/markers/arrow-marker/ArrowMarker.ts","../src/markers/cover-marker/CoverMarker.ts","../src/markers/highlight-marker/HighlightMarker.ts","../src/markers/callout-marker/CalloutMarker.ts","../src/markers/ellipse-marker/EllipseMarker.ts","../src/markers/measurement-marker/MeasurementMarker.ts","../src/markers/ellipse-frame-marker/EllipseFrameMarker.ts","../src/markers/curve-marker/CurveMarker.ts","../src/core/Style.ts","../src/core/Events.ts","../src/MarkerView.ts"],"sourcesContent":["/**\n * Utility class to simplify SVG operations.\n */\nexport class SvgHelper {\n  /**\n   * Creates SVG \"defs\".\n   */\n  public static createDefs(): SVGDefsElement {\n    const defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');\n\n    return defs;\n  }\n\n  /**\n   * Creates SVG stylesheet.\n   */\n  public static createStylesheet(): SVGStyleElement {\n    const stylesheet = document.createElementNS('http://www.w3.org/2000/svg', 'style');\n    stylesheet.setAttribute('type', 'text/css');\n\n    return stylesheet;\n  }\n\n  /**\n   * Sets attributes on an arbitrary SVG element\n   * @param el - target SVG element.\n   * @param attributes - set of name-value attribute pairs.\n   */\n  public static setAttributes(\n    el: SVGElement,\n    attributes: Array<[string, string]>\n  ): void {\n    for (const [attr, value] of attributes) {\n      el.setAttribute(attr, value);\n    }\n  }\n\n  /**\n   * Creates an SVG rectangle with the specified width and height.\n   * @param width \n   * @param height \n   * @param attributes - additional attributes.\n   */\n  public static createRect(\n    width: number | string,\n    height: number | string,\n    attributes?: Array<[string, string]>\n  ): SVGRectElement {\n    const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');\n\n    rect.setAttribute('width', width.toString());\n    rect.setAttribute('height', height.toString());\n    if (attributes) {\n      SvgHelper.setAttributes(rect, attributes);\n    }\n\n    return rect;\n  }\n\n  /**\n   * Creates an SVG line with specified end-point coordinates.\n   * @param x1 \n   * @param y1 \n   * @param x2 \n   * @param y2 \n   * @param attributes - additional attributes.\n   */\n  public static createLine(\n    x1: number | string,\n    y1: number | string,\n    x2: number | string,\n    y2: number | string,\n    attributes?: Array<[string, string]>\n  ): SVGLineElement {\n    const line = document.createElementNS('http://www.w3.org/2000/svg', 'line');\n\n    line.setAttribute('x1', x1.toString());\n    line.setAttribute('y1', y1.toString());\n    line.setAttribute('x2', x2.toString());\n    line.setAttribute('y2', y2.toString());\n    if (attributes) {\n      SvgHelper.setAttributes(line, attributes);\n    }\n\n    return line;\n  }\n\n  /**\n   * Creates an SVG polygon with specified points.\n   * @param points - points as string.\n   * @param attributes - additional attributes.\n   */\n  public static createPolygon(\n    points: string,\n    attributes?: Array<[string, string]>\n  ): SVGPolygonElement {\n    const polygon = document.createElementNS(\n      'http://www.w3.org/2000/svg',\n      'polygon'\n    );\n\n    polygon.setAttribute('points', points);\n    if (attributes) {\n      SvgHelper.setAttributes(polygon, attributes);\n    }\n\n    return polygon;\n  }\n\n  /**\n   * Creates an SVG circle with the specified radius.\n   * @param radius \n   * @param attributes - additional attributes.\n   */\n  public static createCircle(\n    radius: number,\n    attributes?: Array<[string, string]>\n  ): SVGCircleElement {\n    const circle = document.createElementNS(\n      'http://www.w3.org/2000/svg',\n      'circle'\n    );\n\n    circle.setAttribute('cx', (radius / 2).toString());\n    circle.setAttribute('cy', (radius / 2).toString());\n    circle.setAttribute('r', radius.toString());\n    if (attributes) {\n      SvgHelper.setAttributes(circle, attributes);\n    }\n\n    return circle;\n  }\n\n  /**\n   * Creates an SVG ellipse with the specified horizontal and vertical radii.\n   * @param rx \n   * @param ry \n   * @param attributes - additional attributes.\n   */\n  public static createEllipse(\n    rx: number,\n    ry: number,\n    attributes?: Array<[string, string]>\n  ): SVGEllipseElement {\n    const ellipse = document.createElementNS(\n      'http://www.w3.org/2000/svg',\n      'ellipse'\n    );\n\n    ellipse.setAttribute('cx', (rx / 2).toString());\n    ellipse.setAttribute('cy', (ry / 2).toString());\n    ellipse.setAttribute('rx', (rx / 2).toString());\n    ellipse.setAttribute('ry', (ry / 2).toString());\n    if (attributes) {\n      SvgHelper.setAttributes(ellipse, attributes);\n    }\n\n    return ellipse;\n  }\n\n  /**\n   * Creates an SVG group.\n   * @param attributes - additional attributes.\n   */\n  public static createGroup(attributes?: Array<[string, string]>): SVGGElement {\n    const g = document.createElementNS('http://www.w3.org/2000/svg', 'g');\n    if (attributes) {\n      SvgHelper.setAttributes(g, attributes);\n    }\n    return g;\n  }\n\n  /**\n   * Creates an SVG transform.\n   */\n  public static createTransform(): SVGTransform {\n    const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n\n    return svg.createSVGTransform();\n  }\n\n  /**\n   * Creates an SVG marker.\n   * @param id \n   * @param orient \n   * @param markerWidth \n   * @param markerHeight \n   * @param refX \n   * @param refY \n   * @param markerElement \n   */\n  public static createMarker(\n    id: string,\n    orient: string,\n    markerWidth: number | string,\n    markerHeight: number | string,\n    refX: number | string,\n    refY: number | string,\n    markerElement: SVGGraphicsElement\n  ): SVGMarkerElement {\n    const marker = document.createElementNS(\n      'http://www.w3.org/2000/svg',\n      'marker'\n    );\n    SvgHelper.setAttributes(marker, [\n      ['id', id],\n      ['orient', orient],\n      ['markerWidth', markerWidth.toString()],\n      ['markerHeight', markerHeight.toString()],\n      ['refX', refX.toString()],\n      ['refY', refY.toString()],\n    ]);\n\n    marker.appendChild(markerElement);\n\n    return marker;\n  }\n\n  /**\n   * Creaes an SVG text element.\n   * @param attributes - additional attributes.\n   */\n  public static createText(\n    attributes?: Array<[string, string]>\n  ): SVGTextElement {\n    const text = document.createElementNS('http://www.w3.org/2000/svg', 'text');\n    text.setAttribute('x', '0');\n    text.setAttribute('y', '0');\n\n    if (attributes) {\n      SvgHelper.setAttributes(text, attributes);\n    }\n\n    return text;\n  }\n\n  /**\n   * Creates an SVG TSpan.\n   * @param text - inner text.\n   * @param attributes - additional attributes.\n   */\n  public static createTSpan(\n    text: string,\n    attributes?: Array<[string, string]>\n  ): SVGTSpanElement {\n    const tspan = document.createElementNS(\n      'http://www.w3.org/2000/svg',\n      'tspan'\n    );\n    tspan.textContent = text;\n\n    if (attributes) {\n      SvgHelper.setAttributes(tspan, attributes);\n    }\n\n    return tspan;\n  }\n\n  /**\n   * Creates an SVG image element.\n   * @param attributes - additional attributes.\n   */\n  public static createImage(\n    attributes?: Array<[string, string]>\n  ): SVGImageElement {\n    const image = document.createElementNS(\n      'http://www.w3.org/2000/svg',\n      'image'\n    );\n\n    if (attributes) {\n      SvgHelper.setAttributes(image, attributes);\n    }\n\n    return image;\n  }\n\n  /**\n   * Creates an SVG point with the specified coordinates.\n   * @param x \n   * @param y \n   */\n  public static createPoint(      \n    x: number,\n    y: number\n  ): SVGPoint {\n      const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n      const svgPoint = svg.createSVGPoint();\n      svgPoint.x = x;\n      svgPoint.y = y;\n  \n      return svgPoint;\n  }\n\n  /**\n   * Creates an SVG path with the specified shape (d).\n   * @param d - path shape\n   * @param attributes - additional attributes.\n   */\n   public static createPath(\n    d: string,\n    attributes?: Array<[string, string]>\n  ): SVGPathElement {\n    const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');\n\n    path.setAttribute('d', d);\n    if (attributes) {\n      SvgHelper.setAttributes(path, attributes);\n    }\n\n    return path;\n  }\n}\n","/**\n * Manages commercial marker.js Live licenses.\n */\nexport class Activator {\n  private static key: string;\n\n  /**\n   * Add a license key\n   * @param key license key sent to you after purchase.\n   */\n  public static addKey(key: string): void {\n    Activator.key = key;\n  }\n\n  /**\n   * Returns true if the copy of marker.js Live is commercially licensed.\n   */\n  public static get isLicensed(): boolean {\n    // NOTE:\n    // before removing or modifying this please consider supporting marker.js\n    // by visiting https://markerjs.com/ for details\n    // thank you!\n    if (Activator.key) {\n      const keyRegex = new RegExp(/^MJSL-[A-Z][0-9]{3}-[A-Z][0-9]{3}-[0-9]{4}$/, 'i');\n      return keyRegex.test(Activator.key);\n    } else {\n      return false;\n    }\n  }\n}\n","/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n    extendStatics = Object.setPrototypeOf ||\r\n        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n        function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n    return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n    extendStatics(d, b);\r\n    function __() { this.constructor = d; }\r\n    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n    __assign = Object.assign || function __assign(t) {\r\n        for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n            s = arguments[i];\r\n            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n        }\r\n        return t;\r\n    }\r\n    return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n    var t = {};\r\n    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n        t[p] = s[p];\r\n    if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n            if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n                t[p[i]] = s[p[i]];\r\n        }\r\n    return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n    if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n    return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n    return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n    if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n    return new (P || (P = Promise))(function (resolve, reject) {\r\n        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n        function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n        step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n    });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n    return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n    function verb(n) { return function (v) { return step([n, v]); }; }\r\n    function step(op) {\r\n        if (f) throw new TypeError(\"Generator is already executing.\");\r\n        while (_) try {\r\n            if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n            if (y = 0, t) op = [op[0] & 2, t.value];\r\n            switch (op[0]) {\r\n                case 0: case 1: t = op; break;\r\n                case 4: _.label++; return { value: op[1], done: false };\r\n                case 5: _.label++; y = op[1]; op = [0]; continue;\r\n                case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n                default:\r\n                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n                    if (t[2]) _.ops.pop();\r\n                    _.trys.pop(); continue;\r\n            }\r\n            op = body.call(thisArg, _);\r\n        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n    }\r\n}\r\n\r\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\r\n    if (k2 === undefined) k2 = k;\r\n    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\r\n}) : (function(o, m, k, k2) {\r\n    if (k2 === undefined) k2 = k;\r\n    o[k2] = m[k];\r\n});\r\n\r\nexport function __exportStar(m, o) {\r\n    for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n}\r\n\r\nexport function __values(o) {\r\n    var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n    if (m) return m.call(o);\r\n    if (o && typeof o.length === \"number\") return {\r\n        next: function () {\r\n            if (o && i >= o.length) o = void 0;\r\n            return { value: o && o[i++], done: !o };\r\n        }\r\n    };\r\n    throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n    var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n    if (!m) return o;\r\n    var i = m.call(o), r, ar = [], e;\r\n    try {\r\n        while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n    }\r\n    catch (error) { e = { error: error }; }\r\n    finally {\r\n        try {\r\n            if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n        }\r\n        finally { if (e) throw e.error; }\r\n    }\r\n    return ar;\r\n}\r\n\r\nexport function __spread() {\r\n    for (var ar = [], i = 0; i < arguments.length; i++)\r\n        ar = ar.concat(__read(arguments[i]));\r\n    return ar;\r\n}\r\n\r\nexport function __spreadArrays() {\r\n    for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n    for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n        for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n            r[k] = a[j];\r\n    return r;\r\n};\r\n\r\nexport function __await(v) {\r\n    return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n    if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n    var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n    return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n    function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n    function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n    function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n    function fulfill(value) { resume(\"next\", value); }\r\n    function reject(value) { resume(\"throw\", value); }\r\n    function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n    var i, p;\r\n    return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n    function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n    if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n    var m = o[Symbol.asyncIterator], i;\r\n    return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n    function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n    function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n    if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n    return cooked;\r\n};\r\n\r\nvar __setModuleDefault = Object.create ? (function(o, v) {\r\n    Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n    o[\"default\"] = v;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n    if (mod && mod.__esModule) return mod;\r\n    var result = {};\r\n    if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n    __setModuleDefault(result, mod);\r\n    return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n    return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, privateMap) {\r\n    if (!privateMap.has(receiver)) {\r\n        throw new TypeError(\"attempted to get private field on non-instance\");\r\n    }\r\n    return privateMap.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, privateMap, value) {\r\n    if (!privateMap.has(receiver)) {\r\n        throw new TypeError(\"attempted to set private field on non-instance\");\r\n    }\r\n    privateMap.set(receiver, value);\r\n    return value;\r\n}\r\n","import { SvgHelper } from './SvgHelper';\nimport { IPoint } from './IPoint';\nimport { MarkerBaseState } from './MarkerBaseState';\n\n/**\n * Base class for all available and custom marker types.\n * \n * All markers used with marker.js Live should be descendants of this class.\n */\nexport class MarkerBase {\n  /**\n   * String type name of the marker type. \n   * \n   * Used when adding {@link MarkerView.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static typeName = 'MarkerBase';\n\n  protected _outerContainer: SVGGElement;\n  /**\n   * Outer SVG group container not manipulated or transformed by the marker itself in any way\n   */\n  public get outerContainer(): SVGGElement {\n    return this._outerContainer;\n  }\n\n  protected _container: SVGGElement;\n  /**\n   * SVG container object holding the marker's visual.\n   */\n  public get container(): SVGGElement {\n    return this._container;\n  }\n\n  /**\n   * Additional information about the marker\n   */\n  public notes?: string;\n\n  /**\n   * Marker type title (display name) used for accessibility and other attributes.\n   */\n  public static title: string;\n\n  /**\n   * Method called when marker creation is finished.\n   */\n  public onMarkerCreated: (marker: MarkerBase) => void;\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   */\n  constructor(container: SVGGElement) {\n    this._outerContainer = container;\n    const innerContainer = SvgHelper.createGroup();\n    this._outerContainer.appendChild(innerContainer);\n    this._container = innerContainer;\n  }\n\n  /**\n   * Returns true if passed SVG element belongs to the marker. False otherwise.\n   * \n   * @param el - target element.\n   */\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars\n  public ownsTarget(el: EventTarget): boolean {\n    return false;\n  }\n\n  /**\n   * Selects this marker.\n   */\n  // eslint-disable-next-line @typescript-eslint/no-empty-function\n  public select(): void {}\n\n  /**\n   * Deselects this marker.\n   */\n  // eslint-disable-next-line @typescript-eslint/no-empty-function\n  public deselect(): void {}\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) down event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function\n  public pointerDown(point: IPoint, target?: EventTarget):void {}\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) double click event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function\n  public dblClick(point: IPoint, target?: EventTarget):void {}\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) up event.\n   * \n   * @param point - event coordinates.\n   */\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function\n  public pointerUp(point: IPoint):void {}\n\n  /**\n   * Disposes the marker and clean's up.\n   */\n  // eslint-disable-next-line @typescript-eslint/no-empty-function\n  public dispose(): void {}\n\n  /**\n   * Adds marker's root visual element to the container group.\n   * @param element - marker's visual element.\n   */\n  protected addMarkerVisualToContainer(element: SVGElement): void {\n    if (this.container.childNodes.length > 0) {\n      this.container.insertBefore(element, this.container.childNodes[0]);\n    } else {\n      this.container.appendChild(element);\n    }\n  }\n\n  /**\n   * Restores previously saved marker state.\n   * \n   * @param state - previously saved state.\n   */\n  public restoreState(state: MarkerBaseState): void {\n    this.notes = state.notes;\n  }\n\n  /**\n   * Scales marker. Used after the image resize.\n   * \n   * @param scaleX - horizontal scale\n   * @param scaleY - vertical scale\n   */\n  // eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars\n  public scale(scaleX: number, scaleY: number): void {}\n}\n","/**\n * Represents a simplified version of the SVGMatrix.\n */\nexport interface ITransformMatrix {\n  a: number;\n  b: number;\n  c: number;\n  d: number;\n  e: number;\n  f: number;\n}\n\n/**\n * A utility class to transform between SVGMatrix and its simplified representation.\n */\nexport class TransformMatrix {\n  public static toITransformMatrix(matrix: SVGMatrix): ITransformMatrix {\n    return {\n      a: matrix.a,\n      b: matrix.b,\n      c: matrix.c,\n      d: matrix.d,\n      e: matrix.e,\n      f: matrix.f\n    }\n  }\n  public static toSVGMatrix(currentMatrix: SVGMatrix, newMatrix: ITransformMatrix): SVGMatrix {\n    currentMatrix.a = newMatrix.a;\n    currentMatrix.b = newMatrix.b;\n    currentMatrix.c = newMatrix.c;\n    currentMatrix.d = newMatrix.d;\n    currentMatrix.e = newMatrix.e;\n    currentMatrix.f = newMatrix.f;\n    return currentMatrix;\n  }\n}","import { MarkerBase } from '../core/MarkerBase';\n\nimport { IPoint } from '../core/IPoint';\nimport { SvgHelper } from '../core/SvgHelper';\n\nimport { RectangularBoxMarkerBaseState } from './RectangularBoxMarkerBaseState';\nimport { MarkerBaseState } from '../core/MarkerBaseState';\nimport { TransformMatrix } from '../core/TransformMatrix';\n\n/**\n * RectangularBoxMarkerBase is a base class for all marker's with rectangular controls such as all rectangle markers,\n * text and callout markers.\n * \n * It creates and manages the rectangular control box and related resize, move, and rotate manipulations.\n */\nexport class RectangularBoxMarkerBase extends MarkerBase {\n  /**\n   * x coordinate of the top-left corner.\n   */\n  protected left = 0;\n  /**\n   * y coordinate of the top-left corner.\n   */\n  protected top = 0;\n  /**\n   * Marker width.\n   */\n  protected width = 0;\n  /**\n   * Marker height.\n   */\n  protected height = 0;\n\n  /**\n   * The default marker size when the marker is created with a click (without dragging).\n   */\n  protected defaultSize: IPoint = {x: 50, y: 20};\n\n  /**\n   * x coordinate of the top-left corner at the start of manipulation.\n   */\n  protected manipulationStartLeft: number;\n  /**\n   * y coordinate of the top-left corner at the start of manipulation.\n   */\n  protected manipulationStartTop: number;\n  /**\n   * Width at the start of manipulation.\n   */\n  protected manipulationStartWidth: number;\n  /**\n   * Height at the start of manipulation.\n   */\n  protected manipulationStartHeight: number;\n\n  /**\n   * x coordinate of the pointer at the start of manipulation.\n   */\n  protected manipulationStartX: number;\n  /**\n   * y coordinate of the pointer at the start of manipulation.\n   */\n  protected manipulationStartY: number;\n\n  /**\n   * Pointer's horizontal distance from the top left corner.\n   */\n  protected offsetX = 0;\n  /**\n   * Pointer's vertical distance from the top left corner.\n   */\n  protected offsetY = 0;\n\n  /**\n   * Marker's rotation angle.\n   */\n  protected rotationAngle = 0;\n\n  /**\n   * x coordinate of the marker's center.\n   */\n  protected get centerX(): number {\n    return this.left + this.width / 2;\n  }\n  /**\n   * y coordinate of the marker's center.\n   */\n  protected get centerY(): number {\n    return this.top + this.height / 2;\n  }\n\n  private _visual: SVGGraphicsElement;\n  /**\n   * Container for the marker's visual.\n   */\n  protected get visual(): SVGGraphicsElement {\n    return this._visual;\n  }\n  protected set visual(value: SVGGraphicsElement) {\n    this._visual = value;\n    const translate = SvgHelper.createTransform();\n    this._visual.transform.baseVal.appendItem(translate);\n  }\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   */\n  constructor(container: SVGGElement) {\n    super(container);\n\n    // add rotation transform\n    this.container.transform.baseVal.appendItem(SvgHelper.createTransform());\n  }\n\n  /**\n   * Returns true if passed SVG element belongs to the marker. False otherwise.\n   * \n   * @param el - target element.\n   */\n  public ownsTarget(el: EventTarget): boolean {\n    if (super.ownsTarget(el)) {\n      return true;\n    } else {\n      return false;\n    }\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) down event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerDown(point: IPoint, target?: EventTarget): void {\n    super.pointerDown(point, target);\n\n    this.select();\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) up event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerUp(point: IPoint): void {\n    super.pointerUp(point);\n  }\n\n  /**\n   * Moves visual to the specified coordinates.\n   * @param point - coordinates of the new top-left corner of the visual.\n   */\n  protected moveVisual(point: IPoint): void {\n    this.visual.style.transform = `translate(${point.x}px, ${point.y}px)`;\n    // const translate = this.visual.transform.baseVal.getItem(0);\n    // translate.setTranslate(point.x, point.y);\n    // this.visual.transform.baseVal.replaceItem(translate, 0);\n  }\n\n  /**\n   * Resizes the marker based on pointer coordinates and context.\n   * @param point - pointer coordinates.\n   */\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars\n  protected resize(point: IPoint): void {\n    this.setSize();\n  }\n\n  /**\n   * Sets control box size and location.\n   */\n  protected setSize(): void {\n    this.moveVisual({x: this.left, y: this.top});\n  }\n\n  private rotate(point: IPoint) {\n    // avoid glitch when crossing the 0 rotation point\n    if (Math.abs(point.x - this.centerX) > 0.1) {\n      const sign = Math.sign(point.x - this.centerX);\n      this.rotationAngle =\n        (Math.atan((point.y - this.centerY) / (point.x - this.centerX)) * 180) /\n          Math.PI +\n        90 * sign;\n      this.applyRotation();\n    }\n  }\n\n  private applyRotation() {\n    const rotate = this.container.transform.baseVal.getItem(0);\n    rotate.setRotate(this.rotationAngle, this.centerX, this.centerY);\n    this.container.transform.baseVal.replaceItem(rotate, 0);\n  }\n\n  /**\n   * Returns point coordinates based on the actual screen coordinates and marker's rotation.\n   * @param point - original pointer coordinates\n   */\n  protected rotatePoint(point: IPoint): IPoint {\n    if (this.rotationAngle === 0) {\n      return point;\n    }\n    \n    const matrix = this.container.getCTM();\n    let svgPoint = SvgHelper.createPoint(point.x, point.y);\n    svgPoint = svgPoint.matrixTransform(matrix);\n\n    const result = { x: svgPoint.x, y: svgPoint.y };\n\n    return result;\n  }\n\n  /**\n   * Returns original point coordinates based on coordinates with rotation applied.\n   * @param point - rotated point coordinates.\n   */\n  protected unrotatePoint(point: IPoint): IPoint {\n    if (this.rotationAngle === 0) {\n      return point;\n    }\n    \n    let matrix = this.container.getCTM();\n    matrix = matrix.inverse();\n    let svgPoint = SvgHelper.createPoint(point.x, point.y);\n    svgPoint = svgPoint.matrixTransform(matrix);\n\n    const result = { x: svgPoint.x, y: svgPoint.y };\n\n    return result;\n  }\n\n  /**\n   * Displays marker's controls.\n   */\n  public select(): void {\n    super.select();\n  }\n\n  /**\n   * Hides marker's controls.\n   */\n  public deselect(): void {\n    super.deselect();\n  }\n\n  /**\n   * Restores marker's state to the previously saved one.\n   * @param state - previously saved state.\n   */\n  public restoreState(state: MarkerBaseState): void {\n    super.restoreState(state);\n    const rbmState = state as RectangularBoxMarkerBaseState;\n    this.left = rbmState.left;\n    this.top = rbmState.top;\n    this.width = rbmState.width;\n    this.height = rbmState.height;\n    this.rotationAngle = rbmState.rotationAngle;\n    this.visual.transform.baseVal.getItem(0).setMatrix(\n      TransformMatrix.toSVGMatrix(this.visual.transform.baseVal.getItem(0).matrix, rbmState.visualTransformMatrix)\n    );\n    this.container.transform.baseVal.getItem(0).setMatrix(\n      TransformMatrix.toSVGMatrix(this.container.transform.baseVal.getItem(0).matrix, rbmState.containerTransformMatrix)\n    );\n    // this.moveVisual({x: this.left, y: this.top});\n    // this.applyRotation();\n  }\n\n  /**\n   * Scales marker. Used after the image resize.\n   * \n   * @param scaleX - horizontal scale\n   * @param scaleY - vertical scale\n   */\n  public scale(scaleX: number, scaleY: number): void {\n    super.scale(scaleX, scaleY);\n\n    const rPoint = this.rotatePoint({x: this.left, y: this.top});\n    const point = this.unrotatePoint({x: rPoint.x * scaleX, y: rPoint.y * scaleY});\n\n    this.left = point.x;\n    this.top = point.y;\n    this.width = this.width * scaleX;\n    this.height = this.height * scaleY;\n  }\n\n}\n","import { IPoint } from '../core/IPoint';\nimport { SvgHelper } from '../core/SvgHelper';\nimport { RectangularBoxMarkerBase } from './RectangularBoxMarkerBase';\nimport { RectangleMarkerState } from './RectangleMarkerState';\nimport { MarkerBaseState } from '../core/MarkerBaseState';\n\n/**\n * RecatngleMarker is a base class for all rectangular markers (Frame, Cover, Highlight, etc.)\n */\nexport abstract class RectangleMarker extends RectangularBoxMarkerBase {\n  /**\n   * String type name of the marker type. \n   * \n   * Used when adding {@link MarkerView.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static title = 'Rectangle marker';\n\n  /**\n   * Recangle fill color.\n   */\n  protected fillColor = 'transparent';\n  /**\n   * Rectangle stroke color.\n   */\n  protected strokeColor = 'transparent';\n  /**\n   * Rectangle border stroke width.\n   */\n  protected strokeWidth = 0;\n  /**\n   * Rectangle border stroke dash array.\n   */\n  protected strokeDasharray = '';\n  /**\n   * Rectangle opacity (alpha). 0 to 1.\n   */\n  protected opacity = 1;\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   */\n  constructor(container: SVGGElement) {\n    super(container);\n\n    this.setStrokeColor = this.setStrokeColor.bind(this);\n    this.setFillColor = this.setFillColor.bind(this);\n    this.setStrokeWidth = this.setStrokeWidth.bind(this);\n    this.setStrokeDasharray = this.setStrokeDasharray.bind(this);\n    this.createVisual = this.createVisual.bind(this);\n  }\n\n  /**\n   * Returns true if passed SVG element belongs to the marker. False otherwise.\n   * \n   * @param el - target element.\n   */\n  public ownsTarget(el: EventTarget): boolean {\n    if (super.ownsTarget(el) || el === this.visual) {\n      return true;\n    } else {\n      return false;\n    }\n  }\n\n  /**\n   * Creates the marker's rectangle visual.\n   */\n  protected createVisual(): void {\n    this.visual = SvgHelper.createRect(1, 1, [\n      ['fill', this.fillColor],\n      ['stroke', this.strokeColor],\n      ['stroke-width', this.strokeWidth.toString()],\n      ['stroke-dasharray', this.strokeDasharray],\n      ['opacity', this.opacity.toString()]\n    ]);\n    this.addMarkerVisualToContainer(this.visual);\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) down event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerDown(point: IPoint, target?: EventTarget): void {\n    super.pointerDown(point, target);\n  }\n\n  /**\n   * Resizes the marker based on the pointer coordinates.\n   * @param point - current pointer coordinates.\n   */\n  protected resize(point: IPoint): void {\n    super.resize(point);\n    this.setSize();\n  }\n\n  /**\n   * Sets visual's width and height attributes based on marker's width and height.\n   */\n  protected setSize(): void {\n    super.setSize();\n    SvgHelper.setAttributes(this.visual, [\n      ['width', this.width.toString()],\n      ['height', this.height.toString()],\n    ]);\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) up event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerUp(point: IPoint): void {\n    super.pointerUp(point);\n    this.setSize();\n  }\n\n  /**\n   * Sets rectangle's border stroke color.\n   * @param color - color as string\n   */\n  protected setStrokeColor(color: string): void {\n    this.strokeColor = color;\n    if (this.visual) {\n      SvgHelper.setAttributes(this.visual, [['stroke', this.strokeColor]]);\n    }\n  }\n  /**\n   * Sets rectangle's fill color.\n   * @param color - color as string\n   */\n  protected setFillColor(color: string): void {\n    this.fillColor = color;\n    if (this.visual) {\n      SvgHelper.setAttributes(this.visual, [['fill', this.fillColor]]);\n    }\n  }\n  /**\n   * Sets rectangle's border stroke (line) width.\n   * @param color - color as string\n   */\n  protected setStrokeWidth(width: number): void {\n    this.strokeWidth = width;\n    if (this.visual) {\n      SvgHelper.setAttributes(this.visual, [['stroke-width', this.strokeWidth.toString()]]);\n    }\n  }\n  /**\n   * Sets rectangle's border stroke dash array.\n   * @param color - color as string\n   */\n  protected setStrokeDasharray(dashes: string): void {\n    this.strokeDasharray = dashes;\n    if (this.visual) {\n      SvgHelper.setAttributes(this.visual, [['stroke-dasharray', this.strokeDasharray]]);\n    }\n  }\n\n  /**\n   * Restores previously saved marker state.\n   * \n   * @param state - previously saved state.\n   */\n  public restoreState(state: MarkerBaseState): void {\n    const rectState = state as RectangleMarkerState;\n    this.fillColor = rectState.fillColor;\n    this.strokeColor = rectState.strokeColor;\n    this.strokeWidth = rectState.strokeWidth;\n    this.strokeDasharray = rectState.strokeDasharray;\n    this.opacity = rectState.opacity;\n\n    this.createVisual();\n    super.restoreState(state);\n    this.setSize();\n  }\n\n  /**\n   * Scales marker. Used after the image resize.\n   * \n   * @param scaleX - horizontal scale\n   * @param scaleY - vertical scale\n   */\n  public scale(scaleX: number, scaleY: number): void {\n    super.scale(scaleX, scaleY);\n\n    this.setSize();\n  }\n}\n","import { RectangleMarker } from '../RectangleMarker';\n\nexport class FrameMarker extends RectangleMarker {\n  /**\n   * String type name of the marker type. \n   * \n   * Used when adding {@link MarkerView.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static typeName = 'FrameMarker';\n  \n  /**\n   * Marker type title (display name) used for accessibility and other attributes.\n   */\n  public static title = 'Frame marker';\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   */\n  constructor(container: SVGGElement) {\n    super(container);\n  }\n}\n","import { MarkerBase } from '../core/MarkerBase';\n\nimport { IPoint } from '../core/IPoint';\n\nimport { LinearMarkerBaseState } from './LinearMarkerBaseState';\nimport { MarkerBaseState } from '../core/MarkerBaseState';\n\n/**\n * LinearMarkerBase is a base class for all line-type markers (Line, Arrow, Measurement Tool, etc.).\n */\nexport class LinearMarkerBase extends MarkerBase {\n  /**\n   * x coordinate of the first end-point\n   */\n  protected x1 = 0;\n  /**\n   * y coordinate of the first end-point\n   */\n  protected y1 = 0;\n  /**\n   * x coordinate of the second end-point\n   */\n  protected x2 = 0;\n  /**\n   * y coordinate of the second end-point\n   */\n  protected y2 = 0;\n\n  /**\n   * Default line length when marker is created with a simple click (without dragging).\n   */\n  protected defaultLength = 50;\n\n  /**\n   * Marker's main visual.\n   */\n  protected visual: SVGGraphicsElement;\n\n  /**\n   * Creates a LineMarkerBase object.\n   * \n   * @param container - SVG container to hold marker's visual.\n   */\n  constructor(container: SVGGElement) {\n    super(container);\n  }\n\n  /**\n   * Returns true if passed SVG element belongs to the marker. False otherwise.\n   * \n   * @param el - target element.\n   */\n  public ownsTarget(el: EventTarget): boolean {\n    if (super.ownsTarget(el)) {\n      return true;\n    } else {\n      return false;\n    }\n  }\n\n  \n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) down event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerDown(point: IPoint, target?: EventTarget): void {\n    super.pointerDown(point, target);\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) up event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerUp(point: IPoint): void {\n    super.pointerUp(point);\n  }\n\n  /**\n   * When implemented adjusts marker visual after manipulation when needed.\n   */\n  // eslint-disable-next-line @typescript-eslint/no-empty-function\n  protected adjustVisual(): void {}\n\n  /**\n   * Resizes the line marker.\n   * @param point - current manipulation coordinates.\n   */\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars\n  protected resize(point: IPoint): void {\n    this.adjustVisual();\n  }\n\n  /**\n   * Displays marker's controls.\n   */\n  public select(): void {\n    super.select();\n  }\n\n  /**\n   * Hides marker's controls.\n   */\n  public deselect(): void {\n    super.deselect();\n  }\n\n  /**\n   * Restores marker's state to the previously saved one.\n   * @param state - previously saved state.\n   */\n  public restoreState(state: MarkerBaseState): void {\n    super.restoreState(state);\n    const lmbState = state as LinearMarkerBaseState;\n    this.x1 = lmbState.x1;\n    this.y1 = lmbState.y1;\n    this.x2 = lmbState.x2;\n    this.y2 = lmbState.y2;\n  }\n\n  /**\n   * Scales marker. Used after the image resize.\n   * \n   * @param scaleX - horizontal scale\n   * @param scaleY - vertical scale\n   */\n  public scale(scaleX: number, scaleY: number): void {\n    super.scale(scaleX, scaleY);\n\n    this.x1 = this.x1 * scaleX;\n    this.y1 = this.y1 * scaleY;\n    this.x2 = this.x2 * scaleX;\n    this.y2 = this.y2 * scaleY;\n\n    this.adjustVisual();\n  }\n}\n","import { IPoint } from '../../core/IPoint';\nimport { SvgHelper } from '../../core/SvgHelper';\nimport { LinearMarkerBase } from '../LinearMarkerBase';\nimport { LineMarkerState } from './LineMarkerState';\nimport { MarkerBaseState } from '../../core/MarkerBaseState';\n\nexport class LineMarker extends LinearMarkerBase {\n  /**\n   * String type name of the marker type. \n   * \n   * Used when adding {@link MarkerView.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static typeName = 'LineMarker';\n  \n  /**\n   * Marker type title (display name) used for accessibility and other attributes.\n   */\n  public static title = 'Line marker';\n\n  /**\n   * Invisible wider line to make selection easier/possible.\n   */\n  protected selectorLine: SVGLineElement;\n  /**\n   * Visible marker line.\n   */\n  protected visibleLine: SVGLineElement;\n\n  /**\n   * Line color.\n   */\n  protected strokeColor = 'transparent';\n  /**\n   * Line width.\n   */\n  protected strokeWidth = 0;\n  /**\n   * Line dash array.\n   */\n  protected strokeDasharray = '';\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   */\n  constructor(container: SVGGElement) {\n    super(container);\n\n    this.setStrokeColor = this.setStrokeColor.bind(this);\n    this.setStrokeWidth = this.setStrokeWidth.bind(this);\n    this.setStrokeDasharray = this.setStrokeDasharray.bind(this);\n  }\n\n  /**\n   * Returns true if passed SVG element belongs to the marker. False otherwise.\n   * \n   * @param el - target element.\n   */\n  public ownsTarget(el: EventTarget): boolean {\n    if (\n      super.ownsTarget(el) ||\n      el === this.visual ||\n      el === this.selectorLine ||\n      el === this.visibleLine\n    ) {\n      return true;\n    } else {\n      return false;\n    }\n  }\n\n  private createVisual() {\n    this.visual = SvgHelper.createGroup();\n    this.selectorLine = SvgHelper.createLine(\n      this.x1,\n      this.y1,\n      this.x2,\n      this.y2,\n      [\n        ['stroke', 'transparent'],\n        ['stroke-width', (this.strokeWidth + 10).toString()],\n      ]\n    );\n    this.visibleLine = SvgHelper.createLine(\n      this.x1,\n      this.y1,\n      this.x2,\n      this.y2,\n      [\n        ['stroke', this.strokeColor],\n        ['stroke-width', this.strokeWidth.toString()],\n      ]\n    );\n    this.visual.appendChild(this.selectorLine);\n    this.visual.appendChild(this.visibleLine);\n\n    this.addMarkerVisualToContainer(this.visual);\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) down event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerDown(point: IPoint, target?: EventTarget): void {\n    super.pointerDown(point, target);\n  }\n\n  /**\n   * Adjusts visual after manipulation.\n   */\n  protected adjustVisual(): void {\n    this.selectorLine.setAttribute('x1', this.x1.toString());\n    this.selectorLine.setAttribute('y1', this.y1.toString());\n    this.selectorLine.setAttribute('x2', this.x2.toString());\n    this.selectorLine.setAttribute('y2', this.y2.toString());\n\n    this.visibleLine.setAttribute('x1', this.x1.toString());\n    this.visibleLine.setAttribute('y1', this.y1.toString());\n    this.visibleLine.setAttribute('x2', this.x2.toString());\n    this.visibleLine.setAttribute('y2', this.y2.toString());\n\n    SvgHelper.setAttributes(this.visibleLine, [['stroke', this.strokeColor]]);\n    SvgHelper.setAttributes(this.visibleLine, [['stroke-width', this.strokeWidth.toString()]]);\n    SvgHelper.setAttributes(this.visibleLine, [['stroke-dasharray', this.strokeDasharray.toString()]]);\n  }\n\n  /**\n   * Sets line color.\n   * @param color - new color.\n   */\n  protected setStrokeColor(color: string): void {\n    this.strokeColor = color;\n    this.adjustVisual();\n  }\n  /**\n   * Sets line width.\n   * @param width - new width.\n   */\n  protected setStrokeWidth(width: number): void {\n    this.strokeWidth = width\n    this.adjustVisual();\n  }\n\n  /**\n   * Sets line dash array.\n   * @param dashes - new dash array.\n   */\n  protected setStrokeDasharray(dashes: string): void {\n    this.strokeDasharray = dashes;\n    this.adjustVisual();\n  }\n\n  /**\n   * Restores previously saved marker state.\n   * \n   * @param state - previously saved state.\n   */\n  public restoreState(state: MarkerBaseState): void {\n    super.restoreState(state);\n\n    const lmState = state as LineMarkerState;\n    this.strokeColor = lmState.strokeColor;\n    this.strokeWidth = lmState.strokeWidth;\n    this.strokeDasharray = lmState.strokeDasharray;\n\n    this.createVisual();\n    this.adjustVisual();\n  }\n}\n","import { IPoint } from '../../core/IPoint';\nimport { SvgHelper } from '../../core/SvgHelper';\nimport { RectangularBoxMarkerBase } from '../RectangularBoxMarkerBase';\nimport { TextMarkerState } from './TextMarkerState';\nimport { MarkerBaseState } from '../../core/MarkerBaseState';\n\nexport class TextMarker extends RectangularBoxMarkerBase {\n  /**\n   * String type name of the marker type.\n   *\n   * Used when adding {@link MarkerView.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static typeName = 'TextMarker';\n\n  /**\n   * Marker type title (display name) used for accessibility and other attributes.\n   */\n  public static title = 'Text marker';\n\n  /**\n   * Text color.\n   */\n  protected color = 'transparent';\n  /**\n   * Text's font family.\n   */\n  protected fontFamily: string;\n  /**\n   * Padding inside of the marker's bounding box in percents.\n   */\n  protected padding = 5;\n\n  private text = '';\n  /**\n   * Visual text element.\n   */\n  protected textElement: SVGTextElement;\n  /**\n   * Text background rectangle.\n   */\n  protected bgRectangle: SVGRectElement;\n\n  private pointerDownPoint: IPoint;\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   */\n  constructor(container: SVGGElement) {\n    super(container);\n\n    this.defaultSize = { x: 100, y: 30 };\n\n    this.setColor = this.setColor.bind(this);\n    this.setFont = this.setFont.bind(this);\n    this.renderText = this.renderText.bind(this);\n    this.sizeText = this.sizeText.bind(this);\n    this.setSize = this.setSize.bind(this);\n  }\n\n  /**\n   * Returns true if passed SVG element belongs to the marker. False otherwise.\n   *\n   * @param el - target element.\n   */\n  public ownsTarget(el: EventTarget): boolean {\n    if (\n      super.ownsTarget(el) ||\n      el === this.visual ||\n      el === this.textElement ||\n      el === this.bgRectangle\n    ) {\n      return true;\n    } else {\n      let found = false;\n      this.textElement.childNodes.forEach((span) => {\n        if (span === el) {\n          found = true;\n        }\n      });\n      return found;\n    }\n  }\n\n  /**\n   * Creates text marker visual.\n   */\n  protected createVisual(): void {\n    this.visual = SvgHelper.createGroup();\n\n    this.bgRectangle = SvgHelper.createRect(1, 1, [['fill', 'transparent']]);\n    this.visual.appendChild(this.bgRectangle);\n\n    this.textElement = SvgHelper.createText([\n      ['fill', this.color],\n      ['font-family', this.fontFamily],\n      ['font-size', '16px'],\n      ['x', '0'],\n      ['y', '0'],\n    ]);\n    this.textElement.transform.baseVal.appendItem(SvgHelper.createTransform()); // translate transorm\n    this.textElement.transform.baseVal.appendItem(SvgHelper.createTransform()); // scale transorm\n\n    this.visual.appendChild(this.textElement);\n\n    this.addMarkerVisualToContainer(this.visual);\n    this.renderText();\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) down event.\n   *\n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerDown(point: IPoint, target?: EventTarget): void {\n    super.pointerDown(point, target);\n\n    this.pointerDownPoint = point;\n  }\n\n  private renderText() {\n    const LINE_SIZE = '1.2em';\n\n    while (this.textElement.lastChild) {\n      this.textElement.removeChild(this.textElement.lastChild);\n    }\n\n    const lines = this.text.split(/\\r\\n|[\\n\\v\\f\\r\\x85\\u2028\\u2029]/);\n    lines.forEach((line) => {\n      this.textElement.appendChild(\n        SvgHelper.createTSpan(\n          // workaround for swallowed empty lines\n          line.trim() === '' ? ' ' : line.trim(),\n          [\n            ['x', '0'],\n            ['dy', LINE_SIZE],\n          ]\n        )\n      );\n    });\n\n    setTimeout(this.sizeText, 10);\n  }\n\n  private getTextScale(): number {\n    const textSize = this.textElement.getBBox();\n    let scale = 1.0;\n    if (textSize.width > 0 && textSize.height > 0) {\n      const xScale =\n        (this.width * 1.0 - (this.width * this.padding * 2) / 100) /\n        textSize.width;\n      const yScale =\n        (this.height * 1.0 - (this.height * this.padding * 2) / 100) /\n        textSize.height;\n      scale = Math.min(xScale, yScale);\n    }\n    return scale;\n  }\n\n  private getTextPosition(scale: number): IPoint {\n    const textSize = this.textElement.getBBox();\n    let x = 0;\n    let y = 0;\n    if (textSize.width > 0 && textSize.height > 0) {\n      x = (this.width - textSize.width * scale) / 2;\n      y = this.height / 2 - (textSize.height * scale) / 2;\n    }\n    return { x: x, y: y };\n  }\n\n  private sizeText() {\n    const textBBox = this.textElement.getBBox();\n    const scale = this.getTextScale();\n    const position = this.getTextPosition(scale);\n    position.y -= textBBox.y * scale; // workaround adjustment for text not being placed at y=0\n\n    if (navigator.userAgent.indexOf('Edge/') > -1) {\n      // workaround for legacy Edge as transforms don't work otherwise but this way it doesn't work in Safari\n      this.textElement.style.transform = `translate(${position.x}px, ${position.y}px) scale(${scale}, ${scale})`;\n    } else {\n      this.textElement.transform.baseVal\n        .getItem(0)\n        .setTranslate(position.x, position.y);\n      this.textElement.transform.baseVal.getItem(1).setScale(scale, scale);\n    }\n  }\n\n  /**\n   * Resize marker based on current pointer coordinates and context.\n   * @param point\n   */\n  protected resize(point: IPoint): void {\n    super.resize(point);\n    this.setSize();\n    this.sizeText();\n  }\n\n  /**\n   * Sets size of marker elements after manipulation.\n   */\n  protected setSize(): void {\n    super.setSize();\n    SvgHelper.setAttributes(this.visual, [\n      ['width', this.width.toString()],\n      ['height', this.height.toString()],\n    ]);\n    SvgHelper.setAttributes(this.bgRectangle, [\n      ['width', this.width.toString()],\n      ['height', this.height.toString()],\n    ]);\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) up event.\n   *\n   * @param point - event coordinates.\n   */\n  public pointerUp(point: IPoint): void {\n    super.pointerUp(point);\n    this.setSize();\n  }\n\n  /**\n   * Deselects this marker, renders text (if necessary), and hides selected marker UI.\n   */\n  public deselect(): void {\n    super.deselect();\n  }\n\n  /**\n   * Opens text editor on double-click.\n   * @param point\n   * @param target\n   */\n  public dblClick(point: IPoint, target?: EventTarget): void {\n    super.dblClick(point, target);\n  }\n\n  /**\n   * Sets text color.\n   * @param color - new text color.\n   */\n  protected setColor(color: string): void {\n    SvgHelper.setAttributes(this.textElement, [['fill', color]]);\n    this.color = color;\n  }\n\n  /**\n   * Sets font family.\n   * @param font - new font family.\n   */\n  protected setFont(font: string): void {\n    SvgHelper.setAttributes(this.textElement, [['font-family', font]]);\n    this.fontFamily = font;\n    this.renderText();\n  }\n\n  /**\n   * Restores previously saved marker state.\n   *\n   * @param state - previously saved state.\n   */\n  public restoreState(state: MarkerBaseState): void {\n    const textState = state as TextMarkerState;\n    this.color = textState.color;\n    this.fontFamily = textState.fontFamily;\n    this.padding = textState.padding;\n    this.text = textState.text;\n\n    this.createVisual();\n    super.restoreState(state);\n    this.setSize();\n  }\n\n  /**\n   * Scales marker. Used after the image resize.\n   *\n   * @param scaleX - horizontal scale\n   * @param scaleY - vertical scale\n   */\n  public scale(scaleX: number, scaleY: number): void {\n    super.scale(scaleX, scaleY);\n\n    this.setSize();\n    this.sizeText();\n  }\n}\n","import { IPoint } from '../../core/IPoint';\nimport { SvgHelper } from '../../core/SvgHelper';\nimport { RectangularBoxMarkerBase } from '../RectangularBoxMarkerBase';\nimport { FreehandMarkerState } from './FreehandMarkerState';\nimport { MarkerBaseState } from '../../core/MarkerBaseState';\n\nexport class FreehandMarker extends RectangularBoxMarkerBase {\n  /**\n   * String type name of the marker type.\n   *\n   * Used when adding {@link MarkerView.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static typeName = 'FreehandMarker';\n\n  /**\n   * Marker type title (display name) used for accessibility and other attributes.\n   */\n  public static title = 'Freehand marker';\n\n  /**\n   * Marker color.\n   */\n  protected color = 'transparent';\n  /**\n   * Marker's stroke width.\n   */\n  protected lineWidth = 3;\n\n  private drawingImage: SVGImageElement;\n  private drawingImgUrl: string;\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   */\n  constructor(container: SVGGElement) {\n    super(container);\n  }\n\n  /**\n   * Returns true if passed SVG element belongs to the marker. False otherwise.\n   *\n   * @param el - target element.\n   */\n  public ownsTarget(el: EventTarget): boolean {\n    if (\n      super.ownsTarget(el) ||\n      el === this.visual ||\n      el === this.drawingImage\n    ) {\n      return true;\n    } else {\n      return false;\n    }\n  }\n\n  private createVisual() {\n    this.visual = SvgHelper.createGroup();\n    this.drawingImage = SvgHelper.createImage();\n    this.visual.appendChild(this.drawingImage);\n\n    const translate = SvgHelper.createTransform();\n    this.visual.transform.baseVal.appendItem(translate);\n    this.addMarkerVisualToContainer(this.visual);\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) down event.\n   *\n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerDown(point: IPoint, target?: EventTarget): void {\n    super.pointerDown(point, target);\n  }\n\n  /**\n   * Resize marker based on current pointer coordinates and context.\n   * @param point\n   */\n  protected resize(point: IPoint): void {\n    super.resize(point);\n    SvgHelper.setAttributes(this.visual, [\n      ['width', this.width.toString()],\n      ['height', this.height.toString()],\n    ]);\n    SvgHelper.setAttributes(this.drawingImage, [\n      ['width', this.width.toString()],\n      ['height', this.height.toString()],\n    ]);\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) up event.\n   *\n   * @param point - event coordinates.\n   */\n  public pointerUp(point: IPoint): void {\n    super.pointerUp(point);\n  }\n\n  /**\n   * Selects this marker and displays appropriate selected marker UI.\n   */\n  public select(): void {\n    super.select();\n  }\n\n  /**\n   * Deselects this marker and hides selected marker UI.\n   */\n  public deselect(): void {\n    super.deselect();\n  }\n\n  private setDrawingImage() {\n    SvgHelper.setAttributes(this.drawingImage, [\n      ['width', this.width.toString()],\n      ['height', this.height.toString()],\n    ]);\n    SvgHelper.setAttributes(this.drawingImage, [['href', this.drawingImgUrl]]);\n    this.moveVisual({ x: this.left, y: this.top });\n  }\n\n  /**\n   * Restores previously saved marker state.\n   *\n   * @param state - previously saved state.\n   */\n  public restoreState(state: MarkerBaseState): void {\n    this.createVisual();\n    super.restoreState(state);\n    this.drawingImgUrl = (state as FreehandMarkerState).drawingImgUrl;\n    this.setDrawingImage();\n  }\n\n  /**\n   * Scales marker. Used after the image resize.\n   *\n   * @param scaleX - horizontal scale\n   * @param scaleY - vertical scale\n   */\n  public scale(scaleX: number, scaleY: number): void {\n    super.scale(scaleX, scaleY);\n\n    this.setDrawingImage();\n  }\n}\n","import { IPoint } from '../../core/IPoint';\nimport { SvgHelper } from '../../core/SvgHelper';\nimport { LineMarker } from '../line-marker/LineMarker';\nimport { ArrowMarkerState, ArrowType } from './ArrowMarkerState';\nimport { MarkerBaseState } from '../../core/MarkerBaseState';\n\n/**\n * Represents an arrow marker.\n */\nexport class ArrowMarker extends LineMarker {\n  /**\n   * String type name of the marker type. \n   * \n   * Used when adding {@link MarkerView.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static typeName = 'ArrowMarker';\n\n  /**\n   * Marker type title (display name) used for accessibility and other attributes.\n   */\n  public static title = 'Arrow marker';\n\n  private arrow1: SVGPolygonElement;\n  private arrow2: SVGPolygonElement;\n\n  private arrowType: ArrowType = 'end';\n\n  private arrowBaseHeight = 10;\n  private arrowBaseWidth = 10;\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   */\n  constructor(container: SVGGElement) {\n    super(container);\n\n    this.getArrowPoints = this.getArrowPoints.bind(this);\n    this.setArrowType = this.setArrowType.bind(this);\n  }\n\n  /**\n   * Returns true if passed SVG element belongs to the marker. False otherwise.\n   * \n   * @param el - target element.\n   */\n  public ownsTarget(el: EventTarget): boolean {\n    if (\n      super.ownsTarget(el) ||\n      el === this.arrow1 || el === this.arrow2\n    ) {\n      return true;\n    } else {\n      return false;\n    }\n  }\n\n  private getArrowPoints(offsetX: number, offsetY: number): string {\n    const width = this.arrowBaseWidth + this.strokeWidth * 2;\n    const height = this.arrowBaseHeight + this.strokeWidth * 2;\n    return `${offsetX - width / 2},${\n      offsetY + height / 2\n    } ${offsetX},${offsetY - height / 2} ${\n      offsetX + width / 2},${offsetY + height / 2}`;\n  }\n\n  private createTips() {\n    this.arrow1 = SvgHelper.createPolygon(this.getArrowPoints(this.x1, this.y1), [['fill', this.strokeColor]]);\n    this.arrow1.transform.baseVal.appendItem(SvgHelper.createTransform());\n    this.visual.appendChild(this.arrow1);\n\n    this.arrow2 = SvgHelper.createPolygon(this.getArrowPoints(this.x2, this.y2), [['fill', this.strokeColor]]);\n    this.arrow2.transform.baseVal.appendItem(SvgHelper.createTransform());\n    this.visual.appendChild(this.arrow2);\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) down event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerDown(point: IPoint, target?: EventTarget): void {\n    super.pointerDown(point, target);\n  }\n\n  /**\n   * Adjusts marker visual after manipulation.\n   */\n  protected adjustVisual(): void {\n    super.adjustVisual();\n\n    if (this.arrow1 && this.arrow2) {\n      this.arrow1.style.display = (this.arrowType === 'both' || this.arrowType === 'start') ? '' : 'none';\n      this.arrow2.style.display = (this.arrowType === 'both' || this.arrowType === 'end') ? '' : 'none';\n\n      SvgHelper.setAttributes(this.arrow1, [\n        ['points', this.getArrowPoints(this.x1, this.y1)],\n        ['fill', this.strokeColor]\n      ]);\n      SvgHelper.setAttributes(this.arrow2, [\n        ['points', this.getArrowPoints(this.x2, this.y2)],\n        ['fill', this.strokeColor]\n      ]);\n\n      if (Math.abs(this.x1 - this.x2) > 0.1) {\n        const lineAngle1 =\n          (Math.atan((this.y2 - this.y1) / (this.x2 - this.x1)) * 180) / Math.PI + 90 * Math.sign(this.x1 - this.x2);\n\n        const a1transform = this.arrow1.transform.baseVal.getItem(0);\n        a1transform.setRotate(lineAngle1, this.x1, this.y1);\n        this.arrow1.transform.baseVal.replaceItem(a1transform, 0);\n\n        const a2transform = this.arrow2.transform.baseVal.getItem(0);\n        a2transform.setRotate(lineAngle1 + 180, this.x2, this.y2);\n        this.arrow2.transform.baseVal.replaceItem(a2transform, 0);\n      }\n    }\n  }\n\n  private setArrowType(arrowType: ArrowType) {\n    this.arrowType = arrowType;\n    this.adjustVisual();\n  }\n\n  /**\n   * Restores previously saved marker state.\n   * \n   * @param state - previously saved state.\n   */\n  public restoreState(state: MarkerBaseState): void {\n    super.restoreState(state);\n\n    const amState = state as ArrowMarkerState;\n    this.arrowType = amState.arrowType;\n\n    this.createTips();\n    this.adjustVisual();\n  }\n\n}\n","import { RectangleMarker } from '../RectangleMarker';\n\nexport class CoverMarker extends RectangleMarker {\n  /**\n   * String type name of the marker type. \n   * \n   * Used when adding {@link MarkerView.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static typeName = 'CoverMarker';\n\n  /**\n   * Marker type title (display name) used for accessibility and other attributes.\n   */\n  public static title = 'Cover marker';\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   */\n  constructor(container: SVGGElement) {\n    super(container);\n\n    this.strokeWidth = 0;\n  }\n}\n","import { CoverMarker } from '../cover-marker/CoverMarker';\nimport { SvgHelper } from '../../core/SvgHelper';\n\nexport class HighlightMarker extends CoverMarker {\n  /**\n   * String type name of the marker type. \n   * \n   * Used when adding {@link MarkerView.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static typeName = 'HighlightMarker';\n  /**\n   * Marker type title (display name) used for accessibility and other attributes.\n   */\n  public static title = 'Highlight marker';\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   */\n  constructor(container: SVGGElement) {\n    super(container);\n\n    this.setOpacity = this.setOpacity.bind(this);\n\n    this.strokeWidth = 0;\n  }\n\n  /**\n   * Sets marker's opacity (0..1).\n   * @param opacity - new opacity value.\n   */\n  protected setOpacity(opacity: number): void {\n    this.opacity = opacity;\n    if (this.visual) {\n      SvgHelper.setAttributes(this.visual, [['opacity', this.opacity.toString()]]);\n    }\n  }\n}\n","import { IPoint } from '../../core/IPoint';\nimport { SvgHelper } from '../../core/SvgHelper';\nimport { TextMarker } from '../text-marker/TextMarker';\nimport { CalloutMarkerState } from './CalloutMarkerState';\nimport { MarkerBaseState } from '../../core/MarkerBaseState';\n\nexport class CalloutMarker extends TextMarker {\n  /**\n   * String type name of the marker type.\n   *\n   * Used when adding {@link MarkerView.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static typeName = 'CalloutMarker';\n\n  /**\n   * Marker type title (display name) used for accessibility and other attributes.\n   */\n  public static title = 'Callout marker';\n\n  private bgColor = 'transparent';\n\n  private tipPosition: IPoint = { x: 0, y: 0 };\n  private tipBase1Position: IPoint = { x: 0, y: 0 };\n  private tipBase2Position: IPoint = { x: 0, y: 0 };\n  private tip: SVGPolygonElement;\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   */\n  constructor(container: SVGGElement) {\n    super(container);\n\n    this.defaultSize = { x: 100, y: 30 };\n\n    this.setBgColor = this.setBgColor.bind(this);\n    this.getTipPoints = this.getTipPoints.bind(this);\n    this.positionTip = this.positionTip.bind(this);\n    this.setTipPoints = this.setTipPoints.bind(this);\n  }\n\n  /**\n   * Returns true if passed SVG element belongs to the marker. False otherwise.\n   *\n   * @param el - target element.\n   */\n  public ownsTarget(el: EventTarget): boolean {\n    return super.ownsTarget(el) || this.tip === el;\n  }\n\n  private createTip() {\n    SvgHelper.setAttributes(this.bgRectangle, [\n      ['fill', this.bgColor],\n      ['rx', '10px'],\n    ]);\n\n    this.tip = SvgHelper.createPolygon(this.getTipPoints(), [\n      ['fill', this.bgColor],\n    ]);\n    this.visual.appendChild(this.tip);\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) down event.\n   *\n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerDown(point: IPoint, target?: EventTarget): void {\n    super.pointerDown(point, target);\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) up event.\n   *\n   * @param point - event coordinates.\n   */\n  public pointerUp(point: IPoint): void {\n    super.pointerUp(point);\n  }\n\n  /**\n   * Sets marker's background/fill color.\n   * @param color - new background color.\n   */\n  protected setBgColor(color: string): void {\n    SvgHelper.setAttributes(this.bgRectangle, [['fill', color]]);\n    SvgHelper.setAttributes(this.tip, [['fill', color]]);\n    this.bgColor = color;\n  }\n\n  private getTipPoints(): string {\n    this.setTipPoints();\n    return `${this.tipBase1Position.x},${this.tipBase1Position.y} ${this.tipBase2Position.x},${this.tipBase2Position.y} ${this.tipPosition.x},${this.tipPosition.y}`;\n  }\n\n  private setTipPoints(isCreating = false) {\n    let offset = Math.min(this.height / 2, 15);\n    let baseWidth = this.height / 5;\n    if (isCreating) {\n      this.tipPosition = { x: offset + baseWidth / 2, y: this.height + 20 };\n    }\n\n    const cornerAngle = Math.atan(this.height / 2 / (this.width / 2));\n    if (\n      this.tipPosition.x < this.width / 2 &&\n      this.tipPosition.y < this.height / 2\n    ) {\n      // top left\n      const tipAngle = Math.atan(\n        (this.height / 2 - this.tipPosition.y) /\n          (this.width / 2 - this.tipPosition.x)\n      );\n      if (cornerAngle < tipAngle) {\n        baseWidth = this.width / 5;\n        offset = Math.min(this.width / 2, 15);\n        this.tipBase1Position = { x: offset, y: 0 };\n        this.tipBase2Position = { x: offset + baseWidth, y: 0 };\n      } else {\n        this.tipBase1Position = { x: 0, y: offset };\n        this.tipBase2Position = { x: 0, y: offset + baseWidth };\n      }\n    } else if (\n      this.tipPosition.x >= this.width / 2 &&\n      this.tipPosition.y < this.height / 2\n    ) {\n      // top right\n      const tipAngle = Math.atan(\n        (this.height / 2 - this.tipPosition.y) /\n          (this.tipPosition.x - this.width / 2)\n      );\n      if (cornerAngle < tipAngle) {\n        baseWidth = this.width / 5;\n        offset = Math.min(this.width / 2, 15);\n        this.tipBase1Position = { x: this.width - offset - baseWidth, y: 0 };\n        this.tipBase2Position = { x: this.width - offset, y: 0 };\n      } else {\n        this.tipBase1Position = { x: this.width, y: offset };\n        this.tipBase2Position = { x: this.width, y: offset + baseWidth };\n      }\n    } else if (\n      this.tipPosition.x >= this.width / 2 &&\n      this.tipPosition.y >= this.height / 2\n    ) {\n      // bottom right\n      const tipAngle = Math.atan(\n        (this.tipPosition.y - this.height / 2) /\n          (this.tipPosition.x - this.width / 2)\n      );\n      if (cornerAngle < tipAngle) {\n        baseWidth = this.width / 5;\n        offset = Math.min(this.width / 2, 15);\n        this.tipBase1Position = {\n          x: this.width - offset - baseWidth,\n          y: this.height,\n        };\n        this.tipBase2Position = { x: this.width - offset, y: this.height };\n      } else {\n        this.tipBase1Position = {\n          x: this.width,\n          y: this.height - offset - baseWidth,\n        };\n        this.tipBase2Position = { x: this.width, y: this.height - offset };\n      }\n    } else {\n      // bottom left\n      const tipAngle = Math.atan(\n        (this.tipPosition.y - this.height / 2) /\n          (this.width / 2 - this.tipPosition.x)\n      );\n      if (cornerAngle < tipAngle) {\n        baseWidth = this.width / 5;\n        offset = Math.min(this.width / 2, 15);\n        this.tipBase1Position = { x: offset, y: this.height };\n        this.tipBase2Position = { x: offset + baseWidth, y: this.height };\n      } else {\n        this.tipBase1Position = { x: 0, y: this.height - offset };\n        this.tipBase2Position = { x: 0, y: this.height - offset - baseWidth };\n      }\n    }\n  }\n\n  /**\n   * Resize marker based on current pointer coordinates and context.\n   * @param point\n   */\n  protected resize(point: IPoint): void {\n    super.resize(point);\n    this.positionTip();\n  }\n\n  private positionTip() {\n    SvgHelper.setAttributes(this.tip, [['points', this.getTipPoints()]]);\n  }\n\n  /**\n   * Selects this marker and displays appropriate selected marker UI.\n   */\n  public select(): void {\n    this.positionTip();\n    super.select();\n  }\n\n  /**\n   * Restores previously saved marker state.\n   *\n   * @param state - previously saved state.\n   */\n  public restoreState(state: MarkerBaseState): void {\n    const calloutState = state as CalloutMarkerState;\n    this.bgColor = calloutState.bgColor;\n    this.tipPosition = calloutState.tipPosition;\n\n    super.restoreState(state);\n    this.createTip();\n    this.setTipPoints();\n  }\n\n  /**\n   * Scales marker. Used after the image resize.\n   *\n   * @param scaleX - horizontal scale\n   * @param scaleY - vertical scale\n   */\n  public scale(scaleX: number, scaleY: number): void {\n    super.scale(scaleX, scaleY);\n\n    this.tipPosition = {\n      x: this.tipPosition.x * scaleX,\n      y: this.tipPosition.y * scaleY,\n    };\n\n    this.positionTip();\n  }\n}\n","import { IPoint } from '../../core/IPoint';\nimport { SvgHelper } from '../../core/SvgHelper';\nimport { RectangularBoxMarkerBase } from '../RectangularBoxMarkerBase';\nimport { RectangleMarkerState } from '../RectangleMarkerState';\nimport { MarkerBaseState } from '../../core/MarkerBaseState';\n\nexport class EllipseMarker extends RectangularBoxMarkerBase {\n  /**\n   * String type name of the marker type. \n   * \n   * Used when adding {@link MarkerView.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static typeName = 'EllipseMarker';\n  /**\n   * Marker type title (display name) used for accessibility and other attributes.\n   */\n  public static title = 'Ellipse marker';\n\n  /**\n   * Ellipse fill color.\n   */\n  protected fillColor = 'transparent';\n  /**\n   * Ellipse border color.\n   */\n  protected strokeColor = 'transparent';\n  /**\n   * Ellipse border line width.\n   */\n  protected strokeWidth = 0;\n  /**\n   * Ellipse border dash array.\n   */\n  protected strokeDasharray = '';\n  /**\n   * Ellipse opacity (0..1).\n   */\n  protected opacity = 1;\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   */\n  constructor(container: SVGGElement) {\n    super(container);\n\n    this.setStrokeColor = this.setStrokeColor.bind(this);\n    this.setFillColor = this.setFillColor.bind(this);\n    this.setStrokeWidth = this.setStrokeWidth.bind(this);\n    this.setStrokeDasharray = this.setStrokeDasharray.bind(this);\n    this.setOpacity = this.setOpacity.bind(this);\n    this.createVisual = this.createVisual.bind(this);\n  }\n\n  /**\n   * Returns true if passed SVG element belongs to the marker. False otherwise.\n   * \n   * @param el - target element.\n   */\n  public ownsTarget(el: EventTarget): boolean {\n    if (super.ownsTarget(el) || el === this.visual) {\n      return true;\n    } else {\n      return false;\n    }\n  }\n\n  /**\n   * Creates marker visual.\n   */\n  protected createVisual(): void {\n    this.visual = SvgHelper.createEllipse(this.width / 2, this.height / 2, [\n      ['fill', this.fillColor],\n      ['stroke', this.strokeColor],\n      ['stroke-width', this.strokeWidth.toString()],\n      ['stroke-dasharray', this.strokeDasharray],\n      ['opacity', this.opacity.toString()]\n    ]);\n    this.addMarkerVisualToContainer(this.visual);\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) down event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerDown(point: IPoint, target?: EventTarget): void {\n    super.pointerDown(point, target);\n  }\n\n  /**\n   * Resize marker based on current pointer coordinates and context.\n   * @param point \n   */\n  protected resize(point: IPoint): void {\n    super.resize(point);\n    this.setSize();\n  }\n\n  /**\n   * Sets marker's visual size after manipulation.\n   */\n  protected setSize(): void {\n    super.setSize();\n    SvgHelper.setAttributes(this.visual, [\n      ['cx', (this.width / 2).toString()],\n      ['cy', (this.height / 2).toString()],\n      ['rx', (this.width / 2).toString()],\n      ['ry', (this.height / 2).toString()],\n    ]);\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) up event.\n   * \n   * @param point - event coordinates.\n   */\n  public pointerUp(point: IPoint): void {\n    super.pointerUp(point);\n    this.setSize();\n  }\n\n  /**\n   * Sets marker's line color.\n   * @param color - new line color.\n   */\n  protected setStrokeColor(color: string): void {\n    this.strokeColor = color;\n    if (this.visual) {\n      SvgHelper.setAttributes(this.visual, [['stroke', this.strokeColor]]);\n    }\n  }\n  /**\n   * Sets marker's fill (background) color.\n   * @param color - new fill color.\n   */\n  protected setFillColor(color: string): void {\n    this.fillColor = color;\n    if (this.visual) {\n      SvgHelper.setAttributes(this.visual, [['fill', this.fillColor]]);\n    }\n  }\n  /**\n   * Sets marker's line width.\n   * @param width - new line width\n   */\n  protected setStrokeWidth(width: number): void {\n    this.strokeWidth = width;\n    if (this.visual) {\n      SvgHelper.setAttributes(this.visual, [['stroke-width', this.strokeWidth.toString()]]);\n    }\n  }\n  /**\n   * Sets marker's border dash array.\n   * @param dashes - new dash array.\n   */\n  protected setStrokeDasharray(dashes: string): void {\n    this.strokeDasharray = dashes;\n    if (this.visual) {\n      SvgHelper.setAttributes(this.visual, [['stroke-dasharray', this.strokeDasharray]]);\n    }\n  }\n  /**\n   * Sets marker's opacity.\n   * @param opacity - new opacity value (0..1).\n   */\n  protected setOpacity(opacity: number): void {\n    this.opacity = opacity;\n    if (this.visual) {\n      SvgHelper.setAttributes(this.visual, [['opacity', this.opacity.toString()]]);\n    }\n  }\n\n  /**\n   * Restores previously saved marker state.\n   * \n   * @param state - previously saved state.\n   */\n  public restoreState(state: MarkerBaseState): void {\n    const rectState = state as RectangleMarkerState;\n    this.fillColor = rectState.fillColor;\n    this.strokeColor = rectState.strokeColor;\n    this.strokeWidth = rectState.strokeWidth;\n    this.strokeDasharray = rectState.strokeDasharray;\n    this.opacity = rectState.opacity;\n\n    this.createVisual();\n    super.restoreState(state);\n    this.setSize();\n  }\n\n  /**\n   * Scales marker. Used after the image resize.\n   * \n   * @param scaleX - horizontal scale\n   * @param scaleY - vertical scale\n   */\n  public scale(scaleX: number, scaleY: number): void {\n    super.scale(scaleX, scaleY);\n\n    this.setSize();\n  }\n}\n","import { IPoint } from '../../core/IPoint';\nimport { SvgHelper } from '../../core/SvgHelper';\nimport { LineMarker } from '../line-marker/LineMarker';\nimport { MarkerBaseState } from '../../core/MarkerBaseState';\n\nexport class MeasurementMarker extends LineMarker {\n  /**\n   * String type name of the marker type. \n   * \n   * Used when adding {@link MarkerView.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static typeName = 'MeasurementMarker';\n\n  /**\n   * Marker type title (display name) used for accessibility and other attributes.\n   */\n  public static title = 'Measurement marker';\n\n  private tip1: SVGLineElement;\n  private tip2: SVGLineElement;\n\n  private get tipLength(): number {\n    return 10 + this.strokeWidth * 3;\n  }\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   */\n  constructor(container: SVGGElement) {\n    super(container);\n  }\n\n  /**\n   * Returns true if passed SVG element belongs to the marker. False otherwise.\n   * \n   * @param el - target element.\n   */\n  public ownsTarget(el: EventTarget): boolean {\n    if (\n      super.ownsTarget(el) ||\n      el === this.tip1 || el === this.tip2\n    ) {\n      return true;\n    } else {\n      return false;\n    }\n  }\n\n  private createTips() {\n    this.tip1 = SvgHelper.createLine(\n      this.x1 - this.tipLength / 2, \n      this.y1, \n      this.x1 + this.tipLength / 2, \n      this.y1, \n      [\n        ['stroke', this.strokeColor],\n        ['stroke-width', this.strokeWidth.toString()]\n      ]);\n    this.tip1.transform.baseVal.appendItem(SvgHelper.createTransform());\n    this.visual.appendChild(this.tip1);\n\n    this.tip2 = SvgHelper.createLine(\n      this.x2 - this.tipLength / 2, \n      this.y2, \n      this.x2 + this.tipLength / 2, \n      this.y2, \n      [\n        ['stroke', this.strokeColor],\n        ['stroke-width', this.strokeWidth.toString()]\n      ]);\n    this.tip2.transform.baseVal.appendItem(SvgHelper.createTransform());\n    this.visual.appendChild(this.tip2);\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) down event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerDown(point: IPoint, target?: EventTarget): void {\n    super.pointerDown(point, target);\n  }\n\n  /**\n   * Adjusts marker visual after manipulation.\n   */\n  protected adjustVisual(): void {\n    super.adjustVisual();\n\n    if (this.tip1 && this.tip2) {\n\n      SvgHelper.setAttributes(this.tip1,[\n        ['x1', (this.x1 - this.tipLength / 2).toString()], \n        ['y1', this.y1.toString()], \n        ['x2', (this.x1 + this.tipLength / 2).toString()], \n        ['y2', this.y1.toString()], \n        ['stroke', this.strokeColor],\n        ['stroke-width', this.strokeWidth.toString()]\n      ]);\n      SvgHelper.setAttributes(this.tip2,[\n        ['x1', (this.x2 - this.tipLength / 2).toString()], \n        ['y1', this.y2.toString()], \n        ['x2', (this.x2 + this.tipLength / 2).toString()], \n        ['y2', this.y2.toString()], \n        ['stroke', this.strokeColor],\n        ['stroke-width', this.strokeWidth.toString()]\n      ]);\n\n      if (Math.abs(this.x1 - this.x2) > 0.1) {\n        const lineAngle1 =\n          (Math.atan((this.y2 - this.y1) / (this.x2 - this.x1)) * 180) / Math.PI + 90 * Math.sign(this.x1 - this.x2);\n\n        const a1transform = this.tip1.transform.baseVal.getItem(0);\n        a1transform.setRotate(lineAngle1, this.x1, this.y1);\n        this.tip1.transform.baseVal.replaceItem(a1transform, 0);\n\n        const a2transform = this.tip2.transform.baseVal.getItem(0);\n        a2transform.setRotate(lineAngle1 + 180, this.x2, this.y2);\n        this.tip2.transform.baseVal.replaceItem(a2transform, 0);\n      }\n    }\n  }\n\n  /**\n   * Restores previously saved marker state.\n   * \n   * @param state - previously saved state.\n   */\n  public restoreState(state: MarkerBaseState): void {\n    super.restoreState(state);\n\n    this.createTips();\n    this.adjustVisual();\n  }\n}\n","import { EllipseMarker } from '../ellipse-marker/EllipseMarker';\n\nexport class EllipseFrameMarker extends EllipseMarker {\n  /**\n   * String type name of the marker type. \n   * \n   * Used when adding {@link MarkerView.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static typeName = 'EllipseFrameMarker';\n  /**\n   * Marker type title (display name) used for accessibility and other attributes.\n   */\n  public static title = 'Ellipse frame marker';\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   */\n  constructor(container: SVGGElement) {\n    super(container);\n\n    this.fillColor = 'transparent';\n  }\n}\n","import { IPoint } from '../../core/IPoint';\nimport { SvgHelper } from '../../core/SvgHelper';\nimport { LinearMarkerBase } from '../LinearMarkerBase';\nimport { CurveMarkerState } from './CurveMarkerState';\nimport { MarkerBaseState } from '../../core/MarkerBaseState';\n\nexport class CurveMarker extends LinearMarkerBase {\n  /**\n   * String type name of the marker type. \n   * \n   * Used when adding {@link MarkerView.availableMarkerTypes} via a string and to save and restore state.\n   */\n  public static typeName = 'CurveMarker';\n  \n  /**\n   * Marker type title (display name) used for accessibility and other attributes.\n   */\n  public static title = 'Curve marker';\n  /**\n   * Invisible wider curve to make selection easier/possible.\n   */\n  protected selectorCurve: SVGPathElement;\n  /**\n   * Visible marker curve.\n   */\n  protected visibleCurve: SVGPathElement;\n\n  /**\n   * Line color.\n   */\n  protected strokeColor = 'transparent';\n  /**\n   * Line width.\n   */\n  protected strokeWidth = 0;\n  /**\n   * Line dash array.\n   */\n  protected strokeDasharray = '';\n\n  private curveX = 0;\n  private curveY = 0;\n\n  /**\n   * Creates a new marker.\n   *\n   * @param container - SVG container to hold marker's visual.\n   */\n  constructor(container: SVGGElement) {\n    super(container);\n\n    this.setStrokeColor = this.setStrokeColor.bind(this);\n    this.setStrokeWidth = this.setStrokeWidth.bind(this);\n    this.setStrokeDasharray = this.setStrokeDasharray.bind(this);\n    this.adjustVisual = this.adjustVisual.bind(this);\n    this.resize = this.resize.bind(this);\n  }\n\n  /**\n   * Returns true if passed SVG element belongs to the marker. False otherwise.\n   * \n   * @param el - target element.\n   */\n  public ownsTarget(el: EventTarget): boolean {\n    if (\n      super.ownsTarget(el) ||\n      el === this.visual ||\n      el === this.selectorCurve ||\n      el === this.visibleCurve\n    ) {\n      return true;\n    } else {\n      return false;\n    }\n  }\n\n  private getPathD(): string {\n    const result = `M ${this.x1} ${this.y1} Q ${this.curveX} ${this.curveY}, ${this.x2} ${this.y2}`;\n    return result;\n  }\n\n  private createVisual() {\n    this.visual = SvgHelper.createGroup();\n    this.selectorCurve = SvgHelper.createPath(\n      this.getPathD(),\n      [\n        ['stroke', 'transparent'],\n        ['stroke-width', (this.strokeWidth + 10).toString()],\n        ['fill', 'transparent'],\n      ]\n    );\n    this.visibleCurve = SvgHelper.createPath(\n      this.getPathD(),\n      [\n        ['stroke', this.strokeColor],\n        ['stroke-width', this.strokeWidth.toString()],\n        ['fill', 'transparent'],\n      ]\n    );\n    this.visual.appendChild(this.selectorCurve);\n    this.visual.appendChild(this.visibleCurve);\n\n    this.addMarkerVisualToContainer(this.visual);\n  }\n\n  /**\n   * Handles pointer (mouse, touch, stylus, etc.) down event.\n   * \n   * @param point - event coordinates.\n   * @param target - direct event target element.\n   */\n  public pointerDown(point: IPoint, target?: EventTarget): void {\n    super.pointerDown(point, target);\n  }\n\n  /**\n   * Adjusts visual after manipulation.\n   */\n  protected adjustVisual(): void {\n    this.selectorCurve.setAttribute('d', this.getPathD());\n\n    this.visibleCurve.setAttribute('d', this.getPathD());\n\n    SvgHelper.setAttributes(this.visibleCurve, [['stroke', this.strokeColor]]);\n    SvgHelper.setAttributes(this.visibleCurve, [['stroke-width', this.strokeWidth.toString()]]);\n    SvgHelper.setAttributes(this.visibleCurve, [['stroke-dasharray', this.strokeDasharray.toString()]]);\n  }\n\n  /**\n   * Sets line color.\n   * @param color - new color.\n   */\n  protected setStrokeColor(color: string): void {\n    this.strokeColor = color;\n    this.adjustVisual();\n  }\n  /**\n   * Sets line width.\n   * @param width - new width.\n   */\n  protected setStrokeWidth(width: number): void {\n    this.strokeWidth = width\n    this.adjustVisual();\n  }\n\n  /**\n   * Sets line dash array.\n   * @param dashes - new dash array.\n   */\n  protected setStrokeDasharray(dashes: string): void {\n    this.strokeDasharray = dashes;\n    this.adjustVisual();\n  }\n\n  /**\n   * Scales marker. Used after the image resize.\n   * \n   * @param scaleX - horizontal scale\n   * @param scaleY - vertical scale\n   */\n   public scale(scaleX: number, scaleY: number): void {\n    this.curveX = this.curveX * scaleX;\n    this.curveY = this.curveY * scaleY;\n    super.scale(scaleX, scaleY);\n  }\n\n  /**\n   * Restores previously saved marker state.\n   * \n   * @param state - previously saved state.\n   */\n  public restoreState(state: MarkerBaseState): void {\n    super.restoreState(state);\n\n    const lmState = state as CurveMarkerState;\n    this.strokeColor = lmState.strokeColor;\n    this.strokeWidth = lmState.strokeWidth;\n    this.strokeDasharray = lmState.strokeDasharray;\n    this.curveX = lmState.curveX;\n    this.curveY = lmState.curveY;\n\n    this.createVisual();\n    this.adjustVisual();\n  }\n}\n","/**\n * Simple utility CSS-in-JS implementation.\n */\nexport class StyleManager {\n\n  private _classNamePrefixBase = '__markerjslive_';\n  /**\n   * Static CSS class name used for the wrapper element.\n   */\n   public get classNamePrefixBase(): string {\n    return this._classNamePrefixBase;\n  }\n\n  private _classNamePrefix: string;\n  /**\n   * Prefix used for all internally created CSS classes.\n   */\n  public get classNamePrefix(): string {\n    return this._classNamePrefix;\n  }\n\n  private classes: StyleClass[] = [];\n  private rules: StyleRule[] = [];\n  private styleSheet?: HTMLStyleElement;\n\n  /**\n   * For cases when you need to add the stylesheet to anything\n   * other than document.head (default), set this property\n   * before calling `show()`.\n   */\n  public styleSheetRoot: HTMLElement;\n\n  /**\n   * Initializes a new style manager.\n   * @param instanceNo - instance id.\n   */\n  constructor(instanceNo: number) {\n    this._classNamePrefix = `${this._classNamePrefixBase}_${instanceNo}_`;\n  }\n\n  /**\n   * Adds a CSS class declaration.\n   * @param styleClass - class to add.\n   */\n  public addClass(styleClass: StyleClass): StyleClass {\n    if (this.styleSheet === undefined) {\n      this.addStyleSheet();\n    }\n    styleClass.name = `${this.classNamePrefix}${styleClass.localName}`;\n    this.classes.push(styleClass);\n    this.styleSheet.sheet.insertRule(\n      `.${styleClass.name} {${styleClass.style}}`,\n      this.styleSheet.sheet.cssRules.length\n    );\n    return styleClass;\n  }\n\n  /**\n   * Add arbitrary CSS rule\n   * @param styleRule - CSS rule to add.\n   */\n  public addRule(styleRule: StyleRule): void {\n    if (this.styleSheet === undefined) {\n      this.addStyleSheet();\n    }\n    this.rules.push(styleRule);\n    // this.styleSheet.sheet.addRule(styleRule.selector, styleRule.style); // crashes in legacy Edge\n    this.styleSheet.sheet.insertRule(\n      `${styleRule.selector} {${styleRule.style}}`,\n      this.styleSheet.sheet.cssRules.length\n    );\n  }\n\n  private addStyleSheet() {\n    this.styleSheet = document.createElement('style');\n    (this.styleSheetRoot ?? document.head).appendChild(this.styleSheet);\n  }\n\n  public removeStyleSheet(): void {\n    if (this.styleSheet) {\n      (this.styleSheetRoot ?? document.head).removeChild(this.styleSheet);\n      this.styleSheet = undefined;\n    }\n  }\n}\n\n/**\n * Represents an arbitrary CSS rule.\n */\nexport class StyleRule {\n  /**\n   * CSS selector.\n   */\n  public selector: string;\n  /**\n   * Style declaration for the rule.\n   */\n  public style: string;\n  /**\n   * Creates an arbitrary CSS rule using the selector and style rules.\n   * @param selector - CSS selector\n   * @param style - styles to apply\n   */\n  constructor(selector: string, style: string) {\n    this.selector = selector;\n    this.style = style; \n  }\n}\n\n/**\n * Represents a CSS class.\n */\nexport class StyleClass {\n  /**\n   * CSS style rules for the class.\n   */\n  public style: string;\n  \n  /**\n   * Class name without the global prefix.\n   */\n  public localName: string;\n  /**\n   * Fully qualified CSS class name.\n   */\n  public name: string;\n\n  /**\n   * Creates a CSS class declaration based on supplied (local) name and style rules.\n   * @param name - local CSS class name (will be prefixed with the marker.js prefix).\n   * @param style - style declarations.\n   */\n  constructor(name: string, style: string) {\n    this.localName = name;\n    this.style = style; \n  }\n}\n","import { MarkerView } from '../MarkerView';\nimport { MarkerBase } from './MarkerBase';\n\n/**\n * General MarkerView event handler type.\n */\nexport type MarkerViewEventHandler = (markerView: MarkerView) => void;\n\n/**\n * Marker event handler type.\n */\nexport type MarkerEventHandler = (\n  markerView: MarkerView,\n  marker?: MarkerBase\n) => void;\n\n/**\n * Pointer related marker event handler type.\n */\nexport type PointerEventHandler = (\n  markerView: MarkerView,\n  event: PointerEvent,\n  marker?: MarkerBase\n) => void;\n\n/**\n * Describes a repository of MarkerView event handlers.\n */\nexport interface IEventListenerRepository {\n  /**\n   * Event handlers for the `create` event.\n   */\n  create: MarkerViewEventHandler[];\n  /**\n   * Event handlers for the `close` event.\n   */\n  close: MarkerViewEventHandler[];\n  /**\n   * Event handlers for the `load` event.\n   */\n  load: MarkerViewEventHandler[];\n  /**\n   * Event handlers for the `select` event.\n   */\n  select: MarkerEventHandler[];\n  /**\n   * Event handlers for the `over` event.\n   */\n  over: MarkerEventHandler[];\n  /**\n   * Event handlers for the `pointerdown` event.\n   */\n  pointerdown: PointerEventHandler[];\n  /**\n   * Event handlers for the `pointermove` event.\n   */\n  pointermove: PointerEventHandler[];\n  /**\n   * Event handlers for the `pointerup` event.\n   */\n  pointerup: PointerEventHandler[];\n  /**\n   * Event handlers for the `pointerenter` event.\n   */\n  pointerenter: PointerEventHandler[];\n  /**\n   * Event handlers for the `pointerleave` event.\n   */\n  pointerleave: PointerEventHandler[];\n}\n\n/**\n * Event handler type for a specific event type.\n */\nexport type EventHandler<\n  T extends keyof IEventListenerRepository\n> = T extends 'select'\n  ? MarkerEventHandler\n  : T extends 'over'\n  ? MarkerEventHandler\n  : T extends 'pointerdown'\n  ? PointerEventHandler\n  : T extends 'pointermove'\n  ? PointerEventHandler\n  : T extends 'pointerup'\n  ? PointerEventHandler\n  : T extends 'pointerenter'\n  ? PointerEventHandler\n  : T extends 'pointerleave'\n  ? PointerEventHandler\n  : MarkerViewEventHandler;\n\n/**\n * Event handler repository.\n */\nexport class EventListenerRepository implements IEventListenerRepository {\n  /**\n   * Event handlers for the `create` event.\n   */\n  create: MarkerViewEventHandler[] = [];\n  /**\n   * Event handlers for the `close` event.\n   */\n  close: MarkerViewEventHandler[] = [];\n  /**\n   * Event handlers for the `load` event.\n   */\n  load: MarkerViewEventHandler[] = [];\n  /**\n   * Event handlers for the `select` event.\n   */\n  select: MarkerEventHandler[] = [];\n  /**\n   * Event handlers for the `over` event.\n   */\n  over: MarkerEventHandler[] = [];\n  /**\n   * Event handlers for the `pointerdown` event.\n   */\n  pointerdown: PointerEventHandler[] = [];\n  /**\n   * Event handlers for the `pointermove` event.\n   */\n  pointermove: PointerEventHandler[] = [];\n  /**\n   * Event handlers for the `pointerup` event.\n   */\n  pointerup: PointerEventHandler[] = [];\n  /**\n   * Event handlers for the `pointerenter` event.\n   */\n  pointerenter: PointerEventHandler[] = [];\n  /**\n   * Event handlers for the `pointerleave` event.\n   */\n  pointerleave: PointerEventHandler[] = [];\n\n  /**\n   * Add an event handler for a specific event type.\n   * @param eventType - event type.\n   * @param handler - function to handle the event.\n   */\n  public addEventListener<T extends keyof IEventListenerRepository>(\n    eventType: T,\n    handler: EventHandler<T>\n  ): void {\n    (<Array<EventHandler<T>>>this[eventType]).push(handler);\n  }\n\n  /**\n   * Remove an event handler for a specific event type.\n   * @param eventType - event type.\n   * @param handler - function currently handling the event.\n   */\n  public removeEventListener<T extends keyof IEventListenerRepository>(\n    eventType: T,\n    handler: EventHandler<T>\n  ): void {\n    const index = (<Array<EventHandler<T>>>this[eventType]).indexOf(handler);\n    if (index > -1) {\n      (<Array<EventHandler<T>>>this[eventType]).splice(index, 1);\n    }\n  }\n}\n","import { SvgHelper } from './core/SvgHelper';\nimport { Activator } from './core/Activator';\n\nimport Logo from './assets/markerjs-logo-m.svg';\n\nimport { MarkerBase } from './core/MarkerBase';\nimport { FrameMarker } from './markers/frame-marker/FrameMarker';\nimport { LineMarker } from './markers/line-marker/LineMarker';\nimport { TextMarker } from './markers/text-marker/TextMarker';\nimport { FreehandMarker } from './markers/freehand-marker/FreehandMarker';\nimport { ArrowMarker } from './markers/arrow-marker/ArrowMarker';\nimport { CoverMarker } from './markers/cover-marker/CoverMarker';\nimport { HighlightMarker } from './markers/highlight-marker/HighlightMarker';\nimport { CalloutMarker } from './markers/callout-marker/CalloutMarker';\nimport { EllipseMarker } from './markers/ellipse-marker/EllipseMarker';\nimport { MeasurementMarker } from './markers/measurement-marker/MeasurementMarker';\nimport { EllipseFrameMarker } from './markers/ellipse-frame-marker/EllipseFrameMarker';\nimport { CurveMarker } from './markers/curve-marker/CurveMarker';\n\nimport { MarkerAreaState } from './MarkerAreaState';\nimport { IPoint } from './core/IPoint';\n\nimport { StyleManager } from './core/Style';\nimport {\n  EventHandler,\n  EventListenerRepository,\n  IEventListenerRepository,\n} from './core/Events';\nimport { IMarkerViewPlugin } from './core/MarkerViewPlugin';\n\n/**\n * MarkerViews is the main class of marker.js Live. It controls the core behavior of the library.\n *\n * The simplest marker.js Live usage scenario looks something like this:\n *\n * ```typescript\n * // skip this line if you are importing marker.js Live into the global space via the script tag\n * import * as mjslive from 'markerjs-live';\n *\n * // create an instance of MarkerView and pass the target image reference as a parameter\n * const markerView = new mjslive.MarkerView(target);\n *\n * // call the show() method and pass your annotation configuration (created with marker.js 2) as a parameter\n * markerView.show(markerState);\n * ```\n */\nexport class MarkerView {\n  private target: HTMLElement;\n  private targetObserver: ResizeObserver;\n\n  private imageWidth: number;\n  private imageHeight: number;\n  private left: number;\n  private top: number;\n\n  public markerImage: SVGSVGElement;\n  private markerImageHolder: HTMLDivElement;\n  private defs: SVGDefsElement;\n\n  private coverDiv: HTMLDivElement;\n  private uiDiv: HTMLDivElement;\n  private contentDiv: HTMLDivElement;\n  private editorCanvas: HTMLDivElement;\n  private editingTarget: HTMLCanvasElement;\n  private overlayContainer: HTMLDivElement;\n\n  private touchPoints = 0;\n\n  private logoUI: HTMLElement;\n\n  private static instanceCounter = 0;\n  private _instanceNo: number;\n  /**\n   * Instance id of this instance\n   */\n  public get instanceNo(): number {\n    return this._instanceNo;\n  }\n\n  /**\n   * Manage style releated settings via the `styles` property.\n   */\n  public styles: StyleManager;\n\n  /**\n   * Marker types supported by this instance. \n   * You can remove some types to limit the markers displayed.\n   */\n  public availableMarkerTypes: typeof MarkerBase[] = [\n    FrameMarker,\n    FreehandMarker,\n    ArrowMarker,\n    TextMarker,\n    EllipseFrameMarker,\n    EllipseMarker,\n    HighlightMarker,\n    CalloutMarker,\n    MeasurementMarker,\n    CoverMarker,\n    LineMarker,\n    CurveMarker\n  ];\n\n  /**\n   * `targetRoot` is used to set an alternative positioning root.\n   *\n   * This is useful in cases when your target image is positioned, say, inside a div with `position: relative;`\n   *\n   * ```typescript\n   * // set targetRoot to a specific div instead of document.body\n   * markerView.targetRoot = document.getElementById('myRootElement');\n   * ```\n   *\n   * @default document.body\n   */\n  public targetRoot: HTMLElement;\n\n  private currentMarker?: MarkerBase;\n  private hoveredMarker?: MarkerBase;\n  /**\n   * The list of all markers displayed.\n   */\n  public markers: MarkerBase[] = [];\n\n  private isDragging = false;\n\n  private _isOpen = false;\n  /**\n   * Returns `true` when MarkerView is open and `false` otherwise.\n   *\n   * @readonly\n   */\n  public get isOpen(): boolean {\n    return this._isOpen;\n  }\n\n  private plugins: IMarkerViewPlugin[] = [];\n\n  /**\n   * The suffix of the CSS class name of the marker container (SVG group) element.\n   */\n  public readonly MARKER_CONTAINER_CLASS_SUFFIX = 'marker-container';\n\n  /**\n   * Creates a new MarkerView for the specified target image.\n   *\n   * ```typescript\n   * // create an instance of MarkerView and pass the target image reference as a parameter\n   * let markerView = new mjslive.MarkerView(document.getElementById('myimg'));\n   * ```\n   *\n   * @param target image object to be overlayed with markers.\n   */\n  constructor(target: HTMLElement) {\n    this._instanceNo = MarkerView.instanceCounter++;\n\n    this.styles = new StyleManager(this.instanceNo);\n\n    this.target = target;\n    this.targetRoot = document.body;\n\n    this.open = this.open.bind(this);\n    this.setTopLeft = this.setTopLeft.bind(this);\n\n    this.addNewMarker = this.addNewMarker.bind(this);\n    this.setCurrentMarker = this.setCurrentMarker.bind(this);\n    this.onPointerDown = this.onPointerDown.bind(this);\n    this.onDblClick = this.onDblClick.bind(this);\n    this.onPointerMove = this.onPointerMove.bind(this);\n    this.onPointerUp = this.onPointerUp.bind(this);\n    this.onKeyUp = this.onKeyUp.bind(this);\n    this.close = this.close.bind(this);\n    this.closeUI = this.closeUI.bind(this);\n    this.clientToLocalCoordinates = this.clientToLocalCoordinates.bind(this);\n    this.onWindowResize = this.onWindowResize.bind(this);\n    this.removeMarker = this.removeMarker.bind(this);\n  }\n\n  private open(): void {\n    this.setupResizeObserver();\n    this.setEditingTarget();\n    this.setTopLeft();\n    this.initMarkerCanvas();\n    this.initOverlay();\n    this.attachEvents();\n\n    if (!Activator.isLicensed) {\n      // NOTE:\n      // before removing this call please consider supporting marker.js\n      // by visiting https://markerjs.com/ for details\n      // thank you!\n      this.addLogo();\n    }\n\n    this._isOpen = true;\n  }\n\n  /**\n   * Initializes the MarkerView and show the markers.\n   * \n   * @param state - marker configuration created with marker.js 2.\n   */\n  public show(state: MarkerAreaState): void {\n    this.showUI();\n    this.open();\n    \n    this.plugins.forEach(plugin => plugin.init(this));\n    \n    this.eventListeners['create'].forEach((created) => created(this));\n\n    this.restoreState(state);\n\n    this.eventListeners['load'].forEach((loaded) => loaded(this));\n  }\n\n  /**\n   * Closes the MarkerView.\n   */\n  public close(): void {\n    if (this.isOpen) {\n      if (this.coverDiv) {\n        this.closeUI();\n      }\n      if (this.targetObserver) {\n        this.targetObserver.unobserve(this.target);\n      }\n      this._isOpen = false;\n\n      this.eventListeners['close'].forEach(closed => closed(this));\n    }\n  }\n\n  private setupResizeObserver() {\n    if (window.ResizeObserver) {\n      this.targetObserver = new ResizeObserver(() => {\n        this.resize(this.target.clientWidth, this.target.clientHeight);\n      });\n      this.targetObserver.observe(this.target);\n    }\n  }\n\n  private resize(newWidth: number, newHeight: number) {\n    const scaleX = newWidth / this.imageWidth;\n    const scaleY = newHeight / this.imageHeight;\n\n    this.imageWidth = Math.round(newWidth);\n    this.imageHeight = Math.round(newHeight);\n    // this.editingTarget.src = this.target.src;\n    this.editingTarget.width = this.imageWidth;\n    this.editingTarget.height = this.imageHeight;\n    this.editingTarget.style.width = `${this.imageWidth}px`;\n    this.editingTarget.style.height = `${this.imageHeight}px`;\n\n    this.markerImage.setAttribute('width', this.imageWidth.toString());\n    this.markerImage.setAttribute('height', this.imageHeight.toString());\n    this.markerImage.setAttribute(\n      'viewBox',\n      '0 0 ' + this.imageWidth.toString() + ' ' + this.imageHeight.toString()\n    );\n\n    this.markerImageHolder.style.width = `${this.imageWidth}px`;\n    this.markerImageHolder.style.height = `${this.imageHeight}px`;\n\n    this.overlayContainer.style.width = `${this.imageWidth}px`;\n    this.overlayContainer.style.height = `${this.imageHeight}px`;\n\n    this.coverDiv.style.width = `${this.imageWidth.toString()}px`;\n\n    this.positionLogo();\n\n    this.scaleMarkers(scaleX, scaleY);\n  }\n\n  private scaleMarkers(scaleX: number, scaleY: number) {\n    let preScaleSelectedMarker: MarkerBase;\n    if (!(this.currentMarker && this.currentMarker instanceof TextMarker)) {\n      preScaleSelectedMarker = this.currentMarker;\n      this.setCurrentMarker();\n    }\n    this.markers.forEach((marker) => marker.scale(scaleX, scaleY));\n    if (preScaleSelectedMarker !== undefined) {\n      this.setCurrentMarker(preScaleSelectedMarker);\n    }\n  }\n\n  private setEditingTarget() {\n    this.imageWidth = Math.round(this.target.clientWidth);\n    this.imageHeight = Math.round(this.target.clientHeight);\n    // this.editingTarget.src = this.target.src;\n    this.editingTarget.width = this.imageWidth;\n    this.editingTarget.height = this.imageHeight;\n    this.editingTarget.style.width = `${this.imageWidth}px`;\n    this.editingTarget.style.height = `${this.imageHeight}px`;\n  }\n\n  private setTopLeft() {\n    const targetRect = this.editingTarget.getBoundingClientRect();\n    const bodyRect = this.editorCanvas.getBoundingClientRect();\n    this.left = targetRect.left - bodyRect.left;\n    this.top = targetRect.top - bodyRect.top;\n  }\n\n  private initMarkerCanvas(): void {\n    this.markerImageHolder = document.createElement('div');\n    this.markerImageHolder.style.setProperty('touch-action', 'pinch-zoom');\n\n    this.markerImage = document.createElementNS(\n      'http://www.w3.org/2000/svg',\n      'svg'\n    );\n    this.markerImage.setAttribute('xmlns', 'http://www.w3.org/2000/svg');\n    this.markerImage.setAttribute('width', this.imageWidth.toString());\n    this.markerImage.setAttribute('height', this.imageHeight.toString());\n    this.markerImage.setAttribute(\n      'viewBox',\n      '0 0 ' + this.imageWidth.toString() + ' ' + this.imageHeight.toString()\n    );\n    this.markerImage.style.pointerEvents = 'auto';\n\n    this.markerImageHolder.style.position = 'absolute';\n    this.markerImageHolder.style.width = `${this.imageWidth}px`;\n    this.markerImageHolder.style.height = `${this.imageHeight}px`;\n    this.markerImageHolder.style.transformOrigin = 'top left';\n    this.positionMarkerImage();\n\n    this.defs = SvgHelper.createDefs();\n    this.markerImage.appendChild(this.defs);\n\n    this.markerImageHolder.appendChild(this.markerImage);\n\n    this.editorCanvas.appendChild(this.markerImageHolder);\n  }\n\n  private initOverlay(): void {\n    this.overlayContainer = document.createElement('div');\n    this.overlayContainer.style.position = 'absolute';\n    this.overlayContainer.style.left = '0px';\n    this.overlayContainer.style.top = '0px';\n    this.overlayContainer.style.width = `${this.imageWidth}px`;\n    this.overlayContainer.style.height = `${this.imageHeight}px`;\n    this.overlayContainer.style.display = 'flex';\n    this.markerImageHolder.appendChild(this.overlayContainer);\n  }\n\n  private positionMarkerImage() {\n    this.markerImageHolder.style.top = this.top + 'px';\n    this.markerImageHolder.style.left = this.left + 'px';\n  }\n\n  private attachEvents() {\n    this.markerImage.addEventListener('pointerdown', this.onPointerDown);\n    this.markerImage.addEventListener('dblclick', this.onDblClick);\n    window.addEventListener('pointermove', this.onPointerMove);\n    window.addEventListener('pointerup', this.onPointerUp);\n    window.addEventListener('pointercancel', () => {\n      if (this.touchPoints > 0) {\n        this.touchPoints--;\n      }\n    });\n    window.addEventListener('pointerout', () => {\n      if (this.touchPoints > 0) {\n        this.touchPoints--;\n      }\n    });\n    window.addEventListener('pointerleave', this.onPointerUp);\n    window.addEventListener('resize', this.onWindowResize);\n    window.addEventListener('keyup', this.onKeyUp);\n  }\n\n  /**\n   * NOTE:\n   *\n   * before removing or modifying this method please consider supporting marker.js\n   * by visiting https://markerjs.com/#price for details\n   *\n   * thank you!\n   */\n  private addLogo() {\n    this.logoUI = document.createElement('div');\n    this.logoUI.style.display = 'inline-block';\n    this.logoUI.style.margin = '0px';\n    this.logoUI.style.padding = '0px';\n    this.logoUI.style.fill = '#333333';\n\n    const link = document.createElement('a');\n    link.href = 'https://markerjs.com/';\n    link.target = '_blank';\n    link.innerHTML = Logo;\n    link.title = 'Powered by marker.js';\n\n    link.style.display = 'grid';\n    link.style.alignItems = 'center';\n    link.style.justifyItems = 'center';\n    link.style.padding = '3px';\n    link.style.width = '20px';\n    link.style.height = '20px';\n\n    this.logoUI.appendChild(link);\n\n    this.editorCanvas.appendChild(this.logoUI);\n\n    this.logoUI.style.position = 'absolute';\n    this.logoUI.style.pointerEvents = 'all';\n    this.positionLogo();\n  }\n\n  private positionLogo() {\n    if (this.logoUI) {\n      this.logoUI.style.left = `${this.markerImageHolder.offsetLeft + 10}px`;\n      this.logoUI.style.top = `${\n        this.markerImageHolder.offsetTop +\n        this.markerImageHolder.offsetHeight -\n        this.logoUI.clientHeight -\n        10\n      }px`;\n    }\n  }\n\n  private showUI(): void {\n    this.coverDiv = document.createElement('div');\n    this.coverDiv.className = `${this.styles.classNamePrefixBase} ${this.styles.classNamePrefix}`;\n    // hardcode font size so nothing inside is affected by higher up settings\n    this.coverDiv.style.fontSize = '16px';\n    this.coverDiv.style.userSelect = 'none';\n    this.coverDiv.style.position = 'absolute';\n    this.coverDiv.style.top = `${this.target.offsetTop.toString()}px`;\n    this.coverDiv.style.left = `${this.target.offsetLeft.toString()}px`;\n    this.coverDiv.style.width = `${this.target.offsetWidth.toString()}px`;\n    //this.coverDiv.style.height = `${this.target.offsetHeight.toString()}px`;\n    this.coverDiv.style.zIndex = '5';\n    // flex causes the ui to stretch when toolbox has wider nowrap panels\n    //this.coverDiv.style.display = 'flex';\n    this.targetRoot.appendChild(this.coverDiv);\n\n    this.uiDiv = document.createElement('div');\n    this.uiDiv.style.display = 'flex';\n    this.uiDiv.style.flexDirection = 'column';\n    this.uiDiv.style.flexGrow = '2';\n    this.uiDiv.style.margin = '0px';\n    this.uiDiv.style.border = '0px';\n    // this.uiDiv.style.overflow = 'hidden';\n    //this.uiDiv.style.backgroundColor = '#ffffff';\n    this.coverDiv.appendChild(this.uiDiv);\n\n    this.contentDiv = document.createElement('div');\n    this.contentDiv.style.display = 'flex';\n    this.contentDiv.style.flexDirection = 'row';\n    this.contentDiv.style.flexGrow = '2';\n    this.contentDiv.style.flexShrink = '1';\n    this.uiDiv.appendChild(this.contentDiv);\n\n    this.editorCanvas = document.createElement('div');\n    this.editorCanvas.style.flexGrow = '2';\n    this.editorCanvas.style.flexShrink = '1';\n    this.editorCanvas.style.position = 'relative';\n    this.editorCanvas.style.overflow = 'hidden';\n    this.editorCanvas.style.display = 'flex';\n    this.editorCanvas.style.pointerEvents = 'none';\n    this.contentDiv.appendChild(this.editorCanvas);\n\n    this.editingTarget = document.createElement('canvas');\n    this.editorCanvas.appendChild(this.editingTarget);\n  }\n\n  private closeUI() {\n    // @todo better cleanup\n    this.targetRoot.removeChild(this.coverDiv);\n  }\n\n  private removeMarker(marker: MarkerBase) {\n    this.markerImage.removeChild(marker.container);\n    if (this.markers.indexOf(marker) > -1) {\n      this.markers.splice(this.markers.indexOf(marker), 1);\n    }\n    marker.dispose();\n  }\n\n  /**\n   * Uses the state created with marker.js 2 to display the markers.\n   *\n   * @param state - previously saved marker.js 2 state object.\n   */\n  private restoreState(state: MarkerAreaState): void {\n    this.markers.splice(0);\n    while (this.markerImage.lastChild) {\n      this.markerImage.removeChild(this.markerImage.lastChild);\n    }\n    state.markers.forEach((markerState) => {\n      const markerType = this.availableMarkerTypes.find(\n        (mType) => mType.typeName === markerState.typeName\n      );\n      if (markerType !== undefined) {\n        const marker = this.addNewMarker(markerType);\n        marker.restoreState(markerState);\n        this.markers.push(marker);\n      }\n    });\n    if (\n      state.width &&\n      state.height &&\n      (state.width !== this.imageWidth || state.height !== this.imageHeight)\n    ) {\n      this.scaleMarkers(\n        this.imageWidth / state.width,\n        this.imageHeight / state.height\n      );\n    }\n  }\n\n  private addNewMarker(markerType: typeof MarkerBase): MarkerBase {\n    const g = SvgHelper.createGroup();\n    g.setAttribute('class', `${this.styles.classNamePrefix}${this.MARKER_CONTAINER_CLASS_SUFFIX}`);\n    this.markerImage.appendChild(g);\n\n    return new markerType(g);\n  }\n\n  /**\n   * Sets the currently selected marker or deselects it if no parameter passed.\n   *\n   * @param marker marker to select. Deselects current marker if undefined.\n   */\n  public setCurrentMarker(marker?: MarkerBase): void {\n    const currentChanged = this.currentMarker !== marker;\n\n    if (this.currentMarker !== undefined) {\n      this.currentMarker.deselect();\n    }\n    this.currentMarker = marker;\n    if (this.currentMarker !== undefined) {\n      this.currentMarker.select();\n    }\n\n    if (currentChanged) {\n      this.eventListeners['select'].forEach((selected) =>\n        selected(this, marker)\n      );\n    }\n  }\n\n  private onPointerDown(ev: PointerEvent) {\n    this.touchPoints++;\n    if (this.touchPoints === 1 || ev.pointerType !== 'touch') {\n      const hitMarker = this.markers.find((m) => m.ownsTarget(ev.target));\n      if (hitMarker !== undefined) {\n        this.setCurrentMarker(hitMarker);\n        this.isDragging = true;\n        this.currentMarker.pointerDown(\n          this.clientToLocalCoordinates(ev.clientX, ev.clientY),\n          ev.target\n        );\n      } else {\n        this.setCurrentMarker();\n      }\n\n      if (this.eventListeners['pointerdown'].length > 0) {\n        this.eventListeners['pointerdown'].forEach((pointerDownHandler) =>\n          pointerDownHandler(this, ev, hitMarker)\n        );\n      }\n    }\n  }\n\n  private onDblClick(ev: PointerEvent) {\n    const hitMarker = this.markers.find((m) => m.ownsTarget(ev.target));\n    if (hitMarker !== undefined && hitMarker !== this.currentMarker) {\n      this.setCurrentMarker(hitMarker);\n    }\n    if (this.currentMarker !== undefined) {\n      this.currentMarker.dblClick(\n        this.clientToLocalCoordinates(ev.clientX, ev.clientY),\n        ev.target\n      );\n    } else {\n      this.setCurrentMarker();\n    }\n  }\n\n  private isPointerIn = false;\n  private onPointerMove(ev: PointerEvent) {\n    if (this.touchPoints === 1 || ev.pointerType !== 'touch') {\n      if (this.currentMarker !== undefined || this.isDragging) {\n        ev.preventDefault();\n      }\n    }\n\n    if (\n      this.eventListeners['over'].length > 0 ||\n      this.eventListeners['pointermove'].length > 0\n    ) {\n      const hitMarker = this.markers.find((m) => m.ownsTarget(ev.target));\n      if (hitMarker !== this.hoveredMarker) {\n        this.hoveredMarker = hitMarker;\n        this.eventListeners['over'].forEach((overHandler) =>\n          overHandler(this, this.hoveredMarker)\n        );\n      }\n\n      this.eventListeners['pointermove'].forEach((pointerMoveHandler) =>\n        pointerMoveHandler(this, ev, hitMarker)\n      );\n\n      if (!this.isPointerIn && (hitMarker !== undefined || this.markerImage === ev.target)) {\n        this.isPointerIn = true;\n        this.eventListeners['pointerenter'].forEach((pointerEnterHandler) =>\n          pointerEnterHandler(this, ev, hitMarker)\n        );\n      }\n\n      if (this.isPointerIn && hitMarker === undefined && this.markerImage !== ev.target) {\n        this.isPointerIn = false;\n        this.eventListeners['pointerleave'].forEach((pointerLeaveHandler) =>\n          pointerLeaveHandler(this, ev, hitMarker)\n        );\n      }\n    }\n  }\n\n  private onPointerUp(ev: PointerEvent) {\n    if (this.touchPoints > 0) {\n      this.touchPoints--;\n    }\n    if (this.touchPoints === 0) {\n      if (this.isDragging && this.currentMarker !== undefined) {\n        this.currentMarker.pointerUp(\n          this.clientToLocalCoordinates(ev.clientX, ev.clientY)\n        );\n      }\n    }\n    this.isDragging = false;\n\n    if (this.eventListeners['pointerup'].length > 0) {\n      const hitMarker = this.markers.find((m) => m.ownsTarget(ev.target));\n      this.eventListeners['pointerup'].forEach((pointerUpHandler) =>\n        pointerUpHandler(this, ev, hitMarker)\n      );\n    }\n\n  }\n\n  private onKeyUp(ev: KeyboardEvent) {\n    if (\n      this.currentMarker !== undefined &&\n      (ev.key === 'Delete' || ev.key === 'Backspace')\n    ) {\n      this.removeMarker(this.currentMarker);\n      this.setCurrentMarker();\n      this.markerImage.style.cursor = 'default';\n    }\n  }\n\n  private clientToLocalCoordinates(x: number, y: number): IPoint {\n    const clientRect = this.markerImage.getBoundingClientRect();\n    return { x: x - clientRect.left, y: y - clientRect.top };\n  }\n\n  private onWindowResize() {\n    this.positionUI();\n  }\n\n  private positionUI() {\n    this.setTopLeft();\n    this.coverDiv.style.top = `${this.target.offsetTop.toString()}px`;\n    this.coverDiv.style.left = `${this.target.offsetLeft.toString()}px`;\n    this.positionMarkerImage();\n    this.positionLogo();\n  }\n\n  private eventListeners = new EventListenerRepository();\n  /**\n   * Adds an event listener for one of the marker.js Live events.\n   * \n   * @param eventType - type of the event.\n   * @param handler - function handling the event.\n   */\n  public addEventListener<T extends keyof IEventListenerRepository>(\n    eventType: T,\n    handler: EventHandler<T>\n  ): void {\n    this.eventListeners.addEventListener(eventType, handler);\n  }\n\n  /**\n   * Removes an event listener for one of the marker.js Live events.\n   * \n   * @param eventType - type of the event.\n   * @param handler - function currently handling the event.\n   */\n  public removeEventListener<T extends keyof IEventListenerRepository>(\n    eventType: T,\n    handler: EventHandler<T>\n  ): void {\n    this.eventListeners.removeEventListener(eventType, handler);\n  }\n\n  /**\n   * Adds a plugin to the plugin array.\n   * @param plugin \n   */\n  public addPlugin(plugin: IMarkerViewPlugin): void {\n    this.plugins.push(plugin);\n  }\n  \n  /**\n   * Removes a plugin from the plugin array.\n   * @param plugin \n   */\n  public removePlugin(plugin: IMarkerViewPlugin): void {\n    const pluginIndex = this.plugins.indexOf(plugin);\n    if (pluginIndex >= 0) {\n      this.plugins.splice(pluginIndex, 1);\n    }\n  }\n}\n"],"names":["SvgHelper","document","createElementNS","stylesheet","setAttribute","el","attributes","attributes_1","_i","_a","attr","value","width","height","rect","toString","setAttributes","x1","y1","x2","y2","line","points","polygon","radius","circle","rx","ry","ellipse","g","createSVGTransform","id","orient","markerWidth","markerHeight","refX","refY","markerElement","marker","appendChild","text","tspan","textContent","image","x","y","svgPoint","createSVGPoint","d","path","Activator","key","Object","RegExp","test","extendStatics","b","setPrototypeOf","__proto__","Array","p","prototype","hasOwnProperty","call","__extends","__","this","constructor","create","container","_outerContainer","innerContainer","createGroup","_container","MarkerBase","point","target","element","childNodes","length","insertBefore","state","notes","scaleX","scaleY","TransformMatrix","matrix","a","c","e","f","currentMatrix","newMatrix","_super","_this","transform","baseVal","appendItem","createTransform","RectangularBoxMarkerBase","left","top","_visual","translate","ownsTarget","pointerDown","select","pointerUp","visual","style","setSize","moveVisual","Math","abs","centerX","sign","rotationAngle","atan","centerY","PI","applyRotation","rotate","getItem","setRotate","replaceItem","getCTM","createPoint","matrixTransform","inverse","deselect","restoreState","rbmState","setMatrix","toSVGMatrix","visualTransformMatrix","containerTransformMatrix","scale","rPoint","rotatePoint","unrotatePoint","setStrokeColor","bind","setFillColor","setStrokeWidth","setStrokeDasharray","createVisual","RectangleMarker","createRect","fillColor","strokeColor","strokeWidth","strokeDasharray","opacity","addMarkerVisualToContainer","resize","color","dashes","rectState","FrameMarker","LinearMarkerBase","adjustVisual","lmbState","LineMarker","selectorLine","visibleLine","createLine","lmState","defaultSize","setColor","setFont","renderText","sizeText","TextMarker","textElement","bgRectangle","found_1","forEach","span","createText","fontFamily","pointerDownPoint","lastChild","removeChild","split","createTSpan","trim","setTimeout","textSize","getBBox","xScale","padding","yScale","min","textBBox","getTextScale","position","getTextPosition","navigator","userAgent","indexOf","setTranslate","setScale","dblClick","font","textState","FreehandMarker","drawingImage","createImage","drawingImgUrl","setDrawingImage","getArrowPoints","setArrowType","ArrowMarker","arrow1","arrow2","offsetX","offsetY","arrowBaseWidth","arrowBaseHeight","createPolygon","display","arrowType","lineAngle1","a1transform","a2transform","amState","createTips","CoverMarker","setOpacity","HighlightMarker","setBgColor","getTipPoints","positionTip","setTipPoints","CalloutMarker","tip","bgColor","tipBase1Position","tipBase2Position","tipPosition","isCreating","offset","baseWidth","cornerAngle","calloutState","createTip","EllipseMarker","createEllipse","MeasurementMarker","tip1","tip2","tipLength","EllipseFrameMarker","CurveMarker","selectorCurve","visibleCurve","curveX","curveY","createPath","getPathD","instanceNo","_classNamePrefix","_classNamePrefixBase","StyleManager","styleClass","undefined","styleSheet","addStyleSheet","name","classNamePrefix","localName","classes","push","sheet","insertRule","cssRules","styleRule","rules","selector","createElement","styleSheetRoot","head","EventListenerRepository","eventType","handler","index","splice","_instanceNo","MarkerView","instanceCounter","styles","targetRoot","body","open","setTopLeft","addNewMarker","setCurrentMarker","onPointerDown","onDblClick","onPointerMove","onPointerUp","onKeyUp","close","closeUI","clientToLocalCoordinates","onWindowResize","removeMarker","_isOpen","setupResizeObserver","setEditingTarget","initMarkerCanvas","initOverlay","attachEvents","isLicensed","addLogo","showUI","plugins","plugin","init","eventListeners","created","loaded","isOpen","coverDiv","targetObserver","unobserve","closed","window","ResizeObserver","clientWidth","clientHeight","observe","newWidth","newHeight","imageWidth","imageHeight","round","editingTarget","markerImage","markerImageHolder","overlayContainer","positionLogo","scaleMarkers","preScaleSelectedMarker","currentMarker","markers","targetRect","getBoundingClientRect","bodyRect","editorCanvas","setProperty","pointerEvents","transformOrigin","positionMarkerImage","defs","createDefs","addEventListener","touchPoints","logoUI","margin","fill","link","href","innerHTML","title","alignItems","justifyItems","offsetLeft","offsetTop","offsetHeight","className","classNamePrefixBase","fontSize","userSelect","offsetWidth","zIndex","uiDiv","flexDirection","flexGrow","border","contentDiv","flexShrink","overflow","dispose","markerState","markerType","availableMarkerTypes","find","mType","typeName","MARKER_CONTAINER_CLASS_SUFFIX","currentChanged","selected","ev","pointerType","hitMarker_1","m","isDragging","clientX","clientY","pointerDownHandler","hitMarker","preventDefault","hitMarker_2","hoveredMarker","overHandler","pointerMoveHandler","isPointerIn","pointerEnterHandler","pointerLeaveHandler","hitMarker_3","pointerUpHandler","cursor","clientRect","positionUI","removeEventListener","pluginIndex"],"mappings":"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"}
\ No newline at end of file
diff --git a/capsule-prototype/js/libs/markerjslive/package.json b/capsule-prototype/js/libs/markerjslive/package.json
new file mode 100644
index 0000000000000000000000000000000000000000..8194a7c443a8142c92983f17a74f806392476afa
--- /dev/null
+++ b/capsule-prototype/js/libs/markerjslive/package.json
@@ -0,0 +1,26 @@
+{
+  "name": "markerjs-live",
+  "version": "1.0.2",
+  "description": "Live player for image annotations created with marker.js 2",
+  "main": "markerjs-live.js",
+  "module": "markerjs-live.esm.js",
+  "types": "markerjs-live.d.ts",
+  "author": "Alan Mendelevich",
+  "license": "SEE LICENSE IN LICENSE",
+  "scripts": {},
+  "repository": {
+    "type": "git",
+    "url": "https://github.com/ailon/markerjs-live"
+  },
+  "keywords": [
+    "annotate",
+    "mark",
+    "highlight",
+    "image",
+    "photo",
+    "graphics",
+    "javascript",
+    "typescript",
+    "comment"
+  ]
+}
diff --git a/capsule-prototype/js/online-rekall/Project.js b/capsule-prototype/js/online-rekall/Project.js
index 6698c77fbccdc4cea39cda5b5c18a0085ad3607f..c741f51b66d8213e29f117d76d8490f875c034db 100644
--- a/capsule-prototype/js/online-rekall/Project.js
+++ b/capsule-prototype/js/online-rekall/Project.js
@@ -55,11 +55,6 @@ Project.prototype.getDocument = function(path) {
 
 Project.prototype.loadXML = function(xml) {
 	this.sources["Files"] = new Source();
-	/*
-	this.sources["Files"].addMapping("file:///Users/guillaume/Documents/Rekall/Walden/Enregistrements/infinitespaces-test8H264.mov", "file:///Users/guillaume/Documents/Rekall/Walden/Test.txt");
-	this.sources["Files"].addMapping("file:///Users/guillaume/Documents/Rekall/Walden/Test.txt", "file:///Users/guillaume/Documents/Rekall/Walden/Enregistrements/infinitespaces-test8H264.mov");
-	this.sources["Files"].addMapping("file:///Users/guillaume/Documents/Rekall/Walden/Technique/trad auto.doc", "file:///Users/guillaume/Documents/Rekall/Walden/Enregistrements/infinitespaces-test8H264.mov");
-	*/
 
 	var thiss = this;
 	var counts = {documents: 0, tags: 0, metadatas: 0};
@@ -276,24 +271,6 @@ Project.prototype.analyse = function() {
 			var tag = colorSortingCategory.tags[key];
 			tag.update(colorSortingCategory.color);
 			tag.isSelectable = colorSortingCategory.checked;
-
-			//Analyse de vignettes
-			/*
-			if(true) {
-				var thumbUrl = undefined
-				if((tag.getMetadata("File->Thumbnail") != undefined) && (tag.getMetadata("File->Thumbnail") != "")) {
-					var thumbUrl = Utils.getPreviewPath(tag);
-
-					if(tag.isVideo())	thumbUrl += "_1.jpg";
-					else				thumbUrl +=  ".jpg";
-				}
-				tag.thumbnail = {url: thumbUrl, tag: tag};
-
-				if(rekall.panner.thumbnails[colorSortingCategory.category] == undefined)
-					rekall.panner.thumbnails[colorSortingCategory.category] = {category: colorSortingCategory, thumbnails: [], documents: []};
-				rekall.panner.thumbnails[colorSortingCategory.category].thumbnails.push(tag.thumbnail);
-			}
-			*/
 		}
 	}
 	
@@ -349,25 +326,20 @@ Project.prototype.analyse = function() {
 			if((tag.getMetadata("Rekall->Highlight") != undefined) && (tag.getMetadata("Rekall->Highlight") != "")) {   
 			
 				//Dom
-				//$('#flattentimeline_highlight').append(function() {     
 				$('#flattentimeline').append(function() {
 					var styleColor = "background-color: " + tag.color + ";";
 					var textColor = "color: " + tag.color + ";";       
 					var textColor2 = "color: rgba(255,255,255,1)";     
 					var textColor3 = "color: rgba(255,255,255,.75)";
 					
-					var colorTransp = "";//styleColor.replace(/rgb/g, "rgba").replace(/\)/g, ",.75)");
+					var colorTransp = "";
 
-					/*var styleColor = "background-image: -webkit-linear-gradient(left, #000 0%, " + tag.color + " 100%);";*/
-					var styleColor2 = styleColor;//"background-color: #3EA8B1;";
+					var styleColor2 = styleColor;
 					var styleImage = "";
 					if(tag.thumbnail.url != undefined) {  
 
-						//styleImage = "background-image: url(" + tag.thumbnail.url + ");";//" opacity: 0.5;";
 						styleImage = "background-image: -webkit-linear-gradient(right bottom,  rgba(20,46,51,.60) 0%,rgba(20,46,51,.90) 100%), url(" + tag.thumbnail.url + "); background-image: -moz-linear-gradient(right bottom,  rgba(20,46,51,.60) 0%,rgba(20,46,51,.90) 100%), url(" + tag.thumbnail.url + "); background-image: -o-linear-gradient(right bottom,  rgba(20,46,51,.60) 0%,rgba(20,46,51,.90) 100%), url(" + tag.thumbnail.url + ");";
-						//	styleImage = "background-image: -webkit-linear-gradient(right bottom,  "+tag.color.replace(/rgb/g, "rgba").replace(/\)/g, ",.6)")+" 0%,"+tag.color.replace(/rgb/g, "rgba").replace(/\)/g, ",.9)")+" 100%), url(" + tag.thumbnail.url + ");";
-						/*styleColor += "opacity: 0.25;"; */
-					} else styleImage = "background-color: " + tag.color + "; background-image: -webkit-linear-gradient(right bottom, rgba(20,46,51,.5) 0%,rgba(20,46,51,.8) 100%); background-image: -moz-linear-gradient(right bottom, rgba(20,46,51,.5) 0%,rgba(20,46,51,.8) 100%); background-image: -o-linear-gradient(right bottom, rgba(20,46,51,.5) 0%,rgba(20,46,51,.8) 100%);" ;//styleColor.replace(/rgb/g, "rgba").replace(/\)/g, ",.85)");//"background-color: rgba(255,255,255,.25)";
+					} else styleImage = "background-color: " + tag.color + "; background-image: -webkit-linear-gradient(right bottom, rgba(20,46,51,.5) 0%,rgba(20,46,51,.8) 100%); background-image: -moz-linear-gradient(right bottom, rgba(20,46,51,.5) 0%,rgba(20,46,51,.8) 100%); background-image: -o-linear-gradient(right bottom, rgba(20,46,51,.5) 0%,rgba(20,46,51,.8) 100%);" ;
 
 					var icnType = "";
 					var tmpType = tag.getMetadata("Rekall->Type");
@@ -381,22 +353,9 @@ Project.prototype.analyse = function() {
 					else if(tmpType.indexOf("video/") >=0 ) 			icnType = "background-image:url(css/images/icn-video.png);";  
 					
 					var typeTxt = tmpType.split("/")[1].replace(/marker/g, "note");  
-                                    
-                    /*
-					var htmlHighlight = ""; 
-					htmlHighlight	+=	"<div draggable=true class='flattentimeline_item flattentimeline_highlightitem' style='"+colorTransp+"' >";
-					if(tag.thumbnail.url != undefined)  htmlHighlight	+=	"<div class='flattentimeline_type'			style='" + icnType +"' title='" + tmpType + "'></div>";       
-					htmlHighlight	+=	"<div class='flattentimeline_image'      	style='" + styleImage + "'></div>"; 
-					htmlHighlight 	+=	"<div class='flattentimeline_title' 		style='" + textColor2 + "' title='" + tag.getMetadata("Rekall->Name") + "'>" + tag.getMetadata("Rekall->Name") + "</div>";   
-					htmlHighlight 	+=	"<div class='flattentimeline_description' style='" + textColor3 + "'>" + tag.getMetadata("Rekall->Comments") + "</div>"; 
-					htmlHighlight 	+= "<div class='flattentimeline_opacifiant' style='" + styleColor2 + "'></div>";  
-					htmlHighlight    += "</div>";   
-					*/                              
 					
 					var htmlHighlight = ""; 
 					htmlHighlight	+=	"<div draggable=true class='flattentimeline_item flattentimeline_highlightitem' style='"+colorTransp+" "+styleImage+"'>";
-					//if(tag.thumbnail.url != undefined)  htmlHighlight	+=	"<div class='flattentimeline_type'			style='" + icnType +"' title='" + tmpType + "'></div>";       
-					//htmlHighlight	+=	"<div class='flattentimeline_image'      	style='"+colorTransp+" "+styleImage+"'></div>"; 
 					htmlHighlight 	+=	"<div class='flattentimeline_title' 		style='" + textColor + "' title='" + tag.getMetadata("Rekall->Name") + "'>" + tag.getMetadata("Rekall->Name") + "</div>"; 
 					
 					
@@ -410,7 +369,6 @@ Project.prototype.analyse = function() {
 						var tmpcount = 0;
 						var tmpIndex = tmpComments.indexOf("<br/>");
 						while((tmpcount<3)&&(tmpIndex!=-1)) {
-							//alert(tmpComments+" / "+tmpIndex);
 							tmpcount++;
 							tmpIndex = tmpComments.indexOf("<br/>",tmpIndex+1);
 						}
@@ -430,7 +388,6 @@ Project.prototype.analyse = function() {
 					tag.flattenTimelineDom = $(htmlHighlight); 
 					tag.flattenTimelineDom.click(function(event) { 
 						tag.openPopupEdit();                
-						//tag.openBrowser();
 					});
 					tag.flattenTimelineDom.on({
 						dragstart: function(event) {
@@ -454,12 +411,10 @@ Project.prototype.analyse = function() {
 					
 					var colorTransp = styleColor.replace(/rgb/g, "rgba").replace(/\)/g, ",.75)");
 
-					/*var styleColor = "background-image: -webkit-linear-gradient(left, #000 0%, " + tag.color + " 100%);";*/
-					var styleColor2 = styleColor;//"background-color: #3EA8B1;";
+					var styleColor2 = styleColor;
 					var styleImage = "";
 					if(tag.thumbnail.url != undefined) {
-						styleImage = "background-image: url(" + tag.thumbnail.url + ");";//" opacity: 0.5;";
-						/*styleColor += "opacity: 0.25;"; */
+						styleImage = "background-image: url(" + tag.thumbnail.url + ");";
 					} else styleImage = "background-color: rgba(255,255,255,.25)";
 
 					var icnType = "";
@@ -485,7 +440,6 @@ Project.prototype.analyse = function() {
 					tag.flattenTimelineDom = $(html);
 					tag.flattenTimelineDom.click(function(event) {                
 						tag.openPopupEdit(); 
-						//tag.openBrowser();
 					});
 					tag.flattenTimelineDom.on({
 						dragstart: function(event) {
@@ -521,7 +475,6 @@ Project.prototype.analyse = function() {
 					'font-family': 		'OpenSans',
 				},
 				onCaptionChange: function(num_c) {
-					//console.log("playing: " + num_c + " caption");
 				}
 			}
 		});
diff --git a/capsule-prototype/js/online-rekall/Tag.js b/capsule-prototype/js/online-rekall/Tag.js
index 3968ddbe48af655930a723a491e87a37d19912bf..f6cd7fe6bfd0195d6e861e3b3cee41cf94f72d0b 100644
--- a/capsule-prototype/js/online-rekall/Tag.js
+++ b/capsule-prototype/js/online-rekall/Tag.js
@@ -98,6 +98,12 @@ Tag.prototype.openQuickLook = function() {
 Tag.prototype.downloadFile = function() {
 	return this.document.downloadFile();
 }
+Tag.prototype.getDownloadLink = function(original = false) {
+  return this.document.getDownloadLink(original);
+}
+Tag.prototype.getFileName = function() {
+  return this.document.getFileName();
+}
 Tag.prototype.openBrowser = function() {
 	return this.document.openBrowser();
 }   
@@ -138,30 +144,4 @@ Tag.prototype.update = function(color, strong) {
 		strokeColor = this.color;
 		strokeWidth = 0.8;
 	}
-	
-	/*
-	if((this.selected) || (this.document.selected > 0)) {
-		strokeColor = '#FFFFFF';
-		if(this.selected) {
-			if(strong)		strokeWidth = 2;
-			else			strokeWidth = 1.5;
-		}
-		else
-			strokeWidth       = 0.8;
-	}
-	
-	if(this.isMarkerCache) {
-		if(strokeColor == "")
-			this.visuel.rect.setStroke(fillColor);	
-		else
-			this.visuel.rect.setStroke(strokeColor);
-		this.visuel.rect.setStrokeWidth(max(1, strokeWidth));
-	}
-	else {
-		this.visuel.rect.setFill       (fillColor);
-		this.visuel.rect.setStroke     (strokeColor);	
-		this.visuel.rect.setStrokeWidth(strokeWidth);
-	}
-	this.visuel.rect.setOpacity(opacity);
-	*/
 }
diff --git a/capsule-prototype/js/online-rekall/Timeline.js b/capsule-prototype/js/online-rekall/Timeline.js
index 2b004b23b0db3103a97e054ed7c135a3e6749dad..b6ac6e58ff2c2d8af1bc5da660559e926716701d 100644
--- a/capsule-prototype/js/online-rekall/Timeline.js
+++ b/capsule-prototype/js/online-rekall/Timeline.js
@@ -92,7 +92,6 @@ Timeline.prototype.updateFlattenTimeline = function() {
 				var dom = tag.flattenTimelineDom;
 				if(dom != undefined) {
 					if(progress == undefined) {         
-						//dom.slideUp();  
 						dom.removeClass("docTocome").removeClass("docLive").removeClass("docFaraway");
 						dom.find(".flattentimeline_counter").hide();
 					}
@@ -103,17 +102,13 @@ Timeline.prototype.updateFlattenTimeline = function() {
 							dom.find(".flattentimeline_opacifiant").css("width", "100%");
 
 						if((0 <= progress) && (progress < 1))  
-							dom.removeClass("docTocome").removeClass("docFaraway").addClass("docLive");//.slideDown();//("opacity", 1.0).slideDown();   
-							//dom.css("opacity", 1.0).slideDown();
+							dom.removeClass("docTocome").removeClass("docFaraway").addClass("docLive");
 						else if((-5 <= progress) && (progress <= 0))
-							dom.removeClass("docLive").removeClass("docFaraway").addClass("docTocome");//.slideDown();
-							//dom.css("opacity", 0.5).slideDown();
+							dom.removeClass("docLive").removeClass("docFaraway").addClass("docTocome");
 						else if(-9999999 < progress)
-							dom.removeClass("docTocome").removeClass("docLive").addClass("docFaraway");//.slideDown();
-							//dom.css("opacity", 0.1).slideDown();
+							dom.removeClass("docTocome").removeClass("docLive").addClass("docFaraway");
 						else         
-							dom.removeClass("docTocome").removeClass("docLive").removeClass("docFaraway");//.hide();
-							//dom.css("opacity", 0.1).hide();
+							dom.removeClass("docTocome").removeClass("docLive").removeClass("docFaraway");
 					}
 				}
 			}
diff --git a/capsule-prototype/js/online-script.js b/capsule-prototype/js/online-script.js
index 53bf01c47a605794eec5d5195791abfa102ee153..34d52382b1b0832faf8d114b7c12f38e1b0054b5 100644
--- a/capsule-prototype/js/online-script.js
+++ b/capsule-prototype/js/online-script.js
@@ -50,26 +50,6 @@ $(document).ready(function() {
 
 				setEditionControls();
 
-				//Geoloc en mode édition
-				/*
-				if((false) && (navigator.geolocation)) {
-					navigator.geolocation.getCurrentPosition(function(position) {
-						rekall_common.owner.locationGps = position.coords.latitude + "," + position.coords.longitude;
-						$.ajax("http://maps.googleapis.com/maps/api/geocode/json", {
-							type: "GET",
-							dataType: "json",
-							data: {"latlng": rekall_common.owner.locationGps},
-							success: function(infos) {
-								if((infos.results != undefined) && (infos.results[0] != undefined) && (infos.results[0].formatted_address != undefined))
-									rekall_common.owner.locationName = infos.results[0].formatted_address;
-							},
-							error: function() {
-							}
-						});
-					});
-				}
-				*/
-
 			} else {
 				$(".empty").hide();
 				$(".displayMode").show();
@@ -136,7 +116,6 @@ $(document).ready(function() {
 	});
 
 	$("#popupAlertButtonYesdeleteproject").click(function(){
-		//alert("pouf");
 		removeProject();
 	});
 
@@ -211,13 +190,6 @@ function setEditionControls() {
 		drop: function(event) { $("#flattentimeline").removeClass("draggable").removeClass("drag");  }
 	});
 
-	/*
-	$("#left_menu_bottom").click(function(event){
-		//var tmp = $(".vjs-marker").css("z-index");
-		//alert("val = "+tmp);
-	});
-	*/
-
 	$("#left_menu_item_settings").click(function(event){
 		event.stopPropagation();
 		rekall.timeline.pause();
@@ -307,15 +279,12 @@ function setEditionControls() {
 		var isEnter = false;
 		if (event.key !== undefined) {
 			if (event.key === 'Enter' && event.altKey) {
-				//openAlert('Alt + Enter pressed!');
 			} else if(event.key === 'Enter') isEnter = true;
 		} else if (event.keyIdentifier !== undefined) {
 			if (event.keyIdentifier === "Enter" && event.altKey) {
-				//openAlert('Alt + Enter pressed!');
 			} else if(event.keyIdentifier === 'Enter') isEnter = true;
 		} else if (event.keyCode !== undefined) {
 			if (event.keyCode === 13 && event.altKey) {
-				//openAlert('Alt + Enter pressed!');
 			} else if(event.keyCode === 13) isEnter = true;
 		}
 
@@ -434,7 +403,7 @@ function setEditionControls() {
 		event.stopPropagation();
 		closeInputs();
 		$("#popupTC").hide();
-		$("#popupTCedit").show();//.focus();
+		$("#popupTCedit").show();
 	});
 
 	$(".popupTCeditfield").click(function(event){
@@ -540,30 +509,6 @@ function setEditionControls() {
 		}
 	});
 
-	//Validation du commentaire avec Entrée = désactivé
-	/*$("#popupLegendeInput").keyup(function(event){
-		event.stopPropagation();
-
-		var isEnter = false;
-		if (event.key !== undefined) {
-		       if (event.key === 'Enter' && event.altKey) {
-		          //openAlert('Alt + Enter pressed!');
-		       } else if(event.key === 'Enter') isEnter = true;
-		    } else if (event.keyIdentifier !== undefined) {
-		       if (event.keyIdentifier === "Enter" && event.altKey) {
-		          //openAlert('Alt + Enter pressed!');
-		       } else if(event.keyIdentifier === 'Enter') isEnter = true;
-		    } else if (event.keyCode !== undefined) {
-		       if (event.keyCode === 13 && event.altKey) {
-		          //openAlert('Alt + Enter pressed!');
-		    } else if(event.keyCode === 13) isEnter = true;
-		}
-
-		if(isEnter == true) {
-			closeInputs();
-		}
-	}); */
-
 	$("#popupAuthorInput").keyup(function(event){
 		event.stopPropagation();
 		if(event.which == 13) {
@@ -602,40 +547,38 @@ function setEditionControls() {
     console.debug("set playback rate to " + event.target.value);
     window.app.rekall.Rekall().videoPlayer.playbackRate(Number(event.target.value));
   });
-}
 
-/*var rubanTimeout = 0;
-var rubanMessage = "";
-var rubanTimeoutTime = 0;
-function openAlert(message, duration) {
-	alert("ça passe ?");
-	if(message == undefined) {
-		clearInterval(rubanTimeout);
-		$("#ruban").slideUp(function() {
-			$("#ruban").html("");
-		});
-	}
-	else if($("#ruban").text().length == 0) {
-		openAlert();
-		messageWithClose = message;
-		if(duration == undefined)
-			duration = 15;
-		rubanTimeoutTime = duration;
-		rubanTimeout = setInterval(function() {
-			rubanTimeoutTime--;
-			if(rubanTimeoutTime > 0) {
-				if(rubanTimeoutTime > 1000)
-					messageWithClose = message + "&nbsp;&nbsp;&nbsp;&nbsp;<u onClick='javascript:openAlert();'>&times;&nbsp;close</u>";
-				else
-					messageWithClose = message + "&nbsp;&nbsp;&nbsp;&nbsp;<u onClick='javascript:openAlert();'>&times;&nbsp;autoclose in " + rubanTimeoutTime + " sec.</u>";
-				$("#ruban").html(messageWithClose);
-				$("#ruban").slideDown();
-			}
-			else
-				openAlert();
-		}, 1000);
-	}
-}*/
+  $('#editAnnotationPic').click(function(ev) {
+    $('#edit_pic_modal').show();
+    var keyDoc = ev.target.parentElement.parentElement.attributes['keydoc'];
+    var markerArea = new markerjs2.MarkerArea(document.getElementById('annotation_img_edit'));
+    markerArea.targetRoot = document.getElementById('edit_pic_modal');
+    markerArea.addEventListener('render', (event) => {
+      var state = markerArea.getState();
+      window.my_current_markerjs_data_in_ugly_global = state;
+      markerArea.close(true);
+      setMetaFromDom(keyDoc.value, "Rekall->MarkerjsState", btoa(JSON.stringify(state)));
+
+      var b64img = event.dataUrl;
+      var data = b64img.match(/data:([a-z]+)\/([a-z]+);base64,(.*)/);
+      var type = data[1], subtype = data[2], b64data = data[3];
+      var bin_str = atob(b64data);
+      var n = b64data.length;
+      var uar = new Uint8Array(n);
+      while (n--) uar[n] = bin_str.charCodeAt(n);
+      var file = new File([uar], keyDoc.value.substr(1), {type: type+'/'+subtype});
+      $('#left_menu_item_btn_addfile').files = [file];
+      uploadFiles([file], {'edited': 1});
+      $('#popupImg').attr('src', $('#popupImg').attr('src') + '&time=' + performance.now());
+    });
+    markerArea.addEventListener('close', () => $('#edit_pic_modal').hide());
+    markerArea.renderAtNaturalSize = true;
+    markerArea.show();
+    if (window.my_current_markerjs_data_in_ugly_global)
+      markerArea.restoreState(window.my_current_markerjs_data_in_ugly_global);
+
+  })
+}
 
 function closeSettingsPopup() {
 	closeSettingsInputs();
@@ -780,7 +723,6 @@ function closeSettingsInputs() {
 			}
 		}
 
-		//alert("ok");
 	});
 	$(".popupSettingsInput").hide();
 	$(".popupSettingsTxt").show();
@@ -873,8 +815,6 @@ function closeInputs() {
 				if(isReturn) return true;
 			}
 		}
-
-		//alert("ok");
 	});
 	$(".popupInput:not(.popupInputNoHide)").hide();
 	$(".popupRightItem").show();
@@ -893,7 +833,7 @@ function closeEdit() {
 function openVideo() {
 		$('#mosaic_tab').hide();
 		$('#video_tab').show();
-		$('#left_menu .bottom').show();
+		$('#left_menu_controls').show();
 }
 
 function openMosaic() {
@@ -930,7 +870,7 @@ function openMosaic() {
 		rekall.timeline.pause();
 		$('#mosaic_tab').show();
 		$('#video_tab').hide();
-		$('#left_menu .bottom').hide();
+		$('#left_menu_controls').hide();
 
     let container = $('#mosaic_tab');
     container.html('');
@@ -1026,57 +966,66 @@ function getTagGradientColor(tag) {
 
 function fillPopupEdit(tag) {
 
-	//if(rekall_common.owner.canEdit) { alert("edit mode !"); }
 	var isPaused = rekall.timeline.isPaused();
 	rekall.timeline.pause();
 
- //   var bgColor = "-webkit-linear-gradient(right bottom,  rgb(20,46,51) 0%, #757F81 150%)" ; //"rgb(20,46,51)";
-
-	$("#popupEdit").attr("isPaused",isPaused);//.css("background",bgColor);
+	$("#popupEdit").attr("isPaused",isPaused);
 	$("#popupTC").css("background",tag.color);
-	/*$("#popupType").css("color",tag.color);*/
 
 	var bgColorLeft = tag.color.replace(/rgb/g, "rgba").replace(/\)/g, ",.35)");
 
-bgColorLeft = getTagGradientColor(tag);
+  bgColorLeft = getTagGradientColor(tag);
 
 	$("#popupLeft").css("background",bgColorLeft);
 
+  var type = tag.getMetadata("Rekall->Type");
+
+  $("#popupImg").unbind( "click" );
 	if(tag.isMarker()==true){
 		$("#popupImg").show();
 		$("#popupImg").attr("src","../shared/css/images/img-note.png");
-		$("#popupImg").unbind( "click" );
-
 	} else {
 		if(tag.thumbnail.url){
-			$("#popupImg").attr("src",tag.thumbnail.url);
+			$("#popupImg").attr("src", tag.getDownloadLink() || tag.thumbnail.url);
+      $('#annotation_img_edit').attr('src', tag.getDownloadLink(true));
 		} else {
-			var type = tag.getMetadata("Rekall->Type");
-			//alert(type);
-			if(type.indexOf("image") > -1) $("#popupImg").attr("src","../shared/css/images/img-image.png");  //alert("image");
-			else if(type.indexOf("pdf") > -1) $("#popupImg").attr("src","../shared/css/images/img-pdf.png");  //alert("pdf");
-			else if(type.indexOf("audio") > -1) $("#popupImg").attr("src","../shared/css/images/img-music.png");  //alert("son");
-			else if(type.indexOf("vcard") > -1) $("#popupImg").attr("src","../shared/css/images/img-user.png");  //alert("user");
-			else if(type.indexOf("video") > -1) $("#popupImg").attr("src","../shared/css/images/img-video.png");  //alert("video");
-			else if(type.indexOf("msword") > -1) $("#popupImg").attr("src","../shared/css/images/img-word.png");  //alert("word");
-			else if(type.indexOf("link") > -1) $("#popupImg").attr("src","../shared/css/images/img-link.png");  //alert("son");
-			else $("#popupImg").attr("src","../shared/css/images/img-document.png");  //alert(type);
+			if(type.indexOf("image") > -1) $("#popupImg").attr("src","../shared/css/images/img-image.png")
+			else if(type.indexOf("pdf") > -1) $("#popupImg").attr("src","../shared/css/images/img-pdf.png")
+			else if(type.indexOf("audio") > -1) $("#popupImg").attr("src","../shared/css/images/img-music.png")
+			else if(type.indexOf("vcard") > -1) $("#popupImg").attr("src","../shared/css/images/img-user.png")
+			else if(type.indexOf("video") > -1) $("#popupImg").attr("src","../shared/css/images/img-video.png")
+			else if(type.indexOf("msword") > -1) $("#popupImg").attr("src","../shared/css/images/img-word.png")
+			else if(type.indexOf("link") > -1) $("#popupImg").attr("src","../shared/css/images/img-link.png")
+			else $("#popupImg").attr("src","../shared/css/images/img-document.png");
 		}
-		$("#popupImg").unbind( "click" );
 		$("#popupImg").click(function(event){
 			event.stopPropagation();
 			if(tag.isLink()) {
-				if(link != "")
-				window.open(link,'_blank');
+				if(link != "") window.open(link,'_blank');
 			}
 			else
-				tag.openBrowser();
+				window.open($('#popupImg')[0].src, '_blank');
 		});
 	}
 
 	$("#popupNom").css("color",tag.color);
 
-	$("#popupType").html(tag.getMetadata("Rekall->Type")).css("color",tag.color);
+  window.my_current_markerjs_data_in_ugly_global = null;
+  $('#editAnnotationPic').hide();
+  $('#linkToOriginalImage').hide();
+  if (type.split('/')[0] == 'image') {
+    $('#editAnnotationPic').html('edit');
+    $('#editAnnotationPic').show();
+    $('#linkToOriginalImage').show();
+    $('#linkToOriginalImage').unbind('click');
+    $('#linkToOriginalImage').click(() => window.open(tag.getDownloadLink(true), '_blank'));
+    var data = tag.getMetadata('Rekall->MarkerjsState');
+    if (data)
+      window.my_current_markerjs_data_in_ugly_global = JSON.parse(atob(data));
+  }
+
+	$("#popupType").html(type).css("color",tag.color);
+
 	var name = tag.getMetadata("Rekall->Name");
 	if(name!="") $("#popupNom").html(name).removeClass("empty");
 	else $("#popupNom").html("+ Add a name").addClass("empty");
@@ -1265,15 +1214,11 @@ function deleteFromDomFinished() {
 
 //Gestion d'upload
 var filesToUpload = [], fileIsUploading = false;
-function uploadFiles(files) {
+function uploadFiles(files, additionnal_post_data={}) {
 	$.each(files, function(index, file) {
 		var formData = new FormData();
 
 		if(file.name != undefined) {
-			var colorCategory = rekall.sortings["colors"].categories[Sorting.prefix + file.type];
-			if(colorCategory != undefined) {
-			}
-			var fileType     = (file.type.split("/"))[0];
 			var fileDateTime = moment(file.lastModifiedDate);
 
 			if (file.size > rekall_common.uploadMax) {
@@ -1306,6 +1251,7 @@ function uploadFiles(files) {
 		formData.append("author",       rekall_common.owner.author);
 		formData.append("locationGps",  rekall_common.owner.locationGps);
 		formData.append("locationName", rekall_common.owner.locationName);
+    Object.keys(additionnal_post_data).forEach(k => formData.append(k, additionnal_post_data[k]));
 
 		if(formData != undefined) {
 			filesToUpload.push({
@@ -1320,13 +1266,11 @@ function uploadFiles(files) {
 					var myXhr = $.ajaxSettings.xhr();
 					if(myXhr.upload) {
 						myXhr.upload.addEventListener('progress', function(event) {
-							rouletteProgress(floor(event.loaded / event.total * 100));
+							rouletteProgress(Math.floor(event.loaded / event.total * 100));
 						}, false);
 					}
 					return myXhr;
 				},
-				beforeSend: function(data) {
-				},
 				success:    function(data) {
 					try {
 						console.log(data);
@@ -1385,7 +1329,6 @@ function shareEmbed() {
 	var embedUrl = '<iframe src="' + window.app.rekall.Rekall('getUrl', 'projectPreview') + '" width="' + width + '" height="' + height + '" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>';
 	embedUrl += '<p><a href="' + window.app.rekall.Rekall('getUrl', 'projectPreview') + '">' + window.app.rekall.Rekall('projectName') + '</a> from '+rekall.project.metadata["Author"]+' on <a href="http://www.memorekall.fr">MemoRekall</a>.</p>';
 	console.log(embedUrl);
-//	openAlert("Embed code in console");
 	return embedUrl;
 }
 
diff --git a/capsule-prototype/js/rekall/Document.js b/capsule-prototype/js/rekall/Document.js
index ff38052ec1dda2e11e9b222710a48a539e84af4a..f06c3ba2a28ebff72c67ad5c36c079a063531700 100644
--- a/capsule-prototype/js/rekall/Document.js
+++ b/capsule-prototype/js/rekall/Document.js
@@ -86,6 +86,15 @@ Document.prototype.isLink = function(version) {
 	else
 		return type.startsWith("rekall/link"); 
 }
+Document.prototype.getDownloadLink = function(original = false) {
+  var path = Utils.getLocalFilePath(this, "file");
+  return original ? path.replace('file.php?r=', 'file.php?r=rk_original_af7ef02e_') : path;
+}
+Document.prototype.getFileName = function() {
+  var path = Utils.getLocalFilePath(this, "file");
+  return path.replace(/.*r=(.*)/, (f, m) => m);
+}
+
 
 
 Document.availableMetadataKeys = new Object();
@@ -182,4 +191,4 @@ Document.prototype.downloadFile = function() {
 }
 
 function Metadata() {
-}
\ No newline at end of file
+}
diff --git a/capsule-prototype/js/rekall/Sorting.js b/capsule-prototype/js/rekall/Sorting.js
index 799f5a9956d05c782ab21e250e181826c9f867f0..614f7e0ee9dd43f4d7dde03e6d566d3af5ab635b 100644
--- a/capsule-prototype/js/rekall/Sorting.js
+++ b/capsule-prototype/js/rekall/Sorting.js
@@ -41,20 +41,6 @@ Sorting.prototype.setCriterias = function(metadataConfigStr, valCanBeFloats, met
 			var metadataKeyPortionFormula = metadataConfigs[1].trim().toLowerCase();
 			this.metadataFormat = metadataKeyPortionFormula;    
 			
-			/*
-			if     (this.metadataFormat == "year")			metadataKeyPortionFormula = "0,4";
-			else if(this.metadataFormat == "month")			metadataKeyPortionFormula = "0,6";
-			else if(this.metadataFormat == "day")			metadataKeyPortionFormula = "0,8";
-			else if(this.metadataFormat == "hour")			metadataKeyPortionFormula = "0,11";
-			else if(this.metadataFormat == "minute")		metadataKeyPortionFormula = "0,13";
-			else if(this.metadataFormat == "second")		metadataKeyPortionFormula = "0,15";
-			else if(this.metadataFormat == "year_only")		metadataKeyPortionFormula = "0,4";
-			else if(this.metadataFormat == "month_only")	metadataKeyPortionFormula = "4,2";
-			else if(this.metadataFormat == "day_only")		metadataKeyPortionFormula = "6,2";
-			else if(this.metadataFormat == "hour_only")		metadataKeyPortionFormula = "9,2";
-			else if(this.metadataFormat == "minute_only")	metadataKeyPortionFormula = "11,2";
-			else if(this.metadataFormat == "second_only")	metadataKeyPortionFormula = "13,2";
-			*/	                                                  
 			if     (this.metadataFormat == "year")			metadataKeyPortionFormula = "-1,-1,YYYY,YYYY";
 			else if(this.metadataFormat == "month")			metadataKeyPortionFormula = "-1,-1,YYYY:MM,MMMM YYYY";
 			else if(this.metadataFormat == "day")			metadataKeyPortionFormula = "-1,-1,YYYY:MM:DD,ddd LL";
@@ -83,8 +69,6 @@ Sorting.prototype.setCriterias = function(metadataConfigStr, valCanBeFloats, met
 		}
 	}           
 	
-	//alert(this.metadataKey+" / "+this.metadataFormat+" / "+analyse);
-	
 	if(valCanBeFloats == undefined)
 		valCanBeFloats = false;
 	this.valCanBeFloats = valCanBeFloats;
@@ -143,17 +127,11 @@ Sorting.prototype.analyseAdd = function(tag, metadata, alwaysIncludeTags, useThi
 		if(metadata == undefined)
 			metadata = tag.getMetadata(this.metadataKey);
 		var metadataRaw = metadata;
-//		if(metadataRaw == undefined) 
-//			metadataRaw = "Unknown";
 		if(metadataRaw == undefined)
 			return false;
 				
 		metadata = this.parseMeta(metadataRaw);
 
-		/*
-		if((metadata == Sorting.prefix) && (this.metadataKey != undefined) && (this.metadataKey != ""))
-			return false;
-		*/
 		if((this.metadataSearch != undefined) && (this.metadataSearch != "") && (metadata.toLowerCase().indexOf(this.metadataSearch.toLowerCase()) < 0))
 			return false;
 		
diff --git a/capsule-prototype/php/upload.php b/capsule-prototype/php/upload.php
index c069ed2ede0dee2460c1a6054f759e945f095ce6..69de6b99bccabd7f334473ad56e905efa2f9f542 100644
--- a/capsule-prototype/php/upload.php
+++ b/capsule-prototype/php/upload.php
@@ -57,24 +57,27 @@
 			
 			if(is_uploaded_file($_FILES[$fileinfo]['tmp_name'])) {
 				if(file_exists($_FILES[$fileinfo]['tmp_name'])) {
-					if(!file_exists($uploadFolder.$filename)) {
-						if(is_writable($uploadFolder)) {
+          if(is_writable($uploadFolder)) {
+              if(!file_exists($uploadFolder.$filename) || $_POST['edited'] == 1) {
 							//echo "Upload de ".$fileinfo."\t".$filename."...";
 							if(move_uploaded_file($_FILES[$fileinfo]['tmp_name'], $uploadFolder.$filename)) {
-								$metasAdded = addFileToProject($uploadFolder.$filename, $metas, $tcIn, $tcOut);
-								$key = $metasAdded["key"];
-								unset($metasAdded["key"]);
-								$retour .= '"code":1, "tcIn":'.$tcIn.', "tcOut":'.$tcOut.', "key":"'.$key.'", "status":"OK ('.(filesize($uploadFolder.$filename)/1000.).' kB)", "metas":'.json_encode($metasAdded);
+                if (!file_exists($uploadFolder.'rk_original_af7ef02e_'.$filename) && $_POST['edited'] != 1) {
+                  copy($uploadFolder.$filename, $uploadFolder.'original_'.$filename);
+                  $metasAdded = addFileToProject($uploadFolder.$filename, $metas, $tcIn, $tcOut);
+                  $key = $metasAdded["key"];
+                  unset($metasAdded["key"]);
+                  $retour .= '"code":1, "tcIn":'.$tcIn.', "tcOut":'.$tcOut.', "key":"'.$key.'", "status":"OK ('.(filesize($uploadFolder.$filename)/1000.).' kB)", "metas":'.json_encode($metasAdded);
+                }
 								$status |= true;
 							}
 							else
 								$retour .= '"code":0, "error":"Server error (copy of '.$uploadFolder.$filename.' is impossible)"';
 						}
 						else
-							$retour .= '"code":-1, "error":"The upload folder '.$uploadFolder.' has not enough permissions"';
+              $retour .= '"code":-2, "error":"File is already in project"';
 					}
 					else
-						$retour .= '"code":-2, "error":"File is already in project"';
+            $retour .= '"code":-1, "error":"The upload folder '.$uploadFolder.' has not enough permissions"';
 				} 
 				else
 					$retour .= '"code":-3, "error":"Server error in upload (temporary file missing)"';
@@ -154,4 +157,4 @@
 		    <input type="submit" value="Upload Image" name="submit">
 		</form>
 	</body>
-</html>
\ No newline at end of file
+</html>
diff --git a/src/Command/RekallProjectDuplicateImagesCommand.php b/src/Command/RekallProjectDuplicateImagesCommand.php
new file mode 100644
index 0000000000000000000000000000000000000000..74fbf3f902d040d173c7ce4ccef2cfb01a19c9c8
--- /dev/null
+++ b/src/Command/RekallProjectDuplicateImagesCommand.php
@@ -0,0 +1,143 @@
+<?php
+
+namespace App\Command;
+
+use LogicException;
+use Symfony\Component\Console\Attribute\AsCommand;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Helper\ProgressBar;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\ConsoleOutputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Filesystem\Filesystem;
+use Symfony\Component\Filesystem\Path;
+use Symfony\Component\HttpKernel\KernelInterface;
+
+#[AsCommand(
+    name: 'rekall:project:duplicate-images',
+    description: 'Duplicate each JPG/PNG/GIF file to keep original separated from edited',
+)]
+class RekallProjectDuplicateImagesCommand extends Command
+{
+    private Filesystem $file_system;
+    private KernelInterface $kernel;
+
+    private string $legacy_root;
+
+    private static string $LEGACY_DIRECTORY_NAME = 'legacy';
+    private static string $IMG_GLOB = '*.{[pP][nN][gG],[jJ][pP][gG],[jJ][pP][eE][gG],[gG][iI][fF]}';
+    private static string $ORIGINAL_FILE_PREPEND_WITH = 'rk_original_af7ef02e_';
+
+    public function __construct(Filesystem $filesystem, KernelInterface $kernel)
+    {
+        parent::__construct();
+        $this->file_system = $filesystem;
+        $this->kernel = $kernel;
+        $this->legacy_root = Path::join($this->kernel->getProjectDir(), self::$LEGACY_DIRECTORY_NAME);
+    }
+
+    protected function configure(): void
+    {
+    }
+
+    protected function execute(InputInterface $input, OutputInterface $output): int
+    {
+        if (!$output instanceof ConsoleOutputInterface) {
+            throw new LogicException('This command accepts only an instance of "ConsoleOutputInterface".');
+        }
+
+        ProgressBar::setFormatDefinition(
+            'project_update_message',
+            ' %current%/%max% [%bar%] %percent%% : Updating project :%project% %elapsed%'
+        );
+        $output->writeln('Updating images for all projects started');
+
+        $all_file_in_directory = $this->getProjectsDirectories();
+        if (false === $all_file_in_directory) {
+            return Command::FAILURE;
+        }
+
+        $all_projects_progress_bar = new ProgressBar($output->section());
+        $all_projects_progress_bar->setFormat(
+            '%current%/%max% [%bar%] %percent%% : Overall project update progressing (%elapsed%)'
+        );
+        $all_projects_progress_bar->SetMessage('Projects update progress');
+        $all_projects_progress_bar->start();
+
+        foreach ($all_projects_progress_bar->iterate($all_file_in_directory) as $project_directory) {
+            $current_legacy_path = Path::join($project_directory, 'file');
+
+            if (!$this->file_system->exists($current_legacy_path)) {
+                $output->writeln("'$current_legacy_path' don't exists");
+                continue;
+            }
+
+            if (!is_dir($current_legacy_path)) {
+                $output->writeln("'$current_legacy_path' is not a directory");
+                continue;
+            }
+
+            $this->updateProjectDirectory(
+                $output,
+                $current_legacy_path
+            );
+            $all_projects_progress_bar->advance();
+        }
+
+        $all_projects_progress_bar->finish();
+
+        return Command::SUCCESS;
+    }
+
+    /**
+     * @return string[]|false
+     */
+    private function getProjectsDirectories(): array|false
+    {
+        $all_directories_and_files = glob($this->legacy_root . '/*');
+        if (false === $all_directories_and_files) {
+            return false;
+        }
+        return $all_directories_and_files;
+    }
+
+    /**
+     * @param ConsoleOutputInterface $output
+     * @param string $current_legacy_path
+     * @return void
+     */
+    protected function updateProjectDirectory(
+        ConsoleOutputInterface $output,
+        string $current_legacy_path
+    ): void {
+        $output->writeln("Updating project :$current_legacy_path");
+        $success = 0;
+        $failed = 0;
+
+        $ar = glob("$current_legacy_path/" . self::$IMG_GLOB, GLOB_BRACE);
+        if ($ar === false) {
+            $output->writeln("Failed to list projects images files for '$current_legacy_path'");
+            return;
+        }
+        foreach ($ar as $filename) {
+            if (str_starts_with($filename, $current_legacy_path . '/' . self::$ORIGINAL_FILE_PREPEND_WITH)) {
+                continue;
+            }
+            $target = str_replace(
+                $current_legacy_path . '/',
+                $current_legacy_path . '/' . self::$ORIGINAL_FILE_PREPEND_WITH,
+                $filename
+            );
+            if (!file_exists($target)) {
+                if (!copy($filename, $target)) {
+                    $output->writeln("Failed to copy '$filename' to '$target'");
+                    $failed++;
+                } else {
+                    $success++;
+                }
+            }
+        }
+
+        $output->writeln("Updated project :$current_legacy_path, $success files duplicated, $failed failed ---> DONE");
+    }
+}