<commit_before>#!/usr/bin/env node
// vi fiz/bin/fiz.js
var Liftoff = require("liftoff");
var argv = require("minimist")(process.argv.slice(2));
var path = require("path");
var fs = require("fs");
var cli = new Liftoff({
  name: "fiz",
  processTitle: "fiz",
  moduleName: "fiz",
  configName: "fis-conf",

  //only js supported
  extensions: {
    ".js": null
  }
});

cli.launch({
  cwd: argv.r || argv.root,
  configPath: argv.f || argv.file
}, function(env){
  //捕获命令行
  var command = argv["_"];

  //fiz get项目
  if("get" == command[0]){
    //提供的服务
    var targetHash = {
      "web": {
        name: "web-template",
        url: "https://github.com/luozt/fiz-web-template.git"
      }
    };

    //检测是否存在该服务
    var cmd1 = command[1];
    var targetObj = targetHash[cmd1];
    if(!targetObj){
      console.log("Not such \"" + cmd1 + "\" get-target!");
      return false;
    }

    var noDir = !!argv["n"];
    var folder = targetObj.name;
    var childProcess = require("child_process");
    var exec = childProcess.exec;

    console.log("start get [ " + cmd1 + " ]");

    var child = exec("git clone " + targetObj.url, function(err, stdout, stderr){
      if(err){
        console.log("git clone err: " + err);
        return;
      }

      console.log("get [ " + cmd1 + " ] success");

      var child2 = exec("rm -rf " + folder + "/.git", function(err, stdout){
        if (err){
          console.log("rm "+ folder +"/.git error");
          return;
        }

        if (noDir){
          var child3 = exec("cp -rf " + folder + "/* ./", function(err, stdout){
            if(err){
              console.log("cp " + folder + " folder error");
              return;
            }

            var child4 = exec("rm -rf " + folder, function(err, stdout){
              if (err){
                console.log("rm "+ folder +" folder error")
                return;
              }
            });
          });
        }
      });
    });
  }

  // 移动文件夹，不支持文件
  if("mvDirContent" == command[0]){
    var childProcess, exec, dest, folder, child, cwd;

    cwd = process.cwd();
    folder = argv["src"];
    dest = argv["to"];

    if(!dest || "string" != typeof dest){
      console.log("dest: "+dest+", operate destination required!");
      return false;
    }

    if(!folder || "string" !== typeof folder){
      folder = cwd;
    }

    childProcess = require("child_process");
    exec = childProcess.exec;

    if(!fs.existsSync(folder)){
      console.log("source: "+folder+", not such a source Foler!");
      return;
    }

    if("/" === folder.slice(-1)){
      folder = folder.slice(0,-1);
    }

    console.log("source folder: "+folder);
    console.log("destination folder: "+dest);

    child = exec("mv -f "+folder+"/** "+dest, function(err, stdout){
      var child2;

      if(err){
        console.log(err);
        console.log("mv "+folder+" folder content error when execing: "+"mv -f "+folder+"/** "+dest);
        return;
      }

      child2 = exec("rm -rf "+folder, function(err, stdout){
        var child3, clearFolder;

        if(err){
          console.log(err);
          console.log("rm "+folder+" folder error");
          return;
        }

        // 检测是否还有要删除的文件夹
        clearFolder = argv["clear"];
        if(clearFolder){
          child3 = exec("rm -rf "+clearFolder, function(err, stdout){
            if(err){
              console.log(err);
              console.log("rm "+clearFolder+" folder error");
              return;
            }
          });
        }
      });
    });
  }

  //引用fis
  else{
    var fis;
    if(!env.modulePath){
      fis = require("./");
    }else{
      fis = require(env.modulePath);
    }

    fis.set("system.localNPMFolder", path.join(env.cwd, "node_modules/fiz"));
    //fis.set('system.globalNPMFolder', path.dirname(__dirname));
    fis.cli.run(argv, env);
  }

});

<commit_msg>修复使用get命令还会调用fis的问题；<commit_after>#!/usr/bin/env node
// vi fiz/bin/fiz.js
var Liftoff = require("liftoff");
var argv = require("minimist")(process.argv.slice(2));
var path = require("path");
var fs = require("fs");
var cli = new Liftoff({
  name: "fiz",
  processTitle: "fiz",
  moduleName: "fiz",
  configName: "fis-conf",

  //only js supported
  extensions: {
    ".js": null
  }
});

cli.launch({
  cwd: argv.r || argv.root,
  configPath: argv.f || argv.file
}, function(env){
  //捕获命令行
  var command = argv["_"];

  switch(command[0]){
    // fiz get
    case "get":
      //提供的服务
      var targetHash = {
        "web": {
          name: "web-template",
          url: "https://github.com/luozt/fiz-web-template.git"
        }
      };

      //检测是否存在该服务
      var cmd1 = command[1];
      var targetObj = targetHash[cmd1];
      if(!targetObj){
        console.log("Not such \"" + cmd1 + "\" get-target!");
        return false;
      }

      var noDir = !!argv["n"];
      var folder = targetObj.name;
      var childProcess = require("child_process");
      var exec = childProcess.exec;

      console.log("start get [ " + cmd1 + " ]");

      var child = exec("git clone " + targetObj.url, function(err, stdout, stderr){
        if(err){
          console.log("git clone err: " + err);
          return;
        }

        console.log("get [ " + cmd1 + " ] success");

        var child2 = exec("rm -rf " + folder + "/.git", function(err, stdout){
          if (err){
            console.log("rm "+ folder +"/.git error");
            return;
          }

          if (noDir){
            var child3 = exec("cp -rf " + folder + "/* ./", function(err, stdout){
              if(err){
                console.log("cp " + folder + " folder error");
                return;
              }

              var child4 = exec("rm -rf " + folder, function(err, stdout){
                if (err){
                  console.log("rm "+ folder +" folder error")
                  return;
                }
              });
            });
          }
        });
      });
      break;

    // 移动文件夹，不支持文件
    case "mvDirContent":
      var childProcess, exec, dest, folder, child, cwd;

      cwd = process.cwd();
      folder = argv["src"];
      dest = argv["to"];

      if(!dest || "string" != typeof dest){
        console.log("dest: "+dest+", operate destination required!");
        return false;
      }

      if(!folder || "string" !== typeof folder){
        folder = cwd;
      }

      childProcess = require("child_process");
      exec = childProcess.exec;

      if(!fs.existsSync(folder)){
        console.log("source: "+folder+", not such a source Foler!");
        return;
      }

      if("/" === folder.slice(-1)){
        folder = folder.slice(0,-1);
      }

      console.log("source folder: "+folder);
      console.log("destination folder: "+dest);

      child = exec("mv -f "+folder+"/** "+dest, function(err, stdout){
        var child2;

        if(err){
          console.log(err);
          console.log("mv "+folder+" folder content error when execing: "+"mv -f "+folder+"/** "+dest);
          return;
        }

        child2 = exec("rm -rf "+folder, function(err, stdout){
          var child3, clearFolder;

          if(err){
            console.log(err);
            console.log("rm "+folder+" folder error");
            return;
          }

          // 检测是否还有要删除的文件夹
          clearFolder = argv["clear"];
          if(clearFolder){
            child3 = exec("rm -rf "+clearFolder, function(err, stdout){
              if(err){
                console.log(err);
                console.log("rm "+clearFolder+" folder error");
                return;
              }
            });
          }
        });
      });
      break;

    // 引用fis
    default:
      var fis;

      if(!env.modulePath){
        fis = require("./");
      }else{
        fis = require(env.modulePath);
      }

      fis.set("system.localNPMFolder", path.join(env.cwd, "node_modules/fiz"));
      // fis.set('system.globalNPMFolder', path.dirname(__dirname));
      fis.cli.run(argv, env);
  }

});

<|endoftext|>


<commit_before>jIRCs.prototype.display = function(domobj) {
    if (!domobj) {
        var scripts = document.getElementsByTagName('script');
        domobj = scripts[scripts.length - 1].parentNode;
    }
    var container = document.createElement('table');
    var windowR = document.createElement('tr');
    var tabbarR = document.createElement('tr');
    var topicR = document.createElement('tr');
    var formR = document.createElement('tr');
    var formD = document.createElement('td');
    var windowD = document.createElement('td');
    var userlistD = document.createElement('td');
    var window = document.createElement('div');
    var tabbar = document.createElement('td');
    var topic = document.createElement('td');
    var userlist = document.createElement('div');
    var form = document.createElement('form');
    var input = document.createElement('input');
    var disobj = {
        'container': container,
        'messagebox': input,
        'tabBar': tabbar,
        'topic': topic,
        'userlist': userlist,
        'userlistD': userlistD,
        'form': form,
        'chatWindow': window,
        'channels': {},
        'window': '',
        'windowHistory': [],
        'height': domobj.clientHeight
    };
    container.className = "jircs_main";
    tabbar.className = "jircs_tabBar";
    topic.className = "jircs_topic";
    userlist.className = "jircs_userlist";
    form.className = "jircs_form";
    input.className = "jircs_input";
    window.className = "jircs_window";
    self = this;
    container.addEventListener("click", function(e) {
        if(e.target && e.target.className == 'jircs_channel_link') {
            self.send('JOIN',[e.target.innerHTML]);
            e.preventDefault();
        }
    });
    form.onsubmit = function() {
        self.handleLine(input.value, disobj);
        input.value = '';
        return false;
    };
    input.type = 'text';
    input.onkeydown = function(e) {
        var keyCode = e.keyCode || e.which;
        if(keyCode == 9) {
            // Get cursor position
            var cursor = 0;
            if (e.target.createTextRange) {
                var r = document.selection.createRange().duplicate()
                r.moveEnd('character', e.target.value.length)
                if (r.text == '')
                    return e.target.value.length
                cursor = e.target.value.lastIndexOf(r.text)
            } else {
                cursor = e.target.selectionStart
            }
            var begin = e.target.value.lastIndexOf(' ',cursor) + 1;
            var end = e.target.value.indexOf(' ',cursor);
            if(end == -1) end = e.target.value.length;
            var name = e.target.value.substring(begin,end);
            var possible = [];
            // Complete the name
            for(var n in self.channels[disobj.window].names) {
                if(self.channels[disobj.window].names.hasOwnProperty(n) && n.substring(0,name.length).toLowerCase() == name.toLowerCase())
                    possible.push(n);
            }
            if(possible.length == 1)
                name = possible[0];
            else if(possible.length == 0)
                self.renderLine(disobj.window,'','No Possible Nicknames');
            else
                self.renderLine(disobj.window,'','Possible Nicknames: '+possible.join(' '));
            e.target.value = e.target.value.substring(0,begin) + name + e.target.value.substr(end);
            e.preventDefault();
        }
    };
    form.appendChild(input);
    //give focus to input box whenever chat is clicked
    container.onclick = function() {
        input.focus();
    };
    tabbar.colSpan = 2;
    topic.colSpan = 2;
    formD.colSpan = 2;
    formD.appendChild(form);
    windowD.appendChild(window);
    userlistD.appendChild(userlist);
    formR.appendChild(formD);
    windowR.appendChild(windowD);
    windowR.appendChild(userlistD);
    tabbarR.appendChild(tabbar);
    topicR.appendChild(topic);
    container.appendChild(tabbarR);
    container.appendChild(topicR);
    container.appendChild(windowR);
    container.appendChild(formR);
    domobj.appendChild(container);
    this.fixHeights(disobj);
    //set up Status window
    this.initChan("Status", disobj);
    this.activateChan("Status", disobj);
    this.displays.push(disobj);
};

jIRCs.prototype.initChan = function(channel, disobj) {
    var table = document.createElement('table');
    var tab = document.createElement('span');
    table.className = "jircs_chatTable";
    tab.className = "jircs_tab";
    tab.appendChild(document.createTextNode(channel));
    self = this;
    tab.onclick = function() {
        self.activateChan(channel, disobj);
    };
    if (channel != "Status") {
        var closeBtn = document.createElement("span");
        closeBtn.appendChild(document.createTextNode("X"));
        closeBtn.onclick = function() {
            self.destroyChan(channel);
        };
        closeBtn.className = "jircs_tab_closeBtn";
        tab.appendChild(closeBtn);
    }
    disobj.tabBar.appendChild(tab);
    table.style.display = "none"; //hide new channel
    disobj.chatWindow.appendChild(table);
    disobj.channels[channel] = {'table': table, 'tab': tab};
};

jIRCs.prototype.destroyChan = function(channel) {
    if (channel != 'Status' && channel in this.channels) {
       //part channel
       this.send("PART",[channel]);
       //Iterate through displays
       this.displays.forEach(function(disobj) {
           //remove from DOM
           disobj.tabBar.removeChild(disobj.channels[channel].tab);
           disobj.chatWindow.removeChild(disobj.channels[channel].table);
           //destroy
           delete(disobj.channels[channel]);
           //pick a channel to activate
           var newchan = disobj.windowHistory.pop();
           while (newchan && !disobj.channels[newchan]) newchan = disobj.windowHistory.pop() || false;
           if(!newchan) newchan = 'Status';
           this.activateChan(newchan, disobj);
       }, this);
       delete(this.channels[channel]);
    }
};

jIRCs.prototype.activateChan = function(channel, disobj) {
    if (disobj.channels[channel] && disobj.window != channel) {
        this.displays.forEach(function(idisobj) {
            for (var chan in idisobj.channels) {
                var newClass = 'jircs_tab';
                if(idisobj == disobj)
                    disobj.channels[chan].table.style.display = "none";
                else if(idisobj.channels[chan].tab.className.indexOf("jircs_tab_active") >= 0)
                    newClass += ' jircs_tab_active';
                if(chan != channel) {
                    if(idisobj.channels[chan].tab.className.indexOf("jircs_tab_attention") >= 0)
                        newClass += " jircs_tab_attention"
                    if(idisobj.channels[chan].tab.className.indexOf("jircs_tab_hilight") >= 0)
                        newClass += " jircs_tab_hilight"
                }
                idisobj.channels[chan].tab.className = newClass;
            }
        }, this);
        disobj.channels[channel].table.style.display = "table";
        disobj.channels[channel].tab.className += " jircs_tab_active";
        disobj.windowHistory.push(disobj.window);
        disobj.window = channel;
        this.renderTopic(disobj);
        this.renderUserlist(disobj);
    }
};

jIRCs.prototype.renderLine = function(channel, speaker, message) {
        if (!channel)
            channel = "Status";
        var now = new Date();
        var h = '' + now.getHours();
        var m = '' + now.getMinutes();
        var s = '' + now.getSeconds();
        var row = document.createElement('tr');
        var date = document.createElement('td');
        var user = document.createElement('td');
        var text = document.createElement('td');
        row.className = "jircs_chatRow";
        date.className = "jircs_chatDate";
        user.className = "jircs_chatUser";
        text.className = "jircs_chatText";
        date.appendChild(document.createTextNode('[' + (h.length > 1 ? h : '0'+h) + ':' + (m.length > 1 ? m : '0'+m) + ':' + (s.length > 1 ? s : '0'+s) + ']'));
        user.appendChild(document.createTextNode(speaker));
        text.appendChild(document.createTextNode(message));
        row.appendChild(date);
        if(speaker == '') {
            text.className += " jircs_action";
            text.colSpan = 2;
        }
        else
            row.appendChild(user);
        var nickCheck = new RegExp("\\b"+this.nickname+"\\b");
        if(nickCheck.test(message)) { // Hilight
            row.className += " jircs_hilight";
        }
        row.appendChild(text);
        text.innerHTML = text.innerHTML.replace(this.url_regex, this.linkMunger); // Auto-linkify links
        if(!(channel in this.channels))
            this.channels[channel] = {} // Add a new object in which we can store channel data
        // Track open channels
        var open = [];
        for(var d in this.displays)
            open.push(this.displays[d].window);
        this.displays.forEach(function(disobj) {
            if (!disobj.channels[channel])
                this.initChan(channel, disobj);
            var b = (disobj.chatWindow.scrollHeight < disobj.chatWindow.clientHeight || disobj.chatWindow.scrollHeight <= disobj.chatWindow.scrollTop + disobj.chatWindow.clientHeight + 5); // 5px buffer just in case
            var r = row.cloneNode(true);
            r.innerHTML = r.innerHTML.replace(/([>\s])(#[^\s\a,:]+?)([<\s])/ig,'$1$2$3'); // Auto-linkify channels
            disobj.channels[channel].table.appendChild(r);
            if(b) disobj.chatWindow.scrollTop = disobj.chatWindow.scrollHeight - disobj.chatWindow.clientHeight; // Only scroll when user is at the bottom
            if (open.indexOf(channel) == -1) {
                if(disobj.channels[channel].tab.className.indexOf("jircs_tab_attention") == -1)
                    disobj.channels[channel].tab.className += " jircs_tab_attention";
                if(disobj.channels[channel].tab.className.indexOf("jircs_tab_hilight") == -1 && nickCheck.test(message))
                    disobj.channels[channel].tab.className += " jircs_tab_hilight";
            }
        }, this);
};

jIRCs.prototype.renderTopic = function(disobj) {
    disobj.topic.innerHTML = "";
    if(!(disobj.window in this.channels && this.channels[disobj.window].topic)) {
        this.fixHeights(disobj);
        return;
    }
    var tmsg = document.createElement('p');
    tmsg.appendChild(document.createTextNode(this.channels[disobj.window].topic.message));
    tmsg.className = 'jircs_topic_message';
    disobj.topic.appendChild(tmsg);
    if(this.channels[disobj.window].topic.creator) {
        var tcreator = document.createElement('p');
        var msg = 'Set by ' + this.channels[disobj.window].topic.creator;
        if(this.channels[disobj.window].topic.time) {
            var t = this.channels[disobj.window].topic.time;
            var h = '' + t.getHours();
            var m = '' + t.getMinutes();
            var s = '' + t.getSeconds();
            msg += ' on ' + (t.getMonth() + 1) + '/' + t.getDate() + '/' + t.getFullYear() + ' ' + (h.length > 1 ? h : '0'+h) + ':' + (m.length > 1 ? m : '0'+m) + ':' + (s.length > 1 ? s : '0'+s);
        }
        tcreator.appendChild(document.createTextNode(msg));
        tcreator.className = 'jircs_topic_creator';
        disobj.topic.appendChild(tcreator);
    }
    this.fixHeights(disobj);
};

jIRCs.prototype.renderUserlist = function(disobj) {
    disobj.userlist.innerHTML = "";
    disobj.userlistD.style.width = '0px';
    if(!(disobj.window in this.channels))
        return;
    var users = {};
    var prefix = '', rank = '';
    for(var u in this.channels[disobj.window].names) {
        prefix = this.channels[disobj.window].names[u];
        if(prefix.length) prefix = prefix.charAt(0);
        rank = prefix in this.statuses ? this.statuses[prefix] : '';
        if(!(rank in users))
            users[rank] = [];
        users[rank].push(prefix + u);
    }
    this.statusOrder.forEach(function(r) {
        if(!(r in users))
            return;
        var ulist = users[r];
        // Case insensitive sort
        ulist.sort(function(a,b) { if(a.toLowerCase() > b.toLowerCase()) return 1; if(a.toLowerCase() < b.toLowerCase()) return -1; return 0;});
        console.log(ulist);
        ulist.forEach(function(u) {
            var p = document.createElement('p');
            p.appendChild(document.createTextNode(u));
            p.className = 'jircs_userlist_user';
            disobj.userlist.appendChild(p);
        }, this);
    }, this);
    disobj.userlistD.style.width = (disobj.userlist.scrollWidth + 20) + 'px';
    disobj.userlist.scrollTop = 0;
};

jIRCs.prototype.fixHeights = function(disobj) {
    disobj.chatWindow.style.height = disobj.userlist.style.height = '0px';
    var h = (disobj.height - disobj.container.offsetHeight) + 'px';
    console.log(h);
    disobj.chatWindow.style.height = disobj.userlist.style.height = h;
};<commit_msg>Convert .on* to addEventListener, allow selection<commit_after>jIRCs.prototype.display = function(domobj) {
    if (!domobj) {
        var scripts = document.getElementsByTagName('script');
        domobj = scripts[scripts.length - 1].parentNode;
    }
    var container = document.createElement('table');
    var windowR = document.createElement('tr');
    var tabbarR = document.createElement('tr');
    var topicR = document.createElement('tr');
    var formR = document.createElement('tr');
    var formD = document.createElement('td');
    var windowD = document.createElement('td');
    var userlistD = document.createElement('td');
    var window = document.createElement('div');
    var tabbar = document.createElement('td');
    var topic = document.createElement('td');
    var userlist = document.createElement('div');
    var form = document.createElement('form');
    var input = document.createElement('input');
    var disobj = {
        'container': container,
        'messagebox': input,
        'tabBar': tabbar,
        'topic': topic,
        'userlist': userlist,
        'userlistD': userlistD,
        'form': form,
        'chatWindow': window,
        'channels': {},
        'window': '',
        'windowHistory': [],
        'height': domobj.clientHeight
    };
    container.className = "jircs_main";
    tabbar.className = "jircs_tabBar";
    topic.className = "jircs_topic";
    userlist.className = "jircs_userlist";
    form.className = "jircs_form";
    input.className = "jircs_input";
    window.className = "jircs_window";
    self = this;
    container.addEventListener("click", function(e) {
        if(e.target && e.target.className == 'jircs_channel_link') {
            self.send('JOIN',[e.target.innerHTML]);
            e.preventDefault();
        }
    });
    container.addEventListener("mousedown", function(e) {
        disobj.mouse = {'x':e.screenX,'y':e.screenY};
    });
    container.addEventListener("mouseup", function(e) {
        if(!('mouse' in disobj && 'x' in disobj.mouse && 'y' in disobj.mouse)) {
            input.focus();
        }
        var dx = disobj.mouse.x - e.screenX,
            dy = disobj.mouse.y - e.screenY;
        if(dx < 0) dx *= -1;
        if(dy < 0) dy *= -1;
        if(dx < 5 && dy < 5 && e.button == 0) //Make sure text selection works as expected
            input.focus();
    });
    form.addEventListener("submit", function(e) {
        self.handleLine(input.value, disobj);
        input.value = '';
        e.preventDefault();
    });
    input.type = 'text';
    input.addEventListener("keydown", function(e) {
        var keyCode = e.keyCode || e.which;
        if(keyCode == 9) {
            // Get cursor position
            var cursor = 0;
            if (e.target.createTextRange) {
                var r = document.selection.createRange().duplicate()
                r.moveEnd('character', e.target.value.length)
                if (r.text == '')
                    cursor = e.target.value.length
                cursor = e.target.value.lastIndexOf(r.text)
            } else {
                cursor = e.target.selectionStart
            }
            var begin = e.target.value.lastIndexOf(' ',cursor) + 1;
            var end = e.target.value.indexOf(' ',cursor);
            if(end == -1) end = e.target.value.length;
            var name = e.target.value.substring(begin,end);
            var possible = [];
            // Complete the name
            for(var n in self.channels[disobj.window].names) {
                if(self.channels[disobj.window].names.hasOwnProperty(n) && n.substring(0,name.length).toLowerCase() == name.toLowerCase())
                    possible.push(n);
            }
            if(possible.length == 1)
                name = possible[0];
            else if(possible.length == 0)
                self.renderLine(disobj.window,'','No Possible Nicknames');
            else
                self.renderLine(disobj.window,'','Possible Nicknames: '+possible.join(' '));
            e.target.value = e.target.value.substring(0,begin) + name + e.target.value.substr(end);
            e.preventDefault();
        }
    });
    form.appendChild(input);
    tabbar.colSpan = 2;
    topic.colSpan = 2;
    formD.colSpan = 2;
    formD.appendChild(form);
    windowD.appendChild(window);
    userlistD.appendChild(userlist);
    formR.appendChild(formD);
    windowR.appendChild(windowD);
    windowR.appendChild(userlistD);
    tabbarR.appendChild(tabbar);
    topicR.appendChild(topic);
    container.appendChild(tabbarR);
    container.appendChild(topicR);
    container.appendChild(windowR);
    container.appendChild(formR);
    domobj.appendChild(container);
    this.fixHeights(disobj);
    //set up Status window
    this.initChan("Status", disobj);
    this.activateChan("Status", disobj);
    this.displays.push(disobj);
};

jIRCs.prototype.initChan = function(channel, disobj) {
    var table = document.createElement('table');
    var tab = document.createElement('span');
    table.className = "jircs_chatTable";
    tab.className = "jircs_tab";
    tab.appendChild(document.createTextNode(channel));
    self = this;
    tab.addEventListener("click", function() {
        self.activateChan(channel, disobj);
    });
    if (channel != "Status") {
        var closeBtn = document.createElement("span");
        closeBtn.appendChild(document.createTextNode("X"));
        closeBtn.addEventListener("click", function() {
            self.destroyChan(channel);
        });
        closeBtn.className = "jircs_tab_closeBtn";
        tab.appendChild(closeBtn);
    }
    disobj.tabBar.appendChild(tab);
    table.style.display = "none"; //hide new channel
    disobj.chatWindow.appendChild(table);
    disobj.channels[channel] = {'table': table, 'tab': tab};
};

jIRCs.prototype.destroyChan = function(channel) {
    if (channel != 'Status' && channel in this.channels) {
       //part channel
       this.send("PART",[channel]);
       //Iterate through displays
       this.displays.forEach(function(disobj) {
           //remove from DOM
           disobj.tabBar.removeChild(disobj.channels[channel].tab);
           disobj.chatWindow.removeChild(disobj.channels[channel].table);
           //destroy
           delete(disobj.channels[channel]);
           //pick a channel to activate
           var newchan = disobj.windowHistory.pop();
           while (newchan && !disobj.channels[newchan]) newchan = disobj.windowHistory.pop() || false;
           if(!newchan) newchan = 'Status';
           this.activateChan(newchan, disobj);
       }, this);
       delete(this.channels[channel]);
    }
};

jIRCs.prototype.activateChan = function(channel, disobj) {
    if (disobj.channels[channel] && disobj.window != channel) {
        this.displays.forEach(function(idisobj) {
            for (var chan in idisobj.channels) {
                var newClass = 'jircs_tab';
                if(idisobj == disobj)
                    disobj.channels[chan].table.style.display = "none";
                else if(idisobj.channels[chan].tab.className.indexOf("jircs_tab_active") >= 0)
                    newClass += ' jircs_tab_active';
                if(chan != channel) {
                    if(idisobj.channels[chan].tab.className.indexOf("jircs_tab_attention") >= 0)
                        newClass += " jircs_tab_attention"
                    if(idisobj.channels[chan].tab.className.indexOf("jircs_tab_hilight") >= 0)
                        newClass += " jircs_tab_hilight"
                }
                idisobj.channels[chan].tab.className = newClass;
            }
        }, this);
        disobj.channels[channel].table.style.display = "table";
        disobj.channels[channel].tab.className += " jircs_tab_active";
        disobj.windowHistory.push(disobj.window);
        disobj.window = channel;
        this.renderTopic(disobj);
        this.renderUserlist(disobj);
    }
};

jIRCs.prototype.renderLine = function(channel, speaker, message) {
        if (!channel)
            channel = "Status";
        var now = new Date();
        var h = '' + now.getHours();
        var m = '' + now.getMinutes();
        var s = '' + now.getSeconds();
        var row = document.createElement('tr');
        var date = document.createElement('td');
        var user = document.createElement('td');
        var text = document.createElement('td');
        row.className = "jircs_chatRow";
        date.className = "jircs_chatDate";
        user.className = "jircs_chatUser";
        text.className = "jircs_chatText";
        date.appendChild(document.createTextNode('[' + (h.length > 1 ? h : '0'+h) + ':' + (m.length > 1 ? m : '0'+m) + ':' + (s.length > 1 ? s : '0'+s) + ']'));
        user.appendChild(document.createTextNode(speaker));
        text.appendChild(document.createTextNode(message));
        row.appendChild(date);
        if(speaker == '') {
            text.className += " jircs_action";
            text.colSpan = 2;
        }
        else
            row.appendChild(user);
        var nickCheck = new RegExp("\\b"+this.nickname+"\\b");
        if(nickCheck.test(message)) { // Hilight
            row.className += " jircs_hilight";
        }
        row.appendChild(text);
        text.innerHTML = text.innerHTML.replace(this.url_regex, this.linkMunger); // Auto-linkify links
        if(!(channel in this.channels))
            this.channels[channel] = {} // Add a new object in which we can store channel data
        // Track open channels
        var open = [];
        for(var d in this.displays)
            open.push(this.displays[d].window);
        this.displays.forEach(function(disobj) {
            if (!disobj.channels[channel])
                this.initChan(channel, disobj);
            var b = (disobj.chatWindow.scrollHeight < disobj.chatWindow.clientHeight || disobj.chatWindow.scrollHeight <= disobj.chatWindow.scrollTop + disobj.chatWindow.clientHeight + 5); // 5px buffer just in case
            var r = row.cloneNode(true);
            r.innerHTML = r.innerHTML.replace(/([>\s])(#[^\s\a,:]+?)([<\s])/ig,'$1$2$3'); // Auto-linkify channels
            disobj.channels[channel].table.appendChild(r);
            if(b) disobj.chatWindow.scrollTop = disobj.chatWindow.scrollHeight - disobj.chatWindow.clientHeight; // Only scroll when user is at the bottom
            if (open.indexOf(channel) == -1) {
                if(disobj.channels[channel].tab.className.indexOf("jircs_tab_attention") == -1)
                    disobj.channels[channel].tab.className += " jircs_tab_attention";
                if(disobj.channels[channel].tab.className.indexOf("jircs_tab_hilight") == -1 && nickCheck.test(message))
                    disobj.channels[channel].tab.className += " jircs_tab_hilight";
            }
        }, this);
};

jIRCs.prototype.renderTopic = function(disobj) {
    disobj.topic.innerHTML = "";
    if(!(disobj.window in this.channels && this.channels[disobj.window].topic)) {
        this.fixHeights(disobj);
        return;
    }
    var tmsg = document.createElement('p');
    tmsg.appendChild(document.createTextNode(this.channels[disobj.window].topic.message));
    tmsg.className = 'jircs_topic_message';
    disobj.topic.appendChild(tmsg);
    if(this.channels[disobj.window].topic.creator) {
        var tcreator = document.createElement('p');
        var msg = 'Set by ' + this.channels[disobj.window].topic.creator;
        if(this.channels[disobj.window].topic.time) {
            var t = this.channels[disobj.window].topic.time;
            var h = '' + t.getHours();
            var m = '' + t.getMinutes();
            var s = '' + t.getSeconds();
            msg += ' on ' + (t.getMonth() + 1) + '/' + t.getDate() + '/' + t.getFullYear() + ' ' + (h.length > 1 ? h : '0'+h) + ':' + (m.length > 1 ? m : '0'+m) + ':' + (s.length > 1 ? s : '0'+s);
        }
        tcreator.appendChild(document.createTextNode(msg));
        tcreator.className = 'jircs_topic_creator';
        disobj.topic.appendChild(tcreator);
    }
    this.fixHeights(disobj);
};

jIRCs.prototype.renderUserlist = function(disobj) {
    disobj.userlist.innerHTML = "";
    disobj.userlistD.style.width = '0px';
    if(!(disobj.window in this.channels))
        return;
    var users = {};
    var prefix = '', rank = '';
    for(var u in this.channels[disobj.window].names) {
        prefix = this.channels[disobj.window].names[u];
        if(prefix.length) prefix = prefix.charAt(0);
        rank = prefix in this.statuses ? this.statuses[prefix] : '';
        if(!(rank in users))
            users[rank] = [];
        users[rank].push(prefix + u);
    }
    this.statusOrder.forEach(function(r) {
        if(!(r in users))
            return;
        var ulist = users[r];
        // Case insensitive sort
        ulist.sort(function(a,b) { if(a.toLowerCase() > b.toLowerCase()) return 1; if(a.toLowerCase() < b.toLowerCase()) return -1; return 0;});
        console.log(ulist);
        ulist.forEach(function(u) {
            var p = document.createElement('p');
            p.appendChild(document.createTextNode(u));
            p.className = 'jircs_userlist_user';
            disobj.userlist.appendChild(p);
        }, this);
    }, this);
    disobj.userlistD.style.width = (disobj.userlist.scrollWidth + 20) + 'px';
    disobj.userlist.scrollTop = 0;
};

jIRCs.prototype.fixHeights = function(disobj) {
    disobj.chatWindow.style.height = disobj.userlist.style.height = '0px';
    var h = (disobj.height - disobj.container.offsetHeight) + 'px';
    console.log(h);
    disobj.chatWindow.style.height = disobj.userlist.style.height = h;
};<|endoftext|>


<commit_before>var ipc = require('ipc');
var fs = require('fs');
var validationNotes = require('./validation_notes.json')

var container = document.getElementById("editor");
var hot = new Handsontable(container, {
  colHeaders: true,
  rowHeaders: true,
  columnSorting: true,
  contextMenu: false
});

container.addEventListener('contextmenu', function (e) {
  e.preventDefault();
  if (hot.getSelected()[0] == 0) {
    rowAbove.enabled = false
  }
  if (hot.getSelected()[1] == 0) {
    columnLeft.enabled = false
  }
  menu.popup(remote.getCurrentWindow());
  rowAbove.enabled = true
  columnLeft.enabled = true
}, false);

ipc.on('loadData', function(data) {
  csv = $.csv.toArrays(data);
  hot.loadData(csv);
  //refactorColumns(csv_2);
  fixRaggedRows(csv);
});

ipc.on('saveData', function(fileName) {
  data = $.csv.fromArrays(hot.getData());
  fs.writeFile(fileName, data, function (err) {
  });
  document.title = fileName;
});

ipc.on('getCSV', function() {
  data = $.csv.fromArrays(hot.getData());
  ipc.send('sendCSV', data);
})

ipc.on('validate', function() {
  validate();
});

// How to use:
// getValidation("Example,CSV,content\na,b,c\n")
//  .then(function(validation) {console.log(validation)})

function getValidation(content) {
  request = require('request');
  content = new Buffer(content).toString("base64");
  content = "editor.csv;data:text/csv;base64," + content;
  return new Promise(function(resolve, reject) {
    request.post("http://csvlint.io/package.json", { formData: {"files_data[]": content } }, function(error, response, body) {

      if (error) return reject(error);

      var packageURL = JSON.parse(response.body).package.url;
      var interval = setInterval(function() {
        request.get(packageURL + ".json", function(error, response, body) {
          try {
            var validationURL = JSON.parse(body).package.validations[0].url;
            clearInterval(interval);
            request.get(validationURL + ".json", function(error, response, body) {
              if (error) return reject(error);
              resolve(JSON.parse(body));
            });
          } catch(e) {}
        });
      }, 1000);

    });
  });
}

// Splits validation returned from CSVLint into errors, warnings and info messages

function validate() {
  data = $.csv.fromArrays(hot.getData());
  $('#right-panel').removeClass("hidden")
  $('#message-panel').html("

Loading validation results...

");
  getValidation(data).then(function(json_validation) {
    errors = json_validation.validation.errors
    warnings = json_validation.validation.warnings
    info_messages = json_validation.validation.info
    console.error(errors)
    console.warn(warnings)
    console.info(info_messages);
    displayValidationMessages(json_validation.validation);
  });
}

function displayValidationMessages(validation) {
  var $messagePanel = $('#message-panel');
  $messagePanel.html("
Validation results
")
  resultsTemplate = _.template('
<%= validation.errors.length %> errors, <%= validation.warnings.length %> warnings and <%= validation.info.length %> info messages:
')
  $messagePanel.append(resultsTemplate({'validation': validation}));

  var messageTemplate = _.template('<div class="<%= cssClass %>">
<%= errorText(type) %> <% if (row) print("on row " + row) %> <% if (col) print("on column " + col) %>

');
  var messages = _.flatten([
    _.map(validation.errors,   function(d) { return _.extend({}, d, { cssClass: 'message validation-error' }) }),
    _.map(validation.warnings, function(d) { return _.extend({}, d, { cssClass: 'message validation-warning' }) }),
    _.map(validation.info,     function(d) { return _.extend({}, d, { cssClass: 'message validation-info' }) })
  ]);
  if (messages.length) {
    var html = _.map(messages, messageTemplate);
    $messagePanel.append(html);
  } else {
    $messagePanel.append('
CSV Valid!
');
  }
}

function errorText(error) {
  return validationNotes.errors[error]
}

// Currently redundant unless the user refuses to fix ragged rows
function refactorColumns(csv_array) {
  col_add = getMaxColumns(csv_array) - hot.countCols()
  // adds a column by default if the amount parameter is 0, hence conditional
  if (col_add != 0) {
    hot.alter('insert_col', null, col_add)
  }
}

function getMaxColumns(csv_array) {
  max_columns = 0
  for (var i = 0; i < csv_array.length; i++) {
    col_length = csv_array[i].length
    if (col_length > max_columns) {
      max_columns = col_length
    }
  }
  return max_columns
}

// Fills undefined cells with an empty string, keeping the table in a
// rectangular format

function fixRaggedRows(csv_array) {
  ragged_rows = 0;
  //
  for (var y = 0; y < csv_array.length; y++) {
    for (var x = 0; x < getMaxColumns(csv_array); x++) {
      if (hot.getDataAtCell(y,x) === undefined || hot.getDataAtCell(y,x) === null) {
        if (ragged_rows == 0) {
          if (confirm("Your file has ragged rows, do you want to correct this?")) {
            ragged_rows = 1
            fixCell(csv_array,y,x)
          }
          else {ragged_rows = -1}
        }
        else if (ragged_rows == 1) {
          fixCell(csv_array,y,x)
        }
      }
    }
  }
  updateTable(csv_array)
}

function fixCell(csv_array,y,x) {
  csv_array[y].push("")
  console.log("Cell (" + String.fromCharCode(97 + x).toUpperCase() + "," + (y + 1) + ") has been added to file")
}

function updateTable(csv_array) {
  hot.updateSettings ({
    data: csv_array,
  });
}

$('button[data-dismiss=alert]').click(function() {
  $(this).parent('.alert').addClass('hidden')
})
<commit_msg>Show guidance too<commit_after>var ipc = require('ipc');
var fs = require('fs');
var validationNotes = require('./validation_notes.json')

var container = document.getElementById("editor");
var hot = new Handsontable(container, {
  colHeaders: true,
  rowHeaders: true,
  columnSorting: true,
  contextMenu: false
});

container.addEventListener('contextmenu', function (e) {
  e.preventDefault();
  if (hot.getSelected()[0] == 0) {
    rowAbove.enabled = false
  }
  if (hot.getSelected()[1] == 0) {
    columnLeft.enabled = false
  }
  menu.popup(remote.getCurrentWindow());
  rowAbove.enabled = true
  columnLeft.enabled = true
}, false);

ipc.on('loadData', function(data) {
  csv = $.csv.toArrays(data);
  hot.loadData(csv);
  //refactorColumns(csv_2);
  fixRaggedRows(csv);
});

ipc.on('saveData', function(fileName) {
  data = $.csv.fromArrays(hot.getData());
  fs.writeFile(fileName, data, function (err) {
  });
  document.title = fileName;
});

ipc.on('getCSV', function() {
  data = $.csv.fromArrays(hot.getData());
  ipc.send('sendCSV', data);
})

ipc.on('validate', function() {
  validate();
});

// How to use:
// getValidation("Example,CSV,content\na,b,c\n")
//  .then(function(validation) {console.log(validation)})

function getValidation(content) {
  request = require('request');
  content = new Buffer(content).toString("base64");
  content = "editor.csv;data:text/csv;base64," + content;
  return new Promise(function(resolve, reject) {
    request.post("http://csvlint.io/package.json", { formData: {"files_data[]": content } }, function(error, response, body) {

      if (error) return reject(error);

      var packageURL = JSON.parse(response.body).package.url;
      var interval = setInterval(function() {
        request.get(packageURL + ".json", function(error, response, body) {
          try {
            var validationURL = JSON.parse(body).package.validations[0].url;
            clearInterval(interval);
            request.get(validationURL + ".json", function(error, response, body) {
              if (error) return reject(error);
              resolve(JSON.parse(body));
            });
          } catch(e) {}
        });
      }, 1000);

    });
  });
}

// Splits validation returned from CSVLint into errors, warnings and info messages

function validate() {
  data = $.csv.fromArrays(hot.getData());
  $('#right-panel').removeClass("hidden")
  $('#message-panel').html("

Loading validation results...

");
  getValidation(data).then(function(json_validation) {
    errors = json_validation.validation.errors
    warnings = json_validation.validation.warnings
    info_messages = json_validation.validation.info
    console.error(errors)
    console.warn(warnings)
    console.info(info_messages);
    displayValidationMessages(json_validation.validation);
  });
}

function displayValidationMessages(validation) {
  var $messagePanel = $('#message-panel');
  $messagePanel.html("
Validation results
")
  resultsTemplate = _.template('
<%= validation.errors.length %> errors, <%= validation.warnings.length %> warnings and <%= validation.info.length %> info messages:
')
  $messagePanel.append(resultsTemplate({'validation': validation}));

  var messageTemplate = _.template('<div class="<%= cssClass %>">
<%= errorText(type) %> <% if (row) print("on row " + row) %> <% if (col) print("on column " + col) %>

<%= errorGuidance(type) %>

');
  var messages = _.flatten([
    _.map(validation.errors,   function(d) { return _.extend({}, d, { cssClass: 'message validation-error' }) }),
    _.map(validation.warnings, function(d) { return _.extend({}, d, { cssClass: 'message validation-warning' }) }),
    _.map(validation.info,     function(d) { return _.extend({}, d, { cssClass: 'message validation-info' }) })
  ]);
  if (messages.length) {
    var html = _.map(messages, messageTemplate);
    $messagePanel.append(html);
  } else {
    $messagePanel.append('
CSV Valid!
');
  }
}

function errorText(error) {
  return validationNotes.errors[error]
}

function errorGuidance(error) {
  return validationNotes.errors[error + '_guidance_html']
}

// Currently redundant unless the user refuses to fix ragged rows
function refactorColumns(csv_array) {
  col_add = getMaxColumns(csv_array) - hot.countCols()
  // adds a column by default if the amount parameter is 0, hence conditional
  if (col_add != 0) {
    hot.alter('insert_col', null, col_add)
  }
}

function getMaxColumns(csv_array) {
  max_columns = 0
  for (var i = 0; i < csv_array.length; i++) {
    col_length = csv_array[i].length
    if (col_length > max_columns) {
      max_columns = col_length
    }
  }
  return max_columns
}

// Fills undefined cells with an empty string, keeping the table in a
// rectangular format

function fixRaggedRows(csv_array) {
  ragged_rows = 0;
  //
  for (var y = 0; y < csv_array.length; y++) {
    for (var x = 0; x < getMaxColumns(csv_array); x++) {
      if (hot.getDataAtCell(y,x) === undefined || hot.getDataAtCell(y,x) === null) {
        if (ragged_rows == 0) {
          if (confirm("Your file has ragged rows, do you want to correct this?")) {
            ragged_rows = 1
            fixCell(csv_array,y,x)
          }
          else {ragged_rows = -1}
        }
        else if (ragged_rows == 1) {
          fixCell(csv_array,y,x)
        }
      }
    }
  }
  updateTable(csv_array)
}

function fixCell(csv_array,y,x) {
  csv_array[y].push("")
  console.log("Cell (" + String.fromCharCode(97 + x).toUpperCase() + "," + (y + 1) + ") has been added to file")
}

function updateTable(csv_array) {
  hot.updateSettings ({
    data: csv_array,
  });
}

$('button[data-dismiss=alert]').click(function() {
  $(this).parent('.alert').addClass('hidden')
})
<|endoftext|>


<commit_before>'use strict';

var EventEmitter = require('events').EventEmitter,
  Gpio = require('onoff').Gpio,
  Q = require('q'),
  util = require('util'),
  tick = global.setImmediate || process.nextTick;

var __ROW_OFFSETS = [0x00, 0x40, 0x14, 0x54];

var __COMMANDS = {
  CLEAR_DISPLAY: 0x01,
  HOME: 0x02,
  SET_CURSOR: 0x80,
  DISPLAY_ON: 0x04,
  DISPLAY_OFF: ~0x04,
  CURSOR_ON: 0x02,
  CURSOR_OFF: ~0x02,
  BLINK_ON: 0x01,
  BLINK_OFF: ~0x01,
  SCROLL_LEFT: 0x18,
  SCROLL_RIGHT: 0x1c,
  LEFT_TO_RIGHT: 0x02,
  RIGHT_TO_LEFT: ~0x02,
  AUTOSCROLL_ON: 0x01,
  AUTOSCROLL_OFF: ~0x01
};

function Lcd(config) {
  var i;

  if (!(this instanceof Lcd)) {
    return new Lcd(config);
  }

  EventEmitter.call(this);

  this.cols = config.cols || 16; // TODO - Never used, remove?
  this.rows = config.rows || 1;
  this.largeFont = !!config.largeFont;

  this.rs = new Gpio(config.rs, 'low'); // reg. select, output, initially low
  this.e = new Gpio(config.e, 'low'); // enable, output, initially low

  this.data = []; // data bus, db4 thru db7, outputs, initially low
  for (i = 0; i < config.data.length; i += 1) {
    this.data.push(new Gpio(config.data[i], 'low'));
  }

  this.displayControl = 0x0c; // display on, cursor off, cursor blink off
  this.displayMode = 0x06; // left to right, no shift

  this.asyncOps = [];

  this.init();
}

util.inherits(Lcd, EventEmitter);
module.exports = Lcd;

// private
Lcd.prototype.init = function () {
  Q.delay(16)                                               // wait > 15ms
  .then(function () { this._write4Bits(0x03); }.bind(this)) // 1st wake up
  .delay(6)                                                 // wait > 4.1ms
  .then(function () { this._write4Bits(0x03); }.bind(this)) // 2nd wake up
  .delay(2)                                                 // wait > 160us
  .then(function () { this._write4Bits(0x03); }.bind(this)) // 3rd wake up
  .delay(2)                                                 // wait > 160us
  .then(function () {
    var displayFunction = 0x20;

    this._write4Bits(0x02); // 4 bit interface

    if (this.rows > 1) {
      displayFunction |= 0x08;
    }
    if (this.rows === 1 && this.largeFont) {
      displayFunction |= 0x04;
    }
    this._command(displayFunction);

    this._command(0x10);
    this._command(this.displayControl);
    this._command(this.displayMode);

    this._command(0x01); // clear display (don't call clear to avoid event)
  }.bind(this))
  .delay(3)             // wait > 1.52ms for display to clear
  .then(function () { this.emit('ready'); }.bind(this));
};

Lcd.prototype.print = function (val, cb) {
  this._queueAsyncOperation(function (cb2) {
    var index,
      displayFills;

    val += '';

    // If n*80+m characters should be printed, where n>1, m<80, don't display the
    // first (n-1)*80 characters as they will be overwritten. For example, if
    // asked to print 802 characters, don't display the first 720.
    displayFills = Math.floor(val.length / 80);
    index = displayFills > 1 ? (displayFills - 1) * 80 : 0;

    this._printChar(val, index, cb, cb2);
  }.bind(this));
};

// private
Lcd.prototype._printChar = function (str, index, cb, cb2) {
  tick(function () {
    if (index >= str.length) {
      if (cb) {
        cb(null, str);
      } else {
        this.emit('printed', str);
      }

      return cb2(null);
    }

    try {
      this._write(str.charCodeAt(index));
      this._printChar(str, index + 1, cb, cb2);
    } catch (e) {
      if (cb) {
        cb(e);
      } else {
        this.emit('error', e);
      }

      return cb2(e);
    }
  }.bind(this));
};

Lcd.prototype.clear = function (cb) {
  this._queueAsyncOperation(function (cb2) {
    // Wait > 1.52ms. There were issues waiting for 2ms so wait 3ms.
    this._commandAndDelay(__COMMANDS.CLEAR_DISPLAY, 3, 'clear', cb, cb2);
  }.bind(this));
};

Lcd.prototype.home = function (cb) {
  this._queueAsyncOperation(function (cb2) {
    // Wait > 1.52ms. There were issues waiting for 2ms so wait 3ms.
    this._commandAndDelay(__COMMANDS.HOME, 3, 'home', cb, cb2);
  }.bind(this));
};

Lcd.prototype.setCursor = function (col, row) {
  var r = row > this.rows ? this.rows - 1 : row; //TODO: throw error instead? Seems like this could cause a silent bug.
  //we don't check for column because scrolling is a possibility. Should we check if it's in range if scrolling is off?
  this._command(__COMMANDS.SET_CURSOR | (col + __ROW_OFFSETS[r]));
};

Lcd.prototype.display = function () {
  this.displayControl |= __COMMANDS.DISPLAY_ON;
  this._command(this.displayControl);
};

Lcd.prototype.noDisplay = function () {
  this.displayControl &= __COMMANDS.DISPLAY_OFF;
  this._command(this.displayControl);
};

Lcd.prototype.cursor = function () {
  this.displayControl |= __COMMANDS.CURSOR_ON;
  this._command(this.displayControl);
};

Lcd.prototype.noCursor = function () {
  this.displayControl &= __COMMANDS.CURSOR_OFF;
  this._command(this.displayControl);
};

Lcd.prototype.blink = function () {
  this.displayControl |= __COMMANDS.BLINK_ON;
  this._command(this.displayControl);
};

Lcd.prototype.noBlink = function () {
  this.displayControl &= __COMMANDS.BLINK_OFF;
  this._command(this.displayControl);
};

Lcd.prototype.scrollDisplayLeft = function () {
  this._command(__COMMANDS.SCROLL_LEFT);
};

Lcd.prototype.scrollDisplayRight = function () {
  this._command(__COMMANDS.SCROLL_RIGHT);
};

Lcd.prototype.leftToRight = function () {
  this.displayMode |= __COMMANDS.LEFT_TO_RIGHT;
  this._command(this.displayMode);
};

Lcd.prototype.rightToLeft = function () {
  this.displayMode &= __COMMANDS.RIGHT_TO_LEFT;
  this._command(this.displayMode);
};

Lcd.prototype.autoscroll = function () {
  this.displayMode |= __COMMANDS.AUTOSCROLL_ON;
  this._command(this.displayMode);
};

Lcd.prototype.noAutoscroll = function () {
  this.displayMode &= __COMMANDS.AUTOSCROLL_OFF;
  this._command(this.displayMode);
};

Lcd.prototype.close = function () {
  var i;

  this.rs.unexport();
  this.e.unexport();

  for (i = 0; i < this.data.length; i += 1) {
    this.data[i].unexport();
  }
};

// private
Lcd.prototype._queueAsyncOperation = function (asyncOperation) {
  this.asyncOps.push(asyncOperation);

  if (this.asyncOps.length === 1) {
    (function next() {
      this.asyncOps[0](function () {
        this.asyncOps.shift();
        if (this.asyncOps.length !== 0) {
          next.bind(this)();
        }
      }.bind(this));
    }.bind(this)());
  }
}

// private
Lcd.prototype._commandAndDelay = function (command, timeout, event, cb, cb2) {
  tick(function () {
    try {
      this._command(command);
    } catch (e) {
      if (cb) {
        cb(e);
      } else {
        this.emit('error', e);
      }

      return cb2(e);
    }

    setTimeout(function () {
      if (cb) {
        cb(null);
      } else {
        this.emit(event);
      }

      return cb2(null);
    }.bind(this), timeout);
  }.bind(this));
};

// private
Lcd.prototype._command = function (cmd) {
  this._send(cmd, 0);
};

// private
Lcd.prototype._write = function (val) {
  this._send(val, 1);
};

// private
Lcd.prototype._send = function (val, mode) {
  this.rs.writeSync(mode);
  this._write4Bits(val >> 4);
  this._write4Bits(val);
};

// private
Lcd.prototype._write4Bits = function (val) {
  if(!(typeof val === 'number')){
    throw new Error("Value passed to ._write4Bits must be a number");
  }

  var i;

  for (i = 0; i < this.data.length; i += 1, val = val >> 1) {
    this.data[i].writeSync(val & 1);
  }

  // enable pulse >= 300ns
  // writeSync takes ~10 microseconds to execute on the BBB, so there's
  // nothing special needed to wait 300 nanoseconds.
  this.e.writeSync(1);
  this.e.writeSync(0);
};

<commit_msg>remove usage of process.nextTick<commit_after>'use strict';

var EventEmitter = require('events').EventEmitter,
  Gpio = require('onoff').Gpio,
  Q = require('q'),
  util = require('util');

var __ROW_OFFSETS = [0x00, 0x40, 0x14, 0x54];

var __COMMANDS = {
  CLEAR_DISPLAY: 0x01,
  HOME: 0x02,
  SET_CURSOR: 0x80,
  DISPLAY_ON: 0x04,
  DISPLAY_OFF: ~0x04,
  CURSOR_ON: 0x02,
  CURSOR_OFF: ~0x02,
  BLINK_ON: 0x01,
  BLINK_OFF: ~0x01,
  SCROLL_LEFT: 0x18,
  SCROLL_RIGHT: 0x1c,
  LEFT_TO_RIGHT: 0x02,
  RIGHT_TO_LEFT: ~0x02,
  AUTOSCROLL_ON: 0x01,
  AUTOSCROLL_OFF: ~0x01
};

function Lcd(config) {
  var i;

  if (!(this instanceof Lcd)) {
    return new Lcd(config);
  }

  EventEmitter.call(this);

  this.cols = config.cols || 16; // TODO - Never used, remove?
  this.rows = config.rows || 1;
  this.largeFont = !!config.largeFont;

  this.rs = new Gpio(config.rs, 'low'); // reg. select, output, initially low
  this.e = new Gpio(config.e, 'low'); // enable, output, initially low

  this.data = []; // data bus, db4 thru db7, outputs, initially low
  for (i = 0; i < config.data.length; i += 1) {
    this.data.push(new Gpio(config.data[i], 'low'));
  }

  this.displayControl = 0x0c; // display on, cursor off, cursor blink off
  this.displayMode = 0x06; // left to right, no shift

  this.asyncOps = [];

  this.init();
}

util.inherits(Lcd, EventEmitter);
module.exports = Lcd;

// private
Lcd.prototype.init = function () {
  Q.delay(16)                                               // wait > 15ms
  .then(function () { this._write4Bits(0x03); }.bind(this)) // 1st wake up
  .delay(6)                                                 // wait > 4.1ms
  .then(function () { this._write4Bits(0x03); }.bind(this)) // 2nd wake up
  .delay(2)                                                 // wait > 160us
  .then(function () { this._write4Bits(0x03); }.bind(this)) // 3rd wake up
  .delay(2)                                                 // wait > 160us
  .then(function () {
    var displayFunction = 0x20;

    this._write4Bits(0x02); // 4 bit interface

    if (this.rows > 1) {
      displayFunction |= 0x08;
    }
    if (this.rows === 1 && this.largeFont) {
      displayFunction |= 0x04;
    }
    this._command(displayFunction);

    this._command(0x10);
    this._command(this.displayControl);
    this._command(this.displayMode);

    this._command(0x01); // clear display (don't call clear to avoid event)
  }.bind(this))
  .delay(3)             // wait > 1.52ms for display to clear
  .then(function () { this.emit('ready'); }.bind(this));
};

Lcd.prototype.print = function (val, cb) {
  this._queueAsyncOperation(function (cb2) {
    var index,
      displayFills;

    val += '';

    // If n*80+m characters should be printed, where n>1, m<80, don't display the
    // first (n-1)*80 characters as they will be overwritten. For example, if
    // asked to print 802 characters, don't display the first 720.
    displayFills = Math.floor(val.length / 80);
    index = displayFills > 1 ? (displayFills - 1) * 80 : 0;

    this._printChar(val, index, cb, cb2);
  }.bind(this));
};

// private
Lcd.prototype._printChar = function (str, index, cb, cb2) {
  setImmediate(function () {
    if (index >= str.length) {
      if (cb) {
        cb(null, str);
      } else {
        this.emit('printed', str);
      }

      return cb2(null);
    }

    try {
      this._write(str.charCodeAt(index));
      this._printChar(str, index + 1, cb, cb2);
    } catch (e) {
      if (cb) {
        cb(e);
      } else {
        this.emit('error', e);
      }

      return cb2(e);
    }
  }.bind(this));
};

Lcd.prototype.clear = function (cb) {
  this._queueAsyncOperation(function (cb2) {
    // Wait > 1.52ms. There were issues waiting for 2ms so wait 3ms.
    this._commandAndDelay(__COMMANDS.CLEAR_DISPLAY, 3, 'clear', cb, cb2);
  }.bind(this));
};

Lcd.prototype.home = function (cb) {
  this._queueAsyncOperation(function (cb2) {
    // Wait > 1.52ms. There were issues waiting for 2ms so wait 3ms.
    this._commandAndDelay(__COMMANDS.HOME, 3, 'home', cb, cb2);
  }.bind(this));
};

Lcd.prototype.setCursor = function (col, row) {
  var r = row > this.rows ? this.rows - 1 : row; //TODO: throw error instead? Seems like this could cause a silent bug.
  //we don't check for column because scrolling is a possibility. Should we check if it's in range if scrolling is off?
  this._command(__COMMANDS.SET_CURSOR | (col + __ROW_OFFSETS[r]));
};

Lcd.prototype.display = function () {
  this.displayControl |= __COMMANDS.DISPLAY_ON;
  this._command(this.displayControl);
};

Lcd.prototype.noDisplay = function () {
  this.displayControl &= __COMMANDS.DISPLAY_OFF;
  this._command(this.displayControl);
};

Lcd.prototype.cursor = function () {
  this.displayControl |= __COMMANDS.CURSOR_ON;
  this._command(this.displayControl);
};

Lcd.prototype.noCursor = function () {
  this.displayControl &= __COMMANDS.CURSOR_OFF;
  this._command(this.displayControl);
};

Lcd.prototype.blink = function () {
  this.displayControl |= __COMMANDS.BLINK_ON;
  this._command(this.displayControl);
};

Lcd.prototype.noBlink = function () {
  this.displayControl &= __COMMANDS.BLINK_OFF;
  this._command(this.displayControl);
};

Lcd.prototype.scrollDisplayLeft = function () {
  this._command(__COMMANDS.SCROLL_LEFT);
};

Lcd.prototype.scrollDisplayRight = function () {
  this._command(__COMMANDS.SCROLL_RIGHT);
};

Lcd.prototype.leftToRight = function () {
  this.displayMode |= __COMMANDS.LEFT_TO_RIGHT;
  this._command(this.displayMode);
};

Lcd.prototype.rightToLeft = function () {
  this.displayMode &= __COMMANDS.RIGHT_TO_LEFT;
  this._command(this.displayMode);
};

Lcd.prototype.autoscroll = function () {
  this.displayMode |= __COMMANDS.AUTOSCROLL_ON;
  this._command(this.displayMode);
};

Lcd.prototype.noAutoscroll = function () {
  this.displayMode &= __COMMANDS.AUTOSCROLL_OFF;
  this._command(this.displayMode);
};

Lcd.prototype.close = function () {
  var i;

  this.rs.unexport();
  this.e.unexport();

  for (i = 0; i < this.data.length; i += 1) {
    this.data[i].unexport();
  }
};

// private
Lcd.prototype._queueAsyncOperation = function (asyncOperation) {
  this.asyncOps.push(asyncOperation);

  if (this.asyncOps.length === 1) {
    (function next() {
      this.asyncOps[0](function () {
        this.asyncOps.shift();
        if (this.asyncOps.length !== 0) {
          next.bind(this)();
        }
      }.bind(this));
    }.bind(this)());
  }
}

// private
Lcd.prototype._commandAndDelay = function (command, timeout, event, cb, cb2) {
  setImmediate(function () {
    try {
      this._command(command);
    } catch (e) {
      if (cb) {
        cb(e);
      } else {
        this.emit('error', e);
      }

      return cb2(e);
    }

    setTimeout(function () {
      if (cb) {
        cb(null);
      } else {
        this.emit(event);
      }

      return cb2(null);
    }.bind(this), timeout);
  }.bind(this));
};

// private
Lcd.prototype._command = function (cmd) {
  this._send(cmd, 0);
};

// private
Lcd.prototype._write = function (val) {
  this._send(val, 1);
};

// private
Lcd.prototype._send = function (val, mode) {
  this.rs.writeSync(mode);
  this._write4Bits(val >> 4);
  this._write4Bits(val);
};

// private
Lcd.prototype._write4Bits = function (val) {
  if(!(typeof val === 'number')){
    throw new Error("Value passed to ._write4Bits must be a number");
  }

  var i;

  for (i = 0; i < this.data.length; i += 1, val = val >> 1) {
    this.data[i].writeSync(val & 1);
  }

  // enable pulse >= 300ns
  // writeSync takes ~10 microseconds to execute on the BBB, so there's
  // nothing special needed to wait 300 nanoseconds.
  this.e.writeSync(1);
  this.e.writeSync(0);
};

<|endoftext|>


<commit_before>(function(){

    if(typeof(document.saw) !== object){
        document.saw = {};
    }

    function getDic(){
        var result = {};
        for (var i=0; i < 256; i++) {
            var ch = String.fromCharCode(i);
            result[ch] = i;
        };
        return result;
    }

    function tTable(){
        var result = {};
        for (var i=0; i < 256; i++) {
            var ch = String.fromCharCode(i);
            result[i] = ch;
        };
        return result;
    }

    var LZW = {

        encode:function(str){
            var index = 256;
            var dictionary = getDic();
            var outStr = [];
            var s = '';

            var len = str.length;
            s = str[0];
            for(var i=1; i < len; i++){
                var c = str[i];
                if(dictionary[s+c]){
                    s = s+c;
                }else{
                    //console.log(ch + 'sec');
                    var code = ++index;
                    outStr.push(String.fromCharCode(dictionary[s]));
                    dictionary[s+c] = code;
                    s = c;
                }
            }
            for(var c in s ){
                outStr.push(s[c]);
            }

            return outStr.join('');
        },

        decode:function(str){

             var table = tTable(),
             buffer = '',
             outStr = [];

            // outStr.push(str[0]);
             var first_code = str[0].charCodeAt(0);
             var len = str.length;
             var counter = 255;
             var character = '';
             for (var i=0; i < len; i++) {
                 var next_code = str[i].charCodeAt(0);

                 if(!table[next_code]){
                     buffer = table[first_code];
                     buffer = buffer + character;
                 }else{
                     buffer = table[next_code];

                 }

                 outStr.push(buffer);
                 character = buffer[0];
                 table[++counter] = table[first_code] +
                                    character;

                 first_code = next_code;

             };

             return outStr.join('');
        }

    };

    document.saw.lzw = LZW;

}());<commit_msg>rebuild as clean object<commit_after>(function(){

    //create "saw" global if not there
    if(window.saw === undefined){
        window.saw = {};
    }
    /**
     * Returns a pre-popuated dictionary to begin encoding
     * @private
     * @method getDic
     * @return {Object} result a hash table with ascii letters as keys
     */
    function getDic(){
        var result = {};
        for (var i=0; i < 256; i++) {
            var ch = String.fromCharCode(i);
            result[ch] = i;
        };
        return result;
    }

    /**
     * Prepopulates translation table
     * @private
     * @method tTable
     * @return {Object} translation table (hash table)
     */
    function tTable(){
        var result = {};
        for (var i=0; i < 256; i++) {
            var ch = String.fromCharCode(i);
            result[i] = ch;
        };
        return result;
    }

    //Define the object and public methods
    var LZW = {

        /**
         * Encodes the string as an LZW compressed binary stream...except
         * because we can't really use binary in javascript we are using the unicode
         * character specified by the decimal code output by the algorithm in each place
         *
         * @method encode
         * @param {String} str The string to encode
         * @return {String} str The encoded string
         */
        encode:function(str){
            var index = 256,
            dictionary = getDic(),
            outStr = [],
            s = '';

            var len = str.length,
            s = str[0];

            for(var i=1; i < len; i++){
                var c = str[i];
                if(dictionary[s+c]){
                    s = s+c;
                }else{
                    var code = ++index;

                    outStr.push(String.fromCharCode(dictionary[s]));
                    dictionary[s+c] = code;
                    s = c;
                }
            }
            for(var c in s ){
                outStr.push(s[c]);
            }

            return outStr.join('');
        },

        decode:function(str){

            //init translation table
             var table = tTable(),

             //buffer will store the string we are working on
             buffer = '',

             //store the characters in an array as they are added
             outStr = [],

             //init first_code
             first_code = str[0].charCodeAt(0),

             //get string length for loop
             len = str.length,

             //counter so we know where to start after the base table
             counter = 255,

             //this will be handy for the case where next_code does not exist in the table
             character = '';

             //main decode loop
             for (var i=0; i < len; i++) {
                 var next_code = str[i].charCodeAt(0);

                 if(!table[next_code]){ //handles the exception case
                     buffer = table[first_code];
                     buffer = buffer + character;
                 }else{
                     //add decoded char to buffer
                     buffer = table[next_code];
                 }

                 //add buffer to output
                 outStr.push(buffer);

                 character = buffer[0];
                 //add new substring to table
                 table[++counter] = table[first_code] +
                                    character;

                 //time for the next char
                 first_code = next_code;
             };

             return outStr.join('');
        },

        strSize:function(str){

            return encodeURIComponent(str).replace(/%../g, 'x').length;
        }

    };

    window.saw.lzw = LZW;

}());<|endoftext|>


<commit_before>var getQueryStringVal = function () {
    var vars = [], hash;
    var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
    for (var i = 0; i < hashes.length; i++) {
        hash = hashes[i].split('=');
        vars.push(hash[0]);
        vars[hash[0]] = hash[1];
    }
    return vars;
}
var myObj = getQueryStringVal();

var x = myObj.x.split(',');
var y = myObj.y.split(',');
var r = myObj.r.split(',');
var px = myObj.px.split(',');
var py = myObj.py.split(',');

function initMap() { // Create the map.
    var map = new google.maps.Map(document.getElementById('map'), {
        zoom: 6,
        center: { lat: parseFloat(x[0]), lng: parseFloat(y[0]) },
        mapTypeId: 'terrain'
    });
    for (var i = 0; i < x.length; i++) {
        try {
            var circle = new google.maps.Circle({ //Circle
                strokeColor: '#FF0000',
                strokeOpacity: 0.8,
                strokeWeight: 2,
                fillColor: '#FF0000',
                fillOpacity: 0.35,
                map: map,
                center: new google.maps.LatLng(parseFloat(x[i]), parseFloat(y[i])),
                radius: r[i] * 1000 //Converting Meters to KiloMeters
            });
        } catch (err) {
            console.log("Circle Failed: " + err);
        }
        var pathList = [];
        for (var j = 0; j < px.length ; j++) {
            pathList[j] = new google.maps.LatLng(parseFloat(px[j]), parseFloat(py[j]))
            var marker = new google.maps.Marker({ //Marker
                position: pathList[j],
                map: map
            });
        }
        try { //Polygonic Path
            var path = new google.maps.Polyline({
                path: pathList,
                strokeColor: "#0000FF",
                strokeOpacity: 0.8,
                map: map,
                strokeWeight: 2
            });
        } catch (err) {
            console.log("Path Failed: " + err);
        }
    }
}<commit_msg>Add files via upload<commit_after>var getQueryStringVal = function () {
    var vars = [], hash;
    var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
    for (var i = 0; i < hashes.length; i++) {
        hash = hashes[i].split('=');
        vars.push(hash[0]);
        vars[hash[0]] = hash[1];
    }
    return vars;
}
var myObj = getQueryStringVal();

var x = myObj.x.split(',');
var y = myObj.y.split(',');
var r = myObj.r.split(',');
var px = myObj.px.split(',');
var py = myObj.py.split(',');

function initMap() { // Create the map.
    var map = new google.maps.Map(document.getElementById('map'), {
        zoom: 6,
        center: { lat: parseFloat(x[0]), lng: parseFloat(y[0]) },
        mapTypeId: 'terrain'
    });
    for (var i = 0; i < x.length; i++) {
        try {
            var circle = new google.maps.Circle({ //Circle
                strokeColor: '#FF0000',
                strokeOpacity: 0.8,
                strokeWeight: 2,
                fillColor: '#FF0000',
                fillOpacity: 0.35,
                map: map,
                center: new google.maps.LatLng(parseFloat(x[i]), parseFloat(y[i])),
                radius: r[i] * 1000 //Converting Meters to KiloMeters
            });
        } catch (err) {
            console.log("Circle Failed: " + err);
        }
        try {
            var pathList = [];
            for (var j = 0; j < px.length ; j++) {
                pathList[j] = new google.maps.LatLng(parseFloat(px[j]), parseFloat(py[j]))
                var marker = new google.maps.Marker({ //Marker
                    position: pathList[j],
                    map: map
                });
            }
            try { //Polygonic Path
                var path = new google.maps.Polyline({
                    path: pathList,
                    strokeColor: "#0000FF",
                    strokeOpacity: 0.8,
                    map: map,
                    strokeWeight: 2
                });
            } catch (err) {
                console.log("Path Failed: " + err);
            }
        } catch (e) {
            console.log("No Path data found: " + e);
        }
    }
}<|endoftext|>


<commit_before>
// Testing Leaflet map
// REMEMBER TO COMMENT-IN ALSO Leadlet & Geohash libraries

var mymap;
var circleGroup;
var largestDoc_count;

function initMap()
{
    options.species = $("#species").val();

    if (undefined == mymap)
    {
        // http://stackoverflow.com/questions/37166172/mapbox-tiles-and-leafletjs
        mymap = L.map('mymap').setView([60, 14], 5);
        L.tileLayer('https://api.mapbox.com/styles/v1/mapbox/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}', {
            attribution: 'Map data © OpenStreetMap contributors, CC-BY-SA, Imagery © Mapbox',
            maxZoom: 18,
            id: 'light-v9', // streets-v9 satellite-streets-v9 light-v9 dark-v9 outdoors-v9
            accessToken: mapboxAccessToken
        }).addTo(mymap);
    }

    clearMap();
    getTaxonMap();
}

function clearMap() {
    // Remove old markers
    if (undefined != circleGroup)
    {
        mymap.removeLayer(circleGroup);
        largestDoc_count = undefined;
    }

    // Adjust height to fit screen
    let formBottom = $("#form").offset().top + $("#form").height(); // Calculate using form element, because mymap gives oddly large top value
    let mapHeight = $(window).height() - formBottom - 40; // margins
    $("#mymap").height(mapHeight);
    console.log("Adjusted map height to " + mapHeight);
}

function getTaxonMap()
{
    let queryObject = {
        "size" : 0,
        "query" : {
            "term" : {
                "species" : options.species
            }
        },
        "aggregations" : {
            "grid" : {
                "geohash_grid" : {
                    "field" : "coordinates",
                    "precision" : 4
                }
            }
        }
    };

    console.log(queryObject);

    let callback = function(elasticData) {

        let count = elasticData.hits.total;
        if (0 == count) {
            console.log("DATA MISSING, count == " + count);
            $("#ladda").html("");
            $("#total").text("Species not found");
            $("#container").html("");
        }
        else {
            console.log("FOUND DATA, count == " + count);
            // Leaflet map
            console.log("Mapdata:");
            console.log(elasticData);

            $("#heading").text(options.species);
            drawMap(elasticData);

            // Show count
            let countFormatted = count.toLocaleString();
            $("#total").text(countFormatted + " occurrences");
        }
    };

    elasticQueryModule.query(queryObject, callback);
}

function drawMap(elasticData) {
    let buckets = elasticData.aggregations.grid.buckets;
    let circles = [];

    for (let i = 0; i < buckets.length; i++) {
//      console.log(buckets[i]);
        circles.push(createMarker(buckets[i]));
    }

    circleGroup = L.layerGroup(circles);
    circleGroup.addTo(mymap);

    $("#ladda").html("");
}

function createMarker(bucket)
{
    let coordinateObject = Geohash.decode(bucket.key);

    if (undefined == largestDoc_count)
    {
        largestDoc_count = bucket.doc_count;
    }
    let size = Math.floor(bucket.doc_count / largestDoc_count * 15000);

    let circle = L.circle([coordinateObject.lat, coordinateObject.lon], {
        color: '#006AA7',
        fillColor: '#006AA7',
        fillOpacity: 0.5,
        radius: size
    })
//    console.log(circle);
    circle.bindPopup(bucket.doc_count + " occurrences");
    return circle;
}

<commit_msg>Result count relative to marker area<commit_after>
// Testing Leaflet map
// REMEMBER TO COMMENT-IN ALSO Leadlet & Geohash libraries

var mymap;
var circleGroup;
var largestDoc_count;

function initMap()
{
    options.species = $("#species").val();

    if (undefined == mymap)
    {
        // http://stackoverflow.com/questions/37166172/mapbox-tiles-and-leafletjs
        mymap = L.map('mymap').setView([62, 13], 5);
        L.tileLayer('https://api.mapbox.com/styles/v1/mapbox/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}', {
            attribution: 'Map data © OpenStreetMap contributors, CC-BY-SA, Imagery © Mapbox',
            maxZoom: 18,
            id: 'light-v9', // streets-v9 satellite-streets-v9 light-v9 dark-v9 outdoors-v9
            accessToken: mapboxAccessToken
        }).addTo(mymap);
    }

    clearMap();
    getTaxonMap();
}

function clearMap() {
    // Remove old markers
    if (undefined != circleGroup)
    {
        mymap.removeLayer(circleGroup);
        largestDoc_count = undefined;
    }

    // Adjust height to fit screen
    let formBottom = $("#form").offset().top + $("#form").height(); // Calculate using form element, because mymap gives oddly large top value
    let mapHeight = $(window).height() - formBottom - 40; // margins
    $("#mymap").height(mapHeight);
    console.log("Adjusted map height to " + mapHeight);
}

function getTaxonMap()
{
    let queryObject = {
        "size" : 0,
        "query" : {
            "term" : {
                "species" : options.species
            }
        },
        "aggregations" : {
            "grid" : {
                "geohash_grid" : {
                    "field" : "coordinates",
                    "precision" : 4
                }
            }
        }
    };

    console.log(queryObject);

    let callback = function(elasticData) {

        let count = elasticData.hits.total;
        if (0 == count) {
            console.log("DATA MISSING, count == " + count);
            $("#ladda").html("");
            $("#total").text("Species not found");
            $("#container").html("");
        }
        else {
            console.log("FOUND DATA, count == " + count);
            // Leaflet map
            console.log("Mapdata:");
            console.log(elasticData);

            $("#heading").text(options.species);
            drawMap(elasticData);

            // Show count
            let countFormatted = count.toLocaleString();
            $("#total").text(countFormatted + " occurrences");
        }
    };

    elasticQueryModule.query(queryObject, callback);
}

function drawMap(elasticData) {
    let buckets = elasticData.aggregations.grid.buckets;
    let circles = [];

    for (let i = 0; i < buckets.length; i++) {
//      console.log(buckets[i]);
        circles.push(createMarker(buckets[i]));
    }

    circleGroup = L.layerGroup(circles);
    circleGroup.addTo(mymap);

    $("#ladda").html("");
}

function createMarker(bucket)
{
    let coordinateObject = Geohash.decode(bucket.key);

    if (undefined == largestDoc_count)
    {
        largestDoc_count = bucket.doc_count;
    }

//    let radius = Math.floor(bucket.doc_count / largestDoc_count * 15000); // radius grows linearly
    let radius = Math.sqrt(bucket.doc_count / largestDoc_count / Math.PI) * 20000; // Area grows linearly

    let circle = L.circle([coordinateObject.lat, coordinateObject.lon], {
        color: '#006AA7',
        fillColor: '#006AA7',
        fillOpacity: 0.5,
        weight: 1,
        radius: Math.floor(radius)
    })
//    console.log("r = " + radius);
    circle.bindPopup(bucket.doc_count + " occurrences");
    return circle;
}

<|endoftext|>


<commit_before>// Copyright (c) 2015 Mapzen
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// Based on code by Patrick.Brockmann@lsce.ipsl.fr, see
// http://bl.ocks.org/PBrockmann/raw/230f567762de650953b5/

var cities_data = {},
    data_keys = ["km_new_roads", "inland_water_area_named", "km_new_oneways", "total_road_segments",
					  "building_address_count", "building_area", "inland_water_length_named",
					  "km_edits_to_existing_oneways", "building_count", "km_new_named_roads",
					  "km_edits_to_existing_named_roads", "km_edits_to_existing_roads",
					  "inland_water_length", "inland_water_area", "aerialway_count"];

$("#slider").slider({
	 value: 2015,
	 min: 2008,
	 max: 2015,
	 step: 1,
	 slide: function( event, ui ) {
		  $("#year").val(ui.value);
		  redraw(ui.value.toString());
		  }
});
$("#year").val($("#slider").slider("value") );

	 var w = 900;
	 var h = 500;
var selected_cities = {};

	 var xy = d3.geo.equirectangular()
        .scale(150);

	 var path = d3.geo.path()
		  .projection(xy);

	 var svg = d3.select("#graph").insert("svg:svg")
		  .attr("width", w)
        .attr("height", h);

	 var states = svg.append("svg:g")
		  .attr("id", "states");

	 var circles = svg.append("svg:g")
		  .attr("id", "circles");

	 var labels = svg.append("svg:g")
		  .attr("id", "labels");

	 d3.json("world-countries.json", function(collection) {
		  states.selectAll("path")
				.data(collection.features)
				.enter().append("svg:path")
				.attr("d", path)
            .on("mouseover", function(d) {
                d3.select(this).style("fill","#6C0")
                    .append("svg:title")
                    .text(d.properties.name);})
            .on("mouseout", function(d) {
                d3.select(this).style("fill","#ccc");});
	 });

	 var scalefactor=1/50.0 ;
	 var chart = null,
    last_selected = [],
    last_column = '';

	 function update_graph() {
		  var colelem = document.getElementById("column"),
        column = colelem[colelem.selectedIndex].value,
        coltext = colelem[colelem.selectedIndex].innerText;
		  var year = document.getElementById("slider").value || "2015";

		  var max_val = 0.0;
		  var gdata = Object.keys(cities_data).map(function(city_name) {
				var cdata = cities_data[city_name];
				obj = {}
				obj.name = city_name;
				obj.lat = 0.5 * (cdata.bbox[1] + cdata.bbox[3]);
				obj.lon = 0.5 * (cdata.bbox[0] + cdata.bbox[2]);
				Object.keys(cdata)
					 .filter(function(k) {
						  return isFinite(+k);
					 })
					 .map(function(k) {
						  var val = cdata[k][column];
						  if (val > max_val) { max_val = val; }
						  obj[k] = val;
					 });
				return obj;
		  });
		  scalefactor = 40.0 / Math.sqrt(max_val);

		  var circ_update = circles.selectAll("circle")
				.data(gdata);

		  circ_update
				.enter()
				.append("svg:circle")
				.attr("cx", function(d, i) { return xy([d.lon,d.lat])[0]; })
				.attr("cy", function(d, i) { return xy([d.lon,d.lat])[1]; })
            .on("mouseover", function(d) {
                d3.select(this).classed("over", true);})
            .on("mouseout", function(d) {
                d3.select(this).classed("over", false);})
				.on("click", function(d) {
					 var sel = d3.select(this);
					 if (sel.classed("selected")) {
						  sel.classed("selected", false);
						  delete selected_cities[d.name];
						  update_chart();
					 } else {
						  sel.classed("selected", true);
						  selected_cities[d.name] = true;
						  update_chart();
					 }
				});

		  circ_update
				.attr("r",  function(d) { return Math.sqrt(+d[year])*scalefactor; })
				.attr("title",  function(d) { return d["name"]+": "+Math.round(d[year]); });

		  circ_update.exit().remove();
	 }

	 function redraw(year) {
        circles.selectAll("circle")
				.transition()
				.duration(1000).ease("linear")
				.attr("r",  function(d) { return Math.sqrt(+d[year])*scalefactor; })
				.attr("title",  function(d) { return d["name"]+": "+Math.round(d[year]); });

        labels.selectAll("text")
				.text(function(d) { return Math.round(d[year]); });
	 }

var chart = null,
    last_selected = {},
    last_column = '';

function update_chart() {
  var colelem = document.getElementById("column"),
      column = colelem[colelem.selectedIndex].value,
      coltext = colelem[colelem.selectedIndex].innerText;

	 Object.keys(selected_cities).map(function(city_name) {
	 	  if (last_selected[city_name] &&
	 			column == last_column) {
	 			return;
	 	  }

	 	  var city_data = cities_data[city_name];

	 	  city_data = Object.keys(city_data)
	 			.filter(function(k) {
	 				 return isFinite(+k);
	 			})
	 			.map(function(k) {
	 				 obj = {}
	 				 obj.year = "" + k + "-01-01";
	 				 obj[city_name] = city_data[k][column];
	 				 return obj;
	 			});

	 	  if (chart) {
	 			chart.load({
	 				 id: city_name,
	 				 json: city_data,
	 				 type: 'line',
	 				 keys: {
	 					  x: 'year',
	 					  value: [city_name]
	 				 }
	 			});
	 	  } else {
	 			chart = c3.generate({
	 				 bindto: '#chart',
	 				 data: {
	 					  id: city_name,
	 					  json: city_data,
	 					  type: 'line',
	 					  keys: {
	 							x: 'year',
	 							value: [city_name]
	 					  }
	 				 },
	 				 axis: {
	 					  x: {
	 							type: 'timeseries',
	 							tick: {
	 								 format: '%Y-%m-%d'
	 							}
	 					  }
	 				 }
	 			});
	 	  }
    });

	 Object.keys(last_selected).map(function(city_name) {
	 	  if (!selected_cities[city_name]) {
	 			chart.unload(city_name);
	 	  }
	 });

	 last_selected = {};
	 Object.keys(selected_cities).map(function(city_name) {
		  last_selected[city_name] = true;
	 });
	 last_column = column;
}

function load_data(city) {
	 // TODO: put proper, public URL in here!
	 d3.json("/" + city + ".json", function(json) {

		  Object.keys(json).map(function(d) {
				if (isFinite(+d)) {
					 Object.keys(d).map(function(r) {
						  if (data_keys.indexOf(r) == -1) {
								delete d[r];
						  }
					 });
				}
		  });

		  cities_data[city] = json;
		  update_graph();
	 });
}

load_data("aarhus_denmark");
load_data("abidjan_ivory_coast");
load_data("abuja_nigeria");
load_data("accra_ghana");
load_data("adelaide_australia");
load_data("albany_new_york");
load_data("amsterdam_netherlands");
load_data("athens_greece");
load_data("atlanta_georgia");
load_data("auckland_new_zealand");
load_data("austin_texas");
load_data("bangkok_thailand");
load_data("barcelona_spain");
load_data("beijing_china");
load_data("berlin_germany");
load_data("bogota_colombia");
load_data("boston_massachusetts");
load_data("brasilia_brazil");
load_data("brisbane_australia");
load_data("brussels_belgium");
load_data("bucharest_romania");
load_data("budapest_hungary");
load_data("buenos_aires_argentina");
load_data("cairo_egypt");
load_data("cape_town_south_africa");
load_data("chennai_india");
load_data("chicago_illinois");
load_data("copenhagen_denmark");
load_data("dallas_texas");
load_data("dc_baltimore_maryland");
load_data("denver_boulder_colorado");
load_data("detroit_michigan");
load_data("dubai_abu_dhabi");
load_data("dublin_ireland");
load_data("edinburgh_scotland");
load_data("frankfurt_germany");
load_data("hong_kong_china");
load_data("houston_texas");
load_data("hyderabad_india");
load_data("istanbul_turkey");
load_data("jakarta_indonesia");
load_data("johannesburg_south_africa");
load_data("krakow_poland");
load_data("kuala_lumpur_malaysia");
load_data("kyiv_ukraine");
load_data("lagos_nigeria");
load_data("lisbon_portugal");
load_data("london_england");
load_data("los_angeles_california");
load_data("lyon_france");
load_data("madrid_spain");
load_data("manchester_england");
load_data("manila_philippines");
load_data("melbourne_australia");
load_data("mexico_city_mexico");
load_data("miami_florida");
load_data("milan_italy");
load_data("minsk_belarus");
load_data("montreal_canada");
load_data("moscow_russia");
load_data("mumbai_india");
load_data("naples_italy");
load_data("new_delhi_india");
load_data("new_orleans_louisiana");
load_data("new_york_new_york");
load_data("oslo_norway");
load_data("ottawa_canada");
load_data("perth_australia");
load_data("philadelphia_pennsylvania");
load_data("portland_oregon");
load_data("prague_czech_republic");
load_data("saint_petersburg_russia");
load_data("san_diego_tijuana_mexico");
load_data("san_francisco_bay_california");
load_data("san_francisco_california");
load_data("san_jose_california");
load_data("santiago_chile");
load_data("sao_paulo_brazil");
load_data("seattle_washington");
load_data("seoul_south_korea");
load_data("shanghai_china");
load_data("singapore");
load_data("sydney_australia");
load_data("taipei_taiwan");
load_data("tel_aviv_israel");
load_data("tokyo_japan");
load_data("toronto_canada");
load_data("vancouver_canada");
load_data("venice_italy");
load_data("warsaw_poland");
load_data("zurich_switzerland");
<commit_msg>Point to S3 bucket.<commit_after>// Copyright (c) 2015 Mapzen
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// Based on code by Patrick.Brockmann@lsce.ipsl.fr, see
// http://bl.ocks.org/PBrockmann/raw/230f567762de650953b5/

var cities_data = {},
    data_keys = ["km_new_roads", "inland_water_area_named", "km_new_oneways", "total_road_segments",
					  "building_address_count", "building_area", "inland_water_length_named",
					  "km_edits_to_existing_oneways", "building_count", "km_new_named_roads",
					  "km_edits_to_existing_named_roads", "km_edits_to_existing_roads",
					  "inland_water_length", "inland_water_area", "aerialway_count"];

$("#slider").slider({
	 value: 2015,
	 min: 2008,
	 max: 2015,
	 step: 1,
	 slide: function( event, ui ) {
		  $("#year").val(ui.value);
		  redraw(ui.value.toString());
		  }
});
$("#year").val($("#slider").slider("value") );

	 var w = 900;
	 var h = 500;
var selected_cities = {};

	 var xy = d3.geo.equirectangular()
        .scale(150);

	 var path = d3.geo.path()
		  .projection(xy);

	 var svg = d3.select("#graph").insert("svg:svg")
		  .attr("width", w)
        .attr("height", h);

	 var states = svg.append("svg:g")
		  .attr("id", "states");

	 var circles = svg.append("svg:g")
		  .attr("id", "circles");

	 var labels = svg.append("svg:g")
		  .attr("id", "labels");

	 d3.json("world-countries.json", function(collection) {
		  states.selectAll("path")
				.data(collection.features)
				.enter().append("svg:path")
				.attr("d", path)
            .on("mouseover", function(d) {
                d3.select(this).style("fill","#6C0")
                    .append("svg:title")
                    .text(d.properties.name);})
            .on("mouseout", function(d) {
                d3.select(this).style("fill","#ccc");});
	 });

	 var scalefactor=1/50.0 ;
	 var chart = null,
    last_selected = [],
    last_column = '';

	 function update_graph() {
		  var colelem = document.getElementById("column"),
        column = colelem[colelem.selectedIndex].value,
        coltext = colelem[colelem.selectedIndex].innerText;
		  var year = document.getElementById("slider").value || "2015";

		  var max_val = 0.0;
		  var gdata = Object.keys(cities_data).map(function(city_name) {
				var cdata = cities_data[city_name];
				obj = {}
				obj.name = city_name;
				obj.lat = 0.5 * (cdata.bbox[1] + cdata.bbox[3]);
				obj.lon = 0.5 * (cdata.bbox[0] + cdata.bbox[2]);
				Object.keys(cdata)
					 .filter(function(k) {
						  return isFinite(+k);
					 })
					 .map(function(k) {
						  var val = cdata[k][column];
						  if (val > max_val) { max_val = val; }
						  obj[k] = val;
					 });
				return obj;
		  });
		  scalefactor = 40.0 / Math.sqrt(max_val);

		  var circ_update = circles.selectAll("circle")
				.data(gdata);

		  circ_update
				.enter()
				.append("svg:circle")
				.attr("cx", function(d, i) { return xy([d.lon,d.lat])[0]; })
				.attr("cy", function(d, i) { return xy([d.lon,d.lat])[1]; })
            .on("mouseover", function(d) {
                d3.select(this).classed("over", true);})
            .on("mouseout", function(d) {
                d3.select(this).classed("over", false);})
				.on("click", function(d) {
					 var sel = d3.select(this);
					 if (sel.classed("selected")) {
						  sel.classed("selected", false);
						  delete selected_cities[d.name];
						  update_chart();
					 } else {
						  sel.classed("selected", true);
						  selected_cities[d.name] = true;
						  update_chart();
					 }
				});

		  circ_update
				.attr("r",  function(d) { return Math.sqrt(+d[year])*scalefactor; })
				.attr("title",  function(d) { return d["name"]+": "+Math.round(d[year]); });

		  circ_update.exit().remove();
	 }

	 function redraw(year) {
        circles.selectAll("circle")
				.transition()
				.duration(1000).ease("linear")
				.attr("r",  function(d) { return Math.sqrt(+d[year])*scalefactor; })
				.attr("title",  function(d) { return d["name"]+": "+Math.round(d[year]); });

        labels.selectAll("text")
				.text(function(d) { return Math.round(d[year]); });
	 }

var chart = null,
    last_selected = {},
    last_column = '';

function update_chart() {
  var colelem = document.getElementById("column"),
      column = colelem[colelem.selectedIndex].value,
      coltext = colelem[colelem.selectedIndex].innerText;

	 Object.keys(selected_cities).map(function(city_name) {
	 	  if (last_selected[city_name] &&
	 			column == last_column) {
	 			return;
	 	  }

	 	  var city_data = cities_data[city_name];

	 	  city_data = Object.keys(city_data)
	 			.filter(function(k) {
	 				 return isFinite(+k);
	 			})
	 			.map(function(k) {
	 				 obj = {}
	 				 obj.year = "" + k + "-01-01";
	 				 obj[city_name] = city_data[k][column];
	 				 return obj;
	 			});

	 	  if (chart) {
	 			chart.load({
	 				 id: city_name,
	 				 json: city_data,
	 				 type: 'line',
	 				 keys: {
	 					  x: 'year',
	 					  value: [city_name]
	 				 }
	 			});
	 	  } else {
	 			chart = c3.generate({
	 				 bindto: '#chart',
	 				 data: {
	 					  id: city_name,
	 					  json: city_data,
	 					  type: 'line',
	 					  keys: {
	 							x: 'year',
	 							value: [city_name]
	 					  }
	 				 },
	 				 axis: {
	 					  x: {
	 							type: 'timeseries',
	 							tick: {
	 								 format: '%Y-%m-%d'
	 							}
	 					  }
	 				 }
	 			});
	 	  }
    });

	 Object.keys(last_selected).map(function(city_name) {
	 	  if (!selected_cities[city_name]) {
	 			chart.unload(city_name);
	 	  }
	 });

	 last_selected = {};
	 Object.keys(selected_cities).map(function(city_name) {
		  last_selected[city_name] = true;
	 });
	 last_column = column;
}

function load_data(city) {
	 d3.json("http://planet.us-east-1.mapzen.com.s3.amazonaws.com/history-analysis/json/" + city + ".json", function(json) {

		  Object.keys(json).map(function(d) {
				if (isFinite(+d)) {
					 Object.keys(d).map(function(r) {
						  if (data_keys.indexOf(r) == -1) {
								delete d[r];
						  }
					 });
				}
		  });

		  cities_data[city] = json;
		  update_graph();
	 });
}

load_data("aarhus_denmark");
load_data("abidjan_ivory_coast");
load_data("abuja_nigeria");
load_data("accra_ghana");
load_data("adelaide_australia");
load_data("albany_new_york");
load_data("amsterdam_netherlands");
load_data("athens_greece");
load_data("atlanta_georgia");
load_data("auckland_new_zealand");
load_data("austin_texas");
load_data("bangkok_thailand");
load_data("barcelona_spain");
load_data("beijing_china");
load_data("berlin_germany");
load_data("bogota_colombia");
load_data("boston_massachusetts");
load_data("brasilia_brazil");
load_data("brisbane_australia");
load_data("brussels_belgium");
load_data("bucharest_romania");
load_data("budapest_hungary");
load_data("buenos_aires_argentina");
load_data("cairo_egypt");
load_data("cape_town_south_africa");
load_data("chennai_india");
load_data("chicago_illinois");
load_data("copenhagen_denmark");
load_data("dallas_texas");
load_data("dc_baltimore_maryland");
load_data("denver_boulder_colorado");
load_data("detroit_michigan");
load_data("dubai_abu_dhabi");
load_data("dublin_ireland");
load_data("edinburgh_scotland");
load_data("frankfurt_germany");
load_data("hong_kong_china");
load_data("houston_texas");
load_data("hyderabad_india");
load_data("istanbul_turkey");
load_data("jakarta_indonesia");
load_data("johannesburg_south_africa");
load_data("krakow_poland");
load_data("kuala_lumpur_malaysia");
load_data("kyiv_ukraine");
load_data("lagos_nigeria");
load_data("lisbon_portugal");
load_data("london_england");
load_data("los_angeles_california");
load_data("lyon_france");
load_data("madrid_spain");
load_data("manchester_england");
load_data("manila_philippines");
load_data("melbourne_australia");
load_data("mexico_city_mexico");
load_data("miami_florida");
load_data("milan_italy");
load_data("minsk_belarus");
load_data("montreal_canada");
load_data("moscow_russia");
load_data("mumbai_india");
load_data("naples_italy");
load_data("new_delhi_india");
load_data("new_orleans_louisiana");
load_data("new_york_new_york");
load_data("oslo_norway");
load_data("ottawa_canada");
load_data("perth_australia");
load_data("philadelphia_pennsylvania");
load_data("portland_oregon");
load_data("prague_czech_republic");
load_data("saint_petersburg_russia");
load_data("san_diego_tijuana_mexico");
load_data("san_francisco_bay_california");
load_data("san_francisco_california");
load_data("san_jose_california");
load_data("santiago_chile");
load_data("sao_paulo_brazil");
load_data("seattle_washington");
load_data("seoul_south_korea");
load_data("shanghai_china");
load_data("singapore");
load_data("sydney_australia");
load_data("taipei_taiwan");
load_data("tel_aviv_israel");
load_data("tokyo_japan");
load_data("toronto_canada");
load_data("vancouver_canada");
load_data("venice_italy");
load_data("warsaw_poland");
load_data("zurich_switzerland");
<|endoftext|>