<commit_before>/*global
 define, require, console
 */
/*jslint
 browser:true,
 vars: true,
 white: true
 */
define([
    'bluebird'
        // 'kb_types',
        // 'kb.runtime'
],
    function (Promise) {
        'use strict';

        function factory(config) {
            var plugins = {},
                runtime = config.runtime,
                services = {};

            /*
             * All of these installXXX installers return an array of
             * promises.
             */

            function registerService(serviceNames, serviceDef) {
                serviceNames.forEach(function (name) {
                    services[name] = serviceDef;
                });
            }
            function getService(name) {
                return services[name];
            }
//
//            function installMenus(menus) {
//                if (!menus) {
//                    return;
//                }
//                return menus.map(function (item) {
//                    return new Promise(function (resolve) {
//                        Runtime.send('navbar', 'add-menu-item', item);
//                        resolve();
//                    });
//                });
//            }
//
//            function installTypes(types) {
//                if (!types) {
//                    return;
//                }
//                return types.map(function (typeDef) {
//                    var type = typeDef.type,
//                        viewers = typeDef.viewers;
//                    viewers.forEach(function (viewerDef) {
//                        return new Promise(function (resolve) {
//                            Types.addViewer(type, viewerDef);
//                            resolve();
//                        });
//                    });
//                });
//            }
//
//            function installWidgets(widgets) {
//                /*
//                 *
//                 */
//                return [new Promise(function (resolve) {
//                        if (widgets) {
//                            widgets.forEach(function (widgetDef) {
//                                Runtime.addWidget(widgetDef);
//                            });
//                        }
//                        resolve();
//                    })];
//            }
//
//            function installBoot(cfg) {
//                return [new Promise(function (resolve) {
//                        /*
//                         * Send a message to the app manager to install this widget
//                         * at the root.
//                         */
//                        // just hard code this for now.
//                        // Runtime.setRootWidget('root');
//                        //if (cfg.mainWidget) {
//                        //    Runtime.addWidget({
////
//                        //    });
//                        //}
//                        //Runtime.setRootWidget(cfg.boot);
//                        resolve();
//
//                    })];
//            }

            function arrayExtend(to, from) {
                if (from) {
                    from.forEach(function (item) {
                        to.push(item);
                    });
                }
                return to;
            }

//            var services = {};
//            function addService(type, def) {
//
//            }
            function installIntoService(pluralTypeName, def) {
                return Promise.try(function () {
                    var typeName;
                    var m = pluralTypeName.match(/(.*?)(:?(s)|($))$/);
                    if (!m) {
                        return;
                    }
                    typeName = m[1];
                    if (!runtime.hasService(typeName)) {
                        console.log(runtime.dumpServices());
                        throw {
                            name: 'MissingService',
                            message: 'The requested service "' + typeName + '" was not registered in the plugin manager',
                            suggestion: 'This is a web app configuration issue, not a user error'
                        };
                    }
                    var service = runtime.getService(typeName);
                    // console.log('SERVICE'); console.log(typeName); console.log(service);
                    if (service.pluginHandler) {
                        return service.pluginHandler(def);
                    }
                });
            }

            function installPlugin(pluginLocation, pluginDef) {
                // build up a list of modules and add them to the require config.
                return new Promise(function (resolve, reject) {
                    var paths = {},
                        shims = {},
                        sourcePath = pluginLocation.directory,
                        dependencies = [];

                    // load any styles.
                    // NB these are styles for the plugin as a whole.
                    // TODO: do away with this. the styles should be dependencies
                    // of the panel and widgets. widget css code is below...
                    if (pluginDef.source.styles) {
                        pluginDef.source.styles.forEach(function (style) {
                            if (style.file) {
                                dependencies.push('css!' + sourcePath + '/resources/css/' + style.file);
                            }
                        });
                    }

                    // Add each module defined to the require config paths.
                    pluginDef.source.modules.forEach(function (source) {
                        var jsSourceFile = source.file,
                            matched = jsSourceFile.match(/^(.+?)(?:(?:\.js$)|(?:$))/);
                        if (matched) {
                            jsSourceFile = matched[1];
                            var sourceFile = sourcePath + '/modules/' + jsSourceFile;
                            paths[source.module] = sourceFile;
                            // A module may also have an accompanying css file, which will
                            // be added as a dependency via shims.
                            if (source.css) {
                                var styleModule = source.module + '_css';
                                paths[styleModule] = sourceFile;
                                shims[source.module] = {deps: ['css!' + styleModule]};
                            }
                        }
                    });

                    // This usage of require.config will merge with the existing
                    // require configuration.
                    require.config({paths: paths, shim: shims});

                    // Create a dynamic module for the plugin to use. The current use
                    // case is for code within the plugin to have access to the path
                    // to the plugin for loading other files.
                    //
                    // NB: this implies that the plugin package name is unique in
                    // the system. To enforce or at least help developers with this
                    // we should have a plugin registry.
                    define('kb_plugin_' + pluginDef.package.name, [], function () {
                        return {
                            plugin: {
                                path: '/' + sourcePath + '/resources'
                            }
                        };
                    });

                    // Now install any routes.
                    if (pluginDef.install) {
                        require(dependencies, function () {
                            var installSteps = [];

                            Object.keys(pluginDef.install).forEach(function (serviceName) {
                                var installDef = pluginDef.install[serviceName],
                                    intallationPromise = installIntoService(serviceName, installDef);
                                arrayExtend(installSteps, [intallationPromise]);
                            });
                            // Do all of the install steps.
                            Promise.all(installSteps)
                                .then(function (doneSteps) {
//                                    doneSteps.forEach(function (step) {
//                                        if (step.isRejected()) {
//                                            console.log('install step error for ' + pluginLocation.name);
//                                            console.log(step.reason());
//                                        }
//                                    })
                                    resolve();
                                })
                                .catch(function (err) {
                                    console.log('ERROR');
                                    console.log(err);
                                    reject(err);
                                });
                        });
                    } else {
                        console.log('No installation?');
                        resolve();
                    }
                });
            }
            function makePromiseIterator(actions) {
                var x = 0;
                return new Promise(function (topResolve, topReject) {
                    function promiseIterator(actions) {
                        var iter = String(x);
                        x += 1;
                        if (actions === undefined || actions.length === 0) {
                            topResolve('DONE');
                        }
                        var next = actions[0],
                            rest = actions.slice(1);
                        Promise.try(function () {
                            return new Promise(function (resolve, reject, notify) {
                                next(resolve, reject, notify);
                            });
                        }).then(function (result) {
                            promiseIterator(rest);
                        }).catch(function (err) {
                            topReject(err);
                        });
                    }
                    promiseIterator(actions);
                });
            }

            /**
             *
             * @param {type} pluginDef
             * @returns {Promise}
             */
            function loadPlugin(pluginNameOrLocation) {
                var pluginLocation;
                if (typeof pluginNameOrLocation === 'string') {
                    pluginLocation = {
                        name: pluginNameOrLocation,
                        directory: 'plugins/' + pluginNameOrLocation
                    };
                } else {
                    pluginLocation = pluginNameOrLocation;
                }
                return new Promise(function (resolve, reject) {
                    require(['yaml!' + pluginLocation.directory + '/config.yml'], function (pluginConfig) {
                        installPlugin(pluginLocation, pluginConfig)
                            .then(function () {
                                resolve(pluginLocation);
                            })
                            .catch(function (err) {
                                reject(err);
                            });
                    });
                });
            }

            function installPlugins(pluginDefs) {
                var loaders = pluginDefs.map(function (plugin) {
                    return loadPlugin(plugin);
                });
                return Promise.settle(loaders);
            }

            // plugins are in an array of arrays. each top level array is processed
            // strictly in sequential order.
            function installPluginSets(pluginDefs) {
                var loadSets = pluginDefs.map(function (set) {
                    return function (resolve, reject, notify) {
                        installPlugins(set)
                            .then(function () {
                                resolve();
                            })
                            .catch(function (err) {
                                reject(err);
                            });
                    };
                });

                return makePromiseIterator(loadSets);
            }

            return {
                installPlugins: installPlugins,
                installPluginSets: installPluginSets,
                registerService: registerService
            };
        }
        return {
            make: function (config) {
                return factory(config);
            }
        };
    });<commit_msg>moved back to kbase-common-js<commit_after><|endoftext|>


<commit_before>/*  This file is part of Iain Hamiltons Isometric HTML5 App.

    Iain Hamiltons Isometric HTML5 App is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Iain Hamiltons Isometric HTML5 App is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Iain Hamiltons Isometric HTML5 App.  If not, see <http://www.gnu.org/licenses/>. */

function XMLPopulate() {
	var xmlDoc;

	this.loadXML = function (fileName) {
        xmlhttp=new XMLHttpRequest();
		xmlhttp.open("GET",fileName,false);
		xmlhttp.send();
		xmlDoc=xmlhttp.responseXML;

    };

	this.getContent = function(name,container){
		var tempArray = Array();
		var generatedArray = Array();
		var row;
		var toGet = xmlDoc.getElementsByTagName(name)[0];
		for(var i=0;i<toGet.getElementsByTagName(container).length;i++){
			 var rowSplit = toGet.getElementsByTagName(container)[i].childNodes[0].nodeValue;
			 rowSplit = rowSplit.split(",");
				for(var j=0;j<rowSplit.length;j++){
					tempArray.push(rowSplit[j]);
				}
				generatedArray.push(tempArray);
				tempArray =[];
		}
		return generatedArray;
	};

	this.getAttribute = function(name,attribute,node){
		if(!node){node =0;}
		var toGet = xmlDoc.getElementsByTagName(name)[node];
		attribute = toGet.attributes.getNamedItem(attribute).value;
		return attribute;
	};

	this.length = function(name){
		return xmlDoc.getElementsByTagName(name).length;
	}

  this.saveMap = function (id, groundTiles, heightTiles, objectTiles) {
    var groundMap ="";
    for(var i =0;i<groundTiles.length;i++){
      groundMap += "<row>";
			for(var j=0;j<groundTiles[i].length;j++){
				groundMap += groundTiles[i][j];
				if(j!= groundTiles[i].length-1){
          groundMap += ",";
        }
			}
			groundMap += "</row>";
		}

    var heightMap ="";
    for(var i =0;i<heightTiles.length;i++){
      heightMap += "<row>";
      for(var j=0;j<heightTiles[i].length;j++){
        heightMap += heightTiles[i][j];
        if(j!= heightTiles[i].length-1){
          heightMap += ",";
        }
      }
      heightMap += "</row>";
    }

    var objectMap ="";
    for(var i =0;i<objectTiles.length;i++){
      objectMap += "<row>";
      for(var j=0;j<objectTiles[i].length;j++){
        objectMap += objectTiles[i][j];
        if(j!= objectTiles[i].length-1){
          objectMap += ",";
        }
      }
      objectMap += "</row>";
    }

    xmlhttp=new XMLHttpRequest();
    data = "id=" + id + "&groundMap=" + groundMap + "&heightMap=" + heightMap + "&objectMap=" + objectMap;

    xmlhttp.open("POST","map-save.php",true);
    xmlhttp.setRequestHeader("Connection", "close");
    xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

    xmlhttp.onreadystatechange = function() {
      if(xmlhttp.readyState == 4 && xmlhttp.status == 200) {
        alert("Map Saved");
      }
    };
    xmlhttp.send(data);
  };

}

<commit_msg>Update XMLPopulate.js<commit_after>/*  Copyright 2013 Iain Hamitlon & Edward Smyth

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

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

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

function XMLPopulate() {
	var xmlDoc;

	this.loadXML = function (fileName) {
        xmlhttp=new XMLHttpRequest();
		xmlhttp.open("GET",fileName,false);
		xmlhttp.send();
		xmlDoc=xmlhttp.responseXML;

    };

	this.getContent = function(name,container){
		var tempArray = Array();
		var generatedArray = Array();
		var row;
		var toGet = xmlDoc.getElementsByTagName(name)[0];
		for(var i=0;i<toGet.getElementsByTagName(container).length;i++){
			 var rowSplit = toGet.getElementsByTagName(container)[i].childNodes[0].nodeValue;
			 rowSplit = rowSplit.split(",");
				for(var j=0;j<rowSplit.length;j++){
					tempArray.push(rowSplit[j]);
				}
				generatedArray.push(tempArray);
				tempArray =[];
		}
		return generatedArray;
	};

	this.getAttribute = function(name,attribute,node){
		if(!node){node =0;}
		var toGet = xmlDoc.getElementsByTagName(name)[node];
		attribute = toGet.attributes.getNamedItem(attribute).value;
		return attribute;
	};

	this.length = function(name){
		return xmlDoc.getElementsByTagName(name).length;
	}

  this.saveMap = function (id, groundTiles, heightTiles, objectTiles) {
    var groundMap ="";
    for(var i =0;i<groundTiles.length;i++){
      groundMap += "<row>";
			for(var j=0;j<groundTiles[i].length;j++){
				groundMap += groundTiles[i][j];
				if(j!= groundTiles[i].length-1){
          groundMap += ",";
        }
			}
			groundMap += "</row>";
		}

    var heightMap ="";
    for(var i =0;i<heightTiles.length;i++){
      heightMap += "<row>";
      for(var j=0;j<heightTiles[i].length;j++){
        heightMap += heightTiles[i][j];
        if(j!= heightTiles[i].length-1){
          heightMap += ",";
        }
      }
      heightMap += "</row>";
    }

    var objectMap ="";
    for(var i =0;i<objectTiles.length;i++){
      objectMap += "<row>";
      for(var j=0;j<objectTiles[i].length;j++){
        objectMap += objectTiles[i][j];
        if(j!= objectTiles[i].length-1){
          objectMap += ",";
        }
      }
      objectMap += "</row>";
    }

    xmlhttp=new XMLHttpRequest();
    data = "id=" + id + "&groundMap=" + groundMap + "&heightMap=" + heightMap + "&objectMap=" + objectMap;

    xmlhttp.open("POST","map-save.php",true);
    xmlhttp.setRequestHeader("Connection", "close");
    xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

    xmlhttp.onreadystatechange = function() {
      if(xmlhttp.readyState == 4 && xmlhttp.status == 200) {
        alert("Map Saved");
      }
    };
    xmlhttp.send(data);
  };

}

<|endoftext|>


<commit_before>//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// Sets color range of data, if applicable
//-------------------------------------------------------------------

d3plus.data.color = function(vars) {

  if (vars.color.key && typeof vars.color.key == "object") {
    if (vars.color.key[vars.id.key]) {
      var color_id = vars.color.key[vars.id.key]
    }
    else {
      var color_id = vars.color.key[Object.keys(vars.color.key)[0]]
    }
  }
  else {
    var color_id = vars.color.key
  }

  if (vars.data.value && color_id && vars.data.keys[color_id] == "number" && (vars.color.changed || vars.data.changed || vars.depth.changed || vars.time.solo.changed || vars.time.mute.changed)) {

    if (vars.dev.value) d3plus.console.group("Calculating Color Scale")

    if (vars.dev.value) d3plus.console.time("get data range")

    var data_range = []
    vars.data.pool.forEach(function(d){
      var val = parseFloat(d3plus.variable.value(vars,d,color_id))
      if (typeof val == "number" && !isNaN(val) && data_range.indexOf(val) < 0) data_range.push(val)
    })

    if (vars.dev.value) d3plus.console.timeEnd("get data range")

    if (data_range.length > 1) {

      var data_domain = null

      if (vars.dev.value) d3plus.console.time("create color scale")

      data_range = d3.extent(data_range)

      if (data_range[0] < 0 && data_range[1] > 0) {
        var color_range = vars.style.color.range
        data_range.push(data_range[1])
        data_range[1] = 0
      }
      else if (data_range[1] > 0 || data_range[0] < 0) {
        var color_range = vars.style.color.heatmap
        data_range = d3plus.utils.buckets(data_range,color_range.length)
      }
      else {
        var color_range = vars.style.color.range.slice(0)
      }

      vars.color_scale = d3.scale.sqrt()
        .domain(data_range)
        .range(color_range)
        .interpolate(d3.interpolateRgb)

      if (vars.dev.value) d3plus.console.timeEnd("create color scale")

    }
    else {
      vars.color_scale = null
    }

    if (vars.dev.value) d3plus.console.groupEnd()

  }
  else {
    vars.color_scale = null
  }

}
<commit_msg>fix for color scale disappearing on update<commit_after>//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// Sets color range of data, if applicable
//-------------------------------------------------------------------
d3plus.data.color = function(vars) {

  if (vars.color.key && typeof vars.color.key == "object") {
    if (vars.color.key[vars.id.key]) {
      var color_id = vars.color.key[vars.id.key]
    }
    else {
      var color_id = vars.color.key[Object.keys(vars.color.key)[0]]
    }
  }
  else {
    var color_id = vars.color.key
  }

  if (vars.data.value && color_id && vars.data.keys[color_id] == "number" && (vars.color.changed || vars.data.changed || vars.depth.changed || vars.time.solo.changed || vars.time.mute.changed)) {

    if (vars.dev.value) d3plus.console.group("Calculating Color Scale")

    if (vars.dev.value) d3plus.console.time("get data range")

    var data_range = []
    vars.data.pool.forEach(function(d){
      var val = parseFloat(d3plus.variable.value(vars,d,color_id))
      if (typeof val == "number" && !isNaN(val) && data_range.indexOf(val) < 0) data_range.push(val)
    })

    if (vars.dev.value) d3plus.console.timeEnd("get data range")

    if (data_range.length > 1) {

      var data_domain = null

      if (vars.dev.value) d3plus.console.time("create color scale")

      data_range = d3.extent(data_range)

      if (data_range[0] < 0 && data_range[1] > 0) {
        var color_range = vars.style.color.range
        data_range.push(data_range[1])
        data_range[1] = 0
      }
      else if (data_range[1] > 0 || data_range[0] < 0) {
        var color_range = vars.style.color.heatmap
        data_range = d3plus.utils.buckets(data_range,color_range.length)
      }
      else {
        var color_range = vars.style.color.range.slice(0)
      }

      vars.color_scale = d3.scale.sqrt()
        .domain(data_range)
        .range(color_range)
        .interpolate(d3.interpolateRgb)

      if (vars.dev.value) d3plus.console.timeEnd("create color scale")

    }
    else {
      vars.color_scale = null
    }

    if (vars.dev.value) d3plus.console.groupEnd()

  }
  else if (!color_id || (color_id && vars.data.keys[color_id] != "number")) {
    vars.color_scale = null
  }

}
<|endoftext|>


<commit_before>export const patterns = [{
	name:"Date in format dd/mm/yyyy",
	regex:/^(0?[1-9]|[12][0-9]|3[01])([ /\-])(0?[1-9]|1[012])\2(19[0-9][0-9]|20[0-9][0-9])$/,
	description:"Will match dates with dashes, slashes or with spaces dd-mm-yyyy dd/mm/yyyy dd mm yyyy",
	tags:"date time"
},
{
	name:"HTML tags",
	regex:/^<([a-z0-9]+)([^<]+)*(?:>(.*)<\/\1>|\s+\/>)$/,
	description:"Match opening and closing HTML tags with content between",
	tags:"markup,xml,html"
},
{
	name:"Username",
	regex:/^[a-zA-Z0-9_-]{3,16}$/,
	description:"A string between 3 and 16 characters, allowing alphanumeric characters and hyphens and underscores",
	tags:"username,validation"
},
{
	name:"Password",
	regex:/^[a-zA-Z0-9+_-]{6,18}$/,
	description:"A string between 6 and 18 characters, allowing alphanumeric characters and hypehns and underscores",
	tags:"password,validation"
},
{
	name:"Hex Value",
	regex:/^#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/,
	description:"Base 16 numbers, such as RGB values",
	tags:"hex,color"
},
{
	name:"URL Slug",
	regex:/^[a-z0-9-]+$/,
	description:"Match valid URL slugs",
	tags:"URL"
},
{
	name:"Email",
	regex:/^([a-z0-9+_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,24})$/,
	description:"Match standards complient email addresses",
	tags:"email,validation"
},
{
	name:"SRC of image tag",
	regex:/\< *[img][^\>]*[src] *= *[\"\']{0,1}([^\"\'\ >]*)/,
	description:"Match the src attribute of an HTML image tag",
	tags:"html,tag,image"
},
{
	name:"URL",
	regex:/^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/,
	description:"Match URL with optional protocal",
	tags:"url,address,http"
},
{
	name:"IPv4 Address",
	regex:/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/,
	description:"Match IP v4 addresses",
	tags:"tcpip,internet,address"
},
{
	name:"Positive Integer",
	regex:/^\d+$/,
	descriptions:"Match whole numbers above zero",
	tags:"number"
},
{
	name:"Negative Integer",
	regex:/^-\d+$/,
	description:"Match whole numbers below zero",
	tags:"number"
},
{
	name:"Integer",
	regex:/^-?\d+$/,
	description:"Match whole numbers, above or below zero",
	tags:"number"
},
{
	name:"Positive number",
	regex:/^\d*\.?\d+$/,
	description:"Match integers or floats that are positive",
	tags:"float"
},
{
	name:"Negative number",
	regex:/^-\d*\.?\d+$/,
	description:"Match integers or floats that are negative",
	tags:"float"
},
{
	name:"Positive or negative number",
	regex:/^-?\d*\.?\d+$/,
	description:"Match integers or floats that are positive or negative",
	tags:"float"
},
{
	name:"Phone number",
	regex:/^\+?[\d\s]{3,}$/,
	description:"Match phone numbers at least 3 digits long",
	tags:"validation"
},
{
	name:"New line",
	regex:/[\r\n]|$/,
	description:"Match new lines within text",
	tags:"text"
},
{
	name:"ID of Youtube video",
	regex:/https?:\/\/(?:youtu\.be\/|(?:[a-z]{2,3}\.)?youtube\.com\/watch(?:\?|#\!)v=)([\w-]{11}).*/gi,
	description:"Match the ID of a youtube video URL",
	tags:"video,youtube,url"
},
{
	name:"CSS comment",
	regex:/\/\*[^*]*\*+([^/*][^*]*\*+)*\//,
	description:"Match standard CSS comments",
	tags:"css,comment,code"
}/*,
{
	name:"Word exception",
	regex:/\bTarzan\b|\bJane\b|\bSuperman\b|(\w+)/,
	description:"Match all words apart from the ones listed",
	tags:"words,sentence,blacklist"
}*/
];
<commit_msg>update html tag for h1 to h6<commit_after>export const patterns = [{
	name:"Date in format dd/mm/yyyy",
	regex:/^(0?[1-9]|[12][0-9]|3[01])([ /\-])(0?[1-9]|1[012])\2(19[0-9][0-9]|20[0-9][0-9])$/,
	description:"Will match dates with dashes, slashes or with spaces dd-mm-yyyy dd/mm/yyyy dd mm yyyy",
	tags:"date time"
},
{
	name:"HTML tags",
	regex:/^<([a-z1-6]+)([^<]+)*(?:>(.*)<\/\1>|\s+\/>)$/,
	description:"Match opening and closing HTML tags with content between",
	tags:"markup,xml,html"
},
{
	name:"Username",
	regex:/^[a-zA-Z0-9_-]{3,16}$/,
	description:"A string between 3 and 16 characters, allowing alphanumeric characters and hyphens and underscores",
	tags:"username,validation"
},
{
	name:"Password",
	regex:/^[a-zA-Z0-9+_-]{6,18}$/,
	description:"A string between 6 and 18 characters, allowing alphanumeric characters and hypehns and underscores",
	tags:"password,validation"
},
{
	name:"Hex Value",
	regex:/^#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/,
	description:"Base 16 numbers, such as RGB values",
	tags:"hex,color"
},
{
	name:"URL Slug",
	regex:/^[a-z0-9-]+$/,
	description:"Match valid URL slugs",
	tags:"URL"
},
{
	name:"Email",
	regex:/^([a-z0-9+_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,24})$/,
	description:"Match standards complient email addresses",
	tags:"email,validation"
},
{
	name:"SRC of image tag",
	regex:/\< *[img][^\>]*[src] *= *[\"\']{0,1}([^\"\'\ >]*)/,
	description:"Match the src attribute of an HTML image tag",
	tags:"html,tag,image"
},
{
	name:"URL",
	regex:/^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/,
	description:"Match URL with optional protocal",
	tags:"url,address,http"
},
{
	name:"IPv4 Address",
	regex:/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/,
	description:"Match IP v4 addresses",
	tags:"tcpip,internet,address"
},
{
	name:"Positive Integer",
	regex:/^\d+$/,
	descriptions:"Match whole numbers above zero",
	tags:"number"
},
{
	name:"Negative Integer",
	regex:/^-\d+$/,
	description:"Match whole numbers below zero",
	tags:"number"
},
{
	name:"Integer",
	regex:/^-?\d+$/,
	description:"Match whole numbers, above or below zero",
	tags:"number"
},
{
	name:"Positive number",
	regex:/^\d*\.?\d+$/,
	description:"Match integers or floats that are positive",
	tags:"float"
},
{
	name:"Negative number",
	regex:/^-\d*\.?\d+$/,
	description:"Match integers or floats that are negative",
	tags:"float"
},
{
	name:"Positive or negative number",
	regex:/^-?\d*\.?\d+$/,
	description:"Match integers or floats that are positive or negative",
	tags:"float"
},
{
	name:"Phone number",
	regex:/^\+?[\d\s]{3,}$/,
	description:"Match phone numbers at least 3 digits long",
	tags:"validation"
},
{
	name:"New line",
	regex:/[\r\n]|$/,
	description:"Match new lines within text",
	tags:"text"
},
{
	name:"ID of Youtube video",
	regex:/https?:\/\/(?:youtu\.be\/|(?:[a-z]{2,3}\.)?youtube\.com\/watch(?:\?|#\!)v=)([\w-]{11}).*/gi,
	description:"Match the ID of a youtube video URL",
	tags:"video,youtube,url"
},
{
	name:"CSS comment",
	regex:/\/\*[^*]*\*+([^/*][^*]*\*+)*\//,
	description:"Match standard CSS comments",
	tags:"css,comment,code"
}/*,
{
	name:"Word exception",
	regex:/\bTarzan\b|\bJane\b|\bSuperman\b|(\w+)/,
	description:"Match all words apart from the ones listed",
	tags:"words,sentence,blacklist"
}*/
];
<|endoftext|>


<commit_before>"use strict";

var destroyBlockandLogStreamer = require("./block-management/destroy-block-and-log-streamer");
var internalState = require("./internal-state");

function disconnect() {
  return function (dispatch) {
    dispatch(destroyBlockandLogStreamer());

    internalState.get("transporter").close();
  };
}

module.exports = disconnect;
<commit_msg>Check if transporter exists<commit_after>"use strict";

var destroyBlockandLogStreamer = require("./block-management/destroy-block-and-log-streamer");
var internalState = require("./internal-state");

function disconnect() {
  return function (dispatch) {
    dispatch(destroyBlockandLogStreamer());

    if (internalState.get("transporter") !== null) internalState.get("transporter").close();
  };
}

module.exports = disconnect;
<|endoftext|>


<commit_before>'use strict'

const co = require('co')
const cli = require('heroku-cli-util')

function * run (context, heroku) {
  const sortBy = require('lodash.sortby')
  const partition = require('lodash.partition')

  let org = (!context.flags.personal && context.org) ? context.org : null
  let space = context.flags.space
  if (space) org = (yield heroku.get(`/spaces/${space}`)).organization.name

  function regionizeAppName (app) {
    if (app.region && app.region.name !== 'us') {
      return `${app.name} (${cli.color.green(app.region.name)})`
    } else {
      return app.name
    }
  }

  let isNotOrgApp = (app) => !app.owner.email.endsWith('@herokumanager.com')

  function listApps (apps) {
    apps.forEach((app) => cli.log(regionizeAppName(app)))
    cli.log()
  }

  function print (apps, user) {
    if (apps.length === 0) {
      if (space) cli.log(`There are no apps in space ${cli.color.green(space)}.`)
      else if (org) cli.log(`There are no apps in organization ${cli.color.magenta(org)}.`)
      else cli.log('You have no apps.')
      return
    } else if (space) {
      cli.styledHeader(`Apps in space ${cli.color.green(space)}`)
      listApps(apps)
    } else if (org) {
      cli.styledHeader(`Apps in organization ${cli.color.magenta(org)}`)
      listApps(apps)
    } else {
      apps = partition(apps, (app) => app.owner.email === user.email)
      if (apps[0].length > 0) {
        cli.styledHeader(`${cli.color.cyan(user.email)} Apps`)
        listApps(apps[0])
      }

      if (apps[1].length > 0) {
        cli.styledHeader('Collaborated Apps')
        cli.table(apps[1], {
          printHeader: false,
          columns: [
            {key: 'name', get: regionizeAppName},
            {key: 'owner.email'}
          ]
        })
      }
    }
  }

  let requests = yield {
    apps: org ? heroku.get(`/organizations/${org}/apps`) : heroku.get('/apps'),
    user: heroku.get('/account')
  }
  let apps = sortBy(requests.apps, 'name')
  if (!context.flags.all && !org && !space) apps = apps.filter(isNotOrgApp)
  if (space) apps = apps.filter((a) => a.space && (a.space.name === space || a.space.id === space))

  if (context.flags.json) {
    cli.styledJSON(apps)
  } else {
    print(apps, requests.user)
  }
}

let cmd = {
  description: 'list your apps',
  help: `
Example:

 $ heroku apps
 === My Apps
 example
 example2

 === Collaborated Apps
 theirapp   other@owner.name`,
  needsAuth: true,
  wantsOrg: true,
  flags: [
    {name: 'all', char: 'A', description: 'include apps in all organizations'},
    {name: 'json', description: 'output in json format'},
    {name: 'space', hasValue: true, description: 'filter by space', hidden: true},
    {name: 'personal', char: 'p', description: 'list apps in personal account when a default org is set'}
  ],
  run: cli.command(co.wrap(run))
}

module.exports = [
  Object.assign({topic: 'apps'}, cmd),
  Object.assign({command: 'list', hidden: true}, cmd),
  Object.assign({topic: 'apps', command: 'list', hidden: true}, cmd)
]
<commit_msg>fix list alias<commit_after>'use strict'

const co = require('co')
const cli = require('heroku-cli-util')

function * run (context, heroku) {
  const sortBy = require('lodash.sortby')
  const partition = require('lodash.partition')

  let org = (!context.flags.personal && context.org) ? context.org : null
  let space = context.flags.space
  if (space) org = (yield heroku.get(`/spaces/${space}`)).organization.name

  function regionizeAppName (app) {
    if (app.region && app.region.name !== 'us') {
      return `${app.name} (${cli.color.green(app.region.name)})`
    } else {
      return app.name
    }
  }

  let isNotOrgApp = (app) => !app.owner.email.endsWith('@herokumanager.com')

  function listApps (apps) {
    apps.forEach((app) => cli.log(regionizeAppName(app)))
    cli.log()
  }

  function print (apps, user) {
    if (apps.length === 0) {
      if (space) cli.log(`There are no apps in space ${cli.color.green(space)}.`)
      else if (org) cli.log(`There are no apps in organization ${cli.color.magenta(org)}.`)
      else cli.log('You have no apps.')
      return
    } else if (space) {
      cli.styledHeader(`Apps in space ${cli.color.green(space)}`)
      listApps(apps)
    } else if (org) {
      cli.styledHeader(`Apps in organization ${cli.color.magenta(org)}`)
      listApps(apps)
    } else {
      apps = partition(apps, (app) => app.owner.email === user.email)
      if (apps[0].length > 0) {
        cli.styledHeader(`${cli.color.cyan(user.email)} Apps`)
        listApps(apps[0])
      }

      if (apps[1].length > 0) {
        cli.styledHeader('Collaborated Apps')
        cli.table(apps[1], {
          printHeader: false,
          columns: [
            {key: 'name', get: regionizeAppName},
            {key: 'owner.email'}
          ]
        })
      }
    }
  }

  let requests = yield {
    apps: org ? heroku.get(`/organizations/${org}/apps`) : heroku.get('/apps'),
    user: heroku.get('/account')
  }
  let apps = sortBy(requests.apps, 'name')
  if (!context.flags.all && !org && !space) apps = apps.filter(isNotOrgApp)
  if (space) apps = apps.filter((a) => a.space && (a.space.name === space || a.space.id === space))

  if (context.flags.json) {
    cli.styledJSON(apps)
  } else {
    print(apps, requests.user)
  }
}

let cmd = {
  description: 'list your apps',
  help: `
Example:

 $ heroku apps
 === My Apps
 example
 example2

 === Collaborated Apps
 theirapp   other@owner.name`,
  needsAuth: true,
  wantsOrg: true,
  flags: [
    {name: 'all', char: 'A', description: 'include apps in all organizations'},
    {name: 'json', description: 'output in json format'},
    {name: 'space', hasValue: true, description: 'filter by space', hidden: true},
    {name: 'personal', char: 'p', description: 'list apps in personal account when a default org is set'}
  ],
  run: cli.command(co.wrap(run))
}

module.exports = [
  Object.assign({topic: 'apps'}, cmd),
  Object.assign({topic: 'list', hidden: true}, cmd),
  Object.assign({topic: 'apps', command: 'list', hidden: true}, cmd)
]
<|endoftext|>


<commit_before>/* eslint strict: [2, global] */

'use strict';

const path = require('path');
const co = require('co');
const glob = require('glob');
const Request = require('./request');
const Stash = require('./stash');
const Notify = require('./notify');
const Diff = require('./diff');

class Dumpinator {
  static run(config) {
    const parallelRequests = 2;
    const jobs = [];
    const notify = new Notify();
    const routes = config.getRoutes();

    routes.forEach((test) => {
      if (config.options.debug) {
        console.log('[DEBUG] add route:', test); // eslint-disable-line no-console
      }

      notify.addTest(test);
      jobs.push(co(function* task() {
        const request = new Request();
        let response;
        try {
          response = yield request.load(test);
        } catch (err) {
          notify.setState(test, 'download-failed', err.message);
          return;
        }

        const stash = new Stash(path.join(__dirname, `../tmp/${test.id}-${test.side}.json`));
        yield stash.add(response);
        notify.setState(test, 'downloaded');

        if (test.status && test.status !== response.meta.status) {
          notify.setState(test, 'failed', `HTTP status code ${test.status} expected, but got ${response.meta.status}`);

          return;
        }

        if (notify.getState(test) === 'downloaded') {
          const testResult = yield Dumpinator.compare(test);
          if (testResult === null) {
            notify.setTestPassed(test);
          } else {
            notify.setTestFailed(test);
          }
        } else if (notify.getState(test) === 'download-failed') {
          notify.setTestFailed(test);
        }
      }));
    });

    this.parallelize(jobs, parallelRequests).then((res) => {
      notify.finish();
    }).catch((err) => {
      notify.error(err);
      throw err;
    });

    return notify;
  }

  /**
   *
   * Runs n promises in parallel
   *
   * @method parallelize
   *
   * @param  {array} jobs Promise queue. Must be an array of promises
   * @param  {number} numParallel Number of jobs in parallel
   *
   * @return {Object} Returns a promise after last job hast been done
   */
  static parallelize(jobs, numParallel) {
    numParallel = numParallel || 2;
    const slots = [];
    const results = [];
    const beer = 'full';

    for (let i = 0; i < numParallel; i += 1) {
      slots.push(co(function* slotGenerator() {
        while (beer !== 'empty') { // it never gets empty ;)
          const next = jobs.shift();
          if (!next) {
            return; // we're done. Lets have a coffee :)
          }

          const res = yield next;
          results.push(res);
        }
      }));
    }

    return Promise.all(slots).then(() => results);
  }

  static report(notify) {
    const Reporter = require('./reporter/cli-reporter'); // eslint-disable-line global-require
    const reporter = new Reporter();
    return reporter.report(notify);
  }

  static compare(test) {
    return Promise.all(['left', 'right'].map((side) => {
      const stash = new Stash(path.join(__dirname, `../tmp/${test.id}-${side}.json`));
      return stash.fetch();
    })).then((res) => {
      const diff = new Diff();
      const headerDiff = diff.compare(res[0].headers, res[1].headers, test.ignoreHeader, true);
      if (!headerDiff) {
        return 'Headers doesn\'t match';
      }

      const bodyDiff = diff.compare(res[0].body, res[1].body, test.ignoreBody);
      if (!bodyDiff) {
        return 'Bodies doesn\'t match';
      }

      return null;
    });
  }

  static diff(testId) {
    const stashDir = path.join(__dirname, '../tmp/');
    return co(function* dumpinatorDiff() {
      const testFiles = glob.sync(`${testId}*-left.json`, { cwd: stashDir });

      if (testFiles.length === 0) {
        return {
          type: 'error',
          code: 1001,
          msg: 'No tests found. Check the id.'
        };
      } else if (testFiles.length > 1) {
        return {
          type: 'error',
          code: 1002,
          msg: 'Multiple tests found. Provide a unique id.',
          testFiles
        };
      }

      const leftStash = new Stash(path.join(stashDir, testFiles[0]));
      const left = yield leftStash.fetch();

      const rightStash = new Stash(path.join(stashDir, testFiles[0].replace('-left', '-right')));
      const right = yield rightStash.fetch();

      const diff = new Diff();
      return {
        type: 'diff',
        bodyDiff: yield diff.diff(left.body, right.body),
        headerDiff: yield diff.diff(left.headers, right.headers)
      };
    });
  }

  static reportDiff(diff, options) {
    const Reporter = require('./reporter/cli-reporter'); // eslint-disable-line global-require
    const reporter = new Reporter(options);
    reporter.diff(diff);
  }
}

module.exports = Dumpinator;
<commit_msg>Typo fix<commit_after>/* eslint strict: [2, global] */

'use strict';

const path = require('path');
const co = require('co');
const glob = require('glob');
const Request = require('./request');
const Stash = require('./stash');
const Notify = require('./notify');
const Diff = require('./diff');

class Dumpinator {
  static run(config) {
    const parallelRequests = 2;
    const jobs = [];
    const notify = new Notify();
    const routes = config.getRoutes();

    routes.forEach((test) => {
      if (config.options.debug) {
        console.log('[DEBUG] add route:', test); // eslint-disable-line no-console
      }

      notify.addTest(test);
      jobs.push(co(function* task() {
        const request = new Request();
        let response;
        try {
          response = yield request.load(test);
        } catch (err) {
          notify.setState(test, 'download-failed', err.message);
          return;
        }

        const stash = new Stash(path.join(__dirname, `../tmp/${test.id}-${test.side}.json`));
        yield stash.add(response);
        notify.setState(test, 'downloaded');

        if (test.status && test.status !== response.meta.status) {
          notify.setState(test, 'failed', `HTTP status code ${test.status} expected, but got ${response.meta.status}`);

          return;
        }

        if (notify.getState(test) === 'downloaded') {
          const testResult = yield Dumpinator.compare(test);
          if (testResult === null) {
            notify.setTestPassed(test);
          } else {
            notify.setTestFailed(test);
          }
        } else if (notify.getState(test) === 'download-failed') {
          notify.setTestFailed(test);
        }
      }));
    });

    this.parallelize(jobs, parallelRequests).then((res) => {
      notify.finish();
    }).catch((err) => {
      notify.error(err);
      throw err;
    });

    return notify;
  }

  /**
   *
   * Runs n promises in parallel
   *
   * @method parallelize
   *
   * @param  {array} jobs Promise queue. Must be an array of promises
   * @param  {number} numParallel Number of jobs in parallel
   *
   * @return {Object} Returns a promise after last job hast been done
   */
  static parallelize(jobs, numParallel) {
    numParallel = numParallel || 2;
    const slots = [];
    const results = [];
    const beer = 'full';

    for (let i = 0; i < numParallel; i += 1) {
      slots.push(co(function* slotGenerator() {
        while (beer !== 'empty') { // it never gets empty ;)
          const next = jobs.shift();
          if (!next) {
            return; // we're done. Lets have a coffee :)
          }

          const res = yield next;
          results.push(res);
        }
      }));
    }

    return Promise.all(slots).then(() => results);
  }

  static report(notify) {
    const Reporter = require('./reporter/cli-reporter'); // eslint-disable-line global-require
    const reporter = new Reporter();
    return reporter.report(notify);
  }

  static compare(test) {
    return Promise.all(['left', 'right'].map((side) => {
      const stash = new Stash(path.join(__dirname, `../tmp/${test.id}-${side}.json`));
      return stash.fetch();
    })).then((res) => {
      const diff = new Diff();
      const headerDiff = diff.compare(res[0].headers, res[1].headers, test.ignoreHeader, true);
      if (!headerDiff) {
        return 'Headers don\'t match';
      }

      const bodyDiff = diff.compare(res[0].body, res[1].body, test.ignoreBody);
      if (!bodyDiff) {
        return 'Bodies don\'t match';
      }

      return null;
    });
  }

  static diff(testId) {
    const stashDir = path.join(__dirname, '../tmp/');
    return co(function* dumpinatorDiff() {
      const testFiles = glob.sync(`${testId}*-left.json`, { cwd: stashDir });

      if (testFiles.length === 0) {
        return {
          type: 'error',
          code: 1001,
          msg: 'No tests found. Check the id.'
        };
      } else if (testFiles.length > 1) {
        return {
          type: 'error',
          code: 1002,
          msg: 'Multiple tests found. Provide a unique id.',
          testFiles
        };
      }

      const leftStash = new Stash(path.join(stashDir, testFiles[0]));
      const left = yield leftStash.fetch();

      const rightStash = new Stash(path.join(stashDir, testFiles[0].replace('-left', '-right')));
      const right = yield rightStash.fetch();

      const diff = new Diff();
      return {
        type: 'diff',
        bodyDiff: yield diff.diff(left.body, right.body),
        headerDiff: yield diff.diff(left.headers, right.headers)
      };
    });
  }

  static reportDiff(diff, options) {
    const Reporter = require('./reporter/cli-reporter'); // eslint-disable-line global-require
    const reporter = new Reporter(options);
    reporter.diff(diff);
  }
}

module.exports = Dumpinator;
<|endoftext|>


<commit_before>let Database = require('./../../utils/database.js');

module.exports = {
    usage: 'Changes the current prefix to the inputted term. Spaces cannot be used.\n`prefix [new prefix]`',
    dm: false,
    delete: false,
    togglable: false,
    cooldown: 20,
    process: (msg, args) => {
        return new Promise(resolve => {
            Database.changePrefix(msg.channel.guild.id, args).then(() => {
                resolve({
                    message: "📋 Successfully changed prefix to `" + args + "` 📋",
                    delete: true
                })
            }).catch(err => {
                resolve({
                    message: "⛔ " + err + " ⛔",
                    delete: true
                })
            })
        });
    }
}<commit_msg>Commented prefix.js<commit_after>let Database = require('./../../utils/database.js');

module.exports = {
    usage: 'Changes the current prefix to the inputted term. Spaces cannot be used.\n`prefix [new prefix]`',
    dm: false,
    delete: false,
    togglable: false,
    cooldown: 20,
    process: (msg, args) => {
        return new Promise(resolve => {
            //Changes guild prefix to the entered args
            Database.changePrefix(msg.channel.guild.id, args).then(() => {
                //If successful
                resolve({
                    message: "📋 Successfully changed prefix to `" + args + "` 📋",
                    delete: true
                })
            }).catch(err => {
                //If rejected
                resolve({
                    message: "⛔ " + err + " ⛔",
                    delete: true
                })
            })
        });
    }
}<|endoftext|>


<commit_before>const GReYBot = require('../greybot');

exports.commands = [
	'prune',
	'kick'
]

var lastPruned = new Date().getTime() - (GReYBot.Config.pruneInterval * 1000);

exports.prune = {
	usage: '<count|1-100>',
	process: (msg, suffix) => {
		var count = parseInt(suffix) || 0;

		if (msg.member.hasPermission('MANAGE_MESSAGES')) {
			var timeSinceLastPrune = Math.floor(new Date().getTime() - lastPruned);
			console.log(timeSinceLastPrune);
			if (timeSinceLastPrune > (GReYBot.Config.pruneInterval * 1000)) {
				count++;
				if (count > 1) {
					if (count > GReYBot.Config.pruneMax) count = GReYBot.Config.pruneMax;

					msg.channel.fetchMessages({ limit: count })
						.then(messages => messages.map(m => m.delete()))
						.then(function () {
							msg.channel.send({
								embed: {
									color: GReYBot.Config.defaultEmbedColor,
									description: `Pruning ${count - 1} messages...`
								}
							}).then(message => message.delete(5000));
						});

					lastPruned = new Date().getTime();
				}
			}
			else {
				var wait = Math.floor(GReYBot.Config.pruneInterval - (timeSinceLastPrune / 1000));
				msg.channel.send({
					embed: {
						color: GReYBot.Config.defaultEmbedColor,
						description: `You can't do that yet, please wait ${wait} second${wait > 1 ? "s" : ""}`
					}
				}).then(message => message.delete(5000));
			}
		}
		else {
			msg.channel.send({
				embed: {
					color: GReYBot.Config.defaultEmbedColor,
					description: `You can't do that ${msg.member}...`
				}
			}).then(message => message.delete(5000));
		}
	}
}

exports.kick = {
	usage: '<user> <reason>',
	description: 'Kick a user with an optional reason. Requires both the command user and the bot to have kick permission',
	process: (bot, msg, suffix) => {
		let args = suffix.split(" ");
		if (args.length > 0 && args[0]) {
			let hasPermissonToKick =  msg.guild.members.get(bot.user.id).permissions.has("KICK_MEMBERS");
			if (!hasPermissonToKick) {
				msg.channel.send( "I don't have permission to kick people!");
				return;
			}
			if (!msg.guild.members.get(msg.author.id).permissions.has("KICK_MEMBERS")) {
				msg.channel.send( "You don't have permission to kick people!");
				return;
			}
			var targetId = resolveMention(args[0]);
			let target = msg.guild.members.get(targetId);
			if (target != undefined) {
				if (!target.kickable) {
					msg.channel.send("I can't kick " + target + ". Do they have the same or a higher role than me?");
					return;
				}
				if (args.length > 1) {
					let reason = args.slice(1).join(" ");
					target.kick(reason).then(x => {
						msg.channel.send("Kicking " + target + " from " + msg.guild + " for " + reason + "!");
					}).catch(err => msg.channel.send("Kicking " + target + " failed:\n"));
				} else {
					target.kick().then(x => {
						msg.channel.send("Kicking " + target + " from " + msg.guild + "!");
					}).catch(err => msg.channel.send("Kicking " + target + " failed:\n"));
				}
			} else {
				msg.channel.send("I couldn't find a user " + args[0]);
			}
		} else {
			msg.channel.send("You must specify a user to kick!");
		}
	}
}
<commit_msg>fixed kick command to actually work<commit_after>const GReYBot = require('../greybot');

exports.commands = [
	'prune',
	'kick'
]

var lastPruned = new Date().getTime() - (GReYBot.Config.pruneInterval * 1000);

function resolveMention(usertxt){
	var userid = usertxt;
	if(usertxt.startsWith('<@!')){
		userid = usertxt.substr(3,usertxt.length-4);
	} else {
		if(usertxt.startsWith('<@')){
			userid = usertxt.substr(2,usertxt.length-3);
		}
	}
	return userid;
}

exports.prune = {
	usage: '<count|1-100>',
	process: (msg, suffix) => {
		var count = parseInt(suffix) || 0;

		if (msg.member.hasPermission('MANAGE_MESSAGES')) {
			var timeSinceLastPrune = Math.floor(new Date().getTime() - lastPruned);
			console.log(timeSinceLastPrune);
			if (timeSinceLastPrune > (GReYBot.Config.pruneInterval * 1000)) {
				count++;
				if (count > 1) {
					if (count > GReYBot.Config.pruneMax) count = GReYBot.Config.pruneMax;

					msg.channel.fetchMessages({ limit: count })
						.then(messages => messages.map(m => m.delete()))
						.then(function () {
							msg.channel.send({
								embed: {
									color: GReYBot.Config.defaultEmbedColor,
									description: `Pruning ${count - 1} messages...`
								}
							}).then(message => message.delete(5000));
						});

					lastPruned = new Date().getTime();
				}
			}
			else {
				var wait = Math.floor(GReYBot.Config.pruneInterval - (timeSinceLastPrune / 1000));
				msg.channel.send({
					embed: {
						color: GReYBot.Config.defaultEmbedColor,
						description: `You can't do that yet, please wait ${wait} second${wait > 1 ? "s" : ""}`
					}
				}).then(message => message.delete(5000));
			}
		}
		else {
			msg.channel.send({
				embed: {
					color: GReYBot.Config.defaultEmbedColor,
					description: `You can't do that ${msg.member}...`
				}
			}).then(message => message.delete(5000));
		}
	}
}

exports.kick = {
	usage: '<user> <reason>',
	description: 'Kick a user with an optional reason. Requires both the command user and the bot to have kick permission',
	process: (msg, suffix) => {
		let args = suffix.split(" ");
		if (args.length > 0 && args[0]) {
			let hasPermissonToKick =  msg.guild.me.hasPermission("KICK_MEMBERS");
			if (!hasPermissonToKick) {
				msg.channel.send( "I don't have permission to kick people!");
				return;
			}
			if (!msg.member.hasPermission("KICK_MEMBERS")) {
				msg.channel.send( "You don't have permission to kick people!");
				return;
			}
			let targetId = resolveMention(args[0]);
			msg.guild.fetchMember(targetId).then(member => {
				if (member != undefined) {
					if (!member.kickable) {
						msg.channel.send("I can't kick " + member + ". Do they have the same or a higher role than me?");
						return;
					}
					if (args.length > 1) {
						let reason = args.slice(1).join(" ");
						member.kick(reason).then(x => {
							msg.channel.send("Kicking " + member + " from " + msg.guild + " for " + reason + "!");
						}).catch(err => msg.channel.send("Kicking " + member + " failed:\n"));
					} else {
						member.kick().then(x => {
							msg.channel.send("Kicking " + member + " from " + msg.guild + "!");
						}).catch(err => msg.channel.send("Kicking " + member + " failed:\n"));
					}
				} else {
					msg.channel.send("I couldn't find a user " + args[0]);
				}
			});
		} else {
			msg.channel.send("You must specify a user to kick!");
		}
	}
}
<|endoftext|>


<commit_before>//gets the info for a server
module.exports = function command(bot, info)
{
  'use strict';
  return {
    name: 'Server Info',
    inline: false,
    //the alias can be set by putting what you'd like in that array
    alias: ['si'],
    //description that shows up in the help menu
    description: 'Gets information on the current server.',
    //set the permissions [public, elevated, mod, private]
    permissions: 'public',
    action: function(details)
    {

      const getInfo = function(uid)
      {
        let emb = {};
        let server = bot.servers[details.serverID];
        let safe = false;
        if(server != undefined)
        {
          emb.title = server.name + "'s Info";
          emb.description = '\n _ _';
          let thumbnail = {url: getIcon(details.serverID)};
          emb.thumbnail = thumbnail;
          let fields = [];
          emb.color = server.members[server.owner_id].color;
          //owner
          let owner = {name: 'Owner', value: `${bot.users[server.owner_id].username}#${bot.users[server.owner_id].discriminator}`};
          fields.push(owner);
          //reagion
          let region = {name: 'Region', value: server.region};
          fields.push(region);
          //creation time
          let created = {name: 'Created', value: getCreatedTime(server.id)};
          fields.push(created);
          //channel info
          let channels = {name: 'Channels', value: getChannelInfo(server.channels) };
          fields.push(channels);
          //member count
          let members = {name: 'Members', value: `${server.member_count} Members`};
          fields.push(members);
          //roles
          let serverRoles = {name: 'Roles', value: Object.keys(server.roles).map(x => server.roles[x].name).join(', ')};
          fields.push(serverRoles);
          emb.fields = fields;

          return emb;
        }
        else
        {
          emb.title = 'Error';
          emb.description = 'You are either not in a server, or there was an error looking up server info.';
          emb.color = 0xFF0000;
          return emb;
        }
      };
      const getChannelInfo = function(channels)
      {
        let voice = 0;
        let text = 0;
        Object.keys(channels).forEach((key) =>
        {
          if(channels[key].type == undefined)
          {
            text ++;
          }
          else
          {
            if(channels[key].type == 'text')
            {
              text ++;
            }
            else
            {
              voice ++;
            }
          }
        });
        return `${text} Text, ${voice} Voice`;
      };
      const getRoles = function(server)
      {
        const maxLength = 1014;
        const roles = Object.keys(server.roles).map(x => server.roles[x].name).join(', ');
        let numRoles = undefined;
        if(roles.length > maxLength)
        {
          numRoles = Object.keys(server.roles).length;
          return `${numRoles} Roles`;
        }
        else
        {
          return roles;
        }
      };
      const getCreatedTime = function(uid)
      {
        let t = (uid / 4194304) + 1420070400000;
        let created = new Date(t);
        return `${created.toUTCString()}`;
      };
      const getJoinedTime = function(uid)
      {
        let d = new Date(bot.servers[details.serverID].members[details.userID].joined_at);
        let localOffset = 5 * 60000;
        let utc = d.getTime() + localOffset;
        let dUTC = new Date(utc);
        return `${d.toUTCString()}`;

      };
      const getIcon = function(sid)
      {
        return `https://cdn.discordapp.com/icons/${sid}/${bot.servers[sid].icon}.jpg`;
      };
      //console.log(details.input);
      if(details.input === '')
      {
        bot.sendMessage({
          to: details.channelID,
          embed: getInfo(details.userID)
        });
      }
      else if(details.args.length == 2)
      {
        let uid = info.utility.stripUID(details.args[1]);
        if(uid)
        {
          let link = getAvatar(uid);
          if(link.includes('null.jpg'))
          {
            bot.sendMessage({
              to: details.channelID,
              message: 'The user has a default avatar.'
            });
          }
          else
          {
            bot.sendMessage({
              to: details.channelID,
              embed: getInfo(uid)
            });
          }
        }
      }
      else
      {
        bot.sendMessage({
          to: details.channelID,
          message: 'Please look at the help menu to see how to properly use the command.'
        });
      }
    }
  };
};<commit_msg>Server Info command fixed<commit_after>//gets the info for a server
module.exports = function command(bot, info)
{
  'use strict';
  return {
    name: 'Server Info',
    inline: false,
    //the alias can be set by putting what you'd like in that array
    alias: ['si'],
    //description that shows up in the help menu
    description: 'Gets information on the current server.',
    //set the permissions [public, elevated, mod, private]
    permissions: 'public',
    action: function(details)
    {

      const getInfo = function(uid)
      {

        let emb = {};
        let server = bot.servers[details.serverID];
        let safe = false;
        if(server != undefined)
        {
          emb.title = server.name + "'s Info";
          emb.description = '\n _ _';
          let thumbnail = {url: getIcon(details.serverID)};
          emb.thumbnail = thumbnail;
          let fields = [];
          emb.color = server.members[server.owner_id].color;
          //owner
          let owner = {name: 'Owner', value: `${bot.users[server.owner_id].username}#${bot.users[server.owner_id].discriminator}`};
          fields.push(owner);
          //reagion
          let region = {name: 'Region', value: server.region};
          fields.push(region);
          //creation time
          let created = {name: 'Created', value: getCreatedTime(server.id)};
          fields.push(created);
          //channel info
          let channels = {name: 'Channels', value: getChannelInfo(server.channels) };
          fields.push(channels);
          //member count
          let members = {name: 'Members', value: `${server.member_count} Members`};
          fields.push(members);
          //roles
          let serverRoles = {name: 'Roles', value: getRoles(bot.servers[details.serverID])};
          fields.push(serverRoles);
          emb.fields = fields;

          return emb;
        }
        else
        {
          emb.title = 'Error';
          emb.description = 'You are either not in a server, or there was an error looking up server info.';
          emb.color = 0xFF0000;
          return emb;
        }
      };
      const getChannelInfo = function(channels)
      {
        let voice = 0;
        let text = 0;
        Object.keys(channels).forEach((key) =>
        {
          if(channels[key].type == undefined)
          {
            text ++;
          }
          else
          {
            if(channels[key].type == 'text')
            {
              text ++;
            }
            else
            {
              voice ++;
            }
          }
        });
        return `${text} Text, ${voice} Voice`;
      };
      const getRoles = function(server)
      {
        const maxLength = 1014;
        const roles = Object.keys(server.roles).map(x => server.roles[x].name).join(', ');
        let numRoles = undefined;
        if(roles.length > maxLength)
        {
          numRoles = Object.keys(server.roles).length;
          return `${numRoles} Roles`;
        }
        else
        {
          return roles;
        }
      };
      const getCreatedTime = function(uid)
      {
        let t = (uid / 4194304) + 1420070400000;
        let created = new Date(t);
        return `${created.toUTCString()}`;
      };
      const getJoinedTime = function(uid)
      {
        let d = new Date(bot.servers[details.serverID].members[details.userID].joined_at);
        let localOffset = 5 * 60000;
        let utc = d.getTime() + localOffset;
        let dUTC = new Date(utc);
        return `${d.toUTCString()}`;

      };
      const getIcon = function(sid)
      {
        return `https://cdn.discordapp.com/icons/${sid}/${bot.servers[sid].icon}.jpg`;
      };
      //console.log(details.input);
      if(details.input === '')
      {
        bot.sendMessage({
          to: details.channelID,
          embed: getInfo(details.userID)
        });
      }
      else if(details.args.length == 2)
      {
        let uid = info.utility.stripUID(details.args[1]);
        if(uid)
        {
          let link = getAvatar(uid);
          if(link.includes('null.jpg'))
          {
            bot.sendMessage({
              to: details.channelID,
              message: 'The user has a default avatar.'
            });
          }
          else
          {
            bot.sendMessage({
              to: details.channelID,
              embed: getInfo(uid)
            });
          }
        }
      }
      else
      {
        bot.sendMessage({
          to: details.channelID,
          message: 'Please look at the help menu to see how to properly use the command.'
        });
      }
    }
  };
};<|endoftext|>


<commit_before>'use strict';

const Command = require('../../models/Command.js');

class SetModRole extends Command {
  constructor(bot) {
    super(bot, 'settings.setModRole', 'set mod', 'Sets the server\'s mod role.');
    this.usages = [
      { description: 'Change the configured mod role', parameters: ['mod role id'] },
    ];
    this.regex = new RegExp(`^${this.call}\\s?(?:(?:<#)(\\d+)(?:>))?$`, 'i');
    this.requiresAuth = true;
    this.allowDM = false;
  }

  /**
   * Run the command
   * @param {Message} message Message with a command to handle, reply to,
   *                          or perform an action based on parameters.
   * @returns {string} success status
   */
  async run(message) {
    const roleId = message.strippedContent.match(this.regex)[1];
    if (roleId && message.guild.roles.has(roleId.trim())) {
      await this.settings.setGuildSetting(message.guild, 'modRole', roleId);
      this.messageManager.notifySettingsChange(message, true, true);
      return this.messageManager.statuses.SUCCESS;
    }
    await this.settings.deleteGuildSetting(message.guild, 'modRole');
    this.messageManager.notifySettingsChange(message, true, true);
    return this.messageManager.statuses.SUCCESS;
  }
}

module.exports = SetModRole;
<commit_msg>fix for set mod role issue<commit_after>'use strict';

const Command = require('../../models/Command.js');

class SetModRole extends Command {
  constructor(bot) {
    super(bot, 'settings.setModRole', 'set mod', 'Sets the server\'s mod role.');
    this.usages = [
      { description: 'Change the configured mod role', parameters: ['mod role id'] },
    ];
    this.regex = new RegExp(`^${this.call}\\s?(?:(?:<@&)(\\d+)(?:>))?$`, 'i');
    this.requiresAuth = true;
    this.allowDM = false;
  }

  /**
   * Run the command
   * @param {Message} message Message with a command to handle, reply to,
   *                          or perform an action based on parameters.
   * @returns {string} success status
   */
  async run(message) {
    const roleId = message.strippedContent.match(this.regex)[1];
    if (roleId && message.guild.roles.has(roleId.trim())) {
      await this.settings.setGuildSetting(message.guild, 'modRole', roleId);
      this.messageManager.notifySettingsChange(message, true, true);
      return this.messageManager.statuses.SUCCESS;
    }
    await this.settings.deleteGuildSetting(message.guild, 'modRole');
    this.messageManager.notifySettingsChange(message, true, true);
    return this.messageManager.statuses.SUCCESS;
  }
}

module.exports = SetModRole;
<|endoftext|>


<commit_before>const { Argument, Command } = require('discord-akairo');
const { db } = require('../../struct/Database');
const Starboard = require('../../struct/Starboard');

class TopStarsCommand extends Command {
	constructor() {
		super('topStars', {
			aliases: ['top-stars', 'top-star', 'star-top', 'stars-top'],
			category: 'starboard',
			channel: 'guild',
			clientPermissions: ['EMBED_LINKS'],
			quoted: false,
			args: [
				{
					'id': 'page',
					'type': Argument.range('integer', 0, Infinity),
					'default': 1,
					'prompt': {
						start: 'Invalid page. Which page would you like to view?',
						retry: 'Please provide a valid page number.',
						optional: true
					}
				}
			],
			description: {
				content: 'Displays a list of users sorted by how many stars they have in the guild.',
				usage: '[page]',
				examples: ['', '3']
			}
		});

		this.perPage = 10;
	}

	async exec(message, { page }) {
		const starboard = this.client.starboards.get(message.guild.id);

		if (!starboard.channel) {
			const prefix = this.handler.prefix(message);
			return message.util.reply(`There isn't a starboard channel to use. Set one using the \`${prefix}starboard\` command!`);
		}

		const total = Number((await db.query(`
			SELECT
				COUNT(DISTINCT "authorID")
			FROM stars WHERE "guildID" = :guildID
		`, {
			type: db.Sequelize.QueryTypes.SELECT,
			replacements: { guildID: message.guild.id }
		}))[0].count);

		const topStars = await db.query(`
			SELECT
				SUM("starCount") AS amount,
				"authorID"
			FROM stars
			WHERE "guildID" = :guildID
			GROUP BY "authorID" ORDER BY amount DESC
			OFFSET :offset
			LIMIT :limit
		`, {
			type: db.Sequelize.QueryTypes.SELECT,
			replacements: {
				guildID: message.guild.id,
				offset: (page - 1) * this.perPage,
				limit: this.perPage
			}
		});

		const users = await Promise.all(topStars.map(async row => {
			const user = await this.client.users.fetch(row.authorID).catch(() => ({ tag: 'Unknown#????' }));

			return {
				tag: user.tag,
				amount: row.amount
			};
		}));

		const embed = this.client.util.embed()
			.setColor(0xFFAC33)
			.setTitle(`Star Leaderboard — Page ${page} of ${Math.ceil(total / this.perPage)}`);

		if (users.length) {
			const desc = users
				.map(({ tag, amount }, index) => `${1 + index + ((page - 1) * this.perPage)}. **${tag} ::** ${amount} ${Starboard.getEscapedStarEmoji(amount)}`);

			embed.setDescription(desc);
		} else {
			embed.setTitle('Star Leaderboard')
				.setDescription('*Nothing to show here yet...*');
		}

		return message.util.send({ embed });
	}
}

module.exports = TopStarsCommand;
<commit_msg>Fix page range (#14)<commit_after>const { Argument, Command } = require('discord-akairo');
const { db } = require('../../struct/Database');
const Starboard = require('../../struct/Starboard');

class TopStarsCommand extends Command {
	constructor() {
		super('topStars', {
			aliases: ['top-stars', 'top-star', 'star-top', 'stars-top'],
			category: 'starboard',
			channel: 'guild',
			clientPermissions: ['EMBED_LINKS'],
			quoted: false,
			args: [
				{
					'id': 'page',
					'type': Argument.range('integer', 1, Infinity),
					'default': 1,
					'prompt': {
						start: 'Invalid page. Which page would you like to view?',
						retry: 'Please provide a valid page number.',
						optional: true
					}
				}
			],
			description: {
				content: 'Displays a list of users sorted by how many stars they have in the guild.',
				usage: '[page]',
				examples: ['', '3']
			}
		});

		this.perPage = 10;
	}

	async exec(message, { page }) {
		const starboard = this.client.starboards.get(message.guild.id);

		if (!starboard.channel) {
			const prefix = this.handler.prefix(message);
			return message.util.reply(`There isn't a starboard channel to use. Set one using the \`${prefix}starboard\` command!`);
		}

		const total = Number((await db.query(`
			SELECT
				COUNT(DISTINCT "authorID")
			FROM stars WHERE "guildID" = :guildID
		`, {
			type: db.Sequelize.QueryTypes.SELECT,
			replacements: { guildID: message.guild.id }
		}))[0].count);

		const topStars = await db.query(`
			SELECT
				SUM("starCount") AS amount,
				"authorID"
			FROM stars
			WHERE "guildID" = :guildID
			GROUP BY "authorID" ORDER BY amount DESC
			OFFSET :offset
			LIMIT :limit
		`, {
			type: db.Sequelize.QueryTypes.SELECT,
			replacements: {
				guildID: message.guild.id,
				offset: (page - 1) * this.perPage,
				limit: this.perPage
			}
		});

		const users = await Promise.all(topStars.map(async row => {
			const user = await this.client.users.fetch(row.authorID).catch(() => ({ tag: 'Unknown#????' }));

			return {
				tag: user.tag,
				amount: row.amount
			};
		}));

		const embed = this.client.util.embed()
			.setColor(0xFFAC33)
			.setTitle(`Star Leaderboard — Page ${page} of ${Math.ceil(total / this.perPage)}`);

		if (users.length) {
			const desc = users
				.map(({ tag, amount }, index) => `${1 + index + ((page - 1) * this.perPage)}. **${tag} ::** ${amount} ${Starboard.getEscapedStarEmoji(amount)}`);

			embed.setDescription(desc);
		} else {
			embed.setTitle('Star Leaderboard')
				.setDescription('*Nothing to show here yet...*');
		}

		return message.util.send({ embed });
	}
}

module.exports = TopStarsCommand;
<|endoftext|>


<commit_before>import { createStore, applyMiddleware, compose } from 'redux';
import createSagaMiddleware from 'redux-saga';
import invariant from 'redux-immutable-state-invariant';
import { persistStore, persistReducer, createTransform } from 'redux-persist';
import autoMergeLevel2 from 'redux-persist/lib/stateReconciler/autoMergeLevel2';
import getStoredStateMigrateV4 from 'redux-persist/lib/integration/getStoredStateMigrateV4';
import applyAppStateListener from 'redux-enhancer-react-native-appstate';
import FileSystemStorage from 'redux-persist-filesystem-storage';
import AsyncStorage from '@react-native-community/async-storage';
import rootReducer from '../reducers';
import rootSaga from '../sagas';
import getStoredStateMigrateToFileSystemStorage from './getStoredStateMigrateToFileSystemStorage';

const myTransform = createTransform(
  (inboundState, key, state) => {
    switch (key) {
      case 'entities': {
        const {
          entities,
          browsingHistoryIllusts,
          browsingHistoryNovels,
          muteUsers,
        } = state;
        const selectedUsersEntities = {};
        const selectedIllustsEntities = browsingHistoryIllusts.items
          .filter(id => entities.illusts[id])
          .reduce((prev, id) => {
            prev[id] = entities.illusts[id];
            const userId = entities.illusts[id].user;
            selectedUsersEntities[userId] = entities.users[userId];
            return prev;
          }, {});
        const selectedNovelsEntities = browsingHistoryNovels.items
          .filter(id => entities.novels[id])
          .reduce((prev, id) => {
            prev[id] = entities.novels[id];
            const userId = entities.novels[id].user;
            selectedUsersEntities[userId] = entities.users[userId];
            return prev;
          }, {});
        const selectedUsersEntities2 = muteUsers.items
          .filter(id => entities.users[id])
          .reduce((prev, id) => {
            prev[id] = entities.users[id];
            return prev;
          }, {});
        const finalSelectedUsersEntities = {
          ...selectedUsersEntities,
          ...selectedUsersEntities2,
        };
        return {
          ...inboundState,
          illusts: selectedIllustsEntities,
          novels: selectedNovelsEntities,
          users: finalSelectedUsersEntities,
        };
      }
      case 'browsingHistoryIllusts': {
        const { entities, browsingHistoryIllusts } = state;
        return {
          ...inboundState,
          items: browsingHistoryIllusts.items.filter(
            id =>
              entities.illusts[id] &&
              entities.illusts[id].user &&
              entities.users[entities.illusts[id].user],
          ),
        };
      }
      case 'browsingHistoryNovels': {
        const { entities, browsingHistoryNovels } = state;
        return {
          ...inboundState,
          items: browsingHistoryNovels.items.filter(
            id =>
              entities.novels[id] &&
              entities.novels[id].user &&
              entities.users[entities.novels[id].user],
          ),
        };
      }
      default:
        return inboundState;
    }
  },
  outboundState => outboundState,
  {
    whitelist: [
      'entities',
      'browsingHistoryIllusts',
      'browsingHistoryNovels',
      'muteUsers',
    ],
  },
);

const clearV4PersistedContents = () =>
  AsyncStorage.getAllKeys((err, keys) => {
    if (!err && keys && keys.length) {
      const keyPrefix = 'persist:root';
      const v5PersistKeys = keys.filter(key => key.indexOf(keyPrefix) === 0);
      if (v5PersistKeys.length) {
        AsyncStorage.multiRemove(v5PersistKeys, () => Promise.resolve());
      } else {
        const v4KeyPrefix = 'reduxPersist:';
        const v4PersistKeys = keys.filter(
          key => key.indexOf(v4KeyPrefix) === 0,
        );
        if (v4PersistKeys.length) {
          AsyncStorage.multiRemove(v4PersistKeys, () => Promise.resolve());
        }
      }
    }
    return Promise.resolve();
  });

export default function configureStore() {
  let enhancer;
  const sagaMiddleware = createSagaMiddleware();
  if (process.env.NODE_ENV !== 'production') {
    const composeEnhancers =
      // eslint-disable-next-line no-underscore-dangle
      window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
    enhancer = composeEnhancers(
      applyAppStateListener(),
      applyMiddleware(invariant(), sagaMiddleware),
      // devTools(),
    );
  } else {
    enhancer = compose(
      applyAppStateListener(),
      applyMiddleware(sagaMiddleware),
    );
  }

  const v4Config = {
    whitelist: [
      'searchHistory',
      'browsingHistoryIllusts',
      'browsingHistoryNovels',
      'highlightTags',
      'muteTags',
      'muteUsers',
      'saveImageSettings',
      'novelSettings',
      'entities',
      'auth',
      'i18n',
    ],
    storage: AsyncStorage,
    transforms: [myTransform],
  };

  const v5Config = {
    key: 'root',
    stateReconciler: autoMergeLevel2,
    whitelist: [
      'searchHistory',
      'browsingHistoryIllusts',
      'browsingHistoryNovels',
      'highlightTags',
      'muteTags',
      'muteUsers',
      'saveImageSettings',
      'initialScreenSettings',
      'novelSettings',
      'entities',
      'auth',
      'i18n',
      'theme',
    ],
    storage: AsyncStorage,
    transforms: [myTransform],
    getStoredState: getStoredStateMigrateV4(v4Config),
  };

  const persistConfig = {
    key: 'root',
    timeout: 15000, // https://github.com/rt2zz/redux-persist/issues/717
    stateReconciler: autoMergeLevel2,
    whitelist: [
      'searchHistory',
      'browsingHistoryIllusts',
      'browsingHistoryNovels',
      'highlightTags',
      'muteSettings',
      'muteTags',
      'muteUsers',
      'saveImageSettings',
      'initialScreenSettings',
      'novelSettings',
      'likeButtonSettings',
      'entities',
      'auth',
      'i18n',
      'theme',
    ],
    storage: FileSystemStorage,
    transforms: [myTransform],
    getStoredState: getStoredStateMigrateToFileSystemStorage(
      v5Config,
      v4Config,
    ),
    debug: process.env.NODE_ENV !== 'production',
  };
  const persistedReducer = persistReducer(persistConfig, rootReducer);
  const store = createStore(persistedReducer, undefined, enhancer);
  sagaMiddleware.run(rootSaga);

  const persistor = persistStore(store, undefined, clearV4PersistedContents);
  if (module.hot) {
    // eslint-disable-next-line global-require
    const nextRootReducer = require('../reducers');
    module.hot.accept(() => {
      store.replaceReducer(persistReducer(persistConfig, nextRootReducer));
    });
  }

  return { store, persistor };
}
<commit_msg>Migrate old persisted initialScreenSettings from SCREENS.Ranking to SCREENS.RankingPreview<commit_after>import { createStore, applyMiddleware, compose } from 'redux';
import createSagaMiddleware from 'redux-saga';
import invariant from 'redux-immutable-state-invariant';
import { persistStore, persistReducer, createTransform } from 'redux-persist';
import autoMergeLevel2 from 'redux-persist/lib/stateReconciler/autoMergeLevel2';
import getStoredStateMigrateV4 from 'redux-persist/lib/integration/getStoredStateMigrateV4';
import applyAppStateListener from 'redux-enhancer-react-native-appstate';
import FileSystemStorage from 'redux-persist-filesystem-storage';
import AsyncStorage from '@react-native-community/async-storage';
import rootReducer from '../reducers';
import rootSaga from '../sagas';
import getStoredStateMigrateToFileSystemStorage from './getStoredStateMigrateToFileSystemStorage';
import { SCREENS } from '../constants';

const myTransform = createTransform(
  (inboundState, key, state) => {
    switch (key) {
      case 'entities': {
        const {
          entities,
          browsingHistoryIllusts,
          browsingHistoryNovels,
          muteUsers,
        } = state;
        const selectedUsersEntities = {};
        const selectedIllustsEntities = browsingHistoryIllusts.items
          .filter(id => entities.illusts[id])
          .reduce((prev, id) => {
            prev[id] = entities.illusts[id];
            const userId = entities.illusts[id].user;
            selectedUsersEntities[userId] = entities.users[userId];
            return prev;
          }, {});
        const selectedNovelsEntities = browsingHistoryNovels.items
          .filter(id => entities.novels[id])
          .reduce((prev, id) => {
            prev[id] = entities.novels[id];
            const userId = entities.novels[id].user;
            selectedUsersEntities[userId] = entities.users[userId];
            return prev;
          }, {});
        const selectedUsersEntities2 = muteUsers.items
          .filter(id => entities.users[id])
          .reduce((prev, id) => {
            prev[id] = entities.users[id];
            return prev;
          }, {});
        const finalSelectedUsersEntities = {
          ...selectedUsersEntities,
          ...selectedUsersEntities2,
        };
        return {
          ...inboundState,
          illusts: selectedIllustsEntities,
          novels: selectedNovelsEntities,
          users: finalSelectedUsersEntities,
        };
      }
      case 'browsingHistoryIllusts': {
        const { entities, browsingHistoryIllusts } = state;
        return {
          ...inboundState,
          items: browsingHistoryIllusts.items.filter(
            id =>
              entities.illusts[id] &&
              entities.illusts[id].user &&
              entities.users[entities.illusts[id].user],
          ),
        };
      }
      case 'browsingHistoryNovels': {
        const { entities, browsingHistoryNovels } = state;
        return {
          ...inboundState,
          items: browsingHistoryNovels.items.filter(
            id =>
              entities.novels[id] &&
              entities.novels[id].user &&
              entities.users[entities.novels[id].user],
          ),
        };
      }
      case 'initialScreenSettings': {
        const { initialScreenSettings } = state;
        // migrate Ranking To RankingPreview as navigator changed
        return {
          ...inboundState,
          routeName:
            initialScreenSettings.routeName === SCREENS.Ranking
              ? SCREENS.RankingPreview
              : initialScreenSettings.routeName,
        };
      }
      default:
        return inboundState;
    }
  },
  outboundState => outboundState,
  {
    whitelist: [
      'entities',
      'browsingHistoryIllusts',
      'browsingHistoryNovels',
      'muteUsers',
      'initialScreenSettings',
    ],
  },
);

const clearV4PersistedContents = () =>
  AsyncStorage.getAllKeys((err, keys) => {
    if (!err && keys && keys.length) {
      const keyPrefix = 'persist:root';
      const v5PersistKeys = keys.filter(key => key.indexOf(keyPrefix) === 0);
      if (v5PersistKeys.length) {
        AsyncStorage.multiRemove(v5PersistKeys, () => Promise.resolve());
      } else {
        const v4KeyPrefix = 'reduxPersist:';
        const v4PersistKeys = keys.filter(
          key => key.indexOf(v4KeyPrefix) === 0,
        );
        if (v4PersistKeys.length) {
          AsyncStorage.multiRemove(v4PersistKeys, () => Promise.resolve());
        }
      }
    }
    return Promise.resolve();
  });

export default function configureStore() {
  let enhancer;
  const sagaMiddleware = createSagaMiddleware();
  if (process.env.NODE_ENV !== 'production') {
    const composeEnhancers =
      // eslint-disable-next-line no-underscore-dangle
      window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
    enhancer = composeEnhancers(
      applyAppStateListener(),
      applyMiddleware(invariant(), sagaMiddleware),
      // devTools(),
    );
  } else {
    enhancer = compose(
      applyAppStateListener(),
      applyMiddleware(sagaMiddleware),
    );
  }

  const v4Config = {
    whitelist: [
      'searchHistory',
      'browsingHistoryIllusts',
      'browsingHistoryNovels',
      'highlightTags',
      'muteTags',
      'muteUsers',
      'saveImageSettings',
      'novelSettings',
      'entities',
      'auth',
      'i18n',
    ],
    storage: AsyncStorage,
    transforms: [myTransform],
  };

  const v5Config = {
    key: 'root',
    stateReconciler: autoMergeLevel2,
    whitelist: [
      'searchHistory',
      'browsingHistoryIllusts',
      'browsingHistoryNovels',
      'highlightTags',
      'muteTags',
      'muteUsers',
      'saveImageSettings',
      'initialScreenSettings',
      'novelSettings',
      'entities',
      'auth',
      'i18n',
      'theme',
    ],
    storage: AsyncStorage,
    transforms: [myTransform],
    getStoredState: getStoredStateMigrateV4(v4Config),
  };

  const persistConfig = {
    key: 'root',
    timeout: 15000, // https://github.com/rt2zz/redux-persist/issues/717
    stateReconciler: autoMergeLevel2,
    whitelist: [
      'searchHistory',
      'browsingHistoryIllusts',
      'browsingHistoryNovels',
      'highlightTags',
      'muteSettings',
      'muteTags',
      'muteUsers',
      'saveImageSettings',
      'initialScreenSettings',
      'novelSettings',
      'likeButtonSettings',
      'entities',
      'auth',
      'i18n',
      'theme',
    ],
    storage: FileSystemStorage,
    transforms: [myTransform],
    getStoredState: getStoredStateMigrateToFileSystemStorage(
      v5Config,
      v4Config,
    ),
    debug: process.env.NODE_ENV !== 'production',
  };
  const persistedReducer = persistReducer(persistConfig, rootReducer);
  const store = createStore(persistedReducer, undefined, enhancer);
  sagaMiddleware.run(rootSaga);

  const persistor = persistStore(store, undefined, clearV4PersistedContents);
  if (module.hot) {
    // eslint-disable-next-line global-require
    const nextRootReducer = require('../reducers');
    module.hot.accept(() => {
      store.replaceReducer(persistReducer(persistConfig, nextRootReducer));
    });
  }

  return { store, persistor };
}
<|endoftext|>