<commit_before>// api
Friends = {};

STATUSES     = {};
STATUSES.pending = "pending"; // for the user who sent the request
STATUSES.friend  = "friend";  // when both users are friends
STATUSES.request = "request"; // for the user on the recieving end of the request
STATUSES.empty   = "empty";   // used for denied requests and removed friends

if (Meteor.isServer) {
    var _onCreateUser = Accounts.onCreateUser.bind(Accounts);
    // Since onCreateUser overrides default behavior, and we don't want to restrict package users
    // by removing the onCreateUser function, we override onCreateUser to modify the user document before the regular onCreateUser call.

    // TODO: This doesn't work, I'll comment it out until someone finds a solution http://stackoverflow.com/questions/25583543/overriding-a-package-method-in-meteor
    // Accounts.onCreateUser = function (func) {
    //     console.log('onCreateUser definition');
    //     _onCreateUser(function (options, user) {
    //         console.log('onCreateUser call, the user should now have a profile');
    //         if (!user.profile) {
    //             user.profile = options.profile || {};
    //         }
    //         if (!user.profile.friends) {
    //             user.profile.friends = [];
    //         }
    //         return func(options, user);
    //     });
    // };

    // TODO: using the dirty way here, now people can't use Accounts.onCreateUser or this package will fail to work. This DOES work though
    Accounts.onCreateUser(function (options, user) {
        if (!user.profile) {
            user.profile = options.profile || {};
        }
        if (!user.profile.friends) {
            user.profile.friends = [];
        }
        return user;
    });
}

Meteor.methods({
    addFriend: function (userId, friendId, status) {
        Meteor.users.update({_id: userId},
            {$addToSet: {"profile.friends": {_id: friendId, status: status}}});
    },
    /**
     * Updates the status of two friends.
     * The first user's status will be applied to the second users reference to
     * the first user and the other way around. The second user's status wil be
     * applied to the first user's reference to the second user.
     *
     * This might be a bit confusing so here's an example
     *
     * We have two users, this state resembles that of just after one
     * user sent a friend request to someone else
     * by user1 to user2
     * user1 {profile.friends = [{
     *   userId: user2,
     *   status: "pending"
     * }]}
     * user2 {profile.friends = [{
     *     userId: user1,
     *     status: "request"
     * }]}
     *
     * calling updateFriendStatus ({
     *     userId: user1,
     *     status: "updatedStatus1" // using fake statuses for clarity
     * },{
     *     userId: user2,
     *     status: "updatedStatus2"
     * })
     *
     * will result in
     * user1 {profile.friends = [{
     *   userId: user2,
     *   status: "updatedStatus2"
     * }]}
     * user2 {profile.friends = [{
     *     userId: user1,
     *     status: "updatedStatus1"
     * }]}
     *
     * The userStatus objects are structured like this
     * {
     *     userId: "340usdfh0932ujweh032ur",
     *     status: "friend" // a status from STATUSES
     * }
     */
    updateFriendStatus: function (userStatus, userStatus2) {
        if (!this.isSimulation) {
            var updateStatus = function (userId, friendId, status) {
                Meteor.users.update({_id: userId, "profile.friends._id": friendId}, {$set: {"profile.friends.$.status": status}});
            };
            updateStatus(userStatus.userId, userStatus2.userId, userStatus2.status);
            updateStatus(userStatus2.userId, userStatus.userId, userStatus.status);
        }
    },
    friendRequest: function (userId, friendId) {
        console.dir(STATUSES);
        if (!validations.areRelated(userId, friendId)) {
            Meteor.call('addFriend', userId, friendId, STATUSES.pending);
            Meteor.call('addFriend', friendId, userId, STATUSES.request);
        }
    },
    confirmRequest: function (userId, friendId) {
        var validated = validations.validateUserRelations(
            {userId: userId, status: STATUSES.pending},
            {userId: friendId, status: STATUSES.request}
        );
        if (validated) {
            Meteor.call('updateFriendStatus',
                {userId: userId, status: STATUSES.friend},
                {userId: friendId, status: STATUSES.friend}
            );
        }
    },
    denyRequest: function (userId, friendId) {
        var validated = validations.validateUserRelations(
            {userId: userId, status: STATUSES.request},
            {userId: friendId, status: STATUSES.pending}
        );
        // TODO: add option to choose between empty for the request sender or
        // pending, for privacy
        if (validated) {
            Meteor.call('updateFriendStatus',
                {userId: userId, status: STATUSES.empty},
                {userId: friendId, status: STATUSES.empty}
            );
        }
    },
    removeFriend: function (userId, friendId) {
        var validated = validations.validateUserRelations(
            {userId: userId, status: STATUSES.friend},
            {userId: friendId, status: STATUSES.friend}
        );
        // TODO: add option to choose between empty for the removed friend or
        // friend, for privacy
        if (validated) {
            Meteor.call('updateFriendStatus',
                {userId: userId, status: STATUSES.empty},
                {userId: friendId, status: STATUSES.empty}
            );
        }
    }
});

/**
 * wrapper method for the Meteor friendRequest method
 */
Friends.friendRequest = function (userId, friendId) {
    Meteor.call('friendRequest', userId, friendId);
};

/**
 * wrapper method for the Meteor confirmRequest method
 */
Friends.confirmRequest = function (userId, friendId) {
    Meteor.call('confirmRequest', userId, friendId);
};

/**
 * wrapper method for the Meteor denyRequest method
 */
Friends.denyRequest = function (userId, friendId) {
    Meteor.call('denyRequest', userId, friendId);
};

/**
 * wrapper method for the Meteor removeFriend method
 */
Friends.removeFriend = function (userId, friendId) {
    Meteor.call('removeFriend', userId, friendId);
};<commit_msg>Removed a console.dir call<commit_after>// api
Friends = {};

STATUSES     = {};
STATUSES.pending = "pending"; // for the user who sent the request
STATUSES.friend  = "friend";  // when both users are friends
STATUSES.request = "request"; // for the user on the recieving end of the request
STATUSES.empty   = "empty";   // used for denied requests and removed friends

if (Meteor.isServer) {
    var _onCreateUser = Accounts.onCreateUser.bind(Accounts);
    // Since onCreateUser overrides default behavior, and we don't want to restrict package users
    // by removing the onCreateUser function, we override onCreateUser to modify the user document before the regular onCreateUser call.

    // TODO: This doesn't work, I'll comment it out until someone finds a solution http://stackoverflow.com/questions/25583543/overriding-a-package-method-in-meteor
    // Accounts.onCreateUser = function (func) {
    //     console.log('onCreateUser definition');
    //     _onCreateUser(function (options, user) {
    //         console.log('onCreateUser call, the user should now have a profile');
    //         if (!user.profile) {
    //             user.profile = options.profile || {};
    //         }
    //         if (!user.profile.friends) {
    //             user.profile.friends = [];
    //         }
    //         return func(options, user);
    //     });
    // };

    // TODO: using the dirty way here, now people can't use Accounts.onCreateUser or this package will fail to work. This DOES work though
    Accounts.onCreateUser(function (options, user) {
        if (!user.profile) {
            user.profile = options.profile || {};
        }
        if (!user.profile.friends) {
            user.profile.friends = [];
        }
        return user;
    });
}

Meteor.methods({
    addFriend: function (userId, friendId, status) {
        Meteor.users.update({_id: userId},
            {$addToSet: {"profile.friends": {_id: friendId, status: status}}});
    },
    /**
     * Updates the status of two friends.
     * The first user's status will be applied to the second users reference to
     * the first user and the other way around. The second user's status wil be
     * applied to the first user's reference to the second user.
     *
     * This might be a bit confusing so here's an example
     *
     * We have two users, this state resembles that of just after one
     * user sent a friend request to someone else
     * by user1 to user2
     * user1 {profile.friends = [{
     *   userId: user2,
     *   status: "pending"
     * }]}
     * user2 {profile.friends = [{
     *     userId: user1,
     *     status: "request"
     * }]}
     *
     * calling updateFriendStatus ({
     *     userId: user1,
     *     status: "updatedStatus1" // using fake statuses for clarity
     * },{
     *     userId: user2,
     *     status: "updatedStatus2"
     * })
     *
     * will result in
     * user1 {profile.friends = [{
     *   userId: user2,
     *   status: "updatedStatus2"
     * }]}
     * user2 {profile.friends = [{
     *     userId: user1,
     *     status: "updatedStatus1"
     * }]}
     *
     * The userStatus objects are structured like this
     * {
     *     userId: "340usdfh0932ujweh032ur",
     *     status: "friend" // a status from STATUSES
     * }
     */
    updateFriendStatus: function (userStatus, userStatus2) {
        if (!this.isSimulation) {
            var updateStatus = function (userId, friendId, status) {
                Meteor.users.update({_id: userId, "profile.friends._id": friendId}, {$set: {"profile.friends.$.status": status}});
            };
            updateStatus(userStatus.userId, userStatus2.userId, userStatus2.status);
            updateStatus(userStatus2.userId, userStatus.userId, userStatus.status);
        }
    },
    friendRequest: function (userId, friendId) {
        if (!validations.areRelated(userId, friendId)) {
            Meteor.call('addFriend', userId, friendId, STATUSES.pending);
            Meteor.call('addFriend', friendId, userId, STATUSES.request);
        }
    },
    confirmRequest: function (userId, friendId) {
        var validated = validations.validateUserRelations(
            {userId: userId, status: STATUSES.pending},
            {userId: friendId, status: STATUSES.request}
        );
        if (validated) {
            Meteor.call('updateFriendStatus',
                {userId: userId, status: STATUSES.friend},
                {userId: friendId, status: STATUSES.friend}
            );
        }
    },
    denyRequest: function (userId, friendId) {
        var validated = validations.validateUserRelations(
            {userId: userId, status: STATUSES.request},
            {userId: friendId, status: STATUSES.pending}
        );
        // TODO: add option to choose between empty for the request sender or
        // pending, for privacy
        if (validated) {
            Meteor.call('updateFriendStatus',
                {userId: userId, status: STATUSES.empty},
                {userId: friendId, status: STATUSES.empty}
            );
        }
    },
    removeFriend: function (userId, friendId) {
        var validated = validations.validateUserRelations(
            {userId: userId, status: STATUSES.friend},
            {userId: friendId, status: STATUSES.friend}
        );
        // TODO: add option to choose between empty for the removed friend or
        // friend, for privacy
        if (validated) {
            Meteor.call('updateFriendStatus',
                {userId: userId, status: STATUSES.empty},
                {userId: friendId, status: STATUSES.empty}
            );
        }
    }
});

/**
 * wrapper method for the Meteor friendRequest method
 */
Friends.friendRequest = function (userId, friendId) {
    Meteor.call('friendRequest', userId, friendId);
};

/**
 * wrapper method for the Meteor confirmRequest method
 */
Friends.confirmRequest = function (userId, friendId) {
    Meteor.call('confirmRequest', userId, friendId);
};

/**
 * wrapper method for the Meteor denyRequest method
 */
Friends.denyRequest = function (userId, friendId) {
    Meteor.call('denyRequest', userId, friendId);
};

/**
 * wrapper method for the Meteor removeFriend method
 */
Friends.removeFriend = function (userId, friendId) {
    Meteor.call('removeFriend', userId, friendId);
};<|endoftext|>


<commit_before>'use strict';

/* https://github.com/angular/protractor/blob/master/docs/toc.md */

describe('my app', function() {

  it('should automatically redirect to /home when location hash/fragment is empty', function() {
    browser.get('index.html');
    expect(browser.getLocationAbsUrl()).toMatch("/home");
  });

  describe('home', function() {

    beforeEach(function() {
      browser.get('index.html#!/home');
    });

    it('should render home when user navigates to /home', function() {
      expect(element.all(by.css('[ng-view] p')).first().getText()).
        toMatch(/partial for view 1/);
    });

  });

  describe('view2', function() {

    beforeEach(function() {
      browser.get('index.html#!/view2');
    });

    it('should render view2 when user navigates to /view2', function() {
      expect(element.all(by.css('[ng-view] p')).first().getText()).
        toMatch(/partial for view 2/);
    });

  });
});
<commit_msg>updated e2e<commit_after>'use strict';

/* https://github.com/angular/protractor/blob/master/docs/toc.md */

describe('my app', function() {

  it('should automatically redirect to /home when location hash/fragment is empty', function() {
    browser.get('index.html');
    expect(browser.getLocationAbsUrl()).toMatch("/contact-list");
  });
});
<|endoftext|>


<commit_before>import { expect } from 'chai';
import testUtils from './utils';

describe('application launch', function () {

    beforeEach(testUtils.beforeEach);
    afterEach(testUtils.afterEach);

    it('no test code here', function () {
        // end to end test code here
        return function() {
            done();
        };
    });
});
<commit_msg>Change e2e file<commit_after>import { expect } from 'chai';
import testUtils from './utils';

describe('application launch', function () {

    beforeEach(testUtils.beforeEach);
    afterEach(testUtils.afterEach);

});
<|endoftext|>


<commit_before>/*
 * Paper.js
 *
 * This file is part of Paper.js, a JavaScript Vector Graphics Library,
 * based on Scriptographer.org and designed to be largely API compatible.
 * http://paperjs.org/
 * http://scriptographer.org/
 *
 * Copyright (c) 2011, Juerg Lehni & Jonathan Puckey
 * http://lehni.org/ & http://jonathanpuckey.com/
 *
 * Distributed under the MIT license. See LICENSE file for details.
 *
 * All rights reserved.
 */

/**
 * @name PaperScript
 * @namespace
 */
var PaperScript = this.PaperScript = new function() {
/*#*/ include('../../lib/parse-js-min.js');

	// Math Operators

	var operators = {
		'+': 'add',
		'-': 'subtract',
		'*': 'multiply',
		'/': 'divide',
		'%': 'modulo',
		'==': 'equals',
		'!=': 'equals'
	};

	function $eval(left, operator, right) {
		var handler = operators[operator];
		if (left && left[handler]) {
			var res = left[handler](right);
			return operator == '!=' ? !res : res;
		}
		switch (operator) {
		case '+': return left + right;
		case '-': return left - right;
		case '*': return left * right;
		case '/': return left / right;
		case '%': return left % right;
		case '==': return left == right;
		case '!=': return left != right;
		default:
			throw new Error('Implement Operator: ' + operator);
		}
	};

	// Sign Operators

	var signOperators = {
		'-': 'negate'
	};

	function $sign(operator, value) {
		var handler = signOperators[operator];
		if (value && value[handler]) {
			return value[handler]();
		}
		switch (operator) {
		case '+': return +value;
		case '-': return -value;
		default:
			throw new Error('Implement Sign Operator: ' + operator);
		}
	}

	// AST Helpers

	function isDynamic(exp) {
		var type = exp[0];
		return type != 'num' && type != 'string';
	}

	function handleOperator(operator, left, right) {
		// Only replace operators with calls to $operator if the left hand side
		// is potentially an object.
		if (operators[operator] && isDynamic(left)) {
			// Replace with call to $operator(left, operator, right):
			return ['call', ['name', '$eval'],
					[left, ['string', operator], right]];
		}
	}

	/**
	 * Compiles PaperScript code into JavaScript code.
	 *
	 * @name PaperScript.compile
	 * @function
	 * @param {String} code The PaperScript code.
	 * @return {String} The compiled PaperScript as JavaScript code.
	 */
	function compile(code) {
		// Use parse-js to translate the code into a AST structure which is then
		// walked and parsed for operators to overload. The resulting AST is
		// translated back to code and evaluated.
		var ast = parse_js.parse(code),
			walker = parse_js.ast_walker(),
			walk = walker.walk;

		ast = walker.with_walkers({
			'binary': function(operator, left, right) {
				// Handle simple mathematical operators here:
				return handleOperator(operator, left = walk(left),
						right = walk(right))
						// Always return something since we're walking left and
						// right for the handleOperator() call already.
						|| [this[0], operator, left, right];
			},

			'assign': function(operator, left, right) {
				// Handle assignments like +=, -=, etc:
				// Check if the assignment operator needs to be handled by paper
				// if so, convert the assignment to a simple = and use result of
				// of handleOperator on the right hand side.
				var res = handleOperator(operator, left = walk(left),
						right = walk(right));
				if (res)
					return [this[0], true, left, res];
				// Always return something for the same reason as in binary
				return [this[0], operator, left, right];
			},

			'unary-prefix': function(operator, exp) {
				if (signOperators[operator] && isDynamic(exp)) {
					return ['call', ['name', '$sign'],
							[['string', operator], walk(exp)]];
				}
			}
		}, function() {
			return walk(ast);
		});

		return parse_js.gen_code(ast, {
			beautify: true
		});
	}

	/**
	 * Evaluates parsed PaperScript code in the passed {@link PaperScope}
	 * object. It also installs handlers automatically for us.
	 *
	 * @name PaperScript.evaluate
	 * @function
	 * @param {String} code The PaperScript code.
	 * @param {PaperScript} scope The scope in which the code is executed.
	 * @return {Object} The result of the code evaluation.
	 */
	function evaluate(code, scope) {
		// Set currently active scope.
		paper = scope;
		var view = scope.view,
			// TODO: Add support for multiple tools
			tool = scope.tool = /on(?:Key|Mouse)(?:Up|Down|Move|Drag)/.test(code)
					&& new Tool(),
			res;
		// Define variables for potential handlers, so eval() calls below to
		// fetch their values do not require try-catch around them.
		// Use with(){} in order to make the scope the current 'global' scope
		// instead of window.
		with (scope) {
			// Within this, use a function scope, so local variables to not try
			// and set themselves on the scope object.
			(function() {
				var onEditOptions, onSelect, onDeselect, onReselect, onMouseDown,
					onMouseUp, onMouseDrag, onMouseMove, onKeyDown, onKeyUp,
					onFrame, onResize,
					handlers = [ 'onEditOptions', 'onSelect', 'onDeselect',
						'onReselect', 'onMouseDown', 'onMouseUp', 'onMouseDrag',
						'onMouseMove', 'onKeyDown', 'onKeyUp'];
				res = eval(compile(code));
				if (tool) {
					// We could do this instead to avoid eval(), but it's longer
					// tool.onEditOptions = onEditOptions;
					// tool.onSelect = onSelect;
					// tool.onDeselect = onDeselect;
					// tool.onReselect = onReselect;
					// tool.onMouseDown = onMouseDown;
					// tool.onMouseUp = onMouseUp;
					// tool.onMouseDrag = onMouseDrag;
					// tool.onMouseMove = onMouseMove;
					// tool.onKeyDown = onKeyDown;
					// tool.onKeyUp = onKeyUp;
					Base.each(handlers, function(key) {
						tool[key] = eval(key);
					});
				}
				if (view) {
					view.onResize = onResize;
					view.setOnFrame(onFrame);
					// Automatically draw view at the end.
					view.draw();
				}
			}).call(scope);
		}
		return res;
	}

/*#*/ if (options.browser) {
	// Code borrowed from Coffee Script:
	function request(url, scope) {
		var xhr = new (window.ActiveXObject || XMLHttpRequest)(
				'Microsoft.XMLHTTP');
		xhr.open('GET', url, true);
		if (xhr.overrideMimeType) {
			xhr.overrideMimeType('text/plain');
		}
		xhr.onreadystatechange = function() {
			if (xhr.readyState === 4) {
				return evaluate(xhr.responseText, scope);
			}
		};
		return xhr.send(null);
	}

	function load() {
		var scripts = document.getElementsByTagName('script');
		for (var i = 0, l = scripts.length; i < l; i++) {
			var script = scripts[i];
			// Only load this script if it not loaded already.
			// Support both text/paperscript and text/x-paperscript:
			if (/^text\/(?:x-|)paperscript$/.test(script.type)
					&& !script.getAttribute('data-paper-loaded')) {
				// Produce a new PaperScope for this script now. Scopes are
				// cheap so let's not worry about the initial one that was
				// already created.
				// Define an id for each PaperScript, so its scope can be
				// retrieved through PaperScope.get().
				// If a canvas id is provided, pass it on to the PaperScope
				// so a project is created for it now.
				var canvas = PaperScript.getAttribute(script, 'canvas');
				canvas = canvas && document.getElementById(canvas);
				var scope = new PaperScope(script);
				scope.setup(canvas);
				if (script.src) {
					// If we're loading from a source, request that first and then
					// run later.
					request(script.src, scope);
				} else {
					// We can simply get the code form the script tag.
					evaluate(script.innerHTML, scope);
				}
				// Mark script as loaded now.
				script.setAttribute('data-paper-loaded', true);
			}
		}
	}

	DomEvent.add(window, { load: load });

	// Produces helpers to e.g. check for both 'canvas' and 'data-paper-canvas'
	// attributes:
	function handleAttribute(name) {
		name += 'Attribute';
		return function(el, attr) {
			return el[name](attr) || el[name]('data-paper-' + attr);
		};
	}

	return {
		compile: compile,
		evaluate: evaluate,
		load: load,
		getAttribute: handleAttribute('get'),
		hasAttribute: handleAttribute('has')
	};

/*#*/ } else { // !options.browser

	return {
		compile: compile,
		evaluate: evaluate
	};

/*#*/ } // !options.browser
};

// Export load directly:
this.load = PaperScript.load;
<commit_msg>Let View handle the retrieving of the canvas object.<commit_after>/*
 * Paper.js
 *
 * This file is part of Paper.js, a JavaScript Vector Graphics Library,
 * based on Scriptographer.org and designed to be largely API compatible.
 * http://paperjs.org/
 * http://scriptographer.org/
 *
 * Copyright (c) 2011, Juerg Lehni & Jonathan Puckey
 * http://lehni.org/ & http://jonathanpuckey.com/
 *
 * Distributed under the MIT license. See LICENSE file for details.
 *
 * All rights reserved.
 */

/**
 * @name PaperScript
 * @namespace
 */
var PaperScript = this.PaperScript = new function() {
/*#*/ include('../../lib/parse-js-min.js');

	// Math Operators

	var operators = {
		'+': 'add',
		'-': 'subtract',
		'*': 'multiply',
		'/': 'divide',
		'%': 'modulo',
		'==': 'equals',
		'!=': 'equals'
	};

	function $eval(left, operator, right) {
		var handler = operators[operator];
		if (left && left[handler]) {
			var res = left[handler](right);
			return operator == '!=' ? !res : res;
		}
		switch (operator) {
		case '+': return left + right;
		case '-': return left - right;
		case '*': return left * right;
		case '/': return left / right;
		case '%': return left % right;
		case '==': return left == right;
		case '!=': return left != right;
		default:
			throw new Error('Implement Operator: ' + operator);
		}
	};

	// Sign Operators

	var signOperators = {
		'-': 'negate'
	};

	function $sign(operator, value) {
		var handler = signOperators[operator];
		if (value && value[handler]) {
			return value[handler]();
		}
		switch (operator) {
		case '+': return +value;
		case '-': return -value;
		default:
			throw new Error('Implement Sign Operator: ' + operator);
		}
	}

	// AST Helpers

	function isDynamic(exp) {
		var type = exp[0];
		return type != 'num' && type != 'string';
	}

	function handleOperator(operator, left, right) {
		// Only replace operators with calls to $operator if the left hand side
		// is potentially an object.
		if (operators[operator] && isDynamic(left)) {
			// Replace with call to $operator(left, operator, right):
			return ['call', ['name', '$eval'],
					[left, ['string', operator], right]];
		}
	}

	/**
	 * Compiles PaperScript code into JavaScript code.
	 *
	 * @name PaperScript.compile
	 * @function
	 * @param {String} code The PaperScript code.
	 * @return {String} The compiled PaperScript as JavaScript code.
	 */
	function compile(code) {
		// Use parse-js to translate the code into a AST structure which is then
		// walked and parsed for operators to overload. The resulting AST is
		// translated back to code and evaluated.
		var ast = parse_js.parse(code),
			walker = parse_js.ast_walker(),
			walk = walker.walk;

		ast = walker.with_walkers({
			'binary': function(operator, left, right) {
				// Handle simple mathematical operators here:
				return handleOperator(operator, left = walk(left),
						right = walk(right))
						// Always return something since we're walking left and
						// right for the handleOperator() call already.
						|| [this[0], operator, left, right];
			},

			'assign': function(operator, left, right) {
				// Handle assignments like +=, -=, etc:
				// Check if the assignment operator needs to be handled by paper
				// if so, convert the assignment to a simple = and use result of
				// of handleOperator on the right hand side.
				var res = handleOperator(operator, left = walk(left),
						right = walk(right));
				if (res)
					return [this[0], true, left, res];
				// Always return something for the same reason as in binary
				return [this[0], operator, left, right];
			},

			'unary-prefix': function(operator, exp) {
				if (signOperators[operator] && isDynamic(exp)) {
					return ['call', ['name', '$sign'],
							[['string', operator], walk(exp)]];
				}
			}
		}, function() {
			return walk(ast);
		});

		return parse_js.gen_code(ast, {
			beautify: true
		});
	}

	/**
	 * Evaluates parsed PaperScript code in the passed {@link PaperScope}
	 * object. It also installs handlers automatically for us.
	 *
	 * @name PaperScript.evaluate
	 * @function
	 * @param {String} code The PaperScript code.
	 * @param {PaperScript} scope The scope in which the code is executed.
	 * @return {Object} The result of the code evaluation.
	 */
	function evaluate(code, scope) {
		// Set currently active scope.
		paper = scope;
		var view = scope.view,
			// TODO: Add support for multiple tools
			tool = scope.tool = /on(?:Key|Mouse)(?:Up|Down|Move|Drag)/.test(code)
					&& new Tool(),
			res;
		// Define variables for potential handlers, so eval() calls below to
		// fetch their values do not require try-catch around them.
		// Use with(){} in order to make the scope the current 'global' scope
		// instead of window.
		with (scope) {
			// Within this, use a function scope, so local variables to not try
			// and set themselves on the scope object.
			(function() {
				var onEditOptions, onSelect, onDeselect, onReselect, onMouseDown,
					onMouseUp, onMouseDrag, onMouseMove, onKeyDown, onKeyUp,
					onFrame, onResize,
					handlers = [ 'onEditOptions', 'onSelect', 'onDeselect',
						'onReselect', 'onMouseDown', 'onMouseUp', 'onMouseDrag',
						'onMouseMove', 'onKeyDown', 'onKeyUp'];
				res = eval(compile(code));
				if (tool) {
					// We could do this instead to avoid eval(), but it's longer
					// tool.onEditOptions = onEditOptions;
					// tool.onSelect = onSelect;
					// tool.onDeselect = onDeselect;
					// tool.onReselect = onReselect;
					// tool.onMouseDown = onMouseDown;
					// tool.onMouseUp = onMouseUp;
					// tool.onMouseDrag = onMouseDrag;
					// tool.onMouseMove = onMouseMove;
					// tool.onKeyDown = onKeyDown;
					// tool.onKeyUp = onKeyUp;
					Base.each(handlers, function(key) {
						tool[key] = eval(key);
					});
				}
				if (view) {
					view.onResize = onResize;
					view.setOnFrame(onFrame);
					// Automatically draw view at the end.
					view.draw();
				}
			}).call(scope);
		}
		return res;
	}

/*#*/ if (options.browser) {
	// Code borrowed from Coffee Script:
	function request(url, scope) {
		var xhr = new (window.ActiveXObject || XMLHttpRequest)(
				'Microsoft.XMLHTTP');
		xhr.open('GET', url, true);
		if (xhr.overrideMimeType) {
			xhr.overrideMimeType('text/plain');
		}
		xhr.onreadystatechange = function() {
			if (xhr.readyState === 4) {
				return evaluate(xhr.responseText, scope);
			}
		};
		return xhr.send(null);
	}

	function load() {
		var scripts = document.getElementsByTagName('script');
		for (var i = 0, l = scripts.length; i < l; i++) {
			var script = scripts[i];
			// Only load this script if it not loaded already.
			// Support both text/paperscript and text/x-paperscript:
			if (/^text\/(?:x-|)paperscript$/.test(script.type)
					&& !script.getAttribute('data-paper-loaded')) {
				// Produce a new PaperScope for this script now. Scopes are
				// cheap so let's not worry about the initial one that was
				// already created.
				// Define an id for each PaperScript, so its scope can be
				// retrieved through PaperScope.get().
				// If a canvas id is provided, pass it on to the PaperScope
				// so a project is created for it now.
				var scope = new PaperScope(script);
				scope.setup(PaperScript.getAttribute(script, 'canvas'));
				if (script.src) {
					// If we're loading from a source, request that first and then
					// run later.
					request(script.src, scope);
				} else {
					// We can simply get the code form the script tag.
					evaluate(script.innerHTML, scope);
				}
				// Mark script as loaded now.
				script.setAttribute('data-paper-loaded', true);
			}
		}
	}

	DomEvent.add(window, { load: load });

	// Produces helpers to e.g. check for both 'canvas' and 'data-paper-canvas'
	// attributes:
	function handleAttribute(name) {
		name += 'Attribute';
		return function(el, attr) {
			return el[name](attr) || el[name]('data-paper-' + attr);
		};
	}

	return {
		compile: compile,
		evaluate: evaluate,
		load: load,
		getAttribute: handleAttribute('get'),
		hasAttribute: handleAttribute('has')
	};

/*#*/ } else { // !options.browser

	return {
		compile: compile,
		evaluate: evaluate
	};

/*#*/ } // !options.browser
};

// Export load directly:
this.load = PaperScript.load;
<|endoftext|>


<commit_before>var request = require('request')
require('dotenv').config()
start = `39.733543, -104.992554`
end=`39.733543, -104.91`

  // var latlng = new google.maps.LatLng(startd);
  // var myOptions = {
  //   zoom: 15,
  //   center: latlng,
  //   mapTypeControl: false,
  //   navigationControlOptions: {style: google.maps.NavigationControlStyle.SMALL},
  //   mapTypeId: google.maps.MapTypeId.ROADMAP
  // };
  // var map = new google.maps.Map(document.getElementById("mapcanvas"), myOptions);

  // var marker = new google.maps.Marker({
  //     position: latlng,
  //     map: map,
  //     title:"You are here! (at least within a "+position.coords.accuracy+" meter radius)"
  // });

function getDirects(start,end){
	request(`https://maps.googleapis.com/maps/api/directions/json?origin=${start}&destination=${end}&mode=walking&key=${process.env.MAP_KEY}`,function(error,success,body){
		// switch(succ){

		// }
		// console.log(success)
		var jsonB = JSON.parse(body)
		console.log(jsonB.routes[0].legs)
	})
}
// getDirects(start,end)

function getMap(start,end){
	var googUrl = `https://maps.googleapis.com/maps/api/`
	// console.log(`https://maps.googleapis.com/maps/api/directions/json?origin=${start}&destination=${end}&mode=walking&key=${process.env.MAP_KEY}`)
	request(`${googUrl}directions/json?origin=${start}&destination=${end}&mode=walking&key=${process.env.MAP_KEY}`,function(error,success,body){
		var jsonB = JSON.parse(body)
		var route =jsonB.routes[0].overview_polyline.points
		// console.log(route)
		let mapUrl =`${googUrl}staticmap?size=600x400&origin=${start}&destination=${end}&path=enc%3A${route}&key=${process.env.DIRECTIONS_KEY}`
		return mapUrl
	})
}
getMap(start,end)

module.exports={
	getMap:getMap
}
// var latlng = new google.maps.LatLng(39.733543, -104.992554);
// var myOptions = {
// 	zoom: 15,
// 	center: latlng,
// 	mapTypeControl: false,
// 	navigationControlOptions: {style: google.maps.NavigationControlStyle.SMALL},
// 	mapTypeId: google.maps.MapTypeId.ROADMAP
// };
// var map = new google.maps.Map(document.getElementById("mapcanvas"), myOptions);
// var marker = new google.maps.Marker({
// 	position: latlng,
// 	map: map,
// 	title:"You are here! (at least within a "+position.coords.accuracy+" meter radius)"
// });
// console.log(map)

// {
//   origin: LatLng | String | google.maps.Place,
//   destination: LatLng | String | google.maps.Place,
//   travelMode: TravelMode,
//   transitOptions: TransitOptions,
//   drivingOptions: DrivingOptions,
//   unitSystem: UnitSystem,
//   waypoints[]: DirectionsWaypoint,
//   optimizeWaypoints: Boolean,
//   provideRouteAlternatives: Boolean,
//   avoidHighways: Boolean,
//   avoidTolls: Boolean,
//   region: String
// }

<commit_msg>extra (<commit_after>var request = require('request')
require('dotenv').config()
start = `39.733543, -104.992554`
end=`39.733543, -104.91`

  // var latlng = new google.maps.LatLng(startd);
  // var myOptions = {
  //   zoom: 15,
  //   center: latlng,
  //   mapTypeControl: false,
  //   navigationControlOptions: {style: google.maps.NavigationControlStyle.SMALL},
  //   mapTypeId: google.maps.MapTypeId.ROADMAP
  // };
  // var map = new google.maps.Map(document.getElementById("mapcanvas"), myOptions);

  // var marker = new google.maps.Marker({
  //     position: latlng,
  //     map: map,
  //     title:"You are here! (at least within a "+position.coords.accuracy+" meter radius)"
  // });

// function getDirects(start,end){
// 	request(`https://maps.googleapis.com/maps/api/directions/json?origin=${start}&destination=${end}&mode=walking&key=${process.env.MAP_KEY}`,function(error,success,body){
// 		// switch(succ){

// 		// }
// 		// console.log(success)
// 		var jsonB = JSON.parse(body)
// 		console.log(jsonB.routes[0].legs)
// 	})
// }
// getDirects(start,end)

function getMap(start,end){
	var googUrl = `https://maps.googleapis.com/maps/api/`
	// console.log(`https://maps.googleapis.com/maps/api/directions/json?origin=${start}&destination=${end}&mode=walking&key=${process.env.MAP_KEY}`)
	request(`${googUrl}directions/json?origin=${start}&destination=${end}&mode=walking&key=${process.env.MAP_KEY}`,function(error,success,body){
		var route =JSON.parse(body).routes[0].overview_polyline.points
		// console.log(route)
		let mapUrl =`${googUrl}staticmap?size=600x400&origin=${start}&destination=${end}&path=enc%3A${route}&key=${process.env.DIRECTIONS_KEY}`
		return mapUrl
	})
}
getMap(start,end)

module.exports={
	getMap:getMap
}
// var latlng = new google.maps.LatLng(39.733543, -104.992554);
// var myOptions = {
// 	zoom: 15,
// 	center: latlng,
// 	mapTypeControl: false,
// 	navigationControlOptions: {style: google.maps.NavigationControlStyle.SMALL},
// 	mapTypeId: google.maps.MapTypeId.ROADMAP
// };
// var map = new google.maps.Map(document.getElementById("mapcanvas"), myOptions);
// var marker = new google.maps.Marker({
// 	position: latlng,
// 	map: map,
// 	title:"You are here! (at least within a "+position.coords.accuracy+" meter radius)"
// });
// console.log(map)

// {
//   origin: LatLng | String | google.maps.Place,
//   destination: LatLng | String | google.maps.Place,
//   travelMode: TravelMode,
//   transitOptions: TransitOptions,
//   drivingOptions: DrivingOptions,
//   unitSystem: UnitSystem,
//   waypoints[]: DirectionsWaypoint,
//   optimizeWaypoints: Boolean,
//   provideRouteAlternatives: Boolean,
//   avoidHighways: Boolean,
//   avoidTolls: Boolean,
//   region: String
// }

<|endoftext|>


<commit_before>if (typeof require == 'undefined') (function() {
	var XHR = window.XMLHttpRequest || function() { return new ActiveXObject("Msxml2.XMLHTTP"); },
		log = window.console && console.log

  	// Regex to split a filename into [*, dir, basename, ext], posix version, from https://github.com/ry/node/blob/master/lib/path.js
	var splitPathRegex = /^(.+\/(?!$)|\/)?((?:.+?)?(\.[^.]*)?)$/,
		getDir = function(path) { return splitPathRegex.exec(path)[1] || '' }

	var slashDotSlashRegex = /\/\.\//g,
		doubleSlashRegex = /\/\//g
	var resolvePath = function(base, path) {
		if (path[0] == '/') { path = require._root + path }
		else { path = base + path }
		var pathParts = path
				.replace(doubleSlashRegex, '/')
				.replace(slashDotSlashRegex, '/')
				.split('/')

		var i=0
		while (i < pathParts.length) {
			if (pathParts[i] == '..') {
				pathParts.splice(i - 1, 2)
				i--
			} else {
				i++
			}
		}

		var possiblesBase = pathParts.join('/')
		return [possiblesBase + '.js', possiblesBase + '/index.js']
	}

	// IE6 won't return an anonymous function from eval, so use the function constructor instead
	var evaluate = typeof eval('(function(){})') == 'undefined'
		? function(src, path) { return (new Function('return ' + src))() }
		: function(src, path) { var src = src + '\n//@ sourceURL=' + path; return eval(src) }

	var fetchFile = function(possiblePaths) {
		while (possiblePaths.length) {
			var possiblePath = possiblePaths[0],
				url = location.protocol + '//' + location.host + possiblePath,
				xhr = new XHR()
			try {
				xhr.open('GET', url, false)
				xhr.send(null)
			} catch(e) {
				log(url, 'fetchFile open/send error:', e)
			}

			if (xhr.status == -1100) { // safari file://
				// XXX: We have no way to tell in opera if a file exists and is empty, or is 404
				log(url, 'fetchFile xhr.status error:', xhr.status)
			} else if (xhr.status < 400) {
				return xhr.responseText;
			}
			possiblePaths.shift()
		}
		return null
	}

	var pageBasePath = location.pathname.replace(/\/[^\/]*$/, '/')
	window.require = function(modulePath) {
		var baseStack = require._base,
			currentBase = baseStack[baseStack.length - 1] || require._root || pageBasePath,
			possiblePaths = resolvePath(currentBase, modulePath)

		for (var i=0, path; path = possiblePaths[i]; i++) {
			if (require._modules[path]) { return require._modules[path] }
		}

		var moduleCode = fetchFile(possiblePaths),
			foundPath = possiblePaths[0] // fetchFile will remove bad paths from possiblePaths

		if (!foundPath) {
			log(path, 'failed to load module', modulePath)
			return
		}
		require._base.push(getDir(foundPath))
		var moduleFriendlyName = foundPath.replace(/[\/.]/g, '_')
		try {
			var inContextCode = '(function(module){ var exports = module.exports;\n'+ moduleCode +'\n})',
				importerFunction = evaluate(inContextCode, foundPath)
		} catch(e) {
			if(e instanceof SyntaxError) { log(foundPath, 'a syntax error prevented execution') }
			throw e
		}

			// the "module" object in a node module
		var moduleObject = { exports: {} }
		try {
			importerFunction(moduleObject)
		} catch(e) {
			if(e.type == 'syntax_error') {
				log(foundPath, 'Syntax error while importing module', e)
				throw e
			} else if (!e.requireLogged) {
				e.requireLogged = true
				if (e.type == 'stack_overflow') {
					log(foundPath, 'Stack overflow while importing module', e)
				} else {
					log(foundPath, 'enable "break on error" in your debugger to debug', e)
				}
				throw e
			}
		}

		require._modules[foundPath] = moduleObject.exports
		require._base.pop()
		return moduleObject.exports
	}

	require._modules = {}
	require._base = []
	require._root = null

	var browserRequireScript = document.getElementById('browser-require'),
		appURL = browserRequireScript && browserRequireScript.getAttribute('main'),
		rootURL = browserRequireScript && browserRequireScript.getAttribute('root')
	if (rootURL) { require._root = rootURL }
	if (appURL) { require(appURL) }
})()
<commit_msg>Avoid loading circular dependencies<commit_after>if (typeof require == 'undefined') (function() {
	var XHR = window.XMLHttpRequest || function() { return new ActiveXObject("Msxml2.XMLHTTP"); },
		log = window.console && console.log

  	// Regex to split a filename into [*, dir, basename, ext], posix version, from https://github.com/ry/node/blob/master/lib/path.js
	var splitPathRegex = /^(.+\/(?!$)|\/)?((?:.+?)?(\.[^.]*)?)$/,
		getDir = function(path) { return splitPathRegex.exec(path)[1] || '' }

	var slashDotSlashRegex = /\/\.\//g,
		doubleSlashRegex = /\/\//g
	var resolvePath = function(base, path) {
		if (path[0] == '/') { path = require._root + path }
		else { path = base + path }
		var pathParts = path
				.replace(doubleSlashRegex, '/')
				.replace(slashDotSlashRegex, '/')
				.split('/')

		var i=0
		while (i < pathParts.length) {
			if (pathParts[i] == '..') {
				pathParts.splice(i - 1, 2)
				i--
			} else {
				i++
			}
		}

		var possiblesBase = pathParts.join('/')
		return [possiblesBase + '.js', possiblesBase + '/index.js']
	}

	// IE6 won't return an anonymous function from eval, so use the function constructor instead
	var evaluate = typeof eval('(function(){})') == 'undefined'
		? function(src, path) { return (new Function('return ' + src))() }
		: function(src, path) { var src = src + '\n//@ sourceURL=' + path; return eval(src) }

	var fetchFile = function(possiblePaths) {
		while (possiblePaths.length) {
			var possiblePath = possiblePaths[0],
				url = location.protocol + '//' + location.host + possiblePath,
				xhr = new XHR()
			if (!require._attempted[url]) {
				require._attempted[url] = true
				try {
					xhr.open('GET', url, false)
					xhr.send(null)
				} catch(e) {
					log(url, 'fetchFile open/send error:', e)
				}

				if (xhr.status == -1100) { // safari file://
					// XXX: We have no way to tell in opera if a file exists and is empty, or is 404
					log(url, 'fetchFile xhr.status error:', xhr.status)
				} else if (xhr.status < 400) {
					return xhr.responseText;
				}
			}
			possiblePaths.shift()
		}
		return null
	}

	var pageBasePath = location.pathname.replace(/\/[^\/]*$/, '/')
	window.require = function(modulePath) {
		var baseStack = require._base,
			currentBase = baseStack[baseStack.length - 1] || require._root || pageBasePath,
			possiblePaths = resolvePath(currentBase, modulePath)

		for (var i=0, path; path = possiblePaths[i]; i++) {
			if (require._modules[path]) { return require._modules[path] }
		}

		var moduleCode = fetchFile(possiblePaths),
			foundPath = possiblePaths[0] // fetchFile will remove bad paths from possiblePaths

		if (!foundPath) {
			log(path, 'failed to load module', modulePath)
			return
		}
		require._base.push(getDir(foundPath))
		var moduleFriendlyName = foundPath.replace(/[\/.]/g, '_')
		try {
			var inContextCode = '(function(module){ var exports = module.exports;\n'+ moduleCode +'\n})',
				importerFunction = evaluate(inContextCode, foundPath)
		} catch(e) {
			if(e instanceof SyntaxError) { log(foundPath, 'a syntax error prevented execution') }
			throw e
		}

			// the "module" object in a node module
		var moduleObject = { exports: {} }
		try {
			importerFunction(moduleObject)
		} catch(e) {
			if(e.type == 'syntax_error') {
				log(foundPath, 'Syntax error while importing module', e)
				throw e
			} else if (!e.requireLogged) {
				e.requireLogged = true
				if (e.type == 'stack_overflow') {
					log(foundPath, 'Stack overflow while importing module', e)
				} else {
					log(foundPath, 'enable "break on error" in your debugger to debug', e)
				}
				throw e
			}
		}

		require._modules[foundPath] = moduleObject.exports
		require._base.pop()
		return moduleObject.exports
	}

	require._modules = {}
	require._attempted = {}
	require._base = []
	require._root = null

	var browserRequireScript = document.getElementById('browser-require'),
		appURL = browserRequireScript && browserRequireScript.getAttribute('main'),
		rootURL = browserRequireScript && browserRequireScript.getAttribute('root')
	if (rootURL) { require._root = rootURL }
	if (appURL) { require(appURL) }
})()
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2012-2013 B3Partners B.V.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
/**
 * @class
 * @constructor
 * @description
 * The openlayers map object wrapper
 */
Ext.define ("viewer.viewercontroller.openlayers.OpenLayersMap",{
    extend: "viewer.viewercontroller.controller.Map",
    layersLoading : null,
    utils:null,
    /**
     * @constructor
     * @see viewer.viewercontroller.controller.Map#constructor
     */
    constructor: function(config){
        viewer.viewercontroller.openlayers.OpenLayersMap.superclass.constructor.call(this, config);
        this.initConfig(config);
        this.utils = Ext.create("viewer.viewercontroller.openlayers.Utils");
        var maxBounds=null;
        if (config.options.maxExtent){
            maxBounds = this.utils.createBounds(config.options.maxExtent);
        }
        var startBounds;
        if (config.options.startExtent){
            startBounds= this.utils.createBounds(config.options.startExtent);
        }
        //set the Center point
        if (startBounds){
            config.center = startBounds.getCenterLonLat();
        }else if (maxBounds){
            config.center = maxBounds.getCenterLonLat();
        }else{
            this.viewerController.logger.error("No bounds found, can't center viewport");
        }

        config.restrictedExtent = maxBounds;

        //create a click control that handles only single click
        var me=this;

        //Overwrite default OpenLayers tools,don't set any mouse controls
        config.controls=[
            new OpenLayers.Control.Attribution(),
            new OpenLayers.Control.Navigation()
        ];
        this.frameworkMap=new OpenLayers.Map(config.domId,config);
        this.frameworkMap.centerLayerContainer();
        /* Zoom to the start extent when the first layer is added
         * because openlayers needs the baselayer to zoom. After zooming, remove the listener.
         */
        if(config.options.startExtent){
            var me = this;
            var handler = function(){
                me.zoomToExtent(config.options.startExtent);
                me.removeListener(viewer.viewercontroller.controller.Event.ON_LAYER_ADDED,handler,handler);
            };
            this.addListener(viewer.viewercontroller.controller.Event.ON_LAYER_ADDED,handler,handler);
        }
        this.layersLoading = 0;
        this.markerLayer=null;
        this.defaultIcon=null;
        this.markers=new Object();
        this.getFeatureInfoControl = null;
        this.addListener(viewer.viewercontroller.controller.Event.ON_LAYER_REMOVED,this.layerRemoved, this);
        return this;
    },

    /**
    *See @link Map.getAllWMSLayers
    */
    getAllWMSLayers : function(){
        var lagen = new Array();
        for(var i = 0 ; i < this.layers.length;i++){
            if(this.layers[i] instanceof OpenLayersWMSLayer){
                lagen.push(this.layers[i]);
            }
        }
        return lagen;
    },

    /**
    *See @link Map.getAllVectorLayers
    */
    getAllVectorLayers : function(){
        var lagen = new Array();
        for(var i = 0 ; i < this.layers.length;i++){
            if(this.layers[i] instanceof OpenLayersVectorLayer){
                lagen.push(this.layers[i]);
            }
        }
        return lagen;
    },

    /**
    *See @link Map.remove
    */
    remove : function(){
        this.getFrameworkMap().destroy();
    },

    /**
    *Add a layer. Also see @link Map.addLayer
    **/
    addLayer : function(layer){
        this.superclass.addLayer.call(this,layer);
        //delete layer.getFrameworkLayer().id;
        var map = this.getFrameworkMap()
        var l = layer.getFrameworkLayer();
        try{
            map.addLayer(l);
        }catch(exception){
            this.viewerController.logger.error(exception);
        }
    },

    /**
    *remove the specific layer. See @link Map.removeLayer
    **/
    removeLayer : function(layer){
        //remove layer from framework
        this.getFrameworkMap().removeLayer(layer.getFrameworkLayer());
        /**
         *Dont call super because we listen to a remove of the layer with a listener
         *at the framework:
         *viewer.viewercontroller.openlayers.OpenLayersMap.superclass.removeLayer.call(this,layer);
         */
    },

    layerRemoved : function (map, options){
        var l = options.layer.getFrameworkLayer();
        for ( var i = 0 ; i < this.layers.length ;i++){
            var frameworkLayer = this.layers[i].getFrameworkLayer();
            if(frameworkLayer.id == l.id){
                this.layers.splice(i,1);
                break;
            }
        }
    },

    setLayerVisible : function (layer, visible){
        this.superclass.setLayerVisible.call(this,layer,visible);
        layer.setVisible(visible);
    },

    /**
    * see @link Map.setLayerIndex
    */
    setLayerIndex : function (layer, newIndex){
        if (!(layer instanceof OpenLayersLayer)){
            throw("OpenLayersMap.setLayerIndex(): Given layer not of type OpenLayersLayer.");
        }
        this.getFrameworkMap().setLayerIndex(layer.getFrameworkLayer(),newIndex);
        return Map.prototype.setLayerIndex(layer,newIndex);
    },

    /**
    * Sets the getfeatureinfo control of this map
    */
    setGetFeatureInfoControl : function (control){
        if( control.type != Tool.GET_FEATURE_INFO){
            throw ("Type of given control not of type GET_FEATURE_INFO, but: " + control.type);
        }
        this.getFeatureInfoControl = control;
    },

    /**
    * Move the viewport to the maxExtent. See @link Map.zoomToMaxExtent
    **/
    zoomToMaxExtent : function (){
        this.getFrameworkMap().zoomToExtent(this.getFrameworkMap().getMaxExtent());
    },
    /**
    * See @link Map.zoomToExtent
    **/
    zoomToExtent : function(extent){
        var bounds=this.utils.createBounds(extent)
        this.getFrameworkMap().zoomToExtent(bounds);
    },

    /**
    * See @link Map.zoomToScale
    * @deprecated, use zoomToResolution because it zooms to a resolution and not a scale
    */
    zoomToScale : function(scale){
        this.getFrameworkMap().zoomToResolution(scale);
    },

    /**
    * See @link Map.zoomToResolution
    */
    zoomToResolution : function(resolution){
        this.getFrameworkMap().zoomTo(this.getFrameworkMap().getZoomForResolution(resolution));
    },

    /**
    * See @link viewer.viewercontroller.controller.Map#moveTo
    */
    moveTo: function(x,y){
        this.getFrameworkMap().panTo(new OpenLayers.LonLat(x,y));
    },

    /**
    * See @link Map.setMaxExtent
    * WARNING: Bug in openlayers: doesn't change the maxextent
    * As workaround add the maxExtent when initing the map
    */
    setMaxExtent : function(extent){
        if (this.getFrameworkMap()!=null){
            this.getFrameworkMap().setOptions({
                maxExtent: Utils.createBounds(extent)
            });
        }
    },

    /**
    * See @link Map.getMaxExtent
    */
    getMaxExtent : function(){
        return Utils.createExtent(this.getFrameworkMap().getMaxExtent());
    },

    /**
    * See @link Map.getExtent
    */
    getExtent : function(){
        var extent = this.utils.createExtent(this.getFrameworkMap().getExtent());
        return extent;
    },

    /*TODO:
        doIdentify : function(x,y){}
        update : function(){}
        removeMarker : function(markerName){}
        */
    /**
    *see @link Map.setMarker
    *TODO: marker icon path...
    */
    setMarker : function(markerName,x,y,type){
        if (this.markerLayer==null){
            this.markerLayer = new OpenLayers.Layer.Markers("Markers");
            this.frameworkMap.addLayer(this.markerLayer);
            var size = new OpenLayers.Size(17,17);
            var offset = new OpenLayers.Pixel(-(size.w/2), -size.h);
            this.defaultIcon= new OpenLayers.Icon(contextPath+'/viewer-html/common/openlayers/img/marker.png',size,offset);
        }
        /*According the 'type' load a icon: no types yet only default*/
        var icon= this.defaultIcon.clone();
        if (this.markers[markerName]==undefined){
            this.markers[markerName]= new OpenLayers.Marker(new OpenLayers.LonLat(x,y),icon);
            this.markerLayer.addMarker(this.markers[markerName]);
        }else{
            this.markers[markerName].moveTo(this.frameworkMap.getLayerPxFromLonLat(new OpenLayers.LonLat(x,y)));
        }

    },

    /**
    * see @link Map.removeMarker
    */
    removeMarker : function(markerName){
        if (this.markers[markerName] && this.markerLayer!=null){
            this.markerLayer.removeMarker(this.markers[markerName]);
            this.markers[markerName].destroy();
            delete this.markers[markerName];
        }
    },

    /**
     * @see Ext.util.Observable#addListener
     * @param event the event
     * @param handler the handler
     * @param scope the scope
     * Overwrite the addListener. Register event on the OpenLayers Map (only once)
     * If the event is thrown by the OpenLayers event the given handlers are called.
     */
    addListener : function(event,handler,scope){
        var olSpecificEvent = this.viewerController.mapComponent.getSpecificEventName(event);
        if(olSpecificEvent){
            if(!scope){
                scope = this;
            }
            /* Add event to OpenLayersMap only once, to prevent multiple fired events.
             * count the events for removing the listener again.
             */
            if(this.enabledEvents[olSpecificEvent]){
                this.enabledEvents[olSpecificEvent]++;
            }else{
                this.enabledEvents[olSpecificEvent] = 1;
                this.frameworkMap.events.register(olSpecificEvent, this, this.handleEvent);
            }
        }
        viewer.viewercontroller.openlayers.OpenLayersMap.superclass.addListener.call(this,event,handler,scope);
    },

    /**
     * @see Ext.util.Observable#removeListener
     * @param event the event
     * @param handler the handler
     * @param scope the scope
     * Overwrite the removeListener. Unregister the event on the OpenLayers Map if there
     * are no listeners anymore.
     */
    removeListener : function (event,handler,scope){
        var olSpecificEvent = this.viewerController.mapComponent.getSpecificEventName(event);
        if(olSpecificEvent){
            if(!scope){
                scope = this;
            }
            /* Remove event from OpenLayersMap if the number of events == 0
             * If there are no listeners for the OpenLayers event, remove the listener.
             */
            if(this.enabledEvents[olSpecificEvent]){
                this.enabledEvents[olSpecificEvent]--;
                if (this.enabledEvents[olSpecificEvent] <= 0){
                    this.enabledEvents[olSpecificEvent]=0;
                    this.frameworkMap.events.unregister(olSpecificEvent, this, this.handleEvent);
                }
            }
            viewer.viewercontroller.openlayers.OpenLayersMap.superclass.removeListener.call(this,event,handler,scope);
        }else{
            this.viewerController.logger.warning("Event not listed in OpenLayersMapComponent >"+ event + "<. The application  might not work correctly.");
        }
    },

    /**
     * Handles the events fired by OpenLayers.Map and propagates them to the registered objects.
     *
     */
    handleEvent : function(args){
        var event = args.type;
        var options={};
        var genericEvent = this.viewerController.mapComponent.getGenericEventName(event);
        if (genericEvent==viewer.viewercontroller.controller.Event.ON_LAYER_ADDED){
            options.layer=this.getLayerByOpenLayersId(args.layer.id);
            if (options.layer ==undefined){
                //if no layer found return, dont fire
                return;
            }
        }else if (genericEvent== viewer.viewercontroller.controller.Event.ON_LAYER_VISIBILITY_CHANGED){
            options.layer=this.getLayerByOpenLayersId(args.layer.id);
            if (options.layer ==undefined){
                //if no layer found return, dont fire
                return;
            }
            options.visible=args.layer.visibility;
        }else if (genericEvent==viewer.viewercontroller.controller.Event.ON_LAYER_REMOVED){
            options.layer=this.getLayerByOpenLayersId(args.layer.id);
            if (options.layer ==undefined){
                //if no layer found return, dont fire
                return;
            }
        }else if (genericEvent==viewer.viewercontroller.controller.Event.ON_FINISHED_CHANGE_EXTENT ||
                  genericEvent==viewer.viewercontroller.controller.Event.ON_CHANGE_EXTENT){
            options.extent=this.getExtent();
        }else{
            this.viewerController.logger.error("The event "+genericEvent+" is not implemented in the OpenLayersMap.handleEvent()");
        }
        this.fireEvent(genericEvent,this,options);
    },

    /**
    *See @link Map.getScale
    *@deprecated, use getResolution because it returns the resolution and not the scale
    */
    getScale : function(){
        return this.getResolution();
    },

    /**
    *See @link Map.getResolution
    */
    getResolution : function(){
        return this.getFrameworkMap().getResolution();
    },
    /**
     *See @link Map.getResolutions
     */
    getResolutions : function(){
        return this.getFrameworkMap().resolutions;
    },
    /**
    *See @link Map.coordinateToPixel
    *@returns a OpenLayers.pixel object (has a .x and a .y)
    */
    coordinateToPixel : function(x,y){
        return this.getFrameworkMap().getPixelFromLonLat(new OpenLayers.LonLat(x,y));
    },

    pixelToCoordinate : function (x,y){
        var lonLat = this.getFrameworkMap().getLonLatFromPixel(new OpenLayers.Pixel(x,y));
        return {x: lonLat.lon,y: lonLat.lat};
    },

    /**
    *see @link Map.getCenter
    *@return a OpenLayers.LonLat object with .x references to .lon and .y references to .lat
    */
    getCenter : function(){
        var lonlat=this.getFrameworkMap().getCenter();
        lonlat.x=lonlat.lon;
        lonlat.y=lonlat.lat;
        return lonlat;
    },

    getWidth : function(){
        var size = this.frameworkMap.getSize();
        return size.w;
    },

    getHeight : function (){
        var size = this.frameworkMap.getSize();
        return size.h;
    },
    updateSize : function(){
        this.getFrameworkMap().updateSize();
    },

    /**
     * The OpenLayers ID can't be changed. With this function you can get the
     * viewer.viewercontroller.openlayers.OpenLayersLayer with the openlayersid
     * @param olId the openlayers id of the layer
     * @return a viewer.viewercontroller.openlayers.OpenLayersLayer that
     * contains the openlayers layer with the given id.
     */
    getLayerByOpenLayersId: function(olId){
        for (var i=0; i < this.layers.length; i++){
            if (this.layers[i].frameworkLayer){
                if (this.layers[i].frameworkLayer.id == olId){
                    return this.layers[i];
                }
            }
        }
    }
});<commit_msg>implemented the openlayersMap setLayerIndex function<commit_after>/*
 * Copyright (C) 2012-2013 B3Partners B.V.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
/**
 * @class
 * @constructor
 * @description
 * The openlayers map object wrapper
 */
Ext.define ("viewer.viewercontroller.openlayers.OpenLayersMap",{
    extend: "viewer.viewercontroller.controller.Map",
    layersLoading : null,
    utils:null,
    /**
     * @constructor
     * @see viewer.viewercontroller.controller.Map#constructor
     */
    constructor: function(config){
        viewer.viewercontroller.openlayers.OpenLayersMap.superclass.constructor.call(this, config);
        this.initConfig(config);
        this.utils = Ext.create("viewer.viewercontroller.openlayers.Utils");
        var maxBounds=null;
        if (config.options.maxExtent){
            maxBounds = this.utils.createBounds(config.options.maxExtent);
        }
        var startBounds;
        if (config.options.startExtent){
            startBounds= this.utils.createBounds(config.options.startExtent);
        }
        //set the Center point
        if (startBounds){
            config.center = startBounds.getCenterLonLat();
        }else if (maxBounds){
            config.center = maxBounds.getCenterLonLat();
        }else{
            this.viewerController.logger.error("No bounds found, can't center viewport");
        }

        config.restrictedExtent = maxBounds;

        //create a click control that handles only single click
        var me=this;

        //Overwrite default OpenLayers tools,don't set any mouse controls
        config.controls=[
            new OpenLayers.Control.Attribution(),
            new OpenLayers.Control.Navigation()
        ];
        this.frameworkMap=new OpenLayers.Map(config.domId,config);
        this.frameworkMap.centerLayerContainer();
        /* Zoom to the start extent when the first layer is added
         * because openlayers needs the baselayer to zoom. After zooming, remove the listener.
         */
        if(config.options.startExtent){
            var me = this;
            var handler = function(){
                me.zoomToExtent(config.options.startExtent);
                me.removeListener(viewer.viewercontroller.controller.Event.ON_LAYER_ADDED,handler,handler);
            };
            this.addListener(viewer.viewercontroller.controller.Event.ON_LAYER_ADDED,handler,handler);
        }
        this.layersLoading = 0;
        this.markerLayer=null;
        this.defaultIcon=null;
        this.markers=new Object();
        this.getFeatureInfoControl = null;
        this.addListener(viewer.viewercontroller.controller.Event.ON_LAYER_REMOVED,this.layerRemoved, this);
        return this;
    },

    /**
    *See @link Map.getAllWMSLayers
    */
    getAllWMSLayers : function(){
        var lagen = new Array();
        for(var i = 0 ; i < this.layers.length;i++){
            if(this.layers[i] instanceof OpenLayersWMSLayer){
                lagen.push(this.layers[i]);
            }
        }
        return lagen;
    },

    /**
    *See @link Map.getAllVectorLayers
    */
    getAllVectorLayers : function(){
        var lagen = new Array();
        for(var i = 0 ; i < this.layers.length;i++){
            if(this.layers[i] instanceof OpenLayersVectorLayer){
                lagen.push(this.layers[i]);
            }
        }
        return lagen;
    },

    /**
    *See @link Map.remove
    */
    remove : function(){
        this.getFrameworkMap().destroy();
    },

    /**
    *Add a layer. Also see @link Map.addLayer
    **/
    addLayer : function(layer){
        this.superclass.addLayer.call(this,layer);
        //delete layer.getFrameworkLayer().id;
        var map = this.getFrameworkMap()
        var l = layer.getFrameworkLayer();
        try{
            map.addLayer(l);
        }catch(exception){
            this.viewerController.logger.error(exception);
        }
    },

    /**
    *remove the specific layer. See @link Map.removeLayer
    **/
    removeLayer : function(layer){
        //remove layer from framework
        this.getFrameworkMap().removeLayer(layer.getFrameworkLayer());
        /**
         *Dont call super because we listen to a remove of the layer with a listener
         *at the framework:
         *viewer.viewercontroller.openlayers.OpenLayersMap.superclass.removeLayer.call(this,layer);
         */
    },

    layerRemoved : function (map, options){
        var l = options.layer.getFrameworkLayer();
        for ( var i = 0 ; i < this.layers.length ;i++){
            var frameworkLayer = this.layers[i].getFrameworkLayer();
            if(frameworkLayer.id == l.id){
                this.layers.splice(i,1);
                break;
            }
        }
    },

    setLayerVisible : function (layer, visible){
        this.superclass.setLayerVisible.call(this,layer,visible);
        layer.setVisible(visible);
    },

    /**
    * see @link Map.setLayerIndex
    */
    setLayerIndex : function (layer, newIndex){
        this.getFrameworkMap().setLayerIndex(layer.getFrameworkLayer(),newIndex);
        return this.callParent(arguments);
    },

    /**
    * Sets the getfeatureinfo control of this map
    */
    setGetFeatureInfoControl : function (control){
        if( control.type != Tool.GET_FEATURE_INFO){
            throw ("Type of given control not of type GET_FEATURE_INFO, but: " + control.type);
        }
        this.getFeatureInfoControl = control;
    },

    /**
    * Move the viewport to the maxExtent. See @link Map.zoomToMaxExtent
    **/
    zoomToMaxExtent : function (){
        this.getFrameworkMap().zoomToExtent(this.getFrameworkMap().getMaxExtent());
    },
    /**
    * See @link Map.zoomToExtent
    **/
    zoomToExtent : function(extent){
        var bounds=this.utils.createBounds(extent)
        this.getFrameworkMap().zoomToExtent(bounds);
    },

    /**
    * See @link Map.zoomToScale
    * @deprecated, use zoomToResolution because it zooms to a resolution and not a scale
    */
    zoomToScale : function(scale){
        this.getFrameworkMap().zoomToResolution(scale);
    },

    /**
    * See @link Map.zoomToResolution
    */
    zoomToResolution : function(resolution){
        this.getFrameworkMap().zoomTo(this.getFrameworkMap().getZoomForResolution(resolution));
    },

    /**
    * See @link viewer.viewercontroller.controller.Map#moveTo
    */
    moveTo: function(x,y){
        this.getFrameworkMap().panTo(new OpenLayers.LonLat(x,y));
    },

    /**
    * See @link Map.setMaxExtent
    * WARNING: Bug in openlayers: doesn't change the maxextent
    * As workaround add the maxExtent when initing the map
    */
    setMaxExtent : function(extent){
        if (this.getFrameworkMap()!=null){
            this.getFrameworkMap().setOptions({
                maxExtent: Utils.createBounds(extent)
            });
        }
    },

    /**
    * See @link Map.getMaxExtent
    */
    getMaxExtent : function(){
        return Utils.createExtent(this.getFrameworkMap().getMaxExtent());
    },

    /**
    * See @link Map.getExtent
    */
    getExtent : function(){
        var extent = this.utils.createExtent(this.getFrameworkMap().getExtent());
        return extent;
    },

    /*TODO:
        doIdentify : function(x,y){}
        update : function(){}
        removeMarker : function(markerName){}
        */
    /**
    *see @link Map.setMarker
    *TODO: marker icon path...
    */
    setMarker : function(markerName,x,y,type){
        if (this.markerLayer==null){
            this.markerLayer = new OpenLayers.Layer.Markers("Markers");
            this.frameworkMap.addLayer(this.markerLayer);
            var size = new OpenLayers.Size(17,17);
            var offset = new OpenLayers.Pixel(-(size.w/2), -size.h);
            this.defaultIcon= new OpenLayers.Icon(contextPath+'/viewer-html/common/openlayers/img/marker.png',size,offset);
        }
        /*According the 'type' load a icon: no types yet only default*/
        var icon= this.defaultIcon.clone();
        if (this.markers[markerName]==undefined){
            this.markers[markerName]= new OpenLayers.Marker(new OpenLayers.LonLat(x,y),icon);
            this.markerLayer.addMarker(this.markers[markerName]);
        }else{
            this.markers[markerName].moveTo(this.frameworkMap.getLayerPxFromLonLat(new OpenLayers.LonLat(x,y)));
        }

    },

    /**
    * see @link Map.removeMarker
    */
    removeMarker : function(markerName){
        if (this.markers[markerName] && this.markerLayer!=null){
            this.markerLayer.removeMarker(this.markers[markerName]);
            this.markers[markerName].destroy();
            delete this.markers[markerName];
        }
    },

    /**
     * @see Ext.util.Observable#addListener
     * @param event the event
     * @param handler the handler
     * @param scope the scope
     * Overwrite the addListener. Register event on the OpenLayers Map (only once)
     * If the event is thrown by the OpenLayers event the given handlers are called.
     */
    addListener : function(event,handler,scope){
        var olSpecificEvent = this.viewerController.mapComponent.getSpecificEventName(event);
        if(olSpecificEvent){
            if(!scope){
                scope = this;
            }
            /* Add event to OpenLayersMap only once, to prevent multiple fired events.
             * count the events for removing the listener again.
             */
            if(this.enabledEvents[olSpecificEvent]){
                this.enabledEvents[olSpecificEvent]++;
            }else{
                this.enabledEvents[olSpecificEvent] = 1;
                this.frameworkMap.events.register(olSpecificEvent, this, this.handleEvent);
            }
        }
        viewer.viewercontroller.openlayers.OpenLayersMap.superclass.addListener.call(this,event,handler,scope);
    },

    /**
     * @see Ext.util.Observable#removeListener
     * @param event the event
     * @param handler the handler
     * @param scope the scope
     * Overwrite the removeListener. Unregister the event on the OpenLayers Map if there
     * are no listeners anymore.
     */
    removeListener : function (event,handler,scope){
        var olSpecificEvent = this.viewerController.mapComponent.getSpecificEventName(event);
        if(olSpecificEvent){
            if(!scope){
                scope = this;
            }
            /* Remove event from OpenLayersMap if the number of events == 0
             * If there are no listeners for the OpenLayers event, remove the listener.
             */
            if(this.enabledEvents[olSpecificEvent]){
                this.enabledEvents[olSpecificEvent]--;
                if (this.enabledEvents[olSpecificEvent] <= 0){
                    this.enabledEvents[olSpecificEvent]=0;
                    this.frameworkMap.events.unregister(olSpecificEvent, this, this.handleEvent);
                }
            }
            viewer.viewercontroller.openlayers.OpenLayersMap.superclass.removeListener.call(this,event,handler,scope);
        }else{
            this.viewerController.logger.warning("Event not listed in OpenLayersMapComponent >"+ event + "<. The application  might not work correctly.");
        }
    },

    /**
     * Handles the events fired by OpenLayers.Map and propagates them to the registered objects.
     *
     */
    handleEvent : function(args){
        var event = args.type;
        var options={};
        var genericEvent = this.viewerController.mapComponent.getGenericEventName(event);
        if (genericEvent==viewer.viewercontroller.controller.Event.ON_LAYER_ADDED){
            options.layer=this.getLayerByOpenLayersId(args.layer.id);
            if (options.layer ==undefined){
                //if no layer found return, dont fire
                return;
            }
        }else if (genericEvent== viewer.viewercontroller.controller.Event.ON_LAYER_VISIBILITY_CHANGED){
            options.layer=this.getLayerByOpenLayersId(args.layer.id);
            if (options.layer ==undefined){
                //if no layer found return, dont fire
                return;
            }
            options.visible=args.layer.visibility;
        }else if (genericEvent==viewer.viewercontroller.controller.Event.ON_LAYER_REMOVED){
            options.layer=this.getLayerByOpenLayersId(args.layer.id);
            if (options.layer ==undefined){
                //if no layer found return, dont fire
                return;
            }
        }else if (genericEvent==viewer.viewercontroller.controller.Event.ON_FINISHED_CHANGE_EXTENT ||
                  genericEvent==viewer.viewercontroller.controller.Event.ON_CHANGE_EXTENT){
            options.extent=this.getExtent();
        }else{
            this.viewerController.logger.error("The event "+genericEvent+" is not implemented in the OpenLayersMap.handleEvent()");
        }
        this.fireEvent(genericEvent,this,options);
    },

    /**
    *See @link Map.getScale
    *@deprecated, use getResolution because it returns the resolution and not the scale
    */
    getScale : function(){
        return this.getResolution();
    },

    /**
    *See @link Map.getResolution
    */
    getResolution : function(){
        return this.getFrameworkMap().getResolution();
    },
    /**
     *See @link Map.getResolutions
     */
    getResolutions : function(){
        return this.getFrameworkMap().resolutions;
    },
    /**
    *See @link Map.coordinateToPixel
    *@returns a OpenLayers.pixel object (has a .x and a .y)
    */
    coordinateToPixel : function(x,y){
        return this.getFrameworkMap().getPixelFromLonLat(new OpenLayers.LonLat(x,y));
    },

    pixelToCoordinate : function (x,y){
        var lonLat = this.getFrameworkMap().getLonLatFromPixel(new OpenLayers.Pixel(x,y));
        return {x: lonLat.lon,y: lonLat.lat};
    },

    /**
    *see @link Map.getCenter
    *@return a OpenLayers.LonLat object with .x references to .lon and .y references to .lat
    */
    getCenter : function(){
        var lonlat=this.getFrameworkMap().getCenter();
        lonlat.x=lonlat.lon;
        lonlat.y=lonlat.lat;
        return lonlat;
    },

    getWidth : function(){
        var size = this.frameworkMap.getSize();
        return size.w;
    },

    getHeight : function (){
        var size = this.frameworkMap.getSize();
        return size.h;
    },
    updateSize : function(){
        this.getFrameworkMap().updateSize();
    },

    /**
     * The OpenLayers ID can't be changed. With this function you can get the
     * viewer.viewercontroller.openlayers.OpenLayersLayer with the openlayersid
     * @param olId the openlayers id of the layer
     * @return a viewer.viewercontroller.openlayers.OpenLayersLayer that
     * contains the openlayers layer with the given id.
     */
    getLayerByOpenLayersId: function(olId){
        for (var i=0; i < this.layers.length; i++){
            if (this.layers[i].frameworkLayer){
                if (this.layers[i].frameworkLayer.id == olId){
                    return this.layers[i];
                }
            }
        }
    }
});<|endoftext|>


<commit_before>/*
 * Paper.js
 *
 * This file is part of Paper.js, a JavaScript Vector Graphics Library,
 * based on Scriptographer.org and designed to be largely API compatible.
 * http://paperjs.org/
 * http://scriptographer.org/
 *
 * Copyright (c) 2011, Juerg Lehni & Jonathan Puckey
 * http://lehni.org/ & http://jonathanpuckey.com/
 *
 * Distributed under the MIT license. See LICENSE file for details.
 *
 * All rights reserved.
 */

/**
 * @name PaperScript
 * @namespace
 */

/*#*/ if (options.parser == 'acorn') {
/*#*/ include('../../lib/acorn-min.js');
/*#*/ } else {
/*#*/ include('../../lib/esprima-min.js');
/*#*/ }

var PaperScript = this.PaperScript = new function() {
	// Operators to overload

	var binaryOperators = {
		'+': 'add',
		'-': 'subtract',
		'*': 'multiply',
		'/': 'divide',
		'%': 'modulo',
		'==': 'equals',
		'!=': 'equals'
	};

	var unaryOperators = {
		'-': 'negate',
		'+': null
	};

	// Use very short name for the binary operator (_$_) as well as the
	// unary operator ($_), as operations will be replaced with then.
	// The underscores stands for the values, and the $ for the operators.

	// Binary Operator Handler
	function _$_(left, operator, right) {
		var handler = binaryOperators[operator];
		if (left && left[handler]) {
			var res = left[handler](right);
			return operator === '!=' ? !res : res;
		}
		switch (operator) {
		case '+': return left + right;
		case '-': return left - right;
		case '*': return left * right;
		case '/': return left / right;
		case '%': return left % right;
		case '==': return left == right;
		case '!=': return left != right;
		default:
			throw new Error('Implement Operator: ' + operator);
		}
	}

	// Unary Operator Handler
	function $_(operator, value) {
		var handler = unaryOperators[operator];
		if (handler && value && value[handler])
			return value[handler]();
		switch (operator) {
		case '+': return +value;
		case '-': return -value;
		default:
			throw new Error('Implement Unary Operator: ' + operator);
		}
	}

	// AST Helpers

	/**
	 * Compiles PaperScript code into JavaScript code.
	 *
	 * @name PaperScript.compile
	 * @function
	 * @param {String} code The PaperScript code.
	 * @return {String} The compiled PaperScript as JavaScript code.
	 */
	function compile(code) {
		// Use Acorn or Esprima to translate the code into an AST structure
		// which is then walked and parsed for operators to overload.
		// Instead of modifying the AST and converting back to code, we directly
		// change the source code based on the parser's range information, so we
		// can preserve line-numbers in syntax errors and remove the need for
		// Escodegen.

		// Tracks code insertions so we can add their differences to the
		// original offsets.
		var insertions = [];

		// Converts an original offset to the one in the current state of the
		// modified code.
		function getOffset(offset) {
			var start = offset;
			// Add all insertions before this location together to calculate
			// the current offset
			for (var i = 0, l = insertions.length; i < l; i++) {
				var insertion = insertions[i];
				if (insertion[0] >= offset)
					break;
				offset += insertion[1];
			}
			return offset;
		}

		// Returns the node's code as a string, taking insertions into account.
		function getCode(node) {
			return code.substring(getOffset(node.range[0]),
					getOffset(node.range[1]));
		}

		// Replaces the node's code with a new version and keeps insertions
		// information up-to-date.
		function replaceCode(node, str) {
			var start = getOffset(node.range[0]),
				end = getOffset(node.range[1]);
			var insert = 0;
			// Sort insertions by their offset, so getOffest() can do its thing
			for (var i = insertions.length - 1; i >= 0; i--) {
				if (start > insertions[i][0]) {
					insert = i + 1;
					break;
				}
			}
			insertions.splice(insert, 0, [start, str.length - end + start]);
			code = code.substring(0, start) + str + code.substring(end);
		}

		// Recursively walks the AST and replaces the code of certain nodes
		function walkAst(node) {
			for (var key in node) {
				if (key === 'range')
					continue;
				var value = node[key];
				if (Array.isArray(value)) {
					for (var i = 0, l = value.length; i < l; i++)
						walkAst(value[i]);
				} else if (Base.isObject(value)) {
					walkAst(value);
				}
			}
			switch (node.type) {
			case 'BinaryExpression':
				if (node.operator in binaryOperators
						&& node.left.type !== 'Literal') {
					var left = getCode(node.left),
						right = getCode(node.right);
					replaceCode(node, '_$_(' + left + ', "' + node.operator
							+ '", ' + right + ')');
				}
				break;
			case 'AssignmentExpression':
				if (/^.=$/.test(node.operator)
						&& node.left.type !== 'Literal') {
					var left = getCode(node.left),
						right = getCode(node.right);
					replaceCode(node, left + ' = _$_(' + left + ', "'
							+ node.operator[0] + '", ' + right + ')');
				}
				break;
			case 'UpdateExpression':
				if (!node.prefix) {
					var arg = getCode(node.argument);
					replaceCode(node, arg + ' = _$_(' + arg + ', "'
							+ node.operator[0] + '", 1)');
				}
				break;
			case 'UnaryExpression':
				if (node.operator in unaryOperators
						&& node.argument.type !== 'Literal') {
					var arg = getCode(node.argument);
					replaceCode(node, '$_("' + node.operator + '", '
							+ arg + ')');
				}
				break;
			}
		}
		// Now do the parsing magic
/*#*/ if (options.parser == 'acorn') {
		walkAst(acorn.parse(code, { ranges: true }));
/*#*/ } else {
		walkAst(esprima.parse(code, { range: true }));
/*#*/ }
		return code;
	}

	/**
	 * Evaluates parsed PaperScript code in the passed {@link PaperScope}
	 * object. It also installs handlers automatically for us.
	 *
	 * @name PaperScript.evaluate
	 * @function
	 * @param {String} code The PaperScript code.
	 * @param {PaperScript} scope The scope in which the code is executed.
	 * @return {Object} The result of the code evaluation.
	 */
	function evaluate(code, scope) {
		// Set currently active scope.
		paper = scope;
		var view = scope.project && scope.project.view,
			res;
		// Define variables for potential handlers, so eval() calls below to
		// fetch their values do not require try-catch around them.
		// Use with(){} in order to make the scope the current 'global' scope
		// instead of window.
		with (scope) {
			// Within this, use a function scope, so local variables to not try
			// and set themselves on the scope object.
			(function() {
				var onActivate, onDeactivate, onEditOptions,
					onMouseDown, onMouseUp, onMouseDrag, onMouseMove,
					onKeyDown, onKeyUp, onFrame, onResize;
				res = eval(compile(code));
				// Only look for tool handlers if something resembling their
				// name is contained in the code.
				if (/on(?:Key|Mouse)(?:Up|Down|Move|Drag)/.test(code)) {
					Base.each(Tool.prototype._events, function(key) {
						var value = eval(key);
						if (value) {
							// Use the getTool accessor that handles auto tool
							// creation for us:
							scope.getTool()[key] = value;
						}
					});
				}
				if (view) {
					view.setOnResize(onResize);
					// Fire resize event directly, so any user
					// defined resize handlers are called.
					view.fire('resize', {
						size: view.size,
						delta: new Point()
					});
					view.setOnFrame(onFrame);
					// Automatically draw view at the end.
					view.draw();
				}
			}).call(scope);
		}
		return res;
	}

/*#*/ if (options.browser) {
	// Code borrowed from Coffee Script:
	function request(url, scope) {
		var xhr = new (window.ActiveXObject || XMLHttpRequest)(
				'Microsoft.XMLHTTP');
		xhr.open('GET', url, true);
		if (xhr.overrideMimeType)
			xhr.overrideMimeType('text/plain');
		xhr.onreadystatechange = function() {
			if (xhr.readyState === 4) {
				return evaluate(xhr.responseText, scope);
			}
		};
		return xhr.send(null);
	}

	function load() {
		var scripts = document.getElementsByTagName('script');
		for (var i = 0, l = scripts.length; i < l; i++) {
			var script = scripts[i];
			// Only load this script if it not loaded already.
			// Support both text/paperscript and text/x-paperscript:
			if (/^text\/(?:x-|)paperscript$/.test(script.type)
					&& !script.getAttribute('data-paper-ignore')) {
				// Produce a new PaperScope for this script now. Scopes are
				// cheap so let's not worry about the initial one that was
				// already created.
				// Define an id for each PaperScript, so its scope can be
				// retrieved through PaperScope.get().
				// If a canvas id is provided, pass it on to the PaperScope
				// so a project is created for it now.
				var scope = new PaperScope(script);
				scope.setup(PaperScript.getAttribute(script, 'canvas'));
				if (script.src) {
					// If we're loading from a source, request that first and then
					// run later.
					request(script.src, scope);
				} else {
					// We can simply get the code form the script tag.
					evaluate(script.innerHTML, scope);
				}
				// Mark script as loaded now.
				script.setAttribute('data-paper-ignore', true);
			}
		}
	}

	DomEvent.add(window, { load: load });

	// Produces helpers to e.g. check for both 'canvas' and 'data-paper-canvas'
	// attributes:
	function handleAttribute(name) {
		name += 'Attribute';
		return function(el, attr) {
			return el[name](attr) || el[name]('data-paper-' + attr);
		};
	}

	return {
		compile: compile,
		evaluate: evaluate,
		load: load,
		getAttribute: handleAttribute('get'),
		hasAttribute: handleAttribute('has')
	};

/*#*/ } else { // !options.browser

	return {
		compile: compile,
		evaluate: evaluate
	};

/*#*/ } // !options.browser
};

// Export load directly:
this.load = PaperScript.load;
<commit_msg>No need to throw operator exceptions since we're checking for their existence in the parsing.<commit_after>/*
 * Paper.js
 *
 * This file is part of Paper.js, a JavaScript Vector Graphics Library,
 * based on Scriptographer.org and designed to be largely API compatible.
 * http://paperjs.org/
 * http://scriptographer.org/
 *
 * Copyright (c) 2011, Juerg Lehni & Jonathan Puckey
 * http://lehni.org/ & http://jonathanpuckey.com/
 *
 * Distributed under the MIT license. See LICENSE file for details.
 *
 * All rights reserved.
 */

/**
 * @name PaperScript
 * @namespace
 */

/*#*/ if (options.parser == 'acorn') {
/*#*/ include('../../lib/acorn-min.js');
/*#*/ } else {
/*#*/ include('../../lib/esprima-min.js');
/*#*/ }

var PaperScript = this.PaperScript = new function() {
	// Operators to overload

	var binaryOperators = {
		'+': 'add',
		'-': 'subtract',
		'*': 'multiply',
		'/': 'divide',
		'%': 'modulo',
		'==': 'equals',
		'!=': 'equals'
	};

	var unaryOperators = {
		'-': 'negate',
		'+': null
	};

	// Use very short name for the binary operator (_$_) as well as the
	// unary operator ($_), as operations will be replaced with then.
	// The underscores stands for the values, and the $ for the operators.

	// Binary Operator Handler
	function _$_(left, operator, right) {
		var handler = binaryOperators[operator];
		if (left && left[handler]) {
			var res = left[handler](right);
			return operator === '!=' ? !res : res;
		}
		switch (operator) {
		case '+': return left + right;
		case '-': return left - right;
		case '*': return left * right;
		case '/': return left / right;
		case '%': return left % right;
		case '==': return left == right;
		case '!=': return left != right;
		}
	}

	// Unary Operator Handler
	function $_(operator, value) {
		var handler = unaryOperators[operator];
		if (handler && value && value[handler])
			return value[handler]();
		switch (operator) {
		case '+': return +value;
		case '-': return -value;
		}
	}

	// AST Helpers

	/**
	 * Compiles PaperScript code into JavaScript code.
	 *
	 * @name PaperScript.compile
	 * @function
	 * @param {String} code The PaperScript code.
	 * @return {String} The compiled PaperScript as JavaScript code.
	 */
	function compile(code) {
		// Use Acorn or Esprima to translate the code into an AST structure
		// which is then walked and parsed for operators to overload.
		// Instead of modifying the AST and converting back to code, we directly
		// change the source code based on the parser's range information, so we
		// can preserve line-numbers in syntax errors and remove the need for
		// Escodegen.

		// Tracks code insertions so we can add their differences to the
		// original offsets.
		var insertions = [];

		// Converts an original offset to the one in the current state of the
		// modified code.
		function getOffset(offset) {
			var start = offset;
			// Add all insertions before this location together to calculate
			// the current offset
			for (var i = 0, l = insertions.length; i < l; i++) {
				var insertion = insertions[i];
				if (insertion[0] >= offset)
					break;
				offset += insertion[1];
			}
			return offset;
		}

		// Returns the node's code as a string, taking insertions into account.
		function getCode(node) {
			return code.substring(getOffset(node.range[0]),
					getOffset(node.range[1]));
		}

		// Replaces the node's code with a new version and keeps insertions
		// information up-to-date.
		function replaceCode(node, str) {
			var start = getOffset(node.range[0]),
				end = getOffset(node.range[1]);
			var insert = 0;
			// Sort insertions by their offset, so getOffest() can do its thing
			for (var i = insertions.length - 1; i >= 0; i--) {
				if (start > insertions[i][0]) {
					insert = i + 1;
					break;
				}
			}
			insertions.splice(insert, 0, [start, str.length - end + start]);
			code = code.substring(0, start) + str + code.substring(end);
		}

		// Recursively walks the AST and replaces the code of certain nodes
		function walkAst(node) {
			for (var key in node) {
				if (key === 'range')
					continue;
				var value = node[key];
				if (Array.isArray(value)) {
					for (var i = 0, l = value.length; i < l; i++)
						walkAst(value[i]);
				} else if (Base.isObject(value)) {
					walkAst(value);
				}
			}
			switch (node.type) {
			case 'BinaryExpression':
				if (node.operator in binaryOperators
						&& node.left.type !== 'Literal') {
					var left = getCode(node.left),
						right = getCode(node.right);
					replaceCode(node, '_$_(' + left + ', "' + node.operator
							+ '", ' + right + ')');
				}
				break;
			case 'AssignmentExpression':
				if (/^.=$/.test(node.operator)
						&& node.left.type !== 'Literal') {
					var left = getCode(node.left),
						right = getCode(node.right);
					replaceCode(node, left + ' = _$_(' + left + ', "'
							+ node.operator[0] + '", ' + right + ')');
				}
				break;
			case 'UpdateExpression':
				if (!node.prefix) {
					var arg = getCode(node.argument);
					replaceCode(node, arg + ' = _$_(' + arg + ', "'
							+ node.operator[0] + '", 1)');
				}
				break;
			case 'UnaryExpression':
				if (node.operator in unaryOperators
						&& node.argument.type !== 'Literal') {
					var arg = getCode(node.argument);
					replaceCode(node, '$_("' + node.operator + '", '
							+ arg + ')');
				}
				break;
			}
		}
		// Now do the parsing magic
/*#*/ if (options.parser == 'acorn') {
		walkAst(acorn.parse(code, { ranges: true }));
/*#*/ } else {
		walkAst(esprima.parse(code, { range: true }));
/*#*/ }
		return code;
	}

	/**
	 * Evaluates parsed PaperScript code in the passed {@link PaperScope}
	 * object. It also installs handlers automatically for us.
	 *
	 * @name PaperScript.evaluate
	 * @function
	 * @param {String} code The PaperScript code.
	 * @param {PaperScript} scope The scope in which the code is executed.
	 * @return {Object} The result of the code evaluation.
	 */
	function evaluate(code, scope) {
		// Set currently active scope.
		paper = scope;
		var view = scope.project && scope.project.view,
			res;
		// Define variables for potential handlers, so eval() calls below to
		// fetch their values do not require try-catch around them.
		// Use with(){} in order to make the scope the current 'global' scope
		// instead of window.
		with (scope) {
			// Within this, use a function scope, so local variables to not try
			// and set themselves on the scope object.
			(function() {
				var onActivate, onDeactivate, onEditOptions,
					onMouseDown, onMouseUp, onMouseDrag, onMouseMove,
					onKeyDown, onKeyUp, onFrame, onResize;
				res = eval(compile(code));
				// Only look for tool handlers if something resembling their
				// name is contained in the code.
				if (/on(?:Key|Mouse)(?:Up|Down|Move|Drag)/.test(code)) {
					Base.each(Tool.prototype._events, function(key) {
						var value = eval(key);
						if (value) {
							// Use the getTool accessor that handles auto tool
							// creation for us:
							scope.getTool()[key] = value;
						}
					});
				}
				if (view) {
					view.setOnResize(onResize);
					// Fire resize event directly, so any user
					// defined resize handlers are called.
					view.fire('resize', {
						size: view.size,
						delta: new Point()
					});
					view.setOnFrame(onFrame);
					// Automatically draw view at the end.
					view.draw();
				}
			}).call(scope);
		}
		return res;
	}

/*#*/ if (options.browser) {
	// Code borrowed from Coffee Script:
	function request(url, scope) {
		var xhr = new (window.ActiveXObject || XMLHttpRequest)(
				'Microsoft.XMLHTTP');
		xhr.open('GET', url, true);
		if (xhr.overrideMimeType)
			xhr.overrideMimeType('text/plain');
		xhr.onreadystatechange = function() {
			if (xhr.readyState === 4) {
				return evaluate(xhr.responseText, scope);
			}
		};
		return xhr.send(null);
	}

	function load() {
		var scripts = document.getElementsByTagName('script');
		for (var i = 0, l = scripts.length; i < l; i++) {
			var script = scripts[i];
			// Only load this script if it not loaded already.
			// Support both text/paperscript and text/x-paperscript:
			if (/^text\/(?:x-|)paperscript$/.test(script.type)
					&& !script.getAttribute('data-paper-ignore')) {
				// Produce a new PaperScope for this script now. Scopes are
				// cheap so let's not worry about the initial one that was
				// already created.
				// Define an id for each PaperScript, so its scope can be
				// retrieved through PaperScope.get().
				// If a canvas id is provided, pass it on to the PaperScope
				// so a project is created for it now.
				var scope = new PaperScope(script);
				scope.setup(PaperScript.getAttribute(script, 'canvas'));
				if (script.src) {
					// If we're loading from a source, request that first and then
					// run later.
					request(script.src, scope);
				} else {
					// We can simply get the code form the script tag.
					evaluate(script.innerHTML, scope);
				}
				// Mark script as loaded now.
				script.setAttribute('data-paper-ignore', true);
			}
		}
	}

	DomEvent.add(window, { load: load });

	// Produces helpers to e.g. check for both 'canvas' and 'data-paper-canvas'
	// attributes:
	function handleAttribute(name) {
		name += 'Attribute';
		return function(el, attr) {
			return el[name](attr) || el[name]('data-paper-' + attr);
		};
	}

	return {
		compile: compile,
		evaluate: evaluate,
		load: load,
		getAttribute: handleAttribute('get'),
		hasAttribute: handleAttribute('has')
	};

/*#*/ } else { // !options.browser

	return {
		compile: compile,
		evaluate: evaluate
	};

/*#*/ } // !options.browser
};

// Export load directly:
this.load = PaperScript.load;
<|endoftext|>