<commit_before>/**
 * jCarouselLite - jQuery plugin to navigate images/any content in a carousel style widget.
 * @requires jQuery v1.2 or above
 *
 * http://gmarwaha.com/jquery/jcarousellite/
 *
 * Copyright (c) 2007 Ganeshji Marwaha (gmarwaha.com)
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 *
 * Version: 1.0.1
 * Note: Requires jquery 1.2 or above from version 1.0.1
 */

(function($) {
$.fn.jCarouselLite = function(o) {
    o = $.extend({
        btnPrev: null,
        btnNext: null,
        btnGo: null,
        mouseWheel: false,
        auto: null,

        speed: 200,
        easing: null,

        vertical: false,
        circular: true,
        visible: 3,
        start: 0,
        scroll: 1,

        beforeStart: null,
        afterEnd: null
    }, o || {});

    return this.each(function() {
        // Returns the element collection. Chainable.

        var running = false,
            animCss = o.vertical ? "top" : "left",
            sizeCss = o.vertical ? "height" : "width",
            div = $(this),
            ul = $(".slider", div),
            tLi = $(".panel", ul),
            tl = tLi.size(),
            v = o.visible;

        if(o.circular) {
            ul.prepend(tLi.slice(tl-v-1+1).clone())
              .append(tLi.slice(0,v).clone());
            o.start += v;
        }

        if (!o.circular && o.scroll > 1) {
            while (tl % o.scroll != 0) {
                ul.append('

');
                tl++;
            }
        }

        var li = $(".panel", ul), itemLength = li.size(), curr = o.start;
        div.css("visibility", "visible");

        li.css({"float": o.vertical ? "none" : "left"});
        ul.css({margin: "0", padding: "0", position: "relative", "list-style-type": "none", "z-index": "1"});
        div.css({overflow: "hidden", position: "relative", "z-index": "2", left: "0"});

        // Full li size (including margin, used for animation).
        var liSize = o.vertical ? li.outerHeight(true) : li.outerWidth(true);
        // Size of full ul (total length, not just for the visible items).
        var ulSize = liSize * itemLength;
        // Size of entire div (total length, for only the visible items).
        var divSize = liSize * v;

        li.css({width: li.width(), height: li.height()});
        ul.css(sizeCss, ulSize+"px").css(animCss, -(curr*liSize));

        // Width of the DIV. length of visible images.
        div.css(sizeCss, divSize+"px");

        if (!o.circular) {
            $(o.btnPrev + "," + o.btnNext).removeClass("disabled");
            if (o.btnPrev && curr == 0) {
                $(o.btnPrev).addClass("disabled");
            }
            if (o.btnNext && curr >= itemLength - v) {
                $(o.btnNext).addClass("disabled");
            }
        }

        if(o.btnPrev) {
            $(o.btnPrev).click(function() {
                var to = curr - o.scroll;
                if (!o.circular && to < 0) {
                    to = 0;
                }
                return go(to);
            });
        }

        if(o.btnNext) {
            $(o.btnNext).click(function() {
                var to = curr + o.scroll;
                if (!o.circular && to > itemLength - v - 1){
                    to = itemLength - v;
                }
                return go(to);
            });
        }

        if(o.btnGo)
            $.each(o.btnGo, function(i, val) {
                $(val).click(function() {
                    return go(o.circular ? o.visible+i : i);
                });
            });

        if(o.mouseWheel && div.mousewheel)
            div.mousewheel(function(e, d) {
                return d>0 ? go(curr-o.scroll) : go(curr+o.scroll);
            });

        if(o.auto)
            setInterval(function() {
                go(curr+o.scroll);
            }, o.auto+o.speed);

        function vis() {
            return li.slice(curr).slice(0,v);
        };

        function go(to) {
            if(!running) {
                if(o.beforeStart)
                    o.beforeStart.call(this, vis());

                if(o.circular) {            // If circular we are in first or last, then goto the other end
                    if(to<=o.start-v-1) {           // If first, then goto last
                        ul.css(animCss, -((itemLength-(v*2-curr))*liSize)+"px");
                        // If "scroll" > 1, then the "to" might not be equal to the condition; it can be lesser depending on the number of elements.
                        curr = to == o.start-v-1 ? itemLength-(v*2)-1 : itemLength-(v*2)-o.scroll+curr;
                    } else if(to>=itemLength-v+1) { // If last, then goto first
                        ul.css(animCss, -((curr - (itemLength - (v*2))) * liSize) + "px");
                        // If "scroll" > 1, then the "to" might not be equal to the condition; it can be greater depending on the number of elements.
                        curr = to == itemLength-v+1 ? v+1 : curr - (itemLength - (v*2)) + o.scroll;
                    } else curr = to;
                } else {                    // If non-circular and to points to first or last, we just return.
                    if(to<0 || to>itemLength-v) return false;
                    else curr = to;
                }                           // If neither overrides it, the curr will still be "to" and we can proceed.

                running = true;

                ul.animate(
                    animCss == "left" ? { left: -(curr*liSize) } : { top: -(curr*liSize) } , o.speed, o.easing,
                    function() {
                        if(o.afterEnd)
                            o.afterEnd.call(this, vis());
                        running = false;
                    }
                );
                // Disable buttons when the carousel reaches the last/first,
                // and enable when not.
                if (!o.circular) {
                    $(o.btnPrev + "," + o.btnNext).removeClass("disabled");
                    if (o.btnPrev && curr == 0) {
                        $(o.btnPrev).addClass("disabled");
                    }
                    if (o.btnNext && curr >= itemLength - v) {
                        $(o.btnNext).addClass("disabled");
                    }
                }

            }
            return false;
        };

        // Change panel widths on resize to keep the page liquid
        $(window).resize(function(){
            setPanelWidth("both");
            liSize = o.vertical ? li.outerHeight(true) : li.outerWidth(true);
            ul.css(sizeCss, ulSize+"px").css(animCss, -(curr*liSize));
        });

    });
};

function css(el, prop) {
    return parseInt($.css(el[0], prop)) || 0;
};

})(jQuery);

$(document).ready(function(){
    // Construct URL for the link back to the discovery promo pane.
    if ($(".detail").length) {
        $(".install-action a").attr("target", "_self");
        var version = localStorage.getItem("discopane-browser-version", version),
            platform = localStorage.getItem("discopane-browser-platform", platform),
            url = document.body.getAttribute("data-pane-url");
        url = url.replace(":version:", version).replace(":platform:", platform);
        $("p#back a").attr("href", url);

        $("#images").fadeIn("slow").addClass("js").jCarouselLite({
            btnNext: "#images .nav-next a",
            btnPrev: "#images .nav-prev a",
            circular: false
        });
        $(".addon-info").addClass("js");

        // Set up the lightbox.
        var lb_baseurl = z.media_url + "img/jquery-lightbox/";
        $("#images li.panel a[rel=jquery-lightbox]").lightBox({
            overlayOpacity: 0.6,
            imageBlank: lb_baseurl + "lightbox-blank.gif",
            imageLoading: lb_baseurl + "lightbox-ico-loading.gif",
            imageBtnClose: "",
            imageBtnPrev: "",
            imageBtnNext: "",
            containerResizeSpeed: 350
        });
    }

    // Set up the carousel.
    $("#main-feature").fadeIn("slow").addClass("js").jCarouselLite({
        btnNext: "#main-feature .nav-next a",
        btnPrev: "#main-feature .nav-prev a",
        visible: 1
    });

    setPanelWidth("detail");
});

function debounce(fn, ms, ctxt) {
    var ctx = ctxt || window;
    var to, del = ms, fun = fn;
    return function () {
        var args = arguments;
        clearTimeout(to);
        to = setTimeout(function() {
            fun.apply(ctx, args);
        }, del);
    };
}

function setPanelWidth(section) {
    // Set the width of panels (jCarousel requires a pixel width but our page
    // is liquid, so we'll set the width in px on pageload and on resize).
    if (section == "both" || section == "detail") {
        var panelWidth = $("#main").width();
        $("#main-feature, #main-feature .panel, #images").css("width", panelWidth);
        // We show three images at a time, so the width of each is 1/3 minus a
        // right margin of 10px.
        $("#images .panel").css("width", panelWidth / 3 - 10);
    }
    if (section == "both" || section == "pane") {
        var galleryWidth = $("#recs .gallery").width();
        $("#recs .gallery .panel").css({
            "width": 0.3 * galleryWidth,
            "margin-right": 0.05 * galleryWidth
        });
        $("#recs .gallery .panel:nth-child(3n)").each(function(i){
            $(this).css("margin-right", 0.05 * galleryWidth + i + 2);
        });
    }
}
<commit_msg>fix 'back to add-ons' link (bug 635060)<commit_after>/**
 * jCarouselLite - jQuery plugin to navigate images/any content in a carousel style widget.
 * @requires jQuery v1.2 or above
 *
 * http://gmarwaha.com/jquery/jcarousellite/
 *
 * Copyright (c) 2007 Ganeshji Marwaha (gmarwaha.com)
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 *
 * Version: 1.0.1
 * Note: Requires jquery 1.2 or above from version 1.0.1
 */

(function($) {
$.fn.jCarouselLite = function(o) {
    o = $.extend({
        btnPrev: null,
        btnNext: null,
        btnGo: null,
        mouseWheel: false,
        auto: null,

        speed: 200,
        easing: null,

        vertical: false,
        circular: true,
        visible: 3,
        start: 0,
        scroll: 1,

        beforeStart: null,
        afterEnd: null
    }, o || {});

    return this.each(function() {
        // Returns the element collection. Chainable.

        var running = false,
            animCss = o.vertical ? "top" : "left",
            sizeCss = o.vertical ? "height" : "width",
            div = $(this),
            ul = $(".slider", div),
            tLi = $(".panel", ul),
            tl = tLi.size(),
            v = o.visible;

        if(o.circular) {
            ul.prepend(tLi.slice(tl-v-1+1).clone())
              .append(tLi.slice(0,v).clone());
            o.start += v;
        }

        if (!o.circular && o.scroll > 1) {
            while (tl % o.scroll != 0) {
                ul.append('

');
                tl++;
            }
        }

        var li = $(".panel", ul), itemLength = li.size(), curr = o.start;
        div.css("visibility", "visible");

        li.css({"float": o.vertical ? "none" : "left"});
        ul.css({margin: "0", padding: "0", position: "relative", "list-style-type": "none", "z-index": "1"});
        div.css({overflow: "hidden", position: "relative", "z-index": "2", left: "0"});

        // Full li size (including margin, used for animation).
        var liSize = o.vertical ? li.outerHeight(true) : li.outerWidth(true);
        // Size of full ul (total length, not just for the visible items).
        var ulSize = liSize * itemLength;
        // Size of entire div (total length, for only the visible items).
        var divSize = liSize * v;

        li.css({width: li.width(), height: li.height()});
        ul.css(sizeCss, ulSize+"px").css(animCss, -(curr*liSize));

        // Width of the DIV. length of visible images.
        div.css(sizeCss, divSize+"px");

        if (!o.circular) {
            $(o.btnPrev + "," + o.btnNext).removeClass("disabled");
            if (o.btnPrev && curr == 0) {
                $(o.btnPrev).addClass("disabled");
            }
            if (o.btnNext && curr >= itemLength - v) {
                $(o.btnNext).addClass("disabled");
            }
        }

        if(o.btnPrev) {
            $(o.btnPrev).click(function() {
                var to = curr - o.scroll;
                if (!o.circular && to < 0) {
                    to = 0;
                }
                return go(to);
            });
        }

        if(o.btnNext) {
            $(o.btnNext).click(function() {
                var to = curr + o.scroll;
                if (!o.circular && to > itemLength - v - 1){
                    to = itemLength - v;
                }
                return go(to);
            });
        }

        if(o.btnGo)
            $.each(o.btnGo, function(i, val) {
                $(val).click(function() {
                    return go(o.circular ? o.visible+i : i);
                });
            });

        if(o.mouseWheel && div.mousewheel)
            div.mousewheel(function(e, d) {
                return d>0 ? go(curr-o.scroll) : go(curr+o.scroll);
            });

        if(o.auto)
            setInterval(function() {
                go(curr+o.scroll);
            }, o.auto+o.speed);

        function vis() {
            return li.slice(curr).slice(0,v);
        };

        function go(to) {
            if(!running) {
                if(o.beforeStart)
                    o.beforeStart.call(this, vis());

                if(o.circular) {            // If circular we are in first or last, then goto the other end
                    if(to<=o.start-v-1) {           // If first, then goto last
                        ul.css(animCss, -((itemLength-(v*2-curr))*liSize)+"px");
                        // If "scroll" > 1, then the "to" might not be equal to the condition; it can be lesser depending on the number of elements.
                        curr = to == o.start-v-1 ? itemLength-(v*2)-1 : itemLength-(v*2)-o.scroll+curr;
                    } else if(to>=itemLength-v+1) { // If last, then goto first
                        ul.css(animCss, -((curr - (itemLength - (v*2))) * liSize) + "px");
                        // If "scroll" > 1, then the "to" might not be equal to the condition; it can be greater depending on the number of elements.
                        curr = to == itemLength-v+1 ? v+1 : curr - (itemLength - (v*2)) + o.scroll;
                    } else curr = to;
                } else {                    // If non-circular and to points to first or last, we just return.
                    if(to<0 || to>itemLength-v) return false;
                    else curr = to;
                }                           // If neither overrides it, the curr will still be "to" and we can proceed.

                running = true;

                ul.animate(
                    animCss == "left" ? { left: -(curr*liSize) } : { top: -(curr*liSize) } , o.speed, o.easing,
                    function() {
                        if(o.afterEnd)
                            o.afterEnd.call(this, vis());
                        running = false;
                    }
                );
                // Disable buttons when the carousel reaches the last/first,
                // and enable when not.
                if (!o.circular) {
                    $(o.btnPrev + "," + o.btnNext).removeClass("disabled");
                    if (o.btnPrev && curr == 0) {
                        $(o.btnPrev).addClass("disabled");
                    }
                    if (o.btnNext && curr >= itemLength - v) {
                        $(o.btnNext).addClass("disabled");
                    }
                }

            }
            return false;
        };

        // Change panel widths on resize to keep the page liquid
        $(window).resize(function(){
            setPanelWidth("both");
            liSize = o.vertical ? li.outerHeight(true) : li.outerWidth(true);
            ul.css(sizeCss, ulSize+"px").css(animCss, -(curr*liSize));
        });

    });
};

function css(el, prop) {
    return parseInt($.css(el[0], prop)) || 0;
};

})(jQuery);

$(document).ready(function(){
    // Construct URL for the link back to the discovery promo pane.
    if ($(".detail").length) {
        $(".install-action a").attr("target", "_self");
        var version = localStorage.getItem("discopane-browser-version"),
            platform = localStorage.getItem("discopane-browser-platform"),
            url = document.body.getAttribute("data-pane-url");
        url = url.replace(":version:", version).replace(":platform:", platform);
        $("p#back a").attr("href", url);

        $("#images").fadeIn("slow").addClass("js").jCarouselLite({
            btnNext: "#images .nav-next a",
            btnPrev: "#images .nav-prev a",
            circular: false
        });
        $(".addon-info").addClass("js");

        // Set up the lightbox.
        var lb_baseurl = z.media_url + "img/jquery-lightbox/";
        $("#images li.panel a[rel=jquery-lightbox]").lightBox({
            overlayOpacity: 0.6,
            imageBlank: lb_baseurl + "lightbox-blank.gif",
            imageLoading: lb_baseurl + "lightbox-ico-loading.gif",
            imageBtnClose: "",
            imageBtnPrev: "",
            imageBtnNext: "",
            containerResizeSpeed: 350
        });
    }

    // Set up the carousel.
    $("#main-feature").fadeIn("slow").addClass("js").jCarouselLite({
        btnNext: "#main-feature .nav-next a",
        btnPrev: "#main-feature .nav-prev a",
        visible: 1
    });

    setPanelWidth("detail");
});

function debounce(fn, ms, ctxt) {
    var ctx = ctxt || window;
    var to, del = ms, fun = fn;
    return function () {
        var args = arguments;
        clearTimeout(to);
        to = setTimeout(function() {
            fun.apply(ctx, args);
        }, del);
    };
}

function setPanelWidth(section) {
    // Set the width of panels (jCarousel requires a pixel width but our page
    // is liquid, so we'll set the width in px on pageload and on resize).
    if (section == "both" || section == "detail") {
        var panelWidth = $("#main").width();
        $("#main-feature, #main-feature .panel, #images").css("width", panelWidth);
        // We show three images at a time, so the width of each is 1/3 minus a
        // right margin of 10px.
        $("#images .panel").css("width", panelWidth / 3 - 10);
    }
    if (section == "both" || section == "pane") {
        var galleryWidth = $("#recs .gallery").width();
        $("#recs .gallery .panel").css({
            "width": 0.3 * galleryWidth,
            "margin-right": 0.05 * galleryWidth
        });
        $("#recs .gallery .panel:nth-child(3n)").each(function(i){
            $(this).css("margin-right", 0.05 * galleryWidth + i + 2);
        });
    }
}
<|endoftext|>


<commit_before>var React = require('react');
var OpenExps = require('./OpenExps');
var Measure = require('./Measure');
var Request = require('./Request');

// STATELOGIC logic to add in state properties
// STATELOGIC create the the depVar variable

var DepVar = React.createClass({
  render: function() {
    return (

      //name as header

{this.props.depVar.name}

      //currently only supports one measure...

Measures

      <Measure measure = {this.props.depVar.measures[0]}>

Requests

      <Request request = {this.props.depVar.requests[0]}>

    );
  }
});

module.exports = DepVar;<commit_msg>fixed line ending<commit_after>var React = require('react');
var OpenExps = require('./OpenExps');
var Measure = require('./Measure');
var Request = require('./Request');

// STATELOGIC logic to add in state properties
// STATELOGIC create the the depVar variable

var DepVar = React.createClass({
  render: function() {
    return (

      //name as header

{this.props.depVar.name}

      //currently only supports one measure...

Measures

      <Measure measure = {this.props.depVar.measures[0]}>

Requests

      <Request request = {this.props.depVar.requests[0]}>

    );
  }
});

module.exports = DepVar;
<|endoftext|>


<commit_before>/**
  This is a jQuery plugin to support autocompleting values in our text fields.

  @module $.fn.autocomplete
**/

export var CANCELLED_STATUS = "__CANCELLED";

var keys = {
  backSpace: 8,
  tab: 9,
  enter: 13,
  shift: 16,
  ctrl: 17,
  alt: 18,
  esc: 27,
  space: 32,
  leftWindows: 91,
  rightWindows: 92,
  pageUp: 33,
  pageDown: 34,
  end: 35,
  home: 36,
  leftArrow: 37,
  upArrow: 38,
  rightArrow: 39,
  downArrow: 40,
  insert: 45,
  deleteKey: 46,
  zero: 48,
  a: 65,
  z: 90,
};

let inputTimeout;

export default function(options) {
  var autocompletePlugin = this;

  if (this.length === 0) return;

  if (options === 'destroy') {
    Ember.run.cancel(inputTimeout);

    $(this).off('keypress.autocomplete')
           .off('keydown.autocomplete')
           .off('paste.autocomplete');

    return;
  }

  if (options && options.cancel && this.data("closeAutocomplete")) {
    this.data("closeAutocomplete")();
    return this;
  }

  if (this.length !== 1) {
    alert("only supporting one matcher at the moment");
  }

  var disabled = options && options.disabled;
  var wrap = null;
  var autocompleteOptions = null;
  var selectedOption = null;
  var completeStart = null;
  var completeEnd = null;
  var me = this;
  var div = null;

  // input is handled differently
  var isInput = this[0].tagName === "INPUT";
  var inputSelectedItems = [];

  var closeAutocomplete = function() {
    if (div) {
      div.hide().remove();
    }
    div = null;
    completeStart = null;
    autocompleteOptions = null;
  };

  var addInputSelectedItem = function(item) {
    var transformed,
        transformedItem = item;

    if (options.transformComplete) { transformedItem = options.transformComplete(transformedItem); }
    // dump what we have in single mode, just in case
    if (options.single) { inputSelectedItems = []; }
    transformed = _.isArray(transformedItem) ? transformedItem : [transformedItem || item];

    var divs = transformed.map(function(itm) {
      var d = $("
" + itm + "
");
      var prev = me.parent().find('.item:last');
      if (prev.length === 0) {
        me.parent().prepend(d);
      } else {
        prev.after(d);
      }
      inputSelectedItems.push(itm);
      return d[0];
    });

    if (options.onChangeItems) { options.onChangeItems(inputSelectedItems); }

    $(divs).find('a').click(function() {
      closeAutocomplete();
      inputSelectedItems.splice($.inArray(transformedItem, inputSelectedItems), 1);
      $(this).parent().parent().remove();
      if (options.single) {
        me.show();
      }
      if (options.onChangeItems) {
        options.onChangeItems(inputSelectedItems);
      }
      return false;
    });
  };

  var completeTerm = function(term) {
    if (term) {
      if (isInput) {
        me.val("");
        if(options.single){
          me.hide();
        }
        addInputSelectedItem(term);
      } else {
        if (options.transformComplete) {
          term = options.transformComplete(term);
        }

        if (term) {
          var text = me.val();
          text = text.substring(0, completeStart) + (options.key || "") + term + ' ' + text.substring(completeEnd + 1, text.length);
          me.val(text);
          Discourse.Utilities.setCaretPosition(me[0], completeStart + 1 + term.length);
        }
      }
    }
    closeAutocomplete();
  };

  if (isInput) {
    var width = this.width();
    wrap = this.wrap("
").parent();
    wrap.width(width);
    if(options.single) {
      this.css("width","100%");
    } else {
      this.width(150);
    }
    this.attr('name', this.attr('name') + "-renamed");
    var vals = this.val().split(",");
    _.each(vals,function(x) {
      if (x !== "") {
        if (options.reverseTransform) {
          x = options.reverseTransform(x);
        }
        addInputSelectedItem(x);
      }
    });
    if(options.items) {
      _.each(options.items, function(item){
        addInputSelectedItem(item);
      });
    }
    this.val("");
    completeStart = 0;
    wrap.click(function() {
      autocompletePlugin.focus();
      return true;
    });
  }

  var markSelected = function() {
    var links = div.find('li a');
    links.removeClass('selected');
    return $(links[selectedOption]).addClass('selected');
  };

  var renderAutocomplete = function() {
    if (div) {
      div.hide().remove();
    }
    if (autocompleteOptions.length === 0) return;

    div = $(options.template({ options: autocompleteOptions }));

    var ul = div.find('ul');
    selectedOption = 0;
    markSelected();
    ul.find('li').click(function() {
      selectedOption = ul.find('li').index(this);
      completeTerm(autocompleteOptions[selectedOption]);
      return false;
    });
    var pos = null;
    var vOffset = 0;
    var hOffset = 0;
    if (isInput) {
      pos = {
        left: 0,
        top: 0
      };
      vOffset = -32;
      hOffset = 0;
    } else {
      pos = me.caretPosition({
        pos: completeStart,
        key: options.key
      });
      hOffset = 27;
    }
    div.css({
      left: "-1000px"
    });

    me.parent().append(div);

    if(!isInput){
      vOffset = div.height();
    }

    if (Discourse.Mobile.mobileView && !isInput) {
      div.css('width', 'auto');

      if ((me.height() / 2) >= pos.top) { vOffset = -23; }
      if ((me.width() / 2) <= pos.left) { hOffset = -div.width(); }
    }

    var mePos = me.position();
    var borderTop = parseInt(me.css('border-top-width'), 10) || 0;
    div.css({
      position: 'absolute',
      top: (mePos.top + pos.top - vOffset + borderTop) + 'px',
      left: (mePos.left + pos.left + hOffset) + 'px'
    });
  };

  var updateAutoComplete = function(r) {

    if (completeStart === null) return;

    if (r && r.then && typeof(r.then) === "function") {
      if (div) {
        div.hide().remove();
      }
      r.then(updateAutoComplete);
      return;
    }

    // Allow an update method to cancel. This allows us to debounce
    // promises without leaking
    if (r === CANCELLED_STATUS) {
      return;
    }

    autocompleteOptions = r;
    if (!r || r.length === 0) {
      closeAutocomplete();
    } else {
      renderAutocomplete();
    }
  };

  // chain to allow multiples
  var oldClose = me.data("closeAutocomplete");
  me.data("closeAutocomplete", function() {
    if (oldClose) {
      oldClose();
    }
    closeAutocomplete();
  });

  $(this).on('paste.autocomplete', function() {
    _.delay(function(){
      me.trigger("keydown");
    }, 50);
  });

  $(this).on('keypress.autocomplete', function(e) {
    var caretPosition, term;

    // keep hunting backwards till you hit a the @ key
    if (options.key && e.which === options.key.charCodeAt(0)) {
      caretPosition = Discourse.Utilities.caretPosition(me[0]);
      var prevChar = me.val().charAt(caretPosition - 1);
      if (!prevChar || /[^\w\)\]]/.test(prevChar)) {
        completeStart = completeEnd = caretPosition;
        updateAutoComplete(options.dataSource(""));
      }
    } else if ((completeStart !== null) && (e.charCode !== 0)) {
      caretPosition = Discourse.Utilities.caretPosition(me[0]);
      term = me.val().substring(completeStart + (options.key ? 1 : 0), caretPosition);
      term += String.fromCharCode(e.charCode);
      updateAutoComplete(options.dataSource(term));
    }
  });

  $(this).on('keydown.autocomplete', function(e) {
    var c, caretPosition, i, initial, prev, prevIsGood, stopFound, term, total, userToComplete;

    if(e.ctrlKey || e.altKey || e.metaKey){
      return true;
    }

    if(options.allowAny){
      // saves us wiring up a change event as well, keypress is while its pressed

      Ember.run.cancel(inputTimeout);
      inputTimeout = Ember.run.later(function(){
        if(inputSelectedItems.length === 0) {
          inputSelectedItems.push("");
        }

        if(_.isString(inputSelectedItems[0]) && me.val().length > 0) {
          inputSelectedItems.pop();
          inputSelectedItems.push(me.val());
          if (options.onChangeItems) {
            options.onChangeItems(inputSelectedItems);
          }
        }

      }, 50);
    }

    if (!options.key) {
      completeStart = 0;
    }
    if (e.which === keys.shift) return;
    if ((completeStart === null) && e.which === keys.backSpace && options.key) {
      c = Discourse.Utilities.caretPosition(me[0]);
      c -= 1;
      initial = c;
      prevIsGood = true;
      while (prevIsGood && c >= 0) {
        c -= 1;
        prev = me[0].value[c];
        stopFound = prev === options.key;
        if (stopFound) {
          prev = me[0].value[c - 1];
          if (!prev || /[^\w\)\]]/.test(prev)) {
            completeStart = c;
            caretPosition = completeEnd = initial;
            term = me[0].value.substring(c + 1, initial);
            updateAutoComplete(options.dataSource(term));
            return true;
          }
        }
        prevIsGood = /[a-zA-Z\.]/.test(prev);
      }
    }

    // ESC
    if (e.which === keys.esc) {
      if (div !== null) {
        closeAutocomplete();
        return false;
      }
      return true;
    }

    if (completeStart !== null) {
      caretPosition = Discourse.Utilities.caretPosition(me[0]);

      // If we've backspaced past the beginning, cancel unless no key
      if (caretPosition <= completeStart && options.key) {
        closeAutocomplete();
        return false;
      }

      // Keyboard codes! So 80's.
      switch (e.which) {
        case keys.enter:
        case keys.rightArrow:
        case keys.tab:
          if (!autocompleteOptions) return true;
          if (selectedOption >= 0 && (userToComplete = autocompleteOptions[selectedOption])) {
            completeTerm(userToComplete);
          } else {
            // We're cancelling it, really.
            return true;
          }
          e.stopImmediatePropagation();
          return false;
        case keys.upArrow:
          selectedOption = selectedOption - 1;
          if (selectedOption < 0) {
            selectedOption = 0;
          }
          markSelected();
          return false;
        case keys.downArrow:
          total = autocompleteOptions.length;
          selectedOption = selectedOption + 1;
          if (selectedOption >= total) {
            selectedOption = total - 1;
          }
          if (selectedOption < 0) {
            selectedOption = 0;
          }
          markSelected();
          return false;
        case keys.backSpace:
          completeEnd = caretPosition;
          caretPosition--;

          if (caretPosition < 0) {
            closeAutocomplete();
            if (isInput) {
              i = wrap.find('a:last');
              if (i) {
                i.click();
              }
            }
            return true;
          }

          term = me.val().substring(completeStart + (options.key ? 1 : 0), caretPosition);

          updateAutoComplete(options.dataSource(term));
          return true;
        default:
          completeEnd = caretPosition;
          return true;
      }
    }
  });

  return this;
}
<commit_msg>UX: Trigger autocompleter only for specific characters.<commit_after>/**
  This is a jQuery plugin to support autocompleting values in our text fields.

  @module $.fn.autocomplete
**/

export var CANCELLED_STATUS = "__CANCELLED";

const allowedLettersRegex = /[\s\t\[\{\(]/;

var keys = {
  backSpace: 8,
  tab: 9,
  enter: 13,
  shift: 16,
  ctrl: 17,
  alt: 18,
  esc: 27,
  space: 32,
  leftWindows: 91,
  rightWindows: 92,
  pageUp: 33,
  pageDown: 34,
  end: 35,
  home: 36,
  leftArrow: 37,
  upArrow: 38,
  rightArrow: 39,
  downArrow: 40,
  insert: 45,
  deleteKey: 46,
  zero: 48,
  a: 65,
  z: 90,
};

let inputTimeout;

export default function(options) {
  var autocompletePlugin = this;

  if (this.length === 0) return;

  if (options === 'destroy') {
    Ember.run.cancel(inputTimeout);

    $(this).off('keypress.autocomplete')
           .off('keydown.autocomplete')
           .off('paste.autocomplete');

    return;
  }

  if (options && options.cancel && this.data("closeAutocomplete")) {
    this.data("closeAutocomplete")();
    return this;
  }

  if (this.length !== 1) {
    alert("only supporting one matcher at the moment");
  }

  var disabled = options && options.disabled;
  var wrap = null;
  var autocompleteOptions = null;
  var selectedOption = null;
  var completeStart = null;
  var completeEnd = null;
  var me = this;
  var div = null;

  // input is handled differently
  var isInput = this[0].tagName === "INPUT";
  var inputSelectedItems = [];

  var closeAutocomplete = function() {
    if (div) {
      div.hide().remove();
    }
    div = null;
    completeStart = null;
    autocompleteOptions = null;
  };

  var addInputSelectedItem = function(item) {
    var transformed,
        transformedItem = item;

    if (options.transformComplete) { transformedItem = options.transformComplete(transformedItem); }
    // dump what we have in single mode, just in case
    if (options.single) { inputSelectedItems = []; }
    transformed = _.isArray(transformedItem) ? transformedItem : [transformedItem || item];

    var divs = transformed.map(function(itm) {
      var d = $("
" + itm + "
");
      var prev = me.parent().find('.item:last');
      if (prev.length === 0) {
        me.parent().prepend(d);
      } else {
        prev.after(d);
      }
      inputSelectedItems.push(itm);
      return d[0];
    });

    if (options.onChangeItems) { options.onChangeItems(inputSelectedItems); }

    $(divs).find('a').click(function() {
      closeAutocomplete();
      inputSelectedItems.splice($.inArray(transformedItem, inputSelectedItems), 1);
      $(this).parent().parent().remove();
      if (options.single) {
        me.show();
      }
      if (options.onChangeItems) {
        options.onChangeItems(inputSelectedItems);
      }
      return false;
    });
  };

  var completeTerm = function(term) {
    if (term) {
      if (isInput) {
        me.val("");
        if(options.single){
          me.hide();
        }
        addInputSelectedItem(term);
      } else {
        if (options.transformComplete) {
          term = options.transformComplete(term);
        }

        if (term) {
          var text = me.val();
          text = text.substring(0, completeStart) + (options.key || "") + term + ' ' + text.substring(completeEnd + 1, text.length);
          me.val(text);
          Discourse.Utilities.setCaretPosition(me[0], completeStart + 1 + term.length);
        }
      }
    }
    closeAutocomplete();
  };

  if (isInput) {
    var width = this.width();
    wrap = this.wrap("
").parent();
    wrap.width(width);
    if(options.single) {
      this.css("width","100%");
    } else {
      this.width(150);
    }
    this.attr('name', this.attr('name') + "-renamed");
    var vals = this.val().split(",");
    _.each(vals,function(x) {
      if (x !== "") {
        if (options.reverseTransform) {
          x = options.reverseTransform(x);
        }
        addInputSelectedItem(x);
      }
    });
    if(options.items) {
      _.each(options.items, function(item){
        addInputSelectedItem(item);
      });
    }
    this.val("");
    completeStart = 0;
    wrap.click(function() {
      autocompletePlugin.focus();
      return true;
    });
  }

  var markSelected = function() {
    var links = div.find('li a');
    links.removeClass('selected');
    return $(links[selectedOption]).addClass('selected');
  };

  var renderAutocomplete = function() {
    if (div) {
      div.hide().remove();
    }
    if (autocompleteOptions.length === 0) return;

    div = $(options.template({ options: autocompleteOptions }));

    var ul = div.find('ul');
    selectedOption = 0;
    markSelected();
    ul.find('li').click(function() {
      selectedOption = ul.find('li').index(this);
      completeTerm(autocompleteOptions[selectedOption]);
      return false;
    });
    var pos = null;
    var vOffset = 0;
    var hOffset = 0;
    if (isInput) {
      pos = {
        left: 0,
        top: 0
      };
      vOffset = -32;
      hOffset = 0;
    } else {
      pos = me.caretPosition({
        pos: completeStart,
        key: options.key
      });
      hOffset = 27;
    }
    div.css({
      left: "-1000px"
    });

    me.parent().append(div);

    if(!isInput){
      vOffset = div.height();
    }

    if (Discourse.Mobile.mobileView && !isInput) {
      div.css('width', 'auto');

      if ((me.height() / 2) >= pos.top) { vOffset = -23; }
      if ((me.width() / 2) <= pos.left) { hOffset = -div.width(); }
    }

    var mePos = me.position();
    var borderTop = parseInt(me.css('border-top-width'), 10) || 0;
    div.css({
      position: 'absolute',
      top: (mePos.top + pos.top - vOffset + borderTop) + 'px',
      left: (mePos.left + pos.left + hOffset) + 'px'
    });
  };

  var updateAutoComplete = function(r) {

    if (completeStart === null) return;

    if (r && r.then && typeof(r.then) === "function") {
      if (div) {
        div.hide().remove();
      }
      r.then(updateAutoComplete);
      return;
    }

    // Allow an update method to cancel. This allows us to debounce
    // promises without leaking
    if (r === CANCELLED_STATUS) {
      return;
    }

    autocompleteOptions = r;
    if (!r || r.length === 0) {
      closeAutocomplete();
    } else {
      renderAutocomplete();
    }
  };

  // chain to allow multiples
  var oldClose = me.data("closeAutocomplete");
  me.data("closeAutocomplete", function() {
    if (oldClose) {
      oldClose();
    }
    closeAutocomplete();
  });

  $(this).on('paste.autocomplete', function() {
    _.delay(function(){
      me.trigger("keydown");
    }, 50);
  });

  $(this).on('keypress.autocomplete', function(e) {
    var caretPosition, term;

    // keep hunting backwards till you hit a the @ key
    if (options.key && e.which === options.key.charCodeAt(0)) {
      caretPosition = Discourse.Utilities.caretPosition(me[0]);
      var prevChar = me.val().charAt(caretPosition - 1);
      if (!prevChar || allowedLettersRegex.test(prevChar)) {
        completeStart = completeEnd = caretPosition;
        updateAutoComplete(options.dataSource(""));
      }
    } else if ((completeStart !== null) && (e.charCode !== 0)) {
      caretPosition = Discourse.Utilities.caretPosition(me[0]);
      term = me.val().substring(completeStart + (options.key ? 1 : 0), caretPosition);
      term += String.fromCharCode(e.charCode);
      updateAutoComplete(options.dataSource(term));
    }
  });

  $(this).on('keydown.autocomplete', function(e) {
    var c, caretPosition, i, initial, prev, prevIsGood, stopFound, term, total, userToComplete;

    if(e.ctrlKey || e.altKey || e.metaKey){
      return true;
    }

    if(options.allowAny){
      // saves us wiring up a change event as well, keypress is while its pressed

      Ember.run.cancel(inputTimeout);
      inputTimeout = Ember.run.later(function(){
        if(inputSelectedItems.length === 0) {
          inputSelectedItems.push("");
        }

        if(_.isString(inputSelectedItems[0]) && me.val().length > 0) {
          inputSelectedItems.pop();
          inputSelectedItems.push(me.val());
          if (options.onChangeItems) {
            options.onChangeItems(inputSelectedItems);
          }
        }

      }, 50);
    }

    if (!options.key) {
      completeStart = 0;
    }
    if (e.which === keys.shift) return;
    if ((completeStart === null) && e.which === keys.backSpace && options.key) {
      c = Discourse.Utilities.caretPosition(me[0]);
      c -= 1;
      initial = c;
      prevIsGood = true;
      while (prevIsGood && c >= 0) {
        c -= 1;
        prev = me[0].value[c];
        stopFound = prev === options.key;
        if (stopFound) {
          prev = me[0].value[c - 1];
          if (!prev || allowedLettersRegex.test(prev)) {
            completeStart = c;
            caretPosition = completeEnd = initial;
            term = me[0].value.substring(c + 1, initial);
            updateAutoComplete(options.dataSource(term));
            return true;
          }
        }
        prevIsGood = /[a-zA-Z\.]/.test(prev);
      }
    }

    // ESC
    if (e.which === keys.esc) {
      if (div !== null) {
        closeAutocomplete();
        return false;
      }
      return true;
    }

    if (completeStart !== null) {
      caretPosition = Discourse.Utilities.caretPosition(me[0]);

      // If we've backspaced past the beginning, cancel unless no key
      if (caretPosition <= completeStart && options.key) {
        closeAutocomplete();
        return false;
      }

      // Keyboard codes! So 80's.
      switch (e.which) {
        case keys.enter:
        case keys.rightArrow:
        case keys.tab:
          if (!autocompleteOptions) return true;
          if (selectedOption >= 0 && (userToComplete = autocompleteOptions[selectedOption])) {
            completeTerm(userToComplete);
          } else {
            // We're cancelling it, really.
            return true;
          }
          e.stopImmediatePropagation();
          return false;
        case keys.upArrow:
          selectedOption = selectedOption - 1;
          if (selectedOption < 0) {
            selectedOption = 0;
          }
          markSelected();
          return false;
        case keys.downArrow:
          total = autocompleteOptions.length;
          selectedOption = selectedOption + 1;
          if (selectedOption >= total) {
            selectedOption = total - 1;
          }
          if (selectedOption < 0) {
            selectedOption = 0;
          }
          markSelected();
          return false;
        case keys.backSpace:
          completeEnd = caretPosition;
          caretPosition--;

          if (caretPosition < 0) {
            closeAutocomplete();
            if (isInput) {
              i = wrap.find('a:last');
              if (i) {
                i.click();
              }
            }
            return true;
          }

          term = me.val().substring(completeStart + (options.key ? 1 : 0), caretPosition);

          updateAutoComplete(options.dataSource(term));
          return true;
        default:
          completeEnd = caretPosition;
          return true;
      }
    }
  });

  return this;
}
<|endoftext|>


<commit_before>/**
* @license Apache-2.0
*
* Copyright (c) 2018 The Stdlib Authors.
*
* 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.
*/

'use strict';

// MODULES //

var isInteger = require( '@stdlib/math/base/assert/is-integer' );
var isNegativeZero = require( '@stdlib/math/base/assert/is-negative-zero' );
var PINF = require( '@stdlib/constants/math/float64-pinf' );
var NINF = require( '@stdlib/constants/math/float64-ninf' );
var FLOAT32_SMALLEST_SUBNORMAL = require( '@stdlib/constants/math/float32-smallest-subnormal' ); // eslint-disable-line id-length
var INT8_MIN = require( '@stdlib/constants/math/int8-min' );
var INT16_MIN = require( '@stdlib/constants/math/int16-min' );
var INT32_MIN = require( '@stdlib/constants/math/int32-min' );
var UINT8_MAX = require( '@stdlib/constants/math/uint8-max' );
var UINT16_MAX = require( '@stdlib/constants/math/uint16-max' );
var UINT32_MAX = require( '@stdlib/constants/math/uint32-max' );

// MAIN //

/**
* Returns the minimum ndarray data type of the closest "kind" necessary for storing a provided scalar value.
*
* @param {*} value - scalar value
* @returns {string} ndarray data type
*
* @example
* var dt = minDataType( 3.141592653589793 );
* // returns 'float32'
*
* @example
* var dt = minDataType( 3 );
* // returns 'uint8'
*/
function minDataType( value ) {
	if ( typeof value !== 'number' ) {
		return 'generic';
	}
	if ( value !== value || value === PINF || value === NINF ) {
		return 'float32';
	}
	if ( isInteger( value ) ) {
		if ( value === 0 && isNegativeZero( value ) ) {
			return 'float32';
		}
		if ( value < 0 ) {
			if ( value >= INT8_MIN ) {
				return 'int8';
			}
			if ( value >= INT16_MIN ) {
				return 'int16';
			}
			if ( value >= INT32_MIN ) {
				return 'int32';
			}
			return 'float64';
		}
		if ( value <= UINT8_MAX ) {
			return 'uint8';
		}
		if ( value <= UINT16_MAX ) {
			return 'uint16';
		}
		if ( value <= UINT32_MAX ) {
			return 'uint32';
		}
		return 'float64';
	}
	// Assume that if we are provided a tiny value, we don't want to underflow to zero by storing as `float32`...
	if (
		value > -FLOAT32_SMALLEST_SUBNORMAL &&
		value < FLOAT32_SMALLEST_SUBNORMAL
	) {
		return 'float64';
	}
	// Any number which reaches this point is less than the maximum single-precision floating-point number, as floating-point format supports a limited number of decimals (e.g., (1.0+EPS)*10**15 => 1000000000000000.2, which is less than ~3.4e38)...
	return 'float32';
}

// EXPORTS //

module.exports = minDataType;
<commit_msg>Add TODO<commit_after>/**
* @license Apache-2.0
*
* Copyright (c) 2018 The Stdlib Authors.
*
* 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.
*/

'use strict';

// MODULES //

var isInteger = require( '@stdlib/math/base/assert/is-integer' );
var isNegativeZero = require( '@stdlib/math/base/assert/is-negative-zero' );
var PINF = require( '@stdlib/constants/math/float64-pinf' );
var NINF = require( '@stdlib/constants/math/float64-ninf' );
var FLOAT32_SMALLEST_SUBNORMAL = require( '@stdlib/constants/math/float32-smallest-subnormal' ); // eslint-disable-line id-length
var INT8_MIN = require( '@stdlib/constants/math/int8-min' );
var INT16_MIN = require( '@stdlib/constants/math/int16-min' );
var INT32_MIN = require( '@stdlib/constants/math/int32-min' );
var UINT8_MAX = require( '@stdlib/constants/math/uint8-max' );
var UINT16_MAX = require( '@stdlib/constants/math/uint16-max' );
var UINT32_MAX = require( '@stdlib/constants/math/uint32-max' );

// MAIN //

/**
* Returns the minimum ndarray data type of the closest "kind" necessary for storing a provided scalar value.
*
* @param {*} value - scalar value
* @returns {string} ndarray data type
*
* @example
* var dt = minDataType( 3.141592653589793 );
* // returns 'float32'
*
* @example
* var dt = minDataType( 3 );
* // returns 'uint8'
*/
function minDataType( value ) {
	if ( typeof value !== 'number' ) {
		// TODO: add support for complex numbers
		return 'generic';
	}
	if ( value !== value || value === PINF || value === NINF ) {
		return 'float32';
	}
	if ( isInteger( value ) ) {
		if ( value === 0 && isNegativeZero( value ) ) {
			return 'float32';
		}
		if ( value < 0 ) {
			if ( value >= INT8_MIN ) {
				return 'int8';
			}
			if ( value >= INT16_MIN ) {
				return 'int16';
			}
			if ( value >= INT32_MIN ) {
				return 'int32';
			}
			return 'float64';
		}
		if ( value <= UINT8_MAX ) {
			return 'uint8';
		}
		if ( value <= UINT16_MAX ) {
			return 'uint16';
		}
		if ( value <= UINT32_MAX ) {
			return 'uint32';
		}
		return 'float64';
	}
	// Assume that if we are provided a tiny value, we don't want to underflow to zero by storing as `float32`...
	if (
		value > -FLOAT32_SMALLEST_SUBNORMAL &&
		value < FLOAT32_SMALLEST_SUBNORMAL
	) {
		return 'float64';
	}
	// Any number which reaches this point is less than the maximum single-precision floating-point number, as floating-point format supports a limited number of decimals (e.g., (1.0+EPS)*10**15 => 1000000000000000.2, which is less than ~3.4e38)...
	return 'float32';
}

// EXPORTS //

module.exports = minDataType;
<|endoftext|>


<commit_before>function(doc) {
  if (typeof doc.aliases != "undefined") {
    emit([doc._id, 0, doc.created], doc);
  } else if (typeof doc.drilldown_url != "undefined") {
    emit([doc.tiid, 1, doc.created], doc);
  }
}<commit_msg>remove created from view key, breaks it for now<commit_after>function(doc) {
  if (typeof doc.aliases != "undefined") {
    emit([doc._id, 0], doc);
  } else if (typeof doc.drilldown_url != "undefined") {
    emit([doc.tiid, 1], doc);
  }
}<|endoftext|>


<commit_before>/*    Copyright 2020 Firewalla INC
 *
 *    This program is free software: you can redistribute it and/or  modify
 *    it under the terms of the GNU Affero General Public License, version 3,
 *    as published by the Free Software Foundation.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU Affero General Public License for more details.
 *
 *    You should have received a copy of the GNU Affero General Public License
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

 /*
  * Box (collect the following info)
  *   box states: just rebooted, this process crashed and connect, reconnected the socket io, scheduled update
  *   memory size
  *   mac addresses of ethX
  *   speed of each ethX
  *   Bluetooth mac address
  *   uptime
  *   uname -m
  *   box eid (if have)
  *   box license
  *   gateway mac address (the first three bytes)
  *   cpu temp
  *   current timestamp
  *   hash of firerouter (if applicable)
  *   hash of firewalla
  */

'use strict';

const exec = require('child-process-promise').exec;
const fs = require('fs');
const io2 = require('socket.io-client');
const os = require('os');
const sclient = require('../util/redis_manager.js').getSubscriptionClient();
const socket = io2(
  "https://api.firewalla.com",
  { path: "/socket",
    transports: ['websocket'],
    'upgrade': false }
);
const Promise = require('bluebird');
Promise.promisifyAll(fs);

process.title = 'FireHB';
const launchTime = Math.floor(new Date() / 1000);

let uid = null;

function getUniqueID(info) {
  const randomNumber = Math.floor(Math.random() * 1000000);
  if(info.mac) {
    return `${info.mac.toUpperCase()}-${launchTime}-${randomNumber}`;
  } else {
    return `INVALID_MAC-${launchTime}-${randomNumber}`;
  }
}

function log(message) {
  console.log(new Date(), message);
}

async function getShellOutput(cmd) {
  try {
    const result = await exec(cmd, { encoding: 'utf8' });
    return result && result.stdout && result.stdout.replace(/\n$/,'');
  } catch(err) {
    log("ERROR: "+err);
    return "";
  }
}

async function isBooted() {
  const fwHeartbeatFile = '/dev/shm/fw_heartbeat';
  try{
    await fs.accessAsync(fwHeartbeatFile, fs.constants.F_OK);
    return false;
  } catch (err) {
    log("System was booted.");
    await exec(`touch ${fwHeartbeatFile}`);
    return true;
  }
}

async function getCpuTemperature() {
  return await getShellOutput("cat /sys/class/thermal/thermal_zone0/temp");
}

async function getIPLinks() {
  const ipLinks = await getShellOutput("ip link show");
  return ipLinks.split("\n");
}

async function getDiskFree() {
  const dfFree = await getShellOutput("df -h | jq -sR '[split(\"\n\")[]|select(length>0)|split(\" +\")|add]'");
  return JSON.parse(dfFree);
}

async function getEthernetSpeed() {
    const eths = await getShellOutput("cd /sys/class/net; ls -1d eth* | fgrep -v .");
    if (!eths) return "";
    const ethSpeed = {};
    for (const eth of eths.split("\n")) {
      ethSpeed[eth] = await getShellOutput(`sudo ethtool ${eth} | awk '/Speed:/ {print $2}'`);
    }
    return ethSpeed;
}

async function getGatewayMacPrefix() {
  const gwIP = await getShellOutput("route -n | awk '$1 == \"0.0.0.0\" {print $2}'");
  if ( gwIP ) {
    const gwMacPrefix = await getShellOutput(`arp -a -n | grep ${gwIP} -w | awk '{print $4}' | cut -d: -f1-3`);
    return gwMacPrefix;
  } else {
    return '';
  }
}

async function getGitBranchName(cwd) {
  try {
    const result = await exec("git rev-parse --abbrev-ref HEAD", { cwd: cwd, encoding: 'utf8' });
    return result && result.stdout && result.stdout.trim();
  } catch(err) {
    //log(`ERROR: failed to get latest branch name in ${cwd}`+err);
    return '';
  }
}

async function getLatestCommitHash(cwd) {
  try {
    const result = await exec("git rev-parse HEAD", { cwd: cwd, encoding: 'utf8' });
    return result && result.stdout && result.stdout.trim();
  } catch(err) {
    //log(`ERROR: failed to get latest commit hash in ${cwd}`+err);
    return '';
  }
}

async function getLicenseInfo() {
  const licenseFile = "/home/pi/.firewalla/license";
  return ['SUUID', 'UUID', 'EID', 'LICENSE'].reduce( async (result,licenseField) => {
    result = await result;
    result[licenseField] = (await getShellOutput(`awk '/"${licenseField}"/ {print $NF}' ${licenseFile}`)).replace(/[",]/g,'');
    return result;
  },{});
}

async function getSysinfo(status) {
  const ifs = os.networkInterfaces();
  const memory = os.totalmem()
  const timestamp = Date.now();
  const uptime = os.uptime();
  const [arch, booted, btMac, cpuTemp, diskFree, ethSpeed, gatewayMacPrefix, gitBranchName, hashRouter, hashWalla, licenseInfo, mac, mode, redisEid] =
    await Promise.all([
      getShellOutput("uname -m"),
      isBooted(),
      getShellOutput("hcitool dev | awk '/hci0/ {print $2}'"),
      getCpuTemperature(),
      getDiskFree(),
      getEthernetSpeed(),
      getGatewayMacPrefix(),
      getGitBranchName(),
      getLatestCommitHash("/home/pi/firerouter"),
      getLatestCommitHash("/home/pi/firewalla"),
      getLicenseInfo(),
      getShellOutput("cat /sys/class/net/eth0/address"),
      getShellOutput("redis-cli get mode"),
      getShellOutput("redis-cli hget sys:ept eid")
    ]);

  if(!uid) {
    uid = getUniqueID({mac});
  }

  return {
    arch,
    booted,
    btMac,
    cpuTemp,
    ifs,
    diskFree,
    ethSpeed,
    licenseInfo,
    gatewayMacPrefix,
    gitBranchName,
    hashRouter,
    hashWalla,
    mac,
    memory,
    mode,
    redisEid,
    status,
    timestamp,
    uptime,
    uid
  };
}

async function update(status, extra) {
  let info = await getSysinfo(status);
  if(extra) {
    info = Object.assign({}, info, extra);
  }
  //log(`DEBUG: ${JSON.stringify(info,null,2)}`);
  socket.emit('update', info);
  return info;
}

const job = setInterval(() => {
  update("schedule");
}, 24 * 3600 * 1000); // every day

/* DEBUG
const job2 = setTimeout(() => {
  update("schedule");
}, 3000); // every 3 sec
 */

socket.on('connect', async () => {
  log("Connected to heartbeat server.");
  update('connect');
});

socket.on('disconnect', () => {
  log("Disconnected from heartbeat server.");
});

socket.on('update', () => {
  update("cloud");
});

socket.on('upgrade', () => {
  log("Upgrade started via heartbeat");
  exec("/home/pi/firewalla/scripts/fireupgrade_check.sh");
});

socket.on('reconnect', () => {
  log("Reconnected to heartbeat server.");
  //update('reconnect');
});

const eventName = "FIREWALLA:HEARTBEAT:UPDATE";
sclient.on("message", (channel, message) => {
  if(channel === eventName) {
    try {
      const object = JSON.parse(message);
      update('redis', object);
    } catch(err) {
      log("Failed to parse redis message.");
    }
  }
});
sclient.subscribe(eventName);
<commit_msg>simple change to get df output<commit_after>/*    Copyright 2020 Firewalla INC
 *
 *    This program is free software: you can redistribute it and/or  modify
 *    it under the terms of the GNU Affero General Public License, version 3,
 *    as published by the Free Software Foundation.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU Affero General Public License for more details.
 *
 *    You should have received a copy of the GNU Affero General Public License
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

 /*
  * Box (collect the following info)
  *   box states: just rebooted, this process crashed and connect, reconnected the socket io, scheduled update
  *   memory size
  *   mac addresses of ethX
  *   speed of each ethX
  *   Bluetooth mac address
  *   uptime
  *   uname -m
  *   box eid (if have)
  *   box license
  *   gateway mac address (the first three bytes)
  *   cpu temp
  *   current timestamp
  *   hash of firerouter (if applicable)
  *   hash of firewalla
  */

'use strict';

const exec = require('child-process-promise').exec;
const fs = require('fs');
const io2 = require('socket.io-client');
const os = require('os');
const sclient = require('../util/redis_manager.js').getSubscriptionClient();
const socket = io2(
  "https://api.firewalla.com",
  { path: "/socket",
    transports: ['websocket'],
    'upgrade': false }
);
const Promise = require('bluebird');
Promise.promisifyAll(fs);

process.title = 'FireHB';
const launchTime = Math.floor(new Date() / 1000);

let uid = null;

function getUniqueID(info) {
  const randomNumber = Math.floor(Math.random() * 1000000);
  if(info.mac) {
    return `${info.mac.toUpperCase()}-${launchTime}-${randomNumber}`;
  } else {
    return `INVALID_MAC-${launchTime}-${randomNumber}`;
  }
}

function log(message) {
  console.log(new Date(), message);
}

async function getShellOutput(cmd) {
  try {
    const result = await exec(cmd, { encoding: 'utf8' });
    return result && result.stdout && result.stdout.replace(/\n$/,'');
  } catch(err) {
    log("ERROR: "+err);
    return "";
  }
}

async function isBooted() {
  const fwHeartbeatFile = '/dev/shm/fw_heartbeat';
  try{
    await fs.accessAsync(fwHeartbeatFile, fs.constants.F_OK);
    return false;
  } catch (err) {
    log("System was booted.");
    await exec(`touch ${fwHeartbeatFile}`);
    return true;
  }
}

async function getCpuTemperature() {
  return await getShellOutput("cat /sys/class/thermal/thermal_zone0/temp");
}

async function getIPLinks() {
  const ipLinks = await getShellOutput("ip link show");
  return ipLinks.split("\n");
}

async function getDiskFree() {
  const dfFree = await getShellOutput("df -h");
  return dfFree.split("\n");
}

async function getEthernetSpeed() {
    const eths = await getShellOutput("cd /sys/class/net; ls -1d eth* | fgrep -v .");
    if (!eths) return "";
    const ethSpeed = {};
    for (const eth of eths.split("\n")) {
      ethSpeed[eth] = await getShellOutput(`sudo ethtool ${eth} | awk '/Speed:/ {print $2}'`);
    }
    return ethSpeed;
}

async function getGatewayMacPrefix() {
  const gwIP = await getShellOutput("route -n | awk '$1 == \"0.0.0.0\" {print $2}'");
  if ( gwIP ) {
    const gwMacPrefix = await getShellOutput(`arp -a -n | grep ${gwIP} -w | awk '{print $4}' | cut -d: -f1-3`);
    return gwMacPrefix;
  } else {
    return '';
  }
}

async function getGitBranchName(cwd) {
  try {
    const result = await exec("git rev-parse --abbrev-ref HEAD", { cwd: cwd, encoding: 'utf8' });
    return result && result.stdout && result.stdout.trim();
  } catch(err) {
    //log(`ERROR: failed to get latest branch name in ${cwd}`+err);
    return '';
  }
}

async function getLatestCommitHash(cwd) {
  try {
    const result = await exec("git rev-parse HEAD", { cwd: cwd, encoding: 'utf8' });
    return result && result.stdout && result.stdout.trim();
  } catch(err) {
    //log(`ERROR: failed to get latest commit hash in ${cwd}`+err);
    return '';
  }
}

async function getLicenseInfo() {
  const licenseFile = "/home/pi/.firewalla/license";
  return ['SUUID', 'UUID', 'EID', 'LICENSE'].reduce( async (result,licenseField) => {
    result = await result;
    result[licenseField] = (await getShellOutput(`awk '/"${licenseField}"/ {print $NF}' ${licenseFile}`)).replace(/[",]/g,'');
    return result;
  },{});
}

async function getSysinfo(status) {
  const ifs = os.networkInterfaces();
  const memory = os.totalmem()
  const timestamp = Date.now();
  const uptime = os.uptime();
  const [arch, booted, btMac, cpuTemp, diskFree, ethSpeed, gatewayMacPrefix, gitBranchName, hashRouter, hashWalla, licenseInfo, mac, mode, redisEid] =
    await Promise.all([
      getShellOutput("uname -m"),
      isBooted(),
      getShellOutput("hcitool dev | awk '/hci0/ {print $2}'"),
      getCpuTemperature(),
      getDiskFree(),
      getEthernetSpeed(),
      getGatewayMacPrefix(),
      getGitBranchName(),
      getLatestCommitHash("/home/pi/firerouter"),
      getLatestCommitHash("/home/pi/firewalla"),
      getLicenseInfo(),
      getShellOutput("cat /sys/class/net/eth0/address"),
      getShellOutput("redis-cli get mode"),
      getShellOutput("redis-cli hget sys:ept eid")
    ]);

  if(!uid) {
    uid = getUniqueID({mac});
  }

  return {
    arch,
    booted,
    btMac,
    cpuTemp,
    ifs,
    diskFree,
    ethSpeed,
    licenseInfo,
    gatewayMacPrefix,
    gitBranchName,
    hashRouter,
    hashWalla,
    mac,
    memory,
    mode,
    redisEid,
    status,
    timestamp,
    uptime,
    uid
  };
}

async function update(status, extra) {
  let info = await getSysinfo(status);
  if(extra) {
    info = Object.assign({}, info, extra);
  }
  //log(`DEBUG: ${JSON.stringify(info,null,2)}`);
  socket.emit('update', info);
  return info;
}

const job = setInterval(() => {
  update("schedule");
}, 24 * 3600 * 1000); // every day

/* DEBUG
const job2 = setTimeout(() => {
  update("schedule");
}, 3000); // every 3 sec
 */

socket.on('connect', async () => {
  log("Connected to heartbeat server.");
  update('connect');
});

socket.on('disconnect', () => {
  log("Disconnected from heartbeat server.");
});

socket.on('update', () => {
  update("cloud");
});

socket.on('upgrade', () => {
  log("Upgrade started via heartbeat");
  exec("/home/pi/firewalla/scripts/fireupgrade_check.sh");
});

socket.on('reconnect', () => {
  log("Reconnected to heartbeat server.");
  //update('reconnect');
});

const eventName = "FIREWALLA:HEARTBEAT:UPDATE";
sclient.on("message", (channel, message) => {
  if(channel === eventName) {
    try {
      const object = JSON.parse(message);
      update('redis', object);
    } catch(err) {
      log("Failed to parse redis message.");
    }
  }
});
sclient.subscribe(eventName);
<|endoftext|>


<commit_before>/**
 * Created by google on 16-11-9.
 */

import React, {Component} from "react";
import SwipeableViews from "react-swipeable-views";
import virtualize from "react-swipeable-views/lib/virtualize";
import mod from "react-swipeable-views/lib/utils/mod";

const EnhancedSwipeableViews = virtualize(SwipeableViews);

class CustomAutoPlay extends Component {

    constructor(props) {
        super(props);
        this.state = {index: 0};
    }

    static defaultProps = {
        autoplay: true,
        index: 0,
        interval: 1000,
    };

    componentWillUnmount() {
        clearInterval(this.timer);
    }

    timer = null;

    slideRenderer = (params, children)=> {
        let childrenLength = children.length;
        const {index, key} = params;
        if (mod(index, childrenLength) < childrenLength) {
            return this.dealChild(children[mod(index, childrenLength)], key)
        }
        return null
    }

    middle = (params)=> {
        let {children}=this.props;
        return this.slideRenderer(params, children);
    }

    dealChild = (div, key)=> {
        return

            {div}

    }

    componentDidMount() {
        this.startInterval();
    }

    startInterval() {
        let {autoplay, interval}=this.props;
        if (!autoplay) {
            return
        }
        clearInterval(this.timer);
        this.timer = setInterval(this.handleInterval, interval);
    }

    handleInterval = () => {
        let indexLatest = this.state.index;
        let {children}=this.props;
        let indexNew = mod((indexLatest + 1), children.length);
        this.changeIndex(indexNew)
    };

    onChangeIndex = (index, indexLatest)=> {
        let stateIndex = this.state.index;
        if ((index - indexLatest) > 0) {
            stateIndex += 1;
        } else if ((index - indexLatest) < 0) {
            stateIndex -= 1;
        }
        this.changeIndex(stateIndex)
    }

    handleSwitching = (index, type) => {
        if (this.timer) {
            clearInterval(this.timer);
            this.timer = null;
        } else if (type === 'end') {
            this.startInterval();
        }
    };

    changeIndex = (index)=> {
        let {children}=this.props;
        let childrenLength = children.length;
        index = mod(index, childrenLength)
        this.setState({
            index: index
        })
        let {changeIndexCallBack}=this.props;
        changeIndexCallBack && changeIndexCallBack(index)

    }

    render() {
        let {index}=this.state;
        return (
            <EnhancedSwipeableViews
                index={index}
                onSwitching={this.handleSwitching}
                onChangeIndex={this.onChangeIndex}
                slideRenderer={this.middle}/>
        );
    }
}

export default CustomAutoPlay;
<commit_msg>use compare<commit_after>/**
 * Created by google on 16-11-9.
 */

import React, {Component} from "react";
import SwipeableViews from "react-swipeable-views";
import virtualize from "react-swipeable-views/lib/virtualize";
import mod from "react-swipeable-views/lib/utils/mod";

import shallowCompare from 'react-addons-shallow-compare'

const EnhancedSwipeableViews = virtualize(SwipeableViews);

class CustomAutoPlay extends Component {

    constructor(props) {
        super(props);
        this.state = {index: 0};
    }

    static defaultProps = {
        autoplay: true,
        index: 0,
        interval: 1000,
    };

    shouldComponentUpdate(nextProps, nextState) {
        return shallowCompare(this, nextProps, nextState);
    }

    componentWillUnmount() {
        clearInterval(this.timer);
    }

    timer = null;

    slideRenderer = (params, children)=> {
        let childrenLength = children.length;
        const {index, key} = params;
        if (mod(index, childrenLength) < childrenLength) {
            return this.dealChild(children[mod(index, childrenLength)], key)
        }
        return null
    }

    middle = (params)=> {
        let {children}=this.props;
        return this.slideRenderer(params, children);
    }

    dealChild = (div, key)=> {
        return

            {div}

    }

    componentDidMount() {
        this.startInterval();
    }

    startInterval() {
        let {autoplay, interval}=this.props;
        if (!autoplay) {
            return
        }
        clearInterval(this.timer);
        this.timer = setInterval(this.handleInterval, interval);
    }

    handleInterval = () => {
        let indexLatest = this.state.index;
        let {children}=this.props;
        let indexNew = mod((indexLatest + 1), children.length);
        this.changeIndex(indexNew)
    };

    onChangeIndex = (index, indexLatest)=> {
        let stateIndex = this.state.index;
        if ((index - indexLatest) > 0) {
            stateIndex += 1;
        } else if ((index - indexLatest) < 0) {
            stateIndex -= 1;
        }
        this.changeIndex(stateIndex)
    }

    handleSwitching = (index, type) => {
        if (this.timer) {
            clearInterval(this.timer);
            this.timer = null;
        } else if (type === 'end') {
            this.startInterval();
        }
    };

    changeIndex = (index)=> {
        let {children}=this.props;
        let childrenLength = children.length;
        index = mod(index, childrenLength)
        this.setState({
            index: index
        })
        let {changeIndexCallBack}=this.props;
        changeIndexCallBack && changeIndexCallBack(index)

    }

    render() {
        let {index}=this.state;
        return (
            <EnhancedSwipeableViews
                index={index}
                onSwitching={this.handleSwitching}
                onChangeIndex={this.onChangeIndex}
                slideRenderer={this.middle}/>
        );
    }
}

export default CustomAutoPlay;
<|endoftext|>


<commit_before>(function(window, angular, undefined) {'use strict';
  angular.module('ngSelectBox', [])
  .run(['$templateCache', function($templateCache) {
  		var selectHtml =
  			'
\

\
  					\
  						{{selectedLabel}}\
  						\
  					\

\

\

\

\

\

';

  		$templateCache.put("select.html", selectHtml);
  	}])

  .directive('ngOptgroup', [function() {
  	return {
  		restrict: 'E',
  		scope: {
  			optGroupLabel: '@label',
  			optGroupValue: '@value',
  			optGroupImage: '@image',
  			optGroupTextColor: '@textColor'
  		},
  		transclude: true,
  		replace: true,
  		template: "
\
    						\
    							\
    								{{optGroupLabel}}\
    							\
    						\

",
  		require: '^ngSelectBox',
  		link: function(scope, elem, attrs, ngSelectBox, transclude) {
  			elem.find("a").css("text-decoration", "none").css("outline", "none").css("padding", "5px").css("display", "block").css("color", "#000000");
  			elem.find("img").css("border", "none").css("vertical-align", "middle").css("margin-left", "1px");

  			elem.find("a").bind("mouseover", function() {
  				scope.actualColor = scope.textColor.color;
  				elem.find('a').eq(0).css('color', 'white').css('background-color', '#27A1EC');
  			});

  			elem.find("a").bind("mouseleave", function() {
  				elem.find('a').eq(0).css('color', scope.actualColor).css('background-color', 'white');
  			});

  			if (scope.optGroupTextColor !== undefined) {
  				scope.textColor = {
  					'color': scope.optGroupTextColor
  				};
  			} else {
  				scope.textColor = {
  					'color': '#000000'
  				};
  			}

  			ngSelectBox.space = "\u00A0\u00A0\u00A0";
  			scope.isOptGroupImageVisible = false;

  			if (scope.optGroupImage !== undefined) {
  				scope.isOptGroupImageVisible = true;
  			}

  			transclude(function(clone, scope) {
  				elem.append(clone);
  			});

  			scope.getValue = function(optGroupLabel, optGroupValue, optGroupImage) {
  				ngSelectBox.getValue(optGroupLabel, optGroupValue, optGroupImage);
  			};
  		}
  	};
  }])

  .directive('ngOption', [function() {
  	return {
  		restrict: 'E',
  		scope: {
  			optionLabel: '@label',
  			optionValue: '@value',
  			optSelection: '@selected',
  			optImage: '@image',
  			optTextColor: '@textColor'
  		},
  		replace: true,
  		template: "
\
  						{{space}}\
  							{{optionLabel}}\
  						\

",
  		require: '^ngSelectBox',
  		link: function(scope, elem, attrs, ngSelectBox) {
  			elem.find("a").css("text-decoration", "none").css("outline", "none").css("padding", "5px").css("display", "block").css("color", "#000000");
  			elem.find("img").css("border", "none").css("vertical-align", "middle").css("margin-left", "1px");

  			elem.find("a").bind("mouseover", function() {
  				scope.actualColor = scope.textColor.color;
  				elem.find('a').css('color', 'white').css('background-color', '#27A1EC');
  			});

  			elem.find("a").bind("mouseleave", function() {
  				elem.find('a').css('color', scope.actualColor).css('background-color', 'white');
  			});

  			scope.space = ngSelectBox.space;
  			scope.isOptImageVisible = false;

  			if (scope.optImage !== undefined) {
  				scope.isOptImageVisible = true;
  			}

  			if (scope.optTextColor !== undefined) {
  				scope.textColor = {
  					'color': scope.optTextColor
  				};
  			} else {
  				scope.textColor = {
  					'color': '#000000'
  				};
  			}

  			if ((scope.optSelection === 'false') === false) {
  				ngSelectBox.getValue(scope.optionLabel, scope.optionValue, scope.optImage);
  			}

  			scope.getValue = function(optionLabel, optionValue, optImage) {
  				ngSelectBox.getValue(optionLabel, optionValue, optImage);
  			};
  		}
  	};
  }])

  .directive('ngSelectBox', ['$document', function($document) {
  	return {
  		restrict: 'E',
  		replace: true,
  		scope: {
  			ngModel: '=',
  			width: "@width"
  		},
  		transclude: true,
  		templateUrl: 'select.html',

  		compile: function(tElem, tAttrs) {
  			return {
  				pre: function(scope, iElem, iAttrs) {
  					angular.element(document.querySelector('.ngSelectBox')).css("font-family", "Arial, Helvetica, Sans-Serif").css("font-size", "0.75em").css("color", "#000");
  					angular.element(document.querySelector('.ngSelectBox dd')).css("margin", "0px").css("padding", "0px").css("position", "relative");
  					angular.element(document.querySelector('.ngSelectBox dt')).css("margin", "0px").css("padding", "0px");
  					angular.element(document.querySelector('.ngSelectBox ul')).css("margin", "0px").css("padding", "0px");
  					angular.element(document.querySelector('.ngSelectBox a')).css("text-decoration", "none").css("outline", "none");
  					angular.element(document.querySelector('.ngSelectBox dt a')).css("color", "#000000").css("background-image", "url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABGdBTUEAALGPC/xhBQAAAAZQTFRFAAAAAAAApWe5zwAAAAF0Uk5TAEDm2GYAAAAcSURBVAjXY2BABfIfQIj/AQP7AQbmBgZGNGkGAHE3BFlmUXkHAAAAAElFTkSuQmCC)").css("background-repeat", "no-repeat").css("background-position", "right center").css("display", "block").css("padding-right", "20px").css("border", "1px solid #CDCDCD").css("width", "150px");
  					angular.element(document.querySelector('.ngSelectBox dt a span')).css("cursor", "pointer").css("display", "block").css("padding", "5px");
  					angular.element(document.querySelector('.ngSelectBox dd ul')).css("background", "#ffffff none repeat scroll 0 0").css("border", "1px solid #CDCDCD").css("color", "#CDCDCD").css("display", "none").css("left", "0px").css("padding", "5px 0px").css("position", "absolute").css("top", "0px").css("width", "auto").css("min-width", "170px").css("list-style", "none");
  					angular.element(document.querySelector('.ngSelectBox dd ul li a')).css("padding", "5px").css("display", "block").css("color", "#000000");

  					scope.isOptionVisible = {};
  					scope.isOptionVisible.overflow = 'hidden';
  					scope.isOptionVisible['white-space'] = 'nowrap';
  					scope.isOptionVisible['text-overflow'] = 'ellipsis';
  					scope.ngSelectBoxStyle = angular.copy(scope.isOptionVisible);
  					scope.isOptionVisible.display = 'none';

  					if (scope.width) {
  						scope.isOptionVisible.width = parseInt(scope.width.substring(0, scope.width.indexOf('p'))) + 20 + "px";
  						scope.ngSelectBoxStyle.width = scope.width;
  					}

  					scope.toggleOptions = function() {
  						scope.isOptionVisible.display = (scope.isOptionVisible.display === 'none' ? 'block' : 'none');
  						$document.on("click", scope.onClick);
  					};

  					scope.onClick = function(event) {
  						if (scope.isOptionVisible.display !== 'none') {
  							scope.isOptionVisible.display = 'none';
  							return;
  						}

  						scope.$apply(iAttrs.clickAnywhereButHere);
  						$document.off("click", scope.onClick);
  					};
  				}
  			}
  		},
  		controller: ['$scope',function($scope) {
  			this.space = "";
  			function isJsonObject(object){
           try{
              JSON.parse(object)
              return true;
           }
           catch(err){
              return false;
           }
  			}

  			this.getValue = function(optionLabel, optionValue, optionImage) {
  				$scope.selectedLabel = optionLabel;
  				$scope.selectedValue = optionValue;

  				if (optionImage) {
  					$scope.selectedImage = optionImage;
  					$scope.isSelectedImageVisible = true;
  				} else {
  					$scope.isSelectedImageVisible = false;
  				}

          if(isJsonObject(optionValue)){
            $scope.ngModel = JSON.parse(optionValue);
          }
          else{
            $scope.ngModel = optionValue;
          }
  			};
  		}]
  	};
  }]);
})(window, window.angular);
<commit_msg>ngSelectBox.js<commit_after><|endoftext|>


<commit_before>'use strict';

define(['ol', 'toolbar', 'layermanager', 'geojson', 'sidebar', 'query', 'search', 'print', 'permalink', 'measure', 'geolocation', 'api', 'cesium', 'ows', 'cesiumjs'],

    function(ol, toolbar, layermanager, geojson) {
        var module = angular.module('hs', [
            'hs.toolbar',
            'hs.layermanager',
            'hs.query',
            'hs.search', 'hs.print', 'hs.permalink',
            'hs.geolocation',
            'hs.cesium',
            'hs.sidebar',
            'hs.ows'
        ]);

        module.directive('hs', ['hs.map.service', 'Core', '$compile', '$timeout', function(OlMap, Core, $compile, $timeout) {
            return {
                templateUrl: hsl_path + 'hslayers.html',
                link: function(scope, element) {
                    angular.element('.page-content', element).append($compile('

')(scope));
                    $timeout(function() {
                        Core.fullScreenMap(element)
                    }, 0);
                }
            };
        }]);

        module.value('config', {
            terrain_provider: 'http://gis.lesprojekt.cz/cts/tilesets/rostenice_dmp1g/',
            terrain_providers: [{
                title: 'Local terrain',
                url: 'http://gis.lesprojekt.cz/cts/tilesets/rostenice_dmp1g/',
                active: true
            }, {
                title: 'SRTM',
                url: 'https://assets.agi.com/stk-terrain/v1/tilesets/world/tiles',
                active: false
            }],
            default_layers: [
                new ol.layer.Tile({
                    source: new ol.source.OSM(),
                    title: "OpenStreetMap",
                    base: true,
                    visible: false,
                    minimumTerrainLevel: 15
                }),
                new ol.layer.Tile({
                    title: "Open-Land-Use (WMS)",
                    source: new ol.source.TileWMS({
                        url: 'http://gis.lesprojekt.cz/cgi-bin/mapserv?map=/home/dima/maps/olu/openlandusemap.map',
                        params: {
                            LAYERS: 'olu_bbox_srid',
                            FORMAT: "image/png",
                            INFO_FORMAT: "text/html",
                            minimumTerrainLevel: 15
                        },
                        crossOrigin: null
                    }),
                    legends: ['http://gis.lesprojekt.cz/cgi-bin/mapserv?map=/home/dima/maps/3d_olu/openlandusemap.map&service=WMS&request=GetLegendGraphic&layer=olu_bbox_srid&version=1.3.0&format=image/png&sld_version=1.1.0'],
                    maxResolution: 8550,
                    path: 'Open-Land-Use Map',
                    visible: false,
                    opacity: 0.7
                }),
                new ol.layer.Tile({
                    title: "Slope (in degrees)",
                    source: new ol.source.TileWMS({
                        url: 'http://gis.lesprojekt.cz/cgi-bin/mapserv?map=/home/dima/maps/3d_olu/rostenice.map',
                        params: {
                            LAYERS: 'slope',
                            FORMAT: "image/png",
                            INFO_FORMAT: "text/html",
                            minimumTerrainLevel: 14
                        },
                        crossOrigin: null
                    }),
                    legends: ['http://gis.lesprojekt.cz/cgi-bin/mapserv?map=/home/dima/maps/3d_olu/rostenice.map&service=WMS&request=GetLegendGraphic&layer=slope&version=1.3.0&format=image/png&sld_version=1.1.0'],
                    maxResolution: 8550,
                    visible: false,
                    opacity: 0.7
                }),
                new ol.layer.Tile({
                    title: "Slope orientation",
                    source: new ol.source.TileWMS({
                        url: 'http://gis.lesprojekt.cz/cgi-bin/mapserv?map=/home/dima/maps/3d_olu/rostenice.map',
                        params: {
                            LAYERS: 'orientation',
                            FORMAT: "image/png",
                            INFO_FORMAT: "text/html",
                            minimumTerrainLevel: 14
                        },
                        crossOrigin: null
                    }),
                    legends: ['http://gis.lesprojekt.cz/cgi-bin/mapserv?map=/home/dima/maps/3d_olu/rostenice.map&service=WMS&request=GetLegendGraphic&layer=orientation&version=1.3.0&format=image/png&sld_version=1.1.0'],
                    maxResolution: 8550,
                    visible: false,
                    opacity: 0.7
                }),
                new ol.layer.Tile({
                    title: "Yield potential Rostenice",
                    source: new ol.source.TileWMS({
                        url: 'http://gis.lesprojekt.cz/cgi-bin/mapserv?map=/home/dima/maps/3d_olu/rostenice.map',
                        params: {
                            LAYERS: 'yield_potential',
                            FORMAT: "image/png",
                            INFO_FORMAT: "text/html",
                            minimumTerrainLevel: 14
                        },
                        crossOrigin: null
                    }),
                    legends: ['http://gis.lesprojekt.cz/cgi-bin/mapserv?map=/home/dima/maps/3d_olu/rostenice.map&service=WMS&request=GetLegendGraphic&layer=yield_potential&version=1.3.0&format=image/png&sld_version=1.1.0'],
                    maxResolution: 8550,
                    visible: true,
                    opacity: 0.7
                })

            ],
            default_view: new ol.View({
                center: ol.proj.transform([16.8290202, 49.0751890], 'EPSG:4326', 'EPSG:3857'), //Latitude longitude    to Spherical Mercator
                zoom: 15,
                units: "m"
            })
        });

        module.controller('Main', ['$scope', '$compile', '$element', 'Core', 'hs.map.service', 'config',
            function($scope, $compile, $element, Core, OlMap, config) {
                if (console) console.log("Main called");
                $scope.hsl_path = hsl_path; //Get this from hslayers.js file
                $scope.Core = Core;

                Core.panelEnabled('compositions', false);
                Core.panelEnabled('status_creator', false);

                $scope.$on('infopanel.updated', function(event) {});
            }
        ]);

        return module;
    });
<commit_msg>datasource selector also for rostenice example<commit_after>'use strict';

define(['ol', 'toolbar', 'layermanager', 'geojson', 'sidebar', 'query', 'search', 'print', 'permalink', 'measure', 'geolocation', 'api', 'cesium', 'ows', 'cesiumjs', 'bootstrap', 'datasource_selector'],

    function(ol, toolbar, layermanager, geojson) {
        var module = angular.module('hs', [
            'hs.toolbar',
            'hs.layermanager',
            'hs.query',
            'hs.search', 'hs.print', 'hs.permalink',
            'hs.datasource_selector',
            'hs.geolocation',
            'hs.cesium',
            'hs.sidebar',
            'hs.ows'
        ]);

        module.directive('hs', ['hs.map.service', 'Core', '$compile', '$timeout', function(OlMap, Core, $compile, $timeout) {
            return {
                templateUrl: hsl_path + 'hslayers.html',
                link: function(scope, element) {
                    angular.element('.page-content', element).append($compile('

')(scope));
                    $timeout(function() {
                        Core.fullScreenMap(element)
                    }, 0);
                }
            };
        }]);

        module.value('config', {
            terrain_provider: 'http://gis.lesprojekt.cz/cts/tilesets/rostenice_dmp1g/',
            terrain_providers: [{
                title: 'Local terrain',
                url: 'http://gis.lesprojekt.cz/cts/tilesets/rostenice_dmp1g/',
                active: true
            }, {
                title: 'SRTM',
                url: 'https://assets.agi.com/stk-terrain/v1/tilesets/world/tiles',
                active: false
            }],
            default_layers: [
                new ol.layer.Tile({
                    source: new ol.source.OSM(),
                    title: "OpenStreetMap",
                    base: true,
                    visible: false,
                    minimumTerrainLevel: 15
                }),
                new ol.layer.Tile({
                    title: "Open-Land-Use (WMS)",
                    source: new ol.source.TileWMS({
                        url: 'http://gis.lesprojekt.cz/cgi-bin/mapserv?map=/home/dima/maps/olu/openlandusemap.map',
                        params: {
                            LAYERS: 'olu_bbox_srid',
                            FORMAT: "image/png",
                            INFO_FORMAT: "text/html",
                            minimumTerrainLevel: 15
                        },
                        crossOrigin: null
                    }),
                    legends: ['http://gis.lesprojekt.cz/cgi-bin/mapserv?map=/home/dima/maps/3d_olu/openlandusemap.map&service=WMS&request=GetLegendGraphic&layer=olu_bbox_srid&version=1.3.0&format=image/png&sld_version=1.1.0'],
                    maxResolution: 8550,
                    path: 'Open-Land-Use Map',
                    visible: false,
                    opacity: 0.7
                }),
                new ol.layer.Tile({
                    title: "Slope (in degrees)",
                    source: new ol.source.TileWMS({
                        url: 'http://gis.lesprojekt.cz/cgi-bin/mapserv?map=/home/dima/maps/3d_olu/rostenice.map',
                        params: {
                            LAYERS: 'slope',
                            FORMAT: "image/png",
                            INFO_FORMAT: "text/html",
                            minimumTerrainLevel: 14
                        },
                        crossOrigin: null
                    }),
                    legends: ['http://gis.lesprojekt.cz/cgi-bin/mapserv?map=/home/dima/maps/3d_olu/rostenice.map&service=WMS&request=GetLegendGraphic&layer=slope&version=1.3.0&format=image/png&sld_version=1.1.0'],
                    maxResolution: 8550,
                    visible: false,
                    opacity: 0.7
                }),
                new ol.layer.Tile({
                    title: "Slope orientation",
                    source: new ol.source.TileWMS({
                        url: 'http://gis.lesprojekt.cz/cgi-bin/mapserv?map=/home/dima/maps/3d_olu/rostenice.map',
                        params: {
                            LAYERS: 'orientation',
                            FORMAT: "image/png",
                            INFO_FORMAT: "text/html",
                            minimumTerrainLevel: 14
                        },
                        crossOrigin: null
                    }),
                    legends: ['http://gis.lesprojekt.cz/cgi-bin/mapserv?map=/home/dima/maps/3d_olu/rostenice.map&service=WMS&request=GetLegendGraphic&layer=orientation&version=1.3.0&format=image/png&sld_version=1.1.0'],
                    maxResolution: 8550,
                    visible: false,
                    opacity: 0.7
                }),
                new ol.layer.Tile({
                    title: "Yield potential Rostenice",
                    source: new ol.source.TileWMS({
                        url: 'http://gis.lesprojekt.cz/cgi-bin/mapserv?map=/home/dima/maps/3d_olu/rostenice.map',
                        params: {
                            LAYERS: 'yield_potential',
                            FORMAT: "image/png",
                            INFO_FORMAT: "text/html",
                            minimumTerrainLevel: 14
                        },
                        crossOrigin: null
                    }),
                    legends: ['http://gis.lesprojekt.cz/cgi-bin/mapserv?map=/home/dima/maps/3d_olu/rostenice.map&service=WMS&request=GetLegendGraphic&layer=yield_potential&version=1.3.0&format=image/png&sld_version=1.1.0'],
                    maxResolution: 8550,
                    visible: true,
                    opacity: 0.7
                })

            ],
            project_name: 'erra/map',
            datasources: [
                {
                    title: "Datasets",
                    url: "http://otn-dev.intrasoft-intl.com/otnServices-1.0/platform/ckanservices/datasets",
                    language: 'eng',
                    type: "ckan",
                    download: true
                }, {
                    title: "Services",
                    url: "http://cat.ccss.cz/csw/",
                    language: 'eng',
                    type: "micka",
                    code_list_url: 'http://www.whatstheplan.eu/php/metadata/util/codelists.php?_dc=1440156028103&language=eng&page=1&start=0&limit=25&filter=%5B%7B%22property%22%3A%22label%22%7D%5D'
                }, {
                    title: "Hub layers",
                    url: "http://opentnet.eu/php/metadata/csw/",
                    language: 'eng',
                    type: "micka",
                    code_list_url: 'http://opentnet.eu/php/metadata/util/codelists.php?_dc=1440156028103&language=eng&page=1&start=0&limit=25&filter=%5B%7B%22property%22%3A%22label%22%7D%5D'
                }
            ],
            hostname: {
                "default": {
                    "title": "Default",
                    "type": "default",
                    "editable": false,
                    "url": getHostname()
                }
            },
            'catalogue_url': "/php/metadata/csw",
            'compositions_catalogue_url': "/php/metadata/csw",
            status_manager_url: '/wwwlibs/statusmanager2/index.php',
            default_view: new ol.View({
                center: ol.proj.transform([16.8290202, 49.0751890], 'EPSG:4326', 'EPSG:3857'), //Latitude longitude    to Spherical Mercator
                zoom: 15,
                units: "m"
            })
        });

        module.controller('Main', ['$scope', '$compile', '$element', 'Core', 'hs.map.service', 'config',
            function($scope, $compile, $element, Core, OlMap, config) {
                if (console) console.log("Main called");
                $scope.hsl_path = hsl_path; //Get this from hslayers.js file
                $scope.Core = Core;

                Core.singleDatasources = true;
                Core.panelEnabled('compositions', true);
                Core.panelEnabled('status_creator', false);

                $scope.$on('infopanel.updated', function(event) {});
            }
        ]);

        return module;
    });
<|endoftext|>


<commit_before>const React = require('react');
const Velocity = require('velocity-animate');

const StyleConstants = require('../constants/Style');

const Icon = require('../components/Icon');

const Drawer = React.createClass({
  propTypes: {
    duration: React.PropTypes.number,
    easing: React.PropTypes.array,
    navConfig: React.PropTypes.shape({
      label: React.PropTypes.string.isRequired,
      onNextClick: React.PropTypes.func.isRequired,
      onPreviousClick: React.PropTypes.func.isRequired
    }),
    onClose: React.PropTypes.func.isRequired
  },

  getDefaultProps () {
    return {
      duration: 500,
      easing: [0.28, 0.14, 0.34, 1.04]
    };
  },

  componentDidMount () {
    const el = this._component;
    const transition = { right: 0 };
    const options = {
      duration: this.props.duration,
      easing: this.props.easing
    };

    Velocity(el, transition, options);
    this._animateBackArrow();
    if (this.props.navConfig) {
      this._animateNav();
    }
  },

  componentWillUnmount () {
    console.log('component unmounting');
  },

  _renderNav () {
    const styles = this.styles();

    return this.props.navConfig ?
       (this._nav = ref)} style={styles.nav}>
        <Icon onClick={this.props.navConfig.onPreviousClick} size={25} style={styles.icons} type='caret-left'/>
        {this.props.navConfig.label}
        <Icon onClick={this.props.navConfig.onNextClick} size={25} style={styles.icons} type='caret-right'/>
       : null;
  },

  _handleCloseClick () {
  },

  _animateBackArrow () {
    const el = this._backArrow;
    const transition = { left: 25 };
    const options = {
      delay: this.props.duration,
      duration: this.props.duration,
      easing: this.props.easing
    };

    Velocity(el, transition, options);
  },

  _animateNav () {
    const el = this._nav;
    const transition = { top: 12 };
    const options = {
      delay: this.props.duration,
      duration: this.props.duration,
      easing: this.props.easing
    };

    Velocity(el, transition, options);
  },

  render () {
    const styles = this.styles();

    return (

 (this._component = ref)} style={styles.component}>

           (this._backArrow = ref)} style={styles.backArrowContainer}>
            <Icon onClick={this._handleCloseClick} size={25} style={styles.icons}type='arrow-left'/>

          {this._renderNav()}

          {this.props.children}

    );
  },

  styles () {
    return {
      component: {
        top: 0,
        bottom: 0,
        right: -800,
        position: 'absolute',
        width: 800,
        overflow: 'hidden',
        backgroundColor: StyleConstants.Colors.PORCELAIN
      },
      icons: {
        color: StyleConstants.Colors.ASH
      },
      backArrowContainer: {
        position: 'absolute',
        left: -25,
        top: 12
      },
      header: {
        backgroundColor: StyleConstants.Colors.PORCELAIN,
        borderBottom: 'solid 1px ' + StyleConstants.Colors.FOG,
        height: 15,
        padding: '15px 25px'
      },
      nav: {
        fontFamily: StyleConstants.Fonts.THIN,
        color: StyleConstants.Colors.ASH,
        position: 'absolute',
        right: 25,
        top: -25
      }
    };
  }

});

module.exports = Drawer;
<commit_msg>backArrow naming<commit_after>const React = require('react');
const Velocity = require('velocity-animate');

const StyleConstants = require('../constants/Style');

const Icon = require('../components/Icon');

const Drawer = React.createClass({
  propTypes: {
    duration: React.PropTypes.number,
    easing: React.PropTypes.array,
    navConfig: React.PropTypes.shape({
      label: React.PropTypes.string.isRequired,
      onNextClick: React.PropTypes.func.isRequired,
      onPreviousClick: React.PropTypes.func.isRequired
    }),
    onClose: React.PropTypes.func.isRequired
  },

  getDefaultProps () {
    return {
      duration: 500,
      easing: [0.28, 0.14, 0.34, 1.04]
    };
  },

  componentDidMount () {
    const el = this._component;
    const transition = { right: 0 };
    const options = {
      duration: this.props.duration,
      easing: this.props.easing
    };

    Velocity(el, transition, options);
    this._animateBackArrow();
    if (this.props.navConfig) {
      this._animateNav();
    }
  },

  componentWillUnmount () {
    console.log('component unmounting');
  },

  _renderNav () {
    const styles = this.styles();

    return this.props.navConfig ?
       (this._nav = ref)} style={styles.nav}>
        <Icon onClick={this.props.navConfig.onPreviousClick} size={25} style={styles.icons} type='caret-left'/>
        {this.props.navConfig.label}
        <Icon onClick={this.props.navConfig.onNextClick} size={25} style={styles.icons} type='caret-right'/>
       : null;
  },

  _handleCloseClick () {
  },

  _animateBackArrow () {
    const el = this._backArrow;
    const transition = { left: 25 };
    const options = {
      delay: this.props.duration,
      duration: this.props.duration,
      easing: this.props.easing
    };

    Velocity(el, transition, options);
  },

  _animateNav () {
    const el = this._nav;
    const transition = { top: 12 };
    const options = {
      delay: this.props.duration,
      duration: this.props.duration,
      easing: this.props.easing
    };

    Velocity(el, transition, options);
  },

  render () {
    const styles = this.styles();

    return (

 (this._component = ref)} style={styles.component}>

           (this._backArrow = ref)} style={styles.backArrow}>
            <Icon onClick={this._handleCloseClick} size={25} style={styles.icons}type='arrow-left'/>

          {this._renderNav()}

          {this.props.children}

    );
  },

  styles () {
    return {
      component: {
        top: 0,
        bottom: 0,
        right: -800,
        position: 'absolute',
        width: 800,
        overflow: 'hidden',
        backgroundColor: StyleConstants.Colors.PORCELAIN
      },
      icons: {
        color: StyleConstants.Colors.ASH
      },
      backArrow: {
        position: 'absolute',
        left: -25,
        top: 12
      },
      header: {
        backgroundColor: StyleConstants.Colors.PORCELAIN,
        borderBottom: 'solid 1px ' + StyleConstants.Colors.FOG,
        height: 15,
        padding: '15px 25px'
      },
      nav: {
        fontFamily: StyleConstants.Fonts.THIN,
        color: StyleConstants.Colors.ASH,
        position: 'absolute',
        right: 25,
        top: -25
      }
    };
  }

});

module.exports = Drawer;
<|endoftext|>


<commit_before>angular.module('MyApp', ['ngResource', 'ngMessages', 'ngRoute', 'ngAuth', 'mgcrea.ngStrap'])
  .config(['$routeProvider', function($routeProvider) {
    $routeProvider
      .when('/', {
        templateUrl: 'views/home.html',
        controller: 'HomeCtrl'
      })
      .when('/login', {
        templateUrl: 'views/login.html',
        controller: 'LoginCtrl'
      })
      .when('/signup', {
        templateUrl: 'views/signup.html',
        controller: 'SignupCtrl'
      })
      .when('/logout', {
        template: null,
        controller: 'LogoutCtrl'
      })
      .when('/protected', {
        templateUrl: 'views/protected.html',
        controller: 'ProtectedCtrl'
      })
      .otherwise({
        redirectTo: '/'
      });
  }])
  .config(['AuthProvider', function(AuthProvider) {
    AuthProvider.configure({
      apiUrl: '/api'
    });
  }]);<commit_msg>Move AuthProvider into first config block<commit_after>angular.module('MyApp', ['ngResource', 'ngMessages', 'ngRoute', 'ngAuth', 'mgcrea.ngStrap'])
  .config(['$routeProvider', 'AuthProvider', function($routeProvider, AuthProvider) {
    $routeProvider
      .when('/', {
        templateUrl: 'views/home.html',
        controller: 'HomeCtrl'
      })
      .when('/login', {
        templateUrl: 'views/login.html',
        controller: 'LoginCtrl'
      })
      .when('/signup', {
        templateUrl: 'views/signup.html',
        controller: 'SignupCtrl'
      })
      .when('/logout', {
        template: null,
        controller: 'LogoutCtrl'
      })
      .when('/protected', {
        templateUrl: 'views/protected.html',
        controller: 'ProtectedCtrl'
      })
      .otherwise({
        redirectTo: '/'
      });

    AuthProvider.configure({
      apiUrl: '/api'
    });
  }]);
<|endoftext|>