<commit_before>'use strict';

let express = require('express');
let path = require('path');
let fs = require('fs');
let os = require('os');

let qr = require('qr-image');
let open = require('open');

let app = express();
let router = express.Router();
let ws = require('express-ws')(app);
let ifaces = os.networkInterfaces();

let robot = require('robotjs');

let getFocusProcess = require('./get-focus-process');

let titleOf = {
	"chrome" : "Google Chrome",
	"chromium" : "Google Chrome",
	"POWERPNT" : "PowerPoint",
	"slack" : "Slack",
	"spotify" : "Spotify",
    "WebStorm" : "WebStorm",
    "PyCharm" : "PyCharm"
};

function styleOf(name) {
	let fileName = __dirname + '/styles/' + name + '.json';
	if (fs.existsSync(fileName)) {
		let fileContent = JSON.parse(fs.readFileSync(fileName, 'utf8'));
		return fileContent;
	} else {
		return {};
	}
}

app.use(router);
app.use(express.static('views/static'));

let similarProcesses = {
	"chromium": "chrome",
    "PyCharm": "WebStorm",
    "idea": "WebStorm"
};

router.get('/', function (req, res) {
	res.sendFile(__dirname + '/views/index.html');
});

router.ws('/ws', function (ws, req) {
	ws.on('message', function (msg) {
		msg = JSON.parse(msg);

		if (!msg.error) {
			switch (msg.type) {
				case 'ping':
					msg.type = 'pong';
					ws.send(JSON.stringify(msg));
					break;
				case 'hello':
					ws.send(JSON.stringify({
						type: "process-changed",
						data: {
							name: currentProcess,
							title: titleOf[currentProcess],
							style: styleOf(currentProcess)
						}
					}));
					break;
				case 'keystroke':
					for (let combinations of msg.data.keys) {
						if (typeof combinations === 'string') {
							robot.keyTap(combinations);
						} else {
							let key = combinations.pop();
							robot.keyTap(key, combinations);
						}
					}
					break;

				case 'layout-request':
					let processName = msg.data.process;

					if (processName in similarProcesses) {
						processName = similarProcesses[processName];
					}

					let fileName = __dirname + '/processes/' + processName + '.json';

					if (fs.existsSync(fileName)) {
						let fileContent = JSON.parse(fs.readFileSync(fileName, 'utf8'));
						let payload = JSON.stringify({type: 'layout', data: fileContent});
						ws.send(payload);
					} else {
						console.warn('Layout for "' + processName + '" doesn\'t exists');
					}
			}
		} else {
			console.error(msg.error);
		}
	});
});

let currentProcess = "";
function processWatcher() {
	setInterval(function () {
		getFocusProcess(function (process) {
			if (currentProcess !== process) {
				currentProcess = process;

				for (let client of ws.getWss().clients) {
					client.send(JSON.stringify({
						type: "process-changed",
						data: {
							name: process,
							title: titleOf[process],
							style: styleOf(process)
						}
					}));
				}
			}
		})
	}, 500);
}

processWatcher();

// Start the server on port 3000.
let server = app.listen(3000, () => {
	let host = server.address().address;
	let port = server.address().port;

	console.log('Maquereau server listening at http://%s:%s.', host, port);

	Object.keys(ifaces).forEach(function (ifname) {
		let alias = 0;
		let localIps = [];
		ifaces[ifname].forEach(function (iface) {
			if ('IPv4' !== iface.family || iface.internal !== false) {
				// skip over internal (i.e. 127.0.0.1) and non-ipv4 addresses
				return;
			}
			if (alias >= 1) {
				// this single interface has multiple ipv4 addresses
				console.log(ifname + ':' + alias, iface.address + ":" + port);
				localIps.push(iface.address);
			} else {
				// this interface has only one ipv4 adress
				console.log(ifname, iface.address + ":" + port);
				localIps.push(iface.address);
			}
			++alias;
		});

		let i = 0;
		var qr_png;
		var svg_string;
		localIps.forEach(function (localIp) {
			qr_png = qr.image(localIp + ":" + port, { type: 'png' });
			qr_png.pipe(fs.createWriteStream('scan_me_' + i + '.png'));
			svg_string = qr.imageSync('localIp + ":" + port', { type: 'png' });
			i++
		});
	});
	open('file://' + __dirname + path.sep + 'scan_me_' + 0 + '.png', 'chrome');
});

module.exports = app;
<commit_msg>Make process checking sync<commit_after>'use strict';

let express = require('express');
let path = require('path');
let fs = require('fs');
let os = require('os');

let qr = require('qr-image');
let open = require('open');

let app = express();
let router = express.Router();
let ws = require('express-ws')(app);
let ifaces = os.networkInterfaces();

let robot = require('robotjs');

let getFocusProcess = require('./get-focus-process');

let titleOf = {
	"chrome" : "Google Chrome",
	"chromium" : "Google Chrome",
	"POWERPNT" : "PowerPoint",
	"slack" : "Slack",
	"spotify" : "Spotify",
    "WebStorm" : "WebStorm",
    "PyCharm" : "PyCharm"
};

function styleOf(name) {
	let fileName = __dirname + '/styles/' + name + '.json';
	if (fs.existsSync(fileName)) {
		let fileContent = JSON.parse(fs.readFileSync(fileName, 'utf8'));
		return fileContent;
	} else {
		return {};
	}
}

app.use(router);
app.use(express.static('views/static'));

let similarProcesses = {
	"chromium": "chrome",
    "PyCharm": "WebStorm",
    "idea": "WebStorm"
};

router.get('/', function (req, res) {
	res.sendFile(__dirname + '/views/index.html');
});

router.ws('/ws', function (ws, req) {
	ws.on('message', function (msg) {
		msg = JSON.parse(msg);

		if (!msg.error) {
			switch (msg.type) {
				case 'ping':
					msg.type = 'pong';
					ws.send(JSON.stringify(msg));
					break;
				case 'hello':
					ws.send(JSON.stringify({
						type: "process-changed",
						data: {
							name: currentProcess,
							title: titleOf[currentProcess],
							style: styleOf(currentProcess)
						}
					}));
					break;
				case 'keystroke':
					for (let combinations of msg.data.keys) {
						if (typeof combinations === 'string') {
							robot.keyTap(combinations);
						} else {
							let key = combinations.pop();
							robot.keyTap(key, combinations);
						}
					}
					break;

				case 'layout-request':
					let processName = msg.data.process;

					if (processName in similarProcesses) {
						processName = similarProcesses[processName];
					}

					let fileName = __dirname + '/processes/' + processName + '.json';

					if (fs.existsSync(fileName)) {
						let fileContent = JSON.parse(fs.readFileSync(fileName, 'utf8'));
						let payload = JSON.stringify({type: 'layout', data: fileContent});
						ws.send(payload);
					} else {
						console.warn('Layout for "' + processName + '" doesn\'t exists');
					}
			}
		} else {
			console.error(msg.error);
		}
	});
});

let currentProcess = "";
const timeInterval = 500;

function processWatcher() {
	getFocusProcess(function (process) {
		if (currentProcess !== process) {
			currentProcess = process;

			for (let client of ws.getWss().clients) {
				client.send(JSON.stringify({
					type: "process-changed",
					data: {
						name: process,
						title: titleOf[process],
						style: styleOf(process)
					}
				}));
			}
		}

		setTimeout(processWatcher, timeInterval);
	});
}

setTimeout(processWatcher, timeInterval);

// Start the server on port 3000.
let server = app.listen(3000, () => {
	let host = server.address().address;
	let port = server.address().port;

	console.log('Maquereau server listening at http://%s:%s.', host, port);

	Object.keys(ifaces).forEach(function (ifname) {
		let alias = 0;
		let localIps = [];
		ifaces[ifname].forEach(function (iface) {
			if ('IPv4' !== iface.family || iface.internal !== false) {
				// skip over internal (i.e. 127.0.0.1) and non-ipv4 addresses
				return;
			}
			if (alias >= 1) {
				// this single interface has multiple ipv4 addresses
				console.log(ifname + ':' + alias, iface.address + ":" + port);
				localIps.push(iface.address);
			} else {
				// this interface has only one ipv4 adress
				console.log(ifname, iface.address + ":" + port);
				localIps.push(iface.address);
			}
			++alias;
		});

		let i = 0;
		var qr_png;
		var svg_string;
		localIps.forEach(function (localIp) {
			qr_png = qr.image(localIp + ":" + port, { type: 'png' });
			qr_png.pipe(fs.createWriteStream('scan_me_' + i + '.png'));
			svg_string = qr.imageSync('localIp + ":" + port', { type: 'png' });
			i++
		});
	});
	open('file://' + __dirname + path.sep + 'scan_me_' + 0 + '.png', 'chrome');
});

module.exports = app;
<|endoftext|>


<commit_before>import React from 'react';
import { render } from 'react-dom';
import Provider from '../../../app/containers/Provider';
import DevTools from '../../../app/containers/DevTools';
import createDevStore from '../../../app/store/createDevStore';

const store = createDevStore((action) => {
  chrome.devtools.inspectedWindow.eval('dispatch(' + JSON.stringify(action) + ')', {
    useContentScriptContext: true
  });
});

let rendered = false;

function showDevTools() {
  if (!rendered) {
    render(
      <Provider store={store}>
        <DevTools />
      </Provider>,
      document.getElementById('root')
    );
    rendered = true;
  }
}

const backgroundPageConnection = chrome.runtime.connect({
  name: 'panel'
});

backgroundPageConnection.onMessage.addListener((message) => {
  if (message.source !== 'redux-page') return;
  if (message.na) {
    render(

No store found. Make sure to follow the instructions.
,
      document.getElementById('root')
    );
    rendered = false;
    return;
  }
  if (!message.payload) return;

  store.liftedStore.setState(message.payload);
  showDevTools();
});

backgroundPageConnection.postMessage({
  name: 'init',
  tabId: chrome.devtools.inspectedWindow.tabId
});
<commit_msg>If devToolsExtension wasn't injected, reload the page and inject it<commit_after>import React from 'react';
import { render } from 'react-dom';
import Provider from '../../../app/containers/Provider';
import DevTools from '../../../app/containers/DevTools';
import createDevStore from '../../../app/store/createDevStore';

const store = createDevStore((action) => {
  chrome.devtools.inspectedWindow.eval('dispatch(' + JSON.stringify(action) + ')', {
    useContentScriptContext: true
  });
});

let rendered = false;

function showDevTools() {
  if (!rendered) {
    render(
      <Provider store={store}>
        <DevTools />
      </Provider>,
      document.getElementById('root')
    );
    rendered = true;
  }
}

const backgroundPageConnection = chrome.runtime.connect({
  name: 'panel'
});

backgroundPageConnection.onMessage.addListener((message) => {
  if (message.source !== 'redux-page') return;
  if (message.na) {
    render(

No store found. Make sure to follow the instructions.
,
      document.getElementById('root')
    );
    rendered = false;
    return;
  }
  if (!message.payload) return;

  store.liftedStore.setState(message.payload);
  showDevTools();
});

backgroundPageConnection.postMessage({
  name: 'init',
  tabId: chrome.devtools.inspectedWindow.tabId
});

// If devToolsExtension wasn't injected, reload the page and inject it
chrome.devtools.inspectedWindow.eval(
  'devToolsExtension',
  function(result, isException) {
    if (isException) {
      chrome.devtools.inspectedWindow.reload({
        injectedScript: 'setTimeout( function () {' +
        'var s = document.createElement(\'script\');' +
        's.src = \'' + chrome.extension.getURL('js/content.bundle.js') + '\';' +
        's.onload = function() { this.parentNode.removeChild(this); };' +
        'document.documentElement.appendChild(s);' +
        '}, 0);'
      });
    }
  }
);
<|endoftext|>


<commit_before>(function(){

    "use strict";

    /** This behavior will provide "examine" mode camera control on the given
     *  target transformable.
     *  This behavior does have no notion of the interaction device. All it needs
     *  are deltaX and deltaY values, from which it computes the camera pose.
     *
     *  Usage:
     *  o instantiate this class
     *  o call dolly() and rotate()
     *
     *  @constructor
     */
    XMOT.ExamineControllerBehavior = new XMOT.Class({

        /**
         *  @this {XMOT.ExamineControllerBehavior}
         *  @param {Element|Transformable} targetViewGroup
         *  @param {Object} options
         *
         *  options:
         *  o rotateSpeed, default 1
         *  o dollySpeed, default 40
         *  o examineOrigin, default scene's bounding box center
         */
        initialize: function(targetViewGroup, options) {

            this.target = XMOT.util.getOrCreateTransformable(targetViewGroup);

            /** @private */
            this._scene = XMOT.util.getXml3dRoot(this.target.object);

            /** @private */
            this._rotateSpeed = 1;

            /** @private */
            this._dollySpeed = 40;

            /** @private */
            this._currentAction = this.NONE;

            /** @private */
            this._sceneRadius = this._getSceneRadius();

            /** @private */
            this._examineOrigin = this._getExamineOriginFromScene();

            this._parseOptions(options);
        },

        /**
         *  @this {XMOT.ExamineControllerBehavior}
         */
        lookAt: function(newExamineOrigin) {

            var initCamDirection = new XML3DVec3(0, 0, -1);

            var curDirection = this.target.getOrientation().rotateVec3(initCamDirection);
            var newDirection = newExamineOrigin.subtract(this.target.getPosition());
            newDirection = newDirection.normalize();

            var rotationToNewOrigin = new XML3DRotation();
            rotationToNewOrigin.setRotation(curDirection, newDirection);

            this.target.rotate(rotationToNewOrigin);
            this._examineOrigin.set(newExamineOrigin);
        },

        /**
         *  @this {XMOT.ExamineControllerBehavior}
         */
        dolly: function(deltaX, deltaY) {

            var coef = 0.2 * this._sceneRadius;
            var dy = coef * this._dollySpeed * deltaY;

            var translVec = this._rotateVecToViewSpace(new window.XML3DVec3(0, 0, dy));
            this.target.translate(translVec);
        },

        /**
         *  @this {XMOT.ExamineControllerBehavior}
         *  @param {number} deltaXAngle delta value for rotation around the x-axis
         *  @param {number} deltaYAngle delta value for rotation around the y-axis
         */
        rotate: function(deltaXAngle, deltaYAngle) {
            var dx = -this._rotateSpeed * deltaXAngle * 2.0 * Math.PI;
            var dy = -this._rotateSpeed * deltaYAngle * 2.0 * Math.PI;

            var mx = new window.XML3DRotation(new window.XML3DVec3(1, 0, 0), dx);
            var my = new window.XML3DRotation(new window.XML3DVec3(0, 1, 0), dy);
            var result = mx.multiply(my);

            this._rotateAroundPoint(result, this._examineOrigin);
        },

        /**
         *  @this {XMOT.ExamineControllerBehavior}
         */
        _rotateVecToViewSpace: function(vec) {
            return this.target.getOrientation().rotateVec3(vec);
        },

        /**
         *  @this {XMOT.ExamineControllerBehavior}
         */
        getRotateSpeed: function() {
            return this._rotateSpeed;
        },

        /**
         *  @this {XMOT.ExamineControllerBehavior}
         */
        getDollySpeed: function() {
            return this._dollySpeed;
        },

        /**
         *  @this {XMOT.ExamineControllerBehavior}
         */
        getSceneRadius: function() {
            return this._sceneRadius;
        },

        /**
         *  @this {XMOT.ExamineControllerBehavior}
         */
        getExamineOrigin: function() {
            return new window.XML3DVec3(this._examineOrigin);
        },

        /**
         *  @this {XMOT.ExamineControllerBehavior}
         *  @private
         */
        _parseOptions: function(options) {

            var options = options || {};
            if(options.rotateSpeed !== undefined)
                this._rotateSpeed = options.rotateSpeed;
            if(options.dollySpeed !== undefined)
                this._dollySpeed = options.dollySpeed;
            if(options.examineOrigin !== undefined)
                this._examineOrigin = options.examineOrigin;
        },

        /**
         *  @this {XMOT.ExamineControllerBehavior}
         *  @private
         */
        _rotateAroundPoint: function(rot, point) {
            this.target.rotate(rot);
            var q = new XML3DRotation(this._rotateVecToViewSpace(rot.axis), rot.angle);
            var trans = q.rotateVec3(this.target.getPosition().subtract(point));
            var newPos = point.add(trans);
            this.target.setPosition(newPos);
        },

        /**
         *  @this {XMOT.ExamineControllerBehavior}
         *  @private
         */
        _getSceneRadius: function() {
            var length = this._scene.getBoundingBox().size().length();
            return length * 0.5;
        },

        /**
         *  @this {XMOT.ExamineControllerBehavior}
         *  @private
         */
        _getExamineOriginFromScene: function() {

            var orig = new window.XML3DVec3();

            var bb = this._scene.getBoundingBox();
            if (!bb.isEmpty()) {
                orig.set(bb.center());
            }

            return orig;
        }
    });
}());
<commit_msg>ExamineControllerBehavior: renamed internal method<commit_after>(function(){

    "use strict";

    /** This behavior will provide "examine" mode camera control on the given
     *  target transformable.
     *  This behavior does have no notion of the interaction device. All it needs
     *  are deltaX and deltaY values, from which it computes the camera pose.
     *
     *  Usage:
     *  o instantiate this class
     *  o call dolly() and rotate()
     *
     *  @constructor
     */
    XMOT.ExamineControllerBehavior = new XMOT.Class({

        /**
         *  @this {XMOT.ExamineControllerBehavior}
         *  @param {Element|Transformable} targetViewGroup
         *  @param {Object} options
         *
         *  options:
         *  o rotateSpeed, default 1
         *  o dollySpeed, default 40
         *  o examineOrigin, default scene's bounding box center
         */
        initialize: function(targetViewGroup, options) {

            this.target = XMOT.util.getOrCreateTransformable(targetViewGroup);

            /** @private */
            this._scene = XMOT.util.getXml3dRoot(this.target.object);

            /** @private */
            this._rotateSpeed = 1;

            /** @private */
            this._dollySpeed = 40;

            /** @private */
            this._currentAction = this.NONE;

            /** @private */
            this._sceneRadius = this._getSceneRadius();

            /** @private */
            this._examineOrigin = this._getExamineOriginFromScene();

            this._parseOptions(options);
        },

        /**
         *  @this {XMOT.ExamineControllerBehavior}
         */
        lookAt: function(newExamineOrigin) {

            var initCamDirection = new XML3DVec3(0, 0, -1);

            var curDirection = this.target.getOrientation().rotateVec3(initCamDirection);
            var newDirection = newExamineOrigin.subtract(this.target.getPosition());
            newDirection = newDirection.normalize();

            var rotationToNewOrigin = new XML3DRotation();
            rotationToNewOrigin.setRotation(curDirection, newDirection);

            this.target.rotate(rotationToNewOrigin);
            this._examineOrigin.set(newExamineOrigin);
        },

        /**
         *  @this {XMOT.ExamineControllerBehavior}
         */
        dolly: function(deltaX, deltaY) {

            var coef = 0.2 * this._sceneRadius;
            var dy = coef * this._dollySpeed * deltaY;

            var translVec = this._rotateVecToViewSpace(new window.XML3DVec3(0, 0, dy));
            this.target.translate(translVec);
        },

        /**
         *  @this {XMOT.ExamineControllerBehavior}
         *  @param {number} deltaXAngle delta value for rotation around the x-axis
         *  @param {number} deltaYAngle delta value for rotation around the y-axis
         */
        rotate: function(deltaXAngle, deltaYAngle) {
            var dx = -this._rotateSpeed * deltaXAngle * 2.0 * Math.PI;
            var dy = -this._rotateSpeed * deltaYAngle * 2.0 * Math.PI;

            var mx = new window.XML3DRotation(new window.XML3DVec3(1, 0, 0), dx);
            var my = new window.XML3DRotation(new window.XML3DVec3(0, 1, 0), dy);
            var result = mx.multiply(my);

            this._rotateAroundExamineOrigin(result);
        },

        /**
         *  @this {XMOT.ExamineControllerBehavior}
         */
        _rotateVecToViewSpace: function(vec) {
            return this.target.getOrientation().rotateVec3(vec);
        },

        /**
         *  @this {XMOT.ExamineControllerBehavior}
         */
        getRotateSpeed: function() {
            return this._rotateSpeed;
        },

        /**
         *  @this {XMOT.ExamineControllerBehavior}
         */
        getDollySpeed: function() {
            return this._dollySpeed;
        },

        /**
         *  @this {XMOT.ExamineControllerBehavior}
         */
        getSceneRadius: function() {
            return this._sceneRadius;
        },

        /**
         *  @this {XMOT.ExamineControllerBehavior}
         */
        getExamineOrigin: function() {
            return new window.XML3DVec3(this._examineOrigin);
        },

        /**
         *  @this {XMOT.ExamineControllerBehavior}
         *  @private
         */
        _parseOptions: function(options) {

            var options = options || {};
            if(options.rotateSpeed !== undefined)
                this._rotateSpeed = options.rotateSpeed;
            if(options.dollySpeed !== undefined)
                this._dollySpeed = options.dollySpeed;
            if(options.examineOrigin !== undefined)
                this._examineOrigin = options.examineOrigin;
        },

        /**
         *  @this {XMOT.ExamineControllerBehavior}
         *  @private
         */
        _rotateAroundExamineOrigin: function(rot) {
            this.target.rotate(rot);
            var q = new XML3DRotation(this._rotateVecToViewSpace(rot.axis), rot.angle);
            var trans = q.rotateVec3(this.target.getPosition().subtract(this._examineOrigin));
            var newPos = this._examineOrigin.add(trans);
            this.target.setPosition(newPos);
        },

        /**
         *  @this {XMOT.ExamineControllerBehavior}
         *  @private
         */
        _getSceneRadius: function() {
            var length = this._scene.getBoundingBox().size().length();
            return length * 0.5;
        },

        /**
         *  @this {XMOT.ExamineControllerBehavior}
         *  @private
         */
        _getExamineOriginFromScene: function() {

            var orig = new window.XML3DVec3();

            var bb = this._scene.getBoundingBox();
            if (!bb.isEmpty()) {
                orig.set(bb.center());
            }

            return orig;
        }
    });
}());
<|endoftext|>


<commit_before>/* eslint-disable unicorn/no-process-exit */

// Native
import fs from 'fs'
import path from 'path'

// Packages
import onDeath from 'death'
import fetch from 'node-fetch'

// Utilities
import plusxSync from './chmod'
import { disableProgress, enableProgress, info, showProgress, warn } from './log'

const now = path.join(__dirname, 'now')
const targetWin32 = path.join(__dirname, 'now.exe')
const target = process.platform === 'win32' ? targetWin32 : now
const partial = target + '.partial'

const packagePath = path.join(__dirname, '../../package.json')
const packageJSON = JSON.parse(fs.readFileSync(packagePath, 'utf8'))

const platformToName = {
  darwin: 'now-macos',
  linux: 'now-linux',
  win32: 'now-win.exe'
}

async function main() {
  try {
    fs.writeFileSync(
      now,
      '#!/usr/bin/env node\n' +
        'console.log("Please wait until the \'now\' installation completes!")\n'
    )
  } catch (err) {
    if (err.code === 'EACCES') {
      warn('Please try installing now CLI again with the `--unsafe-perm` option.')
      info('Example: `npm i -g --unsafe-perm now`')

      process.exit()
    }

    throw err
  }

  onDeath(() => {
    fs.writeFileSync(
      now,
      '#!/usr/bin/env node\n' +
        'console.log("The \'now\' installation did not complete successfully.")\n' +
        'console.log("Please run \'npm i -g now\' to reinstall!")\n'
    )
    process.exit()
  })

  info('For the source code, check out: https://github.com/zeit/now-cli')

  // Print an empty line
  console.log('')

  enableProgress('Downloading now CLI ' + packageJSON.version)
  showProgress(0)

  const name = platformToName[process.platform]
  const url = `https://github.com/zeit/now-cli/releases/download/${packageJSON.version}/${name}`
  const resp = await fetch(url)

  if (resp.status !== 200) {
    disableProgress()
    throw new Error(resp.statusText + ' ' + url)
  }

  const size = resp.headers.get('content-length')
  const ws = fs.createWriteStream(partial)

  await new Promise((resolve, reject) => {
    let bytesRead = 0

    resp.body.on('data', chunk => {
      bytesRead += chunk.length
      showProgress(100 * bytesRead / size)
    }).on('error', error => {
      disableProgress()
      reject(error)
    })

    resp.body.pipe(ws)

    ws.on('close', () => {
      showProgress(100)
      disableProgress()
      resolve()
    }).on('error', error => {
      disableProgress()
      reject(error)
    })
  })

  fs.renameSync(partial, target)

  if (process.platform === 'win32') {
    fs.writeFileSync(
      now,
      '#!/usr/bin/env node\n' +
        'var chip = require("child_process")\n' +
        'var args = process.argv.slice(2)\n' +
        'var opts = { stdio: "inherit" }\n' +
        'var r = chip.spawnSync(__dirname + "/now.exe", args, opts)\n' +
        'if (r.error) throw r.error\n' +
        'process.exit(r.status)\n'
    )
  } else {
    plusxSync(now)
  }
}

main().catch(err => {
  console.error(err)
  process.exit(2)
})
<commit_msg>Now fetching CLI downloads from our CDN<commit_after>/* eslint-disable unicorn/no-process-exit */

// Native
import fs from 'fs'
import path from 'path'
import zlib from 'zlib'

// Packages
import onDeath from 'death'
import fetch from 'node-fetch'

// Utilities
import plusxSync from './chmod'
import { disableProgress, enableProgress, info, showProgress, warn } from './log'

const now = path.join(__dirname, 'now')
const targetWin32 = path.join(__dirname, 'now.exe')
const target = process.platform === 'win32' ? targetWin32 : now
const partial = target + '.partial'

const packagePath = path.join(__dirname, '../../package.json')
const packageJSON = JSON.parse(fs.readFileSync(packagePath, 'utf8'))

const platformToName = {
  darwin: 'now-macos',
  linux: 'now-linux',
  win32: 'now-win.exe'
}

async function main() {
  try {
    fs.writeFileSync(
      now,
      '#!/usr/bin/env node\n' +
        'console.log("Please wait until the \'now\' installation completes!")\n'
    )
  } catch (err) {
    if (err.code === 'EACCES') {
      warn('Please try installing now CLI again with the `--unsafe-perm` option.')
      info('Example: `npm i -g --unsafe-perm now`')

      process.exit()
    }

    throw err
  }

  onDeath(() => {
    fs.writeFileSync(
      now,
      '#!/usr/bin/env node\n' +
        'console.log("The \'now\' installation did not complete successfully.")\n' +
        'console.log("Please run \'npm i -g now\' to reinstall!")\n'
    )
    process.exit()
  })

  info('For the source code, check out: https://github.com/zeit/now-cli')

  // Print an empty line
  console.log('')

  enableProgress('Downloading now CLI ' + packageJSON.version)
  showProgress(0)

  const name = platformToName[process.platform]
  const url = `http://cdn.zeit.co/releases/now-cli/${packageJSON.version}/${name}`
  const resp = await fetch(url, { compress: false })

  if (resp.status !== 200) {
    disableProgress()
    throw new Error(resp.statusText + ' ' + url)
  }

  const size = resp.headers.get('content-length')
  const ws = fs.createWriteStream(partial)

  await new Promise((resolve, reject) => {
    let bytesRead = 0

    resp.body.on('data', chunk => {
      bytesRead += chunk.length
      showProgress(100 * bytesRead / size)
    }).on('error', error => {
      disableProgress()
      reject(error)
    })

    const gunzip = zlib.createGunzip()
    resp.body.pipe(gunzip).pipe(ws)

    ws.on('close', () => {
      showProgress(100)
      disableProgress()
      resolve()
    }).on('error', error => {
      disableProgress()
      reject(error)
    })
  })

  fs.renameSync(partial, target)

  if (process.platform === 'win32') {
    fs.writeFileSync(
      now,
      '#!/usr/bin/env node\n' +
        'var chip = require("child_process")\n' +
        'var args = process.argv.slice(2)\n' +
        'var opts = { stdio: "inherit" }\n' +
        'var r = chip.spawnSync(__dirname + "/now.exe", args, opts)\n' +
        'if (r.error) throw r.error\n' +
        'process.exit(r.status)\n'
    )
  } else {
    plusxSync(now)
  }
}

main().catch(err => {
  console.error(err)
  process.exit(2)
})
<|endoftext|>


<commit_before>const router = require("koa-router")();
const {get} = require("lodash/fp");
const moment = require("moment");
const url = require("url");

const {fmiRequest, fmiRawRequest} = require("./utils");

// Get the paths with https://chrome.google.com/webstore/detail/jsonview/chklaanhfefbnpoihckbnefhakgolnmc?hl=en

const getFeatures = get("wfs:FeatureCollection.wfs:member");

const getFeatureId = get(
    "omso:PointTimeSeriesObservation[0].om:featureOfInterest[0].sams:SF_SpatialSamplingFeature[0].$.gml:id"
);
const getFeatureStationName = get(
    "omso:PointTimeSeriesObservation[0].om:featureOfInterest[0].sams:SF_SpatialSamplingFeature[0].sams:shape[0].gml:Point[0].gml:name[0]"
);
const getFeatureStationCoordinates = get(
    "omso:PointTimeSeriesObservation[0].om:featureOfInterest[0].sams:SF_SpatialSamplingFeature[0].sams:shape[0].gml:Point[0].gml:pos[0]"
);

const getFeatureDescriptionHref = get(
    "omso:PointTimeSeriesObservation[0].om:observedProperty[0].$.xlink:href"
);

const getPoints = get(
    "omso:PointTimeSeriesObservation[0].om:result[0].wml2:MeasurementTimeseries[0].wml2:point"
);

const getTime = get("wml2:MeasurementTVP[0].wml2:time[0]");
const getValue = get("wml2:MeasurementTVP[0].wml2:value[0]");

const getDescription = get("ObservableProperty.label[0]");

const getForecastLocationName = get(
    "omso:PointTimeSeriesObservation[0].om:featureOfInterest[0].sams:SF_SpatialSamplingFeature[0].sams:shape[0].gml:MultiPoint[0].gml:pointMembers[0].gml:Point[0].gml:name[0]"
);
const getForecastLocationCoordinates = get(
    "omso:PointTimeSeriesObservation[0].om:featureOfInterest[0].sams:SF_SpatialSamplingFeature[0].sams:shape[0].gml:MultiPoint[0].gml:pointMembers[0].gml:Point[0].gml:pos[0]"
);

const OBSERVATION_PARAMETERS = [
    "winddirection",
    "windspeedms",
    "windgust",
    "n_man",
];
router.get("/api/observations/:fmisid", async ctx => {
    const data = await fmiRequest({
        apikey: ctx.state.fmiApikey,
        query: "fmi::observations::weather::timevaluepair",
        cacheKey: "observations:" + ctx.params.fmisid,
        params: {
            starttime: moment().subtract(1, "days").toISOString(),
            endtime: moment().toISOString(),
            parameters: OBSERVATION_PARAMETERS,
            fmisid: ctx.params.fmisid,
        },
    });

    const featuresWithDescriptions = await Promise.all(
        getFeatures(data).map(async feature => {
            const featureDescriptionHref = getFeatureDescriptionHref(feature);
            const descriptionData = await fmiRawRequest(
                featureDescriptionHref,
                {
                    cacheKey: featureDescriptionHref,
                }
            );

            return {
                id: getFeatureId(feature),
                description: getDescription(descriptionData),
                featureDescriptionHref,
                stationName: getFeatureStationName(feature),
                stationCoordinates: getFeatureStationCoordinates(feature),
                googleMaps: url.resolve(
                    "https://www.google.fi/maps/place/",
                    getFeatureStationCoordinates(feature)
                ),
            };
        })
    );

    ctx.body = {
        fmisid: ctx.params.fmisid,
        stationsURL: "http://ilmatieteenlaitos.fi/havaintoasemat",
        features: featuresWithDescriptions,
    };
});

router.get("/api/observations/:fmisid/:feature", async ctx => {
    const data = await fmiRequest({
        apikey: ctx.state.fmiApikey,
        query: "fmi::observations::weather::timevaluepair",
        cacheKey: "observations:" + ctx.params.fmisid,
        params: {
            starttime: moment().subtract(1, "days").toISOString(),
            endtime: moment().toISOString(),
            parameters: OBSERVATION_PARAMETERS,
            fmisid: ctx.params.fmisid,
        },
    });

    const features = getFeatures(data);
    if (!features) {
        ctx.body = {error: "No data for fmisid: " + ctx.params.fmisid};
        return;
    }

    const feature = features.filter(feature => {
        return getFeatureId(feature) === ctx.params.feature;
    })[0];

    if (!feature) {
        ctx.body = {
            stationName: getFeatureStationName(feature),
            stationCoordinates: getFeatureStationCoordinates(feature),
            error: "No data for feature: " + ctx.params.feature,
            features: features,
        };
        return;
    }

    ctx.body = {
        stationName: getFeatureStationName(feature),
        stationCoordinates: getFeatureStationCoordinates(feature),
        points: getPoints(feature).map(point => ({
            time: getTime(point),
            value: getValue(point),
        })),
    };
});

const FORECAST_PAREMETERS = [
    "winddirection",
    "windspeedms",
    "windgust",
    "maximumwind",
];

router.get("/api/forecasts/:latlon", async ctx => {
    const data = await fmiRequest({
        apikey: ctx.state.fmiApikey,
        query: "fmi::forecast::hirlam::surface::point::timevaluepair",
        cacheKey: "forecasts:" + ctx.params.latlon,
        params: {
            parameters: FORECAST_PAREMETERS,
            latlon: ctx.params.latlon,
        },
    });

    ctx.body = {
        features: getFeatures(data).map(feature => ({
            id: getFeatureId(feature),
            locationName: getForecastLocationName(feature),
            locationCoordinates: getForecastLocationCoordinates(feature),
        })),
    };
});

router.get("/api/forecasts/:latlon/:feature", async ctx => {
    const data = await fmiRequest({
        apikey: ctx.state.fmiApikey,
        query: "fmi::forecast::hirlam::surface::point::timevaluepair",
        cacheKey: "forecasts:" + ctx.params.latlon,
        params: {
            parameters: FORECAST_PAREMETERS,
            latlon: ctx.params.latlon,
        },
    });

    const features = getFeatures(data);
    if (!features) {
        ctx.body = {error: "No data for fmisid: " + ctx.params.fmisid};
        return;
    }

    const feature = features.filter(feature => {
        return getFeatureId(feature) === ctx.params.feature;
    })[0];

    if (!feature) {
        ctx.body = {
            error: "No data for feature: " + ctx.params.feature,
            features: features,
        };
        return;
    }

    ctx.body = {
        locationName: getForecastLocationName(feature),
        locationCoordinates: getForecastLocationCoordinates(feature),
        points: getPoints(feature).map(point => ({
            time: getTime(point),
            value: getValue(point),
        })),
    };
});

module.exports = router;
<commit_msg>Hide featureDescriptionHref<commit_after>const router = require("koa-router")();
const {get} = require("lodash/fp");
const moment = require("moment");
const url = require("url");

const {fmiRequest, fmiRawRequest} = require("./utils");

// Get the paths with https://chrome.google.com/webstore/detail/jsonview/chklaanhfefbnpoihckbnefhakgolnmc?hl=en

const getFeatures = get("wfs:FeatureCollection.wfs:member");

const getFeatureId = get(
    "omso:PointTimeSeriesObservation[0].om:featureOfInterest[0].sams:SF_SpatialSamplingFeature[0].$.gml:id"
);
const getFeatureStationName = get(
    "omso:PointTimeSeriesObservation[0].om:featureOfInterest[0].sams:SF_SpatialSamplingFeature[0].sams:shape[0].gml:Point[0].gml:name[0]"
);
const getFeatureStationCoordinates = get(
    "omso:PointTimeSeriesObservation[0].om:featureOfInterest[0].sams:SF_SpatialSamplingFeature[0].sams:shape[0].gml:Point[0].gml:pos[0]"
);

const getFeatureDescriptionHref = get(
    "omso:PointTimeSeriesObservation[0].om:observedProperty[0].$.xlink:href"
);

const getPoints = get(
    "omso:PointTimeSeriesObservation[0].om:result[0].wml2:MeasurementTimeseries[0].wml2:point"
);

const getTime = get("wml2:MeasurementTVP[0].wml2:time[0]");
const getValue = get("wml2:MeasurementTVP[0].wml2:value[0]");

const getDescription = get("ObservableProperty.label[0]");

const getForecastLocationName = get(
    "omso:PointTimeSeriesObservation[0].om:featureOfInterest[0].sams:SF_SpatialSamplingFeature[0].sams:shape[0].gml:MultiPoint[0].gml:pointMembers[0].gml:Point[0].gml:name[0]"
);
const getForecastLocationCoordinates = get(
    "omso:PointTimeSeriesObservation[0].om:featureOfInterest[0].sams:SF_SpatialSamplingFeature[0].sams:shape[0].gml:MultiPoint[0].gml:pointMembers[0].gml:Point[0].gml:pos[0]"
);

const OBSERVATION_PARAMETERS = [
    "winddirection",
    "windspeedms",
    "windgust",
    "n_man",
];
router.get("/api/observations/:fmisid", async ctx => {
    const data = await fmiRequest({
        apikey: ctx.state.fmiApikey,
        query: "fmi::observations::weather::timevaluepair",
        cacheKey: "observations:" + ctx.params.fmisid,
        params: {
            starttime: moment().subtract(1, "days").toISOString(),
            endtime: moment().toISOString(),
            parameters: OBSERVATION_PARAMETERS,
            fmisid: ctx.params.fmisid,
        },
    });

    const featuresWithDescriptions = await Promise.all(
        getFeatures(data).map(async feature => {
            const featureDescriptionHref = getFeatureDescriptionHref(feature);
            const descriptionData = await fmiRawRequest(
                featureDescriptionHref,
                {
                    cacheKey: featureDescriptionHref,
                }
            );

            return {
                id: getFeatureId(feature),
                description: getDescription(descriptionData),
                stationName: getFeatureStationName(feature),
                stationCoordinates: getFeatureStationCoordinates(feature),
                googleMaps: url.resolve(
                    "https://www.google.fi/maps/place/",
                    getFeatureStationCoordinates(feature)
                ),
            };
        })
    );

    ctx.body = {
        fmisid: ctx.params.fmisid,
        stationsURL: "http://ilmatieteenlaitos.fi/havaintoasemat",
        features: featuresWithDescriptions,
    };
});

router.get("/api/observations/:fmisid/:feature", async ctx => {
    const data = await fmiRequest({
        apikey: ctx.state.fmiApikey,
        query: "fmi::observations::weather::timevaluepair",
        cacheKey: "observations:" + ctx.params.fmisid,
        params: {
            starttime: moment().subtract(1, "days").toISOString(),
            endtime: moment().toISOString(),
            parameters: OBSERVATION_PARAMETERS,
            fmisid: ctx.params.fmisid,
        },
    });

    const features = getFeatures(data);
    if (!features) {
        ctx.body = {error: "No data for fmisid: " + ctx.params.fmisid};
        return;
    }

    const feature = features.filter(feature => {
        return getFeatureId(feature) === ctx.params.feature;
    })[0];

    if (!feature) {
        ctx.body = {
            stationName: getFeatureStationName(feature),
            stationCoordinates: getFeatureStationCoordinates(feature),
            error: "No data for feature: " + ctx.params.feature,
            features: features,
        };
        return;
    }

    ctx.body = {
        stationName: getFeatureStationName(feature),
        stationCoordinates: getFeatureStationCoordinates(feature),
        points: getPoints(feature).map(point => ({
            time: getTime(point),
            value: getValue(point),
        })),
    };
});

const FORECAST_PAREMETERS = [
    "winddirection",
    "windspeedms",
    "windgust",
    "maximumwind",
];

router.get("/api/forecasts/:latlon", async ctx => {
    const data = await fmiRequest({
        apikey: ctx.state.fmiApikey,
        query: "fmi::forecast::hirlam::surface::point::timevaluepair",
        cacheKey: "forecasts:" + ctx.params.latlon,
        params: {
            parameters: FORECAST_PAREMETERS,
            latlon: ctx.params.latlon,
        },
    });

    ctx.body = {
        features: getFeatures(data).map(feature => ({
            id: getFeatureId(feature),
            locationName: getForecastLocationName(feature),
            locationCoordinates: getForecastLocationCoordinates(feature),
        })),
    };
});

router.get("/api/forecasts/:latlon/:feature", async ctx => {
    const data = await fmiRequest({
        apikey: ctx.state.fmiApikey,
        query: "fmi::forecast::hirlam::surface::point::timevaluepair",
        cacheKey: "forecasts:" + ctx.params.latlon,
        params: {
            parameters: FORECAST_PAREMETERS,
            latlon: ctx.params.latlon,
        },
    });

    const features = getFeatures(data);
    if (!features) {
        ctx.body = {error: "No data for fmisid: " + ctx.params.fmisid};
        return;
    }

    const feature = features.filter(feature => {
        return getFeatureId(feature) === ctx.params.feature;
    })[0];

    if (!feature) {
        ctx.body = {
            error: "No data for feature: " + ctx.params.feature,
            features: features,
        };
        return;
    }

    ctx.body = {
        locationName: getForecastLocationName(feature),
        locationCoordinates: getForecastLocationCoordinates(feature),
        points: getPoints(feature).map(point => ({
            time: getTime(point),
            value: getValue(point),
        })),
    };
});

module.exports = router;
<|endoftext|>


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

	"use strict";

	/**
	 *  @class A Timeline class for scheduling and maintaining state
	 *         along a timeline. All events must have a "time" property.
	 *         Internally, events are stored in time order for fast
	 *         retrieval.
	 *  @extends {Tone}
	 *  @param {Positive} [memory=Infinity] The number of previous events that are retained.
	 */
	Tone.Timeline = function(){

		var options = Tone.defaults(arguments, ["memory"], Tone.Timeline);
		Tone.call(this);

		/**
		 *  The array of scheduled timeline events
		 *  @type  {Array}
		 *  @private
		 */
		this._timeline = [];

		/**
		 *  An array of items to remove from the list.
		 *  @type {Array}
		 *  @private
		 */
		this._toRemove = [];

		/**
		 *  Flag if the timeline is mid iteration
		 *  @private
		 *  @type {Boolean}
		 */
		this._iterating = false;

		/**
		 *  The memory of the timeline, i.e.
		 *  how many events in the past it will retain
		 *  @type {Positive}
		 */
		this.memory = options.memory;
	};

	Tone.extend(Tone.Timeline);

	/**
	 *  the default parameters
	 *  @static
	 *  @const
	 */
	Tone.Timeline.defaults = {
		"memory" : Infinity
	};

	/**
	 *  The number of items in the timeline.
	 *  @type {Number}
	 *  @memberOf Tone.Timeline#
	 *  @name length
	 *  @readOnly
	 */
	Object.defineProperty(Tone.Timeline.prototype, "length", {
		get : function(){
			return this._timeline.length;
		}
	});

	/**
	 *  Insert an event object onto the timeline. Events must have a "time" attribute.
	 *  @param  {Object}  event  The event object to insert into the
	 *                           timeline.
	 *  @returns {Tone.Timeline} this
	 */
	Tone.Timeline.prototype.add = function(event){
		//the event needs to have a time attribute
		if (Tone.isUndef(event.time)){
			throw new Error("Tone.Timeline: events must have a time attribute");
		}
		if (this._timeline.length){
			var index = this._search(event.time);
			this._timeline.splice(index + 1, 0, event);
		} else {
			this._timeline.push(event);
		}
		//if the length is more than the memory, remove the previous ones
		if (this.length > this.memory){
			var diff = this.length - this.memory;
			this._timeline.splice(0, diff);
		}
		return this;
	};

	/**
	 *  Remove an event from the timeline.
	 *  @param  {Object}  event  The event object to remove from the list.
	 *  @returns {Tone.Timeline} this
	 */
	Tone.Timeline.prototype.remove = function(event){
		if (this._iterating){
			this._toRemove.push(event);
		} else {
			var index = this._timeline.indexOf(event);
			if (index !== -1){
				this._timeline.splice(index, 1);
			}
		}
		return this;
	};

	/**
	 *  Get the nearest event whose time is less than or equal to the given time.
	 *  @param  {Number}  time  The time to query.
	 *  @returns {Object} The event object set after that time.
	 */
	Tone.Timeline.prototype.get = function(time){
		var index = this._search(time);
		if (index !== -1){
			return this._timeline[index];
		} else {
			return null;
		}
	};

	/**
	 *  Return the first event in the timeline without removing it
	 *  @returns {Object} The first event object
	 */
	Tone.Timeline.prototype.peek = function(){
		return this._timeline[0];
	};

	/**
	 *  Return the first event in the timeline and remove it
	 *  @returns {Object} The first event object
	 */
	Tone.Timeline.prototype.shift = function(){
		return this._timeline.shift();
	};

	/**
	 *  Get the event which is scheduled after the given time.
	 *  @param  {Number}  time  The time to query.
	 *  @returns {Object} The event object after the given time
	 */
	Tone.Timeline.prototype.getAfter = function(time){
		var index = this._search(time);
		if (index + 1 < this._timeline.length){
			return this._timeline[index + 1];
		} else {
			return null;
		}
	};

	/**
	 *  Get the event before the event at the given time.
	 *  @param  {Number}  time  The time to query.
	 *  @returns {Object} The event object before the given time
	 */
	Tone.Timeline.prototype.getBefore = function(time){
		var len = this._timeline.length;
		//if it's after the last item, return the last item
		if (len > 0 && this._timeline[len - 1].time < time){
			return this._timeline[len - 1];
		}
		var index = this._search(time);
		if (index - 1 >= 0){
			return this._timeline[index - 1];
		} else {
			return null;
		}
	};

	/**
	 *  Cancel events after the given time
	 *  @param  {Number}  time  The time to query.
	 *  @returns {Tone.Timeline} this
	 */
	Tone.Timeline.prototype.cancel = function(after){
		if (this._timeline.length > 1){
			var index = this._search(after);
			if (index >= 0){
				if (this._timeline[index].time === after){
					//get the first item with that time
					for (var i = index; i >= 0; i--){
						if (this._timeline[i].time === after){
							index = i;
						} else {
							break;
						}
					}
					this._timeline = this._timeline.slice(0, index);
				} else {
					this._timeline = this._timeline.slice(0, index + 1);
				}
			} else {
				this._timeline = [];
			}
		} else if (this._timeline.length === 1){
			//the first item's time
			if (this._timeline[0].time >= after){
				this._timeline = [];
			}
		}
		return this;
	};

	/**
	 *  Cancel events before or equal to the given time.
	 *  @param  {Number}  time  The time to cancel before.
	 *  @returns {Tone.Timeline} this
	 */
	Tone.Timeline.prototype.cancelBefore = function(time){
		if (this._timeline.length){
			var index = this._search(time);
			if (index >= 0){
				this._timeline = this._timeline.slice(index + 1);
			}
		}
		return this;
	};

	/**
	 *  Does a binary serach on the timeline array and returns the
	 *  nearest event index whose time is after or equal to the given time.
	 *  If a time is searched before the first index in the timeline, -1 is returned.
	 *  If the time is after the end, the index of the last item is returned.
	 *  @param  {Number}  time
	 *  @return  {Number} the index in the timeline array
	 *  @private
	 */
	Tone.Timeline.prototype._search = function(time){
		var beginning = 0;
		var len = this._timeline.length;
		var end = len;
		if (len > 0 && this._timeline[len - 1].time <= time){
			return len - 1;
		}
		while (beginning < end){
			// calculate the midpoint for roughly equal partition
			var midPoint = Math.floor(beginning + (end - beginning) / 2);
			var event = this._timeline[midPoint];
			var nextEvent = this._timeline[midPoint + 1];
			if (event.time === time){
				//choose the last one that has the same time
				for (var i = midPoint; i < this._timeline.length; i++){
					var testEvent = this._timeline[i];
					if (testEvent.time === time){
						midPoint = i;
					}
				}
				return midPoint;
			} else if (event.time < time && nextEvent.time > time){
				return midPoint;
			} else if (event.time > time){
				//search lower
				end = midPoint;
			} else if (event.time < time){
				//search upper
				beginning = midPoint + 1;
			}
		}
		return -1;
	};

	/**
	 *  Internal iterator. Applies extra safety checks for
	 *  removing items from the array.
	 *  @param  {Function}  callback
	 *  @param  {Number=}    lowerBound
	 *  @param  {Number=}    upperBound
	 *  @private
	 */
	Tone.Timeline.prototype._iterate = function(callback, lowerBound, upperBound){
		this._iterating = true;
		lowerBound = Tone.defaultArg(lowerBound, 0);
		upperBound = Tone.defaultArg(upperBound, this._timeline.length - 1);
		for (var i = lowerBound; i <= upperBound; i++){
			callback.call(this, this._timeline[i]);
		}
		this._iterating = false;
		if (this._toRemove.length > 0){
			for (var j = 0; j < this._toRemove.length; j++){
				var index = this._timeline.indexOf(this._toRemove[j]);
				if (index !== -1){
					this._timeline.splice(index, 1);
				}
			}
			this._toRemove = [];
		}
	};

	/**
	 *  Iterate over everything in the array
	 *  @param  {Function}  callback The callback to invoke with every item
	 *  @returns {Tone.Timeline} this
	 */
	Tone.Timeline.prototype.forEach = function(callback){
		this._iterate(callback);
		return this;
	};

	/**
	 *  Iterate over everything in the array at or before the given time.
	 *  @param  {Number}  time The time to check if items are before
	 *  @param  {Function}  callback The callback to invoke with every item
	 *  @returns {Tone.Timeline} this
	 */
	Tone.Timeline.prototype.forEachBefore = function(time, callback){
		//iterate over the items in reverse so that removing an item doesn't break things
		var upperBound = this._search(time);
		if (upperBound !== -1){
			this._iterate(callback, 0, upperBound);
		}
		return this;
	};

	/**
	 *  Iterate over everything in the array after the given time.
	 *  @param  {Number}  time The time to check if items are before
	 *  @param  {Function}  callback The callback to invoke with every item
	 *  @returns {Tone.Timeline} this
	 */
	Tone.Timeline.prototype.forEachAfter = function(time, callback){
		//iterate over the items in reverse so that removing an item doesn't break things
		var lowerBound = this._search(time);
		this._iterate(callback, lowerBound + 1);
		return this;
	};

	/**
	 *  Iterate over everything in the array at or after the given time. Similar to
	 *  forEachAfter, but includes the item(s) at the given time.
	 *  @param  {Number}  time The time to check if items are before
	 *  @param  {Function}  callback The callback to invoke with every item
	 *  @returns {Tone.Timeline} this
	 */
	Tone.Timeline.prototype.forEachFrom = function(time, callback){
		//iterate over the items in reverse so that removing an item doesn't break things
		var lowerBound = this._search(time);
		//work backwards until the event time is less than time
		while (lowerBound >= 0 && this._timeline[lowerBound].time >= time){
			lowerBound--;
		}
		this._iterate(callback, lowerBound + 1);
		return this;
	};

	/**
	 *  Iterate over everything in the array at the given time
	 *  @param  {Number}  time The time to check if items are before
	 *  @param  {Function}  callback The callback to invoke with every item
	 *  @returns {Tone.Timeline} this
	 */
	Tone.Timeline.prototype.forEachAtTime = function(time, callback){
		//iterate over the items in reverse so that removing an item doesn't break things
		var upperBound = this._search(time);
		if (upperBound !== -1){
			this._iterate(function(event){
				if (event.time === time){
					callback.call(this, event);
				}
			}, 0, upperBound);
		}
		return this;
	};

	/**
	 *  Clean up.
	 *  @return  {Tone.Timeline}  this
	 */
	Tone.Timeline.prototype.dispose = function(){
		Tone.prototype.dispose.call(this);
		this._timeline = null;
		this._toRemove = null;
		return this;
	};

	return Tone.Timeline;
});<commit_msg>removing unnecessary conditional<commit_after>define(["Tone/core/Tone"], function (Tone) {

	"use strict";

	/**
	 *  @class A Timeline class for scheduling and maintaining state
	 *         along a timeline. All events must have a "time" property.
	 *         Internally, events are stored in time order for fast
	 *         retrieval.
	 *  @extends {Tone}
	 *  @param {Positive} [memory=Infinity] The number of previous events that are retained.
	 */
	Tone.Timeline = function(){

		var options = Tone.defaults(arguments, ["memory"], Tone.Timeline);
		Tone.call(this);

		/**
		 *  The array of scheduled timeline events
		 *  @type  {Array}
		 *  @private
		 */
		this._timeline = [];

		/**
		 *  An array of items to remove from the list.
		 *  @type {Array}
		 *  @private
		 */
		this._toRemove = [];

		/**
		 *  Flag if the timeline is mid iteration
		 *  @private
		 *  @type {Boolean}
		 */
		this._iterating = false;

		/**
		 *  The memory of the timeline, i.e.
		 *  how many events in the past it will retain
		 *  @type {Positive}
		 */
		this.memory = options.memory;
	};

	Tone.extend(Tone.Timeline);

	/**
	 *  the default parameters
	 *  @static
	 *  @const
	 */
	Tone.Timeline.defaults = {
		"memory" : Infinity
	};

	/**
	 *  The number of items in the timeline.
	 *  @type {Number}
	 *  @memberOf Tone.Timeline#
	 *  @name length
	 *  @readOnly
	 */
	Object.defineProperty(Tone.Timeline.prototype, "length", {
		get : function(){
			return this._timeline.length;
		}
	});

	/**
	 *  Insert an event object onto the timeline. Events must have a "time" attribute.
	 *  @param  {Object}  event  The event object to insert into the
	 *                           timeline.
	 *  @returns {Tone.Timeline} this
	 */
	Tone.Timeline.prototype.add = function(event){
		//the event needs to have a time attribute
		if (Tone.isUndef(event.time)){
			throw new Error("Tone.Timeline: events must have a time attribute");
		}
		if (this._timeline.length){
			var index = this._search(event.time);
			this._timeline.splice(index + 1, 0, event);
		} else {
			this._timeline.push(event);
		}
		//if the length is more than the memory, remove the previous ones
		if (this.length > this.memory){
			var diff = this.length - this.memory;
			this._timeline.splice(0, diff);
		}
		return this;
	};

	/**
	 *  Remove an event from the timeline.
	 *  @param  {Object}  event  The event object to remove from the list.
	 *  @returns {Tone.Timeline} this
	 */
	Tone.Timeline.prototype.remove = function(event){
		if (this._iterating){
			this._toRemove.push(event);
		} else {
			var index = this._timeline.indexOf(event);
			if (index !== -1){
				this._timeline.splice(index, 1);
			}
		}
		return this;
	};

	/**
	 *  Get the nearest event whose time is less than or equal to the given time.
	 *  @param  {Number}  time  The time to query.
	 *  @returns {Object} The event object set after that time.
	 */
	Tone.Timeline.prototype.get = function(time){
		var index = this._search(time);
		if (index !== -1){
			return this._timeline[index];
		} else {
			return null;
		}
	};

	/**
	 *  Return the first event in the timeline without removing it
	 *  @returns {Object} The first event object
	 */
	Tone.Timeline.prototype.peek = function(){
		return this._timeline[0];
	};

	/**
	 *  Return the first event in the timeline and remove it
	 *  @returns {Object} The first event object
	 */
	Tone.Timeline.prototype.shift = function(){
		return this._timeline.shift();
	};

	/**
	 *  Get the event which is scheduled after the given time.
	 *  @param  {Number}  time  The time to query.
	 *  @returns {Object} The event object after the given time
	 */
	Tone.Timeline.prototype.getAfter = function(time){
		var index = this._search(time);
		if (index + 1 < this._timeline.length){
			return this._timeline[index + 1];
		} else {
			return null;
		}
	};

	/**
	 *  Get the event before the event at the given time.
	 *  @param  {Number}  time  The time to query.
	 *  @returns {Object} The event object before the given time
	 */
	Tone.Timeline.prototype.getBefore = function(time){
		var len = this._timeline.length;
		//if it's after the last item, return the last item
		if (len > 0 && this._timeline[len - 1].time < time){
			return this._timeline[len - 1];
		}
		var index = this._search(time);
		if (index - 1 >= 0){
			return this._timeline[index - 1];
		} else {
			return null;
		}
	};

	/**
	 *  Cancel events after the given time
	 *  @param  {Number}  time  The time to query.
	 *  @returns {Tone.Timeline} this
	 */
	Tone.Timeline.prototype.cancel = function(after){
		if (this._timeline.length > 1){
			var index = this._search(after);
			if (index >= 0){
				if (this._timeline[index].time === after){
					//get the first item with that time
					for (var i = index; i >= 0; i--){
						if (this._timeline[i].time === after){
							index = i;
						} else {
							break;
						}
					}
					this._timeline = this._timeline.slice(0, index);
				} else {
					this._timeline = this._timeline.slice(0, index + 1);
				}
			} else {
				this._timeline = [];
			}
		} else if (this._timeline.length === 1){
			//the first item's time
			if (this._timeline[0].time >= after){
				this._timeline = [];
			}
		}
		return this;
	};

	/**
	 *  Cancel events before or equal to the given time.
	 *  @param  {Number}  time  The time to cancel before.
	 *  @returns {Tone.Timeline} this
	 */
	Tone.Timeline.prototype.cancelBefore = function(time){
		if (this._timeline.length){
			var index = this._search(time);
			if (index >= 0){
				this._timeline = this._timeline.slice(index + 1);
			}
		}
		return this;
	};

	/**
	 *  Does a binary serach on the timeline array and returns the
	 *  nearest event index whose time is after or equal to the given time.
	 *  If a time is searched before the first index in the timeline, -1 is returned.
	 *  If the time is after the end, the index of the last item is returned.
	 *  @param  {Number}  time
	 *  @return  {Number} the index in the timeline array
	 *  @private
	 */
	Tone.Timeline.prototype._search = function(time){
		var beginning = 0;
		var len = this._timeline.length;
		var end = len;
		if (len > 0 && this._timeline[len - 1].time <= time){
			return len - 1;
		}
		while (beginning < end){
			// calculate the midpoint for roughly equal partition
			var midPoint = Math.floor(beginning + (end - beginning) / 2);
			var event = this._timeline[midPoint];
			var nextEvent = this._timeline[midPoint + 1];
			if (event.time === time){
				//choose the last one that has the same time
				for (var i = midPoint; i < this._timeline.length; i++){
					var testEvent = this._timeline[i];
					if (testEvent.time === time){
						midPoint = i;
					}
				}
				return midPoint;
			} else if (event.time < time && nextEvent.time > time){
				return midPoint;
			} else if (event.time > time){
				//search lower
				end = midPoint;
			} else {
				//search upper
				beginning = midPoint + 1;
			}
		}
		return -1;
	};

	/**
	 *  Internal iterator. Applies extra safety checks for
	 *  removing items from the array.
	 *  @param  {Function}  callback
	 *  @param  {Number=}    lowerBound
	 *  @param  {Number=}    upperBound
	 *  @private
	 */
	Tone.Timeline.prototype._iterate = function(callback, lowerBound, upperBound){
		this._iterating = true;
		lowerBound = Tone.defaultArg(lowerBound, 0);
		upperBound = Tone.defaultArg(upperBound, this._timeline.length - 1);
		for (var i = lowerBound; i <= upperBound; i++){
			callback.call(this, this._timeline[i]);
		}
		this._iterating = false;
		if (this._toRemove.length > 0){
			for (var j = 0; j < this._toRemove.length; j++){
				var index = this._timeline.indexOf(this._toRemove[j]);
				if (index !== -1){
					this._timeline.splice(index, 1);
				}
			}
			this._toRemove = [];
		}
	};

	/**
	 *  Iterate over everything in the array
	 *  @param  {Function}  callback The callback to invoke with every item
	 *  @returns {Tone.Timeline} this
	 */
	Tone.Timeline.prototype.forEach = function(callback){
		this._iterate(callback);
		return this;
	};

	/**
	 *  Iterate over everything in the array at or before the given time.
	 *  @param  {Number}  time The time to check if items are before
	 *  @param  {Function}  callback The callback to invoke with every item
	 *  @returns {Tone.Timeline} this
	 */
	Tone.Timeline.prototype.forEachBefore = function(time, callback){
		//iterate over the items in reverse so that removing an item doesn't break things
		var upperBound = this._search(time);
		if (upperBound !== -1){
			this._iterate(callback, 0, upperBound);
		}
		return this;
	};

	/**
	 *  Iterate over everything in the array after the given time.
	 *  @param  {Number}  time The time to check if items are before
	 *  @param  {Function}  callback The callback to invoke with every item
	 *  @returns {Tone.Timeline} this
	 */
	Tone.Timeline.prototype.forEachAfter = function(time, callback){
		//iterate over the items in reverse so that removing an item doesn't break things
		var lowerBound = this._search(time);
		this._iterate(callback, lowerBound + 1);
		return this;
	};

	/**
	 *  Iterate over everything in the array at or after the given time. Similar to
	 *  forEachAfter, but includes the item(s) at the given time.
	 *  @param  {Number}  time The time to check if items are before
	 *  @param  {Function}  callback The callback to invoke with every item
	 *  @returns {Tone.Timeline} this
	 */
	Tone.Timeline.prototype.forEachFrom = function(time, callback){
		//iterate over the items in reverse so that removing an item doesn't break things
		var lowerBound = this._search(time);
		//work backwards until the event time is less than time
		while (lowerBound >= 0 && this._timeline[lowerBound].time >= time){
			lowerBound--;
		}
		this._iterate(callback, lowerBound + 1);
		return this;
	};

	/**
	 *  Iterate over everything in the array at the given time
	 *  @param  {Number}  time The time to check if items are before
	 *  @param  {Function}  callback The callback to invoke with every item
	 *  @returns {Tone.Timeline} this
	 */
	Tone.Timeline.prototype.forEachAtTime = function(time, callback){
		//iterate over the items in reverse so that removing an item doesn't break things
		var upperBound = this._search(time);
		if (upperBound !== -1){
			this._iterate(function(event){
				if (event.time === time){
					callback.call(this, event);
				}
			}, 0, upperBound);
		}
		return this;
	};

	/**
	 *  Clean up.
	 *  @return  {Tone.Timeline}  this
	 */
	Tone.Timeline.prototype.dispose = function(){
		Tone.prototype.dispose.call(this);
		this._timeline = null;
		this._toRemove = null;
		return this;
	};

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


<commit_before>/*!
 * Script to build our plugins to use them separately.
 * Copyright 2019 The Bootstrap Authors
 * Copyright 2019 Twitter, Inc.
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 */

'use strict'

const path    = require('path')
const rollup  = require('rollup')
const babel   = require('rollup-plugin-babel')
const banner  = require('./banner.js')

const TEST    = process.env.NODE_ENV === 'test'
const plugins = [
  babel({
    exclude: 'node_modules/**', // Only transpile our source code
    externalHelpersWhitelist: [ // Include only required helpers
      'defineProperties',
      'createClass',
      'inheritsLoose',
      'defineProperty',
      'objectSpread'
    ]
  })
]
const bsPlugins = {
  Alert: path.resolve(__dirname, '../js/src/alert.js'),
  Button: path.resolve(__dirname, '../js/src/button.js'),
  Carousel: path.resolve(__dirname, '../js/src/carousel.js'),
  Collapse: path.resolve(__dirname, '../js/src/collapse.js'),
  Dropdown: path.resolve(__dirname, '../js/src/dropdown.js'),
  Modal: path.resolve(__dirname, '../js/src/modal.js'),
  Popover: path.resolve(__dirname, '../js/src/popover.js'),
  ScrollSpy: path.resolve(__dirname, '../js/src/scrollspy.js'),
  Tab: path.resolve(__dirname, '../js/src/tab.js'),
  Toast: path.resolve(__dirname, '../js/src/toast.js'),
  Tooltip: path.resolve(__dirname, '../js/src/tooltip.js'),
  Util: path.resolve(__dirname, '../js/src/util.js')
}
const rootPath = TEST ? '../js/coverage/dist/' : '../js/dist/'

function build(plugin) {
  console.log(`Building ${plugin} plugin...`)

  const external = ['jquery', 'popper.js']
  const globals = {
    jquery: 'jQuery', // Ensure we use jQuery which is always available even in noConflict mode
    'popper.js': 'Popper'
  }

  // Do not bundle Util in plugins
  if (plugin !== 'Util') {
    external.push(bsPlugins.Util)
    globals[bsPlugins.Util] = 'Util'
  }

  // Do not bundle Tooltip in Popover
  if (plugin === 'Popover') {
    external.push(bsPlugins.Tooltip)
    globals[bsPlugins.Tooltip] = 'Tooltip'
  }

  const pluginFilename = `${plugin.toLowerCase()}.js`

  rollup.rollup({
    input: bsPlugins[plugin],
    plugins,
    external
  }).then((bundle) => {
    bundle.write({
      banner: banner(pluginFilename),
      format: 'umd',
      name: plugin,
      sourcemap: true,
      globals,
      file: path.resolve(__dirname, `${rootPath}${pluginFilename}`)
    })
      .then(() => console.log(`Building ${plugin} plugin... Done!`))
      .catch((err) => console.error(`${plugin}: ${err}`))
  })
}

Object.keys(bsPlugins).forEach((plugin) => build(plugin))
<commit_msg>chore(update): bump to 4.1.3<commit_after>/*!
 * Script to build our plugins to use them separately.
 * Copyright 2019 The Bootstrap Authors
 * Copyright 2019 Twitter, Inc.
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 */

'use strict'

const path    = require('path')
const rollup  = require('rollup')
const babel   = require('rollup-plugin-babel')
const banner  = require('./banner.js')

const TEST    = process.env.NODE_ENV === 'test'
const plugins = [
  babel({
    exclude: 'node_modules/**', // Only transpile our source code
    externalHelpersWhitelist: [ // Include only required helpers
      'defineProperties',
      'createClass',
      'inheritsLoose',
      'defineProperty',
      'objectSpread'
    ]
  })
]
const bsPlugins = {
  Data: path.resolve(__dirname, '../js/src/dom/data.js'),
  EventHandler: path.resolve(__dirname, '../js/src/dom/eventHandler.js'),
  Manipulator: path.resolve(__dirname, '../js/src/dom/manipulator.js'),
  Polyfill: path.resolve(__dirname, '../js/src/dom/polyfill.js'),
  SelectorEngine: path.resolve(__dirname, '../js/src/dom/selectorEngine.js'),
  Alert: path.resolve(__dirname, '../js/src/alert.js'),
  Button: path.resolve(__dirname, '../js/src/button.js'),
  Carousel: path.resolve(__dirname, '../js/src/carousel.js'),
  Collapse: path.resolve(__dirname, '../js/src/collapse.js'),
  Dropdown: path.resolve(__dirname, '../js/src/dropdown.js'),
  Modal: path.resolve(__dirname, '../js/src/modal.js'),
  Popover: path.resolve(__dirname, '../js/src/popover.js'),
  ScrollSpy: path.resolve(__dirname, '../js/src/scrollspy.js'),
  Tab: path.resolve(__dirname, '../js/src/tab.js'),
  Toast: path.resolve(__dirname, '../js/src/toast.js'),
  Tooltip: path.resolve(__dirname, '../js/src/tooltip.js')
}
const rootPath = TEST ? '../js/coverage/dist/' : '../js/dist/'

if (TEST) {
  bsPlugins.Util = path.resolve(__dirname, '../js/src/util/index.js')
  bsPlugins.Sanitizer = path.resolve(__dirname, '../js/src/util/sanitizer.js')
}

const defaultPluginConfig = {
  external: [
    bsPlugins.Data,
    bsPlugins.EventHandler,
    bsPlugins.SelectorEngine
  ],
  globals: {
    [bsPlugins.Data]: 'Data',
    [bsPlugins.EventHandler]: 'EventHandler',
    [bsPlugins.SelectorEngine]: 'SelectorEngine'
  }
}

function getConfigByPluginKey(pluginKey) {
  if (
    pluginKey === 'Data' ||
    pluginKey === 'Manipulator' ||
    pluginKey === 'Polyfill' ||
    pluginKey === 'Util' ||
    pluginKey === 'Sanitizer'
  ) {
    return {
      external: [],
      globals: {}
    }
  }

  if (pluginKey === 'EventHandler' || pluginKey === 'SelectorEngine') {
    return {
      external: [
        bsPlugins.Polyfill
      ],
      globals: {
        [bsPlugins.Polyfill]: 'Polyfill'
      }
    }
  }

  if (pluginKey === 'Alert' || pluginKey === 'Tab') {
    return defaultPluginConfig
  }

  if (
    pluginKey === 'Button' ||
    pluginKey === 'Carousel' ||
    pluginKey === 'Collapse' ||
    pluginKey === 'Modal' ||
    pluginKey === 'ScrollSpy'
  ) {
    const config = Object.assign(defaultPluginConfig)
    config.external.push(bsPlugins.Manipulator)
    config.globals[bsPlugins.Manipulator] = 'Manipulator'
    return config
  }

  if (pluginKey === 'Dropdown' || pluginKey === 'Tooltip') {
    const config = Object.assign(defaultPluginConfig)
    config.external.push(bsPlugins.Manipulator, 'popper.js')
    config.globals[bsPlugins.Manipulator] = 'Manipulator'
    config.globals['popper.js'] = 'Popper'
    return config
  }

  if (pluginKey === 'Popover') {
    return {
      external: [
        bsPlugins.Data,
        bsPlugins.SelectorEngine,
        bsPlugins.Tooltip
      ],
      globals: {
        [bsPlugins.Data]: 'Data',
        [bsPlugins.SelectorEngine]: 'SelectorEngine',
        [bsPlugins.Tooltip]: 'Tooltip'
      }
    }
  }

  if (pluginKey === 'Toast') {
    return {
      external: [
        bsPlugins.Data,
        bsPlugins.EventHandler,
        bsPlugins.Manipulator
      ],
      globals: {
        [bsPlugins.Data]: 'Data',
        [bsPlugins.EventHandler]: 'EventHandler',
        [bsPlugins.Manipulator]: 'Manipulator'
      }
    }
  }
}

function build(plugin) {
  console.log(`Building ${plugin} plugin...`)

  const config = getConfigByPluginKey(plugin)
  const external = config.external
  const globals = config.globals
  let pluginPath = rootPath

  const utilObjects = [
    'Util',
    'Sanitizer'
  ]

  const domObjects = [
    'Data',
    'EventHandler',
    'Manipulator',
    'Polyfill',
    'SelectorEngine'
  ]

  if (utilObjects.includes(plugin)) {
    pluginPath = `${rootPath}/util/`
  }

  if (domObjects.includes(plugin)) {
    pluginPath = `${rootPath}/dom/`
  }

  const pluginFilename = `${plugin.toLowerCase()}.js`

  rollup.rollup({
    input: bsPlugins[plugin],
    plugins,
    external
  }).then((bundle) => {
    bundle.write({
      banner: banner(pluginFilename),
      format: 'umd',
      name: plugin,
      sourcemap: true,
      globals,
      file: path.resolve(__dirname, `${pluginPath}${pluginFilename}`)
    })
      .then(() => console.log(`Building ${plugin} plugin... Done!`))
      .catch((err) => console.error(`${plugin}: ${err}`))
  })
}

Object.keys(bsPlugins).forEach((plugin) => build(plugin))
<|endoftext|>


<commit_before><commit_msg>feat(bbc.modal): backdrop default value is set to true<commit_after><|endoftext|>


<commit_before>const config = require("../config");
const Sequelize = require('sequelize');
const fs = require('fs');
const path = require('path');
const log = require('./logging.js');

const sequelize = new Sequelize(config.DB_URL, {
    operatorsAliases: Sequelize.Op.Aliases,
    logging:          m => log.debug({message: m})
});

const db = {};
const modelsDir = path.join(__dirname, 'models');

fs
    .readdirSync(modelsDir)
    .filter(file => {
        return (file.indexOf('.') !== 0);
    })
    .forEach(file => {
        const model = sequelize['import'](path.join(modelsDir, file));
        db[model.name] = model;
    });

Object.keys(db).forEach(modelName => {
    if (db[modelName].associate) {
        db[modelName].associate(db);
    }
});

db.sequelize = sequelize;
db.Sequelize = Sequelize;

module.exports = db;
<commit_msg>Disable logging<commit_after>const config = require("../config");
const Sequelize = require('sequelize');
const fs = require('fs');
const path = require('path');
const log = require('./logging.js');

const sequelize = new Sequelize(config.DB_URL, {
    operatorsAliases: Sequelize.Op.Aliases,
    logging:          false
});

const db = {};
const modelsDir = path.join(__dirname, 'models');

fs
    .readdirSync(modelsDir)
    .filter(file => {
        return (file.indexOf('.') !== 0);
    })
    .forEach(file => {
        const model = sequelize['import'](path.join(modelsDir, file));
        db[model.name] = model;
    });

Object.keys(db).forEach(modelName => {
    if (db[modelName].associate) {
        db[modelName].associate(db);
    }
});

db.sequelize = sequelize;
db.Sequelize = Sequelize;

module.exports = db;
<|endoftext|>


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

	"use strict";

	/**
	 *  @class  Tone.Player is an audio file player with start, loop, and stop functions.
	 *
	 *  @constructor
	 *  @extends {Tone.Source}
	 *  @param {string|AudioBuffer} url Either the AudioBuffer or the url from
	 *                                  which to load the AudioBuffer
	 *  @param {function=} onload The function to invoke when the buffer is loaded.
	 *                            Recommended to use Tone.Buffer.onload instead.
	 *  @example
	 * var player = new Tone.Player("./path/to/sample.mp3").toMaster();
	 * Tone.Buffer.onload = function(){
	 * 	player.start();
	 * }
	 */
	Tone.Player = function(){

		var options = this.optionsObject(arguments, ["url", "onload"], Tone.Player.defaults);
		Tone.Source.call(this, options);

		/**
		 *  @private
		 *  @type {AudioBufferSourceNode}
		 */
		this._source = null;

		/**
		 *  If the file should play as soon
		 *  as the buffer is loaded.
		 *  @type {boolean}
		 *  @example
		 * //will play as soon as it's loaded
		 * var player = new Tone.Player({
		 * 	"url" : "./path/to/sample.mp3",
		 * 	"autostart" : true,
		 * }).toMaster();
		 */
		this.autostart = options.autostart;

		/**
		 *  the buffer
		 *  @private
		 *  @type {Tone.Buffer}
		 */
		this._buffer = new Tone.Buffer({
			"url" : options.url,
			"onload" : this._onload.bind(this, options.onload),
			"reverse" : options.reverse
		});

		/**
		 *  if the buffer should loop once it's over
		 *  @type {boolean}
		 *  @private
		 */
		this._loop = options.loop;

		/**
		 *  if 'loop' is true, the loop will start at this position
		 *  @type {Time}
		 *  @private
		 */
		this._loopStart = options.loopStart;

		/**
		 *  if 'loop' is true, the loop will end at this position
		 *  @type {Time}
		 *  @private
		 */
		this._loopEnd = options.loopEnd;

		/**
		 *  the playback rate
		 *  @private
		 *  @type {number}
		 */
		this._playbackRate = options.playbackRate;

		/**
		 *  Enabling retrigger will allow a player to be restarted
		 *  before the the previous 'start' is done playing. Otherwise,
		 *  successive calls to Tone.Player.start will only start
		 *  the sample if it had played all the way through.
		 *  @type {boolean}
		 */
		this.retrigger = options.retrigger;
	};

	Tone.extend(Tone.Player, Tone.Source);

	/**
	 *  the default parameters
	 *  @static
	 *  @const
	 *  @type {Object}
	 */
	Tone.Player.defaults = {
		"onload" : Tone.noOp,
		"playbackRate" : 1,
		"loop" : false,
		"autostart" : false,
		"loopStart" : 0,
		"loopEnd" : 0,
		"retrigger" : false,
		"reverse" : false,
	};

	/**
	 *  Load the audio file as an audio buffer.
	 *  Decodes the audio asynchronously and invokes
	 *  the callback once the audio buffer loads.
	 *  Note: this does not need to be called, if a url
	 *  was passed in to the constructor. Only use this
	 *  if you want to manually load a new url.
	 * @param {string} url The url of the buffer to load.
	 *                     Filetype support depends on the
	 *                     browser.
	 *  @param  {function=} callback The function to invoke once
	 *                               the sample is loaded.
	 *  @returns {Tone.Player} this
	 */
	Tone.Player.prototype.load = function(url, callback){
		this._buffer.load(url, this._onload.bind(this, callback));
		return this;
	};

	/**
	 * Internal callback when the buffer is loaded.
	 * @private
	 */
	Tone.Player.prototype._onload = function(callback){
		callback(this);
		if (this.autostart){
			this.start();
		}
	};

	/**
	 *  play the buffer between the desired positions
	 *
	 *  @private
	 *  @param  {Time} [startTime=now] when the player should start.
	 *  @param  {Time} [offset=0] the offset from the beginning of the sample
	 *                                 to start at.
	 *  @param  {Time=} duration how long the sample should play. If no duration
	 *                                is given, it will default to the full length
	 *                                of the sample (minus any offset)
	 *  @returns {Tone.Player} this
	 */
	Tone.Player.prototype._start = function(startTime, offset, duration){
		if (this._buffer.loaded){
			//if it's a loop the default offset is the loopstart point
			if (this._loop){
				offset = this.defaultArg(offset, this._loopStart);
			} else {
				//otherwise the default offset is 0
				offset = this.defaultArg(offset, 0);
			}
			offset = this.toSeconds(offset);
			duration = this.defaultArg(duration, this._buffer.duration - offset);
			//the values in seconds
			startTime = this.toSeconds(startTime);
			duration = this.toSeconds(duration);
			//make the source
			this._source = this.context.createBufferSource();
			this._source.buffer = this._buffer.get();
			//set the looping properties
			if (this._loop){
				this._source.loop = this._loop;
				this._source.loopStart = this.toSeconds(this._loopStart);
				this._source.loopEnd = this.toSeconds(this._loopEnd);
				// this fixes a bug in chrome 42 that breaks looping
				// https://code.google.com/p/chromium/issues/detail?id=457099
				duration = 65536;
			} else {
				this._nextStop = startTime + duration;
			}
			//and other properties
			this._source.playbackRate.value = this._playbackRate;
			this._source.onended = this.onended;
			this._source.connect(this.output);
			//start it
			this._source.start(startTime, offset, duration);
		} else {
			console.log("tried to start Player before the buffer was loaded");
		}
		return this;
	};

	/**
	 *  Stop playback.
	 *  @private
	 *  @param  {Time} [time=now]
	 *  @returns {Tone.Player} this
	 */
	Tone.Player.prototype._stop = function(time){
		if (this._source){
			this._source.stop(this.toSeconds(time));
			this._source = null;
		}
		return this;
	};

	/**
	 *  Set the loop start and end. Will only loop if loop is
	 *  set to true.
	 *  @param {Time} loopStart The loop end time
	 *  @param {Time} loopEnd The loop end time
	 *  @returns {Tone.Player} this
	 *  @example
	 * //loop 0.1 seconds of the file.
	 * player.setLoopPoints(0.2, 0.3);
	 * player.loop = true;
	 */
	Tone.Player.prototype.setLoopPoints = function(loopStart, loopEnd){
		this.loopStart = loopStart;
		this.loopEnd = loopEnd;
		return this;
	};

	/**
	 * If loop is true, the loop will start at this position.
	 * @memberOf Tone.Player#
	 * @type {Time}
	 * @name loopStart
	 */
	Object.defineProperty(Tone.Player.prototype, "loopStart", {
		get : function(){
			return this._loopStart;
		},
		set : function(loopStart){
			this._loopStart = loopStart;
			if (this._source){
				this._source.loopStart = this.toSeconds(loopStart);
			}
		}
	});

	/**
	 * If loop is true, the loop will end at this position.
	 * @memberOf Tone.Player#
	 * @type {Time}
	 * @name loopEnd
	 */
	Object.defineProperty(Tone.Player.prototype, "loopEnd", {
		get : function(){
			return this._loopEnd;
		},
		set : function(loopEnd){
			this._loopEnd = loopEnd;
			if (this._source){
				this._source.loopEnd = this.toSeconds(loopEnd);
			}
		}
	});

	/**
	 * The audio buffer belonging to the player.
	 * @memberOf Tone.Player#
	 * @type {AudioBuffer}
	 * @name buffer
	 */
	Object.defineProperty(Tone.Player.prototype, "buffer", {
		get : function(){
			return this._buffer;
		},
		set : function(buffer){
			this._buffer.set(buffer);
		}
	});

	/**
	 * If the buffer should loop once it's over.
	 * @memberOf Tone.Player#
	 * @type {boolean}
	 * @name loop
	 */
	Object.defineProperty(Tone.Player.prototype, "loop", {
		get : function(){
			return this._loop;
		},
		set : function(loop){
			this._loop = loop;
			if (this._source){
				this._source.loop = loop;
			}
		}
	});

	/**
	 * The playback speed. 1 is normal speed.
	 * Note that this is not a Tone.Signal because of a bug in Blink.
	 * Please star [this issue](https://code.google.com/p/chromium/issues/detail?id=311284)
	 * if this an important thing to you.
	 * @memberOf Tone.Player#
	 * @type {number}
	 * @name playbackRate
	 */
	Object.defineProperty(Tone.Player.prototype, "playbackRate", {
		get : function(){
			return this._playbackRate;
		},
		set : function(rate){
			this._playbackRate = rate;
			if (this._source) {
				this._source.playbackRate.value = rate;
			}
		}
	});

	/**
	 * The direction the buffer should play in
	 * @memberOf Tone.Player#
	 * @type {boolean}
	 * @name reverse
	 */
	Object.defineProperty(Tone.Player.prototype, "reverse", {
		get : function(){
			return this._buffer.reverse;
		},
		set : function(rev){
			this._buffer.reverse = rev;
		}
	});

	/**
	 *  Dispose and disconnect.
	 *  @return {Tone.Player} this
	 */
	Tone.Player.prototype.dispose = function(){
		Tone.Source.prototype.dispose.call(this);
		if (this._source !== null){
			this._source.disconnect();
			this._source = null;
		}
		this._buffer.dispose();
		this._buffer = null;
		return this;
	};

	return Tone.Player;
});
<commit_msg>player 2nd check to make sure buffer is loaded AND the buffer isn't null<commit_after>define(["Tone/core/Tone", "Tone/core/Buffer", "Tone/source/Source"], function(Tone){

	"use strict";

	/**
	 *  @class  Tone.Player is an audio file player with start, loop, and stop functions.
	 *
	 *  @constructor
	 *  @extends {Tone.Source}
	 *  @param {string|AudioBuffer} url Either the AudioBuffer or the url from
	 *                                  which to load the AudioBuffer
	 *  @param {function=} onload The function to invoke when the buffer is loaded.
	 *                            Recommended to use Tone.Buffer.onload instead.
	 *  @example
	 * var player = new Tone.Player("./path/to/sample.mp3").toMaster();
	 * Tone.Buffer.onload = function(){
	 * 	player.start();
	 * }
	 */
	Tone.Player = function(){

		var options = this.optionsObject(arguments, ["url", "onload"], Tone.Player.defaults);
		Tone.Source.call(this, options);

		/**
		 *  @private
		 *  @type {AudioBufferSourceNode}
		 */
		this._source = null;

		/**
		 *  If the file should play as soon
		 *  as the buffer is loaded.
		 *  @type {boolean}
		 *  @example
		 * //will play as soon as it's loaded
		 * var player = new Tone.Player({
		 * 	"url" : "./path/to/sample.mp3",
		 * 	"autostart" : true,
		 * }).toMaster();
		 */
		this.autostart = options.autostart;

		/**
		 *  the buffer
		 *  @private
		 *  @type {Tone.Buffer}
		 */
		this._buffer = new Tone.Buffer({
			"url" : options.url,
			"onload" : this._onload.bind(this, options.onload),
			"reverse" : options.reverse
		});

		/**
		 *  if the buffer should loop once it's over
		 *  @type {boolean}
		 *  @private
		 */
		this._loop = options.loop;

		/**
		 *  if 'loop' is true, the loop will start at this position
		 *  @type {Time}
		 *  @private
		 */
		this._loopStart = options.loopStart;

		/**
		 *  if 'loop' is true, the loop will end at this position
		 *  @type {Time}
		 *  @private
		 */
		this._loopEnd = options.loopEnd;

		/**
		 *  the playback rate
		 *  @private
		 *  @type {number}
		 */
		this._playbackRate = options.playbackRate;

		/**
		 *  Enabling retrigger will allow a player to be restarted
		 *  before the the previous 'start' is done playing. Otherwise,
		 *  successive calls to Tone.Player.start will only start
		 *  the sample if it had played all the way through.
		 *  @type {boolean}
		 */
		this.retrigger = options.retrigger;
	};

	Tone.extend(Tone.Player, Tone.Source);

	/**
	 *  the default parameters
	 *  @static
	 *  @const
	 *  @type {Object}
	 */
	Tone.Player.defaults = {
		"onload" : Tone.noOp,
		"playbackRate" : 1,
		"loop" : false,
		"autostart" : false,
		"loopStart" : 0,
		"loopEnd" : 0,
		"retrigger" : false,
		"reverse" : false,
	};

	/**
	 *  Load the audio file as an audio buffer.
	 *  Decodes the audio asynchronously and invokes
	 *  the callback once the audio buffer loads.
	 *  Note: this does not need to be called, if a url
	 *  was passed in to the constructor. Only use this
	 *  if you want to manually load a new url.
	 * @param {string} url The url of the buffer to load.
	 *                     Filetype support depends on the
	 *                     browser.
	 *  @param  {function=} callback The function to invoke once
	 *                               the sample is loaded.
	 *  @returns {Tone.Player} this
	 */
	Tone.Player.prototype.load = function(url, callback){
		this._buffer.load(url, this._onload.bind(this, callback));
		return this;
	};

	/**
	 * Internal callback when the buffer is loaded.
	 * @private
	 */
	Tone.Player.prototype._onload = function(callback){
		callback(this);
		if (this.autostart){
			this.start();
		}
	};

	/**
	 *  play the buffer between the desired positions
	 *
	 *  @private
	 *  @param  {Time} [startTime=now] when the player should start.
	 *  @param  {Time} [offset=0] the offset from the beginning of the sample
	 *                                 to start at.
	 *  @param  {Time=} duration how long the sample should play. If no duration
	 *                                is given, it will default to the full length
	 *                                of the sample (minus any offset)
	 *  @returns {Tone.Player} this
	 */
	Tone.Player.prototype._start = function(startTime, offset, duration){
		if (this._buffer.loaded && this._buffer._buffer){
			//if it's a loop the default offset is the loopstart point
			if (this._loop){
				offset = this.defaultArg(offset, this._loopStart);
			} else {
				//otherwise the default offset is 0
				offset = this.defaultArg(offset, 0);
			}
			offset = this.toSeconds(offset);
			duration = this.defaultArg(duration, this._buffer.duration - offset);
			//the values in seconds
			startTime = this.toSeconds(startTime);
			duration = this.toSeconds(duration);
			//make the source
			this._source = this.context.createBufferSource();
			this._source.buffer = this._buffer.get();
			//set the looping properties
			if (this._loop){
				this._source.loop = this._loop;
				this._source.loopStart = this.toSeconds(this._loopStart);
				this._source.loopEnd = this.toSeconds(this._loopEnd);
				// this fixes a bug in chrome 42 that breaks looping
				// https://code.google.com/p/chromium/issues/detail?id=457099
				duration = 65536;
			} else {
				this._nextStop = startTime + duration;
			}
			//and other properties
			this._source.playbackRate.value = this._playbackRate;
			this._source.onended = this.onended;
			this._source.connect(this.output);
			//start it
			this._source.start(startTime, offset, duration);
		} else {
			console.log("tried to start Player before the buffer was loaded");
		}
		return this;
	};

	/**
	 *  Stop playback.
	 *  @private
	 *  @param  {Time} [time=now]
	 *  @returns {Tone.Player} this
	 */
	Tone.Player.prototype._stop = function(time){
		if (this._source){
			this._source.stop(this.toSeconds(time));
			this._source = null;
		}
		return this;
	};

	/**
	 *  Set the loop start and end. Will only loop if loop is
	 *  set to true.
	 *  @param {Time} loopStart The loop end time
	 *  @param {Time} loopEnd The loop end time
	 *  @returns {Tone.Player} this
	 *  @example
	 * //loop 0.1 seconds of the file.
	 * player.setLoopPoints(0.2, 0.3);
	 * player.loop = true;
	 */
	Tone.Player.prototype.setLoopPoints = function(loopStart, loopEnd){
		this.loopStart = loopStart;
		this.loopEnd = loopEnd;
		return this;
	};

	/**
	 * If loop is true, the loop will start at this position.
	 * @memberOf Tone.Player#
	 * @type {Time}
	 * @name loopStart
	 */
	Object.defineProperty(Tone.Player.prototype, "loopStart", {
		get : function(){
			return this._loopStart;
		},
		set : function(loopStart){
			this._loopStart = loopStart;
			if (this._source){
				this._source.loopStart = this.toSeconds(loopStart);
			}
		}
	});

	/**
	 * If loop is true, the loop will end at this position.
	 * @memberOf Tone.Player#
	 * @type {Time}
	 * @name loopEnd
	 */
	Object.defineProperty(Tone.Player.prototype, "loopEnd", {
		get : function(){
			return this._loopEnd;
		},
		set : function(loopEnd){
			this._loopEnd = loopEnd;
			if (this._source){
				this._source.loopEnd = this.toSeconds(loopEnd);
			}
		}
	});

	/**
	 * The audio buffer belonging to the player.
	 * @memberOf Tone.Player#
	 * @type {AudioBuffer}
	 * @name buffer
	 */
	Object.defineProperty(Tone.Player.prototype, "buffer", {
		get : function(){
			return this._buffer;
		},
		set : function(buffer){
			this._buffer.set(buffer);
		}
	});

	/**
	 * If the buffer should loop once it's over.
	 * @memberOf Tone.Player#
	 * @type {boolean}
	 * @name loop
	 */
	Object.defineProperty(Tone.Player.prototype, "loop", {
		get : function(){
			return this._loop;
		},
		set : function(loop){
			this._loop = loop;
			if (this._source){
				this._source.loop = loop;
			}
		}
	});

	/**
	 * The playback speed. 1 is normal speed.
	 * Note that this is not a Tone.Signal because of a bug in Blink.
	 * Please star [this issue](https://code.google.com/p/chromium/issues/detail?id=311284)
	 * if this an important thing to you.
	 * @memberOf Tone.Player#
	 * @type {number}
	 * @name playbackRate
	 */
	Object.defineProperty(Tone.Player.prototype, "playbackRate", {
		get : function(){
			return this._playbackRate;
		},
		set : function(rate){
			this._playbackRate = rate;
			if (this._source) {
				this._source.playbackRate.value = rate;
			}
		}
	});

	/**
	 * The direction the buffer should play in
	 * @memberOf Tone.Player#
	 * @type {boolean}
	 * @name reverse
	 */
	Object.defineProperty(Tone.Player.prototype, "reverse", {
		get : function(){
			return this._buffer.reverse;
		},
		set : function(rev){
			this._buffer.reverse = rev;
		}
	});

	/**
	 *  Dispose and disconnect.
	 *  @return {Tone.Player} this
	 */
	Tone.Player.prototype.dispose = function(){
		Tone.Source.prototype.dispose.call(this);
		if (this._source !== null){
			this._source.disconnect();
			this._source = null;
		}
		this._buffer.dispose();
		this._buffer = null;
		return this;
	};

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


<commit_before><commit_msg>added assurance for http header already sent<commit_after><|endoftext|>