<commit_before>/*global logger*/
/*
    WidgetName
    ========================

    @file      : WidgetName.js
    @version   : {{version}}
    @author    : {{author}}
    @date      : {{date}}
    @copyright : {{copyright}}
    @license   : {{license}}

    Documentation
    ========================
    Describe your widget here.
*/

// Required module list. Remove unnecessary modules, you can always get them back from the boilerplate.
define([
    "dojo/_base/declare",
    "mxui/widget/_WidgetBase",
    "dijit/_TemplatedMixin",

    "mxui/dom",
    "dojo/dom",
    "dojo/dom-prop",
    "dojo/dom-geometry",
    "dojo/dom-class",
    "dojo/dom-style",
    "dojo/dom-construct",
    "dojo/_base/array",
    "dojo/_base/lang",
    "dojo/text",
    "dojo/html",
    "dojo/_base/event",

    "WidgetName/lib/jquery-1.11.2",
    "dojo/text!WidgetName/widget/template/WidgetName.html"
], function(declare, _WidgetBase, _TemplatedMixin, dom, dojoDom, dojoProp, dojoGeometry, dojoClass, dojoStyle, dojoConstruct, dojoArray, dojoLang, dojoText, dojoHtml, dojoEvent, _jQuery, widgetTemplate) {
    "use strict";

    var $ = _jQuery.noConflict(true);

    // Declare widget's prototype.
    return declare("WidgetName.widget.WidgetName", [ _WidgetBase, _TemplatedMixin ], {
        // _TemplatedMixin will create our dom node using this HTML template.
        templateString: widgetTemplate,

        // DOM elements
        inputNodes: null,
        colorSelectNode: null,
        colorInputNode: null,
        infoTextNode: null,

        // Parameters configured in the Modeler.
        mfToExecute: "",
        messageString: "",
        backgroundColor: "",

        // Internal variables. Non-primitives created in the prototype are shared between all widget instances.
        _handles: null,
        _contextObj: null,
        _alertDiv: null,

        // dojo.declare.constructor is called to construct the widget instance. Implement to initialize non-primitive properties.
        constructor: function() {
            // Uncomment the following line to enable debug messages
            //logger.level(logger.DEBUG);
            logger.debug(this.id + ".constructor");
            this._handles = [];
        },

        // dijit._WidgetBase.postCreate is called after constructing the widget. Implement to do extra setup work.
        postCreate: function() {
            logger.debug(this.id + ".postCreate");
            this._updateRendering();
            this._setupEvents();
        },

        // mxui.widget._WidgetBase.update is called when context is changed or initialized. Implement to re-render and / or fetch data.
        update: function(obj, callback) {
            logger.debug(this.id + ".update");

            this._contextObj = obj;
            this._resetSubscriptions();
            this._updateRendering();

            callback();
        },

        // mxui.widget._WidgetBase.enable is called when the widget should enable editing. Implement to enable editing if widget is input widget.
        enable: function() {
          logger.debug(this.id + ".enable");
        },

        // mxui.widget._WidgetBase.enable is called when the widget should disable editing. Implement to disable editing if widget is input widget.
        disable: function() {
          logger.debug(this.id + ".disable");
        },

        // mxui.widget._WidgetBase.resize is called when the page's layout is recalculated. Implement to do sizing calculations. Prefer using CSS instead.
        resize: function(box) {
          logger.debug(this.id + ".resize");
        },

        // mxui.widget._WidgetBase.uninitialize is called when the widget is destroyed. Implement to do special tear-down work.
        uninitialize: function() {
          logger.debug(this.id + ".uninitialize");
            // Clean up listeners, helper objects, etc. There is no need to remove listeners added with this.connect / this.subscribe / this.own.
        },

        // We want to stop events on a mobile device
        _stopBubblingEventOnMobile: function(e) {
            logger.debug(this.id + "._stopBubblingEventOnMobile");
            if (typeof document.ontouchstart !== "undefined") {
                dojoEvent.stop(e);
            }
        },

        // Attach events to HTML dom elements
        _setupEvents: function() {
            logger.debug(this.id + "._setupEvents");
            this.connect(this.colorSelectNode, "change", function(e) {
                // Function from mendix object to set an attribute.
                this._contextObj.set(this.backgroundColor, this.colorSelectNode.value);
            });

            this.connect(this.infoTextNode, "click", function(e) {
                // Only on mobile stop event bubbling!
                this._stopBubblingEventOnMobile(e);

                // If a microflow has been set execute the microflow on a click.
                if (this.mfToExecute !== "") {
                    mx.data.action({
                        params: {
                            applyto: "selection",
                            actionname: this.mfToExecute,
                            guids: [ this._contextObj.getGuid() ]
                        },
                        store: {
                            caller: this.mxform
                        },
                        callback: function(obj) {
                            //TODO what to do when all is ok!
                        },
                        error: dojoLang.hitch(this, function(error) {
                            logger.error(this.id + ": An error occurred while executing microflow: " + error.description);
                        })
                    }, this);
                }
            });
        },

        // Rerender the interface.
        _updateRendering: function() {
            logger.debug(this.id + "._updateRendering");
            this.colorSelectNode.disabled = this.readOnly;
            this.colorInputNode.disabled = this.readOnly;

            if (this._contextObj !== null) {
                dojoStyle.set(this.domNode, "display", "block");

                var colorValue = this._contextObj.get(this.backgroundColor);

                this.colorInputNode.value = colorValue;
                this.colorSelectNode.value = colorValue;

                dojoHtml.set(this.infoTextNode, this.messageString);
                dojoStyle.set(this.infoTextNode, "background-color", colorValue);
            } else {
                dojoStyle.set(this.domNode, "display", "none");
            }

            // Important to clear all validations!
            this._clearValidations();
        },

        // Handle validations.
        _handleValidation: function(validations) {
            logger.debug(this.id + "._handleValidation");
            this._clearValidations();

            var validation = validations[0],
                message = validation.getReasonByAttribute(this.backgroundColor);

            if (this.readOnly) {
                validation.removeAttribute(this.backgroundColor);
            } else if (message) {
                this._addValidation(message);
                validation.removeAttribute(this.backgroundColor);
            }
        },

        // Clear validations.
        _clearValidations: function() {
            logger.debug(this.id + "._clearValidations");
            dojoConstruct.destroy(this._alertDiv);
            this._alertDiv = null;
        },

        // Show an error message.
        _showError: function(message) {
            logger.debug(this.id + "._showError");
            if (this._alertDiv !== null) {
                dojoHtml.set(this._alertDiv, message);
                return true;
            }
            this._alertDiv = dojoConstruct.create("div", {
                "class": "alert alert-danger",
                "innerHTML": message
            });
            dojoConstruct.place(this.domNode, this._alertDiv);
        },

        // Add a validation.
        _addValidation: function(message) {
            logger.debug(this.id + "._addValidation");
            this._showError(message);
        },

        // Reset subscriptions.
        _resetSubscriptions: function() {
            logger.debug(this.id + "._resetSubscriptions");
            // Release handles on previous object, if any.
            if (this._handles) {
                dojoArray.forEach(this._handles, function (handle) {
                    mx.data.unsubscribe(handle);
                });
                this._handles = [];
            }

            // When a mendix object exists create subscribtions.
            if (this._contextObj) {
                var objectHandle = this.subscribe({
                    guid: this._contextObj.getGuid(),
                    callback: dojoLang.hitch(this, function(guid) {
                        this._updateRendering();
                    })
                });

                var attrHandle = this.subscribe({
                    guid: this._contextObj.getGuid(),
                    attr: this.backgroundColor,
                    callback: dojoLang.hitch(this, function(guid, attr, attrValue) {
                        this._updateRendering();
                    })
                });

                var validationHandle = this.subscribe({
                    guid: this._contextObj.getGuid(),
                    val: true,
                    callback: dojoLang.hitch(this, this._handleValidation)
                });

                this._handles = [ objectHandle, attrHandle, validationHandle ];
            }
        }
    });
});

require(["WidgetName/widget/WidgetName"], function() {
    "use strict";
});
<commit_msg>required does not need an empty function<commit_after>/*global logger*/
/*
    WidgetName
    ========================

    @file      : WidgetName.js
    @version   : {{version}}
    @author    : {{author}}
    @date      : {{date}}
    @copyright : {{copyright}}
    @license   : {{license}}

    Documentation
    ========================
    Describe your widget here.
*/

// Required module list. Remove unnecessary modules, you can always get them back from the boilerplate.
define([
    "dojo/_base/declare",
    "mxui/widget/_WidgetBase",
    "dijit/_TemplatedMixin",

    "mxui/dom",
    "dojo/dom",
    "dojo/dom-prop",
    "dojo/dom-geometry",
    "dojo/dom-class",
    "dojo/dom-style",
    "dojo/dom-construct",
    "dojo/_base/array",
    "dojo/_base/lang",
    "dojo/text",
    "dojo/html",
    "dojo/_base/event",

    "WidgetName/lib/jquery-1.11.2",
    "dojo/text!WidgetName/widget/template/WidgetName.html"
], function(declare, _WidgetBase, _TemplatedMixin, dom, dojoDom, dojoProp, dojoGeometry, dojoClass, dojoStyle, dojoConstruct, dojoArray, dojoLang, dojoText, dojoHtml, dojoEvent, _jQuery, widgetTemplate) {
    "use strict";

    var $ = _jQuery.noConflict(true);

    // Declare widget's prototype.
    return declare("WidgetName.widget.WidgetName", [ _WidgetBase, _TemplatedMixin ], {
        // _TemplatedMixin will create our dom node using this HTML template.
        templateString: widgetTemplate,

        // DOM elements
        inputNodes: null,
        colorSelectNode: null,
        colorInputNode: null,
        infoTextNode: null,

        // Parameters configured in the Modeler.
        mfToExecute: "",
        messageString: "",
        backgroundColor: "",

        // Internal variables. Non-primitives created in the prototype are shared between all widget instances.
        _handles: null,
        _contextObj: null,
        _alertDiv: null,

        // dojo.declare.constructor is called to construct the widget instance. Implement to initialize non-primitive properties.
        constructor: function() {
            // Uncomment the following line to enable debug messages
            //logger.level(logger.DEBUG);
            logger.debug(this.id + ".constructor");
            this._handles = [];
        },

        // dijit._WidgetBase.postCreate is called after constructing the widget. Implement to do extra setup work.
        postCreate: function() {
            logger.debug(this.id + ".postCreate");
            this._updateRendering();
            this._setupEvents();
        },

        // mxui.widget._WidgetBase.update is called when context is changed or initialized. Implement to re-render and / or fetch data.
        update: function(obj, callback) {
            logger.debug(this.id + ".update");

            this._contextObj = obj;
            this._resetSubscriptions();
            this._updateRendering();

            callback();
        },

        // mxui.widget._WidgetBase.enable is called when the widget should enable editing. Implement to enable editing if widget is input widget.
        enable: function() {
          logger.debug(this.id + ".enable");
        },

        // mxui.widget._WidgetBase.enable is called when the widget should disable editing. Implement to disable editing if widget is input widget.
        disable: function() {
          logger.debug(this.id + ".disable");
        },

        // mxui.widget._WidgetBase.resize is called when the page's layout is recalculated. Implement to do sizing calculations. Prefer using CSS instead.
        resize: function(box) {
          logger.debug(this.id + ".resize");
        },

        // mxui.widget._WidgetBase.uninitialize is called when the widget is destroyed. Implement to do special tear-down work.
        uninitialize: function() {
          logger.debug(this.id + ".uninitialize");
            // Clean up listeners, helper objects, etc. There is no need to remove listeners added with this.connect / this.subscribe / this.own.
        },

        // We want to stop events on a mobile device
        _stopBubblingEventOnMobile: function(e) {
            logger.debug(this.id + "._stopBubblingEventOnMobile");
            if (typeof document.ontouchstart !== "undefined") {
                dojoEvent.stop(e);
            }
        },

        // Attach events to HTML dom elements
        _setupEvents: function() {
            logger.debug(this.id + "._setupEvents");
            this.connect(this.colorSelectNode, "change", function(e) {
                // Function from mendix object to set an attribute.
                this._contextObj.set(this.backgroundColor, this.colorSelectNode.value);
            });

            this.connect(this.infoTextNode, "click", function(e) {
                // Only on mobile stop event bubbling!
                this._stopBubblingEventOnMobile(e);

                // If a microflow has been set execute the microflow on a click.
                if (this.mfToExecute !== "") {
                    mx.data.action({
                        params: {
                            applyto: "selection",
                            actionname: this.mfToExecute,
                            guids: [ this._contextObj.getGuid() ]
                        },
                        store: {
                            caller: this.mxform
                        },
                        callback: function(obj) {
                            //TODO what to do when all is ok!
                        },
                        error: dojoLang.hitch(this, function(error) {
                            logger.error(this.id + ": An error occurred while executing microflow: " + error.description);
                        })
                    }, this);
                }
            });
        },

        // Rerender the interface.
        _updateRendering: function() {
            logger.debug(this.id + "._updateRendering");
            this.colorSelectNode.disabled = this.readOnly;
            this.colorInputNode.disabled = this.readOnly;

            if (this._contextObj !== null) {
                dojoStyle.set(this.domNode, "display", "block");

                var colorValue = this._contextObj.get(this.backgroundColor);

                this.colorInputNode.value = colorValue;
                this.colorSelectNode.value = colorValue;

                dojoHtml.set(this.infoTextNode, this.messageString);
                dojoStyle.set(this.infoTextNode, "background-color", colorValue);
            } else {
                dojoStyle.set(this.domNode, "display", "none");
            }

            // Important to clear all validations!
            this._clearValidations();
        },

        // Handle validations.
        _handleValidation: function(validations) {
            logger.debug(this.id + "._handleValidation");
            this._clearValidations();

            var validation = validations[0],
                message = validation.getReasonByAttribute(this.backgroundColor);

            if (this.readOnly) {
                validation.removeAttribute(this.backgroundColor);
            } else if (message) {
                this._addValidation(message);
                validation.removeAttribute(this.backgroundColor);
            }
        },

        // Clear validations.
        _clearValidations: function() {
            logger.debug(this.id + "._clearValidations");
            dojoConstruct.destroy(this._alertDiv);
            this._alertDiv = null;
        },

        // Show an error message.
        _showError: function(message) {
            logger.debug(this.id + "._showError");
            if (this._alertDiv !== null) {
                dojoHtml.set(this._alertDiv, message);
                return true;
            }
            this._alertDiv = dojoConstruct.create("div", {
                "class": "alert alert-danger",
                "innerHTML": message
            });
            dojoConstruct.place(this.domNode, this._alertDiv);
        },

        // Add a validation.
        _addValidation: function(message) {
            logger.debug(this.id + "._addValidation");
            this._showError(message);
        },

        // Reset subscriptions.
        _resetSubscriptions: function() {
            logger.debug(this.id + "._resetSubscriptions");
            // Release handles on previous object, if any.
            if (this._handles) {
                dojoArray.forEach(this._handles, function (handle) {
                    mx.data.unsubscribe(handle);
                });
                this._handles = [];
            }

            // When a mendix object exists create subscribtions.
            if (this._contextObj) {
                var objectHandle = this.subscribe({
                    guid: this._contextObj.getGuid(),
                    callback: dojoLang.hitch(this, function(guid) {
                        this._updateRendering();
                    })
                });

                var attrHandle = this.subscribe({
                    guid: this._contextObj.getGuid(),
                    attr: this.backgroundColor,
                    callback: dojoLang.hitch(this, function(guid, attr, attrValue) {
                        this._updateRendering();
                    })
                });

                var validationHandle = this.subscribe({
                    guid: this._contextObj.getGuid(),
                    val: true,
                    callback: dojoLang.hitch(this, this._handleValidation)
                });

                this._handles = [ objectHandle, attrHandle, validationHandle ];
            }
        }
    });
});

require(["WidgetName/widget/WidgetName"]);
<|endoftext|>


<commit_before>var StartGame = function(game){};

StartGame.prototype = {

	create: function(){
		this.game.state.lives = 5;
		this.game.state.level = 5;
		this.game.state.maxLevel = levels.length-1;
		this.game.state.start("Main");
	}
}<commit_msg>start from level 1<commit_after>var StartGame = function(game){};

StartGame.prototype = {

	create: function(){
		this.game.state.lives = 5;
		this.game.state.level = 1;
		this.game.state.maxLevel = levels.length-1;
		this.game.state.start("Main");
	}
}<|endoftext|>


<commit_before>require('file?name=[name].[ext]!../node_modules/neo4j-driver/lib/browser/neo4j-web.min.js');
var Movie = require('./models/Movie');
var MovieCast = require('./models/MovieCast');
var Path = require('./models/Path');
var utils = require('./Utils');
var _ = require('lodash');

var neo4j = window.neo4j.v1;
//var driver = neo4j.driver("bolt://localhost", neo4j.auth.basic("neo4j", "Milwan1"));

var driver = neo4j.driver("bolt://wmw.uk.deloitte.com", neo4j.auth.basic("neo4j", "graph"));

function getHierarchy(rootClass) {
  var session = driver.session();
  var query = `MATCH p=(:${rootClass} {title: "${rootClass}"})<-[:is_part_of*]-(x)`
  // switch (rootClass) {
  //   case "Organisation" :
  //     query += ` WHERE x["level"]< 3 `
  //   //case "Process" :
  // }

  query +=" RETURN p"

//console.log(query);
  // 'MATCH p=(:Organisation {title: "Organisation"})<-[:is_part_of*]-(x) \
  // RETURN p',
  return session
    .run(query,{})
    .then(result => {
      session.close();

      if (result.records.length > 0) {
        let firstRecord = result.records[0].get('p');
        let rootTitle = firstRecord.start.properties.title;
        let rootCx = {name: rootTitle, children: []};
        var cxStack = [rootCx];

        let records = result.records;

        for (var recordIndex = 0, recordsLen = records.length; recordIndex < recordsLen; recordIndex++) {
          let pathInfo = records[recordIndex].get('p');
          let pathSegments = pathInfo.segments;  //if we get this far, there will be at least one element in segments array

          let pathLen = pathSegments.length;

          cxStack = cxStack.slice(0, pathLen);
          let currentCx = cxStack[pathLen - 1];
          let node = pathSegments[pathLen - 1];

          let newNode = {name: node.end.properties.title};

          if (typeof(currentCx.children) ==  "undefined") {
            currentCx.children = [];
          }
          currentCx.children.push(newNode);
          cxStack.push(newNode);

        }
        return(cxStack[0]);

    }
    else {
      return {name: "No hierarchy data found"};
    }
    })
    .catch(error => {
      session.close();
      throw error;
    });
}

//should this be in the api?
function setRelationships(lhs, rhs, rel_name, field, hierarchy) {
//   var query = `MATCH (l:${lhs})-[rel:${rel_name}]->(r:${rhs}) \
// WHERE exists(rel.${field}) \
// RETURN id(l) as l_id, id(r) as r_id, l.title as l_title, r.title as r_title, rel.${field} as field `

//for proof of concept at any rate, not insisting on the existence of the value field (ie ftes)
//and defaulting to a value of 1 where a value does not exist in the database.
//needless to say, this ought to change at some point.

var query = `MATCH (l:${lhs})-[rel:${rel_name}]-(r:${rhs}) \
RETURN id(l) as l_id, id(r) as r_id, l.title as l_title, r.title as r_title, case when rel.${field} is null then 1 else rel.${field} end as field `
//console.log(query)
  var session = driver.session();
  return session
  .run(query, {})
    .then(result => {
      session.close();

      if (result.records.length > 0) {
        let records = result.records;

        //var keys = records[0].keys;
        var indices = records[0]._fieldLookup;
        var sourceDictionary = {};

        records.forEach(function (rec, i) {
          //keys ["l_id", "r_id", "l_title", "r_title", "field"]
          // l_id = rec._fields[rec._fieldLookup["l_id"]];
          // r_id = rec._fields[rec._fieldLookup["r_id"]];

          let l_id = rec._fields[indices["l_id"]];
          let r_id = rec._fields[indices["r_id"]];

          let l_title = rec._fields[indices["l_title"]];

          let r_title = rec._fields[indices["r_title"]];
          let field = rec._fields[indices["field"]];

          let rel_info = {target: r_title, target_id: r_id, value: field};

          if (typeof(sourceDictionary[l_title]) != "undefined") {
            sourceDictionary[l_title].push(rel_info);
          }
          else {
            sourceDictionary[l_title] = [rel_info];

          }
        });
// console.log("sourceDictionary")
// console.log(sourceDictionary)

        utils.traverseTree (hierarchy, assignRelationships, null, {rel_dict: sourceDictionary});
// console.log("hierarchy");
// console.log(hierarchy);

        return hierarchy;
    }
    else {
      console.log("no relationships")
      return hierarchy;
    }
    })
    .catch(error => {
      session.close();
      throw error;
    });
}

function assignRelationships(node, props) {
  //this function traverses a tree with name and children properties
  //if the name property is in the list of node names that are known
  //to have relationships, then//the relationships array is added, and the children array, if there is one is deleted

  var dict = props.rel_dict;
  if (typeof(dict[node.name]) != "undefined") {

    //stitch these relationships into this Object
    node["relationships"] = dict[node.name]; //this should be an array of target_node_id and values
    //nodes with relationships are supposed to be children so delete the children collection of this node.
    if (typeof(node.children) != "undefined") {

      //delete node.children;
    }
  }
}

function jobLot(){
  this.jobDict = {};
}

jobLot.prototype.addJob = function(jobFunc, params, callback){
  let id = Object.keys(this.jobDict).length;

  var jobStruct = {job: jobFunc, callback: callback, params: params};
  this.jobDict[id] = jobStruct;
}

jobLot.prototype.doJobs = function(callback) {
  this.jobComplete = callback;
  var that = this;
  Object.keys(this.jobDict).forEach(function(key) {
    let cb = jobLot.createCallback(key, that);
    let job = that.jobDict[key];
    job.job(job.params, cb);
  });
}

jobLot.prototype.jobDone = function(id, result){
  let jobInfo = this.jobDict[id];
  delete this.jobDict[id];
  jobInfo.callback(result);   //need more complex structure if the callback itself needs async processing before the overall job lot can be considered complete.
  if (Object.keys(this.jobDict).length == 0) {
    //all jobs done.
    this.jobComplete();
  }
}

jobLot.createCallback = function(id, jobController) {
  return function (result) {
    jobController.jobDone(id, result);
  }
}

jobLot.createJobLot = function() {
  return new jobLot();
}

exports.getHierarchy = getHierarchy;
exports.setRelationships = setRelationships;
exports.createJobLot = jobLot.createJobLot;
<commit_msg>switch db<commit_after>require('file?name=[name].[ext]!../node_modules/neo4j-driver/lib/browser/neo4j-web.min.js');
var Movie = require('./models/Movie');
var MovieCast = require('./models/MovieCast');
var Path = require('./models/Path');
var utils = require('./Utils');
var _ = require('lodash');

var neo4j = window.neo4j.v1;
var driver = neo4j.driver("bolt://localhost", neo4j.auth.basic("neo4j", "Milwan1"));

function getHierarchy(rootClass) {
  var session = driver.session();
  var query = `MATCH p=(:${rootClass} {title: "${rootClass}"})<-[:is_part_of*]-(x)`
  // switch (rootClass) {
  //   case "Organisation" :
  //     query += ` WHERE x["level"]< 3 `
  //   //case "Process" :
  // }

  query +=" RETURN p"

//console.log(query);
  // 'MATCH p=(:Organisation {title: "Organisation"})<-[:is_part_of*]-(x) \
  // RETURN p',
  return session
    .run(query,{})
    .then(result => {
      session.close();

      if (result.records.length > 0) {
        let firstRecord = result.records[0].get('p');
        let rootTitle = firstRecord.start.properties.title;
        let rootCx = {name: rootTitle, children: []};
        var cxStack = [rootCx];

        let records = result.records;

        for (var recordIndex = 0, recordsLen = records.length; recordIndex < recordsLen; recordIndex++) {
          let pathInfo = records[recordIndex].get('p');
          let pathSegments = pathInfo.segments;  //if we get this far, there will be at least one element in segments array

          let pathLen = pathSegments.length;

          cxStack = cxStack.slice(0, pathLen);
          let currentCx = cxStack[pathLen - 1];
          let node = pathSegments[pathLen - 1];

          let newNode = {name: node.end.properties.title};

          if (typeof(currentCx.children) ==  "undefined") {
            currentCx.children = [];
          }
          currentCx.children.push(newNode);
          cxStack.push(newNode);

        }
        return(cxStack[0]);

    }
    else {
      return {name: "No hierarchy data found"};
    }
    })
    .catch(error => {
      session.close();
      throw error;
    });
}

//should this be in the api?
function setRelationships(lhs, rhs, rel_name, field, hierarchy) {
//   var query = `MATCH (l:${lhs})-[rel:${rel_name}]->(r:${rhs}) \
// WHERE exists(rel.${field}) \
// RETURN id(l) as l_id, id(r) as r_id, l.title as l_title, r.title as r_title, rel.${field} as field `

//for proof of concept at any rate, not insisting on the existence of the value field (ie ftes)
//and defaulting to a value of 1 where a value does not exist in the database.
//needless to say, this ought to change at some point.

var query = `MATCH (l:${lhs})-[rel:${rel_name}]-(r:${rhs}) \
RETURN id(l) as l_id, id(r) as r_id, l.title as l_title, r.title as r_title, case when rel.${field} is null then 1 else rel.${field} end as field `
//console.log(query)
  var session = driver.session();
  return session
  .run(query, {})
    .then(result => {
      session.close();

      if (result.records.length > 0) {
        let records = result.records;

        //var keys = records[0].keys;
        var indices = records[0]._fieldLookup;
        var sourceDictionary = {};

        records.forEach(function (rec, i) {
          //keys ["l_id", "r_id", "l_title", "r_title", "field"]
          // l_id = rec._fields[rec._fieldLookup["l_id"]];
          // r_id = rec._fields[rec._fieldLookup["r_id"]];

          let l_id = rec._fields[indices["l_id"]];
          let r_id = rec._fields[indices["r_id"]];

          let l_title = rec._fields[indices["l_title"]];

          let r_title = rec._fields[indices["r_title"]];
          let field = rec._fields[indices["field"]];

          let rel_info = {target: r_title, target_id: r_id, value: field};

          if (typeof(sourceDictionary[l_title]) != "undefined") {
            sourceDictionary[l_title].push(rel_info);
          }
          else {
            sourceDictionary[l_title] = [rel_info];

          }
        });
// console.log("sourceDictionary")
// console.log(sourceDictionary)

        utils.traverseTree (hierarchy, assignRelationships, null, {rel_dict: sourceDictionary});
// console.log("hierarchy");
// console.log(hierarchy);

        return hierarchy;
    }
    else {
      console.log("no relationships")
      return hierarchy;
    }
    })
    .catch(error => {
      session.close();
      throw error;
    });
}

function assignRelationships(node, props) {
  //this function traverses a tree with name and children properties
  //if the name property is in the list of node names that are known
  //to have relationships, then//the relationships array is added, and the children array, if there is one is deleted

  var dict = props.rel_dict;
  if (typeof(dict[node.name]) != "undefined") {

    //stitch these relationships into this Object
    node["relationships"] = dict[node.name]; //this should be an array of target_node_id and values
    //nodes with relationships are supposed to be children so delete the children collection of this node.
    if (typeof(node.children) != "undefined") {

      //delete node.children;
    }
  }
}

function jobLot(){
  this.jobDict = {};
}

jobLot.prototype.addJob = function(jobFunc, params, callback){
  let id = Object.keys(this.jobDict).length;

  var jobStruct = {job: jobFunc, callback: callback, params: params};
  this.jobDict[id] = jobStruct;
}

jobLot.prototype.doJobs = function(callback) {
  this.jobComplete = callback;
  var that = this;
  Object.keys(this.jobDict).forEach(function(key) {
    let cb = jobLot.createCallback(key, that);
    let job = that.jobDict[key];
    job.job(job.params, cb);
  });
}

jobLot.prototype.jobDone = function(id, result){
  let jobInfo = this.jobDict[id];
  delete this.jobDict[id];
  jobInfo.callback(result);   //need more complex structure if the callback itself needs async processing before the overall job lot can be considered complete.
  if (Object.keys(this.jobDict).length == 0) {
    //all jobs done.
    this.jobComplete();
  }
}

jobLot.createCallback = function(id, jobController) {
  return function (result) {
    jobController.jobDone(id, result);
  }
}

jobLot.createJobLot = function() {
  return new jobLot();
}

exports.getHierarchy = getHierarchy;
exports.setRelationships = setRelationships;
exports.createJobLot = jobLot.createJobLot;
<|endoftext|>


<commit_before>/**
 * @module BlobObject
 * @private
 * @mixin
 * @description Exports BlobObject class.
 */

import Super from './Super';
import Promise from './Promise';
import constructors from './constants/constructors';
import { isArray, isFunction, toStringTag } from './helpers';

/**
 * @member {{buffer: String, binary: String, dataURL: String, text: String}} methods
 * @private
 * @description List of read blob methods.
 */
const methods = {
  buffer: 'ArrayBuffer',
  binary: 'BinaryString',
  dataURL: 'DataURL',
  text: 'Text'
};

/**
 * @typedef {('buffer'|'binary'|'dataURL'|'text')} ReadBlobMethod
 * @public
 * @description Enum type of read blob methods.
 */

/**
 * @typedef {(ArrayBuffer|ArrayBufferView|Blob|String)} BlobParts
 * @public
 * @description Allowed blob parts.
 */

export class BlobObject extends Super {
  /**
   * @class BlobObject
   * @extends Super
   * @public
   * @param {Blob} blob - Blob to wrap.
   * @returns {BlobObject} Instance of BlobObject.
   * @description Wrap of a blob.
   *
   * @example
   * new BlobObject(new Blob(['{"foo":"bar"}'], { type: 'application/json' }));
   */
  constructor(blob) {
    super(blob);
  }

  /**
   * @method BlobObject#readAs
   * @public
   * @param {ReadBlobMethod} method - Method that is used for reading from blob.
   * @param {Function} [progress] - Progress listener.
   * @returns {AbortablePromise} Promise that could be aborted.
   * @description Method for reading from blobs.
   *
   * @example
   * new BlobObject(new Blob(['{"foo":"bar"}'], { type: 'application/json' }))
   *   .readAs('text')
   *   .then((value) => {
   *     console.log(value); // '{"foo":"bar"}'
   *   });
   */
  readAs(method, progress) {
    if (!methods[method]) {
      throw new Error('1st argument must be one of following values: buffer, binary, dataURL, text');
    }

    let reader = new FileReader();
    let toReject;

    if (isFunction(progress)) {
      reader.onprogress = progress;
    }

    const promise = new Promise((resolve, reject) => {
      toReject = reject;

      reader.onerror = () => {
        if (reader) {
          reject(new Error('Reading error'));
        }
      };

      reader.onload = () => {
        resolve(reader.result);
      };

      reader['readAs' + methods[method]](this.$);
    });

    promise.abort = function abort() {
      toReject(new Error('Reading was aborted'));

      reader.abort();

      reader = null;

      return this;
    };

    return promise;
  }

  /**
   * @method BlobObject#saveAs
   * @public
   * @param {String} [name] - Name that is used for saving file.
   * @returns {BlobObject} Returns this.
   * @description Method for saving blobs.
   *
   * @example
   * new BlobObject(new Blob(['{"foo":"bar"}'], { type: 'application/json' }))
   *   .saveAs('blob.json');
   */
  saveAs(name = 'download') {
    const anchor = document.createElement('a');

    anchor.href = URL.createObjectURL(this.$);
    anchor.setAttribute('download', name);
    anchor.click();

    return this;
  }
}

constructors[1].push({
  check: (blob) => /^(Blob|File)$/.test(toStringTag(blob)),
  cls: BlobObject
});

/**
 * @function blob
 * @public
 * @param {(BlobParts[]|BlobParts)} blobParts - Blob parts that are passed to
 * [Blob]{@link https://developer.mozilla.org/en-US/docs/Web/API/Blob/Blob} constructor.
 * @param {Object} [options] - Options that are passed to
 * [Blob]{@link https://developer.mozilla.org/en-US/docs/Web/API/Blob/Blob} constructor.
 * @returns {BlobObject} New instance of BlobObject.
 * @description Function for creating blobs not involving BlobObject and Blob constructors.
 */
export function blob(blobParts, options) {
  if (!isArray(blobParts)) {
    blobParts = [blobParts];
  }

  return new BlobObject(new Blob(blobParts, options));
}

export default BlobObject;
<commit_msg>Blob: add Symbol.toStringTag.<commit_after>/**
 * @module BlobObject
 * @private
 * @mixin
 * @description Exports BlobObject class.
 */

import Super from './Super';
import Promise from './Promise';
import constructors from './constants/constructors';
import { isArray, isFunction, toStringTag, supportSymbol } from './helpers';

/**
 * @member {{buffer: String, binary: String, dataURL: String, text: String}} methods
 * @private
 * @description List of read blob methods.
 */
const methods = {
  buffer: 'ArrayBuffer',
  binary: 'BinaryString',
  dataURL: 'DataURL',
  text: 'Text'
};

/**
 * @typedef {('buffer'|'binary'|'dataURL'|'text')} ReadBlobMethod
 * @public
 * @description Enum type of read blob methods.
 */

/**
 * @typedef {(ArrayBuffer|ArrayBufferView|Blob|String)} BlobParts
 * @public
 * @description Allowed blob parts.
 */

export class BlobObject extends Super {
  /**
   * @class BlobObject
   * @extends Super
   * @public
   * @param {Blob} blob - Blob to wrap.
   * @returns {BlobObject} Instance of BlobObject.
   * @description Wrap of a blob.
   *
   * @example
   * new BlobObject(new Blob(['{"foo":"bar"}'], { type: 'application/json' }));
   */
  constructor(blob) {
    super(blob);
  }

  /**
   * @method BlobObject#readAs
   * @public
   * @param {ReadBlobMethod} method - Method that is used for reading from blob.
   * @param {Function} [progress] - Progress listener.
   * @returns {AbortablePromise} Promise that could be aborted.
   * @description Method for reading from blobs.
   *
   * @example
   * new BlobObject(new Blob(['{"foo":"bar"}'], { type: 'application/json' }))
   *   .readAs('text')
   *   .then((value) => {
   *     console.log(value); // '{"foo":"bar"}'
   *   });
   */
  readAs(method, progress) {
    if (!methods[method]) {
      throw new Error('1st argument must be one of following values: buffer, binary, dataURL, text');
    }

    let reader = new FileReader();
    let toReject;

    if (isFunction(progress)) {
      reader.onprogress = progress;
    }

    const promise = new Promise((resolve, reject) => {
      toReject = reject;

      reader.onerror = () => {
        if (reader) {
          reject(new Error('Reading error'));
        }
      };

      reader.onload = () => {
        resolve(reader.result);
      };

      reader['readAs' + methods[method]](this.$);
    });

    promise.abort = function abort() {
      toReject(new Error('Reading was aborted'));

      reader.abort();

      reader = null;

      return this;
    };

    return promise;
  }

  /**
   * @method BlobObject#saveAs
   * @public
   * @param {String} [name] - Name that is used for saving file.
   * @returns {BlobObject} Returns this.
   * @description Method for saving blobs.
   *
   * @example
   * new BlobObject(new Blob(['{"foo":"bar"}'], { type: 'application/json' }))
   *   .saveAs('blob.json');
   */
  saveAs(name = 'download') {
    const anchor = document.createElement('a');

    anchor.href = URL.createObjectURL(this.$);
    anchor.setAttribute('download', name);
    anchor.click();

    return this;
  }
}

if (supportSymbol) {
  BlobObject.prototype[Symbol.toStringTag] = 'BlobObject';
}

constructors[1].push({
  check: (blob) => /^(Blob|File)$/.test(toStringTag(blob)),
  cls: BlobObject
});

/**
 * @function blob
 * @public
 * @param {(BlobParts[]|BlobParts)} blobParts - Blob parts that are passed to
 * [Blob]{@link https://developer.mozilla.org/en-US/docs/Web/API/Blob/Blob} constructor.
 * @param {Object} [options] - Options that are passed to
 * [Blob]{@link https://developer.mozilla.org/en-US/docs/Web/API/Blob/Blob} constructor.
 * @returns {BlobObject} New instance of BlobObject.
 * @description Function for creating blobs not involving BlobObject and Blob constructors.
 */
export function blob(blobParts, options) {
  if (!isArray(blobParts)) {
    blobParts = [blobParts];
  }

  return new BlobObject(new Blob(blobParts, options));
}

export default BlobObject;
<|endoftext|>


<commit_before>import {expect} from 'chai'
import {it} from 'ember-mocha'
import {describe} from 'mocha'
import {generateToken} from 'webdriverio-server/app/utils/generateToken'

describe('Generate Token', function () {
  describe('General Case', function () {
    it('should generate a 30 character length token', function () {
      const token = generateToken(30)
      expect(token.length).to.equal(30)
    })
  })

  describe('Edge Cases', function () {
    it('should generate an error if passed not a number', function () {
      expect(generateToken('test')).to.throw()
    })

    it('should generate an error if passed a number less than 0', function () {
      expect(generateToken(-1)).to.throw()
    })
  })
})
<commit_msg>Potential fix to generate token test<commit_after>import {expect} from 'chai'
import {it} from 'ember-mocha'
import {describe} from 'mocha'
import {generateToken} from 'webdriverio-server/utils/generateToken'

describe('Generate Token', function () {
  describe('General Case', function () {
    it('should generate a 30 character length token', function () {
      const token = generateToken(30)
      expect(token.length).to.equal(30)
    })
  })

  describe('Edge Cases', function () {
    it('should generate an error if passed not a number', function () {
      expect(generateToken('test')).to.throw()
    })

    it('should generate an error if passed a number less than 0', function () {
      expect(generateToken(-1)).to.throw()
    })
  })
})
<|endoftext|>


<commit_before>module.exports = (function () {
  'use strict';

  let mongo = require('../modules/database');

  /**
   * Add new event to domain collection
   *
   * @param domain
   * @param event
   */
  let add = function (domain, event) {
    event.status = '0';
    return mongo.insertOne(domain, event);
  };

  /**
   * Get domain events
   *
   * @param {string} domain - domain name
   * @param {object} query  - find params (tag, for example)
   * @param {bool} group  - if true, group same events
   * @param {object} sort - sort params, by default sorting by time
   * @param {number} skip - number of events to skip
   * @param {number} limit - number of events to return
   * @param {number} status - 0 - new, 1 - read
   */
  let get = function (domain, query, group, sort, limit, skip) {
    let pipeline = [
      {$match: query}
    ];

    if (group) {
      pipeline.push({$group: {
        _id: '$groupHash',
        type: {$first: '$type'},
        tag: {$first: '$tag'},
        errorLocation: {$first: '$errorLocation'},
        message: {$first: '$message'},
        time: {$last: '$time'},
        count: {$sum: 1},
        status: {$min: '$status'}
      }});
    }

    if (!sort) {
      sort = {
        time: -1
      };
    }

    pipeline.push({
      $sort: sort
    });

    if (skip) {
      pipeline.push({
        $skip: skip
      });
    }

    if (limit) {
      pipeline.push({
        $limit: limit
      });
    }

    return mongo.aggregation(domain, pipeline);
  };

  let markRead = function (collection, eventsIds) {
    return mongo.updateMany(
      collection,
      { _id: { $in: eventsIds } },
      { $set: { 'status': '1' } },
      { upsert: true }
    );
  };

  /**
   * Count events by tags (fatal, warnings, notice, javascript)
   *
   * @param domain
   */
  let countTags = function (domain) {
    return mongo.aggregation(domain, [
      {
        $group: {
          _id: '$tag',
          count: {$sum: 1}
        }
      } ]);
  };

  /**
   * Get events for all users domains
   *
   * @param user
   * @param query
   * @returns {Promise.<TResult>}
   */
  let getAll = function (user, query) {
    let result = [],
      queries = [];

    if (!user.domains) {
      return Promise.resolve([]);
    }

    user.domains.forEach(function (domain) {
      queries.push(
        get(domain, query)
          .then(function (events) {
            result = result.concat(events);
          })
      );
    });

    return Promise.all(queries)
      .then(function () {
        return result;
      });
  };

  return {
    add: add,
    get: get,
    countTags: countTags,
    getAll: getAll,
    markRead: markRead
  };
})();
<commit_msg>Remove comment string<commit_after>module.exports = (function () {
  'use strict';

  let mongo = require('../modules/database');

  /**
   * Add new event to domain collection
   *
   * @param domain
   * @param event
   */
  let add = function (domain, event) {
    event.status = '0';
    return mongo.insertOne(domain, event);
  };

  /**
   * Get domain events
   *
   * @param {string} domain - domain name
   * @param {object} query  - find params (tag, for example)
   * @param {bool} group  - if true, group same events
   * @param {object} sort - sort params, by default sorting by time
   * @param {number} skip - number of events to skip
   * @param {number} limit - number of events to return
   */
  let get = function (domain, query, group, sort, limit, skip) {
    let pipeline = [
      {$match: query}
    ];

    if (group) {
      pipeline.push({$group: {
        _id: '$groupHash',
        type: {$first: '$type'},
        tag: {$first: '$tag'},
        errorLocation: {$first: '$errorLocation'},
        message: {$first: '$message'},
        time: {$last: '$time'},
        count: {$sum: 1},
        status: {$min: '$status'}
      }});
    }

    if (!sort) {
      sort = {
        time: -1
      };
    }

    pipeline.push({
      $sort: sort
    });

    if (skip) {
      pipeline.push({
        $skip: skip
      });
    }

    if (limit) {
      pipeline.push({
        $limit: limit
      });
    }

    return mongo.aggregation(domain, pipeline);
  };

  let markRead = function (collection, eventsIds) {
    return mongo.updateMany(
      collection,
      { _id: { $in: eventsIds } },
      { $set: { 'status': '1' } },
      { upsert: true }
    );
  };

  /**
   * Count events by tags (fatal, warnings, notice, javascript)
   *
   * @param domain
   */
  let countTags = function (domain) {
    return mongo.aggregation(domain, [
      {
        $group: {
          _id: '$tag',
          count: {$sum: 1}
        }
      } ]);
  };

  /**
   * Get events for all users domains
   *
   * @param user
   * @param query
   * @returns {Promise.<TResult>}
   */
  let getAll = function (user, query) {
    let result = [],
      queries = [];

    if (!user.domains) {
      return Promise.resolve([]);
    }

    user.domains.forEach(function (domain) {
      queries.push(
        get(domain, query)
          .then(function (events) {
            result = result.concat(events);
          })
      );
    });

    return Promise.all(queries)
      .then(function () {
        return result;
      });
  };

  return {
    add: add,
    get: get,
    countTags: countTags,
    getAll: getAll,
    markRead: markRead
  };
})();
<|endoftext|>


<commit_before>angular.module('aluno.eventos')

.factory('Eventos', function($resource) {
    return {
        create: function() {
            return $resource("~/api/eventos", {}, {
                "update": {
                    method: "PUT"
                },
                'query': {
                    method: 'GET',
                    isArray: false,
                    cache: false
                }
            });
        }
    };
});<commit_msg>Atualizado o service para exemplo (sem uso no Hello World)<commit_after>angular.module('feature.helloWorld')

.factory('Sample', function($resource) {
    return {
        create: function() {
            return $resource("~/api/sample", {}, {
                "update": {
                    method: "PUT"
                },
                'query': {
                    method: 'GET',
                    isArray: false,
                    cache: false
                }
            });
        }
    };
});
<|endoftext|>


<commit_before>'use strict';

const fs = require('fs');
const path = require('path');
const ProcessManager = require('./../process-manager');
const execFileSync = require('child_process').execFileSync;

const MAX_PROCESSES = 1;
const RESULTS_MAX_LENGTH = 100;
const LOG_PATH = '../logs/modlog/';

class ModlogManager extends ProcessManager {
	onMessageUpstream(message) {
		// Protocol:
		// when crashing: 	  "[id]|0"
		// when not crashing: "[id]|1|[results]"
		let pipeIndex = message.indexOf('|');
		let id = +message.substr(0, pipeIndex);

		if (this.pendingTasks.has(id)) {
			this.pendingTasks.get(id)(message.slice(pipeIndex + 1));
			this.pendingTasks.delete(id);
			this.release();
		}
	}

	onMessageDownstream(message) {
		// protocol:
		// "[id]|[room]|[searchString]|[exactSearch]|[maxLines]"
		let pipeIndex = message.indexOf('|');
		let nextPipeIndex = message.indexOf('|', pipeIndex + 1);
		let id = message.substr(0, pipeIndex);
		let room = message.substr(pipeIndex + 1, nextPipeIndex - pipeIndex - 1);

		pipeIndex = nextPipeIndex;
		nextPipeIndex = message.indexOf('|', pipeIndex + 1);
		let searchString = message.substr(pipeIndex + 1, nextPipeIndex - pipeIndex - 1);

		pipeIndex = nextPipeIndex;
		nextPipeIndex = message.indexOf('|', pipeIndex + 1);
		let exactSearch = message.substr(pipeIndex + 1, nextPipeIndex - pipeIndex - 1);
		let maxLines = message.substr(nextPipeIndex + 1);

		process.send(id + '|' + this.receive(room, searchString, exactSearch, maxLines));
	}

	receive(room, searchString, exactSearch, maxLines) {
		let result;
		exactSearch = exactSearch === '1';
		maxLines = Number(maxLines);
		if (isNaN(maxLines) || maxLines > RESULTS_MAX_LENGTH || maxLines < 1) maxLines = RESULTS_MAX_LENGTH;
		try {
			result = '1|' + runModlog(room, searchString, exactSearch, maxLines);
		} catch (err) {
			require('../crashlogger')(err, 'A modlog query', {
				room: room,
				searchString: searchString,
				exactSearch: exactSearch,
				maxLines: maxLines,
			});
			result = '0';
		}
		return result;
	}
}

exports.ModlogManager = ModlogManager;

const PM = exports.PM = new ModlogManager({
	execFile: __filename,
	maxProcesses: MAX_PROCESSES,
	isChatBased: true,
});

class SortedLimitedLengthList {
	constructor(maxSize) {
		this.maxSize = maxSize;
		this.list = [];
	}

	getListClone() {
		return this.list.slice(0);
	}

	tryInsert(element) {
		let insertedAt = -1;
		for (let i = this.list.length - 1; i >= 0; i--) {
			if (element.localeCompare(this.list[i]) < 0) {
				insertedAt = i + 1;
				if (i === this.list.length - 1) {
					this.list.push(element);
					break;
				}
				this.list.splice(i + 1, 0, element);
				break;
			}
		}
		if (insertedAt < 0) this.list.splice(0, 0, element);
		if (this.list.length > this.maxSize) {
			this.list.pop();
			if (insertedAt === this.list.length) return false;
		}
		return true;
	}
}

function checkRipgrepAvailability() {
	if (Config.ripgrepmodlog === undefined) {
		try {
			execFileSync('rg', ['--version'], {cwd: path.normalize(`${__dirname}/${LOG_PATH}`)});
			Config.ripgrepmodlog = true;
		} catch (error) {
			Config.ripgrepmodlog = false;
		}
	}
	return Config.ripgrepmodlog;
}

function runModlog(room, searchString, exactSearch, maxLines) {
	const useRipgrep = checkRipgrepAvailability();
	let fileNameList = [];
	if (room === 'all') {
		const fileList = fs.readdirSync(`${__dirname}/${LOG_PATH}`);
		for (let i = 0; i < fileList.length; i++) {
			fileNameList.push(fileList[i]);
		}
	} else if (room === 'public') {
		const isPublicRoom = (room => !(room.isPrivate || room.battle || room.isPersonal || room.id === 'global'));
		const publicRoomIds = Array.from(Rooms.rooms.values()).filter(isPublicRoom).map(room => room.id);
		for (let i = 0; i < publicRoomIds.length; i++) {
			fileNameList.push(`modlog_${publicRoomIds[i]}.txt`);
		}
	} else {
		fileNameList = [`modlog_${room}.txt`];
	}

	let regexString;
	if (!searchString) {
		regexString = '.';
	} else if (exactSearch) {
		regexString = searchString.replace(/[\\.+*?()|[\]{}^$]/g, '\\$&');
	} else {
		searchString = toId(searchString);
		regexString = `\\b${searchString.split('').join('[\\W_]*')}\\b`;
	}

	let results = new SortedLimitedLengthList(maxLines);
	if (useRipgrep && searchString) {
		if (room === 'all') fileNameList = [`${__dirname}/${LOG_PATH}`];
		runRipgrepModlog(fileNameList, regexString, results);
	} else {
		fileNameList = fileNameList.map(filename => path.normalize(`${__dirname}/${LOG_PATH}${filename}`));
		const searchStringRegex = new RegExp(regexString, 'i');
		for (let i = 0; i < fileNameList.length; i++) {
			checkRoomModlog(fileNameList[i], searchStringRegex, results);
		}
	}
	const resultData = results.getListClone();
	return resultData.join('\n');
}

function checkRoomModlog(path, regex, results) {
	if (!fs.existsSync(path)) return results;
	let newLines = [];
	let lineFragment = '';
	let blockSize = 1024;
	let buf = Buffer.alloc(blockSize);
	const stats = fs.statSync(path);
	let startPos = stats.size;
	const fd = fs.openSync(path, 'r');

	outerLoop: do {
		startPos -= blockSize;
		if (startPos < 0) {
			blockSize += startPos;
			startPos = 0;
		}
		const bytesRead = fs.readSync(fd, buf, 0, blockSize, startPos);
		newLines = buf.toString().substr(0, bytesRead).split('\n').reverse();
		newLines[0] += lineFragment;
		lineFragment = newLines[newLines.length - 1];
		if (startPos > 0) newLines.splice(-1, 1);
		for (let i = 0; i < newLines.length; i++) {
			if (newLines[i] && regex.test(newLines[i])) {
				const insertionSuccessful = results.tryInsert(newLines[i]);
				if (!insertionSuccessful) {
					break outerLoop;
				}
			}
		}
	} while (startPos > 0);

	fs.close(fd);

	return results;
}

function runRipgrepModlog(paths, regexString, results) {
	let stdout;
	try {
		stdout = execFileSync('rg', ['-i', '-e', regexString, '--no-filename', '--no-line-number', ...paths], {cwd: path.normalize(`${__dirname}/${LOG_PATH}`)});
	} catch (error) {
		return results;
	}
	const fileResults = stdout.toString().split('\n').reverse();
	for (let i = 0; i < fileResults.length; i++) {
		results.tryInsert(fileResults[i]);
	}
	return results;
}

function prettifyResults(rawResults, room, searchString, exactSearch, addModlogLinks, hideIps) {
	if (rawResults === '0') {
		return "The modlog query has crashed.";
	}
	let roomName;
	switch (room) {
	case 'all':
		roomName = "all rooms";
		break;
	case 'public':
		roomName = "all public rooms";
		break;
	default:
		roomName = `room ${room}`;
	}
	if (exactSearch) searchString = `"${searchString}"`;
	let pipeIndex = rawResults.indexOf('|');
	if (pipeIndex < 0) pipeIndex = 0;
	rawResults = rawResults.substr(pipeIndex + 1, rawResults.length);
	if (!rawResults) {
		return `No moderator actions containing ${searchString} found on ${roomName}.` +
				(exactSearch ? "" : " Add quotes to the search parameter to search for a phrase, rather than a user.");
	}
	const resultArray = rawResults.split('\n');
	let lines = resultArray.length;
	const resultString = resultArray.map(line => {
		if (hideIps) line = line.replace(/\([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\)/g, '');
		let bracketIndex = line.indexOf(']');
		let parenIndex = line.indexOf(')');
		if (bracketIndex < 0) return Chat.escapeHTML(line);
		const time = line.slice(1, bracketIndex);
		let timestamp = Chat.toTimestamp(new Date(time), {hour12: true});
		parenIndex = line.indexOf(')');
		let thisRoomID = line.slice(bracketIndex + 3, parenIndex);
		if (addModlogLinks) {
			let url = Config.modloglink(time, thisRoomID);
			if (url) timestamp = `<a href="${url}">${timestamp}</a>`;
		}
		return `<small>[${timestamp}] (${thisRoomID})</small>${Chat.escapeHTML(line.slice(parenIndex + 1))}`;
	}).join(`<br />`);
	let preamble;
	if (searchString) {
		preamble = `|wide||html|<p>The last ${lines} logged actions containing ${searchString} on ${roomName}.` +
						(exactSearch ? "" : " Add quotes to the search parameter to search for a phrase, rather than a user.");
	} else {
		preamble = `|wide||html|<p>The last ${lines} lines of the Moderator Log of ${roomName}.`;
	}
	preamble +=	`</p><p><small>[${Chat.toTimestamp(new Date(), {hour12: true})}] \u2190 current server time</small></p>`;
	return preamble + resultString;
}

exports.commands = {
	timedmodlog: 'modlog',
	modlog: function (target, room, user, connection, cmd) {
		const startTime = Date.now();
		let roomId = (room.id === 'staff' ? 'global' : room.id);
		let hideIps = !user.can('lock');

		if (target.includes(',')) {
			let targets = target.split(',');
			target = targets[1].trim();
			roomId = toId(targets[0]) || room.id;
		}

		let targetRoom = Rooms.search(roomId);
		// if a room alias was used, replace alias with actual id
		if (targetRoom) roomId = targetRoom.id;
		if (roomId.startsWith('battle-') || roomId.startsWith('groupchat-')) this.errorReply("Battles and groupchats don't have individual modlogs.");

		// permission checking
		if (roomId === 'all' || roomId === 'public') {
			if (!this.can('modlog')) return;
		} else {
			if (!this.can('modlog', null, targetRoom)) return;
		}

		let addModlogLinks = Config.modloglink && (!hideIps || (targetRoom && targetRoom.isPrivate !== true));
		// Let's check the number of lines to retrieve or if it's a word instead
		let lines = 0;
		if (!target.match(/[^0-9]/)) {
			lines = parseInt(target || 20);
			if (lines > RESULTS_MAX_LENGTH) lines = RESULTS_MAX_LENGTH;
		}
		let wordSearch = (!lines || lines < 0);
		let searchString = '';
		if (wordSearch) {
			searchString = target.trim();
			lines = RESULTS_MAX_LENGTH;
		}
		let exactSearch = '0';
		if (searchString.match(/^["'].+["']$/)) {
			exactSearch = '1';
			searchString = searchString.substring(1, searchString.length - 1);
		}

		PM.send(roomId, searchString, exactSearch, lines).then(response => connection.popup(prettifyResults(response, roomId, searchString, exactSearch, addModlogLinks, hideIps)));
		if (cmd === 'timedmodlog') this.sendReply(`The modlog query took ${Date.now() - startTime} ms to complete.`);
	},
	modloghelp: ["/modlog [roomid|all|public], [n] - Roomid defaults to current room.",
		"If n is a number or omitted, display the last n lines of the moderator log. Defaults to 20.",
		"If n is not a number, search the moderator log for 'n' on room's log [roomid]. If you set [all] as [roomid], searches for 'n' on all rooms's logs.",
		"If you set [public] as [roomid], searches for 'n' in all public room's logs, excluding battles. Requires: % @ * # & ~",
	],
};
<commit_msg>Fix deprecated fs.close call signature<commit_after>'use strict';

const fs = require('fs');
const path = require('path');
const ProcessManager = require('./../process-manager');
const execFileSync = require('child_process').execFileSync;

const MAX_PROCESSES = 1;
const RESULTS_MAX_LENGTH = 100;
const LOG_PATH = '../logs/modlog/';

class ModlogManager extends ProcessManager {
	onMessageUpstream(message) {
		// Protocol:
		// when crashing: 	  "[id]|0"
		// when not crashing: "[id]|1|[results]"
		let pipeIndex = message.indexOf('|');
		let id = +message.substr(0, pipeIndex);

		if (this.pendingTasks.has(id)) {
			this.pendingTasks.get(id)(message.slice(pipeIndex + 1));
			this.pendingTasks.delete(id);
			this.release();
		}
	}

	onMessageDownstream(message) {
		// protocol:
		// "[id]|[room]|[searchString]|[exactSearch]|[maxLines]"
		let pipeIndex = message.indexOf('|');
		let nextPipeIndex = message.indexOf('|', pipeIndex + 1);
		let id = message.substr(0, pipeIndex);
		let room = message.substr(pipeIndex + 1, nextPipeIndex - pipeIndex - 1);

		pipeIndex = nextPipeIndex;
		nextPipeIndex = message.indexOf('|', pipeIndex + 1);
		let searchString = message.substr(pipeIndex + 1, nextPipeIndex - pipeIndex - 1);

		pipeIndex = nextPipeIndex;
		nextPipeIndex = message.indexOf('|', pipeIndex + 1);
		let exactSearch = message.substr(pipeIndex + 1, nextPipeIndex - pipeIndex - 1);
		let maxLines = message.substr(nextPipeIndex + 1);

		process.send(id + '|' + this.receive(room, searchString, exactSearch, maxLines));
	}

	receive(room, searchString, exactSearch, maxLines) {
		let result;
		exactSearch = exactSearch === '1';
		maxLines = Number(maxLines);
		if (isNaN(maxLines) || maxLines > RESULTS_MAX_LENGTH || maxLines < 1) maxLines = RESULTS_MAX_LENGTH;
		try {
			result = '1|' + runModlog(room, searchString, exactSearch, maxLines);
		} catch (err) {
			require('../crashlogger')(err, 'A modlog query', {
				room: room,
				searchString: searchString,
				exactSearch: exactSearch,
				maxLines: maxLines,
			});
			result = '0';
		}
		return result;
	}
}

exports.ModlogManager = ModlogManager;

const PM = exports.PM = new ModlogManager({
	execFile: __filename,
	maxProcesses: MAX_PROCESSES,
	isChatBased: true,
});

class SortedLimitedLengthList {
	constructor(maxSize) {
		this.maxSize = maxSize;
		this.list = [];
	}

	getListClone() {
		return this.list.slice(0);
	}

	tryInsert(element) {
		let insertedAt = -1;
		for (let i = this.list.length - 1; i >= 0; i--) {
			if (element.localeCompare(this.list[i]) < 0) {
				insertedAt = i + 1;
				if (i === this.list.length - 1) {
					this.list.push(element);
					break;
				}
				this.list.splice(i + 1, 0, element);
				break;
			}
		}
		if (insertedAt < 0) this.list.splice(0, 0, element);
		if (this.list.length > this.maxSize) {
			this.list.pop();
			if (insertedAt === this.list.length) return false;
		}
		return true;
	}
}

function checkRipgrepAvailability() {
	if (Config.ripgrepmodlog === undefined) {
		try {
			execFileSync('rg', ['--version'], {cwd: path.normalize(`${__dirname}/${LOG_PATH}`)});
			Config.ripgrepmodlog = true;
		} catch (error) {
			Config.ripgrepmodlog = false;
		}
	}
	return Config.ripgrepmodlog;
}

function runModlog(room, searchString, exactSearch, maxLines) {
	const useRipgrep = checkRipgrepAvailability();
	let fileNameList = [];
	if (room === 'all') {
		const fileList = fs.readdirSync(`${__dirname}/${LOG_PATH}`);
		for (let i = 0; i < fileList.length; i++) {
			fileNameList.push(fileList[i]);
		}
	} else if (room === 'public') {
		const isPublicRoom = (room => !(room.isPrivate || room.battle || room.isPersonal || room.id === 'global'));
		const publicRoomIds = Array.from(Rooms.rooms.values()).filter(isPublicRoom).map(room => room.id);
		for (let i = 0; i < publicRoomIds.length; i++) {
			fileNameList.push(`modlog_${publicRoomIds[i]}.txt`);
		}
	} else {
		fileNameList = [`modlog_${room}.txt`];
	}

	let regexString;
	if (!searchString) {
		regexString = '.';
	} else if (exactSearch) {
		regexString = searchString.replace(/[\\.+*?()|[\]{}^$]/g, '\\$&');
	} else {
		searchString = toId(searchString);
		regexString = `\\b${searchString.split('').join('[\\W_]*')}\\b`;
	}

	let results = new SortedLimitedLengthList(maxLines);
	if (useRipgrep && searchString) {
		if (room === 'all') fileNameList = [`${__dirname}/${LOG_PATH}`];
		runRipgrepModlog(fileNameList, regexString, results);
	} else {
		fileNameList = fileNameList.map(filename => path.normalize(`${__dirname}/${LOG_PATH}${filename}`));
		const searchStringRegex = new RegExp(regexString, 'i');
		for (let i = 0; i < fileNameList.length; i++) {
			checkRoomModlog(fileNameList[i], searchStringRegex, results);
		}
	}
	const resultData = results.getListClone();
	return resultData.join('\n');
}

function checkRoomModlog(path, regex, results) {
	if (!fs.existsSync(path)) return results;
	let newLines = [];
	let lineFragment = '';
	let blockSize = 1024;
	let buf = Buffer.alloc(blockSize);
	const stats = fs.statSync(path);
	let startPos = stats.size;
	const fd = fs.openSync(path, 'r');

	outerLoop: do {
		startPos -= blockSize;
		if (startPos < 0) {
			blockSize += startPos;
			startPos = 0;
		}
		const bytesRead = fs.readSync(fd, buf, 0, blockSize, startPos);
		newLines = buf.toString().substr(0, bytesRead).split('\n').reverse();
		newLines[0] += lineFragment;
		lineFragment = newLines[newLines.length - 1];
		if (startPos > 0) newLines.splice(-1, 1);
		for (let i = 0; i < newLines.length; i++) {
			if (newLines[i] && regex.test(newLines[i])) {
				const insertionSuccessful = results.tryInsert(newLines[i]);
				if (!insertionSuccessful) {
					break outerLoop;
				}
			}
		}
	} while (startPos > 0);

	fs.close(fd, () => {});

	return results;
}

function runRipgrepModlog(paths, regexString, results) {
	let stdout;
	try {
		stdout = execFileSync('rg', ['-i', '-e', regexString, '--no-filename', '--no-line-number', ...paths], {cwd: path.normalize(`${__dirname}/${LOG_PATH}`)});
	} catch (error) {
		return results;
	}
	const fileResults = stdout.toString().split('\n').reverse();
	for (let i = 0; i < fileResults.length; i++) {
		results.tryInsert(fileResults[i]);
	}
	return results;
}

function prettifyResults(rawResults, room, searchString, exactSearch, addModlogLinks, hideIps) {
	if (rawResults === '0') {
		return "The modlog query has crashed.";
	}
	let roomName;
	switch (room) {
	case 'all':
		roomName = "all rooms";
		break;
	case 'public':
		roomName = "all public rooms";
		break;
	default:
		roomName = `room ${room}`;
	}
	if (exactSearch) searchString = `"${searchString}"`;
	let pipeIndex = rawResults.indexOf('|');
	if (pipeIndex < 0) pipeIndex = 0;
	rawResults = rawResults.substr(pipeIndex + 1, rawResults.length);
	if (!rawResults) {
		return `No moderator actions containing ${searchString} found on ${roomName}.` +
				(exactSearch ? "" : " Add quotes to the search parameter to search for a phrase, rather than a user.");
	}
	const resultArray = rawResults.split('\n');
	let lines = resultArray.length;
	const resultString = resultArray.map(line => {
		if (hideIps) line = line.replace(/\([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\)/g, '');
		let bracketIndex = line.indexOf(']');
		let parenIndex = line.indexOf(')');
		if (bracketIndex < 0) return Chat.escapeHTML(line);
		const time = line.slice(1, bracketIndex);
		let timestamp = Chat.toTimestamp(new Date(time), {hour12: true});
		parenIndex = line.indexOf(')');
		let thisRoomID = line.slice(bracketIndex + 3, parenIndex);
		if (addModlogLinks) {
			let url = Config.modloglink(time, thisRoomID);
			if (url) timestamp = `<a href="${url}">${timestamp}</a>`;
		}
		return `<small>[${timestamp}] (${thisRoomID})</small>${Chat.escapeHTML(line.slice(parenIndex + 1))}`;
	}).join(`<br />`);
	let preamble;
	if (searchString) {
		preamble = `|wide||html|<p>The last ${lines} logged actions containing ${searchString} on ${roomName}.` +
						(exactSearch ? "" : " Add quotes to the search parameter to search for a phrase, rather than a user.");
	} else {
		preamble = `|wide||html|<p>The last ${lines} lines of the Moderator Log of ${roomName}.`;
	}
	preamble +=	`</p><p><small>[${Chat.toTimestamp(new Date(), {hour12: true})}] \u2190 current server time</small></p>`;
	return preamble + resultString;
}

exports.commands = {
	timedmodlog: 'modlog',
	modlog: function (target, room, user, connection, cmd) {
		const startTime = Date.now();
		let roomId = (room.id === 'staff' ? 'global' : room.id);
		let hideIps = !user.can('lock');

		if (target.includes(',')) {
			let targets = target.split(',');
			target = targets[1].trim();
			roomId = toId(targets[0]) || room.id;
		}

		let targetRoom = Rooms.search(roomId);
		// if a room alias was used, replace alias with actual id
		if (targetRoom) roomId = targetRoom.id;
		if (roomId.startsWith('battle-') || roomId.startsWith('groupchat-')) this.errorReply("Battles and groupchats don't have individual modlogs.");

		// permission checking
		if (roomId === 'all' || roomId === 'public') {
			if (!this.can('modlog')) return;
		} else {
			if (!this.can('modlog', null, targetRoom)) return;
		}

		let addModlogLinks = Config.modloglink && (!hideIps || (targetRoom && targetRoom.isPrivate !== true));
		// Let's check the number of lines to retrieve or if it's a word instead
		let lines = 0;
		if (!target.match(/[^0-9]/)) {
			lines = parseInt(target || 20);
			if (lines > RESULTS_MAX_LENGTH) lines = RESULTS_MAX_LENGTH;
		}
		let wordSearch = (!lines || lines < 0);
		let searchString = '';
		if (wordSearch) {
			searchString = target.trim();
			lines = RESULTS_MAX_LENGTH;
		}
		let exactSearch = '0';
		if (searchString.match(/^["'].+["']$/)) {
			exactSearch = '1';
			searchString = searchString.substring(1, searchString.length - 1);
		}

		PM.send(roomId, searchString, exactSearch, lines).then(response => connection.popup(prettifyResults(response, roomId, searchString, exactSearch, addModlogLinks, hideIps)));
		if (cmd === 'timedmodlog') this.sendReply(`The modlog query took ${Date.now() - startTime} ms to complete.`);
	},
	modloghelp: ["/modlog [roomid|all|public], [n] - Roomid defaults to current room.",
		"If n is a number or omitted, display the last n lines of the moderator log. Defaults to 20.",
		"If n is not a number, search the moderator log for 'n' on room's log [roomid]. If you set [all] as [roomid], searches for 'n' on all rooms's logs.",
		"If you set [public] as [roomid], searches for 'n' in all public room's logs, excluding battles. Requires: % @ * # & ~",
	],
};
<|endoftext|>


<commit_before>import { take, put, call, fork, select, all, takeLatest, takeEvery } from 'redux-saga/effects'

import options from 'template-tools/src/utils/options'
import consoleTools from 'template-ui/lib/utils/console'

import { ForkListeners } from '../../utils/saga'
import { devLogger } from '../../utils/console'

import authSelectors from '../auth/selectors'

import actions, { TYPES } from './actions'
import selectors from './selectors'

const REQUIRED = [
  'getRouteHooks',
  'getRoute',
  'getHook'
]

const RouterSaga = (opts = {}) => {
  opts = options.processor(opts, {
    required: REQUIRED
  })

  const { getHook, getRoute, getRouteHooks } = opts

  // run though a sequence of hooks - blocking until
  //  * there are none left
  //  * one of them returns not true
  // hooks = []string
  function* runHookArray(hookNames) {
    let hookList = [].concat(hookNames)
    let ok = true
    while(ok && hookList.length > 0) {
      const nextHook = hookList.shift()
      const hookok = yield call(runHook, nextHook)
      ok = hookok === false ? false : true
      consoleTools.devRun(() => {
        if(!ok) {
          console.log(`HOOK ARRAY CANCELLED: ${nextHook}`)
        }
      })
    }
  }

  function* runRedirect(path) {
    if(path.indexOf('/') != 0) {
      yield call(runHook, path)
      return
    }
    let route = getRoute(path)
    const routerParams = yield select(state => state.router.params)
    route = route.replace(/:(\w+)/g, name => {
      return routerParams[name.replace(/^:/, '')]
    })
    consoleTools.devRun(() => {
      console.log(`REDIRECT: ${path} -> ${route}`)
    })
    yield put(actions.push(route))
  }

  // run a single hook
  function* runHook(name, payload) {
    consoleTools.devRun(() => {
      console.log(`HOOK RUN: ${name}`)
      if(payload) console.dir(payload)
    })
    const hook = getHook(name)
    if(!hook) throw new Error(`no hook found for ${name}`)
    const result = yield call(hook, payload)
    return result
  }

  function* handleRedirectAction(action) {
    yield call(runRedirect, action.name)
  }

  // handle an action that means run a hook
  function* handleHookAction(action) {
    yield call(runHook, action.name, action.payload)
  }

  function* handleChangeAction() {
    const router = yield select(state => state.router)

    // run the onLeave hooks for the previous route (if any)
    const leaveRouteHooks = getRouteHooks(router.previous || {}, 'leave')
    consoleTools.devRun(() => {
      if(leaveRouteHooks.length > 0) {
        console.log(`HOOKS - LEAVE: ${leaveRouteHooks.join(', ')}`)
      }
    })
    yield call(runHookArray, leaveRouteHooks)

    const enterRouteHooks = getRouteHooks(router || {}, 'enter')
    consoleTools.devRun(() => {
      if(enterRouteHooks.length > 0) {
        console.log(`HOOKS - ENTER: ${enterRouteHooks.join(', ')}`)
      }
    })
    yield call(runHookArray, enterRouteHooks)
  }

  function* initialize() {
    yield takeEvery(TYPES.redirect, handleRedirectAction)
    yield takeEvery(TYPES.hook, handleHookAction)
    yield takeEvery(TYPES.changed, handleChangeAction)
    yield call(handleChangeAction)
  }

  return {
    initialize
  }
}

export default RouterSaga<commit_msg>add router hook logging disable<commit_after>import { take, put, call, fork, select, all, takeLatest, takeEvery } from 'redux-saga/effects'

import options from 'template-tools/src/utils/options'
import consoleTools from 'template-ui/lib/utils/console'

import { ForkListeners } from '../../utils/saga'
import { devLogger } from '../../utils/console'

import authSelectors from '../auth/selectors'

import actions, { TYPES } from './actions'
import selectors from './selectors'

const REQUIRED = [
  'getRouteHooks',
  'getRoute',
  'getHook'
]

const RouterSaga = (opts = {}) => {
  opts = options.processor(opts, {
    required: REQUIRED
  })

  const { getHook, getRoute, getRouteHooks } = opts

  // run though a sequence of hooks - blocking until
  //  * there are none left
  //  * one of them returns not true
  // hooks = []string
  function* runHookArray(hookNames) {
    let hookList = [].concat(hookNames)
    let ok = true
    while(ok && hookList.length > 0) {
      const nextHook = hookList.shift()
      const hookok = yield call(runHook, nextHook)
      ok = hookok === false ? false : true
      consoleTools.devRun(() => {
        if(!ok) {
          console.log(`HOOK ARRAY CANCELLED: ${nextHook}`)
        }
      })
    }
  }

  function* runRedirect(path) {
    if(path.indexOf('/') != 0) {
      yield call(runHook, path)
      return
    }
    let route = getRoute(path)
    const routerParams = yield select(state => state.router.params)
    route = route.replace(/:(\w+)/g, name => {
      return routerParams[name.replace(/^:/, '')]
    })
    consoleTools.devRun(() => {
      console.log(`REDIRECT: ${path} -> ${route}`)
    })
    yield put(actions.push(route))
  }

  // run a single hook
  function* runHook(name, payload) {
    consoleTools.devRun(() => {
      if(!payload || !payload._nolog) {
        console.log(`HOOK RUN: ${name}`)
        if(payload) console.dir(payload)
      }
    })
    const hook = getHook(name)
    if(!hook) throw new Error(`no hook found for ${name}`)
    const result = yield call(hook, payload)
    return result
  }

  function* handleRedirectAction(action) {
    yield call(runRedirect, action.name)
  }

  // handle an action that means run a hook
  function* handleHookAction(action) {
    yield call(runHook, action.name, action.payload)
  }

  function* handleChangeAction() {
    const router = yield select(state => state.router)

    // run the onLeave hooks for the previous route (if any)
    const leaveRouteHooks = getRouteHooks(router.previous || {}, 'leave')
    consoleTools.devRun(() => {
      if(leaveRouteHooks.length > 0) {
        console.log(`HOOKS - LEAVE: ${leaveRouteHooks.join(', ')}`)
      }
    })
    yield call(runHookArray, leaveRouteHooks)

    const enterRouteHooks = getRouteHooks(router || {}, 'enter')
    consoleTools.devRun(() => {
      if(enterRouteHooks.length > 0) {
        console.log(`HOOKS - ENTER: ${enterRouteHooks.join(', ')}`)
      }
    })
    yield call(runHookArray, enterRouteHooks)
  }

  function* initialize() {
    yield takeEvery(TYPES.redirect, handleRedirectAction)
    yield takeEvery(TYPES.hook, handleHookAction)
    yield takeEvery(TYPES.changed, handleChangeAction)
    yield call(handleChangeAction)
  }

  return {
    initialize
  }
}

export default RouterSaga<|endoftext|>


<commit_before>import {curryN} from './curryN';

const _construct =
  Fn =>
    curryN(
      Fn.length,
      (...args) =>
        new Fn(...args)
    );

const throwError = () => {throw new Error('Constructor with greater than ten arguments');};

export const construct =
  Fn =>
    Fn.length > 10 ? throwError()
                   : _construct(Fn);
<commit_msg>refactor(construct): refactor to use constructN<commit_after>import {constructN} from './constructN';

export const construct =
  Fn =>
    constructN(Fn.length, Fn);
<|endoftext|>


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

// Packages
const minimist = require('minimist')
const chalk = require('chalk')
const fetch = require('node-fetch')
const ora = require('ora')

// Utilities
const cfg = require('../lib/cfg')
const logo = require('../lib/utils/output/logo')
const { handleError } = require('../lib/error')

const help = () => {
  console.log(`
  ${chalk.bold(`${logo} now logout`)}

  ${chalk.dim('Options:')}

    -h, --help              output usage information
    -c ${chalk.bold.underline('FILE')}, --config=${chalk.bold.underline(
    'FILE'
  )}  config file

  ${chalk.dim('Examples:')}

  ${chalk.gray('–')} Logout from the CLI:

    ${chalk.cyan('$ now logout')}
`)
}

let argv
let apiUrl
let endpoint

const main = async ctx => {
  argv = minimist(ctx.argv.slice(2), {
    string: ['config'],
    boolean: ['help'],
    alias: {
      help: 'h',
      config: 'c'
    }
  })

  apiUrl = argv.url || 'https://api.zeit.co'
  endpoint = apiUrl + '/www/user/tokens/'

  if (argv.config) {
    cfg.setConfigFile(argv.config)
  }

  if (argv.help) {
    help()
    process.exit(0)
  }

  logout()
}

module.exports = async ctx => {
  try {
    await main(ctx)
  } catch (err) {
    handleError(err)
    process.exit(1)
  }
}

const requestHeaders = token => ({
  headers: {
    Authorization: `bearer ${token}`
  }
})

const getTokenId = async token => {
  const result = await fetch(endpoint, requestHeaders(token))
  const tokenList = await result.json()

  if (!tokenList.tokens) {
    return
  }

  const tokenInfo = tokenList.tokens.find(t => token === t.token)

  if (!tokenInfo) {
    return
  }

  return tokenInfo.id
}

const revokeToken = async (token, tokenId) => {
  const details = {
    method: 'DELETE'
  }

  Object.assign(details, requestHeaders(token))
  const result = await fetch(endpoint + encodeURIComponent(tokenId), details)

  if (!result.ok) {
    console.error('Not able to log out')
  }
}

const logout = async () => {
  const spinner = ora({
    text: 'Logging out...'
  }).start()

  const config = await cfg.read()

  try {
    await cfg.removeFile()
  } catch (err) {
    spinner.fail(`Couldn't remove config while logging out`)
    process.exit(1)
  }

  let tokenId

  try {
    tokenId = await getTokenId(argv.token || config.token)
  } catch (err) {
    spinner.fail('Not able to get token id on logout')
    process.exit(1)
  }

  if (!tokenId) {
    return
  }

  try {
    await revokeToken(argv.token || config.token, tokenId)
  } catch (err) {
    spinner.fail('Could not revoke token on logout')
    process.exit(1)
  }

  spinner.succeed('Logged out!')
}
<commit_msg>Made loggin out from .sh work<commit_after>#!/usr/bin/env node

// Packages
const minimist = require('minimist')
const chalk = require('chalk')
const fetch = require('node-fetch')
const ora = require('ora')

// Utilities
const logo = require('../lib/utils/output/logo')
const { handleError } = require('../lib/error')
const {
  readConfigFile,
  writeToConfigFile,
  readAuthConfigFile,
  writeToAuthConfigFile
} = require('../../../../util/config-files')

const help = () => {
  console.log(`
  ${chalk.bold(`${logo} now logout`)}

  ${chalk.dim('Options:')}

    -h, --help              output usage information
    -c ${chalk.bold.underline('FILE')}, --config=${chalk.bold.underline(
    'FILE'
  )}  config file

  ${chalk.dim('Examples:')}

  ${chalk.gray('–')} Logout from the CLI:

    ${chalk.cyan('$ now logout')}
`)
}

let argv
let apiUrl
let endpoint

const main = async ctx => {
  argv = minimist(ctx.argv.slice(2), {
    boolean: ['help'],
    alias: {
      help: 'h'
    }
  })

  apiUrl = argv.url || 'https://api.zeit.co'
  endpoint = apiUrl + '/www/user/tokens/'

  if (argv.help) {
    help()
    process.exit(0)
  }

  logout()
}

module.exports = async ctx => {
  try {
    await main(ctx)
  } catch (err) {
    handleError(err)
    process.exit(1)
  }
}

const requestHeaders = token => ({
  headers: {
    Authorization: `bearer ${token}`
  }
})

const getTokenId = async token => {
  const result = await fetch(endpoint, requestHeaders(token))
  const tokenList = await result.json()

  if (!tokenList.tokens) {
    return
  }

  const tokenInfo = tokenList.tokens.find(t => token === t.token)

  if (!tokenInfo) {
    return
  }

  return tokenInfo.id
}

const revokeToken = async (token, tokenId) => {
  const details = {
    method: 'DELETE'
  }

  Object.assign(details, requestHeaders(token))
  const result = await fetch(endpoint + encodeURIComponent(tokenId), details)

  if (!result.ok) {
    console.error('Not able to log out')
  }
}

const logout = async () => {
  const spinner = ora({
    text: 'Logging out...'
  }).start()

  const configContent = JSON.parse(readConfigFile())

  if (configContent.sh) {
    delete configContent.sh
  }

  const authContent = JSON.parse(readAuthConfigFile())
  const {credentials} = authContent
  const related = credentials.find(item => item.provider === 'sh')
  const index = credentials.indexOf(related)

  credentials.splice(index, 1)
  authContent.credentials = credentials

  try {
    await writeToConfigFile(configContent)
    await writeToAuthConfigFile(authContent)
  } catch (err) {
    spinner.fail(`Couldn't remove config while logging out`)
    process.exit(1)
  }

  let tokenId

  try {
    tokenId = await getTokenId(argv.token || related.token)
  } catch (err) {
    spinner.fail('Not able to get token id on logout')
    process.exit(1)
  }

  if (!tokenId) {
    return
  }

  try {
    await revokeToken(argv.token || related.token, tokenId)
  } catch (err) {
    spinner.fail('Could not revoke token on logout')
    process.exit(1)
  }

  spinner.succeed('Logged out!')
}
<|endoftext|>


<commit_before>angular.module('rc.contextMenu', [])
    .directive("rcContextMenuArea", function() {
        return {
            restrict: "A",
            replace: true,
            link: function(scope, element, attrs) {
                var isOpen = false,
                    isAbsolutePosition = isPositionAbsolute(attrs['rc-position']),
                    contextMenu = angular.element(element.children('.rc-context-menu'));

                contextMenu.css('display', isAbsolutePosition ? 'absolute' : 'fixed');

                function isPositionAbsolute(position) {
                    return typeof position != 'undefined' && position === 'absolute';
                }

                function closeContextMenuOnDesktop(event) {
                    if(isOpen && !isRightClick(event))
                        hideContextMenu();
                }

                function isRightClick(event) {
                    if(event.which)
                        return event.which == 3;
                    else if(event.button)
                        return event.button == 2;
                }

                window.addEventListener("click", closeContextMenuOnDesktop, false);

                function toggleContextMenu(event) {
                    if(element[0].contains(event.target)) {
                        isOpen = true;
                        event.preventDefault();
                        event.stopPropagation();

                        var coordinates = getCoordinates(event, isAbsolutePosition);
                        contextMenu.css({visibility: 'visible', left: coordinates.left, top: coordinates.top});
                    } else if(isOpen) {
                        hideContextMenu();
                    }
                }

                function getCoordinates(event, isAbsolutePosition) {
                    if(isAbsolutePosition) {
                        return {
                            left: (event.pageX - element.offset().left) + 'px',
                            top: (event.pageY - element.offset().top) + 'px'
                        };
                    } else {
                        return {
                            left: event.clientX + 'px',
                            top: event.clientY + 'px'
                        };
                    }
                }

                window.addEventListener("contextmenu", toggleContextMenu, false);

                function hideContextMenu() {
                    isOpen = false;
                    contextMenu.css({visibility: 'hidden'});
                }

                scope.$on('$destroy', function () {
                    window.removeEventListener("click", closeContextMenuOnDesktop, false);
                    window.removeEventListener("contextmenu", toggleContextMenu, false);
                });
            }
        }
    })
    .directive("rcContextMenu", function() {
        return {
            restrict: 'E',
            transclude: true,
            replace: true,
            template: "

",
            scope: {
                isDisabled: "=ngDisabled"
            },
            controller: function($scope) {
                var self = this;
                self.isDisabled = $scope.isDisabled;
            }
        };
    })
    .directive("rcContextMenuTitle", function() {
        return {
            restrict: "E",
            transclude: true,
            replace: true,
            template: "

"
        }
    })
    .directive("rcContextMenuDivider", function() {
        return {
            restrict: "E",
            replace: true,
            template: "

"
        }
    })
    .directive("rcContextMenuItem", function() {
        return {
            restrict: "E",
            transclude: true,
            replace: true,
            require: "^rcContextMenu",
            scope: {
                isDisabled: "=ngDisabled",
                callback: "&onSelect"
            },
            template: "

",
            link: function(scope, element, attrs, contextMenuCtrl) {
                scope.itemWasClicked = function() {
                    if(!scope.isDisabled && !contextMenuCtrl.isDisabled)
                        scope.callback();
                }
            }
        }
    });
<commit_msg>Added function for calculating offset of the element. Fixed syntax mistakes which are related to absolute position.<commit_after>angular.module('rc.contextMenu', [])
    .directive("rcContextMenuArea", function() {
        return {
            restrict: "A",
            replace: true,
            link: function(scope, element, attrs) {
                var isOpen = false,
                    isAbsolutePosition = isPositionAbsolute(attrs['rcPosition']),
                    contextMenu = angular.element(element.children('.rc-context-menu'));

                contextMenu.css({'position': isAbsolutePosition ? 'absolute' : 'fixed'});

                function isPositionAbsolute(position) {
                    return typeof position != 'undefined' && position === 'absolute';
                }

                function closeContextMenuOnDesktop(event) {
                    if(isOpen && !isRightClick(event))
                        hideContextMenu();
                }

                function isRightClick(event) {
                    if(event.which)
                        return event.which == 3;
                    else if(event.button)
                        return event.button == 2;
                }

                window.addEventListener("click", closeContextMenuOnDesktop, false);

                function toggleContextMenu(event) {
                    if(element[0].contains(event.target)) {
                        isOpen = true;
                        event.preventDefault();
                        event.stopPropagation();

                        var coordinates = getCoordinates(event, isAbsolutePosition);
                        contextMenu.css({visibility: 'visible', left: coordinates.left, top: coordinates.top});
                    } else if(isOpen) {
                        hideContextMenu();
                    }
                }

                function getCoordinates(event, isAbsolutePosition) {
                    if(isAbsolutePosition) {
                        var elementOffset = getElementOffset(element[0]);
                        return {
                            left: (event.pageX - elementOffset.left) + 'px',
                            top: (event.pageY - elementOffset.top) + 'px'
                        };
                    } else {
                        return {
                            left: event.clientX + 'px',
                            top: event.clientY + 'px'
                        };
                    }

                    function getElementOffset(element)
                    {
                        var de = document.documentElement;
                        var box = element.getBoundingClientRect();
                        var top = box.top + window.pageYOffset - de.clientTop;
                        var left = box.left + window.pageXOffset - de.clientLeft;
                        return {
                            top: top,
                            left: left
                        };
                    }
                }

                window.addEventListener("contextmenu", toggleContextMenu, false);

                function hideContextMenu() {
                    isOpen = false;
                    contextMenu.css({visibility: 'hidden'});
                }

                scope.$on('$destroy', function () {
                    window.removeEventListener("click", closeContextMenuOnDesktop, false);
                    window.removeEventListener("contextmenu", toggleContextMenu, false);
                });
            }
        }
    })
    .directive("rcContextMenu", function() {
        return {
            restrict: 'E',
            transclude: true,
            replace: true,
            template: "

",
            scope: {
                isDisabled: "=ngDisabled"
            },
            controller: function($scope) {
                var self = this;
                self.isDisabled = $scope.isDisabled;
            }
        };
    })
    .directive("rcContextMenuTitle", function() {
        return {
            restrict: "E",
            transclude: true,
            replace: true,
            template: "

"
        }
    })
    .directive("rcContextMenuDivider", function() {
        return {
            restrict: "E",
            replace: true,
            template: "

"
        }
    })
    .directive("rcContextMenuItem", function() {
        return {
            restrict: "E",
            transclude: true,
            replace: true,
            require: "^rcContextMenu",
            scope: {
                isDisabled: "=ngDisabled",
                callback: "&onSelect"
            },
            template: "

",
            link: function(scope, element, attrs, contextMenuCtrl) {
                scope.itemWasClicked = function() {
                    if(!scope.isDisabled && !contextMenuCtrl.isDisabled)
                        scope.callback();
                }
            }
        }
    });
<|endoftext|>


<commit_before>var data = [];
var sectors_ = ["agriculture", "education", "hlth", "water'"];
_.times(40, function(i){ data.push({sector: sectors_[i%4], something: i%3==0}); });

var sectors;
$.ajax({url: '/static/tmp_sectors.json',async: false,dataType: 'json'})
    .done(function(_sectors){sectors = _sectors;});

module("NMIS", {
    setup: function(){
        NMIS.init(data, sectors);
    },
    teardown: function(){
        NMIS.clear();
    }
});

test("NMIS", function(){
    ok(NMIS.init(data, sectors), "NMIS.init() works");
    ok(NMIS.Tabulation !== undefined, "Tabulation exists");
});

test("Tabulations work with sample data", function(){
    deepEqual(Tabulation.sectorSlug("education", "something"), {
        'false': 7,
        'true': 3
    }, "Tabulation.sectorSlug correctly calculates the tabulations.");
    deepEqual(Tabulation.sectorSlugAsArray("education", "something"),
            [
                {
                    occurrences: 'false',
                    value: 7
                },
                {
                    occurrences: 'true',
                    value: 3
                }
            ], "Tabulation.sectorSlugAsArray (which is used once) maps the tabulations into an array.");
    deepEqual(Tabulation.sectorSlug("education", "something", ["true", "false", "maybe"]), {
        'true': 3,
        'false': 7,
        'maybe': 0
    }, "Tabulation.sectorSlug can receive a list of keys and will include values as 0 if not found.")
});

test("Sectors", function(){
    var sectorList = Sectors.all();
    equal(sectorList.length, 3);
    equal(Sectors.pluck('health').slug, 'health', "Sectors.pluck(slug) works.")
});

var data2;
$.ajax({url: '/static/tmp_data.json',async: false,dataType: 'json'})
    .done(function(_data2){data2 = _data2;});

module("NMIS Data", {
    setup: function(){}
});

test("NMIS Data Validation", function(){
    NMIS.init(data2, sectors);
    ok(NMIS.validateData(), "Data is validated");
    equal(NMIS.dataForSector('health').length, 12, "Data for health has a length of x");
});

module("Table builder", {
    setup: function(){
        this.elem = $('<div />');
        $('#qunit-header').before(this.elem);
        NMIS.init(data2, sectors);
    },
    teardown: function(){
//        this.elem.remove();
    }
});

test("something", function(){
    NMIS.FacilityTables.createForSectors(['health'])
        .appendTo(this.elem);
    NMIS.FacilityTables.select('health', 'malaria');
    equal(this.elem.find('table').length, 1, "There is one table in the element.")
})<commit_msg>changing up "tabulations_test" to use data generated in this file.<commit_after>var data = [];
var sectors = [], _sectors = ["Agriculture", "Education", "Health", "Water"];
_.each(_sectors, function(s){
    sectors.push({
        name: s,
        slug: s.toLowerCase()
    });
});
_.times(40, function(i){
    data.push({
        sector: sectors[i%4].slug,
        something: i%3==0
    });
});

// var sectors;
// $.ajax({url: '/static/tmp_sectors.json',async: false,dataType: 'json'})
//     .done(function(_sectors){sectors = _sectors;});

module("NMIS", {
    setup: function(){
        NMIS.init(data, sectors);
    },
    teardown: function(){
        NMIS.clear();
    }
});

test("NMIS", function(){
    ok(NMIS.init(data, sectors), "NMIS.init() works");
    ok(NMIS.Tabulation !== undefined, "Tabulation exists");
});

test("Tabulations work with sample data", function(){
    deepEqual(Tabulation.sectorSlug("education", "something"), {
        'false': 7,
        'true': 3
    }, "Tabulation.sectorSlug correctly calculates the tabulations.");
    deepEqual(Tabulation.sectorSlugAsArray("education", "something"),
            [
                {
                    occurrences: 'false',
                    value: 7
                },
                {
                    occurrences: 'true',
                    value: 3
                }
            ], "Tabulation.sectorSlugAsArray (which is used once) maps the tabulations into an array.");
    deepEqual(Tabulation.sectorSlug("education", "something", ["true", "false", "maybe"]), {
        'true': 3,
        'false': 7,
        'maybe': 0
    }, "Tabulation.sectorSlug can receive a list of keys and will include values as 0 if not found.")
});

test("Sectors", function(){
    var sectorList = Sectors.all();
    equal(sectorList.length, 4);
    equal(Sectors.pluck('health').slug, 'health', "Sectors.pluck(slug) works.")
});

// var data;
// $.ajax({url: '/static/tmp_data.json',async: false,dataType: 'json'})
//     .done(function(_data){data = _data;});

module("NMIS Data", {
    setup: function(){}
});

test("NMIS Data Validation", function(){
    NMIS.init(data, sectors);
    ok(NMIS.validateData(), "Data is validated");
    equal(NMIS.dataForSector('health').length, 10, "Data for health has a length of x");
});

// test("something", function(){
//     NMIS.FacilityTables.createForSectors(['health'])
//         .appendTo(this.elem);
//     NMIS.FacilityTables.select('health', 'malaria');
//     equal(this.elem.find('table').length, 1, "There is one table in the element.")
// })<|endoftext|>


<commit_before>// ==UserScript==
// @name       Facebook remove adds
// @namespace  http://gubnota.github.io/fenki_js_helpers/plugin/monkey/
// @version    0.0.1
// @downloadURL http://gubnota.github.io/fenki_js_helpers/plugin/monkey/fb_remove_adds.js
// @description removes adds block in Facebook
// @include      https://www.facebook.com/*
// @copyright  2012+, Vladislav Muravyev
// @grant          none
// ==/UserScript==
(function(){
var t = setInterval(function(){
var el = document.getElementsByClassName('ego_column');
    for(var i =0; i<el.length; i++){
    el[i].remove();//clearInterval(t);
    }
    },100);
})();

<commit_msg>rearrangment<commit_after>// ==UserScript==
// @name       Facebook remove adds
// @namespace  http://gubnota.github.io/fenki_js_helpers/plugin/monkey/
// @version    0.0.3
// @downloadURL http://gubnota.github.io/fenki_js_helpers/plugin/monkey/fb_remove_adds.js
// @description removes adds block in Facebook
// @include      https://www.facebook.com/*
// @copyright  2012+, Vladislav Muravyev
// @grant          none
// ==/UserScript==
(function(){
var t = setInterval(function(){
var el = document.getElementsByClassName('ego_column');
    for(var i =0; i<el.length; i++){
    el[i].remove();//clearInterval(t);
    }
    },100);
})();

<|endoftext|>


<commit_before>var dev = 'http://localhost:55881' // eslint-disable-line
var staging = 'http://streetsupport-api-staging.apphb.com' // eslint-disable-line
var live = 'http://api.streetsupport.net' // eslint-disable-line

function p (url) {
  return staging + url
}

var createSessionUrl = '/v1/sessions/create'
var getServiceProvidersUrl = '/v1/all-service-providers'
var serviceProviderVerificationsUrl = '/v1/verified-service-providers'
var serviceProviderPublishedUrl = '/v1/published-service-providers'

module.exports = {
  createSession: p(createSessionUrl),
  getServiceProviders: p(getServiceProvidersUrl),
  serviceProviderVerifications: p(serviceProviderVerificationsUrl),
  serviceProviderPublished: p(serviceProviderPublishedUrl)
}
<commit_msg>point to dev<commit_after>var dev = 'http://localhost:55881' // eslint-disable-line
var staging = 'http://streetsupport-api-staging.apphb.com' // eslint-disable-line
var live = 'http://api.streetsupport.net' // eslint-disable-line

function p (url) {
  return dev + url
}

var createSessionUrl = '/v1/sessions/create'
var getServiceProvidersUrl = '/v1/all-service-providers'
var serviceProviderVerificationsUrl = '/v1/verified-service-providers'
var serviceProviderPublishedUrl = '/v1/published-service-providers'

module.exports = {
  createSession: p(createSessionUrl),
  getServiceProviders: p(getServiceProvidersUrl),
  serviceProviderVerifications: p(serviceProviderVerificationsUrl),
  serviceProviderPublished: p(serviceProviderPublishedUrl)
}
<|endoftext|>