Added mCord apps
diff --git a/views/ngXosViews/mcordTopology/src/css/dev.css b/views/ngXosViews/mcordTopology/src/css/dev.css
new file mode 100644
index 0000000..32d915d
--- /dev/null
+++ b/views/ngXosViews/mcordTopology/src/css/dev.css
@@ -0,0 +1,7 @@
+#xosMcordTopology{
+  position: absolute;
+  /*top: 100px;
+  left: 200px;*/
+  width: 100%;
+  height: 100%;
+}
\ No newline at end of file
diff --git a/views/ngXosViews/mcordTopology/src/css/mcord.css b/views/ngXosViews/mcordTopology/src/css/mcord.css
new file mode 100644
index 0000000..68cca28
--- /dev/null
+++ b/views/ngXosViews/mcordTopology/src/css/mcord.css
@@ -0,0 +1,62 @@
+[ui-view],
+m-cord-topology{
+  width: 100%;
+  height: 100%;
+  display: block;
+}
+
+line {
+  stroke: blue;
+  stroke-width: 1;
+}
+
+line.big{
+  stroke-width: 2;
+}
+
+circle,
+rect {
+  fill: #fff;
+  stroke-width: 1; 
+}
+
+.fabric {
+  stroke: none;
+  fill: #123456;
+  fill-rule: evenodd;
+}
+
+.fabric-container {
+  fill: transparent;
+  stroke: #000;
+  stroke-width: 1;
+}
+
+.bbu {
+  stroke: black;
+  fill: #FF7F0E;
+}
+
+.rru {
+  stroke: #000;
+  fill: #FFBB78;
+}
+
+.rru-shadow {
+  fill: #FFBB78;
+  opacity: .4
+}
+
+.MME, .SGW, .PGW {
+  fill: purple;
+  stroke: #000;
+}
+
+.bbu text, 
+.MME text,
+.SGW text,
+.PGW text {
+  font-size: 10px;
+  stroke-width: 0;
+  fill: #000;
+}
\ No newline at end of file
diff --git a/views/ngXosViews/mcordTopology/src/index.html b/views/ngXosViews/mcordTopology/src/index.html
new file mode 100644
index 0000000..691a869
--- /dev/null
+++ b/views/ngXosViews/mcordTopology/src/index.html
@@ -0,0 +1,36 @@
+<!-- browserSync -->
+<!-- bower:css -->
+<link rel="stylesheet" href="vendor/bootstrap-css/css/bootstrap.css" />
+<!-- endbower --><!-- endcss -->
+<!-- inject:css -->
+<link rel="stylesheet" href="/css/dev.css">
+<link rel="stylesheet" href="/css/mcord.css">
+<!-- endinject -->
+
+<div ng-app="xos.mcordTopology" id="xosMcordTopology">
+    <div ui-view></div>
+</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-resource/angular-resource.js"></script>
+<script src="vendor/ng-lodash/build/ng-lodash.js"></script>
+<script src="vendor/bootstrap-css/js/bootstrap.js"></script>
+<!-- endbower --><!-- endjs -->
+<!-- inject:js -->
+<script src="/xosHelpers/src/xosHelpers.module.js"></script>
+<script src="/xosHelpers/src/services/noHyperlinks.interceptor.js"></script>
+<script src="/xosHelpers/src/services/csrfToken.interceptor.js"></script>
+<script src="/xosHelpers/src/services/api.services.js"></script>
+<script src="/api/ng-xoslib.js"></script>
+<script src="/api/ng-xos.js"></script>
+<script src="/api/ng-hpcapi.js"></script>
+<script src="/.tmp/main.js"></script>
+<script src="/.tmp/static.data.js"></script>
+<script src="/.tmp/node_drawer.js"></script>
+<!-- endinject -->
diff --git a/views/ngXosViews/mcordTopology/src/js/main.js b/views/ngXosViews/mcordTopology/src/js/main.js
new file mode 100644
index 0000000..bf57f1d
--- /dev/null
+++ b/views/ngXosViews/mcordTopology/src/js/main.js
@@ -0,0 +1,296 @@
+'use strict';
+
+angular.module('xos.mcordTopology', [
+  'ngResource',
+  'ngCookies',
+  'ngLodash',
+  'ui.router',
+  'xos.helpers'
+])
+.config(($stateProvider) => {
+  $stateProvider
+  .state('topology', {
+    url: '/',
+    template: '<m-cord-topology></m-cord-topology>'
+  });
+})
+.config(function($httpProvider){
+  $httpProvider.interceptors.push('NoHyperlinks');
+})
+.directive('mCordTopology', function(){
+  return {
+    restrict: 'E',
+    scope: {},
+    bindToController: true,
+    controllerAs: 'vm',
+    template: '',
+    controller: function($element, $interval, XosApi, lodash, TopologyElements, NodeDrawer){
+
+      const el = $element[0];
+
+      let nodes = [];
+      let links = [];
+
+      const filterBBU = (instances) => {
+        return lodash.filter(instances, i => i.name.indexOf('BBU') >= 0);
+      };
+
+      const filterOthers = (instances) => {
+        return lodash.filter(instances, i => {
+          return (i.name.indexOf('MME') >= 0)
+          || (i.name.indexOf('SGW') >= 0)
+          || (i.name.indexOf('PGW') >= 0)
+        });
+      };
+
+      // retrieving instances list
+      const getData = () => {
+
+        nodes = TopologyElements.nodes;
+        links = TopologyElements.links;
+
+        XosApi.Instance_List_GET()
+        .then((instances) => {
+          addBbuNodes(filterBBU(instances));
+          addOtherNodes(filterOthers(instances));
+
+          draw(svg, nodes, links);
+        })
+        .catch((e) => {
+          throw new Error(e);
+        });
+      };
+
+      const force = d3.layout.force();
+
+      // create svg elements
+      const svg = d3.select(el)
+        .append('svg')
+        .style('width', `${el.clientWidth}px`)
+        .style('height', `${el.clientHeight}px`);
+
+      const linkContainer = svg.append('g')
+        .attr({
+          class: 'link-container'
+        });
+
+      const nodeContainer = svg.append('g')
+        .attr({
+          class: 'node-container'
+        });
+
+      // replace human readable ids with d3 ids
+      // NOTE now ids are not manatined on update...
+      const buildLinks = (links, nodes) => {
+        return links.map((l) => {
+
+
+          let source = lodash.findIndex(nodes, {id: l.source});
+          let target = lodash.findIndex(nodes, {id: l.target});
+          // console.log(`link-${source}-${target}`, source, target);
+          return {
+            source: source,
+            target: target,
+            value: 1,
+            id: `link-${source}-${target}`,
+            type: l.source.indexOf('fabric') >= 0 ? 'big':'small'
+          };
+
+        });
+      };
+
+      // find fabric nodes and center horizontally
+      const positionFabricNodes = (nodes) => {
+        return lodash.map(nodes, n => {
+          if(n.type !== 'fabric'){
+            return n;
+          }
+
+          n.x = n.x * hStep;
+          n.y = n.y * vStep;
+
+          return n;
+        });
+      };
+
+      const addBbuNodes = (instances) => {
+
+        // calculate bbu hStep
+        let bbuHStep = ((el.clientWidth / 2) / (instances.length + 1));
+
+        // create nodes
+        let bbuNodes = instances.map((n, i) => {
+          return {
+            type: 'bbu',
+            name: n.name,
+            id: `bbu-${n.id}`,
+            fixed: true,
+            y: vStep * 3,
+            x: bbuHStep * (i + 1)
+          };
+        });
+
+        // create links
+        let bbuLinks = bbuNodes.map(n => {
+          return {
+            source: n.id,
+            target: 'fabric2'
+          };
+        });
+
+        // fake RRU nodes and links
+        instances.forEach((n, i) => {
+          bbuNodes.push({
+            type: 'rru',
+            name: 'rru',
+            id: `rru-${n.id}`,
+            fixed: true,
+            y: vStep * 4,
+            x: bbuHStep * (i + 1)
+          });
+
+          bbuLinks.push({
+            source: `rru-${n.id}`,
+            target: `bbu-${n.id}`
+          });
+        })
+
+        nodes = nodes.concat(bbuNodes);
+
+
+        links = links.concat(bbuLinks);
+      };
+
+      // add MME, PGW, SGW nodes
+      const addOtherNodes = (instances) => {
+        let hStep = ((el.clientWidth / 2) / (instances.length + 1));
+
+        // create nodes
+        let otherNodes = instances.map((n, i) => {
+          return {
+            type: n.name.substring(0, 3),
+            name: n.name,
+            id: `${n.name.substring(0, 3)}-${n.id}`,
+            fixed: true,
+            y: vStep * 3,
+            x: (el.clientWidth / 2) + (hStep * (i + 1))
+          };
+        });
+
+        // create links
+        let otherLinks = otherNodes.map(n => {
+          return {
+            source: n.id,
+            target: 'fabric4'
+          };
+        });
+
+
+        nodes = nodes.concat(otherNodes);
+        links = links.concat(otherLinks);
+      }
+
+      let hStep, vStep;
+
+      hStep = el.clientWidth / 3;
+      vStep = el.clientHeight / 5;
+
+      const draw = (svg, nodes, links) => {
+
+        hStep = el.clientWidth / 3;
+        vStep = el.clientHeight / 5;
+
+        links = buildLinks(links, nodes);
+
+        nodes = positionFabricNodes(nodes);
+
+
+        // start force layout
+        force
+          .nodes(nodes)
+          .links(links)
+          .size([el.clientWidth, el.clientHeight])
+          .charge(-20)
+          .chargeDistance(200)
+          .linkDistance(80)
+          .linkStrength(0.1)
+          .start();
+
+
+        const linkContainer = d3.select('.link-container');
+        const nodeContainer = d3.select('.node-container');
+
+        NodeDrawer.drawFabricBox(nodeContainer, hStep, vStep);
+
+        // draw links
+        var link = linkContainer.selectAll('.link')
+          .data(links, d => d.id);
+        
+        link.enter().append('line')
+          .attr({
+            // class: 'link',
+            id: d => d.id,
+            opacity: 0,
+            class: d => `link ${d.type}`
+          })
+          .transition()
+          .duration(1000)
+          // .delay((d, i) => 50 * i)
+          .attr({
+            opacity: 1
+          });
+
+        link.exit()
+        .remove();
+
+        //draw nodes
+        var node = nodeContainer.selectAll('.node')
+          .data(nodes, d => {
+            return d.id
+          });
+        
+        // append a group for any new node
+        var enter = node.enter()
+          .append('g', d => d.interfaceCfgIdentifier)
+          .attr({
+            class: d => `${d.type} node`,
+            transform: d => `translate(${d.x}, ${d.y})`
+          });
+
+        // draw nodes
+        NodeDrawer.drawBbus(enter.filter('.bbu'))
+        NodeDrawer.drawRrus(enter.filter('.rru'))
+        NodeDrawer.drawFabric(enter.filter('.fabric'))
+        NodeDrawer.drawOthers(enter.filter(d => {
+          return (
+            d.type  === 'MME' ||
+            d.type === 'SGW' ||
+            d.type === 'PGW'
+          )
+        }));
+
+        // remove nodes
+        var exit = node.exit();
+
+        NodeDrawer.removeElements(exit);
+
+        force.on('tick', function() {
+          link
+            .attr('x1', d => d.source.x )
+            .attr('y1', d => d.source.y )
+            .attr('x2', d => d.target.x )
+            .attr('y2', d => d.target.y );
+
+          node.attr('transform', (d) => `translate(${d.x},${d.y})`);
+        });
+      };
+      
+      $interval(() => {
+        getData();
+      }, 5000);
+      getData();
+
+      
+    }
+  };
+});
\ No newline at end of file
diff --git a/views/ngXosViews/mcordTopology/src/js/node_drawer.js b/views/ngXosViews/mcordTopology/src/js/node_drawer.js
new file mode 100644
index 0000000..14bdf99
--- /dev/null
+++ b/views/ngXosViews/mcordTopology/src/js/node_drawer.js
@@ -0,0 +1,167 @@
+'use strict';
+
+angular.module('xos.mcordTopology')
+.service('NodeDrawer', function(TopologyElements){
+
+  const duration = 500;
+
+  let isFabricDrawed = false;
+
+  this.drawFabricBox = (svg, hStep, vStep) => {
+
+    if(isFabricDrawed){
+      return;
+    }
+
+    let fabric = svg.append('g')
+    .attr({
+      transform: `translate(${hStep - 25}, ${vStep - 25})`
+    });
+
+    fabric.append('rect')
+      .attr({
+        width: hStep + 50,
+        height: vStep + 50,
+        class: 'fabric-container'
+      });
+
+    fabric.append('text')
+    .text('Fabric')
+    .attr({
+      'text-anchor': 'middle',
+      x: ((hStep + 50) / 2),
+      y: -10
+    });
+
+    isFabricDrawed = true;
+  };
+
+  this.drawBbus = (nodes) => {
+
+    nodes.append('circle')
+      .attr({
+        class: d => d.type,
+        r: 0,
+        opacity: 0
+      })
+      .transition()
+      .duration(duration)
+      // .delay((d, i) => i * (duration / 2))
+      .attr({
+        r: 15,
+        opacity: 1
+      });
+
+    nodes.append('text')
+    .attr({
+      'text-anchor': 'start',
+      y: 17,
+      x: 17,
+      opacity: 0
+    })
+    .text(d => `BBU ${d.name.substr(d.name.length - 1, 1)}`)
+    .transition()
+    .duration(duration * 2)
+    .attr({
+      opacity: 1
+    });
+  };
+
+  this.drawRrus = (nodes) => {
+
+    nodes.append('circle')
+      .attr({
+        class: d => `${d.type}-shadow`,
+        r: 0,
+        opacity: 0
+      })
+      .transition()
+      .duration(duration * 2)
+      // .delay((d, i) => i * (duration / 2))
+      .attr({
+        r: 30,
+        opacity: 1
+      });
+  
+    nodes.append('circle')
+      .attr({
+        class: d => d.type,
+        r: 0,
+        opacity: 0
+      })
+      .transition()
+      .duration(duration)
+      // .delay((d, i) => i * (duration / 2))
+      .attr({
+        r: 10,
+        opacity: 1
+      });
+  };
+
+  this.drawFabric = (nodes) => {
+    nodes
+      .append('rect')
+      .attr({
+        width: 30,
+        height: 30,
+        x: -15,
+        y: -15
+      });
+
+    nodes
+      .append('path')
+      .attr({
+        class: d => d.type,
+        opacity: 0,
+        d: () => TopologyElements.icons.switch,
+        transform: `translate(-22, -22), scale(0.4)`
+      })
+      .transition()
+      .duration(duration)
+      // .delay((d, i) => i * (duration / 2))
+      .attr({
+        opacity: 1
+      });
+  };
+
+  this.drawOthers = (nodes) => {
+    nodes.append('circle')
+      .attr({
+        class: d => d.type,
+        r: 0,
+        opacity: 0
+      })
+      .transition()
+      .duration(duration)
+      // .delay((d, i) => i * (duration / 2))
+      .attr({
+        r: 15,
+        opacity: 1
+      });
+
+    nodes.append('text')
+    .attr({
+      'text-anchor': 'start',
+      y: 17,
+      x: 17,
+      opacity: 0
+    })
+    .text(d => d.type)
+    .transition()
+    .duration(duration * 2)
+    .attr({
+      opacity: 1
+    });
+
+  };
+
+  this.removeElements = (nodes) => {
+    nodes
+    .transition()
+    .duration(duration)
+    .attr({
+      opacity: 0
+    })
+    .remove();
+  };
+});
\ No newline at end of file
diff --git a/views/ngXosViews/mcordTopology/src/js/static.data.js b/views/ngXosViews/mcordTopology/src/js/static.data.js
new file mode 100644
index 0000000..c38239d
--- /dev/null
+++ b/views/ngXosViews/mcordTopology/src/js/static.data.js
@@ -0,0 +1,63 @@
+'use strict';
+
+angular.module('xos.mcordTopology')
+.constant('TopologyElements', {
+  nodes: [
+    {
+      id: 'fabric1',
+      type: 'fabric',
+      name: 'fabric1',
+      fixed: true,
+      x: 1,
+      y: 1
+    },
+    {
+      id: 'fabric2',
+      type: 'fabric',
+      name: 'fabric2',
+      fixed: true,
+      x: 1,
+      y: 2
+    },
+    {
+      id: 'fabric3',
+      type: 'fabric',
+      name: 'fabric3',
+      fixed: true,
+      x: 2,
+      y: 1
+    },
+    {
+      id: 'fabric4',
+      type: 'fabric',
+      name: 'fabric4',
+      fixed: true,
+      x: 2,
+      y: 2
+    }
+  ],
+  links: [
+    {
+      source: 'fabric1',
+      target: 'fabric2'
+    },
+    {
+      source: 'fabric1',
+      target: 'fabric4'
+    },
+    {
+      source: 'fabric3',
+      target: 'fabric4'
+    },
+    {
+      source: 'fabric3',
+      target: 'fabric2'
+    }
+  ],
+  icons: {
+    switch: `M10,20a10,10,0,0,1,10-10h70a10,10,0,0,1,10,10v70a10,10,
+            0,0,1-10,10h-70a10,10,0,0,1-10-10zM60,26l12,0,0-8,18,13-18,13,0
+            -8-12,0zM60,60l12,0,0-8,18,13-18,13,0-8-12,0zM50,40l-12,0,0-8
+            -18,13,18,13,0-8,12,0zM50,74l-12,0,0-8-18,13,18,13,0-8,12,0z`,
+  }
+})
\ No newline at end of file