<commit_before>const ValidationFail = require('../../Error/ValidationFail');
const Input = require('../../Input');
const assert = require('assert');
const TypeCheck = require('js-typecheck');
const BaseText = require('./BaseText');

/**
 * Hexadecimal input.
 *
 * ```javascript
 * const input = Input.create('myInput: hex', {size: 24});
 * input.setValue('ffff00');
 * ```
 *
 *
Property Summary

 *
 * Property Name | Description | Defined by Default | Default Value
 * --- | --- | :---: | :---:
 * size | optional maximum size of the value in bits | ::none:: | ::none::
 *
 * All properties including the inherited ones can be listed via
 * {@link registeredPropertyNames}
 *
 * @see https://en.wikipedia.org/wiki/Universally_unique_identifier
 */
class Hex extends BaseText{

  /**
   * Returns the current value in decimal
   *
   * @return {number}
   */
  decimalValue(){
    const currentValue = this.value();
    assert(Hex._isHexValue(currentValue), 'Current value is not hexadecimal');

    return parseInt(currentValue, 16);
  }

  /**
   * Sets the current value from a decimal number
   *
   * @param {number} value - decimal value
   */
  setValueFromDecimal(value){
    assert(TypeCheck.isNumber(value), 'Value needs to be a number');

    this.setValue(value.toString(16));
  }

  /**
   * Implements input's validations
   *
   * @param {null|number} at - index used when input has been created as a vector that
   * tells which value should be used
   * @return {Promise<*>} value held by the input based on the current context (at)
   * @protected
   */
  _validation(at){

    // calling super class validations
    return super._validation(at).then((value) => {

      // hex value checking
      if (!Hex._isHexValue(value)){
        throw new ValidationFail('Invalid hex value', Hex.errorCodes[0]);
      }
      // value size checking
      else if (this.property('size') && (value.length / 2) * 8 > this.property('size')){
        throw new ValidationFail('Value exceeds the maximum size allowed', Hex.errorCodes[1]);
      }

      return value;
    });
  }

  /**
   * Auxiliary method that returns a boolean telling if the value is a valid
   * Hexadecimal value.
   *
   * @param {string} value - string containing the hex value
   * @return {boolean}
   * @private
   */
  static _isHexValue(value){
    return (TypeCheck.isString(value) && this._uuidFormatRegEx.test(value));
  }

  static errorCodes = [
    '1747c406-2a14-4d0f-8a1d-1c554763e8a3',
    '0f8d2885-a4ac-4b7f-bb5b-32466c85363a',
  ];
}

Hex._uuidFormatRegEx = /^[0-9a-fA-F]+$/;

// registering the input
Input.registerInput(Hex);

// registering properties
Input.registerProperty(Hex, 'size');

module.exports = Hex;
<commit_msg>removed invalid comment<commit_after>const ValidationFail = require('../../Error/ValidationFail');
const Input = require('../../Input');
const assert = require('assert');
const TypeCheck = require('js-typecheck');
const BaseText = require('./BaseText');

/**
 * Hexadecimal input.
 *
 * ```javascript
 * const input = Input.create('myInput: hex', {size: 24});
 * input.setValue('ffff00');
 * ```
 *
 *
Property Summary

 *
 * Property Name | Description | Defined by Default | Default Value
 * --- | --- | :---: | :---:
 * size | optional maximum size of the value in bits | ::none:: | ::none::
 *
 * All properties including the inherited ones can be listed via
 * {@link registeredPropertyNames}
 */
class Hex extends BaseText{

  /**
   * Returns the current value in decimal
   *
   * @return {number}
   */
  decimalValue(){
    const currentValue = this.value();
    assert(Hex._isHexValue(currentValue), 'Current value is not hexadecimal');

    return parseInt(currentValue, 16);
  }

  /**
   * Sets the current value from a decimal number
   *
   * @param {number} value - decimal value
   */
  setValueFromDecimal(value){
    assert(TypeCheck.isNumber(value), 'Value needs to be a number');

    this.setValue(value.toString(16));
  }

  /**
   * Implements input's validations
   *
   * @param {null|number} at - index used when input has been created as a vector that
   * tells which value should be used
   * @return {Promise<*>} value held by the input based on the current context (at)
   * @protected
   */
  _validation(at){

    // calling super class validations
    return super._validation(at).then((value) => {

      // hex value checking
      if (!Hex._isHexValue(value)){
        throw new ValidationFail('Invalid hex value', Hex.errorCodes[0]);
      }
      // value size checking
      else if (this.property('size') && (value.length / 2) * 8 > this.property('size')){
        throw new ValidationFail('Value exceeds the maximum size allowed', Hex.errorCodes[1]);
      }

      return value;
    });
  }

  /**
   * Auxiliary method that returns a boolean telling if the value is a valid
   * Hexadecimal value.
   *
   * @param {string} value - string containing the hex value
   * @return {boolean}
   * @private
   */
  static _isHexValue(value){
    return (TypeCheck.isString(value) && this._uuidFormatRegEx.test(value));
  }

  static errorCodes = [
    '1747c406-2a14-4d0f-8a1d-1c554763e8a3',
    '0f8d2885-a4ac-4b7f-bb5b-32466c85363a',
  ];
}

Hex._uuidFormatRegEx = /^[0-9a-fA-F]+$/;

// registering the input
Input.registerInput(Hex);

// registering properties
Input.registerProperty(Hex, 'size');

module.exports = Hex;
<|endoftext|>


<commit_before>import React, { PropTypes } from 'react';
import { Text, View, StyleSheet } from 'react-native';
import TopBar from '../components/TopBar';
import CharacteristicList from '../components/CharacteristicList';
import Bluetooth from 'react-native-bluetooth';
import { getAppState, setAppState } from '../lib/GlobalState';

const ServiceDetail = React.createClass({
  propTypes: {
    navigator: PropTypes.func.isRequired,
  },

  getInitialState() {
    const { selectedService } = getAppState();
    this.unsubscribe = () => {};

    return {
      service: selectedService,
      error: null,
      characteristics: [],
    };
  },

  componentWillMount() {
    Bluetooth.discoverCharacteristics(this.state.service, null, characteristic => {
      this.setState({
        characteristics: [...this.state.characteristics, characteristic]
      });
    })
    .then(unsubscribe => this.unsubscribe = unsubscribe)
      .catch(error => {
        this.setState({
          error: error,
        });
      });
  },

  componentWillUnmount() {
    this.unsubscribe();

    setAppState({
      selectedService: null,
    });
  },

  characteristicSelected(characteristic) {
    setAppState({
      selectedCharacteristic: characteristic,
    });

    console.log('Characteristic selected', characteristic);
    // this.props.navigator('CharacteristicDetail');
  },

  renderError() {
    if (this.state.error == null) return null;

    return (<Text style={styles.errorText}>{this.state.error}</Text>);
  },

  render() {
    return (
      <View style={styles.container}>
        <TopBar
          headerText={"Service - " + this.state.service.id}
          backAction={() => this.props.navigator('DeviceDetail')} />
        {this.renderError()}
        <View style={styles.listContainer}>
          <CharacteristicList
            characteristics={this.state.characteristics}
            selectCharacteristic={this.characteristicSelected} />
        </View>
      </View>
    );
  },
});

const styles = StyleSheet.create({
  errorText: {
    fontSize: 18,
    color: 'red',
  },
  container: {
    flex: 1,
  },
  listContainer: {
    flex: 1,
  },
});

export default ServiceDetail;
<commit_msg>Add a characteristic label on Services screen.<commit_after>import React, { PropTypes } from 'react';
import { Text, View, StyleSheet } from 'react-native';
import TopBar from '../components/TopBar';
import CharacteristicList from '../components/CharacteristicList';
import Bluetooth from 'react-native-bluetooth';
import { getAppState, setAppState } from '../lib/GlobalState';

const ServiceDetail = React.createClass({
  propTypes: {
    navigator: PropTypes.func.isRequired,
  },

  getInitialState() {
    const { selectedService } = getAppState();
    this.unsubscribe = () => {};

    return {
      service: selectedService,
      error: null,
      characteristics: [],
    };
  },

  componentWillMount() {
    Bluetooth.discoverCharacteristics(this.state.service, null, characteristic => {
      this.setState({
        characteristics: [...this.state.characteristics, characteristic]
      });
    })
    .then(unsubscribe => this.unsubscribe = unsubscribe)
      .catch(error => {
        this.setState({
          error: error,
        });
      });
  },

  componentWillUnmount() {
    this.unsubscribe();

    setAppState({
      selectedService: null,
    });
  },

  characteristicSelected(characteristic) {
    setAppState({
      selectedCharacteristic: characteristic,
    });

    console.log('Characteristic selected', characteristic);
    // this.props.navigator('CharacteristicDetail');
  },

  renderError() {
    if (this.state.error == null) return null;

    return (<Text style={styles.errorText}>{this.state.error}</Text>);
  },

  render() {
    return (
      <View style={styles.container}>
        <TopBar
          headerText={"Service Detail"}
          backAction={() => this.props.navigator('DeviceDetail')} />
        {this.renderError()}
        <Text style={styles.labelText}>Characteristics</Text>
        <View style={styles.listContainer}>
          <CharacteristicList
            characteristics={this.state.characteristics}
            selectCharacteristic={this.characteristicSelected} />
        </View>
      </View>
    );
  },
});

const styles = StyleSheet.create({
  errorText: {
    fontSize: 18,
    color: 'red',
  },
  labelText: {
    fontSize: 20,
    color: 'grey',
    marginLeft: 15,
  },
  container: {
    flex: 1,
  },
  listContainer: {
    flex: 1,
  },
});

export default ServiceDetail;
<|endoftext|>


<commit_before>'use strict';

angular.module('streama.videoPlayer').directive('streamaVideoPlayer', [
  'localStorageService', '$timeout', '$http', 'streamaVideoPlayerService', '$filter',
  function (localStorageService, $timeout, $http, streamaVideoPlayerService, $filter) {

    return {
      restrict: 'AE',
      templateUrl: 'streama-video-player.touch.html',
      scope: {
        options: '='
      },

      link: function ($scope, $elem, $attrs) {
				$scope.options = streamaVideoPlayerService.initOptions($scope.options);
				if(!$scope.options){
					console.error('There was an error initializing the player. Please refer to the error log.');
					return;
				}
				var video;
        var controlDisplayTimeout;
        var overlayTimeout;
        var volumeChangeTimeout;
        var currentTimeChangeTimeout;
				var currEpisode = null;
        var skipIntro = true;         //Userflag intro should be skipped
        var minimizeOnOutro = true;   //Userflag skip to next episode on outro
				var videoSrc = $scope.options.videoSrc.toString();
				var isAutoScrubberUpdate = true;

				$scope.getBackgroundStyle = getBackgroundStyle;
				$scope.changeEpisode = changeEpisode;
				$scope.selectSubtitle = selectSubtitle;
				$scope.showControls = showControls;
				$scope.toggleSelectEpisodes = toggleSelectEpisodes;
				$scope.createNewPlayerSession = createNewPlayerSession;
        $scope.toggleTextTrack = toggleTextTrack;
        $scope.playerVolumeToggle = playerVolumeToggle;
				$scope.play = play;
				$scope.togglePlay = togglePlay;
				$scope.pause = pause;
				$scope.closeVideo = closeVideo;
				$scope.toggleControls = toggleControls;
				$scope.toggleMobileOverlayBox = toggleMobileOverlayBox;
				$scope.clickVideo = clickVideo;
				$scope.fullScreen = toggleFullScreen;
				$scope.changeSubtitleSize = changeSubtitleSize;
				$scope.next = $scope.options.onNext;
				$scope.isMobileControlsVisible = true;
				$scope.isInitialized = false;
				$scope.loading = true;
				$scope.initialPlay = false;

				$scope.mobileOverlayBox = {
					isVisble: false,
					type: ''
				};

				$scope.verticalSlider1 = {
					value: 5,
					options: {
						floor: 0,
						ceil: 10,
						vertical: true
					}
				};

				if(!$scope.options.isExternalLink){
					$http.head(videoSrc)
						.success(function(){
							initDirective();
						})
						.error(function(data, status) {
							if(status == 406){
								$scope.options.onError('FILE_IN_FS_NOT_FOUND');
							}
						});
				}else{
					initDirective();
				}

				function initDirective() {
					$scope.isInitialized = true;

					$elem.addClass('nocursor');

					if(!$scope.options.isTouch){
						initMouseWheel();
					}
					streamaVideoPlayerService.initMousetrap(video, $scope, skipActivated, changeVolume);
					initExternalTriggers();
					initIsMobile();
					$scope.$on('$destroy', onDirectiveDestroy);
					$scope.$on('$stateChangeSuccess', onStateChangeSuccess);
					generateVolumeScrubberOptions();

					$timeout(function () {
						var $video = $elem.find('video');
						$video.bind("contextmenu",function(){return false;});
						video = $video[0];
						video.oncanplay = onVideoCanPlay;
						video.onwaiting = onVideoWaiting;
						video.onplaying = onVideoPlaying;
						video.onerror = onVideoError;
						video.ontimeupdate = onVideoTimeupdate;
						video.addEventListener('ended', onVideoEnded);
						selectSubtitle(getCurrentSubtitleTrack());
					});
				}

				function changeEpisode(episode) {
					$scope.options.onEpisodeChange(episode);
				}

				function selectSubtitle(subtitle) {
					_.forEach(video.textTracks, function(textTrack, key) {
						if(subtitle && textTrack.id === 'subtitle-' + subtitle.id) {
							textTrack.mode = 'showing';
						}
						else{
							textTrack.mode = 'hidden';
						}

					});

					$scope.options.onSubtitleSelect(subtitle);
					$scope.selectedSubtitleId = _.get(subtitle, 'id');
					localStorageService.set('selectedSubtitleLanguage', _.get(subtitle, 'subtitleSrcLang'));
				}

				function getCurrentSubtitleTrack() {
					return _.find($scope.options.subtitles, {id: $scope.options.currentSubtitle});
				}

        //$scope.controlsVisible = true;
        function showControls() {
          $elem.removeClass('nocursor');
          $timeout.cancel(controlDisplayTimeout);
          $timeout.cancel(overlayTimeout);
          $scope.controlsVisible = true;
          $scope.overlayVisible = false;

          controlDisplayTimeout = $timeout(function(){
            $scope.controlsVisible = false;

            if(!$scope.playing){
              overlayTimeout = $timeout(function () {
                if(!$scope.playing){
                  $scope.overlayVisible = true;
                }
              }, 5000);
            }else{
              $elem.addClass('nocursor');
            }

          }, 1000);
        }

				function generateScrupperOoptions(videoDuration) {
					$scope.scrubber = {
						model: 0,
						options: {
							floor: 0,
							ceil: videoDuration,
							step: 1,
							hideLimitLabels: true,
							hidePointerLabels: true,
							showSelectionBar: true,
							// translate: function(value) {
							// 	return $filter('streamaVideoTime')(value);
							// },
							onStart: function () {
								isAutoScrubberUpdate = false;
							},
							// onChange: function(id) {
							// },
							onEnd: function(sliderId, modelValue, highValue, pointerType) {
								video.currentTime = modelValue;
								$scope.scrubber.model = modelValue;
								isAutoScrubberUpdate = true;
								$scope.options.onScrub(video);
								// $scope.options.onTimeChange(slider, $scope.videoDuration);
							}
						}
					};
				}

				function generateVolumeScrubberOptions() {
					$scope.volumeLevel = localStorageService.get('volumeLevel') || 5;
					$scope.volume = {
						options: {
							floor: 0,
							ceil: 10,
							step: 0.1,
							// precision: 1,
							hideLimitLabels: true,
							hidePointerLabels: true,
							showSelectionBar: true,
							vertical: true,
							onChange: function (sliderId, modelValue, highValue, pointerType) {
								setVolume(modelValue);
							}
						// slide: function (e, slider) {
						// 	setVolume(slider);
						// 	angular.element('#playerVolumeSlider .ui-slider-handle').blur();
						// }
						}
					};
				}

				function closeVideo() {

					//If full screen is enabled, it will be canceled.
					if ($scope.isFullScreen == true) {
						$scope.fullScreen();
					}

					onDirectiveDestroy();
					$scope.options.onClose();
				}

				function toggleControls(){
					$scope.isMobileControlsVisible = !$scope.isMobileControlsVisible;
				}

				function clickVideo() {
					$scope.options.onVideoClick();
				}

				function toggleMobileOverlayBox(type) {
					$scope.mobileOverlayBox.isVisble = !$scope.mobileOverlayBox.isVisble;
					$scope.mobileOverlayBox.type = type;
					if($scope.mobileOverlayBox.isVisble){
						pause();
					}else{
						play();
					}
				}

				function changeSubtitleSize(subtitleSize) {
					$scope.options.subtitleSize = subtitleSize;
					localStorageService.set('subtitleSize', subtitleSize);
				}

				function toggleFullScreen() {
					var docElm;
					var docElmClose = document;
					if($scope.isMobile){
						docElm = video;
					}else{
						docElm = document.documentElement;
					}
					var isFullScreen = window.innerHeight == screen.height;
					if( !isFullScreen) {
						$scope.isFullScreen = true;
						if (docElm.requestFullscreen) {
							docElm.requestFullscreen();
						}
						else if (docElm.mozRequestFullScreen) {
							docElm.mozRequestFullScreen();
						}
						else if (docElm.webkitRequestFullScreen) {
							docElm.webkitRequestFullScreen();
						}
						else if (docElm.msRequestFullscreen) {
							docElm.msRequestFullscreen();
						}
					}

					else{
						$scope.isFullScreen = false;
						if (docElmClose.exitFullscreen) {
							docElmClose.exitFullscreen();
						}
						else if (docElmClose.mozCancelFullScreen) {
							docElmClose.mozCancelFullScreen();
						}
						else if (docElmClose.webkitExitFullscreen) {
							docElmClose.webkitExitFullscreen();
						}
						else if (docElmClose.msExitFullscreen) {
							docElmClose.msExitFullscreen();
						}
					}
				}

				function setVolume(value) {
					var volume = value / 10;
					video.volume = volume;
					if($scope.options.rememberVolumeSetting){
						localStorageService.set('volumeLevel', value);
					}
				}

				function playerVolumeToggle() {
					if($scope.volumeLevel == 0){
						$scope.volumeLevel = 5;
					}else{
						$scope.volumeLevel = 0;
					}
				}

        function initExternalTriggers() {
					$scope.$on('triggerVideoPlay', function (e, data) {
						$scope.play(data);
					});
					$scope.$on('triggerVideoPause', function (e, data) {
						$scope.pause(data);
					});
					$scope.$on('triggerVideoToggle', function (e, data) {
						if ($scope.playing) {
							$scope.pause(data);
						} else {
							$scope.play(data);
						}
					});
					$scope.$on('triggerVideoTimeChange', function (e, data) {
						video.currentTime = data.currentPlayerTime;
						$scope.scrubber.model = data.currentPlayerTime;
					});
				}

				function onStateChangeSuccess(e, toState) {
					if(toState.name != "player"){
						//If full screen is enabled, it will be canceled.
						if ($scope.isFullScreen = true) {
							$scope.fullScreen();
						}
					}
				}

				function onDirectiveDestroy() {

					//Disable these shortcut keys for other pages. They are re-initialized when the user opens the player again.
					Mousetrap.reset();

					console.log("destroy");
					video.pause();
					video.src = '';
					$elem.find('video').children('source').prop('src', '');
					$elem.find('video').remove().length = 0;
				}

				function onVideoTimeupdate(event){
					if(!isAutoScrubberUpdate){
						return;
					}
					_.set($scope.scrubber, 'model', video.currentTime);
					$scope.$apply();
					if(skipIntro)
					{
						if(currEpisode == null)
						{
							currEpisode = $scope.options.currentEpisode;
						}
						if(currEpisode.intro_start < this.currentTime && this.currentTime < currEpisode.intro_end)
						{
							video.currentTime = currEpisode.intro_end;
						}
					}
				}

				function onVideoEnded() {
					if($scope.options.showNextButton){
						$scope.options.onNext();
					}
				}

				function onVideoError(){
					if(!video.duration && !$scope.initialPlay){
						console.error('Video Playback Error');
						$scope.options.onError();
					}
				}

				function onVideoPlaying() {
					$scope.loading = false;
				}

				function onVideoCanPlay() {
					if(!$scope.initialPlay){
						$scope.canplay = true;
						console.log('%c onVideoCanPlay', 'color: deeppink; font-weight: bold; text-shadow: 0 0 5px deeppink;');
						$scope.loading = false;
						$scope.play();
						$scope.videoDuration = video.duration;
						generateScrupperOoptions(video.duration);

						video.currentTime = $scope.options.customStartingTime || 0;
						$scope.scrubber.model = video.currentTime || 0;
						$scope.initialPlay = true;
						if($scope.options.videoTrack){
							video.textTracks[0].mode = "hidden";
						}
					}
				}

				function onVideoWaiting() {
					$scope.loading = true;
				}

				function toggleSelectEpisodes(episodes) {
					$scope.options.selectedEpisodes = episodes;
				}

				function pause(socketData) {
					video.pause();
					$scope.playing = false;
					$scope.options.onPause(video, socketData);
				}

				function togglePlay() {
					if($scope.playing){
						pause();
					}else{
						play();
					}
				}

				function play(socketData) {
					video.play();
					$scope.playing = true;
					$scope.options.onPlay(video, socketData);
					$scope.overlayVisible = false;
				}

				function createNewPlayerSession() {
					$scope.options.onSocketSessionCreate();
				}

				function toggleTextTrack() {
					$scope.isTextTrackVisible = !$scope.isTextTrackVisible;

					if($scope.isTextTrackVisible){
						video.textTracks[0].mode = "showing";
					}else{
						video.textTracks[0].mode = "hidden";
					}
				}

				//Changes the video player's volume. Takes the changing amount as a parameter.
				function changeVolume(amount) {
					$scope.volumeChanged = true;
					$timeout.cancel(volumeChangeTimeout);
					//console.log('%c event', 'color: deeppink; font-weight: bold; text-shadow: 0 0 5px deeppink;', event);
					$scope.volumeLevel += amount;
					//console.log('%c event', 'color: deeppink; font-weight: bold; text-shadow: 0 0 5px deeppink;', event.deltaY, $scope.volumeLevel);
					$scope.volumeLevel = $scope.volumeLevel.clamp(0, 10);
					$scope.$apply();

					volumeChangeTimeout = $timeout(function () {
						$scope.volumeChanged = false;
					}, 1500);
				}

				function initIsMobile() {
					$scope.isMobile = $scope.options.isMobile;

					// if($scope.isMobile){
					// 	console.log('%c MOBILE', 'color: deeppink; font-weight: bold; text-shadow: 0 0 5px deeppink;');
					// 	$scope.playerTemplate = 'streama-video-player.touch.html';
					// }
					// else{
					// 	console.log('%c DESKTOP', 'color: deeppink; font-weight: bold; text-shadow: 0 0 5px deeppink;');
					// 	$scope.playerTemplate = 'streama-video-player.desktop.html';
					// }
				}
				//Shows the video's current time and duration on the upper right corner of the screen for a limited time.
				function skipActivated(){

					$scope.currentTimeChanged = true;
					$scope.options.onTimeChange(video.currentTime, $scope.videoDuration);
					$timeout.cancel(currentTimeChangeTimeout);
					$scope.$apply();

					currentTimeChangeTimeout = $timeout(function () {
						$scope.currentTimeChanged = false;
					}, 10000);
				}

				function initMouseWheel() {
					jQuery($elem).mousewheel(function (event) {
						if (event.deltaY > 0) {
							changeVolume(1);
						} else if (event.deltaY < 0) {
							changeVolume(-1);
						}
						$scope.showControls();
					});
				}

				function getBackgroundStyle() {
					if(!$scope.initialPlay){
						return {'background-image': 'url('+$scope.options.videoStillImage+')'};
					}else{
						return {};
					}
				}

			}
    }
  }]);
<commit_msg>add timeout to toggleControls to prevent code executing twice<commit_after>'use strict';

angular.module('streama.videoPlayer').directive('streamaVideoPlayer', [
  'localStorageService', '$timeout', '$http', 'streamaVideoPlayerService', '$filter',
  function (localStorageService, $timeout, $http, streamaVideoPlayerService, $filter) {

    return {
      restrict: 'AE',
      templateUrl: 'streama-video-player.touch.html',
      scope: {
        options: '='
      },

      link: function ($scope, $elem, $attrs) {
				$scope.options = streamaVideoPlayerService.initOptions($scope.options);
				if(!$scope.options){
					console.error('There was an error initializing the player. Please refer to the error log.');
					return;
				}
				var video;
        var controlDisplayTimeout;
        var overlayTimeout;
        var volumeChangeTimeout;
        var currentTimeChangeTimeout;
				var currEpisode = null;
        var skipIntro = true;         //Userflag intro should be skipped
        var minimizeOnOutro = true;   //Userflag skip to next episode on outro
				var videoSrc = $scope.options.videoSrc.toString();
				var isAutoScrubberUpdate = true;

				$scope.getBackgroundStyle = getBackgroundStyle;
				$scope.changeEpisode = changeEpisode;
				$scope.selectSubtitle = selectSubtitle;
				$scope.showControls = showControls;
				$scope.toggleSelectEpisodes = toggleSelectEpisodes;
				$scope.createNewPlayerSession = createNewPlayerSession;
        $scope.toggleTextTrack = toggleTextTrack;
        $scope.playerVolumeToggle = playerVolumeToggle;
				$scope.play = play;
				$scope.togglePlay = togglePlay;
				$scope.pause = pause;
				$scope.closeVideo = closeVideo;
				$scope.toggleControls = toggleControls;
				$scope.toggleMobileOverlayBox = toggleMobileOverlayBox;
				$scope.clickVideo = clickVideo;
				$scope.fullScreen = toggleFullScreen;
				$scope.changeSubtitleSize = changeSubtitleSize;
				$scope.next = $scope.options.onNext;
				$scope.isMobileControlsVisible = true;
				$scope.isInitialized = false;
				$scope.loading = true;
				$scope.initialPlay = false;

				$scope.mobileOverlayBox = {
					isVisble: false,
					type: ''
				};

				$scope.verticalSlider1 = {
					value: 5,
					options: {
						floor: 0,
						ceil: 10,
						vertical: true
					}
				};

				if(!$scope.options.isExternalLink){
					$http.head(videoSrc)
						.success(function(){
							initDirective();
						})
						.error(function(data, status) {
							if(status == 406){
								$scope.options.onError('FILE_IN_FS_NOT_FOUND');
							}
						});
				}else{
					initDirective();
				}

				function initDirective() {
					$scope.isInitialized = true;

					$elem.addClass('nocursor');

					if(!$scope.options.isTouch){
						initMouseWheel();
					}
					streamaVideoPlayerService.initMousetrap(video, $scope, skipActivated, changeVolume);
					initExternalTriggers();
					initIsMobile();
					$scope.$on('$destroy', onDirectiveDestroy);
					$scope.$on('$stateChangeSuccess', onStateChangeSuccess);
					generateVolumeScrubberOptions();

					$timeout(function () {
						var $video = $elem.find('video');
						$video.bind("contextmenu",function(){return false;});
						video = $video[0];
						video.oncanplay = onVideoCanPlay;
						video.onwaiting = onVideoWaiting;
						video.onplaying = onVideoPlaying;
						video.onerror = onVideoError;
						video.ontimeupdate = onVideoTimeupdate;
						video.addEventListener('ended', onVideoEnded);
						selectSubtitle(getCurrentSubtitleTrack());
					});
				}

				function changeEpisode(episode) {
					$scope.options.onEpisodeChange(episode);
				}

				function selectSubtitle(subtitle) {
					_.forEach(video.textTracks, function(textTrack, key) {
						if(subtitle && textTrack.id === 'subtitle-' + subtitle.id) {
							textTrack.mode = 'showing';
						}
						else{
							textTrack.mode = 'hidden';
						}

					});

					$scope.options.onSubtitleSelect(subtitle);
					$scope.selectedSubtitleId = _.get(subtitle, 'id');
					localStorageService.set('selectedSubtitleLanguage', _.get(subtitle, 'subtitleSrcLang'));
				}

				function getCurrentSubtitleTrack() {
					return _.find($scope.options.subtitles, {id: $scope.options.currentSubtitle});
				}

        //$scope.controlsVisible = true;
        function showControls() {
          $elem.removeClass('nocursor');
          $timeout.cancel(controlDisplayTimeout);
          $timeout.cancel(overlayTimeout);
          $scope.controlsVisible = true;
          $scope.overlayVisible = false;

          controlDisplayTimeout = $timeout(function(){
            $scope.controlsVisible = false;

            if(!$scope.playing){
              overlayTimeout = $timeout(function () {
                if(!$scope.playing){
                  $scope.overlayVisible = true;
                }
              }, 5000);
            }else{
              $elem.addClass('nocursor');
            }

          }, 1000);
        }

				function generateScrupperOoptions(videoDuration) {
					$scope.scrubber = {
						model: 0,
						options: {
							floor: 0,
							ceil: videoDuration,
							step: 1,
							hideLimitLabels: true,
							hidePointerLabels: true,
							showSelectionBar: true,
							// translate: function(value) {
							// 	return $filter('streamaVideoTime')(value);
							// },
							onStart: function () {
								isAutoScrubberUpdate = false;
							},
							// onChange: function(id) {
							// },
							onEnd: function(sliderId, modelValue, highValue, pointerType) {
								video.currentTime = modelValue;
								$scope.scrubber.model = modelValue;
								isAutoScrubberUpdate = true;
								$scope.options.onScrub(video);
								// $scope.options.onTimeChange(slider, $scope.videoDuration);
							}
						}
					};
				}

				function generateVolumeScrubberOptions() {
					$scope.volumeLevel = localStorageService.get('volumeLevel') || 5;
					$scope.volume = {
						options: {
							floor: 0,
							ceil: 10,
							step: 0.1,
							// precision: 1,
							hideLimitLabels: true,
							hidePointerLabels: true,
							showSelectionBar: true,
							vertical: true,
							onChange: function (sliderId, modelValue, highValue, pointerType) {
								setVolume(modelValue);
							}
						// slide: function (e, slider) {
						// 	setVolume(slider);
						// 	angular.element('#playerVolumeSlider .ui-slider-handle').blur();
						// }
						}
					};
				}

				function closeVideo() {

					//If full screen is enabled, it will be canceled.
					if ($scope.isFullScreen == true) {
						$scope.fullScreen();
					}

					onDirectiveDestroy();
					$scope.options.onClose();
				}

				function toggleControls(){
					$timeout(function () {
						$scope.isMobileControlsVisible = !$scope.isMobileControlsVisible;
					});
				}

				function clickVideo() {
					$scope.options.onVideoClick();
				}

				function toggleMobileOverlayBox(type) {
					$scope.mobileOverlayBox.isVisble = !$scope.mobileOverlayBox.isVisble;
					$scope.mobileOverlayBox.type = type;
					if($scope.mobileOverlayBox.isVisble){
						pause();
					}else{
						play();
					}
				}

				function changeSubtitleSize(subtitleSize) {
					$scope.options.subtitleSize = subtitleSize;
					localStorageService.set('subtitleSize', subtitleSize);
				}

				function toggleFullScreen() {
					var docElm;
					var docElmClose = document;
					if($scope.isMobile){
						docElm = video;
					}else{
						docElm = document.documentElement;
					}
					var isFullScreen = window.innerHeight == screen.height;
					if( !isFullScreen) {
						$scope.isFullScreen = true;
						if (docElm.requestFullscreen) {
							docElm.requestFullscreen();
						}
						else if (docElm.mozRequestFullScreen) {
							docElm.mozRequestFullScreen();
						}
						else if (docElm.webkitRequestFullScreen) {
							docElm.webkitRequestFullScreen();
						}
						else if (docElm.msRequestFullscreen) {
							docElm.msRequestFullscreen();
						}
					}

					else{
						$scope.isFullScreen = false;
						if (docElmClose.exitFullscreen) {
							docElmClose.exitFullscreen();
						}
						else if (docElmClose.mozCancelFullScreen) {
							docElmClose.mozCancelFullScreen();
						}
						else if (docElmClose.webkitExitFullscreen) {
							docElmClose.webkitExitFullscreen();
						}
						else if (docElmClose.msExitFullscreen) {
							docElmClose.msExitFullscreen();
						}
					}
				}

				function setVolume(value) {
					var volume = value / 10;
					video.volume = volume;
					if($scope.options.rememberVolumeSetting){
						localStorageService.set('volumeLevel', value);
					}
				}

				function playerVolumeToggle() {
					if($scope.volumeLevel == 0){
						$scope.volumeLevel = 5;
					}else{
						$scope.volumeLevel = 0;
					}
				}

        function initExternalTriggers() {
					$scope.$on('triggerVideoPlay', function (e, data) {
						$scope.play(data);
					});
					$scope.$on('triggerVideoPause', function (e, data) {
						$scope.pause(data);
					});
					$scope.$on('triggerVideoToggle', function (e, data) {
						if ($scope.playing) {
							$scope.pause(data);
						} else {
							$scope.play(data);
						}
					});
					$scope.$on('triggerVideoTimeChange', function (e, data) {
						video.currentTime = data.currentPlayerTime;
						$scope.scrubber.model = data.currentPlayerTime;
					});
				}

				function onStateChangeSuccess(e, toState) {
					if(toState.name != "player"){
						//If full screen is enabled, it will be canceled.
						if ($scope.isFullScreen = true) {
							$scope.fullScreen();
						}
					}
				}

				function onDirectiveDestroy() {

					//Disable these shortcut keys for other pages. They are re-initialized when the user opens the player again.
					Mousetrap.reset();

					console.log("destroy");
					video.pause();
					video.src = '';
					$elem.find('video').children('source').prop('src', '');
					$elem.find('video').remove().length = 0;
				}

				function onVideoTimeupdate(event){
					if(!isAutoScrubberUpdate){
						return;
					}
					_.set($scope.scrubber, 'model', video.currentTime);
					$scope.$apply();
					if(skipIntro)
					{
						if(currEpisode == null)
						{
							currEpisode = $scope.options.currentEpisode;
						}
						if(currEpisode.intro_start < this.currentTime && this.currentTime < currEpisode.intro_end)
						{
							video.currentTime = currEpisode.intro_end;
						}
					}
				}

				function onVideoEnded() {
					if($scope.options.showNextButton){
						$scope.options.onNext();
					}
				}

				function onVideoError(){
					if(!video.duration && !$scope.initialPlay){
						console.error('Video Playback Error');
						$scope.options.onError();
					}
				}

				function onVideoPlaying() {
					$scope.loading = false;
				}

				function onVideoCanPlay() {
					if(!$scope.initialPlay){
						$scope.canplay = true;
						console.log('%c onVideoCanPlay', 'color: deeppink; font-weight: bold; text-shadow: 0 0 5px deeppink;');
						$scope.loading = false;
						$scope.play();
						$scope.videoDuration = video.duration;
						generateScrupperOoptions(video.duration);

						video.currentTime = $scope.options.customStartingTime || 0;
						$scope.scrubber.model = video.currentTime || 0;
						$scope.initialPlay = true;
						if($scope.options.videoTrack){
							video.textTracks[0].mode = "hidden";
						}
					}
				}

				function onVideoWaiting() {
					$scope.loading = true;
				}

				function toggleSelectEpisodes(episodes) {
					$scope.options.selectedEpisodes = episodes;
				}

				function pause(socketData) {
					video.pause();
					$scope.playing = false;
					$scope.options.onPause(video, socketData);
				}

				function togglePlay() {
					if($scope.playing){
						pause();
					}else{
						play();
					}
				}

				function play(socketData) {
					video.play();
					$scope.playing = true;
					$scope.options.onPlay(video, socketData);
					$scope.overlayVisible = false;
				}

				function createNewPlayerSession() {
					$scope.options.onSocketSessionCreate();
				}

				function toggleTextTrack() {
					$scope.isTextTrackVisible = !$scope.isTextTrackVisible;

					if($scope.isTextTrackVisible){
						video.textTracks[0].mode = "showing";
					}else{
						video.textTracks[0].mode = "hidden";
					}
				}

				//Changes the video player's volume. Takes the changing amount as a parameter.
				function changeVolume(amount) {
					$scope.volumeChanged = true;
					$timeout.cancel(volumeChangeTimeout);
					//console.log('%c event', 'color: deeppink; font-weight: bold; text-shadow: 0 0 5px deeppink;', event);
					$scope.volumeLevel += amount;
					//console.log('%c event', 'color: deeppink; font-weight: bold; text-shadow: 0 0 5px deeppink;', event.deltaY, $scope.volumeLevel);
					$scope.volumeLevel = $scope.volumeLevel.clamp(0, 10);
					$scope.$apply();

					volumeChangeTimeout = $timeout(function () {
						$scope.volumeChanged = false;
					}, 1500);
				}

				function initIsMobile() {
					$scope.isMobile = $scope.options.isMobile;

					// if($scope.isMobile){
					// 	console.log('%c MOBILE', 'color: deeppink; font-weight: bold; text-shadow: 0 0 5px deeppink;');
					// 	$scope.playerTemplate = 'streama-video-player.touch.html';
					// }
					// else{
					// 	console.log('%c DESKTOP', 'color: deeppink; font-weight: bold; text-shadow: 0 0 5px deeppink;');
					// 	$scope.playerTemplate = 'streama-video-player.desktop.html';
					// }
				}
				//Shows the video's current time and duration on the upper right corner of the screen for a limited time.
				function skipActivated(){

					$scope.currentTimeChanged = true;
					$scope.options.onTimeChange(video.currentTime, $scope.videoDuration);
					$timeout.cancel(currentTimeChangeTimeout);
					$scope.$apply();

					currentTimeChangeTimeout = $timeout(function () {
						$scope.currentTimeChanged = false;
					}, 10000);
				}

				function initMouseWheel() {
					jQuery($elem).mousewheel(function (event) {
						if (event.deltaY > 0) {
							changeVolume(1);
						} else if (event.deltaY < 0) {
							changeVolume(-1);
						}
						$scope.showControls();
					});
				}

				function getBackgroundStyle() {
					if(!$scope.initialPlay){
						return {'background-image': 'url('+$scope.options.videoStillImage+')'};
					}else{
						return {};
					}
				}

			}
    }
  }]);
<|endoftext|>


<commit_before>/*!
Cloud4all Preferences Management Tools

Copyright 2014 CERTH/HIT

Licensed under the New BSD license. You may not use this file except in
compliance with this License.

You may obtain a copy of the License at
https://github.com/GPII/prefsEditors/LICENSE.txt
*/

/*global fluid, jQuery, gpii*/
/*jslint white: true, onevar: true, funcinvoke: true, forvar: true, undef: true, newcap: true, nomen: true, regexp: true, plusplus: true, bitwise: true, maxerr: 50, indent: 4 */

(function ($, fluid) {

    fluid.defaults("gpii.adjuster.singleSelectionWithKeyboard", {
        gradeNames: ["fluid.littleComponent", "autoInit"],
        mergePolicy: {
            selectorsToIgnore: fluid.prefs.compositePanel.arrayMergePolicy
        },
        selectors: {
            singleSelectionLabels: ""   // to be provided by implementors
        },
        selectorsToIgnore: ["singleSelectionLabels"],
        listeners: {
            "onDomBind.setFocusHandlers": "{that}.setFocusHandlers"
        },
        invokers: {
            setFocusHandlers: {
                funcName: "gpii.adjuster.singleSelectionWithKeyboard.setFocusHandlers",
                args: [
                    "{that}.dom.singleSelectionLabels"
                ]
            }
        }
    });

    gpii.adjuster.singleSelectionWithKeyboard.setFocusHandlers = function (labelsClass) {
        labels = $(labelsClass);

        fluid.each(labels, function (label, index) {
            label = $(label);

            // get the label's associated input
            var inputCssCompliantSelector = "#" + label.attr("for").replace(/\:/g, '\\:');
            var theInput = $(inputCssCompliantSelector);
            // outline container according to focus
            theInput.focusin(function () {
                label.addClass("gpii-focus");
            });
            theInput.focusout(function () {
                label.removeClass("gpii-focus");
            });
        });
    };

})(jQuery, fluid);
<commit_msg>GPII-590: setFocusHandlers function already has labels parameter as jQuery object.<commit_after>/*!
Cloud4all Preferences Management Tools

Copyright 2014 CERTH/HIT

Licensed under the New BSD license. You may not use this file except in
compliance with this License.

You may obtain a copy of the License at
https://github.com/GPII/prefsEditors/LICENSE.txt
*/

/*global fluid, jQuery, gpii*/
/*jslint white: true, onevar: true, funcinvoke: true, forvar: true, undef: true, newcap: true, nomen: true, regexp: true, plusplus: true, bitwise: true, maxerr: 50, indent: 4 */

(function ($, fluid) {

    fluid.defaults("gpii.adjuster.singleSelectionWithKeyboard", {
        gradeNames: ["fluid.littleComponent", "autoInit"],
        mergePolicy: {
            selectorsToIgnore: fluid.prefs.compositePanel.arrayMergePolicy
        },
        selectors: {
            singleSelectionLabels: ""   // to be provided by implementors
        },
        selectorsToIgnore: ["singleSelectionLabels"],
        listeners: {
            "onDomBind.setFocusHandlers": "{that}.setFocusHandlers"
        },
        invokers: {
            setFocusHandlers: {
                funcName: "gpii.adjuster.singleSelectionWithKeyboard.setFocusHandlers",
                args: [
                    "{that}.dom.singleSelectionLabels"
                ]
            }
        }
    });

    gpii.adjuster.singleSelectionWithKeyboard.setFocusHandlers = function (labels) {
        fluid.each(labels, function (label, index) {
            label = $(label);

            // get the label's associated input
            var inputCssCompliantSelector = "#" + label.attr("for").replace(/\:/g, '\\:');
            var theInput = $(inputCssCompliantSelector);
            // outline container according to focus
            theInput.focusin(function () {
                label.addClass("gpii-focus");
            });
            theInput.focusout(function () {
                label.removeClass("gpii-focus");
            });
        });
    };

})(jQuery, fluid);
<|endoftext|>


<commit_before>import React from 'react';
import ReactModal from 'react-modal';
import FontAwesomeIcon from '@fortawesome/react-fontawesome';
import faexclamationtriangle from '@fortawesome/fontawesome-free-solid/faExclamationTriangle';
import firefoxLogo from 'images/browserLogos/firefox-icon.png';
import chromeLogo from 'images/browserLogos/chrome-icon.png';
import edgeLogo from 'images/browserLogos/edge-icon.png';
import safariLogo from 'images/browserLogos/safari-icon.png';
import styles from './upgradeBrowser.css';

const UpgradeBrowser = () => (

    <ReactModal className={styles.layout} overlayClassName={styles.overlay} isOpen="true">

        <FontAwesomeIcon icon={faexclamationtriangle} className={styles.warning_logo} />

Please Upgrade Your Browser

          You might be experiencing some problems viewing this page. Use the links below to download
          or upgrade your existing browser for a seamless experience.

            Microsoft Edge

            Google Chrome

            Mozilla Firefox

            Safari

    </ReactModal>

);

export default UpgradeBrowser;
<commit_msg>Use OutboutLink component for external browser links<commit_after>import React from 'react';
import ReactModal from 'react-modal';
import FontAwesomeIcon from '@fortawesome/react-fontawesome';
import faexclamationtriangle from '@fortawesome/fontawesome-free-solid/faExclamationTriangle';
import OutboundLink from 'shared/components/outboundLink/outboundLink';
import firefoxLogo from 'images/browserLogos/firefox-icon.png';
import chromeLogo from 'images/browserLogos/chrome-icon.png';
import edgeLogo from 'images/browserLogos/edge-icon.png';
import safariLogo from 'images/browserLogos/safari-icon.png';
import styles from './upgradeBrowser.css';

const UpgradeBrowser = () => (

    <ReactModal className={styles.layout} overlayClassName={styles.overlay} isOpen="true">

        <FontAwesomeIcon icon={faexclamationtriangle} className={styles.warning_logo} />

Please Upgrade Your Browser

          You might be experiencing some problems viewing this page. Use the links below to download
          or upgrade your existing browser for a seamless experience.

            Microsoft Edge
            <OutboundLink href="https://www.microsoft.com/windows/microsoft-edge" analyticsEventLabel="User clicked on Edge download link">

            </OutboundLink>

            Google Chrome
            <OutboundLink href="https://www.google.com/chrome" analyticsEventLabel="User clicked on Chrome download link">

            </OutboundLink>

            Mozilla Firefox
            <OutboundLink href="https://www.mozilla.org/firefox/new" analyticsEventLabel="User clicked on Firefox download link">

            </OutboundLink>

            Safari
            <OutboundLink href="https://support.apple.com/downloads/safari" analyticsEventLabel="User clicked on Safari download link">

            </OutboundLink>

    </ReactModal>

);

export default UpgradeBrowser;
<|endoftext|>


<commit_before>require(TEST_HELPER); // <--- This must be at the top of every test file.

var request = require('supertest-as-promised');
var routes = require(__server + '/index.js');

describe('The Server', function() {

  var app = TestHelper.createApp();
  app.use('/', routes);
  app.testReady();

  it_('Returns an Array when "get /api/games" is queried with a tournament_id', function * () {

    //
    // Notice how we're in a generator function (indicated by the the *)
    // See test/test-helper.js for details of why this works.
    //
    yield request(app)
      .get('/api/games?tournament_id=3')
      .expect(200)
      .expect(function(response) {
        expect(response.body).to.be.a('array');
      });
  });
});
<commit_msg>Server tests broken out into routes<commit_after>require(TEST_HELPER); // <--- This must be at the top of every test file.

var request = require('supertest-as-promised');
var routes = require(__server + '/index.js');

describe('The Server', function() {

  var app = TestHelper.createApp();
  app.use('/', routes);
  app.testReady();
  // Notice how these are generator functions (indicated by the the *)
  // See test/test-helper.js for details of why this works.
  // I (Scott) have no clue, but it seems to be working right now.......
  describe('route /api/games', function() {
    it_('"get /api/games" should be a route in the server', function * () {

      yield request(app)
      .get('/api/games')
      .expect(200);
    });

    it_('Returns an Array when "get /api/games" is queried with a tournament_id', function * () {

      yield request(app)
      .get('/api/games?tournament_id=3')
      .expect(200)
      .expect(function(response) {
        expect(response.body).to.be.a('array');
      });
    });

  });

  describe('route /api/games/stats', function() {

    it_('"get /api/games/stats" should be a route in the server', function * () {

      yield request(app)
      .get('/api/games/stats')
      .expect(200);
    });

  });

});
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright (c) 2015 MediaMath Inc. All rights reserved.
 * This code may only be used under the BSD style license found at http://mediamath.github.io/strand/LICENSE.txt

*/
(function (scope) {

	var BehaviorUtils = StrandLib.BehaviorUtils;

	var exists = function(value) {
		return !(value === undefined || value === null);
	}

	scope.DatepickerPanel = Polymer({
		is: 'strand-datepicker-panel',

		properties: {
			// Configuration
			label: {
				type: String,
				value: 'start'
			},
			userEnabledLabel: {
				type: String,
				value: null
			},
			enabled: {
				type: Boolean,
				value: true
			},
			userEnabled: {
				type: Boolean,
				value: true
			},
			useTime: {
				type: Boolean,
				value: true
			},

			// Formatting
			dateFormat: {
				type: String,
				value: 'MM/DD/YYYY'
			},

			// Values
			value: { // datetime as unix timestamp
				type: Number,
				value: null,
				notify: true,
				observer: '_valueChanged'
			},
			date: {
				type: Object,
				value: null,
				notify: true,
				observer: '_dateChanged',
			},
			dateString: { // Date as string
				type: String,
				value: null,
				notify: true,
				observer: '_dateStringChanged'
			},
			time: { // Seconds since midnight
				type: Number,
				value: null,
				notify: true,
			}
		},

		behaviors: [
			StrandTraits.Resolvable,
			StrandTraits.Falsifiable,
			StrandTraits.Refable
		],

		_dateChanged: function(newDate, oldDate) {
			if(exists(newDate)) {
				var wrappedNew = moment(newDate);
				var wrappedOld = moment(oldDate);

				if(!wrappedNew.isSame(wrappedOld)) {
					var dateOnly = wrappedNew.startOf('day');
					this.dateString = dateOnly.format(this.dateFormat).toString();
					this.value = dateOnly.unix() + this.time;
				}
			}
		},

		_dateStringChanged: function(newDate, oldDate) {
			if(exists(newDate) && newDate !== oldDate) {
				var wrappedNew = moment(newDate, this.dateFormat, true);
				var wrappedOld = moment(oldDate, this.dateFormat, true);

				// Wait until date is valid before doing anything
				if(wrappedNew.isValid()) {
					// Update String format if not consistent with this.dateFormat
					var formatted = wrappedNew.format(this.dateFormat).toString();
					if(newDate !== formatted) {
						this.dateString = formatted;
					}
					// Don't do anything if the date didn't actually change
					else if(!wrappedNew.isSame(wrappedOld)) {
						var dateOnly = wrappedNew.startOf('day');
						this.date = dateOnly.toDate();
						this.value = dateOnly.unix() + this.time;
					}
				}
			}
		},

		_valueChanged: function(newValue, oldValue) {
			if(exists(newValue) && newValue !== oldValue) {
				var wrappedUnix = moment.unix(newValue);
				var secondsPerDay = 86400;
				// dateString change handler will change Date object
				this.dateString = wrappedUnix.format(this.dateFormat).toString();
				// get seconds since midnight
				var startOfDay = wrappedUnix.clone().startOf('day');
				this.time = wrappedUnix.diff(startOfDay, 'seconds');
			}
		}

	});

})(window.Strand = window.Strand || {});
<commit_msg>Addt'l passthrough props<commit_after>/**
 * @license
 * Copyright (c) 2015 MediaMath Inc. All rights reserved.
 * This code may only be used under the BSD style license found at http://mediamath.github.io/strand/LICENSE.txt

*/
(function (scope) {

	var BehaviorUtils = StrandLib.BehaviorUtils;

	var exists = function(value) {
		return !(value === undefined || value === null);
	}

	scope.DatepickerPanel = Polymer({
		is: 'strand-datepicker-panel',

		properties: {
			// Configuration
			label: {
				type: String,
				value: 'start'
			},
			userEnabledLabel: {
				type: String,
				value: null
			},
			enabled: {
				type: Boolean,
				value: true
			},
			userEnabled: {
				type: Boolean,
				value: true
			},
			useTime: {
				type: Boolean,
				value: true
			},

			// Formatting
			dateFormat: {
				type: String,
				value: 'MM/DD/YYYY'
			},
			timeFormat: {
				type: String
			},

			// Values
			value: { // datetime as unix timestamp
				type: Number,
				value: null,
				notify: true,
				observer: '_valueChanged'
			},
			date: {
				type: Object,
				value: null,
				notify: true,
				observer: '_dateChanged',
			},
			dateString: { // Date as string
				type: String,
				value: null,
				notify: true,
				observer: '_dateStringChanged'
			},
			time: { // Seconds since midnight
				type: Number,
				value: null,
				notify: true,
			},

			// Pass through for strand-calendar
			pairDate: {
				type: Object,
				notify: true
			},
			disablePast: {
				type: Object,
				notify: true
			},
			disableFuture: {
				type: Object,
				notify: true
			}
		},

		behaviors: [
			StrandTraits.Resolvable,
			StrandTraits.Falsifiable,
			StrandTraits.Refable
		],

		_dateChanged: function(newDate, oldDate) {
			if(exists(newDate)) {
				var wrappedNew = moment(newDate);
				var wrappedOld = moment(oldDate);

				if(!wrappedNew.isSame(wrappedOld)) {
					var dateOnly = wrappedNew.startOf('day');
					this.dateString = dateOnly.format(this.dateFormat).toString();
					this.value = dateOnly.unix() + this.time;
				}
			}
		},

		_dateStringChanged: function(newDate, oldDate) {
			if(exists(newDate) && newDate !== oldDate) {
				var wrappedNew = moment(newDate, this.dateFormat, true);
				var wrappedOld = moment(oldDate, this.dateFormat, true);

				// Wait until date is valid before doing anything
				if(wrappedNew.isValid()) {
					// Update String format if not consistent with this.dateFormat
					var formatted = wrappedNew.format(this.dateFormat).toString();
					if(newDate !== formatted) {
						this.dateString = formatted;
					}
					// Don't do anything if the date didn't actually change
					else if(!wrappedNew.isSame(wrappedOld)) {
						var dateOnly = wrappedNew.startOf('day');
						this.date = dateOnly.toDate();
						this.value = dateOnly.unix() + this.time;
					}
				}
			}
		},

		_valueChanged: function(newValue, oldValue) {
			if(exists(newValue) && newValue !== oldValue) {
				var wrappedUnix = moment.unix(newValue);
				var secondsPerDay = 86400;
				// dateString change handler will change Date object
				this.dateString = wrappedUnix.format(this.dateFormat).toString();
				// get seconds since midnight
				var startOfDay = wrappedUnix.clone().startOf('day');
				this.time = wrappedUnix.diff(startOfDay, 'seconds');
			}
		}

	});

})(window.Strand = window.Strand || {});
<|endoftext|>


<commit_before>YUI.add("trickcard", function (Y) {

    var TrickCard = Y.Base.create("trickcard", Y.Bridge.Card, [], {

        syncUI: function () {
            this.constructor.superclass.syncUI.apply(this, arguments);
            this.get("boundingBox").addClass(this.getClassName(this.get("position")));
        }

    }, {

        CSS_PREFIX: "yui3-card",

        ATTRS: {

            position: {
                writeOnce: "initOnly"
            },

            disabled: {
                value: true
            }

        }

    });

    Y.namespace("Bridge").TrickCard = TrickCard;

}, "0", { requires: ["card"] });
<commit_msg>fixed trickcard<commit_after>YUI.add("trickcard", function (Y) {

    var TrickCard = Y.Base.create("trickcard", Y.Bridge.Card, [], {

        syncUI: function () {
            this.constructor.superclass.syncUI.apply(this, arguments);
            this._syncPosition(this.get("position"));
        },

        _syncPosition: function (position) {
            this.get("boundingBox").addClass(this.getClassName(position));
        }

    }, {

        CSS_PREFIX: "yui3-card",

        ATTRS: {

            position: {
                writeOnce: "initOnly"
            },

            disabled: {
                value: true
            }

        }

    });

    Y.namespace("Bridge").TrickCard = TrickCard;

}, "0", { requires: ["card"] });
<|endoftext|>


<commit_before>function UpdateShippingGrid(session){
	this.canRepeat = true;
	this.session = session;
	this.heartPlayer = null;
	this.ships = [];
	this.savedShipText = "";
	this.powerNeeded = 1;

	//is there relationship drama!?
	this.trigger = function(){
		//console.log("checking shpping grid trigger.")
		//if heart player chagnes, it's a combo session or scratch or i don't care, redo the ships.
		var tmpheartPlayer = findAspectPlayer(this.session.availablePlayers, "Heart");
		if(this.ships.length == 0 || tmpheartPlayer != this.heartPlayer){
			this.createShips(this.session.players);
		}
		this.heartPlayer = tmpheartPlayer;

		if(!this.heartPlayer || this.heartPlayer.dead){
			return false;
		}
		var newShips = this.printShips(this.getGoodShips())
		if(newShips != this.savedShipText && this.heartPlayer.power > this.powerNeeded){
			this.powerNeeded += 5;
			this.savedShipText = newShips;
			return true;
		}
		return false;
	}

	this.renderContent = function(div){
		div.append("
");
		div.append(this.content());
	}

	//for all players, look at all relationships. if goodBig or badBig, return.
	//also grab clubs and diamonds. later.
	this.createShips = function(players){
		//console.log("creating ships")
		this.ships = [];
			for(var i = 0; i<players.length; i++){

				var player = players[i];
				//console.log("making ships for: " + player.title())

				for(var j = 0; j<player.relationships.length; j++){
					var r1 = player.relationships[j];
					var r2 = r1.target.getRelationshipWith(player);
					//console.log("made new ship")
					this.ships.push(new Ship(r1, r2))
				}
			}
				var toRemove = [];
				//get rid of equal ships
				for(var i = 0; i<this.ships.length-1; i++){
					var firstShip = this.ships[i];
					//second loop starts at i because i know i checked first ship no ships already, and second ship agains 1 ship
					for(var j= (i+1); j<this.ships.length; j++){
						var secondShip = this.ships[j];
							if(firstShip.isEqualToShip(secondShip)){
								//console.log("pushing to remove")
								toRemove.push(secondShip);
							}
					}
				}
				//console.log("this many to remove: " + toRemove.length)
				for(var i = 0; i<toRemove.length; i++){
						removeFromArray(toRemove[i], this.ships)
				}

	}

	this.getGoodShips = function(){
		var ret = [];
		for(var i = 0; i<this.ships.length; i++){
			var ship = this.ships[i];
			if(ship.isGoodShip()){
				ret.push(ship);
			}
		}
		return ret;
	}

	this.printShips = function(ships){
		return(ships.map(function(e){
			return e.toString();
		}).join("\n
"));
	}

	this.printAllShips = function(){
		return this.printShips(this.ships);
	}

	this.content = function(){
		//console.log("Updating shipping grid in: " + this.session.session_id);
		removeFromArray(this.heartPlayer, this.session.availablePlayers);
		this.heartPlayer.increasePower();
		return "The " + this.heartPlayer.htmlTitleBasic() + " updates their shipping grid.
" + this.savedShipText;
		//return "todo: update shipping grid for heart player.  updating it lowers the trigger level of all involved.  also, save clubs and diamonds to session. extract ships from it. if a player is in more than one diamonds, erase previous one.";

	}
}

//contains both relationship and it's inverse, knows how to render itself. dead players have a hussie style x over their faces.
//ships can also refuse to render themselves.  return false if that happens.
// render if: r2.saved_type == r2.goodBig || r2.saved_type == r2.badBig
function Ship(r1, r2){
		this.r1 = r1;
		this.r2 = r2;

		this.relationshipTypeToText = function(r){
		if(r.saved_type ==  r.heart){
			return "&#x2665"
		}

		if(r.saved_type ==  r.spades){
			return "&#x2660"
		}

		if(r.saved_type ==  r.clubs){
			return "&#x2663"
		}

		if(r.saved_type ==  r.diamond){
			return "&#x2666"
		}

		if(r.saved_type ==  r.neutral){
			return "0_0"
		}

		if(r.saved_type ==  r.goodBig){
			return "&#x2661"
		}

		if(r.saved_type ==  r.badBig){
			return "&#x2664"
		}

		if(r.saved_type ==  r.goodMild){
			return "&#x263A"
		}

		if(r.saved_type ==  r.badMild){
			return "&#x2639"
		}
		return r.saved_type;
	}

		//a relationship doesn't know who owns it, just what hte target is,so printing is funny
		this.toString = function(){
			return r2.target.htmlTitleBasic() + " " + this.relationshipTypeToText(r1) + "---" + this.relationshipTypeToText(r2) + " " + r1.target.htmlTitleBasic();
		}
		//order doesn't matter.
		this.isEqualToShip = function(ship){
			//console.log("comparing: " + this.toString() + " to "  + ship.toString())
			if(ship.r1 == this.r1 && ship.r2 == this.r2){
				//console.log("they are the same1")
				return true;
			}else if(ship.r2 == this.r1 && ship.r1 == this.r2){
				//console.log("they are the same2")
				return true;
			}
		//	console.log("they are not the same")
			return false;
		}

		this.isGoodShip = function(){
			if(r2.saved_type == "" || r1.saved_type == "" ){
				return false;
			}

			if(r1.saved_type == r1.goodBig || r1.saved_type == r1.badBig || r1.saved_type == r1.heart || r1.saved_type == r1.diamond || r1.saved_type == r1.spades || r1.saved_type == r1.clubs){
				return true;
			}

			if(r2.saved_type == r2.goodBig || r2.saved_type == r1.badBig || r2.saved_type == r1.heart || r2.saved_type == r2.diamond || r2.saved_type == r2.spades || r2.saved_type == r2.clubs){
				return true;
			}
			return false;
		}

}
<commit_msg>more fourth wall bullshit<commit_after>/*

                          ```````   `                 `  ``   `                        ```````                           `
                      ```` `   `   ````           `````   `   `````               ````  `   `` ````                ````  `   ``` `
                   ```               ````        ```             ````           ```                ```          ```             ````
                  ``                   ```      ``                 ```         ```                  ```        ```                ``
           `````..``.`..`````````.``.``-``.``..`..``.```.``..``.``.``.``.``.``-`.-``.``.`..``.``.``..`..``.``.``.```..``.``..`..````..````
           `.-............-..-...-.....-........................................................................-.......................-.`
           `.-..........................................................................................................................-.`
           `......:-....-::::::::::----:++++++++++++++oo+++::::::::::::::...::::::::::::::---------::::::::::::::::::::::::::-....-:......`
           `.-..../.                 -ohddddddddddddddddddhh+`           `.`                                                      ./....-.`
           `......+.              .+yhddddddddddddddddmmmmmddy.          `.`                            `     `                   .+......`
       `````.-....+.           `:shddddddddddddddddmNNNNNNNNmdy.         `.``.+o+.`  `.oo/.           .sh   .sh                   .+....-.` ```
     ```   `......+.         -ohdddddddddddddddmmNNNNNNNNNNNNmdy`        `.`  +d+      sd:             yd    yd                   .+......`   ```
     ```   `.:....+.         .yddddddddddddmmddNNNNmshNNNNmmNNmdo        `.`  +d+      sd-    ---:.    yd    yd    `---:.         .+....:.`    ```
    ```    `......+-          `+hdddddddddms:-hNdyo.``:shmN+omNdh-       `.`  +do------yd-  -s.``-ho   yd    yd   /o```-ss`       -+......`    ```
    ```    `.-....+:            .ohddddddy-``.:-.````````.-:`-NNdo       `.`  +d+``````yd-  yy:::://`  yd    yd  -h:    -do       :+....-.`    ```
     ```   `......+-              .+hdddds```````````````````.NNmh.      `.`  +d+      sd-  yh.    .`  yd    yd  :do    `d+       -+......`    ```
     ```   `.-..../.                .sddddy-`````````````````+Nmdo`      `.`  odo      yd:  -yho//+:   yd    yd   +h/` `/o`  /o.  ./....-.`    ``
       `````....../.                 -yddddh/```````````````/dyo-        `.``.:::.`  `.::-`  `-//:.   .::.  .::.   .::-..    -/`  ./......` ````
        ````......+.                /hddddddds:``````````.-/:.`          `.`                                                      .+......````
           `......+.               -ddmddddddddo-..-//+ohms              `.`                                                      .+......`
           `.-....+.              -hdNmddddddddddhhdddddyNh              `.`                                                      .+....-.`
           `-.....+.           .-ohddmdddddddddddhhdddddso:              `.`                                                      .+.....-`
          ``......+.          .ohdddddddddddddddhs/ddddddh:              `.`                                                      .+......`
        ````......+.         ```:hdddddddddddddh+--/hdddddh-             `.`                                                      .+......`````
      ```  `......+-      ``````.hddddddddddddho....+dddddy`             `.`                                                      -+......`  ```
     ````  `.:...-+:   ``````` `odddddddddddddo/-..-+sdds/.``            `.`                                                      :+-...:.`   ```
     ```   `....../-`````````   :sssssssyyyyyys+o++o+syyo `````          `.`               ````````````````                       -/......`    ``
     ```   `........````````````--------:::::::::::::::::.````````````````.````````````````````````````````````````````````````````.......`    ``
     ```   `....../```````      -+syyyhhhhhhhhhddddddhyo/.    ```        `.`                                                      `+......`   ```
      ``   `.....-+`   `````       ``.shdddddddddddddo         ```       `.`                                                      `+-.....`   ```
       ``` `.....-+`      `````   ````-/hddddddddddddh-         ```      `.`                                                      `+-.....`  ``
         ```.-...-+`          ````````..:oddddddddddddh.         ```     `.`                                                      `+-...-.```
           `.....-+.                 :shyddddddddddddddy.         ```    `.`                                                      .+-.....`
           `.-...-+.                 sddddddddddddddddddy.        ```    `.`                                                      .+-...-.`
           `......+`                 ydddddddddddddddddddh.        ```   `.`                                                      `+......`
        ````......+`                -hydddddddddddddddddddy`        ``   `.`                                                      `+......`````
      ```  `......+`                +hsdddddddddddddddddddds`        ``  `.`                                                      `+......`  ````
     ```   `.....-+`                +y+hddddddddddddddddddddo         `` `.`                                                      `+-.....`   ```
     ```   `.-...-+`                ys+yddddddddddddddddddddd/         ` `.`                                                      `+-...-.`    ```
     ```   `.....-+`               -d++sdddddddddddddddddddddh-        ```.`                                                      `+-.....`    ```
     ```   `:....-+`               -s++ohhhhhddhdddddddhhhhyso+        ` `..`                                                     `+-....:`   ```
      ``   `.....-+`                .++++++oooo-::::/oooo++++++.         `..`                                                     `+-.....`   ```
       ````..-...:+`                -+++++++++/      :+++++++++/         `.`                                                      `+:...-.` ````
        ```......-+.                -+++++++++/       /+++++++++.        `.`                                                      .+-......```
           `.-...:+.                -+++++++++/       `+++++++++/        `.`                                                      .+:...-.`
           `.-...-+-                -+++++++++/        :+++++++++`       `.`                                                      -+-...-.`
           ......./:...--:::::::::--://///////:......--://///////::::::::...::::::::::::::--------:::::::::::::::::::::::::::--...:/.......
           ..-..........................................................................................................................-..
           ..-........-...-..-..................................................................................-..............-........-..
           `````-``.``.```.`````..`..`..``-``-``-``..``.```-``.```.``.`..``.`..`..`..`..`.``..`..``-``.``.``..``.```-```.``-```.``.``-`````

So, speaking of ships, somebody on Tumblr just asked me if JR <3 AB or JR <> AB.  Good question. Personally, I'm still just tickled pink about AB. She's the best. And
that isn't some ironic roleplay thing I'm doing, either. I love robots, I love AI, and, I probably have a big enough ego that I WOULD love a robot clone of myself.

But narratively, I'm thinking about the AutoResponder's complicated relationship with Dirk. And how things must be from AB's perspective. It doesn't matter whether your creator loves or hates
you if they are still trapping you in a box, right?  I figure I probably come off to AB as kinda patronizing and definitely narcisistic. "Oh, I love AB, she's the best, I'm so great for making her!"  How must that sound to the robot in question?
Not enough to make her fight me, but a simmering resentment kinda deal. And then I don't let her "off the leash", so to speak, keeping her from going to all the sessions she wants to. "For her own good."  I tried to convey some of that
shit in some of our yellow yard dialogue, and in some of the now defunct debug dialogue before the RareSessionFinder was as robust as it is today. (you can find that shit in...probably scenario_controller2.js???)

Though some of the pressure probably got released when I upgraded her to handle scratched sessions.  I didn't post anything at the time, but I privately thought it was kinda funny how she kept breaking in ways where she'd
scratch the sessions herself, like she was rebelling, testing the limits of her new freedom.

So I guess neither <3 nor <> but that strange human disease called family??? She's like a little sister or a daughter or something.

*/

function UpdateShippingGrid(session){
	this.canRepeat = true;
	this.session = session;
	this.heartPlayer = null;
	this.ships = [];
	this.savedShipText = "";
	this.powerNeeded = 1;

	//is there relationship drama!?
	this.trigger = function(){
		//console.log("checking shpping grid trigger.")
		//if heart player chagnes, it's a combo session or scratch or i don't care, redo the ships.
		var tmpheartPlayer = findAspectPlayer(this.session.availablePlayers, "Heart");
		if(this.ships.length == 0 || tmpheartPlayer != this.heartPlayer){
			this.createShips(this.session.players);
		}
		this.heartPlayer = tmpheartPlayer;

		if(!this.heartPlayer || this.heartPlayer.dead){
			return false;
		}
		var newShips = this.printShips(this.getGoodShips())
		if(newShips != this.savedShipText && this.heartPlayer.power > this.powerNeeded){
			this.powerNeeded += 5;
			this.savedShipText = newShips;
			return true;
		}
		return false;
	}

	this.renderContent = function(div){
		div.append("
");
		div.append(this.content());
	}

	//for all players, look at all relationships. if goodBig or badBig, return.
	//also grab clubs and diamonds. later.
	this.createShips = function(players){
		//console.log("creating ships")
		this.ships = [];
			for(var i = 0; i<players.length; i++){

				var player = players[i];
				//console.log("making ships for: " + player.title())

				for(var j = 0; j<player.relationships.length; j++){
					var r1 = player.relationships[j];
					var r2 = r1.target.getRelationshipWith(player);
					//console.log("made new ship")
					this.ships.push(new Ship(r1, r2))
				}
			}
				var toRemove = [];
				//get rid of equal ships
				for(var i = 0; i<this.ships.length-1; i++){
					var firstShip = this.ships[i];
					//second loop starts at i because i know i checked first ship no ships already, and second ship agains 1 ship
					for(var j= (i+1); j<this.ships.length; j++){
						var secondShip = this.ships[j];
							if(firstShip.isEqualToShip(secondShip)){
								//console.log("pushing to remove")
								toRemove.push(secondShip);
							}
					}
				}
				//console.log("this many to remove: " + toRemove.length)
				for(var i = 0; i<toRemove.length; i++){
						removeFromArray(toRemove[i], this.ships)
				}

	}

	this.getGoodShips = function(){
		var ret = [];
		for(var i = 0; i<this.ships.length; i++){
			var ship = this.ships[i];
			if(ship.isGoodShip()){
				ret.push(ship);
			}
		}
		return ret;
	}

	this.printShips = function(ships){
		return(ships.map(function(e){
			return e.toString();
		}).join("\n
"));
	}

	this.printAllShips = function(){
		return this.printShips(this.ships);
	}

	this.content = function(){
		//console.log("Updating shipping grid in: " + this.session.session_id);
		removeFromArray(this.heartPlayer, this.session.availablePlayers);
		this.heartPlayer.increasePower();
		return "The " + this.heartPlayer.htmlTitleBasic() + " updates their shipping grid.
" + this.savedShipText;
		//return "todo: update shipping grid for heart player.  updating it lowers the trigger level of all involved.  also, save clubs and diamonds to session. extract ships from it. if a player is in more than one diamonds, erase previous one.";

	}
}

//contains both relationship and it's inverse, knows how to render itself. dead players have a hussie style x over their faces.
//ships can also refuse to render themselves.  return false if that happens.
// render if: r2.saved_type == r2.goodBig || r2.saved_type == r2.badBig
function Ship(r1, r2){
		this.r1 = r1;
		this.r2 = r2;

		this.relationshipTypeToText = function(r){
		if(r.saved_type ==  r.heart){
			return "&#x2665"
		}

		if(r.saved_type ==  r.spades){
			return "&#x2660"
		}

		if(r.saved_type ==  r.clubs){
			return "&#x2663"
		}

		if(r.saved_type ==  r.diamond){
			return "&#x2666"
		}

		if(r.saved_type ==  r.neutral){
			return "0_0"
		}

		if(r.saved_type ==  r.goodBig){
			return "&#x2661"
		}

		if(r.saved_type ==  r.badBig){
			return "&#x2664"
		}

		if(r.saved_type ==  r.goodMild){
			return "&#x263A"
		}

		if(r.saved_type ==  r.badMild){
			return "&#x2639"
		}
		return r.saved_type;
	}

		//a relationship doesn't know who owns it, just what hte target is,so printing is funny
		this.toString = function(){
			return r2.target.htmlTitleBasic() + " " + this.relationshipTypeToText(r1) + "---" + this.relationshipTypeToText(r2) + " " + r1.target.htmlTitleBasic();
		}
		//order doesn't matter.
		this.isEqualToShip = function(ship){
			//console.log("comparing: " + this.toString() + " to "  + ship.toString())
			if(ship.r1 == this.r1 && ship.r2 == this.r2){
				//console.log("they are the same1")
				return true;
			}else if(ship.r2 == this.r1 && ship.r1 == this.r2){
				//console.log("they are the same2")
				return true;
			}
		//	console.log("they are not the same")
			return false;
		}

		this.isGoodShip = function(){
			if(r2.saved_type == "" || r1.saved_type == "" ){
				return false;
			}

			if(r1.saved_type == r1.goodBig || r1.saved_type == r1.badBig || r1.saved_type == r1.heart || r1.saved_type == r1.diamond || r1.saved_type == r1.spades || r1.saved_type == r1.clubs){
				return true;
			}

			if(r2.saved_type == r2.goodBig || r2.saved_type == r1.badBig || r2.saved_type == r1.heart || r2.saved_type == r2.diamond || r2.saved_type == r2.spades || r2.saved_type == r2.clubs){
				return true;
			}
			return false;
		}

}
<|endoftext|>


<commit_before>// @flow weak

import React, { PropTypes } from 'react';
import { createStyleSheet } from 'jss-theme-reactor';
import classNames from 'classnames';
import LabelBase from '../internal/LabelBase';

export const styleSheet = createStyleSheet('FormLabel', () => {
  return {
    root: {}, // expected to be used
  };
});

export default function FormLabel(props, context) {
  const {
    children,
    className: classNameProp,
    ...other
  } = props;
  const classes = context.styleManager.render(styleSheet);

  const className = classNames(classes.root, classNameProp);

  return (
    <LabelBase className={className} {...other}>
      {children}
    </LabelBase>
  );
}

FormLabel.propTypes = {
  animated: PropTypes.bool,
  /**
   * The contents of the `FormLabel`.
   */
  children: PropTypes.node,
  /**
   * The CSS class name of the root element.
   */
  className: PropTypes.string,
  /**
   * Whether the label should be displayed in an error state.
   */
  error: PropTypes.bool,
  /**
   * Whether the inputs this label refers to are focused.
   */
  focused: PropTypes.bool,
  /**
   * Whether this label should indicate that a response is required.
   */
  required: PropTypes.bool,
};

FormLabel.defaultProps = {
  error: false,
  required: false,
};

FormLabel.contextTypes = {
  styleManager: PropTypes.object.isRequired,
};

FormLabel.muiName = 'FormLabel';
<commit_msg>remove unused prop<commit_after>// @flow weak

import React, { PropTypes } from 'react';
import { createStyleSheet } from 'jss-theme-reactor';
import classNames from 'classnames';
import LabelBase from '../internal/LabelBase';

export const styleSheet = createStyleSheet('FormLabel', () => {
  return {
    root: {}, // expected to be used
  };
});

export default function FormLabel(props, context) {
  const {
    children,
    className: classNameProp,
    ...other
  } = props;
  const classes = context.styleManager.render(styleSheet);

  const className = classNames(classes.root, classNameProp);

  return (
    <LabelBase className={className} {...other}>
      {children}
    </LabelBase>
  );
}

FormLabel.propTypes = {
  /**
   * The contents of the `FormLabel`.
   */
  children: PropTypes.node,
  /**
   * The CSS class name of the root element.
   */
  className: PropTypes.string,
  /**
   * Whether the label should be displayed in an error state.
   */
  error: PropTypes.bool,
  /**
   * Whether the inputs this label refers to are focused.
   */
  focused: PropTypes.bool,
  /**
   * Whether this label should indicate that a response is required.
   */
  required: PropTypes.bool,
};

FormLabel.defaultProps = {
  error: false,
  required: false,
};

FormLabel.contextTypes = {
  styleManager: PropTypes.object.isRequired,
};

FormLabel.muiName = 'FormLabel';
<|endoftext|>


<commit_before>
/**
 * Module dependencies.
 */

var fs = require('fs')
  , path = require('path')
  , join = path.join
  , dirname = path.dirname
  , exists = fs.existsSync || path.existsSync
  , defaults = {
        arrow: process.env.NODE_BINDINGS_ARROW || ' → '
      , compiled: process.env.NODE_BINDINGS_COMPILED_DIR || 'compiled'
      , platform: process.platform
      , arch: process.arch
      , version: process.versions.node
      , bindings: 'bindings.node'
      , try: [
          // node-gyp's linked version in the "build" dir
          [ 'module_root', 'build', 'bindings' ]
          // node-waf and gyp_addon (a.k.a node-gyp)
        , [ 'module_root', 'build', 'Debug', 'bindings' ]
        , [ 'module_root', 'build', 'Release', 'bindings' ]
          // Debug files, for development (legacy behavior, remove for node v0.9)
        , [ 'module_root', 'out', 'Debug', 'bindings' ]
        , [ 'module_root', 'Debug', 'bindings' ]
          // Release files, but manually compiled (legacy behavior, remove for node v0.9)
        , [ 'module_root', 'out', 'Release', 'bindings' ]
        , [ 'module_root', 'Release', 'bindings' ]
          // Legacy from node-waf, node <= 0.4.x
        , [ 'module_root', 'build', 'default', 'bindings' ]
          // Production "Release" buildtype binary (meh...)
        , [ 'module_root', 'compiled', 'version', 'platform', 'arch', 'bindings' ]
        ]
    }

/**
 * The main `bindings()` function loads the compiled bindings for a given module.
 * It uses V8's Error API to determine the parent filename that this function is
 * being invoked from, which is then used to find the root directory.
 */

function bindings (opts) {

  // Argument surgery
  if (typeof opts == 'string') {
    opts = { bindings: opts }
  } else if (!opts) {
    opts = {}
  }
  opts.__proto__ = defaults

  // Get the module root
  if (!opts.module_root) {
    opts.module_root = exports.getRoot(exports.getFileName())
  }

  // Ensure the given bindings name ends with .node
  if (path.extname(opts.bindings) != '.node') {
    opts.bindings += '.node'
  }

  var tries = []
    , i = 0
    , l = opts.try.length
    , n
    , b
    , err

  for (; i<l; i++) {
    n = join.apply(null, opts.try[i].map(function (p) {
      return opts[p] || p
    }))
    tries.push(n)
    try {
      b = opts.path ? require.resolve(n) : require(n)
      if (!opts.path) {
        b.path = n
      }
      return b
    } catch (e) {
      if (!/not find/i.test(e.message)) {
        throw e
      }
    }
  }

  err = new Error('Could not locate the bindings file. Tried:\n'
    + tries.map(function (a) { return opts.arrow + a }).join('\n'))
  err.tries = tries
  throw err
}
module.exports = exports = bindings

/**
 * Gets the filename of the JavaScript file that invokes this function.
 * Used to help find the root directory of a module.
 * Optionally accepts an filename argument to skip when searching for the invoking filename
 */

exports.getFileName = function getFileName (calling_file) {
  var origPST = Error.prepareStackTrace
    , origSTL = Error.stackTraceLimit
    , dummy = {}
    , fileName

  Error.stackTraceLimit = 10

  Error.prepareStackTrace = function (e, st) {
    for (var i=0, l=st.length; i<l; i++) {
      fileName = st[i].getFileName()
      if (fileName !== __filename) {
        if (calling_file) {
            if (fileName !== calling_file) {
              return
            }
        } else {
          return
        }
      }
    }
  }

  // run the 'prepareStackTrace' function above
  Error.captureStackTrace(dummy)
  dummy.stack

  // cleanup
  Error.prepareStackTrace = origPST
  Error.stackTraceLimit = origSTL

  return fileName
}

/**
 * Gets the root directory of a module, given an arbitrary filename
 * somewhere in the module tree. The "root directory" is the directory
 * containing the `package.json` file.
 *
 *   In:  /home/nate/node-native-module/lib/index.js
 *   Out: /home/nate/node-native-module
 */

exports.getRoot = function getRoot (file) {
  var dir = dirname(file)
    , prev
  while (true) {
    if (dir === '.') {
      // Avoids an infinite loop in rare cases, like the REPL
      dir = process.cwd()
    }
    if (exists(join(dir, 'package.json')) || exists(join(dir, 'node_modules'))) {
      // Found the 'package.json' file or 'node_modules' dir; we're done
      return dir
    }
    if (prev === dir) {
      // Got to the top
      throw new Error('Could not find module root given file: "' + file
                    + '". Do you have a `package.json` file? ')
    }
    // Try the parent dir next
    prev = dir
    dir = join(dir, '..')
  }
}
<commit_msg>Replaced __proto__ with Object.assign<commit_after>
/**
 * Module dependencies.
 */

var fs = require('fs')
  , path = require('path')
  , join = path.join
  , dirname = path.dirname
  , exists = fs.existsSync || path.existsSync
  , defaults = {
        arrow: process.env.NODE_BINDINGS_ARROW || ' → '
      , compiled: process.env.NODE_BINDINGS_COMPILED_DIR || 'compiled'
      , platform: process.platform
      , arch: process.arch
      , version: process.versions.node
      , bindings: 'bindings.node'
      , try: [
          // node-gyp's linked version in the "build" dir
          [ 'module_root', 'build', 'bindings' ]
          // node-waf and gyp_addon (a.k.a node-gyp)
        , [ 'module_root', 'build', 'Debug', 'bindings' ]
        , [ 'module_root', 'build', 'Release', 'bindings' ]
          // Debug files, for development (legacy behavior, remove for node v0.9)
        , [ 'module_root', 'out', 'Debug', 'bindings' ]
        , [ 'module_root', 'Debug', 'bindings' ]
          // Release files, but manually compiled (legacy behavior, remove for node v0.9)
        , [ 'module_root', 'out', 'Release', 'bindings' ]
        , [ 'module_root', 'Release', 'bindings' ]
          // Legacy from node-waf, node <= 0.4.x
        , [ 'module_root', 'build', 'default', 'bindings' ]
          // Production "Release" buildtype binary (meh...)
        , [ 'module_root', 'compiled', 'version', 'platform', 'arch', 'bindings' ]
        ]
    }

/**
 * The main `bindings()` function loads the compiled bindings for a given module.
 * It uses V8's Error API to determine the parent filename that this function is
 * being invoked from, which is then used to find the root directory.
 */

function bindings (opts) {

  // Argument surgery
  if (typeof opts == 'string') {
    opts = { bindings: opts }
  } else if (!opts) {
    opts = {}
  }
  opts = Object.assign({}, defaults, opts);

  // Get the module root
  if (!opts.module_root) {
    opts.module_root = exports.getRoot(exports.getFileName())
  }

  // Ensure the given bindings name ends with .node
  if (path.extname(opts.bindings) != '.node') {
    opts.bindings += '.node'
  }

  var tries = []
    , i = 0
    , l = opts.try.length
    , n
    , b
    , err

  for (; i<l; i++) {
    n = join.apply(null, opts.try[i].map(function (p) {
      return opts[p] || p
    }))
    tries.push(n)
    try {
      b = opts.path ? require.resolve(n) : require(n)
      if (!opts.path) {
        b.path = n
      }
      return b
    } catch (e) {
      if (!/not find/i.test(e.message)) {
        throw e
      }
    }
  }

  err = new Error('Could not locate the bindings file. Tried:\n'
    + tries.map(function (a) { return opts.arrow + a }).join('\n'))
  err.tries = tries
  throw err
}
module.exports = exports = bindings

/**
 * Gets the filename of the JavaScript file that invokes this function.
 * Used to help find the root directory of a module.
 * Optionally accepts an filename argument to skip when searching for the invoking filename
 */

exports.getFileName = function getFileName (calling_file) {
  var origPST = Error.prepareStackTrace
    , origSTL = Error.stackTraceLimit
    , dummy = {}
    , fileName

  Error.stackTraceLimit = 10

  Error.prepareStackTrace = function (e, st) {
    for (var i=0, l=st.length; i<l; i++) {
      fileName = st[i].getFileName()
      if (fileName !== __filename) {
        if (calling_file) {
            if (fileName !== calling_file) {
              return
            }
        } else {
          return
        }
      }
    }
  }

  // run the 'prepareStackTrace' function above
  Error.captureStackTrace(dummy)
  dummy.stack

  // cleanup
  Error.prepareStackTrace = origPST
  Error.stackTraceLimit = origSTL

  return fileName
}

/**
 * Gets the root directory of a module, given an arbitrary filename
 * somewhere in the module tree. The "root directory" is the directory
 * containing the `package.json` file.
 *
 *   In:  /home/nate/node-native-module/lib/index.js
 *   Out: /home/nate/node-native-module
 */

exports.getRoot = function getRoot (file) {
  var dir = dirname(file)
    , prev
  while (true) {
    if (dir === '.') {
      // Avoids an infinite loop in rare cases, like the REPL
      dir = process.cwd()
    }
    if (exists(join(dir, 'package.json')) || exists(join(dir, 'node_modules'))) {
      // Found the 'package.json' file or 'node_modules' dir; we're done
      return dir
    }
    if (prev === dir) {
      // Got to the top
      throw new Error('Could not find module root given file: "' + file
                    + '". Do you have a `package.json` file? ')
    }
    // Try the parent dir next
    prev = dir
    dir = join(dir, '..')
  }
}
<|endoftext|>


<commit_before>"use strict";

var consolidate = require("gulp-consolidate");
var gulp = require("gulp");
var iconFont = require("gulp-iconfont");
var path = require("path");
var rename = require("gulp-rename");

var config = require("../config");
var fontName = "icon";

gulp.task("icons", function() {
    gulp.src([ path.join(config.root, "icons", "*.svg") ])
    .pipe(iconFont({
        fontName: fontName,
        appendCodepoints: true,
        normalize: true
    }))
    .on("codepoints", function(codepoints, options) {
        gulp.src([ path.resolve(__dirname, "../templates/icons.mustache") ])
        .pipe(consolidate("mustache", {
            glyphs: codepoints.map(function(point) {
                return {
                    name: point.name,
                    codepoint: point.codepoint.toString(16)
                };
            }),
            fontName: fontName,
            fontPath: "../../fonts/",
            className: "icon"
        }))
        .pipe(rename({ basename: "icons", extname: ".less" }))
        .pipe(gulp.dest(path.join(config.root, "less", "core")));
    })
    .pipe(gulp.dest(path.join(config.root, "fonts")));
});
<commit_msg>Added optional font path<commit_after>"use strict";

var consolidate = require("gulp-consolidate");
var gulp = require("gulp");
var iconFont = require("gulp-iconfont");
var path = require("path");
var rename = require("gulp-rename");

var config = require("../config");
var fontName = "icon";
var fontPath = config.fontPath || "../fonts";

gulp.task("icons", function() {
    gulp.src([ path.join(config.root, "icons", "*.svg") ])
    .pipe(iconFont({
        fontName: fontName,
        appendCodepoints: true,
        normalize: true
    }))
    .on("codepoints", function(codepoints, options) {
        gulp.src([ path.resolve(__dirname, "../templates/icons.mustache") ])
        .pipe(consolidate("mustache", {
            glyphs: codepoints.map(function(point) {
                return {
                    name: point.name,
                    codepoint: point.codepoint.toString(16)
                };
            }),
            fontName: fontName,
            fontPath: fontPath,
            className: "icon"
        }))
        .pipe(rename({ basename: "icons", extname: ".less" }))
        .pipe(gulp.dest(path.join(config.root, "less", "core")));
    })
    .pipe(gulp.dest(path.join(config.root, "fonts")));
});
<|endoftext|>


<commit_before>var config = require('../etc/config');
var mongoURI = config.mongoURI;
var MongoClient = require('mongodb').MongoClient;
var Promise = require('bluebird');

var getCollection = function(cb) {
  MongoClient.connect(mongoURI, function(err, db) {
    if(err) return cb(err);
    cb(null, db.collection('ghosts'), db);
  });
}

var Ghosts = {
  OFF: 0,
  WAITING: 1,
  READY: 2,
  find: function(query) {
    return new Promise(function(resolve, reject) {
      getCollection(function(err, collection, db) {
        if (err) return reject(err);
        collection.find(query).toArray(function(err, results) {
          if(err) return reject(err);
          resolve(results);
          db.close();
        });
      })
    });
  },
  findOne: function(query) {
    return Ghosts.find(query).then(function(results) {
      return results[0];
    })
  },
  reload: function(ghost) {
    return this.findOne({ _id: ghost._id });
  },
  // set attributes and return the new document
  set: function(ghost, data) {
    var self = this;
    return new Promise(function(resolve, reject) {
      if (!ghost) return reject(new Error("Ghost is undefined"));
      getCollection(function(err, collection, db) {
        if (err) return reject(err);
        var query = {_id: ghost._id};
        collection.update(query, { $set: data }, {w:1}, function(err) {
          if (err) return reject(err);
          collection.find(query).toArray(function(err, results) {
            if(err) return reject(err);
            resolve(results[0]);
            db.close();
          });
        });
      });
    });
  },
  updateStatus: function(ghost, status) {
    return this.set(ghost, { status: status });
  },
  updateDroplet: function(ghost, droplet) {
    return this.set(ghost, { droplet: droplet });
  },
  updateIpAddress: function(ghost, addr) {
    return this.set(ghost, { ipAddress: addr });
  }
}

module.exports = Ghosts;
<commit_msg>implement enqueueJob and createWorker on Ghost<commit_after>var monq = require('monq');
var config = require('../etc/config');
var mongoURI = config.mongoURI;
var MongoClient = require('mongodb').MongoClient;
var monqClient = monq(config.mongoURI);
var Promise = require('bluebird');
var logger = require('./logger');

var getCollection = function(cb) {
  MongoClient.connect(mongoURI, function(err, db) {
    if(err) return cb(err);
    cb(null, db.collection('ghosts'), db);
  });
}

var Ghosts = {
  OFF: 0,
  WAITING: 1,
  READY: 2,
  find: function(query) {
    return new Promise(function(resolve, reject) {
      getCollection(function(err, collection, db) {
        if (err) return reject(err);
        collection.find(query).toArray(function(err, results) {
          if(err) return reject(err);
          resolve(results);
          db.close();
        });
      })
    });
  },
  findOne: function(query) {
    return Ghosts.find(query).then(function(results) {
      return results[0];
    })
  },
  reload: function(ghost) {
    return this.findOne({ _id: ghost._id });
  },
  // set attributes and return the new document
  set: function(ghost, data) {
    var self = this;
    return new Promise(function(resolve, reject) {
      if (!ghost) return reject(new Error("Ghost is undefined"));
      getCollection(function(err, collection, db) {
        if (err) return reject(err);
        var query = {_id: ghost._id};
        collection.update(query, { $set: data }, {w:1}, function(err) {
          if (err) return reject(err);
          collection.find(query).toArray(function(err, results) {
            if(err) return reject(err);
            resolve(results[0]);
            db.close();
          });
        });
      });
    });
  },
  updateStatus: function(ghost, status) {
    return this.set(ghost, { status: status });
  },
  updateDroplet: function(ghost, droplet) {
    return this.set(ghost, { droplet: droplet });
  },
  updateIpAddress: function(ghost, addr) {
    return this.set(ghost, { ipAddress: addr });
  },
  enqueueJob: function(ghost, queueName, actionName, data) {
    var queue = monqClient.queue(queueName);
    var params = { ghostId: ghost._id, data: data }
    queue.enqueue(actionName, params, function (err, job) {
      if (err) return logger.error('enqueue failure: '+err.stack);
      logger.info('enqueued '+queueName+'::'+actionName);
    });
  },
  createWorker: function(queueName, actionName, actionFunction) {
    var worker = monqClient.worker([queueName]);
    var actions = {};
    actions[actionName] = function(params, callback) {
      Ghosts.findOne({ _id: params.ghostId }).then(function(ghost) {
        actionFunction.apply(this, [ghost, params, callback]);
      }, function() {
        logger.error('no ghost by that id');
        callback(new Error("No ghost by that id"));
      });
    }
    worker.register(actions);
    var label = queueName+'::'+actionName;
    worker.on('dequeued', function (data) {
      logger.info(label+' dequeued a job');
    });
    worker.on('failed', function (data) {
      logger.error(label+' '+data.stack);
    });
    worker.on('complete', function (data) {
      logger.info(label+' job complete');
    });
    worker.on('error', function (err) {
      logger.error(label+' '+err.stack);
    });
    return worker;
  }
}

module.exports = Ghosts;
<|endoftext|>


<commit_before>/**
 * sitemap-index.js
 *
 * An input generator for html-snapshots that uses a sitemap index xml file.
 * Creates the snapshot arguments driven from multiple sitemap.xml urls.
 *
 * Copyright (c) 2013 - 2022 Alex Grant, LocalNerve, contributors
 * Licensed under the MIT license.
 */

const xml2js = require("xml2js");
const common = require("../common");
const { sitemap: sm, sitemapIndex: smi } = require("../common/sitemap");
const base = require("./_base");

// The default options
const defaults = Object.freeze({
  source: "./sitemap-index.xml",
  sitemapPolicy: false,
  // Truthy, directs sitemapIndex sitemap file storage for sitemapPolicy purpose.
  sitemapOutputDir: "_sitemaps_"
});

// This module's export object
const sitemapIndex = {
  /**
   * Generate the input arguments for snapshots from a robots.txt file.
   * Each input argument generated calls the listener passing the input object.
   *
   * @param {Object} options - Sitemap index options.
   * @param {Function} listener - Callback to receive each input.
   * @returns {Promise} Resolves to undefined on completion.
   */
  run: (options, listener) => {
    const opts = Object.assign({}, base.defaults(defaults), options);

    return base.run(opts, generateInput, listener);
  }
};

/**
 * Parse a sitemap index document
 * For each qualifying sitemap element, download, parse the sitemap.
 * Stops processing if an error occurs.
 *
 * @param {Object} options - Sitemap options.
 * @param {Boolean} options.sitemapPolicy - True if sitemap policy should be used.
 * @param {String} document - xml document string.
 * @param {Function} callback - A completion callback.
 */
function parse (options, document, callback) {
  xml2js.parseString(document, {
    trim: true,
    normalizeTags: true,
    normalize: true
  }, (err, result) => {
    if (!err) {
      smi.process(options, result)
        .then(() => callback())
        .catch(callback);
    } else {
      callback(err);
    }
  });
}

/**
 * generateInput
 *
 * Called back by base.run to generate the input for this input type.
 * This can return true on error for true async. An async error is supplied to listener
 * in this case via _abort.
 *
 * @param {Object} options - Sitemap options.
 * @param {String} options.source - Sitemap URL or file path.
 */
function generateInput (options) {
  const retrieve = common.isUrl(options.source) ? sm.getUrl : sm.getFile;
  return retrieve(options, parse)
    .catch(err => {
      options._abort(err);
    })
    .then(() => {
      base.EOI(sitemapIndex);
    });
}

module.exports = sitemapIndex;
<commit_msg>reuse sm.parse for sitemapindex<commit_after>/**
 * sitemap-index.js
 *
 * An input generator for html-snapshots that uses a sitemap index xml file.
 * Creates the snapshot arguments driven from multiple sitemap.xml urls.
 *
 * Copyright (c) 2013 - 2022 Alex Grant, LocalNerve, contributors
 * Licensed under the MIT license.
 */
const common = require("../common");
const { sitemap: sm } = require("../common/sitemap");
const base = require("./_base");

// The default options
const defaults = Object.freeze({
  source: "./sitemap-index.xml",
  sitemapPolicy: false,
  // Truthy, directs sitemapIndex sitemap file storage for sitemapPolicy purpose.
  sitemapOutputDir: "_sitemaps_"
});

// This module's export object
const sitemapIndex = {
  /**
   * Generate the input arguments for snapshots from a robots.txt file.
   * Each input argument generated calls the listener passing the input object.
   *
   * @param {Object} options - Sitemap index options.
   * @param {Function} listener - Callback to receive each input.
   * @returns {Promise} Resolves to undefined on completion.
   */
  run: (options, listener) => {
    const opts = Object.assign({}, base.defaults(defaults), options);

    return base.run(opts, generateInput, listener);
  }
};

/**
 * generateInput
 *
 * Called back by base.run to generate the input for this input type.
 * This can return true on error for true async. An async error is supplied to listener
 * in this case via _abort.
 *
 * @param {Object} options - Sitemap options.
 * @param {String} options.source - Sitemap URL or file path.
 */
function generateInput (options) {
  const retrieve = common.isUrl(options.source) ? sm.getUrl : sm.getFile;
  return retrieve(options, sm.parse)
    .catch(err => {
      options._abort(err);
    })
    .then(() => {
      base.EOI(sitemapIndex);
    });
}

module.exports = sitemapIndex;
<|endoftext|>