<commit_before>/*
 * Copyright 2014 Telefonica Investigación y Desarrollo, S.A.U
 *
 * This file is part of iotagent-lwm2m-lib
 *
 * iotagent-lwm2m-lib is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the License,
 * or (at your option) any later version.
 *
 * iotagent-lwm2m-lib 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public
 * License along with iotagent-lwm2m-lib.
 * If not, seehttp://www.gnu.org/licenses/.
 *
 * For those usages not covered by the GNU Affero General Public License
 * please contact with::[contacto@tid.es]
 */

'use strict';

var async = require('async'),
    apply = async.apply,
    coapUtils = require('./coapUtils'),
    errors = require('../../errors'),
    registry,
    config,
    logger = require('logops'),
    context = {
        op: 'LWM2MLib.DeviceManagement'
    };

/**
 * Execute a read operation for the selected resource, identified following the LWTM2M conventions by its: deviceId,
 * objectType, objectId and resourceId.
 */
function read(deviceId, objectType, objectId, resourceId, callback) {
    function createReadRequest(obj, callback) {
        var request = {
            host: (config.ipProtocol === 'udp6')?'::1':'127.0.0.1',
            port: config.port,
            method: 'GET',
            proxyUri: 'coap://' + (config.ipProtocol === 'udp6' ? '['+obj.address+']' : obj.address) + ':' + obj.port,
            pathname: '/' + objectType + '/' + objectId + '/' + resourceId
        };

        callback(null, request);
    }

    logger.debug(context, 'Reading value from resource /%s/%s/%s in device [%d]',
        objectType, objectId, resourceId, deviceId);

    async.waterfall([
        apply(registry.get, deviceId),
        createReadRequest,
        coapUtils.sendRequest,
        coapUtils.generateProcessResponse(objectType, objectId, resourceId, '2.05')
    ], callback);
}

/**
 * Makes a modification over the selected resource, identified following the LWTM2M conventions by its: deviceId,
 * objectType, objectId and resourceId, changing its value to the value passed as a parameter. The method will
 * determine whether its an Execute or a Write operation.
 *
 * @param {String} method           COAP Method to execute.
 * @param {String} deviceId         ID of the device that will be called.
 * @param {Number} objectType       Object type ID.
 * @param {Number} objectId         Object instance ID.
 * @param {Number} resourceId       Resource ID.
 * @param {String} value            Value to write.
 */
function writeResource(method, deviceId, objectType, objectId, resourceId, value, callback) {
    function createUpdateRequest(obj, callback) {
        var request = {
            host: (config.ipProtocol === 'udp6')?'::1':'127.0.0.1',
            port: config.port,
            method: method,
            proxyUri: 'coap://' + obj.address + ':' + obj.port,
            pathname: '/' + objectType + '/' + objectId + '/' + resourceId,
            payload: value,
            options: {
                'Content-Format': config.writeFormat
            }
        };

        callback(null, request);
    }

    function processResponse(res, callback) {
        if (res.code === '2.04') {
            callback(null, res.payload.toString('utf8'));
        } else if (res.code === '4.04') {
            callback(new errors.ObjectNotFound('/' + objectType + '/' + objectId));
        } else {
            callback(new errors.ClientError(res.code));
        }
    }

    logger.debug(context, 'Writting a new value [%s] on resource /%s/%s/%s in device [%d]',
        value, objectType, objectId, resourceId, deviceId);

    async.waterfall([
        apply(registry.get, deviceId),
        createUpdateRequest,
        coapUtils.sendRequest,
        processResponse
    ], callback);
}

/**
 * Makes a Write operation over the designed resource ID of the selected device.
 */
function write(deviceId, objectType, objectId, resourceId, value, callback) {
    writeResource('PUT', deviceId, objectType, objectId, resourceId, value, callback);
}

/**
 * Makes an Execute operation over the designed resource ID of the selected device.
 */
function execute(deviceId, objectType, objectId, resourceId, value, callback) {
    writeResource('POST', deviceId, objectType, objectId, resourceId, value, callback);
}

/**
 * Write the attributes given as a parameter in the remote resource identified by the Object type and id in the
 * selected device.
 *
 * @param {String} deviceId             ID of the device that holds the resource.
 * @param {String} objectType           ID of the object type of the instance.
 * @param {String} objectId             ID of the instance whose resource will be modified.
 * @param {String} resourceId           ID of the resource to modify.
 * @param {Object} parameters           Object with the parameters to write: each parameter is stored as an attribute.
 */
function writeAttributes(deviceId, objectType, objectId, resourceId, attributes, callback) {
    function createQueryParams(innerCb) {
        var validAttributes = ['pmin', 'pmax', 'gt', 'lt', 'st', 'cancel'],
            result = '?',
            errorList = [];

        for (var i in attributes) {
            if (attributes.hasOwnProperty(i)) {
                if (validAttributes.indexOf(i) >= 0) {
                    result += i + '=' + attributes[i] + '&';
                } else {
                    errorList.push(i);
                }
            }
        }

        if (errorList.length !== 0) {
            innerCb(new errors.UnsupportedAttributes(errorList));
        } else {
            innerCb(null, result);
        }
    }

    function createWriteAttributesRequest(data, innerCb) {
        var request = {
            host: (config.ipProtocol === 'udp6')?'::1':'127.0.0.1',
            port: config.port,
            proxyUri: 'coap://' + data[0].address + ':' + data[0].port,
            method: 'PUT'
        };
        if (objectType && objectId && resourceId) {
            request.pathname = '/' + objectType + '/' + objectId + '/' + resourceId + data[1];
        } else if (objectType && objectId) {
            request.pathname = '/' + objectType + '/' + objectId + data[1];
        } else {
            request.pathname = '/' + objectType + data[1];
        }

        innerCb(null, request);
    }

    logger.debug(context, 'Writting new discover attributes on resource /%s/%s/%s in device [%d]',
        objectType, objectId, resourceId, deviceId);
    logger.debug(context, 'The new attributes are:\n%j', attributes);

    async.waterfall([
        apply(async.parallel, [
            apply(registry.get, deviceId),
            createQueryParams
        ]),
        createWriteAttributesRequest,
        coapUtils.sendRequest,
        coapUtils.generateProcessResponse(objectType, objectId, resourceId, '2.04')
    ], callback);
}

/**
 * Execute a discover operation for the selected resource, identified following the LWTM2M conventions by its:
 * deviceId, objectType, objectId and resourceId.
 */
function discover(deviceId, objectType, objectId, resourceId, fullCallback) {
    var pathname,
        trueCallback;

    if (objectId && resourceId && fullCallback) {
        logger.debug(context, 'Executing a resource discover operation on resource /%s/%s/%s in device [%d]',
            objectType, objectId, resourceId, deviceId);

        pathname= '/' + objectType + '/' + objectId + '/' + resourceId;
        trueCallback = fullCallback;
    } else if (objectId && resourceId) {
        logger.debug(context, 'Executing a instance discover operation on resource /%s/%s in device [%d]',
            objectType, objectId, deviceId);

        pathname= '/' + objectType + '/' + objectId;
        trueCallback = resourceId;
    } else {
        logger.debug(context, 'Executing a type discover operation on resource /%s in device [%d]',
            objectType, deviceId);

        pathname= '/' + objectType;
        trueCallback = objectId;
    }

    function createReadRequest(obj, callback) {
        var request = {
            host: (config.ipProtocol === 'udp6')?'::1':'127.0.0.1',
            port: config.port,
            method: 'GET',
            proxyUri: 'coap://' + obj.address + ':' + obj.port,
            pathname: pathname,
            options: {
                'Accept': 'application/link-format'
            }
        };

        callback(null, request);
    }

    if (!objectType && !objectId && !resourceId) {
        logger.error(context, 'Method called with wrong number of parameters. Couldn\'t identify callback');
    } else {
        async.waterfall([
            apply(registry.get, deviceId),
            createReadRequest,
            coapUtils.sendRequest,
            coapUtils.generateProcessResponse(objectType, objectId, resourceId, '2.05')
        ], trueCallback);
    }
}

function create(deviceId, objectType, objectId, callback) {
    function createUpdateRequest(obj, callback) {
        var request = {
            host: (config.ipProtocol === 'udp6')?'::1':'127.0.0.1',
            port: config.port,
            method: 'POST',
            proxyUri: 'coap://' + obj.address + ':' + obj.port,
            pathname: '/' + objectType + '/' + objectId
        };

        callback(null, request);
    }

    logger.debug(context, 'Creating a new instance of object type [%s] in the device [%d] with instance id [%s]',
        objectType, deviceId, objectId);

    async.waterfall([
        apply(registry.get, deviceId),
        createUpdateRequest,
        coapUtils.sendRequest,
        coapUtils.generateProcessResponse(objectType, objectId, null, '2.01')
    ], callback);
}

function remove(deviceId, objectType, objectId, callback) {
    callback(null);
}

function init(deviceRegistry, newConfig) {
    registry = deviceRegistry;
    config = newConfig;
}

exports.read = read;
exports.write = write;
exports.execute = execute;
exports.writeAttributes = writeAttributes;
exports.discover = discover;
exports.create = create;
exports.remove = remove;
exports.init = init;
<commit_msg>Fixed the rest of the proxyUris.<commit_after>/*
 * Copyright 2014 Telefonica Investigación y Desarrollo, S.A.U
 *
 * This file is part of iotagent-lwm2m-lib
 *
 * iotagent-lwm2m-lib is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the License,
 * or (at your option) any later version.
 *
 * iotagent-lwm2m-lib 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public
 * License along with iotagent-lwm2m-lib.
 * If not, seehttp://www.gnu.org/licenses/.
 *
 * For those usages not covered by the GNU Affero General Public License
 * please contact with::[contacto@tid.es]
 */

'use strict';

var async = require('async'),
    apply = async.apply,
    coapUtils = require('./coapUtils'),
    errors = require('../../errors'),
    registry,
    config,
    logger = require('logops'),
    context = {
        op: 'LWM2MLib.DeviceManagement'
    };

/**
 * Execute a read operation for the selected resource, identified following the LWTM2M conventions by its: deviceId,
 * objectType, objectId and resourceId.
 */
function read(deviceId, objectType, objectId, resourceId, callback) {
    function createReadRequest(obj, callback) {
        var request = {
            host: (config.ipProtocol === 'udp6')?'::1':'127.0.0.1',
            port: config.port,
            method: 'GET',
            proxyUri: 'coap://' + (config.ipProtocol === 'udp6' ? '['+obj.address+']' : obj.address) + ':' + obj.port,
            pathname: '/' + objectType + '/' + objectId + '/' + resourceId
        };

        callback(null, request);
    }

    logger.debug(context, 'Reading value from resource /%s/%s/%s in device [%d]',
        objectType, objectId, resourceId, deviceId);

    async.waterfall([
        apply(registry.get, deviceId),
        createReadRequest,
        coapUtils.sendRequest,
        coapUtils.generateProcessResponse(objectType, objectId, resourceId, '2.05')
    ], callback);
}

/**
 * Makes a modification over the selected resource, identified following the LWTM2M conventions by its: deviceId,
 * objectType, objectId and resourceId, changing its value to the value passed as a parameter. The method will
 * determine whether its an Execute or a Write operation.
 *
 * @param {String} method           COAP Method to execute.
 * @param {String} deviceId         ID of the device that will be called.
 * @param {Number} objectType       Object type ID.
 * @param {Number} objectId         Object instance ID.
 * @param {Number} resourceId       Resource ID.
 * @param {String} value            Value to write.
 */
function writeResource(method, deviceId, objectType, objectId, resourceId, value, callback) {
    function createUpdateRequest(obj, callback) {
        var request = {
            host: (config.ipProtocol === 'udp6')?'::1':'127.0.0.1',
            port: config.port,
            method: method,
            proxyUri: 'coap://' + (config.ipProtocol === 'udp6' ? '['+obj.address+']' : obj.address) + ':' + obj.port,
            pathname: '/' + objectType + '/' + objectId + '/' + resourceId,
            payload: value,
            options: {
                'Content-Format': config.writeFormat
            }
        };

        callback(null, request);
    }

    function processResponse(res, callback) {
        if (res.code === '2.04') {
            callback(null, res.payload.toString('utf8'));
        } else if (res.code === '4.04') {
            callback(new errors.ObjectNotFound('/' + objectType + '/' + objectId));
        } else {
            callback(new errors.ClientError(res.code));
        }
    }

    logger.debug(context, 'Writting a new value [%s] on resource /%s/%s/%s in device [%d]',
        value, objectType, objectId, resourceId, deviceId);

    async.waterfall([
        apply(registry.get, deviceId),
        createUpdateRequest,
        coapUtils.sendRequest,
        processResponse
    ], callback);
}

/**
 * Makes a Write operation over the designed resource ID of the selected device.
 */
function write(deviceId, objectType, objectId, resourceId, value, callback) {
    writeResource('PUT', deviceId, objectType, objectId, resourceId, value, callback);
}

/**
 * Makes an Execute operation over the designed resource ID of the selected device.
 */
function execute(deviceId, objectType, objectId, resourceId, value, callback) {
    writeResource('POST', deviceId, objectType, objectId, resourceId, value, callback);
}

/**
 * Write the attributes given as a parameter in the remote resource identified by the Object type and id in the
 * selected device.
 *
 * @param {String} deviceId             ID of the device that holds the resource.
 * @param {String} objectType           ID of the object type of the instance.
 * @param {String} objectId             ID of the instance whose resource will be modified.
 * @param {String} resourceId           ID of the resource to modify.
 * @param {Object} parameters           Object with the parameters to write: each parameter is stored as an attribute.
 */
function writeAttributes(deviceId, objectType, objectId, resourceId, attributes, callback) {
    function createQueryParams(innerCb) {
        var validAttributes = ['pmin', 'pmax', 'gt', 'lt', 'st', 'cancel'],
            result = '?',
            errorList = [];

        for (var i in attributes) {
            if (attributes.hasOwnProperty(i)) {
                if (validAttributes.indexOf(i) >= 0) {
                    result += i + '=' + attributes[i] + '&';
                } else {
                    errorList.push(i);
                }
            }
        }

        if (errorList.length !== 0) {
            innerCb(new errors.UnsupportedAttributes(errorList));
        } else {
            innerCb(null, result);
        }
    }

    function createWriteAttributesRequest(data, innerCb) {
        var request = {
            host: (config.ipProtocol === 'udp6')?'::1':'127.0.0.1',
            port: config.port,
            proxyUri: 'coap://' + (config.ipProtocol === 'udp6' ? '['+data[0].address+']' : data[0].address) + ':' + data[0].port,
            method: 'PUT'
        };
        if (objectType && objectId && resourceId) {
            request.pathname = '/' + objectType + '/' + objectId + '/' + resourceId + data[1];
        } else if (objectType && objectId) {
            request.pathname = '/' + objectType + '/' + objectId + data[1];
        } else {
            request.pathname = '/' + objectType + data[1];
        }

        innerCb(null, request);
    }

    logger.debug(context, 'Writting new discover attributes on resource /%s/%s/%s in device [%d]',
        objectType, objectId, resourceId, deviceId);
    logger.debug(context, 'The new attributes are:\n%j', attributes);

    async.waterfall([
        apply(async.parallel, [
            apply(registry.get, deviceId),
            createQueryParams
        ]),
        createWriteAttributesRequest,
        coapUtils.sendRequest,
        coapUtils.generateProcessResponse(objectType, objectId, resourceId, '2.04')
    ], callback);
}

/**
 * Execute a discover operation for the selected resource, identified following the LWTM2M conventions by its:
 * deviceId, objectType, objectId and resourceId.
 */
function discover(deviceId, objectType, objectId, resourceId, fullCallback) {
    var pathname,
        trueCallback;

    if (objectId && resourceId && fullCallback) {
        logger.debug(context, 'Executing a resource discover operation on resource /%s/%s/%s in device [%d]',
            objectType, objectId, resourceId, deviceId);

        pathname= '/' + objectType + '/' + objectId + '/' + resourceId;
        trueCallback = fullCallback;
    } else if (objectId && resourceId) {
        logger.debug(context, 'Executing a instance discover operation on resource /%s/%s in device [%d]',
            objectType, objectId, deviceId);

        pathname= '/' + objectType + '/' + objectId;
        trueCallback = resourceId;
    } else {
        logger.debug(context, 'Executing a type discover operation on resource /%s in device [%d]',
            objectType, deviceId);

        pathname= '/' + objectType;
        trueCallback = objectId;
    }

    function createReadRequest(obj, callback) {
        var request = {
            host: (config.ipProtocol === 'udp6')?'::1':'127.0.0.1',
            port: config.port,
            method: 'GET',
            proxyUri: 'coap://' + (config.ipProtocol === 'udp6' ? '['+obj.address+']' : obj.address) + ':' + obj.port,
            pathname: pathname,
            options: {
                'Accept': 'application/link-format'
            }
        };

        callback(null, request);
    }

    if (!objectType && !objectId && !resourceId) {
        logger.error(context, 'Method called with wrong number of parameters. Couldn\'t identify callback');
    } else {
        async.waterfall([
            apply(registry.get, deviceId),
            createReadRequest,
            coapUtils.sendRequest,
            coapUtils.generateProcessResponse(objectType, objectId, resourceId, '2.05')
        ], trueCallback);
    }
}

function create(deviceId, objectType, objectId, callback) {
    function createUpdateRequest(obj, callback) {
        var request = {
            host: (config.ipProtocol === 'udp6')?'::1':'127.0.0.1',
            port: config.port,
            method: 'POST',
            proxyUri: 'coap://' + (config.ipProtocol === 'udp6' ? '['+obj.address+']' : obj.address) + ':' + obj.port,
            pathname: '/' + objectType + '/' + objectId
        };

        callback(null, request);
    }

    logger.debug(context, 'Creating a new instance of object type [%s] in the device [%d] with instance id [%s]',
        objectType, deviceId, objectId);

    async.waterfall([
        apply(registry.get, deviceId),
        createUpdateRequest,
        coapUtils.sendRequest,
        coapUtils.generateProcessResponse(objectType, objectId, null, '2.01')
    ], callback);
}

function remove(deviceId, objectType, objectId, callback) {
    callback(null);
}

function init(deviceRegistry, newConfig) {
    registry = deviceRegistry;
    config = newConfig;
}

exports.read = read;
exports.write = write;
exports.execute = execute;
exports.writeAttributes = writeAttributes;
exports.discover = discover;
exports.create = create;
exports.remove = remove;
exports.init = init;
<|endoftext|>


<commit_before>/**
 * @requires OpenLayers/Control.js
 * @requires OpenLayers/Lang.js
 * @requires OpenLayers/Console.js
 * @requires OpenLayers/Events.js
 * @requires OpenLayers/Events/buttonclick.js
 * @requires OpenLayers/Control/LayerSwitcher.js
  */

OpenLayers.Control.RasterOverlayLayerSwitcher =
	OpenLayers.Class(OpenLayers.Control.LayerSwitcher, {

    layerGroup: null,

    /**
     * Method: loadContents
     * Set up the labels and divs for the control
     */
    loadContents: function() {
        var self=this;

        // layers list div
        this.layersDiv = document.createElement("div");
        this.layersDiv.id = this.id + "_layersDiv";
        OpenLayers.Element.addClass(this.layersDiv, "layersDiv");

        self.toggleWidgetDiv = document.createElement("div");
        OpenLayers.Element.addClass(self.toggleWidgetDiv, "vectorWidgetToggleBtn");
        self.toggleWidgetDiv.tabIndex = 0;
        self.toggleWidgetDiv.innerHTML = this.options.title;

        this.dataLayersDiv = document.createElement("div");
        OpenLayers.Element.addClass(this.dataLayersDiv, "dataLayersDiv");

        self.widget = OpenLayers.Util.createWidget( self.dataLayersDiv );
        if (this.options.popup) {
          this.layersDiv.appendChild(self.toggleWidgetDiv);
          this.layersDiv.appendChild(self.widget);

          var clickFunction = function( e ) {
            var parent = self.toggleWidgetDiv.parentNode;
            //self.toggleClass( parent, 'show' );
            OpenLayers.Element.toggleClass( parent, 'show' );
            var widget = self.dataLayersDiv.parentElement;
            var offset = widget.getBoundingClientRect().bottom - $(window).height();
            if (offset > 0) {
              widget.style.top = widget.style.top.split("px")[0] - offset - 5 + "px"; // don't you love mixed type?
            }
          };

          OpenLayers.Event.observe(
            self.toggleWidgetDiv,
            'click',
            clickFunction,
            true
          );

        } else {
          this.layersDiv.appendChild(this.dataLayersDiv);
        }
        this.div.appendChild(this.layersDiv);
        this.map.events.register('rasterLayerChangeRequest', this, this.rasterLayerChangeRequestHandler);
    },
    rasterLayerChangeRequestHandler: function (evt) {
        this.setLayerVisibilityByShortId(evt.shortId);
    },
    initialize: function(options) {
        this.options = options;
        OpenLayers.Control.LayerSwitcher.prototype.initialize.apply(this, arguments);
        if (options.layerGroup) {
            this.layerGroup = options.layerGroup;
        }
    },
    /**
     * Method: redraw
     * Goes through and takes the current state of the Map and rebuilds the
     *     control to display that state. Groups base layers into a
     *     radio-button group and lists each data layer with a checkbox.
     *
     * Returns:
     * {DOMElement} A reference to the DIV DOMElement containing the control
     */
    redraw: function() {
        //if the state hasn't changed since last redraw, no need
        // to do anything. Just return the existing div.

        var self = this,
            trigger = null,
            containsOverlays = false,
        	containsBaseLayers = false,
        	layers,
        	layer,
        	i,
        	len,
        	li,
        	inputElem,
        	checked,
        	labelSpan,
        	groupDiv,
        	layerList;

        if (!this.checkRedraw()) {
            return this.div;
        }

        //clear out previous layers
        this.clearLayersArray("data");

        // Save state -- for checking layer if the map state changed.
        // We save this before redrawing, because in the process of redrawing
        // we will trigger more visibility changes, and we want to not redraw
        // and enter an infinite loop.
        layers = this.map.layers.slice();

        len = layers.length;
        this.layerStates = new Array(len);
        for (i = 0; i < len; i++) {
            layer = this.map.layers[i];
            this.layerStates[i] = {
                'name': layer.name,
                'visibility': layer.visibility,
                'inRange': layer.inRange,
                'id': layer.id
            };
        }

        if (!this.ascending) {
            layers.reverse();
        }
        if (layers.length > 0) {
        	layerList = document.createElement('ul');
        }
        for (i = 0, len = layers.length; i < len; i++) {
            layer = layers[i];
            baseLayer = layer.isBaseLayer;

            if ( ((this.layerGroup && this.layerGroup === layer.layerGroup) || this.layergroup === null) && !baseLayer && (layer.CLASS_NAME === "OpenLayers.Layer.WMTS" || layer.CLASS_NAME === "OpenLayers.Layer.WMS")) {

                containsOverlays = true;

                // only check a baselayer if it is *the* baselayer, check data
                //  layers if they are visible
                checked = layer.getVisibility();

                // create input element
                inputElem = document.createElement("input");
                inputElem.id = this.id + "_input_" + layer.name;
                inputElem.name = this.id + "raster_layer_selector";
                inputElem.type = "radio";
                inputElem.value = layer.name;
                inputElem.checked = checked;
                inputElem.defaultChecked = checked;
                inputElem.className = "olButton";
                if (checked) {
                    OpenLayers.Element.addClass(inputElem, "is-checked");
                }
                inputElem._layer = layer.id;
                inputElem._layerSwitcher = this.id;

                if (!layer.inRange) {
                    inputElem.disabled = true;
                }

                // create span
                labelSpan = document.createElement("label");
                labelSpan["for"] = inputElem.id;
                OpenLayers.Element.addClass(labelSpan, "labelSpan olButton");
                if (checked) {
                    OpenLayers.Element.addClass(labelSpan, "for-checked");
                }
                labelSpan._layer = layer.id;
                labelSpan._layerSwitcher = this.id;
                labelSpan.innerHTML = layer.name;

                // create list item
                li = document.createElement("li");
                li.id = layer.shortid.replace(/\./g, '-') + '-selector';
                OpenLayers.Element.addClass(li, 'raster-layer-selector-item');

                if (!layer.displayInLayerSwitcher) {
                    OpenLayers.Element.addClass(li, 'hidden');
                }

                this.dataLayers.push({
                    'layer': layer,
                    'inputElem': inputElem,
                    'labelSpan': labelSpan
                });

                trigger = document.createElement('span');
                trigger.setAttribute('id', layer.layer);
                OpenLayers.Element.addClass(trigger, 'layerTriggerTarget');
                OpenLayers.Event.observe(trigger, 'click', OpenLayers.Function.bind(self.activate, self));
                this.events.register("click", this, this.activate);

                labelSpan.appendChild( trigger );
                li.appendChild(inputElem);
                li.appendChild(labelSpan);
                layerList.appendChild(li);
            }
        }
        if (layerList) {
        	layerList.className = "rasterLayerList";
        	this.dataLayersDiv.appendChild(layerList);
        }

        return this.div;
    },
    /**
     * Method: It'll activate the current layer.
     *
     * Parameters:
     * e - {Window.Event}
     */
    activate: function( e ) {
    	var target = e.target;

        var label = target;
        if (target.tagName != "LABEL") {
          label = target.parentNode;
        }

    	var input = document.getElementById(label['for']);

    	return input == null || input.checked ? null :
    	    this.onButtonClick({ 'buttonElement' : label });
    },
    /**
     * Method: updateMap
     * Cycles through the loaded data and base layer input arrays and makes
     *     the necessary calls to the Map object such that that the map's
     *     visual state corresponds to what the user has selected in
     *     the control.
     */
    updateMap: function( order, disableAll ) {
    	var i,
            layerEntry,
            current;

    	if (!order) {
            order = [0,0];
        }
        // set the correct visibilities for the overlays
    	if (order[1] <= order[0]) {
            for (i = 0; i < this.dataLayers.length; i++) {
        		layerEntry = this.dataLayers[i];
        		if (layerEntry.inputElem.checked) {
        		    current = layerEntry;
        		} else {
        		    layerEntry.layer.setVisibility(layerEntry.inputElem.checked && (!disableAll));
                }
            }

    	} else {
            for (i = this.dataLayers.length -1; i >= 0; i--) {
                layerEntry = this.dataLayers[i];
                if (layerEntry.inputElem.checked) {
                    current = layerEntry;
                } else {
                    layerEntry.layer.setVisibility(layerEntry.inputElem.checked && (!disableAll));
                }
            }
    	}
        if (current) {
            current.layer.setVisibility(!disableAll);
        }
    },
    setLayerVisibilityByShortId: function (shortId) {
        var i,
            len,
            layerEntry,
            pin;

        for (i = 0, len = this.dataLayers.length; i < len; i += 1) {
            layerEntry = this.dataLayers[i];

            if (layerEntry.layer.shortid !== shortId) {
                OpenLayers.Element.removeClass(layerEntry.inputElem, "checked");
                OpenLayers.Element.removeClass(layerEntry.inputElem, "is-checked");
                layerEntry.inputElem.checked = false;
            } else {
                pin = i;
                OpenLayers.Element.addClass(layerEntry.inputElem, "checked");
                OpenLayers.Element.addClass(layerEntry.inputElem, "is-checked");
                layerEntry.inputElem.checked = true;
            }
        }
        this.updateMap( [this.pin || 0, pin || 0] );
        this.pin = pin;
    },
    /**
     * Method: onButtonClick
     *
     * Parameters:
     * evt - {Event}
     */
    onButtonClick: function (evt) {
        var i,
            len,
            layerEntry,
            pin = 0,
            button = evt.buttonElement;

        if (button._layerSwitcher === this.id) {
            if (button["for"]) {
                button = document.getElementById(button["for"]);
            }
            if (!button.disabled) {
                var rasterControls = map.getControlsByClass("OpenLayers.Control.RasterOverlayLayerSwitcher");
                var dataLayers = [].concat.apply([],rasterControls.map(function(x){return x.dataLayers}));
                for (i = 0, len = dataLayers.length; i < len; i += 1) {

                    layerEntry = dataLayers[i];

                    if (layerEntry.inputElem !== button) {
                        OpenLayers.Element.removeClass(layerEntry.inputElem, "checked");
                        OpenLayers.Element.removeClass(layerEntry.inputElem, "is-checked");
                        layerEntry.inputElem.checked = false;
                    } else {
                        pin = i;
                        OpenLayers.Element.addClass(layerEntry.inputElem, "checked");
                        OpenLayers.Element.addClass(layerEntry.inputElem, "is-checked");
                        layerEntry.inputElem.checked = true;

                        if (!!layerEntry.layer.maxExtent) {
                          var extent = layerEntry.layer.maxExtent;
                          if (!extent.containsLonLat(map.getCenter())) {
                            map.zoomToExtent(extent);
                          }
                        }

                    }
                }
                for (i = 0; i < rasterControls.length; i++) {
                  rasterControls[i].updateMap( [this.pin || 0, pin || 0] , this != rasterControls[i] );
                }
                this.pin = pin;
            }
            this.map.events.triggerEvent('rasterLayersChangedByClick', {});
        }
    },
    CLASS_NAME: "OpenLayers.Control.RasterOverlayLayerSwitcher"
});
<commit_msg>listen to layerGroup if event is fired<commit_after>/**
 * @requires OpenLayers/Control.js
 * @requires OpenLayers/Lang.js
 * @requires OpenLayers/Console.js
 * @requires OpenLayers/Events.js
 * @requires OpenLayers/Events/buttonclick.js
 * @requires OpenLayers/Control/LayerSwitcher.js
  */

OpenLayers.Control.RasterOverlayLayerSwitcher =
	OpenLayers.Class(OpenLayers.Control.LayerSwitcher, {

    layerGroup: null,

    /**
     * Method: loadContents
     * Set up the labels and divs for the control
     */
    loadContents: function() {
        var self=this;

        // layers list div
        this.layersDiv = document.createElement("div");
        this.layersDiv.id = this.id + "_layersDiv";
        OpenLayers.Element.addClass(this.layersDiv, "layersDiv");

        self.toggleWidgetDiv = document.createElement("div");
        OpenLayers.Element.addClass(self.toggleWidgetDiv, "vectorWidgetToggleBtn");
        self.toggleWidgetDiv.tabIndex = 0;
        self.toggleWidgetDiv.innerHTML = this.options.title;

        this.dataLayersDiv = document.createElement("div");
        OpenLayers.Element.addClass(this.dataLayersDiv, "dataLayersDiv");

        self.widget = OpenLayers.Util.createWidget( self.dataLayersDiv );
        if (this.options.popup) {
          this.layersDiv.appendChild(self.toggleWidgetDiv);
          this.layersDiv.appendChild(self.widget);

          var clickFunction = function( e ) {
            var parent = self.toggleWidgetDiv.parentNode;
            //self.toggleClass( parent, 'show' );
            OpenLayers.Element.toggleClass( parent, 'show' );
            var widget = self.dataLayersDiv.parentElement;
            var offset = widget.getBoundingClientRect().bottom - $(window).height();
            if (offset > 0) {
              widget.style.top = widget.style.top.split("px")[0] - offset - 5 + "px"; // don't you love mixed type?
            }
          };

          OpenLayers.Event.observe(
            self.toggleWidgetDiv,
            'click',
            clickFunction,
            true
          );

        } else {
          this.layersDiv.appendChild(this.dataLayersDiv);
        }
        this.div.appendChild(this.layersDiv);
        this.map.events.register('rasterLayerChangeRequest', this, this.rasterLayerChangeRequestHandler);
    },
    rasterLayerChangeRequestHandler: function (evt) {
        if (!!evt.layerGroup && (evt.layerGroup != this.layerGroup)) { return; }
        this.setLayerVisibilityByShortId(evt.shortId);
    },
    initialize: function(options) {
        this.options = options;
        OpenLayers.Control.LayerSwitcher.prototype.initialize.apply(this, arguments);
        if (options.layerGroup) {
            this.layerGroup = options.layerGroup;
        }
    },
    /**
     * Method: redraw
     * Goes through and takes the current state of the Map and rebuilds the
     *     control to display that state. Groups base layers into a
     *     radio-button group and lists each data layer with a checkbox.
     *
     * Returns:
     * {DOMElement} A reference to the DIV DOMElement containing the control
     */
    redraw: function() {
        //if the state hasn't changed since last redraw, no need
        // to do anything. Just return the existing div.

        var self = this,
            trigger = null,
            containsOverlays = false,
        	containsBaseLayers = false,
        	layers,
        	layer,
        	i,
        	len,
        	li,
        	inputElem,
        	checked,
        	labelSpan,
        	groupDiv,
        	layerList;

        if (!this.checkRedraw()) {
            return this.div;
        }

        //clear out previous layers
        this.clearLayersArray("data");

        // Save state -- for checking layer if the map state changed.
        // We save this before redrawing, because in the process of redrawing
        // we will trigger more visibility changes, and we want to not redraw
        // and enter an infinite loop.
        layers = this.map.layers.slice();

        len = layers.length;
        this.layerStates = new Array(len);
        for (i = 0; i < len; i++) {
            layer = this.map.layers[i];
            this.layerStates[i] = {
                'name': layer.name,
                'visibility': layer.visibility,
                'inRange': layer.inRange,
                'id': layer.id
            };
        }

        if (!this.ascending) {
            layers.reverse();
        }
        if (layers.length > 0) {
        	layerList = document.createElement('ul');
        }
        for (i = 0, len = layers.length; i < len; i++) {
            layer = layers[i];
            baseLayer = layer.isBaseLayer;

            if ( ((this.layerGroup && this.layerGroup === layer.layerGroup) || this.layergroup === null) && !baseLayer && (layer.CLASS_NAME === "OpenLayers.Layer.WMTS" || layer.CLASS_NAME === "OpenLayers.Layer.WMS")) {

                containsOverlays = true;

                // only check a baselayer if it is *the* baselayer, check data
                //  layers if they are visible
                checked = layer.getVisibility();

                // create input element
                inputElem = document.createElement("input");
                inputElem.id = this.id + "_input_" + layer.name;
                inputElem.name = this.id + "raster_layer_selector";
                inputElem.type = "radio";
                inputElem.value = layer.name;
                inputElem.checked = checked;
                inputElem.defaultChecked = checked;
                inputElem.className = "olButton";
                if (checked) {
                    OpenLayers.Element.addClass(inputElem, "is-checked");
                }
                inputElem._layer = layer.id;
                inputElem._layerSwitcher = this.id;

                if (!layer.inRange) {
                    inputElem.disabled = true;
                }

                // create span
                labelSpan = document.createElement("label");
                labelSpan["for"] = inputElem.id;
                OpenLayers.Element.addClass(labelSpan, "labelSpan olButton");
                if (checked) {
                    OpenLayers.Element.addClass(labelSpan, "for-checked");
                }
                labelSpan._layer = layer.id;
                labelSpan._layerSwitcher = this.id;
                labelSpan.innerHTML = layer.name;

                // create list item
                li = document.createElement("li");
                li.id = layer.shortid.replace(/\./g, '-') + '-selector';
                OpenLayers.Element.addClass(li, 'raster-layer-selector-item');

                if (!layer.displayInLayerSwitcher) {
                    OpenLayers.Element.addClass(li, 'hidden');
                }

                this.dataLayers.push({
                    'layer': layer,
                    'inputElem': inputElem,
                    'labelSpan': labelSpan
                });

                trigger = document.createElement('span');
                trigger.setAttribute('id', layer.layer);
                OpenLayers.Element.addClass(trigger, 'layerTriggerTarget');
                OpenLayers.Event.observe(trigger, 'click', OpenLayers.Function.bind(self.activate, self));
                this.events.register("click", this, this.activate);

                labelSpan.appendChild( trigger );
                li.appendChild(inputElem);
                li.appendChild(labelSpan);
                layerList.appendChild(li);
            }
        }
        if (layerList) {
        	layerList.className = "rasterLayerList";
        	this.dataLayersDiv.appendChild(layerList);
        }

        return this.div;
    },
    /**
     * Method: It'll activate the current layer.
     *
     * Parameters:
     * e - {Window.Event}
     */
    activate: function( e ) {
    	var target = e.target;

        var label = target;
        if (target.tagName != "LABEL") {
          label = target.parentNode;
        }

    	var input = document.getElementById(label['for']);

    	return input == null || input.checked ? null :
    	    this.onButtonClick({ 'buttonElement' : label });
    },
    /**
     * Method: updateMap
     * Cycles through the loaded data and base layer input arrays and makes
     *     the necessary calls to the Map object such that that the map's
     *     visual state corresponds to what the user has selected in
     *     the control.
     */
    updateMap: function( order, disableAll ) {
    	var i,
            layerEntry,
            current;

    	if (!order) {
            order = [0,0];
        }
        // set the correct visibilities for the overlays
    	if (order[1] <= order[0]) {
            for (i = 0; i < this.dataLayers.length; i++) {
        		layerEntry = this.dataLayers[i];
        		if (layerEntry.inputElem.checked) {
        		    current = layerEntry;
        		} else {
        		    layerEntry.layer.setVisibility(layerEntry.inputElem.checked && (!disableAll));
                }
            }

    	} else {
            for (i = this.dataLayers.length -1; i >= 0; i--) {
                layerEntry = this.dataLayers[i];
                if (layerEntry.inputElem.checked) {
                    current = layerEntry;
                } else {
                    layerEntry.layer.setVisibility(layerEntry.inputElem.checked && (!disableAll));
                }
            }
    	}
        if (current) {
            current.layer.setVisibility(!disableAll);
        }
    },
    setLayerVisibilityByShortId: function (shortId) {
        var i,
            len,
            layerEntry,
            pin;

        for (i = 0, len = this.dataLayers.length; i < len; i += 1) {
            layerEntry = this.dataLayers[i];

            if (layerEntry.layer.shortid !== shortId) {
                OpenLayers.Element.removeClass(layerEntry.inputElem, "checked");
                OpenLayers.Element.removeClass(layerEntry.inputElem, "is-checked");
                layerEntry.inputElem.checked = false;
            } else {
                pin = i;
                OpenLayers.Element.addClass(layerEntry.inputElem, "checked");
                OpenLayers.Element.addClass(layerEntry.inputElem, "is-checked");
                layerEntry.inputElem.checked = true;
            }
        }
        this.updateMap( [this.pin || 0, pin || 0] );
        this.pin = pin;
    },
    /**
     * Method: onButtonClick
     *
     * Parameters:
     * evt - {Event}
     */
    onButtonClick: function (evt) {
        var i,
            len,
            layerEntry,
            pin = 0,
            button = evt.buttonElement;

        if (button._layerSwitcher === this.id) {
            if (button["for"]) {
                button = document.getElementById(button["for"]);
            }
            if (!button.disabled) {
                var rasterControls = map.getControlsByClass("OpenLayers.Control.RasterOverlayLayerSwitcher");
                var dataLayers = [].concat.apply([],rasterControls.map(function(x){return x.dataLayers}));
                for (i = 0, len = dataLayers.length; i < len; i += 1) {

                    layerEntry = dataLayers[i];

                    if (layerEntry.inputElem !== button) {
                        OpenLayers.Element.removeClass(layerEntry.inputElem, "checked");
                        OpenLayers.Element.removeClass(layerEntry.inputElem, "is-checked");
                        layerEntry.inputElem.checked = false;
                    } else {
                        pin = i;
                        OpenLayers.Element.addClass(layerEntry.inputElem, "checked");
                        OpenLayers.Element.addClass(layerEntry.inputElem, "is-checked");
                        layerEntry.inputElem.checked = true;

                        if (!!layerEntry.layer.maxExtent) {
                          var extent = layerEntry.layer.maxExtent;
                          if (!extent.containsLonLat(map.getCenter())) {
                            map.zoomToExtent(extent);
                          }
                        }

                    }
                }
                for (i = 0; i < rasterControls.length; i++) {
                  rasterControls[i].updateMap( [this.pin || 0, pin || 0] , this != rasterControls[i] );
                }
                this.pin = pin;
            }
            this.map.events.triggerEvent('rasterLayersChangedByClick', {});
        }
    },
    CLASS_NAME: "OpenLayers.Control.RasterOverlayLayerSwitcher"
});
<|endoftext|>


<commit_before>import HashMap from 'hashmap'
import MenuInterface from './MenuInterface'
import BoardInterface from './BoardInterface'

export default class Interface {
  /**
   * @param {Game} game
   * @param {window} window
   */
  constructor (game, window) {
    /** @type {Game} */
    this.game = game

    /** @type {Window} */
    this.window = window

    /** @type {PIXI.Application|null} */
    this.pixiApp = null

    /** @type {HashMap} */
    this.cellInterfacesMap = new HashMap()
  }

  initialize () {
    let document = this.window.document
    this.pixiApp = new PIXI.Application(
      document.body.offsetWidth,
      document.body.offsetHeight,
      {antialias: true}
    )
    document.body.appendChild(this.pixiApp.view)

    let menuInterface = new MenuInterface(this.pixiApp.stage, this.game)
    menuInterface.initialize()

    let boardInterface = new BoardInterface(this.pixiApp, this.game)
    boardInterface.initialize()

    this.game.events.listen('playerLost', data => this.window.alert(data.player.name + ' has lost the match!'))
  }
}
<commit_msg>removed unused HashMap from Interface.js<commit_after>import MenuInterface from './MenuInterface'
import BoardInterface from './BoardInterface'

export default class Interface {
  /**
   * @param {Game} game
   * @param {window} window
   */
  constructor (game, window) {
    /** @type {Game} */
    this.game = game

    /** @type {Window} */
    this.window = window

    /** @type {PIXI.Application|null} */
    this.pixiApp = null
  }

  initialize () {
    let document = this.window.document
    this.pixiApp = new PIXI.Application(
      document.body.offsetWidth,
      document.body.offsetHeight,
      {antialias: true}
    )
    document.body.appendChild(this.pixiApp.view)

    let menuInterface = new MenuInterface(this.pixiApp.stage, this.game)
    menuInterface.initialize()

    let boardInterface = new BoardInterface(this.pixiApp, this.game)
    boardInterface.initialize()

    this.game.events.listen('playerLost', data => this.window.alert(data.player.name + ' has lost the match!'))
  }
}
<|endoftext|>


<commit_before>// jsonParser.js
String.prototype.contains = function(str, ignoreCase) {
	return (ignoreCase ? this.toUpperCase() : this)
	.indexOf(ignoreCase ? str.toUpperCase() : str) >= 0;
};

var jsonParser = function(JSON){
	var dependencies = JSON[dependencies];

	var repoData = {
			libraryCollection: {
				react : false,
				angular: false,
				ember: false,
				backbone: false,
				mithril: false,
				polymer: false,
				flight: false,
				capuccino: false,
				spine: false,
				aurelia: false
			}
		};
		// loop through the dependencies
		for(var dep in dependencies){
			// loop through our comparators
			for(var key in repoData){
				if(dep.contains(key, true)){
					repoData.libraryCollection[key] = true;
					// flag comparator as true if found
				}
			}
		}
		return repoData;
};<commit_msg>testing .travis.yml file<commit_after>// jsonParser.js
String.prototype.contains = function(str, ignoreCase) {
	return (ignoreCase ? this.toUpperCase() : this)
	.indexOf(ignoreCase ? str.toUpperCase() : str) >= 0;
};

var jsonParser = function(JSON){
	var dependencies = JSON[dependencies];

	var repoData = {
			libraryCollection: {
				react : false,
				angular: false,
				ember: false,
				backbone: false,
				mithril: false,
				polymer: false,
				flight: false,
				capuccino: false,
				aurelia: false
				spine: false,
			}
		};
		// loop through the dependencies
		for(var dep in dependencies){
			// loop through our comparators
			for(var key in repoData){
				if(dep.contains(key, true)){
					repoData.libraryCollection[key] = true;
					// flag comparator as true if found
				}
			}
		}
		return repoData;
};<|endoftext|>


<commit_before>var LCD = require('lcd-pcf8574');

/**
 * Module for displaying onto the lcd screen (4*20 characters)
 * @param i2cDev I2C port (/dev/i2c-0 or /dev/i2c-1 according to Raspi version)
 * @param address I2C address of the module (0x27 for standard lcm1602 module)
 * @param nbLines Number of lines on the screen
 * @param nbCols Number of columns on the screen
 */
module.exports = function(i2cDev, address, nbLines, nbCols) {
	var lcd = new LCD(i2cDev, address);
	var curX = 0, curY = 0;

	//init accents
	lcd .createChar(0, [ 130,132,142,145,159,144,142,128 ]) //é
		.createChar(1, [ 136,132,142,145,159,144,142,128 ]) //è
		.createChar(2, [ 132,138,142,145,159,144,142,128 ]) //ê
		.createChar(3, [ 136,134,128,142,145,147,141,128 ]) //à
		.createChar(4, [ 132,138,128,142,145,147,141,128 ]) //â
		.createChar(5, [ 132,138,128,140,132,132,142,128 ]) //î
		.createChar(6, [ 132,138,128,145,145,147,141,128 ]) //û
		.createChar(7, [ 136,134,128,145,145,147,141,128 ]) //ù
		;

	function replaceAccent(str) {
		var chars = ['é', 'è', 'ê', 'à', 'â', 'î', 'û', 'ù'];
		for (var i = 0; i < chars.length; i++) {
			var char = chars[i];
			str = str.replace(char, String.fromCharCode(i));
		}
		return str;
	}

	/**
	 * Move the cursor to the selected position
	 * @param x horizontal position, starts at 0
	 * @param y vertical position, start at 0
	 */
	var goto = function(x, y) {
		lcd.setCursor(x, y);
		curX = x;
		curY = y;
		return this;
	};

	/**
	 * Print a string on the screen at the current location.
	 * If the string is too large for the screen, the string is cut and go to the next line.
	 * The cursor is reset to the initial location after the print.
	 * @param str String to print
	 */
	var print = function(str) {
		var maxStr = str,
			xOrig = curX,
			yOrig = curY;

		while (maxStr.length > (nbCols - curX) && (curY < nbLines - 1)) {
			var maxLength = (nbCols - curX),
				printStr = maxStr.substr(0, maxLength);
			maxStr = maxStr.substr(maxLength);
			lcd.print(replaceAccent(printStr));
			goto(0, curY + 1);
		}

		//at this point, the string has the correct length to be print in the space left
		//or on the last line
		lcd.print(replaceAccent(maxStr.substr(0, nbCols - curX)));

		goto(xOrig, yOrig);
		return this;
	};

	/** Empty the LCD screen */
	var clear = function() {
		lcd.clear();
		return this;
	};

	return {
		goto: goto,
		print: print,
		clear: clear
	}
};<commit_msg>replace was only replacing the 1st special char on each line<commit_after>var LCD = require('lcd-pcf8574');

/**
 * Module for displaying onto the lcd screen (4*20 characters)
 * @param i2cDev I2C port (/dev/i2c-0 or /dev/i2c-1 according to Raspi version)
 * @param address I2C address of the module (0x27 for standard lcm1602 module)
 * @param nbLines Number of lines on the screen
 * @param nbCols Number of columns on the screen
 */
module.exports = function(i2cDev, address, nbLines, nbCols) {
	var lcd = new LCD(i2cDev, address);
	var curX = 0, curY = 0;

	//init accents
	lcd .createChar(0, [ 130,132,142,145,159,144,142,128 ]) //é
		.createChar(1, [ 136,132,142,145,159,144,142,128 ]) //è
		.createChar(2, [ 132,138,142,145,159,144,142,128 ]) //ê
		.createChar(3, [ 136,134,128,142,145,147,141,128 ]) //à
		.createChar(4, [ 132,138,128,142,145,147,141,128 ]) //â
		.createChar(5, [ 132,138,128,140,132,132,142,128 ]) //î
		.createChar(6, [ 132,138,128,145,145,147,141,128 ]) //û
		.createChar(7, [ 136,134,128,145,145,147,141,128 ]) //ù
		;

	function replaceAccent(str) {
		var chars = ['é', 'è', 'ê', 'à', 'â', 'î', 'û', 'ù'];
		for (var i = 0; i < chars.length; i++) {
			var char = chars[i];
			str = str.replace(RegExp(char,"g"), String.fromCharCode(i));
		}
		return str;
	}

	/**
	 * Move the cursor to the selected position
	 * @param x horizontal position, starts at 0
	 * @param y vertical position, start at 0
	 */
	var goto = function(x, y) {
		lcd.setCursor(x, y);
		curX = x;
		curY = y;
		return this;
	};

	/**
	 * Print a string on the screen at the current location.
	 * If the string is too large for the screen, the string is cut and go to the next line.
	 * The cursor is reset to the initial location after the print.
	 * @param str String to print
	 */
	var print = function(str) {
		var maxStr = str,
			xOrig = curX,
			yOrig = curY;

		while (maxStr.length > (nbCols - curX) && (curY < nbLines - 1)) {
			var maxLength = (nbCols - curX),
				printStr = maxStr.substr(0, maxLength);
			maxStr = maxStr.substr(maxLength);
			lcd.print(replaceAccent(printStr));
			goto(0, curY + 1);
		}

		//at this point, the string has the correct length to be print in the space left
		//or on the last line
		lcd.print(replaceAccent(maxStr.substr(0, nbCols - curX)));

		goto(xOrig, yOrig);
		return this;
	};

	/** Empty the LCD screen */
	var clear = function() {
		lcd.clear();
		return this;
	};

	return {
		goto: goto,
		print: print,
		clear: clear
	}
};
<|endoftext|>


<commit_before>var Memcached = require('./memcached.js')
  , fs = require('fs')
  , exec  = require('child_process').exec
  , crypto = require('crypto')

var memcached = new Memcached();
memcached.connect();

var mockMemcached = {
    store: function(key, data, callback) {
        if (callback) {
            callback(new Error("Memcached is OFF"), null);
        }
    },
    get: function(key, callback) {
        callback(new Error({info: "Memcached is disabled in the app"}));
    }
}

function validateOptions(opts) {
    console.log(JSON.stringify(opts));
    if (!opts.entity) {
        throw new Error("No entity is given for processing!");
    }
    if (!opts.type) {
        throw new Error("Type must be declared for processing!");
    }

    if (opts.type != "file" && opts.type != "git" && opts.type != "url" && opts.type != "text") {
        throw new Error("Type must be one of FILE, GIT, URL, TEXT");
    }

    if (opts.type == "url" || opts.type == "text") {
        return;
    }

    if (!opts.target) {
        throw new Error("Target must be specified!");
    }

}

function RequestProcessor(options, callback) {
    var self = this;

    options = options || {};
    options.disableCaching = options.disableCaching || false;
    this.options = options;

    validateOptions(this.options);

    if (!options.disableCaching) {
        self.memcached = memcached;
    } else {
        self.memcached= mockMemcached;
    }
    self.webServiceCallback = callback;

    if (!self.webServiceCallback) {
        throw new Error("Cannot process request without webService callback!");
    }

    this.finishProcessing = function(err, data) {
        self.webServiceCallback(err, data);
        exec('bash shells/cleanup.sh ' + self.tmpdir);
    }

    this.execShellScript = function(cmd, callback) {
        var timeout = 1000*60*2;// no more than 2 minutes evaluation
        exec(cmd, {timeout: timeout}, function(error, stdout, stderr) {
            if (error) {
                console.error("Script '" + cmd + "' exec error: " + stderr);
                self.finishProcessing(new Error(stderr), null);
            } else {
                callback(stdout.trim());
            }
        });
    }

    this.readFile = function(file, callback) {
        fs.readFile(file, function(err, data){
            if (err) {
                console.error("File read error: " + err);
                self.finishProcessing(err, null);
            } else {
                callback(data);
            }
        });
    }

    this.memcacheGet = function(key, getFailedCallback) {
        self.memcached.get(key, function(err, data) {
            if (err || !data) {
                if (err) {
                    console.log("Memcached GET " + key + " error: " + err.message);
                } else {
                    console.log("Memcached GET " + key + " didn't return any value");
                }
                getFailedCallback();
            } else {
                console.log("fetched " + data.length + " bytes from memcache for KEY " + key);
                self.finishProcessing(null, data);
            }
        });
    }

    this.memcacheStore = function(key, data) {
        self.memcached.store(key, data, function(err, resp) {
            self.finishProcessing(null, data);
            console.log("Memcache store response: " + resp);
        });
    }

    this.mkTempDir = function(callback) {
        this.execShellScript("bash shells/mkTempDir.sh tmp", callback);
    }

    this.hashSum = function(type, entity, callback) {
        var cmd = "bash shells/hashSum.sh ";
        if (type == "file") {
            cmd += "-f ";
        } else if (type == "git") {
            cmd += "-g ";
        } else {
            throw new Error("Unknown type for hashSum: " + type);
        }
        cmd += entity;
        this.execShellScript(cmd, callback);
    }

    this.hashAndGet = function(type, entity, failCallback) {
        self.hashSum(type, entity, function(hash) {
            self.memcacheGet(hash, function() {
                failCallback(hash);
            });
        });
    }

    // Hash for git repository is a combination of SHA of its master branch
    // and target file
    this.hashAndGetGit = function(entity, target, failCallback) {
        self.hashSum("git", entity, function(hash) {
            hash = crypto.createHash('md5').update(hash + target).digest('hex');
            self.memcacheGet(hash, function() {
                failCallback(hash);
            });
        });
    };

    this.fetch = function(type, entity, callback) {
        var cmd = 'bash shells/fetch.sh ' + self.tmpdir + " ";
        if (type == "file") {
            cmd += "-f ";
        } else if (type == "url") {
            cmd += "-u ";
        } else if (type == "git") {
            cmd += "-g ";
        } else {
            throw new Error("Wrong options passed to fetch: " + JSON.stringify(options));
        }
        cmd += entity;

        this.execShellScript(cmd, callback);
    }

    this.compile = function (rootdir, target,callback) {
        var cmd = 'bash shells/compile.sh ' + rootdir + ' ' + target;
        this.execShellScript(cmd, function (compiledFileName) {
            console.log("Compiled file saved as: " + compiledFileName);
            self.readFile(compiledFileName, function(data){
                console.log("Successfully read " + data.length + " bytes");
                callback(data);
            });
        });
    }

    this.processUrl = function() {

        function fetchCallback(fetchedFile) {
            self.hashAndGet("file", self.tmpdir + "/" + fetchedFile, function(hash) {
                self.compile(self.tmpdir, fetchedFile, function(data) {
                    self.memcached.store(hash, data, function(err, resp) {
                        self.finishProcessing(null, data);
                        console.log("Memcache store response: " + resp);
                    });
                });
            });
        }

        self.mkTempDir(function(tmpDir) {
            self.tmpdir = tmpDir;
            self.fetch(self.options.type, self.options.entity, fetchCallback);
        });
    }

    this.processText = function() {

      function fetchCallback(fetchedFile) {
          self.hashAndGet("file", self.tmpdir + "/" + fetchedFile, function(hash) {
              self.compile(self.tmpdir, fetchedFile, function(data) {
                  self.memcached.store(hash, data, function(err, resp) {
                      self.finishProcessing(null, data);
                      console.log("Memcache store response: " + resp);
                  });
              });
          });
      }

      self.mkTempDir(function(tmpDir) {
        self.tmpdir = tmpDir;
        var cmd = "cat > " + tmpDir + "/" + "source.tex <<HEREDOC && echo source.tex\n";
        cmd += self.options.entity;
        cmd += "\nHEREDOC";

        self.execShellScript(cmd, fetchCallback);
      });
    }

    this.processFileUpload = function() {

        function fetchCallback() {
            self.compile(self.tmpdir, self.options.target, function(data) {
                self.memcacheStore(self.hash, data);
            });
        }

        function mkTempDirCallback(tmpDir) {
            self.tmpdir = tmpDir;
            self.fetch(self.options.type, self.options.entity, fetchCallback);
        }

        self.hashAndGet("file", self.options.entity, function(hash) {
            self.hash = hash;
            self.mkTempDir(mkTempDirCallback);
        });
    }

    this.processGit = function() {
        function mkTempDirCallback(tmpDir) {
            self.tmpdir = tmpDir;
            self.hashAndGetGit(self.options.entity, self.options.target, hashAndGetCallback);
        }

        function hashAndGetCallback(hash) {
            self.hash = hash;
            self.fetch(self.options.type, self.options.entity, fetchCallback);
        }

        function fetchCallback(gitDir) {
            self.compile(self.tmpdir + "/" + gitDir, self.options.target, function(data) {
                self.memcacheStore(self.hash, data);
            });
        }

        self.mkTempDir(mkTempDirCallback);
    }

    if (self.options.type == "file") {
        self.processFileUpload();
    } else
    if (self.options.type == "url") {
        self.processUrl();
    } else
    if (self.options.type == "git") {
        self.processGit();
    } else
    if (self.options.type == "text") {
        self.processText();
    } else {
        throw new Error("Unknown processing type requested");
    }
}

function processFile(file, target, callback) {
    var rp = new RequestProcessor({
        type: "file",
        entity: file,
        target: target
    }, callback);
    rp.processFileUpload();
}

function processUrl(url, callback) {
    var rp = new RequestProcessor({
        type: "url",
        entity: url
    }
    , callback);
    rp.processUrl();
}

function processGit(git, target, callback) {
    var rp = new RequestProcessor({
        type: "git",
        entity: git,
        target: target
    }, callback);
    rp.processGit();
}

module.exports = {};
module.exports.RequestProcessor = RequestProcessor;
<commit_msg>use system tmp dir for temp files<commit_after>var Memcached = require('./memcached.js')
  , fs = require('fs')
  , exec  = require('child_process').exec
  , crypto = require('crypto')

var memcached = new Memcached();
memcached.connect();

var mockMemcached = {
    store: function(key, data, callback) {
        if (callback) {
            callback(new Error("Memcached is OFF"), null);
        }
    },
    get: function(key, callback) {
        callback(new Error({info: "Memcached is disabled in the app"}));
    }
}

function validateOptions(opts) {
    console.log(JSON.stringify(opts));
    if (!opts.entity) {
        throw new Error("No entity is given for processing!");
    }
    if (!opts.type) {
        throw new Error("Type must be declared for processing!");
    }

    if (opts.type != "file" && opts.type != "git" && opts.type != "url" && opts.type != "text") {
        throw new Error("Type must be one of FILE, GIT, URL, TEXT");
    }

    if (opts.type == "url" || opts.type == "text") {
        return;
    }

    if (!opts.target) {
        throw new Error("Target must be specified!");
    }

}

function RequestProcessor(options, callback) {
    var self = this;

    options = options || {};
    options.disableCaching = options.disableCaching || false;
    this.options = options;

    validateOptions(this.options);

    if (!options.disableCaching) {
        self.memcached = memcached;
    } else {
        self.memcached= mockMemcached;
    }
    self.webServiceCallback = callback;

    if (!self.webServiceCallback) {
        throw new Error("Cannot process request without webService callback!");
    }

    this.finishProcessing = function(err, data) {
        self.webServiceCallback(err, data);
        exec('bash shells/cleanup.sh ' + self.tmpdir);
    }

    this.execShellScript = function(cmd, callback) {
        var timeout = 1000*60*2;// no more than 2 minutes evaluation
        exec(cmd, {timeout: timeout}, function(error, stdout, stderr) {
            if (error) {
                console.error("Script '" + cmd + "' exec error: " + stderr);
                self.finishProcessing(new Error(stderr), null);
            } else {
                callback(stdout.trim());
            }
        });
    }

    this.readFile = function(file, callback) {
        fs.readFile(file, function(err, data){
            if (err) {
                console.error("File read error: " + err);
                self.finishProcessing(err, null);
            } else {
                callback(data);
            }
        });
    }

    this.memcacheGet = function(key, getFailedCallback) {
        self.memcached.get(key, function(err, data) {
            if (err || !data) {
                if (err) {
                    console.log("Memcached GET " + key + " error: " + err.message);
                } else {
                    console.log("Memcached GET " + key + " didn't return any value");
                }
                getFailedCallback();
            } else {
                console.log("fetched " + data.length + " bytes from memcache for KEY " + key);
                self.finishProcessing(null, data);
            }
        });
    }

    this.memcacheStore = function(key, data) {
        self.memcached.store(key, data, function(err, resp) {
            self.finishProcessing(null, data);
            console.log("Memcache store response: " + resp);
        });
    }

    this.mkTempDir = function(callback) {
        this.execShellScript("bash shells/mkTempDir.sh /tmp", callback);
    }

    this.hashSum = function(type, entity, callback) {
        var cmd = "bash shells/hashSum.sh ";
        if (type == "file") {
            cmd += "-f ";
        } else if (type == "git") {
            cmd += "-g ";
        } else {
            throw new Error("Unknown type for hashSum: " + type);
        }
        cmd += entity;
        this.execShellScript(cmd, callback);
    }

    this.hashAndGet = function(type, entity, failCallback) {
        self.hashSum(type, entity, function(hash) {
            self.memcacheGet(hash, function() {
                failCallback(hash);
            });
        });
    }

    // Hash for git repository is a combination of SHA of its master branch
    // and target file
    this.hashAndGetGit = function(entity, target, failCallback) {
        self.hashSum("git", entity, function(hash) {
            hash = crypto.createHash('md5').update(hash + target).digest('hex');
            self.memcacheGet(hash, function() {
                failCallback(hash);
            });
        });
    };

    this.fetch = function(type, entity, callback) {
        var cmd = 'bash shells/fetch.sh ' + self.tmpdir + " ";
        if (type == "file") {
            cmd += "-f ";
        } else if (type == "url") {
            cmd += "-u ";
        } else if (type == "git") {
            cmd += "-g ";
        } else {
            throw new Error("Wrong options passed to fetch: " + JSON.stringify(options));
        }
        cmd += entity;

        this.execShellScript(cmd, callback);
    }

    this.compile = function (rootdir, target,callback) {
        var cmd = 'bash shells/compile.sh ' + rootdir + ' ' + target;
        this.execShellScript(cmd, function (compiledFileName) {
            console.log("Compiled file saved as: " + compiledFileName);
            self.readFile(compiledFileName, function(data){
                console.log("Successfully read " + data.length + " bytes");
                callback(data);
            });
        });
    }

    this.processUrl = function() {

        function fetchCallback(fetchedFile) {
            self.hashAndGet("file", self.tmpdir + "/" + fetchedFile, function(hash) {
                self.compile(self.tmpdir, fetchedFile, function(data) {
                    self.memcached.store(hash, data, function(err, resp) {
                        self.finishProcessing(null, data);
                        console.log("Memcache store response: " + resp);
                    });
                });
            });
        }

        self.mkTempDir(function(tmpDir) {
            self.tmpdir = tmpDir;
            self.fetch(self.options.type, self.options.entity, fetchCallback);
        });
    }

    this.processText = function() {

      function fetchCallback(fetchedFile) {
          self.hashAndGet("file", self.tmpdir + "/" + fetchedFile, function(hash) {
              self.compile(self.tmpdir, fetchedFile, function(data) {
                  self.memcached.store(hash, data, function(err, resp) {
                      self.finishProcessing(null, data);
                      console.log("Memcache store response: " + resp);
                  });
              });
          });
      }

      self.mkTempDir(function(tmpDir) {
        self.tmpdir = tmpDir;
        var cmd = "cat > " + tmpDir + "/" + "source.tex <<HEREDOC && echo source.tex\n";
        cmd += self.options.entity;
        cmd += "\nHEREDOC";

        self.execShellScript(cmd, fetchCallback);
      });
    }

    this.processFileUpload = function() {

        function fetchCallback() {
            self.compile(self.tmpdir, self.options.target, function(data) {
                self.memcacheStore(self.hash, data);
            });
        }

        function mkTempDirCallback(tmpDir) {
            self.tmpdir = tmpDir;
            self.fetch(self.options.type, self.options.entity, fetchCallback);
        }

        self.hashAndGet("file", self.options.entity, function(hash) {
            self.hash = hash;
            self.mkTempDir(mkTempDirCallback);
        });
    }

    this.processGit = function() {
        function mkTempDirCallback(tmpDir) {
            self.tmpdir = tmpDir;
            self.hashAndGetGit(self.options.entity, self.options.target, hashAndGetCallback);
        }

        function hashAndGetCallback(hash) {
            self.hash = hash;
            self.fetch(self.options.type, self.options.entity, fetchCallback);
        }

        function fetchCallback(gitDir) {
            self.compile(self.tmpdir + "/" + gitDir, self.options.target, function(data) {
                self.memcacheStore(self.hash, data);
            });
        }

        self.mkTempDir(mkTempDirCallback);
    }

    if (self.options.type == "file") {
        self.processFileUpload();
    } else
    if (self.options.type == "url") {
        self.processUrl();
    } else
    if (self.options.type == "git") {
        self.processGit();
    } else
    if (self.options.type == "text") {
        self.processText();
    } else {
        throw new Error("Unknown processing type requested");
    }
}

function processFile(file, target, callback) {
    var rp = new RequestProcessor({
        type: "file",
        entity: file,
        target: target
    }, callback);
    rp.processFileUpload();
}

function processUrl(url, callback) {
    var rp = new RequestProcessor({
        type: "url",
        entity: url
    }
    , callback);
    rp.processUrl();
}

function processGit(git, target, callback) {
    var rp = new RequestProcessor({
        type: "git",
        entity: git,
        target: target
    }, callback);
    rp.processGit();
}

module.exports = {};
module.exports.RequestProcessor = RequestProcessor;
<|endoftext|>


<commit_before>var fs = require('fs');

var cmd = module.exports = {};

cmd.type = "basic";
cmd.command = true;
cmd.help = "Help !";
cmd.args = '';

cmd.run = (msg, args) => {
  function format(file, help) {
    var line = '.'+file.replace(".js", "")+"  = "+help+"";
    return line;
  }
  var files = fs.readdirSync("./commands/");
  var lines = ['**```md','[ Commands ]'];
  files.forEach(function(file) {
    if(file.indexOf(".js")) {
      var cmd = require("./"+file)
      lines.push(format(file, cmd.help));
    }
  });
  lines.push('```**');
  var message = lines.join("\n");
  ys.send(msg.author, message);
  ys.send(msg.channel, 'All commands have been sent, look in your DM.');
};
<commit_msg>[EDIT] Help command now only show basic commands.<commit_after>var fs = require('fs');

var cmd = module.exports = {};

cmd.type = "basic";
cmd.command = true;
cmd.help = "Help !";
cmd.args = '';

cmd.run = (msg, args) => {
  function format(file, help) {
    var line = '.'+file.replace(".js", "")+"  = "+help+"";
    return line;
  }
  var files = fs.readdirSync("./commands/");
  var lines = ['**```css','[ Commands ]'];
  files.forEach(function(file) {
    if(file.indexOf(".js")) {
      var cmd = require("./"+file)
      if (cmd.type === 'basic') {
        lines.push(format(file, cmd.help));
      }
    }
  });
  lines.push('```**');
  var message = lines.join("\n");
  ys.send(msg.author, message);
  ys.send(msg.channel, 'All commands have been sent, look in your DM.');
};
<|endoftext|>


<commit_before>const Discord = require('discord.js');
const Util = require('../classes/Util.js');
module.exports.name = 'kick';

module.exports.alias = ['kick'];

module.exports.isAllowed = (message, server) => {
  return (
    message.member.hasPermission('ADMINISTRATOR') ||
    message.member.roles.cache.has('543721608506900480')
  );
};

module.exports.help = ',kick <member>';

module.exports.command = async (message, content, bot, server) => {
  const badPeople = [];
  const executor = message.author;
  let reason = 'Unspecified';
  content = content.replace(Util.REGEX_USER, '');
  const ids = content.match(Util.REGEX_RAW_ID);
  if (ids) {
    badPeople.push(...ids);
    content = content.replace(Util.REGEX_RAW_ID, '');
  }
  badPeople.push(...message.mentions.users.keys());
  if (badPeople.length == 0) {
    message.channel.send('Could not resolve users.');
    return;
  }

  const badIDs = [];
  const badMembers = badPeople
    .map((id) => {
      const mem = server.guild.member(id);
      if (!mem) badIDs.push(id);
      return mem;
    })
    .filter(Boolean);

  // actually ban
  if (!badMembers.every((mem) => mem.bannable)) {
    message.channel.send('They cannot be kicked');
    return;
  }
  let options = /\s?(.*)/.exec(content);
  if (options) {
    if (options[1]) {
      reason = options[1];
    }
  }

  const auditLogReason = `Issued by: ${executor.tag}. Reason: ${reason}`;
  if (auditLogReason.length > 512) {
    await message.channel.send(
      `The kick reason exceeds the limit of 512 characters: ${auditLogReason.length} characters`
    );
    return;
  }
  const bannedPeople = badPeople.map((id) => `<@${id}>`).join('\n');
  const failedBans = [];

  let banMessage = `<:hypergeralthinkban:443803651325034507>  **You are kicking**  <:hypergeralthinkban:443803651325034507>\n\n${bannedPeople}\n\n__Reason__: ${reason}\nType \`confirm\` or \`cancel\``;
  await message.channel.send(banMessage);
  const filter = (m) => m.member.id == executor.id;
  const collector = message.channel.createMessageCollector(filter, {
    time: 45000,
  });
  collector.on('collect', async (m) => {
    const resp = m.content.toLowerCase();
    if (resp === 'confirm') {
      let someBan = false;
      await Promise.all(
        badMembers.map(async (mem) => {
          try {
            await mem.send(
              `You have been kicked from ${server.guild}.\nReason: ${reason}`
            );
          } catch (e) {
            await message.channel.send(
              `Failed to DM the kick reason to ${mem}`
            );
          }
          try {
            await server.guild.members.kick(mem, {
              reason: auditLogReason,
            });
            someBan = true;
            const warning = {
              issued: message.createdTimestamp,
              issuer: message.author.id,
              link: message.url,
              warnMessage: 'Kicked: ' + reason,
            };
            if (server.warnlist[mem.id]) {
              server.warnlist[mem.id].push(warning);
            } else {
              server.warnlist[mem.id] = [warning];
            }
          } catch (e) {
            await message.channel.send(`Failed to kick ${mem}`);
            failedBans.push(mem.id);
          }
        })
      );
      await Promise.all(
        badIDs.map(async (id) => {
          try {
            await server.guild.members.kick(id, {
              reason: auditLogReason,
            });
            someBan = true;
            const warning = {
              issued: message.createdTimestamp,
              issuer: message.author.id,
              link: message.url,
              warnMessage: 'Kicked: ' + reason,
            };
            if (server.warnlist[id]) {
              server.warnlist[id].push(warning);
            } else {
              server.warnlist[id] = [warning];
            }
          } catch (e) {
            await message.channel.send(`Failed to kick <@${id}>`);
            failedBans.push(id);
          }
        })
      );
      if (someBan) {
        collector.stop('Kicked');
      } else {
        collector.stop('Failed');
      }
      return;
    }
    if (resp == 'cancel') {
      collector.stop('Cancelled');
      return;
    }
    message.channel.send('Invalid response. Type `confirm` or `cancel`');
  });
  collector.on('end', (collected, endReason) => {
    if (endReason == 'Kicked') {
      const actualBanned = badPeople.filter((p) => !failedBans.includes(p));
      message.channel.send('✅ Kicked');
      const agt = server.guild.channels.cache.get('755269708579733626');
      let embed = new Discord.MessageEmbed();
      let date = new Date();
      embed.setAuthor(`${message.author.tag}`, message.author.avatarURL());
      embed.title = 'Kick';
      embed.addField(
        'Kicked users:',
        actualBanned.map((b) => `<@${b}>`).join('\n'),
        false
      );
      embed.addField('Kick reason:', reason, false);
      embed.color = Number('0x000000');
      embed.setFooter(`In #${message.channel.name}`);
      embed.timestamp = date;
      agt.send({ embed });

      server.save();
      return;
    } else if (endReason == 'Cancelled') {
      message.channel.send('❌ Cancelled');
      return;
    } else if (endReason == 'Failed') {
      message.channel.send('❌ Unable to kick them');
      return;
    } else {
      message.channel.send('❌ Failed to confirm');
      return;
    }
  });
};
<commit_msg>check server<commit_after>const Discord = require('discord.js');
const Util = require('../classes/Util.js');
module.exports.name = 'kick';

module.exports.alias = ['kick'];

module.exports.isAllowed = (message, server) => {
  return (
    message.member.hasPermission('ADMINISTRATOR') ||
    message.member.roles.cache.has('543721608506900480')
  );
};

module.exports.help = ',kick <member>';

module.exports.command = async (message, content, bot, server) => {
  const badPeople = [];
  const executor = message.author;
  let reason = 'Unspecified';
  content = content.replace(Util.REGEX_USER, '');
  const ids = content.match(Util.REGEX_RAW_ID);
  if (ids) {
    badPeople.push(...ids);
    content = content.replace(Util.REGEX_RAW_ID, '');
  }
  badPeople.push(...message.mentions.users.keys());
  if (badPeople.length == 0) {
    message.channel.send('Could not resolve users.');
    return;
  }

  const badIDs = [];
  const badMembers = badPeople
    .map((id) => {
      const mem = server.guild.member(id);
      if (!mem) badIDs.push(id);
      return mem;
    })
    .filter(Boolean);

  // actually ban
  if (!badMembers.every((mem) => mem.bannable)) {
    message.channel.send('They cannot be kicked');
    return;
  }
  let options = /\s?(.*)/.exec(content);
  if (options) {
    if (options[1]) {
      reason = options[1];
    }
  }

  const auditLogReason = `Issued by: ${executor.tag}. Reason: ${reason}`;
  if (auditLogReason.length > 512) {
    await message.channel.send(
      `The kick reason exceeds the limit of 512 characters: ${auditLogReason.length} characters`
    );
    return;
  }
  const bannedPeople = badPeople.map((id) => `<@${id}>`).join('\n');
  const failedBans = [];

  let banMessage = `<:hypergeralthinkban:443803651325034507>  **You are kicking**  <:hypergeralthinkban:443803651325034507>\n\n${bannedPeople}\n\n__Reason__: ${reason}\nType \`confirm\` or \`cancel\``;
  await message.channel.send(banMessage);
  const filter = (m) => m.member.id == executor.id;
  const collector = message.channel.createMessageCollector(filter, {
    time: 45000,
  });
  collector.on('collect', async (m) => {
    const resp = m.content.toLowerCase();
    if (resp === 'confirm') {
      let someBan = false;
      await Promise.all(
        badMembers.map(async (mem) => {
          try {
            await mem.send(
              `You have been kicked from ${server.guild}.\nReason: ${reason}`
            );
          } catch (e) {
            await message.channel.send(
              `Failed to DM the kick reason to ${mem}`
            );
          }
          try {
            await server.guild.members.kick(mem, {
              reason: auditLogReason,
            });
            someBan = true;
            const warning = {
              issued: message.createdTimestamp,
              issuer: message.author.id,
              link: message.url,
              warnMessage: 'Kicked: ' + reason,
            };
            if (server.warnlist[mem.id]) {
              server.warnlist[mem.id].push(warning);
            } else {
              server.warnlist[mem.id] = [warning];
            }
          } catch (e) {
            await message.channel.send(`Failed to kick ${mem}`);
            failedBans.push(mem.id);
          }
        })
      );
      await Promise.all(
        badIDs.map(async (id) => {
          try {
            await server.guild.members.kick(id, {
              reason: auditLogReason,
            });
            someBan = true;
            const warning = {
              issued: message.createdTimestamp,
              issuer: message.author.id,
              link: message.url,
              warnMessage: 'Kicked: ' + reason,
            };
            if (server.warnlist[id]) {
              server.warnlist[id].push(warning);
            } else {
              server.warnlist[id] = [warning];
            }
          } catch (e) {
            await message.channel.send(`Failed to kick <@${id}>`);
            failedBans.push(id);
          }
        })
      );
      if (someBan) {
        collector.stop('Kicked');
      } else {
        collector.stop('Failed');
      }
      return;
    }
    if (resp == 'cancel') {
      collector.stop('Cancelled');
      return;
    }
    message.channel.send('Invalid response. Type `confirm` or `cancel`');
  });
  collector.on('end', (collected, endReason) => {
    if (endReason == 'Kicked') {
      const actualBanned = badPeople.filter((p) => !failedBans.includes(p));
      message.channel.send('✅ Kicked');
      const agt = server.guild.channels.cache.get('755269708579733626');
      if (!agt) return;
      let embed = new Discord.MessageEmbed();
      let date = new Date();
      embed.setAuthor(`${message.author.tag}`, message.author.avatarURL());
      embed.title = 'Kick';
      embed.addField(
        'Kicked users:',
        actualBanned.map((b) => `<@${b}>`).join('\n'),
        false
      );
      embed.addField('Kick reason:', reason, false);
      embed.color = Number('0x000000');
      embed.setFooter(`In #${message.channel.name}`);
      embed.timestamp = date;
      agt.send({ embed });

      server.save();
      return;
    } else if (endReason == 'Cancelled') {
      message.channel.send('❌ Cancelled');
      return;
    } else if (endReason == 'Failed') {
      message.channel.send('❌ Unable to kick them');
      return;
    } else {
      message.channel.send('❌ Failed to confirm');
      return;
    }
  });
};
<|endoftext|>


<commit_before>const nodeW3CValidator = require('node-w3c-validator');
const del = require('del');

module.exports = () => {
  const settings = require(`${process.cwd()}/marmelad/settings.marmelad`);
  const options = Object.assign({
    format: 'html',
    skipNonHtml: true,
    exec: {
      maxBuffer: 1024 * 1024,
    },
    reportName: 'w3c-validator.html',
  }, settings.w3cValidator);

  del.sync(`${settings.paths.dist}/${options.reportName}`);

  nodeW3CValidator(`${settings.paths.dist}/**/*.html`, options, (err, output) => {
    if (err === null) {
      return;
    }
    nodeW3CValidator.writeFile(`${settings.paths.dist}/${options.reportName}`, output);
  });
};
<commit_msg>Изменил название переменной для хранения опция w3c валидатора<commit_after>const nodeW3CValidator = require('node-w3c-validator');
const del = require('del');

module.exports = () => {
  const settings = require(`${process.cwd()}/marmelad/settings.marmelad`);

  const nw3cOpts = Object.assign({
    format: 'html',
    skipNonHtml: true,
    exec: {
      maxBuffer: 1024 * 1024,
    },
    reportName: 'w3c-validator.html',
  }, settings.w3cValidator);

  del.sync(`${settings.paths.dist}/${nw3cOpts.reportName}`);

  nodeW3CValidator(`${settings.paths.dist}/**/*.html`, nw3cOpts, (err, output) => {
    if (err === null) {
      return;
    }
    nodeW3CValidator.writeFile(`${settings.paths.dist}/${nw3cOpts.reportName}`, output);
  });
};
<|endoftext|>


<commit_before>'use strict';
const CommandUtil = require('../src/command_util')
  .CommandUtil;
const sprintf = require('sprintf')
  .sprintf;
const l10nFile = __dirname + '/../l10n/commands/look.yml';
const l10n = new require('jall')(require('js-yaml').load(require('fs')
    .readFileSync(l10nFile).toString('utf8')), undefined, 'zz');
const wrap = require('wrap-ansi');
const util = require('util');
const Time = require('../src/time').Time;

l10n.throwOnMissingTranslation(false);

exports.command = (rooms, items, players, npcs, Commands) => {

  return (args, player, hasExplored) => {
    const room = rooms.getAt(player.getLocation());
    const locale = player.getLocale();

    let thingIsPlayer = false;

    if (args) {
      args = args.toLowerCase();

      // Look at items in the room first
      let thing = CommandUtil.findItemInRoom(items, args, room, player,
        true);

      if (!thing) {
        // Then the inventory
        thing = CommandUtil.findItemInInventory(args, player, true);
      }

      if (!thing) {
        // Then for an NPC
        thing = CommandUtil.findNpcInRoom(npcs, args, room, player, true);
      }

      // Then the player themselves
      if (!thing && isLookingAtSelf()) {
        thing = player;
        thingIsPlayer = true;
      }

      function isLookingAtSelf() {
        const me = ['me', 'self', player.getName().toLowerCase()];
        return me.indexOf(args) !== -1;
      }

      // Then other players
      if (!thing) {
        players.eachIf(
          CommandUtil.inSameRoom.bind(null, player),
          lookAtOther);
      }

      function lookAtOther(p) {
        if (args === p.getName().toLowerCase()) {
          thing = p;
          player.sayL10n(l10n, 'IN_ROOM', thing.getName());
          thingIsPlayer = true;
          p.sayL10n(l10n, 'BEING_LOOKED_AT', player.getName());
        }
      }

      // Then look at exits
      //TODO: Improve based on player stats/skills?
      if (!thing) {
        const exits = room.getExits();
        const canSee = exits.reduce((canSee, exit) => {
          if (!canSee) { return canSee; }
          if (args === exit.direction) {
            if (exit.door && !exit.door.open) {
              player.say("There's a door in the way.");
              return false;
            }
            thing = rooms.getAt(exit.location);
            player.say(thing.getTitle(locale));
          }
        }, true);
        if (!canSee) { return; }
      }

      if (!thing) {
        player.sayL10n(l10n, 'ITEM_NOT_FOUND');
        return;
      }

      player.say(wrap(thing.getDescription(locale), 80));
      if (thingIsPlayer) { showPlayerEquipment(thing, player); }

      return;
    }

    if (!room) {
      player.sayL10n(l10n, 'LIMBO');
      util.log(player.getName() + ' is in limbo.');
      return;
    }

    // Render the room and its exits
    player.say(room.getArea() + ': ' + room.getTitle(locale));

    const descPreference = player.getPreference('roomdescs');

    if (Time.isDay()) {

      const showShortByDefault = hasExplored === true && descPreference !== 'verbose';

      if (showShortByDefault || descPreference === 'short') {
        player.say(wrap(room.getShortDesc(locale), 80));
      } else {
        player.say(wrap(room.getDescription(locale), 80));
      }

    } else {
      player.say(wrap(room.getDarkDesc(locale), 80));
    }

    player.say('');

    // display players in the same room
    players.eachIf(CommandUtil.inSameRoom.bind(null, player),
      p => player.sayL10n(l10n, 'IN_ROOM', p.getName()));

    // show all the items in the rom
    room.getItems()
      .forEach(id => {
        player.say('<magenta>'
        + items.get(id).getShortDesc(locale)
        + '</magenta>');
      });

    // show all npcs in the room
    room.getNpcs()
      .forEach(id => {
        var npc = npcs.get(id);

        if (npc) {
          var npcLevel = npc.getAttribute('level');
          var playerLevel = player.getAttribute('level');
          var color = 'cyan';

          if ((npcLevel - playerLevel) > 3)
            color = 'red';
          else if ((npcLevel - playerLevel) >= 1)
            color = 'yellow';
          else if (npcLevel === playerLevel)
            color = 'green';

          player.say('<' + color + '>'
            + npc.getShortDesc(player.getLocale())
            + '</' + color + '>');
        }
      });

    player.write('[');
    player.write('<yellow><bold>Obvious exits: </yellow></bold>');
    room.getExits()
      .forEach(exit => player.write(exit.direction + ' '));
    player.say(']');

    function showPlayerEquipment(playerTarget, playerLooking) {
      let naked = true;
      const equipped = playerTarget.getEquipped();
      for (const i in equipped) {
        const item = items.get(equipped[i]);
        naked = false;
        playerLooking.say(
          sprintf(
            "%-15s %s", "<" + i + ">",
            item.getShortDesc(playerLooking.getLocale())
          ));
      }
      if (naked) { playerLooking.sayL10n(l10n, "NAKED"); }
    }

  }
};
<commit_msg>Fix issue with looking into other rooms. Exit name must match.<commit_after>'use strict';
const CommandUtil = require('../src/command_util')
  .CommandUtil;
const sprintf = require('sprintf')
  .sprintf;
const l10nFile = __dirname + '/../l10n/commands/look.yml';
const l10n = new require('jall')(require('js-yaml').load(require('fs')
    .readFileSync(l10nFile).toString('utf8')), undefined, 'zz');
const wrap = require('wrap-ansi');
const util = require('util');
const Time = require('../src/time').Time;

l10n.throwOnMissingTranslation(false);

exports.command = (rooms, items, players, npcs, Commands) => {

  return (args, player, hasExplored) => {
    const room = rooms.getAt(player.getLocation());
    const locale = player.getLocale();

    let thingIsPlayer = false;

    if (args) {
      args = args.toLowerCase();

      // Look at items in the room first
      let thing = CommandUtil.findItemInRoom(items, args, room, player,
        true);

      if (!thing) {
        // Then the inventory
        thing = CommandUtil.findItemInInventory(args, player, true);
      }

      if (!thing) {
        // Then for an NPC
        thing = CommandUtil.findNpcInRoom(npcs, args, room, player, true);
      }

      // Then the player themselves
      if (!thing && isLookingAtSelf()) {
        thing = player;
        thingIsPlayer = true;
      }

      function isLookingAtSelf() {
        const me = ['me', 'self', player.getName().toLowerCase()];
        return me.indexOf(args) !== -1;
      }

      // Then other players
      if (!thing) {
        players.eachIf(
          CommandUtil.inSameRoom.bind(null, player),
          lookAtOther);
      }

      function lookAtOther(p) {
        if (args === p.getName().toLowerCase()) {
          thing = p;
          player.sayL10n(l10n, 'IN_ROOM', thing.getName());
          thingIsPlayer = true;
          p.sayL10n(l10n, 'BEING_LOOKED_AT', player.getName());
        }
      }

      // Then look at exits
      //TODO: Improve based on player stats/skills?
      if (!thing) {
        const exits = room.getExits();
        const canSee = exits.reduce((canSee, exit) => {
          if (!canSee) { return canSee; }
          if (args === exit.direction) {
            if (exit.door && !exit.door.open) {
              player.say("There's a door in the way.");
              return false;
            }
            thing = rooms.getAt(exit.location);
            player.say(thing.getTitle(locale));
          }
        }, true);
      }

      if (!thing) {
        player.sayL10n(l10n, 'ITEM_NOT_FOUND');
        return;
      }

      player.say(wrap(thing.getDescription(locale), 80));
      if (thingIsPlayer) { showPlayerEquipment(thing, player); }

      return;
    }

    if (!room) {
      player.sayL10n(l10n, 'LIMBO');
      util.log(player.getName() + ' is in limbo.');
      return;
    }

    // Render the room and its exits
    player.say(room.getArea() + ': ' + room.getTitle(locale));

    const descPreference = player.getPreference('roomdescs');

    if (Time.isDay()) {

      const showShortByDefault = hasExplored === true && descPreference !== 'verbose';

      if (showShortByDefault || descPreference === 'short') {
        player.say(wrap(room.getShortDesc(locale), 80));
      } else {
        player.say(wrap(room.getDescription(locale), 80));
      }

    } else {
      player.say(wrap(room.getDarkDesc(locale), 80));
    }

    player.say('');

    // display players in the same room
    players.eachIf(CommandUtil.inSameRoom.bind(null, player),
      p => player.sayL10n(l10n, 'IN_ROOM', p.getName()));

    // show all the items in the rom
    room.getItems()
      .forEach(id => {
        player.say('<magenta>'
        + items.get(id).getShortDesc(locale)
        + '</magenta>');
      });

    // show all npcs in the room
    room.getNpcs()
      .forEach(id => {
        var npc = npcs.get(id);

        if (npc) {
          var npcLevel = npc.getAttribute('level');
          var playerLevel = player.getAttribute('level');
          var color = 'cyan';

          if ((npcLevel - playerLevel) > 3)
            color = 'red';
          else if ((npcLevel - playerLevel) >= 1)
            color = 'yellow';
          else if (npcLevel === playerLevel)
            color = 'green';

          player.say('<' + color + '>'
            + npc.getShortDesc(player.getLocale())
            + '</' + color + '>');
        }
      });

    player.write('[');
    player.write('<yellow><bold>Obvious exits: </yellow></bold>');
    room.getExits()
      .forEach(exit => player.write(exit.direction + ' '));
    player.say(']');

    function showPlayerEquipment(playerTarget, playerLooking) {
      let naked = true;
      const equipped = playerTarget.getEquipped();
      for (const i in equipped) {
        const item = items.get(equipped[i]);
        naked = false;
        playerLooking.say(
          sprintf(
            "%-15s %s", "<" + i + ">",
            item.getShortDesc(playerLooking.getLocale())
          ));
      }
      if (naked) { playerLooking.sayL10n(l10n, "NAKED"); }
    }

  }
};
<|endoftext|>