<commit_before>(function (angular) {
  'use strict';
  angular.module('scrollable-table', [])
    .directive('scrollableTable', ['$timeout', '$q', '$parse', function ($timeout, $q, $parse) {
      return {
        transclude: true,
        restrict: 'E',
        scope: {
          rows: '=watch',
          sortFn: '='
        },
        template: '
' +
          '

' +
          '

' +
          '
',
        controller: ['$scope', '$element', '$attrs', function ($scope, $element, $attrs) {
          // define an API for child directives to view and modify sorting parameters
          this.getSortExpr = function () {
            return $scope.sortExpr;
          };
          this.isAsc = function () {
            return $scope.asc;
          };
          this.setSortExpr = function (exp) {
            $scope.asc = true;
            $scope.sortExpr = exp;
          };
          this.toggleSort = function () {
            $scope.asc = !$scope.asc;
          };

          this.doSort = function (comparatorFn) {
            if (comparatorFn) {
              $scope.rows.sort(function (r1, r2) {
                var compared = comparatorFn(r1, r2);
                return $scope.asc ? compared : compared * -1;
              });
            } else {
              $scope.rows.sort(function (r1, r2) {
                var compared = defaultCompare(r1, r2);
                return $scope.asc ? compared : compared * -1;
              });
            }
          };

          this.renderTalble = function (){
            return waitForRender().then(fixHeaderWidths);
          };

          this.getTableElement = function (){
            return $element;
          };

          /**
           * append handle function to execute after table header resize.
           */
          this.appendTableResizingHandler = function (handler){
            var handlerSequence = $scope.headerResizeHanlers || [];
            for(var i = 0;i < handlerSequence.length;i++){
              if(handlerSequence[i].name === handler.name){
                return;
              }
            }
            handlerSequence.push(handler);
            $scope.headerResizeHanlers = handlerSequence;
          };

          function defaultCompare(row1, row2) {
            var exprParts = $scope.sortExpr.match(/(.+)\s+as\s+(.+)/);
            var scope = {};
            scope[exprParts[1]] = row1;
            var x = $parse(exprParts[2])(scope);

            scope[exprParts[1]] = row2;
            var y = $parse(exprParts[2])(scope);

            if (x === y) return 0;
            return x > y ? 1 : -1;
          }

          function scrollToRow(row) {
            var offset = $element.find(".headerSpacer").height();
            var currentScrollTop = $element.find(".scrollArea").scrollTop();
            $element.find(".scrollArea").scrollTop(currentScrollTop + row.position().top - offset);
          }

          $scope.$on('rowSelected', function (event, rowId) {
            var row = $element.find(".scrollArea table tr[row-id='" + rowId + "']");
            if (row.length === 1) {
              // Ensure that the headers have been fixed before scrolling, to ensure accurate
              // position calculations
              $q.all([waitForRender(), headersAreFixed.promise]).then(function () {
                scrollToRow(row);
              });
            }
          });

          // Set fixed widths for the table headers in case the text overflows.
          // There's no callback for when rendering is complete, so check the visibility of the table
          // periodically -- see http://stackoverflow.com/questions/11125078
          function waitForRender() {
            var deferredRender = $q.defer();
            function wait() {
              if ($element.find("table:visible").length === 0) {
                $timeout(wait, 100);
              } else {
                deferredRender.resolve();
              }
            }

            $timeout(wait);
            return deferredRender.promise;
          }

          var headersAreFixed = $q.defer();

          function fixHeaderWidths() {
            if (!$element.find("thead th .th-inner").length) {
              $element.find("thead th").wrapInner('

');
            }
            if($element.find("thead th .th-inner:not(:has(.box))").length) {
              $element.find("thead th .th-inner:not(:has(.box))").wrapInner('

');
            }

            $element.find("table th .th-inner:visible").each(function (index, el) {
              el = angular.element(el);
              var width = el.parent().width(),
                lastCol = $element.find("table th:visible:last"),
                headerWidth = width;
              if (lastCol.css("text-align") !== "center") {
                var hasScrollbar = $element.find(".scrollArea").height() < $element.find("table").height();
                if (lastCol[0] == el.parent()[0] && hasScrollbar) {
                  headerWidth += $element.find(".scrollArea").width() - $element.find("tbody tr").width();
                  headerWidth = Math.max(headerWidth, width);
                }
              }
              var minWidth = _getScale(el.parent().css('min-width')),
                title = el.parent().attr("title");
              headerWidth = Math.max(minWidth, headerWidth);
              el.css("width", headerWidth);
              if (!title) {
                // ordinary column(not soortableHeader) has box child div element that contained title string.
                title = el.find(".title .ng-scope").html() || el.find(".box").html();
              }
              el.attr("title", title.trim());
            });
            headersAreFixed.resolve();
          }

          // when the data model changes, fix the header widths.  See the comments here:
          // http://docs.angularjs.org/api/ng.$timeout
          $scope.$watch('rows', function (newValue, oldValue) {
            if (newValue) {
              renderChains($element.find('.scrollArea').width());
              // clean sort status and scroll to top of table once records replaced.
              $scope.sortExpr = null;
              // FIXME what is the reason here must scroll to top? This may cause confusing if using scrolling to implement pagination.
              $element.find('.scrollArea').scrollTop(0);
            }
          });

          $scope.asc = !$attrs.hasOwnProperty("desc");
          $scope.sortAttr = $attrs.sortAttr;

          $element.find(".scrollArea").scroll(function (event) {
            $element.find("thead th .th-inner").css('margin-left', 0 - event.target.scrollLeft);
          });

          $scope.$on("renderScrollableTable", function() {
//            $timeout(fixHeaderWidths);
            renderChains($element.find('.scrollArea').width());
          });

          angular.element(window).on('resize', function(){
            $scope.$apply();
          });
          $scope.$watch(function(){
            return $element.find('.scrollArea').width();
          }, function(newWidth, oldWidth){
            if(newWidth * oldWidth <= 0){
              return;
            }
            renderChains();
          });

          function renderChains(){
            var resizeQueue = waitForRender().then(fixHeaderWidths),
              customHandlers = $scope.headerResizeHanlers || [];
            for(var i = 0;i < customHandlers.length;i++){
              resizeQueue = resizeQueue.then(customHandlers[i]);
            }
            return resizeQueue;
          }
        }]
      };
    }])
    .directive('sortableHeader', [function () {
      return {
        transclude: true,
        scope: true,
        require: '^scrollableTable',
        template:
          '
' +
            '
' +
            '

' +
            '' +
            '' +
            '' +
            '' +
            '' +
            '' +
            '
' +
            '
',
        link: function (scope, elm, attrs, tableController) {
          var expr = attrs.on || "a as a." + attrs.col;
          scope.element = angular.element(elm);
          scope.isActive = function () {
            return tableController.getSortExpr() === expr;
          };
          scope.toggleSort = function (e) {
            if (scope.isActive()) {
              tableController.toggleSort();
            } else {
              tableController.setSortExpr(expr);
            }
            tableController.doSort(scope[attrs.comparatorFn]);
            e.preventDefault();
          };
          scope.isAscending = function () {
            if (scope.focused && !scope.isActive()) {
              return true;
            } else {
              return tableController.isAsc();
            }
          };

          scope.enter = function () {
            scope.focused = true;
          };
          scope.leave = function () {
            scope.focused = false;
          };

          scope.isLastCol = function() {
            return elm.parent().find("th:last-child").get(0) === elm.get(0);
          };
        }
      };
    }])
    .directive('resizable', ['$compile', function($compile){
      return {
        restrict: 'A',
        priority: 0,
        require: '^scrollableTable',
        link: function postLink(scope, elm, attrs, tableController){
          tableController.appendTableResizingHandler(function(){
            _init();
          });

          tableController.appendTableResizingHandler(function relayoutHeaders(){
            var tableElement = tableController.getTableElement().find('.scrollArea table');
            if(tableElement.css('table-layout') === 'auto'){
              initRodPos();
            }else{
              _resetColumnsSize(tableElement.parent().width());
            }
          });

          scope.resizing = function(e){
            var screenOffset = tableController.getTableElement().find('.scrollArea').scrollLeft(),
              thInnerElm =  angular.element(e.target).parent(),
              thElm = thInnerElm.parent(),
              startPoint = _getScale(thInnerElm.css('left')) + thInnerElm.width() - screenOffset,
              movingPos = e.pageX,
              _document = angular.element(document),
              _body = angular.element('body'),
              coverPanel = angular.element('.scrollableContainer .resizing-cover'),
              scaler = angular.element('
');

            _body.addClass('scrollable-resizing');
            coverPanel.addClass('active');
            angular.element('.scrollableContainer').append(scaler);
            scaler.css('left', startPoint);

            _document.bind('mousemove', function (e){
              var offsetX = e.pageX - movingPos,
                movedOffset = _getScale(scaler.css('left')) - startPoint,
                widthOfActiveCol = thElm.width(),
                minWidthOfActiveCol = _getScale(thElm.css('min-width')),
                widthOfNextColOfActive = thElm.next().width(),
                minWidthOfNextColOfActive = _getScale(thElm.next().css('min-width'));
              movingPos = e.pageX;
              e.preventDefault();
              if((offsetX > 0 && widthOfNextColOfActive - movedOffset <= minWidthOfNextColOfActive)
                || (offsetX < 0 && widthOfActiveCol + movedOffset <= minWidthOfActiveCol)){
                //stopping resize if user trying to extension and the active/next column already minimised.
                return;
              }
              scaler.css('left', _getScale(scaler.css('left')) + offsetX);
            });
            _document.bind('mouseup', function (e) {
              e.preventDefault();
              scaler.remove();
              _body.removeClass('scrollable-resizing');
              coverPanel.removeClass('active');
              _document.unbind('mousemove');
              _document.unbind('mouseup');

              var offsetX = _getScale(scaler.css('left')) - startPoint,
                newWidth = thElm.width(),
                minWidth = _getScale(thElm.css('min-width')),
                widthOfNextColOfActive = thElm.next().width(),
                minWidthOfNextColOfActive = _getScale(thElm.next().css('min-width')),
                tableElement = tableController.getTableElement().find('.scrollArea table');

              //hold original width of cells, to display cells as their original width after turn table-layout to fixed.
              if(tableElement.css('table-layout') === 'auto'){
                tableElement.find("th .th-inner").each(function (index, el) {
                  el = angular.element(el);
                  var width = el.parent().width();
                  el.parent().css('width', width);
                });
              }

              tableElement.css('table-layout', 'fixed');

              if(offsetX > 0 && widthOfNextColOfActive - offsetX <= minWidthOfNextColOfActive){
                offsetX = widthOfNextColOfActive - minWidthOfNextColOfActive;
              }
              thElm.next().removeAttr('style');
              newWidth += offsetX;
              thElm.css('width', Math.max(minWidth, newWidth));
              thElm.next().css('width', widthOfNextColOfActive - offsetX);
              tableController.renderTalble().then(resizeHeaderWidth());
            });
          };

          function _init(){
            var thInnerElms = elm.find('table th .th-inner');
            if(thInnerElms.find('.resize-rod').length == 0){
              tableController.getTableElement().find('.scrollArea table').css('table-layout', 'auto');
              var resizeRod = angular.element('

');
              thInnerElms.append($compile(resizeRod)(scope));
            }
          }

          function initRodPos(){
            var tableElement = tableController.getTableElement();
            var headerPos = 1;//  1 is the width of right border;
            tableElement.find("table th .th-inner:visible").each(function (index, el) {
              el = angular.element(el);
              var width = el.parent().width(),   //to made header consistent with its parent.
              // if it's the last header, add space for the scrollbar equivalent unless it's centered
                minWidth = _getScale(el.parent().css('min-width'));
              width = Math.max(minWidth, width);
              el.css("left", headerPos);
              headerPos += width;
            });
          }

          function resizeHeaderWidth(){
            var headerPos = 1,//  1 is the width of right border;
              tableElement = tableController.getTableElement();
            tableController.getTableElement().find("table th .th-inner:visible").each(function (index, el) {
              el = angular.element(el);
              var width = el.parent().width(),   //to made header consistent with its parent.
              // if it's the last header, add space for the scrollbar equivalent unless it's centered
                lastCol = tableElement.find("table th:visible:last"),
                minWidth = _getScale(el.parent().css('min-width'));
              width = Math.max(minWidth, width);
              //following are resize stuff, to made th-inner position correct.
              //last column's width should be automatically, to avoid horizontal scroll.
              if (lastCol[0] != el.parent()[0]){
                el.parent().css('width', width);
              }
              el.css("left", headerPos);
              headerPos += width;
            });
          }

          function _resetColumnsSize(tableWidth){
            var tableElement = tableController.getTableElement(),
              columnLength = tableElement.find("table th:visible").length,
              lastCol = tableElement.find("table th:visible:last");
            tableElement.find("table th:visible").each(function (index, el) {
              el = angular.element(el);
              if(lastCol.get(0) == el.get(0)){
                //last column's width should be automaically, to avoid horizontal scroll.
                el.css('width', 'auto');
                return;
              }
              var _width = el.data('width');
              if(/\d+%$/.test(_width)){    //percentage
                _width = Math.ceil(tableWidth * _getScale(_width) / 100);
              } else {
                // if data-width not exist, use average width for each columns.
                _width = tableWidth / columnLength;
              }
              el.css('width', _width + 'px');
            });
            tableController.renderTalble().then(resizeHeaderWidth());
          }
        }
      }
    }]);

  function _getScale(sizeCss){
    return parseInt(sizeCss.replace(/px|%/, ''), 10);
  }
})(angular);<commit_msg>add missed scope<commit_after>(function (angular) {
  'use strict';
  angular.module('scrollable-table', [])
    .directive('scrollableTable', ['$timeout', '$q', '$parse', function ($timeout, $q, $parse) {
      return {
        transclude: true,
        restrict: 'E',
        scope: {
          rows: '=watch',
          sortFn: '='
        },
        template: '
' +
          '

' +
          '

' +
          '
',
        controller: ['$scope', '$element', '$attrs', function ($scope, $element, $attrs) {
          // define an API for child directives to view and modify sorting parameters
          this.getSortExpr = function () {
            return $scope.sortExpr;
          };
          this.isAsc = function () {
            return $scope.asc;
          };
          this.setSortExpr = function (exp) {
            $scope.asc = true;
            $scope.sortExpr = exp;
          };
          this.toggleSort = function () {
            $scope.asc = !$scope.asc;
          };

          this.doSort = function (comparatorFn) {
            if (comparatorFn) {
              $scope.rows.sort(function (r1, r2) {
                var compared = comparatorFn(r1, r2);
                return $scope.asc ? compared : compared * -1;
              });
            } else {
              $scope.rows.sort(function (r1, r2) {
                var compared = defaultCompare(r1, r2);
                return $scope.asc ? compared : compared * -1;
              });
            }
          };

          this.renderTalble = function (){
            return waitForRender().then(fixHeaderWidths);
          };

          this.getTableElement = function (){
            return $element;
          };

          /**
           * append handle function to execute after table header resize.
           */
          this.appendTableResizingHandler = function (handler){
            var handlerSequence = $scope.headerResizeHanlers || [];
            for(var i = 0;i < handlerSequence.length;i++){
              if(handlerSequence[i].name === handler.name){
                return;
              }
            }
            handlerSequence.push(handler);
            $scope.headerResizeHanlers = handlerSequence;
          };

          function defaultCompare(row1, row2) {
            var exprParts = $scope.sortExpr.match(/(.+)\s+as\s+(.+)/);
            var scope = {};
            scope[exprParts[1]] = row1;
            var x = $parse(exprParts[2])(scope);

            scope[exprParts[1]] = row2;
            var y = $parse(exprParts[2])(scope);

            if (x === y) return 0;
            return x > y ? 1 : -1;
          }

          function scrollToRow(row) {
            var offset = $element.find(".headerSpacer").height();
            var currentScrollTop = $element.find(".scrollArea").scrollTop();
            $element.find(".scrollArea").scrollTop(currentScrollTop + row.position().top - offset);
          }

          $scope.$on('rowSelected', function (event, rowId) {
            var row = $element.find(".scrollArea table tr[row-id='" + rowId + "']");
            if (row.length === 1) {
              // Ensure that the headers have been fixed before scrolling, to ensure accurate
              // position calculations
              $q.all([waitForRender(), headersAreFixed.promise]).then(function () {
                scrollToRow(row);
              });
            }
          });

          // Set fixed widths for the table headers in case the text overflows.
          // There's no callback for when rendering is complete, so check the visibility of the table
          // periodically -- see http://stackoverflow.com/questions/11125078
          function waitForRender() {
            var deferredRender = $q.defer();
            function wait() {
              if ($element.find("table:visible").length === 0) {
                $timeout(wait, 100);
              } else {
                deferredRender.resolve();
              }
            }

            $timeout(wait);
            return deferredRender.promise;
          }

          var headersAreFixed = $q.defer();

          function fixHeaderWidths() {
            if (!$element.find("thead th .th-inner").length) {
              $element.find("thead th").wrapInner('

');
            }
            if($element.find("thead th .th-inner:not(:has(.box))").length) {
              $element.find("thead th .th-inner:not(:has(.box))").wrapInner('

');
            }

            $element.find("table th .th-inner:visible").each(function (index, el) {
              el = angular.element(el);
              var width = el.parent().width(),
                lastCol = $element.find("table th:visible:last"),
                headerWidth = width;
              if (lastCol.css("text-align") !== "center") {
                var hasScrollbar = $element.find(".scrollArea").height() < $element.find("table").height();
                if (lastCol[0] == el.parent()[0] && hasScrollbar) {
                  headerWidth += $element.find(".scrollArea").width() - $element.find("tbody tr").width();
                  headerWidth = Math.max(headerWidth, width);
                }
              }
              var minWidth = _getScale(el.parent().css('min-width')),
                title = el.parent().attr("title");
              headerWidth = Math.max(minWidth, headerWidth);
              el.css("width", headerWidth);
              if (!title) {
                // ordinary column(not soortableHeader) has box child div element that contained title string.
                title = el.find(".title .ng-scope").html() || el.find(".box").html();
              }
              el.attr("title", title.trim());
            });
            headersAreFixed.resolve();
          }

          // when the data model changes, fix the header widths.  See the comments here:
          // http://docs.angularjs.org/api/ng.$timeout
          $scope.$watch('rows', function (newValue, oldValue) {
            if (newValue) {
              renderChains($element.find('.scrollArea').width());
              // clean sort status and scroll to top of table once records replaced.
              $scope.sortExpr = null;
              // FIXME what is the reason here must scroll to top? This may cause confusing if using scrolling to implement pagination.
              $element.find('.scrollArea').scrollTop(0);
            }
          });

          $scope.asc = !$attrs.hasOwnProperty("desc");
          $scope.sortAttr = $attrs.sortAttr;

          $element.find(".scrollArea").scroll(function (event) {
            $element.find("thead th .th-inner").css('margin-left', 0 - event.target.scrollLeft);
          });

          $scope.$on("renderScrollableTable", function() {
//            $timeout(fixHeaderWidths);
            renderChains($element.find('.scrollArea').width());
          });

          angular.element(window).on('resize', function(){
            $scope.$apply();
          });
          $scope.$watch(function(){
            return $element.find('.scrollArea').width();
          }, function(newWidth, oldWidth){
            if(newWidth * oldWidth <= 0){
              return;
            }
            renderChains();
          });

          function renderChains(){
            var resizeQueue = waitForRender().then(fixHeaderWidths),
              customHandlers = $scope.headerResizeHanlers || [];
            for(var i = 0;i < customHandlers.length;i++){
              resizeQueue = resizeQueue.then(customHandlers[i]);
            }
            return resizeQueue;
          }
        }]
      };
    }])
    .directive('sortableHeader', [function () {
      return {
        transclude: true,
        scope: true,
        require: '^scrollableTable',
        template:
          '
' +
            '
' +
            '

' +
            '' +
            '' +
            '' +
            '' +
            '' +
            '' +
            '
' +
            '
',
        link: function (scope, elm, attrs, tableController) {
          var expr = attrs.on || "a as a." + attrs.col;
          scope.element = angular.element(elm);
          scope.isActive = function () {
            return tableController.getSortExpr() === expr;
          };
          scope.toggleSort = function (e) {
            if (scope.isActive()) {
              tableController.toggleSort();
            } else {
              tableController.setSortExpr(expr);
            }
            tableController.doSort(scope[attrs.comparatorFn]);
            e.preventDefault();
          };
          scope.isAscending = function () {
            if (scope.focused && !scope.isActive()) {
              return true;
            } else {
              return tableController.isAsc();
            }
          };

          scope.enter = function () {
            scope.focused = true;
          };
          scope.leave = function () {
            scope.focused = false;
          };

          scope.isLastCol = function() {
            return elm.parent().find("th:last-child").get(0) === elm.get(0);
          };
        }
      };
    }])
    .directive('resizable', ['$compile', function($compile){
      return {
        restrict: 'A',
        priority: 0,
        scope: true,
        require: '^scrollableTable',
        link: function postLink(scope, elm, attrs, tableController){
          tableController.appendTableResizingHandler(function(){
            _init();
          });

          tableController.appendTableResizingHandler(function relayoutHeaders(){
            var tableElement = tableController.getTableElement().find('.scrollArea table');
            if(tableElement.css('table-layout') === 'auto'){
              initRodPos();
            }else{
              _resetColumnsSize(tableElement.parent().width());
            }
          });

          scope.resizing = function(e){
            var screenOffset = tableController.getTableElement().find('.scrollArea').scrollLeft(),
              thInnerElm =  angular.element(e.target).parent(),
              thElm = thInnerElm.parent(),
              startPoint = _getScale(thInnerElm.css('left')) + thInnerElm.width() - screenOffset,
              movingPos = e.pageX,
              _document = angular.element(document),
              _body = angular.element('body'),
              coverPanel = angular.element('.scrollableContainer .resizing-cover'),
              scaler = angular.element('
');

            _body.addClass('scrollable-resizing');
            coverPanel.addClass('active');
            angular.element('.scrollableContainer').append(scaler);
            scaler.css('left', startPoint);

            _document.bind('mousemove', function (e){
              var offsetX = e.pageX - movingPos,
                movedOffset = _getScale(scaler.css('left')) - startPoint,
                widthOfActiveCol = thElm.width(),
                minWidthOfActiveCol = _getScale(thElm.css('min-width')),
                widthOfNextColOfActive = thElm.next().width(),
                minWidthOfNextColOfActive = _getScale(thElm.next().css('min-width'));
              movingPos = e.pageX;
              e.preventDefault();
              if((offsetX > 0 && widthOfNextColOfActive - movedOffset <= minWidthOfNextColOfActive)
                || (offsetX < 0 && widthOfActiveCol + movedOffset <= minWidthOfActiveCol)){
                //stopping resize if user trying to extension and the active/next column already minimised.
                return;
              }
              scaler.css('left', _getScale(scaler.css('left')) + offsetX);
            });
            _document.bind('mouseup', function (e) {
              e.preventDefault();
              scaler.remove();
              _body.removeClass('scrollable-resizing');
              coverPanel.removeClass('active');
              _document.unbind('mousemove');
              _document.unbind('mouseup');

              var offsetX = _getScale(scaler.css('left')) - startPoint,
                newWidth = thElm.width(),
                minWidth = _getScale(thElm.css('min-width')),
                widthOfNextColOfActive = thElm.next().width(),
                minWidthOfNextColOfActive = _getScale(thElm.next().css('min-width')),
                tableElement = tableController.getTableElement().find('.scrollArea table');

              //hold original width of cells, to display cells as their original width after turn table-layout to fixed.
              if(tableElement.css('table-layout') === 'auto'){
                tableElement.find("th .th-inner").each(function (index, el) {
                  el = angular.element(el);
                  var width = el.parent().width();
                  el.parent().css('width', width);
                });
              }

              tableElement.css('table-layout', 'fixed');

              if(offsetX > 0 && widthOfNextColOfActive - offsetX <= minWidthOfNextColOfActive){
                offsetX = widthOfNextColOfActive - minWidthOfNextColOfActive;
              }
              thElm.next().removeAttr('style');
              newWidth += offsetX;
              thElm.css('width', Math.max(minWidth, newWidth));
              thElm.next().css('width', widthOfNextColOfActive - offsetX);
              tableController.renderTalble().then(resizeHeaderWidth());
            });
          };

          function _init(){
            var thInnerElms = elm.find('table th .th-inner');
            if(thInnerElms.find('.resize-rod').length == 0){
              tableController.getTableElement().find('.scrollArea table').css('table-layout', 'auto');
              var resizeRod = angular.element('

');
              thInnerElms.append($compile(resizeRod)(scope));
            }
          }

          function initRodPos(){
            var tableElement = tableController.getTableElement();
            var headerPos = 1;//  1 is the width of right border;
            tableElement.find("table th .th-inner:visible").each(function (index, el) {
              el = angular.element(el);
              var width = el.parent().width(),   //to made header consistent with its parent.
              // if it's the last header, add space for the scrollbar equivalent unless it's centered
                minWidth = _getScale(el.parent().css('min-width'));
              width = Math.max(minWidth, width);
              el.css("left", headerPos);
              headerPos += width;
            });
          }

          function resizeHeaderWidth(){
            var headerPos = 1,//  1 is the width of right border;
              tableElement = tableController.getTableElement();
            tableController.getTableElement().find("table th .th-inner:visible").each(function (index, el) {
              el = angular.element(el);
              var width = el.parent().width(),   //to made header consistent with its parent.
              // if it's the last header, add space for the scrollbar equivalent unless it's centered
                lastCol = tableElement.find("table th:visible:last"),
                minWidth = _getScale(el.parent().css('min-width'));
              width = Math.max(minWidth, width);
              //following are resize stuff, to made th-inner position correct.
              //last column's width should be automatically, to avoid horizontal scroll.
              if (lastCol[0] != el.parent()[0]){
                el.parent().css('width', width);
              }
              el.css("left", headerPos);
              headerPos += width;
            });
          }

          function _resetColumnsSize(tableWidth){
            var tableElement = tableController.getTableElement(),
              columnLength = tableElement.find("table th:visible").length,
              lastCol = tableElement.find("table th:visible:last");
            tableElement.find("table th:visible").each(function (index, el) {
              el = angular.element(el);
              if(lastCol.get(0) == el.get(0)){
                //last column's width should be automaically, to avoid horizontal scroll.
                el.css('width', 'auto');
                return;
              }
              var _width = el.data('width');
              if(/\d+%$/.test(_width)){    //percentage
                _width = Math.ceil(tableWidth * _getScale(_width) / 100);
              } else {
                // if data-width not exist, use average width for each columns.
                _width = tableWidth / columnLength;
              }
              el.css('width', _width + 'px');
            });
            tableController.renderTalble().then(resizeHeaderWidth());
          }
        }
      }
    }]);

  function _getScale(sizeCss){
    return parseInt(sizeCss.replace(/px|%/, ''), 10);
  }
})(angular);<|endoftext|>


<commit_before>/* eslint-env node, jest */

const vocabwar = require('./index.js');
const Slack = require('../lib/slackMock.js');
const {promisify} = require('util');
const path = require('path');
const fs = require('fs');

let slack = null;

const deleteState = async () => {
	if (await new Promise((resolve) => {
		fs.access(path.join(__dirname, 'state.json'), fs.constants.F_OK, (error) => {
			resolve(!error);
		});
	})) {
		await promisify(fs.unlink)(path.join(__dirname, 'state.json'));
	}
};
/*
describe('vocabwar', () => {
	beforeEach(async () => {
		jest.setTimeout(1000 * 60 * 10);
		slack = new Slack();
		process.env.CHANNEL_SANDBOX = slack.fakeChannel;
		await deleteState();
		await vocabwar(slack);
	});

	afterEach(async () => {
		await deleteState();
	});

	it('responds to "弓箭"', async () => {
		const {username, text, attachments} = await slack.getResponseTo('弓箭');

		expect(username).toBe('vocabwar');
		expect(text).toContain('弓箭');
		expect(attachments).toHaveLength(10);
	});

	it('responds to "即弓箭"', async () => {
		const {username, text} = await slack.getResponseTo('即弓箭');

		expect(username).toBe('vocabwar');
		expect(text).toContain('弓箭');
		expect(text).toContain('終了予定時刻');
	});

	it('responds to "弓箭 お題"', async () => {
		const {username, text} = await slack.getResponseTo('弓箭 丸い');

		expect(username).toBe('vocabwar');
		expect(text).toContain('弓箭');
		expect(text).toContain('終了予定時刻');
		expect(text).toContain('丸い');
	});

	it('does not set unknown words to theme by "弓箭 お題"', async () => {
		const {username, text} = await slack.getResponseTo('弓箭 んをわろれるりら');
		expect(username).toBe('vocabwar');
		expect(text).toContain('知らない');
		expect(text).not.toContain('決定');
	});
});
*/
describe('vocabwar', () => {
	beforeAll(async () => {
		jest.setTimeout(1000 * 60 * 10);
		slack = new Slack();
		process.env.CHANNEL_SANDBOX = slack.fakeChannel;
		await deleteState();
		await vocabwar(slack);
		await slack.getResponseTo('弓箭 丸い');
	});

	afterAll(async () => {
		await deleteState();
	});

	it('rejects the same word as theme', async () => {
		const {username, text} = await slack.getResponseTo('丸い');
		expect(username).toBe('vocabwar');
		expect(text).toContain('お題');
	});

	it('rejects unknown word', async () => {
		const {username, text} = await slack.getResponseTo('んをわろれるりら');
		expect(username).toBe('vocabwar');
		expect(text).toContain('知らない');
	});

	it('reacts "+1" to valid answer', () => new Promise((resolve, reject) => {
		slack.on('reactions.add', ({name}) => {
			expect(name).toBe('+1');
			resolve();
		});

		slack.rtmClient.emit('message', {
			channel: slack.fakeChannel,
			text: '鋭い',
			user: slack.fakeUser,
			ts: slack.fakeTimestamp,
		});
	}));

	it('rejects duplicate answer', () => new Promise((resolve, reject) => {
		slack.on('chat.postMessage', ({text}) => {
			expect(text).toContain('パク');
			resolve();
		});

		slack.rtmClient.emit('message', {
			channel: slack.fakeChannel,
			text: '鋭い',
			user: `${slack.fakeUser}hoge`,
			ts: slack.fakeTimestamp,
		});
	}));

	/* currently unavailable because of slackMock.handleWebcall
	it('posts result', () => new Promise((resolve, reject) => {
		slack.on('chat.postMessage', ({text}) => {
			expect(text).toContain('結果');
			resolve();
		});
	}));
	*/
});
<commit_msg>uncomment tests<commit_after>/* eslint-env node, jest */

const vocabwar = require('./index.js');
const Slack = require('../lib/slackMock.js');
const {promisify} = require('util');
const path = require('path');
const fs = require('fs');

let slack = null;

const deleteState = async () => {
	if (await new Promise((resolve) => {
		fs.access(path.join(__dirname, 'state.json'), fs.constants.F_OK, (error) => {
			resolve(!error);
		});
	})) {
		await promisify(fs.unlink)(path.join(__dirname, 'state.json'));
	}
};

describe('vocabwar', () => {
	beforeEach(async () => {
		jest.setTimeout(1000 * 60 * 10);
		slack = new Slack();
		process.env.CHANNEL_SANDBOX = slack.fakeChannel;
		await deleteState();
		await vocabwar(slack);
	});

	afterEach(async () => {
		await deleteState();
	});

	it('responds to "弓箭"', async () => {
		const {username, text, attachments} = await slack.getResponseTo('弓箭');

		expect(username).toBe('vocabwar');
		expect(text).toContain('弓箭');
		expect(attachments).toHaveLength(10);
	});

	it('responds to "即弓箭"', async () => {
		const {username, text} = await slack.getResponseTo('即弓箭');

		expect(username).toBe('vocabwar');
		expect(text).toContain('弓箭');
		expect(text).toContain('終了予定時刻');
	});

	it('responds to "弓箭 お題"', async () => {
		const {username, text} = await slack.getResponseTo('弓箭 丸い');

		expect(username).toBe('vocabwar');
		expect(text).toContain('弓箭');
		expect(text).toContain('終了予定時刻');
		expect(text).toContain('丸い');
	});

	it('does not set unknown words to theme by "弓箭 お題"', async () => {
		const {username, text} = await slack.getResponseTo('弓箭 んをわろれるりら');
		expect(username).toBe('vocabwar');
		expect(text).toContain('知らない');
		expect(text).not.toContain('決定');
	});
});

describe('vocabwar', () => {
	beforeAll(async () => {
		jest.setTimeout(1000 * 60 * 10);
		slack = new Slack();
		process.env.CHANNEL_SANDBOX = slack.fakeChannel;
		await deleteState();
		await vocabwar(slack);
		await slack.getResponseTo('弓箭 丸い');
	});

	afterAll(async () => {
		await deleteState();
	});

	it('rejects the same word as theme', async () => {
		const {username, text} = await slack.getResponseTo('丸い');
		expect(username).toBe('vocabwar');
		expect(text).toContain('お題');
	});

	it('rejects unknown word', async () => {
		const {username, text} = await slack.getResponseTo('んをわろれるりら');
		expect(username).toBe('vocabwar');
		expect(text).toContain('知らない');
	});

	it('reacts "+1" to valid answer', () => new Promise((resolve, reject) => {
		slack.on('reactions.add', ({name}) => {
			expect(name).toBe('+1');
			resolve();
		});

		slack.rtmClient.emit('message', {
			channel: slack.fakeChannel,
			text: '鋭い',
			user: slack.fakeUser,
			ts: slack.fakeTimestamp,
		});
	}));

	it('rejects duplicate answer', () => new Promise((resolve, reject) => {
		slack.on('chat.postMessage', ({text}) => {
			expect(text).toContain('パク');
			resolve();
		});

		slack.rtmClient.emit('message', {
			channel: slack.fakeChannel,
			text: '鋭い',
			user: `${slack.fakeUser}hoge`,
			ts: slack.fakeTimestamp,
		});
	}));

	/* currently unavailable because of slackMock.handleWebcall
	it('posts result', () => new Promise((resolve, reject) => {
		slack.on('chat.postMessage', ({text}) => {
			expect(text).toContain('結果');
			resolve();
		});
	}));
	*/
});
<|endoftext|>


<commit_before>// Generated on <%= (new Date).toISOString().split('T')[0] %> using <%= packagejs.name %> <%= packagejs.version %>
'use strict';

var gulp = require('gulp'),
    gutil = require('gulp-util'),
    prefix = require('gulp-autoprefixer'),
    cssnano = require('gulp-cssnano'),
    usemin = require('gulp-usemin'),
    uglify = require('gulp-uglify'),<% if(useSass) { %>
    expect = require('gulp-expect-file'),
    sass = require('gulp-sass'),<% } %>
    htmlmin = require('gulp-htmlmin'),
    imagemin = require('gulp-imagemin'),
    ngAnnotate = require('gulp-ng-annotate'),
    ngConstant = require('gulp-ng-constant-fork'),
    eslint = require('gulp-eslint'),
    rev = require('gulp-rev'),<% if (testFrameworks.indexOf('protractor') > -1) { %>
    protractor = require('gulp-protractor').protractor,<% } %>
    es = require('event-stream'),
    flatten = require('gulp-flatten'),
    del = require('del'),
    wiredep = require('wiredep').stream,
    runSequence = require('run-sequence'),
    browserSync = require('browser-sync'),
    sourcemaps = require('gulp-sourcemaps'),
    KarmaServer = require('karma').Server,
    plumber = require('gulp-plumber'),
    changed = require('gulp-changed'),
    handleErrors = require('./gulp/handleErrors'),
    serve = require('./gulp/serve'),
    util = require('./gulp/utils'),
    gulpIf = require('gulp-if'),
    footer = require('gulp-footer');

var yorc = require('./.yo-rc.json')['generator-jhipster'];

var config = {
    app: '<%= MAIN_SRC_DIR %>',
    dist: '<%= DIST_DIR %>',
    test: '<%= TEST_SRC_DIR %>'<% if(useSass) { %>,
    scss: '<%= MAIN_SRC_DIR %>scss/',
    sassSrc: '<%= MAIN_SRC_DIR %>scss/**/*.{scss,sass}',
    cssDir: '<%= MAIN_SRC_DIR %>content/css'<% } %>,
    bower: '<%= MAIN_SRC_DIR %>bower_components/'
};

gulp.task('clean', function () {
    return del([config.dist], { dot: true });
});

gulp.task('copy', function () {
    return es.merge( <% if(enableTranslation) { /* copy i18n folders only if translation is enabled */ %>
        gulp.src(config.app + 'i18n/**')
        .pipe(plumber({errorHandler: handleErrors}))
        .pipe(changed(config.dist + 'i18n/'))
        .pipe(gulp.dest(config.dist + 'i18n/')),<% } %><% if(!useSass) { %>
        gulp.src(config.bower + 'bootstrap/fonts/*.*')
        .pipe(plumber({errorHandler: handleErrors}))
        .pipe(changed(config.dist + 'content/fonts/'))
        .pipe(gulp.dest(config.dist + 'content/fonts/')),<% } %>
        gulp.src(config.app + 'content/**/*.{woff,svg,ttf,eot}')
        .pipe(plumber({errorHandler: handleErrors}))
        .pipe(changed(config.dist + 'content/fonts/'))
        .pipe(flatten())
        .pipe(gulp.dest(config.dist + 'content/fonts/')),
        gulp.src([config.app + 'robots.txt', config.app + 'favicon.ico', config.app + '.htaccess'], { dot: true })
        .pipe(plumber({errorHandler: handleErrors}))
        .pipe(changed(config.dist))
        .pipe(gulp.dest(config.dist))
    );
});

gulp.task('images', function () {
    return gulp.src(config.app + 'content/images/**')
        .pipe(plumber({errorHandler: handleErrors}))
        .pipe(changed(config.dist + 'content/images'))
        .pipe(imagemin({optimizationLevel: 5}))
        .pipe(gulp.dest(config.dist + 'content/images'))
        .pipe(browserSync.reload({stream: true}));
});

<%_ if(useSass) { _%>
gulp.task('sass', function () {
    return es.merge(
        gulp.src(config.sassSrc)
        .pipe(plumber({errorHandler: handleErrors}))
        .pipe(expect(config.sassSrc))
        .pipe(changed(config.cssDir, {extension: '.css'}))
        .pipe(sass({includePaths:config.bower}).on('error', sass.logError))
        .pipe(gulp.dest(config.cssDir)),
        gulp.src(config.bower + 'bootstrap-sass/assets/fonts/bootstrap/*.*')
        .pipe(plumber({errorHandler: handleErrors}))
        .pipe(changed(config.app + 'content/fonts'))
        .pipe(gulp.dest(config.app + 'content/fonts'))
    );
});
<%_ } _%>

<%_ if(enableTranslation) { _%>
gulp.task('languages', function () {
    return gulp.src(config.bower + 'angular-i18n/angular-locale_{' + yorc.languages.join(',') + '}.js')
        .pipe(plumber({errorHandler: handleErrors}))
        .pipe(changed(config.app + 'i18n/'))
        .pipe(gulp.dest(config.app + 'i18n/'));
});
<%_ } _%>

gulp.task('styles', [<% if(useSass) { %>'sass'<% } %>], function () {
    return gulp.src(config.app + 'content/css')
        .pipe(browserSync.reload({stream: true}));
});

gulp.task('wiredep', ['wiredep:test', 'wiredep:app']);

gulp.task('wiredep:app', function () {
    var stream = gulp.src(config.app + 'index.html')
        .pipe(plumber({errorHandler: handleErrors}))
        .pipe(wiredep({
            exclude: [
                /angular-i18n/,  // localizations are loaded dynamically<% if (useSass) { %>
                'bower_components/bootstrap-sass/assets/javascripts/', // Exclude Bootstrap js files as we use ui-bootstrap<% } else { %>
                'bower_components/bootstrap/dist/js/' // exclude bootstrap js files as we use ui-bootstrap<% } %>
            ]
        }))
        .pipe(gulp.dest(config.app));

    return <% if (useSass) { %>es.merge(stream, gulp.src(config.sassSrc)
        .pipe(plumber({errorHandler: handleErrors}))
        .pipe(wiredep({
            ignorePath: /\.\.\/webapp\/bower_components\// // remove ../webapp/bower_components/ from paths of injected sass files
        }))
        .pipe(gulp.dest(config.scss)));<% } else { %>stream;<% } %>
});

gulp.task('wiredep:test', function () {
    return gulp.src(config.test + 'karma.conf.js')
        .pipe(plumber({errorHandler: handleErrors}))
        .pipe(wiredep({
            exclude: [
                /angular-i18n/,  // localizations are loaded dynamically
                /angular-scenario/,<% if (useSass) { %>
                'bower_components/bootstrap-sass/assets/javascripts/', // Exclude Bootstrap js files as we use ui-bootstrap<% } else { %>
                'bower_components/bootstrap/dist/js/' // exclude bootstrap js files as we use ui-bootstrap<% } %>
            ]
            ignorePath: /\.\.\/\.\.\//, // remove ../../ from paths of injected javascripts
            devDependencies: true,
            fileTypes: {
                js: {
                    block: /(([\s\t]*)\/\/\s*bower:*(\S*))(\n|\r|.)*?(\/\/\s*endbower)/gi,
                    detect: {
                        js: /'(.*\.js)'/gi
                    },
                    replace: {
                        js: '\'src/{{filePath}}\','
                    }
                }
            }
        }))
        .pipe(gulp.dest(config.test));
});

gulp.task('usemin', ['images', 'styles'], function () {
    return gulp.src([config.app + '**/*.html', '!' + config.bower + '**/*.html'])
        .pipe(plumber({errorHandler: handleErrors}))
        .pipe(usemin({
            css: [
                prefix,
                'concat',
                cssnano,
                rev
            ],
            html: [
                htmlmin.bind(htmlmin, {collapseWhitespace: true})
            ],
            js: [
                sourcemaps.init,
                ngAnnotate,
                footer.bind(footer, ';'),
                'concat',
                uglify.bind(uglify, { mangle: false }),
                rev,
                sourcemaps.write.bind(sourcemaps.write, '.')
            ]
        }))
        .pipe(gulp.dest(config.dist));
});

gulp.task('ngconstant:dev', function () {
    return ngConstant({
        dest: 'app.constants.js',
        name: '<%= angularAppName %>',
        deps:   false,
        noFile: true,
        interpolate: /\{%=(.+?)%\}/g,
        wrap:
            '(function() {\n' +
            '    "use strict";\n' +
            '    // DO NOT EDIT THIS FILE, EDIT THE GULP TASK NGCONSTANT SETTINGS INSTEAD WHICH GENERATES THIS FILE\n' +
            '    {%= __ngModule %}\n' +
            '})();\n',
        constants: {
            ENV: 'dev',
            VERSION: util.parseVersion()
        }
    })
    .pipe(gulp.dest(config.app + 'app/'));
});

gulp.task('ngconstant:prod', function () {
    return ngConstant({
        dest: 'app.constants.js',
        name: '<%= angularAppName %>',
        deps:   false,
        noFile: true,
        interpolate: /\{%=(.+?)%\}/g,
        wrap:
            '(function() {\n' +
            '    "use strict";\n' +
            '    // DO NOT EDIT THIS FILE, EDIT THE GULP TASK NGCONSTANT SETTINGS INSTEAD WHICH GENERATES THIS FILE\n' +
            '    {%= __ngModule %}\n' +
            '})();\n',
        constants: {
            ENV: 'prod',
            VERSION: util.parseVersion()
        }
    })
    .pipe(gulp.dest(config.app + 'app/'));
});

// check app for eslint errors
gulp.task('eslint', function () {
    return gulp.src(['gulpfile.js', config.app + 'app/**/*.js'])
        .pipe(plumber({errorHandler: handleErrors}))
        .pipe(eslint())
        .pipe(eslint.format())
        .pipe(eslint.failOnError());
});

// check app for eslint errors anf fix some of them
gulp.task('eslint-and-fix', function () {
    return gulp.src(config.app + 'app/**/*.js')
        .pipe(plumber({errorHandler: handleErrors}))
        .pipe(eslint({
            fix: true
        }))
        .pipe(eslint.format())
        .pipe(gulpIf(util.isLintFixed, gulp.dest(config.app + 'app')));
});

gulp.task('test', ['wiredep:test', 'ngconstant:dev'], function (done) {
    new KarmaServer({
        configFile: __dirname + '/' + config.test + 'karma.conf.js',
        singleRun: true
    }, done).start();
});

<%_ if (testFrameworks.indexOf('protractor') > -1) { _%>
gulp.task('protractor', function () {
    return gulp.src([config.test + 'e2e/**/*.js'])
        .pipe(plumber({errorHandler: handleErrors}))
        .pipe(protractor({
            configFile: config.test + 'protractor.conf.js'
        }))
        .on('error', function() {
            gutil.log('E2E Tests failed');
            process.exit(1);
        });
});

gulp.task('itest', ['protractor']);
<%_ } _%>

gulp.task('watch', function () {
    gulp.watch('bower.json', ['wiredep']);
    gulp.watch(['gulpfile.js', <% if(buildTool == 'maven') { %>'pom.xml'<% } else { %>'build.gradle'<% } %>], ['ngconstant:dev']);
    gulp.watch(<% if(useSass) { %>config.sassSrc<% } else { %>config.app + 'content/css/**/*.css'<% } %>, ['styles']);
    gulp.watch(config.app + 'content/images/**', ['images']);
    gulp.watch([config.app + '*.html', config.app + 'app/**', config.app + 'i18n/**']).on('change', browserSync.reload);
});

gulp.task('install', function (done) {
    runSequence('wiredep', 'ngconstant:dev'<% if(useSass) { %>, 'sass'<% } %><% if(enableTranslation) { %>, 'languages'<% } %>, done);
});

gulp.task('serve', function () {
    runSequence('install', serve);
});

gulp.task('build', function (cb) {
    runSequence('clean', 'copy', 'wiredep:app', 'ngconstant:prod', 'eslint', 'usemin', cb);
});

gulp.task('default', ['serve']);
<commit_msg>Add missing coma, wording<commit_after>// Generated on <%= (new Date).toISOString().split('T')[0] %> using <%= packagejs.name %> <%= packagejs.version %>
'use strict';

var gulp = require('gulp'),
    gutil = require('gulp-util'),
    prefix = require('gulp-autoprefixer'),
    cssnano = require('gulp-cssnano'),
    usemin = require('gulp-usemin'),
    uglify = require('gulp-uglify'),<% if(useSass) { %>
    expect = require('gulp-expect-file'),
    sass = require('gulp-sass'),<% } %>
    htmlmin = require('gulp-htmlmin'),
    imagemin = require('gulp-imagemin'),
    ngAnnotate = require('gulp-ng-annotate'),
    ngConstant = require('gulp-ng-constant-fork'),
    eslint = require('gulp-eslint'),
    rev = require('gulp-rev'),<% if (testFrameworks.indexOf('protractor') > -1) { %>
    protractor = require('gulp-protractor').protractor,<% } %>
    es = require('event-stream'),
    flatten = require('gulp-flatten'),
    del = require('del'),
    wiredep = require('wiredep').stream,
    runSequence = require('run-sequence'),
    browserSync = require('browser-sync'),
    sourcemaps = require('gulp-sourcemaps'),
    KarmaServer = require('karma').Server,
    plumber = require('gulp-plumber'),
    changed = require('gulp-changed'),
    handleErrors = require('./gulp/handleErrors'),
    serve = require('./gulp/serve'),
    util = require('./gulp/utils'),
    gulpIf = require('gulp-if'),
    footer = require('gulp-footer');

var yorc = require('./.yo-rc.json')['generator-jhipster'];

var config = {
    app: '<%= MAIN_SRC_DIR %>',
    dist: '<%= DIST_DIR %>',
    test: '<%= TEST_SRC_DIR %>'<% if(useSass) { %>,
    scss: '<%= MAIN_SRC_DIR %>scss/',
    sassSrc: '<%= MAIN_SRC_DIR %>scss/**/*.{scss,sass}',
    cssDir: '<%= MAIN_SRC_DIR %>content/css'<% } %>,
    bower: '<%= MAIN_SRC_DIR %>bower_components/'
};

gulp.task('clean', function () {
    return del([config.dist], { dot: true });
});

gulp.task('copy', function () {
    return es.merge( <% if(enableTranslation) { /* copy i18n folders only if translation is enabled */ %>
        gulp.src(config.app + 'i18n/**')
        .pipe(plumber({errorHandler: handleErrors}))
        .pipe(changed(config.dist + 'i18n/'))
        .pipe(gulp.dest(config.dist + 'i18n/')),<% } %><% if(!useSass) { %>
        gulp.src(config.bower + 'bootstrap/fonts/*.*')
        .pipe(plumber({errorHandler: handleErrors}))
        .pipe(changed(config.dist + 'content/fonts/'))
        .pipe(gulp.dest(config.dist + 'content/fonts/')),<% } %>
        gulp.src(config.app + 'content/**/*.{woff,svg,ttf,eot}')
        .pipe(plumber({errorHandler: handleErrors}))
        .pipe(changed(config.dist + 'content/fonts/'))
        .pipe(flatten())
        .pipe(gulp.dest(config.dist + 'content/fonts/')),
        gulp.src([config.app + 'robots.txt', config.app + 'favicon.ico', config.app + '.htaccess'], { dot: true })
        .pipe(plumber({errorHandler: handleErrors}))
        .pipe(changed(config.dist))
        .pipe(gulp.dest(config.dist))
    );
});

gulp.task('images', function () {
    return gulp.src(config.app + 'content/images/**')
        .pipe(plumber({errorHandler: handleErrors}))
        .pipe(changed(config.dist + 'content/images'))
        .pipe(imagemin({optimizationLevel: 5}))
        .pipe(gulp.dest(config.dist + 'content/images'))
        .pipe(browserSync.reload({stream: true}));
});

<%_ if(useSass) { _%>
gulp.task('sass', function () {
    return es.merge(
        gulp.src(config.sassSrc)
        .pipe(plumber({errorHandler: handleErrors}))
        .pipe(expect(config.sassSrc))
        .pipe(changed(config.cssDir, {extension: '.css'}))
        .pipe(sass({includePaths:config.bower}).on('error', sass.logError))
        .pipe(gulp.dest(config.cssDir)),
        gulp.src(config.bower + 'bootstrap-sass/assets/fonts/bootstrap/*.*')
        .pipe(plumber({errorHandler: handleErrors}))
        .pipe(changed(config.app + 'content/fonts'))
        .pipe(gulp.dest(config.app + 'content/fonts'))
    );
});
<%_ } _%>

<%_ if(enableTranslation) { _%>
gulp.task('languages', function () {
    return gulp.src(config.bower + 'angular-i18n/angular-locale_{' + yorc.languages.join(',') + '}.js')
        .pipe(plumber({errorHandler: handleErrors}))
        .pipe(changed(config.app + 'i18n/'))
        .pipe(gulp.dest(config.app + 'i18n/'));
});
<%_ } _%>

gulp.task('styles', [<% if(useSass) { %>'sass'<% } %>], function () {
    return gulp.src(config.app + 'content/css')
        .pipe(browserSync.reload({stream: true}));
});

gulp.task('wiredep', ['wiredep:test', 'wiredep:app']);

gulp.task('wiredep:app', function () {
    var stream = gulp.src(config.app + 'index.html')
        .pipe(plumber({errorHandler: handleErrors}))
        .pipe(wiredep({
            exclude: [
                /angular-i18n/,  // localizations are loaded dynamically<% if (useSass) { %>
                'bower_components/bootstrap-sass/assets/javascripts/', // Exclude Bootstrap js files as we use ui-bootstrap<% } else { %>
                'bower_components/bootstrap/dist/js/' // exclude bootstrap js files as we use ui-bootstrap<% } %>
            ]
        }))
        .pipe(gulp.dest(config.app));

    return <% if (useSass) { %>es.merge(stream, gulp.src(config.sassSrc)
        .pipe(plumber({errorHandler: handleErrors}))
        .pipe(wiredep({
            ignorePath: /\.\.\/webapp\/bower_components\// // remove ../webapp/bower_components/ from paths of injected sass files
        }))
        .pipe(gulp.dest(config.scss)));<% } else { %>stream;<% } %>
});

gulp.task('wiredep:test', function () {
    return gulp.src(config.test + 'karma.conf.js')
        .pipe(plumber({errorHandler: handleErrors}))
        .pipe(wiredep({
            exclude: [
                /angular-i18n/,  // localizations are loaded dynamically
                /angular-scenario/,<% if (useSass) { %>
                'bower_components/bootstrap-sass/assets/javascripts/', // Exclude Bootstrap js files as we use ui-bootstrap<% } else { %>
                'bower_components/bootstrap/dist/js/' // exclude Bootstrap js files as we use ui-bootstrap<% } %>
            ],
            ignorePath: /\.\.\/\.\.\//, // remove ../../ from paths of injected JavaScript files
            devDependencies: true,
            fileTypes: {
                js: {
                    block: /(([\s\t]*)\/\/\s*bower:*(\S*))(\n|\r|.)*?(\/\/\s*endbower)/gi,
                    detect: {
                        js: /'(.*\.js)'/gi
                    },
                    replace: {
                        js: '\'src/{{filePath}}\','
                    }
                }
            }
        }))
        .pipe(gulp.dest(config.test));
});

gulp.task('usemin', ['images', 'styles'], function () {
    return gulp.src([config.app + '**/*.html', '!' + config.bower + '**/*.html'])
        .pipe(plumber({errorHandler: handleErrors}))
        .pipe(usemin({
            css: [
                prefix,
                'concat',
                cssnano,
                rev
            ],
            html: [
                htmlmin.bind(htmlmin, {collapseWhitespace: true})
            ],
            js: [
                sourcemaps.init,
                ngAnnotate,
                footer.bind(footer, ';'),
                'concat',
                uglify.bind(uglify, { mangle: false }),
                rev,
                sourcemaps.write.bind(sourcemaps.write, '.')
            ]
        }))
        .pipe(gulp.dest(config.dist));
});

gulp.task('ngconstant:dev', function () {
    return ngConstant({
        dest: 'app.constants.js',
        name: '<%= angularAppName %>',
        deps:   false,
        noFile: true,
        interpolate: /\{%=(.+?)%\}/g,
        wrap:
            '(function() {\n' +
            '    "use strict";\n' +
            '    // DO NOT EDIT THIS FILE, EDIT THE GULP TASK NGCONSTANT SETTINGS INSTEAD WHICH GENERATES THIS FILE\n' +
            '    {%= __ngModule %}\n' +
            '})();\n',
        constants: {
            ENV: 'dev',
            VERSION: util.parseVersion()
        }
    })
    .pipe(gulp.dest(config.app + 'app/'));
});

gulp.task('ngconstant:prod', function () {
    return ngConstant({
        dest: 'app.constants.js',
        name: '<%= angularAppName %>',
        deps:   false,
        noFile: true,
        interpolate: /\{%=(.+?)%\}/g,
        wrap:
            '(function() {\n' +
            '    "use strict";\n' +
            '    // DO NOT EDIT THIS FILE, EDIT THE GULP TASK NGCONSTANT SETTINGS INSTEAD WHICH GENERATES THIS FILE\n' +
            '    {%= __ngModule %}\n' +
            '})();\n',
        constants: {
            ENV: 'prod',
            VERSION: util.parseVersion()
        }
    })
    .pipe(gulp.dest(config.app + 'app/'));
});

// check app for eslint errors
gulp.task('eslint', function () {
    return gulp.src(['gulpfile.js', config.app + 'app/**/*.js'])
        .pipe(plumber({errorHandler: handleErrors}))
        .pipe(eslint())
        .pipe(eslint.format())
        .pipe(eslint.failOnError());
});

// check app for eslint errors anf fix some of them
gulp.task('eslint-and-fix', function () {
    return gulp.src(config.app + 'app/**/*.js')
        .pipe(plumber({errorHandler: handleErrors}))
        .pipe(eslint({
            fix: true
        }))
        .pipe(eslint.format())
        .pipe(gulpIf(util.isLintFixed, gulp.dest(config.app + 'app')));
});

gulp.task('test', ['wiredep:test', 'ngconstant:dev'], function (done) {
    new KarmaServer({
        configFile: __dirname + '/' + config.test + 'karma.conf.js',
        singleRun: true
    }, done).start();
});

<%_ if (testFrameworks.indexOf('protractor') > -1) { _%>
gulp.task('protractor', function () {
    return gulp.src([config.test + 'e2e/**/*.js'])
        .pipe(plumber({errorHandler: handleErrors}))
        .pipe(protractor({
            configFile: config.test + 'protractor.conf.js'
        }))
        .on('error', function() {
            gutil.log('E2E Tests failed');
            process.exit(1);
        });
});

gulp.task('itest', ['protractor']);
<%_ } _%>

gulp.task('watch', function () {
    gulp.watch('bower.json', ['wiredep']);
    gulp.watch(['gulpfile.js', <% if(buildTool == 'maven') { %>'pom.xml'<% } else { %>'build.gradle'<% } %>], ['ngconstant:dev']);
    gulp.watch(<% if(useSass) { %>config.sassSrc<% } else { %>config.app + 'content/css/**/*.css'<% } %>, ['styles']);
    gulp.watch(config.app + 'content/images/**', ['images']);
    gulp.watch([config.app + '*.html', config.app + 'app/**', config.app + 'i18n/**']).on('change', browserSync.reload);
});

gulp.task('install', function (done) {
    runSequence('wiredep', 'ngconstant:dev'<% if(useSass) { %>, 'sass'<% } %><% if(enableTranslation) { %>, 'languages'<% } %>, done);
});

gulp.task('serve', function () {
    runSequence('install', serve);
});

gulp.task('build', function (cb) {
    runSequence('clean', 'copy', 'wiredep:app', 'ngconstant:prod', 'eslint', 'usemin', cb);
});

gulp.task('default', ['serve']);
<|endoftext|>


<commit_before>var docco = require('docco');

var path = require('path');
var fs = require('fs');
// save the path to the test directory to load fixtures
var fixture_dir = path.join(path.dirname(fs.realpathSync(__filename)), '../') + 'fixtures/';

describe("The 'parse' function" ,function() {
    it("parses multiline comments as descriptions", function() {
        var sourceFile = fs.readFileSync(fixture_dir + "testSourceFile.js").toString();
        var parsedSections = docco.parse("testSourceFile.js", sourceFile);
        expect(parsedSections).toEqual([
            { docsText: '', codeText: '' }, // empty section in the beginning
            {docsText: ' This should be *markdown* parsed\n   and ist should be **multiline**. ',
             codeText: 'var a = 3+7;\nvar square = function(x) { return x*x; };'}
        ]);
    });

    it("works when the source ends with a description", function() {
        var sourceFile = fs.readFileSync(fixture_dir + "testSourceFileEndingWithDescription.js").toString();
        var parsedSections = docco.parse("testSourceFileEndingWithDescription.js", sourceFile);
        expect(parsedSections).toEqual([
            { docsText: '', codeText: '' }, // empty section in the beginning
            { docsText: " This should be *markdown* parsed\n   and ist should be **multiline**. ",
              codeText: "var a = 3+7;\nvar square = function(x) { return x*x; };" },
            { docsText: " Isn't this great code ? ", codeText: ''}
        ]);
    });
});<commit_msg>Corrections for continuos integration<commit_after>var docco = require('../../docco.js');

var path = require('path');
var fs = require('fs');
// save the path to the test directory to load fixtures
var fixture_dir = path.join(path.dirname(fs.realpathSync(__filename)), '../') + 'fixtures/';

describe("The 'parse' function" ,function() {
    it("parses multiline comments as descriptions", function() {
        var sourceFile = fs.readFileSync(fixture_dir + "testSourceFile.js").toString();
        var parsedSections = docco.parse("testSourceFile.js", sourceFile);
        expect(parsedSections).toEqual([
            { docsText: '', codeText: '' }, // empty section in the beginning
            {docsText: ' This should be *markdown* parsed\n   and ist should be **multiline**. ',
             codeText: 'var a = 3+7;\nvar square = function(x) { return x*x; };'}
        ]);
    });

    it("works when the source ends with a description", function() {
        var sourceFile = fs.readFileSync(fixture_dir + "testSourceFileEndingWithDescription.js").toString();
        var parsedSections = docco.parse("testSourceFileEndingWithDescription.js", sourceFile);
        expect(parsedSections).toEqual([
            { docsText: '', codeText: '' }, // empty section in the beginning
            { docsText: " This should be *markdown* parsed\n   and ist should be **multiline**. ",
              codeText: "var a = 3+7;\nvar square = function(x) { return x*x; };" },
            { docsText: " Isn't this great code ? ", codeText: ''}
        ]);
    });
});<|endoftext|>


<commit_before>$(function() {
    function split( val ) {
        return val.split( /,\s*/ );
    }
    function extractLast( term ) {
        return split( term ).pop();
    }
    $( "#PostTags" )
    // don't navigate away from the field on tab when selecting an item
    .bind( "keydown", function( event ) {
        if ( event.keyCode === $.ui.keyCode.TAB &&
            $( this ).data( "autocomplete" ).menu.active ) {
            event.preventDefault();
        }
    })
    .autocomplete({
        source: function( request, response ) {
            $.getJSON( Hurad.basePath+"tags/index.json", {
                term: extractLast( request.term )
            }, response );
        },
        search: function() {
            // custom minLength
            var term = extractLast( this.value );
            if ( term.length < 2 ) {
                return false;
            }
        },
        focus: function() {
            // prevent value inserted on focus
            return false;
        },
        select: function( event, ui ) {
            var terms = split( this.value );
            // remove the current input
            terms.pop();
            // add the selected item
            terms.push( ui.item.value );
            // add placeholder to get the comma-and-space at the end
            terms.push( "" );
            this.value = terms.join( ", " );
            return false;
        }
    });
});<commit_msg>Remove not used scripts.<commit_after><|endoftext|>


<commit_before>const version = require('child_process').execSync('git describe --always', { cwd: __dirname }).toString().trim();

function moduleFiles(name) {
  return { is: 'group', path: name, elements: [
    { is: 'group', name: "src", path: "src", elements: [
      { is: 'file', name: "index.ts", tags: ["tsc"] }
    ]},
    { is: 'group', name: "tst", path: "tst", elements: [
      { is: 'file', name: "index.ts", tags: ["tsc"] },
      { is: 'file', name: "data/**" , tags: ["rsc"] }
    ]}
  ]}
}

function cwd_test(workspace) {
  return `${__dirname}/../${workspace}/node/node_modules/@openmicrostep`;
}
const tests= [
  `msbuildsystem.shared.tests/index.js`,
  `msbuildsystem.core.tests/index.js`,
  `msbuildsystem.js.tests/index.js`,
  `msbuildsystem.js.typescript.tests/index.js`,
];

module.exports= {
  is: "project",
  name: "MSBuildSystem",
  'files=': {
    is: 'group',
    'cli=':              { is: 'group', elements: [{ is: 'file', name: "cli/src/index.ts"           },
                                                   { is: 'file', name: "cli/src/bin.ts"             }] },
    'core=':             moduleFiles('core'),
    'shared=':           { is: 'group', elements: [{ is: 'file', name: "shared/src/index.ts"        }] },
    'shared tests=':     { is: 'group', elements: [{ is: 'file', name: "shared/tst/index.ts"        }] },
    'foundation=':       { is: 'group', elements: [{ is: 'file', name: "foundation/src/index.ts"    }] },
    //'foundation tests=': { is: 'group', elements: [{ is: 'file', name: "foundation/tst/index.ts"    }] },
    'cxx=':              moduleFiles('cxx'),
    'js=' :              moduleFiles('js'),
    'typescript=':       moduleFiles('js.typescript'),
  },
  'config=': { is: "group",
    'node=': {
      is: "environment",
      npmPackage: { is: "component",
        "version": version,
      }
    },
    'module=': {
      is: "component",
      type: "javascript",
      compiler: "typescript",
      packager: "npm",
      npmPackage: { is: "component",
        "main": "index.js",
        "typings": "index.d.ts",
        devDependencies: { is: "component",
          "@types/node": "^6.0.78"
        }
      },
      tsConfig: { is: "component",
        "module": "commonjs",
        "target": "es6",
        "declaration": true,
        "experimentalDecorators": true,
        "strictNullChecks": true,
        "noImplicitThis": true,
        "noImplicitReturns": true,
        "sourceMap": true,
        //"lib": ["es6"],
        "types": ["node"]
      },
    },
    'module tests=': {
      is: "component",
      components: ["=module"],
      tsConfig: { is: "component",
        "types": ["node", "mocha", "chai"]
      },
      npmPackage: { is: "component",
        dependencies: { is: "component",
          "chai": "4.0.0-canary.2"
        },
        devDependencies: { is: "component",
          "@types/chai": "^3.4.29",
          "@types/mocha": "^2.2.28",
          "@types/node": "^6.0.78",
          "@openmicrostep/tests": "^0.1.0"
        },
      },
    },
  },
  'base=': {
    is: "component",
    components: ["=config:module"],
    environments: ["=config:node"],
  },
  'base tests=': {
    is: "component",
    components: ["=config:module tests"],
    environments: ["=config:node"],
  },
  'targets=': { 'is': 'group',
    'core=': {
      is: "target",
      outputName: '@openmicrostep/msbuildsystem.core',
      targets: ['shared'],
      components: ['=base', '=::shared::'],
      files: ['=files:core:src ? tsc'],
      npmPackage: { is: "component",
        dependencies: { is: "component",
          "fs-extra": "^0.30.0",
          "source-map-support": "^0.4.0"
        },
        devDependencies: { is: "component",
          "@types/fs-extra": "0.0.28",
        },
      },
      exports: [{ is: 'component', name: 'cfg',
        "module=": { is: 'component', components: ['=config:module']       },
        "tests=" : { is: 'component', components: ['=config:module tests'] },
      }]
    },
    'core tests=': {
      is: "target",
      outputName: '@openmicrostep/msbuildsystem.core.tests',
      targets: ['core'],
      components: ['=base tests', '=::core::'],
      files: ['=files:core:tst ? tsc'],
      copyFiles: [{is: 'group', elements: ['=files:core:tst ? rsc'], dest: 'data', expand: true }]
    },
    'shared=': {
      is: "target",
      components: ['=base'],
      outputName: '@openmicrostep/msbuildsystem.shared',
      files: ['=files:shared'],
      npmPackage: { is: "component",
        dependencies: { is: "component",
          "@openmicrostep/async": "^0.1.0"
        },
      }
    },
    'shared tests=': {
      is: "target",
      outputName: '@openmicrostep/msbuildsystem.shared.tests',
      targets: ['shared'],
      components: ['=base tests', '=::shared::'],
      files: ['=files:shared tests'],
    },
    'cli=': {
      is: "target",
      outputName: '@openmicrostep/msbuildsystem.cli',
      components: ['=base', '=::core::'],
      targets: ['core'],
      files: ['=files:cli'],
      //tsConfig: [{ traceResolution: true }],,
      npmPackage: { is: "component",
        bin: { "msbuildsystem": "./bin.js" },
        dependencies: { is: "component",
          "argparse": "^1.0.9",
          "chalk": "^1.1.3"
        },
        devDependencies: { is: "component",
          "@types/argparse": "^1.0.30",
          "@types/chalk": "^0.4.31",
        },
      }
    },
    'foundation=': {
      is: "target",
      outputName: '@openmicrostep/msbuildsystem.foundation',
      targets: ['core'],
      components: ['=base', '=::core::'],
      files: ['=files:foundation']
    },
    /*'foundation tests=': {
      is: "target",
      outputName: '@openmicrostep/msbuildsystem.foundation.tests',
      components: ['=base tests'],
      targets: ['foundation'],
      files: ['=files:foundation tests'],
    },*/
    'cxx=': {
      is: "target",
      outputName: '@openmicrostep/msbuildsystem.cxx',
      targets: ['core', 'foundation'],
      components: ['=base', '=::core::', '=::foundation::'],
      files: ['=files:cxx:src ? tsc'],
    },
    'cxx tests=': {
      is: "target",
      outputName: '@openmicrostep/msbuildsystem.cxx.tests',
      targets: ['cxx'],
      components: ['=base tests', '=::cxx::', '=::core::'],
      files: ['=files:cxx:tst ? tsc'],
      copyFiles: [{is: 'group', elements: ['=files:cxx:tst ? rsc'], dest: 'data/hello-world', expand: true }]
    },
    'js=':               {
      is: 'target',
      outputName: '@openmicrostep/msbuildsystem.js',
      targets: ['core', 'foundation'],
      components: ['=base', '=::core::', '=::foundation::'],
      files: ['=files:js:src ? tsc']
    },
    'js tests=':         {
      is: 'target',
      outputName: '@openmicrostep/msbuildsystem.js.tests',
      targets: ['js'],
      components: ['=base tests', '=::foundation::', '=::core::', '=::js::'],
      files: ['=files:js:tst ? tsc'],
      copyFiles: [{is: 'group', elements: ['=files:js:tst ? rsc'], dest: 'data/hello-world', expand: true }]
    },
    'typescript=':       {
      is: 'target',
      outputName: '@openmicrostep/msbuildsystem.js.typescript',
      targets: ['core', 'foundation', 'js'],
      components: ['=base', '=::foundation::', '=::js::', '=::core::'],
      files: ['=files:typescript:src ? tsc'],
      npmPackage: { is: "component",
        dependencies: { is: "component",
          "typescript": "^2.2.2",
        }
      },
    },
    'typescript tests=': {
      is: 'target',
      outputName: '@openmicrostep/msbuildsystem.js.typescript.tests',
      components: ['=base tests', '=::core::', '=::js::', '=::typescript::'],
      targets: ['typescript'],
      files: ['=files:typescript:tst ? tsc'],
      copyFiles: [{is: 'group', elements: ['=files:typescript:tst ? rsc'], dest: 'data/hello-world', expand: true }]
    },
  },
  'commands=': { is: "group",
    "envs=": { is: "group", elements: [
      { is: "environment", name: "gitlab"  , tags: ["ci"   ] },
      { is: "environment", name: "travis"  , tags: ["ci"   , "coveralls"] },
      { is: "environment", name: "appveyor", tags: ["ci"   ] },
      { is: "environment", name: "local"   , tags: ["local"] },
    ]},
    "shell=": {
      is: "component",
      type: "basic",
      manual: true,
      environments: ["=envs"],
    },
    "cmd_no_cwd=": {
      is: "component",
      type: "cmd",
      tty: true,
      shell: true,
    },
    "cmd=": {
      is: "component",
      components: ["=cmd_no_cwd"],
      cwd: "={cwd}.absolutePath",
    },
    'cwd=': { is: 'group', elements: [{ is: 'file', name: "../" }] },
    "install-deps=": { is: "task", components: ["=cmd"], cmd: "npm install -g -q coveralls nyc @openmicrostep/tests" },
    "build-1=": { is: "task", components: ["=cmd"], cmd: Value([
      "msbuildsystem", "build", "-p", "@msbuildsystem", "-w", "dist/1/"
    ]) },
    "tests-1=": { is: "task", components: ["=cmd_no_cwd"], cwd: cwd_test('dist/1'), cmd: Value([
      "mstests", "-c", ...tests
    ]) },
    "build-2=": { is: "task", components: ["=cmd"], cmd: Value([
      "node", "dist/1/node/node_modules/@openmicrostep/msbuildsystem.cli/index.js", "build", "-p", "@msbuildsystem", "-w", "dist/2/"
    ]) },
    "tests-2=": { is: "task", components: ["=cmd_no_cwd"], cwd: cwd_test('dist/2'), cmd: Value([
      "mstests", "-c", ...tests
    ]) },
    "build-3=": { is: "task", components: ["=cmd"], cmd: Value([
      "node", "dist/2/node/node_modules/@openmicrostep/msbuildsystem.cli/index.js", "build", "-p", "@msbuildsystem", "-w", "dist/3/"
    ]) },
    "tests-3=": { is: "task", components: ["=cmd_no_cwd"], cwd: cwd_test('dist/3'), cmd: Value([
      "mstests", "-c", "-t", "10000", ...tests
    ]) },
    "coverage-local-3=": { is: "task", components: ["=cmd_no_cwd"], cwd: cwd_test('dist/3'), cmd: Value([
      "nyc", "--reporter=html", "--report-dir", `${__dirname}/../dist/coverage`, "-x", "*.tests/**", "mstests",
      "-c", "-t", "20000", ...tests
    ]) },
    "coveralls-3=": { is: "task", components: ["=cmd_no_cwd"], cwd: cwd_test('dist/3'), cmd:
      `nyc --reporter=text-lcov --report-dir ${__dirname}/../dist/coverage -x "*.tests/**" mstests -c -t 20000 ${tests.join(' ')} | coveralls`
    },

    "deploy-shared="    : { is: "task", components: ["=cmd"], cmd: Value(["npm",  "publish", "dist/3/node/node_modules/@openmicrostep/msbuildsystem.shared"       ]) },
    "deploy-core="      : { is: "task", components: ["=cmd"], cmd: Value(["npm",  "publish", "dist/3/node/node_modules/@openmicrostep/msbuildsystem.core"         ]) },
    "deploy-cli="       : { is: "task", components: ["=cmd"], cmd: Value(["npm",  "publish", "dist/3/node/node_modules/@openmicrostep/msbuildsystem.cli"          ]) },
    "deploy-foundation=": { is: "task", components: ["=cmd"], cmd: Value(["npm",  "publish", "dist/3/node/node_modules/@openmicrostep/msbuildsystem.foundation"   ]) },
    "deploy-js="        : { is: "task", components: ["=cmd"], cmd: Value(["npm",  "publish", "dist/3/node/node_modules/@openmicrostep/msbuildsystem.js"           ]) },
    "deploy-ts="        : { is: "task", components: ["=cmd"], cmd: Value(["npm",  "publish", "dist/3/node/node_modules/@openmicrostep/msbuildsystem.js.typescript"]) },
    "deploy=":        { is: "target", components: ["=shell"], targets: ["bootstrap"],
      preTasks: Value(["=deploy-shared","=deploy-core","=deploy-cli","=deploy-foundation","=deploy-js","=deploy-ts"]) },

    "build-tests-1=": { is: "target", components: ["=shell"], preTasks: Value(["=build-1", "=tests-1"]) },
    "build-tests-2=": { is: "target", components: ["=shell"], preTasks: Value(["=build-2", "=tests-2"]) },
    "build-tests-3=": { is: "target", components: ["=shell"], preTasks: Value(["=build-3", "=tests-3"]) },
    "bootstrap=":     { is: "target", components: ["=shell"], preTasksByEnvironment: {
      "=envs ? ci + !coveralls": Value(["=install-deps", "=build-1", "=build-2", "=build-3", "=tests-3"                                    ]),
      "=envs ? ci +  coveralls": Value(["=install-deps", "=build-1", "=build-2", "=build-3", "=tests-3", "=coveralls-3"     ]),
      "=envs ? local"          : Value(["=build-1", "=build-2", "=build-3", "=tests-3", "=coverage-local-3"]),
    } },
  }
}

<commit_msg>ci: should fix coveralls source maps and simplify nyc cwd setup<commit_after>const version = require('child_process').execSync('git describe --always', { cwd: __dirname }).toString().trim();

function moduleFiles(name) {
  return { is: 'group', path: name, elements: [
    { is: 'group', name: "src", path: "src", elements: [
      { is: 'file', name: "index.ts", tags: ["tsc"] }
    ]},
    { is: 'group', name: "tst", path: "tst", elements: [
      { is: 'file', name: "index.ts", tags: ["tsc"] },
      { is: 'file', name: "data/**" , tags: ["rsc"] }
    ]}
  ]}
}

function cwd_test(workspace) {
  return `${workspace}/node/node_modules/@openmicrostep`;
}
function tests(workspace) { return [
  `msbuildsystem.shared.tests/index.js`,
  `msbuildsystem.core.tests/index.js`,
  `msbuildsystem.js.tests/index.js`,
  `msbuildsystem.js.typescript.tests/index.js`,
].map(p => `${cwd_test(workspace)}/${p}`);
}
module.exports= {
  is: "project",
  name: "MSBuildSystem",
  'files=': {
    is: 'group',
    'cli=':              { is: 'group', elements: [{ is: 'file', name: "cli/src/index.ts"           },
                                                   { is: 'file', name: "cli/src/bin.ts"             }] },
    'core=':             moduleFiles('core'),
    'shared=':           { is: 'group', elements: [{ is: 'file', name: "shared/src/index.ts"        }] },
    'shared tests=':     { is: 'group', elements: [{ is: 'file', name: "shared/tst/index.ts"        }] },
    'foundation=':       { is: 'group', elements: [{ is: 'file', name: "foundation/src/index.ts"    }] },
    //'foundation tests=': { is: 'group', elements: [{ is: 'file', name: "foundation/tst/index.ts"    }] },
    'cxx=':              moduleFiles('cxx'),
    'js=' :              moduleFiles('js'),
    'typescript=':       moduleFiles('js.typescript'),
  },
  'config=': { is: "group",
    'node=': {
      is: "environment",
      npmPackage: { is: "component",
        "version": version,
      }
    },
    'module=': {
      is: "component",
      type: "javascript",
      compiler: "typescript",
      packager: "npm",
      npmPackage: { is: "component",
        "main": "index.js",
        "typings": "index.d.ts",
        devDependencies: { is: "component",
          "@types/node": "^6.0.78"
        }
      },
      tsConfig: { is: "component",
        "module": "commonjs",
        "target": "es6",
        "declaration": true,
        "experimentalDecorators": true,
        "strictNullChecks": true,
        "noImplicitThis": true,
        "noImplicitReturns": true,
        "sourceMap": true,
        //"lib": ["es6"],
        "types": ["node"]
      },
    },
    'module tests=': {
      is: "component",
      components: ["=module"],
      tsConfig: { is: "component",
        "types": ["node", "mocha", "chai"]
      },
      npmPackage: { is: "component",
        dependencies: { is: "component",
          "chai": "4.0.0-canary.2"
        },
        devDependencies: { is: "component",
          "@types/chai": "^3.4.29",
          "@types/mocha": "^2.2.28",
          "@types/node": "^6.0.78",
          "@openmicrostep/tests": "^0.1.0"
        },
      },
    },
  },
  'base=': {
    is: "component",
    components: ["=config:module"],
    environments: ["=config:node"],
  },
  'base tests=': {
    is: "component",
    components: ["=config:module tests"],
    environments: ["=config:node"],
  },
  'targets=': { 'is': 'group',
    'core=': {
      is: "target",
      outputName: '@openmicrostep/msbuildsystem.core',
      targets: ['shared'],
      components: ['=base', '=::shared::'],
      files: ['=files:core:src ? tsc'],
      npmPackage: { is: "component",
        dependencies: { is: "component",
          "fs-extra": "^0.30.0",
          "source-map-support": "^0.4.0"
        },
        devDependencies: { is: "component",
          "@types/fs-extra": "0.0.28",
        },
      },
      exports: [{ is: 'component', name: 'cfg',
        "module=": { is: 'component', components: ['=config:module']       },
        "tests=" : { is: 'component', components: ['=config:module tests'] },
      }]
    },
    'core tests=': {
      is: "target",
      outputName: '@openmicrostep/msbuildsystem.core.tests',
      targets: ['core'],
      components: ['=base tests', '=::core::'],
      files: ['=files:core:tst ? tsc'],
      copyFiles: [{is: 'group', elements: ['=files:core:tst ? rsc'], dest: 'data', expand: true }]
    },
    'shared=': {
      is: "target",
      components: ['=base'],
      outputName: '@openmicrostep/msbuildsystem.shared',
      files: ['=files:shared'],
      npmPackage: { is: "component",
        dependencies: { is: "component",
          "@openmicrostep/async": "^0.1.0"
        },
      }
    },
    'shared tests=': {
      is: "target",
      outputName: '@openmicrostep/msbuildsystem.shared.tests',
      targets: ['shared'],
      components: ['=base tests', '=::shared::'],
      files: ['=files:shared tests'],
    },
    'cli=': {
      is: "target",
      outputName: '@openmicrostep/msbuildsystem.cli',
      components: ['=base', '=::core::'],
      targets: ['core'],
      files: ['=files:cli'],
      //tsConfig: [{ traceResolution: true }],,
      npmPackage: { is: "component",
        bin: { "msbuildsystem": "./bin.js" },
        dependencies: { is: "component",
          "argparse": "^1.0.9",
          "chalk": "^1.1.3"
        },
        devDependencies: { is: "component",
          "@types/argparse": "^1.0.30",
          "@types/chalk": "^0.4.31",
        },
      }
    },
    'foundation=': {
      is: "target",
      outputName: '@openmicrostep/msbuildsystem.foundation',
      targets: ['core'],
      components: ['=base', '=::core::'],
      files: ['=files:foundation']
    },
    /*'foundation tests=': {
      is: "target",
      outputName: '@openmicrostep/msbuildsystem.foundation.tests',
      components: ['=base tests'],
      targets: ['foundation'],
      files: ['=files:foundation tests'],
    },*/
    'cxx=': {
      is: "target",
      outputName: '@openmicrostep/msbuildsystem.cxx',
      targets: ['core', 'foundation'],
      components: ['=base', '=::core::', '=::foundation::'],
      files: ['=files:cxx:src ? tsc'],
    },
    'cxx tests=': {
      is: "target",
      outputName: '@openmicrostep/msbuildsystem.cxx.tests',
      targets: ['cxx'],
      components: ['=base tests', '=::cxx::', '=::core::'],
      files: ['=files:cxx:tst ? tsc'],
      copyFiles: [{is: 'group', elements: ['=files:cxx:tst ? rsc'], dest: 'data/hello-world', expand: true }]
    },
    'js=':               {
      is: 'target',
      outputName: '@openmicrostep/msbuildsystem.js',
      targets: ['core', 'foundation'],
      components: ['=base', '=::core::', '=::foundation::'],
      files: ['=files:js:src ? tsc']
    },
    'js tests=':         {
      is: 'target',
      outputName: '@openmicrostep/msbuildsystem.js.tests',
      targets: ['js'],
      components: ['=base tests', '=::foundation::', '=::core::', '=::js::'],
      files: ['=files:js:tst ? tsc'],
      copyFiles: [{is: 'group', elements: ['=files:js:tst ? rsc'], dest: 'data/hello-world', expand: true }]
    },
    'typescript=':       {
      is: 'target',
      outputName: '@openmicrostep/msbuildsystem.js.typescript',
      targets: ['core', 'foundation', 'js'],
      components: ['=base', '=::foundation::', '=::js::', '=::core::'],
      files: ['=files:typescript:src ? tsc'],
      npmPackage: { is: "component",
        dependencies: { is: "component",
          "typescript": "^2.2.2",
        }
      },
    },
    'typescript tests=': {
      is: 'target',
      outputName: '@openmicrostep/msbuildsystem.js.typescript.tests',
      components: ['=base tests', '=::core::', '=::js::', '=::typescript::'],
      targets: ['typescript'],
      files: ['=files:typescript:tst ? tsc'],
      copyFiles: [{is: 'group', elements: ['=files:typescript:tst ? rsc'], dest: 'data/hello-world', expand: true }]
    },
  },
  'commands=': { is: "group",
    "envs=": { is: "group", elements: [
      { is: "environment", name: "gitlab"  , tags: ["ci"   ] },
      { is: "environment", name: "travis"  , tags: ["ci"   , "coveralls"] },
      { is: "environment", name: "appveyor", tags: ["ci"   ] },
      { is: "environment", name: "local"   , tags: ["local"] },
    ]},
    "shell=": {
      is: "component",
      type: "basic",
      manual: true,
      environments: ["=envs"],
    },
    "cmd_no_cwd=": {
      is: "component",
      type: "cmd",
      tty: true,
      shell: true,
    },
    "cmd=": {
      is: "component",
      components: ["=cmd_no_cwd"],
      cwd: "={cwd}.absolutePath",
    },
    'cwd=': { is: 'group', elements: [{ is: 'file', name: "../" }] },
    "install-deps=": { is: "task", components: ["=cmd"], cmd: "npm install -g -q coveralls nyc @openmicrostep/tests" },
    "build-1=": { is: "task", components: ["=cmd"], cmd: Value([
      "msbuildsystem", "build", "-p", "@msbuildsystem", "-w", "dist/1/"
    ]) },
    "tests-1=": { is: "task", components: ["=cmd"], cmd: Value([
      "mstests", "-c", ...tests("dist/1")
    ]) },
    "build-2=": { is: "task", components: ["=cmd"], cmd: Value([
      "node", "dist/1/node/node_modules/@openmicrostep/msbuildsystem.cli/index.js", "build", "-p", "@msbuildsystem", "-w", "dist/2/"
    ]) },
    "tests-2=": { is: "task", components: ["=cmd"], cmd: Value([
      "mstests", "-c", ...tests("dist/2")
    ]) },
    "build-3=": { is: "task", components: ["=cmd"], cmd: Value([
      "node", "dist/2/node/node_modules/@openmicrostep/msbuildsystem.cli/index.js", "build", "-p", "@msbuildsystem", "-w", "dist/3/"
    ]) },
    "tests-3=": { is: "task", components: ["=cmd"], cmd: Value([
      "mstests", "-c", "-t", "10000", ...tests("dist/3")
    ]) },
    "coverage-local-3=": { is: "task", components: ["=cmd"], env: { is: "component", NYC_CWD: cwd_test("dist/3") }, cmd: Value([
      "nyc", "--reporter=text-lcov", "--report-dir", `${__dirname}/../dist/coverage`, "-x", "*.tests/**", "mstests",
      "-c", "-t", "20000", ...tests("dist/3")
    ]) },
    "coveralls-3=": { is: "task", components: ["=cmd"], env: { is: "component", NYC_CWD: cwd_test("dist/3") }, cmd:
      `nyc --reporter=text-lcov --report-dir ${__dirname}/../dist/coverage -x "*.tests/**" mstests -c -t 20000 ${tests("dist/3").join(' ')} | coveralls`
    },

    "deploy-shared="    : { is: "task", components: ["=cmd"], cmd: Value(["npm",  "publish", "dist/3/node/node_modules/@openmicrostep/msbuildsystem.shared"       ]) },
    "deploy-core="      : { is: "task", components: ["=cmd"], cmd: Value(["npm",  "publish", "dist/3/node/node_modules/@openmicrostep/msbuildsystem.core"         ]) },
    "deploy-cli="       : { is: "task", components: ["=cmd"], cmd: Value(["npm",  "publish", "dist/3/node/node_modules/@openmicrostep/msbuildsystem.cli"          ]) },
    "deploy-foundation=": { is: "task", components: ["=cmd"], cmd: Value(["npm",  "publish", "dist/3/node/node_modules/@openmicrostep/msbuildsystem.foundation"   ]) },
    "deploy-js="        : { is: "task", components: ["=cmd"], cmd: Value(["npm",  "publish", "dist/3/node/node_modules/@openmicrostep/msbuildsystem.js"           ]) },
    "deploy-ts="        : { is: "task", components: ["=cmd"], cmd: Value(["npm",  "publish", "dist/3/node/node_modules/@openmicrostep/msbuildsystem.js.typescript"]) },
    "deploy=":        { is: "target", components: ["=shell"], targets: ["bootstrap"],
      preTasks: Value(["=deploy-shared","=deploy-core","=deploy-cli","=deploy-foundation","=deploy-js","=deploy-ts"]) },

    "build-tests-1=": { is: "target", components: ["=shell"], preTasks: Value(["=build-1", "=tests-1"]) },
    "build-tests-2=": { is: "target", components: ["=shell"], preTasks: Value(["=build-2", "=tests-2"]) },
    "build-tests-3=": { is: "target", components: ["=shell"], preTasks: Value(["=build-3", "=tests-3"]) },
    "bootstrap=":     { is: "target", components: ["=shell"], preTasksByEnvironment: {
      "=envs ? ci + !coveralls": Value(["=install-deps", "=build-1", "=build-2", "=build-3", "=tests-3"                                    ]),
      "=envs ? ci +  coveralls": Value(["=install-deps", "=build-1", "=build-2", "=build-3", "=tests-3", "=coveralls-3"     ]),
      "=envs ? local"          : Value(["=build-1", "=build-2", "=build-3", "=tests-3", "=coverage-local-3"]),
    } },
  }
}

<|endoftext|>


<commit_before>import { TopicModel } from './resource/TopicModel';
import { UpvoteModel } from './resource/UpvoteModel';
import mongoose from 'mongoose';

export default function upvote(req) {
  return new Promise((resolve, reject) => {
    let topic_id = req.body._id;
    let user = req.session.user;

    // Check if user has already voted for the topic
    UpvoteModel.find({user: user, topicId: topic_id}).then(function(result){
      if(result.length===0) {
        // make async call to database
        TopicModel.update({_id: mongoose.Types.ObjectId(topic_id)}, {$inc: {upVotes: 1}}).then(function(result){
          UpvoteModel.create({user: user, topicId: topic_id}).then(function(result) {
            TopicModel.find({}).then(function(result) {
              resolve(result);
            }, function(err) {
              reject(err);
            })
          }, function(err) {
            reject(err);
          })
        }, function(err){
          reject(err);
        })
      }
    }, function(err){
      reject(err);
    });
  });
}
<commit_msg>temp fix<commit_after>import { TopicModel } from './resource/TopicModel';
import { UpvoteModel } from './resource/UpvoteModel';
import mongoose from 'mongoose';

export default function upvote(req) {
  return new Promise((resolve, reject) => {
    let topic_id = req.body._id;
    let user = req.session.user || 'kmesta';

    // Check if user has already voted for the topic
    UpvoteModel.find({user: user, topicId: topic_id}).then(function(result){
      if(result.length===0) {
        // make async call to database
        TopicModel.update({_id: mongoose.Types.ObjectId(topic_id)}, {$inc: {upVotes: 1}}).then(function(result){
          UpvoteModel.create({user: user, topicId: topic_id}).then(function(result) {
            TopicModel.find({}).then(function(result) {
              resolve(result);
            }, function(err) {
              reject(err);
            })
          }, function(err) {
            reject(err);
          })
        }, function(err){
          reject(err);
        })
      }
    }, function(err){
      reject(err);
    });
  });
}
<|endoftext|>


<commit_before>const shell = require('shelljs')
const path = require('path')

const phenylModules = shell.exec(
  'ls -F ./modules | grep / | tr -d "/"',
  { silent: true }
).trim().split('\n')

const linkPhenylModules = (moduleNames) => {
  moduleNames.forEach(module => {
    shell.cd('node_modules')
    shell.echo(`link ${module}`)
    shell.ln('-s', `../../${module}`, module)
    shell.cd('../')
  })
}

shell.exec('npm i')

phenylModules.forEach(module => {
  shell.cd(`modules/${module}`)

  const packageJson = require(path.join(__dirname, `../modules/${module}/package.json`))
  let modulesInPhenyl = []

  if (packageJson.dependencies != null) {
    const dependencies = Object.keys(packageJson.dependencies)
    modulesInPhenyl = modulesInPhenyl.concat(dependencies.filter(dependency => (phenylModules.includes(dependency))))
  }

  if (packageJson.devDependencies != null) {
    const devDependencies = Object.keys(packageJson.devDependencies)
    modulesInPhenyl = modulesInPhenyl.concat(devDependencies.filter(devDependency => (phenylModules.includes(devDependency))))
  }

  shell.mkdir('-p', 'node_modules')
  linkPhenylModules(modulesInPhenyl)
  shell.exec('npm i')

  shell.cd('../../')
})
<commit_msg>[tools] improve installation command<commit_after>const shell = require('shelljs')
const path = require('path')

class ModuleLoader {
  constructor() {
    this.visitedModules = {}
    this.loadedModules = {}

    shell.cd(__dirname + '/..')
    this.modules = shell.exec(
      'ls -F ./modules | grep / | tr -d "/"',
      { silent: true }
    ).trim().split('\n')
  }

  load() {
    this.modules.forEach(moduleName => {
      this.installSubModules(moduleName)
    })
  }

  installSubModules(moduleName) {
    if (this.loadedModules[moduleName]) {
      return
    }

    if (this.visitedModules[moduleName]) {
      throw new Error('Circular dependencies detected.')
    }

    this.visitedModules[moduleName] = true

    const dependentModules = this.getDependentModules(moduleName)

    if (dependentModules.length) {
      dependentModules.forEach(depModuleName => {
        this.linkModule(depModuleName, moduleName)
        this.installSubModules(depModuleName)
      })
    }

    console.log(`[${moduleName}] All dependent modules were resolved.`)
    console.log(`[${moduleName}] Running npm install.`)
    shell.cd(`modules/${moduleName}/`)
    shell.exec('npm install')
    shell.cd('../../')
    console.log(`[${moduleName}] install done.\n`)
    this.loadedModules[moduleName] = true
  }

  linkModule(moduleName, ownerModuleName) {
    shell.mkdir('-p', `modules/${ownerModuleName}/node_modules`)
    shell.cd(`modules/${ownerModuleName}/node_modules`)
    console.log(`[${ownerModuleName}] linking ${moduleName}`)
    shell.ln('-s', `../../${moduleName}`, moduleName)
    shell.cd('../../../')
  }

  getDependentModules(moduleName) {
    const packageJson = require(path.join(__dirname, `../modules/${moduleName}/package.json`))
    let dependentModules = []

    if (packageJson.dependencies != null) {
      const dependencies = Object.keys(packageJson.dependencies)
      dependentModules = dependentModules.concat(dependencies.filter(dependency => (this.modules.includes(dependency))))
    }

    if (packageJson.devDependencies != null) {
      const devDependencies = Object.keys(packageJson.devDependencies)
      dependentModules = dependentModules.concat(devDependencies.filter(devDependency => (this.modules.includes(devDependency))))
    }
    return dependentModules
  }
}

new ModuleLoader().load()
<|endoftext|>