<commit_before>import API from 'src/util/api';
import {OCLE} from './libs';

const noop = () => {/* noop */};

const defaultOptions = {
    onMolfileChanged: noop,
    calculateDiastereotopicID: false,
    maxDiastereotopicCalculationTime: 3000
};

class ExpandableMolecule {
    constructor(sample, options) {
        this.options = Object.assign({}, defaultOptions, options);
        this.sample = sample;
        this.molfile = String(this.sample.getChildSync(['$content', 'general', 'molfile']) || '');
        this.idCode = OCLE.Molecule.fromMolfile(this.molfile).getIDCode();
        this.expandedHydrogens = false;
        this.jsmeEditionMode = false;
        this.calculateDiastereotopicID = options.calculateDiastereotopicID;
        this.maxDiastereotopicCalculationTime = options.maxDiastereotopicCalculationTime;

        this.onChange = (event) => {
            // us this really a modification ? or a loop event ...
            // need to compare former oclID with new oclID
            var newMolecule = OCLE.Molecule.fromMolfile(event.target + '');

            var oclID = newMolecule.getIDCodeAndCoordinates();

            if (oclID.idCode !== this.idCode) {
                this.idCode = oclID.idCode;
                this.molfile = event.target + '';
                this.sample.setChildSync(['$content', 'general', 'molfile'], this.molfile);
                this.sample.setChildSync(['$content', 'general', 'ocl'], {
                    value: oclID.idCode,
                    coordinates: oclID.coordinates
                });
            }
            this.options.onMolfileChanged(this);
        };

        API.createData('editableMolfile', this.molfile).then(
            (editableMolfile) => {
                this.editableMolfile = editableMolfile;
                this.bindChange();
                this.updateMolfiles();
                this.setJSMEEdition(false);
            }
        );
    }

    bindChange() {
        this.editableMolfile.onChange(this.onChange);
    }

    unbindChange() {
        this.editableMolfile.unbindChange(this.onChange);
    }

    setJSMEEdition(value, noDepictUpdate) {
        this.jsmeEditionMode = value;

        var options = {
            prefs: []
        };

        if (this.jsmeEditionMode) {
            options.prefs.push('nodepict');
            API.getData('editableMolfile').triggerChange();
            this.expandedHydrogens = false;
        } else {
            options.prefs.push('depict');
            if (!noDepictUpdate) { // TODO when we should not updateMolfile
                this.expandedHydrogens = false;
                this.updateMolfiles();
                API.createData('viewMolfile', this.viewMolfile);
            }

        }
        API.doAction('setJSMEOptions', options);
    }

    setExpandedHydrogens(force) {
        if (force === undefined) {
            this.expandedHydrogens = !this.expandedHydrogens;
        } else {
            this.expandedHydrogens = force;
        }
        if (this.expandedHydrogens) {
            this.setJSMEEdition(false, true);
            API.createData('viewMolfileExpandedH', this.viewMolfileExpandedH);

        } else {
            API.createData('viewMolfile', this.viewMolfile);
        }
    }

    updateMolfiles() {
        var molecule = OCLE.Molecule.fromMolfile(this.molfile);
        let calculateDiastereotopicID = this.calculateDiastereotopicID;
        if (calculateDiastereotopicID) {
            // is it reasonnable to calculate the DiastereotopicID. We check the time it will take
            let start = Date.now();
            molecule.getIDCode();
            let exptected = (Date.now() - start) * molecule.getAllAtoms();
            if (exptected > this.maxDiastereotopicCalculationTime) {
                // eslint-disable-next-line no-console
                console.log('The diastereotopic calculation is expected to last more than 3s. No way to assign molecule.',
                    this.maxDiastereotopicCalculationTime);
                calculateDiastereotopicID = false;
            }
        }

        this.viewMolfile = molecule.toVisualizerMolfile({
            heavyAtomHydrogen: true,
            diastereotopic: calculateDiastereotopicID
        });
        molecule.addImplicitHydrogens();
        this.viewMolfileExpandedH = molecule.toVisualizerMolfile({
            diastereotopic: calculateDiastereotopicID
        });
    }

    handleAction(action) {
        if (!action) return false;
        switch (action.name) {
            case 'toggleJSMEEdition':
                this.setJSMEEdition(!this.jsmeEditionMode);
                break;
            case 'clearMolfile':
                var molfile = API.getData('editableMolfile');
                molfile.setValue('');
                break;
            case 'swapHydrogens':
                this.setExpandedHydrogens();
                break;
            default:
                return false;
        }
        return true;
    }
}

module.exports = ExpandableMolecule;
<commit_msg>simplify the code and prevent too long diastereotopicID calculation<commit_after>import API from 'src/util/api';
import {OCLE} from './libs';

const noop = () => {/* noop */};

const defaultOptions = {
    onMolfileChanged: noop,
    calculateDiastereotopicID: false,
    maxDiastereotopicCalculationTime: 3000
};

class ExpandableMolecule {
    constructor(sample, options) {
        this.options = Object.assign({}, defaultOptions, options);
        this.sample = sample;
        this.molfile = String(this.sample.getChildSync(['$content', 'general', 'molfile']) || '');
        this.idCode = OCLE.Molecule.fromMolfile(this.molfile).getIDCode();
        this.expandedHydrogens = false;
        this.jsmeEditionMode = false;
        this.calculateDiastereotopicID = this.options.calculateDiastereotopicID;
        this.maxDiastereotopicCalculationTime = this.options.maxDiastereotopicCalculationTime;

        this.onChange = (event) => {
            // us this really a modification ? or a loop event ...
            // need to compare former oclID with new oclID
            var newMolecule = OCLE.Molecule.fromMolfile(event.target + '');

            var oclID = newMolecule.getIDCodeAndCoordinates();

            if (oclID.idCode !== this.idCode) {
                this.idCode = oclID.idCode;
                this.molfile = event.target + '';
                this.sample.setChildSync(['$content', 'general', 'molfile'], this.molfile);
                this.sample.setChildSync(['$content', 'general', 'ocl'], {
                    value: oclID.idCode,
                    coordinates: oclID.coordinates
                });
            }
            this.options.onMolfileChanged(this);
        };

        API.createData('editableMolfile', this.molfile).then(
            (editableMolfile) => {
                this.editableMolfile = editableMolfile;
                this.bindChange();
                this.createViewVariable();
            }
        );
    }

    bindChange() {
        this.editableMolfile.onChange(this.onChange);
    }

    unbindChange() {
        this.editableMolfile.unbindChange(this.onChange);
    }

    toggleJSMEEdition() {
        this.jsmeEditionMode = ! this.jsmeEditionMode;
        this.expandedHydrogens = false;
        let options = {
            prefs: []
        };

        if (this.jsmeEditionMode) {
            options.prefs.push('nodepict');
            API.createData('editableMolfile', this.molfile);
        } else {
            options.prefs.push('depict');

        }
        API.doAction('setJSMEOptions', options);
    }

    setExpandedHydrogens() {
        if (this.jsmeEditionMode) {
            this.toggleJSMEEdition();
        } else {
            this.expandedHydrogens = !this.expandedHydrogens;
        }
        this.createViewVariable();
    }

    /*
    We create the view variable with or without expanded hydrogens
     */
    createViewVariable() {
        var molecule = OCLE.Molecule.fromMolfile(this.molfile);
        let calculateDiastereotopicID = this.calculateDiastereotopicID;
        if (calculateDiastereotopicID) {
            // is it reasonnable to calculate the DiastereotopicID. We check the time it will take
            let start = Date.now();
            molecule.getIDCode();
            let expected = (Date.now() - start) * molecule.getAllAtoms();
            if (expected > this.maxDiastereotopicCalculationTime) {
                // eslint-disable-next-line no-console
                console.log('The diastereotopic calculation is expected to last more than 3s. No way to assign molecule.',
                    this.maxDiastereotopicCalculationTime);
                calculateDiastereotopicID = false;
            }
        }
        console.log('expanded', this.expandedHydrogens)
        if (this.expandedHydrogens) {
            molecule.addImplicitHydrogens();
            let viewMolfileExpandedH = molecule.toVisualizerMolfile({
                diastereotopic: calculateDiastereotopicID
            });
            API.createData('viewMolfileExpandedH', viewMolfileExpandedH);
        } else {
            let viewMolfile = molecule.toVisualizerMolfile({
                heavyAtomHydrogen: true,
                diastereotopic: calculateDiastereotopicID
            });
            API.createData('viewMolfile', viewMolfile);
        }
    }

    handleAction(action) {
        if (!action) return false;
        switch (action.name) {
            case 'toggleJSMEEdition':
                this.toggleJSMEEdition(!this.jsmeEditionMode);
                break;
            case 'clearMolfile':
                var molfile = API.getData('editableMolfile');
                molfile.setValue('');
                break;
            case 'swapHydrogens':
                this.setExpandedHydrogens();
                break;
            default:
                return false;
        }
        return true;
    }
}

module.exports = ExpandableMolecule;
<|endoftext|>


<commit_before>/*
 * jQuery delegate plug-in v1.0
 *
 * Copyright (c) 2007 Jörn Zaefferer
 *
 * $Id: jquery.delegate.js 4786 2008-02-19 20:02:34Z joern.zaefferer $
 *
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 */

// provides cross-browser focusin and focusout events
// IE has native support, in other browsers, use event caputuring (neither bubbles)

// provides delegate(type: String, delegate: Selector, handler: Callback) plugin for easier event delegation
// handler is only called when $(event.target).is(delegate), in the scope of the jQuery-object for event.target

// provides triggerEvent(type: String, target: Element) to trigger delegated events
;(function($) {
	$.each({
		focus: 'focusin',
		blur: 'focusout'
	}, function( original, fix ){
		$.event.special[fix] = {
			setup:function() {
				if ( $.browser.msie ) return false;
				this.addEventListener( original, $.event.special[fix].handler, true );
			},
			teardown:function() {
				if ( $.browser.msie ) return false;
				this.removeEventListener( original,
				$.event.special[fix].handler, true );
			},
			handler: function(e) {
				arguments[0] = $.event.fix(e);
				arguments[0].type = fix;
				return $.event.handle.apply(this, arguments);
			}
		};
	});

	$.extend($.fn, {
		delegate: function(type, delegate, handler) {
			return this.bind(type, function(event) {
				var target = $(event.target);
				if (target.is(delegate)) {
					return handler.apply(target, arguments);
				}
			});
		},
		triggerEvent: function(type, target) {
			return this.triggerHandler(type, [jQuery.event.fix({ type: type, target: target })]);
		}
	})
})(jQuery);
<commit_msg>add tooltip<commit_after><|endoftext|>


<commit_before>/**
 * Miscellaneous commands
 */

'use strict';

let moment = require('moment');
let request = require('request');

let messages = [
	"has vanished into nothingness!",
	"used Explosion!",
	"fell into the void.",
	"went into a cave without a repel!",
	"has left the building.",
	"was forced to give StevoDuhHero's mom an oil massage!",
	"was hit by Magikarp's Revenge!",
	"ate a bomb!",
	"is blasting off again!",
	"(Quit: oh god how did this get here i am not good with computer)",
	"was unfortunate and didn't get a cool message.",
	"{{user}}'s mama accidently kicked {{user}} from the server!",
];

function clearRoom(room) {
	let len = (room.log && room.log.length) || 0;
	let users = [];
	while (len--) {
		room.log[len] = '';
	}
	for (let u in room.users) {
		users.push(u);
		Users.get(u).leaveRoom(room, Users.get(u).connections[0]);
	}
	len = users.length;
	setTimeout(function () {
		while (len--) {
			Users.get(users[len]).joinRoom(room, Users.get(users[len]).connections[0]);
		}
	}, 1000);
}

exports.commands = {
	stafflist: 'authority',
	auth: 'authority',
	authlist: 'authority',
	authority: function (target, room, user, connection) {
		let rankLists = {};
		let ranks = Object.keys(Config.groups);
		for (let u in Users.usergroups) {
			let rank = Users.usergroups[u].charAt(0);
			// In case the usergroups.csv file is not proper, we check for the server ranks.
			if (ranks.indexOf(rank) > -1) {
				let name = Users.usergroups[u].substr(1);
				if (!rankLists[rank]) rankLists[rank] = [];
				if (name) rankLists[rank].push(((Users.getExact(name) && Users.getExact(name).connected) ? '**' + name + '**' : name));
			}
		}

		let buffer = [];
		Object.keys(rankLists).sort(function (a, b) {
			return (Config.groups[b] || {rank: 0}).rank - (Config.groups[a] || {rank: 0}).rank;
		}).forEach(function (r) {
			buffer.push((Config.groups[r] ? r + Config.groups[r].name + "s (" + rankLists[r].length + ")" : r) + ":\n" + rankLists[r].sort().join(", "));
		});

		if (!buffer.length) {
			return connection.popup("This server has no auth.");
		}
		connection.popup(buffer.join("\n\n"));
	},

	clearall: function (target, room, user) {
		if (!this.can('declare')) return false;
		if (room.battle) return this.sendReply("You cannot clearall in battle rooms.");

		clearRoom(room);
	},

	gclearall: 'globalclearall',
	globalclearall: function (target, room, user) {
		if (!this.can('gdeclare')) return false;

		for (let u in Users.users) {
			Users.users[u].popup("All rooms are being clear.");
		}

		for (let r in Rooms.rooms) {
			clearRoom(Rooms.rooms[r]);
		}
	},

	hide: function (target, room, user) {
		if (!this.can('lock')) return false;
		user.hiding = true;
		user.updateIdentity();
		this.sendReply("You have hidden your staff symbol.");
	},

	rk: 'kick',
	roomkick: 'kick',
	kick: function (target, room, user) {
		if (!target) return this.parse('/help kick');
		if (!this.canTalk() && !user.can('bypassall')) {
			return this.sendReply("You cannot do this while unable to talk.");
		}

		target = this.splitTarget(target);
		let targetUser = this.targetUser;
		if (!targetUser || !targetUser.connected) return this.sendReply("User \"" + this.targetUsername + "\" not found.");
		if (!this.can('mute', targetUser, room)) return false;

		this.addModCommand(targetUser.name + " was kicked from the room by " + user.name + ".");
		targetUser.popup("You were kicked from " + room.id + " by " + user.name + ".");
		targetUser.leaveRoom(room.id);
	},
	kickhelp: ["/kick - Kick a user out of a room. Requires: % @ # & ~"],

	masspm: 'pmall',
	pmall: function (target, room, user) {
		if (!this.can('pmall')) return false;
		if (!target) return this.parse('/help pmall');

		let pmName = ' Server PM [Do not reply]';

		Users.users.forEach(function (user) {
			let message = '|pm|' + pmName + '|' + user.getIdentity() + '|' + target;
			user.send(message);
		});
	},
	pmallhelp: ["/pmall [message] - PM all users in the server."],

	staffpm: 'pmallstaff',
	pmstaff: 'pmallstaff',
	pmallstaff: function (target, room, user) {
		if (!this.can('forcewin')) return false;
		if (!target) return this.parse('/help pmallstaff');

		let pmName = ' Staff PM [Do not reply]';

		Users.users.forEach(function (user) {
			if (!user.isStaff) return;
			let message = '|pm|' + pmName + '|' + user.getIdentity() + '|' + target;
			user.send(message);
		});
	},
	pmallstaffhelp: ["/pmallstaff [message] - Sends a PM to every staff member online."],

	d: 'poof',
	cpoof: 'poof',
	poof: function (target, room, user) {
		if (Config.poofOff) return this.sendReply("Poof is currently disabled.");
		if (target && !this.can('broadcast')) return false;
		if (room.id !== 'lobby') return false;
		let message = target || messages[Math.floor(Math.random() * messages.length)];
		if (message.indexOf('{{user}}') < 0) message = '{{user}} ' + message;
		message = message.replace(/{{user}}/g, user.name);
		if (!this.canTalk(message)) return false;

		let colour = '#' + [1, 1, 1].map(function () {
			let part = Math.floor(Math.random() * 0xaa);
			return (part < 0x10 ? '0' : '') + part.toString(16);
		}).join('');

		room.addRaw("~~ " + Tools.escapeHTML(message) + " ~~");
		user.disconnectAll();
	},
	poofhelp: ["/poof - Disconnects the user and leaves a message in the room."],

	poofon: function () {
		if (!this.can('poofoff')) return false;
		Config.poofOff = false;
		return this.sendReply("Poof is now enabled.");
	},
	poofonhelp: ["/poofon - Enable the use /poof command."],

	nopoof: 'poofoff',
	poofoff: function () {
		if (!this.can('poofoff')) return false;
		Config.poofOff = true;
		return this.sendReply("Poof is now disabled.");
	},
	poofoffhelp: ["/poofoff - Disable the use of the /poof command."],

	regdate: function (target, room, user) {
		if (!this.canBroadcast()) return;
		if (!target || !toId(target)) return this.parse('/help regdate');
		let username = toId(target);
		request('http://pokemonshowdown.com/users/' + username, function (error, response, body) {
			if (error && response.statusCode !== 200) {
				this.sendReplyBox(Tools.escapeHTML(target) + " is not registered.");
				return room.update();
			}
			let regdate = body.split('')[1].split('')[0].replace(/(|<\/em>)/g, '');
			if (regdate === '(Unregistered)') {
				this.sendReplyBox(Tools.escapeHTML(target) + " is not registered.");
			} else {
				this.sendReplyBox(Tools.escapeHTML(target) + " was registered on " + regdate.slice(7) + ".");
			}
			room.update();
		}.bind(this));
	},
	regdatehelp: ["/regdate - Please specify a valid username."],

	show: function (target, room, user) {
		if (!this.can('lock')) return false;
		user.hiding = false;
		user.updateIdentity();
		this.sendReply("You have revealed your staff symbol.");
	},

	sb: 'showdownboilerplate',
	showdownboilerplate: function (target, room, user) {
		if (!this.canBroadcast()) return;
		this.sendReply("|raw|This server uses Showdown-Boilerplate.");
	},
	showdownboilerplatehelp: ["/showdownboilerplate - Links to the Showdown-Boilerplate repository on Github."],

	seen: function (target, room, user) {
		if (!this.canBroadcast()) return;
		if (!target) return this.parse('/help seen');
		let targetUser = Users.get(target);
		if (targetUser && targetUser.connected) return this.sendReplyBox(targetUser.name + " is currently online.");
		target = Tools.escapeHTML(target);
		let seen = Db('seen').get(toId(target));
		if (!seen) return this.sendReplyBox(target + " has never been online on this server.");
		this.sendReplyBox(target + " was last seen " + moment(seen).fromNow() + ".");
	},
	seenhelp: ["/seen - Shows when the user last connected on the server."],

	tell: function (target, room, user, connection) {
		if (!target) return this.parse('/help tell');
		target = this.splitTarget(target);
		let targetUser = this.targetUser;
		if (!target) {
			this.sendReply("You forgot the comma.");
			return this.parse('/help tell');
		}

		if (targetUser && targetUser.connected) {
			return this.parse('/pm ' + this.targetUsername + ', ' + target);
		}

		if (user.locked) return this.popupReply("You may not send offline messages when locked.");
		if (target.length > 255) return this.popupReply("Your message is too long to be sent as an offline message (>255 characters).");

		if (Config.tellrank === 'autoconfirmed' && !user.autoconfirmed) {
			return this.popupReply("You must be autoconfirmed to send an offline message.");
		} else if (!Config.tellrank || Config.groupsranking.indexOf(user.group) < Config.groupsranking.indexOf(Config.tellrank)) {
			return this.popupReply("You cannot send an offline message because offline messaging is " +
				(!Config.tellrank ? "disabled" : "only available to users of rank " + Config.tellrank + " and above") + ".");
		}

		let userid = toId(this.targetUsername);
		if (userid.length > 18) return this.popupReply("\"" + this.targetUsername + "\" is not a legal username.");

		let sendSuccess = Tells.addTell(user, userid, target);
		if (!sendSuccess) {
			if (sendSuccess === false) {
				return this.popupReply("User " + this.targetUsername + " has too many offline messages queued.");
			} else {
				return this.popupReply("You have too many outgoing offline messages queued. Please wait until some have been received or have expired.");
			}
		}
		return connection.send('|pm|' + user.getIdentity() + '|' +
			(targetUser ? targetUser.getIdentity() : ' ' + this.targetUsername) +
			"|/text This user is currently offline. Your message will be delivered when they are next online.");
	},
	tellhelp: ["/tell [username], [message] - Send a message to an offline user that will be received when they log in."],
};
<commit_msg>Update misc.js<commit_after>/**
 * Miscellaneous commands
 */

'use strict';

let moment = require('moment');
let request = require('request');

let messages = [
	"has vanished into nothingness!",
	"used Explosion!",
	"fell into the void.",
	"went into a cave without a repel!",
	"has left the building.",
	"was forced to give StevoDuhHero's mom an oil massage!",
	"was hit by Magikarp's Revenge!",
	"ate a bomb!",
	"is blasting off again!",
	"(Quit: oh god how did this get here i am not good with computer)",
	"was unfortunate and didn't get a cool message.",
	"{{user}}'s mama accidently kicked {{user}} from the server!",
];

function clearRoom(room) {
	let len = (room.log && room.log.length) || 0;
	let users = [];
	while (len--) {
		room.log[len] = '';
	}
	for (let u in room.users) {
		users.push(u);
		Users.get(u).leaveRoom(room, Users.get(u).connections[0]);
	}
	len = users.length;
	setTimeout(function () {
		while (len--) {
			Users.get(users[len]).joinRoom(room, Users.get(users[len]).connections[0]);
		}
	}, 1000);
}

exports.commands = {
	stafflist: 'authority',
	auth: 'authority',
	authlist: 'authority',
	authority: function (target, room, user, connection) {
		let rankLists = {};
		let ranks = Object.keys(Config.groups);
		for (let u in Users.usergroups) {
			let rank = Users.usergroups[u].charAt(0);
			// In case the usergroups.csv file is not proper, we check for the server ranks.
			if (ranks.indexOf(rank) > -1) {
				let name = Users.usergroups[u].substr(1);
				if (!rankLists[rank]) rankLists[rank] = [];
				if (name) rankLists[rank].push(((Users.getExact(name) && Users.getExact(name).connected) ? '**' + name + '**' : name));
			}
		}

		let buffer = [];
		Object.keys(rankLists).sort(function (a, b) {
			return (Config.groups[b] || {rank: 0}).rank - (Config.groups[a] || {rank: 0}).rank;
		}).forEach(function (r) {
			buffer.push((Config.groups[r] ? r + Config.groups[r].name + "s (" + rankLists[r].length + ")" : r) + ":\n" + rankLists[r].sort().join(", "));
		});

		if (!buffer.length) {
			return connection.popup("This server has no auth.");
		}
		connection.popup(buffer.join("\n\n"));
	},

	clearall: function (target, room, user) {
		if (!this.can('declare')) return false;
		if (room.battle) return this.sendReply("You cannot clearall in battle rooms.");

		clearRoom(room);
	},

	gclearall: 'globalclearall',
	globalclearall: function (target, room, user) {
		if (!this.can('gdeclare')) return false;

		for (let u in Users.users) {
			Users.users[u].popup("All rooms are being clear.");
		}

		for (let r in Rooms.rooms) {
			clearRoom(Rooms.rooms[r]);
		}
	},

	hide: function (target, room, user) {
		if (!this.can('lock')) return false;
		user.hiding = true;
		user.updateIdentity();
		this.sendReply("You have hidden your staff symbol.");
	},

	rk: 'kick',
	roomkick: 'kick',
	kick: function (target, room, user) {
		if (!target) return this.parse('/help kick');
		if (!this.canTalk() && !user.can('bypassall')) {
			return this.sendReply("You cannot do this while unable to talk.");
		}

		target = this.splitTarget(target);
		let targetUser = this.targetUser;
		if (!targetUser || !targetUser.connected) return this.sendReply("User \"" + this.targetUsername + "\" not found.");
		if (!this.can('mute', targetUser, room)) return false;

		this.addModCommand(targetUser.name + " was kicked from the room by " + user.name + ".");
		targetUser.popup("You were kicked from " + room.id + " by " + user.name + ".");
		targetUser.leaveRoom(room.id);
	},
	kickhelp: ["/kick - Kick a user out of a room. Requires: % @ # & ~"],

	masspm: 'pmall',
	pmall: function (target, room, user) {
		if (!this.can('pmall')) return false;
		if (!target) return this.parse('/help pmall');

		let pmName = ' Server PM [Do not reply]';

		Users.users.forEach(function (user) {
			let message = '|pm|' + pmName + '|' + user.getIdentity() + '|' + target;
			user.send(message);
		});
	},
	pmallhelp: ["/pmall [message] - PM all users in the server."],

	staffpm: 'pmallstaff',
	pmstaff: 'pmallstaff',
	pmallstaff: function (target, room, user) {
		if (!this.can('forcewin')) return false;
		if (!target) return this.parse('/help pmallstaff');

		let pmName = ' Staff PM [Do not reply]';

		Users.users.forEach(function (user) {
			if (!user.isStaff) return;
			let message = '|pm|' + pmName + '|' + user.getIdentity() + '|' + target;
			user.send(message);
		});
	},
	pmallstaffhelp: ["/pmallstaff [message] - Sends a PM to every staff member online."],

	d: 'poof',
	cpoof: 'poof',
	poof: function (target, room, user) {
		if (Config.poofOff) return this.sendReply("Poof is currently disabled.");
		if (target && !this.can('broadcast')) return false;
		if (room.id !== 'lobby') return false;
		let message = target || messages[Math.floor(Math.random() * messages.length)];
		if (message.indexOf('{{user}}') < 0) message = '{{user}} ' + message;
		message = message.replace(/{{user}}/g, user.name);
		if (!this.canTalk(message)) return false;

		let colour = '#' + [1, 1, 1].map(function () {
			let part = Math.floor(Math.random() * 0xaa);
			return (part < 0x10 ? '0' : '') + part.toString(16);
		}).join('');

		room.addRaw("~~ " + Tools.escapeHTML(message) + " ~~");
		user.disconnectAll();
	},
	poofhelp: ["/poof - Disconnects the user and leaves a message in the room."],

	poofon: function () {
		if (!this.can('poofoff')) return false;
		Config.poofOff = false;
		return this.sendReply("Poof is now enabled.");
	},
	poofonhelp: ["/poofon - Enable the use /poof command."],

	nopoof: 'poofoff',
	poofoff: function () {
		if (!this.can('poofoff')) return false;
		Config.poofOff = true;
		return this.sendReply("Poof is now disabled.");
	},
	poofoffhelp: ["/poofoff - Disable the use of the /poof command."],

	regdate: function (target, room, user) {
		if (!this.canBroadcast()) return;
		if (!target || !toId(target)) return this.parse('/help regdate');
		let username = toId(target);
		request('http://pokemonshowdown.com/users/' + username, function (error, response, body) {
			if (error && response.statusCode !== 200) {
				this.sendReplyBox(Tools.escapeHTML(target) + " is not registered.");
				return room.update();
			}
			let regdate = body.split('')[1].split('')[0].replace(/(|<\/em>)/g, '');
			if (regdate === '(Unregistered)') {
				this.sendReplyBox(Tools.escapeHTML(target) + " is not registered.");
			} else if (regdate === '(Account disabled)') {
				this.sendReplyBox(Tools.escapeHTML(target) + "'s account is disabled.");
			} else {
				this.sendReplyBox(Tools.escapeHTML(target) + " was registered on " + regdate.slice(7) + ".");
			}
			room.update();
		}.bind(this));
	},
	regdatehelp: ["/regdate - Please specify a valid username."],

	show: function (target, room, user) {
		if (!this.can('lock')) return false;
		user.hiding = false;
		user.updateIdentity();
		this.sendReply("You have revealed your staff symbol.");
	},

	sb: 'showdownboilerplate',
	showdownboilerplate: function (target, room, user) {
		if (!this.canBroadcast()) return;
		this.sendReply("|raw|This server uses Showdown-Boilerplate.");
	},
	showdownboilerplatehelp: ["/showdownboilerplate - Links to the Showdown-Boilerplate repository on Github."],

	seen: function (target, room, user) {
		if (!this.canBroadcast()) return;
		if (!target) return this.parse('/help seen');
		let targetUser = Users.get(target);
		if (targetUser && targetUser.connected) return this.sendReplyBox(targetUser.name + " is currently online.");
		target = Tools.escapeHTML(target);
		let seen = Db('seen').get(toId(target));
		if (!seen) return this.sendReplyBox(target + " has never been online on this server.");
		this.sendReplyBox(target + " was last seen " + moment(seen).fromNow() + ".");
	},
	seenhelp: ["/seen - Shows when the user last connected on the server."],

	tell: function (target, room, user, connection) {
		if (!target) return this.parse('/help tell');
		target = this.splitTarget(target);
		let targetUser = this.targetUser;
		if (!target) {
			this.sendReply("You forgot the comma.");
			return this.parse('/help tell');
		}

		if (targetUser && targetUser.connected) {
			return this.parse('/pm ' + this.targetUsername + ', ' + target);
		}

		if (user.locked) return this.popupReply("You may not send offline messages when locked.");
		if (target.length > 255) return this.popupReply("Your message is too long to be sent as an offline message (>255 characters).");

		if (Config.tellrank === 'autoconfirmed' && !user.autoconfirmed) {
			return this.popupReply("You must be autoconfirmed to send an offline message.");
		} else if (!Config.tellrank || Config.groupsranking.indexOf(user.group) < Config.groupsranking.indexOf(Config.tellrank)) {
			return this.popupReply("You cannot send an offline message because offline messaging is " +
				(!Config.tellrank ? "disabled" : "only available to users of rank " + Config.tellrank + " and above") + ".");
		}

		let userid = toId(this.targetUsername);
		if (userid.length > 18) return this.popupReply("\"" + this.targetUsername + "\" is not a legal username.");

		let sendSuccess = Tells.addTell(user, userid, target);
		if (!sendSuccess) {
			if (sendSuccess === false) {
				return this.popupReply("User " + this.targetUsername + " has too many offline messages queued.");
			} else {
				return this.popupReply("You have too many outgoing offline messages queued. Please wait until some have been received or have expired.");
			}
		}
		return connection.send('|pm|' + user.getIdentity() + '|' +
			(targetUser ? targetUser.getIdentity() : ' ' + this.targetUsername) +
			"|/text This user is currently offline. Your message will be delivered when they are next online.");
	},
	tellhelp: ["/tell [username], [message] - Send a message to an offline user that will be received when they log in."],
};
<|endoftext|>


<commit_before>"use strict";
var config = require("./config");

if (!String.prototype.startsWith) {
    String.prototype.startsWith = function(searchString, position){
        position = position || 0;
        return this.substr(position, searchString.length) === searchString;
    };
}

var ITEMS = {
    messages: {},
    stars: {},
    flags: {},
    lastEvent: {}
};
var noFormattingLinked = function() {
    throw new Error("There is no formatting linked.");
};
var blacklistedUsers = config.blacklistedUsers || [];
var acceptableUsers = config.acceptableUsers || [];

acceptableUsers = acceptableUsers.concat([
    //ID here with //comment with your name
    '145604', // Quill SE
    '24697', // PhiNotPi SE
    '175356', // Downgoat SE
    '116494' // Conor O Brien SE
]);
var messageFormatting = {
    room: noFormattingLinked,
    user: noFormattingLinked,
    activity: noFormattingLinked,
    content: noFormattingLinked,
    edited: noFormattingLinked,
    messageId: noFormattingLinked,
    connection: noFormattingLinked
};
var say = function(){};
var specialSay = function(){};
var noPrefixSay = function(){};
var reply = function(){};
var commands = {};
var limitedAccessCommands = {};

var set = {
    messageFormatting: function(value) {
        messageFormatting = value;
    },
    say: function(value){
        say = value;
    },
    specialSay: function(value){
        specialSay = value;
    },
    noPrefixSay: function(value){
        noPrefixSay = value;
    },
    reply: function(value){
        reply = value;
    },
    commands: function(value){
        commands = value;
    },
    limitedAccessCommands: function(value){
        limitedAccessCommands = value;
    }
};
var EVENT_TYPES = {
    MessagePosted: 1,
    MessageEdited: 2,
    UserEntered: 3,
    UserLeft: 4,
    RoomNameChanged: 5,
    MessageStarred: 6,
    UserMentioned: 8,
    MessageFlagged: 9,
    MessageDeleted: 10,
    UserNotification: 16,
    Invitation: 17,
    MessageReply: 18,
    MessageMovedOut: 19,
    MessageMovedIn: 20
};

var convert = function(str) {
    return !str ? "" // eslint-disable-line no-negated-condition
    : str.replace(/&/g, "&")
         .replace(/>/g, ">")
         .replace(/</g, "<")
         .replace(/"/g, "\"")
         .replace(/'/g, "'");
};

var processCommand = function(event){
    if (String(event.room_id) != "39270" && String(event.room_id) != "89"){
        return false;
    }
    if (!event.content.startsWith("@Marvin ") && !event.content.startsWith("!!/")){
        return false;
    }
    if ((event.content.startsWith("@Marvin") || event.content.startsWith("!!/")) && String(event.room_id) == "89"){
        return false;
    }
    if (String(event.room_id) != "89" && event.content.startsWith("@Quill")){
        return false;
    }
    if (blacklistedUsers.indexOf(String(event.user_id)) !== -1){
        return reply("I can't let you do that.", event);
    }
    var commandArguments = event.content
        .replace("@Marvin ", "")
        .replace("@Quill ", "")
        .replace("!!/", "")
        .split(" ");
    var commandName = commandArguments[0];
    if (commandName == ''){
        return reply("You need to actually type a command...");
    }
    var command = commands[commandName];
    var commandArgs = commandArguments.slice(1);
    if (limitedAccessCommands.hasOwnProperty(commandName) && acceptableUsers.indexOf(String(event.user_id)) === -1){
        if (event.domain == "SE"){
            return reply("I can't let you do that.", event);
        }
    }
    var speaker = (event.domain == "SE" ? say : specialSay);
    if (commands.hasOwnProperty(commandName)){
        switch (commandName){
            case "delete":
            case "join":
            case "leave":
                return say(command("SE", commandArgs));
                break;
            case "restart":
            case "stop":
            case "pull":
                return speaker(say, commandArgs);
                break;
            case "blacklist":
                if (blacklistedUsers.indexOf(commandArgs[0]) > -1){
                    return reply("They're already blacklisted.", event);
                }
                if (acceptableUsers.indexOf(String(commandArgs[0])) !== -1){
                    return reply("They're a special user... don't even try it, sassy pants.", event)
                }
                blacklistedUsers.push(commandArgs[0]);
                return command(commandArgs);
                break;
            case "removeBlacklist":
                if (blacklistedUsers.indexOf(commandArgs[0]) === -1){
                    reply("They're not blacklisted.", event);
                }
                blacklistedUsers.splice(blacklistedUsers.indexOf(commandArgs[0]), 1);
                return command(commandArgs);
                break;
            case "alive":
            case "rampDownTheSarcasm":
            case "rampUpTheSarcasm":
            case "help":
                return reply(
                    command(commandArgs),
                    event
                );
                break;
            case "listCommands":
                return reply(
                    command(acceptableUsers.indexOf(String(event.user_id)) !== -1, commandArgs),
                    event
                );
                break;
            case "listFlagCount":
                return speaker(command(ITEMS.flags, commandArgs));
                break;
            default:
                return say(command(commandArgs))
                break;

        }
    } else {
        return say("Command " + commandName + " not recognised.")
    }
}

/* eslint-disable complexity, max-statements */
var processEvent = function(event) {
    if (event.content === ITEMS.lastEventContent) {
        return false;
    }
    ITEMS.lastEventContent = event.content;
    event.content = convert(event.content);
    switch (event.event_type) {
        case EVENT_TYPES.MessagePosted:
            return processCommand(event);
            break;
        case EVENT_TYPES.MessageEdited:
            return processCommand(event);
            break;
        case EVENT_TYPES.MessageStarred:
            if (!event.message_stars) {
                delete ITEMS.stars[event.message_id];
                return;
            }
            if (ITEMS.stars.hasOwnProperty(event.message_id)){
                return;
            }
            if (event.message_stars > config.star_threshold) {
                ITEMS.stars[event.message_id] = event.message_stars;
                return say(
                    messageFormatting.room(event) +
                    messageFormatting.activity(" highly starred [message](http://chat.stackexchange.com/transcript/message/" + event.message_id + "#" + event.message_id + ") with ") +
                    event.message_stars +
                    " stars."
                )
                .then(function(){
                    return noPrefixSay(
                        "http://chat.stackexchange.com/transcript/message/" + event.message_id + "#" + event.message_id
                    );
                });
            }
            break;
        case EVENT_TYPES.MessageFlagged:
            if (!ITEMS.flags.hasOwnProperty(event.message_id)){
                ITEMS.flags[event.message_id] = event;
                ITEMS.flags[event.message_id].site = "SE";
                specialSay(
                    messageFormatting.activity("A [message](http://chat.stackexchange.com/transcript/message/" + event.message_id + "#" + event.message_id + ") in ") +
                    messageFormatting.room(event) +
                    messageFormatting.activity(" was flagged.")
                ).then(function(){
                    return say(
                        messageFormatting.activity("A [message](http://chat.stackexchange.com/transcript/message/" + event.message_id + "#" + event.message_id + ") in ") +
                        messageFormatting.room(event) +
                        messageFormatting.activity(" was flagged.")
                    );
                });
                // Uncomment the line below to turn on sharing of the message
                //say(messageFormatting.content(event));
            }
            break;
        default:
            return false;
            break;
    }
};
module.exports = {
    processEvent: processEvent,
    convert: convert,
    set: set,
    ITEMS: ITEMS,
    EVENT_TYPES: EVENT_TYPES
};
<commit_msg>fixed some issue that made replies be stringified<commit_after>"use strict";
var config = require("./config");

if (!String.prototype.startsWith) {
    String.prototype.startsWith = function(searchString, position){
        position = position || 0;
        return this.substr(position, searchString.length) === searchString;
    };
}

var ITEMS = {
    messages: {},
    stars: {},
    flags: {},
    lastEvent: {}
};
var noFormattingLinked = function() {
    throw new Error("There is no formatting linked.");
};
var blacklistedUsers = config.blacklistedUsers || [];
var acceptableUsers = config.acceptableUsers || [];

acceptableUsers = acceptableUsers.concat([
    //ID here with //comment with your name
    '145604', // Quill SE
    '24697', // PhiNotPi SE
    '175356', // Downgoat SE
    '116494' // Conor O Brien SE
]);
var messageFormatting = {
    room: noFormattingLinked,
    user: noFormattingLinked,
    activity: noFormattingLinked,
    content: noFormattingLinked,
    edited: noFormattingLinked,
    messageId: noFormattingLinked,
    connection: noFormattingLinked
};
var say = function(){};
var specialSay = function(){};
var noPrefixSay = function(){};
var reply = function(){};
var commands = {};
var limitedAccessCommands = {};

var set = {
    messageFormatting: function(value) {
        messageFormatting = value;
    },
    say: function(value){
        say = value;
    },
    specialSay: function(value){
        specialSay = value;
    },
    noPrefixSay: function(value){
        noPrefixSay = value;
    },
    reply: function(value){
        reply = value;
    },
    commands: function(value){
        commands = value;
    },
    limitedAccessCommands: function(value){
        limitedAccessCommands = value;
    }
};
var EVENT_TYPES = {
    MessagePosted: 1,
    MessageEdited: 2,
    UserEntered: 3,
    UserLeft: 4,
    RoomNameChanged: 5,
    MessageStarred: 6,
    UserMentioned: 8,
    MessageFlagged: 9,
    MessageDeleted: 10,
    UserNotification: 16,
    Invitation: 17,
    MessageReply: 18,
    MessageMovedOut: 19,
    MessageMovedIn: 20
};

var convert = function(str) {
    return !str ? "" // eslint-disable-line no-negated-condition
    : str.replace(/&/g, "&")
         .replace(/>/g, ">")
         .replace(/</g, "<")
         .replace(/"/g, "\"")
         .replace(/'/g, "'");
};

var processCommand = function(event){
    console.log();
    if (event.domain == "stackexchange"){
        if (String(event.room_id) != "39270"){
            return false;
        }
        if (!event.content.startsWith("@Marvin") && !event.content.startsWith("!!/")){
            return false;
        }
    } else if (event.domain == "meta.stackexchange"){
        if (String(event.room_id) != "89"){
            return false;
        }
        if (!event.content.startsWith("@Quill")){
            return false;
        }
    }

    if (blacklistedUsers.indexOf(String(event.user_id)) !== -1){
        if (event.domain != "meta.stackexchange"){
            return reply("I can't let you do that.", event);
        }
    }
    var commandArguments = event.content
        .replace("@Marvin ", "")
        .replace("@Quill ", "")
        .replace("!!/", "")
        .split(" ");
    var commandName = commandArguments[0];
    if (commandName == ''){
        return reply("You need to actually type a command...");
    }
    var command = commands[commandName];
    var commandArgs = commandArguments.slice(1);
    if (limitedAccessCommands.hasOwnProperty(commandName) && acceptableUsers.indexOf(String(event.user_id)) === -1){
        if (event.domain == "stackexchange"){
            return reply("I can't let you do that.", event);
        }
    }
    var speaker = function(){
        return event.domain == "SE" ? say.apply(null, arguments) : specialSay.apply(null, arguments)
    };
    if (commands.hasOwnProperty(commandName)){
        switch (commandName){
            case "delete":
            case "join":
            case "leave":
                return say(command("SE", commandArgs));
                break;
            case "restart":
            case "stop":
            case "pull":
                return speaker(say, commandArgs);
                break;
            case "blacklist":
                if (blacklistedUsers.indexOf(commandArgs[0]) > -1){
                    return reply("They're already blacklisted.", event);
                }
                if (acceptableUsers.indexOf(String(commandArgs[0])) !== -1){
                    return reply("They're a special user... don't even try it, sassy pants.", event)
                }
                blacklistedUsers.push(commandArgs[0]);
                return command(commandArgs);
                break;
            case "removeBlacklist":
                if (blacklistedUsers.indexOf(commandArgs[0]) === -1){
                    reply("They're not blacklisted.", event);
                }
                blacklistedUsers.splice(blacklistedUsers.indexOf(commandArgs[0]), 1);
                return command(commandArgs);
                break;
            case "alive":
            case "rampDownTheSarcasm":
            case "rampUpTheSarcasm":
            case "help":
                return reply(
                    command(commandArgs),
                    event
                );
                break;
            case "listCommands":
                return reply(
                    command(acceptableUsers.indexOf(String(event.user_id)) !== -1, commandArgs),
                    event
                );
                break;
            case "listFlagCount":
                return speaker(command(ITEMS.flags, commandArgs));
                break;
            default:
                return say(command(commandArgs))
                break;

        }
    } else {
        return reply("Command " + commandName + " not recognised.")
    }
}

/* eslint-disable complexity, max-statements */
var processEvent = function(event) {
    if (event.content === ITEMS.lastEventContent) {
        return false;
    }
    ITEMS.lastEventContent = event.content;
    event.content = convert(event.content);
    switch (event.event_type) {
        case EVENT_TYPES.MessagePosted:
            return processCommand(event);
            break;
        case EVENT_TYPES.MessageEdited:
            return processCommand(event);
            break;
        case EVENT_TYPES.MessageStarred:
            if (!event.message_stars) {
                delete ITEMS.stars[event.message_id];
                return;
            }
            if (ITEMS.stars.hasOwnProperty(event.message_id)){
                return;
            }
            if (event.message_stars > config.star_threshold) {
                ITEMS.stars[event.message_id] = event.message_stars;
                return say(
                    messageFormatting.room(event) +
                    messageFormatting.activity(" highly starred [message](http://chat.stackexchange.com/transcript/message/" + event.message_id + "#" + event.message_id + ") with ") +
                    event.message_stars +
                    " stars."
                )
                .then(function(){
                    return noPrefixSay(
                        "http://chat.stackexchange.com/transcript/message/" + event.message_id + "#" + event.message_id
                    );
                });
            }
            break;
        case EVENT_TYPES.MessageFlagged:
            if (!ITEMS.flags.hasOwnProperty(event.message_id)){
                ITEMS.flags[event.message_id] = event;
                ITEMS.flags[event.message_id].site = "SE";
                specialSay(
                    messageFormatting.activity("A [message](http://chat.stackexchange.com/transcript/message/" + event.message_id + "#" + event.message_id + ") in ") +
                    messageFormatting.room(event) +
                    messageFormatting.activity(" was flagged.")
                ).then(function(){
                    return say(
                        messageFormatting.activity("A [message](http://chat.stackexchange.com/transcript/message/" + event.message_id + "#" + event.message_id + ") in ") +
                        messageFormatting.room(event) +
                        messageFormatting.activity(" was flagged.")
                    );
                });
                // Uncomment the line below to turn on sharing of the message
                //say(messageFormatting.content(event));
            }
            break;
        default:
            return false;
            break;
    }
};
module.exports = {
    processEvent: processEvent,
    convert: convert,
    set: set,
    ITEMS: ITEMS,
    EVENT_TYPES: EVENT_TYPES
};
<|endoftext|>


<commit_before>// Copyright 2019 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// <https://apache.org/licenses/LICENSE-2.0>.
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

'use strict';

const path = require('path');

const tar = require('tar');

const { Installer } = require('../../shared/installer.js');

const extract = ({ filePath, binary, alias, os }) => {
	return new Promise(async (resolve, reject) => {
		const tmpPath = path.dirname(filePath);
		await tar.extract({
			file: filePath,
			cwd: tmpPath,
		});
		const installer = new Installer({
			engine: binary,
			path: tmpPath,
		});
		switch (os) {
			case 'mac64':
			case 'linux64': {
				installer.installBinary({ 'hermes': binary });
				installer.installBinary({ 'hermes-repl': `${binary}-repl` });
				break;
			}
			case 'win64': {
				installer.installBinary({ 'hermes.exe': `${binary}.exe` });
				installer.installBinary({ 'hermes-repl': `${binary}-repl.exe` });
				installer.installLibraryGlob('*.dll');
				break;
			}
		}
		resolve();
	});
};

module.exports = extract;
<commit_msg>Add missing .exe<commit_after>// Copyright 2019 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// <https://apache.org/licenses/LICENSE-2.0>.
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

'use strict';

const path = require('path');

const tar = require('tar');

const { Installer } = require('../../shared/installer.js');

const extract = ({ filePath, binary, alias, os }) => {
	return new Promise(async (resolve, reject) => {
		const tmpPath = path.dirname(filePath);
		await tar.extract({
			file: filePath,
			cwd: tmpPath,
		});
		const installer = new Installer({
			engine: binary,
			path: tmpPath,
		});
		switch (os) {
			case 'mac64':
			case 'linux64': {
				installer.installBinary({ 'hermes': binary });
				installer.installBinary({ 'hermes-repl': `${binary}-repl` });
				break;
			}
			case 'win64': {
				installer.installBinary({ 'hermes.exe': `${binary}.exe` });
				installer.installBinary({ 'hermes-repl.exe': `${binary}-repl.exe` });
				installer.installLibraryGlob('*.dll');
				break;
			}
		}
		resolve();
	});
};

module.exports = extract;
<|endoftext|>


<commit_before>import CloseIcon from 'react-icons/lib/md/close'

export default CloseIcon
<commit_msg>[base] Replace CloseIcon<commit_after>import React from 'react'

const strokeStyle = {vectorEffect: 'non-scaling-stroke'}

const CloseIcon = () => (
  <svg
    viewBox="0 0 25 25"
    fill="none"
    xmlns="http://www.w3.org/2000/svg"
    preserveAspectRatio="xMidYMid"
    width="1em"
    height="1em"
  >
    <path d="M19 6L6 19M6 6L19 19" stroke="currentColor" style={strokeStyle} />
  </svg>
)

export default CloseIcon
<|endoftext|>


<commit_before>import styled from 'styled-components'
import SlideMenu from 'react-burger-menu/lib/menus/slide'
import {theme} from 'tocco-ui'

export const StyledWrapper = styled.div`
  display: grid;
  grid-template:
    'header header' auto
    'menu content' 1fr / auto 1fr;
  background-color: #fff;
  height: 100vh;

  .bm-burger-button button:focus {
    outline: 0;
  }
`

export const StyledContent = styled.div`
  grid-area: content;
  background-color: ${theme.color('backgroundBody')};
  overflow: hidden;
  display: flex;
`
export const StyledMenu = styled(SlideMenu)`
  grid-area: menu;
`

export const burgerMenuStyles = {
  bmBurgerButton: {
    position: 'fixed',
    outline: '0',
    width: '24px',
    height: '24px',
    left: '10px',
    top: '10px'
  },
  bmBurgerBarsHover: {
    background: '#a90000'
  },
  bmMenuWrap: {
    position: 'fixed',
    height: '100%'
  },
  bmMenu: {
    background: '#fff',
    padding: '0 0 2em 0',
    fontSize: '1.15em',
    overflow: 'hidden'
  },
  bmMorphShape: {
    fill: '#373a47'
  },
  bmItemList: {
    color: '#b8b7ad',
    height: 'calc(100vh - 160px)'
  },
  bmItem: {
    display: 'inline-block'
  },
  bmOverlay: {
    background: 'rgba(0, 0, 0, 0.3)'
  }
}
<commit_msg>refactor(admin): adapt navigation width to match sidebar<commit_after>import styled from 'styled-components'
import SlideMenu from 'react-burger-menu/lib/menus/slide'
import {theme} from 'tocco-ui'

export const StyledWrapper = styled.div`
  display: grid;
  grid-template:
    'header header' auto
    'menu content' 1fr / auto 1fr;
  background-color: #fff;
  height: 100vh;

  .bm-burger-button button:focus {
    outline: 0;
  }
`

export const StyledContent = styled.div`
  grid-area: content;
  background-color: ${theme.color('backgroundBody')};
  overflow: hidden;
  display: flex;
`
export const StyledMenu = styled(SlideMenu)`
  grid-area: menu;
`

export const burgerMenuStyles = {
  bmBurgerButton: {
    position: 'fixed',
    outline: '0',
    width: '24px',
    height: '24px',
    left: '10px',
    top: '10px'
  },
  bmBurgerBarsHover: {
    background: '#a90000'
  },
  bmMenuWrap: {
    position: 'fixed',
    height: '100%',
    width: '16%',
    minWidth: '350px'
  },
  bmMenu: {
    background: '#fff',
    padding: '0 0 2em 0',
    fontSize: '1.15em',
    overflow: 'hidden'
  },
  bmMorphShape: {
    fill: '#373a47'
  },
  bmItemList: {
    color: '#b8b7ad',
    height: 'calc(100vh - 160px)'
  },
  bmItem: {
    display: 'inline-block'
  },
  bmOverlay: {
    background: 'rgba(0, 0, 0, 0.3)'
  }
}
<|endoftext|>


<commit_before>let async = require('async');
const utils = require('../../utils/utils.js');
const constants = require('../../constants');
const path  = require('path');

require('ejs');
const Templates = {
  vanilla_contract: require('./code_templates/vanilla-contract.js.ejs'),
  embarkjs_contract: require('./code_templates/embarkjs-contract.js.ejs'),
  exec_when_ready: require('./code_templates/exec-when-ready.js.ejs'),
  load_manager: require('./code_templates/load-manager.js.ejs'),
  define_when_env_loaded: require('./code_templates/define-when-env-loaded.js.ejs'),
  main_context: require('./code_templates/main-context.js.ejs'),
  do_when_loaded: require('./code_templates/do-when-loaded.js.ejs'),
  exec_when_env_loaded: require('./code_templates/exec-when-env-loaded.js.ejs')
};

class CodeGenerator {
  constructor(embark, options) {
    this.ready = false;
    this.blockchainConfig = embark.config.blockchainConfig || {};
    this.embarkConfig = embark.config.embarkConfig;
    this.fs = embark.fs;
    this.dappConfigs = {};
    this.logger = embark.logger;
    this.rpcHost = this.blockchainConfig.rpcHost || '';
    this.rpcPort = this.blockchainConfig.rpcPort || '';
    this.contractsConfig = embark.config.contractsConfig || {};
    this.storageConfig = embark.config.storageConfig || {};
    this.communicationConfig = embark.config.communicationConfig || {};
    this.namesystemConfig = embark.config.namesystemConfig || {};
    this.webServerConfig = embark.config.webServerConfig || {};
    this.env = options.env || 'development';
    this.plugins = options.plugins;
    this.events = embark.events;

    this.listenToCommands();
    this.ready = true;
    this.events.emit('code-generator:ready');
  }

  listenToCommands() {
    this.events.on('config:load:contracts', this.generateContractConfig.bind(this));
    this.events.on('config:load:storage', this.generateStorageConfig.bind(this));
    this.events.on('config:load:communication', this.generateCommunicationConfig.bind(this));

    this.events.setCommandHandler('code', (cb) => {
      this.events.request("contracts:list", (_err, contractsList) => {
        let embarkJSABI = this.generateABI(contractsList, {useEmbarkJS: true});
        let contractsJSON = this.generateContractsJSON(contractsList);
        cb(embarkJSABI, contractsJSON);
      });
    });

    this.events.setCommandHandler('code-generator:contract', (contractName, cb) => {
      this.events.request('contracts:contract', contractName, (contract) => {
        this.buildContractJS(contractName, this.generateContractJSON(contract, contract), cb);
      });
    });

    this.events.setCommandHandler('code-generator:contract:vanilla', (contract, gasLimit, cb) => {
      cb(this.generateContractCode(contract, gasLimit));
    });

    this.events.setCommandHandler('code-generator:contract:custom', (contract, cb) => {
      const customCode = this.generateCustomContractCode(contract);
      if (!customCode) {
        // Fallback to generate code from vanilla contract generator.
        //
        // TODO: can be moved into a afterDeploy event
        // just need to figure out the gasLimit coupling issue
        return cb(this.generateContractCode(contract, contract._gasLimit || false));
      }
      cb(customCode);
    });

    this.events.setCommandHandler('code-generator:embarkjs:provider-code', (cb) => {
      cb(this.getEmbarkJsProviderCode());
    });

    this.events.setCommandHandler('code-generator:embarkjs:init-provider-code', (cb) => {
      cb(this.getInitProviderCode());
    });

    this.events.setCommandHandler('code-generator:symlink:generate', (...args) => {
      this.generateSymlink(...args);
    });

    this.events.setCommandHandler("code-generator:embarkjs:build", (cb) => {
      this.buildEmbarkJS(cb);
    });

    this.events.setCommandHandler('code-generator:ready', (cb) => {
      if (this.ready) {
        return cb();
      }
      this.events.once('code-generator:ready', cb);
    });
  }

  generateContracts(contractsList, useEmbarkJS, isDeployment, useLoader) {
    let self = this;
    let result = "\n";
    let contractsPlugins;

    if (useLoader === false) {
      for (let contract of contractsList) {
        let abi = JSON.stringify(contract.abiDefinition);
        result += Templates.vanilla_contract({className: contract.className, abi: abi, contract: contract, gasLimit: constants.codeGenerator.gasLimit});
      }
      return result;
    }

    if (self.blockchainConfig === {} || self.blockchainConfig.enabled === false) {
      return "";
    }

    if (this.plugins) {
      contractsPlugins = this.plugins.getPluginsFor('contractGeneration');
    }

    if (this.plugins && contractsPlugins.length > 0) {
      contractsPlugins.forEach(function (plugin) {
        result += plugin.generateContracts({contracts: contractsList});
      });
    } else {
      for (let contract of contractsList) {
        let abi = JSON.stringify(contract.abiDefinition);
        let gasEstimates = JSON.stringify(contract.gasEstimates);

        let block = "";

        if (useEmbarkJS) {
           let contractAddress = contract.deployedAddress ? ("'" + contract.deployedAddress + "'") : "undefined";
          block += Templates.embarkjs_contract({className: contract.className, abi: abi, contract: contract, contractAddress: contractAddress, gasEstimates: gasEstimates});
        } else {
          block += Templates.vanilla_contract({className: contract.className, abi: abi, contract: contract, gasLimit: (isDeployment ? constants.codeGenerator.gasLimit : false)});
        }
        result += Templates.exec_when_ready({block: block});

      }
    }

    return result;
  }

  checkIfNeedsUpdate(file, newOutput, callback) {
    this.fs.readFile(file, (err, content) => {
      if (err) {
        return callback(null, true);
      }
      callback(null, content.toString() !== newOutput);
    });
  }

  generateContractConfig(contractConfig) {
    this.dappConfigs.blockchain = {
      dappConnection: contractConfig.dappConnection,
      dappAutoEnable: contractConfig.dappAutoEnable,
      warnIfMetamask: this.blockchainConfig.isDev,
      blockchainClient: this.blockchainConfig.ethereumClientName
    };
    this.generateArtifact(this.dappConfigs.blockchain, constants.dappArtifacts.blockchain, constants.dappArtifacts.dir);
  }

  generateStorageConfig(storageConfig) {
    this.dappConfigs.storage = {
      dappConnection: storageConfig.dappConnection
    };
    this.generateArtifact(this.dappConfigs.storage, constants.dappArtifacts.storage, constants.dappArtifacts.dir);
  }

  generateCommunicationConfig(communicationConfig) {
    this.dappConfigs.communication = {
      connection: communicationConfig.connection
    };
    this.generateArtifact(this.dappConfigs.communication, constants.dappArtifacts.communication, constants.dappArtifacts.dir);
  }

  generateArtifact(artifactInput, fileName, dirName, cb = () => {}) {
    const dir = utils.joinPath(this.embarkConfig.generationDir, dirName);
    const filePath = utils.joinPath(dir, fileName);
    if (typeof artifactInput !== 'string') {
      artifactInput = JSON.stringify(artifactInput, null, 2);
    }
    async.waterfall([
      (next) => {
        this.fs.mkdirp(dir, next);
      },
      (_dir, next) => {
        this.checkIfNeedsUpdate(filePath, artifactInput, next);
      },
      (needsUpdate, next) => {
        if (!needsUpdate) {
          return next();
        }
        this.fs.writeFile(filePath, artifactInput, next);
      }
    ], (err) => {
      if (err) {
        this.logger.error(err.message || err);
      }
      cb(err, filePath);
    });
  }

  generateContractCode(contract, gasLimit) {
    let abi = JSON.stringify(contract.abiDefinition);

    let block = "";
    block += Templates.vanilla_contract({className: contract.className, abi: abi, contract: contract, gasLimit: gasLimit});
    return block;
  }

  generateCustomContractCode(contract) {
    const customContractGeneratorPlugin = this.plugins.getPluginsFor('customContractGeneration').splice(-1)[0];
    if (!customContractGeneratorPlugin) {
      return null;
    }
    return customContractGeneratorPlugin.generateCustomContractCode(contract);
  }

  generateNamesInitialization(useEmbarkJS) {
    if (!useEmbarkJS || this.namesystemConfig === {}) return "";

    let result = "\n";
    result += Templates.define_when_env_loaded();
    result += this._getInitCode('names', this.namesystemConfig);

    return result;
  }

  generateStorageInitialization(useEmbarkJS) {
    if (!useEmbarkJS || this.storageConfig === {}) return "";

    let result = "\n";
    result += Templates.define_when_env_loaded();
    result += this._getInitCode('storage', this.storageConfig);

    return result;
  }

  generateCommunicationInitialization(useEmbarkJS) {
    if (!useEmbarkJS || this.communicationConfig === {}) return "";

    let result = "\n";
    result += Templates.define_when_env_loaded();
    result += this._getInitCode('communication', this.communicationConfig);

    return result;
  }

   _getInitCode(codeType, config) {
    let result = "";
    let pluginsWithCode = this.plugins.getPluginsFor('initCode');
    for (let plugin of pluginsWithCode) {
      let initCodes = plugin.embarkjs_init_code[codeType] || [];
      for (let initCode of initCodes) {
        let [block, shouldInit] = initCode;
        if (shouldInit.call(plugin, config)) {
          result += Templates.exec_when_env_loaded({block: block});
        }
      }
    }
    return result;
  }

  generateABI(contractsList, options) {
    let result = "";

    result += this.generateContracts(contractsList, options.useEmbarkJS, options.deployment, true);
    result += this.generateStorageInitialization(options.useEmbarkJS);
    result += this.generateCommunicationInitialization(options.useEmbarkJS);
    result += this.generateNamesInitialization(options.useEmbarkJS);

    return result;
  }

  generateContractJSON(className, contract) {
    let contractJSON = {};

    contractJSON.contract_name = className;
    contractJSON.address = contract.deployedAddress;
    contractJSON.code = contract.code;
    contractJSON.runtime_bytecode = contract.runtimeBytecode;
    contractJSON.real_runtime_bytecode = contract.realRuntimeBytecode;
    contractJSON.swarm_hash = contract.swarmHash;
    contractJSON.gas_estimates = contract.gasEstimates;
    contractJSON.function_hashes = contract.functionHashes;
    contractJSON.abi = contract.abiDefinition;

    return contractJSON;
  }

  generateContractsJSON(contractsList) {
    let contracts = {};

    for (let contract of contractsList) {
      contracts[contract.className] = this.generateContractJSON(contract.className, contract);
    }

    return contracts;
  }

  buildEmbarkJS(cb) {
    const self = this;
    let embarkjsCode = '';
    let code = "/* eslint-disable */";

    async.waterfall([
      function getEmbarkJsLocation(next) {
        self.events.request('version:downloadIfNeeded', 'embarkjs', (err, location) => {
          if (err) {
            this.logger.error(__('Error downloading EmbarkJS'));
            return next(err);
          }
          next(null, location);
        });
      },
      function generateSymlink(location, next) {
        self.generateSymlink(location, 'embarkjs', (err, symlinkDest) => {
          if (err) {
            this.logger.error(__('Error creating a symlink to EmbarkJS'));
            return next(err);
          }
          embarkjsCode += `\nconst EmbarkJS = require("${symlinkDest}").default;`;
          embarkjsCode += "\nexport default EmbarkJS;";
          embarkjsCode += "\nglobal.EmbarkJS = EmbarkJS";
          next();
        });
      },
      function getJSCode(next) {
        code += "\n" + embarkjsCode + "\n";

        code += self.getEmbarkJsProviderCode();
        code += self.generateCommunicationInitialization(true);
        code += self.generateStorageInitialization(true);
        code += self.generateNamesInitialization(true);
        code += self.getReloadPageCode();
        code += '\n/* eslint-enable */';

        next();
      },
      function writeFile(next) {
        self.generateArtifact(code, constants.dappArtifacts.embarkjs, '', next);
      }
    ], function(_err, _result) {
      cb();
    });
  }

  getReloadPageCode() {
    return this.env === 'development' ? this.fs.readFileSync(require('path').join(__dirname,'/code/reload-on-change.js'), 'utf8') : '';
  }

  getEmbarkJsProviderCode() {
    return this.plugins.getPluginsFor('embarkjsCode').reduce((code, plugin) => (
      code += plugin.embarkjs_code.join('\n')
    ), '');
  }

  getInitProviderCode() {
    const codeTypes = {
      blockchain: this.blockchainConfig || {},
      communication: this.communicationConfig || {},
      names: this.namesystemConfig || {},
      storage: this.storageConfig || {}
    };

    return this.plugins.getPluginsFor("initConsoleCode").reduce((acc, plugin) => {
      Object.keys(codeTypes).forEach((codeTypeName) => {
        (plugin.embarkjs_init_console_code[codeTypeName] || []).forEach((initCode) => {
          const [block, shouldInit] = initCode;
          if (shouldInit.call(plugin, codeTypes[codeTypeName])) {
            acc += block;
          }
        });
      });
      return acc;
    }, "");
  }

  buildContractJS(contractName, contractJSON, cb) {
    let contractCode = "import EmbarkJS from '../embarkjs';\n";
    contractCode += `let ${contractName}JSONConfig = ${JSON.stringify(contractJSON)};\n`;
    contractCode += `let ${contractName} = new EmbarkJS.Blockchain.Contract(${contractName}JSONConfig);\n`;

    contractCode += "export default " + contractName + ";\n";

    this.generateArtifact(contractCode, contractName + '.js', constants.dappArtifacts.contractsJs, cb);
  }

  generateSymlink(target, name, callback) {
    async.waterfall([
      // Make directory
      next => {
        const symlinkDir = this.fs.dappPath(this.embarkConfig.generationDir, constants.dappArtifacts.symlinkDir);
        this.fs.mkdirp(symlinkDir, (err) => {
          if (err) {
            return next(err);
          }
          next(null, utils.joinPath(symlinkDir, name).replace(/\\/g, '/'));
        });
      },
      // Remove old symlink because they are not overwritable
      (symlinkDest, next) => {
        this.fs.remove(symlinkDest, (err) => {
          if (err) {
            return next(err);
          }
          next(null, symlinkDest);
        });
      },
      // Make target a directory as files don't work on Windows
      (symlinkDest, next) => {
        this.fs.stat(target, (err, stats) => {
          if (err) {
            return next(err);
          }
          let finalTarget = target;
          if (stats.isFile()) {
            finalTarget = path.dirname(target);
          }
          next(null, symlinkDest, finalTarget);
        });
      },
      (symlinkDest, finalTarget, next) => {
        this.fs.symlink(finalTarget, symlinkDest, 'junction', (err) => {
          if (err) {
            return next(err);
          }
          next(null, symlinkDest);
        });
      }
    ], callback);
  }
}

module.exports = CodeGenerator;
<commit_msg>bugfix(@embark/code_generator): write blockchain config file before writing embarkjs artifact<commit_after>let async = require('async');
const utils = require('../../utils/utils.js');
const constants = require('../../constants');
const path  = require('path');

require('ejs');
const Templates = {
  vanilla_contract: require('./code_templates/vanilla-contract.js.ejs'),
  embarkjs_contract: require('./code_templates/embarkjs-contract.js.ejs'),
  exec_when_ready: require('./code_templates/exec-when-ready.js.ejs'),
  load_manager: require('./code_templates/load-manager.js.ejs'),
  define_when_env_loaded: require('./code_templates/define-when-env-loaded.js.ejs'),
  main_context: require('./code_templates/main-context.js.ejs'),
  do_when_loaded: require('./code_templates/do-when-loaded.js.ejs'),
  exec_when_env_loaded: require('./code_templates/exec-when-env-loaded.js.ejs')
};

class CodeGenerator {
  constructor(embark, options) {
    this.ready = false;
    this.blockchainConfig = embark.config.blockchainConfig || {};
    this.embarkConfig = embark.config.embarkConfig;
    this.fs = embark.fs;
    this.dappConfigs = {};
    this.logger = embark.logger;
    this.rpcHost = this.blockchainConfig.rpcHost || '';
    this.rpcPort = this.blockchainConfig.rpcPort || '';
    this.contractsConfig = embark.config.contractsConfig || {};
    this.storageConfig = embark.config.storageConfig || {};
    this.communicationConfig = embark.config.communicationConfig || {};
    this.namesystemConfig = embark.config.namesystemConfig || {};
    this.webServerConfig = embark.config.webServerConfig || {};
    this.env = options.env || 'development';
    this.plugins = options.plugins;
    this.events = embark.events;

    this.listenToCommands();
    this.ready = true;
    this.events.emit('code-generator:ready');
  }

  listenToCommands() {
    this.events.on('config:load:contracts', this.generateContractConfig.bind(this));
    this.events.on('config:load:storage', this.generateStorageConfig.bind(this));
    this.events.on('config:load:communication', this.generateCommunicationConfig.bind(this));

    this.events.setCommandHandler('code', (cb) => {
      this.events.request("contracts:list", (_err, contractsList) => {
        let embarkJSABI = this.generateABI(contractsList, {useEmbarkJS: true});
        let contractsJSON = this.generateContractsJSON(contractsList);
        cb(embarkJSABI, contractsJSON);
      });
    });

    this.events.setCommandHandler('code-generator:contract', (contractName, cb) => {
      this.events.request('contracts:contract', contractName, (contract) => {
        this.buildContractJS(contractName, this.generateContractJSON(contract, contract), cb);
      });
    });

    this.events.setCommandHandler('code-generator:contract:vanilla', (contract, gasLimit, cb) => {
      cb(this.generateContractCode(contract, gasLimit));
    });

    this.events.setCommandHandler('code-generator:contract:custom', (contract, cb) => {
      const customCode = this.generateCustomContractCode(contract);
      if (!customCode) {
        // Fallback to generate code from vanilla contract generator.
        //
        // TODO: can be moved into a afterDeploy event
        // just need to figure out the gasLimit coupling issue
        return cb(this.generateContractCode(contract, contract._gasLimit || false));
      }
      cb(customCode);
    });

    this.events.setCommandHandler('code-generator:embarkjs:provider-code', (cb) => {
      cb(this.getEmbarkJsProviderCode());
    });

    this.events.setCommandHandler('code-generator:embarkjs:init-provider-code', (cb) => {
      cb(this.getInitProviderCode());
    });

    this.events.setCommandHandler('code-generator:symlink:generate', (...args) => {
      this.generateSymlink(...args);
    });

    this.events.setCommandHandler("code-generator:embarkjs:build", (cb) => {
      this.buildEmbarkJS(cb);
    });

    this.events.setCommandHandler('code-generator:ready', (cb) => {
      if (this.ready) {
        return cb();
      }
      this.events.once('code-generator:ready', cb);
    });
  }

  generateContracts(contractsList, useEmbarkJS, isDeployment, useLoader) {
    let self = this;
    let result = "\n";
    let contractsPlugins;

    if (useLoader === false) {
      for (let contract of contractsList) {
        let abi = JSON.stringify(contract.abiDefinition);
        result += Templates.vanilla_contract({className: contract.className, abi: abi, contract: contract, gasLimit: constants.codeGenerator.gasLimit});
      }
      return result;
    }

    if (self.blockchainConfig === {} || self.blockchainConfig.enabled === false) {
      return "";
    }

    if (this.plugins) {
      contractsPlugins = this.plugins.getPluginsFor('contractGeneration');
    }

    if (this.plugins && contractsPlugins.length > 0) {
      contractsPlugins.forEach(function (plugin) {
        result += plugin.generateContracts({contracts: contractsList});
      });
    } else {
      for (let contract of contractsList) {
        let abi = JSON.stringify(contract.abiDefinition);
        let gasEstimates = JSON.stringify(contract.gasEstimates);

        let block = "";

        if (useEmbarkJS) {
           let contractAddress = contract.deployedAddress ? ("'" + contract.deployedAddress + "'") : "undefined";
          block += Templates.embarkjs_contract({className: contract.className, abi: abi, contract: contract, contractAddress: contractAddress, gasEstimates: gasEstimates});
        } else {
          block += Templates.vanilla_contract({className: contract.className, abi: abi, contract: contract, gasLimit: (isDeployment ? constants.codeGenerator.gasLimit : false)});
        }
        result += Templates.exec_when_ready({block: block});

      }
    }

    return result;
  }

  checkIfNeedsUpdate(file, newOutput, callback) {
    this.fs.readFile(file, (err, content) => {
      if (err) {
        return callback(null, true);
      }
      callback(null, content.toString() !== newOutput);
    });
  }

  generateContractConfig(contractConfig, callback) {
    this.dappConfigs.blockchain = {
      dappConnection: contractConfig.dappConnection,
      dappAutoEnable: contractConfig.dappAutoEnable,
      warnIfMetamask: this.blockchainConfig.isDev,
      blockchainClient: this.blockchainConfig.ethereumClientName
    };
    this.generateArtifact(this.dappConfigs.blockchain, constants.dappArtifacts.blockchain, constants.dappArtifacts.dir, callback);
  }

  generateStorageConfig(storageConfig) {
    this.dappConfigs.storage = {
      dappConnection: storageConfig.dappConnection
    };
    this.generateArtifact(this.dappConfigs.storage, constants.dappArtifacts.storage, constants.dappArtifacts.dir);
  }

  generateCommunicationConfig(communicationConfig) {
    this.dappConfigs.communication = {
      connection: communicationConfig.connection
    };
    this.generateArtifact(this.dappConfigs.communication, constants.dappArtifacts.communication, constants.dappArtifacts.dir);
  }

  generateArtifact(artifactInput, fileName, dirName, cb = () => {}) {
    const dir = utils.joinPath(this.embarkConfig.generationDir, dirName);
    const filePath = utils.joinPath(dir, fileName);
    if (typeof artifactInput !== 'string') {
      artifactInput = JSON.stringify(artifactInput, null, 2);
    }
    async.waterfall([
      (next) => {
        this.fs.mkdirp(dir, next);
      },
      (_dir, next) => {
        this.checkIfNeedsUpdate(filePath, artifactInput, next);
      },
      (needsUpdate, next) => {
        if (!needsUpdate) {
          return next();
        }
        this.fs.writeFile(filePath, artifactInput, next);
      }
    ], (err) => {
      if (err) {
        this.logger.error(err.message || err);
      }
      cb(err, filePath);
    });
  }

  generateContractCode(contract, gasLimit) {
    let abi = JSON.stringify(contract.abiDefinition);

    let block = "";
    block += Templates.vanilla_contract({className: contract.className, abi: abi, contract: contract, gasLimit: gasLimit});
    return block;
  }

  generateCustomContractCode(contract) {
    const customContractGeneratorPlugin = this.plugins.getPluginsFor('customContractGeneration').splice(-1)[0];
    if (!customContractGeneratorPlugin) {
      return null;
    }
    return customContractGeneratorPlugin.generateCustomContractCode(contract);
  }

  generateNamesInitialization(useEmbarkJS) {
    if (!useEmbarkJS || this.namesystemConfig === {}) return "";

    let result = "\n";
    result += Templates.define_when_env_loaded();
    result += this._getInitCode('names', this.namesystemConfig);

    return result;
  }

  generateStorageInitialization(useEmbarkJS) {
    if (!useEmbarkJS || this.storageConfig === {}) return "";

    let result = "\n";
    result += Templates.define_when_env_loaded();
    result += this._getInitCode('storage', this.storageConfig);

    return result;
  }

  generateCommunicationInitialization(useEmbarkJS) {
    if (!useEmbarkJS || this.communicationConfig === {}) return "";

    let result = "\n";
    result += Templates.define_when_env_loaded();
    result += this._getInitCode('communication', this.communicationConfig);

    return result;
  }

   _getInitCode(codeType, config) {
    let result = "";
    let pluginsWithCode = this.plugins.getPluginsFor('initCode');
    for (let plugin of pluginsWithCode) {
      let initCodes = plugin.embarkjs_init_code[codeType] || [];
      for (let initCode of initCodes) {
        let [block, shouldInit] = initCode;
        if (shouldInit.call(plugin, config)) {
          result += Templates.exec_when_env_loaded({block: block});
        }
      }
    }
    return result;
  }

  generateABI(contractsList, options) {
    let result = "";

    result += this.generateContracts(contractsList, options.useEmbarkJS, options.deployment, true);
    result += this.generateStorageInitialization(options.useEmbarkJS);
    result += this.generateCommunicationInitialization(options.useEmbarkJS);
    result += this.generateNamesInitialization(options.useEmbarkJS);

    return result;
  }

  generateContractJSON(className, contract) {
    let contractJSON = {};

    contractJSON.contract_name = className;
    contractJSON.address = contract.deployedAddress;
    contractJSON.code = contract.code;
    contractJSON.runtime_bytecode = contract.runtimeBytecode;
    contractJSON.real_runtime_bytecode = contract.realRuntimeBytecode;
    contractJSON.swarm_hash = contract.swarmHash;
    contractJSON.gas_estimates = contract.gasEstimates;
    contractJSON.function_hashes = contract.functionHashes;
    contractJSON.abi = contract.abiDefinition;

    return contractJSON;
  }

  generateContractsJSON(contractsList) {
    let contracts = {};

    for (let contract of contractsList) {
      contracts[contract.className] = this.generateContractJSON(contract.className, contract);
    }

    return contracts;
  }

  buildEmbarkJS(cb) {
    const self = this;
    let embarkjsCode = '';
    let code = "/* eslint-disable */";

    async.waterfall([
      // TODO: here due to a race condition when running embark build
      function generateConfig(next) {
        self.events.request("config:contractsConfig", (contractsConfig) => {
          self.generateContractConfig(contractsConfig, () => {
            next()
          })
        })
      },
      function getEmbarkJsLocation(next) {
        self.events.request('version:downloadIfNeeded', 'embarkjs', (err, location) => {
          if (err) {
            this.logger.error(__('Error downloading EmbarkJS'));
            return next(err);
          }
          next(null, location);
        });
      },
      function generateSymlink(location, next) {
        self.generateSymlink(location, 'embarkjs', (err, symlinkDest) => {
          if (err) {
            this.logger.error(__('Error creating a symlink to EmbarkJS'));
            return next(err);
          }
          embarkjsCode += `\nconst EmbarkJS = require("${symlinkDest}").default;`;
          embarkjsCode += "\nexport default EmbarkJS;";
          embarkjsCode += "\nglobal.EmbarkJS = EmbarkJS";
          next();
        });
      },
      function getJSCode(next) {
        code += "\n" + embarkjsCode + "\n";

        code += self.getEmbarkJsProviderCode();
        code += self.generateCommunicationInitialization(true);
        code += self.generateStorageInitialization(true);
        code += self.generateNamesInitialization(true);
        code += self.getReloadPageCode();
        code += '\n/* eslint-enable */';

        next();
      },
      function writeFile(next) {
        self.generateArtifact(code, constants.dappArtifacts.embarkjs, '', next);
      }
    ], function(_err, _result) {
      cb();
    });
  }

  getReloadPageCode() {
    return this.env === 'development' ? this.fs.readFileSync(require('path').join(__dirname,'/code/reload-on-change.js'), 'utf8') : '';
  }

  getEmbarkJsProviderCode() {
    return this.plugins.getPluginsFor('embarkjsCode').reduce((code, plugin) => (
      code += plugin.embarkjs_code.join('\n')
    ), '');
  }

  getInitProviderCode() {
    const codeTypes = {
      blockchain: this.blockchainConfig || {},
      communication: this.communicationConfig || {},
      names: this.namesystemConfig || {},
      storage: this.storageConfig || {}
    };

    return this.plugins.getPluginsFor("initConsoleCode").reduce((acc, plugin) => {
      Object.keys(codeTypes).forEach((codeTypeName) => {
        (plugin.embarkjs_init_console_code[codeTypeName] || []).forEach((initCode) => {
          const [block, shouldInit] = initCode;
          if (shouldInit.call(plugin, codeTypes[codeTypeName])) {
            acc += block;
          }
        });
      });
      return acc;
    }, "");
  }

  buildContractJS(contractName, contractJSON, cb) {
    let contractCode = "import EmbarkJS from '../embarkjs';\n";
    contractCode += `let ${contractName}JSONConfig = ${JSON.stringify(contractJSON)};\n`;
    contractCode += `let ${contractName} = new EmbarkJS.Blockchain.Contract(${contractName}JSONConfig);\n`;

    contractCode += "export default " + contractName + ";\n";

    this.generateArtifact(contractCode, contractName + '.js', constants.dappArtifacts.contractsJs, cb);
  }

  generateSymlink(target, name, callback) {
    async.waterfall([
      // Make directory
      next => {
        const symlinkDir = this.fs.dappPath(this.embarkConfig.generationDir, constants.dappArtifacts.symlinkDir);
        this.fs.mkdirp(symlinkDir, (err) => {
          if (err) {
            return next(err);
          }
          next(null, utils.joinPath(symlinkDir, name).replace(/\\/g, '/'));
        });
      },
      // Remove old symlink because they are not overwritable
      (symlinkDest, next) => {
        this.fs.remove(symlinkDest, (err) => {
          if (err) {
            return next(err);
          }
          next(null, symlinkDest);
        });
      },
      // Make target a directory as files don't work on Windows
      (symlinkDest, next) => {
        this.fs.stat(target, (err, stats) => {
          if (err) {
            return next(err);
          }
          let finalTarget = target;
          if (stats.isFile()) {
            finalTarget = path.dirname(target);
          }
          next(null, symlinkDest, finalTarget);
        });
      },
      (symlinkDest, finalTarget, next) => {
        this.fs.symlink(finalTarget, symlinkDest, 'junction', (err) => {
          if (err) {
            return next(err);
          }
          next(null, symlinkDest);
        });
      }
    ], callback);
  }
}

module.exports = CodeGenerator;
<|endoftext|>