<commit_before>'use strict';

var invoke         = require('es5-ext/function/invoke')
  , validFunction  = require('es5-ext/function/valid-function')
  , toInt          = require('es5-ext/number/to-int')
  , eq             = require('es5-ext/object/eq')
  , callable       = require('es5-ext/object/valid-callable')
  , value          = require('es5-ext/object/valid-value')
  , d              = require('d/d')
  , memoize        = require('memoizee/lib/regular')
  , memoizeMethods = require('memoizee/lib/d')(memoize)
  , createReadOnly = require('./create-read-only')

  , forEach = Array.prototype.forEach, pop = Array.prototype.pop
  , push = Array.prototype.push, reverse = Array.prototype.reverse
  , shift = Array.prototype.shift, slice = Array.prototype.slice
  , sort = Array.prototype.sort, splice = Array.prototype.splice
  , unshift = Array.prototype.unshift, bind = Function.prototype.bind
  , max = Math.max, defineProperties = Object.defineProperties
  , hasOwnProperty = Object.prototype.hasOwnProperty
  , invokeDispose = invoke('_dispose');

require('memoizee/lib/ext/ref-counter');
require('memoizee/lib/ext/resolvers');
require('memoizee/lib/ext/dispose');

module.exports = memoize(function (ObservableArray) {
	var ReadOnly = createReadOnly(validFunction(ObservableArray));

	defineProperties(ObservableArray.prototype, memoizeMethods({
		slice: d(function (start, end) {
			var result, refresh, listener, disposed, rStart, rEnd, recalculate;
			if ((((start > 0) && (end >= 0)) || ((start < 0) && (end < 0))) &&
					(start >= end)) {
				return new ReadOnly();
			}
			refresh = function () {
				var changed, i, s = rStart;
				if (result.length !== (rEnd - rStart)) {
					result.length = rEnd - rStart;
					changed = true;
				}
				result.length = rEnd - rStart;
				i = 0;
				while (s !== rEnd) {
					if (hasOwnProperty.call(this, s)) {
						if (!hasOwnProperty.call(result, i) || !eq(result[i], this[s])) {
							changed = true;
							result[i] = this[s];
						}
					} else if (hasOwnProperty.call(result, i)) {
						changed = true;
						delete result[i];
					}
					++i;
					++s;
				}
				return changed;
			}.bind(this);
			if ((start === 0) && (end === Infinity)) {
				// Pure copy
				rStart = 0;
				result = ReadOnly.from(this);
				this.on('change', listener = function (type, arg1, arg2) {
					if (type === 'pop') {
						pop.call(result);
						result.emit('change', 'pop', arg1);
					} else if (type === 'push') {
						push.apply(result, arg1);
						result.emit('change', 'push', arg1);
					} else if (type === 'reverse') {
						reverse.call(result);
						result.emit('change', 'reverse');
					} else if (type === 'shift') {
						shift.call(result);
						result.emit('change', 'shift', arg1);
					} else if (type === 'sort') {
						sort.call(result, arg1);
						result.emit('change', 'sort', arg1);
					} else if (type === 'splice') {
						arg2 = splice.apply(result, arg1);
						result.emit('change', 'splice', arg1, arg2);
					} else if (type === 'unshift') {
						unshift.apply(result, arg1);
						result.emit('change', 'unshift', arg1);
					} else {
						rEnd = this.length;
						refresh();
						result.emit('change');
					}
				});
			} else {
				result = new ReadOnly();
				recalculate = function () {
					var l = this.length;
					rStart = start;
					rEnd = end;
					if (rStart < 0) rStart = max(l + rStart, 0);
					else if (rStart > l) rStart = l;
					if (rEnd < 0) rEnd = max(l + rEnd, 0);
					else if (rEnd > l) rEnd = l;
					if (rStart > rEnd) rStart = rEnd;
				}.bind(this);
				recalculate();
				refresh();
				this.on('change', listener = function (type, arg1, arg2) {
					if (type === 'pop') {
						if ((rEnd === (this.length + 1)) && (rStart !== rEnd)) {
							pop.call(result);
							recalculate();
							result.emit('change', 'pop', arg1);
						} else {
							recalculate();
						}
					} else if (type === 'push') {
						recalculate();
						if ((rEnd > (this.length - arg1.length)) && (rStart !== rEnd)) {
							if (rEnd !== this.length) {
								arg1 = slice.call(arg1, 0, arg1.length - (this.length - rEnd));
							}
							push.apply(result, arg1);
							result.emit('change', 'push', arg1);
						}
					} else {
						recalculate();
						if (refresh()) result.emit('change');
					}
				});
			}
			defineProperties(result, {
				unref: d(function () {
					if (disposed) return;
					this.slice.clearRef(start, end);
				}.bind(this)),
				_dispose: d(function () {
					this.off('change', listener);
					disposed = true;
				}.bind(this))
			});
			return result;
		}, { resolvers: [toInt,
			function (val) { return (val === undefined) ? Infinity : toInt(val); }],
			refCounter: true, dispose: invokeDispose }),

		filter: d(function (callbackFn/*, thisArg*/) {
			var result, listener, refresh, thisArg, cb, disposed;
			(value(this) && callable(callbackFn));
			thisArg = arguments[1];
			cb = memoize(bind.call(callbackFn, thisArg), { length: 1 });
			result = new ReadOnly();
			refresh = function () {
				var i = 0, changed;
				forEach.call(this, function (val, j, self) {
					if (cb(val, j, self)) {
						if (!hasOwnProperty.call(result, i) || !eq(result[i], val)) {
							changed = true;
							result[i] = val;
						}
						++i;
					}
				});
				if (result.length !== i) {
					changed = true;
					result.length = i;
				}
				return changed;
			}.bind(this);
			refresh();
			this.on('change', listener = function () {
				if (refresh()) result.emit('change');
			});
			defineProperties(result, {
				refresh: d(function (index) {
					var filtered;
					index = index >>> 0;
					if (!this.hasOwnProperty(index)) return;
					filtered = Boolean(cb(this[index]));
					cb.clear(this[index]);
					if (Boolean(cb(this[index])) !== filtered) listener();
				}.bind(this)),
				refreshAll: d(function () {
					cb.clearAll();
					listener();
				}),
				unref: d(function () {
					if (disposed) return;
					this.filter.clearRef(callbackFn, thisArg);
				}.bind(this)),
				_dispose: d(function () {
					this.off('change', listener);
					disposed = true;
				}.bind(this))
			});
			return result;
		}, { length: 2, refCounter: true, dispose: invokeDispose }),
		map: d(function (callbackFn/*, thisArg*/) {
			var result, listener, refresh, thisArg, disposed, cb;
			(value(this) && callable(callbackFn));
			thisArg = arguments[1];
			cb = memoize(bind.call(callbackFn, thisArg), { length: 1 });
			result = new ReadOnly();
			refresh = function () {
				var changed;
				if (result.length !== this.length) {
					changed = true;
					result.length = this.length;
				}
				forEach.call(this, function (val, i, self) {
					val = cb(val, i, self);
					if (!hasOwnProperty.call(result, i) || !eq(result[i], val)) {
						changed = true;
						result[i] = val;
					}
				});
				return changed;
			}.bind(this);
			refresh();
			this.on('change', listener = function () {
				if (refresh()) result.emit('change');
			});
			defineProperties(result, {
				refresh: d(function (index) {
					var val;
					index = index >>> 0;
					if (!this.hasOwnProperty(index)) return;
					val = cb(this[index]);
					cb.clear(this[index]);
					if (!eq(cb(this[index]), val)) listener();
				}.bind(this)),
				refreshAll: d(function () {
					cb.clearAll();
					listener();
				}),
				unref: d(function () {
					if (disposed) return;
					this.map.clearRef(callbackFn, thisArg);
				}.bind(this)),
				_dispose: d(function () {
					this.off('change', listener);
					disposed = true;
				}.bind(this))
			});
			return result;
		}, { length: 2, refCounter: true, dispose: invokeDispose })
	}));

	return ObservableArray;
});
<commit_msg>-- cleanup<commit_after>'use strict';

var invoke         = require('es5-ext/function/invoke')
  , validFunction  = require('es5-ext/function/valid-function')
  , toInt          = require('es5-ext/number/to-int')
  , eq             = require('es5-ext/object/eq')
  , callable       = require('es5-ext/object/valid-callable')
  , value          = require('es5-ext/object/valid-value')
  , d              = require('d/d')
  , memoize        = require('memoizee/lib/regular')
  , memoizeMethods = require('memoizee/lib/d')(memoize)
  , createReadOnly = require('./create-read-only')

  , forEach = Array.prototype.forEach, pop = Array.prototype.pop
  , push = Array.prototype.push, reverse = Array.prototype.reverse
  , shift = Array.prototype.shift, slice = Array.prototype.slice
  , sort = Array.prototype.sort, splice = Array.prototype.splice
  , unshift = Array.prototype.unshift, bind = Function.prototype.bind
  , max = Math.max, defineProperties = Object.defineProperties
  , hasOwnProperty = Object.prototype.hasOwnProperty
  , invokeDispose = invoke('_dispose');

require('memoizee/lib/ext/ref-counter');
require('memoizee/lib/ext/resolvers');
require('memoizee/lib/ext/dispose');

module.exports = memoize(function (ObservableArray) {
	var ReadOnly = createReadOnly(validFunction(ObservableArray));

	defineProperties(ObservableArray.prototype, memoizeMethods({
		slice: d(function (start, end) {
			var result, refresh, listener, disposed, rStart, rEnd, recalculate;
			if ((((start > 0) && (end >= 0)) || ((start < 0) && (end < 0))) &&
					(start >= end)) {
				return new ReadOnly();
			}
			refresh = function () {
				var changed, i, s = rStart;
				if (result.length !== (rEnd - rStart)) {
					result.length = rEnd - rStart;
					changed = true;
				}
				result.length = rEnd - rStart;
				i = 0;
				while (s !== rEnd) {
					if (hasOwnProperty.call(this, s)) {
						if (!hasOwnProperty.call(result, i) || !eq(result[i], this[s])) {
							changed = true;
							result[i] = this[s];
						}
					} else if (hasOwnProperty.call(result, i)) {
						changed = true;
						delete result[i];
					}
					++i;
					++s;
				}
				return changed;
			}.bind(this);
			if ((start === 0) && (end === Infinity)) {
				// Pure copy
				rStart = 0;
				result = ReadOnly.from(this);
				this.on('change', listener = function (type, arg1, arg2) {
					if (type === 'pop') {
						pop.call(result);
						result.emit('change', 'pop', arg1);
					} else if (type === 'push') {
						push.apply(result, arg1);
						result.emit('change', 'push', arg1);
					} else if (type === 'reverse') {
						reverse.call(result);
						result.emit('change', 'reverse');
					} else if (type === 'shift') {
						shift.call(result);
						result.emit('change', 'shift', arg1);
					} else if (type === 'sort') {
						sort.call(result, arg1);
						result.emit('change', 'sort', arg1);
					} else if (type === 'splice') {
						arg2 = splice.apply(result, arg1);
						result.emit('change', 'splice', arg1, arg2);
					} else if (type === 'unshift') {
						unshift.apply(result, arg1);
						result.emit('change', 'unshift', arg1);
					} else {
						rEnd = this.length;
						refresh();
						result.emit('change');
					}
				});
			} else {
				result = new ReadOnly();
				recalculate = function () {
					var l = this.length;
					rStart = start;
					rEnd = end;
					if (rStart < 0) rStart = max(l + rStart, 0);
					else if (rStart > l) rStart = l;
					if (rEnd < 0) rEnd = max(l + rEnd, 0);
					else if (rEnd > l) rEnd = l;
					if (rStart > rEnd) rStart = rEnd;
				}.bind(this);
				recalculate();
				refresh();
				this.on('change', listener = function (type, arg1) {
					if (type === 'pop') {
						if ((rEnd === (this.length + 1)) && (rStart !== rEnd)) {
							pop.call(result);
							recalculate();
							result.emit('change', 'pop', arg1);
						} else {
							recalculate();
						}
					} else if (type === 'push') {
						recalculate();
						if ((rEnd > (this.length - arg1.length)) && (rStart !== rEnd)) {
							if (rEnd !== this.length) {
								arg1 = slice.call(arg1, 0, arg1.length - (this.length - rEnd));
							}
							push.apply(result, arg1);
							result.emit('change', 'push', arg1);
						}
					} else {
						recalculate();
						if (refresh()) result.emit('change');
					}
				});
			}
			defineProperties(result, {
				unref: d(function () {
					if (disposed) return;
					this.slice.clearRef(start, end);
				}.bind(this)),
				_dispose: d(function () {
					this.off('change', listener);
					disposed = true;
				}.bind(this))
			});
			return result;
		}, { resolvers: [toInt,
			function (val) { return (val === undefined) ? Infinity : toInt(val); }],
			refCounter: true, dispose: invokeDispose }),

		filter: d(function (callbackFn/*, thisArg*/) {
			var result, listener, refresh, thisArg, cb, disposed;
			(value(this) && callable(callbackFn));
			thisArg = arguments[1];
			cb = memoize(bind.call(callbackFn, thisArg), { length: 1 });
			result = new ReadOnly();
			refresh = function () {
				var i = 0, changed;
				forEach.call(this, function (val, j, self) {
					if (cb(val, j, self)) {
						if (!hasOwnProperty.call(result, i) || !eq(result[i], val)) {
							changed = true;
							result[i] = val;
						}
						++i;
					}
				});
				if (result.length !== i) {
					changed = true;
					result.length = i;
				}
				return changed;
			}.bind(this);
			refresh();
			this.on('change', listener = function () {
				if (refresh()) result.emit('change');
			});
			defineProperties(result, {
				refresh: d(function (index) {
					var filtered;
					index = index >>> 0;
					if (!this.hasOwnProperty(index)) return;
					filtered = Boolean(cb(this[index]));
					cb.clear(this[index]);
					if (Boolean(cb(this[index])) !== filtered) listener();
				}.bind(this)),
				refreshAll: d(function () {
					cb.clearAll();
					listener();
				}),
				unref: d(function () {
					if (disposed) return;
					this.filter.clearRef(callbackFn, thisArg);
				}.bind(this)),
				_dispose: d(function () {
					this.off('change', listener);
					disposed = true;
				}.bind(this))
			});
			return result;
		}, { length: 2, refCounter: true, dispose: invokeDispose }),
		map: d(function (callbackFn/*, thisArg*/) {
			var result, listener, refresh, thisArg, disposed, cb;
			(value(this) && callable(callbackFn));
			thisArg = arguments[1];
			cb = memoize(bind.call(callbackFn, thisArg), { length: 1 });
			result = new ReadOnly();
			refresh = function () {
				var changed;
				if (result.length !== this.length) {
					changed = true;
					result.length = this.length;
				}
				forEach.call(this, function (val, i, self) {
					val = cb(val, i, self);
					if (!hasOwnProperty.call(result, i) || !eq(result[i], val)) {
						changed = true;
						result[i] = val;
					}
				});
				return changed;
			}.bind(this);
			refresh();
			this.on('change', listener = function () {
				if (refresh()) result.emit('change');
			});
			defineProperties(result, {
				refresh: d(function (index) {
					var val;
					index = index >>> 0;
					if (!this.hasOwnProperty(index)) return;
					val = cb(this[index]);
					cb.clear(this[index]);
					if (!eq(cb(this[index]), val)) listener();
				}.bind(this)),
				refreshAll: d(function () {
					cb.clearAll();
					listener();
				}),
				unref: d(function () {
					if (disposed) return;
					this.map.clearRef(callbackFn, thisArg);
				}.bind(this)),
				_dispose: d(function () {
					this.off('change', listener);
					disposed = true;
				}.bind(this))
			});
			return result;
		}, { length: 2, refCounter: true, dispose: invokeDispose })
	}));

	return ObservableArray;
});
<|endoftext|>


<commit_before>/* @flow strict-local */
import { connect } from 'react-redux';

import React, { PureComponent } from 'react';
import { StyleSheet, View } from 'react-native';

import type { Auth, Dispatch, GlobalState } from '../types';
import { ZulipButton } from '../common';
import { subscriptionAdd, subscriptionRemove } from '../api';
import { delay } from '../utils/async';
import { streamNarrow } from '../utils/narrow';
import StreamList from '../streams/StreamList';
import { getAuth, getCanCreateStreams, getStreams, getSubscriptions } from '../selectors';
import { doNarrow, navigateToCreateStream } from '../actions';

const styles = StyleSheet.create({
  wrapper: {
    flex: 1,
  },
  button: {
    margin: 16,
  },
});

type Props = {|
  dispatch: Dispatch,
  auth: Auth,
  canCreateStreams: boolean,
  streams: [],
  subscriptions: [],
|};

class StreamListCard extends PureComponent<Props> {
  handleSwitchChange = (streamName: string, switchValue: boolean) => {
    const { auth } = this.props;

    if (switchValue) {
      subscriptionAdd(auth, [{ name: streamName }]);
    } else {
      subscriptionRemove(auth, [streamName]);
    }
  };

  handleNarrow = (streamName: string) => {
    const { dispatch } = this.props;
    dispatch(doNarrow(streamNarrow(streamName)));
  };

  render() {
    const { dispatch, canCreateStreams, streams, subscriptions } = this.props;
    const subsAndStreams = streams.map(x => ({
      ...x,
      subscribed: subscriptions.some(s => s.stream_id === x.stream_id),
    }));

    return (
      <View style={styles.wrapper}>
        {canCreateStreams && (
          <ZulipButton
            style={styles.button}
            secondary
            text="Create new stream"
            onPress={() =>
              delay(() => {
                dispatch(navigateToCreateStream());
              })
            }
          />
        )}
        <StreamList
          streams={subsAndStreams}
          showSwitch
          showDescriptions
          onSwitch={this.handleSwitchChange}
          onPress={this.handleNarrow}
        />
      </View>
    );
  }
}

export default connect((state: GlobalState) => ({
  auth: getAuth(state),
  canCreateStreams: getCanCreateStreams(state),
  streams: getStreams(state),
  subscriptions: getSubscriptions(state),
}))(StreamListCard);
<commit_msg>stream list: Fix bogus types spelled `[]`.<commit_after>/* @flow strict-local */
import { connect } from 'react-redux';

import React, { PureComponent } from 'react';
import { StyleSheet, View } from 'react-native';

import type { Auth, Dispatch, GlobalState, Stream, Subscription } from '../types';
import { ZulipButton } from '../common';
import { subscriptionAdd, subscriptionRemove } from '../api';
import { delay } from '../utils/async';
import { streamNarrow } from '../utils/narrow';
import StreamList from '../streams/StreamList';
import { getAuth, getCanCreateStreams, getStreams, getSubscriptions } from '../selectors';
import { doNarrow, navigateToCreateStream } from '../actions';

const styles = StyleSheet.create({
  wrapper: {
    flex: 1,
  },
  button: {
    margin: 16,
  },
});

type Props = {|
  dispatch: Dispatch,
  auth: Auth,
  canCreateStreams: boolean,
  streams: Stream[],
  subscriptions: Subscription[],
|};

class StreamListCard extends PureComponent<Props> {
  handleSwitchChange = (streamName: string, switchValue: boolean) => {
    const { auth } = this.props;

    if (switchValue) {
      subscriptionAdd(auth, [{ name: streamName }]);
    } else {
      subscriptionRemove(auth, [streamName]);
    }
  };

  handleNarrow = (streamName: string) => {
    const { dispatch } = this.props;
    dispatch(doNarrow(streamNarrow(streamName)));
  };

  render() {
    const { dispatch, canCreateStreams, streams, subscriptions } = this.props;
    const subsAndStreams = streams.map(x => ({
      ...x,
      subscribed: subscriptions.some(s => s.stream_id === x.stream_id),
    }));

    return (
      <View style={styles.wrapper}>
        {canCreateStreams && (
          <ZulipButton
            style={styles.button}
            secondary
            text="Create new stream"
            onPress={() =>
              delay(() => {
                dispatch(navigateToCreateStream());
              })
            }
          />
        )}
        <StreamList
          streams={(subsAndStreams: $FlowFixMe)} // fixed in next commit
          showSwitch
          showDescriptions
          onSwitch={this.handleSwitchChange}
          onPress={this.handleNarrow}
        />
      </View>
    );
  }
}

export default connect((state: GlobalState) => ({
  auth: getAuth(state),
  canCreateStreams: getCanCreateStreams(state),
  streams: getStreams(state),
  subscriptions: getSubscriptions(state),
}))(StreamListCard);
<|endoftext|>


<commit_before>"use strict";

import { AudioContextBuilder } from "./audio_context_builder";
import { Mixer } from "./mixer";
import { NotePlayer } from "./note_player";
import { WaveWriter } from "./wave_writer";

export function OfflineTransport(tracks, songPlayer, notePlayer, tempo, masterAmplitude, completeCallback) {
  var NUM_CHANNELS = 1;
  var SAMPLE_RATE = 44100;
  var SIXTEENTHS_PER_MINUTE = tempo * 4;
  var STEP_INTERVAL_IN_SECONDS = 60.0 / SIXTEENTHS_PER_MINUTE;
  var FADE_OUT_TIME_IN_SECONDS = 1.5;

  var calculatePlaybackTimeInSeconds = function() {
    var minimumPlaybackTime = songPlayer.stepCount() * STEP_INTERVAL_IN_SECONDS;
    var actualPlaybackTime = songPlayer.playbackTime(notePlayer, STEP_INTERVAL_IN_SECONDS);

    return Math.max(minimumPlaybackTime, actualPlaybackTime) + FADE_OUT_TIME_IN_SECONDS;
  };

  var buildOfflineAudioContext = function(playbackTimeInSeconds) {
    var sampleCount = SAMPLE_RATE * playbackTimeInSeconds;
    var offlineAudioContext = AudioContextBuilder.buildOfflineAudioContext(NUM_CHANNELS, sampleCount, SAMPLE_RATE);

    offlineAudioContext.oncomplete = function(e) {
      var waveWriter = WaveWriter();

      var sampleData = e.renderedBuffer.getChannelData(0);
      var outputView = waveWriter.write(sampleData);
      var blob = new Blob([outputView], { type: "audio/wav" });

      completeCallback(blob);
    };

    return offlineAudioContext;
  };

  var buildOfflineMixer = function(offlineAudioContext) {
    var i;
    var track;
    var offlineMixer = Mixer(offlineAudioContext);

    offlineMixer.setMasterAmplitude(masterAmplitude);

    for (i = 0; i < tracks.length; i++) {
      track = tracks[i];
      offlineMixer.addChannel(track.id, track.volume, track.isMuted, track.reverbBuffer, track.reverbWetPercentage, track.delayTime, track.delayFeedback);
    }

    offlineMixer.masterGainNode().gain.setValueAtTime(masterAmplitude, playbackTimeInSeconds - FADE_OUT_TIME_IN_SECONDS);
    offlineMixer.masterGainNode().gain.linearRampToValueAtTime(0.0, playbackTimeInSeconds);

    return offlineMixer;
  };

  var tick = function() {
    var scheduleAheadTimeInSeconds = songPlayer.stepCount() * STEP_INTERVAL_IN_SECONDS;
    var startTimeInSeconds = offlineAudioContext.currentTime;
    var finalTimeInSeconds = startTimeInSeconds + scheduleAheadTimeInSeconds;

    songPlayer.reset(startTimeInSeconds);
    songPlayer.tick(offlineMixer, notePlayer, finalTimeInSeconds, STEP_INTERVAL_IN_SECONDS, false);

    offlineAudioContext.startRendering();
  };

  var playbackTimeInSeconds = calculatePlaybackTimeInSeconds();
  var offlineAudioContext = buildOfflineAudioContext(playbackTimeInSeconds);
  var offlineMixer = buildOfflineMixer(offlineAudioContext);

  return {
    tick: tick,
  };
};
<commit_msg>Fixing regression in download to *.wav functionality<commit_after>"use strict";

import { AudioContextBuilder } from "./audio_context_builder";
import { Mixer } from "./mixer";
import { NotePlayer } from "./note_player";
import { WaveWriter } from "./wave_writer";

export function OfflineTransport(tracks, songPlayer, notePlayer, tempo, masterAmplitude, completeCallback) {
  var NUM_CHANNELS = 1;
  var SAMPLE_RATE = 44100;
  var SIXTEENTHS_PER_MINUTE = tempo * 4;
  var STEP_INTERVAL_IN_SECONDS = 60.0 / SIXTEENTHS_PER_MINUTE;
  var FADE_OUT_TIME_IN_SECONDS = 1.5;

  var calculatePlaybackTimeInSeconds = function() {
    var minimumPlaybackTime = songPlayer.stepCount() * STEP_INTERVAL_IN_SECONDS;
    var actualPlaybackTime = songPlayer.playbackTime(notePlayer, STEP_INTERVAL_IN_SECONDS);

    return Math.max(minimumPlaybackTime, actualPlaybackTime) + FADE_OUT_TIME_IN_SECONDS;
  };

  var buildOfflineAudioContext = function(playbackTimeInSeconds) {
    var sampleCount = SAMPLE_RATE * playbackTimeInSeconds;
    var offlineAudioContext = AudioContextBuilder.buildOfflineAudioContext(NUM_CHANNELS, sampleCount, SAMPLE_RATE);

    offlineAudioContext.oncomplete = function(e) {
      var waveWriter = WaveWriter();

      var sampleData = e.renderedBuffer.getChannelData(0);
      var outputView = waveWriter.write(sampleData);
      var blob = new Blob([outputView], { type: "audio/wav" });

      completeCallback(blob);
    };

    return offlineAudioContext;
  };

  var buildOfflineMixer = function(offlineAudioContext) {
    var i;
    var track;
    var offlineMixer = Mixer(offlineAudioContext);

    offlineMixer.setMasterAmplitude(masterAmplitude);

    for (i = 0; i < tracks.length; i++) {
      track = tracks[i];
      offlineMixer.addChannel(track.id, track.volume, track.isMuted, track.reverbBuffer, track.reverbWetPercentage, track.delayTime, track.delayFeedback);
    }

    offlineMixer.masterGainNode().gain.setValueAtTime(masterAmplitude, playbackTimeInSeconds - FADE_OUT_TIME_IN_SECONDS);
    offlineMixer.masterGainNode().gain.linearRampToValueAtTime(0.0, playbackTimeInSeconds);

    return offlineMixer;
  };

  var tick = function() {
    var scheduleAheadTimeInSeconds = songPlayer.stepCount() * STEP_INTERVAL_IN_SECONDS;
    var startTimeInSeconds = offlineAudioContext.currentTime;
    var finalTimeInSeconds = startTimeInSeconds + scheduleAheadTimeInSeconds;

    songPlayer.reset(startTimeInSeconds, 0);
    songPlayer.tick(offlineMixer, notePlayer, finalTimeInSeconds, STEP_INTERVAL_IN_SECONDS, false);

    offlineAudioContext.startRendering();
  };

  var playbackTimeInSeconds = calculatePlaybackTimeInSeconds();
  var offlineAudioContext = buildOfflineAudioContext(playbackTimeInSeconds);
  var offlineMixer = buildOfflineMixer(offlineAudioContext);

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


<commit_before>var http = require('http')

http.createServer(function (req, res) {
  console.log('REQ.URL:'+req.url);
  if(req.url.length < 2) {
    console.log('no token here.');
    res.writeHead(200);
    res.end
      ( ''
      + 'click');
  } else {
    var token = req.url.substring(15, 74);
    console.log('TOKEN:'+token);
    var google = http.createClient(80, 'docs.google.com');
    var request = google.request('POST', '/feeds/default/private/full',
      { 'host': 'docs.google.com'
      , 'GData-Version': '3.0'
      , 'Authorization': 'Bearer '+token
      , 'Content-Length': '0'
      , 'Content-Type': 'text/plain'
      , 'Slug': 'LetsRide'
      , 'X-Upload-Content-Length': '30'
      , 'X-Upload-Content-Type': 'text/plain'
      });
    request.end();
    request.on('response', function (response) {
      console.log('STATUS: ' + response.statusCode);
      console.log('HEADERS: ' + JSON.stringify(response.headers));
      response.setEncoding('utf8');
      response.on('data', function (chunk) {
        console.log('BODY: ' + chunk);
      });
    });
    res.writeHead(200, { 'Content-Type': 'text/plain', 'Access-Control-Allow-Origin': '*'});
    res.write('request successfully proxied: ' + req.url +'\n' + JSON.stringify(req.headers, true, 2));
    res.end();
  }
}).listen(9000);
<commit_msg>uploaded LetsRide with server6.js<commit_after>var http = require('http')
  , https = require('https');

http.createServer(function (req, res) {
  console.log('REQ.URL:'+req.url);
  if(req.url.length < 2) {
    console.log('no token here.');
    res.writeHead(200);
    res.end
      ( ''
      + 'click');
  } else {
    var token = req.url.substring(15, 74);
    console.log('TOKEN:'+token);
    var options =
      { 'host': 'docs.google.com'
      , 'port': 443
      , 'method': 'POST'
      , 'path': '/feeds/default/private/full'
      , 'headers':
         { 'GData-Version': '3.0'
         , 'Authorization': 'Bearer '+token
         , 'Content-Length': '0'
         , 'Content-Type': 'text/plain'
         , 'Slug': 'LetsRide'
         , 'X-Upload-Content-Length': '30'
         , 'X-Upload-Content-Type': 'text/plain'
         }
      };
    var req2 = https.request(options, function(res2) {
      res.writeHead(200, { 'Content-Type': 'text/plain', 'Access-Control-Allow-Origin': '*'});
      res.write('request successfully proxied: ' + req.url +'\n' + JSON.stringify(req.headers, true, 2));
      res.write('\nSTATUS: ' + res2.statusCode);
      res.write('\nHEADERS: ' + JSON.stringify(res2.headers));
      res2.setEncoding('utf8');
      res2.on('data', function (chunk) {
        res.write('\nBODY: ' + chunk);
    res.end();
      });
    });
    req2.end();
  }
}).listen(9000);
<|endoftext|>


<commit_before><commit_msg>Updates script to remove case-conflicted files<commit_after><|endoftext|>


<commit_before>'use strict';

var concat = require('gulp-concat'),
	uglify = require('gulp-uglify'),
	gulpif = require('gulp-if'),
	gutil = require('gulp-util'),
	path = require('path'),
	config = require('./package.json'),
	gulp = require('gulp'),
	PluginError = gutil.PluginError;

exports.gulpTaskFactory = function(gulpTask, options) {
	var task = function (gulpTask, options) {
		var isJs = gulpTask.indexOf('.js') > 0;

		if (options.concat !== undefined && options.concat.active && options.concat.config === undefined) {
			throw new PluginError(config.name, 'No concat settings');
		}

		if (options.uglify !== undefined && options.uglify.active && options.uglify.config === undefined) {
			throw new PluginError(config.name, 'No uglify settings');
		}

		try {
			return gulp.src(options.files[gulpTask])
				.pipe(
					gulpif(
						options.concat.active && isJs,
						concat(gulpTask)
					)
				)
				.pipe(
					gulpif(
						options.uglify.active && isJs,
						uglify(options.uglify.config)
					)
				)
				.pipe(gulp.dest(path.join(options.destinationFolder, 'js')));
		} catch (ex) {
			gutil.log(gutil.colors.red('Error creating bundle: ' + gulpTask));
			throw new PluginError(config.name, 'Error creating bundle.');
		}
	};
	return task(gulpTask, options);
};
<commit_msg>Cleaning up the GulpTaskFactory, removing isJS since we're only dealing with JS.<commit_after>'use strict';

var concat = require('gulp-concat'),
	uglify = require('gulp-uglify'),
	gulpif = require('gulp-if'),
	gutil = require('gulp-util'),
	path = require('path'),
	config = require('./package.json'),
	gulp = require('gulp'),
	PluginError = gutil.PluginError;

exports.gulpTaskFactory = function(gulpTask, options) {
	var task = function (gulpTask, options) {

		if (options.concat !== undefined && options.concat.active && options.concat.config === undefined) {
			throw new PluginError(config.name, 'No concat settings');
		}

		if (options.uglify !== undefined && options.uglify.active && options.uglify.config === undefined) {
			throw new PluginError(config.name, 'No uglify settings');
		}

		try {
			gulp.task(gulpTask, function() {
				gulp.src(options.files[gulpTask])
					.pipe(
						gulpif(
							options.concat.active,
							concat(gulpTask)
						)
					)
					.pipe(
						gulpif(
							options.uglify.active,
							uglify(options.uglify.config)
						)
					)
					.pipe(gulp.dest(path.join(options.destinationFolder, 'js')));
			});
		} catch (ex) {
			gutil.log(gutil.colors.red('Error creating bundle: ' + gulpTask));
			throw new PluginError(config.name, 'Error creating bundle.');
		}
	};
	return task(gulpTask, options);
};
<|endoftext|>


<commit_before>
var ExploreJointSourceController = JointSourceController.createComponent("ExploreJointSourceController");

ExploreJointSourceController.createViewFragment = function () {
  return cloneTemplate("#template-explore-jointsource");
};

ExploreJointSourceController.defineAlias("model", "jointSource");

ExploreJointSourceController.defineMethod("initView", function initView() {
  if (!this.view) return;

  setElementProperty(this.view, "jointsource-id", this.jointSource.jointSourceId);
  this.view.style.order = - this.jointSource.jointSourceId;

  this.view.querySelector("[data-ica-action='edit-jointsource']").addEventListener("click", function (e) {
    e.preventDefault();
    e.stopPropagation();
    var fragment = PublisherJointSourceController.createViewFragment();
    var element = fragment.querySelector(".publisher");
    document.body.appendChild(fragment);
    new PublisherJointSourceController(this.controller.jointSource, element);
  }.bind(this.view));

  this.view.addEventListener("click", function (e) {
    e.preventDefault();
    e.stopPropagation();
    var map = new Map([this.controller.jointSource]);
    var fragment = MapController.createViewFragment();
    var element = fragment.querySelector(".map");
    document.body.appendChild(fragment);
    new MapController(map, element);
  }.bind(this.view));

  new TokensController(this.jointSource.metaParticipantsHandler, this.view.querySelector("[data-ica-jointsource-meta='participants']")).componentOf = this;
  new TokensController(this.jointSource.metaThemesHandler, this.view.querySelector("[data-ica-jointsource-meta='themes']")).componentOf = this;
});

ExploreJointSourceController.defineMethod("updateView", function updateView() {
  if (!this.view) return;

  // Reset view
  var parentNode = this.view.parentNode;
  var fragment = this.constructor.createViewFragment();
  var element = fragment.querySelector(".jointsource");
  parentNode.replaceChild(fragment, this.view);
  this.uninitView();
  this._view = element;
  this.initView(false);

  this.view.querySelectorAll("[data-ica-jointsource-meta-predicate]").forEach(function (element) {
    var metaPredicate = getElementProperty(element, "jointsource-meta-predicate");
    if (empty(this.jointSource.meta[metaPredicate])) {
      element.style.display = "none";
    } else {
      element.style.display = "";
    }
  }.bind(this));

  this.view.querySelectorAll("[data-ica-jointsource-meta]").forEach(function (element) {
    element.textContent = this.jointSource.meta[getElementProperty(element, "jointsource-meta")];
  }.bind(this));

  var featuredSource = this.jointSource.sources[Object.keys(this.jointSource.sources)[0]];

  if (featuredSource) switch (featuredSource.constructor) {
    case ImageSource:
      setElementProperty(this.view, "jointsource-feature", "image");
      this.view.style.backgroundImage = featuredSource.content
        ? "url(" + (
          featuredSource.blobHandler.blob instanceof Blob
            ? featuredSource.blobHandler.url
            : featuredSource.blobHandler.url + "?width=" + (this.view.offsetWidth * this.devicePixelRatio)
          ) + ")"
        : "";
      break;
  }
});

ExploreJointSourceController.defineMethod("uninitView", function uninitView() {
  if (!this.view) return;

  removeElementProperty(this.view, "jointsource-id");
});

/*****/

function empty(value) {
  if (Array.isArray(value)) return value.length == 0;
  return !value;
}
<commit_msg>Draft audio playback when mouse hover<commit_after>
var ExploreJointSourceController = JointSourceController.createComponent("ExploreJointSourceController");

ExploreJointSourceController.createViewFragment = function () {
  return cloneTemplate("#template-explore-jointsource");
};

ExploreJointSourceController.defineAlias("model", "jointSource");

ExploreJointSourceController.defineMethod("initView", function initView() {
  if (!this.view) return;

  setElementProperty(this.view, "jointsource-id", this.jointSource.jointSourceId);
  this.view.style.order = - this.jointSource.jointSourceId;

  this.view.querySelector("[data-ica-action='edit-jointsource']").addEventListener("click", function (e) {
    e.preventDefault();
    e.stopPropagation();
    var fragment = PublisherJointSourceController.createViewFragment();
    var element = fragment.querySelector(".publisher");
    document.body.appendChild(fragment);
    new PublisherJointSourceController(this.controller.jointSource, element);
  }.bind(this.view));

  this.view.addEventListener("click", function (e) {
    e.preventDefault();
    e.stopPropagation();
    var map = new Map([this.controller.jointSource]);
    var fragment = MapController.createViewFragment();
    var element = fragment.querySelector(".map");
    document.body.appendChild(fragment);
    new MapController(map, element);
  }.bind(this.view));

  new TokensController(this.jointSource.metaParticipantsHandler, this.view.querySelector("[data-ica-jointsource-meta='participants']")).componentOf = this;
  new TokensController(this.jointSource.metaThemesHandler, this.view.querySelector("[data-ica-jointsource-meta='themes']")).componentOf = this;
});

ExploreJointSourceController.defineMethod("updateView", function updateView() {
  if (!this.view) return;

  // Reset view
  var parentNode = this.view.parentNode;
  var fragment = this.constructor.createViewFragment();
  var element = fragment.querySelector(".jointsource");
  parentNode.replaceChild(fragment, this.view);
  this.uninitView();
  this._view = element;
  this.initView(false);

  this.view.querySelectorAll("[data-ica-jointsource-meta-predicate]").forEach(function (element) {
    var metaPredicate = getElementProperty(element, "jointsource-meta-predicate");
    if (empty(this.jointSource.meta[metaPredicate])) {
      element.style.display = "none";
    } else {
      element.style.display = "";
    }
  }.bind(this));

  this.view.querySelectorAll("[data-ica-jointsource-meta]").forEach(function (element) {
    element.textContent = this.jointSource.meta[getElementProperty(element, "jointsource-meta")];
  }.bind(this));

  var featuredSource = this.jointSource.sources[Object.keys(this.jointSource.sources)[0]];

  if (featuredSource) switch (featuredSource.constructor) {
  case ImageSource:

    setElementProperty(this.view, "jointsource-feature", "image");
    this.view.style.backgroundImage = featuredSource.content
      ? "url(" + (
        featuredSource.blobHandler.blob instanceof Blob
          ? featuredSource.blobHandler.url
          : featuredSource.blobHandler.url + "?width=" + (this.view.offsetWidth * this.devicePixelRatio)
        ) + ")"
      : "";

    break;
  case AudioSource:

    setElementProperty(this.view, "jointsource-feature", "audio");
    if (featuredSource.content) {
      var audio = new Audio(featuredSource.blobHandler.url);

      this.view.audio = audio;

      this.view.addEventListener("mouseover", function mouseOver() {
        this.audio.play();
      }.bind(this.view));
      this.view.addEventListener("mouseout", function mouseOver() {
        this.audio.pause();
        this.audio.currentTime = 0;
      }.bind(this.view));
    }

    break;
  }
});

ExploreJointSourceController.defineMethod("uninitView", function uninitView() {
  if (!this.view) return;

  removeElementProperty(this.view, "jointsource-id");
});

/*****/

function empty(value) {
  if (Array.isArray(value)) return value.length == 0;
  return !value;
}
<|endoftext|>


<commit_before>import { template, last, isEmpty, dropRight } from 'lodash';

const path = require('path');
const archiver = require('archiver');
const shortid = require('shortid');
const fs = require('fs-extra');
const Promise = require('bluebird');
const cpy = require('cpy');
const copy = Promise.promisify(fs.copy);
const readFile = Promise.promisify(fs.readFile);
const writeFile = Promise.promisify(fs.writeFile);
const appendFile = Promise.promisify(fs.appendFile);
const remove = Promise.promisify(fs.remove);
const readJson = Promise.promisify(fs.readJson);
const writeJson = Promise.promisify(fs.writeJson);
const stat = Promise.promisify(fs.stat);
const mkdirs = Promise.promisify(fs.mkdirs);

const npmDependencies = require('./npmDependencies.json');

export { cpy };
export { copy };
export { remove };
export { mkdirs };
export { readFile };
export { writeFile };
export { appendFile };
export { readJson };
export { writeJson };

/**
 * @private
 * @param subStr {string} - what to indent
 * @param options {object} - how many levels (2 spaces per level) or how many spaces to indent
 * @returns {string}
 */
function indentCode(subStr, options) {
  const defaultIndentation = 2;
  let indent;

  if (options.indentLevel) {
    indent = ' '.repeat(options.indentLevel * defaultIndentation);
  } else if (options.indentSpaces) {
    indent = ' '.repeat(options.indentSpaces);
  }
  let array = subStr.toString().split('\n').filter(Boolean);
  array.forEach((line, index) => {
    array[index] = indent + line;
  });
  return array.join('\n');
}

/**
 * Traverse files and remove placeholder comments
 * @param params
 */
export function walkAndRemoveComments(params) {
  const build = path.join(__base, 'build', params.uuid);

  return new Promise((resolve, reject) => {
    fs.walk(build)
      .on('data', (item) => {
        return stat(item.path).then((stats) => {
          if (stats.isFile()) {
            return removeCode(item.path, '//=');
          }
        });
      })
      .on('error', (err) => {
        reject(err);
      })
      .on('end', () => {
        resolve();
      });
  });
}

export async function exists(filepath) {
  try {
    await stat(filepath);
  } catch (err) {
    if (err.code === 'ENOENT') {
      return false;
    }
  }
  return true;
}

export function generateZip(req, res) {
  let archive = archiver('zip');

  archive.on('error', function(err) {
    res.status(500).send(err.message);
  });

  res.on('close', function() {
    console.log('closing...');
    console.log('Archive wrote %d bytes', archive.pointer());
    return res.status(200).send('OK').end();
  });

  res.attachment('megaboilerplate-express.zip');

  archive.pipe(res);

  let files = [
    __base + '/modules/express/app.js',
    __base + '/modules/express/package.json'
  ];

  for (let i in files) {
    archive.append(fs.createReadStream(files[i]), { name: path.basename(files[i]) });
  }

  archive.finalize();
}

/**
 * Add NPM package to package.json.
 * @param pkgName
 * @param params
 * @param isDev
 */
export async function addNpmPackage(pkgName, params, isDev) {
  const packageJson = path.join(__base, 'build', params.uuid, 'package.json');
  const packageObj = await readJson(packageJson);
  const pkgVersion = npmDependencies[pkgName];

  if (isDev) {
    packageObj.devDependencies = packageObj.devDependencies || {};
    packageObj.devDependencies[pkgName] = pkgVersion;
  } else {
    packageObj.dependencies[pkgName] = pkgVersion;
  }

  // Sort dependencies alphabetically in package.json
  packageObj.dependencies = sortJson(packageObj.dependencies);

  if (packageObj.devDependencies) {
    packageObj.devDependencies = sortJson(packageObj.devDependencies);
  }

  await writeJson(packageJson, packageObj, { spaces: 2 });
}

function sortJson(obj) {
  return Object.keys(obj).sort().reduce((a, b) => {
    a[b] = obj[b];
    return a;
  }, {});
}

/**
 * Add NPM script to package.json.
 */
export async function addNpmScript(name, value, params) {
  const packageJson = path.join(__base, 'build', params.uuid, 'package.json');
  const packageObj = await readJson(packageJson);
  packageObj.scripts[name] = value;
  await writeJson(packageJson, packageObj, { spaces: 2 });
}

/**
 * Cleanup build files.
 * @param params
 */
export async function cleanup(params) {
  await remove(path.join(__base, 'build', params.uuid));
}

export async function prepare(params) {
  //params.uuid = shortid.generate();
  // TODO: Remove
  params.uuid = 'testing';
  await remove(path.join(__base, 'build', params.uuid));

  await mkdirs(path.join(__base, 'build', params.uuid));
  console.info('Created', params.uuid);
  return params;
}

/**
 * @param srcFile {buffer} - where to remove
 * @param subStr {string} - what to remove
 * @returns {string}
 */
export async function removeCode(srcFile, subStr) {
  let srcData = await readFile(srcFile);
  let array = srcData.toString().split('\n');
  array.forEach((line, index) => {
    if (line.includes(subStr)) {
      array[index] = null;
    }
  });
  array = array.filter((value) => {
    return value !== null;
  });
  srcData = array.join('\n');
  await writeFile(srcFile, srcData);
}

/**
 *
 * @param srcFile {buffer} - where to replace
 * @param subStr {string} - what to replace
 * @param newSrcFile {string} - replace it with this
 * @param [opts] {object} - options
 * @returns {string}
 */
export async function replaceCode(srcFile, subStr, newSrcFile, opts) {
  opts = opts || {};

  let srcData = await readFile(srcFile);
  let newSrcData = await readFile(newSrcFile);

  const array = srcData.toString().split('\n');

  array.forEach((line, index) => {
    const re = new RegExp(subStr + '$|(\r\n|\r|\n)');
    const isMatch = re.test(line);

    // Preserve whitespace if it detects //_ token
    if (line.indexOf('//_') > - 1) {
      array[index] = '';
    }

    if (isMatch) {
      if (opts.indentLevel) {
        newSrcData = indentCode(newSrcData, { indentLevel: opts.indentLevel });
      }

      if (opts.indentSpaces) {
        newSrcData = indentCode(newSrcData, { indentSpaces: opts.indentSpaces });
      }

      if (isEmpty(last(newSrcData.toString().split('\n')))) {
        newSrcData = dropRight(newSrcData.toString().split('\n')).join('\n');
      }

      if (opts.leadingBlankLine) {
        newSrcData = ['\n', newSrcData].join('');
      }

      array[index] = newSrcData;
    }
  });

  srcData = array.join('\n');

  await writeFile(srcFile, srcData);
}

/**
 * lodash _.template() function
 * @param srcFile
 * @param data
 */
export async function templateReplace(srcFile, data) {
  const src = await readFile(srcFile);
  const compiled = template(src.toString());
  const newSrc = compiled(data);
  await writeFile(srcFile, newSrc);
}

/**
 * Add env vars to .env
 * @param params
 * @param data
 */
export async function addEnv(params, data) {
  const env = path.join(__base, 'build', params.uuid, '.env');
  const vars = [];
  for (const i in data) {
    if (data.hasOwnProperty(i)) {
      vars.push([i, `'${data[i]}'`].join('='));
    }
  }
  await appendFile(env, '\n' + vars.join('\n') + '\n');
}
<commit_msg>Modify removeCode to clean up empty classes<commit_after>import { template, last, isEmpty, dropRight } from 'lodash';

const path = require('path');
const archiver = require('archiver');
const shortid = require('shortid');
const fs = require('fs-extra');
const Promise = require('bluebird');
const cpy = require('cpy');
const copy = Promise.promisify(fs.copy);
const readFile = Promise.promisify(fs.readFile);
const writeFile = Promise.promisify(fs.writeFile);
const appendFile = Promise.promisify(fs.appendFile);
const remove = Promise.promisify(fs.remove);
const readJson = Promise.promisify(fs.readJson);
const writeJson = Promise.promisify(fs.writeJson);
const stat = Promise.promisify(fs.stat);
const mkdirs = Promise.promisify(fs.mkdirs);

const npmDependencies = require('./npmDependencies.json');

export { cpy };
export { copy };
export { remove };
export { mkdirs };
export { readFile };
export { writeFile };
export { appendFile };
export { readJson };
export { writeJson };

/**
 * @private
 * @param subStr {string} - what to indent
 * @param options {object} - how many levels (2 spaces per level) or how many spaces to indent
 * @returns {string}
 */
function indentCode(subStr, options) {
  const defaultIndentation = 2;
  let indent;

  if (options.indentLevel) {
    indent = ' '.repeat(options.indentLevel * defaultIndentation);
  } else if (options.indentSpaces) {
    indent = ' '.repeat(options.indentSpaces);
  }
  let array = subStr.toString().split('\n').filter(Boolean);
  array.forEach((line, index) => {
    array[index] = indent + line;
  });
  return array.join('\n');
}

/**
 * Traverse files and remove placeholder comments
 * @param params
 */
export function walkAndRemoveComments(params) {
  const build = path.join(__base, 'build', params.uuid);

  return new Promise((resolve, reject) => {
    fs.walk(build)
      .on('data', (item) => {
        return stat(item.path).then((stats) => {
          if (stats.isFile()) {
            return removeCode(item.path, '//=')
              .then(() => {
                const isComponent = item.path.includes('components');
                const isHTML = item.path.includes('.html');
                if (isComponent || isHTML) {
                  return removeCssClass(item.path);
                }
              });
          }
        });
      })
      .on('error', (err) => {
        reject(err);
      })
      .on('end', () => {
        resolve();
      });
  });
}

export async function exists(filepath) {
  try {
    await stat(filepath);
  } catch (err) {
    if (err.code === 'ENOENT') {
      return false;
    }
  }
  return true;
}

export function generateZip(req, res) {
  let archive = archiver('zip');

  archive.on('error', function(err) {
    res.status(500).send(err.message);
  });

  res.on('close', function() {
    console.log('closing...');
    console.log('Archive wrote %d bytes', archive.pointer());
    return res.status(200).send('OK').end();
  });

  res.attachment('megaboilerplate-express.zip');

  archive.pipe(res);

  let files = [
    __base + '/modules/express/app.js',
    __base + '/modules/express/package.json'
  ];

  for (let i in files) {
    archive.append(fs.createReadStream(files[i]), { name: path.basename(files[i]) });
  }

  archive.finalize();
}

/**
 * Add NPM package to package.json.
 * @param pkgName
 * @param params
 * @param isDev
 */
export async function addNpmPackage(pkgName, params, isDev) {
  const packageJson = path.join(__base, 'build', params.uuid, 'package.json');
  const packageObj = await readJson(packageJson);
  const pkgVersion = npmDependencies[pkgName];

  if (isDev) {
    packageObj.devDependencies = packageObj.devDependencies || {};
    packageObj.devDependencies[pkgName] = pkgVersion;
  } else {
    packageObj.dependencies[pkgName] = pkgVersion;
  }

  // Sort dependencies alphabetically in package.json
  packageObj.dependencies = sortJson(packageObj.dependencies);

  if (packageObj.devDependencies) {
    packageObj.devDependencies = sortJson(packageObj.devDependencies);
  }

  await writeJson(packageJson, packageObj, { spaces: 2 });
}

function sortJson(obj) {
  return Object.keys(obj).sort().reduce((a, b) => {
    a[b] = obj[b];
    return a;
  }, {});
}

/**
 * Add NPM script to package.json.
 */
export async function addNpmScript(name, value, params) {
  const packageJson = path.join(__base, 'build', params.uuid, 'package.json');
  const packageObj = await readJson(packageJson);
  packageObj.scripts[name] = value;
  await writeJson(packageJson, packageObj, { spaces: 2 });
}

/**
 * Cleanup build files.
 * @param params
 */
export async function cleanup(params) {
  await remove(path.join(__base, 'build', params.uuid));
}

export async function prepare(params) {
  //params.uuid = shortid.generate();
  // TODO: Remove
  params.uuid = 'testing';
  await remove(path.join(__base, 'build', params.uuid));

  await mkdirs(path.join(__base, 'build', params.uuid));
  console.info('Created', params.uuid);
  return params;
}

/**
 * @param srcFile {buffer} - where to remove
 * @param subStr {string} - what to remove
 * @returns {string}
 */
export async function removeCode(srcFile, subStr) {
  let srcData = await readFile(srcFile);
  let array = srcData.toString().split('\n');
  const classAttr = ' class=""' || ' className=""';

  array.forEach((line, index) => {
    if (line.includes(classAttr)) {
      array[index] = line.split(classAttr).join('');
    }
    if (line.includes(subStr)) {
      array[index] = null;
    }
  });
  array = array.filter((value) => {
    return value !== null;
  });
  srcData = array.join('\n');
  await writeFile(srcFile, srcData);
}

/**
 *
 * @param srcFile {buffer} - where to replace
 * @param subStr {string} - what to replace
 * @param newSrcFile {string} - replace it with this
 * @param [opts] {object} - options
 * @returns {string}
 */
export async function replaceCode(srcFile, subStr, newSrcFile, opts) {
  opts = opts || {};

  let srcData = await readFile(srcFile);
  let newSrcData = await readFile(newSrcFile);

  const array = srcData.toString().split('\n');

  array.forEach((line, index) => {
    const re = new RegExp(subStr + '$|(\r\n|\r|\n)');
    const isMatch = re.test(line);

    // Preserve whitespace if it detects //_ token
    if (line.indexOf('//_') > - 1) {
      array[index] = '';
    }

    if (isMatch) {
      if (opts.indentLevel) {
        newSrcData = indentCode(newSrcData, { indentLevel: opts.indentLevel });
      }

      if (opts.indentSpaces) {
        newSrcData = indentCode(newSrcData, { indentSpaces: opts.indentSpaces });
      }

      if (isEmpty(last(newSrcData.toString().split('\n')))) {
        newSrcData = dropRight(newSrcData.toString().split('\n')).join('\n');
      }

      if (opts.leadingBlankLine) {
        newSrcData = ['\n', newSrcData].join('');
      }

      array[index] = newSrcData;
    }
  });

  srcData = array.join('\n');

  await writeFile(srcFile, srcData);
}

/**
 * lodash _.template() function
 * @param srcFile
 * @param data
 */
export async function templateReplace(srcFile, data) {
  const src = await readFile(srcFile);
  const compiled = template(src.toString());
  const newSrc = compiled(data);
  await writeFile(srcFile, newSrc);
}

/**
 * Add env vars to .env
 * @param params
 * @param data
 */
export async function addEnv(params, data) {
  const env = path.join(__base, 'build', params.uuid, '.env');
  const vars = [];
  for (const i in data) {
    if (data.hasOwnProperty(i)) {
      vars.push([i, `'${data[i]}'`].join('='));
    }
  }
  await appendFile(env, '\n' + vars.join('\n') + '\n');
}
<|endoftext|>


<commit_before>'use strict'
exports.getChapterList = getChapterList
exports.scrapeChapterList = scrapeChapterList
var url = require('url')
var getChapter = require('./get-chapter.js')
var cheerio = require('cheerio')
var inherits = require('util').inherits

function ChapterList () {
  Array.call(this, arguments)
}
ChapterList.prototype = {}
inherits(ChapterList, Array)

ChapterList.prototype.addChapter = function (baseName, link) {
  var name = baseName
  var ctr = 0
  while (this.some(function (chap) { return chap.name === name })) {
    name = baseName + ' (' + ++ctr + ')'
  }
  this.push({name: name, link: link})
}

function getChapterList (fetch, thread) {
  return fetch(thread.threadmarks).then(function (res) {
    return res.text()
  }).then(function (html) {
    var $ = cheerio.load(html)
    var base = $('base').attr('href') || thread.threadmarks
    var links = $('li.primaryContent.memberListItem > a')
    var threadMarks = new ChapterList()
    links.each(function () {
      var name = $(this).text().trim()
      var link = $(this).attr('href')
      threadMarks.addChapter(name, url.resolve(base, link))
    })
    return threadMarks
  })
}

function scrapeChapterList (fetch, thread) {
  return getChapter(fetch, thread.raw).then(function (chapter) {
    var $ = cheerio.load(chapter.content)
    var scraped = new ChapterList()
    var links = $('a.internalLink')
    if (links.length === 0) {
      scraped.addChapter(chapter.workTitle, chapter.finalURL)
    } else {
      scraped.addChapter('Index', chapter.finalURL)
    }
    links.each(function (_, link) {
      var $link = $(link)
      var href = url.resolve(chapter.base, $link.attr('href'))
      var name = $link.text().trim()
      if (/^[/]threads[/]|^[/]index.php[?]topic|^[/]posts[/]/.test(url.parse(href).path)) {
        scraped.addChapter(name, href)
      }
    })
    return scraped
  })
}
<commit_msg>Don't add the same chapter link more than once<commit_after>'use strict'
exports.getChapterList = getChapterList
exports.scrapeChapterList = scrapeChapterList
var url = require('url')
var getChapter = require('./get-chapter.js')
var cheerio = require('cheerio')
var inherits = require('util').inherits

function ChapterList () {
  Array.call(this, arguments)
}
ChapterList.prototype = {}
inherits(ChapterList, Array)

ChapterList.prototype.addChapter = function (baseName, link) {
  if (this.some(function (chap) { return chap.link === link })) return
  var name = baseName
  var ctr = 0
  while (this.some(function (chap) { return chap.name === name })) {
    name = baseName + ' (' + ++ctr + ')'
  }
  this.push({name: name, link: link})
}

function getChapterList (fetch, thread) {
  return fetch(thread.threadmarks).then(function (res) {
    return res.text()
  }).then(function (html) {
    var $ = cheerio.load(html)
    var base = $('base').attr('href') || thread.threadmarks
    var links = $('li.primaryContent.memberListItem > a')
    var threadMarks = new ChapterList()
    links.each(function () {
      var name = $(this).text().trim()
      var link = $(this).attr('href')
      threadMarks.addChapter(name, url.resolve(base, link))
    })
    return threadMarks
  })
}

function scrapeChapterList (fetch, thread) {
  return getChapter(fetch, thread.raw).then(function (chapter) {
    var $ = cheerio.load(chapter.content)
    var scraped = new ChapterList()
    var links = $('a.internalLink')
    if (links.length === 0) {
      scraped.addChapter(chapter.workTitle, chapter.finalURL)
    } else {
      scraped.addChapter('Index', chapter.finalURL)
    }
    links.each(function (_, link) {
      var $link = $(link)
      var href = url.resolve(chapter.base, $link.attr('href'))
      var name = $link.text().trim()
      if (/^[/]threads[/]|^[/]index.php[?]topic|^[/]posts[/]/.test(url.parse(href).path)) {
        scraped.addChapter(name, href)
      }
    })
    return scraped
  })
}
<|endoftext|>


<commit_before>var _                = require('underscore');
var gilbarbara_logos = require('logos/app/logos');
var path             = require('path');

module.exports = _.chain(gilbarbara_logos)
	.result('items')
	.map(function(logo) {
		return _.map(logo.files, function(file, i) {
			return {
				id:      'svg-porn/' + logo.shortname + '/' + i,
				name:    logo.name,
				svg_url: path.join(__dirname, 'node_modules/logos/logos', file),
				source:  {
					name:      'SVG PORN',
					shortname: 'svg-porn'
				}
			};
		});
	})
	.flatten()
	.value();
<commit_msg>if we use shortnames for filesname, slashes might end up being a problem<commit_after>var _                = require('underscore');
var gilbarbara_logos = require('logos/app/logos');
var path             = require('path');

module.exports = _.chain(gilbarbara_logos)
	.result('items')
	.map(function(logo) {
		return _.map(logo.files, function(file, i) {
			return {
				id:      'svg-porn-' + logo.shortname + '-' + i,
				name:    logo.name,
				svg_url: path.join(__dirname, 'node_modules/logos/logos', file),
				source:  {
					name:      'SVG PORN',
					shortname: 'svg-porn'
				}
			};
		});
	})
	.flatten()
	.value();
<|endoftext|>


<commit_before>/*
	Requires gamepadGetters.js to be loaded
*/

// Displays information on connected Gamepads in the HTML
function displayInfo() {

	var activeGPs = getActiveGPs()

	// Display a notice based on the number of connected Gamepads
	if (activeGPs.length == 0) {
		document.getElementById("top").innerHTML =
		"
No Gamepads Detected

If a Gamepad is connected," +
		" try pressing one of its buttons
";
	}
	else if (activeGPs.length == 1){
		document.getElementById("top").innerHTML =
		"
1 Gamepad Detected
";
	}
	else {
		document.getElementById("top").innerHTML =
		"
" + activeGPs.length +
		" Gamepads Detected
";
	}

	// Clear the GPs div
	document.getElementById("GPs").innerHTML = "";

	// Populate the GPs div with a gamepad div for each connected
	// gamepad, containing information about that gamepad
	activeGPs.forEach( function(g){
		var msgPart1 = "
" +
		"

Gamepad " +
		String(g.index) +
		"
ID: " +
		g.id +
		"
" +
		String(g.buttons.length) +
		" buttons
" +
		String(g.axes.length) +
		" axes
Mapping: ";

		if (g.mapping == "") {
			document.getElementById("GPs").innerHTML += msgPart1 +
			"None

";
		}
		else {
			document.getElementById("GPs").innerHTML += msgPart1 +
			String(g.mapping)+
			"

";
		}

	});
}

function displayButtons() {
	var activeGPs = getActiveGPs()

	activeGPs.forEach( function(g) {
		var divID = "bd" + String(g.index);
		// document.getElementById(divID).innerHTML = "";
		// getActiveButtons(g).forEach( function(b){
		// 	document.getElementById(divID).innerHTML += String(b);
		// });
		var bkgrnd = "url('./img/controller.png')";
		getActiveButtons(g).forEach( function(b){
			var highlight = ", url('./img/" + String(b) + ".png')";
			bkgrnd = bkgrnd.concat(highlight);
		});
		document.getElementById(divID).style.background = bkgrnd;
	});

}<commit_msg>Readding printing of button numbers to the div.<commit_after>/*
	Requires gamepadGetters.js to be loaded
*/

// Displays information on connected Gamepads in the HTML
function displayInfo() {

	var activeGPs = getActiveGPs()

	// Display a notice based on the number of connected Gamepads
	if (activeGPs.length == 0) {
		document.getElementById("top").innerHTML =
		"
No Gamepads Detected

If a Gamepad is connected," +
		" try pressing one of its buttons
";
	}
	else if (activeGPs.length == 1){
		document.getElementById("top").innerHTML =
		"
1 Gamepad Detected
";
	}
	else {
		document.getElementById("top").innerHTML =
		"
" + activeGPs.length +
		" Gamepads Detected
";
	}

	// Clear the GPs div
	document.getElementById("GPs").innerHTML = "";

	// Populate the GPs div with a gamepad div for each connected
	// gamepad, containing information about that gamepad
	activeGPs.forEach( function(g){
		var msgPart1 = "
" +
		"

Gamepad " +
		String(g.index) +
		"
ID: " +
		g.id +
		"
" +
		String(g.buttons.length) +
		" buttons
" +
		String(g.axes.length) +
		" axes
Mapping: ";

		if (g.mapping == "") {
			document.getElementById("GPs").innerHTML += msgPart1 +
			"None

";
		}
		else {
			document.getElementById("GPs").innerHTML += msgPart1 +
			String(g.mapping)+
			"

";
		}

	});
}

function displayButtons() {
	var activeGPs = getActiveGPs()

	activeGPs.forEach( function(g) {
		var divID = "bd" + String(g.index);

		document.getElementById(divID).innerHTML = "";
		getActiveButtons(g).forEach( function(b){
			document.getElementById(divID).innerHTML += String(b);
		});

		var bkgrnd = "url('./img/controller.png')";
		getActiveButtons(g).forEach( function(b){
			var highlight = ", url('./img/" + String(b) + ".png')";
			bkgrnd = bkgrnd.concat(highlight);
		});
		document.getElementById(divID).style.background = bkgrnd;
	});

}<|endoftext|>


<commit_before>var LocalStrategy = require('passport-local').Strategy;
var User = require("./../models/users");

module.exports = function (passport) {

    passport.use('login', new LocalStrategy({
            passReqToCallback: true
        },
        function (req, username, password, done) {
            // check in mongo if a user with username exists or not
            User.newLogin(username, password, function (err, user) {
                if (err || !user) {
                    console.log("User "+ username + ': Wrong login or password');
                    return done(null, false, req.flash("message", "Wrong login or password"));
                } else {
                    console.log("User " + user.email + " is now logged in");
                    return done(null, user);
                }
            });
            // User and password both match, return user from done method
            // which will be treated like success

        }
    ));

};<commit_msg>fix passport issue<commit_after>var LocalStrategy = require('passport-local').Strategy;
var User = require("./users");

module.exports = function (passport) {

    passport.use('login', new LocalStrategy({
            passReqToCallback: true
        },
        function (req, username, password, done) {
            // check in mongo if a user with username exists or not
            User.newLogin(username, password, function (err, user) {
                if (err || !user) {
                    console.log("User "+ username + ': Wrong login or password');
                    return done(null, false, req.flash("message", "Wrong login or password"));
                } else {
                    console.log("User " + user.email + " is now logged in");
                    return done(null, user);
                }
            });
            // User and password both match, return user from done method
            // which will be treated like success

        }
    ));

};<|endoftext|>


<commit_before>//PLUGIN: facebook

(function (Popcorn){
/**
   * Facebook Popcorn plug-in
   * Places Facebook's "social plugins" inside a div ( http://developers.facebook.com/docs/plugins/ )
   * Sets options according to user input or default values
   * Options parameter will need a target and a type
   * Type is the name of the plugin in fbxml format. i.e: <fb:like> would have a type of like, respectively
   * Target is the id of the document element that the text needs to be
   * attached to, this target element must exist on the DOM
   *
   * @param {Object} options
   *
   * Example:
     var p = Popcorn('#video')
        .facebook({
          id: "fb-likebox",
          href: "http://www.facebook.com/senecacollege",
          type: "LIKE-BOX",
          show_faces: "true",
          header: "false",
          target: 'likeboxdiv'
        } )

    This will show how many people "like" Seneca College's Facebook page, and show their profile pictures (show_faces)
   *
   */
  Popcorn.plugin( "facebook" , {
    manifest:{
      about:{
        name   : "Popcorn Facebook Plugin",
        version: "0.1",
        author : "Dan Ventura",
        website: "dsventura.blogspot.com"
      },
      options:{
        id     : {elem:'input', type:'text', label:'Id'},
        type   : {elem:"input", type:'text', label:"Type"},
        target : 'facebook-container'
      }
    },

    _setup: function( options ) {

      // facebook script requires a div named fb-root
      if( !document.getElementById('fb-root') ) {
        var fbRoot = document.createElement( 'div' );
        fbRoot.id = "fb-root";
        document.body.appendChild( fbRoot );
        //initialize facebook JS SDK
        window.fbAsyncInit = function() {
          FB.init({
            appId  : 'YOUR APP ID',
            status : true,
            cookie : true,
            xfbml  : true
          });
        };
        //load facebook script asynchronously
        (function() {
          var e = document.createElement( 'script' );
          e.setAttribute( 'src', 'http://connect.facebook.net/en_US/all.js' );
          e.setAttribute( 'async', 'true' );
          document.getElementById( 'fb-root' ).appendChild( e );
        }());
      }

      options._container = document.createElement( 'fb:' + options.type.toLowerCase() );

      //setOptions property list doesn't accept dashes
      if(options.type === "LIKE-BOX") {
      console.log(options.type);
        options.type = "likebox";
        console.log(options.type);
      }

      //
      var setOptions = (function ( options ) {
        options._container.setAttribute( 'href', ( options.href || document.URL ) );
        return {
          like: function () {
            options._container.setAttribute( 'width', ( options.width || "450" ) );
            options._container.setAttribute( 'show_faces', ( options.show_faces || "false" ) );
            options._container.setAttribute( 'layout', ( options.layout || "standard" ) );
            options._container.setAttribute( 'font', options.font );
          },
          likebox: function () {
            options._container.setAttribute( 'width', ( options.width || "292" ) );
            options._container.setAttribute( 'show_faces', ( options.show_faces || "false" ) );
            options._container.setAttribute( 'stream', ( options.stream || "false" ) );
            options._container.setAttribute( 'header', ( options.header || "true" ) );
          },
          facepile: function () {
            options._container.setAttribute( 'width', ( options.width || "200" ) );
            options._container.setAttribute( 'max_rows', ( options.max_rows || "1" ) );
          },
          activity: function () {
            options._container.setAttribute( 'width', ( options.width || "300" ) );
            options._container.setAttribute( 'height', ( options.height || "300" ) );
            options._container.setAttribute( 'header', ( options.header || "true" ) );
            options._container.setAttribute( 'border_color', ( options.border_color || "#000000" ) );
            options._container.setAttribute( 'recommendations', ( options.recommendations || "false" ) );
            options._container.setAttribute( 'font', options.font );
          },
        };
      })( options );

      setOptions[ options.type.toLowerCase() ] && setOptions[ options.type.toLowerCase() ]();

      if ( document.getElementById( options.target ) ) {
        document.getElementById( options.target ).appendChild( options._container );
      }
    }
  });

})( Popcorn );<commit_msg>removed console.log calls and a trailing comma<commit_after>//PLUGIN: facebook

(function (Popcorn){
/**
   * Facebook Popcorn plug-in
   * Places Facebook's "social plugins" inside a div ( http://developers.facebook.com/docs/plugins/ )
   * Sets options according to user input or default values
   * Options parameter will need a target and a type
   * Type is the name of the plugin in fbxml format. i.e: <fb:like> would have a type of like, respectively
   * Target is the id of the document element that the text needs to be
   * attached to, this target element must exist on the DOM
   *
   * @param {Object} options
   *
   * Example:
     var p = Popcorn('#video')
        .facebook({
          id: "fb-likebox",
          href: "http://www.facebook.com/senecacollege",
          type: "LIKE-BOX",
          show_faces: "true",
          header: "false",
          target: 'likeboxdiv'
        } )

    This will show how many people "like" Seneca College's Facebook page, and show their profile pictures (show_faces)
   *
   */
  Popcorn.plugin( "facebook" , {
    manifest:{
      about:{
        name   : "Popcorn Facebook Plugin",
        version: "0.1",
        author : "Dan Ventura",
        website: "dsventura.blogspot.com"
      },
      options:{
        id     : {elem:'input', type:'text', label:'Id'},
        type   : {elem:"input", type:'text', label:"Type"},
        target : 'facebook-container'
      }
    },

    _setup: function( options ) {

      // facebook script requires a div named fb-root
      if( !document.getElementById('fb-root') ) {
        var fbRoot = document.createElement( 'div' );
        fbRoot.id = "fb-root";
        document.body.appendChild( fbRoot );
        //initialize facebook JS SDK
        window.fbAsyncInit = function() {
          FB.init({
            appId  : 'YOUR APP ID',
            status : true,
            cookie : true,
            xfbml  : true
          });
        };
        //load facebook script asynchronously
        (function() {
          var e = document.createElement( 'script' );
          e.setAttribute( 'src', 'http://connect.facebook.net/en_US/all.js' );
          e.setAttribute( 'async', 'true' );
          document.getElementById( 'fb-root' ).appendChild( e );
        }());
      }

      options._container = document.createElement( 'fb:' + options.type.toLowerCase() );

      //setOptions property list doesn't accept dashes
      if(options.type === "LIKE-BOX") {
        options.type = "likebox";
      }

      var setOptions = (function ( options ) {
        options._container.setAttribute( 'href', ( options.href || document.URL ) );
        return {
          like: function () {
            options._container.setAttribute( 'width', ( options.width || "450" ) );
            options._container.setAttribute( 'show_faces', ( options.show_faces || "false" ) );
            options._container.setAttribute( 'layout', ( options.layout || "standard" ) );
            options._container.setAttribute( 'font', options.font );
          },
          likebox: function () {
            options._container.setAttribute( 'width', ( options.width || "292" ) );
            options._container.setAttribute( 'show_faces', ( options.show_faces || "false" ) );
            options._container.setAttribute( 'stream', ( options.stream || "false" ) );
            options._container.setAttribute( 'header', ( options.header || "true" ) );
          },
          facepile: function () {
            options._container.setAttribute( 'width', ( options.width || "200" ) );
            options._container.setAttribute( 'max_rows', ( options.max_rows || "1" ) );
          },
          activity: function () {
            options._container.setAttribute( 'width', ( options.width || "300" ) );
            options._container.setAttribute( 'height', ( options.height || "300" ) );
            options._container.setAttribute( 'header', ( options.header || "true" ) );
            options._container.setAttribute( 'border_color', ( options.border_color || "#000000" ) );
            options._container.setAttribute( 'recommendations', ( options.recommendations || "false" ) );
            options._container.setAttribute( 'font', options.font );
          }
        };
      })( options );

      setOptions[ options.type.toLowerCase() ] && setOptions[ options.type.toLowerCase() ]();

      if ( document.getElementById( options.target ) ) {
        document.getElementById( options.target ).appendChild( options._container );
      }
    }
  });

})( Popcorn );<|endoftext|>


<commit_before>/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           ______     ______     ______   __  __     __     ______
          /\  == \   /\  __ \   /\__  _\ /\ \/ /    /\ \   /\__  _\
          \ \  __<   \ \ \/\ \  \/_/\ \/ \ \  _"-.  \ \ \  \/_/\ \/
           \ \_____\  \ \_____\    \ \_\  \ \_\ \_\  \ \_\    \ \_\
            \/_____/   \/_____/     \/_/   \/_/\/_/   \/_/     \/_/
*/

if (!process.env.token) {
    console.log('Error: Specify token in environment');
    process.exit(1);
}

var Botkit = require('./lib/Botkit.js');
var mongoose = require('mongoose');
var os = require('os');

var controller = Botkit.slackbot({
    debug: false,
});

mongoose.connect('mongodb://localhost/slackbot');
var UserSchema = new mongoose.Schema({
    user: String,
    github: String,
    refNum: Number,
    updated_at: {type: Date, default: Date.now}
});
mongoose.model('User', UserSchema);

//Build mongo objects

var bot = controller.spawn({
    token: process.env.token
}).startRTM();

controller.hears(['!reg (.*)', '.reg (.*)', '!register (.*)', '.register (.*)'], 'direct_message', function(bot, message) {
    //Get usernick
    var usernick = "";
    for (i in bot.users) {
        if (i['id'] == message.user){
            usernick = i['name'];
        }
    }

    //******************************************************
    //Need to add webcrawl checks to make sure this is valid
    //******************************************************
    var newGithub = message.match[1];

    var User = mongoose.model("User");
    User.findOne({user: message.user}, function(err, userData) {
        if(!userData) {
            //first get all users so reference numbers can be changed
            User.find({}, function(findAllErr, allUsers){
                if(!findAllErr){
                    //update each user's reference number
                    //shift all reference numbers over by one starting from whatever is referencing the 0 index currently
                    var limit = allUsers[0].refNum - 1;
                    for(var x = 0; x < allUsers.length; x++){
                        if(allUsers[x].refNum <= limit){
                            var newNum = (allUsers[0].refNum - 1) % (allUsers.length + 1);
                            User.update({user: allUsers[x].user}, {refNum: newNum}, function(singleUpdateErr){
                                if(singleUpdateErr) {
                                    console.log("Failed to update " + allUsers[x].user);
                                    console.log(singleUpdateErr);
                                    return; //break registration function if error
                                }
                            });
                        }
                    }
                    //create and save new user now
                    var user = new User({user: message.user, github: newGithub, refNum: limit});
                    user.save(function(err) {
                        if(err) {
                            console.log("User could not be saved!");
                            bot.reply(message, 'An error occured...Please try again later');
                        } else {
                            console.log("New user added~");
                            bot.reply(message,'@' + usernick + ': Your GitHub account of ' + newGithub + ' has been saved.');
                        }
                    })
                }
            });
        } else {
            User.update({user:message.user}, {github: newGithub}, function(err){
                // This code will run when the DB has attempted to update the matching record.
                if(err){
                    bot.reply(message, 'An error occured...Please try again later');
                } else {
                    bot.reply(message,'@' + usernick + ': Your GitHub account of ' + newGithub + ' has been updated.');
                }
            });
        }
    });
});

controller.hears(['!gen', '.gen', '!generate', '.generate'], 'direct_message', function(bot, message) {
    //Get usernick
    var usernick = "";
    for (i in bot.users) {
        if (bot.users[i].id == message.user){
            usernick = bot.users[i].name;
        }
    }

    var User = mongoose.model('User');
    //first get all users so reference numbers can be changed

    User.find({}, function(findAllErr, allUsers){
        User.findOne({user: message.user}, function(err, userData) {
            if(userData && userData.github){
                bot.reply(message, '@' + usernick + ': Please use https://github.com/' + allUsers[userData.refNum].github + " for today~");
            } else {
                bot.reply(message, '@' + usernick + ': You currently do not have a Github account attached. Use the !reg feature to register');
            }
        });
    });
});

controller.hears(['.shuffle'], 'direct_message', function(bot, message){
    var User = mongoose.model('User');
    User.find({}, function(findAllErr, allUsers){
        if(findAllErr){
            console.log(findAllErr);
        } else {
            shift = 1;
            //check to see if you are about to move into your own index position, if so shift 2
            if(((allUsers[0].refNum + 1) % allUsers.length) == 0){
                shift = 2;
            }
            for (i in allUsers){
                var newNum = (allUsers[i].refNum + shift) % allUsers.length;
                User.update({user: allUsers[i].user}, {refNum: newNum}, function(updateErr){
                    if(updateErr) {
                        console.log("Failed to update " + allUsers[i].user);
                    }
                });
            }
            bot.reply(message, 'Shift attempted');
        }
    })
})

/*====================================================================================================
======================================================================================================
======================================================================================================
======================================================================================================*/

controller.hears(['hello', 'hi'], 'direct_message,direct_mention,mention', function(bot, message) {

    bot.api.reactions.add({
        timestamp: message.ts,
        channel: message.channel,
        name: 'robot_face',
    }, function(err, res) {
        if (err) {
            bot.botkit.log('Failed to add emoji reaction :(', err);
        }
    });

    controller.storage.users.get(message.user, function(err, user) {
        if (user && user.name) {
            bot.reply(message, 'Hello ' + user.name + '!!');
        } else {
            bot.reply(message, 'Hello.');
        }
    });
});

controller.hears(['call me (.*)', 'my name is (.*)'], 'direct_message,direct_mention,mention', function(bot, message) {
    var name = message.match[1];
    controller.storage.users.get(message.user, function(err, user) {
        if (!user) {
            user = {
                id: message.user,
            };
        }
        user.name = name;
        controller.storage.users.save(user, function(err, id) {
            bot.reply(message, 'Got it. I will call you ' + user.name + ' from now on.');
        });
    });
});

controller.hears(['what is my name', 'who am i'], 'direct_message,direct_mention,mention', function(bot, message) {
    controller.storage.users.get(message.user, function(err, user) {
        if (user && user.name) {
            bot.reply(message, 'Your name is ' + user.name);
        } else {
            bot.startConversation(message, function(err, convo) {
                if (!err) {
                    convo.say('I do not know your name yet!');
                    convo.ask('What should I call you?', function(response, convo) {
                        convo.ask('You want me to call you `' + response.text + '`?', [
                            {
                                pattern: 'yes',
                                callback: function(response, convo) {
                                    // since no further messages are queued after this,
                                    // the conversation will end naturally with status == 'completed'
                                    convo.next();
                                }
                            },
                            {
                                pattern: 'no',
                                callback: function(response, convo) {
                                    // stop the conversation. this will cause it to end with status == 'stopped'
                                    convo.stop();
                                }
                            },
                            {
                                default: true,
                                callback: function(response, convo) {
                                    convo.repeat();
                                    convo.next();
                                }
                            }
                        ]);

                        convo.next();

                    }, {'key': 'nickname'}); // store the results in a field called nickname

                    convo.on('end', function(convo) {
                        if (convo.status == 'completed') {
                            bot.reply(message, 'OK! I will update my dossier...');

                            controller.storage.users.get(message.user, function(err, user) {
                                if (!user) {
                                    user = {
                                        id: message.user,
                                    };
                                }
                                user.name = convo.extractResponse('nickname');
                                controller.storage.users.save(user, function(err, id) {
                                    bot.reply(message, 'Got it. I will call you ' + user.name + ' from now on.');
                                });
                            });

                        } else {
                            // this happens if the conversation ended prematurely for some reason
                            bot.reply(message, 'OK, nevermind!');
                        }
                    });
                }
            });
        }
    });
});

controller.hears(['shutdown'], 'direct_message', function(bot, message) {

    bot.startConversation(message, function(err, convo) {

        convo.ask('Are you sure you want me to shutdown?', [
            {
                pattern: bot.utterances.yes,
                callback: function(response, convo) {
                    convo.say('Bye!');
                    convo.next();
                    setTimeout(function() {
                        process.exit();
                    }, 3000);
                }
            },
        {
            pattern: bot.utterances.no,
            default: true,
            callback: function(response, convo) {
                convo.say('*Phew!*');
                convo.next();
            }
        }
        ]);
    });
});

controller.hears(['uptime', 'identify yourself', 'who are you', 'what is your name'],
    'direct_message,direct_mention,mention', function(bot, message) {

        var hostname = os.hostname();
        var uptime = formatUptime(process.uptime());

        bot.reply(message,
            ':robot_face: I am a bot named <@' + bot.identity.name +
             '>. I have been running for ' + uptime + ' on ' + hostname + '.');

    });

function formatUptime(uptime) {
    var unit = 'second';
    if (uptime > 60) {
        uptime = uptime / 60;
        unit = 'minute';
    }
    if (uptime > 60) {
        uptime = uptime / 60;
        unit = 'hour';
    }
    if (uptime != 1) {
        unit = unit + 's';
    }

    uptime = uptime + ' ' + unit;
    return uptime;
}
<commit_msg>Added DB info to Bot info function<commit_after>/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           ______     ______     ______   __  __     __     ______
          /\  == \   /\  __ \   /\__  _\ /\ \/ /    /\ \   /\__  _\
          \ \  __<   \ \ \/\ \  \/_/\ \/ \ \  _"-.  \ \ \  \/_/\ \/
           \ \_____\  \ \_____\    \ \_\  \ \_\ \_\  \ \_\    \ \_\
            \/_____/   \/_____/     \/_/   \/_/\/_/   \/_/     \/_/
*/

if (!process.env.token) {
    console.log('Error: Specify token in environment');
    process.exit(1);
}

var Botkit = require('./lib/Botkit.js');
var mongoose = require('mongoose');
var os = require('os');

var controller = Botkit.slackbot({
    debug: false,
});

mongoose.connect('mongodb://localhost/slackbot');
var UserSchema = new mongoose.Schema({
    user: String,
    github: String,
    refNum: Number,
    updated_at: {type: Date, default: Date.now}
});
mongoose.model('User', UserSchema);

//Build mongo objects

var bot = controller.spawn({
    token: process.env.token
}).startRTM();

controller.hears(['!reg (.*)', '.reg (.*)', '!register (.*)', '.register (.*)'], 'direct_message', function(bot, message) {
    //Get usernick
    var usernick = "";
    for (i in bot.users) {
        if (i['id'] == message.user){
            usernick = i['name'];
        }
    }

    //******************************************************
    //Need to add webcrawl checks to make sure this is valid
    //******************************************************
    var newGithub = message.match[1];

    var User = mongoose.model("User");
    User.findOne({user: message.user}, function(err, userData) {
        if(!userData) {
            //first get all users so reference numbers can be changed
            User.find({}, function(findAllErr, allUsers){
                if(!findAllErr){
                    //update each user's reference number
                    //shift all reference numbers over by one starting from whatever is referencing the 0 index currently
                    var limit = allUsers[0].refNum - 1;
                    for(var x = 0; x < allUsers.length; x++){
                        if(allUsers[x].refNum <= limit){
                            var newNum = (allUsers[0].refNum - 1) % (allUsers.length + 1);
                            User.update({user: allUsers[x].user}, {refNum: newNum}, function(singleUpdateErr){
                                if(singleUpdateErr) {
                                    console.log("Failed to update " + allUsers[x].user);
                                    console.log(singleUpdateErr);
                                    return; //break registration function if error
                                }
                            });
                        }
                    }
                    //create and save new user now
                    var user = new User({user: message.user, github: newGithub, refNum: limit});
                    user.save(function(err) {
                        if(err) {
                            console.log("User could not be saved!");
                            bot.reply(message, 'An error occured...Please try again later');
                        } else {
                            console.log("New user added~");
                            bot.reply(message,'@' + usernick + ': Your GitHub account of ' + newGithub + ' has been saved.');
                        }
                    })
                }
            });
        } else {
            User.update({user:message.user}, {github: newGithub}, function(err){
                // This code will run when the DB has attempted to update the matching record.
                if(err){
                    bot.reply(message, 'An error occured...Please try again later');
                } else {
                    bot.reply(message,'@' + usernick + ': Your GitHub account of ' + newGithub + ' has been updated.');
                }
            });
        }
    });
});

controller.hears(['!gen', '.gen', '!generate', '.generate'], 'direct_message', function(bot, message) {
    //Get usernick
    var usernick = "";
    for (i in bot.users) {
        if (bot.users[i].id == message.user){
            usernick = bot.users[i].name;
        }
    }

    var User = mongoose.model('User');
    //first get all users so reference numbers can be changed

    User.find({}, function(findAllErr, allUsers){
        User.findOne({user: message.user}, function(err, userData) {
            if(userData && userData.github){
                bot.reply(message, '@' + usernick + ': Please use https://github.com/' + allUsers[userData.refNum].github + " for today~");
            } else {
                bot.reply(message, '@' + usernick + ': You currently do not have a Github account attached. Use the !reg feature to register');
            }
        });
    });
});

controller.hears(['.shuffle'], 'direct_message', function(bot, message){
    var User = mongoose.model('User');
    User.find({}, function(findAllErr, allUsers){
        if(findAllErr){
            console.log(findAllErr);
        } else {
            shift = 1;
            //check to see if you are about to move into your own index position, if so shift 2
            if(((allUsers[0].refNum + 1) % allUsers.length) == 0){
                shift = 2;
            }
            for (i in allUsers){
                var newNum = (allUsers[i].refNum + shift) % allUsers.length;
                User.update({user: allUsers[i].user}, {refNum: newNum}, function(updateErr){
                    if(updateErr) {
                        console.log("Failed to update " + allUsers[i].user);
                    }
                });
            }
            bot.reply(message, 'Shift attempted');
        }
    })
})

/*====================================================================================================
======================================================================================================
======================================================================================================
======================================================================================================*/

controller.hears(['hello', 'hi'], 'direct_message,direct_mention,mention', function(bot, message) {

    bot.api.reactions.add({
        timestamp: message.ts,
        channel: message.channel,
        name: 'robot_face',
    }, function(err, res) {
        if (err) {
            bot.botkit.log('Failed to add emoji reaction :(', err);
        }
    });

    controller.storage.users.get(message.user, function(err, user) {
        if (user && user.name) {
            bot.reply(message, 'Hello ' + user.name + '!!');
        } else {
            bot.reply(message, 'Hello.');
        }
    });
});

controller.hears(['call me (.*)', 'my name is (.*)'], 'direct_message,direct_mention,mention', function(bot, message) {
    var name = message.match[1];
    controller.storage.users.get(message.user, function(err, user) {
        if (!user) {
            user = {
                id: message.user,
            };
        }
        user.name = name;
        controller.storage.users.save(user, function(err, id) {
            bot.reply(message, 'Got it. I will call you ' + user.name + ' from now on.');
        });
    });
});

controller.hears(['what is my name', 'who am i'], 'direct_message,direct_mention,mention', function(bot, message) {
    controller.storage.users.get(message.user, function(err, user) {
        if (user && user.name) {
            bot.reply(message, 'Your name is ' + user.name);
        } else {
            bot.startConversation(message, function(err, convo) {
                if (!err) {
                    convo.say('I do not know your name yet!');
                    convo.ask('What should I call you?', function(response, convo) {
                        convo.ask('You want me to call you `' + response.text + '`?', [
                            {
                                pattern: 'yes',
                                callback: function(response, convo) {
                                    // since no further messages are queued after this,
                                    // the conversation will end naturally with status == 'completed'
                                    convo.next();
                                }
                            },
                            {
                                pattern: 'no',
                                callback: function(response, convo) {
                                    // stop the conversation. this will cause it to end with status == 'stopped'
                                    convo.stop();
                                }
                            },
                            {
                                default: true,
                                callback: function(response, convo) {
                                    convo.repeat();
                                    convo.next();
                                }
                            }
                        ]);

                        convo.next();

                    }, {'key': 'nickname'}); // store the results in a field called nickname

                    convo.on('end', function(convo) {
                        if (convo.status == 'completed') {
                            bot.reply(message, 'OK! I will update my dossier...');

                            controller.storage.users.get(message.user, function(err, user) {
                                if (!user) {
                                    user = {
                                        id: message.user,
                                    };
                                }
                                user.name = convo.extractResponse('nickname');
                                controller.storage.users.save(user, function(err, id) {
                                    bot.reply(message, 'Got it. I will call you ' + user.name + ' from now on.');
                                });
                            });

                        } else {
                            // this happens if the conversation ended prematurely for some reason
                            bot.reply(message, 'OK, nevermind!');
                        }
                    });
                }
            });
        }
    });
});

controller.hears(['shutdown'], 'direct_message', function(bot, message) {

    bot.startConversation(message, function(err, convo) {

        convo.ask('Are you sure you want me to shutdown?', [
            {
                pattern: bot.utterances.yes,
                callback: function(response, convo) {
                    convo.say('Bye!');
                    convo.next();
                    setTimeout(function() {
                        process.exit();
                    }, 3000);
                }
            },
        {
            pattern: bot.utterances.no,
            default: true,
            callback: function(response, convo) {
                convo.say('*Phew!*');
                convo.next();
            }
        }
        ]);
    });
});

//Gets some basic bot info
controller.hears(['~info'],
    'direct_message,direct_mention', function(bot, message) {
        var User = mongoose.model('User');
        var hostname = os.hostname();
        var uptime = formatUptime(process.uptime());
        var messageStr = ':robot_face: I am a bot named <@' + bot.identity.name +
             '>. I have been running for ' + uptime + ' on ' + hostname + '.\n';

        User.find({}, function(err, allUsers){
                if(!err){
                    messageStr += "\n=====Current DB Info=====\n";
                    for (i in allUsers){
                        messageStr += "User Index: " + i + ", GitHub: " + allUsers[i].github + ", Current Ref Num: " + allUsers[i].refNum + "\n";
                    }
                    bot.reply(message, str);
                }
        });
    });

function formatUptime(uptime) {
    var unit = 'second';
    if (uptime > 60) {
        uptime = uptime / 60;
        unit = 'minute';
    }
    if (uptime > 60) {
        uptime = uptime / 60;
        unit = 'hour';
    }
    if (uptime != 1) {
        unit = unit + 's';
    }

    uptime = uptime + ' ' + unit;
    return uptime;
}
<|endoftext|>