<commit_before>function Timeline($element) {

  var _this = this;
  var _$element = $element;
  var _$content = $element.querySelector('.content');
  var _$clearTimeline = $element.querySelector('#cleartimeline');
  var _$autoscroll = $element.querySelector('#autoscroll');
  var _autoscroll = true;
  Timeline.ITEM_TYPES = {
    RECEIVED_EVENT: 'received event',
    RECEIVED_RESPONSE: 'received response',
    SEND_EVENT: 'send event',
    SUCCESS: 'connection success',
    INFO: 'connection info',
    WARNING: 'connection warning',
    ERROR: 'connection error'
  };

  this.receivedEvent = function(type,data) {
    this.addItem(Timeline.ITEM_TYPES.RECEIVED_EVENT,type,data);
  };
  this.receivedResponse = function(response) {
    this.addItem(Timeline.ITEM_TYPES.RECEIVED_RESPONSE,'Response',response);
  };
  this.sendEvent = function(type,data) {
    this.addItem(Timeline.ITEM_TYPES.SEND_EVENT,type,data);
  };
  this.addSuccess = function(header,body) {
    this.addItem(Timeline.ITEM_TYPES.SUCCESS,header,body,body);
  };
  this.addInfo = function(header,body) {
    this.addItem(Timeline.ITEM_TYPES.INFO,header,body,body);
  };
  this.addWarning = function(header,body) {
    this.addItem(Timeline.ITEM_TYPES.WARNING,header,body,body);
  };
  this.addError = function(header,body) {
    this.addItem(Timeline.ITEM_TYPES.ERROR,header,body,body);
  };

  // ToDo: add parsing failed indicator
  this.addItem = function(type,header,body) {
    console.log('addItem: ',arguments);

    var rawBody = body;
    if(typeof body == 'object') {
      rawBody = JSON.stringify(body, undefined, 2);
      body = YAML.stringify(body,2);
    }

    var $row = document.createElement("div");
    $row.setAttribute("class",'row ');

    var $item = document.createElement("div");
    $item.setAttribute("class",type+' item columns');
    $row.appendChild($item);

    var $header = document.createElement("div");
    $header.setAttribute("class",'header small-12 medium-3 columns');
    $header.textContent = header;
    $item.appendChild($header);

    if(body) {
      var $body = document.createElement("pre");
      $body.setAttribute("class",'body small-12 medium-9 columns');
      $body.textContent = body;
      $item.appendChild($body);
    }
    if(rawBody) {
      var $rawBody = document.createElement("pre");
      $rawBody.setAttribute("class",'rawbody small-12 medium-9 columns');
      $rawBody.textContent = rawBody;
      $item.appendChild($rawBody);
    }
    _$content.appendChild($row);
    fadeIn($item);
    if(_autoscroll) {
      _$content.scrollTop = _$content.scrollHeight;
    }
  };

  this.clear = function() {
    while (_$content.firstChild) {
      _$content.removeChild(_$content.firstChild);
    }
  };
  function fadeIn($element) {
    // Make the element fully transparent.
    $element.style.opacity = 0;
    // Make sure the initial state is applied.
    window.getComputedStyle($element).opacity;
    // Fade it in.
    $element.style.opacity = 1;
  }
  _$clearTimeline.onclick = function() {
    _this.clear();
  };
  _$autoscroll.onclick = function() {
    _autoscroll = !_autoscroll;
    this.classList.toggle('disabled');
  };
}<commit_msg>Improved incoming json2yaml parsing<commit_after>function Timeline($element) {

  var _this = this;
  var _$element = $element;
  var _$content = $element.querySelector('.content');
  var _$clearTimeline = $element.querySelector('#cleartimeline');
  var _$autoscroll = $element.querySelector('#autoscroll');
  var _autoscroll = true;
  Timeline.ITEM_TYPES = {
    RECEIVED_EVENT: 'received event',
    RECEIVED_RESPONSE: 'received response',
    SEND_EVENT: 'send event',
    SUCCESS: 'connection success',
    INFO: 'connection info',
    WARNING: 'connection warning',
    ERROR: 'connection error'
  };

  this.receivedEvent = function(type,data) {
    this.addItem(Timeline.ITEM_TYPES.RECEIVED_EVENT,type,data);
  };
  this.receivedResponse = function(response) {
    this.addItem(Timeline.ITEM_TYPES.RECEIVED_RESPONSE,'Response',response);
  };
  this.sendEvent = function(type,data) {
    this.addItem(Timeline.ITEM_TYPES.SEND_EVENT,type,data);
  };
  this.addSuccess = function(header,body) {
    this.addItem(Timeline.ITEM_TYPES.SUCCESS,header,body,body);
  };
  this.addInfo = function(header,body) {
    this.addItem(Timeline.ITEM_TYPES.INFO,header,body,body);
  };
  this.addWarning = function(header,body) {
    this.addItem(Timeline.ITEM_TYPES.WARNING,header,body,body);
  };
  this.addError = function(header,body) {
    this.addItem(Timeline.ITEM_TYPES.ERROR,header,body,body);
  };

  // ToDo: add parsing failed indicator
  this.addItem = function(type,header,body) {
    console.log('addItem: ',arguments);

    var rawBody = body;
    if(typeof body == 'object') {
      rawBody = JSON.stringify(body, undefined, 2);
      body = YAML.stringify(body,5,2);
    }

    var $row = document.createElement("div");
    $row.setAttribute("class",'row ');

    var $item = document.createElement("div");
    $item.setAttribute("class",type+' item columns');
    $row.appendChild($item);

    var $header = document.createElement("div");
    $header.setAttribute("class",'header small-12 medium-3 columns');
    $header.textContent = header;
    $item.appendChild($header);

    if(body) {
      var $body = document.createElement("pre");
      $body.setAttribute("class",'body small-12 medium-9 columns');
      $body.textContent = body;
      $item.appendChild($body);
    }
    if(rawBody) {
      var $rawBody = document.createElement("pre");
      $rawBody.setAttribute("class",'rawbody small-12 medium-9 columns');
      $rawBody.textContent = rawBody;
      $item.appendChild($rawBody);
    }
    _$content.appendChild($row);
    fadeIn($item);
    if(_autoscroll) {
      _$content.scrollTop = _$content.scrollHeight;
    }
  };

  this.clear = function() {
    while (_$content.firstChild) {
      _$content.removeChild(_$content.firstChild);
    }
  };
  function fadeIn($element) {
    // Make the element fully transparent.
    $element.style.opacity = 0;
    // Make sure the initial state is applied.
    window.getComputedStyle($element).opacity;
    // Fade it in.
    $element.style.opacity = 1;
  }
  _$clearTimeline.onclick = function() {
    _this.clear();
  };
  _$autoscroll.onclick = function() {
    _autoscroll = !_autoscroll;
    this.classList.toggle('disabled');
  };
}<|endoftext|>


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

var cli = require('../testcli/runner.js');

function newSuite(path, include) {
	var suite = new cli.TestSuite("date/test/" + path);
	suite.include("test/testUtils.js");
	return suite;
};

function suite() {
    var s = new cli.TestSuite();

    var suites = [
		"testdatefmt_ga_IE.js",
		"testdatefmt_gu_IN.js",
		"testdatefmt_he_IL.js",
		"testdatefmt_hi_IN.js",
		"testdatefmt_hr_HR.js",
		"testdatefmt_id_ID.js",
		"testdatefmt_it_IT.js",
		"testdatefmt_ja_JP.js",
		"testdatefmt.js",
		"testdatefmt_kk_Cyrl_KZ.js",
		"testdatefmt_kn_IN.js",
		"testdatefmt_ko_KR.js",
		//"testdatefmt_ku_Arab_IQ.js",
		"testdatefmt_lt_LT.js",
		"testdatefmt_lv_LV.js",
		"testdatefmt_mk_MK.js",
		"testdatefmt_mn_Cyrl_MN.js",
		"testdatefmt_ml_IN.js",
		"testdatefmt_mr_IN.js",
		"testdatefmt_ms_MY.js",
		"testdatefmt_nb_NO.js",
		"testdatefmt_nl_NL.js"
	];

    suites.forEach(function (path) {
    	s.addSuite(newSuite(path));
    });

    return s;
}

<commit_msg>Committing Oriya data and time test cases<commit_after>/*
 * testSuiteDates.js - test suite for the date tests
 *
 * Copyright © 2014, JEDLSoft
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var cli = require('../testcli/runner.js');

function newSuite(path, include) {
	var suite = new cli.TestSuite("date/test/" + path);
	suite.include("test/testUtils.js");
	return suite;
};

function suite() {
    var s = new cli.TestSuite();

    var suites = [
		"testdatefmt_ga_IE.js",
		"testdatefmt_gu_IN.js",
		"testdatefmt_he_IL.js",
		"testdatefmt_hi_IN.js",
		"testdatefmt_hr_HR.js",
		"testdatefmt_id_ID.js",
		"testdatefmt_it_IT.js",
		"testdatefmt_ja_JP.js",
		"testdatefmt.js",
		"testdatefmt_kk_Cyrl_KZ.js",
		"testdatefmt_kn_IN.js",
		"testdatefmt_ko_KR.js",
		//"testdatefmt_ku_Arab_IQ.js",
		"testdatefmt_lt_LT.js",
		"testdatefmt_lv_LV.js",
		"testdatefmt_mk_MK.js",
		"testdatefmt_mn_Cyrl_MN.js",
		"testdatefmt_ml_IN.js",
		"testdatefmt_mr_IN.js",
		"testdatefmt_ms_MY.js",
		"testdatefmt_nb_NO.js",
		"testdatefmt_nl_NL.js",
		"testdatefmt_or_IN.js"
	];

    suites.forEach(function (path) {
    	s.addSuite(newSuite(path));
    });

    return s;
}

<|endoftext|>


<commit_before>"use strict";

export function WaveWriter(sampleRate) {
  var LITTLE_ENDIAN = true;
  var AUDIO_FORMAT_CODE = 1;  // I.e., PCM
  var NUM_CHANNELS = 1;
  var BITS_PER_SAMPLE = 16;
  var BYTES_PER_SAMPLE = 2;
  var MAX_SAMPLE_VALUE = 32767;

  var BLOCK_ALIGN = BYTES_PER_SAMPLE * NUM_CHANNELS;
  var BYTE_RATE = BLOCK_ALIGN * sampleRate;

  var WAVEFILE_HEADER_BYTE_COUNT = 44;
  var RIFF_CHUNK_BODY_BYTE_COUNT_MINIMUM = 36;
  var FORMAT_CHUNK_BODY_BYTE_COUNT = 16;

  var write = function(rawFloat32SampleData) {
    var sampleDataByteCount = rawFloat32SampleData.length * BYTES_PER_SAMPLE;
    var fileLength = WAVEFILE_HEADER_BYTE_COUNT + sampleDataByteCount;
    var outputView = new DataView(new ArrayBuffer(fileLength));
    var sampleByteOffset;
    var constrainedSample;
    var i;

    outputView.setUint8(  0, "R".charCodeAt(0), LITTLE_ENDIAN);
    outputView.setUint8(  1, "I".charCodeAt(0), LITTLE_ENDIAN);
    outputView.setUint8(  2, "F".charCodeAt(0), LITTLE_ENDIAN);
    outputView.setUint8(  3, "F".charCodeAt(0), LITTLE_ENDIAN);
    outputView.setUint32( 4, RIFF_CHUNK_BODY_BYTE_COUNT_MINIMUM + sampleDataByteCount, LITTLE_ENDIAN);
    outputView.setUint8(  8, "W".charCodeAt(0), LITTLE_ENDIAN);
    outputView.setUint8(  9, "A".charCodeAt(0), LITTLE_ENDIAN);
    outputView.setUint8( 10, "V".charCodeAt(0), LITTLE_ENDIAN);
    outputView.setUint8( 11, "E".charCodeAt(0), LITTLE_ENDIAN);
    outputView.setUint8( 12, "f".charCodeAt(0), LITTLE_ENDIAN);
    outputView.setUint8( 13, "m".charCodeAt(0), LITTLE_ENDIAN);
    outputView.setUint8( 14, "t".charCodeAt(0), LITTLE_ENDIAN);
    outputView.setUint8( 15, " ".charCodeAt(0), LITTLE_ENDIAN);
    outputView.setUint32(16, FORMAT_CHUNK_BODY_BYTE_COUNT, LITTLE_ENDIAN);
    outputView.setUint16(20, AUDIO_FORMAT_CODE, LITTLE_ENDIAN);
    outputView.setUint16(22, NUM_CHANNELS, LITTLE_ENDIAN);
    outputView.setUint32(24, sampleRate, LITTLE_ENDIAN);
    outputView.setUint32(28, BYTE_RATE, LITTLE_ENDIAN);
    outputView.setUint16(32, BLOCK_ALIGN, LITTLE_ENDIAN);
    outputView.setUint16(34, BITS_PER_SAMPLE, LITTLE_ENDIAN);
    outputView.setUint8( 36, "d".charCodeAt(0), LITTLE_ENDIAN);
    outputView.setUint8( 37, "a".charCodeAt(0), LITTLE_ENDIAN);
    outputView.setUint8( 38, "t".charCodeAt(0), LITTLE_ENDIAN);
    outputView.setUint8( 39, "a".charCodeAt(0), LITTLE_ENDIAN);
    outputView.setUint32(40, sampleDataByteCount, LITTLE_ENDIAN);

    sampleByteOffset = WAVEFILE_HEADER_BYTE_COUNT;

    // Float32Array doesn't appear to support forEach() in Safari 9
    for (i = 0; i < rawFloat32SampleData.length; i++) {
      // Should this round?
      constrainedSample = Math.max(Math.min(rawFloat32SampleData[i], 1.0), -1.0);
      outputView.setInt16(sampleByteOffset, constrainedSample * MAX_SAMPLE_VALUE, LITTLE_ENDIAN);

      sampleByteOffset += BYTES_PER_SAMPLE;
    }

    return outputView;
  };

  return {
    write: write,
  };
};
<commit_msg>Better variable name<commit_after>"use strict";

export function WaveWriter(sampleRate) {
  var LITTLE_ENDIAN = true;
  var AUDIO_FORMAT_CODE = 1;  // I.e., PCM
  var NUM_CHANNELS = 1;
  var BITS_PER_SAMPLE = 16;
  var BYTES_PER_SAMPLE = 2;
  var MAX_SAMPLE_VALUE = 32767;

  var BLOCK_ALIGN = BYTES_PER_SAMPLE * NUM_CHANNELS;
  var BYTE_RATE = BLOCK_ALIGN * sampleRate;

  var WAVEFILE_HEADER_BYTE_COUNT = 44;
  var RIFF_CHUNK_BODY_BYTE_COUNT_MINIMUM = 36;
  var FORMAT_CHUNK_BODY_BYTE_COUNT = 16;

  var write = function(rawFloat32SampleData) {
    var sampleDataByteCount = rawFloat32SampleData.length * BYTES_PER_SAMPLE;
    var fileLength = WAVEFILE_HEADER_BYTE_COUNT + sampleDataByteCount;
    var outputView = new DataView(new ArrayBuffer(fileLength));
    var sampleByteOffset;
    var clampedSample;
    var i;

    outputView.setUint8(  0, "R".charCodeAt(0), LITTLE_ENDIAN);
    outputView.setUint8(  1, "I".charCodeAt(0), LITTLE_ENDIAN);
    outputView.setUint8(  2, "F".charCodeAt(0), LITTLE_ENDIAN);
    outputView.setUint8(  3, "F".charCodeAt(0), LITTLE_ENDIAN);
    outputView.setUint32( 4, RIFF_CHUNK_BODY_BYTE_COUNT_MINIMUM + sampleDataByteCount, LITTLE_ENDIAN);
    outputView.setUint8(  8, "W".charCodeAt(0), LITTLE_ENDIAN);
    outputView.setUint8(  9, "A".charCodeAt(0), LITTLE_ENDIAN);
    outputView.setUint8( 10, "V".charCodeAt(0), LITTLE_ENDIAN);
    outputView.setUint8( 11, "E".charCodeAt(0), LITTLE_ENDIAN);
    outputView.setUint8( 12, "f".charCodeAt(0), LITTLE_ENDIAN);
    outputView.setUint8( 13, "m".charCodeAt(0), LITTLE_ENDIAN);
    outputView.setUint8( 14, "t".charCodeAt(0), LITTLE_ENDIAN);
    outputView.setUint8( 15, " ".charCodeAt(0), LITTLE_ENDIAN);
    outputView.setUint32(16, FORMAT_CHUNK_BODY_BYTE_COUNT, LITTLE_ENDIAN);
    outputView.setUint16(20, AUDIO_FORMAT_CODE, LITTLE_ENDIAN);
    outputView.setUint16(22, NUM_CHANNELS, LITTLE_ENDIAN);
    outputView.setUint32(24, sampleRate, LITTLE_ENDIAN);
    outputView.setUint32(28, BYTE_RATE, LITTLE_ENDIAN);
    outputView.setUint16(32, BLOCK_ALIGN, LITTLE_ENDIAN);
    outputView.setUint16(34, BITS_PER_SAMPLE, LITTLE_ENDIAN);
    outputView.setUint8( 36, "d".charCodeAt(0), LITTLE_ENDIAN);
    outputView.setUint8( 37, "a".charCodeAt(0), LITTLE_ENDIAN);
    outputView.setUint8( 38, "t".charCodeAt(0), LITTLE_ENDIAN);
    outputView.setUint8( 39, "a".charCodeAt(0), LITTLE_ENDIAN);
    outputView.setUint32(40, sampleDataByteCount, LITTLE_ENDIAN);

    sampleByteOffset = WAVEFILE_HEADER_BYTE_COUNT;

    // Float32Array doesn't appear to support forEach() in Safari 9
    for (i = 0; i < rawFloat32SampleData.length; i++) {
      // Should this round?
      clampedSample = Math.max(Math.min(rawFloat32SampleData[i], 1.0), -1.0);
      outputView.setInt16(sampleByteOffset, clampedSample * MAX_SAMPLE_VALUE, LITTLE_ENDIAN);

      sampleByteOffset += BYTES_PER_SAMPLE;
    }

    return outputView;
  };

  return {
    write: write,
  };
};
<|endoftext|>


<commit_before>/**
 * XHR.js
 *
 * Released under LGPL License.
 * Copyright (c) 1999-2015 Ephox Corp. All rights reserved
 *
 * License: http://www.tinymce.com/license
 * Contributing: http://www.tinymce.com/contributing
 */

/**
 * This class enables you to send XMLHTTPRequests cross browser.
 * @class tinymce.util.XHR
 * @mixes tinymce.util.Observable
 * @static
 * @example
 * // Sends a low level Ajax request
 * tinymce.util.XHR.send({
 *    url: 'someurl',
 *    success: function(text) {
 *       console.debug(text);
 *    }
 * });
 *
 * // Add custom header to XHR request
 * tinymce.util.XHR.on('beforeSend', function(e) {
 *     e.xhr.setRequestHeader('X-Requested-With', 'Something');
 * });
 */
define("tinymce/util/XHR", [
	"tinymce/util/Observable",
	"tinymce/util/Tools"
], function(Observable, Tools) {
	var XHR = {
		/**
		 * Sends a XMLHTTPRequest.
		 * Consult the Wiki for details on what settings this method takes.
		 *
		 * @method send
		 * @param {Object} settings Object will target URL, callbacks and other info needed to make the request.
		 */
		send: function(settings) {
			var xhr, count = 0;

			function ready() {
				if (!settings.async || xhr.readyState == 4 || count++ > 10000) {
					if (settings.success && count < 10000 && xhr.status == 200) {
						settings.success.call(settings.success_scope, '' + xhr.responseText, xhr, settings);
					} else if (settings.error) {
						settings.error.call(settings.error_scope, count > 10000 ? 'TIMED_OUT' : 'GENERAL', xhr, settings);
					}

					xhr = null;
				} else {
					setTimeout(ready, 10);
				}
			}

			// Default settings
			settings.scope = settings.scope || this;
			settings.success_scope = settings.success_scope || settings.scope;
			settings.error_scope = settings.error_scope || settings.scope;
			settings.async = settings.async === false ? false : true;
			settings.data = settings.data || '';

			XHR.fire('beforeInitialize', {settings: settings});

			xhr = new XMLHttpRequest();

			if (xhr) {
				if (xhr.overrideMimeType) {
					xhr.overrideMimeType(settings.content_type);
				}

				xhr.open(settings.type || (settings.data ? 'POST' : 'GET'), settings.url, settings.async);

				if (settings.crossDomain) {
					xhr.withCredentials = true;
				}

				if (settings.content_type) {
					xhr.setRequestHeader('Content-Type', settings.content_type);
				}

				if (settings.requestheaders) {
					Tools.each(settings.requestheaders, function(header) {
						xhr.setRequestHeader(header.key, header.value);
					});
				}

				xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');

				xhr = XHR.fire('beforeSend', {xhr: xhr, settings: settings}).xhr;
				xhr.send(settings.data);

				// Syncronous request
				if (!settings.async) {
					return ready();
				}

				// Wait for response, onReadyStateChange can not be used since it leaks memory in IE
				setTimeout(ready, 10);
			}
		}
	};

	Tools.extend(XHR, Observable);

	return XHR;
});
<commit_msg>Fixed whitespace issue<commit_after>/**
 * XHR.js
 *
 * Released under LGPL License.
 * Copyright (c) 1999-2015 Ephox Corp. All rights reserved
 *
 * License: http://www.tinymce.com/license
 * Contributing: http://www.tinymce.com/contributing
 */

/**
 * This class enables you to send XMLHTTPRequests cross browser.
 * @class tinymce.util.XHR
 * @mixes tinymce.util.Observable
 * @static
 * @example
 * // Sends a low level Ajax request
 * tinymce.util.XHR.send({
 *    url: 'someurl',
 *    success: function(text) {
 *       console.debug(text);
 *    }
 * });
 *
 * // Add custom header to XHR request
 * tinymce.util.XHR.on('beforeSend', function(e) {
 *     e.xhr.setRequestHeader('X-Requested-With', 'Something');
 * });
 */
define("tinymce/util/XHR", [
	"tinymce/util/Observable",
	"tinymce/util/Tools"
], function(Observable, Tools) {
	var XHR = {
		/**
		 * Sends a XMLHTTPRequest.
		 * Consult the Wiki for details on what settings this method takes.
		 *
		 * @method send
		 * @param {Object} settings Object will target URL, callbacks and other info needed to make the request.
		 */
		send: function(settings) {
			var xhr, count = 0;

			function ready() {
				if (!settings.async || xhr.readyState == 4 || count++ > 10000) {
					if (settings.success && count < 10000 && xhr.status == 200) {
						settings.success.call(settings.success_scope, '' + xhr.responseText, xhr, settings);
					} else if (settings.error) {
						settings.error.call(settings.error_scope, count > 10000 ? 'TIMED_OUT' : 'GENERAL', xhr, settings);
					}

					xhr = null;
				} else {
					setTimeout(ready, 10);
				}
			}

			// Default settings
			settings.scope = settings.scope || this;
			settings.success_scope = settings.success_scope || settings.scope;
			settings.error_scope = settings.error_scope || settings.scope;
			settings.async = settings.async === false ? false : true;
			settings.data = settings.data || '';

			XHR.fire('beforeInitialize', {settings: settings});

			xhr = new XMLHttpRequest();

			if (xhr) {
				if (xhr.overrideMimeType) {
					xhr.overrideMimeType(settings.content_type);
				}

				xhr.open(settings.type || (settings.data ? 'POST' : 'GET'), settings.url, settings.async);

				if (settings.crossDomain) {
					xhr.withCredentials = true;
				}

				if (settings.content_type) {
					xhr.setRequestHeader('Content-Type', settings.content_type);
				}

				if (settings.requestheaders) {
					Tools.each(settings.requestheaders, function(header) {
						xhr.setRequestHeader(header.key, header.value);
					});
				}

				xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');

				xhr = XHR.fire('beforeSend', {xhr: xhr, settings: settings}).xhr;
				xhr.send(settings.data);

				// Syncronous request
				if (!settings.async) {
					return ready();
				}

				// Wait for response, onReadyStateChange can not be used since it leaks memory in IE
				setTimeout(ready, 10);
			}
		}
	};

	Tools.extend(XHR, Observable);

	return XHR;
});
<|endoftext|>


<commit_before>/**
 *   Copyright (C) 2016 Jorge Campos Serrano.
 *
 *   This program is free software: you can redistribute it and/or  modify
 *   it under the terms of the GNU Affero General Public License, version 3,
 *   as published by the Free Software Foundation.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Affero General Public License for more details.
 *
 *   You should have received a copy of the GNU Affero General Public License
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *   As a special exception, the copyright holders give permission to link the
 *   code of portions of this program with the OpenSSL library under certain
 *   conditions as described in each individual source file and distribute
 *   linked combinations including the program with the OpenSSL library. You
 *   must comply with the GNU Affero General Public License in all respects
 *   for all of the code used other than as permitted herein. If you modify
 *   file(s) with this exception, you may extend this exception to your
 *   version of the file(s), but you are not obligated to do so. If you do not
 *   wish to do so, delete this exception statement from your version. If you
 *   delete this exception statement from all source files in the program,
 *   then also delete it in the license file.
 */

var remoteMediaEvId;

MediaManager = (function () {

  var module = {};

  var webrtc = null;
  var localStream;

  var mediaRecorder,
     recordedBlobs;

  function getSTUNObj(stunStr) {
    var urlsParam = 'urls';

    var obj = {};
    obj[urlsParam] = stunStr;
    return obj;
  };

  function getTURNObj(turnStr, username, credential) {
    var urlsParam = 'urls';

    var obj = {
        username: username,
        credential: credential
    };
    obj[urlsParam] = turnStr;
    return obj;
  };

  function generateBlob(name) {
    var blob = new Blob(recordedBlobs, {
      type: 'video/webm'
    });
    blob.name = name;

    return blob;
  };

  function handleDataAvailable(event) {
    if (event.data && event.data.size > 0) {
      recordedBlobs.push(event.data);
    };
  };

  function updateRecording(response) {
    var fileId = JSON.parse(response).id;
    var recordingId = RoomManager.getRoomRecording().id;

    var r = Recordings.findOne({_id: recordingId});

    if (r) {
      var sourceRecording = {
        id: Session.get('myMediaEventId'),
        file: fileId
      };
      r.sources.push(sourceRecording);

      if(Session.get('isModerator')) {
        var events = Timeline.getEvents();

        r.events = events;
        r.duration = events[events.length-1].timestamp;
        r.state = 'finished';

        var playlistId = RoomManager.getRoomPlayList();
        Meteor.call('addRecordingToPlayList', playlistId, recordingId);
      };

      // Update recording
      Meteor.call('updateRecording', recordingId, r);
    }

    var googleService = Meteor.user().services.google;

    var permissionsConfig = {
      fileId: fileId,
      token: googleService.accessToken,
      body: {
        type: 'anyone',
        role: 'reader'
      }
    };
    UploaderManager.insertPermissions(permissionsConfig);

    Session.set('uploading', false);
  }

  function handleStop() {
    var blob = generateBlob(RoomManager.getRoomRecording().title);

    if (blob.size > 0) {
      var data = {
        file: blob,
        token: Meteor.user().services.google.accessToken,
        onComplete: updateRecording
      };

      UploaderManager.upload(data);
      Session.set('uploading', true);
    };
  };

  function onError(event) {
    throwAlert('error', 'Recorder error: ' + event, 'alert-circle');
  };

  function setMyRoom(config) {
    // unmute media and set editor write
    webrtc.unmute();
    ace.edit('editor').setReadOnly(false);
    Session.set('live', true);

    record(config.data);
  };

  function record(data) {
    if(data.recording.active) {
      Session.set('myMediaEventId', data.eventId);
      RoomManager.setRoomRecording(data.recording.info);
      Session.set('recording', true);
      Session.set('stopping', false);
    }
  };

  function unSetMyRoom() {
    // Mute media and set editor read only
    webrtc.mute();
    ace.edit('editor').setReadOnly(true);
    Session.set('live', false);

    if(Session.get('recording')) {
      Session.set('recording', false);
      Session.set('stopping', true);
    }
  };

  function isMessageForMe(id) {
    var sParticipant = ParticipantsManager.getSecondaryParticipant();
    return localStream.id === id && sParticipant != null;
  };

  function addMediaListeners() {
    webrtc.on('readyToCall', function () {
      var room = this.config.room;

      if (room) {
        webrtc.joinRoom(room);
      }
    });

    webrtc.on('localStream', function (stream) {
      // if moderator pause video until start session
      if(Session.get('isModerator')){
        this.pauseVideo();
      }

      // Mute all streams
      this.mute();

      RoomManager.setLocalStream(stream);
      localStream = stream;

      var conf = {
        stream: stream,
        profile: this.config.nick
      };
      ParticipantsManager.addLocalParticipant(conf);

      Session.set('loadingMedia', false);
    });

    webrtc.on('videoAdded', function (video, peer) {
      var conf = {
        stream: peer.stream,
        profile: peer.nick
      };
      ParticipantsManager.addParticipant(conf);
    });

    webrtc.on('videoRemoved', function (video, peer) {
      ParticipantsManager.removeParticipantByStream(peer.stream);
      var lastSParticipant = ParticipantsManager.getSecondaryParticipant();
      if (lastSParticipant) {
        if(Session.get('isModerator') && Session.get('recording')) {
          Timeline.addEvent({
            id: remoteMediaEvId,
            type: 'media',
            toDo: 'remove',
            arg: lastSParticipant.stream.id
          });
        }

        if(lastSParticipant.stream.id === peer.stream.id) {
          ParticipantsManager.updateSecondaryParticipant(lastSParticipant, false);
        }

        if(peer.nick.role === 'moderator') {
          Session.set('live', false);
        }
      }
    });

    webrtc.connection.on('message', function(message){
      switch(message.type) {
        case 'muteMedia':
          unSetMyRoom();
          break;
        case 'setSecondaryParticipant':
          var participantId = message.payload.to;
          var searchedParticipant = ParticipantsManager.getParticipantById(participantId);
          ParticipantsManager.updateSecondaryParticipant(searchedParticipant, message.payload.active);

          if(isMessageForMe(participantId)) {
            setMyRoom(message.payload);
          };
          break;
        case 'recording':
          if(isMessageForMe(message.payload.to)) {
            record(message.payload.data);
          };
          break;
        case 'recordingStop':
          if(isMessageForMe(message.payload.to)) {
            Session.set('recording', false);
            Session.set('stopping', true);
          };
          break;
        case 'setEditorMode':
          setModeEditor(message.payload);
          break;
        case 'textMessage':
          module.addMessage(message.payload, true);
          break;
        case 'finishedSession':
          var lastSParticipant = ParticipantsManager.getSecondaryParticipant();
          if (lastSParticipant) {
            ParticipantsManager.updateSecondaryParticipant(lastSParticipant, false);
          }
          Session.set('live', false);
          $('#finishedBroadcast.modal').modal('show');
          break;
        default:
          break;
      }
    });
  };

  module.getIceServers = function() {
    var iceServers = [];

    iceServers.push(getSTUNObj('stun:stun.l.google.com:19302'));
    // coTURN
    iceServers.push(getTURNObj('turn:webrtcweb.com:80', 'muazkh', 'muazkh'));
    iceServers.push(getTURNObj('turn:webrtcweb.com:443', 'muazkh', 'muazkh'));
    // resiprocate
    iceServers.push(getTURNObj('turn:webrtcweb.com:3344', 'muazkh', 'muazkh'));
    iceServers.push(getTURNObj('turn:webrtcweb.com:4433', 'muazkh', 'muazkh'));
    // restund
    iceServers.push(getTURNObj('turn:webrtcweb.com:4455', 'muazkh', 'muazkh'));
    iceServers.push(getTURNObj('turn:webrtcweb.com:5544?transport=tcp', 'muazkh', 'muazkh'));

    return iceServers;
  };

  module.connect = function(options) {
    // create webrtc connection
    webrtc = new SimpleWebRTC(options);
    addMediaListeners();
    return webrtc;
  };

  module.resumeMedia = function() {
    webrtc.resume();
    Session.set('live', true);
  };

  module.pauseMedia = function() {
    webrtc.pause();
  };

  module.updateSecondaryParticipant = function(participantId, isActive) {
    var lastSParticipant = ParticipantsManager.getSecondaryParticipant();
    if(Session.get('recording') && lastSParticipant) {
      Timeline.addEvent({
        id: remoteMediaEvId,
        type: 'media',
        toDo: 'remove',
        arg: lastSParticipant.stream.id
      });
    }

    // Send message to mute previous secondary participant
    this.sendToAllMessage('muteMedia');

    // Send message to set a new secondary participant
    remoteMediaEvId = Timeline.generateEventId();
    var msg = {
      'to': participantId,
      'active': isActive,
      'data': {
        eventId: remoteMediaEvId,
        recording: {
          active: Session.get('recording'),
          info: RoomManager.getRoomRecording()
        }
      }
    };
    MediaManager.sendToAllMessage('setSecondaryParticipant', msg);

    var searchedParticipant = ParticipantsManager.getParticipantById(participantId);
    ParticipantsManager.updateSecondaryParticipant(searchedParticipant, isActive);

    // If new secondary participant fire event insert.
    var currentSParticipant = ParticipantsManager.getSecondaryParticipant();
    if(Session.get('recording') && currentSParticipant) {
      Timeline.addEvent({
        id: remoteMediaEvId,
        type: 'media',
        toDo: 'insert',
        arg: currentSParticipant.stream.id
      });
    }
  };

  module.sendToAllMessage = function(type, msg) {
    webrtc.sendToAll(type, msg);
  };

  module.addMessage = function(msg, remote) {
    var origin = remote ? '' : 'chat__message--right';
    var p = '
';
    p += '
'+msg.name+'
';
    p += '
';
    p += '
'+''+'
';
    p += '
'+'
'+msg.value+'
'+'
';
    p += '
';
    p += '
';

    $('.chat__container .chat__messages').append(p);

    var scrollValue = $('.chat__container .chat__messages')[0].scrollHeight;
    $('.chat__container').scrollTop(scrollValue);

    if(Session.get('isModerator') && Session.get('recording')) {
      msg.remote = remote;
      Timeline.addEvent({
        type: 'chat',
        toDo: 'insert',
        arg: msg
      });
    }
  };

  module.sendTextMessage = function(value) {
    var msg =  {
      name: webrtc.config.nick.name,
      image: webrtc.config.nick.image,
      value: value
    };

    this.addMessage(msg);
    this.sendToAllMessage('textMessage', msg);
  };

  module.startRecord = function() {
    var options = {mimeType: 'video/webm', bitsPerSecond: 100000};

    recordedBlobs = [];
    try {
      mediaRecorder = new MediaRecorder(localStream, options);
    } catch (e0) {
      try {
        options = {mimeType: 'video/webm,codecs=vp9', bitsPerSecond: 100000};
        mediaRecorder = new MediaRecorder(localStream, options);
      } catch (e1) {
        try {
          // Chrome 47
          options = 'video/vp8';
          mediaRecorder = new MediaRecorder(localStream, options);
        } catch (e2) {
          throwAlert('error', 'MediaRecorder is not supported by this browser.', 'alert-circle');
          return;
        }
      }
    }

    mediaRecorder.onstop = handleStop;
    mediaRecorder.ondataavailable = handleDataAvailable;
    mediaRecorder.onerror = onError;
    // Collect 10ms of data
    mediaRecorder.start(10);
  };

  module.stopRecord = function() {
    if(mediaRecorder) {
      mediaRecorder.stop();
    }
  };

  return module;

}());

Tracker.autorun(function() {
  if(Session.get('recording')) {
    // Create timeline
    Timeline.init({mediaEl: document.getElementById('main-media')});

    MediaManager.startRecord();

    // insert first event
    if(Session.get('isModerator')) {
      throwAlert('info', 'Session is being recorded');

      var evId = Timeline.generateEventId();
      Session.set('myMediaEventId', evId);

      Timeline.addEvent({
        id: evId,
        type: 'media',
        toDo: 'insert',
        arg: RoomManager.getLocalStream().id
      });

      var lastSParticipant = ParticipantsManager.getSecondaryParticipant();
      if (lastSParticipant) {
        remoteMediaEvId = Timeline.generateEventId();
        var msg = {
          'to': lastSParticipant.stream.id,
          'data': {
            eventId: remoteMediaEvId,
            recording: {
              active: Session.get('recording'),
              info: RoomManager.getRoomRecording()
            }
          }
        };
        MediaManager.sendToAllMessage('recording', msg);

        Timeline.addEvent({
          id: remoteMediaEvId,
          type: 'media',
          toDo: 'insert',
          arg: lastSParticipant.stream.id
        });
      }
    };
  };
});

Tracker.autorun(function() {
  if(Session.get('stopping')) {
    MediaManager.stopRecord();

    if(Session.get('isModerator')) {
      throwAlert('info', 'Recording has stopped', 'information');

      var lastSParticipant = ParticipantsManager.getSecondaryParticipant();
      if (lastSParticipant) {
        var msg = {
          'to': lastSParticipant.stream.id
        };
        MediaManager.sendToAllMessage('recordingStop', msg);

        Timeline.addEvent({
          id: remoteMediaEvId,
          type: 'media',
          toDo: 'remove',
          arg: lastSParticipant.stream.id
        });
      }

      // insert last event
      Timeline.addEvent({
        id: Session.get('myMediaEventId'),
        type: 'media',
        toDo: 'remove',
        arg: RoomManager.getLocalStream().id
      });

      Session.set('stopping', false);
    }
  }
});
<commit_msg>Update turn server ports<commit_after>/**
 *   Copyright (C) 2016 Jorge Campos Serrano.
 *
 *   This program is free software: you can redistribute it and/or  modify
 *   it under the terms of the GNU Affero General Public License, version 3,
 *   as published by the Free Software Foundation.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Affero General Public License for more details.
 *
 *   You should have received a copy of the GNU Affero General Public License
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *   As a special exception, the copyright holders give permission to link the
 *   code of portions of this program with the OpenSSL library under certain
 *   conditions as described in each individual source file and distribute
 *   linked combinations including the program with the OpenSSL library. You
 *   must comply with the GNU Affero General Public License in all respects
 *   for all of the code used other than as permitted herein. If you modify
 *   file(s) with this exception, you may extend this exception to your
 *   version of the file(s), but you are not obligated to do so. If you do not
 *   wish to do so, delete this exception statement from your version. If you
 *   delete this exception statement from all source files in the program,
 *   then also delete it in the license file.
 */

var remoteMediaEvId;

MediaManager = (function () {

  var module = {};

  var webrtc = null;
  var localStream;

  var mediaRecorder,
     recordedBlobs;

  function getSTUNObj(stunStr) {
    var urlsParam = 'urls';

    var obj = {};
    obj[urlsParam] = stunStr;
    return obj;
  };

  function getTURNObj(turnStr, username, credential) {
    var urlsParam = 'urls';

    var obj = {
        username: username,
        credential: credential
    };
    obj[urlsParam] = turnStr;
    return obj;
  };

  function generateBlob(name) {
    var blob = new Blob(recordedBlobs, {
      type: 'video/webm'
    });
    blob.name = name;

    return blob;
  };

  function handleDataAvailable(event) {
    if (event.data && event.data.size > 0) {
      recordedBlobs.push(event.data);
    };
  };

  function updateRecording(response) {
    var fileId = JSON.parse(response).id;
    var recordingId = RoomManager.getRoomRecording().id;

    var r = Recordings.findOne({_id: recordingId});

    if (r) {
      var sourceRecording = {
        id: Session.get('myMediaEventId'),
        file: fileId
      };
      r.sources.push(sourceRecording);

      if(Session.get('isModerator')) {
        var events = Timeline.getEvents();

        r.events = events;
        r.duration = events[events.length-1].timestamp;
        r.state = 'finished';

        var playlistId = RoomManager.getRoomPlayList();
        Meteor.call('addRecordingToPlayList', playlistId, recordingId);
      };

      // Update recording
      Meteor.call('updateRecording', recordingId, r);
    }

    var googleService = Meteor.user().services.google;

    var permissionsConfig = {
      fileId: fileId,
      token: googleService.accessToken,
      body: {
        type: 'anyone',
        role: 'reader'
      }
    };
    UploaderManager.insertPermissions(permissionsConfig);

    Session.set('uploading', false);
  }

  function handleStop() {
    var blob = generateBlob(RoomManager.getRoomRecording().title);

    if (blob.size > 0) {
      var data = {
        file: blob,
        token: Meteor.user().services.google.accessToken,
        onComplete: updateRecording
      };

      UploaderManager.upload(data);
      Session.set('uploading', true);
    };
  };

  function onError(event) {
    throwAlert('error', 'Recorder error: ' + event, 'alert-circle');
  };

  function setMyRoom(config) {
    // unmute media and set editor write
    webrtc.unmute();
    ace.edit('editor').setReadOnly(false);
    Session.set('live', true);

    record(config.data);
  };

  function record(data) {
    if(data.recording.active) {
      Session.set('myMediaEventId', data.eventId);
      RoomManager.setRoomRecording(data.recording.info);
      Session.set('recording', true);
      Session.set('stopping', false);
    }
  };

  function unSetMyRoom() {
    // Mute media and set editor read only
    webrtc.mute();
    ace.edit('editor').setReadOnly(true);
    Session.set('live', false);

    if(Session.get('recording')) {
      Session.set('recording', false);
      Session.set('stopping', true);
    }
  };

  function isMessageForMe(id) {
    var sParticipant = ParticipantsManager.getSecondaryParticipant();
    return localStream.id === id && sParticipant != null;
  };

  function addMediaListeners() {
    webrtc.on('readyToCall', function () {
      var room = this.config.room;

      if (room) {
        webrtc.joinRoom(room);
      }
    });

    webrtc.on('localStream', function (stream) {
      // if moderator pause video until start session
      if(Session.get('isModerator')){
        this.pauseVideo();
      }

      // Mute all streams
      this.mute();

      RoomManager.setLocalStream(stream);
      localStream = stream;

      var conf = {
        stream: stream,
        profile: this.config.nick
      };
      ParticipantsManager.addLocalParticipant(conf);

      Session.set('loadingMedia', false);
    });

    webrtc.on('videoAdded', function (video, peer) {
      var conf = {
        stream: peer.stream,
        profile: peer.nick
      };
      ParticipantsManager.addParticipant(conf);
    });

    webrtc.on('videoRemoved', function (video, peer) {
      ParticipantsManager.removeParticipantByStream(peer.stream);
      var lastSParticipant = ParticipantsManager.getSecondaryParticipant();
      if (lastSParticipant) {
        if(Session.get('isModerator') && Session.get('recording')) {
          Timeline.addEvent({
            id: remoteMediaEvId,
            type: 'media',
            toDo: 'remove',
            arg: lastSParticipant.stream.id
          });
        }

        if(lastSParticipant.stream.id === peer.stream.id) {
          ParticipantsManager.updateSecondaryParticipant(lastSParticipant, false);
        }

        if(peer.nick.role === 'moderator') {
          Session.set('live', false);
        }
      }
    });

    webrtc.connection.on('message', function(message){
      switch(message.type) {
        case 'muteMedia':
          unSetMyRoom();
          break;
        case 'setSecondaryParticipant':
          var participantId = message.payload.to;
          var searchedParticipant = ParticipantsManager.getParticipantById(participantId);
          ParticipantsManager.updateSecondaryParticipant(searchedParticipant, message.payload.active);

          if(isMessageForMe(participantId)) {
            setMyRoom(message.payload);
          };
          break;
        case 'recording':
          if(isMessageForMe(message.payload.to)) {
            record(message.payload.data);
          };
          break;
        case 'recordingStop':
          if(isMessageForMe(message.payload.to)) {
            Session.set('recording', false);
            Session.set('stopping', true);
          };
          break;
        case 'setEditorMode':
          setModeEditor(message.payload);
          break;
        case 'textMessage':
          module.addMessage(message.payload, true);
          break;
        case 'finishedSession':
          var lastSParticipant = ParticipantsManager.getSecondaryParticipant();
          if (lastSParticipant) {
            ParticipantsManager.updateSecondaryParticipant(lastSParticipant, false);
          }
          Session.set('live', false);
          $('#finishedBroadcast.modal').modal('show');
          break;
        default:
          break;
      }
    });
  };

  module.getIceServers = function() {
    var iceServers = [];

    iceServers.push(getSTUNObj('stun:stun.l.google.com:19302'));
    // coTURN
    iceServers.push(getTURNObj('turn:webrtcweb.com:7788', 'muazkh', 'muazkh'));
    iceServers.push(getTURNObj('turn:webrtcweb.com:8877', 'muazkh', 'muazkh'));
    // resiprocate
    iceServers.push(getTURNObj('turn:webrtcweb.com:3344', 'muazkh', 'muazkh'));
    iceServers.push(getTURNObj('turn:webrtcweb.com:4433', 'muazkh', 'muazkh'));
    // restund
    iceServers.push(getTURNObj('turn:webrtcweb.com:4455', 'muazkh', 'muazkh'));
    iceServers.push(getTURNObj('turn:webrtcweb.com:5544?transport=tcp', 'muazkh', 'muazkh'));

    return iceServers;
  };

  module.connect = function(options) {
    // create webrtc connection
    webrtc = new SimpleWebRTC(options);
    addMediaListeners();
    return webrtc;
  };

  module.resumeMedia = function() {
    webrtc.resume();
    Session.set('live', true);
  };

  module.pauseMedia = function() {
    webrtc.pause();
  };

  module.updateSecondaryParticipant = function(participantId, isActive) {
    var lastSParticipant = ParticipantsManager.getSecondaryParticipant();
    if(Session.get('recording') && lastSParticipant) {
      Timeline.addEvent({
        id: remoteMediaEvId,
        type: 'media',
        toDo: 'remove',
        arg: lastSParticipant.stream.id
      });
    }

    // Send message to mute previous secondary participant
    this.sendToAllMessage('muteMedia');

    // Send message to set a new secondary participant
    remoteMediaEvId = Timeline.generateEventId();
    var msg = {
      'to': participantId,
      'active': isActive,
      'data': {
        eventId: remoteMediaEvId,
        recording: {
          active: Session.get('recording'),
          info: RoomManager.getRoomRecording()
        }
      }
    };
    MediaManager.sendToAllMessage('setSecondaryParticipant', msg);

    var searchedParticipant = ParticipantsManager.getParticipantById(participantId);
    ParticipantsManager.updateSecondaryParticipant(searchedParticipant, isActive);

    // If new secondary participant fire event insert.
    var currentSParticipant = ParticipantsManager.getSecondaryParticipant();
    if(Session.get('recording') && currentSParticipant) {
      Timeline.addEvent({
        id: remoteMediaEvId,
        type: 'media',
        toDo: 'insert',
        arg: currentSParticipant.stream.id
      });
    }
  };

  module.sendToAllMessage = function(type, msg) {
    webrtc.sendToAll(type, msg);
  };

  module.addMessage = function(msg, remote) {
    var origin = remote ? '' : 'chat__message--right';
    var p = '
';
    p += '
'+msg.name+'
';
    p += '
';
    p += '
'+''+'
';
    p += '
'+'
'+msg.value+'
'+'
';
    p += '
';
    p += '
';

    $('.chat__container .chat__messages').append(p);

    var scrollValue = $('.chat__container .chat__messages')[0].scrollHeight;
    $('.chat__container').scrollTop(scrollValue);

    if(Session.get('isModerator') && Session.get('recording')) {
      msg.remote = remote;
      Timeline.addEvent({
        type: 'chat',
        toDo: 'insert',
        arg: msg
      });
    }
  };

  module.sendTextMessage = function(value) {
    var msg =  {
      name: webrtc.config.nick.name,
      image: webrtc.config.nick.image,
      value: value
    };

    this.addMessage(msg);
    this.sendToAllMessage('textMessage', msg);
  };

  module.startRecord = function() {
    var options = {mimeType: 'video/webm', bitsPerSecond: 100000};

    recordedBlobs = [];
    try {
      mediaRecorder = new MediaRecorder(localStream, options);
    } catch (e0) {
      try {
        options = {mimeType: 'video/webm,codecs=vp9', bitsPerSecond: 100000};
        mediaRecorder = new MediaRecorder(localStream, options);
      } catch (e1) {
        try {
          // Chrome 47
          options = 'video/vp8';
          mediaRecorder = new MediaRecorder(localStream, options);
        } catch (e2) {
          throwAlert('error', 'MediaRecorder is not supported by this browser.', 'alert-circle');
          return;
        }
      }
    }

    mediaRecorder.onstop = handleStop;
    mediaRecorder.ondataavailable = handleDataAvailable;
    mediaRecorder.onerror = onError;
    // Collect 10ms of data
    mediaRecorder.start(10);
  };

  module.stopRecord = function() {
    if(mediaRecorder) {
      mediaRecorder.stop();
    }
  };

  return module;

}());

Tracker.autorun(function() {
  if(Session.get('recording')) {
    // Create timeline
    Timeline.init({mediaEl: document.getElementById('main-media')});

    MediaManager.startRecord();

    // insert first event
    if(Session.get('isModerator')) {
      throwAlert('info', 'Session is being recorded');

      var evId = Timeline.generateEventId();
      Session.set('myMediaEventId', evId);

      Timeline.addEvent({
        id: evId,
        type: 'media',
        toDo: 'insert',
        arg: RoomManager.getLocalStream().id
      });

      var lastSParticipant = ParticipantsManager.getSecondaryParticipant();
      if (lastSParticipant) {
        remoteMediaEvId = Timeline.generateEventId();
        var msg = {
          'to': lastSParticipant.stream.id,
          'data': {
            eventId: remoteMediaEvId,
            recording: {
              active: Session.get('recording'),
              info: RoomManager.getRoomRecording()
            }
          }
        };
        MediaManager.sendToAllMessage('recording', msg);

        Timeline.addEvent({
          id: remoteMediaEvId,
          type: 'media',
          toDo: 'insert',
          arg: lastSParticipant.stream.id
        });
      }
    };
  };
});

Tracker.autorun(function() {
  if(Session.get('stopping')) {
    MediaManager.stopRecord();

    if(Session.get('isModerator')) {
      throwAlert('info', 'Recording has stopped', 'information');

      var lastSParticipant = ParticipantsManager.getSecondaryParticipant();
      if (lastSParticipant) {
        var msg = {
          'to': lastSParticipant.stream.id
        };
        MediaManager.sendToAllMessage('recordingStop', msg);

        Timeline.addEvent({
          id: remoteMediaEvId,
          type: 'media',
          toDo: 'remove',
          arg: lastSParticipant.stream.id
        });
      }

      // insert last event
      Timeline.addEvent({
        id: Session.get('myMediaEventId'),
        type: 'media',
        toDo: 'remove',
        arg: RoomManager.getLocalStream().id
      });

      Session.set('stopping', false);
    }
  }
});
<|endoftext|>


<commit_before>$(document).ready(function() {

    var currUser;

    function initialize() {
        // currUser.get("name") := First and last name
        // currUser.get("picture") := String url of profile picture
    }

    Parse.initialize("VXRx5pZQAr263FPLmgqY2FHEa66zEOLIuK3I2rl6", "OQkMhfc7hMHcBBkiUoClnxAfrF8gpmKaC3jNKq5V");

    window.fbAsyncInit = function() {
        Parse.FacebookUtils.init({
          appId      : '789662264445561',
          xfbml      : true,
          version    : 'v2.3'
        });

        Parse.FacebookUtils.logIn("user_friends", {
            success: function(user) {
                currUser = user;

                FB.api("/me", function(response) {
                    user.set("name", response.name);
                    user.save();
                });

                FB.api("/me/picture?type=large", function(response) {
                    user.set("picture", response.data.url);
                    user.save();
                });

                FB.api("/me/friends", function(response) {
                    console.log("oh");
                    console.log(response);
                    user.save();
                });

                initialize();
            },
            error: function(user, error) {
                alert("You must sign into Facebook to use this app");
            }
        });
    };

    (function(d, s, id){
     var js, fjs = d.getElementsByTagName(s)[0];
     if (d.getElementById(id)) {return;}
     js = d.createElement(s); js.id = id;
     js.src = "http://connect.facebook.net/en_US/sdk.js";
     fjs.parentNode.insertBefore(js, fjs);
    }(document, 'script', 'facebook-jssdk'));

});<commit_msg>Testing friend lists<commit_after>$(document).ready(function() {

    var currUser;

    function initialize() {
        // currUser.get("name") := First and last name
        // currUser.get("picture") := String url of profile picture
    }

    Parse.initialize("VXRx5pZQAr263FPLmgqY2FHEa66zEOLIuK3I2rl6", "OQkMhfc7hMHcBBkiUoClnxAfrF8gpmKaC3jNKq5V");

    window.fbAsyncInit = function() {
        Parse.FacebookUtils.init({
          appId      : '789662264445561',
          xfbml      : true,
          version    : 'v2.3'
        });

        Parse.FacebookUtils.logIn("user_friends", {
            success: function(user) {
                currUser = user;

                FB.api("/me", function(response) {
                    user.set("name", response.name);
                    user.save();
                });

                FB.api("/me/picture?type=large", function(response) {
                    user.set("picture", response.data.url);
                    user.save();
                });

                FB.api("/me/friends", function(response) {
                    console.log("oh");
                    console.log(response);
                    user.save();
                });

                FB.api("/10205901503874063", function(response) {
                    console.log(response.name);
                });

                initialize();
            },
            error: function(user, error) {
                alert("You must sign into Facebook to use this app");
            }
        });
    };

    (function(d, s, id){
     var js, fjs = d.getElementsByTagName(s)[0];
     if (d.getElementById(id)) {return;}
     js = d.createElement(s); js.id = id;
     js.src = "http://connect.facebook.net/en_US/sdk.js";
     fjs.parentNode.insertBefore(js, fjs);
    }(document, 'script', 'facebook-jssdk'));

});<|endoftext|>


<commit_before>"use strict";

var easing = require("easing-js");

//easing
var radarStart = -50;
var time = 0;
var duration = 500;

//radar
var angle = 0;
var period = 5000;
var radius = 80;

module.exports = function(ecs, data) { // eslint-disable-line no-unused-vars
	ecs.addEach(function renderRadar(entity, context, elapsed) { // eslint-disable-line no-unused-vars

		//timer image
		var radarY = 5;
		if(time < duration){
			time += elapsed;
			radarY = easing.easeOutElastic(time, radarStart, 55, duration);
		}
		var radarImage = data.images.get("radar");
		context.drawImage(radarImage, 5, radarY);

		// radar screen
		if(time >= duration){

			var angularVelocity = -((Math.PI * 2) / period);
			var distanceThisFrame = angularVelocity * elapsed;
			angle += distanceThisFrame;

			var cx = 5 + Math.floor(radarImage.width / 2);
			var cy = radarY + Math.floor(radarImage.height / 2);
			var x = radius * Math.cos(angle);
			var y = radius * Math.sin(angle);

			var linePoints = {
				"startX": cx,
				"startY": cy,
				"endX": cx + x,
				"endY": cy + y
			};
			drawLine(context, linePoints, "1px", "#6abd44");

			var playerPosition = data.entities.get(entity, "position");

			data.entities.find("position").forEach(function(id) {
				var entityType = data.entities.get(id, "type");
				var entitySticky = data.entities.get(id, "sticky");
				var entityPlayer = data.entities.get(id, "player");
				var entityPosition = data.entities.get(id, "position");

				if ((entityType !== "trash" && entityType !== "obstacle") || entitySticky || entityPlayer) {
					return;
				}

				var dx = entityPosition.x - playerPosition.x;
				var dy = entityPosition.y - playerPosition.y;

				var max = 1000 * 1000;
				var dist = Math.max(Math.min((dx * dx + dy * dy), max), -max);
				var scaledDist = dist / max * (radius - 3);

				var angle = Math.atan2(entityPosition.y - playerPosition.y, entityPosition.x - playerPosition.x);

				var ex = scaledDist * Math.cos(angle);
				var ey = scaledDist * Math.sin(angle);

				context.strokeStyle = "#6abd44";
				if (entityType === "obstacle") {
					context.strokeStyle = "red";
				}
				context.beginPath();
				context.arc(cx + ex, cy + ey, 3, 0, Math.PI * 2);
				context.stroke();
			});
		}
	}, "player");
};

function drawLine(context, ray, width, color) {
	context.strokeStyle = color;
	context.lineWidth = width;
	context.beginPath();
	context.moveTo(ray.startX, ray.startY);
	context.lineTo(ray.endX, ray.endY);
	context.stroke();
}
<commit_msg>Use rectangles instead of circles on radar<commit_after>"use strict";

var easing = require("easing-js");

//easing
var radarStart = -50;
var time = 0;
var duration = 500;

//radar
var angle = 0;
var period = 5000;
var radius = 80;

module.exports = function(ecs, data) { // eslint-disable-line no-unused-vars
	ecs.addEach(function renderRadar(entity, context, elapsed) { // eslint-disable-line no-unused-vars

		//timer image
		var radarY = 5;
		if(time < duration){
			time += elapsed;
			radarY = easing.easeOutElastic(time, radarStart, 55, duration);
		}
		var radarImage = data.images.get("radar");
		context.drawImage(radarImage, 5, radarY);

		// radar screen
		if(time >= duration){

			var angularVelocity = -((Math.PI * 2) / period);
			var distanceThisFrame = angularVelocity * elapsed;
			angle += distanceThisFrame;

			var cx = 5 + Math.floor(radarImage.width / 2);
			var cy = radarY + Math.floor(radarImage.height / 2);
			var x = radius * Math.cos(angle);
			var y = radius * Math.sin(angle);

			var linePoints = {
				"startX": cx,
				"startY": cy,
				"endX": cx + x,
				"endY": cy + y
			};
			drawLine(context, linePoints, "1px", "#6abd44");

			var playerPosition = data.entities.get(entity, "position");

			data.entities.find("position").forEach(function(id) {
				var entityType = data.entities.get(id, "type");
				var entitySticky = data.entities.get(id, "sticky");
				var entityPlayer = data.entities.get(id, "player");
				var entityPosition = data.entities.get(id, "position");

				if ((entityType !== "trash" && entityType !== "obstacle") || entitySticky || entityPlayer) {
					return;
				}

				var dx = entityPosition.x - playerPosition.x;
				var dy = entityPosition.y - playerPosition.y;

				var max = 1000 * 1000;
				var dist = Math.max(Math.min((dx * dx + dy * dy), max), -max);
				var scaledDist = dist / max * (radius - 3);

				var angle = Math.atan2(entityPosition.y - playerPosition.y, entityPosition.x - playerPosition.x);

				var ex = scaledDist * Math.cos(angle);
				var ey = scaledDist * Math.sin(angle);

				context.fillStyle = "#6abd44";
				if (entityType === "obstacle") {
					context.fillStyle = "red";
				}
				context.fillRect(cx + ex - 1, cy + ey - 1, 3, 3);
			});
		}
	}, "player");
};

function drawLine(context, ray, width, color) {
	context.strokeStyle = color;
	context.lineWidth = width;
	context.beginPath();
	context.moveTo(ray.startX, ray.startY);
	context.lineTo(ray.endX, ray.endY);
	context.stroke();
}
<|endoftext|>


<commit_before>angular.module('sparrow')
.controller('UnTimedCtrl', function() {

})
.component('untimed', {
  controller: 'UnTimedCtrl',
  templateUrl: 'templates/untimed.html'
});<commit_msg>Add addWorkout() which help create a template of untimed workout<commit_after>angular.module('sparrow')
.controller('UnTimedCtrl', function() {
  this.workout = [];
  this.addWorkout = function() {
    var obj = {};
    obj.activity = this.activity;
    obj.sets = this.sets;
    obj.reps = this.reps;
    this.workout.push(obj);
  };
})
.component('untimed', {
  controller: 'UnTimedCtrl',
  templateUrl: 'templates/untimed.html'
});<|endoftext|>


<commit_before>var genUuid = require('node-uuid');
var fs = require('fs');

function time()
{
  return Math.floor(new Date().getTime() / 1000);
}

var eventLogger = {
	logPath: null,
	init: function(path)
	{
		this.logPath = path;
	},
	_writeLog: function(level, category, sortCode, data)
	{
		if (!category)
		{
			category = '';
		}

		if (!sortCode)
		{
			sortCode = '';
		}

		if (this.logPath)
		{
			var uuid = genUuid.v4();

			var fileContents = JSON.stringify({
				uuid: uuid,
				level: level,
				time: time(),
				category: category,
				sortCode: sortCode,
				data: data
			});

			fs.writeFile(this.logPath + '/' + uuid + '.json', fileContents, 'utf8');
		}
	},
	info: function(data, category, sortCode)
	{
		return this._writeLog(2, category, sortCode, data);
	}
}

// Make a Node module, if possible.
if (typeof exports === 'object' && exports)
{
	module.exports = eventLogger;
}<commit_msg>added a header to the top of the file.<commit_after>/**
* @project eventLogger client
* @version 0.1
* @url https://github.com/keverw/eventLogger
* @about A Node.js eventLogger client
**/

var genUuid = require('node-uuid');
var fs = require('fs');

function time()
{
  return Math.floor(new Date().getTime() / 1000);
}

var eventLogger = {
	logPath: null,
	init: function(path)
	{
		this.logPath = path;
	},
	_writeLog: function(level, category, sortCode, data)
	{
		if (!category)
		{
			category = '';
		}

		if (!sortCode)
		{
			sortCode = '';
		}

		if (this.logPath)
		{
			var uuid = genUuid.v4();

			var fileContents = JSON.stringify({
				uuid: uuid,
				level: level,
				time: time(),
				category: category,
				sortCode: sortCode,
				data: data
			});

			fs.writeFile(this.logPath + '/' + uuid + '.json', fileContents, 'utf8');
		}
	},
	info: function(data, category, sortCode)
	{
		return this._writeLog(2, category, sortCode, data);
	}
}

// Make a Node module, if possible.
if (typeof exports === 'object' && exports)
{
	module.exports = eventLogger;
}<|endoftext|>


<commit_before>/*   RSence
 *   Copyright 2008 Riassence Inc.
 *   http://riassence.com/
 *
 *   You should have received a copy of the GNU General Public License along
 *   with this software package. If not, contact licensing@riassence.com
 */

/*** = Description
  ** An application designed to display errors.
  **
  ** Used automatically by the server to report issues.
  ** Stops COMM.Transporter and displays a HWindow with the message contained.
  ** Has two buttons: *Reset Session* and *Reload*
  **
  ** = Usage
  **   jsLoader.load('servermessage');
  **   ReloadApp.nu( 'Session Timeout', 'Your session has timed out', '/' );
  **
**/
var//RSence
ReloadApp = HApplication.extend({

/** Reloads the page using the +_url+ given in the +constructor+.
  **/
  reload: function(){
    var _url = this._url;
    if((!_url)||(_url==='/')){
      window.location.reload(true);
    }
    else {
      window.location.href = _url;
    }
  },

/** = Description
  * Reset the session.
  *
  * Resets the session by calling the hello/goodbye url on the server.
  * The server reads the cookie key and deletes the session bound to it.
  *
  * Reloads the page after a successful request.
  *
  **/
  reset_session: function(){
    COMM.request(
      COMM.Transporter.HelloUrl + '/goodbye', {
        method: 'POST',
        body: ('ses_key='+COMM.Session.ses_key),
        async: true,
        onSuccess: function(){
          window.location.reload(true);
        },
        onFailure: function(){
          window.location.reload(true);
        }
    });
  },

/** = Description
  * Constructs the ReloadApp.
  *
  * Creates an application with a window titled +_title+,
  * containing the +_message+ and *Reset Session* and *Reload*
  * buttons. The +_url+ is the url to load when any of the
  * buttons are pressed.
  *
  * = Parameters
  * +_title+::    The title of the message.
  * +_message+::  The message text content.
  * +_url+::      The url the buttons load when pressed.
  *
  **/
  constructor: function( _title, _message, _url ){
    var _this = this;
    _this.base();
    _this._title = _title;
    _this._message = _message;
    _this._url = _url;
    var _winWidth  = ELEM.windowSize()[0],
        _winHeight = ELEM.windowSize()[1],
        _halfWidth = parseInt(_winWidth/2,10),
        _halfHeight = parseInt(_winHeight/2,10),
        _alertWidth  = 400,
        _alertHeight = 270,
        _alertX      = _halfWidth - 200,
        _alertY      = _halfHeight - 150;
    if(_alertX<10){_alertX = 10;}
    if(_alertY<10){_alertY = 10;}
    HSheet.extend({
      drawSubviews: function(){
        var _this = this,
            _elemId = _this.markupElemIds['subview'],
            _alertIcon = ELEM.make( _elemId ),
            _alertTitle = ELEM.make( _elemId ),
            _alertMessage = ELEM.make( _elemId ),
            _iconUrl = _this.getThemeGfxFile('reloadapp_warning.png');
        _this.setStyle('font-family','Arial, sans-serif');
        _this.setStyle('color','#000');
        _this.setStyle('font-size','13px');
        ELEM.setCSS(_alertIcon,'position:absolute;left:8px;top:8px;width:48px;height:48px;background-image:url('+_iconUrl+');');
        ELEM.setCSS(_alertTitle,'position:absolute;left:64px;top:8px;width:300px;height:24px;line-height:24px;vertical-align:middle;text-align:center;font-weight:bold;overflow:hidden;text-overflow:ellipsis;line-wrap:nowrap;');
        ELEM.setHTML(_alertTitle,_this.app._title);
        ELEM.setCSS(_alertMessage,'position:absolute;left:64px;top:42px;width:332px;height:186px;border-bottom:1px dotted #999;line-height:17px;vertical-align:middle;overflow:auto;');
        ELEM.setHTML(_alertMessage,_this.app._message);
        HButton.extend({
          click: this.app.reload
        }).nu(
          HRect.nu(280, 234, 380, 258 ),
          _this, {
            label: 'Reload',
            events: {
              click: true
            }
          }
        );
        HButton.extend({
          click: this.app.reset_session
        }).nu(
          HRect.nu(20, 234, 170, 258 ),
          _this, {
            label: 'Reset session',
            events: {
              click: true
            }
          }
        );
      }
    }).nu(
      HRect.nu( _alertX, _alertY, _alertX+_alertWidth, _alertY+_alertHeight ),
      _this, {
        label: _title,
        value: 0
        // minSize: [_alertWidth,_alertHeight],
        // maxSize: [_alertWidth,_alertHeight],
        // enabled: true,
        // closeButton: true,
        // noResize: true
      }
    );

    COMM.Transporter.stop = true;
  },

/** Re-focuses the window.
  **/
  onIdle: function(){
    if(this['_alertWindow']){
      HSystem.windowFocus(this._alertWindow);
    }
  }
});
<commit_msg>Ensures the error message is always in the front.<commit_after>/*   RSence
 *   Copyright 2008 Riassence Inc.
 *   http://riassence.com/
 *
 *   You should have received a copy of the GNU General Public License along
 *   with this software package. If not, contact licensing@riassence.com
 */

/*** = Description
  ** An application designed to display errors.
  **
  ** Used automatically by the server to report issues.
  ** Stops COMM.Transporter and displays a HWindow with the message contained.
  ** Has two buttons: *Reset Session* and *Reload*
  **
  ** = Usage
  **   jsLoader.load('servermessage');
  **   ReloadApp.nu( 'Session Timeout', 'Your session has timed out', '/' );
  **
**/
var//RSence
ReloadApp = HApplication.extend({

/** Reloads the page using the +_url+ given in the +constructor+.
  **/
  reload: function(){
    var _url = this._url;
    if((!_url)||(_url==='/')){
      window.location.reload(true);
    }
    else {
      window.location.href = _url;
    }
  },

/** = Description
  * Reset the session.
  *
  * Resets the session by calling the hello/goodbye url on the server.
  * The server reads the cookie key and deletes the session bound to it.
  *
  * Reloads the page after a successful request.
  *
  **/
  reset_session: function(){
    COMM.request(
      COMM.Transporter.HelloUrl + '/goodbye', {
        method: 'POST',
        body: ('ses_key='+COMM.Session.ses_key),
        async: true,
        onSuccess: function(){
          window.location.reload(true);
        },
        onFailure: function(){
          window.location.reload(true);
        }
    });
  },

/** = Description
  * Constructs the ReloadApp.
  *
  * Creates an application with a window titled +_title+,
  * containing the +_message+ and *Reset Session* and *Reload*
  * buttons. The +_url+ is the url to load when any of the
  * buttons are pressed.
  *
  * = Parameters
  * +_title+::    The title of the message.
  * +_message+::  The message text content.
  * +_url+::      The url the buttons load when pressed.
  *
  **/
  constructor: function( _title, _message, _url ){
    var _this = this;
    _this.base();
    _this._title = _title;
    _this._message = _message;
    _this._url = _url;
    var _winWidth  = ELEM.windowSize()[0],
        _winHeight = ELEM.windowSize()[1],
        _halfWidth = parseInt(_winWidth/2,10),
        _halfHeight = parseInt(_winHeight/2,10),
        _alertWidth  = 400,
        _alertHeight = 270,
        _alertX      = _halfWidth - 200,
        _alertY      = _halfHeight - 150;
    if(_alertX<10){_alertX = 10;}
    if(_alertY<10){_alertY = 10;}
    _this._alertSheet = HSheet.extend({
      drawSubviews: function(){
        var _this = this,
            _elemId = _this.markupElemIds['subview'],
            _alertIcon = ELEM.make( _elemId ),
            _alertTitle = ELEM.make( _elemId ),
            _alertMessage = ELEM.make( _elemId ),
            _iconUrl = _this.getThemeGfxFile('reloadapp_warning.png');
        _this.setStyle('font-family','Arial, sans-serif');
        _this.setStyle('color','#000');
        _this.setStyle('font-size','13px');
        ELEM.setCSS(_alertIcon,'position:absolute;left:8px;top:8px;width:48px;height:48px;background-image:url('+_iconUrl+');');
        ELEM.setCSS(_alertTitle,'position:absolute;left:64px;top:8px;width:300px;height:24px;line-height:24px;vertical-align:middle;text-align:center;font-weight:bold;overflow:hidden;text-overflow:ellipsis;line-wrap:nowrap;');
        ELEM.setHTML(_alertTitle,_this.app._title);
        ELEM.setCSS(_alertMessage,'position:absolute;left:64px;top:42px;width:332px;height:186px;border-bottom:1px dotted #999;line-height:17px;vertical-align:middle;overflow:auto;');
        ELEM.setHTML(_alertMessage,_this.app._message);
        HButton.extend({
          click: this.app.reload
        }).nu(
          HRect.nu(280, 234, 380, 258 ),
          _this, {
            label: 'Reload',
            events: {
              click: true
            }
          }
        );
        HButton.extend({
          click: this.app.reset_session
        }).nu(
          HRect.nu(20, 234, 170, 258 ),
          _this, {
            label: 'Reset session',
            events: {
              click: true
            }
          }
        );
      }
    }).nu(
      HRect.nu( _alertX, _alertY, _alertX+_alertWidth, _alertY+_alertHeight ),
      _this, {
        label: _title,
        value: 0
        // minSize: [_alertWidth,_alertHeight],
        // maxSize: [_alertWidth,_alertHeight],
        // enabled: true,
        // closeButton: true,
        // noResize: true
      }
    );

    COMM.Transporter.stop = true;
  },

/** Re-focuses the window.
  **/
  onIdle: function(){
    if(this['_alertSheet']){
      this._alertSheet.bringToFront();
    }
  }
});
<|endoftext|>


<commit_before>#!/usr/bin/env node

/* eslint-disable import/no-extraneous-dependencies */
/* eslint-disable no-console */
/* eslint-disable @typescript-eslint/no-var-requires */

const chalk = require('chalk');
const fs = require('fs');
const path = require('path');
const sass = require('sass');

const ROOT = path.join(__dirname, '..');
const OUT_DIR = path.join(ROOT, 'css');
const STYLES_DIR = path.join(ROOT, 'styles');

function buildCSS(options) {
  // Get the base filename.
  let filename = options.file.split(/\/|\\/).pop().replace('.scss', '');

  // Denote minified CSS.
  if (options.outputStyle === 'compressed') {
    filename = `${filename}.min`;
  }

  // Render CSS files.
  sass.render(options, (err, result) => {
    if (err) {
      console.log(err);
      process.exit(1);
    }

    fs.writeFileSync(path.join(OUT_DIR, `${filename}.css`), result.css);
  });
}

// Create the output directory if it doesn't exist.
if (!fs.existsSync(OUT_DIR)) {
  fs.mkdirSync(OUT_DIR);
}

console.log(chalk.cyan('Building CSS files...\n'));

fs.readdirSync(STYLES_DIR).forEach((filename) => {
  const file = path.join(STYLES_DIR, filename);

  // Include the .scss files in the package by simply copying them over.
  fs.copyFileSync(file, path.join(OUT_DIR, filename));

  // Output both expanded and minified versions.
  ['compressed', 'expanded'].forEach((outputStyle) => {
    buildCSS({
      file,
      outputStyle,
    });
  });
});
<commit_msg>Use `sass.compile` instead of `sass.render`<commit_after>#!/usr/bin/env node

/* eslint-disable import/no-extraneous-dependencies */
/* eslint-disable no-console */
/* eslint-disable @typescript-eslint/no-var-requires */

const chalk = require('chalk');
const fs = require('fs');
const path = require('path');
const sass = require('sass');

const ROOT = path.join(__dirname, '..');
const OUT_DIR = path.join(ROOT, 'css');
const STYLES_DIR = path.join(ROOT, 'styles');

console.log(chalk.cyan('Building CSS files...\n'));

// Create the output directory if it doesn't exist.
if (!fs.existsSync(OUT_DIR)) {
  fs.mkdirSync(OUT_DIR);
}

fs.readdirSync(STYLES_DIR).forEach((filename) => {
  const file = path.join(STYLES_DIR, filename);

  // Include the .scss files in the package by simply copying them over.
  fs.copyFileSync(file, path.join(OUT_DIR, filename));

  // Output both expanded and minified versions.
  ['compressed', 'expanded'].forEach((style) => {
    // Get the base filename.
    let name = filename.replace('.scss', '');
    if (style === 'compressed') {
      // Denote minified CSS.
      name += '.min';
    }

    const result = sass.compile(file, { style });

    fs.writeFileSync(path.join(OUT_DIR, `${name}.css`), result.css);
  });
});

console.log(chalk.cyan('Done.\n'));
<|endoftext|>


<commit_before>(function () {

  var Kran = {}

  var reset = Kran.reset = function() {
    components.length = 0
    collectionsRequieringComp.length = 0
    entity.length = 0
    entityCollections = []
    systems.length = 0
    systems.all.length = 0
  }

  // ***********************************************
  // Component
  //
  var components = []
  var collectionsRequieringComp = []

  var component = Kran.component = function(comp) {
    if (typeof(comp) === "object") {
      var obj = {}
      for (prop in comp) {
        obj[prop] = createComponent(comp[prop])
      }
      return obj
    } else {
      return createComponent(comp)
    }
  }

  var createComponent = function(comp) {
    if (isFunc(comp) || typeof(comp) === "string") {
      components.push(comp)
    } else if (comp === true || comp === undefined) {
      components.push(true)
    } else {
      throw new TypeError("Argument " + comp + " is given but not a function")
    }
    collectionsRequieringComp.push([])
    return components.length - 1
  }

  var checkComponentExistence = function (compId) {
    if (components[compId] !== undefined) {
      return compId
    } else {
      throw new Error("Component " + compId + " does no exist")
    }
  }

  // ***********************************************
  // Entity collections
  //
  var entityCollections = {}

  var EntityCollection = function(comps) {
    this.comps = comps
    this.buffer = new Array(comps.length + 2)
    this.ents = new LinkedList()
    this.arrival = []

    // Mark components that are part of this collection
    comps.forEach(function (compId) {
      checkComponentExistence(compId)
      collectionsRequieringComp[compId].push(this)
    }, this)
  }

  EntityCollection.prototype.callWithComps = function(ent, func, context, ev) {
    if (ev) this.buffer[0] = ev
    for (var i = 0; i < this.comps.length; i++) {
      this.buffer[i + (ev ? 1 : 0)] = ent.comps[this.comps[i]]
    }
    this.buffer[i] = ent
    func.apply(context, this.buffer)
  }

  EntityCollection.prototype.forEachWithComps = function(every, context, ev) {
    this.ents.forEach(function (ent) { // Call every
      this.callWithComps(ent, every, context, ev)
    }, this)
  }

  var getEntityCollection = Kran.getEntityCollection = function(comps) {
    comps = wrapInArray(comps)
    var key = comps.slice(0).sort().toString()
    if (entityCollections[key] === undefined) {
      entityCollections[key] = new EntityCollection(comps)
    }
    return entityCollections[key]
  }

  // ***********************************************
  // System
  //
  var systems = []
  var system = {}

  var runGroup = function() {
    for (var i = 0; i < this.length; i++) {
      systems[this[i]].run()
    }
  }

  var system = Kran.system = function(props) {
    var id = systems.length
    props.run = runSystem

    if (props.components !== undefined) {
      props.components = props.components
      props.coll = getEntityCollection(props.components)
      if (isFunc(props.arrival)) props.coll.arrival.push(props.arrival)
    }
    if (props.on) {
      props.on = wrapInArray(props.on)
      props.on.forEach(function (event) {
        window.addEventListener(event, props.run.bind(props))
      })
    } else {
      // Only systems not listening for events are put in the all group
      systems.all.push(id)
    }
    if (props.group) {
      if (!systems[props.group]) {
        initGroup(props.group)
      }
      systems[props.group].push(id)
    }
    systems.push(props)
  }

  var initGroup = function (name) {
    systems[name] = []
    system[name] = runGroup.bind(systems[name])
  }

  initGroup('all')

  var runSystem = function(ev) {
    if (this.coll !== undefined &&
        this.coll.ents.length == 0) {
      return
    }
    if (ev && ev instanceof CustomEvent) {
      ev = ev.detail
    }
    if (isFunc(this.pre)) this.pre(ev)
    if (isFunc(this.every)) {
      this.coll.forEachWithComps(this.every, this, ev)
    }
    if (isFunc(this.post)) this.post(ev)
  }

  // ***********************************************
  // Entity
  //
  var Entity = function() {
    this.comps = new Array(components.length)
    this.belongsTo = new LinkedList()
  }

  Entity.prototype.add = function(compId, arg1, arg2, arg3, arg4, arg5, arg6, arg7) {
    compId = processCompId(compId)
    if (this.comps[compId] !== undefined) throw new Error("The entity already has the component")
    if (isFunc(components[compId])) {
      this.comps[compId] = new components[compId](arg1, arg2, arg3, arg4, arg5, arg6, arg7)
      this.comps[compId].id = compId
    } else if (typeof components[compId] === "string") {
      var obj = { id: compId }
      obj[components[compId]] = arg1
      this.comps[compId] = obj
    } else {
      this.comps[compId] = compId
    }
    collectionsRequieringComp[compId].forEach(function (coll) {
      if (qualifiesForCollection(this, coll.comps)) {
        addEntityToCollection(this, coll)
      }
    }, this)
    return this
  }

  Entity.prototype.get = function(compId) {
    compId = processCompId(compId)
    return this.comps[compId]
  }

  Entity.prototype.has = function(compId) {
    compId = processCompId(compId)
    return this.comps[compId] !== undefined
  }

  Entity.prototype.get = function(compId) {
    compId = processCompId(compId)
    return this.comps[compId]
  }

  Entity.prototype.has = function(compId) {
    compId = processCompId(compId)
    return this.comps[compId] !== undefined
  }

  Entity.prototype.remove = function(compId) {
    compId = processCompId(compId)
    if (this.comps[compId] === undefined) throw new Error("The entity already has the component")
    this.comps[compId] = undefined
    this.belongsTo.forEach(function (collBelonging, elm) {
      if (!qualifiesForCollection(this, collBelonging.comps)) {
        collBelonging.entry.remove()
        elm.remove()
      }
    }, this)
    return this
  }

  Entity.prototype.trigger = function (compId, arg1, arg2, arg3, arg4, arg5, arg6, arg7) {
    compId = processCompId(compId)
    this.add(compId, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
    this.remove(compId)
  }

  Entity.prototype.delete = function() {
    this.belongsTo.forEach(function (collBelonging, elm) {
      collBelonging.entry.remove()
    })
  }

  var entity = Kran.entity = function () {
    var ent = new Entity()
    return ent
  }

  var CollectionBelonging = function (comps, entry) {
    this.comps = comps; this.entry = entry
  }

  var addEntityToCollection = function(ent, coll) {
    coll.arrival.forEach(function (func) {
      coll.callWithComps(ent, func)
    })
    var collEntry = coll.ents.add(ent)
    ent.belongsTo.add(new CollectionBelonging(coll.comps, collEntry))
  }

  var processCompId = function(compId) {
    if (typeof(compId) === "number") {
      return checkComponentExistence(compId)
    } else if (typeof(compId) == "object" &&
               compId.id !== undefined) {
      return checkComponentExistence(compId.id)
    }
    throw new TypeError("Component " + compId + " does not contain any id")
  }

  var qualifiesForCollection = function (ent, comps) {
    return comps.every(function (compId) {
      if (ent.comps[compId] === undefined) {
        return false
      }
      return true
    })
  }

  // ***********************************************
  // Event system
  //
  Kran.trigger = function(name, data) {
    var event = new CustomEvent(name, { detail: data })
    window.dispatchEvent(event)
  }

  // ***********************************************
  // Helper functions
  //
  var isFunc = function(func) {
    if (typeof(func) === 'function') {
      return true
    } else {
      return false
    }
  }

  var wrapInArray = function(arg) {
    if (arg instanceof Array) {
      return arg
    } else {
      return [arg]
    }
  }

  // ***********************************************
  // Linked list
  //
  var LinkedList = Kran.LinkedList = function () {
    this.head = null
    this.tail = null
    this.length = 0
  }

  function Element(data, list) {
    this.data = data
    this.list = list
    this.prev = list.tail
    this.next = null
  }

  Element.prototype.remove = function() {
    if (this.prev) {
      this.prev.next = this.next
    } else {
      this.list.head = this.next
    }
    if (this.next) {
      this.next.prev = this.prev
    } else {
      this.list.tail = this.prev
    }
    this.list.length--
  }

  LinkedList.prototype.add = function(data) {
    var elm = new Element(data, this)
    if (this.tail) {
      this.tail.next = elm
    } else {
      this.head = elm
    }
    this.tail = elm
    this.length++
    return elm
  }

  LinkedList.prototype.forEach = function(func, context) {
    var elm, nextElm = this.head

    while (nextElm != null) {
      elm = nextElm
      nextElm = elm.next
      func.call(context, elm.data, elm)
    }
  }

  // ***********************************************
  // Export
  //
  if (typeof module === "object" && // CommonJS
      typeof module.exports === "object") {
    module.exports = Kran
  } else if (typeof define === "function" && define.amd) { // AMD module
    define("kran", [], function() { return Kran } )
  } else { // Otherwise just attach to the global object
    this.Kran = Kran
  }

}).call(this)
<commit_msg>Fix bug where entity argument overrides last component in every hook when an event is present plus style cleanup<commit_after>(function () {

  var Kran = {}

  var reset = Kran.reset = function() {
    components.length = 0
    collectionsRequieringComp.length = 0
    entity.length = 0
    entityCollections = []
    systems.length = 0
    systems.all.length = 0
  }

  // ***********************************************
  // Component
  //
  var components = []
  var collectionsRequieringComp = []

  var component = Kran.component = function(comp) {
    if (typeof(comp) === "object") {
      var obj = {}
      for (var prop in comp) {
        obj[prop] = createComponent(comp[prop])
      }
      return obj
    } else {
      return createComponent(comp)
    }
  }

  var createComponent = function(comp) {
    if (isFunc(comp) || typeof(comp) === "string") {
      components.push(comp)
    } else if (comp === true || comp === undefined) {
      components.push(true)
    } else {
      throw new TypeError("Argument " + comp + " is given but not a function")
    }
    collectionsRequieringComp.push([])
    return components.length - 1
  }

  var checkComponentExistence = function (compId) {
    if (components[compId] !== undefined) {
      return compId
    } else {
      throw new Error("Component " + compId + " does no exist")
    }
  }

  // ***********************************************
  // Entity collections
  //
  var entityCollections = {}

  var EntityCollection = function(comps) {
    this.comps = comps
    this.buffer = new Array(comps.length + 2)
    this.ents = new LinkedList()
    this.arrival = []

    // Mark components that are part of this collection
    comps.forEach(function (compId) {
      checkComponentExistence(compId)
      collectionsRequieringComp[compId].push(this)
    }, this)
  }

  EntityCollection.prototype.callWithComps = function(ent, func, context, ev) {
    if (ev) this.buffer[0] = ev
    for (var i = 0; i < this.comps.length; i++) {
      this.buffer[i + (ev ? 1 : 0)] = ent.comps[this.comps[i]]
    }
    this.buffer[i + (ev ? 1 : 0)] = ent
    func.apply(context, this.buffer)
  }

  EntityCollection.prototype.forEachWithComps = function(every, context, ev) {
    this.ents.forEach(function (ent) { // Call every
      this.callWithComps(ent, every, context, ev)
    }, this)
  }

  var getEntityCollection = Kran.getEntityCollection = function(comps) {
    comps = wrapInArray(comps)
    var key = comps.slice(0).sort().toString()
    if (entityCollections[key] === undefined) {
      entityCollections[key] = new EntityCollection(comps)
    }
    return entityCollections[key]
  }

  // ***********************************************
  // System
  //
  var systems = []

  var runGroup = function() {
    for (var i = 0; i < this.length; i++) {
      systems[this[i]].run()
    }
  }

  var system = Kran.system = function(props) {
    var id = systems.length
    props.run = runSystem

    if (props.components !== undefined) {
      props.components = props.components
      props.coll = getEntityCollection(props.components)
      if (isFunc(props.arrival)) props.coll.arrival.push(props.arrival)
    }
    if (props.on) {
      props.on = wrapInArray(props.on)
      props.on.forEach(function (event) {
        window.addEventListener(event, props.run.bind(props))
      })
    } else {
      // Only systems not listening for events are put in the all group
      systems.all.push(id)
    }
    if (props.group) {
      if (!systems[props.group]) {
        initGroup(props.group)
      }
      systems[props.group].push(id)
    }
    systems.push(props)
  }

  var initGroup = function (name) {
    systems[name] = []
    system[name] = runGroup.bind(systems[name])
  }

  initGroup('all')

  var runSystem = function(ev) {
    if (this.coll !== undefined &&
        this.coll.ents.length === 0) {
      return
    }
    if (ev && ev instanceof CustomEvent) {
      ev = ev.detail
    }
    if (isFunc(this.pre)) this.pre(ev)
    if (isFunc(this.every)) {
      this.coll.forEachWithComps(this.every, this, ev)
    }
    if (isFunc(this.post)) this.post(ev)
  }

  // ***********************************************
  // Entity
  //
  var Entity = function() {
    this.comps = new Array(components.length)
    this.belongsTo = new LinkedList()
  }

  Entity.prototype.add = function(compId, arg1, arg2, arg3, arg4, arg5, arg6, arg7) {
    compId = processCompId(compId)
    if (this.comps[compId] !== undefined) throw new Error("The entity already has the component")
    if (isFunc(components[compId])) {
      this.comps[compId] = new components[compId](arg1, arg2, arg3, arg4, arg5, arg6, arg7)
      this.comps[compId].id = compId
    } else if (typeof components[compId] === "string") {
      var obj = { id: compId }
      obj[components[compId]] = arg1
      this.comps[compId] = obj
    } else {
      this.comps[compId] = compId
    }
    collectionsRequieringComp[compId].forEach(function (coll) {
      if (qualifiesForCollection(this, coll.comps)) {
        addEntityToCollection(this, coll)
      }
    }, this)
    return this
  }

  Entity.prototype.get = function(compId) {
    compId = processCompId(compId)
    return this.comps[compId]
  }

  Entity.prototype.has = function(compId) {
    compId = processCompId(compId)
    return this.comps[compId] !== undefined
  }

  Entity.prototype.get = function(compId) {
    compId = processCompId(compId)
    return this.comps[compId]
  }

  Entity.prototype.has = function(compId) {
    compId = processCompId(compId)
    return this.comps[compId] !== undefined
  }

  Entity.prototype.remove = function(compId) {
    compId = processCompId(compId)
    if (this.comps[compId] === undefined) throw new Error("The entity already has the component")
    this.comps[compId] = undefined
    this.belongsTo.forEach(function (collBelonging, elm) {
      if (!qualifiesForCollection(this, collBelonging.comps)) {
        collBelonging.entry.remove()
        elm.remove()
      }
    }, this)
    return this
  }

  Entity.prototype.trigger = function (compId, arg1, arg2, arg3, arg4, arg5, arg6, arg7) {
    compId = processCompId(compId)
    this.add(compId, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
    this.remove(compId)
  }

  Entity.prototype.delete = function() {
    this.belongsTo.forEach(function (collBelonging, elm) {
      collBelonging.entry.remove()
    })
  }

  var entity = Kran.entity = function () {
    var ent = new Entity()
    return ent
  }

  var CollectionBelonging = function (comps, entry) {
    this.comps = comps; this.entry = entry
  }

  var addEntityToCollection = function(ent, coll) {
    coll.arrival.forEach(function (func) {
      coll.callWithComps(ent, func)
    })
    var collEntry = coll.ents.add(ent)
    ent.belongsTo.add(new CollectionBelonging(coll.comps, collEntry))
  }

  var processCompId = function(compId) {
    if (typeof(compId) === "number") {
      return checkComponentExistence(compId)
    } else if (typeof(compId) == "object" &&
               compId.id !== undefined) {
      return checkComponentExistence(compId.id)
    }
    throw new TypeError("Component " + compId + " does not contain any id")
  }

  var qualifiesForCollection = function (ent, comps) {
    return comps.every(function (compId) {
      if (ent.comps[compId] === undefined) {
        return false
      }
      return true
    })
  }

  // ***********************************************
  // Event system
  //
  Kran.trigger = function(name, data) {
    var event = new CustomEvent(name, { detail: data })
    window.dispatchEvent(event)
  }

  // ***********************************************
  // Helper functions
  //
  var isFunc = function(func) {
    if (typeof(func) === 'function') {
      return true
    } else {
      return false
    }
  }

  var wrapInArray = function(arg) {
    if (arg instanceof Array) {
      return arg
    } else {
      return [arg]
    }
  }

  // ***********************************************
  // Linked list
  //
  var LinkedList = Kran.LinkedList = function () {
    this.head = null
    this.tail = null
    this.length = 0
  }

  function Element(data, list) {
    this.data = data
    this.list = list
    this.prev = list.tail
    this.next = null
  }

  Element.prototype.remove = function() {
    if (this.prev) {
      this.prev.next = this.next
    } else {
      this.list.head = this.next
    }
    if (this.next) {
      this.next.prev = this.prev
    } else {
      this.list.tail = this.prev
    }
    this.list.length--
  }

  LinkedList.prototype.add = function(data) {
    var elm = new Element(data, this)
    if (this.tail) {
      this.tail.next = elm
    } else {
      this.head = elm
    }
    this.tail = elm
    this.length++
    return elm
  }

  LinkedList.prototype.forEach = function(func, context) {
    var elm, nextElm = this.head

    while (nextElm !== null) {
      elm = nextElm
      nextElm = elm.next
      func.call(context, elm.data, elm)
    }
  }

  // ***********************************************
  // Export
  //
  if (typeof module === "object" && // CommonJS
      typeof module.exports === "object") {
    module.exports = Kran
  } else if (typeof define === "function" && define.amd) { // AMD module
    define("kran", [], function() { return Kran } )
  } else { // Otherwise just attach to the global object
    this.Kran = Kran
  }

}).call(this)
<|endoftext|>