<commit_before>  /*Application global vars*/
  var year            = 2003;
  var compare         = 'ninguna';
  var state           = "mapa";

  $(document).ready(function(){

    //Deep linking management
    var route = window.location.hash.replace('#','').split('/');
    goToHash(route);
  });

  function initializeApp() {
    initializeWelcomeWindow(); // initialize welcomewindow
    initializeGraph();         // initialize graph
    initializeHeader();        // initialize header options (selects and more) and graph/map menu
    initializeMap();           // initialize map and map modules
    initializeKeyBindings();   // initialize key bindings
  }

  function initializeKeyBindings() {
    $(document).keyup(function(e) {
      if (e.keyCode == 27) {
        $("#welcomewindow").fadeOut();
        explanationwindow.hide();
        comparewindow.hide();
        if (state == "grafico") {
          graphBubbleInfowindow.hide();
        } else {
          infowindow.hide();
        }
      }
    });
  }

  function goToHash(route) {
    //Check variable application state
    if (route[0]!="mapa" && route[0]!="grafico") {
      initializeApp();
      return false;
    }

    // //Check variable of compare
    if (!$('div.option_list ul li a.'+route[5]).length) {
      initializeApp();
      return false;
    }

    // Check length of the array
    if (route.length!=8) {
      initializeApp();
      return false;
    }

    // Check provincia-autonomia-municipio
    if (route[6]!="autonomias" && route[6]!="municipios" && route[6]!="provincias") {
      initializeApp();
      return false;
    }

    //check 1-num 2-num 3-num 4-year 5-string
    if (isNaN(route[1]) || isNaN(route[2]) || isNaN(route[3]) || isNaN(route[4]) || route[4].length!=4 || !isNaN(route[5])) {
      initializeApp();
      return false;
    }

    // Check zoom
    if (route[3]>12 || route[3]<6) {
      initializeApp();
      return false;
    }

    //All ok - change variables!
    start_center = new google.maps.LatLng(parseFloat(route[1]),parseFloat(route[2]));
    start_zoom = parseInt(route[3]);
    year = parseInt(route[4]);
    state = route[0];
    $("div.year_slider").slider("value",year);
    compare = route[5].replace(/_/g," ");
    deep = route[6];
    name = route[7];
    var value = $('div.option_list ul li a.'+route[5]).text();
    // Remove selected variable
    $('div.option_list ul li.selected').each(function(i,ele){$(ele).removeClass('selected');});
    $('div.select').each(function(i,ele){$(ele).removeClass('selected');});
    $('div.select span.inner_select a').each(function(i,ele){var text = $(ele).attr('title'); $(ele).text(text);});
    // Add new selected variable
    $('div.option_list ul li a.'+route[5]).closest('li').addClass('selected');
    $('div.option_list ul li a.'+route[5]).closest('div.select').addClass('selected');
    $('div.option_list ul li a.'+route[5]).closest('div.select').find('span.inner_select a').text(value);

    initializeApp();
  }

  function initializeWelcomeWindow() {
    $("#welcomewindow a.close_info").click(function(ev) {
      ev.stopPropagation();
      ev.preventDefault();
      $("#welcomewindow").fadeOut("slow");
    });

    $("#welcomewindow a.start").click(function(ev) {
      ev.stopPropagation();
      ev.preventDefault();
      $("#welcomewindow").fadeOut("slow");

        var text = $("div.select div.option_list ul li a.paro").text();
        $("div.select div.outer_select.money").parent().addClass("selected");
        $("div.select div.outer_select.money span.inner_select a").text(text);
        $("div.select div.option_list ul li a.paro").parent().addClass("selected");
        compare = "paro";

        if (year < 2005) { // because we don't have paro information prior 2005
          updateNewSliderValue(2005, year);
        }
        changeHash();
    });

    $("#welcomewindow a.explore").click(function(ev) {
      ev.stopPropagation();
      ev.preventDefault();
      $("#welcomewindow").fadeOut("slow");
    });

    $("#welcomewindow a.more_info").click(function(ev) {
      ev.stopPropagation();
      ev.preventDefault();
      $("#welcomewindow").fadeOut("slow", function() {
        explanationwindow.show();
      });
    });

    $("#welcomewindow a.know_more").click(function(ev) {
      ev.stopPropagation();
      ev.preventDefault();
      $("#welcomewindow").fadeOut("slow");
    });
  }

  function changeHash() {
    var latlng = peninsula.getCenter();
    var zoom = peninsula.getZoom();
    var hash = "#"+ state + "/" + latlng.lat().toFixed(3)+"/"+latlng.lng().toFixed(3)+"/"+zoom+"/"+year+"/"+compare.replace(/ /g,'_')+"/"+deep+"/"+name;
    window.location.hash = hash;
    updateWadusText();
  }
<commit_msg>Added binding to body so we can close the welcomewindow on clicking outside<commit_after>  /*Application global vars*/
  var year            = 2003;
  var compare         = 'ninguna';
  var state           = "mapa";

  $(document).ready(function(){

    //Deep linking management
    var route = window.location.hash.replace('#','').split('/');
    goToHash(route);
  });

  function initializeApp() {
    initializeWelcomeWindow(); // initialize welcomewindow
    initializeGraph();         // initialize graph
    initializeHeader();        // initialize header options (selects and more) and graph/map menu
    initializeMap();           // initialize map and map modules
    initializeKeyBindings();   // initialize key bindings
  }

  function initializeKeyBindings() {
    $(document).keyup(function(e) {
      if (e.keyCode == 27) {
        $("#welcomewindow").fadeOut();
        explanationwindow.hide();
        comparewindow.hide();
        if (state == "grafico") {
          graphBubbleInfowindow.hide();
        } else {
          infowindow.hide();
        }
      }
    });
  }

  function goToHash(route) {
    //Check variable application state
    if (route[0]!="mapa" && route[0]!="grafico") {
      initializeApp();
      return false;
    }

    // //Check variable of compare
    if (!$('div.option_list ul li a.'+route[5]).length) {
      initializeApp();
      return false;
    }

    // Check length of the array
    if (route.length!=8) {
      initializeApp();
      return false;
    }

    // Check provincia-autonomia-municipio
    if (route[6]!="autonomias" && route[6]!="municipios" && route[6]!="provincias") {
      initializeApp();
      return false;
    }

    //check 1-num 2-num 3-num 4-year 5-string
    if (isNaN(route[1]) || isNaN(route[2]) || isNaN(route[3]) || isNaN(route[4]) || route[4].length!=4 || !isNaN(route[5])) {
      initializeApp();
      return false;
    }

    // Check zoom
    if (route[3]>12 || route[3]<6) {
      initializeApp();
      return false;
    }

    //All ok - change variables!
    start_center = new google.maps.LatLng(parseFloat(route[1]),parseFloat(route[2]));
    start_zoom = parseInt(route[3]);
    year = parseInt(route[4]);
    state = route[0];
    $("div.year_slider").slider("value",year);
    compare = route[5].replace(/_/g," ");
    deep = route[6];
    name = route[7];
    var value = $('div.option_list ul li a.'+route[5]).text();
    // Remove selected variable
    $('div.option_list ul li.selected').each(function(i,ele){$(ele).removeClass('selected');});
    $('div.select').each(function(i,ele){$(ele).removeClass('selected');});
    $('div.select span.inner_select a').each(function(i,ele){var text = $(ele).attr('title'); $(ele).text(text);});
    // Add new selected variable
    $('div.option_list ul li a.'+route[5]).closest('li').addClass('selected');
    $('div.option_list ul li a.'+route[5]).closest('div.select').addClass('selected');
    $('div.option_list ul li a.'+route[5]).closest('div.select').find('span.inner_select a').text(value);

    initializeApp();
  }

  function initializeWelcomeWindow() {

    $('body').click(function(event) {
      if (!$(event.target).closest('div#welcomewindow').length) {
        $("#welcomewindow").fadeOut("slow");
        $('body').unbind('click');
      }
    });

    $("#welcomewindow a.close_info").click(function(ev) {
      ev.stopPropagation();
      ev.preventDefault();
      $("#welcomewindow").fadeOut("slow");
    });

    $("#welcomewindow a.start").click(function(ev) {
      ev.stopPropagation();
      ev.preventDefault();

      $("#welcomewindow").fadeOut("slow");

        var text = $("div.select div.option_list ul li a.paro").text();
        $("div.select div.outer_select.money").parent().addClass("selected");
        $("div.select div.outer_select.money span.inner_select a").text(text);
        $("div.select div.option_list ul li a.paro").parent().addClass("selected");
        compare = "paro";

        if (year < 2005) { // because we don't have paro information prior 2005
          updateNewSliderValue(2005, year);
        }
        changeHash();
    });

    $("#welcomewindow a.explore").click(function(ev) {
      ev.stopPropagation();
      ev.preventDefault();
      $("#welcomewindow").fadeOut("slow");
    });

    $("#welcomewindow a.more_info").click(function(ev) {
      ev.stopPropagation();
      ev.preventDefault();
      $("#welcomewindow").fadeOut("slow", function() {
        explanationwindow.show();
      });
    });

    $("#welcomewindow a.know_more").click(function(ev) {
      ev.stopPropagation();
      ev.preventDefault();
      $("#welcomewindow").fadeOut("slow");
    });
  }

  function changeHash() {
    var latlng = peninsula.getCenter();
    var zoom = peninsula.getZoom();
    var hash = "#"+ state + "/" + latlng.lat().toFixed(3)+"/"+latlng.lng().toFixed(3)+"/"+zoom+"/"+year+"/"+compare.replace(/ /g,'_')+"/"+deep+"/"+name;
    window.location.hash = hash;
    updateWadusText();
  }
<|endoftext|>


<commit_before>// header of the output log
var outputText = "test results\n    all measurements are in milliseconds unless otherwise specified";

// base string used for string manipulations, thanks to http://www.lipsum.com/
var baseString = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent egestas laoreet porttitor. Quisque eu dignissim turpis, eu feugiat sapien. Duis at vestibulum quam. Sed eget ipsum leo. Duis eu ligula sem. Suspendisse vitae faucibus enim. Aliquam erat volutpat. Vestibulum condimentum ut erat ac rhoncus. Nulla porttitor scelerisque tortor, a pretium sapien pretium quis.";

// used internally
var completedTasks = 0,
    taskQueue = new Array(),
    totalTasks,
    running = false;

// wrappers for repetitive functions
function element(arg) {
    return document.getElementById(arg);
}
function output(arg,header) {
    outputText += "\n";
    if (header)
        outputText += "\ntask: ";
    else
        outputText += "    ";
    outputText += arg;
}
function changeStatus(arg) {
    element("status").innerHTML = arg + "

";
}
function changeDescription(arg) {
    element("description").innerHTML = "
" + arg;
}

// print quick summary statistics and extra data of an array of numbers
function summary(array) {
    var n = array.length,
        half = Math.floor(n/2),
        sum = 0,
        median;

    array.sort(function(a,b) {
        return a - b;
    });

    for (i = 0; i < n; i++) {
        sum += array[i];
    }

    if (n % 2 == 1) {
        median = array[half];
    } else {
        median = (array[half]+array[half-1])/2;
    }

    output("items: " + array.join(", "));
    output("n: " + n);
    output("sum: " + sum);
    output("mean: " + sum/n);
    output("median: " + median);
}

// add a table consisting of a function and its sleep time to the task queue
function queue(name, fn, sleep) {
    taskQueue.push([name, fn, sleep]);
}

// recursive function that iterates over the task queue and gives feedback
function runNextTask() {
    if (! totalTasks) {
        totalTasks = taskQueue.length
    }

    var currentTask = taskQueue.shift(),
        delay = currentTask[2];

    if (! delay) {
        delay = 50;
    }

    changeStatus("The page may appear to be frozen; please do not refresh, leave the tab, or close the app

Running task: " + currentTask[0]);
    completedTasks++;
    element("progressBarFg").style.width = completedTasks/totalTasks*100 + "%";

    // recurse
    setTimeout(function() {
        currentTask[1]();
        if (taskQueue.length > 0) {
            runNextTask();
        }
    }, delay);
}

function main() {

    element("description").removeAttribute("style");

    // first, queue all tasks

    // dump browser info
    queue("Dumping browser information", function() {
        output("browser information dump",true);
        output("user-agent: " + navigator.userAgent);
    });

    // regex
    changeStatus("Loading regex...");
    var regexTrials = 10,
        regexReps = 16,
        regexChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890~!@#$%^&_|:<>", // each one is iterated over
        regexData = new Array(),
        regexTitle = regexChars.length + " regex replaces, " + baseString.length + " characters, " + regexReps + " reps",
        regexDesc = "Testing how fast the browser can perform simple text operations";
    for (run = 0; run < regexTrials; run++) {
        queue(regexTitle + ", trial #" + (run + 1), function() {
            changeDescription(regexDesc);
            var start = Date.now();
            for (r = 0; r < regexReps; r++) {
                var str = baseString;
                for (i = 0; i < regexChars.length; i++) {
                    var regex = new RegExp(regexChars.charAt(i),"g");
                    str = str.replace(regex,"0");
                }
                console.log(str);
            }
            var dt = (Date.now() - start);
            regexData.push(dt);
        });
    }
    queue("Collecting regex results", function() {
        output(regexTitle,true);
        summary(regexData);
    });

    // crypto (sjcl 1.0.0)
    changeStatus("Loading crypto...");
    var cryptoPass = "ayy lmao",
        cryptoTrials = 10,
        cryptoReps = 32,
        cryptoData = new Array(),
        cryptoTitle = "SJCL encrypt, decrypt " + baseString.length + " characters, " + cryptoReps + " reps",
        cryptoDesc = "Testing how fast the browser can encrypt and decrypt a string multiple times, using the Stanford JavaScript Crypto Library";
    for (run = 0; run < cryptoTrials; run++) {
        queue(cryptoTitle + ", trial #" + (run + 1), function() {
            changeDescription(cryptoDesc);
            var str = baseString,
                start = Date.now();
            for (i = 0; i < cryptoReps; i++) {
                console.log(sjcl.decrypt(cryptoPass,sjcl.encrypt(cryptoPass,str)));
            }
            var dt = (Date.now() - start);
            cryptoData.push(dt);
        });
    }
    queue("Collecting crypto results", function() {
        output(cryptoTitle,true);
        summary(cryptoData);
    });

    // increment
    changeStatus("Loading increment...");
    var incrementIterations = 10000000,
        incrementTrials = 10,
        incrementData = new Array(),
        incrementTitle = incrementIterations + " increments",
        incrementDesc = "Testing how fast the browser can run a ton of loops, incrementing a single variable by one every time";
    for (run = 0; run < incrementTrials; run++) {
        queue(incrementTitle + ", trial #" + (run + 1), function() {
            changeDescription(incrementDesc);
            var start = Date.now();
            var x = 0;
            for (i = 0; i < incrementIterations; i++) {
                x++;
            }
            var dt = (Date.now() - start);
            console.log("x = " + x);
            incrementData.push(dt);
        });
    }
    queue("Collecting increment results", function() {
        output(incrementTitle,true);
        summary(incrementData);
    });

    // factorial (math.js 2.4.2)
    changeStatus("Loading factorial...");
    var factorialArg = 2048
        factorialTrials = 10
        factorialData = new Array()
        factorialTitle = factorialArg + "!",
        factorialDesc = "Testing how fast the browser can solve the factorial of 2048";
    for (run = 0; run < factorialTrials; run++) {
        queue(factorialTitle + ", trial #" + (run + 1), function() {
            changeDescription(factorialDesc);
            var start = Date.now();
            math.config({precision:6000});
            console.log(factorialArg + "!: " + math.factorial(math.bignumber(factorialArg)));
            var dt = (Date.now() - start);
            factorialData.push(dt);
        });
    }
    queue("Collecting factorial results", function() {
        output(factorialTitle,true);
        summary(factorialData);
    });

    // TODO: more benchmarks here

    // finalize results
    queue("Collecting results", function() {
        element("output").innerHTML = outputText;
        element("outputBox").removeAttribute("style");
        element("description").setAttribute("style","display: none;");

        element("progressBarBg").style.height = "0px";
        element("status").innerHTML = "Tests finished. Please enter any additional information that you'd like to provide into the box below (browser, phone model, how your day is going, etc.) and click the button when finished. The more information, the better!

The results of your test can be found below the button.";
        document.title = "The Tanner Times Phone Study (waiting for input)";

        element("button").innerHTML = "Click here to submit your results (does nothing yet)";

        // modify and display the form
        element("results").innerHTML = outputText;
        element("form").removeAttribute("style");
    });

    // run all queued tasks
    runNextTask();
}

element("button").onclick = function() {
    if (running == false) {
        running = true;
        element("button").innerHTML = "Working...";
        element("button").setAttribute("style","display: none;");
        element("progressBarBg").style.height = "50px";
        changeStatus("Starting...");
        document.title = "The Tanner Times Phone Study (working)";
        setTimeout(main,100);
    }
}

<commit_msg>added descriptions, added "element" function to wrap about document.getElementById<commit_after>// header of the output log
var outputText = "test results\n    all measurements are in milliseconds unless otherwise specified";

// base string used for string manipulations, thanks to http://www.lipsum.com/
var baseString = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent egestas laoreet porttitor. Quisque eu dignissim turpis, eu feugiat sapien. Duis at vestibulum quam. Sed eget ipsum leo. Duis eu ligula sem. Suspendisse vitae faucibus enim. Aliquam erat volutpat. Vestibulum condimentum ut erat ac rhoncus. Nulla porttitor scelerisque tortor, a pretium sapien pretium quis.";

// used internally
var completedTasks = 0,
    taskQueue = new Array(),
    totalTasks,
    running = false;

// wrappers for repetitive functions
function element(arg) {
    return document.getElementById(arg);
}
function output(arg,header) {
    outputText += "\n";
    if (header)
        outputText += "\ntask: ";
    else
        outputText += "    ";
    outputText += arg;
}
function changeStatus(arg) {
    element("status").innerHTML = arg + "

";
}
function changeDescription(arg) {
    element("description").innerHTML = "
" + arg;
}

// print quick summary statistics and extra data of an array of numbers
function summary(array) {
    var n = array.length,
        half = Math.floor(n/2),
        sum = 0,
        median;

    array.sort(function(a,b) {
        return a - b;
    });

    for (i = 0; i < n; i++) {
        sum += array[i];
    }

    if (n % 2 == 1) {
        median = array[half];
    } else {
        median = (array[half]+array[half-1])/2;
    }

    output("items: " + array.join(", "));
    output("n: " + n);
    output("sum: " + sum);
    output("mean: " + sum/n);
    output("median: " + median);
}

// add a table consisting of a function and its sleep time to the task queue
function queue(name, fn, sleep) {
    taskQueue.push([name, fn, sleep]);
}

// recursive function that iterates over the task queue and gives feedback
function runNextTask() {
    if (! totalTasks) {
        totalTasks = taskQueue.length
    }

    var currentTask = taskQueue.shift(),
        delay = currentTask[2];

    if (! delay) {
        delay = 50;
    }

    changeStatus("The page may appear to be frozen; please do not refresh, leave the tab, or close the app

Running task: " + currentTask[0]);
    completedTasks++;
    element("progressBarFg").style.width = completedTasks/totalTasks*100 + "%";

    // recurse
    setTimeout(function() {
        currentTask[1]();
        if (taskQueue.length > 0) {
            runNextTask();
        }
    }, delay);
}

function main() {

    // first, queue all tasks

    // dump browser info
    queue("Dumping browser information", function() {
        output("browser information dump",true);
        output("user-agent: " + navigator.userAgent);
    });

    // regex
    changeStatus("Loading regex...");
    var regexTrials = 10,
        regexReps = 16,
        regexChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890~!@#$%^&_|:<>", // each one is iterated over
        regexData = new Array(),
        regexTitle = regexChars.length + " regex replaces, " + baseString.length + " characters, " + regexReps + " reps",
        regexDesc = "Testing how fast the browser can perform simple text operations";
    for (run = 0; run < regexTrials; run++) {
        queue(regexTitle + ", trial #" + (run + 1), function() {
            changeDescription(regexDesc);
            var start = Date.now();
            for (r = 0; r < regexReps; r++) {
                var str = baseString;
                for (i = 0; i < regexChars.length; i++) {
                    var regex = new RegExp(regexChars.charAt(i),"g");
                    str = str.replace(regex,"0");
                }
                console.log(str);
            }
            var dt = (Date.now() - start);
            regexData.push(dt);
        });
    }
    queue("Collecting regex results", function() {
        output(regexTitle,true);
        summary(regexData);
    });

    // crypto (sjcl 1.0.0)
    changeStatus("Loading crypto...");
    var cryptoPass = "ayy lmao",
        cryptoTrials = 10,
        cryptoReps = 32,
        cryptoData = new Array(),
        cryptoTitle = "SJCL encrypt, decrypt " + baseString.length + " characters, " + cryptoReps + " reps",
        cryptoDesc = "Testing how fast the browser can encrypt and decrypt a string multiple times, using the Stanford JavaScript Crypto Library";
    for (run = 0; run < cryptoTrials; run++) {
        queue(cryptoTitle + ", trial #" + (run + 1), function() {
            changeDescription(cryptoDesc);
            var str = baseString,
                start = Date.now();
            for (i = 0; i < cryptoReps; i++) {
                console.log(sjcl.decrypt(cryptoPass,sjcl.encrypt(cryptoPass,str)));
            }
            var dt = (Date.now() - start);
            cryptoData.push(dt);
        });
    }
    queue("Collecting crypto results", function() {
        output(cryptoTitle,true);
        summary(cryptoData);
    });

    // increment
    changeStatus("Loading increment...");
    var incrementIterations = 10000000,
        incrementTrials = 10,
        incrementData = new Array(),
        incrementTitle = incrementIterations + " increments",
        incrementDesc = "Testing how fast the browser can run a ton of loops, incrementing a single variable by one every time";
    for (run = 0; run < incrementTrials; run++) {
        queue(incrementTitle + ", trial #" + (run + 1), function() {
            changeDescription(incrementDesc);
            var start = Date.now();
            var x = 0;
            for (i = 0; i < incrementIterations; i++) {
                x++;
            }
            var dt = (Date.now() - start);
            console.log("x = " + x);
            incrementData.push(dt);
        });
    }
    queue("Collecting increment results", function() {
        output(incrementTitle,true);
        summary(incrementData);
    });

    // factorial (math.js 2.4.2)
    changeStatus("Loading factorial...");
    var factorialArg = 2048
        factorialTrials = 10
        factorialData = new Array()
        factorialTitle = factorialArg + "!",
        factorialDesc = "Testing how fast the browser can solve the factorial of 2048";
    for (run = 0; run < factorialTrials; run++) {
        queue(factorialTitle + ", trial #" + (run + 1), function() {
            changeDescription(factorialDesc);
            var start = Date.now();
            math.config({precision:6000});
            console.log(factorialArg + "!: " + math.factorial(math.bignumber(factorialArg)));
            var dt = (Date.now() - start);
            factorialData.push(dt);
        });
    }
    queue("Collecting factorial results", function() {
        output(factorialTitle,true);
        summary(factorialData);
    });

    // TODO: more benchmarks here

    // finalize results
    queue("Collecting results", function() {
        element("output").innerHTML = outputText;
        element("outputBox").removeAttribute("style");
        element("description").setAttribute("style","display: none;");

        element("progressBarBg").style.height = "0px";
        element("status").innerHTML = "Tests finished. Please enter any additional information that you'd like to provide into the box below (browser, phone model, how your day is going, etc.) and click the button when finished. The more information, the better!

The results of your test can be found below the button.";
        document.title = "The Tanner Times Phone Study (waiting for input)";

        element("button").innerHTML = "Click here to submit your results (does nothing yet)";

        // modify and display the form
        element("results").innerHTML = outputText;
        element("form").removeAttribute("style");
    });

    // run all queued tasks
    runNextTask();
}

element("button").onclick = function() {
    if (running == false) {
        running = true;
        element("button").innerHTML = "Working...";
        element("button").setAttribute("style","display: none;");
        element("progressBarBg").style.height = "50px";
        changeStatus("Starting...");
        document.title = "The Tanner Times Phone Study (working)";
        element("description").removeAttribute("style");
        setTimeout(main,100);
    }
}

<|endoftext|>


<commit_before>/**
 * Created by MorningWind on 8/27/2015.
 */
// ref : http://www.goodboydigital.com/pixi-js-tutorial-getting-started/
// ref : https://github.com/jquery-boilerplate/jquery-boilerplate

;(function ($, window, document, undefined) {
    var gameName = "WebGame";
    defaults = {
        canvasSize: {x:640, y:690}
    };

    function Game( element, options ) {
        this.element = element;
        this.settings = $.extend( {}, defaults, options );
        this._defaults = defaults;
        this._name = gameName;

        this.init();
    }

    // Avoid Plugin.prototype conflicts
    $.extend(Game.prototype, {
        init: function () {
            this.initCall();
        },
        initCall: function () {
            console.log("Hello World!");
        }
    });

    // A really lightweight plugin wrapper around the constructor,
    // preventing against multiple instantiations
    $.fn[ gameName ] = function ( options ) {
        return this.each(function() {
            if ( !$.data( this, "plugin_" + gameName ) ) {
                $.data( this, "plugin_" + gameName, new Game( this, options ) );
            }
        });
    };

})( jQuery, window, document );

function PIXITest()
{
    var stage = new PIXI.Container();

    var renderer = PIXI.autoDetectRenderer(1800, 1200);

    document.body.appendChild(renderer.view);

    var planet;
    var smallPlanet;

    PIXI.loader.add('planet', 'planet.png').load(function(loader, resources){
        planet = new PIXI.Sprite(resources.planet.texture);
        smallPlanet = new PIXI.Sprite(resources.planet.texture);

        planet.anchor.x = 0.5;
        planet.anchor.y = 0.5;

        smallPlanet.anchor.x = 1.0;
        smallPlanet.anchor.y = 1.0;

        planet.position.x = 900;
        planet.position.y = 600;

        smallPlanet.position.x = 300;
        smallPlanet.position.y = 300;

        smallPlanet.scale.x = 0.5;
        smallPlanet.scale.y = 0.5;

        stage.addChild(planet);
        stage.addChild(smallPlanet);

        animate();
    });

    function animate() {

        requestAnimationFrame( animate );

        planet.rotation += 0.01;
        smallPlanet.rotation += 0.05;
        // render the stage
        renderer.render(stage);
    }

}

<commit_msg>에셋 에셋이 필요하다<commit_after>/**
 * Created by MorningWind on 8/27/2015.
 */
// ref : http://www.goodboydigital.com/pixi-js-tutorial-getting-started/
// ref : https://github.com/jquery-boilerplate/jquery-boilerplate

;(function ($, window, document, undefined) {
    var gameName = "WebGame";
    defaults = {
        canvasSize: {x:640, y:690}
    };

    function Game( element, options ) {
        this.element = element;
        this.settings = $.extend( {}, defaults, options );
        this._defaults = defaults;
        this._name = gameName;

        this.init();
    }

    // Avoid Plugin.prototype conflicts
    $.extend(Game.prototype, {
        init: function () {
            this.stage = new PIXI.Stage(0x334499);

            this.scene = new PIXI.DisplayObjectContainer();
            this.stage.addChild(this.scene);

            this.renderer = PIXI.autoDetectRenderer(defaults.canvasSize.x, defaults.canvasSize.y);

            $(this.element).append(this.renderer.view);

            requestAnimationFrame(this.animate.bind(this));

            this.loadAssets();

        },
        loadAssets:function(){
            var loader = new PIXI.AssetLoader(['assets/interface.json']);
            loader.onComplete = this.onLoadAssets.bind(this);

            loader.load();
        },
        onLoadAssets:function(){
            var texture = PIXI.Texture.fromImage('bg.png');
            var paperBG = new PIXI.Sprite(texture);
            this.scene.addChild(paperBG);
        },
        animate: function(){
            requestAnimationFrame(this.animate.bind(this));

            this.renderer.render(this.stage);
        }
    });

    // A really lightweight plugin wrapper around the constructor,
    // preventing against multiple instantiations
    $.fn[ gameName ] = function ( options ) {
        return this.each(function() {
            if ( !$.data( this, "plugin_" + gameName ) ) {
                $.data( this, "plugin_" + gameName, new Game( this, options ) );
            }
        });
    };

})( jQuery, window, document );

function PIXITest()
{
    var stage = new PIXI.Container();

    var renderer = PIXI.autoDetectRenderer(1800, 1200);

    document.body.appendChild(renderer.view);

    var planet;
    var smallPlanet;

    PIXI.loader.add('planet', 'planet.png').load(function(loader, resources){
        planet = new PIXI.Sprite(resources.planet.texture);
        smallPlanet = new PIXI.Sprite(resources.planet.texture);

        planet.anchor.x = 0.5;
        planet.anchor.y = 0.5;

        smallPlanet.anchor.x = 1.0;
        smallPlanet.anchor.y = 1.0;

        planet.position.x = 900;
        planet.position.y = 600;

        smallPlanet.position.x = 300;
        smallPlanet.position.y = 300;

        smallPlanet.scale.x = 0.5;
        smallPlanet.scale.y = 0.5;

        stage.addChild(planet);
        stage.addChild(smallPlanet);

        animate();
    });

    function animate() {

        requestAnimationFrame( animate );

        planet.rotation += 0.01;
        smallPlanet.rotation += 0.05;
        // render the stage
        renderer.render(stage);
    }

}

<|endoftext|>


<commit_before>
/**
 * Module dependencies.
 */

var debug = require('debug')('wpcom:like');

/**
 * Follow methods
 *
 * @param {String} site_id site id
 * @param {WPCOM} wpcom
 * @api public
 */

function Follow(site_id, wpcom){
  if (!site_id) {
    throw new Error('`site id` is not correctly defined');
  }

  if (!(this instanceof Follow)) return new Follow(site_id, wpcom);

  this.wpcom = wpcom;
  this._site_id = site_id;
}

/**
 * :FOLLOW:
 * List a site's followers
 * in reverse-chronological
 * order
 *
 */
Follow.prototype.followers = function(fn) {
  var path = '/sites/' + this._site_id + '/follows/'
  this.wpcom.sendRequest(path, null, null, fn);
};

/**
 * :FOLLOW:
 * Follow the site
 *
 */
Follow.prototype.follow = function(fn) {
  var path = '/sites/' + this._site_id + '/follows/new';
  this.wpcom.sendRequest({method: 'POST', path: path}, null, null, fn);
};

/**
 * :FOLLOW:
 * Unfollow the site
 *
 */
Follow.prototype.unfollow = function(fn) {
  var path = '/sites/' + this._site_id + '/follows/mine/delete';
  this.wpcom.sendRequest({method: 'POST', path: path}, null, null, fn);
};

/**
 * :FOLLOW:
 * Get the follow status for current
 * user on current blog site
 *
 */
Follow.prototype.is_following = function(fn) {
  var path = '/sites/' + this._site_id + '/follows/mine';
  this.wpcom.sendRequest(path, null, null, fn);
};

module.exports = Follow;<commit_msg>Follow: Rename functions to match style and pass query<commit_after>
/**
 * Module dependencies.
 */

var debug = require('debug')('wpcom:like');

/**
 * Follow methods
 *
 * @param {String} site_id site id
 * @param {WPCOM} wpcom
 * @api public
 */

function Follow(site_id, wpcom){
  if (!site_id) {
    throw new Error('`site id` is not correctly defined');
  }

  if (!(this instanceof Follow)) return new Follow(site_id, wpcom);

  this.wpcom = wpcom;
  this._site_id = site_id;
}

/**
 * :FOLLOW:
 * List a site's followers
 * in reverse-chronological
 * order
 *
 */
Follow.prototype.follows =
Follow.prototype.followsList = function(query, fn) {
  var path = '/sites/' + this._site_id + '/follows/'
  this.wpcom.sendRequest(path, query, null, fn);
};

/**
 * :FOLLOW:
 * Follow the site
 *
 */
Follow.prototype.follow =
Follow.prototype.new =
Follow.prototype.add = function(query, fn) {
  var path = '/sites/' + this._site_id + '/follows/new';
  this.wpcom.sendRequest({method: 'POST', path: path}, query, null, fn);
};

/**
 * :FOLLOW:
 * Unfollow the site
 *
 */
Follow.prototype.unfollow =
Follow.prototype.remove =
Follow.prototype.del = function(query, fn) {
  var path = '/sites/' + this._site_id + '/follows/mine/delete';
  this.wpcom.sendRequest({method: 'POST', path: path}, query, null, fn);
};

/**
 * :FOLLOW:
 * Get the follow status for current
 * user on current blog site
 *
 */
Follow.prototype.state =
Follow.prototype.mine = function(query, fn) {
  var path = '/sites/' + this._site_id + '/follows/mine';
  this.wpcom.sendRequest(path, query, null, fn);
};

module.exports = Follow;<|endoftext|>


<commit_before>import * as React from 'react';

/**
 * Main List Element to be displayed on the Navigation.
 *
 * @param {href: a URL String to a resource, innerText: The display text}
 */
const NavigationItem = props =>

{props.innerText}

    /**
     * Main Navigation List.
     * Instance will be embedded in ./Header component.
     *
     * @param {options: [option]} props arbituary object containing an array of
     * options, where each option = {link:String, text: String}.
     */
    export const Navigation = (props) => {
  return (

      {props.options.map(option => <NavigationItem href={option.link} innerText={option.text}/>)}

  );
}
<commit_msg>Adjust JSDoc comment to be more descriptive<commit_after>import * as React from 'react';

/**
 * Main List Element to be displayed on the Navigation.
 *
 * @param {href: a URL String to a resource, innerText: The display text}
 */
const NavigationItem = props =>

{props.innerText}

    /**
     * Main Navigation List.
     * Instance will be embedded in ./Header component.
     *
     * @param {Object} props
     * @param {Object} props.options an array of navigation options.
     * @param {Object} props.options.option a navigation option.
     * @param {String} props.options.option.link an external URL.
     * @param {String} props.options.option.text the displayed text.
     */
    export const Navigation = (props) => {
  return (

      {props.options.map(option => <NavigationItem href={option.link} innerText={option.text}/>)}

  );
}
<|endoftext|>


<commit_before>"use strict";

/*global nodeca, _*/

var NLib  = require('nlib');
var Async = NLib.Vendor.Async;

////////////////////////////////////////////////////////////////////////////////

module.exports.parserParameters = {
  version:      nodeca.runtime.version,
  addHelp:      true,
  help:         'Create user and assign with some groups',
  description:  'Create user '
};

module.exports.commandLineArguments = [
  {
    args:    [ 'action' ],
    options: {
      help:   'cli command add/update',
      choices: ['add', 'update']
    }
  },
  {
    args:    [ '--group' ],
    options: {
      dest:         'mark_to_add',
      help:         'add user to group',
      action:       'append',
      defaultValue: [],
      type: 'string'
    }
  },
  {
    args:    [ '--no-group' ],
    options: {
      dest:         'mark_to_remove',
      help:         'remove user from group',
      action:       'append',
      defaultValue: [],
      type: 'string'
    }
  },
  {
    args:    [ '-u', '--user' ],
    options: {
      help:         'target user',
      type: 'string',
      required: true
    }
  },
    {
    args:    [ '--pass' ],
    options: {
      help:         'user passsword. required only for add command',
      type: 'string'

    }
  },
  {
    args:    [ '--email' ],
    options: {
      help:         'user email. required only for add command',
      type: 'string'
    }
  }
];

module.exports.run = function (args, callback) {
  Async.series([
    require('../lib/init/redis'),
    require('../lib/init/mongoose'),
    NLib.InitStages.loadModels,
    NLib.InitStages.loadServerApiSubtree
  ], function (err) {
    var user = null;
    var to_add = {};
    var to_remove = [];

    // FIXME check to_remove and to_add intersection
    Async.series([

      // fetch usergroups
      function (callback) {
        var UserGroup = nodeca.models.users.UserGroup;
        UserGroup.find().select('_id short_name')
            .exec(function(err, docs) {
          if (err) {
              callback(err);
              return;
          }
          docs.forEach(function(group) {
            if (args.mark_to_remove.indexOf(group.short_name) !== -1) {
              to_remove.push(group._id.toString());
            }
            if (args.mark_to_add.indexOf(group.short_name) !== -1) {
              to_add[group._id.toString()] = group;
            }
          });
          // FIXME check all groups were found from both lists?
          callback();
        });
      },

      // find or create user
      function(callback) {
        // FIXME test existing login and email
        var User = nodeca.models.users.User;
        var auth = new nodeca.models.users.AuthLink();

        if ('add' === args.action) {
          // FIXME user revalidator for pass and email test
          if (!args.pass || !args.email) {
            callback('Invalid password or email');
            return;
          }
          user = new User({
            nick: args.user,
            joined_ts: new Date
          });

          user.save(function (err) {
            if (err) {
              callback(err);
              return;
            }

            var provider = auth.providers.create({
              'type': 'plain',
              'email': args.email
            });

            provider.setPass(args.pass);

            auth.user_id = user._id;
            auth.providers.push(provider);

            auth.save(callback);
          });
        }
        else {
          User.findOne({nick: args.user}).exec(function(err, doc) {
            if (err) {
              callback(err);
              return;
            }
            if (!user) {
              callback('User not found, check name or use `add`');
            }
            user = doc;
            callback();
          });
        }
      },

      // update groups
      function(callback) {
        if (!_.isEmpty(to_remove) && !_.isEmpty(user.usergroups)) {
          user.usergroups = user.usergroups.filter(function(group) {
            return to_remove.indexOf(group.toString()) === -1;
          });
        }
        if (!_.isEmpty(to_add)) {
          // remove from to_add list already assigned groups
          user.usergroups.forEach(function(group) {
            var group_id = group.toString();
            if (to_add[group_id]) {
              to_add = _.without(to_add, group_id);
            }
          });
          if (!_.isEmpty(to_add)) {
            _.values(to_add).forEach(function(group) {
              user.usergroups.push(group);
            });
          }
        }
        user.save(callback);
      }
    ], function (err) {
      if (err) {
        console.log(err);
        console.log('\n');
        process.exit(0);
      }
      console.log('Ok');
      console.log('\n');
      process.exit(0);
    });

  });
};
<commit_msg>Fix user CLI script<commit_after>"use strict";

/*global N, underscore*/

// 3rd-party
var _     = underscore;
var async = require('async');

////////////////////////////////////////////////////////////////////////////////

module.exports.parserParameters = {
  version:      N.runtime.version,
  addHelp:      true,
  help:         'Create user and assign with some groups',
  description:  'Create user '
};

module.exports.commandLineArguments = [
  {
    args:    [ 'action' ],
    options: {
      help:   'cli command add/update',
      choices: ['add', 'update']
    }
  },
  {
    args:    [ '--group' ],
    options: {
      dest:         'mark_to_add',
      help:         'add user to group',
      action:       'append',
      defaultValue: [],
      type: 'string'
    }
  },
  {
    args:    [ '--no-group' ],
    options: {
      dest:         'mark_to_remove',
      help:         'remove user from group',
      action:       'append',
      defaultValue: [],
      type: 'string'
    }
  },
  {
    args:    [ '-u', '--user' ],
    options: {
      help:         'target user',
      type: 'string',
      required: true
    }
  },
  {
    args:    [ '--pass' ],
    options: {
      help:         'user passsword. required only for add command',
      type: 'string'

    }
  },
  {
    args:    [ '--email' ],
    options: {
      help:         'user email. required only for add command',
      type: 'string'
    }
  }
];

module.exports.run = function (args, callback) {
  async.series([
    require('../lib/system/init/redis'),
    require('../lib/system/init/mongoose'),
    require('../lib/system/init/models'),
    require('../lib/system/init/stores'),
    require('../lib/system/init/check_migrations')
  ], function (err) {
    var user      = null;
    var to_add    = {};
    var to_remove = [];

    // FIXME check to_remove and to_add intersection
    async.series([
      // fetch usergroups
      function (callback) {
        var UserGroup = N.models.users.UserGroup;

        UserGroup.find().select('_id short_name').exec(function (err, docs) {
          if (err) {
            callback(err);
            return;
          }

          docs.forEach(function (group) {
            if (args.mark_to_remove.indexOf(group.short_name) !== -1) {
              to_remove.push(group._id.toString());
            }
            if (args.mark_to_add.indexOf(group.short_name) !== -1) {
              to_add[group._id.toString()] = group;
            }
          });

          // FIXME check all groups were found from both lists?
          callback();
        });
      },

      // find or create user
      function (callback) {
        // FIXME test existing login and email
        var User = N.models.users.User;
        var auth = new N.models.users.AuthLink();

        if ('add' === args.action) {
          // FIXME user revalidator for pass and email test
          if (!args.pass || !args.email) {
            callback('Invalid password or email');
            return;
          }

          user = new User({
            nick: args.user,
            joined_ts: new Date
          });

          user.save(function (err) {
            if (err) {
              callback(err);
              return;
            }

            var provider = auth.providers.create({
              'type': 'plain',
              'email': args.email
            });

            provider.setPass(args.pass);

            auth.user_id = user._id;
            auth.providers.push(provider);

            auth.save(callback);
          });
        } else {
          User.findOne({nick: args.user}).exec(function (err, doc) {
            if (err) {
              callback(err);
              return;
            }
            if (!user) {
              callback('User not found, check name or use `add`');
            }
            user = doc;
            callback();
          });
        }
      },

      // update groups
      function (callback) {
        if (!_.isEmpty(to_remove) && !_.isEmpty(user.usergroups)) {
          user.usergroups = user.usergroups.filter(function (group) {
            return to_remove.indexOf(group.toString()) === -1;
          });
        }
        if (!_.isEmpty(to_add)) {
          // remove from to_add list already assigned groups
          user.usergroups.forEach(function (group) {
            var group_id = group.toString();
            if (to_add[group_id]) {
              to_add = _.without(to_add, group_id);
            }
          });
          if (!_.isEmpty(to_add)) {
            _.values(to_add).forEach(function (group) {
              user.usergroups.push(group);
            });
          }
        }
        user.save(callback);
      }
    ], function (err) {
      if (err) {
        console.log(err + "\n");
        process.exit(0);
      }

      console.log('OK\n');
      process.exit(0);
    });
  });
};
<|endoftext|>


<commit_before>/**
 * Copyright 2013 Facebook, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var docblockRe = /^\s*(\/\*\*(.|\r?\n)*?\*\/)/;

var ltrimRe = /^\s*/;
/**
 * @param {String} contents
 * @return {String}
 */
function extract(contents) {
  var match = contents.match(docblockRe);
  if (match) {
    return match[0].replace(ltrimRe, '') || '';
  }
  return '';
}

var commentStartRe = /^\/\*\*?/;
var commentEndRe = /\*\/$/;
var wsRe = /[\t ]+/g;
var stringStartRe = /(\r?\n|^) *\*/g;
var multilineRe = /(?:^|\r?\n) *(@[^\r\n]*?) *\r?\n *([^@\r\n\s][^@\r\n]+?) *\r?\n/g;
var propertyRe = /(?:^|\r?\n) *@(\S+) *([^\r\n]*)/g;

/**
 * @param {String} contents
 * @return {Array}
 */
function parse(docblock) {
  docblock = docblock
    .replace(commentStartRe, '')
    .replace(commentEndRe, '')
    .replace(wsRe, ' ')
    .replace(stringStartRe, '$1');

  // Normalize multi-line directives
  var prev = '';
  while (prev != docblock) {
    prev = docblock;
    docblock = docblock.replace(multilineRe, "\r?\n$1 $2\r?\n");
  }
  docblock = docblock.trim();

  var result = [];
  var match;
  while (match = propertyRe.exec(docblock)) {
    result.push([match[1], match[2]]);
  }

  return result;
}

/**
 * Same as parse but returns an object of prop: value instead of array of paris
 * If a property appers more than once the last one will be returned
 *
 * @param {String} contents
 * @return {Object}
 */
function parseAsObject(docblock) {
  var pairs = parse(docblock);
  var result = {};
  for (var i = 0; i < pairs.length; i++) {
    result[pairs[i][0]] = pairs[i][1];
  }
  return result;
}

exports.extract = extract;
exports.parse = parse;
exports.parseAsObject = parseAsObject;
<commit_msg>Docblock should not add carriage return when parsing variables<commit_after>/**
 * Copyright 2013 Facebook, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var docblockRe = /^\s*(\/\*\*(.|\r?\n)*?\*\/)/;

var ltrimRe = /^\s*/;
/**
 * @param {String} contents
 * @return {String}
 */
function extract(contents) {
  var match = contents.match(docblockRe);
  if (match) {
    return match[0].replace(ltrimRe, '') || '';
  }
  return '';
}

var commentStartRe = /^\/\*\*?/;
var commentEndRe = /\*\/$/;
var wsRe = /[\t ]+/g;
var stringStartRe = /(\r?\n|^) *\*/g;
var multilineRe = /(?:^|\r?\n) *(@[^\r\n]*?) *\r?\n *([^@\r\n\s][^@\r\n]+?) *\r?\n/g;
var propertyRe = /(?:^|\r?\n) *@(\S+) *([^\r\n]*)/g;

/**
 * @param {String} contents
 * @return {Array}
 */
function parse(docblock) {
  docblock = docblock
    .replace(commentStartRe, '')
    .replace(commentEndRe, '')
    .replace(wsRe, ' ')
    .replace(stringStartRe, '$1');

  // Normalize multi-line directives
  var prev = '';
  while (prev != docblock) {
    prev = docblock;
    docblock = docblock.replace(multilineRe, "\n$1 $2\n");
  }
  docblock = docblock.trim();

  var result = [];
  var match;
  while (match = propertyRe.exec(docblock)) {
    result.push([match[1], match[2]]);
  }

  return result;
}

/**
 * Same as parse but returns an object of prop: value instead of array of paris
 * If a property appers more than once the last one will be returned
 *
 * @param {String} contents
 * @return {Object}
 */
function parseAsObject(docblock) {
  var pairs = parse(docblock);
  var result = {};
  for (var i = 0; i < pairs.length; i++) {
    result[pairs[i][0]] = pairs[i][1];
  }
  return result;
}

exports.extract = extract;
exports.parse = parse;
exports.parseAsObject = parseAsObject;
<|endoftext|>


<commit_before>#!/usr/bin/env node
var fs = require('fs-extra');
var path = require('path');
var childProcess = require('child_process');
var sortPackageJson = require('sort-package-json');

/**
 * Add an extension to the source tree of JupyterLab.
 * It takes as an argument either a path to a directory
 * on the local filesystem or a URL to a git repository.
 * In the former case, it copies the directory into the
 * source tree, in the latter it adds the repository as
 * a git submodule.
 *
 * It also adds the relevant metadata to the build files.
 */

// Make sure we have required command line arguments.
if (process.argv.length < 3) {
    var msg = '** Must supply a target extension';
    process.stderr.write(msg);
    process.exit(1);
}

// Extract the desired git repository and repository name.
var target = process.argv[2];
var basePath = path.resolve('.');
var packageDirName;

var packagePath = '';
if (target[0] === '.' || target[0] === '/') {
  // If the target starts with a '.' or a '/', treat it as a local path.
  packagePath = path.resolve(target);
  // Possibly remove a trailing slash.
  if (packagePath[packagePath.length-1] === '/') {
    packagePath = packagePath.slice(0, -1);
  }
  packageDirName = packagePath.split('/').pop();
  // Copy the package directory contents to the sibling package.
  var newPackagePath = path.join(basePath, 'packages', packageDirName);
  fs.copySync(packagePath, newPackagePath);
} else {
  // Otherwise treat it as a git reposotory and try to add it.
  packageDirName = target.split('/').pop().split('.')[0];
  var packagePath = path.join(basePath, 'packages', packageDirName);
  // Add the repository as a submodule.
  childProcess.execSync('git submodule add --force '+ target + ' ' + packagePath);
}

// Get the package.json of the extension.
var package = require(path.join(packagePath, 'package.json'));

// Add the extension to packages/all-packages/package.json
var allPackagesPath = path.join(basePath, 'packages', 'all-packages', 'package.json');
var allPackages = require(allPackagesPath);
allPackages.dependencies[package.name] = '^'+String(package.version);
var text = JSON.stringify(sortPackageJson(allPackages), null, 2) + '\n';
fs.writeFileSync(allPackagesPath, text);

// Add the extension path to packages/all-packages/tsconfig.json
var tsconfigPath = path.join(basePath, 'packages', 'all-packages', 'tsconfig.json');
var tsconfig = require(tsconfigPath);
tsconfig.compilerOptions.paths[package.name] = [path.join('..', packageDirName, 'src')];
fs.writeFileSync(tsconfigPath, JSON.stringify(tsconfig, null, 2) + '\n');

// Add the extension to packages/all-packages/src/index.ts
var indexPath = path.join(basePath, 'packages', 'all-packages', 'src', 'index.ts');
var index = fs.readFileSync(indexPath, 'utf8');
index = index + 'import "' + package.name + '";\n';
fs.writeFileSync(indexPath, index);

// Update the core jupyterlab build dependencies.
childProcess.execSync('npm run update:core');
<commit_msg>Clean up the addsibling logic<commit_after>#!/usr/bin/env node
var fs = require('fs-extra');
var path = require('path');
var childProcess = require('child_process');
var sortPackageJson = require('sort-package-json');

/**
 * Add an extension to the source tree of JupyterLab.
 * It takes as an argument either a path to a directory
 * on the local filesystem or a URL to a git repository.
 * In the former case, it copies the directory into the
 * source tree, in the latter it adds the repository as
 * a git submodule.
 *
 * It also adds the relevant metadata to the build files.
 */

// Make sure we have required command line arguments.
if (process.argv.length < 3) {
    var msg = '** Must supply a target extension';
    process.stderr.write(msg);
    process.exit(1);
}

// Extract the desired git repository and repository name.
var target = process.argv[2];
var basePath = path.resolve('.');
var packageDirName;

var packagePath = '';
if (target[0] === '.' || target[0] === '/') {
  // If the target starts with a '.' or a '/', treat it as a local path.
  packagePath = path.resolve(target);
  // Possibly remove a trailing slash.
  if (packagePath[packagePath.length-1] === '/') {
    packagePath = packagePath.slice(0, -1);
  }
  packageDirName = packagePath.split('/').pop();
  // Copy the package directory contents to the sibling package.
  var newPackagePath = path.join(basePath, 'packages', packageDirName);
  fs.copySync(packagePath, newPackagePath);
} else {
  // Otherwise treat it as a git reposotory and try to add it.
  packageDirName = target.split('/').pop().split('.')[0];
  var packagePath = path.join(basePath, 'packages', packageDirName);
  // Add the repository as a submodule.
  childProcess.execSync('git submodule add --force '+ target + ' ' + packagePath);
}

// Remove any existing node_modules in the extension.
if (fs.existsSync(path.join(packagePath, 'node_modules'))) {
  fs.removeSync(path.join(packagePath, 'node_modules'));
}

// Get the package.json of the extension.
var package = require(path.join(packagePath, 'package.json'));

// Add the extension to packages/all-packages/package.json
var allPackagesPath = path.join(basePath, 'packages', 'all-packages', 'package.json');
var allPackages = require(allPackagesPath);
allPackages.dependencies[package.name] = '^'+String(package.version);
var text = JSON.stringify(sortPackageJson(allPackages), null, 2) + '\n';
fs.writeFileSync(allPackagesPath, text);

// Add the extension path to packages/all-packages/tsconfig.json
var tsconfigPath = path.join(basePath, 'packages', 'all-packages', 'tsconfig.json');
var tsconfig = require(tsconfigPath);
tsconfig.compilerOptions.paths[package.name] = [path.join('..', packageDirName, 'src')];
fs.writeFileSync(tsconfigPath, JSON.stringify(tsconfig, null, 2) + '\n');

// Add the extension to packages/all-packages/src/index.ts
var indexPath = path.join(basePath, 'packages', 'all-packages', 'src', 'index.ts');
var index = fs.readFileSync(indexPath, 'utf8');
index = index + 'import "' + package.name + '";\n';
fs.writeFileSync(indexPath, index);

// Update the core jupyterlab build dependencies.
childProcess.execSync('npm run update:core', {stdio:[0,1,2]});

// Update the lerna symlinks.
childProcess.execSync('npm install', {stdio:[0,1,2]});
<|endoftext|>


<commit_before>import fs from 'fs'
import config from './config'
import { isWhite } from './utils'
import PDFDocument from 'pdfkit'

class Document extends PDFDocument {
  constructor(options) {
    super(options)

    if (!isWhite(options.background)) {
      this.on('pageAdded', () => { this._setBackground(options.background) })
      this.emit('pageAdded') // necessary to apply changes in first page
    }

    options.baseFont && this.font(options.baseFont)

    options.baseFontSize && this.fontSize(options.baseFontSize)
  }

  get margins() { return this.page.margins }

  get pageSize() { return { width: this.page.width, height: this.page.height } }

  get contentWidth() {
    const { left, right } = this.margins

    return this.pageSize.width - (left + right)
  }

  /*
   * Forces a new line
   *
   * @return {undefined}
   */
  newLine() {
    this.text(' ')
  }

  /*
   * Allows to write text in vertical
   *
   * @desc Saves the context, rotates the document and writes the given text in
   * vertical, from left and bottom to right and top.
   *
   * @param {String} text - the text to write
   * @param {number} x - the desired distance from left (bottom in the original
   *                     document orientation)
   * @param {number} y - the desired distance from bottom (left in the original
   *                     document orientation)
   * @param {object} args - remaining args accepted by {@link PDFDocument#text}
   *
   * @return {undefined}
   */
  verticalText(text, x, y, ...args) {
    const previousX = this.x
    const previousY = this.y
    const recalculatedX = y - this.pageSize.height
    const recalculatedY = x

    this.save()

    this.rotate(270)
    this.text(text, recalculatedX, recalculatedY, ...args)

    this.restore()

    this.x = previousX
    this.y = previousY
  }

  _setBackground(background) {
    const previousColor = this._fillColor && this._fillColor[0]

    this.rect(0, 0, this.page.width, this.page.height)
    this.fill(background)

    this.fill(previousColor) // restore the fill color
  }

  /*
   * Render a properly a text with links
   *
   * @param {object} textWithLink - the text that contains a link
   * @param {object} args - remaining args accepted by {@link PDFDocument#text}
   *
   * @return {undefined}
   */
  textWithLink(textWithLink, ...args) {
    console.log(typeof textWithLink)
    const input = textWithLink.input
    const linkLength = textWithLink[0].length
    const linkIndex = textWithLink.index
    const linkCaption = textWithLink[2]
    const linkUrl = textWithLink[3]

    let opts = {}

    if (typeof args[args.length -1] === 'object') {
      opts = args.pop()
    }

    this.text(input.slice(0, linkIndex), ...args, {...opts, continued: true })
    this.text(linkCaption, { ...opts, continued: true, link: linkUrl, underline: config.underlineLinks })
    this.text(input.slice(linkIndex + linkLength), { ...opts, continued: true, link: false, underline: false })

    if (opts.newLine === false) {
      return
    }

    this.newLine()
  }
}

const document = new Document(config.document)
document.pipe(fs.createWriteStream(config.outputFilename))

export default document
<commit_msg>Improve #textWithLink method<commit_after>import fs from 'fs'
import config from './config'
import { isWhite } from './utils'
import PDFDocument from 'pdfkit'

class Document extends PDFDocument {
  constructor(options) {
    super(options)

    if (!isWhite(options.background)) {
      this.on('pageAdded', () => { this._setBackground(options.background) })
      this.emit('pageAdded') // necessary to apply changes in first page
    }

    options.baseFont && this.font(options.baseFont)

    options.baseFontSize && this.fontSize(options.baseFontSize)
  }

  get margins() { return this.page.margins }

  get pageSize() { return { width: this.page.width, height: this.page.height } }

  get contentWidth() {
    const { left, right } = this.margins

    return this.pageSize.width - (left + right)
  }

  /*
   * Forces a new line
   *
   * @return {undefined}
   */
  newLine() {
    this.text(' ')
  }

  /*
   * Allows to write text in vertical
   *
   * @desc Saves the context, rotates the document and writes the given text in
   * vertical, from left and bottom to right and top.
   *
   * @param {String} text - the text to write
   * @param {number} x - the desired distance from left (bottom in the original
   *                     document orientation)
   * @param {number} y - the desired distance from bottom (left in the original
   *                     document orientation)
   * @param {object} args - remaining args accepted by {@link PDFDocument#text}
   *
   * @return {undefined}
   */
  verticalText(text, x, y, ...args) {
    const previousX = this.x
    const previousY = this.y
    const recalculatedX = y - this.pageSize.height
    const recalculatedY = x

    this.save()

    this.rotate(270)
    this.text(text, recalculatedX, recalculatedY, ...args)

    this.restore()

    this.x = previousX
    this.y = previousY
  }

  _setBackground(background) {
    const previousColor = this._fillColor && this._fillColor[0]

    this.rect(0, 0, this.page.width, this.page.height)
    this.fill(background)

    this.fill(previousColor) // restore the fill color
  }

  /*
   * Renders properly links into given text
   *
   * @note: currently only has support for one link
   * @todo: support multiple links
   *
   * @param {Object} textWithLink - object with text and link matches
   * @param {...Object} args - remaining args accepted by {@link PDFDocument#text}
   *
   * @return {undefined}
   */
  textWithLink(textWithLink, ...args) {
    let opts = {}
    const input = textWithLink.input
    const linkLength = textWithLink[0].length
    const linkIndex = textWithLink.index
    const linkCaption = textWithLink[2]
    const linkUrl = textWithLink[3]

    if (typeof args[args.length -1] === 'object') {
      opts = args.pop()
    }

    const linkOptions = {
      ...opts,
      continued: true,
      link: linkUrl,
      underline: config.underlineLinks
    }

    if (linkIndex > 0) {
      this.text(input.slice(0, linkIndex), ...args, {...opts, continued: true })
      this.text(linkCaption, linkOptions)
    } else {
      this.text(linkCaption, ...args, linkOptions)
    }

    this.text(input.slice(linkIndex + linkLength), {...opts, continued: true, link: false, underline: false })

    if (opts.newLine === false) {
      return
    }

    this.newLine()
  }
}

const document = new Document(config.document)
document.pipe(fs.createWriteStream(config.outputFilename))

export default document
<|endoftext|>


<commit_before>/* jshint node:true */
'use strict';

const helper = require('../core/helper');

class Handler {
  constructor(options) {
    this._options = options;
    this._options.handleString = this._options.handleString || this._handleString;
    this._options.handleNumber = this._options.handleNumber || this._handleNumber;
    this._options.handleBoolean = this._options.handleBoolean || this._handleBoolean;
    this._options.handleDate = this._options.handleDate || this._handleDate;
    this._options.handleObject = this._options.handleObject || (ob)=>this._handleObject(ob);
  }

  _setHeaders(result, item) {
    let self = this;
    if (!item) return result;
    return result.map(function(element) {
      element.item = element.item ? item + self._options.headerPathString + element.item : item;
      return element;
    });
  }
  /**
   * Check the element type of the element call the correct handle function
   *
   * @param element Element that will be checked
   * @param item Used to make the headers/path breadcrumb
   */
  check(element, item) {
    //Check if element is a String
    if (helper.isString(element)) {
      return [{
        item: item,
        value: this._options.handleString(element, item),
      }];
    }
    //Check if element is a Number
    else if (helper.isNumber(element)) {
      return [{
        item: item,
        value: this._options.handleNumber(element, item),
      }];
    }
    //Check if element is a Boolean
    else if (helper.isBoolean(element)) {
      return [{
        item: item,
        value: this._options.handleBoolean.bind(this)(element, item),
      }];
    }
    //Check if element is a Date
    else if (helper.isDate(element)) {
      return [{
        item: item,
        value: this._options.handleDate(element, item),
      }];
    }
    //Check if element is an Array
    else if (helper.isArray(element)) {
      var resultArray = this._handleArray(element, item);
      return this._setHeaders(resultArray, item);
    }
    //Check if element is a Object
    else if (helper.isObject(element)) {
      var resultObject = this._options.handleObject(element, item, () => this._handleObject.apply(this, arguments));
      return this._setHeaders(resultObject, item);
    }

    return [{
      item: item,
      value: '',
    }];
  }

  /**
   * Handle all Objects
   *
   * @param {Object} obj
   * @returns {Array} result
   */
  _handleObject(obj) {
    var result = [];
    //Look every object props
    for (var prop in obj) {
      var propData = obj[prop];
      //Check the propData type
      var resultCheckType = this.check(propData, prop);
      //Append to results
      result = result.concat(resultCheckType);
    }
    return result;
  }
  /**
   * Handle all Arrays, merges arrays with primitive types in a single value
   *
   * @param {Array} array
   * @returns {Array} result
   */
  _handleArray(array) {
    let self = this;
    let result = [];
    var firstElementWithoutItem;
    for (let element of array) {
      //Check the propData type
      var resultCheckType = self.check(element);
      //Check for results without itens, merge all itens with the first occurrence
      if (resultCheckType.length === 0) continue;
      var firstResult = resultCheckType[0];
      if (!firstResult.item && firstElementWithoutItem !== undefined) {
        firstElementWithoutItem.value += self._options.arrayPathString + firstResult.value;
        continue;
      } else if (resultCheckType.length > 0 && !firstResult.item && firstElementWithoutItem === undefined) {
        firstElementWithoutItem = firstResult;
      }
      //Append to results
      result = result.concat(resultCheckType);
    }
    return result;
  }
  /**
   * Handle all Boolean variables, can be replaced with options.handleBoolean
   *
   * @param {Boolean} boolean
   * @returns {String} result
   */
  _handleBoolean(boolean) {
    var result;
    //Check for booolean options
    if (boolean) {
      result = this._options.booleanTrueString || 'true';
    } else {
      result = this._options.booleanFalseString || 'false';
    }
    return result;
  }
  /**
   * Handle all String variables, can be replaced with options.handleString
   *
   * @param {String} string
   * @returns {String} string
   */
  _handleString(string) {
    return string;
  }
  /**
   * Handle all Number variables, can be replaced with options.handleNumber
   *
   * @param {Number} number
   * @returns {Number} number
   */
  _handleNumber(number) {
    return number;
  }
  /**
   * Handle all Date variables, can be replaced with options.handleDate
   *
   * @param {Date} number
   * @returns {string} result
   */
  _handleDate(date) {
    return date.toLocaleDateString();
  }

}

module.exports = Handler;
<commit_msg>syntax fix again<commit_after>/* jshint node:true */
'use strict';

const helper = require('../core/helper');

class Handler {
  constructor(options) {
    this._options = options;
    this._options.handleString = this._options.handleString || this._handleString;
    this._options.handleNumber = this._options.handleNumber || this._handleNumber;
    this._options.handleBoolean = this._options.handleBoolean || this._handleBoolean;
    this._options.handleDate = this._options.handleDate || this._handleDate;
    this._options.handleObject = this._options.handleObject || ((ob)=>this._handleObject(ob));
  }

  _setHeaders(result, item) {
    let self = this;
    if (!item) return result;
    return result.map(function(element) {
      element.item = element.item ? item + self._options.headerPathString + element.item : item;
      return element;
    });
  }
  /**
   * Check the element type of the element call the correct handle function
   *
   * @param element Element that will be checked
   * @param item Used to make the headers/path breadcrumb
   */
  check(element, item) {
    //Check if element is a String
    if (helper.isString(element)) {
      return [{
        item: item,
        value: this._options.handleString(element, item),
      }];
    }
    //Check if element is a Number
    else if (helper.isNumber(element)) {
      return [{
        item: item,
        value: this._options.handleNumber(element, item),
      }];
    }
    //Check if element is a Boolean
    else if (helper.isBoolean(element)) {
      return [{
        item: item,
        value: this._options.handleBoolean.bind(this)(element, item),
      }];
    }
    //Check if element is a Date
    else if (helper.isDate(element)) {
      return [{
        item: item,
        value: this._options.handleDate(element, item),
      }];
    }
    //Check if element is an Array
    else if (helper.isArray(element)) {
      var resultArray = this._handleArray(element, item);
      return this._setHeaders(resultArray, item);
    }
    //Check if element is a Object
    else if (helper.isObject(element)) {
      var resultObject = this._options.handleObject(element, item, () => this._handleObject.apply(this, arguments));
      return this._setHeaders(resultObject, item);
    }

    return [{
      item: item,
      value: '',
    }];
  }

  /**
   * Handle all Objects
   *
   * @param {Object} obj
   * @returns {Array} result
   */
  _handleObject(obj) {
    var result = [];
    //Look every object props
    for (var prop in obj) {
      var propData = obj[prop];
      //Check the propData type
      var resultCheckType = this.check(propData, prop);
      //Append to results
      result = result.concat(resultCheckType);
    }
    return result;
  }
  /**
   * Handle all Arrays, merges arrays with primitive types in a single value
   *
   * @param {Array} array
   * @returns {Array} result
   */
  _handleArray(array) {
    let self = this;
    let result = [];
    var firstElementWithoutItem;
    for (let element of array) {
      //Check the propData type
      var resultCheckType = self.check(element);
      //Check for results without itens, merge all itens with the first occurrence
      if (resultCheckType.length === 0) continue;
      var firstResult = resultCheckType[0];
      if (!firstResult.item && firstElementWithoutItem !== undefined) {
        firstElementWithoutItem.value += self._options.arrayPathString + firstResult.value;
        continue;
      } else if (resultCheckType.length > 0 && !firstResult.item && firstElementWithoutItem === undefined) {
        firstElementWithoutItem = firstResult;
      }
      //Append to results
      result = result.concat(resultCheckType);
    }
    return result;
  }
  /**
   * Handle all Boolean variables, can be replaced with options.handleBoolean
   *
   * @param {Boolean} boolean
   * @returns {String} result
   */
  _handleBoolean(boolean) {
    var result;
    //Check for booolean options
    if (boolean) {
      result = this._options.booleanTrueString || 'true';
    } else {
      result = this._options.booleanFalseString || 'false';
    }
    return result;
  }
  /**
   * Handle all String variables, can be replaced with options.handleString
   *
   * @param {String} string
   * @returns {String} string
   */
  _handleString(string) {
    return string;
  }
  /**
   * Handle all Number variables, can be replaced with options.handleNumber
   *
   * @param {Number} number
   * @returns {Number} number
   */
  _handleNumber(number) {
    return number;
  }
  /**
   * Handle all Date variables, can be replaced with options.handleDate
   *
   * @param {Date} number
   * @returns {string} result
   */
  _handleDate(date) {
    return date.toLocaleDateString();
  }

}

module.exports = Handler;
<|endoftext|>


<commit_before>// Copyright (c) 2013 John Granström
//
// 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.

var spawn = require('child_process').spawn,
	util = require('util'),
	fs = require('fs'),
	misc = require('./misc'),
	EventEmitter = require('events').EventEmitter,
	CommandPool = require('./commandpool').CommandPool
	Signals = require('./command').Signals;

// Create a new Go-object for the specified .go-file.
// Will also intialize Go-object if second parameter is true.
//
// Throws error if no path provided to .go-file.
util.inherits(Go, EventEmitter);
exports.Go = Go;
function Go(options, callback) {
	if(options === undefined || options === null) {
		misc.raiseError('No options provided.')
	}
	if(options.path == undefined || options.path == null) {
		misc.raiseError('No path provided to .go-file.');
	}

	misc.mergeDefaultOptions(options, {
		maxCommandsRunning: 10,
		defaultCommandTimeoutSec: 5,
		cwd: process.cwd(),
	});
	this.options = options;

	this.goFile = options.path;
	this.proc = null;
	this.initialized = false;
	this.commandPool = new CommandPool(this)

	if(options.initAtOnce) {
		this.init(callback);
	}
}

// Initialize by launching go process and prepare for commands.
// Do as early as possible to avoid delay when executing first command.
//
// callback has parameters (err)
Go.prototype.init = function(callback) {
	var self = this;
	fs.exists(this.goFile, function(exists) {
		if(!exists) {
			misc.callbackIfAvailable(callback, misc.getError('.go-file not found for given path.'));
			return;
		}
		// Spawn go process within current working directory
		self.proc = spawn('go', ['run', self.goFile], { cwd: self.options.cwd, env: process.env });

		// Setup handlers
		self.proc.stdout.on('data', function(data){
			handleStdout(self, data);
		});
		self.proc.stderr.on('data', function(data){
			handleErr(self, data, false);
		});
		self.proc.on('close', function(){
			handleClose(self);
		});

		// Init complete
		self.initialized = true;
		misc.callbackIfAvailable(callback, null);
	});
}

// Close go by sending termination signal
Go.prototype.close = function() {
	if(this.initialized) {
		// Send prioritized termination signal
		this.commandPool.planExecution(Signals.Termination, true);
	}
}

// Create and execute a command of JSON data
// Takes parameters:
// 		data (required) - actual command JSON
//		callback (required) - the callback to call with possible result when execution ends
//		options (optional) - overrides default execution options
Go.prototype.execute = function(data, callback, options) {
	if(this.initialized) {
		// Important to not leave go in an infinite loop eatig cpu
		try { // Contain outer exceptions and close go before rethrowing exception.
			this.commandPool.planExecution(this.commandPool.createCommand(data, callback), false, options);
		} catch (e) {
			this.close();
			throw e;
		}
	}
}

// Receive data from go-module
function handleStdout(go, data) {
	// Response may be several command responses separated by new lines
	data.toString().split("\n").forEach(function(resp) {
		// Discard empty lines
		if(resp.length > 0) {
			// Parse each command response with a event-loop in between to avoid blocking
			process.nextTick(function(){parseResponse(go, resp)});
		}
	});
}

// Parse a _single_ command response as JSON and handle it
// If parsing fails a internal error event will be emitted with the response data
function parseResponse(go, resp) {
	var parsed;
	try {
		parsed = JSON.parse(resp);
	} catch (e) {
		handleErr(go, resp, true);
		return;
	}

	// Important to not leave go in an infinite loop eatig cpu
	try { // Contain outer exceptions and close go before rethrowing exception.
		go.commandPool.handleResponse(parsed) // Handle response outside throw to avoid catching those exceptions
	} catch (e) {
		go.close();
		throw e;
	}
}

// Emit error event on go instance, pass through raw error data
// Errors may either be internal parser errors or external errors received from stderr
function handleErr(go, data, parser) {
	if(go.listeners('error').length > 0) { // Only emit event if there are listeners
		go.emit('error', {parser: parser, data: data});
	}
}

// Emit close event on go instance
function handleClose(go) {
	if(go.listeners('close').length > 0) { // Only emit event if there are listeners
		go.emit('close');
	}
}<commit_msg>Fixed handling for when Go process closes unexpectedly by for example panic<commit_after>// Copyright (c) 2013 John Granström
//
// 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.

var spawn = require('child_process').spawn,
	util = require('util'),
	fs = require('fs'),
	misc = require('./misc'),
	EventEmitter = require('events').EventEmitter,
	CommandPool = require('./commandpool').CommandPool
	Signals = require('./command').Signals;

// Create a new Go-object for the specified .go-file.
// Will also intialize Go-object if second parameter is true.
//
// Throws error if no path provided to .go-file.
util.inherits(Go, EventEmitter);
exports.Go = Go;
function Go(options, callback) {
	if(options === undefined || options === null) {
		misc.raiseError('No options provided.')
	}
	if(options.path == undefined || options.path == null) {
		misc.raiseError('No path provided to .go-file.');
	}

	misc.mergeDefaultOptions(options, {
		maxCommandsRunning: 10,
		defaultCommandTimeoutSec: 5,
		cwd: process.cwd(),
	});
	this.options = options;

	this.goFile = options.path;
	this.proc = null;
	this.initialized = false;
	this.commandPool = new CommandPool(this)

	if(options.initAtOnce) {
		this.init(callback);
	}
}

// Initialize by launching go process and prepare for commands.
// Do as early as possible to avoid delay when executing first command.
//
// callback has parameters (err)
Go.prototype.init = function(callback) {
	var self = this;
	fs.exists(this.goFile, function(exists) {
		if(!exists) {
			misc.callbackIfAvailable(callback, misc.getError('.go-file not found for given path.'));
			return;
		}
		// Spawn go process within current working directory
		self.proc = spawn('go', ['run', self.goFile], { cwd: self.options.cwd, env: process.env });

		// Setup handlers
		self.proc.stdout.on('data', function(data){
			handleStdout(self, data);
		});
		self.proc.stderr.on('data', function(data){
			handleErr(self, data, false);
		});
		self.proc.on('close', function(){
			handleClose(self);
		});

		// Init complete
		self.initialized = true;
		misc.callbackIfAvailable(callback, null);
	});
}

// Close go by sending termination signal
Go.prototype.close = function() {
	if(this.initialized) {
		// Send prioritized termination signal
		this.commandPool.planExecution(Signals.Termination, true);
	}
}

// Create and execute a command of JSON data
// Takes parameters:
// 		data (required) - actual command JSON
//		callback (required) - the callback to call with possible result when execution ends
//		options (optional) - overrides default execution options
Go.prototype.execute = function(data, callback, options) {
	if(this.initialized) {
		// Important to not leave go in an infinite loop eatig cpu
		try { // Contain outer exceptions and close go before rethrowing exception.
			this.commandPool.planExecution(this.commandPool.createCommand(data, callback), false, options);
		} catch (e) {
			this.close();
			throw e;
		}
	}
}

// Receive data from go-module
function handleStdout(go, data) {
	// Response may be several command responses separated by new lines
	data.toString().split("\n").forEach(function(resp) {
		// Discard empty lines
		if(resp.length > 0) {
			// Parse each command response with a event-loop in between to avoid blocking
			process.nextTick(function(){parseResponse(go, resp)});
		}
	});
}

// Parse a _single_ command response as JSON and handle it
// If parsing fails a internal error event will be emitted with the response data
function parseResponse(go, resp) {
	var parsed;
	try {
		parsed = JSON.parse(resp);
	} catch (e) {
		handleErr(go, resp, true);
		return;
	}

	// Important to not leave go in an infinite loop eatig cpu
	try { // Contain outer exceptions and close go before rethrowing exception.
		go.commandPool.handleResponse(parsed) // Handle response outside throw to avoid catching those exceptions
	} catch (e) {
		go.close();
		throw e;
	}
}

// Emit error event on go instance, pass through raw error data
// Errors may either be internal parser errors or external errors received from stderr
function handleErr(go, data, parser) {
	if(go.listeners('error').length > 0) { // Only emit event if there are listeners
		go.emit('error', {parser: parser, data: data});
	}
}

// Go panic and process ends causes calls to this
// Emit close event on go instance
function handleClose(go) {
	// If process closes we set initialized to false to avoid invalid close() or execute()
	go.initialized = false;
	if(go.listeners('close').length > 0) { // Only emit event if there are listeners
		go.emit('close');
	}
}<|endoftext|>


<commit_before>var ElementType = require("./ElementType.js");

function getTest (checkVal) {
	return function (value) { return value === checkVal; };
}

var arrayPush = Array.prototype.push;
function filterArray(test, arr, recurse, limit){
	var result = [], childs;

	for(var i = 0, j = arr.length; i < j; i++){
		if(test(arr[i])){
			result.push(arr[i]);
			if(--limit <= 0) break;
		}

		if(recurse && (childs = arr[i].children)){
			childs = filterArray(test, childs, limit);
			arrayPush.apply(result, childs);
			limit -= childs.length;
			if(limit <= 0) break;
		}
	}
	return result;
}

function filter(test, element, recurse, limit){
	if(recurse !== false) recurse = true;
	if(isNaN(limit)) limit = Infinity;
	if(!Array.isArray(element)){
		element = [element];
	}
	return filterArray(test, element, recurse, limit);
}

module.exports = {
	testElement: function testElement(options, element) {
		 var type = element.type;

		 for(var key in options){
		 	if(key === "tag_name"){
		 		if(type !== ElementType.Tag && type !== ElementType.Script && type !== ElementType.Style) return false;
		 		if(!options.tag_name(element.name)) return false;
		 	} else if(key === "tag_type") {
		 		if(!options.tag_type(type)) return false;
		 	} else if(key === "tag_contains") {
		 		if(type !== ElementType.Text && type !== ElementType.Comment && type !== ElementType.Directive) return false;
		 		if(!options.tag_contains(element.data)) return false;
		 	} else if(!element.attribs || !options[key](element.attribs[key]))
		 		return false;
		 }

		 return true;
	},

	getElements: function(options, element, recurse, limit){
		for(var key in options){
			if(typeof options[key] !== "function"){
				options[key] = getTest(options[key]);
			}
		}

		return filter(this.testElement.bind(null, options), element, recurse, limit);
	},

	getElementById: function(id, element, recurse) {
		var result;
		if(typeof id === "function"){
			result = filter(function(elem){
				return elem.attribs && id(elem.attribs);
			}, element, recurse, 1);
		}
		else{
			result = filter(function(elem){
				return elem.attribs && elem.attribs.id === id;
			}, element, recurse, 1);
		}
		return result.length ? result[0] : null;
	},

	getElementsByTagName: function(name, element, recurse, limit){
		if(typeof name === "function") return filter(function(elem){
			var type = elem.type;
			if(type !== ElementType.Tag && type !== ElementType.Script && type !== ElementType.Style) return false;
			return name(elem.name);
		}, element, recurse, limit);

		else return filter(function(elem){
			var type = elem.type;
			if(type !== ElementType.Tag && type !== ElementType.Script && type !== ElementType.Style) return false;
			return elem.name === name;
		}, element, recurse, limit);
	},

	getElementsByTagType: function(type, element, recurse, limit){
		if(typeof type === "function"){
			return filter(function(elem){return type(elem.type);}, element, recurse, limit);
		}
		else return filter(function(elem){return elem.type === type;}, element, recurse, limit);
	},

	getInnerHTML: function(elem){
		if(!elem.children) return "";

		var childs = elem.children,
			childNum = childs.length,
			ret = "";

		for(var i = 0; i < childNum; i++){
			ret += this.getOuterHTML(childs[i]);
		}

		return ret;
	},

	getOuterHTML: function(elem){
		var type = elem.type;

		if(type === ElementType.Text) return elem.data;
		if(type === ElementType.Comment) return "<!--" + elem.data + "-->";

		var ret = "<" + elem.name;

		var value;
		for(var name in elem.attribs){
			value = elem.attribs[name];
			ret += " " + name + "=";

			if(/^[^\s"\'\`\=\<\>]+$/.test(value)) ret += value;
			else if(value.indeOf("\"") !== -1) ret += "'" + value + "'";
			else ret += "\"" + value + "\"";
		}

		if(type === ElementType.Directive) return ret + ">";
		if(type === ElementType.Tag && !elem.children) return ret + " />";

		return ">" + ret + this.getInnerHTML(elem) + "</" + elem.name + ">";
	}
};<commit_msg>Makes sure recursion works properly<commit_after>var ElementType = require("./ElementType.js");

function getTest (checkVal) {
	return function (value) { return value === checkVal; };
}

var arrayPush = Array.prototype.push;
function filterArray(test, arr, recurse, limit){
	var result = [], childs;

	for(var i = 0, j = arr.length; i < j; i++){
		if(test(arr[i])){
			result.push(arr[i]);
			if(--limit <= 0) break;
		}

		if(recurse && (childs = arr[i].children)){
			childs = filterArray(test, childs, recurse, limit);
			arrayPush.apply(result, childs);
			limit -= childs.length;
			if(limit <= 0) break;
		}
	}
	return result;
}

function filter(test, element, recurse, limit){
	if(recurse !== false) recurse = true;
	if(isNaN(limit)) limit = Infinity;
	if(!Array.isArray(element)){
		element = [element];
	}
	return filterArray(test, element, recurse, limit);
}

module.exports = {
	testElement: function testElement(options, element) {
		 var type = element.type;

		 for(var key in options){
		 	if(key === "tag_name"){
		 		if(type !== ElementType.Tag && type !== ElementType.Script && type !== ElementType.Style) return false;
		 		if(!options.tag_name(element.name)) return false;
		 	} else if(key === "tag_type") {
		 		if(!options.tag_type(type)) return false;
		 	} else if(key === "tag_contains") {
		 		if(type !== ElementType.Text && type !== ElementType.Comment && type !== ElementType.Directive) return false;
		 		if(!options.tag_contains(element.data)) return false;
		 	} else if(!element.attribs || !options[key](element.attribs[key]))
		 		return false;
		 }

		 return true;
	},

	getElements: function(options, element, recurse, limit){
		for(var key in options){
			if(typeof options[key] !== "function"){
				options[key] = getTest(options[key]);
			}
		}

		return filter(this.testElement.bind(null, options), element, recurse, limit);
	},

	getElementById: function(id, element, recurse) {
		var result;
		if(typeof id === "function"){
			result = filter(function(elem){
				return elem.attribs && id(elem.attribs);
			}, element, recurse, 1);
		}
		else{
			result = filter(function(elem){
				return elem.attribs && elem.attribs.id === id;
			}, element, recurse, 1);
		}
		return result.length ? result[0] : null;
	},

	getElementsByTagName: function(name, element, recurse, limit){
		if(typeof name === "function") return filter(function(elem){
			var type = elem.type;
			if(type !== ElementType.Tag && type !== ElementType.Script && type !== ElementType.Style) return false;
			return name(elem.name);
		}, element, recurse, limit);

		else return filter(function(elem){
			var type = elem.type;
			if(type !== ElementType.Tag && type !== ElementType.Script && type !== ElementType.Style) return false;
			return elem.name === name;
		}, element, recurse, limit);
	},

	getElementsByTagType: function(type, element, recurse, limit){
		if(typeof type === "function"){
			return filter(function(elem){return type(elem.type);}, element, recurse, limit);
		}
		else return filter(function(elem){return elem.type === type;}, element, recurse, limit);
	},

	getInnerHTML: function(elem){
		if(!elem.children) return "";

		var childs = elem.children,
			childNum = childs.length,
			ret = "";

		for(var i = 0; i < childNum; i++){
			ret += this.getOuterHTML(childs[i]);
		}

		return ret;
	},

	getOuterHTML: function(elem){
		var type = elem.type;

		if(type === ElementType.Text) return elem.data;
		if(type === ElementType.Comment) return "<!--" + elem.data + "-->";

		var ret = "<" + elem.name;

		var value;
		for(var name in elem.attribs){
			value = elem.attribs[name];
			ret += " " + name + "=";

			if(/^[^\s"\'\`\=\<\>]+$/.test(value)) ret += value;
			else if(value.indeOf("\"") !== -1) ret += "'" + value + "'";
			else ret += "\"" + value + "\"";
		}

		if(type === ElementType.Directive) return ret + ">";
		if(type === ElementType.Tag && !elem.children) return ret + " />";

		return ">" + ret + this.getInnerHTML(elem) + "</" + elem.name + ">";
	}
};
<|endoftext|>


<commit_before>const fs = require('fs').promises
const path = require('path')

const shell = require('shelljs')

const { getPackages, isPro, registryUrl } = require('../utils')

const cwd = process.cwd()

process.env.PATH = `${cwd}/bin:${cwd}/node_modules/.bin:${process.env.PATH}`

shell.config.verbose = true
shell.config.fatal = true

ensureCleanIndex()

const { gitTag } = checkVersion()
let packages

main().catch((error) => {
  console.error(error)

  process.exit(1)
})

async function main (ps) {
  gitDetatch()

  clean()

  packages = await getPackages()

  await runBuild()

  await commitAndTag()
  await pushAndPublish()
}

function ensureCleanIndex () {
  // make sure the repo is clean
  try {
    shell.exec('git diff-index -G . HEAD --stat --exit-code')
  } catch {
    throw new Error('working directory must be clean')
  }
}

function checkVersion () {
  const getVersion = require('../getVersion')
  const version = require('semver').clean(getVersion())

  if (!version) {
    throw new Error('failed to parse version')
  }

  return {
    version,
    gitTag: 'v' + version,
  }
}

function gitDetatch () {
  shell.exec('git checkout --detach')
}

function clean () {
  shell.exec('_clean')
}

async function runBuild () {
  // copy README to interactjs package
  await Promise.all(
    packages
      .filter((p) => p.endsWith('interactjs'))
      .map((p) => fs.copyFile(`${cwd}/README.md`, `${p}/README.md`)),
  )

  // copy license file and npmignore to all packages
  const licenseFilename = isPro ? 'LICENSE.md' : 'LICENSE'
  await Promise.all(
    packages.map(async (pkg) => {
      await fs.copyFile(licenseFilename, path.join(pkg, licenseFilename))
      await fs.copyFile('.npmignore', path.join(pkg, '.npmignore'))
    }),
  )

  if (isPro) await fs.rm(path.resolve('LICENSE'))

  // clean up scope deps
  shell.exec('npx _check_deps')

  if (!isPro) {
    // bundle interactjs
    shell.exec('npm run bundle')

    // generate docs
    shell.exec('npm run docs')
  }

  // create @interactjs/**/use/* modules
  shell.exec('npx _add_plugin_indexes')

  // generate types
  shell.exec('npx _types')

  // generate esnext .js modules
  shell.exec('npx _esnext')

  // set publishConfig
  await editPackageJsons((pkg) => {
    pkg.publishConfig = isPro ? { access: 'restricted', registry: registryUrl } : { access: 'public' }
  })
}

function commitAndTag () {
  // commit and add new version tag
  shell.exec('git add --all .')
  shell.exec('git add --force packages')
  shell.exec('git reset **/node_modules')
  shell.exec(`git commit --no-verify -m ${gitTag}`)
  shell.exec(`git tag ${gitTag}`)
}

async function pushAndPublish () {
  const { NPM_TAG } = process.env

  try {
    shell.exec(`git push --no-verify origin ${gitTag}`)
  } catch {
    throw new Error(`failed to push git tag ${gitTag} to origin`)
  }

  const gitHead = shell.exec('git rev-parse --short HEAD').trim()
  editPackageJsons((pkg) => {
    pkg.gitHead = gitHead
  })

  const npmPublishCommand = 'npm publish' + (NPM_TAG ? ` --tag ${NPM_TAG}` : '')
  const packagesToPublish = isPro ? packages.filter((p) => /@interactjs\//.test(p)) : packages

  for (const pkg of packagesToPublish) {
    shell.exec(npmPublishCommand, { cwd: path.resolve(pkg) })
  }

  shell.exec('git checkout $(git ls-files "**package.json")')
}

async function editPackageJsons (func) {
  await ['.', ...packages].map(async (packageDir) => {
    const file = path.resolve(packageDir, 'package.json')
    const pkg = JSON.parse((await fs.readFile(file)).toString())

    func(pkg)

    await fs.writeFile(file, `${JSON.stringify(pkg, null, 2)}\n`)
  })
}
<commit_msg>chore: release without creating local tag<commit_after>const fs = require('fs').promises
const path = require('path')

const shell = require('shelljs')

const { getPackages, isPro, registryUrl } = require('../utils')

const cwd = process.cwd()

process.env.PATH = `${cwd}/bin:${cwd}/node_modules/.bin:${process.env.PATH}`

shell.config.verbose = true
shell.config.fatal = true

ensureCleanIndex()

const { gitTag } = checkVersion()
let packages

main().catch((error) => {
  console.error(error)

  process.exit(1)
})

async function main (ps) {
  gitDetatch()

  clean()

  packages = await getPackages()

  await runBuild()

  await commit()
  await pushAndPublish()
}

function ensureCleanIndex () {
  // make sure the repo is clean
  try {
    shell.exec('git diff-index -G . HEAD --stat --exit-code')
  } catch {
    throw new Error('working directory must be clean')
  }
}

function checkVersion () {
  const getVersion = require('../getVersion')
  const version = require('semver').clean(getVersion())

  if (!version) {
    throw new Error('failed to parse version')
  }

  return {
    version,
    gitTag: 'v' + version,
  }
}

function gitDetatch () {
  shell.exec('git checkout --detach')
}

function clean () {
  shell.exec('_clean')
}

async function runBuild () {
  // copy README to interactjs package
  await Promise.all(
    packages
      .filter((p) => p.endsWith('interactjs'))
      .map((p) => fs.copyFile(`${cwd}/README.md`, `${p}/README.md`)),
  )

  // copy license file and npmignore to all packages
  const licenseFilename = isPro ? 'LICENSE.md' : 'LICENSE'
  await Promise.all(
    packages.map(async (pkg) => {
      await fs.copyFile(licenseFilename, path.join(pkg, licenseFilename))
      await fs.copyFile('.npmignore', path.join(pkg, '.npmignore'))
    }),
  )

  if (isPro) await fs.rm(path.resolve('LICENSE'))

  // clean up scope deps
  shell.exec('npx _check_deps')

  if (!isPro) {
    // bundle interactjs
    shell.exec('npm run bundle')

    // generate docs
    shell.exec('npm run docs')
  }

  // create @interactjs/**/use/* modules
  shell.exec('npx _add_plugin_indexes')

  // generate types
  shell.exec('npx _types')

  // generate esnext .js modules
  shell.exec('npx _esnext')

  // set publishConfig
  await editPackageJsons((pkg) => {
    pkg.publishConfig = isPro ? { access: 'restricted', registry: registryUrl } : { access: 'public' }
  })
}

function commit () {
  // commit and add new version tag
  shell.exec('git add --all .')
  shell.exec('git add --force packages')
  shell.exec('git reset **/node_modules')
  shell.exec(`git commit --no-verify -m ${gitTag}`)
}

async function pushAndPublish () {
  const { NPM_TAG } = process.env

  try {
    shell.exec(`git push --no-verify origin HEAD:refs/tags/${gitTag}`)
  } catch {
    throw new Error(`failed to push git tag ${gitTag} to origin`)
  }

  const gitHead = shell.exec('git rev-parse --short HEAD').trim()
  editPackageJsons((pkg) => {
    pkg.gitHead = gitHead
  })

  const npmPublishCommand = 'npm publish' + (NPM_TAG ? ` --tag ${NPM_TAG}` : '')
  const packagesToPublish = isPro ? packages.filter((p) => /@interactjs\//.test(p)) : packages

  for (const pkg of packagesToPublish) {
    shell.exec(npmPublishCommand, { cwd: path.resolve(pkg) })
  }

  shell.exec('git checkout $(git ls-files "**package.json")')
}

async function editPackageJsons (func) {
  await ['.', ...packages].map(async (packageDir) => {
    const file = path.resolve(packageDir, 'package.json')
    const pkg = JSON.parse((await fs.readFile(file)).toString())

    func(pkg)

    await fs.writeFile(file, `${JSON.stringify(pkg, null, 2)}\n`)
  })
}
<|endoftext|>