diff --git a/capsule-prototype/index.html b/capsule-prototype/index.html
index 4d5a2759effb4d67c6e9bed8cada2cd46cb4cdb8..42d139c96b41170d7ea324bf77d45012eff41b21 100644
--- a/capsule-prototype/index.html
+++ b/capsule-prototype/index.html
@@ -26,7 +26,6 @@
 	<script language="javascript" type='text/javascript' src='../shared/js/libs/fastdom.js'></script>
 	<script language="javascript" type='text/javascript' src='../shared/js/libs/moment-with-langs.min.js'></script>
 	<script language="javascript" type="text/javascript" src='../shared/js/shared.js'></script>
-	<script language="javascript" type="text/javascript" src='../shared/js/MosaicPanelWidget.js'></script>
 
 	<script language="javascript" type='text/javascript' src="../shared/php/rekallApp.js.php"></script>
 
@@ -40,6 +39,7 @@
 	<script language="javascript" type='text/javascript' src='../shared/js/online-rekall/Tags.js'></script>
 	<script language="javascript" type='text/javascript' src='../shared/js/online-rekall/Timeline.js'></script>
 	<script language="javascript" type='text/javascript' src="../shared/js/online-rekall/RekallApplication.js"></script>
+	<script language="javascript" type="text/javascript" src='../shared/js/MosaicPanelWidget.js'></script>
 
 	<script language="javascript" type='text/javascript' src='../shared/js/iannix.js'></script>
 	<script language="javascript" type='text/javascript' src='../shared/js/online-script.js'></script>
diff --git a/capsule-prototype/js/MosaicPanelWidget.js b/capsule-prototype/js/MosaicPanelWidget.js
index e4382afd524d587f274c1c0ded421f6500035709..6eb6d083174279d4b076cd64defabdcf430f36aa 100644
--- a/capsule-prototype/js/MosaicPanelWidget.js
+++ b/capsule-prototype/js/MosaicPanelWidget.js
@@ -1,164 +1,184 @@
-function MosaicPanelWidget(opts){
-
-    const defaultOptions = {
-        htmlElement: $('#mosaic_tab'),
-        rekall: window.app.rekall.Rekall('rekall'),
-        getTagGradientColor: function(tag) {
-            var isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;  // Opera 8.0+ (UA detection to detect Blink/v8-powered Opera)
-            var isFirefox = typeof InstallTrigger !== 'undefined';   // Firefox 1.0+
-            var isSafari = Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0;   // At least Safari 3+: "[object HTMLElementConstructor]"
-            var isChrome = !!window.chrome && !isOpera;              // Chrome 1+
-            var isIE = /*@cc_on!@*/false || !!document.documentMode; // At least IE6
-
-            if(isOpera) {
-                return  "-o-linear-gradient(right bottom,  rgba(20,46,51,1) 0%, "+tag.color+" 100%)";
+((app) => {
+        function MosaicPanelWidget() {
+            const defaultOptions = {
+                getTagGradientColor: function (tag) {
+                    var isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;  // Opera 8.0+ (UA detection to detect Blink/v8-powered Opera)
+                    var isFirefox = typeof InstallTrigger !== 'undefined';   // Firefox 1.0+
+                    var isSafari = Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0;   // At least Safari 3+: "[object HTMLElementConstructor]"
+                    var isChrome = !!window.chrome && !isOpera;              // Chrome 1+
+                    var isIE = /*@cc_on!@*/false || !!document.documentMode; // At least IE6
+
+                    if (isOpera) {
+                        return "-o-linear-gradient(right bottom,  rgba(20,46,51,1) 0%, " + tag.color + " 100%)";
+                    }
+                    if (isFirefox) {
+                        return "-moz-linear-gradient(right bottom,  rgba(20,46,51,1) 0%, " + tag.color + " 100%)";
+                    }
+                    if ((isSafari) || (isChrome)) {
+                        return "-webkit-linear-gradient(right bottom,  rgba(20,46,51,1) 0%, " + tag.color + " 100%)";
+                    }
+                },
+                getPreviewPath: function (tagOrDoc) {
+                    Utils.getPreviewPath(tagOrDoc);
+                },
+                htmlElement: function() { return $('#mosaic_tab') },
+                isOpen: false,
+                pubsub: function() {
+                    return app.rekall.Rekall('pubSub');
+                },
+                rekall: function() {
+                    return app.rekall.Rekall('rekall');
+                }
+            };
+
+            const localOptions = $.extend({}, defaultOptions);
+
+            const getUrl = function (tagOrDoc, path) {
+                if ('undefined' === typeof path) {
+                    let [reg, type] = tagOrDoc.getMetadata("Rekall->Type").split('/');
+                    if (reg === 'rekall') {
+                        if (type === 'marker') type = 'note';
+                    }
+                    return "../shared/css/images/img-" + type + ".png";
+                } else {
+                    return path;
+                }
             }
-            if(isFirefox) {
-                return "-moz-linear-gradient(right bottom,  rgba(20,46,51,1) 0%, "+tag.color+" 100%)";
+
+            const createHtmlElementForTagOrDoc = function (tagOrDoc) {
+                let path = localOptions.getPreviewPath(tagOrDoc);
+                let name = tagOrDoc.getMetadata("Rekall->Name");
+                let url = getUrl(tagOrDoc, path);
+
+                let div = $('<div/>').addClass('mosaic_item').on('click', function () {
+                    tagOrDoc.openPopupEdit();
+                });
+                div.append($('<img/>').attr('src', url).attr('onerror', "this.src='../shared/css/images/img-document.png';"));
+                div.append($('<span/>').addClass('caption').text(name));
+                div.attr('data-rekall-labels', '');
+                div.attr('data-rekall-labels', tagOrDoc.getMetadata('Rekall->Labels'));
+                return div;
             }
-            if((isSafari)||(isChrome)){
-                return "-webkit-linear-gradient(right bottom,  rgba(20,46,51,1) 0%, "+tag.color+" 100%)";
+
+            const getFilterElement = function (text, color, callback, css_class) {
+                return $('<div/>')
+                    .addClass('mosaic_filter_item')
+                    .addClass(css_class)
+                    .on('click', callback)
+                    .css('background-color', color)
+                    .append($('<h2/>').text(text));
             }
-        },
-        getPreviewPath: function (tagOrDoc){
-            Utils.getPreviewPath(tagOrDoc);
-        },
-        isOpen: false
-    };
-
-    const localOptions = $.extend({}, defaultOptions, opts);
-
-    const getUrl = function(tagOrDoc, path){
-        if ('undefined' === typeof path) {
-            let [reg, type] = tagOrDoc.getMetadata("Rekall->Type").split('/');
-            if (reg === 'rekall') {
-                if (type === 'marker') type = 'note';
+
+            const emptyPanel = function () {
+                localOptions.htmlElement().html('');
             }
-            return "../shared/css/images/img-"+type+".png";
-        } else {
-            return path;
-        }
-    }
 
-    const createHtmlElementForTagOrDoc = function (tagOrDoc) {
-        let path = localOptions.getPreviewPath(tagOrDoc);
-        let name = tagOrDoc.getMetadata("Rekall->Name");
-        let url = getUrl(tagOrDoc, path);
-
-        let div=$('<div/>').addClass('mosaic_item').on('click', function() {tagOrDoc.openPopupEdit();});
-        div.append($('<img/>').attr('src', url).attr('onerror', "this.src='../shared/css/images/img-document.png';"));
-        div.append($('<span/>').addClass('caption').text(name));
-        div.attr('data-rekall-labels', '');
-        div.attr('data-rekall-labels', tagOrDoc.getMetadata('Rekall->Labels'));
-        return div;
-    }
+            const fillPanel = function () {
+                let filterdiv = $('<div/>').addClass('mosaic_filter');
+                filterdiv.append(getFilterElement(
+                    'Reset filters',
+                    'rgb(100,100,100)',
+                    function () {
+                        $('.mosaic_filter_item').removeClass('mosaic_filter_disabled');
+                        $('.mosaic_category').show();
+                    },
+                    'mosaic_filter_item_all'
+                ));
+                localOptions.htmlElement().append(filterdiv);
+                let labels = new Set();
+                // TODO is there a better way to iterate over tags or documents ?
+                for (let [k, v] of Object.entries(localOptions.rekall().sortings.colors.categories)) {
+                    let categoryName = localOptions.rekall().sortings.colors.getCategoryName(k)
+                    let category = $('<div/>').addClass('mosaic_category').css('background', localOptions.getTagGradientColor(v));
+
+                    let grid = $('<div/>').addClass('mosaic_category_grid');
+
+                    category.append($('<h2/>').text(categoryName));
+                    category.append(grid);
+
+                    filterdiv.append(getFilterElement(
+                        categoryName,
+                        v.color, function () {
+                            category.toggle();
+                            $(this).toggleClass('mosaic_filter_disabled');
+                        },
+                        ''
+                    ));
+
+                    for (let i in v.tags) {
+                        grid.append(createHtmlElementForTagOrDoc(v.tags[i]));
+                        let current_labels = v.tags[i].getMetadata('Rekall->Labels');
+                        if (current_labels && current_labels != '') {
+                            current_labels.split(';').forEach(l => {
+                                if (l != '') labels.add(l)
+                            });
+                        }
+                    }
+                    localOptions.htmlElement().append(category);
+                }
 
-    const getFilterElement = function (text, color, callback, css_class) {
-        return $('<div/>')
-            .addClass('mosaic_filter_item')
-            .addClass(css_class)
-            .on('click', callback)
-            .css('background-color', color)
-            .append($('<h2/>').text(text));
-    }
+                labels.forEach(l => {
+                    let button = $('<p/>').html(l);
+                    button.my_state = undefined;
+                    button.addClass('mosaic_label_filter');
+                    button.click(ev => {
+                        if (typeof (ev.target.my_state) === 'undefined') ev.target.my_state = true;
+                        else ev.target.my_state = !ev.target.my_state;
+                        if (ev.target.my_state) $(ev.target).addClass('mosaic_label_filter_enabled');
+                        else $(ev.target).removeClass('mosaic_label_filter_enabled');
+                        let labels = new Set();
+                        $('.mosaic_label_filter').toArray().forEach(f => {
+                            if (f.my_state == true)
+                                labels.add(f.innerHTML);
+                        });
+                        if (!labels.size) {
+                            $('.mosaic_label_filter').toArray().forEach(f => {
+                                f.my_state = undefined;
+                                $(f).removeClass('mosaic_label_filter_enabled');
+                            });
+                        }
+                        console.debug('filters: ', labels);
+                        $('.mosaic_item').toArray().forEach(t => {
+                            if (!labels.size || Array.from(labels).map(l => t.dataset.rekallLabels.indexOf(l) != -1).includes(true))
+                                $(t).show();
+                            else
+                                $(t).hide();
+                        });
+                    })
+                    filterdiv.append(button);
+                });
+            }
 
-    const emptyPanel = function(){
-        localOptions.htmlElement.html('');
-    }
+            return {
+                show: function () {
+                    if (localOptions.isOpen)
+                        return;
 
-    const fillPanel = function(){
-        let filterdiv = $('<div/>').addClass('mosaic_filter');
-        filterdiv.append(getFilterElement(
-            'Reset filters',
-            'rgb(100,100,100)',
-            function () {
-                $('.mosaic_filter_item').removeClass('mosaic_filter_disabled');
-                $('.mosaic_category').show();
-            },
-            'mosaic_filter_item_all'
-        ));
-        localOptions.htmlElement.append(filterdiv);
-        let labels = new Set();
-        // TODO is there a better way to iterate over tags or documents ?
-        for ( let [k, v] of  Object.entries(localOptions.rekall.sortings.colors.categories)) {
-            let categoryName = localOptions.rekall.sortings.colors.getCategoryName(k)
-            let category = $('<div/>').addClass('mosaic_category').css('background', localOptions.getTagGradientColor(v));
-
-            let grid = $('<div/>').addClass('mosaic_category_grid');
-
-            category.append($('<h2/>').text(categoryName));
-            category.append(grid);
-
-            filterdiv.append(getFilterElement(
-                categoryName,
-                v.color,function() {
-                    category.toggle();
-                    $(this).toggleClass('mosaic_filter_disabled');
+                    localOptions.rekall().timeline.pause();
+                    fillPanel();
+                    localOptions.htmlElement().show();
+                    localOptions.updateObserver = localOptions.pubsub().subscribe('popupEdit.updated', this.refresh);
+                    localOptions.isOpen = true;
                 },
-                ''
-            ));
-
-            for (let i in v.tags){
-                grid.append(createHtmlElementForTagOrDoc(v.tags[i]));
-                let current_labels = v.tags[i].getMetadata('Rekall->Labels');
-                if (current_labels && current_labels != '') {
-                    current_labels.split(';').forEach(l => {if (l != '') labels.add(l)});
+                hide: function () {
+                    if (!localOptions.isOpen)
+                        return;
+
+                    localOptions.pubsub().unsubscribe(localOptions.updateObserver);
+                    localOptions.updateObserver = undefined;
+                    localOptions.htmlElement().hide();
+                    emptyPanel();
+                    localOptions.isOpen = false;
+                },
+                refresh: function () {
+                    emptyPanel();
+                    fillPanel();
                 }
-            }
-            localOptions.htmlElement.append(category);
+            };
+
         }
 
-        labels.forEach(l => {
-            let button = $('<p/>').html(l);
-            button.my_state = undefined;
-            button.addClass('mosaic_label_filter');
-            button.click(ev => {
-                if (typeof(ev.target.my_state) === 'undefined') ev.target.my_state = true;
-                else ev.target.my_state = !ev.target.my_state;
-                if (ev.target.my_state) $(ev.target).addClass('mosaic_label_filter_enabled');
-                else $(ev.target).removeClass('mosaic_label_filter_enabled');
-                let labels = new Set();
-                $('.mosaic_label_filter').toArray().forEach(f => {
-                    if (f.my_state == true)
-                        labels.add(f.innerHTML);
-                });
-                if (!labels.size) {
-                    $('.mosaic_label_filter').toArray().forEach(f => {
-                        f.my_state = undefined;
-                        $(f).removeClass('mosaic_label_filter_enabled');
-                    });
-                }
-                console.debug('filters: ', labels);
-                $('.mosaic_item').toArray().forEach(t => {
-                    if (!labels.size || Array.from(labels).map(l => t.dataset.rekallLabels.indexOf(l) != -1).includes(true))
-                        $(t).show();
-                    else
-                        $(t).hide();
-                });
-            })
-            filterdiv.append(button);
-        });
-    }
+        app.rekall.Rekall('mosaicWidget', MosaicPanelWidget());
 
-    return {
-        show: function(){
-            if (localOptions.isOpen)
-                return;
-
-            localOptions.rekall.timeline.pause();
-            fillPanel();
-            localOptions.htmlElement.show();
-            localOptions.updateObserver = window.app.rekall.Rekall('pubSub').subscribe('popupEdit.updated', this.refresh)
-        },
-        hide: function (){
-            window.app.rekall.Rekall('pubSub').unsubscribe(localOptions.updateObserver);
-            localOptions.updateObserver = undefined;
-            localOptions.htmlElement.hide();
-            emptyPanel();
-        },
-        refresh: function (){
-            emptyPanel();
-            fillPanel();
-        }
-    };
-}
\ No newline at end of file
+    }
+)(window.app = window.app || {})
\ No newline at end of file
diff --git a/capsule-prototype/js/online-script.js b/capsule-prototype/js/online-script.js
index cd11dd403f800636188b851a8eab32e690761677..3a2987758bce3e6b1551067088f6deec32ea8fc5 100644
--- a/capsule-prototype/js/online-script.js
+++ b/capsule-prototype/js/online-script.js
@@ -12,7 +12,6 @@ window.onload = function() {
 	pubSub.subscribe('open_paste_modal', openPasteModal);
 	pubSub.subscribe('close_paste_modal', closePasteModal);
 	pubSub.subscribe('updated.project.name', onUpdatedProjectName);
-	window.app.rekall.Rekall('mosaicWidget', new MosaicPanelWidget())
 };
 
 $(document).ready(function() {