<commit_before>//
// Copyright (c) 2016 Satoshi Nakajima (https://github.com/snakajima)
// License: The MIT License
//

import React, { Component } from 'react';

class Selection extends Component {
  constructor(props) {
    super();
  }

  render() {
    const scale = this.props.scale;
    const x = this.props.element.x * scale;
    const y = this.props.element.y * scale;
    const w = this.props.element.w * scale;
    const h = this.props.element.h * scale;
    return (

    );
  }
}

export default Selection;
<commit_msg>selection:draggable<commit_after>//
// Copyright (c) 2016 Satoshi Nakajima (https://github.com/snakajima)
// License: The MIT License
//

import React, { Component } from 'react';
import DragContext from './DragContext';

class Selection extends Component {
  constructor(props) {
    super();
    this.onDragStart = this.onDragStart.bind(this);
  }

  onDragStart(e,type) {
    DragContext.setContext({ pageIndex:this.props.pageIndex, id:this.props.element.id,
                             x:e.clientX, y:e.clientY });
  }

  render() {
    const scale = this.props.scale;
    const x = this.props.element.x * scale;
    const y = this.props.element.y * scale;
    const w = this.props.element.w * scale;
    const h = this.props.element.h * scale;
    return (

this.onDragStart(e,0)}
        />
        this.onDragStart(e,0)}
        />
        this.onDragStart(e,0)}
        />
        this.onDragStart(e,0)}
        />
        this.onDragStart(e,0)}
        />
        this.onDragStart(e,0)}
        />
        this.onDragStart(e,0)}
        />
        this.onDragStart(e,0)}
        />
        this.onDragStart(e,0)}
        />

    );
  }
}

export default Selection;
<|endoftext|>


<commit_before>// ==UserScript==
// @name         Twitch Auto Theater
// @version      1.0.2
// @updateURL    https://raw.githubusercontent.com/domosapien/Twitch-Auto-Theater/master/twitch-auto-theater.js
// @downloadURL  https://raw.githubusercontent.com/domosapien/Twitch-Auto-Theater/master/twitch-auto-theater.js
// @match        www.twitch.tv/*
// @grant        none
// ==/UserScript==

/* jshint -W097 jquery:true */

'use strict';

var observer = new MutationObserver(function (mutations) {
	mutations.forEach(function (mutation) {
		if (!mutation.addedNodes) {
			return;
		}

		for (var i = 0; i < mutation.addedNodes.length; i++) {
			// do things to your newly added nodes here
			var $node = $(mutation.addedNodes[i]).find('button.player-button--theatre');
			if ($node.length) {
				$node.trigger('click');
				observer.disconnect();
			}
		}
	});
});

function startObserver() {
	observer.observe(document.body, {
		childList: true,
		subtree: true,
		attributes: false,
		characterData: false
	});
}

startObserver();

window.onpopstate = function (event) {
	startObserver();
};
<commit_msg>Short-circuit observer to exit on first click<commit_after>// ==UserScript==
// @name         Twitch Auto Theater
// @version      1.0.2
// @updateURL    https://raw.githubusercontent.com/domosapien/Twitch-Auto-Theater/master/twitch-auto-theater.js
// @downloadURL  https://raw.githubusercontent.com/domosapien/Twitch-Auto-Theater/master/twitch-auto-theater.js
// @match        www.twitch.tv/*
// @grant        none
// ==/UserScript==

/* jshint -W097 jquery:true */

'use strict';

var observer = new MutationObserver(function (mutations) {
	mutations.forEach(function (mutation) {
		if (!mutation.addedNodes) {
			return;
		}

		for (var i = 0; i < mutation.addedNodes.length; i++) {
			// do things to your newly added nodes here
			var $node = $(mutation.addedNodes[i]).find('button.player-button--theatre');
			if ($node.length) {
				$node.trigger('click');
				observer.disconnect();
				return;
			}
		}
	});
});

function startObserver() {
	observer.observe(document.body, {
		childList: true,
		subtree: true,
		attributes: false,
		characterData: false
	});
}

startObserver();

window.onpopstate = function (event) {
	startObserver();
};
<|endoftext|>


<commit_before>#!/usr/bin/env node

process.stdin.resume();
process.stdin.setEncoding('utf8');

var wrench = require('wrench');
var fs = require('fs');
var path = require('path');
var json = require('json');

var argv = require('optimist').argv;

var command = argv._[0];
var arg1 = argv._[1];
var force = argv.force ? true : false;
var sampleDirName = 'nombo-samples';

var parsePackageFile = function(moduleDir) {
	var packageFile = moduleDir + '/package.json';
	try {
		if(fs.existsSync(packageFile)) {
			return json.parse(fs.readFileSync(packageFile, 'utf8'));
		}
	} catch(e) {}

	return {};
}

var errorMessage = function(message) {
	console.log('\033[0;31m[Error]\033[0m ' + message);
}

var successMessage = function(message) {
	console.log('\033[0;32m[Success]\033[0m ' + message);
}

var warningMessage = function(message) {
	console.log('\033[0;33m[Warning]\033[0m ' + message);
}

var showCorrectUsage = function() {
	console.log('Usage: nombo [options] [command]\n');
	console.log('Options:');
	console.log("  -v                Get the version number of the current Nombo installation");
	console.log('  --help            Get info on how to use this command');
	console.log('  --force           Force all necessary directory modifications without prompts');
	console.log();
	console.log('Commands:');
	console.log('  create <appname>  Create a new app <appname> within the working directory');
	console.log('  samples           Create an nombo-samples directory');
}

var failedToRemoveDirMessage = function(dirPath) {
	errorMessage('Failed to remove existing directory at ' + dirPath + '. This directory may be used by another program or you may not have the permission to remove it.');
}

var failedToCreateMessage = function() {
	errorMessage('Failed to create necessary files. Please check your permissions and try again.');
}

var prompt = function(message, callback) {
	process.stdout.write(message + ' ');
	process.stdin.on('data', function inputHandler(text) {
		process.stdin.removeListener('data', inputHandler);
		callback(text)
	});
}

var prompConfirm = function(message, callback) {
	prompt(message, function(data) {
		data = data.toLowerCase().replace(/[\r\n]/g, '');
		callback(data == 'y' || data == 'yes');
	});
}

var copyDirRecursive = function(src, dest) {
	try {
		wrench.copyDirSyncRecursive(src, dest);
		return true;
	} catch(e) {
		failedToCreateMessage();
	}
	return false;
}

var rmdirRecursive = function(dirname) {
	try {
		wrench.rmdirSyncRecursive(dirname);
		return true;
	} catch(e) {
		failedToRemoveDirMessage(dirname);
	}
	return false;
}

var createFrameworkDir = function(destDir, callback) {
	var nomboSrcDir = __dirname + '/..';
	var progressMessage = 'Installing Nombo modules... This may take a while.';
	var finishedMessage = 'Done';
	var success = true;
	var subModulesDir = destDir + '/node_modules';
	var mainModulesDir = destDir + '/../';
	var coreModulesDir = destDir + '/';

	var moveModules = function() {
		var nodeModules = fs.readdirSync(subModulesDir);
		var coreModules, coreModuleDir;
		var curFile, moduleDest;
		var i, j;
		for(i in nodeModules) {
			curFile = subModulesDir + '/' + nodeModules[i];
			if(nodeModules[i] == 'nombo') {
				coreModules = fs.readdirSync(curFile);
				for(j in coreModules) {
					if(coreModules[j] != 'index.js') {
						coreModuleDir = curFile + '/' + coreModules[j];
						copyDirRecursive(coreModuleDir, coreModulesDir + coreModules[j]);
						wrench.rmdirSyncRecursive(coreModuleDir);
					}
				}
			} else if(fs.statSync(curFile).isDirectory()) {
				moduleDest = mainModulesDir + nodeModules[i];
				if(fs.existsSync(moduleDest)) {
					wrench.rmdirSyncRecursive(moduleDest);
				}
				copyDirRecursive(curFile, moduleDest);
				wrench.rmdirSyncRecursive(curFile);
			}
		}
	}

	var proceed = function(confirm) {
		if(confirm) {
			console.log(progressMessage);
			success = rmdirRecursive(destDir) && copyDirRecursive(nomboSrcDir, destDir);
			moveModules();
			console.log(finishedMessage);
		}
		callback(success);
	}

	if(fs.existsSync(destDir)) {
		var srcPkg = parsePackageFile(nomboSrcDir);
		var destPkg = parsePackageFile(destDir);

		if(srcPkg.version == destPkg.version) {
			moveModules();
			callback(success);
		} else if(force) {
			console.log(progressMessage);
			success = rmdirRecursive(destDir) && copyDirRecursive(nomboSrcDir, destDir);
			moveModules();
			console.log(finishedMessage);
			callback(success);
		} else {
			prompConfirm('A different version of the Nombo framework directory already exists at ' + nomboDestDir + '. Overwrite it (y/n)?', proceed);
		}
	} else {
		console.log(progressMessage);
		success = copyDirRecursive(nomboSrcDir, destDir);
		moveModules();
		console.log(finishedMessage);
		callback(success);
	}
}

var createSamplesDir = function(destDir, callback) {
	var samplesSrcPath = __dirname + '/../samples';
	var progressMessage = 'Setting up sample apps...';
	var finishedMessage = 'Done';
	var success = true;
	var proceed = function(confirm) {
		if(confirm) {
			console.log(progressMessage);
			success = rmdirRecursive(destDir) && copyDirRecursive(samplesSrcPath, destDir);
			console.log(finishedMessage);
			callback(success);
		} else {
			errorMessage('Skipped samples setup process');
			callback(false);
		}
	}

	if(fs.existsSync(destDir)) {
		if(force) {
			console.log(progressMessage);
			success = rmdirRecursive(destDir) && copyDirRecursive(samplesSrcPath, destDir);
			console.log(finishedMessage);
			callback(success);
		} else {
			prompConfirm('A directory already exists at ' + destDir + '. Overwrite it (y/n)?', proceed);
		}
	} else {
		console.log(progressMessage);
		success = copyDirRecursive(samplesSrcPath, destDir);
		console.log(finishedMessage);
		callback(success);
	}
}

var createAppDir = function(destDir, callback) {
	var appSrcPath = __dirname + '/../app';
	var progressMessage = 'Setting up app structure...';
	var finishedMessage = 'Done';
	var success = true;
	var proceed = function(confirm) {
		if(confirm) {
			console.log(progressMessage);
			success = rmdirRecursive(destDir) && copyDirRecursive(appSrcPath, destDir);
			console.log(finishedMessage);
			callback(success);
		} else {
			errorMessage('Skipped app structure setup process');
			callback(false);
		}
	}

	if(fs.existsSync(destDir)) {
		if(force) {
			console.log(progressMessage);
			success = rmdirRecursive(destDir) && copyDirRecursive(appSrcPath, destDir);
			console.log(finishedMessage);
			callback(success);
		} else {
			prompConfirm('A directory already exists at ' + destDir + '. Overwrite it (y/n)?', proceed);
		}
	} else {
		console.log(progressMessage);
		success = copyDirRecursive(appSrcPath, destDir);
		console.log(finishedMessage);
		callback(success);
	}
}

if(argv.help) {
	showCorrectUsage();
	process.exit();
}

if(argv.v) {
	var nomboDir = __dirname + '/../../nombo';
	var nomboPkg = parsePackageFile(nomboDir);
	console.log('v' + nomboPkg.version);
	process.exit();
}

var wd = process.cwd();

var nodeModulesDir = wd + '/node_modules';
var nomboDestDir = nodeModulesDir + '/nombo';

if(!fs.existsSync(nodeModulesDir)) {
	fs.mkdirSync(nodeModulesDir);
}

if(command == 'create' || command == 'samples') {
	var begin = function(confirm) {
		if(confirm) {
			createFrameworkDir(nomboDestDir, function(frameworkSuccess) {
				if(frameworkSuccess) {
					if(command == 'samples') {
						var samplesDestDir = path.normalize(wd + '/' + sampleDirName);
						createSamplesDir(samplesDestDir, function(samplesSuccess) {
							if(samplesSuccess) {
								successMessage("Install process is complete. Run 'node " + sampleDirName + "/memo/server.node' to launch the memo sample app. Access at http://localhost:8000/");
							}
							process.exit();
						});
					} else if(command == 'create') {
						if(arg1) {
							var appDestDir = path.normalize(wd + '/' + arg1);
							createAppDir(appDestDir, function(appSuccess) {
								if(appSuccess) {
									successMessage("Install process is complete. Run 'node " + arg1 + "/server.node' to launch. Access at http://localhost:8000/");
								}
								process.exit();
							});
						} else {
							successMessage('The Nombo framework core has been installed. Nombo apps which are placed within the ' + wd + ' directory (including subdirectories) will use this framework core.');
							process.exit();
						}
					}
				} else {
					process.exit();
				}
			});
		} else {
			errorMessage("The Nombo installation was cancelled");
			process.exit();
		}
	}

	if(force) {
		begin(true);
	} else {
		prompConfirm('You are about to install Nombo. Please note that as part of the installation process, new modules will be added inside the ' + nodeModulesDir + ' directory - Existing modules may be overwitten. Would you like to continue (y/n)?', begin);
	}
} else {
	errorMessage("'" + command + "' is not a valid Nombo command");
	showCorrectUsage();
	process.exit();
}
<commit_msg>Changed cli.js to use linux line endings<commit_after>#!/usr/bin/env node

process.stdin.resume();
process.stdin.setEncoding('utf8');

var wrench = require('wrench');
var fs = require('fs');
var path = require('path');
var json = require('json');

var argv = require('optimist').argv;

var command = argv._[0];
var arg1 = argv._[1];
var force = argv.force ? true : false;
var sampleDirName = 'nombo-samples';

var parsePackageFile = function(moduleDir) {
	var packageFile = moduleDir + '/package.json';
	try {
		if(fs.existsSync(packageFile)) {
			return json.parse(fs.readFileSync(packageFile, 'utf8'));
		}
	} catch(e) {}

	return {};
}

var errorMessage = function(message) {
	console.log('\033[0;31m[Error]\033[0m ' + message);
}

var successMessage = function(message) {
	console.log('\033[0;32m[Success]\033[0m ' + message);
}

var warningMessage = function(message) {
	console.log('\033[0;33m[Warning]\033[0m ' + message);
}

var showCorrectUsage = function() {
	console.log('Usage: nombo [options] [command]\n');
	console.log('Options:');
	console.log("  -v                Get the version number of the current Nombo installation");
	console.log('  --help            Get info on how to use this command');
	console.log('  --force           Force all necessary directory modifications without prompts');
	console.log();
	console.log('Commands:');
	console.log('  create <appname>  Create a new app <appname> within the working directory');
	console.log('  samples           Create an nombo-samples directory');
}

var failedToRemoveDirMessage = function(dirPath) {
	errorMessage('Failed to remove existing directory at ' + dirPath + '. This directory may be used by another program or you may not have the permission to remove it.');
}

var failedToCreateMessage = function() {
	errorMessage('Failed to create necessary files. Please check your permissions and try again.');
}

var prompt = function(message, callback) {
	process.stdout.write(message + ' ');
	process.stdin.on('data', function inputHandler(text) {
		process.stdin.removeListener('data', inputHandler);
		callback(text)
	});
}

var prompConfirm = function(message, callback) {
	prompt(message, function(data) {
		data = data.toLowerCase().replace(/[\r\n]/g, '');
		callback(data == 'y' || data == 'yes');
	});
}

var copyDirRecursive = function(src, dest) {
	try {
		wrench.copyDirSyncRecursive(src, dest);
		return true;
	} catch(e) {
		failedToCreateMessage();
	}
	return false;
}

var rmdirRecursive = function(dirname) {
	try {
		wrench.rmdirSyncRecursive(dirname);
		return true;
	} catch(e) {
		failedToRemoveDirMessage(dirname);
	}
	return false;
}

var createFrameworkDir = function(destDir, callback) {
	var nomboSrcDir = __dirname + '/..';
	var progressMessage = 'Installing Nombo modules... This may take a while.';
	var finishedMessage = 'Done';
	var success = true;
	var subModulesDir = destDir + '/node_modules';
	var mainModulesDir = destDir + '/../';
	var coreModulesDir = destDir + '/';

	var moveModules = function() {
		var nodeModules = fs.readdirSync(subModulesDir);
		var coreModules, coreModuleDir;
		var curFile, moduleDest;
		var i, j;
		for(i in nodeModules) {
			curFile = subModulesDir + '/' + nodeModules[i];
			if(nodeModules[i] == 'nombo') {
				coreModules = fs.readdirSync(curFile);
				for(j in coreModules) {
					if(coreModules[j] != 'index.js') {
						coreModuleDir = curFile + '/' + coreModules[j];
						copyDirRecursive(coreModuleDir, coreModulesDir + coreModules[j]);
						wrench.rmdirSyncRecursive(coreModuleDir);
					}
				}
			} else if(fs.statSync(curFile).isDirectory()) {
				moduleDest = mainModulesDir + nodeModules[i];
				if(fs.existsSync(moduleDest)) {
					wrench.rmdirSyncRecursive(moduleDest);
				}
				copyDirRecursive(curFile, moduleDest);
				wrench.rmdirSyncRecursive(curFile);
			}
		}
	}

	var proceed = function(confirm) {
		if(confirm) {
			console.log(progressMessage);
			success = rmdirRecursive(destDir) && copyDirRecursive(nomboSrcDir, destDir);
			moveModules();
			console.log(finishedMessage);
		}
		callback(success);
	}

	if(fs.existsSync(destDir)) {
		var srcPkg = parsePackageFile(nomboSrcDir);
		var destPkg = parsePackageFile(destDir);

		if(srcPkg.version == destPkg.version) {
			moveModules();
			callback(success);
		} else if(force) {
			console.log(progressMessage);
			success = rmdirRecursive(destDir) && copyDirRecursive(nomboSrcDir, destDir);
			moveModules();
			console.log(finishedMessage);
			callback(success);
		} else {
			prompConfirm('A different version of the Nombo framework directory already exists at ' + nomboDestDir + '. Overwrite it (y/n)?', proceed);
		}
	} else {
		console.log(progressMessage);
		success = copyDirRecursive(nomboSrcDir, destDir);
		moveModules();
		console.log(finishedMessage);
		callback(success);
	}
}

var createSamplesDir = function(destDir, callback) {
	var samplesSrcPath = __dirname + '/../samples';
	var progressMessage = 'Setting up sample apps...';
	var finishedMessage = 'Done';
	var success = true;
	var proceed = function(confirm) {
		if(confirm) {
			console.log(progressMessage);
			success = rmdirRecursive(destDir) && copyDirRecursive(samplesSrcPath, destDir);
			console.log(finishedMessage);
			callback(success);
		} else {
			errorMessage('Skipped samples setup process');
			callback(false);
		}
	}

	if(fs.existsSync(destDir)) {
		if(force) {
			console.log(progressMessage);
			success = rmdirRecursive(destDir) && copyDirRecursive(samplesSrcPath, destDir);
			console.log(finishedMessage);
			callback(success);
		} else {
			prompConfirm('A directory already exists at ' + destDir + '. Overwrite it (y/n)?', proceed);
		}
	} else {
		console.log(progressMessage);
		success = copyDirRecursive(samplesSrcPath, destDir);
		console.log(finishedMessage);
		callback(success);
	}
}

var createAppDir = function(destDir, callback) {
	var appSrcPath = __dirname + '/../app';
	var progressMessage = 'Setting up app structure...';
	var finishedMessage = 'Done';
	var success = true;
	var proceed = function(confirm) {
		if(confirm) {
			console.log(progressMessage);
			success = rmdirRecursive(destDir) && copyDirRecursive(appSrcPath, destDir);
			console.log(finishedMessage);
			callback(success);
		} else {
			errorMessage('Skipped app structure setup process');
			callback(false);
		}
	}

	if(fs.existsSync(destDir)) {
		if(force) {
			console.log(progressMessage);
			success = rmdirRecursive(destDir) && copyDirRecursive(appSrcPath, destDir);
			console.log(finishedMessage);
			callback(success);
		} else {
			prompConfirm('A directory already exists at ' + destDir + '. Overwrite it (y/n)?', proceed);
		}
	} else {
		console.log(progressMessage);
		success = copyDirRecursive(appSrcPath, destDir);
		console.log(finishedMessage);
		callback(success);
	}
}

if(argv.help) {
	showCorrectUsage();
	process.exit();
}

if(argv.v) {
	var nomboDir = __dirname + '/../../nombo';
	var nomboPkg = parsePackageFile(nomboDir);
	console.log('v' + nomboPkg.version);
	process.exit();
}

var wd = process.cwd();

var nodeModulesDir = wd + '/node_modules';
var nomboDestDir = nodeModulesDir + '/nombo';

if(!fs.existsSync(nodeModulesDir)) {
	fs.mkdirSync(nodeModulesDir);
}

if(command == 'create' || command == 'samples') {
	var begin = function(confirm) {
		if(confirm) {
			createFrameworkDir(nomboDestDir, function(frameworkSuccess) {
				if(frameworkSuccess) {
					if(command == 'samples') {
						var samplesDestDir = path.normalize(wd + '/' + sampleDirName);
						createSamplesDir(samplesDestDir, function(samplesSuccess) {
							if(samplesSuccess) {
								successMessage("Install process is complete. Run 'node " + sampleDirName + "/memo/server.node' to launch the memo sample app. Access at http://localhost:8000/");
							}
							process.exit();
						});
					} else if(command == 'create') {
						if(arg1) {
							var appDestDir = path.normalize(wd + '/' + arg1);
							createAppDir(appDestDir, function(appSuccess) {
								if(appSuccess) {
									successMessage("Install process is complete. Run 'node " + arg1 + "/server.node' to launch. Access at http://localhost:8000/");
								}
								process.exit();
							});
						} else {
							successMessage('The Nombo framework core has been installed. Nombo apps which are placed within the ' + wd + ' directory (including subdirectories) will use this framework core.');
							process.exit();
						}
					}
				} else {
					process.exit();
				}
			});
		} else {
			errorMessage("The Nombo installation was cancelled");
			process.exit();
		}
	}

	if(force) {
		begin(true);
	} else {
		prompConfirm('You are about to install Nombo. Please note that as part of the installation process, new modules will be added inside the ' + nodeModulesDir + ' directory - Existing modules may be overwitten. Would you like to continue (y/n)?', begin);
	}
} else {
	errorMessage("'" + command + "' is not a valid Nombo command");
	showCorrectUsage();
	process.exit();
}
<|endoftext|>


<commit_before>/*
 *
 * The MIT License (MIT)
 *
 * Copyright (c) 2013-2014 Jiri Vrany, Jiri Hnidek
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 */

"use strict";

/* globals define, ArrayBuffer */

define(["taggroup"], function(tagGroup) {

    describe("Tag Group commands test suite", function() {
        var testNode, view, messageLen, mockBuffer, mockView, result;

        describe("received tag group subscribe command", function() {
            beforeEach(function() {
                testNode = tagGroup.subscribe(182, 31);
                view = new DataView(testNode);
            });

            it("length of subscribe command should be equal to 17", function() {
                expect(testNode.byteLength).toEqual(17);
            });

            it("first byte - opcode - should be 66", function() {
                expect(view.getUint8(0)).toEqual(66);
            });

            it("second byte - message length - should be 14 ", function() {
                expect(view.getUint8(1)).toEqual(17);
            });

            it("third byte - share - should be 0 ", function() {
                expect(view.getUint8(2)).toEqual(0);
            });

            it("fourth byte node ID should be 182", function() {
                expect(view.getUint32(3)).toEqual(182);
            });

            it("tagGroup (byte 8) id should be 31", function() {
                expect(view.getUint16(7)).toEqual(31);
            });

        });

        describe("got TagGroupCreate from server", function() {
            beforeEach(function() {

                messageLen = 11;
                mockBuffer = new ArrayBuffer(messageLen);
                view = new DataView(mockBuffer);

                view.setUint8(0, 64); //tagGroupCreate command
                view.setUint8(1, 17); //length
                view.setUint8(2, 0); //share is 0
                view.setUint32(3, 115); //Node ID
                view.setUint16(7, 68); //TagGroupID
                view.setUint16(9, 62);//custom type

            });

            it("command should be parsed out as TAG_GROUP_CREATE, NODE_ID = 111 object", function() {

                mockView = new DataView(mockBuffer);
                result = tagGroup.getTagGroupValues(64, mockView, 0, mockBuffer.byteLength);

                expect(result).toEqual({
                    CMD: "TAG_GROUP_CREATE",
                    SHARE: 0,
                    NODE_ID: 115,
                    TAG_GROUP_ID: 68,
                    CUSTOM_TYPE: 62
                });
            });
        });

    });

});
<commit_msg>cleanup of tagLayerGroup module<commit_after>/*
 *
 * The MIT License (MIT)
 *
 * Copyright (c) 2013-2014 Jiri Vrany, Jiri Hnidek
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 */

"use strict";

/* globals define, ArrayBuffer */

define(["taggroup"], function(tagGroup) {

    describe("Tag Group commands test suite", function() {
        var testNode, view, messageLen, mockBuffer, mockView, result;

        describe("Prepare TagGroupUnsubscribe command", function() {
            beforeEach(function() {
                testNode = tagGroup.subscribe(182, 31);
                view = new DataView(testNode);
            });

            it("length of subscribe command should be equal to 17", function() {
                expect(testNode.byteLength).toEqual(17);
            });

            it("first byte - opcode - should be 66", function() {
                expect(view.getUint8(0)).toEqual(66);
            });

            it("second byte - message length - should be 14 ", function() {
                expect(view.getUint8(1)).toEqual(17);
            });

            it("third byte - share - should be 0 ", function() {
                expect(view.getUint8(2)).toEqual(0);
            });

            it("fourth byte node ID should be 182", function() {
                expect(view.getUint32(3)).toEqual(182);
            });

            it("tagGroup (byte 8) id should be 31", function() {
                expect(view.getUint16(7)).toEqual(31);
            });

        });

        describe("Prepare tagGroupUnsubscribe command", function() {
            beforeEach(function() {
                testNode = tagGroup.unsubscribe(182, 31);
                view = new DataView(testNode);
            });

            it("first byte - opCode - should be 67", function() {
                expect(view.getUint8(0)).toEqual(67);
            });

        });

        describe("got TagGroupCreate from server", function() {
            beforeEach(function() {

                messageLen = 11;
                mockBuffer = new ArrayBuffer(messageLen);
                view = new DataView(mockBuffer);

                view.setUint8(0, 64); //tagGroupCreate command
                view.setUint8(1, messageLen); //length
                view.setUint8(2, 0); //share is 0
                view.setUint32(3, 115); //Node ID
                view.setUint16(7, 68); //TagGroupID
                view.setUint16(9, 62); //custom type

            });

            it("command should be parsed out as TAG_GROUP_CREATE, NODE_ID = 111 object", function() {

                mockView = new DataView(mockBuffer);
                result = tagGroup.getTagGroupValues(64, mockView, 0, mockBuffer.byteLength);

                expect(result).toEqual({
                    CMD: "TAG_GROUP_CREATE",
                    SHARE: 0,
                    NODE_ID: 115,
                    TAG_GROUP_ID: 68,
                    CUSTOM_TYPE: 62
                });
            });
        });

        describe("got TagGroupDestroy from server", function() {
            beforeEach(function() {

                messageLen = 9;
                mockBuffer = new ArrayBuffer(messageLen);
                view = new DataView(mockBuffer);

                view.setUint8(0, 65); //tagGroupDestroy command
                view.setUint8(1, messageLen); //length
                view.setUint8(2, 0); //share is 0
                view.setUint32(3, 115); //Node ID
                view.setUint16(7, 68); //TagGroupID

            });

            it("command should be parsed out as TAG_GROUP_DESTROY object", function() {

                mockView = new DataView(mockBuffer);
                result = tagGroup.getTagGroupValues(65, mockView, 0, mockBuffer.byteLength);

                expect(result).toEqual({
                    CMD: "TAG_GROUP_DESTROY",
                    SHARE: 0,
                    NODE_ID: 115,
                    TAG_GROUP_ID: 68
                });
            });
        });

        describe("got TagGroupSubscribe from server", function() {
            beforeEach(function() {

                messageLen = 17;
                mockBuffer = new ArrayBuffer(messageLen);
                view = new DataView(mockBuffer);

                view.setUint8(0, 66); //tagGroupSubscribe command
                view.setUint8(1, messageLen); //length
                view.setUint8(2, 0); //share is 0
                view.setUint32(3, 115); //Node ID
                view.setUint16(7, 68); //TagGroupID
                view.setUint32(9, 1215); //VERSION
                view.setUint32(13, 8115); //CRC32

            });

            it("command should be parsed out as TAG_GROUP_SUBSCRIBE object", function() {

                mockView = new DataView(mockBuffer);
                result = tagGroup.getTagGroupValues(66, mockView, 0, mockBuffer.byteLength);

                expect(result).toEqual({
                    CMD: "TAG_GROUP_SUBSCRIBE",
                    SHARE: 0,
                    NODE_ID: 115,
                    TAG_GROUP_ID: 68,
                    VERSION: 1215,
                    CRC32: 8115
                });
            });
        });

    });

});
<|endoftext|>


<commit_before>var _    = require('lodash');

var fs    = require('fs');
var spawn = require('child_process').spawn;
var join  = require('path').join;
var shell = require('shelljs');

module.exports = function ($){
  return new App($);
};

function App($) {
  this.$ = $;
  this.log = require('./log')($, 'electrify:app');
}

App.prototype.terminate = function(done){
  // this.log.info('terminating app');
  this.stop_meteor();
  this.$.plugins.stop(done);
};

App.prototype.init = function(done){
  this.log.info('initialize app');
  this.$.scaffold.prepare();
  this.$.waterfal([
    [this.ensure_deps               , this            ] ,
    [this.$.plugins.acquire         , this.$.plugins  ] ,
    [function(){ if(done) done(); } , null            ]
  ]);
};

App.prototype.run = function(done){
  this.log.info('running app');
  this.$.waterfal([
    [this.ensure_deps               , this            ] ,
    [this.$.plugins.auto_load       , this.$.plugins  ] ,
    [this.$.plugins.acquire         , this.$.plugins  ] ,
    [this.$.plugins.start           , this.$.plugins  ] ,
    [this.start_meteor              , this            ] ,
    [function(){ if(done) done(); } , null            ]
  ]);
};

App.prototype.start_meteor = function(done){

  this.log.info('starting meteor');

  var command = 'meteor' + (this.$.env.sys.is_windows ? '.bat' : '');
  var env     = _.clone(this.$.env.app.settings);

  _.extend(env, process.env);
  _.extend(env, this.$.plugins.env());

  this.meteor_process = spawn(command, [], {
    cwd: this.$.env.app.meteor,
    env: env,
    // ignore on windows and them pipe stdout and sterr bellow
    // spawning meteor with stdio=inherit on windows breaks things silently,
    // not good mr windows
    stdio: this.$.env.sys.is_windows ? 'pipe' : 'inherit'
  });

  if(this.$.env.sys.is_windows) {
    this.meteor_process.stdout.pipe(process.stdout);
    this.meteor_process.stderr.pipe(process.stderr);
  }

  var meteor_url = 'http://localhost:3000';
  this.$.plugins.get('nodejs').meteor_ready(meteor_url, function(){
    done(meteor_url);
  });
};

App.prototype.stop_meteor = function() {
  if(this.meteor_process)
    this.$._kill(this.meteor_process);
};

App.prototype.bundle = function(done){
  this.log.info('bundling app');
  this.$.scaffold.prepare();
  this.$.waterfal([
    [this.ensure_deps                       , this.$.plugins  ] ,
    [this.$.plugins.auto_load               , this.$.plugins  ] ,
    [this.$.plugins.acquire                 , this.$.plugins  ] ,
    [this.bundle_meteor                     , this            ] ,
    [function(){ if(done) done(); }         , null            ]
  ]);
};

App.prototype.package = function(options, done){
  var self = this;
  this.bundle(function(){
    self.$.electron.package(options, function(){
      if(done) done();
    });
  });
};

App.prototype.bundle_meteor = function( /* server_url, */ done) {
  this.log.info('bundling meteor');

  var tmp_dir             = join(this.$.env.core.tmp, 'bundling');
  var bundled_dir         = join(tmp_dir, 'bundle');
  var electrify_app_dir   = join(this.$.env.app.root, 'app');
  var programs_server_dir = join(electrify_app_dir, 'programs', 'server');

  // resetting folders
  shell.rm('-rf', tmp_dir);
  shell.mkdir('-p', tmp_dir);

  // bundle meteor
  var self = this;
  spawn('meteor' + (this.$.env.sys.is_windows ? '.bat' : ''), [
      'build', tmp_dir,
      '--server', null,
      // '--server', (server_url !== undefined ? server_url : null),
      '--directory'
    ], {
      cwd: this.$.env.app.meteor,
      stdio: this.$.env.stdio
    }
  ).on('exit', function(){

    // inject meteor's settings file within the bundled app
    fs.writeFileSync(
      join(bundled_dir, 'settings.json'),
      JSON.stringify(self.$.env.app.settings, null, 2)
    );

    // move bundled meteor into .electrify
    shell.rm('-rf', electrify_app_dir);
    shell.mv(bundled_dir, electrify_app_dir);
    shell.rm('-rf', tmp_dir);

    self.log.info('ensuring meteor dependencies');

    // instead of entering the folder and doing an usual `npm install`, which
    // would imply in another bugs around node-fibers native re-build with
    // node-gyp, we just copy the whole `node_modules` folder that is officially
    // distributed with meteor, its 'ready to go and doesn't need to be rebuilt
    shell.cp('-r', self.$.env.meteor.server_modules, programs_server_dir);

    if(done) done();
  });
};

App.prototype.ensure_deps = function(done) {

  this.log.info('ensuring electrify dependencies');

  // in development mode, override install with local electrify version
  if(this.$.env.is_development_mode) {

    var self_path = join(__dirname, '..');
    spawn(this.$.env.meteor.node, [
      this.$.env.meteor.npm,
      'i',
      self_path,
      '--save'
    ], {
      cwd: this.$.env.app.root,
      stdio: this.$.env.stdio
    }).on('exit', done);

    return;
  }

  // fetch version infos
  var pkg_path    = join(this.$.env.app.root, 'package.json');
  var pkg_version = require(pkg_path).dependencies.electrify;
  var version     = this.$.env.version;

  // check and warn users about electrify versions mismatch
  if(pkg_version != version) {
    this.log.warn([
      "{{IMPORTANT}} Your local electrify npm package must match version",
      version,
      " -- please update it to avoid errors"
    ].join(' '));
  }

  spawn(this.$.env.meteor.node, [this.$.env.meteor.npm, 'i'], {
    cwd: this.$.env.app.root,
    stdio: this.$.env.stdio
  }).on('exit', done);
};<commit_msg>making things faster<commit_after>var _    = require('lodash');

var fs    = require('fs');
var spawn = require('child_process').spawn;
var join  = require('path').join;
var shell = require('shelljs');

module.exports = function ($){
  return new App($);
};

function App($) {
  this.$ = $;
  this.log = require('./log')($, 'electrify:app');
}

App.prototype.terminate = function(done){
  // this.log.info('terminating app');
  this.stop_meteor();
  this.$.plugins.stop(done);
};

App.prototype.init = function(done){
  this.log.info('initialize app');
  this.$.scaffold.prepare();
  this.$.waterfal([
    [this.ensure_deps               , this            ] ,
    [this.$.plugins.acquire         , this.$.plugins  ] ,
    [function(){ if(done) done(); } , null            ]
  ]);
};

App.prototype.run = function(done){
  this.log.info('running app');
  this.$.waterfal([
    [this.ensure_deps               , this            ] ,
    [this.$.plugins.auto_load       , this.$.plugins  ] ,
    [this.$.plugins.acquire         , this.$.plugins  ] ,
    [this.$.plugins.start           , this.$.plugins  ] ,
    [this.start_meteor              , this            ] ,
    [function(){ if(done) done(); } , null            ]
  ]);
};

App.prototype.start_meteor = function(done){

  this.log.info('starting meteor');

  var command = 'meteor' + (this.$.env.sys.is_windows ? '.bat' : '');
  var env     = _.clone(this.$.env.app.settings);

  _.extend(env, process.env);
  _.extend(env, this.$.plugins.env());

  this.meteor_process = spawn(command, [], {
    cwd: this.$.env.app.meteor,
    env: env,
    // ignore on windows and them pipe stdout and sterr bellow
    // spawning meteor with stdio=inherit on windows breaks things silently,
    // not good mr windows
    stdio: this.$.env.sys.is_windows ? 'pipe' : 'inherit'
  });

  if(this.$.env.sys.is_windows) {
    this.meteor_process.stdout.pipe(process.stdout);
    this.meteor_process.stderr.pipe(process.stderr);
  }

  var meteor_url = 'http://localhost:3000';
  this.$.plugins.get('nodejs').meteor_ready(meteor_url, function(){
    done(meteor_url);
  });
};

App.prototype.stop_meteor = function() {
  if(this.meteor_process)
    this.$._kill(this.meteor_process);
};

App.prototype.bundle = function(done){
  this.log.info('bundling app');
  this.$.scaffold.prepare();
  this.$.waterfal([
    [this.ensure_deps                       , this.$.plugins  ] ,
    [this.$.plugins.auto_load               , this.$.plugins  ] ,
    [this.$.plugins.acquire                 , this.$.plugins  ] ,
    [this.bundle_meteor                     , this            ] ,
    [function(){ if(done) done(); }         , null            ]
  ]);
};

App.prototype.package = function(options, done){
  var self = this;
  this.bundle(function(){
    self.$.electron.package(options, function(){
      if(done) done();
    });
  });
};

App.prototype.bundle_meteor = function( /* server_url, */ done) {
  this.log.info('bundling meteor');

  var tmp_dir             = join(this.$.env.core.tmp, 'bundling');
  var bundled_dir         = join(tmp_dir, 'bundle');
  var electrify_app_dir   = join(this.$.env.app.root, 'app');
  var programs_server_dir = join(electrify_app_dir, 'programs', 'server');

  // resetting folders
  shell.rm('-rf', tmp_dir);
  shell.mkdir('-p', tmp_dir);

  // bundle meteor
  var self = this;
  spawn('meteor' + (this.$.env.sys.is_windows ? '.bat' : ''), [
      'build', tmp_dir,
      '--server', null,
      // '--server', (server_url !== undefined ? server_url : null),
      '--directory'
    ], {
      cwd: this.$.env.app.meteor,
      stdio: this.$.env.stdio
    }
  ).on('exit', function(){

    // inject meteor's settings file within the bundled app
    fs.writeFileSync(
      join(bundled_dir, 'settings.json'),
      JSON.stringify(self.$.env.app.settings, null, 2)
    );

    // move bundled meteor into .electrify
    shell.rm('-rf', electrify_app_dir);
    shell.mv(bundled_dir, electrify_app_dir);
    shell.rm('-rf', tmp_dir);

    self.log.info('ensuring meteor dependencies');

    // instead of entering the folder and doing an usual `npm install`, which
    // would imply in another bugs around node-fibers native re-build with
    // node-gyp, we just copy the whole `node_modules` folder that is officially
    // distributed with meteor, its 'ready to go and doesn't need to be rebuilt
    shell.cp('-r', self.$.env.meteor.server_modules, programs_server_dir);

    if(done) done();
  });
};

App.prototype.ensure_deps = function(done) {

  this.log.info('ensuring electrify dependencies');

  // in development mode, use local electrify version
  if(this.$.env.is_development_mode) {

    var from = join(__dirname, '..');
    var to = join(this.$.env.app.root, 'node_modules');

    shell.rm('-rf', to);
    shell.mkdir('-p', to);
    shell.cp('-r', from, to);

    return setTimeout(done, 1);
  }

  // fetch version infos
  var pkg_path    = join(this.$.env.app.root, 'package.json');
  var pkg_version = require(pkg_path).dependencies.electrify;
  var version     = this.$.env.version;

  // check and warn users about electrify versions mismatch
  if(pkg_version != version) {
    this.log.warn([
      "{{IMPORTANT}} Your local electrify npm package must match version",
      version,
      " -- please update it to avoid errors"
    ].join(' '));
  }

  spawn(this.$.env.meteor.node, [this.$.env.meteor.npm, 'i'], {
    cwd: this.$.env.app.root,
    stdio: this.$.env.stdio
  }).on('exit', done);
};<|endoftext|>


<commit_before>var RadarChart = {
  draw: function(id, d, options){
    var cfg = {
     radius: 5,
     w: 600,
     h: 600,
     factor: 1,
     factorLegend: .85,
     levels: 3,
     maxValue: 0,
     radians: 2 * Math.PI,
     opacityArea: 0.5,
     color: d3.scale.category10()
    };
    if('undefined' !== typeof options){
      for(var i in options){
        if('undefined' !== typeof options[i]){
          cfg[i] = options[i];
        }
      }
    }
    cfg.maxValue = Math.max(cfg.maxValue, d3.max(d, function(i){return d3.max(i.map(function(o){return o.value;}))}));
    var allAxis = (d[0].map(function(i, j){return i.axis}));
    var total = allAxis.length;
    var radius = cfg.factor*Math.min(cfg.w/2, cfg.h/2);
    d3.select(id).select("svg").remove();
    var g = d3.select(id).append("svg").attr("width", cfg.w).attr("height", cfg.h).append("g");

    var tooltip;

    for(var j=0; j<cfg.levels; j++){
      var levelFactor = cfg.factor*radius*((j+1)/cfg.levels);
      g.selectAll(".levels").data(allAxis).enter().append("svg:line")
       .attr("x1", function(d, i){return levelFactor*(1-cfg.factor*Math.sin(i*cfg.radians/total));})
       .attr("y1", function(d, i){return levelFactor*(1-cfg.factor*Math.cos(i*cfg.radians/total));})
       .attr("x2", function(d, i){return levelFactor*(1-cfg.factor*Math.sin((i+1)*cfg.radians/total));})
       .attr("y2", function(d, i){return levelFactor*(1-cfg.factor*Math.cos((i+1)*cfg.radians/total));})
       .attr("class", "line").style("stroke", "grey").style("stroke-width", "0.5px").attr("transform", "translate(" + (cfg.w/2-levelFactor) + ", " + (cfg.h/2-levelFactor) + ")");;

    }

    series = 0;

    var axis = g.selectAll(".axis").data(allAxis).enter().append("g").attr("class", "axis");

    axis.append("line")
        .attr("x1", cfg.w/2)
        .attr("y1", cfg.h/2)
        .attr("x2", function(j, i){return cfg.w/2*(1-cfg.factor*Math.sin(i*cfg.radians/total));})
        .attr("y2", function(j, i){return cfg.h/2*(1-cfg.factor*Math.cos(i*cfg.radians/total));})
        .attr("class", "line").style("stroke", "grey").style("stroke-width", "1px");

    axis.append("text").attr("class", "legend")
        .text(function(d){return d}).style("font-family", "sans-serif").style("font-size", "10px").attr("transform", function(d, i){return "translate(0, -10)"})
        .attr("x", function(d, i){return cfg.w/2*(1-cfg.factorLegend*Math.sin(i*cfg.radians/total))-20*Math.sin(i*cfg.radians/total);})
        .attr("y", function(d, i){return cfg.h/2*(1-Math.cos(i*cfg.radians/total))+20*Math.cos(i*cfg.radians/total);});

    d.forEach(function(y, x){
      dataValues = [];
      g.selectAll(".nodes")
        .data(y, function(j, i){
          dataValues.push([
            cfg.w/2*(1-(parseFloat(Math.max(j.value, 0))/cfg.maxValue)*cfg.factor*Math.sin(i*cfg.radians/total)),
            cfg.h/2*(1-(parseFloat(Math.max(j.value, 0))/cfg.maxValue)*cfg.factor*Math.cos(i*cfg.radians/total))
          ]);
        });
      dataValues.push(dataValues[0]);
      g.selectAll(".area")
                     .data([dataValues])
                     .enter()
                     .append("polygon")
                     .attr("class", "radar-chart-serie"+series)
                     .style("stroke-width", "2px")
                     .style("stroke", cfg.color(series))
                     .attr("points",function(d) {
                         var str="";
                         for(var pti=0;pti<d.length;pti++){
                             str=str+d[pti][0]+","+d[pti][1]+" ";
                         }
                         return str;
                      })
                     .style("fill", function(j, i){return cfg.color(series)})
                     .style("fill-opacity", cfg.opacityArea)
                     .on('mouseover', function (d){
                                        z = "polygon."+d3.select(this).attr("class");
                                        g.selectAll("polygon").transition(200).style("fill-opacity", 0.1);
                                        g.selectAll(z).transition(200).style("fill-opacity", .7);
                                      })
                     .on('mouseout', function(){
                                        g.selectAll("polygon").transition(200).style("fill-opacity", cfg.opacityArea);
                     });
      series++;
    });
    series=0;

    d.forEach(function(y, x){
      g.selectAll(".nodes")
        .data(y).enter()
        .append("svg:circle").attr("class", "radar-chart-serie"+series)
        .attr('r', cfg.radius)
        .attr("alt", function(j){return Math.max(j.value, 0)})
        .attr("cx", function(j, i){
          dataValues.push([
            cfg.w/2*(1-(parseFloat(Math.max(j.value, 0))/cfg.maxValue)*cfg.factor*Math.sin(i*cfg.radians/total)),
            cfg.h/2*(1-(parseFloat(Math.max(j.value, 0))/cfg.maxValue)*cfg.factor*Math.cos(i*cfg.radians/total))
        ]);
        return cfg.w/2*(1-(Math.max(j.value, 0)/cfg.maxValue)*cfg.factor*Math.sin(i*cfg.radians/total));
        })
        .attr("cy", function(j, i){
          return cfg.h/2*(1-(Math.max(j.value, 0)/cfg.maxValue)*cfg.factor*Math.cos(i*cfg.radians/total));
        })
        .attr("data-id", function(j){return j.axis})
        .style("fill", cfg.color(series)).style("fill-opacity", .9)
        .on('mouseover', function (d){
                    newX =  parseFloat(d3.select(this).attr('cx')) - 10;
                    newY =  parseFloat(d3.select(this).attr('cy')) - 5;
                    tooltip.attr('x', newX).attr('y', newY).text(d.value).transition(200).style('opacity', 1);
                    z = "polygon."+d3.select(this).attr("class");
                    g.selectAll("polygon").transition(200).style("fill-opacity", 0.1);
                    g.selectAll(z).transition(200).style("fill-opacity", .7);
                  })
        .on('mouseout', function(){
                    tooltip.transition(200).style('opacity', 0);
                    g.selectAll("polygon").transition(200).style("fill-opacity", cfg.opacityArea);
                  })
        .append("svg:title")
        .text(function(j){return Math.max(j.value, 0)});

      series++;
    });
    //Tooltip
    tooltip = g.append('text').style('opacity', 0).style('font-family', 'sans-serif').style('font-size', '13px');
  }
};
<commit_msg>improve label positioning, fix extra applications of factor on the scale<commit_after>var RadarChart = {
  draw: function(id, d, options){
    var cfg = {
     radius: 5,
     w: 600,
     h: 600,
     factor: .95,
     factorLegend: 1,
     levels: 3,
     maxValue: 0,
     radians: 2 * Math.PI,
     opacityArea: 0.5,
     color: d3.scale.category10(),
     fontSize: 10
    };
    if('undefined' !== typeof options){
      for(var i in options){
        if('undefined' !== typeof options[i]){
          cfg[i] = options[i];
        }
      }
    }
    cfg.maxValue = Math.max(cfg.maxValue, d3.max(d, function(i){return d3.max(i.map(function(o){return o.value;}))}));
    var allAxis = (d[0].map(function(i, j){return i.axis}));
    var total = allAxis.length;
    var radius = cfg.factor*Math.min(cfg.w/2, cfg.h/2);
    d3.select(id).select("svg").remove();
    var g = d3.select(id).append("svg").attr("width", cfg.w).attr("height", cfg.h).append("g");

    var tooltip;
    function getPosition(i, range, factor, func){
      factor = typeof factor !== 'undefined' ? factor : 1;
      return range * (1 - factor * func(i * cfg.radians / total));
    }
    function getHorizontalPosition(i, range, factor){
      return getPosition(i, range, factor, Math.sin);
    }
    function getVerticalPosition(i, range, factor){
      return getPosition(i, range, factor, Math.cos);
    }

    for(var j=0; j<cfg.levels; j++){
      var levelFactor = radius*((j+1)/cfg.levels);
      g.selectAll(".levels").data(allAxis).enter().append("svg:line")
       .attr("x1", function(d, i){return getHorizontalPosition(i, levelFactor);})
       .attr("y1", function(d, i){return getVerticalPosition(i, levelFactor);})
       .attr("x2", function(d, i){return getHorizontalPosition(i+1, levelFactor);})
       .attr("y2", function(d, i){return getVerticalPosition(i+1, levelFactor);})
       .attr("class", "line").style("stroke", "grey").style("stroke-width", "0.5px").attr("transform", "translate(" + (cfg.w/2-levelFactor) + ", " + (cfg.h/2-levelFactor) + ")");

    }

    series = 0;

    var axis = g.selectAll(".axis").data(allAxis).enter().append("g").attr("class", "axis");

    axis.append("line")
        .attr("x1", cfg.w/2)
        .attr("y1", cfg.h/2)
        .attr("x2", function(j, i){return getHorizontalPosition(i, cfg.w/2, cfg.factor);})
        .attr("y2", function(j, i){return getVerticalPosition(i, cfg.h/2, cfg.factor);})
        .attr("class", "line").style("stroke", "grey").style("stroke-width", "1px");

    axis.append("text").attr("class", "legend")
        .text(function(d){return d})
        .style("font-family", "sans-serif").style("font-size", cfg.fontSize + "px")
        .style("text-anchor", function(d, i){
          var p = getHorizontalPosition(i, 0.5);
          return (p < 0.4) ? "start" : ((p > 0.6) ? "end" : "middle");
        })
        .attr("transform", function(d, i){
          var p = getVerticalPosition(i, cfg.h / 2);
          return p < cfg.fontSize ? "translate(0, " + (cfg.fontSize - p) + ")" : "";
        })
        .attr("x", function(d, i){return getHorizontalPosition(i, cfg.w / 2, cfg.factorLegend);})
        .attr("y", function(d, i){return getVerticalPosition(i, cfg.h / 2, cfg.factorLegend);});

    d.forEach(function(y, x){
      dataValues = [];
      g.selectAll(".nodes")
        .data(y, function(j, i){
          dataValues.push([
            getHorizontalPosition(i, cfg.w/2, (parseFloat(Math.max(j.value, 0))/cfg.maxValue)*cfg.factor),
            getVerticalPosition(i, cfg.h/2, (parseFloat(Math.max(j.value, 0))/cfg.maxValue)*cfg.factor)
          ]);
        });
      dataValues.push(dataValues[0]);
      g.selectAll(".area")
                     .data([dataValues])
                     .enter()
                     .append("polygon")
                     .attr("class", "radar-chart-serie"+series)
                     .style("stroke-width", "2px")
                     .style("stroke", cfg.color(series))
                     .attr("points",function(d) {
                         var str="";
                         for(var pti=0;pti<d.length;pti++){
                             str=str+d[pti][0]+","+d[pti][1]+" ";
                         }
                         return str;
                      })
                     .style("fill", function(j, i){return cfg.color(series)})
                     .style("fill-opacity", cfg.opacityArea)
                     .on('mouseover', function (d){
                                        z = "polygon."+d3.select(this).attr("class");
                                        g.selectAll("polygon").transition(200).style("fill-opacity", 0.1);
                                        g.selectAll(z).transition(200).style("fill-opacity", .7);
                                      })
                     .on('mouseout', function(){
                                        g.selectAll("polygon").transition(200).style("fill-opacity", cfg.opacityArea);
                     });
      series++;
    });
    series=0;

    d.forEach(function(y, x){
      g.selectAll(".nodes")
        .data(y).enter()
        .append("svg:circle").attr("class", "radar-chart-serie"+series)
        .attr('r', cfg.radius)
        .attr("alt", function(j){return Math.max(j.value, 0)})
        .attr("cx", function(j, i){
          dataValues.push([
            getHorizontalPosition(i, cfg.w/2, (parseFloat(Math.max(j.value, 0))/cfg.maxValue)*cfg.factor),
            getVerticalPosition(i, cfg.h/2, (parseFloat(Math.max(j.value, 0))/cfg.maxValue)*cfg.factor)
          ]);
          return getHorizontalPosition(i, cfg.w/2, (Math.max(j.value, 0)/cfg.maxValue)*cfg.factor);
        })
        .attr("cy", function(j, i){
          return getVerticalPosition(i, cfg.h/2, (Math.max(j.value, 0)/cfg.maxValue)*cfg.factor);
        })
        .attr("data-id", function(j){return j.axis})
        .style("fill", cfg.color(series)).style("fill-opacity", .9)
        .on('mouseover', function (d){
                    newX =  parseFloat(d3.select(this).attr('cx')) - 10;
                    newY =  parseFloat(d3.select(this).attr('cy')) - 5;
                    tooltip.attr('x', newX).attr('y', newY).text(d.value).transition(200).style('opacity', 1);
                    z = "polygon."+d3.select(this).attr("class");
                    g.selectAll("polygon").transition(200).style("fill-opacity", 0.1);
                    g.selectAll(z).transition(200).style("fill-opacity", .7);
                  })
        .on('mouseout', function(){
                    tooltip.transition(200).style('opacity', 0);
                    g.selectAll("polygon").transition(200).style("fill-opacity", cfg.opacityArea);
                  })
        .append("svg:title")
        .text(function(j){return Math.max(j.value, 0)});

      series++;
    });
    //Tooltip
    tooltip = g.append('text').style('opacity', 0).style('font-family', 'sans-serif').style('font-size', '13px');
  }
};
<|endoftext|>


<commit_before>/**
  Copyright 2010-2011 Ondrej Certik <ondrej@certik.cz>
  Copyright 2010-2011 Mateusz Paprocki <mattpap@gmail.com>
  Copyright 2011 Christian Iversen <ci@sikkerhed.org>

  Permission is hereby granted, free of charge, to any person
  obtaining a copy of this software and associated documentation
  files (the "Software"), to deal in the Software without
  restriction, including without limitation the rights to use,
  copy, modify, merge, publish, distribute, sublicense, and/or sell
  copies of the Software, and to permit persons to whom the
  Software is furnished to do so, subject to the following
  conditions:

  The above copyright notice and this permission notice shall be
  included in all copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  OTHER DEALINGS IN THE SOFTWARE.
**/

var basestring = __inherit(object, "basestring");

var __py2js_str;

basestring.prototype.__init__ = function(s) {
    if (!defined(s)) {
        this._obj = '';
    } else {
        if (typeof(s) === "string") {
            this._obj = s;
        } else if (defined(s.__str__)) {
            this._obj = js(s.__str__());
        } else if (defined(s.toString)) {
            this._obj = s.toString();
        } else
            this._obj = js(s);
    }
};

var __basestring_real__ = basestring.__call__;

basestring.__call__ = function(obj) {
    if (js(isinstance(obj, basestring))) {
        return obj;
    } else {
        return __basestring_real__(obj);
    }
};

basestring.prototype.__str__ = function () {
    return this;
};

basestring.prototype.__repr__ = function () {
    return "'" + this + "'";
};

basestring.prototype._js_ = function () {
    return this._obj;
};

basestring.prototype.__hash__ = function () {
    var value = 0x345678;
    var length = this.__len__();

    for (var index in this._obj) {
        value = ((1000003*value) & 0xFFFFFFFF) ^ this._obj[index];
        value = value ^ length;
    }

    if (value == -1) {
        value = -2;
    }

    return value;
};

basestring.prototype.__len__ = function() {
    return _int.__call__(this._obj.length);
};

basestring.prototype.__iter__ = function() {
    return iter.__call__(this._obj);
};

basestring.prototype.__mod__ = function(args) {
    return basestring.__call__(sprintf.apply(null, Array.prototype.concat([this._obj], js(args))));
};

basestring.prototype.__bool__ = function() {
    return py_builtins.bool(this._obj);
};

basestring.prototype.__eq__ = function(s) {
    if (typeof(s) === "string")
        return bool.__call__(this._obj == s);
    else if (js(isinstance.__call__(s, basestring)))
        return bool.__call__(this._obj == s._obj);
    else
        return False;
};

basestring.prototype.__gt__ = function(s) {
    if (typeof(s) === "string")
        return bool.__call__(this._obj > s);
    else if (js(isinstance.__call__(s, basestring)))
        return bool.__call__(this._obj > s._obj);
    else
        return False;
};

basestring.prototype.__lt__ = function(s) {
    if (typeof(s) === "string")
        return bool.__call__(this._obj < s);
    else if (js(isinstance.__call__(s, basestring)))
        return bool.__call__(this._obj < s._obj);
    else
        return False;
};

basestring.prototype.__contains__ = function(item) {
    for (var index in this._obj) {
        if (item == this._obj[index]) {
            return True;
        }
    }

    return False;
};

basestring.prototype.__getitem__ = function(index) {
    var seq;
    if (js(isinstance.__call__(index, slice))) {
        var s = index;
        var inds = js(s.indices(len(this)));
        var start = inds[0];
        var stop = inds[1];
        var step = inds[2];
        seq = "";
        for (var i = start; i < stop; i += step) {
            seq = seq + js(this.__getitem__(i));
        }
        return this.__class__.__call__(seq);
    } else if ((index >= 0) && (index < js(len(this))))
        return this._obj[index];
    else if ((index < 0) && (index >= -js(len(this))))
        return this._obj[index+js(len(this))];
    else
        throw py_builtins.IndexError.__call__("string index out of range");
};

basestring.prototype.__setitem__ = function(index, value) {
    throw py_builtins.TypeError.__call__("'str' object doesn't support item assignment");
};

basestring.prototype.__delitem__ = function(index) {
    throw py_builtins.TypeError.__call__("'str' object doesn't support item deletion");
};

basestring.prototype.__add__ = function(c) {
    return basestring.__call__(this._obj + c._obj);
};

basestring.prototype.__iadd__ = basestring.prototype.__add__;

basestring.prototype.count = Function(function(needle, start, end) {
    if (!defined(start))
        start = 0;
    if (!defined(end))
        end = null;
    var count = 0;
    var s = this.__getitem__(slice.__call__(start, end));
    var idx = s.find(needle);
    while (idx != -1) {
        count += 1;
        s = s.__getitem__(slice.__call__(idx+1, null));
        idx = s.find(needle);
    }
    return count;
});

basestring.prototype.index = Function(function(value, start, end) {
    if (!defined(start)) {
        start = 0;
    }

    for (var i = js(start); !defined(end) || (start < end); i++) {
        var _value = this._obj[i];

        if (!defined(_value)) {
            break;
        }

        if (_value == value) {
            return _int.__call__(i);
        }
    }

    throw py_builtins.ValueError.__call__("substring not found");
});

basestring.prototype.find = Function(function(s) {
    return this._obj.search(s);
});

basestring.prototype.rfind = Function(function(s) {
    var rev = function(s) {
        var a = list.__call__(__py2js_str.__call__(s));
        a.reverse();
        a = __py2js_str.__call__("").join(a);
        return a;
    };
    var a = rev(this);
    var b = rev(s);
    var r = a.find(b);
    if (r == -1)
        return r;
    return len(this) - len(b) - r;
});

basestring.prototype.join = Function(function(s) {
    return __py2js_str.__call__(js(s).join(js(this)));
});

basestring.prototype.replace = Function(function(old, _new, count) {
    old = js(old);
    _new = js(_new);
    var old_s;
    var new_s;

    if (defined(count))
        count = js(count);
    else
        count = -1;
    old_s = "";
    new_s = this._obj;
    while ((count != 0) && (new_s != old_s)) {
        old_s = new_s;
        new_s = new_s.replace(old, _new);
        count -= 1;
    }
    return __py2js_str.__call__(new_s);
});

basestring.prototype.lstrip = Function(function(chars) {
    if (js(len(this)) === 0)
        return this;
    if (defined(chars))
        chars = tuple.__call__(chars);
    else
        chars = tuple.__call__(["\n", "\t", " "]);
    var i = 0;
    while ((i < js(len(this))) && (js(chars.__contains__(this.__getitem__(i))))) {
        i += 1;
    }
    return this.__getitem__(slice.__call__(i, null));
});

basestring.prototype.rstrip = Function(function(chars) {
    if (js(len(this)) === 0)
        return this;
    if (defined(chars))
        chars = tuple.__call__(chars);
    else
        chars = tuple.__call__(["\n", "\t", " "]);
    var i = js(len(this))-1;
    while ((i >= 0) && (js(chars.__contains__(this.__getitem__(i))))) {
        i -= 1;
    }
    return this.__getitem__(slice.__call__(i+1));
});

basestring.prototype.strip = Function(function(chars) {
    return this.lstrip(chars).rstrip(chars);
});

basestring.prototype.split = Function(function(sep) {
    var r_new;
    if (defined(sep)) {
        var r = list.__call__(this._obj.split(sep));
        r_new = list.__call__([]);
        iterate(iter.__call__(r), function(item) {
                r_new.append(basestring.__call__(item));
        });
        return r_new;
    }
    else {
        r_new = list.__call__([]);
        iterate(iter.__call__(this.split(" ")), function(item) {
                if (len(item) > 0)
                    r_new.append(item);
        });
        return r_new;
    }
});

basestring.prototype.splitlines = Function(function() {
    return this.split("\n");
});

basestring.prototype.lower = Function(function() {
    return __py2js_str.__call__(this._obj.toLowerCase());
});

basestring.prototype.upper = Function(function() {
    return __py2js_str.__call__(this._obj.toUpperCase());
});

basestring.prototype.encode = Function(function(encoding) {
    return this;
});

basestring.prototype.decode = Function(function(encoding) {
    return this;
});

var str = __inherit(basestring, "str");
var unicode = __inherit(basestring, "unicode");

unicode.prototype.__init__ = function(s) {
    if (!defined(s)) {
        this._obj = '';
    } else {
        if (typeof(s) === "string") {
            this._obj = s;
        } else if (defined(s.__unicode__)) {
            this._obj = js(s.__unicode__());
        } else if (defined(s.toString)) {
            this._obj = s.toString();
        } else
            this._obj = js(s);
    }
};

__py2js_str = str;<commit_msg> * Use new sprintf() function in str.__mod__<commit_after>/**
  Copyright 2010-2011 Ondrej Certik <ondrej@certik.cz>
  Copyright 2010-2011 Mateusz Paprocki <mattpap@gmail.com>
  Copyright 2011 Christian Iversen <ci@sikkerhed.org>

  Permission is hereby granted, free of charge, to any person
  obtaining a copy of this software and associated documentation
  files (the "Software"), to deal in the Software without
  restriction, including without limitation the rights to use,
  copy, modify, merge, publish, distribute, sublicense, and/or sell
  copies of the Software, and to permit persons to whom the
  Software is furnished to do so, subject to the following
  conditions:

  The above copyright notice and this permission notice shall be
  included in all copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  OTHER DEALINGS IN THE SOFTWARE.
**/

var basestring = __inherit(object, "basestring");

var __py2js_str;

basestring.prototype.__init__ = function(s) {
    if (!defined(s)) {
        this._obj = '';
    } else {
        if (typeof(s) === "string") {
            this._obj = s;
        } else if (defined(s.__str__)) {
            this._obj = js(s.__str__());
        } else if (defined(s.toString)) {
            this._obj = s.toString();
        } else
            this._obj = js(s);
    }
};

var __basestring_real__ = basestring.__call__;

basestring.__call__ = function(obj) {
    if (js(isinstance(obj, basestring))) {
        return obj;
    } else {
        return __basestring_real__(obj);
    }
};

basestring.prototype.__str__ = function () {
    return this;
};

basestring.prototype.__repr__ = function () {
    return "'" + this + "'";
};

basestring.prototype._js_ = function () {
    return this._obj;
};

basestring.prototype.__hash__ = function () {
    var value = 0x345678;
    var length = this.__len__();

    for (var index in this._obj) {
        value = ((1000003*value) & 0xFFFFFFFF) ^ this._obj[index];
        value = value ^ length;
    }

    if (value == -1) {
        value = -2;
    }

    return value;
};

basestring.prototype.__len__ = function() {
    return _int.__call__(this._obj.length);
};

basestring.prototype.__iter__ = function() {
    return iter.__call__(this._obj);
};

basestring.prototype.__mod__ = function(args) {
    return basestring.__call__(sprintf(this, args));
};

basestring.prototype.__bool__ = function() {
    return py_builtins.bool(this._obj);
};

basestring.prototype.__eq__ = function(s) {
    if (typeof(s) === "string")
        return bool.__call__(this._obj == s);
    else if (js(isinstance.__call__(s, basestring)))
        return bool.__call__(this._obj == s._obj);
    else
        return False;
};

basestring.prototype.__gt__ = function(s) {
    if (typeof(s) === "string")
        return bool.__call__(this._obj > s);
    else if (js(isinstance.__call__(s, basestring)))
        return bool.__call__(this._obj > s._obj);
    else
        return False;
};

basestring.prototype.__lt__ = function(s) {
    if (typeof(s) === "string")
        return bool.__call__(this._obj < s);
    else if (js(isinstance.__call__(s, basestring)))
        return bool.__call__(this._obj < s._obj);
    else
        return False;
};

basestring.prototype.__contains__ = function(item) {
    for (var index in this._obj) {
        if (item == this._obj[index]) {
            return True;
        }
    }

    return False;
};

basestring.prototype.__getitem__ = function(index) {
    var seq;
    if (js(isinstance.__call__(index, slice))) {
        var s = index;
        var inds = js(s.indices(len(this)));
        var start = inds[0];
        var stop = inds[1];
        var step = inds[2];
        seq = "";
        for (var i = start; i < stop; i += step) {
            seq = seq + js(this.__getitem__(i));
        }
        return this.__class__.__call__(seq);
    } else if ((index >= 0) && (index < js(len(this))))
        return this._obj[index];
    else if ((index < 0) && (index >= -js(len(this))))
        return this._obj[index+js(len(this))];
    else
        throw py_builtins.IndexError.__call__("string index out of range");
};

basestring.prototype.__setitem__ = function(index, value) {
    throw py_builtins.TypeError.__call__("'str' object doesn't support item assignment");
};

basestring.prototype.__delitem__ = function(index) {
    throw py_builtins.TypeError.__call__("'str' object doesn't support item deletion");
};

basestring.prototype.__add__ = function(c) {
    return basestring.__call__(this._obj + c._obj);
};

basestring.prototype.__iadd__ = basestring.prototype.__add__;

basestring.prototype.count = Function(function(needle, start, end) {
    if (!defined(start))
        start = 0;
    if (!defined(end))
        end = null;
    var count = 0;
    var s = this.__getitem__(slice.__call__(start, end));
    var idx = s.find(needle);
    while (idx != -1) {
        count += 1;
        s = s.__getitem__(slice.__call__(idx+1, null));
        idx = s.find(needle);
    }
    return count;
});

basestring.prototype.index = Function(function(value, start, end) {
    if (!defined(start)) {
        start = 0;
    }

    for (var i = js(start); !defined(end) || (start < end); i++) {
        var _value = this._obj[i];

        if (!defined(_value)) {
            break;
        }

        if (_value == value) {
            return _int.__call__(i);
        }
    }

    throw py_builtins.ValueError.__call__("substring not found");
});

basestring.prototype.find = Function(function(s) {
    return this._obj.search(s);
});

basestring.prototype.rfind = Function(function(s) {
    var rev = function(s) {
        var a = list.__call__(__py2js_str.__call__(s));
        a.reverse();
        a = __py2js_str.__call__("").join(a);
        return a;
    };
    var a = rev(this);
    var b = rev(s);
    var r = a.find(b);
    if (r == -1)
        return r;
    return len(this) - len(b) - r;
});

basestring.prototype.join = Function(function(s) {
    return __py2js_str.__call__(js(s).join(js(this)));
});

basestring.prototype.replace = Function(function(old, _new, count) {
    old = js(old);
    _new = js(_new);
    var old_s;
    var new_s;

    if (defined(count))
        count = js(count);
    else
        count = -1;
    old_s = "";
    new_s = this._obj;
    while ((count != 0) && (new_s != old_s)) {
        old_s = new_s;
        new_s = new_s.replace(old, _new);
        count -= 1;
    }
    return __py2js_str.__call__(new_s);
});

basestring.prototype.lstrip = Function(function(chars) {
    if (js(len(this)) === 0)
        return this;
    if (defined(chars))
        chars = tuple.__call__(chars);
    else
        chars = tuple.__call__(["\n", "\t", " "]);
    var i = 0;
    while ((i < js(len(this))) && (js(chars.__contains__(this.__getitem__(i))))) {
        i += 1;
    }
    return this.__getitem__(slice.__call__(i, null));
});

basestring.prototype.rstrip = Function(function(chars) {
    if (js(len(this)) === 0)
        return this;
    if (defined(chars))
        chars = tuple.__call__(chars);
    else
        chars = tuple.__call__(["\n", "\t", " "]);
    var i = js(len(this))-1;
    while ((i >= 0) && (js(chars.__contains__(this.__getitem__(i))))) {
        i -= 1;
    }
    return this.__getitem__(slice.__call__(i+1));
});

basestring.prototype.strip = Function(function(chars) {
    return this.lstrip(chars).rstrip(chars);
});

basestring.prototype.split = Function(function(sep) {
    var r_new;
    if (defined(sep)) {
        var r = list.__call__(this._obj.split(sep));
        r_new = list.__call__([]);
        iterate(iter.__call__(r), function(item) {
                r_new.append(basestring.__call__(item));
        });
        return r_new;
    }
    else {
        r_new = list.__call__([]);
        iterate(iter.__call__(this.split(" ")), function(item) {
                if (len(item) > 0)
                    r_new.append(item);
        });
        return r_new;
    }
});

basestring.prototype.splitlines = Function(function() {
    return this.split("\n");
});

basestring.prototype.lower = Function(function() {
    return __py2js_str.__call__(this._obj.toLowerCase());
});

basestring.prototype.upper = Function(function() {
    return __py2js_str.__call__(this._obj.toUpperCase());
});

basestring.prototype.encode = Function(function(encoding) {
    return this;
});

basestring.prototype.decode = Function(function(encoding) {
    return this;
});

var str = __inherit(basestring, "str");
var unicode = __inherit(basestring, "unicode");

unicode.prototype.__init__ = function(s) {
    if (!defined(s)) {
        this._obj = '';
    } else {
        if (typeof(s) === "string") {
            this._obj = s;
        } else if (defined(s.__unicode__)) {
            this._obj = js(s.__unicode__());
        } else if (defined(s.toString)) {
            this._obj = s.toString();
        } else
            this._obj = js(s);
    }
};

__py2js_str = str;<|endoftext|>


<commit_before>/*var Panagram = (function () {
	function Panagram (category) {
		this.category = category;
	}
	Panagram.prototype.Dex = function () {
		switch (toId(category)) {
			case 'pokmon': return Tools.data.Pokedex;
			case 'item': return Tools.data.Items;
			case '

exports.commands = {
	panagramhelp: 'panagramrules',
	panagramrules: function(target, room, user) {
		if (!this.canBroadcast()) return;
		return this.sendReplyBox('Pangram rules and commands
' +
			'/panagram - Starts a game of Panagram in the room (Panagrams are just anagrams with Pokemon). Illegal and CAP Pokemon won\'t be selected. Must be ranked + or higher to use.
' +
			'/guessp [Pokemon] - Guesses a Pokémon. After guessing incorrectly, you cannot guess again in the same game. There are a total of 3 tries per game. The answer is revealed after all 3 chances are over.
' +
			'/panagramend OR /endpanagram OR /endp - Ends the current game of Panagram.');
	},
	//panagram commands.
	panagram: function(target, room, user) {
		if (!this.can('broadcast', null, room)) return false;
		if (room.panagram) return this.sendReply('There is already a game of Panagram going on.');
		var mixer = function(word) {
			var array = [];
			for (var k = 0; k < word.length; k++) {
				array.push(word[k]);
			}
			var a;
			var b;
			var i = array.length;
			while (i) {
				a = Math.floor(Math.random() * i);
				i--;
				b = array[i];
				array[i] = array[a];
				array[a] = b;
			}
			return array.join('').toString();
		}
		var pokedex = Object.keys(Tools.data.Pokedex), poke;
		do {
			poke = pokedex[Math.floor(Math.random() * pokedex.length)];
		} while (Tools.data.Pokedex[poke].num < 0 || Tools.data.Pokedex[poke].num < 0)
		var panagram = mixer(poke.toString());
		while (panagram == poke) {
			panagram = mixer(poke);
		}
		//var x = Math.floor(Math.random() * panagram.length);
		this.add('|html|
A game of Panagram has been started!
' +
			'The scrambled Pokémon is ' + panagram + '
' +
			'Type in /gp or /guesspoke [Pokémon] to guess the Pokémon!');
		room.panagram = {};
		room.panagram.guessed = [];
		room.panagram.chances = 2;
		room.panagram.answer = toId(poke);
	},

	gp: 'guessp',
	guesspoke: 'guessp',
	guessp: function(target, room, user, cmd) {
		if (!room.panagram) return this.sendReply('There is no game of Panagram going on in this room.');
		if (room.panagram[user.userid]) return this.sendReply("You've already guessed once!");
		if (!target) return this.sendReply("The proper syntax is /guessp [pokemon]");
		if (!Tools.data.Pokedex[toId(target)]) return this.sendReply("'" + target + "' is not a valid Pokémon.");
		if (Tools.data.Pokedex[toId(target)].num < 1) return this.sendReply(Tools.data.Pokedex[toId(target)].species + ' is either an illegal or a CAP Pokémon.');
		if (Tools.data.Pokedex[toId(target)].baseSpecies) target = toId(Tools.data.Pokedex[toId(target)].baseSpecies);
		if (room.panagram.guessed.indexOf(toId(target)) > -1) return this.sendReply("That Pokemon has already been guessed!");
		if (room.panagram.answer == toId(target)) {
			this.add('|html|' + user.name + ' guessed ' + Tools.data.Pokedex[toId(target)].species + ', which was the correct answer! Congratulations!');
			delete room.panagram;
		} else {
			if (room.panagram.chances > 0) {
				this.add('|html|' + user.name + ' guessed ' + Tools.data.Pokedex[toId(target)].species + ', but was not the correct answer...');
				room.panagram[user.userid] = toId(target);
				room.panagram.guessed.push(toId(target));
				room.panagram.chances--;
			} else {
				this.add('|html|' + user.name + ' guessed ' + Tools.data.Pokedex[toId(target)].species + ', but was not the correct answer. You have failed to guess the Pokemon, which was ' + Tools.data.Pokedex[room.panagram.answer].species + '');
				delete room.panagram;
			}
		}
	},
	panagramoff: 'endpanagram',
	endp: 'endpanagram',
	panagramend: 'endpanagram',
	endpanagram: function(target, room, user) {
		if (!room.panagram) return this.sendReply('There is no panagram game going on in this room yet.');
		this.add("|html|The game of Panagram has been ended.");
		delete room.panagram;
	}
};*/
<commit_msg>New Panagram script<commit_after>var pGames = exports.pGames = {};

function mix(word) {
	var arr = [];
	for (var k = 0; k < word.length; k++) {
		arr.push(word[k]);
	}
	var a, b, i = arr.length;
	while (i) {
		a = Math.floor(Math.random() * i);
		i--;
		b = arr[i];
		arr[i] = arr[a];
		arr[a] = b;
	}
	return arr.join('').toString();
}

var Panagram = (function () {
	function Panagram(room, category) {
		this.room = room;
		this.category = category;
		switch (toId(category)) {
		case 'items':
		case 'item':
			this.dex = Tools.data.Items;
			break;
		case 'abilities':
		case 'ability':
			this.dex = Tools.data.Abilities;
			break;
		case 'moves':
		case 'move':
			this.dex = Tools.data.Movedex;
			break;
		default:
			this.dex = Tools.data.Pokedex;
		}
		do {
			this.answer = this.dex[Object.keys(this.dex)[Math.floor(Math.random() * Object.keys(this.dex).length)]];
		} while (this.answer.num < 1 || this.answer.baseSpecies);
		this.mixed = mix(this.category === 'pokemon' ? toId(this.answer.species) : this.answer.name.toLowerCase());

		this.room.add('|html|
A game of Panagram was started! Scrambled word: ' + this.mixed + '. Category: ' + category + '
' +
			'Enter your answer into the chat to guess!'
		);
		this.users = {};
		this.guessed = {};

		var Game = this;
		this.room.chat = function (user, message, connection) {
			message = CommandParser.parse(message, this, user, connection);
			if (Game.dex[toId(message)]) {
				var guess = Game.dex[toId(message)];
				var guessName = guess.id || toId(guess.species);
				if (Game.users[user.userid]) return user.sendTo(this, 'You cannot guess more than once per game of panagram.');
				for (var i in Game.users)
					if (Game.users[i].latestIp === user.latestIp) return user.sendTo(this, 'One of your alts have already guessed once in this game of panagram.');
				if (guessName in Game.guessed) return user.sendTo(this, 'That word has already been guessed.');
				if (guessName === (Game.answer.id || toId(Game.answer.species))) {
					this.add('|html|' + user.name + ' guessed ' + (guess.name || guess.species) + ', which was the correct answer! Congratulations!');
					Game.end();
				} else if (guess.num < 1 || guess.baseSpecies) user.sendTo(this, (guess.name || guess.species) + ' is either an alternate form or doesn\'t exist in the games. These cannot be guessed.');
				else {
					if (Object.keys(Game.users).length < 3) {
						this.add('|html|' + user.name + ' guessed ' + (guess.name || guess.species) + ', but was not the correct answer...');
						Game.guessed[guessName] = user.userid;
						Game.users[user.userid] = user;
					} else {
						this.add('|html|' + user.name + ' guessed ' + (guess.name || guess.species) + ', but was not the correct answer. You have failed to guess the Pokemon, which was ' + (answer.name || answer.species) + '');
						Game.end();
					}
				}
			} else {
				if (message && message !== true) {
					this.add('|c|' + user.getIdentity(this.id) + '|' + message);
				}
			}
			this.update();
		};
	}

	Panagram.prototype.end = function (forced) {
		if (forced) this.room.add('The game of panagram has been forcibly ended.');
		this.room.chat = Rooms.Room.prototype.chat;
		delete pGames[this.room.id];
	};
	return Panagram;
})();

var cmds = {
	rules: 'help',
	help: function (target, room, user) {
		if (!this.canBroadcast()) return;
		this.sendReplyBox('Panagram Commands
' +
			'
/panagram Category - Starts a game of panagram that follows the specified category. Valid categories include Pokemon, Items, Abilities and moves. Not specifying a category starts a pokemon panagram by default. Requires + or higher to use.' +
			'
/panagram end or /endp - Ends a game of panagram. Requires + or higher to use.
' +
			'Users can guess answers by simply typing them into the chat.'
		);
	},

	pokemon: '',
	item: '',
	items: '',
	ability: '',
	abilities: '',
	move: '',
	moves: '',
	'': function (target, room, user, connection, cmd) {
		if (pGames[room.id]) return this.sendReply('There is currently a game of panagram going on in this room.');
		if (!this.can('broadcast', null, room)) return this.sendReply('You must be ranked + or higher to start a game of panagram in this room.');
		if (!cmd) cmd = 'pokemon';

		pGames[room.id] = new Panagram(room, cmd);
	},

	end: function (target, room, user) {
		if (!pGames[room.id]) return this.sendReply('There is no game of panagram going on in this room.');
		if (!this.can('broadcast', null, room)) return this.sendReply('You must be ranked + or higher to end a game of panagram in this room.');

		pGames[room.id].end(true);
	}
}

exports.commands = {
	panagram: cmds,
	endpanagram: 'endp',
	endp: cmds.end,
}
<|endoftext|>


<commit_before>'use strict';

angular.module('observatory3App')
.controller('ProjectsCtrl', function ($scope, $http) {
    $scope.projects = [];
    $scope.projectToAdd = {active: true};

    $scope.getCurrentProjects = function() {
        $http.get('/api/projects').success(function(projects) {
            $scope.projects = projects;
        });
        $scope.past = false;
    };

    $scope.getPastProjects = function() {
        $http.get('/api/projects/past').success(function(projects) {
            $scope.projects = projects;
        });
        $scope.past = true;
    };

    $scope.getInfo = function() {
        if($scope.projectToAdd.repositoryUrl) {
            var splitUrl = $scope.projectToAdd.repositoryUrl.split('/');
            $scope.projectToAdd.githubUsername = splitUrl[splitUrl.length - 2];
            $scope.projectToAdd.githubProjectName = $scope.projectToAdd.name = splitUrl[splitUrl.length - 1];
            $.getJSON('https://api.github.com/repos/' + $scope.projectToAdd.githubUsername + '/' + $scope.projectToAdd.githubProjectName, function(response) {
                $scope.projectToAdd.websiteURL = response.homepage;
                $scope.projectToAdd.description = response.description;
                $scope.$apply();
            });
        }
    };

    $scope.submit = function(form) {
        $scope.submitted = true;

        if(form.$valid) {
            $scope.submitted = false;
            $('#addProject').modal('hide');
            // use setTimeout because hiding the modal takes longer than the post request
            // and results in the modal disappearing but the overlay staying if not used
            setTimeout(function() {
                $http.post('/api/projects', $scope.projectToAdd);
                $scope.projectToAdd = {active: true};
                if ($scope.past){
                    $scope.getPastProjects();
                }
                else{
                    $scope.getCurrentProjects();
                }
            }, 200);
        }
    };

    $scope.getCurrentProjects(); // update the webpage when connecting the controller
});
<commit_msg>added redirect on adding new project<commit_after>'use strict';

angular.module('observatory3App')
.controller('ProjectsCtrl', function ($scope, $location, $http) {
    $scope.projects = [];
    $scope.projectToAdd = {active: true};

    $scope.getCurrentProjects = function() {
        $http.get('/api/projects').success(function(projects) {
            $scope.projects = projects;
        });
        $scope.past = false;
    };

    $scope.getPastProjects = function() {
        $http.get('/api/projects/past').success(function(projects) {
            $scope.projects = projects;
        });
        $scope.past = true;
    };

    $scope.getInfo = function() {
        if($scope.projectToAdd.repositoryUrl) {
            var splitUrl = $scope.projectToAdd.repositoryUrl.split('/');
            $scope.projectToAdd.githubUsername = splitUrl[splitUrl.length - 2];
            $scope.projectToAdd.githubProjectName = $scope.projectToAdd.name = splitUrl[splitUrl.length - 1];
            $.getJSON('https://api.github.com/repos/' + $scope.projectToAdd.githubUsername + '/' + $scope.projectToAdd.githubProjectName, function(response) {
                $scope.projectToAdd.websiteURL = response.homepage;
                $scope.projectToAdd.description = response.description;
                $scope.$apply();
            });
        }
    };

    $scope.submit = function(form) {
        $scope.submitted = true;

        if(form.$valid) {
            $scope.submitted = false;
            $('#addProject').modal('hide');
            // use setTimeout because hiding the modal takes longer than the post request
            // and results in the modal disappearing but the overlay staying if not used
            setTimeout(function() {
                $http.post('/api/projects', $scope.projectToAdd);

                if ($scope.past){
                    $scope.getPastProjects();
                }
                else{
                    $scope.getCurrentProjects();
                }
                var redirectUsername = $scope.projectToAdd.githubUsername;
                var redirectProjectName = $scope.projectToAdd.githubProjectName;
                $scope.projectToAdd = {active: true};

                $location.path( 'projects/' + redirectUsername + '/' + redirectProjectName + '/profile');
            }, 200);
        }
    };

    $scope.getCurrentProjects(); // update the webpage when connecting the controller
});
<|endoftext|>