<commit_before>/**
 * @augments JsSIP
 * @class Class creating a SIP URI.
 *
 * @param {String} [scheme]
 * @param {String} [user]
 * @param {String} host
 * @param {String} [port]
 * @param {Object} [parameters]
 * @param {Object} [headers]
 *
 */
JsSIP.URI = function(scheme, user, host, port, parameters, headers) {
  var param, header;

  // Checks
  if(!host) {
    throw new TypeError('missing or invalid "host" parameter');
  }

  this.scheme = scheme || JsSIP.C.SIP;

  // Initialize parameters
  this.parameters = {};
  this.headers = {};

  for (param in parameters) {
    this.setParam(param, parameters[param]);
  }

  for (header in headers) {
    this.setHeader(header, headers[header]);
  }

  Object.defineProperties(this, {
    scheme: {
      get: function(){ return scheme; },
      set: function(value){
        scheme = value.toLowerCase();
      }
    },

    user: {
      get: function(){ return user; },
      set: function(value){
        user = value;
      }
    },

    host: {
      get: function(){ return host; },
      set: function(value){
        host = value.toLowerCase();
      }
    },
    port: {
      get: function(){ return port; },
      set: function(value){
        port = parseInt(value,10);
      }
    }
  });
};
JsSIP.URI.prototype = {
  setParam: function(key, value) {
    if(key) {
      this.parameters[key.toLowerCase()] = (typeof value === 'undefined' || value === null) ? null : value.toString().toLowerCase();
    }
  },

  getParam: function(key) {
    if(key) {
      return this.parameters[key.toLowerCase()];
    }
  },

  hasParam: function(key) {
    if(key) {
      return (this.parameters.hasOwnProperty(key.toLowerCase()) && true) || false;
    }
  },

  deleteParam: function(parameter) {
    var value;
    parameter = parameter.toLowerCase();
    if (this.parameters.hasOwnProperty(parameter)) {
      value = this.parameters[parameter];
      delete this.parameters[parameter];
      return value;
    }
  },

  clearParams: function() {
    this.parameters = {};
  },

  setHeader: function(name, value) {
    this.headers[JsSIP.Utils.headerize(name)] = (value instanceof Array) ? value : [value];
  },

  getHeader: function(name) {
    if(name) {
      return this.headers[JsSIP.Utils.headerize(name)];
    }
  },

  hasHeader: function(name) {
    if(name) {
      return (this.headers.hasOwnProperty(name.toLowerCase()) && true) || false;
    }
  },

  deleteHeader: function(header) {
    var value;
    header = JsSIP.Utils.headerize(header);
    if(this.headers.hasOwnProperty(header)) {
      value = this.headers[header];
      delete this.headers[header];
      return value;
    }
  },

  clearHeaders: function() {
    this.headers = {};
  },

  clone: function() {
    return new JsSIP.URI(
      this.scheme,
      this.user,
      this.host,
      this.port,
      window.JSON.parse(window.JSON.stringify(this.parameters)),
      window.JSON.parse(window.JSON.stringify(this.headers)));
  },

  toString: function(){
    var header, parameter, idx, uri,
      headers = [];

    uri  = this.scheme + ':';
    uri += this.user ? JsSIP.Utils.escapeUser(this.user) + '@' : '';
    uri += this.host;
    uri += this.port ? ':' + this.port : '';

    for (parameter in this.parameters) {
      uri += ';'+ parameter;
      uri += (this.parameters[parameter] === null) ? '' : '=' + this.parameters[parameter];
    }

    for(header in this.headers) {
      for(idx in this.headers[header]) {
        headers.push(header + '=' + this.headers[header][idx]);
      }
    }

    if (headers.length > 0) {
      uri += '?' + headers.join('&');
    }

    return uri;
  },
  toAor: function(){
      var aor;

      aor  = this.scheme + ':';
      aor += this.user ? JsSIP.Utils.escapeUser(this.user) + '@' : '';
      aor += this.host;

      return aor;
  }
};<commit_msg>Fix URI schema default value.<commit_after>/**
 * @augments JsSIP
 * @class Class creating a SIP URI.
 *
 * @param {String} [scheme]
 * @param {String} [user]
 * @param {String} host
 * @param {String} [port]
 * @param {Object} [parameters]
 * @param {Object} [headers]
 *
 */
JsSIP.URI = function(scheme, user, host, port, parameters, headers) {
  var param, header;

  // Checks
  if(!host) {
    throw new TypeError('missing or invalid "host" parameter');
  }

  scheme = scheme || JsSIP.C.SIP;

  // Initialize parameters
  this.parameters = {};
  this.headers = {};

  for (param in parameters) {
    this.setParam(param, parameters[param]);
  }

  for (header in headers) {
    this.setHeader(header, headers[header]);
  }

  Object.defineProperties(this, {
    scheme: {
      get: function(){ return scheme; },
      set: function(value){
        scheme = value.toLowerCase();
      }
    },

    user: {
      get: function(){ return user; },
      set: function(value){
        user = value;
      }
    },

    host: {
      get: function(){ return host; },
      set: function(value){
        host = value.toLowerCase();
      }
    },
    port: {
      get: function(){ return port; },
      set: function(value){
        port = parseInt(value,10);
      }
    }
  });
};
JsSIP.URI.prototype = {
  setParam: function(key, value) {
    if(key) {
      this.parameters[key.toLowerCase()] = (typeof value === 'undefined' || value === null) ? null : value.toString().toLowerCase();
    }
  },

  getParam: function(key) {
    if(key) {
      return this.parameters[key.toLowerCase()];
    }
  },

  hasParam: function(key) {
    if(key) {
      return (this.parameters.hasOwnProperty(key.toLowerCase()) && true) || false;
    }
  },

  deleteParam: function(parameter) {
    var value;
    parameter = parameter.toLowerCase();
    if (this.parameters.hasOwnProperty(parameter)) {
      value = this.parameters[parameter];
      delete this.parameters[parameter];
      return value;
    }
  },

  clearParams: function() {
    this.parameters = {};
  },

  setHeader: function(name, value) {
    this.headers[JsSIP.Utils.headerize(name)] = (value instanceof Array) ? value : [value];
  },

  getHeader: function(name) {
    if(name) {
      return this.headers[JsSIP.Utils.headerize(name)];
    }
  },

  hasHeader: function(name) {
    if(name) {
      return (this.headers.hasOwnProperty(name.toLowerCase()) && true) || false;
    }
  },

  deleteHeader: function(header) {
    var value;
    header = JsSIP.Utils.headerize(header);
    if(this.headers.hasOwnProperty(header)) {
      value = this.headers[header];
      delete this.headers[header];
      return value;
    }
  },

  clearHeaders: function() {
    this.headers = {};
  },

  clone: function() {
    return new JsSIP.URI(
      this.scheme,
      this.user,
      this.host,
      this.port,
      window.JSON.parse(window.JSON.stringify(this.parameters)),
      window.JSON.parse(window.JSON.stringify(this.headers)));
  },

  toString: function(){
    var header, parameter, idx, uri,
      headers = [];

    uri  = this.scheme + ':';
    uri += this.user ? JsSIP.Utils.escapeUser(this.user) + '@' : '';
    uri += this.host;
    uri += this.port ? ':' + this.port : '';

    for (parameter in this.parameters) {
      uri += ';'+ parameter;
      uri += (this.parameters[parameter] === null) ? '' : '=' + this.parameters[parameter];
    }

    for(header in this.headers) {
      for(idx in this.headers[header]) {
        headers.push(header + '=' + this.headers[header][idx]);
      }
    }

    if (headers.length > 0) {
      uri += '?' + headers.join('&');
    }

    return uri;
  },
  toAor: function(){
      var aor;

      aor  = this.scheme + ':';
      aor += this.user ? JsSIP.Utils.escapeUser(this.user) + '@' : '';
      aor += this.host;

      return aor;
  }
};<|endoftext|>


<commit_before>/**
 * @class Ext.tree.IndentedTreeNodeUI
 * This class provides an alternate UI implementation for Ext TreeNodes. Node text
 * will wrap across multiple lines and will be indented to the right of the icon.
 *

 * Since text can span multiple "rows", it's advised that you set lines: false
 * in your TreePanel config when using this ui.
 *

 * To use, set uiProvider: Ext.tree.IndentedTreeNodeUI on every node you load.
 * You will also need some css to ensure the new tree nodes look like they should. At the minimum:
 *

.x-tree-node table {
  font: normal 11px arial, tahoma, helvetica, sans-serif;
  line-height: 17px;
}

 */
Ext.tree.IndentedTreeNodeUI = Ext.extend(Ext.tree.TreeNodeUI, {

  renderElements : function(n, a, targetNode, bulkRender){
      // add some indent caching, this helps performance when rendering a large tree
      this.indentMarkup = n.parentNode ? n.parentNode.ui.getChildIndent() : '';

      var cb = typeof a.checked == 'boolean';
      var href = a.href ? a.href : Ext.isGecko ? "" : "#";
      var buf = ['

',
          '

',
          '',this.indentMarkup,"",
          '',
          '',
          cb ? ('<input class="x-tree-node-cb" type="checkbox" ' + (a.checked ? 'checked="checked" />' : '/>')) : '',
          '	',n.text,"

",
          '

',
          "
"].join('');

      var nel;
      if(bulkRender !== true && n.nextSibling && (nel = n.nextSibling.ui.getEl())){
          this.wrap = Ext.DomHelper.insertHtml("beforeBegin", nel, buf);
      }else{
          this.wrap = Ext.DomHelper.insertHtml("beforeEnd", targetNode, buf);
      }

      this.elNode = this.wrap.childNodes[0];
      this.ctNode = this.wrap.childNodes[1];
      var cs = this.elNode.childNodes[0].childNodes[0].childNodes[0].childNodes[0].childNodes;
      this.indentNode = cs[0];
      this.ecNode = cs[1];
      this.iconNode = cs[2];
      var index = 3;
      if(cb){
          this.checkbox = cs[3];
          // fix for IE6
          this.checkbox.defaultChecked = this.checkbox.checked;
          index++;
      }
      this.anchor = this.elNode.childNodes[0].childNodes[0].childNodes[0].childNodes[1].firstChild;
      this.textNode = this.anchor.firstChild;
  }

});

Ext.override(Ext.tree.TreeEventModel, {
  getNodeTarget : function(e){
      var t = e.getTarget('.x-tree-node-icon', 1);
      if(!t){
          t = e.getTarget('.x-tree-node-el', 7); //changed from depth of 6 to 7
      }
      return t;
  }
});

<commit_msg>changed wording in doc<commit_after>/**
 * @class Ext.tree.IndentedTreeNodeUI
 * This class provides an alternate UI implementation for Ext TreeNodes. Node text
 * will wrap across multiple lines and will be indented.
 *

 * Since text can span multiple "rows", it's advised that you set lines: false
 * in your TreePanel config when using this ui.
 *

 * To use, set uiProvider: Ext.tree.IndentedTreeNodeUI on every node you load.
 * You will also need some css to ensure the new tree nodes look like they should. At the minimum:
 *

.x-tree-node table {
  font: normal 11px arial, tahoma, helvetica, sans-serif;
  line-height: 17px;
}

 */
Ext.tree.IndentedTreeNodeUI = Ext.extend(Ext.tree.TreeNodeUI, {

  renderElements : function(n, a, targetNode, bulkRender){
      // add some indent caching, this helps performance when rendering a large tree
      this.indentMarkup = n.parentNode ? n.parentNode.ui.getChildIndent() : '';

      var cb = typeof a.checked == 'boolean';
      var href = a.href ? a.href : Ext.isGecko ? "" : "#";
      var buf = ['

',
          '

',
          '',this.indentMarkup,"",
          '',
          '',
          cb ? ('<input class="x-tree-node-cb" type="checkbox" ' + (a.checked ? 'checked="checked" />' : '/>')) : '',
          '	',n.text,"

",
          '

',
          "
"].join('');

      var nel;
      if(bulkRender !== true && n.nextSibling && (nel = n.nextSibling.ui.getEl())){
          this.wrap = Ext.DomHelper.insertHtml("beforeBegin", nel, buf);
      }else{
          this.wrap = Ext.DomHelper.insertHtml("beforeEnd", targetNode, buf);
      }

      this.elNode = this.wrap.childNodes[0];
      this.ctNode = this.wrap.childNodes[1];
      var cs = this.elNode.childNodes[0].childNodes[0].childNodes[0].childNodes[0].childNodes;
      this.indentNode = cs[0];
      this.ecNode = cs[1];
      this.iconNode = cs[2];
      var index = 3;
      if(cb){
          this.checkbox = cs[3];
          // fix for IE6
          this.checkbox.defaultChecked = this.checkbox.checked;
          index++;
      }
      this.anchor = this.elNode.childNodes[0].childNodes[0].childNodes[0].childNodes[1].firstChild;
      this.textNode = this.anchor.firstChild;
  }

});

Ext.override(Ext.tree.TreeEventModel, {
  getNodeTarget : function(e){
      var t = e.getTarget('.x-tree-node-icon', 1);
      if(!t){
          t = e.getTarget('.x-tree-node-el', 7); //changed from depth of 6 to 7
      }
      return t;
  }
});

<|endoftext|>


<commit_before>;(function( $, undefined )
{
	var bridge;

	function ViewModel()
	{
		this.stations = ko.observableArray([]);

		this.json = ko.observable({});

		this.history = ko.observableArray([]);

		this.addHistory = function(json)
		{
			this.history.unshift(json);
		}

		this.forceUpdateHistory = function($data)
		{
			viewModel.json($data);
			viewModel.addHistory(viewModel.json());
		}
		this.songUrl = ko.computed(function(key)
		{
			return this.json()['audioURL'];
		}, this);

		this.albumArt = ko.computed(function(key)
		{
			return this.json()['artistArtUrl'];
		}, this);

		this.title = ko.computed(function(key)
		{
			return this.json()['songTitle'];
		}, this);

		this.artist = ko.computed(function(key)
		{
			return this.json()['artistSummary'];
		}, this);

		this.album = ko.computed(function(key)
		{
			return this.json()['albumTitle'];
		}, this);
	}
	window.viewModel = new ViewModel();

	viewModel.getStations = function()
	{
		bridge.getService("pandora", function (service) {
			service.getStationList(function(data) {
				viewModel.stations(data);
			});
		});
	}

	viewModel.updateVM = function()
	ko.bindingHandlers.jPlayer =
	{
		$("#jquery_jplayer_1").jPlayer("pause");
		bridge.getService("pandora", function (service) {
			service.getNextSong(function(data) {
				data['artistArtUrl'] = data['artistArtUrl'] || "/static/img/noalbumart.png";
				viewModel.json(data);
				viewModel.addHistory(viewModel.json());
		init: function(element, valueAccessor, allBindingsAccessor, viewModel)
		{
			$(element).jPlayer({
				ready: function(event)
				{
					$(this).jPlayer("setMedia", {
						mp3: viewModel.json().audioURL,
					}).jPlayer("play");
				},
				ended: function(event)
				{
					viewModel.updateVM();
				},
				swfPath: "http://www.jplayer.org/2.1.0/js/Jplayer.swf",
				supplied: "mp3",
				preload: 'auto',
				wmode: 'window',
			});
		});
	}

	$(document).ready(function()
	{
		bridge = new Bridge({ apiKey: "//FILL THIS IN" });
		},

		bridge.ready(function() {
			viewModel.getStations();
			viewModel.updateVM();
			ko.applyBindings(viewModel, document.head);
			ko.applyBindings(viewModel, document.body);
		});
	});
		update: function(element, valueAccessor, allBindingsAccessor, viewModel)
		{
			console.log("jPlayer updated! Now playing "
						+ viewModel.json().songTitle
						+ " by "
						+ viewModel.json().artistSummary
						+ " at URL "
						+ viewModel.json().audioURL);
			$(element).jPlayer("clearMedia").jPlayer("setMedia", {
				mp3: viewModel.json().audioURL
			}).jPlayer("play");
		}
	};
}(jQuery));
<commit_msg>Move vM methods below vM properties.<commit_after>;(function( $, undefined )
{
	var bridge;

	function ViewModel()
	{
		this.stations = ko.observableArray([]);

		this.json = ko.observable({});

		this.history = ko.observableArray([]);

		this.songUrl = ko.computed(function(key)
		{
			return this.json()['audioURL'];
		}, this);

		this.albumArt = ko.computed(function(key)
		{
			return this.json()['artistArtUrl'];
		}, this);

		this.title = ko.computed(function(key)
		{
			return this.json()['songTitle'];
		}, this);

		this.artist = ko.computed(function(key)
		{
			return this.json()['artistSummary'];
		}, this);

		this.album = ko.computed(function(key)
		{
			return this.json()['albumTitle'];
		}, this);
	}
	window.viewModel = new ViewModel();

	viewModel.getStations = function()
	{
		bridge.getService("pandora", function (service) {
			service.getStationList(function(data) {
				viewModel.stations(data);

		this.quickMix = ko.computed(function(key)
		{
			return ko.utils.arrayFilter(this.stations(), function(item)
			{
				return item['isQuickMix'];
			})[0];
		}, this);

		this.addHistory = function(json)
		{
			this.history.unshift(json);
		}

		this.forceUpdateHistory = function($data)
		{
			viewModel.json($data);
			viewModel.addHistory(viewModel.json());
		}

		this.updateVM = function()
		{
			$("#jquery_jplayer_1").jPlayer("pause");
			bridge.getService("pandora", function(service)
			{
				service.getNextSong(function(data) {
					data['artistArtUrl'] = data['artistArtUrl'] || "/static/img/noalbumart.png";
					viewModel.json(data);
					viewModel.addHistory(viewModel.json());
				});
			});
		});
	}

	viewModel.updateVM = function()
	ko.bindingHandlers.jPlayer =
	{
		$("#jquery_jplayer_1").jPlayer("pause");
		bridge.getService("pandora", function (service) {
			service.getNextSong(function(data) {
				data['artistArtUrl'] = data['artistArtUrl'] || "/static/img/noalbumart.png";
				viewModel.json(data);
				viewModel.addHistory(viewModel.json());
		init: function(element, valueAccessor, allBindingsAccessor, viewModel)
		{
			$(element).jPlayer({
				ready: function(event)
				{
					$(this).jPlayer("setMedia", {
						mp3: viewModel.json().audioURL,
					}).jPlayer("play");
				},
				ended: function(event)
				{
					viewModel.updateVM();
				},
				swfPath: "http://www.jplayer.org/2.1.0/js/Jplayer.swf",
				supplied: "mp3",
				preload: 'auto',
				wmode: 'window',
			});
		});
	}

	$(document).ready(function()
	{
		bridge = new Bridge({ apiKey: "//FILL THIS IN" });
		},

		bridge.ready(function() {
			viewModel.getStations();
			viewModel.updateVM();
			ko.applyBindings(viewModel, document.head);
			ko.applyBindings(viewModel, document.body);
		});
	});
		update: function(element, valueAccessor, allBindingsAccessor, viewModel)
		{
			console.log("jPlayer updated! Now playing "
						+ viewModel.json().songTitle
						+ " by "
						+ viewModel.json().artistSummary
						+ " at URL "
						+ viewModel.json().audioURL);
			$(element).jPlayer("clearMedia").jPlayer("setMedia", {
				mp3: viewModel.json().audioURL
			}).jPlayer("play");
		}
	};
}(jQuery));
<|endoftext|>


<commit_before>import React from 'react';
import { StyleSheet, Text, View, Button, ImageBackground, ScrollView } from 'react-native';
import ScrollableTabView, { DefaultTabBar, } from 'react-native-scrollable-tab-view';
import Icon from 'react-native-vector-icons/FontAwesome';
import BasicText from './sub/basicText.js';
import CustomTabBar from './sub/customTabBar.js'
import IconTabBar from './sub/iconTabBar.js'
import { globals } from '../styles/globals.js';

export default class FourTab extends React.Component {
  backgroundImage(section) {
    if (section === "online") {
      return `source=${require('../assets/online-icon.png')}`;
    } else {
      return `source=${require('../assets/identity-icon.png')}`;
    }
  }

  getTabs(props) {
    tabInfo = [
      {
        label: 'exclamation',
        type: 'text',
        content: props.tab1
      },
      {
        label: 'lightbulb-o',
        type: 'text',
        content: props.tab2
      },
      {
        label: 'list-ul',
        type: 'view',
        content: props.tab3
      },
      {
        label: 'book',
        type: 'view',
        content: props.tab4
      }
    ]
    let tabsArray = [];
    for (let i=0; i<props.length; i++) {
      tabsArray.push(
        <ScrollView tabLabel={tabInfo[i].label}>
          {tabInfo[i].type === 'text' ? <BasicText isParagraph>{tabInfo[i].content}</BasicText> : <View>{tabInfo[i].content}</View>}
        </ScrollView>
      )
    }
    return tabsArray;
  }

  render() {

    return (
      <ScrollableTabView style={[globals.green, globals.base]} initialPage={0}
        renderTabBar={() =>
          <IconTabBar backgroundColor={this.props.backgroundColor} />} >
          {this.getTabs(this.props)}
      </ScrollableTabView>
    );
  }
};
<commit_msg>tab bar order reversal now works<commit_after>import React from 'react';
import { StyleSheet, Text, View, Button, ImageBackground, ScrollView } from 'react-native';
import ScrollableTabView, { DefaultTabBar, } from 'react-native-scrollable-tab-view';
import Icon from 'react-native-vector-icons/FontAwesome';
import BasicText from './sub/basicText.js';
import CustomTabBar from './sub/customTabBar.js'
import IconTabBar from './sub/iconTabBar.js'
import { globals } from '../styles/globals.js';
import { prefs } from '../routes/prefs.js';

export default class FourTab extends React.Component {
  backgroundImage(section) {
    if (section === "online") {
      return `source=${require('../assets/online-icon.png')}`;
    } else {
      return `source=${require('../assets/identity-icon.png')}`;
    }
  }

  getTabs(props) {
    tabInfo = [
      {
        label: 'exclamation',
        type: 'text',
        content: props.tab1
      },
      {
        label: 'lightbulb-o',
        type: 'text',
        content: props.tab2
      },
      {
        label: 'list-ul',
        type: 'view',
        content: props.tab3
      },
      {
        label: 'book',
        type: 'view',
        content: props.tab4
      }
    ];
    let tabsArray = [];
    let numOfTabs = props.tab4 ? 3 : 2;
    for (let i=0; i<=numOfTabs; i++) {
      tabsArray.push(
        <ScrollView tabLabel={tabInfo[i].label} key={i}>
            {tabInfo[i].type === "text" ?
              <BasicText isParagraph>{tabInfo[i].content}</BasicText> :
              <View>{tabInfo[i].content}</View>
            }
        </ScrollView>
      )
    }
    if (prefs.language === "pk") {
      return tabsArray.reverse();
    } else {
      return tabsArray;
    }
  }

  render() {
    let numOfTabs = this.props.tab4 ? 3 : 2;
    return (
      <ScrollableTabView style={[globals.green, globals.base]} initialPage={prefs.language === 'pk' ? numOfTabs : 0}
        renderTabBar={() =>
          <IconTabBar backgroundColor={this.props.backgroundColor} />} >
          {this.getTabs(this.props)}
      </ScrollableTabView>
    );
  }
};
<|endoftext|>


<commit_before>var fs = require("fs");
var path = require('path');
var _ = require('./third/underscore.js');

var files = module.exports = {
  // A sort comparator to order files into load order.
  sort: function (a, b) {
    // main.* loaded last
    ismain_a = (path.basename(a).indexOf('main.') === 0);
    ismain_b = (path.basename(b).indexOf('main.') === 0);
    if (ismain_a !== ismain_b) {
      return (ismain_a ? 1 : -1);
    }

    // /lib/ loaded first
    islib_a = (a.indexOf('/lib/') !== -1);
    islib_b = (b.indexOf('/lib/') !== -1);
    if (islib_a !== islib_b) {
      return (islib_a ? -1 : 1);
    }

    // deeper paths loaded first.
    len_a = a.split('/').length;
    len_b = b.split('/').length;
    if (len_a !== len_b) {
      return (len_a < len_b ? 1 : -1);
    }

    // otherwise alphabetical
    return (a < b ? -1 : 1);
  },

  // Returns true if this is a file we should maybe care about (stat it,
  // descend if it is a directory, etc).
  pre_filter: function (filename) {
    if (!filename) { return false; }
    // no . files
    var base = path.basename(filename);
    if (base && base[0] === '.') { return false; }

    // XXX
    // first, we only want to exclude APP_ROOT/public, not some deeper public
    // second, we don't really like this at all
    // third, we don't update the app now if anything here changes
    if (filename.indexOf('/public/') !== -1) { return false; }

    return true;
  },

  // Returns true if this is a file we should monitor.
  // Iterate over all the interesting files, applying 'func' to each
  // file path. 'extensions' is an array of extensions to include (eg
  // ['.html', '.js'])
  file_list_async: function (filepath, extensions, func) {
    if (!files.pre_filter(filepath)) { return; }
    fs.stat(filepath, function(err, stats) {
      if (err) {
        // XXX!
        return;
      }

      if (stats.isDirectory()) {
        fs.readdir(filepath, function(err, fileNames) {
          if(err) {
            // XXX!
            return;
          }

          _.each(fileNames, function (fileName) {
            files.file_list_async(path.join(filepath, fileName),
                                  extensions, func);
          });
        });
      } else if (_.indexOf(extensions, path.extname(filepath)) !== -1) {
        func(filepath);
      }
    });
  },

  file_list_sync: function (filepath, extensions) {
    var ret = [];
    if (!files.pre_filter(filepath)) { return ret; }
    var stats = fs.statSync(filepath);
    if (stats.isDirectory()) {
      var fileNames = fs.readdirSync(filepath);
      _.each(fileNames, function (fileName) {
        ret = ret.concat(files.file_list_sync(
          path.join(filepath, fileName), extensions));
      });
    } else if (_.indexOf(extensions, path.extname(filepath)) !== -1) {
      ret.push(filepath);
    }

    return ret;
  },

  // given a path, traverse upwards until we find a .meteor
  // directory that contains a 'packages' file. returns either the
  // path to a top-level app or null for no app found. if filepath
  // isn't given, use cwd.
  find_app_dir: function (filepath) {
    var test_dir = filepath || process.cwd();
    while (test_dir) {
      if (path.existsSync(path.join(test_dir, '.meteor/packages'))) {
        break;
      }
      var new_dir = path.dirname(test_dir);
      if (new_dir === test_dir) {
        test_dir = null;
      } else {
        test_dir = new_dir;
      }
    }
    if (!test_dir)
      return null;

    return test_dir;
  },

  // create a .gitignore file in dir_path if one doesn't exist. add
  // 'entry' to the .gitignore on its own line at the bottom of the
  // file, if the exact line does not already exist in the file.
  // XXX unused. remove?
  add_to_gitignore: function (dir_path, entry) {
    var filepath = path.join(dir_path, ".gitignore");
    if (path.existsSync(filepath)) {
      var data = fs.readFileSync(filepath, 'utf8');
      var lines = data.split(/\n/);
      if (_.any(lines, function (x) { return x === entry })) {
        // already there do nothing
      } else {
        // rewrite file w/ new entry.
        if (data.substr(-1) !== "\n") data = data + "\n";
        data = data + entry + "\n";
        fs.writeFileSync(filepath, data, 'utf8');
      }
    } else {
      // doesn't exist, just write it.
      fs.writeFileSync(filepath, entry + "\n", 'utf8');
    }
  },

  // True if we're in a git checkout of Meteor, else false (we're in
  // an installation.)
  in_checkout: function () {
    try {
      if (path.existsSync(path.join(__dirname, "../../.git")))
        return true;
    } catch (e) { console.log(e);}

    return false;
  },

  // Return the root of dev_bundle (probably /usr/local/meteor in an
  // install, or (checkout root)/dev_bundle in a checkout..)
  get_dev_bundle: function () {
    if (files.in_checkout()) {
      return path.join(__dirname, '../../dev_bundle');
    }
    else
      return path.join(__dirname, '../..');
  },

  // Return where the packages are stored
  get_package_dir: function () {
    return path.join(__dirname, '../../packages');
  },

  // Return the directory that contains the core tool (the top-level
  // 'app' directory)
  get_core_dir: function () {
    return path.join(__dirname, '../../app');
  },

  // Try to find the prettiest way to present a path to the
  // user. Presently, the main thing it does is replace $HOME with ~.
  pretty_path: function (path) {
    path = fs.realpathSync(path);
    var home = process.env.HOME;
    if (home && path.substr(0, home.length) === home)
      path = "~" + path.substr(home.length);
    return path;
  },

  // Like rm -r.
  rm_recursive: function (p) {
    try {
      // the l in lstat is critical -- we want to remove symbolic
      // links, not what they point to
      var stat = fs.lstatSync(p);
    } catch (e) {
      if (e.code == "ENOENT")
        return;
      throw e;
    }

    if (stat.isDirectory()) {
      _.each(fs.readdirSync(p), function (file) {
        file = path.join(p, file);
        files.rm_recursive(file);
      });
      fs.rmdirSync(p)
    } else
      fs.unlinkSync(p);
  },

  // like mkdir -p. if it returns true, the item is a directory (even
  // if it was already created). if it returns false, the item is not
  // a directory and we couldn't make it one.
  mkdir_p: function (dir, mode) {
    var p = path.resolve(dir);
    var ps = path.normalize(p).split('/');

    if (path.existsSync(p)) {
      if (fs.statSync(p).isDirectory()) { return true;}
      return false;
    }

    // doesn't exist. recurse to build parent.
    var success = files.mkdir_p(ps.slice(0,-1).join('/'), mode);
    // parent is not a directory.
    if (!success) { return false; }

    fs.mkdirSync(p, mode);

    // double check we exist now
    if (!path.existsSync(p) ||
        !fs.statSync(p).isDirectory())
      return false; // wtf
    return true;
  },

  // Roughly like cp -R. 'from' should be a directory. 'to' can either
  // be a directory, or it can not exist (in which case it will be
  // created with mkdir_p.) Doesn't think about file mode at all.
  //
  // If options.transformer_{filename, contents} is present, it should
  // be a function, and the contents (as a buffer) or filename will be
  // passed through the function. Use this to, eg, fill templates.
  //
  // If options.ignore is present, it should be a list of regexps. Any
  // file whose basename matches one of the regexps, before
  // transformation, will be skipped.
  cp_r: function (from, to, options) {
    options = options || {};
    files.mkdir_p(to, 0755);
    _.each(fs.readdirSync(from), function (f) {
      if (_.any(options.ignore || [], function (pattern) {
        return f.match(pattern);
      })) return;

      var full_from = path.join(from, f);
      if (options.transform_filename)
        f = options.transform_filename(f);
      var full_to = path.join(to, f);
      if (fs.statSync(full_from).isDirectory())
        files.cp_r(full_from, full_to, options);
      else {
        if (!options.transform_contents) {
          // XXX reads full file into memory.. lame.
          fs.writeFileSync(full_to, fs.readFileSync(full_from))
        } else {
          var contents = fs.readFileSync(full_from);
          contents = options.transform_contents(contents, f);
          fs.writeFileSync(full_to, contents);
        }
      }
    });
  }

};
<commit_msg>Functions to distinguish between app directories and package directories.<commit_after>var fs = require("fs");
var path = require('path');
var _ = require('./third/underscore.js');

var files = module.exports = {
  // A sort comparator to order files into load order.
  sort: function (a, b) {
    // main.* loaded last
    ismain_a = (path.basename(a).indexOf('main.') === 0);
    ismain_b = (path.basename(b).indexOf('main.') === 0);
    if (ismain_a !== ismain_b) {
      return (ismain_a ? 1 : -1);
    }

    // /lib/ loaded first
    islib_a = (a.indexOf('/lib/') !== -1);
    islib_b = (b.indexOf('/lib/') !== -1);
    if (islib_a !== islib_b) {
      return (islib_a ? -1 : 1);
    }

    // deeper paths loaded first.
    len_a = a.split('/').length;
    len_b = b.split('/').length;
    if (len_a !== len_b) {
      return (len_a < len_b ? 1 : -1);
    }

    // otherwise alphabetical
    return (a < b ? -1 : 1);
  },

  // Returns true if this is a file we should maybe care about (stat it,
  // descend if it is a directory, etc).
  pre_filter: function (filename) {
    if (!filename) { return false; }
    // no . files
    var base = path.basename(filename);
    if (base && base[0] === '.') { return false; }

    // XXX
    // first, we only want to exclude APP_ROOT/public, not some deeper public
    // second, we don't really like this at all
    // third, we don't update the app now if anything here changes
    if (filename.indexOf('/public/') !== -1) { return false; }

    return true;
  },

  // Returns true if this is a file we should monitor.
  // Iterate over all the interesting files, applying 'func' to each
  // file path. 'extensions' is an array of extensions to include (eg
  // ['.html', '.js'])
  file_list_async: function (filepath, extensions, func) {
    if (!files.pre_filter(filepath)) { return; }
    fs.stat(filepath, function(err, stats) {
      if (err) {
        // XXX!
        return;
      }

      if (stats.isDirectory()) {
        fs.readdir(filepath, function(err, fileNames) {
          if(err) {
            // XXX!
            return;
          }

          _.each(fileNames, function (fileName) {
            files.file_list_async(path.join(filepath, fileName),
                                  extensions, func);
          });
        });
      } else if (_.indexOf(extensions, path.extname(filepath)) !== -1) {
        func(filepath);
      }
    });
  },

  file_list_sync: function (filepath, extensions) {
    var ret = [];
    if (!files.pre_filter(filepath)) { return ret; }
    var stats = fs.statSync(filepath);
    if (stats.isDirectory()) {
      var fileNames = fs.readdirSync(filepath);
      _.each(fileNames, function (fileName) {
        ret = ret.concat(files.file_list_sync(
          path.join(filepath, fileName), extensions));
      });
    } else if (_.indexOf(extensions, path.extname(filepath)) !== -1) {
      ret.push(filepath);
    }

    return ret;
  },

  // given a path, returns true if it is a meteor application (has a
  // .meteor directory with a 'packages' file). false otherwise.
  is_app_dir: function (filepath) {
    return path.existsSync(path.join(filepath, '.meteor/packages'));
  },

  // given a path, returns true if it is a meteor package (is a
  // directory with a 'packages.js' file). false otherwise.
  //
  // Note that a directory can be both a package _and_ an application.
  is_package_dir: function (filepath) {
    return path.existsSync(path.join(filepath, 'package.js'));
  },

  // given a predicate function and a starting path, traverse upwards
  // from the path until we find a path that satisfys the predicate.
  //
  // returns either the path to the lowest level directory that passed
  // the test or null for none found. if starting path isn't given, use
  // cwd.
  find_upwards: function (predicate, start_path) {
    var test_dir = start_path || process.cwd();
    while (test_dir) {
      if (predicate(test_dir)) {
        break;
      }
      var new_dir = path.dirname(test_dir);
      if (new_dir === test_dir) {
        test_dir = null;
      } else {
        test_dir = new_dir;
      }
    }
    if (!test_dir)
      return null;

    return test_dir;
  },

  // compatibility shim. delete when unused.
  find_app_dir: function (filepath) {
    return files.find_upwards(files.is_app_dir, filepath);
  },

  // create a .gitignore file in dir_path if one doesn't exist. add
  // 'entry' to the .gitignore on its own line at the bottom of the
  // file, if the exact line does not already exist in the file.
  // XXX unused. remove?
  add_to_gitignore: function (dir_path, entry) {
    var filepath = path.join(dir_path, ".gitignore");
    if (path.existsSync(filepath)) {
      var data = fs.readFileSync(filepath, 'utf8');
      var lines = data.split(/\n/);
      if (_.any(lines, function (x) { return x === entry })) {
        // already there do nothing
      } else {
        // rewrite file w/ new entry.
        if (data.substr(-1) !== "\n") data = data + "\n";
        data = data + entry + "\n";
        fs.writeFileSync(filepath, data, 'utf8');
      }
    } else {
      // doesn't exist, just write it.
      fs.writeFileSync(filepath, entry + "\n", 'utf8');
    }
  },

  // True if we're in a git checkout of Meteor, else false (we're in
  // an installation.)
  in_checkout: function () {
    try {
      if (path.existsSync(path.join(__dirname, "../../.git")))
        return true;
    } catch (e) { console.log(e);}

    return false;
  },

  // Return the root of dev_bundle (probably /usr/local/meteor in an
  // install, or (checkout root)/dev_bundle in a checkout..)
  get_dev_bundle: function () {
    if (files.in_checkout()) {
      return path.join(__dirname, '../../dev_bundle');
    }
    else
      return path.join(__dirname, '../..');
  },

  // Return where the packages are stored
  get_package_dir: function () {
    return path.join(__dirname, '../../packages');
  },

  // Return the directory that contains the core tool (the top-level
  // 'app' directory)
  get_core_dir: function () {
    return path.join(__dirname, '../../app');
  },

  // Try to find the prettiest way to present a path to the
  // user. Presently, the main thing it does is replace $HOME with ~.
  pretty_path: function (path) {
    path = fs.realpathSync(path);
    var home = process.env.HOME;
    if (home && path.substr(0, home.length) === home)
      path = "~" + path.substr(home.length);
    return path;
  },

  // Like rm -r.
  rm_recursive: function (p) {
    try {
      // the l in lstat is critical -- we want to remove symbolic
      // links, not what they point to
      var stat = fs.lstatSync(p);
    } catch (e) {
      if (e.code == "ENOENT")
        return;
      throw e;
    }

    if (stat.isDirectory()) {
      _.each(fs.readdirSync(p), function (file) {
        file = path.join(p, file);
        files.rm_recursive(file);
      });
      fs.rmdirSync(p)
    } else
      fs.unlinkSync(p);
  },

  // like mkdir -p. if it returns true, the item is a directory (even
  // if it was already created). if it returns false, the item is not
  // a directory and we couldn't make it one.
  mkdir_p: function (dir, mode) {
    var p = path.resolve(dir);
    var ps = path.normalize(p).split('/');

    if (path.existsSync(p)) {
      if (fs.statSync(p).isDirectory()) { return true;}
      return false;
    }

    // doesn't exist. recurse to build parent.
    var success = files.mkdir_p(ps.slice(0,-1).join('/'), mode);
    // parent is not a directory.
    if (!success) { return false; }

    fs.mkdirSync(p, mode);

    // double check we exist now
    if (!path.existsSync(p) ||
        !fs.statSync(p).isDirectory())
      return false; // wtf
    return true;
  },

  // Roughly like cp -R. 'from' should be a directory. 'to' can either
  // be a directory, or it can not exist (in which case it will be
  // created with mkdir_p.) Doesn't think about file mode at all.
  //
  // If options.transformer_{filename, contents} is present, it should
  // be a function, and the contents (as a buffer) or filename will be
  // passed through the function. Use this to, eg, fill templates.
  //
  // If options.ignore is present, it should be a list of regexps. Any
  // file whose basename matches one of the regexps, before
  // transformation, will be skipped.
  cp_r: function (from, to, options) {
    options = options || {};
    files.mkdir_p(to, 0755);
    _.each(fs.readdirSync(from), function (f) {
      if (_.any(options.ignore || [], function (pattern) {
        return f.match(pattern);
      })) return;

      var full_from = path.join(from, f);
      if (options.transform_filename)
        f = options.transform_filename(f);
      var full_to = path.join(to, f);
      if (fs.statSync(full_from).isDirectory())
        files.cp_r(full_from, full_to, options);
      else {
        if (!options.transform_contents) {
          // XXX reads full file into memory.. lame.
          fs.writeFileSync(full_to, fs.readFileSync(full_from))
        } else {
          var contents = fs.readFileSync(full_from);
          contents = options.transform_contents(contents, f);
          fs.writeFileSync(full_to, contents);
        }
      }
    });
  }

};
<|endoftext|>


<commit_before>'use strict';

import React, {
  PropTypes,
  ScrollView,
  View,
} from 'react-native';
import ScrollableMixin from 'react-native-scrollable-mixin';

import cloneReferencedElement from 'react-clone-referenced-element';

import DefaultLoadingIndicator from './DefaultLoadingIndicator';

class InfiniteScrollView extends React.Component {
  static propTypes = {
    ...ScrollView.propTypes,
    distanceToLoadMore: PropTypes.number.isRequired,
    canLoadMore: PropTypes.bool.isRequired,
    onLoadError: PropTypes.func,
    onLoadMoreAsync: PropTypes.func.isRequired,
    renderLoadingIndicator: PropTypes.func.isRequired,
    renderLoadingErrorIndicator: PropTypes.func.isRequired,
  };

  static defaultProps = {
    distanceToLoadMore: 1500,
    canLoadMore: false,
    scrollEventThrottle: 100,
    renderLoadingIndicator: () => <DefaultLoadingIndicator />,
    renderLoadingErrorIndicator: () => <View />,
    renderScrollComponent: props => <ScrollView {...props} />,
  };

  constructor(props, context) {
    super(props, context);

    this.state = {
      isDisplayingError: false,
    };

    this._loadMoreAsync = this._loadMoreAsync.bind(this);
  }

  getScrollResponder(): ReactComponent {
    return this._scrollComponent.getScrollResponder();
  }

  setNativeProps(nativeProps) {
    this._scrollComponent.setNativeProps(nativeProps);
  }

  render() {
    let statusIndicator;

    if (this.state.isDisplayingError) {
      statusIndicator = React.cloneElement(
        this.props.renderLoadingErrorIndicator(
          { onRetryLoadMore: this._loadMoreAsync }
         ),
        { key: 'loading-error-indicator' },
      );
    } else if (this.props.canLoadMore) {
      statusIndicator = React.cloneElement(
        this.props.renderLoadingIndicator(),
        { key: 'loading-indicator' },
      );
    }

    let {
      renderScrollComponent,
      ...props,
    } = this.props;
    Object.assign(props, {
      onScroll: this._handleScroll.bind(this),
      children: [this.props.children, statusIndicator],
    });

    return cloneReferencedElement(renderScrollComponent(props), {
      ref: component => { this._scrollComponent = component; },
    });
  }

  _handleScroll(event) {
    if (this.props.onScroll) {
      this.props.onScroll(event);
    }

    if (this._shouldLoadMore(event)) {
      this._loadMoreAsync().catch(error => {
        console.error('Unexpected error while loading more content:', error);
      });
    }
  }

  _shouldLoadMore(event) {
    return !this.state.isLoading &&
      !this.props.canLoadMore &&
      !this.state.isDisplayingError &&
      this._distanceFromEnd(event) < this.props.distanceToLoadMore;
  }

  async _loadMoreAsync() {
    if (this.state.isLoading && __DEV__) {
      throw new Error('_loadMoreAsync called while isLoading is true');
    }

    try {
      this.setState({isDisplayingError: false, isLoading: true});
      await this.props.onLoadMoreAsync();
    } catch (e) {
      this.props.onLoadError && this.props.onLoadError(e);
      this.setState({isDisplayingError: true});
    } finally {
      this.setState({isLoading: false});
    }
  }

  _distanceFromEnd(event): number {
    let {
      contentSize,
      contentInset,
      contentOffset,
      layoutMeasurement,
    } = event.nativeEvent;

    if (this.props.horizontal) {
      var contentLength = contentSize.width;
      var trailingInset = contentInset.right;
      var scrollOffset = contentOffset.x;
      var viewportLength = layoutMeasurement.width;
    } else {
      contentLength = contentSize.height;
      trailingInset = contentInset.bottom;
      scrollOffset = contentOffset.y;
      viewportLength = layoutMeasurement.height;
    }

    return contentLength + trailingInset - scrollOffset - viewportLength;
  }
}

Object.assign(InfiniteScrollView.prototype, ScrollableMixin);

module.exports = InfiniteScrollView;
<commit_msg>[Bugfix] Show loading indicator when isLoading = true, not canLoadMore<commit_after>'use strict';

import React, {
  PropTypes,
  ScrollView,
  View,
} from 'react-native';
import ScrollableMixin from 'react-native-scrollable-mixin';

import cloneReferencedElement from 'react-clone-referenced-element';

import DefaultLoadingIndicator from './DefaultLoadingIndicator';

class InfiniteScrollView extends React.Component {
  static propTypes = {
    ...ScrollView.propTypes,
    distanceToLoadMore: PropTypes.number.isRequired,
    canLoadMore: PropTypes.bool.isRequired,
    onLoadError: PropTypes.func,
    onLoadMoreAsync: PropTypes.func.isRequired,
    renderLoadingIndicator: PropTypes.func.isRequired,
    renderLoadingErrorIndicator: PropTypes.func.isRequired,
  };

  static defaultProps = {
    distanceToLoadMore: 1500,
    canLoadMore: false,
    scrollEventThrottle: 100,
    renderLoadingIndicator: () => <DefaultLoadingIndicator />,
    renderLoadingErrorIndicator: () => <View />,
    renderScrollComponent: props => <ScrollView {...props} />,
  };

  constructor(props, context) {
    super(props, context);

    this.state = {
      isDisplayingError: false,
    };

    this._loadMoreAsync = this._loadMoreAsync.bind(this);
  }

  getScrollResponder(): ReactComponent {
    return this._scrollComponent.getScrollResponder();
  }

  setNativeProps(nativeProps) {
    this._scrollComponent.setNativeProps(nativeProps);
  }

  render() {
    let statusIndicator;

    if (this.state.isDisplayingError) {
      statusIndicator = React.cloneElement(
        this.props.renderLoadingErrorIndicator(
          { onRetryLoadMore: this._loadMoreAsync }
         ),
        { key: 'loading-error-indicator' },
      );
    } else if (this.state.isLoading) {
      statusIndicator = React.cloneElement(
        this.props.renderLoadingIndicator(),
        { key: 'loading-indicator' },
      );
    }

    let {
      renderScrollComponent,
      ...props,
    } = this.props;
    Object.assign(props, {
      onScroll: this._handleScroll.bind(this),
      children: [this.props.children, statusIndicator],
    });

    return cloneReferencedElement(renderScrollComponent(props), {
      ref: component => { this._scrollComponent = component; },
    });
  }

  _handleScroll(event) {
    if (this.props.onScroll) {
      this.props.onScroll(event);
    }

    if (this._shouldLoadMore(event)) {
      this._loadMoreAsync().catch(error => {
        console.error('Unexpected error while loading more content:', error);
      });
    }
  }

  _shouldLoadMore(event) {
    return !this.state.isLoading &&
      !this.props.canLoadMore &&
      !this.state.isDisplayingError &&
      this._distanceFromEnd(event) < this.props.distanceToLoadMore;
  }

  async _loadMoreAsync() {
    if (this.state.isLoading && __DEV__) {
      throw new Error('_loadMoreAsync called while isLoading is true');
    }

    try {
      this.setState({isDisplayingError: false, isLoading: true});
      await this.props.onLoadMoreAsync();
    } catch (e) {
      this.props.onLoadError && this.props.onLoadError(e);
      this.setState({isDisplayingError: true});
    } finally {
      this.setState({isLoading: false});
    }
  }

  _distanceFromEnd(event): number {
    let {
      contentSize,
      contentInset,
      contentOffset,
      layoutMeasurement,
    } = event.nativeEvent;

    if (this.props.horizontal) {
      var contentLength = contentSize.width;
      var trailingInset = contentInset.right;
      var scrollOffset = contentOffset.x;
      var viewportLength = layoutMeasurement.width;
    } else {
      contentLength = contentSize.height;
      trailingInset = contentInset.bottom;
      scrollOffset = contentOffset.y;
      viewportLength = layoutMeasurement.height;
    }

    return contentLength + trailingInset - scrollOffset - viewportLength;
  }
}

Object.assign(InfiniteScrollView.prototype, ScrollableMixin);

module.exports = InfiniteScrollView;
<|endoftext|>


<commit_before><commit_msg>Reformat code<commit_after><|endoftext|>


<commit_before>function accessor(constructor, name) {
    constructor.prototype[name]= function(new_value) {
	return this["_" + name];
    };
}

function Ant() {
    this._row= 5;
    this._column= 5;
    this._direction= 'up';
}

accessor(Ant, "row");
accessor(Ant, "column");
accessor(Ant, "direction");

Ant.prototype.step= function() {
    this._column= 6;
    this._direction= 'right';
};
<commit_msg>Refactoring: extract more code to accessor()<commit_after>function accessor(constructor, name) {
    constructor.prototype[name]= function(new_value) {
	var field= "_" + name;
	if (new_value !== undefined)
	    this[field]= new_value;
	return this[field];
    };
}

function Ant() {
    this.row(5);
    this.column(5);
    this.direction('up');
}

accessor(Ant, "row");
accessor(Ant, "column");
accessor(Ant, "direction");

Ant.prototype.step= function() {
    this.column(6);
    this.direction('right');
};
<|endoftext|>


<commit_before>var express = require('express');
var http = require('https');
var logfmt = require('logfmt');
var app = express();

app.use(logfmt.requestLogger());
app.use(express.urlencoded());

app.get('/', function(req, res) {
  res.send('The best bot. The only bot. The not-huebot.');
});

function reply(context, message, icon, name) {
  var options = {
    host: context.team_domain + '.slack.com',
    port: 443,
    method: 'POST',
    path: '/services/hooks/incoming-webhook?token=' + encodeURIComponent(process.env.SLACK_POST_KEY),
    headers: {'Content-type': 'application/json'}
  };
  icon = icon || ':ghost:';

  var req = http.request(options, function (res) {
    res.on('data', console.log).setEncoding('utf8');
  });
  req.write(JSON.stringify({
    channel: '#' + context.channel_name,
    text: message.message || message,
    icon_emoji: (icon[0] == ':') ? icon : null,
    icon_url:   (icon[0] == ':') ? null : icon,
    username: name,
    attachments: message.message ? [message] : [],
  }));
  req.end();
}

var intents = require('./intents');
intents.reply = reply;
function handleIntent(context, outcome) {
  if (!outcome) {
    reply(context, "My wit has run out.");
  } else if (intents[outcome.intent]) {
    intents[outcome.intent](context, outcome.entities, outcome.confidence);
  } else {
    reply(context, {
      message: "I'm confused.",
      fallback: JSON.stringify(outcome),
      color: 'warning',
      text: 'Unhandled intent `' + outcome.intent + '`',
      pretext: (outcome.confidence*100) + '% confidence',
      fields: Object.keys(outcome.entities).map(function (entity) {
        console.log(outcome.entities[entity]);
        var value, data = outcome.entities[entity];

        if (data[0])
          value = data.map(function (d) { return d.value; }).join('; ');
        else
          value = data.value;

        return {
          title: entity,
          value: value,
          short: value.length < 50,
        };
      }),
    });
  }
};

var wit = require('./wit');
app.post('/slack', function (req, res) {
  // token, channel_name, text, team_domain, trigger_word,
  // user_name, channel_id, service_id, user_id, timestamp, team_id
  console.log(req.body.text);
  wit.message(req.body, req.body.text, handleIntent);

  res.send('ok');
});

app.post('/slack/last', function (req, res) {
  req.body.team_domain = 'twelfthbit';

  intents._users.findOne({user_id: req.body.user_id}, function (err, item) {
    if (err) {
      res.send('Error reading from mongo D:');
      console.log(err);
    } else if (!item || !item.usernames) {
      res.send("I have no dirt on you, bro.");
    } else if (!item.usernames['lastfm'] && !item.usernames['listensws']) {
      res.send("No idea what your lastfm or listens.ws usernames are.");
    } else if (item.usernames['lastfm']) {
      require('./last').lastfm(item.usernames['lastfm'], function (text, img) {
        reply(req.body, text, img || ':cd:', req.body.user_name + ' is listening to');
      });
    } else if (item.usernames['listensws']) {
      require('./last').listensws(item.usernames['listensws'], function (text, img) {
        reply(req.body, text, img || ':cd:', req.body.user_name + ' is listening to');
      });
    }

    res.send('');
  });
});

var port = Number(process.env.PORT || 5000);
app.listen(port, function() {
  console.log('Listening on', port);
});
<commit_msg>Add a confidence threshold (0.5)<commit_after>var express = require('express');
var http = require('https');
var logfmt = require('logfmt');
var app = express();

app.use(logfmt.requestLogger());
app.use(express.urlencoded());

app.get('/', function(req, res) {
  res.send('The best bot. The only bot. The not-huebot.');
});

function reply(context, message, icon, name) {
  var options = {
    host: context.team_domain + '.slack.com',
    port: 443,
    method: 'POST',
    path: '/services/hooks/incoming-webhook?token=' + encodeURIComponent(process.env.SLACK_POST_KEY),
    headers: {'Content-type': 'application/json'}
  };
  icon = icon || ':ghost:';

  var req = http.request(options, function (res) {
    res.on('data', console.log).setEncoding('utf8');
  });
  req.write(JSON.stringify({
    channel: '#' + context.channel_name,
    text: message.fallback ? '' : message,
    icon_emoji: (icon[0] == ':') ? icon : null,
    icon_url:   (icon[0] == ':') ? null : icon,
    username: name,
    attachments: message.fallback ? [message] : [],
  }));
  req.end();
}

var intents = require('./intents');
intents.reply = reply;
function handleIntent(context, outcome) {
  if (!outcome) {
    reply(context, "My wit has run out.");
  } else if (outcome.confidence < 0.5) {
    reply(context, "I'm sorry, were you talking about " + outcome.intent + "? Please speak up!");
  } else if (intents[outcome.intent]) {
    intents[outcome.intent](context, outcome.entities, outcome.confidence);
  } else {
    reply(context, {
      fallback: JSON.stringify(outcome),
      color: 'warning',
      text: "I don't know how to handle `" + outcome.intent + '` (' + (outcome.confidence*100) + '% confidence)',
      fields: Object.keys(outcome.entities).map(function (entity) {
        console.log(outcome.entities[entity]);
        var value, data = outcome.entities[entity];

        if (data[0])
          value = data.map(function (d) { return d.value; }).join('; ');
        else
          value = data.value;

        return {
          title: entity,
          value: value,
          short: value.length < 50,
        };
      }),
    });
  }
};

var wit = require('./wit');
app.post('/slack', function (req, res) {
  // token, channel_name, text, team_domain, trigger_word,
  // user_name, channel_id, service_id, user_id, timestamp, team_id
  console.log(req.body.text);
  wit.message(req.body, req.body.text, handleIntent);

  res.send('ok');
});

app.post('/slack/last', function (req, res) {
  req.body.team_domain = 'twelfthbit';

  intents._users.findOne({user_id: req.body.user_id}, function (err, item) {
    if (err) {
      res.send('Error reading from mongo D:');
      console.log(err);
    } else if (!item || !item.usernames) {
      res.send("I have no dirt on you, bro.");
    } else if (!item.usernames['lastfm'] && !item.usernames['listensws']) {
      res.send("No idea what your lastfm or listens.ws usernames are.");
    } else if (item.usernames['lastfm']) {
      require('./last').lastfm(item.usernames['lastfm'], function (text, img) {
        reply(req.body, text, img || ':cd:', req.body.user_name + ' is listening to');
      });
    } else if (item.usernames['listensws']) {
      require('./last').listensws(item.usernames['listensws'], function (text, img) {
        reply(req.body, text, img || ':cd:', req.body.user_name + ' is listening to');
      });
    }

    res.send('');
  });
});

var port = Number(process.env.PORT || 5000);
app.listen(port, function() {
  console.log('Listening on', port);
});
<|endoftext|>


<commit_before>define(["Tone/core/Tone"], function (Tone) {

	"use strict";

	/**
	 *  AnalyserNode.getFloatTimeDomainData polyfill
	 *  @private
	 */
	if (window.AnalyserNode && !AnalyserNode.prototype.getFloatTimeDomainData){
		//referenced https://github.com/mohayonao/get-float-time-domain-data
		AnalyserNode.prototype.getFloatTimeDomainData = function(array){
			var uint8 = new Uint8Array(array.length);
			this.getByteTimeDomainData(uint8);
			for (var i = 0; i < uint8.length; i++){
				array[i] = (uint8[i] - 128) / 128;
			}
		};
	}

	/**
	 *  @class  Wrapper around the native Web Audio's
	 *          [AnalyserNode](http://webaudio.github.io/web-audio-api/#idl-def-AnalyserNode).
	 *          Extracts FFT or Waveform data from the incoming signal.
	 *  @extends {Tone}
	 *  @param {String=} type The return type of the analysis, either "fft", or "waveform".
	 *  @param {Number=} size The size of the FFT. Value must be a power of
	 *                       two in the range 32 to 32768.
	 */
	Tone.Analyser = function(){

		var options = this.optionsObject(arguments, ["type", "size"], Tone.Analyser.defaults);

		/**
		 *  The analyser node.
		 *  @private
		 *  @type {AnalyserNode}
		 */
		this._analyser = this.input = this.output = this.context.createAnalyser();

		/**
		 *  The analysis type
		 *  @type {String}
		 *  @private
		 */
		this._type = options.type;

		/**
		 *  The return type of the analysis
		 *  @type {String}
		 *  @private
		 */
		this._returnType = options.returnType;

		/**
		 *  The buffer that the FFT data is written to
		 *  @type {TypedArray}
		 *  @private
		 */
		this._buffer = null;

		//set the values initially
		this.size = options.size;
		this.type = options.type;
		this.returnType = options.returnType;
		this.minDecibels = options.minDecibels;
		this.maxDecibels = options.maxDecibels;
	};

	Tone.extend(Tone.Analyser);

	/**
	 *  The default values.
	 *  @type {Object}
	 *  @const
	 */
	Tone.Analyser.defaults = {
		"size" : 1024,
		"returnType" : "byte",
		"type" : "fft",
		"smoothing" : 0.8,
		"maxDecibels" : -30,
		"minDecibels" : -100
	};

	/**
	 *  Possible return types of Tone.Analyser.analyse()
	 *  @enum {String}
	 */
	Tone.Analyser.Type = {
		Waveform : "waveform",
		FFT : "fft"
	};

	/**
	 *  Possible return types of Tone.Analyser.analyse().
	 *  byte values are between [0,255]. float values are between
	 *  [-1, 1] when the type is set to "waveform" and between
	 *  [minDecibels,maxDecibels] when the type is "fft".
	 *  @enum {String}
	 */
	Tone.Analyser.ReturnType = {
		Byte : "byte",
		Float : "float"
	};

	/**
	 *  Run the analysis given the current settings and return the
	 *  result as a TypedArray.
	 *  @returns {TypedArray}
	 */
	Tone.Analyser.prototype.analyse = function(){
		if (this._type === Tone.Analyser.Type.FFT){
			if (this._returnType === Tone.Analyser.ReturnType.Byte){
				this._analyser.getByteFrequencyData(this._buffer);
			} else {
				this._analyser.getFloatFrequencyData(this._buffer);
			}
		} else if (this._type === Tone.Analyser.Type.Waveform){
			if (this._returnType === Tone.Analyser.ReturnType.Byte){
				this._analyser.getByteTimeDomainData(this._buffer);
			} else {
				this._analyser.getFloatTimeDomainData(this._buffer);
			}
		}
		return this._buffer;
	};

	/**
	 *  The size of analysis. This must be a power of two in the range 32 to 32768.
	 *  @memberOf Tone.Analyser#
	 *  @type {Number}
	 *  @name size
	 */
	Object.defineProperty(Tone.Analyser.prototype, "size", {
		get : function(){
			return this._analyser.frequencyBinCount;
		},
		set : function(size){
			this._analyser.fftSize = size * 2;
			this.type = this._type;
		}
	});

	/**
	 *  The return type of Tone.Analyser.analyse(), either "byte" or "float".
	 *  When the type is set to "byte" the range of values returned in the array
	 *  are between 0-255. "float" values are between
	 *  [-1, 1] when the type is set to "waveform" and between
	 *  [minDecibels,maxDecibels] when the type is "fft".
	 *  @memberOf Tone.Analyser#
	 *  @type {String}
	 *  @name type
	 */
	Object.defineProperty(Tone.Analyser.prototype, "returnType", {
		get : function(){
			return this._returnType;
		},
		set : function(type){
			if (type === Tone.Analyser.ReturnType.Byte){
				this._buffer = new Uint8Array(this._analyser.frequencyBinCount);
			} else if (type === Tone.Analyser.ReturnType.Float){
				this._buffer = new Float32Array(this._analyser.frequencyBinCount);
			} else {
				throw new TypeError("Tone.Analayser: invalid return type: "+type);
			}
			this._returnType = type;
		}
	});

	/**
	 *  The analysis function returned by Tone.Analyser.analyse(), either "fft" or "waveform".
	 *  @memberOf Tone.Analyser#
	 *  @type {String}
	 *  @name type
	 */
	Object.defineProperty(Tone.Analyser.prototype, "type", {
		get : function(){
			return this._type;
		},
		set : function(type){
			if (type !== Tone.Analyser.Type.Waveform && type !== Tone.Analyser.Type.FFT){
				throw new TypeError("Tone.Analyser: invalid type: "+type);
			}
			this._type = type;
		}
	});

	/**
	 *  0 represents no time averaging with the last analysis frame.
	 *  @memberOf Tone.Analyser#
	 *  @type {NormalRange}
	 *  @name smoothing
	 */
	Object.defineProperty(Tone.Analyser.prototype, "smoothing", {
		get : function(){
			return this._analyser.smoothingTimeConstant;
		},
		set : function(val){
			this._analyser.smoothingTimeConstant = val;
		}
	});

	/**
	 *  The smallest decibel value which is analysed by the FFT.
	 *  @memberOf Tone.Analyser#
	 *  @type {Decibels}
	 *  @name minDecibels
	 */
	Object.defineProperty(Tone.Analyser.prototype, "minDecibels", {
		get : function(){
			return this._analyser.minDecibels;
		},
		set : function(val){
			this._analyser.minDecibels = val;
		}
	});

	/**
	 *  The largest decibel value which is analysed by the FFT.
	 *  @memberOf Tone.Analyser#
	 *  @type {Decibels}
	 *  @name maxDecibels
	 */
	Object.defineProperty(Tone.Analyser.prototype, "maxDecibels", {
		get : function(){
			return this._analyser.maxDecibels;
		},
		set : function(val){
			this._analyser.maxDecibels = val;
		}
	});

	/**
	 *  Clean up.
	 *  @return  {Tone.Analyser}  this
	 */
	Tone.Analyser.prototype.dispose = function(){
		Tone.prototype.dispose.call(this);
		this._analyser.disconnect();
		this._analyser = null;
		this._buffer = null;
	};

	return Tone.Analyser;
});<commit_msg>surfaced returnType in docs<commit_after>define(["Tone/core/Tone"], function (Tone) {

	"use strict";

	/**
	 *  AnalyserNode.getFloatTimeDomainData polyfill
	 *  @private
	 */
	if (window.AnalyserNode && !AnalyserNode.prototype.getFloatTimeDomainData){
		//referenced https://github.com/mohayonao/get-float-time-domain-data
		AnalyserNode.prototype.getFloatTimeDomainData = function(array){
			var uint8 = new Uint8Array(array.length);
			this.getByteTimeDomainData(uint8);
			for (var i = 0; i < uint8.length; i++){
				array[i] = (uint8[i] - 128) / 128;
			}
		};
	}

	/**
	 *  @class  Wrapper around the native Web Audio's
	 *          [AnalyserNode](http://webaudio.github.io/web-audio-api/#idl-def-AnalyserNode).
	 *          Extracts FFT or Waveform data from the incoming signal.
	 *  @extends {Tone}
	 *  @param {String=} type The return type of the analysis, either "fft", or "waveform".
	 *  @param {Number=} size The size of the FFT. Value must be a power of
	 *                       two in the range 32 to 32768.
	 */
	Tone.Analyser = function(){

		var options = this.optionsObject(arguments, ["type", "size"], Tone.Analyser.defaults);

		/**
		 *  The analyser node.
		 *  @private
		 *  @type {AnalyserNode}
		 */
		this._analyser = this.input = this.output = this.context.createAnalyser();

		/**
		 *  The analysis type
		 *  @type {String}
		 *  @private
		 */
		this._type = options.type;

		/**
		 *  The return type of the analysis
		 *  @type {String}
		 *  @private
		 */
		this._returnType = options.returnType;

		/**
		 *  The buffer that the FFT data is written to
		 *  @type {TypedArray}
		 *  @private
		 */
		this._buffer = null;

		//set the values initially
		this.size = options.size;
		this.type = options.type;
		this.returnType = options.returnType;
		this.minDecibels = options.minDecibels;
		this.maxDecibels = options.maxDecibels;
	};

	Tone.extend(Tone.Analyser);

	/**
	 *  The default values.
	 *  @type {Object}
	 *  @const
	 */
	Tone.Analyser.defaults = {
		"size" : 1024,
		"returnType" : "byte",
		"type" : "fft",
		"smoothing" : 0.8,
		"maxDecibels" : -30,
		"minDecibels" : -100
	};

	/**
	 *  Possible return types of Tone.Analyser.analyse()
	 *  @enum {String}
	 */
	Tone.Analyser.Type = {
		Waveform : "waveform",
		FFT : "fft"
	};

	/**
	 *  Possible return types of Tone.Analyser.analyse().
	 *  byte values are between [0,255]. float values are between
	 *  [-1, 1] when the type is set to "waveform" and between
	 *  [minDecibels,maxDecibels] when the type is "fft".
	 *  @enum {String}
	 */
	Tone.Analyser.ReturnType = {
		Byte : "byte",
		Float : "float"
	};

	/**
	 *  Run the analysis given the current settings and return the
	 *  result as a TypedArray.
	 *  @returns {TypedArray}
	 */
	Tone.Analyser.prototype.analyse = function(){
		if (this._type === Tone.Analyser.Type.FFT){
			if (this._returnType === Tone.Analyser.ReturnType.Byte){
				this._analyser.getByteFrequencyData(this._buffer);
			} else {
				this._analyser.getFloatFrequencyData(this._buffer);
			}
		} else if (this._type === Tone.Analyser.Type.Waveform){
			if (this._returnType === Tone.Analyser.ReturnType.Byte){
				this._analyser.getByteTimeDomainData(this._buffer);
			} else {
				this._analyser.getFloatTimeDomainData(this._buffer);
			}
		}
		return this._buffer;
	};

	/**
	 *  The size of analysis. This must be a power of two in the range 32 to 32768.
	 *  @memberOf Tone.Analyser#
	 *  @type {Number}
	 *  @name size
	 */
	Object.defineProperty(Tone.Analyser.prototype, "size", {
		get : function(){
			return this._analyser.frequencyBinCount;
		},
		set : function(size){
			this._analyser.fftSize = size * 2;
			this.type = this._type;
		}
	});

	/**
	 *  The return type of Tone.Analyser.analyse(), either "byte" or "float".
	 *  When the type is set to "byte" the range of values returned in the array
	 *  are between 0-255. "float" values are between
	 *  [-1, 1] when the type is set to "waveform" and between
	 *  [minDecibels,maxDecibels] when the type is "fft".
	 *  @memberOf Tone.Analyser#
	 *  @type {String}
	 *  @name returnType
	 */
	Object.defineProperty(Tone.Analyser.prototype, "returnType", {
		get : function(){
			return this._returnType;
		},
		set : function(type){
			if (type === Tone.Analyser.ReturnType.Byte){
				this._buffer = new Uint8Array(this._analyser.frequencyBinCount);
			} else if (type === Tone.Analyser.ReturnType.Float){
				this._buffer = new Float32Array(this._analyser.frequencyBinCount);
			} else {
				throw new TypeError("Tone.Analayser: invalid return type: "+type);
			}
			this._returnType = type;
		}
	});

	/**
	 *  The analysis function returned by Tone.Analyser.analyse(), either "fft" or "waveform".
	 *  @memberOf Tone.Analyser#
	 *  @type {String}
	 *  @name type
	 */
	Object.defineProperty(Tone.Analyser.prototype, "type", {
		get : function(){
			return this._type;
		},
		set : function(type){
			if (type !== Tone.Analyser.Type.Waveform && type !== Tone.Analyser.Type.FFT){
				throw new TypeError("Tone.Analyser: invalid type: "+type);
			}
			this._type = type;
		}
	});

	/**
	 *  0 represents no time averaging with the last analysis frame.
	 *  @memberOf Tone.Analyser#
	 *  @type {NormalRange}
	 *  @name smoothing
	 */
	Object.defineProperty(Tone.Analyser.prototype, "smoothing", {
		get : function(){
			return this._analyser.smoothingTimeConstant;
		},
		set : function(val){
			this._analyser.smoothingTimeConstant = val;
		}
	});

	/**
	 *  The smallest decibel value which is analysed by the FFT.
	 *  @memberOf Tone.Analyser#
	 *  @type {Decibels}
	 *  @name minDecibels
	 */
	Object.defineProperty(Tone.Analyser.prototype, "minDecibels", {
		get : function(){
			return this._analyser.minDecibels;
		},
		set : function(val){
			this._analyser.minDecibels = val;
		}
	});

	/**
	 *  The largest decibel value which is analysed by the FFT.
	 *  @memberOf Tone.Analyser#
	 *  @type {Decibels}
	 *  @name maxDecibels
	 */
	Object.defineProperty(Tone.Analyser.prototype, "maxDecibels", {
		get : function(){
			return this._analyser.maxDecibels;
		},
		set : function(val){
			this._analyser.maxDecibels = val;
		}
	});

	/**
	 *  Clean up.
	 *  @return  {Tone.Analyser}  this
	 */
	Tone.Analyser.prototype.dispose = function(){
		Tone.prototype.dispose.call(this);
		this._analyser.disconnect();
		this._analyser = null;
		this._buffer = null;
	};

	return Tone.Analyser;
});<|endoftext|>


<commit_before>var browserify = require('browserify');
var shim = require('browserify-shim');
var gulp = require('gulp');
var concat = require('gulp-concat');
var derequire = require('gulp-derequire');
var mocha = require('gulp-mocha');
var rename = require('gulp-rename');
var source = require('vinyl-source-stream');
var streamify = require('gulp-streamify');
var uglify = require('gulp-uglify');

var tests = [
	{ name: 'NavigationRouting', from: './test/NavigationRoutingTest.ts', to: 'navigationRouting.test.js' },
	{ name: 'StateInfo', from: './test/StateInfoTest.ts', to: 'stateInfo.test.js' },
	{ name: 'Navigation', from: './test/NavigationTest.ts', to: 'navigation.test.js' },
	{ name: 'NavigationData', from: './test/NavigationDataTest.ts', to: 'navigationData.test.js' }
];
var plugins = [
	{ name: 'NavigationReact', from: './src/react/NavigationReact.ts', to: 'navigation.react.js' },
	{ name: 'NavigationKnockout', from: './src/knockout/NavigationKnockout.ts', to: 'navigation.knockout.js' }
];
var testTasks = [];
function testTask(from, to) {
	return browserify(from)
		.plugin('tsify')
		.bundle()
		.pipe(source(to))
		.pipe(rename(to))
		.pipe(gulp.dest('./build'))
        .pipe(mocha({ reporter: 'nyan' }));
}
for (var i = 0; i < tests.length; i++) {
	(function (test) {
		gulp.task('Test' + test.name, function () {
			return testTask(test.from, test.to)
		});
	})(tests[i]);
	testTasks.push('Test' + tests[i].name);
}
gulp.task('test', testTasks);

gulp.task('BuildNavigationRouting', function () {
	return buildTask('NavigationRouting', './src/routing/NavigationRouting.ts', 'navigation.routing.js')
		.pipe(rename('navigation.routing.min.js'))
		.pipe(streamify(uglify()))
		.pipe(gulp.dest('./build'));
});
gulp.task('BuildNavigation', function () {
	return buildTask('Navigation', './src/Navigation.ts', 'navigation.js');
});
var buildTasks = ['BuildNavigationRouting', 'BuildNavigation'];
function buildTask(name, from, to) {
	return browserify(from, { standalone: name })
		.plugin('tsify')
		.transform(shim)
		.bundle()
		.pipe(source(to))
		.pipe(rename(to))
		.pipe(derequire())
		.pipe(gulp.dest('./build'));
}
for (var i = 0; i < plugins.length; i++) {
	(function (plugin) {
		gulp.task('Build' + plugin.name, function () {
			return buildTask(plugin.name, plugin.from, plugin.to);
		});
	})(plugins[i]);
	buildTasks.push('Build' + plugins[i].name);
}
gulp.task('UnifyNavigation', ['BuildNavigationRouting', 'BuildNavigation'], function () {
	return gulp.src(['./build/navigation.routing.js', './build/navigation.js'])
		.pipe(concat('navigation.js'))
		.pipe(gulp.dest('./build'))
		.pipe(rename('navigation.min.js'))
		.pipe(streamify(uglify()))
		.pipe(gulp.dest('./build'));
});
buildTasks.push('UnifyNavigation');
for (var i = 0; i < plugins.length; i++) {
	(function (plugin) {
		gulp.task('Unify' + plugin.name, ['UnifyNavigation', 'Build' + plugin.name], function () {
			return gulp.src(['./build/navigation.js', './build/' + plugin.to])
				.pipe(concat(plugin.to))
				.pipe(gulp.dest('./build'))
				.pipe(rename(plugin.to.replace(/js$/, 'min.js')))
				.pipe(streamify(uglify()))
				.pipe(gulp.dest('./build'));
		});
	})(plugins[i]);
	buildTasks.push('Unify' + plugins[i].name);
}
gulp.task('build', buildTasks);
<commit_msg>Used default mocha reporter<commit_after>var browserify = require('browserify');
var shim = require('browserify-shim');
var gulp = require('gulp');
var concat = require('gulp-concat');
var derequire = require('gulp-derequire');
var mocha = require('gulp-mocha');
var rename = require('gulp-rename');
var source = require('vinyl-source-stream');
var streamify = require('gulp-streamify');
var uglify = require('gulp-uglify');

var tests = [
	{ name: 'NavigationRouting', from: './test/NavigationRoutingTest.ts', to: 'navigationRouting.test.js' },
	{ name: 'StateInfo', from: './test/StateInfoTest.ts', to: 'stateInfo.test.js' },
	{ name: 'Navigation', from: './test/NavigationTest.ts', to: 'navigation.test.js' },
	{ name: 'NavigationData', from: './test/NavigationDataTest.ts', to: 'navigationData.test.js' }
];
var plugins = [
	{ name: 'NavigationReact', from: './src/react/NavigationReact.ts', to: 'navigation.react.js' },
	{ name: 'NavigationKnockout', from: './src/knockout/NavigationKnockout.ts', to: 'navigation.knockout.js' }
];
var testTasks = [];
function testTask(from, to) {
	return browserify(from)
		.plugin('tsify')
		.bundle()
		.pipe(source(to))
		.pipe(rename(to))
		.pipe(gulp.dest('./build'))
        .pipe(mocha());
}
for (var i = 0; i < tests.length; i++) {
	(function (test) {
		gulp.task('Test' + test.name, function () {
			return testTask(test.from, test.to)
		});
	})(tests[i]);
	testTasks.push('Test' + tests[i].name);
}
gulp.task('test', testTasks);

gulp.task('BuildNavigationRouting', function () {
	return buildTask('NavigationRouting', './src/routing/NavigationRouting.ts', 'navigation.routing.js')
		.pipe(rename('navigation.routing.min.js'))
		.pipe(streamify(uglify()))
		.pipe(gulp.dest('./build'));
});
gulp.task('BuildNavigation', function () {
	return buildTask('Navigation', './src/Navigation.ts', 'navigation.js');
});
var buildTasks = ['BuildNavigationRouting', 'BuildNavigation'];
function buildTask(name, from, to) {
	return browserify(from, { standalone: name })
		.plugin('tsify')
		.transform(shim)
		.bundle()
		.pipe(source(to))
		.pipe(rename(to))
		.pipe(derequire())
		.pipe(gulp.dest('./build'));
}
for (var i = 0; i < plugins.length; i++) {
	(function (plugin) {
		gulp.task('Build' + plugin.name, function () {
			return buildTask(plugin.name, plugin.from, plugin.to);
		});
	})(plugins[i]);
	buildTasks.push('Build' + plugins[i].name);
}
gulp.task('UnifyNavigation', ['BuildNavigationRouting', 'BuildNavigation'], function () {
	return gulp.src(['./build/navigation.routing.js', './build/navigation.js'])
		.pipe(concat('navigation.js'))
		.pipe(gulp.dest('./build'))
		.pipe(rename('navigation.min.js'))
		.pipe(streamify(uglify()))
		.pipe(gulp.dest('./build'));
});
buildTasks.push('UnifyNavigation');
for (var i = 0; i < plugins.length; i++) {
	(function (plugin) {
		gulp.task('Unify' + plugin.name, ['UnifyNavigation', 'Build' + plugin.name], function () {
			return gulp.src(['./build/navigation.js', './build/' + plugin.to])
				.pipe(concat(plugin.to))
				.pipe(gulp.dest('./build'))
				.pipe(rename(plugin.to.replace(/js$/, 'min.js')))
				.pipe(streamify(uglify()))
				.pipe(gulp.dest('./build'));
		});
	})(plugins[i]);
	buildTasks.push('Unify' + plugins[i].name);
}
gulp.task('build', buildTasks);
<|endoftext|>