<commit_before>'use strict';

var _ = require('lodash'),
  platform = require('os').platform(),
  raw_config = require('../../config/platform.json');

// reduce callback to get platform index
var getIndex = function(result, val, key) {
  if (result !== false) {
    return result;
  }
  return val == platform ? key : false;
};

// map callback to get a specific platform config.
var getConfig = function(options, key, config) {
  return [key, key == 'index' ? config.index : options[config.index]];
};

// set index
raw_config.index = _.reduce(raw_config.platform, getIndex, false);

// export a processed config
module.exports = _.object(_.map(raw_config, getConfig));
<commit_msg>replaced reduce with getIndex to simplify things<commit_after>'use strict';

var _ = require('lodash'),
  platform = require('os').platform(),
  raw_config = require('../../config/platform.json');

// findIndex callback to get platform
var getIndex = function(val) {
  return val === platform;
};

// map callback to set a specific platform config.
var getConfig = function(options, key, config) {
  return [key, key == 'index' ? config.index : options[config.index]];
};

// set index
raw_config.index = _.findIndex(raw_config.platform, getIndex);

// export a processed config
module.exports = _.object(_.map(raw_config, getConfig));
<|endoftext|>


<commit_before>import Promise from 'bluebird'
import fetch from 'node-fetch'
import {
  merge,
  length,
  keys,
} from 'ramda'
import qs from 'qs'
import routes from './routes'

const defaultHeaders = {
  'Content-Type': 'application/json',
}

function ApiError (response) {
  this.response = response
  this.name = 'ApiError'
  if (Error.captureStackTrace) {
    Error.captureStackTrace(this, ApiError)
  }
}

ApiError.prototype = Object.create(Error.prototype)
ApiError.prototype.constructor = ApiError

function buildRequestParams (method, endpoint, options, data) {
  let query = ''
  let body = ''
  let headers = options.headers || {}

  const payload = merge(
    options.body || {},
    data || {},
  )

  const queries = options.qs || {}

  if (length(keys(queries))) {
    query = `${qs.stringify(queries)}`
  }

  if (['GET', 'HEAD'].includes(method)) {
    if (length(keys(payload)) > 0) {
      query += `${query ? '&' : ''}${qs.stringify(payload, { encode: false })}`
    }
  } else if (length(keys(payload)) > 0) {
    body = JSON.stringify(payload)
    headers = merge(headers, defaultHeaders)
  }

  const url = `${endpoint}${query ? `?${query}` : ''}`

  /* eslint-disable */
  // console.log(
  //   'url:', url,
  //   '\nheaders:', headers,
  //   '\payload:', payload,
  //   '\nbody:', body,
  // )
  /* eslint-enable */

  return { url, params: { method, body, headers } }
}

function handleError (response) {
  if (response.status === 500) {
    return Promise.reject(
      new ApiError({
        errors: [{ message: 'Pagar.me server error' }],
      })
    )
  }

  return response.json()
    .then(body => Promise.reject(new ApiError(body)))
}

function handleResult (response) {
  if (response.ok) {
    return response.json()
  }

  return handleError(response)
}

function buildRequest (method) {
  return function request (options, path, body) {
    const endpoint = (options.baseURL || routes.base) + path
    const { url, params } = buildRequestParams(method, endpoint, options, body)

    return fetch(url, params).then(handleResult)
  }
}

export default {
  get: buildRequest('GET'),
  put: buildRequest('PUT'),
  post: buildRequest('POST'),
  delete: buildRequest('DELETE'),
}
<commit_msg>Removed unnecessary console.log in request.js<commit_after>import Promise from 'bluebird'
import fetch from 'node-fetch'
import {
  merge,
  length,
  keys,
} from 'ramda'
import qs from 'qs'
import routes from './routes'

const defaultHeaders = {
  'Content-Type': 'application/json',
}

function ApiError (response) {
  this.response = response
  this.name = 'ApiError'
  if (Error.captureStackTrace) {
    Error.captureStackTrace(this, ApiError)
  }
}

ApiError.prototype = Object.create(Error.prototype)
ApiError.prototype.constructor = ApiError

function buildRequestParams (method, endpoint, options, data) {
  let query = ''
  let body = ''
  let headers = options.headers || {}

  const payload = merge(
    options.body || {},
    data || {},
  )

  const queries = options.qs || {}

  if (length(keys(queries))) {
    query = `${qs.stringify(queries)}`
  }

  if (['GET', 'HEAD'].includes(method)) {
    if (length(keys(payload)) > 0) {
      query += `${query ? '&' : ''}${qs.stringify(payload, { encode: false })}`
    }
  } else if (length(keys(payload)) > 0) {
    body = JSON.stringify(payload)
    headers = merge(headers, defaultHeaders)
  }

  const url = `${endpoint}${query ? `?${query}` : ''}`

  return { url, params: { method, body, headers } }
}

function handleError (response) {
  if (response.status === 500) {
    return Promise.reject(
      new ApiError({
        errors: [{ message: 'Pagar.me server error' }],
      })
    )
  }

  return response.json()
    .then(body => Promise.reject(new ApiError(body)))
}

function handleResult (response) {
  if (response.ok) {
    return response.json()
  }

  return handleError(response)
}

function buildRequest (method) {
  return function request (options, path, body) {
    const endpoint = (options.baseURL || routes.base) + path
    const { url, params } = buildRequestParams(method, endpoint, options, body)

    return fetch(url, params).then(handleResult)
  }
}

export default {
  get: buildRequest('GET'),
  put: buildRequest('PUT'),
  post: buildRequest('POST'),
  delete: buildRequest('DELETE'),
}
<|endoftext|>


<commit_before>self.addEventListener('install', event => {
	console.log('Worker installed');

	event.waitUntil(
		caches.open('hummingbird-anime-client')
			.then(cache => cache.addAll([
				'public/images/icons/favicon.ico',
				'public/css/app.min.css',
				'public/js/index.min.js',
				'public/js/index-authed.min.js',
				'public/js/tables.min.js',
			]))
	);
});

self.addEventListener('fetch', event => {

	event.respondWith(
		caches.match(event.request).then(response => {
			if (response !== undefined) {
				// Return cached version
				return response;
			}

			return fetch(event.request).then(response => {
				const clone = response.clone();

				caches.open('hummingbird-anime-client').then(cache => {
					cache.put(event.request, clone);
				});

				return response;
			});
		})
	);
});<commit_msg>Update service worker so it only caches images<commit_after>const CACHE_NAME = 'hummingbird-anime-client';

async function fromCache (request) {
	const cache = await caches.open(CACHE_NAME);
	return await cache.match(request);
}

async function fromNetwork (request) {
	return await fetch(request);
}

async function update (request) {
	const cache = await caches.open(CACHE_NAME);
	const response = await fetch(request);

	if (request.url.includes('/public/images/')) {
		console.log('Saving to cache: ', request.url);
		await cache.put(request, response.clone());
	}

	return response;
}

function refresh (response) {
	return self.clients.matchAll().then(clients => {
		clients.forEach(client => {
			const message = {
				type: 'refresh',
				url: response.url,
				eTag: response.headers.get('ETag')
			};

			client.postMessage(JSON.stringify(message));
		})
	});
}

self.addEventListener('install', event => {
	console.log('Public Folder Worker installed');

	event.waitUntil(
		caches.open(CACHE_NAME)
			.then(cache => cache.addAll([
				'public/images/icons/favicon.ico',
				'public/images/streaming-logos/amazon.svg',
				'public/images/streaming-logos/crunchyroll.svg',
				'public/images/streaming-logos/daisuki.svg',
				'public/images/streaming-logos/funimation.svg',
				'public/images/streaming-logos/hidive.svg',
				'public/images/streaming-logos/hulu.svg',
				'public/images/streaming-logos/netflix.svg',
				'public/images/streaming-logos/tubitv.svg',
				'public/images/streaming-logos/viewster.svg',
			]))
	)
});

self.addEventListener('activate', event => {
	console.log('Public Folder Worker activated');
});

// Pull css, images, and javascript from cache
self.addEventListener('fetch', event => {
	fromCache(event.request).then(cached => {
		if (cached !== undefined) {
			event.respondWith(cached);
		} else {
			event.respondWith(fromNetwork(event.request));
		}
	});

	event.waitUntil(
		update(event.request).then(refresh)
	);
});<|endoftext|>


<commit_before>/****************************************************************************
 * ui.js
 * openacousticdevices.info
 * July 2017
 *****************************************************************************/

'use strict';

/*global window, document*/

var timeHandler = require('./timePeriods.js');
var lifeDisplay = require('./lifeDisplay.js');

var strftime = require('strftime').utc();

/* UI components */

var idDisplay = document.getElementById('id-display');
var idLabel = document.getElementById('id-label');

var timeDisplay = document.getElementById('time-display');

var batteryDisplay = document.getElementById('battery-display');
var batteryLabel = document.getElementById('battery-label');

var startTimeInput = document.getElementById('start-time-input');
var endTimeInput = document.getElementById('end-time-input');

var recordingDurationInput = document.getElementById('recording-duration-input');
var sleepDurationInput = document.getElementById('sleep-duration-input');

var configureButton = document.getElementById('configure-button');

/* Function to rescale */

function rescale(canvas) {

    var scaleFactor = 1;

    if (window.hasOwnProperty('devicePixelRatio')) {
        if (window.devicePixelRatio > 1) {
            scaleFactor = window.devicePixelRatio;
        }
    }

    if (scaleFactor > 1) {

        canvas.width = canvas.width * scaleFactor;
        canvas.height = canvas.height * scaleFactor;

        canvas.style.width = canvas.width / scaleFactor + 'px';
        canvas.style.height = canvas.height / scaleFactor + 'px';

    }

}

/* Rescale for resolution of screen */

var timeCanvas = document.getElementById("time-canvas");
var timeContext = timeCanvas.getContext("2d");

rescale(timeCanvas);

var labelCanvas = document.getElementById("label-canvas");
var labelContext = labelCanvas.getContext("2d");

rescale(labelCanvas);

/* Update time period canvas */

function updateCanvas(timePeriods) {

    var i, recX, recLen, currentDate, currentMins, currentX;

    timeContext.clearRect(0, 0, timeCanvas.width, timeCanvas.height);

    for (i = 0; i < timePeriods.length; i += 1) {

        recX = timePeriods[i].startMins * timeCanvas.width / 1440; // width / 1440 minutes
        recLen = (timePeriods[i].endMins - timePeriods[i].startMins) * timeCanvas.width / 1440;

        timeContext.fillStyle = "#FF0000";
        timeContext.fillRect(recX, 0, recLen, timeCanvas.height);

    }

    // 6am, midday and 6pm markers.
    timeContext.fillStyle = "#000000";
    timeContext.fillRect(0.25 * timeCanvas.width, 0, 0.002 * timeCanvas.width, timeCanvas.height);
    timeContext.fillRect(0.5 * timeCanvas.width, 0, 0.002 * timeCanvas.width, timeCanvas.height);
    timeContext.fillRect(0.75 * timeCanvas.width, 0, 0.002 * timeCanvas.width, timeCanvas.height);

    currentDate = new Date();
    currentMins = (currentDate.getUTCHours() * 60) + currentDate.getUTCMinutes();
    currentX = currentMins * timeCanvas.width / 1440;

    timeContext.fillStyle = "#00AF00";
    timeContext.fillRect((currentX - 1), 0, 0.004 * timeCanvas.width, timeCanvas.height);

}

exports.updateCanvas = updateCanvas;

/* Regularly update time period canvas so green line reflects current time */

function updateCanvasTimer() {

    updateCanvas(timeHandler.getTimePeriods());
    setTimeout(updateCanvasTimer, 60000);

}

exports.updateCanvasTimer = updateCanvasTimer;

/* Draw labels below time period canvas */

exports.drawTimeLabels = function () {

    labelContext.font = Math.floor(0.25 * timeCanvas.height) + "pt Helvetica";

    labelContext.fillText("00:00", 0, 0.3 * timeCanvas.height);
    labelContext.fillText("06:00", 0.225 * timeCanvas.width, 0.3 * timeCanvas.height);
    labelContext.fillText("12:00", 0.475 * timeCanvas.width, 0.3 * timeCanvas.height);
    labelContext.fillText("18:00", 0.725 * timeCanvas.width, 0.3 * timeCanvas.height);
    labelContext.fillText("24:00", 0.945 * timeCanvas.width, 0.3 * timeCanvas.height);

};

/* Retrieve the radio button selected from a group of named buttons */

function getSelectedRadioValue(radioName) {
    return document.querySelector('input[name="' + radioName + '"]:checked').value;
}

exports.getSelectedRadioValue = getSelectedRadioValue;

/* Initialise device information displays */

exports.initialiseDisplay = function () {

    idDisplay.value = "0000000000000000";

    timeDisplay.textContent = "00:00:00 01/01/1970";

    batteryDisplay.textContent = "0.0V";

};

/* Disable/enable device information display */

exports.disableDisplay = function () {

    timeDisplay.style.color = "lightgrey";

    idLabel.style.color = "lightgrey";

    idDisplay.style.color = "lightgrey";

    batteryLabel.style.color = "lightgrey";

    batteryDisplay.style.color = "lightgrey";

    configureButton.disabled = true;

};

exports.enableDisplayAndShowTime = function (date) {

    var strftimeUTC = strftime.timezone(0);

    timeDisplay.textContent = strftimeUTC("%H:%M:%S %d/%m/%Y", date);

    timeDisplay.style.color = "black";

    idLabel.style.color = "black";

    idDisplay.style.color = "black";

    batteryLabel.style.color = "black";

    batteryDisplay.style.color = "black";

    configureButton.disabled = false;

};

/* Insert retrieved values into device information display */

exports.updateIdDisplay = function (id) {

    if (id !== idDisplay.value) {

        idDisplay.value = id;

    }

};

exports.updateBatteryDisplay = function (batteryState) {

    batteryDisplay.textContent = batteryState;

};

/* Verify that an input value is between a max and min, notifying the user if this is not the case */

function inputIsCorrect(input, min, max) {

    var correct = true;

    if (input.value === "") {

        input.value = min;
        correct = false;

    } else if (input.value < min) {

        input.value = min;
        correct = false;

    } else if (input.value > max) {

        input.value = max;
        correct = false;

    }

    if (!correct) {

        input.style.border = "1px solid #ff0000";
        input.style.padding = "2px 1px";
        input.style.color = "red";

        setTimeout(function () {

            input.style.border = "";
            input.style.padding = "";
            input.style.color = "";

        }, 2500);

    }

    return correct;

}

/* Apply range checks to sleep and recording duration textboxes */

function checkInputs(callback) {

    var complete = true;

    complete = inputIsCorrect(sleepDurationInput, 0, 43200);
    complete = inputIsCorrect(recordingDurationInput, 1, 43200) && complete;

    if (complete) {
        callback();
    }

}

exports.checkInputs = checkInputs;

/* Verify that time inputs are in the correct format */

function timeInputIsCorrect(input) {

    var time, hours, mins, correct = true,
        patt = new RegExp("^[0-9]?[0-9]:[0-9]{2}$");

    /* Check input is in the format "00:00" */

    if (!patt.test(input.value)) {

        correct = false;

    } else {

        time = input.value.split(":");
        if (time.length !== 2) {

            correct = false;

        } else {

            hours = parseInt(time[0], 10);
            mins = parseInt(time[1], 10);

            if (hours < 0 || isNaN(hours)) {

                correct = false;

            } else if (mins > 59) {

                correct = false;

            } else if (mins < 0 || isNaN(mins)) {

                correct = false;

            }

        }

    }

    if (!correct) {

        input.style.border = "1px solid #ff0000";
        input.style.padding = "2px 1px";
        input.style.color = "red";

        setTimeout(function () {

            input.style.border = "";
            input.style.padding = "";
            input.style.color = "";

        }, 2500);

    }

    return correct;
}

/* Apply error/default styles to time textboxes */

function setTimeInputStyleError() {

    startTimeInput.value = "0:00";
    startTimeInput.style.border = "1px solid #ff0000";
    startTimeInput.style.padding = "2px 1px";
    startTimeInput.style.color = "red";

    endTimeInput.value = "24:00";
    endTimeInput.style.border = "1px solid #ff0000";
    endTimeInput.style.padding = "2px 1px";
    endTimeInput.style.color = "red";

}

function setTimeInputStyleDefault() {

    startTimeInput.style.border = "";
    startTimeInput.style.padding = "";
    startTimeInput.style.color = "";

    endTimeInput.style.border = "";
    endTimeInput.style.padding = "";
    endTimeInput.style.color = "";

}

exports.setTimeInputStyleError = setTimeInputStyleError;
exports.setTimeInputStyleDefault = setTimeInputStyleDefault;

/* Apply input validation on start and end recording time inputs */

exports.checkTimeInputs = function (callback) {

    var complete, startTimeSplit, endTimeSplit, startTimestamp, endTimestamp;

    complete = timeInputIsCorrect(startTimeInput);
    complete = timeInputIsCorrect(endTimeInput) && complete;

    startTimeSplit = startTimeInput.value.split(":");
    endTimeSplit = endTimeInput.value.split(":");
    startTimestamp = (parseInt(startTimeSplit[0], 10) * 60) + parseInt(startTimeSplit[1], 10);
    endTimestamp = (parseInt(endTimeSplit[0], 10) * 60) + parseInt(endTimeSplit[1], 10);

    if (endTimestamp === startTimestamp) {

        complete = false;
        setTimeInputStyleError();
        setTimeout(setTimeInputStyleDefault, 2500);

    }

    if (complete) {
        callback();
    }

};

/* Only allow the input of '0-9' and ':' in time textboxes */

function checkTimeKeypress(event) {
    var patt = new RegExp("^[0-9]|:$");
    if (!patt.test(event.key)) {
        event.preventDefault();
    }
}

/* Add listeners to all radio buttons which update the life display */

exports.addRadioButtonListeners = function () {

    var radioButtons, i;

    radioButtons = document.getElementsByName("sample-rate-radio");

    for (i = 0; i < radioButtons.length; i += 1) {

        radioButtons[i].addEventListener('change', lifeDisplay.updateLifeDisplay);

    }

};

/* Add event listeners to textboxes */

startTimeInput.addEventListener('keypress', checkTimeKeypress);
endTimeInput.addEventListener('keypress', checkTimeKeypress);

sleepDurationInput.addEventListener('change', function () {
    checkInputs(lifeDisplay.updateLifeDisplay);
});

recordingDurationInput.addEventListener('change', function () {
    checkInputs(lifeDisplay.updateLifeDisplay);
});<commit_msg>Reset time display when device is disconnected<commit_after>/****************************************************************************
 * ui.js
 * openacousticdevices.info
 * July 2017
 *****************************************************************************/

'use strict';

/*global window, document*/

var timeHandler = require('./timePeriods.js');
var lifeDisplay = require('./lifeDisplay.js');

var strftime = require('strftime').utc();

/* UI components */

var idDisplay = document.getElementById('id-display');
var idLabel = document.getElementById('id-label');

var timeDisplay = document.getElementById('time-display');

var batteryDisplay = document.getElementById('battery-display');
var batteryLabel = document.getElementById('battery-label');

var startTimeInput = document.getElementById('start-time-input');
var endTimeInput = document.getElementById('end-time-input');

var recordingDurationInput = document.getElementById('recording-duration-input');
var sleepDurationInput = document.getElementById('sleep-duration-input');

var configureButton = document.getElementById('configure-button');

/* Function to rescale */

function rescale(canvas) {

    var scaleFactor = 1;

    if (window.hasOwnProperty('devicePixelRatio')) {
        if (window.devicePixelRatio > 1) {
            scaleFactor = window.devicePixelRatio;
        }
    }

    if (scaleFactor > 1) {

        canvas.width = canvas.width * scaleFactor;
        canvas.height = canvas.height * scaleFactor;

        canvas.style.width = canvas.width / scaleFactor + 'px';
        canvas.style.height = canvas.height / scaleFactor + 'px';

    }

}

/* Rescale for resolution of screen */

var timeCanvas = document.getElementById("time-canvas");
var timeContext = timeCanvas.getContext("2d");

rescale(timeCanvas);

var labelCanvas = document.getElementById("label-canvas");
var labelContext = labelCanvas.getContext("2d");

rescale(labelCanvas);

/* Update time period canvas */

function updateCanvas(timePeriods) {

    var i, recX, recLen, currentDate, currentMins, currentX;

    timeContext.clearRect(0, 0, timeCanvas.width, timeCanvas.height);

    for (i = 0; i < timePeriods.length; i += 1) {

        recX = timePeriods[i].startMins * timeCanvas.width / 1440; // width / 1440 minutes
        recLen = (timePeriods[i].endMins - timePeriods[i].startMins) * timeCanvas.width / 1440;

        timeContext.fillStyle = "#FF0000";
        timeContext.fillRect(recX, 0, recLen, timeCanvas.height);

    }

    // 6am, midday and 6pm markers.
    timeContext.fillStyle = "#000000";
    timeContext.fillRect(0.25 * timeCanvas.width, 0, 0.002 * timeCanvas.width, timeCanvas.height);
    timeContext.fillRect(0.5 * timeCanvas.width, 0, 0.002 * timeCanvas.width, timeCanvas.height);
    timeContext.fillRect(0.75 * timeCanvas.width, 0, 0.002 * timeCanvas.width, timeCanvas.height);

    currentDate = new Date();
    currentMins = (currentDate.getUTCHours() * 60) + currentDate.getUTCMinutes();
    currentX = currentMins * timeCanvas.width / 1440;

    timeContext.fillStyle = "#00AF00";
    timeContext.fillRect((currentX - 1), 0, 0.004 * timeCanvas.width, timeCanvas.height);

}

exports.updateCanvas = updateCanvas;

/* Regularly update time period canvas so green line reflects current time */

function updateCanvasTimer() {

    updateCanvas(timeHandler.getTimePeriods());
    setTimeout(updateCanvasTimer, 60000);

}

exports.updateCanvasTimer = updateCanvasTimer;

/* Draw labels below time period canvas */

exports.drawTimeLabels = function () {

    labelContext.font = Math.floor(0.25 * timeCanvas.height) + "pt Helvetica";

    labelContext.fillText("00:00", 0, 0.3 * timeCanvas.height);
    labelContext.fillText("06:00", 0.225 * timeCanvas.width, 0.3 * timeCanvas.height);
    labelContext.fillText("12:00", 0.475 * timeCanvas.width, 0.3 * timeCanvas.height);
    labelContext.fillText("18:00", 0.725 * timeCanvas.width, 0.3 * timeCanvas.height);
    labelContext.fillText("24:00", 0.945 * timeCanvas.width, 0.3 * timeCanvas.height);

};

/* Retrieve the radio button selected from a group of named buttons */

function getSelectedRadioValue(radioName) {
    return document.querySelector('input[name="' + radioName + '"]:checked').value;
}

exports.getSelectedRadioValue = getSelectedRadioValue;

/* Initialise device information displays */

function initialiseDisplay() {

    idDisplay.value = "0000000000000000";

    timeDisplay.textContent = "00:00:00 01/01/1970";

    batteryDisplay.textContent = "0.0V";

};

exports.initialiseDisplay = initialiseDisplay;

/* Disable/enable device information display */

exports.disableDisplay = function () {

    timeDisplay.style.color = "lightgrey";

    idLabel.style.color = "lightgrey";

    idDisplay.style.color = "lightgrey";

    batteryLabel.style.color = "lightgrey";

    batteryDisplay.style.color = "lightgrey";

    configureButton.disabled = true;

    initialiseDisplay();

};

exports.enableDisplayAndShowTime = function (date) {

    var strftimeUTC = strftime.timezone(0);

    timeDisplay.textContent = strftimeUTC("%H:%M:%S %d/%m/%Y", date);

    timeDisplay.style.color = "black";

    idLabel.style.color = "black";

    idDisplay.style.color = "black";

    batteryLabel.style.color = "black";

    batteryDisplay.style.color = "black";

    configureButton.disabled = false;

};

/* Insert retrieved values into device information display */

exports.updateIdDisplay = function (id) {

    if (id !== idDisplay.value) {

        idDisplay.value = id;

    }

};

exports.updateBatteryDisplay = function (batteryState) {

    batteryDisplay.textContent = batteryState;

};

/* Verify that an input value is between a max and min, notifying the user if this is not the case */

function inputIsCorrect(input, min, max) {

    var correct = true;

    if (input.value === "") {

        input.value = min;
        correct = false;

    } else if (input.value < min) {

        input.value = min;
        correct = false;

    } else if (input.value > max) {

        input.value = max;
        correct = false;

    }

    if (!correct) {

        input.style.border = "1px solid #ff0000";
        input.style.padding = "2px 1px";
        input.style.color = "red";

        setTimeout(function () {

            input.style.border = "";
            input.style.padding = "";
            input.style.color = "";

        }, 2500);

    }

    return correct;

}

/* Apply range checks to sleep and recording duration textboxes */

function checkInputs(callback) {

    var complete = true;

    complete = inputIsCorrect(sleepDurationInput, 0, 43200);
    complete = inputIsCorrect(recordingDurationInput, 1, 43200) && complete;

    if (complete) {
        callback();
    }

}

exports.checkInputs = checkInputs;

/* Verify that time inputs are in the correct format */

function timeInputIsCorrect(input) {

    var time, hours, mins, correct = true,
        patt = new RegExp("^[0-9]?[0-9]:[0-9]{2}$");

    /* Check input is in the format "00:00" */

    if (!patt.test(input.value)) {

        correct = false;

    } else {

        time = input.value.split(":");
        if (time.length !== 2) {

            correct = false;

        } else {

            hours = parseInt(time[0], 10);
            mins = parseInt(time[1], 10);

            if (hours < 0 || isNaN(hours)) {

                correct = false;

            } else if (mins > 59) {

                correct = false;

            } else if (mins < 0 || isNaN(mins)) {

                correct = false;

            }

        }

    }

    if (!correct) {

        input.style.border = "1px solid #ff0000";
        input.style.padding = "2px 1px";
        input.style.color = "red";

        setTimeout(function () {

            input.style.border = "";
            input.style.padding = "";
            input.style.color = "";

        }, 2500);

    }

    return correct;
}

/* Apply error/default styles to time textboxes */

function setTimeInputStyleError() {

    startTimeInput.value = "0:00";
    startTimeInput.style.border = "1px solid #ff0000";
    startTimeInput.style.padding = "2px 1px";
    startTimeInput.style.color = "red";

    endTimeInput.value = "24:00";
    endTimeInput.style.border = "1px solid #ff0000";
    endTimeInput.style.padding = "2px 1px";
    endTimeInput.style.color = "red";

}

function setTimeInputStyleDefault() {

    startTimeInput.style.border = "";
    startTimeInput.style.padding = "";
    startTimeInput.style.color = "";

    endTimeInput.style.border = "";
    endTimeInput.style.padding = "";
    endTimeInput.style.color = "";

}

exports.setTimeInputStyleError = setTimeInputStyleError;
exports.setTimeInputStyleDefault = setTimeInputStyleDefault;

/* Apply input validation on start and end recording time inputs */

exports.checkTimeInputs = function (callback) {

    var complete, startTimeSplit, endTimeSplit, startTimestamp, endTimestamp;

    complete = timeInputIsCorrect(startTimeInput);
    complete = timeInputIsCorrect(endTimeInput) && complete;

    startTimeSplit = startTimeInput.value.split(":");
    endTimeSplit = endTimeInput.value.split(":");
    startTimestamp = (parseInt(startTimeSplit[0], 10) * 60) + parseInt(startTimeSplit[1], 10);
    endTimestamp = (parseInt(endTimeSplit[0], 10) * 60) + parseInt(endTimeSplit[1], 10);

    if (endTimestamp === startTimestamp) {

        complete = false;
        setTimeInputStyleError();
        setTimeout(setTimeInputStyleDefault, 2500);

    }

    if (complete) {
        callback();
    }

};

/* Only allow the input of '0-9' and ':' in time textboxes */

function checkTimeKeypress(event) {
    var patt = new RegExp("^[0-9]|:$");
    if (!patt.test(event.key)) {
        event.preventDefault();
    }
}

/* Add listeners to all radio buttons which update the life display */

exports.addRadioButtonListeners = function () {

    var radioButtons, i;

    radioButtons = document.getElementsByName("sample-rate-radio");

    for (i = 0; i < radioButtons.length; i += 1) {

        radioButtons[i].addEventListener('change', lifeDisplay.updateLifeDisplay);

    }

};

/* Add event listeners to textboxes */

startTimeInput.addEventListener('keypress', checkTimeKeypress);
endTimeInput.addEventListener('keypress', checkTimeKeypress);

sleepDurationInput.addEventListener('change', function () {
    checkInputs(lifeDisplay.updateLifeDisplay);
});

recordingDurationInput.addEventListener('change', function () {
    checkInputs(lifeDisplay.updateLifeDisplay);
});<|endoftext|>


<commit_before>
// Show commands in textarea
function updateCommands() {
    var value = "";
    // Configure git
    if (user.name.changed() && user.name.isValid()) {
        value += "git config --global user.name \"" + user.get("name") + "\"\n";
    }
    if (user.email.changed() && user.email.isValid()) {
        value += "git config --global user.email " + user.get("email") + "\n";
    }
    // Create public/private SSH keypair
    if (!user.key.isValid()) {
        value += "printf \"\\n\" | ssh-keygen -t rsa -N ''\n"
    }
    // Enter home directory
    value += "cd ~";
    // Create repository
    if ($("#cloned").val() != "true") {
        value += "\ngit init " + model.repo();
    }
    // Enter repository
    value += "\ncd " + model.repo();
    // Configure upstream
    if (!model.hasRemote('upstream')) {
        value += "\ngit remote add upstream \\";
        value += "\n" + model.upstream() + ".git";
    }
    if (Bitbucket.existingUser() && !model.hasRemote('bitbucket')) {
        value += "\ngit remote add bitbucket \\";
        value += "\ngit@bitbucket.org:" + ((Bitbucket.getUsername() == null) ? user.get("login") : Bitbucket.getUsername()) + "/" + model.repo() + ".git";
    }
    // Add origin
    var origin = host.getOrigin();
    if (origin && !model.hasRemote('origin')) {
        value += "\ngit remote add origin \\";
        value += "\ngit@" + origin.getHostname() + ":" + ((origin.getUsername() == null) ? user.get("login") : origin.getUsername()) + "/" + model.repo() + ".git";
    }

    // Configure remotes
    for (var key in Gitlab.collaborators) {
        if (!model.hasRemote(key + "-gitlab")) {
            value += "\ngit remote add " + key + "-gitlab \\\ngit@gitlab.com:" + key + "/" + model.repo().toLowerCase() + ".git";
        }
    }
    for (var key in Github.collaborators) {
        if (!model.hasRemote(key + "-github")) {
            value += "\ngit remote add " + key + "-github \\\ngit@github.com:" + key + "/" + model.repo() + ".git";
        }
    }
    // Fetch everything
    value += "\ngit fetch --all";
    value += "\ngit merge upstream/master";
    value += "\ngit submodule update --init --recursive < /dev/null"
    // Push to origin
    if (origin) {
        value += "\ngit push -u origin master\n";
    }
    $("#command-line").val(value);
}

// Quick and dirty: get the platform (operating system)
// Courtesy: http://stackoverflow.com/questions/11219582/how-to-detect-my-browser-version-and-operating-system-using-javascript
function getPlatform() {
    var platform="unknown";
    if (navigator.appVersion.indexOf("Win")!=-1) platform="windows";
    if (navigator.appVersion.indexOf("Mac")!=-1) platform="mac";
    if (navigator.appVersion.indexOf("X11")!=-1) platform="linux";
    if (navigator.appVersion.indexOf("Linux")!=-1) platform="linux";
    return platform;
}

function showPlatform() {
    $(".unknown").hide();
    $(".windows").hide();
    $(".mac").hide();
    $(".linux").hide();
    $("." + getPlatform()).show();
}

// Validate profile, outlining broken fields in red
function validateUser() {
    var fields = [ user.name, user.email, user.key, user.gravatar ];
    var id = [ "#name", "#email", "#public-key", "#gravatar" ];
    var i;
    var allValid = true;
    for (i = 0; i < fields.length; i++) {
        if (fields[i].isValid()) {
            $(id[i]).removeAttr('style');
            allValid = false;
        }
        else {
            $(id[i]).css('border-color','red');
        }
    }
    return allValid;
}

// Setup all accounts
function setupAccounts() {
    var hosts = [ Github, Gitlab ];
    var settings = {
        title: user.get("login") + "@" + user.get("host"),
        key: user.get("key"),
        name: user.get("name"),
        email: user.get("email"),
        callback: controller.update,
    };
    for (var i = 0; i < hosts.length; i++) {
        hosts[i].setupAccount(settings);
    }
}

function updateView(event) {
    validateUser();
    setupAccounts();

    // Gravatar
    $("#gravatar").attr('src', 'http://www.gravatar.com/avatar/' + user.gravatar.value() + '?d=retro&s=140');
    user.gravatar.checkValid(function(status) {
        controller.update('gravatar-account',status);
    });

    // Don't allow sign-in unless their email is valid
    $("#github-signin").prop("disabled", !user.email.isValid());
    $("#gitlab-signin").prop("disabled", !user.email.isValid());
//    $("#bitbucket-signin").prop("disabled", !user.email.isValid());

    // Update repository URLs
    if (Github.existingUser()) {
        $('#github-login').text(Github.getUsername());
        $(".github-repo-href").attr("href", Github.repoURL());
        $("#github-collaborator-href").attr("href", Github.repoURL() + "/settings/collaboration");
        $("#github-private-href").attr("href", Github.repoURL() + "/settings");
    }
    if (Gitlab.existingUser()) {
        $('#gitlab-login').text(Gitlab.getUsername());
        $(".gitlab-repo-href").attr("href", Gitlab.repoURL());
        $("#gitlab-collaborator-href").attr("href", Gitlab.repoURL() + "/project_members");
        $("#gitlab-private-href").attr("href", Gitlab.repoURL() + "/edit");
    }
    if (Bitbucket.existingUser()) {
        controller.update('bitbucket-repository', true);
        $("#bitbucket-user").attr("href", "https://bitbucket.org/account/user/" + Bitbucket.getUsername() + "/");
        $("#bitbucket-email").attr("href", "https://bitbucket.org/account/user/" + Bitbucket.getUsername() + "/email/");
        $("#bitbucket-ssh").attr("href", "https://bitbucket.org/account/user/" + Bitbucket.getUsername() + "/ssh-keys/");
        $(".bitbucket-repo-href").attr("href", Bitbucket.repoURL());
        $("#bitbucket-collaborator-href").attr("href", Bitbucket.repoURL() + "/admin/access");
        $("#bitbucket-private-href").attr("href", Bitbucket.repoURL() + "/admin");
    }
    Github.getCollaborators({
        page: 1,
        success: function(collaborators) {
            for (var key in collaborators) {
                $("#repositories").append("
" + collaborators[key] + "'s repository
");
            }
            updateCommands();
        },
        callback: function(key, value) {
            $("#github-collaborator-" + key).text(value + "'s repository");
        },
        fail: function() {}
    });
    Gitlab.getCollaborators({
        success: function(collaborators) {
            for (var key in collaborators) {
                $("#repositories").append("
" + collaborators[key] + "'s repository
");
            }
            updateCommands();
        },
        fail: function() {}
    });

    updateCommands();
};

$( "#name" ).on( "change", updateView );
$( "#email" ).on( "change", updateView );
$( "#github-password" ).on( "change", updateView );
$( "#gitlab-password" ).on( "change", updateView );

$("#github-signout").on("click", function(event) {
    Github.logout();
    $("#github-signin").prop("disabled",false);
    $("#otp").val('');
    $("#github-password").val('');
    $("#github-password").removeAttr('style');
    $("#otp").hide();
    controller.update('github-authenticated', false);
});

function GithubSignin(event) {
    $("#github-signin").prop("disabled",true);
    Github.login({
        username: user.email.value(),
        password: $("#github-password").val(),
        otp: $("#otp").val(),
        authenticated: function(login) {
            updateView();
        },
        badCredential: function() {
            $("#github-signin").prop("disabled",false);
            $("#github-password").val('');
            $("#github-password").css('border-color','red');
            updateView();
        },
        twoFactor: function() {
            $("#github-signin").prop("disabled",false);
            $("#github-password").prop("disabled", false);
            $("#github-password").removeAttr('style');
            $("#github-forgot").hide();
            $('.github-two-factor').show();
            $('#otp').focus();
        }
    });
}

$("#github-signin").on("click", GithubSignin);

$('#github-password').keypress(function (e) {
  if (e.which == 13) {
    GithubSignin(e);
  }
});

$('#otp').keypress(function (e) {
  if (e.which == 13) {
    GithubSignin(e);
  }
});

function GitlabSignin(event) {
    $("#gitlab-signin").prop("disabled",true);
    Gitlab.login({
        email: user.email.value(),
        password: $("#gitlab-password").val(),
        authenticated: function(login) {
            updateView();
        },
        badCredential: function() {
            $("#gitlab-signin").prop("disabled",false);
            $("#gitlab-password").val('');
            $("#gitlab-password").css('border-color','red');
            updateView();
        },
    });
}

$("#gitlab-signin").on("click", GitlabSignin);

$('#gitlab-password').keypress(function (e) {
  if (e.which == 13) {
    GitlabSignin(e);
  }
});

$("#bitbucket-signin").on("click", function(event) {
    updateView();
});

$("#bitbucket-login").keypress(function (e) {
  if (e.which == 13) {
    updateView();
  }
});

$("#gitlab-signout").on("click", function(event) {
    Gitlab.logout();
    $("#gitlab-signin").prop("disabled",false);
    $("#gitlab-password").val('');
    $("#gitlab-password").removeAttr('style');
    controller.update('gitlab-authenticated', false);
});

$(function() {
    // Show values from local storage, if available
    $("#name").val(user.get("name"));
    $("#email").val(user.get("email"));
    showPlatform();
    updateView();
});

$("#local-setup-button").on("click", function(event) {
    $("#local-setup-button").prop("disabled",true);
    setupLocal();
});

function setupLocal() {
    // Information to pass to the server
    var data = {
        "github.login": Github.getUsername(),
        "gitlab.login": Gitlab.getUsername(),
        "bitbucket.login": Bitbucket.getUsername(),
        "user.name": user.get("name"),
        "user.email": user.get("email"),
    };
    $.extend(data, Github.collaborators);
    $.extend(data, Gitlab.collaborators);
    $.ajax({
        method: "POST",
        dataType: "json",
        crossDomain: true,
        url: 'http://localhost:8080/setup',
        data: data,
        success: function(response) {
            $("#stored-name").val(response.name);
            $("#stored-email").val(response.email);
            $("#cloned").val();
            updateView();
            controller.update('git-status',response.status);
        },
        error: function(response) {
            alert("Local server not responding.");
        }
    });
}
<commit_msg>Fixed another broken gitlab link.<commit_after>
// Show commands in textarea
function updateCommands() {
    var value = "";
    // Configure git
    if (user.name.changed() && user.name.isValid()) {
        value += "git config --global user.name \"" + user.get("name") + "\"\n";
    }
    if (user.email.changed() && user.email.isValid()) {
        value += "git config --global user.email " + user.get("email") + "\n";
    }
    // Create public/private SSH keypair
    if (!user.key.isValid()) {
        value += "printf \"\\n\" | ssh-keygen -t rsa -N ''\n"
    }
    // Enter home directory
    value += "cd ~";
    // Create repository
    if ($("#cloned").val() != "true") {
        value += "\ngit init " + model.repo();
    }
    // Enter repository
    value += "\ncd " + model.repo();
    // Configure upstream
    if (!model.hasRemote('upstream')) {
        value += "\ngit remote add upstream \\";
        value += "\n" + model.upstream() + ".git";
    }
    if (Bitbucket.existingUser() && !model.hasRemote('bitbucket')) {
        value += "\ngit remote add bitbucket \\";
        value += "\ngit@bitbucket.org:" + ((Bitbucket.getUsername() == null) ? user.get("login") : Bitbucket.getUsername()) + "/" + model.repo() + ".git";
    }
    // Add origin
    var origin = host.getOrigin();
    if (origin && !model.hasRemote('origin')) {
        value += "\ngit remote add origin \\";
        value += "\ngit@" + origin.getHostname() + ":" + ((origin.getUsername() == null) ? user.get("login") : origin.getUsername()) + "/" + model.repo() + ".git";
    }

    // Configure remotes
    for (var key in Gitlab.collaborators) {
        if (!model.hasRemote(key + "-gitlab")) {
            value += "\ngit remote add " + key + "-gitlab \\\ngit@gitlab.com:" + key + "/" + model.repo().toLowerCase() + ".git";
        }
    }
    for (var key in Github.collaborators) {
        if (!model.hasRemote(key + "-github")) {
            value += "\ngit remote add " + key + "-github \\\ngit@github.com:" + key + "/" + model.repo() + ".git";
        }
    }
    // Fetch everything
    value += "\ngit fetch --all";
    value += "\ngit merge upstream/master";
    value += "\ngit submodule update --init --recursive < /dev/null"
    // Push to origin
    if (origin) {
        value += "\ngit push -u origin master\n";
    }
    $("#command-line").val(value);
}

// Quick and dirty: get the platform (operating system)
// Courtesy: http://stackoverflow.com/questions/11219582/how-to-detect-my-browser-version-and-operating-system-using-javascript
function getPlatform() {
    var platform="unknown";
    if (navigator.appVersion.indexOf("Win")!=-1) platform="windows";
    if (navigator.appVersion.indexOf("Mac")!=-1) platform="mac";
    if (navigator.appVersion.indexOf("X11")!=-1) platform="linux";
    if (navigator.appVersion.indexOf("Linux")!=-1) platform="linux";
    return platform;
}

function showPlatform() {
    $(".unknown").hide();
    $(".windows").hide();
    $(".mac").hide();
    $(".linux").hide();
    $("." + getPlatform()).show();
}

// Validate profile, outlining broken fields in red
function validateUser() {
    var fields = [ user.name, user.email, user.key, user.gravatar ];
    var id = [ "#name", "#email", "#public-key", "#gravatar" ];
    var i;
    var allValid = true;
    for (i = 0; i < fields.length; i++) {
        if (fields[i].isValid()) {
            $(id[i]).removeAttr('style');
            allValid = false;
        }
        else {
            $(id[i]).css('border-color','red');
        }
    }
    return allValid;
}

// Setup all accounts
function setupAccounts() {
    var hosts = [ Github, Gitlab ];
    var settings = {
        title: user.get("login") + "@" + user.get("host"),
        key: user.get("key"),
        name: user.get("name"),
        email: user.get("email"),
        callback: controller.update,
    };
    for (var i = 0; i < hosts.length; i++) {
        hosts[i].setupAccount(settings);
    }
}

function updateView(event) {
    validateUser();
    setupAccounts();

    // Gravatar
    $("#gravatar").attr('src', 'http://www.gravatar.com/avatar/' + user.gravatar.value() + '?d=retro&s=140');
    user.gravatar.checkValid(function(status) {
        controller.update('gravatar-account',status);
    });

    // Don't allow sign-in unless their email is valid
    $("#github-signin").prop("disabled", !user.email.isValid());
    $("#gitlab-signin").prop("disabled", !user.email.isValid());
//    $("#bitbucket-signin").prop("disabled", !user.email.isValid());

    // Update repository URLs
    if (Github.existingUser()) {
        $('#github-login').text(Github.getUsername());
        $(".github-repo-href").attr("href", Github.repoURL());
        $("#github-collaborator-href").attr("href", Github.repoURL() + "/settings/collaboration");
        $("#github-private-href").attr("href", Github.repoURL() + "/settings");
    }
    if (Gitlab.existingUser()) {
        $('#gitlab-login').text(Gitlab.getUsername());
        $(".gitlab-repo-href").attr("href", Gitlab.repoURL());
        $("#gitlab-collaborator-href").attr("href", Gitlab.repoURL() + "/project_members");
        $("#gitlab-private-href").attr("href", Gitlab.repoURL() + "/edit");
    }
    if (Bitbucket.existingUser()) {
        controller.update('bitbucket-repository', true);
        $("#bitbucket-user").attr("href", "https://bitbucket.org/account/user/" + Bitbucket.getUsername() + "/");
        $("#bitbucket-email").attr("href", "https://bitbucket.org/account/user/" + Bitbucket.getUsername() + "/email/");
        $("#bitbucket-ssh").attr("href", "https://bitbucket.org/account/user/" + Bitbucket.getUsername() + "/ssh-keys/");
        $(".bitbucket-repo-href").attr("href", Bitbucket.repoURL());
        $("#bitbucket-collaborator-href").attr("href", Bitbucket.repoURL() + "/admin/access");
        $("#bitbucket-private-href").attr("href", Bitbucket.repoURL() + "/admin");
    }
    Github.getCollaborators({
        page: 1,
        success: function(collaborators) {
            for (var key in collaborators) {
                $("#repositories").append("
" + collaborators[key] + "'s repository
");
            }
            updateCommands();
        },
        callback: function(key, value) {
            $("#github-collaborator-" + key).text(value + "'s repository");
        },
        fail: function() {}
    });
    Gitlab.getCollaborators({
        success: function(collaborators) {
            for (var key in collaborators) {
                $("#repositories").append("
" + collaborators[key] + "'s repository
");
            }
            updateCommands();
        },
        fail: function() {}
    });

    updateCommands();
};

$( "#name" ).on( "change", updateView );
$( "#email" ).on( "change", updateView );
$( "#github-password" ).on( "change", updateView );
$( "#gitlab-password" ).on( "change", updateView );

$("#github-signout").on("click", function(event) {
    Github.logout();
    $("#github-signin").prop("disabled",false);
    $("#otp").val('');
    $("#github-password").val('');
    $("#github-password").removeAttr('style');
    $("#otp").hide();
    controller.update('github-authenticated', false);
});

function GithubSignin(event) {
    $("#github-signin").prop("disabled",true);
    Github.login({
        username: user.email.value(),
        password: $("#github-password").val(),
        otp: $("#otp").val(),
        authenticated: function(login) {
            updateView();
        },
        badCredential: function() {
            $("#github-signin").prop("disabled",false);
            $("#github-password").val('');
            $("#github-password").css('border-color','red');
            updateView();
        },
        twoFactor: function() {
            $("#github-signin").prop("disabled",false);
            $("#github-password").prop("disabled", false);
            $("#github-password").removeAttr('style');
            $("#github-forgot").hide();
            $('.github-two-factor').show();
            $('#otp').focus();
        }
    });
}

$("#github-signin").on("click", GithubSignin);

$('#github-password').keypress(function (e) {
  if (e.which == 13) {
    GithubSignin(e);
  }
});

$('#otp').keypress(function (e) {
  if (e.which == 13) {
    GithubSignin(e);
  }
});

function GitlabSignin(event) {
    $("#gitlab-signin").prop("disabled",true);
    Gitlab.login({
        email: user.email.value(),
        password: $("#gitlab-password").val(),
        authenticated: function(login) {
            updateView();
        },
        badCredential: function() {
            $("#gitlab-signin").prop("disabled",false);
            $("#gitlab-password").val('');
            $("#gitlab-password").css('border-color','red');
            updateView();
        },
    });
}

$("#gitlab-signin").on("click", GitlabSignin);

$('#gitlab-password').keypress(function (e) {
  if (e.which == 13) {
    GitlabSignin(e);
  }
});

$("#bitbucket-signin").on("click", function(event) {
    updateView();
});

$("#bitbucket-login").keypress(function (e) {
  if (e.which == 13) {
    updateView();
  }
});

$("#gitlab-signout").on("click", function(event) {
    Gitlab.logout();
    $("#gitlab-signin").prop("disabled",false);
    $("#gitlab-password").val('');
    $("#gitlab-password").removeAttr('style');
    controller.update('gitlab-authenticated', false);
});

$(function() {
    // Show values from local storage, if available
    $("#name").val(user.get("name"));
    $("#email").val(user.get("email"));
    showPlatform();
    updateView();
});

$("#local-setup-button").on("click", function(event) {
    $("#local-setup-button").prop("disabled",true);
    setupLocal();
});

function setupLocal() {
    // Information to pass to the server
    var data = {
        "github.login": Github.getUsername(),
        "gitlab.login": Gitlab.getUsername(),
        "bitbucket.login": Bitbucket.getUsername(),
        "user.name": user.get("name"),
        "user.email": user.get("email"),
    };
    $.extend(data, Github.collaborators);
    $.extend(data, Gitlab.collaborators);
    $.ajax({
        method: "POST",
        dataType: "json",
        crossDomain: true,
        url: 'http://localhost:8080/setup',
        data: data,
        success: function(response) {
            $("#stored-name").val(response.name);
            $("#stored-email").val(response.email);
            $("#cloned").val();
            updateView();
            controller.update('git-status',response.status);
        },
        error: function(response) {
            alert("Local server not responding.");
        }
    });
}
<|endoftext|>


<commit_before>export const jsLibs = [
	{
		url: 'https://code.jquery.com/jquery-3.2.1.min.js',
		label: 'jQuery',
		type: 'js'
	},
	{
		url: 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js',
		label: 'Bootstrap 3',
		type: 'js'
	},
	{
		url:
			'https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js',
		label: 'Bootstrap 4',
		type: 'js'
	},
	{
		url:
			'https://cdn.jsdelivr.net/npm/foundation-sites@6.5.0-rc.3/dist/js/foundation.min.js',
		label: 'Foundation',
		type: 'js'
	},
	{
		url: 'https://semantic-ui.com/dist/semantic.min.js',
		label: 'Semantic UI',
		type: 'js'
	},
	{
		url: 'https://ajax.googleapis.com/ajax/libs/angularjs/1.6.5/angular.min.js',
		label: 'Angular',
		type: 'js'
	},
	{
		url:
			'https://cdnjs.cloudflare.com/ajax/libs/react/16.2.0/umd/react.production.min.js',
		label: 'React',
		type: 'js'
	},
	{
		url:
			'https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.2.0/umd/react-dom.production.min.js',
		label: 'React DOM',
		type: 'js'
	},
	{
		url: 'https://unpkg.com/vue/dist/vue.min.js',
		label: 'Vue.js',
		type: 'js'
	},
	{
		url: 'https://cdnjs.cloudflare.com/ajax/libs/three.js/89/three.min.js',
		label: 'Three.js',
		type: 'js'
	},
	{
		url: 'https://d3js.org/d3.v5.min.js',
		label: 'D3',
		type: 'js'
	},
	{
		url:
			'https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js',
		label: 'Underscore',
		type: 'js'
	},
	{
		url: 'https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.3/TweenMax.min.js',
		label: 'Greensock TweenMax',
		type: 'js'
	},
	{
		url: 'https://cdnjs.cloudflare.com/ajax/libs/uikit/2.27.5/js/uikit.min.js',
		label: 'UIkit 2',
		type: 'js'
	},
	{
		url:
			'https://getuikit.com/assets/uikit/dist/js/uikit.js',
		label: 'UIkit 3',
		type: 'js'
	},
	{
		url: 'https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.1/p5.min.js',
		label: 'p5.js',
		type: 'js'
	},
	{
		url: 'https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.1/addons/p5.dom.min.js',
		label: 'p5.js DOM',
		type: 'js'
	},
	{
		url: 'https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.1/addons/p5.sound.min.js',
		label: 'p5.js Sound',
		type: 'js'
	}
];
export const cssLibs = [
	{
		url:
			'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css',
		label: 'Bootstrap 3',
		type: 'css'
	},
	{
		url:
			'https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css',
		label: 'Bootstrap 4',
		type: 'css'
	},
	{
		url:
			'https://cdn.jsdelivr.net/npm/foundation-sites@6.5.0-rc.3/dist/css/foundation.min.css',
		label: 'Foundation',
		type: 'css'
	},
	{
		url: 'https://semantic-ui.com/dist/semantic.min.css',
		label: 'Semantic UI',
		type: 'css'
	},
	{
		url: 'https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.1/css/bulma.min.css',
		label: 'Bulma',
		type: 'css'
	},

	{
		url: 'https://cdnjs.cloudflare.com/ajax/libs/hint.css/2.5.0/hint.min.css',
		label: 'Hint.css',
		type: 'css'
	},
	{
		url: 'https://cdn.jsdelivr.net/npm/tailwindcss/dist/tailwind.min.css',
		label: 'Tailwind.css',
		type: 'css'
	},
	{
		url:
			'https://cdnjs.cloudflare.com/ajax/libs/uikit/2.27.5/css/uikit.min.css',
		label: 'UIkit 2',
		type: 'css'
	},
	{
		url:
			'https://getuikit.com/assets/uikit/dist/css/uikit.css',
		label: 'UIkit 3',
		type: 'css'
	},
	{
		url:
			'https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css',
		label: 'Animate.css',
		type: 'css'
	},
	{
		url:
			'https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css',
		label: 'FontAwesome 4',
		type: 'css'
	},
	{
		url: 'https://use.fontawesome.com/releases/v5.4.1/css/all.css',
		label: 'FontAwesome 5',
		type: 'css'
	}
];
<commit_msg>Update libraryList.js<commit_after>export const jsLibs = [
	{
		url: 'https://code.jquery.com/jquery-3.2.1.min.js',
		label: 'jQuery',
		type: 'js'
	},
	{
		url: 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js',
		label: 'Bootstrap 3',
		type: 'js'
	},
	{
		url:
			'https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js',
		label: 'Bootstrap 4',
		type: 'js'
	},
	{
		url:
			'https://cdn.jsdelivr.net/npm/foundation-sites@6.5.0-rc.3/dist/js/foundation.min.js',
		label: 'Foundation',
		type: 'js'
	},
	{
		url: 'https://semantic-ui.com/dist/semantic.min.js',
		label: 'Semantic UI',
		type: 'js'
	},
	{
		url: 'https://ajax.googleapis.com/ajax/libs/angularjs/1.6.5/angular.min.js',
		label: 'Angular',
		type: 'js'
	},
	{
		url:
			'https://cdnjs.cloudflare.com/ajax/libs/react/16.2.0/umd/react.production.min.js',
		label: 'React',
		type: 'js'
	},
	{
		url:
			'https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.2.0/umd/react-dom.production.min.js',
		label: 'React DOM',
		type: 'js'
	},
	{
		url: 'https://unpkg.com/vue/dist/vue.min.js',
		label: 'Vue.js',
		type: 'js'
	},
	{
		url: 'https://cdnjs.cloudflare.com/ajax/libs/three.js/89/three.min.js',
		label: 'Three.js',
		type: 'js'
	},
	{
		url: 'https://d3js.org/d3.v5.min.js',
		label: 'D3',
		type: 'js'
	},
	{
		url:
			'https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js',
		label: 'Underscore',
		type: 'js'
	},
	{
		url: 'https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.3/TweenMax.min.js',
		label: 'Greensock TweenMax',
		type: 'js'
	},
	{
		url: 'https://cdnjs.cloudflare.com/ajax/libs/uikit/2.27.5/js/uikit.min.js',
		label: 'UIkit 2',
		type: 'js'
	},
	{
		url:
			'https://getuikit.com/assets/uikit/dist/js/uikit.js',
		label: 'UIkit 3',
		type: 'js'
	},
	{
		url: 'https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.1/p5.min.js',
		label: 'p5.js',
		type: 'js'
	},
	{
		url: 'https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.1/addons/p5.dom.min.js',
		label: 'p5.js DOM',
		type: 'js'
	},
	{
		url: 'https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.1/addons/p5.sound.min.js',
		label: 'p5.js Sound',
		type: 'js'
	}
];
export const cssLibs = [
	{
		url:
			'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css',
		label: 'Bootstrap 3',
		type: 'css'
	},
	{
		url:
			'https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css',
		label: 'Bootstrap 4',
		type: 'css'
	},
	{
		url:
			'https://cdn.jsdelivr.net/npm/foundation-sites@6.5.0-rc.3/dist/css/foundation.min.css',
		label: 'Foundation',
		type: 'css'
	},
	{
		url: 'https://semantic-ui.com/dist/semantic.min.css',
		label: 'Semantic UI',
		type: 'css'
	},
	{
		url: 'https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.2/css/bulma.min.css',
		label: 'Bulma',
		type: 'css'
	},

	{
		url: 'https://cdnjs.cloudflare.com/ajax/libs/hint.css/2.5.0/hint.min.css',
		label: 'Hint.css',
		type: 'css'
	},
	{
		url: 'https://cdn.jsdelivr.net/npm/tailwindcss/dist/tailwind.min.css',
		label: 'Tailwind.css',
		type: 'css'
	},
	{
		url:
			'https://cdnjs.cloudflare.com/ajax/libs/uikit/2.27.5/css/uikit.min.css',
		label: 'UIkit 2',
		type: 'css'
	},
	{
		url:
			'https://getuikit.com/assets/uikit/dist/css/uikit.css',
		label: 'UIkit 3',
		type: 'css'
	},
	{
		url:
			'https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css',
		label: 'Animate.css',
		type: 'css'
	},
	{
		url:
			'https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css',
		label: 'FontAwesome 4',
		type: 'css'
	},
	{
		url: 'https://use.fontawesome.com/releases/v5.4.1/css/all.css',
		label: 'FontAwesome 5',
		type: 'css'
	}
];
<|endoftext|>


<commit_before>'use strict';

const _ = require('lodash');
const chalk = require('chalk');

const EventsBus = require('./EventsBus');

class Logger {
    constructor(prefix) {
        let onEvent = this.onEvent.bind(this);

        this._prefix = '';

        EventsBus.listen('**', function (data) {
            onEvent(this.event, data);
        });
    }
    onEvent(event, payload) {
        let prefix = this._prefix;
        let output = '';

        // If we get a string through,
        // attempt to parse it to json
        if (typeof payload === 'string') {
            try { payload = JSON.parse(payload) } catch (err) {}
        }

        if (typeof payload.name !== 'undefined') {
            prefix += chalk.green(`[${payload.name}]`)
        }

        if (typeof event !== 'undefined') {
            prefix += chalk.yellow(`[${event}]`);
        }

        if (typeof payload.data === 'string' && event.indexOf('data:') === -1 ) {
            output += payload.data;
        }

        if (event.indexOf(':error') !== -1) {
            output += this.stringify(payload.data);
        }

        if (event.indexOf('data:') === 0) {
            output += this.stringify(payload);
        }

        if (event.indexOf('syrup:started') === 0) {
            output += this.stringify(payload);
        }

        console.log(`${prefix} ${output}`);
    }
    stringify(data) {
        try {
            if (typeof data === 'object') {
                let _data = {};
                _.each(data, (value, key) => {
                    if (key.indexOf('_') !== 0) {
                        _data[key] = value;
                    }
                });

                data = JSON.stringify(_data);
            }
        } catch (err) {

        }

        return (typeof data === 'undefined') ? '' : data;
    }
}

module.exports = Logger;<commit_msg>Clean up logger<commit_after>'use strict';

const _ = require('lodash');
const chalk = require('chalk');

const EventsBus = require('./EventsBus');

class Logger {
    constructor() {
        let onEvent = this.onEvent.bind(this);

        this._prefix = '';

        EventsBus.listen('**', function (data) {
            onEvent(this.event, data);
        });
    }
    onEvent(event, payload) {
        let prefix = this._prefix;
        let output = '';

        // If we get a string through,
        // attempt to parse it to json
        if (typeof payload === 'string') {
            try { payload = JSON.parse(payload); } catch (err) {}
        }

        if (typeof payload.name !== 'undefined') {
            prefix += chalk.green(`[${payload.name}]`);
        }

        if (typeof event !== 'undefined') {
            prefix += chalk.yellow(`[${event}]`);
        }

        if (typeof payload.data === 'string' && event.indexOf('data:') === -1 ) {
            output += payload.data;
        }

        if (event.indexOf(':error') !== -1) {
            output += this.stringify(payload.data);
        }

        if (event.indexOf('data:') === 0) {
            output += this.stringify(payload);
        }

        if (event.indexOf('syrup:started') === 0) {
            output += this.stringify(payload);
        }

        console.log(`${prefix} ${output}`);
    }
    stringify(data) {
        try {
            if (typeof data === 'object') {
                let _data = {};
                _.each(data, (value, key) => {
                    if (key.indexOf('_') !== 0) {
                        _data[key] = value;
                    }
                });

                data = JSON.stringify(_data);
            }
        } catch (err) {

        }

        return (typeof data === 'undefined') ? '' : data;
    }
}

module.exports = Logger;<|endoftext|>


<commit_before>/*
 Copyright (c) 2015, Kotaro Endo.
 All rights reserved.

 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions
 are met:

 1. Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.

 2. Redistributions in binary form must reproduce the above
    copyright notice, this list of conditions and the following
    disclaimer in the documentation and/or other materials provided
    with the distribution.

 3. Neither the name of the copyright holder nor the names of its
    contributors may be used to endorse or promote products derived
    from this software without specific prior written permission.

 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

'use strict';

var process = {};

process.binding = (function() {
	var bindings = {
		contextify : {},
		natives : {},
		smalloc : {},
		constants : {},
		fs : {},
		uv : {},
		http_parser : {},
		crypto : {},
		tty_wrap : {},
		timer_wrap : {},
		pipe_wrap : {},
		cares_wrap : {},
		tcp_wrap : {},
		udp_wrap : {},
		stream_wrap : {},
		signal_wrap : {},
	};
	return function(name) {
		return bindings[name];
	}
})();

Object.defineProperty(Object.prototype, "__defineGetter__", {
	value : function(n, getter) {
		Object.defineProperty(this, n, {
			get : getter
		});
	},
	writable : true,
	enumerable : false,
	configurable : true
});

Object.defineProperty(Number, "isFinite", {
	value : function(value) {
		return typeof value === "number" && isFinite(value);
	},
	writable : true,
	enumerable : false,
	configurable : true
});

Object.defineProperty(Error, "stackTraceLimit", {
	get : function() {
		return getSystemProperty("stackTraceLimit");
	},
	set : function(value) {
		setSystemProperty("stackTraceLimit", value);
	},
	enumerable : true,
	configurable : true
});

Error.captureStackTrace = (function() {
	function StackTraceEntry(info) {
		this.info = info;
	}
	StackTraceEntry.prototype.getFileName = function() {
		return this.info.filename;
	}
	StackTraceEntry.prototype.getLineNumber = function() {
		return this.info.lineNumber;
	}
	StackTraceEntry.prototype.getColumnNumber = function() {
		return this.info.columnNumber;
	}
	StackTraceEntry.prototype.getFunctionName = function() {
		return this.info.functionName;
	}
	StackTraceEntry.prototype.isEval = function() {
		return !this.info.functionObject;
	}

	function prepareStackTrace(obj, stack) {
		var A = [];
		A[0] = "Error";
		for (var i = 0; i < stack.length; i++) {
			var info = stack[i].info;
			var finfo = info.filename + ":" + info.lineNumber + ":" + info.columnNumber;
			A[i+1] = finfo;
			if (info.functionName) {
				A[i+1] = info.functionName + " (" + finfo + ")";
			}
		}
		return A.join("\n    at ");
	}

	return function(obj, func) {
		Error.stackTraceLimit++;
		var e = new Error();
		Error.stackTraceLimit--;
		var stack = [];
		for (var i = 1;; i++) {
			var info = e.getStackTraceEntry(i);
			if (!info) {
				break;
			}
			if (info.functionObject === func) {
				stack = [];
				continue;
			}
			stack.push(new StackTraceEntry(info));
		}
		if (Error.prepareStackTrace) {
			var value = Error.prepareStackTrace(obj, stack);
		}
		else {
			var value = prepareStackTrace(obj, stack);
		}
		Object.defineProperty(obj, "stack", {
			value : value,
			writable : true,
			enumerable : false,
			configurable : true
		});
	};

})();
<commit_msg>bug fix<commit_after>/*
 Copyright (c) 2015, Kotaro Endo.
 All rights reserved.

 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions
 are met:

 1. Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.

 2. Redistributions in binary form must reproduce the above
    copyright notice, this list of conditions and the following
    disclaimer in the documentation and/or other materials provided
    with the distribution.

 3. Neither the name of the copyright holder nor the names of its
    contributors may be used to endorse or promote products derived
    from this software without specific prior written permission.

 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

'use strict';

var process = {};

process.binding = (function() {
	var bindings = {
		contextify : {},
		natives : {},
		smalloc : {},
		constants : {},
		fs : {},
		uv : {},
		http_parser : {},
		crypto : {},
		tty_wrap : {},
		timer_wrap : {},
		pipe_wrap : {},
		cares_wrap : {},
		tcp_wrap : {},
		udp_wrap : {},
		stream_wrap : {},
		signal_wrap : {},
	};
	return function(name) {
		return bindings[name];
	}
})();

Object.defineProperty(Object.prototype, "__defineGetter__", {
	value : function(n, getter) {
		Object.defineProperty(this, n, {
			get : getter
		});
	},
	writable : true,
	enumerable : false,
	configurable : true
});

Object.defineProperty(Number, "isFinite", {
	value : function(value) {
		return typeof value === "number" && isFinite(value);
	},
	writable : true,
	enumerable : false,
	configurable : true
});

Object.defineProperty(Error, "stackTraceLimit", {
	get : function() {
		return getSystemProperty("stackTraceLimit");
	},
	set : function(value) {
		setSystemProperty("stackTraceLimit", value);
	},
	enumerable : true,
	configurable : true
});

Error.captureStackTrace = (function() {
	function StackTraceEntry(info) {
		this.info = info;
	}
	StackTraceEntry.prototype.getFileName = function() {
		return this.info.filename;
	}
	StackTraceEntry.prototype.getLineNumber = function() {
		return this.info.lineNumber;
	}
	StackTraceEntry.prototype.getColumnNumber = function() {
		return this.info.columnNumber;
	}
	StackTraceEntry.prototype.getFunctionName = function() {
		return this.info.functionName;
	}
	StackTraceEntry.prototype.isEval = function() {
		return !this.info.functionObject;
	}

	function prepareStackTrace(obj, stack) {
		var A = [];
		A[0] = Error.prototype.toString.call(obj);
		for (var i = 0; i < stack.length; i++) {
			var info = stack[i].info;
			var finfo = info.filename + ":" + info.lineNumber + ":" + info.columnNumber;
			A[i+1] = finfo;
			if (info.functionName) {
				A[i+1] = info.functionName + " (" + finfo + ")";
			}
		}
		return A.join("\n    at ");
	}

	return function(obj, func) {
		Error.stackTraceLimit++;
		var e = new Error();
		Error.stackTraceLimit--;
		var stack = [];
		for (var i = 1;; i++) {
			var info = e.getStackTraceEntry(i);
			if (!info) {
				break;
			}
			if (info.functionObject === func) {
				stack = [];
				continue;
			}
			stack.push(new StackTraceEntry(info));
		}
		if (Error.prepareStackTrace) {
			var value = Error.prepareStackTrace(obj, stack);
		}
		else {
			var value = prepareStackTrace(obj, stack);
		}
		Object.defineProperty(obj, "stack", {
			value : value,
			writable : true,
			enumerable : false,
			configurable : true
		});
	};

})();
<|endoftext|>


<commit_before>// TODO: pass third argument which is "original tokens" array

export function File(path, node) {
  this.print(path, 'program');
  node[this.key] = [...node[this.tKey]];
  // const programPath = path.get('program');
  // node[this.key] = [
  //   ...programPath.srcElBefore(),
  //   ...programPath.srcEl(),
  //   ...programPath.srcElAfter()
  // ];
}

// TODO: dedupe
function last(t) {
  return t[t.length - 1];
}

export function Program(path, node) {
  // TODO: turn assignment on to t into a method,
  // automatically do reference assignment instead of relying on visitors
  const t = [];

  let lastDirectivePath = null;
  this.print(path, 'directives', {
    before: (firstPath) => {
      t.push(...firstPath.srcElBefore());
    },
    each: (path) => {
      t.push(path.srcEl());
    },
    between: (leftPath, rightPath) => {
      t.push(...leftPath.srcElUntil(rightPath));
    },
    after: (lastPath) => {
      lastDirectivePath = lastPath;
    }
  });

  this.print(path, 'body', {
    before: (firstPath) => {
      t.push(...firstPath.srcElSince(lastDirectivePath));
    },
    each: (path) => {
      t.push(path.srcEl());
    },
    between: (leftPath, rightPath) => {
      t.push(...leftPath.srcElUntil(rightPath));
    },
    after: (lastPath) => {
      t.push(...lastPath.srcElAfter());
    },
    empty: () => {
      if (lastDirectivePath) {
        t.push(...lastDirectivePath.srcElAfter());
      } else {
        t.push(...node[this.tKey]);
      }
    }
  });

  node[this.key] = t;

  if (this._sourceLastElement && this._sourceLastElement.value === '\n') {
    const {
      el,
      index,
      node: newlineNode
    } = (path.lastSrcEl(
      (el) => el.element !== 'EOF' && el.value !== '',
      this.key
    ) || {});
    if (el != null && el.value !== '\n') {
      newlineNode[this.key].push({element: 'WhiteSpace', value: '\n'});
    }
  }
}

export function Directive(path, node) {
  const valuePath = path.get('value');
  this.print(path, 'value');
  const trailing = valuePath.srcElAfter();
  const t = [
    ...valuePath.srcElBefore(),
    valuePath.srcEl(),
  ];
  const mappedTrailing = [];
  let beforeLineTerminator = true;
  for (const el of trailing) {
    if (beforeLineTerminator && el.element === 'LineTerminator') {
      beforeLineTerminator = false;
      mappedTrailing.push({element: 'Punctuator', value: ';'});
      if (el.value !== '') {
        mappedTrailing.push(el);
      }
    } else {
      mappedTrailing.push(el);
    }
  }
  if (beforeLineTerminator) {
    t.push({element: 'Punctuator', value: ';'});
  }
  t.push(...mappedTrailing);
  node[this.key] = t;
}

export function DirectiveLiteral(path, node) {
  node[this.key] = [...node[this.tKey]];
}

export function _printBlockLeading(leadingElements) {
  const t = [];
  let beforeExcl = true;
  let beforeOpen = true;
  for (const element of (leadingElements: Array)) {
    if (element.element === 'Punctuator' && element.value === '!') {
      beforeExcl = false;
    } else if (element.element === 'Indent') {
      beforeOpen = false;
      t.push({element: 'Punctuator', value: '{'});
    } else {
      t.push(element);
    }
  }
  if (beforeExcl && beforeOpen) {
    t.push({element: 'Punctuator', value: '{'});
  }
  return t;
}
// TODO: convert all / most empty LineTermainators into '\n'
export function _printBlockTrailing(path, trailingElements) {
  const t = [];
  for (const element of (trailingElements: Array)) {
    if (element.element === 'LineTerminator') {
      if (element.value === '') {
        // do nothing
      } else {
        t.push(element);
      }
    } else if (element.element === 'Dedent') {
      const lastElement = t[t.length - 1] || this._lastElement;
      if (lastElement.value !== '\n') {
        t.push({element: 'LineTerminator', value: '\n'});
      }
      t.push(...path.indent());
      t.push({element: 'Punctuator', value: '}'});
    } else {
      t.push(element);
    }
  }
  return t;
}

export function BlockStatement(path, node) {
  const t = [];

  // TODO: read formatting markers and omit newlines where applicable
  let lastDirectivePath;
  if (node.directives && node.directives.length) {
    this.print(path, 'directives', {
      before: (firstPath) => {
        const leadingElements = firstPath.srcElBefore();
        t.push(...this._printBlockLeading(leadingElements));
      },
      each(path) { t.push(path.srcEl()); },
      between(leftPath, rightPath) {
        t.push(...leftPath.srcElUntil(rightPath));
      },
      after(lastPath) {
        lastDirectivePath = lastPath;
      }
    });
  }

  this.print(path, 'body', {
    before: (firstPath) => {
      const leadingElements = firstPath.srcElSince(lastDirectivePath);
      if (node.directives && node.directives.length) {
        t.push(...leadingElements);
      } else {
        t.push(...this._printBlockLeading(leadingElements));
      }
    },
    each: (path) => {
      t.push(path.srcEl());
    },
    between: (leftPath, rightPath) => {
      t.push(...leftPath.srcElUntil(rightPath));
    },
    after: (lastPath) => {
      // TODO: put close curly where dedent is instead
      const trailingElements = lastPath.srcElAfter(lastPath);
      t.push(...this._printBlockTrailing(path, trailingElements));
    },
    empty: () => {
      if (!lastDirectivePath) {
        t.push({element: 'Punctuator', value: '{'});
      }
      // ... // TODO: strip out indent/dedents
      if (lastDirectivePath) {
        t.push(...this._printBlockTrailing(path, lastDirectivePath.srcElAfter()));
      } else {
        t.push({element: 'Punctuator', value: '}'});
        t.push(...node[this.tKey]);
      }
    }
  });

  if (path.parent.type === 'BlockStatement' || path.parent.type === 'Program') {
    let prevEl;
    const {
      el: lastBeforeDedent
    } = path.lastSrcEl((el) => {
      if (el.element !== 'Dedent' && el.element !== 'Indent') {
        if (el.value === '') return false;
        if (prevEl && prevEl.element === 'Dedent') return true;
      }
      prevEl = el;
      return false;
    });

    if (lastBeforeDedent.value === '\n') t.push({element: 'WhiteSpace', value: '\n'});
  }

  node[this.key] = t;
}
<commit_msg>fix: fix some printing routines<commit_after>// TODO: pass third argument which is "original tokens" array

export function File(path, node) {
  this.print(path, 'program');
  node[this.key] = [...node[this.tKey]];
  // const programPath = path.get('program');
  // node[this.key] = [
  //   ...programPath.srcElBefore(),
  //   ...programPath.srcEl(),
  //   ...programPath.srcElAfter()
  // ];
}

// TODO: dedupe
function last(t) {
  return t[t.length - 1];
}

export function Program(path, node) {
  // TODO: turn assignment on to t into a method,
  // automatically do reference assignment instead of relying on visitors
  const t = [];

  let lastDirectivePath = null;
  if (node.directives) this.print(path, 'directives', {
    before: (firstPath) => {
      t.push(...firstPath.srcElBefore());
    },
    each: (path) => {
      t.push(path.srcEl());
    },
    between: (leftPath, rightPath) => {
      t.push(...leftPath.srcElUntil(rightPath));
    },
    after: (lastPath) => {
      lastDirectivePath = lastPath;
    }
  });

  this.print(path, 'body', {
    before: (firstPath) => {
      t.push(...firstPath.srcElSince(lastDirectivePath));
    },
    each: (path) => {
      t.push(path.srcEl());
    },
    between: (leftPath, rightPath) => {
      t.push(...leftPath.srcElUntil(rightPath));
    },
    after: (lastPath) => {
      t.push(...lastPath.srcElAfter());
    },
    empty: () => {
      if (lastDirectivePath) {
        t.push(...lastDirectivePath.srcElAfter());
      } else {
        t.push(...node[this.tKey]);
      }
    }
  });

  node[this.key] = t;

  if (this._sourceLastElement && this._sourceLastElement.value === '\n') {
    const {
      el,
      index,
      node: newlineNode
    } = (path.lastSrcEl(
      (el) => el.element !== 'EOF' && el.value !== '',
      this.key
    ) || {});
    if (el != null && el.value !== '\n') {
      newlineNode[this.key].push({element: 'WhiteSpace', value: '\n'});
    }
  }
}

export function Directive(path, node) {
  const valuePath = path.get('value');
  this.print(path, 'value');
  const trailing = valuePath.srcElAfter();
  const t = [
    ...valuePath.srcElBefore(),
    valuePath.srcEl(),
  ];
  const mappedTrailing = [];
  let beforeLineTerminator = true;
  for (const el of trailing) {
    if (beforeLineTerminator && el.element === 'LineTerminator') {
      beforeLineTerminator = false;
      mappedTrailing.push({element: 'Punctuator', value: ';'});
      if (el.value !== '') {
        mappedTrailing.push(el);
      }
    } else {
      mappedTrailing.push(el);
    }
  }
  if (beforeLineTerminator) {
    t.push({element: 'Punctuator', value: ';'});
  }
  t.push(...mappedTrailing);
  node[this.key] = t;
}

export function DirectiveLiteral(path, node) {
  node[this.key] = [...node[this.tKey]];
}

export function _printBlockLeading(leadingElements) {
  const t = [];
  let beforeExcl = true;
  let beforeOpen = true;
  for (const element of (leadingElements: Array)) {
    if (element.element === 'Punctuator' && element.value === '!') {
      beforeExcl = false;
    } else if (element.element === 'Indent') {
      beforeOpen = false;
      t.push({element: 'Punctuator', value: '{'});
    } else {
      t.push(element);
    }
  }
  if (beforeExcl && beforeOpen) {
    t.push({element: 'Punctuator', value: '{'});
  }
  return t;
}
// TODO: convert all / most empty LineTermainators into '\n'
export function _printBlockTrailing(path, trailingElements) {
  const t = [];
  for (const element of (trailingElements: Array)) {
    if (element.element === 'LineTerminator') {
      if (element.value === '') {
        // do nothing
      } else {
        t.push(element);
      }
    } else if (element.element === 'Dedent') {
      const lastElement = t[t.length - 1] || this._lastElement;
      if (lastElement.value !== '\n') {
        t.push({element: 'LineTerminator', value: '\n'});
      }
      t.push(...path.indent());
      t.push({element: 'Punctuator', value: '}'});
    } else {
      t.push(element);
    }
  }
  return t;
}

export function BlockStatement(path, node) {
  const t = [];

  // TODO: read formatting markers and omit newlines where applicable
  let lastDirectivePath;
  if (node.directives && node.directives.length) {
    this.print(path, 'directives', {
      before: (firstPath) => {
        const leadingElements = firstPath.srcElBefore();
        t.push(...this._printBlockLeading(leadingElements));
      },
      each(path) { t.push(path.srcEl()); },
      between(leftPath, rightPath) {
        t.push(...leftPath.srcElUntil(rightPath));
      },
      after(lastPath) {
        lastDirectivePath = lastPath;
      }
    });
  }

  this.print(path, 'body', {
    before: (firstPath) => {
      const leadingElements = firstPath.srcElSince(lastDirectivePath);
      if (node.directives && node.directives.length) {
        t.push(...leadingElements);
      } else {
        t.push(...this._printBlockLeading(leadingElements));
      }
    },
    each: (path) => {
      t.push(path.srcEl());
    },
    between: (leftPath, rightPath) => {
      t.push(...leftPath.srcElUntil(rightPath));
    },
    after: (lastPath) => {
      // TODO: put close curly where dedent is instead
      const trailingElements = lastPath.srcElAfter(lastPath);
      t.push(...this._printBlockTrailing(path, trailingElements));
    },
    empty: () => {
      if (!lastDirectivePath) {
        t.push({element: 'Punctuator', value: '{'});
      }
      // ... // TODO: strip out indent/dedents
      if (lastDirectivePath) {
        t.push(...this._printBlockTrailing(path, lastDirectivePath.srcElAfter()));
      } else {
        t.push({element: 'Punctuator', value: '}'});
        // TODO: only do this if it's a stanlone block. make a test in node (like needs-parenthises)
        // to check if it's a stanalone block
        t.push(...node[this.tKey].filter((el) => !(el.element === 'Punctuator' && el.value === '!')));
      }
    }
  });

  if (path.parent.type === 'BlockStatement' || path.parent.type === 'Program') {
    let prevEl;
    const {
      el: lastBeforeDedent
    } = path.lastSrcEl((el) => {
      if (el.element !== 'Dedent' && el.element !== 'Indent') {
        if (el.value === '') return false;
        if (prevEl && prevEl.element === 'Dedent') return true;
      }
      prevEl = el;
      return false;
    }) || {};

    if (lastBeforeDedent && lastBeforeDedent.value === '\n') t.push({element: 'WhiteSpace', value: '\n'});
  }

  node[this.key] = t;
}
<|endoftext|>


<commit_before>import { unwrapChildren } from '../util/domHelpers'

export default class WrapBodyContent {

  import(dom) {
    let bodies = dom.findAll('body')
    bodies.forEach((body) => {
      const sigBlock = body.find('sig-block')
      const children = body.children
      body.empty()
      body.append(
        dom.createElement('body-content').append(children)
      )
      if (sigBlock) {
        body.append(sigBlock)
      }
    })
  }

  export(dom) {
    let contentEls = dom.findAll('body-content')
    contentEls.forEach(unwrapChildren)
  }
}
<commit_msg>Ensure that there is at least one p element inside body.<commit_after>import { unwrapChildren } from '../util/domHelpers'

export default class WrapBodyContent {

  import(dom) {
    let bodies = dom.findAll('body')
    bodies.forEach((body) => {
      const sigBlock = body.find('sig-block')
      const children = body.children
      // Ensure there is at least one p element inside body
      if (children.length ===0) {
        children.push(dom.createElement('p'))
      }
      body.empty()
      body.append(
        dom.createElement('body-content').append(children)
      )
      if (sigBlock) {
        body.append(sigBlock)
      }
    })
  }

  export(dom) {
    let contentEls = dom.findAll('body-content')
    contentEls.forEach(unwrapChildren)
  }
}
<|endoftext|>


<commit_before>'use strict'

module.exports = {
  hooks: {
    'pre-commit': 'npm run lint',
    'pre-push': 'npm run lint && npm test',
  },
}
<commit_msg>Add build step to pre-push git hook<commit_after>'use strict'

module.exports = {
  hooks: {
    'pre-commit': 'npm run lint',
    'pre-push': 'npm run lint && npm build && npm test',
  },
}
<|endoftext|>


<commit_before>/*
Copyright 2019 New Vector Ltd
Copyright 2019, 2020 The Matrix.org Foundation C.I.C.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

const assert = require('assert');
const {openMemberInfo} = require("./memberlist");

async function startVerification(session, name) {
    session.log.step("opens their opponent's profile and starts verification");
    await openMemberInfo(session, name);
    // click verify in member info
    const firstVerifyButton = await session.query(".mx_UserInfo_verifyButton");
    await firstVerifyButton.click();

    // wait for the animation to finish
    await session.delay(1000);

    // click 'start verification'
    const startVerifyButton = await session.query('.mx_UserInfo_container .mx_AccessibleButton_kind_primary');
    await startVerifyButton.click();
    session.log.done();
}

async function getSasCodes(session) {
    const sasLabelElements = await session.queryAll(
        ".mx_VerificationShowSas .mx_VerificationShowSas_emojiSas .mx_VerificationShowSas_emojiSas_label");
    const sasLabels = await Promise.all(sasLabelElements.map(e => session.innerText(e)));
    return sasLabels;
}

async function doSasVerification(session) {
    session.log.step("hunts for the emoji to yell at their opponent");
    const sasCodes = await getSasCodes(session);
    session.log.done(sasCodes);

    // Assume they match
    session.log.step("assumes the emoji match");
    const matchButton = await session.query(".mx_VerificationShowSas .mx_AccessibleButton_kind_primary");
    await matchButton.click();
    session.log.done();

    // Wait for a big green shield (universal sign that it worked)
    session.log.step("waits for a green shield");
    await session.query(".mx_VerificationPanel_verified_section .mx_E2EIcon_verified");
    session.log.done();

    // Click 'Got It'
    session.log.step("confirms the green shield");
    const doneButton = await session.query(".mx_VerificationPanel_verified_section .mx_AccessibleButton_kind_primary");
    await doneButton.click();
    session.log.done();

    // Wait a bit for the animation
    session.log.step("confirms their opponent has a green shield");
    await session.delay(1000);

    // Verify that we now have a green shield in their name (proving it still works)
    await session.query('.mx_UserInfo_profile .mx_E2EIcon_verified');
    session.log.done();

    return sasCodes;
}

module.exports.startSasVerifcation = async function(session, name) {
    session.log.startGroup("starts verification");
    await startVerification(session, name);

    // expect to be waiting (the presence of a spinner is a good thing)
    await session.query('.mx_UserInfo_container .mx_EncryptionInfo_spinner');

    const sasCodes = await doSasVerification(session);
    session.log.endGroup();
    return sasCodes;
};

module.exports.acceptSasVerification = async function(session, name) {
    session.log.startGroup("accepts verification");
    const requestToast = await session.query('.mx_Toast_icon_verification');

    // verify the toast is for verification
    const toastHeader = await requestToast.$("h2");
    const toastHeaderText = await session.innerText(toastHeader);
    assert.equal(toastHeaderText, 'Verification Request');
    const toastDescription = await requestToast.$(".mx_Toast_description");
    const toastDescText = await session.innerText(toastDescription);
    assert.equal(toastDescText.startsWith(name), true,
        `verification opponent mismatch: expected to start with '${name}', got '${toastDescText}'`);

    // accept the verification
    const acceptButton = await requestToast.$(".mx_AccessibleButton_kind_primary");
    await acceptButton.click();

    // find the emoji button
    const startEmojiButton = await session.query(".mx_VerificationPanel_verifyByEmojiButton");
    await startEmojiButton.click();

    const sasCodes = await doSasVerification(session);
    session.log.endGroup();
    return sasCodes;
};
<commit_msg>Fix tests<commit_after>/*
Copyright 2019 New Vector Ltd
Copyright 2019, 2020 The Matrix.org Foundation C.I.C.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

const assert = require('assert');
const {openMemberInfo} = require("./memberlist");

async function startVerification(session, name) {
    session.log.step("opens their opponent's profile and starts verification");
    await openMemberInfo(session, name);
    // click verify in member info
    const firstVerifyButton = await session.query(".mx_UserInfo_verifyButton");
    await firstVerifyButton.click();

    // wait for the animation to finish
    await session.delay(1000);

    // click 'start verification'
    const startVerifyButton = await session.query('.mx_UserInfo_container .mx_AccessibleButton_kind_primary');
    await startVerifyButton.click();
    session.log.done();
}

async function getSasCodes(session) {
    const sasLabelElements = await session.queryAll(
        ".mx_VerificationShowSas .mx_VerificationShowSas_emojiSas .mx_VerificationShowSas_emojiSas_label");
    const sasLabels = await Promise.all(sasLabelElements.map(e => session.innerText(e)));
    return sasLabels;
}

async function doSasVerification(session) {
    session.log.step("hunts for the emoji to yell at their opponent");
    const sasCodes = await getSasCodes(session);
    session.log.done(sasCodes);

    // Assume they match
    session.log.step("assumes the emoji match");
    const matchButton = await session.query(".mx_VerificationShowSas .mx_AccessibleButton_kind_primary");
    await matchButton.click();
    session.log.done();

    // Wait for a big green shield (universal sign that it worked)
    session.log.step("waits for a green shield");
    await session.query(".mx_VerificationPanel_verified_section .mx_E2EIcon_verified");
    session.log.done();

    // Click 'Got It'
    session.log.step("confirms the green shield");
    const doneButton = await session.query(".mx_VerificationPanel_verified_section .mx_AccessibleButton_kind_primary");
    await doneButton.click();
    session.log.done();

    // Wait a bit for the animation
    session.log.step("confirms their opponent has a green shield");
    await session.delay(1000);

    // Verify that we now have a green shield in their name (proving it still works)
    await session.query('.mx_UserInfo_profile .mx_E2EIcon_verified');
    session.log.done();

    return sasCodes;
}

module.exports.startSasVerifcation = async function(session, name) {
    session.log.startGroup("starts verification");
    await startVerification(session, name);

    // expect to be waiting (the presence of a spinner is a good thing)
    await session.query('.mx_UserInfo_container .mx_EncryptionInfo_spinner');

    const sasCodes = await doSasVerification(session);
    session.log.endGroup();
    return sasCodes;
};

module.exports.acceptSasVerification = async function(session, name) {
    session.log.startGroup("accepts verification");
    const requestToast = await session.query('.mx_Toast_icon_verification');

    // verify the toast is for verification
    const toastHeader = await requestToast.$("h2");
    const toastHeaderText = await session.innerText(toastHeader);
    assert.equal(toastHeaderText, 'Verification requested');
    const toastDescription = await requestToast.$(".mx_Toast_description");
    const toastDescText = await session.innerText(toastDescription);
    assert.equal(toastDescText.startsWith(name), true,
        `verification opponent mismatch: expected to start with '${name}', got '${toastDescText}'`);

    // accept the verification
    const acceptButton = await requestToast.$(".mx_AccessibleButton_kind_primary");
    await acceptButton.click();

    // find the emoji button
    const startEmojiButton = await session.query(".mx_VerificationPanel_verifyByEmojiButton");
    await startEmojiButton.click();

    const sasCodes = await doSasVerification(session);
    session.log.endGroup();
    return sasCodes;
};
<|endoftext|>