<commit_before>var app = angular.module('app');

app.directive('project', function() {
  return {
    restrict: 'E',
    //scope: true,
    scope: {
      createDependency: '=',
      tree: '=',
      selectedNode: '=',
      colors: '=',
      dependency: '=',
      show: '='
    },
    template: '
' +
              '  <button class="btn btn-default" ng-click="setMode(\'commits\')"></button>' +
              '  <button class="btn btn-default" ng-click="setMode(\'links\')"></button>' +
              '  <button class="btn btn-default" ng-click="btnAddRowClicked()"> Add row</button>' +
              '  <button class="btn btn-default" ng-click="btnRedrawClicked()">Redraw</button>' +
              '  <svg></svg>' +
              '
',
    link: function(scope, element, attrs) {
      var $scope = scope;
      $scope.mode = 'commits';

      var firstCommit = null;
      var selectedPath = null;
      $scope.selectedNode = null;

      var lineFunction = d3.svg.line()
        .x(function(d) { return d.x; })
        .y(function(d) { return d.y; })
        .interpolate("linear");

      $scope.setMode = function(mode) {
        $scope.mode = mode;
        $scope.drawTree();
      };

      $scope.btnRedrawClicked = function() {
        $scope.drawTree();
      };

      $scope.btnAddRowClicked = function() {
        $scope.tree.push({id: $scope.tree.length.toString(), parents: [], column: 0, parentsPaths: {}, color: '#5aa1be'});
        $scope.drawTree();
      };

      $scope.drawTree = function() {
        if ($scope.$root.$$phase != '$apply' && $scope.$root.$$phase != '$digest') {
          $scope.$apply();
        }
        var xGap = 30;
        var yGap = 30;
        var cols = 10;
        var radius = 8;

        var svg = d3.select(element.find('svg')[0])
          .style('border', '1px solid gray')
          .attr('width', '100%')
          .attr('height', '300px');
        svg.selectAll('*').remove();

        var linesGroup = svg.append('g');
        var lineGroup = linesGroup.selectAll('lines')
          .data($scope.tree)
          .enter()
          .append('g');

        lineGroup
          .append('path')
          .attr('d', function(path, idx) {
            var d = [];
            d.push({x: 0, y: idx * yGap + yGap});
            d.push({x: $(svg[0][0]).width(), y: idx * yGap + yGap});
            return lineFunction(d)
          })
          .attr('stroke-width', 1)
          .attr('fill', 'none')
          .attr('stroke', '#aaa')
          .on('click', function(a, row, c) {
            $scope.tree.splice(row, 1);
            $scope.drawTree();
          });

          if ($scope.mode == 'commits') {
            lineGroup.selectAll('dummyCircle')
              .data(function(d, i) { return _.range(cols); })
              .enter()
              .append('circle')
                .attr('r', radius)
                .attr('stroke', '#ddd')
                .attr('fill', '#fff')
                .attr('cx', function(c) { return c * xGap + xGap; })
                .attr('cy', function(c, i, a) { return a * yGap + yGap })
                .on('mouseenter', function() { d3.select(this).attr('fill', '#f00'); })
                .on('mouseleave', function() { d3.select(this).attr('fill', '#fff'); })
                .on('click', function(a,b,c) {
                  $scope.tree[c].column = a;
                  $scope.drawTree();
                });
          } else {
            lineGroup.selectAll('dummyCircle')
              .data(function(d, i) { return _.range(cols); })
              .enter()
              .append('circle')
                .attr('r', 5)
                .attr('fill', 'none')
                .attr('stroke', '#ddd')
                .attr('fill', '#ddd')
                .attr('cx', function(c) { return c * xGap + xGap; })
                .attr('cy', function(c, i, a) { return a * yGap + yGap })
                .on('mousedown', function() {})
                .on('mouseup', function(item, columnIndex, rowIndex) {
                  if (selectedPath) {
                    console.log(selectedPath, columnIndex, rowIndex);
                    addPathNode(selectedPath[1], columnIndex, rowIndex);
                    console.log(selectedPath[1]);
                    selectedPath = null;
                    $scope.drawTree();
                  }
                });
          }

          var addPathNode = function(path, x, y) {
            if (y == path.path[0][1] && x > path.path[0][0]) {
              path.path.splice(1, 0, [x, y, 2]);
              return;
            }
            for (var i = 0; i < path.path.length; i++) {
              var pathItem = path.path[i];
              if (y > pathItem[1]) {
                continue;
              }
              path.path.splice(i, 0, [x, y, 1]);
              break;
            }
          };

          var nodesGroup = svg.append('g').attr('class', 'nodes');
          var nodeGroup = nodesGroup.selectAll('nodes')
            .data($scope.tree)
            .enter()
            .append('g')
            .attr('class', 'node');

          // Each paths
          var pathsGroup = nodeGroup
            .append('g')
            .attr('class', 'paths');
          pathsGroup
            .selectAll('g')
            .data(function(node) {
              return _.map(node.parentsPaths, function(pathItem, parentId) { return [node, pathItem, parentId]; });
            })
            .enter()
            .append('path')
              .attr('d', function(item) {
                var node = item[0];
                var path = item[1];
                var parentId = item[2];
                var p = $scope.tree[parentId];
                var result = [];
                _.each(path.path, function(item) {
                  var point = {
                    x: item[0] * xGap + xGap,
                    y: item[1] * yGap + yGap
                  };
                  if (item[2] == 2) {
                    point.y += 6;
                  }
                  if (item[2] == 1) {
                    point.y -= 6;
                  }
                  result.push(point);
                });
                return lineFunction(result)
              })
              .attr('stroke-width', 3)
              .attr('fill', 'none')
              .attr('stroke', function(item) {
                return item[1].color;
              })
              .on('mousedown', function(item) {
                selectedPath = item;
              })
              .on('click', function(item) {
                var node = item[0];
                var idx = _.indexOf(node.parents, item[1]);
                $scope.tree[node.id].parents.splice(idx, 1);
                $scope.drawTree();
              });

          var addPath = function(rowIndex) {
            var firstNode = $scope.tree[firstCommit];
            var lastNode = $scope.tree[rowIndex];
            $scope.tree[firstCommit].parents.push(rowIndex.toString());
            $scope.tree[firstCommit].parents = _.sortBy($scope.tree[firstCommit].parents);
            $scope.tree[firstCommit].parentsPaths[rowIndex.toString()] = {
              path: [
                [firstNode.column, parseInt(firstNode.id), 0],
                [lastNode.column, parseInt(lastNode.id), 0]],
              color: '#5aa1be'};
            firstCommit = null;
            $scope.drawTree();
          };

          // Each nodes
          nodeGroup.append('circle')
            .attr('r', radius)
            .attr('fill', function(node) { return node.color; })
            .attr('stroke', '#000')
            .attr('cx', function(node) {
              return node.column * xGap + xGap;
            })
            .attr('cy', function(node, idx) { return idx * yGap + yGap })
            .on('mouseenter', function() { d3.select(this).attr('fill', '#f00'); })
            .on('mouseleave', function(node) { d3.select(this).attr('fill', node.color); })
            .on('mousedown', function(node, rowIndex) {
              firstCommit = rowIndex;
            })
            .on('mouseup', function(node, rowIndex) {
              if (firstCommit == rowIndex) {
                return;
              }
              if (firstCommit > rowIndex) {
                firstCommit = [rowIndex, rowIndex = firstCommit][0]; // swap vars
              }
              if (!_.includes($scope.tree[firstCommit].parents, rowIndex)) {
                addPath(rowIndex);
              }
            })
            .on('click', function(node) {
              $scope.selectedNode = node;
              $scope.$apply();
            });

      };

      $scope.$watchCollection('tree', function(newValue, oldValue) {
        $scope.drawTree();
        //new ZeroClipboard($('.copy-btn'));
      });

    }
  }
});
<commit_msg>focus-me & ng-enter directives<commit_after>var app = angular.module('app');

app.directive('project', function() {
  return {
    restrict: 'E',
    //scope: true,
    scope: {
      createDependency: '=',
      tree: '=',
      selectedNode: '=',
      colors: '=',
      dependency: '=',
      show: '='
    },
    template: '
' +
              '  <button class="btn btn-default" ng-click="setMode(\'commits\')"></button>' +
              '  <button class="btn btn-default" ng-click="setMode(\'links\')"></button>' +
              '  <button class="btn btn-default" ng-click="btnAddRowClicked()"> Add row</button>' +
              '  <button class="btn btn-default" ng-click="btnRedrawClicked()">Redraw</button>' +
              '  <svg></svg>' +
              '
',
    link: function(scope, element, attrs) {
      var $scope = scope;
      $scope.mode = 'commits';

      var firstCommit = null;
      var selectedPath = null;
      $scope.selectedNode = null;

      var lineFunction = d3.svg.line()
        .x(function(d) { return d.x; })
        .y(function(d) { return d.y; })
        .interpolate("linear");

      $scope.setMode = function(mode) {
        $scope.mode = mode;
        $scope.drawTree();
      };

      $scope.btnRedrawClicked = function() {
        $scope.drawTree();
      };

      $scope.btnAddRowClicked = function() {
        $scope.tree.push({id: $scope.tree.length.toString(), parents: [], column: 0, parentsPaths: {}, color: '#5aa1be'});
        $scope.drawTree();
      };

      $scope.drawTree = function() {
        if ($scope.$root.$$phase != '$apply' && $scope.$root.$$phase != '$digest') {
          $scope.$apply();
        }
        var xGap = 30;
        var yGap = 30;
        var cols = 10;
        var radius = 8;

        var svg = d3.select(element.find('svg')[0])
          .style('border', '1px solid gray')
          .attr('width', '100%')
          .attr('height', '300px');
        svg.selectAll('*').remove();

        var linesGroup = svg.append('g');
        var lineGroup = linesGroup.selectAll('lines')
          .data($scope.tree)
          .enter()
          .append('g');

        lineGroup
          .append('path')
          .attr('d', function(path, idx) {
            var d = [];
            d.push({x: 0, y: idx * yGap + yGap});
            d.push({x: $(svg[0][0]).width(), y: idx * yGap + yGap});
            return lineFunction(d)
          })
          .attr('stroke-width', 1)
          .attr('fill', 'none')
          .attr('stroke', '#aaa')
          .on('click', function(a, row, c) {
            $scope.tree.splice(row, 1);
            $scope.drawTree();
          });

          if ($scope.mode == 'commits') {
            lineGroup.selectAll('dummyCircle')
              .data(function(d, i) { return _.range(cols); })
              .enter()
              .append('circle')
                .attr('r', radius)
                .attr('stroke', '#ddd')
                .attr('fill', '#fff')
                .attr('cx', function(c) { return c * xGap + xGap; })
                .attr('cy', function(c, i, a) { return a * yGap + yGap })
                .on('mouseenter', function() { d3.select(this).attr('fill', '#f00'); })
                .on('mouseleave', function() { d3.select(this).attr('fill', '#fff'); })
                .on('click', function(a,b,c) {
                  $scope.tree[c].column = a;
                  $scope.drawTree();
                });
          } else {
            lineGroup.selectAll('dummyCircle')
              .data(function(d, i) { return _.range(cols); })
              .enter()
              .append('circle')
                .attr('r', 5)
                .attr('fill', 'none')
                .attr('stroke', '#ddd')
                .attr('fill', '#ddd')
                .attr('cx', function(c) { return c * xGap + xGap; })
                .attr('cy', function(c, i, a) { return a * yGap + yGap })
                .on('mousedown', function() {})
                .on('mouseup', function(item, columnIndex, rowIndex) {
                  if (selectedPath) {
                    console.log(selectedPath, columnIndex, rowIndex);
                    addPathNode(selectedPath[1], columnIndex, rowIndex);
                    console.log(selectedPath[1]);
                    selectedPath = null;
                    $scope.drawTree();
                  }
                });
          }

          var addPathNode = function(path, x, y) {
            if (y == path.path[0][1] && x > path.path[0][0]) {
              path.path.splice(1, 0, [x, y, 2]);
              return;
            }
            for (var i = 0; i < path.path.length; i++) {
              var pathItem = path.path[i];
              if (y > pathItem[1]) {
                continue;
              }
              path.path.splice(i, 0, [x, y, 1]);
              break;
            }
          };

          var nodesGroup = svg.append('g').attr('class', 'nodes');
          var nodeGroup = nodesGroup.selectAll('nodes')
            .data($scope.tree)
            .enter()
            .append('g')
            .attr('class', 'node');

          // Each paths
          var pathsGroup = nodeGroup
            .append('g')
            .attr('class', 'paths');
          pathsGroup
            .selectAll('g')
            .data(function(node) {
              return _.map(node.parentsPaths, function(pathItem, parentId) { return [node, pathItem, parentId]; });
            })
            .enter()
            .append('path')
              .attr('d', function(item) {
                var node = item[0];
                var path = item[1];
                var parentId = item[2];
                var p = $scope.tree[parentId];
                var result = [];
                _.each(path.path, function(item) {
                  var point = {
                    x: item[0] * xGap + xGap,
                    y: item[1] * yGap + yGap
                  };
                  if (item[2] == 2) {
                    point.y += 6;
                  }
                  if (item[2] == 1) {
                    point.y -= 6;
                  }
                  result.push(point);
                });
                return lineFunction(result)
              })
              .attr('stroke-width', 3)
              .attr('fill', 'none')
              .attr('stroke', function(item) {
                return item[1].color;
              })
              .on('mousedown', function(item) {
                selectedPath = item;
              })
              .on('click', function(item) {
                var node = item[0];
                var idx = _.indexOf(node.parents, item[1]);
                $scope.tree[node.id].parents.splice(idx, 1);
                $scope.drawTree();
              });

          var addPath = function(rowIndex) {
            var firstNode = $scope.tree[firstCommit];
            var lastNode = $scope.tree[rowIndex];
            $scope.tree[firstCommit].parents.push(rowIndex.toString());
            $scope.tree[firstCommit].parents = _.sortBy($scope.tree[firstCommit].parents);
            $scope.tree[firstCommit].parentsPaths[rowIndex.toString()] = {
              path: [
                [firstNode.column, parseInt(firstNode.id), 0],
                [lastNode.column, parseInt(lastNode.id), 0]],
              color: '#5aa1be'};
            firstCommit = null;
            $scope.drawTree();
          };

          // Each nodes
          nodeGroup.append('circle')
            .attr('r', radius)
            .attr('fill', function(node) { return node.color; })
            .attr('stroke', '#000')
            .attr('cx', function(node) {
              return node.column * xGap + xGap;
            })
            .attr('cy', function(node, idx) { return idx * yGap + yGap })
            .on('mouseenter', function() { d3.select(this).attr('fill', '#f00'); })
            .on('mouseleave', function(node) { d3.select(this).attr('fill', node.color); })
            .on('mousedown', function(node, rowIndex) {
              firstCommit = rowIndex;
            })
            .on('mouseup', function(node, rowIndex) {
              if (firstCommit == rowIndex) {
                return;
              }
              if (firstCommit > rowIndex) {
                firstCommit = [rowIndex, rowIndex = firstCommit][0]; // swap vars
              }
              if (!_.includes($scope.tree[firstCommit].parents, rowIndex)) {
                addPath(rowIndex);
              }
            })
            .on('click', function(node) {
              $scope.selectedNode = node;
              $scope.$apply();
            });

      };

      $scope.$watchCollection('tree', function(newValue, oldValue) {
        $scope.drawTree();
        //new ZeroClipboard($('.copy-btn'));
      });

    }
  }
});

app.directive('focusMe', function($timeout) {
  return {
    scope: { trigger: '@focusMe' },
    link: function(scope, element, attr) {
      var predicate = attr.focusMe || true;
      switch (predicate) {
        case "true": case "yes": case "1":
          predicate = true;
          break;
        case "false": case "no": case "0": case null:
          predicate = false;
          break;
        default:
          predicate = Boolean(predicate);
          break;
      }
      if (!predicate) {
        return;
      }
      scope.$watch('trigger', function(value) {
        $timeout(function() {
          element[0].focus();
        });
      });
    }
  };
});

app.directive('ngEnter', function() {
  return function(scope, element, attrs) {
    element.bind("keydown keypress", function(event) {
      if(event.which === 13) {
        scope.$apply(function(){
          scope.$eval(attrs.ngEnter, {'event': event});
        });
        event.preventDefault();
      }
    });
  };
});
<|endoftext|>


<commit_before>//----------------------------------------------------------------------
//
// This source file is part of the furipota project.
//
// Licensed under MIT. See LICENCE for full licence information.
// See CONTRIBUTORS for the list of contributors to the project.
//
//----------------------------------------------------------------------

const program = require('commander');
const path = require('path');
const VM = require('./vm');
const runtime = require('./runtime');
const package = require('../package.json');

program.version(package.version);

program.command('run [file] [pipeline]')
  .description(`Runs the provided pipeline to completion.`)
  .action(async (definitions, pipeline, options) => {
    try {
      const file = path.resolve(process.cwd(), definitions);
      const vm = new VM(path.dirname(file));
      vm.plugin(runtime);
      await vm.import(file);
      const stream = vm.global.get(pipeline).invoke(vm);
      stream.subscribe({
        Value(x){ },
        Error(x){
          console.log('Error:', x);
        },
        Close(){ }
      });
      await stream.run();
    } catch (error) {
      console.error(error.stack);
      process.exit(1);
    }
  });

program.parse(process.argv);
<commit_msg>Adds support for providing plugins<commit_after>//----------------------------------------------------------------------
//
// This source file is part of the furipota project.
//
// Licensed under MIT. See LICENCE for full licence information.
// See CONTRIBUTORS for the list of contributors to the project.
//
//----------------------------------------------------------------------

const program = require('commander');
const path = require('path');
const VM = require('./vm');
const runtime = require('./runtime');
const package = require('../package.json');

const collect = (value, memo) => {
  memo.push(value);
  return memo;
};

const toModuleId = (module) => {
  if (/^\./.test(module)) {
    return path.resolve(process.cwd(), module);
  } else {
    return module;
  }
};

program.version(package.version);

program.command('run <file> <pipeline>')
  .description(`Runs the provided pipeline to completion.`)
  .option('-p, --plugin [module]', 'The module ID of a Furipota plugin', collect, [])
  .action(async (definitions, pipeline, options) => {
    try {
      const file = path.resolve(process.cwd(), definitions);
      const vm = new VM(path.dirname(file));
      vm.plugin(runtime);
      options.plugin.forEach(plugin => vm.plugin(require(toModuleId(plugin))));
      await vm.import(file);
      const stream = vm.global.get(pipeline).invoke(vm);
      stream.subscribe({
        Value(x){ },
        Error(x){
          console.log('Error:', x);
        },
        Close(){ }
      });
      await stream.run();
    } catch (error) {
      console.error(error.stack);
      process.exit(1);
    }
  });

program.parse(process.argv);

if (process.argv.length < 3) {
  program.help();
}<|endoftext|>


<commit_before>angular.module('service-module')
    .controller('serviceHeaderController',['$scope','$element','$http',function($scope,$element,$http){
        $scope.goto = function(name){
            $element.find('.item').removeClass('active');
            $element.find('.'+name).addClass('active');
            var $collapse = $element.find('.navbar-collapse');
            $collapse.addClass('collapsing')
                .removeClass('in');
            setTimeout(function(){
                $collapse.removeClass('collapsing');
            },300);
        };
        $scope.exit = function(){
            var id = sessionStorage.getItem('sessionID');
            $http({
                url:localStorage.getItem('ip')+'retailer/user/logoff?sessionID='+id,
                method:'POST',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'
                }
            }).success(function(){
                location.assign('/');
            });
        };
    }])
    .controller('queryController',['$scope','$rootScope','$http',function($scope,$rootScope,$http){
        $rootScope.goto('query');
        $scope.phoneNum = '';
        $scope.method = {};
        $scope.state = {};
        $scope.methods = [];
        $scope.search = {
            key:'phone',
            value:$scope.phoneNum
        };
        $http({
            url:localStorage.getItem('ip')+'retailer/salesMode/getAll?sessionID='+sID,
            method:'GET',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'
            }
        }).success(function(data){
            if(data.result=='1')$scope.methods = data.data;
        });
        $scope.$watch('[search.key,method,state,phoneNum]',function(newVal){
            switch(newVal[0]){
                case 'phone':
                    $scope.search.value = '';
                    $scope.search.value = newVal[3];
                    break;
                case 'method':
                    $scope.search.value = [];
                    for(key in newVal[1]){
                        if(newVal[1][key])$scope.search.value.push(key);
                    }
                    break;
                case 'state':
                    $scope.search.value = [];
                    for(state in newVal[2]){
                        if(newVal[2][state])$scope.search.value.push(state);
                    }
                    break;
            }
        },true);
        $scope.find = function(search){
            console.log(search);
            location.assign('#/qresult/'+search.key+'/'+search.value);
        };
        $scope.validatephone = function(){
            var reg = /^(0|86|17951)?(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$/;
            return reg.test($scope.search.value);
        };
        $scope.validate = function(){
            if($scope.search.key=='phone') {
                return $scope.validatephone();
            }
            else if($scope.search.key=='method'){
                var reg = /[0-9a-f]{32}/;
                for(i in $scope.search.value){
                    if(!reg.test($scope.search.value[i]))return false;
                }
                return true;
            }
            else if($scope.search.key=='state'){
                var reg = /(pending|visits|chips|knockdowns)/;
                for(i in $scope.search.value){
                    if(!reg.test($scope.search.value[i]))return false;
                }
                return true;
            }
        };
    }])
    .controller('qresultController',['$scope','$routeParams','$http',function($scope,$routeParams,$http){
        $scope.dataList = [];
        var pageNum=1,
            idle = true,
            totalPageNum,
            id = sessionStorage.getItem('sessionID'),
            querydata,
            states = ['pending','visits','chips','knockdowns'];
        switch($routeParams.key){
            case 'phone':querydata = '&mobile='+$routeParams.value;break;
            case 'method':
                var values = $routeParams.value.split(',');
                querydata = '';
                for(key in values){
                    querydata += '&method[]='+values[key];
                }
                break;
            case 'state':
                var values = $routeParams.value.split(',');
                querydata = '';
                for(key in values){
                    querydata += '&state[]='+(states.indexOf(values[key]));
                }
                break;
        }
        console.log(querydata);
        function getData(pageNum){
            idle = false;
            $http({
                url:localStorage.getItem('ip')+'retailer/customer/query?sessionID='+id+
                '&aCurPage='+pageNum+'&aPageSize=10'+querydata,
                method:'GET',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'
                }
            }).success(function(data){
                console.log(data);
                if(data.result=="1"){
                    $scope.dataList = $scope.dataList.concat(data.data.dataList);
                    totalPageNum = data.data.totalPageNum;
                }
                idle = true;
            });
        }
        $scope.stateParse = function(state){
            switch(state){
                case '0': return '未';break;
                case '1': return '访';break;
                case '2': return '筹';break;
                case '3': return '成';break;
                default: return '错';
            }
        };
        getData(pageNum);
        $list = angular.element("ul.cust-list");
        $list.height(window.innerHeight-150);
        $list.on('scroll',function(e){
            var t = e.target;
            if(idle && pageNum<totalPageNum && t.scrollHeight-t.scrollTop-5 <= +t.style.height.slice(0,-2)){
                console.log('load new data');
                getData(++pageNum);
            }
        });
    }])
    .controller('listController',['$scope','$rootScope','$http',function($scope,$rootScope,$http){
        $rootScope.goto('list');
        $scope.dataList = [];
        $scope.n = 1;
        $scope.change = function(n){
            $scope.n = n;
        };
        var pageNum,
            idle = true,
            totalPageNum,
            id = sessionStorage.getItem('sessionID');
        $scope.$watch('n',function(newVal){
            pageNum = 1;
            $scope.dataList = [];
            getData(pageNum, newVal);
        });
        function getData(pageNum, cat){
            idle = false;
            $http({
                url:localStorage.getItem('ip')+'retailer/customer/query?sessionID='+id+
                '&aCurPage='+pageNum+'&aPageSize=10&state[]='+cat,
                method:'GET',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'
                }
            }).success(function(data){
                console.log(data);
                if(data.result=="1"){
                    $scope.dataList = $scope.dataList.concat(data.data.dataList);
                    totalPageNum = data.data.totalPageNum;
                }
                idle = true;
            });
        }
        $scope.stateParse = function(state){
            switch(state){
                case '1': return '未';break;
                case '2': return '访';break;
                case '3': return '筹';break;
                case '4': return '成';break;
                default: return '错';
            }
        };
        $list = angular.element("ul.cust-list");
        $list.height(window.innerHeight-150);
        $list.on('scroll',function(e){
            var t = e.target;
            if(idle && pageNum<totalPageNum && t.scrollHeight-t.scrollTop-5 <= +t.style.height.slice(0,-2)){
                console.log('load new data');
                getData(++pageNum, $scope.n);
            }
        });
    }])
    .controller('custDetails',['$routeParams','$scope','$http',function($routeParams,$scope,$http){
        $scope.service = true;
        $scope.data = {};
        var id =  $routeParams.cust;
        $http({
            url:localStorage.getItem('ip')+'retailer/customer/detail?uuid='+id+'&sessionID='+sID,
            method:'GET',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'
            }
        }).success(function(data){
            console.log(data);
            if(data.result=="1")$scope.data = data.data;
        });
        $scope.changeState = function(){
            location.assign('#/'+id+'/change');
        }
    }])
    .controller('custChange',['$scope',function($scope){
        $scope.step = 0;
    }])
    .controller('stepContentCtrl',['$scope','$http','$routeParams',function($scope,$http,$routeParams){
        $scope.updating = true;
        var id = $routeParams.cust;
        var custData = {};
        $http({
            url:localStorage.getItem('ip')+'retailer/customer/detail?uuid='+id+'&sessionID='+sID,
            method:'GET',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'
            }
        }).success(function(data){
            console.log(data);
            if(data.result=="1"){
                custData = data.data;
                $scope.visitCount = custData.visitCount=='null'?0:custData.visitCount;
                $scope.$parent.step = +custData.state+1;
                $scope.updating = false;
            }
        });
        function updateServer(updateTime){
            $scope.updating = true;
            var url = localStorage.getItem('ip')+'retailer/customer/modifyCustomer';
            var datapost = 'sessionID='+sID+
                '&uuid='+id+
                '&position='+custData.position+
                '&name='+custData.name+
                '&visitCount='+$scope.visitCount+
                '&mobile='+custData.mobile+
                '&detail='+(custData.detail||'')+
                '&state='+($scope.$parent.step-1)+
                '&isUpdate='+updateTime;
            $http({
                url:url,
                method:'POST',
                data:datapost,
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded;charset=gb2312'
                }
            }).success(function(data){
                if(data.result=='1'){
                    $scope.updating=false;
                }
                else alert('update cust state failed!');
            });
        }
        $scope.nextStep = function(){
            $scope.$parent.step++;
            if($scope.$parent.step=='2')
                $scope.visitCount = '1';
            updateServer(true);
        };
        $scope.prevStep = function(){
            $scope.$parent.step--;
            if($scope.$parent.step=='1')
                $scope.visitCount = '0';
            updateServer(false);
        };
        $scope.addCount = function(){
            if(+$scope.visitCount<=60)
                $scope.visitCount = +$scope.visitCount+1+'';
            updateServer(true);
        };
        $scope.cutCount = function(){
            if(+$scope.visitCount>1)
                $scope.visitCount = +$scope.visitCount-1+'';
            else if(+$scope.visitCount==1)
                $scope.prevStep();
            updateServer(true);
        };
    }]);<commit_msg>no message<commit_after>angular.module('service-module')
    .controller('serviceHeaderController',['$scope','$element','$http',function($scope,$element,$http){
        $scope.goto = function(name){
            $element.find('.item').removeClass('active');
            $element.find('.'+name).addClass('active');
            var $collapse = $element.find('.navbar-collapse');
            $collapse.addClass('collapsing')
                .removeClass('in');
            setTimeout(function(){
                $collapse.removeClass('collapsing');
            },300);
        };
        $scope.exit = function(){
            var id = sessionStorage.getItem('sessionID');
            $http({
                url:localStorage.getItem('ip')+'retailer/user/logoff?sessionID='+id,
                method:'POST',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'
                }
            }).success(function(){
                location.assign('/');
            });
        };
    }])
    .controller('queryController',['$scope','$rootScope','$http',function($scope,$rootScope,$http){
        $rootScope.goto('query');
        $scope.phoneNum = '';
        $scope.method = {};
        $scope.state = {};
        $scope.methods = [];
        $scope.search = {
            key:'phone',
            value:$scope.phoneNum
        };
        $http({
            url:localStorage.getItem('ip')+'retailer/salesMode/getAll?sessionID='+sID,
            method:'GET',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'
            }
        }).success(function(data){
            if(data.result=='1')$scope.methods = data.data;
        });
        $scope.$watch('[search.key,method,state,phoneNum]',function(newVal){
            switch(newVal[0]){
                case 'phone':
                    $scope.search.value = '';
                    $scope.search.value = newVal[3];
                    break;
                case 'method':
                    $scope.search.value = [];
                    for(key in newVal[1]){
                        if(newVal[1][key])$scope.search.value.push(key);
                    }
                    break;
                case 'state':
                    $scope.search.value = [];
                    for(state in newVal[2]){
                        if(newVal[2][state])$scope.search.value.push(state);
                    }
                    break;
            }
        },true);
        $scope.find = function(search){
            console.log(search);
            location.assign('#/qresult/'+search.key+'/'+search.value);
        };
        $scope.validatephone = function(){
            var reg = /^(0|86|17951)?(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$/;
            return reg.test($scope.search.value);
        };
        $scope.validate = function(){
            if($scope.search.key=='phone') {
                return $scope.validatephone();
            }
            else if($scope.search.key=='method'){
                var reg = /[0-9a-f]{32}/;
                for(i in $scope.search.value){
                    if(!reg.test($scope.search.value[i]))return false;
                }
                return true;
            }
            else if($scope.search.key=='state'){
                var reg = /(pending|visits|chips|knockdowns)/;
                for(i in $scope.search.value){
                    if(!reg.test($scope.search.value[i]))return false;
                }
                return true;
            }
        };
    }])
    .controller('qresultController',['$scope','$routeParams','$http',function($scope,$routeParams,$http){
        $scope.dataList = [];
        var pageNum=1,
            idle = true,
            totalPageNum,
            id = sessionStorage.getItem('sessionID'),
            querydata,
            states = ['pending','visits','chips','knockdowns'];
        switch($routeParams.key){
            case 'phone':querydata = '&mobile='+$routeParams.value;break;
            case 'method':
                var values = $routeParams.value.split(',');
                querydata = '';
                for(key in values){
                    querydata += '&method[]='+values[key];
                }
                break;
            case 'state':
                var values = $routeParams.value.split(',');
                querydata = '';
                for(key in values){
                    querydata += '&state[]='+(states.indexOf(values[key]));
                }
                break;
        }
        console.log(querydata);
        function getData(pageNum){
            idle = false;
            $http({
                url:localStorage.getItem('ip')+'retailer/customer/query?sessionID='+id+
                '&aCurPage='+pageNum+'&aPageSize=10'+querydata,
                method:'GET',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'
                }
            }).success(function(data){
                console.log(data);
                if(data.result=="1"){
                    $scope.dataList = $scope.dataList.concat(data.data.dataList);
                    totalPageNum = data.data.totalPageNum;
                }
                idle = true;
            });
        }
        $scope.stateParse = function(state){
            switch(state){
                case '0': return '未';break;
                case '1': return '访';break;
                case '2': return '筹';break;
                case '3': return '成';break;
                default: return '错';
            }
        };
        getData(pageNum);
        $list = angular.element("ul.cust-list");
        $list.height(window.innerHeight-150);
        $list.on('scroll',function(e){
            var t = e.target;
            if(idle && pageNum<totalPageNum && t.scrollHeight-t.scrollTop-5 <= +t.style.height.slice(0,-2)){
                console.log('load new data');
                getData(++pageNum);
            }
        });
    }])
    .controller('listController',['$scope','$rootScope','$http',function($scope,$rootScope,$http){
        $rootScope.goto('list');
        $scope.dataList = [];
        $scope.n = 1;
        $scope.change = function(n){
            $scope.n = n;
        };
        var pageNum,
            idle = true,
            totalPageNum,
            id = sessionStorage.getItem('sessionID');
        $scope.$watch('n',function(newVal){
            pageNum = 1;
            $scope.dataList = [];
            getData(pageNum, newVal);
        });
        function getData(pageNum, cat){
            idle = false;
            $http({
                url:localStorage.getItem('ip')+'retailer/customer/query?sessionID='+id+
                '&aCurPage='+pageNum+'&aPageSize=10&state[]='+cat,
                method:'GET',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'
                }
            }).success(function(data){
                console.log(data);
                if(data.result=="1"){
                    $scope.dataList = $scope.dataList.concat(data.data.dataList);
                    totalPageNum = data.data.totalPageNum;
                }
                idle = true;
            });
        }
        $scope.stateParse = function(state){
            switch(state){
                case '1': return '未';break;
                case '2': return '访';break;
                case '3': return '筹';break;
                case '4': return '成';break;
                default: return '错';
            }
        };
        $list = angular.element("ul.cust-list");
        $list.height(window.innerHeight-150);
        $list.on('scroll',function(e){
            var t = e.target;
            if(idle && pageNum<totalPageNum && t.scrollHeight-t.scrollTop-5 <= +t.style.height.slice(0,-2)){
                console.log('load new data');
                getData(++pageNum, $scope.n);
            }
        });
    }])
    .controller('custDetails',['$routeParams','$scope','$http',function($routeParams,$scope,$http){
        $scope.service = true;
        $scope.data = {};
        var id =  $routeParams.cust;
        $http({
            url:localStorage.getItem('ip')+'retailer/customer/detail?uuid='+id+'&sessionID='+sID,
            method:'GET',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'
            }
        }).success(function(data){
            console.log(data);
            if(data.result=="1")$scope.data = data.data;
        });
        $scope.changeState = function(){
            location.assign('#/'+id+'/change');
        }
    }])
    .controller('custChange',['$scope',function($scope){
        $scope.step = 0;
    }])
    .controller('stepContentCtrl',['$scope','$http','$routeParams',function($scope,$http,$routeParams){
        $scope.updating = true;
        var id = $routeParams.cust;
        var custData = {};
        $http({
            url:localStorage.getItem('ip')+'retailer/customer/detail?uuid='+id+'&sessionID='+sID,
            method:'GET',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'
            }
        }).success(function(data){
            console.log(data);
            if(data.result=="1"){
                custData = data.data;
                $scope.visitCount = custData.visitCount=='null'?0:custData.visitCount;
                $scope.$parent.step = +custData.state+1;
                $scope.updating = false;
            }
        });
        function updateServer(updateTime){
            $scope.updating = true;
            var url = localStorage.getItem('ip')+'retailer/customer/modifyCustomer';
            var datapost = 'sessionID='+sID+
                '&uuid='+id+
                '&position='+custData.position+
                '&name='+custData.name+
                '&visitCount='+$scope.visitCount+
                '&mobile='+custData.mobile+
                '&detail='+(custData.detail||'')+
                '&state='+($scope.$parent.step-1)+
                '&isUpdate='+updateTime;
            $http({
                url:url,
                method:'POST',
                data:datapost,
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded;charset=gb2312'
                }
            }).success(function(data){
                if(data.result=='1'){
                    $scope.updating=false;
                }
                else alert('update cust state failed!');
            });
        }
        $scope.nextStep = function(){
            $scope.$parent.step++;
            if($scope.$parent.step=='2')
                $scope.visitCount = '1';
            updateServer(true);
        };
        $scope.prevStep = function(){
            $scope.$parent.step--;
            if($scope.$parent.step=='1')
                $scope.visitCount = '0';
            updateServer(false);
        };
        $scope.addCount = function(){
            if(+$scope.visitCount<=60)
                $scope.visitCount = +$scope.visitCount+1+'';
            updateServer(true);
        };
        $scope.cutCount = function(){
            if(+$scope.visitCount>1)
                $scope.visitCount = +$scope.visitCount-1+'';
            else if(+$scope.visitCount==1)
                $scope.prevStep();
            updateServer(false);
        };
    }]);<|endoftext|>


<commit_before>async function(args) {
/*
created_timestamp(-1)
base_component_id("homepage")
is_app(true)
display_name("Homepage app")
description('Homepage app')
uses_javascript_librararies(["aframe"])

load_once_from_file(true)
read_only(true)
logo_url("https://cdn0.tnwcdn.com/wp-content/blogs.dir/1/files/2017/05/Best-Homepages--796x563.jpg")
*/
    var introa = []//['homepage_1','homepage_2','homepage_3','homepage_4',
                   // 'homepage_5','homepage_6',"todo","form_subscribe_to_appshare","test"]
    await load("app_editor_3")
    var mm = null

    Vue.component('homepage', {

      template: `

Appshare

                                            Create a new app

                                           <button style='margin-bottom:10px;'  class='btn btn-primary' v-on:click='copyAndEditApp($event,"todo")'>Add database app</button>
                                           <button style='margin-bottom:10px;'  class='btn btn-primary' v-on:click='copyAndEditApp($event,"game")'>Add 3d AFrame app</button>
                                           <button style='margin-bottom:10px;' class='btn btn-primary' v-on:click='copyAndEditApp($event,"new_app")'>Text only</button>

Close

                                               <component v-if='' :is='"app_editor_3"' v-bind:app_id='item.data.id' v-bind:card_index='index'></component>

                                       {{item.data.id?"" + item.data.id.substring(0,20):""}}{{(item.data.id && ((item.data.id.length > 20))?"...":"")}}
                                       <component v-if='edit_app != item.data.id' :is='item.data.id'></component>

                                        {{item.data.id?"" + item.data.id.substring(0,20):""}}{{(item.data.id && ((item.data.id.length > 20))?"...":"")}}
                                        Editable
                                        Read only

                                      View source

                                        Edit

`
      ,

    data: function() {
        return {
                    apps: [],
                    intro_apps: [],
                    loaded_app: new Object(),
                    show_menu: null,
                    refresh: 0,
                    edit_app: null,
                    app_records: new Object(),
                    msnry: null
                }},

      mounted: async function() {
            mm = this

            this.msnry = new Masonry( mm.$refs.maingrid, {
              itemSelector: '.grid-item'
            });
            Vue.nextTick(() => {
                  this.msnry.reloadItems();
                  this.msnry.layout();
              });

           mm.addAdder()

           var sql =    "select  *  from  system_code  where " +
                        "        component_type = 'app' and base_component_id like 'homepage_%'" +
                        "        and code_tag = 'LATEST' order by base_component_id asc"

           var results = await callApp(
               {
                    driver_name:    "systemFunctions2",
                    method_name:    "sql"
               }
               ,
               {
                   sql: sql
               })
               for (var rt=0; rt < results.length; rt++) {
                   var appId = results[rt].base_component_id
                   mm.addAppFast(appId,-1, results[rt])
               }

                   //zzz
               mm.search()

            this.$root.$on('message', (text) => {
                if (text.type == "insert_app_at") {
                    console.log(JSON.stringify(text,null,2));
                    mm.intro_apps.splice(text.card_index, 0, {});
                    mm.addApp(text.base_component_id, text.card_index)
                    mm.edit_app = text.base_component_id
                    mm.refresh++
                }
            })
      },
      methods: {
          addAdder: async function() {
                  mm.intro_apps.push( {
                                        type: "add",
                                      } )
                mm.refresh++
              },
              addAppFast: async function(baseComponentId, cardIndex,vv) {
                  if (baseComponentId) {

                      var x = eval("(" + vv.code + ")")
                      x.call()
                      setTimeout(function() {
                          var app = {
                                                type: "app",
                                                data:
                                                    {
                                                        id: baseComponentId
                                                    }
                                              }
                          if (cardIndex != -1) {
                            mm.intro_apps[cardIndex] =  app

                          } else {
                            mm.intro_apps.push( app  )
                          }
                          mm.loaded_app[baseComponentId] = true
                          if (vv) {
                              mm.app_records[vv.base_component_id] = vv
                              mm.refresh++
                          }
                          setTimeout(function() {
                              mm.msnry.reloadItems();
                              mm.msnry.layout();
                          },50)
                      },100)

                  }
              },
            addApp: async function(baseComponentId, cardIndex) {
              if (baseComponentId) {
                  var app = {
                                        type: "app",
                                        data:
                                            {
                                                id: baseComponentId
                                            }
                                      }
                  if (cardIndex != -1) {
                    mm.intro_apps[cardIndex] =  app

                  } else {
                    mm.intro_apps.push( app  )
                  }
                  mm.loaded_app[baseComponentId] = true
                  var vv = await load(baseComponentId)
                  if (vv) {
                      mm.app_records[vv.base_component_id] = vv
                      mm.refresh++
                  }
                  setTimeout(function() {
                      mm.msnry.reloadItems();
                      mm.msnry.layout();
                  },50)
              }
          },
          copyApp: async function(  baseComponentId ) {
              callDriverMethod( {driver_name: "copyApp",
                                 method_name: "copyAppshareApp"}
                                ,{base_component_id:    baseComponentId}
                          ,
                          function(result) {
                              mm.intro_apps.splice(1, 0, {});
                              mm.addApp(result.value.base_component_id, 1)

                          })
          },
          copyAndEditApp: async function(event,  baseComponentId ) {
              callDriverMethod( {driver_name: "copyApp",
                                 method_name: "copyAppshareApp"}
                                ,{base_component_id:    baseComponentId}
                          ,
                          function(result) {
                              mm.intro_apps.splice(1, 0, {});
                              mm.addApp(result.value.base_component_id, 1)
                              setTimeout(function() {
                                    mm.editApp(event, result.value.base_component_id)
                              },50)

                          })
          },
          isEditable: function(baseComponentId) {
                if (this.app_records[baseComponentId]) {
                    if ((this.app_records[baseComponentId].read_write_status == null ) ||
                         (this.app_records[baseComponentId].read_write_status.indexOf("READ") == -1 ))   {
                         return true
                }

                }

               return false
          },
          isInlineApp: function(baseComponentId) {
                if (baseComponentId && (baseComponentId.length > 0)) {
                    if ((!this.isEditable(baseComponentId)) && (baseComponentId.startsWith("homepage"))) {
                        return true
                    }
                }

               return false
          },
          editApp: async function(event,item) {
              event.stopPropagation()
              this.show_menu = null;
              this.edit_app = item;
          },
          showMenu: async function(item) {
            this.show_menu= item;
          },

          search: async function() {
              var sql =    "SELECT  *  " +
                           " FROM system_code where component_type = 'app' and code_tag = 'LATEST' and " +
                           " visibility = 'PUBLIC' order by base_component_id asc; "

              var results = await callApp(
                  {
                       driver_name:    "systemFunctions2",
                       method_name:    "sql"
                  }
                  ,
                  {
                      sql: sql
                  })
              for (var rt=0; rt < results.length; rt++) {
                  var appId = results[rt].base_component_id
                  if (!mm.loaded_app[  appId  ]) {
                        mm.addAppFast(appId,-1, results[rt])
                  }
              }
              }

      }
    })

}
<commit_msg>Make a VB app the default when making a new app<commit_after>async function(args) {
/*
created_timestamp(-1)
base_component_id("homepage")
is_app(true)
display_name("Homepage app")
description('Homepage app')
uses_javascript_librararies(["aframe"])

load_once_from_file(true)
read_only(true)
logo_url("https://cdn0.tnwcdn.com/wp-content/blogs.dir/1/files/2017/05/Best-Homepages--796x563.jpg")
*/
    var introa = []//['homepage_1','homepage_2','homepage_3','homepage_4',
                   // 'homepage_5','homepage_6',"todo","form_subscribe_to_appshare","test"]
    await load("app_editor_3")
    var mm = null

    Vue.component('homepage', {

      template: `

Appshare

                                            Create a new app

                                           <select v-model="app_type">
                                              <option selected value="homepage_5">Visual Builder 6</option>
                                              <option          value="todo">Database app</option>
                                              <option          value="game">3d AFrame app</option>
                                              <option          value="new_app">Text only</option>
                                            </select>
                                           <button style='margin-bottom:10px;' class='btn btn-primary' v-on:click='copyAndEditApp($event,app_type)'>Go</button>

Close

                                               <component v-if='' :is='"app_editor_3"' v-bind:app_id='item.data.id' v-bind:card_index='index'></component>

                                       {{item.data.id?"" + item.data.id.substring(0,20):""}}{{(item.data.id && ((item.data.id.length > 20))?"...":"")}}
                                       <component v-if='edit_app != item.data.id' :is='item.data.id'></component>

                                        {{item.data.id?"" + item.data.id.substring(0,20):""}}{{(item.data.id && ((item.data.id.length > 20))?"...":"")}}
                                        Editable
                                        Read only

                                      View source

                                        Edit

`
      ,

    data: function() {
        return {
                    apps: [],
                    app_type: "homepage_5",
                    intro_apps: [],
                    loaded_app: new Object(),
                    show_menu: null,
                    refresh: 0,
                    edit_app: null,
                    app_records: new Object(),
                    msnry: null
                }},

      mounted: async function() {
            mm = this

            this.msnry = new Masonry( mm.$refs.maingrid, {
              itemSelector: '.grid-item'
            });
            Vue.nextTick(() => {
                  this.msnry.reloadItems();
                  this.msnry.layout();
              });

           mm.addAdder()

           var sql =    "select  *  from  system_code  where " +
                        "        component_type = 'app' and base_component_id like 'homepage_%'" +
                        "        and code_tag = 'LATEST' order by base_component_id asc"

           var results = await callApp(
               {
                    driver_name:    "systemFunctions2",
                    method_name:    "sql"
               }
               ,
               {
                   sql: sql
               })
               for (var rt=0; rt < results.length; rt++) {
                   var appId = results[rt].base_component_id
                   mm.addAppFast(appId,-1, results[rt])
               }

                   //zzz
               mm.search()

            this.$root.$on('message', (text) => {
                if (text.type == "insert_app_at") {
                    console.log(JSON.stringify(text,null,2));
                    mm.intro_apps.splice(text.card_index, 0, {});
                    mm.addApp(text.base_component_id, text.card_index)
                    mm.edit_app = text.base_component_id
                    mm.refresh++
                }
            })
      },
      methods: {
          addAdder: async function() {
                  mm.intro_apps.push( {
                                        type: "add",
                                      } )
                mm.refresh++
              },
              addAppFast: async function(baseComponentId, cardIndex,vv) {
                  if (baseComponentId) {

                      var x = eval("(" + vv.code + ")")
                      x.call()
                      setTimeout(function() {
                          var app = {
                                                type: "app",
                                                data:
                                                    {
                                                        id: baseComponentId
                                                    }
                                              }
                          if (cardIndex != -1) {
                            mm.intro_apps[cardIndex] =  app

                          } else {
                            mm.intro_apps.push( app  )
                          }
                          mm.loaded_app[baseComponentId] = true
                          if (vv) {
                              mm.app_records[vv.base_component_id] = vv
                              mm.refresh++
                          }
                          setTimeout(function() {
                              mm.msnry.reloadItems();
                              mm.msnry.layout();
                          },50)
                      },100)

                  }
              },
            addApp: async function(baseComponentId, cardIndex) {
              if (baseComponentId) {
                  var app = {
                                        type: "app",
                                        data:
                                            {
                                                id: baseComponentId
                                            }
                                      }
                  if (cardIndex != -1) {
                    mm.intro_apps[cardIndex] =  app

                  } else {
                    mm.intro_apps.push( app  )
                  }
                  mm.loaded_app[baseComponentId] = true
                  var vv = await load(baseComponentId)
                  if (vv) {
                      mm.app_records[vv.base_component_id] = vv
                      mm.refresh++
                  }
                  setTimeout(function() {
                      mm.msnry.reloadItems();
                      mm.msnry.layout();
                  },50)
              }
          },
          copyApp: async function(  baseComponentId ) {
              callDriverMethod( {driver_name: "copyApp",
                                 method_name: "copyAppshareApp"}
                                ,{base_component_id:    baseComponentId}
                          ,
                          function(result) {
                              mm.intro_apps.splice(1, 0, {});
                              mm.addApp(result.value.base_component_id, 1)

                          })
          },
          copyAndEditApp: async function(event,  baseComponentId ) {
              callDriverMethod( {driver_name: "copyApp",
                                 method_name: "copyAppshareApp"}
                                ,{base_component_id:    baseComponentId}
                          ,
                          function(result) {
                              mm.intro_apps.splice(1, 0, {});
                              mm.addApp(result.value.base_component_id, 1)
                              setTimeout(function() {
                                    mm.editApp(event, result.value.base_component_id)
                              },50)

                          })
          },
          isEditable: function(baseComponentId) {
                if (this.app_records[baseComponentId]) {
                    if ((this.app_records[baseComponentId].read_write_status == null ) ||
                         (this.app_records[baseComponentId].read_write_status.indexOf("READ") == -1 ))   {
                         return true
                }

                }

               return false
          },
          isInlineApp: function(baseComponentId) {
                if (baseComponentId && (baseComponentId.length > 0)) {
                    if ((!this.isEditable(baseComponentId)) && (baseComponentId.startsWith("homepage"))) {
                        return true
                    }
                }

               return false
          },
          editApp: async function(event,item) {
              event.stopPropagation()
              this.show_menu = null;
              this.edit_app = item;
          },
          showMenu: async function(item) {
            this.show_menu= item;
          },

          search: async function() {
              var sql =    "SELECT  *  " +
                           " FROM system_code where component_type = 'app' and code_tag = 'LATEST' and " +
                           " visibility = 'PUBLIC' order by base_component_id asc; "

              var results = await callApp(
                  {
                       driver_name:    "systemFunctions2",
                       method_name:    "sql"
                  }
                  ,
                  {
                      sql: sql
                  })
              for (var rt=0; rt < results.length; rt++) {
                  var appId = results[rt].base_component_id
                  if (!mm.loaded_app[  appId  ]) {
                        mm.addAppFast(appId,-1, results[rt])
                  }
              }
              }

      }
    })

}
<|endoftext|>


<commit_before><commit_msg>More cleanup<commit_after><|endoftext|>


<commit_before><commit_msg>updated delete message<commit_after><|endoftext|>


<commit_before>const slide = document.getElementById('slide')
  , sequence = [
    'start', 'purpose', 'me', 'us',
    'research', 'values', 'discuss'
  ]

let index = 0

function slideDirection (key) {
  switch (key) {
    case 'ArrowLeft':
    case 'ArrowDown':
      return --index; break
    case 'ArrowRight':
    case 'ArrowUp':
      return ++index; break
    default:
      return index;
  }
}

document.onkeydown = function(event) {
  slide.className = sequence[slideDirection(event.key)] || sequence[sequence.length - 1]
};
<commit_msg>makes it easier to change order of slides (for testing/dev) and adds in the new in10 slides<commit_after>const slide = document.getElementById('slide')
  , sequence = [
    'start',
    'purpose',
    'research',
    'me',
    'us',
    'in10',
    'in10edu',
    'in10exp',
    'values',
    'discuss',
  ]

slide.className = sequence[0]
var index = 0

function slideDirection (key) {
  switch (key) {
    case 'ArrowLeft':
    case 'ArrowDown':
      return --index; break
    case 'ArrowRight':
    case 'ArrowUp':
      return ++index; break
    default:
      return index;
  }
}

document.onkeydown = function(event) {
  slide.className = sequence[slideDirection(event.key)] || sequence[sequence.length - 1]
};
<|endoftext|>


<commit_before>if (typeof DUOSHUO !== 'undefined') hookDUOSHUO_tp();
else $('[src="http://static.duoshuo.com/embed.js"]')[0].onload = hookDUOSHUO_tp;

function hookDUOSHUO_tp() {
    var _D_post = DUOSHUO.templates.post
    DUOSHUO.templates.post = function (e, t) {
        var rs = _D_post(e, t);
        var agent = e.post.agent;
        var isAdmin;
        if (typeof duoshuo_user_ID !== 'undefined') {
            if (e.post.author.user_id && (e.post.author.user_id == duoshuo_user_ID)) {
                if (duoshuo_admin_nickname) {
                    isAdmin = '' + duoshuo_admin_nickname + '';
                } else {
                    isAdmin = '博主';
                }
            } else {
                isAdmin = '';
            }
        } else {
            isAdmin = '';
        }
        if (agent && /^Mozilla/.test(agent)) rs = rs.replace(/<\/div>
/, isAdmin + showUa(agent) + '

');
        return rs;
    }
}
//移动客户端判断
function checkMobile() {
    var isiPad = navigator.userAgent.match(/iPad/i) !== null;
    if (isiPad) {
        return false;
    }
    var isMobile = navigator.userAgent.match(/iphone|android|phone|mobile|wap|netfront|x11|java|opera mobi|opera mini|ucweb|windows ce|symbian|symbianos|series|webos|sony|blackberry|dopod|nokia|samsung|palmsource|xda|pieplus|meizu|midp|cldc|motorola|foma|docomo|up.browser|up.link|blazer|helio|hosin|huawei|novarra|coolpad|webos|techfaith|palmsource|alcatel|amoi|ktouch|nexian|ericsson|philips|sagem|wellcom|bunjalloo|maui|smartphone|iemobile|spice|bird|zte-|longcos|pantech|gionee|portalmmm|jig browser|hiptop|benq|haier|^lct|320x320|240x320|176x220/i) != null;
    if (isMobile) {
        return true;
    }
    return false;
}

function showUa(string) {
    $.ua.set(string);
    var sua = $.ua;
    var br = '  ';
    var osIco = ' ';
    var browserIco = ' '
    var osName = sua.os.name;
    var browserName = sua.browser.name;
    if (checkMobile()) br = '

';

    if (osName == 'Android') osIco = ' ';
    if (osName.match(/linux/i)) osIco = ' ';
    if (osName.match(/mac os|ios/i)) osIco = ' ';
    if (sua.os.version == 'x86_64') sua.os.version = 'x64';

    if (browserName.match(/chrome|chromium/i)) browserIco = ' ';
    if (browserName.match(/firefox/i)) browserIco = ' ';
    if (browserName.match(/opera/i)) browserIco = ' ';
    if (browserName.match(/safari/i)) browserIco = ' ';
    if (browserName.match(/ie/i)) browserIco = ' ';

    return br + '' + osIco +
        sua.os.name + ' ' + sua.os.version + '' + br +
        '' + browserIco +
        sua.browser.name + '|' + sua.browser.version + '';
}
<commit_msg>同pull request #443<commit_after>if (typeof DUOSHUO !== 'undefined') hookDUOSHUO_tp();
else $('#duoshuo-script')[0].onload = hookDUOSHUO_tp;

function hookDUOSHUO_tp() {
    var _D_post = DUOSHUO.templates.post
    DUOSHUO.templates.post = function (e, t) {
        var rs = _D_post(e, t);
        var agent = e.post.agent;
        var isAdmin;
        if (typeof duoshuo_user_ID !== 'undefined') {
            if (e.post.author.user_id && (e.post.author.user_id == duoshuo_user_ID)) {
                if (duoshuo_admin_nickname) {
                    isAdmin = '' + duoshuo_admin_nickname + '';
                } else {
                    isAdmin = '博主';
                }
            } else {
                isAdmin = '';
            }
        } else {
            isAdmin = '';
        }
        if (agent && /^Mozilla/.test(agent)) rs = rs.replace(/<\/div>
/, isAdmin + showUa(agent) + '

');
        return rs;
    }
}
//移动客户端判断
function checkMobile() {
    var isiPad = navigator.userAgent.match(/iPad/i) !== null;
    if (isiPad) {
        return false;
    }
    var isMobile = navigator.userAgent.match(/iphone|android|phone|mobile|wap|netfront|x11|java|opera mobi|opera mini|ucweb|windows ce|symbian|symbianos|series|webos|sony|blackberry|dopod|nokia|samsung|palmsource|xda|pieplus|meizu|midp|cldc|motorola|foma|docomo|up.browser|up.link|blazer|helio|hosin|huawei|novarra|coolpad|webos|techfaith|palmsource|alcatel|amoi|ktouch|nexian|ericsson|philips|sagem|wellcom|bunjalloo|maui|smartphone|iemobile|spice|bird|zte-|longcos|pantech|gionee|portalmmm|jig browser|hiptop|benq|haier|^lct|320x320|240x320|176x220/i) != null;
    if (isMobile) {
        return true;
    }
    return false;
}

function showUa(string) {
    $.ua.set(string);
    var sua = $.ua;
    var br = '  ';
    var osIco = ' ';
    var browserIco = ' '
    var osName = sua.os.name;
    var browserName = sua.browser.name;
    if (checkMobile()) br = '

';

    if (osName == 'Android') osIco = ' ';
    if (osName.match(/linux/i)) osIco = ' ';
    if (osName.match(/mac os|ios/i)) osIco = ' ';
    if (sua.os.version == 'x86_64') sua.os.version = 'x64';

    if (browserName.match(/chrome|chromium/i)) browserIco = ' ';
    if (browserName.match(/firefox/i)) browserIco = ' ';
    if (browserName.match(/opera/i)) browserIco = ' ';
    if (browserName.match(/safari/i)) browserIco = ' ';
    if (browserName.match(/ie/i)) browserIco = ' ';

    return br + '' + osIco +
        sua.os.name + ' ' + sua.os.version + '' + br +
        '' + browserIco +
        sua.browser.name + '|' + sua.browser.version + '';
}
<|endoftext|>


<commit_before>var  app = angular.module('NightOwl', []).constant( 'API_CONFIG',{

	"API_URL":"http://nightowl.local",

	"loadingID" : "#loading",

	"installation": {
		"name" : "production",
		"colour" : "red"
	},

	"restrictions" : [
		"boolean",
		"member_list",
		"memberID",
		"percent"
	],

	"filters" : [
		"All",
		"Key",
		"Value",
		"Date",
		"Owner",
		"Description"
	],

	"defaultFilters" : {
		"prefix" : "darklaunch",
		"dataCenter" : "dc1",
		"filterBy" : "All",
		"filter" : ""
	},

	"metadata" : {
		"restrictions":{
			"boolean":{"type":"select", "values":["true","false"]},
			"member_list":{"type":"text", "placeholder":"comma seperated list"},
			"memberID":{"type":"text"},
			"percent":{"type":"text", "placeholder":"between 0 and 100"}
		}
	},

	"dataCenters": [
		{
			"name": "Data Center 1",
			"value" : "dc1",
			"prefixes":{
				"darklaunch" : {
					"dashboard": {
						"core" : {},

						"api":{
							"1":{
								"ANDROID" : {},
								"APPLE" : {}
							},

							"2":{
								"ANDROID" : {},
								"APPLE" : {}
							}
						},

						"apiold":{}
					},

					"service":{
						"social-communication" : {}
					}
				}
			},
		},
		{"name": "Data Center 2", "value" : "dc2"},
		{"name": "Data Center 3", "value" : "dc3"}
	],

	"tokenName": "NightOwlAuth",

	"auditFilters" : [
        "Last 24 Hours",
        "All",
        "User",
        "Code",
        "Message"
    ]
});
<commit_msg>Replaced nightowl.local with 127.0.0.1<commit_after>var  app = angular.module('NightOwl', []).constant( 'API_CONFIG',{

	"API_URL":"http://127.0.0.1",

	"loadingID" : "#loading",

	"installation": {
		"name" : "production",
		"colour" : "red"
	},

	"restrictions" : [
		"boolean",
		"member_list",
		"memberID",
		"percent"
	],

	"filters" : [
		"All",
		"Key",
		"Value",
		"Date",
		"Owner",
		"Description"
	],

	"defaultFilters" : {
		"prefix" : "darklaunch",
		"dataCenter" : "dc1",
		"filterBy" : "All",
		"filter" : ""
	},

	"metadata" : {
		"restrictions":{
			"boolean":{"type":"select", "values":["true","false"]},
			"member_list":{"type":"text", "placeholder":"comma seperated list"},
			"memberID":{"type":"text"},
			"percent":{"type":"text", "placeholder":"between 0 and 100"}
		}
	},

	"dataCenters": [
		{
			"name": "Data Center 1",
			"value" : "dc1",
			"prefixes":{
				"darklaunch" : {
					"dashboard": {
						"core" : {},

						"api":{
							"1":{
								"ANDROID" : {},
								"APPLE" : {}
							},

							"2":{
								"ANDROID" : {},
								"APPLE" : {}
							}
						},

						"apiold":{}
					},

					"service":{
						"social-communication" : {}
					}
				}
			},
		},
		{"name": "Data Center 2", "value" : "dc2"},
		{"name": "Data Center 3", "value" : "dc3"}
	],

	"tokenName": "NightOwlAuth",

	"auditFilters" : [
        "Last 24 Hours",
        "All",
        "User",
        "Code",
        "Message"
    ]
});
<|endoftext|>


<commit_before>/**
 * Copyright 2017, Google, Inc.
 * Licensed under the Apache License, Version 2.0 (the "License")
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

'use strict';

require('colors');

exports.call = [
  ['functions call helloWorld', 'Invokes the helloWorld function with no data.'],
  [`functions call helloWorld --data='{"foo":"bar"}'`, 'LINUX/MAC: Invokes the helloWorld function, passing it inline JSON.'],
  [`functions call helloWorld --data={\"foo\":\"bar\"}`, 'WINDOWS: Invokes the helloWorld function, passing it inline JSON.'],
  ['functions call helloWorld --file=/path/to/datafile.json', 'Invokes the helloWorld function, passing it a path to a JSON file.'],
  ['functions call helloWorld --service=grpc', 'Invokes the helloWorld function, using gRPC to make the request.']
];

exports.clear = [];

exports['config.defaults'] = [
  ['functions config defaults', 'Prints the default settings.'],
  ['functions config defaults --json', 'Prints the default settings as JSON.']
];

exports['config.list'] = [
  ['functions config list', 'Prints the current settings.'],
  ['functions config list --json', 'Prints the current settings as JSON.']
];

exports['config.set'] = [
  ['functions config set projectId my-project', `Sets ${'projectId'.bold} to ${'my-project'.bold}.`]
];

exports.debug = [];

exports.delete = [
  ['functions delete helloWorld']
];

exports.deploy = [
  ['cd /path/to/src; functions deploy helloWorld --trigger-http'],
  ['functions deploy helloWorld --local-path=/path/to/src --trigger-http'],
  ['functions deploy testHelloWorld -l=/path/to/src --entry-point=helloWorld --trigger-http'],
  ['cd /path/to/src; functions deploy helloGCS --trigger-bucket=my-bucket'],
  ['functions deploy helloPubSub -l=/path/to/src --trigger-topic=my-topic']
];

exports.describe = [
  ['functions describe helloWorld']
];

exports['event-types.list'] = [];

exports.inspect = [];

exports.reset = [
  ['functions reset helloWorld', `Reset the helloWorld function's worker process.`],
  ['functions reset helloWorld --keep', `Reset the helloWorld function's worker process, but keep its debugging settings, if any.`]
];

exports.restart = [];

exports.start = [];

exports.status = [];

exports.stop = [];

exports['logs.read'] = [
  ['functions logs read --limit=10', 'Display the most recent 10 lines from the logs']
];

exports['logs.clear'] = [];

exports.config = exports['config.list'].concat(exports['config.set']);
exports['event-types'] = exports['event-types.list'];
exports.logs = exports['logs.read'];
<commit_msg>Make lint happy<commit_after>/**
 * Copyright 2017, Google, Inc.
 * Licensed under the Apache License, Version 2.0 (the "License")
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

'use strict';

require('colors');

exports.call = [
  ['functions call helloWorld', 'Invokes the helloWorld function with no data.'],
  [`functions call helloWorld --data='{"foo":"bar"}'`, 'LINUX/MAC: Invokes the helloWorld function, passing it inline JSON.'],
  [`functions call helloWorld --data={\"foo\":\"bar\"}`, 'WINDOWS: Invokes the helloWorld function, passing it inline JSON.'], // eslint-disable-line
  ['functions call helloWorld --file=/path/to/datafile.json', 'Invokes the helloWorld function, passing it a path to a JSON file.'],
  ['functions call helloWorld --service=grpc', 'Invokes the helloWorld function, using gRPC to make the request.']
];

exports.clear = [];

exports['config.defaults'] = [
  ['functions config defaults', 'Prints the default settings.'],
  ['functions config defaults --json', 'Prints the default settings as JSON.']
];

exports['config.list'] = [
  ['functions config list', 'Prints the current settings.'],
  ['functions config list --json', 'Prints the current settings as JSON.']
];

exports['config.set'] = [
  ['functions config set projectId my-project', `Sets ${'projectId'.bold} to ${'my-project'.bold}.`]
];

exports.debug = [];

exports.delete = [
  ['functions delete helloWorld']
];

exports.deploy = [
  ['cd /path/to/src; functions deploy helloWorld --trigger-http'],
  ['functions deploy helloWorld --local-path=/path/to/src --trigger-http'],
  ['functions deploy testHelloWorld -l=/path/to/src --entry-point=helloWorld --trigger-http'],
  ['cd /path/to/src; functions deploy helloGCS --trigger-bucket=my-bucket'],
  ['functions deploy helloPubSub -l=/path/to/src --trigger-topic=my-topic']
];

exports.describe = [
  ['functions describe helloWorld']
];

exports['event-types.list'] = [];

exports.inspect = [];

exports.reset = [
  ['functions reset helloWorld', `Reset the helloWorld function's worker process.`],
  ['functions reset helloWorld --keep', `Reset the helloWorld function's worker process, but keep its debugging settings, if any.`]
];

exports.restart = [];

exports.start = [];

exports.status = [];

exports.stop = [];

exports['logs.read'] = [
  ['functions logs read --limit=10', 'Display the most recent 10 lines from the logs']
];

exports['logs.clear'] = [];

exports.config = exports['config.list'].concat(exports['config.set']);
exports['event-types'] = exports['event-types.list'];
exports.logs = exports['logs.read'];
<|endoftext|>


<commit_before><commit_msg>Update Pool_Base.js<commit_after><|endoftext|>


<commit_before>import React from 'react'
import { render } from 'react-dom'
import { Provider } from 'react-redux'
import { ConnectedRouter } from 'connected-react-router'

import store, { history } from './store'
import App from './containers/App'

if (module.hot) {
  module.hot.accept()
}

render(
  <Provider store={store}>
    <ConnectedRouter history={history}>
      <App/>
    </ConnectedRouter>
  </Provider>,
  document.querySelector('#app')
)
<commit_msg>another test commit<commit_after>import React from 'react'
import { render } from 'react-dom'
import { Provider } from 'react-redux'
import { ConnectedRouter } from 'connected-react-router'

import store, { history } from './store'
import App from './containers/App'

if (module.hot) {
  module.hot.accept()
}

render(
  <Provider store={store}>
    <ConnectedRouter history={history}>
      <App/>
    </ConnectedRouter>
  </Provider>,
  document.querySelector('#app')
)

<|endoftext|>


<commit_before>'use strict';
window.__REACT_DEVTOOLS_GLOBAL_HOOK__ = {};

const App = require('./components/app.js');
const React = require('react');
const ReactDom = require('react-dom');
const activeStore = require('./store/activeStore.js');
const alertStore = require('./store/alertStore.js');
const call = require('./call.js');
const debug = require('debug')('peer-calls:index');
const notificationsStore = require('./store/notificationsStore.js');
const play = require('./browser/video.js').play;
const streamStore = require('./store/streamStore.js');

function render() {
  debug('rendering');
  ReactDom.render(<App />, document.querySelector('#container'));
  play();
}

activeStore.addListener(render);
alertStore.addListener(render);
notificationsStore.addListener(render);
streamStore.addListener(render);

render();

call.init();
<commit_msg>Fix broken app for clients with react dev tools extension<commit_after>'use strict';
if (!window.__REACT_DEVTOOLS_GLOBAL_HOOK__) {
  window.__REACT_DEVTOOLS_GLOBAL_HOOK__ = {};
}

const App = require('./components/app.js');
const React = require('react');
const ReactDom = require('react-dom');
const activeStore = require('./store/activeStore.js');
const alertStore = require('./store/alertStore.js');
const call = require('./call.js');
const debug = require('debug')('peer-calls:index');
const notificationsStore = require('./store/notificationsStore.js');
const play = require('./browser/video.js').play;
const streamStore = require('./store/streamStore.js');

function render() {
  debug('rendering');
  ReactDom.render(<App />, document.querySelector('#container'));
  play();
}

activeStore.addListener(render);
alertStore.addListener(render);
notificationsStore.addListener(render);
streamStore.addListener(render);

render();

call.init();
<|endoftext|>


<commit_before><commit_msg>added some comments; changed success message to always fire and added a timestamp<commit_after><|endoftext|>


<commit_before>/*
	Copyright (C) 2018 Claude SIMON (http://q37.info/contact/).

	This file is part of XDHq.

	XDHq is free software: you can redistribute it and/or
	modify it under the terms of the GNU Affero General Public License as
	published by the Free Software Foundation, either version 3 of the
	License, or (at your option) any later version.

	XDHq is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
	Affero General Public License for more details.

	You should have received a copy of the GNU Affero General Public License
	along with XDHq If not, see <http://www.gnu.org/licenses/>.
*/

/*
This is the Node.js Atlas (http://atlastk/) version
of the TodoMVC application (http://todomvc.com/).
*/

"use strict"

var atlasId = "";

if (process.env.EPEIOS_SRC) {
	let epeiosPath = "";

	if (process.platform == 'win32')
		epeiosPath = "h:/hg/epeios/"
	else
		epeiosPath = "~/hg/epeios/"

	atlasId = epeiosPath + "tools/xdhq/Atlas/NJS/Atlas.js";
} else {
	atlasId = 'atlastk';
}

const atlas = require(atlasId);
const Tree = atlas.Tree;
const DOM = atlas.DOM;
const readAsset = atlas.readAsset;

class MyData extends DOM {
	constructor() {
		super();
		this.timestamp = new Date();
		this.exclude = null;
		this.index = -1;
		this.todos = [
			{
				"completed": true,
				"label": "Note 1"
			}, {
				"completed": false,
				"label": "Note 2"
			}
		];
		 this.todos = [];
	}
	itemsLeft() {
		var i = this.todos.length;
		var count = 0;

		while (i--) {
			if (!this.todos[i]['completed'])
				count++;
		}

		return count;
	}
}

function displayCount(dom, count) {
	var text = "";

	switch (count) {
		case 0:
			break;
		case 1:
			text = "1 item left";
			break;
		default:
			text = count + " items left";
			break;
	}

	dom.setContent("Count", text);
}

function handleCount(dom) {
	var count = dom.itemsLeft();

	if (count != dom.todos.length)
		dom.disableElement("HideClearCompleted",
			() => displayCount(dom, count)
		)
	else
		dom.enableElement("HideClearCompleted",
			() => displayCount(dom, count)
		)
}

function displayTodos(dom) {
	var tree = atlas.createTree();
	var i = 0;
	var todo;

	dom.index = -1;

	tree = tree.ele("Todos");

	while (i < dom.todos.length) {
		todo = dom.todos[i];
		if (dom.exclude === null || (todo['completed'] != dom.exclude))
				tree = tree.ele('Todo', { 'id': i, 'completed' : todo["completed"] }, todo["label"] ).up();
		i++;
	}

	tree = tree.up();

	dom.setLayoutXSL("Todos", tree, "Todos.xsl",
		() => handleCount(dom)
	);
}

function newSession() {
	console.log("New session detected !");

	return new MyData();
}

var head = "";

function acConnect(dom, id) {
	dom.headUp( readAsset( head ),
		() => dom.setLayout("", readAsset( "Main.html"),
			() => dom.focus("Input",
				() => dom.disableElements(["HideActive", "HideCompleted"],
					() => displayTodos(dom)
				)
			)
		)
	);
}

function submitNew(dom) {
	dom.getContent("Input",
		(content) => dom.setContent("Input", "",
			() => {
				if (content.trim() != "") {
					dom.todos.unshift(
						{
							"completed": false,
							"label": content
						}
					);
					displayTodos(dom);
				}
			}
		)
	);
}

function submitModification(dom) {
	let id = dom.index;
	dom.index = -1;

	dom.getContent("Input." + id,
		(content) => dom.setContent("Input." + id, "",
			() => {
				if (content.trim() != "") {
					dom.todos[id]['label'] = content;
					dom.setContent("Label." + id, content,
						() => dom.removeClasses(
							{
								["View." + id]: "hide",
								["Todo." + id]: "editing"
							}
						)
					);
				} else {
					dom.todos.splice(id, 1);
					displayTodos(dom);
				}
			}
		)
	);
}

function acSubmit(dom, id) {
	if (dom.index == -1) {
		submitNew(dom);
	} else {
		submitModification(dom);
	}
}

function acDestroy(dom, id) {
	dom.getContent(id,
		(content) => {
			dom.todos.splice(parseInt(content), 1);
			displayTodos(dom);
		}
	);
}

function acToggle(dom, id) {
	var i = parseInt(id);

	dom.todos[i]['completed'] = !dom.todos[i]['completed'];

	// Can't use 'ToggleClasses', because then 2 elements would have same key...
	dom.toggleClass("Todo." + id, "completed",
		() => dom.toggleClass( "Todo." + id, "active",
			() => {
				if (dom.exclude == null)
					handleCount(dom);
			}
		)
	);
}

function acAll(dom, id) {
	dom.exclude = null;

	dom.addClass("All", "selected",
		() => dom.removeClasses(
			{
				"Active": "selected",
				"Completed": "selected"
			},
			() => dom.disableElements( ["HideActive", "HideCompleted"] )
		)
	)
}

function acActive(dom, id) {
	dom.exclude = true;

	dom.addClass("Active", "selected",
		() => dom.removeClasses(
			{
				"All": "selected",
				"Completed": "selected"
			},
			() => dom.disableElement( "HideActive",
				() => dom.enableElement( "HideCompleted") )
		)
	)
}

function acCompleted(dom, id) {
	dom.exclude = false;

	dom.addClass("Completed", "selected",
		() => dom.removeClasses(
			{
				"All": "selected",
				"Active": "selected"
			},
			() => dom.disableElement("HideCompleted",
				() =>dom.enableElement("HideActive"))
		)
	)
}

function acClear(dom, id) {
	var i = 0;

	while (i < dom.todos.length) {
		if (dom.todos[i]['completed'])
			dom.todos.splice(i, 1);
		else
			i++;
	}

	displayTodos(dom);
}

function acEdit(dom, id) {
	dom.getContent(id,
		(content) => dom.addClasses(
			{
				["View." + content]: "hide",
				[id]: "editing"
			},
			() => {
				dom.index = parseInt(content);
				dom.setContent("Input." + content, dom.todos[dom.index]['label'],
					() => dom.focus("Input." + content))
			}
		)
	);
}

function acCancel(dom, id) {
	var id = dom.index;
	dom.index = -1;

	dom.setContent("Input." + id, "",
		() => dom.removeClasses(
			{
				["View." + id]: "hide",
				["Todo." + id]: "editing"
			}
		)
	);
}

function main() {
	var callbacks =	{
		"Connect": acConnect,
		"Submit": acSubmit,
		"Destroy": acDestroy,
		"Toggle": acToggle,
		"All": acAll,
		"Active": acActive,
		"Completed": acCompleted,
		"Clear": acClear,
		"Edit": acEdit,
		"Cancel": acCancel,
	};

	atlas.launch(newSession, "Connect", callbacks);

	switch (atlas.mode) {
		case atlas.modes.PROD:
			head = "HeadPROD.html";
			break;
		case atlas.modes.DEMO:
			head = "HeadDEMO.html";
			break;
		default:
			throw "Unknown mode !!!";
			break;
	}
}

main();
<commit_msg>24/07/2018 06:20:43<commit_after>/*
	Copyright (C) 2018 Claude SIMON (http://q37.info/contact/).

	This file is part of XDHq.

	XDHq is free software: you can redistribute it and/or
	modify it under the terms of the GNU Affero General Public License as
	published by the Free Software Foundation, either version 3 of the
	License, or (at your option) any later version.

	XDHq is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
	Affero General Public License for more details.

	You should have received a copy of the GNU Affero General Public License
	along with XDHq If not, see <http://www.gnu.org/licenses/>.
*/

/*
This is the Node.js Atlas (http://atlastk/) version
of the TodoMVC application (http://todomvc.com/).
*/

"use strict"

var atlasId = "";

if (process.env.EPEIOS_SRC) {
	let epeiosPath = "";

	if (process.platform == 'win32')
		epeiosPath = "h:/hg/epeios/"
	else
		epeiosPath = "~/hg/epeios/"

	atlasId = epeiosPath + "tools/xdhq/Atlas/NJS/Atlas.js";
} else {
	atlasId = 'atlastk';
}

const atlas = require(atlasId);
const DOM = atlas.DOM;
const readAsset = atlas.readAsset;

class MyData extends DOM {
	constructor() {
		super();
		this.timestamp = new Date();
		this.exclude = null;
		this.index = -1;
		this.todos = [
			{
				"completed": true,
				"label": "Note 1"
			}, {
				"completed": false,
				"label": "Note 2"
			}
		];
		 this.todos = [];
	}
	itemsLeft() {
		var i = this.todos.length;
		var count = 0;

		while (i--) {
			if (!this.todos[i]['completed'])
				count++;
		}

		return count;
	}
}

function displayCount(dom, count) {
	var text = "";

	switch (count) {
		case 0:
			break;
		case 1:
			text = "1 item left";
			break;
		default:
			text = count + " items left";
			break;
	}

	dom.setContent("Count", text);
}

function handleCount(dom) {
	var count = dom.itemsLeft();

	if (count != dom.todos.length)
		dom.disableElement("HideClearCompleted",
			() => displayCount(dom, count)
		)
	else
		dom.enableElement("HideClearCompleted",
			() => displayCount(dom, count)
		)
}

function displayTodos(dom) {
	var tree = atlas.createTree();
	var i = 0;
	var todo;

	dom.index = -1;

	tree = tree.ele("Todos");

	while (i < dom.todos.length) {
		todo = dom.todos[i];
		if (dom.exclude === null || (todo['completed'] != dom.exclude))
				tree = tree.ele('Todo', { 'id': i, 'completed' : todo["completed"] }, todo["label"] ).up();
		i++;
	}

	tree = tree.up();

	dom.setLayoutXSL("Todos", tree, "Todos.xsl",
		() => handleCount(dom)
	);
}

function newSession() {
	console.log("New session detected !");

	return new MyData();
}

var head = "";

function acConnect(dom, id) {
	dom.headUp( readAsset( head ),
		() => dom.setLayout("", readAsset( "Main.html"),
			() => dom.focus("Input",
				() => dom.disableElements(["HideActive", "HideCompleted"],
					() => displayTodos(dom)
				)
			)
		)
	);
}

function submitNew(dom) {
	dom.getContent("Input",
		(content) => dom.setContent("Input", "",
			() => {
				if (content.trim() != "") {
					dom.todos.unshift(
						{
							"completed": false,
							"label": content
						}
					);
					displayTodos(dom);
				}
			}
		)
	);
}

function submitModification(dom) {
	let id = dom.index;
	dom.index = -1;

	dom.getContent("Input." + id,
		(content) => dom.setContent("Input." + id, "",
			() => {
				if (content.trim() != "") {
					dom.todos[id]['label'] = content;
					dom.setContent("Label." + id, content,
						() => dom.removeClasses(
							{
								["View." + id]: "hide",
								["Todo." + id]: "editing"
							}
						)
					);
				} else {
					dom.todos.splice(id, 1);
					displayTodos(dom);
				}
			}
		)
	);
}

function acSubmit(dom, id) {
	if (dom.index == -1) {
		submitNew(dom);
	} else {
		submitModification(dom);
	}
}

function acDestroy(dom, id) {
	dom.getContent(id,
		(content) => {
			dom.todos.splice(parseInt(content), 1);
			displayTodos(dom);
		}
	);
}

function acToggle(dom, id) {
	var i = parseInt(id);

	dom.todos[i]['completed'] = !dom.todos[i]['completed'];

	// Can't use 'ToggleClasses', because then 2 elements would have same key...
	dom.toggleClass("Todo." + id, "completed",
		() => dom.toggleClass( "Todo." + id, "active",
			() => {
				if (dom.exclude == null)
					handleCount(dom);
			}
		)
	);
}

function acAll(dom, id) {
	dom.exclude = null;

	dom.addClass("All", "selected",
		() => dom.removeClasses(
			{
				"Active": "selected",
				"Completed": "selected"
			},
			() => dom.disableElements( ["HideActive", "HideCompleted"] )
		)
	)
}

function acActive(dom, id) {
	dom.exclude = true;

	dom.addClass("Active", "selected",
		() => dom.removeClasses(
			{
				"All": "selected",
				"Completed": "selected"
			},
			() => dom.disableElement( "HideActive",
				() => dom.enableElement( "HideCompleted") )
		)
	)
}

function acCompleted(dom, id) {
	dom.exclude = false;

	dom.addClass("Completed", "selected",
		() => dom.removeClasses(
			{
				"All": "selected",
				"Active": "selected"
			},
			() => dom.disableElement("HideCompleted",
				() =>dom.enableElement("HideActive"))
		)
	)
}

function acClear(dom, id) {
	var i = 0;

	while (i < dom.todos.length) {
		if (dom.todos[i]['completed'])
			dom.todos.splice(i, 1);
		else
			i++;
	}

	displayTodos(dom);
}

function acEdit(dom, id) {
	dom.getContent(id,
		(content) => dom.addClasses(
			{
				["View." + content]: "hide",
				[id]: "editing"
			},
			() => {
				dom.index = parseInt(content);
				dom.setContent("Input." + content, dom.todos[dom.index]['label'],
					() => dom.focus("Input." + content))
			}
		)
	);
}

function acCancel(dom, id) {
	var id = dom.index;
	dom.index = -1;

	dom.setContent("Input." + id, "",
		() => dom.removeClasses(
			{
				["View." + id]: "hide",
				["Todo." + id]: "editing"
			}
		)
	);
}

function main() {
	var callbacks =	{
		"Connect": acConnect,
		"Submit": acSubmit,
		"Destroy": acDestroy,
		"Toggle": acToggle,
		"All": acAll,
		"Active": acActive,
		"Completed": acCompleted,
		"Clear": acClear,
		"Edit": acEdit,
		"Cancel": acCancel,
	};

	atlas.launch(newSession, "Connect", callbacks);

	switch (atlas.mode) {
		case atlas.modes.PROD:
			head = "HeadPROD.html";
			break;
		case atlas.modes.DEMO:
			head = "HeadDEMO.html";
			break;
		default:
			throw "Unknown mode !!!";
			break;
	}
}

main();
<|endoftext|>


<commit_before>describe('Charts', function () {

  var
    width = 480,
    height = 320,
    a, b, options, defaults;

  defaults = {
    width : 480,
    height : 320,
    offsetLeft : 0,
    offsetRight : 0,
    color : "rgb(192,216,0)",
    context : null,
    data : null,
    fill : false,
    fillColor : null,
    fillOpacity : 0.4,
    fillStyle : "rgba(192,216,0,0.4)",
    fontColor : "#545454",
    fontSize : 7.5,
    htmlText : true,
    lineWidth : 2,
    shadowSize : 4,
    show : false,
    stacked : false,
    textEnabled : true,
    xScale : function (x) { return x; },
    yScale : function (y) { return height - y; }
  };

  describe('Lines', function () {

    describe('Draw', function () {

      beforeEach(function () {
        this.addMatchers(imagediff.jasmine);
        a = imagediff.createCanvas(width, height);
        b = imagediff.createCanvas(width, height);
        options = _.clone(defaults);
        options.context = a.getContext('2d');
      });

      it('draws a line chart', function () {

        options.data = [
          [0, 0],
          [240, 300],
          [480, 0]
        ];

        TestFlotr.graphTypes.lines.draw(options);
        options.context = b.getContext('2d');
        StableFlotr.graphTypes.lines.draw(options);

        expect(b).toImageDiffEqual(a);
      });

      it('skips null values', function () {
        options.data = [
          [0, 0],
          [100, 50],
          [200, null],
          [300, 150],
          [400, 200],
          [480, 240]
        ];

        TestFlotr.graphTypes.lines.draw(options);
        options.context = b.getContext('2d');
        StableFlotr.graphTypes.lines.draw(options);
        expect(b).toImageDiffEqual(a);
      });
    });
  });
});
<commit_msg>Added two lines test (note: this is just drawing two lines using the same options, we aren't supplying two lines of data at once).<commit_after>describe('Charts', function () {

  var
    width = 480,
    height = 320,
    a, b, options, defaults;

  defaults = {
    width : 480,
    height : 320,
    offsetLeft : 0,
    offsetRight : 0,
    color : "rgb(192,216,0)",
    context : null,
    data : null,
    fill : false,
    fillColor : null,
    fillOpacity : 0.4,
    fillStyle : "rgba(192,216,0,0.4)",
    fontColor : "#545454",
    fontSize : 7.5,
    htmlText : true,
    lineWidth : 2,
    shadowSize : 4,
    show : false,
    stacked : false,
    textEnabled : true,
    xScale : function (x) { return x; },
    yScale : function (y) { return height - y; }
  };

  describe('Lines', function () {

    describe('Draw', function () {

      beforeEach(function () {
        this.addMatchers(imagediff.jasmine);
        a = imagediff.createCanvas(width, height);
        b = imagediff.createCanvas(width, height);
        options = _.clone(defaults);
        options.context = a.getContext('2d');
      });

      it('draws a line chart', function () {

        options.data = [
          [0, 0],
          [240, 300],
          [480, 0]
        ];

        TestFlotr.graphTypes.lines.draw(options);
        options.context = b.getContext('2d');
        StableFlotr.graphTypes.lines.draw(options);

        expect(b).toImageDiffEqual(a);
      });

      it('skips null values', function () {
        options.data = [
          [0, 0],
          [100, 50],
          [200, null],
          [300, 150],
          [400, 200],
          [480, 240]
        ];

        TestFlotr.graphTypes.lines.draw(options);
        options.context = b.getContext('2d');
        StableFlotr.graphTypes.lines.draw(options);
        expect(b).toImageDiffEqual(a);
      });

      it('draws two lines', function () {

        // First line
        options.data = [[0, 0], [240, 160], [480, 320]];
        TestFlotr.graphTypes.lines.draw(options);
        options.context = b.getContext('2d');
        StableFlotr.graphTypes.lines.draw(options);

        // Second Line
        options.context = a.getContext('2d');
        options.data = [[0, 320], [240, 160], [480, 0]];
        TestFlotr.graphTypes.lines.draw(options);
        options.context = b.getContext('2d');
        StableFlotr.graphTypes.lines.draw(options);

        expect(b).toImageDiffEqual(a);
      });
    });
  });
});
<|endoftext|>