From fe447d3f511ead5ee9938da7d573b09256affaeb Mon Sep 17 00:00:00 2001
From: xgui3783 <xgui3783@gmail.com>
Date: Wed, 1 Aug 2018 21:45:10 +1000
Subject: [PATCH] Pr bugfixes (#80)

* fixes + updates on api

* built in plugin dev

* fixes #77 #79
---
 .../atlasViewer.apiService.service.ts         |  16 +-
 .../atlasViewer.constantService.service.ts    |  11 +-
 .../atlasViewer.dataService.service.ts        |  15 +-
 src/plugin_examples/newWebJugex/app.js        |   2 +
 src/plugin_examples/newWebJugex/app.js.map    |   1 +
 src/plugin_examples/newWebJugex/manifest.js   |   2 +
 .../newWebJugex/manifest.js.map               |   1 +
 src/plugin_examples/newWebJugex/manifest.json |   6 +
 src/plugin_examples/newWebJugex/script.js     | 228 ++++++++++++++++
 src/plugin_examples/newWebJugex/template.html | 248 ++++++++++++++++++
 src/plugin_examples/newWebJugex/vendor.js     |   2 +
 src/plugin_examples/newWebJugex/vendor.js.map |   1 +
 src/plugin_examples/plugin_api.md             |   2 +-
 src/res/css/plugin_styles.css                 |  20 +-
 .../nehubaContainer.component.ts              |  52 ++--
 .../nehubaViewer/nehubaViewer.component.ts    |  25 +-
 16 files changed, 574 insertions(+), 58 deletions(-)
 create mode 100644 src/plugin_examples/newWebJugex/app.js
 create mode 100644 src/plugin_examples/newWebJugex/app.js.map
 create mode 100644 src/plugin_examples/newWebJugex/manifest.js
 create mode 100644 src/plugin_examples/newWebJugex/manifest.js.map
 create mode 100644 src/plugin_examples/newWebJugex/manifest.json
 create mode 100644 src/plugin_examples/newWebJugex/script.js
 create mode 100644 src/plugin_examples/newWebJugex/template.html
 create mode 100644 src/plugin_examples/newWebJugex/vendor.js
 create mode 100644 src/plugin_examples/newWebJugex/vendor.js.map

diff --git a/src/atlasViewer/atlasViewer.apiService.service.ts b/src/atlasViewer/atlasViewer.apiService.service.ts
index efa52221e..cdd6fb3c3 100644
--- a/src/atlasViewer/atlasViewer.apiService.service.ts
+++ b/src/atlasViewer/atlasViewer.apiService.service.ts
@@ -1,8 +1,8 @@
 import { Injectable } from "@angular/core";
 import { Store, select } from "@ngrx/store";
-import { ViewerStateInterface, safeFilter } from "../services/stateStore.service";
+import { ViewerStateInterface, safeFilter, getLabelIndexMap } from "../services/stateStore.service";
 import { Observable } from "rxjs";
-import { map } from "rxjs/operators";
+import { map, distinctUntilChanged } from "rxjs/operators";
 
 declare var window
 
@@ -13,6 +13,7 @@ declare var window
 export class AtlasViewerAPIServices{
 
   private loadedTemplates$ : Observable<any>
+  private selectParcellation$ : Observable<any>
   public interactiveViewer : InteractiveViewerInterface
 
   public loadedLibraries : Map<string,{counter:number,src:HTMLElement|null}> = new Map()
@@ -27,6 +28,12 @@ export class AtlasViewerAPIServices{
       map(state=>state.fetchedTemplates)
     )
 
+    this.selectParcellation$ = this.store.pipe(
+      select('viewerState'),
+      safeFilter('parcellationSelected'),
+      map(state => state.parcellationSelected)
+    )
+
     this.interactiveViewer = {
       metadata : {
         selectedTemplateBSubject : this.store.pipe(
@@ -42,7 +49,9 @@ export class AtlasViewerAPIServices{
         selectedRegionsBSubject : this.store.pipe(
           select('viewerState'),
           safeFilter('regionsSelected'),
-          map(state=>state.regionsSelected)),
+          map(state=>state.regionsSelected),
+          distinctUntilChanged((arr1, arr2) => arr1.length === arr2.length && (arr1 as any[]).every((item, index) => item.name === arr2[index].name))
+        ),
 
         loadedTemplates : [],
 
@@ -69,6 +78,7 @@ export class AtlasViewerAPIServices{
 
   private init(){
     this.loadedTemplates$.subscribe(templates=>this.interactiveViewer.metadata.loadedTemplates = templates)
+    this.selectParcellation$.subscribe(parcellation => this.interactiveViewer.metadata.regionsLabelIndexMap = getLabelIndexMap(parcellation.regions))
   }
 }
 
diff --git a/src/atlasViewer/atlasViewer.constantService.service.ts b/src/atlasViewer/atlasViewer.constantService.service.ts
index 64759d6d9..80e4ca6cb 100644
--- a/src/atlasViewer/atlasViewer.constantService.service.ts
+++ b/src/atlasViewer/atlasViewer.constantService.service.ts
@@ -103,9 +103,10 @@ const parseURLToElement = (url:string):HTMLElement=>{
 }
 
 export const SUPPORT_LIBRARY_MAP : Map<string,HTMLElement> = new Map([
-  ['jquery3',parseURLToElement('http://code.jquery.com/jquery-3.3.1.min.js')],
-  ['jquery2',parseURLToElement('http://code.jquery.com/jquery-2.2.4.min.js')],
-  ['webcomponentsLite',parseURLToElement('https://cdnjs.cloudflare.com/ajax/libs/webcomponentsjs/1.1.0/webcomponents-lite.js')],
-  ['react16',parseURLToElement('https://unpkg.com/react@16/umd/react.development.js')],
-  ['reactdom16',parseURLToElement('https://unpkg.com/react-dom@16/umd/react-dom.development.js')],
+  ['jquery@3',parseURLToElement('http://code.jquery.com/jquery-3.3.1.min.js')],
+  ['jquery@2',parseURLToElement('http://code.jquery.com/jquery-2.2.4.min.js')],
+  ['webcomponentsLite@1.1.0',parseURLToElement('https://cdnjs.cloudflare.com/ajax/libs/webcomponentsjs/1.1.0/webcomponents-lite.js')],
+  ['react@16',parseURLToElement('https://unpkg.com/react@16/umd/react.development.js')],
+  ['reactdom@16',parseURLToElement('https://unpkg.com/react-dom@16/umd/react-dom.development.js')],
+  ['vue@2.5.16',parseURLToElement('https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js')],
 ])
diff --git a/src/atlasViewer/atlasViewer.dataService.service.ts b/src/atlasViewer/atlasViewer.dataService.service.ts
index cd1704da8..97e5ff75b 100644
--- a/src/atlasViewer/atlasViewer.dataService.service.ts
+++ b/src/atlasViewer/atlasViewer.dataService.service.ts
@@ -14,21 +14,14 @@ export class AtlasViewerDataService implements OnDestroy{
   private subscriptions : Subscription[] = []
 
   public promiseFetchedPluginManifests : Promise<PluginManifest[]> = new Promise((resolve,reject)=>{
-    // fetch('http://medpc055.ime.kfa-juelich.de:5080/collectPlugins')
-    //   .then(res=>res.json())
-    //   .then(json=>resolve(json))
-    //   .catch(err=>reject(err))
     if(PLUGINDEV){
-      
+      fetch('http://localhost:10080/allPluginmanifests')
+        .then(res=>res.json())
+        .then(json=>resolve(json))
+        .catch(reject)
     }else{
       resolve([])
     }
-    Promise.all([
-      fetch('http://localhost:10080/jugex/manifest.json').then(res=>res.json()),
-      fetch('http://localhost:10080/testPlugin/manifest.json').then(res=>res.json())
-    ])
-      .then(arr=>resolve(arr))
-      .catch(e=>reject(e))
   })
 
   public promiseFetchedTemplates : Promise<any[]> = Promise.all(this.constantService.templateUrls.map(url=>
diff --git a/src/plugin_examples/newWebJugex/app.js b/src/plugin_examples/newWebJugex/app.js
new file mode 100644
index 000000000..ed622b39c
--- /dev/null
+++ b/src/plugin_examples/newWebJugex/app.js
@@ -0,0 +1,2 @@
+webpackJsonp([0],{AjZS:function(n,e,t){(n.exports=t("FZ+f")(!0)).push([n.i,"\ndiv.v-pill-container[data-v-94d8f66e]\n{\n  display:inline-block;\n  white-space: nowrap;\n  margin:5px;\n  padding:0.2em 0.6em;\n  border-radius: 0.8em;\n}\ndiv.v-pill-container[data-v-94d8f66e]\n{\n  cursor: default;\n  -webkit-transition: all 300ms;\n  transition: all 300ms;\n  background-color:rgba(50,50,50,0.2);\n}\ndiv.v-pill-container[data-v-94d8f66e]:hover\n{\n  background-color:rgba(150,150,150,0.2);\n}\nspan.v-pill-name[data-v-94d8f66e]\n{\n  cursor: default;\n  display:inline-block;\n}\nspan.v-pill-remove[data-v-94d8f66e]\n{\n  cursor: default;\n  display:inline-block;\n}\nspan.v-pill-remove[data-v-94d8f66e]:hover\n{\n  font-weight: 900;\n  color:rgba(200,30,30,1);\n}\n","",{version:3,sources:["/home/xgui3783/dev/projects/vue-components/src/components/src/components/pill.vue"],names:[],mappings:";AAuBA;;EAEA,qBAAA;EACA,oBAAA;EACA,WAAA;EACA,oBAAA;EACA,qBAAA;CACA;AAEA;;EAEA,gBAAA;EACA,8BAAA;EAAA,sBAAA;EACA,oCAAA;CACA;AAEA;;EAEA,uCAAA;CACA;AAEA;;EAEA,gBAAA;EACA,qBAAA;CACA;AACA;;EAEA,gBAAA;EACA,qBAAA;CACA;AAEA;;EAEA,iBAAA;EACA,wBAAA;CACA",file:"pill.vue",sourcesContent:['<template>\n<div @click.stop.prevent = "$emit(\'select-pill\')" class = "v-pill-container">\n  <span class = "v-pill-name">{{ name }}</span>\n  <span v-if = "closable" @click.stop.prevent = "$emit(\'remove-pill\')" class = "v-pill-remove">&times;</span>\n</div>\n</template>\n\n<script>\nmodule.exports = {\n  props: {\n    name: {\n      type: String,\n      default: \'Untitled\'\n    },\n    closable: {\n      type: Boolean,\n      default: true\n    }\n  }\n}\n<\/script>\n\n<style scoped>\ndiv.v-pill-container\n{\n  display:inline-block;\n  white-space: nowrap;\n  margin:5px;\n  padding:0.2em 0.6em;\n  border-radius: 0.8em;\n}\n\ndiv.v-pill-container\n{\n  cursor: default;\n  transition: all 300ms;\n  background-color:rgba(50,50,50,0.2);\n}\n\ndiv.v-pill-container:hover\n{\n  background-color:rgba(150,150,150,0.2);\n}\n\nspan.v-pill-name\n{\n  cursor: default;\n  display:inline-block;\n}\nspan.v-pill-remove\n{\n  cursor: default;\n  display:inline-block;\n}\n\nspan.v-pill-remove:hover\n{\n  font-weight: 900;\n  color:rgba(200,30,30,1);\n}\n</style>\n'],sourceRoot:""}])},B6Kj:function(n,e,t){var o=t("RpWc");"string"==typeof o&&(o=[[n.i,o,""]]),o.locals&&(n.exports=o.locals);t("rjj0")("9aafbbb6",o,!1,{})},CJjv:function(n,e,t){var o=t("n8WV");"string"==typeof o&&(o=[[n.i,o,""]]),o.locals&&(n.exports=o.locals);t("rjj0")("6decef42",o,!1,{})},E8lD:function(n,e,t){var o=t("fKQA");"string"==typeof o&&(o=[[n.i,o,""]]),o.locals&&(n.exports=o.locals);t("rjj0")("041522c3",o,!1,{})},"KU0+":function(n,e,t){var o=t("R6Sg");"string"==typeof o&&(o=[[n.i,o,""]]),o.locals&&(n.exports=o.locals);t("rjj0")("c9be660c",o,!1,{})},NHnr:function(n,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=t("lRwf"),i=t.n(o),r={props:{top:Number,left:Number},data:function(){return{show:{type:Boolean,default:!1}}},computed:{contentContainerLeft:function(){return this.top&&this.left&&this.$refs.content&&this.$refs.screen?Math.min(this.left,this.$refs.screen.clientWidth-this.$refs.content.clientWidth)+"px":"0px"},contentContainerTop:function(){return this.top&&this.left&&this.$refs.content&&this.$refs.screen?Math.min(this.top,this.$refs.screen.clientHeight-this.$refs.content.clientHeight)+"px":"0px"},contentContainerWidth:function(){return this.top&&this.left&&this.$refs.content&&this.$refs.screen?"auto":"100%"},contentContainerHeight:function(){return this.top&&this.left&&this.$refs.content&&this.$refs.screen?"auto":"100%"}}},a=function(){var n=this,e=n.$createElement,t=n._self._c||e;return t("div",[t("div",{staticClass:"v-modal-container"},[t("div",{ref:"screen",staticClass:"v-modal-screen",on:{click:function(e){n.$emit("close-modal")}}}),n._v(" "),t("div",{staticClass:"v-modal-content-container",style:{top:n.contentContainerTop,left:n.contentContainerLeft,width:n.contentContainerWidth,height:n.contentContainerHeight}},[t("div",{ref:"content",staticClass:"v-modal-content"},[t("div",{staticClass:"v-modal-header"},[n._t("v-modal-header")],2),n._v(" "),t("div",{staticClass:"v-modal-body"},[n._t("v-modal-body")],2),n._v(" "),t("div",{staticClass:"v-modal-footer"},[n._t("v-modal-footer")],2)])])])])};a._withStripped=!0;var s={render:a,staticRenderFns:[]},l=s;var A=!1;var c=t("VU/8")(r,l,!1,function(n){A||t("CJjv")},"data-v-0eaeaf66",null);c.options.__file="src/components/modal.vue";var d=c.exports,p=t("u0wG"),u={props:{placeholder:{type:String,default:"Start typing to search ..."},rawarray:{type:Array,default:function(){return[]}},rendermax:{type:Number,default:25}},data:function(){return{showSuggestions:!1,typedText:"",highlightIndex:0}},methods:{selectSlice:function(n){this.$emit("selectslice",n)},hitEnter:function(){switch(event.key){case"ArrowDown":this.highlightIndex+=1;break;case"Escape":this.$refs.input.blur();break;case"ArrowUp":this.highlightIndex-=1,this.highlightIndex<=0&&(this.highlightIndex+=this.filteredArray.length);break;case"Enter":var n=this.filteredArray.slice();if(n.length>0){this.typedText="";var e=document.querySelector(":focus");e&&e.blur(),this.selectSlice(n[0])}break;default:this.highlightIndex=0}}},computed:{rawArrayLowerCase:function(){return this.rawarray.map(function(n){return n.toLowerCase()})},typedTextLowerCase:function(){return this.typedText.toLowerCase()},filteredArray:function(){var n=this,e=new RegExp(this.typedText,"i"),t=this.rawarray.find(function(e){return e.toLowerCase()===n.typedTextLowerCase}),o=this.rawarray.filter(function(n){return e.test(n)}).filter(function(e){return e.toLowerCase()!==n.typedTextLowerCase}).filter(function(e,t){return t<=n.rendermax});return t?[t].concat(o.slice(0,o.length>=this.rendermax?o.length-1:o.length)):o}}},h=function(){var n=this,e=n.$createElement,t=n._self._c||e;return t("div",{staticClass:"autocomplete-container"},[t("input",{directives:[{name:"model",rawName:"v-model",value:n.typedText,expression:"typedText"}],ref:"input",attrs:{type:"text",placeholder:n.placeholder},domProps:{value:n.typedText},on:{keydown:function(e){return e.stopPropagation(),n.hitEnter(e)},focus:function(e){n.showSuggestions=!0},blur:function(e){n.showSuggestions=!1},input:function(e){e.target.composing||(n.typedText=e.target.value)}}}),n._v(" "),t("transition",{attrs:{name:"fade"}},[n.showSuggestions?t("div",{staticClass:"autocomplete-suggestion-container"},n._l(n.filteredArray,function(e,o){return t("div",{key:o,staticClass:"autocomplete-suggestions",class:{active:n.highlightIndex%n.filteredArray.length===o},on:{mousedown:function(t){n.selectSlice(e)}}},[n._v("\n        "+n._s(e)+"\n      ")])})):n._e()])],1)};h._withStripped=!0;var f={render:h,staticRenderFns:[]},m=f;var v=!1;var g=t("VU/8")(u,m,!1,function(n){v||t("B6Kj")},"data-v-8351e810",null);g.options.__file="src/components/autocomplete.vue";var C=g.exports,y={props:{value:{type:String,default:"default value"},copyable:{type:Boolean,default:!0}},data:function(){return{copiedFlag:!1,timeoutRef:0,copyBtnShown:!1}},methods:{copyToClipBoard:function(){var n=this;this.copiedFlag=!0,this.timeoutRef&&clearTimeout(this.timeoutRef),setTimeout(function(){n.copiedFlag=!1,n.timeoutRef=0},2e3),this.$refs.inputEl.focus(),this.$refs.inputEl.select(),document.execCommand("copy",!1)},methodGetCopyText:function(){return this.copiedFlag?"Copied!":"Copy"}}},E=function(){var n=this,e=n.$createElement,t=n._self._c||e;return t("div",{staticClass:"copy-field-root"},[t("input",{ref:"inputEl",attrs:{readonly:"",type:"text"},domProps:{value:n.value}}),n._v(" "),t("div",{attrs:{hidden:!n.copyable},on:{click:function(e){return e.stopPropagation(),n.copyToClipBoard(e)}}},[n._v(n._s(n.methodGetCopyText())+"\n  ")])])};E._withStripped=!0;var b={render:E,staticRenderFns:[]},x=b;var w=!1;var k=t("VU/8")(y,x,!1,function(n){w||t("E8lD")},null,null);k.options.__file="src/components/copyfield.vue";var B=k.exports,_={props:{collapsedHeight:{type:Number,default:25}},data:function(){return{collapsed:{type:Boolean,default:!0},actualHeight:{type:Number,default:25}}},mounted:function(){this.actualHeight=this.$refs.readmoreContentContainer.clientHeight},methods:{toggle:function(){this.collapsed=!this.collapsed}},computed:{computedHeight:function(){return(this.collapsed?this.collapsedHeight:this.actualHeight)+"px"}}},$=function(){var n=this,e=n.$createElement,t=n._self._c||e;return t("div",{staticClass:"readmore-container"},[t("div",{staticClass:"readmore-content",style:{height:n.computedHeight}},[t("div",{ref:"readmoreContentContainer"},[n._t("readmoreContent")],2)]),n._v(" "),t("div",{staticClass:"readmore-sliver",on:{click:n.toggle}},[n.collapsed?n._t("resizeSliverContentCollapsed"):n._e(),n._v(" "),n.collapsed?n._e():n._t("resizeSliverContentShown")],2)])};$._withStripped=!0;var S={render:$,staticRenderFns:[]},T=S;var R=!1;var H=t("VU/8")(_,T,!1,function(n){R||t("KU0+")},"data-v-92448f0a",null);H.options.__file="src/components/readmore.vue";var j=H.exports;i.a.config.productionTip=!1,i.a.component("vue-modal",d),i.a.component("vue-pill",p.default),i.a.component("vue-autocomplete",C),i.a.component("vue-copyfield",B),i.a.component("vue-readmore",j)},R6Sg:function(n,e,t){(n.exports=t("FZ+f")(!0)).push([n.i,"\n.readmore-content[data-v-92448f0a]\n{\n  -webkit-transition: all 0.3s;\n  transition: all 0.3s;\n  overflow-y : hidden;\n}\n.readmore-sliver[data-v-92448f0a]\n{\n  min-height: 0.5em;\n  -webkit-transition: all 0.3s;\n  transition: all 0.3s;\n  background-color: rgba(128,128,128,0.2);\n}\n.readmore-sliver[data-v-92448f0a]:hover\n{\n  -webkit-transform: translateY(-2px);\n          transform: translateY(-2px);\n  background-color: rgba(128,128,128,0.4);\n}\n","",{version:3,sources:["/home/xgui3783/dev/projects/vue-components/src/components/src/components/readmore.vue"],names:[],mappings:";AAiDA;;EAEA,6BAAA;EAAA,qBAAA;EACA,oBAAA;CACA;AACA;;EAEA,kBAAA;EACA,6BAAA;EAAA,qBAAA;EACA,wCAAA;CACA;AACA;;EAEA,oCAAA;UAAA,4BAAA;EACA,wCAAA;CACA",file:"readmore.vue",sourcesContent:['<template>\n<div class = "readmore-container">\n  <div :style = "{ height : computedHeight }" class = "readmore-content">\n    <div ref = "readmoreContentContainer">\n      <slot name = "readmoreContent"></slot>\n    </div>\n  </div>\n  <div @click = "toggle" class = "readmore-sliver">\n    <slot v-if = "collapsed" name = "resizeSliverContentCollapsed">\n    </slot>\n    <slot v-if = "!collapsed" name = "resizeSliverContentShown">\n    </slot>\n  </div>\n</div>\n</template>\n<script>\nexport default {\n  props: {\n    collapsedHeight: {\n      type: Number,\n      default: 25\n    }\n  },\n  data: () => ({\n    collapsed: {\n      type: Boolean,\n      default: true\n    },\n    actualHeight: {\n      type: Number,\n      default: 25\n    }\n  }),\n  mounted: function () {\n    this.actualHeight = this.$refs.readmoreContentContainer.clientHeight\n  },\n  methods: {\n    toggle: function () {\n      this.collapsed = !this.collapsed\n    }\n  },\n  computed: {\n    computedHeight: function () {\n      return `${this.collapsed ? this.collapsedHeight : this.actualHeight}px`\n    }\n  }\n}\n<\/script>\n<style scoped>\n.readmore-content\n{\n  transition: all 0.3s;\n  overflow-y : hidden;\n}\n.readmore-sliver\n{\n  min-height: 0.5em;\n  transition: all 0.3s;\n  background-color: rgba(128,128,128,0.2);\n}\n.readmore-sliver:hover\n{\n  transform: translateY(-2px);\n  background-color: rgba(128,128,128,0.4);\n}\n</style>\n'],sourceRoot:""}])},RQup:function(n,e){n.exports={props:{name:{type:String,default:"Untitled"},closable:{type:Boolean,default:!0}}}},RpWc:function(n,e,t){(n.exports=t("FZ+f")(!0)).push([n.i,'\ndiv.autocomplete-container[data-v-8351e810]\n{\n  cursor:default;\n}\n.autocomplete-suggestions[data-v-8351e810]\n{\n  width:100%;\n  display:block;\n  padding:0.1em 0.3em;\n  -webkit-transition: all 200ms;\n  transition: all 200ms;\n  background-color:rgba(230,230,230,0.5);\n}\n.autocomplete-suggestions.active[data-v-8351e810]\n{\n  background-color:rgba(230,230,230,0.95);\n}\n.autocomplete-suggestions[data-v-8351e810]:hover\n{\n  background-color:rgba(230,230,230,0.95);\n}\ndiv.autocomplete-container:focus-within .autocomplete-suggestions[data-v-8351e810]\n{\n  display: block;\n}\ndiv.autocomplete-suggestion-container[data-v-8351e810]\n{\n  width: 100%;\n  max-height:10em;\n  overflow-y:auto;\n  overflow-x:hidden;\n  z-index:2;\n}\ninput[type="text"][data-v-8351e810]\n{\n  width:100%;\n  height:100%;\n  z-index:1;\n}\n',"",{version:3,sources:["/home/xgui3783/dev/projects/vue-components/src/components/src/components/autocomplete.vue"],names:[],mappings:";AAoGA;;EAEA,eAAA;CACA;AAEA;;EAEA,WAAA;EACA,cAAA;EACA,oBAAA;EACA,8BAAA;EAAA,sBAAA;EACA,uCAAA;CACA;AAEA;;EAEA,wCAAA;CACA;AAEA;;EAEA,wCAAA;CACA;AAEA;;EAEA,eAAA;CACA;AAEA;;EAEA,YAAA;EACA,gBAAA;EACA,gBAAA;EACA,kBAAA;EACA,UAAA;CACA;AACA;;EAEA,WAAA;EACA,YAAA;EACA,UAAA;CACA",file:"autocomplete.vue",sourcesContent:['<template>\n<div class = "autocomplete-container">\n  <input\n    ref = "input"\n    @keydown.stop = "hitEnter"\n    type = "text"\n    @focus = "showSuggestions = true"\n    @blur = "showSuggestions = false"\n    v-model = "typedText"\n    :placeholder = "placeholder"/>\n  <transition name = "fade">\n    <div v-if = "showSuggestions" class = "autocomplete-suggestion-container">\n      <div\n        @mousedown="selectSlice(item)"\n        class = "autocomplete-suggestions"\n        :class = "{active : ((highlightIndex % filteredArray.length) === index)}"\n        v-bind:key = "index"\n        v-for = "(item,index) in filteredArray">\n        {{ item }}\n      </div>\n    </div>\n  </transition>\n</div>\n</template>\n\n<script>\nexport default {\n  props: {\n    placeholder: {\n      type: String,\n      default: \'Start typing to search ...\'\n    },\n    rawarray: {\n      type: Array,\n      default: () => ([])\n    },\n    rendermax: {\n      type: Number,\n      default: 25\n    }\n  },\n  data: () => ({\n    showSuggestions: false,\n    typedText: \'\',\n    highlightIndex: 0\n  }),\n  methods: {\n    selectSlice: function (item) {\n      this.$emit(\'selectslice\', item)\n    },\n    hitEnter: function () {\n      switch (event.key) {\n        case \'ArrowDown\':\n          this.highlightIndex += 1\n          break\n        case \'Escape\':\n          this.$refs.input.blur()\n          break\n        case \'ArrowUp\':\n          this.highlightIndex -= 1\n          if (this.highlightIndex <= 0) this.highlightIndex += this.filteredArray.length\n          break\n        case \'Enter\':\n          const array = this.filteredArray.slice()\n          if (array.length > 0) {\n            this.typedText = \'\'\n            const el = document.querySelector(\':focus\')\n            if (el) el.blur()\n            this.selectSlice(array[0])\n          }\n          break\n        default:\n          this.highlightIndex = 0\n          break\n      }\n    }\n  },\n  computed: {\n    rawArrayLowerCase: function () {\n      return this.rawarray.map(item => item.toLowerCase())\n    },\n    typedTextLowerCase: function () {\n      return this.typedText.toLowerCase()\n    },\n    filteredArray: function () {\n      const regex = new RegExp(this.typedText, \'i\')\n      const completeMatch = this.rawarray.find(item => item.toLowerCase() === this.typedTextLowerCase)\n      const othermatches = this.rawarray\n        .filter(item => regex.test(item))\n        .filter(item => item.toLowerCase() !== this.typedTextLowerCase)\n        .filter((_, idx) => idx <= this.rendermax)\n      return completeMatch\n        ? [completeMatch].concat(othermatches.slice(0, othermatches.length >= this.rendermax ? othermatches.length - 1 : othermatches.length))\n        : othermatches\n    }\n  }\n}\n<\/script>\n\n<style scoped>\ndiv.autocomplete-container\n{\n  cursor:default;\n}\n\n.autocomplete-suggestions\n{\n  width:100%;\n  display:block;\n  padding:0.1em 0.3em;\n  transition: all 200ms;\n  background-color:rgba(230,230,230,0.5);\n}\n\n.autocomplete-suggestions.active\n{\n  background-color:rgba(230,230,230,0.95);\n}\n\n.autocomplete-suggestions:hover\n{\n  background-color:rgba(230,230,230,0.95);\n}\n\ndiv.autocomplete-container:focus-within .autocomplete-suggestions\n{\n  display: block;\n}\n\ndiv.autocomplete-suggestion-container\n{\n  width: 100%;\n  max-height:10em;\n  overflow-y:auto;\n  overflow-x:hidden;\n  z-index:2;\n}\ninput[type="text"]\n{\n  width:100%;\n  height:100%;\n  z-index:1;\n}\n</style>\n'],sourceRoot:""}])},ck25:function(n,e,t){"use strict";var o=function(){var n=this,e=n.$createElement,t=n._self._c||e;return t("div",{staticClass:"v-pill-container",on:{click:function(e){e.stopPropagation(),e.preventDefault(),n.$emit("select-pill")}}},[t("span",{staticClass:"v-pill-name"},[n._v(n._s(n.name))]),n._v(" "),n.closable?t("span",{staticClass:"v-pill-remove",on:{click:function(e){e.stopPropagation(),e.preventDefault(),n.$emit("remove-pill")}}},[n._v("×")]):n._e()])};o._withStripped=!0;var i={render:o,staticRenderFns:[]};e.a=i},fKQA:function(n,e,t){(n.exports=t("FZ+f")(!0)).push([n.i,"\n.copy-field-root\n{\n  width: 100%;\n  white-space: nowrap;\n}\n.copy-field-root *\n{\n  color:black\n}\n.copy-field-root > input\n{\n  width : 100%;\n  height:2.0em;\n  display: inline-block;\n  vertical-align : middle;\n  -webkit-box-sizing: border-box;\n          box-sizing: border-box;\n  position : relative;\n\n  border : solid 1px rgba(128,128,128,0.6);\n  z-index: 8;\n}\n.copy-field-root > div:not([hidden])\n{\n  position : relative;\n  z-index: 9;\n  cursor:default;\n  display: inline-block;\n  -webkit-box-sizing:border-box;\n          box-sizing:border-box;\n  margin : 0.2em;\n  height : 1.6em;\n  margin-left:-4em;\n  font-size:100%;\n  vertical-align : middle;\n  text-align: center;\n  font-size:0.9em;\n  padding : 0.2em;\n\n  color:rgba(0,0,0,0.8);\n  border : solid 1px rgba(0,0,0,0.5);\n\n  background-color:rgba(230,230,230,0.9);\n}\n.copy-field-root > div:hover\n{\n  background-color:rgba(240,240,240,1.0);\n}\n","",{version:3,sources:["/home/xgui3783/dev/projects/vue-components/src/components/src/components/copyfield.vue"],names:[],mappings:";AAiDA;;EAEA,YAAA;EACA,oBAAA;CACA;AAEA;;EAEA,WAAA;CACA;AAEA;;EAEA,aAAA;EACA,aAAA;EACA,sBAAA;EACA,wBAAA;EACA,+BAAA;UAAA,uBAAA;EACA,oBAAA;;EAEA,yCAAA;EACA,WAAA;CACA;AAEA;;EAEA,oBAAA;EACA,WAAA;EACA,eAAA;EACA,sBAAA;EACA,8BAAA;UAAA,sBAAA;EACA,eAAA;EACA,eAAA;EACA,iBAAA;EACA,eAAA;EACA,wBAAA;EACA,mBAAA;EACA,gBAAA;EACA,gBAAA;;EAEA,sBAAA;EACA,mCAAA;;EAEA,uCAAA;CACA;AAEA;;EAEA,uCAAA;CACA",file:"copyfield.vue",sourcesContent:['<template>\n<div class = "copy-field-root">\n  <input ref = "inputEl" readonly v-bind:value = "value" type = "text" />\n  <div\n    v-bind:hidden = "!copyable"\n    @click.stop = "copyToClipBoard">{{ methodGetCopyText() }}\n  </div>\n</div>\n</template>\n\n<script>\nexport default {\n  props: {\n    value: {\n      type: String,\n      default: \'default value\'\n    },\n    copyable: {\n      type: Boolean,\n      default: true\n    }\n  },\n  data: () => ({\n    copiedFlag: false,\n    timeoutRef: 0,\n    copyBtnShown: false\n  }),\n  methods: {\n    copyToClipBoard: function () {\n      this.copiedFlag = true\n      if (this.timeoutRef) {\n        clearTimeout(this.timeoutRef)\n      }\n      setTimeout(() => {\n        this.copiedFlag = false\n        this.timeoutRef = 0\n      }, 2000)\n\n      this.$refs.inputEl.focus()\n      this.$refs.inputEl.select()\n      document.execCommand(\'copy\', false)\n    },\n    methodGetCopyText: function () {\n      return this.copiedFlag ? \'Copied!\' : \'Copy\'\n    }\n  }\n}\n<\/script>\n<style>\n.copy-field-root\n{\n  width: 100%;\n  white-space: nowrap;\n}\n\n.copy-field-root *\n{\n  color:black\n}\n\n.copy-field-root > input\n{\n  width : 100%;\n  height:2.0em;\n  display: inline-block;\n  vertical-align : middle;\n  box-sizing: border-box;\n  position : relative;\n\n  border : solid 1px rgba(128,128,128,0.6);\n  z-index: 8;\n}\n\n.copy-field-root > div:not([hidden])\n{\n  position : relative;\n  z-index: 9;\n  cursor:default;\n  display: inline-block;\n  box-sizing:border-box;\n  margin : 0.2em;\n  height : 1.6em;\n  margin-left:-4em;\n  font-size:100%;\n  vertical-align : middle;\n  text-align: center;\n  font-size:0.9em;\n  padding : 0.2em;\n\n  color:rgba(0,0,0,0.8);\n  border : solid 1px rgba(0,0,0,0.5);\n\n  background-color:rgba(230,230,230,0.9);\n}\n\n.copy-field-root > div:hover\n{\n  background-color:rgba(240,240,240,1.0);\n}\n</style>\n'],sourceRoot:""}])},lRwf:function(n,e){n.exports=Vue},n8WV:function(n,e,t){(n.exports=t("FZ+f")(!0)).push([n.i,"\n.v-modal-container[data-v-0eaeaf66]\n{\n  top: 0;\n  width:100%;\n  height:100%;\n  position : absolute;\n  z-index:999;\n}\n.v-modal-screen[data-v-0eaeaf66]\n{\n  top : 0;\n  position : absolute;\n  width:100%;\n  height:100%;\n  background-color:rgba(30,30,30,0.2);\n}\n.v-modal-content-container[data-v-0eaeaf66]\n{\n  top : 0;\n  position : absolute;\n  display : -webkit-box;\n  display : -ms-flexbox;\n  display : flex;\n  -webkit-box-align: center;\n      -ms-flex-align: center;\n          align-items: center;\n  -ms-flex-line-pack: center;\n      align-content: center;\n  -webkit-box-pack: center;\n      -ms-flex-pack: center;\n          justify-content: center;\n\n  pointer-events: none;\n}\n.v-modal-content[data-v-0eaeaf66]\n{\n  -webkit-box-flex : 0;\n      -ms-flex : 0 0 auto;\n          flex : 0 0 auto;\n  pointer-events: all;\n}\n\n","",{version:3,sources:["/home/xgui3783/dev/projects/vue-components/src/components/src/components/modal.vue"],names:[],mappings:";AA4DA;;EAEA,OAAA;EACA,WAAA;EACA,YAAA;EACA,oBAAA;EACA,YAAA;CACA;AACA;;EAEA,QAAA;EACA,oBAAA;EACA,WAAA;EACA,YAAA;EACA,oCAAA;CACA;AAEA;;EAEA,QAAA;EACA,oBAAA;EACA,sBAAA;EAAA,sBAAA;EAAA,eAAA;EACA,0BAAA;MAAA,uBAAA;UAAA,oBAAA;EACA,2BAAA;MAAA,sBAAA;EACA,yBAAA;MAAA,sBAAA;UAAA,wBAAA;;EAEA,qBAAA;CACA;AACA;;EAEA,qBAAA;MAAA,oBAAA;UAAA,gBAAA;EACA,oBAAA;CACA",file:"modal.vue",sourcesContent:['<template>\n<div>\n  <div class = "v-modal-container">\n    <div\n      ref = "screen"\n      v-on:click = "$emit(\'close-modal\')"\n      class = "v-modal-screen">\n    </div>\n    <div\n      v-bind:style = "{top:contentContainerTop,left:contentContainerLeft,width:contentContainerWidth,height:contentContainerHeight,}"\n      class = "v-modal-content-container">\n      <div\n        ref = "content"\n        class = "v-modal-content">\n        <div class = "v-modal-header">\n          <slot name = "v-modal-header">\n          </slot>\n        </div>\n        <div class = "v-modal-body">\n          <slot name = "v-modal-body">\n          </slot>\n        </div>\n        <div class = "v-modal-footer">\n          <slot name = "v-modal-footer">\n          </slot>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n</template>\n<script>\nexport default {\n  props: {\n    top: Number,\n    left: Number\n  },\n  data: () => ({\n    show: {\n      type: Boolean,\n      default: false\n    }\n  }),\n  computed: {\n    contentContainerLeft: function () {\n      return this.top && this.left && this.$refs.content && this.$refs.screen ? Math.min(this.left, this.$refs.screen.clientWidth - this.$refs.content.clientWidth) + \'px\' : `0px`\n    },\n    contentContainerTop: function () {\n      return this.top && this.left && this.$refs.content && this.$refs.screen ? Math.min(this.top, this.$refs.screen.clientHeight - this.$refs.content.clientHeight) + \'px\' : `0px`\n    },\n    contentContainerWidth: function () {\n      return this.top && this.left && this.$refs.content && this.$refs.screen ? \'auto\' : `100%`\n    },\n    contentContainerHeight: function () {\n      return this.top && this.left && this.$refs.content && this.$refs.screen ? \'auto\' : `100%`\n    }\n  }\n}\n<\/script>\n<style scoped>\n.v-modal-container\n{\n  top: 0;\n  width:100%;\n  height:100%;\n  position : absolute;\n  z-index:999;\n}\n.v-modal-screen\n{\n  top : 0;\n  position : absolute;\n  width:100%;\n  height:100%;\n  background-color:rgba(30,30,30,0.2);\n}\n\n.v-modal-content-container\n{\n  top : 0;\n  position : absolute;\n  display : flex;\n  align-items: center;\n  align-content: center;\n  justify-content: center;\n\n  pointer-events: none;\n}\n.v-modal-content\n{\n  flex : 0 0 auto;\n  pointer-events: all;\n}\n\n</style>\n'],sourceRoot:""}])},"nFT+":function(n,e,t){var o=t("AjZS");"string"==typeof o&&(o=[[n.i,o,""]]),o.locals&&(n.exports=o.locals);t("rjj0")("12958e8c",o,!1,{})},u0wG:function(n,e,t){"use strict";var o=t("RQup"),i=t.n(o),r=t("ck25"),a=!1;var s=function(n){a||t("nFT+")},l=t("VU/8")(i.a,r.a,!1,s,"data-v-94d8f66e",null);l.options.__file="src/components/pill.vue",e.default=l.exports}},["NHnr"]);
+//# sourceMappingURL=app.js.map
\ No newline at end of file
diff --git a/src/plugin_examples/newWebJugex/app.js.map b/src/plugin_examples/newWebJugex/app.js.map
new file mode 100644
index 000000000..b676d7239
--- /dev/null
+++ b/src/plugin_examples/newWebJugex/app.js.map
@@ -0,0 +1 @@
+{"version":3,"sources":["webpack:///./src/components/pill.vue?058a","webpack:///./src/components/autocomplete.vue?d5dc","webpack:///./src/components/modal.vue?b3b0","webpack:///./src/components/copyfield.vue?5b43","webpack:///./src/components/readmore.vue?f84b","webpack:///src/components/modal.vue","webpack:///./src/components/modal.vue?3efc","webpack:///./src/components/modal.vue","webpack:///src/components/autocomplete.vue","webpack:///./src/components/autocomplete.vue?220c","webpack:///./src/components/autocomplete.vue","webpack:///src/components/copyfield.vue","webpack:///./src/components/copyfield.vue?d3b4","webpack:///./src/components/copyfield.vue","webpack:///src/components/readmore.vue","webpack:///./src/components/readmore.vue?fad6","webpack:///./src/components/readmore.vue","webpack:///./src/main.js","webpack:///./src/components/readmore.vue?2a65","webpack:///src/components/pill.vue","webpack:///./src/components/autocomplete.vue?905f","webpack:///./src/components/pill.vue?c6c2","webpack:///./src/components/copyfield.vue?23c7","webpack:///external \"Vue\"","webpack:///./src/components/modal.vue?2409","webpack:///./src/components/pill.vue?5a83","webpack:///./src/components/pill.vue"],"names":["module","exports","__webpack_require__","push","i","version","sources","names","mappings","file","sourcesContent","sourceRoot","content","locals","modal","props","top","Number","left","data","show","type","Boolean","default","computed","contentContainerLeft","this","$refs","screen","Math","min","clientWidth","contentContainerTop","clientHeight","contentContainerWidth","contentContainerHeight","render","_vm","_h","$createElement","_c","_self","staticClass","ref","on","click","$event","$emit","_v","style","width","height","_t","_withStripped","esExports","staticRenderFns","components_modal","disposed","Component","normalizeComponent","ssrContext","options","__file","src_components_modal","autocomplete","placeholder","String","rawarray","Array","rendermax","showSuggestions","typedText","highlightIndex","methods","selectSlice","item","hitEnter","event","key","input","blur","filteredArray","length","array","slice","el","document","querySelector","rawArrayLowerCase","map","toLowerCase","typedTextLowerCase","_this","regex","RegExp","completeMatch","find","othermatches","filter","test","_","idx","concat","autocomplete_render","directives","name","rawName","value","expression","attrs","domProps","keydown","stopPropagation","focus","target","composing","_l","index","class","active","mousedown","_s","_e","autocomplete_esExports","components_autocomplete","autocomplete_disposed","autocomplete_Component","autocomplete_normalizeComponent","src_components_autocomplete","copyfield","copyable","copiedFlag","timeoutRef","copyBtnShown","copyToClipBoard","clearTimeout","setTimeout","inputEl","select","execCommand","methodGetCopyText","copyfield_render","readonly","hidden","copyfield_esExports","components_copyfield","copyfield_disposed","copyfield_Component","copyfield_normalizeComponent","src_components_copyfield","readmore","collapsedHeight","collapsed","actualHeight","mounted","readmoreContentContainer","toggle","computedHeight","readmore_render","readmore_esExports","components_readmore","readmore_disposed","readmore_Component","readmore_normalizeComponent","src_components_readmore","external__Vue__default","a","config","productionTip","component","pill","closable","preventDefault","__webpack_exports__","Vue","__WEBPACK_IMPORTED_MODULE_1__node_modules_vue_loader_lib_template_compiler_index_id_data_v_94d8f66e_hasScoped_true_transformToRequire_video_src_poster_source_src_img_src_image_xlink_href_buble_transforms_node_modules_vue_loader_lib_selector_type_template_index_0_pill_vue__","__vue_styles__","__WEBPACK_IMPORTED_MODULE_0__babel_loader_node_modules_vue_loader_lib_selector_type_script_index_0_pill_vue___default"],"mappings":"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","file":"static/js/app.js","sourcesContent":["exports = module.exports = require(\"../../node_modules/css-loader/lib/css-base.js\")(true);\n// imports\n\n\n// module\nexports.push([module.id, \"\\ndiv.v-pill-container[data-v-94d8f66e]\\n{\\n  display:inline-block;\\n  white-space: nowrap;\\n  margin:5px;\\n  padding:0.2em 0.6em;\\n  border-radius: 0.8em;\\n}\\ndiv.v-pill-container[data-v-94d8f66e]\\n{\\n  cursor: default;\\n  -webkit-transition: all 300ms;\\n  transition: all 300ms;\\n  background-color:rgba(50,50,50,0.2);\\n}\\ndiv.v-pill-container[data-v-94d8f66e]:hover\\n{\\n  background-color:rgba(150,150,150,0.2);\\n}\\nspan.v-pill-name[data-v-94d8f66e]\\n{\\n  cursor: default;\\n  display:inline-block;\\n}\\nspan.v-pill-remove[data-v-94d8f66e]\\n{\\n  cursor: default;\\n  display:inline-block;\\n}\\nspan.v-pill-remove[data-v-94d8f66e]:hover\\n{\\n  font-weight: 900;\\n  color:rgba(200,30,30,1);\\n}\\n\", \"\", {\"version\":3,\"sources\":[\"/home/xgui3783/dev/projects/vue-components/src/components/src/components/pill.vue\"],\"names\":[],\"mappings\":\";AAuBA;;EAEA,qBAAA;EACA,oBAAA;EACA,WAAA;EACA,oBAAA;EACA,qBAAA;CACA;AAEA;;EAEA,gBAAA;EACA,8BAAA;EAAA,sBAAA;EACA,oCAAA;CACA;AAEA;;EAEA,uCAAA;CACA;AAEA;;EAEA,gBAAA;EACA,qBAAA;CACA;AACA;;EAEA,gBAAA;EACA,qBAAA;CACA;AAEA;;EAEA,iBAAA;EACA,wBAAA;CACA\",\"file\":\"pill.vue\",\"sourcesContent\":[\"<template>\\n<div @click.stop.prevent = \\\"$emit('select-pill')\\\" class = \\\"v-pill-container\\\">\\n  <span class = \\\"v-pill-name\\\">{{ name }}</span>\\n  <span v-if = \\\"closable\\\" @click.stop.prevent = \\\"$emit('remove-pill')\\\" class = \\\"v-pill-remove\\\">&times;</span>\\n</div>\\n</template>\\n\\n<script>\\nmodule.exports = {\\n  props: {\\n    name: {\\n      type: String,\\n      default: 'Untitled'\\n    },\\n    closable: {\\n      type: Boolean,\\n      default: true\\n    }\\n  }\\n}\\n</script>\\n\\n<style scoped>\\ndiv.v-pill-container\\n{\\n  display:inline-block;\\n  white-space: nowrap;\\n  margin:5px;\\n  padding:0.2em 0.6em;\\n  border-radius: 0.8em;\\n}\\n\\ndiv.v-pill-container\\n{\\n  cursor: default;\\n  transition: all 300ms;\\n  background-color:rgba(50,50,50,0.2);\\n}\\n\\ndiv.v-pill-container:hover\\n{\\n  background-color:rgba(150,150,150,0.2);\\n}\\n\\nspan.v-pill-name\\n{\\n  cursor: default;\\n  display:inline-block;\\n}\\nspan.v-pill-remove\\n{\\n  cursor: default;\\n  display:inline-block;\\n}\\n\\nspan.v-pill-remove:hover\\n{\\n  font-weight: 900;\\n  color:rgba(200,30,30,1);\\n}\\n</style>\\n\"],\"sourceRoot\":\"\"}]);\n\n// exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/css-loader?{\"sourceMap\":true}!./node_modules/vue-loader/lib/style-compiler?{\"vue\":true,\"id\":\"data-v-94d8f66e\",\"scoped\":true,\"hasInlineConfig\":false}!./node_modules/vue-loader/lib/selector.js?type=styles&index=0!./src/components/pill.vue\n// module id = AjZS\n// module chunks = 0","// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = require(\"!!../../node_modules/css-loader/index.js?{\\\"sourceMap\\\":true}!../../node_modules/vue-loader/lib/style-compiler/index.js?{\\\"vue\\\":true,\\\"id\\\":\\\"data-v-8351e810\\\",\\\"scoped\\\":true,\\\"hasInlineConfig\\\":false}!../../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./autocomplete.vue\");\nif(typeof content === 'string') content = [[module.id, content, '']];\nif(content.locals) module.exports = content.locals;\n// add the styles to the DOM\nvar update = require(\"!../../node_modules/vue-style-loader/lib/addStylesClient.js\")(\"9aafbbb6\", content, false, {});\n// Hot Module Replacement\nif(module.hot) {\n // When the styles change, update the <style> tags\n if(!content.locals) {\n   module.hot.accept(\"!!../../node_modules/css-loader/index.js?{\\\"sourceMap\\\":true}!../../node_modules/vue-loader/lib/style-compiler/index.js?{\\\"vue\\\":true,\\\"id\\\":\\\"data-v-8351e810\\\",\\\"scoped\\\":true,\\\"hasInlineConfig\\\":false}!../../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./autocomplete.vue\", function() {\n     var newContent = require(\"!!../../node_modules/css-loader/index.js?{\\\"sourceMap\\\":true}!../../node_modules/vue-loader/lib/style-compiler/index.js?{\\\"vue\\\":true,\\\"id\\\":\\\"data-v-8351e810\\\",\\\"scoped\\\":true,\\\"hasInlineConfig\\\":false}!../../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./autocomplete.vue\");\n     if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n     update(newContent);\n   });\n }\n // When the module is disposed, remove the <style> tags\n module.hot.dispose(function() { update(); });\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/vue-style-loader!./node_modules/css-loader?{\"sourceMap\":true}!./node_modules/vue-loader/lib/style-compiler?{\"vue\":true,\"id\":\"data-v-8351e810\",\"scoped\":true,\"hasInlineConfig\":false}!./node_modules/vue-loader/lib/selector.js?type=styles&index=0!./src/components/autocomplete.vue\n// module id = B6Kj\n// module chunks = 0","// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = require(\"!!../../node_modules/css-loader/index.js?{\\\"sourceMap\\\":true}!../../node_modules/vue-loader/lib/style-compiler/index.js?{\\\"vue\\\":true,\\\"id\\\":\\\"data-v-0eaeaf66\\\",\\\"scoped\\\":true,\\\"hasInlineConfig\\\":false}!../../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./modal.vue\");\nif(typeof content === 'string') content = [[module.id, content, '']];\nif(content.locals) module.exports = content.locals;\n// add the styles to the DOM\nvar update = require(\"!../../node_modules/vue-style-loader/lib/addStylesClient.js\")(\"6decef42\", content, false, {});\n// Hot Module Replacement\nif(module.hot) {\n // When the styles change, update the <style> tags\n if(!content.locals) {\n   module.hot.accept(\"!!../../node_modules/css-loader/index.js?{\\\"sourceMap\\\":true}!../../node_modules/vue-loader/lib/style-compiler/index.js?{\\\"vue\\\":true,\\\"id\\\":\\\"data-v-0eaeaf66\\\",\\\"scoped\\\":true,\\\"hasInlineConfig\\\":false}!../../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./modal.vue\", function() {\n     var newContent = require(\"!!../../node_modules/css-loader/index.js?{\\\"sourceMap\\\":true}!../../node_modules/vue-loader/lib/style-compiler/index.js?{\\\"vue\\\":true,\\\"id\\\":\\\"data-v-0eaeaf66\\\",\\\"scoped\\\":true,\\\"hasInlineConfig\\\":false}!../../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./modal.vue\");\n     if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n     update(newContent);\n   });\n }\n // When the module is disposed, remove the <style> tags\n module.hot.dispose(function() { update(); });\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/vue-style-loader!./node_modules/css-loader?{\"sourceMap\":true}!./node_modules/vue-loader/lib/style-compiler?{\"vue\":true,\"id\":\"data-v-0eaeaf66\",\"scoped\":true,\"hasInlineConfig\":false}!./node_modules/vue-loader/lib/selector.js?type=styles&index=0!./src/components/modal.vue\n// module id = CJjv\n// module chunks = 0","// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = require(\"!!../../node_modules/css-loader/index.js?{\\\"sourceMap\\\":true}!../../node_modules/vue-loader/lib/style-compiler/index.js?{\\\"vue\\\":true,\\\"id\\\":\\\"data-v-1d7c4045\\\",\\\"scoped\\\":false,\\\"hasInlineConfig\\\":false}!../../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./copyfield.vue\");\nif(typeof content === 'string') content = [[module.id, content, '']];\nif(content.locals) module.exports = content.locals;\n// add the styles to the DOM\nvar update = require(\"!../../node_modules/vue-style-loader/lib/addStylesClient.js\")(\"041522c3\", content, false, {});\n// Hot Module Replacement\nif(module.hot) {\n // When the styles change, update the <style> tags\n if(!content.locals) {\n   module.hot.accept(\"!!../../node_modules/css-loader/index.js?{\\\"sourceMap\\\":true}!../../node_modules/vue-loader/lib/style-compiler/index.js?{\\\"vue\\\":true,\\\"id\\\":\\\"data-v-1d7c4045\\\",\\\"scoped\\\":false,\\\"hasInlineConfig\\\":false}!../../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./copyfield.vue\", function() {\n     var newContent = require(\"!!../../node_modules/css-loader/index.js?{\\\"sourceMap\\\":true}!../../node_modules/vue-loader/lib/style-compiler/index.js?{\\\"vue\\\":true,\\\"id\\\":\\\"data-v-1d7c4045\\\",\\\"scoped\\\":false,\\\"hasInlineConfig\\\":false}!../../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./copyfield.vue\");\n     if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n     update(newContent);\n   });\n }\n // When the module is disposed, remove the <style> tags\n module.hot.dispose(function() { update(); });\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/vue-style-loader!./node_modules/css-loader?{\"sourceMap\":true}!./node_modules/vue-loader/lib/style-compiler?{\"vue\":true,\"id\":\"data-v-1d7c4045\",\"scoped\":false,\"hasInlineConfig\":false}!./node_modules/vue-loader/lib/selector.js?type=styles&index=0!./src/components/copyfield.vue\n// module id = E8lD\n// module chunks = 0","// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = require(\"!!../../node_modules/css-loader/index.js?{\\\"sourceMap\\\":true}!../../node_modules/vue-loader/lib/style-compiler/index.js?{\\\"vue\\\":true,\\\"id\\\":\\\"data-v-92448f0a\\\",\\\"scoped\\\":true,\\\"hasInlineConfig\\\":false}!../../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./readmore.vue\");\nif(typeof content === 'string') content = [[module.id, content, '']];\nif(content.locals) module.exports = content.locals;\n// add the styles to the DOM\nvar update = require(\"!../../node_modules/vue-style-loader/lib/addStylesClient.js\")(\"c9be660c\", content, false, {});\n// Hot Module Replacement\nif(module.hot) {\n // When the styles change, update the <style> tags\n if(!content.locals) {\n   module.hot.accept(\"!!../../node_modules/css-loader/index.js?{\\\"sourceMap\\\":true}!../../node_modules/vue-loader/lib/style-compiler/index.js?{\\\"vue\\\":true,\\\"id\\\":\\\"data-v-92448f0a\\\",\\\"scoped\\\":true,\\\"hasInlineConfig\\\":false}!../../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./readmore.vue\", function() {\n     var newContent = require(\"!!../../node_modules/css-loader/index.js?{\\\"sourceMap\\\":true}!../../node_modules/vue-loader/lib/style-compiler/index.js?{\\\"vue\\\":true,\\\"id\\\":\\\"data-v-92448f0a\\\",\\\"scoped\\\":true,\\\"hasInlineConfig\\\":false}!../../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./readmore.vue\");\n     if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n     update(newContent);\n   });\n }\n // When the module is disposed, remove the <style> tags\n module.hot.dispose(function() { update(); });\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/vue-style-loader!./node_modules/css-loader?{\"sourceMap\":true}!./node_modules/vue-loader/lib/style-compiler?{\"vue\":true,\"id\":\"data-v-92448f0a\",\"scoped\":true,\"hasInlineConfig\":false}!./node_modules/vue-loader/lib/selector.js?type=styles&index=0!./src/components/readmore.vue\n// module id = KU0+\n// module chunks = 0","<template>\n<div>\n  <div class = \"v-modal-container\">\n    <div\n      ref = \"screen\"\n      v-on:click = \"$emit('close-modal')\"\n      class = \"v-modal-screen\">\n    </div>\n    <div\n      v-bind:style = \"{top:contentContainerTop,left:contentContainerLeft,width:contentContainerWidth,height:contentContainerHeight,}\"\n      class = \"v-modal-content-container\">\n      <div\n        ref = \"content\"\n        class = \"v-modal-content\">\n        <div class = \"v-modal-header\">\n          <slot name = \"v-modal-header\">\n          </slot>\n        </div>\n        <div class = \"v-modal-body\">\n          <slot name = \"v-modal-body\">\n          </slot>\n        </div>\n        <div class = \"v-modal-footer\">\n          <slot name = \"v-modal-footer\">\n          </slot>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n</template>\n<script>\nexport default {\n  props: {\n    top: Number,\n    left: Number\n  },\n  data: () => ({\n    show: {\n      type: Boolean,\n      default: false\n    }\n  }),\n  computed: {\n    contentContainerLeft: function () {\n      return this.top && this.left && this.$refs.content && this.$refs.screen ? Math.min(this.left, this.$refs.screen.clientWidth - this.$refs.content.clientWidth) + 'px' : `0px`\n    },\n    contentContainerTop: function () {\n      return this.top && this.left && this.$refs.content && this.$refs.screen ? Math.min(this.top, this.$refs.screen.clientHeight - this.$refs.content.clientHeight) + 'px' : `0px`\n    },\n    contentContainerWidth: function () {\n      return this.top && this.left && this.$refs.content && this.$refs.screen ? 'auto' : `100%`\n    },\n    contentContainerHeight: function () {\n      return this.top && this.left && this.$refs.content && this.$refs.screen ? 'auto' : `100%`\n    }\n  }\n}\n</script>\n<style scoped>\n.v-modal-container\n{\n  top: 0;\n  width:100%;\n  height:100%;\n  position : absolute;\n  z-index:999;\n}\n.v-modal-screen\n{\n  top : 0;\n  position : absolute;\n  width:100%;\n  height:100%;\n  background-color:rgba(30,30,30,0.2);\n}\n\n.v-modal-content-container\n{\n  top : 0;\n  position : absolute;\n  display : flex;\n  align-items: center;\n  align-content: center;\n  justify-content: center;\n\n  pointer-events: none;\n}\n.v-modal-content\n{\n  flex : 0 0 auto;\n  pointer-events: all;\n}\n\n</style>\n\n\n\n// WEBPACK FOOTER //\n// src/components/modal.vue","var render = function() {\n  var _vm = this\n  var _h = _vm.$createElement\n  var _c = _vm._self._c || _h\n  return _c(\"div\", [\n    _c(\"div\", { staticClass: \"v-modal-container\" }, [\n      _c(\"div\", {\n        ref: \"screen\",\n        staticClass: \"v-modal-screen\",\n        on: {\n          click: function($event) {\n            _vm.$emit(\"close-modal\")\n          }\n        }\n      }),\n      _vm._v(\" \"),\n      _c(\n        \"div\",\n        {\n          staticClass: \"v-modal-content-container\",\n          style: {\n            top: _vm.contentContainerTop,\n            left: _vm.contentContainerLeft,\n            width: _vm.contentContainerWidth,\n            height: _vm.contentContainerHeight\n          }\n        },\n        [\n          _c(\"div\", { ref: \"content\", staticClass: \"v-modal-content\" }, [\n            _c(\n              \"div\",\n              { staticClass: \"v-modal-header\" },\n              [_vm._t(\"v-modal-header\")],\n              2\n            ),\n            _vm._v(\" \"),\n            _c(\n              \"div\",\n              { staticClass: \"v-modal-body\" },\n              [_vm._t(\"v-modal-body\")],\n              2\n            ),\n            _vm._v(\" \"),\n            _c(\n              \"div\",\n              { staticClass: \"v-modal-footer\" },\n              [_vm._t(\"v-modal-footer\")],\n              2\n            )\n          ])\n        ]\n      )\n    ])\n  ])\n}\nvar staticRenderFns = []\nrender._withStripped = true\nvar esExports = { render: render, staticRenderFns: staticRenderFns }\nexport default esExports\nif (module.hot) {\n  module.hot.accept()\n  if (module.hot.data) {\n    require(\"vue-hot-reload-api\")      .rerender(\"data-v-0eaeaf66\", esExports)\n  }\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/vue-loader/lib/template-compiler?{\"id\":\"data-v-0eaeaf66\",\"hasScoped\":true,\"transformToRequire\":{\"video\":[\"src\",\"poster\"],\"source\":\"src\",\"img\":\"src\",\"image\":\"xlink:href\"},\"buble\":{\"transforms\":{}}}!./node_modules/vue-loader/lib/selector.js?type=template&index=0!./src/components/modal.vue\n// module id = null\n// module chunks = ","var disposed = false\nfunction injectStyle (ssrContext) {\n  if (disposed) return\n  require(\"!!vue-style-loader!css-loader?{\\\"sourceMap\\\":true}!../../node_modules/vue-loader/lib/style-compiler/index?{\\\"vue\\\":true,\\\"id\\\":\\\"data-v-0eaeaf66\\\",\\\"scoped\\\":true,\\\"hasInlineConfig\\\":false}!../../node_modules/vue-loader/lib/selector?type=styles&index=0!./modal.vue\")\n}\nvar normalizeComponent = require(\"!../../node_modules/vue-loader/lib/component-normalizer\")\n/* script */\nexport * from \"!!babel-loader!../../node_modules/vue-loader/lib/selector?type=script&index=0!./modal.vue\"\nimport __vue_script__ from \"!!babel-loader!../../node_modules/vue-loader/lib/selector?type=script&index=0!./modal.vue\"\n/* template */\nimport __vue_template__ from \"!!../../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-0eaeaf66\\\",\\\"hasScoped\\\":true,\\\"transformToRequire\\\":{\\\"video\\\":[\\\"src\\\",\\\"poster\\\"],\\\"source\\\":\\\"src\\\",\\\"img\\\":\\\"src\\\",\\\"image\\\":\\\"xlink:href\\\"},\\\"buble\\\":{\\\"transforms\\\":{}}}!../../node_modules/vue-loader/lib/selector?type=template&index=0!./modal.vue\"\n/* template functional */\nvar __vue_template_functional__ = false\n/* styles */\nvar __vue_styles__ = injectStyle\n/* scopeId */\nvar __vue_scopeId__ = \"data-v-0eaeaf66\"\n/* moduleIdentifier (server only) */\nvar __vue_module_identifier__ = null\nvar Component = normalizeComponent(\n  __vue_script__,\n  __vue_template__,\n  __vue_template_functional__,\n  __vue_styles__,\n  __vue_scopeId__,\n  __vue_module_identifier__\n)\nComponent.options.__file = \"src/components/modal.vue\"\n\n/* hot reload */\nif (module.hot) {(function () {\n  var hotAPI = require(\"vue-hot-reload-api\")\n  hotAPI.install(require(\"vue\"), false)\n  if (!hotAPI.compatible) return\n  module.hot.accept()\n  if (!module.hot.data) {\n    hotAPI.createRecord(\"data-v-0eaeaf66\", Component.options)\n  } else {\n    hotAPI.reload(\"data-v-0eaeaf66\", Component.options)\n  }\n  module.hot.dispose(function (data) {\n    disposed = true\n  })\n})()}\n\nexport default Component.exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/components/modal.vue\n// module id = null\n// module chunks = ","<template>\n<div class = \"autocomplete-container\">\n  <input\n    ref = \"input\"\n    @keydown.stop = \"hitEnter\"\n    type = \"text\"\n    @focus = \"showSuggestions = true\"\n    @blur = \"showSuggestions = false\"\n    v-model = \"typedText\"\n    :placeholder = \"placeholder\"/>\n  <transition name = \"fade\">\n    <div v-if = \"showSuggestions\" class = \"autocomplete-suggestion-container\">\n      <div\n        @mousedown=\"selectSlice(item)\"\n        class = \"autocomplete-suggestions\"\n        :class = \"{active : ((highlightIndex % filteredArray.length) === index)}\"\n        v-bind:key = \"index\"\n        v-for = \"(item,index) in filteredArray\">\n        {{ item }}\n      </div>\n    </div>\n  </transition>\n</div>\n</template>\n\n<script>\nexport default {\n  props: {\n    placeholder: {\n      type: String,\n      default: 'Start typing to search ...'\n    },\n    rawarray: {\n      type: Array,\n      default: () => ([])\n    },\n    rendermax: {\n      type: Number,\n      default: 25\n    }\n  },\n  data: () => ({\n    showSuggestions: false,\n    typedText: '',\n    highlightIndex: 0\n  }),\n  methods: {\n    selectSlice: function (item) {\n      this.$emit('selectslice', item)\n    },\n    hitEnter: function () {\n      switch (event.key) {\n        case 'ArrowDown':\n          this.highlightIndex += 1\n          break\n        case 'Escape':\n          this.$refs.input.blur()\n          break\n        case 'ArrowUp':\n          this.highlightIndex -= 1\n          if (this.highlightIndex <= 0) this.highlightIndex += this.filteredArray.length\n          break\n        case 'Enter':\n          const array = this.filteredArray.slice()\n          if (array.length > 0) {\n            this.typedText = ''\n            const el = document.querySelector(':focus')\n            if (el) el.blur()\n            this.selectSlice(array[0])\n          }\n          break\n        default:\n          this.highlightIndex = 0\n          break\n      }\n    }\n  },\n  computed: {\n    rawArrayLowerCase: function () {\n      return this.rawarray.map(item => item.toLowerCase())\n    },\n    typedTextLowerCase: function () {\n      return this.typedText.toLowerCase()\n    },\n    filteredArray: function () {\n      const regex = new RegExp(this.typedText, 'i')\n      const completeMatch = this.rawarray.find(item => item.toLowerCase() === this.typedTextLowerCase)\n      const othermatches = this.rawarray\n        .filter(item => regex.test(item))\n        .filter(item => item.toLowerCase() !== this.typedTextLowerCase)\n        .filter((_, idx) => idx <= this.rendermax)\n      return completeMatch\n        ? [completeMatch].concat(othermatches.slice(0, othermatches.length >= this.rendermax ? othermatches.length - 1 : othermatches.length))\n        : othermatches\n    }\n  }\n}\n</script>\n\n<style scoped>\ndiv.autocomplete-container\n{\n  cursor:default;\n}\n\n.autocomplete-suggestions\n{\n  width:100%;\n  display:block;\n  padding:0.1em 0.3em;\n  transition: all 200ms;\n  background-color:rgba(230,230,230,0.5);\n}\n\n.autocomplete-suggestions.active\n{\n  background-color:rgba(230,230,230,0.95);\n}\n\n.autocomplete-suggestions:hover\n{\n  background-color:rgba(230,230,230,0.95);\n}\n\ndiv.autocomplete-container:focus-within .autocomplete-suggestions\n{\n  display: block;\n}\n\ndiv.autocomplete-suggestion-container\n{\n  width: 100%;\n  max-height:10em;\n  overflow-y:auto;\n  overflow-x:hidden;\n  z-index:2;\n}\ninput[type=\"text\"]\n{\n  width:100%;\n  height:100%;\n  z-index:1;\n}\n</style>\n\n\n\n// WEBPACK FOOTER //\n// src/components/autocomplete.vue","var render = function() {\n  var _vm = this\n  var _h = _vm.$createElement\n  var _c = _vm._self._c || _h\n  return _c(\n    \"div\",\n    { staticClass: \"autocomplete-container\" },\n    [\n      _c(\"input\", {\n        directives: [\n          {\n            name: \"model\",\n            rawName: \"v-model\",\n            value: _vm.typedText,\n            expression: \"typedText\"\n          }\n        ],\n        ref: \"input\",\n        attrs: { type: \"text\", placeholder: _vm.placeholder },\n        domProps: { value: _vm.typedText },\n        on: {\n          keydown: function($event) {\n            $event.stopPropagation()\n            return _vm.hitEnter($event)\n          },\n          focus: function($event) {\n            _vm.showSuggestions = true\n          },\n          blur: function($event) {\n            _vm.showSuggestions = false\n          },\n          input: function($event) {\n            if ($event.target.composing) {\n              return\n            }\n            _vm.typedText = $event.target.value\n          }\n        }\n      }),\n      _vm._v(\" \"),\n      _c(\"transition\", { attrs: { name: \"fade\" } }, [\n        _vm.showSuggestions\n          ? _c(\n              \"div\",\n              { staticClass: \"autocomplete-suggestion-container\" },\n              _vm._l(_vm.filteredArray, function(item, index) {\n                return _c(\n                  \"div\",\n                  {\n                    key: index,\n                    staticClass: \"autocomplete-suggestions\",\n                    class: {\n                      active:\n                        _vm.highlightIndex % _vm.filteredArray.length === index\n                    },\n                    on: {\n                      mousedown: function($event) {\n                        _vm.selectSlice(item)\n                      }\n                    }\n                  },\n                  [_vm._v(\"\\n        \" + _vm._s(item) + \"\\n      \")]\n                )\n              })\n            )\n          : _vm._e()\n      ])\n    ],\n    1\n  )\n}\nvar staticRenderFns = []\nrender._withStripped = true\nvar esExports = { render: render, staticRenderFns: staticRenderFns }\nexport default esExports\nif (module.hot) {\n  module.hot.accept()\n  if (module.hot.data) {\n    require(\"vue-hot-reload-api\")      .rerender(\"data-v-8351e810\", esExports)\n  }\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/vue-loader/lib/template-compiler?{\"id\":\"data-v-8351e810\",\"hasScoped\":true,\"transformToRequire\":{\"video\":[\"src\",\"poster\"],\"source\":\"src\",\"img\":\"src\",\"image\":\"xlink:href\"},\"buble\":{\"transforms\":{}}}!./node_modules/vue-loader/lib/selector.js?type=template&index=0!./src/components/autocomplete.vue\n// module id = null\n// module chunks = ","var disposed = false\nfunction injectStyle (ssrContext) {\n  if (disposed) return\n  require(\"!!vue-style-loader!css-loader?{\\\"sourceMap\\\":true}!../../node_modules/vue-loader/lib/style-compiler/index?{\\\"vue\\\":true,\\\"id\\\":\\\"data-v-8351e810\\\",\\\"scoped\\\":true,\\\"hasInlineConfig\\\":false}!../../node_modules/vue-loader/lib/selector?type=styles&index=0!./autocomplete.vue\")\n}\nvar normalizeComponent = require(\"!../../node_modules/vue-loader/lib/component-normalizer\")\n/* script */\nexport * from \"!!babel-loader!../../node_modules/vue-loader/lib/selector?type=script&index=0!./autocomplete.vue\"\nimport __vue_script__ from \"!!babel-loader!../../node_modules/vue-loader/lib/selector?type=script&index=0!./autocomplete.vue\"\n/* template */\nimport __vue_template__ from \"!!../../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-8351e810\\\",\\\"hasScoped\\\":true,\\\"transformToRequire\\\":{\\\"video\\\":[\\\"src\\\",\\\"poster\\\"],\\\"source\\\":\\\"src\\\",\\\"img\\\":\\\"src\\\",\\\"image\\\":\\\"xlink:href\\\"},\\\"buble\\\":{\\\"transforms\\\":{}}}!../../node_modules/vue-loader/lib/selector?type=template&index=0!./autocomplete.vue\"\n/* template functional */\nvar __vue_template_functional__ = false\n/* styles */\nvar __vue_styles__ = injectStyle\n/* scopeId */\nvar __vue_scopeId__ = \"data-v-8351e810\"\n/* moduleIdentifier (server only) */\nvar __vue_module_identifier__ = null\nvar Component = normalizeComponent(\n  __vue_script__,\n  __vue_template__,\n  __vue_template_functional__,\n  __vue_styles__,\n  __vue_scopeId__,\n  __vue_module_identifier__\n)\nComponent.options.__file = \"src/components/autocomplete.vue\"\n\n/* hot reload */\nif (module.hot) {(function () {\n  var hotAPI = require(\"vue-hot-reload-api\")\n  hotAPI.install(require(\"vue\"), false)\n  if (!hotAPI.compatible) return\n  module.hot.accept()\n  if (!module.hot.data) {\n    hotAPI.createRecord(\"data-v-8351e810\", Component.options)\n  } else {\n    hotAPI.reload(\"data-v-8351e810\", Component.options)\n  }\n  module.hot.dispose(function (data) {\n    disposed = true\n  })\n})()}\n\nexport default Component.exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/components/autocomplete.vue\n// module id = null\n// module chunks = ","<template>\n<div class = \"copy-field-root\">\n  <input ref = \"inputEl\" readonly v-bind:value = \"value\" type = \"text\" />\n  <div\n    v-bind:hidden = \"!copyable\"\n    @click.stop = \"copyToClipBoard\">{{ methodGetCopyText() }}\n  </div>\n</div>\n</template>\n\n<script>\nexport default {\n  props: {\n    value: {\n      type: String,\n      default: 'default value'\n    },\n    copyable: {\n      type: Boolean,\n      default: true\n    }\n  },\n  data: () => ({\n    copiedFlag: false,\n    timeoutRef: 0,\n    copyBtnShown: false\n  }),\n  methods: {\n    copyToClipBoard: function () {\n      this.copiedFlag = true\n      if (this.timeoutRef) {\n        clearTimeout(this.timeoutRef)\n      }\n      setTimeout(() => {\n        this.copiedFlag = false\n        this.timeoutRef = 0\n      }, 2000)\n\n      this.$refs.inputEl.focus()\n      this.$refs.inputEl.select()\n      document.execCommand('copy', false)\n    },\n    methodGetCopyText: function () {\n      return this.copiedFlag ? 'Copied!' : 'Copy'\n    }\n  }\n}\n</script>\n<style>\n.copy-field-root\n{\n  width: 100%;\n  white-space: nowrap;\n}\n\n.copy-field-root *\n{\n  color:black\n}\n\n.copy-field-root > input\n{\n  width : 100%;\n  height:2.0em;\n  display: inline-block;\n  vertical-align : middle;\n  box-sizing: border-box;\n  position : relative;\n\n  border : solid 1px rgba(128,128,128,0.6);\n  z-index: 8;\n}\n\n.copy-field-root > div:not([hidden])\n{\n  position : relative;\n  z-index: 9;\n  cursor:default;\n  display: inline-block;\n  box-sizing:border-box;\n  margin : 0.2em;\n  height : 1.6em;\n  margin-left:-4em;\n  font-size:100%;\n  vertical-align : middle;\n  text-align: center;\n  font-size:0.9em;\n  padding : 0.2em;\n\n  color:rgba(0,0,0,0.8);\n  border : solid 1px rgba(0,0,0,0.5);\n\n  background-color:rgba(230,230,230,0.9);\n}\n\n.copy-field-root > div:hover\n{\n  background-color:rgba(240,240,240,1.0);\n}\n</style>\n\n\n\n// WEBPACK FOOTER //\n// src/components/copyfield.vue","var render = function() {\n  var _vm = this\n  var _h = _vm.$createElement\n  var _c = _vm._self._c || _h\n  return _c(\"div\", { staticClass: \"copy-field-root\" }, [\n    _c(\"input\", {\n      ref: \"inputEl\",\n      attrs: { readonly: \"\", type: \"text\" },\n      domProps: { value: _vm.value }\n    }),\n    _vm._v(\" \"),\n    _c(\n      \"div\",\n      {\n        attrs: { hidden: !_vm.copyable },\n        on: {\n          click: function($event) {\n            $event.stopPropagation()\n            return _vm.copyToClipBoard($event)\n          }\n        }\n      },\n      [_vm._v(_vm._s(_vm.methodGetCopyText()) + \"\\n  \")]\n    )\n  ])\n}\nvar staticRenderFns = []\nrender._withStripped = true\nvar esExports = { render: render, staticRenderFns: staticRenderFns }\nexport default esExports\nif (module.hot) {\n  module.hot.accept()\n  if (module.hot.data) {\n    require(\"vue-hot-reload-api\")      .rerender(\"data-v-1d7c4045\", esExports)\n  }\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/vue-loader/lib/template-compiler?{\"id\":\"data-v-1d7c4045\",\"hasScoped\":false,\"transformToRequire\":{\"video\":[\"src\",\"poster\"],\"source\":\"src\",\"img\":\"src\",\"image\":\"xlink:href\"},\"buble\":{\"transforms\":{}}}!./node_modules/vue-loader/lib/selector.js?type=template&index=0!./src/components/copyfield.vue\n// module id = null\n// module chunks = ","var disposed = false\nfunction injectStyle (ssrContext) {\n  if (disposed) return\n  require(\"!!vue-style-loader!css-loader?{\\\"sourceMap\\\":true}!../../node_modules/vue-loader/lib/style-compiler/index?{\\\"vue\\\":true,\\\"id\\\":\\\"data-v-1d7c4045\\\",\\\"scoped\\\":false,\\\"hasInlineConfig\\\":false}!../../node_modules/vue-loader/lib/selector?type=styles&index=0!./copyfield.vue\")\n}\nvar normalizeComponent = require(\"!../../node_modules/vue-loader/lib/component-normalizer\")\n/* script */\nexport * from \"!!babel-loader!../../node_modules/vue-loader/lib/selector?type=script&index=0!./copyfield.vue\"\nimport __vue_script__ from \"!!babel-loader!../../node_modules/vue-loader/lib/selector?type=script&index=0!./copyfield.vue\"\n/* template */\nimport __vue_template__ from \"!!../../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-1d7c4045\\\",\\\"hasScoped\\\":false,\\\"transformToRequire\\\":{\\\"video\\\":[\\\"src\\\",\\\"poster\\\"],\\\"source\\\":\\\"src\\\",\\\"img\\\":\\\"src\\\",\\\"image\\\":\\\"xlink:href\\\"},\\\"buble\\\":{\\\"transforms\\\":{}}}!../../node_modules/vue-loader/lib/selector?type=template&index=0!./copyfield.vue\"\n/* template functional */\nvar __vue_template_functional__ = false\n/* styles */\nvar __vue_styles__ = injectStyle\n/* scopeId */\nvar __vue_scopeId__ = null\n/* moduleIdentifier (server only) */\nvar __vue_module_identifier__ = null\nvar Component = normalizeComponent(\n  __vue_script__,\n  __vue_template__,\n  __vue_template_functional__,\n  __vue_styles__,\n  __vue_scopeId__,\n  __vue_module_identifier__\n)\nComponent.options.__file = \"src/components/copyfield.vue\"\n\n/* hot reload */\nif (module.hot) {(function () {\n  var hotAPI = require(\"vue-hot-reload-api\")\n  hotAPI.install(require(\"vue\"), false)\n  if (!hotAPI.compatible) return\n  module.hot.accept()\n  if (!module.hot.data) {\n    hotAPI.createRecord(\"data-v-1d7c4045\", Component.options)\n  } else {\n    hotAPI.reload(\"data-v-1d7c4045\", Component.options)\n  }\n  module.hot.dispose(function (data) {\n    disposed = true\n  })\n})()}\n\nexport default Component.exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/components/copyfield.vue\n// module id = null\n// module chunks = ","<template>\n<div class = \"readmore-container\">\n  <div :style = \"{ height : computedHeight }\" class = \"readmore-content\">\n    <div ref = \"readmoreContentContainer\">\n      <slot name = \"readmoreContent\"></slot>\n    </div>\n  </div>\n  <div @click = \"toggle\" class = \"readmore-sliver\">\n    <slot v-if = \"collapsed\" name = \"resizeSliverContentCollapsed\">\n    </slot>\n    <slot v-if = \"!collapsed\" name = \"resizeSliverContentShown\">\n    </slot>\n  </div>\n</div>\n</template>\n<script>\nexport default {\n  props: {\n    collapsedHeight: {\n      type: Number,\n      default: 25\n    }\n  },\n  data: () => ({\n    collapsed: {\n      type: Boolean,\n      default: true\n    },\n    actualHeight: {\n      type: Number,\n      default: 25\n    }\n  }),\n  mounted: function () {\n    this.actualHeight = this.$refs.readmoreContentContainer.clientHeight\n  },\n  methods: {\n    toggle: function () {\n      this.collapsed = !this.collapsed\n    }\n  },\n  computed: {\n    computedHeight: function () {\n      return `${this.collapsed ? this.collapsedHeight : this.actualHeight}px`\n    }\n  }\n}\n</script>\n<style scoped>\n.readmore-content\n{\n  transition: all 0.3s;\n  overflow-y : hidden;\n}\n.readmore-sliver\n{\n  min-height: 0.5em;\n  transition: all 0.3s;\n  background-color: rgba(128,128,128,0.2);\n}\n.readmore-sliver:hover\n{\n  transform: translateY(-2px);\n  background-color: rgba(128,128,128,0.4);\n}\n</style>\n\n\n\n// WEBPACK FOOTER //\n// src/components/readmore.vue","var render = function() {\n  var _vm = this\n  var _h = _vm.$createElement\n  var _c = _vm._self._c || _h\n  return _c(\"div\", { staticClass: \"readmore-container\" }, [\n    _c(\n      \"div\",\n      {\n        staticClass: \"readmore-content\",\n        style: { height: _vm.computedHeight }\n      },\n      [\n        _c(\n          \"div\",\n          { ref: \"readmoreContentContainer\" },\n          [_vm._t(\"readmoreContent\")],\n          2\n        )\n      ]\n    ),\n    _vm._v(\" \"),\n    _c(\n      \"div\",\n      { staticClass: \"readmore-sliver\", on: { click: _vm.toggle } },\n      [\n        _vm.collapsed ? _vm._t(\"resizeSliverContentCollapsed\") : _vm._e(),\n        _vm._v(\" \"),\n        !_vm.collapsed ? _vm._t(\"resizeSliverContentShown\") : _vm._e()\n      ],\n      2\n    )\n  ])\n}\nvar staticRenderFns = []\nrender._withStripped = true\nvar esExports = { render: render, staticRenderFns: staticRenderFns }\nexport default esExports\nif (module.hot) {\n  module.hot.accept()\n  if (module.hot.data) {\n    require(\"vue-hot-reload-api\")      .rerender(\"data-v-92448f0a\", esExports)\n  }\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/vue-loader/lib/template-compiler?{\"id\":\"data-v-92448f0a\",\"hasScoped\":true,\"transformToRequire\":{\"video\":[\"src\",\"poster\"],\"source\":\"src\",\"img\":\"src\",\"image\":\"xlink:href\"},\"buble\":{\"transforms\":{}}}!./node_modules/vue-loader/lib/selector.js?type=template&index=0!./src/components/readmore.vue\n// module id = null\n// module chunks = ","var disposed = false\nfunction injectStyle (ssrContext) {\n  if (disposed) return\n  require(\"!!vue-style-loader!css-loader?{\\\"sourceMap\\\":true}!../../node_modules/vue-loader/lib/style-compiler/index?{\\\"vue\\\":true,\\\"id\\\":\\\"data-v-92448f0a\\\",\\\"scoped\\\":true,\\\"hasInlineConfig\\\":false}!../../node_modules/vue-loader/lib/selector?type=styles&index=0!./readmore.vue\")\n}\nvar normalizeComponent = require(\"!../../node_modules/vue-loader/lib/component-normalizer\")\n/* script */\nexport * from \"!!babel-loader!../../node_modules/vue-loader/lib/selector?type=script&index=0!./readmore.vue\"\nimport __vue_script__ from \"!!babel-loader!../../node_modules/vue-loader/lib/selector?type=script&index=0!./readmore.vue\"\n/* template */\nimport __vue_template__ from \"!!../../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-92448f0a\\\",\\\"hasScoped\\\":true,\\\"transformToRequire\\\":{\\\"video\\\":[\\\"src\\\",\\\"poster\\\"],\\\"source\\\":\\\"src\\\",\\\"img\\\":\\\"src\\\",\\\"image\\\":\\\"xlink:href\\\"},\\\"buble\\\":{\\\"transforms\\\":{}}}!../../node_modules/vue-loader/lib/selector?type=template&index=0!./readmore.vue\"\n/* template functional */\nvar __vue_template_functional__ = false\n/* styles */\nvar __vue_styles__ = injectStyle\n/* scopeId */\nvar __vue_scopeId__ = \"data-v-92448f0a\"\n/* moduleIdentifier (server only) */\nvar __vue_module_identifier__ = null\nvar Component = normalizeComponent(\n  __vue_script__,\n  __vue_template__,\n  __vue_template_functional__,\n  __vue_styles__,\n  __vue_scopeId__,\n  __vue_module_identifier__\n)\nComponent.options.__file = \"src/components/readmore.vue\"\n\n/* hot reload */\nif (module.hot) {(function () {\n  var hotAPI = require(\"vue-hot-reload-api\")\n  hotAPI.install(require(\"vue\"), false)\n  if (!hotAPI.compatible) return\n  module.hot.accept()\n  if (!module.hot.data) {\n    hotAPI.createRecord(\"data-v-92448f0a\", Component.options)\n  } else {\n    hotAPI.reload(\"data-v-92448f0a\", Component.options)\n  }\n  module.hot.dispose(function (data) {\n    disposed = true\n  })\n})()}\n\nexport default Component.exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/components/readmore.vue\n// module id = null\n// module chunks = ","import Vue from 'vue'\n// import App from './App'\nimport Modal from './components/modal.vue'\nimport Pill from './components/pill.vue'\nimport AutoComplete from './components/autocomplete.vue'\nimport CopyField from './components/copyfield.vue'\nimport Readmore from './components/readmore.vue'\n\nVue.config.productionTip = false\n\n/* eslint-disable no-new */\n// new Vue({\n//   el: '#app',\n//   render: h => h(App)\n// })\nVue.component('vue-modal', Modal)\nVue.component('vue-pill', Pill)\nVue.component('vue-autocomplete', AutoComplete)\nVue.component('vue-copyfield', CopyField)\nVue.component('vue-readmore', Readmore)\n\n\n\n// WEBPACK FOOTER //\n// ./src/main.js","exports = module.exports = require(\"../../node_modules/css-loader/lib/css-base.js\")(true);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n.readmore-content[data-v-92448f0a]\\n{\\n  -webkit-transition: all 0.3s;\\n  transition: all 0.3s;\\n  overflow-y : hidden;\\n}\\n.readmore-sliver[data-v-92448f0a]\\n{\\n  min-height: 0.5em;\\n  -webkit-transition: all 0.3s;\\n  transition: all 0.3s;\\n  background-color: rgba(128,128,128,0.2);\\n}\\n.readmore-sliver[data-v-92448f0a]:hover\\n{\\n  -webkit-transform: translateY(-2px);\\n          transform: translateY(-2px);\\n  background-color: rgba(128,128,128,0.4);\\n}\\n\", \"\", {\"version\":3,\"sources\":[\"/home/xgui3783/dev/projects/vue-components/src/components/src/components/readmore.vue\"],\"names\":[],\"mappings\":\";AAiDA;;EAEA,6BAAA;EAAA,qBAAA;EACA,oBAAA;CACA;AACA;;EAEA,kBAAA;EACA,6BAAA;EAAA,qBAAA;EACA,wCAAA;CACA;AACA;;EAEA,oCAAA;UAAA,4BAAA;EACA,wCAAA;CACA\",\"file\":\"readmore.vue\",\"sourcesContent\":[\"<template>\\n<div class = \\\"readmore-container\\\">\\n  <div :style = \\\"{ height : computedHeight }\\\" class = \\\"readmore-content\\\">\\n    <div ref = \\\"readmoreContentContainer\\\">\\n      <slot name = \\\"readmoreContent\\\"></slot>\\n    </div>\\n  </div>\\n  <div @click = \\\"toggle\\\" class = \\\"readmore-sliver\\\">\\n    <slot v-if = \\\"collapsed\\\" name = \\\"resizeSliverContentCollapsed\\\">\\n    </slot>\\n    <slot v-if = \\\"!collapsed\\\" name = \\\"resizeSliverContentShown\\\">\\n    </slot>\\n  </div>\\n</div>\\n</template>\\n<script>\\nexport default {\\n  props: {\\n    collapsedHeight: {\\n      type: Number,\\n      default: 25\\n    }\\n  },\\n  data: () => ({\\n    collapsed: {\\n      type: Boolean,\\n      default: true\\n    },\\n    actualHeight: {\\n      type: Number,\\n      default: 25\\n    }\\n  }),\\n  mounted: function () {\\n    this.actualHeight = this.$refs.readmoreContentContainer.clientHeight\\n  },\\n  methods: {\\n    toggle: function () {\\n      this.collapsed = !this.collapsed\\n    }\\n  },\\n  computed: {\\n    computedHeight: function () {\\n      return `${this.collapsed ? this.collapsedHeight : this.actualHeight}px`\\n    }\\n  }\\n}\\n</script>\\n<style scoped>\\n.readmore-content\\n{\\n  transition: all 0.3s;\\n  overflow-y : hidden;\\n}\\n.readmore-sliver\\n{\\n  min-height: 0.5em;\\n  transition: all 0.3s;\\n  background-color: rgba(128,128,128,0.2);\\n}\\n.readmore-sliver:hover\\n{\\n  transform: translateY(-2px);\\n  background-color: rgba(128,128,128,0.4);\\n}\\n</style>\\n\"],\"sourceRoot\":\"\"}]);\n\n// exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/css-loader?{\"sourceMap\":true}!./node_modules/vue-loader/lib/style-compiler?{\"vue\":true,\"id\":\"data-v-92448f0a\",\"scoped\":true,\"hasInlineConfig\":false}!./node_modules/vue-loader/lib/selector.js?type=styles&index=0!./src/components/readmore.vue\n// module id = R6Sg\n// module chunks = 0","<template>\n<div @click.stop.prevent = \"$emit('select-pill')\" class = \"v-pill-container\">\n  <span class = \"v-pill-name\">{{ name }}</span>\n  <span v-if = \"closable\" @click.stop.prevent = \"$emit('remove-pill')\" class = \"v-pill-remove\">&times;</span>\n</div>\n</template>\n\n<script>\nmodule.exports = {\n  props: {\n    name: {\n      type: String,\n      default: 'Untitled'\n    },\n    closable: {\n      type: Boolean,\n      default: true\n    }\n  }\n}\n</script>\n\n<style scoped>\ndiv.v-pill-container\n{\n  display:inline-block;\n  white-space: nowrap;\n  margin:5px;\n  padding:0.2em 0.6em;\n  border-radius: 0.8em;\n}\n\ndiv.v-pill-container\n{\n  cursor: default;\n  transition: all 300ms;\n  background-color:rgba(50,50,50,0.2);\n}\n\ndiv.v-pill-container:hover\n{\n  background-color:rgba(150,150,150,0.2);\n}\n\nspan.v-pill-name\n{\n  cursor: default;\n  display:inline-block;\n}\nspan.v-pill-remove\n{\n  cursor: default;\n  display:inline-block;\n}\n\nspan.v-pill-remove:hover\n{\n  font-weight: 900;\n  color:rgba(200,30,30,1);\n}\n</style>\n\n\n\n// WEBPACK FOOTER //\n// src/components/pill.vue","exports = module.exports = require(\"../../node_modules/css-loader/lib/css-base.js\")(true);\n// imports\n\n\n// module\nexports.push([module.id, \"\\ndiv.autocomplete-container[data-v-8351e810]\\n{\\n  cursor:default;\\n}\\n.autocomplete-suggestions[data-v-8351e810]\\n{\\n  width:100%;\\n  display:block;\\n  padding:0.1em 0.3em;\\n  -webkit-transition: all 200ms;\\n  transition: all 200ms;\\n  background-color:rgba(230,230,230,0.5);\\n}\\n.autocomplete-suggestions.active[data-v-8351e810]\\n{\\n  background-color:rgba(230,230,230,0.95);\\n}\\n.autocomplete-suggestions[data-v-8351e810]:hover\\n{\\n  background-color:rgba(230,230,230,0.95);\\n}\\ndiv.autocomplete-container:focus-within .autocomplete-suggestions[data-v-8351e810]\\n{\\n  display: block;\\n}\\ndiv.autocomplete-suggestion-container[data-v-8351e810]\\n{\\n  width: 100%;\\n  max-height:10em;\\n  overflow-y:auto;\\n  overflow-x:hidden;\\n  z-index:2;\\n}\\ninput[type=\\\"text\\\"][data-v-8351e810]\\n{\\n  width:100%;\\n  height:100%;\\n  z-index:1;\\n}\\n\", \"\", {\"version\":3,\"sources\":[\"/home/xgui3783/dev/projects/vue-components/src/components/src/components/autocomplete.vue\"],\"names\":[],\"mappings\":\";AAoGA;;EAEA,eAAA;CACA;AAEA;;EAEA,WAAA;EACA,cAAA;EACA,oBAAA;EACA,8BAAA;EAAA,sBAAA;EACA,uCAAA;CACA;AAEA;;EAEA,wCAAA;CACA;AAEA;;EAEA,wCAAA;CACA;AAEA;;EAEA,eAAA;CACA;AAEA;;EAEA,YAAA;EACA,gBAAA;EACA,gBAAA;EACA,kBAAA;EACA,UAAA;CACA;AACA;;EAEA,WAAA;EACA,YAAA;EACA,UAAA;CACA\",\"file\":\"autocomplete.vue\",\"sourcesContent\":[\"<template>\\n<div class = \\\"autocomplete-container\\\">\\n  <input\\n    ref = \\\"input\\\"\\n    @keydown.stop = \\\"hitEnter\\\"\\n    type = \\\"text\\\"\\n    @focus = \\\"showSuggestions = true\\\"\\n    @blur = \\\"showSuggestions = false\\\"\\n    v-model = \\\"typedText\\\"\\n    :placeholder = \\\"placeholder\\\"/>\\n  <transition name = \\\"fade\\\">\\n    <div v-if = \\\"showSuggestions\\\" class = \\\"autocomplete-suggestion-container\\\">\\n      <div\\n        @mousedown=\\\"selectSlice(item)\\\"\\n        class = \\\"autocomplete-suggestions\\\"\\n        :class = \\\"{active : ((highlightIndex % filteredArray.length) === index)}\\\"\\n        v-bind:key = \\\"index\\\"\\n        v-for = \\\"(item,index) in filteredArray\\\">\\n        {{ item }}\\n      </div>\\n    </div>\\n  </transition>\\n</div>\\n</template>\\n\\n<script>\\nexport default {\\n  props: {\\n    placeholder: {\\n      type: String,\\n      default: 'Start typing to search ...'\\n    },\\n    rawarray: {\\n      type: Array,\\n      default: () => ([])\\n    },\\n    rendermax: {\\n      type: Number,\\n      default: 25\\n    }\\n  },\\n  data: () => ({\\n    showSuggestions: false,\\n    typedText: '',\\n    highlightIndex: 0\\n  }),\\n  methods: {\\n    selectSlice: function (item) {\\n      this.$emit('selectslice', item)\\n    },\\n    hitEnter: function () {\\n      switch (event.key) {\\n        case 'ArrowDown':\\n          this.highlightIndex += 1\\n          break\\n        case 'Escape':\\n          this.$refs.input.blur()\\n          break\\n        case 'ArrowUp':\\n          this.highlightIndex -= 1\\n          if (this.highlightIndex <= 0) this.highlightIndex += this.filteredArray.length\\n          break\\n        case 'Enter':\\n          const array = this.filteredArray.slice()\\n          if (array.length > 0) {\\n            this.typedText = ''\\n            const el = document.querySelector(':focus')\\n            if (el) el.blur()\\n            this.selectSlice(array[0])\\n          }\\n          break\\n        default:\\n          this.highlightIndex = 0\\n          break\\n      }\\n    }\\n  },\\n  computed: {\\n    rawArrayLowerCase: function () {\\n      return this.rawarray.map(item => item.toLowerCase())\\n    },\\n    typedTextLowerCase: function () {\\n      return this.typedText.toLowerCase()\\n    },\\n    filteredArray: function () {\\n      const regex = new RegExp(this.typedText, 'i')\\n      const completeMatch = this.rawarray.find(item => item.toLowerCase() === this.typedTextLowerCase)\\n      const othermatches = this.rawarray\\n        .filter(item => regex.test(item))\\n        .filter(item => item.toLowerCase() !== this.typedTextLowerCase)\\n        .filter((_, idx) => idx <= this.rendermax)\\n      return completeMatch\\n        ? [completeMatch].concat(othermatches.slice(0, othermatches.length >= this.rendermax ? othermatches.length - 1 : othermatches.length))\\n        : othermatches\\n    }\\n  }\\n}\\n</script>\\n\\n<style scoped>\\ndiv.autocomplete-container\\n{\\n  cursor:default;\\n}\\n\\n.autocomplete-suggestions\\n{\\n  width:100%;\\n  display:block;\\n  padding:0.1em 0.3em;\\n  transition: all 200ms;\\n  background-color:rgba(230,230,230,0.5);\\n}\\n\\n.autocomplete-suggestions.active\\n{\\n  background-color:rgba(230,230,230,0.95);\\n}\\n\\n.autocomplete-suggestions:hover\\n{\\n  background-color:rgba(230,230,230,0.95);\\n}\\n\\ndiv.autocomplete-container:focus-within .autocomplete-suggestions\\n{\\n  display: block;\\n}\\n\\ndiv.autocomplete-suggestion-container\\n{\\n  width: 100%;\\n  max-height:10em;\\n  overflow-y:auto;\\n  overflow-x:hidden;\\n  z-index:2;\\n}\\ninput[type=\\\"text\\\"]\\n{\\n  width:100%;\\n  height:100%;\\n  z-index:1;\\n}\\n</style>\\n\"],\"sourceRoot\":\"\"}]);\n\n// exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/css-loader?{\"sourceMap\":true}!./node_modules/vue-loader/lib/style-compiler?{\"vue\":true,\"id\":\"data-v-8351e810\",\"scoped\":true,\"hasInlineConfig\":false}!./node_modules/vue-loader/lib/selector.js?type=styles&index=0!./src/components/autocomplete.vue\n// module id = RpWc\n// module chunks = 0","var render = function() {\n  var _vm = this\n  var _h = _vm.$createElement\n  var _c = _vm._self._c || _h\n  return _c(\n    \"div\",\n    {\n      staticClass: \"v-pill-container\",\n      on: {\n        click: function($event) {\n          $event.stopPropagation()\n          $event.preventDefault()\n          _vm.$emit(\"select-pill\")\n        }\n      }\n    },\n    [\n      _c(\"span\", { staticClass: \"v-pill-name\" }, [_vm._v(_vm._s(_vm.name))]),\n      _vm._v(\" \"),\n      _vm.closable\n        ? _c(\n            \"span\",\n            {\n              staticClass: \"v-pill-remove\",\n              on: {\n                click: function($event) {\n                  $event.stopPropagation()\n                  $event.preventDefault()\n                  _vm.$emit(\"remove-pill\")\n                }\n              }\n            },\n            [_vm._v(\"×\")]\n          )\n        : _vm._e()\n    ]\n  )\n}\nvar staticRenderFns = []\nrender._withStripped = true\nvar esExports = { render: render, staticRenderFns: staticRenderFns }\nexport default esExports\nif (module.hot) {\n  module.hot.accept()\n  if (module.hot.data) {\n    require(\"vue-hot-reload-api\")      .rerender(\"data-v-94d8f66e\", esExports)\n  }\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/vue-loader/lib/template-compiler?{\"id\":\"data-v-94d8f66e\",\"hasScoped\":true,\"transformToRequire\":{\"video\":[\"src\",\"poster\"],\"source\":\"src\",\"img\":\"src\",\"image\":\"xlink:href\"},\"buble\":{\"transforms\":{}}}!./node_modules/vue-loader/lib/selector.js?type=template&index=0!./src/components/pill.vue\n// module id = ck25\n// module chunks = 0","exports = module.exports = require(\"../../node_modules/css-loader/lib/css-base.js\")(true);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n.copy-field-root\\n{\\n  width: 100%;\\n  white-space: nowrap;\\n}\\n.copy-field-root *\\n{\\n  color:black\\n}\\n.copy-field-root > input\\n{\\n  width : 100%;\\n  height:2.0em;\\n  display: inline-block;\\n  vertical-align : middle;\\n  -webkit-box-sizing: border-box;\\n          box-sizing: border-box;\\n  position : relative;\\n\\n  border : solid 1px rgba(128,128,128,0.6);\\n  z-index: 8;\\n}\\n.copy-field-root > div:not([hidden])\\n{\\n  position : relative;\\n  z-index: 9;\\n  cursor:default;\\n  display: inline-block;\\n  -webkit-box-sizing:border-box;\\n          box-sizing:border-box;\\n  margin : 0.2em;\\n  height : 1.6em;\\n  margin-left:-4em;\\n  font-size:100%;\\n  vertical-align : middle;\\n  text-align: center;\\n  font-size:0.9em;\\n  padding : 0.2em;\\n\\n  color:rgba(0,0,0,0.8);\\n  border : solid 1px rgba(0,0,0,0.5);\\n\\n  background-color:rgba(230,230,230,0.9);\\n}\\n.copy-field-root > div:hover\\n{\\n  background-color:rgba(240,240,240,1.0);\\n}\\n\", \"\", {\"version\":3,\"sources\":[\"/home/xgui3783/dev/projects/vue-components/src/components/src/components/copyfield.vue\"],\"names\":[],\"mappings\":\";AAiDA;;EAEA,YAAA;EACA,oBAAA;CACA;AAEA;;EAEA,WAAA;CACA;AAEA;;EAEA,aAAA;EACA,aAAA;EACA,sBAAA;EACA,wBAAA;EACA,+BAAA;UAAA,uBAAA;EACA,oBAAA;;EAEA,yCAAA;EACA,WAAA;CACA;AAEA;;EAEA,oBAAA;EACA,WAAA;EACA,eAAA;EACA,sBAAA;EACA,8BAAA;UAAA,sBAAA;EACA,eAAA;EACA,eAAA;EACA,iBAAA;EACA,eAAA;EACA,wBAAA;EACA,mBAAA;EACA,gBAAA;EACA,gBAAA;;EAEA,sBAAA;EACA,mCAAA;;EAEA,uCAAA;CACA;AAEA;;EAEA,uCAAA;CACA\",\"file\":\"copyfield.vue\",\"sourcesContent\":[\"<template>\\n<div class = \\\"copy-field-root\\\">\\n  <input ref = \\\"inputEl\\\" readonly v-bind:value = \\\"value\\\" type = \\\"text\\\" />\\n  <div\\n    v-bind:hidden = \\\"!copyable\\\"\\n    @click.stop = \\\"copyToClipBoard\\\">{{ methodGetCopyText() }}\\n  </div>\\n</div>\\n</template>\\n\\n<script>\\nexport default {\\n  props: {\\n    value: {\\n      type: String,\\n      default: 'default value'\\n    },\\n    copyable: {\\n      type: Boolean,\\n      default: true\\n    }\\n  },\\n  data: () => ({\\n    copiedFlag: false,\\n    timeoutRef: 0,\\n    copyBtnShown: false\\n  }),\\n  methods: {\\n    copyToClipBoard: function () {\\n      this.copiedFlag = true\\n      if (this.timeoutRef) {\\n        clearTimeout(this.timeoutRef)\\n      }\\n      setTimeout(() => {\\n        this.copiedFlag = false\\n        this.timeoutRef = 0\\n      }, 2000)\\n\\n      this.$refs.inputEl.focus()\\n      this.$refs.inputEl.select()\\n      document.execCommand('copy', false)\\n    },\\n    methodGetCopyText: function () {\\n      return this.copiedFlag ? 'Copied!' : 'Copy'\\n    }\\n  }\\n}\\n</script>\\n<style>\\n.copy-field-root\\n{\\n  width: 100%;\\n  white-space: nowrap;\\n}\\n\\n.copy-field-root *\\n{\\n  color:black\\n}\\n\\n.copy-field-root > input\\n{\\n  width : 100%;\\n  height:2.0em;\\n  display: inline-block;\\n  vertical-align : middle;\\n  box-sizing: border-box;\\n  position : relative;\\n\\n  border : solid 1px rgba(128,128,128,0.6);\\n  z-index: 8;\\n}\\n\\n.copy-field-root > div:not([hidden])\\n{\\n  position : relative;\\n  z-index: 9;\\n  cursor:default;\\n  display: inline-block;\\n  box-sizing:border-box;\\n  margin : 0.2em;\\n  height : 1.6em;\\n  margin-left:-4em;\\n  font-size:100%;\\n  vertical-align : middle;\\n  text-align: center;\\n  font-size:0.9em;\\n  padding : 0.2em;\\n\\n  color:rgba(0,0,0,0.8);\\n  border : solid 1px rgba(0,0,0,0.5);\\n\\n  background-color:rgba(230,230,230,0.9);\\n}\\n\\n.copy-field-root > div:hover\\n{\\n  background-color:rgba(240,240,240,1.0);\\n}\\n</style>\\n\"],\"sourceRoot\":\"\"}]);\n\n// exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/css-loader?{\"sourceMap\":true}!./node_modules/vue-loader/lib/style-compiler?{\"vue\":true,\"id\":\"data-v-1d7c4045\",\"scoped\":false,\"hasInlineConfig\":false}!./node_modules/vue-loader/lib/selector.js?type=styles&index=0!./src/components/copyfield.vue\n// module id = fKQA\n// module chunks = 0","module.exports = Vue;\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"Vue\"\n// module id = lRwf\n// module chunks = 0","exports = module.exports = require(\"../../node_modules/css-loader/lib/css-base.js\")(true);\n// imports\n\n\n// module\nexports.push([module.id, \"\\n.v-modal-container[data-v-0eaeaf66]\\n{\\n  top: 0;\\n  width:100%;\\n  height:100%;\\n  position : absolute;\\n  z-index:999;\\n}\\n.v-modal-screen[data-v-0eaeaf66]\\n{\\n  top : 0;\\n  position : absolute;\\n  width:100%;\\n  height:100%;\\n  background-color:rgba(30,30,30,0.2);\\n}\\n.v-modal-content-container[data-v-0eaeaf66]\\n{\\n  top : 0;\\n  position : absolute;\\n  display : -webkit-box;\\n  display : -ms-flexbox;\\n  display : flex;\\n  -webkit-box-align: center;\\n      -ms-flex-align: center;\\n          align-items: center;\\n  -ms-flex-line-pack: center;\\n      align-content: center;\\n  -webkit-box-pack: center;\\n      -ms-flex-pack: center;\\n          justify-content: center;\\n\\n  pointer-events: none;\\n}\\n.v-modal-content[data-v-0eaeaf66]\\n{\\n  -webkit-box-flex : 0;\\n      -ms-flex : 0 0 auto;\\n          flex : 0 0 auto;\\n  pointer-events: all;\\n}\\n\\n\", \"\", {\"version\":3,\"sources\":[\"/home/xgui3783/dev/projects/vue-components/src/components/src/components/modal.vue\"],\"names\":[],\"mappings\":\";AA4DA;;EAEA,OAAA;EACA,WAAA;EACA,YAAA;EACA,oBAAA;EACA,YAAA;CACA;AACA;;EAEA,QAAA;EACA,oBAAA;EACA,WAAA;EACA,YAAA;EACA,oCAAA;CACA;AAEA;;EAEA,QAAA;EACA,oBAAA;EACA,sBAAA;EAAA,sBAAA;EAAA,eAAA;EACA,0BAAA;MAAA,uBAAA;UAAA,oBAAA;EACA,2BAAA;MAAA,sBAAA;EACA,yBAAA;MAAA,sBAAA;UAAA,wBAAA;;EAEA,qBAAA;CACA;AACA;;EAEA,qBAAA;MAAA,oBAAA;UAAA,gBAAA;EACA,oBAAA;CACA\",\"file\":\"modal.vue\",\"sourcesContent\":[\"<template>\\n<div>\\n  <div class = \\\"v-modal-container\\\">\\n    <div\\n      ref = \\\"screen\\\"\\n      v-on:click = \\\"$emit('close-modal')\\\"\\n      class = \\\"v-modal-screen\\\">\\n    </div>\\n    <div\\n      v-bind:style = \\\"{top:contentContainerTop,left:contentContainerLeft,width:contentContainerWidth,height:contentContainerHeight,}\\\"\\n      class = \\\"v-modal-content-container\\\">\\n      <div\\n        ref = \\\"content\\\"\\n        class = \\\"v-modal-content\\\">\\n        <div class = \\\"v-modal-header\\\">\\n          <slot name = \\\"v-modal-header\\\">\\n          </slot>\\n        </div>\\n        <div class = \\\"v-modal-body\\\">\\n          <slot name = \\\"v-modal-body\\\">\\n          </slot>\\n        </div>\\n        <div class = \\\"v-modal-footer\\\">\\n          <slot name = \\\"v-modal-footer\\\">\\n          </slot>\\n        </div>\\n      </div>\\n    </div>\\n  </div>\\n</div>\\n</template>\\n<script>\\nexport default {\\n  props: {\\n    top: Number,\\n    left: Number\\n  },\\n  data: () => ({\\n    show: {\\n      type: Boolean,\\n      default: false\\n    }\\n  }),\\n  computed: {\\n    contentContainerLeft: function () {\\n      return this.top && this.left && this.$refs.content && this.$refs.screen ? Math.min(this.left, this.$refs.screen.clientWidth - this.$refs.content.clientWidth) + 'px' : `0px`\\n    },\\n    contentContainerTop: function () {\\n      return this.top && this.left && this.$refs.content && this.$refs.screen ? Math.min(this.top, this.$refs.screen.clientHeight - this.$refs.content.clientHeight) + 'px' : `0px`\\n    },\\n    contentContainerWidth: function () {\\n      return this.top && this.left && this.$refs.content && this.$refs.screen ? 'auto' : `100%`\\n    },\\n    contentContainerHeight: function () {\\n      return this.top && this.left && this.$refs.content && this.$refs.screen ? 'auto' : `100%`\\n    }\\n  }\\n}\\n</script>\\n<style scoped>\\n.v-modal-container\\n{\\n  top: 0;\\n  width:100%;\\n  height:100%;\\n  position : absolute;\\n  z-index:999;\\n}\\n.v-modal-screen\\n{\\n  top : 0;\\n  position : absolute;\\n  width:100%;\\n  height:100%;\\n  background-color:rgba(30,30,30,0.2);\\n}\\n\\n.v-modal-content-container\\n{\\n  top : 0;\\n  position : absolute;\\n  display : flex;\\n  align-items: center;\\n  align-content: center;\\n  justify-content: center;\\n\\n  pointer-events: none;\\n}\\n.v-modal-content\\n{\\n  flex : 0 0 auto;\\n  pointer-events: all;\\n}\\n\\n</style>\\n\"],\"sourceRoot\":\"\"}]);\n\n// exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/css-loader?{\"sourceMap\":true}!./node_modules/vue-loader/lib/style-compiler?{\"vue\":true,\"id\":\"data-v-0eaeaf66\",\"scoped\":true,\"hasInlineConfig\":false}!./node_modules/vue-loader/lib/selector.js?type=styles&index=0!./src/components/modal.vue\n// module id = n8WV\n// module chunks = 0","// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = require(\"!!../../node_modules/css-loader/index.js?{\\\"sourceMap\\\":true}!../../node_modules/vue-loader/lib/style-compiler/index.js?{\\\"vue\\\":true,\\\"id\\\":\\\"data-v-94d8f66e\\\",\\\"scoped\\\":true,\\\"hasInlineConfig\\\":false}!../../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./pill.vue\");\nif(typeof content === 'string') content = [[module.id, content, '']];\nif(content.locals) module.exports = content.locals;\n// add the styles to the DOM\nvar update = require(\"!../../node_modules/vue-style-loader/lib/addStylesClient.js\")(\"12958e8c\", content, false, {});\n// Hot Module Replacement\nif(module.hot) {\n // When the styles change, update the <style> tags\n if(!content.locals) {\n   module.hot.accept(\"!!../../node_modules/css-loader/index.js?{\\\"sourceMap\\\":true}!../../node_modules/vue-loader/lib/style-compiler/index.js?{\\\"vue\\\":true,\\\"id\\\":\\\"data-v-94d8f66e\\\",\\\"scoped\\\":true,\\\"hasInlineConfig\\\":false}!../../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./pill.vue\", function() {\n     var newContent = require(\"!!../../node_modules/css-loader/index.js?{\\\"sourceMap\\\":true}!../../node_modules/vue-loader/lib/style-compiler/index.js?{\\\"vue\\\":true,\\\"id\\\":\\\"data-v-94d8f66e\\\",\\\"scoped\\\":true,\\\"hasInlineConfig\\\":false}!../../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./pill.vue\");\n     if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n     update(newContent);\n   });\n }\n // When the module is disposed, remove the <style> tags\n module.hot.dispose(function() { update(); });\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/vue-style-loader!./node_modules/css-loader?{\"sourceMap\":true}!./node_modules/vue-loader/lib/style-compiler?{\"vue\":true,\"id\":\"data-v-94d8f66e\",\"scoped\":true,\"hasInlineConfig\":false}!./node_modules/vue-loader/lib/selector.js?type=styles&index=0!./src/components/pill.vue\n// module id = nFT+\n// module chunks = 0","var disposed = false\nfunction injectStyle (ssrContext) {\n  if (disposed) return\n  require(\"!!vue-style-loader!css-loader?{\\\"sourceMap\\\":true}!../../node_modules/vue-loader/lib/style-compiler/index?{\\\"vue\\\":true,\\\"id\\\":\\\"data-v-94d8f66e\\\",\\\"scoped\\\":true,\\\"hasInlineConfig\\\":false}!../../node_modules/vue-loader/lib/selector?type=styles&index=0!./pill.vue\")\n}\nvar normalizeComponent = require(\"!../../node_modules/vue-loader/lib/component-normalizer\")\n/* script */\nexport * from \"!!babel-loader!../../node_modules/vue-loader/lib/selector?type=script&index=0!./pill.vue\"\nimport __vue_script__ from \"!!babel-loader!../../node_modules/vue-loader/lib/selector?type=script&index=0!./pill.vue\"\n/* template */\nimport __vue_template__ from \"!!../../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-94d8f66e\\\",\\\"hasScoped\\\":true,\\\"transformToRequire\\\":{\\\"video\\\":[\\\"src\\\",\\\"poster\\\"],\\\"source\\\":\\\"src\\\",\\\"img\\\":\\\"src\\\",\\\"image\\\":\\\"xlink:href\\\"},\\\"buble\\\":{\\\"transforms\\\":{}}}!../../node_modules/vue-loader/lib/selector?type=template&index=0!./pill.vue\"\n/* template functional */\nvar __vue_template_functional__ = false\n/* styles */\nvar __vue_styles__ = injectStyle\n/* scopeId */\nvar __vue_scopeId__ = \"data-v-94d8f66e\"\n/* moduleIdentifier (server only) */\nvar __vue_module_identifier__ = null\nvar Component = normalizeComponent(\n  __vue_script__,\n  __vue_template__,\n  __vue_template_functional__,\n  __vue_styles__,\n  __vue_scopeId__,\n  __vue_module_identifier__\n)\nComponent.options.__file = \"src/components/pill.vue\"\n\n/* hot reload */\nif (module.hot) {(function () {\n  var hotAPI = require(\"vue-hot-reload-api\")\n  hotAPI.install(require(\"vue\"), false)\n  if (!hotAPI.compatible) return\n  module.hot.accept()\n  if (!module.hot.data) {\n    hotAPI.createRecord(\"data-v-94d8f66e\", Component.options)\n  } else {\n    hotAPI.reload(\"data-v-94d8f66e\", Component.options)\n  }\n  module.hot.dispose(function (data) {\n    disposed = true\n  })\n})()}\n\nexport default Component.exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/components/pill.vue\n// module id = u0wG\n// module chunks = 0"],"sourceRoot":""}
\ No newline at end of file
diff --git a/src/plugin_examples/newWebJugex/manifest.js b/src/plugin_examples/newWebJugex/manifest.js
new file mode 100644
index 000000000..1f3bed735
--- /dev/null
+++ b/src/plugin_examples/newWebJugex/manifest.js
@@ -0,0 +1,2 @@
+!function(r){var n=window.webpackJsonp;window.webpackJsonp=function(e,u,c){for(var f,i,p,a=0,l=[];a<e.length;a++)i=e[a],o[i]&&l.push(o[i][0]),o[i]=0;for(f in u)Object.prototype.hasOwnProperty.call(u,f)&&(r[f]=u[f]);for(n&&n(e,u,c);l.length;)l.shift()();if(c)for(a=0;a<c.length;a++)p=t(t.s=c[a]);return p};var e={},o={2:0};function t(n){if(e[n])return e[n].exports;var o=e[n]={i:n,l:!1,exports:{}};return r[n].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=r,t.c=e,t.d=function(r,n,e){t.o(r,n)||Object.defineProperty(r,n,{configurable:!1,enumerable:!0,get:e})},t.n=function(r){var n=r&&r.__esModule?function(){return r.default}:function(){return r};return t.d(n,"a",n),n},t.o=function(r,n){return Object.prototype.hasOwnProperty.call(r,n)},t.p="",t.oe=function(r){throw console.error(r),r}}([]);
+//# sourceMappingURL=manifest.js.map
\ No newline at end of file
diff --git a/src/plugin_examples/newWebJugex/manifest.js.map b/src/plugin_examples/newWebJugex/manifest.js.map
new file mode 100644
index 000000000..0bd52be68
--- /dev/null
+++ b/src/plugin_examples/newWebJugex/manifest.js.map
@@ -0,0 +1 @@
+{"version":3,"sources":["webpack:///webpack/bootstrap 5735c67e542cf68358f5"],"names":["parentJsonpFunction","window","chunkIds","moreModules","executeModules","moduleId","chunkId","result","i","resolves","length","installedChunks","push","Object","prototype","hasOwnProperty","call","modules","shift","__webpack_require__","s","installedModules","2","exports","module","l","m","c","d","name","getter","o","defineProperty","configurable","enumerable","get","n","__esModule","object","property","p","oe","err","console","error"],"mappings":"aACA,IAAAA,EAAAC,OAAA,aACAA,OAAA,sBAAAC,EAAAC,EAAAC,GAIA,IADA,IAAAC,EAAAC,EAAAC,EAAAC,EAAA,EAAAC,KACQD,EAAAN,EAAAQ,OAAoBF,IAC5BF,EAAAJ,EAAAM,GACAG,EAAAL,IACAG,EAAAG,KAAAD,EAAAL,GAAA,IAEAK,EAAAL,GAAA,EAEA,IAAAD,KAAAF,EACAU,OAAAC,UAAAC,eAAAC,KAAAb,EAAAE,KACAY,EAAAZ,GAAAF,EAAAE,IAIA,IADAL,KAAAE,EAAAC,EAAAC,GACAK,EAAAC,QACAD,EAAAS,OAAAT,GAEA,GAAAL,EACA,IAAAI,EAAA,EAAYA,EAAAJ,EAAAM,OAA2BF,IACvCD,EAAAY,IAAAC,EAAAhB,EAAAI,IAGA,OAAAD,GAIA,IAAAc,KAGAV,GACAW,EAAA,GAIA,SAAAH,EAAAd,GAGA,GAAAgB,EAAAhB,GACA,OAAAgB,EAAAhB,GAAAkB,QAGA,IAAAC,EAAAH,EAAAhB,IACAG,EAAAH,EACAoB,GAAA,EACAF,YAUA,OANAN,EAAAZ,GAAAW,KAAAQ,EAAAD,QAAAC,IAAAD,QAAAJ,GAGAK,EAAAC,GAAA,EAGAD,EAAAD,QAKAJ,EAAAO,EAAAT,EAGAE,EAAAQ,EAAAN,EAGAF,EAAAS,EAAA,SAAAL,EAAAM,EAAAC,GACAX,EAAAY,EAAAR,EAAAM,IACAhB,OAAAmB,eAAAT,EAAAM,GACAI,cAAA,EACAC,YAAA,EACAC,IAAAL,KAMAX,EAAAiB,EAAA,SAAAZ,GACA,IAAAM,EAAAN,KAAAa,WACA,WAA2B,OAAAb,EAAA,SAC3B,WAAiC,OAAAA,GAEjC,OADAL,EAAAS,EAAAE,EAAA,IAAAA,GACAA,GAIAX,EAAAY,EAAA,SAAAO,EAAAC,GAAsD,OAAA1B,OAAAC,UAAAC,eAAAC,KAAAsB,EAAAC,IAGtDpB,EAAAqB,EAAA,GAGArB,EAAAsB,GAAA,SAAAC,GAA8D,MAApBC,QAAAC,MAAAF,GAAoBA","file":"static/js/manifest.js","sourcesContent":[" \t// install a JSONP callback for chunk loading\n \tvar parentJsonpFunction = window[\"webpackJsonp\"];\n \twindow[\"webpackJsonp\"] = function webpackJsonpCallback(chunkIds, moreModules, executeModules) {\n \t\t// add \"moreModules\" to the modules object,\n \t\t// then flag all \"chunkIds\" as loaded and fire callback\n \t\tvar moduleId, chunkId, i = 0, resolves = [], result;\n \t\tfor(;i < chunkIds.length; i++) {\n \t\t\tchunkId = chunkIds[i];\n \t\t\tif(installedChunks[chunkId]) {\n \t\t\t\tresolves.push(installedChunks[chunkId][0]);\n \t\t\t}\n \t\t\tinstalledChunks[chunkId] = 0;\n \t\t}\n \t\tfor(moduleId in moreModules) {\n \t\t\tif(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {\n \t\t\t\tmodules[moduleId] = moreModules[moduleId];\n \t\t\t}\n \t\t}\n \t\tif(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules, executeModules);\n \t\twhile(resolves.length) {\n \t\t\tresolves.shift()();\n \t\t}\n \t\tif(executeModules) {\n \t\t\tfor(i=0; i < executeModules.length; i++) {\n \t\t\t\tresult = __webpack_require__(__webpack_require__.s = executeModules[i]);\n \t\t\t}\n \t\t}\n \t\treturn result;\n \t};\n\n \t// The module cache\n \tvar installedModules = {};\n\n \t// objects to store loaded and loading chunks\n \tvar installedChunks = {\n \t\t2: 0\n \t};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// on error function for async loading\n \t__webpack_require__.oe = function(err) { console.error(err); throw err; };\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 5735c67e542cf68358f5"],"sourceRoot":""}
\ No newline at end of file
diff --git a/src/plugin_examples/newWebJugex/manifest.json b/src/plugin_examples/newWebJugex/manifest.json
new file mode 100644
index 000000000..afb5f7c49
--- /dev/null
+++ b/src/plugin_examples/newWebJugex/manifest.json
@@ -0,0 +1,6 @@
+{
+  "name" : "fzj.xg.webjugex",
+  "type" : "plugin",
+  "templateURL" : "http://localhost:10080/newWebJugex/template.html",
+  "scriptURL" : "http://localhost:10080/newWebJugex/script.js"
+}
\ No newline at end of file
diff --git a/src/plugin_examples/newWebJugex/script.js b/src/plugin_examples/newWebJugex/script.js
new file mode 100644
index 000000000..95046c5f1
--- /dev/null
+++ b/src/plugin_examples/newWebJugex/script.js
@@ -0,0 +1,228 @@
+(() => {
+
+  const backendRoot = `http://medpc055.ime.kfa-juelich.de:8005`
+  const srcRoot = 'http://localhost:10080/newWebJugex'
+
+  /* so that on shutdown, we could unload these libraries */
+  const onshutdownCB = []
+  const loadedExternalLibraries = []
+  const subscriptions = []
+
+  const loadExternalJsLibrary = (url) => new Promise((resolve,reject) => {
+    const el = document.createElement('script')
+    el.setAttribute('src',url)
+    el.onload = () => {
+      loadedExternalLibraries.push(el)
+      resolve()
+    }
+    el.onerror = () => reject()
+    document.head.appendChild(el)
+  })
+
+  const parseCoordToFile = (json) => {
+    return Object.keys(json).reduce((acc, curr) => {
+      const newRows = json[curr].map(item => {
+        return `${curr},${item.xyz.join(',')},${item.winsorzed_mean.join(',')}`
+      })
+      return acc.concat(newRows)
+    }, []).join('\n')
+  }
+
+  const parsePvalToFile = (json) => {
+    return Object.keys(json).map(key => `${key},${json[key]}`).join('\n')
+  }
+
+  const jugexResponseParser = (json) => {
+    const pval = json[1]
+    const coord = json[0]
+    const stringCoordFile = parseCoordToFile(coord)
+    const stringPvalFile = parsePvalToFile(pval)
+    const stringTitledCoordFile = Object.keys(pval).join(',').concat('\n').concat(stringCoordFile)
+    return {
+      pval : stringPvalFile,
+      coord : stringTitledCoordFile
+    }
+  }
+
+  interactiveViewer.pluginControl.loadExternalLibraries(['vue@2.5.16'])
+    .then(() => loadExternalJsLibrary(`${srcRoot}/manifest.js`))
+    .then(() => loadExternalJsLibrary(`${srcRoot}/vendor.js`))
+    .then(() => loadExternalJsLibrary(`${srcRoot}/app.js`))
+    .then(() => {
+
+      const controller = new Vue({
+        el: '#fzj\\.xg\\.newWebJugex\\.container',
+        props: {
+          regionNameToPMapURLMap: {
+            type: Map,
+            default: () => new Map()
+          }
+        },
+        data: {
+          allgenes: [],
+          chosengenes: [],
+          roi1: '',
+          roi2: '',
+          regions: [],
+          singleProbeMode:true,
+          simpleMode:true,
+          ignoreCustomProbe:false,
+          nPermutations:1000
+        },
+        methods: {
+          removeGene: function (gene) {
+            this.chosengenes = this.chosengenes.filter(g => g !== gene)
+          },
+          startAnalysis: function () {
+            const body = {
+              area1: {
+                name: this.roi1,
+                PMapURL: this.regionNameToPMapURLMap.get(this.roi1)
+              },
+              mode: false,
+              area2: {
+                name: this.roi2,
+                PMapURL: this.regionNameToPMapURLMap.get(this.roi2)
+              },
+              hemisphere: 'left',
+              selectedGenes: this.chosengenes,
+              threshold: '0.2'
+            }
+
+            this.$emit('start-analysis', Object.assign({}, body))
+          }
+        },
+        computed: {
+          placeholderTextRoi1: function () {
+            return this.roi1 === '' ? 'Start typing to search ...': this.roi1
+          },
+          placeholderTextRoi2: function () {
+            return this.roi2 === '' ? 'Start typing to search ...': this.roi2
+          },
+          getAllgenes: function () {
+            return this.allgenes
+          }
+        },
+        mounted: function () {
+          fetch(backendRoot)
+            .then(res => res.json())
+            .then(array => this.allgenes = array)
+            .catch(console.warn)
+        }
+      })
+
+      interactiveViewer.metadata.datasetsBSubject.subscribe(array => 
+        controller.regionNameToPMapURLMap = new Map(array
+          .filter(item => item.type === 'Cytoarchitectonic Probabilistic Map'
+            && typeof item.regionName !== 'undefined' 
+            && item.regionName.constructor === Array 
+            && item.regionName.length > 0
+            && typeof item.files !== 'undefined'
+            && item.files.constructor === Array
+            && item.files.length > 0
+            && typeof item.files[0].url !== 'undefined')
+          .map(item => [item.regionName[0].regionName, item.files[0].url])))
+
+      controller.regions = Array.from(interactiveViewer.metadata.regionsLabelIndexMap.values())
+        .map(item=>item.name)
+
+      const normaliseToTwoDigit = (input) => `${input.toString().length > 1 ? '' : '0'}${input.toString()}`
+
+      Vue.component('fzj-xg-newwebjugex-analysis-card',{
+        template: `
+        <div class = "panel panel-default">
+          <div 
+            @click = "showbody = !showbody"
+            class = "panel-header btn btn-default btn-block">
+            <span 
+              v-if = "status">
+              Analysis complete. {{ dateString }}
+            </span>
+            <div
+              v-if = "!status">
+              <div class = "fzj.xg.newWebJugex.spinner">&bull;</div>
+              <div>Analysing</div>
+            </div>
+            <span
+              @click.stop = "$emit('remove-card')" 
+              class = "pull-right close">
+                &times;
+            </span>
+          </div>
+          <div 
+            v-if = "showbody"
+            class = "panel-body">
+            <div v-if = "error">
+              {{ error }}
+            </div>
+            <div v-else-if = "pvaldata && coorddata">
+            <a download = "pval.csv" :href = "'data:text/csv;charset=utf-8,' + pvaldata">download pvals</a><br />
+            <a download = "coord.csv" :href = "'data:text/csv;charset=utf-8,' + coorddata">download coord data</a>
+            </div>
+            <div v-else>
+              We are still working on on analysing your data ...
+            </div>
+          </div>
+        </div>
+        `,
+        props: {
+          querydata: {
+            type: Object,
+            default: () => ({})
+          }
+        },
+        data: () => ({
+          status: false,
+          showbody: false,
+          datenow : new Date(),
+          error : null,
+          pvaldata : null,
+          coorddata : null
+        }),
+        computed: {
+          dateString: function () {
+            return `${this.datenow.getFullYear().toString()}${normaliseToTwoDigit(this.datenow.getMonth() + 1)}${normaliseToTwoDigit(this.datenow.getDate())}_${normaliseToTwoDigit(this.datenow.getHours())}${normaliseToTwoDigit(this.datenow.getMinutes())}`
+          }
+        },
+        mounted: function () {
+          fetch(`${backendRoot}/jugex`,{
+            method: 'POST',
+            headers: {
+              'Content-Type': 'application/json'
+            },
+            body: JSON.stringify(this.querydata)
+          })
+            .then(res=>res.json())
+            .then(json => {
+              this.status = true
+              const rjson = jugexResponseParser(json)
+              this.pvaldata = rjson.pval
+              this.coorddata = rjson.coord
+            })
+            .catch(e => {
+              this.status = true
+              this.error = JSON.stringify(e)
+            })
+        }
+      })
+
+      const result = new Vue({
+        el: '#fzj\\.xg\\.newWebJugex\\.result',
+        data: {
+          analyses: []
+        },
+        methods: {
+          addAnalysis: function (json) {
+            this.analyses.push(json)
+          },
+          removeAnalysis: function (index) {
+            this.analyses.splice(index, 1)
+          }
+        }
+      })
+
+      controller.$on('start-analysis', (data) => {
+        result.addAnalysis(data)
+      })
+    })
+})()
\ No newline at end of file
diff --git a/src/plugin_examples/newWebJugex/template.html b/src/plugin_examples/newWebJugex/template.html
new file mode 100644
index 000000000..f820797a2
--- /dev/null
+++ b/src/plugin_examples/newWebJugex/template.html
@@ -0,0 +1,248 @@
+<div v-cloak id = "fzj.xg.newWebJugex.container">
+  <vue-readmore
+    :collapsed-height = "40">
+    <template slot = "readmoreContent">
+      <small id = "fzj.xg.newWebJugex.desc">
+          Find a set of differentially expressed genes between two user defined volumes of interest based on JuBrain maps. <br />
+          The tool downloads expression values of user specified sets of genes from Allen Brain API.<br />
+          Then, it uses zscores to find which genes are expressed differentially between the user specified regions of interests.<br />
+          After the analysis is finished, the genes and their calculated p values are displayed. There is also an option of downloading the gene names and their p values<br />
+          and the roi coordinates used in the analysis.
+          Please select two regions of interest, and at least one gene :
+      </small>
+    </template>
+    <template slot = "resizeSliverContentCollapsed">
+      <div class = "text-center">
+        <i class = "glyphicon glyphicon-chevron-down"></i>
+      </div>
+    </template>
+    <template slot = "resizeSliverContentShown">
+      <div class = "text-center">
+        <i class = "glyphicon glyphicon-chevron-up"></i>
+      </div>
+    </template>
+  </vue-readmore>
+
+  <div class="fzj.xg.newWebJugex.spacer"></div>
+
+  <div class="btn-group">
+    <div
+      @click = "simpleMode = true"
+      :class = "{'btn-active': simpleMode === true}"
+      class = "btn btn-default">
+      Simple
+    </div>
+    <div
+      @click = "simpleMode = false"
+      :class = "{'btn-active': simpleMode === false}"
+      class = "btn btn-default">
+      Advanced
+    </div>
+  </div>
+
+  <div class="fzj.xg.newWebJugex.spacer"></div>
+
+  <div style = "z-index:5" class="input-group">
+    <div class="input-group-addon">
+      ROI1:
+    </div>
+    <vue-autocomplete
+      ref = "roi1"
+      @selectslice = "roi1 = $event"
+      class = "form-control fzj.xg.newWebJugex.vueAutocompleteFormControl"
+      :rawarray = "regions"
+      :placeholder = "placeholderTextRoi1">
+  
+    </vue-autocomplete>
+  </div>
+  <div style = "z-index:4" class="input-group">
+    <div class="input-group-addon">
+      ROI2:
+    </div>
+    <vue-autocomplete
+      ref = "roi2"
+      @selectslice = "roi2 = $event"
+      class = "form-control fzj.xg.newWebJugex.vueAutocompleteFormControl"
+      :rawarray = "regions"
+      :placeholder = "placeholderTextRoi2">
+  
+    </vue-autocomplete>
+  </div>
+
+  <div class="fzj.xg.newWebJugex.spacer"></div>
+
+  <div style = "z-index:3" class = "input-group">
+    <vue-autocomplete
+      ref = "genelist"
+      @selectslice = "chosengenes.push( $event );$refs.genelist.$refs.input.focus()"
+      class = "form-control fzj.xg.newWebJugex.vueAutocompleteFormControl"
+      :rawarray = "getAllgenes"
+      :placeholder = "'Search for genes of interest ...'">
+  
+    </vue-autocomplete>
+    
+    <div class = "input-group-btn">
+      <div webjugex-tooltip = "accepts a comma delimited utf-8 encoded file" class = "btn btn-default fzj.xg.newWebJugex.geneBtns">
+        Import
+      </div>
+    </div>
+    <div class = "input-group-btn">
+      <div webjugex-tooltip = "saves the gene list as a comma delimited, utf8 encoded csv file" class = "btn btn-default fzj.xg.newWebJugex.geneBtns">
+        Export
+      </div>
+    </div>
+
+  </div>
+
+  <vue-pill 
+    class = "fzj.xg.newWebJugex.pill"
+    @remove-pill = "removeGene(item)" 
+    v-for = "(item,index) in chosengenes" 
+    :key = "index" 
+    :name = "item">
+  </vue-pill>
+
+  <div class="fzj.xg.newWebJugex.spacer"></div>
+
+  <div 
+    @click = "singleProbeMode = !singleProbeMode"
+    class = "btn btn-default"
+    :class = "{'btn-active': singleProbeMode === true}">
+    <small>
+      Single Probe Mode
+    </small>
+  </div>
+
+  <div 
+    @click = "ignoreCustomProbe = !ignoreCustomProbe"
+    class = "btn btn-default"
+    :class = "{'btn-active': ignoreCustomProbe === true}">
+    <small>
+      Ignore Custom Probe
+    </small>
+  </div>
+
+  <div class="fzj.xg.newWebJugex.spacer"></div>
+
+  <div 
+    @click = "startAnalysis"
+    class="btn btn-default btn-block">
+    Start Differential Analysis
+  </div>
+
+</div>
+<div v-cloak id = "fzj.xg.newWebJugex.result">
+  <fzj-xg-newwebjugex-analysis-card
+    class = "fzj.xg.newWebJugex.analysisCard.container"
+    @remove-card = "removeAnalysis(index)"
+    :querydata = "item"
+    :key = "index"
+    v-for = "(item, index) in analyses">
+
+  </fzj-xg-newwebjugex-analysis-card>
+</div>
+<div class = "fzj.xg.newWebJugex.padding"></div>
+<style>
+[v-cloak]
+{
+  display:none;
+}
+#fzj\.xg\.newWebJugex\.container
+{
+  padding: 0.5em;
+}
+#fzj\.xg\.newWebJugex\.desc
+{
+  display:block;
+}
+.fzj\.xg\.newWebJugex\.autocomplete
+{
+  border : 1px rgba(0,0,0,0.1) solid;
+  width:10em;
+  padding:1em;
+  box-sizing: border-box;
+  position:absolute;
+}
+
+.fzj\.xg\.newWebJugex\.autocomplete input
+{
+  width:100%;
+}
+
+.fzj\.xg\.newWebJugex\.vueAutocompleteFormControl
+{
+  padding:0;
+}
+.fzj\.xg\.newWebJugex\.padding
+{
+  height:10em;
+}
+
+.fzj\.xg\.newWebJugex\.spacer
+{
+  height: 0.5em;
+}
+
+.fzj\.xg\.newWebJugex\.geneBtns
+{
+  height:34px;
+}
+
+#fzj\.xg\.newWebJugex\.container [webjugex-tooltip]
+{
+  position: relative;
+}
+
+#fzj\.xg\.newWebJugex\.container [webjugex-tooltip]:after
+{
+  content: attr(webjugex-tooltip);
+  position: absolute;
+  top: 3em;
+  right: 0;
+  color:white;
+  background-color:rgba(0,0,0,0.7);
+  width: 10em;
+  white-space: normal;
+  display: inline-block;
+  padding: 0.2em;
+  pointer-events: none;
+  transition: all 0.2s;
+  opacity: 0;
+}
+
+#fzj\.xg\.newWebJugex\.container [webjugex-tooltip]:hover:after
+{
+  opacity: 1;
+}
+
+#fzj\.xg\.newWebJugex\.container .btn-active
+{
+  color:rgba(255, 255, 255, 1.0);
+  text-shadow: 1px 0 0 rgba(0, 255, 0, 0.15),
+    -1px 0 0 rgba(0, 255, 0, 0.15),
+    0 1px 0 rgba(0, 255, 0, 0.15),
+    0 -1px 0 rgba(0, 255, 0, 0.15);
+}
+
+#fzj\.xg\.newWebJugex\.result
+{
+  padding: 0.5em;
+}
+
+#fzj\.xg\.newWebJugex\.result .fzj\.xg\.newWebJugex\.spinner
+{
+  animation: slidein 0.7s ease-in-out 0s infinite both;
+}
+
+@keyframes slidein {
+  0% { transform: translateX(0px); }
+  50% { transform: translateX(10px); }
+  100%   { transform: translateX(0px); }
+}
+
+
+.fzj\.xg\.newWebJugex\.analysisCard\.container
+{
+  margin-bottom: 0;
+}
+</style>
\ No newline at end of file
diff --git a/src/plugin_examples/newWebJugex/vendor.js b/src/plugin_examples/newWebJugex/vendor.js
new file mode 100644
index 000000000..5fb83edbb
--- /dev/null
+++ b/src/plugin_examples/newWebJugex/vendor.js
@@ -0,0 +1,2 @@
+webpackJsonp([1],{"FZ+f":function(e,t){e.exports=function(e){var t=[];return t.toString=function(){return this.map(function(t){var n=function(e,t){var n=e[1]||"",r=e[3];if(!r)return n;if(t&&"function"==typeof btoa){var o=(i=r,"/*# sourceMappingURL=data:application/json;charset=utf-8;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(i))))+" */"),s=r.sources.map(function(e){return"/*# sourceURL="+r.sourceRoot+e+" */"});return[n].concat(s).concat([o]).join("\n")}var i;return[n].join("\n")}(t,e);return t[2]?"@media "+t[2]+"{"+n+"}":n}).join("")},t.i=function(e,n){"string"==typeof e&&(e=[[null,e,""]]);for(var r={},o=0;o<this.length;o++){var s=this[o][0];"number"==typeof s&&(r[s]=!0)}for(o=0;o<e.length;o++){var i=e[o];"number"==typeof i[0]&&r[i[0]]||(n&&!i[2]?i[2]=n:n&&(i[2]="("+i[2]+") and ("+n+")"),t.push(i))}},t}},"VU/8":function(e,t){e.exports=function(e,t,n,r,o,s){var i,a=e=e||{},u=typeof e.default;"object"!==u&&"function"!==u||(i=e,a=e.default);var c,d="function"==typeof a?a.options:a;if(t&&(d.render=t.render,d.staticRenderFns=t.staticRenderFns,d._compiled=!0),n&&(d.functional=!0),o&&(d._scopeId=o),s?(c=function(e){(e=e||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext)||"undefined"==typeof __VUE_SSR_CONTEXT__||(e=__VUE_SSR_CONTEXT__),r&&r.call(this,e),e&&e._registeredComponents&&e._registeredComponents.add(s)},d._ssrRegister=c):r&&(c=r),c){var f=d.functional,p=f?d.render:d.beforeCreate;f?(d._injectStyles=c,d.render=function(e,t){return c.call(t),p(e,t)}):d.beforeCreate=p?[].concat(p,c):[c]}return{esModule:i,exports:a,options:d}}},rjj0:function(e,t,n){var r="undefined"!=typeof document;if("undefined"!=typeof DEBUG&&DEBUG&&!r)throw new Error("vue-style-loader cannot be used in a non-browser environment. Use { target: 'node' } in your Webpack config to indicate a server-rendering environment.");var o=n("tTVk"),s={},i=r&&(document.head||document.getElementsByTagName("head")[0]),a=null,u=0,c=!1,d=function(){},f=null,p="data-vue-ssr-id",l="undefined"!=typeof navigator&&/msie [6-9]\b/.test(navigator.userAgent.toLowerCase());function h(e){for(var t=0;t<e.length;t++){var n=e[t],r=s[n.id];if(r){r.refs++;for(var o=0;o<r.parts.length;o++)r.parts[o](n.parts[o]);for(;o<n.parts.length;o++)r.parts.push(g(n.parts[o]));r.parts.length>n.parts.length&&(r.parts.length=n.parts.length)}else{var i=[];for(o=0;o<n.parts.length;o++)i.push(g(n.parts[o]));s[n.id]={id:n.id,refs:1,parts:i}}}}function v(){var e=document.createElement("style");return e.type="text/css",i.appendChild(e),e}function g(e){var t,n,r=document.querySelector("style["+p+'~="'+e.id+'"]');if(r){if(c)return d;r.parentNode.removeChild(r)}if(l){var o=u++;r=a||(a=v()),t=b.bind(null,r,o,!1),n=b.bind(null,r,o,!0)}else r=v(),t=function(e,t){var n=t.css,r=t.media,o=t.sourceMap;r&&e.setAttribute("media",r);f.ssrId&&e.setAttribute(p,t.id);o&&(n+="\n/*# sourceURL="+o.sources[0]+" */",n+="\n/*# sourceMappingURL=data:application/json;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(o))))+" */");if(e.styleSheet)e.styleSheet.cssText=n;else{for(;e.firstChild;)e.removeChild(e.firstChild);e.appendChild(document.createTextNode(n))}}.bind(null,r),n=function(){r.parentNode.removeChild(r)};return t(e),function(r){if(r){if(r.css===e.css&&r.media===e.media&&r.sourceMap===e.sourceMap)return;t(e=r)}else n()}}e.exports=function(e,t,n,r){c=n,f=r||{};var i=o(e,t);return h(i),function(t){for(var n=[],r=0;r<i.length;r++){var a=i[r];(u=s[a.id]).refs--,n.push(u)}t?h(i=o(e,t)):i=[];for(r=0;r<n.length;r++){var u;if(0===(u=n[r]).refs){for(var c=0;c<u.parts.length;c++)u.parts[c]();delete s[u.id]}}}};var m,y=(m=[],function(e,t){return m[e]=t,m.filter(Boolean).join("\n")});function b(e,t,n,r){var o=n?"":r.css;if(e.styleSheet)e.styleSheet.cssText=y(t,o);else{var s=document.createTextNode(o),i=e.childNodes;i[t]&&e.removeChild(i[t]),i.length?e.insertBefore(s,i[t]):e.appendChild(s)}}},tTVk:function(e,t){e.exports=function(e,t){for(var n=[],r={},o=0;o<t.length;o++){var s=t[o],i=s[0],a={id:e+":"+o,css:s[1],media:s[2],sourceMap:s[3]};r[i]?r[i].parts.push(a):n.push(r[i]={id:i,parts:[a]})}return n}}});
+//# sourceMappingURL=vendor.js.map
\ No newline at end of file
diff --git a/src/plugin_examples/newWebJugex/vendor.js.map b/src/plugin_examples/newWebJugex/vendor.js.map
new file mode 100644
index 000000000..a131d0fce
--- /dev/null
+++ b/src/plugin_examples/newWebJugex/vendor.js.map
@@ -0,0 +1 @@
+{"version":3,"sources":["webpack:///./node_modules/css-loader/lib/css-base.js","webpack:///./node_modules/vue-loader/lib/component-normalizer.js","webpack:///./node_modules/vue-style-loader/lib/addStylesClient.js","webpack:///./node_modules/vue-style-loader/lib/listToStyles.js"],"names":["module","exports","useSourceMap","list","toString","this","map","item","content","cssMapping","btoa","sourceMapping","sourceMap","unescape","encodeURIComponent","JSON","stringify","sourceURLs","sources","source","sourceRoot","concat","join","cssWithMappingToString","i","modules","mediaQuery","alreadyImportedModules","length","id","push","rawScriptExports","compiledTemplate","functionalTemplate","injectStyles","scopeId","moduleIdentifier","esModule","scriptExports","type","default","hook","options","render","staticRenderFns","_compiled","functional","_scopeId","context","$vnode","ssrContext","parent","__VUE_SSR_CONTEXT__","call","_registeredComponents","add","_ssrRegister","existing","beforeCreate","_injectStyles","h","hasDocument","document","DEBUG","Error","listToStyles","__webpack_require__","stylesInDom","head","getElementsByTagName","singletonElement","singletonCounter","isProduction","noop","ssrIdKey","isOldIE","navigator","test","userAgent","toLowerCase","addStylesToDom","styles","domStyle","refs","j","parts","addStyle","createStyleElement","styleElement","createElement","appendChild","obj","update","remove","querySelector","parentNode","removeChild","styleIndex","applyToSingletonTag","bind","css","media","setAttribute","ssrId","styleSheet","cssText","firstChild","createTextNode","newObj","parentId","_isProduction","_options","newList","mayRemove","textStore","replaceText","index","replacement","filter","Boolean","cssNode","childNodes","insertBefore","newStyles","part"],"mappings":"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","file":"static/js/vendor.js","sourcesContent":["/*\n\tMIT License http://www.opensource.org/licenses/mit-license.php\n\tAuthor Tobias Koppers @sokra\n*/\n// css base code, injected by the css-loader\nmodule.exports = function(useSourceMap) {\n\tvar list = [];\n\n\t// return the list of modules as css string\n\tlist.toString = function toString() {\n\t\treturn this.map(function (item) {\n\t\t\tvar content = cssWithMappingToString(item, useSourceMap);\n\t\t\tif(item[2]) {\n\t\t\t\treturn \"@media \" + item[2] + \"{\" + content + \"}\";\n\t\t\t} else {\n\t\t\t\treturn content;\n\t\t\t}\n\t\t}).join(\"\");\n\t};\n\n\t// import a list of modules into the list\n\tlist.i = function(modules, mediaQuery) {\n\t\tif(typeof modules === \"string\")\n\t\t\tmodules = [[null, modules, \"\"]];\n\t\tvar alreadyImportedModules = {};\n\t\tfor(var i = 0; i < this.length; i++) {\n\t\t\tvar id = this[i][0];\n\t\t\tif(typeof id === \"number\")\n\t\t\t\talreadyImportedModules[id] = true;\n\t\t}\n\t\tfor(i = 0; i < modules.length; i++) {\n\t\t\tvar item = modules[i];\n\t\t\t// skip already imported module\n\t\t\t// this implementation is not 100% perfect for weird media query combinations\n\t\t\t//  when a module is imported multiple times with different media queries.\n\t\t\t//  I hope this will never occur (Hey this way we have smaller bundles)\n\t\t\tif(typeof item[0] !== \"number\" || !alreadyImportedModules[item[0]]) {\n\t\t\t\tif(mediaQuery && !item[2]) {\n\t\t\t\t\titem[2] = mediaQuery;\n\t\t\t\t} else if(mediaQuery) {\n\t\t\t\t\titem[2] = \"(\" + item[2] + \") and (\" + mediaQuery + \")\";\n\t\t\t\t}\n\t\t\t\tlist.push(item);\n\t\t\t}\n\t\t}\n\t};\n\treturn list;\n};\n\nfunction cssWithMappingToString(item, useSourceMap) {\n\tvar content = item[1] || '';\n\tvar cssMapping = item[3];\n\tif (!cssMapping) {\n\t\treturn content;\n\t}\n\n\tif (useSourceMap && typeof btoa === 'function') {\n\t\tvar sourceMapping = toComment(cssMapping);\n\t\tvar sourceURLs = cssMapping.sources.map(function (source) {\n\t\t\treturn '/*# sourceURL=' + cssMapping.sourceRoot + source + ' */'\n\t\t});\n\n\t\treturn [content].concat(sourceURLs).concat([sourceMapping]).join('\\n');\n\t}\n\n\treturn [content].join('\\n');\n}\n\n// Adapted from convert-source-map (MIT)\nfunction toComment(sourceMap) {\n\t// eslint-disable-next-line no-undef\n\tvar base64 = btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap))));\n\tvar data = 'sourceMappingURL=data:application/json;charset=utf-8;base64,' + base64;\n\n\treturn '/*# ' + data + ' */';\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/css-loader/lib/css-base.js\n// module id = FZ+f\n// module chunks = 1","/* globals __VUE_SSR_CONTEXT__ */\n\n// IMPORTANT: Do NOT use ES2015 features in this file.\n// This module is a runtime utility for cleaner component module output and will\n// be included in the final webpack user bundle.\n\nmodule.exports = function normalizeComponent (\n  rawScriptExports,\n  compiledTemplate,\n  functionalTemplate,\n  injectStyles,\n  scopeId,\n  moduleIdentifier /* server only */\n) {\n  var esModule\n  var scriptExports = rawScriptExports = rawScriptExports || {}\n\n  // ES6 modules interop\n  var type = typeof rawScriptExports.default\n  if (type === 'object' || type === 'function') {\n    esModule = rawScriptExports\n    scriptExports = rawScriptExports.default\n  }\n\n  // Vue.extend constructor export interop\n  var options = typeof scriptExports === 'function'\n    ? scriptExports.options\n    : scriptExports\n\n  // render functions\n  if (compiledTemplate) {\n    options.render = compiledTemplate.render\n    options.staticRenderFns = compiledTemplate.staticRenderFns\n    options._compiled = true\n  }\n\n  // functional template\n  if (functionalTemplate) {\n    options.functional = true\n  }\n\n  // scopedId\n  if (scopeId) {\n    options._scopeId = scopeId\n  }\n\n  var hook\n  if (moduleIdentifier) { // server build\n    hook = function (context) {\n      // 2.3 injection\n      context =\n        context || // cached call\n        (this.$vnode && this.$vnode.ssrContext) || // stateful\n        (this.parent && this.parent.$vnode && this.parent.$vnode.ssrContext) // functional\n      // 2.2 with runInNewContext: true\n      if (!context && typeof __VUE_SSR_CONTEXT__ !== 'undefined') {\n        context = __VUE_SSR_CONTEXT__\n      }\n      // inject component styles\n      if (injectStyles) {\n        injectStyles.call(this, context)\n      }\n      // register component module identifier for async chunk inferrence\n      if (context && context._registeredComponents) {\n        context._registeredComponents.add(moduleIdentifier)\n      }\n    }\n    // used by ssr in case component is cached and beforeCreate\n    // never gets called\n    options._ssrRegister = hook\n  } else if (injectStyles) {\n    hook = injectStyles\n  }\n\n  if (hook) {\n    var functional = options.functional\n    var existing = functional\n      ? options.render\n      : options.beforeCreate\n\n    if (!functional) {\n      // inject component registration as beforeCreate hook\n      options.beforeCreate = existing\n        ? [].concat(existing, hook)\n        : [hook]\n    } else {\n      // for template-only hot-reload because in that case the render fn doesn't\n      // go through the normalizer\n      options._injectStyles = hook\n      // register for functioal component in vue file\n      options.render = function renderWithStyleInjection (h, context) {\n        hook.call(context)\n        return existing(h, context)\n      }\n    }\n  }\n\n  return {\n    esModule: esModule,\n    exports: scriptExports,\n    options: options\n  }\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/vue-loader/lib/component-normalizer.js\n// module id = VU/8\n// module chunks = 1","/*\n  MIT License http://www.opensource.org/licenses/mit-license.php\n  Author Tobias Koppers @sokra\n  Modified by Evan You @yyx990803\n*/\n\nvar hasDocument = typeof document !== 'undefined'\n\nif (typeof DEBUG !== 'undefined' && DEBUG) {\n  if (!hasDocument) {\n    throw new Error(\n    'vue-style-loader cannot be used in a non-browser environment. ' +\n    \"Use { target: 'node' } in your Webpack config to indicate a server-rendering environment.\"\n  ) }\n}\n\nvar listToStyles = require('./listToStyles')\n\n/*\ntype StyleObject = {\n  id: number;\n  parts: Array<StyleObjectPart>\n}\n\ntype StyleObjectPart = {\n  css: string;\n  media: string;\n  sourceMap: ?string\n}\n*/\n\nvar stylesInDom = {/*\n  [id: number]: {\n    id: number,\n    refs: number,\n    parts: Array<(obj?: StyleObjectPart) => void>\n  }\n*/}\n\nvar head = hasDocument && (document.head || document.getElementsByTagName('head')[0])\nvar singletonElement = null\nvar singletonCounter = 0\nvar isProduction = false\nvar noop = function () {}\nvar options = null\nvar ssrIdKey = 'data-vue-ssr-id'\n\n// Force single-tag solution on IE6-9, which has a hard limit on the # of <style>\n// tags it will allow on a page\nvar isOldIE = typeof navigator !== 'undefined' && /msie [6-9]\\b/.test(navigator.userAgent.toLowerCase())\n\nmodule.exports = function (parentId, list, _isProduction, _options) {\n  isProduction = _isProduction\n\n  options = _options || {}\n\n  var styles = listToStyles(parentId, list)\n  addStylesToDom(styles)\n\n  return function update (newList) {\n    var mayRemove = []\n    for (var i = 0; i < styles.length; i++) {\n      var item = styles[i]\n      var domStyle = stylesInDom[item.id]\n      domStyle.refs--\n      mayRemove.push(domStyle)\n    }\n    if (newList) {\n      styles = listToStyles(parentId, newList)\n      addStylesToDom(styles)\n    } else {\n      styles = []\n    }\n    for (var i = 0; i < mayRemove.length; i++) {\n      var domStyle = mayRemove[i]\n      if (domStyle.refs === 0) {\n        for (var j = 0; j < domStyle.parts.length; j++) {\n          domStyle.parts[j]()\n        }\n        delete stylesInDom[domStyle.id]\n      }\n    }\n  }\n}\n\nfunction addStylesToDom (styles /* Array<StyleObject> */) {\n  for (var i = 0; i < styles.length; i++) {\n    var item = styles[i]\n    var domStyle = stylesInDom[item.id]\n    if (domStyle) {\n      domStyle.refs++\n      for (var j = 0; j < domStyle.parts.length; j++) {\n        domStyle.parts[j](item.parts[j])\n      }\n      for (; j < item.parts.length; j++) {\n        domStyle.parts.push(addStyle(item.parts[j]))\n      }\n      if (domStyle.parts.length > item.parts.length) {\n        domStyle.parts.length = item.parts.length\n      }\n    } else {\n      var parts = []\n      for (var j = 0; j < item.parts.length; j++) {\n        parts.push(addStyle(item.parts[j]))\n      }\n      stylesInDom[item.id] = { id: item.id, refs: 1, parts: parts }\n    }\n  }\n}\n\nfunction createStyleElement () {\n  var styleElement = document.createElement('style')\n  styleElement.type = 'text/css'\n  head.appendChild(styleElement)\n  return styleElement\n}\n\nfunction addStyle (obj /* StyleObjectPart */) {\n  var update, remove\n  var styleElement = document.querySelector('style[' + ssrIdKey + '~=\"' + obj.id + '\"]')\n\n  if (styleElement) {\n    if (isProduction) {\n      // has SSR styles and in production mode.\n      // simply do nothing.\n      return noop\n    } else {\n      // has SSR styles but in dev mode.\n      // for some reason Chrome can't handle source map in server-rendered\n      // style tags - source maps in <style> only works if the style tag is\n      // created and inserted dynamically. So we remove the server rendered\n      // styles and inject new ones.\n      styleElement.parentNode.removeChild(styleElement)\n    }\n  }\n\n  if (isOldIE) {\n    // use singleton mode for IE9.\n    var styleIndex = singletonCounter++\n    styleElement = singletonElement || (singletonElement = createStyleElement())\n    update = applyToSingletonTag.bind(null, styleElement, styleIndex, false)\n    remove = applyToSingletonTag.bind(null, styleElement, styleIndex, true)\n  } else {\n    // use multi-style-tag mode in all other cases\n    styleElement = createStyleElement()\n    update = applyToTag.bind(null, styleElement)\n    remove = function () {\n      styleElement.parentNode.removeChild(styleElement)\n    }\n  }\n\n  update(obj)\n\n  return function updateStyle (newObj /* StyleObjectPart */) {\n    if (newObj) {\n      if (newObj.css === obj.css &&\n          newObj.media === obj.media &&\n          newObj.sourceMap === obj.sourceMap) {\n        return\n      }\n      update(obj = newObj)\n    } else {\n      remove()\n    }\n  }\n}\n\nvar replaceText = (function () {\n  var textStore = []\n\n  return function (index, replacement) {\n    textStore[index] = replacement\n    return textStore.filter(Boolean).join('\\n')\n  }\n})()\n\nfunction applyToSingletonTag (styleElement, index, remove, obj) {\n  var css = remove ? '' : obj.css\n\n  if (styleElement.styleSheet) {\n    styleElement.styleSheet.cssText = replaceText(index, css)\n  } else {\n    var cssNode = document.createTextNode(css)\n    var childNodes = styleElement.childNodes\n    if (childNodes[index]) styleElement.removeChild(childNodes[index])\n    if (childNodes.length) {\n      styleElement.insertBefore(cssNode, childNodes[index])\n    } else {\n      styleElement.appendChild(cssNode)\n    }\n  }\n}\n\nfunction applyToTag (styleElement, obj) {\n  var css = obj.css\n  var media = obj.media\n  var sourceMap = obj.sourceMap\n\n  if (media) {\n    styleElement.setAttribute('media', media)\n  }\n  if (options.ssrId) {\n    styleElement.setAttribute(ssrIdKey, obj.id)\n  }\n\n  if (sourceMap) {\n    // https://developer.chrome.com/devtools/docs/javascript-debugging\n    // this makes source maps inside style tags work properly in Chrome\n    css += '\\n/*# sourceURL=' + sourceMap.sources[0] + ' */'\n    // http://stackoverflow.com/a/26603875\n    css += '\\n/*# sourceMappingURL=data:application/json;base64,' + btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))) + ' */'\n  }\n\n  if (styleElement.styleSheet) {\n    styleElement.styleSheet.cssText = css\n  } else {\n    while (styleElement.firstChild) {\n      styleElement.removeChild(styleElement.firstChild)\n    }\n    styleElement.appendChild(document.createTextNode(css))\n  }\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/vue-style-loader/lib/addStylesClient.js\n// module id = rjj0\n// module chunks = 1","/**\n * Translates the list format produced by css-loader into something\n * easier to manipulate.\n */\nmodule.exports = function listToStyles (parentId, list) {\n  var styles = []\n  var newStyles = {}\n  for (var i = 0; i < list.length; i++) {\n    var item = list[i]\n    var id = item[0]\n    var css = item[1]\n    var media = item[2]\n    var sourceMap = item[3]\n    var part = {\n      id: parentId + ':' + i,\n      css: css,\n      media: media,\n      sourceMap: sourceMap\n    }\n    if (!newStyles[id]) {\n      styles.push(newStyles[id] = { id: id, parts: [part] })\n    } else {\n      newStyles[id].parts.push(part)\n    }\n  }\n  return styles\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/vue-style-loader/lib/listToStyles.js\n// module id = tTVk\n// module chunks = 1"],"sourceRoot":""}
\ No newline at end of file
diff --git a/src/plugin_examples/plugin_api.md b/src/plugin_examples/plugin_api.md
index 1ea94a644..bbf95aeca 100644
--- a/src/plugin_examples/plugin_api.md
+++ b/src/plugin_examples/plugin_api.md
@@ -124,7 +124,7 @@ window.interactiveViewer
   - *loadExternalLibraries([LIBRARY_NAME_1,LIBRARY_NAME_2])* Function that loads external libraries. Pass the name of the libraries as an Array of string, and returns a Promise. When promise resolves, the libraries are loaded. **n.b.** while unlikely, there is a possibility that multiple requests to load external libraries in quick succession can cause the promise to resolve before the library is actually loaded. 
 
   ```js
-  const currentlySupportedLibraries = ['jquery2','jquery3','webcomponentsLite','react16','reactdom16']
+  const currentlySupportedLibraries = ['jquery@2','jquery@3','webcomponentsLite@1.1.0','react@16','reactdom@16','vue@2.5.16']
 
   window.interactivewViewer.loadExternalLibraries(currentlySupportedLibraries)
     .then(()=>{
diff --git a/src/res/css/plugin_styles.css b/src/res/css/plugin_styles.css
index 3fbdf3457..e2c75f3ba 100644
--- a/src/res/css/plugin_styles.css
+++ b/src/res/css/plugin_styles.css
@@ -23,6 +23,12 @@
   box-shadow : rgba(5, 5, 5, 0.25) 0px 4px 6px 0px;
 }
 
+[plugincontainer] .form-control
+{
+  background:none;
+  border:none;
+}
+
 /* colour */
 [darktheme="true"] [plugincontainer] .btn,
 [darktheme="true"] [plugincontainer] .input-group-addon,
@@ -30,6 +36,18 @@
 [darktheme="true"] [plugincontainer] .panel
 {
   background-color:rgba(80,80,80,0.8);
-  color:white;
+  color:rgba(255,255,255,0.8);
 }
 
+[darktheme="true"] [plugincontainer] hr
+{
+  border-color:rgba(100,100,100,0.5);
+}
+
+[darktheme="true"] [plugincontainer] .btn.btn-active
+{
+  background-color:rgba(65,65,65,0.8);
+  transform: translateY(2px);
+  color:rgba(255,255,255,1.0);
+  box-shadow: inset 0 2px 2px -2px rgba(0,0,0,0.2);
+}
\ No newline at end of file
diff --git a/src/ui/nehubaContainer/nehubaContainer.component.ts b/src/ui/nehubaContainer/nehubaContainer.component.ts
index cc6ca1b4e..df92d5321 100644
--- a/src/ui/nehubaContainer/nehubaContainer.component.ts
+++ b/src/ui/nehubaContainer/nehubaContainer.component.ts
@@ -4,7 +4,6 @@ import { Store, select } from "@ngrx/store";
 import { ViewerStateInterface, safeFilter, SELECT_REGIONS, getLabelIndexMap, DataEntry, CHANGE_NAVIGATION, isDefined, MOUSE_OVER_SEGMENT } from "../../services/stateStore.service";
 import { Observable, Subscription, fromEvent, combineLatest, merge } from "rxjs";
 import { filter,map, take, scan, debounceTime, distinctUntilChanged, switchMap } from "rxjs/operators";
-import * as export_nehuba from 'export_nehuba'
 import { AtlasViewerAPIServices } from "../../atlasViewer/atlasViewer.apiService.service";
 import { timedValues } from "../../util/generator";
 
@@ -142,12 +141,10 @@ export class NehubaContainer implements OnInit,OnDestroy,AfterViewInit{
       distinctUntilChanged()
     )
 
-    /* patch NG */
-    this.patchNG()
-
     /* each time a new viewer is initialised, take the first event to get the translation function */
     this.newViewer$.pipe(
-      switchMap(()=>fromEvent(this.elementRef.nativeElement,'sliceRenderEvent').pipe(
+      switchMap(() => fromEvent(this.elementRef.nativeElement, 'sliceRenderEvent')
+        .pipe(
           scan((acc:Event[],event:Event)=>{
             const target = (event as Event).target as HTMLElement
             const key = target.offsetLeft < 5 && target.offsetTop < 5 ?
@@ -286,37 +283,6 @@ export class NehubaContainer implements OnInit,OnDestroy,AfterViewInit{
     spatialData.highlight = false
   }
 
-  private patchNG(){
-
-    const { LayerManager, UrlHashBinding } = export_nehuba.getNgPatchableObj()
-    
-    UrlHashBinding.prototype.setUrlHash = ()=>{
-      // console.log('seturl hash')
-      // console.log('setting url hash')
-    }
-
-    UrlHashBinding.prototype.updateFromUrlHash = ()=>{
-      // console.log('update hash binding')
-    }
-
-    /* TODO find a more permanent fix to disable double click */
-    LayerManager.prototype.invokeAction = (arg) => {
-      const region = this.regionsLabelIndexMap.get(this.nehubaViewer.mouseOverSegment)
-      // const foundRegion = INTERACTIVE_VIEWER.viewerHandle.mouseOverNehuba.getValue().foundRegion
-      if(arg=='select'&& region ){
-        this.selectedRegionIndexSet.has(region.labelIndex) ?
-          this.store.dispatch({
-            type : SELECT_REGIONS,
-            selectRegions : [...this.selectedRegionIndexSet].filter(idx=>idx!==region.labelIndex).map(idx=>this.regionsLabelIndexMap.get(idx))
-          }) :
-          this.store.dispatch({
-            type : SELECT_REGIONS,
-            selectRegions : [...this.selectedRegionIndexSet].map(idx=>this.regionsLabelIndexMap.get(idx)).concat(region)
-          })
-      }
-    }
-  }
-
   private handleParcellation(parcellation:any){
     this.regionsLabelIndexMap = getLabelIndexMap(parcellation.regions)
     this.nehubaViewer.regionsLabelIndexMap = this.regionsLabelIndexMap
@@ -376,6 +342,20 @@ export class NehubaContainer implements OnInit,OnDestroy,AfterViewInit{
       this.nehubaViewer.mouseoverSegmentEmitter.subscribe(this.handleEmittedMouseoverSegment.bind(this))
     )
 
+    this.nehubaViewerSubscriptions.push(
+      this.nehubaViewer.regionSelectionEmitter.subscribe(region => {
+        this.selectedRegionIndexSet.has(region.labelIndex) ?
+          this.store.dispatch({
+            type : SELECT_REGIONS,
+            selectRegions : [...this.selectedRegionIndexSet].filter(idx=>idx!==region.labelIndex).map(idx=>this.regionsLabelIndexMap.get(idx))
+          }) :
+          this.store.dispatch({
+            type : SELECT_REGIONS,
+            selectRegions : [...this.selectedRegionIndexSet].map(idx=>this.regionsLabelIndexMap.get(idx)).concat(region)
+          })
+      })
+    )
+
     this.setupViewerHandleApi()
   }
 
diff --git a/src/ui/nehubaContainer/nehubaViewer/nehubaViewer.component.ts b/src/ui/nehubaContainer/nehubaViewer/nehubaViewer.component.ts
index 6163d3e1e..6dab59b59 100644
--- a/src/ui/nehubaContainer/nehubaViewer/nehubaViewer.component.ts
+++ b/src/ui/nehubaContainer/nehubaViewer/nehubaViewer.component.ts
@@ -15,6 +15,7 @@ export class NehubaViewerUnit implements AfterViewInit,OnDestroy{
   
   @Output() debouncedViewerPositionChange : EventEmitter<any> = new EventEmitter()
   @Output() mouseoverSegmentEmitter : EventEmitter<any | number | null> = new EventEmitter()
+  @Output() regionSelectionEmitter : EventEmitter<any> = new EventEmitter()
 
   /* only used to set initial navigation state */
   initNav : any
@@ -46,7 +47,7 @@ export class NehubaViewerUnit implements AfterViewInit,OnDestroy{
   ]
 
   constructor(public elementRef:ElementRef){
-    
+    this.patchNG()
   }
 
   private _parcellationId : string
@@ -104,6 +105,28 @@ export class NehubaViewerUnit implements AfterViewInit,OnDestroy{
     })
   }
 
+  private patchNG(){
+
+    const { LayerManager, UrlHashBinding } = export_nehuba.getNgPatchableObj()
+    
+    UrlHashBinding.prototype.setUrlHash = () => {
+      // console.log('seturl hash')
+      // console.log('setting url hash')
+    }
+
+    UrlHashBinding.prototype.updateFromUrlHash = () => {
+      // console.log('update hash binding')
+    }
+    
+    /* TODO find a more permanent fix to disable double click */
+    LayerManager.prototype.invokeAction = (arg) => {
+      const region = this.regionsLabelIndexMap.get(this.mouseOverSegment)
+      if (arg === 'select' && region) {
+        this.regionSelectionEmitter.emit(region)
+      }
+    }
+  }
+
   private filterLayers(l:any,layerObj:any):boolean{
     return Object.keys(layerObj).length == 0 && layerObj.constructor == Object ?
       true :
-- 
GitLab