<commit_before>/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2014 Broad Institute
 *
 * 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.
 */

/**
 * Created by turner on 9/19/14.
 */
var igv = (function (igv) {

    igv.Popover = function (parentDiv) {

        this.markupWithParentDiv(parentDiv)
    };

    igv.Popover.prototype.markupWithParentDiv = function(parentDiv) {

        var myself = this,
            popoverCloseElement,
            popoverCloseIcon;

        if (this.parentDiv) {
            return;
        }

        this.parentDiv = parentDiv;

        // popover
        this.popoverDiv = $('
')[0];
        $(this.parentDiv).append(this.popoverDiv);

        // popover content
        this.popoverContentDiv = $('
')[0];
        $(this.popoverDiv).append(this.popoverContentDiv);

        // popover close
        popoverCloseElement = $('')[0];
        $(this.popoverDiv).append(popoverCloseElement);

        popoverCloseIcon = $('')[0];
        $(popoverCloseElement).append(popoverCloseIcon);

        $(popoverCloseElement).hover(

            function() {
                $(popoverCloseIcon).removeClass("fa-times"       );
                $(popoverCloseIcon).addClass   ("fa-times-circle fa-lg");

                $(popoverCloseIcon).css({
                    "color" : "#222"
                });
            },

            function() {
                $(popoverCloseIcon).removeClass("fa-times-circle fa-lg");
                $(popoverCloseIcon).addClass   ("fa-times"       );

                $(popoverCloseIcon).css({
                    "color" : "#444"
                });

            }
        );

        popoverCloseElement.onclick = function (e) {
            $(myself.popoverDiv).hide();
        };

    };

    igv.Popover.prototype.testData = function (rows) {
        var i,
            name,
            nameValues = [];

        for (i = 0; i < rows; i++) {
            name = "name " + i;
            nameValues.push( { name : name, value : "verbsgohuman" } );
        }

        return nameValues;
    };

    igv.Popover.prototype.hide = function () {
        $(this.popoverDiv).hide();
    };

    igv.Popover.prototype.show = function (pageX, pageY, content) {

        var left,
            height,
            containerCoordinates = { x : pageX, y : pageY },
            containerRect = { x : 0, y : 0, width : $(window).width(), height : $(window).height() },
            popupRect = { },
            popupX = pageX,
            popupY = pageY;

        if (content) {

            $(this.popoverContentDiv).html(content);

            popupX -= $(this.parentDiv).offset().left;
            popupY -= $(this.parentDiv).offset().top;
            popupRect = { x : popupX, y : popupY, width : $(popoverDiv).outerWidth(), height : $(popoverDiv).outerHeight() };

            left = popupX;
            if (containerCoordinates.x + popupRect.width > containerRect.width) {
                left = popupX - popupRect.width;
            }

            $(popoverDiv).css({
                "left": left + "px",
                "top" : popupY  + "px"
            }).show();

            height = $(this.popoverContentDiv).height() + 20;
            $(popoverDiv).css({
                "height": height + "px"
            });
        }
    };

    return igv;

})(igv || {});

<commit_msg>Popover cleanup<commit_after>/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2014 Broad Institute
 *
 * 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.
 */

/**
 * Created by turner on 9/19/14.
 */
var igv = (function (igv) {

    igv.Popover = function (parentDiv) {

        this.markupWithParentDiv(parentDiv)
    };

    igv.Popover.prototype.markupWithParentDiv = function(parentDiv) {

        var myself = this,
            popoverCloseElement,
            popoverCloseIcon;

        if (this.parentDiv) {
            return;
        }

        this.parentDiv = parentDiv;

        // popover
        this.popoverDiv = $('
')[0];
        $(this.parentDiv).append(this.popoverDiv);

        // popover content
        this.popoverContentDiv = $('
')[0];
        $(this.popoverDiv).append(this.popoverContentDiv);

        // popover close
        popoverCloseElement = $('')[0];
        $(this.popoverDiv).append(popoverCloseElement);

        popoverCloseIcon = $('')[0];
        $(popoverCloseElement).append(popoverCloseIcon);

        $(popoverCloseElement).hover(

            function() {
                $(popoverCloseIcon).removeClass("fa-times"       );
                $(popoverCloseIcon).addClass   ("fa-times-circle fa-lg");

                $(popoverCloseIcon).css({
                    "color" : "#222"
                });
            },

            function() {
                $(popoverCloseIcon).removeClass("fa-times-circle fa-lg");
                $(popoverCloseIcon).addClass   ("fa-times"       );

                $(popoverCloseIcon).css({
                    "color" : "#444"
                });

            }
        );

        popoverCloseElement.onclick = function (e) {
            $(myself.popoverDiv).hide();
        };

    };

    igv.Popover.prototype.testData = function (rows) {
        var i,
            name,
            nameValues = [];

        for (i = 0; i < rows; i++) {
            name = "name " + i;
            nameValues.push( { name : name, value : "verbsgohuman" } );
        }

        return nameValues;
    };

    igv.Popover.prototype.hide = function () {
        $(this.popoverDiv).hide();
    };

    igv.Popover.prototype.show = function (pageX, pageY, content) {

        var left,
            height,
            containerCoordinates = { x : pageX, y : pageY },
            containerRect = { x : 0, y : 0, width : $(window).width(), height : $(window).height() },
            popupRect = { },
            popupX = pageX,
            popupY = pageY;

        if (content) {

            $(this.popoverContentDiv).html(content);

            popupX -= $(this.parentDiv).offset().left;
            popupY -= $(this.parentDiv).offset().top;
            popupRect = { x : popupX, y : popupY, width : $(this.popoverDiv).outerWidth(), height : $(this.popoverDiv).outerHeight() };

            left = popupX;
            if (containerCoordinates.x + popupRect.width > containerRect.width) {
                left = popupX - popupRect.width;
            }

            $(this.popoverDiv).css({
                "left": left + "px",
                "top" : popupY  + "px"
            }).show();

            height = $(this.popoverContentDiv).height() + 20;
            $(this.popoverDiv).css({
                "height": height + "px"
            });
        }
    };

    return igv;

})(igv || {});

<|endoftext|>


<commit_before>
window.attach_placeling_place = function(json) {
    jQuery('#placeling_place_json').val( encodeURI( json ) );
    renderPlaceAdmin( );
};

window.get_placeling_json = function(json) {
    return jQuery('#placeling_place_json').val();
};

jQuery(document).ready(function(){

    jQuery("form[name=post]").validate();

    jQuery('form[name=post]').submit(function(){
	jQuery('form[name=post]').validate();

	if ( !jQuery('form[name=post]').valid() ) {
	    jQuery("textarea[name=placeling_placemark_memo]").focus();
	    return false;
	}
	return true;
    });

    renderPlaceAdmin( );

    jQuery("a#placeling_remove_place").live('click', function(){
	jQuery("#placeling_place_json").val();
	renderPlaceAdmin( );
	return false;
    });

});

function renderPlaceAdmin( ){

	if ( jQuery("#placeling_place_json").val() != ""){
	    raw_json = unescape( jQuery("#placeling_place_json").val() );

	    place =  JSON.parse( raw_json );

	    var raw_place = jQuery('#placeling_place_json').val();
	    var json_place = unescape( raw_place );
	    var place = JSON.parse( json_place );

	    lat = place.lat;
	    lng = place.lng;
	    name = place.name;
	    map_url = place.map_url;

	    template = getPlacelingAdminTemplate();

	    jQuery("#placeling_tagged_place").html( template( place ) );
	    jQuery("#add_place .placeling_place_name").html( name );
	    jQuery("#add_place #placeling_tagged").show();
	    jQuery("#add_place #placeling_untagged").hide();

	    if ( place.perspectives[0] && place.perspectives[0].mine){
		jQuery("textarea[name=placeling_placemark_memo]").val(  place.perspectives[0].memo );
	    }

	    jQuery("#empty_place").hide();
	    jQuery("#placeling_tagged_place").show();

	    jQuery("#placeling_placemark_memo").rules("add", {
		required: true,
		minlength: 20,
		messages: {
		    required: "Required input",
		    minlength: jQuery.format("At least {0} characters are necessary")
		}
	    });

	} else {
	    jQuery("#placeling_tagged_place").html("");
	    jQuery("#add_place .placeling_place_name").html( "" );
	    jQuery("#add_place #placeling_tagged").hide();
	    jQuery("#add_place #placeling_untagged").show();
	    jQuery("#empty_place").show();
	    jQuery("#placeling_tagged_place").hide();
	}
}

function getPlacelingAdminTemplate(){
	return _.template("
		\

						\
				    <img src='<%= map_url %>'/>							\

										\

						\

<%= name %>
			\

<%= street_address %>
	\

<%= city_data %>
			\

										\

						\

remove place
	\

										\

		\

					\
			    <fieldset>									\
				    Placemark Note				\
				    <textarea id='placeling_placemark_memo' rows='5' cols='50' name='placeling_placemark_memo'></textarea>	\
				    <input name='placeling_placemark_photos' type='checkbox' id='placeling_placemark_photos' checked='checked'>Attach Photos? \
			    </fieldset>									\

		\
	");

}

<commit_msg>add some basic templates to the display of placeling stuff<commit_after>
window.attach_placeling_place = function(json) {
    jQuery('#placeling_place_json').val( encodeURI( json ) );
    renderPlaceAdmin( );
};

window.get_placeling_json = function(json) {
    return jQuery('#placeling_place_json').val();
};

jQuery(document).ready(function(){

    jQuery("form[name=post]").validate();

    jQuery('form[name=post]').submit(function(){
	jQuery('form[name=post]').validate();

	if ( !jQuery('form[name=post]').valid() ) {
	    jQuery("textarea[name=placeling_placemark_memo]").focus();
	    return false;
	}
	return true;
    });

    renderPlaceAdmin( );

    jQuery("a#placeling_remove_place").live('click', function(){
	jQuery("#placeling_place_json").val();
	renderPlaceAdmin( );
	return false;
    });

});

function renderPlaceAdmin( ){

	if ( jQuery("#placeling_place_json").val() != ""){
	    raw_json = unescape( jQuery("#placeling_place_json").val() );

	    place =  JSON.parse( raw_json );

	    var raw_place = jQuery('#placeling_place_json').val();
	    var json_place = unescape( raw_place );
	    var place = JSON.parse( json_place );

	    lat = place.lat;
	    lng = place.lng;
	    name = place.name;
	    map_url = place.map_url;

	    template = getPlacelingAdminTemplate();

	    jQuery("#placeling_tagged_place").html( template( place ) );
	    jQuery("#add_place .placeling_place_name").html( name );
	    jQuery("#add_place #placeling_tagged").show();
	    jQuery("#add_place #placeling_untagged").hide();

	    if ( place.perspectives[0] && place.perspectives[0].mine){
		jQuery("textarea[name=placeling_placemark_memo]").val(  place.perspectives[0].memo );
	    }

	    jQuery("#empty_place").hide();
	    jQuery("#placeling_tagged_place").show();

	    jQuery("#placeling_placemark_memo").rules("add", {
		required: true,
		minlength: 20,
		messages: {
		    required: "Required input",
		    minlength: jQuery.format("At least {0} characters are necessary")
		}
	    });

	} else {
	    jQuery("#placeling_tagged_place").html("");
	    jQuery("#add_place .placeling_place_name").html( "" );
	    jQuery("#add_place #placeling_tagged").hide();
	    jQuery("#add_place #placeling_untagged").show();
	    jQuery("#empty_place").show();
	    jQuery("#placeling_tagged_place").hide();
	}
}

function getPlacelingAdminTemplate(){
	return _.template("
		\

						\
				    <img src='<%= map_url %>'/>							\

										\

						\

<%= name %>
			\

<%= street_address %>
	\

<%= city_data %>
			\

										\

						\

remove place
	\

										\

		\

 			\

					\
			    <fieldset>									\

Placemark Note
				\
				    <textarea id='placeling_placemark_memo' rows='5' cols='50' name='placeling_placemark_memo'></textarea>\

<input name='placeling_placemark_photos' type='checkbox' id='placeling_placemark_photos' checked='checked'>Attach Photos?
 \
			    </fieldset>									\

		\
	");

}

<|endoftext|>


<commit_before>const {ipcRenderer} = require('electron');
const marked = require('marked');
const renderer = new marked.Renderer();
const hljs = require('highlight.js');
const fs = require('fs');
const path = require('path');
const Viz = require("viz.js");

marked.setOptions({
  renderer: renderer,
  gfm: true,
  breaks: false
});

// escape HTML special characters
// from: http://qiita.com/noriaki/items/4bfef8d7cf85dc1035b3
function escapeHtml(content) {
  var TABLE_FOR_ESCAPE_HTML = {
    "&": "&",
    "\"": """,
    "<": "<",
    ">": ">"
  };
  return content.replace(/[&"<>]/g, function(match) {
    return TABLE_FOR_ESCAPE_HTML[match];
  });
}

// redering code
renderer.code = function (code, language) {
  const CONV_ERR_HEAD = "\n******************* Convert Error *******************\n";
  const CONV_ERR_TAIL = "*****************************************************\n";
  if (language == "graphviz") {
    let result;
    try {
      result = Viz(code);
      return result;
    } catch (error) {
      return '
' + hljs.highlightAuto(code).value + CONV_ERR_HEAD + error + CONV_ERR_TAIL +'
';
    }
  } else {
    return '
' + hljs.highlightAuto(code).value + '
';
  }
}

// rendering list
renderer.listitem = function (text) {
  if (text.startsWith("[x]")) {
    return '
<input type="checkbox" checked="true" disabled="true">' + text.slice(3) + '
';
  } else if (text.startsWith("[ ]")) {
    return '
<input type="checkbox" disabled="true">' + text.slice(3) + '
';
  } else {
    return '
' + text + '
';
  }
}

// rendering html (sanitize script)
renderer.html = function (html) {
  if (html.match(/<[^>]*script[^>]*>/g) !== null) {
    return '
' + html.replace(/\</g, "<").replace(/\>/g, ">").trim() + '
';
  } else if (html.match(/<[^>]* on[^=>]*=/) !== null) {
    return '
' + html.replace(/\</g, "<").replace(/\>/g, ">").trim() + '
';
  } else {
    return html;
  }
}

// request preview
ipcRenderer.on('preview', function(event, data, baseURI) {
  let base = document.getElementsByTagName("base")[0];
  if (baseURI != "") {
    base.setAttribute("href", baseURI);
  }
  base.setAttribute("target", "_blank");
  document.getElementById('body').innerHTML = marked(data, { renderer: renderer });
  document.title = document.getElementsByTagName("h1")[0].innerHTML;
});

// request export HTML
ipcRenderer.on('export-HTML', function(event, filename) {
  let base = document.getElementsByTagName("base")[0];
  base.removeAttribute("href");
  base.removeAttribute("target");

  // http://blog.mudatobunka.org/entry/2015/12/23/211425#postscript
  fs.writeFile (filename, new XMLSerializer().serializeToString(document), function (error) {
    if (error != null) {
      alert ('error: ' + error + '\n' + filename);
      return;
    }
    let src_css = path.join(__dirname, '../templates/github.css');
    let dest_css = path.join(path.dirname(filename), "github.css");
    fs.createReadStream(src_css).pipe(fs.createWriteStream(dest_css));
  });

  base.setAttribute("target", "_blank");
});

<commit_msg>add uiflow support<commit_after>const {ipcRenderer} = require('electron');
const marked = require('marked');
const renderer = new marked.Renderer();
const hljs = require('highlight.js');
const fs = require('fs');
const path = require('path');
const Viz = require("viz.js");
const uiflow = require("uiflow");

marked.setOptions({
  renderer: renderer,
  gfm: true,
  breaks: false
});

// escape HTML special characters
// from: http://qiita.com/noriaki/items/4bfef8d7cf85dc1035b3
function escapeHtml(content) {
  var TABLE_FOR_ESCAPE_HTML = {
    "&": "&",
    "\"": """,
    "<": "<",
    ">": ">"
  };
  return content.replace(/[&"<>]/g, function(match) {
    return TABLE_FOR_ESCAPE_HTML[match];
  });
}

// redering code
renderer.code = function (code, language) {
  const CONV_ERR_HEAD = "\n******************* Convert Error *******************\n";
  const CONV_ERR_TAIL = "*****************************************************\n";
  if (language == "graphviz") {
    let result;
    try {
      result = Viz(code);
      return result;
    } catch (error) {
      return '
' + hljs.highlightAuto(code).value + CONV_ERR_HEAD + error + CONV_ERR_TAIL +'
';
    }
  } else if(language == "uiflow") {
    try {
      let dot = uiflow.compile(code);
      return Viz(dot);
    } catch (error) {
      console.log(error);
      return '
' + escapeHtml(code) + CONV_ERR_HEAD + error + '\n' + CONV_ERR_TAIL +'
';
    }
  } else {
    return '
' + hljs.highlightAuto(code).value + '
';
  }
}

// rendering list
renderer.listitem = function (text) {
  if (text.startsWith("[x]")) {
    return '
<input type="checkbox" checked="true" disabled="true">' + text.slice(3) + '
';
  } else if (text.startsWith("[ ]")) {
    return '
<input type="checkbox" disabled="true">' + text.slice(3) + '
';
  } else {
    return '
' + text + '
';
  }
}

// rendering html (sanitize script)
renderer.html = function (html) {
  if (html.match(/<[^>]*script[^>]*>/g) !== null) {
    return '
' + html.replace(/\</g, "<").replace(/\>/g, ">").trim() + '
';
  } else if (html.match(/<[^>]* on[^=>]*=/) !== null) {
    return '
' + html.replace(/\</g, "<").replace(/\>/g, ">").trim() + '
';
  } else {
    return html;
  }
}

// request preview
ipcRenderer.on('preview', function(event, data, baseURI) {
  let base = document.getElementsByTagName("base")[0];
  if (baseURI != "") {
    base.setAttribute("href", baseURI);
  }
  base.setAttribute("target", "_blank");
  document.getElementById('body').innerHTML = marked(data, { renderer: renderer });
  document.title = document.getElementsByTagName("h1")[0].innerHTML;
});

// request export HTML
ipcRenderer.on('export-HTML', function(event, filename) {
  let base = document.getElementsByTagName("base")[0];
  base.removeAttribute("href");
  base.removeAttribute("target");

  // http://blog.mudatobunka.org/entry/2015/12/23/211425#postscript
  fs.writeFile (filename, new XMLSerializer().serializeToString(document), function (error) {
    if (error != null) {
      alert ('error: ' + error + '\n' + filename);
      return;
    }
    let src_css = path.join(__dirname, '../templates/github.css');
    let dest_css = path.join(path.dirname(filename), "github.css");
    fs.createReadStream(src_css).pipe(fs.createWriteStream(dest_css));
  });

  base.setAttribute("target", "_blank");
});

<|endoftext|>


<commit_before>'use strict';

var app_initialized = false;
var data_table = null;

var defaults = {
  cost_duration: 'hourly',
  region: 'us-east-1',
  reserved_term: 'yrTerm1Standard.noUpfront',
  min_memory: 0,
  min_computeunits: 0,
  min_storage: 0
};

var settings = store.get('ec2_settings') || {};
for (var key in defaults) {
  if (settings[key] === undefined) {
    settings[key] = defaults[key];
  }
}

function init_data_table() {
  data_table = $('#data').DataTable({
    "bPaginate": false,
    "bInfo": false,
    "bStateSave": true,
    "oSearch": {
      "bRegex": true,
      "bSmart": false
    },
    "aoColumnDefs": [
      {
        "aTargets": [
          "memory",
          "computeunits",
          "vcpus",
          "storage",
          "ebs-throughput",
          "ebs-iops",
          "ebs-max-bandwidth",
          "networkperf",
          "cost-ondemand",
          "cost-reserved"
        ],
        "sType": "span-sort"
      },
      {
        "aTargets": [
          "ecu-per-vcpu",
          "enhanced-networking",
          "maxips",
          "linux-virtualization",
          "cost-ondemand-mswinSQLWeb",
          "cost-ondemand-mswinSQL",
          "cost-reserved-mswinSQLWeb",
          "cost-reserved-mswinSQL",
          "ebs-throughput",
          "ebs-iops",
          "max_bandwidth"
        ],
        "bVisible": false
      }
    ],
    // default sort by linux cost
    "aaSorting": [
      [15, "asc"]
    ],
    'initComplete': function () {
      // fire event in separate context so that calls to get_data_table()
      // receive the cached object.
      setTimeout(function () {
        on_data_table_initialized();
      }, 0);
    },
    'drawCallback': function () {
      // abort if initialization hasn't finished yet (initial draw)
      if (data_table === null) {
        return;
      }

      // Whenever the table is drawn, update the costs. This is necessary
      // because the cost duration may have changed while a filter was being
      // used and so some rows will need updating.
      redraw_costs();
    },
    // Store filtering, sorting, etc - core datatable feature
    'stateSave': true
  });

  return data_table;
}

$(document).ready(function () {
  init_data_table();
});

function change_cost(duration) {
  // update menu text
  var first = duration.charAt(0).toUpperCase();
  var text = first + duration.substr(1);
  $("#cost-dropdown .dropdown-toggle .text").text(text);

  // update selected menu option
  $('#cost-dropdown li a').each(function (i, e) {
    e = $(e);
    if (e.attr('duration') == duration) {
      e.parent().addClass('active');
    } else {
      e.parent().removeClass('active');
    }
  });

  var hour_multipliers = {
    "hourly": 1,
    "daily": 24,
    "weekly": (7 * 24),
    "monthly": (365 * 24 / 12),
    "annually": (365 * 24)
  };
  var multiplier = hour_multipliers[duration];
  var per_time;
  $.each($("td.cost-ondemand"), function (i, elem) {
    elem = $(elem);
    per_time = elem.data("pricing")[settings.region];
    if (per_time && !isNaN(per_time)) {
      per_time = (per_time * multiplier).toFixed(3);
      elem.text("$" + per_time + " " + duration);
    } else {
      elem.text("unavailable");
    }
  });

  $.each($("td.cost-reserved"), function (i, elem) {
    elem = $(elem);
    per_time = elem.data("pricing")[settings.region];

    if (!per_time) {
      elem.text("unavailable");
      return;
    }

    per_time = per_time[settings.reserved_term];

    if (per_time && !isNaN(per_time)) {
      per_time = (per_time * multiplier).toFixed(3);
      elem.text("$" + per_time + " " + duration);
    } else {
      elem.text("unavailable");
    }
  });

  settings.cost_duration = duration;
  maybe_update_url();
}

function change_region(region) {
  settings.region = region;
  var region_name = null;
  $('#region-dropdown li a').each(function (i, e) {
    e = $(e);
    if (e.data('region') === region) {
      e.parent().addClass('active');
      region_name = e.text();
    } else {
      e.parent().removeClass('active');
    }
  });
  $("#region-dropdown .dropdown-toggle .text").text(region_name);
  change_cost(settings.cost_duration);
}

function change_reserved_term(term) {
  settings.reserved_term = term;
  var $dropdown = $('#reserved-term-dropdown'),
    $activeLink = $dropdown.find('li a[data-reserved-term="' + term + '"]'),
    term_name = $activeLink.text();

  $dropdown.find('li').removeClass('active');
  $activeLink.closest('li').addClass('active');

  $dropdown.find('.dropdown-toggle .text').text(term_name);
  change_cost(settings.cost_duration);
}

// Update all visible costs to the current duration.
// Called after new columns or rows are shown as their costs may be inaccurate.
function redraw_costs() {
  change_cost(settings.cost_duration);
}

function setup_column_toggle() {
  $.each(data_table.columns().indexes(), function (i, idx) {
    var column = data_table.column(idx);
    $("#filter-dropdown ul").append(
      $('<li>')
        .toggleClass('active', column.visible())
        .append(
          $('<a>', {href: "javascript:;"})
            .text($(column.header()).text())
            .click(function (e) {
              toggle_column(i);
              $(this).parent().toggleClass("active");
              $(this).blur(); // prevent focus style from sticking in Firefox
              e.stopPropagation(); // keep dropdown menu open
            })
        )
    );
  });
}

function setup_clear() {
  $('.btn-clear').click(function () {
    // Reset app.
    settings = JSON.parse(JSON.stringify(defaults)); // clone
    clear_row_selections();
    maybe_update_url();
    store.clear();
    data_table.state.clear();
    window.location.reload();
  });
}

function clear_row_selections() {
  $('#data tbody tr').removeClass('highlight');
}

function url_for_selections() {
  var params = {
    min_memory: settings.min_memory,
    min_computeunits: settings.min_computeunits,
    min_storage: settings.min_storage,
    filter: data_table.settings()[0].oPreviousSearch['sSearch'],
    region: settings.region,
    cost_duration: settings.cost_duration,
    reserved_term: settings.reserved_term
  };

  // avoid storing empty or default values in URL
  for (var key in params) {
    if (params[key] === '' || params[key] == null || params[key] === defaults[key]) {
      delete params[key];
    }
  }

  // selected rows
  var selected_row_ids = $('#data tbody tr.highlight').map(function () {
    return this.id;
  }).get();
  if (selected_row_ids.length > 0) {
    params.selected = selected_row_ids;
  }

  var url = location.origin + location.pathname;
  var parameters = [];
  for (var setting in params) {
    if (params[setting] !== undefined) {
      parameters.push(setting + '=' + params[setting]);
    }
  }
  if (parameters.length > 0) {
    url = url + '?' + parameters.join('&');
  }
  return url;
}

function maybe_update_url() {
  // Save localstorage data as well
  store.set('ec2_settings', settings);

  if (!history.replaceState) {
    return;
  }

  try {
    var url = url_for_selections();
    if (document.location == url) {
      return;
    }

    history.replaceState(null, '', url);
  } catch (ex) {
    // doesn't matter
  }
}

var apply_min_values = function () {
  var all_filters = $('[data-action="datafilter"]');
  var data_rows = $('#data tr:has(td)');

  data_rows.show();

  all_filters.each(function () {
    var filter_on = $(this).data('type');
    var filter_val = parseFloat($(this).val()) || 0;

    // update global variable for dynamic URL
    settings["min_" + filter_on] = filter_val;

    var match_fail = data_rows.filter(function () {
      var row_val;
      row_val = parseFloat(
        $(this).find('td[class~="' + filter_on + '"] span').attr('sort')
      );
      return row_val < filter_val;
    });

    match_fail.hide();
  });
  maybe_update_url();
};

function on_data_table_initialized() {
  if (app_initialized) return;
  app_initialized = true;

  // process URL settings
  var url_settings = get_url_parameters();
  for (var key in url_settings) {
    switch (key) {
      case 'region':
        settings.region = url_settings['region'];
        break;
      case 'cost_duration':
        settings.cost_duration = url_settings['cost_duration'];
        break;
      case 'reserved_term':
        settings.reserved_term = url_settings['reserved_term'];
        break;
      case 'filter':
        data_table.filter(url_settings['filter']);
        break;
      case 'min_memory':
        $('[data-action="datafilter"][data-type="memory"]').val(url_settings['min_memory']);
        apply_min_values();
        break;
      case 'min_computeunits':
        $('[data-action="datafilter"][data-type="computeunits"]').val(url_settings['min_computeunits']);
        apply_min_values();
        break;
      case 'min_storage':
        $('[data-action="datafilter"][data-type="storage"]').val(url_settings['min_storage']);
        apply_min_values();
        break;
      case 'selected':
        // apply highlight to selected rows
        $.each(url_settings['selected'].split(','), function (_, id) {
          id = id.replace('.', '\\.');
          $('#' + id).addClass('highlight');
        });
        break;
    }
  }

  configure_highlighting();

  // Allow row filtering by min-value match.
  $('[data-action=datafilter]').on('keyup', apply_min_values);

  change_region(settings.region);
  change_cost(settings.cost_duration);
  change_reserved_term(settings.reserved_term);

  $.extend($.fn.dataTableExt.oStdClasses, {
    "sWrapper": "dataTables_wrapper form-inline"
  });

  setup_column_toggle();

  setup_clear();

  // enable bootstrap tooltips
  $('abbr').tooltip({
    placement: function (tt, el) {
      return (this.$element.parents('thead').length) ? 'top' : 'right';
    }
  });

  $("#cost-dropdown li").bind("click", function (e) {
    change_cost(e.target.getAttribute("duration"));
  });

  $("#region-dropdown li").bind("click", function (e) {
    change_region($(e.target).data('region'));
  });

  $("#reserved-term-dropdown li").bind("click", function (e) {
    change_reserved_term($(e.target).data('reservedTerm'));
  });

  // apply classes to search box
  $('div.dataTables_filter input').addClass('form-control search');
}

// sorting for colums with more complex data
// http://datatables.net/plug-ins/sorting#hidden_title
jQuery.extend(jQuery.fn.dataTableExt.oSort, {
  "span-sort-pre": function (elem) {
    var matches = elem.match(/sort="(.*?)"/);
    if (matches) {
      return parseFloat(matches[1]);
    }
    return 0;
  },

  "span-sort-asc": function (a, b) {
    return ((a < b) ? -1 : ((a > b) ? 1 : 0));
  },

  "span-sort-desc": function (a, b) {
    return ((a < b) ? 1 : ((a > b) ? -1 : 0));
  }
});

// toggle columns
function toggle_column(col_index) {
  var is_visible = data_table.column(col_index).visible();
  data_table.column(col_index).visible(is_visible ? false : true);
  redraw_costs();
}

// retrieve all the parameters from the location string
function get_url_parameters() {
  var settings = {};
  if (!location.search) {
    return settings;
  }
  var params = location.search.slice(1).split('&');
  params.forEach(function (param) {
    var parts = param.split('=');
    var key = parts[0];
    var val = parts[1];
    // support legacy key names
    if (key == 'cost') {
      key = 'cost_duration';
    } else if (key == 'term') {
      key = 'reserved_term';
    }
    settings[key] = val;
  });

  return settings;
}

function configure_highlighting() {
  var compareOn = false,
    $compareBtn = $('.btn-compare'),
    $rows = $('#data tbody tr');

  // Allow row highlighting by clicking.
  $rows.click(function () {
    $(this).toggleClass('highlight');

    if (!compareOn) {
      $compareBtn.prop('disabled', !$rows.is('.highlight'));
    }

    maybe_update_url();
  });

  $compareBtn.prop('disabled', !$($rows).is('.highlight'));
  $compareBtn.text($compareBtn.data('textOff'));

  $compareBtn.click(function () {
    if (compareOn) {
      $rows.show();
      $compareBtn.text($compareBtn.data('textOff'))
        .addClass('btn-primary')
        .removeClass('btn-success')
        .prop('disabled', !$rows.is('.highlight'));
    } else {
      $rows.filter(':not(.highlight)').hide();
      $compareBtn.text($compareBtn.data('textOn'))
        .addClass('btn-success')
        .removeClass('btn-primary');
    }

    compareOn = !compareOn;
  });
}
<commit_msg>Properly use settings stored in localstorage when no URL params are available<commit_after>'use strict';

var app_initialized = false;
var data_table = null;

var defaults = {
  cost_duration: 'hourly',
  region: 'us-east-1',
  reserved_term: 'yrTerm1Standard.noUpfront',
  min_memory: 0,
  min_computeunits: 0,
  min_storage: 0
};

var settings = store.get('ec2_settings') || {};
for (var key in defaults) {
  if (settings[key] === undefined) {
    settings[key] = defaults[key];
  }
}

function init_data_table() {
  data_table = $('#data').DataTable({
    "bPaginate": false,
    "bInfo": false,
    "bStateSave": true,
    "oSearch": {
      "bRegex": true,
      "bSmart": false
    },
    "aoColumnDefs": [
      {
        "aTargets": [
          "memory",
          "computeunits",
          "vcpus",
          "storage",
          "ebs-throughput",
          "ebs-iops",
          "ebs-max-bandwidth",
          "networkperf",
          "cost-ondemand",
          "cost-reserved"
        ],
        "sType": "span-sort"
      },
      {
        "aTargets": [
          "ecu-per-vcpu",
          "enhanced-networking",
          "maxips",
          "linux-virtualization",
          "cost-ondemand-mswinSQLWeb",
          "cost-ondemand-mswinSQL",
          "cost-reserved-mswinSQLWeb",
          "cost-reserved-mswinSQL",
          "ebs-throughput",
          "ebs-iops",
          "max_bandwidth"
        ],
        "bVisible": false
      }
    ],
    // default sort by linux cost
    "aaSorting": [
      [15, "asc"]
    ],
    'initComplete': function () {
      // fire event in separate context so that calls to get_data_table()
      // receive the cached object.
      setTimeout(function () {
        on_data_table_initialized();
      }, 0);
    },
    'drawCallback': function () {
      // abort if initialization hasn't finished yet (initial draw)
      if (data_table === null) {
        return;
      }

      // Whenever the table is drawn, update the costs. This is necessary
      // because the cost duration may have changed while a filter was being
      // used and so some rows will need updating.
      redraw_costs();
    },
    // Store filtering, sorting, etc - core datatable feature
    'stateSave': true
  });

  return data_table;
}

$(document).ready(function () {
  init_data_table();
});

function change_cost(duration) {
  // update menu text
  var first = duration.charAt(0).toUpperCase();
  var text = first + duration.substr(1);
  $("#cost-dropdown .dropdown-toggle .text").text(text);

  // update selected menu option
  $('#cost-dropdown li a').each(function (i, e) {
    e = $(e);
    if (e.attr('duration') == duration) {
      e.parent().addClass('active');
    } else {
      e.parent().removeClass('active');
    }
  });

  var hour_multipliers = {
    "hourly": 1,
    "daily": 24,
    "weekly": (7 * 24),
    "monthly": (365 * 24 / 12),
    "annually": (365 * 24)
  };
  var multiplier = hour_multipliers[duration];
  var per_time;
  $.each($("td.cost-ondemand"), function (i, elem) {
    elem = $(elem);
    per_time = elem.data("pricing")[settings.region];
    if (per_time && !isNaN(per_time)) {
      per_time = (per_time * multiplier).toFixed(3);
      elem.text("$" + per_time + " " + duration);
    } else {
      elem.text("unavailable");
    }
  });

  $.each($("td.cost-reserved"), function (i, elem) {
    elem = $(elem);
    per_time = elem.data("pricing")[settings.region];

    if (!per_time) {
      elem.text("unavailable");
      return;
    }

    per_time = per_time[settings.reserved_term];

    if (per_time && !isNaN(per_time)) {
      per_time = (per_time * multiplier).toFixed(3);
      elem.text("$" + per_time + " " + duration);
    } else {
      elem.text("unavailable");
    }
  });

  settings.cost_duration = duration;
  maybe_update_url();
}

function change_region(region) {
  settings.region = region;
  var region_name = null;
  $('#region-dropdown li a').each(function (i, e) {
    e = $(e);
    if (e.data('region') === region) {
      e.parent().addClass('active');
      region_name = e.text();
    } else {
      e.parent().removeClass('active');
    }
  });
  $("#region-dropdown .dropdown-toggle .text").text(region_name);
  change_cost(settings.cost_duration);
}

function change_reserved_term(term) {
  settings.reserved_term = term;
  var $dropdown = $('#reserved-term-dropdown'),
    $activeLink = $dropdown.find('li a[data-reserved-term="' + term + '"]'),
    term_name = $activeLink.text();

  $dropdown.find('li').removeClass('active');
  $activeLink.closest('li').addClass('active');

  $dropdown.find('.dropdown-toggle .text').text(term_name);
  change_cost(settings.cost_duration);
}

// Update all visible costs to the current duration.
// Called after new columns or rows are shown as their costs may be inaccurate.
function redraw_costs() {
  change_cost(settings.cost_duration);
}

function setup_column_toggle() {
  $.each(data_table.columns().indexes(), function (i, idx) {
    var column = data_table.column(idx);
    $("#filter-dropdown ul").append(
      $('<li>')
        .toggleClass('active', column.visible())
        .append(
          $('<a>', {href: "javascript:;"})
            .text($(column.header()).text())
            .click(function (e) {
              toggle_column(i);
              $(this).parent().toggleClass("active");
              $(this).blur(); // prevent focus style from sticking in Firefox
              e.stopPropagation(); // keep dropdown menu open
            })
        )
    );
  });
}

function setup_clear() {
  $('.btn-clear').click(function () {
    // Reset app.
    settings = JSON.parse(JSON.stringify(defaults)); // clone
    clear_row_selections();
    maybe_update_url();
    store.clear();
    data_table.state.clear();
    window.location.reload();
  });
}

function clear_row_selections() {
  $('#data tbody tr').removeClass('highlight');
}

function url_for_selections() {
  var params = {
    min_memory: settings.min_memory,
    min_computeunits: settings.min_computeunits,
    min_storage: settings.min_storage,
    filter: data_table.settings()[0].oPreviousSearch['sSearch'],
    region: settings.region,
    cost_duration: settings.cost_duration,
    reserved_term: settings.reserved_term
  };

  // avoid storing empty or default values in URL
  for (var key in params) {
    if (params[key] === '' || params[key] == null || params[key] === defaults[key]) {
      delete params[key];
    }
  }

  // selected rows
  var selected_row_ids = $('#data tbody tr.highlight').map(function () {
    return this.id;
  }).get();
  if (selected_row_ids.length > 0) {
    params.selected = selected_row_ids;
  }

  var url = location.origin + location.pathname;
  var parameters = [];
  for (var setting in params) {
    if (params[setting] !== undefined) {
      parameters.push(setting + '=' + params[setting]);
    }
  }
  if (parameters.length > 0) {
    url = url + '?' + parameters.join('&');
  }
  return url;
}

function maybe_update_url() {
  // Save localstorage data as well
  store.set('ec2_settings', settings);

  if (!history.replaceState) {
    return;
  }

  try {
    var url = url_for_selections();
    if (document.location == url) {
      return;
    }

    history.replaceState(null, '', url);
  } catch (ex) {
    // doesn't matter
  }
}

var apply_min_values = function () {
  var all_filters = $('[data-action="datafilter"]');
  var data_rows = $('#data tr:has(td)');

  data_rows.show();

  all_filters.each(function () {
    var filter_on = $(this).data('type');
    var filter_val = parseFloat($(this).val()) || 0;

    // update global variable for dynamic URL
    settings["min_" + filter_on] = filter_val;

    var match_fail = data_rows.filter(function () {
      var row_val;
      row_val = parseFloat(
        $(this).find('td[class~="' + filter_on + '"] span').attr('sort')
      );
      return row_val < filter_val;
    });

    match_fail.hide();
  });
  maybe_update_url();
};

function on_data_table_initialized() {
  if (app_initialized) return;
  app_initialized = true;

  // process URL settings
  var url_settings = get_url_parameters();
  for (var key in url_settings) {
    switch (key) {
      case 'region':
        settings.region = url_settings['region'];
        break;
      case 'cost_duration':
        settings.cost_duration = url_settings['cost_duration'];
        break;
      case 'reserved_term':
        settings.reserved_term = url_settings['reserved_term'];
        break;
      case 'filter':
        data_table.filter(url_settings['filter']);
        break;
      case 'min_memory':
        $('[data-action="datafilter"][data-type="memory"]').val(url_settings['min_memory']);
        apply_min_values();
        break;
      case 'min_computeunits':
        $('[data-action="datafilter"][data-type="computeunits"]').val(url_settings['min_computeunits']);
        apply_min_values();
        break;
      case 'min_storage':
        $('[data-action="datafilter"][data-type="storage"]').val(url_settings['min_storage']);
        apply_min_values();
        break;
      case 'selected':
        // apply highlight to selected rows
        $.each(url_settings['selected'].split(','), function (_, id) {
          id = id.replace('.', '\\.');
          $('#' + id).addClass('highlight');
        });
        break;
    }
  }

  configure_highlighting();

  // Allow row filtering by min-value match.
  $('[data-action=datafilter]').on('keyup', apply_min_values);

  change_region(settings.region);
  change_cost(settings.cost_duration);
  change_reserved_term(settings.reserved_term);

  $.extend($.fn.dataTableExt.oStdClasses, {
    "sWrapper": "dataTables_wrapper form-inline"
  });

  setup_column_toggle();

  setup_clear();

  // enable bootstrap tooltips
  $('abbr').tooltip({
    placement: function (tt, el) {
      return (this.$element.parents('thead').length) ? 'top' : 'right';
    }
  });

  $("#cost-dropdown li").bind("click", function (e) {
    change_cost(e.target.getAttribute("duration"));
  });

  $("#region-dropdown li").bind("click", function (e) {
    change_region($(e.target).data('region'));
  });

  $("#reserved-term-dropdown li").bind("click", function (e) {
    change_reserved_term($(e.target).data('reservedTerm'));
  });

  // apply classes to search box
  $('div.dataTables_filter input').addClass('form-control search');
}

// sorting for colums with more complex data
// http://datatables.net/plug-ins/sorting#hidden_title
jQuery.extend(jQuery.fn.dataTableExt.oSort, {
  "span-sort-pre": function (elem) {
    var matches = elem.match(/sort="(.*?)"/);
    if (matches) {
      return parseFloat(matches[1]);
    }
    return 0;
  },

  "span-sort-asc": function (a, b) {
    return ((a < b) ? -1 : ((a > b) ? 1 : 0));
  },

  "span-sort-desc": function (a, b) {
    return ((a < b) ? 1 : ((a > b) ? -1 : 0));
  }
});

// toggle columns
function toggle_column(col_index) {
  var is_visible = data_table.column(col_index).visible();
  data_table.column(col_index).visible(is_visible ? false : true);
  redraw_costs();
}

// retrieve all the parameters from the location string
function get_url_parameters() {
  if (!location.search) {
    // when no URL params, return global settings (possibly initialized from localstorage)
    return settings;
  }
  var params = location.search.slice(1).split('&');
  params.forEach(function (param) {
    var parts = param.split('=');
    var key = parts[0];
    var val = parts[1];
    // support legacy key names
    if (key == 'cost') {
      key = 'cost_duration';
    } else if (key == 'term') {
      key = 'reserved_term';
    }
    settings[key] = val;
  });

  return settings;
}

function configure_highlighting() {
  var compareOn = false,
    $compareBtn = $('.btn-compare'),
    $rows = $('#data tbody tr');

  // Allow row highlighting by clicking.
  $rows.click(function () {
    $(this).toggleClass('highlight');

    if (!compareOn) {
      $compareBtn.prop('disabled', !$rows.is('.highlight'));
    }

    maybe_update_url();
  });

  $compareBtn.prop('disabled', !$($rows).is('.highlight'));
  $compareBtn.text($compareBtn.data('textOff'));

  $compareBtn.click(function () {
    if (compareOn) {
      $rows.show();
      $compareBtn.text($compareBtn.data('textOff'))
        .addClass('btn-primary')
        .removeClass('btn-success')
        .prop('disabled', !$rows.is('.highlight'));
    } else {
      $rows.filter(':not(.highlight)').hide();
      $compareBtn.text($compareBtn.data('textOn'))
        .addClass('btn-success')
        .removeClass('btn-primary');
    }

    compareOn = !compareOn;
  });
}
<|endoftext|>


<commit_before>/*
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
Copyright (c) 2014 Mozilla Corporation

Contributors:
Jeff Bryner jbryner@mozilla.com
Anthony Verez averez@mozilla.com
*/

//configuration settings

mozdef = {
  rootURL: "http://localhost",
  port: "80",
  rootAPI: "http://localhost:8081",
  kibanaURL: "http://localhost:9090/app/kibana#",
  enableBlockIP: false,
  enableClientAccountCreation: true
}
<commit_msg>Use password auth in single docker container config<commit_after>/*
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
Copyright (c) 2014 Mozilla Corporation

Contributors:
Jeff Bryner jbryner@mozilla.com
Anthony Verez averez@mozilla.com
*/

//configuration settings

mozdef = {
  rootURL: "http://localhost",
  port: "80",
  rootAPI: "http://localhost:8081",
  kibanaURL: "http://localhost:9090/app/kibana#",
  enableBlockIP: false,
  enableClientAccountCreation: true,
  authenticationType: "meteor-password"
}
<|endoftext|>


<commit_before>//This is a file for miscellaneous commands.

exports.commands = {
  hc: function(target, room, user) {
    return this.parse('/hotpatch chat')
  }
}
<commit_msg>Update alpha.js<commit_after>/**
 * Miscellaneous commands
 */

'use strict';
/*eslint no-restricted-modules: [0]*/

let moment = require('moment');
let request = require('request');
const color = require('../config/color');
let fs = require('fs');

let messages = [
	"ventured into Shrek's Swamp.",
	"disrespected the OgreLord!",
	"used Explosion!",
	"was swallowed up by the Earth!",
	"was eaten by Lex!",
	"was sucker punched by Absol!",
	"has left the building.",
	"got lost in the woods!",
	"left for their lover!",
	"couldn't handle the coldness of Frost!",
	"was hit by Magikarp's Revenge!",
	"was sucked into a whirlpool!",
	"got scared and left the server!",
	"went into a cave without a repel!",
	"got eaten by a bunch of piranhas!",
	"ventured too deep into the forest without an escape rope",
	"got shrekt",
	"woke up an angry Snorlax!",
	"was forced to give jd an oil massage!",
	"was used as shark bait!",
	"peered through the hole on Shedinja's back",
	"received judgment from the almighty Arceus!",
	"used Final Gambit and missed!",
	"went into grass without any Pokemon!",
	"made a Slowbro angry!",
	"took a focus punch from Breloom!",
	"got lost in the illusion of reality.",
	"ate a bomb!",
	"left for a timeout!",
	"fell into a snake pit!",
	"has vanished into nothingness!",
	"used Explosion!",
	"fell into the void.",
	"went into a cave without a repel!",
	"has left the building.",
	"was forced to give StevoDuhHero's mom an oil massage!",
	"was hit by Magikarp's Revenge!",
	"ate a bomb!",
	"is blasting off again!",
	"(Quit: oh god how did this get here i am not good with computer)",
	"was unfortunate and didn't get a cool message.",
	"{{user}}'s mama accidently kicked {{user}} from the server!",
];

function clearRoom(room) {
	let len = (room.log && room.log.length) || 0;
	let users = [];
	while (len--) {
		room.log[len] = '';
	}
	for (let u in room.users) {
		users.push(u);
		Users.get(u).leaveRoom(room, Users.get(u).connections[0]);
	}
	len = users.length;
	setTimeout(function () {
		while (len--) {
			Users.get(users[len]).joinRoom(room, Users.get(users[len]).connections[0]);
		}
	}, 1000);
}

exports.commands = {
	 shoppm: function (target, room, user) {
        if (!user.canShopPM) return this.sendReply('You need to buy this item from the shop to use.');
        if (!target) return this.sendReply('/shoppm [message] - PM all users in the server.');
        if (target.indexOf('/html') >= 0) return this.sendReply('Cannot contain /html.');

        let pmName = '~Global PM from ' + user.name +' [Do not reply]';

        Users.users.forEach(function (user) {
            let message = '|pm|' + pmName + '|' + user.getIdentity() + '|' + target;
            user.send(message);
        });
        user.canShopPM = false;
    },

	stafflist: 'al',
	authlist: 'al',
	auth: 'al',
	authlist: 'al',
	al: function(target, room, user, connection) {
		fs.readFile('config/usergroups.csv', 'utf8', function(err, data) {
			var staff = {
				"admins": [],
				"leaders": [],
				"mods": [],
				"drivers": [],
				"operators": [],
				"voices": []
			};
			var row = ('' + data).split('\n');
			for (var i = row.length; i > -1; i--) {
				if (!row[i]) continue;
				var rank = row[i].split(',')[1].replace("\r", '');
				var person = row[i].split(',')[0];
				function nameColor (name) {
					if (Users.getExact(name) && Users(name).connected) {
						return '' + Tools.escapeHTML(Users.getExact(name).name) + '';
					} else {
						return '' + Tools.escapeHTML(name) + '';
					}
				}
				switch (rank) {
					case '~':
						staff['admins'].push(nameColor(person));
						break;
					case '&':
						if (toId(person) === 'tintins') break;
						staff['leaders'].push(nameColor(person));
						break;
					case '@':
						staff['mods'].push(nameColor(person));
						break;
					case '%':
						staff['drivers'].push(nameColor(person));
						break;
					case '$':
						staff['operators'].push(nameColor(person));
						break;
					case '+':
						staff['voices'].push(nameColor(person));
						break;
					default:
						continue;
				}
			}
			connection.popup('|html|' +
				'
Server Authority List
' +
				'~Administrators (' + staff['admins'].length + '):
' + staff['admins'].join(', ') +
				'
&Leaders (' + staff['leaders'].length + '):
' + staff['leaders'].join(', ') +
				'
@Moderators (' + staff['mods'].length + '):
' + staff['mods'].join(', ') +
				'
%Drivers (' + staff['drivers'].length + '):
' + staff['drivers'].join(', ') +
				'
$Operators (' + staff['operators'].length + '):
' + staff['operators'].join(', ') +
				'
+Voices (' + staff['voices'].length + '):
' + staff['voices'].join(', ') +
				'

<blink>(Bold / italic = currently online)</blink>'
			);
		});
	},

	clearall: function (target, room, user) {
		if (!this.can('declare')) return false;
		if (room.battle) return this.sendReply("You cannot clearall in battle rooms.");

		clearRoom(room);
	},

	gclearall: 'globalclearall',
	globalclearall: function (target, room, user) {
		if (!this.can('gdeclare')) return false;

		for (let u in Users.users) {
			Users.users[u].popup("All rooms are being clear.");
		}

		for (let r in Rooms.rooms) {
			clearRoom(Rooms.rooms[r]);
		}
	},

	hide: function (target, room, user) {
		if (!this.can('lock')) return false;
		user.hiding = true;
		user.updateIdentity();
		this.sendReply("You have hidden your staff symbol.");
	},

	rk: 'kick',
	roomkick: 'kick',
	kick: function (target, room, user) {
		if (!target) return this.parse('/help kick');
		if (!this.canTalk() && !user.can('bypassall')) {
			return this.sendReply("You cannot do this while unable to talk.");
		}

		target = this.splitTarget(target);
		let targetUser = this.targetUser;
		if (!targetUser || !targetUser.connected) return this.sendReply("User \"" + this.targetUsername + "\" not found.");
		if (!this.can('mute', targetUser, room)) return false;

		this.addModCommand(targetUser.name + " was kicked from the room by " + user.name + ".");
		targetUser.popup("You were kicked from " + room.id + " by " + user.name + ".");
		targetUser.leaveRoom(room.id);
	},
	kickhelp: ["/kick - Kick a user out of a room. Requires: % @ # & ~"],

	masspm: 'pmall',
	pmall: function (target, room, user) {
		if (!this.can('pmall')) return false;
		if (!target) return this.parse('/help pmall');

		let pmName = ' Server PM [Do not reply]';

		Users.users.forEach(function (user) {
			let message = '|pm|' + pmName + '|' + user.getIdentity() + '|' + target;
			user.send(message);
		});
	},
	pmallhelp: ["/pmall [message] - PM all users in the server."],

	staffpm: 'pmallstaff',
	pmstaff: 'pmallstaff',
	pmallstaff: function (target, room, user) {
		if (!this.can('forcewin')) return false;
		if (!target) return this.parse('/help pmallstaff');

		let pmName = ' Staff PM [Do not reply]';

		Users.users.forEach(function (user) {
			if (!user.isStaff) return;
			let message = '|pm|' + pmName + '|' + user.getIdentity() + '|' + target;
			user.send(message);
		});
	},
	pmallstaffhelp: ["/pmallstaff [message] - Sends a PM to every staff member online."],

	d: 'poof',
	cpoof: 'poof',
	poof: function (target, room, user) {
		if (Config.poofOff) return this.sendReply("Poof is currently disabled.");
		if (target && !this.can('broadcast')) return false;
		if (room.id !== 'lobby') return false;
		let message = target || messages[Math.floor(Math.random() * messages.length)];
		if (message.indexOf('{{user}}') < 0) message = '{{user}} ' + message;
		message = message.replace(/{{user}}/g, user.name);
		if (!this.canTalk(message)) return false;

		let colour = '#' + [1, 1, 1].map(function () {
			let part = Math.floor(Math.random() * 0xaa);
			return (part < 0x10 ? '0' : '') + part.toString(16);
		}).join('');

		room.addRaw("~~ " + Tools.escapeHTML(message) + " ~~");
		user.disconnectAll();
	},
	poofhelp: ["/poof - Disconnects the user and leaves a message in the room."],

	poofon: function () {
		if (!this.can('poofoff')) return false;
		Config.poofOff = false;
		return this.sendReply("Poof is now enabled.");
	},
	poofonhelp: ["/poofon - Enable the use /poof command."],

	nopoof: 'poofoff',
	poofoff: function () {
		if (!this.can('poofoff')) return false;
		Config.poofOff = true;
		return this.sendReply("Poof is now disabled.");
	},
	poofoffhelp: ["/poofoff - Disable the use of the /poof command."],

	regdate: function (target, room, user) {
		if (!this.runBroadcast()) return;
		if (!target || !toId(target)) return this.parse('/help regdate');
		let username = toId(target);
		request('http://pokemonshowdown.com/users/' + username, function (error, response, body) {
			if (error && response.statusCode !== 200) {
				this.sendReplyBox(Tools.escapeHTML(target) + " is not registered.");
				return room.update();
			}
			let regdate = body.split('')[1].split('')[0].replace(/(|<\/em>)/g, '');
			if (regdate === '(Unregistered)') {
				this.sendReplyBox("<font color='" + color(target) + '"' + Tools.escapeHTML(target) + " is not registered.");
			} else if (regdate === '(Account disabled)') {
				this.sendReplyBox("<font color='" + color(target) + "'" + Tools.escapeHTML(target) + "'s account is disabled.");
			} else {
				this.sendReplyBox("" + Tools.escapeHTML(target) + " was registered on " + regdate.slice(7) + ".");
			}
			room.update();
		}.bind(this));
	},

	regdatehelp: ["/regdate - Please specify a valid username."],

	show: function (target, room, user) {
		if (!this.can('lock')) return false;
		user.hiding = false;
		user.updateIdentity();
		this.sendReply("You have revealed your staff symbol.");
	},

	sb: 'showdownboilerplate',
	showdownboilerplate: function (target, room, user) {
		if (!this.runBroadcast()) return;
		this.sendReply("|raw|This server uses Showdown-Boilerplate.");
	},
	showdownboilerplatehelp: ["/showdownboilerplate - Links to the Showdown-Boilerplate repository on Github."],
     lastseen: 'seen',
    seen: function (target, room, user) {
		if (!this.runBroadcast()) return;
		if (!target) return this.parse('/help seen');
		let targetUser = Users.get(target);
		if (targetUser && targetUser.connected) return this.sendReplyBox("" + targetUser.name + " is Currently Online.");
		target = Tools.escapeHTML(target);
		let seen = Db('seen').get(toId(target));
		if (!seen) return this.sendReplyBox("" + target + "has never been online on this server.");
		this.sendReplyBox("" + target + " was last seen " + moment(seen).fromNow() + ".");
	},
	seenhelp: ["/seen - Shows when the user last connected on the server."],
    hc: function(target, room, user) {
    return this.parse('/hotpatch chat')
  },
	tell: function (target, room, user, connection) {
		if (!target) return this.parse('/help tell');
		target = this.splitTarget(target);
		let targetUser = this.targetUser;
		if (!target) {
			this.sendReply("You forgot the comma.");
			return this.parse('/help tell');
		}

		if (targetUser && targetUser.connected) {
			return this.parse('/pm ' + this.targetUsername + ', ' + target);
		}

		if (user.locked) return this.popupReply("You may not send offline messages when locked.");
		if (target.length > 255) return this.popupReply("Your message is too long to be sent as an offline message (>255 characters).");

		if (Config.tellrank === 'autoconfirmed' && !user.autoconfirmed) {
			return this.popupReply("You must be autoconfirmed to send an offline message.");
		} else if (!Config.tellrank || Config.groupsranking.indexOf(user.group) < Config.groupsranking.indexOf(Config.tellrank)) {
			return this.popupReply("You cannot send an offline message because offline messaging is " +
				(!Config.tellrank ? "disabled" : "only available to users of rank " + Config.tellrank + " and above") + ".");
		}

		let userid = toId(this.targetUsername);
		if (userid.length > 18) return this.popupReply("\"" + this.targetUsername + "\" is not a legal username.");

		let sendSuccess = Tells.addTell(user, userid, target);
		if (!sendSuccess) {
			if (sendSuccess === false) {
				return this.popupReply("User " + this.targetUsername + " has too many offline messages queued.");
			} else {
				return this.popupReply("You have too many outgoing offline messages queued. Please wait until some have been received or have expired.");
			}
		}
		return connection.send('|pm|' + user.getIdentity() + '|' +
			(targetUser ? targetUser.getIdentity() : ' ' + this.targetUsername) +
			"|/text This user is currently offline. Your message will be delivered when they are next online.");
	},
	tellhelp: ["/tell [username], [message] - Send a message to an offline user that will be received when they log in."],

	hc: function(target, room, user) {
	  return this.parse('/hotpatch chat');
	},
};
<|endoftext|>


<commit_before>define(function(require, exports, module) {
    main.consumes = ["c9", "Plugin", "fs"];
    main.provides = ["watcher"];
    return main;

    function main(options, imports, register) {
        var Plugin = imports.Plugin;
        var fs = imports.fs;
        var c9 = imports.c9;

        var basename = require("path").basename;
        var dirname = require("path").dirname;

        /***** Initialization *****/

        var plugin = new Plugin("Ajax.org", main.consumes);
        var emit = plugin.getEmitter();

        var WAIT_FOR_SIGNAL = false; //c9.platform == "darwin";
        var IGNORE_TIMEOUT = WAIT_FOR_SIGNAL ? 60000 : 1000;

        var ignored = {};
        var handlers = {};
        var loaded = false;
        var cached;

        function load(){
            if (loaded) return false;
            loaded = true;

            function ignoreHandler(e) {
                if (!options || !options.testing)
                    ignore(e.path, 60000);
            }

            function doneHandler(e) {
                if (!options || !options.testing) {
                    clearTimeout(ignored[e.path]);
                    ignored[e.path] = setTimeout(function(){
                        unignore(e.path);
                    }, IGNORE_TIMEOUT);
                }
            }

            fs.on("beforeWriteFile", ignoreHandler, plugin);
            fs.on("afterWriteFile", doneHandler, plugin);
            fs.on("beforeRename", ignoreHandler, plugin);
            fs.on("afterRename", doneHandler, plugin);
            fs.on("beforeMkdir", ignoreHandler, plugin);
            fs.on("afterMkdir", doneHandler, plugin);
            fs.on("beforeMkdirP", ignoreHandler, plugin);
            fs.on("afterMkdirP", doneHandler, plugin);
            fs.on("beforeUnlink", ignoreHandler, plugin);
            fs.on("afterUnlink", doneHandler, plugin);
            fs.on("beforeRmfile", ignoreHandler, plugin);
            fs.on("afterRmfile", doneHandler, plugin);
            fs.on("beforeRmdir", ignoreHandler, plugin);
            fs.on("afterRmdir", doneHandler, plugin);

            c9.on("disconnect", function(){
                if (!cached)
                    cached = Object.keys(handlers);
                handlers = {};
            });

            c9.on("connect", function(){
                if (cached) {
                    handlers = {};
                    cached.forEach(function(path) {
                        watch(path);
                    });
                    cached = null;
                }
            });
        }

        /***** Methods *****/

        function handleError(err, path) {
            if (err.code === "EDISCONNECT")
                return false;

            // console.error("[watchers] error watching '" + path + "': " + JSON.stringify(err));
            if (typeof handlers[path] === "function")
                fs.unwatch(path, handlers[path]);
            delete handlers[path];

            emit("failed", { path : path });

            return false;
        }

        function ignore(path, timeout, skipParent) {
            if (!timeout)
                timeout = IGNORE_TIMEOUT;

            if (ignored[path])
                clearTimeout(ignored[path]);

            ignored[path] = setTimeout(function(){
                unignore(path);
            }, timeout);

            if (skipParent)
                return;

            var parent = dirname(path);
            if (parent != path)
                ignore(parent, timeout, true);
        }

        function unignore(path) {
            var parent = dirname(path);

            clearTimeout(ignored[path]);
            clearTimeout(ignored[parent]);

            delete ignored[path];
            delete ignored[parent];
        }

        function watch(path, $refresh, $force) {
            // If we've started setting a watcher within the last minute, abort
            var handler = handlers[path];
            if (!$force && handler && (!(handler instanceof Date)
              || handler.getTime() + 60000 > Date.now())) {
                // We already have a watcher for this file, or it's still initializing
                // let's just make sure no one tries to unwatch it right now
                handler.unwatchScheduled = false;
                return;
            }
            // console.log("[watchers] watching", path);

            if (!$force) {
                // Make sure a possible retry on this path is no longer used
                if (handler)
                    clearTimeout(handler.timeout);

                handlers[path] = handler = new Date();
                handlers[path].retries = 0;
            }

            fs.watch(path, function handler(err, event, filename, stat, files) {
                if (err) {
                    if (err.code == "ENOENT" && handlers[path] && handlers[path].retries < 1) {
                        handlers[path].retries++;
                        handlers[path].timeout =
                            setTimeout(function(){
                                watch(path, $refresh, true);
                            }, 1000);
                        return false;
                    }
                    return handleError(err, path);
                }

                // OSX sometimes doesn't know the filename
                if (!filename)
                    filename = basename(path);

                if (event == "init") {
                    if (handler.unwatchScheduled) {
                        fs.unwatch(path, handler);
                        emit("unwatch", { path: path });
                    }
                    else {
                        handlers[path] = handler;
                    }

                    if ($refresh)
                        fs.readdir(path, function() {});
                    return;
                }

                if (ignored[path] || (!options.testing && stat.vfsWrite)) {
                    if (WAIT_FOR_SIGNAL)
                        ignore(path, 200);
                    // console.warn("[watchers] ignored event for", path, stat.vfsWrite ? "(was vfsWrite)" : "(was on ignore list)");

                    fireWatcherEvent(".all");
                } else {
                    fireWatcherEvent("");
                    fireWatcherEvent(".all");
                }

                function fireWatcherEvent(eventSuffix) {
                    if (event == "error") {
                        // console.error("[watchers] received error for", path, err, stat);
                    }
                    else if (event == "delete") {
                        fs.unwatch(path, handler);
                        delete handlers[path];
                        // console.log("[watchers] received", event, "event for", path, stat);
                        emit("delete" + eventSuffix, { path : path });
                    }
                    else if (event == "directory") {
                        emit("directory" + eventSuffix, {
                            path: path,
                            files: files,
                            stat: stat
                        });
                    }
                    else {
                        // console.log("[watchers] received", event, "event for", path, stat);
                        emit("change" + eventSuffix, {
                            type: event,  // change || rename
                            filename: filename,
                            path: path,
                            stat: stat
                        });
                    }
                }
            });
        }

        function unwatch(path) {
            if (handlers[path]) {
                // console.log("[watchers] stopped watching", path);
                if (typeof handlers[path] == "function") {
                    fs.unwatch(path, handlers[path]);
                    emit("unwatch", { path: path });
                    delete handlers[path];
                } else {
                    handlers[path].unwatchScheduled = true;
                }
            }
        }

        function check(path, timestamp) {
            fs.stat(path, function(err, stat) {
                if (err) {
                    if (err.code == "EDISCONNECT")
                        return;
                    if (err.code == "ENOENT" || err.code == "EBADF") {
                        console.log("[watcher] sending artificial check event for", path, "(deleted)", stat);
                        emit("delete", { path : path });
                    }
                    else {
                        // console.error("[watchers] watcher.check received unknown error ", err);
                    }
                }
                else if (timestamp < stat.mtime) {
                    console.log("[watcher] sending artificial check event for", path,
                        "(expected mtime " + timestamp + ")", stat);
                    emit("change", {
                        type: "change",
                        filename: basename(path),
                        path: path,
                        stat: stat
                    });
                }
            });
        }

        /***** Lifecycle *****/

        plugin.on("load", function(){
            load();
        });
        plugin.on("enable", function(){

        });
        plugin.on("disable", function(){

        });
        plugin.on("unload", function(){
            loaded = false;
        });

        /***** Register and define API *****/

        /**
         * Watches files and directories for changes
         * @singleton
         **/
        plugin.freezePublicAPI({
            _events: [
                /**
                 * @event change Fires when a file is changed
                 * @param {Object} e
                 * @param {String} e.path      the path of the changed file
                 * @param {String} e.type      can take the value "change" or "rename".
                 * @param {String} e.filename  the filename of the file that is
                 *   changed (especially interesting when watcher a directory)
                 * @param {Object} e.stat      object containing information
                 *   about the path. See {@link fs#stat}.
                 */
                "change",
                /**
                 * @event delete Fires when a file is removed
                 * @param {Object} e
                 * @param {String} e.path  the path of the removed file
                 * @param {Object} e.stat  object containing information about
                 *   the path. See {@link fs#stat}.
                 */
                "delete",
                /**
                 * @event directory Fires when a directory contents is changed
                 * @param {Object} e
                 * @param {String} e.path   the path of the removed file
                 * @param {Array}  e.files  list of stat objects representing
                 *   the new file listing of the directory. See {@link fs#stat}.
                 * @param {Object} e.stat   object containing information
                 *   about the path. See {@link fs#stat}.
                 */
                "directory",
                /**
                 * @event failed Fires when a watcher fails to be set
                 * @param {Object} e
                 * @param {String} e.path   the path
                 */
                "failed",
                /**
                 * @event unwatch A watcher got removed for a path
                 * @param {Object} e
                 * @param {String} e.path   the path
                 */
                "unwatch",
            ],

            /**
             * Set a watcher for a path
             * @param {String} path the path of the file or directory to watch
             */
            watch: watch,

            /**
             * Remove a watcher for a path
             * @param {String} path the path of the file or directory to unwatch
             */
            unwatch: unwatch,

            /**
             * Checks whether a file has changed or is deleted
             * @param {String} path the path of the file to check
             */
            check: check,

            /**
             * Ignore watching a path for [timeout] milliseconds. This is useful
             * when the file operation occurs on this client.
             * @param {String} path    the path of the file or directory to ignore
             * @param {Number} timeout the amount of milliseconds to ignore the path
             * @private
             */
            ignore: ignore
        });

        register(null, {
            watcher: plugin
        });
    }
});<commit_msg>Adding logging to track down redis failures and why they're happening<commit_after>/**
 * Watcher
 * Watches files and folders for changes and notifies the rest of the system when they happen.
 **/
define(function(require, exports, module) {
    main.consumes = ["c9", "Plugin", "fs"];
    main.provides = ["watcher"];
    return main;

    function main(options, imports, register) {
        var Plugin = imports.Plugin;
        var fs = imports.fs;
        var c9 = imports.c9;

        var basename = require("path").basename;
        var dirname = require("path").dirname;

        /***** Initialization *****/

        var plugin = new Plugin("Ajax.org", main.consumes);
        var emit = plugin.getEmitter();

        var WAIT_FOR_SIGNAL = false; //c9.platform == "darwin";
        var IGNORE_TIMEOUT = WAIT_FOR_SIGNAL ? 60000 : 1000;

        var ignored = {};
        var handlers = {};
        var loaded = false;
        var cached;

        function load(){
            if (loaded) return false;
            loaded = true;

            function ignoreHandler(e) {
                if (!options || !options.testing)
                    ignore(e.path, 60000);
            }

            function doneHandler(e) {
                if (!options || !options.testing) {
                    clearTimeout(ignored[e.path]);
                    ignored[e.path] = setTimeout(function(){
                        unignore(e.path);
                    }, IGNORE_TIMEOUT);
                }
            }

            fs.on("beforeWriteFile", ignoreHandler, plugin);
            fs.on("afterWriteFile", doneHandler, plugin);
            fs.on("beforeRename", ignoreHandler, plugin);
            fs.on("afterRename", doneHandler, plugin);
            fs.on("beforeMkdir", ignoreHandler, plugin);
            fs.on("afterMkdir", doneHandler, plugin);
            fs.on("beforeMkdirP", ignoreHandler, plugin);
            fs.on("afterMkdirP", doneHandler, plugin);
            fs.on("beforeUnlink", ignoreHandler, plugin);
            fs.on("afterUnlink", doneHandler, plugin);
            fs.on("beforeRmfile", ignoreHandler, plugin);
            fs.on("afterRmfile", doneHandler, plugin);
            fs.on("beforeRmdir", ignoreHandler, plugin);
            fs.on("afterRmdir", doneHandler, plugin);

            c9.on("disconnect", function(){
                if (!cached)
                    cached = Object.keys(handlers);
                handlers = {};
            });

            c9.on("connect", function(){
                if (cached) {
                    handlers = {};
                    cached.forEach(function(path) {
                        watch(path);
                    });
                    cached = null;
                }
            });
        }

        /***** Methods *****/

        function handleError(err, path) {
            if (err.code === "EDISCONNECT")
                return false;

            // console.error("[watchers] error watching '" + path + "': " + JSON.stringify(err));
            if (typeof handlers[path] === "function")
                fs.unwatch(path, handlers[path]);
            delete handlers[path];

            emit("failed", { path : path });

            return false;
        }

        function ignore(path, timeout, skipParent) {
            if (!timeout)
                timeout = IGNORE_TIMEOUT;

            if (ignored[path])
                clearTimeout(ignored[path]);

            ignored[path] = setTimeout(function(){
                unignore(path);
            }, timeout);

            if (skipParent)
                return;

            var parent = dirname(path);
            if (parent != path)
                ignore(parent, timeout, true);
        }

        function unignore(path) {
            var parent = dirname(path);

            clearTimeout(ignored[path]);
            clearTimeout(ignored[parent]);

            delete ignored[path];
            delete ignored[parent];
        }

        function watch(path, $refresh, $force) {
            // If we've started setting a watcher within the last minute, abort
            var handler = handlers[path];
            if (!$force && handler && (!(handler instanceof Date)
              || handler.getTime() + 60000 > Date.now())) {
                // We already have a watcher for this file, or it's still initializing
                // let's just make sure no one tries to unwatch it right now
                handler.unwatchScheduled = false;
                return;
            }
            // console.log("[watchers] watching", path);

            if (!$force) {
                // Make sure a possible retry on this path is no longer used
                if (handler)
                    clearTimeout(handler.timeout);

                handlers[path] = handler = new Date();
                handlers[path].retries = 0;
            }

            fs.watch(path, function handler(err, event, filename, stat, files) {
                if (err) {
                    if (err.code == "ENOENT" && handlers[path] && handlers[path].retries < 1) {
                        handlers[path].retries++;
                        handlers[path].timeout =
                            setTimeout(function(){
                                watch(path, $refresh, true);
                            }, 1000);
                        return false;
                    }
                    return handleError(err, path);
                }

                // OSX sometimes doesn't know the filename
                if (!filename)
                    filename = basename(path);

                if (event == "init") {
                    if (handler.unwatchScheduled) {
                        fs.unwatch(path, handler);
                        emit("unwatch", { path: path });
                    }
                    else {
                        handlers[path] = handler;
                    }

                    if ($refresh)
                        fs.readdir(path, function() {});
                    return;
                }

                if (ignored[path] || (!options.testing && stat.vfsWrite)) {
                    if (WAIT_FOR_SIGNAL)
                        ignore(path, 200);
                    // console.warn("[watchers] ignored event for", path, stat.vfsWrite ? "(was vfsWrite)" : "(was on ignore list)");

                    fireWatcherEvent(".all");
                } else {
                    fireWatcherEvent("");
                    fireWatcherEvent(".all");
                }

                function fireWatcherEvent(eventSuffix) {
                    if (event == "error") {
                        // console.error("[watchers] received error for", path, err, stat);
                    }
                    else if (event == "delete") {
                        fs.unwatch(path, handler);
                        delete handlers[path];
                        // console.log("[watchers] received", event, "event for", path, stat);
                        emit("delete" + eventSuffix, { path : path });
                    }
                    else if (event == "directory") {
                        emit("directory" + eventSuffix, {
                            path: path,
                            files: files,
                            stat: stat
                        });
                    }
                    else {
                        // console.log("[watchers] received", event, "event for", path, stat);
                        emit("change" + eventSuffix, {
                            type: event,  // change || rename
                            filename: filename,
                            path: path,
                            stat: stat
                        });
                    }
                }
            });
        }

        function unwatch(path) {
            if (handlers[path]) {
                // console.log("[watchers] stopped watching", path);
                if (typeof handlers[path] == "function") {
                    fs.unwatch(path, handlers[path]);
                    emit("unwatch", { path: path });
                    delete handlers[path];
                } else {
                    handlers[path].unwatchScheduled = true;
                }
            }
        }

        function check(path, timestamp) {
            fs.stat(path, function(err, stat) {
                if (err) {
                    if (err.code == "EDISCONNECT")
                        return;
                    if (err.code == "ENOENT" || err.code == "EBADF") {
                        console.log("[watcher] sending artificial check event for", path, "(deleted)", stat);
                        emit("delete", { path : path });
                    }
                    else {
                        // console.error("[watchers] watcher.check received unknown error ", err);
                    }
                }
                else if (timestamp < stat.mtime) {
                    console.log("[watcher] sending artificial check event for", path,
                        "(expected mtime " + timestamp + ")", stat);
                    emit("change", {
                        type: "change",
                        filename: basename(path),
                        path: path,
                        stat: stat
                    });
                }
            });
        }

        /***** Lifecycle *****/

        plugin.on("load", function(){
            load();
        });
        plugin.on("enable", function(){

        });
        plugin.on("disable", function(){

        });
        plugin.on("unload", function(){
            loaded = false;
        });

        /***** Register and define API *****/

        /**
         * Watches files and directories for changes
         * @singleton
         **/
        plugin.freezePublicAPI({
            _events: [
                /**
                 * @event change Fires when a file is changed
                 * @param {Object} e
                 * @param {String} e.path      the path of the changed file
                 * @param {String} e.type      can take the value "change" or "rename".
                 * @param {String} e.filename  the filename of the file that is
                 *   changed (especially interesting when watcher a directory)
                 * @param {Object} e.stat      object containing information
                 *   about the path. See {@link fs#stat}.
                 */
                "change",
                /**
                 * @event delete Fires when a file is removed
                 * @param {Object} e
                 * @param {String} e.path  the path of the removed file
                 * @param {Object} e.stat  object containing information about
                 *   the path. See {@link fs#stat}.
                 */
                "delete",
                /**
                 * @event directory Fires when a directory contents is changed
                 * @param {Object} e
                 * @param {String} e.path   the path of the removed file
                 * @param {Array}  e.files  list of stat objects representing
                 *   the new file listing of the directory. See {@link fs#stat}.
                 * @param {Object} e.stat   object containing information
                 *   about the path. See {@link fs#stat}.
                 */
                "directory",
                /**
                 * @event failed Fires when a watcher fails to be set
                 * @param {Object} e
                 * @param {String} e.path   the path
                 */
                "failed",
                /**
                 * @event unwatch A watcher got removed for a path
                 * @param {Object} e
                 * @param {String} e.path   the path
                 */
                "unwatch",
            ],

            /**
             * Set a watcher for a path
             * @param {String} path the path of the file or directory to watch
             */
            watch: watch,

            /**
             * Remove a watcher for a path
             * @param {String} path the path of the file or directory to unwatch
             */
            unwatch: unwatch,

            /**
             * Checks whether a file has changed or is deleted
             * @param {String} path the path of the file to check
             */
            check: check,

            /**
             * Ignore watching a path for [timeout] milliseconds. This is useful
             * when the file operation occurs on this client.
             * @param {String} path    the path of the file or directory to ignore
             * @param {Number} timeout the amount of milliseconds to ignore the path
             * @private
             */
            ignore: ignore
        });

        register(null, {
            watcher: plugin
        });
    }
});<|endoftext|>


<commit_before>import {get_data} from './utils'
const {React, rpc, i18n} = Serverboards
const {Loading, Error} = Serverboards.Components
const {map_get} = Serverboards.utils

class Mini5 extends React.Component{
  componentDidMount(){
    const props = this.props
    props.setTitle(" ")
    // console.log("props", props)
    this.updateData(props)
  }
  updateData(props){
    props.setClass( `${props.config.color || "grey"} card` )
  }
  componentWillReceiveProps(newprops){
    if (!Serverboards.utils.object_is_equal(newprops.config, this.props.config)){
      // console.log("New props: ", newprops)
      this.updateData(newprops)
    }
  }
  shouldComponentUpdate(nextprops, nextstate){
    return !(Serverboards.utils.object_is_equal(this.props.config, nextprops.config))
  }
  render(){
    const props = this.props
    const config = props.config

    const data = map_get(config, ["data", "rows"])

    if (map_get(config, ["data", "error"])){
      return (
        <Error/>
      )
    }

    if (!data){
      return (
        <Loading.Widget/>
      )
    }

    return (

{config.title}

          {data.map( datum => (

                <span className={`ui bigger oneline text`}>
                  {datum[1]}

{datum[0]}

          ))}

    )
  }
}

Serverboards.add_widget("serverboards.core.widgets/minin", Mini5, {react: true})
<commit_msg>Loading from minin at data line<commit_after>import {get_data} from './utils'
const {React, rpc, i18n} = Serverboards
const {Loading, Error} = Serverboards.Components
const {map_get} = Serverboards.utils

class Mini5 extends React.Component{
  componentDidMount(){
    const props = this.props
    props.setTitle(" ")
    // console.log("props", props)
    this.updateData(props)
  }
  updateData(props){
    props.setClass( `${props.config.color || "grey"} card` )
  }
  componentWillReceiveProps(newprops){
    if (!Serverboards.utils.object_is_equal(newprops.config, this.props.config)){
      // console.log("New props: ", newprops)
      this.updateData(newprops)
    }
  }
  shouldComponentUpdate(nextprops, nextstate){
    return !(Serverboards.utils.object_is_equal(this.props.config, nextprops.config))
  }
  render(){
    const props = this.props
    const config = props.config

    const data = map_get(config, ["data", "rows"])

    if (map_get(config, ["data", "error"])){
      return (
        <Error/>
      )
    }

    return (

{config.title}

          {!data ? (
            <Loading.Widget/>
          ) : data.map( datum => (

                <span className={`ui bigger oneline text`}>
                  {datum[1]}

{datum[0]}

          ))}

    )
  }
}

Serverboards.add_widget("serverboards.core.widgets/minin", Mini5, {react: true})
<|endoftext|>