<commit_before>/**
* provides general window funtionality like close/resize for windows (browser, folder)
*/
FrameWindow = function(frameClass,headerClass){

	this.windowFunctionality = true;

	/**
	* initializes frame with functionality close/resize/drag/fullscreen dependent on given <params>
	*/
	this.initializeFrame = function(params){

		this.params = params;

		var frame = this;
//		this.addClass("frame passiveFrame");
		this.addClass("frame");
		this.addClass(frameClass);
		this.visibility = true;

		this.toolbarDiv = $("
").appendTo(this);
		this.toolbarDiv.addClass(headerClass);

		this.windowTools = $("
").appendTo(this.toolbarDiv);
		var headline = $("
").appendTo(this.toolbarDiv);
		this.label = $("").appendTo(headline);

		this.content = $("
").appendTo(this);
		$(this.content).css('position','relative');
		$(this.content).mousedown(function(){
			frame.updateZIndex(false);
		});

		this.dragLock = false;
		if( params.draggable ){
			this.mousedown(function(evt){
				if( frame.windowFunctionality ){
					frame.dragFrame(evt);
				}
			});
			$(this.content).bind('mousedown',function(e){
				e.stopPropagation();
			});
		}

		if( params.concealable ){
			this.visibilityButton = $("
").appendTo(this.windowTools);
			this.visibilityLink = $(' ').appendTo(this.visibilityButton);
			this.visibilityLink.attr("title",Util.getString('minimizeWindow'));
			this.visibilityButton.click(function(){
				frame.toggleVisibility();
			});
		}

		if( params.removable ){
			this.removeButton = $("
").appendTo(this.windowTools);
			var removeLink = $('').appendTo(this.removeButton);
//			$('').appendTo(removeLink);
			removeLink.attr("title",Util.getString('removeWindow'));
			this.removeButton.click(function(){
				frame.toolbarDiv.remove();
				if( typeof params.triggerRemove != 'undefined' ){
					params.triggerRemove();
				}
				a18Gui.checkGrid();
				$(frame).remove();
			});
		}

/*		if( params.fullscreen ){
			var fullscreenLi = $('
').appendTo(this.windowTools);
			var fullscreen = $('').appendTo(fullscreenLi);
			fullscreen.attr('title',Util.getString('fullscreenMode'));
			var maximized = false;
			var w, h, l, t;
			fullscreen.click(function(){
				maximized = !maximized;
				var width, height, left, top;
				if( maximized ){
					w = $(frame).width();
					h = $(frame).height();
					t = $(frame).position().top;
					l = $(frame).position().left;
					var marginGap = a18Props.margin;
					width = $(a18Gui.containerDiv).width()-2*marginGap;
					height = $(a18Gui.containerDiv).height()-2*marginGap;
					left = marginGap;
					top = marginGap;
				}
				else {
					width = w;
					height = h;
					left = l;
					top = t;
				}
				frame.position(left,top);
				frame.setSize(width,height);
				frame.resize();
				frame.resizeContent();
			});

		}
*/
		this.updateZIndex(true);

		$(this).mousedown(function(){
			frame.updateZIndex(false);
		});

	};

	/**
	* updates z-index of frame, so that a selected frame is always completely visible
	*/
	this.updateZIndex = function(set){
		if( !set ){
			var zIndex = $(this).css('z-index');
			if( a18Gui.zIndex != zIndex ){
				set = true;
			}
		}
		if( set ){
			var z = a18Gui.getZIndex();
			$(this).css('z-index',z);
			if( typeof a18Gui.activeWindow != 'undefined' ){
//				a18Gui.activeWindow.removeClass('activeFrame');
//				a18Gui.activeWindow.addClass('passiveFrame');
			}
			a18Gui.activeWindow = this;
//			a18Gui.activeWindow.removeClass('passiveFrame');
//			a18Gui.activeWindow.addClass('activeFrame');
		}
	};

	/**
	* sets window functionality if there are constraints from automatic grid layout
	*/
	this.setWindowFunctionality = function(windowFunctionality){
		this.windowFunctionality = windowFunctionality;
		this.setResizability(this.windowFunctionality);
	};

	/**
	* sets resizability of the frame
	*/
	this.setResizability = function(append){
		var frame = this;
		if( this.params.resizable && append && this.windowFunctionality && this.visibility ){
			$(this).resizable({
				helper: "ui-resizable-helper",
				minHeight: a18Props.minWindowHeight,
				minWidth: a18Props.minWindowWidth,
				/*
				resize: function() {
					frame.resize();
				},
				*/
				stop: function() {
					frame.resize();
					if( typeof frame.params.triggerResize != 'undefined' ){
						frame.params.triggerResize();
					}
				}
			});
			var resizeHandles = $('.ui-resizable-handle',frame);
			for( var i=0; i<resizeHandles.length; i++ ){
				$(resizeHandles[i]).mousedown(function(){
					frame.dragLock = true;
					$(document).mousemove(function(){
						a18Gui.checkHeight();
					});
				});
				$(resizeHandles[i]).mouseup(function(){
					$(document).mousemove(null);
					frame.dragLock = false;
				});
			}
		}
		else if( this.params.resizable ){
			$(this).resizable('destroy');
		}
	};

	/**
	* sets size of the frame
	*/
	this.setSize = function(width,height){
		this.css('width', width+"px" );
		this.css('height',height+'px');
	};

	/**
	* resizes the frame
	*/
	this.resize = function(){
		//this.toolbarDiv.css('width',($(this).width())+'px');
	//	$(this.label).css('margin',Math.floor((this.toolbarDiv.height()-this.label.height())/2)+'px');
		var p = parseInt($(this).css("padding-top"))*2-4;
//		this.content.css('width', ($(this).width()-p)+"px");
		this.content.css('height', ($(this).height()-p-this.toolbarDiv.height())+"px");
	};

	/**
	* places the frame
	*/
	this.position = function(left,top){
		this.css('left',left+'px');
		this.css('top',top+'px');
	};

	/**
	* return a frames' position
	*/
	this.getPosition = function(){
		if( this.visibility ){
			return {
				t: $(this).position().top,
				l: $(this).position().left,
				w: $(this).width(),
				h: $(this).height()
			};
		}
		return {
			t: this.top,
			l: this.left,
			w: this.width,
			h: this.height
		};
	};

	/**
	* arranges minimize/maximize functionality
	*/
	this.toggleVisibility = function(){
		var frame = this;
		var padding = parseInt($(this).css("padding-top"));
		this.visibility = !this.visibility;
		if( this.visibility ){
			this.visibilityLink.removeClass("button-open");
			this.visibilityLink.addClass("button-minimize");
			$(this).animate({
				height: "-="+($(frame).height()-frame.height),
				top: "-="+($(frame).position().top-frame.top),
				left: "-="+($(frame).position().left-frame.left),
				width: "-="+($(frame).width()-frame.width)
			  }, 500, function(){
					frame.resize();
					a18Gui.checkGrid();
					a18Gui.checkHeight();
			});
			this.setResizability(true);
		}
		else {
			this.top = $(this).position().top;
			this.left = $(this).position().left;
			this.width = $(this).width();
			this.height = $(this).height();
			this.visibilityLink.removeClass("button-minimize");
			this.visibilityLink.addClass("button-open");
			$(this).animate({
				height: "-="+($(frame).height()-$(frame.toolbarDiv).height()+5),
				top: "-="+(frame.top-10),
				left: "+="+(frame.width/2-(frame.label.width()+frame.windowTools.width()+20)/2),
			    	width: "-="+($(frame).width()-frame.label.width()-frame.windowTools.width()-20)
			  }, 500, function(){
					frame.resize();
					a18Gui.checkGrid();
					a18Gui.checkHeight();
			});
			this.setResizability(false);
		}
	};

	/**
	* set label (old design)
	*/
	this.setLabel = function(label){
		$(this.label).html(label);
		//$(this.label).css('margin',Math.floor((this.toolbarDiv.height()-this.label.height())/2)+'px');
	};

	/**
	* perfoms drag functionality for frame
	*/
	this.dragFrame = function(evt){
		var frame = this;
		var getMousePosition = function(e){
			if(!e){
		    	e = window.event;
			}
		    var body = (window.document.compatMode && window.document.compatMode == "CSS1Compat") ? window.document.documentElement : window.document.body;
		    return {
		    	top: e.pageY ? e.pageY : e.clientY,
		        left: e.pageX ? e.pageX : e.clientX
		    };
		}
		var startPos = getMousePosition(evt);
		var windowLeft = $(frame).position().left;
		var windowTop = $(frame).position().top;
		document.onmouseup = function(){
			document.onmousemove = null;
			document.onmouseup = null;
		}
		document.onmousemove = function(e){
			if( !frame.dragLock ){
				var pos = getMousePosition(e);
				frame.css('left',(windowLeft+pos.left-startPos.left)+'px');
				frame.css('top',(windowTop+pos.top-startPos.top)+'px');
				a18Gui.checkHeight();
			}
		}
	};

	/**
	* returns a frames visibility (if frame is minimized or not)
	*/
	this.isVisible = function(){
		return this.visibility;
	};

};
<commit_msg>removed draggable bug (drag frame after resize was not possible)<commit_after>/**
* provides general window funtionality like close/resize for windows (browser, folder)
*/
FrameWindow = function(frameClass,headerClass){

	this.windowFunctionality = true;

	/**
	* initializes frame with functionality close/resize/drag/fullscreen dependent on given <params>
	*/
	this.initializeFrame = function(params){

		this.params = params;

		var frame = this;
//		this.addClass("frame passiveFrame");
		this.addClass("frame");
		this.addClass(frameClass);
		this.visibility = true;

		this.toolbarDiv = $("
").appendTo(this);
		this.toolbarDiv.addClass(headerClass);

		this.windowTools = $("
").appendTo(this.toolbarDiv);
		var headline = $("
").appendTo(this.toolbarDiv);
		this.label = $("").appendTo(headline);

		this.content = $("
").appendTo(this);
		$(this.content).css('position','relative');
		$(this.content).mousedown(function(){
			frame.updateZIndex(false);
		});

		this.dragLock = false;
		if( params.draggable ){
			this.mousedown(function(evt){
				if( frame.windowFunctionality ){
					frame.dragFrame(evt);
				}
			});
			$(this.content).bind('mousedown',function(e){
				e.stopPropagation();
			});
		}

		if( params.concealable ){
			this.visibilityButton = $("
").appendTo(this.windowTools);
			this.visibilityLink = $(' ').appendTo(this.visibilityButton);
			this.visibilityLink.attr("title",Util.getString('minimizeWindow'));
			this.visibilityButton.click(function(){
				frame.toggleVisibility();
			});
		}

		if( params.removable ){
			this.removeButton = $("
").appendTo(this.windowTools);
			var removeLink = $('').appendTo(this.removeButton);
//			$('').appendTo(removeLink);
			removeLink.attr("title",Util.getString('removeWindow'));
			this.removeButton.click(function(){
				frame.toolbarDiv.remove();
				if( typeof params.triggerRemove != 'undefined' ){
					params.triggerRemove();
				}
				a18Gui.checkGrid();
				$(frame).remove();
			});
		}

/*		if( params.fullscreen ){
			var fullscreenLi = $('
').appendTo(this.windowTools);
			var fullscreen = $('').appendTo(fullscreenLi);
			fullscreen.attr('title',Util.getString('fullscreenMode'));
			var maximized = false;
			var w, h, l, t;
			fullscreen.click(function(){
				maximized = !maximized;
				var width, height, left, top;
				if( maximized ){
					w = $(frame).width();
					h = $(frame).height();
					t = $(frame).position().top;
					l = $(frame).position().left;
					var marginGap = a18Props.margin;
					width = $(a18Gui.containerDiv).width()-2*marginGap;
					height = $(a18Gui.containerDiv).height()-2*marginGap;
					left = marginGap;
					top = marginGap;
				}
				else {
					width = w;
					height = h;
					left = l;
					top = t;
				}
				frame.position(left,top);
				frame.setSize(width,height);
				frame.resize();
				frame.resizeContent();
			});

		}
*/
		this.updateZIndex(true);

		$(this).mousedown(function(){
			frame.updateZIndex(false);
		});

	};

	/**
	* updates z-index of frame, so that a selected frame is always completely visible
	*/
	this.updateZIndex = function(set){
		if( !set ){
			var zIndex = $(this).css('z-index');
			if( a18Gui.zIndex != zIndex ){
				set = true;
			}
		}
		if( set ){
			var z = a18Gui.getZIndex();
			$(this).css('z-index',z);
			if( typeof a18Gui.activeWindow != 'undefined' ){
//				a18Gui.activeWindow.removeClass('activeFrame');
//				a18Gui.activeWindow.addClass('passiveFrame');
			}
			a18Gui.activeWindow = this;
//			a18Gui.activeWindow.removeClass('passiveFrame');
//			a18Gui.activeWindow.addClass('activeFrame');
		}
	};

	/**
	* sets window functionality if there are constraints from automatic grid layout
	*/
	this.setWindowFunctionality = function(windowFunctionality){
		this.windowFunctionality = windowFunctionality;
		this.setResizability(this.windowFunctionality);
	};

	/**
	* sets resizability of the frame
	*/
	this.setResizability = function(append){
		var frame = this;
		if( this.params.resizable && append && this.windowFunctionality && this.visibility ){
			$(this).resizable({
				helper: "ui-resizable-helper",
				minHeight: a18Props.minWindowHeight,
				minWidth: a18Props.minWindowWidth,
				/*
				resize: function() {
					frame.resize();
				},
				*/
				stop: function() {
					frame.resize();
					if( typeof frame.params.triggerResize != 'undefined' ){
						frame.params.triggerResize();
					}
				}
			});
			var resizeHandles = $('.ui-resizable-handle',frame);
			for( var i=0; i<resizeHandles.length; i++ ){
				$(resizeHandles[i]).mousedown(function(){
					frame.dragLock = true;
					$(document).mousemove(function(){
						a18Gui.checkHeight();
					});
					$(document).mouseup(function(){
						$(document).mousemove(null);
						frame.dragLock = false;
					});
				});
			}
		}
		else if( this.params.resizable ){
			$(this).resizable('destroy');
		}
	};

	/**
	* sets size of the frame
	*/
	this.setSize = function(width,height){
		this.css('width', width+"px" );
		this.css('height',height+'px');
	};

	/**
	* resizes the frame
	*/
	this.resize = function(){
		//this.toolbarDiv.css('width',($(this).width())+'px');
	//	$(this.label).css('margin',Math.floor((this.toolbarDiv.height()-this.label.height())/2)+'px');
		var p = parseInt($(this).css("padding-top"))*2-4;
//		this.content.css('width', ($(this).width()-p)+"px");
		this.content.css('height', ($(this).height()-p-this.toolbarDiv.height())+"px");
	};

	/**
	* places the frame
	*/
	this.position = function(left,top){
		this.css('left',left+'px');
		this.css('top',top+'px');
	};

	/**
	* return a frames' position
	*/
	this.getPosition = function(){
		if( this.visibility ){
			return {
				t: $(this).position().top,
				l: $(this).position().left,
				w: $(this).width(),
				h: $(this).height()
			};
		}
		return {
			t: this.top,
			l: this.left,
			w: this.width,
			h: this.height
		};
	};

	/**
	* arranges minimize/maximize functionality
	*/
	this.toggleVisibility = function(){
		var frame = this;
		var padding = parseInt($(this).css("padding-top"));
		this.visibility = !this.visibility;
		if( this.visibility ){
			this.visibilityLink.removeClass("button-open");
			this.visibilityLink.addClass("button-minimize");
			$(this).animate({
				height: "-="+($(frame).height()-frame.height),
				top: "-="+($(frame).position().top-frame.top),
				left: "-="+($(frame).position().left-frame.left),
				width: "-="+($(frame).width()-frame.width)
			  }, 500, function(){
					frame.resize();
					a18Gui.checkGrid();
					a18Gui.checkHeight();
			});
			this.setResizability(true);
		}
		else {
			this.top = $(this).position().top;
			this.left = $(this).position().left;
			this.width = $(this).width();
			this.height = $(this).height();
			this.visibilityLink.removeClass("button-minimize");
			this.visibilityLink.addClass("button-open");
			$(this).animate({
				height: "-="+($(frame).height()-$(frame.toolbarDiv).height()+5),
				top: "-="+(frame.top-10),
				left: "+="+(frame.width/2-(frame.label.width()+frame.windowTools.width()+20)/2),
			    	width: "-="+($(frame).width()-frame.label.width()-frame.windowTools.width()-20)
			  }, 500, function(){
					frame.resize();
					a18Gui.checkGrid();
					a18Gui.checkHeight();
			});
			this.setResizability(false);
		}
	};

	/**
	* set label (old design)
	*/
	this.setLabel = function(label){
		$(this.label).html(label);
		//$(this.label).css('margin',Math.floor((this.toolbarDiv.height()-this.label.height())/2)+'px');
	};

	/**
	* perfoms drag functionality for frame
	*/
	this.dragFrame = function(evt){
		var frame = this;
		var getMousePosition = function(e){
			if(!e){
		    	e = window.event;
			}
		    var body = (window.document.compatMode && window.document.compatMode == "CSS1Compat") ? window.document.documentElement : window.document.body;
		    return {
		    	top: e.pageY ? e.pageY : e.clientY,
		        left: e.pageX ? e.pageX : e.clientX
		    };
		}
		var startPos = getMousePosition(evt);
		var windowLeft = $(frame).position().left;
		var windowTop = $(frame).position().top;
		document.onmouseup = function(){
			document.onmousemove = null;
			document.onmouseup = null;
		}
		document.onmousemove = function(e){
			if( !frame.dragLock ){
				var pos = getMousePosition(e);
				frame.css('left',(windowLeft+pos.left-startPos.left)+'px');
				frame.css('top',(windowTop+pos.top-startPos.top)+'px');
				a18Gui.checkHeight();
			}
		}
	};

	/**
	* returns a frames visibility (if frame is minimized or not)
	*/
	this.isVisible = function(){
		return this.visibility;
	};

};
<|endoftext|>


<commit_before>module.exports = {

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

name: "Store Server Things",

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

section: "Server Control",

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

subtitle: function(data) {
	const servers = ['Current Server', 'Temp Variable', 'Server Variable', 'Global Variable'];
	const info = ['Creation Date', 'Time to AFK', 'Is server available?', 'More than 250 members?', 'Date bot joined server', 'Total Channel Amount', 'Emoji amount', 'Embed Links', 'DND Members Count', 'Online Members Count (fixed)', 'Offline Members Count', 'Idle Members Count', 'Total Bots Count in Server', 'Server Channel IDs', 'Server Role IDs', 'Server Member IDs', 'Server Bot Count', 'Server Human Member Count', 'Server Member Count', 'Text Channel Amount', 'Voice Channel Amount'];
	return `${servers[parseInt(data.server)]} - ${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, EGGSY & EliteArtz",

	 // The version of the mod (Defaults to 1.0.0)
	 version: "1.8.7",
	 //19&20 Added by Invarion in 1.8.8 | Taken from bashy's mod
	 //21&22 Added by Invarion in 1.8.8 |

	 // A short description to show on the mod line for this mod (Must be on a single line)
	 short_description: "Stores more Server Information",

	 // 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 = 'Text';
	switch(info) {
		case 0:
			dataType = "Date";
			break;
		case 1:
			dataType = "Number";
			break;
		case 2:
			dataType = "Boolean";
			break;
		case 3:
			dataType = "Boolean";
			break;
		case 4:
			dataType = "Date";
			break;
		case 5:
			dataType = "Number";
			break;
		case 6:
			dataType = "Number";
			break;
		case 7:
			dataType = "Boolean";
			break;
		case 8:
			dataType = "Number";
			break;
		case 9:
			dataType = "Number";
			break;
		case 10:
			dataType = "Number";
			break;
		case 11:
			dataType = "Number";
			break;
		case 12:
			dataType = "Number";
			break;
		case 13:
			dataType = 'Server Channel IDs';
			break;
		case 14:
			dataType = 'Server Role IDs';
			break;
		case 15:
			dataType = 'Server Member IDs';
			break;
		case 16:
			dataType = 'Number';
			break;
		case 17:
			dataType = 'Number';
			break;
		case 18:
			dataType = 'Number';
			break;
		case 19:
			dataType = 'Number';
			break;
		case 20:
			dataType = 'Number';
			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: ["server", "varName", "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 EGGSY, EliteArtz, Invarion & Lasse!

		Source Server:

		<select id="server" class="round" onchange="glob.serverChange(this, 'varNameContainer')">
			${data.servers[isEvent ? 1 : 0]}
		</select>

		Variable Name:

		<input id="varName" class="round" type="text" list="variableList">

		Source Info:

		<select id="info" class="round">
			<option value="0" selected>Servers Creation Date</option>
			<option value="1">Time User gets AFK</option>
			<option value="2">Is Server available?</option>
			<option value="4">Date Bot Joined</option>
			<option value="5">Total Channel Amount</option>
			<option value="19">Text Channel Amount</option>
			<option value="20">Voice Channel Amount</option>
			<option value="21">Text Channel List</option>
			<option value="22">Voice Channel List</option>
			<option value="6">Server Emoji Amount</option>
			<option value="7">Embeds links?</option>
			<option value="9">Online Members Count</option
			<option value="11">Idle Members Count</option>
			<option value="8">DND Members Count</option>
			<option value="10">Offline Members Count</option>
			<option value="13">Server Channel IDs</option>
			<option value="14">Server Role IDs</option>
			<option value="15">Server Member IDs</option>
      <option value="18">Server Member Count</option>
			<option value="16">Server Bot Count</option>
			<option value="17">Server Human Member Count</option>
			<option value="12">Total Bots in Servers</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() {
	const {glob, document} = this;

	glob.serverChange(document.getElementById('server'), 'varNameContainer')
},

//---------------------------------------------------------------------
// 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 data = cache.actions[cache.index];
	const server = parseInt(data.server);
	const varName = this.evalMessage(data.varName, cache);
	const info = parseInt(data.info);
	const targetServer = this.getServer(server, varName, cache);
	if(!targetServer) {
		this.callNextAction(cache);
		return;
	}
	let result;
	switch(info) {
		case 0:
			result = targetServer.createdAt;
			break;
		case 1:
			result = targetServer.afkTimeout;
			break;
		case 2:
			result = targetServer.available;
			break;
		case 3:
			result = targetServer.large; //Deprecated in v1.8.5
			break;
		case 4:
			result = targetServer.joinedAt;
			break;
		case 5:
			result = targetServer.channels.array().length;
			break;
		case 6:
			result = targetServer.emojis.array().length;
			break;
		case 7:
			result = targetServer.embedEnabled;
			break;
		case 8:
			result = targetServer.members.filter(m => m.user.presence.status == "dnd").size;
			break;
		case 9:
			result = targetServer.members.filter(m => m.user.presence.status == "online").size;
			break;
		case 10:
			result = targetServer.members.filter(m => m.user.presence.status == "offline").size;
			break;
		case 11:
			result = targetServer.members.filter(m => m.user.presence.status == "idle").size;
			break;
		case 12:
			result = targetServer.members.filter(m => m.user.bot).size;
			break;
		case 13:
			result = targetServer.channels.map(channels => channels.id);
			break;
		case 14:
			result = targetServer.roles.map(roles => roles.id);
			break;
		case 15:
			result = targetServer.members.map(members => members.id);
			break;
		case 16:
			result = targetServer.members.filter(m => m.user.bot == true).size;
			break;
		case 17:
			result = targetServer.members.filter(m => m.user.bot == false).size;
			break;
		case 18:
			result = targetServer.memberCount; //Added by Lasse in 1.8.7
			break;
		case 19:
			result = targetServer.channels.findAll('type', 'text').length; //Added by Invarion in 1.8.8 | Taken from bashy's mod
			break;
		case 20:
			result = targetServer.channels.findAll('type', 'voice').length; //Added by Invarion in 1.8.8 | Taken from bashy's mod
			break;
		case 21:
			result = targetServer.channels.findAll('type', 'text');  //Added by Invarion in 1.8.8
	   		break;
		case 22:
	   		result = targetServer.channels.findAll('type', 'voice'); //Added by Invarion in 1.8.8
		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>Store Server Info Mod<commit_after>module.exports = {
//---------------------------------------------------------------------
// Notes Section
//
// More Than 250 Members is deprecated please keep in mind its the #3 vaule. (do NOT remove)
// given the large amount of Infos here PLEASE document everything properly so the next person that adds onto it will know whats going on. thanks
//---------------------------------------------------------------------

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

name: "Store Server Things",

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

section: "Server Control",

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

subtitle: function(data) {
	const servers = ['Current Server', 'Temp Variable', 'Server Variable', 'Global Variable'];
	const info = ['Creation Date', 'Time To AFK', 'Is Server Available?', 'More than 250 members?', 'Date Bot Joined Server', 'Channel Amount',	'Emoji Amount', 'Embed Links', 'DND Members Count', 'Online Members Count (fixed)',	'Offline Members Count',	'Idle Members Count',	'Total Bots Count In Server',	'Server Channel IDs',	'Server Role IDs',	'Server Member IDs',	'Server Bot Member Count',	'Server Human Member Count',	'Server Member Count',	'Role Count',	'Text Channel Count', 'Voice Channel Count'];
	return `${servers[parseInt(data.server)]} - ${data.info} - ${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, EGGSY, EliteArtz & Danno3817",

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

	 // A short description to show on the mod line for this mod (Must be on a single line)
	 short_description: "Stores more Server Information",

	 // 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 = 'Text';
	// Case 3 is deprecated please read above Note Section before editing.
	switch(info) {
		case 0:
			dataType = "Date"; // Creation Date.
			break;
		case 1:
			dataType = "Number"; // Time To AFK.
			break;
		case 2:
			dataType = "Boolean"; // Is Server Avilable?
			break;
		case 3:
			dataType = "Boolean"; // More Than 250 Members? //Deprecated in v1.8.5
			break;
		case 4:
			dataType = "Date"; // Date bot Joined Server.
			break;
		case 5:
			dataType = "Number"; // Channel Amount.
			break;
		case 6:
			dataType = "Number"; // Emoji Amount.
			break;
		case 7:
			dataType = "Boolean"; // Embed Links.
			break;
		case 8:
			dataType = "Number"; // DND Members Count.
			break;
		case 9:
			dataType = "Number"; // Online Members Count. (fixed)
			break;
		case 10:
			dataType = "Number"; // Offline Members Count.
			break;
		case 11:
			dataType = "Number"; // Idle Members Count.
			break;
		case 12:
			dataType = "Number"; // Total Bots Count In Server.
			break;
		case 13:
			dataType = 'Server Channel IDs'; // Server Channel IDs.
			break;
		case 14:
			dataType = 'Server Role IDs'; // Server Roles IDs.
			break;
		case 15:
			dataType = 'Server Member IDs'; // Server Member IDs.
			break;
		case 16:
			dataType = 'Number'; // Server Bot Member Count.
			break;
		case 17:
			dataType = 'Number'; // Server Human Member Count.
			break;
		case 18:
			dataType = 'Number'; // Server Member Count. //Added by Lasse in
			break;
		case 19:
			dataType = 'Number'; // Role Count.
			break;
		case 20:
			dataType = 'Number'; // Text Channel
			break;
		case 21:
			dataType = 'Number'; // Voice Channel

	}
	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: ["server", "varName", "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
//---------------------------------------------------------------------

// current Value is 21 (if you add to it please increase the Value as seen fit)
html: function(isEvent, data) {
	return `

			Mod Info:

			Created by EGGSY, EliteArtz, Lasse! & Danno3817

		Source Server:

		<select id="server" class="round" onchange="glob.serverChange(this, 'varNameContainer')">
			${data.servers[isEvent ? 1 : 0]}
		</select>

		Variable Name:

		<input id="varName" class="round" type="text" list="variableList">

		Source Info:

		<select id="info" class="round" >
			<optgroup label="Creation/Join Dates">
				<option value="0" selected>Servers Creation Date</option>
				<option value="4">Date Bot Joined</option>
			</optgroup>
			<optgroup label="Member Infos">
				<option value="12">Total Bots in Servers</option>
				<option value="16">Bot Count (Same as Total Bots In Servers)</option>
				<option value="17">Human Member Count</option>
				<option value="18">Member Count(Same as Human Member Count)</option>
			</optgroup>
			<optgroup label="Member Status Infos">
				<option value="8">DND Members Count</option>
				<option value="9">Online Members Count</option>
				<option value="10">Offline Members Count</option>
				<option vaule="11">Idle Members Count</option>
			</optgroup>
			<optgroup label="ID Infos">
				<option value="13">Server Channel IDs</option>
				<option value="14">Server Role IDs</option>
				<option value="15">Server Member IDs</option>
			</optgroup>
			<optgroup label="Channel Infos">
				<option value="5">Channel Amount</option>
				<option value="20">Text Channel Count</option>
				<option value="21">Voice Channel Count</option>
			</optgroup>
			<optgroup label="Other">
				<option value="1">Time User gets AFK</option>
				<option value="2">Is Server available?</option>
				<option value="6">Emoji Amount</option>
				<option value="7">Embeds links?</option>
				<option value="19">Role Count</option>
			</optgroup>

			</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() {
	const {glob, document} = this;

	glob.serverChange(document.getElementById('server'), 'varNameContainer')
},

//---------------------------------------------------------------------
// 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.
//---------------------------------------------------------------------

// Please read above Notes Section before editing.
action: function(cache) {
	const data = cache.actions[cache.index];
	const server = parseInt(data.server);
	const varName = this.evalMessage(data.varName, cache);
	const info = parseInt(data.info);
	const targetServer = this.getServer(server, varName, cache);
	if(!targetServer) {
		this.callNextAction(cache);
		return;
	}
	let result;
	switch(info) {
		case 0:
			result = targetServer.createdAt; // Creation Date.
			break;
		case 1:
			result = targetServer.afkTimeout; // Time To AFK.
			break;
		case 2:
			result = targetServer.available; // Is Server Avilable?
			break;
		case 3:
			result = targetServer.large; // More Than 250 Members? //Deprecated in v1.8.5
			break;
		case 4:
			result = targetServer.joinedAt; // Date bot Joined Server.
			break;
		case 5:
			result = targetServer.channels.array().length; // Channel Amount.
			break;
		case 6:
			result = targetServer.emojis.array().length; // Emoji Amount.
			break;
		case 7:
			result = targetServer.embedEnabled; // Embed Links.
			break;
		case 8:
			result = targetServer.members.filter(m => m.user.presence.status == "dnd").size; // DND Members Count.
			break;
		case 9:
			result = targetServer.members.filter(m => m.user.presence.status == "online").size; // Online Members Count.
			break;
		case 10:
			result = targetServer.members.filter(m => m.user.presence.status == "offline").size; // Offline Members Count.
			break;
		case 11:
			result = targetServer.members.filter(m => m.user.presence.status == "idle").size; // Idle Members Count.
			break;
		case 12:
			result = targetServer.members.filter(m => m.user.bot).size; // Total Bots Count In Server.
			break;
		case 13:
			result = targetServer.channels.map(channels => channels.id); // Server Channel IDs.
			break;
		case 14:
			result = targetServer.roles.map(roles => roles.id); // Server Roles IDs.
			break;
		case 15:
			result = targetServer.members.map(members => members.id); // Server Member IDs.
			break;
		case 16:
			result = targetServer.members.filter(m => m.user.bot == true).size; // Server Bot Member Count.
			break;
		case 17:
			result = targetServer.members.filter(m => m.user.bot == false).size; // Server Human Member Count.
			break;
		case 18:
			result = targetServer.memberCount; // Server Member Count. //Added by Lasse in 1.8.7
			break;
		case 19:
			result = targetServer.roles.size; // Role Count.
			break;
		case 20:
			result = targetServer.channels.findAll('type', 'text').length; // Text Channel Count.
			break;
		case 21:
			result = targetServer.channels.findAll('type', 'voice').length; // Voice Channel Count.
			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>module.exports = {

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

    name: "File Control",

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

    section: "File Stuff",

    //---------------------------------------------------------------------
        // 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: "Danno3187", //Original Idea by EliteArtz

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

        // A short description to show on the mod line for this mod (Must be on a single line)
        short_description: "Allows a user to interact with 'Files'",

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

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

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

    subtitle: function(data) {
        const filetasks = ['Create', 'Write', 'Append', 'Delete'];
        return `${filetasks[parseInt(data.filetask)]} ${data.filename}${data.format}`;
    },

    //---------------------------------------------------------------------
    // 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: ["input", "format", "filename", "filepath", "filetask"],

    //---------------------------------------------------------------------
    // 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

        Made by Danno3817, EliteArtz & EGGSY

                File Format:

                <select id="format" class="round">
                <option value=".json">JSON</option>
                <option value=".txt">TXT</option>
                <option value=".js">JS</option>
                <option value=".log" selected>LOG</option>
                </select>

                File Task:

                <select id="filetask" class="round">
                <option value="0" selected>Create</option>
                <option value="1">Write</option>
                <option value="2">Append</option>
                <option value="3">Delete</option>
                </select>

                File Name:

                <textarea id="filename" placeholder="Insert File Name Here..." class="round" style="width 50%; resize: none; padding: 4px 0px;" type="textarea" rows="1" cols="25";></textarea>

                File Path:

                <textarea id="filepath" placeholder="Insert Path Here... Example Below" class="round" style="width99%; resize: none;" type="textarea" rows="1" cols="60"></textarea>

            Input Text:

            <textarea id="input" placeholder="Leave Blank For None." class="round" style="width: 99%; resize: 1;" type="textarea" rows="8" cols="35"></textarea>

Important info:

            If you want to delete something in current directory, you can add '.' (dot) before '/':

            e.g:

            My bot directory is: "/root/myBot/"

            I want to delete: "/root/myBot/delete.txt"

            Then I need to write "./delete.txt" in the field.

            Please be careful while using this mod. Don't forget there is no turning back after deleting the file.

`
    },

    //---------------------------------------------------------------------
    // 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 data = cache.actions[cache.index];

        const fileNAME = this.evalMessage(data.filename, cache);
        const filePATH = this.evalMessage(data.filepath, cache);
        const FullFile = filePATH + fileNAME + `${data.format}`;
        const fs = require('fs');

        const task = parseInt(data.filetask);

        const inputtext = this.evalMessage(data.input, cache);

        switch(task){
            case 0:
            console.log("Create File Activated");
            try {
                if (filePATH && fileNAME){
                    fs.writeFileSync(FullFile,"");
                }else{
                console.log("File name or File path is missing.");
                }
            }catch (err){
            console.log("ERROR!" + err.stack ? err.stack : err);
            }this.callNextAction(cache);
            break;

            case 1:
            console.log("Write File Activated");
            try{
                if (filePATH && fileNAME) {
                    fs.writeFileSync(FullFile, inputtext, console.log(`${data.filename}${data.format} File was written.`));
                } else {
                console.log(`File name or File path is missing.`);
                }
            } catch (err) {
                console.log("ERROR!" + err.stack ? err.stack : err);
            }this.callNextAction(cache);
            break;

            case 2:
            console.log("Append File Activated");
            try {
                if (filePATH && fileNAME){
                    fs.appendFileSync(FullFile, inputtext + '\r\n' );
                }else{
                console.log("File name or File path is missing.");
                }
            }catch (err){
            console.log("ERROR!" + err.stack ? err.stack : err);
            }this.callNextAction(cache);
            break;

            case 3:
            console.log("Delete File Activated");
            try {
                if (filePATH && fileNAME) {
                    fs.exists(`${FullFile}`, function(exists) {
                        if(exists) {
                            fs.unlink(FullFile, (err) => {
                                if (err) return console.log(`Something went wrong while deleting: [${err}]`);
                                console.log(`Sucessfully deleted [${FullFile}].`);
                              });
                        } else {
                            console.log('File not found, nothing to delete.');
                        }
                      });
                } else {
                console.log(`File path is missing.`);
                }
            } catch (err) {
                console.log("ERROR!" + err.stack ? err.stack : err);
            }
            this.callNextAction(cache);
            break;

        }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>Update file_control_MOD.js<commit_after>module.exports = {

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

    name: "File Control",

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

    section: "File Stuff",

    //---------------------------------------------------------------------
        // 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: "Danno3187", //Original Idea by EliteArtz

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

        // A short description to show on the mod line for this mod (Must be on a single line)
        short_description: "Allows a user to interact with 'Files'",

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

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

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

    subtitle: function(data) {
        const filetasks = ['Create', 'Write', 'Append', 'Delete'];
        return `${filetasks[parseInt(data.filetask)]} ${data.filename}${data.format}`;
    },

    //---------------------------------------------------------------------
    // 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: ["input", "format", "filename", "filepath", "filetask"],

    //---------------------------------------------------------------------
    // 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

        Made by Danno3817, EliteArtz & EGGSY

                File Format:

                <select id="format" class="round">
                <option value=".json">JSON</option>
                <option value=".txt">TXT</option>
                <option value=".js">JS</option>
                <option value=".log" selected>LOG</option>
                </select>

                File Task:

                <select id="filetask" class="round">
                <option value="0" selected>Create</option>
                <option value="1">Write</option>
                <option value="2">Append</option>
                <option value="3">Delete</option>
                </select>

                File Name:

                <textarea id="filename" placeholder="Insert File Name Here..." class="round" style="width 50%; resize: none; padding: 4px 0px;" type="textarea" rows="1" cols="25";></textarea>

                File Path:

                <textarea id="filepath" placeholder="Insert Path Here... Example Below" class="round" style="width99%; resize: none;" type="textarea" rows="1" cols="60"></textarea>

            Input Text:

            <textarea id="input" placeholder="Leave Blank For None." class="round" style="width: 99%; resize: 1;" type="textarea" rows="8" cols="35"></textarea>

Important info:

            If you want to delete something in current directory, you can add '.' (dot) before '/':

            e.g:

            My bot directory is: "/root/myBot/"

            I want to delete: "/root/myBot/delete.txt"

            Then I need to write "./delete.txt" in the field.

            Please be careful while using this mod. Don't forget there is no turning back after deleting the file.

`
    },

    //---------------------------------------------------------------------
    // 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 data = cache.actions[cache.index];

        const fileNAME = this.evalMessage(data.filename, cache);
        const filePATH = this.evalMessage(data.filepath, cache);
        const FullFile = filePATH + fileNAME + `${data.format}`;
        const fs = require('fs');

        const task = parseInt(data.filetask);

        const inputtext = this.evalMessage(data.input, cache);

        switch(task){
            case 0:
            console.log("Create File Activated");
            try {
                if (filePATH && fileNAME){
                    fs.writeFileSync(FullFile,"");
                }else{
                console.log("File name or File path is missing.");
                }
            }catch (err){
            console.log("ERROR!" + err.stack ? err.stack : err);
            }this.callNextAction(cache);
            break;

            case 1:
            try{
                if (filePATH && fileNAME) {
                    fs.writeFileSync(FullFile, inputtext, console.log(`${data.filename}${data.format} File was written.`));
                } else {
                console.log(`File name or File path is missing.`);
                }
            } catch (err) {
                console.log("ERROR!" + err.stack ? err.stack : err);
            }this.callNextAction(cache);
            break;

            case 2:
            try {
                if (filePATH && fileNAME){
                    fs.appendFileSync(FullFile, inputtext + '\r\n' );
                }else{
                console.log("File name or File path is missing.");
                }
            }catch (err){
            console.log("ERROR!" + err.stack ? err.stack : err);
            }this.callNextAction(cache);
            break;

            case 3:
            try {
                if (filePATH && fileNAME) {
                    fs.exists(`${FullFile}`, function(exists) {
                        if(exists) {
                            fs.unlink(FullFile, (err) => {
                                if (err) return console.log(`Something went wrong while deleting: [${err}]`);
                                console.log(`Sucessfully deleted [${FullFile}].`);
                              });
                        } else {
                            console.log('File not found, nothing to delete.');
                        }
                      });
                } else {
                console.log(`File path is missing.`);
                }
            } catch (err) {
                console.log("ERROR!" + err.stack ? err.stack : err);
            }
            this.callNextAction(cache);
            break;

        }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>const browserify = require('browserify');
const buffer = require('vinyl-buffer');
const del = require('del');
const gulp = require('gulp');
const gulp_if = require('gulp-if');
const gutil = require('gulp-util');
const livereload = require('gulp-livereload');
const path = require('path');
const source = require('vinyl-source-stream');
const sourcemaps = require('gulp-sourcemaps');
const uglify = require('gulp-uglify');
const watchify = require('watchify');

const transform_SVG = require('tools/browserify/svg');
const transform_TMPL = require('tools/browserify/template');

const env = require('tools/gulp/env');

const output_dir = path.join(env.outputDirectory, 'assets', 'js');
const sources_dir = path.join('sources', 'js');

const browserify_base_options = {
	debug: true,
	paths: ['node_modules', sources_dir],
	transform: [[
		'babelify', {
			presets: ['es2015'],
			plugins: ['transform-runtime']
		}
	], [
		transform_SVG
	], [
		transform_TMPL
	]]
};

const bundles = Object.assign(
	{arkanoid: path.join(sources_dir, env.target)},
	env.isDevelopment ? {editor: path.join(sources_dir, 'editor', 'main.js')}: {},
	env.isDevelopment ? {sound: path.join(sources_dir, 'sound', 'arkanoid', 'main.js')}: {}
);

Object.entries(bundles).forEach(([bundle_name, entry_point]) => {
	function bundle(bundler) {
		return bundler
			.bundle()
			.on('error', (err) => {
				gutil.log(
					gutil.colors.red('Browserify compile error: '),
					err.message, '\n\t'
				);
				if (env.isProduction) {
					err.stream.end();
					process.exit(1);
				}
			})
			.pipe(source(`${bundle_name}.js`))
			.pipe(buffer())
			.pipe(sourcemaps.init({loadMaps: true}))
			.pipe(gulp_if(!env.isDevelopment, uglify()))
			.pipe(gulp_if(env.isDevelopment, sourcemaps.write()))
			.pipe(gulp.dest(output_dir))
			.pipe(livereload());
	}

	function create_browserify_bundler(options) {
		return browserify(
			entry_point,
			Object.assign({}, browserify_base_options, options || {})
		);
	}

	function create_watchify_bundler(bundle) {
		const bundler = watchify(create_browserify_bundler(entry_point, watchify.args));
		bundler
			.on('update', (ids) => {
				gutil.log('Update:');
				ids.forEach((id) => gutil.log(` - ${id}`))
				bundle(bundler);
			})
			.on('log', gutil.log)
		return bundler;
	}

	const task_base_name = `${bundle_name}-bundle`

	gulp.task(task_base_name, () => bundle(create_browserify_bundler()));
	gulp.task(`${task_base_name}-clean`, () => del(output_dir));
	gulp.task(`${task_base_name}-watch`, [task_base_name], () => bundle(create_watchify_bundler(bundle)));
});

const tasks = Object.keys(bundles).reduce((value, bundle) => ({
	// reducer
	'bundle':       [].concat(value['bundle'], `${bundle}-bundle`),
	'bundle-clean': [].concat(value['bundle-clean'], `${bundle}-bundle-clean`),
	'bundle-watch': [].concat(value['bundle-watch'], `${bundle}-bundle-watch`)
}), {
	// initial value
	'bundle':       [],
	'bundle-clean': [],
	'bundle-watch': []
});

Object.entries(tasks).forEach(([task, deps]) => {
	gulp.task(task, deps)
});

module.exports = {
	build: 'bundle',
	clean: 'bundle-clean',
	watch: 'bundle-watch'
};
<commit_msg>Fix template transformation<commit_after>const browserify = require('browserify');
const buffer = require('vinyl-buffer');
const del = require('del');
const gulp = require('gulp');
const gulp_if = require('gulp-if');
const gutil = require('gulp-util');
const livereload = require('gulp-livereload');
const path = require('path');
const source = require('vinyl-source-stream');
const sourcemaps = require('gulp-sourcemaps');
const uglify = require('gulp-uglify');
const watchify = require('watchify');

const transform_TMPL = require('tools/browserify/template');

const env = require('tools/gulp/env');

const output_dir = path.join(env.outputDirectory, 'assets', 'js');
const sources_dir = path.join('sources', 'js');

const browserify_base_options = {
	debug: true,
	paths: ['node_modules', sources_dir],
	transform: [[
		transform_TMPL
	], [
		'babelify', {
			extensions: ['.js', '.tmpl'],
			presets: ['es2015'],
			plugins: ['transform-runtime']
		}
	]]
};

const bundles = Object.assign(
	{arkanoid: path.join(sources_dir, env.target)},
	env.isDevelopment ? {editor: path.join(sources_dir, 'editor', 'main.js')}: {},
	env.isDevelopment ? {sound: path.join(sources_dir, 'sound', 'arkanoid', 'main.js')}: {}
);

Object.entries(bundles).forEach(([bundle_name, entry_point]) => {
	function bundle(bundler) {
		return bundler
			.bundle()
			.on('error', err => {
				gutil.log(
					gutil.colors.red('Browserify compile error: '),
					err.toString()
				);
				if (env.isProduction) {
					err.stream.end();
					process.exit(1);
				}
			})
			.pipe(source(`${bundle_name}.js`))
			.pipe(buffer())
			.pipe(sourcemaps.init({loadMaps: true}))
			.pipe(gulp_if(!env.isDevelopment, uglify()))
			.pipe(gulp_if(env.isDevelopment, sourcemaps.write()))
			.pipe(gulp.dest(output_dir))
			.pipe(livereload());
	}

	function create_browserify_bundler(options) {
		return browserify(
			entry_point,
			Object.assign({}, browserify_base_options, options || {})
		);
	}

	function create_watchify_bundler(bundle) {
		const bundler = watchify(create_browserify_bundler(entry_point, watchify.args));
		bundler
			.on('update', (ids) => {
				gutil.log('Update:');
				ids.forEach((id) => gutil.log(` - ${id}`))
				bundle(bundler);
			})
			.on('log', gutil.log)
		return bundler;
	}

	const task_base_name = `${bundle_name}-bundle`

	gulp.task(task_base_name, () => bundle(create_browserify_bundler()));
	gulp.task(`${task_base_name}-clean`, () => del(output_dir));
	gulp.task(`${task_base_name}-watch`, [task_base_name], () => bundle(create_watchify_bundler(bundle)));
});

const tasks = Object.keys(bundles).reduce((value, bundle) => ({
	// reducer
	'bundle':       [].concat(value['bundle'], `${bundle}-bundle`),
	'bundle-clean': [].concat(value['bundle-clean'], `${bundle}-bundle-clean`),
	'bundle-watch': [].concat(value['bundle-watch'], `${bundle}-bundle-watch`)
}), {
	// initial value
	'bundle':       [],
	'bundle-clean': [],
	'bundle-watch': []
});

Object.entries(tasks).forEach(([task, deps]) => {
	gulp.task(task, deps)
});

module.exports = {
	build: 'bundle',
	clean: 'bundle-clean',
	watch: 'bundle-watch'
};
<|endoftext|>


<commit_before>/* Main unmaze library
   Copyright 2017 Mariusz Skoneczko
   Licensed under the MIT license
*/

const MAZE = {
    FREE: 0,
    WALL: 1,
    END: 2,
    TRAIL: 3
};

class Maze {
    constructor(width, height) {
        if (width < 2 || height < 2) {
            throw new RangeError("Dimensions too small");
        }
        this.width = width;
        this.height = height;

        this.maze = new Array(width);
        // create 'matrix' maze where maze[x][y] such that x < width, y < height
        for (let i = 0; i < width; i++) {
            this.maze[i] = new Array(height);
        }
        this.allWall();
        this.start = {x: null, y: null};
        this.robot = {x: null, y: null};
    }

    allWall() {
        for (let i = 0; i < this.width; i++) {
            for (let j = 0; j < this.height; j++) {
                this.maze[i][j] = MAZE.WALL;
            }
        }
    }

    setStart(x, y) {
        this.start = {x: x, y: y};
    }

    setEnd(x, y) {
        this.maze[x][y] = MAZE.END;
    }

    robotToStart() {
        this.robot.x = this.start.x;
        this.robot.y = this.start.y;
    }

    resetRobot() {
        this.robotToStart();
        for (let i = 0; i < this.width; i++) {
            for (let j= 0; j < this.height; j++) {
                if (this.maze[i][j] === MAZE.TRAIL) {
                    this.maze[i][j] = MAZE.FREE;
                }
            }
        }
    }

    save() {
        return btoa(JSON.stringify({
            maze: this.maze,
            start: this.start
        }));
    }

    load(savedata) {
        let loaddata = JSON.parse(atob(savedata));
        this.maze = loaddata.maze;
        this.start = loaddata.start;
        this.robotToStart();
        this.width = this.maze.length;
        this.height = this.maze[0].length;
    }
}

const SOLVE_STATUS = {
    EXPLORING: 0,
    SOLVED: 1,
    FAILED: 2,
    RETRACING: 3
};

const DIRECTION = {
    UP: 0,
    RIGHT: 1,
    DOWN: 2,
    LEFT: 3
};

const INVERT_DIRECTION = {
    [DIRECTION.UP]: DIRECTION.DOWN,
    [DIRECTION.RIGHT]: DIRECTION.LEFT,
    [DIRECTION.DOWN]: DIRECTION.UP,
    [DIRECTION.LEFT]: DIRECTION.RIGHT
};

class MazeSolver {
    constructor(maze) {
        this.maze = maze;
        this.status = SOLVE_STATUS.EXPLORING;
        this.junction_memory = {};
        this.move_memory = [];
        this.last_direction = null;
        this.steps = 0;
    }

    adjacent() {
        let up, right, down, left;

        if (this.maze.robot.y === 0) {
            up = MAZE.WALL;
        } else {
            up = this.maze.maze[this.maze.robot.x][this.maze.robot.y - 1];
        }

        if (this.maze.robot.x === this.maze.width - 1) {
            right = MAZE.WALL;
        } else {
            right = this.maze.maze[this.maze.robot.x + 1][this.maze.robot.y];
        }

        if (this.maze.robot.y === this.maze.height - 1) {
            down = MAZE.WALL;
        } else {
            down = this.maze.maze[this.maze.robot.x][this.maze.robot.y + 1];
        }

        if (this.maze.robot.x === 0) {
            left = MAZE.WALL;
        } else {
            left = this.maze.maze[this.maze.robot.x - 1][this.maze.robot.y];
        }

        return {
            [DIRECTION.UP]: up,
            [DIRECTION.RIGHT]: right,
            [DIRECTION.DOWN]: down,
            [DIRECTION.LEFT]: left
        };
    }

    isSolved() {
        if (this.maze.maze[this.maze.robot.x][this.maze.robot.y] === MAZE.END) {
            return true;
        } else {
            return false;
        }
    }

    possibleNext(adjacent) {
        let possibilities = [];
        for (let key in adjacent) {
            if (adjacent[key] === MAZE.FREE || adjacent[key] === MAZE.END) {
                possibilities.push(parseInt(key));
            }
        }
        return possibilities;
    }

    isJunction(possibilities) {
        if (possibilities.length > 1) {
            return true;
        } else {
            return false;
        }
    }

    isDeadEnd(possibilities) {
        if (possibilities.length === 0) {
            return true;
        } else {
            return false;
        }
    }

    move(direction, log=true) {
        if (log) this.move_memory.push(direction);
        this.last_direction = direction;
        if (direction === DIRECTION.UP) {
            this.maze.robot.y -= 1;
        } else if (direction === DIRECTION.RIGHT) {
            this.maze.robot.x += 1;
        } else if (direction === DIRECTION.DOWN) {
            this.maze.robot.y += 1;
        } else if (direction === DIRECTION.LEFT) {
            this.maze.robot.x -= 1;
        }
    }

    explore(possibilities) {
        if (this.isJunction(possibilities)) {
            if (this.junction_memory[[this.maze.robot.x, this.maze.robot.y].toString()] === undefined) {
                // new junction!
                let direction = possibilities[0];
                this.junction_memory[[this.maze.robot.x, this.maze.robot.y].toString()] = [direction];
                // set down trail to avoid considering this a new junction if there is a loop
                this.maze.maze[this.maze.robot.x][this.maze.robot.y] = MAZE.TRAIL;
                this.move(direction);
            } else {
                // we already handled this junction before
                this.move(INVERT_DIRECTION[this.move_memory.pop()], false);
                this.maze.maze[this.maze.robot.x][this.maze.robot.y] = MAZE.FREE;
                this.status = SOLVE_STATUS.RETRACING;
            }
        } else if (this.isDeadEnd(possibilities)) {
            // move back to last position and THEN retrace: handles loops correctly
            this.move(INVERT_DIRECTION[this.move_memory.pop()], false);
            // remove trail
            this.maze.maze[this.maze.robot.x][this.maze.robot.y] = MAZE.FREE;
            this.status = SOLVE_STATUS.RETRACING;
        } else {
            // move to the next available space
            // but first, set down a trail tile (BEFORE moving)
            this.maze.maze[this.maze.robot.x][this.maze.robot.y] = MAZE.TRAIL;
            this.move(possibilities[0]);
        }
    }

    goBack(adjacent) {
        if (this.maze.robot.x === this.maze.start.x && this.maze.robot.y === this.maze.start.y) {
            this.status = SOLVE_STATUS.FAILED;
        } else {
            let direction = INVERT_DIRECTION[this.move_memory.pop()];
            this.move(direction, false);
            // remove trail
            this.maze.maze[this.maze.robot.x][this.maze.robot.y] = MAZE.FREE;
        }
    }

    retrace(adjacent, possibilities) {
        if (this.isJunction(possibilities)) {
            // choose a direction we have not been in before, or continue retracing if there is none
            let junction_paths = this.junction_memory[[this.maze.robot.x, this.maze.robot.y].toString()];
            let direction = null;
            for (let possibility of possibilities) {
                // possibility that we have not been to before
                if (junction_paths.indexOf(possibility) === -1) {
                    direction = possibility;
                    break;
                }
            }
            if (direction === null) {
                // we have been everywhere possible from this junction
                this.goBack(adjacent);
            } else {
                junction_paths.push(direction);
                this.maze.maze[this.maze.robot.x][this.maze.robot.y] = MAZE.TRAIL;
                this.status = SOLVE_STATUS.EXPLORING;
                this.move(direction);
            }
        } else {
            this.goBack(adjacent);
        }
    }

    ai() {
        let adjacent = this.adjacent();
        let possibilities = this.possibleNext(adjacent);

        if (this.isSolved()) {
            this.status = SOLVE_STATUS.SOLVED;
            return;
        }

        if (this.status === SOLVE_STATUS.EXPLORING) {
            this.explore(possibilities);
        } else if (this.status === SOLVE_STATUS.RETRACING) {
            this.retrace(adjacent, possibilities);
        }
    }

    done() {
        if (this.status === SOLVE_STATUS.SOLVED || this.status === SOLVE_STATUS.FAILED) {
            return true;
        } else {
            return false;
        }
    }

    step() {
        if (!this.done()) {
            this.ai();
            this.steps += 1;
        }

        return this.status;
    }
}
<commit_msg>Removed useless argument from goBack method<commit_after>/* Main unmaze library
   Copyright 2017 Mariusz Skoneczko
   Licensed under the MIT license
*/

const MAZE = {
    FREE: 0,
    WALL: 1,
    END: 2,
    TRAIL: 3
};

class Maze {
    constructor(width, height) {
        if (width < 2 || height < 2) {
            throw new RangeError("Dimensions too small");
        }
        this.width = width;
        this.height = height;

        this.maze = new Array(width);
        // create 'matrix' maze where maze[x][y] such that x < width, y < height
        for (let i = 0; i < width; i++) {
            this.maze[i] = new Array(height);
        }
        this.allWall();
        this.start = {x: null, y: null};
        this.robot = {x: null, y: null};
    }

    allWall() {
        for (let i = 0; i < this.width; i++) {
            for (let j = 0; j < this.height; j++) {
                this.maze[i][j] = MAZE.WALL;
            }
        }
    }

    setStart(x, y) {
        this.start = {x: x, y: y};
    }

    setEnd(x, y) {
        this.maze[x][y] = MAZE.END;
    }

    robotToStart() {
        this.robot.x = this.start.x;
        this.robot.y = this.start.y;
    }

    resetRobot() {
        this.robotToStart();
        for (let i = 0; i < this.width; i++) {
            for (let j= 0; j < this.height; j++) {
                if (this.maze[i][j] === MAZE.TRAIL) {
                    this.maze[i][j] = MAZE.FREE;
                }
            }
        }
    }

    save() {
        return btoa(JSON.stringify({
            maze: this.maze,
            start: this.start
        }));
    }

    load(savedata) {
        let loaddata = JSON.parse(atob(savedata));
        this.maze = loaddata.maze;
        this.start = loaddata.start;
        this.robotToStart();
        this.width = this.maze.length;
        this.height = this.maze[0].length;
    }
}

const SOLVE_STATUS = {
    EXPLORING: 0,
    SOLVED: 1,
    FAILED: 2,
    RETRACING: 3
};

const DIRECTION = {
    UP: 0,
    RIGHT: 1,
    DOWN: 2,
    LEFT: 3
};

const INVERT_DIRECTION = {
    [DIRECTION.UP]: DIRECTION.DOWN,
    [DIRECTION.RIGHT]: DIRECTION.LEFT,
    [DIRECTION.DOWN]: DIRECTION.UP,
    [DIRECTION.LEFT]: DIRECTION.RIGHT
};

class MazeSolver {
    constructor(maze) {
        this.maze = maze;
        this.status = SOLVE_STATUS.EXPLORING;
        this.junction_memory = {};
        this.move_memory = [];
        this.last_direction = null;
        this.steps = 0;
    }

    adjacent() {
        let up, right, down, left;

        if (this.maze.robot.y === 0) {
            up = MAZE.WALL;
        } else {
            up = this.maze.maze[this.maze.robot.x][this.maze.robot.y - 1];
        }

        if (this.maze.robot.x === this.maze.width - 1) {
            right = MAZE.WALL;
        } else {
            right = this.maze.maze[this.maze.robot.x + 1][this.maze.robot.y];
        }

        if (this.maze.robot.y === this.maze.height - 1) {
            down = MAZE.WALL;
        } else {
            down = this.maze.maze[this.maze.robot.x][this.maze.robot.y + 1];
        }

        if (this.maze.robot.x === 0) {
            left = MAZE.WALL;
        } else {
            left = this.maze.maze[this.maze.robot.x - 1][this.maze.robot.y];
        }

        return {
            [DIRECTION.UP]: up,
            [DIRECTION.RIGHT]: right,
            [DIRECTION.DOWN]: down,
            [DIRECTION.LEFT]: left
        };
    }

    isSolved() {
        if (this.maze.maze[this.maze.robot.x][this.maze.robot.y] === MAZE.END) {
            return true;
        } else {
            return false;
        }
    }

    possibleNext(adjacent) {
        let possibilities = [];
        for (let key in adjacent) {
            if (adjacent[key] === MAZE.FREE || adjacent[key] === MAZE.END) {
                possibilities.push(parseInt(key));
            }
        }
        return possibilities;
    }

    isJunction(possibilities) {
        if (possibilities.length > 1) {
            return true;
        } else {
            return false;
        }
    }

    isDeadEnd(possibilities) {
        if (possibilities.length === 0) {
            return true;
        } else {
            return false;
        }
    }

    move(direction, log=true) {
        if (log) this.move_memory.push(direction);
        this.last_direction = direction;
        if (direction === DIRECTION.UP) {
            this.maze.robot.y -= 1;
        } else if (direction === DIRECTION.RIGHT) {
            this.maze.robot.x += 1;
        } else if (direction === DIRECTION.DOWN) {
            this.maze.robot.y += 1;
        } else if (direction === DIRECTION.LEFT) {
            this.maze.robot.x -= 1;
        }
    }

    explore(possibilities) {
        if (this.isJunction(possibilities)) {
            if (this.junction_memory[[this.maze.robot.x, this.maze.robot.y].toString()] === undefined) {
                // new junction!
                let direction = possibilities[0];
                this.junction_memory[[this.maze.robot.x, this.maze.robot.y].toString()] = [direction];
                // set down trail to avoid considering this a new junction if there is a loop
                this.maze.maze[this.maze.robot.x][this.maze.robot.y] = MAZE.TRAIL;
                this.move(direction);
            } else {
                // we already handled this junction before
                this.move(INVERT_DIRECTION[this.move_memory.pop()], false);
                this.maze.maze[this.maze.robot.x][this.maze.robot.y] = MAZE.FREE;
                this.status = SOLVE_STATUS.RETRACING;
            }
        } else if (this.isDeadEnd(possibilities)) {
            // move back to last position and THEN retrace: handles loops correctly
            this.move(INVERT_DIRECTION[this.move_memory.pop()], false);
            // remove trail
            this.maze.maze[this.maze.robot.x][this.maze.robot.y] = MAZE.FREE;
            this.status = SOLVE_STATUS.RETRACING;
        } else {
            // move to the next available space
            // but first, set down a trail tile (BEFORE moving)
            this.maze.maze[this.maze.robot.x][this.maze.robot.y] = MAZE.TRAIL;
            this.move(possibilities[0]);
        }
    }

    goBack() {
        if (this.maze.robot.x === this.maze.start.x && this.maze.robot.y === this.maze.start.y) {
            this.status = SOLVE_STATUS.FAILED;
        } else {
            let direction = INVERT_DIRECTION[this.move_memory.pop()];
            this.move(direction, false);
            // remove trail
            this.maze.maze[this.maze.robot.x][this.maze.robot.y] = MAZE.FREE;
        }
    }

    retrace(adjacent, possibilities) {
        if (this.isJunction(possibilities)) {
            // choose a direction we have not been in before, or continue retracing if there is none
            let junction_paths = this.junction_memory[[this.maze.robot.x, this.maze.robot.y].toString()];
            let direction = null;
            for (let possibility of possibilities) {
                // possibility that we have not been to before
                if (junction_paths.indexOf(possibility) === -1) {
                    direction = possibility;
                    break;
                }
            }
            if (direction === null) {
                // we have been everywhere possible from this junction
                this.goBack();
            } else {
                junction_paths.push(direction);
                this.maze.maze[this.maze.robot.x][this.maze.robot.y] = MAZE.TRAIL;
                this.status = SOLVE_STATUS.EXPLORING;
                this.move(direction);
            }
        } else {
            this.goBack();
        }
    }

    ai() {
        let adjacent = this.adjacent();
        let possibilities = this.possibleNext(adjacent);

        if (this.isSolved()) {
            this.status = SOLVE_STATUS.SOLVED;
            return;
        }

        if (this.status === SOLVE_STATUS.EXPLORING) {
            this.explore(possibilities);
        } else if (this.status === SOLVE_STATUS.RETRACING) {
            this.retrace(adjacent, possibilities);
        }
    }

    done() {
        if (this.status === SOLVE_STATUS.SOLVED || this.status === SOLVE_STATUS.FAILED) {
            return true;
        } else {
            return false;
        }
    }

    step() {
        if (!this.done()) {
            this.ai();
            this.steps += 1;
        }

        return this.status;
    }
}
<|endoftext|>


<commit_before>import gql from "graphql-tag"

// used in Availability component (homepage)
const GET_STOCK_TOTALS = gql`
  query StockList($cursor: Int!) {
    listPlasmids(input: { cursor: $cursor, limit: 30000 }) {
      totalCount
    }
    listStrains(input: { cursor: $cursor, limit: 30000 }) {
      totalCount
    }
  }
`

const GET_STRAIN_LIST = gql`
  query StrainList($cursor: Int!, $filter: String!) {
    listStrains(input: { cursor: $cursor, limit: 10, filter: $filter }) {
      nextCursor
      strains {
        id
        label
        summary
        in_stock
      }
    }
  }
`

const GET_PLASMID_LIST = gql`
  query PlasmidListFilter($cursor: Int!, $filter: String!) {
    listPlasmids(input: { cursor: $cursor, limit: 10, filter: $filter }) {
      nextCursor
      plasmids {
        id
        name
        summary
        in_stock
      }
    }
  }
`

const GET_RELATED_STRAINS = gql`
  query StrainList($filter: String!) {
    listStrains(input: { limit: 10, filter: $filter }) {
      strains {
        id
        label
      }
    }
  }
`

const GET_PLASMID = gql`
  query Plasmid($id: ID!) {
    plasmid(id: $id) {
      id
      name
      summary
      depositor
      publications {
        id
        doi
      }
      dbxrefs
      genes
      image_map
      sequence
      keywords
      genbank_accession
      in_stock
    }
  }
`

const GET_STRAIN = gql`
  query Strain($id: ID!) {
    strain(id: $id) {
      id
      label
      summary
      species
      parent {
        id
        label
      }
      depositor
      plasmid
      dbxrefs
      publications {
        id
        doi
      }
      genes
      in_stock
      systematic_name
      genotypes
      mutagenesis_method
      genetic_modification
      names
      characteristics
    }
  }
`

/**
 * query will still need these from annotations:
      phenotypes {
        phenotype
        note
        assay
        environment
        publication {
         doi
         id
        }
      }
 */

const LOGIN = gql`
  mutation Login($input: LoginInput!) {
    login(input: $input) {
      token
      user {
        id
        first_name
        last_name
        roles {
          role
          permissions {
            permission
          }
        }
      }
    }
  }
`

const POST_ORDER = gql`
  mutation CreateOrder($input: CreateOrderInput!) {
    createOrder(input: $input) {
      id
    }
  }
`

export {
  GET_STOCK_TOTALS,
  GET_STRAIN_LIST,
  GET_PLASMID_LIST,
  GET_RELATED_STRAINS,
  GET_STRAIN,
  GET_PLASMID,
  LOGIN,
  POST_ORDER,
}
<commit_msg>feat: add new queries for logout, refresh token<commit_after>import gql from "graphql-tag"

// used in Availability component (homepage)
const GET_STOCK_TOTALS = gql`
  query StockList($cursor: Int!) {
    listPlasmids(input: { cursor: $cursor, limit: 30000 }) {
      totalCount
    }
    listStrains(input: { cursor: $cursor, limit: 30000 }) {
      totalCount
    }
  }
`

const GET_STRAIN_LIST = gql`
  query StrainList($cursor: Int!, $filter: String!) {
    listStrains(input: { cursor: $cursor, limit: 10, filter: $filter }) {
      nextCursor
      strains {
        id
        label
        summary
        in_stock
      }
    }
  }
`

const GET_PLASMID_LIST = gql`
  query PlasmidListFilter($cursor: Int!, $filter: String!) {
    listPlasmids(input: { cursor: $cursor, limit: 10, filter: $filter }) {
      nextCursor
      plasmids {
        id
        name
        summary
        in_stock
      }
    }
  }
`

const GET_RELATED_STRAINS = gql`
  query StrainList($filter: String!) {
    listStrains(input: { limit: 10, filter: $filter }) {
      strains {
        id
        label
      }
    }
  }
`

const GET_PLASMID = gql`
  query Plasmid($id: ID!) {
    plasmid(id: $id) {
      id
      name
      summary
      depositor
      publications {
        id
        doi
      }
      dbxrefs
      genes
      image_map
      sequence
      keywords
      genbank_accession
      in_stock
    }
  }
`

const GET_STRAIN = gql`
  query Strain($id: ID!) {
    strain(id: $id) {
      id
      label
      summary
      species
      parent {
        id
        label
      }
      depositor
      plasmid
      dbxrefs
      publications {
        id
        doi
      }
      genes
      in_stock
      systematic_name
      genotypes
      mutagenesis_method
      genetic_modification
      names
      characteristics
    }
  }
`

/**
 * query will still need these from annotations:
      phenotypes {
        phenotype
        note
        assay
        environment
        publication {
         doi
         id
        }
      }
 */

const GET_REFRESH_TOKEN = gql`
  query GetRefreshToken($token: string!) {
    getRefreshToken(token: $token) {
      token
    }
  }
`

// MUTATIONS

const LOGIN = gql`
  mutation Login($input: LoginInput!) {
    login(input: $input) {
      token
      user {
        id
        first_name
        last_name
        roles {
          role
          permissions {
            permission
          }
        }
      }
    }
  }
`

const LOGOUT = gql`
  mutation Logout {
    logout {
      success
    }
  }
`

const POST_ORDER = gql`
  mutation CreateOrder($input: CreateOrderInput!) {
    createOrder(input: $input) {
      id
    }
  }
`

export {
  GET_STOCK_TOTALS,
  GET_STRAIN_LIST,
  GET_PLASMID_LIST,
  GET_RELATED_STRAINS,
  GET_STRAIN,
  GET_PLASMID,
  GET_REFRESH_TOKEN,
  LOGIN,
  LOGOUT,
  POST_ORDER,
}
<|endoftext|>


<commit_before>(function() {

  // Establish the root object, `window` in the browser, or `exports` on the server.
  var root = this;

  // from underscore.js
  function isUndefined(obj) {
    return obj === void 0;
  }

  function command(execFunc, undoFunc){
    var f = function(){
      return execFunc.apply(execFunc, arguments);
    };
    f.undo = undoFunc;
    return f;
  }

  function execute(command) {
    command();
    this.undoCommands.push(command);
    this.redoCommands = [];
  }

  function undo() {
    var command = this.undoCommands.pop();
    if (isUndefined(command)) return;
    command.undo();
    this.redoCommands.push(command);
  }

  function redo() {
    var command = this.redoCommands.pop();
    if (isUndefined(command)) return;
    command();
    this.undoCommands.push(command);
  }

  function unredo() {
    return {
      undoCommands: [],
      redoCommands: [],
      command: command,
      execute: execute,
      undo: undo,
      redo: redo
    };
  }

  unredo.command = command;

  root.unredo = unredo;

}.call(this));
<commit_msg>Refactor<commit_after>(function () {
  "use strict";

  // Establish the root object, `window` in the browser, or `exports` on the server.
  var root = this;

  var slice = Array.prototype.slice;

  function isUndefined(obj) {
    return obj === void 0;
  }

  function partial(func) {
    var args = slice.call(arguments, 1);
    return function() {
      return func.apply(this, args.concat(slice.call(arguments)));
    };
  }

  function command(execFunc, undoFunc){
    var f = function(){
      return execFunc.apply(execFunc, arguments);
    };
    f.undo = undoFunc;
    return f;
  }

  function execute(undoCommands, redoCommands, command) {
    command();
    undoCommands.push(command);
    redoCommands = [];
  }

  function undo(undoCommands, redoCommands) {
    var command = undoCommands.pop();
    if (isUndefined(command)) return;
    command.undo();
    redoCommands.push(command);
  }

  function redo(undoCommands, redoCommands) {
    var command = redoCommands.pop();
    if (isUndefined(command)) return;
    command();
    undoCommands.push(command);
  }

  function unredo() {
    var obj = {
      undoCommands: [],
      redoCommands: []
    };
    obj.command = command;
    obj.execute = partial(execute, obj.undoCommands, obj.redoCommands);
    obj.undo = partial(undo, obj.undoCommands, obj.redoCommands);
    obj.redo = partial(redo, obj.undoCommands, obj.redoCommands);
    return obj;
  }

  unredo.command = command;
  root.unredo = unredo;

}.call(this));
<|endoftext|>