diff --git a/tvue/src/main/webapp/index.html b/tvue/src/main/webapp/index.html
new file mode 100644
index 0000000..15f7c20
--- /dev/null
+++ b/tvue/src/main/webapp/index.html
@@ -0,0 +1,382 @@
+<!DOCTYPE html>
+<!--
+  ~ Copyright 2014 Open Networking Laboratory
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<html>
+<head>
+    <title>Topology Viewer</title>
+    <script src="libs/d3.v3.min.js"></script>
+    <script src="libs/jquery-1.11.1.min.js"></script>
+    <style>
+        .link {
+        }
+
+        .node {
+            stroke-width: 3px;
+        }
+
+        .textClass {
+            stroke: #323232;
+            font-family: "Lucida Grande", "Droid Sans", Arial, Helvetica, sans-serif;
+            font-weight: normal;
+            stroke-width: .5;
+            font-size: 14px;
+        }
+    </style>
+</head>
+<body>
+    <script>
+        // Adapted from sample code @ ericcoopey’s block #6c602d7cb14b25c179a4
+        // by Thomas Vachuska
+
+        var graph,
+                topo = {vertexes:{}, edges:{}},
+                paths = [],
+                currentPath = 0;
+
+        // Set up the canvas
+        var w = 2048,
+                h = 2048;
+
+        // Allocate colors predictably
+        var color = d3.scale.category10(),
+                deviceColor = color(2),
+                sourceColor = color(0),
+                targetColor = color(1),
+                dummy1Color = color(9),
+                dummy2Color = color(8),
+                dummy3Color = color(7),
+                dummy4Color = color(6),
+                offlineColor = color(5),
+                dummy5Color = color(4),
+                hostColor = color(3);
+
+        var selectedNode,
+                sourceNode,
+                targetNode,
+                pathRequested;
+
+
+        function fillColor(d) {
+            return ((targetNode && targetNode.id == d.id) ? targetColor :
+                    ((sourceNode && sourceNode.id == d.id) ? sourceColor :
+                            d.online ? color(d.group) : offlineColor));
+        }
+
+        function strokeColor(d) {
+            return selectedNode && d.id == selectedNode.id ? "#f00" : "#aaa";
+        }
+
+        function linkColor(d) {
+            if (!paths || paths.length == 0) {
+                return "#666";
+            }
+
+            var path = paths[currentPath];
+            if (path) {
+                for (var i = 0, n = path.length; i < n; i++) {
+                    var link = path[i];
+                    if ((link.src == d.source.id || link.dst == d.source.id) &&
+                            (link.dst == d.target.id || link.src == d.target.id)) {
+                        return "#f00";
+                    }
+                }
+            }
+            return "#666";
+        }
+
+        function linkKey(link) {
+            return link.source.id + "-" + link.target.id;
+
+        };
+
+        function toggleNode(node) {
+            pathRequested = false;
+            return selectedNode && selectedNode != node ? selectedNode : null;
+
+        };
+
+        function refreshPaths() {
+            d3.selectAll("line").attr("stroke", linkColor);
+        }
+
+        function fetchPaths() {
+            if (!pathRequested && sourceNode && targetNode) {
+                pathRequested = true;
+                d3.json("rs/topology/paths/" + sourceNode.id + "/" + targetNode.id, function(error, data) {
+                    currentPath = 0;
+                    paths = data.paths;
+                    refreshPaths();
+                });
+            }
+        }
+
+        function resetSelections() {
+            selectedNode = null;
+            sourceNode = null;
+            targetNode = null;
+            paths = [];
+            currentPath = 0;
+            refreshPaths();
+            d3.selectAll(".nodeStrokeClass").attr("stroke", strokeColor);
+        }
+
+        function nextPath() {
+            currentPath = paths && currentPath < paths.length - 1 ? currentPath + 1 : 0
+            console.log("Showing path: " + currentPath);
+            refreshPaths();
+        }
+
+        function dblclick(d) {
+            d3.select(this).classed("fixed", d.fixed = false);
+        }
+
+        function dragstart(d) {
+            // d3.select(this).classed("fixed", d.fixed = true);
+        }
+
+
+        function topoGraph() {
+            // Add and remove elements on the graph object
+            this.addNode = function (vertex, stamp) {
+                var node = topo.vertexes[vertex.name];
+                if (node) {
+                    var oldState = node.online;
+                    node.online = vertex.online;
+                    node.stamp = stamp;
+                    if (oldState != node.online) {
+                        update();
+                        return true;
+                    }
+                    return false;
+                }
+                node = {"id": vertex.name, "label": vertex.label,
+                    "group": vertex.group, "online": vertex.online, "stamp": stamp};
+                nodes.push(node);
+                topo.vertexes[vertex.name] = node;
+                update();
+                return true;
+            };
+
+            this.addLink = function (edge, stamp) {
+                var key = edge.source + "-" + edge.target;
+                var link = topo.edges[key];
+                if (link) {
+                    var oldValue = link.value;
+                    link.value = edge.value;
+                    link.stamp = stamp;
+                    if (oldValue != link.value) {
+                        update();
+                        return true;
+                    }
+                    return false;
+                }
+                link = {"source": findNode(edge.source), "target": findNode(edge.target),
+                        "value": edge.value, "stamp": stamp};
+                links.push(link);
+                topo.edges[key] = link;
+                update();
+                return true;
+            };
+
+            this.prune = function (stamp) {
+                var linksChanged = pruneArray(links, stamp, topo.edges, linkKey);
+                var nodesChanged = pruneArray(nodes, stamp, topo.vertexes,
+                        function(node) { return node.id; });
+                if (linksChanged || nodesChanged) {
+                    update();
+                    return true;
+                }
+                return false;
+            };
+
+            var pruneArray = function(array, stamp, map, key) {
+                var changed = false;
+                for (var i = 0; i < array.length; i++) {
+                    if (array[i].stamp < stamp) {
+                        changed = true;
+                        map[key(array[i])] = null;
+                        array.splice(i, 1);
+                        i--;
+                    }
+                }
+                return changed;
+            };
+
+            var findNode = function (id) {
+                for (var i in nodes) {
+                    if (nodes[i]["id"] === id) return nodes[i];
+                }
+            };
+
+            var force = d3.layout.force();
+
+            var drag = force.drag()
+                    .on("dragstart", dragstart);
+
+            var nodes = force.nodes(),
+                    links = force.links();
+
+            var vis = d3.select("body")
+                    .append("svg:svg")
+                    .attr("width", w)
+                    .attr("height", h)
+                    .attr("id", "svg")
+                    .attr("pointer-events", "all")
+                    .attr("viewBox", "0 0 " + w + " " + h)
+                    .attr("perserveAspectRatio", "xMinYMid")
+                    .append('svg:g');
+
+            d3.select("body")
+                    .on("keydown", function(d) {
+                        console.log(d3.event.keyCode);
+                        if (d3.event.keyCode == 27) {
+                            resetSelections();
+                        } else if (d3.event.keyCode == 83) {
+                            sourceNode = toggleNode(sourceNode);
+                        } else if (d3.event.keyCode == 68) {
+                            targetNode = toggleNode(targetNode);
+                        } else if (d3.event.keyCode == 65) {
+                            var aux = sourceNode;
+                            sourceNode = targetNode;
+                            targetNode = aux;
+                        } else if (d3.event.keyCode == 70) {
+                            nextPath();
+                        } else if (d3.event.keyCode == 67 && selectedNode) {
+                            selectedNode.fixed = !selectedNode.fixed;
+                        }
+
+                        d3.selectAll(".nodeStrokeClass").attr("fill", fillColor);
+                        fetchPaths();
+                    });
+
+
+            var update = function () {
+                var link = vis.selectAll("line")
+                        .data(links, linkKey);
+
+                link.enter().append("line")
+                        .attr("id", linkKey)
+                        .attr("class", "link")
+                        .attr("stroke-width", function (d) { return d.value; })
+                        .attr("stroke", linkColor);
+                link.append("title").text(function (d) { return d.id; });
+                link.exit().remove();
+
+                var node = vis.selectAll("g.node")
+                        .data(nodes, function (d) { return d.id; })
+                        .on("click", function(d) {
+                            selectedNode = d;
+                            d3.selectAll(".nodeStrokeClass").attr("stroke", strokeColor);
+                        });
+
+                var nodeEnter = node.enter().append("g")
+                        .attr("class", "node")
+                        .on("dblclick", dblclick)
+                        .call(force.drag);
+
+                nodeEnter.append("svg:circle")
+                        .attr("r", function(d) { return 28 / 2; })
+                        .attr("id", function (d) { return "n-" + d.id.replace(/[.:]/g, ""); })
+                        .attr("class", "nodeStrokeClass")
+                        .attr("fill", fillColor)
+                        .attr("stroke", strokeColor);
+
+                nodeEnter.append("image")
+                        .attr("xlink:href", function(d) { return d.group == 2 ? "images/switch.png" : "images/server.png"; })
+                        .attr("x", -12)
+                        .attr("y", -12)
+                        .attr("width", 24)
+                        .attr("height", 24);
+
+                nodeEnter.append("svg:text")
+                        .attr("class", "textClass")
+                        .attr("x", 20)
+                        .attr("y", ".31em")
+                        .text(function (d) { return d.label; });
+
+                node.exit().remove();
+
+                d3.selectAll("nodeStrokeClass").attr("stroke", strokeColor);
+
+                force.on("tick", function () {
+                    node.attr("transform", function (d) {
+                        return "translate(" + d.x + "," + d.y + ")";
+                    });
+
+                    link.attr("x1", function (d) { return d.source.x; })
+                            .attr("y1", function (d) { return d.source.y; })
+                            .attr("x2", function (d) { return d.target.x; })
+                            .attr("y2", function (d) { return d.target.y; });
+                });
+
+                // Restart the force layout.
+                force
+                        .gravity(0.3)
+                        .charge(-15000)
+                        .friction(0.1)
+                        .linkDistance(function(d) { return d.value * 30; })
+                        .linkStrength(function(d) { return d.value * 0.6; })
+                        .size([w, h])
+                        .start();
+            };
+
+            // Make it all go
+            update();
+        }
+
+        function drawGraph() {
+            graph = new topoGraph("#svgdiv");
+            bringNodesToFront();
+        }
+
+        function bringNodesToFront() {
+            $(".nodeStrokeClass").each(function( index ) {
+                var gnode = this.parentNode;
+                gnode.parentNode.appendChild(gnode);
+            });
+        }
+
+        function addNodes() {
+            d3.select("svg")
+                    .remove();
+            drawGraph();
+        }
+
+        function fetchData() {
+            var stamp = new Date().getTime();
+                d3.json("rs/topology/graph", function(error, data) {
+                var changed = false;
+                data.vertexes.forEach(function(vertex) { changed = graph.addNode(vertex, stamp) || changed; });
+                data.edges.forEach(function(edge) { changed = graph.addLink(edge, stamp) || changed; });
+
+                changed = graph.prune(stamp) || changed;
+                if (changed) {
+                    bringNodesToFront();
+                    // Update node and links styles
+                    d3.selectAll(".nodeStrokeClass").attr("fill", fillColor);
+                    d3.selectAll(".line").attr("stroke-width", function (d) { return d.value; })
+                }
+
+                setTimeout(fetchData, 1000);
+            });
+        };
+
+        drawGraph();
+        setTimeout(fetchData, 500);
+
+    </script>
+</body>
+</html>
\ No newline at end of file
