<commit_before>'use strict';

/**
 * Convert HTML in even better HTML.
 * @param {String} string
 * @return {String}
 * @constructor
 */
var markyMark = function markyMark (string) {
  var internal = {};
  var external = {};

  external.chunks = [];
  internal.mode   = '';

  /**
   * Do actual conversion
   * @param {String} string
   * @return {String}
   */
  external.convert = function convert (string) {
    external.chunks = [];
    internal.mode   = '';
    var currentChunk = '';
    for (var i = 0, len = string.length; i < len; i++) {
      var c = string[i];

      if (internal.mode === '<>' || internal.mode === '</>') {
        internal.pushChunk(currentChunk, '');
        currentChunk = '';
      }
      if (c === '<') {
        internal.pushChunk(currentChunk, c);
        currentChunk = '';
      }
      else if (internal.mode === '<' && c === '/') {
        internal.mode += c;
      }
      else if (c === '>') {
        internal.mode += c;
      }
      currentChunk += c;
    }
    internal.pushChunk(currentChunk);
    return external.chunks.join('');
  };

  /**
   * Push a single chunk to the chunk array, but convert chunks by looking at the current mode
   * @param {String} chunk
   * @param {String} mode
   * @return {Boolean}
   */
  internal.pushChunk = function pushChunk (chunk, newMode) {
    newMode = newMode || '';
    if (chunk) {
      switch (internal.mode) {
        case '':
          // Text node
          chunk = internal.convertText(chunk);
          break;
        case '':
          chunk = internal.convertCode(chunk);
          break;
        case '<css>':
          chunk = internal.convertCss(chunk);
          break;
        case '':
          chunk = internal.convertHtml(chunk);
          break;
        case '<markdown>':
          chunk = internal.convertMarkdown(chunk);
          break;
        case '<>':
          if (chunk.match(/<code class/)) {
            var lang = chunk.match(/(css|html|markdown)/);
            if (lang && lang[1]) {
              newMode = '<'+lang[1]+'>';
            }
            else {
              newMode = '';
            }
          }
          else if (chunk === '') {
              newMode = '<no>';
          }
          break;
      }
      external.chunks.push(chunk);
    }
    internal.mode = newMode;
    return newMode;
  };

  /**
   * Convert text node. Will do some pretty clever UTF-8 emoji stunts as well.
   * @see    http://apps.timwhitlock.info/emoji/tables/unicode
   * @param  {String} string
   * @return {String}
   */
  internal.convertText = function convertText(string) {
    var entityMap = {
      '...': '…',
      '… …': '…',
      '(C)': '©',
      '(R)': '®',
      '(TM)': '™',
      '(+-)': '±',
      '(1/4)': '¼',
      '(1/2)': '½',
      '(3/4)': '¾',
      '->': '→',
      '=>': '⇒',
      '<-': '←',
      '<=': '⇐',
    };
    string = string.replace(/(\.\.\.|… …|\(C\)|\(R\)|\(TM\)|\(+-\)|\(1\/4\)|\(1\/2\)|\(3\/4\)|->|=>|<-|<=)/g, function(s) {
      return entityMap[s];
    });

    entityMap = {
      ':)': '😊',
      ':(': '😕',
      ':|': '😐',
      ':D': '😄',
      ':P': '😋',
      ':O': '😯',
      ';)': '😉',
      '8)': '😎',
    };
    string = string.replace(/(\W|^)(:(?:\(|\)|\||D|P|O)|(?:;|8)\))(\W|$)/g, function(all, before, s, after) {
      return before + entityMap[s] + after;
    });

    return string
      .replace(/\s--\s/g, ' — ')
      .replace(/(\d)\s*-\s*(\d)/g,'$1–$2')
      .replace(/(\s)-(\s)/g,'$1–$2')
      .replace(/(\d\s*)(x|\*)(\s*\d)/g,'$1×$3')
      .replace(/(^|[^\S])"(\S.*?\S)"([^\S]|$)/g,'$1„$2“$3') // TODO: Fix quotation with inline tags
      .replace(/(^|[^\S])(?:'|')(\S.*?\S)(?:'|')([^\S]|$)/g,'$1‚$2‘$3')
    ;
  };

  /**
   * Convert code text node
   * @param {String} string
   * @return {String}
   */
  internal.convertCode = function convertCode(string) {
    return string
      .replace(/(\b)(var|function|method|class|const|external|internal|protected|use|public|private)(\b)/g, '$1$2$3')
      .replace(/(\b)(and|array|break|case|die|do|echo|s?printf?|else(if)?|elsif|final|for(each|Each)?|map|try|catch|then|global|if|include(_once)?|length|list|map|new|or|require(_once)?|return|self|switch|this|throw|while)(\b)/g, '$1$2$3')
      .replace(/([\s|=|;])([\d\.]+)([\s|=|;])/g, '$1$2$3')
      .replace(/([^\\])("|'|')(.*?)("|'|')/g,'$1$2$3$4')
      .replace(/(\b)(null|undefined|true|false)(\b)/gi, '$1$2$3')
      .replace(/((?:\/\/|\s#).+?(?:\n|$))/g, '$1')
      .replace(/(\/\*[\s\S]+?\*\/)/g, '$1')
    ;
  };

  /**
   * Convert code text node
   * @param {String} string
   * @return {String}
   */
  internal.convertCss = function convertCss(string) {
    return string
      .replace(/(\b)(color|background-color|float|text-align|position|display)(\b)/g, '$1$2$3')
      .replace(/(\b)(inherit|top|bottom|left|right|auto|center|middle|block|inline|inline-block|none)(\b)/g, '$1$2$3')
      .replace(/(\b)((?:\.|#)[a-zA-Z0-9_\-]+)(\b)/g, '$1$2$3')
      .replace(/(\b)((?:$)[a-zA-Z0-9_\-]+)(\b)/g, '$1$2$3')
      .replace(/(\b)(@(?:include|if|extend|mixin|function|else|elseif))(\b)/g, '$1$2$3')
      .replace(/([^\\])("|'|')(.*?)("|'|')/g,'$1$2$3$4')
      .replace(/([\d\.]+[a-z]+)/g, '$1$2$3')
      .replace(/(\/\/.+?(?:\n|$))/g, '$1')
      .replace(/(\/\*[\s\S]+?\*\/)/g, '$1')
      ;
  };

  /**
   * Convert code text node
   * @param {String} string
   * @return {String}
   */
  internal.convertHtml = function convertHtml(string) {
    return string
      .replace(/(<\/?)([a-zA-Z0-9]+)/g, '$1$2')
      .replace(/(&(?:#x)?[a-zA-F0-9]+?;)/g, '$1')
      .replace(/(\s)([a-zA-Z0-9_\-]+?)(=")(.+?)(")/g, '$1$2$3$4$5')
      .replace(/(<--.+?-->)/g, '$1')
    ;
  };

  /**
   * Convert Markdown code text node
   * @param {String}
   * @return {String}
   */
  internal.convertMarkdown = function convertMarkdown(string) {
    return string
      .replace(/(^|\n|\r)([=\-]{3,})(\n|\r|$)/g, '$1$2')
      .replace(/(#+.+?(?:\n|$))/g, '$1')
    ;
  };

  return external.convert(string);
};

module.exports = markyMark;
<commit_msg>Some more smileys<commit_after>'use strict';

/**
 * Convert HTML in even better HTML.
 * @param {String} string
 * @return {String}
 * @constructor
 */
var markyMark = function markyMark (string) {
  var internal = {};
  var external = {};

  external.chunks = [];
  internal.mode   = '';

  /**
   * Do actual conversion
   * @param {String} string
   * @return {String}
   */
  external.convert = function convert (string) {
    external.chunks = [];
    internal.mode   = '';
    var currentChunk = '';
    for (var i = 0, len = string.length; i < len; i++) {
      var c = string[i];

      if (internal.mode === '<>' || internal.mode === '</>') {
        internal.pushChunk(currentChunk, '');
        currentChunk = '';
      }
      if (c === '<') {
        internal.pushChunk(currentChunk, c);
        currentChunk = '';
      }
      else if (internal.mode === '<' && c === '/') {
        internal.mode += c;
      }
      else if (c === '>') {
        internal.mode += c;
      }
      currentChunk += c;
    }
    internal.pushChunk(currentChunk);
    return external.chunks.join('');
  };

  /**
   * Push a single chunk to the chunk array, but convert chunks by looking at the current mode
   * @param {String} chunk
   * @param {String} mode
   * @return {Boolean}
   */
  internal.pushChunk = function pushChunk (chunk, newMode) {
    newMode = newMode || '';
    if (chunk) {
      switch (internal.mode) {
        case '':
          // Text node
          chunk = internal.convertText(chunk);
          break;
        case '':
          chunk = internal.convertCode(chunk);
          break;
        case '<css>':
          chunk = internal.convertCss(chunk);
          break;
        case '':
          chunk = internal.convertHtml(chunk);
          break;
        case '<markdown>':
          chunk = internal.convertMarkdown(chunk);
          break;
        case '<>':
          if (chunk.match(/<code class/)) {
            var lang = chunk.match(/(css|html|markdown)/);
            if (lang && lang[1]) {
              newMode = '<'+lang[1]+'>';
            }
            else {
              newMode = '';
            }
          }
          else if (chunk === '') {
              newMode = '<no>';
          }
          break;
      }
      external.chunks.push(chunk);
    }
    internal.mode = newMode;
    return newMode;
  };

  /**
   * Convert text node. Will do some pretty clever UTF-8 emoji stunts as well.
   * @see    http://apps.timwhitlock.info/emoji/tables/unicode
   * @param  {String} string
   * @return {String}
   */
  internal.convertText = function convertText(string) {
    var entityMap = {
      '...': '…',
      '… …': '…',
      '(C)': '©',
      '(R)': '®',
      '(TM)': '™',
      '(+-)': '±',
      '(1/4)': '¼',
      '(1/2)': '½',
      '(3/4)': '¾',
      '->': '→',
      '=>': '⇒',
      '<-': '←',
      '<=': '⇐',
    };
    string = string.replace(/(\.\.\.|… …|\(C\)|\(R\)|\(TM\)|\(+-\)|\(1\/4\)|\(1\/2\)|\(3\/4\)|->|=>|<-|<=)/g, function(s) {
      return entityMap[s];
    });

    entityMap = {
      ':)': '😊',
      ':(': '😕',
      ':|': '😐',
      ':D': '😄',
      ':P': '😋',
      ':O': '😯',
      ':*': '😘',
      ';)': '😉',
      '8)': '😎',
      'XP': '😝'
    };
    string = string.replace(/(\W|^)(:(?:\(|\)|\||D|P|O|\*)|(?:;|8)\)|XP)(\W|$)/g, function(all, before, s, after) {
      return before + entityMap[s] + after;
    });

    return string
      .replace(/\s--\s/g, ' — ')
      .replace(/(\d)\s*-\s*(\d)/g,'$1–$2')
      .replace(/(\s)-(\s)/g,'$1–$2')
      .replace(/(\d\s*)(x|\*)(\s*\d)/g,'$1×$3')
      .replace(/(^|[^\S])"(\S.*?\S)"([^\S]|$)/g,'$1„$2“$3') // TODO: Fix quotation with inline tags
      .replace(/(^|[^\S])(?:'|')(\S.*?\S)(?:'|')([^\S]|$)/g,'$1‚$2‘$3')
    ;
  };

  /**
   * Convert code text node
   * @param {String} string
   * @return {String}
   */
  internal.convertCode = function convertCode(string) {
    return string
      .replace(/(\b)(var|function|method|class|const|external|internal|protected|use|public|private)(\b)/g, '$1$2$3')
      .replace(/(\b)(and|array|break|case|die|do|echo|s?printf?|else(if)?|elsif|final|for(each|Each)?|map|try|catch|then|global|if|include(_once)?|length|list|map|new|or|require(_once)?|return|self|switch|this|throw|while)(\b)/g, '$1$2$3')
      .replace(/([\s|=|;])([\d\.]+)([\s|=|;])/g, '$1$2$3')
      .replace(/([^\\])("|'|')(.*?)("|'|')/g,'$1$2$3$4')
      .replace(/(\b)(null|undefined|true|false)(\b)/gi, '$1$2$3')
      .replace(/((?:\/\/|\s#).+?(?:\n|$))/g, '$1')
      .replace(/(\/\*[\s\S]+?\*\/)/g, '$1')
    ;
  };

  /**
   * Convert code text node
   * @param {String} string
   * @return {String}
   */
  internal.convertCss = function convertCss(string) {
    return string
      .replace(/(\b)(color|background-color|float|text-align|position|display)(\b)/g, '$1$2$3')
      .replace(/(\b)(inherit|top|bottom|left|right|auto|center|middle|block|inline|inline-block|none)(\b)/g, '$1$2$3')
      .replace(/(\b)((?:\.|#)[a-zA-Z0-9_\-]+)(\b)/g, '$1$2$3')
      .replace(/(\b)((?:$)[a-zA-Z0-9_\-]+)(\b)/g, '$1$2$3')
      .replace(/(\b)(@(?:include|if|extend|mixin|function|else|elseif))(\b)/g, '$1$2$3')
      .replace(/([^\\])("|'|')(.*?)("|'|')/g,'$1$2$3$4')
      .replace(/([\d\.]+[a-z]+)/g, '$1$2$3')
      .replace(/(\/\/.+?(?:\n|$))/g, '$1')
      .replace(/(\/\*[\s\S]+?\*\/)/g, '$1')
      ;
  };

  /**
   * Convert code text node
   * @param {String} string
   * @return {String}
   */
  internal.convertHtml = function convertHtml(string) {
    return string
      .replace(/(<\/?)([a-zA-Z0-9]+)/g, '$1$2')
      .replace(/(&(?:#x)?[a-zA-F0-9]+?;)/g, '$1')
      .replace(/(\s)([a-zA-Z0-9_\-]+?)(=")(.+?)(")/g, '$1$2$3$4$5')
      .replace(/(<--.+?-->)/g, '$1')
    ;
  };

  /**
   * Convert Markdown code text node
   * @param {String}
   * @return {String}
   */
  internal.convertMarkdown = function convertMarkdown(string) {
    return string
      .replace(/(^|\n|\r)([=\-]{3,})(\n|\r|$)/g, '$1$2')
      .replace(/(#+.+?(?:\n|$))/g, '$1')
    ;
  };

  return external.convert(string);
};

module.exports = markyMark;
<|endoftext|>


<commit_before>// Converts a video stream into a stream of png buffers. Each 'data' event
// is guaranteed to contain exactly 1 png image.

// @TODO Figure out why ffmpeg.stdin.write seems to always return false and
// never emits 'drain' event (so we can get backpressure working)
// @TODO handle ffmpeg exit (and trigger "error" if unexpected)

var Stream      = require('stream').Stream;
var util        = require('util');
var spawn       = require('child_process').spawn;
var PngSplitter = require('../PngSplitter');

module.exports = PngEncoder;
util.inherits(PngEncoder, Stream);
function PngEncoder(options) {
  Stream.call(this);

  options = options || {};

  this.writable = true;
  this.readable = true;

  this._spawn       = options.spawn || spawn;
  this._frameRate   = options.frameRate || 5;
  this._pngSplitter = options.pngSplitter || new PngSplitter();
  this._log         = options.log;
  this._ffmpeg      = undefined;
  this._ending      = false;
}

PngEncoder.prototype.write = function(buffer) {
  if (!this._ffmpeg) {
    this._initFfmpegAndPipes();
  }

  this._ffmpeg.stdin.write(buffer);
};

PngEncoder.prototype._initFfmpegAndPipes = function() {
  this._ffmpeg = this._spawnFfmpeg();

  // @TODO: Make this more sophisticated for somehow and figure out how it
  // will work with the planned new data recording system.
  if (this._log) {
    this._ffmpeg.stderr.pipe(this._log);
  }

  this._ffmpeg.stdout.pipe(this._pngSplitter);
  this._pngSplitter.on('data', this.emit.bind(this, 'data'));

  // 'error' can be EPIPE if ffmpeg does not exist. We handle this with the
  // 'exit' event below.
  this._ffmpeg.stdin.on('error', function() {});

  var self = this;
  this._ffmpeg.on('exit', function(code) {
    if (code === 0) {
      // we expected ffmpeg to exit
      if (self._ending) {
        self.emit('end');
        return;
      }

      self.emit('error', new Error('Unexpected ffmpeg exit with code 0.'));
      return;
    }

    // 127 is used by the OS to indicate that ffmpeg was not found
    if (code === 127) {
      self.emit('error', new Error('Ffmpeg was not found / exit code 127.'));
      return;
    }

    self.emit('error', new Error('Ffmpeg exited with error code: ' + code));
  });
};

PngEncoder.prototype._spawnFfmpeg = function() {
  return this._spawn('ffmpeg', [
    '-i' ,'-',
    '-f', 'image2pipe',
    '-vcodec', 'png',
    '-r', this._frameRate,
    '-',
  ]);
};

PngEncoder.prototype.end = function() {
  this._ending = true;
  this._ffmpeg.stdin.end();
};
<commit_msg>Comment<commit_after>// Converts a video stream into a stream of png buffers. Each 'data' event
// is guaranteed to contain exactly 1 png image.

// @TODO Figure out why ffmpeg.stdin.write seems to always return false and
// never emits 'drain' event (so we can get backpressure working)
// @TODO handle ffmpeg exit (and trigger "error" if unexpected)

var Stream      = require('stream').Stream;
var util        = require('util');
var spawn       = require('child_process').spawn;
var PngSplitter = require('../PngSplitter');

module.exports = PngEncoder;
util.inherits(PngEncoder, Stream);
function PngEncoder(options) {
  Stream.call(this);

  options = options || {};

  this.writable = true;
  this.readable = true;

  this._spawn       = options.spawn || spawn;
  this._frameRate   = options.frameRate || 5;
  this._pngSplitter = options.pngSplitter || new PngSplitter();
  this._log         = options.log;
  this._ffmpeg      = undefined;
  this._ending      = false;
}

PngEncoder.prototype.write = function(buffer) {
  if (!this._ffmpeg) {
    this._initFfmpegAndPipes();
  }

  this._ffmpeg.stdin.write(buffer);
};

PngEncoder.prototype._initFfmpegAndPipes = function() {
  this._ffmpeg = this._spawnFfmpeg();

  // @TODO: Make this more sophisticated for somehow and figure out how it
  // will work with the planned new data recording system.
  if (this._log) {
    this._ffmpeg.stderr.pipe(this._log);
  }

  this._ffmpeg.stdout.pipe(this._pngSplitter);
  this._pngSplitter.on('data', this.emit.bind(this, 'data'));

  // 'error' can be EPIPE if ffmpeg does not exist. We handle this with the
  // 'exit' event below.
  this._ffmpeg.stdin.on('error', function() {});

  var self = this;
  this._ffmpeg.on('exit', function(code) {
    if (code === 0) {
      // we expected ffmpeg to exit
      if (self._ending) {
        self.emit('end');
        return;
      }

      self.emit('error', new Error('Unexpected ffmpeg exit with code 0.'));
      return;
    }

    // 127 is used by the OS to indicate that ffmpeg was not found
    if (code === 127) {
      self.emit('error', new Error('Ffmpeg was not found / exit code 127.'));
      return;
    }

    self.emit('error', new Error('Ffmpeg exited with error code: ' + code));
  });
};

PngEncoder.prototype._spawnFfmpeg = function() {
  // @TODO allow people to configure the ffmpeg path
  return this._spawn('ffmpeg', [
    '-i' ,'-',
    '-f', 'image2pipe',
    '-vcodec', 'png',
    '-r', this._frameRate,
    '-',
  ]);
};

PngEncoder.prototype.end = function() {
  this._ending = true;
  this._ffmpeg.stdin.end();
};
<|endoftext|>


<commit_before>// this sets the background color of the master UIView (when there are no windows/tab groups on it)
Titanium.UI.setBackgroundColor('#000');

var _home = {};

(function() {
	// namespace
	var osname = Titanium.Platform.osname;

	// private var
	var longitude = null;
	var latitude = null;
	var accuracy = null;
	var isLocationReady = false;

	var isSetLocationCallback = false;

	function getLocation() {
		if(isSetLocationCallback) {
			return;
		}
		isSetLocationCallback = true;

		function translateErrorCode(code) {
			if (code == null) {
				return null;
			}
			switch (code) {
				case Ti.Geolocation.ERROR_LOCATION_UNKNOWN:
					return "Location unknown";
				case Ti.Geolocation.ERROR_DENIED:
					return "Access denied";
				case Ti.Geolocation.ERROR_NETWORK:
					return "Network error";
				case Ti.Geolocation.ERROR_HEADING_FAILURE:
					return "Failure to detect heading";
				case Ti.Geolocation.ERROR_REGION_MONITORING_DENIED:
					return "Region monitoring access denied";
				case Ti.Geolocation.ERROR_REGION_MONITORING_FAILURE:
					return "Region monitoring access failure";
				case Ti.Geolocation.ERROR_REGION_MONITORING_DELAYED:
					return "Region monitoring setup delayed";
			}
		}

		function onLocation(e) {
			if (!e.success || e.error) {
				//currentLocation.text = 'error: ' + JSON.stringify(e.error);
				Ti.API.info("Code translation: "+translateErrorCode(e.code));
				alert('error ' + JSON.stringify(e.error));
				return;
			}
			isLocationReady=true;

			//var longitude = e.coords.longitude;
			//var latitude = e.coords.latitude;
			//var altitude = e.coords.altitude;
			//var heading = e.coords.heading;
			//var accuracy = e.coords.accuracy;
			//var speed = e.coords.speed;
			var timestamp = e.coords.timestamp;
			//var altitudeAccuracy = e.coords.altitudeAccuracy;

			latitude = e.coords.latitude;
			longitude = e.coords.longitude;
			accuracy = e.coords.accuracy;

			//Ti.API.info('speed ' + speed);
			//currentLocation.text = 'long:' + longitude + ' lat: ' + latitude;
			Titanium.API.info('geo - current location: ' + new Date(timestamp) + ' long ' + longitude + ' lat ' + latitude + ' accuracy ' + accuracy);
		}

		function reverseGeocoder(latitude,longitude) {
			Titanium.Geolocation.reverseGeocoder(latitude,longitude, function(evt) {
				if (evt.success) {
					var places = evt.places;
					if (places && places.length) {
						reverseGeo.text = places[0].address;
					} else {
						reverseGeo.text = "No address found";
					}
					Ti.API.debug("reverse geolocation result = "+JSON.stringify(evt));
				} else {
					Ti.UI.createAlertDialog({
						title:'Reverse geo error',
						message:evt.error
					}).show();
					Ti.API.info("Code translation: "+translateErrorCode(e.code));
				}
			});
		}

		//
		//  SHOW CUSTOM ALERT IF DEVICE HAS GEO TURNED OFF
		//
		if (Titanium.Geolocation.locationServicesEnabled === false) {
			Titanium.UI.createAlertDialog({
				title:'Kitchen Sink',
				message:'Your device has geo turned off - turn it on.'
			}).show();
		} else {
			if (Titanium.Platform.name != 'android') {
				var authorization = Titanium.Geolocation.locationServicesAuthorization;
				Ti.API.info('Authorization: '+authorization);
				if (authorization == Titanium.Geolocation.AUTHORIZATION_DENIED) {
					Ti.UI.createAlertDialog({
						title:'Kitchen Sink',
						message:'You have disallowed Titanium from running geolocation services.'
					}).show();
				} else if (authorization == Titanium.Geolocation.AUTHORIZATION_RESTRICTED) {
					Ti.UI.createAlertDialog({
						title:'Kitchen Sink',
						message:'Your system has disallowed Titanium from running geolocation services.'
					}).show();
				}
			}
			//
			//  SET ACCURACY - THE FOLLOWING VALUES ARE SUPPORTED
			//
			// Titanium.Geolocation.ACCURACY_BEST
			// Titanium.Geolocation.ACCURACY_NEAREST_TEN_METERS
			// Titanium.Geolocation.ACCURACY_HUNDRED_METERS
			// Titanium.Geolocation.ACCURACY_KILOMETER
			// Titanium.Geolocation.ACCURACY_THREE_KILOMETERS
			//
			Titanium.Geolocation.accuracy = Titanium.Geolocation.ACCURACY_HUNDRED_METERS;
			//
			//  SET DISTANCE FILTER.  THIS DICTATES HOW OFTEN AN EVENT FIRES BASED ON THE DISTANCE THE DEVICE MOVES
			//  THIS VALUE IS IN METERS
			//
			Titanium.Geolocation.distanceFilter = 10;
			//
			// GET CURRENT POSITION - THIS FIRES ONCE
			//
			Titanium.Geolocation.getCurrentPosition(onLocation);
			//
			// EVENT LISTENER FOR GEO EVENTS - THIS WILL FIRE REPEATEDLY (BASED ON DISTANCE FILTER)
			//
			Titanium.Geolocation.addEventListener('location', onLocation);
		}
	}

	//
	// create base UI tab and root window
	//
	var win = Titanium.UI.createWindow({
		title:'Home',
		backgroundColor:'#fff'
	});
	var tab = Titanium.UI.createTab({
		icon:'KS_nav_views.png',
		title:'Home',
		window:win
	});

	// button
	var init = Titanium.UI.createButton({
		borderColor:'#000',
		borderWidth:'1.0',
		color:'#999',
		title:'Init',
		font: {
			fontSize:20,
			fontFamily:'Helvetica Neue'
		},
		textAlign:'center',
		backgroundColor:'#fff',
		top:'5%',
		left:'5%',
		height:'40%',
		width:'90%',
	});
	var receive = Titanium.UI.createButton({
		borderColor:'#000',
		borderWidth:'1.0',
		color:'#999',
		title:'Receive',
		font: {
			fontSize:20,
			fontFamily:'Helvetica Neue'
		},
		textAlign:'center',
		backgroundColor:'#fff',
		top:'55%',
		left:'5%',
		height:'40%',
		width:'90%',
	});

	init.addEventListener("click", function() {
		/*Titanium.Media.showCamera({
		 success:function(event)
		 {
		 var image = event.media;

		 Ti.API.debug('Our type was: '+event.mediaType);
		 if(event.mediaType == Ti.Media.MEDIA_TYPE_PHOTO)
		 {
		 var imageView = Ti.UI.createImageView({width:win1.width,height:win1.height,image:event.media});
		 win1.add(imageView);
		 }
		 else
		 {
		 alert("got the wrong type back ="+event.mediaType);
		 }
		 },
		 cancel:function()
		 {
		 alert('You canceled the action.');
		 },
		 error:function(error)
		 {
		 // create alert
		 var a = Titanium.UI.createAlertDialog({title:'Camera'});

		 // set message
		 if (error.code == Titanium.Media.NO_CAMERA)
		 {
		 a.setMessage('Please run this test on device');
		 }
		 else
		 {
		 a.setMessage('Unexpected error: ' + error.code);
		 }

		 // show alert
		 a.show();
		 },
		 saveToPhotoGallery:true,
		 allowEditing:true,
		 mediaTypes:[Ti.Media.MEDIA_TYPE_PHOTO],
		 })*/
		function onQRRead(barcode) {
			var label = Titanium.UI.createLabel({
				text:'Barcode: ' + barcode,
				textAlign:'center',
				width:'auto'
			});
			win.add(label);
			var HTTPClient = Titanium.Network.createHTTPClient({
				connectionType: 'POST',
				location: "https://fibottyl.appspot.com/checkin",
			});
		}

		if(osname == "android") {
			var titaniumBarcode = require('com.mwaysolutions.barcode');
			titaniumBarcode.scan({
				success: function (data) {
					if(data && data.barcode) {
						onQRRead(data.barcode);
					} else {
						alert(JSON.stringify(data));
					}
				},
				error: function (err) {
					alert("Error!! " + err);
				},
				cancel: function () {
					//alert("cancel");
				}
			});
		} else if(osname == "ipad" || osname == "iphone") {
			var TiBar = require('tibar');
			TiBar.scan({
				// simple configuration for iPhone simulator
				configure: {
					classType: "ZBarReaderController",
					sourceType: "Album",
					cameraMode: "Default",
					symbol: {
						"QR-Code":true,
					}
				},
				success: function(data) {
					Ti.API.info('TiBar success callback!');
					if(data && data.barcode) {
						onQRRead(data.barcode);
					}
				},/*
				cancel: function() {
					Ti.API.info('TiBar cancel callback!');
				},
				error: function() {
					Ti.API.info('TiBar error callback!');
				}*/
			});
			//
		}
		/*
		 var intent = Ti.Android.createIntent({
		 action: "com.google.zxing.client.android.SCAN"
		 });
		 intent.putExtra("SCAN_MODE", "QR_SCAN_MODE");
		 var activity = Ti.Android.currentActivity;
		 activity.startActivityForResult(intent, function(e) {
		 if (e.resultCode == Ti.Android.RESULT_OK) {
		 var contents = e.intent.getStringExtra("SCAN_RESULT");
		 var format = e.intent.getStringExtra("SCAN_RESULT_FORMAT");
		 Ti.UI.createNotification({
		 message: "Contents: " + contents + ", Format: " + format
		 }).show();
		 } else if (e.resultCode == Ti.Android.RESULT_CANCELED) {
		 Ti.UI.createNotification({
		 message: "Scan canceled!"
		 }).show();
		 }
		 });
		 */
	});
	// for iPhone either use web service or http://code.google.com/p/tibar/

	function showQRFallback(str) {
		str = "me@nuttyknot.com";
		var url = "https://chart.googleapis.com/chart?cht=qr&chl="+Titanium.Network.encodeURIComponent(str)+"&chs="+win.width+"x"+win.height;
		var imageView = Ti.UI.createImageView({
			width:win.width,
			height:win.height,
			image:url,
			top:0,
			left:0,
			zIndex:100,
		});
		var invite = Titanium.UI.createLabel({
			text:'Invite other to scan this QR code',
			color:"#000",
			textAlign:'center',
			width:'auto',
			top:"80%",
			font: {
				fontSize:20,
				fontFamily:'Helvetica Neue'
			},
			zIndex:1000,
		});

		var win2 = Titanium.UI.createWindow({
			title:'QR Code',
			backgroundColor:'#fff'
		});
		win2.add(invite);
		win2.add(imageView);
		imageView.addEventListener('click', function() {
			win2.close();
			//this.remove();
		});
		Ti.UI.currentTab.open(win2);
		//https://chart.googleapis.com/chart?cht=qr&chl=Hello+world&chs=200x200
	}

	receive.addEventListener('click', function() {
		if(osname == "android") {
			var intent = Ti.Android.createIntent({
				action: "com.google.zxing.client.android.ENCODE"
			});
			intent.putExtra("ENCODE_TYPE", "TEXT_TYPE");
			intent.putExtra("ENCODE_DATA", "me@nuttyknot.com");
			var activity = Ti.Android.currentActivity;
			activity.startActivityForResult(intent, function(e) {
				if ("error" in e) {
					showQRFallback();
					return;
				}
				/*if (e.resultCode == Ti.Android.RESULT_OK) {
				 var contents = e.intent.getStringExtra("SCAN_RESULT");
				 var format = e.intent.getStringExtra("SCAN_RESULT_FORMAT");
				 Ti.UI.createNotification({
				 message: "Contents: " + contents + ", Format: " + format
				 }).show();
				 } else if (e.resultCode == Ti.Android.RESULT_CANCELED) {
				 Ti.UI.createNotification({
				 message: "Scan canceled!"
				 }).show();
				 }*/
			});
		} else if(osname == "ipad" || osname == "iphone") {
			//
		}
	});
	//win1.add(label1);
	win.add(init);
	win.add(receive);

	getLocation();

	_home.tab = tab;
})();<commit_msg>Clean up<commit_after>// this sets the background color of the master UIView (when there are no windows/tab groups on it)
Titanium.UI.setBackgroundColor('#000');

var _home = {};

(function() {
	// namespace
	var osname = Titanium.Platform.osname;

	// private var
	var longitude = null;
	var latitude = null;
	var accuracy = null;
	var isLocationReady = false;

	var isSetLocationCallback = false;

	function getLocation() {
		if(isSetLocationCallback) {
			return;
		}
		isSetLocationCallback = true;

		function translateErrorCode(code) {
			if (code == null) {
				return null;
			}
			switch (code) {
				case Ti.Geolocation.ERROR_LOCATION_UNKNOWN:
					return "Location unknown";
				case Ti.Geolocation.ERROR_DENIED:
					return "Access denied";
				case Ti.Geolocation.ERROR_NETWORK:
					return "Network error";
				case Ti.Geolocation.ERROR_HEADING_FAILURE:
					return "Failure to detect heading";
				case Ti.Geolocation.ERROR_REGION_MONITORING_DENIED:
					return "Region monitoring access denied";
				case Ti.Geolocation.ERROR_REGION_MONITORING_FAILURE:
					return "Region monitoring access failure";
				case Ti.Geolocation.ERROR_REGION_MONITORING_DELAYED:
					return "Region monitoring setup delayed";
			}
		}

		function onLocation(e) {
			if (!e.success || e.error) {
				//currentLocation.text = 'error: ' + JSON.stringify(e.error);
				Ti.API.info("Code translation: "+translateErrorCode(e.code));
				//alert('error ' + JSON.stringify(e.error));
				return;
			}
			isLocationReady=true;

			//var longitude = e.coords.longitude;
			//var latitude = e.coords.latitude;
			//var altitude = e.coords.altitude;
			//var heading = e.coords.heading;
			//var accuracy = e.coords.accuracy;
			//var speed = e.coords.speed;
			var timestamp = e.coords.timestamp;
			//var altitudeAccuracy = e.coords.altitudeAccuracy;

			latitude = e.coords.latitude;
			longitude = e.coords.longitude;
			accuracy = e.coords.accuracy;

			//Ti.API.info('speed ' + speed);
			//currentLocation.text = 'long:' + longitude + ' lat: ' + latitude;
			Titanium.API.info('geo - current location: ' + new Date(timestamp) + ' long ' + longitude + ' lat ' + latitude + ' accuracy ' + accuracy);
		}

		function reverseGeocoder(latitude,longitude) {
			Titanium.Geolocation.reverseGeocoder(latitude,longitude, function(evt) {
				if (evt.success) {
					var places = evt.places;
					if (places && places.length) {
						reverseGeo.text = places[0].address;
					} else {
						reverseGeo.text = "No address found";
					}
					Ti.API.debug("reverse geolocation result = "+JSON.stringify(evt));
				} else {
					Ti.UI.createAlertDialog({
						title:'Reverse geo error',
						message:evt.error
					}).show();
					Ti.API.info("Code translation: "+translateErrorCode(e.code));
				}
			});
		}

		//
		//  SHOW CUSTOM ALERT IF DEVICE HAS GEO TURNED OFF
		//
		if (Titanium.Geolocation.locationServicesEnabled === false) {
			Titanium.UI.createAlertDialog({
				title:'Kitchen Sink',
				message:'Your device has geo turned off - turn it on.'
			}).show();
		} else {
			if (Titanium.Platform.name != 'android') {
				var authorization = Titanium.Geolocation.locationServicesAuthorization;
				Ti.API.info('Authorization: '+authorization);
				if (authorization == Titanium.Geolocation.AUTHORIZATION_DENIED) {
					Ti.UI.createAlertDialog({
						title:'Kitchen Sink',
						message:'You have disallowed Titanium from running geolocation services.'
					}).show();
				} else if (authorization == Titanium.Geolocation.AUTHORIZATION_RESTRICTED) {
					Ti.UI.createAlertDialog({
						title:'Kitchen Sink',
						message:'Your system has disallowed Titanium from running geolocation services.'
					}).show();
				}
			}
			//
			//  SET ACCURACY - THE FOLLOWING VALUES ARE SUPPORTED
			//
			// Titanium.Geolocation.ACCURACY_BEST
			// Titanium.Geolocation.ACCURACY_NEAREST_TEN_METERS
			// Titanium.Geolocation.ACCURACY_HUNDRED_METERS
			// Titanium.Geolocation.ACCURACY_KILOMETER
			// Titanium.Geolocation.ACCURACY_THREE_KILOMETERS
			//
			Titanium.Geolocation.accuracy = Titanium.Geolocation.ACCURACY_HUNDRED_METERS;
			//
			//  SET DISTANCE FILTER.  THIS DICTATES HOW OFTEN AN EVENT FIRES BASED ON THE DISTANCE THE DEVICE MOVES
			//  THIS VALUE IS IN METERS
			//
			Titanium.Geolocation.distanceFilter = 10;
			//
			// GET CURRENT POSITION - THIS FIRES ONCE
			//
			Titanium.Geolocation.getCurrentPosition(onLocation);
			//
			// EVENT LISTENER FOR GEO EVENTS - THIS WILL FIRE REPEATEDLY (BASED ON DISTANCE FILTER)
			//
			Titanium.Geolocation.addEventListener('location', onLocation);
		}
	}

	//
	// create base UI tab and root window
	//
	var win = Titanium.UI.createWindow({
		title:'Home',
		backgroundColor:'#fff'
	});
	var tab = Titanium.UI.createTab({
		icon:'KS_nav_views.png',
		title:'Home',
		window:win
	});

	// button
	var init = Titanium.UI.createButton({
		borderColor:'#000',
		borderWidth:'1.0',
		color:'#999',
		title:'Init',
		font: {
			fontSize:20,
			fontFamily:'Helvetica Neue'
		},
		textAlign:'center',
		backgroundColor:'#fff',
		top:'5%',
		left:'5%',
		height:'40%',
		width:'90%',
	});
	var receive = Titanium.UI.createButton({
		borderColor:'#000',
		borderWidth:'1.0',
		color:'#999',
		title:'Receive',
		font: {
			fontSize:20,
			fontFamily:'Helvetica Neue'
		},
		textAlign:'center',
		backgroundColor:'#fff',
		top:'55%',
		left:'5%',
		height:'40%',
		width:'90%',
	});

	init.addEventListener("click", function() {
		/*Titanium.Media.showCamera({
		 success:function(event)
		 {
		 var image = event.media;

		 Ti.API.debug('Our type was: '+event.mediaType);
		 if(event.mediaType == Ti.Media.MEDIA_TYPE_PHOTO)
		 {
		 var imageView = Ti.UI.createImageView({width:win1.width,height:win1.height,image:event.media});
		 win1.add(imageView);
		 }
		 else
		 {
		 alert("got the wrong type back ="+event.mediaType);
		 }
		 },
		 cancel:function()
		 {
		 alert('You canceled the action.');
		 },
		 error:function(error)
		 {
		 // create alert
		 var a = Titanium.UI.createAlertDialog({title:'Camera'});

		 // set message
		 if (error.code == Titanium.Media.NO_CAMERA)
		 {
		 a.setMessage('Please run this test on device');
		 }
		 else
		 {
		 a.setMessage('Unexpected error: ' + error.code);
		 }

		 // show alert
		 a.show();
		 },
		 saveToPhotoGallery:true,
		 allowEditing:true,
		 mediaTypes:[Ti.Media.MEDIA_TYPE_PHOTO],
		 })*/
		function onQRRead(barcode) {
			var label = Titanium.UI.createLabel({
				text:'Barcode: ' + barcode,
				textAlign:'center',
				width:'auto'
			});
			win.add(label);
			var HTTPClient = Titanium.Network.createHTTPClient({
				connectionType: 'POST',
				location: "https://fibottyl.appspot.com/checkin",
			});
		}

		if(osname == "android") {
			var titaniumBarcode = require('com.mwaysolutions.barcode');
			titaniumBarcode.scan({
				success: function (data) {
					if(data && data.barcode) {
						onQRRead(data.barcode);
					} else {
						alert(JSON.stringify(data));
					}
				},
				error: function (err) {
					alert("Error!! " + err);
				},
				cancel: function () {
					//alert("cancel");
				}
			});
		} else if(osname == "ipad" || osname == "iphone") {
			var TiBar = require('tibar');
			TiBar.scan({
				// simple configuration for iPhone simulator
				configure: {
					classType: "ZBarReaderController",
					sourceType: "Album",
					cameraMode: "Default",
					symbol: {
						"QR-Code":true,
					}
				},
				success: function(data) {
					Ti.API.info('TiBar success callback!');
					if(data && data.barcode) {
						onQRRead(data.barcode);
					}
				},/*
				cancel: function() {
					Ti.API.info('TiBar cancel callback!');
				},
				error: function() {
					Ti.API.info('TiBar error callback!');
				}*/
			});
			//
		}
	});
	// for iPhone either use web service or http://code.google.com/p/tibar/

	function showQRFallback(str) {
		str = "me@nuttyknot.com";
		var url = "https://chart.googleapis.com/chart?cht=qr&chl="+Titanium.Network.encodeURIComponent(str)+"&chs="+win.width+"x"+win.height;
		var imageView = Ti.UI.createImageView({
			width:win.width,
			height:win.height,
			image:url,
			top:0,
			left:0,
			zIndex:100,
		});
		var invite = Titanium.UI.createLabel({
			text:'Invite other to scan this QR code',
			color:"#000",
			textAlign:'center',
			width:'auto',
			top:"80%",
			font: {
				fontSize:20,
				fontFamily:'Helvetica Neue'
			},
			zIndex:1000,
		});

		var win2 = Titanium.UI.createWindow({
			title:'QR Code',
			backgroundColor:'#fff'
		});
		win2.add(invite);
		win2.add(imageView);
		imageView.addEventListener('click', function() {
			win2.close();
			//this.remove();
		});
		Ti.UI.currentTab.open(win2);
		//https://chart.googleapis.com/chart?cht=qr&chl=Hello+world&chs=200x200
	}

	receive.addEventListener('click', function() {
		if(osname == "android") {
			var intent = Ti.Android.createIntent({
				action: "com.google.zxing.client.android.ENCODE"
			});
			intent.putExtra("ENCODE_TYPE", "TEXT_TYPE");
			intent.putExtra("ENCODE_DATA", "me@nuttyknot.com");
			var activity = Ti.Android.currentActivity;
			activity.startActivityForResult(intent, function(e) {
				if ("error" in e) {
					showQRFallback();
					return;
				}
				/*if (e.resultCode == Ti.Android.RESULT_OK) {
				 var contents = e.intent.getStringExtra("SCAN_RESULT");
				 var format = e.intent.getStringExtra("SCAN_RESULT_FORMAT");
				 Ti.UI.createNotification({
				 message: "Contents: " + contents + ", Format: " + format
				 }).show();
				 } else if (e.resultCode == Ti.Android.RESULT_CANCELED) {
				 Ti.UI.createNotification({
				 message: "Scan canceled!"
				 }).show();
				 }*/
			});
		} else if(osname == "ipad" || osname == "iphone") {
			showQRFallback();
		}
	});
	//win1.add(label1);
	win.add(init);
	win.add(receive);

	getLocation();

	_home.tab = tab;
})();<|endoftext|>


<commit_before>'use babel';

/** @jsx etch.dom */
/* @flow*/
import etch from 'etch';
import { Emitter, CompositeDisposable, Disposable } from 'atom';
import { normalizeString } from '../helpers';
import type { Message } from '../types';

// TODO
// - sort data by column head
// - resize column
// - only current file filter
// - soft wrap table
export default class ResultView {
  properties: {
    messages: Array<Message>;
    ansiToHtml: boolean;
    softWrap: boolean;
 }
  refs: any;
  element: any;
  panel: any;
  emitter: Emitter;
  disposables: CompositeDisposable;

  constructor(properties:Object) {
    this.properties = properties;
    this.emitter = new Emitter();
    this.disposables = new CompositeDisposable();
    etch.initialize(this);
    const softWrapHandler = () => {
      console.log('this', this);
      this.properties.softWrap = this.refs.softWrap.isChecked;
      this.update(this.properties);
    };
    this.refs.softWrap.addEventListener('click', softWrapHandler);
    this.disposables.add(new Disposable(() => { this.refs.closeButton.removeEventListener('click', softWrapHandler()); }));
  }

  render() {
    return (

            Failed: {this.properties.messages.filter(result => result.state === 'failed').length}
            Skipped: {this.properties.messages.filter(result => result.state === 'skipped').length}
            Passed: {this.properties.messages.filter(result => result.state === 'passed').length}

            <input class='input-checkbox' ref='softWrap' type='checkbox'/> Soft Wrap
            <input class='input-checkbox' type='checkbox'/> Current file only
            <button class="inline-block-tight btn btn-sm" title="Test Project"
              onclick={this.handleTestButtonClick.bind(this, true)}>Test Project</button>

State

Duration

Title

Error

Location

 0 ? 'display: none;' : ''}>No tester messages

          {this.properties.messages.map((message, index) =>

                      {message.state || 'unknown'}

{message.duration || 0}ms

{message.title || ''}

                      {atom.project.relativizePath(message.filePath)[1] || message.filePath || ''}:{message.lineNumber.toString() || ''}

)}

    );
  }

  update(newProperties:Object) {
    if (this.properties.messages !== newProperties.messages) {
      this.properties.messages = newProperties.messages;
      return etch.update(this);
    }
    return Promise.resolve();
  }

  async destroy() {
    await etch.destroy(this);
  }

  getTitle() {
    return 'Tester results';
  }

  getIconName() {
    return 'law';
  }

  getDefaultLocation() {
    return 'bottom';
  }

  getAllowedLocations() {
    return ['left', 'right', 'bottom'];
  }

  getURI() {
    return 'atom://tester-result-view';
  }

  getPath() {
    return 'atom://tester-result-view';
  }

  getElement() {
    return this.element;
  }

  onTestButtonClick(callback : Function) : Disposable {
    return this.emitter.on('test-button-click', callback);
  }

  handleRowClick(selectedIndex: number): void {
    const message = this.properties.messages[selectedIndex];
    atom.workspace.open(message.filePath, { initialLine: message.lineNumber });
  }

  handleTestButtonClick(shouldTestCurrentProject :boolean):void {
    console.log('handleTestButtonClick', shouldTestCurrentProject);
    this.emitter.emit('test-button-click', shouldTestCurrentProject);
  }
}
<commit_msg>fix soft wrap<commit_after>'use babel';

/** @jsx etch.dom */
/* @flow*/
import etch from 'etch';
import { Emitter, CompositeDisposable, Disposable } from 'atom';
import { normalizeString } from '../helpers';
import type { Message } from '../types';

// TODO
// - sort data by column head
// - resize column
// - only current file filter
// - soft wrap table
export default class ResultView {
  properties: {
    messages: Array<Message>;
    ansiToHtml: boolean;
    softWrap: boolean;
 }
  refs: any;
  element: any;
  panel: any;
  emitter: Emitter;
  disposables: CompositeDisposable;

  constructor(properties:Object) {
    this.properties = properties;
    this.emitter = new Emitter();
    this.disposables = new CompositeDisposable();
    etch.initialize(this);

    const softWrapHandler = () => {
      this.update(this.properties);
    };
    this.refs.softWrap.addEventListener('click', softWrapHandler);
    this.disposables.add(new Disposable(() => { this.refs.softWrap.removeEventListener('click', softWrapHandler()); }));
  }

  render() {
    return (

            Failed: {this.properties.messages.filter(result => result.state === 'failed').length}
            Skipped: {this.properties.messages.filter(result => result.state === 'skipped').length}
            Passed: {this.properties.messages.filter(result => result.state === 'passed').length}

            <input class='input-checkbox' ref='softWrap' type='checkbox'/> Soft Wrap
            <input class='input-checkbox' type='checkbox'/> Current file only
            <button class="inline-block-tight btn btn-sm" title="Test Project"
              onclick={this.handleTestButtonClick.bind(this, true)}>Test Project</button>

State

Duration

Title

Error

Location

 0 ? 'display: none;' : ''}>No tester messages

          {this.properties.messages.map((message, index) =>

                      {message.state || 'unknown'}

{message.duration || 0}ms

{message.title || ''}

                      {atom.project.relativizePath(message.filePath)[1] || message.filePath || ''}:{message.lineNumber.toString() || ''}

)}

    );
  }

  update(newProperties:Object) {
    if (this.properties.messages !== newProperties.messages) {
      this.properties.messages = newProperties.messages;
      return etch.update(this);
    }
    return Promise.resolve();
  }

  async destroy() {
    await etch.destroy(this);
  }

  getTitle() {
    return 'Tester results';
  }

  getIconName() {
    return 'law';
  }

  getDefaultLocation() {
    return 'bottom';
  }

  getAllowedLocations() {
    return ['left', 'right', 'bottom'];
  }

  getURI() {
    return 'atom://tester-result-view';
  }

  getPath() {
    return 'atom://tester-result-view';
  }

  getElement() {
    return this.element;
  }

  onTestButtonClick(callback : Function) : Disposable {
    return this.emitter.on('test-button-click', callback);
  }

  handleRowClick(selectedIndex: number): void {
    const message = this.properties.messages[selectedIndex];
    atom.workspace.open(message.filePath, { initialLine: message.lineNumber });
  }

  handleTestButtonClick(shouldTestCurrentProject :boolean):void {
    console.log('handleTestButtonClick', shouldTestCurrentProject);
    this.emitter.emit('test-button-click', shouldTestCurrentProject);
  }
}
<|endoftext|>


<commit_before>import React, {Component, PropTypes} from 'react';
import d3 from 'd3';

export default class LiquidGauge extends Component {
  static propTypes = {
    backgroundColor: PropTypes.oneOfType([
      React.PropTypes.string,
      React.PropTypes.arrayOf(React.PropTypes.string)
    ]),
    compassFont: PropTypes.string,
    lineColor: PropTypes.string,
    shadowColor: PropTypes.string,
    subColor: PropTypes.string,
    subFont: PropTypes.string,
    textColor: PropTypes.string,
    textFont: PropTypes.string
  };

  static defaultProps = {
    // Background color, should this be transparent by default?
    backgroundColor: ['#022f2c', '#479791'],

    // Font to use for compass text
    compassFont: 'Century Gothic',

    // Color to draw lines, should this be foreground color?
    lineColor: '#006363',

    // Color of drop shadow
    shadowColor: '#1d7373',

    // Color of subscripts
    subColor: '#888',

    // Font to use for subscripts
    subFont: 'Century Gothic',

    // Color of main text
    textColor: '#099',

    // Font to use for main text
    textFont: 'Century Gothic',

    width: 400
  }

  componentDidMount() {
    const gauge = this.renderWindGauge("WindGauge", this.props.value);

    this.setState({gauge: gauge});
  }

  componentWillReceiveProps(nextProps) {
    if(nextProps.width !== this.props.width) {
      const gauge = this.renderWindGauge("WindGauge", this.props.value);
      this.setState({gauge: gauge});
    } else if(this.state !== null) {
      this.state.gauge.update(this.props.value);
    }
  }

  render() {
    return <div / >;
  }

  renderWindGauge(elementId, value) {
    function deg2rad(deg) {
      return deg / 180 * Math.PI;
    }

    let el = React.findDOMNode(this);

    let {width, height, background, lineColor, textColor} = this.props;

    while (el.firstChild) {
      el.removeChild(el.firstChild);
    }

    let svg = d3.select(el).append("svg")
      .attr("width", width)
      .attr("height", height);

    let gradient = svg.append("defs")
      .append("linearGradient")
        .attr("id", "gradient")
        .attr("x1", "100%")
        .attr("y1", "0%")
        .attr("x2", "0%")
        .attr("y2", "0%")
        .attr("spreadMethod", "pad");

    gradient.append("stop")
      .attr("offset", "0%")
      .attr("stop-color", background[0])
      .attr("stop-opacity", 1);

    gradient.append("stop")
      .attr("offset", "100%")
      .attr("stop-color", background[1])
      .attr("stop-opacity", 1);

    svg.append("rect")
      .attr("width", width)
      .attr("height", height)
      //.style("fill", "url(#gradient)");
      .style("fill", "black");

    let divider = [{x: 0.6 * width, y: 0 * height / 3},
                   {x: 0.7 * width, y: 1 * height / 3},
                   {x: 0.7 * width, y: 2 * height / 3},
                   {x: 0.6 * width, y: 3 * height / 3}];

    let line2 = [{x: 0.7 * width, y: 1 * height / 3},
                 {x: 1.0 * width, y: 1 * height / 3}];

    let line3 = [{x: 0.7 * width, y: 2 * height / 3},
                 {x: 1.0 * width, y: 2 * height / 3}];

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

    svg.append("path")
      .attr("d", lineFunction(divider))
      .attr("stroke", lineColor)
      .attr("stroke-width", 4)
      .attr("fill", "none");

    svg.append("path")
      .attr("d", lineFunction(line2))
      .attr("stroke", lineColor)
      .attr("stroke-width", 4)
      .attr("fill", "none");

    svg.append("path")
      .attr("d", lineFunction(line3))
      .attr("stroke", lineColor)
      .attr("stroke-width", 4)
      .attr("fill", "none");

    const boxWidth = 0.35 * width,
          mBoxWidth = 0.30 * width,
          boxHeight=  height / 3,
          boxX = 0.65 * width,
          mBoxX = 0.7 * width;

    drawDataBox(boxX,  0 * height / 3, boxWidth,  boxHeight, 123, 123, "KTS", "BSPD");
    drawDataBox(mBoxX, 1 * height / 3, mBoxWidth, boxHeight, 123, 123, "\u00B0", "AWA");
    drawDataBox(boxX,  2 * height / 3, boxWidth,  boxHeight, 123, 123, "KTS", "AWS");

    function drawDataBox(x, y, w, h, val, tgt, units, measure) {
//
//      let box = svg.append("rect")
//        .attr("x", x)
//        .attr("y", y)
//        .attr("width", w)
//        .attr("height", h)
//        .attr("rx", 3)
//        .attr("ry", 3)
//        .attr("fill", "none")
//        .attr("stroke", lineColor)
//        .attr("stroke-width", 2);

      const valSize = 75,
            subSize = 24,
            unitSize = units === '\u00B0' ? 48 : 24,
            padding = 20;

      let unitText = svg.append("text")
        .attr("x", x + w - 2 * padding)
        .attr("y", y + padding + 2 * subSize)
        .attr("font-family", "Century Gothic")
        .attr("text-anchor", "end")
        .attr("fill", textColor)
        .attr("font-size", unitSize)
        .text(units);

      let w1 = unitText.node().getBBox().width;

      let valueText = svg.append("text")
        .attr("x", x + w - w1 - 2 * padding)
        .attr("y", y + padding + valSize)
        .attr("text-anchor", "end")
        .attr("fill", textColor)
        .attr("font-size", valSize)
        .text(val);

      let subText = svg.append("text")
        .attr("x", 0)
        .attr("y", y + h / 2)
        .attr("font-size", subSize)
        .attr("fill", textColor)
        .attr("text-anchor", "middle")
        .attr("transform", "translate(0," + measure.length * -10 + ")")
        .selectAll("tspan")
          .data(measure.split(''))
          .enter().append("tspan")
            .attr("x", x + w - padding)
            .attr("dy", "0.8em")
            .text(function(d) { return d});

      let tgtText = svg.append("text")
        .attr("x", x + w - 2 * padding)
        .attr("y", y + h - padding / 2)
        .attr("fill", textColor)
        .attr("text-anchor", "end")
        .text(tgt);

      let w2 = tgtText.node().getBBox().width;

      let tgtLbl = svg.append("text")
        .attr("x", x + w - w2 - 25 - 2 * padding)
        .attr("y", y + h - padding / 2)
        .attr("fill", textColor)
        .attr("text-anchor", "end")
        .text("Target:");

      if(tgt >= val) {
        triangle(x + w - w2 - 20 - 2 * padding, y + h - padding / 2, 18, 18, 'up');
      } else {
        triangle(x + w - w2 - 20 - 2 * padding, y + h - padding / 2, 18, 18, 'dn');
      }
    }

    function triangle(x, y, w, h, dir) {
      var tx, ty, rx;
      tx = x + w / 2;
      if(dir == 'up') {
        ty = y - h;
      } else {
        ty = y;
        y -= h;
      }
      rx = x + w;

      var tPoints = [{x:tx, y:ty}, {x:x, y:y}, {x:rx, y:y}];

      svg.append("path")
        .attr("d", lineFunction(tPoints) + "Z")
        .attr("fill", textColor);

    }

    function GaugeUpdater() {
      this.update = function(value) {
      }
    }

    return new GaugeUpdater();
  }
}
<commit_msg>Add compass circle drawing code<commit_after>import React, {Component, PropTypes} from 'react';
import d3 from 'd3';

export default class LiquidGauge extends Component {
  static propTypes = {
    backgroundColor: PropTypes.oneOfType([
      React.PropTypes.string,
      React.PropTypes.arrayOf(React.PropTypes.string)
    ]),
    compassFont: PropTypes.string,
    lineColor: PropTypes.string,
    shadowColor: PropTypes.string,
    subColor: PropTypes.string,
    subFont: PropTypes.string,
    textColor: PropTypes.string,
    textFont: PropTypes.string
  };

  static defaultProps = {
    // Background color, should this be transparent by default?
    backgroundColor: ['#022f2c', '#479791'],

    // Font to use for compass text
    compassFont: 'Century Gothic',

    // Color to draw lines, should this be foreground color?
    lineColor: '#006363',

    // Color of drop shadow
    shadowColor: '#1d7373',

    // Color of subscripts
    subColor: '#888',

    // Font to use for subscripts
    subFont: 'Century Gothic',

    // Color of main text
    textColor: '#099',

    // Font to use for main text
    textFont: 'Century Gothic',

    width: 400
  }

  componentDidMount() {
    const gauge = this.renderWindGauge("WindGauge", this.props.value);

    this.setState({gauge: gauge});
  }

  componentWillReceiveProps(nextProps) {
    if(nextProps.width !== this.props.width) {
      const gauge = this.renderWindGauge("WindGauge", this.props.value);
      this.setState({gauge: gauge});
    } else if(this.state !== null) {
      this.state.gauge.update(this.props.value);
    }
  }

  render() {
    return <div / >;
  }

  renderWindGauge(elementId, value) {
    function deg2rad(deg) {
      return deg / 180 * Math.PI;
    }

    let el = React.findDOMNode(this);

    let {width, height, background, lineColor, textColor} = this.props;

    while (el.firstChild) {
      el.removeChild(el.firstChild);
    }

    let svg = d3.select(el).append("svg")
      .attr("width", width)
      .attr("height", height);

    svg.append("rect")
      .attr("width", width)
      .attr("height", height)
      .style("fill", "#333");

    let divider = [{x: 0.6 * width, y: 0 * height / 3},
                   {x: 0.7 * width, y: 1 * height / 3},
                   {x: 0.7 * width, y: 2 * height / 3},
                   {x: 0.6 * width, y: 3 * height / 3}];

    let line2 = [{x: 0.7 * width, y: 1 * height / 3},
                 {x: 1.0 * width, y: 1 * height / 3}];

    let line3 = [{x: 0.7 * width, y: 2 * height / 3},
                 {x: 1.0 * width, y: 2 * height / 3}];

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

    svg.append("path")
      .attr("d", lineFunction(divider))
      .attr("stroke", lineColor)
      .attr("stroke-width", 4)
      .attr("fill", "none");

    svg.append("path")
      .attr("d", lineFunction(line2))
      .attr("stroke", lineColor)
      .attr("stroke-width", 4)
      .attr("fill", "none");

    svg.append("path")
      .attr("d", lineFunction(line3))
      .attr("stroke", lineColor)
      .attr("stroke-width", 4)
      .attr("fill", "none");

    const boxWidth = 0.35 * width,
          mBoxWidth = 0.30 * width,
          boxHeight=  height / 3,
          boxX = 0.65 * width,
          mBoxX = 0.7 * width;

    drawDataBox(boxX,  0 * height / 3, boxWidth,  boxHeight, 123, 123, "KTS", "BSPD");
    drawDataBox(mBoxX, 1 * height / 3, mBoxWidth, boxHeight, 123, 123, "\u00B0", "AWA");
    drawDataBox(boxX,  2 * height / 3, boxWidth,  boxHeight, 123, 123, "KTS", "AWS");

    drawCircle(45);

    function drawDataBox(x, y, w, h, val, tgt, units, measure) {
      const valSize = 75,
            subSize = 24,
            unitSize = units === '\u00B0' ? 48 : 24,
            padding = 20;

      let unitText = svg.append("text")
        .attr("x", x + w - 2 * padding)
        .attr("y", y + padding + 2 * subSize)
        .attr("font-family", "Century Gothic")
        .attr("text-anchor", "end")
        .attr("fill", textColor)
        .attr("font-size", unitSize)
        .text(units);

      let w1 = unitText.node().getBBox().width;

      let valueText = svg.append("text")
        .attr("x", x + w - w1 - 2 * padding)
        .attr("y", y + padding + valSize)
        .attr("text-anchor", "end")
        .attr("fill", textColor)
        .attr("font-size", valSize)
        .text(val);

      let subText = svg.append("text")
        .attr("x", 0)
        .attr("y", y + h / 2)
        .attr("font-size", subSize)
        .attr("fill", textColor)
        .attr("text-anchor", "middle")
        .attr("transform", "translate(0," + measure.length * -10 + ")")
        .selectAll("tspan")
          .data(measure.split(''))
          .enter().append("tspan")
            .attr("x", x + w - padding)
            .attr("dy", "0.8em")
            .text(function(d) { return d});

      let tgtText = svg.append("text")
        .attr("x", x + w - 2 * padding)
        .attr("y", y + h - padding / 2)
        .attr("fill", textColor)
        .attr("text-anchor", "end")
        .text(tgt);

      let w2 = tgtText.node().getBBox().width;

      let tgtLbl = svg.append("text")
        .attr("x", x + w - w2 - 25 - 2 * padding)
        .attr("y", y + h - padding / 2)
        .attr("fill", textColor)
        .attr("text-anchor", "end")
        .text("Target:");

      if(tgt >= val) {
        triangle(x + w - w2 - 20 - 2 * padding, y + h - padding / 2, 18, 18, 'up');
      } else {
        triangle(x + w - w2 - 20 - 2 * padding, y + h - padding / 2, 18, 18, 'dn');
      }
    }

    function triangle(x, y, w, h, dir) {
      var tx, ty, rx;
      tx = x + w / 2;
      if(dir == 'up') {
        ty = y - h;
      } else {
        ty = y;
        y -= h;
      }
      rx = x + w;

      var tPoints = [{x:tx, y:ty}, {x:x, y:y}, {x:rx, y:y}];

      svg.append("path")
        .attr("d", lineFunction(tPoints) + "Z")
        .attr("fill", textColor);

    }

    function drawCircle(heading, targetHeading, trueWindAngle, apparentWindAngle) {
      const originX = width / 3,
            originY = height / 2,
            radius  = Math.min(originX, originY) - 35;

      const g = svg.append("g")
        .attr("transform", "translate(" + originX + "," + originY + ") rotate(" + heading  + ")");

      g.append("circle")
        .attr("r", radius)
        .attr("stroke", lineColor)
        .attr("stroke-width", 4)
        .attr("fill", "none");

      for(let i = 0; i < 64; i++) {
        let tickLength = 10;
        let tickWidth = 1;

        if(i % 16 == 0) {
          tickLength = 30;
        } else if(i % 8 == 0) {
          tickLength = 25;
        } else if(i % 4 == 0) {
          tickLength = 20;
          tickWidth = 2;
        } else if(i % 2 == 0) {
          tickLength = 15;
        }

        let tickAngle = i * Math.PI / 32;

        const tickPath = [
          {x: -Math.cos(tickAngle) * radius,
           y: -Math.sin(tickAngle) * radius},
          {x: -Math.cos(tickAngle) * (radius - tickLength),
           y: -Math.sin(tickAngle) * (radius - tickLength)}
        ];

        g.append("path")
          .attr("d", lineFunction(tickPath))
          .attr("stroke", lineColor)
          .attr("stroke-width", tickWidth)
          .attr("fill", "none");
      }

      g.append("text").text("N")
        .attr("fill", lineColor)
        .attr("font-size", "20pt")
        .attr("text-anchor", "middle")
        .attr("transform", "translate(0," + -(radius + 5) + ")");

      g.append("text").text("S")
        .attr("fill", lineColor)
        .attr("font-size", "20pt")
        .attr("text-anchor", "middle")
        .attr("transform", "translate(0," + (radius + 5) + ") rotate(180)");

      let east = g.append("text").text("E")
        .attr("fill", lineColor)
        .attr("font-size", "20pt")
        .attr("text-anchor", "middle")
        .attr("transform", "translate(" + (radius + 5) + ",0) rotate(90)");

      g.append("text").text("W")
        .attr("fill", lineColor)
        .attr("font-size", "20pt")
        .attr("text-anchor", "middle")
        .attr("transform", "translate(" + -(radius + 5) + ",0) rotate(270)");
    }

    function GaugeUpdater() {
      this.update = function(value) {
      }
    }

    return new GaugeUpdater();
  }
}
<|endoftext|>


<commit_before>const _ = require('lodash');
const redisClient = require('../../models/redis-client');
const tracking = require('../tracking');
const redis = require('./redis-ads');
const inMemory = require('./in-memory-ads');

const selection = [
  {
    title: 'Ad | Oculus Quest All-in-one VR Gaming Headset',
    link: 'https://amzn.to/2J9POCH',
    content:
      ' Oculus Quest is an all-in-one gaming system for virtual reality. No wires. No PC. Just set up with the Oculus mobile app, and you\'re free to explore VR from almost anywhere. Sensors inside the headset precisely track your movements and instantly translate them into VR, while helping you steer clear of nearby objects. And with Oculus Touch controllers, your hands are in the game, so you can see your every gesture and feel the power of every impact. Take VR gaming to the next level. And everywhere else. Setup requires an iPhone(iOS 10 or higher) or Android(6.0 Marshmallow or higher) smartphone, the Oculus App (free download), 802.11 b/g/n wireless Internet access, and an Oculus account.',
    contentSnippet:
      "Oculus Quest is an all-in-one gaming system for virtual reality. No wires. No PC. Just set up with the Oculus mobile app, and you're free to explore VR from almost anywhere. Sensors inside the headset precisely track your movements and instantly translate them into VR, while helping you steer clear of nearby objects. And with Oculus Touch controllers, your hands are in the game, so you can see your every gesture and feel the power of every impact. Take VR gaming to the next level. And everywhere else. Setup requires an iPhone(iOS 10 or higher) or Android(6.0 Marshmallow or higher) smartphone, the Oculus App (free download), 802.11 b/g/n wireless Internet access, and an Oculus account.",
    publishedDate: '2019-09-11T12:00:00.000Z',
    categories: [],
    author: 'Oculus'
  },
  {
    title:
      'Ad | All-new Echo (3rd Gen) - Smart speaker with Alexa - Twilight Blue',
    link: 'https://amzn.to/2ntWMu4',
    content:
      ' Meet Echo - Echo (3rd Gen) has new premium speakers powered by Dolby to play 360° audio with crisp vocals and dynamic bass response.',
    contentSnippet:
      'Meet Echo - Echo (3rd Gen) has new premium speakers powered by Dolby to play 360° audio with crisp vocals and dynamic bass response.',
    publishedDate: '2019-09-11T12:00:00.000Z',
    categories: [],
    author: 'Amazon'
  },
  {
    title: 'Ad | PlayStation 4 Pro 1TB Console',
    link: 'https://amzn.to/2BdNhmo',
    content:
      ' The most advanced PlayStation system ever. PS4 Pro is designed to take your favorite PS4 games and add to them with more power for graphics, performance, or features for your 4K HDR TV, or 1080p HD TV. Ready to level up?',
    contentSnippet:
      'The most advanced PlayStation system ever. PS4 Pro is designed to take your favorite PS4 games and add to them with more power for graphics, performance, or features for your 4K HDR TV, or 1080p HD TV. Ready to level up?    ',
    publishedDate: '2019-09-11T12:00:00.000Z',
    categories: [],
    author: 'Sony'
  }
];
const getAd = function () {
  return _.sample(selection);
};

const shouldShowAd = async function (req) {
  const client = redisClient.getClient();
  const adsTracker = client ? redis : inMemory;

  if (req.query.support) {
    adsTracker.trackSupportRequest();

    if (await adsTracker.aboveThreshold()) {
      await adsTracker.reset();

      return true;
    }
  }

  return false;
};

const addAds = async function (req, response) {
  if (await shouldShowAd(req)) {
    if (req.query.callback) {
      // eslint-disable-next-line no-param-reassign
      response = response.match(
        new RegExp(`${req.query.callback}\\((.*)\\)`)
      )[1];
    }

    const data = JSON.parse(response);
    const ad = getAd();

    data.responseData.feed.entries.pop();
    data.responseData.feed.entries.unshift(ad);
    // eslint-disable-next-line no-param-reassign
    response = JSON.stringify(data);

    if (req.query.callback) {
      // eslint-disable-next-line no-param-reassign
      response = `${req.query.callback}(${response});`;
    }

    tracking.trackToday('ad:served');

    // eslint-disable-next-line no-console
    console.log(`Embedded ad: ${JSON.stringify(ad)}`);
  }

  return response;
};

module.exports = {
  getAd,
  shouldShowAd,
  addAds
};
<commit_msg>Disable ads<commit_after>const _ = require('lodash');
// const redisClient = require('../../models/redis-client');
const tracking = require('../tracking');
// const redis = require('./redis-ads');
// const inMemory = require('./in-memory-ads');

const selection = [
  {
    title: 'Ad | Oculus Quest All-in-one VR Gaming Headset',
    link: 'https://amzn.to/2J9POCH',
    content:
      ' Oculus Quest is an all-in-one gaming system for virtual reality. No wires. No PC. Just set up with the Oculus mobile app, and you\'re free to explore VR from almost anywhere. Sensors inside the headset precisely track your movements and instantly translate them into VR, while helping you steer clear of nearby objects. And with Oculus Touch controllers, your hands are in the game, so you can see your every gesture and feel the power of every impact. Take VR gaming to the next level. And everywhere else. Setup requires an iPhone(iOS 10 or higher) or Android(6.0 Marshmallow or higher) smartphone, the Oculus App (free download), 802.11 b/g/n wireless Internet access, and an Oculus account.',
    contentSnippet:
      "Oculus Quest is an all-in-one gaming system for virtual reality. No wires. No PC. Just set up with the Oculus mobile app, and you're free to explore VR from almost anywhere. Sensors inside the headset precisely track your movements and instantly translate them into VR, while helping you steer clear of nearby objects. And with Oculus Touch controllers, your hands are in the game, so you can see your every gesture and feel the power of every impact. Take VR gaming to the next level. And everywhere else. Setup requires an iPhone(iOS 10 or higher) or Android(6.0 Marshmallow or higher) smartphone, the Oculus App (free download), 802.11 b/g/n wireless Internet access, and an Oculus account.",
    publishedDate: '2019-09-11T12:00:00.000Z',
    categories: [],
    author: 'Oculus'
  },
  {
    title:
      'Ad | All-new Echo (3rd Gen) - Smart speaker with Alexa - Twilight Blue',
    link: 'https://amzn.to/2ntWMu4',
    content:
      ' Meet Echo - Echo (3rd Gen) has new premium speakers powered by Dolby to play 360° audio with crisp vocals and dynamic bass response.',
    contentSnippet:
      'Meet Echo - Echo (3rd Gen) has new premium speakers powered by Dolby to play 360° audio with crisp vocals and dynamic bass response.',
    publishedDate: '2019-09-11T12:00:00.000Z',
    categories: [],
    author: 'Amazon'
  },
  {
    title: 'Ad | PlayStation 4 Pro 1TB Console',
    link: 'https://amzn.to/2BdNhmo',
    content:
      ' The most advanced PlayStation system ever. PS4 Pro is designed to take your favorite PS4 games and add to them with more power for graphics, performance, or features for your 4K HDR TV, or 1080p HD TV. Ready to level up?',
    contentSnippet:
      'The most advanced PlayStation system ever. PS4 Pro is designed to take your favorite PS4 games and add to them with more power for graphics, performance, or features for your 4K HDR TV, or 1080p HD TV. Ready to level up?    ',
    publishedDate: '2019-09-11T12:00:00.000Z',
    categories: [],
    author: 'Sony'
  }
];
const getAd = function () {
  return _.sample(selection);
};

const shouldShowAd = async function (/* req */) {
  return false;

  // const client = redisClient.getClient();
  // const adsTracker = client ? redis : inMemory;

  // if (req.query.support) {
  //   adsTracker.trackSupportRequest();

  //   if (await adsTracker.aboveThreshold()) {
  //     await adsTracker.reset();

  //     return true;
  //   }
  // }

  // return false;
};

const addAds = async function (req, response) {
  if (await shouldShowAd(req)) {
    if (req.query.callback) {
      // eslint-disable-next-line no-param-reassign
      response = response.match(
        new RegExp(`${req.query.callback}\\((.*)\\)`)
      )[1];
    }

    const data = JSON.parse(response);
    const ad = getAd();

    data.responseData.feed.entries.pop();
    data.responseData.feed.entries.unshift(ad);
    // eslint-disable-next-line no-param-reassign
    response = JSON.stringify(data);

    if (req.query.callback) {
      // eslint-disable-next-line no-param-reassign
      response = `${req.query.callback}(${response});`;
    }

    tracking.trackToday('ad:served');

    // eslint-disable-next-line no-console
    console.log(`Embedded ad: ${JSON.stringify(ad)}`);
  }

  return response;
};

module.exports = {
  getAd,
  shouldShowAd,
  addAds
};
<|endoftext|>


<commit_before>'use strict';

const infuraIdsByTarget = {
  staging: '558ee533522a468e9d421d818e06fadb', // this infura id is specific to https://app-staging.stack.cards/
  production: '5d6efa6b750b45459184cd11dd2c8697', // this infura id is specific to https://app.cardstack.com/
};

const pkg = require('../package.json');

// eslint-disable-next-line no-undef
module.exports = function (environment) {
  let ENV = {
    modulePrefix: '@cardstack/web-client',
    environment,
    rootURL: '/',
    locationType: 'auto',
    hubURL: process.env.HUB_URL,
    version: pkg.version,
    sentryDsn: process.env.SENTRY_DSN,
    '@sentry/ember': {
      sentry: {
        dsn: process.env.SENTRY_DSN,
        // debug: true, // uncomment this to get helpful logs about sentry's behavior
        enabled: !!process.env.DEPLOY_TARGET,
        environment: process.env.DEPLOY_TARGET || 'development',
        release:
          `web-client${
            process.env.GITHUB_SHA ? `-${process.env.GITHUB_SHA}` : ''
          }@` + pkg.version,
        // Set tracesSampleRate to 1.0 to capture 100%
        // of transactions for performance monitoring.
        // We recommend adjusting this value in production,
        tracesSampleRate: 1.0,
      },
    },
    pageTitle: {
      separator: ' · ',
    },
    EmberENV: {
      FEATURES: {
        // Here you can enable experimental features on an ember canary build
        // e.g. EMBER_NATIVE_DECORATOR_SUPPORT: true
      },
      EXTEND_PROTOTYPES: {
        // Prevent Ember Data from overriding Date.parse.
        Date: false,
      },
    },

    APP: {
      // Here you can pass flags/options to your application instance
      // when it is created
    },
    chains: {
      layer1: process.env.LAYER_1_CHAIN || 'keth', // set to "eth" for production
      layer2: process.env.LAYER_2_CHAIN || 'sokol', // set to "xdai" for production,
    },
    features: {
      createMerchant: process.env.DEPLOY_TARGET !== 'production',
    },
    infuraId:
      infuraIdsByTarget[process.env.DEPLOY_TARGET] ?? process.env.INFURA_ID,
    urls: {
      appStoreLink: undefined,
      googlePlayStoreLink: undefined,
      testFlightLink: 'https://cardstack.com/cardpay',
      discordBetaChannelLink:
        'https://discord.com/channels/584043165066199050/867588838524190762',
    },
    threadAnimationInterval: 1000,
    'ember-cli-mirage': {
      enabled: false,
    },
  };

  if (environment === 'development') {
    // ENV.APP.LOG_RESOLVER = true;
    // ENV.APP.LOG_ACTIVE_GENERATION = true;
    // ENV.APP.LOG_TRANSITIONS = true;
    // ENV.APP.LOG_TRANSITIONS_INTERNAL = true;
    // ENV.APP.LOG_VIEW_LOOKUPS = true;
    ENV.hubURL = ENV.hubURL ?? 'http://localhost:3000';
    ENV.threadAnimationInterval =
      process.env.THREAD_ANIMATION_INTERVAL ?? ENV.threadAnimationInterval;
  }

  if (environment === 'test') {
    // Testem prefers this...
    ENV.locationType = 'none';
    ENV.chains.layer1 = 'test';
    ENV.chains.layer2 = 'test';

    // thread animation interval > 0 means we might have to wait for css animations in tests
    ENV.threadAnimationInterval = 0;

    // keep test console output quieter
    ENV.APP.LOG_ACTIVE_GENERATION = false;
    ENV.APP.LOG_VIEW_LOOKUPS = false;

    ENV.APP.rootElement = '#ember-testing';
    ENV.APP.autoboot = false;

    // mock server during test
    ENV.hubURL = '';
    ENV['ember-cli-mirage'] = {
      enabled: true,
      trackRequests: true,
    };
  }

  if (environment === 'production') {
    // here you can enable a production-specific feature
  }

  return ENV;
};
<commit_msg>web: Add merchant creation on production (#2055)<commit_after>'use strict';

const infuraIdsByTarget = {
  staging: '558ee533522a468e9d421d818e06fadb', // this infura id is specific to https://app-staging.stack.cards/
  production: '5d6efa6b750b45459184cd11dd2c8697', // this infura id is specific to https://app.cardstack.com/
};

const pkg = require('../package.json');

// eslint-disable-next-line no-undef
module.exports = function (environment) {
  let ENV = {
    modulePrefix: '@cardstack/web-client',
    environment,
    rootURL: '/',
    locationType: 'auto',
    hubURL: process.env.HUB_URL,
    version: pkg.version,
    sentryDsn: process.env.SENTRY_DSN,
    '@sentry/ember': {
      sentry: {
        dsn: process.env.SENTRY_DSN,
        // debug: true, // uncomment this to get helpful logs about sentry's behavior
        enabled: !!process.env.DEPLOY_TARGET,
        environment: process.env.DEPLOY_TARGET || 'development',
        release:
          `web-client${
            process.env.GITHUB_SHA ? `-${process.env.GITHUB_SHA}` : ''
          }@` + pkg.version,
        // Set tracesSampleRate to 1.0 to capture 100%
        // of transactions for performance monitoring.
        // We recommend adjusting this value in production,
        tracesSampleRate: 1.0,
      },
    },
    pageTitle: {
      separator: ' · ',
    },
    EmberENV: {
      FEATURES: {
        // Here you can enable experimental features on an ember canary build
        // e.g. EMBER_NATIVE_DECORATOR_SUPPORT: true
      },
      EXTEND_PROTOTYPES: {
        // Prevent Ember Data from overriding Date.parse.
        Date: false,
      },
    },

    APP: {
      // Here you can pass flags/options to your application instance
      // when it is created
    },
    chains: {
      layer1: process.env.LAYER_1_CHAIN || 'keth', // set to "eth" for production
      layer2: process.env.LAYER_2_CHAIN || 'sokol', // set to "xdai" for production,
    },
    features: {
      createMerchant: true,
    },
    infuraId:
      infuraIdsByTarget[process.env.DEPLOY_TARGET] ?? process.env.INFURA_ID,
    urls: {
      appStoreLink: undefined,
      googlePlayStoreLink: undefined,
      testFlightLink: 'https://cardstack.com/cardpay',
      discordBetaChannelLink:
        'https://discord.com/channels/584043165066199050/867588838524190762',
    },
    threadAnimationInterval: 1000,
    'ember-cli-mirage': {
      enabled: false,
    },
  };

  if (environment === 'development') {
    // ENV.APP.LOG_RESOLVER = true;
    // ENV.APP.LOG_ACTIVE_GENERATION = true;
    // ENV.APP.LOG_TRANSITIONS = true;
    // ENV.APP.LOG_TRANSITIONS_INTERNAL = true;
    // ENV.APP.LOG_VIEW_LOOKUPS = true;
    ENV.hubURL = ENV.hubURL ?? 'http://localhost:3000';
    ENV.threadAnimationInterval =
      process.env.THREAD_ANIMATION_INTERVAL ?? ENV.threadAnimationInterval;
  }

  if (environment === 'test') {
    // Testem prefers this...
    ENV.locationType = 'none';
    ENV.chains.layer1 = 'test';
    ENV.chains.layer2 = 'test';

    // thread animation interval > 0 means we might have to wait for css animations in tests
    ENV.threadAnimationInterval = 0;

    // keep test console output quieter
    ENV.APP.LOG_ACTIVE_GENERATION = false;
    ENV.APP.LOG_VIEW_LOOKUPS = false;

    ENV.APP.rootElement = '#ember-testing';
    ENV.APP.autoboot = false;

    // mock server during test
    ENV.hubURL = '';
    ENV['ember-cli-mirage'] = {
      enabled: true,
      trackRequests: true,
    };
  }

  if (environment === 'production') {
    // here you can enable a production-specific feature
  }

  return ENV;
};
<|endoftext|>


<commit_before>//  Increases the size of the Rectangle object by the specified amounts.
//  The center point of the Rectangle object stays the same, and its size increases
//  to the left and right by the x value, and to the top and the bottom by the y value.

var Inflate = function (rect, x, y)
{
    //  Get the current center
    var cx = rect.x + (rect.width / 2);
    var cy = rect.y + (rect.height / 2);

    //  Inflate
    rect.width = 2 * x;
    rect.height = 2 * y;

    rect.x = x - (rect.width / 2);
    rect.y = y - (rect.height / 2);

    return rect;
};

module.exports = Inflate;
<commit_msg>Fixed Rectangle inflate. Now deflates with negative values too.<commit_after>var CenterOn = require('./CenterOn');

//  Increases the size of the Rectangle object by the specified amounts.
//  The center point of the Rectangle object stays the same, and its size increases
//  to the left and right by the x value, and to the top and the bottom by the y value.

var Inflate = function (rect, x, y)
{
    var cx = rect.centerX;
    var cy = rect.centerY;

    rect.setSize(rect.width + (x * 2), rect.height + (y * 2));

    return CenterOn(rect, cx, cy);
};

module.exports = Inflate;
<|endoftext|>


<commit_before>/*
 **************************************************
 *  Bungee.js
 *
 *  (c) 2012-2013 Johannes Zellner
 *
 *  Bungee may be freely distributed under the MIT license.
 *  For all details and documentation:
 *  http://bungeejs.org
 **************************************************
 */

"use strict";

/*
 **************************************************
 * Animation
 **************************************************
 */

var Bungee = require('./engine.js');

Bungee._animationIndex = 0;
Bungee._debugAnimation = false;

/*
 **************************************************
 * Basic Animation
 **************************************************
 */
Bungee.Step = function (engine, id, parent) {
    var elem = new Bungee.Element(engine, id, parent, "object");

    elem.addProperty("percentage", 0);

    return elem;
};

Bungee.Animation = function (engine, id, parent) {
    var elem = new Bungee.Element(engine, id, parent, "object");
    var index = Bungee._animationIndex++;
    var dirty = true;
    var hasRules = false;
    var animationName = "bungeeAnimation" + index;
    var keyFramesName = "bungeeAnimationKeyFrames" + index;

    elem.addProperty("target", function () { return this.parent; });
    elem.addProperty("duration", 250);
    elem.addProperty("delay", 0);
    elem.addProperty("loops", 1);
    elem.addProperty("reverse", false);
    elem.addProperty("easing", "ease");

    function animationStart(event) {
        Bungee._debugAnimation && console.log("start", event);
        elem.emit("started");
    }

    function animationIteration(event) {
        Bungee._debugAnimation && console.log("iteration", event);
    }

    function animationEnd(event) {
        Bungee._debugAnimation && console.log("end", event);
        elem.stop();
        elem.emit("finished");
    }

    function updateRules() {
        var rule1 = "";
        var rule2 = "";
        var rule3 = "";
        var rule4 = "";

        if (!Bungee._style) {
            Bungee._style = document.createElement('style');
            document.getElementsByTagName('head')[0].appendChild(Bungee._style);
        }

        if (hasRules) {
            var tmpName = "." + animationName;
            var i;

            // remove key frames rule
            for (i = 0; i < Bungee._style.sheet.cssRules.length; ++i) {
                if (Bungee._style.sheet.cssRules[i].name === keyFramesName) {
                    Bungee._style.sheet.deleteRule(i);
                    break;
                }
            }

            // remove animation rule
            for (i = 0; i < Bungee._style.sheet.cssRules.length; ++i) {
                if (Bungee._style.sheet.cssRules[i].selectorText === tmpName) {
                    Bungee._style.sheet.deleteRule(i);
                    break;
                }
            }
        }

        rule1 += "." + animationName + " {\n";
        rule1 += "   animation: ";
        rule1 += keyFramesName + " ";
        rule1 += elem.duration + "ms ";
        rule1 += elem.easing + " ";
        rule1 += elem.delay + " ";
        rule1 += elem.loops + " ";
        rule1 += (elem.reverse ? "alternate" : "normal") + ";\n";
        rule1 += "   -webkit-animation: ";
        rule1 += keyFramesName + " ";
        rule1 += elem.duration + "ms ";
        rule1 += elem.easing + " ";
        rule1 += elem.delay + " ";
        rule1 += elem.loops + " ";
        rule1 += (elem.reverse ? "alternate" : "normal") + ";\n";
        rule1 += "}\n";

        rule2 += "@keyframes " + keyFramesName + " { \n";
        rule3 += "@-webkit-keyframes " + keyFramesName + " { \n";
        for (var j in elem.children()) {
            var child = elem.children()[j];

            if (typeof child.percentage === 'undefined') {
                continue;
            }

            rule2 += "   " + child.percentage + "% {\n";
            rule3 += "   " + child.percentage + "% {\n";

            for (var property in child._properties) {
                if (child.hasOwnProperty(property) && property !== 'percentage') {
                    rule2 += "      " + property + ": " + child[property] + ";\n";
                    rule3 += "      " + property + ": " + child[property] + ";\n";
                }
            }

            rule2 += "   }\n";
            rule3 += "   }\n";
        }
        rule2 += "}\n";
        rule3 += "}\n";

        Bungee._debugAnimation && console.log("Bungee Animation rules:\n", rule2, rule3, rule1);

        try {
            Bungee._style.sheet.insertRule(rule3, Bungee._style.sheet.rules.length);
        } catch (e) {
            Bungee._debugAnimation && console.error("Bungee Animation rule", rule3, "could not be inserted.", e);
        }

        try {
            Bungee._style.sheet.insertRule(rule2, Bungee._style.sheet.rules.length);
        } catch (e) {
            Bungee._debugAnimation && console.error("Bungee Animation rule", rule2, "could not be inserted.", e);
        }

        try {
            Bungee._style.sheet.insertRule(rule1, Bungee._style.sheet.rules.length);
        } catch (e) {
            Bungee._debugAnimation && console.error("Bungee Animation rule", rule1, "could not be inserted.", e);
        }

        hasRules = true;
    }

    function addEventListeners() {
        elem._element = elem.target;
        if (elem._element && elem._element.element) {
            elem._element.element.addEventListener("webkitAnimationStart", animationStart, false);
            elem._element.element.addEventListener("webkitAnimationIteration", animationIteration, false);
            elem._element.element.addEventListener("webkitAnimationEnd", animationEnd, false);
        }
    }

    function markDirty() {
        dirty = true;
    }

    elem.addChanged("target", addEventListeners);
    elem.addChanged("changed", markDirty);

    elem.start = function () {
        if (dirty) {
            updateRules();
            dirty = false;
        }

        if (elem._element)
            elem._element.className = animationName;
    };

    elem.stop = function () {
        elem._element.className = "";
    };

    elem.restart = function () {
        elem.stop();
        elem.start();
    };

    return elem;
};

Bungee.Behavior = function (engine, id, parent) {
    var elem = new Bungee.Element(engine, id, parent, "object");
    var index = Bungee._animationIndex++;
    var hasRules = false;
    var animationName = "bungeeAnimation" + index;

    elem.addProperty("target", function () { return this.parent; });

    function animationStart(event) {
        Bungee._debugAnimation && console.log("start", event);
        elem.emit("started");
    }

    function animationIteration(event) {
        Bungee._debugAnimation && console.log("iteration", event);
    }

    function animationEnd(event) {
        Bungee._debugAnimation && console.log("end", event);
        elem.stop();
        elem.emit("finished");
    }

    function updateRules() {
        var rule = "";
        var rule = "";
        var gotProperties = false;

        if (!Bungee._style) {
            Bungee._style = document.createElement('style');
            document.getElementsByTagName('head')[0].appendChild(Bungee._style);
        }

        if (hasRules) {
            var tmpName = "." + animationName;
            var i;

            // remove animation rule
            for (i = 0; i < Bungee._style.sheet.cssRules.length; ++i) {
                if (Bungee._style.sheet.cssRules[i].selectorText === tmpName) {
                    Bungee._style.sheet.deleteRule(i);
                    break;
                }
            }
        }

        // nothing to do when we got no properties
        if (elem._properties.length === 0) {
            return;
        }

        // create shared parts of the css
        for (var property in elem._properties) {
            if (elem.hasOwnProperty(property) && property !== 'target') {
                if (gotProperties) {
                    rule += ", ";
                } else {
                    gotProperties = true;
                }

                rule += property + " " + elem[property];
            }
        }

        // only actually insert rules if there is no property undefined
        if (gotProperties && rule.indexOf('undefined') === -1) {
            Bungee._debugAnimation && console.log("Bungee Behavior rule", rule);

            elem.parent.element.style['transition'] = rule;
            elem.parent.element.style['-webkit-transition'] = rule;

            hasRules = true;
        }
    }

    function addEventListeners() {
        elem._element = elem.target;
        if (elem._element && elem._element.element) {
            elem._element.element.addEventListener("webkitAnimationStart", animationStart, false);
            elem._element.element.addEventListener("webkitAnimationIteration", animationIteration, false);
            elem._element.element.addEventListener("webkitAnimationEnd", animationEnd, false);
            elem._element.className = animationName;
        }
    }

    elem.addChanged("target", addEventListeners);
    elem.addChanged("changed", updateRules);

    return elem;
};
<commit_msg>Remove obsolete var<commit_after>/*
 **************************************************
 *  Bungee.js
 *
 *  (c) 2012-2013 Johannes Zellner
 *
 *  Bungee may be freely distributed under the MIT license.
 *  For all details and documentation:
 *  http://bungeejs.org
 **************************************************
 */

"use strict";

/*
 **************************************************
 * Animation
 **************************************************
 */

var Bungee = require('./engine.js');

Bungee._animationIndex = 0;
Bungee._debugAnimation = false;

/*
 **************************************************
 * Basic Animation
 **************************************************
 */
Bungee.Step = function (engine, id, parent) {
    var elem = new Bungee.Element(engine, id, parent, "object");

    elem.addProperty("percentage", 0);

    return elem;
};

Bungee.Animation = function (engine, id, parent) {
    var elem = new Bungee.Element(engine, id, parent, "object");
    var index = Bungee._animationIndex++;
    var dirty = true;
    var hasRules = false;
    var animationName = "bungeeAnimation" + index;
    var keyFramesName = "bungeeAnimationKeyFrames" + index;

    elem.addProperty("target", function () { return this.parent; });
    elem.addProperty("duration", 250);
    elem.addProperty("delay", 0);
    elem.addProperty("loops", 1);
    elem.addProperty("reverse", false);
    elem.addProperty("easing", "ease");

    function animationStart(event) {
        Bungee._debugAnimation && console.log("start", event);
        elem.emit("started");
    }

    function animationIteration(event) {
        Bungee._debugAnimation && console.log("iteration", event);
    }

    function animationEnd(event) {
        Bungee._debugAnimation && console.log("end", event);
        elem.stop();
        elem.emit("finished");
    }

    function updateRules() {
        var rule1 = "";
        var rule2 = "";
        var rule3 = "";
        var rule4 = "";

        if (!Bungee._style) {
            Bungee._style = document.createElement('style');
            document.getElementsByTagName('head')[0].appendChild(Bungee._style);
        }

        if (hasRules) {
            var tmpName = "." + animationName;
            var i;

            // remove key frames rule
            for (i = 0; i < Bungee._style.sheet.cssRules.length; ++i) {
                if (Bungee._style.sheet.cssRules[i].name === keyFramesName) {
                    Bungee._style.sheet.deleteRule(i);
                    break;
                }
            }

            // remove animation rule
            for (i = 0; i < Bungee._style.sheet.cssRules.length; ++i) {
                if (Bungee._style.sheet.cssRules[i].selectorText === tmpName) {
                    Bungee._style.sheet.deleteRule(i);
                    break;
                }
            }
        }

        rule1 += "." + animationName + " {\n";
        rule1 += "   animation: ";
        rule1 += keyFramesName + " ";
        rule1 += elem.duration + "ms ";
        rule1 += elem.easing + " ";
        rule1 += elem.delay + " ";
        rule1 += elem.loops + " ";
        rule1 += (elem.reverse ? "alternate" : "normal") + ";\n";
        rule1 += "   -webkit-animation: ";
        rule1 += keyFramesName + " ";
        rule1 += elem.duration + "ms ";
        rule1 += elem.easing + " ";
        rule1 += elem.delay + " ";
        rule1 += elem.loops + " ";
        rule1 += (elem.reverse ? "alternate" : "normal") + ";\n";
        rule1 += "}\n";

        rule2 += "@keyframes " + keyFramesName + " { \n";
        rule3 += "@-webkit-keyframes " + keyFramesName + " { \n";
        for (var j in elem.children()) {
            var child = elem.children()[j];

            if (typeof child.percentage === 'undefined') {
                continue;
            }

            rule2 += "   " + child.percentage + "% {\n";
            rule3 += "   " + child.percentage + "% {\n";

            for (var property in child._properties) {
                if (child.hasOwnProperty(property) && property !== 'percentage') {
                    rule2 += "      " + property + ": " + child[property] + ";\n";
                    rule3 += "      " + property + ": " + child[property] + ";\n";
                }
            }

            rule2 += "   }\n";
            rule3 += "   }\n";
        }
        rule2 += "}\n";
        rule3 += "}\n";

        Bungee._debugAnimation && console.log("Bungee Animation rules:\n", rule2, rule3, rule1);

        try {
            Bungee._style.sheet.insertRule(rule3, Bungee._style.sheet.rules.length);
        } catch (e) {
            Bungee._debugAnimation && console.error("Bungee Animation rule", rule3, "could not be inserted.", e);
        }

        try {
            Bungee._style.sheet.insertRule(rule2, Bungee._style.sheet.rules.length);
        } catch (e) {
            Bungee._debugAnimation && console.error("Bungee Animation rule", rule2, "could not be inserted.", e);
        }

        try {
            Bungee._style.sheet.insertRule(rule1, Bungee._style.sheet.rules.length);
        } catch (e) {
            Bungee._debugAnimation && console.error("Bungee Animation rule", rule1, "could not be inserted.", e);
        }

        hasRules = true;
    }

    function addEventListeners() {
        elem._element = elem.target;
        if (elem._element && elem._element.element) {
            elem._element.element.addEventListener("webkitAnimationStart", animationStart, false);
            elem._element.element.addEventListener("webkitAnimationIteration", animationIteration, false);
            elem._element.element.addEventListener("webkitAnimationEnd", animationEnd, false);
        }
    }

    function markDirty() {
        dirty = true;
    }

    elem.addChanged("target", addEventListeners);
    elem.addChanged("changed", markDirty);

    elem.start = function () {
        if (dirty) {
            updateRules();
            dirty = false;
        }

        if (elem._element)
            elem._element.className = animationName;
    };

    elem.stop = function () {
        elem._element.className = "";
    };

    elem.restart = function () {
        elem.stop();
        elem.start();
    };

    return elem;
};

Bungee.Behavior = function (engine, id, parent) {
    var elem = new Bungee.Element(engine, id, parent, "object");
    var index = Bungee._animationIndex++;
    var hasRules = false;
    var animationName = "bungeeAnimation" + index;

    elem.addProperty("target", function () { return this.parent; });

    function animationStart(event) {
        Bungee._debugAnimation && console.log("start", event);
        elem.emit("started");
    }

    function animationIteration(event) {
        Bungee._debugAnimation && console.log("iteration", event);
    }

    function animationEnd(event) {
        Bungee._debugAnimation && console.log("end", event);
        elem.stop();
        elem.emit("finished");
    }

    function updateRules() {
        var rule = "";
        var gotProperties = false;

        if (!Bungee._style) {
            Bungee._style = document.createElement('style');
            document.getElementsByTagName('head')[0].appendChild(Bungee._style);
        }

        if (hasRules) {
            var tmpName = "." + animationName;
            var i;

            // remove animation rule
            for (i = 0; i < Bungee._style.sheet.cssRules.length; ++i) {
                if (Bungee._style.sheet.cssRules[i].selectorText === tmpName) {
                    Bungee._style.sheet.deleteRule(i);
                    break;
                }
            }
        }

        // nothing to do when we got no properties
        if (elem._properties.length === 0) {
            return;
        }

        // create shared parts of the css
        for (var property in elem._properties) {
            if (elem.hasOwnProperty(property) && property !== 'target') {
                if (gotProperties) {
                    rule += ", ";
                } else {
                    gotProperties = true;
                }

                rule += property + " " + elem[property];
            }
        }

        // only actually insert rules if there is no property undefined
        if (gotProperties && rule.indexOf('undefined') === -1) {
            Bungee._debugAnimation && console.log("Bungee Behavior rule", rule);

            elem.parent.element.style['transition'] = rule;
            elem.parent.element.style['-webkit-transition'] = rule;

            hasRules = true;
        }
    }

    function addEventListeners() {
        elem._element = elem.target;
        if (elem._element && elem._element.element) {
            elem._element.element.addEventListener("webkitAnimationStart", animationStart, false);
            elem._element.element.addEventListener("webkitAnimationIteration", animationIteration, false);
            elem._element.element.addEventListener("webkitAnimationEnd", animationEnd, false);
            elem._element.className = animationName;
        }
    }

    elem.addChanged("target", addEventListeners);
    elem.addChanged("changed", updateRules);

    return elem;
};
<|endoftext|>