<commit_before>/*
  Begin Global Variables
*/

  // Data structure that holds transcriptions. Looks something like the following
  // [ {start: "0:00", end: "0:10", text:"Conditional variables are cool"}, ... ]
  var transcriptions = [];

  // Video anchor used to define when the current transcription segment started
  var anchor = "0:00";

  // Metrics object
  var metrics = {};

  // Global reference to the wavesurfer
  var globalSurfer;

  // Video state
  var videoPlaying = false;

  // Surfer state
  var surferPlaying = false;

  // Start time global reference
  var startTime;

/*
  End Global Variables
*/

window.onbeforeunload = function() {
  if ($(".submit").text() !== "Transcription Submitted!") {
    return 'Are you sure you want to leave without submitting your transcription?';
  }
};

$(document).ready(function () {
  setVideoFromUrl();
  begin();
  initializeMetricsBaseInformation();
});

/*
  Sets the correct video from url parameters
*/
function setVideoFromUrl() {
  var stackURL = document.URL.split("/");
  if (stackURL.indexOf("upload") > -1) {
    var template = '<option class="video-option" value="0">Upload Video</option>';
    $(".video-selector").empty().append(template);
    var videoURL = document.URL.split("=")[1];
    var audioURL = videoURL.replace("mp4", "mp3");
    VIDEOS = [["Uploaded Video", videoURL.replace(".mp4",""), audioURL]];
  } else {
    var videoIndex = 0;
    $(".video-selector option").eq(videoIndex).attr('selected', true);
  }
}

/*
  Gets basic metrics information
*/
function initializeMetricsBaseInformation() {
  var stackURL = document.URL.split("/");
  var user = stackURL.slice(-2)[0];
  metrics["name"] = user;
}

/*
  Started once the DOM finishes loading
*/
function begin() {
  var videoIndex = parseInt($(".video-selector").val(), 10);

  initializeUI();
  loadVideo(videoIndex);
  bindEventListeners();
  bindVideoEvents();

  $(".transcription-input-main").focus();
}

/*
  Initialize the UI to default states
*/
function initializeUI() {
  $(".waveform-loading").removeClass("hidden");
  $(".submit").click(function () {
    var $that = $(this);
    $that.text("Submitting Transcription...");
    $.ajax({
      type: "POST",
      url: "/first",
      data: {
        stats: stats(),
        transcriptions: $(".transcription-input-main").val(),
        className: className,
      },
      success: function (data) {
        $that.text("Transcription Submitted!");
        $that.addClass("unclickable");
      }
    });
  });
}

/*
  Binds event listeners on input elements
*/
function bindEventListeners() {
  $(".video-selector").off().change(begin);
  $(".playback-selector").off().change(changePlaybackSpeed);
  $(".transcription-input-main").off().keypress(inputKeypress);
}

/*
  Binds event listeners on the video
*/
function bindVideoEvents() {
  var video = $(".main-video").get(0);

  var lastUpdate = 0;
  video.ontimeupdate = function () {
    var globalSurferTime = globalSurfer.getCurrentTime();
    var videoCurrentTime = video.currentTime;
    if (Math.abs(globalSurferTime - videoCurrentTime) > 0.1) {
      globalSurfer.skip(videoCurrentTime - globalSurferTime);
    }

    if (videoPlaying && !surferPlaying) {
      globalSurfer.play();
    }

    if (Math.abs(lastUpdate - videoCurrentTime) > 9 || lastUpdate > videoCurrentTime) {
      var scrollLeft = videoCurrentTime * 64;
      $(".waveform-container").animate({scrollLeft: scrollLeft}, 500);
      lastUpdate = videoCurrentTime;
    }
  };

  video.onended = function(e) {
    calculateTotalTime();
  };

  video.addEventListener("loadedmetadata", function () {
    changePlaybackSpeed();
    loadWaveform(function () {
      video.onplay = function () {
        videoPlaying = true;
        globalSurfer.play();
      };
      video.onpause = function () {
        videoPlaying = false;
        globalSurfer.pause();
      };
    });
  });
}

/*
  Changes the playback speed
*/
function changePlaybackSpeed() {
  var playbackRate = parseFloat($(".playback-selector").val());
  $(".main-video").get(0).playbackRate = playbackRate;
  if (globalSurfer) {
    globalSurfer.setPlaybackRate(playbackRate);
  }
  $(".transcription-input-main").focus();
}

/*
  Captures the input keypresses and reacts accordingly
*/
function inputKeypress(e) {
  if (e.which === 96) {
    e.preventDefault();
    incrementMetricCount("rewindTwoSeconds");
    rewindTwoSeconds();
  } else if (e.which === 126) {
    e.preventDefault();
    incrementMetricCount("toggleVideo");
    toggleVideo();
  }

  if (!startTime) {
    startTime = new Date();
  }

  $(".transcription-input-main").blur(function () {
    $(".transcription-input").eq(0).val("");
  });
}

/*
  Rewind the video 5 seconds
*/
function rewindTwoSeconds() {
  var video = $(".main-video").get(0);
  video.currentTime = video.currentTime - 2;
}

/*
  Changes the video play/pause
*/
function toggleVideo() {
  var video = $(".main-video").get(0);
  if (video.paused === false) {
      video.pause();
  } else {
      video.play();
  }
}

/*
  Returns the current time nicely formatted
*/
function getCurrentTime() {
  var currentTime = $(".main-video").get(0).currentTime;

  var currentTimeInMinutes = Math.floor(currentTime / 60);
  var currentTimeInSeconds = Math.floor(currentTime % 60);

  if (currentTimeInSeconds < 10) {
    return currentTimeInMinutes + ":0" + currentTimeInSeconds;
  }
  return currentTimeInMinutes + ":" + currentTimeInSeconds;
}

/*
  Load the waveform for a certain video
*/
function loadWaveform(cb) {
  var videoIndex = parseInt($(".video-selector").val(), 10);
  var wavesurfer = Object.create(WaveSurfer);
  var videoSrc = VIDEOS[videoIndex][2] || VIDEOS[videoIndex][1];
  var video = $(".main-video").get(0);

  surferPlaying = false;

  $("#waveform").empty();
  $(".waveform-outer").css("width", (video.duration * 64) + "px");

  var options = {
    container     : document.querySelector('#waveform'),
    waveColor     : '#5195CE',
    progressColor : '#005DB3',
    loaderColor   : '#005DB3',
    cursorColor   : 'silver',
    pixelRatio    : 1,
    minPxPerSec   : 5,
    height        : 25,
    audioRate     : parseFloat($(".playback-selector").val()),
    normalize     : true,
  };
  wavesurfer.init(options);
  wavesurfer.setVolume(0);
  wavesurfer.load(videoSrc);

  wavesurfer.on('ready', function () {
    wavesurfer.skip(video.currentTime);
    var scrollLeft = video.currentTime * 64 - 200;
    $(".transcription-track, .final-transcription-track, .waveform-container").animate({scrollLeft: scrollLeft}, 500);
    $(".waveform-loading").addClass("hidden");
    disableMacBack($("canvas").toArray());
    $("canvas").mousewheel(function(e) {
      var deltaX = e.originalEvent.wheelDeltaX * -1;
      var deltaY = e.originalEvent.wheelDeltaY;
      if (Math.abs(deltaY) > Math.abs(deltaX)) {
        $(".waveform-container").get(0).scrollLeft -= (deltaY);
        e.preventDefault();
      }
    });
  });

  wavesurfer.on('play', function () {
    surferPlaying = true;
  });

  wavesurfer.on('pause', function () {
    surferPlaying = false;
  });

  wavesurfer.drawer.on('click', function (e, position) {
    var previousTime = wavesurfer.getCurrentTime();
    var wavesurferTime = position * video.duration;
    video.currentTime = wavesurferTime;
    $(".transcription-input-main").focus();
    incrementMetricCount("videoSeek", {time: wavesurferTime - previousTime});
  });

  globalSurfer = wavesurfer;
  cb();
}

/*
  Converts a time string to a time integer
*/
function incrementMetricCount(name, data) {
  metrics[name] = (metrics[name] || {});
  metrics[name].count = (metrics[name].count || 0) + 1;
  if (data) {
    metrics[name].data = (metrics[name].data || []).concat(data);
  }
}

/*
  Calculate total trancsription time
*/
function calculateTotalTime() {
  if (!metrics["totalTime"] && startTime) {
    metrics["totalTime"] = (new Date()).getTime() - startTime.getTime();
  }
}

/*
  Save the metrics
*/
function stats() {
  var videoIndex = parseInt($(".video-selector").val(), 10);
  metrics["video"] = VIDEOS[videoIndex][0];
  calculateTotalTime();
  console.log(JSON.stringify(metrics));
  return JSON.stringify(metrics);
}
<commit_msg>submitt button fixed<commit_after>/*
  Begin Global Variables
*/

  // Data structure that holds transcriptions. Looks something like the following
  // [ {start: "0:00", end: "0:10", text:"Conditional variables are cool"}, ... ]
  var transcriptions = [];

  // Video anchor used to define when the current transcription segment started
  var anchor = "0:00";

  // Metrics object
  var metrics = {};

  // Global reference to the wavesurfer
  var globalSurfer;

  // Video state
  var videoPlaying = false;

  // Surfer state
  var surferPlaying = false;

  // Start time global reference
  var startTime;

/*
  End Global Variables
*/

window.onbeforeunload = function() {
  if ($(".submit").text() !== "Transcription Submitted!") {
    return 'Are you sure you want to leave without submitting your transcription?';
  }
};

$(document).ready(function () {
  setVideoFromUrl();
  begin();
  initializeMetricsBaseInformation();
});

/*
  Sets the correct video from url parameters
*/
function setVideoFromUrl() {
  var stackURL = document.URL.split("/");
  if (stackURL.indexOf("upload") > -1) {
    var template = '<option class="video-option" value="0">Upload Video</option>';
    $(".video-selector").empty().append(template);
    var videoURL = document.URL.split("=")[1];
    var audioURL = videoURL.replace("mp4", "mp3");
    VIDEOS = [["Uploaded Video", videoURL.replace(".mp4",""), audioURL]];
  } else {
    var videoIndex = 0;
    $(".video-selector option").eq(videoIndex).attr('selected', true);
  }
}

/*
  Gets basic metrics information
*/
function initializeMetricsBaseInformation() {
  var stackURL = document.URL.split("/");
  var user = stackURL.slice(-2)[0];
  metrics["name"] = user;
}

/*
  Started once the DOM finishes loading
*/
function begin() {
  var videoIndex = parseInt($(".video-selector").val(), 10);

  initializeUI();
  loadVideo(videoIndex);
  bindEventListeners();
  bindVideoEvents();

  $(".transcription-input-main").focus();
}

/*
  Initialize the UI to default states
*/
function initializeUI() {
  $(".waveform-loading").removeClass("hidden");
  $(".submit").click(function () {
    var $that = $(this);
    $that.text("Submitting Transcription...");
    $.ajax({
      type: "POST",
      url: "/first",
      data: {
        stats: stats(),
        transcriptions: $(".transcription-input-main").val(),
        className: className,
      },
      success: function (data) {
        $that.text("Transcription Submitted!");
        $that.addClass("unclickable");
      },
      error: function(data){
        $that.text("Try Submitting Transcription Again.");
      }
    });
  });
}

/*
  Binds event listeners on input elements
*/
function bindEventListeners() {
  $(".video-selector").off().change(begin);
  $(".playback-selector").off().change(changePlaybackSpeed);
  $(".transcription-input-main").off().keypress(inputKeypress);
}

/*
  Binds event listeners on the video
*/
function bindVideoEvents() {
  var video = $(".main-video").get(0);

  var lastUpdate = 0;
  video.ontimeupdate = function () {
    var globalSurferTime = globalSurfer.getCurrentTime();
    var videoCurrentTime = video.currentTime;
    if (Math.abs(globalSurferTime - videoCurrentTime) > 0.1) {
      globalSurfer.skip(videoCurrentTime - globalSurferTime);
    }

    if (videoPlaying && !surferPlaying) {
      globalSurfer.play();
    }

    if (Math.abs(lastUpdate - videoCurrentTime) > 9 || lastUpdate > videoCurrentTime) {
      var scrollLeft = videoCurrentTime * 64;
      $(".waveform-container").animate({scrollLeft: scrollLeft}, 500);
      lastUpdate = videoCurrentTime;
    }
  };

  video.onended = function(e) {
    calculateTotalTime();
  };

  video.addEventListener("loadedmetadata", function () {
    changePlaybackSpeed();
    loadWaveform(function () {
      video.onplay = function () {
        videoPlaying = true;
        globalSurfer.play();
      };
      video.onpause = function () {
        videoPlaying = false;
        globalSurfer.pause();
      };
    });
  });
}

/*
  Changes the playback speed
*/
function changePlaybackSpeed() {
  var playbackRate = parseFloat($(".playback-selector").val());
  $(".main-video").get(0).playbackRate = playbackRate;
  if (globalSurfer) {
    globalSurfer.setPlaybackRate(playbackRate);
  }
  $(".transcription-input-main").focus();
}

/*
  Captures the input keypresses and reacts accordingly
*/
function inputKeypress(e) {
  if (e.which === 96) {
    e.preventDefault();
    incrementMetricCount("rewindTwoSeconds");
    rewindTwoSeconds();
  } else if (e.which === 126) {
    e.preventDefault();
    incrementMetricCount("toggleVideo");
    toggleVideo();
  }

  if (!startTime) {
    startTime = new Date();
  }

  $(".transcription-input-main").blur(function () {
    $(".transcription-input").eq(0).val("");
  });
}

/*
  Rewind the video 5 seconds
*/
function rewindTwoSeconds() {
  var video = $(".main-video").get(0);
  video.currentTime = video.currentTime - 2;
}

/*
  Changes the video play/pause
*/
function toggleVideo() {
  var video = $(".main-video").get(0);
  if (video.paused === false) {
      video.pause();
  } else {
      video.play();
  }
}

/*
  Returns the current time nicely formatted
*/
function getCurrentTime() {
  var currentTime = $(".main-video").get(0).currentTime;

  var currentTimeInMinutes = Math.floor(currentTime / 60);
  var currentTimeInSeconds = Math.floor(currentTime % 60);

  if (currentTimeInSeconds < 10) {
    return currentTimeInMinutes + ":0" + currentTimeInSeconds;
  }
  return currentTimeInMinutes + ":" + currentTimeInSeconds;
}

/*
  Load the waveform for a certain video
*/
function loadWaveform(cb) {
  var videoIndex = parseInt($(".video-selector").val(), 10);
  var wavesurfer = Object.create(WaveSurfer);
  var videoSrc = VIDEOS[videoIndex][2] || VIDEOS[videoIndex][1];
  var video = $(".main-video").get(0);

  surferPlaying = false;

  $("#waveform").empty();
  $(".waveform-outer").css("width", (video.duration * 64) + "px");

  var options = {
    container     : document.querySelector('#waveform'),
    waveColor     : '#5195CE',
    progressColor : '#005DB3',
    loaderColor   : '#005DB3',
    cursorColor   : 'silver',
    pixelRatio    : 1,
    minPxPerSec   : 5,
    height        : 25,
    audioRate     : parseFloat($(".playback-selector").val()),
    normalize     : true,
  };
  wavesurfer.init(options);
  wavesurfer.setVolume(0);
  wavesurfer.load(videoSrc);

  wavesurfer.on('ready', function () {
    wavesurfer.skip(video.currentTime);
    var scrollLeft = video.currentTime * 64 - 200;
    $(".transcription-track, .final-transcription-track, .waveform-container").animate({scrollLeft: scrollLeft}, 500);
    $(".waveform-loading").addClass("hidden");
    disableMacBack($("canvas").toArray());
    $("canvas").mousewheel(function(e) {
      var deltaX = e.originalEvent.wheelDeltaX * -1;
      var deltaY = e.originalEvent.wheelDeltaY;
      if (Math.abs(deltaY) > Math.abs(deltaX)) {
        $(".waveform-container").get(0).scrollLeft -= (deltaY);
        e.preventDefault();
      }
    });
  });

  wavesurfer.on('play', function () {
    surferPlaying = true;
  });

  wavesurfer.on('pause', function () {
    surferPlaying = false;
  });

  wavesurfer.drawer.on('click', function (e, position) {
    var previousTime = wavesurfer.getCurrentTime();
    var wavesurferTime = position * video.duration;
    video.currentTime = wavesurferTime;
    $(".transcription-input-main").focus();
    incrementMetricCount("videoSeek", {time: wavesurferTime - previousTime});
  });

  globalSurfer = wavesurfer;
  cb();
}

/*
  Converts a time string to a time integer
*/
function incrementMetricCount(name, data) {
  metrics[name] = (metrics[name] || {});
  metrics[name].count = (metrics[name].count || 0) + 1;
  if (data) {
    metrics[name].data = (metrics[name].data || []).concat(data);
  }
}

/*
  Calculate total trancsription time
*/
function calculateTotalTime() {
  if (!metrics["totalTime"] && startTime) {
    metrics["totalTime"] = (new Date()).getTime() - startTime.getTime();
  }
}

/*
  Save the metrics
*/
function stats() {
  var videoIndex = parseInt($(".video-selector").val(), 10);
  metrics["video"] = VIDEOS[videoIndex][0];
  calculateTotalTime();
  console.log(JSON.stringify(metrics));
  return JSON.stringify(metrics);
}
<|endoftext|>


<commit_before>(function() {
  'use strict';

  angular.module('app.components')
    .controller('KitController', KitController);

    KitController.$inject = ['$state','$scope', '$stateParams', 'kitData', 'ownerKits', 'utils', 'sensor', 'FullKit', '$mdDialog', 'belongsToUser', 'timeUtils', 'animation', '$location', 'auth', 'kitUtils', 'userUtils', '$timeout'];
    function KitController($state, $scope, $stateParams, kitData, ownerKits, utils, sensor, FullKit, $mdDialog, belongsToUser, timeUtils, animation, $location, auth, kitUtils, userUtils, $timeout) {
      var vm = this;

      var getChartDataHasBeenCalled = false;
      var mainSensorID, compareSensorID, sensorsData;
      var picker = initializePicker();

      console.log('controller loaded');
      animation.kitLoaded({lat: kitData.latitude ,lng: kitData.longitude, id: parseInt($stateParams.id) });
      vm.kit = kitData;
      vm.ownerKits = ownerKits;
      vm.kitBelongsToUser = belongsToUser;

      var mainSensors = vm.kit.getSensors({type: 'main'});
      vm.battery = mainSensors[1];
      vm.sensors = mainSensors[0];
      vm.sensorsToCompare = vm.kit.getSensors({type: 'compare'});

      vm.slide = slide;
      vm.chartData = [];

      vm.selectedSensor = vm.sensors[0].id;
      vm.selectedSensorData = {
        icon: vm.sensors[0].icon,
        value: vm.sensors[0].value,
        unit: vm.sensors[0].unit,
        color: vm.sensors[0].color
      };

      vm.selectedSensorToCompare = undefined;
      vm.selectedSensorToCompareData = [];

      vm.moveChart = moveChart;
      vm.loadingChart = true;

      vm.dropdownOptions = [
        {text: 'SET UP', value: '1'},
        {text: 'EDIT', value: '2'}
      ];

      vm.dropdownSelected = undefined;

      $scope.$watch('vm.selectedSensor', function(newVal, oldVal) {
        vm.selectedSensorToCompare = undefined;
        vm.selectedSensorToCompareData = {};
        vm.chartDataCompare = [];
        compareSensorID = undefined;

        vm.sensors.forEach(function(sensor) {
          if(sensor.id === newVal) {
            vm.selectedSensorData = {
              icon: sensor.icon,
              value: sensor.value,
              unit: sensor.unit,
              color: sensor.color
            };
          }
        });

        vm.sensorsToCompare = getSensorsToCompare();

        $timeout(function() {
          colorSensorMainIcon();
          colorSensorCompareName();

          setSensor({type: 'main', value: newVal});
          changeChart('sensor', [mainSensorID, compareSensorID]);
        }, 100);

      });

      $scope.$watch('vm.selectedSensorToCompare', function(newVal, oldVal) {

        vm.sensorsToCompare.forEach(function(sensor) {
          if(sensor.id === newVal) {
            vm.selectedSensorToCompareData = {
              icon: sensor.icon,
              color: sensor.color,
              unit: sensor.unit
            };
          }
        });

        $timeout(function() {
          colorSensorCompareName();
          setSensor({type: 'compare', value: newVal});

          if(oldVal === undefined && newVal === undefined) {
            return;
          }
          changeChart('sensor', [mainSensorID, compareSensorID]);
        }, 100);

      });

      $scope.$on('hideChartSpinner', function() {
        vm.loadingChart = false;
      });

      $scope.$on('loggedIn', function() {
        var kitID = parseInt($stateParams.id);
        var userData = auth.getCurrentUser().data;
        var belongsToUser = kitUtils.belongsToUser(userData.kits, kitID);
        var isAdmin = userUtils.isAdmin(userData);

        if(isAdmin || belongsToUser) {
          vm.kitBelongsToUser = true;
        }
      });

      $scope.$on('loggedOut', function() {
        vm.kitBelongsToUser = false;
      });

      $timeout(function() {
        colorSensorMainIcon();
        colorArrows();
        colorClock();
      }, 1000);

      ///////////////

      function slide(direction) {
        var slideContainer = angular.element('.sensors_container');
        var scrollPosition = slideContainer.scrollLeft();
        var slideStep = 20;

        console.log('scroll', scrollPosition);
        if(direction === 'left') {
          slideContainer.scrollLeft(scrollPosition + slideStep);
        } else if(direction === 'right') {
          slideContainer.scrollLeft(scrollPosition - slideStep);
        }
      }

      function getSensorsToCompare() {
        return vm.sensorsToCompare.filter(function(sensor) {
          return sensor.id !== vm.selectedSensor;
        });
      }

      function changeChart(updateType, sensorsID, options) {
        if(!sensorsID[0]) {
          return;
        }

        if(getChartDataHasBeenCalled && !sensorsData) {
          //waiting for the data from the server, render chart on next call
          return;
        //if data is not loaded, get it first -> happens on controller initialization
        } else if(!getChartDataHasBeenCalled) {
          updateType = 'date';
          if(!options) {
            options = {};
          }
          options.from = picker.getValuePickerFrom();
          options.to = picker.getValuePickerTo();
        }

        if(updateType === 'date') {
          //show spinner
          vm.loadingChart = true;
          //grab chart data and save it
          getChartData(options.from, options.to)
            .then(function() {
              vm.chartDataMain = prepareChartData(sensorsID);
            });
        } else if(updateType === 'sensor') {
          vm.chartDataMain = prepareChartData(sensorsID);
        }
      }

      function getChartData(dateFrom, dateTo, options) {
        getChartDataHasBeenCalled = true;
        var deviceID = $stateParams.id;

        return sensor.getSensorsData(deviceID, dateFrom, dateTo)
          .then(function(data) {
            //save sensor data of this kit so that it can be reused
            sensorsData = data.readings;
          });
      }

      function prepareChartData(sensorsID) {
        var parsedDataMain = parseSensorData(sensorsData, sensorsID[0]);
        var mainSensor = {
          data: parsedDataMain,
          color: vm.selectedSensorData.color,
          unit: vm.selectedSensorData.unit
        };
        if(sensorsID[1] && sensorsID[1] !== -1) {
          var parsedDataCompare = parseSensorData(sensorsData, sensorsID[1]);
          var compareSensor = {
            data: parsedDataCompare,
            color: vm.selectedSensorToCompareData.color,
            unit: vm.selectedSensorToCompareData.unit
          };
        }
        var newChartData = [mainSensor, compareSensor];
        return newChartData;
      }

      function parseSensorData(data, sensorID) {
        if(data.length === 0) {
          return [];
        }
        return data.map(function(dataPoint) {
          var time = dataPoint && dataPoint.timestamp;
          var data = dataPoint && dataPoint.data[sensorID];
          data = data === null ? 0 : data;

          return {
            time: time,
            data: data
          };
        });
      }

      function setSensor(options) {
        var sensorID = options.value;
        if(sensorID === undefined) {
          return;
        }
        if(options.type === 'main') {
          mainSensorID = sensorID;
        } else if(options.type === 'compare') {
          compareSensorID = sensorID;
        }
      }

      function colorSensorMainIcon() {
        var svgContainer = angular.element('.sensor_icon_selected');
        var parent = svgContainer.find('.container_parent');
        parent.css('fill', vm.selectedSensorData.color);
      }

      function colorSensorCompareName() {
        var name = angular.element('.sensor_compare').find('md-select-label').find('span');
        name.css('color', vm.selectedSensorToCompareData.color || 'white');
        var icon = angular.element('.sensor_compare').find('md-select-label').find('.md-select-icon');
        icon.css('color', 'white');
      }

      function colorArrows() {
        var svgContainer;

        svgContainer = angular.element('.chart_move_left').find('svg');
        svgContainer.find('.fill_container').css('fill', '#03252D');

        svgContainer = angular.element('.chart_move_right').find('svg');
        svgContainer.find('.fill_container').css('fill', '#4E656B');
      }

      function colorClock() {
        var svgContainer = angular.element('.kit_time_icon');
        svgContainer.find('.stroke_container').css({'stroke-width': '0.5px', 'stroke':'#A4B0B3'});
        svgContainer.find('.fill_container').css('fill', '#A4B0B3');
      }

      function getSecondsFromDate(date) {
        return (new Date(date)).getTime();
      }

      function getCurrentRange() {
        return getSecondsFromDate( picker.getValuePickerTo() ) - getSecondsFromDate( picker.getValuePickerFrom() );
      }

      function moveChart(direction) {
        var valueTo, valueFrom;
        //grab current date range
        var currentRange = getCurrentRange();

        if(direction === 'left') {
          //set both from and to pickers to prev range
          valueTo = picker.getValuePickerFrom();
          valueFrom = getSecondsFromDate( picker.getValuePickerFrom() ) - currentRange;
          picker.setValuePickers([valueFrom, valueTo]);
        } else if(direction === 'right') {
          var today = timeUtils.getToday();
          var currentValueTo = picker.getValuePickerTo();
          if( timeUtils.isSameDay(today, currentValueTo) ) {
            // vm.toPickerDisabled = true;
            return;
          }

          //set both from and to pickers  to next range
          valueFrom = picker.getValuePickerTo();
          valueTo = getSecondsFromDate( picker.getValuePickerTo() ) + currentRange;
          picker.setValuePickers([valueFrom, valueTo]);
        }
      }

      //hide everything but the functions to interact with the pickers
      function initializePicker() {
        var updateType = 'single'; //set update type to single by default

        /*jshint camelcase: false*/
        var from_$input = angular.element('#picker_from').pickadate({
          container: 'body',
          klass: {
            holder: 'picker__holder picker_container'
          }
        });
        var from_picker = from_$input.pickadate('picker');

        var to_$input = angular.element('#picker_to').pickadate({
          container: 'body',
          klass: {
            holder: 'picker__holder picker_container'
          }
        });
        var to_picker = to_$input.pickadate('picker');

        if( from_picker.get('value') ) {
          to_picker.set('min', from_picker.get('select') );
        }
        if( to_picker.get('value') ) {
          from_picker.set('max', to_picker.get('select') );
        }

        from_picker.on('set', function(event) {
          if(event.select) {
            if(to_picker.get('value') && updateType === 'single') {
              changeChart('date', [mainSensorID, compareSensorID], {from: from_picker.get('value'), to: to_picker.get('value') });
            }
            to_picker.set('min', from_picker.get('select') );
          } else if( 'clear' in event) {
            to_picker.set('min', false);
          }
        });

        to_picker.on('set', function(event) {
          if(event.select) {
            if(from_picker.get('value')) {
              changeChart('date', [mainSensorID, compareSensorID], {from: from_picker.get('value'), to: to_picker.get('value') });
            }
            from_picker.set('max', to_picker.get('select'));
          } else if( 'clear' in event) {
            from_picker.set('max', false);
          }
        });

        //set to-picker max to today
        to_picker.set('max', new Date());

        function getToday() {
          return getSecondsFromDate(new Date());
        }

        function getSevenDaysAgo() {
          return getSecondsFromDate( getToday() - (7 * 24 * 60 * 60 * 1000) );
        }

        //set from-picker to seven days ago
        from_picker.set('select', getSevenDaysAgo());
        //set to-picker to today
        to_picker.set('select', getToday());

        return {
          getValuePickerFrom: function() {
            return from_picker.get('value');
          },
          setValuePickerFrom: function(newValue) {
            updateType = 'single';
            from_picker.set('select', newValue);
          },
          getValuePickerTo: function() {
            return to_picker.get('value');
          },
          setValuePickerTo: function(newValue) {
            updateType = 'single';
            to_picker.set('select', newValue);
          },
          setValuePickers: function(newValues) {
            var from = newValues[0];
            var to = newValues[1];

            updateType = 'pair';
            from_picker.set('select', from);
            to_picker.set('select', to);
          }
        };
      }
    }
})();
<commit_msg>fix(picker): fix picker bug<commit_after>(function() {
  'use strict';

  angular.module('app.components')
    .controller('KitController', KitController);

    KitController.$inject = ['$state','$scope', '$stateParams', 'kitData', 'ownerKits', 'utils', 'sensor', 'FullKit', '$mdDialog', 'belongsToUser', 'timeUtils', 'animation', '$location', 'auth', 'kitUtils', 'userUtils', '$timeout'];
    function KitController($state, $scope, $stateParams, kitData, ownerKits, utils, sensor, FullKit, $mdDialog, belongsToUser, timeUtils, animation, $location, auth, kitUtils, userUtils, $timeout) {
      var vm = this;

      var getChartDataHasBeenCalled = false;
      var mainSensorID, compareSensorID, sensorsData;
      var picker = initializePicker();

      // console.log('controller loaded');
      animation.kitLoaded({lat: kitData.latitude ,lng: kitData.longitude, id: parseInt($stateParams.id) });
      vm.kit = kitData;
      vm.ownerKits = ownerKits;
      vm.kitBelongsToUser = belongsToUser;

      var mainSensors = vm.kit.getSensors({type: 'main'});
      vm.battery = mainSensors[1];
      vm.sensors = mainSensors[0];
      vm.sensorsToCompare = vm.kit.getSensors({type: 'compare'});

      vm.slide = slide;
      vm.chartData = [];

      vm.selectedSensor = vm.sensors[0].id;
      vm.selectedSensorData = {
        icon: vm.sensors[0].icon,
        value: vm.sensors[0].value,
        unit: vm.sensors[0].unit,
        color: vm.sensors[0].color
      };

      vm.selectedSensorToCompare = undefined;
      vm.selectedSensorToCompareData = [];

      vm.moveChart = moveChart;
      vm.loadingChart = true;

      vm.dropdownOptions = [
        {text: 'SET UP', value: '1'},
        {text: 'EDIT', value: '2'}
      ];

      vm.dropdownSelected = undefined;

      $scope.$watch('vm.selectedSensor', function(newVal, oldVal) {
        vm.selectedSensorToCompare = undefined;
        vm.selectedSensorToCompareData = {};
        vm.chartDataCompare = [];
        compareSensorID = undefined;

        vm.sensors.forEach(function(sensor) {
          if(sensor.id === newVal) {
            vm.selectedSensorData = {
              icon: sensor.icon,
              value: sensor.value,
              unit: sensor.unit,
              color: sensor.color
            };
          }
        });

        vm.sensorsToCompare = getSensorsToCompare();

        $timeout(function() {
          colorSensorMainIcon();
          colorSensorCompareName();

          setSensor({type: 'main', value: newVal});
          changeChart('sensor', [mainSensorID, compareSensorID]);
        }, 100);

      });

      $scope.$watch('vm.selectedSensorToCompare', function(newVal, oldVal) {

        vm.sensorsToCompare.forEach(function(sensor) {
          if(sensor.id === newVal) {
            vm.selectedSensorToCompareData = {
              icon: sensor.icon,
              color: sensor.color,
              unit: sensor.unit
            };
          }
        });

        $timeout(function() {
          colorSensorCompareName();
          setSensor({type: 'compare', value: newVal});

          if(oldVal === undefined && newVal === undefined) {
            return;
          }
          changeChart('sensor', [mainSensorID, compareSensorID]);
        }, 100);

      });

      $scope.$on('hideChartSpinner', function() {
        vm.loadingChart = false;
      });

      $scope.$on('loggedIn', function() {
        var kitID = parseInt($stateParams.id);
        var userData = auth.getCurrentUser().data;
        var belongsToUser = kitUtils.belongsToUser(userData.kits, kitID);
        var isAdmin = userUtils.isAdmin(userData);

        if(isAdmin || belongsToUser) {
          vm.kitBelongsToUser = true;
        }
      });

      $scope.$on('loggedOut', function() {
        vm.kitBelongsToUser = false;
      });

      $timeout(function() {
        colorSensorMainIcon();
        colorArrows();
        colorClock();
      }, 1000);

      ///////////////

      function slide(direction) {
        var slideContainer = angular.element('.sensors_container');
        var scrollPosition = slideContainer.scrollLeft();
        var slideStep = 20;

        console.log('scroll', scrollPosition);
        if(direction === 'left') {
          slideContainer.scrollLeft(scrollPosition + slideStep);
        } else if(direction === 'right') {
          slideContainer.scrollLeft(scrollPosition - slideStep);
        }
      }

      function getSensorsToCompare() {
        return vm.sensorsToCompare.filter(function(sensor) {
          return sensor.id !== vm.selectedSensor;
        });
      }

      function changeChart(updateType, sensorsID, options) {
        if(!sensorsID[0]) {
          return;
        }

        if(getChartDataHasBeenCalled && !sensorsData) {
          //waiting for the data from the server, render chart on next call
          return;
        //if data is not loaded, get it first -> happens on controller initialization
        } else if(!getChartDataHasBeenCalled) {
          updateType = 'date';
          if(!options) {
            options = {};
          }
          options.from = picker.getValuePickerFrom();
          options.to = picker.getValuePickerTo();
        }

        if(updateType === 'date') {
          //show spinner
          vm.loadingChart = true;
          //grab chart data and save it
          getChartData(options.from, options.to)
            .then(function() {
              vm.chartDataMain = prepareChartData(sensorsID);
            });
        } else if(updateType === 'sensor') {
          vm.chartDataMain = prepareChartData(sensorsID);
        }
      }

      function getChartData(dateFrom, dateTo, options) {
        getChartDataHasBeenCalled = true;
        var deviceID = $stateParams.id;

        return sensor.getSensorsData(deviceID, dateFrom, dateTo)
          .then(function(data) {
            //save sensor data of this kit so that it can be reused
            sensorsData = data.readings;
          });
      }

      function prepareChartData(sensorsID) {
        var parsedDataMain = parseSensorData(sensorsData, sensorsID[0]);
        var mainSensor = {
          data: parsedDataMain,
          color: vm.selectedSensorData.color,
          unit: vm.selectedSensorData.unit
        };
        if(sensorsID[1] && sensorsID[1] !== -1) {
          var parsedDataCompare = parseSensorData(sensorsData, sensorsID[1]);
          var compareSensor = {
            data: parsedDataCompare,
            color: vm.selectedSensorToCompareData.color,
            unit: vm.selectedSensorToCompareData.unit
          };
        }
        var newChartData = [mainSensor, compareSensor];
        return newChartData;
      }

      function parseSensorData(data, sensorID) {
        if(data.length === 0) {
          return [];
        }
        return data.map(function(dataPoint) {
          var time = dataPoint && dataPoint.timestamp;
          var data = dataPoint && dataPoint.data[sensorID];
          data = data === null ? 0 : data;

          return {
            time: time,
            data: data
          };
        });
      }

      function setSensor(options) {
        var sensorID = options.value;
        if(sensorID === undefined) {
          return;
        }
        if(options.type === 'main') {
          mainSensorID = sensorID;
        } else if(options.type === 'compare') {
          compareSensorID = sensorID;
        }
      }

      function colorSensorMainIcon() {
        var svgContainer = angular.element('.sensor_icon_selected');
        var parent = svgContainer.find('.container_parent');
        parent.css('fill', vm.selectedSensorData.color);
      }

      function colorSensorCompareName() {
        var name = angular.element('.sensor_compare').find('md-select-label').find('span');
        name.css('color', vm.selectedSensorToCompareData.color || 'white');
        var icon = angular.element('.sensor_compare').find('md-select-label').find('.md-select-icon');
        icon.css('color', 'white');
      }

      function colorArrows() {
        var svgContainer;

        svgContainer = angular.element('.chart_move_left').find('svg');
        svgContainer.find('.fill_container').css('fill', '#03252D');

        svgContainer = angular.element('.chart_move_right').find('svg');
        svgContainer.find('.fill_container').css('fill', '#4E656B');
      }

      function colorClock() {
        var svgContainer = angular.element('.kit_time_icon');
        svgContainer.find('.stroke_container').css({'stroke-width': '0.5px', 'stroke':'#A4B0B3'});
        svgContainer.find('.fill_container').css('fill', '#A4B0B3');
      }

      function getSecondsFromDate(date) {
        return (new Date(date)).getTime();
      }

      function getCurrentRange() {
        return getSecondsFromDate( picker.getValuePickerTo() ) - getSecondsFromDate( picker.getValuePickerFrom() );
      }

      function moveChart(direction) {
        var valueTo, valueFrom;
        //grab current date range
        var currentRange = getCurrentRange();

        if(direction === 'left') {
          //set both from and to pickers to prev range
          valueTo = picker.getValuePickerFrom();
          valueFrom = getSecondsFromDate( picker.getValuePickerFrom() ) - currentRange;
          picker.setValuePickers([valueFrom, valueTo]);
        } else if(direction === 'right') {
          var today = timeUtils.getToday();
          var currentValueTo = picker.getValuePickerTo();
          if( timeUtils.isSameDay(today, currentValueTo) ) {
            // vm.toPickerDisabled = true;
            return;
          }

          //set both from and to pickers  to next range
          valueFrom = picker.getValuePickerTo();
          valueTo = getSecondsFromDate( picker.getValuePickerTo() ) + currentRange;
          picker.setValuePickers([valueFrom, valueTo]);
        }
      }

      //hide everything but the functions to interact with the pickers
      function initializePicker() {
        var updateType = 'single'; //set update type to single by default

        /*jshint camelcase: false*/
        var from_$input = angular.element('#picker_from').pickadate({
          onClose: function(){
            angular.element(document.activeElement).blur();
          },
          container: 'body',
          klass: {
            holder: 'picker__holder picker_container'
          }
        });
        var from_picker = from_$input.pickadate('picker');

        var to_$input = angular.element('#picker_to').pickadate({
          onClose: function(){
            angular.element(document.activeElement).blur();
          },
          container: 'body',
          klass: {
            holder: 'picker__holder picker_container'
          }
        });
        var to_picker = to_$input.pickadate('picker');

        if( from_picker.get('value') ) {
          to_picker.set('min', from_picker.get('select') );
        }
        if( to_picker.get('value') ) {
          from_picker.set('max', to_picker.get('select') );
        }

        from_picker.on('set', function(event) {
          if(event.select) {
            if(to_picker.get('value') && updateType === 'single') {
              changeChart('date', [mainSensorID, compareSensorID], {from: from_picker.get('value'), to: to_picker.get('value') });
            }
            to_picker.set('min', from_picker.get('select') );
          } else if( 'clear' in event) {
            to_picker.set('min', false);
          }
        });

        to_picker.on('set', function(event) {
          if(event.select) {
            if(from_picker.get('value')) {
              changeChart('date', [mainSensorID, compareSensorID], {from: from_picker.get('value'), to: to_picker.get('value') });
            }
            from_picker.set('max', to_picker.get('select'));
          } else if( 'clear' in event) {
            from_picker.set('max', false);
          }
        });

        //set to-picker max to today
        to_picker.set('max', new Date());

        function getToday() {
          return getSecondsFromDate(new Date());
        }

        function getSevenDaysAgo() {
          return getSecondsFromDate( getToday() - (7 * 24 * 60 * 60 * 1000) );
        }

        //set from-picker to seven days ago
        from_picker.set('select', getSevenDaysAgo());
        //set to-picker to today
        to_picker.set('select', getToday());

        return {
          getValuePickerFrom: function() {
            return from_picker.get('value');
          },
          setValuePickerFrom: function(newValue) {
            updateType = 'single';
            from_picker.set('select', newValue);
          },
          getValuePickerTo: function() {
            return to_picker.get('value');
          },
          setValuePickerTo: function(newValue) {
            updateType = 'single';
            to_picker.set('select', newValue);
          },
          setValuePickers: function(newValues) {
            var from = newValues[0];
            var to = newValues[1];

            updateType = 'pair';
            from_picker.set('select', from);
            to_picker.set('select', to);
          }
        };
      }
    }
})();
<|endoftext|>


<commit_before>import React, {Component, PropTypes} from 'react';
import Relay from 'react-relay';
import PageTitle from '../PageTitle';
import MappedMessage from '../MappedMessage';
import { FormattedMessage, defineMessages, injectIntl, intlShape } from 'react-intl';
import Tags from './Tags';
import {Link} from 'react-router';
import TextField from 'material-ui/TextField';
import Checkbox from 'material-ui/Checkbox';
import FlatButton from 'material-ui/FlatButton';
import MdCreate from 'react-icons/lib/md/create';
import {Card, CardActions, CardHeader, CardTitle, CardText} from 'material-ui/Card';
import IconButton from 'material-ui/IconButton';
import MDEdit from 'react-icons/lib/md/edit';
import MDChevronRight from 'react-icons/lib/md/chevron-right';
import UpdateTeamMutation from '../../relay/UpdateTeamMutation';
import Message from '../Message';
import CreateContactMutation from '../../relay/CreateContactMutation';
import UpdateContactMutation from '../../relay/UpdateContactMutation';
import CreateProject from '../project/CreateProject';
import Can from '../Can';
import CheckContext from '../../CheckContext';
import ContentColumn from '../layout/ContentColumn';
import {bemClass} from '../../helpers';
import ParsedText from '../ParsedText';

const messages = defineMessages({
  editError: {
    id: 'teamComponent.editError',
    defaultMessage: 'Sorry, could not edit the team',
  },
  editSuccess: {
    id: 'teamComponent.editSuccess',
    defaultMessage: 'Team information updated successfully!',
  },
  changeAvatar: {
    id: 'teamComponent.changeAvatar',
    defaultMessage: "You can't change this right now, but we're hard at work to enable it soon!",
  },
  teamName: {
    id: 'teamComponent.teamName',
    defaultMessage: 'Team name',
  },
  teamDescription: {
    id: 'teamComponent.teamDescription',
    defaultMessage: 'Team description',
  },
  location: {
    id: 'teamComponent.location',
    defaultMessage: 'Location',
  },
  phone: {
    id: 'teamComponent.phone',
    defaultMessage: 'Phone number',
  },
  website: {
    id: 'teamComponent.website',
    defaultMessage: 'Website',
  },
  slackWebhook: {
    id: 'teamComponent.slackWebhook',
    defaultMessage: 'Slack webhook',
  },
  slackChannel: {
    id: 'teamComponent.slackChannel',
    defaultMessage: 'Slack default #channel',
  },
  verificationTeam: {
    id: 'teamComponent.verificationTeam',
    defaultMessage: 'Verification Team',
  },
  bridge_verificationTeam: {
    id: 'bridge.teamComponent.verificationTeam',
    defaultMessage: 'Translation Team',
  },
  verificationProjects: {
    id: 'teamComponent.title',
    defaultMessage: 'Verification Projects',
  },
  bridge_verificationProjects: {
    id: 'bridge.teamComponent.title',
    defaultMessage: 'Translation Projects',
  },
});

class TeamComponent extends Component {
  constructor(props) {
    super(props);
    const team = this.props.team, contact = team.contacts.edges[0] || {node: {}};
    this.state = {
      message: null,
      isEditing: false,
      submitDisabled: false,
      values: {
        name: team.name,
        description: team.description,
        slackNotificationsEnabled: team.get_slack_notifications_enabled,
        slackWebhook: team.get_slack_webhook,
        slackChannel: team.get_slack_channel,
        contact_location: contact.node.location,
        contact_phone: contact.node.phone,
        contact_web: contact.node.web,
      },
    };
  }

  setContextTeam() {
    const context = new CheckContext(this);
    const store = context.getContextStore();
    const team = this.props.team;

    if (!store.team || store.team.slug != team.slug) {
      context.setContextStore({team});
      const path = `/${team.slug}`;
      store.history.push(path);
    }
  }

  componentDidMount() {
    this.setContextTeam();
    this.firstTimeFocusProjectInput();
  }

  componentDidUpdate() {
    this.setContextTeam();
  }

  cancelEditTeam(e) {
    e.preventDefault();
    this.setState({isEditing: false});
  }

  firstTimeFocusProjectInput() {
    const projectList = document.querySelector('.team__projects-list');
    const projectInput = document.querySelector('#create-project-title');

    if (projectInput && projectList.innerHTML === '') {
      projectInput.focus();
    }
  }

  editTeamInfo() {
    const that = this;

    const onFailure = transaction => {
      const error = transaction.getError();
      let message = that.props.intl.formatMessage(messages.editError);
      try {
        const json = JSON.parse(error.source);
        if (json.error) {
          message = json.error;
        }
      } catch (e) {}
      that.setState({message, submitDisabled: false});
    };

    const onSuccess = response => {
      this.setState({
        message: that.props.intl.formatMessage(messages.editSuccess),
        isEditing: false,
        submitDisabled: false,
      });
    };

    const values = that.state.values;

    if (!that.state.submitDisabled) {
      Relay.Store.commitUpdate(
        new UpdateTeamMutation({
          name: values.name,
          description: values.description,
          set_slack_notifications_enabled: values.slackNotificationsEnabled,
          set_slack_webhook: values.slackWebhook,
          set_slack_channel: values.slackChannel,
          contact: JSON.stringify({
            location: values.contact_location,
            phone: values.contact_phone,
            web: values.contact_web,
          }),
          id: that.props.team.id,
        }),
        {onSuccess, onFailure}
      );
      that.setState({submitDisabled: true});
    }
  }

  handleEditTeam() {
    this.editTeamInfo();
  }

  handleEntreEditTeamNameAndDescription(e) {
    this.setState({isEditing: true});
    e.preventDefault();
  }

  handleChange(key, e) {
    let value = e.target.value;
    if (e.target.type === 'checkbox' && !e.target.checked) {
      value = '0';
    }
    const values = Object.assign({}, this.state.values);
    values[key] = value;
    this.setState({values});
  }

  render() {
    const team = this.props.team;
    const isEditing = this.state.isEditing;
    const contact = team.contacts.edges[0];
    const contactInfo = [];

    if (contact) {
      if (!!contact.node.location) {
        contactInfo.push(<ParsedText text={contact.node.location} />);
      }

      if (!!contact.node.phone) {
        contactInfo.push(<ParsedText text={contact.node.phone} />);
      }

      if (!!contact.node.web) {
        contactInfo.push(<ParsedText text={contact.node.web} />);
      }
    }

    return (
      <PageTitle prefix={false} skipTeam={false} team={team}>

          <Card className="team__profile team__profile--editing">
            <ContentColumn>
              <Message message={this.state.message} />
              {(() => {
                if (isEditing) {
                  return (

                      <CardText>

                          <TextField
                            className="team__name-input"
                            id="team__name-container"
                            defaultValue={team.name}
                            floatingLabelText={this.props.intl.formatMessage(messages.teamName)}
                            onChange={this.handleChange.bind(this, 'name')}
                            fullWidth
                          />

                          <TextField
                            className="team__description"
                            id="team__description-container"
                            defaultValue={team.description}
                            floatingLabelText={this.props.intl.formatMessage(messages.teamDescription)}
                            onChange={this.handleChange.bind(this, 'description')}
                            fullWidth
                            multiLine={true}
                            rows={1}
                            rowsMax={4}
                          />

                          <TextField
                            className="team__location"
                            id="team__location-container"
                            defaultValue={contact ? contact.node.location : ''}
                            floatingLabelText={this.props.intl.formatMessage(messages.location)}
                            onChange={this.handleChange.bind(this, 'contact_location')}
                            fullWidth
                          />

                          <TextField
                            className="team__phone"
                            id="team__phone-container"
                            defaultValue={contact ? contact.node.phone : ''}
                            floatingLabelText={this.props.intl.formatMessage(messages.phone)}
                            onChange={this.handleChange.bind(this, 'contact_phone')}
                            fullWidth
                          />

                          <TextField
                            className="team__location-name-input"
                            id="team__link-container"
                            defaultValue={contact ? contact.node.web : ''}
                            floatingLabelText={this.props.intl.formatMessage(messages.website)}
                            onChange={this.handleChange.bind(this, 'contact_web')}
                            fullWidth
                          />

                          <Checkbox
                            label={<FormattedMessage id="teamComponent.slackNotificationsEnabled"defaultMessage="Enable Slack notifications" />}
                            defaultChecked={team.get_slack_notifications_enabled === '1'}
                            onCheck={this.handleChange.bind(this, 'slackNotificationsEnabled')}
                            id="team__settings-slack-notifications-enabled"
                            value="1"
                          />

                          <TextField
                            id="team__settings-slack-webhook"
                            defaultValue={team.get_slack_webhook}
                            floatingLabelText={this.props.intl.formatMessage(messages.slackWebhook)}
                            onChange={this.handleChange.bind(this, 'slackWebhook')}
                            fullWidth
                          />

                          <TextField
                            id="team__settings-slack-channel"
                            defaultValue={team.get_slack_channel}
                            floatingLabelText={this.props.intl.formatMessage(messages.slackChannel)}
                            onChange={this.handleChange.bind(this, 'slackChannel')}
                            fullWidth
                          />

                      </CardText>

                      <CardActions className="team__profile-card-actions">
                        <FlatButton
                          className="team__cancel-button"
                          label={<FormattedMessage id="teamComponent.cancelButton"defaultMessage="Cancel" />}
                          onClick={this.cancelEditTeam.bind(this)}
                        />

                        <FlatButton
                          className="team__save-button"
                          label={<FormattedMessage id="teamComponent.saveButton"defaultMessage="Save"disabled={this.state.submitDisabled} />}
                          primary
                          onClick={this.handleEditTeam.bind(this)}
                        />
                      </CardActions>

                  );
                }

                return (

                        <div
                          className="team__avatar"
                          style={{ 'background-image': `url(${team.avatar})` }}
                          title={this.props.intl.formatMessage(messages.changeAvatar)}
                        />

                            {team.name}

                              {<ParsedText text={team.description} /> ||
                                <MappedMessage msgObj={messages} msgKey="verificationTeam" />}

                          {contactInfo}

                      <Can permissions={team.permissions} permission="update Team">
                        <IconButton
                          className="team__edit-button"
                          tooltip={<FormattedMessage id="teamComponent.editButton" defaultMessage="Edit profile" />}
                          tooltipPosition="top-center"
                          onTouchTap={this.handleEntreEditTeamNameAndDescription.bind(this)}
                        >
                          <MDEdit />
                        </IconButton>
                      </Can>

                );
              })()}
            </ContentColumn>
          </Card>

          <ContentColumn>
            <Card>
              <CardHeader titleStyle={{fontSize: "20px", lineHeight: "32px"}} title={<MappedMessage msgObj={messages} msgKey="verificationProjects" />} />

                {team.projects.edges
                  .sortp((a, b) => a.node.title.localeCompare(b.node.title))
                  .map(p => (

                      <Link to={`/${team.slug}/project/${p.node.dbid}`} className="team__project-link">
                        {p.node.title} <MDChevronRight className="arrow" />
                      </Link>

                  ))}

              <Can permissions={team.permissions} permission="create Project">
                <CreateProject className="team__new-project-input" team={team} />
              </Can>
            </Card>
          </ContentColumn>

      </PageTitle>
    );
  }
}

TeamComponent.propTypes = {
  intl: intlShape.isRequired,
};

TeamComponent.contextTypes = {
  store: React.PropTypes.object,
};

export default injectIntl(TeamComponent);
<commit_msg>#6101 Hide projects when editing the team<commit_after>import React, {Component, PropTypes} from 'react';
import Relay from 'react-relay';
import PageTitle from '../PageTitle';
import MappedMessage from '../MappedMessage';
import { FormattedMessage, defineMessages, injectIntl, intlShape } from 'react-intl';
import Tags from './Tags';
import {Link} from 'react-router';
import TextField from 'material-ui/TextField';
import Checkbox from 'material-ui/Checkbox';
import FlatButton from 'material-ui/FlatButton';
import MdCreate from 'react-icons/lib/md/create';
import {Card, CardActions, CardHeader, CardTitle, CardText} from 'material-ui/Card';
import IconButton from 'material-ui/IconButton';
import MDEdit from 'react-icons/lib/md/edit';
import MDChevronRight from 'react-icons/lib/md/chevron-right';
import UpdateTeamMutation from '../../relay/UpdateTeamMutation';
import Message from '../Message';
import CreateContactMutation from '../../relay/CreateContactMutation';
import UpdateContactMutation from '../../relay/UpdateContactMutation';
import CreateProject from '../project/CreateProject';
import Can from '../Can';
import CheckContext from '../../CheckContext';
import ContentColumn from '../layout/ContentColumn';
import {bemClass} from '../../helpers';
import ParsedText from '../ParsedText';

const messages = defineMessages({
  editError: {
    id: 'teamComponent.editError',
    defaultMessage: 'Sorry, could not edit the team',
  },
  editSuccess: {
    id: 'teamComponent.editSuccess',
    defaultMessage: 'Team information updated successfully!',
  },
  changeAvatar: {
    id: 'teamComponent.changeAvatar',
    defaultMessage: "You can't change this right now, but we're hard at work to enable it soon!",
  },
  teamName: {
    id: 'teamComponent.teamName',
    defaultMessage: 'Team name',
  },
  teamDescription: {
    id: 'teamComponent.teamDescription',
    defaultMessage: 'Team description',
  },
  location: {
    id: 'teamComponent.location',
    defaultMessage: 'Location',
  },
  phone: {
    id: 'teamComponent.phone',
    defaultMessage: 'Phone number',
  },
  website: {
    id: 'teamComponent.website',
    defaultMessage: 'Website',
  },
  slackWebhook: {
    id: 'teamComponent.slackWebhook',
    defaultMessage: 'Slack webhook',
  },
  slackChannel: {
    id: 'teamComponent.slackChannel',
    defaultMessage: 'Slack default #channel',
  },
  verificationTeam: {
    id: 'teamComponent.verificationTeam',
    defaultMessage: 'Verification Team',
  },
  bridge_verificationTeam: {
    id: 'bridge.teamComponent.verificationTeam',
    defaultMessage: 'Translation Team',
  },
  verificationProjects: {
    id: 'teamComponent.title',
    defaultMessage: 'Verification Projects',
  },
  bridge_verificationProjects: {
    id: 'bridge.teamComponent.title',
    defaultMessage: 'Translation Projects',
  },
});

class TeamComponent extends Component {
  constructor(props) {
    super(props);
    const team = this.props.team, contact = team.contacts.edges[0] || {node: {}};
    this.state = {
      message: null,
      isEditing: false,
      submitDisabled: false,
      values: {
        name: team.name,
        description: team.description,
        slackNotificationsEnabled: team.get_slack_notifications_enabled,
        slackWebhook: team.get_slack_webhook,
        slackChannel: team.get_slack_channel,
        contact_location: contact.node.location,
        contact_phone: contact.node.phone,
        contact_web: contact.node.web,
      },
    };
  }

  setContextTeam() {
    const context = new CheckContext(this);
    const store = context.getContextStore();
    const team = this.props.team;

    if (!store.team || store.team.slug != team.slug) {
      context.setContextStore({team});
      const path = `/${team.slug}`;
      store.history.push(path);
    }
  }

  componentDidMount() {
    this.setContextTeam();
    this.firstTimeFocusProjectInput();
  }

  componentDidUpdate() {
    this.setContextTeam();
  }

  cancelEditTeam(e) {
    e.preventDefault();
    this.setState({isEditing: false});
  }

  firstTimeFocusProjectInput() {
    const projectList = document.querySelector('.team__projects-list');
    const projectInput = document.querySelector('#create-project-title');

    if (projectInput && projectList.innerHTML === '') {
      projectInput.focus();
    }
  }

  editTeamInfo() {
    const that = this;

    const onFailure = transaction => {
      const error = transaction.getError();
      let message = that.props.intl.formatMessage(messages.editError);
      try {
        const json = JSON.parse(error.source);
        if (json.error) {
          message = json.error;
        }
      } catch (e) {}
      that.setState({message, submitDisabled: false});
    };

    const onSuccess = response => {
      this.setState({
        message: that.props.intl.formatMessage(messages.editSuccess),
        isEditing: false,
        submitDisabled: false,
      });
    };

    const values = that.state.values;

    if (!that.state.submitDisabled) {
      Relay.Store.commitUpdate(
        new UpdateTeamMutation({
          name: values.name,
          description: values.description,
          set_slack_notifications_enabled: values.slackNotificationsEnabled,
          set_slack_webhook: values.slackWebhook,
          set_slack_channel: values.slackChannel,
          contact: JSON.stringify({
            location: values.contact_location,
            phone: values.contact_phone,
            web: values.contact_web,
          }),
          id: that.props.team.id,
        }),
        {onSuccess, onFailure}
      );
      that.setState({submitDisabled: true});
    }
  }

  handleEditTeam() {
    this.editTeamInfo();
  }

  handleEntreEditTeamNameAndDescription(e) {
    this.setState({isEditing: true});
    e.preventDefault();
  }

  handleChange(key, e) {
    let value = e.target.value;
    if (e.target.type === 'checkbox' && !e.target.checked) {
      value = '0';
    }
    const values = Object.assign({}, this.state.values);
    values[key] = value;
    this.setState({values});
  }

  render() {
    const team = this.props.team;
    const isEditing = this.state.isEditing;
    const contact = team.contacts.edges[0];
    const contactInfo = [];

    if (contact) {
      if (!!contact.node.location) {
        contactInfo.push(<ParsedText text={contact.node.location} />);
      }

      if (!!contact.node.phone) {
        contactInfo.push(<ParsedText text={contact.node.phone} />);
      }

      if (!!contact.node.web) {
        contactInfo.push(<ParsedText text={contact.node.web} />);
      }
    }

    return (
      <PageTitle prefix={false} skipTeam={false} team={team}>

          <Card className="team__profile team__profile--editing">
            <ContentColumn>
              <Message message={this.state.message} />
              {(() => {
                if (isEditing) {
                  return (

                      <CardText>

                          <TextField
                            className="team__name-input"
                            id="team__name-container"
                            defaultValue={team.name}
                            floatingLabelText={this.props.intl.formatMessage(messages.teamName)}
                            onChange={this.handleChange.bind(this, 'name')}
                            fullWidth
                          />

                          <TextField
                            className="team__description"
                            id="team__description-container"
                            defaultValue={team.description}
                            floatingLabelText={this.props.intl.formatMessage(messages.teamDescription)}
                            onChange={this.handleChange.bind(this, 'description')}
                            fullWidth
                            multiLine={true}
                            rows={1}
                            rowsMax={4}
                          />

                          <TextField
                            className="team__location"
                            id="team__location-container"
                            defaultValue={contact ? contact.node.location : ''}
                            floatingLabelText={this.props.intl.formatMessage(messages.location)}
                            onChange={this.handleChange.bind(this, 'contact_location')}
                            fullWidth
                          />

                          <TextField
                            className="team__phone"
                            id="team__phone-container"
                            defaultValue={contact ? contact.node.phone : ''}
                            floatingLabelText={this.props.intl.formatMessage(messages.phone)}
                            onChange={this.handleChange.bind(this, 'contact_phone')}
                            fullWidth
                          />

                          <TextField
                            className="team__location-name-input"
                            id="team__link-container"
                            defaultValue={contact ? contact.node.web : ''}
                            floatingLabelText={this.props.intl.formatMessage(messages.website)}
                            onChange={this.handleChange.bind(this, 'contact_web')}
                            fullWidth
                          />

                          <Checkbox
                            label={<FormattedMessage id="teamComponent.slackNotificationsEnabled"defaultMessage="Enable Slack notifications" />}
                            defaultChecked={team.get_slack_notifications_enabled === '1'}
                            onCheck={this.handleChange.bind(this, 'slackNotificationsEnabled')}
                            id="team__settings-slack-notifications-enabled"
                            value="1"
                          />

                          <TextField
                            id="team__settings-slack-webhook"
                            defaultValue={team.get_slack_webhook}
                            floatingLabelText={this.props.intl.formatMessage(messages.slackWebhook)}
                            onChange={this.handleChange.bind(this, 'slackWebhook')}
                            fullWidth
                          />

                          <TextField
                            id="team__settings-slack-channel"
                            defaultValue={team.get_slack_channel}
                            floatingLabelText={this.props.intl.formatMessage(messages.slackChannel)}
                            onChange={this.handleChange.bind(this, 'slackChannel')}
                            fullWidth
                          />

                      </CardText>

                      <CardActions className="team__profile-card-actions">
                        <FlatButton
                          className="team__cancel-button"
                          label={<FormattedMessage id="teamComponent.cancelButton"defaultMessage="Cancel" />}
                          onClick={this.cancelEditTeam.bind(this)}
                        />

                        <FlatButton
                          className="team__save-button"
                          label={<FormattedMessage id="teamComponent.saveButton"defaultMessage="Save"disabled={this.state.submitDisabled} />}
                          primary
                          onClick={this.handleEditTeam.bind(this)}
                        />
                      </CardActions>

                  );
                }

                return (

                        <div
                          className="team__avatar"
                          style={{ 'background-image': `url(${team.avatar})` }}
                          title={this.props.intl.formatMessage(messages.changeAvatar)}
                        />

                            {team.name}

                              {<ParsedText text={team.description} /> ||
                                <MappedMessage msgObj={messages} msgKey="verificationTeam" />}

                          {contactInfo}

                      <Can permissions={team.permissions} permission="update Team">
                        <IconButton
                          className="team__edit-button"
                          tooltip={<FormattedMessage id="teamComponent.editButton" defaultMessage="Edit profile" />}
                          tooltipPosition="top-center"
                          onTouchTap={this.handleEntreEditTeamNameAndDescription.bind(this)}
                        >
                          <MDEdit />
                        </IconButton>
                      </Can>

                );
              })()}
            </ContentColumn>
          </Card>

          {(() => {
            if (!isEditing) {
              return(
                <ContentColumn>
                  <Card>
                    <CardHeader titleStyle={{fontSize: "20px", lineHeight: "32px"}} title={<MappedMessage msgObj={messages} msgKey="verificationProjects" />} />

                      {team.projects.edges
                        .sortp((a, b) => a.node.title.localeCompare(b.node.title))
                        .map(p => (

                            <Link to={`/${team.slug}/project/${p.node.dbid}`} className="team__project-link">
                              {p.node.title} <MDChevronRight className="arrow" />
                            </Link>

                        ))}

                    <Can permissions={team.permissions} permission="create Project">
                      <CreateProject className="team__new-project-input" team={team} />
                    </Can>
                  </Card>
                </ContentColumn>
              );
            }
          })()}

      </PageTitle>
    );
  }
}

TeamComponent.propTypes = {
  intl: intlShape.isRequired,
};

TeamComponent.contextTypes = {
  store: React.PropTypes.object,
};

export default injectIntl(TeamComponent);
<|endoftext|>


<commit_before>let basicFeatures = {
    "Channel": {
        unique: {
            "start": "Point",
            "end": "Point"
        },
        heritable: {
            "channelWidth": "Float",
            "height": "Float"
        },
        defaults: {
            "channelWidth": .80 * 1000,
            "height": .1 * 1000
        },
        minimum: {
            "channelWidth": 3,
            "height": 10,
        },
        maximum: {
            "channelWidth": 2000,
            "height": 1200,
        }
    },
    "Chamber": {
        unique: {
            "start": "Point",
            "end": "Point"
        },
        heritable: {
            "borderWidth": "Float",
            "height": "Float"
        },
        defaults: {
            "borderWidth": .41 * 1000,
            "height": .1 * 1000
        },
        minimum: {
            "borderWidth": 10,
            "height": 10,
        },
        maximum: {
            "borderWidth": 2000,
            "height": 1200,
        }
    },
    "Node": {
        unique: {
            "position": "Point",
        },
        heritable: {
            "radius1": "Float",
            "radius2": "Float",
            "height": "Float",
            "width": "Float",
            "length": "Float"
        },
        defaults: {
            "radius1": 0,
            "radius2": 0,
            "width": 0,
            "length": 0,
            "height": 0
        },
        minimum: {
            "radius1": 0,
            "radius2": 0,
            "height": 10
        },
        maximum: {
            "radius1": 200,
            "radius2": 200,
            "height": 1200
        }
    },
    "CircleValve": {
        unique: {
            "position": "Point",
        },
        heritable: {
            "radius1": "Float",
            "radius2": "Float",
            "height": "Float"
        },
        defaults: {
            "radius1": 1.4 * 1000,
            "radius2": 1.2 * 1000,
            "height": .8 * 1000
        },
        minimum: {
            "radius1": 10,
            "radius2": 10,
            "height": 10
        },
        maximum: {
            "radius1": 2000,
            "radius2": 2000,
            "height": 1200
        }
    },
    "Valve3D": {
        unique: {
            "position": "Point"
        },
        heritable: {
            "orientation": "String",
            "valveRadius": "Float",
            "height": "Float",
            "gap": "Float",
            "width": "Float",
            "length": "Float"
        },
        defaults: {
            "orientation": "V",
            "valveRadius": 1.2 * 1000,
            "height": .8 * 1000,
            "gap": 0.6 * 1000,
            "width": 2.4 * 1000,
            "length": 2.4 * 1000
        },
        minimum: {
          //  "orientation": "V",
            "valveRadius": .1 * 100,
            "height": .1 * 100,
            "gap": .5 * 10
        },
        maximum: {
        //    "orientation": "H",
            "valveRadius": .2 * 10000,
            "height": 1.2 * 1000,
            "gap": .1 * 10000
        }
    },

    "Via": {
        unique: {
            "position": "Point",
        },
        heritable: {
            "radius1": "Float",
            "radius2": "Float",
            "height": "Float"
        },
        defaults: {
            "radius1": .8 * 1000,
            "radius2": .7 * 1000,
            "height": 1.1 * 1000
        },
        minimum: {
            "radius1": 10,
            "radius2": 10,
            "height": 10
        },
        maximum: {
            "radius1": 2000,
            "radius2": 2000,
            "height": 1200
        }
    },
    "Port": {
        unique: {
            "position": "Point",
        },
        heritable: {
            "portRadius": "Float",
            "height": "Float"
        },
        defaults: {
            "portRadius": .7 * 1000,
           // "radius2": .7 * 1000,
            "height": 1.1 * 1000
        },
        minimum: {
            "portRadius": .8 * 10,
         //   "radius2": 10,
            "height": 10
        },
        maximum: {
            "portRadius": 2000,
        //    "radius2": 2000,
            "height": 1200
        }
    },
    "DiamondReactionChamber": {
        unique: {
            "position": "Point",
        },
        heritable: {
            "orientation": "String",
            "channelWidth": "Float",
            "length": "Float",
            "width": "Float",
            "height": "Float"
        },
        defaults: {
            "orientation": "H",
            "channelWidth": .75 * 1000,
            "width": 1.23 * 1000,
            "length": 4.92 * 1000,
            "height": .1 * 1000
        },
        minimum: {
            "channelWidth": 10,
            "width": 30,
            "length": 120,
            "height": 10,
        },
        maximum: {
            "channelWidth": 2000,
            "width": 6000,
            "length": 24 * 1000,
            "height": 1200,
        }
    },
    "Mixer": {
        unique: {
            "position": "Point",
        },
        heritable: {
            "bendSpacing": "Float",
            "numberOfBends": "Float",
            "channelWidth": "Float",
            "bendLength": "Float",
            "orientation": "String",
            "height": "Float"
        },
        defaults: {
            "channelWidth": .80 * 1000,
            "bendSpacing": 1.23 * 1000,
            "numberOfBends": 1,
            "orientation": "H",
            "bendLength": 2.46 * 1000,
            "height": .1 * 1000
        },
        minimum: {
            "channelWidth": 10,
            "bendSpacing": 10,
            "numberOfBends": 1,
            "orientation": "H",
            "bendLength": 10,
            "height": 10,
        },
        maximum: {
            "channelWidth": 2000,
            "bendSpacing": 6000,
            "numberOfBends": 20,
            "orientation": "H",
            "bendLength": 12 * 1000,
            "height": 1200,
        }
    },
    "Tree": {
        unique: {
            "position": "Point"
        },
        heritable: {
            "flowChannelWidth": "Float",
            "orientation": "String",
            "spacing": "Float",
            "leafs": "Float",
            "width": "Float",
            "length": "Float",
            "height": "Float",
            "direction": "String"
        },
        defaults: {
            "flowChannelWidth": .80 * 1000,
            "orientation": "H",
            "spacing": 1.23 * 1000,
            "leafs": 2,
            "width": 2.46 * 1000,
            "length": 2.46 * 1000,
            "height": .1 * 1000,
            "direction": "IN"
        },
        minimum: {
            "flowChannelWidth": 10,
            "spacing": 30,
            "leafs": 2,
            "width": 60,
            "length": 60,
            "height": 10
        },
        maximum: {
            "flowChannelWidth": 2000,
            "spacing": 6000,
            "leafs": 2,
            "width": 12 * 1000,
            "length": 12 * 1000,
            "height": 1200
        }
    },
    "CellTrapL": {
        unique: {
            "position": "Point"
        },
        heritable: {
            "chamberLength": "Float",
            "feedingChannelWidth": "Float",
            "orientation": "String",
            "chamberWidth": "Float",
            "numberOfChambers": "Float",
            "chamberSpacing": "Float",
            "height": "Float"
        },
        defaults: {
            "chamberLength": 1.2 * 1000,
            "feedingChannelWidth": .41 * 1000,
            "orientation": "H",
            "chamberWidth": 1.23 * 1000,
            "numberOfChambers": 3,
            "chamberSpacing": 2.46 * 1000,
            "height": .1 * 1000
        },
        minimum: {
            "chamberLength": 30,
            "feedingChannelWidth": 10,
            "chamberWidth": 30,
            "numberOfChambers": 1,
            "chamberSpacing": 60,
            "height": 10
        },
        maximum: {
            "chamberLength": 6000,
            "feedingChannelWidth": 2000,
            "chamberWidth": 6000,
            "numberOfChambers": 10,
            "chamberSpacing": 12 * 1000,
            "height": 1200
        }
    },
    "DropletGen": {
        unique: {
            "position": "Point"
        },
        heritable: {
            "orificeSize": "Float",
            "height": "Float"
        },
        defaults: {
            "orificeSize": .80 * 1000,
            "height": .1 * 1000
        },
        minimum: {
            "orificeSize": 10,
            "height": 10,
        },
        maximum: {
            "orificeSize": 2000,
            "height": 1200,
        }
    }
}

module.exports = basicFeatures;<commit_msg>Changed default channel width for diamond chambers<commit_after>let basicFeatures = {
    "Channel": {
        unique: {
            "start": "Point",
            "end": "Point"
        },
        heritable: {
            "channelWidth": "Float",
            "height": "Float"
        },
        defaults: {
            "channelWidth": .80 * 1000,
            "height": .1 * 1000
        },
        minimum: {
            "channelWidth": 3,
            "height": 10,
        },
        maximum: {
            "channelWidth": 2000,
            "height": 1200,
        }
    },
    "Chamber": {
        unique: {
            "start": "Point",
            "end": "Point"
        },
        heritable: {
            "borderWidth": "Float",
            "height": "Float"
        },
        defaults: {
            "borderWidth": .41 * 1000,
            "height": .1 * 1000
        },
        minimum: {
            "borderWidth": 10,
            "height": 10,
        },
        maximum: {
            "borderWidth": 2000,
            "height": 1200,
        }
    },
    "Node": {
        unique: {
            "position": "Point",
        },
        heritable: {
            "radius1": "Float",
            "radius2": "Float",
            "height": "Float",
            "width": "Float",
            "length": "Float"
        },
        defaults: {
            "radius1": 0,
            "radius2": 0,
            "width": 0,
            "length": 0,
            "height": 0
        },
        minimum: {
            "radius1": 0,
            "radius2": 0,
            "height": 10
        },
        maximum: {
            "radius1": 200,
            "radius2": 200,
            "height": 1200
        }
    },
    "CircleValve": {
        unique: {
            "position": "Point",
        },
        heritable: {
            "radius1": "Float",
            "radius2": "Float",
            "height": "Float"
        },
        defaults: {
            "radius1": 1.4 * 1000,
            "radius2": 1.2 * 1000,
            "height": .8 * 1000
        },
        minimum: {
            "radius1": 10,
            "radius2": 10,
            "height": 10
        },
        maximum: {
            "radius1": 2000,
            "radius2": 2000,
            "height": 1200
        }
    },
    "Valve3D": {
        unique: {
            "position": "Point"
        },
        heritable: {
            "orientation": "String",
            "valveRadius": "Float",
            "height": "Float",
            "gap": "Float",
            "width": "Float",
            "length": "Float"
        },
        defaults: {
            "orientation": "V",
            "valveRadius": 1.2 * 1000,
            "height": .8 * 1000,
            "gap": 0.6 * 1000,
            "width": 2.4 * 1000,
            "length": 2.4 * 1000
        },
        minimum: {
          //  "orientation": "V",
            "valveRadius": .1 * 100,
            "height": .1 * 100,
            "gap": .5 * 10
        },
        maximum: {
        //    "orientation": "H",
            "valveRadius": .2 * 10000,
            "height": 1.2 * 1000,
            "gap": .1 * 10000
        }
    },

    "Via": {
        unique: {
            "position": "Point",
        },
        heritable: {
            "radius1": "Float",
            "radius2": "Float",
            "height": "Float"
        },
        defaults: {
            "radius1": .8 * 1000,
            "radius2": .7 * 1000,
            "height": 1.1 * 1000
        },
        minimum: {
            "radius1": 10,
            "radius2": 10,
            "height": 10
        },
        maximum: {
            "radius1": 2000,
            "radius2": 2000,
            "height": 1200
        }
    },
    "Port": {
        unique: {
            "position": "Point",
        },
        heritable: {
            "portRadius": "Float",
            "height": "Float"
        },
        defaults: {
            "portRadius": .7 * 1000,
           // "radius2": .7 * 1000,
            "height": 1.1 * 1000
        },
        minimum: {
            "portRadius": .8 * 10,
         //   "radius2": 10,
            "height": 10
        },
        maximum: {
            "portRadius": 2000,
        //    "radius2": 2000,
            "height": 1200
        }
    },
    "DiamondReactionChamber": {
        unique: {
            "position": "Point",
        },
        heritable: {
            "orientation": "String",
            "channelWidth": "Float",
            "length": "Float",
            "width": "Float",
            "height": "Float"
        },
        defaults: {
            "orientation": "H",
            "channelWidth": .80 * 1000,
            "width": 1.23 * 1000,
            "length": 4.92 * 1000,
            "height": .1 * 1000
        },
        minimum: {
            "channelWidth": 10,
            "width": 30,
            "length": 120,
            "height": 10,
        },
        maximum: {
            "channelWidth": 2000,
            "width": 6000,
            "length": 24 * 1000,
            "height": 1200,
        }
    },
    "Mixer": {
        unique: {
            "position": "Point",
        },
        heritable: {
            "bendSpacing": "Float",
            "numberOfBends": "Float",
            "channelWidth": "Float",
            "bendLength": "Float",
            "orientation": "String",
            "height": "Float"
        },
        defaults: {
            "channelWidth": .80 * 1000,
            "bendSpacing": 1.23 * 1000,
            "numberOfBends": 1,
            "orientation": "H",
            "bendLength": 2.46 * 1000,
            "height": .1 * 1000
        },
        minimum: {
            "channelWidth": 10,
            "bendSpacing": 10,
            "numberOfBends": 1,
            "orientation": "H",
            "bendLength": 10,
            "height": 10,
        },
        maximum: {
            "channelWidth": 2000,
            "bendSpacing": 6000,
            "numberOfBends": 20,
            "orientation": "H",
            "bendLength": 12 * 1000,
            "height": 1200,
        }
    },
    "Tree": {
        unique: {
            "position": "Point"
        },
        heritable: {
            "flowChannelWidth": "Float",
            "orientation": "String",
            "spacing": "Float",
            "leafs": "Float",
            "width": "Float",
            "length": "Float",
            "height": "Float",
            "direction": "String"
        },
        defaults: {
            "flowChannelWidth": .80 * 1000,
            "orientation": "H",
            "spacing": 1.23 * 1000,
            "leafs": 2,
            "width": 2.46 * 1000,
            "length": 2.46 * 1000,
            "height": .1 * 1000,
            "direction": "IN"
        },
        minimum: {
            "flowChannelWidth": 10,
            "spacing": 30,
            "leafs": 2,
            "width": 60,
            "length": 60,
            "height": 10
        },
        maximum: {
            "flowChannelWidth": 2000,
            "spacing": 6000,
            "leafs": 2,
            "width": 12 * 1000,
            "length": 12 * 1000,
            "height": 1200
        }
    },
    "CellTrapL": {
        unique: {
            "position": "Point"
        },
        heritable: {
            "chamberLength": "Float",
            "feedingChannelWidth": "Float",
            "orientation": "String",
            "chamberWidth": "Float",
            "numberOfChambers": "Float",
            "chamberSpacing": "Float",
            "height": "Float"
        },
        defaults: {
            "chamberLength": 1.2 * 1000,
            "feedingChannelWidth": .41 * 1000,
            "orientation": "H",
            "chamberWidth": 1.23 * 1000,
            "numberOfChambers": 3,
            "chamberSpacing": 2.46 * 1000,
            "height": .1 * 1000
        },
        minimum: {
            "chamberLength": 30,
            "feedingChannelWidth": 10,
            "chamberWidth": 30,
            "numberOfChambers": 1,
            "chamberSpacing": 60,
            "height": 10
        },
        maximum: {
            "chamberLength": 6000,
            "feedingChannelWidth": 2000,
            "chamberWidth": 6000,
            "numberOfChambers": 10,
            "chamberSpacing": 12 * 1000,
            "height": 1200
        }
    },
    "DropletGen": {
        unique: {
            "position": "Point"
        },
        heritable: {
            "orificeSize": "Float",
            "height": "Float"
        },
        defaults: {
            "orificeSize": .80 * 1000,
            "height": .1 * 1000
        },
        minimum: {
            "orificeSize": 10,
            "height": 10,
        },
        maximum: {
            "orificeSize": 2000,
            "height": 1200,
        }
    }
}

module.exports = basicFeatures;<|endoftext|>


<commit_before>function runTest()
{
    var url = basePath + "commandLine/api/monitor.html";
    FBTest.openNewTab(url, function(win)
    {
        FBTest.enablePanels(["console", "script"], function()
        {
            var tasks = new FBTest.TaskList();
            tasks.push(monitor, win);
            tasks.push(unmonitor, win);
            tasks.run(FBTest.testDone);
        });
    });
}

function monitor(callback, win)
{
    var browser = FBTest.getCurrentTabBrowser();

    var listener =
    {
        onBreakpointAdded: function(bp)
        {
            DebuggerController.removeListener(browser, listener);

            FBTest.clearConsole();
            FBTest.compare(28, bp.lineNo, "The breakpoint must be created on the right line");
            FBTest.compare(2 /*BP_MONITOR*/, bp.type, "The breakpoint must be BP_MONITOR");

            FBTest.waitForDisplayedText("console", "Hello World!", () =>
            {
                var panel = FBTest.getPanel("console").panelNode;
                var rows = panel.getElementsByClassName("logRow");
                if (!FBTest.compare(2, rows.length, "There must be two logs"))
                {
                    callback();
                    return;
                }

                var row = rows[0];
                var link = row.getElementsByClassName("functionCallTitle")[0];
                FBTest.click(link);

                var box = row.getElementsByClassName("objectBox-functionCall")[0];
                var frames = box.getElementsByClassName("objectBox-stackFrame");
                if (FBTest.compare(2, frames.length, "There must be two stack frames"))
                {
                    FBTest.compare("onExecuteTest()monitor.html (line 29)",
                        frames[0].textContent,
                        "Proper frame must be displayed");

                    FBTest.compare("onclick(event=click clientX=0, clientY=0)" +
                        "testBut...te Test (line 1)", frames[1].textContent,
                        "Proper frame must be displayed");
                }

                callback();
            });

            FBTest.clickContentButton(win, "testButton");
        }
    }

    DebuggerController.addListener(browser, listener);

    FBTest.executeCommand("monitor(onExecuteTest)");
}

function unmonitor(callback, win)
{
    var browser = FBTest.getCurrentTabBrowser();

    var listener =
    {
        onBreakpointRemoved: function(bp)
        {
            DebuggerController.removeListener(browser, listener);

            FBTest.clearConsole();
            FBTest.compare(28, bp.lineNo, "Proper breakpoint must be removed");
            FBTest.compare(2 /*BP_MONITOR*/, bp.type, "The breakpoint must be BP_MONITOR");

            FBTest.waitForDisplayedText("console", "Hello World!", () =>
            {
                var panel = FBTest.getPanel("console").panelNode;
                var rows = panel.getElementsByClassName("logRow");
                FBTest.compare(1, rows.length, "There must be one log");

                callback();
            });

            FBTest.clickContentButton(win, "testButton");
        }
    }

    DebuggerController.addListener(browser, listener);

    FBTest.executeCommand("unmonitor(onExecuteTest)");
}
<commit_msg>FBTest: fix expected line numbers<commit_after>function runTest()
{
    var url = basePath + "commandLine/api/monitor.html";
    FBTest.openNewTab(url, function(win)
    {
        FBTest.enablePanels(["console", "script"], function()
        {
            var tasks = new FBTest.TaskList();
            tasks.push(monitor, win);
            tasks.push(unmonitor, win);
            tasks.run(FBTest.testDone);
        });
    });
}

function monitor(callback, win)
{
    var browser = FBTest.getCurrentTabBrowser();

    var listener =
    {
        onBreakpointAdded: function(bp)
        {
            DebuggerController.removeListener(browser, listener);

            FBTest.clearConsole();
            FBTest.compare(31, bp.lineNo, "The breakpoint must be created on the right line");
            FBTest.compare(2 /*BP_MONITOR*/, bp.type, "The breakpoint must be BP_MONITOR");

            FBTest.waitForDisplayedText("console", "Hello World!", () =>
            {
                var panel = FBTest.getPanel("console").panelNode;
                var rows = panel.getElementsByClassName("logRow");
                if (!FBTest.compare(2, rows.length, "There must be two logs"))
                {
                    callback();
                    return;
                }

                var row = rows[0];
                var link = row.getElementsByClassName("functionCallTitle")[0];
                FBTest.click(link);

                var box = row.getElementsByClassName("objectBox-functionCall")[0];
                var frames = box.getElementsByClassName("objectBox-stackFrame");
                if (FBTest.compare(2, frames.length, "There must be two stack frames"))
                {
                    FBTest.compare("onExecuteTest()monitor.html (line 32)",
                        frames[0].textContent,
                        "Proper frame must be displayed");

                    FBTest.compare("onclick(event=click clientX=0, clientY=0)" +
                        "testBut...te Test (line 1)", frames[1].textContent,
                        "Proper frame must be displayed");
                }

                callback();
            });

            FBTest.clickContentButton(win, "testButton");
        }
    }

    DebuggerController.addListener(browser, listener);

    FBTest.executeCommand("monitor(onExecuteTest)");
}

function unmonitor(callback, win)
{
    var browser = FBTest.getCurrentTabBrowser();

    var listener =
    {
        onBreakpointRemoved: function(bp)
        {
            DebuggerController.removeListener(browser, listener);

            FBTest.clearConsole();
            FBTest.compare(31, bp.lineNo, "Proper breakpoint must be removed");
            FBTest.compare(2 /*BP_MONITOR*/, bp.type, "The breakpoint must be BP_MONITOR");

            FBTest.waitForDisplayedText("console", "Hello World!", () =>
            {
                var panel = FBTest.getPanel("console").panelNode;
                var rows = panel.getElementsByClassName("logRow");
                FBTest.compare(1, rows.length, "There must be one log");

                callback();
            });

            FBTest.clickContentButton(win, "testButton");
        }
    }

    DebuggerController.addListener(browser, listener);

    FBTest.executeCommand("unmonitor(onExecuteTest)");
}
<|endoftext|>