Updated yeoman  generator to support external ng-xos-lib
Updateding Custom Views:
- ceilometerDashboard
- contentProvider
- dashboardManager
- developer
- diagnostic
- hpc
- mCordTopology
- openVPN
- serviceGrid
- subscribers
- syncNotifier
- tenant
- truckroll

Change-Id: I8bdebf70d3b72ceca8ec04565213efa60bc0b8d3
diff --git a/.dockerignore b/.dockerignore
index 302c3f5..1bb8c22 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -1,4 +1,5 @@
 views/
 applications/
 xos/tests/api/node_modules
+xos/tests/ui/node_modules
 xos/configurations/cord-pod/images
diff --git a/containers/xos/Dockerfile b/containers/xos/Dockerfile
index f274449..98ba9a3 100644
--- a/containers/xos/Dockerfile
+++ b/containers/xos/Dockerfile
@@ -15,11 +15,13 @@
 
 # ng-xos-lib download
 
-ENV NG_XOS_LIB_URL https://gerrit.opencord.org/ng-xos-lib
+ENV NG_XOS_LIB_URL https://github.com/opencord/ng-xos-lib.git
+ENV NG_XOS_LIB_VERSION 1.0.0
 
 RUN git clone $NG_XOS_LIB_URL /tmp/ng-xos-lib 
-RUN cp /tmp/ng-xos-lib/dist/ngXosHelpers.min.js /opt/xos/core/xoslib/static/js/vendor/ 
-RUN cp /tmp/ng-xos-lib/dist/ngXosVendor.min.js /opt/xos/core/xoslib/static/js/vendor/
+RUN cd /tmp/ng-xos-lib && git checkout tags/$NG_XOS_LIB_VERSION
+RUN cp /tmp/ng-xos-lib/dist/ngXosHelpers.min.js /opt/xos/core/xoslib/static/vendor/ 
+RUN cp /tmp/ng-xos-lib/dist/ngXosVendor.min.js /opt/xos/core/xoslib/static/vendor/
 
 EXPOSE 8000
 
diff --git a/containers/xos/Dockerfile.devel b/containers/xos/Dockerfile.devel
index 25c6471..83c108a 100644
--- a/containers/xos/Dockerfile.devel
+++ b/containers/xos/Dockerfile.devel
@@ -9,11 +9,13 @@
 
 # ng-xos-lib download
 
-ENV NG_XOS_LIB_URL https://gerrit.opencord.org/ng-xos-lib
+ENV NG_XOS_LIB_URL https://github.com/opencord/ng-xos-lib.git
+ENV NG_XOS_LIB_VERSION 1.0.0
 
 RUN git clone $NG_XOS_LIB_URL /tmp/ng-xos-lib 
-RUN cp /tmp/ng-xos-lib/dist/ngXosHelpers.min.js /opt/xos/core/xoslib/static/js/vendor/ 
-RUN cp /tmp/ng-xos-lib/dist/ngXosVendor.min.js /opt/xos/core/xoslib/static/js/vendor/
+RUN cd /tmp/ng-xos-lib && git checkout tags/$NG_XOS_LIB_VERSION
+RUN cp /tmp/ng-xos-lib/dist/ngXosHelpers.min.js /opt/xos/core/xoslib/static/vendor/ 
+RUN cp /tmp/ng-xos-lib/dist/ngXosVendor.min.js /opt/xos/core/xoslib/static/vendor/
 
 RUN chmod +x /opt/xos/tools/xos-manage && sync && \
     /opt/xos/tools/xos-manage genkeys
diff --git a/views/ngXosLib/generator-xos/app/templates/bower.json b/views/ngXosLib/generator-xos/app/templates/bower.json
index 0abca60..e94e145 100644
--- a/views/ngXosLib/generator-xos/app/templates/bower.json
+++ b/views/ngXosLib/generator-xos/app/templates/bower.json
@@ -5,7 +5,7 @@
     "<%= author.name %> <<%= author.email %>>"
   ],
   "description": "The <%= name %> view",
-  "license": "MIT",
+  "license": "Apache-2.0",
   "ignore": [
     "**/.*",
     "node_modules",
@@ -28,6 +28,7 @@
     "bootstrap-css": "3.3.6",
     "angular-chart.js": "~0.10.2",
     "d3": "~3.5.17",
-    "angular-recursion": "~1.0.5"
+    "angular-recursion": "~1.0.5",
+    "ng-xos-lib": "opencord/ng-xos-lib#~1.0.0"
   }
 }
diff --git a/views/ngXosLib/generator-xos/app/templates/gulp/build.js b/views/ngXosLib/generator-xos/app/templates/gulp/build.js
index 00dc995..88d88d3 100644
--- a/views/ngXosLib/generator-xos/app/templates/gulp/build.js
+++ b/views/ngXosLib/generator-xos/app/templates/gulp/build.js
@@ -112,7 +112,7 @@
       .pipe(
         inject(
           gulp.src([
-            options.static + 'js/vendor/xos<%= fileName %>Vendor.js',
+            options.static + 'vendor/xos<%= fileName %>Vendor.js',
             options.static + 'js/xos<%= fileName %>.js',
             options.static + 'css/xos<%= fileName %>.css'
           ]),
@@ -138,7 +138,7 @@
     return gulp.src(bowerDeps)
       .pipe(concat('xos<%= fileName %>Vendor.js'))
       .pipe(uglify())
-      .pipe(gulp.dest(options.static + 'js/vendor/'));
+      .pipe(gulp.dest(options.static + 'vendor/'));
   });
 
   gulp.task('lint', function () {
diff --git a/views/ngXosLib/generator-xos/app/templates/gulp/server.js b/views/ngXosLib/generator-xos/app/templates/gulp/server.js
index 1e40a34..36fdded 100644
--- a/views/ngXosLib/generator-xos/app/templates/gulp/server.js
+++ b/views/ngXosLib/generator-xos/app/templates/gulp/server.js
@@ -52,7 +52,6 @@
       server: {
         baseDir: options.src,
         routes: {
-          '/xos/core/xoslib/static/js/vendor': options.helpers,
           '/xos/core/static': options.static + '../../static/'
         },
         middleware: function(req, res, next){
@@ -115,7 +114,7 @@
         inject(
           gulp.src([
             options.tmp + '**/*.js',
-            options.helpers + 'ngXosHelpers.js'
+            options.helpers + 'ngXosHelpers.min.js'
           ])
           .pipe(angularFilesort()),
           {
diff --git a/views/ngXosLib/generator-xos/app/templates/gulpfile.js b/views/ngXosLib/generator-xos/app/templates/gulpfile.js
index eca4e45..c825df8 100644
--- a/views/ngXosLib/generator-xos/app/templates/gulpfile.js
+++ b/views/ngXosLib/generator-xos/app/templates/gulpfile.js
@@ -12,7 +12,7 @@
   tmp: 'src/.tmp',
   dist: 'dist/',
   api: '../../ngXosLib/api/',
-  helpers: '../../../xos/core/xoslib/static/js/vendor/',
+  helpers: './src/vendor/ng-xos-lib/dist/',
   static: '../../../xos/core/xoslib/static/', // this is the django static folder
   dashboards: '../../../xos/core/xoslib/dashboards/' // this is the django html folder
 };
diff --git a/views/ngXosLib/generator-xos/app/templates/karma.conf.js b/views/ngXosLib/generator-xos/app/templates/karma.conf.js
index 4123be9..e5abf39 100644
--- a/views/ngXosLib/generator-xos/app/templates/karma.conf.js
+++ b/views/ngXosLib/generator-xos/app/templates/karma.conf.js
@@ -26,8 +26,9 @@
 
     // list of files / patterns to load in the browser
     files: bowerComponents.concat([
-      '../../../xos/core/xoslib/static/js/vendor/ngXosVendor.js',
-      '../../../xos/core/xoslib/static/js/vendor/ngXosHelpers.js',
+      './src/vendor/ng-xos-lib/dist/ngXosVendor.min.js',
+      './src/vendor/ng-xos-lib/dist/ngXosHelpers.min.js',
+      'src/js/main.js',
       'src/js/**/*.js',
       'spec/**/*.mock.js',
       'spec/**/*.test.js',
@@ -45,6 +46,7 @@
     preprocessors: {
       'src/js/**/*.js': ['babel'],
       'spec/**/*.test.js': ['babel'],
+      'spec/**/*.mock.js': ['babel'],
       'src/**/*.html': ['ng-html2js']
     },
 
diff --git a/views/ngXosLib/generator-xos/app/templates/package.json b/views/ngXosLib/generator-xos/app/templates/package.json
index b0f77f9..0705f5d 100644
--- a/views/ngXosLib/generator-xos/app/templates/package.json
+++ b/views/ngXosLib/generator-xos/app/templates/package.json
@@ -17,7 +17,7 @@
     "XOSlib"
   ],
   "author": "<%= author.name %>",
-  "license": "MIT",
+  "license": "Apache-2.0",
   "dependencies": {},
   "devDependencies": {
     "autoprefixer": "^6.3.3",
diff --git a/views/ngXosLib/generator-xos/test/build.spec.js b/views/ngXosLib/generator-xos/test/build.spec.js
index c6cab4c3..e2f6b49 100644
--- a/views/ngXosLib/generator-xos/test/build.spec.js
+++ b/views/ngXosLib/generator-xos/test/build.spec.js
@@ -28,7 +28,7 @@
 const basePath = '../../../../xos/core/xoslib';
 const destHtml = path.join(__dirname, basePath + '/dashboards/xosTestDashboard.html');
 const destJs = path.join(__dirname, basePath + '/static/js/xosTestDashboard.js');
-const destVendor = path.join(__dirname, basePath + '/static/js/vendor/xosTestDashboardVendor.js');
+const destVendor = path.join(__dirname, basePath + '/static/vendor/xosTestDashboardVendor.js');
 const destCss = path.join(__dirname, basePath + '/static/css/xosTestDashboard.css');
 
 describe('The XOS Build script', function(){
@@ -140,7 +140,7 @@
 
     it('should include only minified files and minified deps in the index', () => {
       assert.fileContent(destHtml, `<script src="/static/js/xos${fileName}.js"></script>`);
-      assert.fileContent(destHtml, `<script src="/static/js/vendor/xos${fileName}Vendor.js"></script>`);
+      assert.fileContent(destHtml, `<script src="/static/vendor/xos${fileName}Vendor.js"></script>`);
       assert.noFileContent(destHtml, `<!-- bower:css -->`);
       assert.noFileContent(destHtml, `<!-- bower:js -->`);
     });
diff --git a/views/ngXosLib/generator-xos/test/generator.spec.js b/views/ngXosLib/generator-xos/test/generator.spec.js
index 81ac985..50ec25e 100644
--- a/views/ngXosLib/generator-xos/test/generator.spec.js
+++ b/views/ngXosLib/generator-xos/test/generator.spec.js
@@ -9,17 +9,18 @@
 
 const firstCharTouppercase = string => string.replace(/^./, string[0].toUpperCase())
 
-// get bower deps installed in ngXosLib
-let bowerDeps = wiredep({
-  cwd: path.join(__dirname, '../../'), // pretending to be in the ngXosLib root
-  exclude: ['Chart.js']
-});
-bowerDeps = bowerDeps.js.map(d => {
-  let path = d.match(/bower_components\/([1-9a-zA-Z\-`.]+)\//);
-  if(path){
-    return path[1];
-  }
-});
+const bowerDeps = [
+  'angular',
+  'angular-ui-router',
+  'angular-resource',
+  'angular-cookies',
+  'angular-animate',
+  'lodash',
+  'angular-chart.js',
+  'd3',
+  'angular-recursion',
+  'ng-xos-lib'
+];
 
 // test values
 const viewName = 'testDashboard';
@@ -100,7 +101,7 @@
     assert.fileContent(`${testPath}gulp/build.js`, `.pipe(concat('xos${fileName}.css'))`)
     assert.fileContent(`${testPath}gulp/build.js`, `.pipe(concat('xos${fileName}.js'))`)
     assert.fileContent(`${testPath}gulp/build.js`, `module: 'xos.${viewName}'`)
-    assert.fileContent(`${testPath}gulp/build.js`, `options.static + 'js/vendor/xos${fileName}Vendor.js'`)
+    assert.fileContent(`${testPath}gulp/build.js`, `options.static + 'vendor/xos${fileName}Vendor.js'`)
     assert.fileContent(`${testPath}gulp/build.js`, `options.static + 'js/xos${fileName}.js'`)
     assert.fileContent(`${testPath}gulp/build.js`, `options.static + 'css/xos${fileName}.css'`)
     assert.fileContent(`${testPath}gulp/build.js`, `.pipe(concat('xos${fileName}Vendor.js'))`)
diff --git a/views/ngXosViews/ceilometerDashboard/bower.json b/views/ngXosViews/ceilometerDashboard/bower.json
index a3caa9f..41c67d3 100644
--- a/views/ngXosViews/ceilometerDashboard/bower.json
+++ b/views/ngXosViews/ceilometerDashboard/bower.json
@@ -15,7 +15,6 @@
     "tests"
   ],
   "dependencies": {
-    "angular-animate": "1.4.7",n
     "ui.bootstrap": "0.14.3"
   },
   "devDependencies": {
@@ -24,11 +23,14 @@
     "angular": "1.4.7",
     "angular-ui-router": "0.2.15",
     "angular-cookies": "1.4.7",
+    "angular-animate": "1.4.7",
     "angular-resource": "1.4.7",
     "lodash": "~4.11.1",
     "bootstrap-css": "3.3.6",
     "angular-chart.js": "~0.10.2",
-    "d3": "~3.5.17"
+    "d3": "~3.5.17",
+    "angular-recursion": "~1.0.5",
+    "ng-xos-lib": "opencord/ng-xos-lib#~1.0.0"
   },
   "overrides": {
     "ui.bootstrap": {
diff --git a/views/ngXosViews/ceilometerDashboard/gulp/build.js b/views/ngXosViews/ceilometerDashboard/gulp/build.js
index cfb07e2..4608dff 100644
--- a/views/ngXosViews/ceilometerDashboard/gulp/build.js
+++ b/views/ngXosViews/ceilometerDashboard/gulp/build.js
@@ -41,7 +41,9 @@
     return del(
       [
         options.dashboards + 'xosCeilometerDashboard.html',
-        options.static + 'css/xosCeilometerDashboard.css'
+        options.static + 'css/xosCeilometerDashboard.css',
+        options.static + 'images/ceilometerDashboard-icon.png',
+        options.static + 'images/ceilometerDashboard-icon-active.png'
       ],
       {force: true}
     );
@@ -70,6 +72,12 @@
     .pipe(gulp.dest(options.static + 'css/'))
   });
 
+  // copy images in correct folder
+  gulp.task('copyImages', ['wait'], function(){
+    return gulp.src([`${options.icon}/ceilometerDashboard-icon.png`,`${options.icon}/ceilometerDashboard-icon-active.png`])
+    .pipe(gulp.dest(options.static + 'images/'))
+  });
+
   // compile and minify scripts
   gulp.task('scripts', function() {
     return gulp.src([
@@ -104,7 +112,7 @@
       .pipe(
         inject(
           gulp.src([
-            options.static + 'js/vendor/xosCeilometerDashboardVendor.js',
+            options.static + 'vendor/xosCeilometerDashboardVendor.js',
             options.static + 'js/xosCeilometerDashboard.js',
             options.static + 'css/xosCeilometerDashboard.css'
           ]),
@@ -129,8 +137,8 @@
 
     return gulp.src(bowerDeps)
       .pipe(concat('xosCeilometerDashboardVendor.js'))
-      //.pipe(uglify())
-      .pipe(gulp.dest(options.static + 'js/vendor/'));
+      .pipe(uglify())
+      .pipe(gulp.dest(options.static + 'vendor/'));
   });
 
   gulp.task('lint', function () {
@@ -157,6 +165,7 @@
       'wiredep',
       'css',
       'copyCss',
+      'copyImages',
       'copyHtml',
       'cleanTmp'
     );
diff --git a/views/ngXosViews/ceilometerDashboard/gulp/server.js b/views/ngXosViews/ceilometerDashboard/gulp/server.js
index 19caf89..607c85d 100644
--- a/views/ngXosViews/ceilometerDashboard/gulp/server.js
+++ b/views/ngXosViews/ceilometerDashboard/gulp/server.js
@@ -30,6 +30,7 @@
   target: conf.host
 });
 
+
 proxy.on('error', function(error, req, res) {
   res.writeHead(500, {
     'Content-Type': 'text/plain'
@@ -51,7 +52,6 @@
       server: {
         baseDir: options.src,
         routes: {
-          '/xos/core/xoslib/static/js/vendor': options.helpers,
           '/xos/core/static': options.static + '../../static/'
         },
         middleware: function(req, res, next){
@@ -115,7 +115,7 @@
         inject(
           gulp.src([
             options.tmp + '**/*.js',
-            options.helpers + 'ngXosHelpers.js'
+            options.helpers + 'ngXosHelpers.min.js'
           ])
           .pipe(angularFilesort()),
           {
diff --git a/views/ngXosViews/ceilometerDashboard/gulpfile.js b/views/ngXosViews/ceilometerDashboard/gulpfile.js
index 08df554..c825df8 100644
--- a/views/ngXosViews/ceilometerDashboard/gulpfile.js
+++ b/views/ngXosViews/ceilometerDashboard/gulpfile.js
@@ -6,12 +6,13 @@
 var options = {
   src: 'src/',
   css: 'src/css/',
+  icon: 'src/icons',
   sass: 'src/sass/',
   scripts: 'src/js/',
   tmp: 'src/.tmp',
   dist: 'dist/',
   api: '../../ngXosLib/api/',
-  helpers: '../../../xos/core/xoslib/static/js/vendor/',
+  helpers: './src/vendor/ng-xos-lib/dist/',
   static: '../../../xos/core/xoslib/static/', // this is the django static folder
   dashboards: '../../../xos/core/xoslib/dashboards/' // this is the django html folder
 };
diff --git a/views/ngXosViews/ceilometerDashboard/karma.conf.js b/views/ngXosViews/ceilometerDashboard/karma.conf.js
index 9d9e77e..242d8b0 100644
--- a/views/ngXosViews/ceilometerDashboard/karma.conf.js
+++ b/views/ngXosViews/ceilometerDashboard/karma.conf.js
@@ -11,6 +11,7 @@
   return path.relative(process.cwd(), file);
 });
 
+
 module.exports = function(config) {
 /*eslint-enable*/
   config.set({
@@ -25,10 +26,9 @@
 
 
     // list of files / patterns to load in the browser
-    files: [
-      '../../../xos/core/xoslib/static/js/vendor/ngXosVendor.js',
-      '../../../xos/core/xoslib/static/js/vendor/ngXosHelpers.js',
-    ].concat(bowerComponents).concat([
+    files: ['./src/vendor/ng-xos-lib/dist/ngXosVendor.min.js']
+    .concat(bowerComponents).concat([
+      './src/vendor/ng-xos-lib/dist/ngXosHelpers.min.js',
       'src/js/main.js',
       'src/js/**/*.js',
       'spec/**/*.mock.js',
diff --git a/views/ngXosViews/ceilometerDashboard/src/icons/README.md b/views/ngXosViews/ceilometerDashboard/src/icons/README.md
new file mode 100644
index 0000000..0d5a787
--- /dev/null
+++ b/views/ngXosViews/ceilometerDashboard/src/icons/README.md
@@ -0,0 +1,18 @@
+# Set icon for custom dashboard 
+
+## Path to add images : <dashboard-name>/src/icons
+
+### Add two images with name in following format 
+    <dashboard-name>-icon.png
+    <dashboard-name>-icon-active.png
+
+Examples: 
+    If your dashboard name is `slice`
+    then you will add the images with the name as
+        `slice-icon.png`
+        `slice-icon-active.png`
+        
+        
+        
+        
+Note: If you don't add the custom images, then dashboard will use the default images stored at `/xos/core/xoslib/static/images`
\ No newline at end of file
diff --git a/views/ngXosViews/contentProvider/bower.json b/views/ngXosViews/contentProvider/bower.json
index b8a92a7..f46e604 100644
--- a/views/ngXosViews/contentProvider/bower.json
+++ b/views/ngXosViews/contentProvider/bower.json
@@ -2,7 +2,7 @@
   "name": "xos-contentProvider",
   "version": "0.0.0",
   "authors": [
-    "Matteo Scandolo <teo@onlab.us>"
+    "Matteo Scandolo <matteo.scandolo@gmail.com>"
   ],
   "description": "The contentProvider view",
   "license": "MIT",
@@ -27,6 +27,8 @@
     "lodash": "~4.11.1",
     "bootstrap-css": "3.3.6",
     "angular-chart.js": "~0.10.2",
-    "d3": "~3.5.17"
+    "d3": "~3.5.17",
+    "angular-recursion": "~1.0.5",
+    "ng-xos-lib": "opencord/ng-xos-lib#~1.0.0"
   }
 }
diff --git a/views/ngXosViews/contentProvider/gulp/build.js b/views/ngXosViews/contentProvider/gulp/build.js
index 6bef382..c560e4a 100644
--- a/views/ngXosViews/contentProvider/gulp/build.js
+++ b/views/ngXosViews/contentProvider/gulp/build.js
@@ -41,7 +41,9 @@
     return del(
       [
         options.dashboards + 'xosContentProvider.html',
-        options.static + 'css/xosContentProvider.css'
+        options.static + 'css/xosContentProvider.css',
+        options.static + 'images/contentProvider-icon.png',
+        options.static + 'images/contentProvider-icon-active.png'
       ],
       {force: true}
     );
@@ -70,6 +72,12 @@
     .pipe(gulp.dest(options.static + 'css/'))
   });
 
+  // copy images in correct folder
+  gulp.task('copyImages', ['wait'], function(){
+    return gulp.src([`${options.icon}/contentProvider-icon.png`,`${options.icon}/contentProvider-icon-active.png`])
+    .pipe(gulp.dest(options.static + 'images/'))
+  });
+
   // compile and minify scripts
   gulp.task('scripts', function() {
     return gulp.src([
@@ -104,7 +112,7 @@
       .pipe(
         inject(
           gulp.src([
-            options.static + 'js/vendor/xosContentProviderVendor.js',
+            options.static + 'vendor/xosContentProviderVendor.js',
             options.static + 'js/xosContentProvider.js',
             options.static + 'css/xosContentProvider.css'
           ]),
@@ -130,7 +138,7 @@
     return gulp.src(bowerDeps)
       .pipe(concat('xosContentProviderVendor.js'))
       .pipe(uglify())
-      .pipe(gulp.dest(options.static + 'js/vendor/'));
+      .pipe(gulp.dest(options.static + 'vendor/'));
   });
 
   gulp.task('lint', function () {
@@ -157,6 +165,7 @@
       'wiredep',
       'css',
       'copyCss',
+      'copyImages',
       'copyHtml',
       'cleanTmp'
     );
diff --git a/views/ngXosViews/contentProvider/gulp/server.js b/views/ngXosViews/contentProvider/gulp/server.js
index 0bc2bd3..27791f5 100644
--- a/views/ngXosViews/contentProvider/gulp/server.js
+++ b/views/ngXosViews/contentProvider/gulp/server.js
@@ -52,13 +52,12 @@
       server: {
         baseDir: options.src,
         routes: {
-          '/xos/core/xoslib/static/js/vendor': options.helpers,
           '/xos/core/static': options.static + '../../static/'
         },
         middleware: function(req, res, next){
           if(
-            req.url.indexOf('/api/') !== -1 ||
-            req.url.indexOf('/hpcapi/') !== -1
+            req.url.indexOf('/hpcapi/') !== -1 || 
+            req.url.indexOf('/api/') !== -1
           ){
             if(conf.xoscsrftoken && conf.xossessionid){
               req.headers.cookie = `xoscsrftoken=${conf.xoscsrftoken}; xossessionid=${conf.xossessionid}`;
@@ -116,7 +115,7 @@
         inject(
           gulp.src([
             options.tmp + '**/*.js',
-            options.helpers + 'ngXosHelpers.js'
+            options.helpers + 'ngXosHelpers.min.js'
           ])
           .pipe(angularFilesort()),
           {
diff --git a/views/ngXosViews/contentProvider/gulpfile.js b/views/ngXosViews/contentProvider/gulpfile.js
index 08df554..c825df8 100644
--- a/views/ngXosViews/contentProvider/gulpfile.js
+++ b/views/ngXosViews/contentProvider/gulpfile.js
@@ -6,12 +6,13 @@
 var options = {
   src: 'src/',
   css: 'src/css/',
+  icon: 'src/icons',
   sass: 'src/sass/',
   scripts: 'src/js/',
   tmp: 'src/.tmp',
   dist: 'dist/',
   api: '../../ngXosLib/api/',
-  helpers: '../../../xos/core/xoslib/static/js/vendor/',
+  helpers: './src/vendor/ng-xos-lib/dist/',
   static: '../../../xos/core/xoslib/static/', // this is the django static folder
   dashboards: '../../../xos/core/xoslib/dashboards/' // this is the django html folder
 };
diff --git a/views/ngXosViews/contentProvider/karma.conf.js b/views/ngXosViews/contentProvider/karma.conf.js
index 4123be9..e5abf39 100644
--- a/views/ngXosViews/contentProvider/karma.conf.js
+++ b/views/ngXosViews/contentProvider/karma.conf.js
@@ -26,8 +26,9 @@
 
     // list of files / patterns to load in the browser
     files: bowerComponents.concat([
-      '../../../xos/core/xoslib/static/js/vendor/ngXosVendor.js',
-      '../../../xos/core/xoslib/static/js/vendor/ngXosHelpers.js',
+      './src/vendor/ng-xos-lib/dist/ngXosVendor.min.js',
+      './src/vendor/ng-xos-lib/dist/ngXosHelpers.min.js',
+      'src/js/main.js',
       'src/js/**/*.js',
       'spec/**/*.mock.js',
       'spec/**/*.test.js',
@@ -45,6 +46,7 @@
     preprocessors: {
       'src/js/**/*.js': ['babel'],
       'spec/**/*.test.js': ['babel'],
+      'spec/**/*.mock.js': ['babel'],
       'src/**/*.html': ['ng-html2js']
     },
 
diff --git a/views/ngXosViews/contentProvider/src/icons/README.md b/views/ngXosViews/contentProvider/src/icons/README.md
new file mode 100644
index 0000000..0d5a787
--- /dev/null
+++ b/views/ngXosViews/contentProvider/src/icons/README.md
@@ -0,0 +1,18 @@
+# Set icon for custom dashboard 
+
+## Path to add images : <dashboard-name>/src/icons
+
+### Add two images with name in following format 
+    <dashboard-name>-icon.png
+    <dashboard-name>-icon-active.png
+
+Examples: 
+    If your dashboard name is `slice`
+    then you will add the images with the name as
+        `slice-icon.png`
+        `slice-icon-active.png`
+        
+        
+        
+        
+Note: If you don't add the custom images, then dashboard will use the default images stored at `/xos/core/xoslib/static/images`
\ No newline at end of file
diff --git a/views/ngXosViews/contentProvider/src/index.html b/views/ngXosViews/contentProvider/src/index.html
index accd37d..703c613 100644
--- a/views/ngXosViews/contentProvider/src/index.html
+++ b/views/ngXosViews/contentProvider/src/index.html
@@ -26,8 +26,9 @@
 <script src="vendor/Chart.js/Chart.js"></script>
 <script src="vendor/angular-chart.js/dist/angular-chart.js"></script>
 <script src="vendor/d3/d3.js"></script>
+<script src="vendor/angular-recursion/angular-recursion.js"></script>
 <!-- endbower --><!-- endjs -->
 <!-- inject:js -->
-<script src="/../../../xos/core/xoslib/static/js/vendor/ngXosHelpers.js"></script>
+<script src="/vendor/ng-xos-lib/dist/ngXosHelpers.min.js"></script>
 <script src="/.tmp/main.js"></script>
 <!-- endinject -->
diff --git a/views/ngXosViews/dashboardManager/bower.json b/views/ngXosViews/dashboardManager/bower.json
index 5c05525..6e0f60b 100644
--- a/views/ngXosViews/dashboardManager/bower.json
+++ b/views/ngXosViews/dashboardManager/bower.json
@@ -30,6 +30,7 @@
     "bootstrap-css": "3.3.6",
     "angular-chart.js": "~0.10.2",
     "d3": "~3.5.17",
-    "angular-recursion": "~1.0.5"
+    "angular-recursion": "~1.0.5",
+    "ng-xos-lib": "opencord/ng-xos-lib#~1.0.0"
   }
 }
diff --git a/views/ngXosViews/dashboardManager/gulp/build.js b/views/ngXosViews/dashboardManager/gulp/build.js
index 96b7cd2..9789be8 100644
--- a/views/ngXosViews/dashboardManager/gulp/build.js
+++ b/views/ngXosViews/dashboardManager/gulp/build.js
@@ -41,7 +41,9 @@
     return del(
       [
         options.dashboards + 'xosDashboardManager.html',
-        options.static + 'css/xosDashboardManager.css'
+        options.static + 'css/xosDashboardManager.css',
+        options.static + 'images/dashboardManager-icon.png',
+        options.static + 'images/dashboardManager-icon-active.png'
       ],
       {force: true}
     );
@@ -70,6 +72,12 @@
     .pipe(gulp.dest(options.static + 'css/'))
   });
 
+  // copy images in correct folder
+  gulp.task('copyImages', ['wait'], function(){
+    return gulp.src([`${options.icon}/dashboardManager-icon.png`,`${options.icon}/dashboardManager-icon-active.png`])
+    .pipe(gulp.dest(options.static + 'images/'))
+  });
+
   // compile and minify scripts
   gulp.task('scripts', function() {
     return gulp.src([
@@ -104,7 +112,7 @@
       .pipe(
         inject(
           gulp.src([
-            options.static + 'js/vendor/xosDashboardManagerVendor.js',
+            options.static + 'vendor/xosDashboardManagerVendor.js',
             options.static + 'js/xosDashboardManager.js',
             options.static + 'css/xosDashboardManager.css'
           ]),
@@ -130,7 +138,7 @@
     return gulp.src(bowerDeps)
       .pipe(concat('xosDashboardManagerVendor.js'))
       .pipe(uglify())
-      .pipe(gulp.dest(options.static + 'js/vendor/'));
+      .pipe(gulp.dest(options.static + 'vendor/'));
   });
 
   gulp.task('lint', function () {
@@ -157,6 +165,7 @@
       'wiredep',
       'css',
       'copyCss',
+      'copyImages',
       'copyHtml',
       'cleanTmp'
     );
diff --git a/views/ngXosViews/dashboardManager/gulp/server.js b/views/ngXosViews/dashboardManager/gulp/server.js
index 1e40a34..36fdded 100644
--- a/views/ngXosViews/dashboardManager/gulp/server.js
+++ b/views/ngXosViews/dashboardManager/gulp/server.js
@@ -52,7 +52,6 @@
       server: {
         baseDir: options.src,
         routes: {
-          '/xos/core/xoslib/static/js/vendor': options.helpers,
           '/xos/core/static': options.static + '../../static/'
         },
         middleware: function(req, res, next){
@@ -115,7 +114,7 @@
         inject(
           gulp.src([
             options.tmp + '**/*.js',
-            options.helpers + 'ngXosHelpers.js'
+            options.helpers + 'ngXosHelpers.min.js'
           ])
           .pipe(angularFilesort()),
           {
diff --git a/views/ngXosViews/dashboardManager/gulpfile.js b/views/ngXosViews/dashboardManager/gulpfile.js
index 08df554..c825df8 100644
--- a/views/ngXosViews/dashboardManager/gulpfile.js
+++ b/views/ngXosViews/dashboardManager/gulpfile.js
@@ -6,12 +6,13 @@
 var options = {
   src: 'src/',
   css: 'src/css/',
+  icon: 'src/icons',
   sass: 'src/sass/',
   scripts: 'src/js/',
   tmp: 'src/.tmp',
   dist: 'dist/',
   api: '../../ngXosLib/api/',
-  helpers: '../../../xos/core/xoslib/static/js/vendor/',
+  helpers: './src/vendor/ng-xos-lib/dist/',
   static: '../../../xos/core/xoslib/static/', // this is the django static folder
   dashboards: '../../../xos/core/xoslib/dashboards/' // this is the django html folder
 };
diff --git a/views/ngXosViews/dashboardManager/karma.conf.js b/views/ngXosViews/dashboardManager/karma.conf.js
index 5d00727..a10d010 100644
--- a/views/ngXosViews/dashboardManager/karma.conf.js
+++ b/views/ngXosViews/dashboardManager/karma.conf.js
@@ -1,4 +1,3 @@
-'use strict';
 // Karma configuration
 // Generated on Tue Oct 06 2015 09:27:10 GMT+0000 (UTC)
 
@@ -12,7 +11,7 @@
   return path.relative(process.cwd(), file);
 });
 
-// dirt trick to load angular as first
+// dirty trick to load angular as first
 var ngIndex = bowerComponents.findIndex((item) => {
   return item === 'src/vendor/angular/angular.js';
 });
@@ -36,8 +35,8 @@
 
     // list of files / patterns to load in the browser
     files: bowerComponents.concat([
-      '../../../xos/core/xoslib/static/js/vendor/ngXosVendor.js',
-      '../../../xos/core/xoslib/static/js/vendor/ngXosHelpers.js',
+      './src/vendor/ng-xos-lib/dist/ngXosVendor.min.js',
+      './src/vendor/ng-xos-lib/dist/ngXosHelpers.min.js',
       'src/js/main.js',
       'src/js/**/*.js',
       'spec/**/*.mock.js',
@@ -56,6 +55,7 @@
     preprocessors: {
       'src/js/**/*.js': ['babel'],
       'spec/**/*.test.js': ['babel'],
+      'spec/**/*.mock.js': ['babel'],
       'src/**/*.html': ['ng-html2js']
     },
 
diff --git a/views/ngXosViews/dashboardManager/src/css/dev.css b/views/ngXosViews/dashboardManager/src/css/dev.css
new file mode 100644
index 0000000..68b909c
--- /dev/null
+++ b/views/ngXosViews/dashboardManager/src/css/dev.css
@@ -0,0 +1,5 @@
+#xosDashboardManager{
+  position: absolute;
+  top: 100px;
+  left: 200px;
+}
\ No newline at end of file
diff --git a/views/ngXosViews/dashboardManager/src/icons/README.md b/views/ngXosViews/dashboardManager/src/icons/README.md
new file mode 100644
index 0000000..0d5a787
--- /dev/null
+++ b/views/ngXosViews/dashboardManager/src/icons/README.md
@@ -0,0 +1,18 @@
+# Set icon for custom dashboard 
+
+## Path to add images : <dashboard-name>/src/icons
+
+### Add two images with name in following format 
+    <dashboard-name>-icon.png
+    <dashboard-name>-icon-active.png
+
+Examples: 
+    If your dashboard name is `slice`
+    then you will add the images with the name as
+        `slice-icon.png`
+        `slice-icon-active.png`
+        
+        
+        
+        
+Note: If you don't add the custom images, then dashboard will use the default images stored at `/xos/core/xoslib/static/images`
\ No newline at end of file
diff --git a/views/ngXosViews/dashboardManager/src/index.html b/views/ngXosViews/dashboardManager/src/index.html
index 6df0c5f..55613ae 100644
--- a/views/ngXosViews/dashboardManager/src/index.html
+++ b/views/ngXosViews/dashboardManager/src/index.html
@@ -5,6 +5,7 @@
 <!-- endbower -->
 <!-- endcss -->
 <!-- inject:css -->
+<link rel="stylesheet" href="/css/dev.css">
 <link rel="stylesheet" href="/css/main.css">
 <link rel="stylesheet" href="/../../../xos/core/static/xosNgLib.css">
 <!-- endinject -->
@@ -14,10 +15,10 @@
 </div>
 
 <!-- bower:js -->
+<script src="vendor/angular/angular.js"></script>
 <script src="vendor/angular-drag-and-drop-lists/angular-drag-and-drop-lists.js"></script>
 <script src="vendor/js-yaml/dist/js-yaml.js"></script>
 <script src="vendor/jquery/dist/jquery.js"></script>
-<script src="vendor/angular/angular.js"></script>
 <script src="vendor/angular-mocks/angular-mocks.js"></script>
 <script src="vendor/angular-ui-router/release/angular-ui-router.js"></script>
 <script src="vendor/angular-cookies/angular-cookies.js"></script>
@@ -32,7 +33,7 @@
 <!-- endbower -->
 <!-- endjs -->
 <!-- inject:js -->
-<script src="/../../../xos/core/xoslib/static/js/vendor/ngXosHelpers.js"></script>
+<script src="/vendor/ng-xos-lib/dist/ngXosHelpers.min.js"></script>
 <script src="/.tmp/main.js"></script>
 <script src="/.tmp/user-dashboards.directive.js"></script>
 <script src="/.tmp/dashboard-form.directive.js"></script>
diff --git a/views/ngXosViews/dashboardManager/src/templates/users-list.tpl.html b/views/ngXosViews/dashboardManager/src/templates/users-list.tpl.html
new file mode 100644
index 0000000..1fee0e2
--- /dev/null
+++ b/views/ngXosViews/dashboardManager/src/templates/users-list.tpl.html
@@ -0,0 +1 @@
+<xos-table config="vm.tableConfig" data="vm.users"></xos-table>
\ No newline at end of file
diff --git a/views/ngXosViews/developer/bower.json b/views/ngXosViews/developer/bower.json
index da4d6b3..1d82b4a 100644
--- a/views/ngXosViews/developer/bower.json
+++ b/views/ngXosViews/developer/bower.json
@@ -2,7 +2,7 @@
   "name": "xos-developer",
   "version": "0.0.0",
   "authors": [
-    "Matteo Scandolo <teo@onlab.us>"
+    "Matteo Scandolo <matteo.scandolo@gmail.com>"
   ],
   "description": "The developer view",
   "license": "MIT",
@@ -26,6 +26,9 @@
     "angular-resource": "1.4.7",
     "lodash": "~4.11.1",
     "bootstrap-css": "3.3.6",
-    "angular-chart.js": "~0.10.2"
+    "angular-chart.js": "~0.10.2",
+    "d3": "~3.5.17",
+    "angular-recursion": "~1.0.5",
+    "ng-xos-lib": "opencord/ng-xos-lib#~1.0.0"
   }
 }
diff --git a/views/ngXosViews/developer/gulp/build.js b/views/ngXosViews/developer/gulp/build.js
index 87e68d8..4ad71d4 100644
--- a/views/ngXosViews/developer/gulp/build.js
+++ b/views/ngXosViews/developer/gulp/build.js
@@ -41,7 +41,9 @@
     return del(
       [
         options.dashboards + 'xosDeveloper.html',
-        options.static + 'css/xosDeveloper.css'
+        options.static + 'css/xosDeveloper.css',
+        options.static + 'images/developer-icon.png',
+        options.static + 'images/developer-icon-active.png'
       ],
       {force: true}
     );
@@ -70,6 +72,12 @@
     .pipe(gulp.dest(options.static + 'css/'))
   });
 
+  // copy images in correct folder
+  gulp.task('copyImages', ['wait'], function(){
+    return gulp.src([`${options.icon}/developer-icon.png`,`${options.icon}/developer-icon-active.png`])
+    .pipe(gulp.dest(options.static + 'images/'))
+  });
+
   // compile and minify scripts
   gulp.task('scripts', function() {
     return gulp.src([
@@ -104,7 +112,7 @@
       .pipe(
         inject(
           gulp.src([
-            options.static + 'js/vendor/xosDeveloperVendor.js',
+            options.static + 'vendor/xosDeveloperVendor.js',
             options.static + 'js/xosDeveloper.js',
             options.static + 'css/xosDeveloper.css'
           ]),
@@ -130,7 +138,7 @@
     return gulp.src(bowerDeps)
       .pipe(concat('xosDeveloperVendor.js'))
       .pipe(uglify())
-      .pipe(gulp.dest(options.static + 'js/vendor/'));
+      .pipe(gulp.dest(options.static + 'vendor/'));
   });
 
   gulp.task('lint', function () {
@@ -157,6 +165,7 @@
       'wiredep',
       'css',
       'copyCss',
+      'copyImages',
       'copyHtml',
       'cleanTmp'
     );
diff --git a/views/ngXosViews/developer/gulp/server.js b/views/ngXosViews/developer/gulp/server.js
index 1e40a34..36fdded 100644
--- a/views/ngXosViews/developer/gulp/server.js
+++ b/views/ngXosViews/developer/gulp/server.js
@@ -52,7 +52,6 @@
       server: {
         baseDir: options.src,
         routes: {
-          '/xos/core/xoslib/static/js/vendor': options.helpers,
           '/xos/core/static': options.static + '../../static/'
         },
         middleware: function(req, res, next){
@@ -115,7 +114,7 @@
         inject(
           gulp.src([
             options.tmp + '**/*.js',
-            options.helpers + 'ngXosHelpers.js'
+            options.helpers + 'ngXosHelpers.min.js'
           ])
           .pipe(angularFilesort()),
           {
diff --git a/views/ngXosViews/developer/gulpfile.js b/views/ngXosViews/developer/gulpfile.js
index 08df554..c825df8 100644
--- a/views/ngXosViews/developer/gulpfile.js
+++ b/views/ngXosViews/developer/gulpfile.js
@@ -6,12 +6,13 @@
 var options = {
   src: 'src/',
   css: 'src/css/',
+  icon: 'src/icons',
   sass: 'src/sass/',
   scripts: 'src/js/',
   tmp: 'src/.tmp',
   dist: 'dist/',
   api: '../../ngXosLib/api/',
-  helpers: '../../../xos/core/xoslib/static/js/vendor/',
+  helpers: './src/vendor/ng-xos-lib/dist/',
   static: '../../../xos/core/xoslib/static/', // this is the django static folder
   dashboards: '../../../xos/core/xoslib/dashboards/' // this is the django html folder
 };
diff --git a/views/ngXosViews/developer/karma.conf.js b/views/ngXosViews/developer/karma.conf.js
index 4123be9..e5abf39 100644
--- a/views/ngXosViews/developer/karma.conf.js
+++ b/views/ngXosViews/developer/karma.conf.js
@@ -26,8 +26,9 @@
 
     // list of files / patterns to load in the browser
     files: bowerComponents.concat([
-      '../../../xos/core/xoslib/static/js/vendor/ngXosVendor.js',
-      '../../../xos/core/xoslib/static/js/vendor/ngXosHelpers.js',
+      './src/vendor/ng-xos-lib/dist/ngXosVendor.min.js',
+      './src/vendor/ng-xos-lib/dist/ngXosHelpers.min.js',
+      'src/js/main.js',
       'src/js/**/*.js',
       'spec/**/*.mock.js',
       'spec/**/*.test.js',
@@ -45,6 +46,7 @@
     preprocessors: {
       'src/js/**/*.js': ['babel'],
       'spec/**/*.test.js': ['babel'],
+      'spec/**/*.mock.js': ['babel'],
       'src/**/*.html': ['ng-html2js']
     },
 
diff --git a/views/ngXosViews/developer/package.json b/views/ngXosViews/developer/package.json
index f28682f..9a6eff2 100644
--- a/views/ngXosViews/developer/package.json
+++ b/views/ngXosViews/developer/package.json
@@ -9,9 +9,7 @@
     "build": "gulp",
     "test": "karma start",
     "test:ci": "karma start --single-run",
-    "lint": "eslint src/js/",
-    "single-site": "easy-mocker -c ./mocks/config.json -d ./mocks/single-site",
-    "multi-site": "easy-mocker -c ./mocks/config.json -d ./mocks/multi-site"
+    "lint": "eslint src/js/"
   },
   "keywords": [
     "XOS",
@@ -27,7 +25,7 @@
     "css-mqpacker": "^4.0.0",
     "csswring": "^4.2.1",
     "del": "^2.0.2",
-    "easy-mocker": "^1.3.0",
+    "easy-mocker": "^1.2.0",
     "eslint": "^1.8.0",
     "eslint-plugin-angular": "linkmesrl/eslint-plugin-angular",
     "gulp": "^3.9.0",
diff --git a/views/ngXosViews/developer/src/css/dev.css b/views/ngXosViews/developer/src/css/dev.css
new file mode 100644
index 0000000..ca9b692
--- /dev/null
+++ b/views/ngXosViews/developer/src/css/dev.css
@@ -0,0 +1,5 @@
+#xosDeveloper{
+  position: absolute;
+  top: 100px;
+  left: 200px;
+}
\ No newline at end of file
diff --git a/views/ngXosViews/developer/src/icons/README.md b/views/ngXosViews/developer/src/icons/README.md
new file mode 100644
index 0000000..0d5a787
--- /dev/null
+++ b/views/ngXosViews/developer/src/icons/README.md
@@ -0,0 +1,18 @@
+# Set icon for custom dashboard 
+
+## Path to add images : <dashboard-name>/src/icons
+
+### Add two images with name in following format 
+    <dashboard-name>-icon.png
+    <dashboard-name>-icon-active.png
+
+Examples: 
+    If your dashboard name is `slice`
+    then you will add the images with the name as
+        `slice-icon.png`
+        `slice-icon-active.png`
+        
+        
+        
+        
+Note: If you don't add the custom images, then dashboard will use the default images stored at `/xos/core/xoslib/static/images`
\ No newline at end of file
diff --git a/views/ngXosViews/developer/src/index.html b/views/ngXosViews/developer/src/index.html
index f8946e9..e2dd2d0 100644
--- a/views/ngXosViews/developer/src/index.html
+++ b/views/ngXosViews/developer/src/index.html
@@ -5,6 +5,7 @@
 <!-- endbower -->
 <!-- endcss -->
 <!-- inject:css -->
+<link rel="stylesheet" href="/css/dev.css">
 <link rel="stylesheet" href="/css/main.css">
 <link rel="stylesheet" href="/../../../xos/core/static/xosNgLib.css">
 <!-- endinject -->
@@ -25,9 +26,11 @@
 <script src="vendor/bootstrap-css/js/bootstrap.min.js"></script>
 <script src="vendor/Chart.js/Chart.js"></script>
 <script src="vendor/angular-chart.js/dist/angular-chart.js"></script>
+<script src="vendor/d3/d3.js"></script>
+<script src="vendor/angular-recursion/angular-recursion.js"></script>
 <!-- endbower -->
 <!-- endjs -->
 <!-- inject:js -->
-<script src="/../../../xos/core/xoslib/static/js/vendor/ngXosHelpers.js"></script>
+<script src="/vendor/ng-xos-lib/dist/ngXosHelpers.min.js"></script>
 <script src="/.tmp/main.js"></script>
 <!-- endinject -->
\ No newline at end of file
diff --git a/views/ngXosViews/diagnostic/bower.json b/views/ngXosViews/diagnostic/bower.json
index 9279b8e..e5693ea 100644
--- a/views/ngXosViews/diagnostic/bower.json
+++ b/views/ngXosViews/diagnostic/bower.json
@@ -2,7 +2,7 @@
   "name": "xos-diagnostic",
   "version": "0.0.0",
   "authors": [
-    "Matteo Scandolo <teo@onlab.us>"
+    "Matteo Scandolo <matteo.scandolo@gmail.com>"
   ],
   "description": "The diagnostic view",
   "license": "MIT",
@@ -14,7 +14,8 @@
     "test",
     "tests"
   ],
-  "dependencies": {},
+  "dependencies": {
+  },
   "devDependencies": {
     "jquery": "2.1.4",
     "angular-mocks": "1.4.7",
@@ -26,9 +27,8 @@
     "lodash": "~4.11.1",
     "bootstrap-css": "3.3.6",
     "angular-chart.js": "~0.10.2",
-    "d3": "~3.5.17"
-  },
-  "resolutions": {
-    "angular": "1.4.7"
+    "d3": "~3.5.17",
+    "angular-recursion": "~1.0.5",
+    "ng-xos-lib": "opencord/ng-xos-lib#~1.0.0"
   }
 }
diff --git a/views/ngXosViews/diagnostic/gulp/build.js b/views/ngXosViews/diagnostic/gulp/build.js
index 20bbc14..716d301 100644
--- a/views/ngXosViews/diagnostic/gulp/build.js
+++ b/views/ngXosViews/diagnostic/gulp/build.js
@@ -41,7 +41,9 @@
     return del(
       [
         options.dashboards + 'xosDiagnostic.html',
-        options.static + 'css/xosDiagnostic.css'
+        options.static + 'css/xosDiagnostic.css',
+        options.static + 'images/diagnostic-icon.png',
+        options.static + 'images/diagnostic-icon-active.png'
       ],
       {force: true}
     );
@@ -70,6 +72,12 @@
     .pipe(gulp.dest(options.static + 'css/'))
   });
 
+  // copy images in correct folder
+  gulp.task('copyImages', ['wait'], function(){
+    return gulp.src([`${options.icon}/diagnostic-icon.png`,`${options.icon}/diagnostic-icon-active.png`])
+    .pipe(gulp.dest(options.static + 'images/'))
+  });
+
   // compile and minify scripts
   gulp.task('scripts', function() {
     return gulp.src([
@@ -104,7 +112,7 @@
       .pipe(
         inject(
           gulp.src([
-            options.static + 'js/vendor/xosDiagnosticVendor.js',
+            options.static + 'vendor/xosDiagnosticVendor.js',
             options.static + 'js/xosDiagnostic.js',
             options.static + 'css/xosDiagnostic.css'
           ]),
@@ -130,7 +138,7 @@
     return gulp.src(bowerDeps)
       .pipe(concat('xosDiagnosticVendor.js'))
       .pipe(uglify())
-      .pipe(gulp.dest(options.static + 'js/vendor/'));
+      .pipe(gulp.dest(options.static + 'vendor/'));
   });
 
   gulp.task('lint', function () {
@@ -157,6 +165,7 @@
       'wiredep',
       'css',
       'copyCss',
+      'copyImages',
       'copyHtml',
       'cleanTmp'
     );
diff --git a/views/ngXosViews/diagnostic/gulp/server.js b/views/ngXosViews/diagnostic/gulp/server.js
index fbc605b..36fdded 100644
--- a/views/ngXosViews/diagnostic/gulp/server.js
+++ b/views/ngXosViews/diagnostic/gulp/server.js
@@ -52,12 +52,10 @@
       server: {
         baseDir: options.src,
         routes: {
-          '/xos/core/xoslib/static/js/vendor': options.helpers,
           '/xos/core/static': options.static + '../../static/'
         },
         middleware: function(req, res, next){
           if(
-            req.url.indexOf('/?no_hyperlinks') !== -1 ||
             req.url.indexOf('/api/') !== -1
           ){
             if(conf.xoscsrftoken && conf.xossessionid){
@@ -116,7 +114,7 @@
         inject(
           gulp.src([
             options.tmp + '**/*.js',
-            options.helpers + 'ngXosHelpers.js'
+            options.helpers + 'ngXosHelpers.min.js'
           ])
           .pipe(angularFilesort()),
           {
diff --git a/views/ngXosViews/diagnostic/gulpfile.js b/views/ngXosViews/diagnostic/gulpfile.js
index 08df554..c825df8 100644
--- a/views/ngXosViews/diagnostic/gulpfile.js
+++ b/views/ngXosViews/diagnostic/gulpfile.js
@@ -6,12 +6,13 @@
 var options = {
   src: 'src/',
   css: 'src/css/',
+  icon: 'src/icons',
   sass: 'src/sass/',
   scripts: 'src/js/',
   tmp: 'src/.tmp',
   dist: 'dist/',
   api: '../../ngXosLib/api/',
-  helpers: '../../../xos/core/xoslib/static/js/vendor/',
+  helpers: './src/vendor/ng-xos-lib/dist/',
   static: '../../../xos/core/xoslib/static/', // this is the django static folder
   dashboards: '../../../xos/core/xoslib/dashboards/' // this is the django html folder
 };
diff --git a/views/ngXosViews/diagnostic/karma.conf.js b/views/ngXosViews/diagnostic/karma.conf.js
index 44283c8..e5abf39 100644
--- a/views/ngXosViews/diagnostic/karma.conf.js
+++ b/views/ngXosViews/diagnostic/karma.conf.js
@@ -26,8 +26,8 @@
 
     // list of files / patterns to load in the browser
     files: bowerComponents.concat([
-      '../../../xos/core/xoslib/static/js/vendor/ngXosVendor.js',
-      '../../../xos/core/xoslib/static/js/vendor/ngXosHelpers.js',
+      './src/vendor/ng-xos-lib/dist/ngXosVendor.min.js',
+      './src/vendor/ng-xos-lib/dist/ngXosHelpers.min.js',
       'src/js/main.js',
       'src/js/**/*.js',
       'spec/**/*.mock.js',
@@ -46,6 +46,7 @@
     preprocessors: {
       'src/js/**/*.js': ['babel'],
       'spec/**/*.test.js': ['babel'],
+      'spec/**/*.mock.js': ['babel'],
       'src/**/*.html': ['ng-html2js']
     },
 
diff --git a/views/ngXosViews/diagnostic/package.json b/views/ngXosViews/diagnostic/package.json
index e5437b9..d916ea0 100644
--- a/views/ngXosViews/diagnostic/package.json
+++ b/views/ngXosViews/diagnostic/package.json
@@ -1,5 +1,5 @@
 {
-  "name": "xos-serviceTopology",
+  "name": "xos-diagnostic",
   "version": "1.0.0",
   "description": "Angular Application for XOS, created with generator-xos",
   "scripts": {
@@ -8,8 +8,10 @@
     "dev": "NODE_ENV=mock gulp serve",
     "local": "NODE_ENV=local gulp serve",
     "server": "easy-mocker -c ./mocks/diagnostic.conf.json -d ./mocks/data",
+    "prebuild": "npm install && bower install",
     "build": "gulp",
     "test": "karma start",
+    "test:ci": "karma start --single-run",
     "lint": "eslint src/js/"
   },
   "keywords": [
diff --git a/views/ngXosViews/diagnostic/src/css/dev.css b/views/ngXosViews/diagnostic/src/css/dev.css
new file mode 100644
index 0000000..45ce372
--- /dev/null
+++ b/views/ngXosViews/diagnostic/src/css/dev.css
@@ -0,0 +1,5 @@
+#xosDiagnostic{
+  position: absolute;
+  top: 100px;
+  left: 200px;
+}
\ No newline at end of file
diff --git a/views/ngXosViews/diagnostic/src/css/main.css b/views/ngXosViews/diagnostic/src/css/main.css
index 1cf0848..07fe951 100644
--- a/views/ngXosViews/diagnostic/src/css/main.css
+++ b/views/ngXosViews/diagnostic/src/css/main.css
@@ -1,5 +1,6 @@
 /* CONTAINER */
 #xosDiagnostic, [ui-view] {
+  height: 100%;
   min-height: 700px;
   position: relative; }
 
diff --git a/views/ngXosViews/diagnostic/src/icons/README.md b/views/ngXosViews/diagnostic/src/icons/README.md
new file mode 100644
index 0000000..0d5a787
--- /dev/null
+++ b/views/ngXosViews/diagnostic/src/icons/README.md
@@ -0,0 +1,18 @@
+# Set icon for custom dashboard 
+
+## Path to add images : <dashboard-name>/src/icons
+
+### Add two images with name in following format 
+    <dashboard-name>-icon.png
+    <dashboard-name>-icon-active.png
+
+Examples: 
+    If your dashboard name is `slice`
+    then you will add the images with the name as
+        `slice-icon.png`
+        `slice-icon-active.png`
+        
+        
+        
+        
+Note: If you don't add the custom images, then dashboard will use the default images stored at `/xos/core/xoslib/static/images`
\ No newline at end of file
diff --git a/views/ngXosViews/diagnostic/src/index.html b/views/ngXosViews/diagnostic/src/index.html
index f91ebbb..b5c899e 100644
--- a/views/ngXosViews/diagnostic/src/index.html
+++ b/views/ngXosViews/diagnostic/src/index.html
@@ -4,6 +4,7 @@
 <link rel="stylesheet" href="vendor/angular-chart.js/dist/angular-chart.css" />
 <!-- endbower --><!-- endcss -->
 <!-- inject:css -->
+<link rel="stylesheet" href="/css/dev.css">
 <link rel="stylesheet" href="/css/main.css">
 <link rel="stylesheet" href="/../../../xos/core/static/xosNgLib.css">
 <!-- endinject -->
@@ -25,9 +26,10 @@
 <script src="vendor/Chart.js/Chart.js"></script>
 <script src="vendor/angular-chart.js/dist/angular-chart.js"></script>
 <script src="vendor/d3/d3.js"></script>
+<script src="vendor/angular-recursion/angular-recursion.js"></script>
 <!-- endbower --><!-- endjs -->
 <!-- inject:js -->
-<script src="/../../../xos/core/xoslib/static/js/vendor/ngXosHelpers.js"></script>
+<script src="/vendor/ng-xos-lib/dist/ngXosHelpers.min.js"></script>
 <script src="/.tmp/main.js"></script>
 <script src="/.tmp/subscriber-modal.js"></script>
 <script src="/.tmp/serviceTopologyHelper.js"></script>
diff --git a/views/ngXosViews/hpc/bower.json b/views/ngXosViews/hpc/bower.json
index 085650b..6538353 100644
--- a/views/ngXosViews/hpc/bower.json
+++ b/views/ngXosViews/hpc/bower.json
@@ -28,6 +28,7 @@
     "bootstrap-css": "3.3.6",
     "angular-chart.js": "~0.10.2",
     "d3": "~3.5.17",
-    "angular-recursion": "~1.0.5"
+    "angular-recursion": "~1.0.5",
+    "ng-xos-lib": "opencord/ng-xos-lib#~1.0.0"
   }
 }
diff --git a/views/ngXosViews/hpc/gulp/build.js b/views/ngXosViews/hpc/gulp/build.js
index 3cefc6b..64fdaf3 100644
--- a/views/ngXosViews/hpc/gulp/build.js
+++ b/views/ngXosViews/hpc/gulp/build.js
@@ -41,7 +41,9 @@
     return del(
       [
         options.dashboards + 'xosHpc.html',
-        options.static + 'css/xosHpc.css'
+        options.static + 'css/xosHpc.css',
+        options.static + 'images/hpc-icon.png',
+        options.static + 'images/hpc-icon-active.png'
       ],
       {force: true}
     );
@@ -70,6 +72,12 @@
     .pipe(gulp.dest(options.static + 'css/'))
   });
 
+  // copy images in correct folder
+  gulp.task('copyImages', ['wait'], function(){
+    return gulp.src([`${options.icon}/hpc-icon.png`,`${options.icon}/hpc-icon-active.png`])
+    .pipe(gulp.dest(options.static + 'images/'))
+  });
+
   // compile and minify scripts
   gulp.task('scripts', function() {
     return gulp.src([
@@ -104,7 +112,7 @@
       .pipe(
         inject(
           gulp.src([
-            options.static + 'js/vendor/xosHpcVendor.js',
+            options.static + 'vendor/xosHpcVendor.js',
             options.static + 'js/xosHpc.js',
             options.static + 'css/xosHpc.css'
           ]),
@@ -130,7 +138,7 @@
     return gulp.src(bowerDeps)
       .pipe(concat('xosHpcVendor.js'))
       .pipe(uglify())
-      .pipe(gulp.dest(options.static + 'js/vendor/'));
+      .pipe(gulp.dest(options.static + 'vendor/'));
   });
 
   gulp.task('lint', function () {
@@ -157,6 +165,7 @@
       'wiredep',
       'css',
       'copyCss',
+      'copyImages',
       'copyHtml',
       'cleanTmp'
     );
diff --git a/views/ngXosViews/hpc/gulp/server.js b/views/ngXosViews/hpc/gulp/server.js
index c748eb6..36fdded 100644
--- a/views/ngXosViews/hpc/gulp/server.js
+++ b/views/ngXosViews/hpc/gulp/server.js
@@ -52,13 +52,11 @@
       server: {
         baseDir: options.src,
         routes: {
-          '/xos/core/xoslib/static/js/vendor': options.helpers,
           '/xos/core/static': options.static + '../../static/'
         },
         middleware: function(req, res, next){
           if(
-            req.url.indexOf('/api/') !== -1,
-            req.url.indexOf('/xoslib/hpcview') !== -1
+            req.url.indexOf('/api/') !== -1
           ){
             if(conf.xoscsrftoken && conf.xossessionid){
               req.headers.cookie = `xoscsrftoken=${conf.xoscsrftoken}; xossessionid=${conf.xossessionid}`;
@@ -116,7 +114,7 @@
         inject(
           gulp.src([
             options.tmp + '**/*.js',
-            options.helpers + 'ngXosHelpers.js'
+            options.helpers + 'ngXosHelpers.min.js'
           ])
           .pipe(angularFilesort()),
           {
diff --git a/views/ngXosViews/hpc/gulpfile.js b/views/ngXosViews/hpc/gulpfile.js
index 08df554..c825df8 100644
--- a/views/ngXosViews/hpc/gulpfile.js
+++ b/views/ngXosViews/hpc/gulpfile.js
@@ -6,12 +6,13 @@
 var options = {
   src: 'src/',
   css: 'src/css/',
+  icon: 'src/icons',
   sass: 'src/sass/',
   scripts: 'src/js/',
   tmp: 'src/.tmp',
   dist: 'dist/',
   api: '../../ngXosLib/api/',
-  helpers: '../../../xos/core/xoslib/static/js/vendor/',
+  helpers: './src/vendor/ng-xos-lib/dist/',
   static: '../../../xos/core/xoslib/static/', // this is the django static folder
   dashboards: '../../../xos/core/xoslib/dashboards/' // this is the django html folder
 };
diff --git a/views/ngXosViews/hpc/karma.conf.js b/views/ngXosViews/hpc/karma.conf.js
index 4123be9..e5abf39 100644
--- a/views/ngXosViews/hpc/karma.conf.js
+++ b/views/ngXosViews/hpc/karma.conf.js
@@ -26,8 +26,9 @@
 
     // list of files / patterns to load in the browser
     files: bowerComponents.concat([
-      '../../../xos/core/xoslib/static/js/vendor/ngXosVendor.js',
-      '../../../xos/core/xoslib/static/js/vendor/ngXosHelpers.js',
+      './src/vendor/ng-xos-lib/dist/ngXosVendor.min.js',
+      './src/vendor/ng-xos-lib/dist/ngXosHelpers.min.js',
+      'src/js/main.js',
       'src/js/**/*.js',
       'spec/**/*.mock.js',
       'spec/**/*.test.js',
@@ -45,6 +46,7 @@
     preprocessors: {
       'src/js/**/*.js': ['babel'],
       'spec/**/*.test.js': ['babel'],
+      'spec/**/*.mock.js': ['babel'],
       'src/**/*.html': ['ng-html2js']
     },
 
diff --git a/views/ngXosViews/hpc/src/css/dev.css b/views/ngXosViews/hpc/src/css/dev.css
new file mode 100644
index 0000000..5b3694e
--- /dev/null
+++ b/views/ngXosViews/hpc/src/css/dev.css
@@ -0,0 +1,5 @@
+#xosHpc{
+  position: absolute;
+  top: 100px;
+  left: 200px;
+}
\ No newline at end of file
diff --git a/views/ngXosViews/hpc/src/icons/README.md b/views/ngXosViews/hpc/src/icons/README.md
new file mode 100644
index 0000000..0d5a787
--- /dev/null
+++ b/views/ngXosViews/hpc/src/icons/README.md
@@ -0,0 +1,18 @@
+# Set icon for custom dashboard 
+
+## Path to add images : <dashboard-name>/src/icons
+
+### Add two images with name in following format 
+    <dashboard-name>-icon.png
+    <dashboard-name>-icon-active.png
+
+Examples: 
+    If your dashboard name is `slice`
+    then you will add the images with the name as
+        `slice-icon.png`
+        `slice-icon-active.png`
+        
+        
+        
+        
+Note: If you don't add the custom images, then dashboard will use the default images stored at `/xos/core/xoslib/static/images`
\ No newline at end of file
diff --git a/views/ngXosViews/hpc/src/index.html b/views/ngXosViews/hpc/src/index.html
index c945c27..c583282 100644
--- a/views/ngXosViews/hpc/src/index.html
+++ b/views/ngXosViews/hpc/src/index.html
@@ -5,6 +5,7 @@
 <!-- endbower -->
 <!-- endcss -->
 <!-- inject:css -->
+<link rel="stylesheet" href="/css/dev.css">
 <link rel="stylesheet" href="/css/main.css">
 <link rel="stylesheet" href="/../../../xos/core/static/xosNgLib.css">
 <!-- endinject -->
@@ -30,6 +31,6 @@
 <!-- endbower -->
 <!-- endjs -->
 <!-- inject:js -->
-<script src="/../../../xos/core/xoslib/static/js/vendor/ngXosHelpers.js"></script>
+<script src="/vendor/ng-xos-lib/dist/ngXosHelpers.min.js"></script>
 <script src="/.tmp/main.js"></script>
 <!-- endinject -->
\ No newline at end of file
diff --git a/views/ngXosViews/hpc/src/templates/users-list.tpl.html b/views/ngXosViews/hpc/src/templates/users-list.tpl.html
new file mode 100644
index 0000000..1fee0e2
--- /dev/null
+++ b/views/ngXosViews/hpc/src/templates/users-list.tpl.html
@@ -0,0 +1 @@
+<xos-table config="vm.tableConfig" data="vm.users"></xos-table>
\ No newline at end of file
diff --git a/views/ngXosViews/mcordTopology/bower.json b/views/ngXosViews/mcordTopology/bower.json
index ed83aa4..c647403 100644
--- a/views/ngXosViews/mcordTopology/bower.json
+++ b/views/ngXosViews/mcordTopology/bower.json
@@ -2,7 +2,7 @@
   "name": "xos-mcordTopology",
   "version": "0.0.0",
   "authors": [
-    "Matteo Scandolo <teo@onlab.us>"
+    "Matteo Scandolo <matteo.scandolo@gmail.com>"
   ],
   "description": "The mcordTopology view",
   "license": "MIT",
@@ -15,7 +15,6 @@
     "tests"
   ],
   "dependencies": {
-    "d3": "~3.5.16"
   },
   "devDependencies": {
     "jquery": "2.1.4",
@@ -23,8 +22,13 @@
     "angular": "1.4.7",
     "angular-ui-router": "0.2.15",
     "angular-cookies": "1.4.7",
+    "angular-animate": "1.4.7",
     "angular-resource": "1.4.7",
-    "lodash": "^3.10.1",
-    "bootstrap-css": "2.3.2"
+    "lodash": "~4.11.1",
+    "bootstrap-css": "3.3.6",
+    "angular-chart.js": "~0.10.2",
+    "d3": "~3.5.17",
+    "angular-recursion": "~1.0.5",
+    "ng-xos-lib": "opencord/ng-xos-lib#~1.0.0"
   }
 }
diff --git a/views/ngXosViews/mcordTopology/gulp/build.js b/views/ngXosViews/mcordTopology/gulp/build.js
index afc12dd..f4c5534 100644
--- a/views/ngXosViews/mcordTopology/gulp/build.js
+++ b/views/ngXosViews/mcordTopology/gulp/build.js
@@ -41,7 +41,9 @@
     return del(
       [
         options.dashboards + 'xosMcordTopology.html',
-        options.static + 'css/xosMcordTopology.css'
+        options.static + 'css/xosMcordTopology.css',
+        options.static + 'images/mcordTopology-icon.png',
+        options.static + 'images/mcordTopology-icon-active.png'
       ],
       {force: true}
     );
@@ -70,6 +72,12 @@
     .pipe(gulp.dest(options.static + 'css/'))
   });
 
+  // copy images in correct folder
+  gulp.task('copyImages', ['wait'], function(){
+    return gulp.src([`${options.icon}/mcordTopology-icon.png`,`${options.icon}/mcordTopology-icon-active.png`])
+    .pipe(gulp.dest(options.static + 'images/'))
+  });
+
   // compile and minify scripts
   gulp.task('scripts', function() {
     return gulp.src([
@@ -98,13 +106,13 @@
   gulp.task('copyHtml', function(){
     return gulp.src(options.src + 'index.html')
       // remove dev dependencies from html
-      .pipe(replace(/<!-- bower:css -->(\n.*)*\n<!-- endbower --><!-- endcss -->/, ''))
-      .pipe(replace(/<!-- bower:js -->(\n.*)*\n<!-- endbower --><!-- endjs -->/, ''))
+      .pipe(replace(/<!-- bower:css -->(\n^<link.*)*\n<!-- endbower -->/gmi, ''))
+      .pipe(replace(/<!-- bower:js -->(\n^<script.*)*\n<!-- endbower -->/gmi, ''))
       // injecting minified files
       .pipe(
         inject(
           gulp.src([
-            options.static + 'js/vendor/xosMcordTopologyVendor.js',
+            options.static + 'vendor/xosMcordTopologyVendor.js',
             options.static + 'js/xosMcordTopology.js',
             options.static + 'css/xosMcordTopology.css'
           ]),
@@ -130,7 +138,7 @@
     return gulp.src(bowerDeps)
       .pipe(concat('xosMcordTopologyVendor.js'))
       .pipe(uglify())
-      .pipe(gulp.dest(options.static + 'js/vendor/'));
+      .pipe(gulp.dest(options.static + 'vendor/'));
   });
 
   gulp.task('lint', function () {
@@ -150,12 +158,14 @@
   gulp.task('build', function() {
     runSequence(
       'clean',
+      'sass',
       'templates',
       'babel',
       'scripts',
       'wiredep',
       'css',
       'copyCss',
+      'copyImages',
       'copyHtml',
       'cleanTmp'
     );
diff --git a/views/ngXosViews/mcordTopology/gulp/server.js b/views/ngXosViews/mcordTopology/gulp/server.js
index 167a5a9..0ffef89 100644
--- a/views/ngXosViews/mcordTopology/gulp/server.js
+++ b/views/ngXosViews/mcordTopology/gulp/server.js
@@ -10,18 +10,24 @@
 var httpProxy = require('http-proxy');
 var del = require('del');
 var sass = require('gulp-sass');
+var fs = require('fs');
+var path = require('path');
 
 const environment = process.env.NODE_ENV;
 
-if (environment){
-  var conf = require(`../env/${environment}.js`);
-}
-else{
-  var conf = require('../env/default.js')
+if(!fs.existsSync(path.join(__dirname, `../../../env/${environment || 'default'}.js`))){
+  if(!environment){
+    throw new Error('You should define a default.js config in /views/env folder.');
+  }
+  else{
+    throw new Error(`Since you are loading a custom environment, you should define a ${environment}.js config in /views/env folder.`);
+  }
 }
 
+var conf = require(path.join(__dirname, `../../../env/${environment || 'default'}.js`));
+
 var proxy = httpProxy.createProxyServer({
-  target: conf.host || 'http://0.0.0.0:9999'
+  target: conf.host
 });
 
 
@@ -35,12 +41,8 @@
 
 module.exports = function(options){
 
-  // open in browser with sync and proxy to 0.0.0.0
   gulp.task('browser', function() {
     browserSync.init({
-      // reloadDelay: 500,
-      // logLevel: 'debug',
-      // logConnections: true,
       startPath: '#/',
       snippetOptions: {
         rule: {
@@ -50,7 +52,7 @@
       server: {
         baseDir: options.src,
         routes: {
-          '/xos/core/xoslib/static/js/vendor': options.helpers
+          '/xos/core/static': options.static + '../../static/'
         },
         middleware: function(req, res, next){
           if(
@@ -86,6 +88,13 @@
     gulp.watch(`${options.sass}/**/*.scss`, ['sass'], function(){
       browserSync.reload();
     });
+
+    gulp.watch([
+      options.helpers + 'ngXosHelpers.js',
+      options.static + '../../static/xosNgLib.css'
+    ], function(){
+      browserSync.reload();
+    });
   });
 
   // compile sass
@@ -109,7 +118,7 @@
         inject(
           gulp.src([
             options.tmp + '**/*.js',
-            options.helpers + 'ngXosHelpers.js'
+            options.helpers + 'ngXosHelpers.min.js'
           ])
           .pipe(angularFilesort()),
           {
@@ -125,7 +134,10 @@
     return gulp.src(options.src + 'index.html')
       .pipe(
         inject(
-          gulp.src(options.src + 'css/*.css'),
+          gulp.src([
+            options.src + 'css/*.css',
+            options.static + '../../static/xosNgLib.css'
+          ]),
           {
             ignorePath: [options.src]
           }
diff --git a/views/ngXosViews/mcordTopology/gulpfile.js b/views/ngXosViews/mcordTopology/gulpfile.js
index 08df554..c825df8 100644
--- a/views/ngXosViews/mcordTopology/gulpfile.js
+++ b/views/ngXosViews/mcordTopology/gulpfile.js
@@ -6,12 +6,13 @@
 var options = {
   src: 'src/',
   css: 'src/css/',
+  icon: 'src/icons',
   sass: 'src/sass/',
   scripts: 'src/js/',
   tmp: 'src/.tmp',
   dist: 'dist/',
   api: '../../ngXosLib/api/',
-  helpers: '../../../xos/core/xoslib/static/js/vendor/',
+  helpers: './src/vendor/ng-xos-lib/dist/',
   static: '../../../xos/core/xoslib/static/', // this is the django static folder
   dashboards: '../../../xos/core/xoslib/dashboards/' // this is the django html folder
 };
diff --git a/views/ngXosViews/mcordTopology/karma.conf.js b/views/ngXosViews/mcordTopology/karma.conf.js
index 4123be9..e5abf39 100644
--- a/views/ngXosViews/mcordTopology/karma.conf.js
+++ b/views/ngXosViews/mcordTopology/karma.conf.js
@@ -26,8 +26,9 @@
 
     // list of files / patterns to load in the browser
     files: bowerComponents.concat([
-      '../../../xos/core/xoslib/static/js/vendor/ngXosVendor.js',
-      '../../../xos/core/xoslib/static/js/vendor/ngXosHelpers.js',
+      './src/vendor/ng-xos-lib/dist/ngXosVendor.min.js',
+      './src/vendor/ng-xos-lib/dist/ngXosHelpers.min.js',
+      'src/js/main.js',
       'src/js/**/*.js',
       'spec/**/*.mock.js',
       'spec/**/*.test.js',
@@ -45,6 +46,7 @@
     preprocessors: {
       'src/js/**/*.js': ['babel'],
       'spec/**/*.test.js': ['babel'],
+      'spec/**/*.mock.js': ['babel'],
       'src/**/*.html': ['ng-html2js']
     },
 
diff --git a/views/ngXosViews/mcordTopology/src/icons/README.md b/views/ngXosViews/mcordTopology/src/icons/README.md
new file mode 100644
index 0000000..0d5a787
--- /dev/null
+++ b/views/ngXosViews/mcordTopology/src/icons/README.md
@@ -0,0 +1,18 @@
+# Set icon for custom dashboard 
+
+## Path to add images : <dashboard-name>/src/icons
+
+### Add two images with name in following format 
+    <dashboard-name>-icon.png
+    <dashboard-name>-icon-active.png
+
+Examples: 
+    If your dashboard name is `slice`
+    then you will add the images with the name as
+        `slice-icon.png`
+        `slice-icon-active.png`
+        
+        
+        
+        
+Note: If you don't add the custom images, then dashboard will use the default images stored at `/xos/core/xoslib/static/images`
\ No newline at end of file
diff --git a/views/ngXosViews/mcordTopology/src/index.html b/views/ngXosViews/mcordTopology/src/index.html
index d8985de..8b8c714 100644
--- a/views/ngXosViews/mcordTopology/src/index.html
+++ b/views/ngXosViews/mcordTopology/src/index.html
@@ -1,11 +1,13 @@
 <!-- browserSync -->
 <!-- bower:css -->
-<link rel="stylesheet" href="vendor/bootstrap-css/css/bootstrap.css" />
+<link rel="stylesheet" href="vendor/bootstrap-css/css/bootstrap.min.css" />
+<link rel="stylesheet" href="vendor/angular-chart.js/dist/angular-chart.css" />
 <!-- endbower --><!-- endcss -->
 <!-- inject:css -->
 <link rel="stylesheet" href="/css/dev.css">
 <link rel="stylesheet" href="/css/main.css">
 <link rel="stylesheet" href="/css/mcord.css">
+<link rel="stylesheet" href="/../../../xos/core/static/xosNgLib.css">
 <!-- endinject -->
 
 <div ng-app="xos.mcordTopology" id="xosMcordTopology" class="container-fluid">
@@ -13,18 +15,22 @@
 </div>
 
 <!-- bower:js -->
-<script src="vendor/d3/d3.js"></script>
 <script src="vendor/jquery/dist/jquery.js"></script>
 <script src="vendor/angular/angular.js"></script>
 <script src="vendor/angular-mocks/angular-mocks.js"></script>
 <script src="vendor/angular-ui-router/release/angular-ui-router.js"></script>
 <script src="vendor/angular-cookies/angular-cookies.js"></script>
+<script src="vendor/angular-animate/angular-animate.js"></script>
 <script src="vendor/angular-resource/angular-resource.js"></script>
 <script src="vendor/lodash/lodash.js"></script>
-<script src="vendor/bootstrap-css/js/bootstrap.js"></script>
+<script src="vendor/bootstrap-css/js/bootstrap.min.js"></script>
+<script src="vendor/Chart.js/Chart.js"></script>
+<script src="vendor/angular-chart.js/dist/angular-chart.js"></script>
+<script src="vendor/d3/d3.js"></script>
+<script src="vendor/angular-recursion/angular-recursion.js"></script>
 <!-- endbower --><!-- endjs -->
 <!-- inject:js -->
-<script src="/../../../xos/core/xoslib/static/js/vendor/ngXosHelpers.js"></script>
+<script src="/vendor/ng-xos-lib/dist/ngXosHelpers.min.js"></script>
 <script src="/.tmp/main.js"></script>
 <script src="/.tmp/static.data.js"></script>
 <script src="/.tmp/node_drawer.js"></script>
diff --git a/views/ngXosViews/openVPNDashboard/bower.json b/views/ngXosViews/openVPNDashboard/bower.json
index 66d7af1..33cdb88 100644
--- a/views/ngXosViews/openVPNDashboard/bower.json
+++ b/views/ngXosViews/openVPNDashboard/bower.json
@@ -2,10 +2,10 @@
   "name": "xos-openVPNDashboard",
   "version": "0.0.0",
   "authors": [
-    "Matteo Scandolo <teo@onlab.us>"
+    "Jeremy Mowery <jermowery@email.arizona.edu>"
   ],
   "description": "The openVPNDashboard view",
-  "license": "MIT",
+  "license": "Apache-2.0",
   "ignore": [
     "**/.*",
     "node_modules",
@@ -14,8 +14,7 @@
     "test",
     "tests"
   ],
-  "dependencies": {
-  },
+  "dependencies": {},
   "devDependencies": {
     "jquery": "2.1.4",
     "angular-mocks": "1.4.7",
@@ -27,6 +26,9 @@
     "lodash": "~4.11.1",
     "bootstrap-css": "3.3.6",
     "angular-chart.js": "~0.10.2",
-    "d3": "~3.5.17"
+    "d3": "~3.5.17",
+    "angular-recursion": "~1.0.5",
+    "ng-xos-lib": "opencord/ng-xos-lib#~1.0.0",
+    "Blob.js": "eligrey/Blob.js"
   }
 }
diff --git a/views/ngXosViews/openVPNDashboard/gulp/build.js b/views/ngXosViews/openVPNDashboard/gulp/build.js
index 33a2cac..26fc1fe 100644
--- a/views/ngXosViews/openVPNDashboard/gulp/build.js
+++ b/views/ngXosViews/openVPNDashboard/gulp/build.js
@@ -41,7 +41,9 @@
     return del(
       [
         options.dashboards + 'xosOpenVPNDashboard.html',
-        options.static + 'css/xosOpenVPNDashboard.css'
+        options.static + 'css/xosOpenVPNDashboard.css',
+        options.static + 'images/openVPNDashboard-icon.png',
+        options.static + 'images/openVPNDashboard-icon-active.png'
       ],
       {force: true}
     );
@@ -70,6 +72,12 @@
     .pipe(gulp.dest(options.static + 'css/'))
   });
 
+  // copy images in correct folder
+  gulp.task('copyImages', ['wait'], function(){
+    return gulp.src([`${options.icon}/openVPNDashboard-icon.png`,`${options.icon}/openVPNDashboard-icon-active.png`])
+    .pipe(gulp.dest(options.static + 'images/'))
+  });
+
   // compile and minify scripts
   gulp.task('scripts', function() {
     return gulp.src([
@@ -104,7 +112,7 @@
       .pipe(
         inject(
           gulp.src([
-            options.static + 'js/vendor/xosOpenVPNDashboardVendor.js',
+            options.static + 'vendor/xosOpenVPNDashboardVendor.js',
             options.static + 'js/xosOpenVPNDashboard.js',
             options.static + 'css/xosOpenVPNDashboard.css'
           ]),
@@ -130,7 +138,7 @@
     return gulp.src(bowerDeps)
       .pipe(concat('xosOpenVPNDashboardVendor.js'))
       .pipe(uglify())
-      .pipe(gulp.dest(options.static + 'js/vendor/'));
+      .pipe(gulp.dest(options.static + 'vendor/'));
   });
 
   gulp.task('lint', function () {
@@ -157,6 +165,7 @@
       'wiredep',
       'css',
       'copyCss',
+      'copyImages',
       'copyHtml',
       'cleanTmp'
     );
diff --git a/views/ngXosViews/openVPNDashboard/gulp/server.js b/views/ngXosViews/openVPNDashboard/gulp/server.js
index 1e40a34..36fdded 100644
--- a/views/ngXosViews/openVPNDashboard/gulp/server.js
+++ b/views/ngXosViews/openVPNDashboard/gulp/server.js
@@ -52,7 +52,6 @@
       server: {
         baseDir: options.src,
         routes: {
-          '/xos/core/xoslib/static/js/vendor': options.helpers,
           '/xos/core/static': options.static + '../../static/'
         },
         middleware: function(req, res, next){
@@ -115,7 +114,7 @@
         inject(
           gulp.src([
             options.tmp + '**/*.js',
-            options.helpers + 'ngXosHelpers.js'
+            options.helpers + 'ngXosHelpers.min.js'
           ])
           .pipe(angularFilesort()),
           {
diff --git a/views/ngXosViews/openVPNDashboard/gulpfile.js b/views/ngXosViews/openVPNDashboard/gulpfile.js
index 08df554..c825df8 100644
--- a/views/ngXosViews/openVPNDashboard/gulpfile.js
+++ b/views/ngXosViews/openVPNDashboard/gulpfile.js
@@ -6,12 +6,13 @@
 var options = {
   src: 'src/',
   css: 'src/css/',
+  icon: 'src/icons',
   sass: 'src/sass/',
   scripts: 'src/js/',
   tmp: 'src/.tmp',
   dist: 'dist/',
   api: '../../ngXosLib/api/',
-  helpers: '../../../xos/core/xoslib/static/js/vendor/',
+  helpers: './src/vendor/ng-xos-lib/dist/',
   static: '../../../xos/core/xoslib/static/', // this is the django static folder
   dashboards: '../../../xos/core/xoslib/dashboards/' // this is the django html folder
 };
diff --git a/views/ngXosViews/openVPNDashboard/karma.conf.js b/views/ngXosViews/openVPNDashboard/karma.conf.js
index 4123be9..90d1ed0 100644
--- a/views/ngXosViews/openVPNDashboard/karma.conf.js
+++ b/views/ngXosViews/openVPNDashboard/karma.conf.js
@@ -11,6 +11,9 @@
   return path.relative(process.cwd(), file);
 });
 
+// add Blob polyfill for Phantom.js
+bowerComponents.push('src/vendor/Blob.js/Blob.js');
+
 module.exports = function(config) {
 /*eslint-enable*/
   config.set({
@@ -26,8 +29,9 @@
 
     // list of files / patterns to load in the browser
     files: bowerComponents.concat([
-      '../../../xos/core/xoslib/static/js/vendor/ngXosVendor.js',
-      '../../../xos/core/xoslib/static/js/vendor/ngXosHelpers.js',
+      './src/vendor/ng-xos-lib/dist/ngXosVendor.min.js',
+      './src/vendor/ng-xos-lib/dist/ngXosHelpers.min.js',
+      'src/js/main.js',
       'src/js/**/*.js',
       'spec/**/*.mock.js',
       'spec/**/*.test.js',
@@ -45,6 +49,7 @@
     preprocessors: {
       'src/js/**/*.js': ['babel'],
       'spec/**/*.test.js': ['babel'],
+      'spec/**/*.mock.js': ['babel'],
       'src/**/*.html': ['ng-html2js']
     },
 
diff --git a/views/ngXosViews/openVPNDashboard/package.json b/views/ngXosViews/openVPNDashboard/package.json
index 093c76d..09631e4 100644
--- a/views/ngXosViews/openVPNDashboard/package.json
+++ b/views/ngXosViews/openVPNDashboard/package.json
@@ -16,8 +16,8 @@
     "Angular",
     "XOSlib"
   ],
-  "author": "Matteo Scandolo",
-  "license": "MIT",
+  "author": "Jeremy Mowery",
+  "license": "Apache-2.0",
   "dependencies": {},
   "devDependencies": {
     "autoprefixer": "^6.3.3",
diff --git a/views/ngXosViews/openVPNDashboard/spec/sample.test.js b/views/ngXosViews/openVPNDashboard/spec/sample.test.js
index 522ce75..0f49ff3 100644
--- a/views/ngXosViews/openVPNDashboard/spec/sample.test.js
+++ b/views/ngXosViews/openVPNDashboard/spec/sample.test.js
@@ -15,7 +15,7 @@
       {
         email: 'jermowery@email.arizona.edu',
         firstname: 'Jeremy',
-        lastname: 'Mowery' 
+        lastname: 'Mowery'
       }
     ]);
   
diff --git a/views/ngXosViews/openVPNDashboard/src/css/dev.css b/views/ngXosViews/openVPNDashboard/src/css/dev.css
new file mode 100644
index 0000000..557a343
--- /dev/null
+++ b/views/ngXosViews/openVPNDashboard/src/css/dev.css
@@ -0,0 +1,5 @@
+#xosOpenVPNDashboard{
+  position: absolute;
+  top: 100px;
+  left: 200px;
+}
\ No newline at end of file
diff --git a/views/ngXosViews/openVPNDashboard/src/icons/README.md b/views/ngXosViews/openVPNDashboard/src/icons/README.md
new file mode 100644
index 0000000..0d5a787
--- /dev/null
+++ b/views/ngXosViews/openVPNDashboard/src/icons/README.md
@@ -0,0 +1,18 @@
+# Set icon for custom dashboard 
+
+## Path to add images : <dashboard-name>/src/icons
+
+### Add two images with name in following format 
+    <dashboard-name>-icon.png
+    <dashboard-name>-icon-active.png
+
+Examples: 
+    If your dashboard name is `slice`
+    then you will add the images with the name as
+        `slice-icon.png`
+        `slice-icon-active.png`
+        
+        
+        
+        
+Note: If you don't add the custom images, then dashboard will use the default images stored at `/xos/core/xoslib/static/images`
\ No newline at end of file
diff --git a/views/ngXosViews/openVPNDashboard/src/index.html b/views/ngXosViews/openVPNDashboard/src/index.html
index 8a97f14..2f1ac8f 100644
--- a/views/ngXosViews/openVPNDashboard/src/index.html
+++ b/views/ngXosViews/openVPNDashboard/src/index.html
@@ -4,6 +4,7 @@
 <link rel="stylesheet" href="vendor/angular-chart.js/dist/angular-chart.css" />
 <!-- endbower --><!-- endcss -->
 <!-- inject:css -->
+<link rel="stylesheet" href="/css/dev.css">
 <link rel="stylesheet" href="/css/main.css">
 <link rel="stylesheet" href="/../../../xos/core/static/xosNgLib.css">
 <!-- endinject -->
@@ -25,8 +26,9 @@
 <script src="vendor/Chart.js/Chart.js"></script>
 <script src="vendor/angular-chart.js/dist/angular-chart.js"></script>
 <script src="vendor/d3/d3.js"></script>
+<script src="vendor/angular-recursion/angular-recursion.js"></script>
 <!-- endbower --><!-- endjs -->
 <!-- inject:js -->
-<script src="/../../../xos/core/xoslib/static/js/vendor/ngXosHelpers.js"></script>
+<script src="/vendor/ng-xos-lib/dist/ngXosHelpers.min.js"></script>
 <script src="/.tmp/main.js"></script>
 <!-- endinject -->
diff --git a/views/ngXosViews/serviceGrid/bower.json b/views/ngXosViews/serviceGrid/bower.json
index 941c8db..b6a6a31 100644
--- a/views/ngXosViews/serviceGrid/bower.json
+++ b/views/ngXosViews/serviceGrid/bower.json
@@ -2,10 +2,10 @@
   "name": "xos-serviceGrid",
   "version": "0.0.0",
   "authors": [
-    "Matteo Scandolo <teo@onlab.us>"
+    "Matteo Scandolo <matteo.scandolo@gmail.com>"
   ],
   "description": "The serviceGrid view",
-  "license": "MIT",
+  "license": "Apache-2.0",
   "ignore": [
     "**/.*",
     "node_modules",
@@ -32,9 +32,7 @@
     "bootstrap-css": "3.3.6",
     "angular-chart.js": "~0.10.2",
     "d3": "~3.5.17",
-    "angular-recursion": "~1.0.5"
-  },
-  "resolutions": {
-    "lodash": "~4.11.1"
+    "angular-recursion": "~1.0.5",
+    "ng-xos-lib": "opencord/ng-xos-lib#~1.0.0"
   }
 }
diff --git a/views/ngXosViews/serviceGrid/gulp/build.js b/views/ngXosViews/serviceGrid/gulp/build.js
index 2916028..471136b 100644
--- a/views/ngXosViews/serviceGrid/gulp/build.js
+++ b/views/ngXosViews/serviceGrid/gulp/build.js
@@ -41,7 +41,9 @@
     return del(
       [
         options.dashboards + 'xosServiceGrid.html',
-        options.static + 'css/xosServiceGrid.css'
+        options.static + 'css/xosServiceGrid.css',
+        options.static + 'images/serviceGrid-icon.png',
+        options.static + 'images/serviceGrid-icon-active.png'
       ],
       {force: true}
     );
@@ -70,6 +72,12 @@
     .pipe(gulp.dest(options.static + 'css/'))
   });
 
+  // copy images in correct folder
+  gulp.task('copyImages', ['wait'], function(){
+    return gulp.src([`${options.icon}/serviceGrid-icon.png`,`${options.icon}/serviceGrid-icon-active.png`])
+    .pipe(gulp.dest(options.static + 'images/'))
+  });
+
   // compile and minify scripts
   gulp.task('scripts', function() {
     return gulp.src([
@@ -104,7 +112,7 @@
       .pipe(
         inject(
           gulp.src([
-            options.static + 'js/vendor/xosServiceGridVendor.js',
+            options.static + 'vendor/xosServiceGridVendor.js',
             options.static + 'js/xosServiceGrid.js',
             options.static + 'css/xosServiceGrid.css'
           ]),
@@ -130,7 +138,7 @@
     return gulp.src(bowerDeps)
       .pipe(concat('xosServiceGridVendor.js'))
       .pipe(uglify())
-      .pipe(gulp.dest(options.static + 'js/vendor/'));
+      .pipe(gulp.dest(options.static + 'vendor/'));
   });
 
   gulp.task('lint', function () {
@@ -157,6 +165,7 @@
       'wiredep',
       'css',
       'copyCss',
+      'copyImages',
       'copyHtml',
       'cleanTmp'
     );
diff --git a/views/ngXosViews/serviceGrid/gulp/server.js b/views/ngXosViews/serviceGrid/gulp/server.js
index 1e40a34..36fdded 100644
--- a/views/ngXosViews/serviceGrid/gulp/server.js
+++ b/views/ngXosViews/serviceGrid/gulp/server.js
@@ -52,7 +52,6 @@
       server: {
         baseDir: options.src,
         routes: {
-          '/xos/core/xoslib/static/js/vendor': options.helpers,
           '/xos/core/static': options.static + '../../static/'
         },
         middleware: function(req, res, next){
@@ -115,7 +114,7 @@
         inject(
           gulp.src([
             options.tmp + '**/*.js',
-            options.helpers + 'ngXosHelpers.js'
+            options.helpers + 'ngXosHelpers.min.js'
           ])
           .pipe(angularFilesort()),
           {
diff --git a/views/ngXosViews/serviceGrid/gulpfile.js b/views/ngXosViews/serviceGrid/gulpfile.js
index 08df554..c825df8 100644
--- a/views/ngXosViews/serviceGrid/gulpfile.js
+++ b/views/ngXosViews/serviceGrid/gulpfile.js
@@ -6,12 +6,13 @@
 var options = {
   src: 'src/',
   css: 'src/css/',
+  icon: 'src/icons',
   sass: 'src/sass/',
   scripts: 'src/js/',
   tmp: 'src/.tmp',
   dist: 'dist/',
   api: '../../ngXosLib/api/',
-  helpers: '../../../xos/core/xoslib/static/js/vendor/',
+  helpers: './src/vendor/ng-xos-lib/dist/',
   static: '../../../xos/core/xoslib/static/', // this is the django static folder
   dashboards: '../../../xos/core/xoslib/dashboards/' // this is the django html folder
 };
diff --git a/views/ngXosViews/serviceGrid/karma.conf.js b/views/ngXosViews/serviceGrid/karma.conf.js
index 44283c8..e5abf39 100644
--- a/views/ngXosViews/serviceGrid/karma.conf.js
+++ b/views/ngXosViews/serviceGrid/karma.conf.js
@@ -26,8 +26,8 @@
 
     // list of files / patterns to load in the browser
     files: bowerComponents.concat([
-      '../../../xos/core/xoslib/static/js/vendor/ngXosVendor.js',
-      '../../../xos/core/xoslib/static/js/vendor/ngXosHelpers.js',
+      './src/vendor/ng-xos-lib/dist/ngXosVendor.min.js',
+      './src/vendor/ng-xos-lib/dist/ngXosHelpers.min.js',
       'src/js/main.js',
       'src/js/**/*.js',
       'spec/**/*.mock.js',
@@ -46,6 +46,7 @@
     preprocessors: {
       'src/js/**/*.js': ['babel'],
       'spec/**/*.test.js': ['babel'],
+      'spec/**/*.mock.js': ['babel'],
       'src/**/*.html': ['ng-html2js']
     },
 
diff --git a/views/ngXosViews/serviceGrid/package.json b/views/ngXosViews/serviceGrid/package.json
index 130737b..4259a36 100644
--- a/views/ngXosViews/serviceGrid/package.json
+++ b/views/ngXosViews/serviceGrid/package.json
@@ -18,7 +18,7 @@
     "XOSlib"
   ],
   "author": "Matteo Scandolo",
-  "license": "MIT",
+  "license": "Apache-2.0",
   "dependencies": {},
   "devDependencies": {
     "autoprefixer": "^6.3.3",
diff --git a/views/ngXosViews/serviceGrid/src/css/dev.css b/views/ngXosViews/serviceGrid/src/css/dev.css
new file mode 100644
index 0000000..b833a9f
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/css/dev.css
@@ -0,0 +1,5 @@
+#xosServiceGrid{
+  position: absolute;
+  top: 100px;
+  left: 200px;
+}
\ No newline at end of file
diff --git a/views/ngXosViews/serviceGrid/src/icons/README.md b/views/ngXosViews/serviceGrid/src/icons/README.md
new file mode 100644
index 0000000..0d5a787
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/icons/README.md
@@ -0,0 +1,18 @@
+# Set icon for custom dashboard 
+
+## Path to add images : <dashboard-name>/src/icons
+
+### Add two images with name in following format 
+    <dashboard-name>-icon.png
+    <dashboard-name>-icon-active.png
+
+Examples: 
+    If your dashboard name is `slice`
+    then you will add the images with the name as
+        `slice-icon.png`
+        `slice-icon-active.png`
+        
+        
+        
+        
+Note: If you don't add the custom images, then dashboard will use the default images stored at `/xos/core/xoslib/static/images`
\ No newline at end of file
diff --git a/views/ngXosViews/serviceGrid/src/index.html b/views/ngXosViews/serviceGrid/src/index.html
index 0e3fa40..0058e98 100644
--- a/views/ngXosViews/serviceGrid/src/index.html
+++ b/views/ngXosViews/serviceGrid/src/index.html
@@ -5,6 +5,7 @@
 <!-- endbower -->
 <!-- endcss -->
 <!-- inject:css -->
+<link rel="stylesheet" href="/css/dev.css">
 <link rel="stylesheet" href="/css/main.css">
 <link rel="stylesheet" href="/css/side-panel.css">
 <link rel="stylesheet" href="/../../../xos/core/static/xosNgLib.css">
@@ -35,7 +36,7 @@
 <!-- endbower -->
 <!-- endjs -->
 <!-- inject:js -->
-<script src="/../../../xos/core/xoslib/static/js/vendor/ngXosHelpers.js"></script>
+<script src="/vendor/ng-xos-lib/dist/ngXosHelpers.min.js"></script>
 <script src="/.tmp/main.js"></script>
 <script src="/.tmp/tosca_encoder.service.js"></script>
 <script src="/.tmp/slices_encorder.service.js"></script>
diff --git a/views/ngXosViews/serviceGrid/src/templates/users-list.tpl.html b/views/ngXosViews/serviceGrid/src/templates/users-list.tpl.html
new file mode 100644
index 0000000..1fee0e2
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/templates/users-list.tpl.html
@@ -0,0 +1 @@
+<xos-table config="vm.tableConfig" data="vm.users"></xos-table>
\ No newline at end of file
diff --git a/views/ngXosViews/subscribers/bower.json b/views/ngXosViews/subscribers/bower.json
index 2fb2dab..542ffeb 100644
--- a/views/ngXosViews/subscribers/bower.json
+++ b/views/ngXosViews/subscribers/bower.json
@@ -5,7 +5,7 @@
     "Matteo Scandolo <matteo.scandolo@gmail.com>"
   ],
   "description": "The subscribers view",
-  "license": "MIT",
+  "license": "Apache-2.0",
   "ignore": [
     "**/.*",
     "node_modules",
@@ -14,7 +14,8 @@
     "test",
     "tests"
   ],
-  "dependencies": {},
+  "dependencies": {
+  },
   "devDependencies": {
     "jquery": "2.1.4",
     "angular-mocks": "1.4.7",
@@ -27,6 +28,7 @@
     "bootstrap-css": "3.3.6",
     "angular-chart.js": "~0.10.2",
     "d3": "~3.5.17",
-    "angular-recursion": "~1.0.5"
+    "angular-recursion": "~1.0.5",
+    "ng-xos-lib": "opencord/ng-xos-lib#~1.0.0"
   }
 }
diff --git a/views/ngXosViews/subscribers/gulp/build.js b/views/ngXosViews/subscribers/gulp/build.js
index 7f446ed..a23d5be 100644
--- a/views/ngXosViews/subscribers/gulp/build.js
+++ b/views/ngXosViews/subscribers/gulp/build.js
@@ -41,7 +41,9 @@
     return del(
       [
         options.dashboards + 'xosSubscribers.html',
-        options.static + 'css/xosSubscribers.css'
+        options.static + 'css/xosSubscribers.css',
+        options.static + 'images/subscribers-icon.png',
+        options.static + 'images/subscribers-icon-active.png'
       ],
       {force: true}
     );
@@ -70,6 +72,12 @@
     .pipe(gulp.dest(options.static + 'css/'))
   });
 
+  // copy images in correct folder
+  gulp.task('copyImages', ['wait'], function(){
+    return gulp.src([`${options.icon}/subscribers-icon.png`,`${options.icon}/subscribers-icon-active.png`])
+    .pipe(gulp.dest(options.static + 'images/'))
+  });
+
   // compile and minify scripts
   gulp.task('scripts', function() {
     return gulp.src([
@@ -104,7 +112,7 @@
       .pipe(
         inject(
           gulp.src([
-            options.static + 'js/vendor/xosSubscribersVendor.js',
+            options.static + 'vendor/xosSubscribersVendor.js',
             options.static + 'js/xosSubscribers.js',
             options.static + 'css/xosSubscribers.css'
           ]),
@@ -130,7 +138,7 @@
     return gulp.src(bowerDeps)
       .pipe(concat('xosSubscribersVendor.js'))
       .pipe(uglify())
-      .pipe(gulp.dest(options.static + 'js/vendor/'));
+      .pipe(gulp.dest(options.static + 'vendor/'));
   });
 
   gulp.task('lint', function () {
@@ -157,6 +165,7 @@
       'wiredep',
       'css',
       'copyCss',
+      'copyImages',
       'copyHtml',
       'cleanTmp'
     );
diff --git a/views/ngXosViews/subscribers/gulp/server.js b/views/ngXosViews/subscribers/gulp/server.js
index 1e40a34..36fdded 100644
--- a/views/ngXosViews/subscribers/gulp/server.js
+++ b/views/ngXosViews/subscribers/gulp/server.js
@@ -52,7 +52,6 @@
       server: {
         baseDir: options.src,
         routes: {
-          '/xos/core/xoslib/static/js/vendor': options.helpers,
           '/xos/core/static': options.static + '../../static/'
         },
         middleware: function(req, res, next){
@@ -115,7 +114,7 @@
         inject(
           gulp.src([
             options.tmp + '**/*.js',
-            options.helpers + 'ngXosHelpers.js'
+            options.helpers + 'ngXosHelpers.min.js'
           ])
           .pipe(angularFilesort()),
           {
diff --git a/views/ngXosViews/subscribers/gulpfile.js b/views/ngXosViews/subscribers/gulpfile.js
index 08df554..c825df8 100644
--- a/views/ngXosViews/subscribers/gulpfile.js
+++ b/views/ngXosViews/subscribers/gulpfile.js
@@ -6,12 +6,13 @@
 var options = {
   src: 'src/',
   css: 'src/css/',
+  icon: 'src/icons',
   sass: 'src/sass/',
   scripts: 'src/js/',
   tmp: 'src/.tmp',
   dist: 'dist/',
   api: '../../ngXosLib/api/',
-  helpers: '../../../xos/core/xoslib/static/js/vendor/',
+  helpers: './src/vendor/ng-xos-lib/dist/',
   static: '../../../xos/core/xoslib/static/', // this is the django static folder
   dashboards: '../../../xos/core/xoslib/dashboards/' // this is the django html folder
 };
diff --git a/views/ngXosViews/subscribers/karma.conf.js b/views/ngXosViews/subscribers/karma.conf.js
index 0e9c4d8..02c1cb1 100644
--- a/views/ngXosViews/subscribers/karma.conf.js
+++ b/views/ngXosViews/subscribers/karma.conf.js
@@ -27,8 +27,9 @@
     // list of files / patterns to load in the browser
     files: bowerComponents.concat([
       'node_modules/babel-polyfill/dist/polyfill.js',
-      '../../../xos/core/xoslib/static/js/vendor/ngXosVendor.js',
-      '../../../xos/core/xoslib/static/js/vendor/ngXosHelpers.js',
+      './src/vendor/ng-xos-lib/dist/ngXosVendor.min.js',
+      './src/vendor/ng-xos-lib/dist/ngXosHelpers.min.js',
+      'src/js/main.js',
       'src/js/**/*.js',
       'spec/**/*.mock.js',
       'spec/**/*.test.js',
@@ -46,6 +47,7 @@
     preprocessors: {
       'src/js/**/*.js': ['babel'],
       'spec/**/*.test.js': ['babel'],
+      'spec/**/*.mock.js': ['babel'],
       'src/**/*.html': ['ng-html2js']
     },
 
@@ -79,10 +81,7 @@
 
     // start these browsers
     // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
-    browsers: [
-      'PhantomJS',
-      'Chrome'
-    ],
+    browsers: ['PhantomJS'],
 
 
     // Continuous Integration mode
diff --git a/views/ngXosViews/subscribers/package.json b/views/ngXosViews/subscribers/package.json
index 96a2326..812ca00 100644
--- a/views/ngXosViews/subscribers/package.json
+++ b/views/ngXosViews/subscribers/package.json
@@ -17,7 +17,7 @@
     "XOSlib"
   ],
   "author": "Matteo Scandolo",
-  "license": "MIT",
+  "license": "Apache-2.0",
   "dependencies": {},
   "devDependencies": {
     "autoprefixer": "^6.3.3",
@@ -49,7 +49,6 @@
     "jasmine-core": "~2.3.4",
     "karma": "^0.13.14",
     "karma-babel-preprocessor": "~5.2.2",
-    "karma-chrome-launcher": "^1.0.1",
     "karma-coverage": "^0.5.3",
     "karma-jasmine": "~0.3.6",
     "karma-mocha-reporter": "~1.1.1",
diff --git a/views/ngXosViews/subscribers/src/css/dev.css b/views/ngXosViews/subscribers/src/css/dev.css
new file mode 100644
index 0000000..76c2d5b
--- /dev/null
+++ b/views/ngXosViews/subscribers/src/css/dev.css
@@ -0,0 +1,5 @@
+#xosSubscribers{
+  position: absolute;
+  top: 100px;
+  left: 200px;
+}
\ No newline at end of file
diff --git a/views/ngXosViews/subscribers/src/icons/README.md b/views/ngXosViews/subscribers/src/icons/README.md
new file mode 100644
index 0000000..0d5a787
--- /dev/null
+++ b/views/ngXosViews/subscribers/src/icons/README.md
@@ -0,0 +1,18 @@
+# Set icon for custom dashboard 
+
+## Path to add images : <dashboard-name>/src/icons
+
+### Add two images with name in following format 
+    <dashboard-name>-icon.png
+    <dashboard-name>-icon-active.png
+
+Examples: 
+    If your dashboard name is `slice`
+    then you will add the images with the name as
+        `slice-icon.png`
+        `slice-icon-active.png`
+        
+        
+        
+        
+Note: If you don't add the custom images, then dashboard will use the default images stored at `/xos/core/xoslib/static/images`
\ No newline at end of file
diff --git a/views/ngXosViews/subscribers/src/index.html b/views/ngXosViews/subscribers/src/index.html
index 71cbddc..a234964 100644
--- a/views/ngXosViews/subscribers/src/index.html
+++ b/views/ngXosViews/subscribers/src/index.html
@@ -5,6 +5,7 @@
 <!-- endbower -->
 <!-- endcss -->
 <!-- inject:css -->
+<link rel="stylesheet" href="/css/dev.css">
 <link rel="stylesheet" href="/css/main.css">
 <link rel="stylesheet" href="/../../../xos/core/static/xosNgLib.css">
 <!-- endinject -->
@@ -30,6 +31,6 @@
 <!-- endbower -->
 <!-- endjs -->
 <!-- inject:js -->
-<script src="/../../../xos/core/xoslib/static/js/vendor/ngXosHelpers.js"></script>
+<script src="/vendor/ng-xos-lib/dist/ngXosHelpers.min.js"></script>
 <script src="/.tmp/main.js"></script>
 <!-- endinject -->
\ No newline at end of file
diff --git a/views/ngXosViews/subscribers/src/templates/users-list.tpl.html b/views/ngXosViews/subscribers/src/templates/users-list.tpl.html
new file mode 100644
index 0000000..1fee0e2
--- /dev/null
+++ b/views/ngXosViews/subscribers/src/templates/users-list.tpl.html
@@ -0,0 +1 @@
+<xos-table config="vm.tableConfig" data="vm.users"></xos-table>
\ No newline at end of file
diff --git a/views/ngXosViews/synchronizerNotifier/bower.json b/views/ngXosViews/synchronizerNotifier/bower.json
index 8b0eb12..cf98e8d 100644
--- a/views/ngXosViews/synchronizerNotifier/bower.json
+++ b/views/ngXosViews/synchronizerNotifier/bower.json
@@ -5,7 +5,7 @@
     "Matteo Scandolo <matteo.scandolo@gmail.com>"
   ],
   "description": "The synchronizerNotifier view",
-  "license": "MIT",
+  "license": "Apache-2.0",
   "ignore": [
     "**/.*",
     "node_modules",
@@ -14,7 +14,8 @@
     "test",
     "tests"
   ],
-  "dependencies": {},
+  "dependencies": {
+  },
   "devDependencies": {
     "jquery": "2.1.4",
     "angular-mocks": "1.4.7",
@@ -27,6 +28,7 @@
     "bootstrap-css": "3.3.6",
     "angular-chart.js": "~0.10.2",
     "d3": "~3.5.17",
-    "angular-recursion": "~1.0.5"
+    "angular-recursion": "~1.0.5",
+    "ng-xos-lib": "opencord/ng-xos-lib#~1.0.0"
   }
 }
diff --git a/views/ngXosViews/synchronizerNotifier/gulp/build.js b/views/ngXosViews/synchronizerNotifier/gulp/build.js
index ee4bbe9..e90581d 100644
--- a/views/ngXosViews/synchronizerNotifier/gulp/build.js
+++ b/views/ngXosViews/synchronizerNotifier/gulp/build.js
@@ -36,7 +36,9 @@
     return del(
       [
         options.dashboards + 'xosSynchronizerNotifier.html',
-        options.static + 'css/xosSynchronizerNotifier.css'
+        options.static + 'css/xosSynchronizerNotifier.css',
+        options.static + 'images/synchronizerNotifier-icon.png',
+        options.static + 'images/synchronizerNotifier-icon-active.png'
       ],
       {force: true}
     );
@@ -65,6 +67,12 @@
     .pipe(gulp.dest(options.static + 'css/'))
   });
 
+  // copy images in correct folder
+  gulp.task('copyImages', ['wait'], function(){
+    return gulp.src([`${options.icon}/synchronizerNotifier-icon.png`,`${options.icon}/synchronizerNotifier-icon-active.png`])
+    .pipe(gulp.dest(options.static + 'images/'))
+  });
+
   // compile and minify scripts
   gulp.task('scripts', function() {
     return gulp.src([
@@ -99,7 +107,7 @@
       .pipe(
         inject(
           gulp.src([
-            options.static + 'js/vendor/xosSynchronizerNotifierVendor.js',
+            options.static + 'vendor/xosSynchronizerNotifierVendor.js',
             options.static + 'js/xosSynchronizerNotifier.js',
             options.static + 'css/xosSynchronizerNotifier.css'
           ]),
@@ -125,7 +133,7 @@
     return gulp.src(bowerDeps)
       .pipe(concat('xosSynchronizerNotifierVendor.js'))
       .pipe(uglify())
-      .pipe(gulp.dest(options.static + 'js/vendor/'));
+      .pipe(gulp.dest(options.static + 'vendor/'));
   });
 
   gulp.task('lint', function () {
@@ -152,6 +160,7 @@
       'wiredep',
       'css',
       'copyCss',
+      'copyImages',
       'copyHtml',
       'cleanTmp'
     );
diff --git a/views/ngXosViews/synchronizerNotifier/gulp/server.js b/views/ngXosViews/synchronizerNotifier/gulp/server.js
index 1e40a34..36fdded 100644
--- a/views/ngXosViews/synchronizerNotifier/gulp/server.js
+++ b/views/ngXosViews/synchronizerNotifier/gulp/server.js
@@ -52,7 +52,6 @@
       server: {
         baseDir: options.src,
         routes: {
-          '/xos/core/xoslib/static/js/vendor': options.helpers,
           '/xos/core/static': options.static + '../../static/'
         },
         middleware: function(req, res, next){
@@ -115,7 +114,7 @@
         inject(
           gulp.src([
             options.tmp + '**/*.js',
-            options.helpers + 'ngXosHelpers.js'
+            options.helpers + 'ngXosHelpers.min.js'
           ])
           .pipe(angularFilesort()),
           {
diff --git a/views/ngXosViews/synchronizerNotifier/gulpfile.js b/views/ngXosViews/synchronizerNotifier/gulpfile.js
index 08df554..c825df8 100644
--- a/views/ngXosViews/synchronizerNotifier/gulpfile.js
+++ b/views/ngXosViews/synchronizerNotifier/gulpfile.js
@@ -6,12 +6,13 @@
 var options = {
   src: 'src/',
   css: 'src/css/',
+  icon: 'src/icons',
   sass: 'src/sass/',
   scripts: 'src/js/',
   tmp: 'src/.tmp',
   dist: 'dist/',
   api: '../../ngXosLib/api/',
-  helpers: '../../../xos/core/xoslib/static/js/vendor/',
+  helpers: './src/vendor/ng-xos-lib/dist/',
   static: '../../../xos/core/xoslib/static/', // this is the django static folder
   dashboards: '../../../xos/core/xoslib/dashboards/' // this is the django html folder
 };
diff --git a/views/ngXosViews/synchronizerNotifier/karma.conf.js b/views/ngXosViews/synchronizerNotifier/karma.conf.js
index 4123be9..e5abf39 100644
--- a/views/ngXosViews/synchronizerNotifier/karma.conf.js
+++ b/views/ngXosViews/synchronizerNotifier/karma.conf.js
@@ -26,8 +26,9 @@
 
     // list of files / patterns to load in the browser
     files: bowerComponents.concat([
-      '../../../xos/core/xoslib/static/js/vendor/ngXosVendor.js',
-      '../../../xos/core/xoslib/static/js/vendor/ngXosHelpers.js',
+      './src/vendor/ng-xos-lib/dist/ngXosVendor.min.js',
+      './src/vendor/ng-xos-lib/dist/ngXosHelpers.min.js',
+      'src/js/main.js',
       'src/js/**/*.js',
       'spec/**/*.mock.js',
       'spec/**/*.test.js',
@@ -45,6 +46,7 @@
     preprocessors: {
       'src/js/**/*.js': ['babel'],
       'spec/**/*.test.js': ['babel'],
+      'spec/**/*.mock.js': ['babel'],
       'src/**/*.html': ['ng-html2js']
     },
 
diff --git a/views/ngXosViews/synchronizerNotifier/package.json b/views/ngXosViews/synchronizerNotifier/package.json
index ad76efe..9283153 100644
--- a/views/ngXosViews/synchronizerNotifier/package.json
+++ b/views/ngXosViews/synchronizerNotifier/package.json
@@ -17,7 +17,7 @@
     "XOSlib"
   ],
   "author": "Matteo Scandolo",
-  "license": "MIT",
+  "license": "Apache-2.0",
   "dependencies": {},
   "devDependencies": {
     "autoprefixer": "^6.3.3",
diff --git a/views/ngXosViews/synchronizerNotifier/src/css/dev.css b/views/ngXosViews/synchronizerNotifier/src/css/dev.css
new file mode 100644
index 0000000..2d00c8e
--- /dev/null
+++ b/views/ngXosViews/synchronizerNotifier/src/css/dev.css
@@ -0,0 +1,5 @@
+#xosSynchronizerNotifier{
+  position: absolute;
+  top: 100px;
+  left: 200px;
+}
\ No newline at end of file
diff --git a/views/ngXosViews/synchronizerNotifier/src/icons/README.md b/views/ngXosViews/synchronizerNotifier/src/icons/README.md
new file mode 100644
index 0000000..0d5a787
--- /dev/null
+++ b/views/ngXosViews/synchronizerNotifier/src/icons/README.md
@@ -0,0 +1,18 @@
+# Set icon for custom dashboard 
+
+## Path to add images : <dashboard-name>/src/icons
+
+### Add two images with name in following format 
+    <dashboard-name>-icon.png
+    <dashboard-name>-icon-active.png
+
+Examples: 
+    If your dashboard name is `slice`
+    then you will add the images with the name as
+        `slice-icon.png`
+        `slice-icon-active.png`
+        
+        
+        
+        
+Note: If you don't add the custom images, then dashboard will use the default images stored at `/xos/core/xoslib/static/images`
\ No newline at end of file
diff --git a/views/ngXosViews/synchronizerNotifier/src/index.html b/views/ngXosViews/synchronizerNotifier/src/index.html
index cb9b7b5..5205b9d 100644
--- a/views/ngXosViews/synchronizerNotifier/src/index.html
+++ b/views/ngXosViews/synchronizerNotifier/src/index.html
@@ -5,6 +5,7 @@
 <!-- endbower -->
 <!-- endcss -->
 <!-- inject:css -->
+<link rel="stylesheet" href="/css/dev.css">
 <link rel="stylesheet" href="/css/main.css">
 <link rel="stylesheet" href="/../../../xos/core/static/xosNgLib.css">
 <!-- endinject -->
@@ -30,6 +31,6 @@
 <!-- endbower -->
 <!-- endjs -->
 <!-- inject:js -->
-<script src="/../../../xos/core/xoslib/static/js/vendor/ngXosHelpers.js"></script>
+<script src="/vendor/ng-xos-lib/dist/ngXosHelpers.min.js"></script>
 <script src="/.tmp/main.js"></script>
 <!-- endinject -->
\ No newline at end of file
diff --git a/views/ngXosViews/synchronizerNotifier/src/templates/users-list.tpl.html b/views/ngXosViews/synchronizerNotifier/src/templates/users-list.tpl.html
new file mode 100644
index 0000000..1fee0e2
--- /dev/null
+++ b/views/ngXosViews/synchronizerNotifier/src/templates/users-list.tpl.html
@@ -0,0 +1 @@
+<xos-table config="vm.tableConfig" data="vm.users"></xos-table>
\ No newline at end of file
diff --git a/views/ngXosViews/tenant/bower.json b/views/ngXosViews/tenant/bower.json
index c37483b..4c5c1a7 100644
--- a/views/ngXosViews/tenant/bower.json
+++ b/views/ngXosViews/tenant/bower.json
@@ -2,10 +2,10 @@
   "name": "xos-tenant",
   "version": "0.0.0",
   "authors": [
-    " <>"
+    "Arpit Agarwal <arpit@onlab.us>"
   ],
   "description": "The tenant view",
-  "license": "MIT",
+  "license": "Apache-2.0",
   "ignore": [
     "**/.*",
     "node_modules",
@@ -14,7 +14,8 @@
     "test",
     "tests"
   ],
-  "dependencies": {},
+  "dependencies": {
+  },
   "devDependencies": {
     "jquery": "2.1.4",
     "angular-mocks": "1.4.7",
@@ -27,6 +28,7 @@
     "bootstrap-css": "3.3.6",
     "angular-chart.js": "~0.10.2",
     "d3": "~3.5.17",
-    "angular-recursion": "^1.0.5"
+    "angular-recursion": "~1.0.5",
+    "ng-xos-lib": "opencord/ng-xos-lib#~1.0.0"
   }
 }
diff --git a/views/ngXosViews/tenant/gulp/build.js b/views/ngXosViews/tenant/gulp/build.js
index b540fcc..2d2ec6b 100644
--- a/views/ngXosViews/tenant/gulp/build.js
+++ b/views/ngXosViews/tenant/gulp/build.js
@@ -42,7 +42,8 @@
       [
         options.dashboards + 'xosTenant.html',
         options.static + 'css/xosTenant.css',
-        options.static + 'images/*'
+        options.static + 'images/tenant-icon.png',
+        options.static + 'images/tenant-icon-active.png'
       ],
       {force: true}
     );
@@ -71,9 +72,9 @@
     .pipe(gulp.dest(options.static + 'css/'))
   });
 
-    // copy images in correct folder
+  // copy images in correct folder
   gulp.task('copyImages', ['wait'], function(){
-    return gulp.src([`${options.icon}/*.png`])
+    return gulp.src([`${options.icon}/tenant-icon.png`,`${options.icon}/tenant-icon-active.png`])
     .pipe(gulp.dest(options.static + 'images/'))
   });
 
@@ -111,7 +112,7 @@
       .pipe(
         inject(
           gulp.src([
-            options.static + 'js/vendor/xosTenantVendor.js',
+            options.static + 'vendor/xosTenantVendor.js',
             options.static + 'js/xosTenant.js',
             options.static + 'css/xosTenant.css'
           ]),
@@ -137,7 +138,7 @@
     return gulp.src(bowerDeps)
       .pipe(concat('xosTenantVendor.js'))
       .pipe(uglify())
-      .pipe(gulp.dest(options.static + 'js/vendor/'));
+      .pipe(gulp.dest(options.static + 'vendor/'));
   });
 
   gulp.task('lint', function () {
diff --git a/views/ngXosViews/tenant/gulp/server.js b/views/ngXosViews/tenant/gulp/server.js
index 4d64442..f647ec7 100644
--- a/views/ngXosViews/tenant/gulp/server.js
+++ b/views/ngXosViews/tenant/gulp/server.js
@@ -52,15 +52,11 @@
       server: {
         baseDir: options.src,
         routes: {
-          '/xos/core/xoslib/static/js/vendor': options.helpers,
           '/xos/core/static': options.static + '../../static/'
         },
         middleware: function(req, res, next){
           if(
-            // to be removed, deprecated API
-            // req.url.indexOf('/xos/') !== -1 ||
-             req.url.indexOf('/xoslib/tenant') !== -1 ||
-            // req.url.indexOf('/hpcapi/') !== -1 ||
+            req.url.indexOf('/xoslib/tenant') !== -1 ||
             req.url.indexOf('/api/') !== -1
           ){
             if(conf.xoscsrftoken && conf.xossessionid){
@@ -119,7 +115,7 @@
         inject(
           gulp.src([
             options.tmp + '**/*.js',
-            options.helpers + 'ngXosHelpers.js'
+            options.helpers + 'ngXosHelpers.min.js'
           ])
           .pipe(angularFilesort()),
           {
diff --git a/views/ngXosViews/tenant/gulpfile.js b/views/ngXosViews/tenant/gulpfile.js
index 08df554..c825df8 100644
--- a/views/ngXosViews/tenant/gulpfile.js
+++ b/views/ngXosViews/tenant/gulpfile.js
@@ -6,12 +6,13 @@
 var options = {
   src: 'src/',
   css: 'src/css/',
+  icon: 'src/icons',
   sass: 'src/sass/',
   scripts: 'src/js/',
   tmp: 'src/.tmp',
   dist: 'dist/',
   api: '../../ngXosLib/api/',
-  helpers: '../../../xos/core/xoslib/static/js/vendor/',
+  helpers: './src/vendor/ng-xos-lib/dist/',
   static: '../../../xos/core/xoslib/static/', // this is the django static folder
   dashboards: '../../../xos/core/xoslib/dashboards/' // this is the django html folder
 };
diff --git a/views/ngXosViews/tenant/karma.conf.js b/views/ngXosViews/tenant/karma.conf.js
index 4123be9..e5abf39 100644
--- a/views/ngXosViews/tenant/karma.conf.js
+++ b/views/ngXosViews/tenant/karma.conf.js
@@ -26,8 +26,9 @@
 
     // list of files / patterns to load in the browser
     files: bowerComponents.concat([
-      '../../../xos/core/xoslib/static/js/vendor/ngXosVendor.js',
-      '../../../xos/core/xoslib/static/js/vendor/ngXosHelpers.js',
+      './src/vendor/ng-xos-lib/dist/ngXosVendor.min.js',
+      './src/vendor/ng-xos-lib/dist/ngXosHelpers.min.js',
+      'src/js/main.js',
       'src/js/**/*.js',
       'spec/**/*.mock.js',
       'spec/**/*.test.js',
@@ -45,6 +46,7 @@
     preprocessors: {
       'src/js/**/*.js': ['babel'],
       'spec/**/*.test.js': ['babel'],
+      'spec/**/*.mock.js': ['babel'],
       'src/**/*.html': ['ng-html2js']
     },
 
diff --git a/views/ngXosViews/tenant/package.json b/views/ngXosViews/tenant/package.json
index ed04285..d8da5f8 100644
--- a/views/ngXosViews/tenant/package.json
+++ b/views/ngXosViews/tenant/package.json
@@ -16,8 +16,8 @@
     "Angular",
     "XOSlib"
   ],
-  "author": "",
-  "license": "MIT",
+  "author": "Arpit Agarwal",
+  "license": "Apache-2.0",
   "dependencies": {},
   "devDependencies": {
     "autoprefixer": "^6.3.3",
diff --git a/views/ngXosViews/tenant/src/css/dev.css b/views/ngXosViews/tenant/src/css/dev.css
new file mode 100644
index 0000000..0263242
--- /dev/null
+++ b/views/ngXosViews/tenant/src/css/dev.css
@@ -0,0 +1,5 @@
+#xosTenant{
+  position: absolute;
+  top: 100px;
+  left: 200px;
+}
\ No newline at end of file
diff --git a/views/ngXosViews/tenant/src/icons/README.md b/views/ngXosViews/tenant/src/icons/README.md
new file mode 100644
index 0000000..0d5a787
--- /dev/null
+++ b/views/ngXosViews/tenant/src/icons/README.md
@@ -0,0 +1,18 @@
+# Set icon for custom dashboard 
+
+## Path to add images : <dashboard-name>/src/icons
+
+### Add two images with name in following format 
+    <dashboard-name>-icon.png
+    <dashboard-name>-icon-active.png
+
+Examples: 
+    If your dashboard name is `slice`
+    then you will add the images with the name as
+        `slice-icon.png`
+        `slice-icon-active.png`
+        
+        
+        
+        
+Note: If you don't add the custom images, then dashboard will use the default images stored at `/xos/core/xoslib/static/images`
\ No newline at end of file
diff --git a/views/ngXosViews/tenant/src/index.html b/views/ngXosViews/tenant/src/index.html
index d647aa5..d8ebd82 100644
--- a/views/ngXosViews/tenant/src/index.html
+++ b/views/ngXosViews/tenant/src/index.html
@@ -5,6 +5,7 @@
 <!-- endbower -->
 <!-- endcss -->
 <!-- inject:css -->
+<link rel="stylesheet" href="/css/dev.css">
 <link rel="stylesheet" href="/css/main.css">
 <link rel="stylesheet" href="/../../../xos/core/static/xosNgLib.css">
 <!-- endinject -->
@@ -31,7 +32,7 @@
 <!-- endbower -->
 <!-- endjs -->
 <!-- inject:js -->
-<script src="/../../../xos/core/xoslib/static/js/vendor/ngXosHelpers.js"></script>
+<script src="/vendor/ng-xos-lib/dist/ngXosHelpers.min.js"></script>
 <script src="/.tmp/main.js"></script>
 <script src="/.tmp/sitedetail.js"></script>
 <script src="/.tmp/createslice.js"></script>
diff --git a/views/ngXosViews/truckroll/bower.json b/views/ngXosViews/truckroll/bower.json
index 0cc10f7..27373e8 100644
--- a/views/ngXosViews/truckroll/bower.json
+++ b/views/ngXosViews/truckroll/bower.json
@@ -2,10 +2,10 @@
   "name": "xos-truckroll",
   "version": "0.0.0",
   "authors": [
-    "Matteo Scandolo <teo@onlab.us>"
+    "Matteo Scandolo <matteo.scandolo@gmail.com>"
   ],
   "description": "The truckroll view",
-  "license": "MIT",
+  "license": "Apache-2.0",
   "ignore": [
     "**/.*",
     "node_modules",
@@ -27,6 +27,8 @@
     "lodash": "~4.11.1",
     "bootstrap-css": "3.3.6",
     "angular-chart.js": "~0.10.2",
-    "d3": "~3.5.17"
+    "d3": "~3.5.17",
+    "angular-recursion": "~1.0.5",
+    "ng-xos-lib": "opencord/ng-xos-lib#~1.0.0"
   }
 }
diff --git a/views/ngXosViews/truckroll/gulp/build.js b/views/ngXosViews/truckroll/gulp/build.js
index ff48fac..5878b31 100644
--- a/views/ngXosViews/truckroll/gulp/build.js
+++ b/views/ngXosViews/truckroll/gulp/build.js
@@ -41,7 +41,9 @@
     return del(
       [
         options.dashboards + 'xosTruckroll.html',
-        options.static + 'css/xosTruckroll.css'
+        options.static + 'css/xosTruckroll.css',
+        options.static + 'images/truckroll-icon.png',
+        options.static + 'images/truckroll-icon-active.png'
       ],
       {force: true}
     );
@@ -70,6 +72,12 @@
     .pipe(gulp.dest(options.static + 'css/'))
   });
 
+  // copy images in correct folder
+  gulp.task('copyImages', ['wait'], function(){
+    return gulp.src([`${options.icon}/truckroll-icon.png`,`${options.icon}/truckroll-icon-active.png`])
+    .pipe(gulp.dest(options.static + 'images/'))
+  });
+
   // compile and minify scripts
   gulp.task('scripts', function() {
     return gulp.src([
@@ -104,7 +112,7 @@
       .pipe(
         inject(
           gulp.src([
-            options.static + 'js/vendor/xosTruckrollVendor.js',
+            options.static + 'vendor/xosTruckrollVendor.js',
             options.static + 'js/xosTruckroll.js',
             options.static + 'css/xosTruckroll.css'
           ]),
@@ -130,7 +138,7 @@
     return gulp.src(bowerDeps)
       .pipe(concat('xosTruckrollVendor.js'))
       .pipe(uglify())
-      .pipe(gulp.dest(options.static + 'js/vendor/'));
+      .pipe(gulp.dest(options.static + 'vendor/'));
   });
 
   gulp.task('lint', function () {
@@ -157,6 +165,7 @@
       'wiredep',
       'css',
       'copyCss',
+      'copyImages',
       'copyHtml',
       'cleanTmp'
     );
diff --git a/views/ngXosViews/truckroll/gulp/server.js b/views/ngXosViews/truckroll/gulp/server.js
index 1e40a34..36fdded 100644
--- a/views/ngXosViews/truckroll/gulp/server.js
+++ b/views/ngXosViews/truckroll/gulp/server.js
@@ -52,7 +52,6 @@
       server: {
         baseDir: options.src,
         routes: {
-          '/xos/core/xoslib/static/js/vendor': options.helpers,
           '/xos/core/static': options.static + '../../static/'
         },
         middleware: function(req, res, next){
@@ -115,7 +114,7 @@
         inject(
           gulp.src([
             options.tmp + '**/*.js',
-            options.helpers + 'ngXosHelpers.js'
+            options.helpers + 'ngXosHelpers.min.js'
           ])
           .pipe(angularFilesort()),
           {
diff --git a/views/ngXosViews/truckroll/gulpfile.js b/views/ngXosViews/truckroll/gulpfile.js
index 08df554..c825df8 100644
--- a/views/ngXosViews/truckroll/gulpfile.js
+++ b/views/ngXosViews/truckroll/gulpfile.js
@@ -6,12 +6,13 @@
 var options = {
   src: 'src/',
   css: 'src/css/',
+  icon: 'src/icons',
   sass: 'src/sass/',
   scripts: 'src/js/',
   tmp: 'src/.tmp',
   dist: 'dist/',
   api: '../../ngXosLib/api/',
-  helpers: '../../../xos/core/xoslib/static/js/vendor/',
+  helpers: './src/vendor/ng-xos-lib/dist/',
   static: '../../../xos/core/xoslib/static/', // this is the django static folder
   dashboards: '../../../xos/core/xoslib/dashboards/' // this is the django html folder
 };
diff --git a/views/ngXosViews/truckroll/karma.conf.js b/views/ngXosViews/truckroll/karma.conf.js
index 4123be9..e5abf39 100644
--- a/views/ngXosViews/truckroll/karma.conf.js
+++ b/views/ngXosViews/truckroll/karma.conf.js
@@ -26,8 +26,9 @@
 
     // list of files / patterns to load in the browser
     files: bowerComponents.concat([
-      '../../../xos/core/xoslib/static/js/vendor/ngXosVendor.js',
-      '../../../xos/core/xoslib/static/js/vendor/ngXosHelpers.js',
+      './src/vendor/ng-xos-lib/dist/ngXosVendor.min.js',
+      './src/vendor/ng-xos-lib/dist/ngXosHelpers.min.js',
+      'src/js/main.js',
       'src/js/**/*.js',
       'spec/**/*.mock.js',
       'spec/**/*.test.js',
@@ -45,6 +46,7 @@
     preprocessors: {
       'src/js/**/*.js': ['babel'],
       'spec/**/*.test.js': ['babel'],
+      'spec/**/*.mock.js': ['babel'],
       'src/**/*.html': ['ng-html2js']
     },
 
diff --git a/views/ngXosViews/truckroll/package.json b/views/ngXosViews/truckroll/package.json
index 128a229..f397ff0 100644
--- a/views/ngXosViews/truckroll/package.json
+++ b/views/ngXosViews/truckroll/package.json
@@ -17,7 +17,7 @@
     "XOSlib"
   ],
   "author": "Matteo Scandolo",
-  "license": "MIT",
+  "license": "Apache-2.0",
   "dependencies": {},
   "devDependencies": {
     "autoprefixer": "^6.3.3",
diff --git a/views/ngXosViews/truckroll/src/icons/README.md b/views/ngXosViews/truckroll/src/icons/README.md
new file mode 100644
index 0000000..0d5a787
--- /dev/null
+++ b/views/ngXosViews/truckroll/src/icons/README.md
@@ -0,0 +1,18 @@
+# Set icon for custom dashboard 
+
+## Path to add images : <dashboard-name>/src/icons
+
+### Add two images with name in following format 
+    <dashboard-name>-icon.png
+    <dashboard-name>-icon-active.png
+
+Examples: 
+    If your dashboard name is `slice`
+    then you will add the images with the name as
+        `slice-icon.png`
+        `slice-icon-active.png`
+        
+        
+        
+        
+Note: If you don't add the custom images, then dashboard will use the default images stored at `/xos/core/xoslib/static/images`
\ No newline at end of file
diff --git a/views/ngXosViews/truckroll/src/index.html b/views/ngXosViews/truckroll/src/index.html
index bb4f072..567d4e4 100644
--- a/views/ngXosViews/truckroll/src/index.html
+++ b/views/ngXosViews/truckroll/src/index.html
@@ -28,9 +28,10 @@
 <script src="vendor/Chart.js/Chart.js"></script>
 <script src="vendor/angular-chart.js/dist/angular-chart.js"></script>
 <script src="vendor/d3/d3.js"></script>
+<script src="vendor/angular-recursion/angular-recursion.js"></script>
 <!-- endbower -->
 <!-- endjs -->
 <!-- inject:js -->
-<script src="/../../../xos/core/xoslib/static/js/vendor/ngXosHelpers.js"></script>
+<script src="/vendor/ng-xos-lib/dist/ngXosHelpers.min.js"></script>
 <script src="/.tmp/main.js"></script>
 <!-- endinject -->
\ No newline at end of file
diff --git a/views/ngXosViews/truckroll/src/templates/users-list.tpl.html b/views/ngXosViews/truckroll/src/templates/users-list.tpl.html
new file mode 100644
index 0000000..1fee0e2
--- /dev/null
+++ b/views/ngXosViews/truckroll/src/templates/users-list.tpl.html
@@ -0,0 +1 @@
+<xos-table config="vm.tableConfig" data="vm.users"></xos-table>
\ No newline at end of file
diff --git a/xos/core/xoslib/dashboards/xosCeilometerDashboard.html b/xos/core/xoslib/dashboards/xosCeilometerDashboard.html
index 42e22f8..4aa54ba 100644
--- a/xos/core/xoslib/dashboards/xosCeilometerDashboard.html
+++ b/xos/core/xoslib/dashboards/xosCeilometerDashboard.html
@@ -12,6 +12,6 @@
 <!-- endjs -->
 
 <!-- inject:js -->
-<script src="/static/js/vendor/xosCeilometerDashboardVendor.js"></script>
+<script src="/static/vendor/xosCeilometerDashboardVendor.js"></script>
 <script src="/static/js/xosCeilometerDashboard.js"></script>
 <!-- endinject -->
diff --git a/xos/core/xoslib/dashboards/xosDashboardManager.html b/xos/core/xoslib/dashboards/xosDashboardManager.html
index 562bcf7..09e90c8 100644
--- a/xos/core/xoslib/dashboards/xosDashboardManager.html
+++ b/xos/core/xoslib/dashboards/xosDashboardManager.html
@@ -12,6 +12,6 @@
 
 <!-- endjs -->
 <!-- inject:js -->
-<script src="/static/js/vendor/xosDashboardManagerVendor.js"></script>
+<script src="/static/vendor/xosDashboardManagerVendor.js"></script>
 <script src="/static/js/xosDashboardManager.js"></script>
 <!-- endinject -->
\ No newline at end of file
diff --git a/xos/core/xoslib/dashboards/xosDiagnostic.html b/xos/core/xoslib/dashboards/xosDiagnostic.html
index f87baae..8c949c9 100644
--- a/xos/core/xoslib/dashboards/xosDiagnostic.html
+++ b/xos/core/xoslib/dashboards/xosDiagnostic.html
@@ -10,6 +10,6 @@
 
 
 <!-- inject:js -->
-<script src="/static/js/vendor/xosDiagnosticVendor.js"></script>
+<script src="/static/vendor/xosDiagnosticVendor.js"></script>
 <script src="/static/js/xosDiagnostic.js"></script>
 <!-- endinject -->
diff --git a/xos/core/xoslib/dashboards/xosMcordTopology.html b/xos/core/xoslib/dashboards/xosMcordTopology.html
index a4b67a0..132e54f 100644
--- a/xos/core/xoslib/dashboards/xosMcordTopology.html
+++ b/xos/core/xoslib/dashboards/xosMcordTopology.html
@@ -10,6 +10,6 @@
 
 
 <!-- inject:js -->
-<script src="/static/js/vendor/xosMcordTopologyVendor.js"></script>
+<script src="/static/vendor/xosMcordTopologyVendor.js"></script>
 <script src="/static/js/xosMcordTopology.js"></script>
 <!-- endinject -->
diff --git a/xos/core/xoslib/dashboards/xosServiceGrid.html b/xos/core/xoslib/dashboards/xosServiceGrid.html
index ea89ca8..40313c5 100644
--- a/xos/core/xoslib/dashboards/xosServiceGrid.html
+++ b/xos/core/xoslib/dashboards/xosServiceGrid.html
@@ -12,6 +12,6 @@
 
 <!-- endjs -->
 <!-- inject:js -->
-<script src="/static/js/vendor/xosServiceGridVendor.js"></script>
+<script src="/static/vendor/xosServiceGridVendor.js"></script>
 <script src="/static/js/xosServiceGrid.js"></script>
 <!-- endinject -->
\ No newline at end of file
diff --git a/xos/core/xoslib/static/js/vendor/ngXosHelpers.js b/xos/core/xoslib/static/js/vendor/ngXosHelpers.js
deleted file mode 100644
index b378f83..0000000
--- a/xos/core/xoslib/static/js/vendor/ngXosHelpers.js
+++ /dev/null
@@ -1,2 +0,0 @@
-"use strict";function _toConsumableArray(e){if(Array.isArray(e)){for(var n=0,o=Array(e.length);n<e.length;n++)o[n]=e[n];return o}return Array.from(e)}!function(){angular.module("xos.uiComponents",["chart.js","RecursionHelper"])}();var _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol?"symbol":typeof e};!function(){angular.module("xos.uiComponents").directive("xosSmartTable",function(){return{restrict:"E",scope:{config:"="},template:'\n        <div class="row" ng-show="vm.data.length > 0">\n          <div class="col-xs-12 text-right">\n            <a href="" class="btn btn-success" ng-click="vm.createItem()">\n              Add\n            </a>\n          </div>\n        </div>\n        <div class="row">\n          <div class="col-xs-12 table-responsive">\n            <xos-table config="vm.tableConfig" data="vm.data"></xos-table>\n          </div>\n        </div>\n        <div class="panel panel-default" ng-show="vm.detailedItem">\n          <div class="panel-heading">\n            <div class="row">\n              <div class="col-xs-11">\n                <h3 class="panel-title" ng-show="vm.detailedItem.id">Update {{vm.config.resource}} {{vm.detailedItem.id}}</h3>\n                <h3 class="panel-title" ng-show="!vm.detailedItem.id">Create {{vm.config.resource}} item</h3>\n              </div>\n              <div class="col-xs-1">\n                <a href="" ng-click="vm.cleanForm()">\n                  <i class="glyphicon glyphicon-remove pull-right"></i>\n                </a>\n              </div>\n            </div>\n          </div>\n          <div class="panel-body">\n            <xos-form config="vm.formConfig" ng-model="vm.detailedItem"></xos-form>\n          </div>\n        </div>\n        <xos-alert config="{type: \'success\', closeBtn: true}" show="vm.responseMsg">{{vm.responseMsg}}</xos-alert>\n        <xos-alert config="{type: \'danger\', closeBtn: true}" show="vm.responseErr">{{vm.responseErr}}</xos-alert>\n      ',bindToController:!0,controllerAs:"vm",controller:["$injector","LabelFormatter","_","XosFormHelpers",function(e,n,o,t){var i=this;this.responseMsg=!1,this.responseErr=!1,this.tableConfig={columns:[],actions:[{label:"delete",icon:"remove",cb:function(e){i.Resource["delete"]({id:e.id}).$promise.then(function(){o.remove(i.data,function(n){return n.id===e.id}),i.responseMsg=i.config.resource+" with id "+e.id+" successfully deleted"})["catch"](function(n){i.responseErr=n.data.detail||"Error while deleting "+i.config.resource+" with id "+e.id})},color:"red"},{label:"details",icon:"search",cb:function(e){i.detailedItem=e}}],classes:"table table-striped table-bordered table-responsive",filter:"field",order:!0,pagination:{pageSize:10}},this.formConfig={exclude:this.config.hiddenFields,fields:{},formName:this.config.resource+"Form",actions:[{label:"Save",icon:"ok",cb:function(e){var n=void 0,o=!0;e.id?(n=e.$update(),o=!1):n=e.$save(),n.then(function(n){o&&i.data.push(angular.copy(n)),delete i.detailedItem,i.responseMsg=i.config.resource+" with id "+e.id+" successfully saved"})["catch"](function(n){i.responseErr=n.data.detail||"Error while saving "+i.config.resource+" with id "+e.id})},"class":"success"}]},this.cleanForm=function(){delete i.detailedItem},this.createItem=function(){i.detailedItem=new i.Resource},this.Resource=e.get(this.config.resource);var r=function(){i.Resource.query().$promise.then(function(e){if(!e[0])return void(i.data=e);var r=e[0],a=Object.keys(r);o.remove(a,function(e){return"id"===e||"validators"===e}),angular.isArray(i.config.hiddenFields)&&(a=o.difference(a,i.config.hiddenFields));var s=a.map(function(e){return n.format(e)});a.forEach(function(e,n){var o={label:s[n],prop:e};angular.isString(r[e])&&"undefined"!=typeof r[e]&&(o.type=_typeof(r[e])),i.tableConfig.columns.push(o)}),a.forEach(function(e,o){i.formConfig.fields[e]={label:n.format(s[o]).replace(":",""),type:t._getFieldFormat(r[e])}}),i.data=e})};r()}]}})}(),function(){angular.module("xos.uiComponents").directive("xosSmartPie",function(){return{restrict:"E",scope:{config:"="},template:'\n        <canvas\n          class="chart chart-pie {{vm.config.classes}}"\n          chart-data="vm.data" chart-labels="vm.labels"\n          chart-legend="{{vm.config.legend}}">\n        </canvas>\n      ',bindToController:!0,controllerAs:"vm",controller:["$injector","$interval","$scope","$timeout","_",function(e,n,o,t,i){var r=this;if(!this.config.resource&&!this.config.data)throw new Error("[xosSmartPie] Please provide a resource or an array of data in the configuration");var a=function(e){return i.groupBy(e,r.config.groupBy)},s=function(e){return i.reduce(Object.keys(e),function(n,o){return n.concat(e[o].length)},[])},l=function(e){return angular.isFunction(r.config.labelFormatter)?r.config.labelFormatter(Object.keys(e)):Object.keys(e)},c=function(e){var n=a(e);r.data=s(n),r.labels=l(n)};this.config.resource?!function(){r.Resource=e.get(r.config.resource);var o=function(){r.Resource.query().$promise.then(function(e){e[0]&&c(e)})};o(),r.config.poll&&n(function(){o()},1e3*r.config.poll)}():o.$watch(function(){return r.config.data},function(e){e&&c(r.config.data)},!0),o.$on("create",function(e,n){console.log("create: "+n.id)}),o.$on("destroy",function(e,n){console.log("destroy: "+n.id)})}]}})}(),function(){angular.module("xos.uiComponents").directive("xosTable",function(){return{restrict:"E",scope:{data:"=",config:"="},template:'\n          <div ng-show="vm.data.length > 0 && vm.loader == false">\n            <div class="row" ng-if="vm.config.filter == \'fulltext\'">\n              <div class="col-xs-12">\n                <input\n                  class="form-control"\n                  placeholder="Type to search.."\n                  type="text"\n                  ng-model="vm.query"/>\n              </div>\n            </div>\n            <table ng-class="vm.classes" ng-hide="vm.data.length == 0">\n              <thead>\n                <tr>\n                  <th ng-repeat="col in vm.columns">\n                    {{col.label}}\n                    <span ng-if="vm.config.order">\n                      <a href="" ng-click="vm.orderBy = col.prop; vm.reverse = false">\n                        <i class="glyphicon glyphicon-chevron-up"></i>\n                      </a>\n                      <a href="" ng-click="vm.orderBy = col.prop; vm.reverse = true">\n                        <i class="glyphicon glyphicon-chevron-down"></i>\n                      </a>\n                    </span>\n                  </th>\n                  <th ng-if="vm.config.actions">Actions:</th>\n                </tr>\n              </thead>\n              <tbody ng-if="vm.config.filter == \'field\'">\n                <tr>\n                  <td ng-repeat="col in vm.columns">\n                    <input\n                      ng-if="col.type !== \'boolean\' && col.type !== \'array\' && col.type !== \'object\' && col.type !== \'custom\'"\n                      class="form-control"\n                      placeholder="Type to search by {{col.label}}"\n                      type="text"\n                      ng-model="vm.query[col.prop]"/>\n                    <select\n                      ng-if="col.type === \'boolean\'"\n                      class="form-control"\n                      ng-model="vm.query[col.prop]">\n                      <option value="">-</option>\n                      <option value="true">True</option>\n                      <option value="false">False</option>\n                    </select>\n                  </td>\n                  <td ng-if="vm.config.actions"></td>\n                </tr>\n              </tbody>\n              <tbody>\n                <tr ng-repeat="item in vm.data | filter:vm.query:vm.comparator | orderBy:vm.orderBy:vm.reverse | pagination:vm.currentPage * vm.config.pagination.pageSize | limitTo: (vm.config.pagination.pageSize || vm.data.length) track by $index">\n                  <td ng-repeat="col in vm.columns" xos-link-wrapper>\n                    <span ng-if="!col.type">{{item[col.prop]}}</span>\n                    <span ng-if="col.type === \'boolean\'">\n                      <i class="glyphicon"\n                        ng-class="{\'glyphicon-ok\': item[col.prop], \'glyphicon-remove\': !item[col.prop]}">\n                      </i>\n                    </span>\n                    <span ng-if="col.type === \'date\'">\n                      {{item[col.prop] | date:\'H:mm MMM d, yyyy\'}}\n                    </span>\n                    <span ng-if="col.type === \'array\'">\n                      {{item[col.prop] | arrayToList}}\n                    </span>\n                    <span ng-if="col.type === \'object\'">\n                      <dl class="dl-horizontal">\n                        <span ng-repeat="(k,v) in item[col.prop]">\n                          <dt>{{k}}</dt>\n                          <dd>{{v}}</dd>\n                        </span>\n                      </dl>\n                    </span>\n                    <span ng-if="col.type === \'custom\'">\n                      {{col.formatter(item)}}\n                    </span>\n                    <span ng-if="col.type === \'icon\'">\n                      <i class="glyphicon glyphicon-{{col.formatter(item)}}">\n                      </i>\n                    </span>\n                  </td>\n                  <td ng-if="vm.config.actions">\n                    <a href=""\n                      ng-repeat="action in vm.config.actions"\n                      ng-click="action.cb(item)"\n                      title="{{action.label}}">\n                      <i\n                        class="glyphicon glyphicon-{{action.icon}}"\n                        style="color: {{action.color}};"></i>\n                    </a>\n                  </td>\n                </tr>\n              </tbody>\n            </table>\n            <xos-pagination\n              ng-if="vm.config.pagination"\n              page-size="vm.config.pagination.pageSize"\n              total-elements="vm.data.length"\n              change="vm.goToPage">\n              </xos-pagination>\n          </div>\n          <div ng-show="(vm.data.length == 0 || !vm.data) && vm.loader == false">\n             <xos-alert config="{type: \'info\'}">\n              No data to show.\n            </xos-alert>\n          </div>\n          <div ng-show="vm.loader == true">\n            <div class="loader"></div>\n          </div>\n        ',bindToController:!0,controllerAs:"vm",controller:["_","$scope","Comparator",function(e,n,o){var t=this;if(this.comparator=o,this.loader=!0,n.$watch(function(){return t.data},function(e){angular.isDefined(e)&&(t.loader=!1)}),!this.config)throw new Error('[xosTable] Please provide a configuration via the "config" attribute');if(!this.config.columns)throw new Error("[xosTable] Please provide a columns list in the configuration");this.config.order&&angular.isObject(this.config.order)&&(this.reverse=this.config.order.reverse||!1,this.orderBy=this.config.order.field||"id");var i=e.filter(this.config.columns,{type:"custom"});angular.isArray(i)&&i.length>0&&e.forEach(i,function(e){if(!e.formatter||!angular.isFunction(e.formatter))throw new Error("[xosTable] You have provided a custom field type, a formatter function should provided too.")});var r=e.filter(this.config.columns,{type:"icon"});angular.isArray(r)&&r.length>0&&e.forEach(r,function(e){if(!e.formatter||!angular.isFunction(e.formatter))throw new Error("[xosTable] You have provided an icon field type, a formatter function should provided too.")});var a=e.filter(this.config.columns,function(e){return angular.isDefined(e.link)});angular.isArray(a)&&a.length>0&&e.forEach(a,function(e){if(!angular.isFunction(e.link))throw new Error("[xosTable] The link property should be a function.")}),this.columns=this.config.columns,this.classes=this.config.classes||"table table-striped table-bordered",this.config.actions,this.config.pagination&&(this.currentPage=0,this.goToPage=function(e){t.currentPage=e})}]}}).filter("arrayToList",function(){return function(e){return angular.isArray(e)?e.join(", "):e}}).directive("xosLinkWrapper",function(){return{restrict:"A",transclude:!0,template:'\n          <a ng-if="col.link" href="{{col.link(item)}}">\n            <div ng-transclude></div>\n          </a>\n          <div ng-transclude ng-if="!col.link"></div>\n        '}})}(),function(){angular.module("xos.uiComponents").directive("xosValidation",function(){return{restrict:"E",scope:{field:"=",form:"="},template:'\n        <div ng-cloak>\n          <xos-alert config="vm.config" show="vm.field.$error.required !== undefined && vm.field.$error.required !== false  && (vm.field.$touched || vm.form.$submitted)">\n            Field required\n          </xos-alert>\n          <xos-alert config="vm.config" show="vm.field.$error.email !== undefined && vm.field.$error.email !== false && (vm.field.$touched || vm.form.$submitted)">\n            This is not a valid email\n          </xos-alert>\n          <xos-alert config="vm.config" show="vm.field.$error.minlength !== undefined && vm.field.$error.minlength !== false && (vm.field.$touched || vm.form.$submitted)">\n            Too short\n          </xos-alert>\n          <xos-alert config="vm.config" show="vm.field.$error.maxlength !== undefined && vm.field.$error.maxlength !== false && (vm.field.$touched || vm.form.$submitted)">\n            Too long\n          </xos-alert>\n          <xos-alert config="vm.config" show="vm.field.$error.custom !== undefined && vm.field.$error.custom !== false && (vm.field.$touched || vm.form.$submitted)">\n            Field invalid\n          </xos-alert>\n        </div>\n      ',transclude:!0,bindToController:!0,controllerAs:"vm",controller:function(){this.config={type:"danger"}}}})}(),function(){angular.module("xos.uiComponents").directive("xosPagination",function(){return{restrict:"E",scope:{pageSize:"=",totalElements:"=",change:"="},template:'\n        <div class="row" ng-if="vm.pageList.length > 1">\n          <div class="col-xs-12 text-center">\n            <ul class="pagination">\n              <li\n                ng-click="vm.goToPage(vm.currentPage - 1)"\n                ng-class="{disabled: vm.currentPage == 0}">\n                <a href="" aria-label="Previous">\n                    <span aria-hidden="true">&laquo;</span>\n                </a>\n              </li>\n              <li ng-repeat="i in vm.pageList" ng-class="{active: i === vm.currentPage}">\n                <a href="" ng-click="vm.goToPage(i)">{{i + 1}}</a>\n              </li>\n              <li\n                ng-click="vm.goToPage(vm.currentPage + 1)"\n                ng-class="{disabled: vm.currentPage == vm.pages - 1}">\n                <a href="" aria-label="Next">\n                    <span aria-hidden="true">&raquo;</span>\n                </a>\n              </li>\n            </ul>\n          </div>\n        </div>\n      ',bindToController:!0,controllerAs:"vm",controller:["$scope",function(e){var n=this;this.currentPage=0,this.goToPage=function(e){e<0||e===n.pages||(n.currentPage=e,n.change(e))},this.createPages=function(e){for(var n=[],o=0;o<e;o++)n.push(o);return n},e.$watch(function(){return n.totalElements},function(){n.totalElements&&(n.pages=Math.ceil(n.totalElements/n.pageSize),n.pageList=n.createPages(n.pages))})}]}}).filter("pagination",function(){return function(e,n){return e&&angular.isArray(e)?(n=parseInt(n,10),e.slice(n)):e}})}(),function(){angular.module("xos.uiComponents").directive("xosForm",function(){return{restrict:"E",scope:{config:"=",ngModel:"="},template:'\n        <form name="vm.{{vm.config.formName || \'form\'}}" novalidate>\n          <div class="form-group" ng-repeat="(name, field) in vm.formField">\n            <xos-field name="name" field="field" ng-model="vm.ngModel[name]"></xos-field>\n            <xos-validation field="vm[vm.config.formName || \'form\'][name]" form = "vm[vm.config.formName || \'form\']"></xos-validation>\n            <div class="alert alert-info" ng-show="(field.hint).length >0" role="alert">{{field.hint}}</div>\n          </div>\n          <div class="form-group" ng-if="vm.config.actions">\n          <xos-alert config="vm.config.feedback" show="vm.config.feedback.show">{{vm.config.feedback.message}}</xos-alert>\n\n            <button role="button" href=""\n              ng-repeat="action in vm.config.actions"\n              ng-click="action.cb(vm.ngModel, vm[vm.config.formName || \'form\'])"\n              class="btn btn-{{action.class}}"\n              title="{{action.label}}">\n              <i class="glyphicon glyphicon-{{action.icon}}"></i>\n              {{action.label}}\n            </button>\n          </div>\n        </form>\n      ',bindToController:!0,controllerAs:"vm",controller:["$scope","$log","_","XosFormHelpers",function(e,n,o,t){var i=this;if(!this.config)throw new Error('[xosForm] Please provide a configuration via the "config" attribute');if(!this.config.actions)throw new Error("[xosForm] Please provide an action list in the configuration");this.config.feedback||(this.config.feedback={show:!1,message:"Form submitted successfully !!!",type:"success"}),this.excludedField=["id","validators","created","updated","deleted","backend_status"],this.config&&this.config.exclude&&(this.excludedField=this.excludedField.concat(this.config.exclude)),this.formField=[],e.$watch(function(){return i.config},function(){if(i.ngModel){var e=o.difference(Object.keys(i.ngModel),i.excludedField),n=t.parseModelField(e);i.formField=t.buildFormStructure(n,i.config.fields,i.ngModel)}},!0),e.$watch(function(){return i.ngModel},function(e){if(i.formField={},e){var n=o.difference(Object.keys(e),i.excludedField),r=t.parseModelField(n);i.formField=t.buildFormStructure(r,i.config.fields,e)}})}]}})}(),function(){angular.module("xos.uiComponents").directive("xosField",["RecursionHelper",function(e){return{restrict:"E",scope:{name:"=",field:"=",ngModel:"="},template:'\n        <label ng-if="vm.field.type !== \'object\'">{{vm.field.label}}</label>\n            <input\n              xos-custom-validator custom-validator="vm.field.validators.custom || null"\n              ng-if="vm.field.type !== \'boolean\' && vm.field.type !== \'object\' && vm.field.type !== \'select\'"\n              type="{{vm.field.type}}"\n              name="{{vm.name}}"\n              class="form-control"\n              ng-model="vm.ngModel"\n              ng-minlength="vm.field.validators.minlength || 0"\n              ng-maxlength="vm.field.validators.maxlength || 2000"\n              ng-required="vm.field.validators.required || false" />\n              <select class="form-control" ng-if ="vm.field.type === \'select\'"\n                name = "{{vm.name}}"\n                ng-options="item.id as item.label for item in vm.field.options"\n                ng-model="vm.ngModel"\n                ng-required="vm.field.validators.required || false">\n                </select>\n            <span class="boolean-field" ng-if="vm.field.type === \'boolean\'">\n              <a href="#"\n                class="btn btn-success"\n                ng-show="vm.ngModel"\n                ng-click="vm.ngModel = false">\n                <i class="glyphicon glyphicon-ok"></i>\n              </a>\n              <a href="#"\n                class="btn btn-danger"\n                ng-show="!vm.ngModel"\n                ng-click="vm.ngModel = true">\n                <i class="glyphicon glyphicon-remove"></i>\n              </a>\n            </span>\n            <div\n              class="panel panel-default object-field"\n              ng-if="vm.field.type == \'object\' && (!vm.isEmptyObject(vm.ngModel) || !vm.isEmptyObject(vm.field.properties))"\n              >\n              <div class="panel-heading">{{vm.field.label}}</div>\n              <div class="panel-body">\n                <div ng-if="!vm.field.properties" ng-repeat="(k, v) in vm.ngModel">\n                  <xos-field\n                    name="k"\n                    field="{label: vm.formatLabel(k), type: vm.getType(v)}"\n                    ng-model="v">\n                  </xos-field>\n                </div>\n                <div ng-if="vm.field.properties" ng-repeat="(k, v) in vm.field.properties">\n                  <xos-field\n                    name="k"\n                    field="{\n                      label: v.label || vm.formatLabel(k),\n                      type: v.type,\n                      validators: v.validators\n                    }"\n                    ng-model="vm.ngModel[k]">\n                  </xos-field>\n                </div>\n              </div>\n            </div>\n      ',bindToController:!0,controllerAs:"vm",compile:function(n){return e.compile(n)},controller:["$attrs","XosFormHelpers","LabelFormatter",function(e,n,o){if(!this.name)throw new Error("[xosField] Please provide a field name");if(!this.field)throw new Error("[xosField] Please provide a field definition");if(!this.field.type)throw new Error("[xosField] Please provide a type in the field definition");if(!e.ngModel)throw new Error("[xosField] Please provide an ng-model");this.getType=n._getFieldFormat,this.formatLabel=o.format,this.isEmptyObject=function(e){return!e||0===Object.keys(e).length}}]}}]).directive("xosCustomValidator",function(){return{restrict:"A",scope:{fn:"=customValidator"},require:"ngModel",link:function(e,n,o,t){function i(n){var o=e.fn(n);return angular.isArray(o)?t.$setValidity.apply(t,_toConsumableArray(o)):t.$setValidity("custom",o),n}angular.isFunction(e.fn)&&t.$parsers.push(i)}}})}(),function(){angular.module("xos.uiComponents").directive("xosAlert",function(){return{restrict:"E",scope:{config:"=",show:"=?"},template:'\n        <div ng-cloak class="alert alert-{{vm.config.type}}" ng-hide="!vm.show">\n          <button type="button" class="close" ng-if="vm.config.closeBtn" ng-click="vm.dismiss()">\n            <span aria-hidden="true">&times;</span>\n          </button>\n          <p ng-transclude></p>\n        </div>\n      ',transclude:!0,bindToController:!0,controllerAs:"vm",controller:["$timeout",function(e){var n=this;if(!this.config)throw new Error('[xosAlert] Please provide a configuration via the "config" attribute');this.show=this.show!==!1,this.dismiss=function(){n.show=!1},this.config.autoHide&&!function(){var o=e(function(){n.dismiss(),e.cancel(o)},n.config.autoHide)}()}]}})}(),function(){function e(){var e=function(e){return e.split("_").join(" ").trim()},n=function(e){return e.split(/(?=[A-Z])/).map(function(e){return e.toLowerCase()}).join(" ")},o=function(e){return e.slice(0,1).toUpperCase()+e.slice(1)},t=function(t){return t=e(t),t=n(t),t=o(t).replace(/\s\s+/g," ")+":",t.replace("::",":")};return{_formatByUnderscore:e,_formatByUppercase:n,_capitalize:o,format:t}}angular.module("xos.uiComponents").factory("LabelFormatter",e)}();var _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol?"symbol":typeof e};!function(){angular.module("xos.uiComponents").service("XosFormHelpers",["_","LabelFormatter",function(e,n){var o=this;this._isEmail=function(e){var n=/(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))/;return n.test(e)},this._getFieldFormat=function(n){return angular.isArray(n)?"array":e.isDate(n)||!Number.isNaN(Date.parse(n))&&new Date(n).getTime()>6311808e5?"date":"boolean"==typeof n?"boolean":o._isEmail(n)?"email":angular.isString(n)||null===n?"text":"undefined"==typeof n?"undefined":_typeof(n)},this.buildFormStructure=function(t,i,r){return t=angular.extend(t,i),i=i||{},e.reduce(Object.keys(t),function(e,t){return e[t]={label:i[t]&&i[t].label?i[t].label+":":n.format(t),type:i[t]&&i[t].type?i[t].type:o._getFieldFormat(r[t]),validators:i[t]&&i[t].validators?i[t].validators:{},hint:i[t]&&i[t].hint?i[t].hint:""},i[t]&&i[t].options&&(e[t].options=i[t].options),i[t]&&i[t].properties&&(e[t].properties=i[t].properties),"date"===e[t].type&&(r[t]=new Date(r[t])),"number"===e[t].type&&(r[t]=parseInt(r[t],10)),e},{})},this.parseModelField=function(n){return e.reduce(n,function(e,n){return e[n]={},e},{})}}])}(),function(){function e(){return function(e,n){if(angular.isUndefined(e))return!1;if(null===e||null===n)return e===n;if(angular.isObject(n)||angular.isObject(e))return angular.equals(n,e);if(_.isBoolean(e)||_.isBoolean(n))return 0!==e&&1!==e||(e=!!e),angular.equals(n,e);if(!angular.isString(e)||!angular.isString(n)){if(!angular.isDefined(e.toString)||!angular.isDefined(n.toString))return e===n;e=e.toString(),n=n.toString()}return e=e.toLowerCase()+"",n=n.toLowerCase()+"",e.indexOf(n)!==-1}}angular.module("xos.uiComponents").factory("Comparator",e)}(),function(){function e(e,n,o){e.interceptors.push("SetCSRFToken"),n.startSymbol("{$"),n.endSymbol("$}"),o.defaults.stripTrailingSlashes=!1}e.$inject=["$httpProvider","$interpolateProvider","$resourceProvider"],angular.module("xos.helpers",["ngCookies","ngResource","ngAnimate","xos.uiComponents"]).config(e).factory("_",["$window",function(e){return e._}])}(),function(){angular.module("xos.helpers").service("vSG-Collection",["$resource",function(e){return e("/api/service/vsg/")}])}(),function(){angular.module("xos.helpers").service("vOLT-Collection",["$resource",function(e){return e("/api/tenant/cord/volt/:volt_id/",{volt_id:"@id"},{update:{method:"PUT"}})}])}(),function(){angular.module("xos.helpers").service("Login",["$resource",function(e){return e("/api/utility/login/")}]).service("Logout",["$resource",function(e){return e("/api/utility/logout/")}])}(),function(){angular.module("xos.helpers").service("Users",["$resource",function(e){return e("/api/core/users/:id/",{id:"@id"},{update:{method:"PUT"}})}])}(),function(){angular.module("xos.helpers").service("Truckroll",["$resource",function(e){return e("/api/tenant/truckroll/:id/",{id:"@id"},{update:{method:"PUT"}})}])}(),function(){angular.module("xos.helpers").service("Tenants",["$resource",function(e){return e("/api/core/tenants/:id/",{id:"@id"},{update:{method:"PUT"}})}])}(),function(){angular.module("xos.helpers").service("Subscribers",["$resource",function(e){return e("/api/tenant/cord/subscriber/:id/",{id:"@id"},{update:{method:"PUT"},"View-a-Subscriber-Features-Detail":{method:"GET",isArray:!1,url:"/api/tenant/cord/subscriber/:id/features/"},"Read-Subscriber-uplink_speed":{method:"GET",isArray:!1,url:"/api/tenant/cord/subscriber/:id/features/uplink_speed/"},"Update-Subscriber-uplink_speed":{method:"PUT",isArray:!1,url:"/api/tenant/cord/subscriber/:id/features/uplink_speed/"},"Read-Subscriber-downlink_speed":{method:"GET",isArray:!1,url:"/api/tenant/cord/subscriber/:id/features/downlink_speed/"},"Update-Subscriber-downlink_speed":{method:"PUT",isArray:!1,url:"/api/tenant/cord/subscriber/:id/features/downlink_speed/"},"Read-Subscriber-cdn":{method:"GET",isArray:!1,url:"/api/tenant/cord/subscriber/:id/features/cdn/"},"Update-Subscriber-cdn":{method:"PUT",isArray:!1,url:"/api/tenant/cord/subscriber/:id/features/cdn/"},"Read-Subscriber-uverse":{method:"GET",isArray:!1,url:"/api/tenant/cord/subscriber/:id/features/uverse/"},"Update-Subscriber-uverse":{method:"PUT",isArray:!1,url:"/api/tenant/cord/subscriber/:id/features/uverse/"},"Read-Subscriber-status":{method:"GET",isArray:!1,url:"/api/tenant/cord/subscriber/:id/features/status/"},"Update-Subscriber-status":{method:"PUT",isArray:!1,url:"/api/tenant/cord/subscriber/:id/features/status/"}})}])}(),function(){angular.module("xos.helpers").service("SlicesPlus",["$http","$q",function(e,n){this.query=function(o){var t=n.defer();return e.get("/api/utility/slicesplus/",{params:o}).then(function(e){t.resolve(e.data)})["catch"](function(e){t.reject(e.data)}),{$promise:t.promise}},this.get=function(o,t){var i=n.defer();return e.get("/api/utility/slicesplus/"+o,{params:t}).then(function(e){i.resolve(e.data)})["catch"](function(e){i.reject(e.data)}),{$promise:i.promise}}}])}(),function(){angular.module("xos.helpers").service("Slices",["$resource",function(e){return e("/api/core/slices/:id/",{id:"@id"},{update:{method:"PUT"}})}])}(),function(){angular.module("xos.helpers").service("Sites",["$resource",function(e){return e("/api/core/sites/:id/",{id:"@id"},{update:{method:"PUT"}})}])}(),function(){angular.module("xos.helpers").service("Services",["$resource",function(e){return e("/api/core/services/:id/",{id:"@id"},{update:{method:"PUT"}})}])}(),function(){angular.module("xos.helpers").service("ONOS-Services-Collection",["$resource",function(e){return e("/api/service/onos/")}])}(),function(){angular.module("xos.helpers").service("ONOS-App-Collection",["$resource",function(e){return e("/api/tenant/onos/app/")}])}(),function(){angular.module("xos.helpers").service("Nodes",["$resource",function(e){return e("/api/core/nodes/:id/",{id:"@id"},{update:{method:"PUT"}})}])}(),function(){angular.module("xos.helpers").service("Networkstemplates",["$resource",function(e){return e("/api/core/networktemplates/:id/",{id:"@id"},{update:{method:"PUT"}})}])}(),function(){angular.module("xos.helpers").service("Networks",["$resource",function(e){return e("/api/core/networks/:id/",{id:"@id"},{update:{method:"PUT"}})}])}(),function(){angular.module("xos.helpers").service("Me",["$q","$http",function(e,n){this.get=function(){var o=e.defer();return n.get("/api/utility/me/").then(function(e){o.resolve(e.data)})["catch"](function(e){o.reject(e)}),o.promise}}])}(),function(){angular.module("xos.helpers").service("Instances",["$resource",function(e){return e("/api/core/instances/:id/",{id:"@id"},{update:{method:"PUT"}})}])}(),function(){angular.module("xos.helpers").service("Images",["$resource",function(e){return e("/api/core/images/:id/",{id:"@id"},{update:{method:"PUT"}})}])}(),function(){angular.module("xos.helpers").service("Flavors",["$resource",function(e){return e("/api/core/flavors/:id/",{id:"@id"},{update:{method:"PUT"}})}])}(),function(){angular.module("xos.helpers").service("Example-Services-Collection",["$resource",function(e){return e("/api/service/exampleservice/")}])}(),function(){angular.module("xos.helpers").service("Deployments",["$resource",function(e){return e("/api/core/deployments/:id/",{id:"@id"},{update:{method:"PUT"}})}])}(),function(){angular.module("xos.helpers").service("Dashboards",["$resource","$q","$http",function(e,n,o){var t=e("/api/core/dashboardviews/:id/",{id:"@id"},{update:{method:"PUT"}});return t.prototype.$save=function(){var e=n.defer();return o.put("/api/core/dashboardviews/"+this.id+"/",this).then(function(n){e.resolve(n.data)})["catch"](function(n){e.reject(n.data)}),e.promise},t}])}(),function(){angular.module("xos.helpers").service("XosUserPrefs",["$cookies","Me","$q",function(e,n,o){var t=this,i=e.get("xosUserPrefs")?angular.fromJson(e.get("xosUserPrefs")):{};this.getAll=function(){return i=e.get("xosUserPrefs")?angular.fromJson(e.get("xosUserPrefs")):{}},this.setAll=function(n){e.put("xosUserPrefs",angular.toJson(n))},this.getSynchronizerNotificationStatus=function(){var e=!(arguments.length<=0||void 0===arguments[0])&&arguments[0];return e?t.getAll().synchronizers.notification[e]:t.getAll().synchronizers.notification},this.getUserDetailsCookie=function(){var e=o.defer(),n=t.getAll();return n.userData?e.resolve(n.userData):t.setUserDetailsCookie().$promise.then(function(n){e.resolve(n)}),{$promise:e.promise}},this.setUserDetailsCookie=function(){var e=arguments.length<=0||void 0===arguments[0]?null:arguments[0],i=o.defer(),r=t.getAll();return e?(r.userData=e,t.setAll(r),i.resolve(e)):n.get().then(function(e){r.userData=e,t.setAll(r),i.resolve(e)})["catch"](function(e){i.reject(e)}),{$promise:i.promise}},this.setSynchronizerNotificationStatus=function(){var e=!(arguments.length<=0||void 0===arguments[0])&&arguments[0],n=arguments[1];
-if(!e)throw new Error("[XosUserPrefs] When updating a synchronizer is mandatory to provide a name.");var o=t.getAll();o.synchronizers||(o.synchronizers={notification:{}}),o.synchronizers.notification[e]=n,t.setAll(o)}}])}(),function(){angular.module("xos.helpers").service("GraphService",["$q","Tenants","Services",function(e,n,o){var t=this;this.loadCoarseData=function(){var t=void 0,i=e.defer();return o.query().$promise.then(function(e){return t=e,n.query({kind:"coarse"}).$promise}).then(function(e){i.resolve({tenants:e,services:t})}),i.promise},this.getCoarseGraph=function(){return t.loadCoarseData().then(function(e){console.log(e)}),"ciao"}}])}(),function(){angular.module("xos.helpers").factory("Notification",function(){return window.Notification}).service("xosNotification",["$q","$log","Notification",function(e,n,o){var t=this;this.checkPermission=function(){var n=e.defer();return o.requestPermission().then(function(e){"granted"===e?n.resolve(e):n.reject(e)}),n.promise},this.sendNotification=function(e,t){var i=new o(e,t);i.onerror=function(e){n.error(e)}},this.notify=function(e,i){"Notification"in window?"granted"!==o.permission?t.checkPermission().then(function(){return t.sendNotification(e,i)}):"granted"===o.permission&&t.sendNotification(e,i):n.info("This browser does not support desktop notification")}}])}(),function(){function e(){return{request:function(e){return e.url.indexOf(".html")===-1&&(e.url+="?no_hyperlinks=1"),e}}}angular.module("xos.helpers").factory("NoHyperlinks",e)}(),angular.module("xos.helpers").config(["$provide",function(e){e.decorator("$log",["$delegate",function(e){var n=function(){return window.location.href.indexOf("debug=true")>=0},o=e.log,t=e.info,i=e.warn,r=e.debug,a=function(o){return function(){if(n()){var t=[].slice.call(arguments),i=new Date;return t[0]="["+i.getHours()+":"+i.getMinutes()+":"+i.getSeconds()+"] "+t[0],!angular.isFunction(e.reset)||e.debug.logs instanceof Array||e.reset(),o.apply(null,t)}}};return e.info=a(t),e.log=a(o),e.warn=a(i),e.debug=a(r),e}])}]),function(){function e(e){return{request:function(n){return"GET"!==n.method&&(n.headers["X-CSRFToken"]=e.get("xoscsrftoken")),n}}}e.$inject=["$cookies"],angular.module("xos.helpers").factory("SetCSRFToken",e)}();
\ No newline at end of file
diff --git a/xos/core/xoslib/static/js/vendor/jquery-1.11.3.js b/xos/core/xoslib/static/vendor/jquery-1.11.3.js
similarity index 100%
rename from xos/core/xoslib/static/js/vendor/jquery-1.11.3.js
rename to xos/core/xoslib/static/vendor/jquery-1.11.3.js
diff --git a/xos/core/xoslib/static/js/vendor/xosCeilometerDashboardVendor.js b/xos/core/xoslib/static/vendor/xosCeilometerDashboardVendor.js
similarity index 100%
rename from xos/core/xoslib/static/js/vendor/xosCeilometerDashboardVendor.js
rename to xos/core/xoslib/static/vendor/xosCeilometerDashboardVendor.js
diff --git a/xos/core/xoslib/static/js/vendor/xosDashboardManagerVendor.js b/xos/core/xoslib/static/vendor/xosDashboardManagerVendor.js
similarity index 100%
rename from xos/core/xoslib/static/js/vendor/xosDashboardManagerVendor.js
rename to xos/core/xoslib/static/vendor/xosDashboardManagerVendor.js
diff --git a/xos/core/xoslib/static/js/vendor/xosDiagnosticVendor.js b/xos/core/xoslib/static/vendor/xosDiagnosticVendor.js
similarity index 100%
rename from xos/core/xoslib/static/js/vendor/xosDiagnosticVendor.js
rename to xos/core/xoslib/static/vendor/xosDiagnosticVendor.js
diff --git a/xos/core/xoslib/static/js/vendor/xosMcordTopologyVendor.js b/xos/core/xoslib/static/vendor/xosMcordTopologyVendor.js
similarity index 100%
rename from xos/core/xoslib/static/js/vendor/xosMcordTopologyVendor.js
rename to xos/core/xoslib/static/vendor/xosMcordTopologyVendor.js
diff --git a/xos/core/xoslib/static/js/vendor/xosServiceGridVendor.js b/xos/core/xoslib/static/vendor/xosServiceGridVendor.js
similarity index 100%
rename from xos/core/xoslib/static/js/vendor/xosServiceGridVendor.js
rename to xos/core/xoslib/static/vendor/xosServiceGridVendor.js
diff --git a/xos/templates/admin/base.html b/xos/templates/admin/base.html
index 43a8858..4fd5f44 100644
--- a/xos/templates/admin/base.html
+++ b/xos/templates/admin/base.html
@@ -32,8 +32,8 @@
   <script type="text/javascript" src="{% static 'uploadTextarea.js' %}"></script>
 
   <!-- ngXosLib -->
-  <script src="{% static 'js/vendor/ngXosVendor.min.js' %}"></script>
-  <script src="{% static 'js/vendor/ngXosHelpers.min.js' %}"></script>
+  <script src="{% static 'vendor/ngXosVendor.min.js' %}"></script>
+  <script src="{% static 'vendor/ngXosHelpers.min.js' %}"></script>
 
   <script type="text/javascript">var Suit = { $: $.noConflict() }; if (!$) $ = Suit.$; </script>
   {% if 'SHOW_REQUIRED_ASTERISK'|suit_conf %}
diff --git a/xos/tests/ui/karma.conf.views.js b/xos/tests/ui/karma.conf.views.js
index 3cf82df..876c533 100644
--- a/xos/tests/ui/karma.conf.views.js
+++ b/xos/tests/ui/karma.conf.views.js
@@ -11,7 +11,7 @@
 const fs = require('fs');
 
 const viewDir = '../../core/xoslib/static/js/';
-const vendorDir = '../../core/xoslib/static/js/vendor/';
+const vendorDir = '../../core/xoslib/static/vendor/';
 let viewFiles = fs.readdirSync(viewDir);
 let vendorFiles = fs.readdirSync(vendorDir);