<commit_before>/**
* Module that contains the data structure implementations.
* Depends on core.js, anim.js
*/
(function($) {
  if (typeof JSAV === "undefined") { return; }

  // create a utility function as a jQuery "plugin"
  $.fn.getstyles = function() {
    // Returns the values of CSS properties that are given as
    // arguments. For example, $elem.getstyles("background-color", "color")
    // could return an object {"background-color" : "rgb(255, 120, 120)",
    //                         "color" : "rgb(0, 0, 0)"}
    var res = {},
      arg;
    for (var i = 0; i < arguments.length; i++) {
      arg = arguments[i];
      if ($.isArray(arg)) {
        for (var j = 0; j < arg.length; j++) {
          res[arg[j]] = this.css(arg[j]);
        }
      } else {
        res[arg] = this.css(arg);
      }
    }
    return res;
  };

  // helper functions we want to keep private
  var priv = {
    _hide: function() {
      $(this.element).fadeOut(this.jsav.SPEED);
    },
    // utility function that actually implements show
    _show: function() {
      $(this.element).fadeIn(this.jsav.SPEED);
    }
  };

  // common properties/functions for all data structures, these can be copied
  // to the prototype of a new DS using the addCommonProperties(prototype) function
  var common = {
      // gets or sets the id of the DS
      'id': function(newId) {
        if (newId) {
          this._id = newId;
          return this;
        } else {
          if (!(this.hasOwnProperty("_id")) || typeof this._id === "undefined") {
            this._id = JSAV.utils.createUUID();
          }
          return this._id;
        }
      },
      // returns the position of the DS
      'position': function() {
        return JSAV.position(this.element);
      },
      // utility function that actually implements hide
      // animated show function
      show: JSAV.anim(function() { priv._show.apply(this); },
        function() { priv._hide.apply(this); }),
      // animated hide function
      hide: JSAV.anim(function() { priv._hide.apply(this); },
        function() { priv._show.apply(this); }),
      // dummy methods for initializing a DS, the DS should override these
      initialize: function() { },
      initializeFromElement: function() { },
      clone: function() {}
    },
    // initializes a data structure
    initDs = function(dstr, element, options) {
      dstr.options = $.extend(true, {}, options);
      if ($.isArray(element)) {
        dstr.initialize(element);
      } else if (element) { // assume it's a DOM element
        dstr.element = element;
        dstr.initializeFromElement();
      } else {
        // TODO: create an element for this data structure
      }
    };

  // function that selects elements from $elems that match the indices
  // filter (number, array of numbers, or filter function)
  var getIndices = function($elems, indices) {
    if (typeof indices === "undefined") { return $elems; } // use all if no restrictions are given
    if ($.isFunction(indices)) { // use a filter function..
      return $elems.filter(indices); // ..and let jQuery do the work
    } else if ($.isArray(indices)) {
      // return indices that are in the array
      return $elems.filter(function(index, item) {
        for (var i=0; i < indices.length; i++) {
          if (indices[i] == index) { return true; }
        }
        return false;
      });
    } else if (typeof indices === "number"){
      return $elems.eq(indices); // return the specific index
    } else {
      try { // last resort, try if the argument can be parsed into an int..
        return $elems.eq(parseInt(indices, 10));
      } catch (err) {
        return $({}); // ..if not, return an empty set
      }
    }
  };

  /* Array data structure for JSAV library. */
  var AVArray = function(jsav, element, options) {
    this.jsav = jsav;
    initDs(this, element, options);
  };
  var arrproto = AVArray.prototype;
  addCommonProperties(arrproto); // add functionality from common
  function setHighlight(indices, mode) {
    var testDiv = $('
' +
        '

'),
  	  styleDiv = (mode && mode === "add" ? testDiv.find(".jsavnode").filter(".jsavhighlight"):testDiv.find(".jsavnode").not(".jsavhighlight"));
  	// TODO: general way to get styles for the whole av system
  	$("body").append(testDiv);
    this.css(indices, {color: styleDiv.css("color"), "background-color": styleDiv.css("background-color")});
    testDiv.remove();
  }

  arrproto.isHighlight = function(index, options) {
    var testDiv = $('
' +
        '

'),
  	  styleDiv = testDiv.find(".jsavnode").filter(".jsavhighlight");
  	// TODO: general way to get styles for the whole av system
  	$("body").append(testDiv);
  	var isHl = getIndices($(this.element).find("li"), index).css("background-color") == styleDiv.css("background-color");
  	testDiv.remove();
  	return isHl;
  };

  arrproto.highlight = function(indices, options) {
    setHighlight.call(this, indices, "add");
    return this;
  };

  arrproto.unhighlight = function(indices, options) {
    setHighlight.call(this, indices, "remove");
    return this;
  };
  arrproto._setcss = JSAV.anim(function(indices, cssprop) {
    var $elems = getIndices($(this.element).find("li"), indices);
    if (!this.jsav.RECORD && !$.fx.off) { // only animate when playing, not when recording
      // also animate the values due to a bug in webkit based browsers with inherited bg color not changing
      $elems.animate(cssprop, this.jsav.SPEED).find("span.jsavvalue").animate(cssprop, this.jsav.SPEED);
    } else {
      $elems.css(cssprop).find("span.jsavvalue").css(cssprop);
    }
    return this;
  });
  arrproto.css = function(indices, cssprop) {
    var $elems = getIndices($(this.element).find("li"), indices);
    if (typeof cssprop === "string") {
      return $elems.css(cssprop);
    } else {
      if ($.isFunction(indices)) { // if indices is a function, evaluate it right away and get a list of indices
        var all_elems = $(this.element).find("li"),
          sel_indices = []; // array of selected indices
        for (var i = 0; i < $elems.size(); i++) {
          sel_indices.push(all_elems.index($elems[i]));
        }
        indices = sel_indices;
      }
      return this._setcss(indices, cssprop);
    }
  };
  function realSwap(index1, index2, options) {
    var $pi1 = $(this.element).find("li:eq(" + index1 + ")"), // index
      $pi2 = $(this.element).find("li:eq(" + index2 + ")");
    this.jsav.effects.swap($pi1, $pi2);
  }
  arrproto.swap = JSAV.anim(function(index1, index2, options) {
    realSwap.apply(this, arguments);
    return this;
  }, realSwap
  );
  arrproto.clone = function() {
    // fetch all values
    var size = this.size(),
      vals = [];
    for (var i=0; i < size; i++) {
      vals[i] = this.value(i);
    }
    return new AVArray(this.jsav, vals, $.extend(true, {}, this.options, {display: false}));
  };
  arrproto.size = function() { return this.element.find("li").size(); };
  arrproto.value = function(index, newValue) {
    if (!newValue) {
      var val = this.element.find("li:eq(" + index + ")").attr("data-value"),
          intval = parseInt(val, 10);
      if (isNaN(intval)) { return val || "";
      } else return intval;
    } else {
      return this.setvalue(index, newValue);
    }
  };
  arrproto.newindex = function(value) {
    var ind = $("
" + (value || "") + "
")
    ind.attr("data-value", value);
    return ind;
  };
  arrproto.setvalue = JSAV.anim(function(index, newValue) {
    var size = this.size();
    while (index > size - 1) {
      var newli = this.newindex();
      this.element.append(newli);
      size = this.size();
    }
    var $index = this.element.find("li:eq(" + index + ")");
    var oldVal = $index.attr("data-value") || undefined;
    $index.attr("data-value", newValue);
    $index.find(".jsavvalue").html("" + newValue);
    this.layout();
  });
  arrproto.initialize = function(data) {
    var el = this.options.element || $("
"),
      liel, liels = $()
      self = this;
    el.addClass("jsavarray");
    this.options = jQuery.extend({display: true}, this.options);
    $.each(data, function(index, item) {
      liel = self.newindex(item);
      liels = liels.add(liel);
    });
    el.append(liels);
    if (!this.options.element) {
      $(this.jsav.container).append(el);
    }
    this.element = el;
    this.layout();
    el.css("display", "hidden");
    var visible = (typeof this.options.display === "boolean" && this.options.display === true);
    if (visible) {
      if (this.jsav.currentStep() === 0) { // at beginning, just make it visible
        el.css("display", "block");
      } else { // add effect to show otherwise
        this.show();
      }
    }
  };
  arrproto.initializeFromElement = function() {
    // TODO: handle settings from data-attributes
    if (!this.element) { return; }
    var $elem = this.element,
      $elems = $elem.find("li");
    $elem.addClass("jsavarray");
    $elems.each(function(index, item) {
      var $this = $(this);
      if (!$this.attr("data-value")) {
        $this.attr("data-value", parseInt($this.html(), 10));
      }
      $this.addClass("jsavnode jsavindex").html("" + $this.html() + "");
    });
    this.layout();
  };
  arrproto.layout = function() {
    var layoutAlg = this.options.layout || "_default";
    this.element.removeClass("jsavbararray");
    this.jsav.layout.array[layoutAlg](this);
  };
  arrproto.state = function(newstate) {
    if (newstate) {
      $(this.element).html(newstate.html);
    } else {
      var sta = {
        html: $(this.element).html()
      };
      return sta;
    }
  };
  arrproto.equals = function(otherArray, options) {
    var opts = options || {},
      i, j,
      equal,
      cssprop,
      len;
    if ($.isArray(otherArray)) { // simple case of array values
      if (!options) { // if nothing in options is specified
        len = otherArray.length;
        if (this.size() !== len) { // don't compare arrays of different size
          return false;
        }
        for (i = 0; i < len; i++) { // are the values equal
          equal = this.value(i) == otherArray[i];
          if (!equal) { return false; }
        }
        return true; // if tests passed, arrays are equal
      } else { // if options
        if ('css' in opts) { // if css property given, compare given array to property
          cssprop = opts.css;
          for (i = 0; i < len; i++) {
            equal = this.css(i, cssprop) == otherArray[i];
            if (!equal) { return false; }
          }
          return true; // if tests passed, arrays are equal
        }
      }
    } else { // JSAV array
      len = otherArray.size();
      if (this.size() !== len) { // size check
        return false;
      }
      if (!('value' in opts) || opts['value']) { // if comparing values
        for (i = 0; i < len; i++) {
          equal = this.value(i) == otherArray.value(i);
          if (!equal) { return false; }
        }
      }
      if ('css' in opts) { // if comparing css properties
        if ($.isArray(opts.css)) { // array of property names
          for (i = 0; i < opts.css.length; i++) {
            cssprop = opts.css[i];
            for (j = 0; j < len; j++) {
              equal = this.css(j, cssprop) == otherArray.css(j, cssprop);
              if (!equal) { return false; }
            }
          }
        } else { // if not array, expect it to be a property name string
          cssprop = opts.css;
          for (i = 0; i < len; i++) {
            equal = this.css(i, cssprop) == otherArray.css(i, cssprop);
            if (!equal) { return false; }
          }
        }
      }
      return true; // if tests passed, arrays are equal
    }

    // default: return false
    return false;
  };
  arrproto.clear = function() {
    this.element.remove();
  };

  arrproto.toggleArrow = JSAV.anim(function(indices) {
    var $elems = getIndices($(this.element).find("li"), indices);
    $elems.toggleClass("jsavarrow");
  });

  function addCommonProperties(dsPrototype, commonProps) {
    if (!commonProps) { commonProps = common; }
    for (var prop in commonProps) {
      if (commonProps.hasOwnProperty(prop)) {
        dsPrototype[prop] = commonProps[prop];
      }
    }
  }

  JSAV._types.ds = {
	AVArray: AVArray
  };
  // expose the data structures for the JSAV
  JSAV.ext.ds = {
    array: function(element, options) {
      return new AVArray(this, element, options);
    },
    extend: function(strName, strPrototype) {
      // copies properties for strName into strPrototype
      if (strName === "common") {
        addCommonProperties(strPrototype);
      }
    }
  };
})(jQuery);
<commit_msg>Fixed a bug that appeared in IE<commit_after>/**
* Module that contains the data structure implementations.
* Depends on core.js, anim.js
*/
(function($) {
  if (typeof JSAV === "undefined") { return; }

  // create a utility function as a jQuery "plugin"
  $.fn.getstyles = function() {
    // Returns the values of CSS properties that are given as
    // arguments. For example, $elem.getstyles("background-color", "color")
    // could return an object {"background-color" : "rgb(255, 120, 120)",
    //                         "color" : "rgb(0, 0, 0)"}
    var res = {},
      arg;
    for (var i = 0; i < arguments.length; i++) {
      arg = arguments[i];
      if ($.isArray(arg)) {
        for (var j = 0; j < arg.length; j++) {
          res[arg[j]] = this.css(arg[j]);
        }
      } else {
        res[arg] = this.css(arg);
      }
    }
    return res;
  };

  // helper functions we want to keep private
  var priv = {
    _hide: function() {
      $(this.element).fadeOut(this.jsav.SPEED);
    },
    // utility function that actually implements show
    _show: function() {
      $(this.element).fadeIn(this.jsav.SPEED);
    }
  };

  // common properties/functions for all data structures, these can be copied
  // to the prototype of a new DS using the addCommonProperties(prototype) function
  var common = {
      // gets or sets the id of the DS
      'id': function(newId) {
        if (newId) {
          this._id = newId;
          return this;
        } else {
          if (!(this.hasOwnProperty("_id")) || typeof this._id === "undefined") {
            this._id = JSAV.utils.createUUID();
          }
          return this._id;
        }
      },
      // returns the position of the DS
      'position': function() {
        return JSAV.position(this.element);
      },
      // utility function that actually implements hide
      // animated show function
      show: JSAV.anim(function() { priv._show.apply(this); },
        function() { priv._hide.apply(this); }),
      // animated hide function
      hide: JSAV.anim(function() { priv._hide.apply(this); },
        function() { priv._show.apply(this); }),
      // dummy methods for initializing a DS, the DS should override these
      initialize: function() { },
      initializeFromElement: function() { },
      clone: function() {}
    },
    // initializes a data structure
    initDs = function(dstr, element, options) {
      dstr.options = $.extend(true, {}, options);
      if ($.isArray(element)) {
        dstr.initialize(element);
      } else if (element) { // assume it's a DOM element
        dstr.element = element;
        dstr.initializeFromElement();
      } else {
        // TODO: create an element for this data structure
      }
    };

  // function that selects elements from $elems that match the indices
  // filter (number, array of numbers, or filter function)
  var getIndices = function($elems, indices) {
    if (typeof indices === "undefined") { return $elems; } // use all if no restrictions are given
    if ($.isFunction(indices)) { // use a filter function..
      return $elems.filter(indices); // ..and let jQuery do the work
    } else if ($.isArray(indices)) {
      // return indices that are in the array
      return $elems.filter(function(index, item) {
        for (var i=0; i < indices.length; i++) {
          if (indices[i] == index) { return true; }
        }
        return false;
      });
    } else if (typeof indices === "number"){
      return $elems.eq(indices); // return the specific index
    } else {
      try { // last resort, try if the argument can be parsed into an int..
        return $elems.eq(parseInt(indices, 10));
      } catch (err) {
        return $({}); // ..if not, return an empty set
      }
    }
  };

  /* Array data structure for JSAV library. */
  var AVArray = function(jsav, element, options) {
    this.jsav = jsav;
    initDs(this, element, options);
  };
  var arrproto = AVArray.prototype;
  addCommonProperties(arrproto); // add functionality from common
  function setHighlight(indices, mode) {
    var testDiv = $('
' +
        '

'),
  	  styleDiv = (mode && mode === "add" ? testDiv.find(".jsavnode").filter(".jsavhighlight"):testDiv.find(".jsavnode").not(".jsavhighlight"));
  	// TODO: general way to get styles for the whole av system
  	$("body").append(testDiv);
    this.css(indices, {color: styleDiv.css("color"), "background-color": styleDiv.css("background-color")});
    testDiv.remove();
  }

  arrproto.isHighlight = function(index, options) {
    var testDiv = $('
' +
        '

'),
  	  styleDiv = testDiv.find(".jsavnode").filter(".jsavhighlight");
  	// TODO: general way to get styles for the whole av system
  	$("body").append(testDiv);
  	var isHl = getIndices($(this.element).find("li"), index).css("background-color") == styleDiv.css("background-color");
  	testDiv.remove();
  	return isHl;
  };

  arrproto.highlight = function(indices, options) {
    setHighlight.call(this, indices, "add");
    return this;
  };

  arrproto.unhighlight = function(indices, options) {
    setHighlight.call(this, indices, "remove");
    return this;
  };
  arrproto._setcss = JSAV.anim(function(indices, cssprop) {
    var $elems = getIndices($(this.element).find("li"), indices);
    if (!this.jsav.RECORD && !$.fx.off) { // only animate when playing, not when recording
      // also animate the values due to a bug in webkit based browsers with inherited bg color not changing
      $elems.animate(cssprop, this.jsav.SPEED).find("span.jsavvalue").animate(cssprop, this.jsav.SPEED);
    } else {
      $elems.css(cssprop).find("span.jsavvalue").css(cssprop);
    }
    return this;
  });
  arrproto.css = function(indices, cssprop) {
    var $elems = getIndices($(this.element).find("li"), indices);
    if (typeof cssprop === "string") {
      return $elems.css(cssprop);
    } else {
      if ($.isFunction(indices)) { // if indices is a function, evaluate it right away and get a list of indices
        var all_elems = $(this.element).find("li"),
          sel_indices = []; // array of selected indices
        for (var i = 0; i < $elems.size(); i++) {
          sel_indices.push(all_elems.index($elems[i]));
        }
        indices = sel_indices;
      }
      return this._setcss(indices, cssprop);
    }
  };
  function realSwap(index1, index2, options) {
    var $pi1 = $(this.element).find("li:eq(" + index1 + ")"), // index
      $pi2 = $(this.element).find("li:eq(" + index2 + ")");
    this.jsav.effects.swap($pi1, $pi2);
  }
  arrproto.swap = JSAV.anim(function(index1, index2, options) {
    realSwap.apply(this, arguments);
    return this;
  }, realSwap
  );
  arrproto.clone = function() {
    // fetch all values
    var size = this.size(),
      vals = [];
    for (var i=0; i < size; i++) {
      vals[i] = this.value(i);
    }
    return new AVArray(this.jsav, vals, $.extend(true, {}, this.options, {display: false}));
  };
  arrproto.size = function() { return this.element.find("li").size(); };
  arrproto.value = function(index, newValue) {
    if (!newValue) {
      var val = this.element.find("li:eq(" + index + ")").attr("data-value"),
          intval = parseInt(val, 10);
      if (isNaN(intval)) { return val || "";
      } else return intval;
    } else {
      return this.setvalue(index, newValue);
    }
  };
  arrproto._newindex = function(value) {
    var ind = $("
" + (value || "") + "
")
    ind.attr("data-value", value);
    return ind;
  };
  arrproto.setvalue = JSAV.anim(function(index, newValue) {
    var size = this.size();
    while (index > size - 1) {
      var newli = this._newindex();
      this.element.append(newli);
      size = this.size();
    }
    var $index = this.element.find("li:eq(" + index + ")");
    var oldVal = $index.attr("data-value") || undefined;
    $index.attr("data-value", newValue);
    $index.find(".jsavvalue").html("" + newValue);
    this.layout();
  });
  arrproto.initialize = function(data) {
    var el = this.options.element || $("
"),
      liel, liels = $();
    el.addClass("jsavarray");
    this.options = jQuery.extend({display: true}, this.options);
    for (var i=0; i < data.length; i++) {
      liel = this._newindex(data[i]);
      liels = liels.add(liel);
    }
    el.append(liels);
    if (!this.options.element) {
      $(this.jsav.container).append(el);
    }
    this.element = el;
    this.layout();
    el.css("display", "hidden");
    var visible = (typeof this.options.display === "boolean" && this.options.display === true);
    if (visible) {
      if (this.jsav.currentStep() === 0) { // at beginning, just make it visible
        el.css("display", "block");
      } else { // add effect to show otherwise
        this.show();
      }
    }
  };
  arrproto.initializeFromElement = function() {
    // TODO: handle settings from data-attributes
    if (!this.element) { return; }
    var $elem = this.element,
      $elems = $elem.find("li");
    $elem.addClass("jsavarray");
    $elems.each(function(index, item) {
      var $this = $(this);
      if (!$this.attr("data-value")) {
        $this.attr("data-value", parseInt($this.html(), 10));
      }
      $this.addClass("jsavnode jsavindex").html("" + $this.html() + "");
    });
    this.layout();
  };
  arrproto.layout = function() {
    var layoutAlg = this.options.layout || "_default";
    this.element.removeClass("jsavbararray");
    this.jsav.layout.array[layoutAlg](this);
  };
  arrproto.state = function(newstate) {
    if (newstate) {
      $(this.element).html(newstate.html);
    } else {
      var sta = {
        html: $(this.element).html()
      };
      return sta;
    }
  };
  arrproto.equals = function(otherArray, options) {
    var opts = options || {},
      i, j,
      equal,
      cssprop,
      len;
    if ($.isArray(otherArray)) { // simple case of array values
      if (!options) { // if nothing in options is specified
        len = otherArray.length;
        if (this.size() !== len) { // don't compare arrays of different size
          return false;
        }
        for (i = 0; i < len; i++) { // are the values equal
          equal = this.value(i) == otherArray[i];
          if (!equal) { return false; }
        }
        return true; // if tests passed, arrays are equal
      } else { // if options
        if ('css' in opts) { // if css property given, compare given array to property
          cssprop = opts.css;
          for (i = 0; i < len; i++) {
            equal = this.css(i, cssprop) == otherArray[i];
            if (!equal) { return false; }
          }
          return true; // if tests passed, arrays are equal
        }
      }
    } else { // JSAV array
      len = otherArray.size();
      if (this.size() !== len) { // size check
        return false;
      }
      if (!('value' in opts) || opts['value']) { // if comparing values
        for (i = 0; i < len; i++) {
          equal = this.value(i) == otherArray.value(i);
          if (!equal) { return false; }
        }
      }
      if ('css' in opts) { // if comparing css properties
        if ($.isArray(opts.css)) { // array of property names
          for (i = 0; i < opts.css.length; i++) {
            cssprop = opts.css[i];
            for (j = 0; j < len; j++) {
              equal = this.css(j, cssprop) == otherArray.css(j, cssprop);
              if (!equal) { return false; }
            }
          }
        } else { // if not array, expect it to be a property name string
          cssprop = opts.css;
          for (i = 0; i < len; i++) {
            equal = this.css(i, cssprop) == otherArray.css(i, cssprop);
            if (!equal) { return false; }
          }
        }
      }
      return true; // if tests passed, arrays are equal
    }

    // default: return false
    return false;
  };
  arrproto.clear = function() {
    this.element.remove();
  };

  arrproto.toggleArrow = JSAV.anim(function(indices) {
    var $elems = getIndices($(this.element).find("li"), indices);
    $elems.toggleClass("jsavarrow");
  });

  function addCommonProperties(dsPrototype, commonProps) {
    if (!commonProps) { commonProps = common; }
    for (var prop in commonProps) {
      if (commonProps.hasOwnProperty(prop)) {
        dsPrototype[prop] = commonProps[prop];
      }
    }
  }

  JSAV._types.ds = {
	AVArray: AVArray
  };
  // expose the data structures for the JSAV
  JSAV.ext.ds = {
    array: function(element, options) {
      return new AVArray(this, element, options);
    },
    extend: function(strName, strPrototype) {
      // copies properties for strName into strPrototype
      if (strName === "common") {
        addCommonProperties(strPrototype);
      }
    }
  };
})(jQuery);
<|endoftext|>


<commit_before>var input = document.getElementById( "pac-input" );

var initializeMap = function() {
	//help from http://stackoverflow.com/a/24234818/1779797

	fx = google.maps.InfoWindow.prototype.setPosition
	google.maps.InfoWindow.prototype.setPosition = function() {
		fx.apply(this, arguments);
		//this property isn't documented, but as it seems
		//it's only defined for InfoWindows opened on POI's
		if (this.logAsInternal) {
			var infoWindow = this;
			var name = infoWindow.getContent().firstChild.firstChild.nodeValue;
			var pos = infoWindow.position;
			console.log(name);
			console.log(pos.lat() + ", " + pos.lng())
			$.get("/place/" + name + "/" + pos.lat() + "/" + pos.lng(), function(response) {
				console.log(response);
				$("#places-page").text(JSON.stringify(response));
			})
		}
	}

	var styles = [
		{
			"featureType": "road",
			"elementType": "geometry",
			"stylers": [
				{ "hue": "#cc00ff" },
				{ "saturation": -74 },
				{ "lightness": 23 }
			]
		}, {
			"featureType": "landscape",
			"stylers": [
				{ "saturation": -100 },
				{ "lightness": 50 }
			]
		}, {
			"featureType": "poi",
			"elementType": "geometry",
			"stylers": [
				{ "hue": "#55ff00" },
				{ "saturation": 67 }
			]
		}, {
			"featureType": "transit",
			"stylers": [
				{ "visibility": "off" }
			]
		}, {
			"featureType": "water",
			"stylers": [
				{ "hue": "#0077ff" }
			]
		}, {
			"featureType": "road",
			"elementType": "labels",
			"stylers": [
				{ "visibility": "off" }
			]
		}, {
			"featureType": "road.highway",
			"stylers": [
				{ "lightness": 21 }
			]
		}
	];

	var mapOptions = {
		center: {
			lat: 46.78003,
			lng: 7.96637
		}, zoom: 8,
		minZoom: 4,
		disableDefaultUI: true,
		styles: styles
	};

	var map = new google.maps.Map( document.getElementById( "map-canvas" ), mapOptions );

	var flags = {
		"en": "/static/img/flag-en.png",
		"fr": "/static/img/flag-fr.png",
		"es": "/static/img/flag-es.png",
		"de": "/static/img/flag-de.png",
		"it": "/static/img/flag-it.png"
	};

	// Leaving this here for nostalgia & in case the new way is too slow
	/* $.get( "/languageslocations/-180/-90/180/90", function( response ) {
		map.data.addGeoJson( response );

		map.data.setStyle( function( feature ) {
			var lang = feature.getProperty( "language" );
			var icon = "/static/img/dot.png";
			if ( lang in flags ) { icon = flags[lang]; }
			return { "icon": icon };
		} );
	} ); */

	//map.controls[google.maps.ControlPosition.TOP_LEFT].push( input );

	var circle = $( "circle-canvas" ).circle();

	var lastBounds = false;
	var updateLocation = function() {

		// AJAX(map.getBounds().toString(),loadData)

		// ignore changes smaller than 5%
		change = 0.05;
		var update = true;
		var bounds = map.getBounds();
		if ( lastBounds ) {
			var width = lastBounds.getSouthWest().lng() - lastBounds.getNorthEast().lng();
			var height = lastBounds.getSouthWest().lat() - lastBounds.getNorthEast().lat();
			update = Math.abs( ( lastBounds.getSouthWest().lng() - bounds.getSouthWest().lng() ) / width ) > change ||
							 Math.abs( ( lastBounds.getNorthEast().lng() - bounds.getNorthEast().lng() ) / width ) > change ||
							 Math.abs( ( lastBounds.getSouthWest().lat() - bounds.getSouthWest().lat() ) / height ) > change ||
							 Math.abs( ( lastBounds.getNorthEast().lat() - bounds.getNorthEast().lat() ) / height ) > change
		}

		if ( update ) {
			var sw = bounds.getSouthWest();
			var ne = bounds.getNorthEast();

			// create a closure so that when the server replies we use the right lastBounds, bounds etc.
			( function( lastBounds, bounds, sw, ne ) {
			$.get( "/languageslocations/" + sw.lng() + "/" + sw.lat() + "/" + ne.lng() + "/" + ne.lat(),
			function( response ) {

				// Only add features that weren't in lastBounds (ie new ones)
				var filteredFeatures = response.features.filter( function( feature ) {
					var coords = feature.geometry.coordinates;
					var featureLatLng = new google.maps.LatLng( coords[1], coords[0] );
					return lastBounds ? !lastBounds.contains( featureLatLng ) : true;
				} );
				var filteredResponse = { "type": "FeatureCollection", "features": filteredFeatures };
				map.data.addGeoJson( filteredResponse );

				// Remove all feautures which aren't on the screen
				map.data.forEach( function( feature ) {
					var featureLatLng = feature.getGeometry().get();
					if ( !bounds.contains( featureLatLng ) ) {
						map.data.remove( feature );
					}
				} );
				map.data.setStyle( function( feature ) {
					var lang = feature.getProperty( "language" );
					var icon = "/static/img/dot.png";
					if ( lang in flags ) { icon = flags[lang]; }
					return { "icon": icon };
				} );
			} ); } )( lastBounds, bounds, sw, ne );

			$.get( "/languages/" + sw.lng() + "/" + sw.lat() + "/" + ne.lng() + "/" + ne.lat(),
			function( response ) {
				var data = response.data;

				// Sort by tweet count
				data.sort( function( a, b ) {
					return b[1] - a[1];
				} );

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

				// # of segs not including "other"
				var circlePortions = [];
				var otherShare = 100;
				var minShareSize = 1.0;
				var shareLargeEnough = true;

				var languageShareHtml = "";
				for ( i = 0; i < data.length; i++ ) {
					var languageId = data[i][0];
					var languageTweetCount = data[i][1];
					var languageTweetShare = ( languageTweetCount * 100 / tweetCount ).toFixed( 1 );

					if ( languageTweetShare >= minShareSize ) {
						var languageShareDisplay = "
: " + languageTweetShare + "%
\n";

						if ( !( languageId in flags ) ) {
							languageShareDisplay = "
" + languageId + ": " + languageTweetShare +
								"%
\n";
						}

						languageShareHtml += languageShareDisplay;

						circlePortions.push( parseFloat( languageTweetShare ) );
						otherShare -= parseFloat( languageTweetShare );
					}
				}
				$( "#languages" ).html( languageShareHtml );
				if ( otherShare > 1 && otherShare < 100 ) {
					circlePortions.push( otherShare );
					circle.drawLangaugeSegments( circlePortions, true );
				} else {
					circle.drawLangaugeSegments( circlePortions, false );
				}
			} );

			$.get( "/words/" + sw.lng() + "/" + sw.lat() + "/" + ne.lng() + "/" + ne.lat() + "/20",
							function( response ) {
				var words = response.words;
				var wordCloudHtml = "";
				for ( var i = 0; i < words.length; i++ ) {
					wordCloudHtml += "
" +	words[i].word + ": " + words[i].count + "
\n";
				}
				$( "#wordcloud" ).html( wordCloudHtml );
			} );

			lastBounds = bounds;
		}

	};

	//updateLocation()
	google.maps.event.addListener( map, "bounds_changed", updateLocation );

	//temporarily ignore the sheer number of requests that would get sent here

	//Search box, code from https://developers.google.com/maps/documentation/javascript/examples/places-autocomplete

	var autocomplete = new google.maps.places.Autocomplete( input );
	autocomplete.bindTo( "bounds", map );

	var infowindow = new google.maps.InfoWindow();

	google.maps.event.addListener( autocomplete, "place_changed", function() {
		infowindow.close();
		var place = autocomplete.getPlace();
		if ( !place.geometry ) {
			return;
		}

		// If the place has a geometry, then present it on a map.
		if ( place.geometry.viewport ) {
			map.fitBounds( place.geometry.viewport );
		} else {
			map.setCenter( place.geometry.location );
		}
		map.setZoom( 10 );
	} );

};

google.maps.event.addDomListener( window, "load", initializeMap );
<commit_msg>display content in infowindow<commit_after>var input = document.getElementById( "pac-input" );

var initializeMap = function() {
	//help from http://stackoverflow.com/a/24234818/1779797

	fx = google.maps.InfoWindow.prototype.setPosition
	google.maps.InfoWindow.prototype.setPosition = function() {
		fx.apply(this, arguments);
		//this property isn't documented, but as it seems
		//it's only defined for InfoWindows opened on POI's
		if (this.logAsInternal) {
			var infoWindow = this;
			var name = infoWindow.getContent().firstChild.firstChild.nodeValue;
			var pos = infoWindow.position;
			console.log(name);
			console.log(pos.lat() + ", " + pos.lng())
			$.get("/place/" + name + "/" + pos.lat() + "/" + pos.lng(), function(response) {
				console.log(response);
				infoWindow.setContent(JSON.stringify(response));
			})
		}
	}

	var styles = [
		{
			"featureType": "road",
			"elementType": "geometry",
			"stylers": [
				{ "hue": "#cc00ff" },
				{ "saturation": -74 },
				{ "lightness": 23 }
			]
		}, {
			"featureType": "landscape",
			"stylers": [
				{ "saturation": -100 },
				{ "lightness": 50 }
			]
		}, {
			"featureType": "poi",
			"elementType": "geometry",
			"stylers": [
				{ "hue": "#55ff00" },
				{ "saturation": 67 }
			]
		}, {
			"featureType": "transit",
			"stylers": [
				{ "visibility": "off" }
			]
		}, {
			"featureType": "water",
			"stylers": [
				{ "hue": "#0077ff" }
			]
		}, {
			"featureType": "road",
			"elementType": "labels",
			"stylers": [
				{ "visibility": "off" }
			]
		}, {
			"featureType": "road.highway",
			"stylers": [
				{ "lightness": 21 }
			]
		}
	];

	var mapOptions = {
		center: {
			lat: 46.78003,
			lng: 7.96637
		}, zoom: 8,
		minZoom: 4,
		disableDefaultUI: true,
		styles: styles
	};

	var map = new google.maps.Map( document.getElementById( "map-canvas" ), mapOptions );

	var flags = {
		"en": "/static/img/flag-en.png",
		"fr": "/static/img/flag-fr.png",
		"es": "/static/img/flag-es.png",
		"de": "/static/img/flag-de.png",
		"it": "/static/img/flag-it.png"
	};

	// Leaving this here for nostalgia & in case the new way is too slow
	/* $.get( "/languageslocations/-180/-90/180/90", function( response ) {
		map.data.addGeoJson( response );

		map.data.setStyle( function( feature ) {
			var lang = feature.getProperty( "language" );
			var icon = "/static/img/dot.png";
			if ( lang in flags ) { icon = flags[lang]; }
			return { "icon": icon };
		} );
	} ); */

	//map.controls[google.maps.ControlPosition.TOP_LEFT].push( input );

	var circle = $( "circle-canvas" ).circle();

	var lastBounds = false;
	var updateLocation = function() {

		// AJAX(map.getBounds().toString(),loadData)

		// ignore changes smaller than 5%
		change = 0.05;
		var update = true;
		var bounds = map.getBounds();
		if ( lastBounds ) {
			var width = lastBounds.getSouthWest().lng() - lastBounds.getNorthEast().lng();
			var height = lastBounds.getSouthWest().lat() - lastBounds.getNorthEast().lat();
			update = Math.abs( ( lastBounds.getSouthWest().lng() - bounds.getSouthWest().lng() ) / width ) > change ||
							 Math.abs( ( lastBounds.getNorthEast().lng() - bounds.getNorthEast().lng() ) / width ) > change ||
							 Math.abs( ( lastBounds.getSouthWest().lat() - bounds.getSouthWest().lat() ) / height ) > change ||
							 Math.abs( ( lastBounds.getNorthEast().lat() - bounds.getNorthEast().lat() ) / height ) > change
		}

		if ( update ) {
			var sw = bounds.getSouthWest();
			var ne = bounds.getNorthEast();

			// create a closure so that when the server replies we use the right lastBounds, bounds etc.
			( function( lastBounds, bounds, sw, ne ) {
			$.get( "/languageslocations/" + sw.lng() + "/" + sw.lat() + "/" + ne.lng() + "/" + ne.lat(),
			function( response ) {

				// Only add features that weren't in lastBounds (ie new ones)
				var filteredFeatures = response.features.filter( function( feature ) {
					var coords = feature.geometry.coordinates;
					var featureLatLng = new google.maps.LatLng( coords[1], coords[0] );
					return lastBounds ? !lastBounds.contains( featureLatLng ) : true;
				} );
				var filteredResponse = { "type": "FeatureCollection", "features": filteredFeatures };
				map.data.addGeoJson( filteredResponse );

				// Remove all feautures which aren't on the screen
				map.data.forEach( function( feature ) {
					var featureLatLng = feature.getGeometry().get();
					if ( !bounds.contains( featureLatLng ) ) {
						map.data.remove( feature );
					}
				} );
				map.data.setStyle( function( feature ) {
					var lang = feature.getProperty( "language" );
					var icon = "/static/img/dot.png";
					if ( lang in flags ) { icon = flags[lang]; }
					return { "icon": icon };
				} );
			} ); } )( lastBounds, bounds, sw, ne );

			$.get( "/languages/" + sw.lng() + "/" + sw.lat() + "/" + ne.lng() + "/" + ne.lat(),
			function( response ) {
				var data = response.data;

				// Sort by tweet count
				data.sort( function( a, b ) {
					return b[1] - a[1];
				} );

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

				// # of segs not including "other"
				var circlePortions = [];
				var otherShare = 100;
				var minShareSize = 1.0;
				var shareLargeEnough = true;

				var languageShareHtml = "";
				for ( i = 0; i < data.length; i++ ) {
					var languageId = data[i][0];
					var languageTweetCount = data[i][1];
					var languageTweetShare = ( languageTweetCount * 100 / tweetCount ).toFixed( 1 );

					if ( languageTweetShare >= minShareSize ) {
						var languageShareDisplay = "
: " + languageTweetShare + "%
\n";

						if ( !( languageId in flags ) ) {
							languageShareDisplay = "
" + languageId + ": " + languageTweetShare +
								"%
\n";
						}

						languageShareHtml += languageShareDisplay;

						circlePortions.push( parseFloat( languageTweetShare ) );
						otherShare -= parseFloat( languageTweetShare );
					}
				}
				$( "#languages" ).html( languageShareHtml );
				if ( otherShare > 1 && otherShare < 100 ) {
					circlePortions.push( otherShare );
					circle.drawLangaugeSegments( circlePortions, true );
				} else {
					circle.drawLangaugeSegments( circlePortions, false );
				}
			} );

			$.get( "/words/" + sw.lng() + "/" + sw.lat() + "/" + ne.lng() + "/" + ne.lat() + "/20",
							function( response ) {
				var words = response.words;
				var wordCloudHtml = "";
				for ( var i = 0; i < words.length; i++ ) {
					wordCloudHtml += "
" +	words[i].word + ": " + words[i].count + "
\n";
				}
				$( "#wordcloud" ).html( wordCloudHtml );
			} );

			lastBounds = bounds;
		}

	};

	//updateLocation()
	google.maps.event.addListener( map, "bounds_changed", updateLocation );

	//temporarily ignore the sheer number of requests that would get sent here

	//Search box, code from https://developers.google.com/maps/documentation/javascript/examples/places-autocomplete

	var autocomplete = new google.maps.places.Autocomplete( input );
	autocomplete.bindTo( "bounds", map );

	var infowindow = new google.maps.InfoWindow();
	var marker = new google.maps.Marker({
		map: map
	});
	google.maps.event.addListener(marker, 'click', function() {
		infowindow.open(map, marker);
	});

	google.maps.event.addListener( autocomplete, "place_changed", function() {
		infowindow.close();
		var place = autocomplete.getPlace();
		if ( !place.geometry ) {
			return;
		}

		// If the place has a geometry, then present it on a map.
		if ( place.geometry.viewport ) {
			map.fitBounds( place.geometry.viewport );
		} else {
			map.setCenter( place.geometry.location );
		}
		map.setZoom(13);
	});

};

google.maps.event.addDomListener( window, "load", initializeMap );
<|endoftext|>


<commit_before>import React from 'react';
import ReactDOM from 'react-dom';
import createReactClass from 'create-react-class';
import PropTypes from 'prop-types';
import moment from 'moment';
import { formatDate } from '../util';

const DateInput = createReactClass({
  propTypes: {
    prefixCls: PropTypes.string,
    timePicker: PropTypes.object,
    value: PropTypes.object,
    disabledTime: PropTypes.any,
    format: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]),
    locale: PropTypes.object,
    disabledDate: PropTypes.func,
    onChange: PropTypes.func,
    onClear: PropTypes.func,
    placeholder: PropTypes.string,
    onSelect: PropTypes.func,
    selectedValue: PropTypes.object,
    clearIcon: PropTypes.node,
  },

  getInitialState() {
    const selectedValue = this.props.selectedValue;
    return {
      str: formatDate(selectedValue, this.props.format),
      invalid: false,
      hasFocus: false,
    };
  },

  componentWillReceiveProps(nextProps) {
    this.cachedSelectionStart = this.dateInputInstance.selectionStart;
    this.cachedSelectionEnd = this.dateInputInstance.selectionEnd;
    // when popup show, click body will call this, bug!
    const selectedValue = nextProps.selectedValue;
    if (!this.state.hasFocus) {
      this.setState({
        str: formatDate(selectedValue, nextProps.format),
        invalid: false,
      });
    }
  },

  componentDidUpdate() {
    if (this.state.hasFocus && !this.state.invalid &&
        !(this.cachedSelectionStart === 0 && this.cachedSelectionEnd === 0)) {
      this.dateInputInstance.setSelectionRange(this.cachedSelectionStart, this.cachedSelectionEnd);
    }
  },

  onInputChange(event) {
    const str = event.target.value;
    const { disabledDate, format, onChange, selectedValue } = this.props;

    // 没有内容，合法并直接退出
    if (!str) {
      onChange(null);
      this.setState({
        invalid: false,
      });
      return;
    }

    // 不合法直接退出
    const parsed = moment(str, format, true);
    if (!parsed.isValid()) {
      this.setState({
        invalid: true,
      });
      return;
    }

    const value = this.props.value.clone();
    value
      .year(parsed.year())
      .month(parsed.month())
      .date(parsed.date())
      .hour(parsed.hour())
      .minute(parsed.minute())
      .second(parsed.second());

    if (!value || (disabledDate && disabledDate(value))) {
      this.setState({
        invalid: true,
      });
      return;
    }

    if (selectedValue !== value || (
      selectedValue && value && !selectedValue.isSame(value)
    )) {
      onChange(value);
    }
  },

  onClear() {
    this.setState({
      str: '',
    });
    this.props.onClear(null);
  },

  getRootDOMNode() {
    return ReactDOM.findDOMNode(this);
  },

  focus() {
    if (this.dateInputInstance) {
      this.dateInputInstance.focus();
    }
  },

  saveDateInput(dateInput) {
    this.dateInputInstance = dateInput;
  },

  onFocus() {
    this.setState({ hasFocus: true });
  },

  onBlur() {
    this.setState((prevState, prevProps) => ({
      hasFocus: false,
      str: formatDate(prevProps.value, prevProps.format),
    }));
  },

  render() {
    const props = this.props;
    const { invalid, str } = this.state;
    const { locale, prefixCls, placeholder, clearIcon } = props;
    const invalidClass = invalid ? `${prefixCls}-input-invalid` : '';
    return (
      <div className={`${prefixCls}-input-wrap`}>
        <div className={`${prefixCls}-date-input-wrap`}>
          <input
            ref={this.saveDateInput}
            className={`${prefixCls}-input ${invalidClass}`}
            value={str}
            disabled={props.disabled}
            placeholder={placeholder}
            onChange={this.onInputChange}
            onFocus={this.onFocus}
            onBlur={this.onBlur}
          />

        {props.showClear ? (

            {clearIcon || <span className={`${prefixCls}-clear-btn`}/>}

        ) : null}

    );
  },
});

export default DateInput;
<commit_msg>fix test case<commit_after>import React from 'react';
import ReactDOM from 'react-dom';
import createReactClass from 'create-react-class';
import PropTypes from 'prop-types';
import moment from 'moment';
import { formatDate } from '../util';

const DateInput = createReactClass({
  propTypes: {
    prefixCls: PropTypes.string,
    timePicker: PropTypes.object,
    value: PropTypes.object,
    disabledTime: PropTypes.any,
    format: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]),
    locale: PropTypes.object,
    disabledDate: PropTypes.func,
    onChange: PropTypes.func,
    onClear: PropTypes.func,
    placeholder: PropTypes.string,
    onSelect: PropTypes.func,
    selectedValue: PropTypes.object,
    clearIcon: PropTypes.node,
  },

  getInitialState() {
    const selectedValue = this.props.selectedValue;
    return {
      str: formatDate(selectedValue, this.props.format),
      invalid: false,
      hasFocus: false,
    };
  },

  componentWillReceiveProps(nextProps) {
    this.cachedSelectionStart = this.dateInputInstance.selectionStart;
    this.cachedSelectionEnd = this.dateInputInstance.selectionEnd;
    // when popup show, click body will call this, bug!
    const selectedValue = nextProps.selectedValue;
    if (!this.state.hasFocus) {
      this.setState({
        str: formatDate(selectedValue, nextProps.format),
        invalid: false,
      });
    }
  },

  componentDidUpdate() {
    if (this.state.hasFocus && !this.state.invalid &&
        !(this.cachedSelectionStart === 0 && this.cachedSelectionEnd === 0)) {
      this.dateInputInstance.setSelectionRange(this.cachedSelectionStart, this.cachedSelectionEnd);
    }
  },

  onInputChange(event) {
    const str = event.target.value;
    const { disabledDate, format, onChange, selectedValue } = this.props;

    // 没有内容，合法并直接退出
    if (!str) {
      onChange(null);
      this.setState({
        invalid: false,
        str,
      });
      return;
    }

    // 不合法直接退出
    const parsed = moment(str, format, true);
    if (!parsed.isValid()) {
      this.setState({
        invalid: true,
        str,
      });
      return;
    }

    const value = this.props.value.clone();
    value
      .year(parsed.year())
      .month(parsed.month())
      .date(parsed.date())
      .hour(parsed.hour())
      .minute(parsed.minute())
      .second(parsed.second());

    if (!value || (disabledDate && disabledDate(value))) {
      this.setState({
        invalid: true,
        str,
      });
      return;
    }

    if (selectedValue !== value || (
      selectedValue && value && !selectedValue.isSame(value)
    )) {
      this.setState({
        str,
      });
      onChange(value);
    }
  },

  onClear() {
    this.setState({
      str: '',
    });
    this.props.onClear(null);
  },

  getRootDOMNode() {
    return ReactDOM.findDOMNode(this);
  },

  focus() {
    if (this.dateInputInstance) {
      this.dateInputInstance.focus();
    }
  },

  saveDateInput(dateInput) {
    this.dateInputInstance = dateInput;
  },

  onFocus() {
    this.setState({ hasFocus: true });
  },

  onBlur() {
    this.setState((prevState, prevProps) => ({
      hasFocus: false,
      str: formatDate(prevProps.value, prevProps.format),
    }));
  },

  render() {
    const props = this.props;
    const { invalid, str } = this.state;
    const { locale, prefixCls, placeholder, clearIcon } = props;
    const invalidClass = invalid ? `${prefixCls}-input-invalid` : '';
    return (
      <div className={`${prefixCls}-input-wrap`}>
        <div className={`${prefixCls}-date-input-wrap`}>
          <input
            ref={this.saveDateInput}
            className={`${prefixCls}-input ${invalidClass}`}
            value={str}
            disabled={props.disabled}
            placeholder={placeholder}
            onChange={this.onInputChange}
            onFocus={this.onFocus}
            onBlur={this.onBlur}
          />

        {props.showClear ? (

            {clearIcon || <span className={`${prefixCls}-clear-btn`}/>}

        ) : null}

    );
  },
});

export default DateInput;
<|endoftext|>


<commit_before>const gen = require('crypto-random-string');
const {game} = require('../config');

exports.genHealPack = function * (num, hp) {
  while (num--) {
    yield {
      id: gen(8),
      posX: game.area.x * Math.random(),
      posY: game.area.y * Math.random(),
      hp
    };
  }
};

exports.genWeapon = function * (num) {
  while (num--) {
    yield {
      id: gen(8),
      posX: game.area.x * Math.random(),
      posY: game.area.y * Math.random(),
      type: randomType()
    };
  }
};

exports.genWall = function * (num) {
  while (num--) {
    yield {
      posX: game.area.x * Math.random(),
      posY: game.area.y * Math.random(),
      scaleX: Math.random() * 1.5 + 0.5,
      scaleY: Math.random() * 1.5 + 0.5,
      angle: Math.random() * 360
    }
  }
}

function randomType () {
  const random = Math.random();
  if (random < 0.4) return 0;
  if (random < 0.55) return 1;
  if (random < 0.7) return 2;
  if (random < 0.85) return 3;
  return 4;
}
<commit_msg>eslint<commit_after>const gen = require('crypto-random-string');
const {game} = require('../config');

exports.genHealPack = function * (num, hp) {
  while (num--) {
    yield {
      id: gen(8),
      posX: game.area.x * Math.random(),
      posY: game.area.y * Math.random(),
      hp
    };
  }
};

exports.genWeapon = function * (num) {
  while (num--) {
    yield {
      id: gen(8),
      posX: game.area.x * Math.random(),
      posY: game.area.y * Math.random(),
      type: randomType()
    };
  }
};

exports.genWall = function * (num) {
  while (num--) {
    yield {
      posX: game.area.x * Math.random(),
      posY: game.area.y * Math.random(),
      scaleX: Math.random() * 1.5 + 0.5,
      scaleY: Math.random() * 1.5 + 0.5,
      angle: Math.random() * 360
    };
  }
};

function randomType () {
  const random = Math.random();
  if (random < 0.4) return 0;
  if (random < 0.55) return 1;
  if (random < 0.7) return 2;
  if (random < 0.85) return 3;
  return 4;
}
<|endoftext|>


<commit_before>var defaultConfig = require('./karma.conf');

var sauceLaunchers = {
  ie9: {
    base: 'SauceLabs',
    browserName: 'internet explorer',
    platform: 'Windows 7',
    version: '9'
  },
  ie10: {
    base: 'SauceLabs',
    browserName: 'internet explorer',
    platform: 'Windows 7',
    version: '10'
  },
  ie11: {
    base: 'SauceLabs',
    browserName: 'internet explorer',
    platform: 'Windows 8.1',
    version: '11'
  }
}

module.exports = function (config) {

  defaultConfig(config);

  config.set({

    sauceLabs: {
      testName: 'iframe-transport Unit Tests'
    },

    customLaunchers: sauceLaunchers,

    browsers: Object.keys(sauceLaunchers),

    reporters: ['dots', 'saucelabs'],

    singleRun: true

  });

};
<commit_msg>Sauce tests passing in good chunk of browsers<commit_after>var defaultConfig = require('./karma.conf');

var sauceLaunchers = {
  chromeMac: {
    base: 'SauceLabs',
    browserName: 'chrome',
    platform: 'OS X 10.10'
  },
  firefoxMac: {
    base: 'SauceLabs',
    browserName: 'firefox',
    platform: 'OS X 10.10'
  },
  chromeWin7: {
    base: 'SauceLabs',
    browserName: 'chrome',
    platform: 'Windows 7'
  },
  firefoxWin7: {
    base: 'SauceLabs',
    browserName: 'chrome',
    platform: 'Windows 7'
  },
  chromeWin8_1: {
    base: 'SauceLabs',
    browserName: 'chrome',
    platform: 'Windows 8.1'
  },
  firefoxWin8_1: {
    base: 'SauceLabs',
    browserName: 'chrome',
    platform: 'Windows 8.1'
  },
  ie9: {
    base: 'SauceLabs',
    browserName: 'internet explorer',
    platform: 'Windows 7',
    version: '9'
  },
  ie10: {
    base: 'SauceLabs',
    browserName: 'internet explorer',
    platform: 'Windows 7',
    version: '10'
  },
  ie11: {
    base: 'SauceLabs',
    browserName: 'internet explorer',
    platform: 'Windows 8.1',
    version: '11'
  }
}

module.exports = function (config) {

  defaultConfig(config);

  config.set({

    sauceLabs: {
      testName: 'iframe-transport Unit Tests'
    },

    customLaunchers: sauceLaunchers,

    browsers: Object.keys(sauceLaunchers),

    reporters: ['dots', 'saucelabs'],

    singleRun: true

  });

};
<|endoftext|>


<commit_before>/*global PalmSystem, webos: true, palmGetResource */
/**
	A collection of static variables and functions core to webOS functionality
	and the webOS feature-set. A large amount of PalmSystem bindings combined
	with some utility functions.
*/

//* @public
webos = {
	/**
		Returns an object containing the "appID" and "process" identifiers of
		the current-running application.
	*/
	identifier: function(){
		var tokens = PalmSystem.identifier.split(" ");
		return {
			appID: tokens[0],
			process: tokens[1]
		};
	},
	//* Returns an object containing the application's launch parameters.
	launchParams: function() {
		return enyo.json.parse(PalmSystem.launchParams || "{}") || {};
	},
	/**
		Returns an object containing device information such as:

		* `bluetoothAvailable`
		* `carrierName`
		* `coreNaviButton`
		* `keyboardAvailable`
		* `keyboardSlider`
		* `keyboardType`
		* `maximumCardWidth`
		* `maximumCardHeight`
		* `minimumCardWidth`
		* `minimumCardHeight`
		* `modelName`
		* `modelNameAscii`
		* `platformVersion`
		* `platformVersionDot`
		* `platformVersionMajor`
		* `platformVersionMinor`
		* `screenWidth`
		* `screenHeight`
		* `serialNumber`
		* `touchableRows`
		* `wifiAvailable`
	*/
	deviceInfo: function(){
		if (!PalmSystem) {
			return {
				platfromVersionMajor: "",
				modelName: "Browser"
			};
		}
		return enyo.json.parse(PalmSystem.deviceInfo);
	},
	/*
	 * Returns true if device is legacy webOS phone.
	 */
	isPhone: function () {
		return this.deviceInfo().platformVersionMajor <= 2;
	},
	isTablet: function () {
		return this.deviceInfo().platformVersionMajor === 3;
	},
	isLuneOS: function () {
		return (this.deviceInfo().modelName.indexOf("Lune") >= 0);
	},
	//* Returns the full URI path the application is running from.
	fetchAppRootPath: function() {
		var base = window.location.href;
		if('baseURI' in window.document) {
			base = window.document.baseURI;
		} else {
			var baseTags = window.document.getElementsByTagName("base");
			if(baseTags.length > 0) {
				base = baseTags[0].href;
			}
		}
		var match = base.match(new RegExp(".*:\/\/[^#]*\/"));
		if (match) {
			return match[0];
		}
		return "";
	},
	/**
		Synchronously fetchs, parses, and returns the appinfo.json file of
		the running application.
	*/
	fetchAppInfo: function() {
		if (!webos.appInfo) {
			try {
				var appInfoJSON, appInfoPath = webos.fetchAppRootPath() + "appinfo.json";
				if (window.palmGetResource) {
					appInfoJSON = palmGetResource(appInfoPath);
				} else {
					appInfoJSON = enyo.xhr.request({url: appInfoPath, sync: true}).responseText;
				}
				webos.appInfo = enyo.json.parse(appInfoJSON);
			} catch (e) {
				webos.appInfo = undefined;
			}
		}
		return webos.appInfo;
	},
	//* Returns an object containing the _"locale"_, _"localeRegion"_, and _"phoneRegion"_.
	localeInfo: function(){
		return {
			locale: PalmSystem.locale,
			localeRegion: PalmSystem.localeRegion,
			phoneRegion: PalmSystem.phoneRegion
		};
	},
	//* Whether or not the device is in 12-hour format.
	isTwelveHourFormat: function(){
		return (PalmSystem.timeFormat === "HH12");
	},
	//* Pastes any content in the clipboard.
	pasteClipboard: function(){
		PalmSystem.paste();
	},
	/**
		Returns the current device orientation; one of _"up"_, _"down"_, _"left"_,
		or _"right"_.
	*/
	getWindowOrientation: function() {
		//Returns one of 'up', 'down', 'left' or 'right'.
		return PalmSystem.screenOrientation;
	},
	/**
		Sets the device orientation. Acceptable values include _"up"_, _"down"_,
		_"left"_, _"right"_, and _"free"_.
	*/
	setWindowOrientation: function(inOrientation) {
		//inOrientation is one of 'up', 'down', 'left', 'right', or 'free'
		PalmSystem.setWindowOrientation(inOrientation);
	},
	//* Enables or disables fullscreen mode.
	setFullScreen: function(inMode) {
		PalmSystem.enableFullScreenMode(inMode);
	},
	/**
		New content management with LED notifications. Pass _true_ to
		indicate new content, pass _false_ to remove indications.
	*/
	indicateNewContent: function(hasNew) {
		if(webos._throbId) {
			PalmSystem.removeNewContentIndicator(webos._throbId);
			webos._throbId = undefined;
		}
		if(hasNew) {
			webos._throbId = PalmSystem.addNewContentIndicator();
		}
	},
	/**
		Returns _true_ or _false_ depending if the given window is activated.
		If no _inWindow_ is specified, `window` is used.
	*/
	isActivated: function(inWindow) {
		inWindow = inWindow || window;
		if(inWindow.PalmSystem) {
			return inWindow.PalmSystem.isActivated;
		}
		return false;
	},
	/**
		Activates a given window. If no _inWindow_ is specified, `window`
		is used.
	*/
	activate: function(inWindow) {
		inWindow = inWindow || window;
		if(inWindow.PalmSystem) {
			inWindow.PalmSystem.activate();
		}
	},
	/**
		Deactivates a given window. If no _inWindow_ is specified, `window`
		is used.
	*/
	deactivate: function(inWindow) {
		inWindow = inWindow || window;
		if(inWindow.PalmSystem) {
			inWindow.PalmSystem.deactivate();
		}
	},
	/**
		Adds a banner message; it will be displayed briefly before disappearing.
		Returns the banner ID.

		* `inMessage`: (required) message to display
		* `inJson`: (required) JSON-formatted string re-launch parameters
		* `inIcon`: icon to display
		* `inSoundClass`: sound class to play
		* `inSoundPath`: path to sound to play
		* `inSoundDuration`: duration of sound to play
	*/
	addBannerMessage: function(inMessage, inJson, inIcon, inSoundClass, inSoundPath, inSoundDuration) {
		return PalmSystem.addBannerMessage.apply(PalmSystem, arguments);
	},
	//* Removes a banner message by a given banner ID.
	removeBannerMessage: function(inId) {
		PalmSystem.removeBannerMessage.apply(PalmSystem, arguments);
	},
	/**
		Set webOS system properties of a given window.

		Properties are an object and can contain the following settings:

		* `blockScreenTimeout` (Boolean)
		* `setSubtleLightbar` (Boolean)
		* `fastAccelerometer` (Boolean)
	*/
	setWindowProperties: function(inWindow, inProps) {
		if(arguments.length==1) {
			inProps = inWindow;
			inWindow = window;
		}
		if(inWindow.PalmSystem) {
			inWindow.PalmSystem.setWindowProperties(inProps);
		}
	},

	/**
		Searches _inText_ for URLs (web and mailto) and emoticons (if supported),
		and returns a new string with those entities replaced by HTML links and
		images (respectively).

		Passing false for an  _inOptions_ field will prevent LunaSysMgr from
		HTML-izing that text type.

		Default option values:

		* `phoneNumber: true,`
		* `emailAddress: true,`
		* `webLink: true,`
		* `schemalessWebLink: true,`
		* `emoticon: true`
	*/
	runTextIndexer: function(inText, inOptions){
		if (inText && inText.length > 0 && PalmSystem.runTextIndexer) {
			return PalmSystem.runTextIndexer(inText, inOptions);
		}
		return inText;
	}
};

if (window.PalmSystem) {
	PalmSystem.stageReady();
} else {
	webos = {};
}

//* Reference pointing for convenience
enyo.webos = webos;
<commit_msg>improved webos.deviceInfo to store deviceInfo obj<commit_after>/*global PalmSystem, webos: true, palmGetResource */
/**
	A collection of static variables and functions core to webOS functionality
	and the webOS feature-set. A large amount of PalmSystem bindings combined
	with some utility functions.
*/

//* @public
webos = {
	/**
		Returns an object containing the "appID" and "process" identifiers of
		the current-running application.
	*/
	identifier: function(){
		var tokens = PalmSystem.identifier.split(" ");
		return {
			appID: tokens[0],
			process: tokens[1]
		};
	},
	//* Returns an object containing the application's launch parameters.
	launchParams: function() {
		return enyo.json.parse(PalmSystem.launchParams || "{}") || {};
	},
	/**
		Returns an object containing device information such as:

		* `bluetoothAvailable`
		* `carrierName`
		* `coreNaviButton`
		* `keyboardAvailable`
		* `keyboardSlider`
		* `keyboardType`
		* `maximumCardWidth`
		* `maximumCardHeight`
		* `minimumCardWidth`
		* `minimumCardHeight`
		* `modelName`
		* `modelNameAscii`
		* `platformVersion`
		* `platformVersionDot`
		* `platformVersionMajor`
		* `platformVersionMinor`
		* `screenWidth`
		* `screenHeight`
		* `serialNumber`
		* `touchableRows`
		* `wifiAvailable`
	*/
	deviceInfo: function(){
		if (!this._deviceInfo) {
			if (!PalmSystem) {
				this._deviceInfo = {
					platfromVersionMajor: "",
					modelName: "Browser"
				};
			} else {
				this._deviceInfo = enyo.json.parse(PalmSystem.deviceInfo);
			}
		}
		return this._deviceInfo;
	},
	/*
	 * Returns true if device is legacy webOS phone.
	 */
	isPhone: function () {
		return this.deviceInfo().platformVersionMajor <= 2;
	},
	isTablet: function () {
		return this.deviceInfo().platformVersionMajor === 3;
	},
	isLuneOS: function () {
		return (this.deviceInfo().modelName.indexOf("Lune") >= 0);
	},
	//* Returns the full URI path the application is running from.
	fetchAppRootPath: function() {
		var base = window.location.href;
		if('baseURI' in window.document) {
			base = window.document.baseURI;
		} else {
			var baseTags = window.document.getElementsByTagName("base");
			if(baseTags.length > 0) {
				base = baseTags[0].href;
			}
		}
		var match = base.match(new RegExp(".*:\/\/[^#]*\/"));
		if (match) {
			return match[0];
		}
		return "";
	},
	/**
		Synchronously fetchs, parses, and returns the appinfo.json file of
		the running application.
	*/
	fetchAppInfo: function() {
		if (!webos.appInfo) {
			try {
				var appInfoJSON, appInfoPath = webos.fetchAppRootPath() + "appinfo.json";
				if (window.palmGetResource) {
					appInfoJSON = palmGetResource(appInfoPath);
				} else {
					appInfoJSON = enyo.xhr.request({url: appInfoPath, sync: true}).responseText;
				}
				webos.appInfo = enyo.json.parse(appInfoJSON);
			} catch (e) {
				webos.appInfo = undefined;
			}
		}
		return webos.appInfo;
	},
	//* Returns an object containing the _"locale"_, _"localeRegion"_, and _"phoneRegion"_.
	localeInfo: function(){
		return {
			locale: PalmSystem.locale,
			localeRegion: PalmSystem.localeRegion,
			phoneRegion: PalmSystem.phoneRegion
		};
	},
	//* Whether or not the device is in 12-hour format.
	isTwelveHourFormat: function(){
		return (PalmSystem.timeFormat === "HH12");
	},
	//* Pastes any content in the clipboard.
	pasteClipboard: function(){
		PalmSystem.paste();
	},
	/**
		Returns the current device orientation; one of _"up"_, _"down"_, _"left"_,
		or _"right"_.
	*/
	getWindowOrientation: function() {
		//Returns one of 'up', 'down', 'left' or 'right'.
		return PalmSystem.screenOrientation;
	},
	/**
		Sets the device orientation. Acceptable values include _"up"_, _"down"_,
		_"left"_, _"right"_, and _"free"_.
	*/
	setWindowOrientation: function(inOrientation) {
		//inOrientation is one of 'up', 'down', 'left', 'right', or 'free'
		PalmSystem.setWindowOrientation(inOrientation);
	},
	//* Enables or disables fullscreen mode.
	setFullScreen: function(inMode) {
		PalmSystem.enableFullScreenMode(inMode);
	},
	/**
		New content management with LED notifications. Pass _true_ to
		indicate new content, pass _false_ to remove indications.
	*/
	indicateNewContent: function(hasNew) {
		if(webos._throbId) {
			PalmSystem.removeNewContentIndicator(webos._throbId);
			webos._throbId = undefined;
		}
		if(hasNew) {
			webos._throbId = PalmSystem.addNewContentIndicator();
		}
	},
	/**
		Returns _true_ or _false_ depending if the given window is activated.
		If no _inWindow_ is specified, `window` is used.
	*/
	isActivated: function(inWindow) {
		inWindow = inWindow || window;
		if(inWindow.PalmSystem) {
			return inWindow.PalmSystem.isActivated;
		}
		return false;
	},
	/**
		Activates a given window. If no _inWindow_ is specified, `window`
		is used.
	*/
	activate: function(inWindow) {
		inWindow = inWindow || window;
		if(inWindow.PalmSystem) {
			inWindow.PalmSystem.activate();
		}
	},
	/**
		Deactivates a given window. If no _inWindow_ is specified, `window`
		is used.
	*/
	deactivate: function(inWindow) {
		inWindow = inWindow || window;
		if(inWindow.PalmSystem) {
			inWindow.PalmSystem.deactivate();
		}
	},
	/**
		Adds a banner message; it will be displayed briefly before disappearing.
		Returns the banner ID.

		* `inMessage`: (required) message to display
		* `inJson`: (required) JSON-formatted string re-launch parameters
		* `inIcon`: icon to display
		* `inSoundClass`: sound class to play
		* `inSoundPath`: path to sound to play
		* `inSoundDuration`: duration of sound to play
	*/
	addBannerMessage: function(inMessage, inJson, inIcon, inSoundClass, inSoundPath, inSoundDuration) {
		return PalmSystem.addBannerMessage.apply(PalmSystem, arguments);
	},
	//* Removes a banner message by a given banner ID.
	removeBannerMessage: function(inId) {
		PalmSystem.removeBannerMessage.apply(PalmSystem, arguments);
	},
	/**
		Set webOS system properties of a given window.

		Properties are an object and can contain the following settings:

		* `blockScreenTimeout` (Boolean)
		* `setSubtleLightbar` (Boolean)
		* `fastAccelerometer` (Boolean)
	*/
	setWindowProperties: function(inWindow, inProps) {
		if(arguments.length==1) {
			inProps = inWindow;
			inWindow = window;
		}
		if(inWindow.PalmSystem) {
			inWindow.PalmSystem.setWindowProperties(inProps);
		}
	},

	/**
		Searches _inText_ for URLs (web and mailto) and emoticons (if supported),
		and returns a new string with those entities replaced by HTML links and
		images (respectively).

		Passing false for an  _inOptions_ field will prevent LunaSysMgr from
		HTML-izing that text type.

		Default option values:

		* `phoneNumber: true,`
		* `emailAddress: true,`
		* `webLink: true,`
		* `schemalessWebLink: true,`
		* `emoticon: true`
	*/
	runTextIndexer: function(inText, inOptions){
		if (inText && inText.length > 0 && PalmSystem.runTextIndexer) {
			return PalmSystem.runTextIndexer(inText, inOptions);
		}
		return inText;
	}
};

if (window.PalmSystem) {
	PalmSystem.stageReady();
} else {
	webos = {};
}

//* Reference pointing for convenience
enyo.webos = webos;
<|endoftext|>


<commit_before>var request = new XMLHttpRequest;

window.onload = function() {
  document.getElementById('url').style.display = 'none';
};

function find() {
  document.getElementById('url').style.display = 'none';
  var username = document.getElementById('username').value;
  var contest = document.getElementById('contest').value;
  var problem = document.getElementById('problem').value;
  var url = '/get_solution?user=' + username + '&contest=' + contest + '&problem=' + problem
  request.open('GET', url, true);

  request.onreadystatechange = function() {
    if(request.readyState == 4 && request.status == 200) {
      var data = JSON.parse(request.responseText);
      document.getElementById('url').style.display = 'block';
      if(data.status === '!ok') {
        document.getElementById('url').className = 'container alert alert-danger';
        var html = "" + data['url'] + "";
        document.getElementById('url').innerHTML = html;
      } else {
        document.getElementById('url').className = 'container alert alert-success';
        var html = "" + data['url'] + ""
        document.getElementById('url').innerHTML = html;
      }
    }
  }
  request.send();
}<commit_msg>New append to wrapper mode<commit_after>window.onload = function() {
  document.getElementById('wrapper').innerHTML = '';
};

function get() {
  document.getElementById('wrapper').innerHTML = '';
  var usersList = document.getElementById('username').value;
  var contest = document.getElementById('contest').value;
  var problem = document.getElementById('problem').value;
  usersList = usersList.split('+');

  for(var i = 0; i < usersList.length; i++) {
    findSolutionId('/get_solution?user=' + usersList[i] + '&contest=' + contest + '&problem=' + problem);
  }
}

function findSolutionId(url) {
  var request = new XMLHttpRequest();
  request.open('GET', url, true);
  request.onreadystatechange = function() {
    if(request.readyState == 4 && request.status == 200) {
      var response = JSON.parse(request.responseText);
      if(response.status === '!ok') {
        var html = htmlToAppend('alert-danger', 'red', response.data, response.whose, response.error);
        document.getElementById('wrapper').innerHTML += html;
      }
      else {
        var html = htmlToAppend('alert-success', 'green', response.data, response.whose, response.error);
        document.getElementById('wrapper').innerHTML += html;
      }
    }
  }
  request.send();
}

function htmlToAppend(alertType, colorType, url, whose, error) {
  var html = "
";
  html += "";
  html += whose;
  if(error !== '') {
    html += ": " + error;
  } else {
    html += "'s solution :)"
  }
  html += "
"
  return html;
}<|endoftext|>


<commit_before><commit_msg>new function checkNeighbours()<commit_after><|endoftext|>


<commit_before><commit_msg>changes in octoarg<commit_after><|endoftext|>


<commit_before><commit_msg>drop test2<commit_after><|endoftext|>


<commit_before>/**
 * Safe - support for storing Backbone.Model to localstorage/sessionstorage
 * 		  using the 'set' method of Model
 *
 * @constructor - use the key 'safe' to define unique storage key for backbone safe
 *
 * 				examples:
 *
 *				// simple defintion for safe
 *			 	Backbone.Model.extend({ key: 'my-unique-key' });
 *
 * 					// advanced defintion for safe with options
 *	  			Backbone.Model.extend({
 *
 *		 				safe: {
 *		 					key: 'my-unique-key',
 *		 					options: {
 *		 						reload: true
 *		 					}
 *		 				}
 *
 *	  			})
 *
 * @requires Backbone.js, Underscore.js
 * @param {string} uniqueID - the name of the storage you'de like to use
 * @param {object} context  - the Backbone.Model instance reference
 * @param {object} options - (optional) configuration for setting up various features
 *						 - {boolean} reload - true to reload (before initialize) data from local/session storage if exists
 *
 * @author Oren Farhi, http://orizens.com
 *
 * @version 0.3
 *
 */
(function(){

	var _ = this._;
	var Backbone = this.Backbone;

	// if Underscore or Backbone have not been loaded
	// exit to prevent js errors
	if (!_ || !Backbone || !JSON) {
		return;
	}

	// factory for creating extend replacement for Backbone Objects
	function BackboneExtender(bbObject, plugins) {
		var thisExtender = this;
		this.plugins = plugins;
		bbObject["extend"] = _.wrap(bbObject["extend"], function(sourceExtend, config){
			config = config || {}
			// thisExtender.config = config;
			var _sourceFn = config.initialize || this.prototype.initialize || function(){};
			config.initialize = function(){
				var args = [].slice.call(arguments);
				thisExtender.config = config;
				thisExtender.applyPlugins(this, args);
				_sourceFn.apply(this, args);
			};
			return sourceExtend.call(this, config);
		});
	};

	BackboneExtender.prototype.applyPlugins = function(instance, args) {
		var config = this.config,
			plugins = this.plugins,
			args = args || [];
		// run the plugins on this
		_.each(plugins, function(plugFn){
			plugFn.call(instance, config, args);
		});
	};

	BackboneExtender.prototype.addPlug = function(plugFn) {
		this.plugins.push(plugFn);
	};

	var SafePlug = function (config, args) {
		var storageKey,
			storageType;

		// create safe if exist as key
		if (config && config.safe) {

			// handle key, value safe
			storageKey = config.safe.key ? config.safe.key : config.safe;
			// get which storage should be use
			storageType = config.safe.type ? config.safe.type : 'local';

			Backbone.Safe.create(storageKey, this, storageType, config.safe.options || { reload: true });
		}
	}
	// extend Model & Collection constructor to handle safe initialization
	// Backbone.Model.extend = _.wrap(Backbone.Model.extend, BackboneExtender)
	var modelSafePlugin = new BackboneExtender(Backbone.Model, [ SafePlug ]);
	var collectionSafePlugin = new BackboneExtender(Backbone.Collection, [ SafePlug ]);

	Backbone.Safe = function(uniqueID, context, type, options) {

		// parsing options settings
		this._reload = options && options.reload && options.reload === true;

		this.uid = uniqueID;
		this.type = type;
		this.context = context;
		this.isCollection = context.models && context.add;

		// mixins for collection and model
		var collection = {

			// events that Safe is listening in order to
			// trigger save to storage
			events: 'add reset change sort dump',

			// the value to be used when cleaning the safe
			emptyValue: '[]',

			reload: function(options) {
				context.add(this.getData(), options);
			},

			fetch: function(options) {
				var fetchFromSafe = options && options.from;
				if (fetchFromSafe && fetchFromSafe === "safe") {
					this.safe.reload(options);
				} else {
					Backbone.Collection.prototype.fetch.apply(this, arguments);
				}
			},

			toJSON: function(model) {
				if (model.collection) { // From add and remove, this will be a model
					return model.collection.toJSON();
				}
				else {
					return model.toJSON();
				}
			}
		};

		var model = {

			events: 'change',

			emptyValue: '{}',

			reload: function(options) {
				context.set(this.getData(), options);
			},

			// options = { from: "safe" }
			fetch: function (options) {
				var fetchFromSafe = options && options.from;
				if (fetchFromSafe && fetchFromSafe === "safe") {
					this.safe.reload(options);
				} else {
					Backbone.Model.prototype.fetch.apply(this, arguments);
				}
			},

			toJSON: function(model) {
				return model.toJSON();
			}
		};

		// attach relevant object to Safe prototype
		_.extend( this, this.isCollection ? collection : model );

		// if the uid doesn't exist, create it
		this.ensureUID();

		// These are the lines that are responsible for
		// loading the saved data from the storage to the model
		//
		// the data is loaded before the Safe binds to change events
		// storage exist ? -> save to model
		// if it's a collection - use add
		if (this._reload) {
			this.reload();
		}

		// attach Backbone custom methods
		_.extend(context, _.pick(this, ['fetch']));
		// listen to any change event and cache it
		this.debouncedStore = _.debounce(_.bind(this.store, this), 75);
		context.on(this.events, this.debouncedStore, this);
		// adding destroy handler
		context.on('destroy', this.destroy, this);
	};

	Backbone.Safe.prototype = {

		/**
		 * creates a storage item with the provided
		 * UID if not exist
		 */
		ensureUID: function() {
			if (_.isNull(this.getData())){
				this.create();
			}
		},

		create: function() {
			this.storage().setItem(this.uid, this.emptyValue);
		},

		/*
		 * @bbDataObj {collection/model}
		 */
		store: function(bbDataObj) {
			this.storage()
				.setItem(this.uid, JSON.stringify( this.toJSON( bbDataObj )));
		},

		storage: function() {
			return this.type == 'session' ? sessionStorage :  localStorage;
		},

		/**
		 * returns json object of the local saved data
		 * @return {json}
		 */
		getData: function() {
			// JSON.parse can't be run with an empty string
			this._current = this.storage().getItem(this.uid);
			try {
				return this._current ? JSON.parse(this._current) : this._current;
			} catch (e) {
				return {};
			}
		},

		// set the local storage key to the empty value
		reset: function() {
			this.create();
		},

		// removes the key from the localstorage
		destroy: function() {
			this.storage().removeItem( this.uid );
		}
	};

	// factory method
	Backbone.Safe.create = function( uniqueID, context, type, options) {
		if (uniqueID && context) {
			context.safe = new Backbone.Safe(uniqueID, context, type, options);
		}
	};

})();<commit_msg>replace debounce with throttle<commit_after>/**
 * Safe - support for storing Backbone.Model to localstorage/sessionstorage
 * 		  using the 'set' method of Model
 *
 * @constructor - use the key 'safe' to define unique storage key for backbone safe
 *
 * 				examples:
 *
 *				// simple defintion for safe
 *			 	Backbone.Model.extend({ key: 'my-unique-key' });
 *
 * 					// advanced defintion for safe with options
 *	  			Backbone.Model.extend({
 *
 *		 				safe: {
 *		 					key: 'my-unique-key',
 *		 					options: {
 *		 						reload: true
 *		 					}
 *		 				}
 *
 *	  			})
 *
 * @requires Backbone.js, Underscore.js
 * @param {string} uniqueID - the name of the storage you'de like to use
 * @param {object} context  - the Backbone.Model instance reference
 * @param {object} options - (optional) configuration for setting up various features
 *						 - {boolean} reload - true to reload (before initialize) data from local/session storage if exists
 *
 * @author Oren Farhi, http://orizens.com
 *
 * @version 0.3
 *
 */
(function(){

	var _ = this._;
	var Backbone = this.Backbone;

	// if Underscore or Backbone have not been loaded
	// exit to prevent js errors
	if (!_ || !Backbone || !JSON) {
		return;
	}

	// factory for creating extend replacement for Backbone Objects
	function BackboneExtender(bbObject, plugins) {
		var thisExtender = this;
		this.plugins = plugins;
		bbObject["extend"] = _.wrap(bbObject["extend"], function(sourceExtend, config){
			config = config || {}
			// thisExtender.config = config;
			var _sourceFn = config.initialize || this.prototype.initialize || function(){};
			config.initialize = function(){
				var args = [].slice.call(arguments);
				thisExtender.config = config;
				thisExtender.applyPlugins(this, args);
				_sourceFn.apply(this, args);
			};
			return sourceExtend.call(this, config);
		});
	};

	BackboneExtender.prototype.applyPlugins = function(instance, args) {
		var config = this.config,
			plugins = this.plugins,
			args = args || [];
		// run the plugins on this
		_.each(plugins, function(plugFn){
			plugFn.call(instance, config, args);
		});
	};

	BackboneExtender.prototype.addPlug = function(plugFn) {
		this.plugins.push(plugFn);
	};

	var SafePlug = function (config, args) {
		var storageKey,
			storageType;

		// create safe if exist as key
		if (config && config.safe) {

			// handle key, value safe
			storageKey = config.safe.key ? config.safe.key : config.safe;
			// get which storage should be use
			storageType = config.safe.type ? config.safe.type : 'local';

			Backbone.Safe.create(storageKey, this, storageType, config.safe.options || { reload: true });
		}
	}
	// extend Model & Collection constructor to handle safe initialization
	// Backbone.Model.extend = _.wrap(Backbone.Model.extend, BackboneExtender)
	var modelSafePlugin = new BackboneExtender(Backbone.Model, [ SafePlug ]);
	var collectionSafePlugin = new BackboneExtender(Backbone.Collection, [ SafePlug ]);

	Backbone.Safe = function(uniqueID, context, type, options) {

		// parsing options settings
		this._reload = options && options.reload && options.reload === true;

		this.uid = uniqueID;
		this.type = type;
		this.context = context;
		this.isCollection = context.models && context.add;

		// mixins for collection and model
		var collection = {

			// events that Safe is listening in order to
			// trigger save to storage
			events: 'add reset change sort dump',

			// the value to be used when cleaning the safe
			emptyValue: '[]',

			reload: function(options) {
				context.add(this.getData(), options);
			},

			fetch: function(options) {
				var fetchFromSafe = options && options.from;
				if (fetchFromSafe && fetchFromSafe === "safe") {
					this.safe.reload(options);
				} else {
					Backbone.Collection.prototype.fetch.apply(this, arguments);
				}
			},

			toJSON: function(model) {
				if (model.collection) { // From add and remove, this will be a model
					return model.collection.toJSON();
				}
				else {
					return model.toJSON();
				}
			}
		};

		var model = {

			events: 'change',

			emptyValue: '{}',

			reload: function(options) {
				context.set(this.getData(), options);
			},

			// options = { from: "safe" }
			fetch: function (options) {
				var fetchFromSafe = options && options.from;
				if (fetchFromSafe && fetchFromSafe === "safe") {
					this.safe.reload(options);
				} else {
					Backbone.Model.prototype.fetch.apply(this, arguments);
				}
			},

			toJSON: function(model) {
				return model.toJSON();
			}
		};

		// attach relevant object to Safe prototype
		_.extend( this, this.isCollection ? collection : model );

		// if the uid doesn't exist, create it
		this.ensureUID();

		// These are the lines that are responsible for
		// loading the saved data from the storage to the model
		//
		// the data is loaded before the Safe binds to change events
		// storage exist ? -> save to model
		// if it's a collection - use add
		if (this._reload) {
			this.reload();
		}

		// attach Backbone custom methods
		_.extend(context, _.pick(this, ['fetch']));
		// listen to any change event and cache it
		this.debouncedStore = _.throttle(_.bind(this.store, this), 75);
		context.on(this.events, this.debouncedStore, this);
		// adding destroy handler
		context.on('destroy', this.destroy, this);
	};

	Backbone.Safe.prototype = {

		/**
		 * creates a storage item with the provided
		 * UID if not exist
		 */
		ensureUID: function() {
			if (_.isNull(this.getData())){
				this.create();
			}
		},

		create: function() {
			this.storage().setItem(this.uid, this.emptyValue);
		},

		/*
		 * @bbDataObj {collection/model}
		 */
		store: function(bbDataObj) {
			this.storage()
				.setItem(this.uid, JSON.stringify( this.toJSON( bbDataObj )));
		},

		storage: function() {
			return this.type == 'session' ? sessionStorage :  localStorage;
		},

		/**
		 * returns json object of the local saved data
		 * @return {json}
		 */
		getData: function() {
			// JSON.parse can't be run with an empty string
			this._current = this.storage().getItem(this.uid);
			try {
				return this._current ? JSON.parse(this._current) : this._current;
			} catch (e) {
				return {};
			}
		},

		// set the local storage key to the empty value
		reset: function() {
			this.create();
		},

		// removes the key from the localstorage
		destroy: function() {
			this.storage().removeItem( this.uid );
		}
	};

	// factory method
	Backbone.Safe.create = function( uniqueID, context, type, options) {
		if (uniqueID && context) {
			context.safe = new Backbone.Safe(uniqueID, context, type, options);
		}
	};

})();<|endoftext|>


<commit_before><commit_msg>remove console log<commit_after><|endoftext|>


<commit_before><commit_msg>more mobile debugging<commit_after><|endoftext|>


<commit_before><commit_msg>Update js for navigation<commit_after><|endoftext|>


<commit_before><commit_msg>added jsUtil.objects.clone<commit_after><|endoftext|>


<commit_before><commit_msg>слежение за изменением всех файлов выбранного препроцессора<commit_after><|endoftext|>


<commit_before><commit_msg>fix(is): primitive method<commit_after><|endoftext|>


<commit_before>import React, { Component, PropTypes, cloneElement } from 'react';

import {
  Field,
  Meta,
  Label,
  Value,
  Description,
} from '../FormComponents';

export default class InputField extends Component {
  static propTypes = {
    classNames: PropTypes.shape({
      root: PropTypes.string,
      meta: PropTypes.string,
      label: PropTypes.string,
      valueReplay: PropTypes.string,
      description: PropTypes.string,
    }),
    Element: PropTypes.oneOfType([
      PropTypes.string,
      PropTypes.func,
    ]),
    id: PropTypes.string.isRequired,
    meta: PropTypes.node,
    label: PropTypes.node,
    description: PropTypes.node,
    children: PropTypes.element.isRequired,
    error: PropTypes.string,
    valueReplay: PropTypes.string,
    required: PropTypes.bool,
    optionalLabel: PropTypes.string,
  };

  static defaultProps = {
    classNames: {},
    Element: Field,
  };

  render() {
    const {
      id,
      Element,
      meta,
      label,
      description,
      children,
      classNames,
      error,
      valueReplay,
      required,
      optionalLabel,
      ...rest,
    } = this.props;

    const descriptionId = `${id}-description`;
    const sharedProps = { error };

    return (
      <Element className={ classNames.root }>
        { meta && (
          <Meta
            { ...sharedProps }
            className={ classNames.meta }
          >
            { meta }
          </Meta>
        ) }
        <Label
          { ...sharedProps }
          htmlFor={ id }
          className={ classNames.label }
          optionalLabel={ !required && optionalLabel }
        >
          { label }
        </Label>
        { valueReplay && (
          <Value
            { ...sharedProps }
            className={ classNames.valueReplay }
          >
            { valueReplay }
          </Value>
        ) }
        { description && (
          <Description
            { ...sharedProps }
            id={ descriptionId }
            className={ classNames.description }
          >
            { description }
          </Description>
        ) }
        { cloneElement(children, {
          ...rest,
          ...sharedProps,
          ref: (c) => { this.input = c; },
          name: id,
          id,
          required,
          'aria-describedby': descriptionId,
        }) }
      </Element>
    );
  }
}<commit_msg>Allow `<InputField />`'s `valueReply` + `error` props to be nodes<commit_after>import React, { Component, PropTypes, cloneElement } from 'react';

import {
  Field,
  Meta,
  Label,
  Value,
  Description,
} from '../FormComponents';

export default class InputField extends Component {
  static propTypes = {
    classNames: PropTypes.shape({
      root: PropTypes.string,
      meta: PropTypes.string,
      label: PropTypes.string,
      valueReplay: PropTypes.string,
      description: PropTypes.string,
    }),
    Element: PropTypes.oneOfType([
      PropTypes.string,
      PropTypes.func,
    ]),
    id: PropTypes.string.isRequired,
    meta: PropTypes.node,
    label: PropTypes.node,
    description: PropTypes.node,
    children: PropTypes.element.isRequired,
    error: PropTypes.node,
    valueReplay: PropTypes.node,
    required: PropTypes.bool,
    optionalLabel: PropTypes.string,
  };

  static defaultProps = {
    classNames: {},
    Element: Field,
  };

  render() {
    const {
      id,
      Element,
      meta,
      label,
      description,
      children,
      classNames,
      error,
      valueReplay,
      required,
      optionalLabel,
      ...rest,
    } = this.props;

    const descriptionId = `${id}-description`;
    const sharedProps = { error };

    return (
      <Element className={ classNames.root }>
        { meta && (
          <Meta
            { ...sharedProps }
            className={ classNames.meta }
          >
            { meta }
          </Meta>
        ) }
        <Label
          { ...sharedProps }
          htmlFor={ id }
          className={ classNames.label }
          optionalLabel={ !required && optionalLabel }
        >
          { label }
        </Label>
        { valueReplay && (
          <Value
            { ...sharedProps }
            className={ classNames.valueReplay }
          >
            { valueReplay }
          </Value>
        ) }
        { description && (
          <Description
            { ...sharedProps }
            id={ descriptionId }
            className={ classNames.description }
          >
            { description }
          </Description>
        ) }
        { cloneElement(children, {
          ...rest,
          ...sharedProps,
          ref: (c) => { this.input = c; },
          name: id,
          id,
          required,
          'aria-describedby': descriptionId,
        }) }
      </Element>
    );
  }
}<|endoftext|>


<commit_before>import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import DayPicker from 'react-day-picker';
import NavigationBar from './NavigationBar';
import WeekDay from './WeekDay';
import { convertModifiersToClassnames, hasRange, isSelectingFirstDay } from './utils';
import cx from 'classnames';
import theme from './theme.css';

class DatePickerRange extends PureComponent {
  state = {
    selectedStartDate: null,
    to: null,
    enteredTo: null,
  };

  static getDerivedStateFromProps(props, state) {
    if (
      props.selectedRange !== undefined &&
      (props.selectedRange.selectedStartDate !== state.selectedStartDate || props.selectedRange.to !== state.to)
    ) {
      return {
        selectedStartDate: props.selectedRange.selectedStartDate,
        to: props.selectedRange.to,
        enteredTo: props.selectedRange.to,
      };
    }

    return null;
  }

  handleDayClick = day => {
    const { selectedStartDate, to } = this.state;

    if (isSelectingFirstDay(selectedStartDate, to, day)) {
      this.setState(
        {
          selectedStartDate: day,
          to: null,
          enteredTo: null,
        },
        () => this.props.onChange({ selectedStartDate: day, to: null }),
      );
    } else {
      this.setState(
        {
          to: day,
          enteredTo: day,
        },
        () => this.props.onChange({ selectedStartDate, to: day }),
      );
    }
  };

  handleDayMouseEnter = day => {
    const { selectedStartDate, to } = this.state;

    if (!isSelectingFirstDay(selectedStartDate, to, day)) {
      this.setState({
        enteredTo: day,
      });
    }
  };

  render() {
    const { className, size, ...others } = this.props;
    const { selectedStartDate, enteredTo } = this.state;
    const modifiers = { selectedStartDate, to: enteredTo };
    const selectedDays = [selectedStartDate, { selectedStartDate, to: enteredTo }];

    const classNames = cx(
      theme['date-picker'],
      theme[`is-${size}`],
      {
        [theme['has-range']]: hasRange(selectedDays),
      },
      className,
    );

    return (
      <DayPicker
        {...others}
        className={classNames}
        classNames={theme}
        modifiers={convertModifiersToClassnames(modifiers, theme)}
        navbarElement={<NavigationBar size={size} />}
        onDayClick={this.handleDayClick}
        onDayMouseEnter={this.handleDayMouseEnter}
        selectedDays={selectedDays}
        weekdayElement={<WeekDay size={size} />}
      />
    );
  }
}

DatePickerRange.propTypes = {
  className: PropTypes.string,
  onChange: PropTypes.func,
  selectedRange: PropTypes.object,
  size: PropTypes.oneOf(['small', 'medium', 'large']),
};

DatePickerRange.defaultProps = {
  size: 'medium',
};

export default DatePickerRange;
<commit_msg>Renamed prop 'to' to 'selectedEndDate'<commit_after>import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import DayPicker from 'react-day-picker';
import NavigationBar from './NavigationBar';
import WeekDay from './WeekDay';
import { convertModifiersToClassnames, hasRange, isSelectingFirstDay } from './utils';
import cx from 'classnames';
import theme from './theme.css';

class DatePickerRange extends PureComponent {
  state = {
    selectedStartDate: null,
    selectedEndDate: null,
    enteredTo: null,
  };

  static getDerivedStateFromProps(props, state) {
    if (
      props.selectedRange !== undefined &&
      (props.selectedRange.selectedStartDate !== state.selectedStartDate ||
        props.selectedRange.selectedEndDate !== state.selectedEndDate)
    ) {
      return {
        selectedStartDate: props.selectedRange.selectedStartDate,
        selectedEndDate: props.selectedRange.selectedEndDate,
        enteredTo: props.selectedRange.selectedEndDate,
      };
    }

    return null;
  }

  handleDayClick = day => {
    const { selectedStartDate, selectedEndDate } = this.state;

    if (isSelectingFirstDay(selectedStartDate, selectedEndDate, day)) {
      this.setState(
        {
          selectedStartDate: day,
          selectedEndDate: null,
          enteredTo: null,
        },
        () => this.props.onChange({ selectedStartDate: day, selectedEndDate: null }),
      );
    } else {
      this.setState(
        {
          selectedEndDate: day,
          enteredTo: day,
        },
        () => this.props.onChange({ selectedStartDate, selectedEndDate: day }),
      );
    }
  };

  handleDayMouseEnter = day => {
    const { selectedStartDate, selectedEndDate } = this.state;

    if (!isSelectingFirstDay(selectedStartDate, selectedEndDate, day)) {
      this.setState({
        enteredTo: day,
      });
    }
  };

  render() {
    const { className, size, ...others } = this.props;
    const { selectedStartDate, enteredTo } = this.state;
    const modifiers = { from: selectedStartDate, to: enteredTo };
    const selectedDays = [selectedStartDate, { from: selectedStartDate, to: enteredTo }];

    const classNames = cx(
      theme['date-picker'],
      theme[`is-${size}`],
      {
        [theme['has-range']]: hasRange(selectedDays),
      },
      className,
    );

    return (
      <DayPicker
        {...others}
        className={classNames}
        classNames={theme}
        modifiers={convertModifiersToClassnames(modifiers, theme)}
        navbarElement={<NavigationBar size={size} />}
        onDayClick={this.handleDayClick}
        onDayMouseEnter={this.handleDayMouseEnter}
        selectedDays={selectedDays}
        weekdayElement={<WeekDay size={size} />}
      />
    );
  }
}

DatePickerRange.propTypes = {
  className: PropTypes.string,
  onChange: PropTypes.func,
  selectedRange: PropTypes.object,
  size: PropTypes.oneOf(['small', 'medium', 'large']),
};

DatePickerRange.defaultProps = {
  size: 'medium',
};

export default DatePickerRange;
<|endoftext|>