<commit_before>define(["js/core/Component", "google/analytics/PageTracker", "sprd/tracking/Omniture", "sprd/tracking/Optimizely", "sprd/tracking/Wellness"], function (Component, PageTracker, Omniture, Optimizely, Wellness) {

    return Component.inherit("sprd.manager.TrackingManagerBase", {

        ctor: function () {
            this.$orderId = (new Date()).getTime();
            this.callBase();
        },

        inject: {
            google: PageTracker,
            omniture: Omniture,
            optimizely: Optimizely,
            wellness: Wellness
        },

        trackAddToBasket: function () {

            var omniture = this.$.omniture,
                google = this.$.google,
                optimizely = this.$.optimizely;

            omniture.track(null, null, ["event24"]);
            google.trackEvent("Basket", "AddToBasket");
            optimizely.trackEvent("AddToBasket");
        },

        /***
         * track an event, after the add to basket button in the size dialog
         * has been clicked
         */
        trackAddToBasketSize: function () {

            var omniture = this.$.omniture,
                google = this.$.google,
                optimizely = this.$.optimizely;

            omniture.track(null, null, ["scAdd"]);
            optimizely.trackEvent("AddToBasket-Size");
            google.trackEvent("Basket", "AddToBasket-Size");

        },

        trackSaveProductTiming: function (time) {
            var google = this.$.google;
            google.trackTiming("Basket", "SaveProduct", time);
        },

        trackProductCreationError: function (statusCode) {

            var omniture = this.$.omniture;

            omniture && omniture.track(null, {
                prop42: statusCode,
                eVar42: statusCode
            });

        },

        trackAddToBasketError: function (error) {
            this.$.google.trackEvent("Basket", "AddToBasketError", error);
        },

        trackAddToBasketImplementationTiming: function (time) {
            this.$.google.trackTiming("Basket", "AddToBasketImplementation", Date.now() - time);
        },

        trackAddToBasketTiming: function (time, basketItems) {
            this.$.google.trackTiming("Basket", "AddToBasket", time, "Items: " + basketItems);
        },

        trackGoToCheckout: function () {

            var omniture = this.$.omniture,
                google = this.$.google;

            google.trackEvent("Basket", "GoToCheckout");
            omniture.track(null, {
                eVar33: "Designer - Checkout Button"
            });

        },

        trackBasketCreated: function () {
            var omniture = this.$.omniture;
            omniture.track("scOpen", null, ["scOpen"]);
        },

        trackAddAnotherProduct: function () {

            var omniture = this.$.omniture,
                google = this.$.google;

            google.trackEvent("Basket", "CreateAnotherProduct");
            omniture.track(null, {
                eVar33: "Designer - Create other Product Button"
            });

        },

        trackNavigation: function (module) {
            this.$.google.trackEvent("Navigation", module);
        },

        /***
         * user clicked on checkout in the basket
         */
        trackCheckout: function () {
            this.$.google.trackEvent("Basket", "Checkout");
        },

        trackTransaction: function (basket) {

            var google = this.$.google,
                orderId = basket.$.id + '-' + (++this.$orderId),
                transaction = google.createTransaction(orderId, null, basket.vatIncluded());

            basket.$.basketItems.each(function (basketItem) {
                var element = basketItem.$.element;
                transaction.addItem(element.sku(), element.uniqueId() + " - " + element.get('item.name'), basketItem.vatIncluded(), basketItem.$.quantity);
            }, this);

            google.trackTransaction(transaction);
        },

        trackMementoStoreError: function (message, length) {
            this.$.google.trackEvent("Error", "MementoStore", message, length);
        },

        trackStartApplication: function() {
            var omniture = this.$.omniture;
            omniture && omniture.track("start", null, ["event1"]);
        },

        trackUncaughtError: function (message, filename, lineNumber, applicationParameter) {

            var google = this.$.google;
            google.trackEvent("Error", "UncaughtError", message + " from " + filename + ":" + lineNumber
                + "\n" + applicationParameter);
        },

        trackFirstClick: function () {
            this.$.omniture.track("firstClick", null, ["event16"]);
            this.$.optimizely.trackEvent("engagement");
        },

        trackApplicationError: function (message, stack) {
            var google = this.$.google;
            google.trackEvent("Error", "ApplicationError", message + (stack || ""));
        },

        trackApplicationStartComplete: function () {
            this.$.omniture.track("finish", {}, ["event2"]);
        },

        trackApplicationLoadTime: function (time) {
            var google = this.$.google;
            google.trackTiming("Application", "LoadingTime", time);
        },

        trackStartError: function (error) {
            var google = this.$.google;
            google.trackEvent("Application", "StartError");
        },

        trackApplicationStartTime: function (time) {
            var google = this.$.google;
            google.trackTiming("Application", "StartTime", time);
        },

        trackOpenSharePanel: function() {
            var optimizely = this.$.optimizely;
            optimizely.trackEvent("OpenSharePanel");
        },

        trackShareOnFacebook: function () {
            var google = this.$.google;
            google.trackEvent("Share", "Facebook");
        },

        trackShareOnTwitter: function () {
            var google = this.$.google;
            google.trackEvent("Share", "Twitter");
        },

        trackShareLink: function () {
            var google = this.$.google;
            google.trackEvent("Share", "Link");
        },

        trackShareByMail: function () {
            var google = this.$.google;
            google.trackEvent("Share", "Mail");
        },

        trackShareByMailSuccess: function () {
            var google = this.$.google;
            google.trackEvent("Share", "MailSuccess");
        },

        trackShareByMailError: function () {
            var google = this.$.google;
            google.trackEvent("Share", "MailError");
        },

        trackDesignClick: function(data) {
            this.$.wellness.track("designSelection", data);
        },

        trackProductTypeSelection: function(data) {
            this.$.wellness.track("productTypeSelection", data);
        }
    });

});<commit_msg>Edited TrackingManagerBase.<commit_after>define(["js/core/Component"], function (Component) {
    return Component.inherit("sprd.manager.TrackingManagerBase", {
        ctor: function () {
            this.$uniqueId = (new Date()).getTime();
            this.callBase();
        }
    });
});<|endoftext|>


<commit_before>module.exports = {

	//---------------------------------------------------------------------
	// Action Name
	//
	// This is the name of the action displayed in the editor.
	//---------------------------------------------------------------------

	name: "Store Bot Client Info",

	//---------------------------------------------------------------------
	// Action Section
	//
	// This is the section the action will fall into.
	//---------------------------------------------------------------------

	section: "Bot Client Control",

	//---------------------------------------------------------------------
	// Action Subtitle
	//
	// This function generates the subtitle displayed next to the name.
	//---------------------------------------------------------------------

	subtitle: function(data) {
	const info = ['Uptime in Milliseconds', 'Ready At?', 'Ping', 'Guild Amount', 'User Amount', 'Rounded Ping', 'Uptime in Seconds', 'Uptime in Minutes', 'Bot\'s Token', 'Voice Connections Amount', 'Total Amount of Channels', 'Total Amount of Emojis', 'Bot\'s Previous Pings', 'Uptime in Days', 'Uptime in Days (Rounded)', 'Memory (RAM) Usage', 'Bot Guilds Objects', 'Bot Guilds Names', 'Bot Guilds IDs', 'Bot Current Prefix', 'Bot Client ID', 'Discord JS Version', 'Uptime in Hours', 'Restarting Uptime in Days', 'Restarting Uptime in Hours', 'Restarting Uptime in Minutes', 'Restarting Uptime in Seconds', 'Memory (RAM) Usage in MB', 'Bot\'s OS (Process Platform)'];
		return `Bot Client - ${info[parseInt(data.info)]}`;
	},

	//---------------------------------------------------------------------
		 // DBM Mods Manager Variables (Optional but nice to have!)
		 //
		 // These are variables that DBM Mods Manager uses to show information
		 // about the mods for people to see in the list.
		 //---------------------------------------------------------------------

		 // Who made the mod (If not set, defaults to "DBM Mods")
		 author: "Lasse, EliteArtz and EGGSY",

		 // The version of the mod (Defaults to 1.0.0)
		 version: "1.8.5",

		 // A short description to show on the mod line for this mod (Must be on a single line)
		 short_description: "Stores Bot Information like Ping, Total Members or Guilds...",

		 // If it depends on any other mods by name, ex: WrexMODS if the mod uses something from WrexMods

		 //---------------------------------------------------------------------

	//---------------------------------------------------------------------
	// Action Storage Function
	//
	// Stores the relevant variable info for the editor.
	//---------------------------------------------------------------------

	variableStorage: function(data, varType) {
		const type = parseInt(data.storage);
		if(type !== varType) return;
		const info = parseInt(data.info);
		let dataType = 'Unknown Type';
		switch(info) {
			case 0:
				dataType = "Number";
				break;
			case 1:
				dataType = "Date";
				break;
			case 2:
				dataType = "Number";
				break;
			case 3:
				dataType = "Number";
				break;
			case 4:
				dataType = "Number";
				break;
			case 5:
				dataType = "Number";
				break;
			case 6:
				dataType = "Number";
				break;
			case 7:
				dataType = "Number";
				break;
			case 8:
				dataType = "Token";
				break;
			case 9:
				dataType = "Number";
				break;
			case 10:
				dataType = "Number";
				break;
			case 11:
				dataType = "Number";
				break;
			case 12:
				dataType = "Number";
				break;
			case 13:
				dataType = "Time";
				break;
			case 14:
				dataType = "Time";
				break;
			case 15:
				dataType = "Number";
				break;
			case 16:
				dataType = "Guild";
				break;
			case 17:
				dataType = "Guild Name";
				break;
			case 18:
				dataType = "Guild ID";
				break;
			case 19:
				dataType = "Bot Tag";
				break;
			case 20:
				dataType = "Bot ID";
				break;
			case 21:
				dataType = "Version Number";
				break;
			case 22:
				dataType = "Number";
				break;
			case 23:
				dataType = "Time";
				break;
			case 24:
				dataType = "Time";
				break;
			case 25:
				dataType = "Time";
				break;
			case 26:
				dataType = "Time";
				break;
			case 27:
				dataType = "Number";
				break;
			case 28:
				dataType = "OS Name";
				break;
		}
		return ([data.varName2, dataType]);
	},

	//---------------------------------------------------------------------
	// Action Fields
	//
	// These are the fields for the action. These fields are customized
	// by creating elements with corresponding IDs in the HTML. These
	// are also the names of the fields stored in the action's JSON data.
	//---------------------------------------------------------------------

	fields: ["info", "storage", "varName2"],

	//---------------------------------------------------------------------
	// Command HTML
	//
	// This function returns a string containing the HTML used for
	// editting actions.
	//
	// The "isEvent" parameter will be true if this action is being used
	// for an event. Due to their nature, events lack certain information,
	// so edit the HTML to reflect this.
	//
	// The "data" parameter stores constants for select elements to use.
	// Each is an array: index 0 for commands, index 1 for events.
	// The names are: sendTargets, members, roles, channels,
	//                messages, servers, variables
	//---------------------------------------------------------------------

	html: function(isEvent, data) {
		return `

				Mod Info:

				Created by EliteArtz, EGGSY and Lasse!

		Source Info:

		<select id="info" class="round">
			<option value="0">Uptime in Milliseconds</option>
			<option value="1">Ready At</option>
			<option value="2">Ping</option>
			<option value="3">Total Amount of Guilds</option>
			<option value="4">Total Amount of Users</option>
			<option value="5">Rounded Ping</option>
			<option value="6">Uptime in Seconds</option>
			<option value="7">Uptime in Minutes</option>
			<option value="8">Bot's Token</option>
			<option value="9">Total Voice connections</option>
			<option value="10">Total Amount of Channels</option>
			<option value="11">Total Amount of Emojis</option>
			<option value="12">Bot's Previous Pings</option>
			<option value="13">Uptime in Days</option>
			<option value="14">Uptime in Days (Rounded)</option>
			<option value="15">Memory (RAM) Usage</option>
			<option value="16">Bot Guilds Objects</option>
			<option value="17">Bot Guilds Names</option>
			<option value="18">Bot Guilds IDs</option>
			<option value="19">Bot Current Prefix</option>
			<option value="20">Bot Client ID</option>
			<option value="21">Discord JS Version</option>
			<option value="22">Uptime in Hours</option>
			<option value="23">Restarting Uptime in Days</option>
			<option value="24">Restarting Uptime in Hours</option>
			<option value="25">Restarting Uptime in Minutes</option>
			<option value="26">Restarting Uptime in Seconds</option>
			<option value="27">Memory (RAM) Usage in MB</option>
			<option value="28">Bot's OS (Process Platform)</option>
		</select>

			Store In:

			<select id="storage" class="round">
				${data.variables[1]}
			</select>

			Variable Name:

			<input id="varName2" class="round" type="text">

`
	},

	//---------------------------------------------------------------------
	// Action Editor Init Code
	//
	// When the HTML is first applied to the action editor, this code
	// is also run. This helps add modifications or setup reactionary
	// functions for the DOM elements.
	//---------------------------------------------------------------------

	init: function() {
	},

	//---------------------------------------------------------------------
	// Action Bot Function
	//
	// This is the function for the action within the Bot's Action class.
	// Keep in mind event calls won't have access to the "msg" parameter,
	// so be sure to provide checks for variable existance.
	//---------------------------------------------------------------------

	action: function(cache) {
		const botClient = this.getDBM().Bot.bot;
		const dibiem = this.getDBM(); //EliteArtz... really???? Ugh you guys are meme
		const data = cache.actions[cache.index];
		const info = parseInt(data.info);
		const DiscordJS = dibiem.DiscordJS = require('discord.js'); // tf is dibiem
		const msToDay = (1000*60*60*24); // Really? Lasse? Did you really forget this? - :blobshh:
		const used = process.memoryUsage().heapUsed / 1024 / 1024; // Sorry about all const things but this is needed, you know.
		if(!botClient) {
			this.callNextAction(cache);
			return;
		}
		switch(info) {
			case 0:
				result = botClient.uptime;
				break;
			case 1:
				result = botClient.readyAt;
				break;
			case 2:
				result = botClient.ping;
				break;
			case 3:
				result = botClient.guilds.array().length;
				break;
			case 4:
				result = botClient.users.array().length;
				break;
			case 5:
				result = Math.round(botClient.ping);
				break;
			case 6:
				result = Math.floor(botClient.uptime/1000);
				break;
			case 7:
				result = Math.floor(botClient.uptime/1000/60);
				break;
			case 8:
				result = botClient.token;
				break;
			case 9:
				result = botClient.voiceConnections.array().length;
				break;
			case 10:
				result = botClient.channels.size;
				break;
			case 11:
				result = botClient.emojis.size;
				break;
			case 12:
				result = botClient.pings;
				break;
			case 13:
				result = botClient.uptime/msToDay;
				break;
			case 14:
				result = Math.floor(botClient.uptime/msToDay);
				break;
			case 15:
				result = ((process.memoryUsage().heapUsed / 1024) / 1024).toFixed(2) + "%";
				break;
			case 16:
				result = botClient.guilds;
				 break;
			case 17:
				result = botClient.guilds.array();
				break;
			case 18:
				result = botClient.guilds.map(guilds => guilds.id);
				break;
			case 19:
				result = dibiem.Files.data.settings.tag;
				break;
			case 20:
				result = dibiem.Files.data.settings.client;
				break;
			case 21:
				result = DiscordJS.version;
				break;
			case 22:
				result = Math.floor(botClient.uptime/1000/60/60);
				break;
			case 23:
				result = Math.floor((process.uptime() % 31536000) / 86400);
				break;
			case 24:
				result = Math.floor((process.uptime() % 86400) / 3600);
				break;
			case 25:
				result = Math.floor((process.uptime() % 3600) / 60);
				break;
			case 26:
				result = Math.round(process.uptime() % 60);
				break;
			case 27:
				result = Math.round((used * 100) / 100) + " MB";
				break;
			case 28:
				if(process.platform) {
					const platform = process.platform;
					if(platform === 'win32') result = 'Windows';
					else if(platform === 'win64') result = 'Windows';
					else if(platform === 'linux') result = 'Linux';
				}
				break;
			default:
			break;
		}
		if(result !== undefined) {
			const storage = parseInt(data.storage);
			const varName2 = this.evalMessage(data.varName2, cache);
			this.storeValue(result, storage, varName2, cache);
		}
		this.callNextAction(cache);
	},

	//---------------------------------------------------------------------
	// Action Bot Mod
	//
	// Upon initialization of the bot, this code is run. Using the bot's
	// DBM namespace, one can add/modify existing functions if necessary.
	// In order to reduce conflictions between mods, be sure to alias
	// functions you wish to overwrite.
	//---------------------------------------------------------------------

	mod: function(DBM) {
	}

	}; // End of module<commit_msg>Added "CPU Usage in MB" and "Bot's Directory"!<commit_after>module.exports = {

	//---------------------------------------------------------------------
	// Action Name
	//
	// This is the name of the action displayed in the editor.
	//---------------------------------------------------------------------

	name: "Store Bot Client Info",

	//---------------------------------------------------------------------
	// Action Section
	//
	// This is the section the action will fall into.
	//---------------------------------------------------------------------

	section: "Bot Client Control",

	//---------------------------------------------------------------------
	// Action Subtitle
	//
	// This function generates the subtitle displayed next to the name.
	//---------------------------------------------------------------------

	subtitle: function(data) {
	const info = ['Uptime in Milliseconds', 'Ready At?', 'Ping', 'Guild Amount', 'User Amount', 'Rounded Ping', 'Uptime in Seconds', 'Uptime in Minutes', 'Bot\'s Token', 'Voice Connections Amount', 'Total Amount of Channels', 'Total Amount of Emojis', 'Bot\'s Previous Pings', 'Uptime in Days', 'Uptime in Days (Rounded)', 'Memory (RAM) Usage', 'Bot Guilds Objects', 'Bot Guilds Names', 'Bot Guilds IDs', 'Bot Current Prefix', 'Bot Client ID', 'Discord JS Version', 'Uptime in Hours', 'Restarting Uptime in Days', 'Restarting Uptime in Hours', 'Restarting Uptime in Minutes', 'Restarting Uptime in Seconds', 'Memory (RAM) Usage in MB', 'Bot\'s OS (Process Platform)', 'CPU Usage in MB', 'Bot\'s Directory'];
		return `Bot Client - ${info[parseInt(data.info)]}`;
	},

	//---------------------------------------------------------------------
		 // DBM Mods Manager Variables (Optional but nice to have!)
		 //
		 // These are variables that DBM Mods Manager uses to show information
		 // about the mods for people to see in the list.
		 //---------------------------------------------------------------------

		 // Who made the mod (If not set, defaults to "DBM Mods")
		 author: "Lasse, EliteArtz and EGGSY",

		 // The version of the mod (Defaults to 1.0.0)
		 version: "1.8.5",

		 // A short description to show on the mod line for this mod (Must be on a single line)
		 short_description: "Stores Bot Information like Ping, Total Members or Guilds...",

		 // If it depends on any other mods by name, ex: WrexMODS if the mod uses something from WrexMods

		 //---------------------------------------------------------------------

	//---------------------------------------------------------------------
	// Action Storage Function
	//
	// Stores the relevant variable info for the editor.
	//---------------------------------------------------------------------

	variableStorage: function(data, varType) {
		const type = parseInt(data.storage);
		if(type !== varType) return;
		const info = parseInt(data.info);
		let dataType = 'Unknown Type';
		switch(info) {
			case 0:
				dataType = "Number";
				break;
			case 1:
				dataType = "Date";
				break;
			case 2:
				dataType = "Number";
				break;
			case 3:
				dataType = "Number";
				break;
			case 4:
				dataType = "Number";
				break;
			case 5:
				dataType = "Number";
				break;
			case 6:
				dataType = "Number";
				break;
			case 7:
				dataType = "Number";
				break;
			case 8:
				dataType = "Token";
				break;
			case 9:
				dataType = "Number";
				break;
			case 10:
				dataType = "Number";
				break;
			case 11:
				dataType = "Number";
				break;
			case 12:
				dataType = "Number";
				break;
			case 13:
				dataType = "Time";
				break;
			case 14:
				dataType = "Time";
				break;
			case 15:
				dataType = "Number";
				break;
			case 16:
				dataType = "Guild";
				break;
			case 17:
				dataType = "Guild Name";
				break;
			case 18:
				dataType = "Guild ID";
				break;
			case 19:
				dataType = "Bot Tag";
				break;
			case 20:
				dataType = "Bot ID";
				break;
			case 21:
				dataType = "Version Number";
				break;
			case 22:
				dataType = "Number";
				break;
			case 23:
				dataType = "Time";
				break;
			case 24:
				dataType = "Time";
				break;
			case 25:
				dataType = "Time";
				break;
			case 26:
				dataType = "Time";
				break;
			case 27:
				dataType = "Number";
				break;
			case 28:
				dataType = "OS Name";
				break;
			case 29:
				dataType = "Number";
				break;
			case 30:
				dataType = "Directory";
				break;
		}
		return ([data.varName2, dataType]);
	},

	//---------------------------------------------------------------------
	// Action Fields
	//
	// These are the fields for the action. These fields are customized
	// by creating elements with corresponding IDs in the HTML. These
	// are also the names of the fields stored in the action's JSON data.
	//---------------------------------------------------------------------

	fields: ["info", "storage", "varName2"],

	//---------------------------------------------------------------------
	// Command HTML
	//
	// This function returns a string containing the HTML used for
	// editting actions.
	//
	// The "isEvent" parameter will be true if this action is being used
	// for an event. Due to their nature, events lack certain information,
	// so edit the HTML to reflect this.
	//
	// The "data" parameter stores constants for select elements to use.
	// Each is an array: index 0 for commands, index 1 for events.
	// The names are: sendTargets, members, roles, channels,
	//                messages, servers, variables
	//---------------------------------------------------------------------

	html: function(isEvent, data) {
		return `

				Mod Info:

				Created by EliteArtz, EGGSY and Lasse!

		Source Info:

		<select id="info" class="round">
			<option value="0">Uptime in Milliseconds</option>
			<option value="1">Ready At</option>
			<option value="2">Ping</option>
			<option value="3">Total Amount of Guilds</option>
			<option value="4">Total Amount of Users</option>
			<option value="5">Rounded Ping</option>
			<option value="6">Uptime in Seconds</option>
			<option value="7">Uptime in Minutes</option>
			<option value="8">Bot's Token</option>
			<option value="9">Total Voice connections</option>
			<option value="10">Total Amount of Channels</option>
			<option value="11">Total Amount of Emojis</option>
			<option value="12">Bot's Previous Pings</option>
			<option value="13">Uptime in Days</option>
			<option value="14">Uptime in Days (Rounded)</option>
			<option value="15">Memory (RAM) Usage</option>
			<option value="16">Bot Guilds Objects</option>
			<option value="17">Bot Guilds Names</option>
			<option value="18">Bot Guilds IDs</option>
			<option value="19">Bot Current Prefix</option>
			<option value="20">Bot Client ID</option>
			<option value="21">Discord JS Version</option>
			<option value="22">Uptime in Hours</option>
			<option value="23">Restarting Uptime in Days</option>
			<option value="24">Restarting Uptime in Hours</option>
			<option value="25">Restarting Uptime in Minutes</option>
			<option value="26">Restarting Uptime in Seconds</option>
			<option value="27">Memory (RAM) Usage in MB</option>
			<option value="28">Bot's OS (Process Platform)</option>
			<option value="29">CPU Usage in MB</option>
			<option value="30">Bot's Directory</option>
		</select>

			Store In:

			<select id="storage" class="round">
				${data.variables[1]}
			</select>

			Variable Name:

			<input id="varName2" class="round" type="text">

`
	},

	//---------------------------------------------------------------------
	// Action Editor Init Code
	//
	// When the HTML is first applied to the action editor, this code
	// is also run. This helps add modifications or setup reactionary
	// functions for the DOM elements.
	//---------------------------------------------------------------------

	init: function() {
	},

	//---------------------------------------------------------------------
	// Action Bot Function
	//
	// This is the function for the action within the Bot's Action class.
	// Keep in mind event calls won't have access to the "msg" parameter,
	// so be sure to provide checks for variable existance.
	//---------------------------------------------------------------------

	action: function(cache) {
		const botClient = this.getDBM().Bot.bot;
		const dibiem = this.getDBM(); //EliteArtz... really???? Ugh you guys are meme
		const data = cache.actions[cache.index];
		const info = parseInt(data.info);
		const DiscordJS = dibiem.DiscordJS = require('discord.js'); // tf is dibiem
		const msToDay = (1000*60*60*24); // Really? Lasse? Did you really forget this? - :blobshh:
		const usedMEMORY = process.memoryUsage().heapUsed / 1024 / 1024; // Sorry about all const things but this is needed, you know.
		const usedCPU = process.cpuUsage().user / 1024 / 1024;
		if(!botClient) {
			this.callNextAction(cache);
			return;
		}
		switch(info) {
			case 0:
				result = botClient.uptime;
				break;
			case 1:
				result = botClient.readyAt;
				break;
			case 2:
				result = botClient.ping;
				break;
			case 3:
				result = botClient.guilds.array().length;
				break;
			case 4:
				result = botClient.users.array().length;
				break;
			case 5:
				result = Math.round(botClient.ping);
				break;
			case 6:
				result = Math.floor(botClient.uptime/1000);
				break;
			case 7:
				result = Math.floor(botClient.uptime/1000/60);
				break;
			case 8:
				result = botClient.token;
				break;
			case 9:
				result = botClient.voiceConnections.array().length;
				break;
			case 10:
				result = botClient.channels.size;
				break;
			case 11:
				result = botClient.emojis.size;
				break;
			case 12:
				result = botClient.pings;
				break;
			case 13:
				result = botClient.uptime/msToDay;
				break;
			case 14:
				result = Math.floor(botClient.uptime/msToDay);
				break;
			case 15:
				result = ((process.memoryUsage().heapUsed / 1024) / 1024).toFixed(2) + "%";
				break;
			case 16:
				result = botClient.guilds;
				break;
			case 17:
				result = botClient.guilds.array();
				break;
			case 18:
				result = botClient.guilds.map(guilds => guilds.id);
				break;
			case 19:
				result = dibiem.Files.data.settings.tag;
				break;
			case 20:
				result = dibiem.Files.data.settings.client;
				break;
			case 21:
				result = DiscordJS.version;
				break;
			case 22:
				result = Math.floor(botClient.uptime/1000/60/60);
				break;
			case 23:
				result = Math.floor((process.uptime() % 31536000) / 86400);
				break;
			case 24:
				result = Math.floor((process.uptime() % 86400) / 3600);
				break;
			case 25:
				result = Math.floor((process.uptime() % 3600) / 60);
				break;
			case 26:
				result = Math.round(process.uptime() % 60);
				break;
			case 27:
				result = Math.round((usedMEMORY * 100) / 100) + " MB";
				break;
			case 28:
				if(process.platform) {
					const platform = process.platform;
					if(platform === 'win32') result = 'Windows';
					else if(platform === 'aix') result = 'Aix';
					else if(platform === 'linux') result = 'Linux';
					else if(platform === 'darwin') result = 'Darwin';
					else if(platform === 'openbsd') result = 'OpenBSD';
					else if(platform === 'sunos') result = 'Solaris';
					else if(platform === 'freebsd') result = 'FreeBSD';
				}
				break;
			case 29:
				result = Math.round((usedCPU * 100) / 100) + " MB";
				break;
			case 30:
				result = process.cwd();
				break;
			default:
			break;
		}
		if(result !== undefined) {
			const storage = parseInt(data.storage);
			const varName2 = this.evalMessage(data.varName2, cache);
			this.storeValue(result, storage, varName2, cache);
		}
		this.callNextAction(cache);
	},

	//---------------------------------------------------------------------
	// Action Bot Mod
	//
	// Upon initialization of the bot, this code is run. Using the bot's
	// DBM namespace, one can add/modify existing functions if necessary.
	// In order to reduce conflictions between mods, be sure to alias
	// functions you wish to overwrite.
	//---------------------------------------------------------------------

	mod: function(DBM) {
	}

	}; // End of module<|endoftext|>


<commit_before>import * as utils from '../../utils';
import h from '../helper';
import { header as headerWidget, backButton, empty, pad} from '../shared/common';
import layout from '../layout';
import m from 'mithril';
import i18n from '../../i18n';
import isEmpty from 'lodash/lang/isEmpty';

export default function view(ctrl) {
  const headerCtrl = utils.partialf(headerWidget, null,
    backButton(ctrl.tournament().fullName)
  );
  const bodyCtrl = tournamentBody.bind(undefined, ctrl);

  return layout.free(headerCtrl, bodyCtrl, empty, empty);
}

function tournamentBody(ctrl) {
  let data = ctrl.tournament();
  if (isEmpty(data)) return null;

  let body = null;
  if (data.isFinished)
    body = tournamentContentFinished(data);
  else if (!data.isStarted)
    body = tournamentContentCreated(data);
  else
    body = tournamentContentStarted(data);

  return (m('.tournamentContainer', body));
}

function tournamentContentFinished(data) {
  return (

      { tournamentHeader(data, null, null)}
      { tournamentLeaderboard(data, true) }

  );
}

function tournamentContentCreated(data) {
  return (

      { tournamentHeader(data, data.secondsToStart, 'Starts in:')}
      { tournamentLeaderboard(data, false) }

  );
}

function tournamentContentStarted(data) {
  return (

      { tournamentHeader(data, data.secondsToFinish, '')}
      { tournamentLeaderboard(data, false) }
      { tournamentFeaturedGame(data) }

  );
}

function tournamentHeader(data, time, timeText) {
  let variant = variantInfo(data);
  let control = timeControl(data);
  return (

       {variant + ' • ' + control + ' • ' + data.minutes + 'M' }

         {timeInfo(time, timeText)}

  );
}

function variantInfo(data) {
  let variant = data.variant;
  if(variant === 'standard') {
    if(data.schedule)
      variant = data.schedule.speed;
    else if(data.position)
      variant = data.position.name;
    else
      variant = '';
  }

  variant = variant.split(' ')[0]; // Cut off names to first word

  if (variant.length > 0)
    variant = variant.charAt(0).toUpperCase() + variant.substring(1);

  return variant;
}

function timeControl(data) {
  let limit = (data.clock.limit / 60);
  if (data.clock.limit === 30)
    limit = '½';
  else if (data.clock.limit === 45)
    limit = '¾';
  return limit + '+' + data.clock.increment;
}

function timeInfo(time, preceedingText) {
  if (!time) return '';

  let timeStr = '';
  let hours = Math.floor(time / 60 / 60);
  let mins = Math.floor(time / 60) - (hours * 60);
  let secs = time % 60;
  if (hours > 0)
    timeStr = preceedingText + ' ' + hours + ':' + pad(mins, 2) + ':' + pad(secs, 2);
  else
    timeStr = preceedingText + ' ' + mins + ':' + pad(secs, 2);
  return timeStr;
}

function tournamentLeaderboard(data, showTrophies) {
  return (

 {i18n('leaderboard')} ({data.nbPlayers} Players)

        {data.standing.players.map(createLeaderboardItemRenderer(showTrophies))}

  );
}

function createLeaderboardItemRenderer(showTrophies) {
  function renderLeaderboardItem(player, index) {
    const podiumRank = index + 1;
    let trophy = '';
    if (showTrophies && podiumRank < 4) {
      trophy = 'trophy-' + podiumRank;
    }
    return (

        {player.name + ' (' + player.rating + ')'}
        {player.score}

    );
  }
  return renderLeaderboardItem;
}

function tournamentFeaturedGame(data) {
  return (

Featured Game

 m.route('/game/' + data.featured.id))}>
          {data.featured.white.name} ({data.featured.white.rating}) vs. {data.featured.black.name} ({data.featured.black.rating})

  );
}
<commit_msg>Check for featured game. Can be an issue on stage.lichess.org where tournaments are empty<commit_after>import * as utils from '../../utils';
import h from '../helper';
import { header as headerWidget, backButton, empty, pad} from '../shared/common';
import layout from '../layout';
import m from 'mithril';
import i18n from '../../i18n';
import isEmpty from 'lodash/lang/isEmpty';

export default function view(ctrl) {
  const headerCtrl = utils.partialf(headerWidget, null,
    backButton(ctrl.tournament().fullName)
  );
  const bodyCtrl = tournamentBody.bind(undefined, ctrl);

  return layout.free(headerCtrl, bodyCtrl, empty, empty);
}

function tournamentBody(ctrl) {
  let data = ctrl.tournament();
  if (isEmpty(data)) return null;

  let body = null;
  if (data.isFinished)
    body = tournamentContentFinished(data);
  else if (!data.isStarted)
    body = tournamentContentCreated(data);
  else
    body = tournamentContentStarted(data);

  return (m('.tournamentContainer', body));
}

function tournamentContentFinished(data) {
  return (

      { tournamentHeader(data, null, null)}
      { tournamentLeaderboard(data, true) }

  );
}

function tournamentContentCreated(data) {
  return (

      { tournamentHeader(data, data.secondsToStart, 'Starts in:')}
      { tournamentLeaderboard(data, false) }

  );
}

function tournamentContentStarted(data) {
  return (

      { tournamentHeader(data, data.secondsToFinish, '')}
      { tournamentLeaderboard(data, false) }
      { data.featured ? tournamentFeaturedGame(data) : '' }

  );
}

function tournamentHeader(data, time, timeText) {
  let variant = variantInfo(data);
  let control = timeControl(data);
  return (

       {variant + ' • ' + control + ' • ' + data.minutes + 'M' }

         {timeInfo(time, timeText)}

  );
}

function variantInfo(data) {
  let variant = data.variant;
  if(variant === 'standard') {
    if(data.schedule)
      variant = data.schedule.speed;
    else if(data.position)
      variant = data.position.name;
    else
      variant = '';
  }

  variant = variant.split(' ')[0]; // Cut off names to first word

  if (variant.length > 0)
    variant = variant.charAt(0).toUpperCase() + variant.substring(1);

  return variant;
}

function timeControl(data) {
  let limit = (data.clock.limit / 60);
  if (data.clock.limit === 30)
    limit = '½';
  else if (data.clock.limit === 45)
    limit = '¾';
  return limit + '+' + data.clock.increment;
}

function timeInfo(time, preceedingText) {
  if (!time) return '';

  let timeStr = '';
  let hours = Math.floor(time / 60 / 60);
  let mins = Math.floor(time / 60) - (hours * 60);
  let secs = time % 60;
  if (hours > 0)
    timeStr = preceedingText + ' ' + hours + ':' + pad(mins, 2) + ':' + pad(secs, 2);
  else
    timeStr = preceedingText + ' ' + mins + ':' + pad(secs, 2);
  return timeStr;
}

function tournamentLeaderboard(data, showTrophies) {
  return (

 {i18n('leaderboard')} ({data.nbPlayers} Players)

        {data.standing.players.map(createLeaderboardItemRenderer(showTrophies))}

  );
}

function createLeaderboardItemRenderer(showTrophies) {
  function renderLeaderboardItem(player, index) {
    const podiumRank = index + 1;
    let trophy = '';
    if (showTrophies && podiumRank < 4) {
      trophy = 'trophy-' + podiumRank;
    }
    return (

        {player.name + ' (' + player.rating + ')'}
        {player.score}

    );
  }
  return renderLeaderboardItem;
}

function tournamentFeaturedGame(data) {
  return (

Featured Game

 m.route('/game/' + data.featured.id))}>
          {data.featured.white.name} ({data.featured.white.rating}) vs. {data.featured.black.name} ({data.featured.black.rating})

  );
}
<|endoftext|>


<commit_before>import React, { Component, Children } from 'react';
import PropTypes from 'prop-types';
import { Link, withLang } from 'olymp';
import { withAuth } from 'olymp-auth';
import { Menu, Icon } from 'antd';
import { createComponent } from 'olymp-fela';
import { GatewayRegistry } from 'react-gateway';
import Gravatar from 'react-gravatar';

const getInitials = (name) => {
  if (name) {
    const array = name.split(' ');

    switch (array.length) {
      case 1:
        return array[0].charAt(0).toUpperCase();
      default:
        return (
          array[0].charAt(0).toUpperCase() +
          array[array.length - 1].charAt(0).toUpperCase()
        );
    }
  }

  return false;
};

const IconOnly = createComponent(
  ({ theme }) => ({
    marginRight: '0!important',
  }),
  Icon,
  p => Object.keys(p)
);

const UserIcon = createComponent(
  ({ theme, name }) => ({
    float: 'left',
    borderRadius: '50%',
    marginY: theme.space2,
    // marginRight: '0.75rem',
    background: `url(https://invatar0.appspot.com/svg/${getInitials(
      name
    )}.jpg?s=26&bg=${encodeURIComponent(
      theme.color
    )}&color=${encodeURIComponent(
      theme.light
    )}) center center no-repeat, ${theme.color}`,
  }),
  p => <Gravatar {...p} size={30} />,
  p => Object.keys(p)
);

const VerticalMenu = createComponent(
  ({ theme }) => ({
    zIndex: 3,
    // boxShadow: theme.boxShadow,
    // borderBottom: 0,
  }),
  Menu,
  p => Object.keys(p)
);

const RightMenuItem = createComponent(
  () => ({
    float: 'right!important',
  }),
  p => <Menu.Item {...p} />,
  p => Object.keys(p)
);

export default withLang(
  withAuth(
    ({
      auth,
      lang,
      className,
      deviceWidth,
      children,
      query,
      collectionList,
      ...rest
    }) =>
      (<GatewayDest
        component={VerticalMenu}
        mode="horizontal"
        className={className}
        deviceWidth={deviceWidth}
        selectedKeys={[
          ...Object.keys(query),
          ...Object.keys(query).map(x => query[x]),
        ]}
        name="navigation"
      >
        <Menu.Item key="plus">
          <Link to={{ query: { '@plus': null } }}>
            <IconOnly type="plus" />
          </Link>
        </Menu.Item>
        <Menu.Item key="@home">
          <Link to={{ query: { '@deviceWidth': deviceWidth } }}>
            <IconOnly type="home" />
          </Link>
        </Menu.Item>
        <Menu.Item key="@page">
          <Link to={{ query: { '@page': null, '@deviceWidth': deviceWidth } }}>
            <Icon type="edit" /> Seiten
          </Link>
        </Menu.Item>
        <Menu.Item key="@media">
          <Link to={{ query: { '@media': null } }}>
            <Icon type="picture" /> Medien
          </Link>
        </Menu.Item>
        <Menu.SubMenu
          title={

              <Icon type="file-text" /> Sammlungen

          }
        >
          {collectionList.map(collection =>
            (<Menu.Item key={`@${collection.name.toLowerCase()}`}>
              <Link
                to={{
                  query: {
                    [`@${collection.name.toLowerCase()}`]: null,
                  },
                }}
              >
                {collection.name}
              </Link>
            </Menu.Item>)
          )}
        </Menu.SubMenu>
        <Menu.Item key="@analytics">
          <Link to={{ query: { '@analytics': null } }}>
            <IconOnly type="line-chart" />
          </Link>
        </Menu.Item>
        <Menu.Item key="settings">
          <Link to={{ query: { '@settings': null } }}>
            <IconOnly type="setting" />
          </Link>
        </Menu.Item>
        {children}
        <RightMenuItem key="logout">

            <IconOnly type="poweroff" />

        </RightMenuItem>
        <RightMenuItem key="@user">
          <Link to={{ query: { '@user': null } }}>
            <UserIcon
              email={auth.user.email}
              name={auth.user.name}
              default="blank"
            />
            {/* auth.user.name */}
          </Link>
        </RightMenuItem>
      </GatewayDest>)
  )
);

/*
<Menu.Item key="@page">
  <Popover placement="bottom" content={lang.PAGE_MANAGER}>
    <Link
      to={{ query: { '@page': null, '@deviceWidth': deviceWidth } }}
    >
      <Icon type="home" />
    </Link>
  </Popover>
</Menu.Item>
<Menu.Item key="@template">
  <Popover placement="bottom" content="Template-Liste">
    <Link
      to={{ query: { '@template': null, '@deviceWidth': deviceWidth } }}
    >
      <Icon type="appstore-o" />
    </Link>
  </Popover>
</Menu.Item>
<Menu.Item key="@media">
  <Popover placement="bottom" content="Mediathek">
    <Link
      to={{ query: { '@media': null, '@deviceWidth': deviceWidth } }}
    >
      <Icon type="picture" />
    </Link>
  </Popover>
</Menu.Item>
{auth.user && auth.user.isAdmin
  ? <Menu.Item key="@users">
    <Popover placement="bottom" content="Benutzer-Management">
      <Link
        to={{
          query: { '@users': null, '@deviceWidth': deviceWidth },
        }}
      >
        <Icon type="team" />
      </Link>
    </Popover>
  </Menu.Item>
  : null}
<Menu.Item key="@stats">
  <Popover placement="bottom" content="Statistiken">
    <Link
      to={{ query: { '@stats': null, '@deviceWidth': deviceWidth } }}
    >
      <Icon type="line-chart" />
    </Link>
  </Popover>
</Menu.Item>
<Menu.Item key="@share">
  <Popover placement="bottom" content="Teilen">
    <Link
      to={{ query: { '@share': null, '@deviceWidth': deviceWidth } }}
    >
      <Icon type="share-alt" />
    </Link>
  </Popover>
</Menu.Item>
<Menu.Item key="@trash">
  <Popover placement="bottom" content="Papierkorb">
    <Link
      to={{ query: { '@trash': null, '@deviceWidth': deviceWidth } }}
    >
      <Icon type="delete" />
    </Link>
  </Popover>
</Menu.Item>

{collectionList.map(collection =>
  (<Menu.Item key={`@${collection.name.toLowerCase()}`}>
    <Popover placement="bottom" content={`@${collection.name}-Liste`}>
      <Link
        to={{
          query: {
            [`@${collection.name.toLowerCase()}`]: null,
            '@deviceWidth': deviceWidth,
          },
        }}
      >
        <Icon type="file-text" />
      </Link>
    </Popover>
  </Menu.Item>)
)}

<Menu.SubMenu title={<Icon type="laptop" />}>
  <Menu.Item key="@device-no">
    <Link to={{ query: { ...query, '@deviceWidth': undefined } }}>
      <Icon type="laptop" /> Normal
    </Link>
  </Menu.Item>
  <Menu.Item key="@deviceWidth700">
    <Link to={{ query: { ...query, '@deviceWidth': 700 } }}>
      <Icon type="tablet" /> Tablet
    </Link>
  </Menu.Item>
  <Menu.Item key="@deviceWidth400">
    <Link to={{ query: { ...query, '@deviceWidth': 400 } }}>
      <Icon type="phone" /> Mobil
    </Link>
  </Menu.Item>
</Menu.SubMenu>
<Menu.Item key="@user">
  <Popover placement="bottom" content="Profil">
    <Link
      to={{ query: { '@user': null, '@deviceWidth': deviceWidth } }}
    >
      <Icon type="user" />
    </Link>
  </Popover>
</Menu.Item>
<Menu.Item key="@settings">
  <Popover placement="bottom" content="Einstellungen">
    <Link
      to={{ query: { '@settings': null, '@deviceWidth': deviceWidth } }}
    >
      <Icon type="setting" />
    </Link>
  </Popover>
</Menu.Item>
<Separator />
<Menu.Item key="logoff" title="Abmelden">
  <Popover placement="bottom" content="Abmelden">

      <Icon type="poweroff" />

  </Popover>
</Menu.Item>

<Menu.Item key="save" title="Speichern">
  <Button onClick={auth.logout} href="javascript:;">
    Speichern
  </Button>
</Menu.Item>
*/

class GatewayDest extends Component {
  static contextTypes = {
    gatewayRegistry: PropTypes.instanceOf(GatewayRegistry).isRequired,
  };

  static propTypes = {
    name: PropTypes.string.isRequired,
    component: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
  };

  constructor(props, context) {
    super(props, context);
    this.gatewayRegistry = context.gatewayRegistry;
  }

  state = {
    children: null,
  };

  componentWillMount() {
    this.gatewayRegistry.addContainer(this.props.name, this);
  }

  componentWillUnmount() {
    this.gatewayRegistry.removeContainer(this.props.name, this);
  }

  render() {
    const { component, tagName, children, ...attrs } = this.props;
    delete attrs.name;
    return React.createElement(component || tagName || 'div', attrs, [
      children,
      Children.toArray(this.state.children).reverse(),
    ]);
  }
}
<commit_msg>color plus button in nav<commit_after>import React, { Component, Children } from 'react';
import PropTypes from 'prop-types';
import { Link, withLang } from 'olymp';
import { withAuth } from 'olymp-auth';
import { Menu, Icon, Button } from 'antd';
import { createComponent } from 'olymp-fela';
import { GatewayRegistry } from 'react-gateway';
import Gravatar from 'react-gravatar';

const getInitials = (name) => {
  if (name) {
    const array = name.split(' ');

    switch (array.length) {
      case 1:
        return array[0].charAt(0).toUpperCase();
      default:
        return (
          array[0].charAt(0).toUpperCase() +
          array[array.length - 1].charAt(0).toUpperCase()
        );
    }
  }

  return false;
};

const IconOnly = createComponent(
  ({ theme }) => ({
    marginRight: '0!important',
  }),
  Icon,
  p => Object.keys(p)
);
const RoundButton = createComponent(
  ({ theme }) => ({
    backgroundColor: theme.color,
    color: theme.light,
    borderColor: theme.color,
  }),
  Button,
  p => Object.keys(p)
);

const UserIcon = createComponent(
  ({ theme, name }) => ({
    float: 'left',
    borderRadius: '50%',
    marginY: theme.space2,
    // marginRight: '0.75rem',
    background: `url(https://invatar0.appspot.com/svg/${getInitials(
      name
    )}.jpg?s=26&bg=${encodeURIComponent(
      theme.color
    )}&color=${encodeURIComponent(
      theme.light
    )}) center center no-repeat, ${theme.color}`,
  }),
  p => <Gravatar {...p} size={30} />,
  p => Object.keys(p)
);

const VerticalMenu = createComponent(
  ({ theme }) => ({
    zIndex: 3,
    // boxShadow: theme.boxShadow,
    // borderBottom: 0,
  }),
  Menu,
  p => Object.keys(p)
);

const RightMenuItem = createComponent(
  () => ({
    float: 'right!important',
  }),
  p => <Menu.Item {...p} />,
  p => Object.keys(p)
);

export default withLang(
  withAuth(
    ({
      auth,
      lang,
      className,
      deviceWidth,
      children,
      query,
      collectionList,
      ...rest
    }) =>
      (<GatewayDest
        component={VerticalMenu}
        mode="horizontal"
        className={className}
        deviceWidth={deviceWidth}
        selectedKeys={[
          ...Object.keys(query),
          ...Object.keys(query).map(x => query[x]),
        ]}
        name="navigation"
      >
        <Menu.Item key="plus">
          <RoundButton shape="circle" icon="plus" />
        </Menu.Item>
        <Menu.Item key="@home">
          <Link to={{ query: { '@deviceWidth': deviceWidth } }}>
            <IconOnly type="home" />
          </Link>
        </Menu.Item>
        <Menu.Item key="@page">
          <Link to={{ query: { '@page': null, '@deviceWidth': deviceWidth } }}>
            <Icon type="edit" /> Seiten
          </Link>
        </Menu.Item>
        <Menu.Item key="@media">
          <Link to={{ query: { '@media': null } }}>
            <Icon type="picture" /> Medien
          </Link>
        </Menu.Item>
        <Menu.SubMenu
          title={

              <Icon type="file-text" /> Sammlungen

          }
        >
          {collectionList.map(collection =>
            (<Menu.Item key={`@${collection.name.toLowerCase()}`}>
              <Link
                to={{
                  query: {
                    [`@${collection.name.toLowerCase()}`]: null,
                  },
                }}
              >
                {collection.name}
              </Link>
            </Menu.Item>)
          )}
        </Menu.SubMenu>
        <Menu.Item key="@analytics">
          <Link to={{ query: { '@analytics': null } }}>
            <IconOnly type="line-chart" />
          </Link>
        </Menu.Item>
        <Menu.Item key="settings">
          <Link to={{ query: { '@settings': null } }}>
            <IconOnly type="setting" />
          </Link>
        </Menu.Item>
        {children}
        <RightMenuItem key="logout">

            <IconOnly type="poweroff" />

        </RightMenuItem>
        <RightMenuItem key="@user">
          <Link to={{ query: { '@user': null } }}>
            <UserIcon
              email={auth.user.email}
              name={auth.user.name}
              default="blank"
            />
            {/* auth.user.name */}
          </Link>
        </RightMenuItem>
      </GatewayDest>)
  )
);

/*
<Menu.Item key="@page">
  <Popover placement="bottom" content={lang.PAGE_MANAGER}>
    <Link
      to={{ query: { '@page': null, '@deviceWidth': deviceWidth } }}
    >
      <Icon type="home" />
    </Link>
  </Popover>
</Menu.Item>
<Menu.Item key="@template">
  <Popover placement="bottom" content="Template-Liste">
    <Link
      to={{ query: { '@template': null, '@deviceWidth': deviceWidth } }}
    >
      <Icon type="appstore-o" />
    </Link>
  </Popover>
</Menu.Item>
<Menu.Item key="@media">
  <Popover placement="bottom" content="Mediathek">
    <Link
      to={{ query: { '@media': null, '@deviceWidth': deviceWidth } }}
    >
      <Icon type="picture" />
    </Link>
  </Popover>
</Menu.Item>
{auth.user && auth.user.isAdmin
  ? <Menu.Item key="@users">
    <Popover placement="bottom" content="Benutzer-Management">
      <Link
        to={{
          query: { '@users': null, '@deviceWidth': deviceWidth },
        }}
      >
        <Icon type="team" />
      </Link>
    </Popover>
  </Menu.Item>
  : null}
<Menu.Item key="@stats">
  <Popover placement="bottom" content="Statistiken">
    <Link
      to={{ query: { '@stats': null, '@deviceWidth': deviceWidth } }}
    >
      <Icon type="line-chart" />
    </Link>
  </Popover>
</Menu.Item>
<Menu.Item key="@share">
  <Popover placement="bottom" content="Teilen">
    <Link
      to={{ query: { '@share': null, '@deviceWidth': deviceWidth } }}
    >
      <Icon type="share-alt" />
    </Link>
  </Popover>
</Menu.Item>
<Menu.Item key="@trash">
  <Popover placement="bottom" content="Papierkorb">
    <Link
      to={{ query: { '@trash': null, '@deviceWidth': deviceWidth } }}
    >
      <Icon type="delete" />
    </Link>
  </Popover>
</Menu.Item>

{collectionList.map(collection =>
  (<Menu.Item key={`@${collection.name.toLowerCase()}`}>
    <Popover placement="bottom" content={`@${collection.name}-Liste`}>
      <Link
        to={{
          query: {
            [`@${collection.name.toLowerCase()}`]: null,
            '@deviceWidth': deviceWidth,
          },
        }}
      >
        <Icon type="file-text" />
      </Link>
    </Popover>
  </Menu.Item>)
)}

<Menu.SubMenu title={<Icon type="laptop" />}>
  <Menu.Item key="@device-no">
    <Link to={{ query: { ...query, '@deviceWidth': undefined } }}>
      <Icon type="laptop" /> Normal
    </Link>
  </Menu.Item>
  <Menu.Item key="@deviceWidth700">
    <Link to={{ query: { ...query, '@deviceWidth': 700 } }}>
      <Icon type="tablet" /> Tablet
    </Link>
  </Menu.Item>
  <Menu.Item key="@deviceWidth400">
    <Link to={{ query: { ...query, '@deviceWidth': 400 } }}>
      <Icon type="phone" /> Mobil
    </Link>
  </Menu.Item>
</Menu.SubMenu>
<Menu.Item key="@user">
  <Popover placement="bottom" content="Profil">
    <Link
      to={{ query: { '@user': null, '@deviceWidth': deviceWidth } }}
    >
      <Icon type="user" />
    </Link>
  </Popover>
</Menu.Item>
<Menu.Item key="@settings">
  <Popover placement="bottom" content="Einstellungen">
    <Link
      to={{ query: { '@settings': null, '@deviceWidth': deviceWidth } }}
    >
      <Icon type="setting" />
    </Link>
  </Popover>
</Menu.Item>
<Separator />
<Menu.Item key="logoff" title="Abmelden">
  <Popover placement="bottom" content="Abmelden">

      <Icon type="poweroff" />

  </Popover>
</Menu.Item>

<Menu.Item key="save" title="Speichern">
  <Button onClick={auth.logout} href="javascript:;">
    Speichern
  </Button>
</Menu.Item>
*/

class GatewayDest extends Component {
  static contextTypes = {
    gatewayRegistry: PropTypes.instanceOf(GatewayRegistry).isRequired,
  };

  static propTypes = {
    name: PropTypes.string.isRequired,
    component: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
  };

  constructor(props, context) {
    super(props, context);
    this.gatewayRegistry = context.gatewayRegistry;
  }

  state = {
    children: null,
  };

  componentWillMount() {
    this.gatewayRegistry.addContainer(this.props.name, this);
  }

  componentWillUnmount() {
    this.gatewayRegistry.removeContainer(this.props.name, this);
  }

  render() {
    const { component, tagName, children, ...attrs } = this.props;
    delete attrs.name;
    return React.createElement(component || tagName || 'div', attrs, [
      children,
      Children.toArray(this.state.children).reverse(),
    ]);
  }
}
<|endoftext|>


<commit_before>const express = require('express');
const path = require('path');
const logger = require('morgan');
const errorHandler = require('errorhandler');
const expressStatusMonitor = require('express-status-monitor');
const expressValidator = require('express-validator');
const chalk = require('chalk');

/**
 * Set up controller
 */
const quiz1Controller = require('./controllers/quiz1');

/**
 * Set up express
 */
const app = express();
app.set('port', process.env.PORT || 1337);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
app.use(expressStatusMonitor());
app.use(logger('dev'));
app.use(expressValidator());

app.get('/', quiz1Controller.index);

/**
 * Error Handler.
 */
app.use(errorHandler());

/**
 * Start Express server.
 */
app.listen(app.get('port'), () => {
    console.log('%s App is running at http://localhost:%d in %s mode', chalk.green('✓'), app.get('port'), app.get('env'));

    console.log('  Press CTRL-C to stop\n');
});

module.exports = app;<commit_msg>Changes to app.js. Works with express now.<commit_after>const express = require('express');
const path = require('path');
const logger = require('morgan');
const errorHandler = require('errorhandler');
const expressStatusMonitor = require('express-status-monitor');
const expressValidator = require('express-validator');
const chalk = require('chalk');

/**
 * Set up controller
 */
const quiz1Controller = require('./controllers/quiz1');

/**
 * Set up express
 */
const app = express();
app.set('port', process.env.PORT || 1337);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
app.use(expressStatusMonitor());
app.use(logger('dev'));
app.use(expressValidator());

app.get('/', quiz1Controller.index);

/**
 * Error Handler.
 */
app.use(errorHandler());

/**
 * Start Express server.
 */
app.listen(app.get('port'), () => {
    console.log('%s App is running at http://localhost:%d in %s mode', chalk.green('✓'), app.get('port'), app.get('env'));

    console.log('  Press CTRL-C to stop\n');
});

module.exports = app;<|endoftext|>


<commit_before>import React from "react";
import GenericSystemConfig from "./Generic";
import gql from "graphql-tag";
import { Query, Mutation } from "react-apollo";
const SENSORS_QUERY = gql`
  query Sensors($id: ID!) {
    sensor(id: $id) {
      id
      history
    }
  }
`;
const Sensors = props => {
  const { id } = props;
  return (
    <GenericSystemConfig {...props}>
      <Query query={SENSORS_QUERY} variables={{ id }}>
        {({ data, loading }) => {
          if (loading) return null;
          const { history } = data.sensor;
          return (
            <label>
              <Mutation
                mutation={gql`
                  mutation SensorsHistory($id: ID!, $history: Boolean!) {
                    setSensorsHistory(id: $id, history: $history)
                  }
                `}
                refetchQueries={[{ query: SENSORS_QUERY, variables: { id } }]}
              >
                {action => (
                  <input
                    type="checkbox"
                    checked={history}
                    onChange={() =>
                      action({ variables: { id, history: !history } })
                    }
                  />
                )}
              </Mutation>
              Scanning History
            </label>
          );
        }}
      </Query>
    </GenericSystemConfig>
  );
};
export default Sensors;
<commit_msg>Pre-configure sensors auto-targeting.<commit_after>import React from "react";
import GenericSystemConfig from "./Generic";
import gql from "graphql-tag";
import { Query, Mutation } from "react-apollo";
const SENSORS_QUERY = gql`
  query Sensors($id: ID!) {
    sensor(id: $id) {
      id
      history
    }
  }
`;
const Sensors = props => {
  const { id } = props;
  return (
    <GenericSystemConfig {...props}>
      <Query query={SENSORS_QUERY} variables={{ id }}>
        {({ data, loading }) => {
          if (loading) return null;
          const { history, autoTarget } = data.sensor;
          return (
            <Fragment>
              <label>
                <Mutation
                  mutation={gql`
                    mutation SensorsHistory($id: ID!, $history: Boolean!) {
                      setSensorsHistory(id: $id, history: $history)
                    }
                  `}
                  refetchQueries={[{ query: SENSORS_QUERY, variables: { id } }]}
                >
                  {action => (
                    <input
                      type="checkbox"
                      checked={history}
                      onChange={() =>
                        action({ variables: { id, history: !history } })
                      }
                    />
                  )}
                </Mutation>
                Scanning History
              </label>
              <label>
                Auto-add to targeting{" "}
                <Mutation
                  mutation={gql`
                    mutation SensorsAutoTarget($id: ID!, $target: Boolean!) {
                      toggleSensorsAutoTarget(id: $id, target: $target)
                    }
                  `}
                >
                  {action => (
                    <input
                      type="checkbox"
                      checked={autoTarget}
                      onClick={e =>
                        action({ variables: { id, target: e.target.checked } })
                      }
                    />
                  )}
                </Mutation>
              </label>
            </Fragment>
          );
        }}
      </Query>
    </GenericSystemConfig>
  );
};

export default Sensors;
<|endoftext|>


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

var fs = require('fs'), strata
require('./proof')(1, function (serialize, tmp, equal, step, Strata, ok) {
    step(function () {
        serialize(__dirname + '/fixtures/get.json', tmp, step())
    }, function () {
        strata = new Strata({ directory: tmp, leafSize: 3, branchSize: 3 })
        strata.open(step())
    }, function () {
        strata.iterator(strata.key('a'), step())
    }, function (cursor) {
        step(function () {
            cursor.get(cursor.offset, step())
        }, function (got) {
            cursor.unlock()
            equal(got, 'a', 'got')
        })
    }, function () {
        strata.close(step())
    })
})
<commit_msg>Tidy `t/basics/key.t.js`.<commit_after>#!/usr/bin/env node

require('./proof')(1, function (step, Strata, tmp, serialize, equal, ok) {
    var strata
    step(function () {
        serialize(__dirname + '/fixtures/get.json', tmp, step())
    }, function () {
        strata = new Strata({ directory: tmp, leafSize: 3, branchSize: 3 })
        strata.open(step())
    }, function () {
        strata.iterator(strata.key('a'), step())
    }, function (cursor) {
        step(function () {
            cursor.get(cursor.offset, step())
        }, function (got) {
            cursor.unlock()
            equal(got, 'a', 'got')
        })
    }, function () {
        strata.close(step())
    })
})
<|endoftext|>


<commit_before>import _ from 'lodash';
import { createSelector } from 'reselect';
import { getGroupedDepsData } from '../../home/selectors/projectData';

// const nodeWidth(size) = 10;
// const padding(size) = 20;

const elementByIdSelector = state => state.elementById;
const sizeSelector = state => state.size;
const typesSelector = state => state.types;
const padding = size => Math.max(size / 15, 20);

const nodeWidth = size => Math.max(size / 40, 6);

const getPos = (node, size) => {
  const radius = size / 2 - padding(size) - nodeWidth(size) / 2;
  const angle = (node.startAngle + node.endAngle) / 2;
  const x = size / 2 + radius * Math.cos(angle);
  const y = size / 2 + radius * Math.sin(angle);
  return { x, y, angle };
};

const getLink = (source, target, size) => {
  const pos1 = getPos(source, size);
  const pos2 = getPos(target, size);
  const x1 = pos1.x;
  const y1 = pos1.y;
  const x2 = pos2.x;
  const y2 = pos2.y;

  const jx = (x1 + x2) / 2;
  const jy = (y1 + y2) / 2;

  // We need a and b to find theta, and we need to know the sign of each to make sure that the orientation is correct.
  const a = x2 - x1;
  const asign = a < 0 ? -1 : 1;
  const b = y2 - y1;

  const theta = Math.atan(b / a);

  // Find the point that's perpendicular to J on side
  const costheta = asign * Math.cos(theta);
  const sintheta = asign * Math.sin(theta);

  const radius = size / 2 - padding(size) - nodeWidth(size) / 2;
  let ang = Math.abs(pos1.angle - pos2.angle);
  if (ang > Math.PI) ang = 2 * Math.PI - ang;
  ang /= 2;
  const d1 = Math.abs(radius * Math.cos(ang));
  // const d2 = radius - d1;
  const d2 = radius * Math.sin(ang);

  let d = d1;
  if (d > d2 * 2) d = d2 * 2;
  let s = pos1.angle;
  let t = pos2.angle;
  if (Math.abs(s - t) > Math.PI) {
    if (s < t) s += 2 * Math.PI;
    else t += 2 * Math.PI;
  }
  const m = s < t ? d : -d;
  // if (source.angle - target.angle > Math.PI) d = -d;

  const m1 = m * sintheta;
  const m2 = m * costheta;

  // Use c and d to find cpx and cpy
  const cpx = jx - m1;
  const cpy = jy + m2;

  return { x1, y1, x2, y2, cpx, cpy, source, target };
};

const toShow = ele =>
  !ele.owner &&
  ele.type !== 'folder' &&
  ele.type !== 'folder-alias' &&
  (ele.type === 'file' || ele.parts || ele.target);

const ensureArray = (obj, name) => (obj[name] ? obj[name] : (obj[name] = []));

const getFeatures = eleById => {
  const byId = id => eleById[id];
  return Object.values(eleById)
    .filter(ele => ele.type === 'feature')
    .map(f => {
      const elements = {};
      const feature = {
        name: f.name,
        dir: f.target,
        elements,
      };
      const children = [...f.children];
      while (children.length) {
        const child = byId(children.pop());
        if (child.children) {
          children.push.apply(children, child.children);
        }
        if (toShow(child)) {
          ensureArray(elements, child.type).push(child);
        }
      }

      return feature;
    });
};

const getFeatureAngles = (features, featureGap) => {
  const totalAngle = 2*Math.PI - features.length * featureGap;
  const angles = {};
  let count = 0;
  features.forEach(f => {
    Object.keys(f.elements).forEach(type => {
      angles[type] = f.elements[type].length;
      count += f.elements[type].length;
    });
  });
  let start = 0;
  Object.keys(angles).forEach((type, index) => {
    const angle = angles[type] / count * totalAngle;
    start = start + featureGap + angle;
    angles[type] = {
      angle,
      start,
    }
  });
  return angles;
}

export const getDepsDiagramByFeatureData = createSelector(
  elementByIdSelector,
  getGroupedDepsData,
  sizeSelector,
  (elementById, deps, size) => {
    // All nodes should be in the deps diagram.
    // const eles = Object.values(elementById).filter(toShow);

    const features = getFeatures(elementById);
    // console.log('features');
    // return features;

    const eleCount = features.reduce(
      (count, f) => count + Object.values(f.elements).reduce((c, arr) => c + arr.length, 0),
      0
    );

    console.log(eleCount);
    const featureGap = (Math.PI * 2 / eleCount) * 0.4;
    const featureAngles = getFeatureAngles(features, featureGap);
    const avgAngle = (Math.PI * 2 - features.length * groupGap) / eleCount;

    const groups = _.groupBy(eles, 'type');
    Object.values(groups).forEach(arr => arr.sort((a, b) => a.name.localeCompare(b.name)));
    const groupTypes = Object.keys(groups);

    const groupGap = (Math.PI * 2 * 0.4) / eles.length;
    const avgAngle = (Math.PI * 2 - groupTypes.length * groupGap) / eles.length;
    const startAngleByType = {};
    let typeStartAngle = 0;
    let nodes = [];
    let groupNodes = [];
    const nodeById = {};
    groupTypes.forEach(type => {
      groupNodes.push({
        id: type,
        x: size / 2,
        y: size / 2,
        width: nodeWidth(size),
        startAngle: typeStartAngle,
        endAngle: typeStartAngle + groups[type].length * avgAngle,
        type,
        radius: size / 2 - padding(size),
        pieRadius: size / 2 - nodeWidth(size) / 2 - padding(size),
      });
      startAngleByType[type] = typeStartAngle;

      groups[type].forEach((ele, index) => {
        const len = groups[type].length;
        const groupAngle = avgAngle * len;
        // How eleAngle calculated? See below formula
        // len * eleAngle + (len + 1) * eleGap = groupAngle
        // eleGap = eleAngle * 20%
        // paddingAngle = eleAngle * 20%
        const eleAngle = groupAngle / (1.2 * len + 0.2);
        const eleGap = eleAngle * 0.2;
        const startAngle = typeStartAngle + eleGap + index * (eleGap + eleAngle);
        const n = {
          id: ele.id,
          name: ele.name,
          type: ele.type,
          x: size / 2,
          y: size / 2,
          width: nodeWidth(size),
          startAngle,
          endAngle: startAngle + eleAngle,
          radius: size / 2 - padding(size),
        };
        nodeById[n.id] = n;
        nodes.push(n);
      });
      typeStartAngle += groups[type].length * avgAngle + groupGap;
    });

    let links = [];
    eles.forEach(ele => {
      const eleDeps = deps.dependencies[ele.id] || [];
      eleDeps.forEach(dep => {
        const source = nodeById[ele.id];
        const target = nodeById[dep];
        links.push(getLink(source, target, size));
      });
    });

    nodes = _.uniqBy(nodes, 'id');
    links = _.uniqWith(links, _.isEqual);

    const nodeIdHash = nodes.reduce((h, n) => {
      h[n.id] = true;
      return h;
    }, {});
    links = links.filter(l => {
      if (!nodeIdHash[l.source.id])
        console.error(`getAllDepsDiagramData: Link source ${l.source} doesn't exist.`);
      else if (!nodeIdHash[l.target.id])
        console.error(`getAllDepsDiagramData: Link target ${l.target} doesn't exist.`);
      else return true;
      return false;
    });

    return { nodes, links, groups: groupNodes, depsData: deps };
  }
);
<commit_msg>Common nodes calculation for feature diagram.<commit_after>import _ from 'lodash';
import { createSelector } from 'reselect';
import { getGroupedDepsData } from '../../home/selectors/projectData';

// const nodeWidth(size) = 10;
// const padding(size) = 20;

const elementByIdSelector = state => state.elementById;
const sizeSelector = state => state.size;
const typesSelector = state => state.types;
const padding = size => Math.max(size / 15, 20);

const nodeWidth = size => Math.max(size / 40, 6);

const getPos = (node, size) => {
  const radius = size / 2 - padding(size) - nodeWidth(size) / 2;
  const angle = (node.startAngle + node.endAngle) / 2;
  const x = size / 2 + radius * Math.cos(angle);
  const y = size / 2 + radius * Math.sin(angle);
  return { x, y, angle };
};

const getLink = (source, target, size) => {
  const pos1 = getPos(source, size);
  const pos2 = getPos(target, size);
  const x1 = pos1.x;
  const y1 = pos1.y;
  const x2 = pos2.x;
  const y2 = pos2.y;

  const jx = (x1 + x2) / 2;
  const jy = (y1 + y2) / 2;

  // We need a and b to find theta, and we need to know the sign of each to make sure that the orientation is correct.
  const a = x2 - x1;
  const asign = a < 0 ? -1 : 1;
  const b = y2 - y1;

  const theta = Math.atan(b / a);

  // Find the point that's perpendicular to J on side
  const costheta = asign * Math.cos(theta);
  const sintheta = asign * Math.sin(theta);

  const radius = size / 2 - padding(size) - nodeWidth(size) / 2;
  let ang = Math.abs(pos1.angle - pos2.angle);
  if (ang > Math.PI) ang = 2 * Math.PI - ang;
  ang /= 2;
  const d1 = Math.abs(radius * Math.cos(ang));
  // const d2 = radius - d1;
  const d2 = radius * Math.sin(ang);

  let d = d1;
  if (d > d2 * 2) d = d2 * 2;
  let s = pos1.angle;
  let t = pos2.angle;
  if (Math.abs(s - t) > Math.PI) {
    if (s < t) s += 2 * Math.PI;
    else t += 2 * Math.PI;
  }
  const m = s < t ? d : -d;
  // if (source.angle - target.angle > Math.PI) d = -d;

  const m1 = m * sintheta;
  const m2 = m * costheta;

  // Use c and d to find cpx and cpy
  const cpx = jx - m1;
  const cpy = jy + m2;

  return { x1, y1, x2, y2, cpx, cpy, source, target };
};

const toShow = ele =>
  !ele.owner &&
  ele.type !== 'folder' &&
  ele.type !== 'folder-alias' &&
  (ele.type === 'file' || ele.parts || ele.target);

const ensureArray = (obj, name) => (obj[name] ? obj[name] : (obj[name] = []));

const calcAngles = (eles, containerStart, containerAngle, gapRate, isCircle) => {
  // avgAngle * count + gap * gapCount = containerAngle
  // gap = avgAngle * gapRate
  // gapCount = isCircle ? count + 1 : count;
  const count = eles.length;
  const gapCount = isCircle ? count + 1 : count;
  const gap = containerAngle / (count / gapRate + gapCount);
  const leftAngle = containerAngle - gap * gapCount;
  let start = containerStart;
  const total = eles.reduce((p, c) => p + c.weight, 0);
  return eles.map((ele, index) => {
    const angle = (ele.weight / total) * leftAngle;
    const res = {
      start,
      angle,
    };
    start = start + angle + gap;
    return res;
  });
};

const getFeatures = eleById => {
  const byId = id => eleById[id];
  return Object.values(eleById)
    .filter(ele => ele.type === 'feature')
    .map(f => {
      const elements = {};
      const feature = {
        id: f.id,
        name: f.name,
        dir: f.target,
        type: 'feature',
        elements,
      };
      const children = [...f.children];
      while (children.length) {
        const child = byId(children.pop());
        if (child.children) {
          children.push.apply(children, child.children);
        }
        if (toShow(child)) {
          ensureArray(elements, child.type).push(child);
        }
      }
      feature.weight = getFeatureEleCount({ elements });

      return feature;
    });
};

const getFeatureEleCount = f => {
  return Object.values(f.elements).reduce((c, arr) => c + arr.length, 0);
};

// const getFeatureAngles = (features, featureGap) => {
//   const totalAngle = 2 * Math.PI - features.length * featureGap;
//   const angles = {};
//   let count = 0;
//   features.forEach(f => {
//     Object.keys(f.elements).forEach(type => {
//       angles[type] = f.elements[type].length;
//       count += f.elements[type].length;
//     });
//   });
//   let start = 0;
//   Object.keys(angles).forEach((type, index) => {
//     const angle = (angles[type] / count) * totalAngle;
//     start = start + featureGap + angle;
//     angles[type] = {
//       angle,
//       start,
//     };
//   });
//   return angles;
// };

// const getFeatureElementAngles = (feature, start, angle) => {
//   const angles = {};
//   const count = getFeatureEleCount(feature);
//   const typesCount = Object.keys(feature.elements).length;
//   // eleAngle + (typesCount - 1) * gap = angle
//   // gap = eleAngle * 0.2
//   // => eleAngle + (typesCount - 1) * eleAngle * 0.2 = angle
//   // => eleAngle = angle / (0.8 + 0.2 * typesCount)
//   const eleAngle = angle / (0.8 + 0.2 * typesCount);
//   const gap = eleAngle * 0.2;

//   return {
//     angle: eleAngle,
//     gap,
//   };
// };

const getNode = (ele, index, angles, radius, width) => {
  const angle = angles[index];
  return {
    id: ele.id,
    name: ele.name,
    type: ele.type,
    radius,
    width,
    startAngle: angle.start,
    endAngle: angle.start + angle.angle,
  };
};

export const getDepsDiagramByFeatureData = createSelector(
  elementByIdSelector,
  getGroupedDepsData,
  sizeSelector,
  (elementById, deps, size) => {
    // All nodes should be in the deps diagram.
    // const eles = Object.values(elementById).filter(toShow);
    const byId = id => elementById[id];
    const nodes = [];
    const features = getFeatures(elementById);
    const angles = calcAngles(features, 0, Math.PI * 2, 0.1, true);
    // nodes.push.apply(nodes, getNodes(features, angles));

    features.forEach((f, index) => {
      const n = getNode(f, index, angles, 100, 5);
      nodes.push(n);
      const types = Object.keys(f.elements).map(k => ({
        id: `${f.id}-${k}-container`,
        type: `v:container-${k}`,
        name: k,
        weight: f.elements[k].length,
      }));
      const angles2 = calcAngles(types, n.startAngle, n.endAngle - n.startAngle, 0.2, false);
      types.forEach((type, index2) => {
        const n2 = getNode(type, index2, angles2, 94, 5);
        nodes.push(n2);
        console.log(f, type, f.name);
        const eles = f.elements[type.name].map(ele => ({
          id: ele.id,
          type: ele.type,
          name: ele.name,
          weight: 1,
        }));
        const angles3 = calcAngles(eles, n2.startAngle, n2.endAngle - n2.startAngle, 0.2, false);
        eles.forEach((ele, index3) => {
          const n3 = getNode(ele, index3, angles3, 94, 5);
          nodes.push(n3);
        });

      });
    });
    console.log('nodes: ', nodes);

    return { nodes };

    // console.log('features');
    // return features;

    // const eleCount = features.reduce(
    //   (count, f) => count + Object.values(f.elements).reduce((c, arr) => c + arr.length, 0),
    //   0
    // );

    // console.log(eleCount);
    // const featureGap = ((Math.PI * 2) / eleCount) * 0.4;
    // const featureAngles = getFeatureAngles(features, featureGap);
    // const avgAngle = (Math.PI * 2 - features.length * groupGap) / eleCount;

    // const groups = _.groupBy(eles, 'type');
    // Object.values(groups).forEach(arr => arr.sort((a, b) => a.name.localeCompare(b.name)));
    // const groupTypes = Object.keys(groups);

    // const groupGap = (Math.PI * 2 * 0.4) / eles.length;
    // const avgAngle = (Math.PI * 2 - groupTypes.length * groupGap) / eles.length;
    // const startAngleByType = {};
    // let typeStartAngle = 0;
    // let nodes = [];
    // let groupNodes = [];
    // const nodeById = {};
    // groupTypes.forEach(type => {
    //   groupNodes.push({
    //     id: type,
    //     x: size / 2,
    //     y: size / 2,
    //     width: nodeWidth(size),
    //     startAngle: typeStartAngle,
    //     endAngle: typeStartAngle + groups[type].length * avgAngle,
    //     type,
    //     radius: size / 2 - padding(size),
    //     pieRadius: size / 2 - nodeWidth(size) / 2 - padding(size),
    //   });
    //   startAngleByType[type] = typeStartAngle;

    //   groups[type].forEach((ele, index) => {
    //     const len = groups[type].length;
    //     const groupAngle = avgAngle * len;
    //     // How eleAngle calculated? See below formula
    //     // len * eleAngle + (len + 1) * eleGap = groupAngle
    //     // eleGap = eleAngle * 20%
    //     // paddingAngle = eleAngle * 20%
    //     const eleAngle = groupAngle / (1.2 * len + 0.2);
    //     const eleGap = eleAngle * 0.2;
    //     const startAngle = typeStartAngle + eleGap + index * (eleGap + eleAngle);
    //     const n = {
    //       id: ele.id,
    //       name: ele.name,
    //       type: ele.type,
    //       x: size / 2,
    //       y: size / 2,
    //       width: nodeWidth(size),
    //       startAngle,
    //       endAngle: startAngle + eleAngle,
    //       radius: size / 2 - padding(size),
    //     };
    //     nodeById[n.id] = n;
    //     nodes.push(n);
    //   });
    //   typeStartAngle += groups[type].length * avgAngle + groupGap;
    // });

    // let links = [];
    // eles.forEach(ele => {
    //   const eleDeps = deps.dependencies[ele.id] || [];
    //   eleDeps.forEach(dep => {
    //     const source = nodeById[ele.id];
    //     const target = nodeById[dep];
    //     links.push(getLink(source, target, size));
    //   });
    // });

    // nodes = _.uniqBy(nodes, 'id');
    // links = _.uniqWith(links, _.isEqual);

    // const nodeIdHash = nodes.reduce((h, n) => {
    //   h[n.id] = true;
    //   return h;
    // }, {});
    // links = links.filter(l => {
    //   if (!nodeIdHash[l.source.id])
    //     console.error(`getAllDepsDiagramData: Link source ${l.source} doesn't exist.`);
    //   else if (!nodeIdHash[l.target.id])
    //     console.error(`getAllDepsDiagramData: Link target ${l.target} doesn't exist.`);
    //   else return true;
    //   return false;
    // });

    // return { nodes, links, groups: groupNodes, depsData: deps };
  }
);
<|endoftext|>


<commit_before>import baseScale from '../scale/base';
import programBuilder from '../program/programBuilder';
import drawModes from '../program/drawModes';
import areaShader from '../shaders/area/shader';
import { rebind } from '@d3fc/d3fc-rebind';
import attribute from '../buffer/attribute';
import elementIndices from '../buffer/elementIndices';
import types from '../buffer/types';
import rebindCurry from '../rebindCurry';

export default () => {
    const program = programBuilder()
        .mode(drawModes.TRIANGLES)
        .subInstanceCount(6);
    let xScale = baseScale();
    let yScale = baseScale();
    let decorate = () => {};

    const cornerAttribute = attribute()
        .divisor(0)
        .size(3)
        .type(types.UNSIGNED_BYTE)
        .data([
            [0, 0, 0],
            [0, 1, 0],
            [1, 1, 1],
            [0, 0, 1],
            [1, 0, 0],
            [1, 1, 0]
        ]);

    program
        .buffers()
        .elementIndices(elementIndices([0, 1, 2, 3, 4, 5]))
        .attribute('aCorner', cornerAttribute);

    const draw = numElements => {
        const shaderBuilder = areaShader();
        program
            .vertexShader(shaderBuilder.vertex())
            .fragmentShader(shaderBuilder.fragment());

        xScale(program, 'gl_Position', 0);
        yScale(program, 'gl_Position', 1);

        decorate(program);

        program(numElements - 1);
    };

    draw.decorate = (...args) => {
        if (!args.length) {
            return decorate;
        }
        decorate = args[0];
        return draw;
    };

    draw.xScale = (...args) => {
        if (!args.length) {
            return xScale;
        }
        xScale = args[0];
        return draw;
    };

    draw.yScale = (...args) => {
        if (!args.length) {
            return yScale;
        }
        yScale = args[0];
        return draw;
    };

    rebind(draw, program, 'context');
    rebindCurry(
        draw,
        'crossValueAttribute',
        program.buffers(),
        'attribute',
        'aCrossValue'
    );
    rebindCurry(
        draw,
        'crossNextValueAttribute',
        program.buffers(),
        'attribute',
        'aCrossNextValue'
    );
    rebindCurry(
        draw,
        'mainValueAttribute',
        program.buffers(),
        'attribute',
        'aMainValue'
    );
    rebindCurry(
        draw,
        'mainNextValueAttribute',
        program.buffers(),
        'attribute',
        'aMainNextValue'
    );
    rebindCurry(
        draw,
        'baseValueAttribute',
        program.buffers(),
        'attribute',
        'aBaseValue'
    );
    rebindCurry(
        draw,
        'baseNextValueAttribute',
        program.buffers(),
        'attribute',
        'aBaseNextValue'
    );
    rebindCurry(
        draw,
        'definedAttribute',
        program.buffers(),
        'attribute',
        'aDefined'
    );
    rebindCurry(
        draw,
        'definedNextAttribute',
        program.buffers(),
        'attribute',
        'aDefinedNext'
    );

    return draw;
};
<commit_msg>refactor: use array-based rendering for area<commit_after>import baseScale from '../scale/base';
import programBuilder from '../program/programBuilder';
import drawModes from '../program/drawModes';
import areaShader from '../shaders/area/shader';
import { rebind } from '@d3fc/d3fc-rebind';
import attribute from '../buffer/attribute';
import types from '../buffer/types';
import rebindCurry from '../rebindCurry';

export default () => {
    const program = programBuilder()
        .mode(drawModes.TRIANGLES)
        .subInstanceCount(6);
    let xScale = baseScale();
    let yScale = baseScale();
    let decorate = () => {};

    const cornerAttribute = attribute()
        .divisor(0)
        .size(3)
        .type(types.UNSIGNED_BYTE)
        .data([
            [0, 0, 0],
            [0, 1, 0],
            [1, 1, 1],
            [0, 0, 1],
            [1, 0, 0],
            [1, 1, 0]
        ]);

    program.buffers().attribute('aCorner', cornerAttribute);

    const draw = numElements => {
        const shaderBuilder = areaShader();
        program
            .vertexShader(shaderBuilder.vertex())
            .fragmentShader(shaderBuilder.fragment());

        xScale(program, 'gl_Position', 0);
        yScale(program, 'gl_Position', 1);

        decorate(program);

        program(numElements - 1);
    };

    draw.decorate = (...args) => {
        if (!args.length) {
            return decorate;
        }
        decorate = args[0];
        return draw;
    };

    draw.xScale = (...args) => {
        if (!args.length) {
            return xScale;
        }
        xScale = args[0];
        return draw;
    };

    draw.yScale = (...args) => {
        if (!args.length) {
            return yScale;
        }
        yScale = args[0];
        return draw;
    };

    rebind(draw, program, 'context');
    rebindCurry(
        draw,
        'crossValueAttribute',
        program.buffers(),
        'attribute',
        'aCrossValue'
    );
    rebindCurry(
        draw,
        'crossNextValueAttribute',
        program.buffers(),
        'attribute',
        'aCrossNextValue'
    );
    rebindCurry(
        draw,
        'mainValueAttribute',
        program.buffers(),
        'attribute',
        'aMainValue'
    );
    rebindCurry(
        draw,
        'mainNextValueAttribute',
        program.buffers(),
        'attribute',
        'aMainNextValue'
    );
    rebindCurry(
        draw,
        'baseValueAttribute',
        program.buffers(),
        'attribute',
        'aBaseValue'
    );
    rebindCurry(
        draw,
        'baseNextValueAttribute',
        program.buffers(),
        'attribute',
        'aBaseNextValue'
    );
    rebindCurry(
        draw,
        'definedAttribute',
        program.buffers(),
        'attribute',
        'aDefined'
    );
    rebindCurry(
        draw,
        'definedNextAttribute',
        program.buffers(),
        'attribute',
        'aDefinedNext'
    );

    return draw;
};
<|endoftext|>


<commit_before>import { SAGA_LOCATION as _SAGA_LOCATION } from "redux-saga";

function* test1() {
  yield function reduxSagaSource() {
    var res = foo(1, 2, 3);
    res[_SAGA_LOCATION] = {
      fileName: "test/fixtures/base-path/source.js",
      lineNumber: 2,
      code: "foo(1, 2, 3)"
    };
    return res;
  }();
}

test1[_SAGA_LOCATION] = {
  fileName: "test/fixtures/base-path/source.js",
  lineNumber: 1
};

function* test2() {
  yield 2;
}

test2[_SAGA_LOCATION] = {
  fileName: "test/fixtures/base-path/source.js",
  lineNumber: 5
};
<commit_msg>use nodejs require<commit_after>var _SAGA_LOCATION = require("redux-saga").SAGA_LOCATION;

function* test1() {
  yield function reduxSagaSource() {
    var res = foo(1, 2, 3);
    res[_SAGA_LOCATION] = {
      fileName: "test/fixtures/base-path/source.js",
      lineNumber: 2,
      code: "foo(1, 2, 3)"
    };
    return res;
  }();
}

test1[_SAGA_LOCATION] = {
  fileName: "test/fixtures/base-path/source.js",
  lineNumber: 1
};

function* test2() {
  yield 2;
}

test2[_SAGA_LOCATION] = {
  fileName: "test/fixtures/base-path/source.js",
  lineNumber: 5
};
<|endoftext|>