<commit_before>var express = require('express');
var router = express.Router();
var request = require('request');
var gm = require('gm')
    .subClass({imageMagick: true}); // Enable ImageMagick integration.
var imageType = require('image-type');
var uuid = require('node-uuid');
var AWS = require('aws-sdk');
var s3 = new AWS.S3();

router.get('/resize', function (req, res, next) {

    //var srcKey = req.params.key;
    var imageUrl = req.query.src;
    var mode = req.query.mode;
    var max_size = req.query.size ? parseInt(req.query.size) : 200;
    var pixelate = req.query.pixelate || false;

    var options = {
        mode: mode,
        size: max_size,
        pixelate: pixelate
    };

    request({method:'GET', url:imageUrl, encoding:null}, function(error, response, body) {

        if (error) {
            console.error('unable to download image ' + err);
            return res.status(404).send('unable to download image ' + err);
        }

        if (!body)
            return res.status(404).send('no body response for image');

        var imgType = imageType(body);

        if (!imgType || (imgType.mime != "image/jpeg" && imgType.mime != "image/png")) {
            console.log('skipping non-image ' + srcKey);
            return res.status(400).send('not an image type');
        }
        var original = gm(body);
        original.size(function (err, size) {
            if (err) {
                console.error(err);
                return res.status(500).send(err);
            }
            resize_photo(size, options, original, function (err, photo) {
                res.setHeader('Content-Type', 'image/jpeg');
                res.send(photo);
            });
        });

    });

});

var resize_photo = function (size, options, original, next) {

    // Infer the scaling factor to avoid stretching the image unnaturally.
    var scalingFactor;

    switch(options.mode) {
        case 'width':
            scalingFactor = options.size / size.width;
            break;
        case 'height':
            scalingFactor =  options.size / size.height;
            break;
        case 'crop':
            scalingFactor = Math.max(options.size / size.width, options.size / size.height); //for cropping to square
            break;
        default:
            scalingFactor = Math.min(options.size / size.width, options.size / size.height); //for either size
    }

    var width = scalingFactor * size.width;
    var height = scalingFactor * size.height;

    var original = original
        .resize(width, height)
        .autoOrient();

    if (options.mode === 'pad' || options.mode === 'crop') {
        original.gravity('Center').extent(options.size, options.size);
    }

    if (options.pixelate) {
        original.scale('10%').scale('1000%')
    }

    original.toBuffer('jpg', function (err, buffer) {
        if (err) {
            next(err);
        }
        else {
            next(null, buffer);
        }
    });

};

// can fetch from s3 instead of http get
//function getFromS3(filename, callback) {
//    // Download the image from S3
//    s3.getObject({
//        Bucket: srcBucket,
//        Key: filename
//    }, function (err, response) {
//        callback(err, response.Body);
//    });
//}

const containerName = process.env.uploadBucket || 'uploads';

function getUploadUrl(callback) {
    var fileName =  uuid.v4();
    //assuming amazon s3
    var params = {Bucket: containerName, Key: fileName };

    s3.getSignedUrl('putObject', params, function(err, link){
        callback(err, link, fileName);
    });
}

// if we want to pupload to azure instead
//var azure = require('azure-storage');
//var blobService = azure.createBlobService();
//
//function getAzureLink(fileName, callback) {
//    var startDate = new Date();
//    var expiryDate = new Date(startDate);
//    expiryDate.setMinutes(startDate.getMinutes() + 10);
//
//    var sharedAccessPolicy = {
//        AccessPolicy: {
//            Permissions: azure.BlobUtilities.SharedAccessPermissions.WRITE,
//            Start: startDate,
//            Expiry: expiryDate
//        },
//    };
//
//    var token = blobSvc.generateSharedAccessSignature(containerName, fileName, sharedAccessPolicy);
//    var url = blobService.getUrl(containerName, fileName, token);
//       callback(null, url);
//}

router.post('/upload', function (req, res, next) {
    getUploadUrl(function (err, uploadLink, fileName) {
        if (!err) {
            res.send(201,{url: uploadLink, fileName: fileName});
        }
        else {
            res.send(500, err);
        }

    });
});

module.exports = router;
<commit_msg>srckey reference removed<commit_after>var express = require('express');
var router = express.Router();
var request = require('request');
var gm = require('gm')
    .subClass({imageMagick: true}); // Enable ImageMagick integration.
var imageType = require('image-type');
var uuid = require('node-uuid');
var AWS = require('aws-sdk');
var s3 = new AWS.S3();

router.get('/resize', function (req, res, next) {

    //var srcKey = req.params.key;
    var imageUrl = req.query.src;
    var mode = req.query.mode;
    var max_size = req.query.size ? parseInt(req.query.size) : 200;
    var pixelate = req.query.pixelate || false;

    var options = {
        mode: mode,
        size: max_size,
        pixelate: pixelate
    };

    request({method:'GET', url:imageUrl, encoding:null}, function(error, response, body) {

        if (error) {
            console.error('unable to download image ' + err);
            return res.status(404).send('unable to download image ' + err);
        }

        if (!body)
            return res.status(404).send('no body response for image');

        var imgType = imageType(body);

        if (!imgType || (imgType.mime != "image/jpeg" && imgType.mime != "image/png")) {
            console.log('skipping non-image ' + imageUrl);
            return res.status(400).send('not an image type');
        }
        var original = gm(body);
        original.size(function (err, size) {
            if (err) {
                console.error(err);
                return res.status(500).send(err);
            }
            resize_photo(size, options, original, function (err, photo) {
                res.setHeader('Content-Type', 'image/jpeg');
                res.send(photo);
            });
        });

    });

});

var resize_photo = function (size, options, original, next) {

    // Infer the scaling factor to avoid stretching the image unnaturally.
    var scalingFactor;

    switch(options.mode) {
        case 'width':
            scalingFactor = options.size / size.width;
            break;
        case 'height':
            scalingFactor =  options.size / size.height;
            break;
        case 'crop':
            scalingFactor = Math.max(options.size / size.width, options.size / size.height); //for cropping to square
            break;
        default:
            scalingFactor = Math.min(options.size / size.width, options.size / size.height); //for either size
    }

    var width = scalingFactor * size.width;
    var height = scalingFactor * size.height;

    var original = original
        .resize(width, height)
        .autoOrient();

    if (options.mode === 'pad' || options.mode === 'crop') {
        original.gravity('Center').extent(options.size, options.size);
    }

    if (options.pixelate) {
        original.scale('10%').scale('1000%')
    }

    original.toBuffer('jpg', function (err, buffer) {
        if (err) {
            next(err);
        }
        else {
            next(null, buffer);
        }
    });

};

// can fetch from s3 instead of http get
//function getFromS3(filename, callback) {
//    // Download the image from S3
//    s3.getObject({
//        Bucket: srcBucket,
//        Key: filename
//    }, function (err, response) {
//        callback(err, response.Body);
//    });
//}

const containerName = process.env.uploadBucket || 'uploads';

function getUploadUrl(callback) {
    var fileName =  uuid.v4();
    //assuming amazon s3
    var params = {Bucket: containerName, Key: fileName };

    s3.getSignedUrl('putObject', params, function(err, link){
        callback(err, link, fileName);
    });
}

// if we want to pupload to azure instead
//var azure = require('azure-storage');
//var blobService = azure.createBlobService();
//
//function getAzureLink(fileName, callback) {
//    var startDate = new Date();
//    var expiryDate = new Date(startDate);
//    expiryDate.setMinutes(startDate.getMinutes() + 10);
//
//    var sharedAccessPolicy = {
//        AccessPolicy: {
//            Permissions: azure.BlobUtilities.SharedAccessPermissions.WRITE,
//            Start: startDate,
//            Expiry: expiryDate
//        },
//    };
//
//    var token = blobSvc.generateSharedAccessSignature(containerName, fileName, sharedAccessPolicy);
//    var url = blobService.getUrl(containerName, fileName, token);
//       callback(null, url);
//}

router.post('/upload', function (req, res, next) {
    getUploadUrl(function (err, uploadLink, fileName) {
        if (!err) {
            res.send(201,{url: uploadLink, fileName: fileName});
        }
        else {
            res.send(500, err);
        }

    });
});

module.exports = router;
<|endoftext|>


<commit_before>importScripts('./analyzer.js', './deps/interpreter/acorn.js', './deps/interpreter/interpreter.js');
onmessage = function (event) {
  var code = event.data;
  // TODO: Interpreter needs a timeout in case it never halt.
  var interpreter = new Interpreter(code);
  var err;
  // try {
  console.log('onmessage worker');
  try {
    interpreter.run(10000);
  } catch (e) {
    err = e;
    postMessage({err: e.toString()});
  }
  if (err) return;
  console.log('after run');
  var analyzer = new StackAnalyzer(interpreter);
  console.log('ana');
  analyzer.interpreter = null;
  console.log(analyzer);
  postMessage({err: null, analyzer: analyzer});
  // } catch (err) {
  //   throw err;
  //   postMessage({err: err.toString()});
  // }
};
<commit_msg>larger timeout for interpreter.<commit_after>importScripts('./analyzer.js', './deps/interpreter/acorn.js', './deps/interpreter/interpreter.js');
onmessage = function (event) {
  var code = event.data;
  // TODO: Interpreter needs a timeout in case it never halt.
  var interpreter = new Interpreter(code);
  var err;
  // try {
  console.log('onmessage worker');
  try {
    interpreter.run(30000);
  } catch (e) {
    err = e;
    postMessage({err: e.toString()});
  }
  if (err) return;
  console.log('after run');
  var analyzer = new StackAnalyzer(interpreter);
  console.log('ana');
  analyzer.interpreter = null;
  console.log(analyzer);
  postMessage({err: null, analyzer: analyzer});
  // } catch (err) {
  //   throw err;
  //   postMessage({err: err.toString()});
  // }
};
<|endoftext|>


<commit_before>import React from 'react';
import { browserHistory } from 'react-router';
import Drawer from 'material-ui/Drawer';
import { List, ListItem } from 'material-ui/List';
import ICONS from '../styles/icons';
import SvgIcon from 'material-ui/SvgIcon';
// import IconButton from 'material-ui/IconButton';

import AccountBox from 'material-ui/svg-icons/action/account-box';
import Favorite from 'material-ui/svg-icons/action/favorite';
import ShoppingCart from 'material-ui/svg-icons/action/shopping-cart';
import Calendar from 'material-ui/svg-icons/action/today';
import Help from 'material-ui/svg-icons/action/help';

const styles = {
	container: {
		height: '100%',
		width: '100%',
		display: 'flex',
		flexWrap: 'wrap',
		flexDirection: 'column',
		justifyContent: 'flex-start',
	},
	profileTile: {
		// backgroundColor: '#F1F1F1',
		// flex: 2,
		display: 'flex',
		alignItems: 'flex-start',
		justifyContent: 'center',
		padding: 25,
	},
	profileImg: {
		width: '100%',
		borderRadius: 100,
		boxShadow: '0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23)',
	},
	tile1: {
		// flex: 1,
		width: '100%',
		backgroundColor: '#F1F1F1',
	},
	tile2: {
		// flex: 1,
		width: '100%',
		backgroundColor: '#F1F1F1',
	},
	tile3: {
		// flex: 1,
		width: '100%',
		backgroundColor: '#F1F1F1',
	},
	tile4: {
		position: 'fixed',
		bottom: 0,
		left: 110,
	},
	button: {
		// position: 'relative',
		// top: 30,
		color: '#556270',
		backgroundColor: '#FFFFFF',
		fontSize: '2em',
		height: '50%',
		width: '100%',
		boxShadow: '0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23)',
	},
	icon: {
		opacity: 0.75,
	},
};

const AppDrawer = ({ drawerOpen, updateDrawer }) => (
	<Drawer
		className="app-drawer"
		overlayClassName="app-drawer-overlay"
		docked={false}
		width={250}
		open={drawerOpen}
		onRequestChange={() => updateDrawer()}
	>

		<List>
			<ListItem
				onTouchTap={() => {
					updateDrawer();
					browserHistory.push('/settings');
				}}
				primaryText="Settings"
				leftIcon={<AccountBox />}
			/>
			<ListItem
				onTouchTap={() => {
					updateDrawer();
					browserHistory.push('/icebox');
				}}
				primaryText="Icebox"
				leftIcon={
					<SvgIcon className="icon">
						<path d={ICONS.Icebox.d} />
					</SvgIcon>
				}
			/>
			<ListItem
				onTouchTap={() => {
					updateDrawer();
					browserHistory.push('/recipes');
				}}
				primaryText="Recipes"
				leftIcon={
					<SvgIcon className="icon">
						<path d={ICONS.Recipes.d} />
					</SvgIcon>
				}
			/>
			<ListItem
				onTouchTap={() => {
					updateDrawer();
					browserHistory.push('/recipes');
				}}
				primaryText="Past Recipes"
				leftIcon={<Favorite />}
			/>
			<ListItem
				onTouchTap={() => {
					updateDrawer();
					browserHistory.push('/recipes');
				}}
				primaryText="Calendar View"
				leftIcon={<Calendar />}
			/>
			<ListItem
				onTouchTap={() => {
					updateDrawer();
					browserHistory.push('/recipes');
				}}
				primaryText="Shopping List"
				leftIcon={<ShoppingCart />}
			/>
			<ListItem
				onTouchTap={() => {
					updateDrawer();
					browserHistory.push('/');
				}}
				primaryText="Help"
				leftIcon={<Help />}
			/>
		</List>

	</Drawer>
);

AppDrawer.propTypes = {
	drawerOpen: React.PropTypes.bool.isRequired,
	updateDrawer: React.PropTypes.func.isRequired,
};

export default AppDrawer;

/*

	<Link to="/icebox" style={styles.tile1}>
		<IconButton
			style={styles.button}
			className="app-drawer-icebox"
			onTouchTap={() => updateDrawer()}
			iconStyle={styles.icon}
		>
			<SvgIcon className="icon">
				<path d={ICONS.Icebox.d} />
			</SvgIcon>
			Icebox
		</IconButton>
	</Link>
	<Link to="/recipes" style={styles.tile2}>
		<IconButton
			style={styles.button}
			className="app-drawer-recipes"
			onTouchTap={() => updateDrawer()}
			iconStyle={styles.icon}
		>
			<SvgIcon className="icon">
				<path d={ICONS.Recipes.d} />
			</SvgIcon>
			Recipes
		</IconButton>
	</Link>
	<Link to="/settings" style={styles.tile3}>
		<IconButton
			style={styles.button}
			className="app-drawer-settings"
			onTouchTap={() => updateDrawer()}
			iconStyle={styles.icon}
		>
			<SvgIcon className="icon">
				<path d={ICONS.Settings.d} />
			</SvgIcon>
			Settings
		</IconButton>
	</Link>

Help

*/

<commit_msg>[fix] adds classNames to components in appDrawer to pass tests<commit_after>import React from 'react';
import { browserHistory } from 'react-router';
import Drawer from 'material-ui/Drawer';
import { List, ListItem } from 'material-ui/List';
import ICONS from '../styles/icons';
import SvgIcon from 'material-ui/SvgIcon';
// import IconButton from 'material-ui/IconButton';

import AccountBox from 'material-ui/svg-icons/action/account-box';
import Favorite from 'material-ui/svg-icons/action/favorite';
import ShoppingCart from 'material-ui/svg-icons/action/shopping-cart';
import Calendar from 'material-ui/svg-icons/action/today';
import Help from 'material-ui/svg-icons/action/help';

const styles = {
	container: {
		height: '100%',
		width: '100%',
		display: 'flex',
		flexWrap: 'wrap',
		flexDirection: 'column',
		justifyContent: 'flex-start',
	},
	profileTile: {
		// backgroundColor: '#F1F1F1',
		// flex: 2,
		display: 'flex',
		alignItems: 'flex-start',
		justifyContent: 'center',
		padding: 25,
	},
	profileImg: {
		width: '100%',
		borderRadius: 100,
		boxShadow: '0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23)',
	},
	tile1: {
		// flex: 1,
		width: '100%',
		backgroundColor: '#F1F1F1',
	},
	tile2: {
		// flex: 1,
		width: '100%',
		backgroundColor: '#F1F1F1',
	},
	tile3: {
		// flex: 1,
		width: '100%',
		backgroundColor: '#F1F1F1',
	},
	tile4: {
		position: 'fixed',
		bottom: 0,
		left: 110,
	},
	button: {
		// position: 'relative',
		// top: 30,
		color: '#556270',
		backgroundColor: '#FFFFFF',
		fontSize: '2em',
		height: '50%',
		width: '100%',
		boxShadow: '0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23)',
	},
	icon: {
		opacity: 0.75,
	},
};

const AppDrawer = ({ drawerOpen, updateDrawer }) => (
	<Drawer
		className="app-drawer"
		overlayClassName="app-drawer-overlay"
		docked={false}
		width={250}
		open={drawerOpen}
		onRequestChange={() => updateDrawer()}
	>

		<List>
			<ListItem
				className="app-drawer-settings"
				onTouchTap={() => {
					updateDrawer();
					browserHistory.push('/settings');
				}}
				primaryText="Settings"
				leftIcon={<AccountBox />}
			/>
			<ListItem
				className="app-drawer-icebox"
				onTouchTap={() => {
					updateDrawer();
					browserHistory.push('/icebox');
				}}
				primaryText="Icebox"
				leftIcon={
					<SvgIcon className="icon">
						<path d={ICONS.Icebox.d} />
					</SvgIcon>
				}
			/>
			<ListItem
				className="app-drawer-recipes"
				onTouchTap={() => {
					updateDrawer();
					browserHistory.push('/recipes');
				}}
				primaryText="Recipes"
				leftIcon={
					<SvgIcon className="icon">
						<path d={ICONS.Recipes.d} />
					</SvgIcon>
				}
			/>
			<ListItem
				className="app-drawer-pastrecipes"
				onTouchTap={() => {
					updateDrawer();
					browserHistory.push('/recipes');
				}}
				primaryText="Past Recipes"
				leftIcon={<Favorite />}
			/>
			<ListItem
				className="app-drawer-calendar"
				onTouchTap={() => {
					updateDrawer();
					browserHistory.push('/recipes');
				}}
				primaryText="Calendar View"
				leftIcon={<Calendar />}
			/>
			<ListItem
				className="app-drawer-shopping-list"
				onTouchTap={() => {
					updateDrawer();
					browserHistory.push('/recipes');
				}}
				primaryText="Shopping List"
				leftIcon={<ShoppingCart />}
			/>
			<ListItem
				className="app-drawer-help"
				onTouchTap={() => {
					updateDrawer();
					browserHistory.push('/');
				}}
				primaryText="Help"
				leftIcon={<Help />}
			/>
		</List>

	</Drawer>
);

AppDrawer.propTypes = {
	drawerOpen: React.PropTypes.bool.isRequired,
	updateDrawer: React.PropTypes.func.isRequired,
};

export default AppDrawer;

/*

	<Link to="/icebox" style={styles.tile1}>
		<IconButton
			style={styles.button}
			className="app-drawer-icebox"
			onTouchTap={() => updateDrawer()}
			iconStyle={styles.icon}
		>
			<SvgIcon className="icon">
				<path d={ICONS.Icebox.d} />
			</SvgIcon>
			Icebox
		</IconButton>
	</Link>
	<Link to="/recipes" style={styles.tile2}>
		<IconButton
			style={styles.button}
			className="app-drawer-recipes"
			onTouchTap={() => updateDrawer()}
			iconStyle={styles.icon}
		>
			<SvgIcon className="icon">
				<path d={ICONS.Recipes.d} />
			</SvgIcon>
			Recipes
		</IconButton>
	</Link>
	<Link to="/settings" style={styles.tile3}>
		<IconButton
			style={styles.button}
			className="app-drawer-settings"
			onTouchTap={() => updateDrawer()}
			iconStyle={styles.icon}
		>
			<SvgIcon className="icon">
				<path d={ICONS.Settings.d} />
			</SvgIcon>
			Settings
		</IconButton>
	</Link>

Help

*/

<|endoftext|>


<commit_before>(function () {
    var Ipc = require('ipc');
    var _checkLeaks = true;

    function _keyboardEventFor ( type, keyCode, modifier ) {
        var event = new CustomEvent(type);

        event.keyCode = keyCode;
        event.code = keyCode;

        if ( modifier === 'shift')
            event.shiftKey = true;
        else if ( modifier === 'ctrl' )
            event.ctrlKey = true;
        else if ( modifier === 'command' )
            event.metaKey = true;
        else if ( modifier === 'alt' )
            event.altKey = true;

        return event;
    }

    function _makeMouseEvent (type,xy,button) {
        if (!xy) {
            xy = {
                x:0,
                y:0
            }
        }

        var props = {
            bubbles: true,
            cancelable: true,
            clientX: xy.x,
            clientY: xy.y,
            button: button ? button: 0
        };

        var event = new MouseEvent(type,props);
        return event;
    }

    var Tester = {
        send: function ( channel ) {
            if ( !channel ) {
                throw new Error('Please specific a channel for your message');
            }
            var args = [].slice.call( arguments, 0 );
            args.unshift('tester:send');
            Ipc.sendToHost.apply(null,args);
        },

        checkLeaks: function ( enabled ) {
            _checkLeaks = enabled;
        },

        // https://github.com/mochajs/mocha/wiki/Detecting-global-leaks
        detectLeak: function ( name_of_leaking_property ) {
            Object.defineProperty(global, name_of_leaking_property, {
                set : function(value) {
                    throw new Error('Global leak happends here!!');
                }
            });
        },

        focus: function ( target ) {
            Polymer.Base.fire.call(target, 'focus');
        },

        blur: function ( target ) {
            Polymer.Base.fire.call(target, 'blur');
        },

        keyDownOn: function ( target, keyText, modifier ) {
            target.dispatchEvent(_keyboardEventFor('keydown', Editor.KeyCode(keyText), modifier));
        },

        keyUpOn: function ( target, keyText, modifier ) {
            target.dispatchEvent(_keyboardEventFor('keyup', Editor.KeyCode(keyText), modifier));
        },

        keypress: function (target, keyText) {
            target.dispatchEvent(_keyboardEventFor('keypress', Editor.KeyCode(keyText)));
        },

        mouseEvent: function (target, type,xy,button) {
            target.dispatchEvent(_makeMouseEvent(type,xy,button));
        },

        topLeftOfNode: function(target) {
            var bcr = target.getBoundingClientRect();
            return {
              y: bcr.top,
              x: bcr.left
            };
        },

        middleOfNode: function (target) {
            var bcr = target.getBoundingClientRect();
            return {
              y: bcr.top + (bcr.height / 2),
              x: bcr.left + (bcr.width / 2)
            };
        },

    };

    Object.defineProperty( Tester, 'needCheckLeaks', {
        get: function () {
            return _checkLeaks;
        }
    });

    // initialize client-side tester
    window.Tester = Tester;
})();
<commit_msg>强制添加坐标<commit_after>(function () {
    var Ipc = require('ipc');
    var _checkLeaks = true;

    function _keyboardEventFor ( type, keyCode, modifier ) {
        var event = new CustomEvent(type);

        event.keyCode = keyCode;
        event.code = keyCode;

        if ( modifier === 'shift')
            event.shiftKey = true;
        else if ( modifier === 'ctrl' )
            event.ctrlKey = true;
        else if ( modifier === 'command' )
            event.metaKey = true;
        else if ( modifier === 'alt' )
            event.altKey = true;

        return event;
    }

    function _makeMouseEvent (type,x,y,button) {
        var props = {
            bubbles: true,
            cancelable: true,
            clientX: x,
            clientY: y,
            button: button ? button: 0
        };

        var event = new MouseEvent(type,props);
        return event;
    }

    var Tester = {
        send: function ( channel ) {
            if ( !channel ) {
                throw new Error('Please specific a channel for your message');
            }
            var args = [].slice.call( arguments, 0 );
            args.unshift('tester:send');
            Ipc.sendToHost.apply(null,args);
        },

        checkLeaks: function ( enabled ) {
            _checkLeaks = enabled;
        },

        // https://github.com/mochajs/mocha/wiki/Detecting-global-leaks
        detectLeak: function ( name_of_leaking_property ) {
            Object.defineProperty(global, name_of_leaking_property, {
                set : function(value) {
                    throw new Error('Global leak happends here!!');
                }
            });
        },

        focus: function ( target ) {
            Polymer.Base.fire.call(target, 'focus');
        },

        blur: function ( target ) {
            Polymer.Base.fire.call(target, 'blur');
        },

        keyDownOn: function ( target, keyText, modifier ) {
            target.dispatchEvent(_keyboardEventFor('keydown', Editor.KeyCode(keyText), modifier));
        },

        keyUpOn: function ( target, keyText, modifier ) {
            target.dispatchEvent(_keyboardEventFor('keyup', Editor.KeyCode(keyText), modifier));
        },

        keypress: function (target, keyText) {
            target.dispatchEvent(_keyboardEventFor('keypress', Editor.KeyCode(keyText)));
        },

        mouseEvent: function (target, type, x, y, button) {
            target.dispatchEvent(_makeMouseEvent(type, x, y, button));
        },

        topLeftOfNode: function(target) {
            var bcr = target.getBoundingClientRect();
            return {
              y: bcr.top,
              x: bcr.left
            };
        },

        middleOfNode: function (target) {
            var bcr = target.getBoundingClientRect();
            return {
              y: bcr.top + (bcr.height / 2),
              x: bcr.left + (bcr.width / 2)
            };
        },

    };

    Object.defineProperty( Tester, 'needCheckLeaks', {
        get: function () {
            return _checkLeaks;
        }
    });

    // initialize client-side tester
    window.Tester = Tester;
})();
<|endoftext|>


<commit_before>/* InstantClick 2.0 | (C) 2014 Alexandre Dieulot | http://instantclick.io/license.html */
var InstantClick = function(document, location) {
	var currentLocationWithoutHash
	var urlToPreload
	var preloadTimer

	var pHistory = {} // short for "preloadHistory"
	var p = {} // short for "preloads"

	var useBlacklist
	var preloadOnMousedown
	var delayBeforePreload
	var listeners = {change: []}

	////////// HELPERS //////////

	function removeHash(url) {
		var index = url.indexOf('#')
		if (index == -1) {
			return url
		}
		return url.substr(0, index)
	}

	function getLinkTarget(target) {
		while (target.nodeName != 'A') {
			target = target.parentNode
		}
		return target
	}

	function triggerPageEvent(type) {
		for (var i = 0; i < listeners[type].length; i++) {
			listeners[type][i]()
		}
	}

	function changePage(title, body) {
		var doc = document.implementation.createHTMLDocument('')
		doc.documentElement.innerHTML = body
		document.documentElement.replaceChild(doc.body, document.body)

		var elem = document.createElement('i')
		elem.innerHTML = title
		document.title = elem.textContent
	}

	////////// EVENT HANDLERS //////////

	function mousedown(e) {
		preload(getLinkTarget(e.target).href)
	}

	function mouseover(e) {
		var a = getLinkTarget(e.target)
		a.addEventListener('mouseout', mouseout)

		if (!delayBeforePreload) {
			preload(a.href)
		}
		else {
			urlToPreload = a.href
			preloadTimer = setTimeout(preload, delayBeforePreload)
		}
	}

	function click(e) {
		if (e.which > 1 || e.metaKey || e.ctrlKey) { // Opening in new tab
			return
		}
		e.preventDefault()
		display(getLinkTarget(e.target).href)
	}

	function mouseout() {
		if (preloadTimer) {
			clearTimeout(preloadTimer)
			preloadTimer = false
			return
		}

		if (!p.isPreloading || (p.isPreloading && p.isWaitingForCompletion)) {
			return
		}
		p.xhr.abort()
		p.isPreloading = false
		p.isWaitingForCompletion = false
	}

	function readystatechange(e) {
		if (p.xhr.readyState < 4) {
			return
		}
		if (p.xhr.status == 0) { // Aborted
			return
		}

		p.timing.ready = +new Date - p.timing.start

		var text = p.xhr.responseText

		var titleIndex = text.indexOf('<title')
		if (titleIndex > -1) {
			p.title = text.substr(text.indexOf('>', titleIndex) + 1)
			p.title = p.title.substr(0, p.title.indexOf('</title'))
		}

		var bodyIndex = text.indexOf('<body')
		if (bodyIndex > -1) {
			p.body = text.substr(bodyIndex)
			var closingIndex = p.body.indexOf('</body')
			if (closingIndex > -1) {
				p.body = p.body.substr(0, closingIndex)
			}

			var urlWithoutHash = removeHash(p.url)
			pHistory[urlWithoutHash] = {
				body: p.body,
				title: p.title,
				scrollY: urlWithoutHash in pHistory ? pHistory[urlWithoutHash].scrollY : 0
			}
		}
		else {
			p.hasBody = false
		}

		if (p.isWaitingForCompletion) {
			p.isWaitingForCompletion = false
			display(p.url)
		}
	}

	////////// MAIN FUNCTIONS //////////

	function instantanize(isInitializing) {
		var as = document.getElementsByTagName('a'), a, domain = location.protocol + '//' + location.host
		for (var i = as.length - 1; i >= 0; i--) {
			a = as[i]
			if (a.target || // target="_blank" etc.
				a.hasAttribute('download') ||
				a.href.indexOf(domain + '/') != 0 || // another domain (or no href attribute)
				a.href.indexOf('#') > -1 && removeHash(a.href) == currentLocationWithoutHash || // link to an anchor
				(useBlacklist ? a.hasAttribute('data-no-instant') : !a.hasAttribute('data-instant'))) {
				continue
			}
			if (preloadOnMousedown) {
				a.addEventListener('mousedown', mousedown)
			}
			else {
				a.addEventListener('mouseover', mouseover)
			}
			a.addEventListener('click', click)
		}
		if (!isInitializing) {
			var scripts = document.getElementsByTagName('script'), script, copy, parentNode, nextSibling
			for (i = 0, j = scripts.length; i < j; i++) {
				script = scripts[i]
				if (script.hasAttribute('data-no-instant')) {
					continue
				}
				copy = document.createElement('script')
				if (script.src) {
					copy.src = script.src
				}
				if (script.innerHTML) {
					copy.innerHTML = script.innerHTML
				}
				parentNode = script.parentNode
				nextSibling = script.nextSibling
				parentNode.removeChild(script)
				parentNode.insertBefore(copy, nextSibling)
			}
		}
		triggerPageEvent('change')
	}

	function preload(url) {
		if (!preloadOnMousedown && 'display' in p.timing && +new Date - (p.timing.start + p.timing.display) < 100) {
			/* After a page is displayed, if the user's cursor happens to be above a link
			   a mouseover event will be in most browsers triggered automatically, and in
			   other browsers it will be triggered when the user moves his mouse by 1px.

			   Here are the behavior I noticed, all on Windows:
			   - Safari 5.1: auto-triggers after 0 ms
			   - IE 11: auto-triggers after 30-80 ms (looks like it depends on page's size)
			   - Firefox: auto-triggers after 10 ms
			   - Opera 18: auto-triggers after 10 ms

			   - Chrome: triggers when cursor moved
			   - Opera 12.16: triggers when cursor moved

			   To remedy to this, we do not start preloading if last display occured less than
			   100 ms ago. If they happen to click on the link, they will be redirected.
			*/

			return
		}
		if (preloadTimer) {
			clearTimeout(preloadTimer)
			preloadTimer = false
		}

		if (!url) {
			url = urlToPreload
		}

		if ((p.isPreloading && url == p.url) || (p.isPreloading && p.isWaitingForCompletion)) {
			return
		}
		p.isPreloading = true
		p.isWaitingForCompletion = false

		p.url = url
		p.body = false
		p.hasBody = true
		p.timing = {}
		p.timing.start = +new Date
		p.xhr.open('GET', url)
		p.xhr.send()
	}

	function display(url) {
		if (!('display' in p.timing)) {
			p.timing.display = +new Date - p.timing.start
		}
		if (preloadTimer) {
			/* Happens when there’s a delay before preloading and that delay
			   hasn't expired (preloading didn't kick in).
			*/

			if (p.url && p.url != url) {
				/* Happens when the user clicks on a link before preloading
				   kicks in while another link is already preloading.
				*/

				location.href = url
				return
			}
			preload(url)
			p.isWaitingForCompletion = true
			return
		}
		if (!p.isPreloading || (p.isPreloading && p.isWaitingForCompletion)) {
			/* If the page isn't preloaded, it likely means
			   the user has focused on a link (with his Tab
			   key) and then pressed Return, which triggered a click.
			   Because very few people do this, it isn't worth handling this
			   case and preloading on focus (also, focussing on a link
			   doesn't mean it's likely that you'll "click" on it), so we just
			   redirect them when they "click".
			   It could also mean the user hovered over a link less than 100 ms
			   after a page display, thus we didn't start the preload (see
			   comments in `preload()` for the rationale behind this.)

			   If the page is waiting for completion, the user clicked twice
			   while the page was preloading.
			   Two possibilities:
			   1) He clicks on the same link again, either because it's slow
			      to load (there's no browser loading indicator with
			      InstantClick, so he might think his click hasn't registered
			      if the page isn't loading fast enough) or because he has
			      a habit of double clicking on the web;
			   2) He clicks on another link.

			   In the first case, we redirect him (send him to the page the old
			   way) so that he can have the browser's loading indicator back.
			   In the second case, we redirect him because we haven't preloaded
			   that link, since we were already preloading the last one.

			   Determining if it's a double click might be overkill as there is
			   (hopefully) not that many people that double click on the web.
			   Fighting against the perception that the page is stuck is
			   interesting though, a seemingly good way to do that would be to
			   later incorporate a progress bar.
			*/

			location.href = url
			return
		}
		if (!p.hasBody) {
			location.href = p.url
			return
		}
		if (!p.body) {
			p.isWaitingForCompletion = true
			return
		}
		pHistory[currentLocationWithoutHash].scrollY = pageYOffset
		p.isPreloading = false
		p.isWaitingForCompletion = false
		changePage(p.title, p.body)
		var hashIndex = p.url.indexOf('#')
		var hashElem = hashIndex > -1 && document.getElementById(p.url.substr(hashIndex + 1))
		var offset = 0
		if (p.url != location.href && hashElem) {
			for (; hashElem.offsetParent; hashElem = hashElem.offsetParent) {
				offset += hashElem.offsetTop
			}
		}
		scrollTo(0, offset)
		history.pushState(null, null, p.url)
		currentLocationWithoutHash = removeHash(location.href)
		instantanize()
	}

	////////// PUBLIC FUNCTIONS AND VARIABLE //////////

	var supported = 'pushState' in history

	function init() {
		if (!supported) {
			triggerPageEvent('change')
			return
		}
		if (currentLocationWithoutHash) { // Already initialized
			return
		}
		for (var i = 0; i < arguments.length; i++) {
			var arg = arguments[i]
			if (arg === true) {
				useBlacklist = true
			}
			else if (arg == 'mousedown') {
				preloadOnMousedown = true
			}
			else if (typeof arg == 'number') {
				delayBeforePreload = arg
			}
		}
		currentLocationWithoutHash = removeHash(location.href)
		pHistory[currentLocationWithoutHash] = {
			body: document.body.outerHTML,
			title: document.title,
			scrollY: pageYOffset
		}
		p.xhr = new XMLHttpRequest()
		p.xhr.addEventListener('readystatechange', readystatechange)
		p.url = false
		p.body = false
		p.hasBody = true
		p.title = false
		p.isPreloading = false
		p.isWaitingForCompletion = false
		p.timing = {}
		instantanize(true)

		addEventListener('popstate', function() {
			var loc = removeHash(location.href)
			if (loc == currentLocationWithoutHash) {
				return
			}
			if (!(loc in pHistory)) {
				location.href = location.href // Reloads the page and makes use of cache for assets, unlike location.reload()
				return
			}
			pHistory[currentLocationWithoutHash].scrollY = pageYOffset

			currentLocationWithoutHash = loc
			changePage(pHistory[loc].title, pHistory[loc].body)
			scrollTo(0, pHistory[loc].scrollY)
			instantanize()
		})
	}

	function on(type, listener) {
		// Add a function that will be executed with `triggerPageEvent`
		listeners[type].push(listener)
	}

	function debug() {
		return {
			currentLocationWithoutHash: currentLocationWithoutHash,
			p: p,
			pHistory: pHistory,
			supported: supported,
			useBlacklist: useBlacklist
		}
	}

	////////////////////

	return {
		supported: supported,
		init: init,
		on: on,
		debug: debug
	}

}(document, location);
<commit_msg>Blacklisting is now the default.<commit_after>/* InstantClick 2.0 | (C) 2014 Alexandre Dieulot | http://instantclick.io/license.html */
var InstantClick = function(document, location) {
	var currentLocationWithoutHash
	var urlToPreload
	var preloadTimer

	var pHistory = {} // short for "preloadHistory"
	var p = {} // short for "preloads"

	var useBlacklist = true
	var preloadOnMousedown
	var delayBeforePreload
	var listeners = {change: []}

	////////// HELPERS //////////

	function removeHash(url) {
		var index = url.indexOf('#')
		if (index == -1) {
			return url
		}
		return url.substr(0, index)
	}

	function getLinkTarget(target) {
		while (target.nodeName != 'A') {
			target = target.parentNode
		}
		return target
	}

	function triggerPageEvent(type) {
		for (var i = 0; i < listeners[type].length; i++) {
			listeners[type][i]()
		}
	}

	function changePage(title, body) {
		var doc = document.implementation.createHTMLDocument('')
		doc.documentElement.innerHTML = body
		document.documentElement.replaceChild(doc.body, document.body)

		var elem = document.createElement('i')
		elem.innerHTML = title
		document.title = elem.textContent
	}

	////////// EVENT HANDLERS //////////

	function mousedown(e) {
		preload(getLinkTarget(e.target).href)
	}

	function mouseover(e) {
		var a = getLinkTarget(e.target)
		a.addEventListener('mouseout', mouseout)

		if (!delayBeforePreload) {
			preload(a.href)
		}
		else {
			urlToPreload = a.href
			preloadTimer = setTimeout(preload, delayBeforePreload)
		}
	}

	function click(e) {
		if (e.which > 1 || e.metaKey || e.ctrlKey) { // Opening in new tab
			return
		}
		e.preventDefault()
		display(getLinkTarget(e.target).href)
	}

	function mouseout() {
		if (preloadTimer) {
			clearTimeout(preloadTimer)
			preloadTimer = false
			return
		}

		if (!p.isPreloading || (p.isPreloading && p.isWaitingForCompletion)) {
			return
		}
		p.xhr.abort()
		p.isPreloading = false
		p.isWaitingForCompletion = false
	}

	function readystatechange(e) {
		if (p.xhr.readyState < 4) {
			return
		}
		if (p.xhr.status == 0) { // Aborted
			return
		}

		p.timing.ready = +new Date - p.timing.start

		var text = p.xhr.responseText

		var titleIndex = text.indexOf('<title')
		if (titleIndex > -1) {
			p.title = text.substr(text.indexOf('>', titleIndex) + 1)
			p.title = p.title.substr(0, p.title.indexOf('</title'))
		}

		var bodyIndex = text.indexOf('<body')
		if (bodyIndex > -1) {
			p.body = text.substr(bodyIndex)
			var closingIndex = p.body.indexOf('</body')
			if (closingIndex > -1) {
				p.body = p.body.substr(0, closingIndex)
			}

			var urlWithoutHash = removeHash(p.url)
			pHistory[urlWithoutHash] = {
				body: p.body,
				title: p.title,
				scrollY: urlWithoutHash in pHistory ? pHistory[urlWithoutHash].scrollY : 0
			}
		}
		else {
			p.hasBody = false
		}

		if (p.isWaitingForCompletion) {
			p.isWaitingForCompletion = false
			display(p.url)
		}
	}

	////////// MAIN FUNCTIONS //////////

	function instantanize(isInitializing) {
		var as = document.getElementsByTagName('a'), a, domain = location.protocol + '//' + location.host
		for (var i = as.length - 1; i >= 0; i--) {
			a = as[i]
			if (a.target || // target="_blank" etc.
				a.hasAttribute('download') ||
				a.href.indexOf(domain + '/') != 0 || // another domain (or no href attribute)
				a.href.indexOf('#') > -1 && removeHash(a.href) == currentLocationWithoutHash || // link to an anchor
				(useBlacklist ? a.hasAttribute('data-no-instant') : !a.hasAttribute('data-instant'))) {
				continue
			}
			if (preloadOnMousedown) {
				a.addEventListener('mousedown', mousedown)
			}
			else {
				a.addEventListener('mouseover', mouseover)
			}
			a.addEventListener('click', click)
		}
		if (!isInitializing) {
			var scripts = document.getElementsByTagName('script'), script, copy, parentNode, nextSibling
			for (i = 0, j = scripts.length; i < j; i++) {
				script = scripts[i]
				if (script.hasAttribute('data-no-instant')) {
					continue
				}
				copy = document.createElement('script')
				if (script.src) {
					copy.src = script.src
				}
				if (script.innerHTML) {
					copy.innerHTML = script.innerHTML
				}
				parentNode = script.parentNode
				nextSibling = script.nextSibling
				parentNode.removeChild(script)
				parentNode.insertBefore(copy, nextSibling)
			}
		}
		triggerPageEvent('change')
	}

	function preload(url) {
		if (!preloadOnMousedown && 'display' in p.timing && +new Date - (p.timing.start + p.timing.display) < 100) {
			/* After a page is displayed, if the user's cursor happens to be above a link
			   a mouseover event will be in most browsers triggered automatically, and in
			   other browsers it will be triggered when the user moves his mouse by 1px.

			   Here are the behavior I noticed, all on Windows:
			   - Safari 5.1: auto-triggers after 0 ms
			   - IE 11: auto-triggers after 30-80 ms (looks like it depends on page's size)
			   - Firefox: auto-triggers after 10 ms
			   - Opera 18: auto-triggers after 10 ms

			   - Chrome: triggers when cursor moved
			   - Opera 12.16: triggers when cursor moved

			   To remedy to this, we do not start preloading if last display occured less than
			   100 ms ago. If they happen to click on the link, they will be redirected.
			*/

			return
		}
		if (preloadTimer) {
			clearTimeout(preloadTimer)
			preloadTimer = false
		}

		if (!url) {
			url = urlToPreload
		}

		if ((p.isPreloading && url == p.url) || (p.isPreloading && p.isWaitingForCompletion)) {
			return
		}
		p.isPreloading = true
		p.isWaitingForCompletion = false

		p.url = url
		p.body = false
		p.hasBody = true
		p.timing = {}
		p.timing.start = +new Date
		p.xhr.open('GET', url)
		p.xhr.send()
	}

	function display(url) {
		if (!('display' in p.timing)) {
			p.timing.display = +new Date - p.timing.start
		}
		if (preloadTimer) {
			/* Happens when there’s a delay before preloading and that delay
			   hasn't expired (preloading didn't kick in).
			*/

			if (p.url && p.url != url) {
				/* Happens when the user clicks on a link before preloading
				   kicks in while another link is already preloading.
				*/

				location.href = url
				return
			}
			preload(url)
			p.isWaitingForCompletion = true
			return
		}
		if (!p.isPreloading || (p.isPreloading && p.isWaitingForCompletion)) {
			/* If the page isn't preloaded, it likely means
			   the user has focused on a link (with his Tab
			   key) and then pressed Return, which triggered a click.
			   Because very few people do this, it isn't worth handling this
			   case and preloading on focus (also, focussing on a link
			   doesn't mean it's likely that you'll "click" on it), so we just
			   redirect them when they "click".
			   It could also mean the user hovered over a link less than 100 ms
			   after a page display, thus we didn't start the preload (see
			   comments in `preload()` for the rationale behind this.)

			   If the page is waiting for completion, the user clicked twice
			   while the page was preloading.
			   Two possibilities:
			   1) He clicks on the same link again, either because it's slow
			      to load (there's no browser loading indicator with
			      InstantClick, so he might think his click hasn't registered
			      if the page isn't loading fast enough) or because he has
			      a habit of double clicking on the web;
			   2) He clicks on another link.

			   In the first case, we redirect him (send him to the page the old
			   way) so that he can have the browser's loading indicator back.
			   In the second case, we redirect him because we haven't preloaded
			   that link, since we were already preloading the last one.

			   Determining if it's a double click might be overkill as there is
			   (hopefully) not that many people that double click on the web.
			   Fighting against the perception that the page is stuck is
			   interesting though, a seemingly good way to do that would be to
			   later incorporate a progress bar.
			*/

			location.href = url
			return
		}
		if (!p.hasBody) {
			location.href = p.url
			return
		}
		if (!p.body) {
			p.isWaitingForCompletion = true
			return
		}
		pHistory[currentLocationWithoutHash].scrollY = pageYOffset
		p.isPreloading = false
		p.isWaitingForCompletion = false
		changePage(p.title, p.body)
		var hashIndex = p.url.indexOf('#')
		var hashElem = hashIndex > -1 && document.getElementById(p.url.substr(hashIndex + 1))
		var offset = 0
		if (p.url != location.href && hashElem) {
			for (; hashElem.offsetParent; hashElem = hashElem.offsetParent) {
				offset += hashElem.offsetTop
			}
		}
		scrollTo(0, offset)
		history.pushState(null, null, p.url)
		currentLocationWithoutHash = removeHash(location.href)
		instantanize()
	}

	////////// PUBLIC FUNCTIONS AND VARIABLE //////////

	var supported = 'pushState' in history

	function init() {
		if (!supported) {
			triggerPageEvent('change')
			return
		}
		if (currentLocationWithoutHash) { // Already initialized
			return
		}
		for (var i = 0; i < arguments.length; i++) {
			var arg = arguments[i]
			if (arg === true) {
				useBlacklist = false
			}
			else if (arg == 'mousedown') {
				preloadOnMousedown = true
			}
			else if (typeof arg == 'number') {
				delayBeforePreload = arg
			}
		}
		currentLocationWithoutHash = removeHash(location.href)
		pHistory[currentLocationWithoutHash] = {
			body: document.body.outerHTML,
			title: document.title,
			scrollY: pageYOffset
		}
		p.xhr = new XMLHttpRequest()
		p.xhr.addEventListener('readystatechange', readystatechange)
		p.url = false
		p.body = false
		p.hasBody = true
		p.title = false
		p.isPreloading = false
		p.isWaitingForCompletion = false
		p.timing = {}
		instantanize(true)

		addEventListener('popstate', function() {
			var loc = removeHash(location.href)
			if (loc == currentLocationWithoutHash) {
				return
			}
			if (!(loc in pHistory)) {
				location.href = location.href // Reloads the page and makes use of cache for assets, unlike location.reload()
				return
			}
			pHistory[currentLocationWithoutHash].scrollY = pageYOffset

			currentLocationWithoutHash = loc
			changePage(pHistory[loc].title, pHistory[loc].body)
			scrollTo(0, pHistory[loc].scrollY)
			instantanize()
		})
	}

	function on(type, listener) {
		// Add a function that will be executed with `triggerPageEvent`
		listeners[type].push(listener)
	}

	function debug() {
		return {
			currentLocationWithoutHash: currentLocationWithoutHash,
			p: p,
			pHistory: pHistory,
			supported: supported,
			useBlacklist: useBlacklist
		}
	}

	////////////////////

	return {
		supported: supported,
		init: init,
		on: on,
		debug: debug
	}

}(document, location);
<|endoftext|>


<commit_before>/**
 *	@author zz85 / http://twitter.com/blurspline / http://www.lab4games.net/zz85/blog
 *
 *	A general perpose camera, for setting FOV, Lens Focal Length,
 *		and switching between perspective and orthographic views easily.
 *		Use this only if you do not wish to manage
 *		both a Orthographic and Perspective Camera
 *
 */

THREE.CombinedCamera = function ( width, height, fov, near, far, orthoNear, orthoFar ) {

	THREE.Camera.call( this );

	this.fov = fov;

	this.left = -width / 2;
	this.right = width / 2;
	this.top = height / 2;
	this.bottom = -height / 2;

	// We could also handle the projectionMatrix internally, but just wanted to test nested camera objects

	this.cameraO = new THREE.OrthographicCamera( width / - 2, width / 2, height / 2, height / - 2, 	orthoNear, orthoFar );
	this.cameraP = new THREE.PerspectiveCamera( fov, width / height, near, far );

	this.zoom = 1;

	this.toPerspective();

	var aspect = width / height;

};

THREE.CombinedCamera.prototype = Object.create( THREE.Camera.prototype );
THREE.CombinedCamera.prototype.constructor = THREE.CombinedCamera;

THREE.CombinedCamera.prototype.toPerspective = function () {

	// Switches to the Perspective Camera

	this.near = this.cameraP.near;
	this.far = this.cameraP.far;

	this.cameraP.fov =  this.fov / this.zoom ;

	this.cameraP.updateProjectionMatrix();

	this.projectionMatrix = this.cameraP.projectionMatrix;

	this.inPerspectiveMode = true;
	this.inOrthographicMode = false;

};

THREE.CombinedCamera.prototype.toOrthographic = function () {

	// Switches to the Orthographic camera estimating viewport from Perspective

	var fov = this.fov;
	var aspect = this.cameraP.aspect;
	var near = this.cameraP.near;
	var far = this.cameraP.far;

	// The size that we set is the mid plane of the viewing frustum

	var hyperfocus = ( near + far ) / 2;

	var halfHeight = Math.tan( fov * Math.PI / 180 / 2 ) * hyperfocus;
	var planeHeight = 2 * halfHeight;
	var planeWidth = planeHeight * aspect;
	var halfWidth = planeWidth / 2;

	halfHeight /= this.zoom;
	halfWidth /= this.zoom;

	this.cameraO.left = -halfWidth;
	this.cameraO.right = halfWidth;
	this.cameraO.top = halfHeight;
	this.cameraO.bottom = -halfHeight;

	// this.cameraO.left = -farHalfWidth;
	// this.cameraO.right = farHalfWidth;
	// this.cameraO.top = farHalfHeight;
	// this.cameraO.bottom = -farHalfHeight;

	// this.cameraO.left = this.left / this.zoom;
	// this.cameraO.right = this.right / this.zoom;
	// this.cameraO.top = this.top / this.zoom;
	// this.cameraO.bottom = this.bottom / this.zoom;

	this.cameraO.updateProjectionMatrix();

	this.near = this.cameraO.near;
	this.far = this.cameraO.far;
	this.projectionMatrix = this.cameraO.projectionMatrix;

	this.inPerspectiveMode = false;
	this.inOrthographicMode = true;

};

THREE.CombinedCamera.prototype.setSize = function( width, height ) {

	this.cameraP.aspect = width / height;
	this.left = -width / 2;
	this.right = width / 2;
	this.top = height / 2;
	this.bottom = -height / 2;

};

THREE.CombinedCamera.prototype.setFov = function( fov ) {

	this.fov = fov;

	if ( this.inPerspectiveMode ) {

		this.toPerspective();

	} else {

		this.toOrthographic();

	}

};

// For mantaining similar API with PerspectiveCamera

THREE.CombinedCamera.prototype.updateProjectionMatrix = function() {

	if ( this.inPerspectiveMode ) {

		this.toPerspective();

	} else {

		this.toPerspective();
		this.toOrthographic();

	}

};

/*
* Uses Focal Length (in mm) to estimate and set FOV
* 35mm (fullframe) camera is used if frame size is not specified;
* Formula based on http://www.bobatkins.com/photography/technical/field_of_view.html
*/
THREE.CombinedCamera.prototype.setLens = function ( focalLength, frameHeight ) {

	if ( frameHeight === undefined ) frameHeight = 24;

	var fov = 2 * THREE.Math.radToDeg( Math.atan( frameHeight / ( focalLength * 2 ) ) );

	this.setFov( fov );

	return fov;
};

THREE.CombinedCamera.prototype.setZoom = function( zoom ) {

	this.zoom = zoom;

	if ( this.inPerspectiveMode ) {

		this.toPerspective();

	} else {

		this.toOrthographic();

	}

};

THREE.CombinedCamera.prototype.toFrontView = function() {

	this.rotation.x = 0;
	this.rotation.y = 0;
	this.rotation.z = 0;

	// should we be modifing the matrix instead?

	this.rotationAutoUpdate = false;

};

THREE.CombinedCamera.prototype.toBackView = function() {

	this.rotation.x = 0;
	this.rotation.y = Math.PI;
	this.rotation.z = 0;
	this.rotationAutoUpdate = false;

};

THREE.CombinedCamera.prototype.toLeftView = function() {

	this.rotation.x = 0;
	this.rotation.y = - Math.PI / 2;
	this.rotation.z = 0;
	this.rotationAutoUpdate = false;

};

THREE.CombinedCamera.prototype.toRightView = function() {

	this.rotation.x = 0;
	this.rotation.y = Math.PI / 2;
	this.rotation.z = 0;
	this.rotationAutoUpdate = false;

};

THREE.CombinedCamera.prototype.toTopView = function() {

	this.rotation.x = - Math.PI / 2;
	this.rotation.y = 0;
	this.rotation.z = 0;
	this.rotationAutoUpdate = false;

};

THREE.CombinedCamera.prototype.toBottomView = function() {

	this.rotation.x = Math.PI / 2;
	this.rotation.y = 0;
	this.rotation.z = 0;
	this.rotationAutoUpdate = false;

};
<commit_msg>Fix comment typo<commit_after>/**
 *	@author zz85 / http://twitter.com/blurspline / http://www.lab4games.net/zz85/blog
 *
 *	A general perpose camera, for setting FOV, Lens Focal Length,
 *		and switching between perspective and orthographic views easily.
 *		Use this only if you do not wish to manage
 *		both a Orthographic and Perspective Camera
 *
 */

THREE.CombinedCamera = function ( width, height, fov, near, far, orthoNear, orthoFar ) {

	THREE.Camera.call( this );

	this.fov = fov;

	this.left = -width / 2;
	this.right = width / 2;
	this.top = height / 2;
	this.bottom = -height / 2;

	// We could also handle the projectionMatrix internally, but just wanted to test nested camera objects

	this.cameraO = new THREE.OrthographicCamera( width / - 2, width / 2, height / 2, height / - 2, 	orthoNear, orthoFar );
	this.cameraP = new THREE.PerspectiveCamera( fov, width / height, near, far );

	this.zoom = 1;

	this.toPerspective();

	var aspect = width / height;

};

THREE.CombinedCamera.prototype = Object.create( THREE.Camera.prototype );
THREE.CombinedCamera.prototype.constructor = THREE.CombinedCamera;

THREE.CombinedCamera.prototype.toPerspective = function () {

	// Switches to the Perspective Camera

	this.near = this.cameraP.near;
	this.far = this.cameraP.far;

	this.cameraP.fov =  this.fov / this.zoom ;

	this.cameraP.updateProjectionMatrix();

	this.projectionMatrix = this.cameraP.projectionMatrix;

	this.inPerspectiveMode = true;
	this.inOrthographicMode = false;

};

THREE.CombinedCamera.prototype.toOrthographic = function () {

	// Switches to the Orthographic camera estimating viewport from Perspective

	var fov = this.fov;
	var aspect = this.cameraP.aspect;
	var near = this.cameraP.near;
	var far = this.cameraP.far;

	// The size that we set is the mid plane of the viewing frustum

	var hyperfocus = ( near + far ) / 2;

	var halfHeight = Math.tan( fov * Math.PI / 180 / 2 ) * hyperfocus;
	var planeHeight = 2 * halfHeight;
	var planeWidth = planeHeight * aspect;
	var halfWidth = planeWidth / 2;

	halfHeight /= this.zoom;
	halfWidth /= this.zoom;

	this.cameraO.left = -halfWidth;
	this.cameraO.right = halfWidth;
	this.cameraO.top = halfHeight;
	this.cameraO.bottom = -halfHeight;

	// this.cameraO.left = -farHalfWidth;
	// this.cameraO.right = farHalfWidth;
	// this.cameraO.top = farHalfHeight;
	// this.cameraO.bottom = -farHalfHeight;

	// this.cameraO.left = this.left / this.zoom;
	// this.cameraO.right = this.right / this.zoom;
	// this.cameraO.top = this.top / this.zoom;
	// this.cameraO.bottom = this.bottom / this.zoom;

	this.cameraO.updateProjectionMatrix();

	this.near = this.cameraO.near;
	this.far = this.cameraO.far;
	this.projectionMatrix = this.cameraO.projectionMatrix;

	this.inPerspectiveMode = false;
	this.inOrthographicMode = true;

};

THREE.CombinedCamera.prototype.setSize = function( width, height ) {

	this.cameraP.aspect = width / height;
	this.left = -width / 2;
	this.right = width / 2;
	this.top = height / 2;
	this.bottom = -height / 2;

};

THREE.CombinedCamera.prototype.setFov = function( fov ) {

	this.fov = fov;

	if ( this.inPerspectiveMode ) {

		this.toPerspective();

	} else {

		this.toOrthographic();

	}

};

// For maintaining similar API with PerspectiveCamera

THREE.CombinedCamera.prototype.updateProjectionMatrix = function() {

	if ( this.inPerspectiveMode ) {

		this.toPerspective();

	} else {

		this.toPerspective();
		this.toOrthographic();

	}

};

/*
* Uses Focal Length (in mm) to estimate and set FOV
* 35mm (fullframe) camera is used if frame size is not specified;
* Formula based on http://www.bobatkins.com/photography/technical/field_of_view.html
*/
THREE.CombinedCamera.prototype.setLens = function ( focalLength, frameHeight ) {

	if ( frameHeight === undefined ) frameHeight = 24;

	var fov = 2 * THREE.Math.radToDeg( Math.atan( frameHeight / ( focalLength * 2 ) ) );

	this.setFov( fov );

	return fov;
};

THREE.CombinedCamera.prototype.setZoom = function( zoom ) {

	this.zoom = zoom;

	if ( this.inPerspectiveMode ) {

		this.toPerspective();

	} else {

		this.toOrthographic();

	}

};

THREE.CombinedCamera.prototype.toFrontView = function() {

	this.rotation.x = 0;
	this.rotation.y = 0;
	this.rotation.z = 0;

	// should we be modifing the matrix instead?

	this.rotationAutoUpdate = false;

};

THREE.CombinedCamera.prototype.toBackView = function() {

	this.rotation.x = 0;
	this.rotation.y = Math.PI;
	this.rotation.z = 0;
	this.rotationAutoUpdate = false;

};

THREE.CombinedCamera.prototype.toLeftView = function() {

	this.rotation.x = 0;
	this.rotation.y = - Math.PI / 2;
	this.rotation.z = 0;
	this.rotationAutoUpdate = false;

};

THREE.CombinedCamera.prototype.toRightView = function() {

	this.rotation.x = 0;
	this.rotation.y = Math.PI / 2;
	this.rotation.z = 0;
	this.rotationAutoUpdate = false;

};

THREE.CombinedCamera.prototype.toTopView = function() {

	this.rotation.x = - Math.PI / 2;
	this.rotation.y = 0;
	this.rotation.z = 0;
	this.rotationAutoUpdate = false;

};

THREE.CombinedCamera.prototype.toBottomView = function() {

	this.rotation.x = Math.PI / 2;
	this.rotation.y = 0;
	this.rotation.z = 0;
	this.rotationAutoUpdate = false;

};
<|endoftext|>


<commit_before>function $todo(msg){
	return function(){
		air.trace(msg);
	};
};

var Database = new Class({

	Implements: [Events, Options],

	options: {
		file: 'database.sqlite'
	},

	initialize: function(options){
		this.setOptions(options);
		var file = air.File.applicationDirectory.resolvePath(this.options.file);
		this.connection = new air.SQLConnection();
		this.connection.addEventListener('open', this.onOpen.bind(this));
		this.connection.addEventListener('error', this.onError.bind(this));
		this.connection.openAsync(file);
	},

	prepare: function(text, options){
		return new Query(this, text, options);
	},

	onOpen: function(event){
		this.fireEvent('connect', event);
	},

	onError: function(event){
		this.fireEvent('error', event);
	}

});

/*

Example:

var createUser = new Query(db, "INSERT INTO users(nick, name) VALUES (:nick, :name)");
createUser.execute({nick: 'JanK', name: 'Jan Kassens'});
createUser.execute({nick: 'tomocchino', name: 'Tom Occhino'});

*/

var Query = new Class({

	Implements: [Events, Options],

	options: {
	},

	initialize: function(database, text, options){
		this.setOptions(options);
		var statement = new air.SQLStatement();
		statement.addEventListener('error', this.onError.bind(this));
		statement.addEventListener('result', this.onResult.bind(this));
		statement.sqlConnection = database.connection;
		statement.text = text;
		this.statement = statement;
	},

	execute: function(parameters){
		var statement = this.statement;
		statement.clearParameters();
		if ($type(parameters) == 'object'){
			Hash.each(parameters, function(value, key){
				statement.parameters[':' + key] = value;
			});
		} else {
			Array.flatten(arguments).each(function(value, key){
				statement.parameters[key] = value;
			});
		}
		this.statement.execute();
		return this;
	},

	onResult: function(event){
		this.fireEvent('result', this.statement.getResult().data);
	},

	onError: function(event){
		this.fireEvent('error', event);
	}

});
<commit_msg>removing  function<commit_after>var Database = new Class({

	Implements: [Events, Options],

	options: {
		file: 'database.sqlite'
	},

	initialize: function(options){
		this.setOptions(options);
		var file = air.File.applicationDirectory.resolvePath(this.options.file);
		this.connection = new air.SQLConnection();
		this.connection.addEventListener('open', this.onOpen.bind(this));
		this.connection.addEventListener('error', this.onError.bind(this));
		this.connection.openAsync(file);
	},

	prepare: function(text, options){
		return new Query(this, text, options);
	},

	onOpen: function(event){
		this.fireEvent('connect', event);
	},

	onError: function(event){
		this.fireEvent('error', event);
	}

});

/*

Example:

var createUser = new Query(db, "INSERT INTO users(nick, name) VALUES (:nick, :name)");
createUser.execute({nick: 'JanK', name: 'Jan Kassens'});
createUser.execute({nick: 'tomocchino', name: 'Tom Occhino'});

*/

var Query = new Class({

	Implements: [Events, Options],

	options: {
	},

	initialize: function(database, text, options){
		this.setOptions(options);
		var statement = new air.SQLStatement();
		statement.addEventListener('error', this.onError.bind(this));
		statement.addEventListener('result', this.onResult.bind(this));
		statement.sqlConnection = database.connection;
		statement.text = text;
		this.statement = statement;
	},

	execute: function(parameters){
		var statement = this.statement;
		statement.clearParameters();
		if ($type(parameters) == 'object'){
			Hash.each(parameters, function(value, key){
				statement.parameters[':' + key] = value;
			});
		} else {
			Array.flatten(arguments).each(function(value, key){
				statement.parameters[key] = value;
			});
		}
		this.statement.execute();
		return this;
	},

	onResult: function(event){
		this.fireEvent('result', this.statement.getResult().data);
	},

	onError: function(event){
		this.fireEvent('error', event);
	}

});
<|endoftext|>


<commit_before>
var primitives = require('./primitives');
var S = primitives.S,
    K = primitives.K,
    HashSymbol = primitives.HashSymbol;

function Reader (stream) {
    this.stream = stream;
}
exports.Reader = Reader;

Reader.prototype.read = function () {
    this.stream.skipWhitespace();
    if (!this.stream.eof()) {
	switch (this.stream.peekChar()) {
	case ';':
	    this.stream.skipLine();
	    return this.read();
	case '"':
	    return this.readString();
	case '(':
	    return this.readList();
	default:
	    return this.readAtom();
	}
    }
}

var hexNumberExpression = /^0x[0-9a-f]+/i;
var octalNumberExpression = /^0[0-7]+/;
var decimalNumberExpression = /^\d+\.?\d*(?:e-?\d*(?:\d\.?|\.?\d)\d*)?/i;

Reader.prototype.readAtom = function () {
    var c = this.stream.peekChar();
    var rest = this.stream.rest()
    if ([hexNumberExpression,
	 octalNumberExpression,
	 decimalNumberExpression]
	.some(function (expression) {
	    var match = expression.exec(rest);
	    return match && match[0] != '';
	}))
    {
	return this.readNumber();
    } else
	return this.readSymbol();
}

Reader.prototype.readList = function () {
    var result = new Array();
    this.stream.readChar();
    this.stream.skipWhitespace();

    while (this.stream.peekChar() != ')') {
	if (this.stream.eof())
	    throw new Error('Unbalanced parens');
	if (this.stream.peekChar() == ';')
	    this.stream.skipLine();
	else {
	    var next = this.read();
	    result.push(next);
	}
	this.stream.skipWhitespace();
    }

    this.stream.readChar();
    return result;
}

Reader.prototype.readSymbol = function () {
    var match = /[^()\n\t ]+/.exec(this.stream.rest());
    var name = match[0];
    this.stream.index += name.length;
    // TODO: keywords
    if (name[0] == '#' && HashSymbol.names.indexOf(name.substring(1)) >= 0)
	return HashSymbol[name.substring(1)];
    else if (name[name.length - 1] == ":")
	return K(name.slice(0, -1).toLowerCase());
    else
	return S(name.toLowerCase());
}

// TODO: escapes in strings: \t, \r, \n

Reader.prototype.readString = function () {
    this.stream.readChar();
    var c, result = "";
    while ((c = this.stream.readChar()) != '"') {
	if (c == '\\')
	    result += this.stream.readChar();
	else
	    result += c;
    }
    return result;
}

Reader.prototype.readNumber = function () {
    var match = /[^()\n\t ]+/.exec(this.stream.rest());
    this.stream.index += match[0].length;
    return new Number(match[0]);
}<commit_msg>escape newlines<commit_after>
var primitives = require('./primitives');
var S = primitives.S,
    K = primitives.K,
    HashSymbol = primitives.HashSymbol;

function Reader (stream) {
    this.stream = stream;
}
exports.Reader = Reader;

Reader.prototype.read = function () {
    this.stream.skipWhitespace();
    if (!this.stream.eof()) {
	switch (this.stream.peekChar()) {
	case ';':
	    this.stream.skipLine();
	    return this.read();
	case '"':
	    return this.readString();
	case '(':
	    return this.readList();
	default:
	    return this.readAtom();
	}
    }
}

var hexNumberExpression = /^0x[0-9a-f]+/i;
var octalNumberExpression = /^0[0-7]+/;
var decimalNumberExpression = /^\d+\.?\d*(?:e-?\d*(?:\d\.?|\.?\d)\d*)?/i;

Reader.prototype.readAtom = function () {
    var c = this.stream.peekChar();
    var rest = this.stream.rest()
    if ([hexNumberExpression,
	 octalNumberExpression,
	 decimalNumberExpression]
	.some(function (expression) {
	    var match = expression.exec(rest);
	    return match && match[0] != '';
	}))
    {
	return this.readNumber();
    } else
	return this.readSymbol();
}

Reader.prototype.readList = function () {
    var result = new Array();
    this.stream.readChar();
    this.stream.skipWhitespace();

    while (this.stream.peekChar() != ')') {
	if (this.stream.eof())
	    throw new Error('Unbalanced parens');
	if (this.stream.peekChar() == ';')
	    this.stream.skipLine();
	else {
	    var next = this.read();
	    result.push(next);
	}
	this.stream.skipWhitespace();
    }

    this.stream.readChar();
    return result;
}

Reader.prototype.readSymbol = function () {
    var match = /[^()\n\t ]+/.exec(this.stream.rest());
    var name = match[0];
    this.stream.index += name.length;
    // TODO: keywords
    if (name[0] == '#' && HashSymbol.names.indexOf(name.substring(1)) >= 0)
	return HashSymbol[name.substring(1)];
    else if (name[name.length - 1] == ":")
	return K(name.slice(0, -1).toLowerCase());
    else
	return S(name.toLowerCase());
}

Reader.prototype.readString = function () {
    this.stream.readChar();
    var c, result = "";
    while ((c = this.stream.readChar()) != '"') {
	if (c == '\\')
	    result += this.stream.readChar();
	else if (c == '\n')
	    result += '\\n\\\n';
	else
	    result += c;
    }
    return result;
}

Reader.prototype.readNumber = function () {
    var match = /[^()\n\t ]+/.exec(this.stream.rest());
    this.stream.index += match[0].length;
    return new Number(match[0]);
}<|endoftext|>


<commit_before>var generator = require('../lib/generator');

generator({
    name: 'messages',
    keywords:['_'],
    source:['./source','./templates'],
    target:'./locale',
    locales:['ru','en','uk']
})(function(){

});
<commit_msg>refactor test<commit_after>var generator = require('../lib/generator');

generator({
    name: 'messages',
    keywords:['_'],
    source:['./source','./templates'],
    target:'./locale',
    locales:['ru','en','uk']
})(function(){

});
<|endoftext|>


<commit_before>module.exports = function(app) {
	app.get('/', function(req, res) {
		res.resnder('index.ejs');
});
}
<commit_msg>Update routes.js<commit_after>module.exports = function(app) {
	app.get('/', function(req, res) {
		res.resender('index.ejs');
});
}
<|endoftext|>


<commit_before>// app/actions/HistoryActionCreators.js

import {
	EDIT_HISTORY_SET,
	END_EDIT_HISTORY_SET,
	UPDATE_HISTORY_FILTER,
	EXPORTING_CSV
} from '../ActionTypes';
import * as GoogleDriveUploader from '../utility/GoogleDriveUploader';
import * as CSVConverter from '../utility/CSVConverter';
import { getHistorySetsChronological } from '../reducers/SetReducer';

import { Alert, Linking } from 'react-native'
import { GoogleSignin } from 'react-native-google-signin';

export const editHistorySet = (setID) => ({ type: EDIT_HISTORY_SET, setID: setID });

export const endEditHistorySet = () => ({ type: END_EDIT_HISTORY_SET });

export const showRemovedData = () => ({ type: UPDATE_HISTORY_FILTER, showRemoved: true });

export const hideRemovedData = () => ({ type: UPDATE_HISTORY_FILTER, showRemoved: false });

const updateIsExportingCSV = (isExportingCSV) => ({ type: EXPORTING_CSV, isExportingCSV: isExportingCSV });

export const exportHistoryCSV = () => (dispatch, getState) => {
	// logged in check
	let state = getState();
	if (state.auth.email === null) {
		Alert.alert('Sign in Required', 'Please sign in via Settings to use this feature.');
		return;
	}

	GoogleSignin.currentUserAsync().then(async (user) => {
		if (user === null) {
			Alert.alert('Error', 'Error exporting CSV. Please try again later.\n\nTip: Is your internet connection working?');
		} else {
			dispatch(updateIsExportingCSV(true));
			try {
				let date = new Date();
				let name = 'OpenBarbell Data -- Exported on ' + date.toLocaleString() + '.csv';
				let state = getState();
				let sets = getHistorySetsChronological(state.sets);
				let csv = CSVConverter.convert(sets);
				console.log("google access token " + user.accessToken);
				await GoogleDriveUploader.upload(user.accessToken, name, csv, (fileID) => {
					dispatch(updateIsExportingCSV(false));
					Linking.openURL('https://drive.google.com/open?id=' + fileID).catch(err => {
						Alert.alert('Upload Succeeded', 'CSV uploaded to your Google Drive!');
					});
				});
			} catch(err) {
				console.log("Error uploading csv file " + typeof err + " " + err);
				if (err.message == 'Insufficient Permission') { // TODO: should do typeof check but it's not working
					Alert.alert('Google Drive Permissions Error', 'Please log out and log in again. This feature requires additional Google Drive permissions.');
				} else {
					Alert.alert('Error', 'Error exporting CSV. Please try again later.\n\nTip: Is your internet connection working?');
				}
				dispatch(updateIsExportingCSV(false));
			}
		}
	})
	.catch((err) => {
		console.log("EXPORT HISTORY ERROR " + err);
	})
	.done();
};
<commit_msg>Tweaked error messages to reflect that not getting currentUserAsync from GoogleSignIn could be for a variety of reasons<commit_after>// app/actions/HistoryActionCreators.js

import {
	EDIT_HISTORY_SET,
	END_EDIT_HISTORY_SET,
	UPDATE_HISTORY_FILTER,
	EXPORTING_CSV
} from '../ActionTypes';
import * as GoogleDriveUploader from '../utility/GoogleDriveUploader';
import * as CSVConverter from '../utility/CSVConverter';
import { getHistorySetsChronological } from '../reducers/SetReducer';

import { Alert, Linking } from 'react-native'
import { GoogleSignin } from 'react-native-google-signin';

export const editHistorySet = (setID) => ({ type: EDIT_HISTORY_SET, setID: setID });

export const endEditHistorySet = () => ({ type: END_EDIT_HISTORY_SET });

export const showRemovedData = () => ({ type: UPDATE_HISTORY_FILTER, showRemoved: true });

export const hideRemovedData = () => ({ type: UPDATE_HISTORY_FILTER, showRemoved: false });

const updateIsExportingCSV = (isExportingCSV) => ({ type: EXPORTING_CSV, isExportingCSV: isExportingCSV });

export const exportHistoryCSV = () => (dispatch, getState) => {
	// logged in check
	let state = getState();
	if (state.auth.email === null) {
		Alert.alert('Sign in Required', 'Please sign in via Settings to use this feature.');
		return;
	}

	GoogleSignin.currentUserAsync().then(async (user) => {
		if (user === null) {
			Alert.alert('Error Exporting CSV', 'Tip: Is your internet connection working?\n\nTip: Try Logging out then logging in again as this feature requires additional Google Drive permissions.');
		} else {
			dispatch(updateIsExportingCSV(true));
			try {
				let date = new Date();
				let name = 'OpenBarbell Data -- Exported on ' + date.toLocaleString() + '.csv';
				let state = getState();
				let sets = getHistorySetsChronological(state.sets);
				let csv = CSVConverter.convert(sets);
				console.log("google access token " + user.accessToken);
				await GoogleDriveUploader.upload(user.accessToken, name, csv, (fileID) => {
					dispatch(updateIsExportingCSV(false));
					Linking.openURL('https://drive.google.com/open?id=' + fileID).catch(err => {
						Alert.alert('Upload Succeeded', 'CSV uploaded to your Google Drive!');
					});
				});
			} catch(err) {
				console.log("Error uploading csv file " + typeof err + " " + err);
				if (err.message == 'Insufficient Permission') { // TODO: should do typeof check but it's not working
					Alert.alert('Google Drive Permissions Error', 'Please log out and log in again. This feature requires additional Google Drive permissions.');
				} else {
					Alert.alert('Error exporting CSV', 'Please try again later.\n\nTip: Is your internet connection working?');
				}
				dispatch(updateIsExportingCSV(false));
			}
		}
	})
	.catch((err) => {
		console.log("EXPORT HISTORY ERROR " + err);
	})
	.done();
};
<|endoftext|>


<commit_before>var spos=0;
var _GET = {};
var close=false;
var load_fl=false;

(function(){
   var get = window.location.href;
   var x = get.indexOf('?');
   var bad = get.lastIndexOf('?');

   if (x != bad){
       get = get.split('');
       get[bad] = '&';
       get = get.join('');
   }

   if (x!=-1){
       var l = get.length;
       get = get.substr(x+1, l-x);
       l = get.split('&');
       x = 0;
       for(var i in l){
           if (l.hasOwnProperty(i)){
               get = l[i].split('=');
               _GET[get[0]] = get[1];
               x++;
           }
       }
   }
})();

var stbEvent = {
    event : 0,
    onBroadcastMessage : function(e){
        console.log(e);
    },
    onMessage : function(e){
        console.log(e);
    }
};

function init_m()
{
    if(load_fl){
    var punktiT={
        "lock":[t('Parental control'),"ico_lock","ico_lock_act","ico_l_lang","g_pass.html"],
        "lang":[t('Localization'),"ico_lang","ico_lang_act","ico_l_lang","g_local.html"],
        "update":[t('Software update'),"ico_reload","ico_reload_act","ico_l_reload","g_update.html"],
        "net_info":[t('Network info'),"ico_netinfo","ico_netinfo_act","ico_l_netinfo","g_netw.html"],
        "video":[t('Video'),"ico_video","ico_video_act","ico_l_video","g_video.html"],
        "audio":[t('Audio'),"ico_audio","ico_audio_act","ico_l_audio","g_audio.html"],
        "playback":[t('Playback'),"ico_video","ico_video_act","ico_l_video","g_play.html"],
        "portal":[t('Portal'),"ico_lang","ico_lang_act","ico_l_lang","g_portal.html"],
        "net":[t('Network'),"ico_net","ico_net_act","ico_l_net","g_nets.html"],
        "advanced":[t('Advanced settings'),"ico_advset","ico_advset_act","ico_l_advset","g_adv.html"],
        "time_shift":[t('Local TimeShift'),"ico_reload","ico_reload_act","ico_l_reload","g_ts.html"],
        "dvb":[t('DVB'),"ico_reboot","ico_reboot_act","ico_l_reboot","g_dvb.html"],
        "servers":[t('Servers'),"ico_server","ico_server_act","ico_l_server","g_serv.html"],
        "dev_info":[t('Device info'),"ico_sysinfo","ico_sysinfo_act","ico_l_sysinfo","g_dev.html"],
        "reload":[t('Reload portal'),"ico_exit","ico_exit_act","ico_l_exit",2],
        "internal_portal":[t('Go to the inner portal'),"ico_switch","ico_switch_act","ico_l_switch",1],
        "reboot":[t('Reboot device'),"ico_reboot","ico_reboot_act","ico_l_reboot",3]
    };

    if (!_GET['dvb_supported_scan_types']){
        delete punktiT.dvb;
    }

    punkti=[];
    var cache=[];
    for(var i=0;i<prof.modules.length;i++){
        if (!_GET['dvb_supported_scan_types'] && prof.modules[i].name == 'dvb'){
            continue;
        }
        var idx = punkti.length;
        punkti[idx]=punktiT[prof.modules[i].name];
        cache[idx]=new Image();
        cache[idx].src="style/"+parent.put+"/"+punkti[idx][1]+'.png';
        cache[idx].src="style/"+parent.put+"/"+punkti[idx][2]+'.png';
    }
    //punkti[-1]=[t('default'),"ico_empty","ico_empty_act",""];
    kol=punkti.length;
    nextMenu('glavnaya.html');
    document.body.style.display="block";
    }
    else setTimeout(function(){init_m()},100);
}

function up_fl(){
    load_fl=true;
}

function nextMenu(urlP)
{
    switch(urlP){
        case 0:
            switch(punkti[vid-1][4])
            {case 1:conf(t("Do you want to go to the inner portal?"),'','stb.Stop();stb.LoadURL("file:///home/web/services.html");stbWebWindow.close();');break;
            case 2:conf(t("Do you want to restart portal?"),'','stb.Stop();stb.LoadURL("file:///home/web/index.html");stbWebWindow.close();');break;
            case 3:conf(t("Device is going to reboot. Are you sure?"),'','stb.ExecAction("reboot")');break;
            default:cont.style.visibility='hidden';cont.src=punkti[vid-1][4];document.getElementById("zagolovok").innerHTML=punkti[vid-1][0];document.getElementById("ico").innerHTML="";break;}break;
        case "glavnaya.html":cont.style.visibility='hidden';cont.src=urlP;document.getElementById("zagolovok").innerHTML=t("Settings");document.getElementById("ico").innerHTML="";break;
        default:cont.style.visibility='hidden';cont.src=urlP;document.getElementById("zagolovok").innerHTML=punkti[vid-1][0];document.getElementById("ico").innerHTML="";break;
    }
}

function onLoad()
{
    stb.EnableVKButton(true);
    document.cookie = "mac=" + escape(parent.stb.GetDeviceMacAddress()) + '; path=/;';
    load({"type":"stb","action":"get_settings_profile"},function(profile){prof=profile;init_m();});
    switch(screen.height)
    {
      case 480:w=623;h=430;a=45;b=5;put=576;break;
      case 576:w=623;h=430;a=45;b=40;put=576;break;
      case 720:w=1142;h=584;a=60;b=50;put=720;break;
      case 1080:w=1142;h=584;a=380;b=230;put=720;break;
    }
    var fileref = document.createElement("link");
    fileref.setAttribute("rel", "stylesheet");
    fileref.setAttribute("type", "text/css");
    fileref.setAttribute("href", 'style/glav_' + put + '.css');
    document.getElementsByTagName("head")[0].appendChild(fileref);
    window.resizeTo(w,h);
    window.moveTo(a,b);
    cont=document.getElementById("cont");
    cont.width=w;
    cont.height=h;
    langv();
}

function erMes(erm,el){
    close=false;
    elem=el;ind=1;maxin=2;
    var d=document.getElementById('confirm');d.style.display="block";
    document.getElementById('b1').focus();
    d.innerHTML='

'+erm+'
<input id="b1" type="button" value="'+t('Ok')+'" onClick="erMbeck()" />
';
    document.getElementById('b1').focus();
}

function erMbeck(){
    if(close){stbWebWindow.close();}
    else {if(spos!=0)document.getElementById('confirmb').style.display="none";
    else document.getElementById('confirm').style.display="none";
    if(elem!='')cont.contentWindow.document.getElementById(elem).focus();
    else cont.focus();}
}

function conf(erm,el,ef,back){
    if(back)close=true;else close=false;
    elem=el;ind=1;maxin=2;
    func=ef;spos=0;
    var d=document.getElementById('confirm');d.style.display="block";
    document.getElementById('b1').focus();
    d.innerHTML='

'+erm+'
<input id="b2" type="button" value="'+t('Cancel')+'" onClick="erMbeck()" /><input id="b1" type="button" value="'+t('Ok')+'" onClick="confOk()" />
';
    document.getElementById('b2').focus();
}

function confb(erm,el,ef,back){
    if(back)close=true;else close=false;
    elem=el;ind=1;maxin=2;
    func=ef;spos=1;
    var d=document.getElementById('confirmb');d.style.display="block";
    document.getElementById('b1b').focus();
    d.innerHTML='

'+erm+'
<input id="b2b" type="button" value="'+t('Cancel')+'" onClick="erMbeck()" /><input id="b1b" type="button" value="'+t('Ok')+'" onClick="confOk()" />
';
    document.getElementById('b2b').focus();
}

function confOk(){
    eval(func);
    if(document.getElementById('confirmb').style.display=="none")document.getElementById('confirm').style.display="none";
    else document.getElementById('confirmb').style.display="none";
}

function pressKey(e)
{
ec = e.keyCode;
switch(ec)
    {
    case 9:e.preventDefault();break;
    case 40:perehod(1);break;
    case 38:perehod(-1);break;
    case 37:perehod(-1);break;
    case 39:perehod(1);break;
    }
}

function perehod(a)
{
    ind+=a;
    if(ind<1)ind=1;else if(ind>maxin)ind=maxin;
    if(spos!=0)document.getElementById('b'+ind+'b').focus();
    else document.getElementById('b'+ind).focus();
}

function load(params, callback){
   JsHttpRequest.query(
       'GET '+_GET.ajax_loader,

       params,

       function(result, errors){
        // errors - содержит ошибки сервера и debug сообщения
        gSTB.Debug(errors);

           callback(result);
       },

       true,
       {"Authorization" : "Bearer "+_GET.token}
   );
}

function auto_fr_save(t){
    var to_af = 0;
    switch(t){
        case "50_60":
            to_af = 6;
            break;
        case "24_50_60":
            to_af = 7;
            break;
        case "24_50":
            to_af = 3;
            break;
        case "24_60":
            to_af = 5;
            break;
    }
    stb.SetAutoFrameRate(to_af);
    var wra='{"auto_framerate":"'+t+'"}';
    stb.SetEnv(wra);
}<commit_msg>Remove unused settings for MAG260 (issue #4474)<commit_after>var spos=0;
var _GET = {};
var close=false;
var load_fl=false;

(function(){
   var get = window.location.href;
   var x = get.indexOf('?');
   var bad = get.lastIndexOf('?');

   if (x != bad){
       get = get.split('');
       get[bad] = '&';
       get = get.join('');
   }

   if (x!=-1){
       var l = get.length;
       get = get.substr(x+1, l-x);
       l = get.split('&');
       x = 0;
       for(var i in l){
           if (l.hasOwnProperty(i)){
               get = l[i].split('=');
               _GET[get[0]] = get[1];
               x++;
           }
       }
   }
})();

var stbEvent = {
    event : 0,
    onBroadcastMessage : function(e){
        console.log(e);
    },
    onMessage : function(e){
        console.log(e);
    }
};

function init_m()
{
    if(load_fl){
    var punktiT={
        "lock":[t('Parental control'),"ico_lock","ico_lock_act","ico_l_lang","g_pass.html"],
        "lang":[t('Localization'),"ico_lang","ico_lang_act","ico_l_lang","g_local.html"],
        "update":[t('Software update'),"ico_reload","ico_reload_act","ico_l_reload","g_update.html"],
        "net_info":[t('Network info'),"ico_netinfo","ico_netinfo_act","ico_l_netinfo","g_netw.html"],
        "video":[t('Video'),"ico_video","ico_video_act","ico_l_video","g_video.html"],
        "audio":[t('Audio'),"ico_audio","ico_audio_act","ico_l_audio","g_audio.html"],
        "playback":[t('Playback'),"ico_video","ico_video_act","ico_l_video","g_play.html"],
        "portal":[t('Portal'),"ico_lang","ico_lang_act","ico_l_lang","g_portal.html"],
        "net":[t('Network'),"ico_net","ico_net_act","ico_l_net","g_nets.html"],
        "advanced":[t('Advanced settings'),"ico_advset","ico_advset_act","ico_l_advset","g_adv.html"],
        "time_shift":[t('Local TimeShift'),"ico_reload","ico_reload_act","ico_l_reload","g_ts.html"],
        "dvb":[t('DVB'),"ico_reboot","ico_reboot_act","ico_l_reboot","g_dvb.html"],
        "servers":[t('Servers'),"ico_server","ico_server_act","ico_l_server","g_serv.html"],
        "dev_info":[t('Device info'),"ico_sysinfo","ico_sysinfo_act","ico_l_sysinfo","g_dev.html"],
        "reload":[t('Reload portal'),"ico_exit","ico_exit_act","ico_l_exit",2],
        "internal_portal":[t('Go to the inner portal'),"ico_switch","ico_switch_act","ico_l_switch",1],
        "reboot":[t('Reboot device'),"ico_reboot","ico_reboot_act","ico_l_reboot",3]
    };

    if (!_GET['dvb_supported_scan_types']){
        delete punktiT.dvb;
    }

    punkti=[];
    var cache=[];
    for(var i=0;i<prof.modules.length;i++){
        if (!_GET['dvb_supported_scan_types'] && prof.modules[i].name == 'dvb'){
            continue;
        }

        if (gSTB.IsEmulator && ['lock', 'lang', 'video', 'portal', 'dev_info', 'reload', 'reboot'].indexOf(prof.modules[i].name) == -1){
            continue;
        }

        var idx = punkti.length;
        punkti[idx]=punktiT[prof.modules[i].name];
        cache[idx]=new Image();
        cache[idx].src="style/"+parent.put+"/"+punkti[idx][1]+'.png';
        cache[idx].src="style/"+parent.put+"/"+punkti[idx][2]+'.png';
    }
    //punkti[-1]=[t('default'),"ico_empty","ico_empty_act",""];
    kol=punkti.length;
    nextMenu('glavnaya.html');
    document.body.style.display="block";
    }
    else setTimeout(function(){init_m()},100);
}

function up_fl(){
    load_fl=true;
}

function nextMenu(urlP)
{
    switch(urlP){
        case 0:
            switch(punkti[vid-1][4])
            {case 1:conf(t("Do you want to go to the inner portal?"),'','stb.Stop();stb.LoadURL("file:///home/web/services.html");stbWebWindow.close();');break;
            case 2:conf(t("Do you want to restart portal?"),'','stb.Stop();stb.LoadURL("file:///home/web/index.html");stbWebWindow.close();');break;
            case 3:conf(t("Device is going to reboot. Are you sure?"),'','stb.ExecAction("reboot")');break;
            default:cont.style.visibility='hidden';cont.src=punkti[vid-1][4];document.getElementById("zagolovok").innerHTML=punkti[vid-1][0];document.getElementById("ico").innerHTML="";break;}break;
        case "glavnaya.html":cont.style.visibility='hidden';cont.src=urlP;document.getElementById("zagolovok").innerHTML=t("Settings");document.getElementById("ico").innerHTML="";break;
        default:cont.style.visibility='hidden';cont.src=urlP;document.getElementById("zagolovok").innerHTML=punkti[vid-1][0];document.getElementById("ico").innerHTML="";break;
    }
}

function onLoad()
{
    stb.EnableVKButton(true);
    document.cookie = "mac=" + escape(parent.stb.GetDeviceMacAddress()) + '; path=/;';
    load({"type":"stb","action":"get_settings_profile"},function(profile){prof=profile;init_m();});
    switch(screen.height)
    {
      case 480:w=623;h=430;a=45;b=5;put=576;break;
      case 576:w=623;h=430;a=45;b=40;put=576;break;
      case 720:w=1142;h=584;a=60;b=50;put=720;break;
      case 1080:w=1142;h=584;a=380;b=230;put=720;break;
    }
    var fileref = document.createElement("link");
    fileref.setAttribute("rel", "stylesheet");
    fileref.setAttribute("type", "text/css");
    fileref.setAttribute("href", 'style/glav_' + put + '.css');
    document.getElementsByTagName("head")[0].appendChild(fileref);
    window.resizeTo(w,h);
    window.moveTo(a,b);
    cont=document.getElementById("cont");
    cont.width=w;
    cont.height=h;
    langv();
}

function erMes(erm,el){
    close=false;
    elem=el;ind=1;maxin=2;
    var d=document.getElementById('confirm');d.style.display="block";
    document.getElementById('b1').focus();
    d.innerHTML='

'+erm+'
<input id="b1" type="button" value="'+t('Ok')+'" onClick="erMbeck()" />
';
    document.getElementById('b1').focus();
}

function erMbeck(){
    if(close){stbWebWindow.close();}
    else {if(spos!=0)document.getElementById('confirmb').style.display="none";
    else document.getElementById('confirm').style.display="none";
    if(elem!='')cont.contentWindow.document.getElementById(elem).focus();
    else cont.focus();}
}

function conf(erm,el,ef,back){
    if(back)close=true;else close=false;
    elem=el;ind=1;maxin=2;
    func=ef;spos=0;
    var d=document.getElementById('confirm');d.style.display="block";
    document.getElementById('b1').focus();
    d.innerHTML='

'+erm+'
<input id="b2" type="button" value="'+t('Cancel')+'" onClick="erMbeck()" /><input id="b1" type="button" value="'+t('Ok')+'" onClick="confOk()" />
';
    document.getElementById('b2').focus();
}

function confb(erm,el,ef,back){
    if(back)close=true;else close=false;
    elem=el;ind=1;maxin=2;
    func=ef;spos=1;
    var d=document.getElementById('confirmb');d.style.display="block";
    document.getElementById('b1b').focus();
    d.innerHTML='

'+erm+'
<input id="b2b" type="button" value="'+t('Cancel')+'" onClick="erMbeck()" /><input id="b1b" type="button" value="'+t('Ok')+'" onClick="confOk()" />
';
    document.getElementById('b2b').focus();
}

function confOk(){
    eval(func);
    if(document.getElementById('confirmb').style.display=="none")document.getElementById('confirm').style.display="none";
    else document.getElementById('confirmb').style.display="none";
}

function pressKey(e)
{
ec = e.keyCode;
switch(ec)
    {
    case 9:e.preventDefault();break;
    case 40:perehod(1);break;
    case 38:perehod(-1);break;
    case 37:perehod(-1);break;
    case 39:perehod(1);break;
    }
}

function perehod(a)
{
    ind+=a;
    if(ind<1)ind=1;else if(ind>maxin)ind=maxin;
    if(spos!=0)document.getElementById('b'+ind+'b').focus();
    else document.getElementById('b'+ind).focus();
}

function load(params, callback){
   JsHttpRequest.query(
       'GET '+_GET.ajax_loader,

       params,

       function(result, errors){
        // errors - содержит ошибки сервера и debug сообщения
        gSTB.Debug(errors);

           callback(result);
       },

       true,
       {"Authorization" : "Bearer "+_GET.token}
   );
}

function auto_fr_save(t){
    var to_af = 0;
    switch(t){
        case "50_60":
            to_af = 6;
            break;
        case "24_50_60":
            to_af = 7;
            break;
        case "24_50":
            to_af = 3;
            break;
        case "24_60":
            to_af = 5;
            break;
    }
    stb.SetAutoFrameRate(to_af);
    var wra='{"auto_framerate":"'+t+'"}';
    stb.SetEnv(wra);
}<|endoftext|>