http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/a5e2307f/console/dispatch-dashboard/dispatch/static/dashboard/dispatch/lib/ui-grid.js
----------------------------------------------------------------------
diff --git 
a/console/dispatch-dashboard/dispatch/static/dashboard/dispatch/lib/ui-grid.js 
b/console/dispatch-dashboard/dispatch/static/dashboard/dispatch/lib/ui-grid.js
deleted file mode 100644
index 545ef70..0000000
--- 
a/console/dispatch-dashboard/dispatch/static/dashboard/dispatch/lib/ui-grid.js
+++ /dev/null
@@ -1,28540 +0,0 @@
-/*!
- * ui-grid - v3.2.9 - 2016-09-21
- * Copyright (c) 2016 ; License: MIT 
- */
-
-(function () {
-  'use strict';
-  angular.module('ui.grid.i18n', []);
-  angular.module('ui.grid', ['ui.grid.i18n']);
-})();
-(function () {
-  'use strict';
-
-  /**
-   * @ngdoc object
-   * @name ui.grid.service:uiGridConstants
-   * @description Constants for use across many grid features
-   *
-   */
-
-
-  angular.module('ui.grid').constant('uiGridConstants', {
-    LOG_DEBUG_MESSAGES: true,
-    LOG_WARN_MESSAGES: true,
-    LOG_ERROR_MESSAGES: true,
-    CUSTOM_FILTERS: /CUSTOM_FILTERS/g,
-    COL_FIELD: /COL_FIELD/g,
-    MODEL_COL_FIELD: /MODEL_COL_FIELD/g,
-    TOOLTIP: /title=\"TOOLTIP\"/g,
-    DISPLAY_CELL_TEMPLATE: /DISPLAY_CELL_TEMPLATE/g,
-    TEMPLATE_REGEXP: /<.+>/,
-    FUNC_REGEXP: /(\([^)]*\))?$/,
-    DOT_REGEXP: /\./g,
-    APOS_REGEXP: /'/g,
-    BRACKET_REGEXP: 
/^(.*)((?:\s*\[\s*\d+\s*\]\s*)|(?:\s*\[\s*"(?:[^"\\]|\\.)*"\s*\]\s*)|(?:\s*\[\s*'(?:[^'\\]|\\.)*'\s*\]\s*))(.*)$/,
-    COL_CLASS_PREFIX: 'ui-grid-col',
-    ENTITY_BINDING: '$$this',
-    events: {
-      GRID_SCROLL: 'uiGridScroll',
-      COLUMN_MENU_SHOWN: 'uiGridColMenuShown',
-      ITEM_DRAGGING: 'uiGridItemDragStart', // For any item being dragged
-      COLUMN_HEADER_CLICK: 'uiGridColumnHeaderClick'
-    },
-    // copied from 
http://www.lsauer.com/2011/08/javascript-keymap-keycodes-in-json.html
-    keymap: {
-      TAB: 9,
-      STRG: 17,
-      CAPSLOCK: 20,
-      CTRL: 17,
-      CTRLRIGHT: 18,
-      CTRLR: 18,
-      SHIFT: 16,
-      RETURN: 13,
-      ENTER: 13,
-      BACKSPACE: 8,
-      BCKSP: 8,
-      ALT: 18,
-      ALTR: 17,
-      ALTRIGHT: 17,
-      SPACE: 32,
-      WIN: 91,
-      MAC: 91,
-      FN: null,
-      PG_UP: 33,
-      PG_DOWN: 34,
-      UP: 38,
-      DOWN: 40,
-      LEFT: 37,
-      RIGHT: 39,
-      ESC: 27,
-      DEL: 46,
-      F1: 112,
-      F2: 113,
-      F3: 114,
-      F4: 115,
-      F5: 116,
-      F6: 117,
-      F7: 118,
-      F8: 119,
-      F9: 120,
-      F10: 121,
-      F11: 122,
-      F12: 123
-    },
-     /**
-     * @ngdoc object
-     * @name ASC
-     * @propertyOf ui.grid.service:uiGridConstants
-     * @description Used in {@link 
ui.grid.class:GridOptions.columnDef#properties_sort columnDef.sort} and
-     * {@link 
ui.grid.class:GridOptions.columnDef#properties_sortDirectionCycle 
columnDef.sortDirectionCycle}
-     * to configure the sorting direction of the column
-     */
-    ASC: 'asc',
-     /**
-     * @ngdoc object
-     * @name DESC
-     * @propertyOf ui.grid.service:uiGridConstants
-     * @description Used in {@link 
ui.grid.class:GridOptions.columnDef#properties_sort columnDef.sort} and
-     * {@link 
ui.grid.class:GridOptions.columnDef#properties_sortDirectionCycle 
columnDef.sortDirectionCycle}
-     * to configure the sorting direction of the column
-     */
-    DESC: 'desc',
-
-
-     /**
-     * @ngdoc object
-     * @name filter
-     * @propertyOf ui.grid.service:uiGridConstants
-     * @description Used in {@link 
ui.grid.class:GridOptions.columnDef#properties_filter columnDef.filter}
-     * to configure filtering on the column
-     *
-     * `SELECT` and `INPUT` are used with the `type` property of the filter, 
the rest are used to specify
-     * one of the built-in conditions.
-     *
-     * Available `condition` options are:
-     * - `uiGridConstants.filter.STARTS_WITH`
-     * - `uiGridConstants.filter.ENDS_WITH`
-     * - `uiGridConstants.filter.CONTAINS`
-     * - `uiGridConstants.filter.GREATER_THAN`
-     * - `uiGridConstants.filter.GREATER_THAN_OR_EQUAL`
-     * - `uiGridConstants.filter.LESS_THAN`
-     * - `uiGridConstants.filter.LESS_THAN_OR_EQUAL`
-     * - `uiGridConstants.filter.NOT_EQUAL`
-     * - `uiGridConstants.filter.STARTS_WITH`
-     *
-     *
-     * Available `type` options are:
-     * - `uiGridConstants.filter.SELECT` - use a dropdown box for the cell 
header filter field
-     * - `uiGridConstants.filter.INPUT` - use a text box for the cell header 
filter field
-     */
-    filter: {
-      STARTS_WITH: 2,
-      ENDS_WITH: 4,
-      EXACT: 8,
-      CONTAINS: 16,
-      GREATER_THAN: 32,
-      GREATER_THAN_OR_EQUAL: 64,
-      LESS_THAN: 128,
-      LESS_THAN_OR_EQUAL: 256,
-      NOT_EQUAL: 512,
-      SELECT: 'select',
-      INPUT: 'input'
-    },
-
-    /**
-     * @ngdoc object
-     * @name aggregationTypes
-     * @propertyOf ui.grid.service:uiGridConstants
-     * @description Used in {@link 
ui.grid.class:GridOptions.columnDef#properties_aggregationType 
columnDef.aggregationType}
-     * to specify the type of built-in aggregation the column should use.
-     *
-     * Available options are:
-     * - `uiGridConstants.aggregationTypes.sum` - add the values in this 
column to produce the aggregated value
-     * - `uiGridConstants.aggregationTypes.count` - count the number of rows 
to produce the aggregated value
-     * - `uiGridConstants.aggregationTypes.avg` - average the values in this 
column to produce the aggregated value
-     * - `uiGridConstants.aggregationTypes.min` - use the minimum value in 
this column as the aggregated value
-     * - `uiGridConstants.aggregationTypes.max` - use the maximum value in 
this column as the aggregated value
-     */
-    aggregationTypes: {
-      sum: 2,
-      count: 4,
-      avg: 8,
-      min: 16,
-      max: 32
-    },
-
-    // TODO(c0bra): Create full list of these somehow. NOTE: do any allow a 
space before or after them?
-    CURRENCY_SYMBOLS: ['ƒ', '$', '£', '$', '¤', '¥', '៛', '₩', '₱', 
'฿', '₫'],
-
-    /**
-     * @ngdoc object
-     * @name scrollDirection
-     * @propertyOf ui.grid.service:uiGridConstants
-     * @description Set on {@link 
ui.grid.class:Grid#properties_scrollDirection Grid.scrollDirection},
-     * to indicate the direction the grid is currently scrolling in
-     *
-     * Available options are:
-     * - `uiGridConstants.scrollDirection.UP` - set when the grid is scrolling 
up
-     * - `uiGridConstants.scrollDirection.DOWN` - set when the grid is 
scrolling down
-     * - `uiGridConstants.scrollDirection.LEFT` - set when the grid is 
scrolling left
-     * - `uiGridConstants.scrollDirection.RIGHT` - set when the grid is 
scrolling right
-     * - `uiGridConstants.scrollDirection.NONE` - set when the grid is not 
scrolling, this is the default
-     */
-    scrollDirection: {
-      UP: 'up',
-      DOWN: 'down',
-      LEFT: 'left',
-      RIGHT: 'right',
-      NONE: 'none'
-
-    },
-
-    /**
-     * @ngdoc object
-     * @name dataChange
-     * @propertyOf ui.grid.service:uiGridConstants
-     * @description Used with {@link 
ui.grid.core.api:PublicApi#methods_notifyDataChange PublicApi.notifyDataChange},
-     * {@link ui.grid.class:Grid#methods_callDataChangeCallbacks 
Grid.callDataChangeCallbacks},
-     * and {@link ui.grid.class:Grid#methods_registerDataChangeCallback 
Grid.registerDataChangeCallback}
-     * to specify the type of the event(s).
-     *
-     * Available options are:
-     * - `uiGridConstants.dataChange.ALL` - listeners fired on any of these 
events, fires listeners on all events.
-     * - `uiGridConstants.dataChange.EDIT` - fired when the data in a cell is 
edited
-     * - `uiGridConstants.dataChange.ROW` - fired when a row is added or 
removed
-     * - `uiGridConstants.dataChange.COLUMN` - fired when the column 
definitions are modified
-     * - `uiGridConstants.dataChange.OPTIONS` - fired when the grid options 
are modified
-     */
-    dataChange: {
-      ALL: 'all',
-      EDIT: 'edit',
-      ROW: 'row',
-      COLUMN: 'column',
-      OPTIONS: 'options'
-    },
-
-    /**
-     * @ngdoc object
-     * @name scrollbars
-     * @propertyOf ui.grid.service:uiGridConstants
-     * @description Used with {@link 
ui.grid.class:GridOptions#properties_enableHorizontalScrollbar 
GridOptions.enableHorizontalScrollbar}
-     * and {@link ui.grid.class:GridOptions#properties_enableVerticalScrollbar 
GridOptions.enableVerticalScrollbar}
-     * to specify the scrollbar policy for that direction.
-     *
-     * Available options are:
-     * - `uiGridConstants.scrollbars.NEVER` - never show scrollbars in this 
direction
-     * - `uiGridConstants.scrollbars.ALWAYS` - always show scrollbars in this 
direction
-     */
-
-    scrollbars: {
-      NEVER: 0,
-      ALWAYS: 1
-      //WHEN_NEEDED: 2
-    }
-  });
-
-})();
-
-angular.module('ui.grid').directive('uiGridCell', ['$compile', '$parse', 
'gridUtil', 'uiGridConstants', function ($compile, $parse, gridUtil, 
uiGridConstants) {
-  var uiGridCell = {
-    priority: 0,
-    scope: false,
-    require: '?^uiGrid',
-    compile: function() {
-      return {
-        pre: function($scope, $elm, $attrs, uiGridCtrl) {
-          function compileTemplate() {
-            var compiledElementFn = $scope.col.compiledElementFn;
-
-            compiledElementFn($scope, function(clonedElement, scope) {
-              $elm.append(clonedElement);
-            });
-          }
-
-          // If the grid controller is present, use it to get the compiled 
cell template function
-          if (uiGridCtrl && $scope.col.compiledElementFn) {
-             compileTemplate();
-          }
-          // No controller, compile the element manually (for unit tests)
-          else {
-            if ( uiGridCtrl && !$scope.col.compiledElementFn ){
-              // gridUtil.logError('Render has been called before precompile.  
Please log a ui-grid issue');  
-
-              $scope.col.getCompiledElementFn()
-                .then(function (compiledElementFn) {
-                  compiledElementFn($scope, function(clonedElement, scope) {
-                    $elm.append(clonedElement);
-                  });
-                });
-            }
-            else {
-              var html = $scope.col.cellTemplate
-                .replace(uiGridConstants.MODEL_COL_FIELD, 'row.entity.' + 
gridUtil.preEval($scope.col.field))
-                .replace(uiGridConstants.COL_FIELD, 'grid.getCellValue(row, 
col)');
-
-              var cellElement = $compile(html)($scope);
-              $elm.append(cellElement);
-            }
-          }
-        },
-        post: function($scope, $elm, $attrs, uiGridCtrl) {
-          var initColClass = $scope.col.getColClass(false);
-          $elm.addClass(initColClass);
-
-          var classAdded;
-          var updateClass = function( grid ){
-            var contents = $elm;
-            if ( classAdded ){
-              contents.removeClass( classAdded );
-              classAdded = null;
-            }
-
-            if (angular.isFunction($scope.col.cellClass)) {
-              classAdded = $scope.col.cellClass($scope.grid, $scope.row, 
$scope.col, $scope.rowRenderIndex, $scope.colRenderIndex);
-            }
-            else {
-              classAdded = $scope.col.cellClass;
-            }
-            contents.addClass(classAdded);
-          };
-
-          if ($scope.col.cellClass) {
-            updateClass();
-          }
-          
-          // Register a data change watch that would get triggered whenever 
someone edits a cell or modifies column defs
-          var dataChangeDereg = $scope.grid.registerDataChangeCallback( 
updateClass, [uiGridConstants.dataChange.COLUMN, 
uiGridConstants.dataChange.EDIT]);
-          
-          // watch the col and row to see if they change - which would 
indicate that we've scrolled or sorted or otherwise
-          // changed the row/col that this cell relates to, and we need to 
re-evaluate cell classes and maybe other things
-          var cellChangeFunction = function( n, o ){
-            if ( n !== o ) {
-              if ( classAdded || $scope.col.cellClass ){
-                updateClass();
-              }
-
-              // See if the column's internal class has changed
-              var newColClass = $scope.col.getColClass(false);
-              if (newColClass !== initColClass) {
-                $elm.removeClass(initColClass);
-                $elm.addClass(newColClass);
-                initColClass = newColClass;
-              }
-            }
-          };
-
-          // TODO(c0bra): Turn this into a deep array watch
-/*        shouldn't be needed any more given track by col.name
-          var colWatchDereg = $scope.$watch( 'col', cellChangeFunction );
-*/
-          var rowWatchDereg = $scope.$watch( 'row', cellChangeFunction );
-          
-          
-          var deregisterFunction = function() {
-            dataChangeDereg();
-//            colWatchDereg();
-            rowWatchDereg(); 
-          };
-          
-          $scope.$on( '$destroy', deregisterFunction );
-          $elm.on( '$destroy', deregisterFunction );
-        }
-      };
-    }
-  };
-
-  return uiGridCell;
-}]);
-
-
-(function(){
-
-angular.module('ui.grid')
-.service('uiGridColumnMenuService', [ 'i18nService', 'uiGridConstants', 
'gridUtil',
-function ( i18nService, uiGridConstants, gridUtil ) {
-/**
- *  @ngdoc service
- *  @name ui.grid.service:uiGridColumnMenuService
- *
- *  @description Services for working with column menus, factored out
- *  to make the code easier to understand
- */
-
-  var service = {
-    /**
-     * @ngdoc method
-     * @methodOf ui.grid.service:uiGridColumnMenuService
-     * @name initialize
-     * @description  Sets defaults, puts a reference to the $scope on
-     * the uiGridController
-     * @param {$scope} $scope the $scope from the uiGridColumnMenu
-     * @param {controller} uiGridCtrl the uiGridController for the grid
-     * we're on
-     *
-     */
-    initialize: function( $scope, uiGridCtrl ){
-      $scope.grid = uiGridCtrl.grid;
-
-      // Store a reference to this link/controller in the main uiGrid 
controller
-      // to allow showMenu later
-      uiGridCtrl.columnMenuScope = $scope;
-
-      // Save whether we're shown or not so the columns can check
-      $scope.menuShown = false;
-    },
-
-
-    /**
-     * @ngdoc method
-     * @methodOf ui.grid.service:uiGridColumnMenuService
-     * @name setColMenuItemWatch
-     * @description  Setup a watch on $scope.col.menuItems, and update
-     * menuItems based on this.  $scope.col needs to be set by the column
-     * before calling the menu.
-     * @param {$scope} $scope the $scope from the uiGridColumnMenu
-     * @param {controller} uiGridCtrl the uiGridController for the grid
-     * we're on
-     *
-     */
-    setColMenuItemWatch: function ( $scope ){
-      var deregFunction = $scope.$watch('col.menuItems', function (n) {
-        if (typeof(n) !== 'undefined' && n && angular.isArray(n)) {
-          n.forEach(function (item) {
-            if (typeof(item.context) === 'undefined' || !item.context) {
-              item.context = {};
-            }
-            item.context.col = $scope.col;
-          });
-
-          $scope.menuItems = $scope.defaultMenuItems.concat(n);
-        }
-        else {
-          $scope.menuItems = $scope.defaultMenuItems;
-        }
-      });
-
-      $scope.$on( '$destroy', deregFunction );
-    },
-
-
-    /**
-     * @ngdoc boolean
-     * @name enableSorting
-     * @propertyOf ui.grid.class:GridOptions.columnDef
-     * @description (optional) True by default. When enabled, this setting 
adds sort
-     * widgets to the column header, allowing sorting of the data in the 
individual column.
-     */
-    /**
-     * @ngdoc method
-     * @methodOf ui.grid.service:uiGridColumnMenuService
-     * @name sortable
-     * @description  determines whether this column is sortable
-     * @param {$scope} $scope the $scope from the uiGridColumnMenu
-     *
-     */
-    sortable: function( $scope ) {
-      if ( $scope.grid.options.enableSorting && typeof($scope.col) !== 
'undefined' && $scope.col && $scope.col.enableSorting) {
-        return true;
-      }
-      else {
-        return false;
-      }
-    },
-
-    /**
-     * @ngdoc method
-     * @methodOf ui.grid.service:uiGridColumnMenuService
-     * @name isActiveSort
-     * @description  determines whether the requested sort direction is 
current active, to
-     * allow highlighting in the menu
-     * @param {$scope} $scope the $scope from the uiGridColumnMenu
-     * @param {string} direction the direction that we'd have selected for us 
to be active
-     *
-     */
-    isActiveSort: function( $scope, direction ){
-      return (typeof($scope.col) !== 'undefined' && typeof($scope.col.sort) 
!== 'undefined' &&
-              typeof($scope.col.sort.direction) !== 'undefined' && 
$scope.col.sort.direction === direction);
-
-    },
-
-    /**
-     * @ngdoc method
-     * @methodOf ui.grid.service:uiGridColumnMenuService
-     * @name suppressRemoveSort
-     * @description  determines whether we should suppress the removeSort 
option
-     * @param {$scope} $scope the $scope from the uiGridColumnMenu
-     *
-     */
-    suppressRemoveSort: function( $scope ) {
-      if ($scope.col && $scope.col.suppressRemoveSort) {
-        return true;
-      }
-      else {
-        return false;
-      }
-    },
-
-
-    /**
-     * @ngdoc boolean
-     * @name enableHiding
-     * @propertyOf ui.grid.class:GridOptions.columnDef
-     * @description (optional) True by default. When set to false, this 
setting prevents a user from hiding the column
-     * using the column menu or the grid menu.
-     */
-    /**
-     * @ngdoc method
-     * @methodOf ui.grid.service:uiGridColumnMenuService
-     * @name hideable
-     * @description  determines whether a column can be hidden, by checking 
the enableHiding columnDef option
-     * @param {$scope} $scope the $scope from the uiGridColumnMenu
-     *
-     */
-    hideable: function( $scope ) {
-      if (typeof($scope.col) !== 'undefined' && $scope.col && 
$scope.col.colDef && $scope.col.colDef.enableHiding === false ) {
-        return false;
-      }
-      else {
-        return true;
-      }
-    },
-
-
-    /**
-     * @ngdoc method
-     * @methodOf ui.grid.service:uiGridColumnMenuService
-     * @name getDefaultMenuItems
-     * @description  returns the default menu items for a column menu
-     * @param {$scope} $scope the $scope from the uiGridColumnMenu
-     *
-     */
-    getDefaultMenuItems: function( $scope ){
-      return [
-        {
-          title: i18nService.getSafeText('sort.ascending'),
-          icon: 'ui-grid-icon-sort-alt-up',
-          action: function($event) {
-            $event.stopPropagation();
-            $scope.sortColumn($event, uiGridConstants.ASC);
-          },
-          shown: function () {
-            return service.sortable( $scope );
-          },
-          active: function() {
-            return service.isActiveSort( $scope, uiGridConstants.ASC);
-          }
-        },
-        {
-          title: i18nService.getSafeText('sort.descending'),
-          icon: 'ui-grid-icon-sort-alt-down',
-          action: function($event) {
-            $event.stopPropagation();
-            $scope.sortColumn($event, uiGridConstants.DESC);
-          },
-          shown: function() {
-            return service.sortable( $scope );
-          },
-          active: function() {
-            return service.isActiveSort( $scope, uiGridConstants.DESC);
-          }
-        },
-        {
-          title: i18nService.getSafeText('sort.remove'),
-          icon: 'ui-grid-icon-cancel',
-          action: function ($event) {
-            $event.stopPropagation();
-            $scope.unsortColumn();
-          },
-          shown: function() {
-            return service.sortable( $scope ) &&
-                   typeof($scope.col) !== 'undefined' && 
(typeof($scope.col.sort) !== 'undefined' &&
-                   typeof($scope.col.sort.direction) !== 'undefined') && 
$scope.col.sort.direction !== null &&
-                  !service.suppressRemoveSort( $scope );
-          }
-        },
-        {
-          title: i18nService.getSafeText('column.hide'),
-          icon: 'ui-grid-icon-cancel',
-          shown: function() {
-            return service.hideable( $scope );
-          },
-          action: function ($event) {
-            $event.stopPropagation();
-            $scope.hideColumn();
-          }
-        }
-      ];
-    },
-
-
-    /**
-     * @ngdoc method
-     * @methodOf ui.grid.service:uiGridColumnMenuService
-     * @name getColumnElementPosition
-     * @description  gets the position information needed to place the column
-     * menu below the column header
-     * @param {$scope} $scope the $scope from the uiGridColumnMenu
-     * @param {GridCol} column the column we want to position below
-     * @param {element} $columnElement the column element we want to position 
below
-     * @returns {hash} containing left, top, offset, height, width
-     *
-     */
-    getColumnElementPosition: function( $scope, column, $columnElement ){
-      var positionData = {};
-      positionData.left = $columnElement[0].offsetLeft;
-      positionData.top = $columnElement[0].offsetTop;
-      positionData.parentLeft = $columnElement[0].offsetParent.offsetLeft;
-
-      // Get the grid scrollLeft
-      positionData.offset = 0;
-      if (column.grid.options.offsetLeft) {
-        positionData.offset = column.grid.options.offsetLeft;
-      }
-
-      positionData.height = gridUtil.elementHeight($columnElement, true);
-      positionData.width = gridUtil.elementWidth($columnElement, true);
-
-      return positionData;
-    },
-
-
-    /**
-     * @ngdoc method
-     * @methodOf ui.grid.service:uiGridColumnMenuService
-     * @name repositionMenu
-     * @description  Reposition the menu below the new column.  If the menu 
has no child nodes
-     * (i.e. it's not currently visible) then we guess it's width at 100, 
we'll be called again
-     * later to fix it
-     * @param {$scope} $scope the $scope from the uiGridColumnMenu
-     * @param {GridCol} column the column we want to position below
-     * @param {hash} positionData a hash containing left, top, offset, height, 
width
-     * @param {element} $elm the column menu element that we want to reposition
-     * @param {element} $columnElement the column element that we want to 
reposition underneath
-     *
-     */
-    repositionMenu: function( $scope, column, positionData, $elm, 
$columnElement ) {
-      var menu = $elm[0].querySelectorAll('.ui-grid-menu');
-
-      // It's possible that the render container of the column we're attaching 
to is
-      // offset from the grid (i.e. pinned containers), we need to get the 
difference in the offsetLeft
-      // between the render container and the grid
-      var renderContainerElm = gridUtil.closestElm($columnElement, 
'.ui-grid-render-container');
-      var renderContainerOffset = 
renderContainerElm.getBoundingClientRect().left - 
$scope.grid.element[0].getBoundingClientRect().left;
-
-      var containerScrollLeft = 
renderContainerElm.querySelectorAll('.ui-grid-viewport')[0].scrollLeft;
-
-      // default value the last width for _this_ column, otherwise last width 
for _any_ column, otherwise default to 170
-      var myWidth = column.lastMenuWidth ? column.lastMenuWidth : ( 
$scope.lastMenuWidth ? $scope.lastMenuWidth : 170);
-      var paddingRight = column.lastMenuPaddingRight ? 
column.lastMenuPaddingRight : ( $scope.lastMenuPaddingRight ? 
$scope.lastMenuPaddingRight : 10);
-
-      if ( menu.length !== 0 ){
-        var mid = menu[0].querySelectorAll('.ui-grid-menu-mid');
-        if ( mid.length !== 0 && !angular.element(mid).hasClass('ng-hide') ) {
-          myWidth = gridUtil.elementWidth(menu, true);
-          $scope.lastMenuWidth = myWidth;
-          column.lastMenuWidth = myWidth;
-
-          // TODO(c0bra): use padding-left/padding-right based on document 
direction (ltr/rtl), place menu on proper side
-          // Get the column menu right padding
-          paddingRight = 
parseInt(gridUtil.getStyles(angular.element(menu)[0])['paddingRight'], 10);
-          $scope.lastMenuPaddingRight = paddingRight;
-          column.lastMenuPaddingRight = paddingRight;
-        }
-      }
-
-      var left = positionData.left + renderContainerOffset - 
containerScrollLeft + positionData.parentLeft + positionData.width - myWidth + 
paddingRight;
-      if (left < positionData.offset){
-        left = positionData.offset;
-      }
-
-      $elm.css('left', left + 'px');
-      $elm.css('top', (positionData.top + positionData.height) + 'px');
-    }
-
-  };
-
-  return service;
-}])
-
-
-.directive('uiGridColumnMenu', ['$timeout', 'gridUtil', 'uiGridConstants', 
'uiGridColumnMenuService', '$document',
-function ($timeout, gridUtil, uiGridConstants, uiGridColumnMenuService, 
$document) {
-/**
- * @ngdoc directive
- * @name ui.grid.directive:uiGridColumnMenu
- * @description  Provides the column menu framework, leverages uiGridMenu 
underneath
- *
- */
-
-  var uiGridColumnMenu = {
-    priority: 0,
-    scope: true,
-    require: '^uiGrid',
-    templateUrl: 'ui-grid/uiGridColumnMenu',
-    replace: true,
-    link: function ($scope, $elm, $attrs, uiGridCtrl) {
-      uiGridColumnMenuService.initialize( $scope, uiGridCtrl );
-
-      $scope.defaultMenuItems = uiGridColumnMenuService.getDefaultMenuItems( 
$scope );
-
-      // Set the menu items for use with the column menu. The user can later 
add additional items via the watch
-      $scope.menuItems = $scope.defaultMenuItems;
-      uiGridColumnMenuService.setColMenuItemWatch( $scope );
-
-
-      /**
-       * @ngdoc method
-       * @methodOf ui.grid.directive:uiGridColumnMenu
-       * @name showMenu
-       * @description Shows the column menu.  If the menu is already displayed 
it
-       * calls the menu to ask it to hide (it will animate), then it 
repositions the menu
-       * to the right place whilst hidden (it will make an assumption on menu 
width),
-       * then it asks the menu to show (it will animate), then it repositions 
the menu again
-       * once we can calculate it's size.
-       * @param {GridCol} column the column we want to position below
-       * @param {element} $columnElement the column element we want to 
position below
-       */
-      $scope.showMenu = function(column, $columnElement, event) {
-        // Swap to this column
-        $scope.col = column;
-
-        // Get the position information for the column element
-        var colElementPosition = 
uiGridColumnMenuService.getColumnElementPosition( $scope, column, 
$columnElement );
-
-        if ($scope.menuShown) {
-          // we want to hide, then reposition, then show, but we want to wait 
for animations
-          // we set a variable, and then rely on the menu-hidden event to call 
the reposition and show
-          $scope.colElement = $columnElement;
-          $scope.colElementPosition = colElementPosition;
-          $scope.hideThenShow = true;
-
-          $scope.$broadcast('hide-menu', { originalEvent: event });
-        } else {
-          $scope.menuShown = true;
-          uiGridColumnMenuService.repositionMenu( $scope, column, 
colElementPosition, $elm, $columnElement );
-
-          $scope.colElement = $columnElement;
-          $scope.colElementPosition = colElementPosition;
-          $scope.$broadcast('show-menu', { originalEvent: event });
-
-        }
-      };
-
-
-      /**
-       * @ngdoc method
-       * @methodOf ui.grid.directive:uiGridColumnMenu
-       * @name hideMenu
-       * @description Hides the column menu.
-       * @param {boolean} broadcastTrigger true if we were triggered by a 
broadcast
-       * from the menu itself - in which case don't broadcast again as we'll 
get
-       * an infinite loop
-       */
-      $scope.hideMenu = function( broadcastTrigger ) {
-        $scope.menuShown = false;
-        if ( !broadcastTrigger ){
-          $scope.$broadcast('hide-menu');
-        }
-      };
-
-
-      $scope.$on('menu-hidden', function() {
-        if ( $scope.hideThenShow ){
-          delete $scope.hideThenShow;
-
-          uiGridColumnMenuService.repositionMenu( $scope, $scope.col, 
$scope.colElementPosition, $elm, $scope.colElement );
-          $scope.$broadcast('show-menu');
-
-          $scope.menuShown = true;
-        } else {
-          $scope.hideMenu( true );
-
-          if ($scope.col) {
-            //Focus on the menu button
-            gridUtil.focus.bySelector($document, '.ui-grid-header-cell.' + 
$scope.col.getColClass()+ ' .ui-grid-column-menu-button', $scope.col.grid, 
false);
-          }
-        }
-      });
-
-      $scope.$on('menu-shown', function() {
-        $timeout( function() {
-          uiGridColumnMenuService.repositionMenu( $scope, $scope.col, 
$scope.colElementPosition, $elm, $scope.colElement );
-          //Focus on the first item
-          gridUtil.focus.bySelector($document, '.ui-grid-menu-items 
.ui-grid-menu-item', true);
-          delete $scope.colElementPosition;
-          delete $scope.columnElement;
-        }, 200);
-      });
-
-
-      /* Column methods */
-      $scope.sortColumn = function (event, dir) {
-        event.stopPropagation();
-
-        $scope.grid.sortColumn($scope.col, dir, true)
-          .then(function () {
-            $scope.grid.refresh();
-            $scope.hideMenu();
-          });
-      };
-
-      $scope.unsortColumn = function () {
-        $scope.col.unsort();
-
-        $scope.grid.refresh();
-        $scope.hideMenu();
-      };
-
-      //Since we are hiding this column the default hide action will fail so 
we need to focus somewhere else.
-      var setFocusOnHideColumn = function(){
-        $timeout(function(){
-          // Get the UID of the first
-          var focusToGridMenu = function(){
-            return gridUtil.focus.byId('grid-menu', $scope.grid);
-          };
-
-          var thisIndex;
-          $scope.grid.columns.some(function(element, index){
-            if (angular.equals(element, $scope.col)) {
-              thisIndex = index;
-              return true;
-            }
-          });
-
-          var previousVisibleCol;
-          // Try and find the next lower or nearest column to focus on
-          $scope.grid.columns.some(function(element, index){
-            if (!element.visible){
-              return false;
-            } // This columns index is below the current column index
-            else if ( index < thisIndex){
-              previousVisibleCol = element;
-            } // This elements index is above this column index and we haven't 
found one that is lower
-            else if ( index > thisIndex && !previousVisibleCol) {
-              // This is the next best thing
-              previousVisibleCol = element;
-              // We've found one so use it.
-              return true;
-            } // We've reached an element with an index above this column and 
the previousVisibleCol variable has been set
-            else if (index > thisIndex && previousVisibleCol) {
-              // We are done.
-              return true;
-            }
-          });
-          // If found then focus on it
-          if (previousVisibleCol){
-            var colClass = previousVisibleCol.getColClass();
-            gridUtil.focus.bySelector($document, '.ui-grid-header-cell.' + 
colClass+ ' .ui-grid-header-cell-primary-focus', true).then(angular.noop, 
function(reason){
-              if (reason !== 'canceled'){ // If this is canceled then don't 
perform the action
-                //The fallback action is to focus on the grid menu
-                return focusToGridMenu();
-              }
-            });
-          } else {
-            // Fallback action to focus on the grid menu
-            focusToGridMenu();
-          }
-        });
-      };
-
-      $scope.hideColumn = function () {
-        $scope.col.colDef.visible = false;
-        $scope.col.visible = false;
-
-        $scope.grid.queueGridRefresh();
-        $scope.hideMenu();
-        $scope.grid.api.core.notifyDataChange( 
uiGridConstants.dataChange.COLUMN );
-        $scope.grid.api.core.raise.columnVisibilityChanged( $scope.col );
-
-        // We are hiding so the default action of focusing on the button that 
opened this menu will fail.
-        setFocusOnHideColumn();
-      };
-    },
-
-
-
-    controller: ['$scope', function ($scope) {
-      var self = this;
-
-      $scope.$watch('menuItems', function (n) {
-        self.menuItems = n;
-      });
-    }]
-  };
-
-  return uiGridColumnMenu;
-
-}]);
-
-})();
-
-(function(){
-  'use strict';
-
-  angular.module('ui.grid').directive('uiGridFilter', ['$compile', 
'$templateCache', 'i18nService', 'gridUtil', function ($compile, 
$templateCache, i18nService, gridUtil) {
-
-    return {
-      compile: function() {
-        return {
-          pre: function ($scope, $elm, $attrs, controllers) {
-            $scope.col.updateFilters = function( filterable ){
-              $elm.children().remove();
-              if ( filterable ){
-                var template = $scope.col.filterHeaderTemplate;
-
-                $elm.append($compile(template)($scope));
-              }
-            };
-
-            $scope.$on( '$destroy', function() {
-              delete $scope.col.updateFilters;
-            });
-          },
-          post: function ($scope, $elm, $attrs, controllers){
-            $scope.aria = i18nService.getSafeText('headerCell.aria');
-            $scope.removeFilter = function(colFilter, index){
-              colFilter.term = null;
-              //Set the focus to the filter input after the action disables 
the button
-              gridUtil.focus.bySelector($elm, '.ui-grid-filter-input-' + 
index);
-            };
-          }
-        };
-      }
-    };
-  }]);
-})();
-
-(function () {
-  'use strict';
-
-  angular.module('ui.grid').directive('uiGridFooterCell', ['$timeout', 
'gridUtil', 'uiGridConstants', '$compile',
-  function ($timeout, gridUtil, uiGridConstants, $compile) {
-    var uiGridFooterCell = {
-      priority: 0,
-      scope: {
-        col: '=',
-        row: '=',
-        renderIndex: '='
-      },
-      replace: true,
-      require: '^uiGrid',
-      compile: function compile(tElement, tAttrs, transclude) {
-        return {
-          pre: function ($scope, $elm, $attrs, uiGridCtrl) {
-            var cellFooter = $compile($scope.col.footerCellTemplate)($scope);
-            $elm.append(cellFooter);
-          },
-          post: function ($scope, $elm, $attrs, uiGridCtrl) {
-            //$elm.addClass($scope.col.getColClass(false));
-            $scope.grid = uiGridCtrl.grid;
-
-            var initColClass = $scope.col.getColClass(false);
-            $elm.addClass(initColClass);
-
-            // apply any footerCellClass
-            var classAdded;
-            var updateClass = function( grid ){
-              var contents = $elm;
-              if ( classAdded ){
-                contents.removeClass( classAdded );
-                classAdded = null;
-              }
-  
-              if (angular.isFunction($scope.col.footerCellClass)) {
-                classAdded = $scope.col.footerCellClass($scope.grid, 
$scope.row, $scope.col, $scope.rowRenderIndex, $scope.colRenderIndex);
-              }
-              else {
-                classAdded = $scope.col.footerCellClass;
-              }
-              contents.addClass(classAdded);
-            };
-  
-            if ($scope.col.footerCellClass) {
-              updateClass();
-            }
-
-            $scope.col.updateAggregationValue();
-
-            // Watch for column changes so we can alter the col cell class 
properly
-/* shouldn't be needed any more, given track by col.name
-            $scope.$watch('col', function (n, o) {
-              if (n !== o) {
-                // See if the column's internal class has changed
-                var newColClass = $scope.col.getColClass(false);
-                if (newColClass !== initColClass) {
-                  $elm.removeClass(initColClass);
-                  $elm.addClass(newColClass);
-                  initColClass = newColClass;
-                }
-              }
-            });
-*/
-
-
-            // Register a data change watch that would get triggered whenever 
someone edits a cell or modifies column defs
-            var dataChangeDereg = $scope.grid.registerDataChangeCallback( 
updateClass, [uiGridConstants.dataChange.COLUMN]);
-            // listen for visible rows change and update aggregation values
-            $scope.grid.api.core.on.rowsRendered( $scope, 
$scope.col.updateAggregationValue );
-            $scope.grid.api.core.on.rowsRendered( $scope, updateClass );
-            $scope.$on( '$destroy', dataChangeDereg );
-          }
-        };
-      }
-    };
-
-    return uiGridFooterCell;
-  }]);
-
-})();
-
-(function () {
-  'use strict';
-
-  angular.module('ui.grid').directive('uiGridFooter', ['$templateCache', 
'$compile', 'uiGridConstants', 'gridUtil', '$timeout', function 
($templateCache, $compile, uiGridConstants, gridUtil, $timeout) {
-
-    return {
-      restrict: 'EA',
-      replace: true,
-      // priority: 1000,
-      require: ['^uiGrid', '^uiGridRenderContainer'],
-      scope: true,
-      compile: function ($elm, $attrs) {
-        return {
-          pre: function ($scope, $elm, $attrs, controllers) {
-            var uiGridCtrl = controllers[0];
-            var containerCtrl = controllers[1];
-
-            $scope.grid = uiGridCtrl.grid;
-            $scope.colContainer = containerCtrl.colContainer;
-
-            containerCtrl.footer = $elm;
-
-            var footerTemplate = $scope.grid.options.footerTemplate;
-            gridUtil.getTemplate(footerTemplate)
-              .then(function (contents) {
-                var template = angular.element(contents);
-
-                var newElm = $compile(template)($scope);
-                $elm.append(newElm);
-
-                if (containerCtrl) {
-                  // Inject a reference to the footer viewport (if it exists) 
into the grid controller for use in the horizontal scroll handler below
-                  var footerViewport = 
$elm[0].getElementsByClassName('ui-grid-footer-viewport')[0];
-
-                  if (footerViewport) {
-                    containerCtrl.footerViewport = footerViewport;
-                  }
-                }
-              });
-          },
-
-          post: function ($scope, $elm, $attrs, controllers) {
-            var uiGridCtrl = controllers[0];
-            var containerCtrl = controllers[1];
-
-            // gridUtil.logDebug('ui-grid-footer link');
-
-            var grid = uiGridCtrl.grid;
-
-            // Don't animate footer cells
-            gridUtil.disableAnimations($elm);
-
-            containerCtrl.footer = $elm;
-
-            var footerViewport = 
$elm[0].getElementsByClassName('ui-grid-footer-viewport')[0];
-            if (footerViewport) {
-              containerCtrl.footerViewport = footerViewport;
-            }
-          }
-        };
-      }
-    };
-  }]);
-
-})();
-(function () {
-  'use strict';
-
-  angular.module('ui.grid').directive('uiGridGridFooter', ['$templateCache', 
'$compile', 'uiGridConstants', 'gridUtil', '$timeout', function 
($templateCache, $compile, uiGridConstants, gridUtil, $timeout) {
-
-    return {
-      restrict: 'EA',
-      replace: true,
-      // priority: 1000,
-      require: '^uiGrid',
-      scope: true,
-      compile: function ($elm, $attrs) {
-        return {
-          pre: function ($scope, $elm, $attrs, uiGridCtrl) {
-
-            $scope.grid = uiGridCtrl.grid;
-
-
-
-            var footerTemplate = $scope.grid.options.gridFooterTemplate;
-            gridUtil.getTemplate(footerTemplate)
-              .then(function (contents) {
-                var template = angular.element(contents);
-
-                var newElm = $compile(template)($scope);
-                $elm.append(newElm);
-              });
-          },
-
-          post: function ($scope, $elm, $attrs, controllers) {
-
-          }
-        };
-      }
-    };
-  }]);
-
-})();
-(function(){
-  'use strict';
-
-  angular.module('ui.grid').directive('uiGridGroupPanel', ["$compile", 
"uiGridConstants", "gridUtil", function($compile, uiGridConstants, gridUtil) {
-    var defaultTemplate = 'ui-grid/ui-grid-group-panel';
-
-    return {
-      restrict: 'EA',
-      replace: true,
-      require: '?^uiGrid',
-      scope: false,
-      compile: function($elm, $attrs) {
-        return {
-          pre: function ($scope, $elm, $attrs, uiGridCtrl) {
-            var groupPanelTemplate = $scope.grid.options.groupPanelTemplate  
|| defaultTemplate;
-
-             gridUtil.getTemplate(groupPanelTemplate)
-              .then(function (contents) {
-                var template = angular.element(contents);
-                
-                var newElm = $compile(template)($scope);
-                $elm.append(newElm);
-              });
-          },
-
-          post: function ($scope, $elm, $attrs, uiGridCtrl) {
-            $elm.bind('$destroy', function() {
-              // scrollUnbinder();
-            });
-          }
-        };
-      }
-    };
-  }]);
-
-})();
-(function(){
-  'use strict';
-
-  angular.module('ui.grid').directive('uiGridHeaderCell', ['$compile', 
'$timeout', '$window', '$document', 'gridUtil', 'uiGridConstants', 
'ScrollEvent', 'i18nService',
-  function ($compile, $timeout, $window, $document, gridUtil, uiGridConstants, 
ScrollEvent, i18nService) {
-    // Do stuff after mouse has been down this many ms on the header cell
-    var mousedownTimeout = 500;
-    var changeModeTimeout = 500;    // length of time between a touch event 
and a mouse event being recognised again, and vice versa
-
-    var uiGridHeaderCell = {
-      priority: 0,
-      scope: {
-        col: '=',
-        row: '=',
-        renderIndex: '='
-      },
-      require: ['^uiGrid', '^uiGridRenderContainer'],
-      replace: true,
-      compile: function() {
-        return {
-          pre: function ($scope, $elm, $attrs) {
-            var cellHeader = $compile($scope.col.headerCellTemplate)($scope);
-            $elm.append(cellHeader);
-          },
-
-          post: function ($scope, $elm, $attrs, controllers) {
-            var uiGridCtrl = controllers[0];
-            var renderContainerCtrl = controllers[1];
-
-            $scope.i18n = {
-              headerCell: i18nService.getSafeText('headerCell'),
-              sort: i18nService.getSafeText('sort')
-            };
-            $scope.isSortPriorityVisible = function() {
-              //show sort priority if column is sorted and there is at least 
one other sorted column
-              return angular.isNumber($scope.col.sort.priority) && 
$scope.grid.columns.some(function(element, index){
-                  return angular.isNumber(element.sort.priority) && element 
!== $scope.col;
-                });
-            };
-            $scope.getSortDirectionAriaLabel = function(){
-              var col = $scope.col;
-              //Trying to recreate this sort of thing but it was getting messy 
having it in the template.
-              //Sort direction {{col.sort.direction == asc ? 'ascending' : ( 
col.sort.direction == desc ? 'descending':'none')}}. {{col.sort.priority ? 
{{columnPriorityText}} {{col.sort.priority}} : ''}
-              var sortDirectionText = col.sort.direction === 
uiGridConstants.ASC ? $scope.i18n.sort.ascending : ( col.sort.direction === 
uiGridConstants.DESC ? $scope.i18n.sort.descending : $scope.i18n.sort.none);
-              var label = sortDirectionText;
-
-              if ($scope.isSortPriorityVisible()) {
-                label = label + '. ' + $scope.i18n.headerCell.priority + ' ' + 
col.sort.priority;
-              }
-              return label;
-            };
-
-            $scope.grid = uiGridCtrl.grid;
-
-            $scope.renderContainer = 
uiGridCtrl.grid.renderContainers[renderContainerCtrl.containerId];
-
-            var initColClass = $scope.col.getColClass(false);
-            $elm.addClass(initColClass);
-
-            // Hide the menu by default
-            $scope.menuShown = false;
-
-            // Put asc and desc sort directions in scope
-            $scope.asc = uiGridConstants.ASC;
-            $scope.desc = uiGridConstants.DESC;
-
-            // Store a reference to menu element
-            var $colMenu = angular.element( 
$elm[0].querySelectorAll('.ui-grid-header-cell-menu') );
-
-            var $contentsElm = angular.element( 
$elm[0].querySelectorAll('.ui-grid-cell-contents') );
-
-
-            // apply any headerCellClass
-            var classAdded;
-            var previousMouseX;
-
-            // filter watchers
-            var filterDeregisters = [];
-
-
-            /*
-             * Our basic approach here for event handlers is that we listen 
for a down event (mousedown or touchstart).
-             * Once we have a down event, we need to work out whether we have 
a click, a drag, or a
-             * hold.  A click would sort the grid (if sortable).  A drag would 
be used by moveable, so
-             * we ignore it.  A hold would open the menu.
-             *
-             * So, on down event, we put in place handlers for move and up 
events, and a timer.  If the
-             * timer expires before we see a move or up, then we have a long 
press and hence a column menu open.
-             * If the up happens before the timer, then we have a click, and 
we sort if the column is sortable.
-             * If a move happens before the timer, then we are doing column 
move, so we do nothing, the moveable feature
-             * will handle it.
-             *
-             * To deal with touch enabled devices that also have mice, we only 
create our handlers when
-             * we get the down event, and we create the corresponding handlers 
- if we're touchstart then
-             * we get touchmove and touchend, if we're mousedown then we get 
mousemove and mouseup.
-             *
-             * We also suppress the click action whilst this is happening - 
otherwise after the mouseup there
-             * will be a click event and that can cause the column menu to 
close
-             *
-             */
-
-            $scope.downFn = function( event ){
-              event.stopPropagation();
-
-              if (typeof(event.originalEvent) !== 'undefined' && 
event.originalEvent !== undefined) {
-                event = event.originalEvent;
-              }
-
-              // Don't show the menu if it's not the left button
-              if (event.button && event.button !== 0) {
-                return;
-              }
-              previousMouseX = event.pageX;
-
-              $scope.mousedownStartTime = (new Date()).getTime();
-              $scope.mousedownTimeout = $timeout(function() { }, 
mousedownTimeout);
-
-              $scope.mousedownTimeout.then(function () {
-                if ( $scope.colMenu ) {
-                  uiGridCtrl.columnMenuScope.showMenu($scope.col, $elm, event);
-                }
-              });
-
-              uiGridCtrl.fireEvent(uiGridConstants.events.COLUMN_HEADER_CLICK, 
{event: event, columnName: $scope.col.colDef.name});
-
-              $scope.offAllEvents();
-              if ( event.type === 'touchstart'){
-                $document.on('touchend', $scope.upFn);
-                $document.on('touchmove', $scope.moveFn);
-              } else if ( event.type === 'mousedown' ){
-                $document.on('mouseup', $scope.upFn);
-                $document.on('mousemove', $scope.moveFn);
-              }
-            };
-
-            $scope.upFn = function( event ){
-              event.stopPropagation();
-              $timeout.cancel($scope.mousedownTimeout);
-              $scope.offAllEvents();
-              $scope.onDownEvents(event.type);
-
-              var mousedownEndTime = (new Date()).getTime();
-              var mousedownTime = mousedownEndTime - $scope.mousedownStartTime;
-
-              if (mousedownTime > mousedownTimeout) {
-                // long click, handled above with mousedown
-              }
-              else {
-                // short click
-                if ( $scope.sortable ){
-                  $scope.handleClick(event);
-                }
-              }
-            };
-
-            $scope.moveFn = function( event ){
-              // Chrome is known to fire some bogus move events.
-              var changeValue = event.pageX - previousMouseX;
-              if ( changeValue === 0 ){ return; }
-
-              // we're a move, so do nothing and leave for column move (if 
enabled) to take over
-              $timeout.cancel($scope.mousedownTimeout);
-              $scope.offAllEvents();
-              $scope.onDownEvents(event.type);
-            };
-
-            $scope.clickFn = function ( event ){
-              event.stopPropagation();
-              $contentsElm.off('click', $scope.clickFn);
-            };
-
-
-            $scope.offAllEvents = function(){
-              $contentsElm.off('touchstart', $scope.downFn);
-              $contentsElm.off('mousedown', $scope.downFn);
-
-              $document.off('touchend', $scope.upFn);
-              $document.off('mouseup', $scope.upFn);
-
-              $document.off('touchmove', $scope.moveFn);
-              $document.off('mousemove', $scope.moveFn);
-
-              $contentsElm.off('click', $scope.clickFn);
-            };
-
-            $scope.onDownEvents = function( type ){
-              // If there is a previous event, then wait a while before
-              // activating the other mode - i.e. if the last event was a 
touch event then
-              // don't enable mouse events for a wee while (500ms or so)
-              // Avoids problems with devices that emulate mouse events when 
you have touch events
-
-              switch (type){
-                case 'touchmove':
-                case 'touchend':
-                  $contentsElm.on('click', $scope.clickFn);
-                  $contentsElm.on('touchstart', $scope.downFn);
-                  $timeout(function(){
-                    $contentsElm.on('mousedown', $scope.downFn);
-                  }, changeModeTimeout);
-                  break;
-                case 'mousemove':
-                case 'mouseup':
-                  $contentsElm.on('click', $scope.clickFn);
-                  $contentsElm.on('mousedown', $scope.downFn);
-                  $timeout(function(){
-                    $contentsElm.on('touchstart', $scope.downFn);
-                  }, changeModeTimeout);
-                  break;
-                default:
-                  $contentsElm.on('click', $scope.clickFn);
-                  $contentsElm.on('touchstart', $scope.downFn);
-                  $contentsElm.on('mousedown', $scope.downFn);
-              }
-            };
-
-
-            var updateHeaderOptions = function( grid ){
-              var contents = $elm;
-              if ( classAdded ){
-                contents.removeClass( classAdded );
-                classAdded = null;
-              }
-
-              if (angular.isFunction($scope.col.headerCellClass)) {
-                classAdded = $scope.col.headerCellClass($scope.grid, 
$scope.row, $scope.col, $scope.rowRenderIndex, $scope.colRenderIndex);
-              }
-              else {
-                classAdded = $scope.col.headerCellClass;
-              }
-              contents.addClass(classAdded);
-
-              $timeout(function (){
-                var rightMostContainer = $scope.grid.renderContainers['right'] 
? $scope.grid.renderContainers['right'] : $scope.grid.renderContainers['body'];
-                $scope.isLastCol = ( $scope.col === 
rightMostContainer.visibleColumnCache[ 
rightMostContainer.visibleColumnCache.length - 1 ] );
-              });
-
-              // Figure out whether this column is sortable or not
-              if (uiGridCtrl.grid.options.enableSorting && 
$scope.col.enableSorting) {
-                $scope.sortable = true;
-              }
-              else {
-                $scope.sortable = false;
-              }
-
-              // Figure out whether this column is filterable or not
-              var oldFilterable = $scope.filterable;
-              if (uiGridCtrl.grid.options.enableFiltering && 
$scope.col.enableFiltering) {
-                $scope.filterable = true;
-              }
-              else {
-                $scope.filterable = false;
-              }
-
-              if ( oldFilterable !== $scope.filterable){
-                if ( typeof($scope.col.updateFilters) !== 'undefined' ){
-                  $scope.col.updateFilters($scope.filterable);
-                }
-
-                // if column is filterable add a filter watcher
-                if ($scope.filterable) {
-                  $scope.col.filters.forEach( function(filter, i) {
-                    filterDeregisters.push($scope.$watch('col.filters[' + i + 
'].term', function(n, o) {
-                      if (n !== o) {
-                        uiGridCtrl.grid.api.core.raise.filterChanged();
-                        uiGridCtrl.grid.api.core.notifyDataChange( 
uiGridConstants.dataChange.COLUMN );
-                        uiGridCtrl.grid.queueGridRefresh();
-                      }
-                    }));
-                  });
-                  $scope.$on('$destroy', function() {
-                    filterDeregisters.forEach( function(filterDeregister) {
-                      filterDeregister();
-                    });
-                  });
-                } else {
-                  filterDeregisters.forEach( function(filterDeregister) {
-                    filterDeregister();
-                  });
-                }
-
-              }
-
-              // figure out whether we support column menus
-              if ($scope.col.grid.options && 
$scope.col.grid.options.enableColumnMenus !== false &&
-                      $scope.col.colDef && $scope.col.colDef.enableColumnMenu 
!== false){
-                $scope.colMenu = true;
-              } else {
-                $scope.colMenu = false;
-              }
-
-              /**
-              * @ngdoc property
-              * @name enableColumnMenu
-              * @propertyOf ui.grid.class:GridOptions.columnDef
-              * @description if column menus are enabled, controls the column 
menus for this specific
-              * column (i.e. if gridOptions.enableColumnMenus, then you can 
control column menus
-              * using this option. If gridOptions.enableColumnMenus === false 
then you get no column
-              * menus irrespective of the value of this option ).  Defaults to 
true.
-              *
-              */
-              /**
-              * @ngdoc property
-              * @name enableColumnMenus
-              * @propertyOf ui.grid.class:GridOptions.columnDef
-              * @description Override for column menus everywhere - if set to 
false then you get no
-              * column menus.  Defaults to true.
-              *
-              */
-
-              $scope.offAllEvents();
-
-              if ($scope.sortable || $scope.colMenu) {
-                $scope.onDownEvents();
-
-                $scope.$on('$destroy', function () {
-                  $scope.offAllEvents();
-                });
-              }
-            };
-
-/*
-            $scope.$watch('col', function (n, o) {
-              if (n !== o) {
-                // See if the column's internal class has changed
-                var newColClass = $scope.col.getColClass(false);
-                if (newColClass !== initColClass) {
-                  $elm.removeClass(initColClass);
-                  $elm.addClass(newColClass);
-                  initColClass = newColClass;
-                }
-              }
-            });
-*/
-            updateHeaderOptions();
-
-            // Register a data change watch that would get triggered whenever 
someone edits a cell or modifies column defs
-            var dataChangeDereg = $scope.grid.registerDataChangeCallback( 
updateHeaderOptions, [uiGridConstants.dataChange.COLUMN]);
-
-            $scope.$on( '$destroy', dataChangeDereg );
-
-            $scope.handleClick = function(event) {
-              // If the shift key is being held down, add this column to the 
sort
-              var add = false;
-              if (event.shiftKey) {
-                add = true;
-              }
-
-              // Sort this column then rebuild the grid's rows
-              uiGridCtrl.grid.sortColumn($scope.col, add)
-                .then(function () {
-                  if (uiGridCtrl.columnMenuScope) { 
uiGridCtrl.columnMenuScope.hideMenu(); }
-                  uiGridCtrl.grid.refresh();
-                });
-            };
-
-
-            $scope.toggleMenu = function(event) {
-              event.stopPropagation();
-
-              // If the menu is already showing...
-              if (uiGridCtrl.columnMenuScope.menuShown) {
-                // ... and we're the column the menu is on...
-                if (uiGridCtrl.columnMenuScope.col === $scope.col) {
-                  // ... hide it
-                  uiGridCtrl.columnMenuScope.hideMenu();
-                }
-                // ... and we're NOT the column the menu is on
-                else {
-                  // ... move the menu to our column
-                  uiGridCtrl.columnMenuScope.showMenu($scope.col, $elm);
-                }
-              }
-              // If the menu is NOT showing
-              else {
-                // ... show it on our column
-                uiGridCtrl.columnMenuScope.showMenu($scope.col, $elm);
-              }
-            };
-          }
-        };
-      }
-    };
-
-    return uiGridHeaderCell;
-  }]);
-
-})();
-
-(function(){
-  'use strict';
-
-  angular.module('ui.grid').directive('uiGridHeader', ['$templateCache', 
'$compile', 'uiGridConstants', 'gridUtil', '$timeout', 'ScrollEvent',
-    function($templateCache, $compile, uiGridConstants, gridUtil, $timeout, 
ScrollEvent) {
-    var defaultTemplate = 'ui-grid/ui-grid-header';
-    var emptyTemplate = 'ui-grid/ui-grid-no-header';
-
-    return {
-      restrict: 'EA',
-      // templateUrl: 'ui-grid/ui-grid-header',
-      replace: true,
-      // priority: 1000,
-      require: ['^uiGrid', '^uiGridRenderContainer'],
-      scope: true,
-      compile: function($elm, $attrs) {
-        return {
-          pre: function ($scope, $elm, $attrs, controllers) {
-            var uiGridCtrl = controllers[0];
-            var containerCtrl = controllers[1];
-
-            $scope.grid = uiGridCtrl.grid;
-            $scope.colContainer = containerCtrl.colContainer;
-
-            updateHeaderReferences();
-            
-            var headerTemplate;
-            if (!$scope.grid.options.showHeader) {
-              headerTemplate = emptyTemplate;
-            }
-            else {
-              headerTemplate = ($scope.grid.options.headerTemplate) ? 
$scope.grid.options.headerTemplate : defaultTemplate;            
-            }
-
-            gridUtil.getTemplate(headerTemplate)
-              .then(function (contents) {
-                var template = angular.element(contents);
-                
-                var newElm = $compile(template)($scope);
-                $elm.replaceWith(newElm);
-
-                // And update $elm to be the new element
-                $elm = newElm;
-
-                updateHeaderReferences();
-
-                if (containerCtrl) {
-                  // Inject a reference to the header viewport (if it exists) 
into the grid controller for use in the horizontal scroll handler below
-                  var headerViewport = 
$elm[0].getElementsByClassName('ui-grid-header-viewport')[0];
-
-
-                  if (headerViewport) {
-                    containerCtrl.headerViewport = headerViewport;
-                    angular.element(headerViewport).on('scroll', 
scrollHandler);
-                    $scope.$on('$destroy', function () {
-                      angular.element(headerViewport).off('scroll', 
scrollHandler);
-                    });
-                  }
-                }
-
-                $scope.grid.queueRefresh();
-              });
-
-            function updateHeaderReferences() {
-              containerCtrl.header = containerCtrl.colContainer.header = $elm;
-
-              var headerCanvases = 
$elm[0].getElementsByClassName('ui-grid-header-canvas');
-
-              if (headerCanvases.length > 0) {
-                containerCtrl.headerCanvas = 
containerCtrl.colContainer.headerCanvas = headerCanvases[0];
-              }
-              else {
-                containerCtrl.headerCanvas = null;
-              }
-            }
-
-            function scrollHandler(evt) {
-              if (uiGridCtrl.grid.isScrollingHorizontally) {
-                return;
-              }
-              var newScrollLeft = 
gridUtil.normalizeScrollLeft(containerCtrl.headerViewport, uiGridCtrl.grid);
-              var horizScrollPercentage = 
containerCtrl.colContainer.scrollHorizontal(newScrollLeft);
-
-              var scrollEvent = new ScrollEvent(uiGridCtrl.grid, null, 
containerCtrl.colContainer, ScrollEvent.Sources.ViewPortScroll);
-              scrollEvent.newScrollLeft = newScrollLeft;
-              if ( horizScrollPercentage > -1 ){
-                scrollEvent.x = { percentage: horizScrollPercentage };
-              }
-
-              uiGridCtrl.grid.scrollContainers(null, scrollEvent);
-            }
-          },
-
-          post: function ($scope, $elm, $attrs, controllers) {
-            var uiGridCtrl = controllers[0];
-            var containerCtrl = controllers[1];
-
-            // gridUtil.logDebug('ui-grid-header link');
-
-            var grid = uiGridCtrl.grid;
-
-            // Don't animate header cells
-            gridUtil.disableAnimations($elm);
-
-            function updateColumnWidths() {
-              // this styleBuilder always runs after the renderContainer, so 
we can rely on the column widths
-              // already being populated correctly
-
-              var columnCache = containerCtrl.colContainer.visibleColumnCache;
-              
-              // Build the CSS
-              // uiGridCtrl.grid.columns.forEach(function (column) {
-              var ret = '';
-              var canvasWidth = 0;
-              columnCache.forEach(function (column) {
-                ret = ret + column.getColClassDefinition();
-                canvasWidth += column.drawnWidth;
-              });
-
-              containerCtrl.colContainer.canvasWidth = canvasWidth;
-              
-              // Return the styles back to buildStyles which pops them into 
the `customStyles` scope variable
-              return ret;
-            }
-            
-            containerCtrl.header = $elm;
-            
-            var headerViewport = 
$elm[0].getElementsByClassName('ui-grid-header-viewport')[0];
-            if (headerViewport) {
-              containerCtrl.headerViewport = headerViewport;
-            }
-
-            //todo: remove this if by injecting gridCtrl into unit tests
-            if (uiGridCtrl) {
-              uiGridCtrl.grid.registerStyleComputation({
-                priority: 15,
-                func: updateColumnWidths
-              });
-            }
-          }
-        };
-      }
-    };
-  }]);
-
-})();
-
-(function(){
-
-angular.module('ui.grid')
-.service('uiGridGridMenuService', [ 'gridUtil', 'i18nService', 
'uiGridConstants', function( gridUtil, i18nService, uiGridConstants ) {
-  /**
-   *  @ngdoc service
-   *  @name ui.grid.gridMenuService
-   *
-   *  @description Methods for working with the grid menu
-   */
-
-  var service = {
-    /**
-     * @ngdoc method
-     * @methodOf ui.grid.gridMenuService
-     * @name initialize
-     * @description Sets up the gridMenu. Most importantly, sets our
-     * scope onto the grid object as grid.gridMenuScope, allowing us
-     * to operate when passed only the grid.  Second most importantly,
-     * we register the 'addToGridMenu' and 'removeFromGridMenu' methods
-     * on the core api.
-     * @param {$scope} $scope the scope of this gridMenu
-     * @param {Grid} grid the grid to which this gridMenu is associated
-     */
-    initialize: function( $scope, grid ){
-      grid.gridMenuScope = $scope;
-      $scope.grid = grid;
-      $scope.registeredMenuItems = [];
-
-      // not certain this is needed, but would be bad to create a memory leak
-      $scope.$on('$destroy', function() {
-        if ( $scope.grid && $scope.grid.gridMenuScope ){
-          $scope.grid.gridMenuScope = null;
-        }
-        if ( $scope.grid ){
-          $scope.grid = null;
-        }
-        if ( $scope.registeredMenuItems ){
-          $scope.registeredMenuItems = null;
-        }
-      });
-
-      $scope.registeredMenuItems = [];
-
-      /**
-       * @ngdoc function
-       * @name addToGridMenu
-       * @methodOf ui.grid.core.api:PublicApi
-       * @description add items to the grid menu.  Used by features
-       * to add their menu items if they are enabled, can also be used by
-       * end users to add menu items.  This method has the advantage of 
allowing
-       * remove again, which can simplify management of which items are 
included
-       * in the menu when.  (Noting that in most cases the shown and active 
functions
-       * provide a better way to handle visibility of menu items)
-       * @param {Grid} grid the grid on which we are acting
-       * @param {array} items menu items in the format as described in the 
tutorial, with
-       * the added note that if you want to use remove you must also specify 
an `id` field,
-       * which is provided when you want to remove an item.  The id should be 
unique.
-       *
-       */
-      grid.api.registerMethod( 'core', 'addToGridMenu', service.addToGridMenu 
);
-
-      /**
-       * @ngdoc function
-       * @name removeFromGridMenu
-       * @methodOf ui.grid.core.api:PublicApi
-       * @description Remove an item from the grid menu based on a provided 
id. Assumes
-       * that the id is unique, removes only the last instance of that id. 
Does nothing if
-       * the specified id is not found
-       * @param {Grid} grid the grid on which we are acting
-       * @param {string} id the id we'd like to remove from the menu
-       *
-       */
-      grid.api.registerMethod( 'core', 'removeFromGridMenu', 
service.removeFromGridMenu );
-    },
-
-
-    /**
-     * @ngdoc function
-     * @name addToGridMenu
-     * @propertyOf ui.grid.gridMenuService
-     * @description add items to the grid menu.  Used by features
-     * to add their menu items if they are enabled, can also be used by
-     * end users to add menu items.  This method has the advantage of allowing
-     * remove again, which can simplify management of which items are included
-     * in the menu when.  (Noting that in most cases the shown and active 
functions
-     * provide a better way to handle visibility of menu items)
-     * @param {Grid} grid the grid on which we are acting
-     * @param {array} items menu items in the format as described in the 
tutorial, with
-     * the added note that if you want to use remove you must also specify an 
`id` field,
-     * which is provided when you want to remove an item.  The id should be 
unique.
-     *
-     */
-    addToGridMenu: function( grid, menuItems ) {
-      if ( !angular.isArray( menuItems ) ) {
-        gridUtil.logError( 'addToGridMenu: menuItems must be an array, and is 
not, not adding any items');
-      } else {
-        if ( grid.gridMenuScope ){
-          grid.gridMenuScope.registeredMenuItems = 
grid.gridMenuScope.registeredMenuItems ? grid.gridMenuScope.registeredMenuItems 
: [];
-          grid.gridMenuScope.registeredMenuItems = 
grid.gridMenuScope.registeredMenuItems.concat( menuItems );
-        } else {
-          gridUtil.logError( 'Asked to addToGridMenu, but gridMenuScope not 
present.  Timing issue?  Please log issue with ui-grid');
-        }
-      }
-    },
-
-
-    /**
-     * @ngdoc function
-     * @name removeFromGridMenu
-     * @methodOf ui.grid.gridMenuService
-     * @description Remove an item from the grid menu based on a provided id.  
Assumes
-     * that the id is unique, removes only the last instance of that id.  Does 
nothing if
-     * the specified id is not found.  If there is no gridMenuScope or 
registeredMenuItems
-     * then do nothing silently - the desired result is those menu items not 
be present and they
-     * aren't.
-     * @param {Grid} grid the grid on which we are acting
-     * @param {string} id the id we'd like to remove from the menu
-     *
-     */
-    removeFromGridMenu: function( grid, id ){
-      var foundIndex = -1;
-
-      if ( grid && grid.gridMenuScope ){
-        grid.gridMenuScope.registeredMenuItems.forEach( function( value, index 
) {
-          if ( value.id === id ){
-            if (foundIndex > -1) {
-              gridUtil.logError( 'removeFromGridMenu: found multiple items 
with the same id, removing only the last' );
-            } else {
-
-              foundIndex = index;
-            }
-          }
-        });
-      }
-
-      if ( foundIndex > -1 ){
-        grid.gridMenuScope.registeredMenuItems.splice( foundIndex, 1 );
-      }
-    },
-
-
-    /**
-     * @ngdoc array
-     * @name gridMenuCustomItems
-     * @propertyOf ui.grid.class:GridOptions
-     * @description (optional) An array of menu items that should be added to
-     * the gridMenu.  Follow the format documented in the tutorial for column
-     * menu customisation.  The context provided to the action function will
-     * include context.grid.  An alternative if working with dynamic menus is 
to use the
-     * provided api - core.addToGridMenu and core.removeFromGridMenu, which 
handles
-     * some of the management of items for you.
-     *
-     */
-    /**
-     * @ngdoc boolean
-     * @name gridMenuShowHideColumns
-     * @propertyOf ui.grid.class:GridOptions
-     * @description true by default, whether the grid menu should allow 
hide/show
-     * of columns
-     *
-     */
-    /**
-     * @ngdoc method
-     * @methodOf ui.grid.gridMenuService
-     * @name getMenuItems
-     * @description Decides the menu items to show in the menu.  This is a
-     * combination of:
-     *
-     * - the default menu items that are always included,
-     * - any menu items that have been provided through the addMenuItem api. 
These
-     *   are typically added by features within the grid
-     * - any menu items included in grid.options.gridMenuCustomItems.  These 
can be
-     *   changed dynamically, as they're always recalculated whenever we show 
the
-     *   menu
-     * @param {$scope} $scope the scope of this gridMenu, from which we can 
find all
-     * the information that we need
-     * @returns {array} an array of menu items that can be shown
-     */
-    getMenuItems: function( $scope ) {
-      var menuItems = [
-        // this is where we add any menu items we want to always include
-      ];
-
-      if ( $scope.grid.options.gridMenuCustomItems ){
-        if ( !angular.isArray( $scope.grid.options.gridMenuCustomItems ) ){
-          gridUtil.logError( 'gridOptions.gridMenuCustomItems must be an 
array, and is not');
-        } else {
-          menuItems = menuItems.concat( 
$scope.grid.options.gridMenuCustomItems );
-        }
-      }
-
-      var clearFilters = [{
-        title: i18nService.getSafeText('gridMenu.clearAllFilters'),
-        action: function ($event) {
-          $scope.grid.clearAllFilters(undefined, true, undefined);
-        },
-        shown: function() {
-          return $scope.grid.options.enableFiltering;
-        },
-        order: 100
-      }];
-      menuItems = menuItems.concat( clearFilters );
-
-      menuItems = menuItems.concat( $scope.registeredMenuItems );
-
-      if ( $scope.grid.options.gridMenuShowHideColumns !== false ){
-        menuItems = menuItems.concat( service.showHideColumns( $scope ) );
-      }
-
-      menuItems.sort(function(a, b){
-        return a.order - b.order;
-      });
-
-      return menuItems;
-    },
-
-
-    /**
-     * @ngdoc array
-     * @name gridMenuTitleFilter
-     * @propertyOf ui.grid.class:GridOptions
-     * @description (optional) A function that takes a title string
-     * (usually the col.displayName), and converts it into a display value.  
The function
-     * must return either a string or a promise.
-     *
-     * Used for internationalization of the grid menu column names - for 
angular-translate
-     * you can pass $translate as the function, for i18nService you can pass 
getSafeText as the
-     * function
-     * @example
-     * <pre>
-     *   gridOptions = {
-     *     gridMenuTitleFilter: $translate
-     *   }
-     * </pre>
-     */
-    /**
-     * @ngdoc method
-     * @methodOf ui.grid.gridMenuService
-     * @name showHideColumns
-     * @description Adds two menu items for each of the columns in columnDefs. 
 One
-     * menu item for hide, one menu item for show.  Each is visible when 
appropriate
-     * (show when column is not visible, hide when column is visible).  Each 
toggles
-     * the visible property on the columnDef using toggleColumnVisibility
-     * @param {$scope} $scope of a gridMenu, which contains a reference to the 
grid
-     */
-    showHideColumns: function( $scope ){
-      var showHideColumns = [];
-      if ( !$scope.grid.options.columnDefs || 
$scope.grid.options.columnDefs.length === 0 || $scope.grid.columns.length === 0 
) {
-        return showHideColumns;
-      }
-
-      // add header for columns
-      showHideColumns.push({
-        title: i18nService.getSafeText('gridMenu.columns'),
-        order: 300
-      });
-
-      $scope.grid.options.gridMenuTitleFilter = 
$scope.grid.options.gridMenuTitleFilter ? 
$scope.grid.options.gridMenuTitleFilter : function( title ) { return title; };
-
-      $scope.grid.options.columnDefs.forEach( function( colDef, index ){
-        if ( colDef.enableHiding !== false ){
-          // add hide menu item - shows an OK icon as we only show when column 
is already visible
-          var menuItem = {
-            icon: 'ui-grid-icon-ok',
-            action: function($event) {
-              $event.stopPropagation();
-              service.toggleColumnVisibility( this.context.gridCol );
-            },
-            shown: function() {
-              return this.context.gridCol.colDef.visible === true || 
this.context.gridCol.colDef.visible === undefined;
-            },
-            context: { gridCol: $scope.grid.getColumn(colDef.name || 
colDef.field) },
-            leaveOpen: true,
-            order: 301 + index * 2
-          };
-          service.setMenuItemTitle( menuItem, colDef, $scope.grid );
-          showHideColumns.push( menuItem );
-
-          // add show menu item - shows no icon as we only show when column is 
invisible
-          menuItem = {
-            icon: 'ui-grid-icon-cancel',
-            action: function($event) {
-              $event.stopPropagation();
-              service.toggleColumnVisibility( this.context.gridCol );
-            },
-            shown: function() {
-              return !(this.context.gridCol.colDef.visible === true || 
this.context.gridCol.colDef.visible === undefined);
-            },
-            context: { gridCol: $scope.grid.getColumn(colDef.name || 
colDef.field) },
-            leaveOpen: true,
-            order: 301 + index * 2 + 1
-          };
-          service.setMenuItemTitle( menuItem, colDef, $scope.grid );
-          showHideColumns.push( menuItem );
-        }
-      });
-      return showHideColumns;
-    },
-
-
-    /**
-     * @ngdoc method
-     * @methodOf ui.grid.gridMenuService
-     * @name setMenuItemTitle
-     * @description Handles the response from gridMenuTitleFilter, adding it 
directly to the menu
-     * item if it returns a string, otherwise waiting for the promise to 
resolve or reject then
-     * putting the result into the title
-     * @param {object} menuItem the menuItem we want to put the title on
-     * @param {object} colDef the colDef from which we can get displayName, 
name or field
-     * @param {Grid} grid the grid, from which we can get the 
options.gridMenuTitleFilter
-     *
-     */
-    setMenuItemTitle: function( menuItem, colDef, grid ){
-      var title = grid.options.gridMenuTitleFilter( colDef.displayName || 
gridUtil.readableColumnName(colDef.name) || colDef.field );
-
-      if ( typeof(title) === 'string' ){
-        menuItem.title = title;
-      } else if ( title.then ){
-        // must be a promise
-        menuItem.title = "";
-        title.then( function( successValue ) {
-          menuItem.title = successValue;
-        }, function( errorValue ) {
-          menuItem.title = errorValue;
-        });
-      } else {
-        gridUtil.logError('Expected gridMenuTitleFilter to return a string or 
a promise, it has returned neither, bad config');
-        menuItem.title = 'badconfig';
-      }
-    },
-
-    /**
-     * @ngdoc method
-     * @methodOf ui.grid.gridMenuService
-     * @name toggleColumnVisibility
-     * @description Toggles the visibility of an individual column.  Expects 
to be
-     * provided a context that has on it a gridColumn, which is the column that
-     * we'll operate upon.  We change the visibility, and refresh the grid as 
appropriate
-     * @param {GridCol} gridCol the column that we want to toggle
-     *
-     */
-    toggleColumnVisibility: function( gridCol ) {
-      gridCol.colDef.visible = !( gridCol.colDef.visible === true || 
gridCol.colDef.visible === undefined );
-
-      gridCol.grid.refresh();
-      gridCol.grid.api.core.notifyDataChange( 
uiGridConstants.dataChange.COLUMN );
-      gridCol.grid.api.core.raise.columnVisibilityChanged( gridCol );
-    }
-  };
-
-  return service;
-}])
-
-
-
-.directive('uiGridMenuButton', ['gridUtil', 'uiGridConstants', 
'uiGridGridMenuService', 'i18nService',
-function (gridUtil, uiGridConstants, uiGridGridMenuService, i18nService) {
-
-  return {
-    priority: 0,
-    scope: true,
-    require: ['^uiGrid'],
-    templateUrl: 'ui-grid/ui-grid-menu-button',
-    replace: true,
-
-    link: function ($scope, $elm, $attrs, controllers) {
-      var uiGridCtrl = controllers[0];
-
-      // For the aria label
-      $scope.i18n = {
-        aria: i18nService.getSafeText('gridMenu.aria')
-      };
-
-      uiGridGridMenuService.initialize($scope, uiGridCtrl.grid);
-
-      $scope.shown = false;
-
-      $scope.toggleMenu = function () {
-        if ( $scope.shown ){
-          $scope.$broadcast('hide-menu');
-          $scope.shown = false;
-        } else {
-          $scope.menuItems = uiGridGridMenuService.getMenuItems( $scope );
-          $scope.$broadcast('show-menu');
-          $scope.shown = true;
-        }
-      };
-
-      $scope.$on('menu-hidden', function() {
-        $scope.shown = false;
-        gridUtil.focus.bySelector($elm, '.ui-grid-icon-container');
-      });
-    }
-  };
-
-}]);
-
-})();
-
-(function(){
-
-/**
- * @ngdoc directive
- * @name ui.grid.directive:uiGridMenu
- * @element style
- * @restrict A
- *
- * @description
- * Allows us to interpolate expressions in `<style>` elements. Angular doesn't 
do this by default as it can/will/might? break in IE8.
- *
- * @example
- <doc:example module="app">
- <doc:source>
- <script>
- var app = angular.module('app', ['ui.grid']);
-
- app.controller('MainCtrl', ['$scope', function ($scope) {
-
- }]);
- </script>
-
- <div ng-controller="MainCtrl">
-   <div ui-grid-menu shown="true"  ></div>
- </div>
- </doc:source>
- <doc:scenario>
- </doc:scenario>
- </doc:example>
- */
-angular.module('ui.grid')
-
-.directive('uiGridMenu', ['$compile', '$timeout', '$window', '$document', 
'gridUtil', 'uiGridConstants', 'i18nService',
-function ($compile, $timeout, $window, $document, gridUtil, uiGridConstants, 
i18nService) {
-  var uiGridMenu = {
-    priority: 0,
-    scope: {
-      // shown: '&',
-      menuItems: '=',
-      autoHide: '=?'
-    },
-    require: '?^uiGrid',
-    templateUrl: 'ui-grid/uiGridMenu',
-    replace: false,
-    link: function ($scope, $elm, $attrs, uiGridCtrl) {
-
-      $scope.dynamicStyles = '';
-
-      var setupHeightStyle = function(gridHeight) {
-        //menu appears under header row, so substract that height from it's 
total
-        // additional 20px for general padding
-        var gridMenuMaxHeight = gridHeight - uiGridCtrl.grid.headerHeight - 20;
-        $scope.dynamicStyles = [
-          '.grid' + uiGridCtrl.grid.id + ' .ui-grid-menu-mid {',
-          'max-height: ' + gridMenuMaxHeight + 'px;',
-          '}'
-        ].join(' ');
-      };
-
-      if (uiGridCtrl) {
-        setupHeightStyle(uiGridCtrl.grid.gridHeight);
-        uiGridCtrl.grid.api.core.on.gridDimensionChanged($scope, 
function(oldGridHeight, oldGridWidth, newGridHeight, newGridWidth) {
-          setupHeightStyle(newGridHeight);
-               });
-      }
-
-      $scope.i18n = {
-        close: i18nService.getSafeText('columnMenu.close')
-      };
-
-    // *** Show/Hide functions ******
-      $scope.showMenu = function(event, args) {
-        if ( !$scope.shown ){
-
-          /*
-           * In order to animate cleanly we remove the ng-if, wait a digest 
cycle, then
-           * animate the removal of the ng-hide.  We can't successfully (so 
far as I can tell)
-           * animate removal of the ng-if, as the menu items aren't there yet. 
 And we don't want
-           * to rely on ng-show only, as that leaves elements in the DOM that 
are needlessly evaluated
-           * on scroll events.
-           *
-           * Note when testing animation that animations don't run on the 
tutorials.  When debugging it looks
-           * like they do, but angular has a default $animate provider that is 
just a stub, and that's what's
-           * being called.  ALso don't be fooled by the fact that your browser 
has actually loaded the
-           * angular-translate.js, it's not using it.  You need to test 
animations in an external application.
-           */
-          $scope.shown = true;
-
-          $timeout( function() {
-            $scope.shownMid = true;
-            $scope.$emit('menu-shown');
-          });
-        } else if ( !$scope.shownMid ) {
-          // we're probably doing a hide then show, so we don't need to wait 
for ng-if
-          $scope.shownMid = true;
-          $scope.$emit('menu-shown');
-        }
-
-        var docEventType = 'click';
-        if (args && args.originalEvent && args.originalEvent.type && 
args.originalEvent.type === 'touchstart') {
-          docEventType = args.originalEvent.type;
-        }
-
-        // Turn off an existing document click handler
-        angular.element(document).off('click touchstart', applyHideMenu);
-        $elm.off('keyup', checkKeyUp);
-        $elm.off('keydown', checkKeyDown);
-
-        // Turn on the document click handler, but in a timeout so it doesn't 
apply to THIS click if there is one
-        $timeout(function() {
-          angular.element(document).on(docEventType, applyHideMenu);
-          $elm.on('keyup', checkKeyUp);
-          $elm.on('keydown', checkKeyDown);
-
-        });
-        //automatically set the focus to the first button element in the now 
open menu.
-        gridUtil.focus.bySelector($elm, 'button[type=button]', true);
-      };
-
-
-      $scope.hideMenu = function(event) {
-        if ( $scope.shown ){
-          /*
-           * In order to animate cleanly we animate the addition of ng-hide, 
then use a $timeout to
-           * set the ng-if (shown = false) after the animation runs.  In 
theory we can cascade off the
-           * callback on the addClass method, but it is very unreliable with 
unit tests for no discernable reason.
-           *
-           * The user may have clicked on the menu again whilst
-           * we're waiting, so we check that the mid isn't shown before 
applying the ng-if.
-           */
-          $scope.shownMid = false;
-          $timeout( function() {
-            if ( !$scope.shownMid ){
-              $scope.shown = false;
-              $scope.$emit('menu-hidden');
-            }
-          }, 200);
-        }
-
-        angular.element(document).off('click touchstart', applyHideMenu);
-        $elm.off('keyup', checkKeyUp);
-        $elm.off('keydown', checkKeyDown);
-      };
-
-      $scope.$on('hide-menu', function (event, args) {
-        $scope.hideMenu(event, args);
-      });
-
-      $scope.$on('show-menu', function (event, args) {
-        $scope.showMenu(event, args);
-      });
-
-
-    // *** Auto hide when click elsewhere ******
-      var applyHideMenu = function(){
-        if ($scope.shown) {
-          $scope.$apply(function () {
-            $scope.hideMenu();
-          });
-        }
-      };
-
-      // close menu on ESC and keep tab cyclical
-      var checkKeyUp = function(event) {
-        if (event.keyCode === 27) {
-          $scope.hideMenu();
-        }
-      };
-
-      var checkKeyDown = function(event) {
-        var setFocus = function(elm) {
-          elm.focus();
-          event.preventDefault();
-          return false;
-        };
-        if (event.keyCode === 9) {
-          var firstMenuItem, lastMenuItem;
-          var menuItemButtons = 
$elm[0].querySelectorAll('button:not(.ng-hide)');
-          if (menuItemButtons.length > 0) {
-            firstMenuItem = menuItemButtons[0];
-            lastMenuItem = menuItemButtons[menuItemButtons.length - 1];
-            if (event.target === lastMenuItem && !event.shiftKey) {
-              setFocus(firstMenuItem);
-            } else if (event.target === firstMenuItem && event.shiftKey) {
-              setFocus(lastMenuItem);
-            }
-          }
-        }
-      };
-
-      if (typeof($scope.autoHide) === 'undefined' || $scope.autoHide === 
undefined) {
-        $scope.autoHide = true;
-      }
-
-      if ($scope.autoHide) {
-        angular.element($window).on('resize', applyHideMenu);
-      }
-
-      $scope.$on('$destroy', function () {
-        angular.element(document).off('click touchstart', applyHideMenu);
-      });
-
-
-      $scope.$on('$destroy', function() {
-        angular.element($window).off('resize', applyHideMenu);
-      });
-
-      if (uiGridCtrl) {
-       $scope.$on('$destroy', uiGridCtrl.grid.api.core.on.scrollBegin($scope, 
applyHideMenu ));
-      }
-
-      $scope.$on('$destroy', $scope.$on(uiGridConstants.events.ITEM_DRAGGING, 
applyHideMenu ));
-    }
-  };
-
-  return uiGridMenu;
-}])
-
-.directive('uiGridMenuItem', ['gridUtil', '$compile', 'i18nService', function 
(gridUtil, $compile, i18nService) {
-  var uiGridMenuItem = {
-    priority: 0,
-    scope: {
-      name: '=',
-      active: '=',
-      action: '=',
-      icon: '=',
-      shown: '=',
-      context: '=',
-      templateUrl: '=',
-      leaveOpen: '=',
-      screenReaderOnly: '='
-    },
-    require: ['?^uiGrid'],
-    templateUrl: 'ui-grid/uiGridMenuItem',
-    replace: false,
-    compile: function() {
-      return {
-        pre: function ($scope, $elm) {
-          if ($scope.templateUrl) {
-            gridUtil.getTemplate($scope.templateUrl)
-                .then(function (contents) {
-                  var template = angular.element(contents);
-
-                  var newElm = $compile(template)($scope);
-                  $elm.replaceWith(newElm);
-                });
-          }
-        },
-        post: function ($scope, $elm, $attrs, controllers) {
-          var uiGridCtrl = controllers[0];
-
-          // TODO(c0bra): validate that shown and active are functions if 
they're defined. An exception is already thrown above this though
-          // if (typeof($scope.shown) !== 'undefined' && $scope.shown && 
typeof($scope.shown) !== 'function') {
-          //   throw new TypeError("$scope.shown is defined but not a 
function");
-          // }
-          if (typeof($scope.shown) === 'undefined' || $scope.shown === null) {
-            $scope.shown = function() { return true; };
-          }
-
-          $scope.itemShown = function () {
-            var context = {};
-            if ($scope.context) {
-              context.context = $scope.context;
-            }
-
-            if (typeof(uiGridCtrl) !== 'undefined' && uiGridCtrl) {
-              context.grid = uiGridCtrl.grid;
-            }
-
-            return $scope.shown.call(context);
-          };
-
-          $scope.itemAction = function($event,title) {
-            $event.stopPropagation();
-
-            if (typeof($scope.action) === 'function') {
-              var context = {};
-
-              if ($scope.context) {
-                context.context = $scope.context;
-              }
-
-              // Add the grid to the function call context if the uiGrid 
controller is present
-              if (typeof(uiGridCtrl) !== 'undefined' && uiGridCtrl) {
-                context.grid = uiGridCtrl.grid;
-              }
-


<TRUNCATED>

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to