<commit_before>sb.include('flashGate');
/**
@Name: sb.sound
@Author: Paul Visco
@Description: A constructor for creating new sound object instances.  Allows javascript to load, play and stop mp3 sounds.
@Param String url The url of the file to play
@Example:
var yellow = new sb.sound(
	url : 'yellow.mp3',
	debug : true,
	onID3 : function(){},
	onProgress : function(){}
);
yellow.play();
*/
sb.sound = function(params){
	if(!params.url){
		throw('You must pass a url to the sb.sound');
	}

	for(var prop in params){
		this[prop] = params[prop];
	}

	this.id = sb.flashGate.getInterface().sound_create(this.url, this.debug);
	sb.sound.sounds[this.id] = this;
};

/**
@Name: sb.sound.sounds
@Description: Used Internally
*/
sb.sound.sounds = [];

/**
@Name: sb.sound.stopAll
@Description: Stops all sounds playing on the page
@Param String url Optional The url of the file to stop
@Example:
sb.sound.stopAll();
//or
sb.sound.stopAll('yellow.mp3');
*/
sb.sound.stopAll = function(url){
	url = url || '';
	sb.flashGate.getInterface().sounds_stop_all(url);
};

/**
@Name: sb.sound.stopAll
@Description: Sets the global volume of all sounds
@Param Float A float between 0 and 1
@Example:
sb.sound.setGlobalVolume(0.5);
*/

sb.sound.setGlobalVolume = function(volume){
	sb.flashGate.getInterface().sounds_set_global_volume(volume);
};

/**
@Name: sb.sound.muteAll
@Description: Mutes all sounds playing on the page
@Param String url Optional The url of the file to mute
@Example:
sb.sound.muteAll();
//or
sb.sound.muteAll('yellow.mp3');
*/
sb.sound.muteAll = function(){
	sb.flashGate.getInterface().sounds_mute_all();
};

/**
@Name: sb.sound.prototype
@Description: The methods of sb.sound instances
*/
sb.sound.prototype = {

	duration : -1,
	/**
	@Name: sb.sound.prototype.url
	@Description: String The url of the mp3 file
	*/
	url : '',

	/**
	@Name: sb.sound.prototype.id
	@Description: Used Internally
	*/
	id : 0,

	/**
	@Name: sb.sound.prototype.play
	@Param Number position The position to start the file at in milliseconds
	@Param Number loops The number of times to repeat the sound
	@Description: Plays the sound file
	@Example:
	mySound.play();
	*/
	play : function(position, loops){
		position = position || 0;
		loops = loops || 0;
		return sb.flashGate.getInterface().sound_play(this.id, position, loops);
	},

	/**
	@Name: sb.sound.prototype.stop
	@Description: Stops the sound file
	@Example:
	mySound.play();
	*/
	stop : function(){
		return sb.flashGate.getInterface().sound_stop(this.id);
	},

	/**
	@Name: sb.sound.prototype.getPosition
	@Description: Gets the current position in milliseconds
	@Return: Number return the current position in milliseconds
	@Example:
	mySound.getPosition();
	*/
	getPosition : function(){
		return sb.flashGate.getInterface().sound_get_position(this.id);
	},

	/**
	@Name: sb.sound.prototype.setPositionPercent
	@Description: Moves the playhead to a certain position in percent of total
	@Example:
	mySound.setPositionPercent(40);
	*/
	setPositionPercent : function(percent){
		return sb.flashGate.getInterface().sound_set_position_percent(this.id, percent);
	},

	/**
	@Name: sb.sound.prototype.getPositionPercent
	@Description: Gets the current position in percent of total
	@Return: Number return the current position in percent of total
	@Example:
	mySound.getPositionPercent();
	*/
	getPositionPercent : function(){
		return sb.flashGate.getInterface().sound_get_position_percent(this.id);
	},

	/**
	@Name: sb.sound.prototype.setPosition
	@Description: Moves the playhead to a certain position in milliseconds
	@Example:
	mySound.setPosition(4135);
	*/
	setPosition : function(position){
		return sb.flashGate.getInterface().sound_set_position(this.id, position);
	},

	/**
	@Name: sb.sound.prototype.getVolume
	@Description: Gets the current volume
	@Return: float between 0 and 1
	@Example:
	mySound.getVolume();
	*/
	getVolume : function(volume){
		return sb.flashGate.getInterface().sound_get_volume(this.id);
	},

	/**
	@Name: sb.sound.prototype.getVolume
	@Description: Gets the current volume
	@Param: Float volume between 0 and 1
	@Example:
	mySound.setVolume(0.5);
	*/
	setVolume : function(volume){
		sb.flashGate.getInterface().sound_set_volume(this.id, volume);
	},

	/**
	@Name: sb.sound.prototype.getPan
	@Description: Gets the current pan position
	@Return: float between -1 (left) and 1 (right)
	@Example:
	mySound.getPan();
	*/
	getPan : function(){
		return sb.flashGate.getInterface().sound_get_pan(this.id);
	},

	/**
	@Name: sb.sound.prototype.setPan
	@Description: sets the current pan position
	@Param: float pan between -1 (left) and 1 (right)
	@Example:
	mySound.setPan(0.5);
	*/
	setPan : function(pan){
		sb.flashGate.getInterface().sound_set_pan(this.id, pan);
	},

	/**
	@Name: sb.sound.prototype.mute
	@Description: sets the volume to zero for this sound but keeps playing
	@Example:
	mySound.mute();
	*/
	mute : function(){
		this.setVolume(0);
	},
	//tags.album, tags.year, tags.artist, tags.songName, tags.comment, tags.track, tags.genre
	onID3 : function(){},
	//song.sizeK, song.bytesLoaded, song.bytesTotal
	onLoad : function(){},
	//message
	onError : function(){}
};<commit_msg>added onProgress method comments to sound.js<commit_after>sb.include('flashGate');
/**
@Name: sb.sound
@Author: Paul Visco
@Description: A constructor for creating new sound object instances.  Allows javascript to load, play and stop mp3 sounds.
@Param String url The url of the file to play
@Example:
var yellow = new sb.sound(
	url : 'yellow.mp3',
	debug : true,
	onID3 : function(){},
	onProgress : function(){}
);
yellow.play();
*/
sb.sound = function(params){
	if(!params.url){
		throw('You must pass a url to the sb.sound');
	}

	for(var prop in params){
		this[prop] = params[prop];
	}

	this.id = sb.flashGate.getInterface().sound_create(this.url, this.debug);
	sb.sound.sounds[this.id] = this;
};

/**
@Name: sb.sound.sounds
@Description: Used Internally
*/
sb.sound.sounds = [];

/**
@Name: sb.sound.stopAll
@Description: Stops all sounds playing on the page
@Param String url Optional The url of the file to stop
@Example:
sb.sound.stopAll();
//or
sb.sound.stopAll('yellow.mp3');
*/
sb.sound.stopAll = function(url){
	url = url || '';
	sb.flashGate.getInterface().sounds_stop_all(url);
};

/**
@Name: sb.sound.stopAll
@Description: Sets the global volume of all sounds
@Param Float A float between 0 and 1
@Example:
sb.sound.setGlobalVolume(0.5);
*/

sb.sound.setGlobalVolume = function(volume){
	sb.flashGate.getInterface().sounds_set_global_volume(volume);
};

/**
@Name: sb.sound.muteAll
@Description: Mutes all sounds playing on the page
@Param String url Optional The url of the file to mute
@Example:
sb.sound.muteAll();
//or
sb.sound.muteAll('yellow.mp3');
*/
sb.sound.muteAll = function(){
	sb.flashGate.getInterface().sounds_mute_all();
};

/**
@Name: sb.sound.prototype
@Description: The methods of sb.sound instances
*/
sb.sound.prototype = {

	duration : -1,
	/**
	@Name: sb.sound.prototype.url
	@Description: String The url of the mp3 file
	*/
	url : '',

	/**
	@Name: sb.sound.prototype.id
	@Description: Used Internally
	*/
	id : 0,

	/**
	@Name: sb.sound.prototype.play
	@Param Number position The position to start the file at in milliseconds
	@Param Number loops The number of times to repeat the sound
	@Description: Plays the sound file
	@Example:
	mySound.play();
	*/
	play : function(position, loops){
		position = position || 0;
		loops = loops || 0;
		return sb.flashGate.getInterface().sound_play(this.id, position, loops);
	},

	/**
	@Name: sb.sound.prototype.stop
	@Description: Stops the sound file
	@Example:
	mySound.play();
	*/
	stop : function(){
		return sb.flashGate.getInterface().sound_stop(this.id);
	},

	/**
	@Name: sb.sound.prototype.getPosition
	@Description: Gets the current position in milliseconds
	@Return: Number return the current position in milliseconds
	@Example:
	mySound.getPosition();
	*/
	getPosition : function(){
		return sb.flashGate.getInterface().sound_get_position(this.id);
	},

	/**
	@Name: sb.sound.prototype.setPositionPercent
	@Description: Moves the playhead to a certain position in percent of total
	@Example:
	mySound.setPositionPercent(40);
	*/
	setPositionPercent : function(percent){
		return sb.flashGate.getInterface().sound_set_position_percent(this.id, percent);
	},

	/**
	@Name: sb.sound.prototype.getPositionPercent
	@Description: Gets the current position in percent of total
	@Return: Number return the current position in percent of total
	@Example:
	mySound.getPositionPercent();
	*/
	getPositionPercent : function(){
		return sb.flashGate.getInterface().sound_get_position_percent(this.id);
	},

	/**
	@Name: sb.sound.prototype.setPosition
	@Description: Moves the playhead to a certain position in milliseconds
	@Example:
	mySound.setPosition(4135);
	*/
	setPosition : function(position){
		return sb.flashGate.getInterface().sound_set_position(this.id, position);
	},

	/**
	@Name: sb.sound.prototype.getVolume
	@Description: Gets the current volume
	@Return: float between 0 and 1
	@Example:
	mySound.getVolume();
	*/
	getVolume : function(volume){
		return sb.flashGate.getInterface().sound_get_volume(this.id);
	},

	/**
	@Name: sb.sound.prototype.getVolume
	@Description: Gets the current volume
	@Param: Float volume between 0 and 1
	@Example:
	mySound.setVolume(0.5);
	*/
	setVolume : function(volume){
		sb.flashGate.getInterface().sound_set_volume(this.id, volume);
	},

	/**
	@Name: sb.sound.prototype.getPan
	@Description: Gets the current pan position
	@Return: float between -1 (left) and 1 (right)
	@Example:
	mySound.getPan();
	*/
	getPan : function(){
		return sb.flashGate.getInterface().sound_get_pan(this.id);
	},

	/**
	@Name: sb.sound.prototype.setPan
	@Description: sets the current pan position
	@Param: float pan between -1 (left) and 1 (right)
	@Example:
	mySound.setPan(0.5);
	*/
	setPan : function(pan){
		sb.flashGate.getInterface().sound_set_pan(this.id, pan);
	},

	/**
	@Name: sb.sound.prototype.mute
	@Description: sets the volume to zero for this sound but keeps playing
	@Example:
	mySound.mute();
	*/
	mute : function(){
		this.setVolume(0);
	},
	//tags.album, tags.year, tags.artist, tags.songName, tags.comment, tags.track, tags.genre
	onID3 : function(){},
	//song.sizeK, song.bytesLoaded, song.bytesTotal
	onLoad : function(){},
	//message
	onError : function(){},
	//song.position, song.length, song.percent
	onProgress : function(data){}
};<|endoftext|>


<commit_before>'use strict';

var ReactNative = require('react-native');
var RNSound = ReactNative.NativeModules.RNSound;
var IsAndroid = RNSound.IsAndroid;
var IsWindows = RNSound.IsWindows;
var resolveAssetSource = require("react-native/Libraries/Image/resolveAssetSource");
var eventEmitter = new ReactNative.NativeEventEmitter(RNSound);

var nextKey = 0;

function isRelativePath(path) {
  return !/^(\/|http(s?)|asset)/.test(path);
}

function Sound(filename, basePath, onError, options) {
  var asset = resolveAssetSource(filename);
  if (asset) {
    this._filename = asset.uri;
    onError = basePath;
  } else {
    this._filename = basePath ? basePath + '/' + filename : filename;

    if (IsAndroid && !basePath && isRelativePath(filename)) {
      this._filename = filename.toLowerCase().replace(/\.[^.]+$/, '');
    }
  }

  this.registerOnPlay = function() {
    if (this.onPlaySubscription != null) {
      console.warn('On Play change event listener is already registered');
      return;
    }

    if (!IsWindows) {
      this.onPlaySubscription = eventEmitter.addListener(
        'onPlayChange',
        (param) => {
          const { isPlaying, playerKey } = param;
          if (playerKey === this._key) {
            if (isPlaying) {
              this._playing = true;
            }
            else {
              this._playing = false;
            }
          }
        },
      );
    }
  }

  this._loaded = false;
  this._key = nextKey++;
  this._playing = false;
  this._duration = -1;
  this._numberOfChannels = -1;
  this._volume = 1;
  this._pan = 0;
  this._numberOfLoops = 0;
  this._speed = 1;
  this._pitch = 1;
  RNSound.prepare(this._filename, this._key, options || {}, (error, props) => {
    if (props) {
      if (typeof props.duration === 'number') {
        this._duration = props.duration;
      }
      if (typeof props.numberOfChannels === 'number') {
        this._numberOfChannels = props.numberOfChannels;
      }
    }
    if (error === null) {
      this._loaded = true;
      this.registerOnPlay();
    }
    onError && onError(error, props);
  });
}

Sound.prototype.isLoaded = function() {
  return this._loaded;
};

Sound.prototype.play = function(onEnd) {
  if (this._loaded) {
    RNSound.play(this._key, (successfully) => onEnd && onEnd(successfully));
  } else {
    onEnd && onEnd(false);
  }
  return this;
};

Sound.prototype.pause = function(callback) {
  if (this._loaded) {
    RNSound.pause(this._key, () => {
      this._playing = false;
      callback && callback();
    });
  }
  return this;
};

Sound.prototype.stop = function(callback) {
  if (this._loaded) {
    RNSound.stop(this._key, () => {
      this._playing = false;
      callback && callback();
    });
  }
  return this;
};

Sound.prototype.reset = function() {
  if (this._loaded && IsAndroid) {
    RNSound.reset(this._key);
    this._playing = false;
  }
  return this;
};

Sound.prototype.release = function() {
  if (this._loaded) {
    RNSound.release(this._key);
    this._loaded = false;
    if (!IsWindows) {
      if (this.onPlaySubscription != null) {
        this.onPlaySubscription.remove();
        this.onPlaySubscription = null;
      }
    }
  }
  return this;
};

Sound.prototype.getDuration = function() {
  return this._duration;
};

Sound.prototype.getNumberOfChannels = function() {
  return this._numberOfChannels;
};

Sound.prototype.getVolume = function() {
  return this._volume;
};

Sound.prototype.getSpeed = function() {
  return this._speed;
};

Sound.prototype.getPitch = function() {
  return this._pitch;
};

Sound.prototype.setVolume = function(value) {
  this._volume = value;
  if (this._loaded) {
    if (IsAndroid || IsWindows) {
      RNSound.setVolume(this._key, value, value);
    } else {
      RNSound.setVolume(this._key, value);
    }
  }
  return this;
};

Sound.prototype.getSystemVolume = function(callback) {
  if(!IsWindows) {
    RNSound.getSystemVolume(callback);
  }
  return this;
};

Sound.prototype.setSystemVolume = function(value) {
  if (IsAndroid) {
    RNSound.setSystemVolume(value);
  }
  return this;
};

Sound.prototype.getPan = function() {
  return this._pan;
};

Sound.prototype.setPan = function(value) {
  if (this._loaded) {
    RNSound.setPan(this._key, this._pan = value);
  }
  return this;
};

Sound.prototype.getNumberOfLoops = function() {
  return this._numberOfLoops;
};

Sound.prototype.setNumberOfLoops = function(value) {
  this._numberOfLoops = value;
  if (this._loaded) {
    if (IsAndroid || IsWindows) {
      RNSound.setLooping(this._key, !!value);
    } else {
      RNSound.setNumberOfLoops(this._key, value);
    }
  }
  return this;
};

Sound.prototype.setSpeed = function(value) {
  this._speed = value;
  if (this._loaded) {
    if (!IsWindows) {
      RNSound.setSpeed(this._key, value);
    }
  }
  return this;
};

Sound.prototype.setPitch = function(value) {
  this._pitch = value;
  if (this._loaded) {
    if (IsAndroid) {
      RNSound.setPitch(this._key, value);
    }
  }
  return this;
};

Sound.prototype.getCurrentTime = function(callback) {
  if (this._loaded) {
    RNSound.getCurrentTime(this._key, callback);
  }
};

Sound.prototype.setCurrentTime = function(value) {
  if (this._loaded) {
    RNSound.setCurrentTime(this._key, value);
  }
  return this;
};

// android only
Sound.prototype.setSpeakerphoneOn = function(value) {
  if (IsAndroid) {
    RNSound.setSpeakerphoneOn(this._key, value);
  }
};

// ios only

// This is deprecated.  Call the static one instead.

Sound.prototype.setCategory = function(value) {
  Sound.setCategory(value, false);
}

Sound.prototype.isPlaying = function() {
  return this._playing;
}

Sound.enable = function(enabled) {
  RNSound.enable(enabled);
};

Sound.enableInSilenceMode = function(enabled) {
  if (!IsAndroid && !IsWindows) {
    RNSound.enableInSilenceMode(enabled);
  }
};

Sound.setActive = function(value) {
  if (!IsAndroid && !IsWindows) {
    RNSound.setActive(value);
  }
};

Sound.setCategory = function(value, mixWithOthers = false) {
  if (!IsWindows) {
    RNSound.setCategory(value, mixWithOthers);
  }
};

Sound.setMode = function(value) {
  if (!IsAndroid && !IsWindows) {
    RNSound.setMode(value);
  }
};

Sound.setSpeakerPhone = function(value) {
  if (!IsAndroid && !IsWindows) {
    RNSound.setSpeakerPhone(value)
  }
}

Sound.MAIN_BUNDLE = RNSound.MainBundlePath;
Sound.DOCUMENT = RNSound.NSDocumentDirectory;
Sound.LIBRARY = RNSound.NSLibraryDirectory;
Sound.CACHES = RNSound.NSCachesDirectory;

module.exports = Sound;
<commit_msg>Added setPan behavior for android (#443)<commit_after>'use strict';

var ReactNative = require('react-native');
var RNSound = ReactNative.NativeModules.RNSound;
var IsAndroid = RNSound.IsAndroid;
var IsWindows = RNSound.IsWindows;
var resolveAssetSource = require("react-native/Libraries/Image/resolveAssetSource");
var eventEmitter = new ReactNative.NativeEventEmitter(RNSound);

var nextKey = 0;

function isRelativePath(path) {
  return !/^(\/|http(s?)|asset)/.test(path);
}

function calculateRelativeVolume(volume, pan) {
  // calculates a lower volume relative to the pan value
  const relativeVolume = (volume * (1 - Math.abs(pan)));
  return Number(relativeVolume.toFixed(1));
}

function setAndroidVolumes(sound) {
  // calculates the volumes for left and right channels
  if (sound._pan) {
    const relativeVolume = calculateRelativeVolume(sound._volume, sound._pan);
    if (sound._pan < 0) {
      // left is louder
      RNSound.setVolume(sound._key, sound._volume, relativeVolume);
    } else {
      // right is louder
      RNSound.setVolume(sound._key, relativeVolume, sound._volume);
    }
  } else {
    // no panning, same volume on both channels
    RNSound.setVolume(sound._key, sound._volume, sound._volume);
  }
}

function Sound(filename, basePath, onError, options) {
  var asset = resolveAssetSource(filename);
  if (asset) {
    this._filename = asset.uri;
    onError = basePath;
  } else {
    this._filename = basePath ? basePath + '/' + filename : filename;

    if (IsAndroid && !basePath && isRelativePath(filename)) {
      this._filename = filename.toLowerCase().replace(/\.[^.]+$/, '');
    }
  }

  this.registerOnPlay = function() {
    if (this.onPlaySubscription != null) {
      console.warn('On Play change event listener is already registered');
      return;
    }

    if (!IsWindows) {
      this.onPlaySubscription = eventEmitter.addListener(
        'onPlayChange',
        (param) => {
          const { isPlaying, playerKey } = param;
          if (playerKey === this._key) {
            if (isPlaying) {
              this._playing = true;
            }
            else {
              this._playing = false;
            }
          }
        },
      );
    }
  }

  this._loaded = false;
  this._key = nextKey++;
  this._playing = false;
  this._duration = -1;
  this._numberOfChannels = -1;
  this._volume = 1;
  this._pan = 0;
  this._numberOfLoops = 0;
  this._speed = 1;
  this._pitch = 1;
  RNSound.prepare(this._filename, this._key, options || {}, (error, props) => {
    if (props) {
      if (typeof props.duration === 'number') {
        this._duration = props.duration;
      }
      if (typeof props.numberOfChannels === 'number') {
        this._numberOfChannels = props.numberOfChannels;
      }
    }
    if (error === null) {
      this._loaded = true;
      this.registerOnPlay();
    }
    onError && onError(error, props);
  });
}

Sound.prototype.isLoaded = function() {
  return this._loaded;
};

Sound.prototype.play = function(onEnd) {
  if (this._loaded) {
    RNSound.play(this._key, (successfully) => onEnd && onEnd(successfully));
  } else {
    onEnd && onEnd(false);
  }
  return this;
};

Sound.prototype.pause = function(callback) {
  if (this._loaded) {
    RNSound.pause(this._key, () => {
      this._playing = false;
      callback && callback();
    });
  }
  return this;
};

Sound.prototype.stop = function(callback) {
  if (this._loaded) {
    RNSound.stop(this._key, () => {
      this._playing = false;
      callback && callback();
    });
  }
  return this;
};

Sound.prototype.reset = function() {
  if (this._loaded && IsAndroid) {
    RNSound.reset(this._key);
    this._playing = false;
  }
  return this;
};

Sound.prototype.release = function() {
  if (this._loaded) {
    RNSound.release(this._key);
    this._loaded = false;
    if (!IsWindows) {
      if (this.onPlaySubscription != null) {
        this.onPlaySubscription.remove();
        this.onPlaySubscription = null;
      }
    }
  }
  return this;
};

Sound.prototype.getDuration = function() {
  return this._duration;
};

Sound.prototype.getNumberOfChannels = function() {
  return this._numberOfChannels;
};

Sound.prototype.getVolume = function() {
  return this._volume;
};

Sound.prototype.getSpeed = function() {
  return this._speed;
};

Sound.prototype.getPitch = function() {
  return this._pitch;
};

Sound.prototype.setVolume = function(value) {
  this._volume = value;
  if (this._loaded) {
    if (IsAndroid) {
      setAndroidVolumes(this)
    } else {
      RNSound.setVolume(this._key, value);
    }
  }
  return this;
};

Sound.prototype.setPan = function(value) {
  this._pan = value;
  if (this._loaded) {
    if (IsWindows) {
      throw new Error('#setPan not supported on windows');
    } else if (IsAndroid) {
      setAndroidVolumes(this)
    } else {
      RNSound.setPan(this._key, value);
    }
  }
  return this;
};

Sound.prototype.getSystemVolume = function(callback) {
  if(!IsWindows) {
    RNSound.getSystemVolume(callback);
  }
  return this;
};

Sound.prototype.setSystemVolume = function(value) {
  if (IsAndroid) {
    RNSound.setSystemVolume(value);
  }
  return this;
};

Sound.prototype.getPan = function() {
  return this._pan;
};

Sound.prototype.getNumberOfLoops = function() {
  return this._numberOfLoops;
};

Sound.prototype.setNumberOfLoops = function(value) {
  this._numberOfLoops = value;
  if (this._loaded) {
    if (IsAndroid || IsWindows) {
      RNSound.setLooping(this._key, !!value);
    } else {
      RNSound.setNumberOfLoops(this._key, value);
    }
  }
  return this;
};

Sound.prototype.setSpeed = function(value) {
  this._speed = value;
  if (this._loaded) {
    if (!IsWindows) {
      RNSound.setSpeed(this._key, value);
    }
  }
  return this;
};

Sound.prototype.setPitch = function(value) {
  this._pitch = value;
  if (this._loaded) {
    if (IsAndroid) {
      RNSound.setPitch(this._key, value);
    }
  }
  return this;
};

Sound.prototype.getCurrentTime = function(callback) {
  if (this._loaded) {
    RNSound.getCurrentTime(this._key, callback);
  }
};

Sound.prototype.setCurrentTime = function(value) {
  if (this._loaded) {
    RNSound.setCurrentTime(this._key, value);
  }
  return this;
};

// android only
Sound.prototype.setSpeakerphoneOn = function(value) {
  if (IsAndroid) {
    RNSound.setSpeakerphoneOn(this._key, value);
  }
};

// ios only

// This is deprecated.  Call the static one instead.

Sound.prototype.setCategory = function(value) {
  Sound.setCategory(value, false);
}

Sound.prototype.isPlaying = function() {
  return this._playing;
}

Sound.enable = function(enabled) {
  RNSound.enable(enabled);
};

Sound.enableInSilenceMode = function(enabled) {
  if (!IsAndroid && !IsWindows) {
    RNSound.enableInSilenceMode(enabled);
  }
};

Sound.setActive = function(value) {
  if (!IsAndroid && !IsWindows) {
    RNSound.setActive(value);
  }
};

Sound.setCategory = function(value, mixWithOthers = false) {
  if (!IsWindows) {
    RNSound.setCategory(value, mixWithOthers);
  }
};

Sound.setMode = function(value) {
  if (!IsAndroid && !IsWindows) {
    RNSound.setMode(value);
  }
};

Sound.setSpeakerPhone = function(value) {
  if (!IsAndroid && !IsWindows) {
    RNSound.setSpeakerPhone(value)
  }
}

Sound.MAIN_BUNDLE = RNSound.MainBundlePath;
Sound.DOCUMENT = RNSound.NSDocumentDirectory;
Sound.LIBRARY = RNSound.NSLibraryDirectory;
Sound.CACHES = RNSound.NSCachesDirectory;

module.exports = Sound;
<|endoftext|>


<commit_before>var paused = true,
    spiro,
    canvas,
    context,
    line_canvas,
    line_context,
    circle_canvas,
    circle_context,
    center,
    point;

function Gear(x, y, radius) {
    'use strict';
    this.x = x;
    this.y = y;
    this.radius = radius;
}

function Line(length, speed) {
    'use strict';
    this.length = length;
    this.speed = speed;
    this.rotation = 0;
}

Line.prototype.step = function() {
    'use strict';
    var x, y, rads;
    this.rotation += this.speed;
    rads = Math.PI * this.rotation / 360;
    x = this.length * Math.cos(rads);
    y = this.length * Math.sin(rads);
    return [x, y];
};

function Spirograph() {
    'use strict';
    this.lines = [];
    this.lines.push(new Line(400, 2));
    this.gears = [];
    this.gears.push(new Gear(center[0], center[1], 400));
    this.size = 0;
}

Spirograph.prototype.add_gear = function(percent, direction) {
    'use strict';
    var line_len, last_line, new_line, new_speed, real_perc;
    last_line = this.lines[this.lines.length - 1];
    line_len = last_line.length * percent / 100;
    real_perc = percent / 100;
    new_speed = Math.abs(last_line.speed / real_perc) * (1 - real_perc);
    if (direction) {
        new_speed *= -1;
    }
    last_line.length *= ((100 - percent) / 100);
    new_line = new Line(line_len, new_speed);
    new_line.rotation = last_line.rotation;
    this.lines.push(new_line);
    this.gears.push(new Gear(center[0] * 2 - line_len, center[1], line_len));
    update_gearlist();
};

Spirograph.prototype.step = function() {
    'use strict';
    var len, i, line, gear, vector, delta;
    delta = [0, 0];
    delta[0] += center[0];
    delta[1] += center[1];
    for (i = 0; i < this.lines.length; i++) {
        this.gears[i].x = delta[0];
        this.gears[i].y = delta[1];
        line = this.lines[i];
        vector = line.step();
        delta[0] += vector[0];
        delta[1] += vector[1];
    }
    return delta;
};

function mainloop() {
    'use strict';
    if (paused === false) {
        draw_lines();
        draw_circles();

        // draw everything on the visible canvas
        context.clearRect(0, 0, canvas.width, canvas.height);
        context.drawImage(circle_canvas, 0, 0);
        context.drawImage(line_canvas, 0, 0);

        setTimeout(mainloop, 10);
    }
}

function draw_lines() {
        // update the line on off-screen canvas
        line_context.moveTo(point[0], point[1]);
        point = spiro.step();
        line_context.lineTo(point[0], point[1]);
        line_context.stroke();
}

function draw_circles() {
        // predraw the circles on off-screen canvas
        var i, lines, gear;
        lines = spiro.lines;
        circle_context.clearRect(0, 0, canvas.width, canvas.height);
        circle_context.beginPath();
        circle_context.arc(point[0], point[1], 3, 0, Math.PI * 2, false);
        for (i = 0; i < spiro.gears.length; i++) {
            gear = spiro.gears[i];
            circle_context.moveTo(gear.x + gear.radius, gear.y);
            circle_context.arc(gear.x, gear.y, gear.radius, 0,
                    Math.PI * 2, false);
        }
        circle_context.stroke();
}

function toggle_pause() {
    'use strict';
    var pause = document.getElementById("pause");
    if (paused === true) {
        paused = false;
        pause.innerHTML = "Pause";
        mainloop();
    } else {
        paused = true;
        pause.innerHTML = "Start";
    }
    return false;
}

function new_gear() {
    var percent = parseFloat(document.getElementById('gearsize').value);
    var direction = document.getElementById('direction').checked;
    line_context.clearRect(0, 0, canvas.width, canvas.height);
    spiro.add_gear(percent, direction);
    draw_circles();
    line_context.clearRect(0, 0, canvas.width, canvas.height);
    context.drawImage(circle_canvas, 0, 0);
}

function del_gear() {
    var line = spiro.lines.pop();
    spiro.lines[spiro.lines.length - 1].length += line.length;
    spiro.gears.pop();
    update_gearlist();
}

function readKey(event) {
    'use strict';
    switch (event.keyCode) {
        case 32:
            toggle_pause();
            break;
    }
    // console.log(event.keyCode);
}

function update_gearlist() {
    'use strict';
    var gearlist, content, i, gears, lines;
    gearlist = document.getElementById('list');
    gears = spiro.gears;
    lines = spiro.lines;
    content = "";
    content += 'You have ' + gears.length + ' gears.
';
    for (i = 0; i < gears.length; i++) {
        content += "Gear " + (i + 1) + ": " + gears[i].radius + " ";
        if (lines[i].speed > 0) {
            content += "->";
        } else {
            content += "<-";
        }
        content += "
";
    }
    gearlist.innerHTML = content;
}

function init() {
    'use strict';

    // visible "main" canvas
    canvas = document.getElementById('canv');
    context = canvas.getContext('2d');

    // own context for spirograph line since it doesn't need redrawing
    line_canvas = document.createElement('canvas');
    line_canvas.width = canvas.width;
    line_canvas.height = canvas.height;
    line_context = line_canvas.getContext('2d');
    line_context.clearRect(0, 0, canvas.width, canvas.height);
    line_context.strokeStyle = '#666666';

    // own context for spirograph "gears" since they are redrawn each frame
    circle_canvas = document.createElement('canvas');
    circle_canvas.width = canvas.width;
    circle_canvas.height = canvas.height;
    circle_context = circle_canvas.getContext('2d');
    circle_context.clearRect(0, 0, canvas.width, canvas.height);
    circle_context.strokeStyle = '#888888';

    center = [canvas.width / 2, canvas.height / 2];
    spiro = new Spirograph();
    update_gearlist();
    point = spiro.step();
    paused = true;
    draw_circles();
    context.clearRect(0, 0, canvas.width, canvas.height);
    context.drawImage(circle_canvas, 0, 0);
    mainloop();
}
<commit_msg>fixed a performance degradation<commit_after>var paused = true,
    spiro,
    canvas,
    context,
    line_canvas,
    line_context,
    circle_canvas,
    circle_context,
    center,
    point;

function Gear(x, y, radius) {
    'use strict';
    this.x = x;
    this.y = y;
    this.radius = radius;
}

function Line(length, speed) {
    'use strict';
    this.length = length;
    this.speed = speed;
    this.rotation = 0;
}

Line.prototype.step = function() {
    'use strict';
    var x, y, rads;
    this.rotation += this.speed;
    rads = Math.PI * this.rotation / 360;
    x = this.length * Math.cos(rads);
    y = this.length * Math.sin(rads);
    return [x, y];
};

function Spirograph() {
    'use strict';
    this.lines = [];
    this.lines.push(new Line(400, 2));
    this.gears = [];
    this.gears.push(new Gear(center[0], center[1], 400));
    this.size = 0;
}

Spirograph.prototype.add_gear = function(percent, direction) {
    'use strict';
    var line_len, last_line, new_line, new_speed, real_perc;
    last_line = this.lines[this.lines.length - 1];
    line_len = last_line.length * percent / 100;
    real_perc = percent / 100;
    new_speed = Math.abs(last_line.speed / real_perc) * (1 - real_perc);
    if (direction) {
        new_speed *= -1;
    }
    last_line.length *= ((100 - percent) / 100);
    new_line = new Line(line_len, new_speed);
    new_line.rotation = last_line.rotation;
    this.lines.push(new_line);
    this.gears.push(new Gear(center[0] * 2 - line_len, center[1], line_len));
    update_gearlist();
};

Spirograph.prototype.step = function() {
    'use strict';
    var len, i, line, gear, vector, delta;
    delta = [0, 0];
    delta[0] += center[0];
    delta[1] += center[1];
    for (i = 0; i < this.lines.length; i++) {
        this.gears[i].x = delta[0];
        this.gears[i].y = delta[1];
        line = this.lines[i];
        vector = line.step();
        delta[0] += vector[0];
        delta[1] += vector[1];
    }
    return delta;
};

function mainloop() {
    'use strict';
    if (paused === false) {
        draw_lines();
        draw_circles();

        // draw everything on the visible canvas
        context.clearRect(0, 0, canvas.width, canvas.height);
        context.drawImage(circle_canvas, 0, 0);
        context.drawImage(line_canvas, 0, 0);

        setTimeout(mainloop, 10);
    }
}

function draw_lines() {
        // update the line on off-screen canvas
        line_context.beginPath();
        line_context.moveTo(point[0], point[1]);
        point = spiro.step();
        line_context.lineTo(point[0], point[1]);
        line_context.stroke();
}

function draw_circles() {
        // predraw the circles on off-screen canvas
        var i, lines, gear;
        lines = spiro.lines;
        circle_context.clearRect(0, 0, canvas.width, canvas.height);
        circle_context.beginPath();
        circle_context.arc(point[0], point[1], 3, 0, Math.PI * 2, false);
        for (i = 0; i < spiro.gears.length; i++) {
            gear = spiro.gears[i];
            circle_context.moveTo(gear.x + gear.radius, gear.y);
            circle_context.arc(gear.x, gear.y, gear.radius, 0,
                    Math.PI * 2, false);
        }
        circle_context.stroke();
}

function toggle_pause() {
    'use strict';
    var pause = document.getElementById("pause");
    if (paused === true) {
        paused = false;
        pause.innerHTML = "Pause";
        mainloop();
    } else {
        paused = true;
        pause.innerHTML = "Start";
    }
    return false;
}

function new_gear() {
    var percent = parseFloat(document.getElementById('gearsize').value);
    var direction = document.getElementById('direction').checked;
    line_context.clearRect(0, 0, canvas.width, canvas.height);
    spiro.add_gear(percent, direction);
    draw_circles();
    line_context.clearRect(0, 0, canvas.width, canvas.height);
    context.drawImage(circle_canvas, 0, 0);
}

function del_gear() {
    var line = spiro.lines.pop();
    spiro.lines[spiro.lines.length - 1].length += line.length;
    spiro.gears.pop();
    update_gearlist();
}

function readKey(event) {
    'use strict';
    switch (event.keyCode) {
        case 32:
            toggle_pause();
            break;
    }
    // console.log(event.keyCode);
}

function update_gearlist() {
    'use strict';
    var gearlist, content, i, gears, lines;
    gearlist = document.getElementById('list');
    gears = spiro.gears;
    lines = spiro.lines;
    content = "";
    content += 'You have ' + gears.length + ' gears.
';
    for (i = 0; i < gears.length; i++) {
        content += "Gear " + (i + 1) + ": " + gears[i].radius + " ";
        if (lines[i].speed > 0) {
            content += "->";
        } else {
            content += "<-";
        }
        content += "
";
    }
    gearlist.innerHTML = content;
}

function init() {
    'use strict';

    // visible "main" canvas
    canvas = document.getElementById('canv');
    context = canvas.getContext('2d');

    // own context for spirograph line since it doesn't need redrawing
    line_canvas = document.createElement('canvas');
    line_canvas.width = canvas.width;
    line_canvas.height = canvas.height;
    line_context = line_canvas.getContext('2d');
    line_context.clearRect(0, 0, canvas.width, canvas.height);
    line_context.strokeStyle = '#666666';

    // own context for spirograph "gears" since they are redrawn each frame
    circle_canvas = document.createElement('canvas');
    circle_canvas.width = canvas.width;
    circle_canvas.height = canvas.height;
    circle_context = circle_canvas.getContext('2d');
    circle_context.clearRect(0, 0, canvas.width, canvas.height);
    circle_context.strokeStyle = '#888888';

    center = [canvas.width / 2, canvas.height / 2];
    spiro = new Spirograph();
    update_gearlist();
    point = spiro.step();
    paused = true;
    draw_circles();
    context.clearRect(0, 0, canvas.width, canvas.height);
    context.drawImage(circle_canvas, 0, 0);
    mainloop();
}
<|endoftext|>


<commit_before>/* jshint node: true */
module.exports = function(grunt) {
  "use strict";

  var _ = require("underscore");
  var path = require("path");
  var sorter = require("./assets/sorter");

  var constVariables = {};

  grunt.registerTask("build", function() {
    constVariables = require("../../src/const");

    buildSCScript();
    buildClassLib();

    makeBrowserTest();
  });

  function q(str) {
    return "\"" + str + "\"";
  }

  function build(files) {
    return sortModules(files).map(formatter).join("").trim();
  }

  function buildSCScript() {
    var tmpl = _.template(grunt.file.read(__dirname + "/assets/scscript.tmpl"));
    grunt.file.write("build/scscript.js", tmpl({
      version: q(grunt.config.data.pkg.version),
      source: build(grunt.file._expand("src", "!classlib", "!test"))
    }));
  }

  function buildClassLib() {
    grunt.file.write("build/scscript-classlib.js", [
      build(grunt.file._expand("classlib", "!test"))
    ].join(""));
  }

  function sortModules(files) {
    var result = [];

    function walker(filepath) {
      var index, dir, src, re, m;

      index = result.indexOf(filepath);
      if (index !== -1) {
        result.splice(index, 1);
      }
      result.unshift(filepath);

      dir = path.dirname(filepath);
      src = grunt.file.read(filepath);

      re = /^\s*require\("(\..+?)(?:\.js)?"\);\s*$/gm;
      while ((m = re.exec(src)) !== null) {
        walker(path.join(dir, m[1] + ".js"));
      }
    }

    _.each(files, walker);

    return result;
  }

  function formatter(filepath) {
    var src;

    src = grunt.file.read(filepath);

    _.chain(constVariables).keys().each(function(key) {
      src = src.replace(new RegExp("sc." + key + "(?=\\b)", "g"), constVariables[key]);
    });

    src = src.replace(/\s*['"]use strict['"];\s*$/gm, "");
    src = src.replace(/^\s*require\("\.[^"]+"\);\s*$/gm, "");
    src = src.replace(/(\s*\n){2,}/g, "\n\n");
    src = src.trim();

    if (src) {
      src = "\n// " + filepath + "\n" + src + "\n";
    }

    return src;
  }

  function makeBrowserTest() {
    var tests, html;

    tests = grunt.file._expand("test").sort(sorter.byFilePath).map(function(filepath) {
      return "    <script src=\"../../../" + filepath + "\"></script>";
    });
    html = grunt.file.read("assets/index.tmpl").replace("#{TESTS}", tests.join("\n"));

    grunt.file.write("docs/report/test/index.html", html);
  }
};
<commit_msg>:sparkles: fix build task to read index.js<commit_after>/* jshint node: true */
module.exports = function(grunt) {
  "use strict";

  var _ = require("underscore");
  var path = require("path");
  var sorter = require("./assets/sorter");

  var constVariables = {};

  grunt.registerTask("build", function() {
    constVariables = require("../../src/const");

    buildSCScript();
    buildClassLib();

    makeBrowserTest();
  });

  function q(str) {
    return "\"" + str + "\"";
  }

  function build(files) {
    return sortModules(files).map(formatter).join("").trim();
  }

  function buildSCScript() {
    var tmpl = _.template(grunt.file.read(__dirname + "/assets/scscript.tmpl"));
    grunt.file.write("build/scscript.js", tmpl({
      version: q(grunt.config.data.pkg.version),
      source: build(grunt.file._expand("src", "!classlib", "!test"))
    }));
  }

  function buildClassLib() {
    grunt.file.write("build/scscript-classlib.js", [
      build(grunt.file._expand("classlib", "!test"))
    ].join(""));
  }

  function sortModules(files) {
    var result = [];

    function walker(filepath) {
      var index = result.indexOf(filepath);
      if (index !== -1) {
        result.splice(index, 1);
      }
      result.unshift(filepath);

      var dir = path.dirname(filepath);
      var src = grunt.file.read(filepath);

      var re = /^\s*require\("(\..+?)(?:\.js)?"\);\s*$/gm;
      var m;
      while ((m = re.exec(src)) !== null) {
        var filename = m[1];
        if (filename.charAt(filename.length - 1) === "/") {
          filename += "index";
        }
        walker(path.join(dir, filename + ".js"));
      }
    }

    _.each(files, walker);

    return result;
  }

  function formatter(filepath) {
    var src;

    src = grunt.file.read(filepath);

    _.chain(constVariables).keys().each(function(key) {
      src = src.replace(new RegExp("sc." + key + "(?=\\b)", "g"), constVariables[key]);
    });

    src = src.replace(/\s*['"]use strict['"];\s*$/gm, "");
    src = src.replace(/^\s*require\("\.[^"]+"\);\s*$/gm, "");
    src = src.replace(/(\s*\n){2,}/g, "\n\n");
    src = src.trim();

    if (src) {
      src = "\n// " + filepath + "\n" + src + "\n";
    }

    return src;
  }

  function makeBrowserTest() {
    var tests, html;

    tests = grunt.file._expand("test").sort(sorter.byFilePath).map(function(filepath) {
      return "    <script src=\"../../../" + filepath + "\"></script>";
    });
    html = grunt.file.read("assets/index.tmpl").replace("#{TESTS}", tests.join("\n"));

    grunt.file.write("docs/report/test/index.html", html);
  }
};
<|endoftext|>


<commit_before>var P = {

    getRegionsByColors: function (img, colors, options) { // (HTMLImageElement, Array, Object) -> Object
        var opt = options || {},
            canvas = this._wrapByCanvas(img),
            colors = this._colorsToRgb(colors),
            regionsPxs, regions;

        opt.accuracy = opt.accuracy || 3;
        opt.dist = opt.dist || 15;

        var t0 = new Date();
        regionsPxs = this._getRegionsPixels(canvas, colors, opt.accuracy);
        var t1 = new Date();
        console.log('_getRegionsPixels: ', t1 - t0);

        var t0 = new Date();
        regions = this._splitByDist(regionsPxs, opt.dist);
        var t1 = new Date();
        console.log('_splitByDist: ', t1 - t0);

        return regions;
    },

    _getRegionsPixels: function (canvas, colors, accuracy) { // (HTMLCanvasElement, Array, Number) -> Array
        var res = [],
            ctx = canvas.getContext('2d');

        for (var x = 0; x < img.clientWidth; x = x+accuracy) {
            for (var y = 0; y < img.clientHeight; y = y+accuracy) {
                var px = { x: x, y: y },
                    pxCol = this._getPixelColor(ctx, px),
                    nPxs = this._getNeighborPixels(px, {
                        w: canvas.width - accuracy,
                        h: canvas.height - accuracy
                    }, accuracy);
                    nPxCols = this._getPixelsColors(ctx, nPxs); // TODO: 1209ms should be optimized

                // skip if px is not a boundary pixel of the feature
                if (this._areColorsEqualToColor(P.Util.Color.areEqual, nPxCols, pxCol) === true) {
                    continue;
                }

                // is it pixel of the feature?
                if(this._isColorInColors(P.Util.Color.areEqual, pxCol, colors)) {
                    res.push(px);
                }
            }
        }

        return res;
    },

    // TODO: should be optimized. Think about to sorting algorithms
    _splitByDist: function (pixels, dist) { // (Array, Number) -> Array
        var disjointSet = new P.Struct.DisjointSet(),
            res;

        //var t0 = new Date();
        for (var i = 0; i < pixels.length; i++) {
            disjointSet.add(pixels[i]);
            for (var j = i + 1; j < pixels.length; j++) {
                disjointSet.add(pixels[j]);
                if (P.Util.Math.getDistance(pixels[i], pixels[j]) <= dist) {
                    if (!disjointSet.find(pixels[i], pixels[j])) {
                        disjointSet.union(pixels[i], pixels[j]);
                    }
                }
            }
        }
        // var t1 = new Date();
        // console.log('_splitByDist loop: ', t1 - t0);

        res = disjointSet.extract();
        disjointSet.destroy();
        return res;
    },

    _wrapByCanvas: function (img) { // (HTMLImageElement) -> HTMLCanvasElement
        var canv = document.createElement('canvas');
        canv.width = img.width;
        canv.height = img.height;
        canv.getContext('2d').drawImage(img, 0, 0, img.width, img.height);
        return canv;
    },

    _colorsToRgb: function (cols) { // (Array) -> Array
        for (var i = 0; i < cols.length; i++) {
            cols[i] = P.Util.Color.toRGB(cols[i]);
        };
        return cols;
    },

    _getPixelColor: function (context, px) { // (CanvasRenderingContext2D, Object) -> Array
        return context.getImageData(px.x, px.y, 1, 1).data;
    },

    _getPixelsColors: function (context, pxs) { // (CanvasRenderingContext2D, Array) -> Array
        var list = [];
        for (var i = 0; i < pxs.length; i++) {
        	list.push(context.getImageData(pxs[i].x, pxs[i].y, 1, 1).data);
        };
        return list;
    },

    _isColorInColors: function (checkingFunc, col, cols) { // (Function, Array, Array) -> Boolean
        for (var i = 0; i < cols.length; i++) {
            if (checkingFunc(col, cols[i]) === true) {
                return true;
            };
        };
        return false;
    },

    _areColorsEqualToColor: function (checkingFunc, cols, col) { // (Function, Array, Array) -> Boolean
        for (var i = 0; i < cols.length; i++) {
            if (checkingFunc(col, cols[i]) === false) {
                return false;
            };
        };
        return true;
    },

    _getNeighborPixels: function (px, imgSize, accuracy) { // (Object, Object) -> Array
        var res = [];

        if (px.x > 0 && px.y > 0) {
            res.push({ x: px.x-accuracy, y: px.y-accuracy }); // tl
        };

        if (px.y > 0) {
            res.push({ x: px.x,   y: px.y-accuracy }); // t
        };

        if (px.x < imgSize.w && px.y > 0) {
            res.push({ x: px.x+accuracy, y: px.y-accuracy }); // tr
        };

        if (px.x < imgSize.w) {
            res.push({ x: px.x+accuracy, y: px.y }); // r
        };

        if (px.x < imgSize.w && px.y < imgSize.h) {
            res.push({ x: px.x+accuracy, y: px.y+accuracy }); // br
        };

        if (px.y < imgSize.h) {
            res.push({ x: px.x, y: px.y+accuracy }); // b
        };

        if (px.x > 0 && px.y < imgSize.h) {
            res.push({ x: px.x-accuracy, y: px.y+accuracy }); // bl
        };

        if (px.x > 0) {
            res.push({ x: px.x-accuracy, y: px.y }); // l
        };

        return res;
    }
}<commit_msg>_splitByDist, optimized from 1716ms to 270ms<commit_after>var P = {

    getRegionsByColors: function (img, colors, options) { // (HTMLImageElement, Array, Object) -> Object
        var opt = options || {},
            canvas = this._wrapByCanvas(img),
            colors = this._colorsToRgb(colors),
            regionsPxs, regions;

        opt.accuracy = opt.accuracy || 3;
        opt.dist = opt.dist || 15;

        var t0 = new Date();
        regionsPxs = this._getRegionsPixels(canvas, colors, opt.accuracy);
        var t1 = new Date();
        console.log('_getRegionsPixels: ', t1 - t0);

        var t0 = new Date();
        regions = this._splitByDist(regionsPxs, opt.dist);
        var t1 = new Date();
        console.log('_splitByDist: ', t1 - t0); // 1716 -> 270

        return regions;
    },

    _getRegionsPixels: function (canvas, colors, accuracy) { // (HTMLCanvasElement, Array, Number) -> Array
        var res = [],
            ctx = canvas.getContext('2d');

        for (var x = 0; x < img.clientWidth; x = x+accuracy) {
            for (var y = 0; y < img.clientHeight; y = y+accuracy) {
                var px = { x: x, y: y },
                    pxCol = this._getPixelColor(ctx, px),
                    nPxs = this._getNeighborPixels(px, {
                        w: canvas.width - accuracy,
                        h: canvas.height - accuracy
                    }, accuracy);
                    nPxCols = this._getPixelsColors(ctx, nPxs); // TODO: 1209ms should be optimized

                // skip if px is not a boundary pixel of the feature
                if (this._areColorsEqualToColor(P.Util.Color.areEqual, nPxCols, pxCol) === true) {
                    continue;
                }

                // is it pixel of the feature?
                if(this._isColorInColors(P.Util.Color.areEqual, pxCol, colors)) {
                    res.push(px);
                }
            }
        }

        return res;
    },

    // TODO: should be optimized. Think about to sorting algorithms
    _splitByDist: function (pixels, dist) { // (Array, Number) -> Array
        var disjointSet = new P.Struct.DisjointSet(),
            res;

        //var t0 = new Date();
        for (var i = 0; i < pixels.length; i++) {
            disjointSet.add(pixels[i]);
            for (var j = i; j > 0; j--) {
                disjointSet.add(pixels[j]);
                if (P.Util.Math.getDistance(pixels[i], pixels[j]) <= dist) {
                    if (!disjointSet.find(pixels[i], pixels[j])) {
                        disjointSet.union(pixels[i], pixels[j]);
                    }
                }
            }
        }
        // var t1 = new Date();
        // console.log('_splitByDist loop: ', t1 - t0);

        res = disjointSet.extract();
        disjointSet.destroy();
        return res;
    },

    _wrapByCanvas: function (img) { // (HTMLImageElement) -> HTMLCanvasElement
        var canv = document.createElement('canvas');
        canv.width = img.width;
        canv.height = img.height;
        canv.getContext('2d').drawImage(img, 0, 0, img.width, img.height);
        return canv;
    },

    _colorsToRgb: function (cols) { // (Array) -> Array
        for (var i = 0; i < cols.length; i++) {
            cols[i] = P.Util.Color.toRGB(cols[i]);
        };
        return cols;
    },

    _getPixelColor: function (context, px) { // (CanvasRenderingContext2D, Object) -> Array
        return context.getImageData(px.x, px.y, 1, 1).data;
    },

    _getPixelsColors: function (context, pxs) { // (CanvasRenderingContext2D, Array) -> Array
        var list = [];
        for (var i = 0; i < pxs.length; i++) {
        	list.push(context.getImageData(pxs[i].x, pxs[i].y, 1, 1).data);
        };
        return list;
    },

    _isColorInColors: function (checkingFunc, col, cols) { // (Function, Array, Array) -> Boolean
        for (var i = 0; i < cols.length; i++) {
            if (checkingFunc(col, cols[i]) === true) {
                return true;
            };
        };
        return false;
    },

    _areColorsEqualToColor: function (checkingFunc, cols, col) { // (Function, Array, Array) -> Boolean
        for (var i = 0; i < cols.length; i++) {
            if (checkingFunc(col, cols[i]) === false) {
                return false;
            };
        };
        return true;
    },

    _getNeighborPixels: function (px, imgSize, accuracy) { // (Object, Object) -> Array
        var res = [];

        if (px.x > 0 && px.y > 0) {
            res.push({ x: px.x-accuracy, y: px.y-accuracy }); // tl
        };

        if (px.y > 0) {
            res.push({ x: px.x,   y: px.y-accuracy }); // t
        };

        if (px.x < imgSize.w && px.y > 0) {
            res.push({ x: px.x+accuracy, y: px.y-accuracy }); // tr
        };

        if (px.x < imgSize.w) {
            res.push({ x: px.x+accuracy, y: px.y }); // r
        };

        if (px.x < imgSize.w && px.y < imgSize.h) {
            res.push({ x: px.x+accuracy, y: px.y+accuracy }); // br
        };

        if (px.y < imgSize.h) {
            res.push({ x: px.x, y: px.y+accuracy }); // b
        };

        if (px.x > 0 && px.y < imgSize.h) {
            res.push({ x: px.x-accuracy, y: px.y+accuracy }); // bl
        };

        if (px.x > 0) {
            res.push({ x: px.x-accuracy, y: px.y }); // l
        };

        return res;
    }
}<|endoftext|>


<commit_before>/*! W 1.5.1 (https://github.com/pyrsmk/W) */

// Prepare
var listeners = [],
	trigger = false;

// Catch window resize event
if(window.addEventListener) {
	if('onorientationchange' in window) {
		window.addEventListener('orientationchange', function(){
			trigger = true;
		}, false);
	}
	else{
		window.addEventListener('resize', function(){
			trigger = true;
		}, false);
	}
}
else{
	window.attachEvent('onresize', function() {
		trigger = true;
	});
}

// Verify resizes every 10ms
setInterval(function() {
	if(trigger && document.documentElement.clientWidth) {
		trigger = false;
		for(var i=0, j=listeners.length; i<j; ++i) {
			listeners[i].func();
		}
	}
}, 10);

// Get screen orientation
function getOrientation() {
	if('orientation' in window) {
		return !window.orientation ? 'portrait' : 'landscape';
	}
	else{
		var viewport = detectViewport();
		return viewport.width > viewport.height ? 'landscape' : 'portrait';
	}
}

// Viewport resolution detection
function detectViewport(absolute) {
	// Prepare
	var screen_width,
		screen_height,
		values = [
			{width: screen.availWidth, height: screen.availHeight},
			{width: window.outerWidth, height: window.outerHeight},
			{width: window.innerWidth, height: window.innerHeight}
		],
		i, j;
	// Detect right screen resolution from orientation
	if(/(iPad|iPhone|iPod)/g.test(navigator.userAgent) && getOrientation() == 'landscape') {
		screen_width = screen.height;
		screen_height = screen.width;
		// Override window.innerWidth (generally equals to 980)
		values[2].width = screen_width;
	}
	else{
		screen_width = screen.width;
		screen_height = screen.height;
	}
	// Absolute mode
	if(absolute) {
		return {
			width: screen_width,
			height: screen_height
		};
	}
	// Relative mode
	else {
		// Note found values
		for(i=0, j=values.length; i<j; ++i) {
			if(values[i].width > screen_width || values[i].height > screen_height || !values[i].width || !values[i].height) {
				values[i].note = 0;
			}
			else {
				values[i].note = (screen_width - values[i].width) + (screen_height - values[i].height);
			}
		}
		// Sort notes
		values.sort(function(a, b) {
			return b.note - a.note;
		});
		// Return the better values
		return {
			width: values[0].width,
			height: values[0].height
		};
	}
}

// Define W object
var W = {
	getViewportWidth: function(absolute) {
		return detectViewport(absolute).width;
	},
	getViewportHeight: function(absolute) {
		return detectViewport(absolute).height;
	},
	getOrientation: function() {
		return getOrientation();
	},
	addListener: function(func, key) {
		listeners.push({
			func: func,
			key: key
		});
		return func;
	},
	removeListener: function(key) {
		for(var i=0, j=listeners.length; i<j; ++i) {
			if(listeners[i].key == key) {
				listeners.splice(i, 1);
				break;
			}
		}
	},
	clearListeners: function() {
		listeners = [];
	},
	trigger: function(key) {
		for(var i=0, j=listeners.length; i<j; ++i) {
			if(typeof key == 'undefined' || listeners[i].key == key) {
				listeners[i].func();
			}
		}
	}
};
<commit_msg>Update orientation detection<commit_after>/*! W 1.5.2 (https://github.com/pyrsmk/W) */

// Prepare
var listeners = [],
	trigger = false,
	ua = navigator.userAgent.toLowerCase();

// Catch window resize event
if(window.addEventListener) {
	if('onorientationchange' in window) {
		window.addEventListener('orientationchange', function(){
			trigger = true;
		}, false);
	}
	else{
		window.addEventListener('resize', function(){
			trigger = true;
		}, false);
	}
}
else{
	window.attachEvent('onresize', function() {
		trigger = true;
	});
}

// Verify resizes every 10ms
setInterval(function() {
	if(trigger && document.documentElement.clientWidth) {
		trigger = false;
		for(var i=0, j=listeners.length; i<j; ++i) {
			listeners[i].func();
		}
	}
}, 10);

// Get screen orientation
function getOrientation() {
	var landscape;
	if('orientation' in window) {
		var orientation = window.orientation;
		if(/android/g.test(ua)) {
			landscape = (orientation == 0 || orientation == 180);
		}
		else {
			landscape = (orientation == 90 || orientation == -90);
		}
	}
	else {
		// Probably only used by desktop browsers
		var viewport = detectViewport();
		landscape = viewport.width > viewport.height;
	}
	return landscape ? 'landscape' : 'portrait';
}

// Viewport resolution detection
function detectViewport(absolute) {
	// Prepare
	var screen_width,
		screen_height,
		values = [
			{width: screen.availWidth, height: screen.availHeight},
			{width: window.outerWidth, height: window.outerHeight},
			{width: window.innerWidth, height: window.innerHeight}
		],
		i, j;
	// Detect right screen resolution from orientation
	// (calling getOrientation() here can make an infinite loop, but iOS supports window.orientation so it's fine)
	if(/(ipad|iphone|ipod)/g.test(ua) && getOrientation() == 'landscape') {
		screen_width = screen.height;
		screen_height = screen.width;
		// Override window.innerWidth (generally equals to 980)
		values[2].width = screen_width;
	}
	else{
		screen_width = screen.width;
		screen_height = screen.height;
	}
	// Absolute mode
	if(absolute) {
		return {
			width: screen_width,
			height: screen_height
		};
	}
	// Relative mode
	else {
		// Note found values
		for(i=0, j=values.length; i<j; ++i) {
			if(values[i].width > screen_width || values[i].height > screen_height || !values[i].width || !values[i].height) {
				values[i].note = 0;
			}
			else {
				values[i].note = (screen_width - values[i].width) + (screen_height - values[i].height);
			}
		}
		// Sort notes
		values.sort(function(a, b) {
			return b.note - a.note;
		});
		// Return the better values
		return {
			width: values[0].width,
			height: values[0].height
		};
	}
}

// Define W object
var W = {
	getViewportWidth: function(absolute) {
		return detectViewport(absolute).width;
	},
	getViewportHeight: function(absolute) {
		return detectViewport(absolute).height;
	},
	getOrientation: function() {
		return getOrientation();
	},
	addListener: function(func, key) {
		listeners.push({
			func: func,
			key: key
		});
		return func;
	},
	removeListener: function(key) {
		for(var i=0, j=listeners.length; i<j; ++i) {
			if(listeners[i].key == key) {
				listeners.splice(i, 1);
				break;
			}
		}
	},
	clearListeners: function() {
		listeners = [];
	},
	trigger: function(key) {
		for(var i=0, j=listeners.length; i<j; ++i) {
			if(typeof key == 'undefined' || listeners[i].key == key) {
				listeners[i].func();
			}
		}
	}
};
<|endoftext|>


<commit_before>"use strict";

function bindFileUpload(target,
                        request_id,
                        for_update,
                        uploadTemplateId,
                        downloadTemplateId,
                        nextButton) {
    /*
    Binds jquery file upload to the element identified by 'target'

    @param {string} target - jquery selector string (ex. "#fileupload")
    @param {string} request_id - FOIL request id
    @param {bool} for_update - editing a file?
    @param {string} uploadTemplateId - jquery file upload uploadTemplateId
    @param {string} downloadTemplateId - jquery file upload downloadTemplateId
    @param {selector} nextButton - jquery selector for next button of file response workflow
    */

    uploadTemplateId = uploadTemplateId || "template-upload";
    downloadTemplateId = downloadTemplateId || "template-download";

    $(target).fileupload({
        //xhrFields: {withCredentials: true},  // send cross-domain cookies
        url: "/upload/" + request_id,
        formData: for_update ? {update: true} : {},
        uploadTemplateId: uploadTemplateId,
        downloadTemplateId: downloadTemplateId,
        maxChunkSize: 512000,  // 512 kb
        maxFileSize: 500000000, // 500 mb
        chunksend: function (e, data) {
            // stop sending chunks if abort signaled
            if (data.context[0].abortChunkSend) {
                return false;
            }
        },
        chunkdone: function (e, data) {
            // on error, signal to stop sending chunks
            if (data.result) {
                if (data.result.files[0].error) {
                    data.context[0].abortChunkSend = true;
                    data.files[0].error = data.result.files[0].error
                }
            }
        },
        chunkfail: function (e, data) {
            // remove existing partial upload
            deleteUpload(request_id, encodeName(data.files[0].name), false, true);
        }
    }).bind("fileuploaddone", function (e, data) {
        // blueimp says that this will only be called on a successful upload
        // so I'm not sure why I have to check for errors here!
        var file = data.result.files[0];
        if (file.errors === undefined) {
            // start polling status endpoint after scanner startup
            var idVal = encodeName(file.name);
            data.result.files[0].identifier = idVal;
            setTimeout(
                pollUploadStatus.bind(null, file.name, idVal, request_id, for_update, nextButton),
                4000);  // McAfee Scanner minimum 3+ second startup
        }
        else {
            // Re-enable 'next' button
            if (for_update) {
                $(nextButton).attr('enabled', true);
            }
        }
    }).bind("fileuploadadd", function (e, data) {
        if (for_update) {
            var elem_files = $(target).find(".files");
            var templates_upload = elem_files.children(".template-upload");
            var templates_download = elem_files.children(".template-download");
            // Remove template for added file (pre-upload)
            if (templates_upload.length > 0) {
                templates_upload.remove();
            }
            // Remove template for uploaded file and delete corresponding file
            if (templates_download.length > 0) {
                for (var i = 0; i < templates_download.length; i++) {
                    var file_identifier = $(templates_download[i]).attr("id");
                    if (typeof file_identifier != "undefined") {
                        // if this template is for a successful upload
                        deleteUpload(request_id, file_identifier, true);
                    }
                    $(templates_download[i]).remove();
                }
            }
        }
        else {
            // Prevent duplicate files from being added
            var currentFiles = [];
            $(this).fileupload("option").filesContainer.children().each(function () {
                currentFiles.push($.trim($(".original-name", this).text()));
            });
            data.files = $.map(data.files, function (file, i) {
                if ($.inArray(file.name, currentFiles) >= 0) {
                    alert("The file '" + file.name + "' has already been added.");
                    return null;
                }
                return file;
            });
        }
        $(".fileupload-loading").hide();
        $(".fileupload-process").hide();
    }).bind("fileuploadstarted", function (e, data) {
        // Disable 'next' button
        if (for_update) {
            $(nextButton).attr('disabled', true);
        }
    });
}

function encodeName(name) {
    /*
    Returns an encoded (base64 without padding) version of 'name' intended
    for use as/in an html id attribute or for use in a url.
    Padding is removed because '=' is an invalid character for an html id
    and it is reserved character for urls.
     */
    return window.btoa(name).replace(/=/g, "");
}

function pollUploadStatus(upload_filename, htmlId, request_id, for_update, nextButton) {
    /*
    Sends a request to the upload status endpoint
    every 2 seconds until it receives a message indicating
    the upload has completed or until it receives an error
    message, then updates the download template.
     */
    $.ajax({
        type: "GET",
        url: "/upload/status",
        data: {
            request_id: request_id,
            filename: upload_filename,
            for_update: for_update
        },
        dataType: "json",
        success: function(response) {
            var tr = $("#".concat(htmlId));
            if (response.error) {
                // Reveal error message
                tr.find(".error-post-fileupload").removeClass("hidden");
                tr.find(".error-post-fileupload-msg").text("Error processing file.");  // scanning, really
                tr.find(".processing-upload").remove();
                setRemoveBtn(request_id, tr.find(".remove-post-fileupload"),
                    false);  // file already deleted
            }
            else if (response.status != "ready") {
                setTimeout(pollUploadStatus.bind(
                    null, upload_filename, htmlId, request_id, for_update, nextButton
                ), 2000);
            }
            else {
                // Reveal full template
                tr.find(".fileupload-input-fields").removeClass("hidden");
                tr.find(".processing-upload").remove();
                setRemoveBtn(request_id, tr.find(".remove-post-fileupload"), true, for_update);
                if (for_update) {
                    // Enable 'next' button
                    $(nextButton).attr('disabled', false)
                }
            }
        }
    });
}

function deleteUpload(request_id,
                      filecode,
                      updated_only,
                      quarantined_only) {
    /*
    Send a DELETE request to the upload endpoint.
     */
    var data = {};
    if (updated_only) {
        data = {updated_only: true}
    }
    else if (quarantined_only) {
        data = {quarantined_only: true}
    }

    $.ajax({
        type: "DELETE",
        url: sprintf("/upload/request/%s/%s",
            request_id, filecode),
        data: data
    });
}

function setRemoveBtn(request_id, button, sendDelete, for_update) {
    /*
    Reveal remove button and set its click event handler.
     */
    sendDelete = sendDelete || true;
    button.removeClass("hidden");
    button.click(function(e) {
        e.preventDefault();
        var template = $(this).closest(".template-download");
        if (sendDelete) {
            deleteUpload(request_id, template.attr("id"), for_update);
        }
        template.remove();
    });
}
<commit_msg>fix fileupload for_update next button disabled<commit_after>"use strict";

function bindFileUpload(target,
                        request_id,
                        for_update,
                        uploadTemplateId,
                        downloadTemplateId,
                        nextButton) {
    /*
    Binds jquery file upload to the element identified by 'target'

    @param {string} target - jquery selector string (ex. "#fileupload")
    @param {string} request_id - FOIL request id
    @param {bool} for_update - editing a file?
    @param {string} uploadTemplateId - jquery file upload uploadTemplateId
    @param {string} downloadTemplateId - jquery file upload downloadTemplateId
    @param {selector} nextButton - jquery selector for next button of file response workflow
    */

    uploadTemplateId = uploadTemplateId || "template-upload";
    downloadTemplateId = downloadTemplateId || "template-download";

    $(target).fileupload({
        //xhrFields: {withCredentials: true},  // send cross-domain cookies
        url: "/upload/" + request_id,
        formData: for_update ? {update: true} : {},
        uploadTemplateId: uploadTemplateId,
        downloadTemplateId: downloadTemplateId,
        maxChunkSize: 512000,  // 512 kb
        maxFileSize: 500000000, // 500 mb
        chunksend: function (e, data) {
            // stop sending chunks if abort signaled
            if (data.context[0].abortChunkSend) {
                return false;
            }
        },
        chunkdone: function (e, data) {
            // on error, signal to stop sending chunks
            if (data.result) {
                if (data.result.files[0].error) {
                    data.context[0].abortChunkSend = true;
                    data.files[0].error = data.result.files[0].error
                }
            }
        },
        chunkfail: function (e, data) {
            // remove existing partial upload
            deleteUpload(request_id, encodeName(data.files[0].name), false, true);
            // Re-enable 'next' button
            if (for_update) {
                $(nextButton).attr('disabled', false);
            }
        }
    }).bind("fileuploaddone", function (e, data) {
        // blueimp says that this will only be called on a successful upload
        // so I'm not sure why I have to check for errors here!
        var file = data.result.files[0];
        if (file.errors === undefined) {
            // start polling status endpoint after scanner startup
            var idVal = encodeName(file.name);
            data.result.files[0].identifier = idVal;
            setTimeout(
                pollUploadStatus.bind(null, file.name, idVal, request_id, for_update, nextButton),
                4000);  // McAfee Scanner minimum 3+ second startup
        }
        else {
            // Re-enable 'next' button
            if (for_update) {
                $(nextButton).attr('disabled', false);
            }
        }
    }).bind("fileuploadadd", function (e, data) {
        if (for_update) {
            var elem_files = $(target).find(".files");
            var templates_upload = elem_files.children(".template-upload");
            var templates_download = elem_files.children(".template-download");
            // Remove template for added file (pre-upload)
            if (templates_upload.length > 0) {
                templates_upload.remove();
            }
            // Remove template for uploaded file and delete corresponding file
            if (templates_download.length > 0) {
                for (var i = 0; i < templates_download.length; i++) {
                    var file_identifier = $(templates_download[i]).attr("id");
                    if (typeof file_identifier != "undefined") {
                        // if this template is for a successful upload
                        deleteUpload(request_id, file_identifier, true);
                    }
                    $(templates_download[i]).remove();
                }
            }
        }
        else {
            // Prevent duplicate files from being added
            var currentFiles = [];
            $(this).fileupload("option").filesContainer.children().each(function () {
                currentFiles.push($.trim($(".original-name", this).text()));
            });
            data.files = $.map(data.files, function (file, i) {
                if ($.inArray(file.name, currentFiles) >= 0) {
                    alert("The file '" + file.name + "' has already been added.");
                    return null;
                }
                return file;
            });
        }
        $(".fileupload-loading").hide();
        $(".fileupload-process").hide();
    }).bind("fileuploadstarted", function (e, data) {
        // Disable 'next' button
        if (for_update) {
            $(nextButton).attr('disabled', true);
        }
    });
}

function encodeName(name) {
    /*
    Returns an encoded (base64 without padding) version of 'name' intended
    for use as/in an html id attribute or for use in a url.
    Padding is removed because '=' is an invalid character for an html id
    and it is reserved character for urls.
     */
    return window.btoa(name).replace(/=/g, "");
}

function pollUploadStatus(upload_filename, htmlId, request_id, for_update, nextButton) {
    /*
    Sends a request to the upload status endpoint
    every 2 seconds until it receives a message indicating
    the upload has completed or until it receives an error
    message, then updates the download template.
     */
    $.ajax({
        type: "GET",
        url: "/upload/status",
        data: {
            request_id: request_id,
            filename: upload_filename,
            for_update: for_update
        },
        dataType: "json",
        success: function(response) {
            var tr = $("#".concat(htmlId));
            if (response.error) {
                // Reveal error message
                tr.find(".error-post-fileupload").removeClass("hidden");
                tr.find(".error-post-fileupload-msg").text("Error processing file.");  // scanning, really
                tr.find(".processing-upload").remove();
                setRemoveBtn(request_id, tr.find(".remove-post-fileupload"),
                    false);  // file already deleted
            }
            else if (response.status != "ready") {
                setTimeout(pollUploadStatus.bind(
                    null, upload_filename, htmlId, request_id, for_update, nextButton
                ), 2000);
            }
            else {
                // Reveal full template
                tr.find(".fileupload-input-fields").removeClass("hidden");
                tr.find(".processing-upload").remove();
                setRemoveBtn(request_id, tr.find(".remove-post-fileupload"), true, for_update);
                if (for_update) {
                    // Enable 'next' button
                    $(nextButton).attr('disabled', false)
                }
            }
        }
    });
}

function deleteUpload(request_id,
                      filecode,
                      updated_only,
                      quarantined_only) {
    /*
    Send a DELETE request to the upload endpoint.
     */
    var data = {};
    if (updated_only) {
        data = {updated_only: true}
    }
    else if (quarantined_only) {
        data = {quarantined_only: true}
    }

    $.ajax({
        type: "DELETE",
        url: sprintf("/upload/request/%s/%s",
            request_id, filecode),
        data: data
    });
}

function setRemoveBtn(request_id, button, sendDelete, for_update) {
    /*
    Reveal remove button and set its click event handler.
     */
    sendDelete = sendDelete || true;
    button.removeClass("hidden");
    button.click(function(e) {
        e.preventDefault();
        var template = $(this).closest(".template-download");
        if (sendDelete) {
            deleteUpload(request_id, template.attr("id"), for_update);
        }
        template.remove();
    });
}
<|endoftext|>


<commit_before>/* eslint-disable no-useless-escape */
import BaseValidator from 'ember-cp-validations/validators/base';

const ContributorType = BaseValidator.extend({

  validate(value, options, model) {
    const organizationalContributorTypes = [
      'HostingInstitution',
      'RegistrationAgency',
      'RegistrationAuthority',
      'ResearchGroup',
      'Distributor',
    ];

    const contributorTypes = [
      'ContactPerson',
      'DataCollector',
      'DataCurator',
      'DataManager',
      'Distributor',
      'Editor',
      'HostingInstitution',
      'Producer',
      'ProjectLeader',
      'ProjectManager',
      'ProjectMember',
      'RegistrationAgency',
      'RegistrationAuthority',
      'RelatedPerson',
      'Researcher',
      'ResearchGroup',
      'RightsHolder',
      'Sponsor',
      'Supervisor',
      'WorkPackageLeader',
      'Other',
    ];

    const personalContributorTypes = [
      'ContactPerson',
      'DataCurator',
      'Editor',
      'ProjectLeader',
      'ProjectManager',
      'ProjectMember',
      'RelatedPerson',
      'Researcher',
      'Supervisor',
      'WorkPackageLeader',
    ];

    const message = 'Contributor of the Type cannot be of that Name Type.';

    switch (true) {
      case (!value && options.allowBlank):
        return true;
      case organizationalContributorTypes.includes(String(value)) && model.nameType == 'Personal':
        return message;
      case personalContributorTypes.includes(String(value)) && model.nameType == 'Organizational':
        return message;
      case contributorTypes.includes(String(value)):
        return true;
      default:
        return 'The value ' + value + ' is not a valid type';
    }
  },
});

export default ContributorType;
<commit_msg>Update DataCurator contributor type<commit_after>/* eslint-disable no-useless-escape */
import BaseValidator from 'ember-cp-validations/validators/base';

const ContributorType = BaseValidator.extend({

  validate(value, options, model) {
    const organizationalContributorTypes = [
      'HostingInstitution',
      'RegistrationAgency',
      'RegistrationAuthority',
      'ResearchGroup',
      'Distributor',
    ];

    const contributorTypes = [
      'ContactPerson',
      'DataCollector',
      'DataCurator',
      'DataManager',
      'Distributor',
      'Editor',
      'HostingInstitution',
      'Producer',
      'ProjectLeader',
      'ProjectManager',
      'ProjectMember',
      'RegistrationAgency',
      'RegistrationAuthority',
      'RelatedPerson',
      'Researcher',
      'ResearchGroup',
      'RightsHolder',
      'Sponsor',
      'Supervisor',
      'WorkPackageLeader',
      'Other',
    ];

    const personalContributorTypes = [
      'ContactPerson',
      'Editor',
      'ProjectLeader',
      'ProjectManager',
      'ProjectMember',
      'RelatedPerson',
      'Researcher',
      'Supervisor',
      'WorkPackageLeader',
    ];

    const message = 'Contributor of the Type cannot be of that Name Type.';

    switch (true) {
      case (!value && options.allowBlank):
        return true;
      case organizationalContributorTypes.includes(String(value)) && model.nameType == 'Personal':
        return message;
      case personalContributorTypes.includes(String(value)) && model.nameType == 'Organizational':
        return message;
      case contributorTypes.includes(String(value)):
        return true;
      default:
        return 'The value ' + value + ' is not a valid type';
    }
  },
});

export default ContributorType;
<|endoftext|>