<commit_before>/*
Copyright 2007-2009 WebDriver committers
Copyright 2007-2009 Google Inc.
Portions copyright 2007 ThoughtWorks, Inc

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

const charset = "UTF-8";
const CI = Components.interfaces;

function SocketListener(server, transport)
{
    this.outstream = transport.openOutputStream(Components.interfaces.nsITransport.OPEN_BLOCKING, 0, 0);

    this.stream = transport.openInputStream(0, 0, 0);
    var cin = Components.classes["@mozilla.org/intl/converter-input-stream;1"].createInstance(CI.nsIConverterInputStream);
    cin.init(this.stream, charset, 0, 0x0000);

    this.inputStream = cin;

    var pump = Components.classes["@mozilla.org/network/input-stream-pump;1"].createInstance(CI.nsIInputStreamPump);
    pump.init(this.stream, -1, -1, 0, 0, false);
    pump.asyncRead(this, null);

    this.linesLeft = "";
    this.data = "";
    this.command = "";
    this.step = 0;
    this.readLength = false;
    this.wm = Utils.getService("@mozilla.org/appshell/window-mediator;1", "nsIWindowMediator");
    this.server = server;
}

SocketListener.prototype.onStartRequest = function(request, context)
{
}

SocketListener.prototype.onStopRequest = function(request, context, status)
{
}

SocketListener.prototype.onDataAvailable = function(request, context, inputStream, offset, count)
{
    var incoming = {}
    var read = this.inputStream.readString(count, incoming);

    var lines = incoming.value.split('\n');
    for (var j = 0; j < lines.length; j++) {
        if (this.isReadingHeaders()) {
            var head = lines[j].split(": ", 2);
            if (head[0] == "Length") {
                this.linesLeft = head[1] - 0;
                this.readLength = true;
            } else if (lines[j].length == 0 && this.readLength) {
                this.step++;
            }
        } else {
            this.data += lines[j];
            this.linesLeft -= read;

            if (this.linesLeft <= 0) {
                this.executeCommand();
                j++;  // Consume the empty line
            }
        }
    }

    if (this.linesLeft <= 0 && this.data) {
        this.executeCommand();
    }
}

SocketListener.prototype.executeCommand = function() {
    var fxbrowser, fxdocument;
    var self = this;

    var command = JSON.parse(this.data);

    var sendBack = {
        commandName : command ? command.commandName : "Unknown command",
        isError : false,
        response : "",
        elementId : command.elementId
    };

    var statusBarLabel = null;

    var respond = {
        send : function() {
            // Indicate, that we are no longer executing a command ...
            if (statusBarLabel) {
                statusBarLabel.style.color = "black";
            }

            sendBack.context = "" + sendBack.context;
            var remainder = JSON.stringify(sendBack);

            var converter = Utils.newInstance("@mozilla.org/intl/scriptableunicodeconverter", "nsIScriptableUnicodeConverter");
            converter.charset = charset;

            var data = converter.convertToByteArray(remainder, {});
            var header = "Length: " + data.length + "\n\n";
            self.outstream.write(header, header.length);
            self.outstream.flush();

            var stream = converter.convertToInputStream(remainder);
            self.outstream.writeFrom(stream, data.length);
            self.outstream.flush();
            stream.close();
        },

        setField : function(name, value) { sendBack[name] = value; },

        set commandName(name) { sendBack.commandName = name; },
        get commandName()     { return sendBack.commandName; },
        set elementId(id)     { sendBack.elementId = id; },
        get elementId()       { return sendBack.elementId; },
        set isError(error)    { sendBack.isError = error; },
        get isError()         { return sendBack.isError; },
        set response(res)     { sendBack.response = res; },
        get response()        { return sendBack.response; },
        set context(c)        { sendBack.context = c; },
        get context()         { return sendBack.context; }
    };

    respond.context = command.context;

    if (!this.driverPrototype)
        this.driverPrototype = FirefoxDriver.prototype;

    // These are used to locate a new driver, and so not having one is a fine thing to do
    if (command.commandName == "findActiveDriver" ||
        command.commandName == "switchToWindow" ||
        command.commandName == "getAllWindowHandles" ||
        command.commandName == "quit") {

        this.data = "";
        this.linesLeft = 0;
        this.step = 0;
        this.readLength = false;

        respond.commandName = command.commandName;
        this[command.commandName](respond, command.parameters);
    } else if (this.driverPrototype[command.commandName]) {
        var driver;

        var res = command.context.split(" ", 2);
        var context = new Context(res[0], res[1]);

        command.context = command.context.toString();

        var allWindows = this.wm.getEnumerator(null);
        var win;
        while (allWindows.hasMoreElements()) {
            win = allWindows.getNext();
            if (win["fxdriver"] && win.fxdriver.id == context.windowId) {
                fxbrowser = win.getBrowser();
                driver = win.fxdriver;
                break;
            }
        }

        if (!fxbrowser) {
            Utils.dumpn("Unable to find browser with id " + context.windowId + "\n");
            respond.isError = true;
            respond.response = "Unable to find browser with id " + context.windowId;
            respond.send();
            return;
        }
        if (!driver) {
            Utils.dumpn("Unable to find the driver\n");
            respond.isError = true;
            respond.response = "Unable to find the driver";
            respond.send();
            return;
        }

        driver.context = context;
        driver.context.fxbrowser = fxbrowser;

        // Determine whether or not we need to care about frames.
        var frames = fxbrowser.contentWindow.frames;
        if ("?" == driver.context.frameId) {
            if (frames && frames.length) {
                if ("FRAME" == frames[0].frameElement.tagName) {
                    driver.context.frameId = 0;
                } else {
                    driver.context.frameId = undefined;
                }
            } else {
                driver.context.frameId = undefined;
            }
        }

        var frame = fxbrowser.contentWindow;
        if (driver.context.frameId !== undefined) {
            frame = Utils.findFrame(fxbrowser, driver.context.frameId);
            if (!frame) {
                frame = fxbrowser.contentWindow;
                fxdocument = fxbrowser.contextDocument;
            } else {
                fxdocument = frame.document;
            }
        } else {
            fxdocument = fxbrowser.contentDocument;
        }

        driver.context.fxdocument = fxdocument;
        // Indicate, that we are about to execute a command ...
        statusBarLabel = win.document.getElementById("fxdriver-label");
        if (statusBarLabel) {
            statusBarLabel.style.color = "red";
        }

        var webNav = frame.QueryInterface(CI.nsIInterfaceRequestor).getInterface(CI.nsIWebNavigation);
        var loadGroup = webNav.QueryInterface(CI.nsIInterfaceRequestor).getInterface(CI.nsILoadGroup);

        var info = {
            webProgress: loadGroup,
            command: command,
            driver: driver,
            onBlank: false
        };

        this.data = "";
        this.linesLeft = 0;
        this.step = 0;
        this.readLength = 0;

        var wait = function(info) {
            if (info.webProgress.isPending()) {
                info.driver.window.setTimeout(wait, 100, info);
            } else {
                // Ugh! New windows open on "about:blank" before going to their destination
                // URL. This check attempts to tell the difference between a newly opened
                // window and someone actually wanting to do something on about:blank.
                if (info.driver.window.location == "about:blank" && !info.onBlank) {
                  info.onBlank = true;
                  info.driver.window.setTimeout(wait, 100, info);
                } else {
                  try {
                      respond.commandName = info.command.commandName;
                      info.driver[info.command.commandName](respond, info.command.parameters);
                  } catch (e) {
                      var obj = {
                        fileName : e.fileName,
                        lineNumber : e.lineNumber,
                        message : e.message,
                        name : e.name,
                        stack : e.stack
                      };
                      var message = "Exception caught by driver: " + info.command.commandName + "(" + info.command.parameters + ")\n" + e;
                      Utils.dumpn(message);
                      Utils.dump(e);
                      respond.isError = true;
                      respond.context = info.driver.context;
                      respond.response = obj;
                      respond.send();
                  }
                }
            }
        }
        driver.window.setTimeout(wait, 0, info);
    } else {
        Utils.dumpn("Unrecognised command: " + this.command + "\n");
        this.linesLeft = 0;
        this.step = 0;
        this.readLength = false;
        respond.isError = true;
        respond.response = "Unrecognised command: " + command.commandName;
        respond.context = new Context(driver.window);
        respond.send();
    }
};

SocketListener.prototype.isReadingHeaders = function() {
    return this.step == 0;
};

SocketListener.prototype.isReadingLineCount = function() {
    return this.step == 1;
};

SocketListener.prototype.switchToWindow = function(respond, windowId) {
    var lookFor = windowId[0];
    var wm = Utils.getService("@mozilla.org/appshell/window-mediator;1", "nsIWindowMediator");
    var allWindows = wm.getEnumerator(null);

    var matches = function(win, lookFor) {
      if (win.closed)
        return false;

      if (win.content && win.content.name == lookFor)
        return true;

      if (win.top && win.top.fxdriver && win.top.fxdriver.id == lookFor)
        return true;

      return false;
    }

    Utils.dumpn("Looking for: " + windowId);

    while (allWindows.hasMoreElements()) {
        var win = allWindows.getNext();
        if (matches(win, lookFor)) {
            win.focus();
            var driver = win.top.fxdriver;
            if (!driver) {
                respond.isError = true;
                respond.response = "No driver found attached to top window!";
                respond.send();
            }

            respond.response = new Context(win.fxdriver.id).toString();
            respond.send();
            return;
        }
    }

    respond.context = this.context;
    respond.isError = true;
    respond.response = "No window found";
    respond.send();
};

SocketListener.prototype.getAllWindowHandles = function(respond) {
  var wm = Utils.getService("@mozilla.org/appshell/window-mediator;1", "nsIWindowMediator");
  var allWindows = wm.getEnumerator("navigator:browser");

  var res = "";
  var index = -1;
  while (allWindows.hasMoreElements()) {
    var win = allWindows.getNext();

    if (win.top.fxdriver && !win.top.closed) {
      res += win.top.fxdriver.id + ","
    }
  }

  respond.response = res;
  respond.send();
}

SocketListener.prototype.findActiveDriver = function(respond) {
    var win = this.wm.getMostRecentWindow("navigator:browser");
    var driver = win.fxdriver;

    if (!driver) {
        respond.isError = true;
        respond.response = "No drivers associated with the window\n";
    }

    respond.context = this.context;
    respond.response = driver.id;

    respond.send();
};

SocketListener.prototype.quit = function(respond) {
  var appService = Utils.getService("@mozilla.org/toolkit/app-startup;1", "nsIAppStartup");
  appService.quit(CI.nsIAppStartup.eForceQuit);
};
<commit_msg>SimonStewart: Better handling of exceptions in the firefox driver<commit_after>/*
Copyright 2007-2009 WebDriver committers
Copyright 2007-2009 Google Inc.
Portions copyright 2007 ThoughtWorks, Inc

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

const charset = "UTF-8";
const CI = Components.interfaces;

function SocketListener(server, transport)
{
    this.outstream = transport.openOutputStream(Components.interfaces.nsITransport.OPEN_BLOCKING, 0, 0);

    this.stream = transport.openInputStream(0, 0, 0);
    var cin = Components.classes["@mozilla.org/intl/converter-input-stream;1"].createInstance(CI.nsIConverterInputStream);
    cin.init(this.stream, charset, 0, 0x0000);

    this.inputStream = cin;

    var pump = Components.classes["@mozilla.org/network/input-stream-pump;1"].createInstance(CI.nsIInputStreamPump);
    pump.init(this.stream, -1, -1, 0, 0, false);
    pump.asyncRead(this, null);

    this.linesLeft = "";
    this.data = "";
    this.command = "";
    this.step = 0;
    this.readLength = false;
    this.wm = Utils.getService("@mozilla.org/appshell/window-mediator;1", "nsIWindowMediator");
    this.server = server;
}

SocketListener.prototype.onStartRequest = function(request, context)
{
}

SocketListener.prototype.onStopRequest = function(request, context, status)
{
}

SocketListener.prototype.onDataAvailable = function(request, context, inputStream, offset, count)
{
    var incoming = {}
    var read = this.inputStream.readString(count, incoming);

    var lines = incoming.value.split('\n');
    for (var j = 0; j < lines.length; j++) {
        if (this.isReadingHeaders()) {
            var head = lines[j].split(": ", 2);
            if (head[0] == "Length") {
                this.linesLeft = head[1] - 0;
                this.readLength = true;
            } else if (lines[j].length == 0 && this.readLength) {
                this.step++;
            }
        } else {
            this.data += lines[j];
            this.linesLeft -= read;

            if (this.linesLeft <= 0) {
                this.executeCommand();
                j++;  // Consume the empty line
            }
        }
    }

    if (this.linesLeft <= 0 && this.data) {
        this.executeCommand();
    }
}

SocketListener.prototype.executeCommand = function() {
    var fxbrowser, fxdocument;
    var self = this;

    var command = JSON.parse(this.data);

    var sendBack = {
        commandName : command ? command.commandName : "Unknown command",
        isError : false,
        response : "",
        elementId : command.elementId
    };

    var statusBarLabel = null;

    var respond = {
        send : function() {
            // Indicate, that we are no longer executing a command ...
            if (statusBarLabel) {
                statusBarLabel.style.color = "black";
            }

            sendBack.context = "" + sendBack.context;
            var remainder = JSON.stringify(sendBack);

            var converter = Utils.newInstance("@mozilla.org/intl/scriptableunicodeconverter", "nsIScriptableUnicodeConverter");
            converter.charset = charset;

            var data = converter.convertToByteArray(remainder, {});
            var header = "Length: " + data.length + "\n\n";
            self.outstream.write(header, header.length);
            self.outstream.flush();

            var stream = converter.convertToInputStream(remainder);
            self.outstream.writeFrom(stream, data.length);
            self.outstream.flush();
            stream.close();
        },

        setField : function(name, value) { sendBack[name] = value; },

        set commandName(name) { sendBack.commandName = name; },
        get commandName()     { return sendBack.commandName; },
        set elementId(id)     { sendBack.elementId = id; },
        get elementId()       { return sendBack.elementId; },
        set isError(error)    { sendBack.isError = error; },
        get isError()         { return sendBack.isError; },
        set response(res)     { sendBack.response = res; },
        get response()        { return sendBack.response; },
        set context(c)        { sendBack.context = c; },
        get context()         { return sendBack.context; }
    };

    respond.context = command.context;

    if (!this.driverPrototype)
        this.driverPrototype = FirefoxDriver.prototype;

    // These are used to locate a new driver, and so not having one is a fine thing to do
    if (command.commandName == "findActiveDriver" ||
        command.commandName == "switchToWindow" ||
        command.commandName == "getAllWindowHandles" ||
        command.commandName == "quit") {

        this.data = "";
        this.linesLeft = 0;
        this.step = 0;
        this.readLength = false;

        respond.commandName = command.commandName;
        this[command.commandName](respond, command.parameters);
    } else if (this.driverPrototype[command.commandName]) {
        var driver;

        var res = command.context.split(" ", 2);
        var context = new Context(res[0], res[1]);

        command.context = command.context.toString();

        var allWindows = this.wm.getEnumerator(null);
        var win;
        while (allWindows.hasMoreElements()) {
            win = allWindows.getNext();
            if (win["fxdriver"] && win.fxdriver.id == context.windowId) {
                fxbrowser = win.getBrowser();
                driver = win.fxdriver;
                break;
            }
        }

        if (!fxbrowser) {
            Utils.dumpn("Unable to find browser with id " + context.windowId + "\n");
            respond.isError = true;
            respond.response = "Unable to find browser with id " + context.windowId;
            respond.send();
            return;
        }
        if (!driver) {
            Utils.dumpn("Unable to find the driver\n");
            respond.isError = true;
            respond.response = "Unable to find the driver";
            respond.send();
            return;
        }

        driver.context = context;
        driver.context.fxbrowser = fxbrowser;

        // Determine whether or not we need to care about frames.
        var frames = fxbrowser.contentWindow.frames;
        if ("?" == driver.context.frameId) {
            if (frames && frames.length) {
                if ("FRAME" == frames[0].frameElement.tagName) {
                    driver.context.frameId = 0;
                } else {
                    driver.context.frameId = undefined;
                }
            } else {
                driver.context.frameId = undefined;
            }
        }

        var frame = fxbrowser.contentWindow;
        if (driver.context.frameId !== undefined) {
            frame = Utils.findFrame(fxbrowser, driver.context.frameId);
            if (!frame) {
                frame = fxbrowser.contentWindow;
                fxdocument = fxbrowser.contextDocument;
            } else {
                fxdocument = frame.document;
            }
        } else {
            fxdocument = fxbrowser.contentDocument;
        }

        driver.context.fxdocument = fxdocument;
        // Indicate, that we are about to execute a command ...
        statusBarLabel = win.document.getElementById("fxdriver-label");
        if (statusBarLabel) {
            statusBarLabel.style.color = "red";
        }

        var webNav = frame.QueryInterface(CI.nsIInterfaceRequestor).getInterface(CI.nsIWebNavigation);
        var loadGroup = webNav.QueryInterface(CI.nsIInterfaceRequestor).getInterface(CI.nsILoadGroup);

        var info = {
            webProgress: loadGroup,
            command: command,
            driver: driver,
            onBlank: false
        };

        this.data = "";
        this.linesLeft = 0;
        this.step = 0;
        this.readLength = 0;

        var wait = function(info) {
            if (info.webProgress.isPending()) {
                info.driver.window.setTimeout(wait, 100, info);
            } else {
                // Ugh! New windows open on "about:blank" before going to their destination
                // URL. This check attempts to tell the difference between a newly opened
                // window and someone actually wanting to do something on about:blank.
                if (info.driver.window.location == "about:blank" && !info.onBlank) {
                  info.onBlank = true;
                  info.driver.window.setTimeout(wait, 100, info);
                } else {
                  try {
                      respond.commandName = info.command.commandName;
                      info.driver[info.command.commandName](respond, info.command.parameters);
                  } catch (e) {
                      var obj = {
                        fileName : e.fileName,
                        lineNumber : e.lineNumber,
                        message : e.message,
                        name : e.name,
                        stack : e.stack
                      };
                      var message = "Exception caught by driver: " + info.command.commandName + "(" + info.command.parameters + ")\n" + e;
                      Utils.dumpn(message);
                      Utils.dump(e);
                      respond.isError = true;
                      respond.context = info.driver.context;
                      respond.response = obj;
                      respond.send();
                  }
                }
            }
        }
        driver.window.setTimeout(wait, 0, info);
    } else {
        Utils.dumpn("Unrecognised command: " + this.command + "\n");
        this.linesLeft = 0;
        this.step = 0;
        this.readLength = false;
        respond.isError = true;
        respond.response = "Unrecognised command: " + command.commandName;
        // Context was already set.
        respond.send();
    }
};

SocketListener.prototype.isReadingHeaders = function() {
    return this.step == 0;
};

SocketListener.prototype.isReadingLineCount = function() {
    return this.step == 1;
};

SocketListener.prototype.switchToWindow = function(respond, windowId) {
    var lookFor = windowId[0];
    var wm = Utils.getService("@mozilla.org/appshell/window-mediator;1", "nsIWindowMediator");
    var allWindows = wm.getEnumerator(null);

    var matches = function(win, lookFor) {
      if (win.closed)
        return false;

      if (win.content && win.content.name == lookFor)
        return true;

      if (win.top && win.top.fxdriver && win.top.fxdriver.id == lookFor)
        return true;

      return false;
    }

    Utils.dumpn("Looking for: " + windowId);

    while (allWindows.hasMoreElements()) {
        var win = allWindows.getNext();
        if (matches(win, lookFor)) {
            win.focus();
            var driver = win.top.fxdriver;
            if (!driver) {
                respond.isError = true;
                respond.response = "No driver found attached to top window!";
                respond.send();
            }

            respond.response = new Context(win.fxdriver.id).toString();
            respond.send();
            return;
        }
    }

    respond.context = this.context;
    respond.isError = true;
    respond.response = "No window found";
    respond.send();
};

SocketListener.prototype.getAllWindowHandles = function(respond) {
  var wm = Utils.getService("@mozilla.org/appshell/window-mediator;1", "nsIWindowMediator");
  var allWindows = wm.getEnumerator("navigator:browser");

  var res = "";
  var index = -1;
  while (allWindows.hasMoreElements()) {
    var win = allWindows.getNext();

    if (win.top.fxdriver && !win.top.closed) {
      res += win.top.fxdriver.id + ","
    }
  }

  respond.response = res;
  respond.send();
}

SocketListener.prototype.findActiveDriver = function(respond) {
    var win = this.wm.getMostRecentWindow("navigator:browser");
    var driver = win.fxdriver;

    if (!driver) {
        respond.isError = true;
        respond.response = "No drivers associated with the window\n";
    }

    respond.context = this.context;
    respond.response = driver.id;

    respond.send();
};

SocketListener.prototype.quit = function(respond) {
  var appService = Utils.getService("@mozilla.org/toolkit/app-startup;1", "nsIAppStartup");
  appService.quit(CI.nsIAppStartup.eForceQuit);
};
<|endoftext|>


<commit_before>// !preview r2d3 data=list(sources = list("FileStreamSource[file]", "Other[file]"), sinks = list("FileSink[file]")), options = list(demo = TRUE), container = "div"

function StreamStats() {
  var rpmIn = [0];
  var rpmOut = [0];

  var maxIn = 100;
  var maxOut = 100;

  var maxStats = 100;

  this.add = function(rps) {
    if (maxIn < rps.in) maxIn = rps.in;
    if (maxOut < rps.out) maxOut = rps.out;

    rpmIn.unshift(rps.in);
    rpmOut.unshift(rps.out);

    rpmIn = rpmIn.slice(0, Math.min(rpmIn.length, maxStats - 1));
    rpmOut = rpmOut.slice(0, Math.min(rpmOut.length, maxStats - 1));
  };

  this.rpmIn = function() {
    return rpmIn;
  };

  this.rpmOut = function() {
    return rpmOut;
  };

  this.maxIn = function() {
    return maxIn;
  };

  this.maxOut = function() {
    return maxOut;
  };

  this.latestRpsIn = function() {
    return rpmIn[0];
  };

  this.latestRpsOut = function() {
    return rpmOut[0];
  };
}

var stats = new StreamStats();

function StreamRenderer(stats) {
  var self = this;
  var width = 0;
  var height = 0;

  var svg = div.append("svg");
  var chart = div.append("svg")
    .attr("class", "chart")
    .style("top", 0)
    .style("left", 0);

  var chartIn;
  var chartOut;
  var rowsPerSecondIn;
  var rowsPerSecondOut;

  var barWidth = 10;
  var margin = 20;
  var remotesCircle = 10;
  var remotesMargin = margin + remotesCircle;
  var remotesHeight = 80;
  var chartHeight = 0;

  this.formatRps = function(num) {
    return d3.format(",.2r")(num);
  };

  this.setSize = function(newWidth, newHeight) {
    chartHeight = newHeight - 2 * remotesHeight;

    svg.attr("width", newWidth).attr("height", newHeight);

    chart.attr("width", newWidth).attr("height", chartHeight);
    chart.style("top", remotesHeight + "px");

    width = newWidth;
    height =  newHeight;
  };

  this.update = function() {
    chart.attr("class", "chart");
    setTimeout(function() {
      chart.attr("class", "chart animate");
    }, 50);

    rowsPerSecondIn.text(self.formatRps(stats.latestRpsIn()) + " rps");
    rowsPerSecondOut.text(self.formatRps(stats.latestRpsOut()) + " rps");

    var chartHeight = height - 2 * remotesHeight;

    var dataIn = chartIn.selectAll("rect")
      .data(stats.rpmIn());

    var barsIn = dataIn
      .enter()
        .append("rect")
      .merge(dataIn)
        .attr("width", barWidth - 2)
        .attr("height", function(d, i) { return chartHeight / 2 * d / stats.maxIn();})
        .attr("x", function(d, i) { return margin + i * barWidth - barWidth; })
        .attr("y", function(d, i) { return chartHeight / 2 - chartHeight / 2 * d / stats.maxIn(); })
        .attr("class", "barIn");

    var dataOut = chartOut.selectAll("rect")
      .data(stats.rpmOut());

    var barsOut = dataOut.
      enter()
        .append("rect")
      .merge(dataOut)
        .attr("width", barWidth - 2)
        .attr("height", function(d, i) { return chartHeight / 2 * d / stats.maxOut();})
        .attr("x", function(d, i) { return margin + i * barWidth - barWidth; })
        .attr("y", function(d, i) { return chartHeight / 2; })
        .attr("class", "barOut");
  };

  this.render = function() {
    svg.selectAll("g").remove();
    svg.selectAll("text").remove();
    chart.selectAll("rect").remove();

    chartIn = chart.append("g");
    chartOut = chart.append("g");

    rowsPerSecondIn = svg.append("text");
    rowsPerSecondOut = svg.append("text");

    var sourceCircles = svg.selectAll(".source")
      .data(data.sources)
      .enter()
      .append("g")
        .attr("class", "source")
        .attr("transform", function(d, i) {
          return "translate(" + (margin + i * 24) + ", " + remotesMargin + ")";
        })
        .append("circle");

    sourceCircles.attr("cx", "0").attr("cy", "0").attr("r", "10")
      .attr("class", function (d, i) {
        return (i == data.sources.length - 1) ? "source selected" : "source";
      })
      .attr("stroke-width", "2")
      .on("mouseover", function (d, i) {
        sourceCircles.attr("class", "source");
        d3.select(this).attr("class", "source selected");
        sourceText.text(d);
      });

    var sourceText = svg
      .append("text")
        .attr("y", 35).attr("x", margin + data.sources.length * 24)
        .attr("class", "label")
        .text(function(d) { return data.sources[data.sources.length - 1]; });

    rowsPerSecondIn
      .attr("y", 60).attr("x", margin + data.sources.length * 24)
      .attr("class", "rps")
      .text(self.formatRps(stats.latestRpsIn()) + " rps");

    rowsPerSecondIn.append("title").text("rows per second");

    var sinkCircles = svg.selectAll(".sink")
      .data(data.sinks)
      .enter()
      .append("g")
        .attr("class", "sink")
        .attr("transform", function(d, i) {
          return "translate(" + (margin + i * 24) + ","  + (height - remotesMargin) + ")";
        })
        .append("circle");

    sinkCircles.attr("cx", "0").attr("cy", "0").attr("r", "10")
      .attr("class", function (d, i) {
        return (i == data.sinks.length - 1) ? "sink selected" : "sink";
      })
      .attr("stroke-width", "2")
      .on("mouseover", function (d, i) {
        sinkCircles.attr("class", "sink");
        d3.select(this).attr("class", "sink selected");
        sinkText.text(d);
      });

    var sinkText = svg
      .append("text")
        .attr("y", height - 25).attr("x", margin + data.sinks.length * 24)
        .attr("class", "label sinkText")
        .text(function(d) { return data.sinks[data.sinks.length - 1]; });

    rowsPerSecondOut
      .attr("y", height - 50).attr("x", margin + data.sinks.length * 24)
      .attr("class", "rps")
      .text(self.formatRps(stats.latestRpsOut()) + " rps");

    rowsPerSecondOut.append("title").text("rows per second");

    this.update();
  };
}

var renderer = new StreamRenderer(stats);

r2d3.onRender(function(data, svg, width, height, options) {
  renderer.setSize(width, height);
  renderer.render();
});

r2d3.onResize(function(width, height) {
  renderer.setSize(width, height);
  renderer.render();
});

function debug(msg) {
  if (options !== null && "debug" in options) {
    console.log(msg);
  }
}

if (options !== null && "demo" in options) {
  setInterval(function() {
    var data = {
      rps: {
        in: Math.floor(Math.random() * 100),
        out: Math.floor(Math.random() * 100)
      }
    };

    debug(JSON.stringify(data));
    stats.add(data.rps);
    renderer.update();
  }, 1000);
}

if (typeof(Shiny) !== "undefined") {
  Shiny.addCustomMessageHandler("sparklyr_stream_view", function(data) {
      debug(JSON.stringify(data));
      stats.add(data.rps);
      renderer.update();
    }
  );
}
<commit_msg>handle small height in stream chart<commit_after>// !preview r2d3 data=list(sources = list("FileStreamSource[file]", "Other[file]"), sinks = list("FileSink[file]")), options = list(demo = TRUE), container = "div"

function StreamStats() {
  var rpmIn = [0];
  var rpmOut = [0];

  var maxIn = 100;
  var maxOut = 100;

  var maxStats = 100;

  this.add = function(rps) {
    if (maxIn < rps.in) maxIn = rps.in;
    if (maxOut < rps.out) maxOut = rps.out;

    rpmIn.unshift(rps.in);
    rpmOut.unshift(rps.out);

    rpmIn = rpmIn.slice(0, Math.min(rpmIn.length, maxStats - 1));
    rpmOut = rpmOut.slice(0, Math.min(rpmOut.length, maxStats - 1));
  };

  this.rpmIn = function() {
    return rpmIn;
  };

  this.rpmOut = function() {
    return rpmOut;
  };

  this.maxIn = function() {
    return maxIn;
  };

  this.maxOut = function() {
    return maxOut;
  };

  this.latestRpsIn = function() {
    return rpmIn[0];
  };

  this.latestRpsOut = function() {
    return rpmOut[0];
  };
}

var stats = new StreamStats();

function StreamRenderer(stats) {
  var self = this;
  var width = 0;
  var height = 0;

  var svg = div.append("svg");
  var chart = div.append("svg")
    .attr("class", "chart")
    .style("top", 0)
    .style("left", 0);

  var chartIn;
  var chartOut;
  var rowsPerSecondIn;
  var rowsPerSecondOut;

  var barWidth = 10;
  var margin = 15;
  var remotesCircle = 10;
  var remotesMargin = margin;
  var remotesHeight = 0;
  var chartHeight = 0;

  this.formatRps = function(num) {
    return d3.format(",.2r")(num);
  };

  this.setSize = function(newWidth, newHeight) {
    remotesHeight = Math.min(50, newHeight / 3);
    chartHeight = newHeight - 2 * remotesHeight;

    svg.attr("width", newWidth).attr("height", newHeight);

    chart.attr("width", newWidth).attr("height", chartHeight);
    chart.style("top", remotesHeight + "px");

    chart.style("display", newHeight < 120 ? "none" : "block");

    width = newWidth;
    height =  newHeight;
  };

  this.update = function() {
    chart.attr("class", "chart");
    setTimeout(function() {
      chart.attr("class", "chart animate");
    }, 50);

    rowsPerSecondIn.text(self.formatRps(stats.latestRpsIn()) + " rps");
    rowsPerSecondOut.text(self.formatRps(stats.latestRpsOut()) + " rps");

    rowsPerSecondIn.style("display", height < 60 ? "none" : "block");
    rowsPerSecondOut.style("display", height < 60 ? "none" : "block");

    var chartHeight = height - 2 * remotesHeight;

    var dataIn = chartIn.selectAll("rect")
      .data(stats.rpmIn());

    var barsIn = dataIn
      .enter()
        .append("rect")
      .merge(dataIn)
        .attr("width", barWidth - 2)
        .attr("height", function(d, i) { return chartHeight / 2 * d / stats.maxIn();})
        .attr("x", function(d, i) { return margin + i * barWidth - barWidth; })
        .attr("y", function(d, i) { return chartHeight / 2 - chartHeight / 2 * d / stats.maxIn(); })
        .attr("class", "barIn");

    var dataOut = chartOut.selectAll("rect")
      .data(stats.rpmOut());

    var barsOut = dataOut.
      enter()
        .append("rect")
      .merge(dataOut)
        .attr("width", barWidth - 2)
        .attr("height", function(d, i) { return chartHeight / 2 * d / stats.maxOut();})
        .attr("x", function(d, i) { return margin + i * barWidth - barWidth; })
        .attr("y", function(d, i) { return chartHeight / 2; })
        .attr("class", "barOut");
  };

  this.render = function() {
    svg.selectAll("g").remove();
    svg.selectAll("text").remove();
    chart.selectAll("rect").remove();

    chartIn = chart.append("g");
    chartOut = chart.append("g");

    rpsTextSize = Math.min(10 + height / 40, 20);

    rowsPerSecondIn = svg.append("text");
    rowsPerSecondIn.style("font-size", rpsTextSize + "px");

    rowsPerSecondOut = svg.append("text");
    rowsPerSecondOut.style("font-size", rpsTextSize + "px");

    var sourceCircles = svg.selectAll(".source")
      .data(data.sources)
      .enter()
      .append("g")
        .attr("class", "source")
        .attr("transform", function(d, i) {
          return "translate(" + (margin + i * 24) + ", " + remotesMargin + ")";
        })
        .append("circle");

    sourceCircles.attr("cx", "0").attr("cy", "0").attr("r", "10")
      .attr("class", function (d, i) {
        return (i == data.sources.length - 1) ? "source selected" : "source";
      })
      .attr("stroke-width", "2")
      .on("mouseover", function (d, i) {
        sourceCircles.attr("class", "source");
        d3.select(this).attr("class", "source selected");
        sourceText.text(d);
      });

    var sourceText = svg
      .append("text")
        .attr("y", margin + 3).attr("x", margin + data.sources.length * 24)
        .attr("class", "label")
        .text(function(d) { return data.sources[data.sources.length - 1]; });

    rowsPerSecondIn
      .attr("y", margin + rpsTextSize + 5).attr("x", margin + data.sources.length * 24)
      .attr("class", "rps")
      .text(self.formatRps(stats.latestRpsIn()) + " rps");

    rowsPerSecondIn.append("title").text("rows per second");

    var sinkCircles = svg.selectAll(".sink")
      .data(data.sinks)
      .enter()
      .append("g")
        .attr("class", "sink")
        .attr("transform", function(d, i) {
          return "translate(" + (margin + i * 24) + ","  + (height - remotesMargin) + ")";
        })
        .append("circle");

    sinkCircles.attr("cx", "0").attr("cy", "0").attr("r", "10")
      .attr("class", function (d, i) {
        return (i == data.sinks.length - 1) ? "sink selected" : "sink";
      })
      .attr("stroke-width", "2")
      .on("mouseover", function (d, i) {
        sinkCircles.attr("class", "sink");
        d3.select(this).attr("class", "sink selected");
        sinkText.text(d);
      });

    var sinkText = svg
      .append("text")
        .attr("y", height - margin + 3).attr("x", margin + data.sinks.length * 24)
        .attr("class", "label sinkText")
        .text(function(d) { return data.sinks[data.sinks.length - 1]; });

    rowsPerSecondOut
      .attr("y", height - margin - 15).attr("x", margin + data.sinks.length * 24)
      .attr("class", "rps")
      .text(self.formatRps(stats.latestRpsOut()) + " rps");

    rowsPerSecondOut.append("title").text("rows per second");

    this.update();
  };
}

var renderer = new StreamRenderer(stats);

r2d3.onRender(function(data, svg, width, height, options) {
  renderer.setSize(width, height);
  renderer.render();
});

r2d3.onResize(function(width, height) {
  renderer.setSize(width, height);
  renderer.render();
});

function debug(msg) {
  if (options !== null && "debug" in options) {
    console.log(msg);
  }
}

if (options !== null && "demo" in options) {
  setInterval(function() {
    var data = {
      rps: {
        in: Math.floor(Math.random() * 100),
        out: Math.floor(Math.random() * 100)
      }
    };

    debug(JSON.stringify(data));
    stats.add(data.rps);
    renderer.update();
  }, 1000);
}

if (typeof(Shiny) !== "undefined") {
  Shiny.addCustomMessageHandler("sparklyr_stream_view", function(data) {
      debug(JSON.stringify(data));
      stats.add(data.rps);
      renderer.update();
    }
  );
}
<|endoftext|>


<commit_before>var pi = Math.PI,
    tau = 2 * pi,
    epsilon = 1e-6;

function Path() {
  this._x0 = this._y0 = // start of current subpath
  this._x1 = this._y1 = 0; // end of current subpath
  this._ = [];
}

Path.prototype = {
  moveTo: function(x, y) {
    this._.push("M", this._x0 = this._x1 = +x, ",", this._y0 = this._y1 = +y);
  },
  closePath: function() {
    this._x1 = this._x0, this._y1 = this._y0;
    this._.push("Z");
  },
  lineTo: function(x, y) {
    this._.push("L", this._x1 = +x, ",", this._y1 = +y);
  },
  quadraticCurveTo: function(x1, y1, x, y) {
    this._.push("Q", +x1, ",", +y1, ",", this._x1 = +x, ",", this._y1 = +y);
  },
  bezierCurveTo: function(x1, y1, x2, y2, x, y) {
    this._.push("C", +x1, ",", +y1, ",", +x2, ",", +y2, ",", this._x1 = +x, ",", this._y1 = +y);
  },
  arcTo: function(x1, y1, x2, y2, r) {
    x1 = +x1, y1 = +y1, x2 = +x2, y2 = +y2, r = +r;
    var x0 = this._x1,
        y0 = this._y1,
        x21 = x2 - x1,
        y21 = y2 - y1,
        x01 = x0 - x1,
        y01 = y0 - y1,
        x20 = x2 - x0,
        y20 = y2 - y0,
        l21_2 = x21 * x21 + y21 * y21,
        l01_2 = x01 * x01 + y01 * y01,
        l20_2 = x20 * x20 + y20 * y20,
        l21 = Math.sqrt(l21_2),
        l01 = Math.sqrt(l01_2),
        l = r * Math.tan((Math.PI - Math.acos((l21_2 + l01_2 - l20_2) / (2 * l21 * l01))) / 2);
    this._.push(
      "L", x1 + l / l01 * x01, ",", y1 + l / l01 * y01,
      "A", r, ",", r, ",0,0,", +(y01 * x20 > x01 * y20),",", x1 + l / l21 * x21, ",", y1 + l / l21 * y21,
      "L", this._x1 = +x2, ",", this._y1 = +y2
    );
  },
  arc: function(x, y, r, a0, a1) {
    x = +x, y = +y, r = +r;
    var dx = r * Math.cos(a0),
        dy = r * Math.sin(a0),
        x0 = x + dx,
        y0 = y + dy,
        da = Math.abs(a1 - a0);
    this._.push(this._.length ? "L" : "M", x0, ",", y0);
    if (da >= tau - epsilon) {
      this._.push("A", r, ",", r, ",0,1,1,", x - dx, ",", y - dy, "A", r, ",", r, ",0,1,1,", this._x1 = x0, ",", this._y1 = y0);
    } else {
      this._.push("A", r, ",", r, ",0,", +(da >= pi), ",1,", this._x1 = x + r * Math.cos(a1), ",", this._y1 = y + r * Math.sin(a1));
    }
  },
  rect: function(x, y, w, h) {
    this._.push("M", this._x0 = this._x1 = +x, ",", this._y0 = this._y1 = +y, "h", +w, "v", +h, "h", -w, "Z");
  },
  toString: function() {
    return this._.join("");
  }
};

export default function() {
  return new Path;
};
<commit_msg>Add missing space.<commit_after>var pi = Math.PI,
    tau = 2 * pi,
    epsilon = 1e-6;

function Path() {
  this._x0 = this._y0 = // start of current subpath
  this._x1 = this._y1 = 0; // end of current subpath
  this._ = [];
}

Path.prototype = {
  moveTo: function(x, y) {
    this._.push("M", this._x0 = this._x1 = +x, ",", this._y0 = this._y1 = +y);
  },
  closePath: function() {
    this._x1 = this._x0, this._y1 = this._y0;
    this._.push("Z");
  },
  lineTo: function(x, y) {
    this._.push("L", this._x1 = +x, ",", this._y1 = +y);
  },
  quadraticCurveTo: function(x1, y1, x, y) {
    this._.push("Q", +x1, ",", +y1, ",", this._x1 = +x, ",", this._y1 = +y);
  },
  bezierCurveTo: function(x1, y1, x2, y2, x, y) {
    this._.push("C", +x1, ",", +y1, ",", +x2, ",", +y2, ",", this._x1 = +x, ",", this._y1 = +y);
  },
  arcTo: function(x1, y1, x2, y2, r) {
    x1 = +x1, y1 = +y1, x2 = +x2, y2 = +y2, r = +r;
    var x0 = this._x1,
        y0 = this._y1,
        x21 = x2 - x1,
        y21 = y2 - y1,
        x01 = x0 - x1,
        y01 = y0 - y1,
        x20 = x2 - x0,
        y20 = y2 - y0,
        l21_2 = x21 * x21 + y21 * y21,
        l01_2 = x01 * x01 + y01 * y01,
        l20_2 = x20 * x20 + y20 * y20,
        l21 = Math.sqrt(l21_2),
        l01 = Math.sqrt(l01_2),
        l = r * Math.tan((Math.PI - Math.acos((l21_2 + l01_2 - l20_2) / (2 * l21 * l01))) / 2);
    this._.push(
      "L", x1 + l / l01 * x01, ",", y1 + l / l01 * y01,
      "A", r, ",", r, ",0,0,", +(y01 * x20 > x01 * y20), ",", x1 + l / l21 * x21, ",", y1 + l / l21 * y21,
      "L", this._x1 = +x2, ",", this._y1 = +y2
    );
  },
  arc: function(x, y, r, a0, a1) {
    x = +x, y = +y, r = +r;
    var dx = r * Math.cos(a0),
        dy = r * Math.sin(a0),
        x0 = x + dx,
        y0 = y + dy,
        da = Math.abs(a1 - a0);
    this._.push(this._.length ? "L" : "M", x0, ",", y0);
    if (da >= tau - epsilon) {
      this._.push("A", r, ",", r, ",0,1,1,", x - dx, ",", y - dy, "A", r, ",", r, ",0,1,1,", this._x1 = x0, ",", this._y1 = y0);
    } else {
      this._.push("A", r, ",", r, ",0,", +(da >= pi), ",1,", this._x1 = x + r * Math.cos(a1), ",", this._y1 = y + r * Math.sin(a1));
    }
  },
  rect: function(x, y, w, h) {
    this._.push("M", this._x0 = this._x1 = +x, ",", this._y0 = this._y1 = +y, "h", +w, "v", +h, "h", -w, "Z");
  },
  toString: function() {
    return this._.join("");
  }
};

export default function() {
  return new Path;
};
<|endoftext|>


<commit_before>// Copyright (c) 2017, Frappe Technologies and contributors
// For license information, please see license.txt

frappe.ui.form.on('Print Style', {
	refresh: function(frm) {
		/* update in local */
		if (!frm.is_new() && !locals[':Print Style'][frm.doc.name]) {
			locals[':Print Style'][frm.doc.name] = frm.doc;
		}

		frm.add_custom_button(__('Print Settings'), () => {
			frappe.set_route('Form', 'Print Settings');
		})
	}
});
<commit_msg>[minor] print_style.js<commit_after>// Copyright (c) 2017, Frappe Technologies and contributors
// For license information, please see license.txt

frappe.ui.form.on('Print Style', {
	refresh: function(frm) {
		frm.add_custom_button(__('Print Settings'), () => {
			frappe.set_route('Form', 'Print Settings');
		})
	}
});
<|endoftext|>


<commit_before>// Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and Contributors
// MIT License. See license.txt

frappe.provide('frappe.energy_points');

Object.assign(frappe.energy_points, {
	get_points(points) {
		return `= 0 ? '#45A163': '#e42121'}">
			${points > 0 ? '+': ''}${points}
		`;
	},
	log_message(log) {
		const doc_link = frappe.utils.get_form_link(log.reference_doctype, log.reference_name, true);
		const owner_name = frappe.user.full_name(log.owner).bold();
		if (log.type === 'Appreciation') {
			return __('{0} appreciated on {1}', [owner_name, doc_link]);
		}
		if (log.type === 'Criticism') {
			return __('{0} criticized on {1}', [owner_name, doc_link]);
		}
		return __('via automatic rule {0} for {1}', [log.rule.bold(), doc_link]);
	},
	format_log(log, with_timestamp=true) {
		let formatted_log = `
			${this.get_points(log.points)} ${this.log_message(log)}
			${ with_timestamp ? ' - ' + frappe.datetime.comment_when(log.creation):''}
		`;
		return formatted_log;
	},
});<commit_msg>fix: Set with_timestamp=false by default<commit_after>// Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and Contributors
// MIT License. See license.txt

frappe.provide('frappe.energy_points');

Object.assign(frappe.energy_points, {
	get_points(points) {
		return `= 0 ? '#45A163': '#e42121'}">
			${points > 0 ? '+': ''}${points}
		`;
	},
	log_message(log) {
		const doc_link = frappe.utils.get_form_link(log.reference_doctype, log.reference_name, true);
		const owner_name = frappe.user.full_name(log.owner).bold();
		if (log.type === 'Appreciation') {
			return __('{0} appreciated on {1}', [owner_name, doc_link]);
		}
		if (log.type === 'Criticism') {
			return __('{0} criticized on {1}', [owner_name, doc_link]);
		}
		return __('via automatic rule {0} for {1}', [log.rule.bold(), doc_link]);
	},
	format_log(log, with_timestamp=false) {
		let formatted_log = `
			${this.get_points(log.points)} ${this.log_message(log)}
			${ with_timestamp ? ' - ' + frappe.datetime.comment_when(log.creation):''}
		`;
		return formatted_log;
	},
});<|endoftext|>


<commit_before>(function(name, context, definition){
  if (typeof module !== "undefined" && module.exports) {
    module.exports = definition();
  } else if (typeof define === "function" && define.amd) {
    define(definition);
  } else {
    context[name] = definition();

    if (typeof context['$'] === 'undefined') {
      context['$'] = definition();
    }
  }
})('seht', this, function () {
  var
  win = window,
  doc = win.document,
  arrayProto = Array.prototype,
  Regex = {
    HTML: /^\s*<([^\s>]+)/,
    ID: /^\#[\w\-]+$/,
    Ready: /(complete|interactive|loaded)/
  },
  Classes,
  Events,
  Seht;

  /**
   * Functions.
   */

  /**
   * Call a handler for each item in an array or object.
   *
   * @param {Array|Object} obj - An array or object
   * @param {Function} handler - Function to run for each item
   * @param {*} scope - Variable to access as 'this' in handler-function
   * @return {Array|Object} The iterated array or object
   */
  function each(obj, handler, scope) {
    var
    property;

    if (isFinite(obj.length)) {
      // The object looks like an array

      arrayProto.forEach.call(obj, function (item, index) {
        handler.call(scope || item, item, index, obj);
      });
    } else {
      // The object is presumed to be a regular object

      for (property in obj) {
        if (obj.hasOwnProperty(property)) {
          handler.call(scope || obj[property], obj[property], property, obj);
        }
      }
    }

    // Return the object for future use
    return obj;
  }

  /**
   * Find elements based on variables.
   */
  function find(selector, context) {
    if (selector === null || typeof selector === 'undefined') {
      // Nothing to search for, so let's return an empty array

      return [];
    } else if (selector.nodeType || selector === selector.window) {
      // The selector is an element or 'window'

      return [selector];
    } else if (typeof selector === 'object' && isFinite(selector.length)) {
      // The selector is an array

      return selector;
    } else if (typeof selector === 'string') {
      // The selector is a search query, so let's 'query' it

      return query(selector, context);
    }

    // Nothing to search for, so let's return an empty array
    return [];
  }

  /**
   * Create HTML elements from a string.
   */
  function htmlify(string) {
    var
    html;

    if (typeof string !== 'string') {
      return string;
    }

    // Create a new HTML document,
    html = doc.implementation.createHTMLDocument();
    // and set its content to the value of the supplied string
    html.body.innerHTML = string;

    // Return the bodys child elements
    return html.body.children;
  }

  /**
   * Search for elements or create HTML elements.
   */
  function query(selector, context) {
    if (Regex.ID.test(selector)) {
      // The string matches the regex for an ID-search

      return [context.getElementById(selector.slice(1))]
    } else if (Regex.HTML.test(selector)) {
      // The string matches the regex for HTML, so let's 'htmlify' it

      return htmlify(selector);
    }

    // Default …
    return context.querySelectorAll(selector);
  }

  /**
   * Trim and clean a string.
   */
  function trim(string) {
    return string.trim().replace(/\s+/g, ' ');
  }

  /**
   * Objects.
   */

  /**
   * Object for handling element classes.
   */
  Classes = {

    /**
     * Add class names to an element.
     *
     * @this {Array} Array of class names
     * @param {Element} element - Element to modify
     */
    add: function (element) {
      each(this, function (name) {
        if (Classes.contains(element, name) === false) {
          Classes.addClass(element, name);
        }
      });

      element.className = trim(element.className);
    },

    /**
     * Add a single class name to an element.
     */
    addClass: function (element, name) {
      element.className += ' ' + name;
    },

    /**
     * Verify if an element has a specific class name.
     */
    contains: function (element, string) {
      return Classes.regExp(string).test(element.className);
    },

    /**
     * Create the regular expression for a class name.
     */
    regExp: function (string) {
      return new RegExp('(^|\\s+)' + string + '(\\s+|$)');
    },

    /**
     * Remove class names from an element.
     *
     * @this {Array} Array of class names
     * @param {Element} element - Element to modify
     */
    remove: function (element, names) {
      each(this, function (name) {
        if (Classes.contains(element, name)) {
          Classes.removeClass(element, name);
        }
      });

      element.className = trim(element.className);
    },

    /**
     * Remove a single class name from an element.
     */
    removeClass: function (element, name) {
      element.className = element.className.replace(Classes.regExp(name), '');
    },

    /**
     * Toggle classes for an element.
     *
     * @this {Array} Array of class names
     * @param {Element} element - Element to modify
     */
    toggle: function (element) {
      each(this, function (name) {
        if (Classes.contains(element, name)) {
          Classes.removeClass(element, name);
        } else {
          Classes.addClass(element, name);
        }
      });

      element.className = trim(element.className);
    }
  };

  /**
   * Object for handling events.
   */
  Events = {

    /**
     * Event handler for when the document is ready.
     *
     * @param {Function} handler - Handler to call when ready
     */
    ready: function (handler) {
      if (Regex.Ready.test(doc.readyState)) {
        // Old-school ready-event

        handler.call(doc);
      } else {
        // Modern ready-event

        doc.addEventListener('DOMContentLoaded', handler);
      }
    }
  };

  /**
   * Seht.
   */

  /**
   * Function to call Sehts constructor.
   *
   * @param {*=} selector - Query to search for
   * @param {Element=} context - Item in which we look for 'selector'
   * @return {Seht} An old or new Seht object
   */
  function seht(selector, context) {
    if (selector instanceof Seht) {
      // The selector is a Seht object, so let's return it as-is

      return selector;
    }

    // Call the constructor for Seht
    return new Seht(selector || null, context || doc);
  }

  /**
   * Initiates a Seht object.
   *
   * @constructor
   * @param {*} selector - Query to search for
   * @param {Element} context - Item in which we search for 'selector'
   */
  Seht = function (selector, context) {
    var
    elements;

    // Find elements
    elements = find(selector, context);

    // Set length for the current object
    this.length = elements.length;

    // Add each element to the current object
    each(elements, function (element, index) {
      this[index] = element;
    }, this);
  };

  /**
   * Prototypal methods or properties for Seht.
   */
  Seht.prototype = {

    /**
     * Default length for a Seht object.
     */
    length: 0,

    /**
     * Add class names to elements.
     *
     * @param {...String} Class names
     * @return {Seht} The original object
     */
    addClass: function() {
      return each(this, Classes.add, arguments);
    },

    /**
     * Insert HTML after elements.
     *
     * @param {String} string - HTML to insert
     * @return {Seht} The original object
     */
    after: function (string) {
      var
      html,
      next;

      // Turn the string into actual HTML
      html = htmlify(string);

      return each(this, function (element) {
        // Define where to insert the HTML
        next = element.nextSibling;

        each(html, function (item) {
          element.parentNode.insertBefore(item.cloneNode(true), next);
        });
      });
    },

    /**
     * Append HTML to elements.
     *
     * @param {String} string - HTML to append
     * @return {Seht} The original object
     */
    append: function (string) {
      var
      html;

      // Turn the string into actual HTML
      html = htmlify(string);

      return each(this, function (element) {
        each(html, function (item) {
          element.appendChild(item.cloneNode(true));
        })
      });
    },

    /**
     * Append a Seht object to a selector.
     *
     * @param {*} selector - Query to search for
     * @return {Seht} The new object
     */
    appendTo: function (selector) {
      return seht(selector).append(this);
    },

    /**
     * Insert HTML before elements.
     *
     * @param {String} string - HTML to insert
     * @return {Seht} The original object
     */
    before: function (string) {
      var
      html;

      // Turn the string into actual HTML
      html = htmlify(string);

      return each(this, function (element) {
        each(html, function (item) {
          element.parentNode.insertBefore(item.cloneNode(true), element);
        });
      });
    },

    /**
     * Call a handler for each element in the Seht object.
     *
     * @param {Function} handler
     * @return {Seht} The original object
     */
    each: function (handler) {
      return each(this, handler);
    },

    /**
     * Create a Seht object containing only
     * the element at a specific position.
     *
     * @param {Number} index - Index for element
     * @return {Seht|Null} The new object or null
     */
    eq: function (index) {
      return seht(index >= 0 && index < this.length ? this[index] : null);
    },

    /**
     * Create a Seht object containing only the first element.
     *
     * @return {Seht|Null} The new object or null
     */
    first: function () {
      return this.eq(0);
    },

    /**
     * Get an actual element in the Seht object
     * from a specific position.
     */
    get: function (index) {
      if (index >= 0 && index < this.length) {
        return this[index];
      }

      return null;
    },

    /**
     * Verify if an element has a specific class name.
     *
     * @param {String} string - Class name to verify
     * @return {Boolean}
     */
    hasClass: function (string) {
      return Classes.contains(this[0], string);
    },

    /**
     * Get or set the HTML for elements.
     *
     * @param {String=} string - new HTML for elements
     * @return {Seht} The original object
     */
    html: function (string) {
      if (typeof string !== 'undefined') {
        if (string instanceof Seht) {
          // The supplied string is actually Seht
          // object, so let's flatten it.

          string = this.toString();
        }

        return each(this, function (element) {
          element.innerHTML = string;
        });
      } else if (this.length > 0) {
        return this[0].innerHTML;
      }

      return null;
    },

    /**
     * Create a Seht object containing only the last element.
     *
     * @return {Seht|Null} The new object or null
     */
    last: function () {
      return this.eq(this.length - 1);
    },

    /**
     * Prepend HTML to elements.
     *
     * @param {String} string - HTML to prepend
     * @return {Seht} The original object
     */
    prepend: function (string) {
      var
      first,
      html;

      // Turn the string into actual HTML
      html = htmlify(string);

      return each(this, function (element) {
        // Define where to insert the HTML
        first = element.firstChild;

        each(html, function (item) {
          element.insertBefore(item.cloneNode(true), first);
        });
      });
    },

    /**
     * Prepend a Seht object to a selector.
     *
     * @param {*} selector - Query to search for
     * @return {Seht} The new object
     */
    prependTo: function (selector) {
      return seht(selector).prepend(this);
    },

    /**
     * Remove class names from elements.
     *
     * @param {...String} Class names
     * @return {Seht} The original object
     */
    removeClass: function () {
      return each(this, Classes.remove, arguments);
    },

    /**
     * Get or set the text for elements.
     *
     * @param {String=} string - New text for elements
     * @return {Seht} The original object
     */
    text: function (string) {
      if (typeof string !== 'undefined') {
        return each(this, function (element) {
          element.textContent = string;
        });
      } else if (this.length > 0) {
        return this[0].textContent;
      }

      return null;
    },

    /**
     * Toggle class names for elements.
     *
     * @param {...String} Class names
     * @return {Seht} The original object
     */
    toggleClass: function () {
      return each(this, Classes.toggle, arguments);
    },

    /**
     * Convert the Seht object to a regular array.
     *
     * @return {Array} Array of elements
     */
    toArray: function () {
      return arrayProto.slice.call(this);
    },

    /**
     * Flatten the Seht object and combine
     * all elements' HTML.
     *
     * @return {String} The combined HTML
     */
    toString: function () {
      var
      string;

      string = '';

      each(this, function (element) {
        string += element.innerHTML;
      });

      return string;
    },

    /**
     * Set the value for an element.
     *
     * @param {String=} value - New value for elements
     * @return {Seht} The original object
     */
    value: function (value) {
      if (typeof value !== 'undefined') {
        return each(this, function (element) {
          element.value = value;
        });
      }

      return this[0].value;
    }
  };

  seht.each = each;
  seht.ready = Events.ready;

  return seht;
});<commit_msg>attr and data-methods<commit_after>(function(name, context, definition){
  if (typeof module !== 'undefined' && module.exports) {
    module.exports = definition();
  } else if (typeof define === 'function' && define.amd) {
    define(definition);
  } else {
    context[name] = definition();

    if (typeof context['$'] === 'undefined') {
      context['$'] = definition();
    }
  }
})('seht', this, function () {
  var
  win = window,
  doc = win.document,
  arrayProto = Array.prototype,
  undefinedString = 'undefined',
  Regex = {
    HTML: /^\s*<([^\s>]+)/,
    ID: /^\#[\w\-]+$/,
    Ready: /(complete|interactive|loaded)/
  },
  Classes,
  Events,
  Seht;

  /**
   * Functions.
   */

  /**
   * Call a handler for each item in an array or object.
   *
   * @param {Array|Object} obj - An array or object
   * @param {Function} handler - Function to run for each item
   * @param {*} scope - Variable to access as 'this' in handler-function
   * @return {Array|Object} The iterated array or object
   */
  function each(obj, handler, scope) {
    var
    property;

    if (isFinite(obj.length)) {
      // The object looks like an array

      arrayProto.forEach.call(obj, function (item, index) {
        handler.call(scope || item, item, index, obj);
      });
    } else {
      // The object is presumed to be a regular object

      for (property in obj) {
        if (obj.hasOwnProperty(property)) {
          handler.call(scope || obj[property], obj[property], property, obj);
        }
      }
    }

    // Return the object for future use
    return obj;
  }

  /**
   * Find elements based on variables.
   */
  function find(selector, context) {
    if (selector === null || typeof selector === undefinedString) {
      // Nothing to search for, so let's return an empty array

      return [];
    } else if (selector.nodeType || selector === selector.window) {
      // The selector is an element or 'window'

      return [selector];
    } else if (typeof selector === 'object' && isFinite(selector.length)) {
      // The selector is an array

      return selector;
    } else if (typeof selector === 'string') {
      // The selector is a search query, so let's 'query' it

      return query(selector, context);
    }

    // Nothing to search for, so let's return an empty array
    return [];
  }

  /**
   * Create HTML elements from a string.
   */
  function htmlify(string) {
    var
    html;

    if (typeof string !== 'string') {
      return string;
    }

    // Create a new HTML document,
    html = doc.implementation.createHTMLDocument();
    // and set its content to the value of the supplied string
    html.body.innerHTML = string;

    // Return the bodys child elements
    return html.body.children;
  }

  /**
   * Search for elements or create HTML elements.
   */
  function query(selector, context) {
    if (Regex.ID.test(selector)) {
      // The string matches the regex for an ID-search

      return [context.getElementById(selector.slice(1))]
    } else if (Regex.HTML.test(selector)) {
      // The string matches the regex for HTML, so let's 'htmlify' it

      return htmlify(selector);
    }

    // Default …
    return context.querySelectorAll(selector);
  }

  /**
   * Trim and clean a string.
   */
  function trim(string) {
    return string.trim().replace(/\s+/g, ' ');
  }

  /**
   * Objects.
   */

  /**
   * Object for handling element classes.
   */
  Classes = {

    /**
     * Add class names to an element.
     *
     * @this {Array} Array of class names
     * @param {Element} element - Element to modify
     */
    add: function (element) {
      each(this, function (name) {
        if (Classes.contains(element, name) === false) {
          Classes.addClass(element, name);
        }
      });

      element.className = trim(element.className);
    },

    /**
     * Add a single class name to an element.
     */
    addClass: function (element, name) {
      element.className += ' ' + name;
    },

    /**
     * Verify if an element has a specific class name.
     */
    contains: function (element, string) {
      return Classes.regExp(string).test(element.className);
    },

    /**
     * Create the regular expression for a class name.
     */
    regExp: function (string) {
      return new RegExp('(^|\\s+)' + string + '(\\s+|$)');
    },

    /**
     * Remove class names from an element.
     *
     * @this {Array} Array of class names
     * @param {Element} element - Element to modify
     */
    remove: function (element, names) {
      each(this, function (name) {
        if (Classes.contains(element, name)) {
          Classes.removeClass(element, name);
        }
      });

      element.className = trim(element.className);
    },

    /**
     * Remove a single class name from an element.
     */
    removeClass: function (element, name) {
      element.className = element.className.replace(Classes.regExp(name), '');
    },

    /**
     * Toggle classes for an element.
     *
     * @this {Array} Array of class names
     * @param {Element} element - Element to modify
     */
    toggle: function (element) {
      each(this, function (name) {
        if (Classes.contains(element, name)) {
          Classes.removeClass(element, name);
        } else {
          Classes.addClass(element, name);
        }
      });

      element.className = trim(element.className);
    }
  };

  /**
   * Object for handling events.
   */
  Events = {

    /**
     * Event handler for when the document is ready.
     *
     * @param {Function} handler - Handler to call when ready
     */
    ready: function (handler) {
      if (Regex.Ready.test(doc.readyState)) {
        // Old-school ready-event

        handler.call(doc);
      } else {
        // Modern ready-event

        doc.addEventListener('DOMContentLoaded', handler);
      }
    }
  };

  /**
   * Seht.
   */

  /**
   * Function to call Sehts constructor.
   *
   * @param {*=} selector - Query to search for
   * @param {Element=} context - Item in which we look for 'selector'
   * @return {Seht} An old or new Seht object
   */
  function seht(selector, context) {
    if (selector instanceof Seht) {
      // The selector is a Seht object, so let's return it as-is

      return selector;
    }

    // Call the constructor for Seht
    return new Seht(selector || null, context || doc);
  }

  /**
   * Initiates a Seht object.
   *
   * @constructor
   * @param {*} selector - Query to search for
   * @param {Element} context - Item in which we search for 'selector'
   */
  Seht = function (selector, context) {
    var
    elements;

    // Find elements
    elements = find(selector, context);

    // Set length for the current object
    this.length = elements.length;

    // Add each element to the current object
    each(elements, function (element, index) {
      this[index] = element;
    }, this);
  };

  /**
   * Prototypal methods or properties for Seht.
   */
  Seht.prototype = {

    /**
     * Default length for a Seht object.
     */
    length: 0,

    /**
     * Add class names to elements.
     *
     * @param {...String} Class names
     * @return {Seht} The original object
     */
    addClass: function() {
      return each(this, Classes.add, arguments);
    },

    /**
     * Insert HTML after elements.
     *
     * @param {String} string - HTML to insert
     * @return {Seht} The original object
     */
    after: function (string) {
      var
      html,
      next;

      // Turn the string into actual HTML
      html = htmlify(string);

      return each(this, function (element) {
        // Define where to insert the HTML
        next = element.nextSibling;

        each(html, function (item) {
          element.parentNode.insertBefore(item.cloneNode(true), next);
        });
      });
    },

    /**
     * Append HTML to elements.
     *
     * @param {String} string - HTML to append
     * @return {Seht} The original object
     */
    append: function (string) {
      var
      html;

      // Turn the string into actual HTML
      html = htmlify(string);

      return each(this, function (element) {
        each(html, function (item) {
          element.appendChild(item.cloneNode(true));
        })
      });
    },

    /**
     * Append a Seht object to a selector.
     *
     * @param {*} selector - Query to search for
     * @return {Seht} The new object
     */
    appendTo: function (selector) {
      return seht(selector).append(this);
    },

    /**
     * Get or set attributes for elements.
     *
     * @param {String} name - Name of attribute
     * @param {String=} value - New value for attribute
     * @return {Seht|String} The original object or value of attribute
     */
    attr: function (name, value) {
      if (typeof name !== undefinedString && typeof value !== undefinedString) {
        return each(this, function (element) {
          element.setAttribute(name, value);
        });
      } else if (this.length > 0) {
        return this[0].getAttribute(name);
      }

      return null;
    },

    /**
     * Insert HTML before elements.
     *
     * @param {String} string - HTML to insert
     * @return {Seht} The original object
     */
    before: function (string) {
      var
      html;

      // Turn the string into actual HTML
      html = htmlify(string);

      return each(this, function (element) {
        each(html, function (item) {
          element.parentNode.insertBefore(item.cloneNode(true), element);
        });
      });
    },

    /**
     * Get or set data-attributes for elements.
     *
     * @param {String} name - Name of attribute
     * @param {String=} value - New value for attribute
     * @return {Seht|String} The original object or value of attribute
     */
    data: function (name, value) {
      // Define a proper data name
      name = typeof name === undefinedString ? null : 'data-' + name;

      if (name && typeof value !== undefinedString) {
        // Convert a JS object to a JSON string
        value = JSON.stringify(value);

        return each(this, function (element) {
          element.setAttribute(name, value);
        });
      } else if (this.length > 0) {
        value = this[0].getAttribute(name);

        // Return a parsed JSON string
        return JSON.parse(value);
      }

      return null;
    },

    /**
     * Call a handler for each element in the Seht object.
     *
     * @param {Function} handler
     * @return {Seht} The original object
     */
    each: function (handler) {
      return each(this, handler);
    },

    /**
     * Create a Seht object containing only
     * the element at a specific position.
     *
     * @param {Number} index - Index for element
     * @return {Seht|Null} The new object or null
     */
    eq: function (index) {
      return seht(index >= 0 && index < this.length ? this[index] : null);
    },

    /**
     * Create a Seht object containing only the first element.
     *
     * @return {Seht|Null} The new object or null
     */
    first: function () {
      return this.eq(0);
    },

    /**
     * Get an actual element in the Seht object
     * from a specific position.
     */
    get: function (index) {
      if (index >= 0 && index < this.length) {
        return this[index];
      }

      return null;
    },

    /**
     * Verify if an element has a specific class name.
     *
     * @param {String} string - Class name to verify
     * @return {Boolean}
     */
    hasClass: function (string) {
      return Classes.contains(this[0], string);
    },

    /**
     * Get or set the HTML for elements.
     *
     * @param {String=} string - new HTML for elements
     * @return {Seht} The original object
     */
    html: function (string) {
      if (typeof string !== undefinedString) {
        if (string instanceof Seht) {
          // The supplied string is actually Seht
          // object, so let's flatten it.

          string = this.toString();
        }

        return each(this, function (element) {
          element.innerHTML = string;
        });
      } else if (this.length > 0) {
        return this[0].innerHTML;
      }

      return null;
    },

    /**
     * Create a Seht object containing only the last element.
     *
     * @return {Seht|Null} The new object or null
     */
    last: function () {
      return this.eq(this.length - 1);
    },

    /**
     * Prepend HTML to elements.
     *
     * @param {String} string - HTML to prepend
     * @return {Seht} The original object
     */
    prepend: function (string) {
      var
      first,
      html;

      // Turn the string into actual HTML
      html = htmlify(string);

      return each(this, function (element) {
        // Define where to insert the HTML
        first = element.firstChild;

        each(html, function (item) {
          element.insertBefore(item.cloneNode(true), first);
        });
      });
    },

    /**
     * Prepend a Seht object to a selector.
     *
     * @param {*} selector - Query to search for
     * @return {Seht} The new object
     */
    prependTo: function (selector) {
      return seht(selector).prepend(this);
    },

    /**
     * Remove class names from elements.
     *
     * @param {...String} Class names
     * @return {Seht} The original object
     */
    removeClass: function () {
      return each(this, Classes.remove, arguments);
    },

    /**
     * Get or set the text for elements.
     *
     * @param {String=} string - New text for elements
     * @return {Seht} The original object
     */
    text: function (string) {
      if (typeof string !== undefinedString) {
        return each(this, function (element) {
          element.textContent = string;
        });
      } else if (this.length > 0) {
        return this[0].textContent;
      }

      return null;
    },

    /**
     * Toggle class names for elements.
     *
     * @param {...String} Class names
     * @return {Seht} The original object
     */
    toggleClass: function () {
      return each(this, Classes.toggle, arguments);
    },

    /**
     * Convert the Seht object to a regular array.
     *
     * @return {Array} Array of elements
     */
    toArray: function () {
      return arrayProto.slice.call(this);
    },

    /**
     * Flatten the Seht object and combine
     * all elements' HTML.
     *
     * @return {String} The combined HTML
     */
    toString: function () {
      var
      string;

      string = '';

      each(this, function (element) {
        string += element.innerHTML;
      });

      return string;
    },

    /**
     * Set the value for an element.
     *
     * @param {String=} value - New value for elements
     * @return {Seht} The original object
     */
    value: function (value) {
      if (typeof value !== undefinedString) {
        return each(this, function (element) {
          element.value = value;
        });
      } else if (this.length > 0) {
        return this[0].value;
      }

      return null;
    }
  };

  seht.each = each;
  seht.ready = Events.ready;

  return seht;
});<|endoftext|>


<commit_before>import get from 'lodash/get';

const defaultOrder = {
  FIRST: 'asc',
  '': 'asc',
  asc: 'desc',
  desc: ''
};

const byColumn = ({
  sortingColumns,
  sortingOrder = defaultOrder,
  selectedColumn
}) => {
  let sort = sortingOrder.FIRST;

  if (sortingColumns && sortingColumns.hasOwnProperty(selectedColumn)) {
    sort = sortingOrder[sortingColumns[selectedColumn].direction];

    if (!sort) {
      return {};
    }
  }

  return {
    [selectedColumn]: {
      direction: sort,
      position: 0
    }
  };
};

const byColumns = ({
  sortingColumns,
  sortingOrder = defaultOrder,
  selectedColumn
}) => {
  let newSortingColumns = {};

  if (!sortingColumns) {
    return {
      [selectedColumn]: {
        direction: sortingOrder.FIRST,
        position: 0
      }
    };
  } else if (sortingColumns.hasOwnProperty(selectedColumn)) {
    // Clone to avoid mutating the original structure
    newSortingColumns = { ...sortingColumns };

    const newSort = sortingOrder[newSortingColumns[selectedColumn].direction];

    if (newSort) {
      newSortingColumns[selectedColumn] = {
        direction: newSort,
        position: newSortingColumns[selectedColumn].position
      };
    } else {
      delete newSortingColumns[selectedColumn];
    }

    return newSortingColumns;
  }

  return {
    ...sortingColumns,
    [selectedColumn]: {
      direction: sortingOrder.FIRST,
      position: Object.keys(sortingColumns).length
    }
  };
};

// sorter === lodash orderBy
// https://lodash.com/docs#orderBy
const sorter = ({
  columns,
  sortingColumns,
  sort
} = {}) => data => {
  if (!columns) {
    throw new Error('sort.sorter - Missing columns!');
  }

  if (!sortingColumns) {
    return data;
  }

  const columnIndexList = new Array(sortingColumns.length);
  const orderList = new Array(sortingColumns.length);

  Object.keys(sortingColumns).forEach(columnIndex => {
    const realColumn = columns[columnIndex] || { cell: {} };
    const resolver = realColumn.cell && realColumn.cell.resolve || (a => a);
    const sortingColumn = sortingColumns[columnIndex];

    columnIndexList[sortingColumn.position] = row => {
      const value = get(row, realColumn.cell.property);
      const resolvedValue = resolver(value, {
        rowData: row,
        property: realColumn.cell.property
      });

      if (resolvedValue && resolvedValue.toLowerCase) {
        return resolvedValue.toLowerCase();
      }

      return value;
    };

    orderList[sortingColumn.position] = sortingColumn.direction;
  });

  return sort(data, columnIndexList, orderList);
};

export default {
  byColumn,
  byColumns,
  sorter
};
<commit_msg>sort - Drop `lodash.get`<commit_after>const defaultOrder = {
  FIRST: 'asc',
  '': 'asc',
  asc: 'desc',
  desc: ''
};

const byColumn = ({
  sortingColumns,
  sortingOrder = defaultOrder,
  selectedColumn
}) => {
  let sort = sortingOrder.FIRST;

  if (sortingColumns && sortingColumns.hasOwnProperty(selectedColumn)) {
    sort = sortingOrder[sortingColumns[selectedColumn].direction];

    if (!sort) {
      return {};
    }
  }

  return {
    [selectedColumn]: {
      direction: sort,
      position: 0
    }
  };
};

const byColumns = ({
  sortingColumns,
  sortingOrder = defaultOrder,
  selectedColumn
}) => {
  let newSortingColumns = {};

  if (!sortingColumns) {
    return {
      [selectedColumn]: {
        direction: sortingOrder.FIRST,
        position: 0
      }
    };
  } else if (sortingColumns.hasOwnProperty(selectedColumn)) {
    // Clone to avoid mutating the original structure
    newSortingColumns = { ...sortingColumns };

    const newSort = sortingOrder[newSortingColumns[selectedColumn].direction];

    if (newSort) {
      newSortingColumns[selectedColumn] = {
        direction: newSort,
        position: newSortingColumns[selectedColumn].position
      };
    } else {
      delete newSortingColumns[selectedColumn];
    }

    return newSortingColumns;
  }

  return {
    ...sortingColumns,
    [selectedColumn]: {
      direction: sortingOrder.FIRST,
      position: Object.keys(sortingColumns).length
    }
  };
};

// sorter === lodash orderBy
// https://lodash.com/docs#orderBy
const sorter = ({
  columns,
  sortingColumns,
  sort
} = {}) => data => {
  if (!columns) {
    throw new Error('sort.sorter - Missing columns!');
  }

  if (!sortingColumns) {
    return data;
  }

  const columnIndexList = new Array(sortingColumns.length);
  const orderList = new Array(sortingColumns.length);

  // XXX: similar logic as for search and highlight -> share
  Object.keys(sortingColumns).forEach(columnIndex => {
    const realColumn = columns[columnIndex] || { cell: {} };
    const resolver = realColumn.cell && realColumn.cell.resolve || (a => a);
    const sortingColumn = sortingColumns[columnIndex];

    columnIndexList[sortingColumn.position] = row => {
      const value = row[realColumn.cell.property];
      const resolvedValue = resolver(value, {
        rowData: row,
        property: realColumn.cell.property
      });

      if (resolvedValue && resolvedValue.toLowerCase) {
        return resolvedValue.toLowerCase();
      }

      return value;
    };

    orderList[sortingColumn.position] = sortingColumn.direction;
  });

  return sort(data, columnIndexList, orderList);
};

export default {
  byColumn,
  byColumns,
  sorter
};
<|endoftext|>


<commit_before>if (CSMath.accurate['sqrt']) {
	CSMath.sqrt = Math.sqrt
} else {
	/* Algorithm from 'Divide, Square Root and Remainder Algorithms for the IA64 Architecture */

	var sqrtApproximation = Math.sqrt

	CSMath.sqrt = function (a) {
		var y0 = 1.0 / sqrtApproximation(a)

		var H0 = 0.5 * y0,
			S0 = (a * y0)

		var d0 = -CSMath.fms(S0, H0, 0.5)

		var H1 = CSMath.fma(d0, H0, H0),
			S1 = CSMath.fma(d0, S0, S0)

		var d1 = -CSMath.fms(S1, H1, 0.5)

		var H2 = CSMath.fma(d1, H1, H1),
			S2 = CSMath.fma(d1, S1, S1)

		var d2 = -CSMath.fms(S2, H2, 0.5),
			e2 = -CSMath.fms(S2, S2, a)

		var H3 = CSMath.fma(d2, H2, H2),
			S3 = CSMath.fma(e2, H2, S2)

		var e3 = -CSMath.fms(S3, S3, a)

		return CSMath.fma(e3, H3, S3)
	}
}

/* TODO: The root functions have low precision */

CSMath.cbrt = function(a) {
	return Math.pow(a, 1.0 / 3.0)
}<commit_msg>Add some notes about accuracy<commit_after>if (CSMath.accurate['sqrt']) {
	CSMath.sqrt = Math.sqrt
} else {
	/*
	 * Algorithm from 'Divide, Square Root and Remainder Algorithms for the IA64
	 * Architecture' by Intel
	 *
	 *  - It is proven correct under a few assumptions
	 *      1. That Math.sqrt is at least as accurate as the IA64 approximation
	 *         instruction.
	 *      2. That we're using the IA64 extended floating point format. (Which
	 *         we are not)
	 *  - I haven't checked if this algorithm actually works in double-precision,
	 *    but my intuition says that it should be fine.
	 */

	var sqrtApproximation = Math.sqrt

	CSMath.sqrt = function (a) {
		var y0 = 1.0 / sqrtApproximation(a)

		var H0 = 0.5 * y0,
			S0 = (a * y0)

		var d0 = -CSMath.fms(S0, H0, 0.5)

		var H1 = CSMath.fma(d0, H0, H0),
			S1 = CSMath.fma(d0, S0, S0)

		var d1 = -CSMath.fms(S1, H1, 0.5)

		var H2 = CSMath.fma(d1, H1, H1),
			S2 = CSMath.fma(d1, S1, S1)

		var d2 = -CSMath.fms(S2, H2, 0.5),
			e2 = -CSMath.fms(S2, S2, a)

		var H3 = CSMath.fma(d2, H2, H2),
			S3 = CSMath.fma(e2, H2, S2)

		var e3 = -CSMath.fms(S3, S3, a)

		return CSMath.fma(e3, H3, S3)
	}
}

/* TODO: The root functions have low precision */

CSMath.cbrt = function(a) {
	return Math.pow(a, 1.0 / 3.0)
}<|endoftext|>


<commit_before>
var child=require('child_process')
var p=require('bluebird')
var actions=[];

//actions.push("cd ~/.ssh");
//actions.push("echo 'start'");
//actions.push('ssh emmit-dev "cd /var/www/emmit ;touch test.js"& echo done')
//actions.push("echo 'end'");

actions.push("cd ~/.ssh");
actions.push('ssh ubuntu@54.83.47.127 -i ~/Desktop/test/emmit.pem "cd /var/www/emmit;touch test.js;ls;"')
//actions.push('scp -i ~/Desktop/test/emmit.pem ubuntu@54.83.47.127:/var/www/emmit/test.js ~/Desktop/test/')
//actions.push('scp -i ~/Desktop/test/emmit.pem ~/Desktop/test/test2.js ubuntu@54.83.47.127:/var/www/emmit/ ')
actions.push('echo done')

var command1=actions.join(";")

return run(command1)
  .then(function(aaa){
    console.log(aaa);
  })

function run(command){
  var temp= p.defer();
  child.exec(command,function(error,stdout,stderr){
    console.log(stderr);
    temp.resolve(stdout);
  });
  return temp.promise;
}

//git log -1
//git branch
//top -n 1 -b
//find test.js

function action(){
  this.actionType="sshaction";
  this.description="return the highest process";
  this.command="top -n 1 -b";
}

action.prototype.createcommand=function(){

};

<commit_msg>remove test file<commit_after><|endoftext|>


<commit_before>
module.exports = function (Range, a, b, config) {
  var sharejs = require('share/lib/client/index.js');
  var attach = require('../examples/share-ace.js');

  function connectDoc(editor){
    var host = window.location.host.toString().split(":");
    var ws = new WebSocket('ws://'+host[0]+':' + config.port);
    // besser nur einen ws für alle editoren

    ws.onerror = function (e) {
      console.log("websocket error! for editor " + editor);
    }

    ws.onclose = function(){
        //try to reconnect in 5 seconds
        setTimeout(function(){
          connectDoc(editor)
          }, 5000);
        console.log("reconnecting to ws");
    };

    ws.onopen = function () {
      console.log("websocket connected");

      var sjs = new sharejs.Connection(ws);

      var doc = sjs.get(a, b);

      doc.subscribe();
      doc.whenReady(function () {
        setTimeout(function () {
          if (!doc.type) doc.create('text');
          if (doc.type && doc.type.name === 'text') {
            //doc.attachAce(Range, editor);
            attach(Range, editor, doc.createContext())
          }
        });
      });
    }
  };

  return {connect : connectDoc};
}
<commit_msg>(fix) Dont use symlink it is not exported to NPM.<commit_after>
module.exports = function (Range, a, b, config) {
  var sharejs = require('share/lib/client/index.js');
  var attach = require('../share-ace.js');

  function connectDoc(editor){
    var host = window.location.host.toString().split(":");
    var ws = new WebSocket('ws://'+host[0]+':' + config.port);
    // besser nur einen ws für alle editoren

    ws.onerror = function (e) {
      console.log("websocket error! for editor " + editor);
    }

    ws.onclose = function(){
        //try to reconnect in 5 seconds
        setTimeout(function(){
          connectDoc(editor)
          }, 5000);
        console.log("reconnecting to ws");
    };

    ws.onopen = function () {
      console.log("websocket connected");

      var sjs = new sharejs.Connection(ws);

      var doc = sjs.get(a, b);

      doc.subscribe();
      doc.whenReady(function () {
        setTimeout(function () {
          if (!doc.type) doc.create('text');
          if (doc.type && doc.type.name === 'text') {
            //doc.attachAce(Range, editor);
            attach(Range, editor, doc.createContext())
          }
        });
      });
    }
  };

  return {connect : connectDoc};
}
<|endoftext|>