diff --git a/WORKSPACE b/WORKSPACE
index c1e6d7e..9b26760 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -110,14 +110,14 @@
   name = "iron_dropdown",
   build_file = "bower.BUILD",
   remote = "https://github.com/polymerelements/iron-dropdown.git",
-  tag = "v1.3.1",
+  tag = "v1.4.0",
 )
 
 new_git_repository(
   name = "iron_fit_behavior",
   build_file = "bower.BUILD",
   remote = "https://github.com/polymerelements/iron-fit-behavior.git",
-  tag = "v1.0.6",
+  tag = "v1.2.0",
 )
 
 new_git_repository(
@@ -187,7 +187,7 @@
   name = "iron_overlay_behavior",
   build_file = "bower.BUILD",
   remote = "https://github.com/polymerelements/iron-overlay-behavior.git",
-  tag = "v1.6.4",
+  tag = "1.7.2",
 )
 
 new_git_repository(
@@ -215,7 +215,7 @@
   name = "iron_validatable_behavior",
   build_file = "bower.BUILD",
   remote = "https://github.com/polymerelements/iron-validatable-behavior.git",
-  tag = "v1.1.0",
+  tag = "v1.1.1",
 )
 
 new_git_repository(
@@ -264,7 +264,7 @@
   name = "paper_dialog_behavior",
   build_file = "bower.BUILD",
   remote = "https://github.com/polymerelements/paper-dialog-behavior.git",
-  tag = "v1.2.5",
+  tag = "v1.2.6",
 )
 
 new_git_repository(
@@ -285,7 +285,7 @@
   name = "paper_icon_button",
   build_file = "bower.BUILD",
   remote = "https://github.com/polymerelements/paper-icon-button.git",
-  tag = "v1.0.7",
+  tag = "v1.1.1",
 )
 
 new_git_repository(
@@ -411,7 +411,7 @@
   name = "web_animations_js",
   build_file = "bower.BUILD",
   remote = "https://github.com/web-animations/web-animations-js.git",
-  tag = "2.2.0",
+  tag = "2.2.1",
 )
 
 new_git_repository(
diff --git a/bower.BUILD b/bower.BUILD
index 3ad6da4..ea393ca 100644
--- a/bower.BUILD
+++ b/bower.BUILD
@@ -387,6 +387,7 @@
     srcs = [
         "index.html",
         "paper-icon-button.html",
+        "paper-icon-button-light.html",
     ],
 )
 
diff --git a/tensorflow/tensorboard/bower.json b/tensorflow/tensorboard/bower.json
index 1d9bb74b..b9a6657 100644
--- a/tensorflow/tensorboard/bower.json
+++ b/tensorflow/tensorboard/bower.json
@@ -39,7 +39,7 @@
     "font-roboto": "PolymerElements/font-roboto#1.0.1",
     "graphlib": "1.0.7",
     "iron-a11y-announcer": "PolymerElements/iron-a11y-announcer#1.0.4",
-    "iron-a11y-keys-behavior": "PolymerElements/iron-a11y-keys-behavior#1.1.1",
+    "iron-a11y-keys-behavior": "PolymerElements/iron-a11y-keys-behavior#1.1.2",
     "iron-ajax": "PolymerElements/iron-ajax#1.1.1",
     "iron-autogrow-textarea": "PolymerElements/iron-autogrow-textarea#1.0.11",
     "iron-behaviors": "PolymerElements/iron-behaviors#1.0.13",
@@ -70,7 +70,7 @@
     "paper-dialog-behavior": "PolymerElements/paper-dialog-behavior#1.2.5",
     "paper-dropdown-menu": "PolymerElements/paper-dropdown-menu#1.1.3",
     "paper-header-panel": "PolymerElements/paper-header-panel#1.1.4",
-    "paper-icon-button": "PolymerElements/paper-icon-button#1.0.7",
+    "paper-icon-button": "PolymerElements/paper-icon-button#1.1.1",
     "paper-input": "PolymerElements/paper-input#1.1.5",
     "paper-item": "PolymerElements/paper-item#1.1.4",
     "paper-material": "PolymerElements/paper-material#1.0.6",
@@ -112,7 +112,7 @@
     "font-roboto": "1.0.1",
     "graphlib": "1.0.7",
     "iron-a11y-announcer": "1.0.4",
-    "iron-a11y-keys-behavior": "1.1.1",
+    "iron-a11y-keys-behavior": "1.1.2",
     "iron-ajax": "1.1.1",
     "iron-autogrow-textarea": "1.0.11",
     "iron-behaviors": "1.0.13",
@@ -143,7 +143,7 @@
     "paper-dialog-behavior": "1.2.5",
     "paper-dropdown-menu": "1.1.3",
     "paper-header-panel": "1.1.4",
-    "paper-icon-button": "1.0.7",
+    "paper-icon-button": "1.1.1",
     "paper-input": "1.1.5",
     "paper-item": "1.1.4",
     "paper-material": "1.0.6",
diff --git a/tensorflow/tensorboard/dist/tf-tensorboard.html b/tensorflow/tensorboard/dist/tf-tensorboard.html
index 75bc976..3180190 100644
--- a/tensorflow/tensorboard/dist/tf-tensorboard.html
+++ b/tensorflow/tensorboard/dist/tf-tensorboard.html
@@ -36,7 +36,7 @@
 (function (TF) {
     var TensorBoard;
     (function (TensorBoard) {
-        TensorBoard.TABS = ['events', 'images', 'graphs', 'histograms'];
+        TensorBoard.TABS = ['events', 'images', 'audio', 'graphs', 'histograms'];
     })(TensorBoard = TF.TensorBoard || (TF.TensorBoard = {}));
 })(TF || (TF = {}));
 </script>
@@ -101,46 +101,6 @@
 })(TF || (TF = {}));
 </script>
 </head><body><div hidden="" by-vulcanize="">
-<dom-module id="tf-tooltip-coordinator" assetpath="../tf-event-dashboard/">
-  <script>
-    Polymer({
-      is: "tf-tooltip-coordinator",
-      properties: {
-        outTooltipUpdater: {
-          type: Function,
-          value: function() {
-            return (function(tooltipMap, xValue, closestRun) {
-              this._setOutTooltipMap(tooltipMap);
-              this._setOutXValue(xValue);
-              this._setOutClosestRun(closestRun);
-            }).bind(this);
-          },
-          notify: true,
-          readOnly: true,
-        },
-        outTooltipMap: {
-          // a {runName: tooltipValue} map, where runName and tooltipValue are strings.
-          type: Object,
-          notify: true,
-          readOnly: true,
-        },
-        outXValue: {
-          // a string representation of the closest x value for the tooltips
-          type: Number,
-          notify: true,
-          readOnly: true,
-        },
-        outClosestRun: {
-          // the name of the run that is closest to the user cursor (if any)
-          type: String,
-          notify: true,
-          readOnly: true,
-        },
-      },
-    });
-  </script>
-</dom-module>
-
 <dom-module id="scrollbar-style" assetpath="../tf-dashboard-common/">
   <template>
     <style>
@@ -235,17 +195,14 @@
 
   <template>
     <div id="outer-container" class="scrollbar">
-      <template is="dom-repeat" items="[[names]]" sort="[[_tooltipComparator(tooltips, tooltipOrderer)]]">
-        <div class="run-row" color-class$="[[_applyColorClass(item, classScale)]]" null-tooltip$="[[_isNullTooltip(item, tooltips)]]" highlight$="[[_isHighlighted(item, highlights.*)]]">
+      <template is="dom-repeat" items="[[names]]">
+        <div class="run-row" color-class$="[[_applyColorClass(item, classScale)]]">
           <div class="checkbox-container vertical-align-container">
             <paper-checkbox class="checkbox vertical-align-center" name="[[item]]" checked$="[[_isChecked(item,outSelected.*)]]" on-change="_checkboxChange"></paper-checkbox>
           </div>
           <div class="item-label-container">
             <span>[[item]]</span>
           </div>
-          <div class="tooltip-value-container vertical-align-container">
-            <span class="vertical-align-top">[[_lookupTooltip(item,tooltips)]]</span>
-          </div>
         </div>
       </template>
     </div>
@@ -301,12 +258,6 @@
     .vertical-align-container .vertical-align-top {
       align-self: start;
     }
-    [null-tooltip] {
-      display: none;
-    }
-    [highlight] {
-      font-weight: bold;
-    }
   </style>
   </template>
 
@@ -315,18 +266,6 @@
     is: "tf-multi-checkbox",
     properties: {
       names: Array,
-      tooltipOrderer: {
-        /* Used to compute how to order the tooltips based on the tooltip value.
-         * By default, it parses the tooltip strings as numbers.
-         * If set to a falsey value, tooltips are always ordered lexicographically.
-         */
-        type: Function,
-        value: function() {
-          return function(x) {return +x;}
-        },
-      },
-      tooltips: Object,
-      highlights: Array,
       outSelected: {
         type: Array,
         notify: true,
@@ -334,46 +273,14 @@
           return [];
         },
       },
-      hideMissingTooltips: {
-        // If we have tooltips, but some names are missing, do we hide them?
-        type: Boolean,
-        value: true,
-      },
       classScale: Function, // map from run name to css class
     },
     observers: [
       "_initializeOutSelected(names.*)",
     ],
-    _lookupTooltip: function(item, tooltips) {
-      return tooltips != null ? tooltips[item] : null;
-    },
-    _isNullTooltip: function(item, tooltips) {
-      if (!this.hideMissingTooltips) {
-        return true;
-      }
-      if (tooltips == null) {
-        return false;
-      }
-      return tooltips[item] == null;
-    },
     _initializeOutSelected: function(change) {
       this.outSelected = change.base.slice();
     },
-    _tooltipComparator: function(tooltips, tooltipOrderer) {
-      return function(a, b) {
-        if (!tooltips || !tooltipOrderer) {
-          // if we're missing tooltips or orderer, do lexicogrpahic sort
-          return a.localeCompare(b);
-        }
-        function getValue(x) {
-          var value = tooltipOrderer(tooltips[x]);
-          return value == null || _.isNaN(value) ? -Infinity : value;
-        }
-        var aValue = getValue(a);
-        var bValue = getValue(b);
-        return aValue === bValue ? a.localeCompare(b) : bValue - aValue;
-      }
-    },
     _checkboxChange: function(e) {
       var name = e.srcElement.name;
       var idx = this.outSelected.indexOf(name);
@@ -399,9 +306,6 @@
       }, 16);
       return classScale(item);
     },
-    _isHighlighted: function(item, highlights) {
-      return highlights.base.indexOf(item) !== -1;
-    },
   });
   </script>
 
@@ -410,19 +314,11 @@
 <dom-module id="tf-run-selector" assetpath="../tf-event-dashboard/">
   <template>
     <div id="top-text">
-      <template is="dom-if" if="[[xValue]]">
-        <div class="x-tooltip tooltip-container">
-          <div class="x-tooltip-label">[[xType]]</div>
-          <div class="x-tooltip-value">[[xValue]]</div>
-        </div>
-      </template>
-      <template is="dom-if" if="[[!xValue]]">
-        <h3 id="tooltip-help" class="tooltip-container">
-          Runs
-        </h3>
-      </template>
+      <h3 id="tooltip-help" class="tooltip-container">
+        Runs
+      </h3>
     </div>
-    <tf-multi-checkbox names="[[runs]]" tooltips="[[tooltips]]" highlights="[[_arrayify(closestRun)]]" out-selected="{{outSelected}}" class-scale="[[classScale]]" hide-missing-tooltips=""></tf-multi-checkbox>
+    <tf-multi-checkbox names="[[runs]]" out-selected="{{outSelected}}" class-scale="[[classScale]]"></tf-multi-checkbox>
     <paper-button class="x-button" id="toggle-all" on-tap="_toggleAll">
     Toggle All Runs
     </paper-button>
@@ -453,17 +349,6 @@
         margin-top: 5px;
         color: var(--tb-ui-dark-accent);
       }
-      .x-tooltip {
-        display: flex;
-        flex-direction: row;
-      }
-      .x-tooltip-label {
-        flex-grow: 1;
-        align-self: flex-start;
-      }
-      .x-tooltip-value {
-        align-self: flex-end;
-      }
       #tooltip-help {
         color: var(--paper-grey-800);
         margin: 0;
@@ -483,11 +368,7 @@
       outSelected: {type: Array, notify: true},
       // runs: an array of strings, representing the run names that may be chosen
       runs: Array,
-      tooltips: {type: Object, value: null}, // {[run: string]: string}
-      xValue: {type: String, value: null}, // the string representing run's x val
-      xType: String, // string: relative, stpe, wall_time
       classScale: Object, // map from run name to color class (css)
-      closestRun: {type: String, value: null}, // which run has a value closest to mouse coordinate
     },
     _toggleAll: function() {
       if (this.outSelected.length > 0) {
@@ -496,9 +377,6 @@
         this.outSelected = this.runs.slice();
       }
     },
-    _arrayify: function(item) {
-      return [item];
-    },
   });
   </script>
 </dom-module>
@@ -772,14 +650,14 @@
   </template>
   <script>/* Copyright 2015 Google Inc. All Rights Reserved.
 
-Licensed under the Apache License, Version 2.0 (the "License");
+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,
+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.
@@ -797,16 +675,17 @@
     Categorizer.legacyUnderscoreCategorizer = splitCategorizer(/[\/_]/);
     function fallbackCategorizer(s) {
         switch (s) {
-            case "TopLevelNamespaceCategorizer":
+            case 'TopLevelNamespaceCategorizer':
                 return Categorizer.topLevelNamespaceCategorizer;
-            case "LegacyUnderscoreCategorizer":
+            case 'LegacyUnderscoreCategorizer':
                 return Categorizer.legacyUnderscoreCategorizer;
             default:
-                throw new Error("Unrecognized categorization strategy: " + s);
+                throw new Error('Unrecognized categorization strategy: ' + s);
         }
     }
     Categorizer.fallbackCategorizer = fallbackCategorizer;
-    /* An "extractor" is a function that takes a tag name, and "extracts" a category name.
+    /* An 'extractor' is a function that takes a tag name, and 'extracts' a
+     * category name.
      * This function takes an extractor, and produces a categorizer.
      * Currently, it is just used for the fallbackCategorizer, but we may want to
      * refactor the general categorization logic to use the concept of extractors.
@@ -928,6 +807,18 @@
 <dom-module id="tf-chart" assetpath="../tf-event-dashboard/">
   <template>
     <svg id="chartsvg"></svg>
+    <div id="tooltip">
+      <h4 id="headline"></h4>
+      <div class="tooltip-row">
+        Step: <span id="step"></span>
+      </div>
+      <div class="tooltip-row">
+        Time: <span id="time"></span>
+      </div>
+      <div class="tooltip-row">
+        Value: <span id="value"></span>
+      </div>
+    </div>
     <style>
       :host {
         -webkit-user-select: none;
@@ -936,6 +827,7 @@
         flex-direction: column;
         flex-grow: 1;
         flex-shrink: 1;
+        position: relative;
       }
       svg {
         -webkit-user-select: none;
@@ -943,21 +835,49 @@
         flex-grow: 1;
         flex-shrink: 1;
       }
+      .tooltip-row{
+        white-space: nowrap;
+      }
+      #tooltip {
+        pointer-events: none;
+        position: absolute;
+        opacity: 0;
+        box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
+        font-size: 14px;
+        background: rgba(0, 0, 0, 0.8);
+        color: white;
+        border-radius: 4px;
+        line-height: 1.4em;
+        padding: 8px;
+        z-index: 5;
+        cursor: none;
+      }
+      #tooltip #headline {
+        margin: 0 0 2px 0;
+        font-weight: bold;
+      }
+      #tooltip span {
+        font-weight: bold;
+      }
       .plottable .crosshairs line.guide-line {
         stroke: #777;
       }
+      text.tooltip {
+        font-size: 3;
+
+      }
     </style>
   </template>
   <script>/* Copyright 2015 Google Inc. All Rights Reserved.
 
-Licensed under the Apache License, Version 2.0 (the "License");
+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,
+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.
@@ -971,18 +891,22 @@
 (function (Plottable) {
     var DragZoomLayer = (function (_super) {
         __extends(DragZoomLayer, _super);
-        /* Constructs a SelectionBoxLayer with an attached DragInteraction and ClickInteraction.
-         * On drag, it triggers an animated zoom into the box that was dragged.
-         * On double click, it zooms back out to the original view, before any zooming.
-         * The zoom animation uses an easing function (default d3.ease("cubic-in-out")) and is customizable.
-         * Usage: Construct the selection box layer and attach x and y scales, and then add the layer
-         * over the plot you are zooming on using a Component Group.
+        /**
+         * Constructs a SelectionBoxLayer with an attached DragInteraction and
+         * ClickInteraction. On drag, it triggers an animated zoom into the box
+         * that was dragged. On double click, it zooms back out to the original
+         * view, before any zooming.
+         * The zoom animation uses an easing function (default
+         * d3.ease('cubic-in-out')) and is customizable.
+         * Usage: Construct the selection box layer and attach x and y scales,
+         * and then add the layer over the plot you are zooming on using a
+         * Component Group.
          * TODO(danmane) - merge this into Plottable
          */
         function DragZoomLayer(xScale, yScale) {
             _super.call(this);
             this.isZoomed = false;
-            this.easeFn = d3.ease("cubic-in-out");
+            this.easeFn = d3.ease('cubic-in-out');
             this._animationTime = 750;
             this.xScale(xScale);
             this.yScale(yScale);
@@ -992,6 +916,14 @@
             this._doubleClickInteraction.attachTo(this);
             this.setupCallbacks();
         }
+        /**
+         * Register a method that calls when the DragZoom interaction starts.
+         */
+        DragZoomLayer.prototype.interactionStart = function (cb) { this.onStart = cb; };
+        /**
+         * Register a method that calls when the DragZoom interaction ends.
+         */
+        DragZoomLayer.prototype.interactionEnd = function (cb) { this.onEnd = cb; };
         DragZoomLayer.prototype.setupCallbacks = function () {
             var _this = this;
             var dragging = false;
@@ -1000,6 +932,7 @@
                     topLeft: startPoint,
                     bottomRight: startPoint,
                 });
+                _this.onStart();
             });
             this._dragInteraction.onDrag(function (startPoint, endPoint) {
                 _this.bounds({ topLeft: startPoint, bottomRight: endPoint });
@@ -1012,6 +945,9 @@
                 if (dragging) {
                     _this.zoom();
                 }
+                else {
+                    _this.onEnd();
+                }
                 dragging = false;
             });
             this._doubleClickInteraction.onDoubleClick(this.unzoom.bind(this));
@@ -1021,18 +957,22 @@
                 return this._animationTime;
             }
             if (animationTime < 0) {
-                throw new Error("animationTime cannot be negative");
+                throw new Error('animationTime cannot be negative');
             }
             this._animationTime = animationTime;
             return this;
         };
-        /* Set the easing function, which determines how the zoom interpolates over time. */
+        /**
+         * Set the easing function, which determines how the zoom interpolates
+         * over time.
+         */
         DragZoomLayer.prototype.ease = function (fn) {
-            if (typeof (fn) !== "function") {
-                throw new Error("ease function must be a function");
+            if (typeof (fn) !== 'function') {
+                throw new Error('ease function must be a function');
             }
             if (fn(0) !== 0 || fn(1) !== 1) {
-                Plottable.Utils.Window.warn("Easing function does not maintain invariant f(0)==0 && f(1)==1. Bad behavior may result.");
+                Plottable.Utils.Window.warn('Easing function does not maintain invariant ' +
+                    'f(0)==0 && f(1)==1. Bad behavior may result.');
             }
             this.easeFn = fn;
             return this;
@@ -1072,15 +1012,20 @@
             var x1s = this.xScale().domain()[1].valueOf();
             var y0s = this.yScale().domain()[0].valueOf();
             var y1s = this.yScale().domain()[1].valueOf();
-            // Copy a ref to the ease fn, so that changing ease wont affect zooms in progress
+            // Copy a ref to the ease fn, so that changing ease wont affect zooms in
+            // progress.
             var ease = this.easeFn;
-            var interpolator = function (a, b, p) { return d3.interpolateNumber(a, b)(ease(p)); };
+            var interpolator = function (a, b, p) {
+                return d3.interpolateNumber(a, b)(ease(p));
+            };
             this.isZooming(true);
             var start = Date.now();
             var draw = function () {
                 var now = Date.now();
                 var passed = now - start;
-                var p = _this._animationTime === 0 ? 1 : Math.min(1, passed / _this._animationTime);
+                var p = _this._animationTime === 0 ?
+                    1 :
+                    Math.min(1, passed / _this._animationTime);
                 var x0 = interpolator(x0s, x0f, p);
                 var x1 = interpolator(x1s, x1f, p);
                 var y0 = interpolator(y0s, y0f, p);
@@ -1091,6 +1036,7 @@
                     Plottable.Utils.DOM.requestAnimationFramePolyfill(draw);
                 }
                 else {
+                    _this.onEnd();
                     _this.isZooming(false);
                 }
             };
@@ -1125,13 +1071,17 @@
     var Y_TOOLTIP_FORMATTER_PRECISION = 4;
     var STEP_AXIS_FORMATTER_PRECISION = 4;
     var Y_AXIS_FORMATTER_PRECISION = 3;
+    var TOOLTIP_Y_PIXEL_OFFSET = 15;
+    var TOOLTIP_X_PIXEL_OFFSET = 0;
+    var TOOLTIP_CIRCLE_SIZE = 3;
+    var TOOLTIP_CLOSEST_CIRCLE_SIZE = 6;
     var BaseChart = (function () {
-        function BaseChart(tag, dataFn, tooltipUpdater, xType, colorScale) {
+        function BaseChart(tag, dataFn, xType, colorScale, tooltip) {
             this.dataFn = dataFn;
             this.datasets = {};
             this.tag = tag;
             this.colorScale = colorScale;
-            this.tooltipUpdater = tooltipUpdater;
+            this.tooltip = tooltip;
             this.buildChart(xType);
         }
         /**
@@ -1158,74 +1108,11 @@
         };
         BaseChart.prototype.getDataset = function (run) {
             if (this.datasets[run] === undefined) {
-                this.datasets[run] = new Plottable.Dataset([], { run: run, tag: this.tag });
+                this.datasets[run] =
+                    new Plottable.Dataset([], { run: run, tag: this.tag });
             }
             return this.datasets[run];
         };
-        BaseChart.prototype.addCrosshairs = function (plot, yAccessor) {
-            var _this = this;
-            var pi = new Plottable.Interactions.Pointer();
-            pi.attachTo(plot);
-            var xGuideLine = new Plottable.Components.GuideLineLayer("vertical");
-            var yGuideLine = new Plottable.Components.GuideLineLayer("horizontal");
-            xGuideLine.addClass("crosshairs");
-            yGuideLine.addClass("crosshairs");
-            var group = new Plottable.Components.Group([plot, xGuideLine, yGuideLine]);
-            var yfmt = multiscaleFormatter(Y_TOOLTIP_FORMATTER_PRECISION);
-            pi.onPointerMove(function (p) {
-                var run2val = {};
-                var x = _this.xScale.invert(p.x).valueOf();
-                var yMin = _this.yScale.domain()[0];
-                var yMax = _this.yScale.domain()[1];
-                var closestRun = null;
-                var minYDistToRun = Infinity;
-                var yValueForCrosshairs = p.y;
-                plot.datasets().forEach(function (dataset) {
-                    var run = dataset.metadata().run;
-                    var data = dataset.data();
-                    var xs = data.map(function (d, i) { return _this.xAccessor(d, i, dataset).valueOf(); });
-                    var idx = _.sortedIndex(xs, x);
-                    if (idx === 0 || idx === data.length) {
-                        // Only find a point when the cursor is inside the range of the data
-                        // if the cursor is to the left or right of all the data, don't
-                        // attach.
-                        return;
-                    }
-                    var previous = data[idx - 1];
-                    var next = data[idx];
-                    var x0 = _this.xAccessor(previous, idx - 1, dataset).valueOf();
-                    var x1 = _this.xAccessor(next, idx, dataset).valueOf();
-                    var y0 = yAccessor(previous, idx - 1, dataset).valueOf();
-                    var y1 = yAccessor(next, idx, dataset).valueOf();
-                    var slope = (y1 - y0) / (x1 - x0);
-                    var y = y0 + slope * (x - x0);
-                    if (y < yMin || y > yMax || y !== y) {
-                        // don't find data that is off the top or bottom of the plot.
-                        // also don't find data if it is NaN
-                        return;
-                    }
-                    var dist = Math.abs(_this.yScale.scale(y) - p.y);
-                    if (dist < minYDistToRun) {
-                        minYDistToRun = dist;
-                        closestRun = run;
-                        yValueForCrosshairs = _this.yScale.scale(y);
-                    }
-                    // Note this tooltip will display linearly interpolated values
-                    // e.g. will display a y=0 value halfway between [y=-1, y=1], even
-                    // though there is not actually any 0 datapoint. This could be misleading
-                    run2val[run] = yfmt(y);
-                });
-                xGuideLine.pixelPosition(p.x);
-                yGuideLine.pixelPosition(yValueForCrosshairs);
-                _this.tooltipUpdater(run2val, _this.xTooltipFormatter(x), closestRun);
-            });
-            pi.onPointerExit(function () {
-                _this.tooltipUpdater(null, null, null);
-                xGuideLine.pixelPosition(-1);
-                yGuideLine.pixelPosition(-1);
-            });
-            return group;
-        };
         BaseChart.prototype.buildChart = function (xType) {
             if (this.outer) {
                 this.outer.destroy();
@@ -1237,21 +1124,23 @@
             this.xAxis.margin(0).tickLabelPadding(3);
             this.xTooltipFormatter = xComponents.tooltipFormatter;
             this.yScale = new Plottable.Scales.Linear();
-            this.yAxis = new Plottable.Axes.Numeric(this.yScale, "left");
+            this.yAxis = new Plottable.Axes.Numeric(this.yScale, 'left');
             var yFormatter = multiscaleFormatter(Y_AXIS_FORMATTER_PRECISION);
             this.yAxis.margin(0).tickLabelPadding(5).formatter(yFormatter);
             this.yAxis.usesTextWidthApproximation(true);
+            this.dzl = new Plottable.DragZoomLayer(this.xScale, this.yScale);
             var center = this.buildPlot(this.xAccessor, this.xScale, this.yScale);
-            this.gridlines = new Plottable.Components.Gridlines(this.xScale, this.yScale);
-            var dzl = new Plottable.DragZoomLayer(this.xScale, this.yScale);
-            this.center = new Plottable.Components.Group([center, this.gridlines, dzl]);
+            this.gridlines =
+                new Plottable.Components.Gridlines(this.xScale, this.yScale);
+            this.center =
+                new Plottable.Components.Group([this.gridlines, center, this.dzl]);
             this.outer = new Plottable.Components.Table([
                 [this.yAxis, this.center],
                 [null, this.xAxis]
             ]);
         };
         BaseChart.prototype.buildPlot = function (xAccessor, xScale, yScale) {
-            throw new Error("Abstract method not implemented.");
+            throw new Error('Abstract method not implemented.');
         };
         BaseChart.prototype.renderTo = function (target) {
             this.outer.renderTo(target);
@@ -1271,19 +1160,130 @@
             _super.apply(this, arguments);
         }
         LineChart.prototype.buildPlot = function (xAccessor, xScale, yScale) {
-            var yAccessor = function (d) { return d.scalar; };
+            this.yAccessor = function (d) { return d.scalar; };
             var plot = new Plottable.Plots.Line();
             plot.x(xAccessor, xScale);
-            plot.y(yAccessor, yScale);
-            plot.attr("stroke", function (d, i, dataset) { return dataset.metadata().run; }, this.colorScale);
+            plot.y(this.yAccessor, yScale);
+            plot.attr('stroke', function (d, i, dataset) {
+                return dataset.metadata().run;
+            }, this.colorScale);
             this.plot = plot;
-            var group = this.addCrosshairs(plot, yAccessor);
+            var group = this.setupTooltips(plot);
             return group;
         };
+        LineChart.prototype.setupTooltips = function (plot) {
+            var _this = this;
+            var pi = new Plottable.Interactions.Pointer();
+            pi.attachTo(plot);
+            // PointsComponent is a Plottable Component that will hold the little
+            // circles we draw over the closest data points
+            var pointsComponent = new Plottable.Component();
+            var group = new Plottable.Components.Group([plot, pointsComponent]);
+            var hideTooltips = function () {
+                _this.tooltip.style('opacity', 0);
+                pointsComponent.content().selectAll('.point').remove();
+            };
+            var enabled = true;
+            var disableTooltips = function () {
+                enabled = false;
+                hideTooltips();
+            };
+            var enableTooltips = function () { enabled = true; };
+            this.dzl.interactionStart(disableTooltips);
+            this.dzl.interactionEnd(enableTooltips);
+            pi.onPointerMove(function (p) {
+                if (!enabled) {
+                    return;
+                }
+                var target = {
+                    run: null,
+                    x: p.x,
+                    y: p.y,
+                    datum: null,
+                };
+                var centerBBox = _this.gridlines.content().node().getBBox();
+                var points = plot.datasets()
+                    .map(function (dataset) { return _this.findClosestPoint(target, dataset); })
+                    .filter(function (p) {
+                    // Only choose Points that are within window (if we zoomed)
+                    return Plottable.Utils.DOM.intersectsBBox(p.x, p.y, centerBBox);
+                });
+                points.reverse(); // if multiple points are equidistant, choose 1st run
+                var closestPoint = _.min(points, function (p) { return dist(p, target); });
+                points.reverse(); // draw 1st run last, to get the right occlusions
+                var pts = pointsComponent.content().selectAll('.point').data(points, function (p) { return p.run; });
+                if (points.length !== 0) {
+                    pts.enter().append('circle').classed('point', true);
+                    pts.attr('r', function (p) { return p === closestPoint ? TOOLTIP_CLOSEST_CIRCLE_SIZE :
+                        TOOLTIP_CIRCLE_SIZE; })
+                        .attr('cx', function (p) { return p.x; })
+                        .attr('cy', function (p) { return p.y; })
+                        .style('stroke', 'none')
+                        .attr('fill', function (p) { return _this.colorScale.scale(p.run); });
+                    pts.exit().remove();
+                    _this.drawTooltips(closestPoint);
+                }
+                else {
+                    hideTooltips();
+                }
+            });
+            pi.onPointerExit(hideTooltips);
+            return group;
+        };
+        LineChart.prototype.drawTooltips = function (closestPoint) {
+            var _this = this;
+            // Formatters for value, step, and wall_time
+            var valueFormatter = multiscaleFormatter(Y_TOOLTIP_FORMATTER_PRECISION);
+            var stepFormatter = stepX().tooltipFormatter;
+            var wall_timeFormatter = wallX().tooltipFormatter;
+            var datum = closestPoint.datum;
+            this.tooltip.select('#headline')
+                .text(closestPoint.run)
+                .style('color', this.colorScale.scale(closestPoint.run));
+            var step = stepFormatter(datum.step);
+            var date = wall_timeFormatter(+datum.wall_time);
+            var value = valueFormatter(datum.scalar);
+            this.tooltip.select('#step').text(step);
+            this.tooltip.select('#time').text(date);
+            this.tooltip.select('#value').text(value);
+            this.tooltip.style('top', closestPoint.y + TOOLTIP_Y_PIXEL_OFFSET + 'px')
+                .style('left', function () { return _this.yAxis.width() + TOOLTIP_X_PIXEL_OFFSET +
+                closestPoint.x + 'px'; })
+                .style('opacity', 1);
+        };
+        LineChart.prototype.findClosestPoint = function (target, dataset) {
+            var _this = this;
+            var run = dataset.metadata().run;
+            var points = dataset.data().map(function (d, i) {
+                var x = _this.xAccessor(d, i, dataset);
+                var y = _this.yAccessor(d, i, dataset);
+                return {
+                    x: _this.xScale.scale(x),
+                    y: _this.yScale.scale(y),
+                    datum: d,
+                    run: run,
+                };
+            });
+            var idx = _.sortedIndex(points, target, function (p) { return p.x; });
+            if (idx === points.length) {
+                return points[points.length - 1];
+            }
+            else if (idx === 0) {
+                return points[0];
+            }
+            else {
+                var prev = points[idx - 1];
+                var next = points[idx];
+                var prevDist = Math.abs(prev.x - target.x);
+                var nextDist = Math.abs(next.x - target.x);
+                return prevDist < nextDist ? prev : next;
+            }
+        };
         LineChart.prototype.changeRuns = function (runs) {
             var _this = this;
             _super.prototype.changeRuns.call(this, runs);
             var datasets = runs.map(function (r) { return _this.getDataset(r); });
+            datasets.reverse(); // draw first run on top
             this.plot.datasets(datasets);
         };
         return LineChart;
@@ -1303,7 +1303,8 @@
         HistogramChart.prototype.buildPlot = function (xAccessor, xScale, yScale) {
             var _this = this;
             var percents = [0, 228, 1587, 3085, 5000, 6915, 8413, 9772, 10000];
-            var opacities = _.range(percents.length - 1).map(function (i) { return (percents[i + 1] - percents[i]) / 2500; });
+            var opacities = _.range(percents.length - 1)
+                .map(function (i) { return (percents[i + 1] - percents[i]) / 2500; });
             var accessors = percents.map(function (p, i) { return function (datum) { return datum[i][1]; }; });
             var median = 4;
             var medianAccessor = accessors[median];
@@ -1314,24 +1315,23 @@
                 var y = i > median ? accessors[i + 1] : accessors[i];
                 p.y(y, yScale);
                 p.y0(y0);
-                p.attr("fill", function (d, i, dataset) {
+                p.attr('fill', function (d, i, dataset) {
                     return dataset.metadata().run;
                 }, _this.colorScale);
-                p.attr("stroke", function (d, i, dataset) {
+                p.attr('stroke', function (d, i, dataset) {
                     return dataset.metadata().run;
                 }, _this.colorScale);
-                p.attr("stroke-weight", function (d, i, m) { return "0.5px"; });
-                p.attr("stroke-opacity", function () { return opacities[i]; });
-                p.attr("fill-opacity", function () { return opacities[i]; });
+                p.attr('stroke-weight', function (d, i, m) { return '0.5px'; });
+                p.attr('stroke-opacity', function () { return opacities[i]; });
+                p.attr('fill-opacity', function () { return opacities[i]; });
                 return p;
             });
             var medianPlot = new Plottable.Plots.Line();
             medianPlot.x(xAccessor, xScale);
             medianPlot.y(medianAccessor, yScale);
-            medianPlot.attr("stroke", function (d, i, m) { return m.run; }, this.colorScale);
+            medianPlot.attr('stroke', function (d, i, m) { return m.run; }, this.colorScale);
             this.plots = plots;
-            var group = this.addCrosshairs(medianPlot, medianAccessor);
-            return new Plottable.Components.Group([new Plottable.Components.Group(plots), group]);
+            return new Plottable.Components.Group(plots);
         };
         return HistogramChart;
     }(BaseChart));
@@ -1349,13 +1349,13 @@
             }
             var f;
             if (absv >= 1E4) {
-                f = d3.format("." + digits + "e");
+                f = d3.format('.' + digits + 'e');
             }
             else if (absv > 0 && absv < 0.01) {
-                f = d3.format("." + digits + "e");
+                f = d3.format('.' + digits + 'e');
             }
             else {
-                f = d3.format("." + digits + "g");
+                f = d3.format('.' + digits + 'g');
             }
             return f(v);
         };
@@ -1365,7 +1365,7 @@
     }
     function stepX() {
         var scale = new Plottable.Scales.Linear();
-        var axis = new Plottable.Axes.Numeric(scale, "bottom");
+        var axis = new Plottable.Axes.Numeric(scale, 'bottom');
         var formatter = Plottable.Formatters.siSuffix(STEP_AXIS_FORMATTER_PRECISION);
         axis.formatter(formatter);
         return {
@@ -1377,10 +1377,10 @@
     }
     function wallX() {
         var scale = new Plottable.Scales.Time();
-        var formatter = Plottable.Formatters.time("%a %b %e, %H:%M:%S");
+        var formatter = Plottable.Formatters.time('%a %b %e, %H:%M:%S');
         return {
             scale: scale,
-            axis: new Plottable.Axes.Time(scale, "bottom"),
+            axis: new Plottable.Axes.Time(scale, 'bottom'),
             accessor: function (d) { return d.wall_time; },
             tooltipFormatter: function (d) { return formatter(new Date(d)); },
         };
@@ -1397,31 +1397,36 @@
             n -= minutes;
             n *= 60;
             var seconds = Math.floor(n);
-            return days + "d " + hours + "h " + minutes + "m " + seconds + "s";
+            return days + 'd ' + hours + 'h ' + minutes + 'm ' + seconds + 's';
         };
         return {
             scale: scale,
-            axis: new Plottable.Axes.Numeric(scale, "bottom"),
+            axis: new Plottable.Axes.Numeric(scale, 'bottom'),
             accessor: function (d, index, dataset) {
                 var data = dataset.data();
-                // I can't imagine how this function would be called when the data is empty
-                // (after all, it iterates over the data), but lets guard just to be safe.
+                // I can't imagine how this function would be called when the data
+                // is empty
+                // (after all, it iterates over the data), but lets guard just to be
+                // safe.
                 var first = data.length > 0 ? +data[0].wall_time : 0;
                 return (+d.wall_time - first) / (60 * 60 * 1000); // ms to hours
             },
             tooltipFormatter: formatter,
         };
     }
+    function dist(p1, p2) {
+        return Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2));
+    }
     function getXComponents(xType) {
         switch (xType) {
-            case "step":
+            case 'step':
                 return stepX();
-            case "wall_time":
+            case 'wall_time':
                 return wallX();
-            case "relative":
+            case 'relative':
                 return relativeX();
             default:
-                throw new Error("invalid xType: " + xType);
+                throw new Error('invalid xType: ' + xType);
         }
     }
 })(TF || (TF = {}));
@@ -1437,11 +1442,10 @@
         selectedRuns: Array,
         xType: String,
         dataProvider: Function,
-        tooltipUpdater: Function,
         _initialized: Boolean,
       },
       observers: [
-        "_makeChart(type, tag, dataProvider, tooltipUpdater, xType, colorScale, _initialized)",
+        "_makeChart(type, tag, dataProvider, xType, colorScale, _initialized)",
         "_changeRuns(_chart, selectedRuns.*)"
       ],
       _changeRuns: function(chart) {
@@ -1466,13 +1470,14 @@
           throw new Error("Unrecognized chart type");
         }
       },
-      _makeChart: function(type, tag, dataProvider, tooltipUpdater, xType, colorScale, _initialized) {
+      _makeChart: function(type, tag, dataProvider, xType, colorScale, _initialized) {
         if (!_initialized) {
           return;
         }
         if (this._chart) this._chart.destroy();
         var cns = this._constructor(type);
-        var chart = new cns(tag, dataProvider, tooltipUpdater, xType, colorScale);
+        var tooltip = d3.select(this.$.tooltip);
+        var chart = new cns(tag, dataProvider, xType, colorScale, tooltip);
         var svg = d3.select(this.$.chartsvg);
         this.async(function() {
           chart.renderTo(svg);
@@ -1918,14 +1923,14 @@
 </script>
 <script>/* Copyright 2015 Google Inc. All Rights Reserved.
 
-Licensed under the Apache License, Version 2.0 (the "License");
+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,
+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.
@@ -1939,19 +1944,20 @@
 (function (TF) {
     var Backend;
     (function (Backend) {
-        /*
-        * Manages many fetch requests. Launches up to nSimultaneousRequests
-        * simultaneously, and maintains a LIFO queue of requests to process when
-        * more urls are requested than can be handled at once. The queue can be cleared.
-        *
-        * When a request is made, a Promise is returned which resolves with the parsed
-        * JSON result from the request.
-        */
+        /**
+         * Manages many fetch requests. Launches up to nSimultaneousRequests
+         * simultaneously, and maintains a LIFO queue of requests to process when
+         * more urls are requested than can be handled at once. The queue can be
+         * cleared.
+         *
+         * When a request is made, a Promise is returned which resolves with the
+         * parsed JSON result from the request.
+         */
         var RequestCancellationError = (function (_super) {
             __extends(RequestCancellationError, _super);
             function RequestCancellationError() {
                 _super.apply(this, arguments);
-                this.name = "RequestCancellationError";
+                this.name = 'RequestCancellationError';
             }
             return RequestCancellationError;
         }(Error));
@@ -1961,7 +1967,7 @@
             function RequestNetworkError(req, url) {
                 _super.call(this);
                 this.message = "RequestNetworkError: " + req.status + " at " + url;
-                this.name = "RequestNetworkError";
+                this.name = 'RequestNetworkError';
                 this.req = req;
                 this.url = url;
             }
@@ -1984,17 +1990,22 @@
                     var resolver = { resolve: resolve, reject: reject };
                     _this._queue.push(resolver);
                     _this.launchRequests();
-                }).then(function () {
+                })
+                    .then(function () {
                     return _this.promiseWithRetries(url, _this._maxRetries);
-                }).then(function (response) {
-                    // Success - Let's free space for another active reqest, and launch it
+                })
+                    .then(function (response) {
+                    // Success - Let's free space for another active
+                    // reqest, and launch it
                     _this._nActiveRequests--;
                     _this.launchRequests();
                     return response;
                 }, function (rejection) {
-                    if (rejection.name === "RequestNetworkError") {
-                        // If we failed due to network error, we should decrement
-                        // _nActiveRequests because this request was active
+                    if (rejection.name === 'RequestNetworkError') {
+                        // If we failed due to network error, we should
+                        // decrement
+                        // _nActiveRequests because this request was
+                        // active
                         _this._nActiveRequests--;
                         _this.launchRequests();
                     }
@@ -2004,7 +2015,7 @@
             };
             RequestManager.prototype.clearQueue = function () {
                 while (this._queue.length > 0) {
-                    this._queue.pop().reject(new RequestCancellationError("Request cancelled by clearQueue"));
+                    this._queue.pop().reject(new RequestCancellationError('Request cancelled by clearQueue'));
                 }
             };
             /* Return number of currently pending requests */
@@ -2016,7 +2027,8 @@
                 return this._nActiveRequests + this._queue.length;
             };
             RequestManager.prototype.launchRequests = function () {
-                while (this._nActiveRequests < this._nSimultaneousRequests && this._queue.length > 0) {
+                while (this._nActiveRequests < this._nSimultaneousRequests &&
+                    this._queue.length > 0) {
                     this._nActiveRequests++;
                     this._queue.pop().resolve();
                 }
@@ -2025,7 +2037,7 @@
              * Try to request a given URL using overwritable _promiseFromUrl method.
              * If the request fails for any reason, we will retry up to maxRetries
              * times. In practice, this will help us paper over transient network issues
-             * like "502 Bad Gateway".
+             * like '502 Bad Gateway'.
              * By default, Chrome displays network errors in console, so
              * the user will be able to tell when the requests are failing. I think this
              * is a feature, if the request failures and retries are causing any
@@ -2048,7 +2060,7 @@
             RequestManager.prototype._promiseFromUrl = function (url) {
                 return new Promise(function (resolve, reject) {
                     var req = new XMLHttpRequest();
-                    req.open("GET", url);
+                    req.open('GET', url);
                     req.onload = function () {
                         if (req.status === 200) {
                             resolve(JSON.parse(req.responseText));
@@ -2071,14 +2083,14 @@
 </script>
 <script>/* Copyright 2015 Google Inc. All Rights Reserved.
 
-Licensed under the Apache License, Version 2.0 (the "License");
+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,
+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.
@@ -2087,14 +2099,14 @@
 (function (TF) {
     var Backend;
     (function (Backend) {
-        Backend.BAD_CHARACTERS = "#%&{}\\/<>*? $!'\":@+`|=() ";
+        Backend.BAD_CHARACTERS = '#%&{}\\/<>*? $!\'":@+`|=() ';
         /** Cleanup a url so that it can be loaded from a filesystem. */
         function demoify(s) {
             // for consistency with python's urllib.urlencode
-            s = s.replace(new RegExp("%20", "g"), "+");
+            s = s.replace(new RegExp('%20', 'g'), '+');
             for (var i = 0; i < Backend.BAD_CHARACTERS.length; i++) {
                 var c = Backend.BAD_CHARACTERS[i];
-                s = s.replace(new RegExp("\\" + c, "g"), "_");
+                s = s.replace(new RegExp('\\' + c, 'g'), '_');
             }
             return s;
         }
@@ -2103,15 +2115,15 @@
             // It's important that the keys be sorted, so we always grab the right file
             // if we are talking to the backend generated by serialze_tensorboard.py
             if (params == null) {
-                return "";
+                return '';
             }
             var components = _.keys(params)
                 .sort()
                 .filter(function (k) { return params[k] !== undefined; })
-                .map(function (k) { return k + "=" + encodeURIComponent(params[k]); });
-            var result = components.length ? "?" + components.join("&") : "";
+                .map(function (k) { return k + '=' + encodeURIComponent(params[k]); });
+            var result = components.length ? '?' + components.join('&') : '';
             // Replace parens for consistency with urllib.urlencode
-            return result.replace(/\(/g, "%28").replace(/\)/g, "%29");
+            return result.replace(/\(/g, '%28').replace(/\)/g, '%29');
         }
         Backend.queryEncoder = queryEncoder;
     })(Backend = TF.Backend || (TF.Backend = {}));
@@ -2119,14 +2131,14 @@
 </script>
 <script>/* Copyright 2015 Google Inc. All Rights Reserved.
 
-Licensed under the Apache License, Version 2.0 (the "License");
+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,
+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.
@@ -2142,54 +2154,65 @@
          * @param demoMode {boolean} Whether to modify urls for filesystem demo usage.
          */
         function router(dataDir, demoMode) {
-            if (dataDir === void 0) { dataDir = "/data"; }
+            if (dataDir === void 0) { dataDir = '/data'; }
             if (demoMode === void 0) { demoMode = false; }
             var clean = demoMode ? Backend.demoify : function (x) { return x; };
-            if (dataDir[dataDir.length - 1] === "/") {
+            if (dataDir[dataDir.length - 1] === '/') {
                 dataDir = dataDir.slice(0, dataDir.length - 1);
             }
             function standardRoute(route) {
                 return function (tag, run) {
-                    var url = dataDir + "/" + route + clean(Backend.queryEncoder({ tag: tag, run: run }));
+                    var url = dataDir + '/' + route + clean(Backend.queryEncoder({ tag: tag, run: run }));
                     if (demoMode) {
-                        url += ".json";
+                        url += '.json';
                     }
                     return url;
                 };
             }
             function individualImageUrl(query) {
-                var url = dataDir + "/" + clean("individualImage?" + query);
+                var url = dataDir + '/' + clean('individualImage?' + query);
                 if (demoMode) {
-                    url += ".png";
+                    url += '.png';
+                }
+                return url;
+            }
+            function individualAudioUrl(query) {
+                var url = dataDir + '/' + clean('individualAudio?' + query);
+                if (demoMode) {
+                    url += '.wav';
                 }
                 return url;
             }
             function graphUrl(run, limit_attr_size, large_attrs_key) {
-                var query_params = [["run", clean(run)]];
+                var query_params = [['run', clean(run)]];
                 if (limit_attr_size != null && !demoMode) {
-                    query_params.push(["limit_attr_size", String(limit_attr_size)]);
+                    query_params.push(['limit_attr_size', String(limit_attr_size)]);
                 }
                 if (large_attrs_key != null && !demoMode) {
-                    query_params.push(["large_attrs_key", large_attrs_key]);
+                    query_params.push(['large_attrs_key', large_attrs_key]);
                 }
-                var query = query_params.map(function (param) {
-                    return param[0] + "=" + encodeURIComponent(param[1]);
-                }).join("&");
-                var url = dataDir + "/graph" + clean("?" + query);
+                var query = query_params
+                    .map(function (param) {
+                    return param[0] + '=' + encodeURIComponent(param[1]);
+                })
+                    .join('&');
+                var url = dataDir + '/graph' + clean('?' + query);
                 if (demoMode) {
-                    url += ".pbtxt";
+                    url += '.pbtxt';
                 }
                 return url;
             }
             return {
-                runs: function () { return dataDir + "/runs" + (demoMode ? ".json" : ""); },
+                runs: function () { return dataDir + '/runs' + (demoMode ? '.json' : ''); },
                 individualImage: individualImageUrl,
+                individualAudio: individualAudioUrl,
                 graph: graphUrl,
-                scalars: standardRoute("scalars"),
-                histograms: standardRoute("histograms"),
-                compressedHistograms: standardRoute("compressedHistograms"),
-                images: standardRoute("images"),
-                runMetadata: standardRoute("run_metadata"),
+                scalars: standardRoute('scalars'),
+                histograms: standardRoute('histograms'),
+                compressedHistograms: standardRoute('compressedHistograms'),
+                images: standardRoute('images'),
+                audio: standardRoute('audio'),
+                runMetadata: standardRoute('run_metadata'),
             };
         }
         Backend.router = router;
@@ -2216,7 +2239,7 @@
     var Backend;
     (function (Backend_1) {
         Backend_1.TYPES = [
-            'scalar', 'histogram', 'compressedHistogram', 'graph', 'image',
+            'scalar', 'histogram', 'compressedHistogram', 'graph', 'image', 'audio',
             'runMetadata'
         ];
         /**
@@ -2272,6 +2295,14 @@
                 return this.runs().then(function (x) { return _.mapValues(x, 'images'); });
             };
             /**
+             * Return a promise showing the Run-to-Tag mapping for audio data.
+             * TODO(cassandrax): Replace this with the direct route, when
+             * available.
+             */
+            Backend.prototype.audioRuns = function () {
+                return this.runs().then(function (x) { return _.mapValues(x, 'audio'); });
+            };
+            /**
              * Return a promise showing the Run-to-Tag mapping for compressedHistogram
              * data.
              * TODO(cassandrax): Replace this with the direct route, when
@@ -2339,6 +2370,15 @@
                 return p.then(map(this.createImage.bind(this)));
             };
             /**
+             * Return a promise containing AudioDatums for given run and tag.
+             */
+            Backend.prototype.audio = function (tag, run) {
+                var url = this.router.audio(tag, run);
+                var p;
+                p = this.requestManager.request(url);
+                return p.then(map(this.createAudio.bind(this)));
+            };
+            /**
              * Returns a promise to load the string RunMetadata for given run/tag.
              */
             Backend.prototype.runMetadata = function (tag, run) {
@@ -2365,6 +2405,14 @@
                     url: this.router.individualImage(x.query),
                 };
             };
+            Backend.prototype.createAudio = function (x) {
+                return {
+                    content_type: x.content_type,
+                    wall_time: timeToDate(x.wall_time),
+                    step: x.step,
+                    url: this.router.individualAudio(x.query),
+                };
+            };
             return Backend;
         }());
         Backend_1.Backend = Backend;
@@ -2430,8 +2478,9 @@
          * to visualize. When visualizing histograms, having the left edge and width
          * makes things quite a bit easier.
          *
-         * @param {histogram} Histogram - A histogram from tensorboard backend.
-         * @return {HistogramBin[]} - Each bin has an x (left edge), a dx (width), and a y (count).
+         * @param histogram A histogram from tensorboard backend.
+         * @return A histogram bin. Each bin has an x (left edge), a dx (width),
+         *     and a y (count).
          *
          * If given rightedges are inclusive, then these left edges (x) are exclusive.
          */
@@ -2537,15 +2586,15 @@
             backendReload: function () {
                 var _this = this;
                 if (this.dataType == null) {
-                    throw new Error("TF.Backend.Behavior: Need a dataType to reload.");
+                    throw new Error('TF.Backend.Behavior: Need a dataType to reload.');
                 }
                 if (this.backend == null) {
-                    throw new Error("TF.Backend.Behavior: Need a backend to reload.");
+                    throw new Error('TF.Backend.Behavior: Need a backend to reload.');
                 }
-                var runsRoute = this.backend[this.dataType + "Runs"].bind(this.backend);
-                this._setLoadState("pending");
+                var runsRoute = this.backend[this.dataType + 'Runs'].bind(this.backend);
+                this._setLoadState('pending');
                 return runsRoute().then(function (x) {
-                    _this._setLoadState("loaded");
+                    _this._setLoadState('loaded');
                     if (_.isEqual(x, _this.run2tag)) {
                         // If x and run2tag are equal, let's avoid updating everything
                         // since that can needlessly trigger run changes, reloads, etc
@@ -2558,7 +2607,7 @@
                     _this._setRuns(TF.Backend.getRuns(x));
                     return x;
                 }, function (fail) {
-                    _this._setLoadState("failure");
+                    _this._setLoadState('failure');
                     return fail;
                 });
             },
@@ -2573,7 +2622,7 @@
             },
             _throwErrorOnUnrecognizedType: function (dataType) {
                 if (TF.Backend.TYPES.indexOf(dataType) === -1) {
-                    throw new Error("TF.Backend.Behavior: Unknown dataType " + dataType);
+                    throw new Error('TF.Backend.Behavior: Unknown dataType ' + dataType);
                 }
             },
         };
@@ -2585,9 +2634,6 @@
   <template>
     <div id="plumbing">
       <tf-color-scale id="colorScale" runs="[[runs]]" out-color-scale="{{colorScale}}" out-class-scale="{{classScale}}"></tf-color-scale>
-
-      <tf-tooltip-coordinator id="tooltipCoordinator" out-tooltip-updater="{{tooltipUpdater}}" out-tooltip-map="{{tooltipMap}}" out-x-value="{{tooltipXValue}}" out-closest-run="{{closestRun}}"></tf-tooltip-coordinator>
-
     </div>
 
     <tf-dashboard-layout>
@@ -2600,7 +2646,7 @@
           <tf-x-type-selector id="xTypeSelector" out-x-type="{{xType}}"></tf-x-type-selector>
         </div>
         <div class="sidebar-section">
-          <tf-run-selector id="runSelector" runs="[[runs]]" class-scale="[[classScale]]" out-selected="{{selectedRuns}}" tooltips="[[tooltipMap]]" closest-run="[[closestRun]]" x-value="[[tooltipXValue]]" x-type="[[xType]]"></tf-run-selector>
+          <tf-run-selector id="runSelector" runs="[[runs]]" class-scale="[[classScale]]" out-selected="{{selectedRuns}}"></tf-run-selector>
         </div>
       </div>
       <div class="center">
@@ -2612,7 +2658,7 @@
                 <div class="card">
                   <span class="card-title">[[tag]]</span>
                   <div class="card-content">
-                    <tf-chart tag="[[tag]]" data-provider="[[dataProvider]]" type="scalar" id="chart" selected-runs="[[validRuns(tag, selectedRuns.*, run2tag.*)]]" x-type="[[xType]]" color-scale="[[colorScale]]" on-keyup="toggleSelected" tabindex="2" tooltip-updater="[[tooltipUpdater]]"></tf-chart>
+                    <tf-chart tag="[[tag]]" data-provider="[[dataProvider]]" type="scalar" id="chart" selected-runs="[[validRuns(tag, selectedRuns.*, run2tag.*)]]" x-type="[[xType]]" color-scale="[[colorScale]]" on-keyup="toggleSelected" tabindex="2"></tf-chart>
                     <paper-icon-button class="expand-button" shift$="[[_show_download_links]]" icon="fullscreen" on-tap="toggleSelected"></paper-icon-button>
                   </div>
                   <template is="dom-if" if="[[_show_download_links]]">
@@ -2697,8 +2743,6 @@
   <template>
     <div id="plumbing">
       <tf-color-scale id="colorScale" runs="[[runs]]" out-color-scale="{{colorScale}}" out-class-scale="{{classScale}}"></tf-color-scale>
-
-      <tf-tooltip-coordinator id="tooltipCoordinator" out-tooltip-updater="{{tooltipUpdater}}" out-tooltip-map="{{tooltipMap}}" out-x-value="{{tooltipXValue}}" out-closest-run="{{closestRun}}"></tf-tooltip-coordinator>
     </div>
 
     <tf-dashboard-layout>
@@ -2710,7 +2754,7 @@
           <tf-x-type-selector id="xTypeSelector" out-x-type="{{xType}}"></tf-x-type-selector>
         </div>
         <div class="sidebar-section">
-          <tf-run-selector id="runSelector" runs="[[runs]]" class-scale="[[classScale]]" out-selected="{{selectedRuns}}" tooltips="[[tooltipMap]]" closest-run="[[closestRun]]" x-value="[[tooltipXValue]]" x-type="[[xType]]"></tf-run-selector>
+          <tf-run-selector id="runSelector" runs="[[runs]]" class-scale="[[classScale]]" out-selected="{{selectedRuns}}"></tf-run-selector>
           </div>
       </div>
 
@@ -2725,7 +2769,7 @@
                     <div class="card">
                       <span class="card-title">[[tag]]</span>
                       <div class="card-content">
-                        <tf-chart tag="[[tag]]" type="compressedHistogram" id="chart" selected-runs="[[_array(run)]]" x-type="[[xType]]" data-provider="[[dataProvider]]" color-scale="[[colorScale]]" on-keyup="toggleSelected" tabindex="2" tooltip-updater="[[tooltipUpdater]]"></tf-chart>
+                        <tf-chart tag="[[tag]]" type="compressedHistogram" id="chart" selected-runs="[[_array(run)]]" x-type="[[xType]]" data-provider="[[dataProvider]]" color-scale="[[colorScale]]" on-keyup="toggleSelected" tabindex="2"></tf-chart>
                         <paper-icon-button class="expand-button" icon="fullscreen" on-tap="toggleSelected"></paper-icon-button>
                       </div>
                     </div>
@@ -3003,6 +3047,211 @@
   </script>
 </dom-module>
 
+<dom-module id="tf-audio-loader" assetpath="../tf-audio-dashboard/">
+  <style>
+  :host {
+    display: block;
+  }
+  img {
+    width: 100%;
+    height: 100%;
+    image-rendering: pixelated;
+  }
+  </style>
+  <template>
+    <template is="dom-if" if="[[audioUrl]]">
+      <audio controls="" loop="">
+        <source src="[[audioUrl]]" type="[[audioContentType]]">
+      </audio>
+    </template>
+  </template>
+  <script>
+    Polymer({
+      is: "tf-audio-loader",
+      properties: {
+        run: String,
+        tag: String,
+        audioGenerator: Function,
+        audioUrl: String,
+        audioContentType: String
+      },
+      reload: function() {
+        var _this = this;
+        this.audioUrl = ""; // force reload
+        this.audioContentType = "";
+        this.audioGenerator(this.tag, this.run).then(function(metadatas) {
+          var last_metadata = _.last(metadatas);
+          _this.audioUrl = last_metadata.url;
+          _this.audioContentType = last_metadata.content_type;
+        })
+      },
+      ready: function() {
+        // Need to test so that it will not error if it is constructed w/o
+        // all properties (so that it's possible to use stub to mock it out)
+        if (this.run != null && this.tag != null && this.audioGenerator != null) {
+          this.reload();
+        }
+      },
+    });
+  </script>
+</dom-module>
+
+<dom-module id="tf-audio-grid" assetpath="../tf-audio-dashboard/">
+  <template>
+    <style include="scrollbar-style"></style>
+    <div id="fullContainer" class="container scrollbar">
+      <div id="topRow" class="container">
+        <div class="noshrink" id="paddingCell"></div>
+        <template is="dom-repeat" items="[[runs]]" as="run">
+        <div class="run-name-cell noshrink">
+          <span>[[run]]</span>
+        </div>
+      </template>
+      </div>
+      <div id="bottomContainer" class="container">
+        <template is="dom-repeat" items="[[tags]]" as="tag">
+          <div class="audio-row container noshrink">
+            <div class="tag-name-cell noshrink">
+              <span class="tag-name">[[tag]]</span>
+            </div>
+            <template is="dom-repeat" items="[[runs]]" as="run">
+              <div class="audio-cell noshrink">
+                <template is="dom-if" if="[[_exists(run, tag, runToAudio.*)]]">
+                  <tf-audio-loader id="loader" run="[[run]]" tag="[[tag]]" audio-generator="[[audioGenerator]]">
+                  </tf-audio-loader>
+                </template>
+              </div>
+            </template>
+          </div>
+        </template>
+      </div>
+    </div>
+    <style>
+      :host {
+        display: block;
+        height: 100%;
+      }
+      .container {
+        display: flex;
+        flex-wrap: nowrap;
+      }
+      #fullContainer {
+        width: 100%;
+        height: 100%;
+        flex-direction: column;
+        padding-top: 20px;
+        overflow: scroll;
+        -webkit-box-sizing: border-box;
+        -moz-box-sizing: border-box;
+        box-sizing: border-box;
+      }
+      #topRow {
+        flex-direction: row;
+      }
+      #bottomContainer {
+        flex-direction: column;
+        height: 100%;
+        width: 100%;
+      }
+      .audio-row {
+        flex-direction: row;
+        padding-top: 5px;
+      }
+      .audio-cell {
+        width: 300px;
+        height: 30px;
+        border: 1px solid black;
+      }
+      .tag-name-cell {
+        width: 300px;
+        height: 30px;
+        display:flex;
+        flex-direction: column;
+        justify-content: center;
+      }
+      .tag-name {
+        word-wrap: break-word;
+        text-align: center;
+        white-space: nowrap;
+      }
+      .run-name-cell {
+        width: 300px;
+        height: 30px;
+        text-align: center;
+      }
+      .noshrink {
+        flex-shrink: 0;
+      }
+      #paddingCell {
+        width: 300px;
+        height: 30px;
+      }
+    </style>
+  </template>
+  <script>
+    Polymer({
+      is: "tf-audio-grid",
+      properties: {
+        runToAudio: Object,
+        tags: Array,
+        runs: Array,
+        audioGenerator: Function,
+      },
+      _exists: function (run, tag) {
+        return this.runToAudio[run].indexOf(tag) !== -1;
+      },
+    });
+  </script>
+</dom-module>
+
+<dom-module id="tf-audio-dashboard" assetpath="../tf-audio-dashboard/">
+  <template>
+    <div class="center">
+      <tf-no-data-warning data-type="audio" show-warning="[[dataNotFound]]"></tf-no-data-warning>
+      <tf-audio-grid id="audioGrid" run-to-audio="[[run2tag]]" audio-generator="[[dataProvider]]" tags="[[tags]]" runs="[[runs]]"></tf-audio-grid>
+    </div>
+
+    <style>
+      .center {
+        padding-left: 10px;
+        padding-right: 10px;
+        height: 100%;
+        width: 100%;
+        -webkit-box-sizing: border-box;
+        -moz-box-sizing: border-box;
+        box-sizing: border-box;
+      }
+      :host {
+        height: 100%;
+        display: block;
+      }
+
+    </style>
+  </template>
+  <script>
+    Polymer({
+      is: "tf-audio-dashboard",
+      properties: {
+        dataType: {value: "audio"},
+      },
+      behaviors: [
+        TF.Dashboard.ReloadBehavior("tf-audio-loader"),
+        TF.Backend.Behavior
+      ],
+      attached: function() {
+        this.async(function() {
+          this.fire("rendered");
+        });
+      },
+      _hasAudio: function(runToAudioChange) {
+        return _.values(runToAudioChange.base).some(function(arr) {
+          return arr.length > 0;
+        });
+      },
+    });
+  </script>
+</dom-module>
+
 <dom-module id="tf-graph-loader" assetpath="../tf-graph-loader/">
 </dom-module>
 
@@ -3066,7 +3315,7 @@
       value: 0,
       msg: ''
     });
-    var tracker = tf.getTracker(this);
+    var tracker = tf.graph.util.getTracker(this);
     tf.graph.parser.fetchAndParseMetadata(path, tracker)
     .then(function(stats) {
       this._setOutStats(stats);
@@ -3078,7 +3327,7 @@
       value: 0,
       msg: ''
     });
-    var tracker = tf.getTracker(this);
+    var tracker = tf.graph.util.getTracker(this);
     var hierarchyParams = {
       verifyTemplate: true,
       // If a set of numbered op nodes has at least this number of nodes
@@ -3091,7 +3340,7 @@
       seriesMap: {},
     };
     this._setOutHierarchyParams(hierarchyParams);
-    var dataTracker = tf.getSubtaskTracker(tracker, 30, 'Data');
+    var dataTracker = tf.graph.util.getSubtaskTracker(tracker, 30, 'Data');
     tf.graph.parser.fetchAndParseGraphData(path, pbTxtFile, dataTracker)
     .then(function(graph) {
       // Build the flat graph (consists only of Op nodes).
@@ -3119,12 +3368,12 @@
         outEmbeddingTypes: ['^[a-zA-Z]+Summary$'],
         refEdges: refEdges
       };
-      var graphTracker = tf.getSubtaskTracker(tracker, 20, 'Graph');
+      var graphTracker = tf.graph.util.getSubtaskTracker(tracker, 20, 'Graph');
       return tf.graph.build(graph, buildParams, graphTracker);
     })
     .then(function(graph) {
       this._setOutGraph(graph);
-      var hierarchyTracker = tf.getSubtaskTracker(tracker, 50,
+      var hierarchyTracker = tf.graph.util.getSubtaskTracker(tracker, 50,
           'Namespace hierarchy');
       return tf.graph.hierarchy.build(graph, hierarchyParams, hierarchyTracker);
     }.bind(this))
@@ -3161,14 +3410,14 @@
 </script>
 <script>/* Copyright 2015 Google Inc. All Rights Reserved.
 
-Licensed under the Apache License, Version 2.0 (the "License");
+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,
+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.
@@ -3176,149 +3425,159 @@
 var tf;
 (function (tf) {
     /**
-     * Recommended delay (ms) when running an expensive task asynchronously
-     * that gives enough time for the progress bar to update its UI.
+     * Mapping from color palette name to color palette, which contains
+     * exact colors for multiple states of a single color palette.
      */
-    var ASYNC_TASK_DELAY = 20;
-    function time(msg, task) {
-        var start = Date.now();
-        var result = task();
-        /* tslint:disable */
-        console.log(msg, ":", Date.now() - start, "ms");
-        /* tslint:enable */
-        return result;
-    }
-    tf.time = time;
-    /**
-     * Creates a tracker that sets the progress property of the
-     * provided polymer component. The provided component must have
-     * a property called 'progress' that is not read-only. The progress
-     * property is an object with a numerical 'value' property and a
-     * string 'msg' property.
-     */
-    function getTracker(polymerComponent) {
-        return {
-            setMessage: function (msg) {
-                polymerComponent.set("progress", {
-                    value: polymerComponent.progress.value,
-                    msg: msg
-                });
-            },
-            updateProgress: function (value) {
-                polymerComponent.set("progress", {
-                    value: polymerComponent.progress.value + value,
-                    msg: polymerComponent.progress.msg
-                });
-            },
-            reportError: function (msg, err) {
-                // Log the stack trace in the console.
-                console.error(err.stack);
-                // And send a user-friendly message to the UI.
-                polymerComponent.set("progress", {
-                    value: polymerComponent.progress.value,
-                    msg: msg,
-                    error: true
-                });
-            },
-        };
-    }
-    tf.getTracker = getTracker;
-    /**
-     * Creates a tracker for a subtask given the parent tracker, the total progress
-     * of the subtask and the subtask message. The parent task should pass a
-     * subtracker to its subtasks. The subtask reports its own progress which
-     * becames relative to the main task.
-     */
-    function getSubtaskTracker(parentTracker, impactOnTotalProgress, subtaskMsg) {
-        return {
-            setMessage: function (progressMsg) {
-                // The parent should show a concatenation of its message along with
-                // its subtask tracker message.
-                parentTracker.setMessage(subtaskMsg + ": " + progressMsg);
-            },
-            updateProgress: function (incrementValue) {
-                // Update the parent progress relative to the child progress.
-                // For example, if the sub-task progresses by 30%, and the impact on the
-                // total progress is 50%, then the task progresses by 30% * 50% = 15%.
-                parentTracker
-                    .updateProgress(incrementValue * impactOnTotalProgress / 100);
-            },
-            reportError: function (msg, err) {
-                // The parent should show a concatenation of its message along with
-                // its subtask error message.
-                parentTracker.reportError(subtaskMsg + ": " + msg, err);
-            }
-        };
-    }
-    tf.getSubtaskTracker = getSubtaskTracker;
-    /**
-     * Runs an expensive task and return the result.
-     */
-    function runTask(msg, incProgressValue, task, tracker) {
-        // Update the progress message to say the current running task.
-        tracker.setMessage(msg);
-        // Run the expensive task with a delay that gives enough time for the
-        // UI to update.
-        try {
-            var result = tf.time(msg, task);
-            // Update the progress value.
-            tracker.updateProgress(incProgressValue);
-            // Return the result to be used by other tasks.
-            return result;
+    tf.COLORS = [
+        {
+            'name': 'Google Blue',
+            'color': '#4184f3',
+            'active': '#3a53c5',
+            'disabled': '#cad8fc'
+        },
+        {
+            'name': 'Google Red',
+            'color': '#db4437',
+            'active': '#8f2a0c',
+            'disabled': '#e8c6c1'
+        },
+        {
+            'name': 'Google Yellow',
+            'color': '#f4b400',
+            'active': '#db9200',
+            'disabled': '#f7e8b0'
+        },
+        {
+            'name': 'Google Green',
+            'color': '#0f9d58',
+            'active': '#488046',
+            'disabled': '#c2e1cc'
+        },
+        {
+            'name': 'Purple',
+            'color': '#aa46bb',
+            'active': '#5c1398',
+            'disabled': '#d7bce6'
+        },
+        {
+            'name': 'Teal',
+            'color': '#00abc0',
+            'active': '#47828e',
+            'disabled': '#c2eaf2'
+        },
+        {
+            'name': 'Deep Orange',
+            'color': '#ff6f42',
+            'active': '#ca4a06',
+            'disabled': '#f2cbba'
+        },
+        {
+            'name': 'Lime',
+            'color': '#9d9c23',
+            'active': '#7f771d',
+            'disabled': '#f1f4c2'
+        },
+        {
+            'name': 'Indigo',
+            'color': '#5b6abf',
+            'active': '#3e47a9',
+            'disabled': '#c5c8e8'
+        },
+        {
+            'name': 'Pink',
+            'color': '#ef6191',
+            'active': '#ca1c60',
+            'disabled': '#e9b9ce'
+        },
+        {
+            'name': 'Deep Teal',
+            'color': '#00786a',
+            'active': '#2b4f43',
+            'disabled': '#bededa'
+        },
+        {
+            'name': 'Deep Pink',
+            'color': '#c1175a',
+            'active': '#75084f',
+            'disabled': '#de8cae'
+        },
+        {
+            'name': 'Gray',
+            'color': '#9E9E9E',
+            'active': '#424242',
+            'disabled': 'F5F5F5' // 100
         }
-        catch (e) {
-            // Errors that happen inside asynchronous tasks are
-            // reported to the tracker using a user-friendly message.
-            tracker.reportError("Failed " + msg, e);
-        }
-    }
-    tf.runTask = runTask;
+    ].reduce(function (m, c) {
+        m[c.name] = c;
+        return m;
+    }, {});
     /**
-     * Runs an expensive task asynchronously and returns a promise of the result.
+     * Mapping from op category to color palette name
+     * e.g.,  OP_GROUP_COLORS['state_ops'] = 'Google Blue';
      */
-    function runAsyncTask(msg, incProgressValue, task, tracker) {
-        return new Promise(function (resolve, reject) {
-            // Update the progress message to say the current running task.
-            tracker.setMessage(msg);
-            // Run the expensive task with a delay that gives enough time for the
-            // UI to update.
-            setTimeout(function () {
-                try {
-                    var result = tf.time(msg, task);
-                    // Update the progress value.
-                    tracker.updateProgress(incProgressValue);
-                    // Return the result to be used by other tasks.
-                    resolve(result);
-                }
-                catch (e) {
-                    // Errors that happen inside asynchronous tasks are
-                    // reported to the tracker using a user-friendly message.
-                    tracker.reportError("Failed " + msg, e);
-                }
-            }, ASYNC_TASK_DELAY);
-        });
-    }
-    tf.runAsyncTask = runAsyncTask;
-    /**
-     * Returns a query selector with escaped special characters that are not
-     * allowed in a query selector.
-     */
-    function escapeQuerySelector(querySelector) {
-        return querySelector.replace(/([:.\[\],/\\\(\)])/g, "\\$1");
-    }
-    tf.escapeQuerySelector = escapeQuerySelector;
-})(tf || (tf = {})); // close module tf
+    tf.OP_GROUP_COLORS = [
+        {
+            color: 'Google Red',
+            groups: [
+                'gen_legacy_ops', 'legacy_ops', 'legacy_flogs_input',
+                'legacy_image_input', 'legacy_input_example_input',
+                'legacy_sequence_input', 'legacy_seti_input_input'
+            ]
+        },
+        { color: 'Deep Orange', groups: ['constant_ops'] },
+        { color: 'Indigo', groups: ['state_ops'] },
+        { color: 'Purple', groups: ['nn_ops', 'nn'] },
+        { color: 'Google Green', groups: ['math_ops'] },
+        { color: 'Lime', groups: ['array_ops'] },
+        { color: 'Teal', groups: ['control_flow_ops', 'data_flow_ops'] },
+        { color: 'Pink', groups: ['summary_ops'] },
+        { color: 'Deep Pink', groups: ['io_ops'] }
+    ].reduce(function (m, c) {
+        c.groups.forEach(function (group) { m[group] = c.color; });
+        return m;
+    }, {});
+})(tf || (tf = {}));
 </script>
 <script>/* Copyright 2015 Google Inc. All Rights Reserved.
 
-Licensed under the Apache License, Version 2.0 (the "License");
+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,
+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.
+==============================================================================*/
+</script>
+<script>/* Copyright 2015 Google Inc. All Rights Reserved.
+
+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.
+==============================================================================*/
+</script>
+<script>/* Copyright 2015 Google Inc. All Rights Reserved.
+
+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.
@@ -3328,17 +3587,17 @@
     var graph;
     (function (graph_1) {
         /** Delimiter used in node names to denote namespaces. */
-        graph_1.NAMESPACE_DELIM = "/";
-        graph_1.ROOT_NAME = "__root__";
+        graph_1.NAMESPACE_DELIM = '/';
+        graph_1.ROOT_NAME = '__root__';
         /** Attribute key used for storing attributes that are too large. */
-        graph_1.LARGE_ATTRS_KEY = "_too_large_attrs";
+        graph_1.LARGE_ATTRS_KEY = '_too_large_attrs';
         /**
          * Maximum allowed size in bytes, before the attribute is considered large
          * and filtered out of the graph.
          */
         graph_1.LIMIT_ATTR_SIZE = 1024;
         // Separator between the source and the destination name of the edge.
-        graph_1.EDGE_KEY_DELIM = "--";
+        graph_1.EDGE_KEY_DELIM = '--';
         (function (GraphType) {
             GraphType[GraphType["FULL"] = 0] = "FULL";
             GraphType[GraphType["EMBEDDED"] = 1] = "EMBEDDED";
@@ -3376,7 +3635,7 @@
         var SeriesGroupingType = graph_1.SeriesGroupingType;
         ;
         /** Attribute key reserved for the shapes of the output tensors. */
-        var OUTPUT_SHAPES_KEY = "_output_shapes";
+        var OUTPUT_SHAPES_KEY = '_output_shapes';
         /**
          * A SlimGraph is inspired by graphlib.Graph, but having only the functionality
          * that we need.
@@ -3406,7 +3665,7 @@
             }
             EllipsisNodeImpl.prototype.setNumMoreNodes = function (numNodes) {
                 this.numMoreNodes = numNodes;
-                this.name = "... " + numNodes + " more";
+                this.name = '... ' + numNodes + ' more';
             };
             return EllipsisNodeImpl;
         }());
@@ -3461,9 +3720,9 @@
                     // Lookup the node in the graph by its original name, e.g. A. If not
                     // found, lookup by the rewritten name A/(A) in case the name is both
                     // a namespace and a node name.
-                    var nodeName = nodeStats.node_name in graph.nodes ?
-                        nodeStats.node_name :
-                        nodeStats.node_name + graph_1.NAMESPACE_DELIM + "(" + nodeStats.node_name + ")";
+                    var nodeName = nodeStats.node_name in graph.nodes ? nodeStats.node_name :
+                        nodeStats.node_name +
+                            graph_1.NAMESPACE_DELIM + '(' + nodeStats.node_name + ')';
                     // Couldn't find a matching node.
                     if (!(nodeName in graph.nodes)) {
                         return;
@@ -3473,10 +3732,26 @@
                     if (nodeStats.memory) {
                         _.each(nodeStats.memory, function (alloc) {
                             if (alloc.total_bytes) {
-                                totalBytes += Number(alloc.total_bytes);
+                                if (alloc.total_bytes > 0) {
+                                    totalBytes += Number(alloc.total_bytes);
+                                }
+                                else {
+                                    /* tslint:disable */
+                                    console.log('ignoring negative memory allocation for ' + nodeName);
+                                }
                             }
                         });
                     }
+                    var totalMicroSeconds = 0;
+                    if (nodeStats.all_end_rel_micros) {
+                        if (nodeStats.all_end_rel_micros > 0) {
+                            totalMicroSeconds = Number(nodeStats.all_end_rel_micros);
+                        }
+                        else {
+                            /* tslint:disable */
+                            console.log('ignoring negative runtime for ' + nodeName);
+                        }
+                    }
                     var outputSize = null;
                     if (nodeStats.output) {
                         outputSize = _.map(nodeStats.output, function (output) {
@@ -3484,7 +3759,7 @@
                         });
                     }
                     graph.nodes[nodeName].device = devStats.device;
-                    graph.nodes[nodeName].stats = new NodeStats(totalBytes, Number(nodeStats.all_end_rel_micros), outputSize);
+                    graph.nodes[nodeName].stats = new NodeStats(totalBytes, totalMicroSeconds, outputSize);
                 });
             });
         }
@@ -3550,12 +3825,12 @@
             };
             /**
              * Returns the op node associated with the metanode.
-             * For example, if the metanode is "sgd", the associated
+             * For example, if the metanode is 'sgd', the associated
              * op node is sgd/(sgd).
              */
             MetanodeImpl.prototype.getRootOp = function () {
-                var nameSplit = this.name.split("/");
-                var rootOpName = this.name + "/(" + nameSplit[nameSplit.length - 1] + ")";
+                var nameSplit = this.name.split('/');
+                var rootOpName = this.name + '/(' + nameSplit[nameSplit.length - 1] + ')';
                 return this.metagraph.node(rootOpName);
             };
             /**
@@ -3652,10 +3927,11 @@
         }
         graph_1.createSeriesNode = createSeriesNode;
         function getSeriesNodeName(prefix, suffix, parent, startId, endId) {
-            var numRepresentation = (typeof startId !== "undefined" && typeof endId !== "undefined") ?
-                "[" + startId + "-" + endId + "]" : "#";
+            var numRepresentation = (typeof startId !== 'undefined' && typeof endId !== 'undefined') ?
+                '[' + startId + '-' + endId + ']' :
+                '#';
             var pattern = prefix + numRepresentation + suffix;
-            return (parent ? parent + "/" : "") + pattern;
+            return (parent ? parent + '/' : '') + pattern;
         }
         graph_1.getSeriesNodeName = getSeriesNodeName;
         var SeriesNodeImpl = (function () {
@@ -3733,8 +4009,8 @@
          */
         function normalizeInputs(inputs) {
             return _.reduce(inputs, function (normalizedInputs, inputName) {
-                var start = inputName[0] === "^";
-                var colon = inputName.lastIndexOf(":");
+                var start = inputName[0] === '^';
+                var colon = inputName.lastIndexOf(':');
                 var end = colon !== -1 &&
                     inputName.length - colon > 1 &&
                     !(/\D/).test(inputName.substring(colon + 1)) ?
@@ -3758,7 +4034,7 @@
             }
             // Check if this op type and input number corresponds to a
             // reference edge using the refEdges dictionary in the params.
-            var isRefEdge = params.refEdges[outputNode.op + " " + index] === true;
+            var isRefEdge = params.refEdges[outputNode.op + ' ' + index] === true;
             graph.edges.push({
                 v: inputName,
                 w: outputNode.name,
@@ -3795,7 +4071,8 @@
              * even for very large networks that amounts to less than 10k spaces.
              */
             var nodeNames = new Array(rawNodes.length);
-            return tf.runAsyncTask("Normalizing names", 30, function () {
+            return tf.graph.util
+                .runAsyncTask('Normalizing names', 30, function () {
                 var opNodes = new Array(rawNodes.length);
                 var index = 0;
                 _.each(rawNodes, function (rawNode) {
@@ -3815,7 +4092,8 @@
                         });
                         return;
                     }
-                    // The node is not an embedding, so add it to the names and nodes lists.
+                    // The node is not an embedding, so add it to the names and nodes
+                    // lists.
                     opNodes[index] = opNode;
                     nodeNames[index] = opNode.name;
                     index++;
@@ -3826,7 +4104,7 @@
             }, tracker)
                 .then(function (opNodes) {
                 // Create the graph data structure from the graphlib library.
-                return tf.runAsyncTask("Building the data structure", 70, function () {
+                return tf.graph.util.runAsyncTask('Building the data structure', 70, function () {
                     var normalizedNameDict = mapStrictHierarchy(nodeNames, embeddingNodeNames);
                     var graph = new SlimGraph;
                     // Add the nodes to the graph.
@@ -3845,20 +4123,26 @@
                         // Update the name of the node.
                         opNode.name = normalizedName;
                     });
-                    // Visit each node's inputs to add the edges to the graph. If the input
-                    // is an in-embedding, then add it to the node's in-embeddings instead.
+                    // Visit each node's inputs to add the edges to the graph. If the
+                    // input
+                    // is an in-embedding, then add it to the node's in-embeddings
+                    // instead.
                     _.each(opNodes, function (opNode) {
                         _.each(opNode.inputs, function (input, i) {
                             var inputName = input.name;
                             if (inputName in inEmbedding) {
                                 var inEmbedNode = inEmbedding[inputName];
                                 opNode.inEmbeddings.push(inEmbedNode);
-                                // Move the inputs of the in-embedding node into incoming edges of
-                                // the main node. E.g. the control dependency of a constant node
-                                // should be moved to the op node where the constant is embedded.
+                                // Move the inputs of the in-embedding node into incoming
+                                // edges of
+                                // the main node. E.g. the control dependency of a constant
+                                // node
+                                // should be moved to the op node where the constant is
+                                // embedded.
                                 for (var _i = 0, _a = inEmbedNode.inputs; _i < _a.length; _i++) {
                                     var embedInput = _a[_i];
-                                    addEdgeToGraph(graph, normalizedNameDict[embedInput.name] || embedInput.name, opNode, embedInput.isControlDependency, params, i);
+                                    addEdgeToGraph(graph, normalizedNameDict[embedInput.name] ||
+                                        embedInput.name, opNode, embedInput.isControlDependency, params, i);
                                 }
                             }
                             else if (inputName in outEmbedding) {
@@ -3867,7 +4151,8 @@
                                 var outEmbedNode = outEmbedding[inputName];
                                 for (var _b = 0, _c = outEmbedNode.inputs; _b < _c.length; _b++) {
                                     var embedInput = _c[_b];
-                                    addEdgeToGraph(graph, normalizedNameDict[embedInput.name] || embedInput.name, opNode, input.isControlDependency, params, i);
+                                    addEdgeToGraph(graph, normalizedNameDict[embedInput.name] ||
+                                        embedInput.name, opNode, input.isControlDependency, params, i);
                                 }
                             }
                             else {
@@ -3893,7 +4178,7 @@
             var graph = new graphlib.Graph(opt);
             graph.setGraph({
                 name: name,
-                rankdir: "BT",
+                rankdir: 'BT',
                 type: type
             });
             return graph;
@@ -3923,15 +4208,15 @@
          */
         function getStrictName(name) {
             var parts = name.split(graph_1.NAMESPACE_DELIM);
-            return name + graph_1.NAMESPACE_DELIM + "(" + parts[parts.length - 1] + ")";
+            return name + graph_1.NAMESPACE_DELIM + '(' + parts[parts.length - 1] + ')';
         }
         /**
          * For each op node (embedding or non-embedding), rename it if there is a
-         * non-embedding node under its namespace. For example, assume node name "A".
-         * If there is a non-embedding node under its namespace (e.g. "A/B"), "A" will
-         * be renamed to "A/(A)". Then the namespace "A" will contain 2 nodes: "(A)"
-         * and "B". If all the nodes under "A" are embedding nodes (e.g. constant and
-         * summary), keep "A" as an Op node and don't create a namespace.
+         * non-embedding node under its namespace. For example, assume node name 'A'.
+         * If there is a non-embedding node under its namespace (e.g. 'A/B'), 'A' will
+         * be renamed to 'A/(A)'. Then the namespace 'A' will contain 2 nodes: '(A)'
+         * and 'B'. If all the nodes under 'A' are embedding nodes (e.g. constant and
+         * summary), keep 'A' as an Op node and don't create a namespace.
          *
          * @param nodeNames An array of regular (non-embedding) node names.
          * @param embeddingNodeNames An array of embedding node names.
@@ -3953,9 +4238,17 @@
                 _.each(getHierarchicalPath(a).slice(0, -1), function (ns) {
                     namespaceSet[ns] = true;
                 });
-                var b = nodeNames[i + 1];
-                if (_.startsWith(b, a + graph_1.NAMESPACE_DELIM)) {
-                    newNameDictionary[a] = getStrictName(a);
+                for (var j = i + 1; j < nodeNames.length; ++j) {
+                    var b = nodeNames[j];
+                    if (_.startsWith(b, a)) {
+                        if (b.length > a.length && b.charAt(a.length) === graph_1.NAMESPACE_DELIM) {
+                            newNameDictionary[a] = getStrictName(a);
+                            break;
+                        }
+                    }
+                    else {
+                        break;
+                    }
                 }
             }
             // Go through all the embedding node names and rename them in case they
@@ -4028,10 +4321,10 @@
          */
         function getIncludeNodeButtonString(include) {
             if (include === tf.graph.InclusionType.EXCLUDE) {
-                return "Add to main graph";
+                return 'Add to main graph';
             }
             else {
-                return "Remove from main graph";
+                return 'Remove from main graph';
             }
         }
         graph_1.getIncludeNodeButtonString = getIncludeNodeButtonString;
@@ -4042,10 +4335,10 @@
          */
         function getGroupSeriesNodeButtonString(group) {
             if (group === tf.graph.SeriesGroupingType.GROUP) {
-                return "Ungroup this series of nodes";
+                return 'Ungroup this series of nodes';
             }
             else {
-                return "Group this series of nodes";
+                return 'Group this series of nodes';
             }
         }
         graph_1.getGroupSeriesNodeButtonString = getGroupSeriesNodeButtonString;
@@ -4069,275 +4362,14 @@
 </script>
 <script>/* Copyright 2015 Google Inc. All Rights Reserved.
 
-Licensed under the Apache License, Version 2.0 (the "License");
+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.
-==============================================================================*/
-var tf;
-(function (tf) {
-    var graph;
-    (function (graph) {
-        var parser;
-        (function (parser) {
-            /**
-             * Parses a native js value, which can be either a string, boolean or number.
-             *
-             * @param value The value to be parsed.
-             */
-            function parseValue(value) {
-                if (value === "true") {
-                    return true;
-                }
-                if (value === "false") {
-                    return false;
-                }
-                var firstChar = value[0];
-                if (firstChar === "\"") {
-                    return value.substring(1, value.length - 1);
-                }
-                var num = parseFloat(value);
-                return isNaN(num) ? value : num;
-            }
-            /**
-             * Fetches a text file and returns a promise of the result.
-             */
-            function fetchPbTxt(filepath) {
-                return new Promise(function (resolve, reject) {
-                    d3.text(filepath, function (error, text) {
-                        if (error) {
-                            reject(error);
-                            return;
-                        }
-                        resolve(text);
-                    });
-                });
-            }
-            parser.fetchPbTxt = fetchPbTxt;
-            /**
-             * Fetches the metadata file, parses it and returns a promise of the result.
-             */
-            function fetchAndParseMetadata(path, tracker) {
-                return tf.runTask("Reading metadata pbtxt", 40, function () {
-                    if (path == null) {
-                        return Promise.resolve(null);
-                    }
-                    return fetchPbTxt(path).then(function (text) { return new Blob([text]); });
-                }, tracker)
-                    .then(function (blob) {
-                    return tf.runTask("Parsing metadata.pbtxt", 60, function () {
-                        return blob != null ? parseStatsPbTxt(blob) : null;
-                    }, tracker);
-                });
-            }
-            parser.fetchAndParseMetadata = fetchAndParseMetadata;
-            /**
-             * Fetches the graph file, parses it and returns a promise of the result.
-             */
-            function fetchAndParseGraphData(path, pbTxtFile, tracker) {
-                return tf.runTask("Reading graph pbtxt", 40, function () {
-                    return pbTxtFile ?
-                        Promise.resolve(pbTxtFile) :
-                        fetchPbTxt(path).then(function (text) { return new Blob([text]); });
-                }, tracker)
-                    .then(function (blob) {
-                    return tf.runTask("Parsing graph.pbtxt", 60, function () {
-                        return parseGraphPbTxt(blob);
-                    }, tracker);
-                });
-            }
-            parser.fetchAndParseGraphData = fetchAndParseGraphData;
-            /**
-             * Parse a file object in a streaming fashion line by line (or custom delim).
-             * Can handle very large files.
-             * @param input The file object
-             * @param callback The callback called on each line
-             * @param chunkSize The size of each read chunk. (optional)
-             * @param delim The delimiter used to split a line. (optional)
-             * @returns A promise for when it is finished.
-             */
-            function streamParse(file, callback, chunkSize, delim) {
-                if (chunkSize === void 0) { chunkSize = 1000000; }
-                if (delim === void 0) { delim = "\n"; }
-                return new Promise(function (resolve, reject) {
-                    var offset = 0;
-                    var fileSize = file.size - 1;
-                    var data = "";
-                    function readHandler(evt) {
-                        if (evt.target.error == null) {
-                            offset += evt.target.result.length;
-                            var str = evt.target.result;
-                            var parts = str.split(delim);
-                            var first = data + parts[0];
-                            if (parts.length === 1) {
-                                data = first;
-                                readChunk(offset, chunkSize);
-                                return;
-                            }
-                            data = parts[parts.length - 1];
-                            callback(first);
-                            for (var i = 1; i < parts.length - 1; i++) {
-                                callback(parts[i]);
-                            }
-                        }
-                        else {
-                            // read error
-                            reject(evt.target.error);
-                            return;
-                        }
-                        if (offset >= fileSize) {
-                            if (data) {
-                                callback(data);
-                            }
-                            resolve(true);
-                            return;
-                        }
-                        readChunk(offset, chunkSize);
-                    }
-                    function readChunk(offset, size) {
-                        var reader = new FileReader();
-                        var blob = file.slice(offset, offset + size);
-                        reader.onload = readHandler;
-                        reader.readAsText(blob);
-                    }
-                    readChunk(offset, chunkSize);
-                });
-            }
-            parser.streamParse = streamParse;
-            /**
-             * Since proto-txt doesn't explicitly say whether an attribute is repeated
-             * (an array) or not, we keep a hard-coded list of attributes that are known
-             * to be repeated. This list is used in parsing time to convert repeated
-             * attributes into arrays even when the attribute only shows up once in the
-             * object.
-             */
-            var GRAPH_REPEATED_FIELDS = {
-                "node": true,
-                "node.input": true,
-                "node.attr": true,
-                "node.attr.value.list.type": true,
-                "node.attr.value.shape.dim": true,
-                "node.attr.value.tensor.string_val": true,
-                "node.attr.value.tensor.tensor_shape.dim": true,
-                "node.attr.value.list.shape": true,
-                "node.attr.value.list.shape.dim": true,
-                "node.attr.value.list.s": true
-            };
-            var METADATA_REPEATED_FIELDS = {
-                "step_stats.dev_stats": true,
-                "step_stats.dev_stats.node_stats": true,
-                "step_stats.dev_stats.node_stats.output": true,
-                "step_stats.dev_stats.node_stats.memory": true,
-                "step_stats.dev_stats.node_stats.output.tensor_description.shape.dim": true
-            };
-            /**
-             * Parses a blob of proto txt file into a raw Graph object.
-             */
-            function parseGraphPbTxt(input) {
-                return parsePbtxtFile(input, GRAPH_REPEATED_FIELDS).then(function (obj) { return obj["node"]; });
-            }
-            parser.parseGraphPbTxt = parseGraphPbTxt;
-            /**
-             * Parses a blob of proto txt file into a StepStats object.
-             */
-            function parseStatsPbTxt(input) {
-                return parsePbtxtFile(input, METADATA_REPEATED_FIELDS)
-                    .then(function (obj) { return obj["step_stats"]; });
-            }
-            /**
-             * Parses a blob of proto txt file into javascript object.
-             *
-             * @param input The Blob or file object implementing slice.
-             * @param repeatedFields Map (Set) of all the repeated fields, since you can't
-             *   tell directly from the pbtxt if a field is repeated or not.
-             * @returns The parsed object.
-             */
-            function parsePbtxtFile(input, repeatedFields) {
-                var output = {};
-                var stack = [];
-                var path = [];
-                var current = output;
-                function splitNameAndValueInAttribute(line) {
-                    var colonIndex = line.indexOf(":");
-                    var name = line.substring(0, colonIndex).trim();
-                    var value = parseValue(line.substring(colonIndex + 2).trim());
-                    return {
-                        name: name,
-                        value: value
-                    };
-                }
-                /**
-                 * Adds a value, given the attribute name and the host object. If the
-                 * attribute already exists, but is not an array, it will convert it to an
-                 * array of values.
-                 *
-                 * @param obj The host object that holds the attribute.
-                 * @param name The attribute name (key).
-                 * @param value The attribute value.
-                 * @param path A path that identifies the attribute. Used to check if
-                 *     an attribute is an array or not.
-                 */
-                function addAttribute(obj, name, value, path) {
-                    // We treat "node" specially since it is done so often.
-                    var existingValue = obj[name];
-                    if (existingValue == null) {
-                        obj[name] = path.join(".") in repeatedFields ? [value] : value;
-                    }
-                    else if (Array.isArray(existingValue)) {
-                        existingValue.push(value);
-                    }
-                    else {
-                        obj[name] = [existingValue, value];
-                    }
-                }
-                // Run through the file a line at a time.
-                return streamParse(input, function (line) {
-                    if (!line) {
-                        return;
-                    }
-                    switch (line[line.length - 1]) {
-                        case "{":
-                            var name_1 = line.substring(0, line.length - 2).trim();
-                            var newValue = {};
-                            stack.push(current);
-                            path.push(name_1);
-                            addAttribute(current, name_1, newValue, path);
-                            current = newValue;
-                            break;
-                        case "}":
-                            current = stack.pop();
-                            path.pop();
-                            break;
-                        default:
-                            var x = splitNameAndValueInAttribute(line);
-                            addAttribute(current, x.name, x.value, path.concat(x.name));
-                            break;
-                    }
-                }).then(function () {
-                    return output;
-                });
-            }
-        })(parser = graph.parser || (graph.parser = {}));
-    })(graph = tf.graph || (tf.graph = {}));
-})(tf || (tf = {})); // Close module tf.graph.parser.
-</script>
-<script>/* Copyright 2015 Google Inc. All Rights Reserved.
-
-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,
+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.
@@ -4388,9 +4420,9 @@
                     var _this = this;
                     var node = this.index[nodeName];
                     if (!node) {
-                        throw Error("Could not find node in hierarchy: " + nodeName);
+                        throw Error('Could not find node in hierarchy: ' + nodeName);
                     }
-                    if (!("metagraph" in node)) {
+                    if (!('metagraph' in node)) {
                         return null;
                     }
                     var groupNode = node;
@@ -4398,8 +4430,8 @@
                         return groupNode.bridgegraph;
                     }
                     var bridgegraph = groupNode.bridgegraph =
-                        graph_1.createGraph("BRIDGEGRAPH", graph_1.GraphType.BRIDGE);
-                    if (!node.parentNode || !("metagraph" in node.parentNode)) {
+                        graph_1.createGraph('BRIDGEGRAPH', graph_1.GraphType.BRIDGE);
+                    if (!node.parentNode || !('metagraph' in node.parentNode)) {
                         return bridgegraph;
                     }
                     var parentNode = node.parentNode;
@@ -4419,7 +4451,7 @@
                             // there's a Metaedge in the bridgegraph that covers it.
                             _.each(parentMetaedge.baseEdgeList, function (baseEdge) {
                                 // Based on the direction, figure out which is the descendant node
-                                // and which is the "other" node (sibling of parent or ancestor).
+                                // and which is the 'other' node (sibling of parent or ancestor).
                                 var _a = inbound ?
                                     [baseEdge.w, parentEdgeObj.v] :
                                     [baseEdge.v, parentEdgeObj.w], descendantName = _a[0], otherName = _a[1];
@@ -4460,8 +4492,7 @@
                         }
                         currentNode = currentNode.parentNode;
                     }
-                    throw Error("Could not find immediate child for descendant: " +
-                        descendantName);
+                    throw Error('Could not find immediate child for descendant: ' + descendantName);
                 };
                 ;
                 /**
@@ -4474,16 +4505,16 @@
                  * shared ancestor is the ROOT node. A and Z are the highest siblings. Here
                  * are the results of calling getPredecessors():
                  *
-                 *  - getPredecessors("Z/Y/X") === {regular: ["A/B/C"], control: []};
-                 *  - getPredecessors("Z/Y") === {regular: ["A"], control: []};
-                 *  - getPredecessors("Z") === {regular: ["A"], control: []};
+                 *  - getPredecessors('Z/Y/X') === {regular: ['A/B/C'], control: []};
+                 *  - getPredecessors('Z/Y') === {regular: ['A'], control: []};
+                 *  - getPredecessors('Z') === {regular: ['A'], control: []};
                  *
-                 * The reason getPredecessors("Z/Y") returns ["A"] (and not ["A/B"] as you
+                 * The reason getPredecessors('Z/Y') returns ['A'] (and not ['A/B'] as you
                  * might intuitively expect) is because it's not clear how far down the
                  * other end of the hierarchy to traverse in the general case.
                  *
                  * Continuing this example, say there was another BaseEdge A/K->Z/Y/W. When
-                 * we look at Z/Y's predecessors, the best we can say is ["A"] without getting
+                 * we look at Z/Y's predecessors, the best we can say is ['A'] without getting
                  * into the details of which of Z/Y's descendant nodes have predecessors to
                  * which of A's descendants.
                  *
@@ -4493,7 +4524,7 @@
                 HierarchyImpl.prototype.getPredecessors = function (nodeName) {
                     var node = this.index[nodeName];
                     if (!node) {
-                        throw Error("Could not find node with name: " + nodeName);
+                        throw Error('Could not find node with name: ' + nodeName);
                     }
                     var predecessors = this.getOneWayEdges(node, true);
                     // Add embedded predecessors, such as constants.
@@ -4516,7 +4547,7 @@
                 HierarchyImpl.prototype.getSuccessors = function (nodeName) {
                     var node = this.index[nodeName];
                     if (!node) {
-                        throw Error("Could not find node with name: " + nodeName);
+                        throw Error('Could not find node with name: ' + nodeName);
                     }
                     var successors = this.getOneWayEdges(node, false);
                     // Add embedded successors, such as summaries.
@@ -4552,9 +4583,9 @@
                  * interested in the ordering under ROOT. In this case, any of the following
                  * would be legitimate return values:
                  *
-                 *  - { "A": 0, "B": 1, "C": 2 } -- most likely
-                 *  - { "A": 0, "B": 2, "C": 1 } -- less likely
-                 *  - { "A": 12, "B": 100, "C": 99 } -- unlikely, but still OK
+                 *  - { 'A': 0, 'B': 1, 'C': 2 } -- most likely
+                 *  - { 'A': 0, 'B': 2, 'C': 1 } -- less likely
+                 *  - { 'A': 12, 'B': 100, 'C': 99 } -- unlikely, but still OK
                  *
                  * The algorithm does not guarantee that all numbers from 0-N (where N is
                  * the number of nodes) appear exactly once. Rather it guarantees that if
@@ -4570,7 +4601,7 @@
                 HierarchyImpl.prototype.getTopologicalOrdering = function (nodeName) {
                     var node = this.index[nodeName];
                     if (!node) {
-                        throw Error("Could not find node with name: " + nodeName);
+                        throw Error('Could not find node with name: ' + nodeName);
                     }
                     if (!node.isGroupNode) {
                         return null;
@@ -4660,7 +4691,8 @@
             function build(graph, params, tracker) {
                 var h = new HierarchyImpl();
                 var seriesNames = {};
-                return tf.runAsyncTask("Adding nodes", 20, function () {
+                return tf.graph.util
+                    .runAsyncTask('Adding nodes', 20, function () {
                     // Get all the possible device names.
                     var deviceNames = {};
                     _.each(graph.nodes, function (node, nodeName) {
@@ -4672,25 +4704,23 @@
                     addNodes(h, graph);
                 }, tracker)
                     .then(function () {
-                    return tf.runAsyncTask("Detect series", 20, function () {
+                    return tf.graph.util.runAsyncTask('Detect series', 20, function () {
                         if (params.seriesNodeMinSize > 0) {
                             groupSeries(h.root, h, seriesNames, params.seriesNodeMinSize, params.seriesMap);
                         }
                     }, tracker);
                 })
                     .then(function () {
-                    return tf.runAsyncTask("Adding edges", 30, function () {
+                    return tf.graph.util.runAsyncTask('Adding edges', 30, function () {
                         addEdges(h, graph, seriesNames);
                     }, tracker);
                 })
                     .then(function () {
-                    return tf.runAsyncTask("Finding similar subgraphs", 30, function () {
+                    return tf.graph.util.runAsyncTask('Finding similar subgraphs', 30, function () {
                         h.templates = graph_1.template.detect(h, params.verifyTemplate);
                     }, tracker);
                 })
-                    .then(function () {
-                    return h;
-                });
+                    .then(function () { return h; });
             }
             hierarchy_1.build = build;
             ;
@@ -4819,8 +4849,8 @@
                             // This would only occur if the two nodes were the same (a cycle in the
                             // graph), or if one endpoint was a strict ancestor of the other. The
                             // latter shouldn't happen because we rename nodes which are both
-                            // metanodes and op nodes. E.g. "A/B" becomes "A/B/(B)".
-                            throw Error("No difference found between ancestor paths.");
+                            // metanodes and op nodes. E.g. 'A/B' becomes 'A/B/(B)'.
+                            throw Error('No difference found between ancestor paths.');
                         }
                     }
                     var sharedAncestorNode = nodeIndex[sourcePath[sourceAncestorIndex + 1]];
@@ -4928,7 +4958,7 @@
             }
             /**
              * For each cluster of op-nodes based op type, try to detect groupings.
-             * Infer series name using by trying to find pattern "<number>" in the node
+             * Infer series name using by trying to find pattern '<number>' in the node
              * name.
              *
              * @param clusters Dictionary output from clusterNodes().
@@ -4950,14 +4980,14 @@
                     // number at the end of the name after an underscore, which is allowed to
                     // vary.
                     _.each(members, function (name) {
-                        var isGroup = name.charAt(name.length - 1) === "*";
-                        var namepath = name.split("/");
+                        var isGroup = name.charAt(name.length - 1) === '*';
+                        var namepath = name.split('/');
                         var leaf = namepath[namepath.length - 1];
-                        var parent = namepath.slice(0, namepath.length - 1).join("/");
+                        var parent = namepath.slice(0, namepath.length - 1).join('/');
                         var matches = leaf.match(/^(\D*)_(\d+)$/);
                         var prefix;
                         var id;
-                        var suffix = "";
+                        var suffix = '';
                         if (matches) {
                             prefix = matches[1]; // the front non-numeric characters
                             id = matches[2]; // the digits
@@ -4965,7 +4995,7 @@
                         else {
                             prefix = isGroup ? leaf.substr(0, leaf.length - 1) : leaf;
                             id = 0;
-                            suffix = isGroup ? "*" : "";
+                            suffix = isGroup ? '*' : '';
                         }
                         var seriesName = graph_1.getSeriesNodeName(prefix, suffix, parent);
                         candidatesDict[seriesName] = candidatesDict[seriesName] || [];
@@ -5023,6 +5053,981 @@
     })(graph = tf.graph || (tf.graph = {}));
 })(tf || (tf = {})); // close module tf.graph.hierarchy
 </script>
+<script>/* Copyright 2015 Google Inc. All Rights Reserved.
+
+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.
+==============================================================================*/
+var tf;
+(function (tf) {
+    var graph;
+    (function (graph_1) {
+        var layout;
+        (function (layout) {
+            /** Set of parameters that define the look and feel of the graph. */
+            layout.PARAMS = {
+                animation: {
+                    /** Default duration for graph animations in ms. */
+                    duration: 250
+                },
+                graph: {
+                    /** Graph parameter for metanode. */
+                    meta: {
+                        /**
+                         * Dagre's nodesep param - number of pixels that
+                         * separate nodes horizontally in the layout.
+                         *
+                         * See https://github.com/cpettitt/dagre/wiki#configuring-the-layout
+                         */
+                        nodeSep: 5,
+                        /**
+                         * Dagre's ranksep param - number of pixels
+                         * between each rank in the layout.
+                         *
+                         * See https://github.com/cpettitt/dagre/wiki#configuring-the-layout
+                         */
+                        rankSep: 25,
+                        /**
+                         * Dagre's edgesep param - number of pixels that separate
+                         * edges horizontally in the layout.
+                         */
+                        edgeSep: 5,
+                    },
+                    /** Graph parameter for metanode. */
+                    series: {
+                        /**
+                         * Dagre's nodesep param - number of pixels that
+                         * separate nodes horizontally in the layout.
+                         *
+                         * See https://github.com/cpettitt/dagre/wiki#configuring-the-layout
+                         */
+                        nodeSep: 5,
+                        /**
+                         * Dagre's ranksep param - number of pixels
+                         * between each rank in the layout.
+                         *
+                         * See https://github.com/cpettitt/dagre/wiki#configuring-the-layout
+                         */
+                        rankSep: 25,
+                        /**
+                         * Dagre's edgesep param - number of pixels that separate
+                         * edges horizontally in the layout.
+                         */
+                        edgeSep: 5
+                    },
+                    /**
+                     * Padding is used to correctly position the graph SVG inside of its parent
+                     * element. The padding amounts are applied using an SVG transform of X and
+                     * Y coordinates.
+                     */
+                    padding: {
+                        paddingTop: 40,
+                        paddingLeft: 20
+                    }
+                },
+                subscene: {
+                    meta: {
+                        paddingTop: 10,
+                        paddingBottom: 10,
+                        paddingLeft: 10,
+                        paddingRight: 10,
+                        /**
+                         * Used to leave room for the label on top of the highest node in
+                         * the core graph.
+                         */
+                        labelHeight: 20,
+                        /** X-space between each extracted node and the core graph. */
+                        extractXOffset: 15,
+                        /** Y-space between each extracted node. */
+                        extractYOffset: 20
+                    },
+                    series: {
+                        paddingTop: 10,
+                        paddingBottom: 10,
+                        paddingLeft: 10,
+                        paddingRight: 10,
+                        labelHeight: 10
+                    }
+                },
+                nodeSize: {
+                    /** Size of meta nodes. */
+                    meta: {
+                        radius: 5,
+                        width: 60,
+                        /** A scale for the node's height based on number of nodes inside */
+                        height: d3.scale.linear().domain([1, 200]).range([15, 60]).clamp(true),
+                        /** The radius of the circle denoting the expand button. */
+                        expandButtonRadius: 3
+                    },
+                    /** Size of op nodes. */
+                    op: {
+                        width: 15,
+                        height: 6,
+                        radius: 3,
+                        labelOffset: -8
+                    },
+                    /** Size of series nodes. */
+                    series: {
+                        expanded: {
+                            // For expanded series nodes, width and height will be
+                            // computed to account for the subscene.
+                            radius: 10,
+                            labelOffset: 0,
+                        },
+                        vertical: {
+                            // When unexpanded, series whose underlying metagraphs contain
+                            // one or more non-control edges will show as a vertical stack
+                            // of ellipses.
+                            width: 16,
+                            height: 13,
+                            labelOffset: -13,
+                        },
+                        horizontal: {
+                            // When unexpanded, series whose underlying metagraphs contain
+                            // no non-control edges will show as a horizontal stack of
+                            // ellipses.
+                            width: 24,
+                            height: 8,
+                            radius: 10,
+                            labelOffset: -10,
+                        },
+                    },
+                    /** Size of bridge nodes. */
+                    bridge: {
+                        // NOTE: bridge nodes will normally be invisible, but they must
+                        // take up some space so that the layout step leaves room for
+                        // their edges.
+                        width: 20,
+                        height: 20,
+                        radius: 2,
+                        labelOffset: 0
+                    }
+                },
+                shortcutSize: {
+                    /** Size of shortcuts for op nodes */
+                    op: {
+                        width: 10,
+                        height: 4
+                    },
+                    /** Size of shortcuts for meta nodes */
+                    meta: {
+                        width: 12,
+                        height: 4,
+                        radius: 1
+                    },
+                    /** Size of shortcuts for series nodes */
+                    series: {
+                        width: 14,
+                        height: 4,
+                    }
+                },
+                annotations: {
+                    /** Maximum possible width of the bounding box for in annotations */
+                    inboxWidth: 50,
+                    /** Maximum possible width of the bounding box for out annotations */
+                    outboxWidth: 50,
+                    /** X-space between the shape and each annotation-node. */
+                    xOffset: 10,
+                    /** Y-space between each annotation-node. */
+                    yOffset: 3,
+                    /** X-space between each annotation-node and its label. */
+                    labelOffset: 2,
+                    /** Estimate max width for annotation label */
+                    labelWidth: 35
+                },
+                constant: {
+                    size: {
+                        width: 4,
+                        height: 4
+                    }
+                },
+                series: {
+                    /** Maximum number of repeated item for unexpanded series node. */
+                    maxStackCount: 3,
+                    /**
+                     * Positioning offset ratio for collapsed stack
+                     * of parallel series (series without edges between its members).
+                     */
+                    parallelStackOffsetRatio: 0.2,
+                    /**
+                     * Positioning offset ratio for collapsed stack
+                     * of tower series (series with edges between its members).
+                     */
+                    towerStackOffsetRatio: 0.5
+                },
+                minimap: {
+                    /** The maximum width/height the minimap can have. */
+                    size: 150
+                }
+            };
+            /** Calculate layout for a scene of a group node. */
+            function layoutScene(renderNodeInfo) {
+                // Update layout, size, and annotations of its children nodes and edges.
+                if (renderNodeInfo.node.isGroupNode) {
+                    layoutChildren(renderNodeInfo);
+                }
+                // Update position of its children nodes and edges
+                if (renderNodeInfo.node.type === graph_1.NodeType.META) {
+                    layoutMetanode(renderNodeInfo);
+                }
+                else if (renderNodeInfo.node.type === graph_1.NodeType.SERIES) {
+                    layoutSeriesNode(renderNodeInfo);
+                }
+            }
+            layout.layoutScene = layoutScene;
+            ;
+            /**
+             * Updates the total width of an unexpanded node which includes the size of its
+             * in and out annotations.
+             */
+            function updateTotalWidthOfNode(renderInfo) {
+                renderInfo.inboxWidth = renderInfo.inAnnotations.list.length > 0 ?
+                    layout.PARAMS.annotations.inboxWidth : 0;
+                renderInfo.outboxWidth = renderInfo.outAnnotations.list.length > 0 ?
+                    layout.PARAMS.annotations.outboxWidth : 0;
+                // Assign the width of the core box (the main shape of the node).
+                renderInfo.coreBox.width = renderInfo.width;
+                renderInfo.coreBox.height = renderInfo.height;
+                // TODO(jimbo): Account for font width rather than using a magic number.
+                var labelLength = renderInfo.node.name.length -
+                    renderInfo.node.name.lastIndexOf(graph_1.NAMESPACE_DELIM) - 1;
+                var charWidth = 3; // 3 pixels per character.
+                // Compute the total width of the node.
+                renderInfo.width = Math.max(renderInfo.coreBox.width +
+                    renderInfo.inboxWidth + renderInfo.outboxWidth, labelLength * charWidth);
+            }
+            /**
+             * Update layout, size, and annotations of its children nodes and edges.
+             */
+            function layoutChildren(renderNodeInfo) {
+                var children = renderNodeInfo.coreGraph.nodes().map(function (n) {
+                    return renderNodeInfo.coreGraph.node(n);
+                }).concat(renderNodeInfo.isolatedInExtract, renderNodeInfo.isolatedOutExtract);
+                _.each(children, function (childNodeInfo) {
+                    // Set size of each child
+                    switch (childNodeInfo.node.type) {
+                        case graph_1.NodeType.OP:
+                            _.extend(childNodeInfo, layout.PARAMS.nodeSize.op);
+                            break;
+                        case graph_1.NodeType.BRIDGE:
+                            _.extend(childNodeInfo, layout.PARAMS.nodeSize.bridge);
+                            break;
+                        case graph_1.NodeType.META:
+                            if (!childNodeInfo.expanded) {
+                                // Set fixed width and scalable height based on cardinality
+                                _.extend(childNodeInfo, layout.PARAMS.nodeSize.meta);
+                                childNodeInfo.height =
+                                    layout.PARAMS.nodeSize.meta.height(childNodeInfo.node.cardinality);
+                            }
+                            else {
+                                var childGroupNodeInfo = childNodeInfo;
+                                layoutScene(childGroupNodeInfo); // Recursively layout its subscene.
+                            }
+                            break;
+                        case graph_1.NodeType.SERIES:
+                            if (childNodeInfo.expanded) {
+                                _.extend(childNodeInfo, layout.PARAMS.nodeSize.series.expanded);
+                                var childGroupNodeInfo = childNodeInfo;
+                                layoutScene(childGroupNodeInfo); // Recursively layout its subscene.
+                            }
+                            else {
+                                var childGroupNodeInfo = childNodeInfo;
+                                var seriesParams = childGroupNodeInfo.node.hasNonControlEdges ?
+                                    layout.PARAMS.nodeSize.series.vertical :
+                                    layout.PARAMS.nodeSize.series.horizontal;
+                                _.extend(childNodeInfo, seriesParams);
+                            }
+                            break;
+                        default:
+                            throw Error('Unrecognized node type: ' + childNodeInfo.node.type);
+                    }
+                    // Compute total width of un-expanded nodes. Width of expanded nodes
+                    // has already been computed.
+                    if (!childNodeInfo.expanded) {
+                        updateTotalWidthOfNode(childNodeInfo);
+                    }
+                    // Layout each child's annotations
+                    layoutAnnotation(childNodeInfo);
+                });
+            }
+            /**
+             * Calculate layout for a graph using dagre
+             * @param graph the graph to be laid out
+             * @param params layout parameters
+             * @return width and height of the core graph
+             */
+            function dagreLayout(graph, params) {
+                _.extend(graph.graph(), {
+                    nodesep: params.nodeSep,
+                    ranksep: params.rankSep,
+                    edgesep: params.edgeSep
+                });
+                var bridgeNodeNames = [];
+                var nonBridgeNodeNames = [];
+                // Split out nodes into bridge and non-bridge nodes, and calculate the total
+                // width we should use for bridge nodes.
+                _.each(graph.nodes(), function (nodeName) {
+                    var nodeInfo = graph.node(nodeName);
+                    if (nodeInfo.node.type === graph_1.NodeType.BRIDGE) {
+                        bridgeNodeNames.push(nodeName);
+                    }
+                    else {
+                        nonBridgeNodeNames.push(nodeName);
+                    }
+                });
+                // If there are no non-bridge nodes, then the graph has zero size.
+                if (!nonBridgeNodeNames.length) {
+                    return {
+                        width: 0,
+                        height: 0,
+                    };
+                }
+                dagre.layout(graph);
+                // Calculate the true bounding box of the graph by iterating over nodes and
+                // edges rather than accepting dagre's word for it. In particular, we should
+                // ignore the extra-wide bridge nodes and bridge edges, and allow for
+                // annotation boxes and labels.
+                var minX = Infinity;
+                var minY = Infinity;
+                var maxX = -Infinity;
+                var maxY = -Infinity;
+                _.each(nonBridgeNodeNames, function (nodeName) {
+                    var nodeInfo = graph.node(nodeName);
+                    var w = 0.5 * nodeInfo.width;
+                    var x1 = nodeInfo.x - w;
+                    var x2 = nodeInfo.x + w;
+                    minX = x1 < minX ? x1 : minX;
+                    maxX = x2 > maxX ? x2 : maxX;
+                    // TODO(jimbo): Account for the height of labels above op nodes here.
+                    var h = 0.5 * nodeInfo.height;
+                    var y1 = nodeInfo.y - h;
+                    var y2 = nodeInfo.y + h;
+                    minY = y1 < minY ? y1 : minY;
+                    maxY = y2 > maxY ? y2 : maxY;
+                });
+                _.each(graph.edges(), function (edgeObj) {
+                    var edgeInfo = graph.edge(edgeObj);
+                    if (edgeInfo.structural) {
+                        return; // Skip structural edges from min/max calculations.
+                    }
+                    // Since the node size passed to dagre includes the in and out
+                    // annotations, the endpoints of the edge produced by dagre may not
+                    // point to the actual node shape (rectangle, ellipse). We correct the
+                    // end-points by finding the intersection of a line between the
+                    // next-to-last (next-to-first) point and the destination (source)
+                    // rectangle.
+                    var sourceNode = graph.node(edgeInfo.metaedge.v);
+                    var destNode = graph.node(edgeInfo.metaedge.w);
+                    // Straight 3-points edges are special case, since they are curved after
+                    // our default correction. To keep them straight, we remove the mid point
+                    // and correct the first and the last point to be the center of the
+                    // source and destination node respectively.
+                    if (edgeInfo.points.length === 3 && isStraightLine(edgeInfo.points)) {
+                        if (sourceNode != null) {
+                            var cxSource = sourceNode.expanded ?
+                                sourceNode.x : computeCXPositionOfNodeShape(sourceNode);
+                            edgeInfo.points[0].x = cxSource;
+                        }
+                        if (destNode != null) {
+                            var cxDest = destNode.expanded ?
+                                destNode.x : computeCXPositionOfNodeShape(destNode);
+                            edgeInfo.points[2].x = cxDest;
+                        }
+                        // Remove the middle point so the edge doesn't curve.
+                        edgeInfo.points = [edgeInfo.points[0], edgeInfo.points[1]];
+                    }
+                    // Correct the destination endpoint of the edge.
+                    var nextToLastPoint = edgeInfo.points[edgeInfo.points.length - 2];
+                    // The destination node might be null if this is a bridge edge.
+                    if (destNode != null) {
+                        edgeInfo.points[edgeInfo.points.length - 1] =
+                            intersectPointAndNode(nextToLastPoint, destNode);
+                    }
+                    // Correct the source endpoint of the edge.
+                    var secondPoint = edgeInfo.points[1];
+                    // The source might be null if this is a bridge edge.
+                    if (sourceNode != null) {
+                        edgeInfo.points[0] = intersectPointAndNode(secondPoint, sourceNode);
+                    }
+                    _.each(edgeInfo.points, function (point) {
+                        minX = point.x < minX ? point.x : minX;
+                        maxX = point.x > maxX ? point.x : maxX;
+                        minY = point.y < minY ? point.y : minY;
+                        maxY = point.y > maxY ? point.y : maxY;
+                    });
+                });
+                // Shift all nodes and edge points to account for the left-padding amount,
+                // and the invisible bridge nodes.
+                _.each(graph.nodes(), function (nodeName) {
+                    var nodeInfo = graph.node(nodeName);
+                    nodeInfo.x -= minX;
+                    nodeInfo.y -= minY;
+                });
+                _.each(graph.edges(), function (edgeObj) {
+                    _.each(graph.edge(edgeObj).points, function (point) {
+                        point.x -= minX;
+                        point.y -= minY;
+                    });
+                });
+                return {
+                    width: maxX - minX,
+                    height: maxY - minY
+                };
+            }
+            /** Layout a metanode. Only called for an expanded node. */
+            function layoutMetanode(renderNodeInfo) {
+                // First, copy params specific to meta nodes onto this render info object.
+                var params = layout.PARAMS.subscene.meta;
+                _.extend(renderNodeInfo, params);
+                // Invoke dagre.layout() on the core graph and record the bounding box
+                // dimensions.
+                _.extend(renderNodeInfo.coreBox, dagreLayout(renderNodeInfo.coreGraph, layout.PARAMS.graph.meta));
+                // Calculate the position of nodes in isolatedInExtract relative to the
+                // top-left corner of inExtractBox (the bounding box for all inExtract nodes)
+                // and calculate the size of the inExtractBox.
+                var maxInExtractWidth = _.max(renderNodeInfo.isolatedInExtract, function (renderNode) { return renderNode.width; }).width;
+                renderNodeInfo.inExtractBox.width = maxInExtractWidth != null ?
+                    maxInExtractWidth : 0;
+                renderNodeInfo.inExtractBox.height =
+                    _.reduce(renderNodeInfo.isolatedInExtract, function (height, child, i) {
+                        var yOffset = i > 0 ? params.extractYOffset : 0;
+                        // use width/height here to avoid overlaps between extracts
+                        child.x = 0;
+                        child.y = height + yOffset + child.height / 2;
+                        return height + yOffset + child.height;
+                    }, 0);
+                // Calculate the position of nodes in isolatedOutExtract relative to the
+                // top-left corner of outExtractBox (the bounding box for all outExtract
+                // nodes) and calculate the size of the outExtractBox.
+                var maxOutExtractWidth = _.max(renderNodeInfo.isolatedOutExtract, function (renderNode) { return renderNode.width; }).width;
+                renderNodeInfo.outExtractBox.width = maxOutExtractWidth != null ?
+                    maxOutExtractWidth : 0;
+                renderNodeInfo.outExtractBox.height =
+                    _.reduce(renderNodeInfo.isolatedOutExtract, function (height, child, i) {
+                        var yOffset = i > 0 ? params.extractYOffset : 0;
+                        // use width/height here to avoid overlaps between extracts
+                        child.x = 0;
+                        child.y = height + yOffset + child.height / 2;
+                        return height + yOffset + child.height;
+                    }, 0);
+                // Compute the total padding between the core graph, in-extract and
+                // out-extract boxes.
+                var numParts = 0;
+                if (renderNodeInfo.isolatedInExtract.length > 0) {
+                    numParts++;
+                }
+                if (renderNodeInfo.isolatedOutExtract.length > 0) {
+                    numParts++;
+                }
+                if (renderNodeInfo.coreGraph.nodeCount() > 0) {
+                    numParts++;
+                }
+                var offset = layout.PARAMS.subscene.meta.extractXOffset;
+                var padding = numParts <= 1 ? 0 : (numParts <= 2 ? offset : 2 * offset);
+                // Add the in-extract and out-extract width to the core box width.
+                renderNodeInfo.coreBox.width += renderNodeInfo.inExtractBox.width +
+                    renderNodeInfo.outExtractBox.width + padding;
+                renderNodeInfo.coreBox.height =
+                    params.labelHeight +
+                        Math.max(renderNodeInfo.inExtractBox.height, renderNodeInfo.coreBox.height, renderNodeInfo.outExtractBox.height);
+                // Determine the whole metanode's width (from left to right).
+                renderNodeInfo.width = renderNodeInfo.coreBox.width +
+                    params.paddingLeft + params.paddingRight;
+                // Determine the whole metanode's height (from top to bottom).
+                renderNodeInfo.height =
+                    renderNodeInfo.paddingTop +
+                        renderNodeInfo.coreBox.height +
+                        renderNodeInfo.paddingBottom;
+            }
+            /**
+             * Calculate layout for series node's core graph. Only called for an expanded
+             * series.
+             */
+            function layoutSeriesNode(node) {
+                var graph = node.coreGraph;
+                var params = layout.PARAMS.subscene.series;
+                _.extend(node, params);
+                // Layout the core.
+                _.extend(node.coreBox, dagreLayout(node.coreGraph, layout.PARAMS.graph.series));
+                _.each(graph.nodes(), function (nodeName) {
+                    graph.node(nodeName).excluded = false;
+                });
+                // Series do not have in/outExtractBox so no need to include them here.
+                node.width = node.coreBox.width + params.paddingLeft + params.paddingRight;
+                node.height = node.coreBox.height + params.paddingTop + params.paddingBottom;
+            }
+            /**
+             * Calculate layout for annotations of a given node.
+             * This will modify positions of the given node and its annotations.
+             *
+             * @see tf.graph.render.Node and tf.graph.render.Annotation
+             * for description of each property of each render node.
+             *
+             */
+            function layoutAnnotation(renderNodeInfo) {
+                // If the render node is an expanded metanode, then its annotations will not
+                // be visible and we should skip the annotation calculations.
+                if (renderNodeInfo.expanded) {
+                    return;
+                }
+                var inAnnotations = renderNodeInfo.inAnnotations.list;
+                var outAnnotations = renderNodeInfo.outAnnotations.list;
+                // Calculate size for in-annotations
+                _.each(inAnnotations, function (a) { return sizeAnnotation(a); });
+                // Calculate size for out-annotations
+                _.each(outAnnotations, function (a) { return sizeAnnotation(a); });
+                var params = layout.PARAMS.annotations;
+                // Calculate annotation node position (a.dx, a.dy)
+                // and total height for in-annotations
+                // After this chunk of code:
+                // inboxHeight = sum of annotation heights+ (annotation.length - 1 * yOffset)
+                var inboxHeight = _.reduce(inAnnotations, function (height, a, i) {
+                    var yOffset = i > 0 ? params.yOffset : 0;
+                    a.dx = -(renderNodeInfo.coreBox.width + a.width) / 2 - params.xOffset;
+                    a.dy = height + yOffset + a.height / 2;
+                    return height + yOffset + a.height;
+                }, 0);
+                _.each(inAnnotations, function (a) {
+                    a.dy -= inboxHeight / 2;
+                    a.labelOffset = params.labelOffset;
+                });
+                // Calculate annotation node position (a.dx, a.dy)
+                // and total height for out-annotations
+                // After this chunk of code:
+                // outboxHeight = sum of annotation heights +
+                //                (annotation.length - 1 * yOffset)
+                var outboxHeight = _.reduce(outAnnotations, function (height, a, i) {
+                    var yOffset = i > 0 ? params.yOffset : 0;
+                    a.dx = (renderNodeInfo.coreBox.width + a.width) / 2 + params.xOffset;
+                    a.dy = height + yOffset + a.height / 2;
+                    return height + yOffset + a.height;
+                }, 0);
+                _.each(outAnnotations, function (a) {
+                    // adjust by (half of ) the total height
+                    // so dy is relative to the host node's center.
+                    a.dy -= outboxHeight / 2;
+                    a.labelOffset = params.labelOffset;
+                });
+                // Creating scales for touch point between the in-annotation edges
+                // and their hosts.
+                var inTouchHeight = Math.min(renderNodeInfo.height / 2 - renderNodeInfo.radius, inboxHeight / 2);
+                inTouchHeight = inTouchHeight < 0 ? 0 : inTouchHeight;
+                var inY = d3.scale.linear()
+                    .domain([0, inAnnotations.length - 1])
+                    .range([-inTouchHeight, inTouchHeight]);
+                // Calculate annotation edge position
+                _.each(inAnnotations, function (a, i) {
+                    a.points = [
+                        // The annotation node end
+                        {
+                            dx: a.dx + a.width / 2,
+                            dy: a.dy
+                        },
+                        // The host node end
+                        {
+                            dx: -renderNodeInfo.coreBox.width / 2,
+                            // only use scale if there are more than one,
+                            // otherwise center it vertically
+                            dy: inAnnotations.length > 1 ? inY(i) : 0
+                        }
+                    ];
+                });
+                // Creating scales for touch point between the out-annotation edges
+                // and their hosts.
+                var outTouchHeight = Math.min(renderNodeInfo.height / 2 - renderNodeInfo.radius, outboxHeight / 2);
+                outTouchHeight = outTouchHeight < 0 ? 0 : outTouchHeight;
+                var outY = d3.scale.linear()
+                    .domain([0, outAnnotations.length - 1])
+                    .range([-outTouchHeight, outTouchHeight]);
+                _.each(outAnnotations, function (a, i) {
+                    // Add point from the border of the annotation node
+                    a.points = [
+                        // The host node end
+                        {
+                            dx: renderNodeInfo.coreBox.width / 2,
+                            // only use scale if there are more than one,
+                            // otherwise center it vertically
+                            dy: outAnnotations.length > 1 ? outY(i) : 0
+                        },
+                        // The annotation node end
+                        {
+                            dx: a.dx - a.width / 2,
+                            dy: a.dy
+                        }
+                    ];
+                });
+                renderNodeInfo.height =
+                    Math.max(renderNodeInfo.height, inboxHeight, outboxHeight);
+            }
+            /**
+             * Set size of an annotation node.
+             */
+            function sizeAnnotation(a) {
+                switch (a.annotationType) {
+                    case graph_1.render.AnnotationType.CONSTANT:
+                        _.extend(a, layout.PARAMS.constant.size);
+                        break;
+                    case graph_1.render.AnnotationType.SHORTCUT:
+                        if (a.node.type === graph_1.NodeType.OP) {
+                            _.extend(a, layout.PARAMS.shortcutSize.op);
+                        }
+                        else if (a.node.type === graph_1.NodeType.META) {
+                            _.extend(a, layout.PARAMS.shortcutSize.meta);
+                        }
+                        else if (a.node.type === graph_1.NodeType.SERIES) {
+                            _.extend(a, layout.PARAMS.shortcutSize.series);
+                        }
+                        else {
+                            throw Error('Invalid node type: ' + a.node.type);
+                        }
+                        break;
+                    case graph_1.render.AnnotationType.SUMMARY:
+                        _.extend(a, layout.PARAMS.constant.size);
+                        break;
+                }
+            }
+            /**
+             * Determines the center position of the node's shape. The position depends
+             * on if the node has in and out-annotations.
+             */
+            function computeCXPositionOfNodeShape(renderInfo) {
+                if (renderInfo.expanded) {
+                    return renderInfo.x;
+                }
+                var dx = renderInfo.inAnnotations.list.length ? renderInfo.inboxWidth : 0;
+                return renderInfo.x - renderInfo.width / 2 + dx +
+                    renderInfo.coreBox.width / 2;
+            }
+            layout.computeCXPositionOfNodeShape = computeCXPositionOfNodeShape;
+            /** Returns the angle (in degrees) between two points. */
+            function angleBetweenTwoPoints(a, b) {
+                var dx = b.x - a.x;
+                var dy = b.y - a.y;
+                return 180 * Math.atan(dy / dx) / Math.PI;
+            }
+            /**
+             * Returns if a line going through the specified points is a straight line.
+             */
+            function isStraightLine(points) {
+                var angle = angleBetweenTwoPoints(points[0], points[1]);
+                for (var i = 1; i < points.length - 1; i++) {
+                    var newAngle = angleBetweenTwoPoints(points[i], points[i + 1]);
+                    // Have a tolerance of 1 degree.
+                    if (Math.abs(newAngle - angle) > 1) {
+                        return false;
+                    }
+                    angle = newAngle;
+                }
+                return true;
+            }
+            /**
+             * Returns the intersection of a line between the provided point
+             * and the provided rectangle.
+             */
+            function intersectPointAndNode(point, node) {
+                // cx and cy are the center of the rectangle.
+                var cx = node.expanded ?
+                    node.x : computeCXPositionOfNodeShape(node);
+                var cy = node.y;
+                // Calculate the slope
+                var dx = point.x - cx;
+                var dy = point.y - cy;
+                var w = node.expanded ? node.width : node.coreBox.width;
+                var h = node.expanded ? node.height : node.coreBox.height;
+                var deltaX, deltaY;
+                if (Math.abs(dy) * w / 2 > Math.abs(dx) * h / 2) {
+                    // The intersection is above or below the rectangle.
+                    if (dy < 0) {
+                        h = -h;
+                    }
+                    deltaX = dy === 0 ? 0 : h / 2 * dx / dy;
+                    deltaY = h / 2;
+                }
+                else {
+                    // The intersection is left or right of the rectangle.
+                    if (dx < 0) {
+                        w = -w;
+                    }
+                    deltaX = w / 2;
+                    deltaY = dx === 0 ? 0 : w / 2 * dy / dx;
+                }
+                return { x: cx + deltaX, y: cy + deltaY };
+            }
+        })(layout = graph_1.layout || (graph_1.layout = {}));
+    })(graph = tf.graph || (tf.graph = {}));
+})(tf || (tf = {})); // close module
+</script>
+<script>/* Copyright 2015 Google Inc. All Rights Reserved.
+
+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.
+==============================================================================*/
+var tf;
+(function (tf) {
+    var graph;
+    (function (graph) {
+        var parser;
+        (function (parser) {
+            /**
+             * Parses a native js value, which can be either a string, boolean or number.
+             *
+             * @param value The value to be parsed.
+             */
+            function parseValue(value) {
+                if (value === 'true') {
+                    return true;
+                }
+                if (value === 'false') {
+                    return false;
+                }
+                var firstChar = value[0];
+                if (firstChar === '"') {
+                    return value.substring(1, value.length - 1);
+                }
+                var num = parseFloat(value);
+                return isNaN(num) ? value : num;
+            }
+            /**
+             * Fetches a text file and returns a promise of the result.
+             */
+            function fetchPbTxt(filepath) {
+                return new Promise(function (resolve, reject) {
+                    d3.text(filepath, function (error, text) {
+                        if (error) {
+                            reject(error);
+                            return;
+                        }
+                        resolve(text);
+                    });
+                });
+            }
+            parser.fetchPbTxt = fetchPbTxt;
+            /**
+             * Fetches the metadata file, parses it and returns a promise of the result.
+             */
+            function fetchAndParseMetadata(path, tracker) {
+                return tf.graph.util
+                    .runTask('Reading metadata pbtxt', 40, function () {
+                    if (path == null) {
+                        return Promise.resolve(null);
+                    }
+                    return fetchPbTxt(path).then(function (text) { return new Blob([text]); });
+                }, tracker)
+                    .then(function (blob) {
+                    return tf.graph.util.runTask('Parsing metadata.pbtxt', 60, function () {
+                        return blob != null ? parseStatsPbTxt(blob) : null;
+                    }, tracker);
+                });
+            }
+            parser.fetchAndParseMetadata = fetchAndParseMetadata;
+            /**
+             * Fetches the graph file, parses it and returns a promise of the result.
+             */
+            function fetchAndParseGraphData(path, pbTxtFile, tracker) {
+                return tf.graph.util
+                    .runTask('Reading graph pbtxt', 40, function () {
+                    return pbTxtFile ? Promise.resolve(pbTxtFile) :
+                        fetchPbTxt(path).then(function (text) { return new Blob([text]); });
+                }, tracker)
+                    .then(function (blob) {
+                    return tf.graph.util.runTask('Parsing graph.pbtxt', 60, function () {
+                        return parseGraphPbTxt(blob);
+                    }, tracker);
+                });
+            }
+            parser.fetchAndParseGraphData = fetchAndParseGraphData;
+            /**
+             * Parse a file object in a streaming fashion line by line (or custom delim).
+             * Can handle very large files.
+             * @param input The file object
+             * @param callback The callback called on each line
+             * @param chunkSize The size of each read chunk. (optional)
+             * @param delim The delimiter used to split a line. (optional)
+             * @returns A promise for when it is finished.
+             */
+            function streamParse(file, callback, chunkSize, delim) {
+                if (chunkSize === void 0) { chunkSize = 1000000; }
+                if (delim === void 0) { delim = '\n'; }
+                return new Promise(function (resolve, reject) {
+                    var offset = 0;
+                    var fileSize = file.size - 1;
+                    var data = '';
+                    function readHandler(evt) {
+                        if (evt.target.error == null) {
+                            offset += evt.target.result.length;
+                            var str = evt.target.result;
+                            var parts = str.split(delim);
+                            var first = data + parts[0];
+                            if (parts.length === 1) {
+                                data = first;
+                                readChunk(offset, chunkSize);
+                                return;
+                            }
+                            data = parts[parts.length - 1];
+                            callback(first);
+                            for (var i = 1; i < parts.length - 1; i++) {
+                                callback(parts[i]);
+                            }
+                        }
+                        else {
+                            // read error
+                            reject(evt.target.error);
+                            return;
+                        }
+                        if (offset >= fileSize) {
+                            if (data) {
+                                callback(data);
+                            }
+                            resolve(true);
+                            return;
+                        }
+                        readChunk(offset, chunkSize);
+                    }
+                    function readChunk(offset, size) {
+                        var reader = new FileReader();
+                        var blob = file.slice(offset, offset + size);
+                        reader.onload = readHandler;
+                        reader.readAsText(blob);
+                    }
+                    readChunk(offset, chunkSize);
+                });
+            }
+            parser.streamParse = streamParse;
+            /**
+             * Since proto-txt doesn't explicitly say whether an attribute is repeated
+             * (an array) or not, we keep a hard-coded list of attributes that are known
+             * to be repeated. This list is used in parsing time to convert repeated
+             * attributes into arrays even when the attribute only shows up once in the
+             * object.
+             */
+            var GRAPH_REPEATED_FIELDS = {
+                'node': true,
+                'node.input': true,
+                'node.attr': true,
+                'node.attr.value.list.type': true,
+                'node.attr.value.shape.dim': true,
+                'node.attr.value.tensor.string_val': true,
+                'node.attr.value.tensor.tensor_shape.dim': true,
+                'node.attr.value.list.shape': true,
+                'node.attr.value.list.shape.dim': true,
+                'node.attr.value.list.s': true
+            };
+            var METADATA_REPEATED_FIELDS = {
+                'step_stats.dev_stats': true,
+                'step_stats.dev_stats.node_stats': true,
+                'step_stats.dev_stats.node_stats.output': true,
+                'step_stats.dev_stats.node_stats.memory': true,
+                'step_stats.dev_stats.node_stats.output.tensor_description.shape.dim': true
+            };
+            /**
+             * Parses a blob of proto txt file into a raw Graph object.
+             */
+            function parseGraphPbTxt(input) {
+                return parsePbtxtFile(input, GRAPH_REPEATED_FIELDS).then(function (obj) { return obj['node']; });
+            }
+            parser.parseGraphPbTxt = parseGraphPbTxt;
+            /**
+             * Parses a blob of proto txt file into a StepStats object.
+             */
+            function parseStatsPbTxt(input) {
+                return parsePbtxtFile(input, METADATA_REPEATED_FIELDS)
+                    .then(function (obj) { return obj['step_stats']; });
+            }
+            /**
+             * Parses a blob of proto txt file into javascript object.
+             *
+             * @param input The Blob or file object implementing slice.
+             * @param repeatedFields Map (Set) of all the repeated fields, since you can't
+             *   tell directly from the pbtxt if a field is repeated or not.
+             * @returns The parsed object.
+             */
+            function parsePbtxtFile(input, repeatedFields) {
+                var output = {};
+                var stack = [];
+                var path = [];
+                var current = output;
+                function splitNameAndValueInAttribute(line) {
+                    var colonIndex = line.indexOf(':');
+                    var name = line.substring(0, colonIndex).trim();
+                    var value = parseValue(line.substring(colonIndex + 2).trim());
+                    return {
+                        name: name,
+                        value: value
+                    };
+                }
+                /**
+                 * Adds a value, given the attribute name and the host object. If the
+                 * attribute already exists, but is not an array, it will convert it to an
+                 * array of values.
+                 *
+                 * @param obj The host object that holds the attribute.
+                 * @param name The attribute name (key).
+                 * @param value The attribute value.
+                 * @param path A path that identifies the attribute. Used to check if
+                 *     an attribute is an array or not.
+                 */
+                function addAttribute(obj, name, value, path) {
+                    // We treat 'node' specially since it is done so often.
+                    var existingValue = obj[name];
+                    if (existingValue == null) {
+                        obj[name] = path.join('.') in repeatedFields ? [value] : value;
+                    }
+                    else if (Array.isArray(existingValue)) {
+                        existingValue.push(value);
+                    }
+                    else {
+                        obj[name] = [existingValue, value];
+                    }
+                }
+                // Run through the file a line at a time.
+                return streamParse(input, function (line) {
+                    if (!line) {
+                        return;
+                    }
+                    switch (line[line.length - 1]) {
+                        case '{':
+                            var name_1 = line.substring(0, line.length - 2).trim();
+                            var newValue = {};
+                            stack.push(current);
+                            path.push(name_1);
+                            addAttribute(current, name_1, newValue, path);
+                            current = newValue;
+                            break;
+                        case '}':
+                            current = stack.pop();
+                            path.pop();
+                            break;
+                        default:
+                            var x = splitNameAndValueInAttribute(line);
+                            addAttribute(current, x.name, x.value, path.concat(x.name));
+                            break;
+                    }
+                }).then(function () {
+                    return output;
+                });
+            }
+        })(parser = graph.parser || (graph.parser = {}));
+    })(graph = tf.graph || (tf.graph = {}));
+})(tf || (tf = {})); // Close module tf.graph.parser.
+</script>
 <script>var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
     function __() { this.constructor = d; }
@@ -5030,14 +6035,14 @@
 };
 /* Copyright 2015 Google Inc. All Rights Reserved.
 
-Licensed under the Apache License, Version 2.0 (the "License");
+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,
+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.
@@ -5054,10 +6059,7 @@
             /**
              * Color parameters for op nodes.
              */
-            render.OpNodeColors = {
-                DEFAULT_FILL: "white",
-                DEFAULT_STROKE: "#b2b2b2"
-            };
+            render.OpNodeColors = { DEFAULT_FILL: 'white', DEFAULT_STROKE: '#b2b2b2' };
             /**
              * Color parameters for node encoding.
              * @type {Object}
@@ -5066,15 +6068,15 @@
                 /**
                  * Default fill and stroke to use when no other information is available.
                  */
-                DEFAULT_FILL: "#d9d9d9",
-                DEFAULT_STROKE: "#a6a6a6",
+                DEFAULT_FILL: '#d9d9d9',
+                DEFAULT_STROKE: '#a6a6a6',
                 SATURATION: 0.6,
                 LIGHTNESS: 0.85,
                 /**
                  * Neutral color to use when the node is expanded (used when coloring by
                  * compute time, memory and device).
                  */
-                EXPANDED_COLOR: "#f0f0f0",
+                EXPANDED_COLOR: '#f0f0f0',
                 /**
                  * Standard hue values for node color palette.
                  */
@@ -5090,18 +6092,16 @@
                     var light = lightened ? 95 : 80;
                     return d3.hsl(hue, .01 * sat, .01 * light).toString();
                 },
-                DEVICE_PALETTE: function (index) {
-                    return render.MetanodeColors.STRUCTURE_PALETTE(index);
-                },
-                UNKNOWN: "#eee",
-                GRADIENT_OUTLINE: "#888"
+                DEVICE_PALETTE: function (index) { return render.MetanodeColors.STRUCTURE_PALETTE(index); },
+                UNKNOWN: '#eee',
+                GRADIENT_OUTLINE: '#888'
             };
             /**
              * Color parameters for op nodes.
              */
             render.SeriesNodeColors = {
-                DEFAULT_FILL: "white",
-                DEFAULT_STROKE: "#b2b2b2"
+                DEFAULT_FILL: 'white',
+                DEFAULT_STROKE: '#b2b2b2'
             };
             /**
              * Parameters that affect how the graph is rendered on the screen.
@@ -5131,15 +6131,13 @@
                  * sink-like nodes that will be extracted from the main graph.
                  */
                 outExtractTypes: [
-                    "NoOp" // NoOps are sink-like used for managing control dependencies.
+                    'NoOp' // NoOps are sink-like used for managing control dependencies.
                 ],
                 /**
                  * Types patterns for predefined in-extract nodes, which are
                  * source-like nodes that will be extracted from the main graph.
                  */
-                inExtractTypes: [
-                    "Variable"
-                ],
+                inExtractTypes: ['Variable'],
                 /**
                  * When removing edges from a high degree node, remove all of its edges if
                  * detachAllEdgesForHighDegree is true.  Otherwise remove all in-edges if
@@ -5162,7 +6160,7 @@
                  * 2 colors, for the minimum and maximum value respectively, whenever we
                  * have a gradient scale.
                  */
-                minMaxColors: ["#fff5f0", "#fb6a4a"],
+                minMaxColors: ['#fff5f0', '#fb6a4a'],
                 /**
                  * Maximum number of annotations to be displayed on a node before an
                  * ellipsis is used.
@@ -5386,7 +6384,7 @@
                         for (var _i = 1; _i < arguments.length; _i++) {
                             rest[_i - 1] = arguments[_i];
                         }
-                        return rest.concat([inbound ? "IN" : "OUT"]).join("~~");
+                        return rest.concat([inbound ? 'IN' : 'OUT']).join('~~');
                     };
                     // Build out the bridgegraph.
                     var bridgegraph = this.hierarchy.getBridgegraph(nodeName);
@@ -5473,7 +6471,7 @@
                             canDrawBridgePath = !!adjoiningMetaedge;
                         }
                         // Although dataflow edges are acyclic, control dependency edges may
-                        // actually point "backwards" in the graph. If this bridgeMetaedge is
+                        // actually point 'backwards' in the graph. If this bridgeMetaedge is
                         // a control dependency, we need to determine whether it's backwards
                         // pointing so that we render it appropriately.
                         //
@@ -5668,7 +6666,7 @@
                             // set a metaedge between the terminal node and the container node, but
                             // in that case, something about the graph upsets dagre.layout()'s
                             // longestPath algorithm (was getting errors due to an undefined).
-                            var structuralNodeName = getBridgeNodeName(inbound, nodeName, "STRUCTURAL_TARGET");
+                            var structuralNodeName = getBridgeNodeName(inbound, nodeName, 'STRUCTURAL_TARGET');
                             var structuralRenderInfo = coreGraph.node(structuralNodeName);
                             if (!structuralRenderInfo) {
                                 var bridgeNode = {
@@ -6119,7 +7117,7 @@
              *
              * For root node, consider predefined types for source and sink.
              * We do not extract predefined type from non-root so that Variables and the
-             * sgd node (op type = "NoOp") do not get extract from inside own group.
+             * sgd node (op type = 'NoOp') do not get extract from inside own group.
              *
              * The order of extraction is important here as swapping the order can totally
              * screw up the graph layout.
@@ -6207,691 +7205,14 @@
 </script>
 <script>/* Copyright 2015 Google Inc. All Rights Reserved.
 
-Licensed under the Apache License, Version 2.0 (the "License");
+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.
-==============================================================================*/
-var tf;
-(function (tf) {
-    var graph;
-    (function (graph_1) {
-        var template;
-        (function (template) {
-            /**
-             * Detect repeating patterns of subgraphs.
-             * Assign templateId to each subgraph if it belongs to a template.
-             * Returns clusters of similar subgraphs .
-             *
-             * @param graph
-             * @param verifyTemplate whether to run the template verification algorithm
-             * @return a dict (template id => Array of node names)
-             */
-            function detect(h, verifyTemplate) {
-                // In any particular subgraph, there are either
-                // - leaf nodes (which do not have subgraph)
-                // - metanode nodes - some of them have only one member (singular metanode)
-                //                    and some have multiple members (non-singular metanode)
-                // First, generate a nearest neighbor hash of metanode nodes.
-                var nnGroups = clusterSimilarSubgraphs(h);
-                // For each metanode, compare its subgraph (starting from shallower groups)
-                // and assign template id.
-                var templates = groupTemplateAndAssignId(nnGroups, verifyTemplate);
-                // Sort the templates by minimum level in the graph at which they appear,
-                // as this leads to optimal setting of the colors of each template for
-                // maximum differentiation.
-                return _(templates).pairs()
-                    .sortBy(function (pair) {
-                    return pair[1].level;
-                })
-                    .map(function (pair) {
-                    return [pair[0], pair[1].nodes];
-                })
-                    .object().value();
-            }
-            template.detect = detect;
-            ;
-            /**
-             * @return Unique string for a metanode based on depth, |V|, |E| and
-             * op type histogram.
-             */
-            function getSignature(metanode) {
-                // depth=<number> |V|=<number> |E|=<number>
-                var props = _.map({
-                    "depth": metanode.depth,
-                    "|V|": metanode.metagraph.nodes().length,
-                    "|E|": metanode.metagraph.edges().length
-                }, function (v, k) { return k + "=" + v; }).join(" ");
-                // optype1=count1,optype2=count2
-                var ops = _.map(metanode.opHistogram, function (count, op) {
-                    return op + "=" + count;
-                }).join(",");
-                return props + " [ops] " + ops;
-            }
-            /**
-             * Generate a nearest neighbor hash of metanodes
-             * based on depth, |V|, |E|, and opHistogram of their subgraph
-             * (excluding leaf nodes and singular metanodes).
-             * @param graph The graph
-             * @return Array of pairs of [signature,
-             *   Object with min level of the template and an Array of tf.graph.Group]
-             *   sort by ascending order of minimum depth at which metanode appears.
-             */
-            function clusterSimilarSubgraphs(h) {
-                /** a dict from metanode.signature() => Array of tf.graph.Groups */
-                var hashDict = _(h.getNodeMap()).reduce(function (hash, node, name) {
-                    if (node.type !== graph_1.NodeType.META) {
-                        return hash;
-                    }
-                    var levelOfMetaNode = name.split("/").length - 1;
-                    var signature = getSignature(node);
-                    var templateInfo = hash[signature] ||
-                        { nodes: [], level: levelOfMetaNode };
-                    hash[signature] = templateInfo;
-                    templateInfo.nodes.push(node);
-                    if (templateInfo.level > levelOfMetaNode) {
-                        templateInfo.level = levelOfMetaNode;
-                    }
-                    return hash;
-                }, {});
-                return _(hashDict).pairs()
-                    .filter(function (pair) {
-                    return pair[1].nodes.length > 1;
-                })
-                    .sortBy(function (pair) {
-                    // sort by depth
-                    // (all members in the same nnGroup has equal depth)
-                    return pair[1].nodes[0].depth;
-                })
-                    .value();
-            }
-            function groupTemplateAndAssignId(nnGroups, verifyTemplate) {
-                // For each metanode, compare its subgraph (starting from shallower groups)
-                // and assign template id.
-                var result = {};
-                return _.reduce(nnGroups, function (templates, nnGroupPair) {
-                    var signature = nnGroupPair[0], nnGroup = nnGroupPair[1].nodes, clusters = [];
-                    nnGroup.forEach(function (metanode) {
-                        // check with each existing cluster
-                        for (var i = 0; i < clusters.length; i++) {
-                            var similar = !verifyTemplate ||
-                                isSimilarSubgraph(clusters[i].metanode.metagraph, metanode.metagraph);
-                            // if similar, just add this metanode to the cluster
-                            if (similar) {
-                                // get template from the first one
-                                metanode.templateId = clusters[i].metanode.templateId;
-                                clusters[i].members.push(metanode.name);
-                                return;
-                            }
-                        }
-                        // otherwise create a new cluster with id "signature [count] "
-                        metanode.templateId = signature + "[" + clusters.length + "]";
-                        clusters.push({
-                            metanode: metanode,
-                            members: [metanode.name]
-                        });
-                    });
-                    clusters.forEach(function (c) {
-                        templates[c.metanode.templateId] = {
-                            level: nnGroupPair[1].level,
-                            nodes: c.members
-                        };
-                    });
-                    return templates;
-                }, result);
-            }
-            function sortNodes(names, graph, prefix) {
-                return _.sortByAll(names, function (name) {
-                    var node = graph.node(name);
-                    return node.op;
-                }, function (name) {
-                    var node = graph.node(name);
-                    return node.templateId;
-                }, function (name) {
-                    return graph.neighbors(name).length;
-                }, function (name) {
-                    return graph.predecessors(name).length;
-                }, function (name) {
-                    return graph.successors(name).length;
-                }, function (name) {
-                    return name.substr(prefix.length);
-                });
-            }
-            function isSimilarSubgraph(g1, g2) {
-                if (!tf.graph.hasSimilarDegreeSequence(g1, g2)) {
-                    return false;
-                }
-                // if we want to skip, just return true here.
-                // return true;
-                // Verify sequence by running DFS
-                var g1prefix = g1.graph().name;
-                var g2prefix = g2.graph().name;
-                var visited1 = {};
-                var visited2 = {};
-                var stack = [];
-                /**
-                 * push sources or successors into the stack
-                 * if the visiting pattern has been similar.
-                 */
-                function stackPushIfNotDifferent(n1, n2) {
-                    var sub1 = n1.substr(g1prefix.length), sub2 = n2.substr(g2prefix.length);
-                    /* tslint:disable */
-                    if (visited1[sub1] ^ visited2[sub1]) {
-                        console.warn("different visit pattern", "[" + g1prefix + "]", sub1, "[" + g2prefix + "]", sub2);
-                        return true;
-                    }
-                    /* tslint:enable */
-                    if (!visited1[sub1]) {
-                        visited1[sub1] = visited2[sub2] = true;
-                        stack.push({ n1: n1, n2: n2 });
-                    }
-                    return false;
-                }
-                // check if have same # of sources then sort and push
-                var sources1 = g1.sources();
-                var sources2 = g2.sources();
-                if (sources1.length !== sources2.length) {
-                    /* tslint:disable */
-                    console.log("different source length");
-                    /* tslint:enable */
-                    return false;
-                }
-                sources1 = sortNodes(sources1, g1, g1prefix);
-                sources2 = sortNodes(sources2, g2, g2prefix);
-                for (var i = 0; i < sources1.length; i++) {
-                    var different = stackPushIfNotDifferent(sources1[i], sources2[i]);
-                    if (different) {
-                        return false;
-                    }
-                }
-                while (stack.length > 0) {
-                    var cur = stack.pop();
-                    // check node
-                    var similar = isSimilarNode(g1.node(cur.n1), g2.node(cur.n2));
-                    if (!similar) {
-                        return false;
-                    }
-                    // check if have same # of successors then sort and push
-                    var succ1 = g1.successors(cur.n1), succ2 = g2.successors(cur.n2);
-                    if (succ1.length !== succ2.length) {
-                        /* tslint:disable */
-                        console.log("# of successors mismatch", succ1, succ2);
-                        /* tslint:enable */
-                        return false;
-                    }
-                    succ1 = sortNodes(succ1, g1, g1prefix);
-                    succ2 = sortNodes(succ2, g2, g2prefix);
-                    for (var j = 0; j < succ1.length; j++) {
-                        var different = stackPushIfNotDifferent(succ1[j], succ2[j]);
-                        if (different) {
-                            return false;
-                        }
-                    }
-                }
-                return true;
-            }
-            /**
-             * Returns if two nodes have identical structure.
-             */
-            function isSimilarNode(n1, n2) {
-                if (n1.type === graph_1.NodeType.META) {
-                    // compare metanode
-                    var metanode1 = n1;
-                    var metanode2 = n2;
-                    return metanode1.templateId && metanode2.templateId &&
-                        metanode1.templateId === metanode2.templateId;
-                }
-                else if (n1.type === graph_1.NodeType.OP && n2.type === graph_1.NodeType.OP) {
-                    // compare leaf node
-                    return n1.op === n2.op;
-                }
-                else if (n1.type === graph_1.NodeType.SERIES && n2.type === graph_1.NodeType.SERIES) {
-                    // compare series node sizes and operations
-                    // (only need to check one op as all op nodes are identical in series)
-                    var sn1 = n1;
-                    var sn2 = n2;
-                    var seriesnode1Count = sn1.metagraph.nodeCount();
-                    return (seriesnode1Count === sn2.metagraph.nodeCount() &&
-                        (seriesnode1Count === 0 ||
-                            (sn1.metagraph.node(sn1.metagraph.nodes()[0]).op ===
-                                sn2.metagraph.node(sn2.metagraph.nodes()[0]).op)));
-                }
-                return false;
-            }
-        })(template = graph_1.template || (graph_1.template = {}));
-    })(graph = tf.graph || (tf.graph = {}));
-})(tf || (tf = {}));
-</script>
-<script>/* Copyright 2015 Google Inc. All Rights Reserved.
-
-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.
-==============================================================================*/
-var tf;
-(function (tf) {
-    var graph;
-    (function (graph) {
-        var scene;
-        (function (scene) {
-            /** Enums element class of objects in the scene */
-            scene.Class = {
-                Node: {
-                    // <g> element that contains nodes.
-                    CONTAINER: "nodes",
-                    // <g> element that contains detail about a node.
-                    GROUP: "node",
-                    // <g> element that contains visual elements (like rect, ellipse).
-                    SHAPE: "nodeshape",
-                    // <*> element(s) under SHAPE that should receive color updates.
-                    COLOR_TARGET: "nodecolortarget",
-                    // <text> element showing the node's label.
-                    LABEL: "nodelabel",
-                    // <g> element that contains all visuals for the expand/collapse
-                    // button for expandable group nodes.
-                    BUTTON_CONTAINER: "buttoncontainer",
-                    // <circle> element that surrounds expand/collapse buttons.
-                    BUTTON_CIRCLE: "buttoncircle",
-                    // <path> element of the expand button.
-                    EXPAND_BUTTON: "expandbutton",
-                    // <path> element of the collapse button.
-                    COLLAPSE_BUTTON: "collapsebutton"
-                },
-                Edge: {
-                    CONTAINER: "edges",
-                    GROUP: "edge",
-                    LINE: "edgeline",
-                    REF_LINE: "refline",
-                    STRUCTURAL: "structural"
-                },
-                Annotation: {
-                    OUTBOX: "out-annotations",
-                    INBOX: "in-annotations",
-                    GROUP: "annotation",
-                    NODE: "annotation-node",
-                    EDGE: "annotation-edge",
-                    CONTROL_EDGE: "annotation-control-edge",
-                    LABEL: "annotation-label",
-                    ELLIPSIS: "annotation-ellipsis"
-                },
-                Scene: {
-                    GROUP: "scene",
-                    CORE: "core",
-                    INEXTRACT: "in-extract",
-                    OUTEXTRACT: "out-extract"
-                },
-                Subscene: {
-                    GROUP: "subscene"
-                },
-                OPNODE: "op",
-                METANODE: "meta",
-                SERIESNODE: "series",
-                BRIDGENODE: "bridge",
-                ELLIPSISNODE: "ellipsis"
-            };
-            /**
-             * Helper method for fitting the graph in the svg view.
-             *
-             * @param svg The main svg.
-             * @param zoomG The svg group used for panning and zooming.
-             * @param d3zoom The zoom behavior.
-             * @param callback Called when the fitting is done.
-             */
-            function fit(svg, zoomG, d3zoom, callback) {
-                var svgRect = svg.getBoundingClientRect();
-                var sceneSize = zoomG.getBBox();
-                var scale = 0.9 * Math.min(svgRect.width / sceneSize.width, svgRect.height / sceneSize.height, 2);
-                var params = graph.layout.PARAMS.graph;
-                var zoomEvent = d3zoom.scale(scale)
-                    .on("zoomend.fitted", function () {
-                    // Remove the listener for the zoomend event,
-                    // so we don't get called at the end of regular zoom events,
-                    // just those that fit the graph to screen.
-                    d3zoom.on("zoomend.fitted", null);
-                    callback();
-                })
-                    .translate([params.padding.paddingLeft, params.padding.paddingTop])
-                    .event;
-                d3.select(zoomG).transition().duration(500).call(zoomEvent);
-            }
-            scene.fit = fit;
-            ;
-            /**
-             * Helper method for panning the graph to center on the provided node,
-             * if the node is currently off-screen.
-             *
-             * @param nodeName The node to center the graph on
-             * @param svg The root SVG element for the graph
-             * @param zoomG The svg group used for panning and zooming.
-             * @param d3zoom The zoom behavior.
-             * @return True if the graph had to be panned to display the
-             *            provided node.
-             */
-            function panToNode(nodeName, svg, zoomG, d3zoom) {
-                var node = d3.select("[data-name='" + nodeName + "']."
-                    + scene.Class.Node.GROUP).node();
-                if (!node) {
-                    return false;
-                }
-                var translate = d3zoom.translate();
-                // Check if the selected node is off-screen in either
-                // X or Y dimension in either direction.
-                var nodeBox = node.getBBox();
-                var nodeCtm = node.getScreenCTM();
-                var pointTL = svg.createSVGPoint();
-                var pointBR = svg.createSVGPoint();
-                pointTL.x = nodeBox.x;
-                pointTL.y = nodeBox.y;
-                pointBR.x = nodeBox.x + nodeBox.width;
-                pointBR.y = nodeBox.y + nodeBox.height;
-                pointTL = pointTL.matrixTransform(nodeCtm);
-                pointBR = pointBR.matrixTransform(nodeCtm);
-                var isOutsideOfBounds = function (start, end, bound) {
-                    return end < 0 || start > bound;
-                };
-                var svgRect = svg.getBoundingClientRect();
-                if (isOutsideOfBounds(pointTL.x, pointBR.x, svgRect.width) ||
-                    isOutsideOfBounds(pointTL.y, pointBR.y, svgRect.height)) {
-                    // Determine the amount to transform the graph in both X and Y
-                    // dimensions in order to center the selected node. This takes into
-                    // acount the position of the node, the size of the svg scene, the
-                    // amount the scene has been scaled by through zooming, and any previous
-                    // transform already performed by this logic.
-                    var centerX = (pointTL.x + pointBR.x) / 2;
-                    var centerY = (pointTL.y + pointBR.y) / 2;
-                    var dx = ((svgRect.width / 2) - centerX);
-                    var dy = ((svgRect.height / 2) - centerY);
-                    var zoomEvent = d3zoom.translate([translate[0] + dx, translate[1] + dy])
-                        .event;
-                    d3.select(zoomG).transition().duration(500).call(zoomEvent);
-                    return true;
-                }
-                return false;
-            }
-            scene.panToNode = panToNode;
-            ;
-            /**
-             * Given a container d3 selection, select a child svg element of a given tag
-             * and class if exists or append / insert one otherwise.  If multiple children
-             * matches the tag and class name, returns only the first one.
-             *
-             * @param container
-             * @param tagName tag name.
-             * @param className (optional) Class name.
-             * @param before (optional) reference DOM node for insertion.
-             * @return selection of the element
-             */
-            function selectOrCreateChild(container, tagName, className, before) {
-                var child = selectChild(container, tagName, className);
-                if (!child.empty()) {
-                    return child;
-                }
-                var newElement = document.createElementNS("http://www.w3.org/2000/svg", tagName);
-                if (className) {
-                    newElement.classList.add(className);
-                }
-                if (before) {
-                    container.node().insertBefore(newElement, before);
-                }
-                else {
-                    container.node().appendChild(newElement);
-                }
-                return d3.select(newElement)
-                    .datum(container.datum());
-            }
-            scene.selectOrCreateChild = selectOrCreateChild;
-            ;
-            /**
-             * Given a container d3 selection, select a child element of a given tag and
-             * class. If multiple children matches the tag and class name, returns only
-             * the first one.
-             *
-             * @param container
-             * @param tagName tag name.
-             * @param className (optional) Class name.
-             * @return selection of the element, or an empty selection
-             */
-            function selectChild(container, tagName, className) {
-                var children = container.node().childNodes;
-                for (var i = 0; i < children.length; i++) {
-                    var child = children[i];
-                    if (child.tagName === tagName &&
-                        (!className || child.classList.contains(className))) {
-                        return d3.select(child);
-                    }
-                }
-                return d3.select(null);
-            }
-            scene.selectChild = selectChild;
-            ;
-            /**
-             * Select or create a sceneGroup and build/update its nodes and edges.
-             *
-             * Structure Pattern:
-             *
-             * <g class="scene">
-             *   <g class="core">
-             *     <g class="edges">
-             *       ... stuff from tf.graph.scene.edges.build ...
-             *     </g>
-             *     <g class="nodes">
-             *       ... stuff from tf.graph.scene.nodes.build ...
-             *     </g>
-             *   </g>
-             *   <g class="in-extract">
-             *     <g class="nodes">
-             *       ... stuff from tf.graph.scene.nodes.build ...
-             *     </g>
-             *   </g>
-             *   <g class="out-extract">
-             *     <g class="nodes">
-             *       ... stuff from tf.graph.scene.nodes.build ...
-             *     </g>
-             *   </g>
-             * </g>
-             *
-             * @param container D3 selection of the parent.
-             * @param renderNode render node of a metanode or series node.
-             * @param sceneElement <tf-graph-scene> polymer element.
-             * @param sceneClass class attribute of the scene (default="scene").
-             */
-            function buildGroup(container, renderNode, sceneElement, sceneClass) {
-                sceneClass = sceneClass || scene.Class.Scene.GROUP;
-                var isNewSceneGroup = selectChild(container, "g", sceneClass).empty();
-                var sceneGroup = selectOrCreateChild(container, "g", sceneClass);
-                // core
-                var coreGroup = selectOrCreateChild(sceneGroup, "g", scene.Class.Scene.CORE);
-                var coreNodes = _.reduce(renderNode.coreGraph.nodes(), function (nodes, name) {
-                    var node = renderNode.coreGraph.node(name);
-                    if (!node.excluded) {
-                        nodes.push(node);
-                    }
-                    return nodes;
-                }, []);
-                if (renderNode.node.type === graph.NodeType.SERIES) {
-                    // For series, we want the first item on top, so reverse the array so
-                    // the first item in the series becomes last item in the top, and thus
-                    // is rendered on the top.
-                    coreNodes.reverse();
-                }
-                // Create the layer of edges for this scene (paths).
-                scene.edge.buildGroup(coreGroup, renderNode.coreGraph, sceneElement);
-                // Create the layer of nodes for this scene (ellipses, rects etc).
-                scene.node.buildGroup(coreGroup, coreNodes, sceneElement);
-                // In-extract
-                if (renderNode.isolatedInExtract.length > 0) {
-                    var inExtractGroup = selectOrCreateChild(sceneGroup, "g", scene.Class.Scene.INEXTRACT);
-                    scene.node.buildGroup(inExtractGroup, renderNode.isolatedInExtract, sceneElement);
-                }
-                else {
-                    selectChild(sceneGroup, "g", scene.Class.Scene.INEXTRACT).remove();
-                }
-                // Out-extract
-                if (renderNode.isolatedOutExtract.length > 0) {
-                    var outExtractGroup = selectOrCreateChild(sceneGroup, "g", scene.Class.Scene.OUTEXTRACT);
-                    scene.node.buildGroup(outExtractGroup, renderNode.isolatedOutExtract, sceneElement);
-                }
-                else {
-                    selectChild(sceneGroup, "g", scene.Class.Scene.OUTEXTRACT).remove();
-                }
-                position(sceneGroup, renderNode);
-                // Fade in the scene group if it didn't already exist.
-                if (isNewSceneGroup) {
-                    sceneGroup.attr("opacity", 0).transition().attr("opacity", 1);
-                }
-                return sceneGroup;
-            }
-            scene.buildGroup = buildGroup;
-            ;
-            /**
-             * Given a scene's svg group, set  g.in-extract, g.coreGraph, g.out-extract svg
-             * groups' position relative to the scene.
-             *
-             * @param sceneGroup
-             * @param renderNode render node of a metanode or series node.
-             */
-            function position(sceneGroup, renderNode) {
-                // Translate scenes down by the label height so that when showing graphs in
-                // expanded metanodes, the graphs are below the labels.  Do not shift them
-                // down for series nodes as series nodes don't have labels inside of their
-                // bounding boxes.
-                var yTranslate = renderNode.node.type === graph.NodeType.SERIES ?
-                    0 : graph.layout.PARAMS.subscene.meta.labelHeight;
-                // core
-                translate(selectChild(sceneGroup, "g", scene.Class.Scene.CORE), 0, yTranslate);
-                // in-extract
-                var hasInExtract = renderNode.isolatedInExtract.length > 0;
-                var hasOutExtract = renderNode.isolatedOutExtract.length > 0;
-                if (hasInExtract) {
-                    var offset = graph.layout.PARAMS.subscene.meta.extractXOffset;
-                    var inExtractX = renderNode.coreBox.width -
-                        renderNode.inExtractBox.width / 2 - renderNode.outExtractBox.width -
-                        (hasOutExtract ? offset : 0);
-                    translate(selectChild(sceneGroup, "g", scene.Class.Scene.INEXTRACT), inExtractX, yTranslate);
-                }
-                // out-extract
-                if (hasOutExtract) {
-                    var outExtractX = renderNode.coreBox.width -
-                        renderNode.outExtractBox.width / 2;
-                    translate(selectChild(sceneGroup, "g", scene.Class.Scene.OUTEXTRACT), outExtractX, yTranslate);
-                }
-            }
-            ;
-            /** Adds a click listener to a group that fires a graph-select event */
-            function addGraphClickListener(graphGroup, sceneElement) {
-                d3.select(graphGroup).on("click", function () {
-                    sceneElement.fire("graph-select");
-                });
-            }
-            scene.addGraphClickListener = addGraphClickListener;
-            ;
-            /** Helper for adding transform: translate(x0, y0) */
-            function translate(selection, x0, y0) {
-                // If it is already placed on the screen, make it a transition.
-                if (selection.attr("transform") != null) {
-                    selection = selection.transition("position");
-                }
-                selection.attr("transform", "translate(" + x0 + "," + y0 + ")");
-            }
-            scene.translate = translate;
-            ;
-            /**
-             * Helper for setting position of a svg rect
-             * @param rect rect to set position of.
-             * @param cx Center x.
-             * @param cy Center x.
-             * @param width Width to set.
-             * @param height Height to set.
-             */
-            function positionRect(rect, cx, cy, width, height) {
-                rect.transition().attr({
-                    x: cx - width / 2,
-                    y: cy - height / 2,
-                    width: width,
-                    height: height
-                });
-            }
-            scene.positionRect = positionRect;
-            ;
-            /**
-             * Helper for setting position of a svg expand/collapse button
-             * @param button container group
-             * @param renderNode the render node of the group node to position
-             *        the button on.
-             */
-            function positionButton(button, renderNode) {
-                var cx = graph.layout.computeCXPositionOfNodeShape(renderNode);
-                // Position the button in the top-right corner of the group node,
-                // with space given the draw the button inside of the corner.
-                var width = renderNode.expanded ?
-                    renderNode.width : renderNode.coreBox.width;
-                var height = renderNode.expanded ?
-                    renderNode.height : renderNode.coreBox.height;
-                var x = cx + width / 2 - 6;
-                var y = renderNode.y - height / 2 + 6;
-                // For unexpanded series nodes, the button has special placement due
-                // to the unique visuals of this group node.
-                if (renderNode.node.type === graph.NodeType.SERIES && !renderNode.expanded) {
-                    x += 10;
-                    y -= 2;
-                }
-                var translateStr = "translate(" + x + "," + y + ")";
-                button.selectAll("path").transition().attr("transform", translateStr);
-                button.select("circle").transition().attr({
-                    cx: x,
-                    cy: y,
-                    r: graph.layout.PARAMS.nodeSize.meta.expandButtonRadius
-                });
-            }
-            scene.positionButton = positionButton;
-            ;
-            /**
-             * Helper for setting position of a svg ellipse
-             * @param ellipse ellipse to set position of.
-             * @param cx Center x.
-             * @param cy Center x.
-             * @param width Width to set.
-             * @param height Height to set.
-             */
-            function positionEllipse(ellipse, cx, cy, width, height) {
-                ellipse.transition().attr({
-                    cx: cx,
-                    cy: cy,
-                    rx: width / 2,
-                    ry: height / 2
-                });
-            }
-            scene.positionEllipse = positionEllipse;
-            ;
-        })(scene = graph.scene || (graph.scene = {}));
-    })(graph = tf.graph || (tf.graph = {}));
-})(tf || (tf = {})); // close module
-</script>
-<script>/* Copyright 2015 Google Inc. All Rights Reserved.
-
-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,
+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.
@@ -6907,12 +7228,12 @@
                 /**
                  * Populate a given annotation container group
                  *
-                 *     <g class="{in|out}-annotations"></g>
+                 *     <g class='{in|out}-annotations'></g>
                  *
                  * with annotation group of the following structure:
                  *
-                 * <g class="annotation">
-                 *   <g class="annotation-node">
+                 * <g class='annotation'>
+                 *   <g class='annotation-node'>
                  *   \x3c!--
                  *   Content here determined by Scene.node.buildGroup.
                  *   --\x3e
@@ -6927,7 +7248,8 @@
                  */
                 function buildGroup(container, annotationData, d, sceneElement) {
                     // Select all children and join with data.
-                    var annotationGroups = container.selectAll(function () {
+                    var annotationGroups = container
+                        .selectAll(function () {
                         // using d3's selector function
                         // See https://github.com/mbostock/d3/releases/tag/v2.0.0
                         // (It's not listed in the d3 wiki.)
@@ -6935,8 +7257,8 @@
                     })
                         .data(annotationData.list, function (d) { return d.node.name; });
                     annotationGroups.enter()
-                        .append("g")
-                        .attr("data-name", function (a) { return a.node.name; })
+                        .append('g')
+                        .attr('data-name', function (a) { return a.node.name; })
                         .each(function (a) {
                         var aGroup = d3.select(this);
                         // Add annotation to the index in the scene
@@ -6945,11 +7267,11 @@
                         var edgeType = scene.Class.Annotation.EDGE;
                         var metaedge = a.renderMetaedgeInfo && a.renderMetaedgeInfo.metaedge;
                         if (metaedge && !metaedge.numRegularEdges) {
-                            edgeType += " " + scene.Class.Annotation.CONTROL_EDGE;
+                            edgeType += ' ' + scene.Class.Annotation.CONTROL_EDGE;
                         }
                         // If any edges are reference edges, add the reference edge class.
                         if (metaedge && metaedge.numRefEdges) {
-                            edgeType += " " + scene.Class.Edge.REF_LINE;
+                            edgeType += ' ' + scene.Class.Edge.REF_LINE;
                         }
                         scene.edge.appendEdge(aGroup, a, sceneElement, edgeType);
                         if (a.annotationType !== graph.render.AnnotationType.ELLIPSIS) {
@@ -6961,10 +7283,10 @@
                         }
                     });
                     annotationGroups
-                        .attr("class", function (a) {
-                        return scene.Class.Annotation.GROUP + " " +
-                            annotationToClassName(a.annotationType) +
-                            " " + scene.node.nodeClass(a);
+                        .attr('class', function (a) {
+                        return scene.Class.Annotation.GROUP + ' ' +
+                            annotationToClassName(a.annotationType) + ' ' +
+                            scene.node.nodeClass(a);
                     })
                         .each(function (a) {
                         var aGroup = d3.select(this);
@@ -6988,76 +7310,67 @@
                  * Maps an annotation enum to a class name used in css rules.
                  */
                 function annotationToClassName(annotationType) {
-                    return (graph.render.AnnotationType[annotationType] || "")
-                        .toLowerCase() || null;
+                    return (graph.render.AnnotationType[annotationType] || '').toLowerCase() || null;
                 }
                 function buildShape(aGroup, a) {
                     if (a.annotationType === graph.render.AnnotationType.SUMMARY) {
-                        var summary = scene.selectOrCreateChild(aGroup, "use");
+                        var summary = scene.selectOrCreateChild(aGroup, 'use');
                         summary.attr({
-                            "class": "summary",
-                            "xlink:href": "#summary-icon",
-                            "cursor": "pointer"
+                            'class': 'summary',
+                            'xlink:href': '#summary-icon',
+                            'cursor': 'pointer'
                         });
                     }
                     else {
                         var shape = scene.node.buildShape(aGroup, a, scene.Class.Annotation.NODE);
                         // add title tag to get native tooltips
-                        scene.selectOrCreateChild(shape, "title").text(a.node.name);
+                        scene.selectOrCreateChild(shape, 'title').text(a.node.name);
                     }
                 }
                 function addAnnotationLabelFromNode(aGroup, a) {
-                    var namePath = a.node.name.split("/");
+                    var namePath = a.node.name.split('/');
                     var text = namePath[namePath.length - 1];
-                    var shortenedText = text.length > 8 ? text.substring(0, 8) + "..." : text;
+                    var shortenedText = text.length > 8 ? text.substring(0, 8) + '...' : text;
                     return addAnnotationLabel(aGroup, shortenedText, a, null, text);
                 }
                 function addAnnotationLabel(aGroup, label, a, additionalClassNames, fullLabel) {
                     var classNames = scene.Class.Annotation.LABEL;
                     if (additionalClassNames) {
-                        classNames += " " + additionalClassNames;
+                        classNames += ' ' + additionalClassNames;
                     }
                     var titleText = fullLabel ? fullLabel : label;
-                    return aGroup.append("text")
-                        .attr("class", classNames)
-                        .attr("dy", ".35em")
-                        .attr("text-anchor", a.isIn ? "end" : "start")
+                    return aGroup.append('text')
+                        .attr('class', classNames)
+                        .attr('dy', '.35em')
+                        .attr('text-anchor', a.isIn ? 'end' : 'start')
                         .text(label)
-                        .append("title").text(titleText);
+                        .append('title')
+                        .text(titleText);
                 }
                 function addInteraction(selection, d, annotation, sceneElement) {
                     selection
-                        .on("mouseover", function (a) {
-                        sceneElement.fire("annotation-highlight", {
-                            name: a.node.name,
-                            hostName: d.node.name
-                        });
+                        .on('mouseover', function (a) {
+                        sceneElement.fire('annotation-highlight', { name: a.node.name, hostName: d.node.name });
                     })
-                        .on("mouseout", function (a) {
-                        sceneElement.fire("annotation-unhighlight", {
-                            name: a.node.name,
-                            hostName: d.node.name
-                        });
+                        .on('mouseout', function (a) {
+                        sceneElement.fire('annotation-unhighlight', { name: a.node.name, hostName: d.node.name });
                     })
-                        .on("click", function (a) {
-                        // Stop this event"s propagation so that it isn't also considered a
+                        .on('click', function (a) {
+                        // Stop this event's propagation so that it isn't also considered a
                         // graph-select.
                         d3.event.stopPropagation();
-                        sceneElement.fire("annotation-select", {
-                            name: a.node.name,
-                            hostName: d.node.name
-                        });
+                        sceneElement.fire('annotation-select', { name: a.node.name, hostName: d.node.name });
                     });
                     if (annotation.annotationType !== graph.render.AnnotationType.SUMMARY &&
                         annotation.annotationType !== graph.render.AnnotationType.CONSTANT) {
-                        selection.on("contextmenu", scene.contextmenu.getMenu(scene.node.getContextMenu(annotation.node, sceneElement)));
+                        selection.on('contextmenu', scene.contextmenu.getMenu(scene.node.getContextMenu(annotation.node, sceneElement)));
                     }
                 }
                 ;
                 /**
                  * Adjust annotation's position.
                  *
-                 * @param aGroup selection of a "g.annotation" element.
+                 * @param aGroup selection of a 'g.annotation' element.
                  * @param d Host node data.
                  * @param a annotation node data.
                  * @param scene <tf-graph-scene> polymer element.
@@ -7066,7 +7379,7 @@
                     var cx = graph.layout.computeCXPositionOfNodeShape(d);
                     // Annotations that point to embedded nodes (constants,summary)
                     // don't have a render information attached so we don't stylize these.
-                    // Also we don't stylize ellipsis annotations (the string "... and X more").
+                    // Also we don't stylize ellipsis annotations (the string '... and X more').
                     if (a.renderNodeInfo &&
                         a.annotationType !== graph.render.AnnotationType.ELLIPSIS) {
                         scene.node.stylize(aGroup, a.renderNodeInfo, sceneElement, scene.Class.Annotation.NODE);
@@ -7076,7 +7389,7 @@
                         a.width += 10;
                     }
                     // label position
-                    aGroup.select("text." + scene.Class.Annotation.LABEL).transition().attr({
+                    aGroup.select('text.' + scene.Class.Annotation.LABEL).transition().attr({
                         x: cx + a.dx + (a.isIn ? -1 : 1) * (a.width / 2 + a.labelOffset),
                         y: d.y + a.dy
                     });
@@ -7085,20 +7398,18 @@
                     // If there is an image, we adjust the location of the image to be vertically
                     // centered with the node and horizontally centered between the arrow and the
                     // text label.
-                    aGroup.select("use.summary").transition().attr({
+                    aGroup.select('use.summary').transition().attr({
                         x: cx + a.dx - 3,
                         y: d.y + a.dy - 6
                     });
                     // Node position (only one of the shape selection will be non-empty.)
-                    scene.positionEllipse(aGroup.select("." + scene.Class.Annotation.NODE + " ellipse"), cx + a.dx, d.y + a.dy, a.width, a.height);
-                    scene.positionRect(aGroup.select("." + scene.Class.Annotation.NODE + " rect"), cx + a.dx, d.y + a.dy, a.width, a.height);
-                    scene.positionRect(aGroup.select("." + scene.Class.Annotation.NODE + " use"), cx + a.dx, d.y + a.dy, a.width, a.height);
+                    scene.positionEllipse(aGroup.select('.' + scene.Class.Annotation.NODE + ' ellipse'), cx + a.dx, d.y + a.dy, a.width, a.height);
+                    scene.positionRect(aGroup.select('.' + scene.Class.Annotation.NODE + ' rect'), cx + a.dx, d.y + a.dy, a.width, a.height);
+                    scene.positionRect(aGroup.select('.' + scene.Class.Annotation.NODE + ' use'), cx + a.dx, d.y + a.dy, a.width, a.height);
                     // Edge position
-                    aGroup.select("path." + scene.Class.Annotation.EDGE).transition().attr("d", function (a) {
+                    aGroup.select('path.' + scene.Class.Annotation.EDGE).transition().attr('d', function (a) {
                         // map relative position to absolute position
-                        var points = a.points.map(function (p) {
-                            return { x: p.dx + cx, y: p.dy + d.y };
-                        });
+                        var points = a.points.map(function (p) { return { x: p.dx + cx, y: p.dy + d.y }; });
                         return scene.edge.interpolate(points);
                     });
                 }
@@ -7110,14 +7421,79 @@
 </script>
 <script>/* Copyright 2015 Google Inc. All Rights Reserved.
 
-Licensed under the Apache License, Version 2.0 (the "License");
+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,
+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.
+==============================================================================*/
+var tf;
+(function (tf) {
+    var graph;
+    (function (graph) {
+        var scene;
+        (function (scene) {
+            var contextmenu;
+            (function (contextmenu) {
+                /**
+                 * Returns the event listener, which can be used as an argument for the d3
+                 * selection.on function. Renders the context menu that is to be displayed
+                 * in response to the event.
+                 */
+                function getMenu(menu) {
+                    var menuSelection = d3.select('.context-menu');
+                    // Close the menu when anything else is clicked.
+                    d3.select('body').on('click.context', function () { menuSelection.style('display', 'none'); });
+                    // Function called to populate the context menu.
+                    return function (data, index) {
+                        var _this = this;
+                        // Position and display the menu.
+                        var event = d3.event;
+                        menuSelection.style({
+                            'display': 'block',
+                            'left': (event.layerX + 1) + 'px',
+                            'top': (event.layerY + 1) + 'px'
+                        });
+                        // Stop the event from propagating further.
+                        event.preventDefault();
+                        event.stopPropagation();
+                        // Add provided items to the context menu.
+                        menuSelection.html('');
+                        var list = menuSelection.append('ul');
+                        list.selectAll('li')
+                            .data(menu)
+                            .enter()
+                            .append('li')
+                            .html(function (d) { return d.title(data); })
+                            .on('click', function (d, i) {
+                            d.action(_this, data, index);
+                            menuSelection.style('display', 'none');
+                        });
+                    };
+                }
+                contextmenu.getMenu = getMenu;
+                ;
+            })(contextmenu = scene.contextmenu || (scene.contextmenu = {}));
+        })(scene = graph.scene || (graph.scene = {}));
+    })(graph = tf.graph || (tf.graph = {}));
+})(tf || (tf = {})); // close module
+</script>
+<script>/* Copyright 2015 Google Inc. All Rights Reserved.
+
+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.
@@ -7131,7 +7507,7 @@
             var edge;
             (function (edge) {
                 /** Delimiter between dimensions when showing sizes of tensors. */
-                var TENSOR_SHAPE_DELIM = "×";
+                var TENSOR_SHAPE_DELIM = '×';
                 /** The minimum stroke width of an edge. */
                 edge.MIN_EDGE_WIDTH = 0.75;
                 /** The maximum stroke width of an edge. */
@@ -7145,9 +7521,9 @@
                     .domain(DOMAIN_EDGE_WIDTH_SCALE)
                     .range([edge.MIN_EDGE_WIDTH, edge.MAX_EDGE_WIDTH])
                     .clamp(true);
-                var arrowheadMap = d3.scale.quantize()
-                    .domain([edge.MIN_EDGE_WIDTH, edge.MAX_EDGE_WIDTH])
-                    .range(["small", "medium", "large", "xlarge"]);
+                var arrowheadMap = d3.scale.quantize().domain([edge.MIN_EDGE_WIDTH, edge.MAX_EDGE_WIDTH]).range([
+                    'small', 'medium', 'large', 'xlarge'
+                ]);
                 /** Minimum stroke width to put edge labels in the middle of edges */
                 var CENTER_EDGE_LABEL_MIN_STROKE_WIDTH = 2.5;
                 function getEdgeKey(edgeObj) {
@@ -7155,14 +7531,14 @@
                 }
                 edge.getEdgeKey = getEdgeKey;
                 /**
-                 * Select or Create a "g.edges" group to a given sceneGroup
-                 * and builds a number of "g.edge" groups inside the group.
+                 * Select or Create a 'g.edges' group to a given sceneGroup
+                 * and builds a number of 'g.edge' groups inside the group.
                  *
                  * Structure Pattern:
                  *
-                 * <g class="edges">
-                 *   <g class="edge">
-                 *     <path class="edgeline"/>
+                 * <g class='edges'>
+                 *   <g class='edge'>
+                 *     <path class='edgeline'/>
                  *   </g>
                  *   ...
                  * </g>
@@ -7184,7 +7560,7 @@
                         });
                         return edges;
                     }, edges);
-                    var container = scene.selectOrCreateChild(sceneGroup, "g", scene.Class.Edge.CONTAINER);
+                    var container = scene.selectOrCreateChild(sceneGroup, 'g', scene.Class.Edge.CONTAINER);
                     // Select all children and join with data.
                     // (Note that all children of g.edges are g.edge)
                     var edgeGroups = container.selectAll(function () {
@@ -7195,9 +7571,9 @@
                     }).data(edges, getEdgeKey);
                     // Make edges a group to support rendering multiple lines for metaedge
                     edgeGroups.enter()
-                        .append("g")
-                        .attr("class", scene.Class.Edge.GROUP)
-                        .attr("data-edge", getEdgeKey)
+                        .append('g')
+                        .attr('class', scene.Class.Edge.GROUP)
+                        .attr('data-edge', getEdgeKey)
                         .each(function (d) {
                         var edgeGroup = d3.select(this);
                         d.label.edgeGroup = edgeGroup;
@@ -7231,11 +7607,10 @@
                         return null;
                     }
                     if (shape.length === 0) {
-                        return "scalar";
+                        return 'scalar';
                     }
-                    return shape.map(function (size) {
-                        return size === -1 ? "?" : size;
-                    }).join(TENSOR_SHAPE_DELIM);
+                    return shape.map(function (size) { return size === -1 ? '?' : size; })
+                        .join(TENSOR_SHAPE_DELIM);
                 }
                 edge.getShapeLabelFromNode = getShapeLabelFromNode;
                 /**
@@ -7246,7 +7621,7 @@
                 function getLabelForEdge(metaedge, renderInfo) {
                     var isMultiEdge = metaedge.baseEdgeList.length > 1;
                     if (isMultiEdge) {
-                        return metaedge.baseEdgeList.length + " tensors";
+                        return metaedge.baseEdgeList.length + ' tensors';
                     }
                     else {
                         var node_1 = renderInfo.getNodeByName(metaedge.baseEdgeList[0].v);
@@ -7268,11 +7643,12 @@
                     var lineFunc = d3.svg.line()
                         .x(function (d) { return d.x; })
                         .y(function (d) { return d.y; });
-                    var path = d3.select(document.createElementNS("http://www.w3.org/2000/svg", "path")).attr("d", lineFunc(points));
-                    var markerWidth = +marker.attr("markerWidth");
-                    var viewBox = marker.attr("viewBox").split(" ").map(Number);
+                    var path = d3.select(document.createElementNS('http://www.w3.org/2000/svg', 'path'))
+                        .attr('d', lineFunc(points));
+                    var markerWidth = +marker.attr('markerWidth');
+                    var viewBox = marker.attr('viewBox').split(' ').map(Number);
                     var viewBoxWidth = viewBox[2] - viewBox[0];
-                    var refX = +marker.attr("refX");
+                    var refX = +marker.attr('refX');
                     var pathNode = path.node();
                     if (isStart) {
                         var fractionStickingOut = refX / viewBoxWidth;
@@ -7315,23 +7691,22 @@
                     }
                     edgeClass = edgeClass || scene.Class.Edge.LINE; // set default type
                     if (d.label && d.label.structural) {
-                        edgeClass += " " + scene.Class.Edge.STRUCTURAL;
+                        edgeClass += ' ' + scene.Class.Edge.STRUCTURAL;
                     }
                     // Give the path a unique id, which will be used to link
                     // the textPath (edge label) to this path.
-                    var pathId = "path_" + getEdgeKey(d);
+                    var pathId = 'path_' + getEdgeKey(d);
                     var strokeWidth = sceneElement.renderHierarchy.edgeWidthScale(size);
-                    var path = edgeGroup.append("path")
+                    var path = edgeGroup.append('path')
                         .attr({
-                        "id": pathId,
-                        "class": edgeClass,
-                    }).style({
-                        "stroke-width": strokeWidth + "px"
-                    });
+                        'id': pathId,
+                        'class': edgeClass,
+                    })
+                        .style({ 'stroke-width': strokeWidth + 'px' });
                     // Check if there is a reference edge and add an arrowhead of the right size.
                     if (d.label && d.label.metaedge && d.label.metaedge.numRefEdges) {
                         var markerId = "ref-arrowhead-" + arrowheadMap(strokeWidth);
-                        path.style("marker-start", "url(#" + markerId + ")");
+                        path.style('marker-start', "url(#" + markerId + ")");
                         d.label.startMarkerId = markerId;
                     }
                     if (d.label == null || d.label.metaedge == null) {
@@ -7346,18 +7721,22 @@
                     }
                     // Put edge label in the middle of edge only if the edge is thick enough.
                     var baseline = strokeWidth > CENTER_EDGE_LABEL_MIN_STROKE_WIDTH ?
-                        "central" : "text-after-edge";
-                    edgeGroup.append("text").append("textPath").attr({
-                        "xlink:href": "#" + pathId,
-                        "startOffset": "50%",
-                        "text-anchor": "middle",
-                        "dominant-baseline": baseline
-                    }).text(labelForEdge);
+                        'central' :
+                        'text-after-edge';
+                    edgeGroup.append('text')
+                        .append('textPath')
+                        .attr({
+                        'xlink:href': '#' + pathId,
+                        'startOffset': '50%',
+                        'text-anchor': 'middle',
+                        'dominant-baseline': 'central'
+                    })
+                        .text(labelForEdge);
                 }
                 edge.appendEdge = appendEdge;
                 ;
                 edge.interpolate = d3.svg.line()
-                    .interpolate("basis")
+                    .interpolate('basis')
                     .x(function (d) { return d.x; })
                     .y(function (d) { return d.y; });
                 /**
@@ -7370,10 +7749,10 @@
                     // Adjust the path so that start/end markers point to the end
                     // of the path.
                     if (d.label.startMarkerId) {
-                        points = adjustPathPointsForMarker(points, d3.select("#" + d.label.startMarkerId), true);
+                        points = adjustPathPointsForMarker(points, d3.select('#' + d.label.startMarkerId), true);
                     }
                     if (d.label.endMarkerId) {
-                        points = adjustPathPointsForMarker(points, d3.select("#" + d.label.endMarkerId), false);
+                        points = adjustPathPointsForMarker(points, d3.select('#' + d.label.endMarkerId), false);
                     }
                     if (!adjoiningMetaedge) {
                         return d3.interpolate(a, edge.interpolate(points));
@@ -7401,9 +7780,10 @@
                     };
                 }
                 function position(d) {
-                    d3.select(this).select("path." + scene.Class.Edge.LINE)
+                    d3.select(this)
+                        .select('path.' + scene.Class.Edge.LINE)
                         .transition()
-                        .attrTween("d", getEdgePathInterpolator);
+                        .attrTween('d', getEdgePathInterpolator);
                 }
                 ;
                 /**
@@ -7414,9 +7794,8 @@
                  */
                 function stylize(edgeGroup, d, stylize) {
                     var metaedge = d.label.metaedge;
-                    edgeGroup
-                        .select("path." + scene.Class.Edge.LINE)
-                        .classed("control-dep", metaedge && !metaedge.numRegularEdges);
+                    edgeGroup.select('path.' + scene.Class.Edge.LINE)
+                        .classed('control-dep', metaedge && !metaedge.numRegularEdges);
                 }
                 ;
             })(edge = scene.edge || (scene.edge = {}));
@@ -7426,14 +7805,14 @@
 </script>
 <script>/* Copyright 2015 Google Inc. All Rights Reserved.
 
-Licensed under the Apache License, Version 2.0 (the "License");
+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,
+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.
@@ -7447,29 +7826,30 @@
             var node;
             (function (node_1) {
                 /**
-                 * Select or Create a "g.nodes" group to a given sceneGroup
-                 * and builds a number of "g.node" groups inside the group.
+                 * Select or Create a 'g.nodes' group to a given sceneGroup
+                 * and builds a number of 'g.node' groups inside the group.
                  *
                  * Structure Pattern:
                  *
-                 * <g class="nodes">
-                 *   <g class="node">
-                 *     <g class="in-annotations">
+                 * <g class='nodes'>
+                 *   <g class='node'>
+                 *     <g class='in-annotations'>
                  *       ...
                  *     </g>
-                 *     <g class="out-annotations">
+                 *     <g class='out-annotations'>
                  *       ...
                  *     </g>
-                 *     <g class="nodeshape">
+                 *     <g class='nodeshape'>
                  *      \x3c!--
                  *      Content of the node shape should be for the node itself. For example a
                  *      Metanode would have a <rect> with rounded edges, an op would have an
-                 *      <ellipse>. More complex nodes like series may contain multiple elements
-                 *      which are conditionally visible based on whether the node is expanded.
+                 *      <ellipse>. More complex nodes like series may contain multiple
+                 *      elements which are conditionally visible based on whether the node is
+                 *      expanded.
                  *      --\x3e
                  *     </g>
-                 *     <text class="label">node name</text>
-                 *     <g class="subscene">
+                 *     <text class='label'>node name</text>
+                 *     <g class='subscene'>
                  *       \x3c!--
                  *       Content of  the subscene (only for metanode and series node).
                  *
@@ -7491,10 +7871,11 @@
                  * @return selection of the created nodeGroups
                  */
                 function buildGroup(sceneGroup, nodeData, sceneElement) {
-                    var container = scene.selectOrCreateChild(sceneGroup, "g", scene.Class.Node.CONTAINER);
+                    var container = scene.selectOrCreateChild(sceneGroup, 'g', scene.Class.Node.CONTAINER);
                     // Select all children and join with data.
                     // (Note that all children of g.nodes are g.node)
-                    var nodeGroups = container.selectAll(function () {
+                    var nodeGroups = container
+                        .selectAll(function () {
                         // using d3's selector function
                         // See https://github.com/mbostock/d3/releases/tag/v2.0.0
                         // (It's not listed in the d3 wiki.)
@@ -7502,12 +7883,12 @@
                     })
                         .data(nodeData, function (d) {
                         // make sure that we don't have to swap shape type
-                        return d.node.name + ":" + d.node.type;
+                        return d.node.name + ':' + d.node.type;
                     });
                     // ENTER
                     nodeGroups.enter()
-                        .append("g")
-                        .attr("data-name", function (d) { return d.node.name; })
+                        .append('g')
+                        .attr('data-name', function (d) { return d.node.name; })
                         .each(function (d) {
                         var nodeGroup = d3.select(this);
                         // index node group for quick stylizing
@@ -7515,16 +7896,16 @@
                     });
                     // UPDATE
                     nodeGroups
-                        .attr("class", function (d) {
-                        return scene.Class.Node.GROUP + " " + nodeClass(d);
-                    })
+                        .attr('class', function (d) { return scene.Class.Node.GROUP + ' ' + nodeClass(d); })
                         .each(function (d) {
                         var nodeGroup = d3.select(this);
-                        // Add g.in-annotations (always add -- to keep layer order consistent.)
-                        var inAnnotationBox = scene.selectOrCreateChild(nodeGroup, "g", scene.Class.Annotation.INBOX);
+                        // Add g.in-annotations (always add -- to keep layer order
+                        // consistent.)
+                        var inAnnotationBox = scene.selectOrCreateChild(nodeGroup, 'g', scene.Class.Annotation.INBOX);
                         scene.annotation.buildGroup(inAnnotationBox, d.inAnnotations, d, sceneElement);
-                        // Add g.out-annotations  (always add -- to keep layer order consistent.)
-                        var outAnnotationBox = scene.selectOrCreateChild(nodeGroup, "g", scene.Class.Annotation.OUTBOX);
+                        // Add g.out-annotations  (always add -- to keep layer order
+                        // consistent.)
+                        var outAnnotationBox = scene.selectOrCreateChild(nodeGroup, 'g', scene.Class.Annotation.OUTBOX);
                         scene.annotation.buildGroup(outAnnotationBox, d.outAnnotations, d, sceneElement);
                         // Build .shape first (background of the node).
                         var shape = buildShape(nodeGroup, d, scene.Class.Node.SHAPE);
@@ -7549,18 +7930,14 @@
                         sceneElement.removeNodeGroup(d.node.name);
                         var nodeGroup = d3.select(this);
                         if (d.inAnnotations.list.length > 0) {
-                            nodeGroup.select("." + scene.Class.Annotation.INBOX)
-                                .selectAll("." + scene.Class.Annotation.GROUP)
-                                .each(function (a) {
-                                sceneElement.removeAnnotationGroup(a, d);
-                            });
+                            nodeGroup.select('.' + scene.Class.Annotation.INBOX)
+                                .selectAll('.' + scene.Class.Annotation.GROUP)
+                                .each(function (a) { sceneElement.removeAnnotationGroup(a, d); });
                         }
                         if (d.outAnnotations.list.length > 0) {
-                            nodeGroup.select("." + scene.Class.Annotation.OUTBOX)
-                                .selectAll("." + scene.Class.Annotation.GROUP)
-                                .each(function (a) {
-                                sceneElement.removeAnnotationGroup(a, d);
-                            });
+                            nodeGroup.select('.' + scene.Class.Annotation.OUTBOX)
+                                .selectAll('.' + scene.Class.Annotation.GROUP)
+                                .each(function (a) { sceneElement.removeAnnotationGroup(a, d); });
                         }
                     })
                         .remove();
@@ -7586,7 +7963,7 @@
                             return scene.buildGroup(nodeGroup, renderNodeInfo, sceneElement, scene.Class.Subscene.GROUP);
                         }
                         // Clean out existing subscene if the node is not expanded.
-                        scene.selectChild(nodeGroup, "g", scene.Class.Subscene.GROUP).remove();
+                        scene.selectChild(nodeGroup, 'g', scene.Class.Subscene.GROUP).remove();
                     }
                     return null;
                 }
@@ -7597,7 +7974,7 @@
                 function subscenePosition(nodeGroup, d) {
                     var x0 = d.x - d.width / 2.0 + d.paddingLeft;
                     var y0 = d.y - d.height / 2.0 + d.paddingTop;
-                    var subscene = scene.selectChild(nodeGroup, "g", scene.Class.Subscene.GROUP);
+                    var subscene = scene.selectChild(nodeGroup, 'g', scene.Class.Subscene.GROUP);
                     scene.translate(subscene, x0, y0);
                 }
                 ;
@@ -7609,15 +7986,17 @@
                  * @param sceneElement <tf-graph-scene> polymer element.
                  */
                 function addButton(selection, d, sceneElement) {
-                    var group = scene.selectOrCreateChild(selection, "g", scene.Class.Node.BUTTON_CONTAINER);
-                    scene.selectOrCreateChild(group, "circle", scene.Class.Node.BUTTON_CIRCLE);
-                    scene.selectOrCreateChild(group, "path", scene.Class.Node.EXPAND_BUTTON).attr("d", "M0,-2.2 V2.2 M-2.2,0 H2.2");
-                    scene.selectOrCreateChild(group, "path", scene.Class.Node.COLLAPSE_BUTTON).attr("d", "M-2.2,0 H2.2");
-                    group.on("click", function (d) {
+                    var group = scene.selectOrCreateChild(selection, 'g', scene.Class.Node.BUTTON_CONTAINER);
+                    scene.selectOrCreateChild(group, 'circle', scene.Class.Node.BUTTON_CIRCLE);
+                    scene.selectOrCreateChild(group, 'path', scene.Class.Node.EXPAND_BUTTON)
+                        .attr('d', 'M0,-2.2 V2.2 M-2.2,0 H2.2');
+                    scene.selectOrCreateChild(group, 'path', scene.Class.Node.COLLAPSE_BUTTON)
+                        .attr('d', 'M-2.2,0 H2.2');
+                    group.on('click', function (d) {
                         // Stop this event's propagation so that it isn't also considered a
                         // node-select.
                         d3.event.stopPropagation();
-                        sceneElement.fire("node-toggle-expand", { name: d.node.name });
+                        sceneElement.fire('node-toggle-expand', { name: d.node.name });
                     });
                     scene.positionButton(group, d);
                 }
@@ -7632,37 +8011,38 @@
                  */
                 function addInteraction(selection, d, sceneElement, disableInteraction) {
                     if (disableInteraction) {
-                        selection.attr("pointer-events", "none");
+                        selection.attr('pointer-events', 'none');
                         return;
                     }
                     var contextMenuFunction = scene.contextmenu.getMenu(getContextMenu(d.node, sceneElement));
-                    selection.on("dblclick", function (d) {
-                        sceneElement.fire("node-toggle-expand", { name: d.node.name });
+                    selection
+                        .on('dblclick', function (d) {
+                        sceneElement.fire('node-toggle-expand', { name: d.node.name });
                     })
-                        .on("mouseover", function (d) {
+                        .on('mouseover', function (d) {
                         // don't send mouseover over expanded group,
                         // otherwise it is causing too much glitches
                         if (sceneElement.isNodeExpanded(d)) {
                             return;
                         }
-                        sceneElement.fire("node-highlight", { name: d.node.name });
+                        sceneElement.fire('node-highlight', { name: d.node.name });
                     })
-                        .on("mouseout", function (d) {
+                        .on('mouseout', function (d) {
                         // don't send mouseover over expanded group,
                         // otherwise it is causing too much glitches
                         if (sceneElement.isNodeExpanded(d)) {
                             return;
                         }
-                        sceneElement.fire("node-unhighlight", { name: d.node.name });
+                        sceneElement.fire('node-unhighlight', { name: d.node.name });
                     })
-                        .on("click", function (d) {
+                        .on('click', function (d) {
                         // Stop this event's propagation so that it isn't also considered
                         // a graph-select.
                         d3.event.stopPropagation();
-                        sceneElement.fire("node-select", { name: d.node.name });
+                        sceneElement.fire('node-select', { name: d.node.name });
                     })
-                        .on("contextmenu", function (d, i) {
-                        sceneElement.fire("node-select", { name: d.node.name });
+                        .on('contextmenu', function (d, i) {
+                        sceneElement.fire('node-select', { name: d.node.name });
                         contextMenuFunction.call(d, i);
                     });
                 }
@@ -7672,20 +8052,16 @@
                  */
                 function getContextMenu(node, sceneElement) {
                     var menu = [{
-                            title: function (d) {
-                                return graph.getIncludeNodeButtonString(node.include);
-                            },
+                            title: function (d) { return graph.getIncludeNodeButtonString(node.include); },
                             action: function (elm, d, i) {
-                                sceneElement.fire("node-toggle-extract", { name: node.name });
+                                sceneElement.fire('node-toggle-extract', { name: node.name });
                             }
                         }];
                     if (canBeInSeries(node)) {
                         menu.push({
-                            title: function (d) {
-                                return getGroupSettingLabel(node);
-                            },
+                            title: function (d) { return getGroupSettingLabel(node); },
                             action: function (elm, d, i) {
-                                sceneElement.fire("node-toggle-seriesgroup", { name: getSeriesName(node) });
+                                sceneElement.fire('node-toggle-seriesgroup', { name: getSeriesName(node) });
                             }
                         });
                     }
@@ -7749,23 +8125,22 @@
                  * @param sceneElement <tf-graph-scene> polymer element.
                  */
                 function labelBuild(nodeGroup, renderNodeInfo, sceneElement) {
-                    var namePath = renderNodeInfo.node.name.split("/");
+                    var namePath = renderNodeInfo.node.name.split('/');
                     var text = namePath[namePath.length - 1];
                     // Truncate long labels for unexpanded Metanodes.
                     var useFontScale = renderNodeInfo.node.type === graph.NodeType.META &&
                         !renderNodeInfo.expanded;
-                    var label = scene.selectOrCreateChild(nodeGroup, "text", scene.Class.Node.LABEL);
+                    var label = scene.selectOrCreateChild(nodeGroup, 'text', scene.Class.Node.LABEL);
                     // Make sure the label is visually on top among its siblings.
                     var labelNode = label.node();
                     labelNode.parentNode.appendChild(labelNode);
-                    label.attr("dy", ".35em")
-                        .attr("text-anchor", "middle");
+                    label.attr('dy', '.35em').attr('text-anchor', 'middle');
                     if (useFontScale) {
                         if (text.length > sceneElement.maxMetanodeLabelLength) {
-                            text = text.substr(0, sceneElement.maxMetanodeLabelLength - 2) + "...";
+                            text = text.substr(0, sceneElement.maxMetanodeLabelLength - 2) + '...';
                         }
                         var scale = getLabelFontScale(sceneElement);
-                        label.attr("font-size", scale(text.length) + "px");
+                        label.attr('font-size', scale(text.length) + 'px');
                     }
                     label.text(text);
                     return label;
@@ -7790,9 +8165,10 @@
                  * Set label position of a given node group
                  */
                 function labelPosition(nodeGroup, cx, cy, yOffset) {
-                    scene.selectChild(nodeGroup, "text", scene.Class.Node.LABEL).transition()
-                        .attr("x", cx)
-                        .attr("y", cy + yOffset);
+                    scene.selectChild(nodeGroup, 'text', scene.Class.Node.LABEL)
+                        .transition()
+                        .attr('x', cx)
+                        .attr('y', cy + yOffset);
                 }
                 ;
                 /**
@@ -7806,35 +8182,35 @@
                  */
                 function buildShape(nodeGroup, d, nodeClass) {
                     // Create a group to house the underlying visual elements.
-                    var shapeGroup = scene.selectOrCreateChild(nodeGroup, "g", nodeClass);
+                    var shapeGroup = scene.selectOrCreateChild(nodeGroup, 'g', nodeClass);
                     // TODO(jimbo): DOM structure should be templated in HTML somewhere, not JS.
                     switch (d.node.type) {
                         case graph.NodeType.OP:
-                            scene.selectOrCreateChild(shapeGroup, "ellipse", scene.Class.Node.COLOR_TARGET);
+                            scene.selectOrCreateChild(shapeGroup, 'ellipse', scene.Class.Node.COLOR_TARGET);
                             break;
                         case graph.NodeType.SERIES:
                             // Choose the correct stamp to use to represent this series.
-                            var stampType = "annotation";
+                            var stampType = 'annotation';
                             var groupNodeInfo = d;
                             if (groupNodeInfo.coreGraph) {
-                                stampType = groupNodeInfo.node.hasNonControlEdges
-                                    ? "vertical" : "horizontal";
+                                stampType =
+                                    groupNodeInfo.node.hasNonControlEdges ? 'vertical' : 'horizontal';
                             }
-                            scene.selectOrCreateChild(shapeGroup, "use", scene.Class.Node.COLOR_TARGET)
-                                .attr("xlink:href", "#op-series-" + stampType + "-stamp");
-                            scene.selectOrCreateChild(shapeGroup, "rect", scene.Class.Node.COLOR_TARGET)
+                            scene.selectOrCreateChild(shapeGroup, 'use', scene.Class.Node.COLOR_TARGET)
+                                .attr('xlink:href', '#op-series-' + stampType + '-stamp');
+                            scene.selectOrCreateChild(shapeGroup, 'rect', scene.Class.Node.COLOR_TARGET)
                                 .attr({ rx: d.radius, ry: d.radius });
                             break;
                         case graph.NodeType.BRIDGE:
-                            scene.selectOrCreateChild(shapeGroup, "rect", scene.Class.Node.COLOR_TARGET)
+                            scene.selectOrCreateChild(shapeGroup, 'rect', scene.Class.Node.COLOR_TARGET)
                                 .attr({ rx: d.radius, ry: d.radius });
                             break;
                         case graph.NodeType.META:
-                            scene.selectOrCreateChild(shapeGroup, "rect", scene.Class.Node.COLOR_TARGET)
+                            scene.selectOrCreateChild(shapeGroup, 'rect', scene.Class.Node.COLOR_TARGET)
                                 .attr({ rx: d.radius, ry: d.radius });
                             break;
                         default:
-                            throw Error("Unrecognized node type: " + d.node.type);
+                            throw Error('Unrecognized node type: ' + d.node.type);
                     }
                     return shapeGroup;
                 }
@@ -7854,25 +8230,25 @@
                             return scene.Class.ELLIPSISNODE;
                     }
                     ;
-                    throw Error("Unrecognized node type: " + d.node.type);
+                    throw Error('Unrecognized node type: ' + d.node.type);
                 }
                 node_1.nodeClass = nodeClass;
                 ;
                 /** Modify node and its subscene and its label's positional attributes */
                 function position(nodeGroup, d) {
-                    var shapeGroup = scene.selectChild(nodeGroup, "g", scene.Class.Node.SHAPE);
+                    var shapeGroup = scene.selectChild(nodeGroup, 'g', scene.Class.Node.SHAPE);
                     var cx = graph.layout.computeCXPositionOfNodeShape(d);
                     switch (d.node.type) {
                         case graph.NodeType.OP: {
                             // position shape
-                            var shape = scene.selectChild(shapeGroup, "ellipse");
+                            var shape = scene.selectChild(shapeGroup, 'ellipse');
                             scene.positionEllipse(shape, cx, d.y, d.coreBox.width, d.coreBox.height);
                             labelPosition(nodeGroup, cx, d.y, d.labelOffset);
                             break;
                         }
                         case graph.NodeType.META: {
                             // position shape
-                            var shape = scene.selectChild(shapeGroup, "rect");
+                            var shape = scene.selectChild(shapeGroup, 'rect');
                             if (d.expanded) {
                                 scene.positionRect(shape, d.x, d.y, d.width, d.height);
                                 subscenePosition(nodeGroup, d);
@@ -7886,7 +8262,7 @@
                             break;
                         }
                         case graph.NodeType.SERIES: {
-                            var shape = scene.selectChild(shapeGroup, "use");
+                            var shape = scene.selectChild(shapeGroup, 'use');
                             if (d.expanded) {
                                 scene.positionRect(shape, d.x, d.y, d.width, d.height);
                                 subscenePosition(nodeGroup, d);
@@ -7903,12 +8279,12 @@
                             // position shape
                             // NOTE: In reality, these will not be visible, but it helps to put them
                             // in the correct position for debugging purposes.
-                            var shape = scene.selectChild(shapeGroup, "rect");
+                            var shape = scene.selectChild(shapeGroup, 'rect');
                             scene.positionRect(shape, d.x, d.y, d.width, d.height);
                             break;
                         }
                         default: {
-                            throw Error("Unrecognized node type: " + d.node.type);
+                            throw Error('Unrecognized node type: ' + d.node.type);
                         }
                     }
                 }
@@ -7923,7 +8299,7 @@
                 var ColorBy = node_1.ColorBy;
                 ;
                 /**
-                 * Returns the fill color for the node given its state and the "color by"
+                 * Returns the fill color for the node given its state and the 'color by'
                  * option.
                  */
                 function getFillForNode(templateIndex, colorBy, renderInfo, isExpanded) {
@@ -7940,15 +8316,16 @@
                                 // If expanded, we're showing the background rect, which we want to
                                 // appear gray. Otherwise we're showing a stack of ellipses which we
                                 // want to show white.
-                                return isExpanded ? colorParams.EXPANDED_COLOR : "white";
+                                return isExpanded ? colorParams.EXPANDED_COLOR : 'white';
                             }
                             else if (renderInfo.node.type === graph.NodeType.BRIDGE) {
-                                return renderInfo.structural ? "#f0e" :
-                                    renderInfo.node.inbound ? "#0ef" : "#fe0";
+                                return renderInfo.structural ?
+                                    '#f0e' :
+                                    renderInfo.node.inbound ? '#0ef' : '#fe0';
                             }
                             else {
                                 // Op nodes are white.
-                                return "white";
+                                return 'white';
                             }
                         case ColorBy.DEVICE:
                             if (renderInfo.deviceColors == null) {
@@ -7956,24 +8333,24 @@
                                 return colorParams.UNKNOWN;
                             }
                             var id = renderInfo.node.name;
-                            var escapedId = tf.escapeQuerySelector(id);
-                            var gradientDefs = d3.select("svg#svg defs #linearGradients");
-                            var linearGradient_1 = gradientDefs.select("linearGradient#" + escapedId);
+                            var escapedId = tf.graph.util.escapeQuerySelector(id);
+                            var gradientDefs = d3.select('svg#svg defs #linearGradients');
+                            var linearGradient_1 = gradientDefs.select('linearGradient#' + escapedId);
                             // If the linear gradient is not there yet, create it.
                             if (linearGradient_1.size() === 0) {
-                                linearGradient_1 = gradientDefs.append("linearGradient").attr("id", id);
+                                linearGradient_1 = gradientDefs.append('linearGradient').attr('id', id);
                                 // Re-create the stops of the linear gradient.
-                                linearGradient_1.selectAll("*").remove();
+                                linearGradient_1.selectAll('*').remove();
                                 var cumulativeProportion_1 = 0;
                                 // For each device, create a stop using the proportion of that device.
                                 _.each(renderInfo.deviceColors, function (d) {
                                     var color = d.color;
-                                    linearGradient_1.append("stop")
-                                        .attr("offset", cumulativeProportion_1)
-                                        .attr("stop-color", color);
-                                    linearGradient_1.append("stop")
-                                        .attr("offset", cumulativeProportion_1 + d.proportion)
-                                        .attr("stop-color", color);
+                                    linearGradient_1.append('stop')
+                                        .attr('offset', cumulativeProportion_1)
+                                        .attr('stop-color', color);
+                                    linearGradient_1.append('stop')
+                                        .attr('offset', cumulativeProportion_1 + d.proportion)
+                                        .attr('stop-color', color);
                                     cumulativeProportion_1 += d.proportion;
                                 });
                             }
@@ -7987,7 +8364,7 @@
                                 colorParams.EXPANDED_COLOR : renderInfo.memoryColor ||
                                 colorParams.UNKNOWN;
                         default:
-                            throw new Error("Unknown case to color nodes by");
+                            throw new Error('Unknown case to color nodes by');
                     }
                 }
                 node_1.getFillForNode = getFillForNode;
@@ -8001,18 +8378,18 @@
                     var isSelected = sceneElement.isNodeSelected(renderInfo.node.name);
                     var isExtract = renderInfo.isInExtract || renderInfo.isOutExtract;
                     var isExpanded = renderInfo.expanded;
-                    nodeGroup.classed("highlighted", isHighlighted);
-                    nodeGroup.classed("selected", isSelected);
-                    nodeGroup.classed("extract", isExtract);
-                    nodeGroup.classed("expanded", isExpanded);
+                    nodeGroup.classed('highlighted', isHighlighted);
+                    nodeGroup.classed('selected', isSelected);
+                    nodeGroup.classed('extract', isExtract);
+                    nodeGroup.classed('expanded', isExpanded);
                     // Main node always exists here and it will be reached before subscene,
                     // so d3 selection is fine here.
-                    var node = nodeGroup.select("." + nodeClass + " ." + scene.Class.Node.COLOR_TARGET);
+                    var node = nodeGroup.select('.' + nodeClass + ' .' + scene.Class.Node.COLOR_TARGET);
                     var fillColor = getFillForNode(sceneElement.templateIndex, ColorBy[sceneElement.colorBy.toUpperCase()], renderInfo, isExpanded);
-                    node.style("fill", fillColor);
+                    node.style('fill', fillColor);
                     // Choose outline to be darker version of node color if the node is a single
                     // color and is not selected.
-                    node.style("stroke", isSelected ? null : getStrokeForFill(fillColor));
+                    node.style('stroke', isSelected ? null : getStrokeForFill(fillColor));
                 }
                 node_1.stylize = stylize;
                 ;
@@ -8021,7 +8398,7 @@
                  */
                 function getStrokeForFill(fill) {
                     // If node is colored by a gradient, then use a dark gray outline.
-                    return fill.substring(0, 3) === "url" ?
+                    return fill.substring(0, 3) === 'url' ?
                         graph.render.MetanodeColors.GRADIENT_OUTLINE :
                         d3.rgb(fill).darker().toString();
                 }
@@ -8033,14 +8410,14 @@
 </script>
 <script>/* Copyright 2015 Google Inc. All Rights Reserved.
 
-Licensed under the Apache License, Version 2.0 (the "License");
+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,
+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.
@@ -8051,63 +8428,416 @@
     (function (graph) {
         var scene;
         (function (scene) {
-            var contextmenu;
-            (function (contextmenu) {
-                /**
-                 * Returns the event listener, which can be used as an argument for the d3
-                 * selection.on function. Renders the context menu that is to be displayed
-                 * in response to the event.
-                 */
-                function getMenu(menu) {
-                    var menuSelection = d3.select(".context-menu");
-                    // Close the menu when anything else is clicked.
-                    d3.select("body").on("click.context", function () {
-                        menuSelection.style("display", "none");
-                    });
-                    // Function called to populate the context menu.
-                    return function (data, index) {
-                        var _this = this;
-                        // Position and display the menu.
-                        var event = d3.event;
-                        menuSelection.style({
-                            "display": "block",
-                            "left": (event.layerX + 1) + "px",
-                            "top": (event.layerY + 1) + "px"
-                        });
-                        // Stop the event from propagating further.
-                        event.preventDefault();
-                        event.stopPropagation();
-                        // Add provided items to the context menu.
-                        menuSelection.html("");
-                        var list = menuSelection.append("ul");
-                        list.selectAll("li").data(menu).enter()
-                            .append("li")
-                            .html(function (d) {
-                            return d.title(data);
-                        })
-                            .on("click", function (d, i) {
-                            d.action(_this, data, index);
-                            menuSelection.style("display", "none");
-                        });
-                    };
+            /** Enums element class of objects in the scene */
+            scene.Class = {
+                Node: {
+                    // <g> element that contains nodes.
+                    CONTAINER: 'nodes',
+                    // <g> element that contains detail about a node.
+                    GROUP: 'node',
+                    // <g> element that contains visual elements (like rect, ellipse).
+                    SHAPE: 'nodeshape',
+                    // <*> element(s) under SHAPE that should receive color updates.
+                    COLOR_TARGET: 'nodecolortarget',
+                    // <text> element showing the node's label.
+                    LABEL: 'nodelabel',
+                    // <g> element that contains all visuals for the expand/collapse
+                    // button for expandable group nodes.
+                    BUTTON_CONTAINER: 'buttoncontainer',
+                    // <circle> element that surrounds expand/collapse buttons.
+                    BUTTON_CIRCLE: 'buttoncircle',
+                    // <path> element of the expand button.
+                    EXPAND_BUTTON: 'expandbutton',
+                    // <path> element of the collapse button.
+                    COLLAPSE_BUTTON: 'collapsebutton'
+                },
+                Edge: {
+                    CONTAINER: 'edges',
+                    GROUP: 'edge',
+                    LINE: 'edgeline',
+                    REF_LINE: 'refline',
+                    STRUCTURAL: 'structural'
+                },
+                Annotation: {
+                    OUTBOX: 'out-annotations',
+                    INBOX: 'in-annotations',
+                    GROUP: 'annotation',
+                    NODE: 'annotation-node',
+                    EDGE: 'annotation-edge',
+                    CONTROL_EDGE: 'annotation-control-edge',
+                    LABEL: 'annotation-label',
+                    ELLIPSIS: 'annotation-ellipsis'
+                },
+                Scene: {
+                    GROUP: 'scene',
+                    CORE: 'core',
+                    INEXTRACT: 'in-extract',
+                    OUTEXTRACT: 'out-extract'
+                },
+                Subscene: { GROUP: 'subscene' },
+                OPNODE: 'op',
+                METANODE: 'meta',
+                SERIESNODE: 'series',
+                BRIDGENODE: 'bridge',
+                ELLIPSISNODE: 'ellipsis'
+            };
+            /**
+             * Helper method for fitting the graph in the svg view.
+             *
+             * @param svg The main svg.
+             * @param zoomG The svg group used for panning and zooming.
+             * @param d3zoom The zoom behavior.
+             * @param callback Called when the fitting is done.
+             */
+            function fit(svg, zoomG, d3zoom, callback) {
+                var svgRect = svg.getBoundingClientRect();
+                var sceneSize = null;
+                try {
+                    sceneSize = zoomG.getBBox();
+                    if (sceneSize.width === 0) {
+                        // There is no scene anymore. We have been detached from the dom.
+                        return;
+                    }
                 }
-                contextmenu.getMenu = getMenu;
-                ;
-            })(contextmenu = scene.contextmenu || (scene.contextmenu = {}));
+                catch (e) {
+                    // Firefox produced NS_ERROR_FAILURE if we have been
+                    // detached from the dom.
+                    return;
+                }
+                var scale = 0.9 * Math.min(svgRect.width / sceneSize.width, svgRect.height / sceneSize.height, 2);
+                var params = graph.layout.PARAMS.graph;
+                var zoomEvent = d3zoom.scale(scale)
+                    .on('zoomend.fitted', function () {
+                    // Remove the listener for the zoomend event,
+                    // so we don't get called at the end of regular zoom events,
+                    // just those that fit the graph to screen.
+                    d3zoom.on('zoomend.fitted', null);
+                    callback();
+                })
+                    .translate([params.padding.paddingLeft, params.padding.paddingTop])
+                    .event;
+                d3.select(zoomG).transition().duration(500).call(zoomEvent);
+            }
+            scene.fit = fit;
+            ;
+            /**
+             * Helper method for panning the graph to center on the provided node,
+             * if the node is currently off-screen.
+             *
+             * @param nodeName The node to center the graph on
+             * @param svg The root SVG element for the graph
+             * @param zoomG The svg group used for panning and zooming.
+             * @param d3zoom The zoom behavior.
+             * @return True if the graph had to be panned to display the
+             *            provided node.
+             */
+            function panToNode(nodeName, svg, zoomG, d3zoom) {
+                var node = d3
+                    .select('[data-name="' + nodeName + '"].' + scene.Class.Node.GROUP)
+                    .node();
+                if (!node) {
+                    return false;
+                }
+                var translate = d3zoom.translate();
+                // Check if the selected node is off-screen in either
+                // X or Y dimension in either direction.
+                var nodeBox = node.getBBox();
+                var nodeCtm = node.getScreenCTM();
+                var pointTL = svg.createSVGPoint();
+                var pointBR = svg.createSVGPoint();
+                pointTL.x = nodeBox.x;
+                pointTL.y = nodeBox.y;
+                pointBR.x = nodeBox.x + nodeBox.width;
+                pointBR.y = nodeBox.y + nodeBox.height;
+                pointTL = pointTL.matrixTransform(nodeCtm);
+                pointBR = pointBR.matrixTransform(nodeCtm);
+                var isOutsideOfBounds = function (start, end, bound) {
+                    return end < 0 || start > bound;
+                };
+                var svgRect = svg.getBoundingClientRect();
+                if (isOutsideOfBounds(pointTL.x, pointBR.x, svgRect.width) ||
+                    isOutsideOfBounds(pointTL.y, pointBR.y, svgRect.height)) {
+                    // Determine the amount to transform the graph in both X and Y
+                    // dimensions in order to center the selected node. This takes into
+                    // acount the position of the node, the size of the svg scene, the
+                    // amount the scene has been scaled by through zooming, and any previous
+                    // transform already performed by this logic.
+                    var centerX = (pointTL.x + pointBR.x) / 2;
+                    var centerY = (pointTL.y + pointBR.y) / 2;
+                    var dx = ((svgRect.width / 2) - centerX);
+                    var dy = ((svgRect.height / 2) - centerY);
+                    var zoomEvent = d3zoom.translate([translate[0] + dx, translate[1] + dy])
+                        .event;
+                    d3.select(zoomG).transition().duration(500).call(zoomEvent);
+                    return true;
+                }
+                return false;
+            }
+            scene.panToNode = panToNode;
+            ;
+            /**
+             * Given a container d3 selection, select a child svg element of a given tag
+             * and class if exists or append / insert one otherwise.  If multiple children
+             * matches the tag and class name, returns only the first one.
+             *
+             * @param container
+             * @param tagName tag name.
+             * @param className (optional) Class name.
+             * @param before (optional) reference DOM node for insertion.
+             * @return selection of the element
+             */
+            function selectOrCreateChild(container, tagName, className, before) {
+                var child = selectChild(container, tagName, className);
+                if (!child.empty()) {
+                    return child;
+                }
+                var newElement = document.createElementNS('http://www.w3.org/2000/svg', tagName);
+                if (className) {
+                    newElement.classList.add(className);
+                }
+                if (before) {
+                    container.node().insertBefore(newElement, before);
+                }
+                else {
+                    container.node().appendChild(newElement);
+                }
+                return d3.select(newElement)
+                    .datum(container.datum());
+            }
+            scene.selectOrCreateChild = selectOrCreateChild;
+            ;
+            /**
+             * Given a container d3 selection, select a child element of a given tag and
+             * class. If multiple children matches the tag and class name, returns only
+             * the first one.
+             *
+             * @param container
+             * @param tagName tag name.
+             * @param className (optional) Class name.
+             * @return selection of the element, or an empty selection
+             */
+            function selectChild(container, tagName, className) {
+                var children = container.node().childNodes;
+                for (var i = 0; i < children.length; i++) {
+                    var child = children[i];
+                    if (child.tagName === tagName &&
+                        (!className || child.classList.contains(className))) {
+                        return d3.select(child);
+                    }
+                }
+                return d3.select(null);
+            }
+            scene.selectChild = selectChild;
+            ;
+            /**
+             * Select or create a sceneGroup and build/update its nodes and edges.
+             *
+             * Structure Pattern:
+             *
+             * <g class='scene'>
+             *   <g class='core'>
+             *     <g class='edges'>
+             *       ... stuff from tf.graph.scene.edges.build ...
+             *     </g>
+             *     <g class='nodes'>
+             *       ... stuff from tf.graph.scene.nodes.build ...
+             *     </g>
+             *   </g>
+             *   <g class='in-extract'>
+             *     <g class='nodes'>
+             *       ... stuff from tf.graph.scene.nodes.build ...
+             *     </g>
+             *   </g>
+             *   <g class='out-extract'>
+             *     <g class='nodes'>
+             *       ... stuff from tf.graph.scene.nodes.build ...
+             *     </g>
+             *   </g>
+             * </g>
+             *
+             * @param container D3 selection of the parent.
+             * @param renderNode render node of a metanode or series node.
+             * @param sceneElement <tf-graph-scene> polymer element.
+             * @param sceneClass class attribute of the scene (default='scene').
+             */
+            function buildGroup(container, renderNode, sceneElement, sceneClass) {
+                sceneClass = sceneClass || scene.Class.Scene.GROUP;
+                var isNewSceneGroup = selectChild(container, 'g', sceneClass).empty();
+                var sceneGroup = selectOrCreateChild(container, 'g', sceneClass);
+                // core
+                var coreGroup = selectOrCreateChild(sceneGroup, 'g', scene.Class.Scene.CORE);
+                var coreNodes = _.reduce(renderNode.coreGraph.nodes(), function (nodes, name) {
+                    var node = renderNode.coreGraph.node(name);
+                    if (!node.excluded) {
+                        nodes.push(node);
+                    }
+                    return nodes;
+                }, []);
+                if (renderNode.node.type === graph.NodeType.SERIES) {
+                    // For series, we want the first item on top, so reverse the array so
+                    // the first item in the series becomes last item in the top, and thus
+                    // is rendered on the top.
+                    coreNodes.reverse();
+                }
+                // Create the layer of edges for this scene (paths).
+                scene.edge.buildGroup(coreGroup, renderNode.coreGraph, sceneElement);
+                // Create the layer of nodes for this scene (ellipses, rects etc).
+                scene.node.buildGroup(coreGroup, coreNodes, sceneElement);
+                // In-extract
+                if (renderNode.isolatedInExtract.length > 0) {
+                    var inExtractGroup = selectOrCreateChild(sceneGroup, 'g', scene.Class.Scene.INEXTRACT);
+                    scene.node.buildGroup(inExtractGroup, renderNode.isolatedInExtract, sceneElement);
+                }
+                else {
+                    selectChild(sceneGroup, 'g', scene.Class.Scene.INEXTRACT).remove();
+                }
+                // Out-extract
+                if (renderNode.isolatedOutExtract.length > 0) {
+                    var outExtractGroup = selectOrCreateChild(sceneGroup, 'g', scene.Class.Scene.OUTEXTRACT);
+                    scene.node.buildGroup(outExtractGroup, renderNode.isolatedOutExtract, sceneElement);
+                }
+                else {
+                    selectChild(sceneGroup, 'g', scene.Class.Scene.OUTEXTRACT).remove();
+                }
+                position(sceneGroup, renderNode);
+                // Fade in the scene group if it didn't already exist.
+                if (isNewSceneGroup) {
+                    sceneGroup.attr('opacity', 0).transition().attr('opacity', 1);
+                }
+                return sceneGroup;
+            }
+            scene.buildGroup = buildGroup;
+            ;
+            /**
+             * Given a scene's svg group, set  g.in-extract, g.coreGraph, g.out-extract svg
+             * groups' position relative to the scene.
+             *
+             * @param sceneGroup
+             * @param renderNode render node of a metanode or series node.
+             */
+            function position(sceneGroup, renderNode) {
+                // Translate scenes down by the label height so that when showing graphs in
+                // expanded metanodes, the graphs are below the labels.  Do not shift them
+                // down for series nodes as series nodes don't have labels inside of their
+                // bounding boxes.
+                var yTranslate = renderNode.node.type === graph.NodeType.SERIES ?
+                    0 : graph.layout.PARAMS.subscene.meta.labelHeight;
+                // core
+                translate(selectChild(sceneGroup, 'g', scene.Class.Scene.CORE), 0, yTranslate);
+                // in-extract
+                var hasInExtract = renderNode.isolatedInExtract.length > 0;
+                var hasOutExtract = renderNode.isolatedOutExtract.length > 0;
+                if (hasInExtract) {
+                    var offset = graph.layout.PARAMS.subscene.meta.extractXOffset;
+                    var inExtractX = renderNode.coreBox.width -
+                        renderNode.inExtractBox.width / 2 - renderNode.outExtractBox.width -
+                        (hasOutExtract ? offset : 0);
+                    translate(selectChild(sceneGroup, 'g', scene.Class.Scene.INEXTRACT), inExtractX, yTranslate);
+                }
+                // out-extract
+                if (hasOutExtract) {
+                    var outExtractX = renderNode.coreBox.width -
+                        renderNode.outExtractBox.width / 2;
+                    translate(selectChild(sceneGroup, 'g', scene.Class.Scene.OUTEXTRACT), outExtractX, yTranslate);
+                }
+            }
+            ;
+            /** Adds a click listener to a group that fires a graph-select event */
+            function addGraphClickListener(graphGroup, sceneElement) {
+                d3.select(graphGroup).on('click', function () {
+                    sceneElement.fire('graph-select');
+                });
+            }
+            scene.addGraphClickListener = addGraphClickListener;
+            ;
+            /** Helper for adding transform: translate(x0, y0) */
+            function translate(selection, x0, y0) {
+                // If it is already placed on the screen, make it a transition.
+                if (selection.attr('transform') != null) {
+                    selection = selection.transition('position');
+                }
+                selection.attr('transform', 'translate(' + x0 + ',' + y0 + ')');
+            }
+            scene.translate = translate;
+            ;
+            /**
+             * Helper for setting position of a svg rect
+             * @param rect rect to set position of.
+             * @param cx Center x.
+             * @param cy Center x.
+             * @param width Width to set.
+             * @param height Height to set.
+             */
+            function positionRect(rect, cx, cy, width, height) {
+                rect.transition().attr({
+                    x: cx - width / 2,
+                    y: cy - height / 2,
+                    width: width,
+                    height: height
+                });
+            }
+            scene.positionRect = positionRect;
+            ;
+            /**
+             * Helper for setting position of a svg expand/collapse button
+             * @param button container group
+             * @param renderNode the render node of the group node to position
+             *        the button on.
+             */
+            function positionButton(button, renderNode) {
+                var cx = graph.layout.computeCXPositionOfNodeShape(renderNode);
+                // Position the button in the top-right corner of the group node,
+                // with space given the draw the button inside of the corner.
+                var width = renderNode.expanded ?
+                    renderNode.width : renderNode.coreBox.width;
+                var height = renderNode.expanded ?
+                    renderNode.height : renderNode.coreBox.height;
+                var x = cx + width / 2 - 6;
+                var y = renderNode.y - height / 2 + 6;
+                // For unexpanded series nodes, the button has special placement due
+                // to the unique visuals of this group node.
+                if (renderNode.node.type === graph.NodeType.SERIES && !renderNode.expanded) {
+                    x += 10;
+                    y -= 2;
+                }
+                var translateStr = 'translate(' + x + ',' + y + ')';
+                button.selectAll('path').transition().attr('transform', translateStr);
+                button.select('circle').transition().attr({ cx: x, cy: y, r: graph.layout.PARAMS.nodeSize.meta.expandButtonRadius });
+            }
+            scene.positionButton = positionButton;
+            ;
+            /**
+             * Helper for setting position of a svg ellipse
+             * @param ellipse ellipse to set position of.
+             * @param cx Center x.
+             * @param cy Center x.
+             * @param width Width to set.
+             * @param height Height to set.
+             */
+            function positionEllipse(ellipse, cx, cy, width, height) {
+                ellipse.transition().attr({
+                    cx: cx,
+                    cy: cy,
+                    rx: width / 2,
+                    ry: height / 2
+                });
+            }
+            scene.positionEllipse = positionEllipse;
+            ;
         })(scene = graph.scene || (graph.scene = {}));
     })(graph = tf.graph || (tf.graph = {}));
 })(tf || (tf = {})); // close module
 </script>
 <script>/* Copyright 2015 Google Inc. All Rights Reserved.
 
-Licensed under the Apache License, Version 2.0 (the "License");
+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,
+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.
@@ -8116,843 +8846,415 @@
 (function (tf) {
     var graph;
     (function (graph_1) {
-        var layout;
-        (function (layout) {
-            /** Set of parameters that define the look and feel of the graph. */
-            layout.PARAMS = {
-                animation: {
-                    /** Default duration for graph animations in ms. */
-                    duration: 250
-                },
-                graph: {
-                    /** Graph parameter for metanode. */
-                    meta: {
-                        /**
-                         * Dagre's nodesep param - number of pixels that
-                         * separate nodes horizontally in the layout.
-                         *
-                         * See https://github.com/cpettitt/dagre/wiki#configuring-the-layout
-                         */
-                        nodeSep: 5,
-                        /**
-                         * Dagre's ranksep param - number of pixels
-                         * between each rank in the layout.
-                         *
-                         * See https://github.com/cpettitt/dagre/wiki#configuring-the-layout
-                         */
-                        rankSep: 25,
-                        /**
-                         * Dagre's edgesep param - number of pixels that separate
-                         * edges horizontally in the layout.
-                         */
-                        edgeSep: 5,
-                    },
-                    /** Graph parameter for metanode. */
-                    series: {
-                        /**
-                         * Dagre's nodesep param - number of pixels that
-                         * separate nodes horizontally in the layout.
-                         *
-                         * See https://github.com/cpettitt/dagre/wiki#configuring-the-layout
-                         */
-                        nodeSep: 5,
-                        /**
-                         * Dagre's ranksep param - number of pixels
-                         * between each rank in the layout.
-                         *
-                         * See https://github.com/cpettitt/dagre/wiki#configuring-the-layout
-                         */
-                        rankSep: 25,
-                        /**
-                         * Dagre's edgesep param - number of pixels that separate
-                         * edges horizontally in the layout.
-                         */
-                        edgeSep: 5
-                    },
-                    /**
-                     * Padding is used to correctly position the graph SVG inside of its parent
-                     * element. The padding amounts are applied using an SVG transform of X and
-                     * Y coordinates.
-                     */
-                    padding: {
-                        paddingTop: 40,
-                        paddingLeft: 20
-                    }
-                },
-                subscene: {
-                    meta: {
-                        paddingTop: 10,
-                        paddingBottom: 10,
-                        paddingLeft: 10,
-                        paddingRight: 10,
-                        /**
-                         * Used to leave room for the label on top of the highest node in
-                         * the core graph.
-                         */
-                        labelHeight: 20,
-                        /** X-space between each extracted node and the core graph. */
-                        extractXOffset: 15,
-                        /** Y-space between each extracted node. */
-                        extractYOffset: 20
-                    },
-                    series: {
-                        paddingTop: 10,
-                        paddingBottom: 10,
-                        paddingLeft: 10,
-                        paddingRight: 10,
-                        labelHeight: 10
-                    }
-                },
-                nodeSize: {
-                    /** Size of meta nodes. */
-                    meta: {
-                        radius: 5,
-                        width: 60,
-                        /** A scale for the node's height based on number of nodes inside */
-                        height: d3.scale.linear().domain([1, 200]).range([15, 60]).clamp(true),
-                        /** The radius of the circle denoting the expand button. */
-                        expandButtonRadius: 3
-                    },
-                    /** Size of op nodes. */
-                    op: {
-                        width: 15,
-                        height: 6,
-                        radius: 3,
-                        labelOffset: -8
-                    },
-                    /** Size of series nodes. */
-                    series: {
-                        expanded: {
-                            // For expanded series nodes, width and height will be
-                            // computed to account for the subscene.
-                            radius: 10,
-                            labelOffset: 0,
-                        },
-                        vertical: {
-                            // When unexpanded, series whose underlying metagraphs contain
-                            // one or more non-control edges will show as a vertical stack
-                            // of ellipses.
-                            width: 16,
-                            height: 13,
-                            labelOffset: -13,
-                        },
-                        horizontal: {
-                            // When unexpanded, series whose underlying metagraphs contain
-                            // no non-control edges will show as a horizontal stack of
-                            // ellipses.
-                            width: 24,
-                            height: 8,
-                            radius: 10,
-                            labelOffset: -10,
-                        },
-                    },
-                    /** Size of bridge nodes. */
-                    bridge: {
-                        // NOTE: bridge nodes will normally be invisible, but they must
-                        // take up some space so that the layout step leaves room for
-                        // their edges.
-                        width: 20,
-                        height: 20,
-                        radius: 2,
-                        labelOffset: 0
-                    }
-                },
-                shortcutSize: {
-                    /** Size of shortcuts for op nodes */
-                    op: {
-                        width: 10,
-                        height: 4
-                    },
-                    /** Size of shortcuts for meta nodes */
-                    meta: {
-                        width: 12,
-                        height: 4,
-                        radius: 1
-                    },
-                    /** Size of shortcuts for series nodes */
-                    series: {
-                        width: 14,
-                        height: 4,
-                    }
-                },
-                annotations: {
-                    /** Maximum possible width of the bounding box for in annotations */
-                    inboxWidth: 50,
-                    /** Maximum possible width of the bounding box for out annotations */
-                    outboxWidth: 50,
-                    /** X-space between the shape and each annotation-node. */
-                    xOffset: 10,
-                    /** Y-space between each annotation-node. */
-                    yOffset: 3,
-                    /** X-space between each annotation-node and its label. */
-                    labelOffset: 2,
-                    /** Estimate max width for annotation label */
-                    labelWidth: 35
-                },
-                constant: {
-                    size: {
-                        width: 4,
-                        height: 4
-                    }
-                },
-                series: {
-                    /** Maximum number of repeated item for unexpanded series node. */
-                    maxStackCount: 3,
-                    /**
-                     * Positioning offset ratio for collapsed stack
-                     * of parallel series (series without edges between its members).
-                     */
-                    parallelStackOffsetRatio: 0.2,
-                    /**
-                     * Positioning offset ratio for collapsed stack
-                     * of tower series (series with edges between its members).
-                     */
-                    towerStackOffsetRatio: 0.5
-                },
-                minimap: {
-                    /** The maximum width/height the minimap can have. */
-                    size: 150
-                }
-            };
-            /** Calculate layout for a scene of a group node. */
-            function layoutScene(renderNodeInfo) {
-                // Update layout, size, and annotations of its children nodes and edges.
-                if (renderNodeInfo.node.isGroupNode) {
-                    layoutChildren(renderNodeInfo);
-                }
-                // Update position of its children nodes and edges
-                if (renderNodeInfo.node.type === graph_1.NodeType.META) {
-                    layoutMetanode(renderNodeInfo);
-                }
-                else if (renderNodeInfo.node.type === graph_1.NodeType.SERIES) {
-                    layoutSeriesNode(renderNodeInfo);
-                }
+        var template;
+        (function (template) {
+            /**
+             * Detect repeating patterns of subgraphs.
+             * Assign templateId to each subgraph if it belongs to a template.
+             * Returns clusters of similar subgraphs .
+             *
+             * @param graph
+             * @param verifyTemplate whether to run the template verification algorithm
+             * @return a dict (template id => Array of node names)
+             */
+            function detect(h, verifyTemplate) {
+                // In any particular subgraph, there are either
+                // - leaf nodes (which do not have subgraph)
+                // - metanode nodes - some of them have only one member (singular metanode)
+                //                    and some have multiple members (non-singular metanode)
+                // First, generate a nearest neighbor hash of metanode nodes.
+                var nnGroups = clusterSimilarSubgraphs(h);
+                // For each metanode, compare its subgraph (starting from shallower groups)
+                // and assign template id.
+                var templates = groupTemplateAndAssignId(nnGroups, verifyTemplate);
+                // Sort the templates by minimum level in the graph at which they appear,
+                // as this leads to optimal setting of the colors of each template for
+                // maximum differentiation.
+                return _(templates).pairs()
+                    .sortBy(function (pair) {
+                    return pair[1].level;
+                })
+                    .map(function (pair) {
+                    return [pair[0], pair[1].nodes];
+                })
+                    .object().value();
             }
-            layout.layoutScene = layoutScene;
+            template.detect = detect;
             ;
             /**
-             * Updates the total width of an unexpanded node which includes the size of its
-             * in and out annotations.
+             * @return Unique string for a metanode based on depth, |V|, |E| and
+             * op type histogram.
              */
-            function updateTotalWidthOfNode(renderInfo) {
-                renderInfo.inboxWidth = renderInfo.inAnnotations.list.length > 0 ?
-                    layout.PARAMS.annotations.inboxWidth : 0;
-                renderInfo.outboxWidth = renderInfo.outAnnotations.list.length > 0 ?
-                    layout.PARAMS.annotations.outboxWidth : 0;
-                // Assign the width of the core box (the main shape of the node).
-                renderInfo.coreBox.width = renderInfo.width;
-                renderInfo.coreBox.height = renderInfo.height;
-                // TODO(jimbo): Account for font width rather than using a magic number.
-                var labelLength = renderInfo.node.name.length -
-                    renderInfo.node.name.lastIndexOf(graph_1.NAMESPACE_DELIM) - 1;
-                var charWidth = 3; // 3 pixels per character.
-                // Compute the total width of the node.
-                renderInfo.width = Math.max(renderInfo.coreBox.width +
-                    renderInfo.inboxWidth + renderInfo.outboxWidth, labelLength * charWidth);
+            function getSignature(metanode) {
+                // depth=<number> |V|=<number> |E|=<number>
+                var props = _.map({
+                    'depth': metanode.depth,
+                    '|V|': metanode.metagraph.nodes().length,
+                    '|E|': metanode.metagraph.edges().length
+                }, function (v, k) { return k + '=' + v; })
+                    .join(' ');
+                // optype1=count1,optype2=count2
+                var ops = _.map(metanode.opHistogram, function (count, op) {
+                    return op + '=' + count;
+                }).join(',');
+                return props + ' [ops] ' + ops;
             }
             /**
-             * Update layout, size, and annotations of its children nodes and edges.
+             * Generate a nearest neighbor hash of metanodes
+             * based on depth, |V|, |E|, and opHistogram of their subgraph
+             * (excluding leaf nodes and singular metanodes).
+             * @param graph The graph
+             * @return Array of pairs of [signature,
+             *   Object with min level of the template and an Array of tf.graph.Group]
+             *   sort by ascending order of minimum depth at which metanode appears.
              */
-            function layoutChildren(renderNodeInfo) {
-                var children = renderNodeInfo.coreGraph.nodes().map(function (n) {
-                    return renderNodeInfo.coreGraph.node(n);
-                }).concat(renderNodeInfo.isolatedInExtract, renderNodeInfo.isolatedOutExtract);
-                _.each(children, function (childNodeInfo) {
-                    // Set size of each child
-                    switch (childNodeInfo.node.type) {
-                        case graph_1.NodeType.OP:
-                            _.extend(childNodeInfo, layout.PARAMS.nodeSize.op);
-                            break;
-                        case graph_1.NodeType.BRIDGE:
-                            _.extend(childNodeInfo, layout.PARAMS.nodeSize.bridge);
-                            break;
-                        case graph_1.NodeType.META:
-                            if (!childNodeInfo.expanded) {
-                                // Set fixed width and scalable height based on cardinality
-                                _.extend(childNodeInfo, layout.PARAMS.nodeSize.meta);
-                                childNodeInfo.height =
-                                    layout.PARAMS.nodeSize.meta.height(childNodeInfo.node.cardinality);
-                            }
-                            else {
-                                var childGroupNodeInfo = childNodeInfo;
-                                layoutScene(childGroupNodeInfo); // Recursively layout its subscene.
-                            }
-                            break;
-                        case graph_1.NodeType.SERIES:
-                            if (childNodeInfo.expanded) {
-                                _.extend(childNodeInfo, layout.PARAMS.nodeSize.series.expanded);
-                                var childGroupNodeInfo = childNodeInfo;
-                                layoutScene(childGroupNodeInfo); // Recursively layout its subscene.
-                            }
-                            else {
-                                var childGroupNodeInfo = childNodeInfo;
-                                var seriesParams = childGroupNodeInfo.node.hasNonControlEdges ?
-                                    layout.PARAMS.nodeSize.series.vertical :
-                                    layout.PARAMS.nodeSize.series.horizontal;
-                                _.extend(childNodeInfo, seriesParams);
-                            }
-                            break;
-                        default:
-                            throw Error("Unrecognized node type: " + childNodeInfo.node.type);
+            function clusterSimilarSubgraphs(h) {
+                /** a dict from metanode.signature() => Array of tf.graph.Groups */
+                var hashDict = _(h.getNodeMap()).reduce(function (hash, node, name) {
+                    if (node.type !== graph_1.NodeType.META) {
+                        return hash;
                     }
-                    // Compute total width of un-expanded nodes. Width of expanded nodes
-                    // has already been computed.
-                    if (!childNodeInfo.expanded) {
-                        updateTotalWidthOfNode(childNodeInfo);
+                    var levelOfMetaNode = name.split('/').length - 1;
+                    var signature = getSignature(node);
+                    var templateInfo = hash[signature] ||
+                        { nodes: [], level: levelOfMetaNode };
+                    hash[signature] = templateInfo;
+                    templateInfo.nodes.push(node);
+                    if (templateInfo.level > levelOfMetaNode) {
+                        templateInfo.level = levelOfMetaNode;
                     }
-                    // Layout each child's annotations
-                    layoutAnnotation(childNodeInfo);
-                });
+                    return hash;
+                }, {});
+                return _(hashDict).pairs()
+                    .filter(function (pair) {
+                    return pair[1].nodes.length > 1;
+                })
+                    .sortBy(function (pair) {
+                    // sort by depth
+                    // (all members in the same nnGroup has equal depth)
+                    return pair[1].nodes[0].depth;
+                })
+                    .value();
             }
-            /**
-             * Calculate layout for a graph using dagre
-             * @param graph the graph to be laid out
-             * @param params layout parameters
-             * @return width and height of the core graph
-             */
-            function dagreLayout(graph, params) {
-                _.extend(graph.graph(), {
-                    nodesep: params.nodeSep,
-                    ranksep: params.rankSep,
-                    edgesep: params.edgeSep
-                });
-                var bridgeNodeNames = [];
-                var nonBridgeNodeNames = [];
-                // Split out nodes into bridge and non-bridge nodes, and calculate the total
-                // width we should use for bridge nodes.
-                _.each(graph.nodes(), function (nodeName) {
-                    var nodeInfo = graph.node(nodeName);
-                    if (nodeInfo.node.type === graph_1.NodeType.BRIDGE) {
-                        bridgeNodeNames.push(nodeName);
-                    }
-                    else {
-                        nonBridgeNodeNames.push(nodeName);
-                    }
-                });
-                // If there are no non-bridge nodes, then the graph has zero size.
-                if (!nonBridgeNodeNames.length) {
-                    return {
-                        width: 0,
-                        height: 0,
-                    };
-                }
-                dagre.layout(graph);
-                // Calculate the true bounding box of the graph by iterating over nodes and
-                // edges rather than accepting dagre's word for it. In particular, we should
-                // ignore the extra-wide bridge nodes and bridge edges, and allow for
-                // annotation boxes and labels.
-                var minX = Infinity;
-                var minY = Infinity;
-                var maxX = -Infinity;
-                var maxY = -Infinity;
-                _.each(nonBridgeNodeNames, function (nodeName) {
-                    var nodeInfo = graph.node(nodeName);
-                    var w = 0.5 * nodeInfo.width;
-                    var x1 = nodeInfo.x - w;
-                    var x2 = nodeInfo.x + w;
-                    minX = x1 < minX ? x1 : minX;
-                    maxX = x2 > maxX ? x2 : maxX;
-                    // TODO(jimbo): Account for the height of labels above op nodes here.
-                    var h = 0.5 * nodeInfo.height;
-                    var y1 = nodeInfo.y - h;
-                    var y2 = nodeInfo.y + h;
-                    minY = y1 < minY ? y1 : minY;
-                    maxY = y2 > maxY ? y2 : maxY;
-                });
-                _.each(graph.edges(), function (edgeObj) {
-                    var edgeInfo = graph.edge(edgeObj);
-                    if (edgeInfo.structural) {
-                        return; // Skip structural edges from min/max calculations.
-                    }
-                    // Since the node size passed to dagre includes the in and out
-                    // annotations, the endpoints of the edge produced by dagre may not
-                    // point to the actual node shape (rectangle, ellipse). We correct the
-                    // end-points by finding the intersection of a line between the
-                    // next-to-last (next-to-first) point and the destination (source)
-                    // rectangle.
-                    var sourceNode = graph.node(edgeInfo.metaedge.v);
-                    var destNode = graph.node(edgeInfo.metaedge.w);
-                    // Straight 3-points edges are special case, since they are curved after
-                    // our default correction. To keep them straight, we remove the mid point
-                    // and correct the first and the last point to be the center of the
-                    // source and destination node respectively.
-                    if (edgeInfo.points.length === 3 && isStraightLine(edgeInfo.points)) {
-                        if (sourceNode != null) {
-                            var cxSource = sourceNode.expanded ?
-                                sourceNode.x : computeCXPositionOfNodeShape(sourceNode);
-                            edgeInfo.points[0].x = cxSource;
+            function groupTemplateAndAssignId(nnGroups, verifyTemplate) {
+                // For each metanode, compare its subgraph (starting from shallower groups)
+                // and assign template id.
+                var result = {};
+                return _.reduce(nnGroups, function (templates, nnGroupPair) {
+                    var signature = nnGroupPair[0], nnGroup = nnGroupPair[1].nodes, clusters = [];
+                    nnGroup.forEach(function (metanode) {
+                        // check with each existing cluster
+                        for (var i = 0; i < clusters.length; i++) {
+                            var similar = !verifyTemplate ||
+                                isSimilarSubgraph(clusters[i].metanode.metagraph, metanode.metagraph);
+                            // if similar, just add this metanode to the cluster
+                            if (similar) {
+                                // get template from the first one
+                                metanode.templateId = clusters[i].metanode.templateId;
+                                clusters[i].members.push(metanode.name);
+                                return;
+                            }
                         }
-                        if (destNode != null) {
-                            var cxDest = destNode.expanded ?
-                                destNode.x : computeCXPositionOfNodeShape(destNode);
-                            edgeInfo.points[2].x = cxDest;
-                        }
-                        // Remove the middle point so the edge doesn't curve.
-                        edgeInfo.points = [edgeInfo.points[0], edgeInfo.points[1]];
-                    }
-                    // Correct the destination endpoint of the edge.
-                    var nextToLastPoint = edgeInfo.points[edgeInfo.points.length - 2];
-                    // The destination node might be null if this is a bridge edge.
-                    if (destNode != null) {
-                        edgeInfo.points[edgeInfo.points.length - 1] =
-                            intersectPointAndNode(nextToLastPoint, destNode);
-                    }
-                    // Correct the source endpoint of the edge.
-                    var secondPoint = edgeInfo.points[1];
-                    // The source might be null if this is a bridge edge.
-                    if (sourceNode != null) {
-                        edgeInfo.points[0] = intersectPointAndNode(secondPoint, sourceNode);
-                    }
-                    _.each(edgeInfo.points, function (point) {
-                        minX = point.x < minX ? point.x : minX;
-                        maxX = point.x > maxX ? point.x : maxX;
-                        minY = point.y < minY ? point.y : minY;
-                        maxY = point.y > maxY ? point.y : maxY;
+                        // otherwise create a new cluster with id 'signature [count] '
+                        metanode.templateId = signature + '[' + clusters.length + ']';
+                        clusters.push({
+                            metanode: metanode,
+                            members: [metanode.name]
+                        });
                     });
-                });
-                // Shift all nodes and edge points to account for the left-padding amount,
-                // and the invisible bridge nodes.
-                _.each(graph.nodes(), function (nodeName) {
-                    var nodeInfo = graph.node(nodeName);
-                    nodeInfo.x -= minX;
-                    nodeInfo.y -= minY;
-                });
-                _.each(graph.edges(), function (edgeObj) {
-                    _.each(graph.edge(edgeObj).points, function (point) {
-                        point.x -= minX;
-                        point.y -= minY;
+                    clusters.forEach(function (c) {
+                        templates[c.metanode.templateId] = {
+                            level: nnGroupPair[1].level,
+                            nodes: c.members
+                        };
                     });
+                    return templates;
+                }, result);
+            }
+            function sortNodes(names, graph, prefix) {
+                return _.sortByAll(names, function (name) {
+                    var node = graph.node(name);
+                    return node.op;
+                }, function (name) {
+                    var node = graph.node(name);
+                    return node.templateId;
+                }, function (name) {
+                    return graph.neighbors(name).length;
+                }, function (name) {
+                    return graph.predecessors(name).length;
+                }, function (name) {
+                    return graph.successors(name).length;
+                }, function (name) {
+                    return name.substr(prefix.length);
                 });
-                return {
-                    width: maxX - minX,
-                    height: maxY - minY
-                };
             }
-            /** Layout a metanode. Only called for an expanded node. */
-            function layoutMetanode(renderNodeInfo) {
-                // First, copy params specific to meta nodes onto this render info object.
-                var params = layout.PARAMS.subscene.meta;
-                _.extend(renderNodeInfo, params);
-                // Invoke dagre.layout() on the core graph and record the bounding box
-                // dimensions.
-                _.extend(renderNodeInfo.coreBox, dagreLayout(renderNodeInfo.coreGraph, layout.PARAMS.graph.meta));
-                // Calculate the position of nodes in isolatedInExtract relative to the
-                // top-left corner of inExtractBox (the bounding box for all inExtract nodes)
-                // and calculate the size of the inExtractBox.
-                var maxInExtractWidth = _.max(renderNodeInfo.isolatedInExtract, function (renderNode) { return renderNode.width; }).width;
-                renderNodeInfo.inExtractBox.width = maxInExtractWidth != null ?
-                    maxInExtractWidth : 0;
-                renderNodeInfo.inExtractBox.height =
-                    _.reduce(renderNodeInfo.isolatedInExtract, function (height, child, i) {
-                        var yOffset = i > 0 ? params.extractYOffset : 0;
-                        // use width/height here to avoid overlaps between extracts
-                        child.x = 0;
-                        child.y = height + yOffset + child.height / 2;
-                        return height + yOffset + child.height;
-                    }, 0);
-                // Calculate the position of nodes in isolatedOutExtract relative to the
-                // top-left corner of outExtractBox (the bounding box for all outExtract
-                // nodes) and calculate the size of the outExtractBox.
-                var maxOutExtractWidth = _.max(renderNodeInfo.isolatedOutExtract, function (renderNode) { return renderNode.width; }).width;
-                renderNodeInfo.outExtractBox.width = maxOutExtractWidth != null ?
-                    maxOutExtractWidth : 0;
-                renderNodeInfo.outExtractBox.height =
-                    _.reduce(renderNodeInfo.isolatedOutExtract, function (height, child, i) {
-                        var yOffset = i > 0 ? params.extractYOffset : 0;
-                        // use width/height here to avoid overlaps between extracts
-                        child.x = 0;
-                        child.y = height + yOffset + child.height / 2;
-                        return height + yOffset + child.height;
-                    }, 0);
-                // Compute the total padding between the core graph, in-extract and
-                // out-extract boxes.
-                var numParts = 0;
-                if (renderNodeInfo.isolatedInExtract.length > 0) {
-                    numParts++;
+            function isSimilarSubgraph(g1, g2) {
+                if (!tf.graph.hasSimilarDegreeSequence(g1, g2)) {
+                    return false;
                 }
-                if (renderNodeInfo.isolatedOutExtract.length > 0) {
-                    numParts++;
+                // if we want to skip, just return true here.
+                // return true;
+                // Verify sequence by running DFS
+                var g1prefix = g1.graph().name;
+                var g2prefix = g2.graph().name;
+                var visited1 = {};
+                var visited2 = {};
+                var stack = [];
+                /**
+                 * push sources or successors into the stack
+                 * if the visiting pattern has been similar.
+                 */
+                function stackPushIfNotDifferent(n1, n2) {
+                    var sub1 = n1.substr(g1prefix.length), sub2 = n2.substr(g2prefix.length);
+                    /* tslint:disable */
+                    if (visited1[sub1] ^ visited2[sub1]) {
+                        console.warn('different visit pattern', '[' + g1prefix + ']', sub1, '[' + g2prefix + ']', sub2);
+                        return true;
+                    }
+                    /* tslint:enable */
+                    if (!visited1[sub1]) {
+                        visited1[sub1] = visited2[sub2] = true;
+                        stack.push({ n1: n1, n2: n2 });
+                    }
+                    return false;
                 }
-                if (renderNodeInfo.coreGraph.nodeCount() > 0) {
-                    numParts++;
+                // check if have same # of sources then sort and push
+                var sources1 = g1.sources();
+                var sources2 = g2.sources();
+                if (sources1.length !== sources2.length) {
+                    /* tslint:disable */
+                    console.log('different source length');
+                    /* tslint:enable */
+                    return false;
                 }
-                var offset = layout.PARAMS.subscene.meta.extractXOffset;
-                var padding = numParts <= 1 ? 0 : (numParts <= 2 ? offset : 2 * offset);
-                // Add the in-extract and out-extract width to the core box width.
-                renderNodeInfo.coreBox.width += renderNodeInfo.inExtractBox.width +
-                    renderNodeInfo.outExtractBox.width + padding;
-                renderNodeInfo.coreBox.height =
-                    params.labelHeight +
-                        Math.max(renderNodeInfo.inExtractBox.height, renderNodeInfo.coreBox.height, renderNodeInfo.outExtractBox.height);
-                // Determine the whole metanode's width (from left to right).
-                renderNodeInfo.width = renderNodeInfo.coreBox.width +
-                    params.paddingLeft + params.paddingRight;
-                // Determine the whole metanode's height (from top to bottom).
-                renderNodeInfo.height =
-                    renderNodeInfo.paddingTop +
-                        renderNodeInfo.coreBox.height +
-                        renderNodeInfo.paddingBottom;
-            }
-            /**
-             * Calculate layout for series node's core graph. Only called for an expanded
-             * series.
-             */
-            function layoutSeriesNode(node) {
-                var graph = node.coreGraph;
-                var params = layout.PARAMS.subscene.series;
-                _.extend(node, params);
-                // Layout the core.
-                _.extend(node.coreBox, dagreLayout(node.coreGraph, layout.PARAMS.graph.series));
-                _.each(graph.nodes(), function (nodeName) {
-                    graph.node(nodeName).excluded = false;
-                });
-                // Series do not have in/outExtractBox so no need to include them here.
-                node.width = node.coreBox.width + params.paddingLeft + params.paddingRight;
-                node.height = node.coreBox.height + params.paddingTop + params.paddingBottom;
-            }
-            /**
-             * Calculate layout for annotations of a given node.
-             * This will modify positions of the given node and its annotations.
-             *
-             * @see tf.graph.render.Node and tf.graph.render.Annotation
-             * for description of each property of each render node.
-             *
-             */
-            function layoutAnnotation(renderNodeInfo) {
-                // If the render node is an expanded metanode, then its annotations will not
-                // be visible and we should skip the annotation calculations.
-                if (renderNodeInfo.expanded) {
-                    return;
-                }
-                var inAnnotations = renderNodeInfo.inAnnotations.list;
-                var outAnnotations = renderNodeInfo.outAnnotations.list;
-                // Calculate size for in-annotations
-                _.each(inAnnotations, function (a) { return sizeAnnotation(a); });
-                // Calculate size for out-annotations
-                _.each(outAnnotations, function (a) { return sizeAnnotation(a); });
-                var params = layout.PARAMS.annotations;
-                // Calculate annotation node position (a.dx, a.dy)
-                // and total height for in-annotations
-                // After this chunk of code:
-                // inboxHeight = sum of annotation heights+ (annotation.length - 1 * yOffset)
-                var inboxHeight = _.reduce(inAnnotations, function (height, a, i) {
-                    var yOffset = i > 0 ? params.yOffset : 0;
-                    a.dx = -(renderNodeInfo.coreBox.width + a.width) / 2 - params.xOffset;
-                    a.dy = height + yOffset + a.height / 2;
-                    return height + yOffset + a.height;
-                }, 0);
-                _.each(inAnnotations, function (a) {
-                    a.dy -= inboxHeight / 2;
-                    a.labelOffset = params.labelOffset;
-                });
-                // Calculate annotation node position (a.dx, a.dy)
-                // and total height for out-annotations
-                // After this chunk of code:
-                // outboxHeight = sum of annotation heights +
-                //                (annotation.length - 1 * yOffset)
-                var outboxHeight = _.reduce(outAnnotations, function (height, a, i) {
-                    var yOffset = i > 0 ? params.yOffset : 0;
-                    a.dx = (renderNodeInfo.coreBox.width + a.width) / 2 + params.xOffset;
-                    a.dy = height + yOffset + a.height / 2;
-                    return height + yOffset + a.height;
-                }, 0);
-                _.each(outAnnotations, function (a) {
-                    // adjust by (half of ) the total height
-                    // so dy is relative to the host node's center.
-                    a.dy -= outboxHeight / 2;
-                    a.labelOffset = params.labelOffset;
-                });
-                // Creating scales for touch point between the in-annotation edges
-                // and their hosts.
-                var inTouchHeight = Math.min(renderNodeInfo.height / 2 - renderNodeInfo.radius, inboxHeight / 2);
-                inTouchHeight = inTouchHeight < 0 ? 0 : inTouchHeight;
-                var inY = d3.scale.linear()
-                    .domain([0, inAnnotations.length - 1])
-                    .range([-inTouchHeight, inTouchHeight]);
-                // Calculate annotation edge position
-                _.each(inAnnotations, function (a, i) {
-                    a.points = [
-                        // The annotation node end
-                        {
-                            dx: a.dx + a.width / 2,
-                            dy: a.dy
-                        },
-                        // The host node end
-                        {
-                            dx: -renderNodeInfo.coreBox.width / 2,
-                            // only use scale if there are more than one,
-                            // otherwise center it vertically
-                            dy: inAnnotations.length > 1 ? inY(i) : 0
-                        }
-                    ];
-                });
-                // Creating scales for touch point between the out-annotation edges
-                // and their hosts.
-                var outTouchHeight = Math.min(renderNodeInfo.height / 2 - renderNodeInfo.radius, outboxHeight / 2);
-                outTouchHeight = outTouchHeight < 0 ? 0 : outTouchHeight;
-                var outY = d3.scale.linear()
-                    .domain([0, outAnnotations.length - 1])
-                    .range([-outTouchHeight, outTouchHeight]);
-                _.each(outAnnotations, function (a, i) {
-                    // Add point from the border of the annotation node
-                    a.points = [
-                        // The host node end
-                        {
-                            dx: renderNodeInfo.coreBox.width / 2,
-                            // only use scale if there are more than one,
-                            // otherwise center it vertically
-                            dy: outAnnotations.length > 1 ? outY(i) : 0
-                        },
-                        // The annotation node end
-                        {
-                            dx: a.dx - a.width / 2,
-                            dy: a.dy
-                        }
-                    ];
-                });
-                renderNodeInfo.height =
-                    Math.max(renderNodeInfo.height, inboxHeight, outboxHeight);
-            }
-            /**
-             * Set size of an annotation node.
-             */
-            function sizeAnnotation(a) {
-                switch (a.annotationType) {
-                    case graph_1.render.AnnotationType.CONSTANT:
-                        _.extend(a, layout.PARAMS.constant.size);
-                        break;
-                    case graph_1.render.AnnotationType.SHORTCUT:
-                        if (a.node.type === graph_1.NodeType.OP) {
-                            _.extend(a, layout.PARAMS.shortcutSize.op);
-                        }
-                        else if (a.node.type === graph_1.NodeType.META) {
-                            _.extend(a, layout.PARAMS.shortcutSize.meta);
-                        }
-                        else if (a.node.type === graph_1.NodeType.SERIES) {
-                            _.extend(a, layout.PARAMS.shortcutSize.series);
-                        }
-                        else {
-                            throw Error("Invalid node type: " + a.node.type);
-                        }
-                        break;
-                    case graph_1.render.AnnotationType.SUMMARY:
-                        _.extend(a, layout.PARAMS.constant.size);
-                        break;
-                }
-            }
-            /**
-             * Determines the center position of the node's shape. The position depends
-             * on if the node has in and out-annotations.
-             */
-            function computeCXPositionOfNodeShape(renderInfo) {
-                if (renderInfo.expanded) {
-                    return renderInfo.x;
-                }
-                var dx = renderInfo.inAnnotations.list.length ? renderInfo.inboxWidth : 0;
-                return renderInfo.x - renderInfo.width / 2 + dx +
-                    renderInfo.coreBox.width / 2;
-            }
-            layout.computeCXPositionOfNodeShape = computeCXPositionOfNodeShape;
-            /** Returns the angle (in degrees) between two points. */
-            function angleBetweenTwoPoints(a, b) {
-                var dx = b.x - a.x;
-                var dy = b.y - a.y;
-                return 180 * Math.atan(dy / dx) / Math.PI;
-            }
-            /**
-             * Returns if a line going through the specified points is a straight line.
-             */
-            function isStraightLine(points) {
-                var angle = angleBetweenTwoPoints(points[0], points[1]);
-                for (var i = 1; i < points.length - 1; i++) {
-                    var newAngle = angleBetweenTwoPoints(points[i], points[i + 1]);
-                    // Have a tolerance of 1 degree.
-                    if (Math.abs(newAngle - angle) > 1) {
+                sources1 = sortNodes(sources1, g1, g1prefix);
+                sources2 = sortNodes(sources2, g2, g2prefix);
+                for (var i = 0; i < sources1.length; i++) {
+                    var different = stackPushIfNotDifferent(sources1[i], sources2[i]);
+                    if (different) {
                         return false;
                     }
-                    angle = newAngle;
+                }
+                while (stack.length > 0) {
+                    var cur = stack.pop();
+                    // check node
+                    var similar = isSimilarNode(g1.node(cur.n1), g2.node(cur.n2));
+                    if (!similar) {
+                        return false;
+                    }
+                    // check if have same # of successors then sort and push
+                    var succ1 = g1.successors(cur.n1), succ2 = g2.successors(cur.n2);
+                    if (succ1.length !== succ2.length) {
+                        /* tslint:disable */
+                        console.log('# of successors mismatch', succ1, succ2);
+                        /* tslint:enable */
+                        return false;
+                    }
+                    succ1 = sortNodes(succ1, g1, g1prefix);
+                    succ2 = sortNodes(succ2, g2, g2prefix);
+                    for (var j = 0; j < succ1.length; j++) {
+                        var different = stackPushIfNotDifferent(succ1[j], succ2[j]);
+                        if (different) {
+                            return false;
+                        }
+                    }
                 }
                 return true;
             }
             /**
-             * Returns the intersection of a line between the provided point
-             * and the provided rectangle.
+             * Returns if two nodes have identical structure.
              */
-            function intersectPointAndNode(point, node) {
-                // cx and cy are the center of the rectangle.
-                var cx = node.expanded ?
-                    node.x : computeCXPositionOfNodeShape(node);
-                var cy = node.y;
-                // Calculate the slope
-                var dx = point.x - cx;
-                var dy = point.y - cy;
-                var w = node.expanded ? node.width : node.coreBox.width;
-                var h = node.expanded ? node.height : node.coreBox.height;
-                var deltaX, deltaY;
-                if (Math.abs(dy) * w / 2 > Math.abs(dx) * h / 2) {
-                    // The intersection is above or below the rectangle.
-                    if (dy < 0) {
-                        h = -h;
-                    }
-                    deltaX = dy === 0 ? 0 : h / 2 * dx / dy;
-                    deltaY = h / 2;
+            function isSimilarNode(n1, n2) {
+                if (n1.type === graph_1.NodeType.META) {
+                    // compare metanode
+                    var metanode1 = n1;
+                    var metanode2 = n2;
+                    return metanode1.templateId && metanode2.templateId &&
+                        metanode1.templateId === metanode2.templateId;
                 }
-                else {
-                    // The intersection is left or right of the rectangle.
-                    if (dx < 0) {
-                        w = -w;
-                    }
-                    deltaX = w / 2;
-                    deltaY = dx === 0 ? 0 : w / 2 * dy / dx;
+                else if (n1.type === graph_1.NodeType.OP && n2.type === graph_1.NodeType.OP) {
+                    // compare leaf node
+                    return n1.op === n2.op;
                 }
-                return { x: cx + deltaX, y: cy + deltaY };
+                else if (n1.type === graph_1.NodeType.SERIES && n2.type === graph_1.NodeType.SERIES) {
+                    // compare series node sizes and operations
+                    // (only need to check one op as all op nodes are identical in series)
+                    var sn1 = n1;
+                    var sn2 = n2;
+                    var seriesnode1Count = sn1.metagraph.nodeCount();
+                    return (seriesnode1Count === sn2.metagraph.nodeCount() &&
+                        (seriesnode1Count === 0 ||
+                            (sn1.metagraph.node(sn1.metagraph.nodes()[0]).op ===
+                                sn2.metagraph.node(sn2.metagraph.nodes()[0]).op)));
+                }
+                return false;
             }
-        })(layout = graph_1.layout || (graph_1.layout = {}));
+        })(template = graph_1.template || (graph_1.template = {}));
     })(graph = tf.graph || (tf.graph = {}));
-})(tf || (tf = {})); // close module
-</script>
-<script>/* Copyright 2015 Google Inc. All Rights Reserved.
-
-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.
-==============================================================================*/
-var tf;
-(function (tf) {
-    /**
-     * Mapping from color palette name to color palette, which contains
-     * exact colors for multiple states of a single color palette.
-     */
-    tf.COLORS = [
-        {
-            "name": "Google Blue",
-            "color": "#4184f3",
-            "active": "#3a53c5",
-            "disabled": "#cad8fc"
-        },
-        {
-            "name": "Google Red",
-            "color": "#db4437",
-            "active": "#8f2a0c",
-            "disabled": "#e8c6c1"
-        },
-        {
-            "name": "Google Yellow",
-            "color": "#f4b400",
-            "active": "#db9200",
-            "disabled": "#f7e8b0"
-        },
-        {
-            "name": "Google Green",
-            "color": "#0f9d58",
-            "active": "#488046",
-            "disabled": "#c2e1cc"
-        },
-        {
-            "name": "Purple",
-            "color": "#aa46bb",
-            "active": "#5c1398",
-            "disabled": "#d7bce6"
-        },
-        {
-            "name": "Teal",
-            "color": "#00abc0",
-            "active": "#47828e",
-            "disabled": "#c2eaf2"
-        },
-        {
-            "name": "Deep Orange",
-            "color": "#ff6f42",
-            "active": "#ca4a06",
-            "disabled": "#f2cbba"
-        },
-        {
-            "name": "Lime",
-            "color": "#9d9c23",
-            "active": "#7f771d",
-            "disabled": "#f1f4c2"
-        },
-        {
-            "name": "Indigo",
-            "color": "#5b6abf",
-            "active": "#3e47a9",
-            "disabled": "#c5c8e8"
-        },
-        {
-            "name": "Pink",
-            "color": "#ef6191",
-            "active": "#ca1c60",
-            "disabled": "#e9b9ce"
-        },
-        {
-            "name": "Deep Teal",
-            "color": "#00786a",
-            "active": "#2b4f43",
-            "disabled": "#bededa"
-        },
-        {
-            "name": "Deep Pink",
-            "color": "#c1175a",
-            "active": "#75084f",
-            "disabled": "#de8cae"
-        },
-        {
-            "name": "Gray",
-            "color": "#9E9E9E",
-            "active": "#424242",
-            "disabled": "F5F5F5" // 100
-        }
-    ]
-        .reduce(function (m, c) {
-        m[c.name] = c;
-        return m;
-    }, {});
-    /**
-     * Mapping from op category to color palette name
-     * e.g.,  OP_GROUP_COLORS["state_ops"] = "Google Blue";
-     */
-    tf.OP_GROUP_COLORS = [
-        {
-            color: "Google Red",
-            groups: [
-                "gen_legacy_ops", "legacy_ops", "legacy_flogs_input",
-                "legacy_image_input", "legacy_input_example_input",
-                "legacy_sequence_input", "legacy_seti_input_input"
-            ]
-        },
-        { color: "Deep Orange", groups: ["constant_ops"] },
-        { color: "Indigo", groups: ["state_ops"] },
-        { color: "Purple", groups: ["nn_ops", "nn"] },
-        { color: "Google Green", groups: ["math_ops"] },
-        { color: "Lime", groups: ["array_ops"] },
-        { color: "Teal", groups: ["control_flow_ops", "data_flow_ops"] },
-        { color: "Pink", groups: ["summary_ops"] },
-        { color: "Deep Pink", groups: ["io_ops"] }
-    ]
-        .reduce(function (m, c) {
-        c.groups.forEach(function (group) { m[group] = c.color; });
-        return m;
-    }, {});
 })(tf || (tf = {}));
 </script>
 <script>/* Copyright 2015 Google Inc. All Rights Reserved.
 
-Licensed under the Apache License, Version 2.0 (the "License");
+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,
+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.
+==============================================================================*/
+/**
+ * @fileoverview Utility functions for the tensorflow graph visualizer.
+ */
+var tf;
+(function (tf) {
+    var graph;
+    (function (graph) {
+        var util;
+        (function (util) {
+            /**
+             * Recommended delay (ms) when running an expensive task asynchronously
+             * that gives enough time for the progress bar to update its UI.
+             */
+            var ASYNC_TASK_DELAY = 20;
+            function time(msg, task) {
+                var start = Date.now();
+                var result = task();
+                /* tslint:disable */
+                console.log(msg, ':', Date.now() - start, 'ms');
+                /* tslint:enable */
+                return result;
+            }
+            util.time = time;
+            /**
+             * Creates a tracker that sets the progress property of the
+             * provided polymer component. The provided component must have
+             * a property called 'progress' that is not read-only. The progress
+             * property is an object with a numerical 'value' property and a
+             * string 'msg' property.
+             */
+            function getTracker(polymerComponent) {
+                return {
+                    setMessage: function (msg) {
+                        polymerComponent.set('progress', { value: polymerComponent.progress.value, msg: msg });
+                    },
+                    updateProgress: function (value) {
+                        polymerComponent.set('progress', {
+                            value: polymerComponent.progress.value + value,
+                            msg: polymerComponent.progress.msg
+                        });
+                    },
+                    reportError: function (msg, err) {
+                        // Log the stack trace in the console.
+                        console.error(err.stack);
+                        // And send a user-friendly message to the UI.
+                        polymerComponent.set('progress', { value: polymerComponent.progress.value, msg: msg, error: true });
+                    },
+                };
+            }
+            util.getTracker = getTracker;
+            /**
+             * Creates a tracker for a subtask given the parent tracker, the total
+             * progress
+             * of the subtask and the subtask message. The parent task should pass a
+             * subtracker to its subtasks. The subtask reports its own progress which
+             * becames relative to the main task.
+             */
+            function getSubtaskTracker(parentTracker, impactOnTotalProgress, subtaskMsg) {
+                return {
+                    setMessage: function (progressMsg) {
+                        // The parent should show a concatenation of its message along with
+                        // its subtask tracker message.
+                        parentTracker.setMessage(subtaskMsg + ': ' + progressMsg);
+                    },
+                    updateProgress: function (incrementValue) {
+                        // Update the parent progress relative to the child progress.
+                        // For example, if the sub-task progresses by 30%, and the impact on the
+                        // total progress is 50%, then the task progresses by 30% * 50% = 15%.
+                        parentTracker.updateProgress(incrementValue * impactOnTotalProgress / 100);
+                    },
+                    reportError: function (msg, err) {
+                        // The parent should show a concatenation of its message along with
+                        // its subtask error message.
+                        parentTracker.reportError(subtaskMsg + ': ' + msg, err);
+                    }
+                };
+            }
+            util.getSubtaskTracker = getSubtaskTracker;
+            /**
+             * Runs an expensive task and return the result.
+             */
+            function runTask(msg, incProgressValue, task, tracker) {
+                // Update the progress message to say the current running task.
+                tracker.setMessage(msg);
+                // Run the expensive task with a delay that gives enough time for the
+                // UI to update.
+                try {
+                    var result = tf.graph.util.time(msg, task);
+                    // Update the progress value.
+                    tracker.updateProgress(incProgressValue);
+                    // Return the result to be used by other tasks.
+                    return result;
+                }
+                catch (e) {
+                    // Errors that happen inside asynchronous tasks are
+                    // reported to the tracker using a user-friendly message.
+                    tracker.reportError('Failed ' + msg, e);
+                }
+            }
+            util.runTask = runTask;
+            /**
+             * Runs an expensive task asynchronously and returns a promise of the result.
+             */
+            function runAsyncTask(msg, incProgressValue, task, tracker) {
+                return new Promise(function (resolve, reject) {
+                    // Update the progress message to say the current running task.
+                    tracker.setMessage(msg);
+                    // Run the expensive task with a delay that gives enough time for the
+                    // UI to update.
+                    setTimeout(function () {
+                        try {
+                            var result = tf.graph.util.time(msg, task);
+                            // Update the progress value.
+                            tracker.updateProgress(incProgressValue);
+                            // Return the result to be used by other tasks.
+                            resolve(result);
+                        }
+                        catch (e) {
+                            // Errors that happen inside asynchronous tasks are
+                            // reported to the tracker using a user-friendly message.
+                            tracker.reportError('Failed ' + msg, e);
+                        }
+                    }, ASYNC_TASK_DELAY);
+                });
+            }
+            util.runAsyncTask = runAsyncTask;
+            /**
+             * Returns a query selector with escaped special characters that are not
+             * allowed in a query selector.
+             */
+            function escapeQuerySelector(querySelector) {
+                return querySelector.replace(/([:.\[\],/\\\(\)])/g, '\\$1');
+            }
+            util.escapeQuerySelector = escapeQuerySelector;
+        })(util = graph.util || (graph.util = {}));
+    })(graph = tf.graph || (tf.graph = {}));
+})(tf || (tf = {}));
+</script>
+<script>/* Copyright 2015 Google Inc. All Rights Reserved.
+
+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.
@@ -8984,26 +9286,26 @@
                 var $minimap = d3.select(minimap);
                 // The minimap will have 2 main components: the canvas showing the content
                 // and an svg showing a rectangle of the currently zoomed/panned viewpoint.
-                var $minimapSvg = $minimap.select("svg");
+                var $minimapSvg = $minimap.select('svg');
                 // Make the viewpoint rectangle draggable.
-                var $viewpoint = $minimapSvg.select("rect");
+                var $viewpoint = $minimapSvg.select('rect');
                 var dragmove = function (d) {
                     _this.viewpointCoord.x = d3.event.x;
                     _this.viewpointCoord.y = d3.event.y;
                     _this.updateViewpoint();
                 };
                 this.viewpointCoord = { x: 0, y: 0 };
-                var drag = d3.behavior.drag().origin(Object).on("drag", dragmove);
+                var drag = d3.behavior.drag().origin(Object).on('drag', dragmove);
                 $viewpoint.datum(this.viewpointCoord).call(drag);
                 // Make the minimap clickable.
-                $minimapSvg.on("click", function () {
+                $minimapSvg.on('click', function () {
                     if (d3.event.defaultPrevented) {
                         // This click was part of a drag event, so suppress it.
                         return;
                     }
                     // Update the coordinates of the viewpoint.
-                    var width = Number($viewpoint.attr("width"));
-                    var height = Number($viewpoint.attr("height"));
+                    var width = Number($viewpoint.attr('width'));
+                    var height = Number($viewpoint.attr('height'));
                     var clickCoords = d3.mouse($minimapSvg.node());
                     _this.viewpointCoord.x = clickCoords[0] - width / 2;
                     _this.viewpointCoord.y = clickCoords[1] - height / 2;
@@ -9012,12 +9314,13 @@
                 this.viewpoint = $viewpoint.node();
                 this.minimapSvg = $minimapSvg.node();
                 this.minimap = minimap;
-                this.canvas = $minimap.select("canvas.first").node();
+                this.canvas = $minimap.select('canvas.first').node();
                 this.canvasBuffer =
-                    $minimap.select("canvas.second").node();
+                    $minimap.select('canvas.second').node();
                 this.downloadCanvas =
-                    $minimap.select("canvas.download").node();
-                d3.select(this.downloadCanvas).style("display", "none");
+                    $minimap.select('canvas.download').node();
+                d3.select(this.downloadCanvas).style('display', 'none');
+                this.update();
             }
             /**
              * Updates the position and the size of the viewpoint rectangle.
@@ -9026,8 +9329,8 @@
             Minimap.prototype.updateViewpoint = function () {
                 // Update the coordinates of the viewpoint rectangle.
                 d3.select(this.viewpoint)
-                    .attr("x", this.viewpointCoord.x)
-                    .attr("y", this.viewpointCoord.y);
+                    .attr('x', this.viewpointCoord.x)
+                    .attr('y', this.viewpointCoord.y);
                 // Update the translation vector of the main svg to reflect the
                 // new viewpoint.
                 var mainX = -this.viewpointCoord.x * this.scaleMain / this.scaleMinimap;
@@ -9041,20 +9344,30 @@
              */
             Minimap.prototype.update = function () {
                 var _this = this;
-                // The origin hasn't rendered yet. Ignore making an update.
-                if (this.zoomG.childElementCount === 0) {
+                var sceneSize = null;
+                try {
+                    // Get the size of the entire scene.
+                    sceneSize = this.zoomG.getBBox();
+                    if (sceneSize.width === 0) {
+                        // There is no scene anymore. We have been detached from the dom.
+                        return;
+                    }
+                }
+                catch (e) {
+                    // Firefox produced NS_ERROR_FAILURE if we have been
+                    // detached from the dom.
                     return;
                 }
-                var $download = d3.select("#graphdownload");
+                var $download = d3.select('#graphdownload');
                 this.download = $download.node();
-                $download.on("click", function (d) {
-                    _this.download.href = _this.downloadCanvas.toDataURL("image/png");
+                $download.on('click', function (d) {
+                    _this.download.href = _this.downloadCanvas.toDataURL('image/png');
                 });
                 var $svg = d3.select(this.svg);
                 // Read all the style rules in the document and embed them into the svg.
                 // The svg needs to be self contained, i.e. all the style rules need to be
                 // embedded so the canvas output matches the origin.
-                var stylesText = "";
+                var stylesText = '';
                 for (var k = 0; k < document.styleSheets.length; k++) {
                     try {
                         var cssRules = document.styleSheets[k].cssRules ||
@@ -9064,26 +9377,24 @@
                         }
                         for (var i = 0; i < cssRules.length; i++) {
                             // Remove tf-* selectors from the styles.
-                            stylesText += cssRules[i].cssText.replace(/ ?tf-[\w-]+ ?/g, "") +
-                                "\n";
+                            stylesText +=
+                                cssRules[i].cssText.replace(/ ?tf-[\w-]+ ?/g, '') + '\n';
                         }
                     }
                     catch (e) {
-                        if (e.name !== "SecurityError") {
+                        if (e.name !== 'SecurityError') {
                             throw e;
                         }
                     }
                 }
                 // Temporarily add the css rules to the main svg.
-                var svgStyle = $svg.append("style");
+                var svgStyle = $svg.append('style');
                 svgStyle.text(stylesText);
                 // Temporarily remove the zoom/pan transform from the main svg since we
                 // want the minimap to show a zoomed-out and centered view.
                 var $zoomG = d3.select(this.zoomG);
-                var zoomTransform = $zoomG.attr("transform");
-                $zoomG.attr("transform", null);
-                // Get the size of the entire scene.
-                var sceneSize = this.zoomG.getBBox();
+                var zoomTransform = $zoomG.attr('transform');
+                $zoomG.attr('transform', null);
                 // Since we add padding, account for that here.
                 sceneSize.height += this.labelPadding * 2;
                 sceneSize.width += this.labelPadding * 2;
@@ -9128,26 +9439,26 @@
                     width: null,
                     height: null
                 });
-                $zoomG.attr("transform", zoomTransform);
+                $zoomG.attr('transform', zoomTransform);
                 var image = new Image();
                 image.onload = function () {
                     // Draw the svg content onto the buffer canvas.
-                    var context = _this.canvasBuffer.getContext("2d");
+                    var context = _this.canvasBuffer.getContext('2d');
                     context.clearRect(0, 0, _this.canvasBuffer.width, _this.canvasBuffer.height);
                     context.drawImage(image, 0, 0, _this.minimapSize.width, _this.minimapSize.height);
                     requestAnimationFrame(function () {
                         // Hide the old canvas and show the new buffer canvas.
-                        d3.select(_this.canvasBuffer).style("display", null);
-                        d3.select(_this.canvas).style("display", "none");
+                        d3.select(_this.canvasBuffer).style('display', null);
+                        d3.select(_this.canvas).style('display', 'none');
                         // Swap the two canvases.
                         _a = [_this.canvasBuffer, _this.canvas], _this.canvas = _a[0], _this.canvasBuffer = _a[1];
                         var _a;
                     });
-                    var downloadContext = _this.downloadCanvas.getContext("2d");
+                    var downloadContext = _this.downloadCanvas.getContext('2d');
                     downloadContext.clearRect(0, 0, _this.downloadCanvas.width, _this.downloadCanvas.height);
                     downloadContext.drawImage(image, 0, 0, _this.downloadCanvas.width, _this.downloadCanvas.height);
                 };
-                var blob = new Blob([svgXml], { type: "image/svg+xml;charset=utf-8" });
+                var blob = new Blob([svgXml], { type: 'image/svg+xml;charset=utf-8' });
                 image.src = URL.createObjectURL(blob);
             };
             /**
@@ -9159,6 +9470,10 @@
              * @param scale The scaling factor, or none to use the last used one.
              */
             Minimap.prototype.zoom = function (translate, scale) {
+                if (this.scaleMinimap == null) {
+                    // Scene is not ready yet.
+                    return;
+                }
                 // Update the new translate and scale params, only if specified.
                 this.translate = translate || this.translate;
                 this.scaleMain = scale || this.scaleMain;
@@ -9189,10 +9504,10 @@
                     Math.min(Math.max(0, y), mapHeight);
                 var fracIntersect = (w * h) / (mapWidth * mapHeight);
                 if (fracIntersect < FRAC_VIEWPOINT_AREA) {
-                    this.minimap.classList.remove("hidden");
+                    this.minimap.classList.remove('hidden');
                 }
                 else {
-                    this.minimap.classList.add("hidden");
+                    this.minimap.classList.add('hidden');
                 }
             };
             return Minimap;
@@ -9822,12 +10137,12 @@
   /** Main method for building the scene */
   _build: function(renderHierarchy) {
     this.templateIndex = renderHierarchy.hierarchy.getTemplateIndex();
-    tf.time('tf-graph-scene (layout):', function() {
+    tf.graph.util.time('tf-graph-scene (layout):', function() {
       // layout the scene for this meta / series node
       tf.graph.layout.layoutScene(renderHierarchy.root, this);
     }.bind(this));
 
-    tf.time('tf-graph-scene (build scene):', function() {
+    tf.graph.util.time('tf-graph-scene (build scene):', function() {
       tf.graph.scene.buildGroup(d3.select(this.$.root), renderHierarchy.root, this);
       tf.graph.scene.addGraphClickListener(this.$.svg, this);
     }.bind(this));
@@ -10165,7 +10480,7 @@
     }
   },
   _buildRenderHierarchy: function(graphHierarchy) {
-    tf.time('new tf.graph.render.Hierarchy', function() {
+    tf.graph.util.time('new tf.graph.render.Hierarchy', function() {
       if (graphHierarchy.root.type !== tf.graph.NodeType.META) {
         // root must be metanode but sometimes Polymer's dom-if has not
         // remove tf-graph element yet in <tf-node-info>
@@ -10317,8 +10632,8 @@
       value: 0,
       msg: ''
     });
-    var tracker = tf.getTracker(this);
-    var hierarchyTracker = tf.getSubtaskTracker(tracker, 100,
+    var tracker = tf.graph.util.getTracker(this);
+    var hierarchyTracker = tf.graph.util.getSubtaskTracker(tracker, 100,
           'Namespace hierarchy');
     tf.graph.hierarchy.build(this.basicGraph, this.hierarchyParams, hierarchyTracker)
     .then(function(graphHierarchy) {
@@ -11977,6 +12292,8 @@
       </paper-toolbar>
 
       <div id="content" class="fit">
+        <content id="injected-overview"></content>
+
         <template is="dom-if" if="[[_modeIsEvents(mode)]]">
           <tf-event-dashboard id="events" backend="[[_backend]]" router="[[router]]"></tf-event-dashboard>
         </template>
@@ -11985,6 +12302,10 @@
           <tf-image-dashboard id="images" backend="[[_backend]]"></tf-image-dashboard>
         </template>
 
+        <template is="dom-if" if="[[_modeIsAudio(mode)]]">
+          <tf-audio-dashboard id="audio" backend="[[_backend]]"></tf-audio-dashboard>
+        </template>
+
         <template is="dom-if" if="[[_modeIsGraphs(mode)]]">
           <tf-graph-dashboard id="graphs" backend="[[_backend]]" router="[[router]]"></tf-graph-dashboard>
         </template>
@@ -12003,7 +12324,7 @@
       }
 
       #toolbar {
-        background-color: var(--tb-orange-strong);
+        background-color: var(--tb-toolbar-background-color, --tb-orange-strong);
         -webkit-font-smoothing: antialiased;
       }
 
@@ -12014,6 +12335,7 @@
         letter-spacing: -0.025em;
         font-weight: 500;
         flex-grow: 2;
+        display: var(--tb-toolbar-title-display, block);
       }
 
       .tabs {
@@ -12050,6 +12372,7 @@
       #content {
         height: 100%;
       }
+
       [disabled] {
         opacity: 0.2;
         color: white;
@@ -12104,6 +12427,9 @@
       _modeIsImages: function(mode) {
         return mode === "images";
       },
+      _modeIsAudio: function(mode) {
+        return mode === "audio";
+      },
       _modeIsGraphs: function(mode) {
         return mode === "graphs";
       },
