http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/b5deb035/console/stand-alone/package.json
----------------------------------------------------------------------
diff --git a/console/stand-alone/package.json b/console/stand-alone/package.json
index aa59f68..aad443e 100644
--- a/console/stand-alone/package.json
+++ b/console/stand-alone/package.json
@@ -4,7 +4,8 @@
   "description": "Qpid Dispatch Router stand-alone console",
   "main": "index.html",
   "scripts": {
-    "test": "echo \"Error: no test specified\" && exit 1"
+    "test": "mocha --require babel-core/register",
+    "tsc": "tsc"
   },
   "repository": {
     "type": "git",
@@ -31,15 +32,13 @@
     "angular-ui-bootstrap": "^2.5.6",
     "angular-ui-grid": "^4.0.8",
     "angular-ui-slider": "^0.4.0",
-    "bluebird": "^3.5.1",
+    "babel-polyfill": "^6.26.0",
     "bootstrap": "^3.3.7",
     "c3": "^0.4.18",
     "d3": "^3.5.14",
     "d3-path": "^1.0.5",
     "d3-queue": "^3.0.7",
     "d3-time-format": "^2.1.1",
-    "dispatch-management": "~0.1.21",
-    "html5shiv": "^3.7.3",
     "jquery": "^3.2.1",
     "jquery-ui-dist": "^1.12.1",
     "jquery.fancytree": "^2.26.0",
@@ -48,23 +47,38 @@
     "rhea": "^0.2.13"
   },
   "devDependencies": {
+    "@types/mocha": "^5.2.2",
+    "@types/node": "^10.3.3",
     "babel-core": "^6.26.3",
     "babel-preset-env": "^1.7.0",
+    "babel-preset-es2015": "^6.24.1",
+    "browserify": "^16.2.2",
+    "chai": "^4.1.2",
     "del": "^3.0.0",
     "fs": "0.0.1-security",
+    "glob": "^7.1.2",
     "gulp": "github:gulpjs/gulp#4.0",
     "gulp-babel": "^7.0.1",
     "gulp-clean-css": "^3.9.4",
     "gulp-concat": "^2.6.1",
     "gulp-eslint": "^4.0.2",
+    "gulp-if": "^2.0.2",
     "gulp-insert": "^0.5.0",
+    "gulp-mocha": "^6.0.0",
     "gulp-ng-annotate": "^2.1.0",
     "gulp-rename": "^1.2.3",
     "gulp-sourcemaps": "^2.6.4",
+    "gulp-terser": "^1.0.1",
     "gulp-tslint": "^8.1.3",
     "gulp-typescript": "^4.0.2",
     "gulp-uglify": "^3.0.0",
+    "gulp-uglifyes": "^0.1.3",
+    "mocha": "^5.2.0",
+    "rollup-stream": "^1.24.1",
+    "through2": "^2.0.3",
     "tslint": "^5.10.0",
-    "typescript": "^2.9.1"
+    "typescript": "^2.9.1",
+    "vinyl-buffer": "^1.0.1",
+    "vinyl-source-stream": "^2.0.0"
   }
 }

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/b5deb035/console/stand-alone/plugin/css/dispatch.css
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/css/dispatch.css 
b/console/stand-alone/plugin/css/dispatch.css
index 38495ad..f76d421 100644
--- a/console/stand-alone/plugin/css/dispatch.css
+++ b/console/stand-alone/plugin/css/dispatch.css
@@ -975,10 +975,10 @@ i.red {
 }
 
 .qdrListActions div.delete {
-    width: 20em;
+    width: 30em;
     margin: auto;
     border: 1px solid #eaeaea;
-    height: 5em;
+    /* height: 5em; */
     padding: 4em;
     background-color: #fcfcfc;
 }

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/b5deb035/console/stand-alone/plugin/html/qdrList.html
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/html/qdrList.html 
b/console/stand-alone/plugin/html/qdrList.html
index 64aa091..06faa43 100644
--- a/console/stand-alone/plugin/html/qdrList.html
+++ b/console/stand-alone/plugin/html/qdrList.html
@@ -18,16 +18,8 @@ under the License.
 -->
 
 <style>
-@media (min-width: 768px) {
-  .list-grid {
+.list-grid {
     padding-left: 300px;
-  }
-}
-@media (max-width: 768px) {
-  .list-grid {
-      padding-left: 0;
-  }
-
 }
 
 span.fancytree-icon {
@@ -51,11 +43,21 @@ span.fancytree-icon {
   height: 25px;
   width: 300px;
   background-color: #333333;
+  border: 0;
 }
 
 #list-controller div.list-grid select {
     background-color: white;
 }
+
+.list-grid {
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: calc(100% - 40px);
+    margin-left: 20px;
+}
+
 </style>
 
 <div id="list-controller" ng-controller="QDR.ListController">
@@ -71,23 +73,23 @@ span.fancytree-icon {
         </div>
     </div>
 
-    <div class="list-grid col-xs-12">
+    <div class="list-grid">
         <div class="row-fluid qdrListActions">
             <ul class="nav nav-tabs">
                 <li ng-repeat="mode in modes" ng-show="isValid(mode)" 
ng-click="selectMode(mode)" ng-class="{active : isModeSelected(mode)}" 
title="{{mode.title}}" ng-bind-html="mode.content"> </li>
             </ul>
-            <h4>{{selectedRecordName}}</h4>
+            <h4>{{selectedRecordName | to_trusted}}</h4>
             <div ng-show="currentMode.id === 'attributes'" 
class="selectedItems">
-                <div ng-show="selectedRecordName === selectedEntity" 
class="no-content">There are no {{selectedEntity | safePlural}}</div>
+                <div ng-show="selectedRecordName === selectedEntity" 
class="no-content">There are no {{selectedEntity | safePlural | 
to_trusted}}</div>
                 <div id='details-grid' ng-hide="selectedRecordName === 
selectedEntity" ui-grid="details" ui-grid-resize-columns ui-grid-save-state
                 ui-grid-auto-resize ng-style="getTableHeight()"></div>
             </div>
             <div ng-show="currentMode.id === 'delete'">
                 <div class="delete" ng-show="selectedRecordName !== 
selectedEntity">
-                    <button class="btn btn-primary" 
ng-click="remove()">Delete</button> {{selectedRecordName}}
+                    <button class="btn btn-primary" 
ng-click="remove()">Delete</button> {{selectedRecordName | to_trusted}}
                 </div>
                 <div ng-hide="selectedRecordName !== selectedEntity">
-                    There are no {{selectedEntity | safePlural}}
+                    There are no {{selectedEntity | safePlural | to_trusted}}
                 </div>
             </div>
             <div class="operations" ng-show="currentMode.id === 'operations'">
@@ -98,7 +100,7 @@ span.fancytree-icon {
                             <th>Value</th>
                         </tr>
                     <tr title="{{attribute.title}}" ng-repeat="attribute in 
detailFields">
-                        <td><label for="{{attribute.name}}">{{attribute.name | 
humanify}}</label></td>
+                        <td><label for="{{attribute.name}}">{{attribute.name | 
humanify | to_trusted}}</label></td>
                         <!-- we can't do <input type="{angular expression}"> 
because... jquery throws an exception because... -->
                         <td>
                         <div ng-if="attribute.input == 'input'">
@@ -106,7 +108,7 @@ span.fancytree-icon {
                             <div ng-if="attribute.type == 'number'"><input 
type="number" name="{{attribute.name}}" id="{{attribute.name}}" 
ng-model="attribute.rawValue" ng-required="attribute.required" 
ng-class="{required: attribute.required, unique: attribute.unique}" 
class="ui-widget-content ui-corner-all"/><span ng-if="attribute.required" 
title="required" class="required-indicator"></span><span 
ng-if="attribute.unique" title="unique" class="unique-indicator"></span></div>
                             <div ng-if="attribute.type == 'text'"><input 
type="text" name="{{attribute.name}}" id="{{attribute.name}}" 
ng-model="attribute.attributeValue" ng-required="attribute.required" 
ng-class="{required: attribute.required, unique: attribute.unique}" 
class="ui-widget-content ui-corner-all"/><span ng-if="attribute.required" 
title="required" class="required-indicator"></span><span 
ng-if="attribute.unique" title="unique" class="unique-indicator"></span></div>
                             <div ng-if="attribute.type == 
'textarea'"><textarea name="{{attribute.name}}" id="{{attribute.name}}" 
ng-model="attribute.attributeValue" ng-required="attribute.required" 
ng-class="{required: attribute.required, unique: attribute.unique}" 
class="ui-widget-content ui-corner-all"></textarea><span 
ng-if="attribute.required" title="required" 
class="required-indicator"></span><span ng-if="attribute.unique" title="unique" 
class="unique-indicator"></span></div>
-                            <span ng-if="attribute.type == 'disabled'" 
>{{getAttributeValue(attribute)}}</span>
+                            <span ng-if="attribute.type == 'disabled'" 
>{{getAttributeValue(attribute) | to_trusted}}</span>
                         </div>
                         <div ng-if="attribute.input == 'select'">
                             <select id="{{attribute.name}}" 
ng-model="attribute.selected" ng-required="attribute.required" 
ng-class="{required: attribute.required, unique: attribute.unique}" 
ng-options="item for item in attribute.rawtype track by item"></select>
@@ -118,7 +120,7 @@ span.fancytree-icon {
                         </div>
                         </td>
                     </tr>
-                    <tr><td></td><td><button class="btn btn-primary" 
type="button" ng-click="ok()">{{operation | Pascalcase}}</button></td></tr>
+                    <tr><td></td><td><button class="btn btn-primary" 
type="button" ng-click="ok()">{{operation | Pascalcase | 
to_trusted}}</button></td></tr>
                     </table>
                 </fieldset>
             </div>
@@ -139,10 +141,23 @@ span.fancytree-icon {
                         </tr>
                     </table>
                 </div>
-                <div ng-if="logResults.length == 0 && !fetchingLog">No log 
entries for {{selectedRecordName}}</div>
-                <div ng-if="fetchingLog">Fetching logs for 
{{selectedRecordName}}</div>
+                <div ng-if="logResults.length == 0 && !fetchingLog">No log 
entries for {{selectedRecordName | to_trusted}}</div>
+                <div ng-if="fetchingLog">Fetching logs for 
{{selectedRecordName | to_trusted}}</div>
             </div>
         </div>
     </div>
 </div>
 
+<style>
+    @media (min-width: 768px) {
+      .list-grid {
+        padding-left: 300px;
+      }
+    }
+    @media (max-width: 768px) {
+      .list-grid {
+          padding-left: 0;
+      }
+    
+    }
+</style>

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/b5deb035/console/stand-alone/plugin/html/tmplChartConfig.html
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/html/tmplChartConfig.html 
b/console/stand-alone/plugin/html/tmplChartConfig.html
index 4c9c727..efd474e 100644
--- a/console/stand-alone/plugin/html/tmplChartConfig.html
+++ b/console/stand-alone/plugin/html/tmplChartConfig.html
@@ -31,7 +31,7 @@
         <uib-tabset>
             <uib-tab heading="Type">
                 <legend>Chart type</legend>
-                <div>
+                <div class="clearfix">
                     <label><input type="radio" ng-model="dialogChart.type" 
value="value" /> Value Chart</label>
                     <label><input type="radio" ng-model="dialogChart.type" 
value="rate" /> Rate Chart</label>
 <!--
@@ -41,19 +41,15 @@
                     </div>
 -->
                 </div>
-                <div style="clear:both;"> </div>
             </uib-tab>
-<!--
-            <uib-tab ng-hide="$parent.chart.aggregate()" heading="Colors">
+            <uib-tab ng-hide="chart.aggregate()" heading="Colors">
                 <legend>Chart colors</legend>
-                <div>
+                <div class="clearfix">
                     <div class="colorPicker">
-                        <label>Area: <input id="areaColor" name="areaColor" 
type="color" /></label>
+                        <label>Area: <input id="areaColor" name="areaColor" 
type="color" ng-model="dialogChart.areaColor"/></label>
                     </div>
                 </div>
-                <div style="clear:both;"> </div>
             </uib-tab>
--->
             <uib-tab heading="Duration">
                 <legend>Chart duration</legend>
                 <div class="clearfix">

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/b5deb035/console/stand-alone/plugin/js/chord/data.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/chord/data.js 
b/console/stand-alone/plugin/js/chord/data.js
index 7f28a9c..45e68a7 100644
--- a/console/stand-alone/plugin/js/chord/data.js
+++ b/console/stand-alone/plugin/js/chord/data.js
@@ -17,136 +17,132 @@ specific language governing permissions and limitations
 under the License.
 */
 
-'use strict';
-/* global angular Promise MIN_CHORD_THRESHOLD */
+/* global angular Promise */
+import { MIN_CHORD_THRESHOLD } from './matrix.js';
 
 const SAMPLES = 3;  // number of snapshots to use for rate calculations
 
-function ChordData (QDRService, isRate, converter) {
-  this.QDRService = QDRService;
-  this.last_matrix = undefined;
-  this.last_values = {values: undefined, timestamp: undefined};
-  this.rateValues = undefined;
-  this.snapshots = [];  // last N values used for calculating rate
-  this.isRate = isRate;
-  // fn to convert raw data to matrix
-  this.converter = converter;
-  // object that determines which addresses are excluded
-  this.filter = [];
-}
-ChordData.prototype.setRate = function (isRate) {
-  this.isRate = isRate;
-};
-ChordData.prototype.setConverter = function (converter) {
-  this.converter = converter;
-};
-ChordData.prototype.setFilter = function (filter) {
-  this.filter = filter;
-};
-ChordData.prototype.getAddresses = function () {
-  let addresses = {};
-  let outer = this.snapshots;
-  if (outer.length === 0)
-    outer = outer = [this.last_values];
-  outer.forEach( function (snap) {
-    snap.values.forEach( function (lv) {
-      if (!(lv.address in addresses)) {
-        addresses[lv.address] = this.filter.indexOf(lv.address) < 0;
-      }
+class ChordData { // eslint-disable-line no-unused-vars
+  constructor(QDRService, isRate, converter) {
+    this.QDRService = QDRService;
+    this.last_matrix = undefined;
+    this.last_values = { values: undefined, timestamp: undefined };
+    this.rateValues = undefined;
+    this.snapshots = []; // last N values used for calculating rate
+    this.isRate = isRate;
+    // fn to convert raw data to matrix
+    this.converter = converter;
+    // object that determines which addresses are excluded
+    this.filter = [];
+  }
+  setRate(isRate) {
+    this.isRate = isRate;
+  }
+  setConverter(converter) {
+    this.converter = converter;
+  }
+  setFilter(filter) {
+    this.filter = filter;
+  }
+  getAddresses() {
+    let addresses = {};
+    let outer = this.snapshots;
+    if (outer.length === 0)
+      outer = outer = [this.last_values];
+    outer.forEach(function (snap) {
+      snap.values.forEach(function (lv) {
+        if (!(lv.address in addresses)) {
+          addresses[lv.address] = this.filter.indexOf(lv.address) < 0;
+        }
+      }, this);
     }, this);
-  }, this);
-  return addresses;
-};
-ChordData.prototype.getRouters = function () {
-  let routers = {};
-  let outer = this.snapshots;
-  if (outer.length === 0)
-    outer = [this.last_values];
-  outer.forEach( function (snap) {
-    snap.values.forEach( function (lv) {
-      routers[lv.egress] = true;
-      routers[lv.ingress] = true;
+    return addresses;
+  }
+  getRouters() {
+    let routers = {};
+    let outer = this.snapshots;
+    if (outer.length === 0)
+      outer = [this.last_values];
+    outer.forEach(function (snap) {
+      snap.values.forEach(function (lv) {
+        routers[lv.egress] = true;
+        routers[lv.ingress] = true;
+      });
     });
-  });
-  return Object.keys(routers).sort();
-};
-
-ChordData.prototype.applyFilter = function (filter) {
-  if (filter)
-    this.setFilter(filter);
-
-  return new Promise( (function (resolve) {
-    resolve(convert(this, this.last_values));
-  }));
-};
-
-// construct a square matrix of the number of messages each router has 
egressed from each router
-ChordData.prototype.getMatrix = function () {
-  let self = this;
-  return new Promise( (function (resolve, reject) {
-    // get the router.node and router.link info
-    self.QDRService.management.topology.fetchAllEntities([
-      {entity: 'router.node', attrs: ['id', 'index']},
-      {entity: 'router.link', attrs: ['linkType', 'linkDir', 'owningAddr', 
'ingressHistogram']}], 
-    function(results) {
-      if (!results) {
-        reject(Error('unable to fetch entities'));
-        return;
-      }
-      // the raw data received from the rouers
-      let values = [];
-
-      // for each router in the network
-      for (let nodeId in results) {
-        // get a map of router ids to index into ingressHistogram for the 
links for this router.
-        // each routers has a different order for the routers
-        let ingressRouters = [];
-        let routerNode = results[nodeId]['router.node'];
-        let idIndex = routerNode.attributeNames.indexOf('id');
-
-        // ingressRouters is an array of router names in the same order that 
the ingressHistogram values will be in
-        for (let i=0; i<routerNode.results.length; i++) {
-          ingressRouters.push(routerNode.results[i][idIndex]);
+    return Object.keys(routers).sort();
+  }
+  applyFilter(filter) {
+    if (filter)
+      this.setFilter(filter);
+    return new Promise((function (resolve) {
+      resolve(convert(this, this.last_values));
+    }));
+  }
+  // construct a square matrix of the number of messages each router has 
egressed from each router
+  getMatrix() {
+    let self = this;
+    return new Promise((function (resolve, reject) {
+      // get the router.node and router.link info
+      self.QDRService.management.topology.fetchAllEntities([
+        { entity: 'router.node', attrs: ['id', 'index'] },
+        { entity: 'router.link', attrs: ['linkType', 'linkDir', 'owningAddr', 
'ingressHistogram'] }
+      ], function (results) {
+        if (!results) {
+          reject(Error('unable to fetch entities'));
+          return;
         }
-
-        // the name of the router we are working on
-        let egressRouter = 
self.QDRService.management.topology.nameFromId(nodeId);
-
-        // loop through the router links for this router looking for 
out/endpoint/non-console links
-        let routerLinks = results[nodeId]['router.link'];
-        for (let i=0; i<routerLinks.results.length; i++) {
-          let link = 
self.QDRService.utilities.flatten(routerLinks.attributeNames, 
routerLinks.results[i]);
-          // if the link is an outbound/enpoint/non console
-          if (link.linkType === 'endpoint' && link.linkDir === 'out' && 
!link.owningAddr.startsWith('Ltemp.')) {
-            // keep track of the raw egress values as well as their ingress 
and egress routers and the address
-            for (let j=0; j<ingressRouters.length; j++) {
-              let messages = link.ingressHistogram[j];
-              if (messages) {
-                values.push({ingress: ingressRouters[j], 
-                  egress:  egressRouter, 
-                  address: 
self.QDRService.utilities.addr_text(link.owningAddr), 
-                  messages: messages});
+        // the raw data received from the rouers
+        let values = [];
+        // for each router in the network
+        for (let nodeId in results) {
+          // get a map of router ids to index into ingressHistogram for the 
links for this router.
+          // each routers has a different order for the routers
+          let ingressRouters = [];
+          let routerNode = results[nodeId]['router.node'];
+          let idIndex = routerNode.attributeNames.indexOf('id');
+          // ingressRouters is an array of router names in the same order that 
the ingressHistogram values will be in
+          for (let i = 0; i < routerNode.results.length; i++) {
+            ingressRouters.push(routerNode.results[i][idIndex]);
+          }
+          // the name of the router we are working on
+          let egressRouter = self.QDRService.utilities.nameFromId(nodeId);
+          // loop through the router links for this router looking for 
out/endpoint/non-console links
+          let routerLinks = results[nodeId]['router.link'];
+          for (let i = 0; i < routerLinks.results.length; i++) {
+            let link = 
self.QDRService.utilities.flatten(routerLinks.attributeNames, 
routerLinks.results[i]);
+            // if the link is an outbound/enpoint/non console
+            if (link.linkType === 'endpoint' && link.linkDir === 'out' && 
!link.owningAddr.startsWith('Ltemp.')) {
+              // keep track of the raw egress values as well as their ingress 
and egress routers and the address
+              for (let j = 0; j < ingressRouters.length; j++) {
+                let messages = link.ingressHistogram[j];
+                if (messages) {
+                  values.push({
+                    ingress: ingressRouters[j],
+                    egress: egressRouter,
+                    address: 
self.QDRService.utilities.addr_text(link.owningAddr),
+                    messages: messages
+                  });
+                }
               }
             }
           }
         }
-      }
-      // values is an array of objects like [{ingress: 'xxx', egress: 'xxx', 
address: 'xxx', messages: ###}, ....]
-
-      // convert the raw values array into a matrix object
-      let matrix = convert(self, values);
+        // values is an array of objects like [{ingress: 'xxx', egress: 'xxx', 
address: 'xxx', messages: ###}, ....]
+        // convert the raw values array into a matrix object
+        let matrix = convert(self, values);
+        // resolve the promise
+        resolve(matrix);
+      });
+    }));
+  }
+  convertUsing(converter) {
+    let values = this.isRate ? this.rateValues : this.last_values.values;
+    // convert the values to a matrix using the requested converter and the 
current filter
+    return converter(values, this.filter);
+  }
+}
 
-      // resolve the promise
-      resolve(matrix);
-    });
-  }));
-};
-ChordData.prototype.convertUsing = function (converter) {
-  let values = this.isRate ? this.rateValues : this.last_values.values;
 
-  // convert the values to a matrix using the requested converter and the 
current filter
-  return converter(values, this.filter);
-};
 
 // Private functions
 
@@ -226,3 +222,5 @@ let convert = function (self, values) {
 
   return matrix;
 };
+
+export { ChordData };

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/b5deb035/console/stand-alone/plugin/js/chord/filters.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/chord/filters.js 
b/console/stand-alone/plugin/js/chord/filters.js
index 7bb68cc..d184221 100644
--- a/console/stand-alone/plugin/js/chord/filters.js
+++ b/console/stand-alone/plugin/js/chord/filters.js
@@ -16,11 +16,10 @@ KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License.
 */
-'use strict';
-/* global valuesMatrix */
 
+import { valuesMatrix } from './matrix.js';
 // this filter will show an arc per router with the addresses aggregated
-var aggregateAddresses = function (values, filter) { // eslint-disable-line 
no-unused-vars
+export const aggregateAddresses = function (values, filter) {
   let m = new valuesMatrix(true);
   values.forEach (function (value) {
     if (filter.indexOf(value.address) < 0) {
@@ -40,53 +39,8 @@ var aggregateAddresses = function (values, filter) { // 
eslint-disable-line no-u
   return m.sorted();
 };
 
-// this filter will show an arc per router-address
-var _separateAddresses = function (values, filter) { // eslint-disable-line 
no-unused-vars
-  let m = new valuesMatrix(false);
-  values = values.filter( function (v) { return filter.indexOf(v.address) < 
0;});
-  if (values.length === 0)
-    return m;
-
-  let addresses = {}, routers = {};
-  // get the list of routers and addresses in the data
-  values.forEach( function (value) {
-    addresses[value.address] = true;
-    routers[value.ingress] = true;
-    routers[value.egress] = true;
-  });
-  let saddresses = Object.keys(addresses).sort();
-  let srouters = Object.keys(routers).sort();
-  let alen = saddresses.length;
-  // sanity check
-  if (alen === 0)
-    return m;
-
-  /* Convert the data to a matrix */
-
-  // initialize the matrix to have the correct ingress, egress, and address in 
each row and col
-  m.zeroInit(saddresses.length * srouters.length);
-  m.rows.forEach( function (row, r) {
-    let egress = srouters[Math.floor(r/alen)];
-    row.cols.forEach( function (col, c) {
-      let ingress = srouters[Math.floor(c/alen)];
-      let address = saddresses[c % alen];
-      m.setRowCol(r, c, ingress, egress, address, 0);
-    });
-  });
-  // set the values at each cell in the matrix
-  for (let i=0, alen=saddresses.length, vlen=values.length; i<vlen; i++) {
-    let value = values[i];
-    let egressIndex = srouters.indexOf(value.egress);
-    let ingressIndex = srouters.indexOf(value.ingress);
-    let addressIndex = saddresses.indexOf(value.address);
-    let row = egressIndex * alen + addressIndex;
-    let col = ingressIndex * alen + addressIndex;
-    m.setColMessages(row, col, value.messages);
-  }
-  return m;
-};
 
-let separateAddresses = function (values, filter) { // eslint-disable-line 
no-unused-vars
+export const separateAddresses = function (values, filter) {
   let m = new valuesMatrix(false);
   values.forEach( function (value) {
     if (filter.indexOf(value.address) < 0) {

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/b5deb035/console/stand-alone/plugin/js/chord/layout/layout.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/chord/layout/layout.js 
b/console/stand-alone/plugin/js/chord/layout/layout.js
index e3d223f..907e9a8 100644
--- a/console/stand-alone/plugin/js/chord/layout/layout.js
+++ b/console/stand-alone/plugin/js/chord/layout/layout.js
@@ -16,11 +16,9 @@ KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License.
 */
-'use strict';
 /* global d3 */
 
-
-var qrdlayoutChord = function() { // eslint-disable-line no-unused-vars
+var qdrlayoutChord = function() { // eslint-disable-line no-unused-vars
   var chord = {}, chords, groups, matrix, n, padding = 0, τ = Math.PI*2, 
groupBy;
   function relayout() {
     groupBy = groupBy || d3.range(n);
@@ -145,3 +143,5 @@ let unique = function (arr) {
   }
   return Object.keys(counts).length;
 };
+
+export { qdrlayoutChord };
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/b5deb035/console/stand-alone/plugin/js/chord/matrix.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/chord/matrix.js 
b/console/stand-alone/plugin/js/chord/matrix.js
index 3f10ddc..156deb3 100644
--- a/console/stand-alone/plugin/js/chord/matrix.js
+++ b/console/stand-alone/plugin/js/chord/matrix.js
@@ -16,7 +16,6 @@ KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License.
 */
-'use strict';
 /* global d3 */
 
 const MIN_CHORD_THRESHOLD = 0.01;
@@ -212,3 +211,5 @@ let emptyMatrix = function (size) {
   }
   return matrix;
 };
+
+export { MIN_CHORD_THRESHOLD, valuesMatrix };

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/b5deb035/console/stand-alone/plugin/js/chord/qdrChord.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/chord/qdrChord.js 
b/console/stand-alone/plugin/js/chord/qdrChord.js
index 91ee96a..edb1b3a 100644
--- a/console/stand-alone/plugin/js/chord/qdrChord.js
+++ b/console/stand-alone/plugin/js/chord/qdrChord.js
@@ -16,16 +16,21 @@ KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License.
 */
-'use strict';
-/* global angular d3 separateAddresses aggregateAddresses ChordData qdrRibbon 
qrdlayoutChord */
+/* global angular d3 */
 
-var QDR = (function (QDR) {
-  QDR.module.controller('QDR.ChordController', ['$scope', 'QDRService', 
'$location', '$timeout', '$sce', function($scope, QDRService, $location, 
$timeout, $sce) {
+import { QDRRedirectWhenConnected } from '../qdrGlobals.js';
+import { separateAddresses, aggregateAddresses } from './filters.js';
+import { ChordData } from './data.js';
+import { qdrRibbon } from './ribbon/ribbon.js';
+import { qdrlayoutChord } from './layout/layout.js';
 
+export class ChordController {
+  constructor(QDRService, $scope, $location, $timeout, $sce) {
+    this.controllerName = 'QDR.ChordController';
     // if we get here and there is no connection, redirect to the connect page 
and then 
     // return here once we are connected
     if (!QDRService.management.connection.is_connected()) {
-      QDR.redirectWhenConnected($location, 'chord');
+      QDRRedirectWhenConnected($location, 'chord');
       return;
     }
 
@@ -441,7 +446,7 @@ var QDR = (function (QDR) {
 
       // create a new chord layout so we can animate between the last one and 
this one
       let groupBy = matrix.getGroupBy();
-      let rechord = 
qrdlayoutChord().padding(ARCPADDING).groupBy(groupBy).matrix(matrixMessages);
+      let rechord = 
qdrlayoutChord().padding(ARCPADDING).groupBy(groupBy).matrix(matrixMessages);
 
       // The chord layout has a function named .groups() that returns the
       // data for the arcs. We decorate this data with a unique key.
@@ -831,8 +836,7 @@ var QDR = (function (QDR) {
       });
     }
     let interval = setInterval(doUpdate, transitionDuration);
-  
-  }]);
-  return QDR;
 
-} (QDR || {}));
+  }
+}
+ChordController.$inject = ['QDRService', '$scope', '$location', '$timeout', 
'$sce'];

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/b5deb035/console/stand-alone/plugin/js/chord/ribbon/ribbon.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/chord/ribbon/ribbon.js 
b/console/stand-alone/plugin/js/chord/ribbon/ribbon.js
index 604fa1e..fb6996f 100644
--- a/console/stand-alone/plugin/js/chord/ribbon/ribbon.js
+++ b/console/stand-alone/plugin/js/chord/ribbon/ribbon.js
@@ -16,9 +16,7 @@ KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License.
 */
-'use strict';
 /* global d3 */
-
 const halfPI = Math.PI / 2.0;
 const twoPI = Math.PI * 2.0;
 
@@ -163,3 +161,5 @@ let cpRatio = function (gap, x, y) {
   let distScale = d3.scale.linear().domain([0, top/8, top/2, top]).range([0, 
.3, .4, .5]);
   return distScale(dist);
 };
+
+export { qdrRibbon };
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/b5deb035/console/stand-alone/plugin/js/dispatchPlugin.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/dispatchPlugin.js 
b/console/stand-alone/plugin/js/dispatchPlugin.js
deleted file mode 100644
index 47c8a60..0000000
--- a/console/stand-alone/plugin/js/dispatchPlugin.js
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you 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.
-*/
-'use strict';
-/* global angular d3 */
-
-/**
- * @module QDR
- * @main QDR
- *
- * The main entry point for the QDR module
- *
- */
-var QDR = (function(QDR) {
-
-  /**
-   * @property pluginName
-   * @type {string}
-   *
-   * The name of this plugin
-   */
-  QDR.pluginName = 'QDR';
-  QDR.pluginRoot = '';
-  QDR.isStandalone = true;
-
-  /**
-   * @property templatePath
-   * @type {string}
-   *
-   * The top level path to this plugin's partials
-   */
-  QDR.templatePath = 'html/';
-  /**
-   * @property SETTINGS_KEY
-   * @type {string}
-   *
-   * The key used to fetch our settings from local storage
-   */
-  QDR.SETTINGS_KEY = 'QDRSettings';
-  QDR.LAST_LOCATION = 'QDRLastLocation';
-
-  QDR.redirectWhenConnected = function ($location, org) {
-    $location.path(QDR.pluginRoot + '/connect');
-    $location.search('org', org);
-  };
-
-  /**
-   * @property module
-   * @type {object}
-   *
-   * This plugin's angularjs module instance
-   */
-  QDR.module = angular.module(QDR.pluginName, ['ngRoute', 'ngSanitize', 
'ngResource', 'ui.bootstrap',
-    'ui.grid', 'ui.grid.selection', 'ui.grid.autoResize', 
'ui.grid.resizeColumns', 'ui.grid.saveState', 'ui.slider', 'ui.checkbox']);
-
-  // set up the routing for this plugin
-  QDR.module.config(function($routeProvider) {
-    $routeProvider
-      .when('/', {
-        templateUrl: QDR.templatePath + 'qdrOverview.html'
-      })
-      .when('/overview', {
-        templateUrl: QDR.templatePath + 'qdrOverview.html'
-      })
-      .when('/topology', {
-        templateUrl: QDR.templatePath + 'qdrTopology.html'
-      })
-      .when('/list', {
-        templateUrl: QDR.templatePath + 'qdrList.html'
-      })
-      .when('/schema', {
-        templateUrl: QDR.templatePath + 'qdrSchema.html'
-      })
-      .when('/charts', {
-        templateUrl: QDR.templatePath + 'qdrCharts.html'
-      })
-      .when('/chord', {
-        templateUrl: QDR.templatePath + 'qdrChord.html'
-      })
-      .when('/connect', {
-        templateUrl: QDR.templatePath + 'qdrConnect.html'
-      });
-  });
-
-  QDR.module.config(function ($compileProvider) {
-    
$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|chrome-extension|file|blob):/);
-    
$compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|ftp|mailto|chrome-extension):/);
-    /*    var cur = $compileProvider.urlSanitizationWhitelist();
-    
$compileProvider.urlSanitizationWhitelist(/^\s*(https?|ftp|mailto|file|blob):/);
-    cur = $compileProvider.urlSanitizationWhitelist();
-*/
-  });
-
-  QDR.module.filter('to_trusted', ['$sce', function($sce){
-    return function(text) {
-      return $sce.trustAsHtml(text);
-    };
-  }]);
-
-  QDR.module.filter('humanify', function (QDRService) {
-    return function (input) {
-      return QDRService.utilities.humanify(input);
-    };
-  });
-
-  QDR.module.filter('Pascalcase', function () {
-    return function (str) {
-      if (!str)
-        return '';
-      return str.replace(/(\w)(\w*)/g,
-        function(g0,g1,g2){return g1.toUpperCase() + g2.toLowerCase();});
-    };
-  });
-
-  QDR.module.filter('safePlural', function () {
-    return function (str) {
-      var es = ['x', 'ch', 'ss', 'sh'];
-      for (var i=0; i<es.length; ++i) {
-        if (str.endsWith(es[i]))
-          return str + 'es';
-      }
-      if (str.endsWith('y'))
-        return str.substr(0, str.length-2) + 'ies';
-      if (str.endsWith('s'))
-        return str;
-      return str + 's';
-    };
-  });
-
-  QDR.module.filter('pretty', function () {
-    return function (str) {
-      var formatComma = d3.format(',');
-      if (!isNaN(parseFloat(str)) && isFinite(str))
-        return formatComma(str);
-      return str;
-    };
-  });
-
-  QDR.logger = function ($log) {
-    var log = $log;
-
-    this.debug = function (msg) { msg = 'QDR: ' + msg; log.debug(msg);};
-    this.error = function (msg) {msg = 'QDR: ' + msg; log.error(msg);};
-    this.info = function (msg) {msg = 'QDR: ' + msg; log.info(msg);};
-    this.warn = function (msg) {msg = 'QDR: ' + msg; log.warn(msg);};
-
-    return this;
-  };
-  // one-time initialization happens in the run function
-  // of our module
-  QDR.module.run( ['$rootScope', '$route', '$timeout', '$location', '$log', 
'QDRService', 'QDRChartService',  function ($rootScope, $route, $timeout, 
$location, $log, QDRService, QDRChartService) {
-    QDR.log = new QDR.logger($log);
-    QDR.log.info('************* creating Dispatch Console ************');
-    var curPath = $location.path();
-    var org = curPath.substr(1);
-    if (org && org.length > 0 && org !== 'connect') {
-      $location.search('org', org);
-    } else {
-      $location.search('org', null);
-    }
-    QDR.queue = d3.queue;
-
-    if (!QDRService.management.connection.is_connected()) {
-      // attempt to connect to the host:port that served this page
-      var host = $location.host();
-      var port = $location.port();
-      var search = $location.search();
-      if (search.org) {
-        if (search.org === 'connect')
-          $location.search('org', 'overview');
-      }
-      var connectOptions = {address: host, port: port};
-      QDR.log.info('Attempting AMQP over websockets connection using 
address:port of browser ('+host+':'+port+')');
-      QDRService.management.connection.testConnect(connectOptions)
-        .then( function () {
-          // We didn't connect with reconnect: true flag.
-          // The reason being that if we used reconnect:true and the 
connection failed, rhea would keep trying. There
-          // doesn't appear to be a way to tell it to stop trying to reconnect.
-          QDRService.disconnect();
-          QDR.log.info('Connect succeeded. Using address:port of browser');
-          connectOptions.reconnect = true;
-          // complete the connection (create the sender/receiver)
-          QDRService.connect(connectOptions)
-            .then( function () {
-              // register a callback for when the node list is available 
(needed for loading saved charts)
-              
QDRService.management.topology.addUpdatedAction('initChartService', function() {
-                
QDRService.management.topology.delUpdatedAction('initChartService');
-                QDRChartService.init(); // initialize charting service after 
we are connected
-              });
-              // get the list of nodes
-              QDRService.management.topology.startUpdating(false);
-            });
-        }, function () {
-          QDR.log.info('failed to auto-connect to ' + host + ':' + port);
-          QDR.log.info('redirecting to connect page');
-          $timeout(function () {
-            $location.path('/connect');
-            $location.search('org', org);
-            $location.replace();
-          });
-        });
-    }
-
-    $rootScope.$on('$routeChangeSuccess', function() {
-      var path = $location.path();
-      if (path !== '/connect') {
-        localStorage[QDR.LAST_LOCATION] = path;
-      }
-    });
-  }]);
-
-  QDR.module.controller ('QDR.MainController', ['$scope', '$location', 
function ($scope, $location) {
-    QDR.log.debug('started QDR.MainController with location.url: ' + 
$location.url());
-    QDR.log.debug('started QDR.MainController with window.location.pathname : 
' + window.location.pathname);
-    $scope.topLevelTabs = [];
-    $scope.topLevelTabs.push({
-      id: 'qdr',
-      content: 'Qpid Dispatch Router Console',
-      title: 'Dispatch Router Console',
-      isValid: function() { return true; },
-      href: function() { return '#connect'; },
-      isActive: function() { return true; }
-    });
-  }]);
-
-  QDR.module.controller ('QDR.Core', function ($scope, $rootScope) {
-    $scope.alerts = [];
-    $scope.breadcrumb = {};
-    $scope.closeAlert = function(index) {
-      $scope.alerts.splice(index, 1);
-    };
-    $scope.$on('setCrumb', function(event, data) {
-      $scope.breadcrumb = data;
-    });
-    $scope.$on('newAlert', function(event, data) {
-      $scope.alerts.push(data);
-      $scope.$apply();
-    });
-    $scope.$on('clearAlerts', function () {
-      $scope.alerts = [];
-      $scope.$apply();
-    });
-    $scope.pageMenuClicked = function () {
-      $rootScope.$broadcast('pageMenuClicked');
-    };
-  });
-
-  return QDR;
-}(QDR || {}));

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/b5deb035/console/stand-alone/plugin/js/dlgChartController.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/dlgChartController.js 
b/console/stand-alone/plugin/js/dlgChartController.js
index e8c240f..271baa2 100644
--- a/console/stand-alone/plugin/js/dlgChartController.js
+++ b/console/stand-alone/plugin/js/dlgChartController.js
@@ -16,15 +16,11 @@ KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License.
 */
-'use strict';
 /* global angular */
-/**
- * @module QDR
- */
-var QDR = (function(QDR) {
 
-  // controller for the edit/configure chart dialog
-  QDR.module.controller('QDR.ChartDialogController', function($scope, 
QDRChartService, $location, $uibModalInstance, chart, updateTick, dashboard, 
adding) {
+export class ChartDialogController {
+  constructor(QDRChartService, $scope, $location, $uibModalInstance, chart, 
updateTick, dashboard, adding) {
+    this.controllerName = 'QDR.ChartDialogController';
     let dialogSvgChart = null;
     $scope.svgDivId = 'dialogEditChart';    // the div id for the svg chart
 
@@ -41,8 +37,10 @@ var QDR = (function(QDR) {
     });
     $scope.$watch('dialogChart.areaColor', function (newValue, oldValue) {
       if (newValue !== oldValue) {
-        if (dialogSvgChart)
+        if (dialogSvgChart) {
+          dialogSvgChart.chart.areaColor = newValue;
           dialogSvgChart.tick($scope.svgDivId);
+        }
       }
     });
     $scope.$watch('dialogChart.lineColor', function (newValue, oldValue) {
@@ -73,7 +71,7 @@ var QDR = (function(QDR) {
     $scope.showChartsPage = function () {
       cleanup();
       $uibModalInstance.close(true);
-      $location.path(QDR.pluginRoot + '/charts');
+      $location.path('/charts');
     };
 
     var cleanup = function () {
@@ -185,20 +183,13 @@ var QDR = (function(QDR) {
         setTimeout(showChart, 100);
         return;
       }
-      dialogSvgChart = new QDRChartService.pfAreaChart($scope.dialogChart, 
$scope.svgDivId);
-      /*
-      $('input[name=areaColor]').val($scope.dialogChart.areaColor);
-      $('input[name=areaColor]').on('input', function (e) {
-        $scope.dialogChart.areaColor = $(this).val();
-        updateDialogChart()
-      })
-*/
+      dialogSvgChart = QDRChartService.pfAreaChart($scope.dialogChart, 
$scope.svgDivId, false, 550);
       if (updateTimer)
         clearTimeout(updateTimer);
       updateDialogChart();
     };
     showChart();
-  });
-  return QDR;
 
-} (QDR || {}));
+  }
+}
+ChartDialogController.$inject = ['QDRChartService', '$scope', '$location', 
'$uibModalInstance', 'chart', 'updateTick', 'dashboard', 'adding'];

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/b5deb035/console/stand-alone/plugin/js/navbar.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/navbar.js 
b/console/stand-alone/plugin/js/navbar.js
index c17cd77..64d41c0 100644
--- a/console/stand-alone/plugin/js/navbar.js
+++ b/console/stand-alone/plugin/js/navbar.js
@@ -16,105 +16,92 @@ KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License.
 */
-'use strict';
 /* global angular */
 
-/**
- * @module QDR
- */
-var QDR = (function (QDR) {
+export class NavBarController {
+  constructor(QDRService, QDRChartService, $scope, $routeParams, $location) {
+    this.controllerName = 'QDR.NavBarController';
 
-  QDR.breadcrumbs = [
-    {
-      content: '<i class="icon-power"></i> Connect',
-      title: 'Connect to a router',
-      isValid: function () { return true; },
-      href: '#/connect',
-      name: 'Connect'
-    },
-    {
-      content: '<i class="pficon-home"></i> Overview',
-      title: 'View router overview',
-      isValid: function (QDRService) {return 
QDRService.management.connection.is_connected(); },
-      href: '#/overview',
-      name: 'Overview'
-    },
-    {
-      content: '<i class="icon-list "></i> Entities',
-      title: 'View the attributes of the router entities',
-      isValid: function (QDRService) { return 
QDRService.management.connection.is_connected(); },
-      href: '#/list',
-      name: 'Entities'
-    },
-    {
-      content: '<i class="code-branch"></i> Topology',
-      title: 'View router network topology',
-      isValid: function (QDRService) { return 
QDRService.management.connection.is_connected(); },
-      href: '#/topology',
-      name: 'Topology'
-    },
-    {
-      content: '<i class="icon-bar-chart"></i> Charts',
-      title: 'View charts',
-      isValid: function (QDRService) { return 
QDRService.management.connection.is_connected(); },
-      href: '#/charts',
-      name: 'Charts'
-    },
-    {
-      content: '<i class="chord-diagram"></i> Message Flow',
-      title: 'Chord chart',
-      isValid: function (QDRService) { return 
QDRService.management.connection.is_connected(); },
-      href: '#/chord',
-      name: 'Message Flow'
-    },
-    {
-      content: '<i class="icon-schema"></i> Schema',
-      title: 'View dispatch schema',
-      isValid: function (QDRService) { return 
QDRService.management.connection.is_connected(); },
-      href: '#/schema',
-      name: 'Schema'
-    }
-  ];
-  /**
-   * @function NavBarController
-   *
-   * @param $scope
-   * @param workspace
-   *
-   * The controller for this plugin's navigation bar
-   *
-   */
-  QDR.module.controller('QDR.NavBarController', ['$rootScope', '$scope', 
'QDRService', 'QDRChartService', '$routeParams', '$location', 
function($rootScope, $scope, QDRService, QDRChartService, $routeParams, 
$location) {
-    $scope.breadcrumbs = QDR.breadcrumbs;
+    $scope.breadcrumbs = [
+      {
+        content: '<i class="icon-power"></i> Connect',
+        title: 'Connect to a router',
+        isValid: function () { return true; },
+        href: '#/connect',
+        name: 'Connect'
+      },
+      {
+        content: '<i class="pficon-home"></i> Overview',
+        title: 'View router overview',
+        isValid: function (QDRService) {return 
QDRService.management.connection.is_connected(); },
+        href: '#/overview',
+        name: 'Overview'
+      },
+      {
+        content: '<i class="icon-list "></i> Entities',
+        title: 'View the attributes of the router entities',
+        isValid: function (QDRService) { return 
QDRService.management.connection.is_connected(); },
+        href: '#/list',
+        name: 'Entities'
+      },
+      {
+        content: '<i class="code-branch"></i> Topology',
+        title: 'View router network topology',
+        isValid: function (QDRService) { return 
QDRService.management.connection.is_connected(); },
+        href: '#/topology',
+        name: 'Topology'
+      },
+      {
+        content: '<i class="icon-bar-chart"></i> Charts',
+        title: 'View charts',
+        isValid: function (QDRService) { return 
QDRService.management.connection.is_connected(); },
+        href: '#/charts',
+        name: 'Charts'
+      },
+      {
+        content: '<i class="chord-diagram"></i> Message Flow',
+        title: 'Chord chart',
+        isValid: function (QDRService) { return 
QDRService.management.connection.is_connected(); },
+        href: '#/chord',
+        name: 'Message Flow'
+      },
+      {
+        content: '<i class="icon-schema"></i> Schema',
+        title: 'View dispatch schema',
+        isValid: function (QDRService) { return 
QDRService.management.connection.is_connected(); },
+        href: '#/schema',
+        name: 'Schema'
+      }
+    ];
     $scope.isValid = function(link) {
       return link.isValid(QDRService, $location);
     };
-
+  
     $scope.isActive = function(href) {
       return href.split('#')[1] === $location.path();
     };
-
+  
     $scope.isRight = function (link) {
       return angular.isDefined(link.right);
     };
-
+  
     $scope.hasChart = function (link) {
       if (link.href == '#/charts') {
         return QDRChartService.charts.some(function (c) { return c.dashboard; 
});
       }
     };
-
+  
     $scope.isDashboardable = function () {
       return  ($location.path().indexOf('schema') < 0 && 
$location.path().indexOf('connect') < 0);
     };
-
+  
     $scope.addToDashboardLink = function () {
       var href = '#' + $location.path();
       var size = angular.toJson({
         size_x: 2,
         size_y: 2
       });
-
+  
       var routeParams = angular.toJson($routeParams);
       var title = 'Dispatch Router';
       return '/hawtio/#/dashboard/add?tab=dashboard' +
@@ -123,9 +110,8 @@ var QDR = (function (QDR) {
             '&title=' + encodeURIComponent(title) +
             '&size=' + encodeURIComponent(size);
     };
+  }
 
-  }]);
-
-  return QDR;
+}
+NavBarController.$inject = ['QDRService', 'QDRChartService', '$scope', 
'$routeParams', '$location'];
 
-} (QDR || {}));

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/b5deb035/console/stand-alone/plugin/js/posintDirective.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/posintDirective.js 
b/console/stand-alone/plugin/js/posintDirective.js
new file mode 100644
index 0000000..66b1aa0
--- /dev/null
+++ b/console/stand-alone/plugin/js/posintDirective.js
@@ -0,0 +1,75 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you 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.
+*/
+export let posint = function() {
+  return {
+    require: 'ngModel',
+
+    link: function(scope, elem, attr, ctrl) {
+      // input type number allows + and - but we don't want them so filter 
them out
+      elem.bind('keypress', function(event) {
+        let nkey = !event.charCode ? event.which : event.charCode;
+        let skey = String.fromCharCode(nkey);
+        let nono = '-+.,';
+        if (nono.indexOf(skey) >= 0) {
+          event.preventDefault();
+          return false;
+        }
+        // firefox doesn't filter out non-numeric input. it just sets the ctrl 
to invalid
+        if (/[!@#$%^&*()]/.test(skey) && event.shiftKey || // prevent shift 
numbers
+          !( // prevent all but the following
+            nkey <= 0 || // arrows
+            nkey == 8 || // delete|backspace
+            nkey == 13 || // enter
+            (nkey >= 37 && nkey <= 40) || // arrows
+            event.ctrlKey || event.altKey || // ctrl-v, etc.
+            /[0-9]/.test(skey)) // numbers
+        ) {
+          event.preventDefault();
+          return false;
+        }
+      });
+      // check the current value of input
+      var _isPortInvalid = function(value) {
+        let port = value + '';
+        let isErrRange = false;
+        // empty string is valid
+        if (port.length !== 0) {
+          let n = ~~Number(port);
+          if (n < 1 || n > 65535) {
+            isErrRange = true;
+          }
+        }
+        ctrl.$setValidity('range', !isErrRange);
+        return isErrRange;
+      };
+
+      //For DOM -> model validation
+      ctrl.$parsers.unshift(function(value) {
+        return _isPortInvalid(value) ? undefined : value;
+      });
+
+      //For model -> DOM validation
+      ctrl.$formatters.unshift(function(value) {
+        _isPortInvalid(value);
+        return value;
+      });
+    }
+  };
+};
+


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@qpid.apache.org
For additional commands, e-mail: commits-h...@qpid.apache.org

Reply via email to